From 6695f068295cd2c078f5fa6d474c6d674c269c38 Mon Sep 17 00:00:00 2001 From: Konrad Rzeszutek Wilk Date: Wed, 24 Feb 2010 16:05:16 -0500 Subject: [PATCH] Pull from ftp://ftp.netperf.org/netperf/netperf-2.4.5.tar.bz2 --- AUTHORS | 234 + COPYING | 43 + ChangeLog | 1 + INSTALL | 229 + Makefile.am | 4 + Makefile.in | 557 + NEWS | 0 README | 49 + README.aix | 24 + README.hpux | 31 + README.osx | 4 + README.ovms | 66 + README.solaris | 29 + README.vmware | 15 + README.vmware~ | 9 + README.windows | 106 + Release_Notes | 856 + acinclude.m4 | 341 + aclocal.m4 | 1236 + autogen.sh | 5 + config.guess | 1466 + config.h.in | 384 + config.sub | 1579 + configure | 12154 ++++++++ configure.ac | 993 + depcomp | 479 + doc/Makefile.am | 22 + doc/Makefile.in | 606 + doc/examples/Makefile.am | 11 + doc/examples/Makefile.in | 284 + doc/examples/arr_script | 386 + doc/examples/packet_byte_script | 202 + doc/examples/sctp_stream_script | 104 + doc/examples/snapshot_script | 226 + doc/examples/tcp_range_script | 113 + doc/examples/tcp_rr_script | 107 + doc/examples/tcp_stream_script | 104 + doc/examples/udp_rr_script | 107 + doc/examples/udp_stream_script | 104 + doc/netperf.info | 2859 ++ doc/netperf.man | 214 + doc/netperf.texi | 2822 ++ doc/netperf_old.ps | 24014 ++++++++++++++++ doc/netserver.man | 56 + doc/texinfo.tex | 6744 +++++ inet_ntop.c | 1 + install-sh | 294 + m4/.svn/all-wcprops | 5 + m4/.svn/entries | 31 + m4/.svn/format | 1 + m4/m4/.svn/all-wcprops | 23 + m4/m4/.svn/entries | 64 + m4/m4/.svn/format | 1 + m4/m4/.svn/text-base/salen.m4.svn-base | 32 + m4/m4/.svn/text-base/sockaddrin6.m4.svn-base | 60 + m4/m4/.svn/text-base/sockinttypes.m4.svn-base | 154 + m4/m4/salen.m4 | 32 + m4/m4/sockaddrin6.m4 | 60 + m4/m4/sockinttypes.m4 | 154 + missing | 336 + mkinstalldirs | 111 + netperf.spec.in | 55 + src/Makefile.am | 27 + src/Makefile.in | 586 + src/Makefile.uw | 106 + src/NetPerfDir/inet_ntop.c | 6 + src/NetPerfDir/makefile | 7 + src/NetPerfDir/sources | 29 + src/NetPerfDir/sources~ | 27 + src/NetServerDir/inet_ntop.c | 6 + src/NetServerDir/makefile | 7 + src/NetServerDir/sources | 28 + src/NetServerDir/sources~ | 26 + src/dirs | 3 + src/hist.h | 116 + src/missing/Makefile.am | 7 + src/missing/Makefile.in | 491 + src/missing/getaddrinfo.c | 605 + src/missing/getaddrinfo.h | 238 + src/missing/inet_ntop.c | 140 + src/missing/m4/Makefile.am | 1 + src/missing/m4/Makefile.in | 274 + src/missing/m4/herrno.m4 | 41 + src/missing/m4/in6addr.m4 | 89 + src/missing/m4/salen.m4 | 32 + src/missing/m4/sockaddrin6.m4 | 60 + src/missing/m4/sockinttypes.m4 | 154 + src/missing/m4/socklent.m4 | 81 + src/missing/m4/type_socklen_t.m4 | 25 + src/net_uuid.c | 336 + src/netcpu.h | 19 + src/netcpu_kstat.c | 413 + src/netcpu_kstat10.c | 600 + src/netcpu_looper.c | 655 + src/netcpu_none.c | 67 + src/netcpu_ntperf.c | 485 + src/netcpu_osx.c | 149 + src/netcpu_perfstat.c | 351 + src/netcpu_procstat.c | 353 + src/netcpu_pstat.c | 302 + src/netcpu_pstatnew.c | 398 + src/netcpu_sysctl.c | 132 + src/netdrv_ethtool.c | 119 + src/netdrv_none.c | 15 + src/netdrv_solaris.c | 67 + src/netlib.c | 4506 +++ src/netlib.h | 675 + src/netperf.c | 295 + src/netperf_version.h | 1 + src/netperf_version.h.in | 1 + src/netrt_none.c | 17 + src/netrt_rtmget.c | 419 + src/netrt_rtnetlink.c | 250 + src/netsec_linux.c | 148 + src/netsec_none.c | 37 + src/netserver.c | 1090 + src/netsh.c | 1160 + src/netsh.h | 184 + src/netslot_linux.c | 162 + src/netslot_none.c | 56 + src/netslot_solaris.c | 280 + src/netsys_hpux11i.c | 56 + src/netsys_linux.c | 138 + src/netsys_none.c | 8 + src/netsys_solaris.c | 179 + src/nettest_bsd.c | 13001 +++++++++ src/nettest_bsd.h | 635 + src/nettest_dlpi.c | 3798 +++ src/nettest_dlpi.h | 215 + src/nettest_omni.c | 6127 ++++ src/nettest_sctp.c | 4869 ++++ src/nettest_sctp.h | 128 + src/nettest_sdp.c | 3553 +++ src/nettest_sdp.h | 170 + src/nettest_unix.c | 3435 +++ src/nettest_unix.h | 198 + src/nettest_xti.c | 6025 ++++ src/nettest_xti.h | 264 + 138 files changed, 121146 insertions(+) create mode 100644 AUTHORS create mode 100644 COPYING create mode 100644 ChangeLog create mode 100644 INSTALL create mode 100644 Makefile.am create mode 100644 Makefile.in create mode 100644 NEWS create mode 100644 README create mode 100644 README.aix create mode 100644 README.hpux create mode 100644 README.osx create mode 100644 README.ovms create mode 100644 README.solaris create mode 100644 README.vmware create mode 100644 README.vmware~ create mode 100644 README.windows create mode 100644 Release_Notes create mode 100644 acinclude.m4 create mode 100644 aclocal.m4 create mode 100755 autogen.sh create mode 100755 config.guess create mode 100644 config.h.in create mode 100755 config.sub create mode 100755 configure create mode 100644 configure.ac create mode 100755 depcomp create mode 100644 doc/Makefile.am create mode 100644 doc/Makefile.in create mode 100644 doc/examples/Makefile.am create mode 100644 doc/examples/Makefile.in create mode 100755 doc/examples/arr_script create mode 100755 doc/examples/packet_byte_script create mode 100644 doc/examples/sctp_stream_script create mode 100755 doc/examples/snapshot_script create mode 100755 doc/examples/tcp_range_script create mode 100755 doc/examples/tcp_rr_script create mode 100755 doc/examples/tcp_stream_script create mode 100755 doc/examples/udp_rr_script create mode 100644 doc/examples/udp_stream_script create mode 100644 doc/netperf.info create mode 100644 doc/netperf.man create mode 100644 doc/netperf.texi create mode 100644 doc/netperf_old.ps create mode 100644 doc/netserver.man create mode 100644 doc/texinfo.tex create mode 100644 inet_ntop.c create mode 100755 install-sh create mode 100644 m4/.svn/all-wcprops create mode 100644 m4/.svn/entries create mode 100644 m4/.svn/format create mode 100644 m4/m4/.svn/all-wcprops create mode 100644 m4/m4/.svn/entries create mode 100644 m4/m4/.svn/format create mode 100644 m4/m4/.svn/text-base/salen.m4.svn-base create mode 100644 m4/m4/.svn/text-base/sockaddrin6.m4.svn-base create mode 100644 m4/m4/.svn/text-base/sockinttypes.m4.svn-base create mode 100644 m4/m4/salen.m4 create mode 100644 m4/m4/sockaddrin6.m4 create mode 100644 m4/m4/sockinttypes.m4 create mode 100755 missing create mode 100755 mkinstalldirs create mode 100644 netperf.spec.in create mode 100644 src/Makefile.am create mode 100644 src/Makefile.in create mode 100644 src/Makefile.uw create mode 100644 src/NetPerfDir/inet_ntop.c create mode 100644 src/NetPerfDir/makefile create mode 100644 src/NetPerfDir/sources create mode 100644 src/NetPerfDir/sources~ create mode 100644 src/NetServerDir/inet_ntop.c create mode 100644 src/NetServerDir/makefile create mode 100644 src/NetServerDir/sources create mode 100644 src/NetServerDir/sources~ create mode 100644 src/dirs create mode 100644 src/hist.h create mode 100644 src/missing/Makefile.am create mode 100644 src/missing/Makefile.in create mode 100644 src/missing/getaddrinfo.c create mode 100644 src/missing/getaddrinfo.h create mode 100644 src/missing/inet_ntop.c create mode 100644 src/missing/m4/Makefile.am create mode 100644 src/missing/m4/Makefile.in create mode 100644 src/missing/m4/herrno.m4 create mode 100644 src/missing/m4/in6addr.m4 create mode 100644 src/missing/m4/salen.m4 create mode 100644 src/missing/m4/sockaddrin6.m4 create mode 100644 src/missing/m4/sockinttypes.m4 create mode 100644 src/missing/m4/socklent.m4 create mode 100644 src/missing/m4/type_socklen_t.m4 create mode 100644 src/net_uuid.c create mode 100644 src/netcpu.h create mode 100644 src/netcpu_kstat.c create mode 100644 src/netcpu_kstat10.c create mode 100644 src/netcpu_looper.c create mode 100644 src/netcpu_none.c create mode 100644 src/netcpu_ntperf.c create mode 100644 src/netcpu_osx.c create mode 100644 src/netcpu_perfstat.c create mode 100644 src/netcpu_procstat.c create mode 100644 src/netcpu_pstat.c create mode 100644 src/netcpu_pstatnew.c create mode 100644 src/netcpu_sysctl.c create mode 100644 src/netdrv_ethtool.c create mode 100644 src/netdrv_none.c create mode 100644 src/netdrv_solaris.c create mode 100644 src/netlib.c create mode 100644 src/netlib.h create mode 100644 src/netperf.c create mode 100644 src/netperf_version.h create mode 100644 src/netperf_version.h.in create mode 100644 src/netrt_none.c create mode 100644 src/netrt_rtmget.c create mode 100644 src/netrt_rtnetlink.c create mode 100644 src/netsec_linux.c create mode 100644 src/netsec_none.c create mode 100644 src/netserver.c create mode 100644 src/netsh.c create mode 100644 src/netsh.h create mode 100644 src/netslot_linux.c create mode 100644 src/netslot_none.c create mode 100644 src/netslot_solaris.c create mode 100644 src/netsys_hpux11i.c create mode 100644 src/netsys_linux.c create mode 100644 src/netsys_none.c create mode 100644 src/netsys_solaris.c create mode 100644 src/nettest_bsd.c create mode 100644 src/nettest_bsd.h create mode 100644 src/nettest_dlpi.c create mode 100644 src/nettest_dlpi.h create mode 100644 src/nettest_omni.c create mode 100644 src/nettest_sctp.c create mode 100644 src/nettest_sctp.h create mode 100644 src/nettest_sdp.c create mode 100644 src/nettest_sdp.h create mode 100644 src/nettest_unix.c create mode 100644 src/nettest_unix.h create mode 100644 src/nettest_xti.c create mode 100644 src/nettest_xti.h diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 0000000..4692551 --- /dev/null +++ b/AUTHORS @@ -0,0 +1,234 @@ +This file is here for people to list their contributions to the +netperf benchmark. When you enhance or fix something, put your name +and a description of the what/where/whey/why/how here. If you like, +feel free to include an email address. + +I would like to apologize in advance to anyone I've forgotten to +include. + +Rick Jones +Responsible for initial packaging and release of netperf and +"editorial" continuity for subsequent releases. + +Karen Choy +Code to allow netserver to run as a standalone daemon. + +Dave Shield +Wrote the first revision of the netperf and netserver manpages. + +Sarr Blumson +Fixes for AIX 3.1 and 3.2. Also fixes for Solaris 2.1 without +realizing it ;-) + +Jeff Smits +Fixes for TCP_RR and UDP_RR on sytems with an htonl that is not a no-op. + +Warren Burnett +Example code for DLPI tests. + +Several Folks +Code to tell SunOS 4 to *not* restart system calls on receipt of a +signal. + +Fore Systems Inc. +Manpages for the FORE API and question answering + +David Channin +Access to systems running the Fore ATM API + +Jonathan Stone +Include file fixes for Ultrix + +Bruce Barnett +Bunches of warnings fixes and lint picks for Solaris 2.3 + +Herman Dierks et al +Code to calculate confidence intervals for tests + +Hal Murray +Helpful suggestions for the scripts to make them more compatible with +the netperf database (http://www.cup.hp.com/netperf/NetperfPage.html). +His prompting finally got me off my whatever to put the confidence +interval stuff from the guys at IBM into netperf + +Peter Skopp pds@cs.columbia.edu +Fixes to make netperf more secure. + +Tom Wilson +A fix to send_udp_rr to correct bogus throughput values. + +Thorsten Lockert +A bunch of clean-up for the *BSD OSes + +Serge Pachkovsky +Code for low-priority soaker process for AIX and SGI + +The fine folks at Adaptec +The initial port of netperf (1.9PL4) to Windows NT 3.51. + +Robin Callender +The PPC binaries for the 1.9PL4 port of netperf to NT and for assorted +code clean-ups and help with CPU utilization measurements. + +"Todd J. Derr" +For offering to take-on support of the Fore ATM API files with 2.1 and +for his help in making the tar files and such more user-friendly + +Michael Shuldman +Improvements to the makefile and additional checks for OpenBSD + +Kris Corwin +discovery of a debug statement outside of if (debug) that may have +been the cause of all the nasty connection refused errors in random +UDP_RR tests... + +Charles Harris +Initial prototype of the TCP_SENDFILE test support + +Philip Pishioneri of Cornel +Conversion of the netperf.ps manul to PDF format. + +The Hewlett-Packard OpenVMS folks +Assistance with the port to OpenVMS + +Munechika SUMIKAWA @ KAME Project / FreeBSD.org +IPv6 fixes + +Jan Iven of CERN +initial mods for sendfile() under Linux + +Fabrice Bacchella +for pointing-out that Solaris 9 has a copy of Linux sendfile() + +Andrew Gallatin +for assistance with the FreeBSD sysctl() stuff, and later making it +calibration-free +fixes to configure to recognize Solaris 11 +fixes to netcpu_procstat.c for later linux kernels + +Mark Cooper +pointing-out the need for -lresolv when compiling -DDO_DNS on RedHat +7.1 + +Carl Mascott +finding some cut-and-paste erors in create_data_socket error logging + +Fabrice Bacchella +Fixes for -DHISTOGRAM and -DUNIX on Mac OS X, updates to usage strings + +Spencer Frink +Fixes and Cleanup for WIN32. Many over many years. + +Nicholas Thomas +Fixes for DLPI on SVR4 Streams under Linux + +Dave Craig +Fixes for getaddrinfo error returns + +David Mosberger of HP +Workaround for the Linux getsockopt() bug that returns more than that +for which one asked. + +Stephen Burger of HP +Code to implement the netserver CPU binding. + +Vladislav "Vlad" Yasevich of HP +Initial SCTP tests. Enhancements to the configure.ac sources to show +the way to make many of the LIBS="foo" before ./configure unnecessary. + +Padmanabhan "Paddu" S N of HP +Patches for /proc/stat CPU util and recv_tcp_rr. + +Cary Coutant and other hp-mac-users of HP +Access to Mac OS X systems for porting netperf 2.4.0 + +Chris Bertin of HP +Access to AIX for initial porting of netperf 2.4.0 + +James Carlson +Assistance finding the right magic to compile SCTP on Solaris 10. + +Gavin +Pointers on Solaris 10 Microstate accounting. + +Brent Draney +Getting netcpu_perfstat.c in running order on AIX and other misc +fixups in places such as BSD. + +Samuel Ying +Change struct sockaddr to struct sockaddr storage in netserver.c + +Rodolpho Boer +Fix for default message size in UDP_STREAM when defualt SO_SNDBUF size +is > max UDP datagram size. + +Michael Dorff +Getting netperf/netserver to compile under Windows with MS Visual +Studio 2003 + +George Davis +Changes to deal with different floating-point formats. + +Anonymous +Changes to retrieve CPU util on MacOS X. + +Dickon Reed +Patches to attend to some windows in TCP_CRR and TCP_CC under Windows + +Bret McKee +Fixes to get netcpu_looper compiling and working after the "netcpu" +split + +Hans Blom +Improvements to closing/redirecting stdin/stdout/stderr in netserver + +Martin Brown +RPM support in the form of netperf.spec.in and related configure.ac +etc changes + +Shilpi Agarwal +Changes to allow UDP_STREAM to use connected sockets on both sides. + +Steve Reinhardt +Fixes for buffer filling. + +Gisle Vanem +Fixes for Windows compilation under MingW/gcc. + +Scott Weitzenkamp +Patches to enable demo mode in the UDP_STREAM test + +Emir Halepovic +Feedback on the manual + +Kouhei Sutou +Generate netperf_version.h and netperf.spec via configure rather than +makefile, include limits to get PathMAX on FreeBSD. + +Dan Yost +Fix to fflush() each interim result in demo mode to make things +happier for folks redirecting same to a file. + +Alexander Duyck +Fixes to replace struct sockaddr_in with struct sockaddr_storage +Fixes to UDP_RR to preclude hangs on Windows +Fizes to UDP_RR to honour -f and -B options + +Anonymous +Support for sendfile() on OSX + +Matt Waddel +Fix to use vfork() instead of fork() on platforms without fork() + +Simon Burge +Fixes for *BSD CPU util. + +Adam Bidema +Fixes for launching netserver children when the path to netserver.exe +is very long. + +Gisle Vanem +MingW cnd MSDOS (djgpp) leanups. + +Marcel Shuldman +Changes to make netperf more profiling friendly diff --git a/COPYING b/COPYING new file mode 100644 index 0000000..3f3ceb2 --- /dev/null +++ b/COPYING @@ -0,0 +1,43 @@ + + + Copyright (C) 1993 Hewlett-Packard Company + ALL RIGHTS RESERVED. + + The enclosed software and documentation includes copyrighted works + of Hewlett-Packard Co. For as long as you comply with the following + limitations, you are hereby authorized to (i) use, reproduce, and + modify the software and documentation, and to (ii) distribute the + software and documentation, including modifications, for + non-commercial purposes only. + + 1. The enclosed software and documentation is made available at no + charge in order to advance the general development of + high-performance networking products. + + 2. You may not delete any copyright notices contained in the + software or documentation. All hard copies, and copies in + source code or object code form, of the software or + documentation (including modifications) must contain at least + one of the copyright notices. + + 3. The enclosed software and documentation has not been subjected + to testing and quality control and is not a Hewlett-Packard Co. + product. At a future time, Hewlett-Packard Co. may or may not + offer a version of the software and documentation as a product. + + 4. THE SOFTWARE AND DOCUMENTATION IS PROVIDED "AS IS". + HEWLETT-PACKARD COMPANY DOES NOT WARRANT THAT THE USE, + REPRODUCTION, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR + DOCUMENTATION WILL NOT INFRINGE A THIRD PARTY'S INTELLECTUAL + PROPERTY RIGHTS. HP DOES NOT WARRANT THAT THE SOFTWARE OR + DOCUMENTATION IS ERROR FREE. HP DISCLAIMS ALL WARRANTIES, + EXPRESS AND IMPLIED, WITH REGARD TO THE SOFTWARE AND THE + DOCUMENTATION. HP SPECIFICALLY DISCLAIMS ALL WARRANTIES OF + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + + 5. HEWLETT-PACKARD COMPANY WILL NOT IN ANY EVENT BE LIABLE FOR ANY + DIRECT, INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES + (INCLUDING LOST PROFITS) RELATED TO ANY USE, REPRODUCTION, + MODIFICATION, OR DISTRIBUTION OF THE SOFTWARE OR DOCUMENTATION. + + diff --git a/ChangeLog b/ChangeLog new file mode 100644 index 0000000..f9402b1 --- /dev/null +++ b/ChangeLog @@ -0,0 +1 @@ +See the file Release_Notes. \ No newline at end of file diff --git a/INSTALL b/INSTALL new file mode 100644 index 0000000..54caf7c --- /dev/null +++ b/INSTALL @@ -0,0 +1,229 @@ +Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002 Free Software +Foundation, Inc. + + This file is free documentation; the Free Software Foundation gives +unlimited permission to copy, distribute and modify it. + +Basic Installation +================== + + These are generic installation instructions. + + The `configure' shell script attempts to guess correct values for +various system-dependent variables used during compilation. It uses +those values to create a `Makefile' in each directory of the package. +It may also create one or more `.h' files containing system-dependent +definitions. Finally, it creates a shell script `config.status' that +you can run in the future to recreate the current configuration, and a +file `config.log' containing compiler output (useful mainly for +debugging `configure'). + + It can also use an optional file (typically called `config.cache' +and enabled with `--cache-file=config.cache' or simply `-C') that saves +the results of its tests to speed up reconfiguring. (Caching is +disabled by default to prevent problems with accidental use of stale +cache files.) + + If you need to do unusual things to compile the package, please try +to figure out how `configure' could check whether to do them, and mail +diffs or instructions to the address given in the `README' so they can +be considered for the next release. If you are using the cache, and at +some point `config.cache' contains results you don't want to keep, you +may remove or edit it. + + The file `configure.ac' (or `configure.in') is used to create +`configure' by a program called `autoconf'. You only need +`configure.ac' if you want to change it or regenerate `configure' using +a newer version of `autoconf'. + +The simplest way to compile this package is: + + 1. `cd' to the directory containing the package's source code and type + `./configure' to configure the package for your system. If you're + using `csh' on an old version of System V, you might need to type + `sh ./configure' instead to prevent `csh' from trying to execute + `configure' itself. + + Running `configure' takes awhile. While running, it prints some + messages telling which features it is checking for. + + 2. Type `make' to compile the package. + + 3. Optionally, type `make check' to run any self-tests that come with + the package. + + 4. Type `make install' to install the programs and any data files and + documentation. + + 5. You can remove the program binaries and object files from the + source code directory by typing `make clean'. To also remove the + files that `configure' created (so you can compile the package for + a different kind of computer), type `make distclean'. There is + also a `make maintainer-clean' target, but that is intended mainly + for the package's developers. If you use it, you may have to get + all sorts of other programs in order to regenerate files that came + with the distribution. + +Compilers and Options +===================== + + Some systems require unusual options for compilation or linking that +the `configure' script does not know about. Run `./configure --help' +for details on some of the pertinent environment variables. + + You can give `configure' initial values for configuration parameters +by setting variables in the command line or in the environment. Here +is an example: + + ./configure CC=c89 CFLAGS=-O2 LIBS=-lposix + + *Note Defining Variables::, for more details. + +Compiling For Multiple Architectures +==================================== + + You can compile the package for more than one kind of computer at the +same time, by placing the object files for each architecture in their +own directory. To do this, you must use a version of `make' that +supports the `VPATH' variable, such as GNU `make'. `cd' to the +directory where you want the object files and executables to go and run +the `configure' script. `configure' automatically checks for the +source code in the directory that `configure' is in and in `..'. + + If you have to use a `make' that does not support the `VPATH' +variable, you have to compile the package for one architecture at a +time in the source code directory. After you have installed the +package for one architecture, use `make distclean' before reconfiguring +for another architecture. + +Installation Names +================== + + By default, `make install' will install the package's files in +`/usr/local/bin', `/usr/local/man', etc. You can specify an +installation prefix other than `/usr/local' by giving `configure' the +option `--prefix=PATH'. + + You can specify separate installation prefixes for +architecture-specific files and architecture-independent files. If you +give `configure' the option `--exec-prefix=PATH', the package will use +PATH as the prefix for installing programs and libraries. +Documentation and other data files will still use the regular prefix. + + In addition, if you use an unusual directory layout you can give +options like `--bindir=PATH' to specify different values for particular +kinds of files. Run `configure --help' for a list of the directories +you can set and what kinds of files go in them. + + If the package supports it, you can cause programs to be installed +with an extra prefix or suffix on their names by giving `configure' the +option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. + +Optional Features +================= + + Some packages pay attention to `--enable-FEATURE' options to +`configure', where FEATURE indicates an optional part of the package. +They may also pay attention to `--with-PACKAGE' options, where PACKAGE +is something like `gnu-as' or `x' (for the X Window System). The +`README' should mention any `--enable-' and `--with-' options that the +package recognizes. + + For packages that use the X Window System, `configure' can usually +find the X include and library files automatically, but if it doesn't, +you can use the `configure' options `--x-includes=DIR' and +`--x-libraries=DIR' to specify their locations. + +Specifying the System Type +========================== + + There may be some features `configure' cannot figure out +automatically, but needs to determine by the type of machine the package +will run on. Usually, assuming the package is built to be run on the +_same_ architectures, `configure' can figure that out, but if it prints +a message saying it cannot guess the machine type, give it the +`--build=TYPE' option. TYPE can either be a short name for the system +type, such as `sun4', or a canonical name which has the form: + + CPU-COMPANY-SYSTEM + +where SYSTEM can have one of these forms: + + OS KERNEL-OS + + See the file `config.sub' for the possible values of each field. If +`config.sub' isn't included in this package, then this package doesn't +need to know the machine type. + + If you are _building_ compiler tools for cross-compiling, you should +use the `--target=TYPE' option to select the type of system they will +produce code for. + + If you want to _use_ a cross compiler, that generates code for a +platform different from the build platform, you should specify the +"host" platform (i.e., that on which the generated programs will +eventually be run) with `--host=TYPE'. + +Sharing Defaults +================ + + If you want to set default values for `configure' scripts to share, +you can create a site shell script called `config.site' that gives +default values for variables like `CC', `cache_file', and `prefix'. +`configure' looks for `PREFIX/share/config.site' if it exists, then +`PREFIX/etc/config.site' if it exists. Or, you can set the +`CONFIG_SITE' environment variable to the location of the site script. +A warning: not all `configure' scripts look for a site script. + +Defining Variables +================== + + Variables not defined in a site shell script can be set in the +environment passed to `configure'. However, some packages may run +configure again during the build, and the customized values of these +variables may be lost. In order to avoid this problem, you should set +them in the `configure' command line, using `VAR=value'. For example: + + ./configure CC=/usr/local2/bin/gcc + +will cause the specified gcc to be used as the C compiler (unless it is +overridden in the site shell script). + +`configure' Invocation +====================== + + `configure' recognizes the following options to control how it +operates. + +`--help' +`-h' + Print a summary of the options to `configure', and exit. + +`--version' +`-V' + Print the version of Autoconf used to generate the `configure' + script, and exit. + +`--cache-file=FILE' + Enable the cache: use and save the results of the tests in FILE, + traditionally `config.cache'. FILE defaults to `/dev/null' to + disable caching. + +`--config-cache' +`-C' + Alias for `--cache-file=config.cache'. + +`--quiet' +`--silent' +`-q' + Do not print messages saying which checks are being made. To + suppress all normal output, redirect it to `/dev/null' (any error + messages will still be shown). + +`--srcdir=DIR' + Look for the package's source code in directory DIR. Usually + `configure' can determine that directory automatically. + +`configure' also accepts some other, not widely useful, options. Run +`configure --help' for more details. + diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 0000000..fbbd95e --- /dev/null +++ b/Makefile.am @@ -0,0 +1,4 @@ + +AUTOMAKE_OPTIONS = dist-bzip2 dist-zip +SUBDIRS = src doc +EXTRA_DIST = README.* Release_Notes inet_ntop.c autogen.sh m4 diff --git a/Makefile.in b/Makefile.in new file mode 100644 index 0000000..79cbcf3 --- /dev/null +++ b/Makefile.in @@ -0,0 +1,557 @@ +# Makefile.in generated by automake 1.7.9 from Makefile.am. +# @configure_input@ + +# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 +# Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +top_builddir = . + +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +INSTALL = @INSTALL@ +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +host_triplet = @host@ +ACLOCAL = @ACLOCAL@ +AMDEP_FALSE = @AMDEP_FALSE@ +AMDEP_TRUE = @AMDEP_TRUE@ +AMTAR = @AMTAR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +GREP = @GREP@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +NEED_LIBCOMPAT_FALSE = @NEED_LIBCOMPAT_FALSE@ +NEED_LIBCOMPAT_TRUE = @NEED_LIBCOMPAT_TRUE@ +NETCPU_SOURCE = @NETCPU_SOURCE@ +NETDRVLKUP_SOURCE = @NETDRVLKUP_SOURCE@ +NETRTLKUP_SOURCE = @NETRTLKUP_SOURCE@ +NETSECLKUP_SOURCE = @NETSECLKUP_SOURCE@ +NETSLOTLKUP_SOURCE = @NETSLOTLKUP_SOURCE@ +NETSYSLKUP_SOURCE = @NETSYSLKUP_SOURCE@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +ac_ct_CC = @ac_ct_CC@ +am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ +am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +sysconfdir = @sysconfdir@ +target = @target@ +target_alias = @target_alias@ +target_cpu = @target_cpu@ +target_os = @target_os@ +target_vendor = @target_vendor@ + +AUTOMAKE_OPTIONS = dist-bzip2 dist-zip +SUBDIRS = src doc +EXTRA_DIST = README.* Release_Notes inet_ntop.c autogen.sh m4 +subdir = . +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = config.h +CONFIG_CLEAN_FILES = netperf.spec +DIST_SOURCES = + +RECURSIVE_TARGETS = info-recursive dvi-recursive pdf-recursive \ + ps-recursive install-info-recursive uninstall-info-recursive \ + all-recursive install-data-recursive install-exec-recursive \ + installdirs-recursive install-recursive uninstall-recursive \ + check-recursive installcheck-recursive +DIST_COMMON = README $(srcdir)/Makefile.in $(srcdir)/configure AUTHORS \ + COPYING ChangeLog INSTALL Makefile.am NEWS acinclude.m4 \ + aclocal.m4 config.guess config.h.in config.sub configure \ + configure.ac depcomp install-sh missing mkinstalldirs \ + netperf.spec.in +DIST_SUBDIRS = $(SUBDIRS) +all: config.h + $(MAKE) $(AM_MAKEFLAGS) all-recursive + +.SUFFIXES: + +am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ + configure.lineno +$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.ac $(ACLOCAL_M4) + cd $(top_srcdir) && \ + $(AUTOMAKE) --gnu Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe) + +$(top_builddir)/config.status: $(srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + $(SHELL) ./config.status --recheck +$(srcdir)/configure: $(srcdir)/configure.ac $(ACLOCAL_M4) $(CONFIGURE_DEPENDENCIES) + cd $(srcdir) && $(AUTOCONF) + +$(ACLOCAL_M4): configure.ac acinclude.m4 + cd $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) + +config.h: stamp-h1 + @if test ! -f $@; then \ + rm -f stamp-h1; \ + $(MAKE) stamp-h1; \ + else :; fi + +stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status + @rm -f stamp-h1 + cd $(top_builddir) && $(SHELL) ./config.status config.h + +$(srcdir)/config.h.in: $(top_srcdir)/configure.ac $(ACLOCAL_M4) + cd $(top_srcdir) && $(AUTOHEADER) + touch $(srcdir)/config.h.in + +distclean-hdr: + -rm -f config.h stamp-h1 +netperf.spec: $(top_builddir)/config.status netperf.spec.in + cd $(top_builddir) && $(SHELL) ./config.status $@ +uninstall-info-am: + +# This directory's subdirectories are mostly independent; you can cd +# into them and run `make' without going through this Makefile. +# To change the values of `make' variables: instead of editing Makefiles, +# (1) if the variable is set in `config.status', edit `config.status' +# (which will cause the Makefiles to be regenerated when you run `make'); +# (2) otherwise, pass the desired values on the `make' command line. +$(RECURSIVE_TARGETS): + @set fnord $$MAKEFLAGS; amf=$$2; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +mostlyclean-recursive clean-recursive distclean-recursive \ +maintainer-clean-recursive: + @set fnord $$MAKEFLAGS; amf=$$2; \ + dot_seen=no; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + rev=''; for subdir in $$list; do \ + if test "$$subdir" = "."; then :; else \ + rev="$$subdir $$rev"; \ + fi; \ + done; \ + rev="$$rev ."; \ + target=`echo $@ | sed s/-recursive//`; \ + for subdir in $$rev; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ + done && test -z "$$fail" +tags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ + done +ctags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ + done + +ETAGS = etags +ETAGSFLAGS = + +CTAGS = ctags +CTAGSFLAGS = + +tags: TAGS + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + mkid -fID $$unique + +TAGS: tags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + if (etags --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + else \ + include_option=--include; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test -f $$subdir/TAGS && \ + tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ + list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(ETAGS_ARGS)$$tags$$unique" \ + || $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$tags $$unique + +ctags: CTAGS +CTAGS: ctags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(CTAGS_ARGS)$$tags$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$tags $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && cd $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) $$here + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) + +top_distdir = . +distdir = $(PACKAGE)-$(VERSION) + +am__remove_distdir = \ + { test ! -d $(distdir) \ + || { find $(distdir) -type d ! -perm -200 -exec chmod u+w {} ';' \ + && rm -fr $(distdir); }; } + +GZIP_ENV = --best +distuninstallcheck_listfiles = find . -type f -print +distcleancheck_listfiles = find . -type f -print + +distdir: $(DISTFILES) + $(am__remove_distdir) + mkdir $(distdir) + $(mkinstalldirs) $(distdir)/. $(distdir)/src + @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ + list='$(DISTFILES)'; for file in $$list; do \ + case $$file in \ + $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ + $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ + esac; \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test "$$dir" != "$$file" && test "$$dir" != "."; then \ + dir="/$$dir"; \ + $(mkinstalldirs) "$(distdir)$$dir"; \ + else \ + dir=''; \ + fi; \ + if test -d $$d/$$file; then \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test -d $(distdir)/$$subdir \ + || mkdir $(distdir)/$$subdir \ + || exit 1; \ + (cd $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$(top_distdir)" \ + distdir=../$(distdir)/$$subdir \ + distdir) \ + || exit 1; \ + fi; \ + done + -find $(distdir) -type d ! -perm -777 -exec chmod a+rwx {} \; -o \ + ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ + ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ + ! -type d ! -perm -444 -exec $(SHELL) $(install_sh) -c -m a+r {} {} \; \ + || chmod -R a+r $(distdir) +dist-gzip: distdir + $(AMTAR) chof - $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz + $(am__remove_distdir) + +dist-bzip2: distdir + $(AMTAR) chof - $(distdir) | bzip2 -9 -c >$(distdir).tar.bz2 + $(am__remove_distdir) + +dist-zip: distdir + -rm -f $(distdir).zip + zip -rq $(distdir).zip $(distdir) + $(am__remove_distdir) + +dist dist-all: distdir + $(AMTAR) chof - $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz + $(AMTAR) chof - $(distdir) | bzip2 -9 -c >$(distdir).tar.bz2 + -rm -f $(distdir).zip + zip -rq $(distdir).zip $(distdir) + $(am__remove_distdir) + +# This target untars the dist file and tries a VPATH configuration. Then +# it guarantees that the distribution is self-contained by making another +# tarfile. +distcheck: dist + $(am__remove_distdir) + GZIP=$(GZIP_ENV) gunzip -c $(distdir).tar.gz | $(AMTAR) xf - + chmod -R a-w $(distdir); chmod a+w $(distdir) + mkdir $(distdir)/_build + mkdir $(distdir)/_inst + chmod a-w $(distdir) + dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ + && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ + && cd $(distdir)/_build \ + && ../configure --srcdir=.. --prefix="$$dc_install_base" \ + $(DISTCHECK_CONFIGURE_FLAGS) \ + && $(MAKE) $(AM_MAKEFLAGS) \ + && $(MAKE) $(AM_MAKEFLAGS) dvi \ + && $(MAKE) $(AM_MAKEFLAGS) check \ + && $(MAKE) $(AM_MAKEFLAGS) install \ + && $(MAKE) $(AM_MAKEFLAGS) installcheck \ + && $(MAKE) $(AM_MAKEFLAGS) uninstall \ + && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ + distuninstallcheck \ + && chmod -R a-w "$$dc_install_base" \ + && ({ \ + (cd ../.. && $(mkinstalldirs) "$$dc_destdir") \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ + distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ + } || { rm -rf "$$dc_destdir"; exit 1; }) \ + && rm -rf "$$dc_destdir" \ + && $(MAKE) $(AM_MAKEFLAGS) dist-gzip \ + && rm -f $(distdir).tar.gz \ + && $(MAKE) $(AM_MAKEFLAGS) distcleancheck + $(am__remove_distdir) + @echo "$(distdir).tar.gz is ready for distribution" | \ + sed 'h;s/./=/g;p;x;p;x' +distuninstallcheck: + @cd $(distuninstallcheck_dir) \ + && test `$(distuninstallcheck_listfiles) | wc -l` -le 1 \ + || { echo "ERROR: files left after uninstall:" ; \ + if test -n "$(DESTDIR)"; then \ + echo " (check DESTDIR support)"; \ + fi ; \ + $(distuninstallcheck_listfiles) ; \ + exit 1; } >&2 +distcleancheck: distclean + @if test '$(srcdir)' = . ; then \ + echo "ERROR: distcleancheck can only run from a VPATH build" ; \ + exit 1 ; \ + fi + @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ + || { echo "ERROR: files left in build directory after distclean:" ; \ + $(distcleancheck_listfiles) ; \ + exit 1; } >&2 +check-am: all-am +check: check-recursive +all-am: Makefile config.h +installdirs: installdirs-recursive +installdirs-am: + +install: install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-recursive +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -rm -f $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-recursive + +clean-am: clean-generic mostlyclean-am + +distclean: distclean-recursive + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -f Makefile +distclean-am: clean-am distclean-generic distclean-hdr distclean-tags + +dvi: dvi-recursive + +dvi-am: + +info: info-recursive + +info-am: + +install-data-am: + +install-exec-am: + +install-info: install-info-recursive + +install-man: + +installcheck-am: + +maintainer-clean: maintainer-clean-recursive + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -rf $(top_srcdir)/autom4te.cache + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-recursive + +mostlyclean-am: mostlyclean-generic + +pdf: pdf-recursive + +pdf-am: + +ps: ps-recursive + +ps-am: + +uninstall-am: uninstall-info-am + +uninstall-info: uninstall-info-recursive + +.PHONY: $(RECURSIVE_TARGETS) CTAGS GTAGS all all-am check check-am clean \ + clean-generic clean-recursive ctags ctags-recursive dist \ + dist-all dist-bzip2 dist-gzip dist-zip distcheck distclean \ + distclean-generic distclean-hdr distclean-recursive \ + distclean-tags distcleancheck distdir distuninstallcheck dvi \ + dvi-am dvi-recursive info info-am info-recursive install \ + install-am install-data install-data-am install-data-recursive \ + install-exec install-exec-am install-exec-recursive \ + install-info install-info-am install-info-recursive install-man \ + install-recursive install-strip installcheck installcheck-am \ + installdirs installdirs-am installdirs-recursive \ + maintainer-clean maintainer-clean-generic \ + maintainer-clean-recursive mostlyclean mostlyclean-generic \ + mostlyclean-recursive pdf pdf-am pdf-recursive ps ps-am \ + ps-recursive tags tags-recursive uninstall uninstall-am \ + uninstall-info-am uninstall-info-recursive uninstall-recursive + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/NEWS b/NEWS new file mode 100644 index 0000000..e69de29 diff --git a/README b/README new file mode 100644 index 0000000..7745b96 --- /dev/null +++ b/README @@ -0,0 +1,49 @@ + +BE SURE TO READ THE MANUAL. EVEN THOUGH IT MAY BE OUTDATED. + +This is a brief readme file for the netperf TCP/UDP/sockets/etc +performance benchmark. This is here mostly as a boot-strap. The real +information is in the manual, which can be found in netperf.ps and +online from http://www.netperf.org/netperf/NetperfPage.html. The +sources, and a limited number of binaries, can be found from +ftp://ftp.cup.hp.com/dist/networking/benchmarks/netperf/ . + +BE SURE TO READ THE MANUAL. EVEN THOUGH IT MAY BE OUTDATED. + +There is a COPYRIGHT file included. It is called COPYING because that +is what autosomethingorother wanted. It is based on what the HP Legal +Eagles gave me. I am not sure if the legalese is clear, but the intent +is to say "Here is a benchmark. Use it in good health. Pass it along, +port it, enhance it. You didn't pay for this tool, so don't expect it +to be perfect ;-)" The rest of it is there to keep the layers happy... + +While the copyright is pretty much in spirit an "open source" one, it +is not in letter - I never took the time to try to get it approved. +If you feel strongly about the license of the code you use and want +something under the GPL, consider netperf4: + +http://www.netperf.org/svn/netperf4/trunk + +Feel free to report netperf results in public forums, but please be +excruciatingly complete in your description of the test envorinment. +The old netperf database at: + + http://www.netperf.org/netperf/NetperfPage.html + +is no more - or rather the utilities for accessing it no longer run. +The data is still present in the tree, albeit _VERY_ old now. + +There is an Internet mailing list devoted to netperf. It is called +netperf-talk and it is hosted on netperf.org. Subscription requests +should go to netperf-talk-request@netperf.org. + +Please DO NOT SEND subscription requests to netperf-talk! + +If you run into severe difficulties, or are just feeling chatty, +please feel free to drop some email to me - Rick Jones +. Be sure to include a meaningful subject lines. + +happy benchmarking, +rick jones + +BE SURE TO READ THE MANUAL. EVEN THOUGH IT MAY BE OUTDATED. diff --git a/README.aix b/README.aix new file mode 100644 index 0000000..2e57b64 --- /dev/null +++ b/README.aix @@ -0,0 +1,24 @@ +Pseudo-random things about netperf on AIX: + +While it _should_ not be necessary in the release bits, the rc bits +for netperf 2.4.0 required: + + configure _may_ need: + + CFLAGS="-qcpluscmt -lperfstat" + + until such time as Rick Jones can figure-out or be told how to + automagically add those using the configure script (hint hint :) + +The release bits should be OK without the above. Depending on the +name used to invoke the compiler, the -qmumble option may be implicit. + +AIX include files have a VERY unfortuneate set of #define's in them +for phrases network oriented programs are QUITE likely to have in +their source - "rem_addr" and "rem_size" A "cousin" of the Netperf +Contributing Editor reports this interferes with --enable-dlpi +compilation and that it was also a problem for MySQL compiltion. +While we await IBM's APAR with bated breath, netperf has been kludged +to workaround this bug in IBM's include files. It has been reported +that a "PMR" 34940,212,848 has been submitted to IBM in relation to +this bug in their header files. diff --git a/README.hpux b/README.hpux new file mode 100644 index 0000000..7818449 --- /dev/null +++ b/README.hpux @@ -0,0 +1,31 @@ +A note about CPU utilization... + +For HP-UX 11.0 <= system < 11.23 the configure script will select the +"pstat" CPU utilization mechanism. This mechanism is the familiar +HP-UX idle counter mechanism (for all incense and porpoises) and +requires calibration. See src/netcpu_pstat.c for all the details. + +For HP-UX 11.23 >= system, the configure script will select the +"pstatnew" CPU utilization mechanism. 11.23 adds cycle counts for +user, kernel and interrupt modes to the idle cycle counter. As such, +it _should_ be possible to simply take the sum of the four and the +fractions and know how much time was spent in each mode. +HOWEVER... there is a bug in the accounting for interrupt cycles, +where interrupt cycles go missing. SOOO, since there is an accurate +way to know what the total number of cycles should have been over the +interval, and we know (ass-u-me) that the idle cycle counter is good +(since the pstat mechanism has tested that one OK), we will take the +ratio of idle to total cycles to compute CPU util. + +We will still calculate fractions for user, kernel and interrupt, and +report them in debug (-d) output, but with a warning for interrupt +time. See src/netcpu_pstatnew.c for all the details. + +Up through HP-UX 11.23 (aka 11iV2) if you enable burst mode, and +happen to send sub-MSS requests and/or responses you _cannot_ assume +that the packet per second rate on the wire will match the transaction +per second rate reported by netperf, even if you set TCP_NODELAY with +the test-specific -D option. The HP-UX 11.X TCP stack likely will be +generating some immediate 'standalone' ACKnowledgements which may not +be generated by other stacks. This has been reported to the HP-UX TCP +folks, and an announcement will be made when that issue is resolved. diff --git a/README.osx b/README.osx new file mode 100644 index 0000000..eb5dbe5 --- /dev/null +++ b/README.osx @@ -0,0 +1,4 @@ +If you are reading this, it suggests you are using a version of +netperf in which the issue of file/directory name case insensitivity +in OSX has been worked-around by renaming the NetPerf and NetServer +directories to NetPerfDir and NetServerDir respectively. diff --git a/README.ovms b/README.ovms new file mode 100644 index 0000000..f37b89d --- /dev/null +++ b/README.ovms @@ -0,0 +1,66 @@ +February 11, 2003 + +At the time of the initial port, I was not aware of a make facility +for OpenVMS. So, I would just compile and link the various files by +hand: + + $ cc netperf.c + $ cc netlib.c + $ cc netsh.c + $ cc nettest_bsd.c + $ cc netserver.c + $ link/exe=netperf netperf.obj,netsh.obj,netlib.obj,nettest_bsd.obj + $ link/exe=netserver netserver.obj,netsh.obj,netlib.obj,nettest_bsd.obj + +Installation for OpenVMS has a few differences from installation under +say Unix. There is no inetd for VMS - however, there is the concept +of an adding an auxilliary service that seems quite similar. + +To configure netperf for operation as an auxilliary service, you will +need to edit/use the netserver_run.com file and alter the "path" to +netserver accordingly. The version that ships is setup for where Rick +Jones did his initial porting work and most likely is not apropriate +for you :) + + $ define sys$output sys$sysroot:[netperf]hello_service.log + $ define sys$error sys$sysroot:[netperf]hello_service.log + $ run sys$sysroot:[netperf]netserver.exe + +Then it will be necessary to "define" netperf (netserver) as an +auxilliary service. This will need to be customized as apropriate for +your system + + $ tcpip set service netserver - + _$ /port=12865 - + _$ /protocol=tcp - + _$ /user=system - + _$ /limit=48 - + _$ /process_name=netserver - + _$ /file=sys$sysroot:[netperf]netserver_run.com + +And then it is necessary to enable the service: + +$ tcpip enable service netserver + +If you want to disable the service, you can issue the command + +$ tcpip set noservice netserver + +By default, OpenVMS is case-insensitive with commandlines, and will +downshift everything to lower case. This does not interact well with +netperf's use of command-line options like "-H" and "-h" with rather +different meanings. + +To workaround that, the following defines are believed to be +sufficient. + +$ define DECC$ARGV_PARSE_STYLE ENABLE +$ define DECC$EFS_CASE_PRESERVE ENABLE +$ define DECC$POSIX_SEEK_STREAM_FILE ENABLE +$ define DECC$EFS_CHARSET ENABLE +$ set process /parse_style=extended + +I do not know if this will be something one can also do for the +netserver - presumeably one could put these things in the +netserver_run.com file (guessing). At present though I've not tried +that, and I'm also not sure that netserver has any upper-case options. diff --git a/README.solaris b/README.solaris new file mode 100644 index 0000000..c60ca10 --- /dev/null +++ b/README.solaris @@ -0,0 +1,29 @@ +Until the release bits the following was true: + + Until such time as Rick Jones can figure-out or be told how to make it + automagic in the configure script, prior to configure on solaris, you + may need: + + CFLAGS="-lsocket -lnsl -lkstat" + + and if you are trying to compile the SCTP tests: + + CFLAGS="-lxnet -lsocket -lnsl -lkstat -D_XOPEN_SOURCE=500 -D__EXTENSIONS__" + +as the release bits have a "smarter" configure script, and the SCTP +tests use libsctp, the above no longer applies. It should all just be +automagic (although for SCTP you still must --enable-sctp at configure +time) + +Beware CPU util figures on anything before Solaris 10 that does not +say 100%, and still be a triffle cautious with Solaris 10 CPU util +reports. The CPU time accounting mechanisms either do not track time +spent servicing interrupts, or do so in parallel with time spent in +user/kernel/idle which means that some idle time isn't _really_ idle +time. + +And beyond that, it is still not clear if the CPU utilization reported +on systems with hardware threading support (eg UltraSPARC-T1) is +really accurate even ignoring the issue with interrupt time. It is +likely that to be truely accurate, it is necessary to know how much +"real work" any one strand performed. diff --git a/README.vmware b/README.vmware new file mode 100644 index 0000000..02996d2 --- /dev/null +++ b/README.vmware @@ -0,0 +1,15 @@ +Compiling for VMware is somewhat like compiling for Windows - there is +a separate, standalone makefile one uses. In this case, it is +src/Makefile.uw. So, to build the bits, cd to src/ and make -f +Makefile.uw. + +At present, the makefile is setup to use a number of the "none" files +- in particular netcpu_none.c. When/if we enable the "omni" tests +we'll perhaps see the addition of a number of other "none" files as +well. + +Also, seems the way things are "run" under VMware is enough different +that the scripts, should you chose to use them, will need to be +modified. The initial set of patches make some arbitrary changes that +need to be re-worked with some "To run this under VMware uncomment +this line" or somesuch. diff --git a/README.vmware~ b/README.vmware~ new file mode 100644 index 0000000..15a2854 --- /dev/null +++ b/README.vmware~ @@ -0,0 +1,9 @@ +Compiling for VMware is somewhat like compiling for Windows - there is +a separate, standalone makefile one uses. In this case, it is +src/Makefile.uw. + +Also, seems the way things are "run" under VMware is enough different +that the scripts, should you chose to use them, will need to be +modified. The initial set of patches make some arbitrary changes that +need to be re-worked with some "To run this under VMware uncomment +this line" or somesuch. diff --git a/README.windows b/README.windows new file mode 100644 index 0000000..db945f5 --- /dev/null +++ b/README.windows @@ -0,0 +1,106 @@ +It has been reported that versions of netperf have configured and +compiled under Cygwin. + +It is also known that netperf has compiled using the Windows DDK. +Here is a skeleton of the instructions to do so: + +Steps are: + +A) Install the Windows driver developer kit (if not already done). + +B) open a Cmd windows (i.e., a DOS box) for the target environment + (target OS version; free vs checked build; x86, AMD64, or IA64). + This is picked from the "Start\Developer Kits" path. + +C) enter the src\NetPerfDir directory + +D) Edit sources to enable any desired optional features (eg + -DWANT_HISTOGRAM) or to remove features which your version of + Windows might not support (eg -DHAVE_STRUCT_SOCKADDR_STORAGE) + +E) while still in the src\NetperfDir directory type "build /cD". + +F) Repeat steps C through E in src\NetServerDir + +G) the target files will be in a directory like: + NetPerfDir\objchk_wnet_IA64\IA64, NetServerDir\objchk_wnet_IA64\IA64 + NetPerfDir\objfre_wnet_x86\i386, or NetPerfDir\objfre_wnet_AMD64\amd64 + +NOTE: If any components of the path (ie the full names of the files, +including parent directories) contain spaces (eg "My Documents"), +build will charge off into the weeds. + +And if that weren't enough, it is also known that netperf has been +compiled using MS Visual Studio 2003. Here are the instructions from +the person who made that work (See Authors): + +1. Under the PROJECT tab, PROPERTIES, LINKER folder, +Select COMMAND LINE and add WS2_32.lib in the whitespace labeled +Additional Options: + + +2. Under the PROJECT tab, PROPERTIES, C/C++ foleder, +Select Preprocessor, On the right, add DO_IPV6; at the end of the +Preprocessor Definitions whitespace. + + +He goes on to say: + +NOTE: WHEN COMPLING NETSERVER, it works, but I got issued the +foillowing warnigns in my build: + + +------ Rebuild All started: Project: netserver, Configuration: Debug Win32 ------ + +Deleting intermediate files and output files for project 'netserver', configuration 'Debug|Win32'. + +Compiling... + +nettest_bsd.c + +g:\Program Files\netperf\netperf-2.4.1rc1\src\nettest_bsd.c(846) : warning C4267: 'function' : conversion from 'size_t' to 'int', possible loss of data + +g:\Program Files\netperf\netperf-2.4.1rc1\src\nettest_bsd.c(1303) : warning C4267: 'function' : conversion from 'size_t' to 'int', possible loss of data + +g:\Program Files\netperf\netperf-2.4.1rc1\src\nettest_bsd.c(2020) : warning C4267: 'function' : conversion from 'size_t' to 'int', possible loss of data + +g:\Program Files\netperf\netperf-2.4.1rc1\src\nettest_bsd.c(5080) : warning C4267: 'function' : conversion from 'size_t' to 'int', possible loss of data + +g:\Program Files\netperf\netperf-2.4.1rc1\src\nettest_bsd.c(5715) : warning C4267: 'function' : conversion from 'size_t' to 'int', possible loss of data + +g:\Program Files\netperf\netperf-2.4.1rc1\src\nettest_bsd.c(6591) : warning C4267: 'function' : conversion from 'size_t' to 'int', possible loss of data + +g:\Program Files\netperf\netperf-2.4.1rc1\src\nettest_bsd.c(8013) : warning C4267: 'function' : conversion from 'size_t' to 'int', possible loss of data + +g:\Program Files\netperf\netperf-2.4.1rc1\src\nettest_bsd.c(11123) : warning C4267: 'function' : conversion from 'size_t' to 'int', possible loss of data + +netsh.c + +netserver.c + +g:\Program Files\netperf\netperf-2.4.1rc1\src\netserver.c(457) : warning C4267: 'function' : conversion from 'size_t' to 'int', possible loss of data + +netlib.c + +g:\Program Files\netperf\netperf-2.4.1rc1\src\netlib.c(2470) : warning C4267: 'function' : conversion from 'size_t' to 'int', possible loss of data + +g:\Program Files\netperf\netperf-2.4.1rc1\src\netlib.c(2480) : warning C4267: 'function' : conversion from 'size_t' to 'int', possible loss of data + +netcpu_ntperf.c + +inet_ntop.c + +Generating Code... + +Linking... + +Build log was saved at "file://g:\Documents and Settings\Administrator\My Documents\Visual Studio Projects\netserver\Debug\BuildLog.htm" + +netserver - 0 error(s), 11 warning(s) + + + +---------------------- Done ---------------------- + +Rebuild All: 1 succeeded, 0 failed, 0 skipped + diff --git a/Release_Notes b/Release_Notes new file mode 100644 index 0000000..f308413 --- /dev/null +++ b/Release_Notes @@ -0,0 +1,856 @@ +These are the Release Notes leading-up to Revision 2.4.5 of netperf: + +Things changed in this release: + +*) Fixes for Linux procstat-based CPU utilization on newer kernels + from Andrew Gallatin. + +*) Fix for a TCP_RR hang from Michael Shuldman + +*) Compilation cleanups for MingW cnd MSDOS (djgpp) ourtesy of Gisle + Vanem. + +*) Changes to enable compilation and building of netperf for + VMware. Kudos to the person who did the first port, I will be happy + to name that person when told it is OK :) + +*) Fixes from Adam Bidema for launching netserver children when the + path to netserver.exe is very long. + +*) For the first time, netperf2 has a dependency, albeit optional, on + another non-base-os bit of code - libsmbios under Linux. It will + attept to detect this at compile time and use it to report the + system model name in an omni test. If libsmbios is there we will + try to use it, otherwise we will not. If the associated include + file is also there (eg the -dev package in apt-get-speak), we will + use it to get the prototype for SMBIOSGetSystemName, otherwise we + make a guess as to the prototype for SMBIOSGetSystemName(), which + is the only call we make to libsmbios. + +*) Fixes for BSD CPU utilization to deal with different BSD variants + using different types. Courtesy of Simon Burge + +*) The "omni" suite has been added on an experimental basis. If it + works-out then many of the tests in src/nettest_bsd.c, + src/nettest_sdp.c, and src/nettest_sctp.c will be "migrated" to use + the "omni infrastructure" (aka two routines to measure them + all...). Apart from reduced socket code, the omni suite has + user-configurable output in either "human readable," CSV or + keyword=value format. By default, a VERY large quantity of data is + output when asking for csv format (test-specific -o option) or + keyword format (test-specific -k option). The omni suite is not + yet documented (there are some as-yet undiagnosed problems with + doc/netperf.texi in emacs texinfo mode and updating nodes and links + and such - any help there would be appreciated) but there is a + small text file in doc/ describing the names (most) of the + available output's. For the most up-to-date list consult + src/nettest_omni.c and the enum netperf_output_name. Or, you can + pass-in a "filename" of '?' to either of the -O, -o or -k options + and netperf will emit a list of the known available outputs. + +*) Coming along for the ride are some new platform specific files to + determine the probable egress interface for each end of a test, as + well as driver information for that interface. There is also + reporting of "uname" like information for both local and remote + system, and eventually perhaps something about the vendor's model + name for the systems as well as the processor types. The end goal + is to make it easy to get most if not all what one would want in a + database of netperf results. + +*) The UDP_RR test now understands the global -f option to change + output units. It also understands the -B option to tag + results. Courtesy of Alexander Duyck. + +*) A fix has been added for hanging UDP_RR tests under + Windows. Courtesy of Alexander Duyck. + +*) Use vfork() on those platforms without fork(), courtesy of Matt + Waddel + +*) Track the bouncing interfaces that are linux processor affinity + +*) Fixes for Solaris sendfilev usage. + +*) A TCP_MSS test has been added which will report the MSS for a data + connection setup as if the test were a TCP_STREAM test. While the + remote (netserver) is tricked into thinking it is to accept a + TCP_STREAM test, no actual data will flow over the connection. + This means that if the MSS is one which might change over the life + of the connection, it will not be reflected in the test output. + Should this prove to be a problem a single send() can be arranged + along with the return of the shutdown();recv() handshake. + + The idea is that this might be useful for netperf scripts wanting + to parameterize things based on the MSS - for example the + packet_byte_script. + +*) The width of the confidence interval can be specified in fractions + of a percent for the confidence of a clean, close, comfortable + calculation. :) + +*) Honor the global -B option in a TCP_SENDFILE test. + +*) Correct the sense of Send/Recv in the banner of a TCP_MAERTS test. + +These are the Release Notes for Revision 2.4.4 of netperf: + +Things changed in this release: + +*) The LOC_CPU and REM_CPU tests will report their respective beliefs + as to the number of CPUs present when the verbosity is set to more + than one. This can be used when trying to diagnose issues with CPU + utilization. + +*) A kind soul who wishes to remain anonymous provided a patch to + enable use of sendfile() on OSX. + +*) Fix a misplaced \n in a format string of send_tcp_maerts, courtesy + of Alexander Duyck. + +*) There is an experimental global -r option which will allow one to + include CPU utilization measurements, but make the decision about + hitting confidence based on the result only. The test banner will + reflects this when -r is used. + +*) It is no longer necessary to specify a file with the global -F + option when running a _SENDFILE test. Netperf will create a + temporary file and populate it with random data and use that. If + running aggregate tests it is strongly suggested one use a -F + option. Otherwise, the overhead spent creating and populating the + temporary file will be included in the CPU utilization calculation. + +*) The configure script recognizes Solaris 11 and selects the correct + CPU utilization mechanism - or rather it selects the same mechanism + as is used in Solaris 10. Fix courtesy of Andrew Gallatin. + +*) Convert a number of struct sockaddr_in's to struct + sockaddr_storage's and add requisite casts to deal with some abort + problems on Windows and perhaps other platforms as well. Kudos to + Alexander Duyck. + +*) One can now pass a value of 'x' to the global -f option to specify + the units as transactions per second. This is the default for any + request/response test, which is determined by there being a "double + `r'" in the name - eg "RR," "rr," "Rr," or "rR." At present only + the TCP_RR test actually looks for this to be set. + +*) One can request bits/bytes per second as the primary output of a + TCP_RR test by setting the global -f option to [kmgKMG] as with any + of the "STREAM" tests. This converts the primary throughput metric + to a bitrate (byterate) following the verbosity rules for a STREAM + test. Service demand remains usec/Transaction regardless of the + setting of the global -f option. + + A verbosity level of 2 or more will cause the TCP_RR test to report + calculated average RTT latency, transaction rate, and inbound and + outbound transfer rates regardless of the primary units selected + with the global -f paramter. If the primary output is transactions + per second, the reported inbound and outbound transfer rates will + be 10^6 bits per second, otherwise, they honor the setting of the + global -f option. + + All of this is EXPERIMENTAL and subject to change without prior + notice in future versions of netperf. + +*) Replace "break" with "break 2" in acinclude.m4 for a socklen macro + +*) The default for the requested socket buffer size is changed from 0 + to -1 to enable passing a value of 0 under Windows, which tells that + stack one wishes to enable copy-avoidance. + +*) Call fflush() on each interim result displayed in demo mode to make + things happier for folks redirecting same to a file. From Dan + Yost. + +*) In theory each distinct netserver child will have a debug log with + its pid appended to the name, somewhat like what appears to happen + under Windows. + +*) A new global, command-line option to netperf and netserver has been + added. The -V option will cause netperf/netserver to display its + version and exit. + +*) Setting -I without setting -i will now implicitly set the iteration + minimum and maximums as if a -i 10,3 were set. Also, some further + sanity checking on the bounds for each is made. + +*) Fixed a typo in the manual (found by Emir Halepovic) so the + description for the -s and -S options properly specifies they + affect the data connection. + +These are the Release Notes for Revision 2.4.3 of netperf: + +Things changed in this release: + +*) The UDP_STREAM test includes --enable-demo support, courtesy of + patches from Scott Weitzenkamp. + +*) The nettest_dns.* files have been removed from the release and the + repository. Those wishing to perform DNS server tests should + migrate to netperf4 which has better support for DNS test. + +*) Fixes for compiling under Windows with Mingw/gcc courtesy of Gisle + Vanem. + +*) A new global option - -N - has been added. When specified, this + option will tell netperf to not bother to try to establish a + control connection with a remote netserver. Instead, netperf will + only attempt to make a data connection to the remote system. By + default, this will be to the "discard" service for a "STREAM" or + "SENDFILE" test, the "echo" service for a "RR" test and the + "chargen" service for a "MAERTS" test. Any "remote" settings are + changed to reflect their being unused in the test, and a "no + control" tag is added to the test banner when -N is specified. + + This still needs to be propagated to other test files - at least + for those for which it may make sense. + +*) The tests in nettest_bsd.c have been altered to not actually take + timestamps and deltas in --enable-histogram unless the verbosity + level has been set to actually display a histogram. This reduces + the overhead measurably, even on systems with "fast" time calls, + which _may_ mean that a future release of netperf may have + histogram support enabled by default. + + This still needs to be propagated to other test files. Patches + from the community would be most welcome :) + +*) Eliminate a bogus fprintf from the signal catching routine which + was being executed when both intervals and demo mode were active at + the same time. + +*) The nettest_ipv6.* files are no longer included in the source + tar/zip file. IPv6 functionality has been subsumed into the + nettest_bsd.* files for some time now. + +*) Use a higher resolution "time" source for HISTOGRAM support under + Windows, courtesy of Spencer Frink. Prior to this it had no better + than 10ms granularity which could lead to some rather strange + looking results :) + +*) A bug fix reporting recv_size rather than send_size in TCP_MAERTS + when CPU utilization was requested. + +*) A bug fix for buffer filling from a file to properly advance the + buffer pointer when the file is smaller than the send buffer. + +*) Enable certain UDP tests which previously used unconnected sockets + to use connected sockets. Courtesy of Shilpi Agarwal. + +*) The OSX CPU utilization code actually gets put into the tarball in + a make dist now :) + +*) The check to make sure that getaddrinfo returned ai_protocol and/or + ai_socktype's matching that which we requested is done for all socket + and/or protocol types and a warning is emitted if it returns any which + do not match. + +*) The linux CPU affinity code has been made capable of binding to + CPU's >=32 on a 32-bit compilation and >=64 on a 64-bit + compilation. + +*) More complete closing/redirecting of stdin/stdout/stderr/where in + netserver to make it easier to launch netserver at the far-end of a + remote shell. Courtesy of Hans Blom. + +*) Sendfile changes for Solaris courtesy of Andrew Gallatin. + +*) "spec" file support to generate RPMs courtesy of Martin Brown + +These are the Release Notes for Revision 2.4.2 of netperf: + +Things changed in this release: + +*) Fixes for floating point format differences, courtesy of George + Davis. + +*) Additions for CPU util support on MacOS X, courtesy of Anonymous. + +*) Processor affinity is now supported on AIX 5.3 (perhaps earlier) + via the bindprocessor system call. + +*) Fixes for test lockups with TCP_CRR and TCP_CC under Windows + courtesy of Dikon Reed. + +*) Fixes to netcpu_looper.c to get it to actually compile :) + +*) Have netcpu_looper use the bind_to_specific_processor() call + provided by netlib since that knows about more platforms than the + code in netcpu_looper did. The looper CPU binding will use a + mapping to handle cases where the CPU id's on the system may not be + a contiguous space starting from zero. At present, the code that + setups the mapping only knows about retrieving actual CPU ids under + HP-UX. + +*) The netcpu_sysctl method becomes calibration-free, courtesy of + Andrew Gallatin + +These are the Release Notes for Revision 2.4.1 of netperf: + +Things changed in this release: + +*) There is now a -B global command-line argument that will append its + parameter as a string to the end of result lines when test banners + have been suppressed. this is to make it easier to distinguish one + result from another when aggregate restults are being run in + parallel, without having to resort to having the individual results + shell redirected to a file. This has been done for some of the + tests in nettest_bsd.c, but not all of them, nor for the tests in + the other nettest_mumble.c files. + +*) There is now an --enable-spin configure option that will enable + intervals if not already enabled and will have the sender sit and + spin in a tight loop until time for the next interval rather than + wait for an interval timer to expire. This means it should be + possible to have a much finer granularity on the interval, at the + expense of an EXTREME increase in CPU utilization. (To the extent + I'm considering disabling measurement of local CPU utilization when + that mode is enabled, and bursts have been requested - your + feedback on that topic would be most appreciated) + + If only --enable-intervals is used with configure, the old set the + interval timer and wait method is still used. + + If --enable-spin is configured, the test banner will include "spin + intervals" rather than the "intervals" from a plain + --enable-intervals. The sit and spin will either use + gettimeofday(), or gethrtime() if gethrtime() is available. + + This has been implemented in the tests of nettest_bsd.c but none of + the others. Volunteers would be most welcome. I would entertain + the notion of making the implementation a series of inline + functions in netlib. This holds true for the demo mode - why will + become clear when you look at nettest_bsd.c. While things are + considerably cleaner than they were before, with reuse within + nettest_bsd.c, there is no resuse with the rest of the + nettest_mumble.c files. + +*) the -w option for the interval time now takes three optional + suffixes. if the suffix is 'm' (eg 10m) it will assume the user has + specified time in units of milliseconds. if the suffix is 'u' it + will assume microseconds, and if 's' seconds. no suffix remains + milliseconds for backwards compatability with previous netperf + versions. + +*) It should be possible to successfully compile with + --enable-intervals. + +These are the Release Notes for Revision 2.4.1 of netperf: + +Things changed in this release: + +*) netcpu_pstatnew.c has been altered to workaround a bug in the + interrupt cycle accounting in HP-UX 11.23 that is not expected to + be resolved until a later release. basically, some interrupt time + is not counted, which means the sum of idle, user, kernel and + interrupt is less than the cycles per second multiplied by the + elapsed time. the workaround preserves the "no calibration + required" nature of the pstatnew CPU utilization mechanism. you + can see more in netcpu_pstatnew.c and/or in debug output. + +*) in netlib.c recv_response has been renamed + recv_response_timed(addl_time) which is now used in + calibrate_remote_cpu in place of the "sleep(40);recv_response()" + sequence. This then allows the REM_CPU test to complete in less + than 40 seconds when the remote's CPU utilization mechanism does + not require calibration. The value of "addl_time" is added to the + tc_sec field of the select() timeout. A "new" recv_response has + been added that simply calls recv_response_timed(0) - this is to + minimize the number of changes needed elsewhere in the code. + +*) hopefully, this release fixes problems people have been having with + the configure script failing when picking a type for socklen_t. + now, instead of generating an error, it emits a warning and simply + tries socklen_t + +*) the configure script no longer looks for the size of an in_port_t + +*) netlib.c now has code to perform processor binding for Tru64, but + the configure script may or may not detect it correctly. This means + that one may have to edit the config.h file by hand to get the + functionality. + +*) it is known that netperf will compile under Windows XP and 2003 + using the DDK it is possible that netperf 2.4.1 will compile on a + Windows system under VC++/Visual Studio. It might even work!-) See + the README.window file for additional details. + +Things _NOT_ changed in this release: + +*) The automagic determination of the number and type of parameters to + sched_setaffinity under Linux remains brittle at best. + +These are the Release Notes for Revision 2.4.0 of netperf: + +Things changed in this release: + +*) Netperf has been converted to use a configure script. Yes boys and + girls, after 12 years of distributing netperf with just a makefile + I have finally bitten the bullet and cast my fate to autoconf, + automake, etc. To get the most basic netperf built all you should + need to do is: + + cd to the netperf directory + ./configure + make + and perhaps + make install + + (Note, I've not done much with make install - I'm hemming and + hawing over what the default installation location should be) + + Please keep in mind that this is the first time I've tried to use + autoconf et al. I am sure there are things that should be done + differently and would welcome any and all constructive criticisms. + + I suspect there are several places where I've not fully + demonstrated being of the autoconf body - particulary as pertains + to include files being in "#if mumble #endif" blocks. Fixes would + be most welcome. + +*) Speaking of becomming one with various GNU tools, work on a new + netperf manual has begun, with the source being a texinfo document + that is converted to "all" the other formats. This resides in doc/ + . + +*) The platform-specific parts of CPU utilization measurement have + been broken-out into separate .c files and selected at configure + time a la the pcap_mumble files of tcpdump. This makes + src/netlib.c _much_ easier to read and the addition of new CPU + utilization mechanisms much easier. + +*) New HP-UX 11.23 and Solaris 10 CPU utilization measurement + mechanisms (called pstatnew and kstat10 respectively) need no + calibration step. Both have variations on microstate accounting. + HP-UX 11.23 still identifies the method in the headers as 'P' for + pstat. The kstat10 method is identified as 'M' for Microstate. + + Scripts which make calibration runs with LOC_CPU and REM_CPU may + continue to do so, they will just run forty to eighty seconds + faster on platforms with the calibration-free CPU util mechanisms. + +*) Automatic detection of CPU utilization mechanism for HP-UX, Linux, + AIX, *BSD and Solaris. If you do not like what the configure + script selects, you can use --enable-cpuutil= . + +*) The "times" (aka 'T') CPU utilization mechanism has been removed. + It was never very accurate at all, only showing CPU time charged to + the process, and with interrupts and other network processing it is + rarely chaged to a or the correct process. It and other methods + may remain in the format_cpu_method() routine of src/netlib.c for + historical purposes only. + +*) CAVEAT - the "kstat" mechanism is KNOWN TO BE BOGUS for Solaris. + It does not include time spent processing interrupts, and + networking benchmarks will generate at least a few of those... + This affects _ALL_ versions of Solaris with kstat. + + So, do NOT trust any CPU util figures where netperf says the method + was 'K' for kstat - unless perhaps it reports 100% CPU util. + + Solaris 10 takes a step in the right direction adding microstate + accounting similar to what netperf uses on HP-UX 11.23. HOWEVER, + Solaris 10's accounting for user/kernel/idle is done in _parallel_ + with interrupt, which means they overlap. Doubleplusungood. Netperf + attempts to compensate for that with some handwaving + (src/netcpu_kstat10.c) + +*) Initial support for SCTP has been added with the SCTP_STREAM and + SCTP_RR tests. These tests use the libsctp mechanisms for + increased portability. It has been explained that libsctp should + not impart all that much overhead and it does make things rather + simpler. + +*) Netperf now uses getaddrinfo() to resolve hostnames and IP + addresses. A replacement getaddrinfo() is provided for those + platforms where the configure script cannot tell that getaddrinfo + is present. + + There are cases where a host's getaddrinfo call may return results + that ignore the hints for protocol. Netperf catches these and + reports a warning so you can pester your OS source for fixes. + + Solaris getaddrinfo() seems to return results with SCTP procotol + cleared. + + Mac OS X getaddrinfo botches when the service/port is specified as + "0" so one must specify a port number on the netperf command line. + + AIX 5.something getaddrinfo has a different but similar problem + with "0" as a port/service name as well. + + Linux 2.6 and HP-UX 11i getaddrinfo seem to be fine - at least as + far as netperf goes :) + +*) A "Demo Mode" has been added to the main BSD Sockets/TCP/UDP tests: + TCP_STREAM, TCP_MAERTS, TCP_SENDFILE, TCP_RR, TCP_CC, TCP_CRR and + UDP_RR. It has not been added to UDP_STREAM. This mode is enabled + with --enable-demo when configuring netperf, which activates a + global "-D" option. By default, -D will cause interim results + (throughput or transactions/s only, not CPU util) from the + netperf's perspective to be emitted no sooner than once per second. + An optional parameter can specify another interval in units + (floating point) of seconds: + + -D 1.5 + + will make the reporting interval at least 1.5 seconds. + + This mode makes no use of explicit interval timers since that can + be so, well fun on different platforms. Instead, an initial guess + of how many units of work must be done to consume the desired + reporting interval is made, and that guess is refined throughout + the entire test. If something happens to dramatically slow-down + the test, the reproting interval may become must larger for a few + intervals. When things speed-up it is detected very quickly. As + with the --enable-historgram support, if gethrtime() is available + on the platform, it will be used in lieu of gettimeofday(). In any + case, the number of calls to gettimeofday()/gethrtime() is much, + Much, MUCH smaller than for --enable-histogram so while there may + be a measurable effect on the results, it should be rather small. + +*) The global -H option has been enhanced to take an optional address + family specification for the control connection: + + -H , + + Unlike other comma-separated options, where specifying only one + thing will set both, here specifying only one thing will be + ass-u-me-d to be the and will leave defaulted + (AF_UNSPEC). Family can be specified as "4" or "inet" for + AF_INET, "6" or "inet6" for AF_INET6. + +*) A new global -L option has been added to specify the local name/IP + and/or address family for the control connection: + + -L , + + Unlike other comma-separated options, where specifying only one + thing will set both, here specifying only one thing will be + ass-u-me-d to be the and will leave defaulted + (AF_UNSPEC). Family can be specified as "4" or "inet" for + AF_INET, "6" or "inet6" for AF_INET6. + +*) Test-specific -H and -L options are present for the TCP, UDP and + SCTP tests, which are now (intended to be) IP protocol version + agnostic. + +*) Global -4 and -6 options will set the both the local and remote + address family to either AF_INET or AF_INET6 respectively. + +*) Test-specific -4 and -6 options have been added for TCP, UDP and + SCTP tests. + +*) Since the basic TCP UDP and SCTP tests are no longer IPv4-only, the + nettest_ipv6.[ch] files are only included in the source + distribution for historical interest. + +*) The main test banners for the TCP, UDP and SCTP tests have been + enhanced to give both local and remote addressing information for + the data connection. + +*) Compilation under Windows is likely FUBAR at this point. I _hope_ + to start trying to do builds under the DDK soon, but am not sure + when I'll be able to start. Any and all assistance you can give + there would be most welcome. + +*) Various and sundry fixes. TCP_RR should no longer go into an + infinite loop when you abort netperf. I'm sure there are others. + +*) Unix domain socket tests are compiled-in with --enable-unix=yes at + configure time. + +*) DLPI tests are compiled-in with --enable-dlpi=yes at configure + time. + +*) XTI tests are compiled-in with --enable-xti=yes at configure time. + +Things not changed in this release: + +*) Seems like everything has changed :) + +These are the Release Notes for Revision 2.3pl2 of netperf: + +Things changed in this release + +*) One can bind netperf or netserver to specific CPUs with the -T + option. This is a generalization of some HP-UX and netserver specific + work from 2.3pl1. + +*) Extend the kludge to workaround the Linux setsockopt/getsockopt + bizzarreness to the socket buffer sizes for the remote side in + addition to the local side. + +*) Fix the lack of initialization of times_up in recv_tcp_maerts() + that caused confidence intervals to fail miserably. + +*) Other misc fixes - than you to all of you who sent them. + +These are the Release Notes for revision 2.3pl1 of netperf: + +Things changed in this release + +*) The bind() call in create_data_socket() in the file nettest_bsd.c + is no longer conditional on the user's specifying an IP address or + port number to which the data socket should be bound. This fixes + the "connection refused" errors in the UDP tests. + +*) Some experimental code to allow one to specify a CPU to which the + remote netserver should be bound. This is intended to allow one to + get greater certainty (as in confidence intervals) on SMP + systems. At present the functionality is HP-UX specific. + Submittals of changes for a more general approach are welcomed. + +These are the Release Notes for revision 2.3 of netperf: + +Things changed in this release + +*) The user can now specify local and/or remote port numbers for the + data connection using the -P test-specific option. This is to + support those folks who want to run netperf through those evil, + end-to-end-breaking things known as firewalls... :) This changes + the format of some of the control messages, hence the bump in the + update number in the VUF. While it may be possible to mix 2.3 and + pre-2.3 netperf and netserver, it is not supported. + +*) The user can now specify local and/or remote IP addresses for the + data connection using the -I test-specific option. This is to + support those folks who want to run netperf through those evil, + end-to-end-breaking things known as firewalls... :) This changes + the format of some of the control messages, hence the bump in the + update number in the VUF. While it may be possible to mix 2.3 and + pre-2.3 netperf and netserver, it is not supported. + +*) Set DL_mumble message priorities in the DLPI tests + +*) Fix error return check for getaddrinfo() + +*) Those systems with gethrtime() can define -DHAVE_GETHRTIME to use + gethrtime() instead of gettimeofday() and reduce the measurement + overhead when enabling the -DHISTOGRAM functionality. + +*) The default for -DHISTOGRAM compilation now adds a UNIT_USEC and + TEN_USEC row and renames TENTH_MSEC to HUNDRED_USEC. If you want + the old behaviour add -DOLD_HISTOGRAM to CFLAGS. + +*) Add missing '!' in the recv_udp*_stream so we recognize the end of + a timed test correctly. + +*) Replace "||" with "&&" to fix an infinite loop in + recv_tcp_conn_rr() most likely introduced in 2.2pl5. + +*) Code has been added to kludge around the bug in Linux getsockopt() + where it almost always returns twice the value for which one + asks unlike virtually every other stack on the face of the + planet. This was doing some unpleasant things to tests in which + confidence intervals were requested. + +Things not changed in this release + +*) Lots :) + +These are the Release Notes for revision 2.2pl5 of netperf: + +Things changed in this release + +*) Improved (perhaps even usable :) support for Windows, including +compilation and run on Win64. + +*) Fixes for MacOS X and FreeBSD + +Things not changed in this release + +*) Specifying the port number(s) for the data connection + +These are the Release Notes for Revision 2.2pl4 of netperf: + +Things changed in this release + +*) USE_SYSCTL available on suitable FreeBSD releases to measure CPU + utilization without having to resort to -DUSE_LOOPER. + +*) Include Solaris 9 with the Linux sendfile path under -DHAVE_SENDFILE + +This still outstanding in this release + +*) Knowing why signals are not interrupting socket calls under + OpenVMS. A quick try to use threads for timing a la Win32 worked, + but also cut performance in half. Any and all assistance in this + area would be most welcome. + +These are the Release Notes for revisoin 2.2pl3 of netperf: + +Things changed in this release + +*) I started practicing what I preach and will set SO_REUSEADDR before + netserver tries to bind to its well-known port. + +*) Initial port to OpenVMS. This includes support for the OVMS + Auxilliary server (inetd replacement). See README.ovms for more + details on what is involved in compiling and running netperf under + OpenVMS. + +*) Testname comparisons are now case insensitive. This is a side + effect of OpenVMS downshifting commandlines to lowercase. I made + the change and decided it was OK to keep it that way, even though + for OpenVMS one _has_ to set the right defines to disable that + downshifting or the command-line options will not work. For example + "-H" will become "-h" which isn't quite the same thing... + +*) Misc fixes for nettest_ipv6.c. + +*) Support for sendfile() under Linux + +Thins I would like to have changed but did not know how or didn't have +time: + +*) Allow netserver to run as a standalone daemon under OpenVMS +*) Allow netserver to run as a standalone daemon under Windows +*) Rediscover an inetd-like facility for Windows +*) Figure-out how to get low-overhead, accurate, per-CPU utilization + figures under OpenVMS +*) Get the UDP_RR and UDP_STREAM tests to work under OpenVMS, and get + the TCP_RR test to work based on time rather than transaction + count. There is some bug (possibly in OpenVMS?) where the SIGALRM + fires, but a socket call will not return an EINTR. + +Things that changed prior to this release: + +*) Addition of the TCP_MAERTS test - this is a TCP_STREAM test where + the data flows from the netserver to the netperf rather than from + the netperf to the netserver. This can be useful in those + situations where netperf (netserver) is installed on a remote + system, but the tester has no shell access and wishes to get + performance data for the path from netserver to netperf. + +These are the Release Notes for the 2.2 revision of netperf: + +Things changed in this release + +*) Various and sundry bugs fixed (in theory) for platforms such as + FreeBSD and Linux. If I left-out your bug fix, it was purely + accidental - my mind has a very small cache, and sometimes I will + "lose" email in the shuffle. + +*) Initial support for sendfile() on HP-UX. This test will use the + sendfile() call instead of send() to send data to the + remote. Netperf "lies" to netserver and calls it a TCP_STREAM test + since what netserver needs to do is exactly the same. A future + patch may change that and simply have netserver call the same + routine for both test types. Kudos to Charles Harris for the + initial prototype. + +*) The Fore ATM API and HiPPI tests have been dropped from the + distribution. + +Things I would have liked to have changed, but did not have time for: + +*) Conversion of the source and makefile to use the GNU configure/autoconf + utility to make it easier for folks to build by not having to edit + makefiles... You will notice that I have started to switch from + "DO_MUMBLE" to "HAVE_MUMBLE" + +as always - happy benchmarking, + +rick jones + +--------------------------------------------------------------------- + +These are the Release Notes for the 2.1pl3 revision of netperf: + +*) An OBOB (Off By One Bug) in netlib.c that was causing a core dump + on Irix should be fixed. + +*) Irix systems should now be able to determine the number of CPU's + present automagically (code from outside, not tested yet because I + have no MP Irix systems at my disposal) + +*) An alpha version of a TCP_CC test has been added - this is a + TCP_CRR test with out the "RR." + +*) The -Ae has been removed from the default makefile. If someone has + a nice way to automagically generate the correct makefile for + different platforms I would like to learn how. + +happy benchmarking, + +rick jones + +---------------------------------------------------------------------- + +These are the Release Notes for the 2.1 revision of netperf: + +Things Changed in this release: + +*) The XTI (Version 2 of the spec) tests are now documented in the + manual. + +*) The TCP_CRR (Connect Request/Response) test is now documented in + the manual, including a description of how it mimics the behaviour + of http (the protocol underlying the WWW). + +*) Support for for Windows NT 3.51 OS in the BSD Sockets tests (ok, so + they are really Winsock in that case :). Other test suites may be + ported as required/desired/appropriate. + +*) Tests for TCP and UDP, using the IPv6 extensions to BSD sockets are + included in this release. They are included by adding -DUSE_IPv6 to + the makefile and recompiling. + +*) Support for a "long long" datatype should only be required for + -DUSE_PSTAT compilation which is an HP-UX only thing. The + *unbundled* HP compilers from at least "HP92453-01 A.09.61 HP C + Compiler" and later should have the required support. The bundled + compiler may not. GCC should work - check the archives listed in + the comp.sys.hp.hpux FAQ for copies. The FAQ is archived on + rtfm.mit.edu under the path pub/usenet/comp.sys.hp.hpux. + +*) A "proper" fix for double data type alignment has been included. + +*) A new script is included with this release which can be used to + measure aggregate TCP_RR performance (multiple, concurrent + instances of the TCP_RR test). A related use of this script would + be measuring MP scaling. A single-byte TCP_RR test is good for this + purpose for two reasons: + + 1) it excercises the control/protocol paths heavily without + using much in the way of data copies which may be easier to + scale. + 2) most systems can easily saturate cards with bandwidth, but + not so easily with request/response + + Of course, feedback on this is most welcome. + +*) When measuring CPU utilization, the units for service demand have + been changed from milliseconds (designated ms) of CPU per unit (KB + or Transaction) to microseconds (desginated us). + +*) For accurate reporting of service demand, netperf needs to know the + number of CPU's present on a system. On some systems (HP-UX), this + is automatic. For others (All), it is necessary to add a global "-n + " option to both netperf and netserver. + + !! IF THIS IS LEFT-OUT CPU UTILIZATION AND SERVICE DEMAND FOR !! + !! MULTI-PROCESSOR SYSTEMS WILL BE WRONG. !! + + If you know of ways to programatically determine the number of + active CPUs on a system, please let the author Rick Jones + know. + +*) other things I've probably forgotten :) + +Things Not Changed in this release: + +*) The ancillary test suites are essentially unchanged - DLPI, + HiPPI/LLA, Unix Domain, and Fore ATM API. Unless there is much + interest expressed in these tests, 2.1 may be the last release in + which they are included. The order of retirement would likely be + Unix Domain, HiPPI/LLA, Fore ATM API, and then DLPI. + +Miscelaneous Comments: + +*) The -DUSE_LOOPER CPU utilization _seems_ to be nice and low-impact + on HP-UX, Digital Unix, and IRIX. It does not yet seem to be + low-impact on Solaris (I need an example of priocntl usage), AIX + (setpri only works if you are root), and NT (not sure of the + reason). Help with those problems would be most appreciated. diff --git a/acinclude.m4 b/acinclude.m4 new file mode 100644 index 0000000..3895177 --- /dev/null +++ b/acinclude.m4 @@ -0,0 +1,341 @@ + +dnl This comes from libcurl's acinclude.m4. it is not clear if this +dnl is original libcurl code, or other code, so we include the libcurl +dnl copyright here +dnl +dnl +dnl Copyright (c) 1996 - 2005, Daniel Stenberg, . +dnl +dnl All rights reserved. +dnl +dnl Permission to use, copy, modify, and distribute this software for any purpose +dnl with or without fee is hereby granted, provided that the above copyright +dnl notice and this permission notice appear in all copies. +dnl +dnl THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +dnl IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +dnl FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN +dnl NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +dnl DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +dnl OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE +dnl OR OTHER DEALINGS IN THE SOFTWARE. +dnl +dnl Except as contained in this notice, the name of a copyright holder shall not +dnl be used in advertising or otherwise to promote the sale, use or other dealings +dnl in this Software without prior written authorization of the copyright holder. + +dnl Check for socklen_t: historically on BSD it is an int, and in +dnl POSIX 1g it is a type of its own, but some platforms use different +dnl types for the argument to getsockopt, getpeername, etc. So we +dnl have to test to find something that will work. + +dnl Remove the AC_CHECK_TYPE - on HP-UX it would find a socklen_t, but the +dnl function prototypes for getsockopt et al will not actually use +dnl socklen_t args unless _XOPEN_SOURCE_EXTENDED is defined. so, the +dnl AC_CHECK_TYPE will find a socklen_t and think all is happiness and +dnl joy when you will really get warnings about mismatch types - type +dnl mismatches that would be possibly Bad (tm) in a 64-bit compile. +dnl raj 2005-05-11 this change may be redistributed at will + +dnl also, added "extern" to the "int getpeername" in an attempt to resolve +dnl an issue with this code under Solaris 2.9. this too may be +dnl redistributed at will + + +AC_DEFUN([OLD_TYPE_SOCKLEN_T], +[ + AC_MSG_CHECKING([for socklen_t equivalent]) + AC_CACHE_VAL([curl_cv_socklen_t_equiv], + [ + # Systems have either "struct sockaddr *" or + # "void *" as the second argument to getpeername + curl_cv_socklen_t_equiv= + for arg2 in "struct sockaddr" void; do + for t in int size_t unsigned long "unsigned long" socklen_t; do + AC_TRY_COMPILE([ + #ifdef HAVE_SYS_TYPES_H + #include + #endif + #ifdef HAVE_SYS_SOCKET_H + #include + #endif + + extern int getpeername (int, $arg2 *, $t *); + ],[ + $t len; + getpeername(0,0,&len); + ],[ + curl_cv_socklen_t_equiv="$t" + break 2 + ]) + done + done + + if test "x$curl_cv_socklen_t_equiv" = x; then + # take a wild guess + curl_cv_socklen_t_equiv="socklen_t" + AC_MSG_WARN([Cannot find a type to use in place of socklen_t, guessing socklen_t]) + fi + ]) + AC_MSG_RESULT($curl_cv_socklen_t_equiv) + AC_DEFINE_UNQUOTED(netperf_socklen_t, $curl_cv_socklen_t_equiv, + [type to use in place of socklen_t if not defined]) +]) + + +dnl * +dnl * Copyright (c) 2001 Motoyuki Kasahara +dnl * +dnl * Redistribution and use in source and binary forms, with or without +dnl * modification, are permitted provided that the following conditions +dnl * are met: +dnl * 1. Redistributions of source code must retain the above copyright +dnl * notice, this list of conditions and the following disclaimer. +dnl * 2. Redistributions in binary form must reproduce the above copyright +dnl * notice, this list of conditions and the following disclaimer in the +dnl * documentation and/or other materials provided with the distribution. +dnl * 3. Neither the name of the project nor the names of its contributors +dnl * may be used to endorse or promote products derived from this software +dnl * without specific prior written permission. +dnl * +dnl * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND +dnl * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +dnl * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +dnl * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORSBE +dnl * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +dnl * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +dnl * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +dnl * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +dnl * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +dnl * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +dnl * THE POSSIBILITY OF SUCH DAMAGE. +dnl * + +dnl * +dnl * Check for h_errno. +dnl * +AC_DEFUN([AC_DECL_H_ERRNO], +[AC_CACHE_CHECK(for h_errno declaration in netdb.h, ac_cv_decl_h_errno, +[AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#include ]], [[ +h_errno = 0; +]])],[ac_cv_decl_h_errno=yes],[ac_cv_decl_h_errno=no])]) +if test "$ac_cv_decl_h_errno" = yes; then + AC_DEFINE(H_ERRNO_DECLARED, 1, +[Define to 1 if `h_errno' is declared by ]) +fi]) + +dnl * +dnl * Copyright (c) 2001 Motoyuki Kasahara +dnl * +dnl * Redistribution and use in source and binary forms, with or without +dnl * modification, are permitted provided that the following conditions +dnl * are met: +dnl * 1. Redistributions of source code must retain the above copyright +dnl * notice, this list of conditions and the following disclaimer. +dnl * 2. Redistributions in binary form must reproduce the above copyright +dnl * notice, this list of conditions and the following disclaimer in the +dnl * documentation and/or other materials provided with the distribution. +dnl * 3. Neither the name of the project nor the names of its contributors +dnl * may be used to endorse or promote products derived from this software +dnl * without specific prior written permission. +dnl * +dnl * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND +dnl * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +dnl * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +dnl * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORSBE +dnl * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +dnl * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +dnl * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +dnl * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +dnl * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +dnl * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +dnl * THE POSSIBILITY OF SUCH DAMAGE. +dnl * + +dnl * +dnl * Check for struct sockaddr_in6 +dnl * +AC_DEFUN([AC_STRUCT_SOCKADDR_IN6], +[AC_CACHE_CHECK(for struct sockaddr_in6, ac_cv_struct_sockaddr_in6, +[AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#include +#include +#include ]], [[ +struct sockaddr_in6 address; +]])],[ac_cv_struct_sockaddr_in6=yes],[ac_cv_struct_sockaddr_in6=no])]) +if test "$ac_cv_struct_sockaddr_in6" = yes; then + AC_DEFINE(HAVE_STRUCT_SOCKADDR_IN6, 1, +[Define to 1 if defines `struct sockaddr_in6']) +fi]) + +dnl * +dnl * Check for struct sockaddr_storage +dnl * +AC_DEFUN([AC_STRUCT_SOCKADDR_STORAGE], +[AC_CACHE_CHECK(for struct sockaddr_storage, ac_cv_struct_sockaddr_storage, +[AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#include +#include +#include ]], [[ +struct sockaddr_storage address; +]])],[ac_cv_struct_sockaddr_storage=yes],[ac_cv_struct_sockaddr_storage=no])]) +if test "$ac_cv_struct_sockaddr_storage" = yes; then + AC_DEFINE(HAVE_STRUCT_SOCKADDR_STORAGE, 1, +[Define to 1 if defines `struct sockaddr_storage']) +fi]) + +dnl * +dnl * Copyright (c) 2001, 2003 Motoyuki Kasahara +dnl * +dnl * Redistribution and use in source and binary forms, with or without +dnl * modification, are permitted provided that the following conditions +dnl * are met: +dnl * 1. Redistributions of source code must retain the above copyright +dnl * notice, this list of conditions and the following disclaimer. +dnl * 2. Redistributions in binary form must reproduce the above copyright +dnl * notice, this list of conditions and the following disclaimer in the +dnl * documentation and/or other materials provided with the distribution. +dnl * 3. Neither the name of the project nor the names of its contributors +dnl * may be used to endorse or promote products derived from this software +dnl * without specific prior written permission. +dnl * +dnl * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND +dnl * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +dnl * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +dnl * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORSBE +dnl * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +dnl * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +dnl * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +dnl * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +dnl * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +dnl * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +dnl * THE POSSIBILITY OF SUCH DAMAGE. +dnl * + +dnl * +dnl * Check for socklen_t. +dnl * +AC_DEFUN([AC_TYPE_SOCKLEN_T], +[AC_CACHE_CHECK([for socklen_t], ac_cv_type_socklen_t, +[AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#include +#include ]], [[ +socklen_t socklen; +]])],[ac_cv_type_socklen_t=yes],[ac_cv_type_socklen_t=no])]) +if test "$ac_cv_type_socklen_t" != yes; then + AC_DEFINE(socklen_t, int, +[Define to `int' if or does not define.]) +fi]) + +dnl * +dnl * Check for in_port_t. +dnl * +AC_DEFUN([AC_TYPE_IN_PORT_T], +[AC_CACHE_CHECK([for in_port_t], ac_cv_type_in_port_t, +[AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#include +#include +#include ]], [[ +in_port_t in_port; +]])],[ac_cv_type_in_port_t=yes],[ac_cv_type_in_port_t=no])]) +if test "$ac_cv_type_in_port_t" != yes; then + ac_cv_sin_port_size=unknown + AC_RUN_IFELSE([AC_LANG_SOURCE([[ + #include + #include + #include + int main() { + struct sockaddr_in addr; + return (sizeof(addr.sin_port) == sizeof(long)) ? 0 : 1; + } + ]])],[ac_cv_sin_port_size=long],[],[]) + AC_RUN_IFELSE([AC_LANG_SOURCE([[ + #include + #include + #include + int main() { + struct sockaddr_in addr; + return (sizeof(addr.sin_port) == sizeof(int)) ? 0 : 1; + } + ]])],[ac_cv_sin_port_size=int],[],[]) + AC_RUN_IFELSE([AC_LANG_SOURCE([[ + #include + #include + #include + int main() { + struct sockaddr_in addr; + return (sizeof(addr.sin_port) == sizeof(short)) ? 0 : 1; + } + ]])],[ac_cv_sin_port_size=short],[],[]) + AC_RUN_IFELSE([AC_LANG_SOURCE([[ + #include + #include + #include + int main() { + struct sockaddr_in addr; + return (sizeof(addr.sin_port) == sizeof(char)) ? 0 : 1; + } + ]])],[ac_cv_sin_port_size=char],[],[]) + if test "$ac_cv_sin_port_size" = unknown; then + AC_MSG_ERROR([Failed to get size of sin_port in struct sockaddr_in.]) + fi + AC_DEFINE_UNQUOTED(in_port_t, unsigned $ac_cv_sin_port_size, +[Define to `unsigned char', `unsigned short', `unsigned int' or +`unsigned long' according with size of `sin_port' in `struct sockaddr_in', +if , or does not define +`in_port_t'.]) +fi]) + +dnl * +dnl * Check for sa_family_t. +dnl * +AC_DEFUN([AC_TYPE_SA_FAMILY_T], +[AC_CACHE_CHECK([for sa_family_t], ac_cv_type_sa_family_t, +[AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#include +#include ]], [[ +sa_family_t sa_family; +]])],[ac_cv_type_sa_family_t=yes],[ac_cv_type_sa_family_t=no])]) +if test "$ac_cv_type_sa_family_t" != yes; then + ac_cv_sa_family_size=unknown + AC_RUN_IFELSE([AC_LANG_SOURCE([[ + #include + #include + int main() { + struct sockaddr addr; + return (sizeof(addr.sa_family) == sizeof(long)) ? 0 : 1; + } + ]])],[ac_cv_sa_family_size=long],[],[]) + AC_RUN_IFELSE([AC_LANG_SOURCE([[ + #include + #include + int main() { + struct sockaddr addr; + return (sizeof(addr.sa_family) == sizeof(int)) ? 0 : 1; + } + ]])],[ac_cv_sa_family_size=int],[],[]) + AC_RUN_IFELSE([AC_LANG_SOURCE([[ + #include + #include + int main() { + struct sockaddr addr; + return (sizeof(addr.sa_family) == sizeof(short)) ? 0 : 1; + } + ]])],[ac_cv_sa_family_size=short],[],[]) + AC_RUN_IFELSE([AC_LANG_SOURCE([[ + #include + #include + int main() { + struct sockaddr addr; + return (sizeof(addr.sa_family) == sizeof(char)) ? 0 : 1; + } + ]])],[ac_cv_sa_family_size=char],[],[]) + if test "$ac_cv_sa_family_size" = unknown; then + AC_MSG_ERROR([Failed to get size of sa_family in struct sockaddr.]) + fi + AC_DEFINE_UNQUOTED(sa_family_t, unsigned $ac_cv_sa_family_size, +[Define to `unsigned char', `unsigned short', `unsigned int' or +`unsigned long' according with size of `sa_family' in `struct sockaddr', +if or does not define `sa_family_t'.]) +fi]) diff --git a/aclocal.m4 b/aclocal.m4 new file mode 100644 index 0000000..5822b83 --- /dev/null +++ b/aclocal.m4 @@ -0,0 +1,1236 @@ +# generated automatically by aclocal 1.7.9 -*- Autoconf -*- + +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002 +# Free Software Foundation, Inc. +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + + +dnl This comes from libcurl's acinclude.m4. it is not clear if this +dnl is original libcurl code, or other code, so we include the libcurl +dnl copyright here +dnl +dnl +dnl Copyright (c) 1996 - 2005, Daniel Stenberg, . +dnl +dnl All rights reserved. +dnl +dnl Permission to use, copy, modify, and distribute this software for any purpose +dnl with or without fee is hereby granted, provided that the above copyright +dnl notice and this permission notice appear in all copies. +dnl +dnl THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +dnl IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +dnl FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN +dnl NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +dnl DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +dnl OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE +dnl OR OTHER DEALINGS IN THE SOFTWARE. +dnl +dnl Except as contained in this notice, the name of a copyright holder shall not +dnl be used in advertising or otherwise to promote the sale, use or other dealings +dnl in this Software without prior written authorization of the copyright holder. + +dnl Check for socklen_t: historically on BSD it is an int, and in +dnl POSIX 1g it is a type of its own, but some platforms use different +dnl types for the argument to getsockopt, getpeername, etc. So we +dnl have to test to find something that will work. + +dnl Remove the AC_CHECK_TYPE - on HP-UX it would find a socklen_t, but the +dnl function prototypes for getsockopt et al will not actually use +dnl socklen_t args unless _XOPEN_SOURCE_EXTENDED is defined. so, the +dnl AC_CHECK_TYPE will find a socklen_t and think all is happiness and +dnl joy when you will really get warnings about mismatch types - type +dnl mismatches that would be possibly Bad (tm) in a 64-bit compile. +dnl raj 2005-05-11 this change may be redistributed at will + +dnl also, added "extern" to the "int getpeername" in an attempt to resolve +dnl an issue with this code under Solaris 2.9. this too may be +dnl redistributed at will + + +AC_DEFUN([OLD_TYPE_SOCKLEN_T], +[ + AC_MSG_CHECKING([for socklen_t equivalent]) + AC_CACHE_VAL([curl_cv_socklen_t_equiv], + [ + # Systems have either "struct sockaddr *" or + # "void *" as the second argument to getpeername + curl_cv_socklen_t_equiv= + for arg2 in "struct sockaddr" void; do + for t in int size_t unsigned long "unsigned long" socklen_t; do + AC_TRY_COMPILE([ + #ifdef HAVE_SYS_TYPES_H + #include + #endif + #ifdef HAVE_SYS_SOCKET_H + #include + #endif + + extern int getpeername (int, $arg2 *, $t *); + ],[ + $t len; + getpeername(0,0,&len); + ],[ + curl_cv_socklen_t_equiv="$t" + break 2 + ]) + done + done + + if test "x$curl_cv_socklen_t_equiv" = x; then + # take a wild guess + curl_cv_socklen_t_equiv="socklen_t" + AC_MSG_WARN([Cannot find a type to use in place of socklen_t, guessing socklen_t]) + fi + ]) + AC_MSG_RESULT($curl_cv_socklen_t_equiv) + AC_DEFINE_UNQUOTED(netperf_socklen_t, $curl_cv_socklen_t_equiv, + [type to use in place of socklen_t if not defined]) +]) + + +dnl * +dnl * Copyright (c) 2001 Motoyuki Kasahara +dnl * +dnl * Redistribution and use in source and binary forms, with or without +dnl * modification, are permitted provided that the following conditions +dnl * are met: +dnl * 1. Redistributions of source code must retain the above copyright +dnl * notice, this list of conditions and the following disclaimer. +dnl * 2. Redistributions in binary form must reproduce the above copyright +dnl * notice, this list of conditions and the following disclaimer in the +dnl * documentation and/or other materials provided with the distribution. +dnl * 3. Neither the name of the project nor the names of its contributors +dnl * may be used to endorse or promote products derived from this software +dnl * without specific prior written permission. +dnl * +dnl * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND +dnl * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +dnl * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +dnl * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORSBE +dnl * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +dnl * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +dnl * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +dnl * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +dnl * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +dnl * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +dnl * THE POSSIBILITY OF SUCH DAMAGE. +dnl * + +dnl * +dnl * Check for h_errno. +dnl * +AC_DEFUN([AC_DECL_H_ERRNO], +[AC_CACHE_CHECK(for h_errno declaration in netdb.h, ac_cv_decl_h_errno, +[AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#include ]], [[ +h_errno = 0; +]])],[ac_cv_decl_h_errno=yes],[ac_cv_decl_h_errno=no])]) +if test "$ac_cv_decl_h_errno" = yes; then + AC_DEFINE(H_ERRNO_DECLARED, 1, +[Define to 1 if `h_errno' is declared by ]) +fi]) + +dnl * +dnl * Copyright (c) 2001 Motoyuki Kasahara +dnl * +dnl * Redistribution and use in source and binary forms, with or without +dnl * modification, are permitted provided that the following conditions +dnl * are met: +dnl * 1. Redistributions of source code must retain the above copyright +dnl * notice, this list of conditions and the following disclaimer. +dnl * 2. Redistributions in binary form must reproduce the above copyright +dnl * notice, this list of conditions and the following disclaimer in the +dnl * documentation and/or other materials provided with the distribution. +dnl * 3. Neither the name of the project nor the names of its contributors +dnl * may be used to endorse or promote products derived from this software +dnl * without specific prior written permission. +dnl * +dnl * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND +dnl * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +dnl * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +dnl * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORSBE +dnl * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +dnl * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +dnl * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +dnl * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +dnl * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +dnl * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +dnl * THE POSSIBILITY OF SUCH DAMAGE. +dnl * + +dnl * +dnl * Check for struct sockaddr_in6 +dnl * +AC_DEFUN([AC_STRUCT_SOCKADDR_IN6], +[AC_CACHE_CHECK(for struct sockaddr_in6, ac_cv_struct_sockaddr_in6, +[AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#include +#include +#include ]], [[ +struct sockaddr_in6 address; +]])],[ac_cv_struct_sockaddr_in6=yes],[ac_cv_struct_sockaddr_in6=no])]) +if test "$ac_cv_struct_sockaddr_in6" = yes; then + AC_DEFINE(HAVE_STRUCT_SOCKADDR_IN6, 1, +[Define to 1 if defines `struct sockaddr_in6']) +fi]) + +dnl * +dnl * Check for struct sockaddr_storage +dnl * +AC_DEFUN([AC_STRUCT_SOCKADDR_STORAGE], +[AC_CACHE_CHECK(for struct sockaddr_storage, ac_cv_struct_sockaddr_storage, +[AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#include +#include +#include ]], [[ +struct sockaddr_storage address; +]])],[ac_cv_struct_sockaddr_storage=yes],[ac_cv_struct_sockaddr_storage=no])]) +if test "$ac_cv_struct_sockaddr_storage" = yes; then + AC_DEFINE(HAVE_STRUCT_SOCKADDR_STORAGE, 1, +[Define to 1 if defines `struct sockaddr_storage']) +fi]) + +dnl * +dnl * Copyright (c) 2001, 2003 Motoyuki Kasahara +dnl * +dnl * Redistribution and use in source and binary forms, with or without +dnl * modification, are permitted provided that the following conditions +dnl * are met: +dnl * 1. Redistributions of source code must retain the above copyright +dnl * notice, this list of conditions and the following disclaimer. +dnl * 2. Redistributions in binary form must reproduce the above copyright +dnl * notice, this list of conditions and the following disclaimer in the +dnl * documentation and/or other materials provided with the distribution. +dnl * 3. Neither the name of the project nor the names of its contributors +dnl * may be used to endorse or promote products derived from this software +dnl * without specific prior written permission. +dnl * +dnl * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND +dnl * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +dnl * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +dnl * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORSBE +dnl * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +dnl * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +dnl * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +dnl * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +dnl * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +dnl * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +dnl * THE POSSIBILITY OF SUCH DAMAGE. +dnl * + +dnl * +dnl * Check for socklen_t. +dnl * +AC_DEFUN([AC_TYPE_SOCKLEN_T], +[AC_CACHE_CHECK([for socklen_t], ac_cv_type_socklen_t, +[AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#include +#include ]], [[ +socklen_t socklen; +]])],[ac_cv_type_socklen_t=yes],[ac_cv_type_socklen_t=no])]) +if test "$ac_cv_type_socklen_t" != yes; then + AC_DEFINE(socklen_t, int, +[Define to `int' if or does not define.]) +fi]) + +dnl * +dnl * Check for in_port_t. +dnl * +AC_DEFUN([AC_TYPE_IN_PORT_T], +[AC_CACHE_CHECK([for in_port_t], ac_cv_type_in_port_t, +[AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#include +#include +#include ]], [[ +in_port_t in_port; +]])],[ac_cv_type_in_port_t=yes],[ac_cv_type_in_port_t=no])]) +if test "$ac_cv_type_in_port_t" != yes; then + ac_cv_sin_port_size=unknown + AC_RUN_IFELSE([AC_LANG_SOURCE([[ + #include + #include + #include + int main() { + struct sockaddr_in addr; + return (sizeof(addr.sin_port) == sizeof(long)) ? 0 : 1; + } + ]])],[ac_cv_sin_port_size=long],[],[]) + AC_RUN_IFELSE([AC_LANG_SOURCE([[ + #include + #include + #include + int main() { + struct sockaddr_in addr; + return (sizeof(addr.sin_port) == sizeof(int)) ? 0 : 1; + } + ]])],[ac_cv_sin_port_size=int],[],[]) + AC_RUN_IFELSE([AC_LANG_SOURCE([[ + #include + #include + #include + int main() { + struct sockaddr_in addr; + return (sizeof(addr.sin_port) == sizeof(short)) ? 0 : 1; + } + ]])],[ac_cv_sin_port_size=short],[],[]) + AC_RUN_IFELSE([AC_LANG_SOURCE([[ + #include + #include + #include + int main() { + struct sockaddr_in addr; + return (sizeof(addr.sin_port) == sizeof(char)) ? 0 : 1; + } + ]])],[ac_cv_sin_port_size=char],[],[]) + if test "$ac_cv_sin_port_size" = unknown; then + AC_MSG_ERROR([Failed to get size of sin_port in struct sockaddr_in.]) + fi + AC_DEFINE_UNQUOTED(in_port_t, unsigned $ac_cv_sin_port_size, +[Define to `unsigned char', `unsigned short', `unsigned int' or +`unsigned long' according with size of `sin_port' in `struct sockaddr_in', +if , or does not define +`in_port_t'.]) +fi]) + +dnl * +dnl * Check for sa_family_t. +dnl * +AC_DEFUN([AC_TYPE_SA_FAMILY_T], +[AC_CACHE_CHECK([for sa_family_t], ac_cv_type_sa_family_t, +[AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#include +#include ]], [[ +sa_family_t sa_family; +]])],[ac_cv_type_sa_family_t=yes],[ac_cv_type_sa_family_t=no])]) +if test "$ac_cv_type_sa_family_t" != yes; then + ac_cv_sa_family_size=unknown + AC_RUN_IFELSE([AC_LANG_SOURCE([[ + #include + #include + int main() { + struct sockaddr addr; + return (sizeof(addr.sa_family) == sizeof(long)) ? 0 : 1; + } + ]])],[ac_cv_sa_family_size=long],[],[]) + AC_RUN_IFELSE([AC_LANG_SOURCE([[ + #include + #include + int main() { + struct sockaddr addr; + return (sizeof(addr.sa_family) == sizeof(int)) ? 0 : 1; + } + ]])],[ac_cv_sa_family_size=int],[],[]) + AC_RUN_IFELSE([AC_LANG_SOURCE([[ + #include + #include + int main() { + struct sockaddr addr; + return (sizeof(addr.sa_family) == sizeof(short)) ? 0 : 1; + } + ]])],[ac_cv_sa_family_size=short],[],[]) + AC_RUN_IFELSE([AC_LANG_SOURCE([[ + #include + #include + int main() { + struct sockaddr addr; + return (sizeof(addr.sa_family) == sizeof(char)) ? 0 : 1; + } + ]])],[ac_cv_sa_family_size=char],[],[]) + if test "$ac_cv_sa_family_size" = unknown; then + AC_MSG_ERROR([Failed to get size of sa_family in struct sockaddr.]) + fi + AC_DEFINE_UNQUOTED(sa_family_t, unsigned $ac_cv_sa_family_size, +[Define to `unsigned char', `unsigned short', `unsigned int' or +`unsigned long' according with size of `sa_family' in `struct sockaddr', +if or does not define `sa_family_t'.]) +fi]) + +# Do all the work for Automake. -*- Autoconf -*- + +# This macro actually does too much some checks are only needed if +# your package does certain things. But this isn't really a big deal. + +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 +# Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# serial 10 + +AC_PREREQ([2.54]) + +# Autoconf 2.50 wants to disallow AM_ names. We explicitly allow +# the ones we care about. +m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl + +# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) +# AM_INIT_AUTOMAKE([OPTIONS]) +# ----------------------------------------------- +# The call with PACKAGE and VERSION arguments is the old style +# call (pre autoconf-2.50), which is being phased out. PACKAGE +# and VERSION should now be passed to AC_INIT and removed from +# the call to AM_INIT_AUTOMAKE. +# We support both call styles for the transition. After +# the next Automake release, Autoconf can make the AC_INIT +# arguments mandatory, and then we can depend on a new Autoconf +# release and drop the old call support. +AC_DEFUN([AM_INIT_AUTOMAKE], +[AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl + AC_REQUIRE([AC_PROG_INSTALL])dnl +# test to see if srcdir already configured +if test "`cd $srcdir && pwd`" != "`pwd`" && + test -f $srcdir/config.status; then + AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi +AC_SUBST([CYGPATH_W]) + +# Define the identity of the package. +dnl Distinguish between old-style and new-style calls. +m4_ifval([$2], +[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl + AC_SUBST([PACKAGE], [$1])dnl + AC_SUBST([VERSION], [$2])], +[_AM_SET_OPTIONS([$1])dnl + AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl + AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl + +_AM_IF_OPTION([no-define],, +[AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package]) + AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl + +# Some tools Automake needs. +AC_REQUIRE([AM_SANITY_CHECK])dnl +AC_REQUIRE([AC_ARG_PROGRAM])dnl +AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version}) +AM_MISSING_PROG(AUTOCONF, autoconf) +AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version}) +AM_MISSING_PROG(AUTOHEADER, autoheader) +AM_MISSING_PROG(MAKEINFO, makeinfo) +AM_MISSING_PROG(AMTAR, tar) +AM_PROG_INSTALL_SH +AM_PROG_INSTALL_STRIP +# We need awk for the "check" target. The system "awk" is bad on +# some platforms. +AC_REQUIRE([AC_PROG_AWK])dnl +AC_REQUIRE([AC_PROG_MAKE_SET])dnl +AC_REQUIRE([AM_SET_LEADING_DOT])dnl + +_AM_IF_OPTION([no-dependencies],, +[AC_PROVIDE_IFELSE([AC_PROG_CC], + [_AM_DEPENDENCIES(CC)], + [define([AC_PROG_CC], + defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl +AC_PROVIDE_IFELSE([AC_PROG_CXX], + [_AM_DEPENDENCIES(CXX)], + [define([AC_PROG_CXX], + defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl +]) +]) + + +# When config.status generates a header, we must update the stamp-h file. +# This file resides in the same directory as the config header +# that is generated. The stamp files are numbered to have different names. + +# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the +# loop where config.status creates the headers, so we can generate +# our stamp files there. +AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], +[# Compute $1's index in $config_headers. +_am_stamp_count=1 +for _am_header in $config_headers :; do + case $_am_header in + $1 | $1:* ) + break ;; + * ) + _am_stamp_count=`expr $_am_stamp_count + 1` ;; + esac +done +echo "timestamp for $1" >`AS_DIRNAME([$1])`/stamp-h[]$_am_stamp_count]) + +# Copyright 2002 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + +# AM_AUTOMAKE_VERSION(VERSION) +# ---------------------------- +# Automake X.Y traces this macro to ensure aclocal.m4 has been +# generated from the m4 files accompanying Automake X.Y. +AC_DEFUN([AM_AUTOMAKE_VERSION],[am__api_version="1.7"]) + +# AM_SET_CURRENT_AUTOMAKE_VERSION +# ------------------------------- +# Call AM_AUTOMAKE_VERSION so it can be traced. +# This function is AC_REQUIREd by AC_INIT_AUTOMAKE. +AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], + [AM_AUTOMAKE_VERSION([1.7.9])]) + +# Helper functions for option handling. -*- Autoconf -*- + +# Copyright 2001, 2002 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# serial 2 + +# _AM_MANGLE_OPTION(NAME) +# ----------------------- +AC_DEFUN([_AM_MANGLE_OPTION], +[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) + +# _AM_SET_OPTION(NAME) +# ------------------------------ +# Set option NAME. Presently that only means defining a flag for this option. +AC_DEFUN([_AM_SET_OPTION], +[m4_define(_AM_MANGLE_OPTION([$1]), 1)]) + +# _AM_SET_OPTIONS(OPTIONS) +# ---------------------------------- +# OPTIONS is a space-separated list of Automake options. +AC_DEFUN([_AM_SET_OPTIONS], +[AC_FOREACH([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) + +# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) +# ------------------------------------------- +# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. +AC_DEFUN([_AM_IF_OPTION], +[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) + +# +# Check to make sure that the build environment is sane. +# + +# Copyright 1996, 1997, 2000, 2001 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# serial 3 + +# AM_SANITY_CHECK +# --------------- +AC_DEFUN([AM_SANITY_CHECK], +[AC_MSG_CHECKING([whether build environment is sane]) +# Just in case +sleep 1 +echo timestamp > conftest.file +# Do `set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + set X `ls -Lt $srcdir/configure conftest.file 2> /dev/null` + if test "$[*]" = "X"; then + # -L didn't work. + set X `ls -t $srcdir/configure conftest.file` + fi + rm -f conftest.file + if test "$[*]" != "X $srcdir/configure conftest.file" \ + && test "$[*]" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken +alias in your environment]) + fi + + test "$[2]" = conftest.file + ) +then + # Ok. + : +else + AC_MSG_ERROR([newly created file is older than distributed files! +Check your system clock]) +fi +AC_MSG_RESULT(yes)]) + +# -*- Autoconf -*- + + +# Copyright 1997, 1999, 2000, 2001 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# serial 3 + +# AM_MISSING_PROG(NAME, PROGRAM) +# ------------------------------ +AC_DEFUN([AM_MISSING_PROG], +[AC_REQUIRE([AM_MISSING_HAS_RUN]) +$1=${$1-"${am_missing_run}$2"} +AC_SUBST($1)]) + + +# AM_MISSING_HAS_RUN +# ------------------ +# Define MISSING if not defined so far and test if it supports --run. +# If it does, set am_missing_run to use it, otherwise, to nothing. +AC_DEFUN([AM_MISSING_HAS_RUN], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing" +# Use eval to expand $SHELL +if eval "$MISSING --run true"; then + am_missing_run="$MISSING --run " +else + am_missing_run= + AC_MSG_WARN([`missing' script is too old or missing]) +fi +]) + +# AM_AUX_DIR_EXPAND + +# Copyright 2001 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets +# $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to +# `$srcdir', `$srcdir/..', or `$srcdir/../..'. +# +# Of course, Automake must honor this variable whenever it calls a +# tool from the auxiliary directory. The problem is that $srcdir (and +# therefore $ac_aux_dir as well) can be either absolute or relative, +# depending on how configure is run. This is pretty annoying, since +# it makes $ac_aux_dir quite unusable in subdirectories: in the top +# source directory, any form will work fine, but in subdirectories a +# relative path needs to be adjusted first. +# +# $ac_aux_dir/missing +# fails when called from a subdirectory if $ac_aux_dir is relative +# $top_srcdir/$ac_aux_dir/missing +# fails if $ac_aux_dir is absolute, +# fails when called from a subdirectory in a VPATH build with +# a relative $ac_aux_dir +# +# The reason of the latter failure is that $top_srcdir and $ac_aux_dir +# are both prefixed by $srcdir. In an in-source build this is usually +# harmless because $srcdir is `.', but things will broke when you +# start a VPATH build or use an absolute $srcdir. +# +# So we could use something similar to $top_srcdir/$ac_aux_dir/missing, +# iff we strip the leading $srcdir from $ac_aux_dir. That would be: +# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` +# and then we would define $MISSING as +# MISSING="\${SHELL} $am_aux_dir/missing" +# This will work as long as MISSING is not called from configure, because +# unfortunately $(top_srcdir) has no meaning in configure. +# However there are other variables, like CC, which are often used in +# configure, and could therefore not use this "fixed" $ac_aux_dir. +# +# Another solution, used here, is to always expand $ac_aux_dir to an +# absolute PATH. The drawback is that using absolute paths prevent a +# configured tree to be moved without reconfiguration. + +# Rely on autoconf to set up CDPATH properly. +AC_PREREQ([2.50]) + +AC_DEFUN([AM_AUX_DIR_EXPAND], [ +# expand $ac_aux_dir to an absolute path +am_aux_dir=`cd $ac_aux_dir && pwd` +]) + +# AM_PROG_INSTALL_SH +# ------------------ +# Define $install_sh. + +# Copyright 2001 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +AC_DEFUN([AM_PROG_INSTALL_SH], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +install_sh=${install_sh-"$am_aux_dir/install-sh"} +AC_SUBST(install_sh)]) + +# AM_PROG_INSTALL_STRIP + +# Copyright 2001 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# One issue with vendor `install' (even GNU) is that you can't +# specify the program used to strip binaries. This is especially +# annoying in cross-compiling environments, where the build's strip +# is unlikely to handle the host's binaries. +# Fortunately install-sh will honor a STRIPPROG variable, so we +# always use install-sh in `make install-strip', and initialize +# STRIPPROG with the value of the STRIP variable (set by the user). +AC_DEFUN([AM_PROG_INSTALL_STRIP], +[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl +# Installed binaries are usually stripped using `strip' when the user +# run `make install-strip'. However `strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the `STRIP' environment variable to overrule this program. +dnl Don't test for $cross_compiling = yes, because it might be `maybe'. +if test "$cross_compiling" != no; then + AC_CHECK_TOOL([STRIP], [strip], :) +fi +INSTALL_STRIP_PROGRAM="\${SHELL} \$(install_sh) -c -s" +AC_SUBST([INSTALL_STRIP_PROGRAM])]) + +# -*- Autoconf -*- +# Copyright (C) 2003 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# serial 1 + +# Check whether the underlying file-system supports filenames +# with a leading dot. For instance MS-DOS doesn't. +AC_DEFUN([AM_SET_LEADING_DOT], +[rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null +AC_SUBST([am__leading_dot])]) + +# serial 5 -*- Autoconf -*- + +# Copyright (C) 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + + +# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be +# written in clear, in which case automake, when reading aclocal.m4, +# will think it sees a *use*, and therefore will trigger all it's +# C support machinery. Also note that it means that autoscan, seeing +# CC etc. in the Makefile, will ask for an AC_PROG_CC use... + + + +# _AM_DEPENDENCIES(NAME) +# ---------------------- +# See how the compiler implements dependency checking. +# NAME is "CC", "CXX", "GCJ", or "OBJC". +# We try a few techniques and use that to set a single cache variable. +# +# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was +# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular +# dependency, and given that the user is not expected to run this macro, +# just rely on AC_PROG_CC. +AC_DEFUN([_AM_DEPENDENCIES], +[AC_REQUIRE([AM_SET_DEPDIR])dnl +AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl +AC_REQUIRE([AM_MAKE_INCLUDE])dnl +AC_REQUIRE([AM_DEP_TRACK])dnl + +ifelse([$1], CC, [depcc="$CC" am_compiler_list=], + [$1], CXX, [depcc="$CXX" am_compiler_list=], + [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'], + [$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'], + [depcc="$$1" am_compiler_list=]) + +AC_CACHE_CHECK([dependency style of $depcc], + [am_cv_$1_dependencies_compiler_type], +[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named `D' -- because `-MD' means `put the output + # in D'. + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_$1_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` + fi + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + : > sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + case $depmode in + nosideeffect) + # after this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + none) break ;; + esac + # We check with `-c' and `-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle `-M -o', and we need to detect this. + if depmode=$depmode \ + source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # (even with -Werror). So we grep stderr for any message + # that says an option was ignored. + if grep 'ignoring option' conftest.err >/dev/null 2>&1; then :; else + am_cv_$1_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_$1_dependencies_compiler_type=none +fi +]) +AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) +AM_CONDITIONAL([am__fastdep$1], [ + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) +]) + + +# AM_SET_DEPDIR +# ------------- +# Choose a directory name for dependency files. +# This macro is AC_REQUIREd in _AM_DEPENDENCIES +AC_DEFUN([AM_SET_DEPDIR], +[AC_REQUIRE([AM_SET_LEADING_DOT])dnl +AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl +]) + + +# AM_DEP_TRACK +# ------------ +AC_DEFUN([AM_DEP_TRACK], +[AC_ARG_ENABLE(dependency-tracking, +[ --disable-dependency-tracking Speeds up one-time builds + --enable-dependency-tracking Do not reject slow dependency extractors]) +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' +fi +AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) +AC_SUBST([AMDEPBACKSLASH]) +]) + +# Generate code to set up dependency tracking. -*- Autoconf -*- + +# Copyright 1999, 2000, 2001, 2002 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +#serial 2 + +# _AM_OUTPUT_DEPENDENCY_COMMANDS +# ------------------------------ +AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], +[for mf in $CONFIG_FILES; do + # Strip MF so we end up with the name of the file. + mf=`echo "$mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile or not. + # We used to match only the files named `Makefile.in', but + # some people rename them; so instead we look at the file content. + # Grep'ing the first line is not enough: some people post-process + # each Makefile.in and add a new line on top of each file to say so. + # So let's grep whole file. + if grep '^#.*generated by automake' $mf > /dev/null 2>&1; then + dirpart=`AS_DIRNAME("$mf")` + else + continue + fi + grep '^DEP_FILES *= *[[^ @%:@]]' < "$mf" > /dev/null || continue + # Extract the definition of DEP_FILES from the Makefile without + # running `make'. + DEPDIR=`sed -n -e '/^DEPDIR = / s///p' < "$mf"` + test -z "$DEPDIR" && continue + # When using ansi2knr, U may be empty or an underscore; expand it + U=`sed -n -e '/^U = / s///p' < "$mf"` + test -d "$dirpart/$DEPDIR" || mkdir "$dirpart/$DEPDIR" + # We invoke sed twice because it is the simplest approach to + # changing $(DEPDIR) to its actual value in the expansion. + for file in `sed -n -e ' + /^DEP_FILES = .*\\\\$/ { + s/^DEP_FILES = // + :loop + s/\\\\$// + p + n + /\\\\$/ b loop + p + } + /^DEP_FILES = / s/^DEP_FILES = //p' < "$mf" | \ + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do + # Make sure the directory exists. + test -f "$dirpart/$file" && continue + fdir=`AS_DIRNAME(["$file"])` + AS_MKDIR_P([$dirpart/$fdir]) + # echo "creating $dirpart/$file" + echo '# dummy' > "$dirpart/$file" + done +done +])# _AM_OUTPUT_DEPENDENCY_COMMANDS + + +# AM_OUTPUT_DEPENDENCY_COMMANDS +# ----------------------------- +# This macro should only be invoked once -- use via AC_REQUIRE. +# +# This code is only required when automatic dependency tracking +# is enabled. FIXME. This creates each `.P' file that we will +# need in order to bootstrap the dependency handling code. +AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], +[AC_CONFIG_COMMANDS([depfiles], + [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], + [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) +]) + +# Check to see how 'make' treats includes. -*- Autoconf -*- + +# Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# serial 2 + +# AM_MAKE_INCLUDE() +# ----------------- +# Check to see how make treats includes. +AC_DEFUN([AM_MAKE_INCLUDE], +[am_make=${MAKE-make} +cat > confinc << 'END' +am__doit: + @echo done +.PHONY: am__doit +END +# If we don't find an include directive, just comment out the code. +AC_MSG_CHECKING([for style of include used by $am_make]) +am__include="#" +am__quote= +_am_result=none +# First try GNU make style include. +echo "include confinc" > confmf +# We grep out `Entering directory' and `Leaving directory' +# messages which can occur if `w' ends up in MAKEFLAGS. +# In particular we don't look at `^make:' because GNU make might +# be invoked under some other name (usually "gmake"), in which +# case it prints its new name instead of `make'. +if test "`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`" = "done"; then + am__include=include + am__quote= + _am_result=GNU +fi +# Now try BSD make style include. +if test "$am__include" = "#"; then + echo '.include "confinc"' > confmf + if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then + am__include=.include + am__quote="\"" + _am_result=BSD + fi +fi +AC_SUBST([am__include]) +AC_SUBST([am__quote]) +AC_MSG_RESULT([$_am_result]) +rm -f confinc confmf +]) + +# AM_CONDITIONAL -*- Autoconf -*- + +# Copyright 1997, 2000, 2001 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# serial 5 + +AC_PREREQ(2.52) + +# AM_CONDITIONAL(NAME, SHELL-CONDITION) +# ------------------------------------- +# Define a conditional. +AC_DEFUN([AM_CONDITIONAL], +[ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], + [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl +AC_SUBST([$1_TRUE]) +AC_SUBST([$1_FALSE]) +if $2; then + $1_TRUE= + $1_FALSE='#' +else + $1_TRUE='#' + $1_FALSE= +fi +AC_CONFIG_COMMANDS_PRE( +[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then + AC_MSG_ERROR([conditional "$1" was never defined. +Usually this means the macro was only invoked conditionally.]) +fi])]) + +# Like AC_CONFIG_HEADER, but automatically create stamp file. -*- Autoconf -*- + +# Copyright 1996, 1997, 2000, 2001 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +AC_PREREQ([2.52]) + +# serial 6 + +# AM_CONFIG_HEADER is obsolete. It has been replaced by AC_CONFIG_HEADERS. +AU_DEFUN([AM_CONFIG_HEADER], [AC_CONFIG_HEADERS($@)]) + +dnl Copyright (c) 1995, 1996, 1997, 1998 +dnl tising materials mentioning +dnl dnl features or use of this software display the following acknowledgement: +dnl dnl ``This product includes software developed by the University of California, +dnl dnl Lawrence Berkeley Laboratory and its contributors.'' Neither the name of +dnl dnl the University nor the names of its contributors may be used to endorse +dnl dnl or promote products derived from this software without specific prior +dnl dnl written permission. +dnl dnl THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED +dnl dnl WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF +dnl dnl MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +dnl dnl +dnl dnl LBL autoconf macros +dnl dnl +dnl +dnl +dnl Checks to see if the sockaddr struct has the 4.4 BSD sa_len member +dnl borrowed from LBL libpcap +AC_DEFUN(AC_CHECK_SA_LEN, [ + AC_MSG_CHECKING(if sockaddr struct has sa_len member) + AC_CACHE_VAL($1, + AC_TRY_COMPILE([ +# include +# include ], + [u_int i = sizeof(((struct sockaddr *)0)->sa_len)], + $1=yes, + $1=no)) + AC_MSG_RESULT($$1) + if test $$1 = yes ; then + AC_DEFINE([HAVE_SOCKADDR_SA_LEN],1,[Define if struct sockaddr has the sa_len member]) + fi +]) + diff --git a/autogen.sh b/autogen.sh new file mode 100755 index 0000000..9719c23 --- /dev/null +++ b/autogen.sh @@ -0,0 +1,5 @@ +#! /bin/sh + +aclocal -I src/missing/m4 \ +&& automake --add-missing \ +&& autoconf diff --git a/config.guess b/config.guess new file mode 100755 index 0000000..ad5281e --- /dev/null +++ b/config.guess @@ -0,0 +1,1466 @@ +#! /bin/sh +# Attempt to guess a canonical system name. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. + +timestamp='2005-08-03' + +# This file is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA +# 02110-1301, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + + +# Originally written by Per Bothner . +# Please send patches to . Submit a context +# diff and a properly formatted ChangeLog entry. +# +# This script attempts to guess a canonical system name similar to +# config.sub. If it succeeds, it prints the system name on stdout, and +# exits with 0. Otherwise, it exits with 1. +# +# The plan is that this can be called by configure scripts if you +# don't specify an explicit build system type. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] + +Output the configuration name of the system \`$me' is run on. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.guess ($timestamp) + +Originally written by Per Bothner. +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 +Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" >&2 + exit 1 ;; + * ) + break ;; + esac +done + +if test $# != 0; then + echo "$me: too many arguments$help" >&2 + exit 1 +fi + +trap 'exit 1' 1 2 15 + +# CC_FOR_BUILD -- compiler used by this script. Note that the use of a +# compiler to aid in system detection is discouraged as it requires +# temporary files to be created and, as you can see below, it is a +# headache to deal with in a portable fashion. + +# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still +# use `HOST_CC' if defined, but it is deprecated. + +# Portable tmp directory creation inspired by the Autoconf team. + +set_cc_for_build=' +trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; +trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; +: ${TMPDIR=/tmp} ; + { tmp=`(umask 077 && mktemp -d -q "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || + { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || + { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || + { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; +dummy=$tmp/dummy ; +tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; +case $CC_FOR_BUILD,$HOST_CC,$CC in + ,,) echo "int x;" > $dummy.c ; + for c in cc gcc c89 c99 ; do + if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then + CC_FOR_BUILD="$c"; break ; + fi ; + done ; + if test x"$CC_FOR_BUILD" = x ; then + CC_FOR_BUILD=no_compiler_found ; + fi + ;; + ,,*) CC_FOR_BUILD=$CC ;; + ,*,*) CC_FOR_BUILD=$HOST_CC ;; +esac ; set_cc_for_build= ;' + +# This is needed to find uname on a Pyramid OSx when run in the BSD universe. +# (ghazi@noc.rutgers.edu 1994-08-24) +if (test -f /.attbin/uname) >/dev/null 2>&1 ; then + PATH=$PATH:/.attbin ; export PATH +fi + +UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown +UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown +UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown +UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown + +# Note: order is significant - the case branches are not exclusive. + +case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in + *:NetBSD:*:*) + # NetBSD (nbsd) targets should (where applicable) match one or + # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, + # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently + # switched to ELF, *-*-netbsd* would select the old + # object file format. This provides both forward + # compatibility and a consistent mechanism for selecting the + # object file format. + # + # Note: NetBSD doesn't particularly care about the vendor + # portion of the name. We always set it to "unknown". + sysctl="sysctl -n hw.machine_arch" + UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ + /usr/sbin/$sysctl 2>/dev/null || echo unknown)` + case "${UNAME_MACHINE_ARCH}" in + armeb) machine=armeb-unknown ;; + arm*) machine=arm-unknown ;; + sh3el) machine=shl-unknown ;; + sh3eb) machine=sh-unknown ;; + *) machine=${UNAME_MACHINE_ARCH}-unknown ;; + esac + # The Operating System including object format, if it has switched + # to ELF recently, or will in the future. + case "${UNAME_MACHINE_ARCH}" in + arm*|i386|m68k|ns32k|sh3*|sparc|vax) + eval $set_cc_for_build + if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep __ELF__ >/dev/null + then + # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). + # Return netbsd for either. FIX? + os=netbsd + else + os=netbsdelf + fi + ;; + *) + os=netbsd + ;; + esac + # The OS release + # Debian GNU/NetBSD machines have a different userland, and + # thus, need a distinct triplet. However, they do not need + # kernel version information, so it can be replaced with a + # suitable tag, in the style of linux-gnu. + case "${UNAME_VERSION}" in + Debian*) + release='-gnu' + ;; + *) + release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + ;; + esac + # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: + # contains redundant information, the shorter form: + # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. + echo "${machine}-${os}${release}" + exit ;; + *:OpenBSD:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` + echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} + exit ;; + *:ekkoBSD:*:*) + echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} + exit ;; + macppc:MirBSD:*:*) + echo powerppc-unknown-mirbsd${UNAME_RELEASE} + exit ;; + *:MirBSD:*:*) + echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} + exit ;; + alpha:OSF1:*:*) + case $UNAME_RELEASE in + *4.0) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` + ;; + *5.*) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` + ;; + esac + # According to Compaq, /usr/sbin/psrinfo has been available on + # OSF/1 and Tru64 systems produced since 1995. I hope that + # covers most systems running today. This code pipes the CPU + # types through head -n 1, so we only detect the type of CPU 0. + ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` + case "$ALPHA_CPU_TYPE" in + "EV4 (21064)") + UNAME_MACHINE="alpha" ;; + "EV4.5 (21064)") + UNAME_MACHINE="alpha" ;; + "LCA4 (21066/21068)") + UNAME_MACHINE="alpha" ;; + "EV5 (21164)") + UNAME_MACHINE="alphaev5" ;; + "EV5.6 (21164A)") + UNAME_MACHINE="alphaev56" ;; + "EV5.6 (21164PC)") + UNAME_MACHINE="alphapca56" ;; + "EV5.7 (21164PC)") + UNAME_MACHINE="alphapca57" ;; + "EV6 (21264)") + UNAME_MACHINE="alphaev6" ;; + "EV6.7 (21264A)") + UNAME_MACHINE="alphaev67" ;; + "EV6.8CB (21264C)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8AL (21264B)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8CX (21264D)") + UNAME_MACHINE="alphaev68" ;; + "EV6.9A (21264/EV69A)") + UNAME_MACHINE="alphaev69" ;; + "EV7 (21364)") + UNAME_MACHINE="alphaev7" ;; + "EV7.9 (21364A)") + UNAME_MACHINE="alphaev79" ;; + esac + # A Pn.n version is a patched version. + # A Vn.n version is a released version. + # A Tn.n version is a released field test version. + # A Xn.n version is an unreleased experimental baselevel. + # 1.2 uses "1.2" for uname -r. + echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + exit ;; + Alpha\ *:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # Should we change UNAME_MACHINE based on the output of uname instead + # of the specific Alpha model? + echo alpha-pc-interix + exit ;; + 21064:Windows_NT:50:3) + echo alpha-dec-winnt3.5 + exit ;; + Amiga*:UNIX_System_V:4.0:*) + echo m68k-unknown-sysv4 + exit ;; + *:[Aa]miga[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-amigaos + exit ;; + *:[Mm]orph[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-morphos + exit ;; + *:OS/390:*:*) + echo i370-ibm-openedition + exit ;; + *:z/VM:*:*) + echo s390-ibm-zvmoe + exit ;; + *:OS400:*:*) + echo powerpc-ibm-os400 + exit ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) + echo arm-acorn-riscix${UNAME_RELEASE} + exit ;; + arm:riscos:*:*|arm:RISCOS:*:*) + echo arm-unknown-riscos + exit ;; + SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) + echo hppa1.1-hitachi-hiuxmpp + exit ;; + Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) + # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. + if test "`(/bin/universe) 2>/dev/null`" = att ; then + echo pyramid-pyramid-sysv3 + else + echo pyramid-pyramid-bsd + fi + exit ;; + NILE*:*:*:dcosx) + echo pyramid-pyramid-svr4 + exit ;; + DRS?6000:unix:4.0:6*) + echo sparc-icl-nx6 + exit ;; + DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) + case `/usr/bin/uname -p` in + sparc) echo sparc-icl-nx7; exit ;; + esac ;; + sun4H:SunOS:5.*:*) + echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) + echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + i86pc:SunOS:5.*:*) + echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:6*:*) + # According to config.sub, this is the proper way to canonicalize + # SunOS6. Hard to guess exactly what SunOS6 will be like, but + # it's likely to be more like Solaris than SunOS4. + echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:*:*) + case "`/usr/bin/arch -k`" in + Series*|S4*) + UNAME_RELEASE=`uname -v` + ;; + esac + # Japanese Language versions have a version number like `4.1.3-JL'. + echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` + exit ;; + sun3*:SunOS:*:*) + echo m68k-sun-sunos${UNAME_RELEASE} + exit ;; + sun*:*:4.2BSD:*) + UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` + test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 + case "`/bin/arch`" in + sun3) + echo m68k-sun-sunos${UNAME_RELEASE} + ;; + sun4) + echo sparc-sun-sunos${UNAME_RELEASE} + ;; + esac + exit ;; + aushp:SunOS:*:*) + echo sparc-auspex-sunos${UNAME_RELEASE} + exit ;; + # The situation for MiNT is a little confusing. The machine name + # can be virtually everything (everything which is not + # "atarist" or "atariste" at least should have a processor + # > m68000). The system name ranges from "MiNT" over "FreeMiNT" + # to the lowercase version "mint" (or "freemint"). Finally + # the system name "TOS" denotes a system which is actually not + # MiNT. But MiNT is downward compatible to TOS, so this should + # be no problem. + atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) + echo m68k-milan-mint${UNAME_RELEASE} + exit ;; + hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) + echo m68k-hades-mint${UNAME_RELEASE} + exit ;; + *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) + echo m68k-unknown-mint${UNAME_RELEASE} + exit ;; + m68k:machten:*:*) + echo m68k-apple-machten${UNAME_RELEASE} + exit ;; + powerpc:machten:*:*) + echo powerpc-apple-machten${UNAME_RELEASE} + exit ;; + RISC*:Mach:*:*) + echo mips-dec-mach_bsd4.3 + exit ;; + RISC*:ULTRIX:*:*) + echo mips-dec-ultrix${UNAME_RELEASE} + exit ;; + VAX*:ULTRIX*:*:*) + echo vax-dec-ultrix${UNAME_RELEASE} + exit ;; + 2020:CLIX:*:* | 2430:CLIX:*:*) + echo clipper-intergraph-clix${UNAME_RELEASE} + exit ;; + mips:*:*:UMIPS | mips:*:*:RISCos) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c +#ifdef __cplusplus +#include /* for printf() prototype */ + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif + #if defined (host_mips) && defined (MIPSEB) + #if defined (SYSTYPE_SYSV) + printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_SVR4) + printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) + printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); + #endif + #endif + exit (-1); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && + dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && + SYSTEM_NAME=`$dummy $dummyarg` && + { echo "$SYSTEM_NAME"; exit; } + echo mips-mips-riscos${UNAME_RELEASE} + exit ;; + Motorola:PowerMAX_OS:*:*) + echo powerpc-motorola-powermax + exit ;; + Motorola:*:4.3:PL8-*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:Power_UNIX:*:*) + echo powerpc-harris-powerunix + exit ;; + m88k:CX/UX:7*:*) + echo m88k-harris-cxux7 + exit ;; + m88k:*:4*:R4*) + echo m88k-motorola-sysv4 + exit ;; + m88k:*:3*:R3*) + echo m88k-motorola-sysv3 + exit ;; + AViiON:dgux:*:*) + # DG/UX returns AViiON for all architectures + UNAME_PROCESSOR=`/usr/bin/uname -p` + if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] + then + if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ + [ ${TARGET_BINARY_INTERFACE}x = x ] + then + echo m88k-dg-dgux${UNAME_RELEASE} + else + echo m88k-dg-dguxbcs${UNAME_RELEASE} + fi + else + echo i586-dg-dgux${UNAME_RELEASE} + fi + exit ;; + M88*:DolphinOS:*:*) # DolphinOS (SVR3) + echo m88k-dolphin-sysv3 + exit ;; + M88*:*:R3*:*) + # Delta 88k system running SVR3 + echo m88k-motorola-sysv3 + exit ;; + XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) + echo m88k-tektronix-sysv3 + exit ;; + Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) + echo m68k-tektronix-bsd + exit ;; + *:IRIX*:*:*) + echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` + exit ;; + ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. + echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id + exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + i*86:AIX:*:*) + echo i386-ibm-aix + exit ;; + ia64:AIX:*:*) + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} + exit ;; + *:AIX:2:3) + if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + + main() + { + if (!__power_pc()) + exit(1); + puts("powerpc-ibm-aix3.2.5"); + exit(0); + } +EOF + if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` + then + echo "$SYSTEM_NAME" + else + echo rs6000-ibm-aix3.2.5 + fi + elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then + echo rs6000-ibm-aix3.2.4 + else + echo rs6000-ibm-aix3.2 + fi + exit ;; + *:AIX:*:[45]) + IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` + if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then + IBM_ARCH=rs6000 + else + IBM_ARCH=powerpc + fi + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${IBM_ARCH}-ibm-aix${IBM_REV} + exit ;; + *:AIX:*:*) + echo rs6000-ibm-aix + exit ;; + ibmrt:4.4BSD:*|romp-ibm:BSD:*) + echo romp-ibm-bsd4.4 + exit ;; + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and + echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to + exit ;; # report: romp-ibm BSD 4.3 + *:BOSX:*:*) + echo rs6000-bull-bosx + exit ;; + DPX/2?00:B.O.S.:*:*) + echo m68k-bull-sysv3 + exit ;; + 9000/[34]??:4.3bsd:1.*:*) + echo m68k-hp-bsd + exit ;; + hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) + echo m68k-hp-bsd4.4 + exit ;; + 9000/[34678]??:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + case "${UNAME_MACHINE}" in + 9000/31? ) HP_ARCH=m68000 ;; + 9000/[34]?? ) HP_ARCH=m68k ;; + 9000/[678][0-9][0-9]) + if [ -x /usr/bin/getconf ]; then + sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` + sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` + case "${sc_cpu_version}" in + 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 + 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 + 532) # CPU_PA_RISC2_0 + case "${sc_kernel_bits}" in + 32) HP_ARCH="hppa2.0n" ;; + 64) HP_ARCH="hppa2.0w" ;; + '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 + esac ;; + esac + fi + if [ "${HP_ARCH}" = "" ]; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + + #define _HPUX_SOURCE + #include + #include + + int main () + { + #if defined(_SC_KERNEL_BITS) + long bits = sysconf(_SC_KERNEL_BITS); + #endif + long cpu = sysconf (_SC_CPU_VERSION); + + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1"); break; + case CPU_PA_RISC2_0: + #if defined(_SC_KERNEL_BITS) + switch (bits) + { + case 64: puts ("hppa2.0w"); break; + case 32: puts ("hppa2.0n"); break; + default: puts ("hppa2.0"); break; + } break; + #else /* !defined(_SC_KERNEL_BITS) */ + puts ("hppa2.0"); break; + #endif + default: puts ("hppa1.0"); break; + } + exit (0); + } +EOF + (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` + test -z "$HP_ARCH" && HP_ARCH=hppa + fi ;; + esac + if [ ${HP_ARCH} = "hppa2.0w" ] + then + eval $set_cc_for_build + + # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating + # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler + # generating 64-bit code. GNU and HP use different nomenclature: + # + # $ CC_FOR_BUILD=cc ./config.guess + # => hppa2.0w-hp-hpux11.23 + # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess + # => hppa64-hp-hpux11.23 + + if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | + grep __LP64__ >/dev/null + then + HP_ARCH="hppa2.0w" + else + HP_ARCH="hppa64" + fi + fi + echo ${HP_ARCH}-hp-hpux${HPUX_REV} + exit ;; + ia64:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + echo ia64-hp-hpux${HPUX_REV} + exit ;; + 3050*:HI-UX:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + int + main () + { + long cpu = sysconf (_SC_CPU_VERSION); + /* The order matters, because CPU_IS_HP_MC68K erroneously returns + true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct + results, however. */ + if (CPU_IS_PA_RISC (cpu)) + { + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; + case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; + default: puts ("hppa-hitachi-hiuxwe2"); break; + } + } + else if (CPU_IS_HP_MC68K (cpu)) + puts ("m68k-hitachi-hiuxwe2"); + else puts ("unknown-hitachi-hiuxwe2"); + exit (0); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && + { echo "$SYSTEM_NAME"; exit; } + echo unknown-hitachi-hiuxwe2 + exit ;; + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) + echo hppa1.1-hp-bsd + exit ;; + 9000/8??:4.3bsd:*:*) + echo hppa1.0-hp-bsd + exit ;; + *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) + echo hppa1.0-hp-mpeix + exit ;; + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) + echo hppa1.1-hp-osf + exit ;; + hp8??:OSF1:*:*) + echo hppa1.0-hp-osf + exit ;; + i*86:OSF1:*:*) + if [ -x /usr/sbin/sysversion ] ; then + echo ${UNAME_MACHINE}-unknown-osf1mk + else + echo ${UNAME_MACHINE}-unknown-osf1 + fi + exit ;; + parisc*:Lites*:*:*) + echo hppa1.1-hp-lites + exit ;; + C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) + echo c1-convex-bsd + exit ;; + C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) + echo c34-convex-bsd + exit ;; + C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) + echo c38-convex-bsd + exit ;; + C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) + echo c4-convex-bsd + exit ;; + CRAY*Y-MP:*:*:*) + echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*[A-Z]90:*:*:*) + echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ + | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ + -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ + -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*TS:*:*:*) + echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*T3E:*:*:*) + echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*SV1:*:*:*) + echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + *:UNICOS/mp:*:*) + echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) + FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` + echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + 5000:UNIX_System_V:4.*:*) + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` + echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) + echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} + exit ;; + sparc*:BSD/OS:*:*) + echo sparc-unknown-bsdi${UNAME_RELEASE} + exit ;; + *:BSD/OS:*:*) + echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} + exit ;; + *:FreeBSD:*:*) + echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + exit ;; + i*:CYGWIN*:*) + echo ${UNAME_MACHINE}-pc-cygwin + exit ;; + i*:MINGW*:*) + echo ${UNAME_MACHINE}-pc-mingw32 + exit ;; + i*:windows32*:*) + # uname -m includes "-pc" on this system. + echo ${UNAME_MACHINE}-mingw32 + exit ;; + i*:PW*:*) + echo ${UNAME_MACHINE}-pc-pw32 + exit ;; + x86:Interix*:[34]*) + echo i586-pc-interix${UNAME_RELEASE}|sed -e 's/\..*//' + exit ;; + [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) + echo i${UNAME_MACHINE}-pc-mks + exit ;; + i*:Windows_NT*:* | Pentium*:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we + # UNAME_MACHINE based on the output of uname instead of i386? + echo i586-pc-interix + exit ;; + i*:UWIN*:*) + echo ${UNAME_MACHINE}-pc-uwin + exit ;; + amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) + echo x86_64-unknown-cygwin + exit ;; + p*:CYGWIN*:*) + echo powerpcle-unknown-cygwin + exit ;; + prep*:SunOS:5.*:*) + echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + *:GNU:*:*) + # the GNU system + echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + exit ;; + *:GNU/*:*:*) + # other systems with GNU libc and userland + echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu + exit ;; + i*86:Minix:*:*) + echo ${UNAME_MACHINE}-pc-minix + exit ;; + arm*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + cris:Linux:*:*) + echo cris-axis-linux-gnu + exit ;; + crisv32:Linux:*:*) + echo crisv32-axis-linux-gnu + exit ;; + frv:Linux:*:*) + echo frv-unknown-linux-gnu + exit ;; + ia64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + m32r*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + m68*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + mips:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef mips + #undef mipsel + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=mipsel + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=mips + #else + CPU= + #endif + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=` + test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } + ;; + mips64:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef mips64 + #undef mips64el + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=mips64el + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=mips64 + #else + CPU= + #endif + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=` + test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } + ;; + or32:Linux:*:*) + echo or32-unknown-linux-gnu + exit ;; + ppc:Linux:*:*) + echo powerpc-unknown-linux-gnu + exit ;; + ppc64:Linux:*:*) + echo powerpc64-unknown-linux-gnu + exit ;; + alpha:Linux:*:*) + case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in + EV5) UNAME_MACHINE=alphaev5 ;; + EV56) UNAME_MACHINE=alphaev56 ;; + PCA56) UNAME_MACHINE=alphapca56 ;; + PCA57) UNAME_MACHINE=alphapca56 ;; + EV6) UNAME_MACHINE=alphaev6 ;; + EV67) UNAME_MACHINE=alphaev67 ;; + EV68*) UNAME_MACHINE=alphaev68 ;; + esac + objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null + if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi + echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} + exit ;; + parisc:Linux:*:* | hppa:Linux:*:*) + # Look for CPU level + case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in + PA7*) echo hppa1.1-unknown-linux-gnu ;; + PA8*) echo hppa2.0-unknown-linux-gnu ;; + *) echo hppa-unknown-linux-gnu ;; + esac + exit ;; + parisc64:Linux:*:* | hppa64:Linux:*:*) + echo hppa64-unknown-linux-gnu + exit ;; + s390:Linux:*:* | s390x:Linux:*:*) + echo ${UNAME_MACHINE}-ibm-linux + exit ;; + sh64*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + sh*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + sparc:Linux:*:* | sparc64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + x86_64:Linux:*:*) + echo x86_64-unknown-linux-gnu + exit ;; + i*86:Linux:*:*) + # The BFD linker knows what the default object file format is, so + # first see if it will tell us. cd to the root directory to prevent + # problems with other programs or directories called `ld' in the path. + # Set LC_ALL=C to ensure ld outputs messages in English. + ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \ + | sed -ne '/supported targets:/!d + s/[ ][ ]*/ /g + s/.*supported targets: *// + s/ .*// + p'` + case "$ld_supported_targets" in + elf32-i386) + TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu" + ;; + a.out-i386-linux) + echo "${UNAME_MACHINE}-pc-linux-gnuaout" + exit ;; + coff-i386) + echo "${UNAME_MACHINE}-pc-linux-gnucoff" + exit ;; + "") + # Either a pre-BFD a.out linker (linux-gnuoldld) or + # one that does not give us useful --help. + echo "${UNAME_MACHINE}-pc-linux-gnuoldld" + exit ;; + esac + # Determine whether the default compiler is a.out or elf + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + #ifdef __ELF__ + # ifdef __GLIBC__ + # if __GLIBC__ >= 2 + LIBC=gnu + # else + LIBC=gnulibc1 + # endif + # else + LIBC=gnulibc1 + # endif + #else + #ifdef __INTEL_COMPILER + LIBC=gnu + #else + LIBC=gnuaout + #endif + #endif + #ifdef __dietlibc__ + LIBC=dietlibc + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=` + test x"${LIBC}" != x && { + echo "${UNAME_MACHINE}-pc-linux-${LIBC}" + exit + } + test x"${TENTATIVE}" != x && { echo "${TENTATIVE}"; exit; } + ;; + i*86:DYNIX/ptx:4*:*) + # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. + # earlier versions are messed up and put the nodename in both + # sysname and nodename. + echo i386-sequent-sysv4 + exit ;; + i*86:UNIX_SV:4.2MP:2.*) + # Unixware is an offshoot of SVR4, but it has its own version + # number series starting with 2... + # I am not positive that other SVR4 systems won't match this, + # I just have to hope. -- rms. + # Use sysv4.2uw... so that sysv4* matches it. + echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} + exit ;; + i*86:OS/2:*:*) + # If we were able to find `uname', then EMX Unix compatibility + # is probably installed. + echo ${UNAME_MACHINE}-pc-os2-emx + exit ;; + i*86:XTS-300:*:STOP) + echo ${UNAME_MACHINE}-unknown-stop + exit ;; + i*86:atheos:*:*) + echo ${UNAME_MACHINE}-unknown-atheos + exit ;; + i*86:syllable:*:*) + echo ${UNAME_MACHINE}-pc-syllable + exit ;; + i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*) + echo i386-unknown-lynxos${UNAME_RELEASE} + exit ;; + i*86:*DOS:*:*) + echo ${UNAME_MACHINE}-pc-msdosdjgpp + exit ;; + i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) + UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` + if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then + echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} + else + echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} + fi + exit ;; + i*86:*:5:[678]*) + # UnixWare 7.x, OpenUNIX and OpenServer 6. + case `/bin/uname -X | grep "^Machine"` in + *486*) UNAME_MACHINE=i486 ;; + *Pentium) UNAME_MACHINE=i586 ;; + *Pent*|*Celeron) UNAME_MACHINE=i686 ;; + esac + echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} + exit ;; + i*86:*:3.2:*) + if test -f /usr/options/cb.name; then + UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then + UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` + (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 + (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ + && UNAME_MACHINE=i586 + (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ + && UNAME_MACHINE=i686 + (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ + && UNAME_MACHINE=i686 + echo ${UNAME_MACHINE}-pc-sco$UNAME_REL + else + echo ${UNAME_MACHINE}-pc-sysv32 + fi + exit ;; + pc:*:*:*) + # Left here for compatibility: + # uname -m prints for DJGPP always 'pc', but it prints nothing about + # the processor, so we play safe by assuming i386. + echo i386-pc-msdosdjgpp + exit ;; + Intel:Mach:3*:*) + echo i386-pc-mach3 + exit ;; + paragon:*:*:*) + echo i860-intel-osf1 + exit ;; + i860:*:4.*:*) # i860-SVR4 + if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then + echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 + else # Add other i860-SVR4 vendors below as they are discovered. + echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 + fi + exit ;; + mini*:CTIX:SYS*5:*) + # "miniframe" + echo m68010-convergent-sysv + exit ;; + mc68k:UNIX:SYSTEM5:3.51m) + echo m68k-convergent-sysv + exit ;; + M680?0:D-NIX:5.3:*) + echo m68k-diab-dnix + exit ;; + M68*:*:R3V[5678]*:*) + test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; + 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) + OS_REL='' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; + 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4; exit; } ;; + m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) + echo m68k-unknown-lynxos${UNAME_RELEASE} + exit ;; + mc68030:UNIX_System_V:4.*:*) + echo m68k-atari-sysv4 + exit ;; + TSUNAMI:LynxOS:2.*:*) + echo sparc-unknown-lynxos${UNAME_RELEASE} + exit ;; + rs6000:LynxOS:2.*:*) + echo rs6000-unknown-lynxos${UNAME_RELEASE} + exit ;; + PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*) + echo powerpc-unknown-lynxos${UNAME_RELEASE} + exit ;; + SM[BE]S:UNIX_SV:*:*) + echo mips-dde-sysv${UNAME_RELEASE} + exit ;; + RM*:ReliantUNIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + RM*:SINIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + *:SINIX-*:*:*) + if uname -p 2>/dev/null >/dev/null ; then + UNAME_MACHINE=`(uname -p) 2>/dev/null` + echo ${UNAME_MACHINE}-sni-sysv4 + else + echo ns32k-sni-sysv + fi + exit ;; + PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says + echo i586-unisys-sysv4 + exit ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes . + # How about differentiating between stratus architectures? -djm + echo hppa1.1-stratus-sysv4 + exit ;; + *:*:*:FTX*) + # From seanf@swdc.stratus.com. + echo i860-stratus-sysv4 + exit ;; + i*86:VOS:*:*) + # From Paul.Green@stratus.com. + echo ${UNAME_MACHINE}-stratus-vos + exit ;; + *:VOS:*:*) + # From Paul.Green@stratus.com. + echo hppa1.1-stratus-vos + exit ;; + mc68*:A/UX:*:*) + echo m68k-apple-aux${UNAME_RELEASE} + exit ;; + news*:NEWS-OS:6*:*) + echo mips-sony-newsos6 + exit ;; + R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) + if [ -d /usr/nec ]; then + echo mips-nec-sysv${UNAME_RELEASE} + else + echo mips-unknown-sysv${UNAME_RELEASE} + fi + exit ;; + BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. + echo powerpc-be-beos + exit ;; + BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. + echo powerpc-apple-beos + exit ;; + BePC:BeOS:*:*) # BeOS running on Intel PC compatible. + echo i586-pc-beos + exit ;; + SX-4:SUPER-UX:*:*) + echo sx4-nec-superux${UNAME_RELEASE} + exit ;; + SX-5:SUPER-UX:*:*) + echo sx5-nec-superux${UNAME_RELEASE} + exit ;; + SX-6:SUPER-UX:*:*) + echo sx6-nec-superux${UNAME_RELEASE} + exit ;; + Power*:Rhapsody:*:*) + echo powerpc-apple-rhapsody${UNAME_RELEASE} + exit ;; + *:Rhapsody:*:*) + echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} + exit ;; + *:Darwin:*:*) + UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown + case $UNAME_PROCESSOR in + *86) UNAME_PROCESSOR=i686 ;; + unknown) UNAME_PROCESSOR=powerpc ;; + esac + echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} + exit ;; + *:procnto*:*:* | *:QNX:[0123456789]*:*) + UNAME_PROCESSOR=`uname -p` + if test "$UNAME_PROCESSOR" = "x86"; then + UNAME_PROCESSOR=i386 + UNAME_MACHINE=pc + fi + echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} + exit ;; + *:QNX:*:4*) + echo i386-pc-qnx + exit ;; + NSE-?:NONSTOP_KERNEL:*:*) + echo nse-tandem-nsk${UNAME_RELEASE} + exit ;; + NSR-?:NONSTOP_KERNEL:*:*) + echo nsr-tandem-nsk${UNAME_RELEASE} + exit ;; + *:NonStop-UX:*:*) + echo mips-compaq-nonstopux + exit ;; + BS2000:POSIX*:*:*) + echo bs2000-siemens-sysv + exit ;; + DS/*:UNIX_System_V:*:*) + echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} + exit ;; + *:Plan9:*:*) + # "uname -m" is not consistent, so use $cputype instead. 386 + # is converted to i386 for consistency with other x86 + # operating systems. + if test "$cputype" = "386"; then + UNAME_MACHINE=i386 + else + UNAME_MACHINE="$cputype" + fi + echo ${UNAME_MACHINE}-unknown-plan9 + exit ;; + *:TOPS-10:*:*) + echo pdp10-unknown-tops10 + exit ;; + *:TENEX:*:*) + echo pdp10-unknown-tenex + exit ;; + KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) + echo pdp10-dec-tops20 + exit ;; + XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) + echo pdp10-xkl-tops20 + exit ;; + *:TOPS-20:*:*) + echo pdp10-unknown-tops20 + exit ;; + *:ITS:*:*) + echo pdp10-unknown-its + exit ;; + SEI:*:*:SEIUX) + echo mips-sei-seiux${UNAME_RELEASE} + exit ;; + *:DragonFly:*:*) + echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + exit ;; + *:*VMS:*:*) + UNAME_MACHINE=`(uname -p) 2>/dev/null` + case "${UNAME_MACHINE}" in + A*) echo alpha-dec-vms ; exit ;; + I*) echo ia64-dec-vms ; exit ;; + V*) echo vax-dec-vms ; exit ;; + esac ;; + *:XENIX:*:SysV) + echo i386-pc-xenix + exit ;; + i*86:skyos:*:*) + echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' + exit ;; +esac + +#echo '(No uname command or uname output not recognized.)' 1>&2 +#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 + +eval $set_cc_for_build +cat >$dummy.c < +# include +#endif +main () +{ +#if defined (sony) +#if defined (MIPSEB) + /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, + I don't know.... */ + printf ("mips-sony-bsd\n"); exit (0); +#else +#include + printf ("m68k-sony-newsos%s\n", +#ifdef NEWSOS4 + "4" +#else + "" +#endif + ); exit (0); +#endif +#endif + +#if defined (__arm) && defined (__acorn) && defined (__unix) + printf ("arm-acorn-riscix\n"); exit (0); +#endif + +#if defined (hp300) && !defined (hpux) + printf ("m68k-hp-bsd\n"); exit (0); +#endif + +#if defined (NeXT) +#if !defined (__ARCHITECTURE__) +#define __ARCHITECTURE__ "m68k" +#endif + int version; + version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; + if (version < 4) + printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); + else + printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); + exit (0); +#endif + +#if defined (MULTIMAX) || defined (n16) +#if defined (UMAXV) + printf ("ns32k-encore-sysv\n"); exit (0); +#else +#if defined (CMU) + printf ("ns32k-encore-mach\n"); exit (0); +#else + printf ("ns32k-encore-bsd\n"); exit (0); +#endif +#endif +#endif + +#if defined (__386BSD__) + printf ("i386-pc-bsd\n"); exit (0); +#endif + +#if defined (sequent) +#if defined (i386) + printf ("i386-sequent-dynix\n"); exit (0); +#endif +#if defined (ns32000) + printf ("ns32k-sequent-dynix\n"); exit (0); +#endif +#endif + +#if defined (_SEQUENT_) + struct utsname un; + + uname(&un); + + if (strncmp(un.version, "V2", 2) == 0) { + printf ("i386-sequent-ptx2\n"); exit (0); + } + if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ + printf ("i386-sequent-ptx1\n"); exit (0); + } + printf ("i386-sequent-ptx\n"); exit (0); + +#endif + +#if defined (vax) +# if !defined (ultrix) +# include +# if defined (BSD) +# if BSD == 43 + printf ("vax-dec-bsd4.3\n"); exit (0); +# else +# if BSD == 199006 + printf ("vax-dec-bsd4.3reno\n"); exit (0); +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# endif +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# else + printf ("vax-dec-ultrix\n"); exit (0); +# endif +#endif + +#if defined (alliant) && defined (i860) + printf ("i860-alliant-bsd\n"); exit (0); +#endif + + exit (1); +} +EOF + +$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` && + { echo "$SYSTEM_NAME"; exit; } + +# Apollos put the system type in the environment. + +test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; } + +# Convex versions that predate uname can use getsysinfo(1) + +if [ -x /usr/convex/getsysinfo ] +then + case `getsysinfo -f cpu_type` in + c1*) + echo c1-convex-bsd + exit ;; + c2*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + c34*) + echo c34-convex-bsd + exit ;; + c38*) + echo c38-convex-bsd + exit ;; + c4*) + echo c4-convex-bsd + exit ;; + esac +fi + +cat >&2 < in order to provide the needed +information to handle your system. + +config.guess timestamp = $timestamp + +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null` + +hostinfo = `(hostinfo) 2>/dev/null` +/bin/universe = `(/bin/universe) 2>/dev/null` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` +/bin/arch = `(/bin/arch) 2>/dev/null` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` + +UNAME_MACHINE = ${UNAME_MACHINE} +UNAME_RELEASE = ${UNAME_RELEASE} +UNAME_SYSTEM = ${UNAME_SYSTEM} +UNAME_VERSION = ${UNAME_VERSION} +EOF + +exit 1 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/config.h.in b/config.h.in new file mode 100644 index 0000000..4b96e1f --- /dev/null +++ b/config.h.in @@ -0,0 +1,384 @@ +/* config.h.in. Generated from configure.ac by autoheader. */ + +/* Define to one to enable dirty buffer support. May affect results. */ +#undef DIRTY + +/* Define to 1 if you have the `alarm' function. */ +#undef HAVE_ALARM + +/* Define to 1 if you have the header file. */ +#undef HAVE_ARPA_INET_H + +/* Define to 1 if you have the `bindprocessor' function. */ +#undef HAVE_BINDPROCESSOR + +/* Define to 1 if you have the `bind_to_cpu_id' function. */ +#undef HAVE_BIND_TO_CPU_ID + +/* Define to 1 if you have the `bzero' function. */ +#undef HAVE_BZERO + +/* Define to 1 if you have the header file. */ +#undef HAVE_ENDIAN_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_ERRNO_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_FCNTL_H + +/* Define to 1 if you have the `fork' function. */ +#undef HAVE_FORK + +/* Define to 1 if you have the `getaddrinfo' function. */ +#undef HAVE_GETADDRINFO + +/* Define to 1 if you have the `gethostbyname' function. */ +#undef HAVE_GETHOSTBYNAME + +/* Define to 1 if you have the `gethrtime' function. */ +#undef HAVE_GETHRTIME + +/* Define to 1 if you have the `getifaddrs' function. */ +#undef HAVE_GETIFADDRS + +/* Define to 1 if you have the `getnameinfo' function. */ +#undef HAVE_GETNAMEINFO + +/* Define to 1 if you have the `getpagesize' function. */ +#undef HAVE_GETPAGESIZE + +/* Define to 1 if you have the `gettimeofday' function. */ +#undef HAVE_GETTIMEOFDAY + +/* Define to one to include ICSC-EXS tests. */ +#undef HAVE_ICSC_EXS + +/* Define to 1 if you have the header file. */ +#undef HAVE_IFADDRS_H + +/* Define to 1 if you have the `inet_ntoa' function. */ +#undef HAVE_INET_NTOA + +/* Define to 1 if you have the `inet_ntop' function. */ +#undef HAVE_INET_NTOP + +/* Define to 1 if you have the header file. */ +#undef HAVE_INTTYPES_H + +/* Define to 1 if you have the `devinfo' library (-ldevinfo). */ +#undef HAVE_LIBDEVINFO + +/* Define to 1 if you have the `dl' library (-ldl). */ +#undef HAVE_LIBDL + +/* Define to 1 if you have the `exs' library (-lexs). */ +#undef HAVE_LIBEXS + +/* Define to 1 if you have the `kstat' library (-lkstat). */ +#undef HAVE_LIBKSTAT + +/* Define to 1 if you have the `m' library (-lm). */ +#undef HAVE_LIBM + +/* Define to 1 if you have the `mach' library (-lmach). */ +#undef HAVE_LIBMACH + +/* Define to 1 if you have the `nsl' library (-lnsl). */ +#undef HAVE_LIBNSL + +/* Define to 1 if you have the `perfstat' library (-lperfstat). */ +#undef HAVE_LIBPERFSTAT + +/* Define to 1 if you have the `sctp' library (-lsctp). */ +#undef HAVE_LIBSCTP + +/* Define to 1 if you have the `sdp' library (-lsdp). */ +#undef HAVE_LIBSDP + +/* Define to 1 if you have the `sendfile' library (-lsendfile). */ +#undef HAVE_LIBSENDFILE + +/* Define to 1 if you have the `smbios' library (-lsmbios). */ +#undef HAVE_LIBSMBIOS + +/* Define to 1 if you have the `socket' library (-lsocket). */ +#undef HAVE_LIBSOCKET + +/* Define to 1 if you have the header file. */ +#undef HAVE_LIMITS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_MALLOC_H + +/* Define to 1 if you have the `memcpy' function. */ +#undef HAVE_MEMCPY + +/* Define to 1 if you have the header file. */ +#undef HAVE_MEMORY_H + +/* Define to 1 if you have the `memset' function. */ +#undef HAVE_MEMSET + +/* Define to 1 if you have a working `mmap' system call. */ +#undef HAVE_MMAP + +/* Define to 1 if you have the `mpctl' function. */ +#undef HAVE_MPCTL + +/* Define to 1 if you have the `munmap' function. */ +#undef HAVE_MUNMAP + +/* Define to 1 if you have the header file. */ +#undef HAVE_NETDB_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_NETINET_IN_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_NETINET_SCTP_H + +/* Define to 1 if you have the `processor_bind' function. */ +#undef HAVE_PROCESSOR_BIND + +/* Define to 1 if you have the `sched_setaffinity' function. */ +#undef HAVE_SCHED_SETAFFINITY + +/* Define to 1 if `struct sctp_event_subscribe' has a + `sctp_adaptation_layer_event' member */ +#undef HAVE_SCTP_ADAPTATION_LAYER_EVENT + +/* Define to 1 if you have the `select' function. */ +#undef HAVE_SELECT + +/* Define to 1 if you have the `sendfile' function. */ +#undef HAVE_SENDFILE + +/* Define to 1 if you have the header file. */ +#undef HAVE_SIGNAL_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SMBIOS_SYSTEMINFO_H + +/* Define if struct sockaddr has the sa_len member */ +#undef HAVE_SOCKADDR_SA_LEN + +/* Define to 1 if you have the `socket' function. */ +#undef HAVE_SOCKET + +/* Define to 1 if you have the `sqrt' function. */ +#undef HAVE_SQRT + +/* Define to 1 if stdbool.h conforms to C99. */ +#undef HAVE_STDBOOL_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDINT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDLIB_H + +/* Define to 1 if you have the `strcasecmp' function. */ +#undef HAVE_STRCASECMP + +/* Define to 1 if you have the `strchr' function. */ +#undef HAVE_STRCHR + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRINGS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRING_H + +/* Define to 1 if you have the `strstr' function. */ +#undef HAVE_STRSTR + +/* Define to 1 if you have the `strtoul' function. */ +#undef HAVE_STRTOUL + +/* Define to 1 if defines `struct sockaddr_storage' */ +#undef HAVE_STRUCT_SOCKADDR_STORAGE + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_IOCTL_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_MMAN_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_PARAM_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_SBMIOS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_SELECT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_SMBIOS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_SOCKET_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_SOCKIO_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_STAT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TIME_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define to 1 if you have that is POSIX.1 compatible. */ +#undef HAVE_SYS_WAIT_H + +/* Define to 1 if you have the `uname' function. */ +#undef HAVE_UNAME + +/* Define to 1 if you have the header file. */ +#undef HAVE_UNISTD_H + +/* Define to 1 if you have the `vfork' function. */ +#undef HAVE_VFORK + +/* Define to 1 if you have the header file. */ +#undef HAVE_VFORK_H + +/* Define to 1 if `fork' works. */ +#undef HAVE_WORKING_FORK + +/* Define to 1 if `vfork' works. */ +#undef HAVE_WORKING_VFORK + +/* Define to 1 if the system has the type `_Bool'. */ +#undef HAVE__BOOL + +/* Define to 1 if `h_errno' is declared by */ +#undef H_ERRNO_DECLARED + +/* Name of package */ +#undef PACKAGE + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* Define as the return type of signal handlers (`int' or `void'). */ +#undef RETSIGTYPE + +/* Define to the type of arg 1 for `select'. */ +#undef SELECT_TYPE_ARG1 + +/* Define to the type of args 2, 3 and 4 for `select'. */ +#undef SELECT_TYPE_ARG234 + +/* Define to the type of arg 5 for `select'. */ +#undef SELECT_TYPE_ARG5 + +/* Define to 1 if the `setpgrp' function takes no argument. */ +#undef SETPGRP_VOID + +/* Define to 1 if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* Define to 1 if you can safely include both and . */ +#undef TIME_WITH_SYS_TIME + +/* Use Solaris's kstat interface to measure CPU util. */ +#undef USE_KSTAT + +/* Use looper/soaker processes to measure CPU util. */ +#undef USE_LOOPER + +/* Use MacOS X's host_info interface to measure CPU util. */ +#undef USE_OSX + +/* Use AIX's perfstat interface to measure CPU util. */ +#undef USE_PERFSTAT + +/* Use Linux's procstat interface to measure CPU util. */ +#undef USE_PROC_STAT + +/* Use HP-UX's pstat interface to measure CPU util. */ +#undef USE_PSTAT + +/* Use MumbleBSD's sysctl interface to measure CPU util. */ +#undef USE_SYSCTL + +/* Version number of package */ +#undef VERSION + +/* Define to one to include DCCP tests. */ +#undef WANT_DCCP + +/* Define to one to enable demo support. May affect results. */ +#undef WANT_DEMO + +/* Define to one to include DLPI tests. */ +#undef WANT_DLPI + +/* Define to one to enable initial _RR burst support. May affect results. */ +#undef WANT_FIRST_BURST + +/* Define to one to enable histogram support. May affect results. */ +#undef WANT_HISTOGRAM + +/* Define to one to enable paced operation support. May affect results. */ +#undef WANT_INTERVALS + +/* Define to one to include OMNI tests. */ +#undef WANT_OMNI + +/* Define to one to include SCTP tests. */ +#undef WANT_SCTP + +/* Define to one to include SDP tests. */ +#undef WANT_SDP + +/* Define to one to spin waiting on paced operation. WILL AFFEFCT CPU + UTILIZATION */ +#undef WANT_SPIN + +/* Define to one to include Unix Domain socket tests. */ +#undef WANT_UNIX + +/* Define to one to include XTI tests. */ +#undef WANT_XTI + +/* Number of bits in a file offset, on hosts where this is settable. */ +#undef _FILE_OFFSET_BITS + +/* Define for large files, on AIX-style hosts. */ +#undef _LARGE_FILES + +/* Define to empty if `const' does not conform to ANSI C. */ +#undef const + +/* type to use in place of socklen_t if not defined */ +#undef netperf_socklen_t + +/* Define to `long int' if does not define. */ +#undef off_t + +/* Define to `int' if does not define. */ +#undef pid_t + +/* Define to `unsigned int' if does not define. */ +#undef size_t + +/* Define as `fork' if `vfork' does not work. */ +#undef vfork diff --git a/config.sub b/config.sub new file mode 100755 index 0000000..1c366df --- /dev/null +++ b/config.sub @@ -0,0 +1,1579 @@ +#! /bin/sh +# Configuration validation subroutine script. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. + +timestamp='2005-07-08' + +# This file is (in principle) common to ALL GNU software. +# The presence of a machine in this file suggests that SOME GNU software +# can handle that machine. It does not imply ALL GNU software can. +# +# This file is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA +# 02110-1301, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + + +# Please send patches to . Submit a context +# diff and a properly formatted ChangeLog entry. +# +# Configuration subroutine to validate and canonicalize a configuration type. +# Supply the specified configuration type as an argument. +# If it is invalid, we print an error message on stderr and exit with code 1. +# Otherwise, we print the canonical config type on stdout and succeed. + +# This file is supposed to be the same for all GNU packages +# and recognize all the CPU types, system types and aliases +# that are meaningful with *any* GNU software. +# Each package is responsible for reporting which valid configurations +# it does not support. The user should be able to distinguish +# a failure to support a valid configuration from a meaningless +# configuration. + +# The goal of this file is to map all the various variations of a given +# machine specification into a single specification in the form: +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# or in some cases, the newer four-part form: +# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM +# It is wrong to echo any other type of specification. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] CPU-MFR-OPSYS + $0 [OPTION] ALIAS + +Canonicalize a configuration name. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.sub ($timestamp) + +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 +Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" + exit 1 ;; + + *local*) + # First pass through any local machine types. + echo $1 + exit ;; + + * ) + break ;; + esac +done + +case $# in + 0) echo "$me: missing argument$help" >&2 + exit 1;; + 1) ;; + *) echo "$me: too many arguments$help" >&2 + exit 1;; +esac + +# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). +# Here we must recognize all the valid KERNEL-OS combinations. +maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` +case $maybe_os in + nto-qnx* | linux-gnu* | linux-dietlibc | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | \ + kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | storm-chaos* | os2-emx* | rtmk-nova*) + os=-$maybe_os + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` + ;; + *) + basic_machine=`echo $1 | sed 's/-[^-]*$//'` + if [ $basic_machine != $1 ] + then os=`echo $1 | sed 's/.*-/-/'` + else os=; fi + ;; +esac + +### Let's recognize common machines as not being operating systems so +### that things like config.sub decstation-3100 work. We also +### recognize some manufacturers as not being operating systems, so we +### can provide default operating systems below. +case $os in + -sun*os*) + # Prevent following clause from handling this invalid input. + ;; + -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ + -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ + -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ + -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ + -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ + -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ + -apple | -axis | -knuth | -cray) + os= + basic_machine=$1 + ;; + -sim | -cisco | -oki | -wec | -winbond) + os= + basic_machine=$1 + ;; + -scout) + ;; + -wrs) + os=-vxworks + basic_machine=$1 + ;; + -chorusos*) + os=-chorusos + basic_machine=$1 + ;; + -chorusrdb) + os=-chorusrdb + basic_machine=$1 + ;; + -hiux*) + os=-hiuxwe2 + ;; + -sco5) + os=-sco3.2v5 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco4) + os=-sco3.2v4 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2.[4-9]*) + os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2v[4-9]*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco*) + os=-sco3.2v2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -udk*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -isc) + os=-isc2.2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -clix*) + basic_machine=clipper-intergraph + ;; + -isc*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -lynx*) + os=-lynxos + ;; + -ptx*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` + ;; + -windowsnt*) + os=`echo $os | sed -e 's/windowsnt/winnt/'` + ;; + -psos*) + os=-psos + ;; + -mint | -mint[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; +esac + +# Decode aliases for certain CPU-COMPANY combinations. +case $basic_machine in + # Recognize the basic CPU types without company name. + # Some are omitted here because they have special meanings below. + 1750a | 580 \ + | a29k \ + | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ + | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ + | am33_2.0 \ + | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \ + | bfin \ + | c4x | clipper \ + | d10v | d30v | dlx | dsp16xx \ + | fr30 | frv \ + | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ + | i370 | i860 | i960 | ia64 \ + | ip2k | iq2000 \ + | m32r | m32rle | m68000 | m68k | m88k | maxq | mcore \ + | mips | mipsbe | mipseb | mipsel | mipsle \ + | mips16 \ + | mips64 | mips64el \ + | mips64vr | mips64vrel \ + | mips64orion | mips64orionel \ + | mips64vr4100 | mips64vr4100el \ + | mips64vr4300 | mips64vr4300el \ + | mips64vr5000 | mips64vr5000el \ + | mips64vr5900 | mips64vr5900el \ + | mipsisa32 | mipsisa32el \ + | mipsisa32r2 | mipsisa32r2el \ + | mipsisa64 | mipsisa64el \ + | mipsisa64r2 | mipsisa64r2el \ + | mipsisa64sb1 | mipsisa64sb1el \ + | mipsisa64sr71k | mipsisa64sr71kel \ + | mipstx39 | mipstx39el \ + | mn10200 | mn10300 \ + | ms1 \ + | msp430 \ + | ns16k | ns32k \ + | or32 \ + | pdp10 | pdp11 | pj | pjl \ + | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ + | pyramid \ + | sh | sh[1234] | sh[24]a | sh[23]e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \ + | sh64 | sh64le \ + | sparc | sparc64 | sparc64b | sparc86x | sparclet | sparclite \ + | sparcv8 | sparcv9 | sparcv9b \ + | strongarm \ + | tahoe | thumb | tic4x | tic80 | tron \ + | v850 | v850e \ + | we32k \ + | x86 | xscale | xscalee[bl] | xstormy16 | xtensa \ + | z8k) + basic_machine=$basic_machine-unknown + ;; + m32c) + basic_machine=$basic_machine-unknown + ;; + m6811 | m68hc11 | m6812 | m68hc12) + # Motorola 68HC11/12. + basic_machine=$basic_machine-unknown + os=-none + ;; + m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) + ;; + + # We use `pc' rather than `unknown' + # because (1) that's what they normally are, and + # (2) the word "unknown" tends to confuse beginning users. + i*86 | x86_64) + basic_machine=$basic_machine-pc + ;; + # Object if more than one company name word. + *-*-*) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; + # Recognize the basic CPU types with company name. + 580-* \ + | a29k-* \ + | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ + | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ + | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ + | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ + | avr-* \ + | bfin-* | bs2000-* \ + | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \ + | clipper-* | craynv-* | cydra-* \ + | d10v-* | d30v-* | dlx-* \ + | elxsi-* \ + | f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \ + | h8300-* | h8500-* \ + | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ + | i*86-* | i860-* | i960-* | ia64-* \ + | ip2k-* | iq2000-* \ + | m32r-* | m32rle-* \ + | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ + | m88110-* | m88k-* | maxq-* | mcore-* \ + | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ + | mips16-* \ + | mips64-* | mips64el-* \ + | mips64vr-* | mips64vrel-* \ + | mips64orion-* | mips64orionel-* \ + | mips64vr4100-* | mips64vr4100el-* \ + | mips64vr4300-* | mips64vr4300el-* \ + | mips64vr5000-* | mips64vr5000el-* \ + | mips64vr5900-* | mips64vr5900el-* \ + | mipsisa32-* | mipsisa32el-* \ + | mipsisa32r2-* | mipsisa32r2el-* \ + | mipsisa64-* | mipsisa64el-* \ + | mipsisa64r2-* | mipsisa64r2el-* \ + | mipsisa64sb1-* | mipsisa64sb1el-* \ + | mipsisa64sr71k-* | mipsisa64sr71kel-* \ + | mipstx39-* | mipstx39el-* \ + | mmix-* \ + | ms1-* \ + | msp430-* \ + | none-* | np1-* | ns16k-* | ns32k-* \ + | orion-* \ + | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ + | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ + | pyramid-* \ + | romp-* | rs6000-* \ + | sh-* | sh[1234]-* | sh[24]a-* | sh[23]e-* | sh[34]eb-* | shbe-* \ + | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ + | sparc-* | sparc64-* | sparc64b-* | sparc86x-* | sparclet-* \ + | sparclite-* \ + | sparcv8-* | sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \ + | tahoe-* | thumb-* \ + | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ + | tron-* \ + | v850-* | v850e-* | vax-* \ + | we32k-* \ + | x86-* | x86_64-* | xps100-* | xscale-* | xscalee[bl]-* \ + | xstormy16-* | xtensa-* \ + | ymp-* \ + | z8k-*) + ;; + m32c-*) + ;; + # Recognize the various machine names and aliases which stand + # for a CPU type and a company and sometimes even an OS. + 386bsd) + basic_machine=i386-unknown + os=-bsd + ;; + 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) + basic_machine=m68000-att + ;; + 3b*) + basic_machine=we32k-att + ;; + a29khif) + basic_machine=a29k-amd + os=-udi + ;; + abacus) + basic_machine=abacus-unknown + ;; + adobe68k) + basic_machine=m68010-adobe + os=-scout + ;; + alliant | fx80) + basic_machine=fx80-alliant + ;; + altos | altos3068) + basic_machine=m68k-altos + ;; + am29k) + basic_machine=a29k-none + os=-bsd + ;; + amd64) + basic_machine=x86_64-pc + ;; + amd64-*) + basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + amdahl) + basic_machine=580-amdahl + os=-sysv + ;; + amiga | amiga-*) + basic_machine=m68k-unknown + ;; + amigaos | amigados) + basic_machine=m68k-unknown + os=-amigaos + ;; + amigaunix | amix) + basic_machine=m68k-unknown + os=-sysv4 + ;; + apollo68) + basic_machine=m68k-apollo + os=-sysv + ;; + apollo68bsd) + basic_machine=m68k-apollo + os=-bsd + ;; + aux) + basic_machine=m68k-apple + os=-aux + ;; + balance) + basic_machine=ns32k-sequent + os=-dynix + ;; + c90) + basic_machine=c90-cray + os=-unicos + ;; + convex-c1) + basic_machine=c1-convex + os=-bsd + ;; + convex-c2) + basic_machine=c2-convex + os=-bsd + ;; + convex-c32) + basic_machine=c32-convex + os=-bsd + ;; + convex-c34) + basic_machine=c34-convex + os=-bsd + ;; + convex-c38) + basic_machine=c38-convex + os=-bsd + ;; + cray | j90) + basic_machine=j90-cray + os=-unicos + ;; + craynv) + basic_machine=craynv-cray + os=-unicosmp + ;; + cr16c) + basic_machine=cr16c-unknown + os=-elf + ;; + crds | unos) + basic_machine=m68k-crds + ;; + crisv32 | crisv32-* | etraxfs*) + basic_machine=crisv32-axis + ;; + cris | cris-* | etrax*) + basic_machine=cris-axis + ;; + crx) + basic_machine=crx-unknown + os=-elf + ;; + da30 | da30-*) + basic_machine=m68k-da30 + ;; + decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) + basic_machine=mips-dec + ;; + decsystem10* | dec10*) + basic_machine=pdp10-dec + os=-tops10 + ;; + decsystem20* | dec20*) + basic_machine=pdp10-dec + os=-tops20 + ;; + delta | 3300 | motorola-3300 | motorola-delta \ + | 3300-motorola | delta-motorola) + basic_machine=m68k-motorola + ;; + delta88) + basic_machine=m88k-motorola + os=-sysv3 + ;; + djgpp) + basic_machine=i586-pc + os=-msdosdjgpp + ;; + dpx20 | dpx20-*) + basic_machine=rs6000-bull + os=-bosx + ;; + dpx2* | dpx2*-bull) + basic_machine=m68k-bull + os=-sysv3 + ;; + ebmon29k) + basic_machine=a29k-amd + os=-ebmon + ;; + elxsi) + basic_machine=elxsi-elxsi + os=-bsd + ;; + encore | umax | mmax) + basic_machine=ns32k-encore + ;; + es1800 | OSE68k | ose68k | ose | OSE) + basic_machine=m68k-ericsson + os=-ose + ;; + fx2800) + basic_machine=i860-alliant + ;; + genix) + basic_machine=ns32k-ns + ;; + gmicro) + basic_machine=tron-gmicro + os=-sysv + ;; + go32) + basic_machine=i386-pc + os=-go32 + ;; + h3050r* | hiux*) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + h8300hms) + basic_machine=h8300-hitachi + os=-hms + ;; + h8300xray) + basic_machine=h8300-hitachi + os=-xray + ;; + h8500hms) + basic_machine=h8500-hitachi + os=-hms + ;; + harris) + basic_machine=m88k-harris + os=-sysv3 + ;; + hp300-*) + basic_machine=m68k-hp + ;; + hp300bsd) + basic_machine=m68k-hp + os=-bsd + ;; + hp300hpux) + basic_machine=m68k-hp + os=-hpux + ;; + hp3k9[0-9][0-9] | hp9[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k2[0-9][0-9] | hp9k31[0-9]) + basic_machine=m68000-hp + ;; + hp9k3[2-9][0-9]) + basic_machine=m68k-hp + ;; + hp9k6[0-9][0-9] | hp6[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k7[0-79][0-9] | hp7[0-79][0-9]) + basic_machine=hppa1.1-hp + ;; + hp9k78[0-9] | hp78[0-9]) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][13679] | hp8[0-9][13679]) + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][0-9] | hp8[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hppa-next) + os=-nextstep3 + ;; + hppaosf) + basic_machine=hppa1.1-hp + os=-osf + ;; + hppro) + basic_machine=hppa1.1-hp + os=-proelf + ;; + i370-ibm* | ibm*) + basic_machine=i370-ibm + ;; +# I'm not sure what "Sysv32" means. Should this be sysv3.2? + i*86v32) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv32 + ;; + i*86v4*) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv4 + ;; + i*86v) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv + ;; + i*86sol2) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-solaris2 + ;; + i386mach) + basic_machine=i386-mach + os=-mach + ;; + i386-vsta | vsta) + basic_machine=i386-unknown + os=-vsta + ;; + iris | iris4d) + basic_machine=mips-sgi + case $os in + -irix*) + ;; + *) + os=-irix4 + ;; + esac + ;; + isi68 | isi) + basic_machine=m68k-isi + os=-sysv + ;; + m88k-omron*) + basic_machine=m88k-omron + ;; + magnum | m3230) + basic_machine=mips-mips + os=-sysv + ;; + merlin) + basic_machine=ns32k-utek + os=-sysv + ;; + mingw32) + basic_machine=i386-pc + os=-mingw32 + ;; + miniframe) + basic_machine=m68000-convergent + ;; + *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; + mips3*-*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` + ;; + mips3*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown + ;; + monitor) + basic_machine=m68k-rom68k + os=-coff + ;; + morphos) + basic_machine=powerpc-unknown + os=-morphos + ;; + msdos) + basic_machine=i386-pc + os=-msdos + ;; + mvs) + basic_machine=i370-ibm + os=-mvs + ;; + ncr3000) + basic_machine=i486-ncr + os=-sysv4 + ;; + netbsd386) + basic_machine=i386-unknown + os=-netbsd + ;; + netwinder) + basic_machine=armv4l-rebel + os=-linux + ;; + news | news700 | news800 | news900) + basic_machine=m68k-sony + os=-newsos + ;; + news1000) + basic_machine=m68030-sony + os=-newsos + ;; + news-3600 | risc-news) + basic_machine=mips-sony + os=-newsos + ;; + necv70) + basic_machine=v70-nec + os=-sysv + ;; + next | m*-next ) + basic_machine=m68k-next + case $os in + -nextstep* ) + ;; + -ns2*) + os=-nextstep2 + ;; + *) + os=-nextstep3 + ;; + esac + ;; + nh3000) + basic_machine=m68k-harris + os=-cxux + ;; + nh[45]000) + basic_machine=m88k-harris + os=-cxux + ;; + nindy960) + basic_machine=i960-intel + os=-nindy + ;; + mon960) + basic_machine=i960-intel + os=-mon960 + ;; + nonstopux) + basic_machine=mips-compaq + os=-nonstopux + ;; + np1) + basic_machine=np1-gould + ;; + nsr-tandem) + basic_machine=nsr-tandem + ;; + op50n-* | op60c-*) + basic_machine=hppa1.1-oki + os=-proelf + ;; + openrisc | openrisc-*) + basic_machine=or32-unknown + ;; + os400) + basic_machine=powerpc-ibm + os=-os400 + ;; + OSE68000 | ose68000) + basic_machine=m68000-ericsson + os=-ose + ;; + os68k) + basic_machine=m68k-none + os=-os68k + ;; + pa-hitachi) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + paragon) + basic_machine=i860-intel + os=-osf + ;; + pbd) + basic_machine=sparc-tti + ;; + pbb) + basic_machine=m68k-tti + ;; + pc532 | pc532-*) + basic_machine=ns32k-pc532 + ;; + pentium | p5 | k5 | k6 | nexgen | viac3) + basic_machine=i586-pc + ;; + pentiumpro | p6 | 6x86 | athlon | athlon_*) + basic_machine=i686-pc + ;; + pentiumii | pentium2 | pentiumiii | pentium3) + basic_machine=i686-pc + ;; + pentium4) + basic_machine=i786-pc + ;; + pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) + basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumpro-* | p6-* | 6x86-* | athlon-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium4-*) + basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pn) + basic_machine=pn-gould + ;; + power) basic_machine=power-ibm + ;; + ppc) basic_machine=powerpc-unknown + ;; + ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppcle | powerpclittle | ppc-le | powerpc-little) + basic_machine=powerpcle-unknown + ;; + ppcle-* | powerpclittle-*) + basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64) basic_machine=powerpc64-unknown + ;; + ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64le | powerpc64little | ppc64-le | powerpc64-little) + basic_machine=powerpc64le-unknown + ;; + ppc64le-* | powerpc64little-*) + basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ps2) + basic_machine=i386-ibm + ;; + pw32) + basic_machine=i586-unknown + os=-pw32 + ;; + rom68k) + basic_machine=m68k-rom68k + os=-coff + ;; + rm[46]00) + basic_machine=mips-siemens + ;; + rtpc | rtpc-*) + basic_machine=romp-ibm + ;; + s390 | s390-*) + basic_machine=s390-ibm + ;; + s390x | s390x-*) + basic_machine=s390x-ibm + ;; + sa29200) + basic_machine=a29k-amd + os=-udi + ;; + sb1) + basic_machine=mipsisa64sb1-unknown + ;; + sb1el) + basic_machine=mipsisa64sb1el-unknown + ;; + sei) + basic_machine=mips-sei + os=-seiux + ;; + sequent) + basic_machine=i386-sequent + ;; + sh) + basic_machine=sh-hitachi + os=-hms + ;; + sh64) + basic_machine=sh64-unknown + ;; + sparclite-wrs | simso-wrs) + basic_machine=sparclite-wrs + os=-vxworks + ;; + sps7) + basic_machine=m68k-bull + os=-sysv2 + ;; + spur) + basic_machine=spur-unknown + ;; + st2000) + basic_machine=m68k-tandem + ;; + stratus) + basic_machine=i860-stratus + os=-sysv4 + ;; + sun2) + basic_machine=m68000-sun + ;; + sun2os3) + basic_machine=m68000-sun + os=-sunos3 + ;; + sun2os4) + basic_machine=m68000-sun + os=-sunos4 + ;; + sun3os3) + basic_machine=m68k-sun + os=-sunos3 + ;; + sun3os4) + basic_machine=m68k-sun + os=-sunos4 + ;; + sun4os3) + basic_machine=sparc-sun + os=-sunos3 + ;; + sun4os4) + basic_machine=sparc-sun + os=-sunos4 + ;; + sun4sol2) + basic_machine=sparc-sun + os=-solaris2 + ;; + sun3 | sun3-*) + basic_machine=m68k-sun + ;; + sun4) + basic_machine=sparc-sun + ;; + sun386 | sun386i | roadrunner) + basic_machine=i386-sun + ;; + sv1) + basic_machine=sv1-cray + os=-unicos + ;; + symmetry) + basic_machine=i386-sequent + os=-dynix + ;; + t3e) + basic_machine=alphaev5-cray + os=-unicos + ;; + t90) + basic_machine=t90-cray + os=-unicos + ;; + tic54x | c54x*) + basic_machine=tic54x-unknown + os=-coff + ;; + tic55x | c55x*) + basic_machine=tic55x-unknown + os=-coff + ;; + tic6x | c6x*) + basic_machine=tic6x-unknown + os=-coff + ;; + tx39) + basic_machine=mipstx39-unknown + ;; + tx39el) + basic_machine=mipstx39el-unknown + ;; + toad1) + basic_machine=pdp10-xkl + os=-tops20 + ;; + tower | tower-32) + basic_machine=m68k-ncr + ;; + tpf) + basic_machine=s390x-ibm + os=-tpf + ;; + udi29k) + basic_machine=a29k-amd + os=-udi + ;; + ultra3) + basic_machine=a29k-nyu + os=-sym1 + ;; + v810 | necv810) + basic_machine=v810-nec + os=-none + ;; + vaxv) + basic_machine=vax-dec + os=-sysv + ;; + vms) + basic_machine=vax-dec + os=-vms + ;; + vpp*|vx|vx-*) + basic_machine=f301-fujitsu + ;; + vxworks960) + basic_machine=i960-wrs + os=-vxworks + ;; + vxworks68) + basic_machine=m68k-wrs + os=-vxworks + ;; + vxworks29k) + basic_machine=a29k-wrs + os=-vxworks + ;; + w65*) + basic_machine=w65-wdc + os=-none + ;; + w89k-*) + basic_machine=hppa1.1-winbond + os=-proelf + ;; + xbox) + basic_machine=i686-pc + os=-mingw32 + ;; + xps | xps100) + basic_machine=xps100-honeywell + ;; + ymp) + basic_machine=ymp-cray + os=-unicos + ;; + z8k-*-coff) + basic_machine=z8k-unknown + os=-sim + ;; + none) + basic_machine=none-none + os=-none + ;; + +# Here we handle the default manufacturer of certain CPU types. It is in +# some cases the only manufacturer, in others, it is the most popular. + w89k) + basic_machine=hppa1.1-winbond + ;; + op50n) + basic_machine=hppa1.1-oki + ;; + op60c) + basic_machine=hppa1.1-oki + ;; + romp) + basic_machine=romp-ibm + ;; + mmix) + basic_machine=mmix-knuth + ;; + rs6000) + basic_machine=rs6000-ibm + ;; + vax) + basic_machine=vax-dec + ;; + pdp10) + # there are many clones, so DEC is not a safe bet + basic_machine=pdp10-unknown + ;; + pdp11) + basic_machine=pdp11-dec + ;; + we32k) + basic_machine=we32k-att + ;; + sh[1234] | sh[24]a | sh[34]eb | sh[1234]le | sh[23]ele) + basic_machine=sh-unknown + ;; + sparc | sparcv8 | sparcv9 | sparcv9b) + basic_machine=sparc-sun + ;; + cydra) + basic_machine=cydra-cydrome + ;; + orion) + basic_machine=orion-highlevel + ;; + orion105) + basic_machine=clipper-highlevel + ;; + mac | mpw | mac-mpw) + basic_machine=m68k-apple + ;; + pmac | pmac-mpw) + basic_machine=powerpc-apple + ;; + *-unknown) + # Make sure to match an already-canonicalized machine name. + ;; + *) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; +esac + +# Here we canonicalize certain aliases for manufacturers. +case $basic_machine in + *-digital*) + basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` + ;; + *-commodore*) + basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` + ;; + *) + ;; +esac + +# Decode manufacturer-specific aliases for certain operating systems. + +if [ x"$os" != x"" ] +then +case $os in + # First match some system type aliases + # that might get confused with valid system types. + # -solaris* is a basic system type, with this one exception. + -solaris1 | -solaris1.*) + os=`echo $os | sed -e 's|solaris1|sunos4|'` + ;; + -solaris) + os=-solaris2 + ;; + -svr4*) + os=-sysv4 + ;; + -unixware*) + os=-sysv4.2uw + ;; + -gnu/linux*) + os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` + ;; + # First accept the basic system types. + # The portable systems comes first. + # Each alternative MUST END IN A *, to match a version number. + # -sysv* is not here because it comes later, after sysvr4. + -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ + | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\ + | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ + | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ + | -aos* \ + | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ + | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ + | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* | -openbsd* \ + | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ + | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ + | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ + | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ + | -chorusos* | -chorusrdb* \ + | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -mingw32* | -linux-gnu* | -linux-uclibc* | -uxpv* | -beos* | -mpeix* | -udk* \ + | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ + | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ + | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ + | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ + | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ + | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ + | -skyos* | -haiku*) + # Remember, each alternative MUST END IN *, to match a version number. + ;; + -qnx*) + case $basic_machine in + x86-* | i*86-*) + ;; + *) + os=-nto$os + ;; + esac + ;; + -nto-qnx*) + ;; + -nto*) + os=`echo $os | sed -e 's|nto|nto-qnx|'` + ;; + -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ + | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ + | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) + ;; + -mac*) + os=`echo $os | sed -e 's|mac|macos|'` + ;; + -linux-dietlibc) + os=-linux-dietlibc + ;; + -linux*) + os=`echo $os | sed -e 's|linux|linux-gnu|'` + ;; + -sunos5*) + os=`echo $os | sed -e 's|sunos5|solaris2|'` + ;; + -sunos6*) + os=`echo $os | sed -e 's|sunos6|solaris3|'` + ;; + -opened*) + os=-openedition + ;; + -os400*) + os=-os400 + ;; + -wince*) + os=-wince + ;; + -osfrose*) + os=-osfrose + ;; + -osf*) + os=-osf + ;; + -utek*) + os=-bsd + ;; + -dynix*) + os=-bsd + ;; + -acis*) + os=-aos + ;; + -atheos*) + os=-atheos + ;; + -syllable*) + os=-syllable + ;; + -386bsd) + os=-bsd + ;; + -ctix* | -uts*) + os=-sysv + ;; + -nova*) + os=-rtmk-nova + ;; + -ns2 ) + os=-nextstep2 + ;; + -nsk*) + os=-nsk + ;; + # Preserve the version number of sinix5. + -sinix5.*) + os=`echo $os | sed -e 's|sinix|sysv|'` + ;; + -sinix*) + os=-sysv4 + ;; + -tpf*) + os=-tpf + ;; + -triton*) + os=-sysv3 + ;; + -oss*) + os=-sysv3 + ;; + -svr4) + os=-sysv4 + ;; + -svr3) + os=-sysv3 + ;; + -sysvr4) + os=-sysv4 + ;; + # This must come after -sysvr4. + -sysv*) + ;; + -ose*) + os=-ose + ;; + -es1800*) + os=-ose + ;; + -xenix) + os=-xenix + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + os=-mint + ;; + -aros*) + os=-aros + ;; + -kaos*) + os=-kaos + ;; + -zvmoe) + os=-zvmoe + ;; + -none) + ;; + *) + # Get rid of the `-' at the beginning of $os. + os=`echo $os | sed 's/[^-]*-//'` + echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 + exit 1 + ;; +esac +else + +# Here we handle the default operating systems that come with various machines. +# The value should be what the vendor currently ships out the door with their +# machine or put another way, the most popular os provided with the machine. + +# Note that if you're going to try to match "-MANUFACTURER" here (say, +# "-sun"), then you have to tell the case statement up towards the top +# that MANUFACTURER isn't an operating system. Otherwise, code above +# will signal an error saying that MANUFACTURER isn't an operating +# system, and we'll never get to this point. + +case $basic_machine in + *-acorn) + os=-riscix1.2 + ;; + arm*-rebel) + os=-linux + ;; + arm*-semi) + os=-aout + ;; + c4x-* | tic4x-*) + os=-coff + ;; + # This must come before the *-dec entry. + pdp10-*) + os=-tops20 + ;; + pdp11-*) + os=-none + ;; + *-dec | vax-*) + os=-ultrix4.2 + ;; + m68*-apollo) + os=-domain + ;; + i386-sun) + os=-sunos4.0.2 + ;; + m68000-sun) + os=-sunos3 + # This also exists in the configure program, but was not the + # default. + # os=-sunos4 + ;; + m68*-cisco) + os=-aout + ;; + mips*-cisco) + os=-elf + ;; + mips*-*) + os=-elf + ;; + or32-*) + os=-coff + ;; + *-tti) # must be before sparc entry or we get the wrong os. + os=-sysv3 + ;; + sparc-* | *-sun) + os=-sunos4.1.1 + ;; + *-be) + os=-beos + ;; + *-haiku) + os=-haiku + ;; + *-ibm) + os=-aix + ;; + *-knuth) + os=-mmixware + ;; + *-wec) + os=-proelf + ;; + *-winbond) + os=-proelf + ;; + *-oki) + os=-proelf + ;; + *-hp) + os=-hpux + ;; + *-hitachi) + os=-hiux + ;; + i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) + os=-sysv + ;; + *-cbm) + os=-amigaos + ;; + *-dg) + os=-dgux + ;; + *-dolphin) + os=-sysv3 + ;; + m68k-ccur) + os=-rtu + ;; + m88k-omron*) + os=-luna + ;; + *-next ) + os=-nextstep + ;; + *-sequent) + os=-ptx + ;; + *-crds) + os=-unos + ;; + *-ns) + os=-genix + ;; + i370-*) + os=-mvs + ;; + *-next) + os=-nextstep3 + ;; + *-gould) + os=-sysv + ;; + *-highlevel) + os=-bsd + ;; + *-encore) + os=-bsd + ;; + *-sgi) + os=-irix + ;; + *-siemens) + os=-sysv4 + ;; + *-masscomp) + os=-rtu + ;; + f30[01]-fujitsu | f700-fujitsu) + os=-uxpv + ;; + *-rom68k) + os=-coff + ;; + *-*bug) + os=-coff + ;; + *-apple) + os=-macos + ;; + *-atari*) + os=-mint + ;; + *) + os=-none + ;; +esac +fi + +# Here we handle the case where we know the os, and the CPU type, but not the +# manufacturer. We pick the logical manufacturer. +vendor=unknown +case $basic_machine in + *-unknown) + case $os in + -riscix*) + vendor=acorn + ;; + -sunos*) + vendor=sun + ;; + -aix*) + vendor=ibm + ;; + -beos*) + vendor=be + ;; + -hpux*) + vendor=hp + ;; + -mpeix*) + vendor=hp + ;; + -hiux*) + vendor=hitachi + ;; + -unos*) + vendor=crds + ;; + -dgux*) + vendor=dg + ;; + -luna*) + vendor=omron + ;; + -genix*) + vendor=ns + ;; + -mvs* | -opened*) + vendor=ibm + ;; + -os400*) + vendor=ibm + ;; + -ptx*) + vendor=sequent + ;; + -tpf*) + vendor=ibm + ;; + -vxsim* | -vxworks* | -windiss*) + vendor=wrs + ;; + -aux*) + vendor=apple + ;; + -hms*) + vendor=hitachi + ;; + -mpw* | -macos*) + vendor=apple + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + vendor=atari + ;; + -vos*) + vendor=stratus + ;; + esac + basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` + ;; +esac + +echo $basic_machine$os +exit + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/configure b/configure new file mode 100755 index 0000000..af0763b --- /dev/null +++ b/configure @@ -0,0 +1,12154 @@ +#! /bin/sh +# Guess values for system-dependent variables and create Makefiles. +# Generated by GNU Autoconf 2.61 for netperf 2.4.5. +# +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, +# 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. +## --------------------- ## +## M4sh Initialization. ## +## --------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in + *posix*) set -o posix ;; +esac + +fi + + + + +# PATH needs CR +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + echo "#! /bin/sh" >conf$$.sh + echo "exit 0" >>conf$$.sh + chmod +x conf$$.sh + if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then + PATH_SEPARATOR=';' + else + PATH_SEPARATOR=: + fi + rm -f conf$$.sh +fi + +# Support unset when possible. +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + as_unset=unset +else + as_unset=false +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +as_nl=' +' +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +case $0 in + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break +done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + { (exit 1); exit 1; } +fi + +# Work around bugs in pre-3.0 UWIN ksh. +for as_var in ENV MAIL MAILPATH +do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +for as_var in \ + LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ + LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ + LC_TELEPHONE LC_TIME +do + if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then + eval $as_var=C; export $as_var + else + ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var + fi +done + +# Required to use basename. +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + + +# Name of the executable. +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# CDPATH. +$as_unset CDPATH + + +if test "x$CONFIG_SHELL" = x; then + if (eval ":") 2>/dev/null; then + as_have_required=yes +else + as_have_required=no +fi + + if test $as_have_required = yes && (eval ": +(as_func_return () { + (exit \$1) +} +as_func_success () { + as_func_return 0 +} +as_func_failure () { + as_func_return 1 +} +as_func_ret_success () { + return 0 +} +as_func_ret_failure () { + return 1 +} + +exitcode=0 +if as_func_success; then + : +else + exitcode=1 + echo as_func_success failed. +fi + +if as_func_failure; then + exitcode=1 + echo as_func_failure succeeded. +fi + +if as_func_ret_success; then + : +else + exitcode=1 + echo as_func_ret_success failed. +fi + +if as_func_ret_failure; then + exitcode=1 + echo as_func_ret_failure succeeded. +fi + +if ( set x; as_func_ret_success y && test x = \"\$1\" ); then + : +else + exitcode=1 + echo positional parameters were not saved. +fi + +test \$exitcode = 0) || { (exit 1); exit 1; } + +( + as_lineno_1=\$LINENO + as_lineno_2=\$LINENO + test \"x\$as_lineno_1\" != \"x\$as_lineno_2\" && + test \"x\`expr \$as_lineno_1 + 1\`\" = \"x\$as_lineno_2\") || { (exit 1); exit 1; } +") 2> /dev/null; then + : +else + as_candidate_shells= + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + case $as_dir in + /*) + for as_base in sh bash ksh sh5; do + as_candidate_shells="$as_candidate_shells $as_dir/$as_base" + done;; + esac +done +IFS=$as_save_IFS + + + for as_shell in $as_candidate_shells $SHELL; do + # Try only shells that exist, to save several forks. + if { test -f "$as_shell" || test -f "$as_shell.exe"; } && + { ("$as_shell") 2> /dev/null <<\_ASEOF +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in + *posix*) set -o posix ;; +esac + +fi + + +: +_ASEOF +}; then + CONFIG_SHELL=$as_shell + as_have_required=yes + if { "$as_shell" 2> /dev/null <<\_ASEOF +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in + *posix*) set -o posix ;; +esac + +fi + + +: +(as_func_return () { + (exit $1) +} +as_func_success () { + as_func_return 0 +} +as_func_failure () { + as_func_return 1 +} +as_func_ret_success () { + return 0 +} +as_func_ret_failure () { + return 1 +} + +exitcode=0 +if as_func_success; then + : +else + exitcode=1 + echo as_func_success failed. +fi + +if as_func_failure; then + exitcode=1 + echo as_func_failure succeeded. +fi + +if as_func_ret_success; then + : +else + exitcode=1 + echo as_func_ret_success failed. +fi + +if as_func_ret_failure; then + exitcode=1 + echo as_func_ret_failure succeeded. +fi + +if ( set x; as_func_ret_success y && test x = "$1" ); then + : +else + exitcode=1 + echo positional parameters were not saved. +fi + +test $exitcode = 0) || { (exit 1); exit 1; } + +( + as_lineno_1=$LINENO + as_lineno_2=$LINENO + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2") || { (exit 1); exit 1; } + +_ASEOF +}; then + break +fi + +fi + + done + + if test "x$CONFIG_SHELL" != x; then + for as_var in BASH_ENV ENV + do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var + done + export CONFIG_SHELL + exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"} +fi + + + if test $as_have_required = no; then + echo This script requires a shell more modern than all the + echo shells that I found on your system. Please install a + echo modern shell, or manually run the script under such a + echo shell if you do have one. + { (exit 1); exit 1; } +fi + + +fi + +fi + + + +(eval "as_func_return () { + (exit \$1) +} +as_func_success () { + as_func_return 0 +} +as_func_failure () { + as_func_return 1 +} +as_func_ret_success () { + return 0 +} +as_func_ret_failure () { + return 1 +} + +exitcode=0 +if as_func_success; then + : +else + exitcode=1 + echo as_func_success failed. +fi + +if as_func_failure; then + exitcode=1 + echo as_func_failure succeeded. +fi + +if as_func_ret_success; then + : +else + exitcode=1 + echo as_func_ret_success failed. +fi + +if as_func_ret_failure; then + exitcode=1 + echo as_func_ret_failure succeeded. +fi + +if ( set x; as_func_ret_success y && test x = \"\$1\" ); then + : +else + exitcode=1 + echo positional parameters were not saved. +fi + +test \$exitcode = 0") || { + echo No shell found that supports shell functions. + echo Please tell autoconf@gnu.org about your system, + echo including any error possibly output before this + echo message +} + + + + as_lineno_1=$LINENO + as_lineno_2=$LINENO + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || { + + # Create $as_me.lineno as a copy of $as_myself, but with $LINENO + # uniformly replaced by the line number. The first 'sed' inserts a + # line-number line after each line using $LINENO; the second 'sed' + # does the real work. The second script uses 'N' to pair each + # line-number line with the line containing $LINENO, and appends + # trailing '-' during substitution so that $LINENO is not a special + # case at line end. + # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the + # scripts with optimization help from Paolo Bonzini. Blame Lee + # E. McMahon (1931-1989) for sed's syntax. :-) + sed -n ' + p + /[$]LINENO/= + ' <$as_myself | + sed ' + s/[$]LINENO.*/&-/ + t lineno + b + :lineno + N + :loop + s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ + t loop + s/-\n.*// + ' >$as_me.lineno && + chmod +x "$as_me.lineno" || + { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 + { (exit 1); exit 1; }; } + + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensitive to this). + . "./$as_me.lineno" + # Exit status is that of the last command. + exit +} + + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in +-n*) + case `echo 'x\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + *) ECHO_C='\c';; + esac;; +*) + ECHO_N='-n';; +esac + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir +fi +echo >conf$$.file +if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -p'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -p' +elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + +if mkdir -p . 2>/dev/null; then + as_mkdir_p=: +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +if test -x / >/dev/null 2>&1; then + as_test_x='test -x' +else + if ls -dL / >/dev/null 2>&1; then + as_ls_L_option=L + else + as_ls_L_option= + fi + as_test_x=' + eval sh -c '\'' + if test -d "$1"; then + test -d "$1/."; + else + case $1 in + -*)set "./$1";; + esac; + case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in + ???[sx]*):;;*)false;;esac;fi + '\'' sh + ' +fi +as_executable_p=$as_test_x + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + + +exec 7<&0 &1 + +# Name of the host. +# hostname on some systems (SVR3.2, Linux) returns a bogus exit status, +# so uname gets run too. +ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` + +# +# Initializations. +# +ac_default_prefix=/usr/local +ac_clean_files= +ac_config_libobj_dir=. +LIBOBJS= +cross_compiling=no +subdirs= +MFLAGS= +MAKEFLAGS= +SHELL=${CONFIG_SHELL-/bin/sh} + +# Identity of this package. +PACKAGE_NAME='netperf' +PACKAGE_TARNAME='netperf' +PACKAGE_VERSION='2.4.5' +PACKAGE_STRING='netperf 2.4.5' +PACKAGE_BUGREPORT='' + +ac_unique_file="src/hist.h" +ac_config_libobj_dir=src/missing +# Factoring default headers for most tests. +ac_includes_default="\ +#include +#ifdef HAVE_SYS_TYPES_H +# include +#endif +#ifdef HAVE_SYS_STAT_H +# include +#endif +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif +#ifdef HAVE_STRING_H +# if !defined STDC_HEADERS && defined HAVE_MEMORY_H +# include +# endif +# include +#endif +#ifdef HAVE_STRINGS_H +# include +#endif +#ifdef HAVE_INTTYPES_H +# include +#endif +#ifdef HAVE_STDINT_H +# include +#endif +#ifdef HAVE_UNISTD_H +# include +#endif" + +ac_subst_vars='SHELL +PATH_SEPARATOR +PACKAGE_NAME +PACKAGE_TARNAME +PACKAGE_VERSION +PACKAGE_STRING +PACKAGE_BUGREPORT +exec_prefix +prefix +program_transform_name +bindir +sbindir +libexecdir +datarootdir +datadir +sysconfdir +sharedstatedir +localstatedir +includedir +oldincludedir +docdir +infodir +htmldir +dvidir +pdfdir +psdir +libdir +localedir +mandir +DEFS +ECHO_C +ECHO_N +ECHO_T +LIBS +build_alias +host_alias +target_alias +build +build_cpu +build_vendor +build_os +host +host_cpu +host_vendor +host_os +target +target_cpu +target_vendor +target_os +INSTALL_PROGRAM +INSTALL_SCRIPT +INSTALL_DATA +CYGPATH_W +PACKAGE +VERSION +ACLOCAL +AUTOCONF +AUTOMAKE +AUTOHEADER +MAKEINFO +AMTAR +install_sh +STRIP +INSTALL_STRIP_PROGRAM +AWK +SET_MAKE +am__leading_dot +CC +CFLAGS +LDFLAGS +CPPFLAGS +ac_ct_CC +EXEEXT +OBJEXT +DEPDIR +am__include +am__quote +AMDEP_TRUE +AMDEP_FALSE +AMDEPBACKSLASH +CCDEPMODE +am__fastdepCC_TRUE +am__fastdepCC_FALSE +RANLIB +CPP +GREP +EGREP +LIBOBJS +NEED_LIBCOMPAT_TRUE +NEED_LIBCOMPAT_FALSE +NETCPU_SOURCE +NETRTLKUP_SOURCE +NETSLOTLKUP_SOURCE +NETSECLKUP_SOURCE +NETDRVLKUP_SOURCE +NETSYSLKUP_SOURCE +LTLIBOBJS' +ac_subst_files='' + ac_precious_vars='build_alias +host_alias +target_alias +CC +CFLAGS +LDFLAGS +LIBS +CPPFLAGS +CPP' + + +# Initialize some variables set by options. +ac_init_help= +ac_init_version=false +# The variables have the same names as the options, with +# dashes changed to underlines. +cache_file=/dev/null +exec_prefix=NONE +no_create= +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +verbose= +x_includes=NONE +x_libraries=NONE + +# Installation directory options. +# These are left unexpanded so users can "make install exec_prefix=/foo" +# and all the variables that are supposed to be based on exec_prefix +# by default will actually change. +# Use braces instead of parens because sh, perl, etc. also accept them. +# (The list follows the same order as the GNU Coding Standards.) +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datarootdir='${prefix}/share' +datadir='${datarootdir}' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +includedir='${prefix}/include' +oldincludedir='/usr/include' +docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' +infodir='${datarootdir}/info' +htmldir='${docdir}' +dvidir='${docdir}' +pdfdir='${docdir}' +psdir='${docdir}' +libdir='${exec_prefix}/lib' +localedir='${datarootdir}/locale' +mandir='${datarootdir}/man' + +ac_prev= +ac_dashdash= +for ac_option +do + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval $ac_prev=\$ac_option + ac_prev= + continue + fi + + case $ac_option in + *=*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; + *) ac_optarg=yes ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case $ac_dashdash$ac_option in + --) + ac_dashdash=yes ;; + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir=$ac_optarg ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build_alias ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build_alias=$ac_optarg ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file=$ac_optarg ;; + + --config-cache | -C) + cache_file=config.cache ;; + + -datadir | --datadir | --datadi | --datad) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=*) + datadir=$ac_optarg ;; + + -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ + | --dataroo | --dataro | --datar) + ac_prev=datarootdir ;; + -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ + | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) + datarootdir=$ac_optarg ;; + + -disable-* | --disable-*) + ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_feature" : ".*[^-._$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid feature name: $ac_feature" >&2 + { (exit 1); exit 1; }; } + ac_feature=`echo $ac_feature | sed 's/[-.]/_/g'` + eval enable_$ac_feature=no ;; + + -docdir | --docdir | --docdi | --doc | --do) + ac_prev=docdir ;; + -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) + docdir=$ac_optarg ;; + + -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) + ac_prev=dvidir ;; + -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) + dvidir=$ac_optarg ;; + + -enable-* | --enable-*) + ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_feature" : ".*[^-._$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid feature name: $ac_feature" >&2 + { (exit 1); exit 1; }; } + ac_feature=`echo $ac_feature | sed 's/[-.]/_/g'` + eval enable_$ac_feature=\$ac_optarg ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix=$ac_optarg ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he | -h) + ac_init_help=long ;; + -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) + ac_init_help=recursive ;; + -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) + ac_init_help=short ;; + + -host | --host | --hos | --ho) + ac_prev=host_alias ;; + -host=* | --host=* | --hos=* | --ho=*) + host_alias=$ac_optarg ;; + + -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) + ac_prev=htmldir ;; + -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ + | --ht=*) + htmldir=$ac_optarg ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir=$ac_optarg ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir=$ac_optarg ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir=$ac_optarg ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir=$ac_optarg ;; + + -localedir | --localedir | --localedi | --localed | --locale) + ac_prev=localedir ;; + -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) + localedir=$ac_optarg ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst | --locals) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) + localstatedir=$ac_optarg ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir=$ac_optarg ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c | -n) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir=$ac_optarg ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix=$ac_optarg ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix=$ac_optarg ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix=$ac_optarg ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name=$ac_optarg ;; + + -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) + ac_prev=pdfdir ;; + -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) + pdfdir=$ac_optarg ;; + + -psdir | --psdir | --psdi | --psd | --ps) + ac_prev=psdir ;; + -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) + psdir=$ac_optarg ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir=$ac_optarg ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir=$ac_optarg ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site=$ac_optarg ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir=$ac_optarg ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir=$ac_optarg ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target_alias ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target_alias=$ac_optarg ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers | -V) + ac_init_version=: ;; + + -with-* | --with-*) + ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_package" : ".*[^-._$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid package name: $ac_package" >&2 + { (exit 1); exit 1; }; } + ac_package=`echo $ac_package | sed 's/[-.]/_/g'` + eval with_$ac_package=\$ac_optarg ;; + + -without-* | --without-*) + ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_package" : ".*[^-._$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid package name: $ac_package" >&2 + { (exit 1); exit 1; }; } + ac_package=`echo $ac_package | sed 's/[-.]/_/g'` + eval with_$ac_package=no ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes=$ac_optarg ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries=$ac_optarg ;; + + -*) { echo "$as_me: error: unrecognized option: $ac_option +Try \`$0 --help' for more information." >&2 + { (exit 1); exit 1; }; } + ;; + + *=*) + ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` + # Reject names that are not valid shell variable names. + expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid variable name: $ac_envvar" >&2 + { (exit 1); exit 1; }; } + eval $ac_envvar=\$ac_optarg + export $ac_envvar ;; + + *) + # FIXME: should be removed in autoconf 3.0. + echo "$as_me: WARNING: you should use --build, --host, --target" >&2 + expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && + echo "$as_me: WARNING: invalid host type: $ac_option" >&2 + : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option} + ;; + + esac +done + +if test -n "$ac_prev"; then + ac_option=--`echo $ac_prev | sed 's/_/-/g'` + { echo "$as_me: error: missing argument to $ac_option" >&2 + { (exit 1); exit 1; }; } +fi + +# Be sure to have absolute directory names. +for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ + datadir sysconfdir sharedstatedir localstatedir includedir \ + oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ + libdir localedir mandir +do + eval ac_val=\$$ac_var + case $ac_val in + [\\/$]* | ?:[\\/]* ) continue;; + NONE | '' ) case $ac_var in *prefix ) continue;; esac;; + esac + { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 + { (exit 1); exit 1; }; } +done + +# There might be people who depend on the old broken behavior: `$host' +# used to hold the argument of --host etc. +# FIXME: To remove some day. +build=$build_alias +host=$host_alias +target=$target_alias + +# FIXME: To remove some day. +if test "x$host_alias" != x; then + if test "x$build_alias" = x; then + cross_compiling=maybe + echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. + If a cross compiler is detected then cross compile mode will be used." >&2 + elif test "x$build_alias" != "x$host_alias"; then + cross_compiling=yes + fi +fi + +ac_tool_prefix= +test -n "$host_alias" && ac_tool_prefix=$host_alias- + +test "$silent" = yes && exec 6>/dev/null + + +ac_pwd=`pwd` && test -n "$ac_pwd" && +ac_ls_di=`ls -di .` && +ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || + { echo "$as_me: error: Working directory cannot be determined" >&2 + { (exit 1); exit 1; }; } +test "X$ac_ls_di" = "X$ac_pwd_ls_di" || + { echo "$as_me: error: pwd does not report name of working directory" >&2 + { (exit 1); exit 1; }; } + + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then the parent directory. + ac_confdir=`$as_dirname -- "$0" || +$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$0" : 'X\(//\)[^/]' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +echo X"$0" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + srcdir=$ac_confdir + if test ! -r "$srcdir/$ac_unique_file"; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r "$srcdir/$ac_unique_file"; then + test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." + { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2 + { (exit 1); exit 1; }; } +fi +ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" +ac_abs_confdir=`( + cd "$srcdir" && test -r "./$ac_unique_file" || { echo "$as_me: error: $ac_msg" >&2 + { (exit 1); exit 1; }; } + pwd)` +# When building in place, set srcdir=. +if test "$ac_abs_confdir" = "$ac_pwd"; then + srcdir=. +fi +# Remove unnecessary trailing slashes from srcdir. +# Double slashes in file names in object file debugging info +# mess up M-x gdb in Emacs. +case $srcdir in +*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; +esac +for ac_var in $ac_precious_vars; do + eval ac_env_${ac_var}_set=\${${ac_var}+set} + eval ac_env_${ac_var}_value=\$${ac_var} + eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} + eval ac_cv_env_${ac_var}_value=\$${ac_var} +done + +# +# Report the --help message. +# +if test "$ac_init_help" = "long"; then + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat <<_ACEOF +\`configure' configures netperf 2.4.5 to adapt to many kinds of systems. + +Usage: $0 [OPTION]... [VAR=VALUE]... + +To assign environment variables (e.g., CC, CFLAGS...), specify them as +VAR=VALUE. See below for descriptions of some of the useful variables. + +Defaults for the options are specified in brackets. + +Configuration: + -h, --help display this help and exit + --help=short display options specific to this package + --help=recursive display the short help of all the included packages + -V, --version display version information and exit + -q, --quiet, --silent do not print \`checking...' messages + --cache-file=FILE cache test results in FILE [disabled] + -C, --config-cache alias for \`--cache-file=config.cache' + -n, --no-create do not create output files + --srcdir=DIR find the sources in DIR [configure dir or \`..'] + +Installation directories: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [PREFIX] + +By default, \`make install' will install all the files in +\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify +an installation prefix other than \`$ac_default_prefix' using \`--prefix', +for instance \`--prefix=\$HOME'. + +For better control, use the options below. + +Fine tuning of the installation directories: + --bindir=DIR user executables [EPREFIX/bin] + --sbindir=DIR system admin executables [EPREFIX/sbin] + --libexecdir=DIR program executables [EPREFIX/libexec] + --sysconfdir=DIR read-only single-machine data [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] + --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --libdir=DIR object code libraries [EPREFIX/lib] + --includedir=DIR C header files [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc [/usr/include] + --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] + --datadir=DIR read-only architecture-independent data [DATAROOTDIR] + --infodir=DIR info documentation [DATAROOTDIR/info] + --localedir=DIR locale-dependent data [DATAROOTDIR/locale] + --mandir=DIR man documentation [DATAROOTDIR/man] + --docdir=DIR documentation root [DATAROOTDIR/doc/netperf] + --htmldir=DIR html documentation [DOCDIR] + --dvidir=DIR dvi documentation [DOCDIR] + --pdfdir=DIR pdf documentation [DOCDIR] + --psdir=DIR ps documentation [DOCDIR] +_ACEOF + + cat <<\_ACEOF + +Program names: + --program-prefix=PREFIX prepend PREFIX to installed program names + --program-suffix=SUFFIX append SUFFIX to installed program names + --program-transform-name=PROGRAM run sed PROGRAM on installed program names + +System types: + --build=BUILD configure for building on BUILD [guessed] + --host=HOST cross-compile to build programs to run on HOST [BUILD] + --target=TARGET configure for building compilers for TARGET [HOST] +_ACEOF +fi + +if test -n "$ac_init_help"; then + case $ac_init_help in + short | recursive ) echo "Configuration of netperf 2.4.5:";; + esac + cat <<\_ACEOF + +Optional Features: + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --disable-dependency-tracking Speeds up one-time builds + --enable-dependency-tracking Do not reject slow dependency extractors + --disable-largefile omit support for large files + --enable-histogram include individual op timing, may affect result + --enable-dirty write to buffers each time, may affect result + --enable-demo emit interim results during the run. May affect + results. + --enable-unixdomain include Unix Domain socket tests + --enable-dlpi include DLPI (link-layer) tests + --enable-dccp include DCCP tests + --enable-omni include OMNI tests + --enable-xti include XTI socket tests + --enable-sdp include SDP socket tests + --enable-exs include ICSC async sockets tests + --enable-sctp include tests to measure SCTP performance + --enable-intervals include ability to pace operations, may affect + result + --enable-spin paced operations (--enable-intervals) should sit and + spin - WILL affect result + --enable-burst include intial request burst ability in _RR tests, + may affect result + --enable-cpuutil include code to measure CPU utilization using + specified mechanism + --enable-rtlookup include code to find the probable egress interface + using specified mechanism + --enable-slotlookup include code to find the probable egress interface + using specified mechanism + --enable-seclookup include code to find the system security mechanism + and its state + --enable-drvlookup include code to find the driver information for the + probable egress interface + --enable-syslookup include code to find some rudimentary system + information + +Some influential environment variables: + CC C compiler command + CFLAGS C compiler flags + LDFLAGS linker flags, e.g. -L if you have libraries in a + nonstandard directory + LIBS libraries to pass to the linker, e.g. -l + CPPFLAGS C/C++/Objective C preprocessor flags, e.g. -I if + you have headers in a nonstandard directory + CPP C preprocessor + +Use these variables to override the choices made by `configure' or to help +it to find libraries and programs with nonstandard names/locations. + +_ACEOF +ac_status=$? +fi + +if test "$ac_init_help" = "recursive"; then + # If there are subdirs, report their specific --help. + for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue + test -d "$ac_dir" || continue + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,/..,g;s,/,,'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + cd "$ac_dir" || { ac_status=$?; continue; } + # Check for guested configure. + if test -f "$ac_srcdir/configure.gnu"; then + echo && + $SHELL "$ac_srcdir/configure.gnu" --help=recursive + elif test -f "$ac_srcdir/configure"; then + echo && + $SHELL "$ac_srcdir/configure" --help=recursive + else + echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 + fi || ac_status=$? + cd "$ac_pwd" || { ac_status=$?; break; } + done +fi + +test -n "$ac_init_help" && exit $ac_status +if $ac_init_version; then + cat <<\_ACEOF +netperf configure 2.4.5 +generated by GNU Autoconf 2.61 + +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, +2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. +This configure script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it. +_ACEOF + exit +fi +cat >config.log <<_ACEOF +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by netperf $as_me 2.4.5, which was +generated by GNU Autoconf 2.61. Invocation command line was + + $ $0 $@ + +_ACEOF +exec 5>>config.log +{ +cat <<_ASUNAME +## --------- ## +## Platform. ## +## --------- ## + +hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` + +/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` +/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` +/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` +/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` + +_ASUNAME + +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + echo "PATH: $as_dir" +done +IFS=$as_save_IFS + +} >&5 + +cat >&5 <<_ACEOF + + +## ----------- ## +## Core tests. ## +## ----------- ## + +_ACEOF + + +# Keep a trace of the command line. +# Strip out --no-create and --no-recursion so they do not pile up. +# Strip out --silent because we don't want to record it for future runs. +# Also quote any args containing shell meta-characters. +# Make two passes to allow for proper duplicate-argument suppression. +ac_configure_args= +ac_configure_args0= +ac_configure_args1= +ac_must_keep_next=false +for ac_pass in 1 2 +do + for ac_arg + do + case $ac_arg in + -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + continue ;; + *\'*) + ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + case $ac_pass in + 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;; + 2) + ac_configure_args1="$ac_configure_args1 '$ac_arg'" + if test $ac_must_keep_next = true; then + ac_must_keep_next=false # Got value, back to normal. + else + case $ac_arg in + *=* | --config-cache | -C | -disable-* | --disable-* \ + | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ + | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ + | -with-* | --with-* | -without-* | --without-* | --x) + case "$ac_configure_args0 " in + "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; + esac + ;; + -* ) ac_must_keep_next=true ;; + esac + fi + ac_configure_args="$ac_configure_args '$ac_arg'" + ;; + esac + done +done +$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; } +$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; } + +# When interrupted or exit'd, cleanup temporary files, and complete +# config.log. We remove comments because anyway the quotes in there +# would cause problems or look ugly. +# WARNING: Use '\'' to represent an apostrophe within the trap. +# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. +trap 'exit_status=$? + # Save into config.log some information that might help in debugging. + { + echo + + cat <<\_ASBOX +## ---------------- ## +## Cache variables. ## +## ---------------- ## +_ASBOX + echo + # The following way of writing the cache mishandles newlines in values, +( + for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { echo "$as_me:$LINENO: WARNING: Cache variable $ac_var contains a newline." >&5 +echo "$as_me: WARNING: Cache variable $ac_var contains a newline." >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + *) $as_unset $ac_var ;; + esac ;; + esac + done + (set) 2>&1 | + case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + sed -n \ + "s/'\''/'\''\\\\'\'''\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" + ;; #( + *) + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) + echo + + cat <<\_ASBOX +## ----------------- ## +## Output variables. ## +## ----------------- ## +_ASBOX + echo + for ac_var in $ac_subst_vars + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + echo "$ac_var='\''$ac_val'\''" + done | sort + echo + + if test -n "$ac_subst_files"; then + cat <<\_ASBOX +## ------------------- ## +## File substitutions. ## +## ------------------- ## +_ASBOX + echo + for ac_var in $ac_subst_files + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + echo "$ac_var='\''$ac_val'\''" + done | sort + echo + fi + + if test -s confdefs.h; then + cat <<\_ASBOX +## ----------- ## +## confdefs.h. ## +## ----------- ## +_ASBOX + echo + cat confdefs.h + echo + fi + test "$ac_signal" != 0 && + echo "$as_me: caught signal $ac_signal" + echo "$as_me: exit $exit_status" + } >&5 + rm -f core *.core core.conftest.* && + rm -f -r conftest* confdefs* conf$$* $ac_clean_files && + exit $exit_status +' 0 +for ac_signal in 1 2 13 15; do + trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal +done +ac_signal=0 + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -f -r conftest* confdefs.h + +# Predefined preprocessor variables. + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_NAME "$PACKAGE_NAME" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_TARNAME "$PACKAGE_TARNAME" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_VERSION "$PACKAGE_VERSION" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_STRING "$PACKAGE_STRING" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" +_ACEOF + + +# Let the site file select an alternate cache file if it wants to. +# Prefer explicitly selected file to automatically selected ones. +if test -n "$CONFIG_SITE"; then + set x "$CONFIG_SITE" +elif test "x$prefix" != xNONE; then + set x "$prefix/share/config.site" "$prefix/etc/config.site" +else + set x "$ac_default_prefix/share/config.site" \ + "$ac_default_prefix/etc/config.site" +fi +shift +for ac_site_file +do + if test -r "$ac_site_file"; then + { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5 +echo "$as_me: loading site script $ac_site_file" >&6;} + sed 's/^/| /' "$ac_site_file" >&5 + . "$ac_site_file" + fi +done + +if test -r "$cache_file"; then + # Some versions of bash will fail to source /dev/null (special + # files actually), so we avoid doing that. + if test -f "$cache_file"; then + { echo "$as_me:$LINENO: loading cache $cache_file" >&5 +echo "$as_me: loading cache $cache_file" >&6;} + case $cache_file in + [\\/]* | ?:[\\/]* ) . "$cache_file";; + *) . "./$cache_file";; + esac + fi +else + { echo "$as_me:$LINENO: creating cache $cache_file" >&5 +echo "$as_me: creating cache $cache_file" >&6;} + >$cache_file +fi + +# Check that the precious variables saved in the cache have kept the same +# value. +ac_cache_corrupted=false +for ac_var in $ac_precious_vars; do + eval ac_old_set=\$ac_cv_env_${ac_var}_set + eval ac_new_set=\$ac_env_${ac_var}_set + eval ac_old_val=\$ac_cv_env_${ac_var}_value + eval ac_new_val=\$ac_env_${ac_var}_value + case $ac_old_set,$ac_new_set in + set,) + { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,set) + { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5 +echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,);; + *) + if test "x$ac_old_val" != "x$ac_new_val"; then + { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5 +echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + { echo "$as_me:$LINENO: former value: $ac_old_val" >&5 +echo "$as_me: former value: $ac_old_val" >&2;} + { echo "$as_me:$LINENO: current value: $ac_new_val" >&5 +echo "$as_me: current value: $ac_new_val" >&2;} + ac_cache_corrupted=: + fi;; + esac + # Pass precious variables to config.status. + if test "$ac_new_set" = set; then + case $ac_new_val in + *\'*) ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; + *) ac_arg=$ac_var=$ac_new_val ;; + esac + case " $ac_configure_args " in + *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. + *) ac_configure_args="$ac_configure_args '$ac_arg'" ;; + esac + fi +done +if $ac_cache_corrupted; then + { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5 +echo "$as_me: error: changes in the environment can compromise the build" >&2;} + { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5 +echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;} + { (exit 1); exit 1; }; } +fi + + + + + + + + + + + + + + + + + + + + + + + + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +# use the target version rather than host - one day we may want cross-compile +ac_aux_dir= +for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do + if test -f "$ac_dir/install-sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f "$ac_dir/install.sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + elif test -f "$ac_dir/shtool"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/shtool install -c" + break + fi +done +if test -z "$ac_aux_dir"; then + { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" >&5 +echo "$as_me: error: cannot find install-sh or install.sh in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" >&2;} + { (exit 1); exit 1; }; } +fi + +# These three variables are undocumented and unsupported, +# and are intended to be withdrawn in a future Autoconf release. +# They can cause serious problems if a builder's source tree is in a directory +# whose full name contains unusual characters. +ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. +ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. +ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. + + +# Make sure we can run config.sub. +$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || + { { echo "$as_me:$LINENO: error: cannot run $SHELL $ac_aux_dir/config.sub" >&5 +echo "$as_me: error: cannot run $SHELL $ac_aux_dir/config.sub" >&2;} + { (exit 1); exit 1; }; } + +{ echo "$as_me:$LINENO: checking build system type" >&5 +echo $ECHO_N "checking build system type... $ECHO_C" >&6; } +if test "${ac_cv_build+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_build_alias=$build_alias +test "x$ac_build_alias" = x && + ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` +test "x$ac_build_alias" = x && + { { echo "$as_me:$LINENO: error: cannot guess build type; you must specify one" >&5 +echo "$as_me: error: cannot guess build type; you must specify one" >&2;} + { (exit 1); exit 1; }; } +ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || + { { echo "$as_me:$LINENO: error: $SHELL $ac_aux_dir/config.sub $ac_build_alias failed" >&5 +echo "$as_me: error: $SHELL $ac_aux_dir/config.sub $ac_build_alias failed" >&2;} + { (exit 1); exit 1; }; } + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_build" >&5 +echo "${ECHO_T}$ac_cv_build" >&6; } +case $ac_cv_build in +*-*-*) ;; +*) { { echo "$as_me:$LINENO: error: invalid value of canonical build" >&5 +echo "$as_me: error: invalid value of canonical build" >&2;} + { (exit 1); exit 1; }; };; +esac +build=$ac_cv_build +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_build +shift +build_cpu=$1 +build_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +build_os=$* +IFS=$ac_save_IFS +case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac + + +{ echo "$as_me:$LINENO: checking host system type" >&5 +echo $ECHO_N "checking host system type... $ECHO_C" >&6; } +if test "${ac_cv_host+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "x$host_alias" = x; then + ac_cv_host=$ac_cv_build +else + ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || + { { echo "$as_me:$LINENO: error: $SHELL $ac_aux_dir/config.sub $host_alias failed" >&5 +echo "$as_me: error: $SHELL $ac_aux_dir/config.sub $host_alias failed" >&2;} + { (exit 1); exit 1; }; } +fi + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_host" >&5 +echo "${ECHO_T}$ac_cv_host" >&6; } +case $ac_cv_host in +*-*-*) ;; +*) { { echo "$as_me:$LINENO: error: invalid value of canonical host" >&5 +echo "$as_me: error: invalid value of canonical host" >&2;} + { (exit 1); exit 1; }; };; +esac +host=$ac_cv_host +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_host +shift +host_cpu=$1 +host_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +host_os=$* +IFS=$ac_save_IFS +case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac + + +{ echo "$as_me:$LINENO: checking target system type" >&5 +echo $ECHO_N "checking target system type... $ECHO_C" >&6; } +if test "${ac_cv_target+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "x$target_alias" = x; then + ac_cv_target=$ac_cv_host +else + ac_cv_target=`$SHELL "$ac_aux_dir/config.sub" $target_alias` || + { { echo "$as_me:$LINENO: error: $SHELL $ac_aux_dir/config.sub $target_alias failed" >&5 +echo "$as_me: error: $SHELL $ac_aux_dir/config.sub $target_alias failed" >&2;} + { (exit 1); exit 1; }; } +fi + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_target" >&5 +echo "${ECHO_T}$ac_cv_target" >&6; } +case $ac_cv_target in +*-*-*) ;; +*) { { echo "$as_me:$LINENO: error: invalid value of canonical target" >&5 +echo "$as_me: error: invalid value of canonical target" >&2;} + { (exit 1); exit 1; }; };; +esac +target=$ac_cv_target +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_target +shift +target_cpu=$1 +target_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +target_os=$* +IFS=$ac_save_IFS +case $target_os in *\ *) target_os=`echo "$target_os" | sed 's/ /-/g'`;; esac + + +# The aliases save the names the user supplied, while $host etc. +# will get canonicalized. +test -n "$target_alias" && + test "$program_prefix$program_suffix$program_transform_name" = \ + NONENONEs,x,x, && + program_prefix=${target_alias}- + +am__api_version="1.7" +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AmigaOS /C/install, which installs bootblocks on floppy discs +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# OS/2's system install, which has a completely different semantic +# ./install, which can be erroneously created by make from ./install.sh. +{ echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5 +echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6; } +if test -z "$INSTALL"; then +if test "${ac_cv_path_install+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + # Account for people who put trailing slashes in PATH elements. +case $as_dir/ in + ./ | .// | /cC/* | \ + /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ + ?:\\/os2\\/install\\/* | ?:\\/OS2\\/INSTALL\\/* | \ + /usr/ucb/* ) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then + if test $ac_prog = install && + grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + elif test $ac_prog = install && + grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # program-specific install script used by HP pwplus--don't use. + : + else + ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" + break 3 + fi + fi + done + done + ;; +esac +done +IFS=$as_save_IFS + + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL=$ac_cv_path_install + else + # As a last resort, use the slow shell script. Don't cache a + # value for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + INSTALL=$ac_install_sh + fi +fi +{ echo "$as_me:$LINENO: result: $INSTALL" >&5 +echo "${ECHO_T}$INSTALL" >&6; } + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + +{ echo "$as_me:$LINENO: checking whether build environment is sane" >&5 +echo $ECHO_N "checking whether build environment is sane... $ECHO_C" >&6; } +# Just in case +sleep 1 +echo timestamp > conftest.file +# Do `set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + set X `ls -Lt $srcdir/configure conftest.file 2> /dev/null` + if test "$*" = "X"; then + # -L didn't work. + set X `ls -t $srcdir/configure conftest.file` + fi + rm -f conftest.file + if test "$*" != "X $srcdir/configure conftest.file" \ + && test "$*" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + { { echo "$as_me:$LINENO: error: ls -t appears to fail. Make sure there is not a broken +alias in your environment" >&5 +echo "$as_me: error: ls -t appears to fail. Make sure there is not a broken +alias in your environment" >&2;} + { (exit 1); exit 1; }; } + fi + + test "$2" = conftest.file + ) +then + # Ok. + : +else + { { echo "$as_me:$LINENO: error: newly created file is older than distributed files! +Check your system clock" >&5 +echo "$as_me: error: newly created file is older than distributed files! +Check your system clock" >&2;} + { (exit 1); exit 1; }; } +fi +{ echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6; } +test "$program_prefix" != NONE && + program_transform_name="s&^&$program_prefix&;$program_transform_name" +# Use a double $ so make ignores it. +test "$program_suffix" != NONE && + program_transform_name="s&\$&$program_suffix&;$program_transform_name" +# Double any \ or $. echo might interpret backslashes. +# By default was `s,x,x', remove it if useless. +cat <<\_ACEOF >conftest.sed +s/[\\$]/&&/g;s/;s,x,x,$// +_ACEOF +program_transform_name=`echo $program_transform_name | sed -f conftest.sed` +rm -f conftest.sed + + +# expand $ac_aux_dir to an absolute path +am_aux_dir=`cd $ac_aux_dir && pwd` + +test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing" +# Use eval to expand $SHELL +if eval "$MISSING --run true"; then + am_missing_run="$MISSING --run " +else + am_missing_run= + { echo "$as_me:$LINENO: WARNING: \`missing' script is too old or missing" >&5 +echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;} +fi + +for ac_prog in gawk mawk nawk awk +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_AWK+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$AWK"; then + ac_cv_prog_AWK="$AWK" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_AWK="$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +AWK=$ac_cv_prog_AWK +if test -n "$AWK"; then + { echo "$as_me:$LINENO: result: $AWK" >&5 +echo "${ECHO_T}$AWK" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + + test -n "$AWK" && break +done + +{ echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \$(MAKE)" >&5 +echo $ECHO_N "checking whether ${MAKE-make} sets \$(MAKE)... $ECHO_C" >&6; } +set x ${MAKE-make}; ac_make=`echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` +if { as_var=ac_cv_prog_make_${ac_make}_set; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.make <<\_ACEOF +SHELL = /bin/sh +all: + @echo '@@@%%%=$(MAKE)=@@@%%%' +_ACEOF +# GNU make sometimes prints "make[1]: Entering...", which would confuse us. +case `${MAKE-make} -f conftest.make 2>/dev/null` in + *@@@%%%=?*=@@@%%%*) + eval ac_cv_prog_make_${ac_make}_set=yes;; + *) + eval ac_cv_prog_make_${ac_make}_set=no;; +esac +rm -f conftest.make +fi +if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then + { echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6; } + SET_MAKE= +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } + SET_MAKE="MAKE=${MAKE-make}" +fi + +rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null + + # test to see if srcdir already configured +if test "`cd $srcdir && pwd`" != "`pwd`" && + test -f $srcdir/config.status; then + { { echo "$as_me:$LINENO: error: source directory already configured; run \"make distclean\" there first" >&5 +echo "$as_me: error: source directory already configured; run \"make distclean\" there first" >&2;} + { (exit 1); exit 1; }; } +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi + + +# Define the identity of the package. + PACKAGE='netperf' + VERSION='2.4.5' + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE "$PACKAGE" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define VERSION "$VERSION" +_ACEOF + +# Some tools Automake needs. + +ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} + + +AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} + + +AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} + + +AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} + + +MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} + + +AMTAR=${AMTAR-"${am_missing_run}tar"} + +install_sh=${install_sh-"$am_aux_dir/install-sh"} + +# Installed binaries are usually stripped using `strip' when the user +# run `make install-strip'. However `strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the `STRIP' environment variable to overrule this program. +if test "$cross_compiling" != no; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. +set dummy ${ac_tool_prefix}strip; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_STRIP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$STRIP"; then + ac_cv_prog_STRIP="$STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_STRIP="${ac_tool_prefix}strip" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +STRIP=$ac_cv_prog_STRIP +if test -n "$STRIP"; then + { echo "$as_me:$LINENO: result: $STRIP" >&5 +echo "${ECHO_T}$STRIP" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_STRIP"; then + ac_ct_STRIP=$STRIP + # Extract the first word of "strip", so it can be a program name with args. +set dummy strip; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_STRIP"; then + ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_STRIP="strip" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP +if test -n "$ac_ct_STRIP"; then + { echo "$as_me:$LINENO: result: $ac_ct_STRIP" >&5 +echo "${ECHO_T}$ac_ct_STRIP" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + if test "x$ac_ct_STRIP" = x; then + STRIP=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&5 +echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&2;} +ac_tool_warned=yes ;; +esac + STRIP=$ac_ct_STRIP + fi +else + STRIP="$ac_cv_prog_STRIP" +fi + +fi +INSTALL_STRIP_PROGRAM="\${SHELL} \$(install_sh) -c -s" + +# We need awk for the "check" target. The system "awk" is bad on +# some platforms. + + + +ac_config_headers="$ac_config_headers config.h" + +# AC_CONFIG_HEADER(config.h) + + + +# make sure we build netperf_version.h +touch src/netperf_version.h.in + +# Checks for programs. +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. +set dummy ${ac_tool_prefix}gcc; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CC="gcc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&5 +echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +else + CC="$ac_cv_prog_CC" +fi + +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. +set dummy ${ac_tool_prefix}cc; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="${ac_tool_prefix}cc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + + fi +fi +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_prog_rejected=no +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# != 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" + fi +fi +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + for ac_prog in cl.exe + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in cl.exe +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CC="$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + + test -n "$ac_ct_CC" && break +done + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&5 +echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +fi + +fi + + +test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH +See \`config.log' for more details." >&5 +echo "$as_me: error: no acceptable C compiler found in \$PATH +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } + +# Provide some information about the compiler. +echo "$as_me:$LINENO: checking for C compiler version" >&5 +ac_compiler=`set X $ac_compile; echo $2` +{ (ac_try="$ac_compiler --version >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compiler --version >&5") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (ac_try="$ac_compiler -v >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compiler -v >&5") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (ac_try="$ac_compiler -V >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compiler -V >&5") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files a.out a.exe b.out" +# Try to create an executable without -o first, disregard a.out. +# It will help us diagnose broken compilers, and finding out an intuition +# of exeext. +{ echo "$as_me:$LINENO: checking for C compiler default output file name" >&5 +echo $ECHO_N "checking for C compiler default output file name... $ECHO_C" >&6; } +ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` +# +# List of possible output files, starting from the most likely. +# The algorithm is not robust to junk in `.', hence go to wildcards (a.*) +# only as a last resort. b.out is created by i960 compilers. +ac_files='a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out' +# +# The IRIX 6 linker writes into existing files which may not be +# executable, retaining their permissions. Remove them first so a +# subsequent execution test works. +ac_rmfiles= +for ac_file in $ac_files +do + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) ;; + * ) ac_rmfiles="$ac_rmfiles $ac_file";; + esac +done +rm -f $ac_rmfiles + +if { (ac_try="$ac_link_default" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link_default") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. +# So ignore a value of `no', otherwise this would lead to `EXEEXT = no' +# in a Makefile. We should not override ac_cv_exeext if it was cached, +# so that the user can short-circuit this test for compilers unknown to +# Autoconf. +for ac_file in $ac_files '' +do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) + ;; + [ab].out ) + # We found the default executable, but exeext='' is most + # certainly right. + break;; + *.* ) + if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; + then :; else + ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + fi + # We set ac_cv_exeext here because the later test for it is not + # safe: cross compilers may not add the suffix if given an `-o' + # argument, so we may need to know it at that point already. + # Even if this section looks crufty: it has the advantage of + # actually working. + break;; + * ) + break;; + esac +done +test "$ac_cv_exeext" = no && ac_cv_exeext= + +else + ac_file='' +fi + +{ echo "$as_me:$LINENO: result: $ac_file" >&5 +echo "${ECHO_T}$ac_file" >&6; } +if test -z "$ac_file"; then + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { echo "$as_me:$LINENO: error: C compiler cannot create executables +See \`config.log' for more details." >&5 +echo "$as_me: error: C compiler cannot create executables +See \`config.log' for more details." >&2;} + { (exit 77); exit 77; }; } +fi + +ac_exeext=$ac_cv_exeext + +# Check that the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +{ echo "$as_me:$LINENO: checking whether the C compiler works" >&5 +echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6; } +# FIXME: These cross compiler hacks should be removed for Autoconf 3.0 +# If not cross compiling, check that we can run a simple program. +if test "$cross_compiling" != yes; then + if { ac_try='./$ac_file' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + cross_compiling=no + else + if test "$cross_compiling" = maybe; then + cross_compiling=yes + else + { { echo "$as_me:$LINENO: error: cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } + fi + fi +fi +{ echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6; } + +rm -f a.out a.exe conftest$ac_cv_exeext b.out +ac_clean_files=$ac_clean_files_save +# Check that the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +{ echo "$as_me:$LINENO: checking whether we are cross compiling" >&5 +echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6; } +{ echo "$as_me:$LINENO: result: $cross_compiling" >&5 +echo "${ECHO_T}$cross_compiling" >&6; } + +{ echo "$as_me:$LINENO: checking for suffix of executables" >&5 +echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6; } +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + # If both `conftest.exe' and `conftest' are `present' (well, observable) +# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will +# work properly (i.e., refer to `conftest.exe'), while it won't with +# `rm'. +for ac_file in conftest.exe conftest conftest.*; do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) ;; + *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + break;; + * ) break;; + esac +done +else + { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +fi + +rm -f conftest$ac_cv_exeext +{ echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5 +echo "${ECHO_T}$ac_cv_exeext" >&6; } + +rm -f conftest.$ac_ext +EXEEXT=$ac_cv_exeext +ac_exeext=$EXEEXT +{ echo "$as_me:$LINENO: checking for suffix of object files" >&5 +echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6; } +if test "${ac_cv_objext+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.o conftest.obj +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + for ac_file in conftest.o conftest.obj conftest.*; do + test -f "$ac_file" || continue; + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf ) ;; + *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` + break;; + esac +done +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute suffix of object files: cannot compile +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +fi + +rm -f conftest.$ac_cv_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_objext" >&5 +echo "${ECHO_T}$ac_cv_objext" >&6; } +OBJEXT=$ac_cv_objext +ac_objext=$OBJEXT +{ echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5 +echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6; } +if test "${ac_cv_c_compiler_gnu+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_compiler_gnu=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_compiler_gnu=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5 +echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6; } +GCC=`test $ac_compiler_gnu = yes && echo yes` +ac_test_CFLAGS=${CFLAGS+set} +ac_save_CFLAGS=$CFLAGS +{ echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5 +echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6; } +if test "${ac_cv_prog_cc_g+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_save_c_werror_flag=$ac_c_werror_flag + ac_c_werror_flag=yes + ac_cv_prog_cc_g=no + CFLAGS="-g" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_prog_cc_g=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + CFLAGS="" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_c_werror_flag=$ac_save_c_werror_flag + CFLAGS="-g" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_prog_cc_g=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_c_werror_flag=$ac_save_c_werror_flag +fi +{ echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5 +echo "${ECHO_T}$ac_cv_prog_cc_g" >&6; } +if test "$ac_test_CFLAGS" = set; then + CFLAGS=$ac_save_CFLAGS +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi +{ echo "$as_me:$LINENO: checking for $CC option to accept ISO C89" >&5 +echo $ECHO_N "checking for $CC option to accept ISO C89... $ECHO_C" >&6; } +if test "${ac_cv_prog_cc_c89+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_prog_cc_c89=no +ac_save_CC=$CC +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +#include +#include +/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +struct buf { int x; }; +FILE * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} + +/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has + function prototypes and stuff, but not '\xHH' hex character constants. + These don't provoke an error unfortunately, instead are silently treated + as 'x'. The following induces an error, until -std is added to get + proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an + array size at least. It's necessary to write '\x00'==0 to get something + that's true only with -std. */ +int osf4_cc_array ['\x00' == 0 ? 1 : -1]; + +/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters + inside strings and character constants. */ +#define FOO(x) 'x' +int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; + +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +int argc; +char **argv; +int +main () +{ +return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; + ; + return 0; +} +_ACEOF +for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ + -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_prog_cc_c89=$ac_arg +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext + test "x$ac_cv_prog_cc_c89" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC + +fi +# AC_CACHE_VAL +case "x$ac_cv_prog_cc_c89" in + x) + { echo "$as_me:$LINENO: result: none needed" >&5 +echo "${ECHO_T}none needed" >&6; } ;; + xno) + { echo "$as_me:$LINENO: result: unsupported" >&5 +echo "${ECHO_T}unsupported" >&6; } ;; + *) + CC="$CC $ac_cv_prog_cc_c89" + { echo "$as_me:$LINENO: result: $ac_cv_prog_cc_c89" >&5 +echo "${ECHO_T}$ac_cv_prog_cc_c89" >&6; } ;; +esac + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +DEPDIR="${am__leading_dot}deps" + +ac_config_commands="$ac_config_commands depfiles" + + +am_make=${MAKE-make} +cat > confinc << 'END' +am__doit: + @echo done +.PHONY: am__doit +END +# If we don't find an include directive, just comment out the code. +{ echo "$as_me:$LINENO: checking for style of include used by $am_make" >&5 +echo $ECHO_N "checking for style of include used by $am_make... $ECHO_C" >&6; } +am__include="#" +am__quote= +_am_result=none +# First try GNU make style include. +echo "include confinc" > confmf +# We grep out `Entering directory' and `Leaving directory' +# messages which can occur if `w' ends up in MAKEFLAGS. +# In particular we don't look at `^make:' because GNU make might +# be invoked under some other name (usually "gmake"), in which +# case it prints its new name instead of `make'. +if test "`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`" = "done"; then + am__include=include + am__quote= + _am_result=GNU +fi +# Now try BSD make style include. +if test "$am__include" = "#"; then + echo '.include "confinc"' > confmf + if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then + am__include=.include + am__quote="\"" + _am_result=BSD + fi +fi + + +{ echo "$as_me:$LINENO: result: $_am_result" >&5 +echo "${ECHO_T}$_am_result" >&6; } +rm -f confinc confmf + +# Check whether --enable-dependency-tracking was given. +if test "${enable_dependency_tracking+set}" = set; then + enableval=$enable_dependency_tracking; +fi + +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' +fi + + +if test "x$enable_dependency_tracking" != xno; then + AMDEP_TRUE= + AMDEP_FALSE='#' +else + AMDEP_TRUE='#' + AMDEP_FALSE= +fi + + + + +depcc="$CC" am_compiler_list= + +{ echo "$as_me:$LINENO: checking dependency style of $depcc" >&5 +echo $ECHO_N "checking dependency style of $depcc... $ECHO_C" >&6; } +if test "${am_cv_CC_dependencies_compiler_type+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named `D' -- because `-MD' means `put the output + # in D'. + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_CC_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` + fi + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + : > sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + case $depmode in + nosideeffect) + # after this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + none) break ;; + esac + # We check with `-c' and `-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle `-M -o', and we need to detect this. + if depmode=$depmode \ + source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # (even with -Werror). So we grep stderr for any message + # that says an option was ignored. + if grep 'ignoring option' conftest.err >/dev/null 2>&1; then :; else + am_cv_CC_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_CC_dependencies_compiler_type=none +fi + +fi +{ echo "$as_me:$LINENO: result: $am_cv_CC_dependencies_compiler_type" >&5 +echo "${ECHO_T}$am_cv_CC_dependencies_compiler_type" >&6; } +CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type + + + +if + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then + am__fastdepCC_TRUE= + am__fastdepCC_FALSE='#' +else + am__fastdepCC_TRUE='#' + am__fastdepCC_FALSE= +fi + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. +set dummy ${ac_tool_prefix}ranlib; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_RANLIB+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +RANLIB=$ac_cv_prog_RANLIB +if test -n "$RANLIB"; then + { echo "$as_me:$LINENO: result: $RANLIB" >&5 +echo "${ECHO_T}$RANLIB" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_RANLIB"; then + ac_ct_RANLIB=$RANLIB + # Extract the first word of "ranlib", so it can be a program name with args. +set dummy ranlib; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_RANLIB"; then + ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_RANLIB="ranlib" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB +if test -n "$ac_ct_RANLIB"; then + { echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5 +echo "${ECHO_T}$ac_ct_RANLIB" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + if test "x$ac_ct_RANLIB" = x; then + RANLIB=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&5 +echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&2;} +ac_tool_warned=yes ;; +esac + RANLIB=$ac_ct_RANLIB + fi +else + RANLIB="$ac_cv_prog_RANLIB" +fi + + + +{ echo "$as_me:$LINENO: checking for an ANSI C-conforming const" >&5 +echo $ECHO_N "checking for an ANSI C-conforming const... $ECHO_C" >&6; } +if test "${ac_cv_c_const+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ +/* FIXME: Include the comments suggested by Paul. */ +#ifndef __cplusplus + /* Ultrix mips cc rejects this. */ + typedef int charset[2]; + const charset cs; + /* SunOS 4.1.1 cc rejects this. */ + char const *const *pcpcc; + char **ppc; + /* NEC SVR4.0.2 mips cc rejects this. */ + struct point {int x, y;}; + static struct point const zero = {0,0}; + /* AIX XL C 1.02.0.0 rejects this. + It does not let you subtract one const X* pointer from another in + an arm of an if-expression whose if-part is not a constant + expression */ + const char *g = "string"; + pcpcc = &g + (g ? g-g : 0); + /* HPUX 7.0 cc rejects these. */ + ++pcpcc; + ppc = (char**) pcpcc; + pcpcc = (char const *const *) ppc; + { /* SCO 3.2v4 cc rejects this. */ + char *t; + char const *s = 0 ? (char *) 0 : (char const *) 0; + + *t++ = 0; + if (s) return 0; + } + { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */ + int x[] = {25, 17}; + const int *foo = &x[0]; + ++foo; + } + { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */ + typedef const int *iptr; + iptr p = 0; + ++p; + } + { /* AIX XL C 1.02.0.0 rejects this saying + "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */ + struct s { int j; const int *ap[3]; }; + struct s *b; b->j = 5; + } + { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ + const int foo = 10; + if (!foo) return 0; + } + return !cs[0] && !zero.x; +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_c_const=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_c_const=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_c_const" >&5 +echo "${ECHO_T}$ac_cv_c_const" >&6; } +if test $ac_cv_c_const = no; then + +cat >>confdefs.h <<\_ACEOF +#define const +_ACEOF + +fi + + +# Checks for libraries. + +{ echo "$as_me:$LINENO: checking for main in -lm" >&5 +echo $ECHO_N "checking for main in -lm... $ECHO_C" >&6; } +if test "${ac_cv_lib_m_main+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lm $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + + +int +main () +{ +return main (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + ac_cv_lib_m_main=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_lib_m_main=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ echo "$as_me:$LINENO: result: $ac_cv_lib_m_main" >&5 +echo "${ECHO_T}$ac_cv_lib_m_main" >&6; } +if test $ac_cv_lib_m_main = yes; then + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBM 1 +_ACEOF + + LIBS="-lm $LIBS" + +fi +ac_cv_lib_m=ac_cv_lib_m_main + + +# Checks for header files. +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +{ echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5 +echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6; } +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then + if test "${ac_cv_prog_CPP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + # Double quotes because CPP needs to be expanded + for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" + do + ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Broken: fails on valid input. +continue +fi + +rm -f conftest.err conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + # Broken: success on invalid input. +continue +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Passes both tests. +ac_preproc_ok=: +break +fi + +rm -f conftest.err conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.err conftest.$ac_ext +if $ac_preproc_ok; then + break +fi + + done + ac_cv_prog_CPP=$CPP + +fi + CPP=$ac_cv_prog_CPP +else + ac_cv_prog_CPP=$CPP +fi +{ echo "$as_me:$LINENO: result: $CPP" >&5 +echo "${ECHO_T}$CPP" >&6; } +ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Broken: fails on valid input. +continue +fi + +rm -f conftest.err conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + # Broken: success on invalid input. +continue +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Passes both tests. +ac_preproc_ok=: +break +fi + +rm -f conftest.err conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.err conftest.$ac_ext +if $ac_preproc_ok; then + : +else + { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details." >&5 +echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +{ echo "$as_me:$LINENO: checking for grep that handles long lines and -e" >&5 +echo $ECHO_N "checking for grep that handles long lines and -e... $ECHO_C" >&6; } +if test "${ac_cv_path_GREP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + # Extract the first word of "grep ggrep" to use in msg output +if test -z "$GREP"; then +set dummy grep ggrep; ac_prog_name=$2 +if test "${ac_cv_path_GREP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_path_GREP_found=false +# Loop through the user's path and test for each of PROGNAME-LIST +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in grep ggrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" + { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue + # Check for GNU ac_path_GREP and select it if it is found. + # Check for GNU $ac_path_GREP +case `"$ac_path_GREP" --version 2>&1` in +*GNU*) + ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; +*) + ac_count=0 + echo $ECHO_N "0123456789$ECHO_C" >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + echo 'GREP' >> "conftest.nl" + "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + ac_count=`expr $ac_count + 1` + if test $ac_count -gt ${ac_path_GREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_GREP="$ac_path_GREP" + ac_path_GREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + + $ac_path_GREP_found && break 3 + done +done + +done +IFS=$as_save_IFS + + +fi + +GREP="$ac_cv_path_GREP" +if test -z "$GREP"; then + { { echo "$as_me:$LINENO: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5 +echo "$as_me: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;} + { (exit 1); exit 1; }; } +fi + +else + ac_cv_path_GREP=$GREP +fi + + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_path_GREP" >&5 +echo "${ECHO_T}$ac_cv_path_GREP" >&6; } + GREP="$ac_cv_path_GREP" + + +{ echo "$as_me:$LINENO: checking for egrep" >&5 +echo $ECHO_N "checking for egrep... $ECHO_C" >&6; } +if test "${ac_cv_path_EGREP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 + then ac_cv_path_EGREP="$GREP -E" + else + # Extract the first word of "egrep" to use in msg output +if test -z "$EGREP"; then +set dummy egrep; ac_prog_name=$2 +if test "${ac_cv_path_EGREP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_path_EGREP_found=false +# Loop through the user's path and test for each of PROGNAME-LIST +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in egrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" + { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue + # Check for GNU ac_path_EGREP and select it if it is found. + # Check for GNU $ac_path_EGREP +case `"$ac_path_EGREP" --version 2>&1` in +*GNU*) + ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; +*) + ac_count=0 + echo $ECHO_N "0123456789$ECHO_C" >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + echo 'EGREP' >> "conftest.nl" + "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + ac_count=`expr $ac_count + 1` + if test $ac_count -gt ${ac_path_EGREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_EGREP="$ac_path_EGREP" + ac_path_EGREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + + $ac_path_EGREP_found && break 3 + done +done + +done +IFS=$as_save_IFS + + +fi + +EGREP="$ac_cv_path_EGREP" +if test -z "$EGREP"; then + { { echo "$as_me:$LINENO: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5 +echo "$as_me: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;} + { (exit 1); exit 1; }; } +fi + +else + ac_cv_path_EGREP=$EGREP +fi + + + fi +fi +{ echo "$as_me:$LINENO: result: $ac_cv_path_EGREP" >&5 +echo "${ECHO_T}$ac_cv_path_EGREP" >&6; } + EGREP="$ac_cv_path_EGREP" + + +{ echo "$as_me:$LINENO: checking for ANSI C header files" >&5 +echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6; } +if test "${ac_cv_header_stdc+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +#include +#include + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_header_stdc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_header_stdc=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "memchr" >/dev/null 2>&1; then + : +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "free" >/dev/null 2>&1; then + : +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. + if test "$cross_compiling" = yes; then + : +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +#if ((' ' & 0x0FF) == 0x020) +# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#else +# define ISLOWER(c) \ + (('a' <= (c) && (c) <= 'i') \ + || ('j' <= (c) && (c) <= 'r') \ + || ('s' <= (c) && (c) <= 'z')) +# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) +#endif + +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int +main () +{ + int i; + for (i = 0; i < 256; i++) + if (XOR (islower (i), ISLOWER (i)) + || toupper (i) != TOUPPER (i)) + return 2; + return 0; +} +_ACEOF +rm -f conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + : +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +ac_cv_header_stdc=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi + + +fi +fi +{ echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5 +echo "${ECHO_T}$ac_cv_header_stdc" >&6; } +if test $ac_cv_header_stdc = yes; then + +cat >>confdefs.h <<\_ACEOF +#define STDC_HEADERS 1 +_ACEOF + +fi + +{ echo "$as_me:$LINENO: checking for sys/wait.h that is POSIX.1 compatible" >&5 +echo $ECHO_N "checking for sys/wait.h that is POSIX.1 compatible... $ECHO_C" >&6; } +if test "${ac_cv_header_sys_wait_h+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +#ifndef WEXITSTATUS +# define WEXITSTATUS(stat_val) ((unsigned int) (stat_val) >> 8) +#endif +#ifndef WIFEXITED +# define WIFEXITED(stat_val) (((stat_val) & 255) == 0) +#endif + +int +main () +{ + int s; + wait (&s); + s = WIFEXITED (s) ? WEXITSTATUS (s) : 1; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_header_sys_wait_h=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_header_sys_wait_h=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_header_sys_wait_h" >&5 +echo "${ECHO_T}$ac_cv_header_sys_wait_h" >&6; } +if test $ac_cv_header_sys_wait_h = yes; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_SYS_WAIT_H 1 +_ACEOF + +fi + +# On IRIX 5.3, sys/types and inttypes.h are conflicting. + + + + + + + + + +for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ + inttypes.h stdint.h unistd.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +{ echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + eval "$as_ac_Header=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + eval "$as_ac_Header=no" +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + + + + + + + + + + + + + + + + + + + + + +for ac_header in arpa/inet.h endian.h errno.h fcntl.h limits.h malloc.h netdb.h netinet/in.h signal.h stdlib.h string.h strings.h sys/ioctl.h sys/mman.h sys/param.h sys/socket.h sys/time.h unistd.h ifaddrs.h sys/sockio.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + { echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +else + # Is the header compilable? +{ echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_compiler=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6; } + +# Is the header present? +{ echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi + +rm -f conftest.err conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + + ;; +esac +{ echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + +# Some platforms require these. There may be a better way. + +{ echo "$as_me:$LINENO: checking for main in -lsocket" >&5 +echo $ECHO_N "checking for main in -lsocket... $ECHO_C" >&6; } +if test "${ac_cv_lib_socket_main+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lsocket $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + + +int +main () +{ +return main (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + ac_cv_lib_socket_main=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_lib_socket_main=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ echo "$as_me:$LINENO: result: $ac_cv_lib_socket_main" >&5 +echo "${ECHO_T}$ac_cv_lib_socket_main" >&6; } +if test $ac_cv_lib_socket_main = yes; then + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBSOCKET 1 +_ACEOF + + LIBS="-lsocket $LIBS" + +fi +ac_cv_lib_socket=ac_cv_lib_socket_main + +if test "$ac_cv_lib_socket_main" = yes ; then + +{ echo "$as_me:$LINENO: checking for main in -lnsl" >&5 +echo $ECHO_N "checking for main in -lnsl... $ECHO_C" >&6; } +if test "${ac_cv_lib_nsl_main+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lnsl $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + + +int +main () +{ +return main (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + ac_cv_lib_nsl_main=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_lib_nsl_main=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ echo "$as_me:$LINENO: result: $ac_cv_lib_nsl_main" >&5 +echo "${ECHO_T}$ac_cv_lib_nsl_main" >&6; } +if test $ac_cv_lib_nsl_main = yes; then + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBNSL 1 +_ACEOF + + LIBS="-lnsl $LIBS" + +fi +ac_cv_lib_nsl=ac_cv_lib_nsl_main + + +{ echo "$as_me:$LINENO: checking for main in -lsendfile" >&5 +echo $ECHO_N "checking for main in -lsendfile... $ECHO_C" >&6; } +if test "${ac_cv_lib_sendfile_main+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lsendfile $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + + +int +main () +{ +return main (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + ac_cv_lib_sendfile_main=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_lib_sendfile_main=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ echo "$as_me:$LINENO: result: $ac_cv_lib_sendfile_main" >&5 +echo "${ECHO_T}$ac_cv_lib_sendfile_main" >&6; } +if test $ac_cv_lib_sendfile_main = yes; then + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBSENDFILE 1 +_ACEOF + + LIBS="-lsendfile $LIBS" + +fi +ac_cv_lib_sendfile=ac_cv_lib_sendfile_main + + # Check whether --enable-largefile was given. +if test "${enable_largefile+set}" = set; then + enableval=$enable_largefile; +fi + +if test "$enable_largefile" != no; then + + { echo "$as_me:$LINENO: checking for special C compiler options needed for large files" >&5 +echo $ECHO_N "checking for special C compiler options needed for large files... $ECHO_C" >&6; } +if test "${ac_cv_sys_largefile_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_sys_largefile_CC=no + if test "$GCC" != yes; then + ac_save_CC=$CC + while :; do + # IRIX 6.2 and later do not support large files by default, + # so use the C compiler's -n32 option if that helps. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include + /* Check that off_t can represent 2**63 - 1 correctly. + We can't simply define LARGE_OFF_T to be 9223372036854775807, + since some C++ compilers masquerading as C compilers + incorrectly reject 9223372036854775807. */ +#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) + int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 + && LARGE_OFF_T % 2147483647 == 1) + ? 1 : -1]; +int +main () +{ + + ; + return 0; +} +_ACEOF + rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext + CC="$CC -n32" + rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_sys_largefile_CC=' -n32'; break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext + break + done + CC=$ac_save_CC + rm -f conftest.$ac_ext + fi +fi +{ echo "$as_me:$LINENO: result: $ac_cv_sys_largefile_CC" >&5 +echo "${ECHO_T}$ac_cv_sys_largefile_CC" >&6; } + if test "$ac_cv_sys_largefile_CC" != no; then + CC=$CC$ac_cv_sys_largefile_CC + fi + + { echo "$as_me:$LINENO: checking for _FILE_OFFSET_BITS value needed for large files" >&5 +echo $ECHO_N "checking for _FILE_OFFSET_BITS value needed for large files... $ECHO_C" >&6; } +if test "${ac_cv_sys_file_offset_bits+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + while :; do + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include + /* Check that off_t can represent 2**63 - 1 correctly. + We can't simply define LARGE_OFF_T to be 9223372036854775807, + since some C++ compilers masquerading as C compilers + incorrectly reject 9223372036854775807. */ +#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) + int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 + && LARGE_OFF_T % 2147483647 == 1) + ? 1 : -1]; +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_sys_file_offset_bits=no; break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#define _FILE_OFFSET_BITS 64 +#include + /* Check that off_t can represent 2**63 - 1 correctly. + We can't simply define LARGE_OFF_T to be 9223372036854775807, + since some C++ compilers masquerading as C compilers + incorrectly reject 9223372036854775807. */ +#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) + int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 + && LARGE_OFF_T % 2147483647 == 1) + ? 1 : -1]; +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_sys_file_offset_bits=64; break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_cv_sys_file_offset_bits=unknown + break +done +fi +{ echo "$as_me:$LINENO: result: $ac_cv_sys_file_offset_bits" >&5 +echo "${ECHO_T}$ac_cv_sys_file_offset_bits" >&6; } +case $ac_cv_sys_file_offset_bits in #( + no | unknown) ;; + *) +cat >>confdefs.h <<_ACEOF +#define _FILE_OFFSET_BITS $ac_cv_sys_file_offset_bits +_ACEOF +;; +esac +rm -f conftest* + if test $ac_cv_sys_file_offset_bits = unknown; then + { echo "$as_me:$LINENO: checking for _LARGE_FILES value needed for large files" >&5 +echo $ECHO_N "checking for _LARGE_FILES value needed for large files... $ECHO_C" >&6; } +if test "${ac_cv_sys_large_files+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + while :; do + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include + /* Check that off_t can represent 2**63 - 1 correctly. + We can't simply define LARGE_OFF_T to be 9223372036854775807, + since some C++ compilers masquerading as C compilers + incorrectly reject 9223372036854775807. */ +#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) + int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 + && LARGE_OFF_T % 2147483647 == 1) + ? 1 : -1]; +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_sys_large_files=no; break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#define _LARGE_FILES 1 +#include + /* Check that off_t can represent 2**63 - 1 correctly. + We can't simply define LARGE_OFF_T to be 9223372036854775807, + since some C++ compilers masquerading as C compilers + incorrectly reject 9223372036854775807. */ +#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) + int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 + && LARGE_OFF_T % 2147483647 == 1) + ? 1 : -1]; +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_sys_large_files=1; break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_cv_sys_large_files=unknown + break +done +fi +{ echo "$as_me:$LINENO: result: $ac_cv_sys_large_files" >&5 +echo "${ECHO_T}$ac_cv_sys_large_files" >&6; } +case $ac_cv_sys_large_files in #( + no | unknown) ;; + *) +cat >>confdefs.h <<_ACEOF +#define _LARGE_FILES $ac_cv_sys_large_files +_ACEOF +;; +esac +rm -f conftest* + fi +fi + +fi + +# this one is for Tru64 and bind_to_cpu_id + +{ echo "$as_me:$LINENO: checking for main in -lmach" >&5 +echo $ECHO_N "checking for main in -lmach... $ECHO_C" >&6; } +if test "${ac_cv_lib_mach_main+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lmach $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + + +int +main () +{ +return main (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + ac_cv_lib_mach_main=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_lib_mach_main=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ echo "$as_me:$LINENO: result: $ac_cv_lib_mach_main" >&5 +echo "${ECHO_T}$ac_cv_lib_mach_main" >&6; } +if test $ac_cv_lib_mach_main = yes; then + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBMACH 1 +_ACEOF + + LIBS="-lmach $LIBS" + +fi +ac_cv_lib_mach=ac_cv_lib_mach_main + + +# Checks for typedefs, structures, and compiler characteristics. +{ echo "$as_me:$LINENO: checking for an ANSI C-conforming const" >&5 +echo $ECHO_N "checking for an ANSI C-conforming const... $ECHO_C" >&6; } +if test "${ac_cv_c_const+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ +/* FIXME: Include the comments suggested by Paul. */ +#ifndef __cplusplus + /* Ultrix mips cc rejects this. */ + typedef int charset[2]; + const charset cs; + /* SunOS 4.1.1 cc rejects this. */ + char const *const *pcpcc; + char **ppc; + /* NEC SVR4.0.2 mips cc rejects this. */ + struct point {int x, y;}; + static struct point const zero = {0,0}; + /* AIX XL C 1.02.0.0 rejects this. + It does not let you subtract one const X* pointer from another in + an arm of an if-expression whose if-part is not a constant + expression */ + const char *g = "string"; + pcpcc = &g + (g ? g-g : 0); + /* HPUX 7.0 cc rejects these. */ + ++pcpcc; + ppc = (char**) pcpcc; + pcpcc = (char const *const *) ppc; + { /* SCO 3.2v4 cc rejects this. */ + char *t; + char const *s = 0 ? (char *) 0 : (char const *) 0; + + *t++ = 0; + if (s) return 0; + } + { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */ + int x[] = {25, 17}; + const int *foo = &x[0]; + ++foo; + } + { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */ + typedef const int *iptr; + iptr p = 0; + ++p; + } + { /* AIX XL C 1.02.0.0 rejects this saying + "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */ + struct s { int j; const int *ap[3]; }; + struct s *b; b->j = 5; + } + { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ + const int foo = 10; + if (!foo) return 0; + } + return !cs[0] && !zero.x; +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_c_const=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_c_const=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_c_const" >&5 +echo "${ECHO_T}$ac_cv_c_const" >&6; } +if test $ac_cv_c_const = no; then + +cat >>confdefs.h <<\_ACEOF +#define const +_ACEOF + +fi + +{ echo "$as_me:$LINENO: checking for off_t" >&5 +echo $ECHO_N "checking for off_t... $ECHO_C" >&6; } +if test "${ac_cv_type_off_t+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +typedef off_t ac__type_new_; +int +main () +{ +if ((ac__type_new_ *) 0) + return 0; +if (sizeof (ac__type_new_)) + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_type_off_t=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_type_off_t=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_type_off_t" >&5 +echo "${ECHO_T}$ac_cv_type_off_t" >&6; } +if test $ac_cv_type_off_t = yes; then + : +else + +cat >>confdefs.h <<_ACEOF +#define off_t long int +_ACEOF + +fi + +{ echo "$as_me:$LINENO: checking for size_t" >&5 +echo $ECHO_N "checking for size_t... $ECHO_C" >&6; } +if test "${ac_cv_type_size_t+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +typedef size_t ac__type_new_; +int +main () +{ +if ((ac__type_new_ *) 0) + return 0; +if (sizeof (ac__type_new_)) + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_type_size_t=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_type_size_t=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_type_size_t" >&5 +echo "${ECHO_T}$ac_cv_type_size_t" >&6; } +if test $ac_cv_type_size_t = yes; then + : +else + +cat >>confdefs.h <<_ACEOF +#define size_t unsigned int +_ACEOF + +fi + +# AC_TYPE_SOCKLEN_T + + + { echo "$as_me:$LINENO: checking for socklen_t equivalent" >&5 +echo $ECHO_N "checking for socklen_t equivalent... $ECHO_C" >&6; } + if test "${curl_cv_socklen_t_equiv+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + + # Systems have either "struct sockaddr *" or + # "void *" as the second argument to getpeername + curl_cv_socklen_t_equiv= + for arg2 in "struct sockaddr" void; do + for t in int size_t unsigned long "unsigned long" socklen_t; do + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + + #ifdef HAVE_SYS_TYPES_H + #include + #endif + #ifdef HAVE_SYS_SOCKET_H + #include + #endif + + extern int getpeername (int, $arg2 *, $t *); + +int +main () +{ + + $t len; + getpeername(0,0,&len); + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + + curl_cv_socklen_t_equiv="$t" + break 2 + +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + done + done + + if test "x$curl_cv_socklen_t_equiv" = x; then + # take a wild guess + curl_cv_socklen_t_equiv="socklen_t" + { echo "$as_me:$LINENO: WARNING: Cannot find a type to use in place of socklen_t, guessing socklen_t" >&5 +echo "$as_me: WARNING: Cannot find a type to use in place of socklen_t, guessing socklen_t" >&2;} + fi + +fi + + { echo "$as_me:$LINENO: result: $curl_cv_socklen_t_equiv" >&5 +echo "${ECHO_T}$curl_cv_socklen_t_equiv" >&6; } + +cat >>confdefs.h <<_ACEOF +#define netperf_socklen_t $curl_cv_socklen_t_equiv +_ACEOF + + + +# AC_TYPE_IN_PORT_T +{ echo "$as_me:$LINENO: checking for h_errno declaration in netdb.h" >&5 +echo $ECHO_N "checking for h_errno declaration in netdb.h... $ECHO_C" >&6; } +if test "${ac_cv_decl_h_errno+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +#include +int +main () +{ + +h_errno = 0; + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_decl_h_errno=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_decl_h_errno=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_decl_h_errno" >&5 +echo "${ECHO_T}$ac_cv_decl_h_errno" >&6; } +if test "$ac_cv_decl_h_errno" = yes; then + +cat >>confdefs.h <<\_ACEOF +#define H_ERRNO_DECLARED 1 +_ACEOF + +fi +{ echo "$as_me:$LINENO: checking for struct sockaddr_storage" >&5 +echo $ECHO_N "checking for struct sockaddr_storage... $ECHO_C" >&6; } +if test "${ac_cv_struct_sockaddr_storage+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +#include +#include +#include +int +main () +{ + +struct sockaddr_storage address; + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_struct_sockaddr_storage=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_struct_sockaddr_storage=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_struct_sockaddr_storage" >&5 +echo "${ECHO_T}$ac_cv_struct_sockaddr_storage" >&6; } +if test "$ac_cv_struct_sockaddr_storage" = yes; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_STRUCT_SOCKADDR_STORAGE 1 +_ACEOF + +fi +{ echo "$as_me:$LINENO: checking whether time.h and sys/time.h may both be included" >&5 +echo $ECHO_N "checking whether time.h and sys/time.h may both be included... $ECHO_C" >&6; } +if test "${ac_cv_header_time+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +#include + +int +main () +{ +if ((struct tm *) 0) +return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_header_time=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_header_time=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_header_time" >&5 +echo "${ECHO_T}$ac_cv_header_time" >&6; } +if test $ac_cv_header_time = yes; then + +cat >>confdefs.h <<\_ACEOF +#define TIME_WITH_SYS_TIME 1 +_ACEOF + +fi + +{ echo "$as_me:$LINENO: checking for stdbool.h that conforms to C99" >&5 +echo $ECHO_N "checking for stdbool.h that conforms to C99... $ECHO_C" >&6; } +if test "${ac_cv_header_stdbool_h+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +#include +#ifndef bool + "error: bool is not defined" +#endif +#ifndef false + "error: false is not defined" +#endif +#if false + "error: false is not 0" +#endif +#ifndef true + "error: true is not defined" +#endif +#if true != 1 + "error: true is not 1" +#endif +#ifndef __bool_true_false_are_defined + "error: __bool_true_false_are_defined is not defined" +#endif + + struct s { _Bool s: 1; _Bool t; } s; + + char a[true == 1 ? 1 : -1]; + char b[false == 0 ? 1 : -1]; + char c[__bool_true_false_are_defined == 1 ? 1 : -1]; + char d[(bool) 0.5 == true ? 1 : -1]; + bool e = &s; + char f[(_Bool) 0.0 == false ? 1 : -1]; + char g[true]; + char h[sizeof (_Bool)]; + char i[sizeof s.t]; + enum { j = false, k = true, l = false * true, m = true * 256 }; + _Bool n[m]; + char o[sizeof n == m * sizeof n[0] ? 1 : -1]; + char p[-1 - (_Bool) 0 < 0 && -1 - (bool) 0 < 0 ? 1 : -1]; +# if defined __xlc__ || defined __GNUC__ + /* Catch a bug in IBM AIX xlc compiler version 6.0.0.0 + reported by James Lemley on 2005-10-05; see + http://lists.gnu.org/archive/html/bug-coreutils/2005-10/msg00086.html + This test is not quite right, since xlc is allowed to + reject this program, as the initializer for xlcbug is + not one of the forms that C requires support for. + However, doing the test right would require a runtime + test, and that would make cross-compilation harder. + Let us hope that IBM fixes the xlc bug, and also adds + support for this kind of constant expression. In the + meantime, this test will reject xlc, which is OK, since + our stdbool.h substitute should suffice. We also test + this with GCC, where it should work, to detect more + quickly whether someone messes up the test in the + future. */ + char digs[] = "0123456789"; + int xlcbug = 1 / (&(digs + 5)[-2 + (bool) 1] == &digs[4] ? 1 : -1); +# endif + /* Catch a bug in an HP-UX C compiler. See + http://gcc.gnu.org/ml/gcc-patches/2003-12/msg02303.html + http://lists.gnu.org/archive/html/bug-coreutils/2005-11/msg00161.html + */ + _Bool q = true; + _Bool *pq = &q; + +int +main () +{ + + *pq |= q; + *pq |= ! q; + /* Refer to every declared value, to avoid compiler optimizations. */ + return (!a + !b + !c + !d + !e + !f + !g + !h + !i + !!j + !k + !!l + + !m + !n + !o + !p + !q + !pq); + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_header_stdbool_h=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_header_stdbool_h=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_header_stdbool_h" >&5 +echo "${ECHO_T}$ac_cv_header_stdbool_h" >&6; } +{ echo "$as_me:$LINENO: checking for _Bool" >&5 +echo $ECHO_N "checking for _Bool... $ECHO_C" >&6; } +if test "${ac_cv_type__Bool+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +typedef _Bool ac__type_new_; +int +main () +{ +if ((ac__type_new_ *) 0) + return 0; +if (sizeof (ac__type_new_)) + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_type__Bool=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_type__Bool=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_type__Bool" >&5 +echo "${ECHO_T}$ac_cv_type__Bool" >&6; } +if test $ac_cv_type__Bool = yes; then + +cat >>confdefs.h <<_ACEOF +#define HAVE__BOOL 1 +_ACEOF + + +fi + +if test $ac_cv_header_stdbool_h = yes; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_STDBOOL_H 1 +_ACEOF + +fi + + + { echo "$as_me:$LINENO: checking if sockaddr struct has sa_len member" >&5 +echo $ECHO_N "checking if sockaddr struct has sa_len member... $ECHO_C" >&6; } + if test "${ac_cv_sockaddr_has_sa_len+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +# include +# include +int +main () +{ +u_int i = sizeof(((struct sockaddr *)0)->sa_len) + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_sockaddr_has_sa_len=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_sockaddr_has_sa_len=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi + + { echo "$as_me:$LINENO: result: $ac_cv_sockaddr_has_sa_len" >&5 +echo "${ECHO_T}$ac_cv_sockaddr_has_sa_len" >&6; } + if test $ac_cv_sockaddr_has_sa_len = yes ; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_SOCKADDR_SA_LEN 1 +_ACEOF + + fi + + +# Checks for library functions. +# AC_FUNC_ERROR_AT_LINE +{ echo "$as_me:$LINENO: checking for pid_t" >&5 +echo $ECHO_N "checking for pid_t... $ECHO_C" >&6; } +if test "${ac_cv_type_pid_t+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +typedef pid_t ac__type_new_; +int +main () +{ +if ((ac__type_new_ *) 0) + return 0; +if (sizeof (ac__type_new_)) + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_type_pid_t=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_type_pid_t=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_type_pid_t" >&5 +echo "${ECHO_T}$ac_cv_type_pid_t" >&6; } +if test $ac_cv_type_pid_t = yes; then + : +else + +cat >>confdefs.h <<_ACEOF +#define pid_t int +_ACEOF + +fi + + +for ac_header in vfork.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + { echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +else + # Is the header compilable? +{ echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_compiler=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6; } + +# Is the header present? +{ echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi + +rm -f conftest.err conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + + ;; +esac +{ echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + + +for ac_func in fork vfork +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +{ echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } +if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define $ac_func to an innocuous variant, in case declares $ac_func. + For example, HP-UX 11i declares gettimeofday. */ +#define $ac_func innocuous_$ac_func + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef $ac_func + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char $ac_func (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_$ac_func || defined __stub___$ac_func +choke me +#endif + +int +main () +{ +return $ac_func (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + eval "$as_ac_var=no" +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +fi +ac_res=`eval echo '${'$as_ac_var'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + +if test "x$ac_cv_func_fork" = xyes; then + { echo "$as_me:$LINENO: checking for working fork" >&5 +echo $ECHO_N "checking for working fork... $ECHO_C" >&6; } +if test "${ac_cv_func_fork_works+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "$cross_compiling" = yes; then + ac_cv_func_fork_works=cross +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ + + /* By Ruediger Kuhlmann. */ + return fork () < 0; + + ; + return 0; +} +_ACEOF +rm -f conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_func_fork_works=yes +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +ac_cv_func_fork_works=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi + + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_func_fork_works" >&5 +echo "${ECHO_T}$ac_cv_func_fork_works" >&6; } + +else + ac_cv_func_fork_works=$ac_cv_func_fork +fi +if test "x$ac_cv_func_fork_works" = xcross; then + case $host in + *-*-amigaos* | *-*-msdosdjgpp*) + # Override, as these systems have only a dummy fork() stub + ac_cv_func_fork_works=no + ;; + *) + ac_cv_func_fork_works=yes + ;; + esac + { echo "$as_me:$LINENO: WARNING: result $ac_cv_func_fork_works guessed because of cross compilation" >&5 +echo "$as_me: WARNING: result $ac_cv_func_fork_works guessed because of cross compilation" >&2;} +fi +ac_cv_func_vfork_works=$ac_cv_func_vfork +if test "x$ac_cv_func_vfork" = xyes; then + { echo "$as_me:$LINENO: checking for working vfork" >&5 +echo $ECHO_N "checking for working vfork... $ECHO_C" >&6; } +if test "${ac_cv_func_vfork_works+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "$cross_compiling" = yes; then + ac_cv_func_vfork_works=cross +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Thanks to Paul Eggert for this test. */ +$ac_includes_default +#include +#ifdef HAVE_VFORK_H +# include +#endif +/* On some sparc systems, changes by the child to local and incoming + argument registers are propagated back to the parent. The compiler + is told about this with #include , but some compilers + (e.g. gcc -O) don't grok . Test for this by using a + static variable whose address is put into a register that is + clobbered by the vfork. */ +static void +#ifdef __cplusplus +sparc_address_test (int arg) +# else +sparc_address_test (arg) int arg; +#endif +{ + static pid_t child; + if (!child) { + child = vfork (); + if (child < 0) { + perror ("vfork"); + _exit(2); + } + if (!child) { + arg = getpid(); + write(-1, "", 0); + _exit (arg); + } + } +} + +int +main () +{ + pid_t parent = getpid (); + pid_t child; + + sparc_address_test (0); + + child = vfork (); + + if (child == 0) { + /* Here is another test for sparc vfork register problems. This + test uses lots of local variables, at least as many local + variables as main has allocated so far including compiler + temporaries. 4 locals are enough for gcc 1.40.3 on a Solaris + 4.1.3 sparc, but we use 8 to be safe. A buggy compiler should + reuse the register of parent for one of the local variables, + since it will think that parent can't possibly be used any more + in this routine. Assigning to the local variable will thus + munge parent in the parent process. */ + pid_t + p = getpid(), p1 = getpid(), p2 = getpid(), p3 = getpid(), + p4 = getpid(), p5 = getpid(), p6 = getpid(), p7 = getpid(); + /* Convince the compiler that p..p7 are live; otherwise, it might + use the same hardware register for all 8 local variables. */ + if (p != p1 || p != p2 || p != p3 || p != p4 + || p != p5 || p != p6 || p != p7) + _exit(1); + + /* On some systems (e.g. IRIX 3.3), vfork doesn't separate parent + from child file descriptors. If the child closes a descriptor + before it execs or exits, this munges the parent's descriptor + as well. Test for this by closing stdout in the child. */ + _exit(close(fileno(stdout)) != 0); + } else { + int status; + struct stat st; + + while (wait(&status) != child) + ; + return ( + /* Was there some problem with vforking? */ + child < 0 + + /* Did the child fail? (This shouldn't happen.) */ + || status + + /* Did the vfork/compiler bug occur? */ + || parent != getpid() + + /* Did the file descriptor bug occur? */ + || fstat(fileno(stdout), &st) != 0 + ); + } +} +_ACEOF +rm -f conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_func_vfork_works=yes +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +ac_cv_func_vfork_works=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi + + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_func_vfork_works" >&5 +echo "${ECHO_T}$ac_cv_func_vfork_works" >&6; } + +fi; +if test "x$ac_cv_func_fork_works" = xcross; then + ac_cv_func_vfork_works=$ac_cv_func_vfork + { echo "$as_me:$LINENO: WARNING: result $ac_cv_func_vfork_works guessed because of cross compilation" >&5 +echo "$as_me: WARNING: result $ac_cv_func_vfork_works guessed because of cross compilation" >&2;} +fi + +if test "x$ac_cv_func_vfork_works" = xyes; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_WORKING_VFORK 1 +_ACEOF + +else + +cat >>confdefs.h <<\_ACEOF +#define vfork fork +_ACEOF + +fi +if test "x$ac_cv_func_fork_works" = xyes; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_WORKING_FORK 1 +_ACEOF + +fi + +# AC_FUNC_MALLOC + + +for ac_header in stdlib.h unistd.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + { echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +else + # Is the header compilable? +{ echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_compiler=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6; } + +# Is the header present? +{ echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi + +rm -f conftest.err conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + + ;; +esac +{ echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + +for ac_func in getpagesize +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +{ echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } +if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define $ac_func to an innocuous variant, in case declares $ac_func. + For example, HP-UX 11i declares gettimeofday. */ +#define $ac_func innocuous_$ac_func + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef $ac_func + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char $ac_func (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_$ac_func || defined __stub___$ac_func +choke me +#endif + +int +main () +{ +return $ac_func (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + eval "$as_ac_var=no" +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +fi +ac_res=`eval echo '${'$as_ac_var'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + +{ echo "$as_me:$LINENO: checking for working mmap" >&5 +echo $ECHO_N "checking for working mmap... $ECHO_C" >&6; } +if test "${ac_cv_func_mmap_fixed_mapped+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "$cross_compiling" = yes; then + ac_cv_func_mmap_fixed_mapped=no +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +/* malloc might have been renamed as rpl_malloc. */ +#undef malloc + +/* Thanks to Mike Haertel and Jim Avera for this test. + Here is a matrix of mmap possibilities: + mmap private not fixed + mmap private fixed at somewhere currently unmapped + mmap private fixed at somewhere already mapped + mmap shared not fixed + mmap shared fixed at somewhere currently unmapped + mmap shared fixed at somewhere already mapped + For private mappings, we should verify that changes cannot be read() + back from the file, nor mmap's back from the file at a different + address. (There have been systems where private was not correctly + implemented like the infamous i386 svr4.0, and systems where the + VM page cache was not coherent with the file system buffer cache + like early versions of FreeBSD and possibly contemporary NetBSD.) + For shared mappings, we should conversely verify that changes get + propagated back to all the places they're supposed to be. + + Grep wants private fixed already mapped. + The main things grep needs to know about mmap are: + * does it exist and is it safe to write into the mmap'd area + * how to use it (BSD variants) */ + +#include +#include + +#if !defined STDC_HEADERS && !defined HAVE_STDLIB_H +char *malloc (); +#endif + +/* This mess was copied from the GNU getpagesize.h. */ +#ifndef HAVE_GETPAGESIZE +/* Assume that all systems that can run configure have sys/param.h. */ +# ifndef HAVE_SYS_PARAM_H +# define HAVE_SYS_PARAM_H 1 +# endif + +# ifdef _SC_PAGESIZE +# define getpagesize() sysconf(_SC_PAGESIZE) +# else /* no _SC_PAGESIZE */ +# ifdef HAVE_SYS_PARAM_H +# include +# ifdef EXEC_PAGESIZE +# define getpagesize() EXEC_PAGESIZE +# else /* no EXEC_PAGESIZE */ +# ifdef NBPG +# define getpagesize() NBPG * CLSIZE +# ifndef CLSIZE +# define CLSIZE 1 +# endif /* no CLSIZE */ +# else /* no NBPG */ +# ifdef NBPC +# define getpagesize() NBPC +# else /* no NBPC */ +# ifdef PAGESIZE +# define getpagesize() PAGESIZE +# endif /* PAGESIZE */ +# endif /* no NBPC */ +# endif /* no NBPG */ +# endif /* no EXEC_PAGESIZE */ +# else /* no HAVE_SYS_PARAM_H */ +# define getpagesize() 8192 /* punt totally */ +# endif /* no HAVE_SYS_PARAM_H */ +# endif /* no _SC_PAGESIZE */ + +#endif /* no HAVE_GETPAGESIZE */ + +int +main () +{ + char *data, *data2, *data3; + int i, pagesize; + int fd; + + pagesize = getpagesize (); + + /* First, make a file with some known garbage in it. */ + data = (char *) malloc (pagesize); + if (!data) + return 1; + for (i = 0; i < pagesize; ++i) + *(data + i) = rand (); + umask (0); + fd = creat ("conftest.mmap", 0600); + if (fd < 0) + return 1; + if (write (fd, data, pagesize) != pagesize) + return 1; + close (fd); + + /* Next, try to mmap the file at a fixed address which already has + something else allocated at it. If we can, also make sure that + we see the same garbage. */ + fd = open ("conftest.mmap", O_RDWR); + if (fd < 0) + return 1; + data2 = (char *) malloc (2 * pagesize); + if (!data2) + return 1; + data2 += (pagesize - ((long int) data2 & (pagesize - 1))) & (pagesize - 1); + if (data2 != mmap (data2, pagesize, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_FIXED, fd, 0L)) + return 1; + for (i = 0; i < pagesize; ++i) + if (*(data + i) != *(data2 + i)) + return 1; + + /* Finally, make sure that changes to the mapped area do not + percolate back to the file as seen by read(). (This is a bug on + some variants of i386 svr4.0.) */ + for (i = 0; i < pagesize; ++i) + *(data2 + i) = *(data2 + i) + 1; + data3 = (char *) malloc (pagesize); + if (!data3) + return 1; + if (read (fd, data3, pagesize) != pagesize) + return 1; + for (i = 0; i < pagesize; ++i) + if (*(data + i) != *(data3 + i)) + return 1; + close (fd); + return 0; +} +_ACEOF +rm -f conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_func_mmap_fixed_mapped=yes +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +ac_cv_func_mmap_fixed_mapped=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi + + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_func_mmap_fixed_mapped" >&5 +echo "${ECHO_T}$ac_cv_func_mmap_fixed_mapped" >&6; } +if test $ac_cv_func_mmap_fixed_mapped = yes; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_MMAP 1 +_ACEOF + +fi +rm -f conftest.mmap + + + +for ac_header in sys/select.h sys/socket.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + { echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +else + # Is the header compilable? +{ echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_compiler=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6; } + +# Is the header present? +{ echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi + +rm -f conftest.err conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + + ;; +esac +{ echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + +{ echo "$as_me:$LINENO: checking types of arguments for select" >&5 +echo $ECHO_N "checking types of arguments for select... $ECHO_C" >&6; } +if test "${ac_cv_func_select_args+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + for ac_arg234 in 'fd_set *' 'int *' 'void *'; do + for ac_arg1 in 'int' 'size_t' 'unsigned long int' 'unsigned int'; do + for ac_arg5 in 'struct timeval *' 'const struct timeval *'; do + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#ifdef HAVE_SYS_SELECT_H +# include +#endif +#ifdef HAVE_SYS_SOCKET_H +# include +#endif + +int +main () +{ +extern int select ($ac_arg1, + $ac_arg234, $ac_arg234, $ac_arg234, + $ac_arg5); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_func_select_args="$ac_arg1,$ac_arg234,$ac_arg5"; break 3 +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + done + done +done +# Provide a safe default value. +: ${ac_cv_func_select_args='int,int *,struct timeval *'} + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_func_select_args" >&5 +echo "${ECHO_T}$ac_cv_func_select_args" >&6; } +ac_save_IFS=$IFS; IFS=',' +set dummy `echo "$ac_cv_func_select_args" | sed 's/\*/\*/g'` +IFS=$ac_save_IFS +shift + +cat >>confdefs.h <<_ACEOF +#define SELECT_TYPE_ARG1 $1 +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define SELECT_TYPE_ARG234 ($2) +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define SELECT_TYPE_ARG5 ($3) +_ACEOF + +rm -f conftest* + +{ echo "$as_me:$LINENO: checking whether setpgrp takes no argument" >&5 +echo $ECHO_N "checking whether setpgrp takes no argument... $ECHO_C" >&6; } +if test "${ac_cv_func_setpgrp_void+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "$cross_compiling" = yes; then + { { echo "$as_me:$LINENO: error: cannot check setpgrp when cross compiling" >&5 +echo "$as_me: error: cannot check setpgrp when cross compiling" >&2;} + { (exit 1); exit 1; }; } +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +/* If this system has a BSD-style setpgrp which takes arguments, + setpgrp(1, 1) will fail with ESRCH and return -1, in that case + exit successfully. */ + return setpgrp (1,1) != -1; + ; + return 0; +} +_ACEOF +rm -f conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_func_setpgrp_void=no +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +ac_cv_func_setpgrp_void=yes +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi + + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_func_setpgrp_void" >&5 +echo "${ECHO_T}$ac_cv_func_setpgrp_void" >&6; } +if test $ac_cv_func_setpgrp_void = yes; then + +cat >>confdefs.h <<\_ACEOF +#define SETPGRP_VOID 1 +_ACEOF + +fi + +{ echo "$as_me:$LINENO: checking return type of signal handlers" >&5 +echo $ECHO_N "checking return type of signal handlers... $ECHO_C" >&6; } +if test "${ac_cv_type_signal+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include + +int +main () +{ +return *(signal (0, 0)) (0) == 1; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_type_signal=int +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_type_signal=void +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_type_signal" >&5 +echo "${ECHO_T}$ac_cv_type_signal" >&6; } + +cat >>confdefs.h <<_ACEOF +#define RETSIGTYPE $ac_cv_type_signal +_ACEOF + + +# AC_FUNC_STAT +# remove pstat_getdynamic (at least for now) since we don't do +# anything conditional with the check anyway... + + + + + + + + + + + + + + + + + +for ac_func in alarm bzero gethostbyname gethrtime gettimeofday inet_ntoa memset memcpy munmap select socket sqrt strcasecmp strchr strstr strtoul uname +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +{ echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } +if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define $ac_func to an innocuous variant, in case declares $ac_func. + For example, HP-UX 11i declares gettimeofday. */ +#define $ac_func innocuous_$ac_func + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef $ac_func + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char $ac_func (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_$ac_func || defined __stub___$ac_func +choke me +#endif + +int +main () +{ +return $ac_func (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + eval "$as_ac_var=no" +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +fi +ac_res=`eval echo '${'$as_ac_var'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + + +#AC_CONFIG_SUBDIRS(src/missing) + +# does this platform need the replacement getaddrinfo + + + + +for ac_func in getnameinfo getaddrinfo inet_ntop getifaddrs +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +{ echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } +if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define $ac_func to an innocuous variant, in case declares $ac_func. + For example, HP-UX 11i declares gettimeofday. */ +#define $ac_func innocuous_$ac_func + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef $ac_func + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char $ac_func (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_$ac_func || defined __stub___$ac_func +choke me +#endif + +int +main () +{ +return $ac_func (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + eval "$as_ac_var=no" +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +fi +ac_res=`eval echo '${'$as_ac_var'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + +# AC_REPLACE_FUNCS([getaddrinfo]) + + +if test "$ac_cv_func_getaddrinfo$ac_cv_func_getnameinfo" != yesyes ; then + { echo "$as_me:$LINENO: Requesting replacement getaddrinfo/getnameinfo" >&5 +echo "$as_me: Requesting replacement getaddrinfo/getnameinfo" >&6;} + case " $LIBOBJS " in + *" getaddrinfo.$ac_objext "* ) ;; + *) LIBOBJS="$LIBOBJS getaddrinfo.$ac_objext" + ;; +esac + + HAVE_MISSING=yes +fi +if test "$ac_cv_func_inet_ntop" != yes ; then + { echo "$as_me:$LINENO: Requesting replacement inet_ntop" >&5 +echo "$as_me: Requesting replacement inet_ntop" >&6;} + case " $LIBOBJS " in + *" inet_ntop.$ac_objext "* ) ;; + *) LIBOBJS="$LIBOBJS inet_ntop.$ac_objext" + ;; +esac + + HAVE_MISSING=yes +fi + + +if test "$HAVE_MISSING" = "yes"; then + NEED_LIBCOMPAT_TRUE= + NEED_LIBCOMPAT_FALSE='#' +else + NEED_LIBCOMPAT_TRUE='#' + NEED_LIBCOMPAT_FALSE= +fi + + + +for ac_func in sendfile +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +{ echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } +if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define $ac_func to an innocuous variant, in case declares $ac_func. + For example, HP-UX 11i declares gettimeofday. */ +#define $ac_func innocuous_$ac_func + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef $ac_func + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char $ac_func (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_$ac_func || defined __stub___$ac_func +choke me +#endif + +int +main () +{ +return $ac_func (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + eval "$as_ac_var=no" +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +fi +ac_res=`eval echo '${'$as_ac_var'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + + + +for ac_func in uname +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +{ echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } +if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define $ac_func to an innocuous variant, in case declares $ac_func. + For example, HP-UX 11i declares gettimeofday. */ +#define $ac_func innocuous_$ac_func + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef $ac_func + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char $ac_func (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_$ac_func || defined __stub___$ac_func +choke me +#endif + +int +main () +{ +return $ac_func (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + eval "$as_ac_var=no" +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +fi +ac_res=`eval echo '${'$as_ac_var'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + + +# check for the various CPU binding calls + + + + + +for ac_func in mpctl processor_bind sched_setaffinity bind_to_cpu_id bindprocessor +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +{ echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } +if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define $ac_func to an innocuous variant, in case declares $ac_func. + For example, HP-UX 11i declares gettimeofday. */ +#define $ac_func innocuous_$ac_func + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef $ac_func + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char $ac_func (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_$ac_func || defined __stub___$ac_func +choke me +#endif + +int +main () +{ +return $ac_func (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + eval "$as_ac_var=no" +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +fi +ac_res=`eval echo '${'$as_ac_var'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + + +# see if we should be enabling histogram support + +{ echo "$as_me:$LINENO: checking whether to include histogram support" >&5 +echo $ECHO_N "checking whether to include histogram support... $ECHO_C" >&6; } + +# Check whether --enable-histogram was given. +if test "${enable_histogram+set}" = set; then + enableval=$enable_histogram; +fi + + +case "$enable_histogram" in + yes) + use_histogram=true + ;; + no) + use_histogram=false + ;; + '') + # whatever + use_histogram=false + ;; + *) + { { echo "$as_me:$LINENO: error: --enable-histogram takes yes or no" >&5 +echo "$as_me: error: --enable-histogram takes yes or no" >&2;} + { (exit 1); exit 1; }; } + ;; +esac + +if $use_histogram +then + { echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + +if $use_histogram +then + +cat >>confdefs.h <<\_ACEOF +#define WANT_HISTOGRAM +_ACEOF + +fi +# see if we should be enabling histogram support + +{ echo "$as_me:$LINENO: checking whether to include dirty support" >&5 +echo $ECHO_N "checking whether to include dirty support... $ECHO_C" >&6; } + +# Check whether --enable-dirty was given. +if test "${enable_dirty+set}" = set; then + enableval=$enable_dirty; +fi + + +case "$enable_dirty" in + yes) + use_dirty=true + ;; + no) + use_dirty=false + ;; + '') + # whatever + use_dirty=false + ;; + *) + { { echo "$as_me:$LINENO: error: --enable-dirty takes yes or no" >&5 +echo "$as_me: error: --enable-dirty takes yes or no" >&2;} + { (exit 1); exit 1; }; } + ;; +esac + +if $use_dirty +then + { echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + +if $use_dirty +then + +cat >>confdefs.h <<\_ACEOF +#define DIRTY +_ACEOF + +fi + +# see if we should be enabling demo support + +{ echo "$as_me:$LINENO: checking whether to include demo support" >&5 +echo $ECHO_N "checking whether to include demo support... $ECHO_C" >&6; } + +# Check whether --enable-demo was given. +if test "${enable_demo+set}" = set; then + enableval=$enable_demo; +fi + + +case "$enable_demo" in + yes) + use_demo=true + ;; + no) + use_demo=false + ;; + '') + # whatever + use_demo=false + ;; + *) + { { echo "$as_me:$LINENO: error: --enable-demo takes yes or no" >&5 +echo "$as_me: error: --enable-demo takes yes or no" >&2;} + { (exit 1); exit 1; }; } + ;; +esac + +if $use_demo +then + { echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + +if $use_demo +then + +cat >>confdefs.h <<\_ACEOF +#define WANT_DEMO +_ACEOF + +fi + +# see if we should be including the AF_UNIX tests + +{ echo "$as_me:$LINENO: checking whether to include Unix-domain socket tests" >&5 +echo $ECHO_N "checking whether to include Unix-domain socket tests... $ECHO_C" >&6; } + +# Check whether --enable-unixdomain was given. +if test "${enable_unixdomain+set}" = set; then + enableval=$enable_unixdomain; +fi + + +case "$enable_unixdomain" in + yes) + use_unixdomain=true + ;; + no) + use_unixdomain=false + ;; + '') + use_unixdomain=false + ;; + *) + { { echo "$as_me:$LINENO: error: --enable-unixdomain takes yes or no" >&5 +echo "$as_me: error: --enable-unixdomain takes yes or no" >&2;} + { (exit 1); exit 1; }; } + ;; +esac + +if $use_unixdomain +then + { echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + +if $use_unixdomain +then + +cat >>confdefs.h <<\_ACEOF +#define WANT_UNIX +_ACEOF + +fi + +# see if we should be including the DLPI tests + +{ echo "$as_me:$LINENO: checking whether to include DLPI tests" >&5 +echo $ECHO_N "checking whether to include DLPI tests... $ECHO_C" >&6; } + +# Check whether --enable-dlpi was given. +if test "${enable_dlpi+set}" = set; then + enableval=$enable_dlpi; +fi + + +case "$enable_dlpi" in + yes) + use_dlpi=true + ;; + no) + use_dlpi=false + ;; + '') + use_dlpi=false + ;; + *) + { { echo "$as_me:$LINENO: error: --enable-dlpi takes yes or no" >&5 +echo "$as_me: error: --enable-dlpi takes yes or no" >&2;} + { (exit 1); exit 1; }; } + ;; +esac + +if $use_dlpi +then + { echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + +if $use_dlpi +then + +cat >>confdefs.h <<\_ACEOF +#define WANT_DLPI +_ACEOF + +fi + +# see if we should be including the DCCP tests + +{ echo "$as_me:$LINENO: checking whether to include DCCP tests" >&5 +echo $ECHO_N "checking whether to include DCCP tests... $ECHO_C" >&6; } + +# Check whether --enable-dccp was given. +if test "${enable_dccp+set}" = set; then + enableval=$enable_dccp; +fi + + +case "$enable_dccp" in + yes) + use_dccp=true + ;; + no) + use_dccp=false + ;; + '') + use_dccp=false + ;; + *) + { { echo "$as_me:$LINENO: error: --enable-dccp takes yes or no" >&5 +echo "$as_me: error: --enable-dccp takes yes or no" >&2;} + { (exit 1); exit 1; }; } + ;; +esac + +if $use_dccp +then + { echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + +if $use_dccp +then + +cat >>confdefs.h <<\_ACEOF +#define WANT_DCCP +_ACEOF + +fi + +# see if we should be including the OMNI tests + +{ echo "$as_me:$LINENO: checking whether to include OMNI tests" >&5 +echo $ECHO_N "checking whether to include OMNI tests... $ECHO_C" >&6; } + +# Check whether --enable-omni was given. +if test "${enable_omni+set}" = set; then + enableval=$enable_omni; +fi + + +case "$enable_omni" in + yes) + use_omni=true + ;; + no) + use_omni=false + ;; + '') + use_omni=false + ;; + *) + { { echo "$as_me:$LINENO: error: --enable-omni takes yes or no" >&5 +echo "$as_me: error: --enable-omni takes yes or no" >&2;} + { (exit 1); exit 1; }; } + ;; +esac + +if $use_omni +then + { echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + +if $use_omni +then + +cat >>confdefs.h <<\_ACEOF +#define WANT_OMNI +_ACEOF + +fi + + +# see if we should be including the XTI tests + +{ echo "$as_me:$LINENO: checking whether to include XTI tests" >&5 +echo $ECHO_N "checking whether to include XTI tests... $ECHO_C" >&6; } + +# Check whether --enable-xti was given. +if test "${enable_xti+set}" = set; then + enableval=$enable_xti; +fi + + +case "$enable_xti" in + yes) + use_xti=true + ;; + no) + use_xti=false + ;; + '') + use_xti=false + ;; + *) + { { echo "$as_me:$LINENO: error: --enable-xti takes yes or no" >&5 +echo "$as_me: error: --enable-xti takes yes or no" >&2;} + { (exit 1); exit 1; }; } + ;; +esac + +if $use_xti +then + { echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + +if $use_xti +then + +cat >>confdefs.h <<\_ACEOF +#define WANT_XTI +_ACEOF + +fi + +# see if we should be including the SDP tests + +{ echo "$as_me:$LINENO: checking whether to include SDP tests" >&5 +echo $ECHO_N "checking whether to include SDP tests... $ECHO_C" >&6; } + +# Check whether --enable-sdp was given. +if test "${enable_sdp+set}" = set; then + enableval=$enable_sdp; +fi + + +case "$enable_sdp" in + yes) + # probably need to be a bit more sophisticated here + +{ echo "$as_me:$LINENO: checking for t_open in -lsdp" >&5 +echo $ECHO_N "checking for t_open in -lsdp... $ECHO_C" >&6; } +if test "${ac_cv_lib_sdp_t_open+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lsdp $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char t_open (); +int +main () +{ +return t_open (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + ac_cv_lib_sdp_t_open=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_lib_sdp_t_open=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ echo "$as_me:$LINENO: result: $ac_cv_lib_sdp_t_open" >&5 +echo "${ECHO_T}$ac_cv_lib_sdp_t_open" >&6; } +if test $ac_cv_lib_sdp_t_open = yes; then + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBSDP 1 +_ACEOF + + LIBS="-lsdp $LIBS" + +fi + + use_sdp=true + ;; + no) + use_sdp=false + ;; + '') + use_sdp=false + ;; + *) + { { echo "$as_me:$LINENO: error: --enable-sdp takes yes or no" >&5 +echo "$as_me: error: --enable-sdp takes yes or no" >&2;} + { (exit 1); exit 1; }; } + ;; +esac + +if $use_sdp +then + { echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + +if $use_sdp +then + +cat >>confdefs.h <<\_ACEOF +#define WANT_SDP +_ACEOF + +fi + +# see if we should be including the ICSC-EXS tests + +{ echo "$as_me:$LINENO: checking whether to include ICSC-EXS tests" >&5 +echo $ECHO_N "checking whether to include ICSC-EXS tests... $ECHO_C" >&6; } + +# Check whether --enable-exs was given. +if test "${enable_exs+set}" = set; then + enableval=$enable_exs; +fi + + +case "$enable_exs" in + yes) + use_exs=true + if test "${ac_cv_header_sys_exs_h+set}" = set; then + { echo "$as_me:$LINENO: checking for sys/exs.h" >&5 +echo $ECHO_N "checking for sys/exs.h... $ECHO_C" >&6; } +if test "${ac_cv_header_sys_exs_h+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +{ echo "$as_me:$LINENO: result: $ac_cv_header_sys_exs_h" >&5 +echo "${ECHO_T}$ac_cv_header_sys_exs_h" >&6; } +else + # Is the header compilable? +{ echo "$as_me:$LINENO: checking sys/exs.h usability" >&5 +echo $ECHO_N "checking sys/exs.h usability... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_compiler=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6; } + +# Is the header present? +{ echo "$as_me:$LINENO: checking sys/exs.h presence" >&5 +echo $ECHO_N "checking sys/exs.h presence... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi + +rm -f conftest.err conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: sys/exs.h: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: sys/exs.h: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: sys/exs.h: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: sys/exs.h: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: sys/exs.h: present but cannot be compiled" >&5 +echo "$as_me: WARNING: sys/exs.h: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: sys/exs.h: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: sys/exs.h: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: sys/exs.h: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: sys/exs.h: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: sys/exs.h: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: sys/exs.h: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: sys/exs.h: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: sys/exs.h: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: sys/exs.h: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: sys/exs.h: in the future, the compiler will take precedence" >&2;} + + ;; +esac +{ echo "$as_me:$LINENO: checking for sys/exs.h" >&5 +echo $ECHO_N "checking for sys/exs.h... $ECHO_C" >&6; } +if test "${ac_cv_header_sys_exs_h+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_header_sys_exs_h=$ac_header_preproc +fi +{ echo "$as_me:$LINENO: result: $ac_cv_header_sys_exs_h" >&5 +echo "${ECHO_T}$ac_cv_header_sys_exs_h" >&6; } + +fi +if test $ac_cv_header_sys_exs_h = yes; then + : +else + use_exs=false +fi + + + +{ echo "$as_me:$LINENO: checking for exs_init in -lexs" >&5 +echo $ECHO_N "checking for exs_init in -lexs... $ECHO_C" >&6; } +if test "${ac_cv_lib_exs_exs_init+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lexs $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char exs_init (); +int +main () +{ +return exs_init (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + ac_cv_lib_exs_exs_init=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_lib_exs_exs_init=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ echo "$as_me:$LINENO: result: $ac_cv_lib_exs_exs_init" >&5 +echo "${ECHO_T}$ac_cv_lib_exs_exs_init" >&6; } +if test $ac_cv_lib_exs_exs_init = yes; then + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBEXS 1 +_ACEOF + + LIBS="-lexs $LIBS" + +else + use_exs=false +fi + + ;; + no) + use_exs=false + ;; + '') + use_exs=false + ;; + *) + { { echo "$as_me:$LINENO: error: --enable-exs takes yes or no" >&5 +echo "$as_me: error: --enable-exs takes yes or no" >&2;} + { (exit 1); exit 1; }; } + ;; +esac + +if $use_exs +then + { echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + +if $use_exs +then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_ICSC_EXS +_ACEOF + +fi + +# see if we should be enabling SCTP support + + +# Check whether --enable-sctp was given. +if test "${enable_sctp+set}" = set; then + enableval=$enable_sctp; +fi + + +case "$enable_sctp" in + yes) + use_sctp=true + +for ac_header in netinet/sctp.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +{ echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +#include + + +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + eval "$as_ac_Header=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + eval "$as_ac_Header=no" +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +else + use_sctp=false +fi + +done + + case "$host" in + *-*-freebsd7.*) + # FreeBSD 7.x SCTP support doesn't need -lsctp. + ;; + *) + +{ echo "$as_me:$LINENO: checking for main in -lsctp" >&5 +echo $ECHO_N "checking for main in -lsctp... $ECHO_C" >&6; } +if test "${ac_cv_lib_sctp_main+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lsctp $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + + +int +main () +{ +return main (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + ac_cv_lib_sctp_main=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_lib_sctp_main=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ echo "$as_me:$LINENO: result: $ac_cv_lib_sctp_main" >&5 +echo "${ECHO_T}$ac_cv_lib_sctp_main" >&6; } +if test $ac_cv_lib_sctp_main = yes; then + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBSCTP 1 +_ACEOF + + LIBS="-lsctp $LIBS" + +else + use_sctp=false +fi +ac_cv_lib_sctp=ac_cv_lib_sctp_main + + ;; + esac + { echo "$as_me:$LINENO: checking for struct sctp_event_subscribe.sctp_adaptation_layer_event" >&5 +echo $ECHO_N "checking for struct sctp_event_subscribe.sctp_adaptation_layer_event... $ECHO_C" >&6; } +if test "${ac_cv_member_struct_sctp_event_subscribe_sctp_adaptation_layer_event+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include + +int +main () +{ +static struct sctp_event_subscribe ac_aggr; +if (ac_aggr.sctp_adaptation_layer_event) +return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_member_struct_sctp_event_subscribe_sctp_adaptation_layer_event=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include + +int +main () +{ +static struct sctp_event_subscribe ac_aggr; +if (sizeof ac_aggr.sctp_adaptation_layer_event) +return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_member_struct_sctp_event_subscribe_sctp_adaptation_layer_event=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_member_struct_sctp_event_subscribe_sctp_adaptation_layer_event=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_member_struct_sctp_event_subscribe_sctp_adaptation_layer_event" >&5 +echo "${ECHO_T}$ac_cv_member_struct_sctp_event_subscribe_sctp_adaptation_layer_event" >&6; } + + if test "$ac_cv_member_struct_sctp_event_subscribe_sctp_adaptation_layer_event" = "yes"; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_SCTP_ADAPTATION_LAYER_EVENT 1 +_ACEOF + + fi + ;; + no) + use_sctp=false + ;; + '') + # whatever + use_sctp=false + ;; + *) + { { echo "$as_me:$LINENO: error: --enable-sctp takes yes or no" >&5 +echo "$as_me: error: --enable-sctp takes yes or no" >&2;} + { (exit 1); exit 1; }; } + ;; +esac + +{ echo "$as_me:$LINENO: checking whether to include SCTP tests" >&5 +echo $ECHO_N "checking whether to include SCTP tests... $ECHO_C" >&6; } + +if $use_sctp +then + { echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + +if $use_sctp +then + +cat >>confdefs.h <<\_ACEOF +#define WANT_SCTP +_ACEOF + +fi + +# see if we should be enabling paced sends + +{ echo "$as_me:$LINENO: checking whether to include paced send (intervals) support" >&5 +echo $ECHO_N "checking whether to include paced send (intervals) support... $ECHO_C" >&6; } + +# Check whether --enable-intervals was given. +if test "${enable_intervals+set}" = set; then + enableval=$enable_intervals; +fi + + +case "$enable_intervals" in + yes) + use_intervals=true + ;; + no) + use_intervals=false + ;; + '') + use_intervals=false + ;; + *) + { { echo "$as_me:$LINENO: error: --enable-intervals takes yes or no" >&5 +echo "$as_me: error: --enable-intervals takes yes or no" >&2;} + { (exit 1); exit 1; }; } + ;; +esac + +if $use_intervals +then + { echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + +if $use_intervals +then + +cat >>confdefs.h <<\_ACEOF +#define WANT_INTERVALS +_ACEOF + +fi + +# see if paced sends should wait and spin + +{ echo "$as_me:$LINENO: checking whether paced sends should spin" >&5 +echo $ECHO_N "checking whether paced sends should spin... $ECHO_C" >&6; } + +# Check whether --enable-spin was given. +if test "${enable_spin+set}" = set; then + enableval=$enable_spin; +fi + + +case "$enable_spin" in + yes) + use_spin=true + ;; + no) + use_spin=false + ;; + '') + use_spin=false + ;; + *) + { { echo "$as_me:$LINENO: error: --enable-spin takes yes or no" >&5 +echo "$as_me: error: --enable-spin takes yes or no" >&2;} + { (exit 1); exit 1; }; } + ;; +esac + +if $use_spin +then + { echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + +if $use_spin +then + +cat >>confdefs.h <<\_ACEOF +#define WANT_INTERVALS +_ACEOF + + +cat >>confdefs.h <<\_ACEOF +#define WANT_SPIN +_ACEOF + +fi + +# see if we should be enabling initial request bursts + +{ echo "$as_me:$LINENO: checking whether to include initial burst support in _RR tests" >&5 +echo $ECHO_N "checking whether to include initial burst support in _RR tests... $ECHO_C" >&6; } + +# Check whether --enable-burst was given. +if test "${enable_burst+set}" = set; then + enableval=$enable_burst; +fi + + +case "$enable_burst" in + yes) + use_burst=true + ;; + no) + use_burst=false + ;; + '') + use_burst=false + ;; + *) + { { echo "$as_me:$LINENO: error: --enable-burst takes yes or no" >&5 +echo "$as_me: error: --enable-burst takes yes or no" >&2;} + { (exit 1); exit 1; }; } + ;; +esac + +if $use_burst +then + { echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + +if $use_burst +then + +cat >>confdefs.h <<\_ACEOF +#define WANT_FIRST_BURST +_ACEOF + +fi + +# time to see about CPU utilization measurements + +{ echo "$as_me:$LINENO: checking which CPU utilization measurement type to use" >&5 +echo $ECHO_N "checking which CPU utilization measurement type to use... $ECHO_C" >&6; } + +# Check whether --enable-cpuutil was given. +if test "${enable_cpuutil+set}" = set; then + enableval=$enable_cpuutil; +fi + + +NETCPU_SOURCE="$enable_cpuutil" +case "$enable_cpuutil" in + pstat) + use_cpuutil=true + +cat >>confdefs.h <<\_ACEOF +#define USE_PSTAT +_ACEOF + + ;; + pstatnew) + use_cpuutil=true + +cat >>confdefs.h <<\_ACEOF +#define USE_PSTAT +_ACEOF + + ;; + perfstat) + use_cpuutil=true + +cat >>confdefs.h <<\_ACEOF +#define USE_PERFSTAT +_ACEOF + + +{ echo "$as_me:$LINENO: checking for main in -lperfstat" >&5 +echo $ECHO_N "checking for main in -lperfstat... $ECHO_C" >&6; } +if test "${ac_cv_lib_perfstat_main+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lperfstat $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + + +int +main () +{ +return main (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + ac_cv_lib_perfstat_main=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_lib_perfstat_main=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ echo "$as_me:$LINENO: result: $ac_cv_lib_perfstat_main" >&5 +echo "${ECHO_T}$ac_cv_lib_perfstat_main" >&6; } +if test $ac_cv_lib_perfstat_main = yes; then + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBPERFSTAT 1 +_ACEOF + + LIBS="-lperfstat $LIBS" + +fi +ac_cv_lib_perfstat=ac_cv_lib_perfstat_main + + ;; + + looper) + use_cpuutil=true + +cat >>confdefs.h <<\_ACEOF +#define USE_LOOPER +_ACEOF + + ;; + procstat) + use_cpuutil=true + +cat >>confdefs.h <<\_ACEOF +#define USE_PROC_STAT +_ACEOF + + ;; + kstat) + use_cpuutil=true + +cat >>confdefs.h <<\_ACEOF +#define USE_KSTAT +_ACEOF + + +{ echo "$as_me:$LINENO: checking for main in -lkstat" >&5 +echo $ECHO_N "checking for main in -lkstat... $ECHO_C" >&6; } +if test "${ac_cv_lib_kstat_main+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lkstat $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + + +int +main () +{ +return main (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + ac_cv_lib_kstat_main=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_lib_kstat_main=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ echo "$as_me:$LINENO: result: $ac_cv_lib_kstat_main" >&5 +echo "${ECHO_T}$ac_cv_lib_kstat_main" >&6; } +if test $ac_cv_lib_kstat_main = yes; then + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBKSTAT 1 +_ACEOF + + LIBS="-lkstat $LIBS" + +fi +ac_cv_lib_kstat=ac_cv_lib_kstat_main + + ;; + kstat10) + use_cpuutil=true + +cat >>confdefs.h <<\_ACEOF +#define USE_KSTAT +_ACEOF + + +{ echo "$as_me:$LINENO: checking for main in -lkstat" >&5 +echo $ECHO_N "checking for main in -lkstat... $ECHO_C" >&6; } +if test "${ac_cv_lib_kstat_main+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lkstat $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + + +int +main () +{ +return main (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + ac_cv_lib_kstat_main=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_lib_kstat_main=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ echo "$as_me:$LINENO: result: $ac_cv_lib_kstat_main" >&5 +echo "${ECHO_T}$ac_cv_lib_kstat_main" >&6; } +if test $ac_cv_lib_kstat_main = yes; then + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBKSTAT 1 +_ACEOF + + LIBS="-lkstat $LIBS" + +fi +ac_cv_lib_kstat=ac_cv_lib_kstat_main + + ;; + osx) + use_cpuutil=true + +cat >>confdefs.h <<\_ACEOF +#define USE_OSX +_ACEOF + + ;; + '') +# ia64-hp-hpux11.23 +# i386-pc-solaris2.10 +# guess it automagically in a nice big case statement + case $target in + *-*-linux*) + use_cpuutil=true + +cat >>confdefs.h <<\_ACEOF +#define USE_PROC_STAT +_ACEOF + + enable_cpuutil="procstat - auto" + NETCPU_SOURCE="procstat" + ;; + *-*-hpux11.23 | *-*-hpux11.31) + use_cpuutil=true + +cat >>confdefs.h <<\_ACEOF +#define USE_PSTAT +_ACEOF + + enable_cpuutil="pstatnew - auto" + NETCPU_SOURCE="pstatnew" + ;; + *-*-hpux11* | *-*-hpux10*) + use_cpuutil=true + +cat >>confdefs.h <<\_ACEOF +#define USE_PSTAT +_ACEOF + + enable_cpuutil="pstat - auto" + NETCPU_SOURCE="pstat" + ;; + *-*-aix5.*) + use_puutil=true + +cat >>confdefs.h <<\_ACEOF +#define USE_PERFSTAT +_ACEOF + + +{ echo "$as_me:$LINENO: checking for main in -lperfstat" >&5 +echo $ECHO_N "checking for main in -lperfstat... $ECHO_C" >&6; } +if test "${ac_cv_lib_perfstat_main+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lperfstat $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + + +int +main () +{ +return main (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + ac_cv_lib_perfstat_main=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_lib_perfstat_main=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ echo "$as_me:$LINENO: result: $ac_cv_lib_perfstat_main" >&5 +echo "${ECHO_T}$ac_cv_lib_perfstat_main" >&6; } +if test $ac_cv_lib_perfstat_main = yes; then + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBPERFSTAT 1 +_ACEOF + + LIBS="-lperfstat $LIBS" + +fi +ac_cv_lib_perfstat=ac_cv_lib_perfstat_main + + enable_cpuutil="perfstat - auto" + NETCPU_SOURCE="perfstat" + ;; + *-*-solaris2.1*) + use_cpuutil=true + +cat >>confdefs.h <<\_ACEOF +#define USE_KSTAT +_ACEOF + + +{ echo "$as_me:$LINENO: checking for main in -lkstat" >&5 +echo $ECHO_N "checking for main in -lkstat... $ECHO_C" >&6; } +if test "${ac_cv_lib_kstat_main+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lkstat $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + + +int +main () +{ +return main (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + ac_cv_lib_kstat_main=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_lib_kstat_main=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ echo "$as_me:$LINENO: result: $ac_cv_lib_kstat_main" >&5 +echo "${ECHO_T}$ac_cv_lib_kstat_main" >&6; } +if test $ac_cv_lib_kstat_main = yes; then + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBKSTAT 1 +_ACEOF + + LIBS="-lkstat $LIBS" + +fi +ac_cv_lib_kstat=ac_cv_lib_kstat_main + + enable_cpuutil="kstat10 - auto" + NETCPU_SOURCE="kstat10" + ;; + *-*-solaris2.*) + use_cpuutil=true + +cat >>confdefs.h <<\_ACEOF +#define USE_KSTAT +_ACEOF + + +{ echo "$as_me:$LINENO: checking for main in -lkstat" >&5 +echo $ECHO_N "checking for main in -lkstat... $ECHO_C" >&6; } +if test "${ac_cv_lib_kstat_main+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lkstat $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + + +int +main () +{ +return main (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + ac_cv_lib_kstat_main=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_lib_kstat_main=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ echo "$as_me:$LINENO: result: $ac_cv_lib_kstat_main" >&5 +echo "${ECHO_T}$ac_cv_lib_kstat_main" >&6; } +if test $ac_cv_lib_kstat_main = yes; then + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBKSTAT 1 +_ACEOF + + LIBS="-lkstat $LIBS" + +fi +ac_cv_lib_kstat=ac_cv_lib_kstat_main + + enable_cpuutil="kstat - auto" + NETCPU_SOURCE="kstat" + ;; + *-*-freebsd[4-7].* | *-*-netbsd[1-9].* ) + use_cpuutil=true + +cat >>confdefs.h <<\_ACEOF +#define USE_SYSCTL +_ACEOF + + enable_cpuutil="sysctl - auto" + NETCPU_SOURCE="sysctl" + ;; + *-*-darwin*) + use_cpuutil=true + +cat >>confdefs.h <<\_ACEOF +#define USE_OSX +_ACEOF + + enable_cpuutil="osx - auto" + NETCPU_SOURCE="osx" + ;; + *) + use_cpuutil=false + NETCPU_SOURCE="none" + enable_cpuutil="none. Consider teaching configure about your platform." + ;; + esac + ;; + none) + use_cpuutil=false + ;; + *) + { { echo "$as_me:$LINENO: error: --enable-cpuutil takes kstat, kstat10, looper, osx, perfstat, procstat, pstat, pstatnew, sysctl or none" >&5 +echo "$as_me: error: --enable-cpuutil takes kstat, kstat10, looper, osx, perfstat, procstat, pstat, pstatnew, sysctl or none" >&2;} + { (exit 1); exit 1; }; } + ;; +esac + + { echo "$as_me:$LINENO: result: \"$enable_cpuutil\"" >&5 +echo "${ECHO_T}\"$enable_cpuutil\"" >&6; } + + + +# time to see about route lookup mechanisms + +{ echo "$as_me:$LINENO: checking which route lookup type to use" >&5 +echo $ECHO_N "checking which route lookup type to use... $ECHO_C" >&6; } + +# Check whether --enable-rtlookup was given. +if test "${enable_rtlookup+set}" = set; then + enableval=$enable_rtlookup; +fi + + +NETRTLKUP_SOURCE="$enable_rtlookup" +case "$enable_rtlookup" in + rtmget) + use_rtlookup=true + ;; + + rtnetlink) + use_rtlookup=true + ;; + '') +# guess it automagically in a nice big case statement + case $target in + *-*-linux*) + use_rtlookup=true + enable_rtlookup="rtnetlink - auto" + NETRTLKUP_SOURCE="rtnetlink" + ;; + *-*-hpux11.31 | *-*-solaris* | *-*-aix5*) + use_rtlookup=true + enable_rtlookup="rtmget - auto" + NETRTLKUP_SOURCE="rtmget" + ;; + *-*-freebsd[4-7].* | *-*-darwin*) + use_rtlookup=true + enable_rtlookup="rtmget - auto" + NETRTLKUP_SOURCE="rtmget" + ;; + *) + use_rtlookup=false + NETRTLKUP_SOURCE="none" + enable_rtlookup="none. Consider teaching configure about your platform." + ;; + esac + ;; + none) + use_rtlookup=false + ;; + *) + { { echo "$as_me:$LINENO: error: --enable-rtlookup takes rtmget, rtnetlink or none" >&5 +echo "$as_me: error: --enable-rtlookup takes rtmget, rtnetlink or none" >&2;} + { (exit 1); exit 1; }; } + ;; +esac + + { echo "$as_me:$LINENO: result: \"$enable_rtlookup\"" >&5 +echo "${ECHO_T}\"$enable_rtlookup\"" >&6; } + + + +# time to see about slot lookup mechanisms + +{ echo "$as_me:$LINENO: checking which slot lookup type to use" >&5 +echo $ECHO_N "checking which slot lookup type to use... $ECHO_C" >&6; } + +# Check whether --enable-slotlookup was given. +if test "${enable_slotlookup+set}" = set; then + enableval=$enable_slotlookup; +fi + + +NETSLOTLKUP_SOURCE="$enable_slotlookup" +case "$enable_slotlookup" in + + linux) + use_slotlookup=true + ;; + solaris) + use_slotlookup=true + ;; + '') +# guess it automagically in a nice big case statement + case $target in + *-*-linux*) + use_slotlookup=true + enable_slotlookup="linux - auto" + NETSLOTLKUP_SOURCE="linux" + ;; + *-*-solaris*) + use_slotlookup=true + enable_slotlookup="solaris - auto" + NETSLOTLKUP_SOURCE="solaris" + +{ echo "$as_me:$LINENO: checking for main in -ldevinfo" >&5 +echo $ECHO_N "checking for main in -ldevinfo... $ECHO_C" >&6; } +if test "${ac_cv_lib_devinfo_main+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldevinfo $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + + +int +main () +{ +return main (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + ac_cv_lib_devinfo_main=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_lib_devinfo_main=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ echo "$as_me:$LINENO: result: $ac_cv_lib_devinfo_main" >&5 +echo "${ECHO_T}$ac_cv_lib_devinfo_main" >&6; } +if test $ac_cv_lib_devinfo_main = yes; then + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBDEVINFO 1 +_ACEOF + + LIBS="-ldevinfo $LIBS" + +fi +ac_cv_lib_devinfo=ac_cv_lib_devinfo_main + + ;; + *) + use_slotlookup=false + NETSLOTLKUP_SOURCE="none" + enable_slotlookup="none. Consider teaching configure about your platform." + ;; + esac + ;; + none) + use_slotlookup=false + ;; + *) + { { echo "$as_me:$LINENO: error: --enable-slotlookup takes linux or none" >&5 +echo "$as_me: error: --enable-slotlookup takes linux or none" >&2;} + { (exit 1); exit 1; }; } + ;; +esac + + { echo "$as_me:$LINENO: result: \"$enable_slotlookup\"" >&5 +echo "${ECHO_T}\"$enable_slotlookup\"" >&6; } + + + + +# time to see about sec lookup mechanisms + +{ echo "$as_me:$LINENO: checking which sec lookup type to use" >&5 +echo $ECHO_N "checking which sec lookup type to use... $ECHO_C" >&6; } + +# Check whether --enable-seclookup was given. +if test "${enable_seclookup+set}" = set; then + enableval=$enable_seclookup; +fi + + +NETSECLKUP_SOURCE="$enable_seclookup" +case "$enable_seclookup" in + + linux) + use_seclookup=true + ;; + '') +# guess it automagically in a nice big case statement + case $target in + *-*-linux*) + +{ echo "$as_me:$LINENO: checking for main in -ldl" >&5 +echo $ECHO_N "checking for main in -ldl... $ECHO_C" >&6; } +if test "${ac_cv_lib_dl_main+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldl $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + + +int +main () +{ +return main (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + ac_cv_lib_dl_main=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_lib_dl_main=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ echo "$as_me:$LINENO: result: $ac_cv_lib_dl_main" >&5 +echo "${ECHO_T}$ac_cv_lib_dl_main" >&6; } +if test $ac_cv_lib_dl_main = yes; then + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBDL 1 +_ACEOF + + LIBS="-ldl $LIBS" + +fi +ac_cv_lib_dl=ac_cv_lib_dl_main + + use_seclookup=true + enable_seclookup="linux - auto" + NETSECLKUP_SOURCE="linux" + ;; + *) + use_seclookup=false + NETSECLKUP_SOURCE="none" + enable_seclookup="none. Consider teaching configure about your platform." + ;; + esac + ;; + none) + use_seclookup=false + ;; + *) + { { echo "$as_me:$LINENO: error: --enable-seclookup takes linux or none" >&5 +echo "$as_me: error: --enable-seclookup takes linux or none" >&2;} + { (exit 1); exit 1; }; } + ;; +esac + + { echo "$as_me:$LINENO: result: \"$enable_seclookup\"" >&5 +echo "${ECHO_T}\"$enable_seclookup\"" >&6; } + + + + +# time to see about driver lookup mechanisms + +{ echo "$as_me:$LINENO: checking which driver info lookup type to use" >&5 +echo $ECHO_N "checking which driver info lookup type to use... $ECHO_C" >&6; } + +# Check whether --enable-drvlookup was given. +if test "${enable_drvlookup+set}" = set; then + enableval=$enable_drvlookup; +fi + + +NETDRVLKUP_SOURCE="$enable_drvlookup" +case "$enable_drvlookup" in + ethtool) + use_drvlookup=true + ;; + + solaris) + use_drvlookup=true + ;; + '') +# guess it automagically in a nice big case statement + case $target in + *-*-linux*) + use_drvlookup=true + enable_drvlookup="ethtool - auto" + NETDRVLKUP_SOURCE="ethtool" + ;; + *-*-solaris*) + use_drvlookup=true + enable_drvlookup="solaris - auto" + NETDRVLKUP_SOURCE="solaris" + ;; + *) + use_drvlookup=false + NETDRVLKUP_SOURCE="none" + enable_drvlookup="none. Consider teaching configure about your platform." + ;; + esac + ;; + none) + use_drvlookup=false + ;; + *) + { { echo "$as_me:$LINENO: error: --enable-drvlookup takes ethtool or none" >&5 +echo "$as_me: error: --enable-drvlookup takes ethtool or none" >&2;} + { (exit 1); exit 1; }; } + ;; +esac + + { echo "$as_me:$LINENO: result: \"$enable_drvlookup\"" >&5 +echo "${ECHO_T}\"$enable_drvlookup\"" >&6; } + + + +# time to see about system lookup mechanisms + +{ echo "$as_me:$LINENO: checking which system info lookup type to use" >&5 +echo $ECHO_N "checking which system info lookup type to use... $ECHO_C" >&6; } + +# Check whether --enable-syslookup was given. +if test "${enable_syslookup+set}" = set; then + enableval=$enable_syslookup; +fi + + +NETSYSLKUP_SOURCE="$enable_syslookup" +case "$enable_syslookup" in + hpux11i) + use_syslookup=true + ;; + + linux) + use_syslookup=true; + +for ac_header in smbios/SystemInfo.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + { echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +else + # Is the header compilable? +{ echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_compiler=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6; } + +# Is the header present? +{ echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi + +rm -f conftest.err conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + + ;; +esac +{ echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + +{ echo "$as_me:$LINENO: checking for main in -lsmbios" >&5 +echo $ECHO_N "checking for main in -lsmbios... $ECHO_C" >&6; } +if test "${ac_cv_lib_smbios_main+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lsmbios $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + + +int +main () +{ +return main (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + ac_cv_lib_smbios_main=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_lib_smbios_main=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ echo "$as_me:$LINENO: result: $ac_cv_lib_smbios_main" >&5 +echo "${ECHO_T}$ac_cv_lib_smbios_main" >&6; } +if test $ac_cv_lib_smbios_main = yes; then + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBSMBIOS 1 +_ACEOF + + LIBS="-lsmbios $LIBS" + +fi +ac_cv_lib_smbios=ac_cv_lib_smbios_main + + ;; + solaris) + use_syslookup=true; + # this will basically tell us if we can use libsmbios + +for ac_header in sys/sbmios.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + { echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +else + # Is the header compilable? +{ echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_compiler=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6; } + +# Is the header present? +{ echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi + +rm -f conftest.err conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + + ;; +esac +{ echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + +{ echo "$as_me:$LINENO: checking for main in -lsmbios" >&5 +echo $ECHO_N "checking for main in -lsmbios... $ECHO_C" >&6; } +if test "${ac_cv_lib_smbios_main+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lsmbios $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + + +int +main () +{ +return main (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + ac_cv_lib_smbios_main=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_lib_smbios_main=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ echo "$as_me:$LINENO: result: $ac_cv_lib_smbios_main" >&5 +echo "${ECHO_T}$ac_cv_lib_smbios_main" >&6; } +if test $ac_cv_lib_smbios_main = yes; then + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBSMBIOS 1 +_ACEOF + + LIBS="-lsmbios $LIBS" + +fi +ac_cv_lib_smbios=ac_cv_lib_smbios_main + + ;; + '') +# guess it automagically in a nice big case statement + case $target in + *-*-hpux11*) + use_syslookup=true + enable_syslookup="hpux11i - auto" + NETSYSLKUP_SOURCE="hpux11i" + ;; + *-*-linux*) + use_syslookup=true + enable_syslookup="linux - auto" + +for ac_header in smbios/SystemInfo.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + { echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +else + # Is the header compilable? +{ echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_compiler=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6; } + +# Is the header present? +{ echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi + +rm -f conftest.err conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + + ;; +esac +{ echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + +{ echo "$as_me:$LINENO: checking for main in -lsmbios" >&5 +echo $ECHO_N "checking for main in -lsmbios... $ECHO_C" >&6; } +if test "${ac_cv_lib_smbios_main+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lsmbios $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + + +int +main () +{ +return main (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + ac_cv_lib_smbios_main=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_lib_smbios_main=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ echo "$as_me:$LINENO: result: $ac_cv_lib_smbios_main" >&5 +echo "${ECHO_T}$ac_cv_lib_smbios_main" >&6; } +if test $ac_cv_lib_smbios_main = yes; then + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBSMBIOS 1 +_ACEOF + + LIBS="-lsmbios $LIBS" + +fi +ac_cv_lib_smbios=ac_cv_lib_smbios_main + + NETSYSLKUP_SOURCE="linux" + ;; + *-*-solaris*) + use_syslookup=true + enable_syslookup="solaris - auto" + NETSYSLKUP_SOURCE="solaris" + +for ac_header in sys/smbios.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + { echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +else + # Is the header compilable? +{ echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_compiler=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6; } + +# Is the header present? +{ echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi + +rm -f conftest.err conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + + ;; +esac +{ echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + +{ echo "$as_me:$LINENO: checking for main in -lsmbios" >&5 +echo $ECHO_N "checking for main in -lsmbios... $ECHO_C" >&6; } +if test "${ac_cv_lib_smbios_main+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lsmbios $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + + +int +main () +{ +return main (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + ac_cv_lib_smbios_main=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_lib_smbios_main=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ echo "$as_me:$LINENO: result: $ac_cv_lib_smbios_main" >&5 +echo "${ECHO_T}$ac_cv_lib_smbios_main" >&6; } +if test $ac_cv_lib_smbios_main = yes; then + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBSMBIOS 1 +_ACEOF + + LIBS="-lsmbios $LIBS" + +fi +ac_cv_lib_smbios=ac_cv_lib_smbios_main + + ;; + *) + use_syslookup=false + NETSYSLKUP_SOURCE="none" + enable_syslookup="none. Consider teaching configure about your platform." + ;; + esac + ;; + none) + use_syslookup=false + ;; + *) + { { echo "$as_me:$LINENO: error: --enable-syslookup takes hpux11i, linux or none" >&5 +echo "$as_me: error: --enable-syslookup takes hpux11i, linux or none" >&2;} + { (exit 1); exit 1; }; } + ;; +esac + + { echo "$as_me:$LINENO: result: \"$enable_syslookup\"" >&5 +echo "${ECHO_T}\"$enable_syslookup\"" >&6; } + + + +# now spit it all out +ac_config_files="$ac_config_files Makefile src/netperf_version.h src/Makefile src/missing/Makefile src/missing/m4/Makefile doc/Makefile doc/examples/Makefile netperf.spec" + + +cat >confcache <<\_ACEOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs, see configure's option --config-cache. +# It is not useful on other systems. If it contains results you don't +# want to keep, you may remove or edit it. +# +# config.status only pays attention to the cache file if you give it +# the --recheck option to rerun configure. +# +# `ac_cv_env_foo' variables (set or unset) will be overridden when +# loading this file, other *unset* `ac_cv_foo' will be assigned the +# following values. + +_ACEOF + +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, we kill variables containing newlines. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +( + for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { echo "$as_me:$LINENO: WARNING: Cache variable $ac_var contains a newline." >&5 +echo "$as_me: WARNING: Cache variable $ac_var contains a newline." >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + *) $as_unset $ac_var ;; + esac ;; + esac + done + + (set) 2>&1 | + case $as_nl`(ac_space=' '; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + # `set' does not quote correctly, so add quotes (double-quote + # substitution turns \\\\ into \\, and sed turns \\ into \). + sed -n \ + "s/'/'\\\\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" + ;; #( + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) | + sed ' + /^ac_cv_env_/b end + t clear + :clear + s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ + t end + s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + :end' >>confcache +if diff "$cache_file" confcache >/dev/null 2>&1; then :; else + if test -w "$cache_file"; then + test "x$cache_file" != "x/dev/null" && + { echo "$as_me:$LINENO: updating cache $cache_file" >&5 +echo "$as_me: updating cache $cache_file" >&6;} + cat confcache >$cache_file + else + { echo "$as_me:$LINENO: not updating unwritable cache $cache_file" >&5 +echo "$as_me: not updating unwritable cache $cache_file" >&6;} + fi +fi +rm -f confcache + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +DEFS=-DHAVE_CONFIG_H + +ac_libobjs= +ac_ltlibobjs= +for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue + # 1. Remove the extension, and $U if already installed. + ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' + ac_i=`echo "$ac_i" | sed "$ac_script"` + # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR + # will be set to the directory where LIBOBJS objects are built. + ac_libobjs="$ac_libobjs \${LIBOBJDIR}$ac_i\$U.$ac_objext" + ac_ltlibobjs="$ac_ltlibobjs \${LIBOBJDIR}$ac_i"'$U.lo' +done +LIBOBJS=$ac_libobjs + +LTLIBOBJS=$ac_ltlibobjs + + +if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then + { { echo "$as_me:$LINENO: error: conditional \"AMDEP\" was never defined. +Usually this means the macro was only invoked conditionally." >&5 +echo "$as_me: error: conditional \"AMDEP\" was never defined. +Usually this means the macro was only invoked conditionally." >&2;} + { (exit 1); exit 1; }; } +fi +if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then + { { echo "$as_me:$LINENO: error: conditional \"am__fastdepCC\" was never defined. +Usually this means the macro was only invoked conditionally." >&5 +echo "$as_me: error: conditional \"am__fastdepCC\" was never defined. +Usually this means the macro was only invoked conditionally." >&2;} + { (exit 1); exit 1; }; } +fi +if test -z "${NEED_LIBCOMPAT_TRUE}" && test -z "${NEED_LIBCOMPAT_FALSE}"; then + { { echo "$as_me:$LINENO: error: conditional \"NEED_LIBCOMPAT\" was never defined. +Usually this means the macro was only invoked conditionally." >&5 +echo "$as_me: error: conditional \"NEED_LIBCOMPAT\" was never defined. +Usually this means the macro was only invoked conditionally." >&2;} + { (exit 1); exit 1; }; } +fi + +: ${CONFIG_STATUS=./config.status} +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files $CONFIG_STATUS" +{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5 +echo "$as_me: creating $CONFIG_STATUS" >&6;} +cat >$CONFIG_STATUS <<_ACEOF +#! $SHELL +# Generated by $as_me. +# Run this file to recreate the current configuration. +# Compiler output produced by configure, useful for debugging +# configure, is in config.log if it exists. + +debug=false +ac_cs_recheck=false +ac_cs_silent=false +SHELL=\${CONFIG_SHELL-$SHELL} +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF +## --------------------- ## +## M4sh Initialization. ## +## --------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in + *posix*) set -o posix ;; +esac + +fi + + + + +# PATH needs CR +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + echo "#! /bin/sh" >conf$$.sh + echo "exit 0" >>conf$$.sh + chmod +x conf$$.sh + if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then + PATH_SEPARATOR=';' + else + PATH_SEPARATOR=: + fi + rm -f conf$$.sh +fi + +# Support unset when possible. +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + as_unset=unset +else + as_unset=false +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +as_nl=' +' +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +case $0 in + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break +done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + { (exit 1); exit 1; } +fi + +# Work around bugs in pre-3.0 UWIN ksh. +for as_var in ENV MAIL MAILPATH +do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +for as_var in \ + LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ + LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ + LC_TELEPHONE LC_TIME +do + if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then + eval $as_var=C; export $as_var + else + ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var + fi +done + +# Required to use basename. +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + + +# Name of the executable. +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# CDPATH. +$as_unset CDPATH + + + + as_lineno_1=$LINENO + as_lineno_2=$LINENO + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || { + + # Create $as_me.lineno as a copy of $as_myself, but with $LINENO + # uniformly replaced by the line number. The first 'sed' inserts a + # line-number line after each line using $LINENO; the second 'sed' + # does the real work. The second script uses 'N' to pair each + # line-number line with the line containing $LINENO, and appends + # trailing '-' during substitution so that $LINENO is not a special + # case at line end. + # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the + # scripts with optimization help from Paolo Bonzini. Blame Lee + # E. McMahon (1931-1989) for sed's syntax. :-) + sed -n ' + p + /[$]LINENO/= + ' <$as_myself | + sed ' + s/[$]LINENO.*/&-/ + t lineno + b + :lineno + N + :loop + s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ + t loop + s/-\n.*// + ' >$as_me.lineno && + chmod +x "$as_me.lineno" || + { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 + { (exit 1); exit 1; }; } + + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensitive to this). + . "./$as_me.lineno" + # Exit status is that of the last command. + exit +} + + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in +-n*) + case `echo 'x\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + *) ECHO_C='\c';; + esac;; +*) + ECHO_N='-n';; +esac + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir +fi +echo >conf$$.file +if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -p'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -p' +elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + +if mkdir -p . 2>/dev/null; then + as_mkdir_p=: +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +if test -x / >/dev/null 2>&1; then + as_test_x='test -x' +else + if ls -dL / >/dev/null 2>&1; then + as_ls_L_option=L + else + as_ls_L_option= + fi + as_test_x=' + eval sh -c '\'' + if test -d "$1"; then + test -d "$1/."; + else + case $1 in + -*)set "./$1";; + esac; + case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in + ???[sx]*):;;*)false;;esac;fi + '\'' sh + ' +fi +as_executable_p=$as_test_x + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +exec 6>&1 + +# Save the log message, to keep $[0] and so on meaningful, and to +# report actual input values of CONFIG_FILES etc. instead of their +# values after options handling. +ac_log=" +This file was extended by netperf $as_me 2.4.5, which was +generated by GNU Autoconf 2.61. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + $ $0 $@ + +on `(hostname || uname -n) 2>/dev/null | sed 1q` +" + +_ACEOF + +cat >>$CONFIG_STATUS <<_ACEOF +# Files that config.status was made for. +config_files="$ac_config_files" +config_headers="$ac_config_headers" +config_commands="$ac_config_commands" + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF +ac_cs_usage="\ +\`$as_me' instantiates files from templates according to the +current configuration. + +Usage: $0 [OPTIONS] [FILE]... + + -h, --help print this help, then exit + -V, --version print version number and configuration settings, then exit + -q, --quiet do not print progress messages + -d, --debug don't remove temporary files + --recheck update $as_me by reconfiguring in the same conditions + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE + --header=FILE[:TEMPLATE] + instantiate the configuration header FILE + +Configuration files: +$config_files + +Configuration headers: +$config_headers + +Configuration commands: +$config_commands + +Report bugs to ." + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF +ac_cs_version="\\ +netperf config.status 2.4.5 +configured by $0, generated by GNU Autoconf 2.61, + with options \\"`echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\" + +Copyright (C) 2006 Free Software Foundation, Inc. +This config.status script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it." + +ac_pwd='$ac_pwd' +srcdir='$srcdir' +INSTALL='$INSTALL' +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF +# If no file are specified by the user, then we need to provide default +# value. By we need to know if files were specified by the user. +ac_need_defaults=: +while test $# != 0 +do + case $1 in + --*=*) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` + ac_shift=: + ;; + *) + ac_option=$1 + ac_optarg=$2 + ac_shift=shift + ;; + esac + + case $ac_option in + # Handling of the options. + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + ac_cs_recheck=: ;; + --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) + echo "$ac_cs_version"; exit ;; + --debug | --debu | --deb | --de | --d | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + $ac_shift + CONFIG_FILES="$CONFIG_FILES $ac_optarg" + ac_need_defaults=false;; + --header | --heade | --head | --hea ) + $ac_shift + CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg" + ac_need_defaults=false;; + --he | --h) + # Conflict between --help and --header + { echo "$as_me: error: ambiguous option: $1 +Try \`$0 --help' for more information." >&2 + { (exit 1); exit 1; }; };; + --help | --hel | -h ) + echo "$ac_cs_usage"; exit ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil | --si | --s) + ac_cs_silent=: ;; + + # This is an error. + -*) { echo "$as_me: error: unrecognized option: $1 +Try \`$0 --help' for more information." >&2 + { (exit 1); exit 1; }; } ;; + + *) ac_config_targets="$ac_config_targets $1" + ac_need_defaults=false ;; + + esac + shift +done + +ac_configure_extra_args= + +if $ac_cs_silent; then + exec 6>/dev/null + ac_configure_extra_args="$ac_configure_extra_args --silent" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF +if \$ac_cs_recheck; then + echo "running CONFIG_SHELL=$SHELL $SHELL $0 "$ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6 + CONFIG_SHELL=$SHELL + export CONFIG_SHELL + exec $SHELL "$0"$ac_configure_args \$ac_configure_extra_args --no-create --no-recursion +fi + +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX + echo "$ac_log" +} >&5 + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF +# +# INIT-COMMANDS +# +AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF + +# Handling of arguments. +for ac_config_target in $ac_config_targets +do + case $ac_config_target in + "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; + "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; + "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; + "src/netperf_version.h") CONFIG_FILES="$CONFIG_FILES src/netperf_version.h" ;; + "src/Makefile") CONFIG_FILES="$CONFIG_FILES src/Makefile" ;; + "src/missing/Makefile") CONFIG_FILES="$CONFIG_FILES src/missing/Makefile" ;; + "src/missing/m4/Makefile") CONFIG_FILES="$CONFIG_FILES src/missing/m4/Makefile" ;; + "doc/Makefile") CONFIG_FILES="$CONFIG_FILES doc/Makefile" ;; + "doc/examples/Makefile") CONFIG_FILES="$CONFIG_FILES doc/examples/Makefile" ;; + "netperf.spec") CONFIG_FILES="$CONFIG_FILES netperf.spec" ;; + + *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 +echo "$as_me: error: invalid argument: $ac_config_target" >&2;} + { (exit 1); exit 1; }; };; + esac +done + + +# If the user did not use the arguments to specify the items to instantiate, +# then the envvar interface is used. Set only those that are not. +# We use the long form for the default assignment because of an extremely +# bizarre bug on SunOS 4.1.3. +if $ac_need_defaults; then + test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files + test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers + test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands +fi + +# Have a temporary directory for convenience. Make it in the build tree +# simply because there is no reason against having it here, and in addition, +# creating and moving files from /tmp can sometimes cause problems. +# Hook for its removal unless debugging. +# Note that there is a small window in which the directory will not be cleaned: +# after its creation but before its name has been assigned to `$tmp'. +$debug || +{ + tmp= + trap 'exit_status=$? + { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status +' 0 + trap '{ (exit 1); exit 1; }' 1 2 13 15 +} +# Create a (secure) tmp directory for tmp files. + +{ + tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && + test -n "$tmp" && test -d "$tmp" +} || +{ + tmp=./conf$$-$RANDOM + (umask 077 && mkdir "$tmp") +} || +{ + echo "$me: cannot create a temporary directory in ." >&2 + { (exit 1); exit 1; } +} + +# +# Set up the sed scripts for CONFIG_FILES section. +# + +# No need to generate the scripts if there are no CONFIG_FILES. +# This happens for instance when ./config.status config.h +if test -n "$CONFIG_FILES"; then + +_ACEOF + + + +ac_delim='%!_!# ' +for ac_last_try in false false false false false :; do + cat >conf$$subs.sed <<_ACEOF +SHELL!$SHELL$ac_delim +PATH_SEPARATOR!$PATH_SEPARATOR$ac_delim +PACKAGE_NAME!$PACKAGE_NAME$ac_delim +PACKAGE_TARNAME!$PACKAGE_TARNAME$ac_delim +PACKAGE_VERSION!$PACKAGE_VERSION$ac_delim +PACKAGE_STRING!$PACKAGE_STRING$ac_delim +PACKAGE_BUGREPORT!$PACKAGE_BUGREPORT$ac_delim +exec_prefix!$exec_prefix$ac_delim +prefix!$prefix$ac_delim +program_transform_name!$program_transform_name$ac_delim +bindir!$bindir$ac_delim +sbindir!$sbindir$ac_delim +libexecdir!$libexecdir$ac_delim +datarootdir!$datarootdir$ac_delim +datadir!$datadir$ac_delim +sysconfdir!$sysconfdir$ac_delim +sharedstatedir!$sharedstatedir$ac_delim +localstatedir!$localstatedir$ac_delim +includedir!$includedir$ac_delim +oldincludedir!$oldincludedir$ac_delim +docdir!$docdir$ac_delim +infodir!$infodir$ac_delim +htmldir!$htmldir$ac_delim +dvidir!$dvidir$ac_delim +pdfdir!$pdfdir$ac_delim +psdir!$psdir$ac_delim +libdir!$libdir$ac_delim +localedir!$localedir$ac_delim +mandir!$mandir$ac_delim +DEFS!$DEFS$ac_delim +ECHO_C!$ECHO_C$ac_delim +ECHO_N!$ECHO_N$ac_delim +ECHO_T!$ECHO_T$ac_delim +LIBS!$LIBS$ac_delim +build_alias!$build_alias$ac_delim +host_alias!$host_alias$ac_delim +target_alias!$target_alias$ac_delim +build!$build$ac_delim +build_cpu!$build_cpu$ac_delim +build_vendor!$build_vendor$ac_delim +build_os!$build_os$ac_delim +host!$host$ac_delim +host_cpu!$host_cpu$ac_delim +host_vendor!$host_vendor$ac_delim +host_os!$host_os$ac_delim +target!$target$ac_delim +target_cpu!$target_cpu$ac_delim +target_vendor!$target_vendor$ac_delim +target_os!$target_os$ac_delim +INSTALL_PROGRAM!$INSTALL_PROGRAM$ac_delim +INSTALL_SCRIPT!$INSTALL_SCRIPT$ac_delim +INSTALL_DATA!$INSTALL_DATA$ac_delim +CYGPATH_W!$CYGPATH_W$ac_delim +PACKAGE!$PACKAGE$ac_delim +VERSION!$VERSION$ac_delim +ACLOCAL!$ACLOCAL$ac_delim +AUTOCONF!$AUTOCONF$ac_delim +AUTOMAKE!$AUTOMAKE$ac_delim +AUTOHEADER!$AUTOHEADER$ac_delim +MAKEINFO!$MAKEINFO$ac_delim +AMTAR!$AMTAR$ac_delim +install_sh!$install_sh$ac_delim +STRIP!$STRIP$ac_delim +INSTALL_STRIP_PROGRAM!$INSTALL_STRIP_PROGRAM$ac_delim +AWK!$AWK$ac_delim +SET_MAKE!$SET_MAKE$ac_delim +am__leading_dot!$am__leading_dot$ac_delim +CC!$CC$ac_delim +CFLAGS!$CFLAGS$ac_delim +LDFLAGS!$LDFLAGS$ac_delim +CPPFLAGS!$CPPFLAGS$ac_delim +ac_ct_CC!$ac_ct_CC$ac_delim +EXEEXT!$EXEEXT$ac_delim +OBJEXT!$OBJEXT$ac_delim +DEPDIR!$DEPDIR$ac_delim +am__include!$am__include$ac_delim +am__quote!$am__quote$ac_delim +AMDEP_TRUE!$AMDEP_TRUE$ac_delim +AMDEP_FALSE!$AMDEP_FALSE$ac_delim +AMDEPBACKSLASH!$AMDEPBACKSLASH$ac_delim +CCDEPMODE!$CCDEPMODE$ac_delim +am__fastdepCC_TRUE!$am__fastdepCC_TRUE$ac_delim +am__fastdepCC_FALSE!$am__fastdepCC_FALSE$ac_delim +RANLIB!$RANLIB$ac_delim +CPP!$CPP$ac_delim +GREP!$GREP$ac_delim +EGREP!$EGREP$ac_delim +LIBOBJS!$LIBOBJS$ac_delim +NEED_LIBCOMPAT_TRUE!$NEED_LIBCOMPAT_TRUE$ac_delim +NEED_LIBCOMPAT_FALSE!$NEED_LIBCOMPAT_FALSE$ac_delim +NETCPU_SOURCE!$NETCPU_SOURCE$ac_delim +NETRTLKUP_SOURCE!$NETRTLKUP_SOURCE$ac_delim +NETSLOTLKUP_SOURCE!$NETSLOTLKUP_SOURCE$ac_delim +NETSECLKUP_SOURCE!$NETSECLKUP_SOURCE$ac_delim +NETDRVLKUP_SOURCE!$NETDRVLKUP_SOURCE$ac_delim +NETSYSLKUP_SOURCE!$NETSYSLKUP_SOURCE$ac_delim +LTLIBOBJS!$LTLIBOBJS$ac_delim +_ACEOF + + if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 97; then + break + elif $ac_last_try; then + { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 +echo "$as_me: error: could not make $CONFIG_STATUS" >&2;} + { (exit 1); exit 1; }; } + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done + +ac_eof=`sed -n '/^CEOF[0-9]*$/s/CEOF/0/p' conf$$subs.sed` +if test -n "$ac_eof"; then + ac_eof=`echo "$ac_eof" | sort -nru | sed 1q` + ac_eof=`expr $ac_eof + 1` +fi + +cat >>$CONFIG_STATUS <<_ACEOF +cat >"\$tmp/subs-1.sed" <<\CEOF$ac_eof +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +_ACEOF +sed ' +s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g +s/^/s,@/; s/!/@,|#_!!_#|/ +:n +t n +s/'"$ac_delim"'$/,g/; t +s/$/\\/; p +N; s/^.*\n//; s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g; b n +' >>$CONFIG_STATUS >$CONFIG_STATUS <<_ACEOF +CEOF$ac_eof +_ACEOF + + +# VPATH may cause trouble with some makes, so we remove $(srcdir), +# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and +# trailing colons and then remove the whole line if VPATH becomes empty +# (actually we leave an empty line to preserve line numbers). +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=/{ +s/:*\$(srcdir):*/:/ +s/:*\${srcdir}:*/:/ +s/:*@srcdir@:*/:/ +s/^\([^=]*=[ ]*\):*/\1/ +s/:*$// +s/^[^=]*=[ ]*$// +}' +fi + +cat >>$CONFIG_STATUS <<\_ACEOF +fi # test -n "$CONFIG_FILES" + + +for ac_tag in :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS +do + case $ac_tag in + :[FHLC]) ac_mode=$ac_tag; continue;; + esac + case $ac_mode$ac_tag in + :[FHL]*:*);; + :L* | :C*:*) { { echo "$as_me:$LINENO: error: Invalid tag $ac_tag." >&5 +echo "$as_me: error: Invalid tag $ac_tag." >&2;} + { (exit 1); exit 1; }; };; + :[FH]-) ac_tag=-:-;; + :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; + esac + ac_save_IFS=$IFS + IFS=: + set x $ac_tag + IFS=$ac_save_IFS + shift + ac_file=$1 + shift + + case $ac_mode in + :L) ac_source=$1;; + :[FH]) + ac_file_inputs= + for ac_f + do + case $ac_f in + -) ac_f="$tmp/stdin";; + *) # Look for the file first in the build tree, then in the source tree + # (if the path is not absolute). The absolute path cannot be DOS-style, + # because $ac_f cannot contain `:'. + test -f "$ac_f" || + case $ac_f in + [\\/$]*) false;; + *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; + esac || + { { echo "$as_me:$LINENO: error: cannot find input file: $ac_f" >&5 +echo "$as_me: error: cannot find input file: $ac_f" >&2;} + { (exit 1); exit 1; }; };; + esac + ac_file_inputs="$ac_file_inputs $ac_f" + done + + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + configure_input="Generated from "`IFS=: + echo $* | sed 's|^[^:]*/||;s|:[^:]*/|, |g'`" by configure." + if test x"$ac_file" != x-; then + configure_input="$ac_file. $configure_input" + { echo "$as_me:$LINENO: creating $ac_file" >&5 +echo "$as_me: creating $ac_file" >&6;} + fi + + case $ac_tag in + *:-:* | *:-) cat >"$tmp/stdin";; + esac + ;; + esac + + ac_dir=`$as_dirname -- "$ac_file" || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || +echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + { as_dir="$ac_dir" + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || { $as_mkdir_p && mkdir -p "$as_dir"; } || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || { { echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5 +echo "$as_me: error: cannot create directory $as_dir" >&2;} + { (exit 1); exit 1; }; }; } + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,/..,g;s,/,,'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + + case $ac_mode in + :F) + # + # CONFIG_FILE + # + + case $INSTALL in + [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; + *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; + esac +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF +# If the template does not know about datarootdir, expand it. +# FIXME: This hack should be removed a few years after 2.60. +ac_datarootdir_hack=; ac_datarootdir_seen= + +case `sed -n '/datarootdir/ { + p + q +} +/@datadir@/p +/@docdir@/p +/@infodir@/p +/@localedir@/p +/@mandir@/p +' $ac_file_inputs` in +*datarootdir*) ac_datarootdir_seen=yes;; +*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) + { echo "$as_me:$LINENO: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 +echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF + ac_datarootdir_hack=' + s&@datadir@&$datadir&g + s&@docdir@&$docdir&g + s&@infodir@&$infodir&g + s&@localedir@&$localedir&g + s&@mandir@&$mandir&g + s&\\\${datarootdir}&$datarootdir&g' ;; +esac +_ACEOF + +# Neutralize VPATH when `$srcdir' = `.'. +# Shell code in configure.ac might set extrasub. +# FIXME: do we really want to maintain this feature? +cat >>$CONFIG_STATUS <<_ACEOF + sed "$ac_vpsub +$extrasub +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s&@configure_input@&$configure_input&;t t +s&@top_builddir@&$ac_top_builddir_sub&;t t +s&@srcdir@&$ac_srcdir&;t t +s&@abs_srcdir@&$ac_abs_srcdir&;t t +s&@top_srcdir@&$ac_top_srcdir&;t t +s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t +s&@builddir@&$ac_builddir&;t t +s&@abs_builddir@&$ac_abs_builddir&;t t +s&@abs_top_builddir@&$ac_abs_top_builddir&;t t +s&@INSTALL@&$ac_INSTALL&;t t +$ac_datarootdir_hack +" $ac_file_inputs | sed -f "$tmp/subs-1.sed" | sed 's/|#_!!_#|//g' >$tmp/out + +test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && + { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } && + { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } && + { echo "$as_me:$LINENO: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined." >&5 +echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined." >&2;} + + rm -f "$tmp/stdin" + case $ac_file in + -) cat "$tmp/out"; rm -f "$tmp/out";; + *) rm -f "$ac_file"; mv "$tmp/out" $ac_file;; + esac + ;; + :H) + # + # CONFIG_HEADER + # +_ACEOF + +# Transform confdefs.h into a sed script `conftest.defines', that +# substitutes the proper values into config.h.in to produce config.h. +rm -f conftest.defines conftest.tail +# First, append a space to every undef/define line, to ease matching. +echo 's/$/ /' >conftest.defines +# Then, protect against being on the right side of a sed subst, or in +# an unquoted here document, in config.status. If some macros were +# called several times there might be several #defines for the same +# symbol, which is useless. But do not sort them, since the last +# AC_DEFINE must be honored. +ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* +# These sed commands are passed to sed as "A NAME B PARAMS C VALUE D", where +# NAME is the cpp macro being defined, VALUE is the value it is being given. +# PARAMS is the parameter list in the macro definition--in most cases, it's +# just an empty string. +ac_dA='s,^\\([ #]*\\)[^ ]*\\([ ]*' +ac_dB='\\)[ (].*,\\1define\\2' +ac_dC=' ' +ac_dD=' ,' + +uniq confdefs.h | + sed -n ' + t rset + :rset + s/^[ ]*#[ ]*define[ ][ ]*// + t ok + d + :ok + s/[\\&,]/\\&/g + s/^\('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/ '"$ac_dA"'\1'"$ac_dB"'\2'"${ac_dC}"'\3'"$ac_dD"'/p + s/^\('"$ac_word_re"'\)[ ]*\(.*\)/'"$ac_dA"'\1'"$ac_dB$ac_dC"'\2'"$ac_dD"'/p + ' >>conftest.defines + +# Remove the space that was appended to ease matching. +# Then replace #undef with comments. This is necessary, for +# example, in the case of _POSIX_SOURCE, which is predefined and required +# on some systems where configure will not decide to define it. +# (The regexp can be short, since the line contains either #define or #undef.) +echo 's/ $// +s,^[ #]*u.*,/* & */,' >>conftest.defines + +# Break up conftest.defines: +ac_max_sed_lines=50 + +# First sed command is: sed -f defines.sed $ac_file_inputs >"$tmp/out1" +# Second one is: sed -f defines.sed "$tmp/out1" >"$tmp/out2" +# Third one will be: sed -f defines.sed "$tmp/out2" >"$tmp/out1" +# et cetera. +ac_in='$ac_file_inputs' +ac_out='"$tmp/out1"' +ac_nxt='"$tmp/out2"' + +while : +do + # Write a here document: + cat >>$CONFIG_STATUS <<_ACEOF + # First, check the format of the line: + cat >"\$tmp/defines.sed" <<\\CEOF +/^[ ]*#[ ]*undef[ ][ ]*$ac_word_re[ ]*\$/b def +/^[ ]*#[ ]*define[ ][ ]*$ac_word_re[( ]/b def +b +:def +_ACEOF + sed ${ac_max_sed_lines}q conftest.defines >>$CONFIG_STATUS + echo 'CEOF + sed -f "$tmp/defines.sed"' "$ac_in >$ac_out" >>$CONFIG_STATUS + ac_in=$ac_out; ac_out=$ac_nxt; ac_nxt=$ac_in + sed 1,${ac_max_sed_lines}d conftest.defines >conftest.tail + grep . conftest.tail >/dev/null || break + rm -f conftest.defines + mv conftest.tail conftest.defines +done +rm -f conftest.defines conftest.tail + +echo "ac_result=$ac_in" >>$CONFIG_STATUS +cat >>$CONFIG_STATUS <<\_ACEOF + if test x"$ac_file" != x-; then + echo "/* $configure_input */" >"$tmp/config.h" + cat "$ac_result" >>"$tmp/config.h" + if diff $ac_file "$tmp/config.h" >/dev/null 2>&1; then + { echo "$as_me:$LINENO: $ac_file is unchanged" >&5 +echo "$as_me: $ac_file is unchanged" >&6;} + else + rm -f $ac_file + mv "$tmp/config.h" $ac_file + fi + else + echo "/* $configure_input */" + cat "$ac_result" + fi + rm -f "$tmp/out12" +# Compute $ac_file's index in $config_headers. +_am_stamp_count=1 +for _am_header in $config_headers :; do + case $_am_header in + $ac_file | $ac_file:* ) + break ;; + * ) + _am_stamp_count=`expr $_am_stamp_count + 1` ;; + esac +done +echo "timestamp for $ac_file" >`$as_dirname -- $ac_file || +$as_expr X$ac_file : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X$ac_file : 'X\(//\)[^/]' \| \ + X$ac_file : 'X\(//\)$' \| \ + X$ac_file : 'X\(/\)' \| . 2>/dev/null || +echo X$ac_file | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'`/stamp-h$_am_stamp_count + ;; + + :C) { echo "$as_me:$LINENO: executing $ac_file commands" >&5 +echo "$as_me: executing $ac_file commands" >&6;} + ;; + esac + + + case $ac_file$ac_mode in + "depfiles":C) test x"$AMDEP_TRUE" != x"" || for mf in $CONFIG_FILES; do + # Strip MF so we end up with the name of the file. + mf=`echo "$mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile or not. + # We used to match only the files named `Makefile.in', but + # some people rename them; so instead we look at the file content. + # Grep'ing the first line is not enough: some people post-process + # each Makefile.in and add a new line on top of each file to say so. + # So let's grep whole file. + if grep '^#.*generated by automake' $mf > /dev/null 2>&1; then + dirpart=`$as_dirname -- "$mf" || +$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$mf" : 'X\(//\)[^/]' \| \ + X"$mf" : 'X\(//\)$' \| \ + X"$mf" : 'X\(/\)' \| . 2>/dev/null || +echo X"$mf" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + else + continue + fi + grep '^DEP_FILES *= *[^ #]' < "$mf" > /dev/null || continue + # Extract the definition of DEP_FILES from the Makefile without + # running `make'. + DEPDIR=`sed -n -e '/^DEPDIR = / s///p' < "$mf"` + test -z "$DEPDIR" && continue + # When using ansi2knr, U may be empty or an underscore; expand it + U=`sed -n -e '/^U = / s///p' < "$mf"` + test -d "$dirpart/$DEPDIR" || mkdir "$dirpart/$DEPDIR" + # We invoke sed twice because it is the simplest approach to + # changing $(DEPDIR) to its actual value in the expansion. + for file in `sed -n -e ' + /^DEP_FILES = .*\\\\$/ { + s/^DEP_FILES = // + :loop + s/\\\\$// + p + n + /\\\\$/ b loop + p + } + /^DEP_FILES = / s/^DEP_FILES = //p' < "$mf" | \ + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do + # Make sure the directory exists. + test -f "$dirpart/$file" && continue + fdir=`$as_dirname -- "$file" || +$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$file" : 'X\(//\)[^/]' \| \ + X"$file" : 'X\(//\)$' \| \ + X"$file" : 'X\(/\)' \| . 2>/dev/null || +echo X"$file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + { as_dir=$dirpart/$fdir + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || { $as_mkdir_p && mkdir -p "$as_dir"; } || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || { { echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5 +echo "$as_me: error: cannot create directory $as_dir" >&2;} + { (exit 1); exit 1; }; }; } + # echo "creating $dirpart/$file" + echo '# dummy' > "$dirpart/$file" + done +done + ;; + + esac +done # for ac_tag + + +{ (exit 0); exit 0; } +_ACEOF +chmod +x $CONFIG_STATUS +ac_clean_files=$ac_clean_files_save + + +# configure is writing to config.log, and then calls config.status. +# config.status does its own redirection, appending to config.log. +# Unfortunately, on DOS this fails, as config.log is still kept open +# by configure, so config.status won't be able to write to it; its +# output is simply discarded. So we exec the FD to /dev/null, +# effectively closing config.log, so it can be properly (re)opened and +# appended to by config.status. When coming back to configure, we +# need to make the FD available again. +if test "$no_create" != yes; then + ac_cs_success=: + ac_config_status_args= + test "$silent" = yes && + ac_config_status_args="$ac_config_status_args --quiet" + exec 5>/dev/null + $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false + exec 5>>config.log + # Use ||, not &&, to avoid exiting from the if with $? = 1, which + # would make configure fail if this is the last instruction. + $ac_cs_success || { (exit 1); exit 1; } +fi + diff --git a/configure.ac b/configure.ac new file mode 100644 index 0000000..63ba3f1 --- /dev/null +++ b/configure.ac @@ -0,0 +1,993 @@ +# -*- Autoconf -*- +# Process this file with autoconf to produce a configure script. + +FULL-PACKAGE-NAME=netperf +VERSION=2.4.5 +BUG-REPORT-ADDRESS=netperf-feedback@netperf.org + +AC_PREREQ(2.59) +AC_INIT(netperf, 2.4.5) +# use the target version rather than host - one day we may want cross-compile +AC_CANONICAL_TARGET +AC_CONFIG_SRCDIR([src/hist.h]) +AM_INIT_AUTOMAKE([dist-zip]) +AM_CONFIG_HEADER(config.h) +# AC_CONFIG_HEADER(config.h) + +AC_CONFIG_LIBOBJ_DIR(src/missing) + +# make sure we build netperf_version.h +touch src/netperf_version.h.in + +# Checks for programs. +AC_PROG_CC +AC_PROG_RANLIB + +AC_C_CONST + +# Checks for libraries. +AC_HAVE_LIBRARY(m) + +# Checks for header files. +AC_HEADER_STDC +AC_HEADER_SYS_WAIT +AC_CHECK_HEADERS([arpa/inet.h endian.h errno.h fcntl.h limits.h malloc.h netdb.h netinet/in.h signal.h stdlib.h string.h strings.h sys/ioctl.h sys/mman.h sys/param.h sys/socket.h sys/time.h unistd.h ifaddrs.h sys/sockio.h]) + +# Some platforms require these. There may be a better way. +AC_HAVE_LIBRARY(socket) +if test "$ac_cv_lib_socket_main" = yes ; then + AC_HAVE_LIBRARY(nsl) + AC_HAVE_LIBRARY(sendfile) + AC_SYS_LARGEFILE +fi + +# this one is for Tru64 and bind_to_cpu_id +AC_HAVE_LIBRARY(mach) + +# Checks for typedefs, structures, and compiler characteristics. +AC_C_CONST +AC_TYPE_OFF_T +AC_TYPE_SIZE_T +# AC_TYPE_SOCKLEN_T + +OLD_TYPE_SOCKLEN_T + +# AC_TYPE_IN_PORT_T +AC_DECL_H_ERRNO +AC_STRUCT_SOCKADDR_STORAGE +AC_HEADER_TIME +AC_HEADER_STDBOOL +AC_CHECK_SA_LEN(ac_cv_sockaddr_has_sa_len) + +# Checks for library functions. +# AC_FUNC_ERROR_AT_LINE +AC_FUNC_FORK +# AC_FUNC_MALLOC +AC_FUNC_MMAP +AC_FUNC_SELECT_ARGTYPES +AC_FUNC_SETPGRP +AC_TYPE_SIGNAL +# AC_FUNC_STAT +# remove pstat_getdynamic (at least for now) since we don't do +# anything conditional with the check anyway... +AC_CHECK_FUNCS([alarm bzero gethostbyname gethrtime gettimeofday inet_ntoa memset memcpy munmap select socket sqrt strcasecmp strchr strstr strtoul uname]) + +#AC_CONFIG_SUBDIRS(src/missing) + +# does this platform need the replacement getaddrinfo +AC_CHECK_FUNCS([getnameinfo getaddrinfo inet_ntop getifaddrs]) +# AC_REPLACE_FUNCS([getaddrinfo]) + + +if test "$ac_cv_func_getaddrinfo$ac_cv_func_getnameinfo" != yesyes ; then + AC_MSG_NOTICE([Requesting replacement getaddrinfo/getnameinfo]) + AC_LIBOBJ(getaddrinfo) + HAVE_MISSING=yes +fi +if test "$ac_cv_func_inet_ntop" != yes ; then + AC_MSG_NOTICE([Requesting replacement inet_ntop]) + AC_LIBOBJ(inet_ntop) + HAVE_MISSING=yes +fi +AM_CONDITIONAL(NEED_LIBCOMPAT, test "$HAVE_MISSING" = "yes") + +AC_CHECK_FUNCS(sendfile) + +AC_CHECK_FUNCS(uname) + +# check for the various CPU binding calls +AC_CHECK_FUNCS(mpctl processor_bind sched_setaffinity bind_to_cpu_id bindprocessor) + +# see if we should be enabling histogram support + +AC_MSG_CHECKING(whether to include histogram support) + +AC_ARG_ENABLE(histogram, + [AS_HELP_STRING([--enable-histogram],[include individual op timing, may affect result]) ]) + +case "$enable_histogram" in + yes) + use_histogram=true + ;; + no) + use_histogram=false + ;; + '') + # whatever + use_histogram=false + ;; + *) + AC_MSG_ERROR([--enable-histogram takes yes or no]) + ;; +esac + +if $use_histogram +then + AC_MSG_RESULT(yes) +else + AC_MSG_RESULT(no) +fi + +if $use_histogram +then + AC_DEFINE([WANT_HISTOGRAM],,[Define to one to enable histogram support. May affect results.]) +fi +# see if we should be enabling histogram support + +AC_MSG_CHECKING(whether to include dirty support) + +AC_ARG_ENABLE(dirty, + [AS_HELP_STRING([--enable-dirty],[write to buffers each time, may affect result]) ]) + +case "$enable_dirty" in + yes) + use_dirty=true + ;; + no) + use_dirty=false + ;; + '') + # whatever + use_dirty=false + ;; + *) + AC_MSG_ERROR([--enable-dirty takes yes or no]) + ;; +esac + +if $use_dirty +then + AC_MSG_RESULT(yes) +else + AC_MSG_RESULT(no) +fi + +if $use_dirty +then + AC_DEFINE([DIRTY],,[Define to one to enable dirty buffer support. May affect results.]) +fi + +# see if we should be enabling demo support + +AC_MSG_CHECKING(whether to include demo support) + +AC_ARG_ENABLE(demo, + [AS_HELP_STRING([--enable-demo],[emit interim results during the run. May affect results.])]) + +case "$enable_demo" in + yes) + use_demo=true + ;; + no) + use_demo=false + ;; + '') + # whatever + use_demo=false + ;; + *) + AC_MSG_ERROR([--enable-demo takes yes or no]) + ;; +esac + +if $use_demo +then + AC_MSG_RESULT(yes) +else + AC_MSG_RESULT(no) +fi + +if $use_demo +then + AC_DEFINE([WANT_DEMO],,[Define to one to enable demo support. May affect results.]) +fi + +# see if we should be including the AF_UNIX tests + +AC_MSG_CHECKING(whether to include Unix-domain socket tests) + +AC_ARG_ENABLE(unixdomain, + [AS_HELP_STRING([--enable-unixdomain],[include Unix Domain socket tests])]) + +case "$enable_unixdomain" in + yes) + use_unixdomain=true + ;; + no) + use_unixdomain=false + ;; + '') + use_unixdomain=false + ;; + *) + AC_MSG_ERROR([--enable-unixdomain takes yes or no]) + ;; +esac + +if $use_unixdomain +then + AC_MSG_RESULT(yes) +else + AC_MSG_RESULT(no) +fi + +if $use_unixdomain +then + AC_DEFINE([WANT_UNIX],,[Define to one to include Unix Domain socket tests.]) +fi + +# see if we should be including the DLPI tests + +AC_MSG_CHECKING(whether to include DLPI tests) + +AC_ARG_ENABLE(dlpi, + [AS_HELP_STRING([--enable-dlpi],[include DLPI (link-layer) tests])]) + +case "$enable_dlpi" in + yes) + use_dlpi=true + ;; + no) + use_dlpi=false + ;; + '') + use_dlpi=false + ;; + *) + AC_MSG_ERROR([--enable-dlpi takes yes or no]) + ;; +esac + +if $use_dlpi +then + AC_MSG_RESULT(yes) +else + AC_MSG_RESULT(no) +fi + +if $use_dlpi +then + AC_DEFINE([WANT_DLPI],,[Define to one to include DLPI tests.]) +fi + +# see if we should be including the DCCP tests + +AC_MSG_CHECKING(whether to include DCCP tests) + +AC_ARG_ENABLE(dccp, + [AS_HELP_STRING([--enable-dccp],[include DCCP tests])]) + +case "$enable_dccp" in + yes) + use_dccp=true + ;; + no) + use_dccp=false + ;; + '') + use_dccp=false + ;; + *) + AC_MSG_ERROR([--enable-dccp takes yes or no]) + ;; +esac + +if $use_dccp +then + AC_MSG_RESULT(yes) +else + AC_MSG_RESULT(no) +fi + +if $use_dccp +then + AC_DEFINE([WANT_DCCP],,[Define to one to include DCCP tests.]) +fi + +# see if we should be including the OMNI tests + +AC_MSG_CHECKING(whether to include OMNI tests) + +AC_ARG_ENABLE(omni, + [AS_HELP_STRING([--enable-omni],[include OMNI tests])]) + +case "$enable_omni" in + yes) + use_omni=true + ;; + no) + use_omni=false + ;; + '') + use_omni=false + ;; + *) + AC_MSG_ERROR([--enable-omni takes yes or no]) + ;; +esac + +if $use_omni +then + AC_MSG_RESULT(yes) +else + AC_MSG_RESULT(no) +fi + +if $use_omni +then + AC_DEFINE([WANT_OMNI],,[Define to one to include OMNI tests.]) +fi + + +# see if we should be including the XTI tests + +AC_MSG_CHECKING(whether to include XTI tests) + +AC_ARG_ENABLE(xti, + [AS_HELP_STRING([--enable-xti],[include XTI socket tests])]) + +case "$enable_xti" in + yes) + use_xti=true + ;; + no) + use_xti=false + ;; + '') + use_xti=false + ;; + *) + AC_MSG_ERROR([--enable-xti takes yes or no]) + ;; +esac + +if $use_xti +then + AC_MSG_RESULT(yes) +else + AC_MSG_RESULT(no) +fi + +if $use_xti +then + AC_DEFINE([WANT_XTI],,[Define to one to include XTI tests.]) +fi + +# see if we should be including the SDP tests + +AC_MSG_CHECKING(whether to include SDP tests) + +AC_ARG_ENABLE(sdp, + [AS_HELP_STRING([--enable-sdp],[include SDP socket tests])]) + +case "$enable_sdp" in + yes) + # probably need to be a bit more sophisticated here + AC_CHECK_LIB(sdp,t_open) + use_sdp=true + ;; + no) + use_sdp=false + ;; + '') + use_sdp=false + ;; + *) + AC_MSG_ERROR([--enable-sdp takes yes or no]) + ;; +esac + +if $use_sdp +then + AC_MSG_RESULT(yes) +else + AC_MSG_RESULT(no) +fi + +if $use_sdp +then + AC_DEFINE([WANT_SDP],,[Define to one to include SDP tests.]) +fi + +# see if we should be including the ICSC-EXS tests + +AC_MSG_CHECKING(whether to include ICSC-EXS tests) + +AC_ARG_ENABLE(exs, + [AS_HELP_STRING([--enable-exs],[include ICSC async sockets tests])]) + +case "$enable_exs" in + yes) + use_exs=true + AC_CHECK_HEADER(sys/exs.h,,[use_exs=false]) + AC_CHECK_LIB(exs,exs_init,,[use_exs=false]) + ;; + no) + use_exs=false + ;; + '') + use_exs=false + ;; + *) + AC_MSG_ERROR([--enable-exs takes yes or no]) + ;; +esac + +if $use_exs +then + AC_MSG_RESULT(yes) +else + AC_MSG_RESULT(no) +fi + +if $use_exs +then + AC_DEFINE([HAVE_ICSC_EXS],,[Define to one to include ICSC-EXS tests.]) +fi + +# see if we should be enabling SCTP support + + +AC_ARG_ENABLE(sctp, + [AS_HELP_STRING([--enable-sctp],[include tests to measure SCTP performance ])]) + +case "$enable_sctp" in + yes) + use_sctp=true + AC_CHECK_HEADERS(netinet/sctp.h,,use_sctp=false, +[[ +#include +]]) + case "$host" in + *-*-freebsd7.*) + # FreeBSD 7.x SCTP support doesn't need -lsctp. + ;; + *) + AC_HAVE_LIBRARY(sctp,,use_sctp=false) + ;; + esac + AC_CHECK_MEMBER(struct sctp_event_subscribe.sctp_adaptation_layer_event, + , , [#include ]) + if test "$ac_cv_member_struct_sctp_event_subscribe_sctp_adaptation_layer_event" = "yes"; then + AC_DEFINE([HAVE_SCTP_ADAPTATION_LAYER_EVENT], 1, + [Define to 1 if `struct sctp_event_subscribe' has a `sctp_adaptation_layer_event' member]) + fi + ;; + no) + use_sctp=false + ;; + '') + # whatever + use_sctp=false + ;; + *) + AC_MSG_ERROR([--enable-sctp takes yes or no]) + ;; +esac + +AC_MSG_CHECKING(whether to include SCTP tests) + +if $use_sctp +then + AC_MSG_RESULT(yes) +else + AC_MSG_RESULT(no) +fi + +if $use_sctp +then + AC_DEFINE([WANT_SCTP],,[Define to one to include SCTP tests.]) +fi + +# see if we should be enabling paced sends + +AC_MSG_CHECKING([whether to include paced send (intervals) support]) + +AC_ARG_ENABLE(intervals, + [AS_HELP_STRING([--enable-intervals],[include ability to pace operations, may affect result])]) + +case "$enable_intervals" in + yes) + use_intervals=true + ;; + no) + use_intervals=false + ;; + '') + use_intervals=false + ;; + *) + AC_MSG_ERROR([--enable-intervals takes yes or no]) + ;; +esac + +if $use_intervals +then + AC_MSG_RESULT(yes) +else + AC_MSG_RESULT(no) +fi + +if $use_intervals +then + AC_DEFINE([WANT_INTERVALS],,[Define to one to enable paced operation support. May affect results.]) +fi + +# see if paced sends should wait and spin + +AC_MSG_CHECKING([whether paced sends should spin]) + +AC_ARG_ENABLE(spin, + [AS_HELP_STRING([--enable-spin],[paced operations (--enable-intervals) should sit and spin - WILL affect result])]) + +case "$enable_spin" in + yes) + use_spin=true + ;; + no) + use_spin=false + ;; + '') + use_spin=false + ;; + *) + AC_MSG_ERROR([--enable-spin takes yes or no]) + ;; +esac + +if $use_spin +then + AC_MSG_RESULT(yes) +else + AC_MSG_RESULT(no) +fi + +if $use_spin +then + AC_DEFINE([WANT_INTERVALS],,[Define to one to enable paced operation support. May affect results.]) + AC_DEFINE([WANT_SPIN],,[Define to one to spin waiting on paced operation. WILL AFFEFCT CPU UTILIZATION]) +fi + +# see if we should be enabling initial request bursts + +AC_MSG_CHECKING([whether to include initial burst support in _RR tests]) + +AC_ARG_ENABLE(burst, + [AS_HELP_STRING([--enable-burst],[include intial request burst ability in _RR tests, may affect result])]) + +case "$enable_burst" in + yes) + use_burst=true + ;; + no) + use_burst=false + ;; + '') + use_burst=false + ;; + *) + AC_MSG_ERROR([--enable-burst takes yes or no]) + ;; +esac + +if $use_burst +then + AC_MSG_RESULT(yes) +else + AC_MSG_RESULT(no) +fi + +if $use_burst +then + AC_DEFINE([WANT_FIRST_BURST],,[Define to one to enable initial _RR burst support. May affect results.]) +fi + +# time to see about CPU utilization measurements + +AC_MSG_CHECKING([which CPU utilization measurement type to use]) + +AC_ARG_ENABLE(cpuutil, + [AS_HELP_STRING([--enable-cpuutil],[include code to measure CPU utilization using specified mechanism])]) + +NETCPU_SOURCE="$enable_cpuutil" +case "$enable_cpuutil" in + pstat) + use_cpuutil=true + AC_DEFINE([USE_PSTAT],,[Use HP-UX's pstat interface to measure CPU util.]) + ;; + pstatnew) + use_cpuutil=true + AC_DEFINE([USE_PSTAT],,[Use HP-UX's pstat interface to measure CPU util.]) + ;; + perfstat) + use_cpuutil=true + AC_DEFINE([USE_PERFSTAT],,[Use AIX's perfstat interface to measure CPU util.]) + AC_HAVE_LIBRARY(perfstat) + ;; + + looper) + use_cpuutil=true + AC_DEFINE([USE_LOOPER],,[Use looper/soaker processes to measure CPU util.]) + ;; + procstat) + use_cpuutil=true + AC_DEFINE([USE_PROC_STAT],,[Use Linux's procstat interface to measure CPU util.]) + ;; + kstat) + use_cpuutil=true + AC_DEFINE([USE_KSTAT],,[Use Solaris's kstat interface to measure CPU util.]) + AC_HAVE_LIBRARY(kstat) + ;; + kstat10) + use_cpuutil=true + AC_DEFINE([USE_KSTAT],,[Use Solaris's kstat interface to measure CPU util.]) + AC_HAVE_LIBRARY(kstat) + ;; + osx) + use_cpuutil=true + AC_DEFINE([USE_OSX],,[Use MacOS X's host_info interface to measure CPU util.]) + ;; + '') +# ia64-hp-hpux11.23 +# i386-pc-solaris2.10 +# guess it automagically in a nice big case statement + case $target in + *-*-linux*) + use_cpuutil=true + AC_DEFINE([USE_PROC_STAT],,[Use Linux's procstat interface to measure CPU util.]) + enable_cpuutil="procstat - auto" + NETCPU_SOURCE="procstat" + ;; + *-*-hpux11.23 | *-*-hpux11.31) + use_cpuutil=true + AC_DEFINE([USE_PSTAT],,[Use HP-UX's pstat interface to measure CPU util.]) + enable_cpuutil="pstatnew - auto" + NETCPU_SOURCE="pstatnew" + ;; + *-*-hpux11* | *-*-hpux10*) + use_cpuutil=true + AC_DEFINE([USE_PSTAT],,[Use HP-UX's pstat interface to measure CPU util.]) + enable_cpuutil="pstat - auto" + NETCPU_SOURCE="pstat" + ;; + *-*-aix5.*) + use_puutil=true + AC_DEFINE([USE_PERFSTAT],,[Use AIX's perfstat interface to measure CPU util.]) + AC_HAVE_LIBRARY(perfstat) + enable_cpuutil="perfstat - auto" + NETCPU_SOURCE="perfstat" + ;; + *-*-solaris2.1*) + use_cpuutil=true + AC_DEFINE([USE_KSTAT],,[Use Solaris's kstat interface to measure CPU util.]) + AC_HAVE_LIBRARY(kstat) + enable_cpuutil="kstat10 - auto" + NETCPU_SOURCE="kstat10" + ;; + *-*-solaris2.*) + use_cpuutil=true + AC_DEFINE([USE_KSTAT],,[Use Solaris's kstat interface to measure CPU util.]) + AC_HAVE_LIBRARY(kstat) + enable_cpuutil="kstat - auto" + NETCPU_SOURCE="kstat" + ;; + *-*-freebsd[[4-7]].* | *-*-netbsd[[1-9]].* ) + use_cpuutil=true + AC_DEFINE([USE_SYSCTL],,[Use MumbleBSD's sysctl interface to measure CPU util.]) + enable_cpuutil="sysctl - auto" + NETCPU_SOURCE="sysctl" + ;; + *-*-darwin*) + use_cpuutil=true + AC_DEFINE([USE_OSX],,[Use MacOS X's host_info interface to measure CPU util.]) + enable_cpuutil="osx - auto" + NETCPU_SOURCE="osx" + ;; + *) + use_cpuutil=false + NETCPU_SOURCE="none" + enable_cpuutil="none. Consider teaching configure about your platform." + ;; + esac + ;; + none) + use_cpuutil=false + ;; + *) + AC_MSG_ERROR([--enable-cpuutil takes kstat, kstat10, looper, osx, perfstat, procstat, pstat, pstatnew, sysctl or none]) + ;; +esac + + AC_MSG_RESULT("$enable_cpuutil") + +AC_SUBST(NETCPU_SOURCE) + +# time to see about route lookup mechanisms + +AC_MSG_CHECKING([which route lookup type to use]) + +AC_ARG_ENABLE(rtlookup, + [AS_HELP_STRING([--enable-rtlookup],[include code to find the probable egress interface using specified mechanism])]) + +NETRTLKUP_SOURCE="$enable_rtlookup" +case "$enable_rtlookup" in + rtmget) + use_rtlookup=true + ;; + + rtnetlink) + use_rtlookup=true + ;; + '') +# guess it automagically in a nice big case statement + case $target in + *-*-linux*) + use_rtlookup=true + enable_rtlookup="rtnetlink - auto" + NETRTLKUP_SOURCE="rtnetlink" + ;; + *-*-hpux11.31 | *-*-solaris* | *-*-aix5*) + use_rtlookup=true + enable_rtlookup="rtmget - auto" + NETRTLKUP_SOURCE="rtmget" + ;; + *-*-freebsd[[4-7]].* | *-*-darwin*) + use_rtlookup=true + enable_rtlookup="rtmget - auto" + NETRTLKUP_SOURCE="rtmget" + ;; + *) + use_rtlookup=false + NETRTLKUP_SOURCE="none" + enable_rtlookup="none. Consider teaching configure about your platform." + ;; + esac + ;; + none) + use_rtlookup=false + ;; + *) + AC_MSG_ERROR([--enable-rtlookup takes rtmget, rtnetlink or none]) + ;; +esac + + AC_MSG_RESULT("$enable_rtlookup") + +AC_SUBST(NETRTLKUP_SOURCE) + +# time to see about slot lookup mechanisms + +AC_MSG_CHECKING([which slot lookup type to use]) + +AC_ARG_ENABLE(slotlookup, + [AS_HELP_STRING([--enable-slotlookup],[include code to find the probable egress interface using specified mechanism])]) + +NETSLOTLKUP_SOURCE="$enable_slotlookup" +case "$enable_slotlookup" in + + linux) + use_slotlookup=true + ;; + solaris) + use_slotlookup=true + ;; + '') +# guess it automagically in a nice big case statement + case $target in + *-*-linux*) + use_slotlookup=true + enable_slotlookup="linux - auto" + NETSLOTLKUP_SOURCE="linux" + ;; + *-*-solaris*) + use_slotlookup=true + enable_slotlookup="solaris - auto" + NETSLOTLKUP_SOURCE="solaris" + AC_HAVE_LIBRARY(devinfo) + ;; + *) + use_slotlookup=false + NETSLOTLKUP_SOURCE="none" + enable_slotlookup="none. Consider teaching configure about your platform." + ;; + esac + ;; + none) + use_slotlookup=false + ;; + *) + AC_MSG_ERROR([--enable-slotlookup takes linux or none]) + ;; +esac + + AC_MSG_RESULT("$enable_slotlookup") + +AC_SUBST(NETSLOTLKUP_SOURCE) + + +# time to see about sec lookup mechanisms + +AC_MSG_CHECKING([which sec lookup type to use]) + +AC_ARG_ENABLE(seclookup, + [AS_HELP_STRING([--enable-seclookup],[include code to find the system security mechanism and its state])]) + +NETSECLKUP_SOURCE="$enable_seclookup" +case "$enable_seclookup" in + + linux) + use_seclookup=true + ;; + '') +# guess it automagically in a nice big case statement + case $target in + *-*-linux*) + AC_HAVE_LIBRARY(dl) + use_seclookup=true + enable_seclookup="linux - auto" + NETSECLKUP_SOURCE="linux" + ;; + *) + use_seclookup=false + NETSECLKUP_SOURCE="none" + enable_seclookup="none. Consider teaching configure about your platform." + ;; + esac + ;; + none) + use_seclookup=false + ;; + *) + AC_MSG_ERROR([--enable-seclookup takes linux or none]) + ;; +esac + + AC_MSG_RESULT("$enable_seclookup") + +AC_SUBST(NETSECLKUP_SOURCE) + + +# time to see about driver lookup mechanisms + +AC_MSG_CHECKING([which driver info lookup type to use]) + +AC_ARG_ENABLE(drvlookup, + [AS_HELP_STRING([--enable-drvlookup],[include code to find the driver information for the probable egress interface])]) + +NETDRVLKUP_SOURCE="$enable_drvlookup" +case "$enable_drvlookup" in + ethtool) + use_drvlookup=true + ;; + + solaris) + use_drvlookup=true + ;; + '') +# guess it automagically in a nice big case statement + case $target in + *-*-linux*) + use_drvlookup=true + enable_drvlookup="ethtool - auto" + NETDRVLKUP_SOURCE="ethtool" + ;; + *-*-solaris*) + use_drvlookup=true + enable_drvlookup="solaris - auto" + NETDRVLKUP_SOURCE="solaris" + ;; + *) + use_drvlookup=false + NETDRVLKUP_SOURCE="none" + enable_drvlookup="none. Consider teaching configure about your platform." + ;; + esac + ;; + none) + use_drvlookup=false + ;; + *) + AC_MSG_ERROR([--enable-drvlookup takes ethtool or none]) + ;; +esac + + AC_MSG_RESULT("$enable_drvlookup") + +AC_SUBST(NETDRVLKUP_SOURCE) + +# time to see about system lookup mechanisms + +AC_MSG_CHECKING([which system info lookup type to use]) + +AC_ARG_ENABLE(syslookup, + [AS_HELP_STRING([--enable-syslookup],[include code to find some rudimentary system information])]) + +NETSYSLKUP_SOURCE="$enable_syslookup" +case "$enable_syslookup" in + hpux11i) + use_syslookup=true + ;; + + linux) + use_syslookup=true; + AC_CHECK_HEADERS([smbios/SystemInfo.h]) + AC_HAVE_LIBRARY(smbios) + ;; + solaris) + use_syslookup=true; + # this will basically tell us if we can use libsmbios + AC_CHECK_HEADERS([sys/sbmios.h]) + AC_HAVE_LIBRARY(smbios) + ;; + '') +# guess it automagically in a nice big case statement + case $target in + *-*-hpux11*) + use_syslookup=true + enable_syslookup="hpux11i - auto" + NETSYSLKUP_SOURCE="hpux11i" + ;; + *-*-linux*) + use_syslookup=true + enable_syslookup="linux - auto" + AC_CHECK_HEADERS([smbios/SystemInfo.h]) + AC_HAVE_LIBRARY(smbios) + NETSYSLKUP_SOURCE="linux" + ;; + *-*-solaris*) + use_syslookup=true + enable_syslookup="solaris - auto" + NETSYSLKUP_SOURCE="solaris" + AC_CHECK_HEADERS([sys/smbios.h]) + AC_HAVE_LIBRARY(smbios) + ;; + *) + use_syslookup=false + NETSYSLKUP_SOURCE="none" + enable_syslookup="none. Consider teaching configure about your platform." + ;; + esac + ;; + none) + use_syslookup=false + ;; + *) + AC_MSG_ERROR([--enable-syslookup takes hpux11i, linux or none]) + ;; +esac + + AC_MSG_RESULT("$enable_syslookup") + +AC_SUBST(NETSYSLKUP_SOURCE) + +# now spit it all out +AC_CONFIG_FILES([Makefile + src/netperf_version.h + src/Makefile + src/missing/Makefile + src/missing/m4/Makefile + doc/Makefile + doc/examples/Makefile + netperf.spec]) + +AC_OUTPUT diff --git a/depcomp b/depcomp new file mode 100755 index 0000000..edb5d38 --- /dev/null +++ b/depcomp @@ -0,0 +1,479 @@ +#! /bin/sh + +# depcomp - compile a program generating dependencies as side-effects +# Copyright 1999, 2000, 2003 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Originally written by Alexandre Oliva . + +if test -z "$depmode" || test -z "$source" || test -z "$object"; then + echo "depcomp: Variables source, object and depmode must be set" 1>&2 + exit 1 +fi +# `libtool' can also be set to `yes' or `no'. + +if test -z "$depfile"; then + base=`echo "$object" | sed -e 's,^.*/,,' -e 's,\.\([^.]*\)$,.P\1,'` + dir=`echo "$object" | sed 's,/.*$,/,'` + if test "$dir" = "$object"; then + dir= + fi + # FIXME: should be _deps on DOS. + depfile="$dir.deps/$base" +fi + +tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} + +rm -f "$tmpdepfile" + +# Some modes work just like other modes, but use different flags. We +# parameterize here, but still list the modes in the big case below, +# to make depend.m4 easier to write. Note that we *cannot* use a case +# here, because this file can only contain one case statement. +if test "$depmode" = hp; then + # HP compiler uses -M and no extra arg. + gccflag=-M + depmode=gcc +fi + +if test "$depmode" = dashXmstdout; then + # This is just like dashmstdout with a different argument. + dashmflag=-xM + depmode=dashmstdout +fi + +case "$depmode" in +gcc3) +## gcc 3 implements dependency tracking that does exactly what +## we want. Yay! Note: for some reason libtool 1.4 doesn't like +## it if -MD -MP comes after the -MF stuff. Hmm. + "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + mv "$tmpdepfile" "$depfile" + ;; + +gcc) +## There are various ways to get dependency output from gcc. Here's +## why we pick this rather obscure method: +## - Don't want to use -MD because we'd like the dependencies to end +## up in a subdir. Having to rename by hand is ugly. +## (We might end up doing this anyway to support other compilers.) +## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like +## -MM, not -M (despite what the docs say). +## - Using -M directly means running the compiler twice (even worse +## than renaming). + if test -z "$gccflag"; then + gccflag=-MD, + fi + "$@" -Wp,"$gccflag$tmpdepfile" + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + echo "$object : \\" > "$depfile" + alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz +## The second -e expression handles DOS-style file names with drive letters. + sed -e 's/^[^:]*: / /' \ + -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" +## This next piece of magic avoids the `deleted header file' problem. +## The problem is that when a header file which appears in a .P file +## is deleted, the dependency causes make to die (because there is +## typically no way to rebuild the header). We avoid this by adding +## dummy dependencies for each header file. Too bad gcc doesn't do +## this for us directly. + tr ' ' ' +' < "$tmpdepfile" | +## Some versions of gcc put a space before the `:'. On the theory +## that the space means something, we add a space to the output as +## well. +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +hp) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +sgi) + if test "$libtool" = yes; then + "$@" "-Wp,-MDupdate,$tmpdepfile" + else + "$@" -MDupdate "$tmpdepfile" + fi + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + + if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files + echo "$object : \\" > "$depfile" + + # Clip off the initial element (the dependent). Don't try to be + # clever and replace this with sed code, as IRIX sed won't handle + # lines with more than a fixed number of characters (4096 in + # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; + # the IRIX cc adds comments like `#:fec' to the end of the + # dependency line. + tr ' ' ' +' < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \ + tr ' +' ' ' >> $depfile + echo >> $depfile + + # The second pass generates a dummy entry for each header file. + tr ' ' ' +' < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ + >> $depfile + else + # The sourcefile does not contain any dependencies, so just + # store a dummy comment line, to avoid errors with the Makefile + # "include basename.Plo" scheme. + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" + ;; + +aix) + # The C for AIX Compiler uses -M and outputs the dependencies + # in a .u file. In older versions, this file always lives in the + # current directory. Also, the AIX compiler puts `$object:' at the + # start of each line; $object doesn't have directory information. + # Version 6 uses the directory in both cases. + stripped=`echo "$object" | sed 's/\(.*\)\..*$/\1/'` + tmpdepfile="$stripped.u" + if test "$libtool" = yes; then + "$@" -Wc,-M + else + "$@" -M + fi + stat=$? + + if test -f "$tmpdepfile"; then : + else + stripped=`echo "$stripped" | sed 's,^.*/,,'` + tmpdepfile="$stripped.u" + fi + + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + + if test -f "$tmpdepfile"; then + outname="$stripped.o" + # Each line is of the form `foo.o: dependent.h'. + # Do two passes, one to just change these to + # `$object: dependent.h' and one to simply `dependent.h:'. + sed -e "s,^$outname:,$object :," < "$tmpdepfile" > "$depfile" + sed -e "s,^$outname: \(.*\)$,\1:," < "$tmpdepfile" >> "$depfile" + else + # The sourcefile does not contain any dependencies, so just + # store a dummy comment line, to avoid errors with the Makefile + # "include basename.Plo" scheme. + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" + ;; + +icc) + # Intel's C compiler understands `-MD -MF file'. However on + # icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c + # ICC 7.0 will fill foo.d with something like + # foo.o: sub/foo.c + # foo.o: sub/foo.h + # which is wrong. We want: + # sub/foo.o: sub/foo.c + # sub/foo.o: sub/foo.h + # sub/foo.c: + # sub/foo.h: + # ICC 7.1 will output + # foo.o: sub/foo.c sub/foo.h + # and will wrap long lines using \ : + # foo.o: sub/foo.c ... \ + # sub/foo.h ... \ + # ... + + "$@" -MD -MF "$tmpdepfile" + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + # Each line is of the form `foo.o: dependent.h', + # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'. + # Do two passes, one to just change these to + # `$object: dependent.h' and one to simply `dependent.h:'. + sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile" + # Some versions of the HPUX 10.20 sed can't process this invocation + # correctly. Breaking it into two sed invocations is a workaround. + sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" | + sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +tru64) + # The Tru64 compiler uses -MD to generate dependencies as a side + # effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'. + # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put + # dependencies in `foo.d' instead, so we check for that too. + # Subdirectories are respected. + dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` + test "x$dir" = "x$object" && dir= + base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` + + if test "$libtool" = yes; then + tmpdepfile1="$dir.libs/$base.lo.d" + tmpdepfile2="$dir.libs/$base.d" + "$@" -Wc,-MD + else + tmpdepfile1="$dir$base.o.d" + tmpdepfile2="$dir$base.d" + "$@" -MD + fi + + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile1" "$tmpdepfile2" + exit $stat + fi + + if test -f "$tmpdepfile1"; then + tmpdepfile="$tmpdepfile1" + else + tmpdepfile="$tmpdepfile2" + fi + if test -f "$tmpdepfile"; then + sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" + # That's a tab and a space in the []. + sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" + else + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" + ;; + +#nosideeffect) + # This comment above is used by automake to tell side-effect + # dependency tracking mechanisms from slower ones. + +dashmstdout) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout, regardless of -o. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test $1 != '--mode=compile'; do + shift + done + shift + fi + + # Remove `-o $object'. + IFS=" " + for arg + do + case $arg in + -o) + shift + ;; + $object) + shift + ;; + *) + set fnord "$@" "$arg" + shift # fnord + shift # $arg + ;; + esac + done + + test -z "$dashmflag" && dashmflag=-M + # Require at least two characters before searching for `:' + # in the target name. This is to cope with DOS-style filenames: + # a dependency such as `c:/foo/bar' could be seen as target `c' otherwise. + "$@" $dashmflag | + sed 's:^[ ]*[^: ][^:][^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile" + rm -f "$depfile" + cat < "$tmpdepfile" > "$depfile" + tr ' ' ' +' < "$tmpdepfile" | \ +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +dashXmstdout) + # This case only exists to satisfy depend.m4. It is never actually + # run, as this mode is specially recognized in the preamble. + exit 1 + ;; + +makedepend) + "$@" || exit $? + # Remove any Libtool call + if test "$libtool" = yes; then + while test $1 != '--mode=compile'; do + shift + done + shift + fi + # X makedepend + shift + cleared=no + for arg in "$@"; do + case $cleared in + no) + set ""; shift + cleared=yes ;; + esac + case "$arg" in + -D*|-I*) + set fnord "$@" "$arg"; shift ;; + # Strip any option that makedepend may not understand. Remove + # the object too, otherwise makedepend will parse it as a source file. + -*|$object) + ;; + *) + set fnord "$@" "$arg"; shift ;; + esac + done + obj_suffix="`echo $object | sed 's/^.*\././'`" + touch "$tmpdepfile" + ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" + rm -f "$depfile" + cat < "$tmpdepfile" > "$depfile" + sed '1,2d' "$tmpdepfile" | tr ' ' ' +' | \ +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" "$tmpdepfile".bak + ;; + +cpp) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test $1 != '--mode=compile'; do + shift + done + shift + fi + + # Remove `-o $object'. + IFS=" " + for arg + do + case $arg in + -o) + shift + ;; + $object) + shift + ;; + *) + set fnord "$@" "$arg" + shift # fnord + shift # $arg + ;; + esac + done + + "$@" -E | + sed -n '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' | + sed '$ s: \\$::' > "$tmpdepfile" + rm -f "$depfile" + echo "$object : \\" > "$depfile" + cat < "$tmpdepfile" >> "$depfile" + sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +msvisualcpp) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout, regardless of -o, + # because we must use -o when running libtool. + "$@" || exit $? + IFS=" " + for arg + do + case "$arg" in + "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") + set fnord "$@" + shift + shift + ;; + *) + set fnord "$@" "$arg" + shift + shift + ;; + esac + done + "$@" -E | + sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::echo "`cygpath -u \\"\1\\"`":p' | sort | uniq > "$tmpdepfile" + rm -f "$depfile" + echo "$object : \\" > "$depfile" + . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile" + echo " " >> "$depfile" + . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s::\1\::p' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +none) + exec "$@" + ;; + +*) + echo "Unknown depmode $depmode" 1>&2 + exit 1 + ;; +esac + +exit 0 diff --git a/doc/Makefile.am b/doc/Makefile.am new file mode 100644 index 0000000..40167a6 --- /dev/null +++ b/doc/Makefile.am @@ -0,0 +1,22 @@ +# what is your philosophy - distribute pre-made .pdf et al in a make dist +# or not? choose your EXTRA_DIST line accordingly +# EXTRA_DIST = netperf.man netserver.man netperf.txt netperf.html netperf.xml netperf_old.ps netperf.pdf netperf.ps netperf.texi examples + +SUBDIRS = examples + +EXTRA_DIST = netperf.man netserver.man netperf_old.ps netperf.texi +man1_MANS = netperf.man netserver.man +info_TEXINFOS = netperf.texi +CLEANFILES = netperf.txt netperf.xml netperf.html + +netperf.html: $(info_TEXINFOS) + $(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) --html --no-split -I $(srcdir) \ + -o $@ `test -f '$<' || echo '$(srcdir)/'`$< + +netperf.txt: $(info_TEXINFOS) + $(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) --plaintext -I $(srcdir) \ + -o $@ `test -f '$<' || echo '$(srcdir)/'`$< + +netperf.xml: $(info_TEXINFOS) + $(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) --xml -I $(srcdir) \ + -o $@ `test -f '$<' || echo '$(srcdir)/'`$< diff --git a/doc/Makefile.in b/doc/Makefile.in new file mode 100644 index 0000000..3d70235 --- /dev/null +++ b/doc/Makefile.in @@ -0,0 +1,606 @@ +# Makefile.in generated by automake 1.7.9 from Makefile.am. +# @configure_input@ + +# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 +# Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +# what is your philosophy - distribute pre-made .pdf et al in a make dist +# or not? choose your EXTRA_DIST line accordingly +# EXTRA_DIST = netperf.man netserver.man netperf.txt netperf.html netperf.xml netperf_old.ps netperf.pdf netperf.ps netperf.texi examples + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +top_builddir = .. + +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +INSTALL = @INSTALL@ +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +host_triplet = @host@ +ACLOCAL = @ACLOCAL@ +AMDEP_FALSE = @AMDEP_FALSE@ +AMDEP_TRUE = @AMDEP_TRUE@ +AMTAR = @AMTAR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +GREP = @GREP@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +NEED_LIBCOMPAT_FALSE = @NEED_LIBCOMPAT_FALSE@ +NEED_LIBCOMPAT_TRUE = @NEED_LIBCOMPAT_TRUE@ +NETCPU_SOURCE = @NETCPU_SOURCE@ +NETDRVLKUP_SOURCE = @NETDRVLKUP_SOURCE@ +NETRTLKUP_SOURCE = @NETRTLKUP_SOURCE@ +NETSECLKUP_SOURCE = @NETSECLKUP_SOURCE@ +NETSLOTLKUP_SOURCE = @NETSLOTLKUP_SOURCE@ +NETSYSLKUP_SOURCE = @NETSYSLKUP_SOURCE@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +ac_ct_CC = @ac_ct_CC@ +am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ +am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +sysconfdir = @sysconfdir@ +target = @target@ +target_alias = @target_alias@ +target_cpu = @target_cpu@ +target_os = @target_os@ +target_vendor = @target_vendor@ + +SUBDIRS = examples + +EXTRA_DIST = netperf.man netserver.man netperf_old.ps netperf.texi +man1_MANS = netperf.man netserver.man +info_TEXINFOS = netperf.texi +CLEANFILES = netperf.txt netperf.xml netperf.html +subdir = doc +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +DIST_SOURCES = +am__TEXINFO_TEX_DIR = $(srcdir) +INFO_DEPS = netperf.info +DVIS = netperf.dvi +PDFS = netperf.pdf +PSS = netperf.ps +TEXINFOS = netperf.texi + +NROFF = nroff +MANS = $(man1_MANS) + +RECURSIVE_TARGETS = info-recursive dvi-recursive pdf-recursive \ + ps-recursive install-info-recursive uninstall-info-recursive \ + all-recursive install-data-recursive install-exec-recursive \ + installdirs-recursive install-recursive uninstall-recursive \ + check-recursive installcheck-recursive +DIST_COMMON = $(srcdir)/Makefile.in Makefile.am texinfo.tex +DIST_SUBDIRS = $(SUBDIRS) +all: all-recursive + +.SUFFIXES: +.SUFFIXES: .dvi .info .pdf .ps .texi +$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.ac $(ACLOCAL_M4) + cd $(top_srcdir) && \ + $(AUTOMAKE) --gnu doc/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe) + +.texi.info: + @rm -f $@ $@-[0-9] $@-[0-9][0-9] $(@:.info=).i[0-9] $(@:.info=).i[0-9][0-9] + $(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir) \ + -o $@ `test -f '$<' || echo '$(srcdir)/'`$< + +.texi.dvi: + TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \ + MAKEINFO='$(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir)' \ + $(TEXI2DVI) `test -f '$<' || echo '$(srcdir)/'`$< + +.texi.pdf: + TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \ + MAKEINFO='$(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir)' \ + $(TEXI2PDF) `test -f '$<' || echo '$(srcdir)/'`$< +netperf.info: netperf.texi +netperf.dvi: netperf.texi +netperf.pdf: netperf.texi +TEXI2DVI = texi2dvi + +TEXI2PDF = $(TEXI2DVI) --pdf --batch +DVIPS = dvips +.dvi.ps: + $(DVIPS) -o $@ $< + +uninstall-info-am: + $(PRE_UNINSTALL) + @if (install-info --version && \ + install-info --version 2>&1 | sed 1q | grep -i -v debian) >/dev/null 2>&1; then \ + list='$(INFO_DEPS)'; \ + for file in $$list; do \ + relfile=`echo "$$file" | sed 's|^.*/||'`; \ + echo " install-info --info-dir=$(DESTDIR)$(infodir) --remove $(DESTDIR)$(infodir)/$$relfile"; \ + install-info --info-dir=$(DESTDIR)$(infodir) --remove $(DESTDIR)$(infodir)/$$relfile; \ + done; \ + else :; fi + @$(NORMAL_UNINSTALL) + @list='$(INFO_DEPS)'; \ + for file in $$list; do \ + relfile=`echo "$$file" | sed 's|^.*/||'`; \ + relfile_i=`echo "$$relfile" | sed 's|\.info$$||;s|$$|.i|'`; \ + (if cd $(DESTDIR)$(infodir); then \ + echo " rm -f $$relfile $$relfile-[0-9] $$relfile-[0-9][0-9] $$relfile_i[0-9] $$relfile_i[0-9][0-9])"; \ + rm -f $$relfile $$relfile-[0-9] $$relfile-[0-9][0-9] $$relfile_i[0-9] $$relfile_i[0-9][0-9]; \ + else :; fi); \ + done + +dist-info: $(INFO_DEPS) + list='$(INFO_DEPS)'; \ + for base in $$list; do \ + if test -f $$base; then d=.; else d=$(srcdir); fi; \ + for file in $$d/$$base*; do \ + relfile=`expr "$$file" : "$$d/\(.*\)"`; \ + test -f $(distdir)/$$relfile || \ + cp -p $$file $(distdir)/$$relfile; \ + done; \ + done + +mostlyclean-aminfo: + -rm -f netperf.aux netperf.cp netperf.cps netperf.fn netperf.fns netperf.ky \ + netperf.kys netperf.log netperf.pg netperf.pgs netperf.tmp \ + netperf.toc netperf.tp netperf.tps netperf.vr netperf.vrs \ + netperf.dvi netperf.pdf netperf.ps + +maintainer-clean-aminfo: + @list='$(INFO_DEPS)'; for i in $$list; do \ + i_i=`echo "$$i" | sed 's|\.info$$||;s|$$|.i|'`; \ + echo " rm -f $$i $$i-[0-9] $$i-[0-9][0-9] $$i_i[0-9] $$i_i[0-9][0-9]"; \ + rm -f $$i $$i-[0-9] $$i-[0-9][0-9] $$i_i[0-9] $$i_i[0-9][0-9]; \ + done + +man1dir = $(mandir)/man1 +install-man1: $(man1_MANS) $(man_MANS) + @$(NORMAL_INSTALL) + $(mkinstalldirs) $(DESTDIR)$(man1dir) + @list='$(man1_MANS) $(dist_man1_MANS) $(nodist_man1_MANS)'; \ + l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \ + for i in $$l2; do \ + case "$$i" in \ + *.1*) list="$$list $$i" ;; \ + esac; \ + done; \ + for i in $$list; do \ + if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \ + else file=$$i; fi; \ + ext=`echo $$i | sed -e 's/^.*\\.//'`; \ + case "$$ext" in \ + 1*) ;; \ + *) ext='1' ;; \ + esac; \ + inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \ + inst=`echo $$inst | sed -e 's/^.*\///'`; \ + inst=`echo $$inst | sed '$(transform)'`.$$ext; \ + echo " $(INSTALL_DATA) $$file $(DESTDIR)$(man1dir)/$$inst"; \ + $(INSTALL_DATA) $$file $(DESTDIR)$(man1dir)/$$inst; \ + done +uninstall-man1: + @$(NORMAL_UNINSTALL) + @list='$(man1_MANS) $(dist_man1_MANS) $(nodist_man1_MANS)'; \ + l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \ + for i in $$l2; do \ + case "$$i" in \ + *.1*) list="$$list $$i" ;; \ + esac; \ + done; \ + for i in $$list; do \ + ext=`echo $$i | sed -e 's/^.*\\.//'`; \ + case "$$ext" in \ + 1*) ;; \ + *) ext='1' ;; \ + esac; \ + inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \ + inst=`echo $$inst | sed -e 's/^.*\///'`; \ + inst=`echo $$inst | sed '$(transform)'`.$$ext; \ + echo " rm -f $(DESTDIR)$(man1dir)/$$inst"; \ + rm -f $(DESTDIR)$(man1dir)/$$inst; \ + done + +# This directory's subdirectories are mostly independent; you can cd +# into them and run `make' without going through this Makefile. +# To change the values of `make' variables: instead of editing Makefiles, +# (1) if the variable is set in `config.status', edit `config.status' +# (which will cause the Makefiles to be regenerated when you run `make'); +# (2) otherwise, pass the desired values on the `make' command line. +$(RECURSIVE_TARGETS): + @set fnord $$MAKEFLAGS; amf=$$2; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +mostlyclean-recursive clean-recursive distclean-recursive \ +maintainer-clean-recursive: + @set fnord $$MAKEFLAGS; amf=$$2; \ + dot_seen=no; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + rev=''; for subdir in $$list; do \ + if test "$$subdir" = "."; then :; else \ + rev="$$subdir $$rev"; \ + fi; \ + done; \ + rev="$$rev ."; \ + target=`echo $@ | sed s/-recursive//`; \ + for subdir in $$rev; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ + done && test -z "$$fail" +tags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ + done +ctags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ + done + +ETAGS = etags +ETAGSFLAGS = + +CTAGS = ctags +CTAGSFLAGS = + +tags: TAGS + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + mkid -fID $$unique + +TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + if (etags --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + else \ + include_option=--include; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test -f $$subdir/TAGS && \ + tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(ETAGS_ARGS)$$tags$$unique" \ + || $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$tags $$unique + +ctags: CTAGS +CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(CTAGS_ARGS)$$tags$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$tags $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && cd $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) $$here + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) + +top_distdir = .. +distdir = $(top_distdir)/$(PACKAGE)-$(VERSION) + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ + list='$(DISTFILES)'; for file in $$list; do \ + case $$file in \ + $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ + $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ + esac; \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test "$$dir" != "$$file" && test "$$dir" != "."; then \ + dir="/$$dir"; \ + $(mkinstalldirs) "$(distdir)$$dir"; \ + else \ + dir=''; \ + fi; \ + if test -d $$d/$$file; then \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test -d $(distdir)/$$subdir \ + || mkdir $(distdir)/$$subdir \ + || exit 1; \ + (cd $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$(top_distdir)" \ + distdir=../$(distdir)/$$subdir \ + distdir) \ + || exit 1; \ + fi; \ + done + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$(top_distdir)" distdir="$(distdir)" \ + dist-info +check-am: all-am +check: check-recursive +all-am: Makefile $(INFO_DEPS) $(MANS) +installdirs: installdirs-recursive +installdirs-am: + $(mkinstalldirs) $(DESTDIR)$(infodir) $(DESTDIR)$(man1dir) + +install: install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-recursive +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -rm -f $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-recursive + +clean-am: clean-generic mostlyclean-am + +distclean: distclean-recursive + -rm -f Makefile +distclean-am: clean-am distclean-generic distclean-tags + +dvi: dvi-recursive + +dvi-am: $(DVIS) + +info: info-recursive + +info-am: $(INFO_DEPS) + +install-data-am: install-info-am install-man + +install-exec-am: + +install-info: install-info-recursive + +install-info-am: $(INFO_DEPS) + @$(NORMAL_INSTALL) + $(mkinstalldirs) $(DESTDIR)$(infodir) + @list='$(INFO_DEPS)'; \ + for file in $$list; do \ + if test -f $$file; then d=.; else d=$(srcdir); fi; \ + file_i=`echo "$$file" | sed 's|\.info$$||;s|$$|.i|'`; \ + for ifile in $$d/$$file $$d/$$file-[0-9] $$d/$$file-[0-9][0-9] \ + $$d/$$file_i[0-9] $$d/$$file_i[0-9][0-9] ; do \ + if test -f $$ifile; then \ + relfile=`echo "$$ifile" | sed 's|^.*/||'`; \ + echo " $(INSTALL_DATA) $$ifile $(DESTDIR)$(infodir)/$$relfile"; \ + $(INSTALL_DATA) $$ifile $(DESTDIR)$(infodir)/$$relfile; \ + else : ; fi; \ + done; \ + done + @$(POST_INSTALL) + @if (install-info --version && \ + install-info --version 2>&1 | sed 1q | grep -i -v debian) >/dev/null 2>&1; then \ + list='$(INFO_DEPS)'; \ + for file in $$list; do \ + relfile=`echo "$$file" | sed 's|^.*/||'`; \ + echo " install-info --info-dir=$(DESTDIR)$(infodir) $(DESTDIR)$(infodir)/$$relfile";\ + install-info --info-dir=$(DESTDIR)$(infodir) $(DESTDIR)$(infodir)/$$relfile || :;\ + done; \ + else : ; fi +install-man: install-man1 + +installcheck-am: + +maintainer-clean: maintainer-clean-recursive + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-aminfo \ + maintainer-clean-generic + +mostlyclean: mostlyclean-recursive + +mostlyclean-am: mostlyclean-aminfo mostlyclean-generic + +pdf: pdf-recursive + +pdf-am: $(PDFS) + +ps: ps-recursive + +ps-am: $(PSS) + +uninstall-am: uninstall-info-am uninstall-man + +uninstall-info: uninstall-info-recursive + +uninstall-man: uninstall-man1 + +.PHONY: $(RECURSIVE_TARGETS) CTAGS GTAGS all all-am check check-am clean \ + clean-generic clean-recursive ctags ctags-recursive dist-info \ + distclean distclean-generic distclean-recursive distclean-tags \ + distdir dvi dvi-am dvi-recursive info info-am info-recursive \ + install install-am install-data install-data-am \ + install-data-recursive install-exec install-exec-am \ + install-exec-recursive install-info install-info-am \ + install-info-recursive install-man install-man1 \ + install-recursive install-strip installcheck installcheck-am \ + installdirs installdirs-am installdirs-recursive \ + maintainer-clean maintainer-clean-aminfo \ + maintainer-clean-generic maintainer-clean-recursive mostlyclean \ + mostlyclean-aminfo mostlyclean-generic mostlyclean-recursive \ + pdf pdf-am pdf-recursive ps ps-am ps-recursive tags \ + tags-recursive uninstall uninstall-am uninstall-info-am \ + uninstall-info-recursive uninstall-man uninstall-man1 \ + uninstall-recursive + + +netperf.html: $(info_TEXINFOS) + $(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) --html --no-split -I $(srcdir) \ + -o $@ `test -f '$<' || echo '$(srcdir)/'`$< + +netperf.txt: $(info_TEXINFOS) + $(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) --plaintext -I $(srcdir) \ + -o $@ `test -f '$<' || echo '$(srcdir)/'`$< + +netperf.xml: $(info_TEXINFOS) + $(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) --xml -I $(srcdir) \ + -o $@ `test -f '$<' || echo '$(srcdir)/'`$< +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/doc/examples/Makefile.am b/doc/examples/Makefile.am new file mode 100644 index 0000000..9b2a0be --- /dev/null +++ b/doc/examples/Makefile.am @@ -0,0 +1,11 @@ +EXTRA_DIST = \ + arr_script \ + packet_byte_script \ + sctp_stream_script \ + snapshot_script \ + tcp_range_script \ + tcp_rr_script \ + tcp_stream_script \ + udp_rr_script \ + udp_stream_script + diff --git a/doc/examples/Makefile.in b/doc/examples/Makefile.in new file mode 100644 index 0000000..ac6e6ea --- /dev/null +++ b/doc/examples/Makefile.in @@ -0,0 +1,284 @@ +# Makefile.in generated by automake 1.7.9 from Makefile.am. +# @configure_input@ + +# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 +# Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +top_builddir = ../.. + +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +INSTALL = @INSTALL@ +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +host_triplet = @host@ +ACLOCAL = @ACLOCAL@ +AMDEP_FALSE = @AMDEP_FALSE@ +AMDEP_TRUE = @AMDEP_TRUE@ +AMTAR = @AMTAR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +GREP = @GREP@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +NEED_LIBCOMPAT_FALSE = @NEED_LIBCOMPAT_FALSE@ +NEED_LIBCOMPAT_TRUE = @NEED_LIBCOMPAT_TRUE@ +NETCPU_SOURCE = @NETCPU_SOURCE@ +NETDRVLKUP_SOURCE = @NETDRVLKUP_SOURCE@ +NETRTLKUP_SOURCE = @NETRTLKUP_SOURCE@ +NETSECLKUP_SOURCE = @NETSECLKUP_SOURCE@ +NETSLOTLKUP_SOURCE = @NETSLOTLKUP_SOURCE@ +NETSYSLKUP_SOURCE = @NETSYSLKUP_SOURCE@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +ac_ct_CC = @ac_ct_CC@ +am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ +am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +sysconfdir = @sysconfdir@ +target = @target@ +target_alias = @target_alias@ +target_cpu = @target_cpu@ +target_os = @target_os@ +target_vendor = @target_vendor@ +EXTRA_DIST = \ + arr_script \ + packet_byte_script \ + sctp_stream_script \ + snapshot_script \ + tcp_range_script \ + tcp_rr_script \ + tcp_stream_script \ + udp_rr_script \ + udp_stream_script + +subdir = doc/examples +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +DIST_SOURCES = +DIST_COMMON = $(srcdir)/Makefile.in Makefile.am +all: all-am + +.SUFFIXES: +$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.ac $(ACLOCAL_M4) + cd $(top_srcdir) && \ + $(AUTOMAKE) --gnu doc/examples/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe) +uninstall-info-am: +tags: TAGS +TAGS: + +ctags: CTAGS +CTAGS: + +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) + +top_distdir = ../.. +distdir = $(top_distdir)/$(PACKAGE)-$(VERSION) + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ + list='$(DISTFILES)'; for file in $$list; do \ + case $$file in \ + $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ + $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ + esac; \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test "$$dir" != "$$file" && test "$$dir" != "."; then \ + dir="/$$dir"; \ + $(mkinstalldirs) "$(distdir)$$dir"; \ + else \ + dir=''; \ + fi; \ + if test -d $$d/$$file; then \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile + +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -rm -f $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic mostlyclean-am + +distclean: distclean-am + -rm -f Makefile +distclean-am: clean-am distclean-generic + +dvi: dvi-am + +dvi-am: + +info: info-am + +info-am: + +install-data-am: + +install-exec-am: + +install-info: install-info-am + +install-man: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-generic + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-info-am + +.PHONY: all all-am check check-am clean clean-generic distclean \ + distclean-generic distdir dvi dvi-am info info-am install \ + install-am install-data install-data-am install-exec \ + install-exec-am install-info install-info-am install-man \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-generic pdf pdf-am ps ps-am uninstall uninstall-am \ + uninstall-info-am + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/doc/examples/arr_script b/doc/examples/arr_script new file mode 100755 index 0000000..fbcf3f6 --- /dev/null +++ b/doc/examples/arr_script @@ -0,0 +1,386 @@ +# this is retained mostly for historical purposes and may not be +# up to date for contemporary netperf versions +# +# a script that can be used to measure aggregate netperf performance, +# original author is Mike Traynor. Modifications to create the +# "netperf TCP_ARR test" by rick jones +# + +init_parms() { + TEST_TIME=60 + NTEST=3 + TOLERANCE=15 + MAX_RETRIES=3 + + NETPERF="/usr/local/netperf/netperf" + NETPERF="./netperf" + + NPROC_LIST="" + RR_SIZES="" + REM_HOST_LIST="" + DEVFILELIST="" + LLA=0 + TCP=1 + UDP=0 + GPROF=0 +} + +set_default_parms() { + if [ "X$NPROC_LIST" = "X" ] + then + NPROC_LIST="1" + fi + + if [ "X$REM_HOST_LIST" = "X" ] + then + REM_HOST_LIST="127.0.0.1" + fi + + if [ "X$RR_SIZES" = "X" ] + then + RR_SIZES="1,1" + fi + + NHOSTS=`echo $REM_HOST_LIST | awk '{printf "%d",NF}'` + GPROF_RUN_TIME=`expr $TEST_TIME - 20` +} + +usage() { +more << @EOF + +$* + + USAGE: scale_script {test_options} {hostlist} + + Measure maximum system network throughput. + + The following are optional parameters: + + -t nsec : Causes each test to be run for nsec seconds. + -gprof system : Take a gprof sample during the test. system + is the name of the kernel the system was booted + with. + -n "nproclist" : One series of tests is run for each space-separated + value in nproclist. + -r "sizelist" : One series of tests is run for each space-separated + request,reply pair in sizelist. + hostlist : A space separated list of hosts to test against. + + +|-tcp : Run/Don't run TCP tests. + +|-udp : Run/Don't run UDP tests. + +|-lla : Run/Don't run LLA tests; this option also requires + the user to specify a list of network device files + using the -d option described below. + + The following option must be provided when using the -lla option + described above: + + -d "devfilelst" : Where devfilelst is a space-separated list + of network device file pairs. Each pair in + the list contains two device file names, + separated by a comma (eg. /dev/lan0,/dev/lan1), + where the device file on the left side of the + comma is for the local system and the device + file on the right side is for the remote system. + A device file pair must be specified for each + remote host which is specified. + + Examples: + + scale_script -n "8 16" -udp LGs37U1 LGs37U2 -r "1,1 100,100" + + scale_script -t 1000 -n "16" -tcp -gprof /stand/vmunix LGs37U1 LGs37U2 + + scale_script -n 4 -lla -d /dev/lan0,/dev/lan0 /dev/lan1,/dev/lan0 \\ + LGs37U1 LGs37U2 + +@EOF +} + +check_usage() { + if [ `expr $TCP + $UDP + $LLA` -eq 0 ] + then + usage $0: ERROR: Must specify a test + exit + fi + + if [ $LLA -eq 1 ] + then + NDEV=`echo $DEVFILELIST | awk '{printf "%d",NF}'` + if [ $NDEV -ne $NHOSTS ] + then + usage $0: ERROR: Number of device files does not match number of hosts + exit + fi + fi + + for HOST in $REM_HOST_LIST + do + if [ `/etc/ping $HOST 100 1 | awk '/transmitted/{print $4}'`0 -ne 10 ] + then + usage $0: ERROR: Cannot ping host: $HOST + exit + fi + done + + if [ $GPROF -eq 1 ] + then + if [ ! -r $GPROF_KERNEL ] + then + usage $0: ERROR: Cannot find system file: $GPROF_KERNEL + exit + fi + if [ $GPROF_RUN_TIME -le 800 ] + then + echo "\nWARNING: GPROF RUN TIME LESS THAN 800 SECONDS\n" + fi + fi +} + +display_headstone() { +cat << @EOF + +$TESTNAME Aggregate REQUEST/RESPONSE TEST to $REM_HOST_LIST +Local /Remote +Socket Size Request Resp. Elapsed Trans. Num. +Send Recv Size Size Time Rate Concurrent +bytes Bytes bytes bytes secs. per sec Netperfs + +@EOF +} + +display_test_banner() { +cat << @EOF +@EOF +} + +build_sap_list() { + LSAP=4 + SAPLIST="" + PROC=0 + while [ $PROC -lt $NPROCS ] + do + PROC=`expr $PROC + 1` + LSAP=`expr $LSAP + 4` + RSAP=`expr $LSAP + 2` + SAPLIST="$SAPLIST $LSAP,$RSAP" + done +} + +start_gprof() { + if [ $GPROF -eq 1 ] + then + ( kgmon -h; kgmon -r; sleep 10; kgmon -b; sleep $GPROF_RUN_TIME; kgmon -h; kgmon -p $GPROF_KERNEL; mv gmon.out gmon.out.$TEST.$NPROCS )& + fi +} + +start_1_proc_per_host() { + HOSTNUM=0 + for HOST in $REM_HOST_LIST + do + if [ "$TEST" = "HIPPI_RR" ] + then + PROCNUM=`expr $PROCNUM + 1` + SAP=`echo $SAPLIST | awk "{print \\$$PROCNUM}"` + SAP="-s $SAP" + HOSTNUM=`expr $HOSTNUM + 1` + DEVFILE=`echo $DEVFILELIST | awk "{print \\$$HOSTNUM}"` + DEVFILE="-D $DEVFILE" + fi + $NETPERF -t $TEST -l $TEST_TIME -H $HOST -P0 -v0 -- \ + $COW $DEVFILE $SAP $RR_SIZE $SEND_SIZE $SOCKET_SIZE & + done +} + +start_n_procs_per_host() { + PROC=0 + while [ $PROC -lt $1 ] + do + PROCNUM=`expr $PROC \* ${NHOSTS}` + start_1_proc_per_host & + PROC=`expr $PROC + 1` + done + wait +} + +run_1_test() { + start_n_procs_per_host $PROCS_PER_HOST |\ + awk 'BEGIN {max=0;min=99999;sum=0;n=0} \ + {sum += $1;n++;ave=sum/n} \ + $1max {max=$1} \ + {errl=(ave-min)/ave;errm=(max-ave)/ave;err=errl} \ + errm>errl {err=errm} \ + END {printf "Aggregate throughput: %2.2f TPS +/- %2.2f %%\n",sum,err*100}' +} + +run_test_n_times() { + RETRY=0 + TEST_COUNT=0 + while [ $TEST_COUNT -lt $1 ] + do + TEST_COUNT=`expr $TEST_COUNT + 1` + start_gprof + run_1_test > .run_test_n_file + cat .run_test_n_file + ERROR_LVL=`awk '{print int($6+0.99)}' .run_test_n_file` + if [ $ERROR_LVL -gt $TOLERANCE ] + then + RETRY=`expr $RETRY + 1` + if [ $RETRY -le $MAX_RETRIES ] + then + TEST_COUNT=`expr $TEST_COUNT - 1` + TEST_TIME=`expr $TEST_TIME \* 2` + else + echo "!!!This is an INVALID RUN of the arr_script!!!" >&2 + echo "!!!UNABLE to hit TOLERANCE of " $TOLERANCE "!!!" >&2 + echo "Please select a longer initial time and try again." >&2 + exit + fi + fi + done +} + +do_req_rr_sizes() { + for S2 in $RR_SIZES + do + RR_SIZE="-r $S2" + display_test_banner $NPROCS $TEST $S2 + run_test_n_times $NTEST > .do_series_file + TPS=`awk "int(\$6+0.99)<=$TOLERANCE {print}" .do_series_file |\ + awk 'BEGIN {sum=0;n=1} \ + sum>0 {n++} \ + {sum+=$3} \ + END {printf "%2.2f\n",(sum)/(n)}'` + SOCK_SEND=`echo $SOCKET_SIZE | awk '{print $2}'` + SOCK_RECV=`echo $SOCKET_SIZE | awk '{print $4}'` + REQ_SIZE=`echo $S2 | awk -F"," '{print $1}'` + RSP_SIZE=`echo $S2 | awk -F"," '{print $2}'` + echo $SOCK_SEND $SOCK_RECV $REQ_SIZE $RSP_SIZE $TEST_TIME $TPS $PROCS |\ + awk '{printf "%5d %5d %5d %5d %5d %8.2f %5d",$1,$2,$3,$4,$5,$6,$7}' + done +} + +tcp_test() { + #Run the TCP RR tests + TEST="TCP_RR" + SEND_SIZE="" + SOCKET_SIZE="-s 8192 -S 8192" + COW="-V" + do_req_rr_sizes + echo +} + +udp_test() { + #Run the UDP RR tests + TEST="UDP_RR" + SEND_SIZE="" + SOCKET_SIZE="-s 9216 -S 9216" + COW="-V" + do_req_rr_sizes + echo +} + +lla_test() { + #Run the UDP RR tests + TEST="HIPPI_RR" + SEND_SIZE="" + SOCKET_SIZE="" + COW="" + build_sap_list + do_req_rr_sizes + echo +} + +do_req_procs() { + if [ $TCP -eq 1 ] + then + TESTNAME="TCP" + display_headstone + for PROCS in $NPROC_LIST + do + #Determine number of procs per host + PROCS_PER_HOST=`echo $PROCS $REM_HOST_LIST | awk '{printf "%d",($1+NF-2)/(NF-1)}'` + NPROCS=`expr $PROCS_PER_HOST \* $NHOSTS` + tcp_test + done + fi + + if [ $UDP -eq 1 ] + then + TESTNAME="UDP" + display_headstone + for PROCS in $NPROC_LIST + do + #Determine number of procs per host + PROCS_PER_HOST=`echo $PROCS $REM_HOST_LIST | awk '{printf "%d",($1+NF-2)/(NF-1)}'` + NPROCS=`expr $PROCS_PER_HOST \* $NHOSTS` + udp_test + done + fi + + if [ $LLA -eq 1 ] + then + TESTNAME="LLA" + display_headstone + for PROCS in $NPROC_LIST + do + #Determine number of procs per host + PROCS_PER_HOST=`echo $PROCS $REM_HOST_LIST | awk '{printf "%d",($1+NF-2)/(NF-1)}'` + NPROCS=`expr $PROCS_PER_HOST \* $NHOSTS` + lla_test + done + fi +} + +###################################################################### + +init_parms + +PARMS="${0##*/} ${@}" + +# Parse the command line +while [ $# != 0 ] +do + case $1 in + \-gprof) GPROF=1 + GPROF_KERNEL=$2 + shift + ;; + \-t) TEST_TIME=$2 + shift + ;; + \-n) NPROC_LIST="$NPROC_LIST $2" + shift + ;; + \+lla) LLA=1 + ;; + \+tcp) TCP=1 + ;; + \+udp) UDP=1 + ;; + \-lla) LLA=0 + ;; + \-tcp) TCP=0 + ;; + \-udp) UDP=0 + ;; + \-d) DEVFILELIST="$DEVFILELIST $2" + shift + ;; + \-r) RR_SIZES="$RR_SIZES $2" + shift + ;; + \-*) usage $0: ERROR: Unexpected paramter: $1 + exit + ;; + *) REM_HOST_LIST="$REM_HOST_LIST $1" + ;; + esac + shift +done + +set_default_parms +check_usage +do_req_procs + diff --git a/doc/examples/packet_byte_script b/doc/examples/packet_byte_script new file mode 100755 index 0000000..a76b49a --- /dev/null +++ b/doc/examples/packet_byte_script @@ -0,0 +1,202 @@ +#!/bin/sh +# +# This script runs a series of netperf tests intended to gather the +# raw material necessary to arrive at estimates for the cost of +# sending and receiving a TCP segment, the cost of each additional byte +# and the cost of each incremental segment. +# +# there are a number of data points gathered by this script - it might +# run for a considerable length of time. +# +# rick jones 4/99 +# +# teach it about processor affinity and the TCP_MSS test +# rick jones 2007-11-08 +# + +if [ $# -gt 2 ]; then + echo "try again, correctly -> packet_byte_script hostname [CPU]" + exit 1 +fi + +if [ $# -eq 0 ]; then + echo "try again, correctly -> packet_byte_script hostname [CPU]" + exit 1 +fi + +# where is netperf +NETPERF_DIR=${NETPERF_DIR:=/opt/netperf2/bin} + + +# at what port will netserver be waiting? If you decide to run +# netserver at a differnet port than the default of 12865, then set +# the value of NETPERF_PORT apropriately +# NETPERF_PORT="-p some_other_portnum" +NETPERF_PORT=${NETPERF_PORT:=""} + + +# The test length in seconds +NETPERF_TIME=${NETPERF_TIME:=30} + +# How accurate we want the estimate of performance: +# maximum and minimum test iterations (-i) +# confidence level (99 or 95) and interval (percent) +NETPERF_STATS=${NETPERF_STATS:="-i 30,3 -I 99,5"} + +# The socket sizes that we will be testing - using -1 will let it +# be the system default. +NETPERF_SKTS=${NETPERF_SKTS:="-1"} + +# The CPU affinity to be applied +NETPERF_AFFINITY=${NETPERF_AFFINITY:=""} + +# NETPERF_CMD is an amalgam of previous variables +NETPERF_CMD="${NETPERF_DIR}/netperf ${NETPERF_AFFINITY}" + +# if there are two parms, parm one it the hostname and parm two will +# be a CPU indicator. actually, anything as a second parm will cause +# the CPU to be measured, but we will "advertise" it should be "CPU" + +if [ $# -eq 2 ]; then + REM_HOST=$1 + LOC_CPU="-c" + REM_CPU="-C" +fi + +if [ $# -eq 1 ]; then + REM_HOST=$1 +fi + +MSS=`$NETPERF_CMD -H $REM_HOST -t TCP_MSS -P 0 -v 0` + +# The request,response sizes that we will be using. The netperf +# command parser will treat "1" the same as "1,1" - I use 1,1 to +# remember that it is "request,response" + +# start at one and multiply by two on our way to the MSS +bar=1 +while [ $bar -lt $MSS ] +do + NETPERF_REQS="${NETPERF_REQS} $bar" + bar=`expr $bar \* 2` +done + +# and now multiples of the mss and that plus one +for i in 1 2 3 +do + bar=`expr $MSS \* $i` + NETPERF_REQS="${NETPERF_REQS} $bar" + NETPERF_REQS="${NETPERF_REQS} `expr $bar + 1`" +done + +bar=1 +while [ $bar -lt $MSS ] +do + NETPERF_RESP="${NETPERF_RESP} $bar" + bar=`expr $bar \* 2` +done + +for i in 1 2 3 +do + bar=`expr $MSS \* $i` + NETPERF_RESP="${NETPERF_RESP} $bar" + NETPERF_RESP="${NETPERF_RESP} `expr $bar + 1`" +done + + + +# If we are measuring CPU utilization, then we can save beaucoup +# time by saving the results of the CPU calibration and passing +# them in during the real tests. So, we execute the new CPU "tests" +# of netperf and put the values into shell vars. +case $LOC_CPU in +\-c) LOC_RATE=`$NETPERF_CMD $PORT -t LOC_CPU`;; +*) LOC_RATE="" +esac + +case $REM_CPU in +\-C) REM_RATE=`$NETPERF_CMD $PORT -t REM_CPU -H $REM_HOST`;; +*) REM_RATE="" +esac + +# This disables header display +NO_HDR="-P 0" +NO_HDR="" + +for SOCKET_SIZE in $NETPERF_SKTS + do + echo + echo ------------------------------------------------------ + echo Testing with the following command line: + # we echo the command line for cut and paste to th database + echo $NETPERF_CMD $NETPERF_PORT -l $NETPERF_TIME -H $REM_HOST -t TCP_RR \ + $LOC_CPU $LOC_RATE $REM_CPU $REM_RATE $NETPERF_STATS --\ + -s $SOCKET_SIZE -S $SOCKET_SIZE + echo + echo and these settings for send sizes $NETPERF_REQS + echo + + for REQ in $NETPERF_REQS + do + # since we have the confidence interval stuff, we do not + # need to repeat a test multiple times from the shell + $NETPERF_CMD $NETPERF_PORT -l $NETPERF_TIME -H $REM_HOST $NO_HDR \ + -t TCP_RR $LOC_CPU $LOC_RATE $REM_CPU $REM_RATE $NETPERF_STATS --\ + -r ${REQ},1 -s $SOCKET_SIZE -S $SOCKET_SIZE + NO_HDR="-P 0" + done + echo + echo ------------------------------------------------------ + NO_HDR="" + echo Testing with the following command line: + # we echo the command line for cut and paste to th database + echo $NETPERF_CMD $NETPERF_PORT -l $NETPERF_TIME -H $REM_HOST -t TCP_RR \ + $LOC_CPU $LOC_RATE $REM_CPU $REM_RATE $NETPERF_STATS --\ + -s $SOCKET_SIZE -S $SOCKET_SIZE + echo and these settings for response sizes $NETPERF_RESP + echo + for RESP in $NETPERF_RESP + do + # since we have the confidence interval stuff, we do not + # need to repeat a test multiple times from the shell + $NETPERF_CMD $PORT -l $NETPERF_TIME -H $REM_HOST $NO_HDR \ + -t TCP_RR $LOC_CPU $LOC_RATE $REM_CPU $REM_RATE $NETPERF_STATS --\ + -r 1,${RESP} -s $SOCKET_SIZE -S $SOCKET_SIZE + NO_HDR="-P 0" + done + echo + echo ------------------------------------------------------ + NO_HDR="" + echo Testing with the following command line: + # we echo the command line for cut and paste to th database + echo $NETPERF_CMD $NETPERF_PORT -l $NETPERF_TIME -H $REM_HOST -t TCP_STREAM\ + $LOC_CPU $LOC_RATE $REM_CPU $REM_RATE $NETPERF_STATS --\ + -s $SOCKET_SIZE -S $SOCKET_SIZE + echo and these settings for response sizes $NETPERF_RESP + echo + for REQ in $NETPERF_REQS + do + # since we have the confidence interval stuff, we do not + # need to repeat a test multiple times from the shell + $NETPERF_CMD $PORT -l $NETPERF_TIME -H $REM_HOST $NO_HDR \ + -t TCP_STREAM $LOC_CPU $LOC_RATE $REM_CPU $REM_RATE $NETPERF_STATS --\ + -m ${REQ} -s $SOCKET_SIZE -S $SOCKET_SIZE -D + NO_HDR="-P 0" + done +done + +# The test length in seconds for the CRR test, which needs to be +# longer for a connect/request/response test + +NETPERF_CRR_TIME=${NETPERF_CRR_TIME:=120} + +# now we do the TCP_CRR test +echo +echo ------------------------------------------------------ +echo $NETPERF_CMD $NETPERF_PORT -l $NETPERF_CRR_TIME -H $REM_HOST -t TCP_CRR\ + $LOC_CPU $LOC_RATE $REM_CPU $REM_RATE $NETPERF_STATS --\ + -s $SOCKET_SIZE -S $SOCKET_SIZE +echo +$NETPERF_CMD $NETPERF_PORT -l $NETPERF_CRR_TIME -H $REM_HOST -t TCP_CRR\ + $LOC_CPU $LOC_RATE $REM_CPU $REM_RATE $NETPERF_STATS --\ + -s $SOCKET_SIZE -S $SOCKET_SIZE diff --git a/doc/examples/sctp_stream_script b/doc/examples/sctp_stream_script new file mode 100644 index 0000000..ebd850b --- /dev/null +++ b/doc/examples/sctp_stream_script @@ -0,0 +1,104 @@ +#!/bin/sh +# +# This is an example script for using netperf. Feel free to modify it +# as necessary, but I would suggest that you copy this one first. +# +# This version has been modified to take advantage of the confidence +# interval support in revision 2.0 of netperf. it has also been altered +# to make submitting its resutls to the netperf database easier +# raj 11/94 +# +# usage: tcp_stream_script hostname [CPU] +# + +if [ $# -gt 2 ]; then + echo "try again, correctly -> sctp_stream_script hostname [CPU]" + exit 1 +fi + +if [ $# -eq 0 ]; then + echo "try again, correctly -> sctp_stream_script hostname [CPU]" + exit 1 +fi + +# where the programs are +#NETHOME=/usr/local/netperf +#NETHOME="/opt/netperf" +NETHOME=. + +# at what port will netserver be waiting? If you decide to run +# netserver at a differnet port than the default of 12865, then set +# the value of PORT apropriately +#PORT="-p some_other_portnum" +PORT="" + +# The test length in seconds +TEST_TIME=60 + +# How accurate we want the estimate of performance: +# maximum and minimum test iterations (-i) +# confidence level (99 or 95) and interval (percent) +STATS_STUFF="-i 10,2 -I 99,5" + +# The socket sizes that we will be testing +SOCKET_SIZES="57344 32768 8192" + +# The send sizes that we will be using +SEND_SIZES="4096 8192 32768" + +# if there are two parms, parm one it the hostname and parm two will +# be a CPU indicator. actually, anything as a second parm will cause +# the CPU to be measured, but we will "advertise" it should be "CPU" + +if [ $# -eq 2 ]; then + REM_HOST=$1 + LOC_CPU="-c" + REM_CPU="-C" +fi + +if [ $# -eq 1 ]; then + REM_HOST=$1 +fi + +# If we are measuring CPU utilization, then we can save beaucoup +# time by saving the results of the CPU calibration and passing +# them in during the real tests. So, we execute the new CPU "tests" +# of netperf and put the values into shell vars. +case $LOC_CPU in +\-c) LOC_RATE=`$NETHOME/netperf $PORT -t LOC_CPU`;; +*) LOC_RATE="" +esac + +case $REM_CPU in +\-C) REM_RATE=`$NETHOME/netperf $PORT -t REM_CPU -H $REM_HOST`;; +*) REM_RATE="" +esac + +# this will disable headers +NO_HDR="-P 0" + +for SOCKET_SIZE in $SOCKET_SIZES + do + for SEND_SIZE in $SEND_SIZES + do + echo + echo ------------------------------------ + echo + # we echo the command line for cut and paste + echo $NETHOME/netperf $PORT -l $TEST_TIME -H $REM_HOST -t SCTP_STREAM\ + $LOC_CPU $LOC_RATE $REM_CPU $REM_RATE $STATS_STUFF --\ + -m $SEND_SIZE -s $SOCKET_SIZE -S $SOCKET_SIZE + + echo + # since we have the confidence interval stuff, we do not + # need to repeat a test multiple times from the shell + $NETHOME/netperf $PORT -l $TEST_TIME -H $REM_HOST -t SCTP_STREAM\ + $LOC_CPU $LOC_RATE $REM_CPU $REM_RATE $STATS_STUFF --\ + -m $SEND_SIZE -s $SOCKET_SIZE -S $SOCKET_SIZE + + done + done +echo If you wish to submit these results to the netperf database at +echo http://www.cup.hp.com/netperf/NetperfPage.html, please submit each +echo datapoint individually. Individual datapoints are separated by +echo lines of dashes. diff --git a/doc/examples/snapshot_script b/doc/examples/snapshot_script new file mode 100755 index 0000000..0fe6357 --- /dev/null +++ b/doc/examples/snapshot_script @@ -0,0 +1,226 @@ +#!/bin/sh +#set -x +# +# This is a script to generate a quick "snapshot" of performance for a +# pair of nodes. At first, it will perform the following tests: +# +# TCP Stream test with 56KB socket buffers and 4KB sends +# TCP Stream test with 32KB socket buffers and 4KB sends +# TCP Request/Response test with 1 byte requests and 1 byte responses +# UDP Request/Response test with 1 byte requests and 1 byte responses +# UDP Request/Response test with 516 byte requests and 4 byte responses +# UDP Stream test with 32KB socket buffers and 4KB sends +# UDP Stream test with 32KB socket buffers and 1KB sends +# +# All tests will run for sixty seconds. Confidence intervals are used +# to insure the repeatability of the test. This means that the soonest +# the script will be finished is 21 minutes. +# +# This script takes two parameters. The first parm is the name of the +# remote host. It is a required parameter. The second will either +# enable or disable CPU utilization measurements. It is an optional +# parameter which defaults to no CPU utilization measurements. +# +# usage: snapshot_script hostname [CPU] +# +# mod 6/29/95 - echo progress information to stderr so that we can +# see forward progress even when the results are +# re-directed to a file +# +# mod 5/27/96 - switch from NETHOME to NETPERF and take the user's value +# if it is already set +# +# mod 8/12/96 - fix the default netperf command variable so it finds the +# executable and not the directory... +# +# First, let us set-up some of the defaults +# +# where is netperf installed, there are a few possible places: + +NETPERF_CMD=${NETPERF_CMD:=/opt/netperf/netperf} + + +# there should be no more than two parms passed + +if [ $# -gt 2 ]; then + echo "try again, correctly -> snapshot_script hostname [CPU]" + exit 1 +fi + +if [ $# -eq 0 ]; then + echo "try again, correctly -> snapshot_script hostname [CPU]" + exit 1 +fi + +# if there are two parms, parm one it the hostname and parm two will +# be a CPU indicator. actuall, anything as a second parm will cause +# the CPU to be measured, but we will "advertise" it should be "CPU" + +if [ $# -eq 2 ]; then + REM_HOST=$1 + LOC_CPU="-c" + REM_CPU="-C" +fi + +if [ $# -eq 1 ]; then + REM_HOST=$1 +fi + +# at what port will netserver be waiting? If you decide to run +# netserver at a differnet port than the default of 12865, then set +# the value of PORT apropriately +#NETPERF_PORT="-p some_other_portnum" +NETPERF_PORT=${NETPERF_PORT:=""} + +# How accurate we want the estimate of performance: +# maximum and minimum test iterations (-i) +# confidence level (99 or 95) and interval (percent) +STATS_STUFF="-i 10,3 -I 99,5" + +# length in time of the test - should be 60 seconds +NETPERF_TIME=${NETPERF_TIME:=60} + +# where is the bitbucket? +BITBUCKET="/dev/null" + +# announce start of test +echo Netperf snapshot script started at `date` >&2 + +# If we are measuring CPU utilization, then we can save beaucoup time +# by saving the results of the CPU calibration and passing them in +# during the real tests. So, we execute the new CPU "tests" of netperf +# and put the values into shell vars. + +case $LOC_CPU in +\-c) LOC_RATE=`$NETPERF_CMD $NETPERF_PORT -t LOC_CPU`;; +*) LOC_RATE="" +esac + +case $REM_CPU in +\-C) REM_RATE=`$NETPERF_CMD $NETPERF_PORT -t REM_CPU -H $REM_HOST`;; +*) REM_RATE="" +esac + +# We will perform three twenty second warm-up tests at this point, but +# we will not display the results of those tests. This is unlikely to +# make any difference in the results except right after a system +# reboot, but this is supposed to be rather "general." We will do a +# TCP stream and a TCP req/resp test + +WARM_TIME="10" + +$NETPERF_CMD $NETPERF_PORT -l $WARM_TIME -t TCP_STREAM -H $REM_HOST -- \ + -s 32768 -S 32768 -m 4096 > ${BITBUCKET} +$NETPERF_CMD $NETPERF_PORT -l $WARM_TIME -t TCP_STREAM -H $REM_HOST -- \ + -s 32768 -S 32768 -m 96 > ${BITBUCKET} +$NETPERF_CMD $NETPERF_PORT -l $WARM_TIME -t TCP_RR -H $REM_HOST -- \ + -r 1,1 > ${BITBUCKET} + +# The warm-ups are complete, so perform the real tests first, the +# stream tests, then the request/response + +echo Starting 56x4 TCP_STREAM tests at `date` >&2 + +# a 56x4 TCP_STREAM test +echo +echo ------------------------------------ +echo Testing with the following command line: +echo $NETPERF_CMD $NETPERF_PORT -t TCP_STREAM -l $NETPERF_TIME -H $REM_HOST \ + $LOC_CPU $LOC_RATE $REM_CPU $REM_RATE $STATS_STUFF -- \ + -s 57344 -S 57344 -m 4096 +echo +$NETPERF_CMD $NETPERF_PORT -t TCP_STREAM -l $NETPERF_TIME -H $REM_HOST \ + $LOC_CPU $LOC_RATE $REM_CPU $REM_RATE $STATS_STUFF -- \ + -s 57344 -S 57344 -m 4096 +echo +echo +# a 32x4 TCP_STREAM test +echo Starting 32x4 TCP_STREAM tests at `date` >&2 +echo +echo ------------------------------------ +echo Testing with the following command line: +echo $NETPERF_CMD $NETPERF_PORT -t TCP_STREAM -l $NETPERF_TIME -H $REM_HOST \ + $LOC_CPU $LOC_RATE $REM_CPU $REM_RATE $STATS_STUFF -- \ + -s 32768 -S 32768 -m 4096 +echo +$NETPERF_CMD $NETPERF_PORT -t TCP_STREAM -l $NETPERF_TIME -H $REM_HOST \ + $LOC_CPU $LOC_RATE $REM_CPU $REM_RATE $STATS_STUFF -- \ + -s 32768 -S 32768 -m 4096 +echo +echo +# a single-byte TCP_RR +echo Starting 1,1 TCP_RR tests at `date` >&2 +echo +echo ------------------------------------ +echo Testing with the following command line: +echo $NETPERF_CMD $NETPERF_PORT -t TCP_RR -l $NETPERF_TIME -H $REM_HOST \ + $LOC_CPU $LOC_RATE $REM_CPU $REM_RATE $STATS_STUFF -- \ + -r 1,1 +echo +$NETPERF_CMD $NETPERF_PORT -t TCP_RR -l $NETPERF_TIME -H $REM_HOST \ + $LOC_CPU $LOC_RATE $REM_CPU $REM_RATE $STATS_STUFF -- \ + -r 1,1 +echo +echo +echo Starting 1,1 UDP_RR tests at `date` >&2 +echo +echo ------------------------------------ +echo Testing with the following command line: +# a single-byte UDP_RR +echo $NETPERF_CMD $NETPERF_PORT -t UDP_RR -l $NETPERF_TIME -H $REM_HOST \ + $LOC_CPU $LOC_RATE $REM_CPU $REM_RATE $STATS_STUFF -- \ + -r 1,1 +echo +$NETPERF_CMD $NETPERF_PORT -t UDP_RR -l $NETPERF_TIME -H $REM_HOST \ + $LOC_CPU $LOC_RATE $REM_CPU $REM_RATE $STATS_STUFF -- \ + -r 1,1 +echo +echo +# a UDP_RR test much like tftp +echo Starting 512,4 UDP_RR tests at `date` >&2 +echo +echo ------------------------------------ +echo Testing with the following command line: +echo $NETPERF_CMD $NETPERF_PORT -t UDP_RR -l $NETPERF_TIME -H $REM_HOST \ + $LOC_CPU $LOC_RATE $REM_CPU $REM_RATE $STATS_STUFF -- \ + -r 516,4 +echo +$NETPERF_CMD $NETPERF_PORT -t UDP_RR -l $NETPERF_TIME -H $REM_HOST \ + $LOC_CPU $LOC_RATE $REM_CPU $REM_RATE $STATS_STUFF -- -r 516,4 +# a 32x4 UDP_STREAM test +echo Starting 32x4 UDP_STREAM tests at `date` >&2 +echo +echo ------------------------------------ +echo Testing with the following command line: +echo $NETPERF_CMD $NETPERF_PORT -t UDP_STREAM -l $NETPERF_TIME -H $REM_HOST \ + $LOC_CPU $LOC_RATE $REM_CPU $REM_RATE $STATS_STUFF -- \ + -s 32768 -S 32768 -m 4096 +echo +$NETPERF_CMD $NETPERF_PORT -t UDP_STREAM -l $NETPERF_TIME -H $REM_HOST \ + $LOC_CPU $LOC_RATE $REM_CPU $REM_RATE $STATS_STUFF -- \ + -s 32768 -S 32768 -m 4096 +echo +echo +# a 32x1 UDP_STREAM test +echo Starting 32x1 UDP_STREAM tests at `date` >&2 +echo +echo ------------------------------------ +echo Testing with the following command line: +echo $NETPERF_CMD $NETPERF_PORT -t UDP_STREAM -l $NETPERF_TIME -H $REM_HOST \ + $LOC_CPU $LOC_RATE $REM_CPU $REM_RATE $STATS_STUFF -- \ + -s 32768 -S 32768 -m 1024 +echo +$NETPERF_CMD $NETPERF_PORT -t UDP_STREAM -l $NETPERF_TIME -H $REM_HOST \ + $LOC_CPU $LOC_RATE $REM_CPU $REM_RATE $STATS_STUFF -- \ + -s 32768 -S 32768 -m 1024 +echo +echo + +# and that's that +echo Tests completed at `date` >&2 + +echo +echo If you wish to submit these results to the netperf database at +echo http://www.cup.hp.com/netperf/NetperfPage.html, please submit each +echo datapoint individually. Individual datapoints are separated by +echo lines of dashes. diff --git a/doc/examples/tcp_range_script b/doc/examples/tcp_range_script new file mode 100755 index 0000000..b4ec140 --- /dev/null +++ b/doc/examples/tcp_range_script @@ -0,0 +1,113 @@ +#!/bin/sh +# +# stream_range +# +# generate a whole lot of numbers from netperf to see the effects +# of send size on thruput +# + +# +# usage : tcp_stream_range hostname [CPU] +# + +if [ $# -gt 2 ]; then + echo "try again, correctly -> tcp_stream_range hostname [CPU]" + exit 1 +fi + +if [ $# -eq 0 ]; then + echo "try again, correctly -> tcp_stream_range hostname [CPU]" + exit 1 +fi + +# if there are two parms, parm one it the hostname and parm two will +# be a CPU indicator. actually, anything as a second parm will cause +# the CPU to be measured, but we will "advertise" it should be "CPU" + +if [ $# -eq 2 ]; then + REM_HOST=$1 + LOC_CPU="-c" + REM_CPU="-C" +fi + +if [ $# -eq 1 ]; then + REM_HOST=$1 +fi + +# at what port will netserver be waiting? If you decide to run +# netserver at a differnet port than the default of 12865, then set +# the value of PORT apropriately +#PORT="-p some_other_portnum" +PORT="" + +# where is netperf, and are there any "constant" options such as +# the netserver port number +#NETHOME=/usr/etc/net_perf +NETHOME="." +NETPERF=$NETHOME/netperf $PORT + +# How accurate we want the estimate of performance: +# maximum and minimum test iterations (-i) +# confidence level (99 or 95) and interval (percent) +STATS_STUFF="-i 10,2 -I 99,3" + +# +# some stuff for the arithmetic +# +# we start at start, and then multiply by MULT and add ADD. by changing +# these numbers, we can double each time, or increase by a fixed +# amount, or go up by 4x, whatever we like... +# +START=1 + +END=65536 + +MULT=4 + +ADD=0 + +# If we are measuring CPU utilization, then we can save beaucoup +# time by saving the results of the CPU calibration and passing +# them in during the real tests. So, we execute the new CPU "tests" +# of netperf and put the values into shell vars. +case $LOC_CPU in +\-c) LOC_RATE=`$NETPERF -t LOC_CPU`;; +*) LOC_RATE="" +esac + +case $REM_CPU in +\-C) REM_RATE=`$NETPERF -t REM_CPU -H $REM_HOST`;; +*) REM_RATE="" +esac + +TIME="60" + +# +# the maximum socket buffer size is system dependent. for the +# "cannonical" tests we use 32KB, but this can be altered +# +SOCKET_SIZE="-s 32768 -S 32768" + +MESSAGE=$START +while [ $MESSAGE -le $END ]; do + echo + echo ------------------------------------ + echo Testing with the following command line: + echo $NETPERF -l $TIME -H $REM_HOST -t TCP_STREAM\ + $LOC_CPU $LOC_RATE $REM_CPU $REM_RATE $STATS_STUFF --\ + -m $MESSAGE $SOCKET_SIZE + echo + $NETPERF -l $TIME -H $REM_HOST -t TCP_STREAM\ + $LOC_CPU $LOC_RATE $REM_CPU $REM_RATE $STATS_STUFF --\ + -m $MESSAGE $SOCKET_SIZE + + MESSAGE=`expr $MESSAGE + $ADD` + MESSAGE=`expr $MESSAGE \* $MULT` + +done +echo +echo If you wish to submit these results to the netperf database at +echo http://www.cup.hp.com/netperf/NetperfPage.html, please submit each +echo datapoint individually. Individual datapoints are separated by +echo lines of dashes. + diff --git a/doc/examples/tcp_rr_script b/doc/examples/tcp_rr_script new file mode 100755 index 0000000..1b12a6f --- /dev/null +++ b/doc/examples/tcp_rr_script @@ -0,0 +1,107 @@ +#!/bin/sh +# +# This is an example script for using netperf. Feel free to modify it +# as necessary, but I would suggest that you copy this one first. +# +# +# This version has been modified to take advantage of the confidence +# interval support in revision 2.0 of netperf. it has also been altered +# to make submitting its resutls to the netperf database easier +# raj 11/94 +# +# usage: tcp_rr_script hostname [CPU] +# + +if [ $# -gt 2 ]; then + echo "try again, correctly -> tcp_rr_script hostname [CPU]" + exit 1 +fi + +if [ $# -eq 0 ]; then + echo "try again, correctly -> tcp_rr_script hostname [CPU]" + exit 1 +fi + +# where the programs are +#NETHOME=/usr/local/netperf +#NETHOME="/opt/netperf" +NETHOME=. + +# at what port will netserver be waiting? If you decide to run +# netserver at a differnet port than the default of 12865, then set +# the value of PORT apropriately +#PORT="-p some_other_portnum" +PORT="" + +# The test length in seconds +TEST_TIME=60 + +# How accurate we want the estimate of performance: +# maximum and minimum test iterations (-i) +# confidence level (99 or 95) and interval (percent) +STATS_STUFF="-i 10,3 -I 99,5" + +# The socket sizes that we will be testing - using zero will let it +# be the system default. +SOCKET_SIZES="0" + +# The request,response sizes that we will be using. The netperf +# command parser will treat "1" the same as "1,1" - I use 1,1 to +# remember that it is "request,response" +RR_SIZES="1,1 64,64 100,200 128,8192" + +# if there are two parms, parm one it the hostname and parm two will +# be a CPU indicator. actually, anything as a second parm will cause +# the CPU to be measured, but we will "advertise" it should be "CPU" + +if [ $# -eq 2 ]; then + REM_HOST=$1 + LOC_CPU="-c" + REM_CPU="-C" +fi + +if [ $# -eq 1 ]; then + REM_HOST=$1 +fi + +# If we are measuring CPU utilization, then we can save beaucoup +# time by saving the results of the CPU calibration and passing +# them in during the real tests. So, we execute the new CPU "tests" +# of netperf and put the values into shell vars. +case $LOC_CPU in +\-c) LOC_RATE=`$NETHOME/netperf $PORT -t LOC_CPU`;; +*) LOC_RATE="" +esac + +case $REM_CPU in +\-C) REM_RATE=`$NETHOME/netperf $PORT -t REM_CPU -H $REM_HOST`;; +*) REM_RATE="" +esac + +# This disables header display +NO_HDR="-P 0" + +for SOCKET_SIZE in $SOCKET_SIZES + do + for RR_SIZE in $RR_SIZES + do + echo + echo ------------------------------------------------------ + echo Testing with the following command line: + # we echo the command line for cut and paste to th database + echo $NETHOME/netperf $PORT -l $TEST_TIME -H $REM_HOST -t TCP_RR \ + $LOC_CPU $LOC_RATE $REM_CPU $REM_RATE $STATS_STUFF --\ + -r $RR_SIZE -s $SOCKET_SIZE -S $SOCKET_SIZE + echo + # since we have the confidence interval stuff, we do not + # need to repeat a test multiple times from the shell + $NETHOME/netperf $PORT -l $TEST_TIME -H $REM_HOST -t TCP_RR \ + $LOC_CPU $LOC_RATE $REM_CPU $REM_RATE $STATS_STUFF --\ + -r $RR_SIZE -s $SOCKET_SIZE -S $SOCKET_SIZE + done +done +echo +echo If you wish to submit these results to the netperf database at +echo http://www.cup.hp.com/netperf/NetperfPage.html, please submit each +echo datapoint individually. Individual datapoints are separated by +echo lines of dashes. diff --git a/doc/examples/tcp_stream_script b/doc/examples/tcp_stream_script new file mode 100755 index 0000000..c728cb7 --- /dev/null +++ b/doc/examples/tcp_stream_script @@ -0,0 +1,104 @@ +#!/bin/sh +# +# This is an example script for using netperf. Feel free to modify it +# as necessary, but I would suggest that you copy this one first. +# +# This version has been modified to take advantage of the confidence +# interval support in revision 2.0 of netperf. it has also been altered +# to make submitting its resutls to the netperf database easier +# raj 11/94 +# +# usage: tcp_stream_script hostname [CPU] +# + +if [ $# -gt 2 ]; then + echo "try again, correctly -> tcp_stream_script hostname [CPU]" + exit 1 +fi + +if [ $# -eq 0 ]; then + echo "try again, correctly -> tcp_stream_script hostname [CPU]" + exit 1 +fi + +# where the programs are +#NETHOME=/usr/local/netperf +#NETHOME="/opt/netperf" +NETHOME=. + +# at what port will netserver be waiting? If you decide to run +# netserver at a different port than the default of 12865, then set +# the value of PORT apropriately +#PORT="-p some_other_portnum" +PORT="" + +# The test length in seconds +TEST_TIME=60 + +# How accurate we want the estimate of performance: +# maximum and minimum test iterations (-i) +# confidence level (99 or 95) and interval (percent) +STATS_STUFF="-i 10,2 -I 99,5" + +# The socket sizes that we will be testing +SOCKET_SIZES="128K 57344 32768 8192" + +# The send sizes that we will be using +SEND_SIZES="4096 8192 32768" + +# if there are two parms, parm one it the hostname and parm two will +# be a CPU indicator. actually, anything as a second parm will cause +# the CPU to be measured, but we will "advertise" it should be "CPU" + +if [ $# -eq 2 ]; then + REM_HOST=$1 + LOC_CPU="-c" + REM_CPU="-C" +fi + +if [ $# -eq 1 ]; then + REM_HOST=$1 +fi + +# If we are measuring CPU utilization, then we can save beaucoup +# time by saving the results of the CPU calibration and passing +# them in during the real tests. So, we execute the new CPU "tests" +# of netperf and put the values into shell vars. +case $LOC_CPU in +\-c) LOC_RATE=`$NETHOME/netperf $PORT -t LOC_CPU`;; +*) LOC_RATE="" +esac + +case $REM_CPU in +\-C) REM_RATE=`$NETHOME/netperf $PORT -t REM_CPU -H $REM_HOST`;; +*) REM_RATE="" +esac + +# this will disable headers +NO_HDR="-P 0" + +for SOCKET_SIZE in $SOCKET_SIZES + do + for SEND_SIZE in $SEND_SIZES + do + echo + echo ------------------------------------ + echo + # we echo the command line for cut and paste + echo $NETHOME/netperf $PORT -l $TEST_TIME -H $REM_HOST -t TCP_STREAM\ + $LOC_CPU $LOC_RATE $REM_CPU $REM_RATE $STATS_STUFF --\ + -m $SEND_SIZE -s $SOCKET_SIZE -S $SOCKET_SIZE + + echo + # since we have the confidence interval stuff, we do not + # need to repeat a test multiple times from the shell + $NETHOME/netperf $PORT -l $TEST_TIME -H $REM_HOST -t TCP_STREAM\ + $LOC_CPU $LOC_RATE $REM_CPU $REM_RATE $STATS_STUFF --\ + -m $SEND_SIZE -s $SOCKET_SIZE -S $SOCKET_SIZE + + done + done +echo If you wish to submit these results to the netperf database at +echo http://www.cup.hp.com/netperf/NetperfPage.html, please submit each +echo datapoint individually. Individual datapoints are separated by +echo lines of dashes. diff --git a/doc/examples/udp_rr_script b/doc/examples/udp_rr_script new file mode 100755 index 0000000..0248677 --- /dev/null +++ b/doc/examples/udp_rr_script @@ -0,0 +1,107 @@ +#!/bin/sh +# +# This is an example script for using netperf. Feel free to modify it +# as necessary, but I would suggest that you copy this one first. +# +# +# uncomment the next line if you think the script is broken +#set -x + + +if [ $# -gt 2 ]; then + echo "try again, correctly -> udp_rr_script hostname [CPU]" + exit 1 +fi + +if [ $# -eq 0 ]; then + echo "try again, correctly -> udp_rr_script hostname [CPU]" + exit 1 +fi + +# where the programs are + +#NETHOME=/usr/local/netperf +#NETHOME="/opt/netperf" +NETHOME="." + +# at what port will netserver be waiting? If you decide to run +# netserver at a differnet port than the default of 12865, then set +# the value of PORT apropriately +#PORT="-p some_other_portnum" +PORT="" + + +# The test length in seconds + +TEST_TIME=60 + +# How accurate we want the estimate of performance: +# maximum and minimum test iterations (-i) +# confidence level (99 or 95) and interval (percent) + +STATS_STUFF="-i 10,2 -I 99,10" + +# The socket sizes that we will be testing - -1 means use default +# not much point in changing the socket buffer for a UDP request/ +# response test - unless you want to have requests/responses which +# are larger than the default + +SOCKET_SIZES="-1" + +# The send sizes that we will be using + +RR_SIZES="1,1 64,64 100,200 1024,1024" + +# if there are two parms, parm one it the hostname and parm two will +# be a CPU indicator. actually, anything as a second parm will cause +# the CPU to be measured, but we will "advertise" it should be "CPU" + +if [ $# -eq 2 ]; then + REM_HOST=$1 + LOC_CPU="-c" + REM_CPU="-C" +fi + +if [ $# -eq 1 ]; then + LOC_CPU="" + REM_CPU="" + REM_HOST=$1 +fi + +# If we are measuring CPU utilization, then we can save beaucoup +# time by saving the results of the CPU calibration and passing +# them in during the real tests. So, we execute the new CPU "tests" +# of netperf and put the values into shell vars. +case $LOC_CPU in +\-c) LOC_RATE=`$NETHOME/netperf $PORT -t LOC_CPU`;; +*) LOC_RATE="" +esac + +case $REM_CPU in +\-C) REM_RATE=`$NETHOME/netperf $PORT -t REM_CPU -H $REM_HOST`;; +*) REM_RATE="" +esac + +# This turns-off the display headers +NO_HDR="-P 0" + +for SOCKET_SIZE in $SOCKET_SIZES +do + for RR_SIZE in $RR_SIZES + do + echo + echo ------------------------------------------------------ + echo Testing with the following command line: + echo $NETHOME/netperf $PORT -l $TEST_TIME -H $REM_HOST $STATS_STUFF \ + $LOC_CPU $LOC_RATE $REM_CPU $REM_RATE -t UDP_RR --\ + -r $RR_SIZE -s $SOCKET_SIZE -S $SOCKET_SIZE + $NETHOME/netperf $PORT -l $TEST_TIME -H $REM_HOST $STATS_STUFF \ + $LOC_CPU $LOC_RATE $REM_CPU $REM_RATE -t UDP_RR $NO_HDR --\ + -r $RR_SIZE -s $SOCKET_SIZE -S $SOCKET_SIZE + done +done +echo +echo If you wish to submit these results to the netperf database at +echo http://www.cup.hp.com/netperf/NetperfPage.html, please submit each +echo datapoint individually. Individual datapoints are separated by +echo lines of dashes. diff --git a/doc/examples/udp_stream_script b/doc/examples/udp_stream_script new file mode 100644 index 0000000..41ae975 --- /dev/null +++ b/doc/examples/udp_stream_script @@ -0,0 +1,104 @@ +#!/bin/sh +# +# This is an example script for using netperf. Feel free to modify it +# as necessary, but I would suggest that you copy this one first. +# This script performs various UDP unidirectional stream tests. +# + +if [ $# -gt 2 ]; then + echo "try again, correctly -> udp_stream_script hostname [CPU]" + exit 1 +fi + +if [ $# -eq 0 ]; then + echo "try again, correctly -> udp_stream_script hostname [CPU]" + exit 1 +fi + +# where the programs are + +#NETHOME=/usr/local/netperf +#NETHOME="/opt/netperf" +NETHOME="." + +# at what port will netserver be waiting? If you decide to run +# netserver at a differnet port than the default of 12865, then set +# the value of PORT apropriately +#PORT="-p some_other_portnum" +PORT="" + +# The test length in seconds +TEST_TIME=60 + +# How accurate we want the estimate of performance: +# maximum and minimum test iterations (-i) +# confidence level (99 or 95) and interval (percent) + +STATS_STUFF="-i 10,2 -I 99,10" + +# The socket sizes that we will be testing. This should be a list of +# integers separated by spaces + +SOCKET_SIZES="32768" + +# The send sizes that we will be using. Using send sizes that result +# in UDP packets which are larger than link size can be a bad thing to do. +# for FDDI, you can tack-on a 4096 data point + +SEND_SIZES="64 1024 1472" + +# if there are two parms, parm one it the hostname and parm two will +# be a CPU indicator. actually, anything as a second parm will cause +# the CPU to be measured, but we will "advertise" it should be "CPU" + +if [ $# -eq 2 ]; then + REM_HOST=$1 + LOC_CPU="-c" + REM_CPU="-C" +fi + +if [ $# -eq 1 ]; then + LOC_CPU="" + REM_CPU="" + REM_HOST=$1 +fi + +# If we are measuring CPU utilization, then we can save beaucoup +# time by saving the results of the CPU calibration and passing +# them in during the real tests. So, we execute the new CPU "tests" +# of netperf and put the values into shell vars. +case $LOC_CPU in +\-c) LOC_RATE=`$NETHOME/netperf $PORT -t LOC_CPU`;; +*) LOC_RATE="" +esac + +case $REM_CPU in +\-C) REM_RATE=`$NETHOME/netperf $PORT -t REM_CPU -H $REM_HOST`;; +*) REM_RATE="" +esac + +# This will tell netperf that headers are not to be displayed +NO_HDR="-P 0" + +for SOCKET_SIZE in $SOCKET_SIZES +do + for SEND_SIZE in $SEND_SIZES + do + echo + echo ------------------------------------------------------ + echo Testing with the following command line: + echo $NETHOME/netperf $PORT -l $TEST_TIME -H $REM_HOST $STATS_STUFF \ + $LOC_CPU $LOC_RATE $REM_CPU $REM_RATE -t UDP_STREAM -- \ + -m $SEND_SIZE -s $SOCKET_SIZE -S $SOCKET_SIZE + + $NETHOME/netperf $PORT -l $TEST_TIME -H $REM_HOST $STATS_STUFF \ + $LOC_CPU $LOC_RATE $REM_CPU $REM_RATE -t UDP_STREAM -- \ + -m $SEND_SIZE -s $SOCKET_SIZE -S $SOCKET_SIZE + + done +done +echo +echo If you wish to submit these results to the netperf database at +echo http://www.cup.hp.com/netperf/NetperfPage.html, please submit each +echo datapoint individually. Individual datapoints are separated by +echo lines of dashes. diff --git a/doc/netperf.info b/doc/netperf.info new file mode 100644 index 0000000..0a4c0cd --- /dev/null +++ b/doc/netperf.info @@ -0,0 +1,2859 @@ +This is netperf.info, produced by makeinfo version 4.11 from +netperf.texi. + +This is Rick Jones' feeble attempt at a Texinfo-based manual for the +netperf benchmark. + + Copyright (C) 2005-2007 Hewlett-Packard Company + + Permission is granted to copy, distribute and/or modify this + document per the terms of the netperf source licence, a copy of + which can be found in the file `COPYING' of the basic netperf + distribution. + + +File: netperf.info, Node: Top, Next: Introduction, Prev: (dir), Up: (dir) + +Netperf Manual +************** + +This is Rick Jones' feeble attempt at a Texinfo-based manual for the +netperf benchmark. + + Copyright (C) 2005-2007 Hewlett-Packard Company + + Permission is granted to copy, distribute and/or modify this + document per the terms of the netperf source licence, a copy of + which can be found in the file `COPYING' of the basic netperf + distribution. + +* Menu: + +* Introduction:: An introduction to netperf - what it is and whatit is not. +* Installing Netperf:: How to go about installing netperf. +* The Design of Netperf:: +* Global Command-line Options:: +* Using Netperf to Measure Bulk Data Transfer:: +* Using Netperf to Measure Request/Response :: +* Using Netperf to Measure Aggregate Performance:: +* Using Netperf to Measure Bidirectional Transfer:: +* Other Netperf Tests:: +* Address Resolution:: +* Enhancing Netperf:: +* Netperf4:: +* Concept Index:: +* Option Index:: + + --- The Detailed Node Listing --- + +Introduction + +* Conventions:: + +Installing Netperf + +* Getting Netperf Bits:: +* Installing Netperf Bits:: +* Verifying Installation:: + +The Design of Netperf + +* CPU Utilization:: + +Global Command-line Options + +* Command-line Options Syntax:: +* Global Options:: + +Using Netperf to Measure Bulk Data Transfer + +* Issues in Bulk Transfer:: +* Options common to TCP UDP and SCTP tests:: + +Options common to TCP UDP and SCTP tests + +* TCP_STREAM:: +* TCP_MAERTS:: +* TCP_SENDFILE:: +* UDP_STREAM:: +* XTI_TCP_STREAM:: +* XTI_UDP_STREAM:: +* SCTP_STREAM:: +* DLCO_STREAM:: +* DLCL_STREAM:: +* STREAM_STREAM:: +* DG_STREAM:: + +Using Netperf to Measure Request/Response + +* Issues in Request/Response:: +* Options Common to TCP UDP and SCTP _RR tests:: + +Options Common to TCP UDP and SCTP _RR tests + +* TCP_RR:: +* TCP_CC:: +* TCP_CRR:: +* UDP_RR:: +* XTI_TCP_RR:: +* XTI_TCP_CC:: +* XTI_TCP_CRR:: +* XTI_UDP_RR:: +* DLCL_RR:: +* DLCO_RR:: +* SCTP_RR:: + +Using Netperf to Measure Aggregate Performance + +* Running Concurrent Netperf Tests:: +* Using --enable-burst:: + +Using Netperf to Measure Bidirectional Transfer + +* Bidirectional Transfer with Concurrent Tests:: +* Bidirectional Transfer with TCP_RR:: + +Other Netperf Tests + +* CPU rate calibration:: + + +File: netperf.info, Node: Introduction, Next: Installing Netperf, Prev: Top, Up: Top + +1 Introduction +************** + +Netperf is a benchmark that can be use to measure various aspect of +networking performance. The primary foci are bulk (aka unidirectional) +data transfer and request/response performance using either TCP or UDP +and the Berkeley Sockets interface. As of this writing, the tests +available either unconditionally or conditionally include: + + * TCP and UDP unidirectional transfer and request/response over IPv4 + and IPv6 using the Sockets interface. + + * TCP and UDP unidirectional transfer and request/response over IPv4 + using the XTI interface. + + * Link-level unidirectional transfer and request/response using the + DLPI interface. + + * Unix domain sockets + + * SCTP unidirectional transfer and request/response over IPv4 and + IPv6 using the sockets interface. + + While not every revision of netperf will work on every platform +listed, the intention is that at least some version of netperf will +work on the following platforms: + + * Unix - at least all the major variants. + + * Linux + + * Windows + + * OpenVMS + + * Others + + Netperf is maintained and informally supported primarily by Rick +Jones, who can perhaps be best described as Netperf Contributing +Editor. Non-trivial and very appreciated assistance comes from others +in the network performance community, who are too numerous to mention +here. While it is often used by them, netperf is NOT supported via any +of the formal Hewlett-Packard support channels. You should feel free +to make enhancements and modifications to netperf to suit your +nefarious porpoises, so long as you stay within the guidelines of the +netperf copyright. If you feel so inclined, you can send your changes +to netperf-feedback for possible +inclusion into subsequent versions of netperf. + + If you would prefer to make contributions to networking benchmark +using certified "open source" license, please considuer netperf4, which +is distributed under the terms of the GPL. + + The netperf-talk mailing list is +available to discuss the care and feeding of netperf with others who +share your interest in network performance benchmarking. The +netperf-talk mailing list is a closed list and you must first subscribe +by sending email to netperf-talk-request +. + +* Menu: + +* Conventions:: + + +File: netperf.info, Node: Conventions, Prev: Introduction, Up: Introduction + +1.1 Conventions +=============== + +A "sizespec" is a one or two item, comma-separated list used as an +argument to a command-line option that can set one or two, related +netperf parameters. If you wish to set both parameters to separate +values, items should be separated by a comma: + + parameter1,parameter2 + + If you wish to set the first parameter without altering the value of +the second from its default, you should follow the first item with a +comma: + + parameter1, + + Likewise, precede the item with a comma if you wish to set only the +second parameter: + + ,parameter2 + + An item with no commas: + + parameter1and2 + + will set both parameters to the same value. This last mode is one of +the most frequently used. + + There is another variant of the comma-separated, two-item list called +a "optionspec" which is like a sizespec with the exception that a +single item with no comma: + + parameter1 + + will only set the value of the first parameter and will leave the +second parameter at its default value. + + Netperf has two types of command-line options. The first are global +command line options. They are essentially any option not tied to a +particular test or group of tests. An example of a global command-line +option is the one which sets the test type - `-t'. + + The second type of options are test-specific options. These are +options which are only applicable to a particular test or set of tests. +An example of a test-specific option would be the send socket buffer +size for a TCP_STREAM test. + + Global command-line options are specified first with test-specific +options following after a `--' as in: + + netperf -- + + +File: netperf.info, Node: Installing Netperf, Next: The Design of Netperf, Prev: Introduction, Up: Top + +2 Installing Netperf +******************** + +Netperf's primary form of distribution is source code. This allows +installation on systems other than those to which the authors have +ready access and thus the ability to create binaries. There are two +styles of netperf installation. The first runs the netperf server +program - netserver - as a child of inetd. This requires the installer +to have sufficient privileges to edit the files `/etc/services' and +`/etc/inetd.conf' or their platform-specific equivalents. + + The second style is to run netserver as a standalone daemon. This +second method does not require edit privileges on `/etc/services' and +`/etc/inetd.conf' but does mean you must remember to run the netserver +program explicitly after every system reboot. + + This manual assumes that those wishing to measure networking +performance already know how to use anonymous FTP and/or a web browser. +It is also expected that you have at least a passing familiarity with +the networking protocols and interfaces involved. In all honesty, if +you do not have such familiarity, likely as not you have some +experience to gain before attempting network performance measurements. +The excellent texts by authors such as Stevens, Fenner and Rudoff +and/or Stallings would be good starting points. There are likely other +excellent sources out there as well. + +* Menu: + +* Getting Netperf Bits:: +* Installing Netperf Bits:: +* Verifying Installation:: + + +File: netperf.info, Node: Getting Netperf Bits, Next: Installing Netperf Bits, Prev: Installing Netperf, Up: Installing Netperf + +2.1 Getting Netperf Bits +======================== + +Gzipped tar files of netperf sources can be retrieved via anonymous FTP +(ftp://ftp.netperf.org/netperf) for "released" versions of the bits. +Pre-release versions of the bits can be retrieved via anonymous FTP +from the experimental (ftp://ftp.netperf.org/netperf/experimental) +subdirectory. + + For convenience and ease of remembering, a link to the download site +is provided via the NetperfPage (http://www.netperf.org/) + + The bits corresponding to each discrete release of netperf are +tagged (http://www.netperf.org/svn/netperf2/tags) for retrieval via +subversion. For example, there is a tag for the first version +corresponding to this version of the manual - netperf 2.4.3 +(http://www.netperf.org/svn/netperf2/tags/netperf-2.4.3). Those +wishing to be on the bleeding edge of netperf development can use +subversion to grab the top of trunk +(http://www.netperf.org/svn/netperf2/trunk). + + There are likely other places around the Internet from which one can +download netperf bits. These may be simple mirrors of the main netperf +site, or they may be local variants on netperf. As with anything one +downloads from the Internet, take care to make sure it is what you +really wanted and isn't some malicious Trojan or whatnot. Caveat +downloader. + + As a general rule, binaries of netperf and netserver are not +distributed from ftp.netperf.org. From time to time a kind soul or +souls has packaged netperf as a Debian package available via the +apt-get mechanism or as an RPM. I would be most interested in learning +how to enhance the makefiles to make that easier for people, and +perhaps to generate HP-UX swinstall"depots." + + +File: netperf.info, Node: Installing Netperf Bits, Next: Verifying Installation, Prev: Getting Netperf Bits, Up: Installing Netperf + +2.2 Installing Netperf +====================== + +Once you have downloaded the tar file of netperf sources onto your +system(s), it is necessary to unpack the tar file, cd to the netperf +directory, run configure and then make. Most of the time it should be +sufficient to just: + + gzcat .tar.gz | tar xf - + cd + ./configure + make + make install + + Most of the "usual" configure script options should be present +dealing with where to install binaries and whatnot. + ./configure --help + should list all of those and more. + + If the netperf configure script does not know how to automagically +detect which CPU utilization mechanism to use on your platform you may +want to add a `--enable-cpuutil=mumble' option to the configure +command. If you have knowledge and/or experience to contribute to +that area, feel free to contact . + + Similarly, if you want tests using the XTI interface, Unix Domain +Sockets, DLPI or SCTP it will be necessary to add one or more +`--enable-[xti|unix|dlpi|sctp]=yes' options to the configure command. +As of this writing, the configure script will not include those tests +automagically. + + On some platforms, it may be necessary to precede the configure +command with a CFLAGS and/or LIBS variable as the netperf configure +script is not yet smart enough to set them itself. Whenever possible, +these requirements will be found in `README.PLATFORM' files. Expertise +and assistance in making that more automagical in the configure script +would be most welcome. + + Other optional configure-time settings include +`--enable-intervals=yes' to give netperf the ability to "pace" its +_STREAM tests and `--enable-histogram=yes' to have netperf keep a +histogram of interesting times. Each of these will have some effect on +the measured result. If your system supports `gethrtime()' the effect +of the histogram measurement should be minimized but probably still +measurable. For example, the histogram of a netperf TCP_RR test will +be of the individual transaction times: + netperf -t TCP_RR -H lag -v 2 + TCP REQUEST/RESPONSE TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to lag.hpl.hp.com (15.4.89.214) port 0 AF_INET : histogram + Local /Remote + Socket Size Request Resp. Elapsed Trans. + Send Recv Size Size Time Rate + bytes Bytes bytes bytes secs. per sec + + 16384 87380 1 1 10.00 3538.82 + 32768 32768 + Alignment Offset + Local Remote Local Remote + Send Recv Send Recv + 8 0 0 0 + Histogram of request/response times + UNIT_USEC : 0: 0: 0: 0: 0: 0: 0: 0: 0: 0 + TEN_USEC : 0: 0: 0: 0: 0: 0: 0: 0: 0: 0 + HUNDRED_USEC : 0: 34480: 111: 13: 12: 6: 9: 3: 4: 7 + UNIT_MSEC : 0: 60: 50: 51: 44: 44: 72: 119: 100: 101 + TEN_MSEC : 0: 105: 0: 0: 0: 0: 0: 0: 0: 0 + HUNDRED_MSEC : 0: 0: 0: 0: 0: 0: 0: 0: 0: 0 + UNIT_SEC : 0: 0: 0: 0: 0: 0: 0: 0: 0: 0 + TEN_SEC : 0: 0: 0: 0: 0: 0: 0: 0: 0: 0 + >100_SECS: 0 + HIST_TOTAL: 35391 + + Long-time users of netperf will notice the expansion of the main test +header. This stems from the merging-in of IPv6 with the standard IPv4 +tests and the addition of code to specify addressing information for +both sides of the data connection. + + The histogram you see above is basically a base-10 log histogram +where we can see that most of the transaction times were on the order +of one hundred to one-hundred, ninety-nine microseconds, but they were +occasionally as long as ten to nineteen milliseconds + + The `--enable-demo=yes' configure option will cause code to be +included to report interim results during a test run. The rate at +which interim results are reported can then be controlled via the +global `-D' option. Here is an example of -enable-demo mode output: + + src/netperf -D 1.35 -H lag -f M + TCP STREAM TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to lag.hpl.hp.com (15.4.89.214) port 0 AF_INET : demo + Interim result: 9.66 MBytes/s over 1.67 seconds + Interim result: 9.64 MBytes/s over 1.35 seconds + Interim result: 9.58 MBytes/s over 1.36 seconds + Interim result: 9.51 MBytes/s over 1.36 seconds + Interim result: 9.71 MBytes/s over 1.35 seconds + Interim result: 9.66 MBytes/s over 1.36 seconds + Interim result: 9.61 MBytes/s over 1.36 seconds + Recv Send Send + Socket Socket Message Elapsed + Size Size Size Time Throughput + bytes bytes bytes secs. MBytes/sec + + 32768 16384 16384 10.00 9.61 + + Notice how the units of the interim result track that requested by +the `-f' option. Also notice that sometimes the interval will be +longer than the value specified in the `-D' option. This is normal and +stems from how demo mode is implemented without relying on interval +timers, but by calculating how many units of work must be performed to +take at least the desired interval. + + As of this writing, a `make install' will not actually update the +files `/etc/services' and/or `/etc/inetd.conf' or their +platform-specific equivalents. It remains necessary to perform that +bit of installation magic by hand. Patches to the makefile sources to +effect an automagic editing of the necessary files to have netperf +installed as a child of inetd would be most welcome. + + Starting the netserver as a standalone daemon should be as easy as: + $ netserver + Starting netserver at port 12865 + Starting netserver at hostname 0.0.0.0 port 12865 and family 0 + + Over time the specifics of the messages netserver prints to the +screen may change but the gist will remain the same. + + If the compilation of netperf or netserver happens to fail, feel free +to contact or join and ask in +. However, it is quite important that you +include the actual compilation errors and perhaps even the configure +log in your email. Otherwise, it will be that much more difficult for +someone to assist you. + + +File: netperf.info, Node: Verifying Installation, Prev: Installing Netperf Bits, Up: Installing Netperf + +2.3 Verifying Installation +========================== + +Basically, once netperf is installed and netserver is configured as a +child of inetd, or launched as a standalone daemon, simply typing: + netperf + should result in output similar to the following: + $ netperf + TCP STREAM TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to localhost.localdomain (127.0.0.1) port 0 AF_INET + Recv Send Send + Socket Socket Message Elapsed + Size Size Size Time Throughput + bytes bytes bytes secs. 10^6bits/sec + + 87380 16384 16384 10.00 2997.84 + + +File: netperf.info, Node: The Design of Netperf, Next: Global Command-line Options, Prev: Installing Netperf, Up: Top + +3 The Design of Netperf +*********************** + +Netperf is designed around a basic client-server model. There are two +executables - netperf and netserver. Generally you will only execute +the netperf program, with the netserver program being invoked by the +remote system's inetd or equivalent. When you execute netperf, the +first that that will happen is the establishment of a control +connection to the remote system. This connection will be used to pass +test configuration information and results to and from the remote +system. Regardless of the type of test to be run, the control +connection will be a TCP connection using BSD sockets. The control +connection can use either IPv4 or IPv6. + + Once the control connection is up and the configuration information +has been passed, a separate "data" connection will be opened for the +measurement itself using the API's and protocols appropriate for the +specified test. When the test is completed, the data connection will +be torn-down and results from the netserver will be passed-back via the +control connection and combined with netperf's result for display to +the user. + + Netperf places no traffic on the control connection while a test is +in progress. Certain TCP options, such as SO_KEEPALIVE, if set as your +systems' default, may put packets out on the control connection while a +test is in progress. Generally speaking this will have no effect on +the results. + +* Menu: + +* CPU Utilization:: + + +File: netperf.info, Node: CPU Utilization, Prev: The Design of Netperf, Up: The Design of Netperf + +3.1 CPU Utilization +=================== + +CPU utilization is an important, and alas all-too infrequently reported +component of networking performance. Unfortunately, it can be one of +the most difficult metrics to measure accurately as many systems offer +mechanisms that are at best il-suited to measuring CPU utilization in +high interrupt rate (eg networking) situations. + + CPU utilization in netperf is reported as a value between 0 and 100% +regardless of the number of CPUs involved. In addition to CPU +utilization, netperf will report a metric called a "service demand". +The service demand is the normalization of CPU utilization and work +performed. For a _STREAM test it is the microseconds of CPU time +consumed to transfer on KB (K == 1024) of data. For a _RR test it is +the microseconds of CPU time consumed processing a single transaction. +For both CPU utilization and service demand, lower is better. + + Service demand can be particularly useful when trying to gauge the +effect of a performance change. It is essentially a measure of +efficiency, with smaller values being more efficient. + + Netperf is coded to be able to use one of several, generally +platform-specific CPU utilization measurement mechanisms. Single +letter codes will be included in the CPU portion of the test banner to +indicate which mechanism was used on each of the local (netperf) and +remote (netserver) system. + + As of this writing those codes are: + +`U' + The CPU utilization measurement mechanism was unknown to netperf or + netperf/netserver was not compiled to include CPU utilization + measurements. The code for the null CPU utilization mechanism can + be found in `src/netcpu_none.c'. + +`I' + An HP-UX-specific CPU utilization mechanism whereby the kernel + incremented a per-CPU counter by one for each trip through the idle + loop. This mechanism was only available on specially-compiled HP-UX + kernels prior to HP-UX 10 and is mentioned here only for the sake + of historical completeness and perhaps as a suggestion to those + who might be altering other operating systems. While rather + simple, perhaps even simplistic, this mechanism was quite robust + and was not affected by the concerns of statistical methods, or + methods attempting to track time in each of user, kernel, + interrupt and idle modes which require quite careful accounting. + It can be thought-of as the in-kernel version of the looper `L' + mechanism without the context switch overhead. This mechanism + required calibration. + +`P' + An HP-UX-specific CPU utilization mechanism whereby the kernel + keeps-track of time (in the form of CPU cycles) spent in the kernel + idle loop (HP-UX 10.0 to 11.23 inclusive), or where the kernel + keeps track of time spent in idle, user, kernel and interrupt + processing (HP-UX 11.23 and later). The former requires + calibration, the latter does not. Values in either case are + retrieved via one of the pstat(2) family of calls, hence the use + of the letter `P'. The code for these mechanisms is found in + `src/netcpu_pstat.c' and `src/netcpu_pstatnew.c' respectively. + +`K' + A Solaris-specific CPU utilization mechanism where by the kernel + keeps track of ticks (eg HZ) spent in the idle loop. This method + is statistical and is known to be inaccurate when the interrupt + rate is above epsilon as time spent processing interrupts is not + subtracted from idle. The value is retrieved via a kstat() call - + hence the use of the letter `K'. Since this mechanism uses units + of ticks (HZ) the calibration value should invariably match HZ. + (Eg 100) The code for this mechanism is implemented in + `src/netcpu_kstat.c'. + +`M' + A Solaris-specific mechanism available on Solaris 10 and latter + which uses the new microstate accounting mechanisms. There are + two, alas, overlapping, mechanisms. The first tracks nanoseconds + spent in user, kernel, and idle modes. The second mechanism tracks + nanoseconds spent in interrupt. Since the mechanisms overlap, + netperf goes through some hand-waving to try to "fix" the problem. + Since the accuracy of the handwaving cannot be completely + determined, one must presume that while better than the `K' + mechanism, this mechanism too is not without issues. The values + are retrieved via kstat() calls, but the letter code is set to `M' + to distinguish this mechanism from the even less accurate `K' + mechanism. The code for this mechanism is implemented in + `src/netcpu_kstat10.c'. + +`L' + A mechanism based on "looper"or "soaker" processes which sit in + tight loops counting as fast as they possibly can. This mechanism + starts a looper process for each known CPU on the system. The + effect of processor hyperthreading on the mechanism is not yet + known. This mechanism definitely requires calibration. The code + for the "looper"mechanism can be found in `src/netcpu_looper.c' + +`N' + A Microsoft Windows-specific mechanism, the code for which can be + found in `src/netcpu_ntperf.c'. This mechanism too is based on + what appears to be a form of micro-state accounting and requires no + calibration. On laptops, or other systems which may dynamically + alter the CPU frequency to minimize power consumtion, it has been + suggested that this mechanism may become slightly confsed, in + which case using BIOS settings to disable the power saving would + be indicated. + +`S' + This mechanism uses `/proc/stat' on Linux to retrieve time (ticks) + spent in idle mode. It is thought but not known to be reasonably + accurate. The code for this mechanism can be found in + `src/netcpu_procstat.c'. + +`C' + A mechanism somewhat similar to `S' but using the sysctl() call on + BSD-like Operating systems (*BSD and MacOS X). The code for this + mechanism can be found in `src/netcpu_sysctl.c'. + +`Others' + Other mechanisms included in netperf in the past have included + using the times() and getrusage() calls. These calls are actually + rather poorly suited to the task of measuring CPU overhead for + networking as they tend to be process-specific and much + network-related processing can happen outside the context of a + process, in places where it is not a given it will be charged to + the correct, or even a process. They are mentioned here as a + warning to anyone seeing those mechanisms used in other networking + benchmarks. These mechanisms are not available in netperf 2.4.0 + and later. + + For many platforms, the configure script will chose the best +available CPU utilization mechanism. However, some platforms have no +particularly good mechanisms. On those platforms, it is probably best +to use the "LOOPER" mechanism which is basically some number of +processes (as many as there are processors) sitting in tight little +loops counting as fast as they can. The rate at which the loopers +count when the system is believed to be idle is compared with the rate +when the system is running netperf and the ratio is used to compute CPU +utilization. + + In the past, netperf included some mechanisms that only reported CPU +time charged to the calling process. Those mechanisms have been +removed from netperf versions 2.4.0 and later because they are +hopelessly inaccurate. Networking can and often results in CPU time +being spent in places - such as interrupt contexts - that do not get +charged to a or the correct process. + + In fact, time spent in the processing of interrupts is a common issue +for many CPU utilization mechanisms. In particular, the "PSTAT" +mechanism was eventually known to have problems accounting for certain +interrupt time prior to HP-UX 11.11 (11iv1). HP-UX 11iv1 and later are +known to be good. The "KSTAT" mechanism is known to have problems on +all versions of Solaris up to and including Solaris 10. Even the +microstate accounting available via kstat in Solaris 10 has issues, +though perhaps not as bad as those of prior versions. + + The /proc/stat mechanism under Linux is in what the author would +consider an "uncertain" category as it appears to be statistical, which +may also have issues with time spent processing interrupts. + + In summary, be sure to "sanity-check" the CPU utilization figures +with other mechanisms. However, platform tools such as top, vmstat or +mpstat are often based on the same mechanisms used by netperf. + + +File: netperf.info, Node: Global Command-line Options, Next: Using Netperf to Measure Bulk Data Transfer, Prev: The Design of Netperf, Up: Top + +4 Global Command-line Options +***************************** + +This section describes each of the global command-line options +available in the netperf and netserver binaries. Essentially, it is an +expanded version of the usage information displayed by netperf or +netserver when invoked with the `-h' global command-line option. + +* Menu: + +* Command-line Options Syntax:: +* Global Options:: + + +File: netperf.info, Node: Command-line Options Syntax, Next: Global Options, Prev: Global Command-line Options, Up: Global Command-line Options + +4.1 Command-line Options Syntax +=============================== + +Revision 1.8 of netperf introduced enough new functionality to overrun +the English alphabet for mnemonic command-line option names, and the +author was not and is not quite ready to switch to the contemporary +`--mumble' style of command-line options. (Call him a Luddite). + + For this reason, the command-line options were split into two parts - +the first are the global command-line options. They are options that +affect nearly any and every test type of netperf. The second type are +the test-specific command-line options. Both are entered on the same +command line, but they must be separated from one another by a `--' for +correct parsing. Global command-line options come first, followed by +the `--' and then test-specific command-line options. If there are no +test-specific options to be set, the `--' may be omitted. If there are +no global command-line options to be set, test-specific options must +still be preceded by a `--'. For example: + netperf -- + sets both global and test-specific options: + netperf + sets just global options and: + netperf -- + sets just test-specific options. + + +File: netperf.info, Node: Global Options, Prev: Command-line Options Syntax, Up: Global Command-line Options + +4.2 Global Options +================== + +`-a ' + This option allows you to alter the alignment of the buffers used + in the sending and receiving calls on the local system.. Changing + the alignment of the buffers can force the system to use different + copy schemes, which can have a measurable effect on performance. + If the page size for the system were 4096 bytes, and you want to + pass page-aligned buffers beginning on page boundaries, you could + use `-a 4096'. By default the units are bytes, but suffix of "G," + "M," or "K" will specify the units to be 2^30 (GB), 2^20 (MB) or + 2^10 (KB) respectively. A suffix of "g," "m" or "k" will specify + units of 10^9, 10^6 or 10^3 bytes respectively. [Default: 8 bytes] + +`-A ' + This option is identical to the `-a' option with the difference + being it affects alignments for the remote system. + +`-b ' + This option is only present when netperf has been configure with + -enable-intervals=yes prior to compilation. It sets the size of + the burst of send calls in a _STREAM test. When used in + conjunction with the `-w' option it can cause the rate at which + data is sent to be "paced." + +`-B ' + This option will cause `' to be appended to the brief (see + -P) output of netperf. + +`-c [rate]' + This option will ask that CPU utilization and service demand be + calculated for the local system. For those CPU utilization + mechanisms requiring calibration, the options rate parameter may + be specified to preclude running another calibration step, saving + 40 seconds of time. For those CPU utilization mechanisms + requiring no calibration, the optional rate parameter will be + utterly and completely ignored. [Default: no CPU measurements] + +`-C [rate]' + This option requests CPU utilization and service demand + calculations for the remote system. It is otherwise identical to + the `-c' option. + +`-d' + Each instance of this option will increase the quantity of + debugging output displayed during a test. If the debugging output + level is set high enough, it may have a measurable effect on + performance. Debugging information for the local system is + printed to stdout. Debugging information for the remote system is + sent by default to the file `/tmp/netperf.debug'. [Default: no + debugging output] + +`-D [interval,units]' + This option is only available when netperf is configured with + -enable-demo=yes. When set, it will cause netperf to emit periodic + reports of performance during the run. [INTERVAL,UNITS] follow + the semantics of an optionspec. If specified, INTERVAL gives the + minimum interval in real seconds, it does not have to be whole + seconds. The UNITS value can be used for the first guess as to + how many units of work (bytes or transactions) must be done to + take at least INTERVAL seconds. If omitted, INTERVAL defaults to + one second and UNITS to values specific to each test type. + +`-f G|M|K|g|m|k' + This option can be used to change the reporting units for _STREAM + tests. Arguments of "G," "M," or "K" will set the units to 2^30, + 2^20 or 2^10 bytes/s respectively (EG power of two GB, MB or KB). + Arguments of "g," ",m" or "k" will set the units to 10^9, 10^6 or + 10^3 bits/s respectively. [Default: 'm' or 10^6 bits/s] + +`-F ' + This option specified the file from which send which buffers will + be pre-filled . While the buffers will contain data from the + specified file, the file is not fully transfered to the remote + system as the receiving end of the test will not write the + contents of what it receives to a file. This can be used to + pre-fill the send buffers with data having different + compressibility and so is useful when measuring performance over + mechanisms which perform compression. + + While optional for most tests, this option is required for a test + utilizing the sendfile() or related calls because sendfile tests + need a name of a file to reference. + +`-h' + This option causes netperf to display its usage string and exit to + the exclusion of all else. + +`-H ' + This option will set the name of the remote system and or the + address family used for the control connection. For example: + -H linger,4 + will set the name of the remote system to "tardy" and tells + netperf to use IPv4 addressing only. + -H ,6 + will leave the name of the remote system at its default, and + request that only IPv6 addresses be used for the control + connection. + -H lag + will set the name of the remote system to "lag" and leave the + address family to AF_UNSPEC which means selection of IPv4 vs IPv6 + is left to the system's address resolution. + + A value of "inet" can be used in place of "4" to request IPv4 only + addressing. Similarly, a value of "inet6" can be used in place of + "6" to request IPv6 only addressing. A value of "0" can be used + to request either IPv4 or IPv6 addressing as name resolution + dictates. + + By default, the options set with the global `-H' option are + inherited by the test for its data connection, unless a + test-specific `-H' option is specified. + + If a `-H' option follows either the `-4' or `-6' options, the + family setting specified with the -H option will override the `-4' + or `-6' options for the remote address family. If no address + family is specified, settings from a previous `-4' or `-6' option + will remain. In a nutshell, the last explicit global command-line + option wins. + + [Default: "localhost" for the remote name/IP address and "0" (eg + AF_UNSPEC) for the remote address family.] + +`-I ' + This option enables the calculation of confidence intervals and + sets the confidence and width parameters with the first have of the + optionspec being either 99 or 95 for 99% or 95% confidence + respectively. The second value of the optionspec specifies the + width of the desired confidence interval. For example + -I 99,5 + asks netperf to be 99% confident that the measured mean values for + throughput and CPU utilization are within +/- 2.5% of the "real" + mean values. If the `-i' option is specified and the `-I' option + is omitted, the confidence defaults to 99% and the width to 5% + (giving +/- 2.5%) + + If netperf calculates that the desired confidence intervals have + not been met, it emits a noticeable warning that cannot be + suppressed with the `-P' or `-v' options: + + netperf -H tardy.cup -i 3 -I 99,5 + TCP STREAM TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to tardy.cup.hp.com (15.244.44.58) port 0 AF_INET : +/-2.5% 99% conf. + !!! WARNING + !!! Desired confidence was not achieved within the specified iterations. + !!! This implies that there was variability in the test environment that + !!! must be investigated before going further. + !!! Confidence intervals: Throughput : 6.8% + !!! Local CPU util : 0.0% + !!! Remote CPU util : 0.0% + + Recv Send Send + Socket Socket Message Elapsed + Size Size Size Time Throughput + bytes bytes bytes secs. 10^6bits/sec + + 32768 16384 16384 10.01 40.23 + + Where we see that netperf did not meet the desired convidence + intervals. Instead of being 99% confident it was within +/- 2.5% + of the real mean value of throughput it is only confident it was + within +/-3.4%. In this example, increasing the `-i' option + (described below) and/or increasing the iteration length with the + `-l' option might resolve the situation. + +`-i ' + This option enables the calculation of confidence intervals and + sets the minimum and maximum number of iterations to run in + attempting to achieve the desired confidence interval. The first + value sets the maximum number of iterations to run, the second, + the minimum. The maximum number of iterations is silently capped + at 30 and the minimum is silently floored at 3. Netperf repeats + the measurement the minimum number of iterations and continues + until it reaches either the desired confidence interval, or the + maximum number of iterations, whichever comes first. + + If the `-I' option is specified and the `-i' option omitted the + maximum number of iterations is set to 10 and the minimum to three. + + If netperf determines that the desired confidence intervals have + not been met, it emits a noticeable warning. + + The total test time will be somewhere between the minimum and + maximum number of iterations multiplied by the test length + supplied by the `-l' option. + +`-l testlen' + This option controls the length of any one iteration of the + requested test. A positive value for TESTLEN will run each + iteration of the test for at least TESTLEN seconds. A negative + value for TESTLEN will run each iteration for the absolute value of + TESTLEN transactions for a _RR test or bytes for a _STREAM test. + Certain tests, notably those using UDP can only be timed, they + cannot be limited by transaction or byte count. + + In some situations, individual iterations of a test may run for + longer for the number of seconds specified by the `-l' option. In + particular, this may occur for those tests where the socket buffer + size(s) are significantly longer than the bandwidthXdelay product + of the link(s) over which the data connection passes, or those + tests where there may be non-trivial numbers of retransmissions. + + If confidence intervals are enabled via either `-I' or `-i' the + total length of the netperf test will be somewhere between the + minimum and maximum iteration count multiplied by TESTLEN. + +`-L ' + This option is identical to the `-H' option with the difference + being it sets the _local_ hostname/IP and/or address family + information. This option is generally unnecessary, but can be + useful when you wish to make sure that the netperf control and data + connections go via different paths. It can also come-in handy if + one is trying to run netperf through those evil, end-to-end + breaking things known as firewalls. + + [Default: 0.0.0.0 (eg INADDR_ANY) for IPv4 and ::0 for IPv6 for the + local name. AF_UNSPEC for the local address family.] + +`-n numcpus' + This option tells netperf how many CPUs it should ass-u-me are + active on the system running netperf. In particular, this is used + for the *note CPU utilization: CPU Utilization. and service demand + calculations. On certain systems, netperf is able to determine + the number of CPU's automagically. This option will override any + number netperf might be able to determine on its own. + + Note that this option does _not_ set the number of CPUs on the + system running netserver. When netperf/netserver cannot + automagically determine the number of CPUs that can only be set + for netserver via a netserver `-n' command-line option. + +`-N' + This option tells netperf to forego establishing a control + connection. This makes it is possible to run some limited netperf + tests without a corresponding netserver on the remote system. + + With this option set, the test to be run is to get all the + addressing information it needs to establish its data connection + from the command line or internal defaults. If not otherwise + specified by test-specific command line options, the data + connection for a "STREAM" or "SENDFILE" test will be to the + "discard" port, an "RR" test will be to the "echo" port, and a + "MEARTS" test will be to the chargen port. + + The response size of an "RR" test will be silently set to be the + same as the request size. Otherwise the test would hang if the + response size was larger than the request size, or would report an + incorrect, inflated transaction rate if the response size was less + than the request size. + + Since there is no control connection when this option is + specified, it is not possible to set "remote" properties such as + socket buffer size and the like via the netperf command line. Nor + is it possible to retrieve such interesting remote information as + CPU utilization. These items will be set to values which when + displayed should make it immediately obvious that was the case. + + The only way to change remote characteristics such as socket buffer + size or to obtain information such as CPU utilization is to employ + platform-specific methods on the remote system. Frankly, if one + has access to the remote system to employ those methods one aught + to be able to run a netserver there. However, that ability may + not be present in certain "support" situations, hence the addition + of this option. + + Added in netperf 2.4.3. + +`-o ' + The value(s) passed-in with this option will be used as an offset + added to the alignment specified with the `-a' option. For + example: + -o 3 -a 4096 + will cause the buffers passed to the local send and receive calls + to begin three bytes past an address aligned to 4096 bytes. + [Default: 0 bytes] + +`-O ' + This option behaves just as the `-o' option but on the remote + system and in conjunction with the `-A' option. [Default: 0 bytes] + +`-p ' + The first value of the optionspec passed-in with this option tells + netperf the port number at which it should expect the remote + netserver to be listening for control connections. The second + value of the optionspec will request netperf to bind to that local + port number before establishing the control connection. For + example + -p 12345 + tells netperf that the remote netserver is listening on port 12345 + and leaves selection of the local port number for the control + connection up to the local TCP/IP stack whereas + -p ,32109 + leaves the remote netserver port at the default value of 12865 and + causes netperf to bind to the local port number 32109 before + connecting to the remote netserver. + + In general, setting the local port number is only necessary when + one is looking to run netperf through those evil, end-to-end + breaking things known as firewalls. + +`-P 0|1' + A value of "1" for the `-P' option will enable display of the test + banner. A value of "0" will disable display of the test banner. + One might want to disable display of the test banner when running + the same basic test type (eg TCP_STREAM) multiple times in + succession where the test banners would then simply be redundant + and unnecessarily clutter the output. [Default: 1 - display test + banners] + +`-t testname' + This option is used to tell netperf which test you wish to run. + As of this writing, valid values for TESTNAME include: + * *note TCP_STREAM::, *note TCP_MAERTS::, *note TCP_SENDFILE::, + *note TCP_RR::, *note TCP_CRR::, *note TCP_CC:: + + * *note UDP_STREAM::, *note UDP_RR:: + + * *note XTI_TCP_STREAM::, *note XTI_TCP_RR::, *note + XTI_TCP_CRR::, *note XTI_TCP_CC:: + + * *note XTI_UDP_STREAM::, *note XTI_UDP_RR:: + + * *note SCTP_STREAM::, *note SCTP_RR:: + + * *note DLCO_STREAM::, *note DLCO_RR::, *note DLCL_STREAM::, + *note DLCL_RR:: + + * *note LOC_CPU: Other Netperf Tests, *note REM_CPU: Other + Netperf Tests. + Not all tests are always compiled into netperf. In particular, the + "XTI," "SCTP," "UNIX," and "DL*" tests are only included in + netperf when configured with `--enable-[xti|sctp|unix|dlpi]=yes'. + + Netperf only runs one type of test no matter how many `-t' options + may be present on the command-line. The last `-t' global + command-line option will determine the test to be run. [Default: + TCP_STREAM] + +`-v verbosity' + This option controls how verbose netperf will be in its output, + and is often used in conjunction with the `-P' option. If the + verbosity is set to a value of "0" then only the test's SFM (Single + Figure of Merit) is displayed. If local *note CPU utilization: + CPU Utilization. is requested via the `-c' option then the SFM is + the local service demand. Othersise, if remote CPU utilization is + requested via the `-C' option then the SFM is the remote service + demand. If neither local nor remote CPU utilization are requested + the SFM will be the measured throughput or transaction rate as + implied by the test specified with the `-t' option. + + If the verbosity level is set to "1" then the "normal" netperf + result output for each test is displayed. + + If the verbosity level is set to "2" then "extra" information will + be displayed. This may include, but is not limited to the number + of send or recv calls made and the average number of bytes per + send or recv call, or a histogram of the time spent in each send() + call or for each transaction if netperf was configured with + `--enable-histogram=yes'. [Default: 1 - normal verbosity] + +`-w time' + If netperf was configured with `--enable-intervals=yes' then this + value will set the inter-burst time to time milliseconds, and the + `-b' option will set the number of sends per burst. The actual + inter-burst time may vary depending on the system's timer + resolution. + +`-W ' + This option controls the number of buffers in the send (first or + only value) and or receive (second or only value) buffer rings. + Unlike some benchmarks, netperf does not continuously send or + receive from a single buffer. Instead it rotates through a ring of + buffers. [Default: One more than the size of the send or receive + socket buffer sizes (`-s' and/or `-S' options) divided by the send + `-m' or receive `-M' buffer size respectively] + +`-4' + Specifying this option will set both the local and remote address + families to AF_INET - that is use only IPv4 addresses on the + control connection. This can be overridden by a subsequent `-6', + `-H' or `-L' option. Basically, the last option explicitly + specifying an address family wins. Unless overridden by a + test-specific option, this will be inherited for the data + connection as well. + +`-6' + Specifying this option will set both local and and remote address + families to AF_INET6 - that is use only IPv6 addresses on the + control connection. This can be overridden by a subsequent `-4', + `-H' or `-L' option. Basically, the last address family + explicitly specified wins. Unless overridden by a test-specific + option, this will be inherited for the data connection as well. + + + +File: netperf.info, Node: Using Netperf to Measure Bulk Data Transfer, Next: Using Netperf to Measure Request/Response, Prev: Global Command-line Options, Up: Top + +5 Using Netperf to Measure Bulk Data Transfer +********************************************* + +The most commonly measured aspect of networked system performance is +that of bulk or unidirectional transfer performance. Everyone wants to +know how many bits or bytes per second they can push across the +network. The netperf convention for a bulk data transfer test name is +to tack a "_STREAM" suffix to a test name. + +* Menu: + +* Issues in Bulk Transfer:: +* Options common to TCP UDP and SCTP tests:: + + +File: netperf.info, Node: Issues in Bulk Transfer, Next: Options common to TCP UDP and SCTP tests, Prev: Using Netperf to Measure Bulk Data Transfer, Up: Using Netperf to Measure Bulk Data Transfer + +5.1 Issues in Bulk Transfer +=========================== + +There are any number of things which can affect the performance of a +bulk transfer test. + + Certainly, absent compression, bulk-transfer tests can be limited by +the speed of the slowest link in the path from the source to the +destination. If testing over a gigabit link, you will not see more +than a gigabit :) Such situations can be described as being +"network-limited" or "NIC-limited". + + CPU utilization can also affect the results of a bulk-transfer test. +If the networking stack requires a certain number of instructions or +CPU cycles per KB of data transferred, and the CPU is limited in the +number of instructions or cycles it can provide, then the transfer can +be described as being "CPU-bound". + + A bulk-transfer test can be CPU bound even when netperf reports less +than 100% CPU utilization. This can happen on an MP system where one +or more of the CPUs saturate at 100% but other CPU's remain idle. +Typically, a single flow of data, such as that from a single instance +of a netperf _STREAM test cannot make use of much more than the power +of one CPU. Exceptions to this generally occur when netperf and/or +netserver run on CPU(s) other than the CPU(s) taking interrupts from +the NIC(s). + + Distance and the speed-of-light can affect performance for a +bulk-transfer; often this can be mitigated by using larger windows. +One common limit to the performance of a transport using window-based +flow-control is: + Throughput <= WindowSize/RoundTripTime + As the sender can only have a window's-worth of data outstanding on +the network at any one time, and the soonest the sender can receive a +window update from the receiver is one RoundTripTime (RTT). TCP and +SCTP are examples of such protocols. + + Packet losses and their effects can be particularly bad for +performance. This is especially true if the packet losses result in +retransmission timeouts for the protocol(s) involved. By the time a +retransmission timeout has happened, the flow or connection has sat +idle for a considerable length of time. + + On many platforms, some variant on the `netstat' command can be used +to retrieve statistics about packet loss and retransmission. For +example: + netstat -p tcp + will retrieve TCP statistics on the HP-UX Operating System. On other +platforms, it may not be possible to retrieve statistics for a specific +protocol and something like: + netstat -s + would be used instead. + + Many times, such network statistics are keep since the time the stack +started, and we are only really interested in statistics from when +netperf was running. In such situations something along the lines of: + netstat -p tcp > before + netperf -t TCP_mumble... + netstat -p tcp > after + is indicated. The beforeafter +(ftp://ftp.cup.hp.com/dist/networking/tools/) utility can be used to +subtract the statistics in `before' from the statistics in `after' + beforeafter before after > delta + and then one can look at the statistics in `delta'. Beforeafter is +distributed in source form so one can compile it on the platofrm(s) of +interest. + + While it was written with HP-UX's netstat in mind, the annotated +netstat +(ftp://ftp.cup.hp.com/dist/networking/briefs/annotated_netstat.txt) +writeup may be helpful with other platforms as well. + + +File: netperf.info, Node: Options common to TCP UDP and SCTP tests, Prev: Issues in Bulk Transfer, Up: Using Netperf to Measure Bulk Data Transfer + +5.2 Options common to TCP UDP and SCTP tests +============================================ + +Many "test-specific" options are actually common across the different +tests. For those tests involving TCP, UDP and SCTP, whether using the +BSD Sockets or the XTI interface those common options include: + +`-h' + Display the test-suite-specific usage string and exit. For a TCP_ + or UDP_ test this will be the usage string from the source file + nettest_bsd.c. For an XTI_ test, this will be the usage string + from the source file nettest_xti.c. For an SCTP test, this will + be the usage string from the source file nettest_sctp.c. + +`-H ' + Normally, the remote hostname|IP and address family information is + inherited from the settings for the control connection (eg global + command-line `-H', `-4' and/or `-6' options). The test-specific + `-H' will override those settings for the data (aka test) + connection only. Settings for the control connection are left + unchanged. + +`-L ' + The test-specific `-L' option is identical to the test-specific + `-H' option except it affects the local hostname|IP and address + family information. As with its global command-line counterpart, + this is generally only useful when measuring though those evil, + end-to-end breaking things called firewalls. + +`-m bytes' + Set the size of the buffer passed-in to the "send" calls of a + _STREAM test. Note that this may have only an indirect effect on + the size of the packets sent over the network, and certain Layer 4 + protocols do _not_ preserve or enforce message boundaries, so + setting `-m' for the send size does not necessarily mean the + receiver will receive that many bytes at any one time. By default + the units are bytes, but suffix of "G," "M," or "K" will specify + the units to be 2^30 (GB), 2^20 (MB) or 2^10 (KB) respectively. A + suffix of "g," "m" or "k" will specify units of 10^9, 10^6 or 10^3 + bytes respectively. For example: + `-m 32K' + will set the size to 32KB or 32768 bytes. [Default: the local send + socket buffer size for the connection - either the system's + default or the value set via the `-s' option.] + +`-M bytes' + Set the size of the buffer passed-in to the "recv" calls of a + _STREAM test. This will be an upper bound on the number of bytes + received per receive call. By default the units are bytes, but + suffix of "G," "M," or "K" will specify the units to be 2^30 (GB), + 2^20 (MB) or 2^10 (KB) respectively. A suffix of "g," "m" or "k" + will specify units of 10^9, 10^6 or 10^3 bytes respectively. For + example: + `-M 32K' + will set the size to 32KB or 32768 bytes. [Default: the remote + receive socket buffer size for the data connection - either the + system's default or the value set via the `-S' option.] + +`-P ' + Set the local and/or remote port numbers for the data connection. + +`-s ' + This option sets the local send and receive socket buffer sizes for + the data connection to the value(s) specified. Often, this will + affect the advertised and/or effective TCP or other window, but on + some platforms it may not. By default the units are bytes, but + suffix of "G," "M," or "K" will specify the units to be 2^30 (GB), + 2^20 (MB) or 2^10 (KB) respectively. A suffix of "g," "m" or "k" + will specify units of 10^9, 10^6 or 10^3 bytes respectively. For + example: + `-s 128K' + Will request the local send and receive socket buffer sizes to be + 128KB or 131072 bytes. + + While the historic expectation is that setting the socket buffer + size has a direct effect on say the TCP window, today that may not + hold true for all stacks. Further, while the historic expectation + is that the value specified in a setsockopt() call will be the + value returned via a getsockopt() call, at least one stack is + known to deliberately ignore history. When running under Windows + a value of 0 may be used which will be an indication to the stack + the user wants to enable a form of copy avoidance. [Default: -1 - + use the system's default socket buffer sizes] + +`-S ' + This option sets the remote send and/or receive socket buffer sizes + for the data connection to the value(s) specified. Often, this + will affect the advertised and/or effective TCP or other window, + but on some platforms it may not. By default the units are bytes, + but suffix of "G," "M," or "K" will specify the units to be 2^30 + (GB), 2^20 (MB) or 2^10 (KB) respectively. A suffix of "g," "m" + or "k" will specify units of 10^9, 10^6 or 10^3 bytes respectively. + For example: + `-s 128K' + Will request the local send and receive socket buffer sizes to be + 128KB or 131072 bytes. + + While the historic expectation is that setting the socket buffer + size has a direct effect on say the TCP window, today that may not + hold true for all stacks. Further, while the historic expectation + is that the value specified in a setsockopt() call will be the + value returned via a getsockopt() call, at least one stack is + known to deliberately ignore history. When running under Windows + a value of 0 may be used which will be an indication to the stack + the user wants to enable a form of copy avoidance. [Default: -1 - + use the system's default socket buffer sizes] + +`-4' + Set the local and remote address family for the data connection to + AF_INET - ie use IPv4 addressing only. Just as with their global + command-line counterparts the last of the `-4', `-6', `-H' or `-L' + option wins for their respective address families. + +`-6' + This option is identical to its `-4' cousin, but requests IPv6 + addresses for the local and remote ends of the data connection. + + +* Menu: + +* TCP_STREAM:: +* TCP_MAERTS:: +* TCP_SENDFILE:: +* UDP_STREAM:: +* XTI_TCP_STREAM:: +* XTI_UDP_STREAM:: +* SCTP_STREAM:: +* DLCO_STREAM:: +* DLCL_STREAM:: +* STREAM_STREAM:: +* DG_STREAM:: + + +File: netperf.info, Node: TCP_STREAM, Next: TCP_MAERTS, Prev: Options common to TCP UDP and SCTP tests, Up: Options common to TCP UDP and SCTP tests + +5.2.1 TCP_STREAM +---------------- + +The TCP_STREAM test is the default test in netperf. It is quite +simple, transferring some quantity of data from the system running +netperf to the system running netserver. While time spent establishing +the connection is not included in the throughput calculation, time +spent flushing the last of the data to the remote at the end of the +test is. This is how netperf knows that all the data it sent was +received by the remote. In addition to the *note options common to +STREAM tests: Options common to TCP UDP and SCTP tests, the following +test-specific options can be included to possibly alter the behavior of +the test: + +`-C' + This option will set TCP_CORK mode on the data connection on those + systems where TCP_CORK is defined (typically Linux). A full + description of TCP_CORK is beyond the scope of this manual, but in + a nutshell it forces sub-MSS sends to be buffered so every segment + sent is Maximum Segment Size (MSS) unless the application performs + an explicit flush operation or the connection is closed. At + present netperf does not perform any explicit flush operations. + Setting TCP_CORK may improve the bitrate of tests where the "send + size" (`-m' option) is smaller than the MSS. It should also + improve (make smaller) the service demand. + + The Linux tcp(7) manpage states that TCP_CORK cannot be used in + conjunction with TCP_NODELAY (set via the `-d' option), however + netperf does not validate command-line options to enforce that. + +`-D' + This option will set TCP_NODELAY on the data connection on those + systems where TCP_NODELAY is defined. This disables something + known as the Nagle Algorithm, which is intended to make the + segments TCP sends as large as reasonably possible. Setting + TCP_NODELAY for a TCP_STREAM test should either have no effect + when the send size (`-m' option) is larger than the MSS or will + decrease reported bitrate and increase service demand when the + send size is smaller than the MSS. This stems from TCP_NODELAY + causing each sub-MSS send to be its own TCP segment rather than + being aggregated with other small sends. This means more trips up + and down the protocol stack per KB of data transferred, which + means greater CPU utilization. + + If setting TCP_NODELAY with `-D' affects throughput and/or service + demand for tests where the send size (`-m') is larger than the MSS + it suggests the TCP/IP stack's implementation of the Nagle + Algorithm _may_ be broken, perhaps interpreting the Nagle + Algorithm on a segment by segment basis rather than the proper user + send by user send basis. However, a better test of this can be + achieved with the *note TCP_RR:: test. + + + Here is an example of a basic TCP_STREAM test, in this case from a +Debian Linux (2.6 kernel) system to an HP-UX 11iv2 (HP-UX 11.23) system: + + $ netperf -H lag + TCP STREAM TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to lag.hpl.hp.com (15.4.89.214) port 0 AF_INET + Recv Send Send + Socket Socket Message Elapsed + Size Size Size Time Throughput + bytes bytes bytes secs. 10^6bits/sec + + 32768 16384 16384 10.00 80.42 + + We see that the default receive socket buffer size for the receiver +(lag - HP-UX 11.23) is 32768 bytes, and the default socket send buffer +size for the sender (Debian 2.6 kernel) is 16384 bytes. Througput is +expressed as 10^6 (aka Mega) bits per second, and the test ran for 10 +seconds. IPv4 addresses (AF_INET) were used. + + +File: netperf.info, Node: TCP_MAERTS, Next: TCP_SENDFILE, Prev: TCP_STREAM, Up: Options common to TCP UDP and SCTP tests + +5.2.2 TCP_MAERTS +---------------- + +A TCP_MAERTS (MAERTS is STREAM backwards) test is "just like" a *note +TCP_STREAM:: test except the data flows from the netserver to the +netperf. The global command-line `-F' option is ignored for this test +type. The test-specific command-line `-C' option is ignored for this +test type. + + Here is an example of a TCP_MAERTS test between the same two systems +as in the example for the *note TCP_STREAM:: test. This time we request +larger socket buffers with `-s' and `-S' options: + + $ netperf -H lag -t TCP_MAERTS -- -s 128K -S 128K + TCP MAERTS TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to lag.hpl.hp.com (15.4.89.214) port 0 AF_INET + Recv Send Send + Socket Socket Message Elapsed + Size Size Size Time Throughput + bytes bytes bytes secs. 10^6bits/sec + + 221184 131072 131072 10.03 81.14 + + Where we see that Linux, unlike HP-UX, may not return the same value +in a getsockopt() as was requested in the prior setsockopt(). + + This test is included more for benchmarking convenience than anything +else. + + +File: netperf.info, Node: TCP_SENDFILE, Next: UDP_STREAM, Prev: TCP_MAERTS, Up: Options common to TCP UDP and SCTP tests + +5.2.3 TCP_SENDFILE +------------------ + +The TCP_SENDFILE test is "just like" a *note TCP_STREAM:: test except +netperf the platform's `sendfile()' call instead of calling `send()'. +Often this results in a "zero-copy" operation where data is sent +directly from the filesystem buffer cache. This _should_ result in +lower CPU utilization and possibly higher throughput. If it does not, +then you may want to contact your vendor(s) because they have a problem +on their hands. + + Zero-copy mechanisms may also alter the characteristics (size and +number of buffers per) of packets passed to the NIC. In many stacks, +when a copy is performed, the stack can "reserve" space at the +beginning of the destination buffer for things like TCP, IP and Link +headers. This then has the packet contained in a single buffer which +can be easier to DMA to the NIC. When no copy is performed, there is +no opportunity to reserve space for headers and so a packet will be +contained in two or more buffers. + + The *note global `-F' option: Global Options. is required for this +test and it must specify a file of at least the size of the send ring +(*Note the global `-W' option: Global Options.) multiplied by the send +size (*Note the test-specific `-m' option: Options common to TCP UDP +and SCTP tests.). All other TCP-specific options are available and +optional. + + In this first example: + $ netperf -H lag -F ../src/netperf -t TCP_SENDFILE -- -s 128K -S 128K + TCP SENDFILE TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to lag.hpl.hp.com (15.4.89.214) port 0 AF_INET + alloc_sendfile_buf_ring: specified file too small. + file must be larger than send_width * send_size + + we see what happens when the file is too small. Here: + + $ ../src/netperf -H lag -F /boot/vmlinuz-2.6.8-1-686 -t TCP_SENDFILE -- -s 128K -S 128K + TCP SENDFILE TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to lag.hpl.hp.com (15.4.89.214) port 0 AF_INET + Recv Send Send + Socket Socket Message Elapsed + Size Size Size Time Throughput + bytes bytes bytes secs. 10^6bits/sec + + 131072 221184 221184 10.02 81.83 + + we resolve that issue by selecting a larger file. + + +File: netperf.info, Node: UDP_STREAM, Next: XTI_TCP_STREAM, Prev: TCP_SENDFILE, Up: Options common to TCP UDP and SCTP tests + +5.2.4 UDP_STREAM +---------------- + +A UDP_STREAM test is similar to a *note TCP_STREAM:: test except UDP is +used as the transport rather than TCP. + + A UDP_STREAM test has no end-to-end flow control - UDP provides none +and neither does netperf. However, if you wish, you can configure +netperf with `--enable-intervals=yes' to enable the global command-line +`-b' and `-w' options to pace bursts of traffic onto the network. + + This has a number of implications. + + The biggest of these implications is the data which is sent might not +be received by the remote. For this reason, the output of a UDP_STREAM +test shows both the sending and receiving throughput. On some +platforms, it may be possible for the sending throughput to be reported +as a value greater than the maximum rate of the link. This is common +when the CPU(s) are faster than the network and there is no +"intra-stack" flow-control. + + Here is an example of a UDP_STREAM test between two systems connected +by a 10 Gigabit Ethernet link: + $ netperf -t UDP_STREAM -H 192.168.2.125 -- -m 32768 + UDP UNIDIRECTIONAL SEND TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to 192.168.2.125 (192.168.2.125) port 0 AF_INET + Socket Message Elapsed Messages + Size Size Time Okay Errors Throughput + bytes bytes secs # # 10^6bits/sec + + 124928 32768 10.00 105672 0 2770.20 + 135168 10.00 104844 2748.50 + + The first line of numbers are statistics from the sending (netperf) +side. The second line of numbers are from the receiving (netserver) +side. In this case, 105672 - 104844 or 828 messages did not make it +all the way to the remote netserver process. + + If the value of the `-m' option is larger than the local send socket +buffer size (`-s' option) netperf will likely abort with an error +message about how the send call failed: + + netperf -t UDP_STREAM -H 192.168.2.125 + UDP UNIDIRECTIONAL SEND TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to 192.168.2.125 (192.168.2.125) port 0 AF_INET + udp_send: data send error: Message too long + + If the value of the `-m' option is larger than the remote socket +receive buffer, the reported receive throughput will likely be zero as +the remote UDP will discard the messages as being too large to fit into +the socket buffer. + + $ netperf -t UDP_STREAM -H 192.168.2.125 -- -m 65000 -S 32768 + UDP UNIDIRECTIONAL SEND TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to 192.168.2.125 (192.168.2.125) port 0 AF_INET + Socket Message Elapsed Messages + Size Size Time Okay Errors Throughput + bytes bytes secs # # 10^6bits/sec + + 124928 65000 10.00 53595 0 2786.99 + 65536 10.00 0 0.00 + + The example above was between a pair of systems running a "Linux" +kernel. Notice that the remote Linux system returned a value larger +than that passed-in to the `-S' option. In fact, this value was larger +than the message size set with the `-m' option. That the remote socket +buffer size is reported as 65536 bytes would suggest to any sane person +that a message of 65000 bytes would fit, but the socket isn't _really_ +65536 bytes, even though Linux is telling us so. Go figure. + + +File: netperf.info, Node: XTI_TCP_STREAM, Next: XTI_UDP_STREAM, Prev: UDP_STREAM, Up: Options common to TCP UDP and SCTP tests + +5.2.5 XTI_TCP_STREAM +-------------------- + +An XTI_TCP_STREAM test is simply a *note TCP_STREAM:: test using the XTI +rather than BSD Sockets interface. The test-specific `-X ' +option can be used to specify the name of the local and/or remote XTI +device files, which is required by the `t_open()' call made by netperf +XTI tests. + + The XTI_TCP_STREAM test is only present if netperf was configured +with `--enable-xti=yes'. The remote netserver must have also been +configured with `--enable-xti=yes'. + + +File: netperf.info, Node: XTI_UDP_STREAM, Next: SCTP_STREAM, Prev: XTI_TCP_STREAM, Up: Options common to TCP UDP and SCTP tests + +5.2.6 XTI_UDP_STREAM +-------------------- + +An XTI_UDP_STREAM test is simply a *note UDP_STREAM:: test using the XTI +rather than BSD Sockets Interface. The test-specific `-X ' +option can be used to specify the name of the local and/or remote XTI +device files, which is required by the `t_open()' call made by netperf +XTI tests. + + The XTI_UDP_STREAM test is only present if netperf was configured +with `--enable-xti=yes'. The remote netserver must have also been +configured with `--enable-xti=yes'. + + +File: netperf.info, Node: SCTP_STREAM, Next: DLCO_STREAM, Prev: XTI_UDP_STREAM, Up: Options common to TCP UDP and SCTP tests + +5.2.7 SCTP_STREAM +----------------- + +An SCTP_STREAM test is essentially a *note TCP_STREAM:: test using the +SCTP rather than TCP. The `-D' option will set SCTP_NODELAY, which is +much like the TCP_NODELAY option for TCP. The `-C' option is not +applicable to an SCTP test as there is no corresponding SCTP_CORK +option. The author is still figuring-out what the test-specific `-N' +option does :) + + The SCTP_STREAM test is only present if netperf was configured with +`--enable-sctp=yes'. The remote netserver must have also been +configured with `--enable-sctp=yes'. + + +File: netperf.info, Node: DLCO_STREAM, Next: DLCL_STREAM, Prev: SCTP_STREAM, Up: Options common to TCP UDP and SCTP tests + +5.2.8 DLCO_STREAM +----------------- + +A DLPI Connection Oriented Stream (DLCO_STREAM) test is very similar in +concept to a *note TCP_STREAM:: test. Both use reliable, +connection-oriented protocols. The DLPI test differs from the TCP test +in that its protocol operates only at the link-level and does not +include TCP-style segmentation and reassembly. This last difference +means that the value passed-in with the `-m' option must be less than +the interface MTU. Otherwise, the `-m' and `-M' options are just like +their TCP/UDP/SCTP counterparts. + + Other DLPI-specific options include: + +`-D ' + This option is used to provide the fully-qualified names for the + local and/or remote DPLI device files. The syntax is otherwise + identical to that of a "sizespec". + +`-p ' + This option is used to specify the local and/or remote DLPI PPA(s). + The PPA is used to identify the interface over which traffic is to + be sent/received. The syntax of a "ppaspec" is otherwise the same + as a "sizespec". + +`-s sap' + This option specifies the 802.2 SAP for the test. A SAP is + somewhat like either the port field of a TCP or UDP header or the + protocol field of an IP header. The specified SAP should not + conflict with any other active SAPs on the specified PPA's (`-p' + option). + +`-w ' + This option specifies the local send and receive window sizes in + units of frames on those platforms which support setting such + things. + +`-W ' + This option specifies the remote send and receive window sizes in + units of frames on those platforms which support setting such + things. + + The DLCO_STREAM test is only present if netperf was configured with +`--enable-dlpi=yes'. The remote netserver must have also been +configured with `--enable-dlpi=yes'. + + +File: netperf.info, Node: DLCL_STREAM, Next: STREAM_STREAM, Prev: DLCO_STREAM, Up: Options common to TCP UDP and SCTP tests + +5.2.9 DLCL_STREAM +----------------- + +A DLPI ConnectionLess Stream (DLCL_STREAM) test is analogous to a *note +UDP_STREAM:: test in that both make use of unreliable/best-effort, +connection-less transports. The DLCL_STREAM test differs from the +*note UDP_STREAM:: test in that the message size (`-m' option) must +always be less than the link MTU as there is no IP-like fragmentation +and reassembly available and netperf does not presume to provide one. + + The test-specific command-line options for a DLCL_STREAM test are the +same as those for a *note DLCO_STREAM:: test. + + The DLCL_STREAM test is only present if netperf was configured with +`--enable-dlpi=yes'. The remote netserver must have also been +configured with `--enable-dlpi=yes'. + + +File: netperf.info, Node: STREAM_STREAM, Next: DG_STREAM, Prev: DLCL_STREAM, Up: Options common to TCP UDP and SCTP tests + +5.2.10 STREAM_STREAM +-------------------- + +A Unix Domain Stream Socket Stream test (STREAM_STREAM) is similar in +concept to a *note TCP_STREAM:: test, but using Unix Domain sockets. +It is, naturally, limited to intra-machine traffic. A STREAM_STREAM +test shares the `-m', `-M', `-s' and `-S' options of the other _STREAM +tests. In a STREAM_STREAM test the `-p' option sets the directory in +which the pipes will be created rather than setting a port number. The +default is to create the pipes in the system default for the +`tempnam()' call. + + The STREAM_STREAM test is only present if netperf was configured with +`--enable-unix=yes'. The remote netserver must have also been +configured with `--enable-unix=yes'. + + +File: netperf.info, Node: DG_STREAM, Prev: STREAM_STREAM, Up: Options common to TCP UDP and SCTP tests + +5.2.11 DG_STREAM +---------------- + +A Unix Domain Datagram Socket Stream test (SG_STREAM) is very much like +a *note TCP_STREAM:: test except that message boundaries are preserved. +In this way, it may also be considered similar to certain flavors of +SCTP test which can also preserve message boundaries. + + All the options of a *note STREAM_STREAM:: test are applicable to a +DG_STREAM test. + + The DG_STREAM test is only present if netperf was configured with +`--enable-unix=yes'. The remote netserver must have also been +configured with `--enable-unix=yes'. + + +File: netperf.info, Node: Using Netperf to Measure Request/Response, Next: Using Netperf to Measure Aggregate Performance, Prev: Using Netperf to Measure Bulk Data Transfer, Up: Top + +6 Using Netperf to Measure Request/Response +******************************************* + +Request/response performance is often overlooked, yet it is just as +important as bulk-transfer performance. While things like larger +socket buffers and TCP windows can cover a multitude of latency and +even path-length sins, they cannot easily hide from a request/response +test. The convention for a request/response test is to have a _RR +suffix. There are however a few "request/response" tests that have +other suffixes. + + A request/response test, particularly synchronous, one transaction at +at time test such as those found in netperf, is particularly sensitive +to the path-length of the networking stack. An _RR test can also +uncover those platforms where the NIC's are strapped by default with +overbearing interrupt avoidance settings in an attempt to increase the +bulk-transfer performance (or rather, decrease the CPU utilization of a +bulk-transfer test). This sensitivity is most acute for small request +and response sizes, such as the single-byte default for a netperf _RR +test. + + While a bulk-transfer test reports its results in units of bits or +bytes transfered per second, a mumble_RR test reports transactions per +second where a transaction is defined as the completed exchange of a +request and a response. One can invert the transaction rate to arrive +at the average round-trip latency. If one is confident about the +symmetry of the connection, the average one-way latency can be taken as +one-half the average round-trip latency. Netperf does not do either of +these on its own but leaves them as exercises to the benchmarker. + +* Menu: + +* Issues in Request/Response:: +* Options Common to TCP UDP and SCTP _RR tests:: + + +File: netperf.info, Node: Issues in Request/Response, Next: Options Common to TCP UDP and SCTP _RR tests, Prev: Using Netperf to Measure Request/Response, Up: Using Netperf to Measure Request/Response + +6.1 Issues in Reqeust/Response +============================== + +Most if not all the *note Issues in Bulk Transfer:: apply to +request/response. The issue of round-trip latency is even more +important as netperf generally only has one transaction outstanding at +a time. + + A single instance of a one transaction outstanding _RR test should +_never_ completely saturate the CPU of a system. If testing between +otherwise evenly matched systems, the symmetric nature of a _RR test +with equal request and response sizes should result in equal CPU +loading on both systems. However, this may not hold true on MP systems, +particularly if one CPU binds the netperf and netserver differently via +the global `-T' option. + + For smaller request and response sizes packet loss is a bigger issue +as there is no opportunity for a "fast retransmit" or retransmission +prior to a retransmission timer expiring. + + Certain NICs have ways to minimize the number of interrupts sent to +the host. If these are strapped badly they can significantly reduce +the performance of something like a single-byte request/response test. +Such setups are distinguised by seriously low reported CPU utilization +and what seems like a low (even if in the thousands) transaction per +second rate. Also, if you run such an OS/driver combination on faster +or slower hardware and do not see a corresponding change in the +transaction rate, chances are good that the drvier is strapping the NIC +with aggressive interrupt avoidance settings. Good for bulk +throughput, but bad for latency. + + Some drivers may try to automagically adjust the interrupt avoidance +settings. If they are not terribly good at it, you will see +considerable run-to-run variation in reported transaction rates. +Particularly if you "mix-up" _STREAM and _RR tests. + + +File: netperf.info, Node: Options Common to TCP UDP and SCTP _RR tests, Prev: Issues in Request/Response, Up: Using Netperf to Measure Request/Response + +6.2 Options Common to TCP UDP and SCTP _RR tests +================================================ + +Many "test-specific" options are actually common across the different +tests. For those tests involving TCP, UDP and SCTP, whether using the +BSD Sockets or the XTI interface those common options include: + +`-h' + Display the test-suite-specific usage string and exit. For a TCP_ + or UDP_ test this will be the usage string from the source file + `nettest_bsd.c'. For an XTI_ test, this will be the usage string + from the source file `src/nettest_xti.c'. For an SCTP test, this + will be the usage string from the source file `src/nettest_sctp.c'. + +`-H ' + Normally, the remote hostname|IP and address family information is + inherited from the settings for the control connection (eg global + command-line `-H', `-4' and/or `-6' options. The test-specific + `-H' will override those settings for the data (aka test) + connection only. Settings for the control connection are left + unchanged. This might be used to cause the control and data + connections to take different paths through the network. + +`-L ' + The test-specific `-L' option is identical to the test-specific + `-H' option except it affects the local hostname|IP and address + family information. As with its global command-line counterpart, + this is generally only useful when measuring though those evil, + end-to-end breaking things called firewalls. + +`-P ' + Set the local and/or remote port numbers for the data connection. + +`-r ' + This option sets the request (first value) and/or response (second + value) sizes for an _RR test. By default the units are bytes, but a + suffix of "G," "M," or "K" will specify the units to be 2^30 (GB), + 2^20 (MB) or 2^10 (KB) respectively. A suffix of "g," "m" or "k" + will specify units of 10^9, 10^6 or 10^3 bytes respectively. For + example: + `-r 128,16K' + Will set the request size to 128 bytes and the response size to 16 + KB or 16384 bytes. [Default: 1 - a single-byte request and + response ] + +`-s ' + This option sets the local send and receive socket buffer sizes for + the data connection to the value(s) specified. Often, this will + affect the advertised and/or effective TCP or other window, but on + some platforms it may not. By default the units are bytes, but a + suffix of "G," "M," or "K" will specify the units to be 2^30 (GB), + 2^20 (MB) or 2^10 (KB) respectively. A suffix of "g," "m" or "k" + will specify units of 10^9, 10^6 or 10^3 bytes respectively. For + example: + `-s 128K' + Will request the local send and receive socket buffer sizes to be + 128KB or 131072 bytes. + + While the historic expectation is that setting the socket buffer + size has a direct effect on say the TCP window, today that may not + hold true for all stacks. When running under Windows a value of 0 + may be used which will be an indication to the stack the user + wants to enable a form of copy avoidance. [Default: -1 - use the + system's default socket buffer sizes] + +`-S ' + This option sets the remote send and/or receive socket buffer sizes + for the data connection to the value(s) specified. Often, this + will affect the advertised and/or effective TCP or other window, + but on some platforms it may not. By default the units are bytes, + but a suffix of "G," "M," or "K" will specify the units to be 2^30 + (GB), 2^20 (MB) or 2^10 (KB) respectively. A suffix of "g," "m" + or "k" will specify units of 10^9, 10^6 or 10^3 bytes respectively. + For example: + `-s 128K' + Will request the local send and receive socket buffer sizes to be + 128KB or 131072 bytes. + + While the historic expectation is that setting the socket buffer + size has a direct effect on say the TCP window, today that may not + hold true for all stacks. When running under Windows a value of 0 + may be used which will be an indication to the stack the user + wants to enable a form of copy avoidance. [Default: -1 - use the + system's default socket buffer sizes] + +`-4' + Set the local and remote address family for the data connection to + AF_INET - ie use IPv4 addressing only. Just as with their global + command-line counterparts the last of the `-4', `-6', `-H' or `-L' + option wins for their respective address families. + +`-6' + This option is identical to its `-4' cousin, but requests IPv6 + addresses for the local and remote ends of the data connection. + + +* Menu: + +* TCP_RR:: +* TCP_CC:: +* TCP_CRR:: +* UDP_RR:: +* XTI_TCP_RR:: +* XTI_TCP_CC:: +* XTI_TCP_CRR:: +* XTI_UDP_RR:: +* DLCL_RR:: +* DLCO_RR:: +* SCTP_RR:: + + +File: netperf.info, Node: TCP_RR, Next: TCP_CC, Prev: Options Common to TCP UDP and SCTP _RR tests, Up: Options Common to TCP UDP and SCTP _RR tests + +6.2.1 TCP_RR +------------ + +A TCP_RR (TCP Request/Response) test is requested by passing a value of +"TCP_RR" to the global `-t' command-line option. A TCP_RR test can be +though-of as a user-space to user-space `ping' with no think time - it +is a synchronous, one transaction at a time, request/response test. + + The transaction rate is the number of complete transactions exchanged +divided by the length of time it took to perform those transactions. + + If the two Systems Under Test are otherwise identical, a TCP_RR test +with the same request and response size should be symmetric - it should +not matter which way the test is run, and the CPU utilization measured +should be virtually the same on each system. If not, it suggests that +the CPU utilization mechanism being used may have some, well, issues +measuring CPU utilization completely and accurately. + + Time to establish the TCP connection is not counted in the result. +If you want connection setup overheads included, you should consider the +TCP_CC or TCP_CRR tests. + + If specifying the `-D' option to set TCP_NODELAY and disable the +Nagle Algorithm increases the transaction rate reported by a TCP_RR +test, it implies the stack(s) over which the TCP_RR test is running +have a broken implementation of the Nagle Algorithm. Likely as not +they are interpreting Nagle on a segment by segment basis rather than a +user send by user send basis. You should contact your stack vendor(s) +to report the problem to them. + + Here is an example of two systems running a basic TCP_RR test over a +10 Gigabit Ethernet link: + + netperf -t TCP_RR -H 192.168.2.125 + TCP REQUEST/RESPONSE TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to 192.168.2.125 (192.168.2.125) port 0 AF_INET + Local /Remote + Socket Size Request Resp. Elapsed Trans. + Send Recv Size Size Time Rate + bytes Bytes bytes bytes secs. per sec + + 16384 87380 1 1 10.00 29150.15 + 16384 87380 + + In this example the request and response sizes were one byte, the +socket buffers were left at their defaults, and the test ran for all of +10 seconds. The transaction per second rate was rather good :) + + +File: netperf.info, Node: TCP_CC, Next: TCP_CRR, Prev: TCP_RR, Up: Options Common to TCP UDP and SCTP _RR tests + +6.2.2 TCP_CC +------------ + +A TCP_CC (TCP Connect/Close) test is requested by passing a value of +"TCP_CC" to the global `-t' option. A TCP_CC test simply measures how +fast the pair of systems can open and close connections between one +another in a synchronous (one at a time) manner. While this is +considered an _RR test, no request or response is exchanged over the +connection. + + The issue of TIME_WAIT reuse is an important one for a TCP_CC test. +Basically, TIME_WAIT reuse is when a pair of systems churn through +connections fast enough that they wrap the 16-bit port number space in +less time than the length of the TIME_WAIT state. While it is indeed +theoretically possible to "reuse" a connection in TIME_WAIT, the +conditions under which such reuse is possible are rather rare. An +attempt to reuse a connection in TIME_WAIT can result in a non-trivial +delay in connection establishment. + + Basically, any time the connection churn rate approaches: + + Sizeof(clientportspace) / Lengthof(TIME_WAIT) + + there is the risk of TIME_WAIT reuse. To minimize the chances of +this happening, netperf will by default select its own client port +numbers from the range of 5000 to 65535. On systems with a 60 second +TIME_WAIT state, this should allow roughly 1000 transactions per +second. The size of the client port space used by netperf can be +controlled via the test-specific `-p' option, which takes a "sizespec" +as a value setting the minimum (first value) and maximum (second value) +port numbers used by netperf at the client end. + + Since no requests or responses are exchanged during a TCP_CC test, +only the `-H', `-L', `-4' and `-6' of the "common" test-specific +options are likely to have an effect, if any, on the results. The `-s' +and `-S' options _may_ have some effect if they alter the number and/or +type of options carried in the TCP SYNchronize segments. The `-P' and +`-r' options are utterly ignored. + + Since connection establishment and tear-down for TCP is not +symmetric, a TCP_CC test is not symmetric in its loading of the two +systems under test. + + +File: netperf.info, Node: TCP_CRR, Next: UDP_RR, Prev: TCP_CC, Up: Options Common to TCP UDP and SCTP _RR tests + +6.2.3 TCP_CRR +------------- + +The TCP Connect/Request/Response (TCP_CRR) test is requested by passing +a value of "TCP_CRR" to the global `-t' command-line option. A TCP_RR +test is like a merger of a TCP_RR and TCP_CC test which measures the +performance of establishing a connection, exchanging a single +request/response transaction, and tearing-down that connection. This +is very much like what happens in an HTTP 1.0 or HTTP 1.1 connection +when HTTP Keepalives are not used. In fact, the TCP_CRR test was added +to netperf to simulate just that. + + Since a request and response are exchanged the `-r', `-s' and `-S' +options can have an effect on the performance. + + The issue of TIME_WAIT reuse exists for the TCP_CRR test just as it +does for the TCP_CC test. Similarly, since connection establishment +and tear-down is not symmetric, a TCP_CRR test is not symmetric even +when the request and response sizes are the same. + + +File: netperf.info, Node: UDP_RR, Next: XTI_TCP_RR, Prev: TCP_CRR, Up: Options Common to TCP UDP and SCTP _RR tests + +6.2.4 UDP_RR +------------ + +A UDP Request/Response (UDP_RR) test is requested by passing a value of +"UDP_RR" to a global `-t' option. It is very much the same as a TCP_RR +test except UDP is used rather than TCP. + + UDP does not provide for retransmission of lost UDP datagrams, and +netperf does not add anything for that either. This means that if +_any_ request or response is lost, the exchange of requests and +responses will stop from that point until the test timer expires. +Netperf will not really "know" this has happened - the only symptom +will be a low transaction per second rate. + + The netperf side of a UDP_RR test will call `connect()' on its data +socket and thenceforth use the `send()' and `recv()' socket calls. The +netserver side of a UDP_RR test will not call `connect()' and will use +`recvfrom()' and `sendto()' calls. This means that even if the request +and response sizes are the same, a UDP_RR test is _not_ symmetric in +its loading of the two systems under test. + + Here is an example of a UDP_RR test between two otherwise identical +two-CPU systems joined via a 1 Gigabit Ethernet network: + + $ netperf -T 1 -H 192.168.1.213 -t UDP_RR -c -C + UDP REQUEST/RESPONSE TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to 192.168.1.213 (192.168.1.213) port 0 AF_INET + Local /Remote + Socket Size Request Resp. Elapsed Trans. CPU CPU S.dem S.dem + Send Recv Size Size Time Rate local remote local remote + bytes bytes bytes bytes secs. per sec % I % I us/Tr us/Tr + + 65535 65535 1 1 10.01 15262.48 13.90 16.11 18.221 21.116 + 65535 65535 + + This example includes the `-c' and `-C' options to enable CPU +utilization reporting and shows the asymmetry in CPU loading. The `-T' +option was used to make sure netperf and netserver ran on a given CPU +and did not move around during the test. + + +File: netperf.info, Node: XTI_TCP_RR, Next: XTI_TCP_CC, Prev: UDP_RR, Up: Options Common to TCP UDP and SCTP _RR tests + +6.2.5 XTI_TCP_RR +---------------- + +An XTI_TCP_RR test is essentially the same as a *note TCP_RR:: test only +using the XTI rather than BSD Sockets interface. It is requested by +passing a value of "XTI_TCP_RR" to the `-t' global command-line option. + + The test-specific options for an XTI_TCP_RR test are the same as +those for a TCP_RR test with the addition of the `-X ' option +to specify the names of the local and/or remote XTI device file(s). + + +File: netperf.info, Node: XTI_TCP_CC, Next: XTI_TCP_CRR, Prev: XTI_TCP_RR, Up: Options Common to TCP UDP and SCTP _RR tests + +6.2.6 XTI_TCP_CC +---------------- + + +File: netperf.info, Node: XTI_TCP_CRR, Next: XTI_UDP_RR, Prev: XTI_TCP_CC, Up: Options Common to TCP UDP and SCTP _RR tests + +6.2.7 XTI_TCP_CRR +----------------- + + +File: netperf.info, Node: XTI_UDP_RR, Next: DLCL_RR, Prev: XTI_TCP_CRR, Up: Options Common to TCP UDP and SCTP _RR tests + +6.2.8 XTI_UDP_RR +---------------- + +An XTI_UDP_RR test is essentially the same as a UDP_RR test only using +the XTI rather than BSD Sockets interface. It is requested by passing +a value of "XTI_UDP_RR" to the `-t' global command-line option. + + The test-specific options for an XTI_UDP_RR test are the same as +those for a UDP_RR test with the addition of the `-X ' option +to specify the name of the local and/or remote XTI device file(s). + + +File: netperf.info, Node: DLCL_RR, Next: DLCO_RR, Prev: XTI_UDP_RR, Up: Options Common to TCP UDP and SCTP _RR tests + +6.2.9 DLCL_RR +------------- + + +File: netperf.info, Node: DLCO_RR, Next: SCTP_RR, Prev: DLCL_RR, Up: Options Common to TCP UDP and SCTP _RR tests + +6.2.10 DLCO_RR +-------------- + + +File: netperf.info, Node: SCTP_RR, Prev: DLCO_RR, Up: Options Common to TCP UDP and SCTP _RR tests + +6.2.11 SCTP_RR +-------------- + + +File: netperf.info, Node: Using Netperf to Measure Aggregate Performance, Next: Using Netperf to Measure Bidirectional Transfer, Prev: Using Netperf to Measure Request/Response, Up: Top + +7 Using Netperf to Measure Aggregate Performance +************************************************ + +*note Netperf4: Netperf4. is the preferred benchmark to use when one +wants to measure aggregate performance because netperf has no support +for explicit synchronization of concurrent tests. + + Basically, there are two ways to measure aggregate performance with +netperf. The first is to run multiple, concurrent netperf tests and +can be applied to any of the netperf tests. The second is to configure +netperf with `--enable-burst' and is applicable to the TCP_RR test. + +* Menu: + +* Running Concurrent Netperf Tests:: +* Using --enable-burst:: + + +File: netperf.info, Node: Running Concurrent Netperf Tests, Next: Using --enable-burst, Prev: Using Netperf to Measure Aggregate Performance, Up: Using Netperf to Measure Aggregate Performance + +7.1 Running Concurrent Netperf Tests +==================================== + +*note Netperf4: Netperf4. is the preferred benchmark to use when one +wants to measure aggregate performance because netperf has no support +for explicit synchronization of concurrent tests. This leaves netperf2 +results vulnerable to "skew" errors. + + However, since there are times when netperf4 is unavailable it may be +necessary to run netperf. The skew error can be minimized by making use +of the confidence interval functionality. Then one simply launches +multiple tests from the shell using a `for' loop or the like: + + for i in 1 2 3 4 + do + netperf -t TCP_STREAM -H tardy.cup.hp.com -i 10 -P 0 & + done + + which will run four, concurrent *note TCP_STREAM: TCP_STREAM. tests +from the system on which it is executed to tardy.cup.hp.com. Each +concurrent netperf will iterate 10 times thanks to the `-i' option and +will omit the test banners (option `-P') for brevity. The output looks +something like this: + + 87380 16384 16384 10.03 235.15 + 87380 16384 16384 10.03 235.09 + 87380 16384 16384 10.03 235.38 + 87380 16384 16384 10.03 233.96 + + We can take the sum of the results and be reasonably confident that +the aggregate performance was 940 Mbits/s. + + If you see warnings about netperf not achieving the confidence +intervals, the best thing to do is to increase the number of iterations +with `-i' and/or increase the run length of each iteration with `-l'. + + You can also enable local (`-c') and/or remote (`-C') CPU +utilization: + + for i in 1 2 3 4 + do + netperf -t TCP_STREAM -H tardy.cup.hp.com -i 10 -P 0 -c -C & + done + + 87380 16384 16384 10.03 235.47 3.67 5.09 10.226 14.180 + 87380 16384 16384 10.03 234.73 3.67 5.09 10.260 14.225 + 87380 16384 16384 10.03 234.64 3.67 5.10 10.263 14.231 + 87380 16384 16384 10.03 234.87 3.67 5.09 10.253 14.215 + + If the CPU utilizations reported for the same system are the same or +very very close you can be reasonably confident that skew error is +minimized. Presumeably one could then omit `-i' but that is not +advised, particularly when/if the CPU utilization approaches 100 +percent. In the example above we see that the CPU utilization on the +local system remains the same for all four tests, and is only off by +0.01 out of 5.09 on the remote system. + + NOTE: It is very important to rememeber that netperf is calculating + system-wide CPU utilization. When calculating the service demand + (those last two columns in the output above) each netperf assumes + it is the only thing running on the system. This means that for + concurrent tests the service demands reported by netperf will be + wrong. One has to compute service demands for concurrent tests by + hand. + + If you wish you can add a unique, global `-B' option to each command +line to append the given string to the output: + + for i in 1 2 3 4 + do + netperf -t TCP_STREAM -H tardy.cup.hp.com -B "this is test $i" -i 10 -P 0 & + done + + 87380 16384 16384 10.03 234.90 this is test 4 + 87380 16384 16384 10.03 234.41 this is test 2 + 87380 16384 16384 10.03 235.26 this is test 1 + 87380 16384 16384 10.03 235.09 this is test 3 + + You will notice that the tests completed in an order other than they +were started from the shell. This underscores why there is a threat of +skew error and why netperf4 is the preferred tool for aggregate tests. +Even if you see the Netperf Contributing Editor acting to the +contrary!-) + + +File: netperf.info, Node: Using --enable-burst, Prev: Running Concurrent Netperf Tests, Up: Using Netperf to Measure Aggregate Performance + +7.2 Using -enable-burst +======================= + +If one configures netperf with `--enable-burst': + + configure --enable-burst + + Then a test-specific `-b num' option is added to the *note TCP_RR: +TCP_RR. and *note UDP_RR: UDP_RR. tests. This option causes TCP_RR and +UDP_RR to quickly work their way up to having at least `num' +transactions in flight at one time. + + This is used as an alternative to or even in conjunction with +multiple-concurrent _RR tests. When run with just a single instance of +netperf, increasing the burst size can determine the maximum number of +transactions per second can be serviced by a single process: + + for b in 0 1 2 4 8 16 32 + do + netperf -v 0 -t TCP_RR -B "-b $b" -H hpcpc108 -P 0 -- -b $b + done + + 9457.59 -b 0 + 9975.37 -b 1 + 10000.61 -b 2 + 20084.47 -b 4 + 29965.31 -b 8 + 71929.27 -b 16 + 109718.17 -b 32 + + The global `-v' and `-P' options were used to minimize the output to +the single figure of merit which in this case the transaction rate. +The global `-B' option was used to more clearly label the output, and +the test-specific `-b' option enabled by `--enable-burst' set the +number of transactions in flight at one time. + + Now, since the test-specific `-D' option was not specified to set +TCP_NODELAY, the stack was free to "bundle" requests and/or responses +into TCP segments as it saw fit, and since the default request and +response size is one byte, there could have been some considerable +bundling. If one wants to try to achieve a closer to one-to-one +correspondence between a request and response and a TCP segment, add +the test-specific `-D' option: + + for b in 0 1 2 4 8 16 32 + do + netperf -v 0 -t TCP_RR -B "-b $b -D" -H hpcpc108 -P 0 -- -b $b -D + done + + 8695.12 -b 0 -D + 19966.48 -b 1 -D + 20691.07 -b 2 -D + 49893.58 -b 4 -D + 62057.31 -b 8 -D + 108416.88 -b 16 -D + 114411.66 -b 32 -D + + You can see that this has a rather large effect on the reported +transaction rate. In this particular instance, the author believes it +relates to interactions between the test and interrupt coalescing +settings in the driver for the NICs used. + + NOTE: Even if you set the `-D' option that is still not a + guarantee that each transaction is in its own TCP segments. You + should get into the habit of verifying the relationship between the + transaction rate and the packet rate via other means + + You can also combine `--enable-burst' functionality with concurrent +netperf tests. This would then be an "aggregate of aggregates" if you +like: + + + for i in 1 2 3 4 + do + netperf -H hpcpc108 -v 0 -P 0 -i 10 -B "aggregate $i -b 8 -D" -t TCP_RR -- -b 8 -D & + done + + 46668.38 aggregate 4 -b 8 -D + 44890.64 aggregate 2 -b 8 -D + 45702.04 aggregate 1 -b 8 -D + 46352.48 aggregate 3 -b 8 -D + + Since each netperf did hit the confidence intervals, we can be +reasonably certain that the aggregate transaction per second rate was +the sum of all four concurrent tests, or something just shy of 184,000 +transactions per second. To get some idea if that was also the packet +per second rate, we could bracket that `for' loop with something to +gather statistics and run the results through beforeafter +(ftp://ftp.cup.hp.com/dist/networking/tools): + + /usr/sbin/ethtool -S eth2 > before + for i in 1 2 3 4 + do + netperf -H 192.168.2.108 -l 60 -v 0 -P 0 -B "aggregate $i -b 8 -D" -t TCP_RR -- -b 8 -D & + done + wait + /usr/sbin/ethtool -S eth2 > after + + 52312.62 aggregate 2 -b 8 -D + 50105.65 aggregate 4 -b 8 -D + 50890.82 aggregate 1 -b 8 -D + 50869.20 aggregate 3 -b 8 -D + + beforeafter before after > delta + + grep packets delta + rx_packets: 12251544 + tx_packets: 12251550 + + This example uses `ethtool' because the system being used is running +Linux. Other platforms have other tools - for example HP-UX has +lanadmin: + + lanadmin -g mibstats + + and of course one could instead use `netstat'. + + The `wait' is important because we are launching concurrent netperfs +in the background. Without it, the second ethtool command would be run +before the tests finished and perhaps even before the last of them got +started! + + The sum of the reported transaction rates is 204178 over 60 seconds, +which is a total of 12250680 transactions. Each transaction is the +exchange of a request and a response, so we multiply that by 2 to +arrive at 24501360. + + The sum of the ethtool stats is 24503094 packets which matches what +netperf was reporting very well. + + Had the request or response size differed, we would need to know how +it compared with the "MSS" for the connection. + + Just for grins, here is the excercise repeated, using `netstat' +instead of `ethtool' + + netstat -s -t > before + for i in 1 2 3 4 + do + netperf -l 60 -H 192.168.2.108 -v 0 -P 0 -B "aggregate $i -b 8 -D" -t TCP_RR -- -b 8 -D & done + wait + netstat -s -t > after + + 51305.88 aggregate 4 -b 8 -D + 51847.73 aggregate 2 -b 8 -D + 50648.19 aggregate 3 -b 8 -D + 53605.86 aggregate 1 -b 8 -D + + beforeafter before after > delta + + grep segments delta + 12445708 segments received + 12445730 segments send out + 1 segments retransmited + 0 bad segments received. + + The sums are left as an excercise to the reader :) + + Things become considerably more complicated if there are non-trvial +packet losses and/or retransmissions. + + Of course all this checking is unnecessary if the test is a UDP_RR +test because UDP "never" aggregates multiple sends into the same UDP +datagram, and there are no ACKnowledgements in UDP. The loss of a +single request or response will not bring a "burst" UDP_RR test to a +screeching halt, but it will reduce the number of transactions +outstanding at any one time. A "burst" UDP_RR test will come to a halt +if the sum of the lost requests and responses reaches the value +specified in the test-specific `-b' option. + + +File: netperf.info, Node: Using Netperf to Measure Bidirectional Transfer, Next: Other Netperf Tests, Prev: Using Netperf to Measure Aggregate Performance, Up: Top + +8 Using Netperf to Measure Bidirectional Transfer +************************************************* + +There are two ways to use netperf to measure the perfomance of +bidirectional transfer. The first is to run concurrent netperf tests +from the command line. The second is to configure netperf with +`--enable-burst' and use a single instance of the *note TCP_RR: TCP_RR. +test. + + While neither method is more "correct" than the other, each is doing +so in different ways, and that has possible implications. For +instance, using the concurrent netperf test mechanism means that +multiple TCP connections and multiple processes are involved, whereas +using the single instance of TCP_RR there is only one TCP connection +and one process on each end. They may behave differently, especially +on an MP system. + +* Menu: + +* Bidirectional Transfer with Concurrent Tests:: +* Bidirectional Transfer with TCP_RR:: + + +File: netperf.info, Node: Bidirectional Transfer with Concurrent Tests, Next: Bidirectional Transfer with TCP_RR, Prev: Using Netperf to Measure Bidirectional Transfer, Up: Using Netperf to Measure Bidirectional Transfer + +8.1 Bidirectional Transfer with Concurrent Tests +================================================ + +If we had two hosts Fred and Ethel, we could simply run a netperf *note +TCP_STREAM: TCP_STREAM. test on Fred pointing at Ethel, and a +concurrent netperf TCP_STREAM test on Ethel pointing at Fred, but since +there are no mechanisms to synchronize netperf tests and we would be +starting tests from two different systems, there is a considerable risk +of skew error. + + Far better would be to run simultaneous TCP_STREAM and *note +TCP_MAERTS: TCP_MAERTS. tests from just one system, using the concepts +and procedures outlined in *note Running Concurrent Netperf Tests: +Running Concurrent Netperf Tests. Here then is an example: + + for i in 1 + do + netperf -H 192.168.2.108 -t TCP_STREAM -B "outbound" -i 10 -P 0 -v 0 -- -s 256K -S 256K & + netperf -H 192.168.2.108 -t TCP_MAERTS -B "inbound" -i 10 -P 0 -v 0 -- -s 256K -S 256K & + done + + 892.66 outbound + 891.34 inbound + + We have used a `for' loop in the shell with just one iteration +because that will be much easier to get both tests started at more or +less the same time than doing it by hand. The global `-P' and `-v' +options are used because we aren't interested in anything other than +the throughput, and the global `-B' option is used to tag each output +so we know which was inbound and which outbound relative to the system +on which we were running netperf. Of course that sense is switched on +the system running netserver :) The use of the global `-i' option is +explained in *note Running Concurrent Netperf Tests: Running Concurrent +Netperf Tests. + + +File: netperf.info, Node: Bidirectional Transfer with TCP_RR, Prev: Bidirectional Transfer with Concurrent Tests, Up: Using Netperf to Measure Bidirectional Transfer + +8.2 Bidirectional Transfer with TCP_RR +====================================== + +If one configures netperf with `--enable-burst' then one can use the +test-specific `-b' option to increase the number of transactions in +flight at one time. If one also uses the -r option to make those +transactions larger the test starts to look more and more like a +bidirectional transfer than a request/response test. + + Now, the logic behing `--enable-burst' is very simple, and there are +no calls to `poll()' or `select()' which means we want to make sure +that the `send()' calls will never block, or we run the risk of +deadlock with each side stuck trying to call `send()' and neither +calling `recv()'. + + Fortunately, this is easily accomplished by setting a "large enough" +socket buffer size with the test-specific `-s' and `-S' options. +Presently this must be performed by the user. Future versions of +netperf might attempt to do this automagically, but there are some +issues to be worked-out. + + Here then is an example of a bidirectional transfer test using +`--enable-burst' and the *note TCP_RR: TCP_RR. test: + + netperf -t TCP_RR -H hpcpc108 -- -b 6 -r 32K -s 256K -S 256K + TCP REQUEST/RESPONSE TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to hpcpc108.cup.hp.com (16.89.84.108) port 0 AF_INET : first burst 6 + Local /Remote + Socket Size Request Resp. Elapsed Trans. + Send Recv Size Size Time Rate + bytes Bytes bytes bytes secs. per sec + + 524288 524288 32768 32768 10.01 3525.97 + 524288 524288 + + Now, at present netperf does not include a bit or byte rate in the +output of an _RR test which means we must calculate it ourselves. Each +transaction is the exchange of 32768 bytes of request and 32768 bytes +of response, or 65536 bytes. Multiply that by 8 and we arrive at +524288 bits per transaction. Multiply that by 3525.97 and we arrive at +1848623759 bits per second. Since things were uniform, we can divide +that by two and arrive at roughly 924311879 bits per second each way. +That corresponds to "link-rate" for a 1 Gigiabit Ethernet which happens +to be the type of netpwrk used in the example. + + A future version of netperf may perform the calculation on behalf of +the user, but it would likely not emit it unless the user specified a +verbosity of 2 or more with the global `-v' option. + + +File: netperf.info, Node: Other Netperf Tests, Next: Address Resolution, Prev: Using Netperf to Measure Bidirectional Transfer, Up: Top + +9 Other Netperf Tests +********************* + +Apart from the typical performance tests, netperf contains some tests +which can be used to streamline measurements and reporting. These +include CPU rate calibration (present) and host identification (future +enhancement). + +* Menu: + +* CPU rate calibration:: + + +File: netperf.info, Node: CPU rate calibration, Prev: Other Netperf Tests, Up: Other Netperf Tests + +9.1 CPU rate calibration +======================== + +Some of the CPU utilization measurement mechanisms of netperf work by +comparing the rate at which some counter increments when the system is +idle with the rate at which that same counter increments when the +system is running a netperf test. The ratio of those rates is used to +arrive at a CPU utilization percentage. + + This means that netperf must know the rate at which the counter +increments when the system is presumed to be "idle." If it does not +know the rate, netperf will measure it before starting a data transfer +test. This calibration step takes 40 seconds for each of the local or +remote ystems, and if repeated for each netperf test would make taking +repeated measurements rather slow. + + Thus, the netperf CPU utilization options `-c' and and `-C' can take +an optional calibration value. This value is used as the "idle rate" +and the calibration step is not performed. To determine the idle rate, +netperf can be used to run special tests which only report the value of +the calibration - they are the LOC_CPU and REM_CPU tests. These return +the calibration value for the local and remote system respectively. A +common way to use these tests is to store their results into an +environment variable and use that in subsequent netperf commands: + + LOC_RATE=`netperf -t LOC_CPU` + REM_RATE=`netperf -H -t REM_CPU` + netperf -H -c $LOC_RATE -C $REM_RATE ... -- ... + ... + netperf -H -c $LOC_RATE -C $REM_RATE ... -- ... + + If you are going to use netperf to measure aggregate results, it is +important to use the LOC_CPU and REM_CPU tests to get the calibration +values first to avoid issues with some of the aggregate netperf tests +transferring data while others are "idle" and getting bogus calibration +values. When running aggregate tests, it is very important to remember +that any one instance of netperf does not know about the other +instances of netperf. It will report global CPU utilization and will +calculate service demand believing it was the only thing causing that +CPU utilization. So, you can use the CPU utilization reported by +netperf in an aggregate test, but you have to calculate service demands +by hand. + + +File: netperf.info, Node: Address Resolution, Next: Enhancing Netperf, Prev: Other Netperf Tests, Up: Top + +10 Address Resolution +********************* + +Netperf versions 2.4.0 and later have merged IPv4 and IPv6 tests so the +functionality of the tests in `src/nettest_ipv6.c' has been subsumed +into the tests in `src/nettest_bsd.c' This has been accomplished in +part by switching from `gethostbyname()'to `getaddrinfo()' exclusively. +While it was theoretically possible to get multiple results for a +hostname from `gethostbyname()' it was generally unlikely and netperf's +ignoring of the second and later results was not much of an issue. + + Now with `getaddrinfo' and particularly with AF_UNSPEC it is +increasingly likely that a given hostname will have multiple associated +addresses. The `establish_control()' routine of `src/netlib.c' will +indeed attempt to chose from among all the matching IP addresses when +establishing the control connection. Netperf does not _really_ care if +the control connection is IPv4 or IPv6 or even mixed on either end. + + However, the individual tests still ass-u-me that the first result in +the address list is the one to be used. Whether or not this will +turn-out to be an issue has yet to be determined. + + If you do run into problems with this, the easiest workaround is to +specify IP addresses for the data connection explicitly in the +test-specific `-H' and `-L' options. At some point, the netperf tests +_may_ try to be more sophisticated in their parsing of returns from +`getaddrinfo()' - straw-man patches to +would of course be most welcome :) + + Netperf has leveraged code from other open-source projects with +amenable licensing to provide a replacement `getaddrinfo()' call on +those platforms where the `configure' script believes there is no +native getaddrinfo call. As of this writing, the replacement +`getaddrinfo()' as been tested on HP-UX 11.0 and then presumed to run +elsewhere. + + +File: netperf.info, Node: Enhancing Netperf, Next: Netperf4, Prev: Address Resolution, Up: Top + +11 Enhancing Netperf +******************** + +Netperf is constantly evolving. If you find you want to make +enhancements to netperf, by all means do so. If you wish to add a new +"suite" of tests to netperf the general idea is to + + 1. Add files `src/nettest_mumble.c' and `src/nettest_mumble.h' where + mumble is replaced with something meaningful for the test-suite. + + 2. Add support for an apropriate `--enable-mumble' option in + `configure.ac'. + + 3. Edit `src/netperf.c', `netsh.c', and `netserver.c' as required, + using #ifdef WANT_MUMBLE. + + 4. Compile and test + + If you wish to submit your changes for possible inclusion into the +mainline sources, please try to base your changes on the latest +available sources. (*Note Getting Netperf Bits::.) and then send email +describing the changes at a high level to + or perhaps . +If the concensus is positive, then sending context `diff' results to + is the next step. From that point, it +is a matter of pestering the Netperf Contributing Editor until he gets +the changes incorporated :) + + +File: netperf.info, Node: Netperf4, Next: Concept Index, Prev: Enhancing Netperf, Up: Top + +12 Netperf4 +*********** + +Netperf4 is the shorthand name given to version 4.X.X of netperf. This +is really a separate benchmark more than a newer version of netperf, +but it is a decendant of netperf so the netperf name is kept. The +facetious way to describe netperf4 is to say it is the +egg-laying-woolly-milk-pig version of netperf :) The more respectful +way to describe it is to say it is the version of netperf with support +for synchronized, multiple-thread, multiple-test, multiple-system, +network-oriented benchmarking. + + Netperf4 is still undergoing rapid evolution. Those wishing to work +with or on netperf4 are encouraged to join the netperf-dev +(http://www.netperf.org/cgi-bin/mailman/listinfo/netperf-dev) mailing +list and/or peruse the current sources +(http://www.netperf.org/svn/netperf4/trunk). + + +File: netperf.info, Node: Concept Index, Next: Option Index, Prev: Netperf4, Up: Top + +Concept Index +************* + +[index] +* Menu: + +* Aggregate Performance: Using Netperf to Measure Aggregate Performance. + (line 3) +* Bandwidth Limitation: Installing Netperf Bits. + (line 41) +* Connection Latency: TCP_CC. (line 3) +* CPU Utilization: The Design of Netperf. + (line 35) +* Design of Netperf: The Design of Netperf. + (line 6) +* Installation: Installing Netperf. (line 6) +* Introduction: Introduction. (line 6) +* Latency, Connection Establishment <1>: XTI_TCP_CRR. (line 3) +* Latency, Connection Establishment <2>: XTI_TCP_CC. (line 3) +* Latency, Connection Establishment <3>: TCP_CRR. (line 3) +* Latency, Connection Establishment: TCP_CC. (line 3) +* Latency, Request-Response <1>: SCTP_RR. (line 3) +* Latency, Request-Response <2>: DLCO_RR. (line 3) +* Latency, Request-Response <3>: DLCL_RR. (line 3) +* Latency, Request-Response <4>: XTI_UDP_RR. (line 3) +* Latency, Request-Response <5>: XTI_TCP_CRR. (line 3) +* Latency, Request-Response <6>: XTI_TCP_RR. (line 3) +* Latency, Request-Response <7>: UDP_RR. (line 3) +* Latency, Request-Response <8>: TCP_CRR. (line 3) +* Latency, Request-Response: TCP_RR. (line 3) +* Limiting Bandwidth <1>: UDP_STREAM. (line 9) +* Limiting Bandwidth: Installing Netperf Bits. + (line 41) +* Measuring Latency: TCP_RR. (line 3) +* Packet Loss: UDP_RR. (line 3) +* Port Reuse: TCP_CC. (line 13) +* TIME_WAIT: TCP_CC. (line 13) + + +File: netperf.info, Node: Option Index, Prev: Concept Index, Up: Top + +Option Index +************ + +[index] +* Menu: + +* --enable-burst, Configure: Using Netperf to Measure Aggregate Performance. + (line 3) +* --enable-cpuutil, Configure: Installing Netperf Bits. + (line 22) +* --enable-dlpi, Configure: Installing Netperf Bits. + (line 28) +* --enable-histogram, Configure: Installing Netperf Bits. + (line 41) +* --enable-intervals, Configure: Installing Netperf Bits. + (line 41) +* --enable-sctp, Configure: Installing Netperf Bits. + (line 28) +* --enable-unix, Configure: Installing Netperf Bits. + (line 28) +* --enable-xti, Configure: Installing Netperf Bits. + (line 28) +* -4, Global: Global Options. (line 379) +* -4, Test-specific <1>: Options Common to TCP UDP and SCTP _RR tests. + (line 88) +* -4, Test-specific: Options common to TCP UDP and SCTP tests. + (line 110) +* -6 Test-specific: Options Common to TCP UDP and SCTP _RR tests. + (line 94) +* -6, Global: Global Options. (line 388) +* -6, Test-specific: Options common to TCP UDP and SCTP tests. + (line 116) +* -A, Global: Global Options. (line 18) +* -a, Global: Global Options. (line 6) +* -B, Global: Global Options. (line 29) +* -b, Global: Global Options. (line 22) +* -C, Global: Global Options. (line 42) +* -c, Global: Global Options. (line 33) +* -D, Global: Global Options. (line 56) +* -d, Global: Global Options. (line 47) +* -F, Global: Global Options. (line 74) +* -f, Global: Global Options. (line 67) +* -H, Global: Global Options. (line 92) +* -h, Global: Global Options. (line 88) +* -H, Test-specific: Options Common to TCP UDP and SCTP _RR tests. + (line 17) +* -h, Test-specific <1>: Options Common to TCP UDP and SCTP _RR tests. + (line 10) +* -h, Test-specific: Options common to TCP UDP and SCTP tests. + (line 10) +* -i, Global: Global Options. (line 168) +* -I, Global: Global Options. (line 127) +* -L, Global: Global Options. (line 209) +* -l, Global: Global Options. (line 189) +* -L, Test-specific <1>: Options Common to TCP UDP and SCTP _RR tests. + (line 26) +* -L, Test-specific: Options common to TCP UDP and SCTP tests. + (line 25) +* -M, Test-specific: Options common to TCP UDP and SCTP tests. + (line 48) +* -m, Test-specific: Options common to TCP UDP and SCTP tests. + (line 32) +* -N, Global: Global Options. (line 234) +* -n, Global: Global Options. (line 221) +* -O, Global: Global Options. (line 279) +* -o, Global: Global Options. (line 270) +* -P, Global: Global Options. (line 303) +* -p, Global: Global Options. (line 283) +* -P, Test-specific <1>: Options Common to TCP UDP and SCTP _RR tests. + (line 33) +* -P, Test-specific: Options common to TCP UDP and SCTP tests. + (line 61) +* -r, Test-specific: Options Common to TCP UDP and SCTP _RR tests. + (line 36) +* -S Test-specific: Options common to TCP UDP and SCTP tests. + (line 87) +* -S, Test-specific: Options Common to TCP UDP and SCTP _RR tests. + (line 68) +* -s, Test-specific <1>: Options Common to TCP UDP and SCTP _RR tests. + (line 48) +* -s, Test-specific: Options common to TCP UDP and SCTP tests. + (line 64) +* -t, Global: Global Options. (line 312) +* -v, Global: Global Options. (line 341) +* -W, Global: Global Options. (line 370) +* -w, Global: Global Options. (line 363) + + + +Tag Table: +Node: Top439 +Node: Introduction2700 +Node: Conventions5161 +Node: Installing Netperf6924 +Node: Getting Netperf Bits8478 +Node: Installing Netperf Bits10296 +Node: Verifying Installation16760 +Node: The Design of Netperf17464 +Node: CPU Utilization19046 +Node: Global Command-line Options27659 +Node: Command-line Options Syntax28198 +Node: Global Options29580 +Node: Using Netperf to Measure Bulk Data Transfer48876 +Node: Issues in Bulk Transfer49541 +Node: Options common to TCP UDP and SCTP tests53070 +Node: TCP_STREAM59364 +Node: TCP_MAERTS63132 +Node: TCP_SENDFILE64365 +Node: UDP_STREAM66681 +Node: XTI_TCP_STREAM70117 +Node: XTI_UDP_STREAM70762 +Node: SCTP_STREAM71407 +Node: DLCO_STREAM72107 +Node: DLCL_STREAM74080 +Node: STREAM_STREAM74954 +Node: DG_STREAM75800 +Node: Using Netperf to Measure Request/Response76469 +Node: Issues in Request/Response78390 +Node: Options Common to TCP UDP and SCTP _RR tests80396 +Node: TCP_RR85375 +Node: TCP_CC87719 +Node: TCP_CRR89916 +Node: UDP_RR90962 +Node: XTI_TCP_RR92983 +Node: XTI_TCP_CC93566 +Node: XTI_TCP_CRR93732 +Node: XTI_UDP_RR93900 +Node: DLCL_RR94477 +Node: DLCO_RR94630 +Node: SCTP_RR94782 +Node: Using Netperf to Measure Aggregate Performance94918 +Node: Running Concurrent Netperf Tests95753 +Node: Using --enable-burst99645 +Node: Using Netperf to Measure Bidirectional Transfer105830 +Node: Bidirectional Transfer with Concurrent Tests106903 +Node: Bidirectional Transfer with TCP_RR108769 +Node: Other Netperf Tests111303 +Node: CPU rate calibration111749 +Node: Address Resolution114090 +Node: Enhancing Netperf116066 +Node: Netperf4117303 +Node: Concept Index118213 +Node: Option Index120603 + +End Tag Table diff --git a/doc/netperf.man b/doc/netperf.man new file mode 100644 index 0000000..f1002c4 --- /dev/null +++ b/doc/netperf.man @@ -0,0 +1,214 @@ +.TH netperf 1 "" +.SH NAME + +netperf \- a network performance benchmark + +.SH SYNOPSIS + +.B netperf +[global options] -- [test specific options] + +.SH DESCRIPTION +.B Netperf +is a benchmark that can be used to measure various aspects of +networking performance. +Currently, its focus is on bulk data transfer and request/response +performance using either TCP or UDP, and the Berkeley Sockets +interface. In addition, tests for DLPI, and Unix Domain +Sockets, tests for IPv6 may be conditionally compiled-in. + +.SS GLOBAL OPTIONS + +.TP +.B \-4 +Use AF_INET (aka IPv4) addressing for the control and possibly data +connections. +.TP +.B \-6 +Use AF_INET6 (aka IPv6) addressing for the control and possibly data +connections. +.TP +.B \-a sizespec +Alter the send and receive buffer alignments on the local system. +This defaults to 8 bytes. +.TP +.B \-A sizespec +As -a, but for the remote system. +.TP +.B \-B brandstr +Add brandstr to the output of a test with banners disabled. +.TP +.B \-c [rate] +Request CPU utilization and service demand calculations for the +local system. If the optional rate parameter is specified, +.B netperf +will use that instead of calculating the rate itself. +.TP +.B \-C [rate] +As -c, but for the remote system. +.TP +.B \-d +Increase the quantity of debugging output displayed during +a test (possibly at the expense of performance). +.TP +.B \-D [secs,units] (*) +Display interim results at least every secs seconds uning units as the +initial guess for units per second. This is only available when +netperf has been configured with --enable-demo. +.TP +.B \-f GMKgmk +Change the units of measure for *_STREAM tests. Capital letters are +powers of two, lowercase are powers of ten. +.TP +.B \-F fill_file +Pre-fill the send buffers with data from the named file. This is +intended to provide a means for avoiding buffers that are filled with +data which is trivially easy to compress. A good choice for a file +that should be present on any system is this manpage - netperf.man. +Other files may be provided as part of the distribution. +.TP +.B \-h +Display a usage string, and exit. +.TP +.B \-H name|ip,family (*) +Set the hostname (or IP address) and address family to use to +establish the control connection to the remote system. Passing a +single name with no comma will only set remote_host and will leave +selection of address family for the control connection to the stack or +by a -4 -r -6 command line option. +.TP +.B \-i max,min +Set the maximum and minimum number of iterations when trying to reach +certain confidence levels. +.TP +.B \-I lvl,[,intvl] +Specify the confidence level (either 95 or 99 - 99 is the default) and +the width of the confidence interval as a percentage (default 10) +.TP +.B \-l testlen +Specify the length of the test (default 10 seconds). +A negative value sets the number of request/response transactions, +or the number of bytes for a stream test. +.TP +.B \-L name|ip,fam (*) +Set the local name|IP and/or address family for the socket used for +the control connection to the remote netserver. +.TP +.B \-n numcpus +Specify the number of CPU's in the system on those systems for which +netperf has no way to find the number of CPU's programatically. +.TP +.B \-N +This option will tell netperf to not establish a control connection to +a remote netserver. Instead it will try to establish a data +connection directly, using only the information supplied by the +command line parameters and/or internal defaults. Unless other ports +are provided by the command line, by default the data connection will +be to the "discard" port for a "STREAM" or "SENDFILE" test, the "echo" +port for an "RR" test or the "chargen" port for a "MAERTS" test. +.TP +.B \-o sizespec +Set an offset from the alignment specified with -a. +.TP +.B \-O sizespec +As -o, but for the remote system. +.TP +.B \-p portnum,locport (*) +Direct the control connection to a netserver listening on the +specified port, rather than using a "netperf" entry in +/etc/services or the internal default (port 12865). If ",locport" is +specified the control connection will be established from that local +port number. Specifying a single port number with no comma will +specify only the remote netserver port number and will leave local +port number selection to the stack. +.TP +.B \-P 0|1 +Show (1) or suppress (0) the test banner. +.TP +.B \-t testname +Specify the test to perform. +Valid testnames include, but are not limited to, nor always compiled-in: +.RS +.RS +.nf +.I TCP_STREAM +.I TCP_SENDFILE +.I TCP_MAERTS +.I TCP_RR +.I TCP_CRR +.I UDP_STREAM +.I UDP_RR +.I DLCO_STREAM +.I DLCO_RR +.I DLCL_STREAM +.I DLCL_RR +.I STREAM_STREAM +.I STREAM_RR +.I DG_STREAM +.I DG_RR +.I LOC_CPU +.I REM_CPU +.fi +.RE +.RE +.TP +.B \-T lcpu,remcpu +Request that netperf be bound to CPU lcpu and/or netserver be bound to +CPU rcpu. +.TP +.B \-v verbosity +Set the verbosity level for the test (only with -P). + + +.SS TEST SPECIFIC OPTIONS + +.TP +.B \-h +Display a usage string based on the test name set with -t, and exit. + +Please consult the netperf manual +.I +Netperf: A Network Performance Benchmark +(netperf.ps) for more information. Or you can join and mail to +netperf-talk@netperf.org. + +.SH NOTE +For those options taking two parms, at least one must be specified; +specifying one value without a comma will set both parms to that +value, specifying a value with a leading comma will set just the +second parm, a value with a trailing comma will set just the first. To +set each parm to unique values, specify both and separate them with a +comma. + +* For these options taking two parms, specifying one value with no +comma will only set the first parms and will leave the second at the +default value. To set the second value it must be preceded with a +comma or be a comma-separated pair. This is to retain previous netperf +behaviour. + + +.SH BUGS +There are bound to be bugs. If you think you have found a bug, please +mention it in netperf-talk@netperf.org. List membership is required +to send email to the list. See +http://www.netperf.org/cgi-bin/mailman/listinfo/netperf-talk . If all +else fails send email to Rick Jones . + +.SH SEE ALSO +.C netserver +.br +.I +Netperf: A Network Performance Benchmark +.br +http://www.netperf.org/ + +.SH AUTHORS +HP Information Networks Division - Networking Performance Team. +.br +Rick Jones +.br +Karen Choy HP IND +.br +Dave Shield (man pages) +.br +Others too numerous to mention here - see the ACKNWLDGMNTS file diff --git a/doc/netperf.texi b/doc/netperf.texi new file mode 100644 index 0000000..10727cf --- /dev/null +++ b/doc/netperf.texi @@ -0,0 +1,2822 @@ +\input texinfo @c -*-texinfo-*- +@c %**start of header +@setfilename netperf.info +@settitle Care and Feeding of Netperf 2.4.X +@c %**end of header + +@copying +This is Rick Jones' feeble attempt at a Texinfo-based manual for the +netperf benchmark. + +Copyright @copyright{} 2005-2007 Hewlett-Packard Company +@quotation +Permission is granted to copy, distribute and/or modify this document +per the terms of the netperf source licence, a copy of which can be +found in the file @file{COPYING} of the basic netperf distribution. +@end quotation +@end copying + +@titlepage +@title Care and Feeding of Netperf +@subtitle Versions 2.4.3 and Later +@author Rick Jones @email{rick.jones2@@hp.com} +@c this is here to start the copyright page +@page +@vskip 0pt plus 1filll +@insertcopying +@end titlepage + +@c begin with a table of contents +@contents + +@ifnottex +@node Top, Introduction, (dir), (dir) +@top Netperf Manual + +@insertcopying +@end ifnottex + +@menu +* Introduction:: An introduction to netperf - what it is and whatit is not. +* Installing Netperf:: How to go about installing netperf. +* The Design of Netperf:: +* Global Command-line Options:: +* Using Netperf to Measure Bulk Data Transfer:: +* Using Netperf to Measure Request/Response :: +* Using Netperf to Measure Aggregate Performance:: +* Using Netperf to Measure Bidirectional Transfer:: +* Other Netperf Tests:: +* Address Resolution:: +* Enhancing Netperf:: +* Netperf4:: +* Concept Index:: +* Option Index:: + +@detailmenu + --- The Detailed Node Listing --- + +Introduction + +* Conventions:: + +Installing Netperf + +* Getting Netperf Bits:: +* Installing Netperf Bits:: +* Verifying Installation:: + +The Design of Netperf + +* CPU Utilization:: + +Global Command-line Options + +* Command-line Options Syntax:: +* Global Options:: + +Using Netperf to Measure Bulk Data Transfer + +* Issues in Bulk Transfer:: +* Options common to TCP UDP and SCTP tests:: + +Options common to TCP UDP and SCTP tests + +* TCP_STREAM:: +* TCP_MAERTS:: +* TCP_SENDFILE:: +* UDP_STREAM:: +* XTI_TCP_STREAM:: +* XTI_UDP_STREAM:: +* SCTP_STREAM:: +* DLCO_STREAM:: +* DLCL_STREAM:: +* STREAM_STREAM:: +* DG_STREAM:: + +Using Netperf to Measure Request/Response + +* Issues in Request/Response:: +* Options Common to TCP UDP and SCTP _RR tests:: + +Options Common to TCP UDP and SCTP _RR tests + +* TCP_RR:: +* TCP_CC:: +* TCP_CRR:: +* UDP_RR:: +* XTI_TCP_RR:: +* XTI_TCP_CC:: +* XTI_TCP_CRR:: +* XTI_UDP_RR:: +* DLCL_RR:: +* DLCO_RR:: +* SCTP_RR:: + +Using Netperf to Measure Aggregate Performance + +* Running Concurrent Netperf Tests:: +* Using --enable-burst:: + +Using Netperf to Measure Bidirectional Transfer + +* Bidirectional Transfer with Concurrent Tests:: +* Bidirectional Transfer with TCP_RR:: + +Other Netperf Tests + +* CPU rate calibration:: + +@end detailmenu +@end menu + +@node Introduction, Installing Netperf, Top, Top +@chapter Introduction + +@cindex Introduction + +Netperf is a benchmark that can be use to measure various aspect of +networking performance. The primary foci are bulk (aka +unidirectional) data transfer and request/response performance using +either TCP or UDP and the Berkeley Sockets interface. As of this +writing, the tests available either unconditionally or conditionally +include: + +@itemize @bullet +@item +TCP and UDP unidirectional transfer and request/response over IPv4 and +IPv6 using the Sockets interface. +@item +TCP and UDP unidirectional transfer and request/response over IPv4 +using the XTI interface. +@item +Link-level unidirectional transfer and request/response using the DLPI +interface. +@item +Unix domain sockets +@item +SCTP unidirectional transfer and request/response over IPv4 and IPv6 +using the sockets interface. +@end itemize + +While not every revision of netperf will work on every platform +listed, the intention is that at least some version of netperf will +work on the following platforms: + +@itemize @bullet +@item +Unix - at least all the major variants. +@item +Linux +@item +Windows +@item +OpenVMS +@item +Others +@end itemize + +Netperf is maintained and informally supported primarily by Rick +Jones, who can perhaps be best described as Netperf Contributing +Editor. Non-trivial and very appreciated assistance comes from others +in the network performance community, who are too numerous to mention +here. While it is often used by them, netperf is NOT supported via any +of the formal Hewlett-Packard support channels. You should feel free +to make enhancements and modifications to netperf to suit your +nefarious porpoises, so long as you stay within the guidelines of the +netperf copyright. If you feel so inclined, you can send your changes +to +@email{netperf-feedback@@netperf.org,netperf-feedback} for possible +inclusion into subsequent versions of netperf. + +If you would prefer to make contributions to networking benchmark +using certified ``open source'' license, please considuer netperf4, +which is distributed under the terms of the GPL. + +The @email{netperf-talk@@netperf.org,netperf-talk} mailing list is +available to discuss the care and feeding of netperf with others who +share your interest in network performance benchmarking. The +netperf-talk mailing list is a closed list and you must first +subscribe by sending email to +@email{netperf-talk-request@@netperf.org,netperf-talk-request}. + + +@menu +* Conventions:: +@end menu + +@node Conventions, , Introduction, Introduction +@section Conventions + +A @dfn{sizespec} is a one or two item, comma-separated list used as an +argument to a command-line option that can set one or two, related +netperf parameters. If you wish to set both parameters to separate +values, items should be separated by a comma: + +@example +parameter1,parameter2 +@end example + +If you wish to set the first parameter without altering the value of +the second from its default, you should follow the first item with a +comma: + +@example +parameter1, +@end example + + +Likewise, precede the item with a comma if you wish to set only the +second parameter: + +@example +,parameter2 +@end example + +An item with no commas: + +@example +parameter1and2 +@end example + +will set both parameters to the same value. This last mode is one of +the most frequently used. + +There is another variant of the comma-separated, two-item list called +a @dfn{optionspec} which is like a sizespec with the exception that a +single item with no comma: + +@example +parameter1 +@end example + +will only set the value of the first parameter and will leave the +second parameter at its default value. + +Netperf has two types of command-line options. The first are global +command line options. They are essentially any option not tied to a +particular test or group of tests. An example of a global +command-line option is the one which sets the test type - @option{-t}. + +The second type of options are test-specific options. These are +options which are only applicable to a particular test or set of +tests. An example of a test-specific option would be the send socket +buffer size for a TCP_STREAM test. + +Global command-line options are specified first with test-specific +options following after a @code{--} as in: + +@example +netperf -- +@end example + + +@node Installing Netperf, The Design of Netperf, Introduction, Top +@chapter Installing Netperf + +@cindex Installation + +Netperf's primary form of distribution is source code. This allows +installation on systems other than those to which the authors have +ready access and thus the ability to create binaries. There are two +styles of netperf installation. The first runs the netperf server +program - netserver - as a child of inetd. This requires the +installer to have sufficient privileges to edit the files +@file{/etc/services} and @file{/etc/inetd.conf} or their +platform-specific equivalents. + +The second style is to run netserver as a standalone daemon. This +second method does not require edit privileges on @file{/etc/services} +and @file{/etc/inetd.conf} but does mean you must remember to run the +netserver program explicitly after every system reboot. + +This manual assumes that those wishing to measure networking +performance already know how to use anonymous FTP and/or a web +browser. It is also expected that you have at least a passing +familiarity with the networking protocols and interfaces involved. In +all honesty, if you do not have such familiarity, likely as not you +have some experience to gain before attempting network performance +measurements. The excellent texts by authors such as Stevens, Fenner +and Rudoff and/or Stallings would be good starting points. There are +likely other excellent sources out there as well. + +@menu +* Getting Netperf Bits:: +* Installing Netperf Bits:: +* Verifying Installation:: +@end menu + +@node Getting Netperf Bits, Installing Netperf Bits, Installing Netperf, Installing Netperf +@section Getting Netperf Bits + +Gzipped tar files of netperf sources can be retrieved via +@uref{ftp://ftp.netperf.org/netperf,anonymous FTP} +for ``released'' versions of the bits. Pre-release versions of the +bits can be retrieved via anonymous FTP from the +@uref{ftp://ftp.netperf.org/netperf/experimental,experimental} subdirectory. + +For convenience and ease of remembering, a link to the download site +is provided via the +@uref{http://www.netperf.org/, NetperfPage} + +The bits corresponding to each discrete release of netperf are +@uref{http://www.netperf.org/svn/netperf2/tags,tagged} for retrieval +via subversion. For example, there is a tag for the first version +corresponding to this version of the manual - +@uref{http://www.netperf.org/svn/netperf2/tags/netperf-2.4.3,netperf +2.4.3}. Those wishing to be on the bleeding edge of netperf +development can use subversion to grab the +@uref{http://www.netperf.org/svn/netperf2/trunk,top of trunk}. + +There are likely other places around the Internet from which one can +download netperf bits. These may be simple mirrors of the main +netperf site, or they may be local variants on netperf. As with +anything one downloads from the Internet, take care to make sure it is +what you really wanted and isn't some malicious Trojan or whatnot. +Caveat downloader. + +As a general rule, binaries of netperf and netserver are not +distributed from ftp.netperf.org. From time to time a kind soul or +souls has packaged netperf as a Debian package available via the +apt-get mechanism or as an RPM. I would be most interested in +learning how to enhance the makefiles to make that easier for people, +and perhaps to generate HP-UX swinstall``depots.'' + +@node Installing Netperf Bits, Verifying Installation, Getting Netperf Bits, Installing Netperf +@section Installing Netperf + +Once you have downloaded the tar file of netperf sources onto your +system(s), it is necessary to unpack the tar file, cd to the netperf +directory, run configure and then make. Most of the time it should be +sufficient to just: + +@example +gzcat .tar.gz | tar xf - +cd +./configure +make +make install +@end example + +Most of the ``usual'' configure script options should be present +dealing with where to install binaries and whatnot. +@example +./configure --help +@end example +should list all of those and more. + +@vindex --enable-cpuutil, Configure +If the netperf configure script does not know how to automagically +detect which CPU utilization mechanism to use on your platform you may +want to add a @code{--enable-cpuutil=mumble} option to the configure +command. If you have knowledge and/or experience to contribute to +that area, feel free to contact @email{netperf-feedback@@netperf.org}. + +@vindex --enable-xti, Configure +@vindex --enable-unix, Configure +@vindex --enable-dlpi, Configure +@vindex --enable-sctp, Configure +Similarly, if you want tests using the XTI interface, Unix Domain +Sockets, DLPI or SCTP it will be necessary to add one or more +@code{--enable-[xti|unix|dlpi|sctp]=yes} options to the configure +command. As of this writing, the configure script will not include +those tests automagically. + +On some platforms, it may be necessary to precede the configure +command with a CFLAGS and/or LIBS variable as the netperf configure +script is not yet smart enough to set them itself. Whenever possible, +these requirements will be found in @file{README.@var{platform}} files. +Expertise and assistance in making that more automagical in the +configure script would be most welcome. + +@cindex Limiting Bandwidth +@cindex Bandwidth Limitation +@vindex --enable-intervals, Configure +@vindex --enable-histogram, Configure +Other optional configure-time settings include +@code{--enable-intervals=yes} to give netperf the ability to ``pace'' +its _STREAM tests and @code{--enable-histogram=yes} to have netperf +keep a histogram of interesting times. Each of these will have some +effect on the measured result. If your system supports +@code{gethrtime()} the effect of the histogram measurement should be +minimized but probably still measurable. For example, the histogram +of a netperf TCP_RR test will be of the individual transaction times: +@example +netperf -t TCP_RR -H lag -v 2 +TCP REQUEST/RESPONSE TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to lag.hpl.hp.com (15.4.89.214) port 0 AF_INET : histogram +Local /Remote +Socket Size Request Resp. Elapsed Trans. +Send Recv Size Size Time Rate +bytes Bytes bytes bytes secs. per sec + +16384 87380 1 1 10.00 3538.82 +32768 32768 +Alignment Offset +Local Remote Local Remote +Send Recv Send Recv + 8 0 0 0 +Histogram of request/response times +UNIT_USEC : 0: 0: 0: 0: 0: 0: 0: 0: 0: 0 +TEN_USEC : 0: 0: 0: 0: 0: 0: 0: 0: 0: 0 +HUNDRED_USEC : 0: 34480: 111: 13: 12: 6: 9: 3: 4: 7 +UNIT_MSEC : 0: 60: 50: 51: 44: 44: 72: 119: 100: 101 +TEN_MSEC : 0: 105: 0: 0: 0: 0: 0: 0: 0: 0 +HUNDRED_MSEC : 0: 0: 0: 0: 0: 0: 0: 0: 0: 0 +UNIT_SEC : 0: 0: 0: 0: 0: 0: 0: 0: 0: 0 +TEN_SEC : 0: 0: 0: 0: 0: 0: 0: 0: 0: 0 +>100_SECS: 0 +HIST_TOTAL: 35391 +@end example + +Long-time users of netperf will notice the expansion of the main test +header. This stems from the merging-in of IPv6 with the standard IPv4 +tests and the addition of code to specify addressing information for +both sides of the data connection. + +The histogram you see above is basically a base-10 log histogram where +we can see that most of the transaction times were on the order of one +hundred to one-hundred, ninety-nine microseconds, but they were +occasionally as long as ten to nineteen milliseconds + +The @option{--enable-demo=yes} configure option will cause code to be +included to report interim results during a test run. The rate at +which interim results are reported can then be controlled via the +global @option{-D} option. Here is an example of --enable-demo mode +output: + +@example +src/netperf -D 1.35 -H lag -f M +TCP STREAM TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to lag.hpl.hp.com (15.4.89.214) port 0 AF_INET : demo +Interim result: 9.66 MBytes/s over 1.67 seconds +Interim result: 9.64 MBytes/s over 1.35 seconds +Interim result: 9.58 MBytes/s over 1.36 seconds +Interim result: 9.51 MBytes/s over 1.36 seconds +Interim result: 9.71 MBytes/s over 1.35 seconds +Interim result: 9.66 MBytes/s over 1.36 seconds +Interim result: 9.61 MBytes/s over 1.36 seconds +Recv Send Send +Socket Socket Message Elapsed +Size Size Size Time Throughput +bytes bytes bytes secs. MBytes/sec + + 32768 16384 16384 10.00 9.61 +@end example + +Notice how the units of the interim result track that requested by the +@option{-f} option. Also notice that sometimes the interval will be +longer than the value specified in the @option{-D} option. This is +normal and stems from how demo mode is implemented without relying on +interval timers, but by calculating how many units of work must be +performed to take at least the desired interval. + +As of this writing, a @code{make install} will not actually update the +files @file{/etc/services} and/or @file{/etc/inetd.conf} or their +platform-specific equivalents. It remains necessary to perform that +bit of installation magic by hand. Patches to the makefile sources to +effect an automagic editing of the necessary files to have netperf +installed as a child of inetd would be most welcome. + +Starting the netserver as a standalone daemon should be as easy as: +@example +$ netserver +Starting netserver at port 12865 +Starting netserver at hostname 0.0.0.0 port 12865 and family 0 +@end example + +Over time the specifics of the messages netserver prints to the screen +may change but the gist will remain the same. + +If the compilation of netperf or netserver happens to fail, feel free +to contact @email{netperf-feedback@@netperf.org} or join and ask in +@email{netperf-talk@@netperf.org}. However, it is quite important +that you include the actual compilation errors and perhaps even the +configure log in your email. Otherwise, it will be that much more +difficult for someone to assist you. + +@node Verifying Installation, , Installing Netperf Bits, Installing Netperf +@section Verifying Installation + +Basically, once netperf is installed and netserver is configured as a +child of inetd, or launched as a standalone daemon, simply typing: +@example +netperf +@end example +should result in output similar to the following: +@example +$ netperf +TCP STREAM TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to localhost.localdomain (127.0.0.1) port 0 AF_INET +Recv Send Send +Socket Socket Message Elapsed +Size Size Size Time Throughput +bytes bytes bytes secs. 10^6bits/sec + + 87380 16384 16384 10.00 2997.84 +@end example + + +@node The Design of Netperf, Global Command-line Options, Installing Netperf, Top +@chapter The Design of Netperf + +@cindex Design of Netperf + +Netperf is designed around a basic client-server model. There are +two executables - netperf and netserver. Generally you will only +execute the netperf program, with the netserver program being invoked +by the remote system's inetd or equivalent. +When you execute netperf, the first that that will happen is the +establishment of a control connection to the remote system. This +connection will be used to pass test configuration information and +results to and from the remote system. Regardless of the type of test +to be run, the control connection will be a TCP connection using BSD +sockets. The control connection can use either IPv4 or IPv6. + +Once the control connection is up and the configuration information +has been passed, a separate ``data'' connection will be opened for the +measurement itself using the API's and protocols appropriate for the +specified test. When the test is completed, the data connection will +be torn-down and results from the netserver will be passed-back via the +control connection and combined with netperf's result for display to +the user. + +Netperf places no traffic on the control connection while a test is in +progress. Certain TCP options, such as SO_KEEPALIVE, if set as your +systems' default, may put packets out on the control connection while +a test is in progress. Generally speaking this will have no effect on +the results. + +@menu +* CPU Utilization:: +@end menu + +@cindex CPU Utilization +@node CPU Utilization, , The Design of Netperf, The Design of Netperf +@section CPU Utilization + +CPU utilization is an important, and alas all-too infrequently +reported component of networking performance. Unfortunately, it can +be one of the most difficult metrics to measure accurately as many +systems offer mechanisms that are at best il-suited to measuring CPU +utilization in high interrupt rate (eg networking) situations. + +CPU utilization in netperf is reported as a value between 0 and 100% +regardless of the number of CPUs involved. In addition to CPU +utilization, netperf will report a metric called a @dfn{service +demand}. The service demand is the normalization of CPU utilization +and work performed. For a _STREAM test it is the microseconds of CPU +time consumed to transfer on KB (K == 1024) of data. For a _RR test +it is the microseconds of CPU time consumed processing a single +transaction. For both CPU utilization and service demand, lower is +better. + +Service demand can be particularly useful when trying to gauge the +effect of a performance change. It is essentially a measure of +efficiency, with smaller values being more efficient. + +Netperf is coded to be able to use one of several, generally +platform-specific CPU utilization measurement mechanisms. Single +letter codes will be included in the CPU portion of the test banner to +indicate which mechanism was used on each of the local (netperf) and +remote (netserver) system. + +As of this writing those codes are: + +@table @code +@item U +The CPU utilization measurement mechanism was unknown to netperf or +netperf/netserver was not compiled to include CPU utilization +measurements. The code for the null CPU utilization mechanism can be +found in @file{src/netcpu_none.c}. +@item I +An HP-UX-specific CPU utilization mechanism whereby the kernel +incremented a per-CPU counter by one for each trip through the idle +loop. This mechanism was only available on specially-compiled HP-UX +kernels prior to HP-UX 10 and is mentioned here only for the sake of +historical completeness and perhaps as a suggestion to those who might +be altering other operating systems. While rather simple, perhaps even +simplistic, this mechanism was quite robust and was not affected by +the concerns of statistical methods, or methods attempting to track +time in each of user, kernel, interrupt and idle modes which require +quite careful accounting. It can be thought-of as the in-kernel +version of the looper @code{L} mechanism without the context switch +overhead. This mechanism required calibration. +@item P +An HP-UX-specific CPU utilization mechanism whereby the kernel +keeps-track of time (in the form of CPU cycles) spent in the kernel +idle loop (HP-UX 10.0 to 11.23 inclusive), or where the kernel keeps +track of time spent in idle, user, kernel and interrupt processing +(HP-UX 11.23 and later). The former requires calibration, the latter +does not. Values in either case are retrieved via one of the pstat(2) +family of calls, hence the use of the letter @code{P}. The code for +these mechanisms is found in @file{src/netcpu_pstat.c} and +@file{src/netcpu_pstatnew.c} respectively. +@item K +A Solaris-specific CPU utilization mechanism where by the kernel +keeps track of ticks (eg HZ) spent in the idle loop. This method is +statistical and is known to be inaccurate when the interrupt rate is +above epsilon as time spent processing interrupts is not subtracted +from idle. The value is retrieved via a kstat() call - hence the use +of the letter @code{K}. Since this mechanism uses units of ticks (HZ) +the calibration value should invariably match HZ. (Eg 100) The code +for this mechanism is implemented in @file{src/netcpu_kstat.c}. +@item M +A Solaris-specific mechanism available on Solaris 10 and latter which +uses the new microstate accounting mechanisms. There are two, alas, +overlapping, mechanisms. The first tracks nanoseconds spent in user, +kernel, and idle modes. The second mechanism tracks nanoseconds spent +in interrupt. Since the mechanisms overlap, netperf goes through some +hand-waving to try to ``fix'' the problem. Since the accuracy of the +handwaving cannot be completely determined, one must presume that +while better than the @code{K} mechanism, this mechanism too is not +without issues. The values are retrieved via kstat() calls, but the +letter code is set to @code{M} to distinguish this mechanism from the +even less accurate @code{K} mechanism. The code for this mechanism is +implemented in @file{src/netcpu_kstat10.c}. +@item L +A mechanism based on ``looper''or ``soaker'' processes which sit in +tight loops counting as fast as they possibly can. This mechanism +starts a looper process for each known CPU on the system. The effect +of processor hyperthreading on the mechanism is not yet known. This +mechanism definitely requires calibration. The code for the +``looper''mechanism can be found in @file{src/netcpu_looper.c} +@item N +A Microsoft Windows-specific mechanism, the code for which can be +found in @file{src/netcpu_ntperf.c}. This mechanism too is based on +what appears to be a form of micro-state accounting and requires no +calibration. On laptops, or other systems which may dynamically alter +the CPU frequency to minimize power consumtion, it has been suggested +that this mechanism may become slightly confsed, in which case using +BIOS settings to disable the power saving would be indicated. + +@item S +This mechanism uses @file{/proc/stat} on Linux to retrieve time +(ticks) spent in idle mode. It is thought but not known to be +reasonably accurate. The code for this mechanism can be found in +@file{src/netcpu_procstat.c}. +@item C +A mechanism somewhat similar to @code{S} but using the sysctl() call +on BSD-like Operating systems (*BSD and MacOS X). The code for this +mechanism can be found in @file{src/netcpu_sysctl.c}. +@item Others +Other mechanisms included in netperf in the past have included using +the times() and getrusage() calls. These calls are actually rather +poorly suited to the task of measuring CPU overhead for networking as +they tend to be process-specific and much network-related processing +can happen outside the context of a process, in places where it is not +a given it will be charged to the correct, or even a process. They +are mentioned here as a warning to anyone seeing those mechanisms used +in other networking benchmarks. These mechanisms are not available in +netperf 2.4.0 and later. +@end table + + + +For many platforms, the configure script will chose the best available +CPU utilization mechanism. However, some platforms have no +particularly good mechanisms. On those platforms, it is probably best +to use the ``LOOPER'' mechanism which is basically some number of +processes (as many as there are processors) sitting in tight little +loops counting as fast as they can. The rate at which the loopers +count when the system is believed to be idle is compared with the rate +when the system is running netperf and the ratio is used to compute +CPU utilization. + +In the past, netperf included some mechanisms that only reported CPU +time charged to the calling process. Those mechanisms have been +removed from netperf versions 2.4.0 and later because they are +hopelessly inaccurate. Networking can and often results in CPU time +being spent in places - such as interrupt contexts - that do not get +charged to a or the correct process. + +In fact, time spent in the processing of interrupts is a common issue +for many CPU utilization mechanisms. In particular, the ``PSTAT'' +mechanism was eventually known to have problems accounting for certain +interrupt time prior to HP-UX 11.11 (11iv1). HP-UX 11iv1 and later +are known to be good. The ``KSTAT'' mechanism is known to have +problems on all versions of Solaris up to and including Solaris 10. +Even the microstate accounting available via kstat in Solaris 10 has +issues, though perhaps not as bad as those of prior versions. + +The /proc/stat mechanism under Linux is in what the author would +consider an ``uncertain'' category as it appears to be statistical, +which may also have issues with time spent processing interrupts. + +In summary, be sure to ``sanity-check'' the CPU utilization figures +with other mechanisms. However, platform tools such as top, vmstat or +mpstat are often based on the same mechanisms used by netperf. + +@node Global Command-line Options, Using Netperf to Measure Bulk Data Transfer, The Design of Netperf, Top +@chapter Global Command-line Options + +This section describes each of the global command-line options +available in the netperf and netserver binaries. Essentially, it is +an expanded version of the usage information displayed by netperf or +netserver when invoked with the @option{-h} global command-line +option. + +@menu +* Command-line Options Syntax:: +* Global Options:: +@end menu + +@node Command-line Options Syntax, Global Options, Global Command-line Options, Global Command-line Options +@comment node-name, next, previous, up +@section Command-line Options Syntax + +Revision 1.8 of netperf introduced enough new functionality to overrun +the English alphabet for mnemonic command-line option names, and the +author was not and is not quite ready to switch to the contemporary +@option{--mumble} style of command-line options. (Call him a Luddite). + +For this reason, the command-line options were split into two parts - +the first are the global command-line options. They are options that +affect nearly any and every test type of netperf. The second type are +the test-specific command-line options. Both are entered on the same +command line, but they must be separated from one another by a @code{--} +for correct parsing. Global command-line options come first, followed +by the @code{--} and then test-specific command-line options. If there +are no test-specific options to be set, the @code{--} may be omitted. If +there are no global command-line options to be set, test-specific +options must still be preceded by a @code{--}. For example: +@example +netperf -- +@end example +sets both global and test-specific options: +@example +netperf +@end example +sets just global options and: +@example +netperf -- +@end example +sets just test-specific options. + +@node Global Options, , Command-line Options Syntax, Global Command-line Options +@comment node-name, next, previous, up +@section Global Options + +@table @code +@vindex -a, Global +@item -a +This option allows you to alter the alignment of the buffers used in +the sending and receiving calls on the local system.. Changing the +alignment of the buffers can force the system to use different copy +schemes, which can have a measurable effect on performance. If the +page size for the system were 4096 bytes, and you want to pass +page-aligned buffers beginning on page boundaries, you could use +@samp{-a 4096}. By default the units are bytes, but suffix of ``G,'' +``M,'' or ``K'' will specify the units to be 2^30 (GB), 2^20 (MB) or +2^10 (KB) respectively. A suffix of ``g,'' ``m'' or ``k'' will specify +units of 10^9, 10^6 or 10^3 bytes respectively. [Default: 8 bytes] + +@vindex -A, Global +@item -A +This option is identical to the @option{-a} option with the difference +being it affects alignments for the remote system. + +@vindex -b, Global +@item -b +This option is only present when netperf has been configure with +--enable-intervals=yes prior to compilation. It sets the size of the +burst of send calls in a _STREAM test. When used in conjunction with +the @option{-w} option it can cause the rate at which data is sent to +be ``paced.'' + +@vindex -B, Global +@item -B +This option will cause @option{} to be appended to the brief +(see -P) output of netperf. + +@vindex -c, Global +@item -c [rate] +This option will ask that CPU utilization and service demand be +calculated for the local system. For those CPU utilization mechanisms +requiring calibration, the options rate parameter may be specified to +preclude running another calibration step, saving 40 seconds of time. +For those CPU utilization mechanisms requiring no calibration, the +optional rate parameter will be utterly and completely ignored. +[Default: no CPU measurements] + +@vindex -C, Global +@item -C [rate] +This option requests CPU utilization and service demand calculations +for the remote system. It is otherwise identical to the @option{-c} +option. + +@vindex -d, Global +@item -d +Each instance of this option will increase the quantity of debugging +output displayed during a test. If the debugging output level is set +high enough, it may have a measurable effect on performance. +Debugging information for the local system is printed to stdout. +Debugging information for the remote system is sent by default to the +file @file{/tmp/netperf.debug}. [Default: no debugging output] + +@vindex -D, Global +@item -D [interval,units] +This option is only available when netperf is configured with +--enable-demo=yes. When set, it will cause netperf to emit periodic +reports of performance during the run. [@var{interval},@var{units}] +follow the semantics of an optionspec. If specified, +@var{interval} gives the minimum interval in real seconds, it does not +have to be whole seconds. The @var{units} value can be used for the +first guess as to how many units of work (bytes or transactions) must +be done to take at least @var{interval} seconds. If omitted, +@var{interval} defaults to one second and @var{units} to values +specific to each test type. + +@vindex -f, Global +@item -f G|M|K|g|m|k +This option can be used to change the reporting units for _STREAM +tests. Arguments of ``G,'' ``M,'' or ``K'' will set the units to +2^30, 2^20 or 2^10 bytes/s respectively (EG power of two GB, MB or +KB). Arguments of ``g,'' ``,m'' or ``k'' will set the units to 10^9, +10^6 or 10^3 bits/s respectively. [Default: 'm' or 10^6 bits/s] + +@vindex -F, Global +@item -F +This option specified the file from which send which buffers will be +pre-filled . While the buffers will contain data from the specified +file, the file is not fully transfered to the remote system as the +receiving end of the test will not write the contents of what it +receives to a file. This can be used to pre-fill the send buffers +with data having different compressibility and so is useful when +measuring performance over mechanisms which perform compression. + +While optional for most tests, this option is required for a test +utilizing the sendfile() or related calls because sendfile tests need +a name of a file to reference. + +@vindex -h, Global +@item -h +This option causes netperf to display its usage string and exit to the +exclusion of all else. + +@vindex -H, Global +@item -H +This option will set the name of the remote system and or the address +family used for the control connection. For example: +@example +-H linger,4 +@end example +will set the name of the remote system to ``tardy'' and tells netperf to +use IPv4 addressing only. +@example +-H ,6 +@end example +will leave the name of the remote system at its default, and request +that only IPv6 addresses be used for the control connection. +@example +-H lag +@end example +will set the name of the remote system to ``lag'' and leave the +address family to AF_UNSPEC which means selection of IPv4 vs IPv6 is +left to the system's address resolution. + +A value of ``inet'' can be used in place of ``4'' to request IPv4 only +addressing. Similarly, a value of ``inet6'' can be used in place of +``6'' to request IPv6 only addressing. A value of ``0'' can be used +to request either IPv4 or IPv6 addressing as name resolution dictates. + +By default, the options set with the global @option{-H} option are +inherited by the test for its data connection, unless a test-specific +@option{-H} option is specified. + +If a @option{-H} option follows either the @option{-4} or @option{-6} +options, the family setting specified with the -H option will override +the @option{-4} or @option{-6} options for the remote address +family. If no address family is specified, settings from a previous +@option{-4} or @option{-6} option will remain. In a nutshell, the +last explicit global command-line option wins. + +[Default: ``localhost'' for the remote name/IP address and ``0'' (eg +AF_UNSPEC) for the remote address family.] + +@vindex -I, Global +@item -I +This option enables the calculation of confidence intervals and sets +the confidence and width parameters with the first have of the +optionspec being either 99 or 95 for 99% or 95% confidence +respectively. The second value of the optionspec specifies the width +of the desired confidence interval. For example +@example +-I 99,5 +@end example +asks netperf to be 99% confident that the measured mean values for +throughput and CPU utilization are within +/- 2.5% of the ``real'' +mean values. If the @option{-i} option is specified and the +@option{-I} option is omitted, the confidence defaults to 99% and the +width to 5% (giving +/- 2.5%) + +If netperf calculates that the desired confidence intervals have not +been met, it emits a noticeable warning that cannot be suppressed with +the @option{-P} or @option{-v} options: + +@example +netperf -H tardy.cup -i 3 -I 99,5 +TCP STREAM TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to tardy.cup.hp.com (15.244.44.58) port 0 AF_INET : +/-2.5% @ 99% conf. +!!! WARNING +!!! Desired confidence was not achieved within the specified iterations. +!!! This implies that there was variability in the test environment that +!!! must be investigated before going further. +!!! Confidence intervals: Throughput : 6.8% +!!! Local CPU util : 0.0% +!!! Remote CPU util : 0.0% + +Recv Send Send +Socket Socket Message Elapsed +Size Size Size Time Throughput +bytes bytes bytes secs. 10^6bits/sec + + 32768 16384 16384 10.01 40.23 +@end example + +Where we see that netperf did not meet the desired convidence +intervals. Instead of being 99% confident it was within +/- 2.5% of +the real mean value of throughput it is only confident it was within ++/-3.4%. In this example, increasing the @option{-i} option +(described below) and/or increasing the iteration length with the +@option{-l} option might resolve the situation. + +@vindex -i, Global +@item -i +This option enables the calculation of confidence intervals and sets +the minimum and maximum number of iterations to run in attempting to +achieve the desired confidence interval. The first value sets the +maximum number of iterations to run, the second, the minimum. The +maximum number of iterations is silently capped at 30 and the minimum +is silently floored at 3. Netperf repeats the measurement the minimum +number of iterations and continues until it reaches either the +desired confidence interval, or the maximum number of iterations, +whichever comes first. + +If the @option{-I} option is specified and the @option{-i} option +omitted the maximum number of iterations is set to 10 and the minimum +to three. + +If netperf determines that the desired confidence intervals have not +been met, it emits a noticeable warning. + +The total test time will be somewhere between the minimum and maximum +number of iterations multiplied by the test length supplied by the +@option{-l} option. + +@vindex -l, Global +@item -l testlen +This option controls the length of any @b{one} iteration of the requested +test. A positive value for @var{testlen} will run each iteration of +the test for at least @var{testlen} seconds. A negative value for +@var{testlen} will run each iteration for the absolute value of +@var{testlen} transactions for a _RR test or bytes for a _STREAM test. +Certain tests, notably those using UDP can only be timed, they cannot +be limited by transaction or byte count. + +In some situations, individual iterations of a test may run for longer +for the number of seconds specified by the @option{-l} option. In +particular, this may occur for those tests where the socket buffer +size(s) are significantly longer than the bandwidthXdelay product of +the link(s) over which the data connection passes, or those tests +where there may be non-trivial numbers of retransmissions. + +If confidence intervals are enabled via either @option{-I} or +@option{-i} the total length of the netperf test will be somewhere +between the minimum and maximum iteration count multiplied by +@var{testlen}. + +@vindex -L, Global +@item -L +This option is identical to the @option{-H} option with the difference +being it sets the _local_ hostname/IP and/or address family +information. This option is generally unnecessary, but can be useful +when you wish to make sure that the netperf control and data +connections go via different paths. It can also come-in handy if one +is trying to run netperf through those evil, end-to-end breaking +things known as firewalls. + +[Default: 0.0.0.0 (eg INADDR_ANY) for IPv4 and ::0 for IPv6 for the +local name. AF_UNSPEC for the local address family.] + +@vindex -n, Global +@item -n numcpus +This option tells netperf how many CPUs it should ass-u-me are active +on the system running netperf. In particular, this is used for the +@ref{CPU Utilization,CPU utilization} and service demand calculations. +On certain systems, netperf is able to determine the number of CPU's +automagically. This option will override any number netperf might be +able to determine on its own. + +Note that this option does _not_ set the number of CPUs on the system +running netserver. When netperf/netserver cannot automagically +determine the number of CPUs that can only be set for netserver via a +netserver @option{-n} command-line option. + +@vindex -N, Global +@item -N +This option tells netperf to forego establishing a control +connection. This makes it is possible to run some limited netperf +tests without a corresponding netserver on the remote system. + +With this option set, the test to be run is to get all the addressing +information it needs to establish its data connection from the command +line or internal defaults. If not otherwise specified by +test-specific command line options, the data connection for a +``STREAM'' or ``SENDFILE'' test will be to the ``discard'' port, an +``RR'' test will be to the ``echo'' port, and a ``MEARTS'' test will +be to the chargen port. + +The response size of an ``RR'' test will be silently set to be the +same as the request size. Otherwise the test would hang if the +response size was larger than the request size, or would report an +incorrect, inflated transaction rate if the response size was less +than the request size. + +Since there is no control connection when this option is specified, it +is not possible to set ``remote'' properties such as socket buffer +size and the like via the netperf command line. Nor is it possible to +retrieve such interesting remote information as CPU utilization. +These items will be set to values which when displayed should make it +immediately obvious that was the case. + +The only way to change remote characteristics such as socket buffer +size or to obtain information such as CPU utilization is to employ +platform-specific methods on the remote system. Frankly, if one has +access to the remote system to employ those methods one aught to be +able to run a netserver there. However, that ability may not be +present in certain ``support'' situations, hence the addition of this +option. + +Added in netperf 2.4.3. + +@vindex -o, Global +@item -o +The value(s) passed-in with this option will be used as an offset +added to the alignment specified with the @option{-a} option. For +example: +@example +-o 3 -a 4096 +@end example +will cause the buffers passed to the local send and receive calls to +begin three bytes past an address aligned to 4096 bytes. [Default: 0 +bytes] + +@vindex -O, Global +@item -O +This option behaves just as the @option{-o} option but on the remote +system and in conjunction with the @option{-A} option. [Default: 0 +bytes] + +@vindex -p, Global +@item -p +The first value of the optionspec passed-in with this option tells +netperf the port number at which it should expect the remote netserver +to be listening for control connections. The second value of the +optionspec will request netperf to bind to that local port number +before establishing the control connection. For example +@example +-p 12345 +@end example +tells netperf that the remote netserver is listening on port 12345 and +leaves selection of the local port number for the control connection +up to the local TCP/IP stack whereas +@example +-p ,32109 +@end example +leaves the remote netserver port at the default value of 12865 and +causes netperf to bind to the local port number 32109 before +connecting to the remote netserver. + +In general, setting the local port number is only necessary when one +is looking to run netperf through those evil, end-to-end breaking +things known as firewalls. + +@vindex -P, Global +@item -P 0|1 +A value of ``1'' for the @option{-P} option will enable display of +the test banner. A value of ``0'' will disable display of the test +banner. One might want to disable display of the test banner when +running the same basic test type (eg TCP_STREAM) multiple times in +succession where the test banners would then simply be redundant and +unnecessarily clutter the output. [Default: 1 - display test banners] + +@vindex -t, Global +@item -t testname +This option is used to tell netperf which test you wish to run. As of +this writing, valid values for @var{testname} include: +@itemize +@item +@ref{TCP_STREAM}, @ref{TCP_MAERTS}, @ref{TCP_SENDFILE}, @ref{TCP_RR}, @ref{TCP_CRR}, @ref{TCP_CC} +@item +@ref{UDP_STREAM}, @ref{UDP_RR} +@item +@ref{XTI_TCP_STREAM}, @ref{XTI_TCP_RR}, @ref{XTI_TCP_CRR}, @ref{XTI_TCP_CC} +@item +@ref{XTI_UDP_STREAM}, @ref{XTI_UDP_RR} +@item +@ref{SCTP_STREAM}, @ref{SCTP_RR} +@item +@ref{DLCO_STREAM}, @ref{DLCO_RR}, @ref{DLCL_STREAM}, @ref{DLCL_RR} +@item +@ref{Other Netperf Tests,LOC_CPU}, @ref{Other Netperf Tests,REM_CPU} +@end itemize +Not all tests are always compiled into netperf. In particular, the +``XTI,'' ``SCTP,'' ``UNIX,'' and ``DL*'' tests are only included in +netperf when configured with +@option{--enable-[xti|sctp|unix|dlpi]=yes}. + +Netperf only runs one type of test no matter how many @option{-t} +options may be present on the command-line. The last @option{-t} +global command-line option will determine the test to be +run. [Default: TCP_STREAM] + +@vindex -v, Global +@item -v verbosity +This option controls how verbose netperf will be in its output, and is +often used in conjunction with the @option{-P} option. If the +verbosity is set to a value of ``0'' then only the test's SFM (Single +Figure of Merit) is displayed. If local @ref{CPU Utilization,CPU +utilization} is requested via the @option{-c} option then the SFM is +the local service demand. Othersise, if remote CPU utilization is +requested via the @option{-C} option then the SFM is the remote +service demand. If neither local nor remote CPU utilization are +requested the SFM will be the measured throughput or transaction rate +as implied by the test specified with the @option{-t} option. + +If the verbosity level is set to ``1'' then the ``normal'' netperf +result output for each test is displayed. + +If the verbosity level is set to ``2'' then ``extra'' information will +be displayed. This may include, but is not limited to the number of +send or recv calls made and the average number of bytes per send or +recv call, or a histogram of the time spent in each send() call or for +each transaction if netperf was configured with +@option{--enable-histogram=yes}. [Default: 1 - normal verbosity] + +@vindex -w, Global +@item -w time +If netperf was configured with @option{--enable-intervals=yes} then +this value will set the inter-burst time to time milliseconds, and the +@option{-b} option will set the number of sends per burst. The actual +inter-burst time may vary depending on the system's timer resolution. + +@vindex -W, Global +@item -W +This option controls the number of buffers in the send (first or only +value) and or receive (second or only value) buffer rings. Unlike +some benchmarks, netperf does not continuously send or receive from a +single buffer. Instead it rotates through a ring of +buffers. [Default: One more than the size of the send or receive +socket buffer sizes (@option{-s} and/or @option{-S} options) divided +by the send @option{-m} or receive @option{-M} buffer size +respectively] + +@vindex -4, Global +@item -4 +Specifying this option will set both the local and remote address +families to AF_INET - that is use only IPv4 addresses on the control +connection. This can be overridden by a subsequent @option{-6}, +@option{-H} or @option{-L} option. Basically, the last option +explicitly specifying an address family wins. Unless overridden by a +test-specific option, this will be inherited for the data connection +as well. + +@vindex -6, Global +@item -6 +Specifying this option will set both local and and remote address +families to AF_INET6 - that is use only IPv6 addresses on the control +connection. This can be overridden by a subsequent @option{-4}, +@option{-H} or @option{-L} option. Basically, the last address family +explicitly specified wins. Unless overridden by a test-specific +option, this will be inherited for the data connection as well. + +@end table + + +@node Using Netperf to Measure Bulk Data Transfer, Using Netperf to Measure Request/Response , Global Command-line Options, Top +@chapter Using Netperf to Measure Bulk Data Transfer + +The most commonly measured aspect of networked system performance is +that of bulk or unidirectional transfer performance. Everyone wants +to know how many bits or bytes per second they can push across the +network. The netperf convention for a bulk data transfer test name is +to tack a ``_STREAM'' suffix to a test name. + +@menu +* Issues in Bulk Transfer:: +* Options common to TCP UDP and SCTP tests:: +@end menu + +@node Issues in Bulk Transfer, Options common to TCP UDP and SCTP tests, Using Netperf to Measure Bulk Data Transfer, Using Netperf to Measure Bulk Data Transfer +@comment node-name, next, previous, up +@section Issues in Bulk Transfer + +There are any number of things which can affect the performance of a +bulk transfer test. + +Certainly, absent compression, bulk-transfer tests can be limited by +the speed of the slowest link in the path from the source to the +destination. If testing over a gigabit link, you will not see more +than a gigabit :) Such situations can be described as being +@dfn{network-limited} or @dfn{NIC-limited}. + +CPU utilization can also affect the results of a bulk-transfer test. +If the networking stack requires a certain number of instructions or +CPU cycles per KB of data transferred, and the CPU is limited in the +number of instructions or cycles it can provide, then the transfer can +be described as being @dfn{CPU-bound}. + +A bulk-transfer test can be CPU bound even when netperf reports less +than 100% CPU utilization. This can happen on an MP system where one +or more of the CPUs saturate at 100% but other CPU's remain idle. +Typically, a single flow of data, such as that from a single instance +of a netperf _STREAM test cannot make use of much more than the power +of one CPU. Exceptions to this generally occur when netperf and/or +netserver run on CPU(s) other than the CPU(s) taking interrupts from +the NIC(s). + +Distance and the speed-of-light can affect performance for a +bulk-transfer; often this can be mitigated by using larger windows. +One common limit to the performance of a transport using window-based +flow-control is: +@example +Throughput <= WindowSize/RoundTripTime +@end example +As the sender can only have a window's-worth of data outstanding on +the network at any one time, and the soonest the sender can receive a +window update from the receiver is one RoundTripTime (RTT). TCP and +SCTP are examples of such protocols. + +Packet losses and their effects can be particularly bad for +performance. This is especially true if the packet losses result in +retransmission timeouts for the protocol(s) involved. By the time a +retransmission timeout has happened, the flow or connection has sat +idle for a considerable length of time. + +On many platforms, some variant on the @command{netstat} command can +be used to retrieve statistics about packet loss and +retransmission. For example: +@example +netstat -p tcp +@end example +will retrieve TCP statistics on the HP-UX Operating System. On other +platforms, it may not be possible to retrieve statistics for a +specific protocol and something like: +@example +netstat -s +@end example +would be used instead. + +Many times, such network statistics are keep since the time the stack +started, and we are only really interested in statistics from when +netperf was running. In such situations something along the lines of: +@example +netstat -p tcp > before +netperf -t TCP_mumble... +netstat -p tcp > after +@end example +is indicated. The +@uref{ftp://ftp.cup.hp.com/dist/networking/tools/,beforeafter} utility +can be used to subtract the statistics in @file{before} from the +statistics in @file{after} +@example +beforeafter before after > delta +@end example +and then one can look at the statistics in @file{delta}. Beforeafter +is distributed in source form so one can compile it on the platofrm(s) +of interest. + +While it was written with HP-UX's netstat in mind, the +@uref{ftp://ftp.cup.hp.com/dist/networking/briefs/annotated_netstat.txt,annotated +netstat} writeup may be helpful with other platforms as well. + +@node Options common to TCP UDP and SCTP tests, , Issues in Bulk Transfer, Using Netperf to Measure Bulk Data Transfer +@comment node-name, next, previous, up +@section Options common to TCP UDP and SCTP tests + +Many ``test-specific'' options are actually common across the +different tests. For those tests involving TCP, UDP and SCTP, whether +using the BSD Sockets or the XTI interface those common options +include: + +@table @code +@vindex -h, Test-specific +@item -h +Display the test-suite-specific usage string and exit. For a TCP_ or +UDP_ test this will be the usage string from the source file +nettest_bsd.c. For an XTI_ test, this will be the usage string from +the source file nettest_xti.c. For an SCTP test, this will be the +usage string from the source file nettest_sctp.c. + +@item -H +Normally, the remote hostname|IP and address family information is +inherited from the settings for the control connection (eg global +command-line @option{-H}, @option{-4} and/or @option{-6} options). +The test-specific @option{-H} will override those settings for the +data (aka test) connection only. Settings for the control connection +are left unchanged. + +@vindex -L, Test-specific +@item -L +The test-specific @option{-L} option is identical to the test-specific +@option{-H} option except it affects the local hostname|IP and address +family information. As with its global command-line counterpart, this +is generally only useful when measuring though those evil, end-to-end +breaking things called firewalls. + +@vindex -m, Test-specific +@item -m bytes +Set the size of the buffer passed-in to the ``send'' calls of a +_STREAM test. Note that this may have only an indirect effect on the +size of the packets sent over the network, and certain Layer 4 +protocols do _not_ preserve or enforce message boundaries, so setting +@option{-m} for the send size does not necessarily mean the receiver +will receive that many bytes at any one time. By default the units are +bytes, but suffix of ``G,'' ``M,'' or ``K'' will specify the units to +be 2^30 (GB), 2^20 (MB) or 2^10 (KB) respectively. A suffix of ``g,'' +``m'' or ``k'' will specify units of 10^9, 10^6 or 10^3 bytes +respectively. For example: +@example +@code{-m 32K} +@end example +will set the size to 32KB or 32768 bytes. [Default: the local send +socket buffer size for the connection - either the system's default or +the value set via the @option{-s} option.] + +@vindex -M, Test-specific +@item -M bytes +Set the size of the buffer passed-in to the ``recv'' calls of a +_STREAM test. This will be an upper bound on the number of bytes +received per receive call. By default the units are bytes, but suffix +of ``G,'' ``M,'' or ``K'' will specify the units to be 2^30 (GB), 2^20 +(MB) or 2^10 (KB) respectively. A suffix of ``g,'' ``m'' or ``k'' +will specify units of 10^9, 10^6 or 10^3 bytes respectively. For +example: +@example +@code{-M 32K} +@end example +will set the size to 32KB or 32768 bytes. [Default: the remote receive +socket buffer size for the data connection - either the system's +default or the value set via the @option{-S} option.] + +@vindex -P, Test-specific +@item -P +Set the local and/or remote port numbers for the data connection. + +@vindex -s, Test-specific +@item -s +This option sets the local send and receive socket buffer sizes for +the data connection to the value(s) specified. Often, this will +affect the advertised and/or effective TCP or other window, but on +some platforms it may not. By default the units are bytes, but suffix +of ``G,'' ``M,'' or ``K'' will specify the units to be 2^30 (GB), 2^20 +(MB) or 2^10 (KB) respectively. A suffix of ``g,'' ``m'' or ``k'' +will specify units of 10^9, 10^6 or 10^3 bytes respectively. For +example: +@example +@code{-s 128K} +@end example +Will request the local send and receive socket buffer sizes to be +128KB or 131072 bytes. + +While the historic expectation is that setting the socket buffer size +has a direct effect on say the TCP window, today that may not hold +true for all stacks. Further, while the historic expectation is that +the value specified in a setsockopt() call will be the value returned +via a getsockopt() call, at least one stack is known to deliberately +ignore history. When running under Windows a value of 0 may be used +which will be an indication to the stack the user wants to enable a +form of copy avoidance. [Default: -1 - use the system's default socket +buffer sizes] + +@vindex -S Test-specific +@item -S +This option sets the remote send and/or receive socket buffer sizes +for the data connection to the value(s) specified. Often, this +will affect the advertised and/or effective TCP or other window, but +on some platforms it may not. By default the units are bytes, but +suffix of ``G,'' ``M,'' or ``K'' will specify the units to be 2^30 +(GB), 2^20 (MB) or 2^10 (KB) respectively. A suffix of ``g,'' ``m'' +or ``k'' will specify units of 10^9, 10^6 or 10^3 bytes respectively. +For example: +@example +@code{-s 128K} +@end example +Will request the local send and receive socket buffer sizes to be +128KB or 131072 bytes. + +While the historic expectation is that setting the socket buffer size +has a direct effect on say the TCP window, today that may not hold +true for all stacks. Further, while the historic expectation is that +the value specified in a setsockopt() call will be the value returned +via a getsockopt() call, at least one stack is known to deliberately +ignore history. When running under Windows a value of 0 may be used +which will be an indication to the stack the user wants to enable a +form of copy avoidance. [Default: -1 - use the system's default socket +buffer sizes] + +@vindex -4, Test-specific +@item -4 +Set the local and remote address family for the data connection to +AF_INET - ie use IPv4 addressing only. Just as with their global +command-line counterparts the last of the @option{-4}, @option{-6}, +@option{-H} or @option{-L} option wins for their respective address +families. + +@vindex -6, Test-specific +@item -6 +This option is identical to its @option{-4} cousin, but requests IPv6 +addresses for the local and remote ends of the data connection. + +@end table + + +@menu +* TCP_STREAM:: +* TCP_MAERTS:: +* TCP_SENDFILE:: +* UDP_STREAM:: +* XTI_TCP_STREAM:: +* XTI_UDP_STREAM:: +* SCTP_STREAM:: +* DLCO_STREAM:: +* DLCL_STREAM:: +* STREAM_STREAM:: +* DG_STREAM:: +@end menu + +@node TCP_STREAM, TCP_MAERTS, Options common to TCP UDP and SCTP tests, Options common to TCP UDP and SCTP tests +@subsection TCP_STREAM + +The TCP_STREAM test is the default test in netperf. It is quite +simple, transferring some quantity of data from the system running +netperf to the system running netserver. While time spent +establishing the connection is not included in the throughput +calculation, time spent flushing the last of the data to the remote at +the end of the test is. This is how netperf knows that all the data +it sent was received by the remote. In addition to the @ref{Options +common to TCP UDP and SCTP tests,options common to STREAM tests}, the +following test-specific options can be included to possibly alter the +behavior of the test: + +@table @code +@item -C +This option will set TCP_CORK mode on the data connection on those +systems where TCP_CORK is defined (typically Linux). A full +description of TCP_CORK is beyond the scope of this manual, but in a +nutshell it forces sub-MSS sends to be buffered so every segment sent +is Maximum Segment Size (MSS) unless the application performs an +explicit flush operation or the connection is closed. At present +netperf does not perform any explicit flush operations. Setting +TCP_CORK may improve the bitrate of tests where the ``send size'' +(@option{-m} option) is smaller than the MSS. It should also improve +(make smaller) the service demand. + +The Linux tcp(7) manpage states that TCP_CORK cannot be used in +conjunction with TCP_NODELAY (set via the @option{-d} option), however +netperf does not validate command-line options to enforce that. + +@item -D +This option will set TCP_NODELAY on the data connection on those +systems where TCP_NODELAY is defined. This disables something known +as the Nagle Algorithm, which is intended to make the segments TCP +sends as large as reasonably possible. Setting TCP_NODELAY for a +TCP_STREAM test should either have no effect when the send size +(@option{-m} option) is larger than the MSS or will decrease reported +bitrate and increase service demand when the send size is smaller than +the MSS. This stems from TCP_NODELAY causing each sub-MSS send to be +its own TCP segment rather than being aggregated with other small +sends. This means more trips up and down the protocol stack per KB of +data transferred, which means greater CPU utilization. + +If setting TCP_NODELAY with @option{-D} affects throughput and/or +service demand for tests where the send size (@option{-m}) is larger +than the MSS it suggests the TCP/IP stack's implementation of the +Nagle Algorithm _may_ be broken, perhaps interpreting the Nagle +Algorithm on a segment by segment basis rather than the proper user +send by user send basis. However, a better test of this can be +achieved with the @ref{TCP_RR} test. + +@end table + +Here is an example of a basic TCP_STREAM test, in this case from a +Debian Linux (2.6 kernel) system to an HP-UX 11iv2 (HP-UX 11.23) +system: + +@example +$ netperf -H lag +TCP STREAM TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to lag.hpl.hp.com (15.4.89.214) port 0 AF_INET +Recv Send Send +Socket Socket Message Elapsed +Size Size Size Time Throughput +bytes bytes bytes secs. 10^6bits/sec + + 32768 16384 16384 10.00 80.42 +@end example + +We see that the default receive socket buffer size for the receiver +(lag - HP-UX 11.23) is 32768 bytes, and the default socket send buffer +size for the sender (Debian 2.6 kernel) is 16384 bytes. Througput is +expressed as 10^6 (aka Mega) bits per second, and the test ran for 10 +seconds. IPv4 addresses (AF_INET) were used. + +@node TCP_MAERTS, TCP_SENDFILE, TCP_STREAM, Options common to TCP UDP and SCTP tests +@comment node-name, next, previous, up +@subsection TCP_MAERTS + +A TCP_MAERTS (MAERTS is STREAM backwards) test is ``just like'' a +@ref{TCP_STREAM} test except the data flows from the netserver to the +netperf. The global command-line @option{-F} option is ignored for +this test type. The test-specific command-line @option{-C} option is +ignored for this test type. + +Here is an example of a TCP_MAERTS test between the same two systems +as in the example for the @ref{TCP_STREAM} test. This time we request +larger socket buffers with @option{-s} and @option{-S} options: + +@example +$ netperf -H lag -t TCP_MAERTS -- -s 128K -S 128K +TCP MAERTS TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to lag.hpl.hp.com (15.4.89.214) port 0 AF_INET +Recv Send Send +Socket Socket Message Elapsed +Size Size Size Time Throughput +bytes bytes bytes secs. 10^6bits/sec + +221184 131072 131072 10.03 81.14 +@end example + +Where we see that Linux, unlike HP-UX, may not return the same value +in a getsockopt() as was requested in the prior setsockopt(). + +This test is included more for benchmarking convenience than anything +else. + +@node TCP_SENDFILE, UDP_STREAM, TCP_MAERTS, Options common to TCP UDP and SCTP tests +@comment node-name, next, previous, up +@subsection TCP_SENDFILE + +The TCP_SENDFILE test is ``just like'' a @ref{TCP_STREAM} test except +netperf the platform's @code{sendfile()} call instead of calling +@code{send()}. Often this results in a @dfn{zero-copy} operation +where data is sent directly from the filesystem buffer cache. This +_should_ result in lower CPU utilization and possibly higher +throughput. If it does not, then you may want to contact your +vendor(s) because they have a problem on their hands. + +Zero-copy mechanisms may also alter the characteristics (size and +number of buffers per) of packets passed to the NIC. In many stacks, +when a copy is performed, the stack can ``reserve'' space at the +beginning of the destination buffer for things like TCP, IP and Link +headers. This then has the packet contained in a single buffer which +can be easier to DMA to the NIC. When no copy is performed, there is +no opportunity to reserve space for headers and so a packet will be +contained in two or more buffers. + +The @ref{Global Options,global @option{-F} option} is required for this test and it must +specify a file of at least the size of the send ring (@xref{Global +Options,the global @option{-W} option}.) multiplied by the send size +(@xref{Options common to TCP UDP and SCTP tests,the test-specific +@option{-m} option}.). All other TCP-specific options are available +and optional. + +In this first example: +@example +$ netperf -H lag -F ../src/netperf -t TCP_SENDFILE -- -s 128K -S 128K +TCP SENDFILE TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to lag.hpl.hp.com (15.4.89.214) port 0 AF_INET +alloc_sendfile_buf_ring: specified file too small. +file must be larger than send_width * send_size +@end example + +we see what happens when the file is too small. Here: + +@example +$ ../src/netperf -H lag -F /boot/vmlinuz-2.6.8-1-686 -t TCP_SENDFILE -- -s 128K -S 128K +TCP SENDFILE TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to lag.hpl.hp.com (15.4.89.214) port 0 AF_INET +Recv Send Send +Socket Socket Message Elapsed +Size Size Size Time Throughput +bytes bytes bytes secs. 10^6bits/sec + +131072 221184 221184 10.02 81.83 +@end example + +we resolve that issue by selecting a larger file. + + +@node UDP_STREAM, XTI_TCP_STREAM, TCP_SENDFILE, Options common to TCP UDP and SCTP tests +@subsection UDP_STREAM + +A UDP_STREAM test is similar to a @ref{TCP_STREAM} test except UDP is +used as the transport rather than TCP. + +@cindex Limiting Bandwidth +A UDP_STREAM test has no end-to-end flow control - UDP provides none +and neither does netperf. However, if you wish, you can configure +netperf with @code{--enable-intervals=yes} to enable the global +command-line @option{-b} and @option{-w} options to pace bursts of +traffic onto the network. + +This has a number of implications. + +The biggest of these implications is the data which is sent might not +be received by the remote. For this reason, the output of a +UDP_STREAM test shows both the sending and receiving throughput. On +some platforms, it may be possible for the sending throughput to be +reported as a value greater than the maximum rate of the link. This +is common when the CPU(s) are faster than the network and there is no +@dfn{intra-stack} flow-control. + +Here is an example of a UDP_STREAM test between two systems connected +by a 10 Gigabit Ethernet link: +@example +$ netperf -t UDP_STREAM -H 192.168.2.125 -- -m 32768 +UDP UNIDIRECTIONAL SEND TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to 192.168.2.125 (192.168.2.125) port 0 AF_INET +Socket Message Elapsed Messages +Size Size Time Okay Errors Throughput +bytes bytes secs # # 10^6bits/sec + +124928 32768 10.00 105672 0 2770.20 +135168 10.00 104844 2748.50 + +@end example + +The first line of numbers are statistics from the sending (netperf) +side. The second line of numbers are from the receiving (netserver) +side. In this case, 105672 - 104844 or 828 messages did not make it +all the way to the remote netserver process. + +If the value of the @option{-m} option is larger than the local send +socket buffer size (@option{-s} option) netperf will likely abort with +an error message about how the send call failed: + +@example +netperf -t UDP_STREAM -H 192.168.2.125 +UDP UNIDIRECTIONAL SEND TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to 192.168.2.125 (192.168.2.125) port 0 AF_INET +udp_send: data send error: Message too long +@end example + +If the value of the @option{-m} option is larger than the remote +socket receive buffer, the reported receive throughput will likely be +zero as the remote UDP will discard the messages as being too large to +fit into the socket buffer. + +@example +$ netperf -t UDP_STREAM -H 192.168.2.125 -- -m 65000 -S 32768 +UDP UNIDIRECTIONAL SEND TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to 192.168.2.125 (192.168.2.125) port 0 AF_INET +Socket Message Elapsed Messages +Size Size Time Okay Errors Throughput +bytes bytes secs # # 10^6bits/sec + +124928 65000 10.00 53595 0 2786.99 + 65536 10.00 0 0.00 +@end example + +The example above was between a pair of systems running a ``Linux'' +kernel. Notice that the remote Linux system returned a value larger +than that passed-in to the @option{-S} option. In fact, this value +was larger than the message size set with the @option{-m} option. +That the remote socket buffer size is reported as 65536 bytes would +suggest to any sane person that a message of 65000 bytes would fit, +but the socket isn't _really_ 65536 bytes, even though Linux is +telling us so. Go figure. + +@node XTI_TCP_STREAM, XTI_UDP_STREAM, UDP_STREAM, Options common to TCP UDP and SCTP tests +@subsection XTI_TCP_STREAM + +An XTI_TCP_STREAM test is simply a @ref{TCP_STREAM} test using the XTI +rather than BSD Sockets interface. The test-specific @option{-X +} option can be used to specify the name of the local and/or +remote XTI device files, which is required by the @code{t_open()} call +made by netperf XTI tests. + +The XTI_TCP_STREAM test is only present if netperf was configured with +@code{--enable-xti=yes}. The remote netserver must have also been +configured with @code{--enable-xti=yes}. + +@node XTI_UDP_STREAM, SCTP_STREAM, XTI_TCP_STREAM, Options common to TCP UDP and SCTP tests +@subsection XTI_UDP_STREAM + +An XTI_UDP_STREAM test is simply a @ref{UDP_STREAM} test using the XTI +rather than BSD Sockets Interface. The test-specific @option{-X +} option can be used to specify the name of the local and/or +remote XTI device files, which is required by the @code{t_open()} call +made by netperf XTI tests. + +The XTI_UDP_STREAM test is only present if netperf was configured with +@code{--enable-xti=yes}. The remote netserver must have also been +configured with @code{--enable-xti=yes}. + +@node SCTP_STREAM, DLCO_STREAM, XTI_UDP_STREAM, Options common to TCP UDP and SCTP tests +@subsection SCTP_STREAM + +An SCTP_STREAM test is essentially a @ref{TCP_STREAM} test using the SCTP +rather than TCP. The @option{-D} option will set SCTP_NODELAY, which +is much like the TCP_NODELAY option for TCP. The @option{-C} option +is not applicable to an SCTP test as there is no corresponding +SCTP_CORK option. The author is still figuring-out what the +test-specific @option{-N} option does :) + +The SCTP_STREAM test is only present if netperf was configured with +@code{--enable-sctp=yes}. The remote netserver must have also been +configured with @code{--enable-sctp=yes}. + +@node DLCO_STREAM, DLCL_STREAM, SCTP_STREAM, Options common to TCP UDP and SCTP tests +@subsection DLCO_STREAM + +A DLPI Connection Oriented Stream (DLCO_STREAM) test is very similar +in concept to a @ref{TCP_STREAM} test. Both use reliable, +connection-oriented protocols. The DLPI test differs from the TCP +test in that its protocol operates only at the link-level and does not +include TCP-style segmentation and reassembly. This last difference +means that the value passed-in with the @option{-m} option must be +less than the interface MTU. Otherwise, the @option{-m} and +@option{-M} options are just like their TCP/UDP/SCTP counterparts. + +Other DLPI-specific options include: + +@table @code +@item -D +This option is used to provide the fully-qualified names for the local +and/or remote DPLI device files. The syntax is otherwise identical to +that of a @dfn{sizespec}. +@item -p +This option is used to specify the local and/or remote DLPI PPA(s). +The PPA is used to identify the interface over which traffic is to be +sent/received. The syntax of a @dfn{ppaspec} is otherwise the same as +a @dfn{sizespec}. +@item -s sap +This option specifies the 802.2 SAP for the test. A SAP is somewhat +like either the port field of a TCP or UDP header or the protocol +field of an IP header. The specified SAP should not conflict with any +other active SAPs on the specified PPA's (@option{-p} option). +@item -w +This option specifies the local send and receive window sizes in units +of frames on those platforms which support setting such things. +@item -W +This option specifies the remote send and receive window sizes in +units of frames on those platforms which support setting such things. +@end table + +The DLCO_STREAM test is only present if netperf was configured with +@code{--enable-dlpi=yes}. The remote netserver must have also been +configured with @code{--enable-dlpi=yes}. + + +@node DLCL_STREAM, STREAM_STREAM, DLCO_STREAM, Options common to TCP UDP and SCTP tests +@subsection DLCL_STREAM + +A DLPI ConnectionLess Stream (DLCL_STREAM) test is analogous to a +@ref{UDP_STREAM} test in that both make use of unreliable/best-effort, +connection-less transports. The DLCL_STREAM test differs from the +@ref{UDP_STREAM} test in that the message size (@option{-m} option) must +always be less than the link MTU as there is no IP-like fragmentation +and reassembly available and netperf does not presume to provide one. + +The test-specific command-line options for a DLCL_STREAM test are the +same as those for a @ref{DLCO_STREAM} test. + +The DLCL_STREAM test is only present if netperf was configured with +@code{--enable-dlpi=yes}. The remote netserver must have also been +configured with @code{--enable-dlpi=yes}. + +@node STREAM_STREAM, DG_STREAM, DLCL_STREAM, Options common to TCP UDP and SCTP tests +@comment node-name, next, previous, up +@subsection STREAM_STREAM + +A Unix Domain Stream Socket Stream test (STREAM_STREAM) is similar in +concept to a @ref{TCP_STREAM} test, but using Unix Domain sockets. It is, +naturally, limited to intra-machine traffic. A STREAM_STREAM test +shares the @option{-m}, @option{-M}, @option{-s} and @option{-S} +options of the other _STREAM tests. In a STREAM_STREAM test the +@option{-p} option sets the directory in which the pipes will be +created rather than setting a port number. The default is to create +the pipes in the system default for the @code{tempnam()} call. + +The STREAM_STREAM test is only present if netperf was configured with +@code{--enable-unix=yes}. The remote netserver must have also been +configured with @code{--enable-unix=yes}. + +@node DG_STREAM, , STREAM_STREAM, Options common to TCP UDP and SCTP tests +@comment node-name, next, previous, up +@subsection DG_STREAM + +A Unix Domain Datagram Socket Stream test (SG_STREAM) is very much +like a @ref{TCP_STREAM} test except that message boundaries are preserved. +In this way, it may also be considered similar to certain flavors of +SCTP test which can also preserve message boundaries. + +All the options of a @ref{STREAM_STREAM} test are applicable to a DG_STREAM +test. + +The DG_STREAM test is only present if netperf was configured with +@code{--enable-unix=yes}. The remote netserver must have also been +configured with @code{--enable-unix=yes}. + + +@node Using Netperf to Measure Request/Response , Using Netperf to Measure Aggregate Performance, Using Netperf to Measure Bulk Data Transfer, Top +@chapter Using Netperf to Measure Request/Response + +Request/response performance is often overlooked, yet it is just as +important as bulk-transfer performance. While things like larger +socket buffers and TCP windows can cover a multitude of latency and +even path-length sins, they cannot easily hide from a request/response +test. The convention for a request/response test is to have a _RR +suffix. There are however a few ``request/response'' tests that have +other suffixes. + +A request/response test, particularly synchronous, one transaction at +at time test such as those found in netperf, is particularly sensitive +to the path-length of the networking stack. An _RR test can also +uncover those platforms where the NIC's are strapped by default with +overbearing interrupt avoidance settings in an attempt to increase the +bulk-transfer performance (or rather, decrease the CPU utilization of +a bulk-transfer test). This sensitivity is most acute for small +request and response sizes, such as the single-byte default for a +netperf _RR test. + +While a bulk-transfer test reports its results in units of bits or +bytes transfered per second, a mumble_RR test reports transactions per +second where a transaction is defined as the completed exchange of a +request and a response. One can invert the transaction rate to arrive +at the average round-trip latency. If one is confident about the +symmetry of the connection, the average one-way latency can be taken +as one-half the average round-trip latency. Netperf does not do +either of these on its own but leaves them as exercises to the +benchmarker. + +@menu +* Issues in Request/Response:: +* Options Common to TCP UDP and SCTP _RR tests:: +@end menu + +@node Issues in Request/Response, Options Common to TCP UDP and SCTP _RR tests, Using Netperf to Measure Request/Response , Using Netperf to Measure Request/Response +@comment node-name, next, previous, up +@section Issues in Reqeust/Response + +Most if not all the @ref{Issues in Bulk Transfer} apply to +request/response. The issue of round-trip latency is even more +important as netperf generally only has one transaction outstanding at +a time. + +A single instance of a one transaction outstanding _RR test should +_never_ completely saturate the CPU of a system. If testing between +otherwise evenly matched systems, the symmetric nature of a _RR test +with equal request and response sizes should result in equal CPU +loading on both systems. However, this may not hold true on MP +systems, particularly if one CPU binds the netperf and netserver +differently via the global @option{-T} option. + +For smaller request and response sizes packet loss is a bigger issue +as there is no opportunity for a @dfn{fast retransmit} or +retransmission prior to a retransmission timer expiring. + +Certain NICs have ways to minimize the number of interrupts sent to +the host. If these are strapped badly they can significantly reduce +the performance of something like a single-byte request/response test. +Such setups are distinguised by seriously low reported CPU utilization +and what seems like a low (even if in the thousands) transaction per +second rate. Also, if you run such an OS/driver combination on faster +or slower hardware and do not see a corresponding change in the +transaction rate, chances are good that the drvier is strapping the +NIC with aggressive interrupt avoidance settings. Good for bulk +throughput, but bad for latency. + +Some drivers may try to automagically adjust the interrupt avoidance +settings. If they are not terribly good at it, you will see +considerable run-to-run variation in reported transaction rates. +Particularly if you ``mix-up'' _STREAM and _RR tests. + + +@node Options Common to TCP UDP and SCTP _RR tests, , Issues in Request/Response, Using Netperf to Measure Request/Response +@comment node-name, next, previous, up +@section Options Common to TCP UDP and SCTP _RR tests + +Many ``test-specific'' options are actually common across the +different tests. For those tests involving TCP, UDP and SCTP, whether +using the BSD Sockets or the XTI interface those common options +include: + +@table @code +@vindex -h, Test-specific +@item -h +Display the test-suite-specific usage string and exit. For a TCP_ or +UDP_ test this will be the usage string from the source file +@file{nettest_bsd.c}. For an XTI_ test, this will be the usage string +from the source file @file{src/nettest_xti.c}. For an SCTP test, this +will be the usage string from the source file +@file{src/nettest_sctp.c}. + +@vindex -H, Test-specific +@item -H +Normally, the remote hostname|IP and address family information is +inherited from the settings for the control connection (eg global +command-line @option{-H}, @option{-4} and/or @option{-6} options. +The test-specific @option{-H} will override those settings for the +data (aka test) connection only. Settings for the control connection +are left unchanged. This might be used to cause the control and data +connections to take different paths through the network. + +@vindex -L, Test-specific +@item -L +The test-specific @option{-L} option is identical to the test-specific +@option{-H} option except it affects the local hostname|IP and address +family information. As with its global command-line counterpart, this +is generally only useful when measuring though those evil, end-to-end +breaking things called firewalls. + +@vindex -P, Test-specific +@item -P +Set the local and/or remote port numbers for the data connection. + +@vindex -r, Test-specific +@item -r +This option sets the request (first value) and/or response (second +value) sizes for an _RR test. By default the units are bytes, but a +suffix of ``G,'' ``M,'' or ``K'' will specify the units to be 2^30 +(GB), 2^20 (MB) or 2^10 (KB) respectively. A suffix of ``g,'' ``m'' +or ``k'' will specify units of 10^9, 10^6 or 10^3 bytes +respectively. For example: +@example +@code{-r 128,16K} +@end example +Will set the request size to 128 bytes and the response size to 16 KB +or 16384 bytes. [Default: 1 - a single-byte request and response ] + +@vindex -s, Test-specific +@item -s +This option sets the local send and receive socket buffer sizes for +the data connection to the value(s) specified. Often, this will +affect the advertised and/or effective TCP or other window, but on +some platforms it may not. By default the units are bytes, but a +suffix of ``G,'' ``M,'' or ``K'' will specify the units to be 2^30 +(GB), 2^20 (MB) or 2^10 (KB) respectively. A suffix of ``g,'' ``m'' +or ``k'' will specify units of 10^9, 10^6 or 10^3 bytes +respectively. For example: +@example +@code{-s 128K} +@end example +Will request the local send and receive socket buffer sizes to be +128KB or 131072 bytes. + +While the historic expectation is that setting the socket buffer size +has a direct effect on say the TCP window, today that may not hold +true for all stacks. When running under Windows a value of 0 may be +used which will be an indication to the stack the user wants to enable +a form of copy avoidance. [Default: -1 - use the system's default +socket buffer sizes] + +@vindex -S, Test-specific +@item -S +This option sets the remote send and/or receive socket buffer sizes +for the data connection to the value(s) specified. Often, this +will affect the advertised and/or effective TCP or other window, but +on some platforms it may not. By default the units are bytes, but a +suffix of ``G,'' ``M,'' or ``K'' will specify the units to be 2^30 +(GB), 2^20 (MB) or 2^10 (KB) respectively. A suffix of ``g,'' ``m'' +or ``k'' will specify units of 10^9, 10^6 or 10^3 bytes respectively. +For example: +@example +@code{-s 128K} +@end example +Will request the local send and receive socket buffer sizes to be +128KB or 131072 bytes. + +While the historic expectation is that setting the socket buffer size +has a direct effect on say the TCP window, today that may not hold +true for all stacks. When running under Windows a value of 0 may be +used which will be an indication to the stack the user wants to enable +a form of copy avoidance. [Default: -1 - use the system's default +socket buffer sizes] + +@vindex -4, Test-specific +@item -4 +Set the local and remote address family for the data connection to +AF_INET - ie use IPv4 addressing only. Just as with their global +command-line counterparts the last of the @option{-4}, @option{-6}, +@option{-H} or @option{-L} option wins for their respective address +families. + +@vindex -6 Test-specific +@item -6 +This option is identical to its @option{-4} cousin, but requests IPv6 +addresses for the local and remote ends of the data connection. + +@end table + +@menu +* TCP_RR:: +* TCP_CC:: +* TCP_CRR:: +* UDP_RR:: +* XTI_TCP_RR:: +* XTI_TCP_CC:: +* XTI_TCP_CRR:: +* XTI_UDP_RR:: +* DLCL_RR:: +* DLCO_RR:: +* SCTP_RR:: +@end menu + +@node TCP_RR, TCP_CC, Options Common to TCP UDP and SCTP _RR tests, Options Common to TCP UDP and SCTP _RR tests +@cindex Measuring Latency +@cindex Latency, Request-Response +@subsection TCP_RR + +A TCP_RR (TCP Request/Response) test is requested by passing a value +of ``TCP_RR'' to the global @option{-t} command-line option. A TCP_RR +test can be though-of as a user-space to user-space @code{ping} with +no think time - it is a synchronous, one transaction at a time, +request/response test. + +The transaction rate is the number of complete transactions exchanged +divided by the length of time it took to perform those transactions. + +If the two Systems Under Test are otherwise identical, a TCP_RR test +with the same request and response size should be symmetric - it +should not matter which way the test is run, and the CPU utilization +measured should be virtually the same on each system. If not, it +suggests that the CPU utilization mechanism being used may have some, +well, issues measuring CPU utilization completely and accurately. + +Time to establish the TCP connection is not counted in the result. If +you want connection setup overheads included, you should consider the +TCP_CC or TCP_CRR tests. + +If specifying the @option{-D} option to set TCP_NODELAY and disable +the Nagle Algorithm increases the transaction rate reported by a +TCP_RR test, it implies the stack(s) over which the TCP_RR test is +running have a broken implementation of the Nagle Algorithm. Likely +as not they are interpreting Nagle on a segment by segment basis +rather than a user send by user send basis. You should contact your +stack vendor(s) to report the problem to them. + +Here is an example of two systems running a basic TCP_RR test over a +10 Gigabit Ethernet link: + +@example +netperf -t TCP_RR -H 192.168.2.125 +TCP REQUEST/RESPONSE TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to 192.168.2.125 (192.168.2.125) port 0 AF_INET +Local /Remote +Socket Size Request Resp. Elapsed Trans. +Send Recv Size Size Time Rate +bytes Bytes bytes bytes secs. per sec + +16384 87380 1 1 10.00 29150.15 +16384 87380 +@end example + +In this example the request and response sizes were one byte, the +socket buffers were left at their defaults, and the test ran for all +of 10 seconds. The transaction per second rate was rather good :) + +@node TCP_CC, TCP_CRR, TCP_RR, Options Common to TCP UDP and SCTP _RR tests +@cindex Connection Latency +@cindex Latency, Connection Establishment +@subsection TCP_CC + +A TCP_CC (TCP Connect/Close) test is requested by passing a value of +``TCP_CC'' to the global @option{-t} option. A TCP_CC test simply +measures how fast the pair of systems can open and close connections +between one another in a synchronous (one at a time) manner. While +this is considered an _RR test, no request or response is exchanged +over the connection. + +@cindex Port Reuse +@cindex TIME_WAIT +The issue of TIME_WAIT reuse is an important one for a TCP_CC test. +Basically, TIME_WAIT reuse is when a pair of systems churn through +connections fast enough that they wrap the 16-bit port number space in +less time than the length of the TIME_WAIT state. While it is indeed +theoretically possible to ``reuse'' a connection in TIME_WAIT, the +conditions under which such reuse is possible are rather rare. An +attempt to reuse a connection in TIME_WAIT can result in a non-trivial +delay in connection establishment. + +Basically, any time the connection churn rate approaches: + +Sizeof(clientportspace) / Lengthof(TIME_WAIT) + +there is the risk of TIME_WAIT reuse. To minimize the chances of this +happening, netperf will by default select its own client port numbers +from the range of 5000 to 65535. On systems with a 60 second +TIME_WAIT state, this should allow roughly 1000 transactions per +second. The size of the client port space used by netperf can be +controlled via the test-specific @option{-p} option, which takes a +@dfn{sizespec} as a value setting the minimum (first value) and +maximum (second value) port numbers used by netperf at the client end. + +Since no requests or responses are exchanged during a TCP_CC test, +only the @option{-H}, @option{-L}, @option{-4} and @option{-6} of the +``common'' test-specific options are likely to have an effect, if any, +on the results. The @option{-s} and @option{-S} options _may_ have +some effect if they alter the number and/or type of options carried in +the TCP SYNchronize segments. The @option{-P} and @option{-r} +options are utterly ignored. + +Since connection establishment and tear-down for TCP is not symmetric, +a TCP_CC test is not symmetric in its loading of the two systems under +test. + +@node TCP_CRR, UDP_RR, TCP_CC, Options Common to TCP UDP and SCTP _RR tests +@cindex Latency, Connection Establishment +@cindex Latency, Request-Response +@subsection TCP_CRR + +The TCP Connect/Request/Response (TCP_CRR) test is requested by +passing a value of ``TCP_CRR'' to the global @option{-t} command-line +option. A TCP_RR test is like a merger of a TCP_RR and TCP_CC test +which measures the performance of establishing a connection, exchanging +a single request/response transaction, and tearing-down that +connection. This is very much like what happens in an HTTP 1.0 or +HTTP 1.1 connection when HTTP Keepalives are not used. In fact, the +TCP_CRR test was added to netperf to simulate just that. + +Since a request and response are exchanged the @option{-r}, +@option{-s} and @option{-S} options can have an effect on the +performance. + +The issue of TIME_WAIT reuse exists for the TCP_CRR test just as it +does for the TCP_CC test. Similarly, since connection establishment +and tear-down is not symmetric, a TCP_CRR test is not symmetric even +when the request and response sizes are the same. + +@node UDP_RR, XTI_TCP_RR, TCP_CRR, Options Common to TCP UDP and SCTP _RR tests +@cindex Latency, Request-Response +@cindex Packet Loss +@subsection UDP_RR + +A UDP Request/Response (UDP_RR) test is requested by passing a value +of ``UDP_RR'' to a global @option{-t} option. It is very much the +same as a TCP_RR test except UDP is used rather than TCP. + +UDP does not provide for retransmission of lost UDP datagrams, and +netperf does not add anything for that either. This means that if +_any_ request or response is lost, the exchange of requests and +responses will stop from that point until the test timer expires. +Netperf will not really ``know'' this has happened - the only symptom +will be a low transaction per second rate. + +The netperf side of a UDP_RR test will call @code{connect()} on its +data socket and thenceforth use the @code{send()} and @code{recv()} +socket calls. The netserver side of a UDP_RR test will not call +@code{connect()} and will use @code{recvfrom()} and @code{sendto()} +calls. This means that even if the request and response sizes are the +same, a UDP_RR test is _not_ symmetric in its loading of the two +systems under test. + +Here is an example of a UDP_RR test between two otherwise +identical two-CPU systems joined via a 1 Gigabit Ethernet network: + +@example +$ netperf -T 1 -H 192.168.1.213 -t UDP_RR -c -C +UDP REQUEST/RESPONSE TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to 192.168.1.213 (192.168.1.213) port 0 AF_INET +Local /Remote +Socket Size Request Resp. Elapsed Trans. CPU CPU S.dem S.dem +Send Recv Size Size Time Rate local remote local remote +bytes bytes bytes bytes secs. per sec % I % I us/Tr us/Tr + +65535 65535 1 1 10.01 15262.48 13.90 16.11 18.221 21.116 +65535 65535 +@end example + +This example includes the @option{-c} and @option{-C} options to +enable CPU utilization reporting and shows the asymmetry in CPU +loading. The @option{-T} option was used to make sure netperf and +netserver ran on a given CPU and did not move around during the test. + +@node XTI_TCP_RR, XTI_TCP_CC, UDP_RR, Options Common to TCP UDP and SCTP _RR tests +@cindex Latency, Request-Response +@subsection XTI_TCP_RR + +An XTI_TCP_RR test is essentially the same as a @ref{TCP_RR} test only +using the XTI rather than BSD Sockets interface. It is requested by +passing a value of ``XTI_TCP_RR'' to the @option{-t} global +command-line option. + +The test-specific options for an XTI_TCP_RR test are the same as those +for a TCP_RR test with the addition of the @option{-X } option to +specify the names of the local and/or remote XTI device file(s). + +@node XTI_TCP_CC, XTI_TCP_CRR, XTI_TCP_RR, Options Common to TCP UDP and SCTP _RR tests +@comment node-name, next, previous, up +@cindex Latency, Connection Establishment +@subsection XTI_TCP_CC + +@node XTI_TCP_CRR, XTI_UDP_RR, XTI_TCP_CC, Options Common to TCP UDP and SCTP _RR tests +@comment node-name, next, previous, up +@cindex Latency, Connection Establishment +@cindex Latency, Request-Response +@subsection XTI_TCP_CRR + +@node XTI_UDP_RR, DLCL_RR, XTI_TCP_CRR, Options Common to TCP UDP and SCTP _RR tests +@cindex Latency, Request-Response +@subsection XTI_UDP_RR + +An XTI_UDP_RR test is essentially the same as a UDP_RR test only using +the XTI rather than BSD Sockets interface. It is requested by passing +a value of ``XTI_UDP_RR'' to the @option{-t} global command-line +option. + +The test-specific options for an XTI_UDP_RR test are the same as those +for a UDP_RR test with the addition of the @option{-X } +option to specify the name of the local and/or remote XTI device +file(s). + +@node DLCL_RR, DLCO_RR, XTI_UDP_RR, Options Common to TCP UDP and SCTP _RR tests +@comment node-name, next, previous, up +@cindex Latency, Request-Response +@subsection DLCL_RR + +@node DLCO_RR, SCTP_RR, DLCL_RR, Options Common to TCP UDP and SCTP _RR tests +@comment node-name, next, previous, up +@cindex Latency, Request-Response +@subsection DLCO_RR + +@node SCTP_RR, , DLCO_RR, Options Common to TCP UDP and SCTP _RR tests +@comment node-name, next, previous, up +@cindex Latency, Request-Response +@subsection SCTP_RR + +@node Using Netperf to Measure Aggregate Performance, Using Netperf to Measure Bidirectional Transfer, Using Netperf to Measure Request/Response , Top +@comment node-name, next, previous, up +@cindex Aggregate Performance +@vindex --enable-burst, Configure +@chapter Using Netperf to Measure Aggregate Performance + +@ref{Netperf4,Netperf4} is the preferred benchmark to use when one +wants to measure aggregate performance because netperf has no support +for explicit synchronization of concurrent tests. + +Basically, there are two ways to measure aggregate performance with +netperf. The first is to run multiple, concurrent netperf tests and +can be applied to any of the netperf tests. The second is to +configure netperf with @code{--enable-burst} and is applicable to the +TCP_RR test. + +@menu +* Running Concurrent Netperf Tests:: +* Using --enable-burst:: +@end menu + +@node Running Concurrent Netperf Tests, Using --enable-burst, Using Netperf to Measure Aggregate Performance, Using Netperf to Measure Aggregate Performance +@comment node-name, next, previous, up +@section Running Concurrent Netperf Tests + +@ref{Netperf4,Netperf4} is the preferred benchmark to use when one +wants to measure aggregate performance because netperf has no support +for explicit synchronization of concurrent tests. This leaves +netperf2 results vulnerable to @dfn{skew} errors. + +However, since there are times when netperf4 is unavailable it may be +necessary to run netperf. The skew error can be minimized by making +use of the confidence interval functionality. Then one simply +launches multiple tests from the shell using a @code{for} loop or the +like: + +@example +for i in 1 2 3 4 +do +netperf -t TCP_STREAM -H tardy.cup.hp.com -i 10 -P 0 & +done +@end example + +which will run four, concurrent @ref{TCP_STREAM,TCP_STREAM} tests from +the system on which it is executed to tardy.cup.hp.com. Each +concurrent netperf will iterate 10 times thanks to the @option{-i} +option and will omit the test banners (option @option{-P}) for +brevity. The output looks something like this: + +@example + 87380 16384 16384 10.03 235.15 + 87380 16384 16384 10.03 235.09 + 87380 16384 16384 10.03 235.38 + 87380 16384 16384 10.03 233.96 +@end example + +We can take the sum of the results and be reasonably confident that +the aggregate performance was 940 Mbits/s. + +If you see warnings about netperf not achieving the confidence +intervals, the best thing to do is to increase the number of +iterations with @option{-i} and/or increase the run length of each +iteration with @option{-l}. + +You can also enable local (@option{-c}) and/or remote (@option{-C}) +CPU utilization: + +@example +for i in 1 2 3 4 +do +netperf -t TCP_STREAM -H tardy.cup.hp.com -i 10 -P 0 -c -C & +done + +87380 16384 16384 10.03 235.47 3.67 5.09 10.226 14.180 +87380 16384 16384 10.03 234.73 3.67 5.09 10.260 14.225 +87380 16384 16384 10.03 234.64 3.67 5.10 10.263 14.231 +87380 16384 16384 10.03 234.87 3.67 5.09 10.253 14.215 +@end example + +If the CPU utilizations reported for the same system are the same or +very very close you can be reasonably confident that skew error is +minimized. Presumeably one could then omit @option{-i} but that is +not advised, particularly when/if the CPU utilization approaches 100 +percent. In the example above we see that the CPU utilization on the +local system remains the same for all four tests, and is only off by +0.01 out of 5.09 on the remote system. + +@quotation +@b{NOTE: It is very important to rememeber that netperf is calculating +system-wide CPU utilization. When calculating the service demand +(those last two columns in the output above) each netperf assumes it +is the only thing running on the system. This means that for +concurrent tests the service demands reported by netperf will be +wrong. One has to compute service demands for concurrent tests by +hand.} +@end quotation + +If you wish you can add a unique, global @option{-B} option to each +command line to append the given string to the output: + +@example +for i in 1 2 3 4 +do +netperf -t TCP_STREAM -H tardy.cup.hp.com -B "this is test $i" -i 10 -P 0 & +done + +87380 16384 16384 10.03 234.90 this is test 4 +87380 16384 16384 10.03 234.41 this is test 2 +87380 16384 16384 10.03 235.26 this is test 1 +87380 16384 16384 10.03 235.09 this is test 3 +@end example + +You will notice that the tests completed in an order other than they +were started from the shell. This underscores why there is a threat +of skew error and why netperf4 is the preferred tool for aggregate +tests. Even if you see the Netperf Contributing Editor acting to the +contrary!-) + +@node Using --enable-burst, , Running Concurrent Netperf Tests, Using Netperf to Measure Aggregate Performance +@comment node-name, next, previous, up +@section Using --enable-burst + +If one configures netperf with @code{--enable-burst}: + +@example +configure --enable-burst +@end example + +Then a test-specific @option{-b num} option is added to the +@ref{TCP_RR,TCP_RR} and @ref{UDP_RR,UDP_RR} tests. This option causes +TCP_RR and UDP_RR to quickly work their way up to having at least +@option{num} transactions in flight at one time. + +This is used as an alternative to or even in conjunction with +multiple-concurrent _RR tests. When run with just a single instance +of netperf, increasing the burst size can determine the maximum number +of transactions per second can be serviced by a single process: + +@example +for b in 0 1 2 4 8 16 32 +do + netperf -v 0 -t TCP_RR -B "-b $b" -H hpcpc108 -P 0 -- -b $b +done + +9457.59 -b 0 +9975.37 -b 1 +10000.61 -b 2 +20084.47 -b 4 +29965.31 -b 8 +71929.27 -b 16 +109718.17 -b 32 +@end example + +The global @option{-v} and @option{-P} options were used to minimize +the output to the single figure of merit which in this case the +transaction rate. The global @code{-B} option was used to more +clearly label the output, and the test-specific @option{-b} option +enabled by @code{--enable-burst} set the number of transactions in +flight at one time. + +Now, since the test-specific @option{-D} option was not specified to +set TCP_NODELAY, the stack was free to ``bundle'' requests and/or +responses into TCP segments as it saw fit, and since the default +request and response size is one byte, there could have been some +considerable bundling. If one wants to try to achieve a closer to +one-to-one correspondence between a request and response and a TCP +segment, add the test-specific @option{-D} option: + +@example +for b in 0 1 2 4 8 16 32 +do + netperf -v 0 -t TCP_RR -B "-b $b -D" -H hpcpc108 -P 0 -- -b $b -D +done + + 8695.12 -b 0 -D + 19966.48 -b 1 -D + 20691.07 -b 2 -D + 49893.58 -b 4 -D + 62057.31 -b 8 -D + 108416.88 -b 16 -D + 114411.66 -b 32 -D +@end example + +You can see that this has a rather large effect on the reported +transaction rate. In this particular instance, the author believes it +relates to interactions between the test and interrupt coalescing +settings in the driver for the NICs used. + +@quotation +@b{NOTE: Even if you set the @option{-D} option that is still not a +guarantee that each transaction is in its own TCP segments. You +should get into the habit of verifying the relationship between the +transaction rate and the packet rate via other means} +@end quotation + +You can also combine @code{--enable-burst} functionality with +concurrent netperf tests. This would then be an ``aggregate of +aggregates'' if you like: + +@example + +for i in 1 2 3 4 +do + netperf -H hpcpc108 -v 0 -P 0 -i 10 -B "aggregate $i -b 8 -D" -t TCP_RR -- -b 8 -D & +done + + 46668.38 aggregate 4 -b 8 -D + 44890.64 aggregate 2 -b 8 -D + 45702.04 aggregate 1 -b 8 -D + 46352.48 aggregate 3 -b 8 -D + +@end example + +Since each netperf did hit the confidence intervals, we can be +reasonably certain that the aggregate transaction per second rate was +the sum of all four concurrent tests, or something just shy of 184,000 +transactions per second. To get some idea if that was also the packet +per second rate, we could bracket that @code{for} loop with something +to gather statistics and run the results through +@uref{ftp://ftp.cup.hp.com/dist/networking/tools,beforeafter}: + +@example +/usr/sbin/ethtool -S eth2 > before +for i in 1 2 3 4 +do + netperf -H 192.168.2.108 -l 60 -v 0 -P 0 -B "aggregate $i -b 8 -D" -t TCP_RR -- -b 8 -D & +done +wait +/usr/sbin/ethtool -S eth2 > after + + 52312.62 aggregate 2 -b 8 -D + 50105.65 aggregate 4 -b 8 -D + 50890.82 aggregate 1 -b 8 -D + 50869.20 aggregate 3 -b 8 -D + +beforeafter before after > delta + +grep packets delta + rx_packets: 12251544 + tx_packets: 12251550 + +@end example + +This example uses @code{ethtool} because the system being used is +running Linux. Other platforms have other tools - for example HP-UX +has lanadmin: + +@example +lanadmin -g mibstats +@end example + +and of course one could instead use @code{netstat}. + +The @code{wait} is important because we are launching concurrent +netperfs in the background. Without it, the second ethtool command +would be run before the tests finished and perhaps even before the +last of them got started! + +The sum of the reported transaction rates is 204178 over 60 seconds, +which is a total of 12250680 transactions. Each transaction is the +exchange of a request and a response, so we multiply that by 2 to +arrive at 24501360. + +The sum of the ethtool stats is 24503094 packets which matches what +netperf was reporting very well. + +Had the request or response size differed, we would need to know how +it compared with the @dfn{MSS} for the connection. + +Just for grins, here is the excercise repeated, using @code{netstat} +instead of @code{ethtool} + +@example +netstat -s -t > before +for i in 1 2 3 4 +do + netperf -l 60 -H 192.168.2.108 -v 0 -P 0 -B "aggregate $i -b 8 -D" -t TCP_RR -- -b 8 -D & done +wait +netstat -s -t > after + + 51305.88 aggregate 4 -b 8 -D + 51847.73 aggregate 2 -b 8 -D + 50648.19 aggregate 3 -b 8 -D + 53605.86 aggregate 1 -b 8 -D + +beforeafter before after > delta + +grep segments delta + 12445708 segments received + 12445730 segments send out + 1 segments retransmited + 0 bad segments received. +@end example + +The sums are left as an excercise to the reader :) + +Things become considerably more complicated if there are non-trvial +packet losses and/or retransmissions. + +Of course all this checking is unnecessary if the test is a UDP_RR +test because UDP ``never'' aggregates multiple sends into the same UDP +datagram, and there are no ACKnowledgements in UDP. The loss of a +single request or response will not bring a ``burst'' UDP_RR test to a +screeching halt, but it will reduce the number of transactions +outstanding at any one time. A ``burst'' UDP_RR test @b{will} come to a +halt if the sum of the lost requests and responses reaches the value +specified in the test-specific @option{-b} option. + + +@node Using Netperf to Measure Bidirectional Transfer, Other Netperf Tests, Using Netperf to Measure Aggregate Performance, Top +@comment node-name, next, previous, up +@chapter Using Netperf to Measure Bidirectional Transfer + +There are two ways to use netperf to measure the perfomance of +bidirectional transfer. The first is to run concurrent netperf tests +from the command line. The second is to configure netperf with +@code{--enable-burst} and use a single instance of the +@ref{TCP_RR,TCP_RR} test. + +While neither method is more ``correct'' than the other, each is doing +so in different ways, and that has possible implications. For +instance, using the concurrent netperf test mechanism means that +multiple TCP connections and multiple processes are involved, whereas +using the single instance of TCP_RR there is only one TCP connection +and one process on each end. They may behave differently, especially +on an MP system. + +@menu +* Bidirectional Transfer with Concurrent Tests:: +* Bidirectional Transfer with TCP_RR:: +@end menu + +@node Bidirectional Transfer with Concurrent Tests, Bidirectional Transfer with TCP_RR, Using Netperf to Measure Bidirectional Transfer, Using Netperf to Measure Bidirectional Transfer +@comment node-name, next, previous, up +@section Bidirectional Transfer with Concurrent Tests + +If we had two hosts Fred and Ethel, we could simply run a netperf +@ref{TCP_STREAM,TCP_STREAM} test on Fred pointing at Ethel, and a +concurrent netperf TCP_STREAM test on Ethel pointing at Fred, but +since there are no mechanisms to synchronize netperf tests and we +would be starting tests from two different systems, there is a +considerable risk of skew error. + +Far better would be to run simultaneous TCP_STREAM and +@ref{TCP_MAERTS,TCP_MAERTS} tests from just @b{one} system, using the +concepts and procedures outlined in @ref{Running Concurrent Netperf +Tests,Running Concurrent Netperf Tests}. Here then is an example: + +@example +for i in 1 +do + netperf -H 192.168.2.108 -t TCP_STREAM -B "outbound" -i 10 -P 0 -v 0 -- -s 256K -S 256K & + netperf -H 192.168.2.108 -t TCP_MAERTS -B "inbound" -i 10 -P 0 -v 0 -- -s 256K -S 256K & +done + + 892.66 outbound + 891.34 inbound + +@end example + +We have used a @code{for} loop in the shell with just one iteration +because that will be @b{much} easier to get both tests started at more or +less the same time than doing it by hand. The global @option{-P} and +@option{-v} options are used because we aren't interested in anything +other than the throughput, and the global @option{-B} option is used +to tag each output so we know which was inbound and which outbound +relative to the system on which we were running netperf. Of course +that sense is switched on the system running netserver :) The use of +the global @option{-i} option is explained in @ref{Running Concurrent +Netperf Tests,Running Concurrent Netperf Tests}. + +@node Bidirectional Transfer with TCP_RR, , Bidirectional Transfer with Concurrent Tests, Using Netperf to Measure Bidirectional Transfer +@comment node-name, next, previous, up +@section Bidirectional Transfer with TCP_RR + +If one configures netperf with @code{--enable-burst} then one can use +the test-specific @option{-b} option to increase the number of +transactions in flight at one time. If one also uses the -r option to +make those transactions larger the test starts to look more and more +like a bidirectional transfer than a request/response test. + +Now, the logic behing @code{--enable-burst} is very simple, and there +are no calls to @code{poll()} or @code{select()} which means we want +to make sure that the @code{send()} calls will never block, or we run +the risk of deadlock with each side stuck trying to call @code{send()} +and neither calling @code{recv()}. + +Fortunately, this is easily accomplished by setting a ``large enough'' +socket buffer size with the test-specific @option{-s} and @option{-S} +options. Presently this must be performed by the user. Future +versions of netperf might attempt to do this automagically, but there +are some issues to be worked-out. + +Here then is an example of a bidirectional transfer test using +@code{--enable-burst} and the @ref{TCP_RR,TCP_RR} test: + +@example +netperf -t TCP_RR -H hpcpc108 -- -b 6 -r 32K -s 256K -S 256K +TCP REQUEST/RESPONSE TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to hpcpc108.cup.hp.com (16.89.84.108) port 0 AF_INET : first burst 6 +Local /Remote +Socket Size Request Resp. Elapsed Trans. +Send Recv Size Size Time Rate +bytes Bytes bytes bytes secs. per sec + +524288 524288 32768 32768 10.01 3525.97 +524288 524288 + +@end example + +Now, at present netperf does not include a bit or byte rate in the +output of an _RR test which means we must calculate it ourselves. Each +transaction is the exchange of 32768 bytes of request and 32768 bytes +of response, or 65536 bytes. Multiply that by 8 and we arrive at +524288 bits per transaction. Multiply that by 3525.97 and we arrive +at 1848623759 bits per second. Since things were uniform, we can +divide that by two and arrive at roughly 924311879 bits per second +each way. That corresponds to ``link-rate'' for a 1 Gigiabit Ethernet +which happens to be the type of netpwrk used in the example. + +A future version of netperf may perform the calculation on behalf of +the user, but it would likely not emit it unless the user specified a +verbosity of 2 or more with the global @option{-v} option. + +@node Other Netperf Tests, Address Resolution, Using Netperf to Measure Bidirectional Transfer, Top +@chapter Other Netperf Tests + +Apart from the typical performance tests, netperf contains some tests +which can be used to streamline measurements and reporting. These +include CPU rate calibration (present) and host identification (future +enhancement). + +@menu +* CPU rate calibration:: +@end menu + +@node CPU rate calibration, , Other Netperf Tests, Other Netperf Tests +@section CPU rate calibration + +Some of the CPU utilization measurement mechanisms of netperf work by +comparing the rate at which some counter increments when the system is +idle with the rate at which that same counter increments when the +system is running a netperf test. The ratio of those rates is used to +arrive at a CPU utilization percentage. + +This means that netperf must know the rate at which the counter +increments when the system is presumed to be ``idle.'' If it does not +know the rate, netperf will measure it before starting a data transfer +test. This calibration step takes 40 seconds for each of the local or +remote ystems, and if repeated for each netperf test would make taking +repeated measurements rather slow. + +Thus, the netperf CPU utilization options @option{-c} and and +@option{-C} can take an optional calibration value. This value is +used as the ``idle rate'' and the calibration step is not +performed. To determine the idle rate, netperf can be used to run +special tests which only report the value of the calibration - they +are the LOC_CPU and REM_CPU tests. These return the calibration value +for the local and remote system respectively. A common way to use +these tests is to store their results into an environment variable and +use that in subsequent netperf commands: + +@example +LOC_RATE=`netperf -t LOC_CPU` +REM_RATE=`netperf -H -t REM_CPU` +netperf -H -c $LOC_RATE -C $REM_RATE ... -- ... +... +netperf -H -c $LOC_RATE -C $REM_RATE ... -- ... +@end example + +If you are going to use netperf to measure aggregate results, it is +important to use the LOC_CPU and REM_CPU tests to get the calibration +values first to avoid issues with some of the aggregate netperf tests +transferring data while others are ``idle'' and getting bogus +calibration values. When running aggregate tests, it is very +important to remember that any one instance of netperf does not know +about the other instances of netperf. It will report global CPU +utilization and will calculate service demand believing it was the +only thing causing that CPU utilization. So, you can use the CPU +utilization reported by netperf in an aggregate test, but you have to +calculate service demands by hand. + +@node Address Resolution, Enhancing Netperf, Other Netperf Tests, Top +@comment node-name, next, previous, up +@chapter Address Resolution + +Netperf versions 2.4.0 and later have merged IPv4 and IPv6 tests so +the functionality of the tests in @file{src/nettest_ipv6.c} has been +subsumed into the tests in @file{src/nettest_bsd.c} This has been +accomplished in part by switching from @code{gethostbyname()}to +@code{getaddrinfo()} exclusively. While it was theoretically possible +to get multiple results for a hostname from @code{gethostbyname()} it +was generally unlikely and netperf's ignoring of the second and later +results was not much of an issue. + +Now with @code{getaddrinfo} and particularly with AF_UNSPEC it is +increasingly likely that a given hostname will have multiple +associated addresses. The @code{establish_control()} routine of +@file{src/netlib.c} will indeed attempt to chose from among all the +matching IP addresses when establishing the control connection. +Netperf does not _really_ care if the control connection is IPv4 or +IPv6 or even mixed on either end. + +However, the individual tests still ass-u-me that the first result in +the address list is the one to be used. Whether or not this will +turn-out to be an issue has yet to be determined. + +If you do run into problems with this, the easiest workaround is to +specify IP addresses for the data connection explicitly in the +test-specific @option{-H} and @option{-L} options. At some point, the +netperf tests _may_ try to be more sophisticated in their parsing of +returns from @code{getaddrinfo()} - straw-man patches to +@email{netperf-feedback@@netperf.org} would of course be most welcome +:) + +Netperf has leveraged code from other open-source projects with +amenable licensing to provide a replacement @code{getaddrinfo()} call +on those platforms where the @command{configure} script believes there +is no native getaddrinfo call. As of this writing, the replacement +@code{getaddrinfo()} as been tested on HP-UX 11.0 and then presumed to +run elsewhere. + +@node Enhancing Netperf, Netperf4, Address Resolution, Top +@comment node-name, next, previous, up +@chapter Enhancing Netperf + +Netperf is constantly evolving. If you find you want to make +enhancements to netperf, by all means do so. If you wish to add a new +``suite'' of tests to netperf the general idea is to + +@enumerate +@item +Add files @file{src/nettest_mumble.c} and @file{src/nettest_mumble.h} +where mumble is replaced with something meaningful for the test-suite. +@item +Add support for an apropriate @option{--enable-mumble} option in +@file{configure.ac}. +@item +Edit @file{src/netperf.c}, @file{netsh.c}, and @file{netserver.c} as +required, using #ifdef WANT_MUMBLE. +@item +Compile and test +@end enumerate + +If you wish to submit your changes for possible inclusion into the +mainline sources, please try to base your changes on the latest +available sources. (@xref{Getting Netperf Bits}.) and then send email +describing the changes at a high level to +@email{netperf-feedback@@netperf.org} or perhaps +@email{netperf-talk@@netperf.org}. If the concensus is positive, then +sending context @command{diff} results to +@email{netperf-feedback@@netperf.org} is the next step. From that +point, it is a matter of pestering the Netperf Contributing Editor +until he gets the changes incorporated :) + +@node Netperf4, Concept Index, Enhancing Netperf, Top +@comment node-name, next, previous, up +@chapter Netperf4 + +Netperf4 is the shorthand name given to version 4.X.X of netperf. +This is really a separate benchmark more than a newer version of +netperf, but it is a decendant of netperf so the netperf name is +kept. The facetious way to describe netperf4 is to say it is the +egg-laying-woolly-milk-pig version of netperf :) The more respectful +way to describe it is to say it is the version of netperf with support +for synchronized, multiple-thread, multiple-test, multiple-system, +network-oriented benchmarking. + +Netperf4 is still undergoing rapid evolution. Those wishing to work +with or on netperf4 are encouraged to join the +@uref{http://www.netperf.org/cgi-bin/mailman/listinfo/netperf-dev,netperf-dev} +mailing list and/or peruse the +@uref{http://www.netperf.org/svn/netperf4/trunk,current sources}. + +@node Concept Index, Option Index, Netperf4, Top +@unnumbered Concept Index + +@printindex cp + +@node Option Index, , Concept Index, Top +@comment node-name, next, previous, up +@unnumbered Option Index + +@printindex vr +@bye + +@c LocalWords: texinfo setfilename settitle titlepage vskip pt filll ifnottex +@c LocalWords: insertcopying cindex dfn uref printindex cp diff --git a/doc/netperf_old.ps b/doc/netperf_old.ps new file mode 100644 index 0000000..a6db420 --- /dev/null +++ b/doc/netperf_old.ps @@ -0,0 +1,24014 @@ +%!PS-Adobe-3.0 +%%Creator: (Interleaf, Inc.) +%%Copyright: (Copyright(c) 1993 Interleaf, Inc.) +%%Version: 6.0 0 +%%BoundingBox: 0 0 612 792 +%%For: (raj) +%%CreationDate: (Tue, Feb 27, 1996 16:53:39) +%%Title: (Netperf) +%%Pages: (atend) +%%DocumentNeededResources: (atend) +%%DocumentSuppliedResources: (atend) +%%DocumentProcessColors: (atend) +%%DocumentCustomColors: (atend) +%ILEAFJob Ticket Start +%ILEAFPrintTo: "device" +%ILEAFCollate: "True" +%ILEAFCopies: "1" +%ILEAFCoverPage: "False" +%ILEAFCropMarks: "Off" +%ILEAFDuplex: "None" +%ILEAFFace: "Down" +%ILEAFManualFeed: "True" +%ILEAFPageSize: "Letter" +%ILEAFCenter: "None" +%ILEAFScale: "100" +%ILEAFAutoScale: "False" +%ILEAFAutoPageSize: "True" +%ILEAFFiltArgs: "-nmsg -def '#-ppd#GENERIC.PPD#-e#-dps#A3#' " +%ILEAFFilter: "pl2ps" +%ILEAFSpool: "n" +%ILEAFModel: "Generic PostScript" +%ILEAFPPDFile: "GENERIC.PPD" +%ILEAFFilterLoc: "desktop" +%ILEAFJob Ticket End +%%EndComments +%%BeginProlog +userdict /Ileaf_6.0.0 400 dict dup begin put +/MAJOR 6 def/MINOR 0 def/SUB 0 def +/bdf {bind def} bind def +/ilput {Ileaf_6.0.0 3 1 roll dup begin put} bdf +/ildef {bind end def} bdf +/ldf{load def}bdf +/xdf{exch def}bdf +/sdf{string def}bdf +/imatrix[1.0 0.0 0.0 -1.0 0.0 0.0]def +/MAXCHARS 128 def +/VMHEAD 1000 def +/BOGUSWIDTH -1 def +/mesg 64 sdf +/charstr 12 sdf +/istr 3 sdf +/ILEncoding 256 array def +/ILSymBEnc 256 array def +/ILDingbats 256 array def +/trashheap 1024 sdf +/emsg1 256 sdf +/emsg2 256 sdf +/inch{72 mul}bdf +/pgstate 0 def/DPIx 0 def/DPIy 0 def +/PSfontobj 1024 dict def +/BinaryMode false def +/L /lineto ldf +/M /moveto ldf +/C /closepath ldf +/N /newpath ldf +/LW /setlinewidth ldf +/GS /gsave ldf +/GR /grestore ldf +/SF /setfont ldf +/SD /setdash ldf +/CD /countdictstack ldf +% User definable macros for custom prologues +/BOJ {} def +/EOJ {} def +/BOS {} def +/EOS {} def +% +/initialize {Ileaf_6.0.0 begin} bdf +/terminate /end ldf +/npop { + {pop} repeat +} bdf +% + /hline 0 def /y 11 def /jishdr 0 def + /nl {/y y .33 sub def 1 inch y inch M} bdf +/headerpage{ + /#copies 1 def + /jishdr xdf + jishdr { + /GothicBBB-Medium-83pv-RKSJ-H findfont 14 scalefont setfont + } { + /Helvetica-Bold/ILhelvb ILEncoding 0 ReEncode + /ILhelvb findfont 18 scalefont setfont + } ifelse + nl nl nl + hline length dup dup + 25 gt{26 sub dup hline exch(( ...))put} {pop 0}ifelse + exch 1 sub -1 3 -1 roll{hline exch get show nl}for + jishdr { + /GothicBBB-Medium-83pv-RKSJ-H findfont 8 scalefont setfont + } { + /Helvetica findfont 8 scalefont setfont + } ifelse + 1 inch dup M + emsg1 0 get 0 ne{1 inch .75 inch M emsg1 show}if + emsg2 0 get 0 ne{1 inch .5 inch M emsg2 show}if +} bdf +% +/lline 0 def +/logme{ + (\tInterleaf::pl2ps 5.6.0\n)print + lline length dup dup + 5 gt {5 sub}{pop 0}ifelse + exch 1 sub -1 3 -1 roll{(\tInterleaf::)print lline exch get print(\n)print}for + flush +}bdf +% + /msg /print load def +/vck{ % stack => major minor sub + 3 copy + MAJOR ne exch MINOR ne or exch SUB ne or { + headerpage + 4 {nl} repeat + (Interleaf:: FATAL ERROR: pspro.ps and pl2ps versions do not agree.\n) + dup msg show nl + (Interleaf:: pspro.ps Version 5.6.0\n) dup msg show nl + (Interleaf:: pl2ps Version ) dup msg show + 3 {mesg cvs dup msg show (.) dup msg show} repeat + showpage + quit + } {3 npop} ifelse +}bdf +% +/el{ + matrix currentmatrix 8 1 roll + translate rotate scale 0 0 1 5 -2 roll arc setmatrix +}bdf +/addconic{ + matrix currentmatrix 9 1 roll + translate rotate scale + 0 0 1 6 -3 roll 1 eq{arc}{arcn}ifelse + setmatrix +}bdf +/dp{1 setlinejoin 1 setlinecap stroke}bdf +/ALIGN_NONE 0 def/ALIGN_OPEN 1 def/ALIGN_CLOSE 2 def +/PPWADJ [0 0 4 8 12 16 20]def +/MINSCALE .1 def +% +/plDict 7 dict ilput + /dist 0 def /y1 0 def /x1 0 def /ymoveto 0 def /xmoveto 0 def + /y2 0 def /x2 0 def +/plen{ + plDict begin + /dist 0 def + flattenpath + { + /y1 xdf/x1 xdf + /ymoveto y1 def/xmoveto x1 def + } + { + /y2 xdf/x2 xdf + /dist dist y2 y1 sub dup mul + x2 x1 sub dup mul add sqrt add def + /y1 y2 def/x1 x2 def + } + {} + { + /y2 ymoveto def/x2 xmoveto def + /dist dist y2 y1 sub dup mul + x2 x1 sub dup mul add sqrt add def + /y1 y2 def/x1 x2 def + } + pathforall dist + end +}ildef +% +/spDict 21 dict ilput + /style 0 def/width 0 def/pattern 0 def + /scaleup 0 def/indx 0 def/adj 0 def + /val 0 def/iszero 0 def/offset 0 def + /patternlen 0 def/n 0 def/extralen 0 def + /halfpatlen 0 def/scale1 0 def/scale2 0 def + /offset 0 def/firstdash 0 def/dashpct 0 def + /pathlen 0 def/x 0 def/y 0 def +/setpenpat{ + spDict begin + % + /patternlen 0 def/iszero 0 def + /style xdf/width xdf/pattern xdf + /scaleup DPIx 300 div def + /indx width 1 add scaleup div 4 div cvi def + indx 1 gt indx 7 lt and { + /adj PPWADJ indx get scaleup mul def + /indx 0 def + pattern { + /iszero indx 2 mod def iszero + 0 ne {adj add/val xdf} {/val xdf} ifelse + pattern indx val put /indx indx 1 add def + } forall + }if + % + /pathlen plen def + pattern{patternlen add/patternlen xdf}forall + style ALIGN_NONE eq{}if + % + style ALIGN_CLOSE eq{ + /n pathlen patternlen div cvi def + /extralen pathlen cvi patternlen cvi mod def + /halfpatlen patternlen 2 div def + extralen halfpatlen gt {/n n 1 add def} if + n 0 eq {/n 1 def} if + /scale1 pathlen n patternlen mul div def + scale1 MINSCALE gt{ + /indx 0 def + pattern{ + scale1 mul/val xdf + val 0 eq{/val 1 def}if + pattern indx val cvi put + /indx indx 1 add def + }forall + }if + /offset pattern 0 get 2 div round def + }if + % + style ALIGN_OPEN eq{ + /firstdash pattern 0 get def + /dashpct firstdash patternlen div def + /n pathlen patternlen div dashpct sub cvi def + /scale1 pathlen n dashpct add patternlen mul div def + /scale2 pathlen n dashpct add 1 add patternlen mul div def + /x scale2 1 sub abs def + /y scale1 1 sub abs def + x y lt{/scale1 scale2 def}if + scale1 MINSCALE gt{ + /indx 0 def + pattern{ + scale1 mul/val xdf + val 0 eq{/val 1 def}if + pattern indx val cvi put + /indx indx 1 add def + }forall + /offset 0 def + }if + }if + pattern offset setdash + end +}ildef +% +/hpos 0 def /vpos 0 def /sEnd 0 def +/msp 0 def /nsp 0 def /str 0 def +/s{ + /msp xdf/sEnd xdf/nsp xdf/vpos xdf/hpos xdf/str xdf + hpos vpos moveto + msp -1 ne + {sEnd hpos sub str stringwidth pop sub nsp div 0 msp str widthshow} + {str show} + ifelse +}bdf +% +/RL /rlineto ldf +/RM /rmoveto ldf +/RC /rcurveto ldf +/ptsz 0 def +/ec{ + /ptsz xdf/vpos xdf/hpos xdf + gsave + newpath hpos vpos moveto + ptsz DPIx 72 div mul 1000 div dup neg scale + 30 -110 RM 573 0 RL 0 873 RL -573 0 RL 0 -873 RL + 40 833 RM 493 0 RL 0 -793 RL -493 0 RL 0 793 RL + 194 -137 RM 94 0 RL 0 94 RL -94 0 RL 0 -94 RL + 10 -176 RM 0 -83 -162 -95 -162 -257 RC + 0 -119 109 -174 208 -174 RC 116 0 201 69 201 172 RC + 0 34 RL -83 0 RL 4 -63 -6 -148 -119 -148 RC + -74 0 -128 48 -128 121 RC 0 133 158 136 158 252 RC + 0 45 0 95 0 95 RC -75 0 RL 0 0 0 -52 0 -95 RC + closepath fill + grestore +}bdf +% +/ilr{BinaryMode{readstring}{readhexstring}ifelse}bdf +% +/dbsize 0 def/cf 0 def +/ccd[ + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0{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} + {t1_1}{t1_2}{3 t1}{4 t1}{5 t1}{6 t1}{7 t1}{8 t1} + {9 t1}{10 t1}{11 t1}{12 t1}{13 t1}{14 t1}{15 t1}{16 t1} + {t2_1}{t2_2}{3 t2}{4 t2}{5 t2}{6 t2}{7 t2}{8 t2} + {9 t2}{10 t2}{11 t2}{12 t2}{ditto}{rn}{raw} +]def +/t1tab[ + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 16#00 16#01 16#02 16#04 16#08 16#10 16#20 16#40 + 16#80 16#03 16#06 16#0c 16#18 16#30 16#60 16#c0 + 16#07 16#0e 16#1c 16#38 16#70 16#e0 16#0f 16#1e + 16#3c 16#78 16#f0 16#1f 16#3e 16#7c 16#f8 16#3f + 16#7e 16#fc 16#7f 16#fe 16#ff 16#a0 16#90 16#88 + 16#84 16#82 16#81 16#50 16#48 16#44 16#42 16#41 + 16#28 16#24 16#22 16#21 16#14 16#12 16#11 16#0a + 16#09 16#05 16#00 16#00 16#00 16#00 16#00 16#00 +]def +/rn{ + cf read pop 32 sub 6 bitshift cf read pop 32 sub or +}bdf +/t1_1{ + 2 copy 2 copy + get cf read pop t1tab exch get xor put 1 +}bdf +/t1_2{ + 2 copy 2 copy + get cf read pop t1tab exch get xor put 1 add + 2 copy 2 copy + get cf read pop t1tab exch get xor put 1 +}bdf +/t1{ + {2 copy 2 copy get cf read pop t1tab exch get xor put 1 add}repeat + 0 +}bdf +/s1 1 sdf +/t2_1{ + 2 copy 2 copy + get cf s1 readhexstring pop 0 get xor put 1 +}bdf +/t2_2{ + 2 copy 2 copy + get cf s1 readhexstring pop 0 get xor put 1 add + 2 copy 2 copy + get cf s1 readhexstring pop 0 get xor put 1 +}bdf +/t2{ + {2 copy 2 copy get cf s1 readhexstring pop 0 get xor put 1 add}repeat + 0 +}bdf +/ditto{ + dbsize +}bdf +/raw{ + 2 copy pop + cf exch readhexstring pop pop + dbsize +}bdf +/dl{ + dline 0 cf es readline pop + {ccd exch get exec add}forall pop + 0 dbsize getinterval +}bdf +/rhex {currentfile exch readhexstring pop} bdf +/neg1Set{ + 0 1 2 index length 1 sub {1 index exch 255 put} for + pop +}bdf +/screenSet{ + currentscreen + 3 index dup length 0 eq {pop} {exch pop} ifelse + exch + 4 index dup -1 eq {pop} {exch pop} ifelse + exch + 3 -1 roll + 5 index dup -1 eq {pop} {exch pop} ifelse + 3 1 roll + setscreen + 3 npop +}bdf +/tDict 9 dict ilput + /mapsz 0 def/tf 0 def + /wmap 0 def/bmap 0 def/gmap 0 def/rmap 0 def/clr 0 def +/trans { + tDict begin + /mapsz xdf/wmap xdf/bmap xdf/gmap xdf/rmap xdf/clr xdf + /tf {exch mapsz mul round cvi get} bdf + systemdict /setcolortransfer known clr and{ + rmap length 0 ne {{rmap tf}} {{}} ifelse + gmap length 0 ne {{gmap tf}} {{}} ifelse + bmap length 0 ne {{bmap tf}} {{}} ifelse + {} setcolortransfer + }{ + wmap length 0 ne { + [currenttransfer /exec load wmap /tf load /exec load] + cvx settransfer + } if + } ifelse + end +}ildef +/cDict 6 dict ilput + /sl 0 def/r 0 def/g 0 def/b 0 def/w 0 def +/clrimg{ + cDict begin + /sl xdf + /r sl sdf/g sl sdf/b sl sdf/w sl sdf + + systemdict /colorimage known { + {r rhex} {g rhex} {b rhex w rhex pop} true 3 colorimage + }{ + {r rhex pop g rhex pop b rhex pop w rhex} image + } ifelse + end +}ildef +/iDict 9 dict ilput + /dbsize 0 def/cf 0 def/msk 0 def/cmprs 0 def + /es 0 def/dline 0 def +/ilimg{ + iDict begin + /cmprs xdf/msk xdf/dbsize xdf + /dline dbsize sdf dline neg1Set + + msk 1 eq { + cmprs 1 eq { + /cf currentfile def/es dbsize sdf + {dl}imagemask + } + {{dline rhex} imagemask} ifelse + } + {{dline rhex} image} ifelse + end +}ildef +/blankImg{ + /dbsize xdf + /scanline dbsize sdf scanline neg1Set + {scanline}image +}def +% +/wmode 0 def/newencoding 0 def/newname 0 def +/ReEncode{ + /wmode xdf/newencoding xdf/newname xdf + findfont dup maxlength 1 add dict begin + { 1 index /FID ne + {def} {pop pop} ifelse + } forall + currentdict end + dup /FontName newname put + newencoding -1 ne {dup /Encoding newencoding put} if + wmode 1 eq wmode 2 eq or{dup /WMode 1 put}if + wmode 2 eq{dup /CDevProc {pop pop pop pop 0 exch -1000 exch 2 div 1000} put}if + newname exch definefont pop +} bdf +/charstr 0 def/encoding 0 def/i 0 def +/insertcharnum{ + /charstr 12 sdf + % + /encoding xdf/i xdf + (char)charstr copy pop + i istr cvs pop + charstr 4 3 string putinterval + encoding i charstr cvn put +}bdf +ILEncoding 0[ +/Aacute/Acircumflex/Adieresis/Agrave/Aring/Atilde/Ccedilla/Eacute +/Ecircumflex/Edieresis/Egrave/Iacute/Icircumflex/Idieresis/Igrave/Ntilde +/Oacute/Ocircumflex/Odieresis/Ograve/Otilde/Scaron/Uacute/Ucircumflex +/Udieresis/Ugrave/Ydieresis/Zcaron/char28/char29/char30/char31 +/space/exclam/quotedbl/numbersign/dollar/percent/ampersand/quoteright +/parenleft/parenright/asterisk/plus/comma/hyphen/period/slash +/zero/one/two/three/four/five/six/seven +/eight/nine/colon/semicolon/less/equal/greater/question +/at/A/B/C/D/E/F/G +/H/I/J/K/L/M/N/O +/P/Q/R/S/T/U/V/W +/X/Y/Z/bracketleft/backslash/bracketright/asciicircum/underscore +/quoteleft/a/b/c/d/e/f/g +/h/i/j/k/l/m/n/o +/p/q/r/s/t/u/v/w +/x/y/z/braceleft/bar/braceright/asciitilde/quotedblleft +/aacute/acircumflex/adieresis/agrave/aring/atilde/ccedilla/eacute +/ecircumflex/edieresis/egrave/iacute/icircumflex/idieresis/igrave/ntilde +/oacute/ocircumflex/odieresis/ograve/otilde/scaron/uacute/ucircumflex +/udieresis/ugrave/ydieresis/zcaron/char156/char157/char158/char159 +/char160/exclamdown/cent/sterling/fraction/yen/florin/section +/currency/quotesingle/quotedblleft/guillemotleft/guilsinglleft/guilsinglright/fi/fl +/char176/endash/dagger/daggerdbl/periodcentered/char181/paragraph/bullet +/quotesinglbase/quotedblbase/quotedblright/guillemotright/ellipsis/perthousand/char190/questiondown +/char192/grave/acute/circumflex/tilde/macron/breve/dotaccent +/dieresis/char201/ring/cedilla/char204/hungarumlaut/ogonek/caron +/emdash/char209/char210/char211/char212/char213/char214/char215 +/char216/char217/char218/char219/char220/char221/char222/char223 +/char224/AE/char226/ordfeminine/char228/char229/char230/char231 +/Lslash/Oslash/OE/ordmasculine/char236/char237/char238/char239 +/char240/ae/char242/char243/char244/dotlessi/char246/char247 +/lslash/oslash/oe/germandbls/char252/char253/char254/char255 +]putinterval +ILSymBEnc 32[ +/space/logicalor/arrowright/arrowdblleft/arrowdblup +/arrowdblright/lozenge/arrowhorizex/angleleft/registersans +/Upsilon1/plusminus/second/angle/greaterequal +/radical/ellipsis/Ifraktur/spade/lessequal +/minute/degree/fraction/florin/infinity +/approxequal/integral/propersuperset/parenrightbt/arrowup +/bracketrighttp/aleph/arrowdblboth/bracerightbt/integralbt +/notsubset/bracketleftbt/trademarksans/bracelefttp/braceleftmid +/braceleftbt/bracketlefttp/braceex/apple/angleright +/parenrightex/parenrighttp/arrowdown/divide/element +/summation/bracketleftex/parenlefttp/parenleftbt/dotmath +/copyrightsans/integralex/parenleftex/integraltp/registerserif +/intersection/trademarkserif/arrowdbldown/gradient/logicalnot +/reflexsubset/equivalence/propersubset/partialdiff/arrowboth +/circlemultiply/heart/bracketrightex/bracerightmid/emptyset +/bracketrightbt/Rfraktur/proportional/reflexsuperset/carriagereturn +/notequal/notelement/diamond/club/bracerighttp +/arrowleft/weierstrass/bullet/circleplus/multiply +/arrowvertex/copyrightserif/union/product/logicaland +]putinterval +0 1 32{ILSymBEnc insertcharnum}for +127 1 255{ILSymBEnc insertcharnum}for +ILDingbats 0[ +/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef +/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef +/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef +/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef +/space/a1/a2/a202/a3/a4/a5/a119 +/a118/a117/a11/a12/a13/a14/a15/a16 +/a105/a17/a18/a19/a20/a21/a22/a23 +/a24/a25/a26/a27/a28/a6/a7/a8 +/a9/a10/a29/a30/a31/a32/a33/a34 +/a35/a36/a37/a38/a39/a40/a41/a42 +/a43/a44/a45/a46/a47/a48/a49/a50 +/a51/a52/a53/a54/a55/a56/a57/a58 +/a59/a60/a61/a62/a63/a64/a65/a66 +/a67/a68/a69/a70/a71/a72/a73/a74 +/a203/a75/a204/a76/a77/a78/a79/a81 +/a82/a83/a84/a97/a98/a99/a100/.notdef +/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef +/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef +/.notdef/.notdef/.notdef/a205/a206/a85/a86/a87 +/a88/a89/a90/a91/a92/a93/a94/a95 +/a96/a101/a102/a103/a104/a106/a107/a108 +/a112/a111/a110/a109/a120/a121/a122/a123 +/a124/a125/a126/a127/a128/a129/a130/a131 +/a132/a133/a134/a135/a136/a137/a138/a139 +/a140/a141/a142/a143/a144/a145/a146/a147 +/a148/a149/a150/a151/a152/a153/a154/a155 +/a156/a157/a158/a159/a160/a161/a163/a164 +/a196/a165/a192/a166/a167/a168/a169/a170 +/a171/a172/a173/a162/a174/a175/a176/a177 +/a178/a179/a193/a180/a199/a181/a200/a182 +/.notdef/a201/a183/a184/a197/a185/a194/a198 +/a186/a195/a187/a188/a189/a190/a191/.notdef]putinterval +% +/newFont +{ + findfont imatrix makefont + exch DPIx 72 div mul scalefont +} bdf +/wmode 0 def/encoding 0 def/ILfont 0 def/PSfont 0 def/ptsize 0 def +/declareNFont{ + /wmode xdf/encoding xdf/ILfont xdf/PSfont xdf/ptsize xdf + FontDirectory ILfont known false eq{PSfont ILfont encoding wmode ReEncode}if + ptsize ILfont newFont +}bdf +/declareRFont{ % stack => Printerleaf Font Name + PSfontobj exch 2 copy dup 10 dict dup begin + /FontType 3 def + /FontMatrix[DPIx 300 div 0 0 DPIy 300 div 0 0]def + /FontBBox[0 0 0 0]def + /Encoding ILEncoding def + /BuildChar{ + 0 begin + /char xdf + /fontdict xdf + /charname fontdict/Encoding get char get def + /charinfo fontdict/CharData get charname get def + /wx charinfo 0 get def + charinfo 0 get BOGUSWIDTH eq + {puterrchar} + { + /charbbox charinfo 1 4 getinterval def + wx 0 charbbox aload pop setcachedevice + charinfo 5 get charinfo 6 get true + fontdict/imagemaskmatrix get + dup 5 charinfo 8 get put + dup 4 charinfo 7 get put + charinfo 9 get + imagemask + } + ifelse + end + }def + /BuildChar load 0 7 dict put + /imagemaskmatrix[1 0 0 1 0 0]def + /CharData MAXCHARS dict def + end + definefont put get + /CharData get/space[16 0 0 1 1 16 1 0 0[<00>]cvx]put +}def +% +/egDict 3 dict ilput + /chnum 0 def/font 0 def/w 0 def +/numLoadEmptyGlyph{ + egDict begin + /chnum xdf/font xdf/w xdf + w font PSfontobj font get/Encoding get chnum get + LoadEmptyGlyph + end +}ildef +/puterrchar{ + PSfontobj errfontname get dup + /BuildChar get errcharno exch exec + (\tInterleaf::out of VM loading bitmap(?). Try breaking up document\n) + dup print flush + emsg1 copy pop +}def +/QUIT{ + (\tInterleaf::completely out of memory. \n\tTry breaking up the document \n) + dup print flush + emsg2 copy pop stop +}def +/lgDict 15 dict ilput + /charno 0 def/fontname 0 def/height 0 def/width 0 def + /hsize 0 def/nbytes 0 def/glyph 0 def/tx 0 def/ty 0 def/lly 0 def + /llx 0 def/urx 0 def/lsb 0 def/glyph 0 def/NoVMHead 0 def +/LoadGlyph{ + lgDict begin + % + /charno xdf/fontname xdf/height xdf/vadj xdf/width xdf/hsize xdf/lsb xdf + /NoVMHead vmstatus exch sub exch pop dup + VMHEAD 2 idiv lt{QUIT}if + VMHEAD lt{true}{false}ifelse def + /nbytes hsize 15 add 16 idiv 2 mul height mul def + NoVMHead not{/glyph nbytes sdf}if + currentfile NoVMHead {trashheap 0 nbytes getinterval}{glyph}ifelse + readhexstring 2 npop + /hsize hsize 15 add 16 idiv 16 mul def + /lly height vadj add def + /urx hsize lsb add def + /tx lsb neg def + /ty vadj neg def + PSfontobj fontname get dup /Encoding get charno get + exch /CharData get exch + NoVMHead {[BOGUSWIDTH]} + {[width lsb lly urx vadj hsize height tx ty[glyph]cvx]}ifelse + put end +}ildef +% + /scfrq 0 def/scang 0 def +/solidFill{ + /scfrq xdf/scang xdf/scproc xdf + gsave + scfrq -1 ne scang -1 ne or /scproc load length 0 ne or{ + scfrq scang /scproc load screenSet + }if + eofill + grestore +}bdf + /patchar 0 def/pffontname 0 def + /fillpatset {/patchar xdf/pffontname xdf} def + /patstr 1 sdf +/patternFill{ + /scfrq xdf/scang xdf/scproc xdf + gsave + scfrq -1 ne scang -1 ne or /scproc load length 0 ne or{ + scfrq scang /scproc load screenSet + }if + currentfont PSfontobj pffontname get setfont pFill + dup null ne{setfont}{pop}ifelse + grestore +}bdf +/pfDict 7 dict ilput + /paty 0 def/patx 0 def/#chars 0 def + /ry 0 def/rx 0 def/ly 0 def/lx 0 def +/pFill{ + pfDict begin + gsave 1 1 1 setrgbcolor eofill grestore + % setup factors + patstr 0 patchar put + patstr stringwidth pop + /paty exch def/patx paty def + % setup region + eoclip + pathbbox + /ry exch floor def + /rx exch floor def + /ly exch ceiling cvi + dup 0 lt{paty sub}if cvi + dup paty ceiling cvi mod sub def + /lx exch ceiling cvi + dup 0 lt{patx sub}if cvi + dup patx ceiling cvi mod sub def + /ry ry paty add def + /ly ly paty sub def + newpath + % blastchars + /#chars rx lx sub patx div ceiling cvi def + ly paty ry{lx exch M #chars{patstr show}repeat}for + newpath + end +}ildef +% +/BeginEpsf{ + /ILB4Epsf save def + /clp{newpath moveto lineto lineto lineto closepath clip} def + /ILDictCnt countdictstack def + /ILOpCnt count 1 sub def + 0 setgray 0 setlinecap + 1 setlinewidth 0 setlinejoin + 10 setmiterlimit [] 0 setdash newpath + /showpage {} def +}def +/EndEpsf{ + count ILOpCnt sub {pop} repeat + countdictstack ILDictCnt sub {end} repeat + ILB4Epsf restore +}def +% +/clp{newpath M L L L closepath clip}bdf +% + /cm 0 def/pgw 0 def/pgl 0 def/cn 0 def/pw 0 def + /pw2 0 def/lnx 0 def/lny 0 def +/cropdefs[ +{} % 0 +{ % 1 + 0 0 M lnx neg 0 L + 0 0 M 0 lny neg L +} +{ % 2 + 0 0 M lnx 0 L + 0 0 M 0 lny L +} +{ % 3 + lnx .25 mul neg 0 M lnx neg 0 L + 0 lny .25 mul neg M 0 lny neg L +} +{ % 4 + lnx .25 mul 0 M lnx 0 L + 0 lny .25 mul M 0 lny L +} +{ % 5 + lnx neg 0 M lnx 0 L + 0 lny neg M 0 lny L +} +{ % 6 + [lnx .75 mul lnx .50 mul]0 setdash + lnx neg 0 M lnx 0 L 0 lny neg M 0 lny L +} +{ % 7 + cn 1 eq cn 3 eq or {90 rotate}if + 0 0 M lnx neg 0 L + 0 lny M 0 lny neg L + cn 1 eq cn 3 eq or {90 neg rotate}if + /cn cn 1 add def +} +]def +/cutmarks{ %stack: pglen pgwid cmtype => --- + 0 SSG [] 0 setdash + /cm xdf/pgwid xdf/pglen xdf + /pw DPIx 80 div def/pw2 pw 2 div def + /lnx DPIx 4 div def/lny DPIy 4 div def + pw LW + /cn 0 def newpath + % upper left corner + pw2 neg pw2 neg translate + cropdefs cm get exec + % upper right corner + pgwid pw add 0 translate + 90 rotate cropdefs cm get exec 90 neg rotate + % lower right corner + 0 pglen pw add translate + 180 rotate cropdefs cm get exec 180 neg rotate + % lower left corner + pgwid pw add neg 0 translate + 270 rotate cropdefs cm get exec 270 neg rotate + dp +}bdf +/bop {/pgstate save def} bdf +/eop {pgstate restore showpage} bdf +/ndf +{ + 1 index where {pop pop pop} {dup xcheck {bind} if def} ifelse +} bdf +/setcmykcolor +{ + 4 copy pop add add + 0 eq + {1 sub neg setgray 3 npop} + { + 1 sub 4 1 roll + 3 { + 3 index add neg dup 0 lt {pop 0} if + 3 1 roll + } repeat + setrgbcolor pop + } + ifelse +} ndf +/packedarray +{ + array astore readonly +} ndf +/findcmykcustomcolor +{ + 5 packedarray +} ndf +/setcustomcolor +{ + exch + aload pop pop + 4 {4 index mul 4 1 roll} repeat + 5 -1 roll pop + setcmykcolor +} ndf +/setseparationgray {setgray} ndf +/SSG {setseparationgray} def +/FC {findcmykcustomcolor def} bdf +/CC {setcustomcolor} def +/ilfeatend{ + stopped cleartomark CD exch sub dup + 0 gt {{end} repeat} {pop} ifelse +}bdf +end +%%EndProlog +%%BeginSetup +Ileaf_6.0.0 /initialize get exec +0 0 6 vck +%%IncludeFeature: *ManualFeed True +%%IncludeFeature: *PageRegion Letter +%%IncludeFeature: *Duplex None +%%EndSetup +%%Page: (1) 1 +%%PageResources: (atend) +%%PageProcessColors: (atend) +%%PageCustomColors: (atend) +%%BeginPageSetup +bop +%Defining font PSOwstdutchb +%!FontType1-1.0: PSOwstdutchb +10 dict begin +/FontName /PSOwstdutchb def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001000 0 0 0.001000 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 1 /C0032 put +dup 2 /C0044 put +dup 3 /C0045 put +dup 4 /C0046 put +dup 5 /C0049 put +dup 6 /C0050 put +dup 7 /C0053 put +dup 8 /C0054 put +dup 9 /C0057 put +dup 10 /C0058 put +dup 11 /C0065 put +dup 12 /C0066 put +dup 13 /C0067 put +dup 14 /C0068 put +dup 15 /C0070 put +dup 16 /C0072 put +dup 17 /C0073 put +dup 18 /C0078 put +dup 19 /C0080 put +dup 20 /C0082 put +dup 21 /C0097 put +dup 22 /C0098 put +dup 23 /C0099 put +dup 24 /C0100 put +dup 25 /C0101 put +dup 26 /C0102 put +dup 27 /C0104 put +dup 28 /C0105 put +dup 29 /C0107 put +dup 30 /C0108 put +dup 31 /C0109 put +dup 32 /C0110 put +dup 33 /C0111 put +dup 34 /C0112 put +dup 35 /C0114 put +dup 36 /C0115 put +dup 37 /C0116 put +dup 38 /C0117 put +dup 39 /C0118 put +dup 40 /C0119 put +dup 41 /C0121 put +readonly def +/FontBBox [-16 -209 798 694] readonly def +currentdict end +currentfile eexec +D9D66F633B846A989B9974B0179FC6CC445BC7C8A959A39A32E9DCE7FAEF17EE3BEC9F +50E1A6FCA651FC4B3769A0A91041557502E25A5D6180FE25A3D11BF079E1DF66E54EE9B7C229AF891739707A2A0EC140306B5E43E52B79BFB89E459E50 +6EC6F610A70775A31C460976C4F79449D86E57ACE491E5C6BF20CC4307B1DAF7630252 +E9AF8CFB69B50EDAE9D36A6104AFEF8832F920FD2346B2C7104CD11E3BEE999CFA9F5A +49DB3173EE48D1C82994237F360407B022E0B4 +502E94EA8B493651EF2D03F0B513D655047568325B512AE6 +6AC6F53F3848CF70DE25481CC65D8B1A5793AA +3C4282D111112BEE28AFCA7A3808D4444C4669CA +84EAAAF989219F51AB3476A1B0B5F2246BC306E6 +625C6679C417ED2A8E9BD010DE37D40265074C268420EA157C62583FAA018F369F10C267E5A689 +14B3CF05D7E3E7301A1D113C +B87969B0B7A33DFDE5 +61041C8A +79E0C55F075199031370610430 +0D19993C66A904E0A393097C33E2B533C751B03DB292D3F16A37AEE640B3CB8F7D47F2E44B2ABFB4C83CFE179622890516BEC9EC41E287FAB18F +46752A98 +B524197F79749498F1B81B499E +5B173784DF8DA9E453CD0839B33BA0D67E613FCB416EEE +9A51DA49 +4646622F22B13473EBDF96A0DA +8A349322E8D94CD0E91C99EA0C3BC09462899C6BDDE61874BCDB50101C49F1 +E1743DDB +AA28EA75BD57850EA9D937150B +85ACF426E34B3183131BC979DB458E0EBAAB66D7F5CEC82005F3EE4DB4BABCBA207EE2F466925562FDBCA112942CD36FA5390091E872502364E19BF7 +EB242AAF +39D8F4BFAE6EA27F8AC7A1AEE0 +A56BE808C10F17EB6B5D91B5695DEB6ED22DD16F2574D72935E5EC7C7575C6B182265968DA8EB6DA68C0BABFFD6F48F334792ACE62EC353A1D4E6DD37BBEF2AEC2E79F31E1F9BCC9F1A33AE39EAF26DB49D5A601 +4AC21A61 +30AE391F2BE80CBCFE383A1FF8 +8A692FD09F448C9C5F4B03B6065E06AD0FFDA68FFDC619AFAA3B0F9CC10CA085709F8BB2E0D21D20413929003D8477143562ABA4DFBF6A333A34E870017DEABEB0766CF0F1F790312030121B75B0971AC653B5B0F058 +4EB1686C +442AE58C59831E753FA85AA04683 +23052D12A3C2410F588D51311D615774EFBC826AFD52DECFB2F903DD90EE28E43D87002B3BDB36C47A6B0C54CEE9A8D7C45CDDB50D8FD4F6356B06F528815838D2306DCD035AC49687685AB64A2F795D67F85862D716DC44A9AFBB9DC1CBBA029AB60318 +982A8B1B +D2FFBB02FD01173E5CD80E37570A +1CCF168699188F4C6EB598A4E1C1BC88062227672A089BB6E757698D44389F9A62F8A7A884348A3C9914F5778D1C1D8C452A326093A90FB4D3B1C4D35833F54B5FB0ECC6CD82DF7F4DBC97BB882BCF21368FC9B4B7D2CFEDA9A08D7B28E0717ECA3B2230 +42CE9CDA +A2BE47BBFC4FCF37EE8FE6D2DC +18EB4C0275F35929C2D50769FB6302CA7361DB4EB79376DA9232C2FDAAA3AD90213C23EA5BE7DCB51998AAD022D9B5F1D517960F9471 +1BDB3D4F +5A1E7EC34294EB573CCDEFB149CB +67410C30B42FEE86F6FACB036772521273A839D8802D2D75F9E33F9F4A0CC24C34E7253170E428828BB551EA9A25134702A47F849E2A0B4A3D439252EF5141F427027B79CD248B7EE41A8C106EEF5DE3BE596CCBB90B3B189AB35DDEB3542AC6A753EFB538FE79D745E342 +B12150C6 +88EC9208F2E40CE65B143031D964 +DA80934B50EB86975F0FB517161F3C6FB6371E9C7BCBC091BB417DFB5DC2E2C561131401430DEB8372E3DC7681765C50395636060E28722935D6DE8376F935757FF5B88CE250528CA3DDE197E49BBDD3A1997A980B0A8D04FCEE14A978656DC771F044152589E04E00761146896D0C3FB2882DB81C62E00903D0 +48665C99 +DD79A2AC894FFD47B73A8DDE1813 +A84E326E8D6997E4B75BA00815A988B7C067B945E0EE8B89A5308013EBD51B5DF8C9976FFB253A48ED42E03B23DD495508986176AEF41381C398B70A60642CB37DA8F96A0D7C1C2B41746CAE243937783234C2D0497E7C95A0A4D9AFA732A28EF44B208151469458 +C41094FB +F639F26659F56EB2E0244B800E +A15AF8C1C16150BE6CE7DBC0BEBD67767480748ACA150A7BBF822D77C4917E55EB5C9A7497A92203946F1E28A554C0A722F13219C27E8D30FEBFF24D8E5467D1C36F08F1A39326CDD93356DB6EA380C42C2C52D0FE6021 +0123DEC9 +B8EDF943F72513AF92A015AC5D6B +5F8B5A14A9CE63EFB0EE1BFED91DB21AC9C69B44D3D0DCAE6BC8805234449191EC643A340102B404311119BEEC5263717A5057D58367A740BA188DC0AB2EA96C4640AFFDBD3A6C59A4AD78045E1CBCCC7D867A0A0597968A211189CD5C149ACFCF281DEE +0850472B +81C5FA1AEEF723927B57179C5C3F +2FA8A9D8ED480A23883579198DEC83FB49C110F3AC157B61FEC86E311E6E0539931518434A54D0736D9CAFD4A07A04ABFE47B57BF5334D6167E8BC6BD6E13775DCFA2D1DCA3769F7BD4D5538793338E000EB497ECF83DED1C764AEA9884135D90203BF1C41E74AF2873A6B723455214F3FDAFAE8B47985 +5E90CAE2 +89753CAB2B3D6ABEDE6085CF2D +85B1CE6F86551DF6306F05FB872BF842A438C03F16A8B7D5E8C641B1639DC4115BED40DDE0DE13FA9D1BA8F95589ED9581CA0CF91DD99D38A0264ADBC6A7 +D788C389 +E0113D3B2BE229D6EF51985E86 +9E1187E763DA4A7F760A8C9F02CB06029A805B2A2FBAAC660E946BCEEB17345175D3037509C381FB232404636C698931B292233B859F73641232843827B341A6A57105FB6B7977D3B3BBD7D876334B5711599345F771E06DB9E255DC1343C3 +FAC063CE +5F3300BB595DEAB80C4842870603 +D2AD96126332E1B474B3B6E6314724924E2A182AE1BFC657C3A76312530AB7558E40586340A1CBAC9BF1B22B8293F889041ED56532B6EB112D0CA49FE74DFEE75D49E08A9AB48C7AC96D4C361AA7822F7EAF125561C8108710DDC7BE50576FF2BB044809 +E476682F +354947D8E327F80099E5D53AB056 +B9EAE669C433E962051CF401A9720E64BAB32C526D0FA290959551A8B7736DC2D162A82EBEDB18460E29EC6AE52B600284377236AC6BE1B427068AE23442019D5227942A14EC99E1C0942965F24CA06172962BEDF6B0BD51FFE53DCC2C26FD817855A3B51832495B914BCABB563E526DC0002AE2E2 +14D4066F +BC0200488F7D3714CEBC740FC4EB +A1C8499D93A6BDBFDD35DBE8E0CF96DDAA8C602EC67F69FCF7AAA78276F1205E4C3BCD4A596CEB41EC06F170C20364CABF269F193326EFABD05E8B75EDC4F76F1FCAE99AEFFE428300BEF6194C0F51B3F532112796E32942F0BE538E9A3FC16A036E7C31FD28322B3E0E9F0C609ADC00CC6D01554A8248FF6FB7C2A31DF6 +8717 +B150A02F +4B633E85 +91B7A203AB175DFBA1A815B739 +88E6499894235763247279C794D0C3253DF46D1304D36F5A3D72793D3F7A1FD6D57B038D7512E6A01EB625DBDBB846FE812056E54CEB42897219BC87C7BBDC9D4FB7A168704F3F7C539209BC8A60F85B78CFCC97543063595308CEC86140 +742E2397 +2504277105808A1FC4E56A3AA4 +2584181D7982B00E04E0D30FA1ACE8DB1D8F211FF06C6A6F344195AD874B32ABDDC6325EDE3680E4BDF4CC1777993EC2768355D89128452F5CFDDD07C9DCCDCF3D123A82E8A36FAC6ACCA651BC7F9CBE10B4 +0FAC9830 +8487361AD3AE2B86B8AEB47E1194 +13DD95565C3B6D7755DC03905D9DC58935B2D1AA4B18292E915DAFA471E15803F583646B00E401EB147F195AFC9EE37EDD5472D6CD00E37834CFB826AD0AD9FD79EE2F8A79CF6266F9338184E1B64E5FBFA469D7FFCDF4D038AE2549BC170C726B741BFBAB13EDCA511667D7 +EF79B296 +5F4F9C3DD461DFB521702A7FF9 +EE61B06EF2F5C9571F6D296019D2F88B8C064F36A72758FBE0B572DDD4D0D0F73C1B2D3673C90AA3F9C19F2013060BB61E1242FFB08EE9EFFD6BFD98DEBDFA4DFCCD4CCF7B5AAE247BF215A6C44B47CB6AC6180A322BE0F10923EB6F +87F7295B +65A89C92B661E31F50D4D32497 +12471E850AFED8660E5CF4E24FDE6E94C10352AFE8AA1B06D9866A54E1E7AAE7063A3A015FB37D2826634B3CCB0CA2DB8CFE3F7BF47DCD181A1170E344E1BBE34CEF9777940C1EF5BC4A1A488344DBB0ABC79A604A52000AB05EF075FE +3B5B77F9 +D7B3A48B7BF18AB4FA4C3D2A68B2 +366102AB003CE4E8C42757183727E114C85825E1EB79397E1FDA84FEE5915B148CE9EE5F97DDE93B40B38C3B2630FA7BB016BD0B53C5A6B2621BD34F2E22739DF22CB78BA3475A1672074E9A77624D8C2FD5AAD24CE110571D86C3985D1BCC330C05BB9763A408BD +8ADD0311 +2AEBBFA7ADEC853154E8576E72 +A81865705DEF380C9419F11D7513A35F79132BF2BDCE18CFEF5232B24A4ACC80FC43EA6E44EC03E7AFECC474781CD127EB7A87DBC53C2D81C29A8D8C022425760B2BF11C9EAE86E938AC8D45E02C +DC6F9193 +35C629032ABF89CB22349EB99970 +7A229E2E68F92DC55D27C7B45E61B500740A14CA1D71204EBCFAF918E51F0A78EA9CD90B884DD52530C36D2DE3E320AC7044AF8578E00C32EE0D7A568332B5BCB57D541E43D1CD58944010DF89C10F9D869397ACD1E4667E79907D78CB7994F7117CFDA2B8C4141025112FF2802DBA3120EF9D0DBFF7447DE2D584557D49 +F2A4 +0E3D +69E47849 +BA945735613CBFF1E6916E6B55 +5B31670CDDE45AA7F7D4E39D1919480719729CEA6BC3AC682A58115FA2E77BA6BAD1E9004597313AE9E7DF6E921771459913B0AA +9F4F92F4 +996C5EE766F11D04B1A195D80866 +2B7F771BA5C2A7B2D95DC29D79416A6E9CEDB0A22BF4515C23ABFB0F876071A862BC2BD887C5CEED12DC19EBCEA0BB004B29B893EBBECEA6A95DD0E5577A4593ACB0AA30A661E7054F28289235F0E792B7D20E96F2CBFE13002FEECE567A683CB96BDCC5613703CBFC7B3BCF174F11B413B4DA7CBE5F89B210A2213CC4EB +300C +DBE40BF16FF1A255A7D566420C653291A4C76E1FC9F923B5FC86ADEC +2F3A7122 +1B29A400BAA243C94285AB1D2D1A +624F58B32F57204A2982B1AB376D067ED6A0F13CFD2BCC06E5BB254AD9B6A29484481F5762677435A7BAB00216AD461A60E1445A5E3C447A794140E16C1525D03F27225186962639E833BBA7E332681378A43A3412915F466B49DDE87C3357FF23C09A597D8F00 +289CCCB7 +60C3AF62A8001A844B0ECADFAE +F80EC2B6BB8D16BEC1D957BEF8B8A200EE9C9B821AC12F58943B02C54C9EFCA6A6F6F935D15E60628D271B98885A44B79D2CB4325D16FDD325BEDAA9DB6A462AC1C6A5302695 +15E6A156 +89F1D0E355B17B3F652C89794FD5 +37D7AC870BB9C09978D42D533E594CB0F123F251D1E2586345ABD4C010C6C59319960C8E12D274052E5398D396532DF9222A90AF8C9E29CE881C7164D4B38B36C52D1F5D0869A99B103DD1CA36147D697A77ADC0E9C9F919DEA180A8849DF3F70A96C1077D83224B38C12857EE3970C3F7 +06DE4EF3 +F465EED40C0C0CCEEBC159A8AD +8558F0492B1AC84CE21B091E7E32904F00B81B366E97E7FC6E91016C6D3CD26E481F31A82D9A0EBD8B2A3ABDE994DC6A23098C91DD1C18636C7E95399EF7EFD10A53D04E80B5902C1A573AAB5E9BDEB5B8B7D9DAD52C223026 +9BFB743A +BA3CA234003C97BD2DB5E68400C6 +706D29DFC0D52384C291BD16897A484B1E6C10854C2D823A86EF031BA4008C7E65BAB6A2C70662622E820588619F497A5DC5CF002BCB71D3A1D875716545E47AB6499402D187EF081F54EA2B23049AFCC17CB9E031562B014E2C49B89214F5F6465D4E10B088D3D45B32ACA3B39717D90B3CF471016A36F3DC +9C7E7F7B +E4F378F7FEDBAAC5F504E24C58 +2927E6F423AD7066015A7316EDF0AED5726167B66D5CFD163F92394FA87EF377F3C29664268C3A5C5581E81E6634EEEE664A8475ADBE5984B8CECA69A178669714801ECD +42CC67DB +EED13891C79E497B9C46CD383D +3857F11C59A14DBEAD3763749904F4AC91C5E5DD47C12EDEBEE214896E903990D3E15F91C1BBE10DBFC4247E4B0DBB0134026E74C82A724739AC15A95A4A3DA76B76B22B11B014E3CC5F39BD32F09D02C0C9AF4B4055AC14C22B49 +3AB2453E +1061A11BAD86521446C7DE5F26 +AB8FC019DD681306EE5B3D94474F5374C68A12D01767E132CBD869777B37DFCE4542B0E894B9AD7226421073CABC9CBCA562451DBA9A878F8810DAE3C7AABE1DD5D048003D1CDECBDB1BC1F404859A02B548F3C508CB3891CA1E9CE0 +AC9B3C9C +9AD01AFD3ADB2E452755D3409002 +CAE1C9042906014A4A57F1F48804301628CE167F0285B0B594B205D476598468406C5A4510F0478F075336FEBE85B9806B32DF35F2B11CEBF0729638BED415302B546457E5BB2A4B3BF5512E6133A26206C38DDEEA6E2E05F1C6B564DD023603F2A13182392E89055D90326E4CA0BAF089A046F72B9ED7681638AFAF4FE9 +4A12 +92FE42AFB7351C119DC064 +8DD0F16D +2392EBB1920FF41778E2965DD763 +1276D516D835D9AEABF98F48ED7A58A6279CBB0D631820537BA12BDCD73F481A35A1DE134C48C7D7A72AE240ACE9898E76238D8D4294932152B9F7174D76D515DF659048878347E80FE826FE8C1FD90B24F9B3EAC4DECD1F744227FCEA13ADA7F396F578CEB8831EDB781BCA22229594EC4C0C181C47A8E531D478115D17 +44B2 +89 +669EBD9B +12B8B755F70FD71F39567963E6EC +917BC6FEA7CEE964 +5DC7CE2D +ECF2B5B56033167CBDD13C88EA603E6B84DA24D9D20CADC8E60AA4BA8CEACC298EC0 +4BA8A338E8B53AD6C97F3738EF95B84C93F32370D35FDB18134C0CD8A8F9A7C517F3005ED4E8 +D54432A79CC4C0E393E2E7C3B99FB91DB69A84C63DC4AAFEA193C4 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +%Defining font PSOwstdutchbi +%!FontType1-1.0: PSOwstdutchbi +10 dict begin +/FontName /PSOwstdutchbi def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001000 0 0 0.001000 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 1 /C0063 put +readonly def +/FontBBox [84 -13 471 683] readonly def +currentdict end +currentfile eexec +D9D66F633B846A989B9974B0179FC6CC445BC7C8A959A39A32E9DCE7FAEF17EE3BEC9F +50E1A6FCA651FC4B3769A0A91041557502E25A5D6180FE25A3D11BF079E1DF66E54EE9B7C229AF891739707A2A0EC140306B5E43E52B79BFB89E459E50 +6EC6F610A70775A31C460976C4F79449D86E57ACE491E5C6BF20CC4307B1DAF7630252 +E9AF8CFB69B50EDAE9D36A6104AFEF8832F920FD2346B2C7104CD11E3BEE999CFA9F5A +49DB3173EE48D1C82994237F360407B022E0B4 +502E94EA8B493651EF2D03F0B513D655047568325B512AE6 +6AC6F53F3848CF70DE25481CC65D8B1A5793AA +3C4282D111112BEE28AFCA7A3808D4444C4669CA +84EAAAF989219F51AB3476A1B0B5F2246BC306E6 +625C6679C417ED2A8E9BD010DE37D40265074C2684268F16195489648993B9C4D3B534FA887C +DEF605FA87B3FBAEC826AC7E1E20 +250E3AABDDA9ADD30F86E07417D415A5C5F3C75B2D0826BEB6F3013607ED8A663020839C9041F4F7C7978EA3451C0F83A22A59A183D3AB0AB9DC1DDF375217A89B7556A556E7C8BD6ED64D3E9B19FEFA6DBF2A8B1D7A4AD1AB7A6DF880F7EFB3E5DF4C13A66BAC11 +56DC59CC +EEC84A45D81614AC1B97B8A2F81D +9A9D3BAAF1FB2118 +EC0D2C7E +1A1D607B828FA12B6EF68C7EB5615F934707CA5B4619FE8DFF0D37E3550CECFC8A2C +F8F223E46E11C8A14D58AD13906E8985616C0BD911D6B23DE6DC29D4D5DBD4B6A61956586E84 +5D5E25A2F6811872DC86C238C92A7EFF1905D6DD6B55F980F95573 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +/DPIx 1270 def /DPIy 1270 def +72 DPIx div 72 DPIy div neg scale +0 -13970 translate +1.00 1.00 scale +/wst:dutch24b 24.00 /PSOwstdutchb newFont def +/wst:dutch18b 18.00 /PSOwstdutchb newFont def +/wst:dutch72bi 72.00 /PSOwstdutchbi newFont def +%%EndPageSetup +GS +0 13978 10801 13978 10801 0 0 0 clp +wst:dutch24b SF +0.00 0.00 0.00 1.00 setcmykcolor +<1219252219231a0a> 4639 2965 0 6139 -1 s +wst:dutch18b SF +<0b011219252821231d0113> 2922 3473 0 4642 -1 s +<19231a21231f15201719010c1920171b1f15231d> 4631 3473 0 7853 -1 s +<11201a21231f15251c2120011219252821231d24010e1c271c241c2120> 3261 5625 0 7514 -1 s +<1019281e1925250313> 3473 5930 0 4984 -1 s +<15171d152318010d211f22152029> 4973 5930 0 7303 -1 s +<0f> 4166 6235 0 4357 -1 s +<191623> 4343 6235 0 4792 -1 s +<26152329010507020105090908> 4798 6235 0 6610 -1 s +N +53 LW +[] 0 SD +0.00 0.00 0.00 0.00 setcmykcolor +122.0340 -39.8126 0 531.6085 531.6120 39.8476 6471.2510 9717.6770 addconic +147.7512 -32.2887 0 531.9476 531.9525 -27.7457 7269.0162 9257.3427 addconic +69.9049 -110.0760 0 531.9504 531.9438 -9.8994 7269.0695 8335.2984 addconic +-71.8156 139.0736 0 532.0484 532.0527 40.9349 6546.3731 8147.0777 addconic +-118.4577 99.7284 0 531.5814 531.5758 45.0000 5862.6495 8656.5755 addconic +-161.6974 17.7169 0 532.0489 532.0446 41.6451 5694.4459 9424.5238 addconic +{} -1.0 -1.0 solidFill +dp +N +17 LW +0.00 0.00 0.00 0.00 setcmykcolor +-41.1168 138.8827 0 532.0465 532.0531 41.1174 6545.9506 8147.9977 addconic +5965 9883 M +40.0635 -139.3211 1 532.0497 532.0449 19.3299 5694.1107 9425.0767 addconic +5597 9119 M +119.9997 -60.0288 1 532.0451 532.0499 0.0000 5863.0202 8658.2299 addconic +7003 7874 M +-120.0000 60.0300 1 532.0509 532.0466 0.0000 7269.0257 8334.7658 addconic +-28.9488 151.0224 1 532.0487 532.0535 -31.0514 7268.9782 9256.7705 addconic +44.9998 -134.9994 1 532.0497 532.0462 -45.0000 6470.9520 9718.0035 addconic +{} -1.0 -1.0 solidFill +0.00 0.00 0.00 1.00 setcmykcolor +N +-41.1168 138.8827 0 532.0465 532.0531 41.1174 6545.9506 8147.9977 addconic +5965 9883 M +40.0635 -139.3211 1 532.0497 532.0449 19.3299 5694.1107 9425.0767 addconic +5597 9119 M +119.9997 -60.0288 1 532.0451 532.0499 0.0000 5863.0202 8658.2299 addconic +7003 7874 M +-120.0000 60.0300 1 532.0509 532.0466 0.0000 7269.0257 8334.7658 addconic +-28.9488 151.0224 1 532.0487 532.0535 -31.0514 7268.9782 9256.7705 addconic +44.9998 -134.9994 1 532.0497 532.0462 -45.0000 6470.9520 9718.0035 addconic +dp +0 LW +N +0.00 0.00 0.00 1.00 setcmykcolor +7730 8069 M +C +N +7730 9523 M +C +N +6471 10251 M +C +N +5233 9691 M +C +N +5402 8391 M +C +N +6546 7615 M +C +N +0.00 0.00 0.00 0.00 setcmykcolor +5916 8668 M +7026 8668 L +7026 8668 L +7026 8917 L +5916 8917 L +C +{} -1.0 -1.0 solidFill +0.00 0.00 0.00 1.00 setcmykcolor +N +5916 8668 M +7026 8668 L +7026 8668 L +7026 8917 L +5916 8917 L +C +17 LW +N +0.00 0.00 0.00 1.00 setcmykcolor +5770 7803 M +3906 7803 L +dp +N +5261 8142 M +3398 8142 L +dp +N +5007 8481 M +3144 8481 L +dp +N +5007 8820 M +3144 8820 L +dp +N +4923 9159 M +3059 9159 L +dp +N +4838 9497 M +2974 9497 L +dp +N +5092 9836 M +3228 9836 L +dp +N +5770 10175 M +3906 10175 L +dp +wst:dutch72bi SF +<01> 6354 9319 0 6976 -1 s +wst:dutch24b SF +<14> 4293 4490 0 4591 -1 s +<19271c241c212001060405> 4583 4490 0 6485 -1 s +GR +eop +%%PageTrailer +%%PageResources: +%%PageProcessColors: Black +%%PageCustomColors: +%%Page: (2) 2 +%%PageResources: (atend) +%%PageProcessColors: (atend) +%%PageCustomColors: (atend) +%%BeginPageSetup +bop +%Defining font PSOwstdutch +%!FontType1-1.0: PSOwstdutch +10 dict begin +/FontName /PSOwstdutch def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001000 0 0 0.001000 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 1 /C0032 put +dup 2 /C0050 put +dup 3 /C0058 put +dup 4 /C0065 put +dup 5 /C0066 put +dup 6 /C0077 put +dup 7 /C0078 put +dup 8 /C0080 put +dup 9 /C0097 put +dup 10 /C0099 put +dup 11 /C0101 put +dup 12 /C0102 put +dup 13 /C0103 put +dup 14 /C0104 put +dup 15 /C0105 put +dup 16 /C0107 put +dup 17 /C0109 put +dup 18 /C0110 put +dup 19 /C0111 put +dup 20 /C0112 put +dup 21 /C0114 put +dup 22 /C0115 put +dup 23 /C0116 put +dup 24 /C0117 put +dup 25 /C0119 put +readonly def +/FontBBox [-25 -238 920 722] readonly def +currentdict end +currentfile eexec +D9D66F633B846A989B9974B0179FC6CC445BC7C8A959A39A32E9DCE7FAEF17EE3BEC9F +50E1A6FCA651FC4B3769A0A91041557502E25A5D6180FE25A3D11BF079E1DF66E54EE9B7C229AF891739707A2A0EC140306B5E43E52B79BFB89E459E50 +6EC6F610A70775A31C460976C4F79449D86E57ACE491E5C6BF20CC4307B1DAF7630252 +E9AF8CFB69B50EDAE9D36A6104AFEF8832F920FD2346B2C7104CD11E3BEE999CFA9F5A +49DB3173EE48D1C82994237F360407B022E0B4 +502E94EA8B493651EF2D03F0B513D655047568325B512AE6 +6AC6F53F3848CF70DE25481CC65D8B1A5793AA +3C4282D111112BEE28AFCA7A3808D4444C4669CA +84EAAAF989219F51AB3476A1B0B5F2246BC306E6 +625C6679C417ED2A8E9BD010DE37D40265074C26842699A34E3649842B194F49D845069DF85493 +1539025D8B7E5F8B1C5D2C91 +AC39A18D8BF0C90D95 +6DB2540D +AEA704F12B6ACBB7C2E5688D0E +BEACFF4986C025D87F2314C9F8814328C29A3584D4606BFBA118F6DDAC6EB68DF9350C677A064AAB1B5BE20CBE9B28CDB2882DAD10BAFEB2D1D147E70E904D0CDADE0756B853D310FB92FF9CD936EEF71B729F072664D6920F94 +1575559A +056F112A4E8FB5C8B6658DF687 +C9A775D937976D4A3E4436A18A14A074E9891CF1A13C6BA05951978168D31C1035B5727FED5D093A2E659C4519BB8299013A4C7F259C +6A4BE78C +0776563D20A5997B483E76EFF022 +3DB9ACA68AEC5DFD52B784EBB0FFF289CCB8B8BC0C954629DD0207B9A31A998D6E19D620B1583B468A9F8651B476C6DBDB0CFD106418C1FC16164428A752494F9FEC1162449E3C0790123C3620EB6DE337BA8BD007A48138D207CA66206E6D7377F3F70F8267CAD5E19AE240F451CA2AEB6361 +DA18D2D2 +9D775C7E79EA542ABC602C3B5E16 +FDACB9A75E011D7BECB098F6EB8FCE09D4CEDFE700FCB1EEBDF4FE3B99C0459B751806E68EE893021163791532EF6A2EF3946E4BA30E89E1BA60AD241CFE24723C37346EDB9F78FE1579E869F75E528AD91D915FD52CC24A332E7E3516625E4BDEC8222203CE277D59F95C32991354A98F69B50352085E2C6393496A2110 +9535 +4A +E334F45A +63AA9EEB2E86E85E35CE52CB6583 +FA4C6F641A0923C925B20E99112AF9D789F7E9AACA5340E5A7ABE2D07B86E2E85C2F2096D75727B62B29C3A696196632910886ACED887A31876761FE895D3C00129A940ED9AA748709DBC0B63C9CE7D9C30A20B16C151D7D15D688F87DDE4FC97138F642FE563225DE4F5055B3A0C7 +E9A8412F +46432715FC785BA1917FD25711 +0AB63FFE85D3DA34E627C01B52B0799D486492EF90EBDEBCC2EDC4EEA927297402FE71DBDDA647CD31AFE41716B111E4822C1156C2877D7FFBEE77E4531AF93CDB9E5A9AE16BECB8A3D09FB03C22323B9EFBD3B11981E62995C40AE7 +E6DEDE72 +4CC3C86B6CEB77F6C76CF6319AC5 +34D25798C1ACDD146E61A7A98172182CBFE58A4D8534B38AF00C7B403625EC01AA210C92787F4EC2780BE5C3F01307FA30ED2020AB78A279CC4C33660EBE02829343FB738A8FC643492BBBBB2C8994983EBAE0351FD328610048242D3B1A6E7FAE3797A027A13744063B +F1B2A353 +2A200C231F4E0EAB04A115AC5D6B +5F8B5A14B14CE3A2F281CB627C8FCB8012E2A42A3CEAEE538352DE083939FBD372EF975BB173F87591E9B0D1D285341D831448FFE1FF1E2DCD381A2D82E00B280321AD02055AEE397DF9D54897D7BE6DFCE673621F0B2DAAE978D17AD37B5E20B5686E47310E4E8EBC3A7614335D3354419555010B13DA4449AA2AFC2A20 +B724 +09F8E9 +19FC7B9B +7639D997B93C6BCF9762A6F0E3 +58BB96C8B918B91BAC311D8E262A378CB222177CBA6EF1F0E12F922436DF200EF29D3FEE0EA51750012B4829487158895F6CA9F4A9AE3FFF97A07B164D36E3BC5E1B8EF63FA0D5ABE814940016FFCC70F572 +6B099C18 +A3A9A9D32D51C01D4605E7686D +F03F80B28588664D596006748092A8E10CB722C9FEB0011E86AF24467208DB3F94654040F4E02D532D8A6214DCAF50A8AE0E0BCC97E19843505DF5579A066902625B74E536E0A339139B68FA470A50A93134DE69D7CFEC4B50 +CB03BE29 +63CB57DF71EA687A44CEB5C4BD +A5A093F40660697B6DF57CEAD63CD6524F0B73E463B01371094E847F72D90E1F52A24E38BB293FAFE54D9FB9D01C09233EA1D3F262CCD7E70F11FC2361C3EEAEB7BB7B52FE25D5A1B2FB26BACD19113B0F6A6DBB9BB34A4867E54B73 +AB34E0A0 +A2089A7396EA95C4CCC241B3B206 +5A1560B1569849071545D2D705B1611F7B6D01E394812AEAC7A89E04C062929C7BDDF0D824441F03DEA862C05DD99C4D23AE15DF6467DAD3C8B1235BE93C4E6D89E023B819FD8845B150252A950D2FC096F7DFECC15807E34F398D5439374B8C57D8BBE40F06CF35039D1BD4CAACA3A4054782E57AA98FA0A575B75E6A10 +89BF +2FE6DC6CD1128FB9CCA60385382110A647052610D2F2A8F119ABD24580F0720F532BE1CDA9164E4727D6A562E443C4 +EB5B2E92 +CC85203A7CC19F9BBBE0BE14A62F +9F5823B793C047E50E56B0ED9D6295D8E0911AA58DC7110BA19271EB32AB6233FE86DEC5D6FD0DBA763DEA44A1B6EC43AF22464C453FD29FDFAD5524615AC8B63837DFFDD101C43E20FC9729F92642002828343154735DBFD28FEA02E5147E6BE9877E6D520A47E764AB435A13 +13E8AD87 +DDC85E7919AD1C30596D1DEA63 +1967D663F9ECDC8A976466BEC3D60E7FAC1E2F58C0C54532FD9B8642D0618A62FFEEB02F912720C2F708DB067601FAE097C6E3861EC42F1F932F3EF66B6021E73930C8F72878DEB45703A93851DE4835 +D9F13DAD +9038B78CC18CF83BF644436D3B6D +B6ED212E093B357C35571E479D9FD4FEEB11396EF621E3B9B2704A901AE51CD230DD341401B56D1B6D926B510F6549BF0AF3B8C23EF50EC13719EE234DEFBC4182343E4F2D970E0BA6BF969A6BBC4DB8CA5FC1290E13D8A890937D27BEE881EE1AF5D3395647FD4C6E2D8F3661A70DBAC70B129FA179AC0C79A4495F835D +0253 +8F166AD5B1A36D2F3420BA51AB70D8C0209C9F2C4FC17CD74518D59C4F68082549DC80 +5AF1DB31 +2530EA714F5460CCC2598056EFDE +8757BD4041C2A024E012A35C44D851FFA108722EDF4B32C1AE62B65619C31F91D78C72D8702C0476D013049942297AA41711005DD726CF130D66879422D4C0D4E2F0344CC0DA606CC0AE794150CAF93DEB9CF1C98B4B7FC6A7779A3A11A24C99CDAFE5F1D7CFA2EF596189DFAEFBAEA23BA25F1CC44E0E3F9D63527D4B96 +BAA1 +6E1E1A07AE4C53C21DAD2D942139214DB83E99B12C41CB77883D4A38C6FFB1 +F0F6F059 +4D0DE2248E9B060347A22E0879C5 +8516AC14595477E082ADB7693902C945449EF5DE20DB521D01803F1F5BA0DE2AA34CC13D5A64870BBD061C281BEA1063427C878500FFE0FBEFFA61855ED5D400818B1905E5B994EEFCCB4AF7CF69898011D7F4B0D3970E03B79DBD62A4049F0ADCE21BC8A38C7DE7C05B017A +F9BB28F8 +B59427447151B45B92EDB859A9 +F9A257A3C6C225AD334D7DF7B3B1478821C73AF8EF869DE781C4EFEDE339F49AE5B05C80D02428C127D511F45A5C5146A420728B194D097AA77610EC7AA76056BA6422D39B8B +E0E18883 +519421B3D7B0451069DFC144723F +5403453E05175F7B16191D7E45EC9F24B18DED5920E6A2FD7B7EE9EE9948384DF57121337E9B75FBAB61B8B668797829C18BFF5C939FF5E13933524D58A2EA4019C1F25C8957FBDF6A994CBDBC70C0D3889DC44B13EB8E0B9537DEA5905F6565B3BE56C43DBF8C2F44CCEEE84CEF32F68C2EE14BDE4600 +BFB29360 +54153419D0AEF83EC050353832 +01CDE43ED7373FB3C41DC72F4BC0FFB8D7BCF4890D032CFC2506FE4D76DCE4A8DE05DEB4C996F4F2E1AE7F175402B12B3AFCFFBDFA808510FE60EEAC259AB8C710121C76720B76D6EEB49E2A157FE0E8D6FBF21B737113 +3F774D10 +01B8A6AC3B644B35336A485C2576 +91281454FA3A0C163AB72D5AA788832E24EF69228BD7E6E0C88DDE701B667F18F2B39EAAB5C84A9EBA7214357D6BB48C8E062E132E1DD1AE1772ADA4671E49E84B34D6402562BDB1868B33A51E8DFA97648176B425A146DBF4AB11F148A2381D6483371FEC2A45D11CAEC34C59EFCEB55149B3CF8DF68024928EC3A6 +4E99FAB3 +8E534831DED802D7A843ABCACE +FF8F8370283BB7C36B8583F24668721BC31116D83CFD0BF9CBE65FCA8FB5D55C94851F71BE7BFA8FC1F18690D5A5FF3D8DBE53D9072238D00DF0801C43CDAB1DF7BC8F5A75 +3E8943F9 +B9CD0888116632C59D3546BE45 +5D07E9841338335DA1232D100C30C29D7909E8C2851487D5D903F8E9218B93AE706C35A83BCEC7DC5BAAB2E63E3BFB50CFFBB231214428EFE480EE806A06181AFADEE0B48E9C51AA0FCEDB52CBDDC63C4B376A315E41E03164972E0E5462FB4EB0AB +1B44366E +13FB0E3E2A570599121D19CA03EB +E2F1EEE5E3D6A959FBFF537DA67F8E1D94705A77498515C2609C8AFAFD38D43EAA5FEBD9F675589D7939D894B56BFDFC5B6339F5F12954D417D07DD2CB3C50206500F7FE90BA7B431CA118F4729F1405B468875A5F84E97C3F0C0B97EE112EC8F4DAB7F06489F125309411CA0E76BB364DA39DB1CB73316FB001AD494936 +EF92 +62550B6F1B9D356C3ED1A8DBC28F +B1B3D21C +F3D95BE14287644D262E0C138C54 +012C6E00CCC4613C +DB16D7A0 +1AEE3AAD3AEB6FA4CA47A5079BB62F48A6D2055C96B4BC2266D99E514C57AD80FE57 +2B26015461DDE4E2956900E48261240AB4313A24E37008E07A8BB9927F3430D66864D453CF70 +795B65FFED2385963995474E956A28EDF615561156315C3BD71026 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +%Defining font PSOwstdutchb +%!FontType1-1.0: PSOwstdutchb +10 dict begin +/FontName /PSOwstdutchb def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001000 0 0 0.001000 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 1 /C0032 put +dup 2 /C0046 put +dup 3 /C0048 put +dup 4 /C0076 put +dup 5 /C0083 put +dup 6 /C0084 put +dup 7 /C0097 put +dup 8 /C0099 put +dup 9 /C0101 put +dup 10 /C0102 put +dup 11 /C0103 put +dup 12 /C0104 put +dup 13 /C0105 put +dup 14 /C0108 put +dup 15 /C0110 put +dup 16 /C0111 put +dup 17 /C0116 put +dup 18 /C0117 put +readonly def +/FontBBox [0 -209 636 694] readonly def +currentdict end +currentfile eexec +D9D66F633B846A989B9974B0179FC6CC445BC7C8A959A39A32E9DCE7FAEF17EE3BEC9F +50E1A6FCA651FC4B3769A0A91041557502E25A5D6180FE25A3D11BF079E1DF66E54EE9B7C229AF891739707A2A0EC140306B5E43E52B79BFB89E459E50 +6EC6F610A70775A31C460976C4F79449D86E57ACE491E5C6BF20CC4307B1DAF7630252 +E9AF8CFB69B50EDAE9D36A6104AFEF8832F920FD2346B2C7104CD11E3BEE999CFA9F5A +49DB3173EE48D1C82994237F360407B022E0B4 +502E94EA8B493651EF2D03F0B513D655047568325B512AE6 +6AC6F53F3848CF70DE25481CC65D8B1A5793AA +3C4282D111112BEE28AFCA7A3808D4444C4669CA +84EAAAF989219F51AB3476A1B0B5F2246BC306E6 +625C6679C417ED2A8E9BD010DE37D40265074C268425D9A4327DA39CB2DFD7488DC30A83BD6536 +5400151DAC104266BE4EBCAE +4B08321016E28AB4C8 +D564DD37 +35505D841146976EDFB4BD729A +2F49DCCD6B4ECE1DAC32EA5679613B7894EE61C72050B6DCA08334000C4A16 +680A3781 +2832EF2992B1104EE36A2BEC06 +9187F54DBBD14CB48FBE819520EA9E057AFA159D622D74C5C4CB4C4E2F70D48C28C58AC259E41F36D6A193F1F10137F8F5642E0DA320E93E1A0774CF9A06A15A8E4A2B38163CD410C997F131229F6A +D332FB6B +2FBF456459B60863BA8C1F90FF +30BDC971AE7EBD62761B023840D691D8B09A1F10C2BB2A62E0E0A98680F70AA19C2E1A5D647F7E90062E9DDCCC518B47EDA99BE33A6F060A065CBBDFBCDDC5438B410D6973CD936B49 +CE511B0D +65C61BBB8AF8AA0FF9B7F76DBFB5 +783DB3C03649CA09CB59394CBE8B92706BD4A92F47BBCDC090D5FC43BEC0BA2D3B9DE68BAE50E2C6F2754BA7D3771C10B7E5FDF26F528B90F81CCBB2DC4042130A82D647F0F0089DB25161EF9A691224B469EE7262D2D138909BF5D553AB92F83A388F09212FF8F6F7274B254E97BB4D80DF55460CB998BC8D0264A9F017 +B892 +995D8191 +931742473EBCC599E506C676DE +7CB1ADC71AE7563A2D5B9E9B9BE86E902832DC46E62790E0CD0A09030BC6663D2ADCF9825A962B9113455345AA10E280FFC7E3C20EC33C37949D2685012AB97FB19E1648DC1714DF49 +4C8AF35B +4C8D51540ED76ED50F96B09FEF1E +8801B29B674F9551A9B93028B0F66B958F93471DBA031FE00421C843EE4471ED8AE3836B1012844D063FDFB6CD6FC0491B1A5369D4590D177CFFDDDC25A31DC6C75337D89B0EB0897A4C04FF2C6613AE6733EF9CD6BD2A69E0FC6FF01DF7F773328B47FE45D6CEE02105CA85E9D7A40B52E33BC58A920550C445FFBCB568 +E6F8 +6E876E1F +48A26CCF +A445B617F6A475EDE5040E429B +59000BA0B10D9973F06FCAA454A68FD04B33D9EB959F120468774D6E0CDF593B1FBDD768B585F2A6A2BAAC6A38F78538658E0595E54CE4D1A67BF90F7E9A0019260F81FC89926EC48A0A5D0117AF7FD10501 +91353519 +F8A647B334B8DA1F425DB3B914 +A0C7743BF576A6ED8ADD79A477EEDA1E500DEB56D66C581503CC690A454DCFFEC44119549362F46FF04231426E287FC443EAAD58D662D22CA510BF84D490927C6914B3FBD12B01C456574DC37BFCDD5E7F61D7B4B9F5FC1CE7665716 +268D405F +C6AC769EAB9BF85B5D37D993CC +C2992E449E116CB1388AA73280FE4A1CC057A59745D2F9953E2006695731E50A25241B8F9E9CDD2FA40FCE7EB1C85AD7647B2A64C252ED9E9D5700C3FE22EBCAC38BBE98CB1B6A20E2F49FD5EB16AF3B69A6B497F3A7499913911A71B8 +2DA15F7E +9B1C8962924BBF0E9712ED925C55 +E4B0DF0EF0B6B9AA1DF1608476A8D88F47C586AFA3EFC690B78ACA9FE8B9E914EC8D5ED7950371DB3752F86402ED52E5034482240ABC6A6B24640B86CE56327B3E6BECC5BC408295F930F3B7CD81DBCBF70A00615D15B508B037F0DFAA1DC995B2943CAE780B5E128482A32AD3650B263678CFD774A46A8A815D9EE8D2FF +5592 +9A65A487DCC54698245318247C2F62B3969FBB45940B4E24666979AF41AE4DFF86A9B57BC1 +DF6F96B3 +D56CE95C18D62CDE7CDB6D763294 +7C4AB3AF8CF87AF4C901C712F6ACD9CF51958EE7080DC57AE027355ADD1680E4B00EDE32076E48F3F5101B058A42524D7A5E3FCBD39BCB6ADCB74F4F1CD3BA618EE60611C4FA220BDD52227F2E973E80B31AB5F1AA275C4EA1078FA3F8D9D56518F306A455E6EABE +6CFAD1EA +3ED3110B0F658DCF2B0FB1758B +AC67E14299CEE0D6D45B3A17F3EC3E216BAC77C24B2C257BBDEEF06A9081C874A1C69AFDFD460DA2593C6B49AB3019B66F06D8785B2B1D5F0BBFA33E8B2FFD6841B846D1AD7ACF265856D79D5AF4 +1DFD4FC3 +7546C69C7FEF40F7640028317C +6FFE3A2D1EA4B1100DBE9255988535FACF20C1DC7A66B890ABD2E4A5B669F9C54C8968D77326EB424A441B14405F96F66CCE9B30 +4671F371 +AD9D377F7A185A45D2AF605D5D86 +CC06E8023029CFF9D381AE953B3FE64DE8E304EC4BEEEDC3EDA6F236995F6CDA51AB9692B5353FF124F7EF6E5CE1492C32599969890DCE464A26F95AA8AA9AA51E11315F1F2A58915C02E920463C1E434CB23FAAB4139B251A21CA1D75FE954CFAF72AA0EF1B7A +DD30F2C7 +7EE5060C7C62F322E4FCD278C1 +CBB2D87B51A32205CCE6E0EB5D50E6DE9978BE98375361A7A7BE2BB8968A62745067074DE4E5D2F6890DEAD8A1189B5C8AA5F16A3DF1F10E3A431631F87611A90AE3F2690B76 +FFE57E75 +4DECB6810ECD0C0C54AA49D316 +055F12C838C48692DDD6CA890EB1E5A113D05566DA3525667AC821274C4F0D28496025A9B298999F1E35184F9875EF36B121751431A76C64697269A1E1E177A1DB78D91A +47B9AAB2 +B813336F109D6A51C649598578 +CC1C437E16197D4B63A8F13DD90EB6403B5C78DF19CD3F7E3606C809557E05CF3F47A050012A14A181487BDED6D303FAC6280EFA21A4AC570329B23416570B82EC9FBF1FB8F729D7E64CDB9A35897E55964DDDD154C8E202AEF5C8 +EF19146C +FDCA5A7575C40D8081CDC4403C71 +A36FEECB325C0E57 +F41D41F8 +AF10BD28B17FF96BAB1082D0F5D99BFD517674B23160B778CFB624CA76EE57F1A2B6 +2E15E2BCDBA2C77165F007402166EA5CB784F1C1EA5BFADEC57DE6EB798FB889DB8758546774 +289E053A7BD388D270DFBA485993A172AF18364CDBC86604FB5AE4 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +%Defining font PSOsymclas +%!FontType1-1.0: PSOsymclas +10 dict begin +/FontName /PSOsymclas def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001000 0 0 0.001000 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 1 /C0069 put +readonly def +/FontBBox [106 45 775 713] readonly def +currentdict end +currentfile eexec +D9D66F633B846A989B9974B0179FC6CC445BC7C8A959A39A32E9DCE7FAEF17EE3BEC9F +50E1A6FCA651FC4B3769A0A91041557502E25A5D6180FE25A3D11BF079E1DF66E54EE9B7C229AF891739707A2A0EC140306B5E43E52B79BFB89E459E50 +6EC6F610A70775A31C460976C4F79449D86E57ACE491E5C6BF20CC4307B1DAF7630252 +E9AF8CFB69B50EDAE9D36A6104AFEF8832F920FD2346B2C7104CD11E3BEE999CFA9F5A +49DB3173EE48D1C82994237F360407B022E0B4 +502E94EA8B493651EF2D03F0B513D655047568325B512AE6 +6AC6F53F3848CF70DE25481CC65D8B1A5793AA +3C4282D111112BEE28AFCA7A3808D4444C4669CA +84EAAAF989219F51AB3476A1B0B5F2246BC306E6 +625C6679C417ED2A8E9BD010DE37D40265074C2684268F16195489648993B9C4D3B534FA887C +DEF605FA87B991F4D20A8F78DACE +5A54C070E03D5C59D9D2D3E06B09CEE028D68B62AB3AEC43C1DD20BA70D288597D9BD8E06818FF764EBAB436723988E8D7CA59E16D39032516BFC5D552ACDEEC6BE938BEF2F43CFFBC811C3626C4DF5F8CF080676520B51C60CEDAD1FE6C92D1431C702174CE517A8FA9377D075A0B6833DAB101DB65397F1419EF5F0016 +004F +6F0824F9657BB4F1C8F981709956865F6855EFAE +9242AD55 +91BBBEE163D844DDA894E13190C9 +2480439E4C71CADA +BD043A9B +A315CAF72652AA7FE6DB2E84D82A6111CE4DE90C02DA0AFFE2620922262A45AB4ED0 +EEC9F4520DD12703442F7D028D4526BD8B771E09FBE11B2749E2D3906894E8D4BFD3F379F14C +3C874F550606965E22FE487B247B5C2D06728490C8F2A3B588CDFC +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +/DPIx 1270 def /DPIy 1270 def +72 DPIx div 72 DPIy div neg scale +0 -13970 translate +1.00 1.00 scale +/wst:dutch14b 14.00 /PSOwstdutchb newFont def +/wst:dutch10 10.00 /PSOwstdutch newFont def +%%IncludeResource: font Courier +/wst:courps10 10.00 /Courier /wst:courps ILEncoding 0 declareNFont def +/wst:dutch14 14.00 /PSOwstdutch newFont def +%%IncludeResource: font Helvetica +/wst:helvps10 10.00 /Helvetica /wst:helvps ILEncoding 0 declareNFont def +/sym:clas10 10.00 /PSOsymclas newFont def +%%EndPageSetup +GS +0 13978 10801 13978 10801 0 0 0 clp +wst:dutch14 SF +0.00 0.00 0.00 1.00 setcmykcolor +<070b17140b150c03010401050b120a0e11091510010c131501060b091618150f120d01070b17191315100108> 2207 558 0 7384 -1 s +<0b150c13151109120a0b> 7375 558 0 8593 -1 s +wst:dutch10 SF +<02> 9434 13300 0 9522 -1 s +wst:helvps10 SF +<4e6574706572663a205265766973696f6e20322e313b20436f7079726967687420> 1322 13280 4 3868 32 s +sym:clas10 SF +<01> 3868 13280 0 4019 -1 s +wst:helvps10 SF +<2031393933b131393935204865776c657474b15061636b61726420436f6d70616e79> 4019 13280 3 7133 32 s +wst:dutch14b SF +<050908110d100f> 1271 1458 0 2055 -1 s +<00030200060c090004090b070e000511120a0a> 2055 1458 4 4007 0 s +wst:courps10 SF +<2020202020202020202020202020436f707972696768742028432920313939332c313939342c31393935204865776c657474b15061636b61726420436f6d70616e79> 1271 2263 18 8267 32 s +<20202020202020202020202020202020202020202020202020414c4c205249474854532052455345525645442e> 1271 2467 27 6041 32 s +<202054686520656e636c6f73656420736f66747761726520616e6420646f63756d656e74696f6e20696e636c7564657320636f70797269676874656420776f726b73206f66> 1271 2875 10 8585 32 s +<20204865776c657474b15061636b61726420436f2e20466f72206173206c6f6e6720617320796f7520636f6d706c7920776974682074686520666f6c6c6f77696e67> 1271 3080 12 8267 32 s +<20206c696d69746174696f6e732c20796f75206172652068657265627920617574686f72697a656420746f20286929207573652c20726570726f647563652c20616e64> 1271 3284 11 8373 32 s +<20206d6f646966792074686520736f66747761726520616e6420646f63756d656e746174696f6e2c20616e6420746f2028696929206469737472696275746520746865> 1271 3488 11 8373 32 s +<2020736f66747761726520616e6420646f63756d656e746174696f6e2c20696e636c7564696e67206d6f64696669636174696f6e732c20666f72> 1271 3692 7 7419 32 s +<20206e6f6eb1636f6d6d65726369616c20707572706f736573206f6e6c792e> 1271 3896 4 4557 32 s +<2020312e202054686520656e636c6f73656420736f66747761726520616e6420646f63756d656e746174696f6e206973206d61646520617661696c61626c65206174206e6f> 1271 4304 13 8585 32 s +<20202020202063686172676520696e206f7264657220746f20616476616e6365207468652067656e6572616c20646576656c6f706d656e74206f66> 1271 4508 14 7525 32 s +<20202020202068696768b1706572666f726d616e6365206e6574776f726b696e672070726f64756374732e> 1271 4712 8 5829 32 s +<2020322e2020596f75206d6179206e6f742064656c65746520616e7920636f70797269676874206e6f746963657320636f6e7461696e656420696e20746865> 1271 5120 13 7949 32 s +<202020202020736f667477617265206f7220646f63756d656e746174696f6e2e20416c6c206861726420636f706965732c20616e6420636f7069657320696e> 1271 5324 14 7949 32 s +<202020202020736f7572636520636f6465206f72206f626a65637420636f646520666f726d2c206f662074686520736f667477617265206f72> 1271 5528 15 7313 32 s +<202020202020646f63756d656e746174696f6e2028696e636c7564696e67206d6f64696669636174696f6e7329206d75737420636f6e7461696e206174206c65617374> 1271 5732 12 8373 32 s +<2020202020206f6e65206f662074686520636f70797269676874206e6f74696365732e> 1271 5937 10 4981 32 s +<2020332e202054686520656e636c6f73656420736f66747761726520616e6420646f63756d656e746174696f6e20686173206e6f74206265656e207375626a6563746564> 1271 6345 12 8479 32 s +<202020202020746f2074657374696e6720616e64207175616c69747920636f6e74726f6c20616e64206973206e6f742061204865776c657474b15061636b61726420436f2e> 1271 6549 16 8585 32 s +<20202020202070726f647563742e2041742061206675747572652074696d652c204865776c657474b15061636b61726420436f2e206d6179206f72206d6179206e6f74> 1271 6753 16 8373 32 s +<2020202020206f6666657220612076657273696f6e206f662074686520736f66747761726520616e6420646f63756d656e746174696f6e20617320612070726f647563742e> 1271 6957 16 8585 32 s +<2020342e202054484520534f46545741524520414e4420444f43554d454e544154494f4e2049532050524f564944454420ba4153204953ba2e> 1271 7365 11 7313 32 s +<2020202020204845574c455454b15041434b41524420434f4d50414e5920444f4553204e4f542057415252414e54205448415420544845205553452c> 1271 7569 13 7631 32 s +<202020202020524550524f44554354494f4e2c204d4f44494649434154494f4e204f5220444953545249425554494f4e204f462054484520534f465457415245204f52> 1271 7773 13 8373 32 s +<202020202020444f43554d454e544154494f4e2057494c4c204e4f5420494e4652494e47452041205448495244205041525459275320494e54454c4c45435455414c> 1271 7977 13 8267 32 s +<20202020202050524f5045525459205249474854532e20485020444f4553204e4f542057415252414e5420544841542054484520534f465457415245204f52> 1271 8181 15 7949 32 s +<202020202020444f43554d454e544154494f4e204953204552524f5220465245452e20485020444953434c41494d5320414c4c2057415252414e544945532c> 1271 8385 13 7949 32 s +<2020202020204558505245535320414e4420494d504c4945442c20574954482052454741524420544f2054484520534f46545741524520414e4420544845> 1271 8589 15 7843 32 s +<202020202020444f43554d454e544154494f4e2e204850205350454349464943414c4c5920444953434c41494d5320414c4c2057415252414e54494553204f46> 1271 8793 12 8055 32 s +<2020202020204d45524348414e544142494c49545920414e44204649544e45535320464f52204120504152544943554c415220505552504f53452e> 1271 8998 12 7525 32 s +<2020352e20204845574c455454b15041434b41524420434f4d50414e592057494c4c204e4f5420494e20414e59204556454e54204245204c4941424c4520464f5220414e59> 1271 9406 14 8585 32 s +<2020202020204449524543542c20494e4449524543542c205350454349414c2c20494e434944454e54414c204f5220434f4e53455155454e5449414c2044414d41474553> 1271 9610 12 8479 32 s +<20202020202028494e434c5544494e47204c4f53542050524f46495453292052454c4154454420544f20414e59205553452c20524550524f44554354494f4e2c> 1271 9814 13 8055 32 s +<2020202020204d4f44494649434154494f4e2c204f5220444953545249425554494f4e204f462054484520534f465457415245204f5220444f43554d454e544154494f4e2e> 1271 10018 13 8585 32 s +GR +eop +%%PageTrailer +%%PageResources: font Courier +%%+ font Helvetica +%%PageProcessColors: Black +%%PageCustomColors: +%%Page: (3) 3 +%%PageResources: (atend) +%%PageProcessColors: (atend) +%%PageCustomColors: (atend) +%%BeginPageSetup +bop +%Defining font PSOwstdutch +%!FontType1-1.0: PSOwstdutch +10 dict begin +/FontName /PSOwstdutch def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001000 0 0 0.001000 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 1 /C0032 put +dup 2 /C0034 put +dup 3 /C0039 put +dup 4 /C0040 put +dup 5 /C0041 put +dup 6 /C0044 put +dup 7 /C0045 put +dup 8 /C0046 put +dup 9 /C0047 put +dup 10 /C0048 put +dup 11 /C0049 put +dup 12 /C0050 put +dup 13 /C0051 put +dup 14 /C0052 put +dup 15 /C0053 put +dup 16 /C0054 put +dup 17 /C0055 put +dup 18 /C0056 put +dup 19 /C0057 put +dup 20 /C0058 put +dup 21 /C0059 put +dup 22 /C0063 put +dup 23 /C0065 put +dup 24 /C0066 put +dup 25 /C0067 put +dup 26 /C0068 put +dup 27 /C0069 put +dup 28 /C0070 put +dup 29 /C0071 put +dup 30 /C0072 put +dup 31 /C0073 put +dup 32 /C0076 put +dup 33 /C0077 put +dup 34 /C0078 put +dup 35 /C0080 put +dup 36 /C0083 put +dup 37 /C0084 put +dup 38 /C0085 put +dup 39 /C0087 put +dup 40 /C0089 put +dup 41 /C0096 put +dup 42 /C0097 put +dup 43 /C0098 put +dup 44 /C0099 put +dup 45 /C0100 put +dup 46 /C0101 put +dup 47 /C0102 put +dup 48 /C0103 put +dup 49 /C0104 put +dup 50 /C0105 put +dup 51 /C0107 put +dup 52 /C0108 put +dup 53 /C0109 put +dup 54 /C0110 put +dup 55 /C0111 put +dup 56 /C0112 put +dup 57 /C0113 put +dup 58 /C0114 put +dup 59 /C0115 put +dup 60 /C0116 put +dup 61 /C0117 put +dup 62 /C0118 put +dup 63 /C0119 put +dup 64 /C0120 put +dup 65 /C0121 put +dup 66 /C0122 put +dup 67 /C0127 put +dup 68 /C0262 put +readonly def +/FontBBox [-25 -256 978 739] readonly def +currentdict end +currentfile eexec +D9D66F633B846A989B9974B0179FC6CC445BC7C8A959A39A32E9DCE7FAEF17EE3BEC9F +50E1A6FCA651FC4B3769A0A91041557502E25A5D6180FE25A3D11BF079E1DF66E54EE9B7C229AF891739707A2A0EC140306B5E43E52B79BFB89E459E50 +6EC6F610A70775A31C460976C4F79449D86E57ACE491E5C6BF20CC4307B1DAF7630252 +E9AF8CFB69B50EDAE9D36A6104AFEF8832F920FD2346B2C7104CD11E3BEE999CFA9F5A +49DB3173EE48D1C82994237F360407B022E0B4 +502E94EA8B493651EF2D03F0B513D655047568325B512AE6 +6AC6F53F3848CF70DE25481CC65D8B1A5793AA +3C4282D111112BEE28AFCA7A3808D4444C4669CA +84EAAAF989219F51AB3476A1B0B5F2246BC306E6 +625C6679C417ED2A8E9BD010DE37D40265074C2684224C22A511BD5CA25D46542453920A678147 +AFC21FA7F4F5862CF1709F6C +BF8C3ECCBFE4507DB5 +612E491F +087A12D0ADB82F28DA93FC23F52C +CEAF524940C77625947ABC17220384663B647815F94C97322EE3AA265BF180CAB3B718279AFE22F9CADE8CCD09858F70BA644F1412CDC6DAF6F810D2EA6C5020CD3D66D1E0DD45B76A301C06B1CF9602829F54913BF787A0A3F9310924D89F5C22CA6BB573DBEA +572C228A +9C7DD0944C1BAB2B7BEE1312FB +9ABF4D5F7B6F67A603088289D982643065FC81628F7A3985D14F90F3109AB8363611081784019958F667C0BEB03FF8F7BEE5234089F39F63 +DDF68CE7 +A62FF96536EE116F86EF2E5BD3 +598EC528527730AF7D6474A3483502EFBFA5866450CC412CD54B059DEDBAF619E391E874A2E812CD543248E14D758644A1FDA985E68538070676AE8F727F9A72 +8FA95D48 +EA14D9C20C227A11A48F18BCCE +AF2AD29C27D3320D85D679827CC6C46B4A74CD80071B250A6BB5CFA0E5DA375F6BE5C2B04DC88F763699602E32DE873A7F116BB7B25845D85C297DF54B3ABC +0E5A6758 +3C1A13306805F44E79D0E8FFF4 +10792A2569C39A97D8B1746C1115D3BDA9F4FBB52C670A9E4098E33AFDA6B611A458B67F0853EE88B4D1B6011888A197AA49F3930F507029A4 +EA9387C3 +10E312CE1EE15BF81C654B754C +7937F678F9506F922E4D2A7A48CA7E73BE40BB5C4776DB +1E1000B1 +5AC9F7E5D4F63482EE9789840A +5620C8DD8F68E12B965E420C86C5CAED645A7CB367DEA22DC4D7543CB68E82 +3DDCECEA +4521ED08FBC8FA997A6A189D0C +954FF3EE83167DCBD66CE97A015CEB3DDC5E57522C319DB82B464038 +CA3DDB2E +011999FF3748BFA69C7F7DE951 +79875F21DFC8E20439EF74B8355B3BE608CB7F70C660FA694A444B469F7CD130E23BE90F64EFD70CA6AE7876B0E03D950A9C602880F121E19135E8C7B72CEF15567B3EEF032CF29E408D +8EA2D55D +98600A5FA903D45D261E3A4AFD +B7509A19AB3AE34204F6C98BEE7C84D1F94E159348D38CE183E625E4806644BC79F8C418DFF9C60001547392584F0987DC7834645C921766DAA11CD95C56AE +85BD57A7 +1C82AE663C5A951013CE73F632 +0E7FBCE95097A4B55348CAB6D26F568837C57791F5FF7EF641B3ACF0D7DF13EE28AAA71A6B7E03E7A879826F491636F84CD2187425BF251CCFC34349A30AC69F9AABAAE2A1FC8DAA47B48DCA440EF8618B80EBCE8EE611942AEF +923DA4E1 +FCC51F765C42EF3EAD869C1D3E65 +22929391A21320C1CCCA124697B32BA264C0B6FE2218AF9865ACC1A2AD98E2C80D2EF7BCCDD7B65EE434B1C53360568C5D5D8710DB3D749E1F075EB53A6ECCD178E0F09DA02DF81F357F2015B61BA9D44DA65A8A60E6AA359E119643B45419D6CA408A0B4990B1DC7D3F5863982402 +A531E2D7 +CA6EB3091C9AD286C5EFC7CEA6 +075FE46AA8D75DC0B87D08DBEB5984344ECD8B0F2746A62D53878D215A611259720BDDF5BCD1C326B193EF46539DD19A6F517EC7990F6AB59FC2 +8FAD59D0 +AA88E9AA9654AA5528E6E5FCA3 +C6AD820A1A100DA2333C7B39A95D67B64A47BA85C43279A3691BABB50A769D6979427A5774A31FB90EE7FD265D705A2C6C5185941AB1E1AA519D94E1FA35D4F52D6EDF64ECFC27CCB2A3DD0CD90B254D8BB31DE2C800B5EFAF9A42183AD0915718 +1E6A292A +80465D681A1F6ECDE5DF2DE760A9 +8868ACB4E46623EB6223F7E996280A27F1C10E1547B6735F8004178BD2386D0F843ED62BD2C097CE5E70D171A064F4EDD911EE2DF60321790E29292537E634391514B72C9D0B3329EC2ADA8B9873E0E52DBCC8765195412181EF545570515F4A27DA237B +7C89865C +830A53F63D5C25810538BA7DF2 +E210640A5129A80C73B47E30004CC04FC0E6B1EA2AD238A7A5487BA170898E29A677B8218D7D8F5D1C8D64 +4C351293 +DCF6D7EFA698AE73ADC9358A3A33 +68746A02CA5A9649DCCE8621B1D6F6DB819DD4472B25E1853AA2A1BEDC07298D9A375521F5F17F1A396D2509E9E492E28F2207A82D499270CE64EC80F4D825B29B64D5E73F85018DF897E8EBC75A60810BF3748CFC3114CD4FC2C3BD8AD6B7858341293470C0E470756B33B9EC13BD623523FE07B0236FE1594A +692F601B +ED3EC53ACDDEF7823ABC45D254B0 +F9C17873BFEFB472483B69662E7CA7BF3C3947FAD0FF274545249402FB77CCDBE56EFB69785C819D51DDB9B2947D8D64AAB259F192BADB586BADCDD8B6FC1E738647DECD0FD09383F3085850BE1EC8084819C6182508D8F0A04E2AB1CA87067299A71C8D10 +DF9C9F3D +DD5778A961522DD57B8C8FC175 +DC6FD9A00076833BDB53D2B8FEB9063E936CA35F01B6F5723C650D67DB7183B0CC329AB36AA2D614DE9F57ADA7AEF47907E5C668B224 +FB46F259 +4E93E36622AAD5C385E431C10B +B4D94A382CB2BF32C9F53DA41460D3A38667D6D1887CE80BD7E94454ED22D30E35D6EF934D2ADC234CFB3CCDD9A0345BDC3FB46839BB6A2237977E14974DFB54117B6FD1706B8E2786E1FCDFC3399628 +709AE4DF +8A1DEE94B737D54876B67F2EE55B +ABE1C5C9228F81E5A90E2476F86C80B758B282AB19E259FA05431893DF39BC65F48FC612F894705D9932F8CDEAEA57330610E0FBEBDDA11DE98DCF224B406224FF7FD779A15C0EBDEDC745AE1F00C49B596740BA06B73A8503343219E0EDE86C7BCC0D80BE87233B +00CC2E6F +D8AD1301B973010A8FA75A119F22 +82B0FD21DD7BC49106A928C2BDAE7E9C78E7832737557F2031AA2357973371AE4C8CDEFBAB4408686B0EABA1E9E9960D611621CBA8AA0FC3C92571FD28EF563C412837AC473AF0A1D41BBE0C819595F83508160F76203DA116C0A9F01A2D85FA8B6D3C793EAEF43AD2D383285AA51387BB8998 +D7D5E575 +1CEC17029EEF9C35FA818FAD1B23 +9532A49623BDB98B02CB67D9A8514C2D71B8EC228CF2336397C6B5A42FD06BB0C89C2BBB0D89DEEB4D4C51CB015C9DB84DD9E282AA9371A0ADA84465934350A9A6CF854048D3F200B890E1A8B6D7FB5DE665F1F80ED23DECCE62451FEB33329F0DCD5908F709C8F18DDDA3A3867FA38234F98CD4B92DE5E412A9DF4D8182 +1525 +31 +48E348C8 +D79C8309BEA5F0DB6677A763C3 +178F38BB846B264C4DA942E8B01819292AA75D09E27EAA3CBF571A7B496DED8227EAC5C4286DEB2710970ECD9B4B9770911AB92B5C03B57A8E7B24439FABC26CAD90E4DAB16568E44B9E373AFF0AD8E47784A346B48E6E26A44A444193D2FE1239 +8A84FC85 +03699F53D37D7A0E0A3189700A +D11B06A99C4F80B727689A78CA7EC53FFE966CA2CD29E762967FE18AFE2960221E553968541BE64AF0AF0459BCF7426574A31C25ECB4719B8220558F9F56B4E30EB2DF47712357DD90821B3E1F06A1453454459DDA69585A0EDED924F3E23AF00337A1 +998DA878 +CBA3A9B330D0C9BD02D6F27D6E47 +F4FB96020706E063864498AB7CEC62C0547D88E04CB19AD2173640B9BBA498BE2E29CC347A64C3D73D9CBC3953938439B63F0E4FA1A5C7FA6295E6488DBB96BB1E818FE4D52BADDDA9460A513126DEBA627BE5AB171110E1C3BAA403FD984F024961CA8FC1E4FFD53981678ABF3ACFFE45D7C80B201A013B37BE3B8EF436 +5DB7B119 +821E3D597EFFB3FEEE149C3EE06D +1BB6833E4CF66C0FD482C0929DE9C062D7AEFD2C12AD49AF6D8CE1DB1C6D058194E3FD437F199C6991E0812D2E5E97F47860ED3C23F95F9F7FBB24E6EABFE53BB1C9F06AA87394C00560F60C61C80E54184ACE073C41D2A796678CCCA43B579C1286AFF1A028569CFC +20D1D307 +B41E8351698C61D0914B18C7E370 +4CDAD37EBF302E30692877DB64A07C5477AF809BF36AC2DBC2531583AC73593C9D6CE5C6DD5DF15409CDA73D444E8587EC7203D2602A914694B11E6A126C5303BD4DD1AD7FFDAD99A956A9F454CE208E3B790EC0DEB1B17F6398982F2C878728EFEA319489F42E4020372B8E5536BE703736CB57AE5188063B69 +5334DF80 +6033F7FE65F8EC0331573D99FA2E +D03C47641C913F864FAE6EEE35F1F24BC2467787A37B7A3ED626D24D698BCE379008CED85906D83315FD100649748B9F89902A51715CA7A51A39AAAC84D10CC79E4358A0C7F81009662643DB880EBB280472CAE3074E0A226D939E167D83A6F7211AE0B017BDF334DB170B043B862EA1A3168F3549AE2AECF1391573D02D +08FE +71110DC5868DD2C92FF3E7 +929D692B +3EBEACBEF86B9C1E3A6FE6622E +CEB154CE9F17F8EDFC0AB91B62FC4B76423714E19CEC388E23C70AD9B399C49BDAD6ED7F76C80D37AE0B77E9EC9A4C09D9AAA335D39924E778896D +CD7D2158 +51547983613D01497720782185 +9BB191D59C6C41DAE26BE002EA0156401D9C77B3594620EA0CAF67A11D928D369240A4D128837548DF680EA20223BE8DF696717B052A3438B68ECFC4C51AF1D81759981E3D3EDF +9DCBEB15 +BE9F28BDEA18372F6885BB126FFE +6BE2391040B86F19D6DF8ADEE180737A5FC86A51B8070E0830AB930CAC285C6CA499C2C7AE213D1817235532DAEF2FF66C2A43D6C66C519547D9B995C8EDD08CF420BFBF64F4AF6199C1E514FA8A71B5FB50FDECFBFC88AC2E2D02C907D1C78BB0B9B87717A4FD38E486865CA2F0B6 +97877723 +7FD8B2AC8525FCA3CE9BCE9E7A +787A5C6C08A8B87AB785C977E68F9D6152F81D240EDF6F26331C6091CC2F025B10ADA4CD01BB11E4B894D201531C27BBE22EE866F31A6AB991080C0B31C0B927DDC0CF04A5A33F5E93D4CC6AF049E10181866E197B257215A83E4843 +9701AD12 +03BD113782B5611094DA2CBBEDE0 +59D026A50DDB18E68E5C1FBA1A45179DB0E1220BC486FC523CD2B36EC80F492B4611C9FFF412A988A848B27551FED4797773C338A46623FD5F37B9B2CF4F5CB161147DE6C3F2861E3EDC63D9C3942E8381DD25A7FFE8E7395243BEF9FED4CD75B828A612B8F50E5A2C1E +27465CD7 +4D97BF9A9445FAE6C3F503CB1D43 +978B1B0677D28EE0469ED5EFDB4025E9519F24B3B69E55B4CFA66177266DEBE0B0303ABD225B68EAFFFBD6DB78644CC42CACF213344246E96BEBDDAAC67C0F186278BD8E96C9C2EA991FCB2D54A5D2D551427840756302C1A5516B8387658710BCCC5CEF352C4B572AEE173C75A1E24DA87637A53CFAC9FF4E122DCB0A93 +DE09 +2B7053 +A340C2C5 +A5778B45D05C9437C115735F17 +18E0BB5696B05F6480613B37473D8124893B67BB10369A8F7CF3B9D292A8D084F541A0A6DCD4A74F4103910613DE77BC8D957AAE39A473C236C1007EEC217C6172F756D4C20358848F8B24752A55A056AE +F4324C63 +8514D2D498DDD91F45557EFBC166 +E9384CF3CFE81DCDEEA0AB2986B31F956132570A63E2B3F07012ECAA0C6F5B3B65D5C29AE39AAA8EAF763EF4CA9771AE9274FBCCA9356E3A4AFEA85CBEC87DD65A385F0B775A097C5CD78B96D61B1A3CD81831B9F68B2BBF1559A06EA56AAE057A27B621 +A0A477D4 +652D69A87DA6C647008F8FAF25DB +3B6D67966149419075A6DED25B8060A7EDECE485FBA929968A5B0EA28097470EE34C4434F63B2BE568C36FE8669B91E96304DC90A05FEAF0D93925084A1888A49557F96B51950273651342CC1A43C6825830FFC9C1AB3185B008AD38247485D7E6087558D014A7C140AA730C0BFAD243F3011AD27B95A774318F893AB3AF +732A +AC909FFFF78BDD6A5064769097250E1A +7ED73119 +A896F0A21B0BCC77FD2461F4B71B +7028415C5C1938186E7D7CF32203FD04FEEB653D2E51B45984A5EF53D514C205D70E3CB718E3DF83C8FA11845D8BAF7BCF1F19F7480AF17FD087C2F15894D5F8895F656381D6C6CD2E1FE4BACFD83C275A516C0AC9CDEAC5F9AEC4E65726060C56952B29D3A0458EBB44AB4D517856A18ED733 +D731660F +BF16EDEB13B85B9BC8976420C7 +6FC705B1C43713757899BA4C9E29A5E068CA627AA5784A6BE09CC102378F9A2B50B467AA7894196D1F2DC660D183D79C260C8DB3532D088C48D0 +EADCA6D2 +E50C11FF09D8090D17B0A6E50FDE +64083AA77EC5F5C7E932C750AF419750688767B13DDFDE0BC6FBA8DB074A40C526EB0BE3A0F3AE5AF05462EFC1DC99DE6737EA09FB9452451AF3DA40B337567742253D64D68233C1035BCD052835F772B493AB4A7FDB47945DF4A00FD2BD06A90A421DF99C86A6E863B2EAF29110828D269B9BF6AB5794D4DE7B0C6F02A3 +1CC0 +F8C163 +72E817C4 +4F6E9D1AEA48609614B6B0A216 +CECD233B94BB3763C561B84425D68620E409C85F311EE10303CEB00B746479DFD1F2ACBC03A25463B1D4FD1BA42C883F9018AA53B5F849548BE1AEB2AFBB4B67666B41DB2E6EF69C6620C3EA5D087A664A4E57A2667BB7CE +C3D1D584 +71D2591082E214C3423A7829EF +715B07B720A1999884E59531DDA078E106733709BF51014B6D545402B2F666425437D2115D4EA3B0822ED1A8E8EABA8F6CBB3B7353136D66C7FDE6C07FDEDF482D083312E013C01F730C2F9FB6732D4D83FE +927022C6 +4111DBF61941DA2CAA6BC2A8D245 +3D65A8C9EC0AB7357ECD143FAFAEFFE3C2194691B0C9831D491BB459C6BB7135AB8066E999540364EEA5D6F2845DC8D2374CF3DFE21A06331DE0D19C524F2FAA79C555E51EAC41036840B3AE4DE56B1E01D197C57C4D1C7DB27AE680EABDFA6B61805F0A268528BD320C0942620D +F7708F69 +871DBF4C00D6A8356EB6A487F1 +4B9D9A5B9BF8EDF751B1FC04B0541F65B0AB5E7FADE531F102E7CDB869833D94A209532CF65A29AD02C9BC7AFC967EF63AFA5C7270BDD2A0178A0CC2C34CF7D27D910518A0C1E32B278B76EF3D172BE0BD166154A5EDBF2D92 +C4C8B19D +D6BFF6073F0ECBB0F9D4CCD2D2 +49ECF4B2BECAF7E189A4F1CBCD070077A7C4E3BE59E1B077581D7491CC129082DFB5644E7D5957699C26D53E9B90EA6714D3669A368601D59F55FB37BF170F4F4479DBC0F592AFF0DF18AA49D193D5B659095812FE74543A740B2145 +2A250139 +7B01C57F9302A37EC5F7F6618C37 +5D1EC39D9F86402EA704EB316329F24B8F9296B37B74C7CC5B38D364F7D9B18E5B0B0F1DAEE9B5F77F4D8E36BD25BF971D3EEF39AA97B0B0EF491A9C47DAC8C5CEFC33A730A432FA807DC4D8B722A438575A353E88726CF67EB6587F61B1AD09766475D468F7DB8641F69D9D6A82B032B2C759DF7AFA2F618C2EC862AB49 +C614 +BE8486D1F17C3D482EE1F74DA443895E572A4BF4DD250268E3D3BB80CD473137349D8FCFEA7478550C61C6E4C29941 +94163D83 +9672EE7203FDF0DF2056D9518EAA +9CCF3132E01DD98D0DF6CAD2A55EDD452BB6F6DB5FD6FF997B28AC38D6C4CCA9A3647419F7A0F9F1703820F821F5435F622ADDDE82AFCD26CE7F57994C5A607CF905837E30D973FD50EDEA5EFFF959DBC324F487C7A3E25F4303733F2D417CE154FD39E9FACD558266F37F2111 +D4F18D0E +D01F6457D08E3B6606033723BA +1DE8C7316EE11849E44E9DC4F7E552555B89E7F9EAE6318A377F4F8743BA137F053FC41A21CD7E2B4C0309906BEABDFFFA20235BF6742AD2990B7FB7B3ADDDEC34860297C363916F2E4FF2BF46FDE5AA +BCCDEA58 +B7F309BBF1A2784B5B0590C353F4 +64EAFB98DC676A3E609D59B675771DEB1F2D6D44FA8B9DB11533EE626607FAE00FD0D82F5F97AFB3C42943BBE4C9C9FB74B2CDBFB5A21302C21A0DB3F8DD2F788D69D29F5E3D0B62EEDFA5254B3229CE039D7EDC96683C5EF111DC9CDAD4DAD8A53A5F5DB2821925906327FAC154325AE13029D8776FB8FE8F15FD809039 +7FA3 +845F56CC67251D801D892B1E859DE6A82690F70AEF5C5BB21A89242887B9D823236EEE +41417FB6 +32F52692663EF2D7218F207745 +49A2D4DA66D3EE67FEC1ED65B9C8D2D5C065E4F34F765341385C313CA2DAC9D54817477038CA5ED40ACAC6A2B5EAD65A6CD12BBD9AE4 +FDF53C84 +783C15AD3E068D61745C62D5743D +00BE2F710937580E62B0E579475AFBEAC31B9E72C3959C425E5E93A2C39ACE4732995037457E4F05A60BF71E5D8695B37104A409F1F43E602DC94EFDBD7415700056B96BE613E51B812BBF3B8B4353632619424CA09D47B4421F4DF97797F88CD5B8C81513E327F06BC640560D17E009A05EF1CB3CE58F58654624FDB178 +E097 +099ED867C5A5DC84C7CF576FF52AC3CA9F2BF84ACF3B77F184563C1180B19D +7BE8096D +13F67E595940DEEBA3AC9B2D697C +75CE2B61DA31ACBBBE8AB5EBDA8F8E9AF8873EC5D577ED8D98F68C1DD473EF7757CFE09F99496C8D9B7F8A8757960AA8F6E84D3212968F35CE4A4EFFE7D472747D9B5CDC2B60AFD997F12759E379F79B7FBBA25ECF4892E6B52641A31764D44D01E25FE1D05F6971C3CBA0AA +80A6A82F +4FB2014FF4E6B86337E91CFF26 +875BC7B6C660EA39CDCD6737BFD06BA924F793D469E14747D47722EBF35A5DCD021667DF7168D08187A8CC55B566D3B890EE95D52353F600EB5B2B54B81D359585B0547BE7AE +07465F76 +6A7B6BF084D8C37A6BF455891180 +493205BD0E371DC2206E4572FD7BA3ABF3234454EA4E58F11AF9AD10B3A35C328DCEE32B61BC0B6400F63B4EA2724A9278A64DC016508EC99EE790B7281E2116D2581946D40C2EAE4961BFADD0C4960926BFA004E3CDBD622A0F215113F30741020FBA0B597D779968C2CE2E54C7F8B8D48A6D8B40423D +0364BD59 +E33418BE9079F356B54D4A19BC80 +F638158D6584D9C89438E1D6642D95EA5099A39915EE3760E0FAFC5B74922AFB58BF910C67897FDDB56C95B93347E4C2919155BC9D461CCADE76D14AFCA093F9A13EDF7182C50F36A4CA423E116D14042406BED3D253231BC2176EB3E32601966B2C053EE56BCB87E28D +F2E4865B +EDA9974E4117630FCE45C985F9 +C4EE95BC985C3B383A5CA2A4BEE4259C156F32AEADC6217235AC345E3D3E34F8B8D417D2004D0374D3D86DBFC83BC919CA9BE4587A37C1D408F2FCF446E55533C3056B00F4AEB5651AFA6B8C1D78231E102665A0F2EACB +C45E855F +518B51874E2CCFA1286927DD7392 +D7A101E2D772E49FCB7351E2610452D323A8838B837E5420F222258616B00562ACB597F784D06128F93FC95E118760C368C528F9247A1BC00DCBED75C58706ADCB7D162CCE1E9E5A98F88DA2B8F7DCA171636A59BC8BDCF1DAE6C351D0CFA57EF881D3AC149EAD4C8E7934D04DECB4AF68ABBD7385AB1BF5F3073D86 +F0BC1D2C +3F6D541935A0E13DD6F9B56C36 +17FEA2E7D173FF4BAE09E1A372BE86EDA0BC00C78523C20221EAB5D55E7976A03878879F15CA5FDBE108AB78E183493E9657C3CE04974E81AAB64AEF07BCF866D3AF81C4C1 +AAAF29BF +2A96D8CF0BBD7DCA4CDFA1B773 +04C21C36A5B0E549FE3A7011F88D2DAB6C4A8116C35D4B7B2EB589F479086EAFE358454D4517F16CA5D19AAE79D861176A2F1D800F773359234CBA33628C1057DE2E7AE7662E3065EC174FDB2CE5DA59E18D1E891BBF4DE25A7A80AC7D7DC336452B +FA5110E5 +249A631743DEEC0039D6B683E0 +113647B28D5453B97B4A9546623E203B5A420CF97C2C6EAF9DD4030A372C6D60EE6B16E91271B4C8041FF02F9E55477FA54ED7FFFC0C710BBA11B4C9D52DEB6A48F76B932EC72ACDE5C1A974423DD67CBF1A8432C46A551D51 +6EB01FB1 +51A430917881A89FBC10793536F6 +7C1588EDA8721163CE91E514E23D3E97048525F22E977F312451DC17DBB35FE233F18FD070F7196C608B045064F718CA26BEB9CF8ACF7D6E60746C5F52E28B79BFE60EF2E2CE11C08B3383CCF2F2B1DAB2C4E23F23067D4FF175E52595D92F5CC024374E92DF463867349AE73339BC020F0FD634F00FA1F1DD095D4234D0 +5AA2 +5CF32489FC91BD050B4107DA69D0 +90F000D7 +EC794F8FCE120444DF283E70E24B +D8D345F5FADC5B92A1005E68D7E32C048336E4916719B95FD44C8E9ED667DD23668F50C666D500AF2BB717556F54EFEC5BA47D4FD698C0D3C391522E33858ABC3DA72C99E635E344F0FB1BAE2DA075189DA59A843550F2C0B27111987E983F48C69604106D766C82C46404F368532AC8F0485B2F927F39B329FE07C235F6 +1E48 +8F720AC0B0474323E615DBE7ECC04D1625034B5C468C943F46 +BDA74E64 +D6A59A5E7E82183744B80682EB17 +2AF78530E4D0B7C5AFD04E9D64A4B19ABBF91EB867554068743418EAA9734B42A909D242547FC18B0B58956B8F76E2513748098633AC7FAF69A20007EDE057A74C4DA300F40B7C03FCCEA29EC8DB637F987EAAEAB58696C9045267112B66F0F65E393AEB555024384701C74FDF2A9CB8B6526569FE8A7AB6F858C8FC0873 +B090 +D9680AA0 +39D4650E0995D7BD0C8C664C6F +732F6D1EFEDC008064ABB6D661B8256AC3122DBE58175AC593BB1A38BA655B88772886B9BD165941086462C7C1129FB6C623D6200482AF8847406E975DFD7F +7E4BEA20 +865D94DF9D60FA10B5267D952A37 +9B660FE317AA8E5D41BE770444736F497431AA0E6F802732B86B50487D326A44D5F08F7E0F7B46E775FC247F68329D0FB68746F90EC11B02B2F229992558BD32E7EA3B040C0887F39EF4E8297B719115CB3306E2ED74092C9F24FCB7784DB8C537435B6B652EED4B0C +A16ECBB6 +CDEDD10CE38C2780D767D7A65C +52482D6E916CECBFB7DBFE36CEE122A3C6A04F7F922D +BAFE5265 +EF8AD7CEDF922F8A36AFA0D3A18B +B5E4115C16D89607 +D14968CD +E36CA209BC1BA67EBC2FE9FC0FBF85D7F26FAD17C75CA2932FEAD6DC153BEADF8FA5 +4C49F6F0ABE6C5DC9AFB5E4085A35C9B6604A9D8A49906FFF72E7C415638488098CE64A95835 +F7B8745FF77A3CF0A6CFBF76C46BDD804DD9A789770772E5BF80DF +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +%Defining font PSOwstdutchb +%!FontType1-1.0: PSOwstdutchb +10 dict begin +/FontName /PSOwstdutchb def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001000 0 0 0.001000 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 1 /C0032 put +dup 2 /C0046 put +dup 3 /C0049 put +dup 4 /C0067 put +dup 5 /C0068 put +dup 6 /C0073 put +dup 7 /C0078 put +dup 8 /C0079 put +dup 9 /C0083 put +dup 10 /C0084 put +dup 11 /C0097 put +dup 12 /C0098 put +dup 13 /C0099 put +dup 14 /C0100 put +dup 15 /C0101 put +dup 16 /C0102 put +dup 17 /C0105 put +dup 18 /C0108 put +dup 19 /C0110 put +dup 20 /C0111 put +dup 21 /C0114 put +dup 22 /C0115 put +dup 23 /C0116 put +dup 24 /C0117 put +dup 25 /C0118 put +readonly def +/FontBBox [-4 -17 742 694] readonly def +currentdict end +currentfile eexec +D9D66F633B846A989B9974B0179FC6CC445BC7C8A959A39A32E9DCE7FAEF17EE3BEC9F +50E1A6FCA651FC4B3769A0A91041557502E25A5D6180FE25A3D11BF079E1DF66E54EE9B7C229AF891739707A2A0EC140306B5E43E52B79BFB89E459E50 +6EC6F610A70775A31C460976C4F79449D86E57ACE491E5C6BF20CC4307B1DAF7630252 +E9AF8CFB69B50EDAE9D36A6104AFEF8832F920FD2346B2C7104CD11E3BEE999CFA9F5A +49DB3173EE48D1C82994237F360407B022E0B4 +502E94EA8B493651EF2D03F0B513D655047568325B512AE6 +6AC6F53F3848CF70DE25481CC65D8B1A5793AA +3C4282D111112BEE28AFCA7A3808D4444C4669CA +84EAAAF989219F51AB3476A1B0B5F2246BC306E6 +625C6679C417ED2A8E9BD010DE37D40265074C26842699A34E3649842B194F49D845069DF85493 +1539025D8B7E5F8B1C5D2C91 +AC39A18D8BF0C90D95 +6DB2540D +AEA704F12ABAF3E0AAAF56159B +724B67EB97E2C3215DDF2B15C6EBDE114EFF03C97F3A58D9ABED1553250F70 +3963F08B +CAF922D4CB695AEE709226E53B +46DB56C9D89C303A632921AD86F384BC96E6F4C11C52A0C1DAFDF82715F2D5A298FA9C2EB7A91E3C0DDB271EF3E065170AB1EE1C2FC5273B941F20AB +4F994E6B +E4167D1A86E24CC7AA9D08EA3961 +649C030976B91812E2A769ED651F0939064FAD60D2DBEC8488DD928FBBCECFD5962DBCDDD3261D9BC394C3BFC3313722924CE7F6E826A107EBC293B55F8139EEE17C527C292DBA87445D478246CBAA854239ECD27F271AA021FE35EFD30AA1899D4102DA6D02C484 +E1CB1BD2 +DC62C963EA1C46F4B1414419F5 +E85244ADA459ECCEB99B4F788823F187BE6846FE04411DC7EABECBE139A2B696F407BD1F7885D6D1B8F1BD118DDAEAC075774E3EC4D34FA205042609195E238BB143CA1EBD2C8601902590710108E91B2F468EDB050256 +DFFC7715 +47C600A4437F11EF71485A1F48 +00A5303A4438CCB5628D9AAA4D6C23FC813FDB4900BD9DD8EEF089D9F7B70FE47BADC25E841866893745517070280C95A564806CB8634201893BEB792983 +354C6A96 +001282D87D109ADAF09D46C135 +4E5FC1A690093D0822387B95135EAEA9627FDEB8CE3E9BD4203D6D59EA38279EA1BBAB5BA86CFF671881709BFA8CEAB1F5F81F8A62E34C8434D13BE61689FF3041DC81B61CAC1EAF6BBD17DF0DA01D43AC420D8D35413DD642054FD9D89762 +A0E3253E +4E5A31296B61105981BDCF0E009C +C38FCBE99E2B7252527C2B300A5F311D965C37E36357984B40A28C8D32C9470E2F66E7A5F4A2B71E967880280DE43696D4BE0D6439F066EB912666A83E0F0A770CCB0542224C14D0E5742C68F793CA0115C8155FBEE6DE8BA58BBC1B2279FA743F5240707AA6F738D4 +6843715C +06E126A734A4D59A2A21D263C777 +14E5F401C9A72F255496109B763A7D902619E113537E0BAF9649F72A8867CAD9C031D45EA11432AC5A2C953B4622589ED1A2FF14BDEAB4F9D89C67956A64F95FCAF589F882FD019822D5AC46BB6326F15C09C3DD776062345A932AFBBBDFF973BD9B6B9F578C303463C2DFA74108243BDFBBE698467E8EE106CFEC6F26D1 +DA14 +66064ED5 +2CAE60EE7F0440B3A603DA8B57 +4FD56BF4392CB21893F5A642C2E00B6F6E010BC3595D205DBB7030A4B3BCBBECC897F607F752265766AB0EBC69758EB500CAC5AFE105C06065077B07C916AEF7ACC56F844C21BD0581 +8A5BF19E +09D7D7465C35989A9A56CEDFA01A +8BDE3627FCBAC4B3FE523C010C750A7BCFFA00DE417194826C142B2BF8D4839117B00774D7D6E7AE20954E490DE4A6F9481954A36C860A2D3A85B328D6749AA7862715C558B9BF31594733C197226C3A5A5C14EA81003FB801EFC8B6C8B25914957D2240109FD281D2C2FBF77868064F998F24E8F7A8119C26BA2447DF51 +C24C +B7C8ACFC +1E5A8F0A +6DD09E2766BD6118238154EC7D +BB3A58849E17DD315C47825AF98D3DAD189A8D0ACE32B05D0F28F8249C89F89C4B7F9B9EA43D1462934002DC1284E5C375C6901330C82072EF72449151AF18399BFEB5FBD8B182996838C875CF3B64FA676E30D398C4CF95A228434F0E83 +9C9E61F3 +CEA8ECC06F286ECD2C1870E9E7 +453C99E8ACFCE8E5DE955524F93A19C2CE1C608043B8246404F857CB7A0AD846BABF299A31901DFE9E4EBE464F1EE81C786239499B007A3A5D3BE752E84EE00D3C44CEE3EB615502A904ECB090F76E0BC7A9 +27846E9F +93E6B5D935463D48C7A9A81BF656 +2ECE8758CD748A8BD2F9B81A51E93CA503A83158630B9A857C4C3BFB7117465488D368B6251A43FA3AFA6D07EC59C2FE97BDDB8507FB3C1B5504CC9E284437DFE5A3E9F6D1E706212E7B58ABAADE0E2B4020AA6918980F89F63FFBB0C3F33C4FDB60B582265DF7CD0D2EAE9A +A544CE0A +F91903E299CBE4F5F7788A7243 +C3044621688380278D3D82761B761FAA49144D4C7C230934B4D3870DF772A3F66FC6CE44454AF4769DF439B3008B1CBDD49F83C8BD528502A1D12EE8179AABC6C4F3560B910314E9CB8BC1C6F05E1E4962C08C98459E92406A8D627C +DE83A7F5 +00313FC99C325FD1A66353DDFA +9C87125EF692BFB532CF9BF28E2BFD8F549E8FDF3E0969B16C0065A26A8A27191EF8B591B5B227A3D3A87E3C695303A3FD26252791E0406438C22F4C1238CE6AC97D3745ADEDF7C58D6A40D8C2DF949AE6D14E0B2E95A54B801D4C49E4 +111A1D42 +579B64A1DD59E8326D12BD51E1 +2300D2729657BBA004ABB4584F5C57C6B5359BF8E9F9FFFAEBFD6542A7BA32774C9F34D992C39ABDCCE8AD64BAC3ACB0EB2CFC43C4C9A1313CCB31D6ED4C24492E88A3667D2060A72586ABD45991 +D9E700D8 +899CDC56700DE35BAED691A53B +D33F9AED98B84A16FD578F377AFA0D925D66C74629C781CD6AB0470F61C998BEC025A1A723381B4AE8E9D8CD4684747F3A440EC2 +E6CD1AB7 +156DF724256EDB1C5EE4A540432B +97CD7F695A0CACEA80F1E5B45F80438BE02C21F1D42DFFA2F4CFF90B6C00B407E92B9B6C5D35554671F22237F0B1F993FA9CAD620E507CD74C5D7B5E3F84D3A3DCC18284ED87DFDDDB6588FDB5F005E22B15126BF9752AE1EF626706BFC003499F988FA3E33993 +B7FFC5A1 +6E0CAB0880998BDEF0BD708901 +000DE64F9F7E1FC9D4D5F871BA8A3925EFE88D9ED2185007912EDE24CDCF7CDA8B9EBB2019E0ECE0F0DCDF18FCCA3F5B8136E7E3FE82580E1BFD50426D23971450CBD358C8C9 +FC3A6061 +4F19899200D221ED2B0DFE501A +BDEAB932D331107E3D0C9B3B29B32709B1E4FFE0302237DAB2D6CBAAD7E4E07EA72113C930AFA82B10CD855108D3BABEEC7CC1B2EDB143C5D4D9D89F4A5B459A649BBCA20E90F9C30D588AF47FBE4CAFEEB0AFAF99B0C9E759 +C5D70ED4 +7B8979D8F61FC389EE4F92B0A965 +BEA31B1E0C516F0A896755F3C176FDBEA71F94094A4C2E45D1AC1AAA507DF92DBFE9EDC3041951A0F63C34190EADD6E9D52A8D0C67D90C594A65D4FF5D40AFEACA2DC558981A7A057F6A947F1E2C4F9206684B28BFEE0FC4A109AA5FAFA623088C5B61009B28980223E8803679E1FB6697452AF766769FCFA8 +8259406D +0D7B964B07CE39A3D11A188FE1 +0A825C389B8C13C5017E157DD08AE3CAABF2E3A5A68E8BF2E7D2545A817515A90A75EAEFD326FADA2A68D5B8CA60F77F9CE33FEC2E10B9A60F7BB34520061418C3A23A86 +0D0AFE34 +9E9613EAF7367BD11EB96148B8 +7232D14BD566768B1B8A1C16F02689273E4B2DD8655934D2DB088DE815A02881EC3E363ED719EE705AA8BAEE09B8CE42CE22AE98CE8597C11F6B778330835B0093EFCAA28F4511B97EC2B26B06BFBB229903ED9893C4FB929BBFEA +D2ED1477 +0D01029E72EC4271391DF278C4 +6A4F26DEA2B7FDC1EB3981D9B6E129C1104031B085B6E06F82C84791E19A5F1F43D08773E26EB7565DE40BB474B2E7BA154270E29A47D1189C9D51BE38BC4268C19B626D7F18062C03E32D4443D42C17F3E7C2BF8934DA1DC8559F81 +7D001D93 +DE44CFDEE5E5A66E1CBE88B207BD +EAD9C0073D48B84C +ABBD1DD2 +9296E74545A9B70F5BAD34E484DD1AA25DDF67A8A08409BF0F1019CE0DE3F8A90F3A +C9D62BD40EA98858615EB3AFA127074E8C15782B0AD9EBA5DC042A92F2542AEA413BF8F06C7F +A296F7837FFF9E103C0EB8B484A713EB40CB59B36080E946099F27 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +%Defining font PSOwstdutchi +%!FontType1-1.0: PSOwstdutchi +10 dict begin +/FontName /PSOwstdutchi def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001000 0 0 0.001000 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 1 /C0097 put +dup 2 /C0099 put +dup 3 /C0100 put +dup 4 /C0101 put +dup 5 /C0105 put +dup 6 /C0108 put +dup 7 /C0112 put +dup 8 /C0115 put +dup 9 /C0116 put +dup 10 /C0122 put +readonly def +/FontBBox [-144 -227 513 728] readonly def +currentdict end +currentfile eexec +D9D66F633B846A989B9974B0179FC6CC445BC7C8A959A39A32E9DCE7FAEF17EE3BEC9F +50E1A6FCA651FC4B3769A0A91041557502E25A5D6180FE25A3D11BF079E1DF66E54EE9B7C229AF891739707A2A0EC140306B5E43E52B79BFB89E459E50 +6EC6F610A70775A31C460976C4F79449D86E57ACE491E5C6BF20CC4307B1DAF7630252 +E9AF8CFB69B50EDAE9D36A6104AFEF8832F920FD2346B2C7104CD11E3BEE999CFA9F5A +49DB3173EE48D1C82994237F360407B022E0B4 +502E94EA8B493651EF2D03F0B513D655047568325B512AE6 +6AC6F53F3848CF70DE25481CC65D8B1A5793AA +3C4282D111112BEE28AFCA7A3808D4444C4669CA +84EAAAF989219F51AB3476A1B0B5F2246BC306E6 +625C6679C417ED2A8E9BD010DE37D40265074C268425D1309D17F31B1F9C00C372EEE61BDCAA94 +722ED7F5FA19B18DE53144B3B19D +36FF290BC1B65AEB29D817AB2D8434F2F92B33D00CF510E6D20E00A151499A809B832F241A5AA5170C1C93FF855205CB9E36E1007A066D77759217685FBB0C957B27835CB8B3906A5F9D69114D7C741AC5BD8278D0E5C1D37F796308B04F551F700E91CA2E5D8ACFE60F612B252E9B9CDA395040818A573615B1D49D95F2 +A56F +FFD49763891B71ADBE7A658EFC +6E3717B1 +FFE8790265EF9C6AF3D4BDE288 +86E9CC71D69602354EC595B930C9E69D05DE9013E10BD1BF4E70AAEAE13AC8507A9C861BF94D6FDD16A5E58F4DE19055A9A6756F2FF029A99660ACD430618A0BA273F8A3E8C8AFAD14A0502F5D89FFDFA8F086F55592D18C924B59FD1C5A4AEB +FD1BEB04 +A9E445A1937F5865D92741BB2A5F +77E281FF537F5FF7355ED6705006989425178636F162A7D50FA38628D27ADD4AF8DD3620F4F36CC034E76FC7BC055BEED109EFF0DC8665FC797D8D482F327942FD3934C7D98F723901113D8DEE101D7F388AB23B9A8F0F4F94861E821AD7648ED3867717A2EDA938B86CB32807D74F33CF59477D4B9BC31C953BDC578663 +7939 +92EDE3F1B007D1899C444F77808ACC9CF4E3CBC8D2CF068BC793C5F43F2C8E862C2D6D29FDE493D8C3530A91C617A022 +83224C04 +66F71C37FB5CEB957372738EB12D +A190F7B7DE9989E761119F9EE12FB8C674AB3C03643767BCD0F87246B52CCD610D774F3057ADD7F6B14E005CD1B0A704E0FC25AC9782225C368C0DDE3884DF43475DEFE7FDC22B878F1A7D13551581094BA759CAB8391BFDEA7A25BB2685CCC008C51C1947 +10795D00 +C7498487A3D5048D36D503CCED88 +5841ECE7E5AA56B9BD0FC7092857BC7E155D64976FF1DAADD9E0F2B743E4855587064E429C6A757B1E4F36A43EDA879F09E1752B7F864D9F1227234CC2B753E10F7D1FA9218B467E8E0CB5A8B5BE0935DBA2410D9FF3834EC18CF33BBC81A2FBBC2EA11357A6A6B41ECAB3E1D1988A26E664598EAB938D455F +0FF57B34 +A7F65529D21173E4A762CCA91A17 +36D459502C50A0D295303B1CC6A4403B599C821C5117285DAC71332641C133C3C94684827FE5634CED5A1D133C4195E348A1B468164B07BA09D9AF82FF7F360F54D06F70DAB63336393BD90BB5A6A4C008DBD20D43068B4295A585E9E3D1DE2C0E8AA3DC7F +B30FE868 +A72ABD95B96AF3F52AC0E3561BDF +F8913638A84E8AED2DAE7502C8E58FDBB6EF800995C567C52FBE3A0EFE34D3EFCF9E016AFED19EAF39883E05B0C3C546BE63242E4E6489362058A7ACADB3A914CBAA999DB97615BC1CD67B79AF3CFCA60B52CD054806907DACB9A7CC9AF3CA2CAB487344BC8F7DAE3D1104DAF75209C363BADE6D5E0C3F50863DAB0B217C +26EF +10BA015F98F4C4D33637C907DBD2C4065FA2600C5DE7ECFA270681B12D7767A40485949F6F4FECA11D76 +A64F8D7A +1DC4104306FC92CB40F33594AFE8 +3C605102A17A3B1ABCE3ADDAA0A74C7EFD575380BD18E8AA57CD715450F993B5D9DB435770D16ABCEF27EB8B285E6ED41CD7707C4000FCFA5C1A85DFB00819D612866E3C936FF02E40B880827468A335FB7FACEED7701AC06B4521B4AA0DDC039F8AC7C72A03D3FD20B52796C4FDEFD692EEB66CEB99 +2DE3A22D +D30489A6FA2997ADE08F51F51F +7358CF4B0EED9294436AAA4C609D2AE1DD4335C4CE76A46CA0A98FEB864C350D67F5168D406D5397BC7C9D26A3DCC35B3949315B78663CFD085F16A5CDC771A4ECE3BD6B407717C8E84044812BE589A655AA06BCB7CB08 +3C922B37 +97D911D6EDC48AD2C5419826D9CC +D763F5BAF44EDAADCB3201012012D6182E384A6CE910BACBF99CE50825B9A3C66906737DB01DAB50731BAEA13037524B0121442736F95014BBAADD3324C9BDDA8AED86E802A5819190D5B292638ADE571F750D0B002CE1FC77627A16256A9BD43270F285FD471E2110BCB48AEF6AF479F74A70E22499ACFD71DF20A83492 +C3DF +9895475D92F0374154 +961AA661 +6D4F2D086BB461FDADF52584F6DA +9923AB7499FB5432 +7E682A31 +9FA4FF3E2DA5A9580EEB03048AD96311CC765E1E294AFE15554C1FFCC080BAE37D4A +7B27E37B46862423985FB9D9555EBA7B97FF19F3C2F68F9C9600FF12A973ABB3E10B8F38DE49 +7F08DA2360FB5F1ED1822613CB69B43486F87F17080FDE52902955 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +%Defining font PSOsymclas +%!FontType1-1.0: PSOsymclas +10 dict begin +/FontName /PSOsymclas def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001000 0 0 0.001000 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 1 /C0069 put +dup 2 /C0083 put +readonly def +/FontBBox [50 45 775 713] readonly def +currentdict end +currentfile eexec +D9D66F633B846A989B9974B0179FC6CC445BC7C8A959A39A32E9DCE7FAEF17EE3BEC9F +50E1A6FCA651FC4B3769A0A91041557502E25A5D6180FE25A3D11BF079E1DF66E54EE9B7C229AF891739707A2A0EC140306B5E43E52B79BFB89E459E50 +6EC6F610A70775A31C460976C4F79449D86E57ACE491E5C6BF20CC4307B1DAF7630252 +E9AF8CFB69B50EDAE9D36A6104AFEF8832F920FD2346B2C7104CD11E3BEE999CFA9F5A +49DB3173EE48D1C82994237F360407B022E0B4 +502E94EA8B493651EF2D03F0B513D655047568325B512AE6 +6AC6F53F3848CF70DE25481CC65D8B1A5793AA +3C4282D111112BEE28AFCA7A3808D4444C4669CA +84EAAAF989219F51AB3476A1B0B5F2246BC306E6 +625C6679C417ED2A8E9BD010DE37D40265074C2684275DD89A8790EAD18EFC77D3FFAE84DA5D +312074C4D542DD5BEC70968F75DC +250C3954E8DFB8F4857BFEF092EBA49D248955A858C5A5F55F7B987EA06EC8428D939084C88F5B157D80AB2D706A7EB936C3429173588D2ABA6A27DC94C0B484F316663555797004CBFA79E7B8545C810BF9CA92F61ABD9E202ED9E95943DF7A5ABBF3C20BDE3B6EEC9C0B95A4C9C1D38AA7C6786ADBBB79EE183BDDF194 +1953 +6449DBB7AE47E9FC6F3ABF1DCD7A1E274E87DAE9 +A22737FA +6404B215A27BFAF6D0B50E94D2 +07123A5BB380C86DB5033EE743181BBFCC0356571F7297A207C23F1E588257FDEF5DF229 +CABF3B3C +9E0988C63B358ACA4B4FEB033DFB +E2E387A06A23CACA +8E104B90 +DFDBD41F063E8A8DFA0ABA4DD7443015526AE5255315597779E04D85849305EA4F31 +5CDAD06E5841E1B8074760C99702B8CF443D752174D996C94E690797A9587CF5017DEB11E5FE +02576E9E08B39688BBE99A186AA8FC7E222F5E52B29A7FDF379EF5 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +/DPIx 1270 def /DPIy 1270 def +72 DPIx div 72 DPIy div neg scale +0 -13970 translate +1.00 1.00 scale +/wst:dutch12 12.00 /PSOwstdutch newFont def +/sym:clas12 12.00 /PSOsymclas newFont def +/wst:dutch12b 12.00 /PSOwstdutchb newFont def +/wst:dutch12i 12.00 /PSOwstdutchi newFont def +/wst:dutch14b 14.00 /PSOwstdutchb newFont def +/wst:dutch10 10.00 /PSOwstdutch newFont def +/wst:dutch14 14.00 /PSOwstdutch newFont def +%%IncludeResource: font Helvetica +/wst:helvps10 10.00 /Helvetica /wst:helvps ILEncoding 0 declareNFont def +/sym:clas10 10.00 /PSOsymclas newFont def +%%EndPageSetup +GS +0 13978 10801 13978 10801 0 0 0 clp +wst:dutch14 SF +0.00 0.00 0.00 1.00 setcmykcolor +<222e3c382e3a2f14011701182e362c31352a3a33012f373a01212e2a3b3d3a32363001222e3c3f373a330123> 2207 558 0 7384 -1 s +<2e3a2f373a352a362c2e> 7375 558 0 8593 -1 s +wst:dutch10 SF +<0d> 9434 13385 0 9522 -1 s +wst:helvps10 SF +<4e6574706572663a> 1322 13267 0 1949 -1 s +<205265766973696f6e20322e313b20436f7079726967687420> 1949 13267 4 3868 32 s +sym:clas10 SF +<01> 3868 13267 0 4019 -1 s +wst:helvps10 SF +<2031393933b131393935204865776c657474b15061636b61726420436f6d70616e79> 4019 13267 3 7133 32 s +wst:dutch14b SF +<090f0d17111413> 1271 1458 0 2055 -1 s +<0003020006131715140e180d17111413> 2055 1458 2 3718 0 s +wst:dutch12 SF +<222e3c382e3a2f00323b002a> 1271 2021 2 2350 0 s +<002b2e362c31352a3a33> 2350 2021 1 3427 0 s +<003c312a3c002c2a36002b2e003d3b2e2d003c3700352e2a3b3d3a2e003e2a3a32373d3b002a3b382e2c3c3b00372f00362e3c3f373a3332363000382e3a2f373a> 3427 2021 11 9461 0 s +<44> 9461 2021 0 9531 -1 s +<352a362c2e08> 1271 2266 0 1917 -1 s +<001f3c3b00383a32352a3a41002f372c3d3b00323b003736002b3d3433002d2a3c2a003c3a2a363b2f2e3a002a362d003a2e393d2e3b3c093a2e3b3837363b2e00382e3a2f373a352a362c2e003d3b323630002e32> 1917 2266 13 9461 0 s +<44> 9461 2266 0 9531 -1 s +<3c312e3a> 1271 2510 0 1642 -1 s +<0025192300373a00261a23002a362d003c312e00182e3a332e342e410024372c332e3c3b0032363c2e3a2f2a2c2e080025312e3a2e002a3a2e0037383c3237362a34003c2e3b3c3b002a3e2a32342a2b342e003c37> 1642 2510 14 9531 0 s +<352e2a3b3d3a2e> 1271 2755 0 2038 -1 s +<003c312e00382e3a2f373a352a362c2e00372f001a20231f060026363240001a37352a32360024372c332e3c3b06003c312e001c> 2038 2755 9 6852 0 s +<373a2e0017> 6844 2755 1 7338 0 s +<2521> 7318 2755 0 7658 -1 s +<0017231f002a362d003c312e001e23001e3223> 7658 2755 5 9461 0 s +<44> 9461 2755 0 9531 -1 s +<231f> 1271 3000 0 1480 -1 s +<002020170032363c2e3a2f2a2c2e08> 1480 3000 2 2876 0 s +<2531323b> 1271 3329 0 1665 -1 s +<003c373734> 1665 3329 1 2064 0 s +<00323b00352a32363c2a32362e2d002a362d0032362f373a352a343441003b3d3838373a3c2e2d002b41003c312e001f221a00222e3c3f373a333236300023> 2064 3329 10 7909 0 s +<2e3a2f373a352a362c2e0025> 7901 3329 1 9125 0 s +<2e2a3508> 9094 3329 0 9531 -1 s +<1f3c> 1271 3574 0 1421 -1 s +<00323b00> 1421 3574 2 1662 0 s +wst:dutch12b SF +<07080a> 1662 3574 0 2118 -1 s +wst:dutch12 SF +<003b3d3838373a3c2e2d003e322a002a364100372f003c312e> 2118 3574 5 4340 0 s +<0036373a352a34001e2e3f342e3c3c0723> 4340 3574 2 6119 0 s +<2a2c332a3a2d003b3d3838373a3c002c312a36362e343b080028> 6111 3574 3 8572 0 s +<373d002a3a2e002f3a2e2e> 8546 3574 2 9531 0 s +<3c37> 1271 3819 0 1456 -1 s +<00352a332e002e36312a362c2e352e363c3b002a362d0035372d322f322c2a3c3237363b003c37003c31323b003c37373408> 1456 3819 7 6110 0 s +<2531323b002d372c3d352e363c00323b00373a302a3632422e2d00043437373b2e3441050032363c37003b2e3e2e3a2a34003b2e2c3c3237363b002a3b002f373434373f3b14> 1271 4147 9 7464 0 s +sym:clas12 SF +<02> 1271 4476 0 1359 -1 s +wst:dutch12 SF +<242e2c3c323736000b0800323b003f312a3c0041373d002a3a2e003a2e2a2d323630003a3230313c0036373f08> 1589 4476 8 5574 0 s +sym:clas12 SF +<02> 1271 4805 0 1359 -1 s +wst:dutch12 SF +<242e2c3c323736> 1589 4805 0 2262 -1 s +<000c08002d2e3b2c3a322b2e3b0031373f> 2262 4805 3 3776 0 s +<003c3700302e3c003c312e00362e3c382e3a2f002b323c3b002a362d0031373f003c37003b2e3c073d380041373d3a003b413b3c2e35003c37003a3d36> 3776 4805 13 9213 0 s +<362e3c382e3a2f08> 1589 5050 0 2304 -1 s +<001f3c002a343b37002d2e3b2c3a322b2e3b002a003b323538342e003f2a41003c37003e2e3a322f41003c312a3c003c312e0032363b3c2a34342a3c32373600312a3b002b2e2e36003b3d2c2c2e3b3b2f3d3408> 2304 5050 14 9213 0 s +sym:clas12 SF +<02> 1271 5378 0 1359 -1 s +wst:dutch12 SF +<242e2c3c323736> 1589 5378 0 2262 -1 s +<000d08002d2e3b2c3a322b2e3b003c312e002d2e3b32303600372f00362e3c382e3a2f08> 2262 5378 6 5342 0 s +sym:clas12 SF +<02> 1271 5707 0 1359 -1 s +wst:dutch12 SF +<242e2c3c323736> 1589 5707 0 2262 -1 s +<000e08002d2e3b2c3a322b2e3b00362e3c382e3a2f> 2262 5707 3 4048 0 s +<033b002b3d3433002d2a3c2a> 4060 5707 2 5074 0 s +<003c3a2a363b2f2e3a003c2e3b3c3b002a362d003c312e323a002c3735352a362d003432362e0037383c3237363b08> 5074 5707 7 9213 0 s +sym:clas12 SF +<02> 1271 6035 0 1359 -1 s +wst:dutch12 SF +<242e2c3c323736> 1589 6035 0 2262 -1 s +<000f08002d2e3b2c3a322b2e3b00362e3c382e3a2f> 2262 6035 3 4075 0 s +<033b003a2e393d2e3b3c073a2e3b3837363b2e003c2e3b3c3b002a362d003c312e323a002c3735352a362d0037383c3237363b08> 4087 6035 6 8979 0 s +sym:clas12 SF +<02> 1271 6364 0 1359 -1 s +wst:dutch12 SF +<242e2c3c323736> 1589 6364 0 2262 -1 s +<001008002d2e3b2c3a322b2e3b003b37352e> 2262 6364 3 3817 0 s +<00372f003c312e003b3d3838373a3c323630003c2e3b3c003c41382e3b00372f00362e3c382e3a2f002a362d003c312e323a002c3735352a362d003432362e> 3817 6364 11 9213 0 s +<37383c3237363b08> 1589 6609 0 2314 -1 s +sym:clas12 SF +<02> 1271 6938 0 1359 -1 s +wst:dutch12 SF +<242e2c3c323736> 1589 6938 0 2262 -1 s +<00110800383a373e322d2e3b002a002d2e3b2c3a32383c32373600372f003c312e003034372b2a34002c3735352a362d073432362e0037383c3237363b002f373a00362e3c382e3a2f08> 2262 6938 11 8978 0 s +sym:clas12 SF +<02> 1271 7266 0 1359 -1 s +wst:dutch12 SF +<242e2c3c32373600120800383a373e322d2e3b003b37352e002e402a3538342e3b00372f00362e3c382e3a2f003d3b2a302e08> 1589 7266 7 6286 0 s +sym:clas12 SF +<02> 1271 7595 0 1359 -1 s +wst:dutch12 SF +<242e2c3c3237360013080034323b3c3b003c312e002c312a36302e3b002a362d002f32402e3b003236003c31323b003a2e3e323b32373600372f00362e3c382e3a2f08> 1589 7595 11 7215 0 s +sym:clas12 SF +<02> 1271 7924 0 1359 -1 s +wst:dutch12 SF +<242e2c3c323736000b0a080034323b3c3b003b2e3e2e3a2a34003336373f3600383a372b342e353b003f323c31003c31323b003a2e3e323b32373600372f00362e3c382e3a2f08> 1589 7924 10 7802 0 s +sym:clas12 SF +<02> 1271 8252 0 1359 -1 s +wst:dutch12 SF +<242e2c3c323736000b0b0800383a373e322d2e3b003b37352e003c3a373d2b342e3b3137373c323630002a3b3b323b3c2a362c2e08> 1589 8252 5 6417 0 s +<27> 1271 8581 0 1480 -1 s +<2e003c312a36330041373d003236002a2d3e2a362c2e002f373a0041373d3a002c3735352e363c3b06002a362d003137382e003c312a3c0041373d002f32362d003c31323b003c373734003d3b2e2f3d3408> 1463 8581 15 8890 0 s +<25312e00352a32363c2a32362e3a3b00372f00362e3c382e3a2f08> 1271 8910 3 3759 0 s +<29291e373f002f2a3b3c00323b00323c16001f3c033b003b37002f2a3b3c06003c312a3c000808080200150705> 1271 9238 9 4774 0 s +wst:dutch12b SF +<041413190f131711141316000b130e00050f101113111711141316> 1271 9682 2 3877 0 s +wst:dutch12 SF +<28> 1271 10074 0 1433 -1 s +<373d> 1407 10074 0 1639 -1 s +<00352a410036373c002b2e002f2a353234322a3a003f323c31003b37352e00372f003c312e002c37363e2e363c3237363b002a362d002d2e2f3236323c3237363b003d3b2e2d002b41003c31323b002d372c3d352e363c08> 1639 10074 15 9531 0 s +<1d2e362e3a2a34344106> 1271 10318 0 2219 -1 s +<00323c2e353b00372f00382a3a3c322c3d342a3a00323538373a3c2a362c2e06002c3735352a362d003432362e0037383c3237363b06002a362d002c3735352a362d3b> 2219 10318 9 8650 0 s +<003f323434002b2e003236> 8650 10318 3 9531 0 s +wst:dutch12b SF +<0c14120e100b0d0f> 1271 10563 0 2035 -1 s +wst:dutch12 SF +<003c41382e08001c32342e362a352e3b002a362d002c3735352a362d003432362e00323c2e353b003a2e393d323a323630003d3b2e3a003b3d2b3b3c323c3d3c323736003f323434002a38382e2a3a003236> 2035 10563 12 9531 0 s +wst:dutch12i SF +<050901060502050a0403> 1271 10808 0 2041 -1 s +wst:dutch12 SF +<003c41382e08> 2041 10808 1 2532 0 s +<1700> 1271 11137 1 1488 0 s +wst:dutch12i SF +<08050a0408070402> 1488 11137 0 2167 -1 s +wst:dutch12 SF +<00323b002a0037362e00373a003c3f3700323c2e350034323b3c00382a3b3b2e2d003f323c31002a002c3735352a362d003432362e0037383c323736003c312a3c002c2a36003b2e3c003c312e003e2a343d2e> 2167 11137 18 9531 0 s +<372f> 1271 11382 0 1457 -1 s +<0037362e00373a003c3f3700362e3c382e3a2f00382a3a2a352e3c2e3a3b0800001f2f0041373d003f323b31003c37003b2e3c002b373c3100382a3a2a352e3c2e3a3b003c37003b2e382a3a2a3c2e003e2a343d2e3b0600323c2e353b> 1457 11382 17 9531 0 s +<3b31373d342d> 1271 11627 0 1874 -1 s +<002b2e003b2e382a3a2a3c2e2d002b41002a002c3735352a0007001b30002929382a3a350b06382a3a350c0208001f2f0041373d003f323b31003c37003b2e3c003c312e002f323a3b3c00382a3a2a352e3c2e3a> 1874 11627 16 9531 0 s +<3f323c31373d3c002a343c2e3a323630003c312e003e2a343d2e00372f003c312e003b2e2c37362d060041373d003b31373d342d002f373434373f003c312e002f323a3b3c00323c2e35003f323c31002a002c3735352a0007001b30> 1271 11871 17 9531 0 s +<2929382a3a350b060208> 1271 12116 0 2164 -1 s +<002032332e3f323b2e0600383a2e2c2e2d2e003c312e00323c2e35003f323c31002a002c3735352a00322f0041373d003f323b31003c37003b2e3c0037363441003c312e003b2e2c37362d00382a3a2a352e> 2164 12116 16 9461 0 s +<44> 9461 12116 0 9531 -1 s +<3c2e3a> 1271 12361 0 1526 -1 s +<0007001b30004306382a3a350c020800173600323c2e35003f323c31373d3c> 1526 12361 6 4512 0 s +<002a002c3735352a003f323434003b2e3c002b373c3100382a3a2a352e3c2e3a3b08002531323b00342a3b3c0035372d2e00323b003c312e> 4512 12361 11 9531 0 s +<37362e> 1271 12606 0 1608 -1 s +<0035373b3c002f3a2e393d2e363c3441003d3b2e2d08> 1608 12606 3 3608 0 s +GR +eop +%%PageTrailer +%%PageResources: font Helvetica +%%PageProcessColors: Black +%%PageCustomColors: +%%Page: (4) 4 +%%PageResources: (atend) +%%PageProcessColors: (atend) +%%PageCustomColors: (atend) +%%BeginPageSetup +bop +%Defining font PSOwstdutch +%!FontType1-1.0: PSOwstdutch +10 dict begin +/FontName /PSOwstdutch def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001000 0 0 0.001000 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 1 /C0032 put +dup 2 /C0034 put +dup 3 /C0040 put +dup 4 /C0041 put +dup 5 /C0044 put +dup 6 /C0045 put +dup 7 /C0046 put +dup 8 /C0047 put +dup 9 /C0048 put +dup 10 /C0049 put +dup 11 /C0050 put +dup 12 /C0052 put +dup 13 /C0058 put +dup 14 /C0065 put +dup 15 /C0066 put +dup 16 /C0067 put +dup 17 /C0069 put +dup 18 /C0071 put +dup 19 /C0073 put +dup 20 /C0077 put +dup 21 /C0078 put +dup 22 /C0080 put +dup 23 /C0082 put +dup 24 /C0083 put +dup 25 /C0084 put +dup 26 /C0095 put +dup 27 /C0096 put +dup 28 /C0097 put +dup 29 /C0098 put +dup 30 /C0099 put +dup 31 /C0100 put +dup 32 /C0101 put +dup 33 /C0102 put +dup 34 /C0103 put +dup 35 /C0104 put +dup 36 /C0105 put +dup 37 /C0107 put +dup 38 /C0108 put +dup 39 /C0109 put +dup 40 /C0110 put +dup 41 /C0111 put +dup 42 /C0112 put +dup 43 /C0114 put +dup 44 /C0115 put +dup 45 /C0116 put +dup 46 /C0117 put +dup 47 /C0118 put +dup 48 /C0119 put +dup 49 /C0120 put +dup 50 /C0121 put +dup 51 /C0122 put +readonly def +/FontBBox [-25 -256 920 739] readonly def +currentdict end +currentfile eexec +D9D66F633B846A989B9974B0179FC6CC445BC7C8A959A39A32E9DCE7FAEF17EE3BEC9F +50E1A6FCA651FC4B3769A0A91041557502E25A5D6180FE25A3D11BF079E1DF66E54EE9B7C229AF891739707A2A0EC140306B5E43E52B79BFB89E459E50 +6EC6F610A70775A31C460976C4F79449D86E57ACE491E5C6BF20CC4307B1DAF7630252 +E9AF8CFB69B50EDAE9D36A6104AFEF8832F920FD2346B2C7104CD11E3BEE999CFA9F5A +49DB3173EE48D1C82994237F360407B022E0B4 +502E94EA8B493651EF2D03F0B513D655047568325B512AE6 +6AC6F53F3848CF70DE25481CC65D8B1A5793AA +3C4282D111112BEE28AFCA7A3808D4444C4669CA +84EAAAF989219F51AB3476A1B0B5F2246BC306E6 +625C6679C417ED2A8E9BD010DE37D40265074C2684219565F66AB74CD7DBC8621179B209E1B7D7 +DBDEFDE447C11C429FD272CE +6A23BADE7C3E6E2917 +CDBA180E +1D4521A443FF567762EB5199C717 +C8C05CC43DA3C8A67EDDE4B0591451A5529C9F7D872F70FBB41A95DBF76B42B5166775AA384F9E4EDC71C7F72FEAD15832540AF586F17EBED52157899180D1AAE39775B4B5BC1199A65BC43A6F26C9E011EB4C48F94C9F451209EE6211FB8B2BFFB89E236C2E83 +862A322A +73850B28CA74F38F90C2946D5B +9FD8DECF590381BC318A5F3088A6B1620B19A86CD20ADC2DCBF8091F12BDAA07AA79916014F9EA295CA0E60D937B0857A51B3B40FB30F9DF3F6C28A4D281AAF0 +4642954C +360289AB62E0F91906E4D8EC13 +C0B542DBF5F3164A477F53D8AF895BFB151AF9331223F01ACC958F26366AC3E9A2F70D989156D6354C2A2806DC1F898BDEE996B0AB32B1A98FFAD9A275D3DB +B2057F72 +6F37EA705794F55682092C9ABE +53C544DEBFE59BB84B09EA5052FAC2C23D63A898A6BDF9905203D75386E283EFD585418FB9FDDC6C1600A884D39450B7B78A2E8C0B39930A32 +AE101DFE +D04249F02B9C10025EA8B1E1C2 +D6AB922783ABEEBD8E49F3A3B99800E8C87184E2201014 +2EC4AAE0 +4D73D9BDFE6906549E700512C5 +8E83F41CDE09BFE578D5E1CF8EC73383D9129BE9301069DA22939F4B9EE9DD +3D06E333 +9424EF5D91D1405992A5E0313B +E509548C0626C6CE1F682438B986A27F8F0C08F6195A7F606C8637FB +109AAEB6 +795019E7B3CE6641B5759C59A2 +CB5645DEA64C4AE2967228D43A48A7969CC90214634B0BD6EA612FBE01691B6FF3C1BFEB35ED2388E7A64604F4D5E3168F8F395EB0FB7738DBFD6790E8D6AA85D454C9A87E319834F9FD +50BF435F +C8E72B5E493642336170B47D01 +CEA50E0DBB2462824DA2FF3AE94F2273D5F94D1BF211306DB07331F4B528427D3B1DA1B3C44CC5DC6FFDDEF7EDCC7D9681B6DC494BF2DA3BECAF5587EBF051 +77BD0E58 +57C78FC9D1BBB63C659F9F4E94 +FBD66E7CBCDADB6E87C649C4209C421339FD0FBB3F15BB7E7DFD21728EF70C53AB12C18450E7DF9035FAC7D6E2DE0649918D73DD913F2A3768A19133F2E35E49931F6119D3E5AD87470F52DC6E2996C43EE4F55E876102039038 +634F1B08 +5D350520ED90DEDF99DF0196EA +4BCB09F0B6C478A03F78A6AB212B5881D4A8044A17B12085D7515D1B742E635AD6313EF848BE4B2401E5A6254AB604D544CDA2842AB2F9A3799A +96964347 +A6D37DAA2A4D5CF7685628A879 +49CD0D4D42CBDA18236AE904DBB5B90F8134C7A76789304BC2EF7755C12186B39C1A3312708F7CC8DCB01579EE66F207D7CC73457FA8 +4A77658A +B8001C0B0EFF4A225B05B6C07BFB +23791A595ACBDB59A4B56DDC58DA876252E62C591D3BAA65CC9C99CC1DD24D9B600BCACCF7351FDBFC08136090AEC0CC33279ED61D38EE52AC138ACF4287EDE6FB9B33A70BF0B30208D1A5541470F10B78F4EB6541252061714A5A6D3E5185B6F9F624914D722AFB50EA5B0C711A240F7BC94F +684A7F57 +A92D26B914A40F3BB6B3459DD05E +EEA240F0CF9072D19C20882833E7D7E34263AFAA7CEF7AF33509B88CAEC8CA9FF8EB2CD34D80DE9E3ED207C587EC016391FF81D05D1D89023A61C615FC2DB6B041861613B5C120CFED2B9BAF62427896478FB3F3A5DB118B3166CD1394779BF9EC495C69A73EC58CD341DDD9044F1A665CDB348CB6216646A942993FAAFE +0CE5 +E2 +EA4B38E5 +935A453D449B7CB5B1D4677A6D +2AED73408E2E7CE4FF9122CC7474E08163408E14383C22FF132E19A27BAE30689DB94A09CD756D54ADA51E4CEE47471230F8D35B1CA9B93901773159D0EBC93A3E3EFE78CDE03E6FD6B490BAF331FC04265ED6611770F9246CE647E54C6BAAAA54 +CA0A0B77 +5F16EA0B47E472DE554602548AA3 +3E45BC277DC6D6AF76127913C9AA1A9753FBB69A4C084E5B2A110C94A985E2C1C4C75A2659F0D3F7E2BDB95381247CDA87F6B84B2F7560A27E21540F1AE3B6000848B58A72117273A38D6583ABF180B9D25C71D829B60BC99459CB89F7F8EE5D46DACECD50125FFA8F6324BAF2F52E2A156EC127C5873575CD4AB49DDE0A +2811DB12 +4FD08262911D0B01DD0349444EEE +34A923569A75233D63B725D2C3F160E2631A2E945E59AC7C65840E8902BCBD59BF5A20AC3248818012F2EF1E33CC89E4CB90467C6DB911E5B88FF5192AB71B60A532A391C960C531DD5A76D9ABE1DFC71951FE9B3FAFED31618ADD8212A90B71B77756A103496F06690FF5B80AB41AAAD2EE34E9952194A3D59F +3114AD7C +8D6712E6474337BEFD56C524E1 +5C7E5DD0BAAF34276C9561485377B7A1EEDE0222F2A7CA6CE0113B6D2118880AE600A4442AE6267472B2219AC0F65975337B0CF54ADE938E8B4071 +F0CAA80E +9BD048E778D602B23DB0109E5B29 +1B20B85736EDEFBAA6DC59602C5798CED2A08191A716B47330BD7F3431E4ECC83D6A74C455A50ED9997CFC51CBCD892C4C2711BE62BAAAE570A4AB16CB0A8273F55FAC55BB403F3523FBE3F1F56A60DB9129C422C08186ECC5DC07B88CE56FFC03BA761881ED0E9B9109FF66E74052 +19B365CE +5BFB7A9AB8D75E1DF17E9FDF6F +F3A0842C07F45A5FA1BD31EEB4DD5715A42C8391D4D5DEB78B2B07D9FAC54D75F3A543B189F2530C6B75B96F293C99DCCCDFC2F381F90A8DE0788F4C54065B4D1BA5507614B38C7AA0A5A1FAA3FB18EE70B0D629EFA6B14480FF55C4 +8944B400 +19BDB0B6A6437E37EBB8930A8833 +5101F1276870A58F8BE742BC3D254A2DB2BA9DF7766EAFC23C87CF630136491CFC40B472C756908D5689F6E49278250F5BF267617CC1A7D16309F7061DC7D4D2FBC97CC03C4484E903BEE5FB5DFB41BBEF228225D93D8AF799789803A5CEA500FEB803B372284BCE5CA6 +5BC593E6 +E69FE740F29F86F17C415C26A601 +78B8E8F8B857BC14BBE115F5FA89BADEA35FEEA0BC3BDB452B0B49C73E0FDB8BB367CF30D86F9FE26D93D9DDB8419761F8C075E1EFD47573307E0A2401F5E758EC0AB30680FB45A3EC038D000C22BA4D1A65EA74610EFFFC5BFC5ED46DA53E748E206A764729B7AA39C6AF4724893D21F4A40FC8A6ACBEE59D9B994817A0 +3B6CFFAE +3E97F7DEAC482B33942D764A66C7 +D6AEE897BACC45E3E635C0C84C5E2D79551A856721F1CD64ED5C62FC43C2A3526F1C5BF039A9B35FD187A7E50811004ED7AC093E32F0CB1B46A43E71268EC74EA414A0164FBF06C58130BB0714F6293A64FE35D8386BC027664265918BC7DBEF2A5E6173B40DD6A9891AE7CCA0AFB5C6DF2575401B95174CC94CF84A4A29 +9C73 +CB43E4 +B81EA595 +51A3F85790A9D87F093F112C54 +B15F6B8F009904A3E2EE2BC48D4F9F023E567C1CC874CAB62662DED944AEA74A5C5D79D9E976FFE171B2E7A13A5CFF6CFD3ECF52C37EB2ACB58817DA9A1C4FA83C102F58892C6A2A0DBE6C2C0703173FFA +41E0C894 +B14EBAEE3C5AA74B00F17A4C84 +ED0BF61A1907DFFF0A2BE300C1B2593D8E5BAB63F752 +804F96BC +28919A267CDCBE955958FC6EAE +7BCBA2D6CF3C923CC74E9E7C3E1BB8575C3BCF29A69A71D7698FA1EB0B67C9F68B2955348F06482F797B142CF2B1C7E1C970F394AF7A10395B06 +3386CFBB +2ED348166F284EA583089B0BD14E +D17ED6CB0CC6C9C1F2CD96AAC3C5E57BB61659F8AA32B1E19E36B2C23BF9FB9DEF41C5021F72ED825C333A233EAC20734424CEAABE99C2F0DCE521475A798A361DAF6ECD5B0813D9A39B9167D9C02771E442952D08914E4F1FF390ACA8B4D5529E4221E0F561EC111D93F662476288E51AF61B1504EA58667E753CBC586D +0E66 +8DC2DF +860ED8CB +652AE22D811F72304AF399E09D +4ED56A732E86B8B9E4EA6899B16C3AED4F60C11023475EAA1F39859018AC0192B17E9F6690283422585F92667AC86D8578A8761681B6AE6FF49C43680E958FB0465689D9ED532ABDC96D3FFB1E6812A6B9D13C8E71B361FA +2E599723 +0294A761BAA81EA99627F8B594 +F29CCFDA460FC29D36B00FD2415ED210F0E99362B0F13A03E695ADADCA3235F165205467EF6805129697C4E8AEA4E6EE2A5A7886B4D623AA3BAC7C8F216E94CA917E55B046E529CB17D3BAE041B798025D48 +42261003 +596335B2368F3E9F892B59FC6D52 +EC845BE43F8E7FB72C0359B332806B568D397B17ACEE31AC36F508C605BB0F18886C516D1FD8F040F12C9F940B91292193F40812A9D559526CFC5B8E1349D467A4E114E087C838DAB56442C5E32E4536F42F7FA0BFA4F0D60A124C040E10FFD3E2E12341C3145114F7BB6AA6D879 +0AE5E587 +F798BE0D734249BA39E216DC09 +694D24069F8349B1BB9CBCF9AD28A3A0D52CFCE95FD526B7B52679D8A80BBA7ACECBCBF2AC4443A8078D7DB961A8C706F78AEAC71803CF334C76282857F270B4DDB7715BE73484B4F5EFEDD8A8DB696B1DA6C59C7507629358 +4F974CD1 +B97B12D0DC2AA5467A25524B08 +C70599D51BD9F8ED32471C304D3BB92D05E09A7EBC74F30DBA64229FB22B2404049A149FE83A0B72912C74A237C9A2659DFF115D0517ECEEFED64B943E6F81ED39C1F4491542E653A45C5D8AE07F903B2483E0C2F21016D65753FEC6 +9F912771 +259C3D703EFF81DC72433EC7E447 +4E1925903423AE6775417ABF1E43BD739723C70FD633852123C77C68C3527F83A2A567E4AF60CDAEDADD6FD155B49C7A80AE670659961DE7C2EBEA96D5D4F19532BDBE79D4BA9E7F88DD44D8DDBA241120FE3D8F432CE19319BA86275CEA3A274515F3D303C89154292FE87CA6E7EB7EDEFE52A57AC4FC9161BD052517C6 +47C3 +74079F39DC1CDFF6FCE06A2E4290695DA64DD6237A503D66DBA9614E140EE06BEBA4501974F279E07228EF7F3F40E5 +E4216064 +2E662282F70C916F6B4DBE2105B8 +61FAC6C3780BEE5CB755725BEB7161DADBEC53F79BBB76F4E48F40E56C7DF56E2ECEE844056F62D758AA1D5744CCADAD5265EC2E877A5C4E9861E2F9A5C2C2D89B0181F51EDA478A5D1DE63315BAD87FACA43524BBF7E2D763AE7C0613E9F797ECEEA2B6B72B492BC3CD20E1AD +634CCA91 +D3816C9EC24FA71D8D7182873F +D7866F5F2B71C69DA64CAF61E077E1FDF477A15BCFF743BDDB92BB3EDCF50C9F3860C63DBD52654E455158D6BACFCB80A3706DE482B098DCD973FAB9D4CC28C709F7A02C50F47336FA378B08B38E61F9 +7DDE8ECB +71103F703D54F876763BD89B49C4 +0BB267263F8B42AD76B2175596C20EDB57996EB5C3463197E5382D6919C20A33C49A7F1F7BD5E56D452DA6A140729882E52C24BDCB5C8AD7BE3F60B16810791A2B354F17A3C0C76401703000A2523A8218E7057B416393994E0D85D523911182502349B1CB0DAEFABA85060BF5268F8602ADB506ED930A3D715F1B5AA7AC +AEE1 +35164164B15AAC5D0D416CF3A635A72CE86D49C362F242A172CFE726795D5C055C2000 +1796A400 +06C81FC7EEEB06A3A02C741198 +AF6A356DDCA4940507C729D0E83BB9DDE1393D27DBBAFEE166260DCB1450B7E30E05DA6103F1C545D8C92F1297A4892E66F9C9FCA749 +82043E9F +FE875B56589B3196571A71BD88D6 +C5CD5510FC3C8A686C5FCAFB99D3FC85503EBAD6940D4458050754AB86560B5884DB2B9DF1EE730432A263C9C1353E0467856DA2F16E1009344D1967CCA7717585EE4AF3D7189ECAD2E3D4A039496825CC885508F7358388747CF9AF30973F9C0AE7C6125E6B18B88D3A4F20212DE3CF1DECEF3EDD8CCE7C63C6B0998679 +7C16 +8C661AB46F0389EA89FBF118E11AECCB20EFD832E767581E15F972EEAC8A82 +F3FB7DC9 +083151C30385A317B3B393FAA4D9 +90B61CBA3AD7ACF3E935B96CF5A43A9953414F485713A5584E3BA8DB275CC884F8B3913BAC5A763C5CC710EE41871C37C35360455981B8C16072152A610B43BC6DFC95823D604CE36C93AF5F1AFFE3075679396C66ACBDBEE01B7C75D81AB2CBE553FAC20DFF6E0B2FD5E2C1 +33AE9C4A +2129D2C1E5C6C9DFCCC73264E9 +4622662736DCE286B201F9B082589A253BCB8BED8D9B7AD37E589854205254F84F0EDAC2CD34AB34EE7551535C9C48ABEAE8ADF7CEA06840F40A12DB9F57FD70C8EC78F884C7 +53C56DB4 +2106FA8EA28D98707B39233093AA +FA54FFA594366AD142116DE382AC62804B04B2BE191DD960616BDBDE2519886FED26E3FADE89FA0A5B71ABC477B5CCCF7786DEFA65016C4FE20E363F5404A378438B12A4BF54C2771AE618D7729B07E73FD8C820B7C252F7FAFBD3E9505A9AA8E8AB3ACE7E275A51FF461699F439F55516122528F6F6D0 +DD2EB48A +AAE7C91B88F745B5B78D5B9BAC +0B2865D5E00D5B90B68D92C924B725520FC3868CD2596B25B863EC1C7D4466FFE1F5A0E42B7BC67D9DBE04581355735EBBED620E2DC2F8B8D5F2561D5B29F6FFB66B89D9BD0852AE5EBC94251386776B2D615304453699 +244B7EFE +D4FA60E16F6A07B289DA907B2A19 +150135B738A6307C5D7AA01B43056309E254FC6C08FB8E4581C8CD6497E002AC4D7B54C810580811748A403E53BD4A0351173A30A37A4501778BBD45E4774B8E74BB9B0BE57E627AD3E7DC303D01377ADAF3C481ABF77B9E9B04E9FB69382883B98C4C6981B69BA414849D3F7F2FBD349A1250C282EF4D1430BE7B95 +9A801858 +FD9B250D29FA6573832F796E97 +E492D77B017B5DA6BF5EF65BB07E3A288E9A0A678ED2B4A6A6C7E6D6227C95D7BD83EE38C21589056E4F36D156C596FC81E6E1A0E222F9F9FD4081C0B9854ADC8ED035B326 +C8A12CA4 +F5CD9361A5CF78D109654A5104 +DA36595623E424C7199568BE842CF66F337AA1B094F8FF7627F349411E2961BB1486C3A5B7147E550BF91A7AFB52FE8D67B364BD121D3CEE9A4350E448B9F9BEE45340A26021F609CBADCD674074C06FD9805C3DC83C6E9305A7F1BB355129CC0FD4 +687AFFF5 +E47005977AA6966C380E3C283E +F9BDDA94360706E84A7C10FD8EBFAE1FC4038960F730BB5E85D6890E688DB3FA0211EBFB7AB24C92A90B6A47D80B1CB8D4AEE9D2AEF609BADCA67ABCBFDA7ADE20E9D4F16345A5330AA434A1D6EBDB118019446CDCCDA8A67D +49F80FF5 +62E34FA17E69624DAE8AB113A3E3 +47B57978A2C0131B8C0E6F405833BBD672D4361973BF67A04D5B7CCD032B0AEFC605E78FE931170843A867BBE041F7AA1D7F0607979F397C50327E3E0A395C598F44CAAA0452C76B3385F208956CEBDEA8DADCF57B61557C6C002A0B2BFB311037A7352AEC5493C4955351AA2D722E679E1D1D23A51253A9BA3AFB54FB9D +74B3 +DE30C41F3504AA820C76E16DDEFE +04D81536 +B864704AD12624B6F6B51B179B69 +1DFCBD8186FDCFAD3610B2EFCBF6B01A30633E570BA26B6395E2A495F3E7A3DEF402F387E6A4C1DBF01E107A262A2621198F9704A2792CA205222E1B956750DAB4F193F68EB346B657EC1DCCE261E152B9E199D30FEFCF6D4D3E43659A57DB198E70493C169674473B6A36566270847C022C2968A404A5B976AF7B4727C5 +AB37 +E0466DA967BAF22A08E3DBF6334F511E0216B725E990C8C495 +691B392A +2528805B3CA328883C63CBDC8CAB +B9120CB680A199E447C320ADD4747E3DF10AB8B3466A61E8E1AACC0D897FC15F70DBA950FAF19D104ADD7B76E5BE4FDD240483D511A697F2915B06DFF39799B0D68F56C705D7293FDDB47235B3F7FF04EACC7D6D669214DEEBF90C6992688653120E94B3AD95BC5EE4C739F11978AB67B61D2622E707035BED01748EE31C +837B +57992F4C +D542F9B7B4822E55C033F4D753 +F6CC0F038B159879083A717CDA1D86D0299853C0E103099B077EB40598B7A6F3285894CEC4CB02A9D27B8E3B5CD8DA549309B189A8544EE1DD818C80911B46 +143674CB +53B62A669B23390046BD82F33CA6 +1BC587A593F8BF07 +C9DE0A73 +D0766AB6B8E51DEB715DDEF16290B873199591E37E0552E11420933A430C38217321 +5EF929949C0B0EE89881B4666F9FD27B46F0DAF28C3C786A358E141385FE1C5388F85907E72B +40498A8C3D95F50E499B7C959B6D30DF685D282AAD577EC32D83A2 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +%Defining font PSOsymclas +%!FontType1-1.0: PSOsymclas +10 dict begin +/FontName /PSOsymclas def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001000 0 0 0.001000 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 1 /C0069 put +readonly def +/FontBBox [106 45 775 713] readonly def +currentdict end +currentfile eexec +D9D66F633B846A989B9974B0179FC6CC445BC7C8A959A39A32E9DCE7FAEF17EE3BEC9F +50E1A6FCA651FC4B3769A0A91041557502E25A5D6180FE25A3D11BF079E1DF66E54EE9B7C229AF891739707A2A0EC140306B5E43E52B79BFB89E459E50 +6EC6F610A70775A31C460976C4F79449D86E57ACE491E5C6BF20CC4307B1DAF7630252 +E9AF8CFB69B50EDAE9D36A6104AFEF8832F920FD2346B2C7104CD11E3BEE999CFA9F5A +49DB3173EE48D1C82994237F360407B022E0B4 +502E94EA8B493651EF2D03F0B513D655047568325B512AE6 +6AC6F53F3848CF70DE25481CC65D8B1A5793AA +3C4282D111112BEE28AFCA7A3808D4444C4669CA +84EAAAF989219F51AB3476A1B0B5F2246BC306E6 +625C6679C417ED2A8E9BD010DE37D40265074C2684268F16195489648993B9C4D3B534FA887C +DEF605FA87B991F4D20A8F78DACE +5A54C070E03D5C59D9D2D3E06B09CEE028D68B62AB3AEC43C1DD20BA70D288597D9BD8E06818FF764EBAB436723988E8D7CA59E16D39032516BFC5D552ACDEEC6BE938BEF2F43CFFBC811C3626C4DF5F8CF080676520B51C60CEDAD1FE6C92D1431C702174CE517A8FA9377D075A0B6833DAB101DB65397F1419EF5F0016 +004F +6F0824F9657BB4F1C8F981709956865F6855EFAE +9242AD55 +91BBBEE163D844DDA894E13190C9 +2480439E4C71CADA +BD043A9B +A315CAF72652AA7FE6DB2E84D82A6111CE4DE90C02DA0AFFE2620922262A45AB4ED0 +EEC9F4520DD12703442F7D028D4526BD8B771E09FBE11B2749E2D3906894E8D4BFD3F379F14C +3C874F550606965E22FE487B247B5C2D06728490C8F2A3B588CDFC +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +/DPIx 1270 def /DPIy 1270 def +72 DPIx div 72 DPIy div neg scale +0 -13970 translate +1.00 1.00 scale +/wst:dutch12 12.00 /PSOwstdutch newFont def +/wst:dutch10 10.00 /PSOwstdutch newFont def +/wst:dutch14 14.00 /PSOwstdutch newFont def +%%IncludeResource: font Helvetica +/wst:helvps10 10.00 /Helvetica /wst:helvps ILEncoding 0 declareNFont def +/sym:clas10 10.00 /PSOsymclas newFont def +%%EndPageSetup +GS +0 13978 10801 13978 10801 0 0 0 clp +wst:dutch14 SF +0.00 0.00 0.00 1.00 setcmykcolor +<15202d2a202b210d010e010f20281e23271c2b250121292b0114201c2c2e2b2428220115202d30292b250116> 2207 558 0 7384 -1 s +<202b21292b271c281e20> 7375 558 0 8593 -1 s +wst:dutch10 SF +<0c> 9434 13300 0 9522 -1 s +wst:helvps10 SF +<4e6574706572663a> 1322 13280 0 1949 -1 s +<205265766973696f6e20322e313b20436f7079726967687420> 1949 13280 4 3868 32 s +sym:clas10 SF +<01> 3868 13280 0 4019 -1 s +wst:helvps10 SF +<2031393933b131393935204865776c657474b15061636b61726420436f6d70616e79> 4019 13280 3 7133 32 s +wst:dutch12 SF +<15202d2a202b21> 1271 1431 0 1980 -1 s +<00231c2c002d3029002d322a202c002921001e2927271c281f002624282000292a2d2429282c07> 1980 1431 7 5617 0 s +<001923200021242b2c2d001c2b20002226291d1c26001e2927271c281f002624282000292a2d2429282c07> 5617 1431 7 9531 0 s +<19232032> 1271 1676 0 1726 -1 s +<001c2b2000202c2c20282d241c262632001c283200292a2d242928002d231c2d00242c0028292d002d24201f002d29> 1726 1676 9 5475 0 s +<001c002a1c2b2d241e2e261c2b002d202c2d0500292b00222b292e2a002921002d202c2d2c07000e280020311c272a2620> 5475 1676 9 9531 0 s +<2921> 1271 1921 0 1457 -1 s +<001c002226291d1c26001e2927271c281f002624282000292a2d242928> 1457 1921 5 4167 0 s +<00242c002d2320002d202c2d002d322a200700192320002c201e29281f00292a2d2429282c001c2b20002d202c2d002c2a201e2421241e00292a2d2429282c07> 4167 1921 11 9531 0 s +<1923202c20> 1271 2166 0 1817 -1 s +<001c2b2000292a2d2429282c003023241e23001c2b200029282632001c2a2a26241e1c1d2620002d29001c002a1c2b2d241e2e261c2b> 1817 2166 9 6504 0 s +<002d202c2d07000e280020311c272a2620002921001c002d202c2d002c2a201e2421241e> 6504 2166 7 9531 0 s +<292a2d242928> 1271 2411 0 1862 -1 s +<0030292e261f001d20002d2320002c20281f002c291e25202d001d2e2121202b002c2433200021292b001c001910161a181917110e14002d202c2d07001226291d1c26001e2927271c281f0026242820> 1862 2411 14 9531 0 s +<292a2d2429282c> 1271 2656 0 1943 -1 s +<001c2b20002c2a201e242124201f0021242b2c2d05002d202c2d002c2a201e2421241e002c201e29281f07001923203200272e2c2d001d20002c202a1c2b1c2d201f00212b292700201c1e2300292d23202b001d32> 1943 2656 14 9377 0 s +<001c> 9377 2656 1 9531 0 s +<1b1b060602> 1271 2901 0 1830 -1 s +<00032d3029001f1c2c23202c04070013210032292e0030242c23002d290022242f20002d202c2d002c2a201e2421241e00292a2d2429282c002928263205002d23203200272e2c2d001d20002a2b201e201f201f001d32> 1830 2901 16 9531 0 s +<1b1b06060207> 1271 3146 0 1883 -1 s +<0003111200070828202d2a202b21000606000627000a090b0c04> 1883 3146 5 4532 0 s +GR +eop +%%PageTrailer +%%PageResources: font Helvetica +%%PageProcessColors: Black +%%PageCustomColors: +%%Page: (5) 5 +%%PageResources: (atend) +%%PageProcessColors: (atend) +%%PageCustomColors: (atend) +%%BeginPageSetup +bop +%Defining font PSOwstdutch +%!FontType1-1.0: PSOwstdutch +10 dict begin +/FontName /PSOwstdutch def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001000 0 0 0.001000 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 1 /C0032 put +dup 2 /C0034 put +dup 3 /C0040 put +dup 4 /C0041 put +dup 5 /C0044 put +dup 6 /C0045 put +dup 7 /C0046 put +dup 8 /C0047 put +dup 9 /C0053 put +dup 10 /C0058 put +dup 11 /C0060 put +dup 12 /C0061 put +dup 13 /C0062 put +dup 14 /C0064 put +dup 15 /C0065 put +dup 16 /C0066 put +dup 17 /C0067 put +dup 18 /C0070 put +dup 19 /C0072 put +dup 20 /C0073 put +dup 21 /C0077 put +dup 22 /C0078 put +dup 23 /C0079 put +dup 24 /C0080 put +dup 25 /C0082 put +dup 26 /C0084 put +dup 27 /C0087 put +dup 28 /C0089 put +dup 29 /C0097 put +dup 30 /C0098 put +dup 31 /C0099 put +dup 32 /C0100 put +dup 33 /C0101 put +dup 34 /C0102 put +dup 35 /C0103 put +dup 36 /C0104 put +dup 37 /C0105 put +dup 38 /C0107 put +dup 39 /C0108 put +dup 40 /C0109 put +dup 41 /C0110 put +dup 42 /C0111 put +dup 43 /C0112 put +dup 44 /C0113 put +dup 45 /C0114 put +dup 46 /C0115 put +dup 47 /C0116 put +dup 48 /C0117 put +dup 49 /C0118 put +dup 50 /C0119 put +dup 51 /C0120 put +dup 52 /C0121 put +dup 53 /C0122 put +dup 54 /C0127 put +dup 55 /C0262 put +readonly def +/FontBBox [-25 -256 978 739] readonly def +currentdict end +currentfile eexec +D9D66F633B846A989B9974B0179FC6CC445BC7C8A959A39A32E9DCE7FAEF17EE3BEC9F +50E1A6FCA651FC4B3769A0A91041557502E25A5D6180FE25A3D11BF079E1DF66E54EE9B7C229AF891739707A2A0EC140306B5E43E52B79BFB89E459E50 +6EC6F610A70775A31C460976C4F79449D86E57ACE491E5C6BF20CC4307B1DAF7630252 +E9AF8CFB69B50EDAE9D36A6104AFEF8832F920FD2346B2C7104CD11E3BEE999CFA9F5A +49DB3173EE48D1C82994237F360407B022E0B4 +502E94EA8B493651EF2D03F0B513D655047568325B512AE6 +6AC6F53F3848CF70DE25481CC65D8B1A5793AA +3C4282D111112BEE28AFCA7A3808D4444C4669CA +84EAAAF989219F51AB3476A1B0B5F2246BC306E6 +625C6679C417ED2A8E9BD010DE37D40265074C268421912B00DE5CFBFA849BE7D67692D2B46689 +87571FF9AAC939AD7F8506F5 +E212668FC1CD93CA4F +90F000D7 +EC794F8E1EA89333D3BB42627082 +CA3A4A3DBAFC25560F11FE1D6825562615D88EF20546AF20BBB7502A9558E2430718DE76A59BB615C1AADDE7186AA65E3331C00366B1C7B5DCEE1E600DF7ABE143B3BB6BE5AD843600860D8C93DB720945A7075F9E74782726DC65AB2AFA0E81B659CF2CABFDDA +E163B586 +FE543E597D8376CC2E221FDCF6 +C10CD968E8B3156D20C02A3279152F687C7457EA971780CCE1605D6395FF62CEECF72CC3414B51DBF3A5C978C909F6132A8C0E12C48AA6E85BFFA40B4A0369AF +DD672080 +A09CD2883A8F5F1895DF513D31 +54E0773807F1E363D7E86F82DF9C780EEABBB77C0845E73D35A5D93B0D7BC2592298678C1B2EEB8AD84D7A930E5520103096FF1566C8034D9F404A15FF245D +91B47733 +105C63BFE5ABC0EAEB56F2BEC8 +DA7413927FDF1DAF1B1E3C8BE01007FB15B058A627EFBE28080A5EC168E1F5D028A21273FE3450BF55DA0A5540557112D3425355AD03934842 +97FB3BCD +64A0B1D80DB7F0E18ABC0A8786 +08407B929B0D5D9F9E1FCBE9ACA8A25A578FA557E0A1B8 +CBE28C49 +E2D89A6680A28E03521D4783F1 +1B5F18895C457358A2C13B8605C62FCB4303CC6D932B0DEDF68FA12F2096CC +053172E5 +7CE5D7B329822E21114416638C +3BB4570936E2451AF9AE8B5CC2BD225B6F5D6706E22007416B00B72C +407210FF +310307B794E5E818DCA54F1D1B +22718DFD6859841DFEC82194EA26A11F381D02A49782EA70BC69F9FD5B950BAA1B34169A7703BAFAF02565410EEC999BD9A222506DB7AC6ADA5816AA96CB6E6615038AD77A4B88616837525F5044AF6A7A6E0C6F0C6C1C29CFA348804616A3A9CC +9A495AA0 +2BE869366815184BD89EC6250B +2EE63584FF04EFE9C40A0F47BE78997CF57BC179D7B1C3559C784817E51692D374B7CB2C21494A845F752EE622B667EE7201DFCF2EBF +1A5A8AEA +FF53E74F66D964D6F559B8E28B +279CF25CF8AB74791EBF15064BA866F1333AB88CC1C88B568A237EFBF37E7C7766AF2D015401A50A50 +246D8A36 +EFD67766A56BC7E14374074C25 +5686B775F5C071DF67C04C62A29D407C97659DDE67745C25A677A1B97082A6B2BACFC459 +86998E23 +AF59B47852A041F2395C15D20F +AAC795403190C189CADE2756B88F2D787A0F686AFCD0739B2141DEC7AE6D79FD6FCD80341052F8 +0D33A21C +DD523B2A12F0FD732F0F5D737142 +7BAC81B3C1BAEF198ECAE69D17FDA39EB1232083F749517AB41651D8F692CE04F6987280336CF66BB6DC68171F9F182BB59A402D33FA253FB512395496248E7F594A417157B74F8D78754CFA6F7383ED50CCEE01241FE52BBF9C9CC51C856820A3431734B1EC96522935E53F05622528E47BCA5A58046656DF20278810A4 +903D +9942E7A6F823D11791F76D3F32C3FBC9FF691B90ACF688BABC12C7261BE52FC5C01DC6233BBCDE87C69F1C825E3A90708454DC037CC63ED96360CD6B347206EDD2476618F0EA6E54701C4C3A90DE64BBC160864E0162426DB22294654D5F9EB595F02FF5321E50AB70DE9F87C53539FE0A8B330E9FFF774CCD603CDDDB5B +9B +DFAC3882 +B47AAD832C7E749730FBD24A451A +B19EA46786383D7FAEF25DC7941858A54C044B93661EA14FE3668E24DF6535D27644E68C50A66A98E5823666E8D976A33D362FE8BD7986225F34C8EEB401C70CC5C1ED60D81EF22F05DBAAF9EF1AF09139A9F6F62A505FBB7416246745E3928C03A48BA945689084A260984148860B67339C2D +BA44D152 +F9937E5FC09376AF64557E05F600 +FD03CC51F27DDB895BB39F0B48A4ED1CB658621DF60366C79EAC9BB8E3E8BB6DFF1573B3118F4095827E21620C4D1ACF9053B61FEB668E659409C36068D4F95E3458ECCFE8174CB7D70D60E541DB7F380A2D26339FFECDDA5903EB06C0950EBD709F64EFAFCD2B39B6FB0856F2327A789C10FC8AC4D4F2E24BC6D474E43B +F552 +01 +ADA2CA4E +9EC74D6385A850CB35CE3EF01C +D10EBE049B41FC66FC7C34E764B2944758ED3FCDDF58FED860E9D1F83988151F34C7C02BD3702A17E45DB08E38E5C62F46065733009C315D493BC3450B39D1FD0BA51034A213B1420E9BB4AD1B7C2DB0B93D706562457135FE8824AFFEC2EEDB60 +609C0383 +87534318E9EB0ACE15F7C6D5F9A8 +BB59A8136E5B4A11262ECE352A3730BF7D993215B85D22536085E8AAB28ED4D815E25A7BAAB9CCC533BF493012CC961F7752913FD26E6C8C9DFED9EB862AF9C938043776B710139C308BE2697B209A0329981733032ECAF66C0B58DB50FCB4C86B3365D465D89C8EFA +CD7D2158 +515479836139C78DA6DBB37ADE87 +C03A2DD16687B238238EC431C338ADD3952D2F19A58F1216825AA1754BA7EEA01F09620BA27C18E0C77E7ED9B69BD2D57CDA92B436E3E46741A7E28BF6FAB341B49A207F995BF05B85270E707367E3B86F9A7513ADDBDDDFF2CBD9FA2A4C6D726D0316E4DE93365600477608CDA61D4BE5454F2B8B1B9A61BAD5390E45CC +BBDE +64D104B3AD65A5F1F1C0A3 +E9B3115F +D1149858391B0A220A2E6E10D5 +505522332BEA03C78C8911515E6377C4EF86EE989B1AEF9B9FF33E571569E51E1BC4D2C3CEBFE803ED01E171BEAEE65F040AFD769CEADABE21D86F +1928B7C5 +772A4C013390C2F4C9770A4930EF +1E3E7332357B6807AE32C04368B059ED3AC530A30FB9FF186B69E5197A86E52FE4C6D75414D91FA57080C3F663B1109B817590CC70C1E4C749CE8730E727C35D76512540C1A37151B8CE3155ADB6351B71A06172ED07DE4BB3E40D22A7399CCF1424A051947CE5F3FAA65E107EEE2D +19D2ABA4 +4EB55B476FB9AA1F9781DB5586 +3E11A214C1DE0C999489B47B3D8CFB2BF50F789CF9CFD879C708F333497247755449C27FB203428CA56DB64A58A4964084B9A3B999637165E65753E487AE098A8C27DD55D3E8D4C787D0EA50ACC5F382443361ADC7C5A4DD47CFF983 +205C8196 +3DE54BE13A4009FA318245A0E0 +17C3352B2D425E1F55B4A5AD6A258B8F09BFF061151A103A5B778B8354A28B2CDC785172898A1B144C0F5AB10854B4EFE545DDA6384ED439B01891A38882D580E0641C1CDC06533BA666EA642B99633D973404 +7A7E5E7D +338DC9BD1D89B5CC5FD7876A8318 +4F0F93C90FDF128C231392F8DA3915B67C1BDC267D0AE6A744B8B2D17938173F023AD5727160B37ADCC0BAC065367DE6CC1820C10DF22B5CA46C7A1226AA52CF5BD36F43EE2BA2EE5165783170381FED4B30454C5E80C0F031EDF5BF656E31457DBDA55D41C7C4C8E992 +F8AC5C20 +56DC9144409FFF8DA878F86ED784 +92C31CE44CA6F076C87599EB4D7BD060FF528B4E82134417415ECC67B7352A5A13D3CB701D7C482E61D7038856C8656537A68F3C829E858034A383D0549225D744860E122EB8C4E40BCF7A9A9140437F5B0AD85DEC719B6EB5B9563F61453B2D7DBB30EE2E9DEF801600108807CB953E802161F4840B22799176FE310D9C +3CB8FE2D +B4547EE8307C556B489877E9E4 +121D68FBC4707730B55F776C3D785EFD5844EC01317E0CD70262051BA2630D08EAA6ED83935AD30172A49B9F63E5AE9AE9FB789257813D6D990278A7F902DD1F044F5F866C5A6B7C4260D9F8B1BA071A36 +85B8045E +A54972CA1D0E2D2D1C611A4BC132 +ADADC92C4638B3C6CDBEF1843D266F3A731A60CE8C3DCEEAE596E5CE1352C65FA628F1A13B91DFD92DCBA8396D67722ED3E1C885365B5F5D9327226B91584E4B567006910814D6987C3DAE0091E150D1BD71D4063B9FD83874376A815DF1CB34DE12CC06374328EC8BDD2A45E752D03FFD4CF205178B872477626BEF0E98 +DA67 +5452953DDB74ABAC990F66FEC92227E5 +EB8634CB +C6FE825882CC3E5EF80272314C41 +2C5DB4A6294486078B531186A9BBF77204A87A909BF95D6CDB40D62C3EE03C6DE94509F8AE1F36765422CC6A20C120B3D3FCCA10E0F088EC4C73DB389D76C899283D13FB26B95E8A714609A64ACAFE27A528E363C83E9420FD8D7249EF50A48ACE10CB8AC93D3E5473AADD8925740C0FF7BFB7 +9C5F3D64 +EAFABFC006C2C423257947C9849D +74C89F5D8B5640CF99485C7DE4E1EFBD3901DCDF5318BEB3AF7BBC5B720EB85F68C8FECBC5E8874505230CCB0640A8CD10E9F496DF91571598C56E8DCF3B15FC35E6774A14A125E5BB7B469F014F6C6B3703147368001B233F1F2CF309537EC970B17F88F404FA77D799985A7E3B2D47333146BC12FF265CEF043DC352FB +BBF3 +387672 +37FCCE37 +916E2EA4233DDB533925B7C87E +1D24C34E1EE5504C3B7498C8961384758D26DAE6E98327F445C116E8DDC37D5977B9BC5904C31A4263E2DCA7B4032447225D887F373BE5C46D9441B871637CE6B531F5000481F06DAF62FA7FDDAB88AD3B593531337544D0 +0C760EB1 +5E024CFD26C7A7C3044558B100 +4827BF9D4AD8512E8FBA07368C0CF8227DF19727976DF273251E55C444BFBBDDF2F07B962631A1BA9982DE120960A799D2830D8A367BF6051B216B6B06A45E48C325898E9F4DB0459AE5D4D2A3ACF9844648 +30206548 +098D95BEF98CE2EBE692BC531F99 +999053018F3788EE2CBDECC92E530B7C7630C3D72A94E4CC7D498992FD310147BC35DC5BB2009B6BB29FBE9B74F666A66BD633F2FA5A8D17B32C90FC683FD8350882961A891E3F9FD6CA68E0D6851BAEF291CCABD73ED0735FD4FA7A8F6482CEC8C406D658F55E2D97A3A86350EF +2EB96866 +9EAB3139DDD7710BA0284813B2 +98DD1D7E4D0DEF20D2F0AA8415D0CC163FB7130AF4F71357AB3630D8E8D26743C97F5C71CC0D8BECF4CD41099BBE9F6DF8835A37A654AEAD16008F6E97727582EF583CE51C42B204EF3BCBB840C3EC548CAED02341C5A0BAA6 +9CC7BC51 +724187981628AE29BC8ED3011D +4E2E1A18266B561246EC3AE5D819FE5B41093BEE52A12AA5DD1618385AF4259B7372F779C9E34203E0463C8D215650200828F878DABE64D7DCD52FEBD2BB3781F46D3382E0530858DF97A0E12D2B87EA5E2D2B23D8DE5D8C399957A4 +84066BDE +909F48C0B4AB33035C3723329DA3 +9C7D667AD876FB76C0639C5F2523773C7020274FA29A14D5CABD858A3886D72D626DDAE24823BFD39562206D394C4C06DFEEAA53EB9497433694CD921CD210ACA07F5E4C46CF1254A154C553FD2957C9DEA7D751C48679A745807E9441D8624771DC2E973239A7A3FC21CDC4C6080C090F271A4F149461D75A9D52170352 +8235 +AF13795A20E4C52D8E6F6CC123FF6693C0EF841A73EDE0F8479FA657EFEBD5EA9B9C25F26DA5FB33E64F250EE2A372 +8754A59B +1BC42E39C33F6F531751B00C952D +EE1F6CE60B754C79D03E0D8003267DB7478819CE157491C1724412E5799642CDC79647113D885318E3C70CAAD3E55BE694FEE81E84832DDCD0E27B0150E05D8D8897921DEA65156DE5B936058F42399F2AA932D0503BEF9F78C227728BA8C6DB97FB153E497B71EFB46424968C +5EFB85EA +5CB139EFCB2AB8577E6DC7F6AE +E22D1892608C24A09A1E73093EB9C77F8A2F87DEDC98EF41730C62EB27951699463871DAF852462D7EBDD8527AA93515473255761C49FA38346432AAD220021F503CE3BF665154D5B676E5D8D71C5577 +82F0A3E1 +AE6894A949D862685EFCFF2326B4 +0E27E0344ECBE6A688CE40CED1120DC044357DE7FB6BAA47198A67199181B288159687CCA9E04D93C72F802F60B44FCB58C08BD28F5E35D0E62C2201A72B14F224DAA7029D27FBE8F82708117B65386592453BBD8CFC49088CD439644A38A4F29F6CAB22FB9700FDCA4B753FACD193E5AADBB97C01793C7E25A07CBDEB3C +2BA8 +99F3AA7F71142B7A94CD15A5E77B958D86A41458F2CA53EF8EF3B14F62FD974F70231A +F4060411 +78400A5DFC904FB63B39CD22CE +9C2F3D5B960EC19A953D38174054E4144EF3679A8E26416A7B47E49603A518A7FD0027BCD00084F823191BC7490E1FE34AB9143FF83F +3AE9B97C +D5510745F41296E9C011312FE2FF +D0CF3E5BC19C1E17648C2B874347CA9E598C1A057D68A6C7B1B3ABB4AED49572E9739FCD22F41BA98D2A1EB6F9548D823431C686F828B85FC64C3F7FDED818954C4BC96C26CE2B052B8B89DF5FB234AD91EA38466394DADC3ACECA328D3C97280286FB8AE4CFB5C263642E601CF119ED81AE3CE43623DD4BCF2FB67658F8 +A0DF +C387DC5E6467D10142538102E1469BD241BBCF33C21E76136B054BBFC6D6BC +C16B52E0 +E950C5DF47D2BAB5C0AC0DD79E71 +C527867B1357EECD6B412BF06D81821428F73269BCC5494ED8ADBDEE9D57A55173E58AEA271808D2CE68C3D035F7EB4801CBC306904368D3841EE1ED4CAF974218217CD0036F140ED2B97212A88DB4D856EA81A69179277786406D1647058F1B0C19D0A8DC9D9CC54DC58888 +898A376E +147A1DC955D970FFE8A0BFA511 +1A578AFFD34407DEB4A31A3338E257FA0E87BC2BC38EBB13EBDA5513BF9A25AF459E25BC4876D10F21BEA73FA1FFC1064888B9AC194B4F7A80F1E9A0C2CC1A4F1660A8FB1543 +D8593FAB +2BBD401FDE3325D4DEA0BDEF8BA5 +75387DD049C52945864370B0A5A8635C1F6F55C5D2FBCDDEBE1858BF0518A95794DE0A1BE1AF033EC28E6FB6E0593663176008AD70F331E15DBA97222DBAB09DCB8AC86BAFCA34D980BCC3CDDF5B0C883205EC2B6638ACC47B0ABF1BA0CCF52455AC5EE244D22C5CD09593D7A363909C891A16E6A90F10 +AA94B5CC +8205151AAB0BF05F031A6363DCEF +D2F3B251394D4963320ECA4FB126A0F91CB76D02D0905AD1AE8B5E04BE3F385C3ABED1544A84B736E6EF9B88AFBFF30DDC390691C4689999DBD8F224B495065C03FBD3E7925BA8D35409C4BA16FA6150CE75E3ABBECB8AAAAF8FE844CA9462E456847DADFCC5827DE3EB +8534BCF5 +A83F5DB5EC2AB3A0A70EF1BEBA +5095045A1031973C5500DC84C4063A72C2375B76DAE0820D7111FBFDFE5BEC6E5C1C459680D8C0CEF2F728D0CAC5D05D992D02CFBA49E49489EA62E06FF76CBDBB07809B7C4155B3D0FE5A5C3FB1A41A44CA7E167F4394 +AA97859F +C36689D3E2D47C7C38E5EA0ED503 +C7B55E1F4DBADF8F17F3473B9A282BB346AB11EF6DC10984B29DF87DA3CE9DA6FFACF4CA7749004FF6738A40054E0C03160779231C1CA6F6C8A730C5AAFA8A67228F7CF643DDC6E003A4F0E825EBB816184881D46B5F89D9B282B6838C5353A1C4CEE3DA256742E682B905AF9263018DEC976970D14C302A6E35B67C +EF4FA704 +BA8A073C071C64782DFD043464 +A75D9E0BC759852CE536B0527664B944133F0D5B9FD64F75181E1074F9BAEDBB43BF3DC1D3FF8A9D9878A6AB82657D3FBEFD8D2E37E173DFB186464D5F93DAF6D4AAA49365 +127F95F3 +33E51891CB536AC650309CF795 +520A812266602D133A8BEB8D682935DBC4780B8FCAD4F68AC4F3DB4E35E8115E92FF90090E7148FFB1DC3BC97CF7A4A28559E8837A7A553767271CE5C579EF32CFCEE258FBDF4627CF441F3E2F11C1CE5E806447F4C04DABB3E22FB4BED32515B728 +85AE4F23 +163D918F80456060906187C823 +F5330878FD629F54694A9886E0491EEA543D11801301988C2EA0A0D205E3C22BDEE3AB00910C43D147406AF7427A0D390ACA9298833E97B6ECCD34160FDDAD00E6A44B8C788F58B1319AEFCAF541951704EE211043A069C750 +B0ED6B4C +A46FA08BAA001D31064F09927AF3 +ADE81FE968DEE362CF394828F136C5028C522995207926BD207458AC3778DC23DF71AA9569E06A7BF67683019A57940D83E3A388684EA8F1EF38DB4C299D62B878B999CD8FB1743F8D3A6FC033DAF6ACF7A07484CB17D031BDCFB405A5122E9EA516B898D784B76D4B4FC233E7EE4D28EBECBDC7FA6DF9DECC7CA34F36AE +8192 +17B4B4CBA57F493D38CA604EECDA +DEA5331A +42B36DEF414BE163E5A59914AD3D +E63CB597BA0893AADB07A605972924374CFED24E72B110E39D7FA018E0FFA267FE619C46BBCF020DBCBD22F6A14EC9F012F197C25C64332109454B3721E340FDE78F52A69FD7BE3B74FC48CC843663A39C52A33AD1649FC2714247A43E1E363FECC968E6D3B43F33ADF7262AE1CF3B3804C4751F64584101FAC202973C63 +ABD7 +A9861DCDB01A4B3E9683D87285F8E005F16F07A5FB4463EF05 +D19A38D4 +9DA063E3D242DB09675355E8D643 +E8CE7C64B03BFC9D4F19A1E77A0BDA4C76FF99C13ABC6162ED0263A77225E295C4B6EE6E68C5CA2AE0BC052105324BC6DC92A08E06865B57609B03D0179F719021FF6561A45044B0A304AD107043404689A49B34243871A9C56D7D9712ADA66DAD02999DB0A8FC72D3EFDF8A854B06983910334B22BFCABCA578A0B8DA7C +D813 +4F5ED0E1 +935F82E8F177EED7F93DA3EAF2 +0FD084536BE7A88B4D9F31011CDB4A9EF81DB0685A53E68CE13D9FC9C481A6957EF1B7D2C3A322E95422A86BE91559C0852FB667BE122559F67DC2C9B4C98F +8613C412 +735A6246B3800B85B8D01F20F126 +F94694A59961A2848B051F953BE51A30F900D0757DF65F7C99425322F27F49EB2032CF5209D2AEC3152AB54FB5CE711FCB77696F4E02AE51D750BDA276B0F8E39A540854EDEB9F7CF040F29785199E2152E62E25C53BE6834271EC90A0F7697126AB101A2AFA98F83E +5B7B77FC +B77FEC8591AB34A9EDFEE2A839 +FB365DE43A726DA77763737965FA643EFDEDCC9AB5A1 +B10BB121 +F0E242DC60AB7227B0C25A465E9F +002FA79A5480AEF7 +B1FB89AB +18F2437341067DC9ECDD1D765C12C74F37BCE07537D027B3E2A01AFBAE3E161CFB37 +0A0216FE165EE4069D779A7D72DACE7E7F6E234BEAC3798994E2C6F969326F541215EC59BB3A +AF57E630814016421726AEADEB53A288BDE06C8E8D31B37A42D047 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +%Defining font PSOwstdutchb +%!FontType1-1.0: PSOwstdutchb +10 dict begin +/FontName /PSOwstdutchb def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001000 0 0 0.001000 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 1 /C0032 put +dup 2 /C0046 put +dup 3 /C0050 put +dup 4 /C0058 put +dup 5 /C0069 put +dup 6 /C0071 put +dup 7 /C0073 put +dup 8 /C0078 put +dup 9 /C0079 put +dup 10 /C0083 put +dup 11 /C0084 put +dup 12 /C0097 put +dup 13 /C0098 put +dup 14 /C0099 put +dup 15 /C0100 put +dup 16 /C0101 put +dup 17 /C0102 put +dup 18 /C0103 put +dup 19 /C0104 put +dup 20 /C0105 put +dup 21 /C0108 put +dup 22 /C0109 put +dup 23 /C0110 put +dup 24 /C0111 put +dup 25 /C0112 put +dup 26 /C0114 put +dup 27 /C0115 put +dup 28 /C0116 put +dup 29 /C0117 put +dup 30 /C0121 put +readonly def +/FontBBox [-10 -209 798 694] readonly def +currentdict end +currentfile eexec +D9D66F633B846A989B9974B0179FC6CC445BC7C8A959A39A32E9DCE7FAEF17EE3BEC9F +50E1A6FCA651FC4B3769A0A91041557502E25A5D6180FE25A3D11BF079E1DF66E54EE9B7C229AF891739707A2A0EC140306B5E43E52B79BFB89E459E50 +6EC6F610A70775A31C460976C4F79449D86E57ACE491E5C6BF20CC4307B1DAF7630252 +E9AF8CFB69B50EDAE9D36A6104AFEF8832F920FD2346B2C7104CD11E3BEE999CFA9F5A +49DB3173EE48D1C82994237F360407B022E0B4 +502E94EA8B493651EF2D03F0B513D655047568325B512AE6 +6AC6F53F3848CF70DE25481CC65D8B1A5793AA +3C4282D111112BEE28AFCA7A3808D4444C4669CA +84EAAAF989219F51AB3476A1B0B5F2246BC306E6 +625C6679C417ED2A8E9BD010DE37D40265074C2684274C264E5F45F0286BD1B23D26C34626E07A +5B039DB36C18005EE32CFA64 +906B285CB8BD7F0968 +D47F5242 +22DA29BB63E91AD86291368AD5 +A88A8B573E6EFBAA343D54E80F1886B6E63ADDE84119240E0B442BF2824996 +FA6F5BC7 +41125C64417312AD806FB91AFC +16D82DEC4B8AF9280A31F07BA6E26893D28A501A95660A62DC78F63B875197074D7B446FD2F7DCD4EBAB2CCC89190FFD0C16F9B37A78310998E584FB6978CAB14862655F25F2E0CB0CE211D1F66FC3485032C411 +82DF0B9E +7BF2AB6BD7D1702054BE49E6E2 +C27C0E78620612D9E1E891DD99D57AC02E32A6EDF4206742334ADD569D569D377533D343E6C86497E7571BF6BE2CAE74A7AEEF5A0CCC +38DB562A +C06486C456BC04A7FF6D562B4ED0 +40B05072B8689854FE82C7F624A417C4D47971219DB412BFE654AC71AE7D37EFF9929929A874536DD7A020F93C4113ACF1A1748B18B34080E566A7A52F2941E63DB134DD432828BBA5416516FA1567DA4C8552B17A3BF2695C57D23F178E22C288E673C44E04428B6811E7B8020B +55738CCE +D0E183FABC6C1D57E61E1B70EF23 +8C02844A7889B60FFC2F50A5A4E85D95A34FAD2E9B0E6109377553933CCD91F810AAA223FA2EDE0B9736621706C40CA1B3A99E031A1C88CF1C74DE8BD0BAE89325137797C72158F02209CA00ACB9CCB189E09FF86B4D9DFEBF407D3BEE7AAB15D825B65578AEF67E644B63981BCDD7F58EEEE623722235 +FC9A358D +AFC8C19BDEF328FAD8197CA4A1 +14D09F0FF27680B547B6535F1168849785A74512650855BA4F6A9CC08C94BC90D3D2382EA543089DCEB9CDE3A3A52F61FF520BB6D88378628B5125976643 +B069DEA2 +CC62AEF6F31BD42CAEC76C7E92 +68E3BDDC9979658FFD7486A47279F32434EB1E82287B58443C4BA86DEB28C70F69E8FA7995F0C5D1DF60B184F21F121AE6F2D4BCA0D7DDD385496203A561AA02EE883A8BA04255FEB89CE09D8EE57541C568416F957FC244FDADC4AD8CA22C +FA9BCA30 +CD95828ED8958E088D9FE70A9C4D +007671558CBC547CE1FEBB6BFEA5A6EF7CF80AA3704017BADA97D520FD332C6A3B81F97CAD83056719BEBD6768D1CB01386526D30F36984C738B3AF5A4ABC28EF071A30EF675C00833CFCC8A197EF7C591E05601339B6B2429E1C9E689093F720BEB0D764DFFBAEDC1 +600FDD9E +428425D2404A285576A81764CF5E +131CE693B3BB941283C3EB72E84747ABE4266D857D06A7B667333B61C8700AAD29D94AA98B57BF2F60DB76C724E2D932B935F89B589CF4AF6F53988888B103391F406FEBEA3F9EB20550CB1981194E21C962D62E324C1DED002592DC2E117D2DE5846D2AA9ECB6E1D3D75999F9F44EF5A35598255963959626E04B6CCF10 +1804 +0399B747 +1F967A808C374AE5B4350EEE78 +C24BE584A0A8C6BBBBFA03476BDB6D06DAF776BDFE8BC8075E52C52411775092F6EFEDB3239ACFB03E9CF43EE03239F5C698D56723C069DDAA4520678C1986F18F83EF4F0C8E282714 +D975E505 +6AFA59B4285779E527BC8B7C18E2 +A7B55A71204D8F15C69FF1ACEC778B858E812BAE60E68599340DFA93E3601238A14C546E3308559B32DCA1CB86BED58680F15555EF1EA37C55A935AA10C7804B1F8C2495DA9DBEE20BFF1D7F87F9AA180AB7B936A6A8A0A0749DDEBDE90286D27BC2D88C12AC7539B331263193A5C7F484985CECEF40A27F07D2213BE87E +9652 +09B10BB2 +07698EFB +F280E75819C5BCFB7874A0D88A +7F566883E1282B6F9346805913F79F9FA9F22A023674E0DF9005E37BA8D42D31D3F17D48A952A8FC9985461804CE98F551103B53C057C40315D72330B2DAAC68603619FC05348B299275551A0CE2B9CA62AC58C3A1BFF13871628CC24D7D +5C639022 +3EE834AFE48B8D2111898E28BD +BB4E975D3A66F1ABB827699F714ACBEC75AD22930772E0CF9F9A496C578D5C4E494CD9D1A0AA33851586399CB151C819F8D4CD43A10977476B0851F4D515578D4FB9EFADA3909663BDD6E907AE7616C250FA +DDFA3BC2 +95292CFD9E1357E6FF2E3E20BBCD +42F78C46751E5AE981706EA30620A3E91E76EF2BE3E10CA82AED444C490CB440D1A2CBECB675DA235294AAD355D7F4B4FD5F8DCB5F5CA193304206BC718A7100764D39BA1271725B19DBBFEF94255382DC23C3CE09EA0BEB472B57DF6B8E657CB2187E7B7243D4A490C0EC94 +772D8FC3 +C2F17846E5280CCBD7205570AC +830F81D3FA06D6B66DE7E9508A59BBFD7F51656F9BA736DDF57D14E53A61AB3F2E2C329A7901EB66D763F6231306DE6CCBF9AFFE8E94BC0F9FB556A59F831610C56AC64D3B4AD9D512D0BE75639069FFEE6C5AC8306350F81D567982 +1F18F736 +299FA3A26D8B1ECCC6244C26ED +6EEA47C357A8F2878C812EAD33F474ABCACAF333B15E5B3FC892A6E51CFA60CB93C4CB0E5F0054F9D452E449654D0D2258B2D69160231D36E83538F282A3C85B4BB62155D2210F3F070BF6690FBDE557917E4A478EDBD525F6EB1C453A +564268CE +30EDADD025DA83ECE04831A6B492 +4EB4F3D4318BC0A01CB908BF96536C41AECFCFADCFB0645BA6D6AC119740875A2E8AA3B7A71EDE61C787BEDFDEFF076726C3C56D7C0FB41FC5E1F4D08315A3DA6BDCEC4276E31CE82AE3441AAF87E800B02C099E75389F68345AB339E940261D01FFC2BB350C4D7056981BC1136D2FBAC7CDF8396C30F8CECF4159F00BA3 +F456 +8D5A092BBA61A90241767D6D4E0F9C52A12A3A3387152CD952B7EF1370DD63C7F80424D324 +49B376C4 +8569B94ACC535DB0CB99C06E05F9 +BEF1443C7D9A2AA9503419D2F07EA5A6238E7836C11167740050400E98A85E145F7B4CCCB8D7AE854368C47B961092E6E58F59BEC749C599992E504E349544269650B32834AA1A5AB103383D6FF3EE7F63A2FC708BEE853C345A8C44AA4BCCD098CDE1F9884F3E69 +DB52E7D7 +C9BA4DFCADAD98EB2A2D38BFD7 +4002ACCC1DBD57553B9533F37152758DFFB69F4916A47DC549FBC0ACF5338565B9CB265BEEB02D56DC6F48A06698E6FB1F5259AA74D34B089EA7CDC7EFA7D58B16A0ACEB32C4A6063AE82102EE99 +72557CCD +CC65BB33B00F47BB9193E3E2CD +CD5088764F3AFAF4FC18217C9E0CC81F269F5AEB9A7CEF4D17C8B85145B64D9975CDECB44B52363911A98D97BC2C775178E1C562 +2730514E +167B806A5C8A42A278A6679207C7 +6C9999033BF63766F9526AD6C8B854E5ED1AAC24A3CAB9A23CBCA9D5CB4601A253E4931FAA4A930BFDDDEC6AA4A5633314FA35055C500DC8965338717674D06BB9FF9F06BCDE8EB8F5A1DD2FD4238B546EFC9A5C0858EA003AE6E53111A3D00E50BFA325BC1E21DEDECF0C1C17B94F417292C1D90C8CE1028A8AB6A5EB5F +5641 +171B91B5E039964DF0F39BF4BA7D1B3599BB725C7435FFE2ED4FFC7F +30424945 +AD896C6C1A6831BF28F7F660E826 +2CD10AA4F1CFAA3794EA46509CFBC23F26402F035E19F0CEBC0B3B6CBC36F24D8F77D0DA3611A6B35C1076D802BCE78C529EB0C82BCB38203A0A66246F5872BD110709A1A161C5C0175B58B52AE7E286A0438D5D887DA3C47EB436E766F21D9B05B853A3986B26 +EFAAF294 +2E75B0747770EC9BE022663B82 +E2544A6F40CC1D3F5106649F62A79C81B3CFDABF4D32094FDB71396D227BB30C4B9697AD61E8138857ED7859E082ABAD06B4AC5962A6AE98D43AA5579165D71DC747E73E56DD +21890B5F +2DDF9B4032C55A52393C9E1B363E +F5FA426A8A745928D4DD30E54C763F17114F04C98E29A68A523CEE33E03847880A6676F0E04992564025338C20051472DC3A3E13C5DA113247D8A7F64441454FC57A6CF5B4C7F7203A6D5FB0C59B6AEC43291AFD56DA85D420867680FDE8FC1455CABD54BD812CCA1B61F1FCFFD629DF67 +BCC57B27 +988217BDDA826AFD6E5BF357C6 +5E46F471BBC5320A5198668B58B65484C190430FC877B9B5BA6F96832D4D15DFDC164148721BCBE05CD1482DBB7CF13133342E660C189A16A25303D975FC2532B0C05D01F7D9B99C1B6AB1A88F3744A2202D0C9F6D08A5AC5D +7D33B32B +7FAE2A2EB83422742C315B7E440A +A3A095CBEE26578F5D61D2B064BEF6978FC7A1E3D61FB8B2230D710F50A9C72D900F22A7CD94F8BDA64E4A0847127814885E119127DFDB6F83C8AA35FA5539F4E2967A5A2501A968692992656F27710089FC7A966017B303D59F9D0AE523900EE2DC67A983AB1ACE2C9BA824641D2ED140147C353E8992BACB +8FC63B6C +1E184370D112265E6E9C7EFD39 +38553AEA148BF8C8B16586CCBA94018EBB38325E466B2EEB07551F8AF3A876E0276559D68202938E0A892325272D95875C20CF596A91115A06C312553E4399638A9F7F8E +0C35D83B +E381CE8B2B1CABF23014334298 +B97EA049001F8904EBEEA427618B3F18660750A8A565DE771304CCBC176D19D4F424E1D283169E19BE9CFA2A38CB2EA448578E3B5EA7032CC65F4737AEA2F954C3C57D776DAD6FD8AD0BD3D87385A62CEDB950B068926CF6C8726C +8EEC393D +E1F8B746701A72899A4D95874CFE +D7C05171BCD3497A6C2AA6290010A15F66485BC8562EDC5BEFFCBBF1D262C3EC788AED97C64AEF5914659CD68935ACFF328BAB6494CA986EC65DE341D696C4677A07AAC6DBC63E85BB29240FF52F71AD021B2E91B7527E43EDD89B55E99FE232A34EA599D3E259CB4DF02EA19E6FABC18F6B6560DCF7B50828809D28301D +E54C +3A +6089F82D +63A828956C03D0D995D6E88FCF29 +C984876B6F1B5B8A +49CBAEF9 +BBDB7219F5CC9CB5C5BFD1E329A9EADECC03AC817A01E882A3B4F2B89410EDD7F50E +FCFF76281A7451E392C53923861B62E3059D2A8DE12CBBA6A7257F85D734E18152C54F49C81E +2A06F2E5A904749B0F119C6DB33F3A11AD0A03EF6D434DD13E28A8 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +%Defining font PSOwstdutchi +%!FontType1-1.0: PSOwstdutchi +10 dict begin +/FontName /PSOwstdutchi def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001000 0 0 0.001000 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 1 /C0032 put +dup 2 /C0046 put +dup 3 /C0047 put +dup 4 /C0095 put +dup 5 /C0097 put +dup 6 /C0098 put +dup 7 /C0099 put +dup 8 /C0100 put +dup 9 /C0101 put +dup 10 /C0102 put +dup 11 /C0103 put +dup 12 /C0104 put +dup 13 /C0105 put +dup 14 /C0107 put +dup 15 /C0109 put +dup 16 /C0110 put +dup 17 /C0111 put +dup 18 /C0112 put +dup 19 /C0114 put +dup 20 /C0115 put +dup 21 /C0116 put +dup 22 /C0117 put +dup 23 /C0118 put +dup 24 /C0119 put +readonly def +/FontBBox [-144 -236 757 725] readonly def +currentdict end +currentfile eexec +D9D66F633B846A989B9974B0179FC6CC445BC7C8A959A39A32E9DCE7FAEF17EE3BEC9F +50E1A6FCA651FC4B3769A0A91041557502E25A5D6180FE25A3D11BF079E1DF66E54EE9B7C229AF891739707A2A0EC140306B5E43E52B79BFB89E459E50 +6EC6F610A70775A31C460976C4F79449D86E57ACE491E5C6BF20CC4307B1DAF7630252 +E9AF8CFB69B50EDAE9D36A6104AFEF8832F920FD2346B2C7104CD11E3BEE999CFA9F5A +49DB3173EE48D1C82994237F360407B022E0B4 +502E94EA8B493651EF2D03F0B513D655047568325B512AE6 +6AC6F53F3848CF70DE25481CC65D8B1A5793AA +3C4282D111112BEE28AFCA7A3808D4444C4669CA +84EAAAF989219F51AB3476A1B0B5F2246BC306E6 +625C6679C417ED2A8E9BD010DE37D40265074C2684269A711773B1F062EFDCE93198A765F8F55A +6E9F60B43AD213B6F99675D4 +AE976E2319012C37B0 +302BEA47 +3B98CEF2181F487E60BC68223C +A5F86E7A115CFC2AE9165470EAEC678CB0DB27C2BC338F2147E8CD552D1E42 +3812A612 +E3F98DB266B650DF66CA2583D3 +958E9EE0A0B63B7867F2268327D79DD9860D80713FDA4B82EE +A74B55DA +6381153753244DFCBD7DA2BAD9 +955F9061254DDC5A489077D97027245C05D94591F48E +CE29B2F6 +0D5FE23555A0FE78128F1A64CDD9 +1A9718631B0CA99E469954D1736C63BC1076171D274B36E4C8E3BEF5FB9EFF35C6E47C3D0A42A70ABCD91EA5923DA436CD6BAA2E2EBF93D139D5B8ADBF4D3EB16A7D4A0A0C9A4ECF3BF4A6593BA6151291B34672DCAABC58E6B0A6A3F02B5001B3BBFCC7618D573E7E7B6B50C417E40FD1BD3E9BCD94BFF3755B9CFC53B8 +5865 +243074F954E234A9103B8FADFD +00ACC4AA +B7859A895242187928E9C3BCA795 +44B1A2F7D8A06CE14F279DA101AD412F27C2DD9166C4A859F2E88D42C8749F7826332F2B39D95AFE040F0C7A5975B15AA97DED5FB1E662985F7C91FE322B88491969165E64A7FAB8CE00F88F461870DD681998879E0C1F92CD29FA2A4CC502876B7CBB8E3AC6981301F3FDCA4FC5AA3C42D0D981DECEBCD14C6FE4431DD3 +957E +B6BA1D881AEE1A83E5EE2C9F7069B1F0 +0B6D768B +239BE3343AA73DE4EC8C466E8E +7190803852418BBD9A90B75B1E5628D38172895FCCBB92372EAE79263C94906ECC4B80697A1F61CA8B4664E0EBA0713487080BEDD508BE2CB921A5E4E2467E250DE38ACD9A28FEDD95D4741E08EAB9A0BE2470FE4FE4EBEF8E89F2FA0543177E +0EDB5F0A +25F60E21630304FE6831BEF4530B +351B697B5C7934254F1B55FE746B9387925CDEBF3DAB15BE2DE2E83580B63C7EF6383D6681E9B252054985DDAA91B731B136D2FFF4CC7366B44F11793B80C04A8F32F10CA835613823D82D9A9F4393C1BCC6347E146E6CA7A29E91ED0399CADA9B4888A41F4F28B8CF2DACF022E06E33B7988572CA3DCB0380223C0918F5 +9BF6 +F966E5E99E0698BCA0B332ECCCB097950CC731EF7FAC4D23C569371E06F5B90CA0D6725C87F225C66EE6F14539BD7CEB +F8D0533A +F5F750C58859172EBE961EC9198B +C03CE04A81733BA0D3F66ADCD702556ED77DC60B3ED563B218E7CC67C3D71615E21BCFD9A47B707092110D5E67A2D5C2A521222833E3B6315A9BFD875670FBBEA5610A753289C721910F76123722A7C6324C6780C06B2EBC66951A0EAC56C346A4BCD3E761 +CAB98073 +CE511FFA322CB6090643D4799241 +3B4D7D1E498D0EE71CE1EFAFBB3AAB71984F58957C1F02DF28DBE6D4C9640A9C607AC6AF20890332D916B156C382D0F4EAFF795BFED7E423DA6AF6C11AF66167113EB0164C26330CB81497008209ACDF516FD2A64B92807FD5F0BD5657ECA6C62915B4DFB4A8B12E39F32682A930890653B32F3022E40C0EEA7FD1B103AF +B825 +FA2DA4F6 +F8169B5F +ACBBA0C833A918CF3428D2602173 +8105BCED0B709156ACA403D4829DC70DA0964D21C3EA7E7A3C11237BF1B058D8DA560961431B795103E7A7606AAA078DB3B25D956BDB5781D97EEB2B447FABC85454BECBF6E7E7E9B154A3F7B284CE95F8DDC8D99DDB121A6CBE20D881E98DEAF83874637AA5CFB09E437672219FB824ADAEBCD8C847F622FAC6006ACEC0 +46EC +61F007E627B9EB0372468C82879C888A003900CAEA7810B3FE03745706109ECEDF1BA7DDB8940F43823A +AC78344A +110D2E7BA93154FC97C2CCDA4AB3 +9A27AE30D8E25C87A917AC66404E8D7AB9DB1F39B32E4C4B9A720EE2E31B883D896E7D0D62AA8DF10F904CCC07D61BFC01587E411113B12087833C3C3788A2F8473D7AA263AD170E1F1E284CDCBA18897B938F01D51B8D90DA53FBDD0CDAB53625CD7B3823871A29CBFE94FD85BE13055DBFCBFB491BDC50F9B325D428EF +B7EC +DC8B116125360C458F962944D6E0F301165104246F76F3B71F822C +35EFFEBA +D84563B6BB11E042A08C6FCA15CD +098A1B0696998EA6B9385F831962A976EE9C8059828870CF3C393D9E39AE62782767CD410E516F96F8CAB81AB387DFC73FEA40803638072F2E00C5B56B0890156811FD4ACD5105462C7435D8CC64034172EC1F5D8102CEA613AE94F82DD3B4AA847C13C31D7060E9BE20D948BD725AEC5BDBEBC7E1CF17E295 +843DC060 +9A721D7BC4E86B758DE5BC32FE65 +8EDF08834B78AD3A039926DB08DCA517CE64F3E93127D02776CD9D476F0501ABDBB27627EFE5B28577F34785FB7834E7E266EE170D6C5112677C63D38133BCC4D56F7F8BC98DEDC97EA3B37D2A5F1C8A887BC8E47CFCDB1881C25F7DA475F6342ADAF13605CBA78BA3C6926D2A42991BAE51AFCEA83E923C4AD4FC8E7135 +F27D +F1737FFA52195D36DA8F11ACDDCE9BC13285 +6A45AC9B +CDDA87E843223CAF7B3EFDFA07FE +94011A0B86AC32BC6C1E510062B2DA2F734B8B319D1F25E51E0F52BA7DADEF5C5AF50EA7F2C4468540DCBB0622F30D87B68CB4D63BF5197B88447BB709C56F30C701738DF6C8D3AC18DC4F7BDD0E2D4A86564F5707E0F298FD8C4C7CEFA5C8AE96FEA0BF7714B1170B01CB9502E4058F20537BD181EBBA0A78D91F148C65 +8187 +4DFA0075DF56533D26D72518E5C85864E8D91C8FA2196C218E2FE3479ED9798A9A82C6DDE5CD4F7BD2D7B3E0C8F20ED3149CB83E97DDD6E033649A90D751143AC92D5370AAF591BB2483DD +9060815E +4F40D7C7F22980AD0D2D05C19A89 +6203E598EFF7A8B638AA2B49EBCE82609D3FB8F0F9D909CE9B88632A7F556F153E3997334709CCCDFABC01C903E85D545A1AF26972493A849BB7A2335E19265B8F01C29E4C33E988E0EAE58EAD63F9DCD9076776E66F4DD682B0F3E3A88749519B33F5DE091BF4678678D757D48ADECC2906CE23954E2D0AB9479755F0F1 +8EAA +A1DEFED82A8866560E81AB89EBB1E344036BEDDA4D84ECAF8B +3504B318 +6C2F51C7DEC51ACFC884CC8A93 +D55990B09FDB1FBBAC644C3226E3F0155B27E2345050FC1C27B29AC60479A3C5CCB6B644D63DC4796343552FF5046623F048968C890BA5175F7D059588E667BFCC57F7C0089B587D82227DF30F4D08D721FC16AC5B90334335E0695BC5F5C8 +9B0CB60A +88FD2381F55A915ECC5F0F0473D5 +983C86714C1A8ED7F22BCFD5BB20234A64E4693357B7CFE57267E5827861786371D572DE54A6D6E9A5EEF73B4279F94A9090F697D5D2B2502CE747C33A8B70822435BE5D377C8D1EDED4AFBAE521DF18F62F0271DCE118624BDE4D59C042C78FA0A4E404B70E1F4A34AA8E7D263C97BA533C55E31EB696BA5FFB988C2301 +3FCA +A7BD88FCCEC0645DF61C455E986AE810943EAE114BA9A8BCA724CCD4D280B0E57C0430798815B70CDABC +8EC91599 +9E0FADF1653C3FDDAFF9727A63 +2EDD250548807E34C7A7013F01DD3F1EAA52F8146A76DB2495CA2D60FB0A84F66AAD4BA157D1EEB3670157D978AD87837EB2579FD67107804514FAC39F75E255922AA6C4CC4226DB0E974CD52DE2C96A392DBECBECBE8D486224EB +EFF0BFB6 +9F72002C6A0C5E0C566D81260345 +756E793A099D0B5CB81E29E76DDD033934329A7D773BFF97813A4387FBB4FD52FFF3F4D6351FEED6D7F84F0FD6761866829D5CEB88648B114A0E3C645919B9ADCF20FBD86B1B04E7F039A75E7998409F87E3CBD7ED65CFA66A4ED5FB76FDA409CE74B3D62A5E071A8AA7531D812420943E8616439B4B +DE42F729 +1EB22FC2A2FBF82EFCC4FD57B0 +891FBA2EF0A76B49665B446D9D7B105BCB44793EFF49DED9A15ED203CF765E1EE7B8F6F98DA814D4E3F88656067E9A1AB781582343B05B48E33554680C6A606EFE1E0BB9791A9165B786952FC534F07B204E13EFBC9E42 +AFE2E5D3 +56945120B796546E5E316555DA1A +22700A875B545107DFDD48A8EE2F3ECDC3520B38D8BD7AB2CA5AE1AC75B87033753866A879E23AE901E244D7AACF4350BABFEABC02A8BBE6511752F623000C699E2FCB90E9B54D7465E5E02450050235642DB933ECF7BE1BED29AC65830718C802EB14C72DA02B0BDF3D45ED734215931D736DA843D45C1218DF4E63BCD5 +B918 +2989C0C06791844E667A1CA66E4276358300D03BBE6EDF +34E94565 +9A6DC02CDF1067C9572C41BCC1 +60FB1D79486867175555A3761C1AAEF8367F3B688C767392727863F95CC6A65828D616F8381619CCDE3262D0F1E600BBACF2A1FC9A11E5514DC38097025961DC9171568EF625543261376C10D4F6BB889F0A856F98F5F2224DB7 +5BC42A51 +F788AF2FD156C7EC710167CF3F09 +D11A879A9148BB28BC22247626EE4DC09C0370736B123D602DB66260639191A30B346A3A08CA2052CF297EAF2C3F0EC6DB5E609489FF96BD70282A803129555688C2608FD12F05B9D33166AED99894FA4B5BBC3F06793D0D1838CF2C3C0020F0996E94146026A0C79D3074C6E641B5 +A9A3BD9D +D9519FFAD8246DF0D2618DF7D51C +4905B01A3CAF220F +126E3EEF +552F3D9C4E04759D5EFB5D44FAD0033D650162424A8C11D177C90214410FEA765BDA +34DE10D98849793C56F3BEC029B6FF4D740E0B91590DB2815DDC40E9F351989D78C010D5451F +B516D041BAFC5114BA5A9139F78C7BBF010E319C2E6AFCB95A3906 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +%Defining font PSOsymclas +%!FontType1-1.0: PSOsymclas +10 dict begin +/FontName /PSOsymclas def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001000 0 0 0.001000 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 1 /C0069 put +readonly def +/FontBBox [106 45 775 713] readonly def +currentdict end +currentfile eexec +D9D66F633B846A989B9974B0179FC6CC445BC7C8A959A39A32E9DCE7FAEF17EE3BEC9F +50E1A6FCA651FC4B3769A0A91041557502E25A5D6180FE25A3D11BF079E1DF66E54EE9B7C229AF891739707A2A0EC140306B5E43E52B79BFB89E459E50 +6EC6F610A70775A31C460976C4F79449D86E57ACE491E5C6BF20CC4307B1DAF7630252 +E9AF8CFB69B50EDAE9D36A6104AFEF8832F920FD2346B2C7104CD11E3BEE999CFA9F5A +49DB3173EE48D1C82994237F360407B022E0B4 +502E94EA8B493651EF2D03F0B513D655047568325B512AE6 +6AC6F53F3848CF70DE25481CC65D8B1A5793AA +3C4282D111112BEE28AFCA7A3808D4444C4669CA +84EAAAF989219F51AB3476A1B0B5F2246BC306E6 +625C6679C417ED2A8E9BD010DE37D40265074C2684268F16195489648993B9C4D3B534FA887C +DEF605FA87B991F4D20A8F78DACE +5A54C070E03D5C59D9D2D3E06B09CEE028D68B62AB3AEC43C1DD20BA70D288597D9BD8E06818FF764EBAB436723988E8D7CA59E16D39032516BFC5D552ACDEEC6BE938BEF2F43CFFBC811C3626C4DF5F8CF080676520B51C60CEDAD1FE6C92D1431C702174CE517A8FA9377D075A0B6833DAB101DB65397F1419EF5F0016 +004F +6F0824F9657BB4F1C8F981709956865F6855EFAE +9242AD55 +91BBBEE163D844DDA894E13190C9 +2480439E4C71CADA +BD043A9B +A315CAF72652AA7FE6DB2E84D82A6111CE4DE90C02DA0AFFE2620922262A45AB4ED0 +EEC9F4520DD12703442F7D028D4526BD8B771E09FBE11B2749E2D3906894E8D4BFD3F379F14C +3C874F550606965E22FE487B247B5C2D06728490C8F2A3B588CDFC +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +/DPIx 1270 def /DPIy 1270 def +72 DPIx div 72 DPIy div neg scale +0 -13970 translate +1.00 1.00 scale +/wst:dutch12 12.00 /PSOwstdutch newFont def +/wst:dutch12b 12.00 /PSOwstdutchb newFont def +/wst:dutch12i 12.00 /PSOwstdutchi newFont def +/wst:dutch14b 14.00 /PSOwstdutchb newFont def +/wst:dutch10 10.00 /PSOwstdutch newFont def +/wst:dutch14 14.00 /PSOwstdutch newFont def +%%IncludeResource: font Helvetica +/wst:helvps10 10.00 /Helvetica /wst:helvps ILEncoding 0 declareNFont def +/sym:clas10 10.00 /PSOsymclas newFont def +%%EndPageSetup +GS +0 13978 10801 13978 10801 0 0 0 clp +wst:dutch14 SF +0.00 0.00 0.00 1.00 setcmykcolor +<16212f2b212d220a010f011021291f24281d2d2601222a2d0115211d2e302d2529230116212f322a2d260118> 2207 558 0 7384 -1 s +<212d222a2d281d291f21> 7375 558 0 8593 -1 s +wst:dutch10 SF +<09> 9434 13385 0 9522 -1 s +wst:helvps10 SF +<4e6574706572663a> 1322 13267 0 1949 -1 s +<205265766973696f6e20322e313b20436f7079726967687420> 1949 13267 4 3868 32 s +sym:clas10 SF +<01> 3868 13267 0 4019 -1 s +wst:helvps10 SF +<2031393933b131393935204865776c657474b15061636b61726420436f6d70616e79> 4019 13267 3 7133 32 s +wst:dutch14b SF +<0a100e1c141817> 1271 1458 0 2055 -1 s +<0003020007171b1c0c15151417120008101c19101a11> 2055 1458 3 4268 0 s +wst:dutch12 SF +<16212f2b212d22> 1271 2038 0 1980 -1 s +<002b2d25281d2d3400222a2d28002a220020252e2f2d251e302f252a2900252e002e2a302d1f21001f2a202107001a24252e00252e002f2a001d27272a320025292e2f1d27271d2f252a29002a29002e342e2f21282e002a2f24> 1980 2038 15 9461 0 s +<37> 9461 2038 0 9531 -1 s +<212d> 1271 2283 0 1457 -1 s +<002f241d29002f242a2e21002f2a003224251f24002f2421001d302f242a2d2e00241d3121001d1f1f212e2e001d2920> 1457 2283 9 5856 0 s +<002f24302e002f2421001d1e2527252f34002f2a001f2d211d2f21001e25291d2d25212e07001a24212d21> 5856 2283 7 9531 0 s +<1d2d21> 1271 2528 0 1562 -1 s +<002f322a00321d342e002f2a0025292e2f1d27270029212f2b212d2207001a24210022252d2e2f002d30292e002f24210029212f2b212d22002e212d31212d002b2d2a232d1d28050029212f2e212d31212d05001d2e001d001f24252720> 1562 2528 16 9531 0 s +<2a22> 1271 2773 0 1457 -1 s +<002529212f2005003224251f24002d212c30252d212e002f241d2f002f24210025292e2f1d2727212d002a220029212f2b212d22001e21001d1e2721002f2a002120252f002f242100222527212e00> 1457 2773 15 8124 0 s +wst:dutch12i SF +<0309150703140913170d070914> 8124 2773 0 9137 -1 s +wst:dutch12 SF +<001d2920> 9137 2773 1 9531 0 s +wst:dutch12i SF +<03091507030d10091508020711100a> 1271 3018 0 2500 -1 s +wst:dutch12 SF +<00032a2d002f2421252d00212c3025311d2721292f0407001a2421002e211f2a292000252e002f2a002d30290029212f2e212d31212d001d2e001d002e2f1d29201d272a292100201d21282a2907> 2500 3018 13 9531 0 s +<1a24252e> 1271 3263 0 1665 -1 s +<002e211f2a29200028212f242a2000202a212e00292a2f002d212c30252d21002120252f001f1d2b1d1e2527252f25212e002a29> 1665 3263 8 6359 0 s +<0000> 6359 3263 2 6456 0 s +wst:dutch12i SF +<0309150703140913170d070914> 6456 3263 0 7469 -1 s +wst:dutch12 SF +<001d292000> 7469 3263 2 7903 0 s +wst:dutch12i SF +<03091507030d10091508020711100a> 7903 3263 0 9132 -1 s +wst:dutch12 SF +<07001e302f> 9132 3263 1 9531 0 s +<202a212e> 1271 3507 0 1689 -1 s +<0028211d29> 1689 3507 1 2225 0 s +<002f241d2f00342a300028302e2f002d212821281e212d002f2a002d3029002f24210029212f2e212d31212d002b2d2a232d1d280021332b27251f252f273407001a2421002e211f2a29200028212f24> 2225 3507 13 9461 0 s +<37> 9461 3507 0 9531 -1 s +<2a20> 1271 3752 0 1503 -1 s +<00252e002d212c30252d212000222a2d001b> 1503 3752 4 3107 0 s +<2529202a322e00161a> 3099 3752 1 4084 0 s +<07> 4053 3752 0 4106 -1 s +<1a24252e> 1271 4086 0 1665 -1 s +<00281d29301d27001d2e2e3028212e002f241d2f002f242a2e210032252e24252923002f2a0028211d2e302d210029212f322a2d26252923> 1665 4086 8 7044 0 s +<002b212d222a2d281d291f21001d272d211d20340026292a32> 7044 4086 3 9531 0 s +<242a32> 1271 4331 0 1646 -1 s +<002f2a00302e21001d292a2934282a302e00121a18> 1646 4331 4 3778 0 s +<07> 3743 4331 0 3796 -1 s +wst:dutch12b SF +<06101c1c141712001c13100017101c19101a11000d141c1b00111a1816001c13100007171c101a17101c> 1271 4786 6 5031 0 s +wst:dutch12 SF +<12> 1271 5186 0 1402 -1 s +<2a2d> 1394 5186 0 1591 -1 s +<002f242a2e21002b212a2b2721001f2a2929211f2f2120002f2a002f24210014292f212d29212f050029212f2b212d2200252e001d311d25271d1e27210031251d001b1b1b> 1591 5186 11 7837 0 s +<0700142200342a30001d2d2100292a2f001f2a29> 7806 5186 5 9461 0 s +<37> 9461 5186 0 9531 -1 s +<29211f2f2120> 1271 5431 0 1875 -1 s +<002f2a002f24210014292f212d29212f002e301f24002f241d2f00342a30001f1d2900302e21001b1b1b> 1875 5431 9 5868 0 s +<05002f242129> 5837 5431 1 6345 0 s +<00342a3000281d34001e21001d1e2721002f2a002d212f2d252131210029212f2b212d22> 6345 5431 7 9531 0 s +<31251d> 1271 5676 0 1530 -1 s +<00121a18002a2d001d2900121a1800281d2527002e212d31212d07001422001d27270021272e2100221d25272e0500342a30001f1d29002e2129200021281d2527002f2a0016212f2b212d220019> 1530 5676 17 8361 0 s +<212c30212e2f000b29212f> 8353 5676 1 9461 0 s +<37> 9461 5676 0 9531 -1 s +<2b212d22062d212c30212e2f0e29212f2b212d22071f302b07242b071f2a280d07> 1271 5921 0 4692 -1 s +<1422> 1271 6254 0 1422 -1 s +<00342a3000241d3121001d001b1b1b001e2d2a322e212d0500342a30001f1d29002d212f2d252131210029212f2b212d220031251d002f24210016212f2b212d220018> 1422 6254 13 7572 0 s +<1d23210700142f00252e00272a1f1d2f2120001d2f> 7564 6254 4 9211 0 s +<000b1d> 9211 6254 1 9531 0 s +<242d21220c02242f2f2b0a0808323232071f302b07242b071f2a280829212f2b212d220816212f2b212d2218> 1271 6499 0 5606 -1 s +<1d232107242f2827020d001a24210016212f2b212d22> 5598 6499 2 7802 0 s +<0018> 7802 6499 1 7967 0 s +<1d2321000b081d0d070012> 7959 6499 2 9048 0 s +<2a27272a32> 9040 6499 0 9531 -1 s +<2f2421> 1271 6744 0 1561 -1 s +<00272529262e00222d2a28002f241d2f002b1d232107> 1561 6744 4 3478 0 s +<16212f2b212d22> 1271 7077 0 1980 -1 s +<002e2a302d1f21001e252f2e001d2d21001d272e2a001d311d25271d1e27210031251d001d292a2934282a302e00121a1800222d2a2800> 1980 7077 10 6802 0 s +wst:dutch12b SF +<111c19020e1d19021319020e1816> 6802 7077 0 8156 -1 s +wst:dutch12 SF +<002529002f24210020252d211f2f2a2d34> 8156 7077 3 9531 0 s +wst:dutch12i SF +<080d1415031009151811130e0d100b03060910070c0f05130e14> 1271 7322 0 3707 -1 s +wst:dutch12 SF +<0700001c> 3707 7322 2 3986 0 s +<2a30002e242a30272000302e2100> 3960 7322 3 5193 0 s +wst:dutch12b SF +<0d14170c1a1e0016180f10> 5193 7322 1 6310 0 s +wst:dutch12 SF +<002f2d1d292e22212d2e0032242129001e2d252923252923002a31212d002f2421001e252f2e> 6310 7322 6 9531 0 s +<1d2e> 1271 7567 0 1457 -1 s +<00342a300032252727001e2100232d1d1e1e252923002f242100271d2f212e2f001f2a2b34002a22002f24252e00202a1f302821292f001d272a29230032252f24002f24210029212f2b212d220011002e2a302d1f2100222527212e07> 1457 7567 17 9531 0 s +wst:dutch12b SF +<08090b05> 1271 7901 0 1866 -1 s +<0400> 1870 7901 1 1975 0 s +wst:dutch12 SF +<00172720212d0031212d2e252a292e002a22> 1975 7901 3 3568 0 s +<0029212f2b212d220032212d21001d311d25271d1e27210031251d001d292a2934282a302e00121a1800222d2a2800> 3568 7901 8 7972 0 s +wst:dutch12b SF +<0e1815021319020e1816> 7972 7901 0 8951 -1 s +wst:dutch12 SF +<00302920212d> 8951 7901 1 9531 0 s +<2f2421> 1271 8145 0 1561 -1 s +<0020252d211f2f2a2d3400> 1561 8145 2 2447 0 s +wst:dutch12i SF +<080d1415031009151811130e0d100b03060910070c0f05130e1403> 2447 8145 0 4941 -1 s +wst:dutch12 SF +<0700172f24212d002e212d31212d2e002a29002f24210014292f212d29212f00281d34> 4941 8145 6 8021 0 s +<00241d3121001f2a2b25212e07001a2421> 8021 8145 3 9531 0 s +<362b2d25281d2d3402> 1271 8390 0 2179 -1 s +<002b271d1f21002f2a00232a00222a2d0029212f2b212d22001e252f2e00252e00222f2b071f302b07242b071f2a2807> 2179 8390 8 6280 0 s +<1b24252721> 1271 8724 0 1817 -1 s +<002f24210029212f2b212d22002e2a302d1f21001e252f2e001f1d29001e21002b271d1f2120001d29343224212d21> 1817 8724 8 6049 0 s +<002a29002f2421002e342e2f212805002f24252e00281d29301d270032252727001d2e2e302821> 6049 8724 7 9531 0 s +<2f241d2f> 1271 8969 0 1630 -1 s +<002f2421002e2a302d1f21001e252f2e001d2d21002b271d1f2120002529002f24210020252d211f2f2a2d34> 1630 8969 8 5437 0 s +wst:dutch12i SF +<0003111215031009151209130a03141307> 5437 8969 1 6784 0 s +wst:dutch12 SF +<07000018> 6784 8969 2 7076 0 s +<2d2131252a302e002d2131252e252a292e002a220029212f2b212d22> 7072 8969 3 9531 0 s +<32212d21> 1271 9214 0 1705 -1 s +<001d2e2e30282120> 1705 9214 1 2527 0 s +<002f2a001e21002b271d1f212000252900> 2527 9214 5 3914 0 s +wst:dutch12i SF +<031614130309150703100915041209130a03141307> 3914 9214 0 5600 -1 s +wst:dutch12 SF +<05001e302f002f24252e00241d2e001e212129001f241d29232120002f2a001e212f2f212d0021282b241d> 5600 9214 8 9461 0 s +<37> 9461 9214 0 9531 -1 s +<2e253521> 1271 9458 0 1607 -1 s +<002f241d2f0029212f2b212d2200252e00292a2f001d29002a2222251f251d270013213227212f2f0618> 1607 9458 7 5386 0 s +<1d1f261d2d20002b2d2a20301f2f07001c> 5378 9458 2 7036 0 s +<2a30001d2d2100222d2121> 7010 9458 2 8020 0 s +<002f2a002b271d1f210029212f2b212d22> 8020 9458 3 9531 0 s +<3224212d2131212d> 1271 9703 0 2103 -1 s +<00342a30002725262105002b2d2a3125202120002f241d2f00342a3000281d2621002f24210029211f212e2e1d2d3400282a202522251f1d2f252a292e002f2a002f2421002e1f2d252b2f2e07> 2103 9703 12 8923 0 s +wst:dutch12b SF +<07171b1c0c1515141712001c1310000d141c1b> 1271 10159 2 2890 0 s +wst:dutch12 SF +<17291f21> 1271 10558 0 1757 -1 s +<00342a3000241d3121002b271d1f2120002f24210029212f2b212d22002e2a302d1f21001e252f2e002a292f2a002f2421002e342e2f21280500252f00252e0029211f212e2e1d2d34002f2a001f2a282b252721002f242128> 1757 10558 16 9531 0 s +<1d2920> 1271 10803 0 1608 -1 s +<002b212d222a2d28002e2a2821002120252f252923002f1d2e262e07001a24252e002e211f2f252a29001d2e2e3028212e002f241d2f00342a3000241d3121002127211f2f2120002f2a0025292e2f1d2727002f2421> 1608 10803 14 9531 0 s +<1e21291f24281d2d26> 1271 11048 0 2284 -1 s +<002e212d31212d050029212f2e212d31212d05001d2e001d001f24252720002a22002529212f2007> 2284 11048 7 5584 0 s +<1a2421> 1271 11382 0 1631 -1 s +<0029212f2b212d220020252e2f2d251e302f252a290025291f273020212e001d00281d262122252721003224251f24001d2e2e3028212e002f2421002133252e2f21291f21002a22002f24210020252d211f2f2a2d3400> 1631 11382 13 9138 0 s +wst:dutch12i SF +<0311121503> 9138 11382 0 9531 -1 s +<1009151209130a> 1271 11627 0 1868 -1 s +<02> 1864 11627 0 1917 -1 s +wst:dutch12 SF +<00142200342a3000202a00292a2f0032252e24002f2a00241d31210029212f2b212d220025292e2f1d27272120002f24212d210500252f0032252727001e210029211f212e2e1d2d3400222a2d00342a30002f2a002120252f> 1917 11627 18 9531 0 s +<2f2421> 1271 11871 0 1561 -1 s +<00281d26212225272107001a> 1561 11871 2 2656 0 s +<2a001d2e2e252e2f002529002f24252e002b2d2a1f212e2e05002a1e31252a302e00281d2d26212d2e00241d3121001e212129002b271d1f2120002529002f242100281d262122252721002f2a> 2625 11871 13 9531 0 s +<252920251f1d2f21> 1271 12116 0 1991 -1 s +<0032241d2f0028302e2f001e21001f241d2923212007000f272e2a05002e2a2821002e342e2f21282e002d212c30252d21> 1991 12116 8 6535 0 s +<0020252222212d21292f001f2a282b252721002e32252f1f24212e001d2920002725> 6535 12116 5 9461 0 s +<37> 9461 12116 0 9531 -1 s +<1e2d1d2d25212e07> 1271 12361 0 1948 -1 s +<0012> 1948 12361 1 2113 0 s +<2a2d002f242a2e21002e342e2f21282e003224212d21002f2421002d212c30252d212821292f2e0032212d210026292a3229002f2a002f2421001d302f242a2d2e05001f2a282821292f2e00241d3121> 2105 12361 12 9531 0 s +<1e212129> 1271 12606 0 1710 -1 s +<001d20202120002f2a002f242100281d26212225272107> 1710 12606 4 3793 0 s +GR +eop +%%PageTrailer +%%PageResources: font Helvetica +%%PageProcessColors: Black +%%PageCustomColors: +%%Page: (6) 6 +%%PageResources: (atend) +%%PageProcessColors: (atend) +%%PageCustomColors: (atend) +%%BeginPageSetup +bop +%Defining font PSOwstdutch +%!FontType1-1.0: PSOwstdutch +10 dict begin +/FontName /PSOwstdutch def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001000 0 0 0.001000 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 1 /C0032 put +dup 2 /C0034 put +dup 3 /C0036 put +dup 4 /C0040 put +dup 5 /C0041 put +dup 6 /C0044 put +dup 7 /C0045 put +dup 8 /C0046 put +dup 9 /C0047 put +dup 10 /C0048 put +dup 11 /C0049 put +dup 12 /C0050 put +dup 13 /C0054 put +dup 14 /C0058 put +dup 15 /C0060 put +dup 16 /C0062 put +dup 17 /C0065 put +dup 18 /C0066 put +dup 19 /C0067 put +dup 20 /C0068 put +dup 21 /C0069 put +dup 22 /C0071 put +dup 23 /C0072 put +dup 24 /C0073 put +dup 25 /C0077 put +dup 26 /C0078 put +dup 27 /C0079 put +dup 28 /C0080 put +dup 29 /C0082 put +dup 30 /C0083 put +dup 31 /C0084 put +dup 32 /C0085 put +dup 33 /C0088 put +dup 34 /C0095 put +dup 35 /C0097 put +dup 36 /C0098 put +dup 37 /C0099 put +dup 38 /C0100 put +dup 39 /C0101 put +dup 40 /C0102 put +dup 41 /C0103 put +dup 42 /C0104 put +dup 43 /C0105 put +dup 44 /C0107 put +dup 45 /C0108 put +dup 46 /C0109 put +dup 47 /C0110 put +dup 48 /C0111 put +dup 49 /C0112 put +dup 50 /C0113 put +dup 51 /C0114 put +dup 52 /C0115 put +dup 53 /C0116 put +dup 54 /C0117 put +dup 55 /C0118 put +dup 56 /C0119 put +dup 57 /C0120 put +dup 58 /C0121 put +dup 59 /C0122 put +dup 60 /C0127 put +dup 61 /C0262 put +readonly def +/FontBBox [-25 -256 920 766] readonly def +currentdict end +currentfile eexec +D9D66F633B846A989B9974B0179FC6CC445BC7C8A959A39A32E9DCE7FAEF17EE3BEC9F +50E1A6FCA651FC4B3769A0A91041557502E25A5D6180FE25A3D11BF079E1DF66E54EE9B7C229AF891739707A2A0EC140306B5E43E52B79BFB89E459E50 +6EC6F610A70775A31C460976C4F79449D86E57ACE491E5C6BF20CC4307B1DAF7630252 +E9AF8CFB69B50EDAE9D36A6104AFEF8832F920FD2346B2C7104CD11E3BEE999CFA9F5A +49DB3173EE48D1C82994237F360407B022E0B4 +502E94EA8B493651EF2D03F0B513D655047568325B512AE6 +6AC6F53F3848CF70DE25481CC65D8B1A5793AA +3C4282D111112BEE28AFCA7A3808D4444C4669CA +84EAAAF989219F51AB3476A1B0B5F2246BC306E6 +625C6679C417ED2A8E9BD010DE37D40265074C26842247DA7FC91B9FEBA82925C7B7A9B0D22DD1 +7C0E9A7093608F1410546F00 +09F98531B5959B588C +79CC3103 +04952A259B81E452111B161889F2 +3347D5B60BCBEE9DEA320EC36F8F8E4485C03CD6EEB3F882180086CE0471E1CA1A4F2EB1D79854FAEC9E095FE26CFBCA133E36124CDEBB7D8A85300AD1F0F916EE730CB9C210361B827FF637510A47A20B477D6788D0C4E48B1195C329378AA1D8574A6FD6BE84 +8C1C7C8C +88054795FFE7D8388BA5324A41A2 +C2E98854954C2F9DA3C70D12E2F90CBB8E7A26AF605B104E4245BD51E585C69953D726BD3CAB51EC5F1A47FA287539198E81854D4F96E6CEE2A936FA2968BF327C3A198D1A59FFA173092B674F6208BE70A9C3F88BC9B3B53C670F9D8921EE9A5650C9E21E8FE3F07E7871F759F807A91E47DCC0FBFB766054CA1BE2CD58 +FDC7 +7F4BE1D1CBBACA12C04463C6 +AD34E6EF +BC59EE09DEA06F016EC0255FDC +CE0B208F6BDD63519C341761D949777A3EC4C899873DFD2DCF3F5F7FEEB0705F8B11BBE4631B9B59DD69F4C8BBED3E2DE2BA46ADC0D6F51294283DEE153C8EC5 +3670C2EA +9AE8A0D1B2B6BA27AF73030A9F +3040C92156C91AD44008802B9F70A1F5DC2E85BCC3174B033F4F5AC0076A783E990FD2B296CA1A157A78F02842F576687C38063D6CBA84D69870B115A31F49 +2A39A850 +CB94006B55165E0100A567FB66 +A67AB2E9E853537508FA240B1EDFD6120549F6E8FF2CC5919980386317C66D6182A342C3F54915EB2E4DD3EDD2CB1DBAB1E505366B947A50D4 +B934090C +0D8A5E874303E0FC34A8962EF0 +DB618EEE45FFD5767ACE93A0B06AC0CCA79B79A2CB41C0 +58CBD7B7 +D4EFAE7B388F90540547C2A607 +4B263DFBAF0214BE565842FE8CF748A878792281A597ED26F02713C274627C +61F914DF +F17836686BCD68CA0110E0F50A +FA773ED0CC8058672CCA1B83B42CD233DF4A42E4011DADE8892E3AD1 +772D8FC3 +C2F1784797F6584C0BA2C2AD16 +9FF342667B4077E05E7821B79A408F9330D572820F443E2EB1B7FF2B5C7B9371BEBAF246ECAC2CDE2B1C20A2E7829F3A727A6C16C5A90FCB16C780CF0C37785A1E32FBF360F71D40E779 +0A57937A +A11A7DEB9DD813B81AA26B393A +98569E59227826A4CCCDD1BF59AD2F9E02E6416358B9EB0BBFCEAFB07E70C1710E7DFEB4C8DA604F95813FC28B14C0A77A20A518A3CD571AB9F1CB932CCBCB +434BEFF7 +5D3A15DDDE22D51A0694AD4A2D +AACA192E30EE5DF17E495E924EC808546EEBFC93EAEBB4B3DCEE5981009AD393EA692C2BE16FC5CA9356AB13685E1F208E3A6A07EF5A287B0CCABA286FD6F42F018F47D72329C6857FC5E31470F2122EE590BDCD7B9B4E936B2C +70B9D389 +05C1083E2AC53752D75664EF1F6F +3A8F40FC9094F9FE9F39A1F650F795B0654650B44FAFED24BA99B148194A8E0ABA5B2BB75E07D0CCF1C2D9B538DB822BA6071C45BE5BDF4F5ECDBD6FD8B9BAB90E17C427D08798291E29662466F22C04BFD0CA12987C3DC4EDD73E8D6F32FF4FD19E394A +13585AB3 +EAC7E6A16A0F9199183FCAB6E4 +0E485982E0B4A31CACEB88E873E3DA70B49424DD0047692FCF29CF2A23325A050D91A726497F395B0ADA544B312873F060AF0966FCEC +33E5D360 +218FAF2DC0EFCFE61AF3E318B9 +83E57668F27CD511CFA75140DCDE358E090016153B0EBFEFF4046130A7460E4F4DB159E0C2C59625EF +4C5191ED +8FE03EDDA25E2EC971CD3EF178 +20F028D3BB6F1A31128A480694585CE3D9D1FD2F2DE056CC7D091D19FDFDFE79F88726D8B1CCB1 +B887388A +25CD84EA9A6B528CA835FE346818 +6ECD90E27CF940B572C1EEC69606FFB07E8252B91CC94158C2DD8434AA90E0F928DF07BC89EEEA7B423F7B8407498BE06D4D7CEF16C7E4A1EDD8667DE27290B0C1FC74B48DE936411134780CAAA7BDC8C6629BB3C8216C670CF6308706AE865D3C7F51344E8B583D41FDDFF9AC4875B706BAA0 +EA4A2484 +B476D1235396513D4608DB9F3E3F +BE084A2D4404E834E9DEB7E9B8CDCF37059F2D9ECE70E3401AC979CC71B864E7337F02FC28E1D5E20FD635F3969311948FFA318C8B025DB7A780E6AB3246F744A298C7D327146E275B92494CFFA02D22D97BE2BC7F560DA60D7DA900BD23FD4A51C6A169885198A47179637A3853B077B54048DE7993A07D323F0B0CBC97 +955D +C0 +E2C7E3AF +FBDF7AC26C10E8D04C9CB20A61 +7275B4BE0011F0C1118B2E87E5678EA31B9E509116CF8425F50DCBCF32613AD830B8B1DCF0CB07BBB50A5D43A40E25403D50621B6943A73D45837F79A8866C096317E3294900CAA8A74C99D60505FE6BCA4D244BA1F20E9623C447AE645CED7F3F +7F60F55E +28F2B41BBA0824B7714C205294 +597B0938E36441DBAFEEB432125A949F108BE1C1AA29063E48FE2031CE88C5AB0BA66AC672963D35F922F00C1729907DEFF8FAEC37EBE5B86548C12DB0EEF9E15EBDFD611F2C5D1AEB7950514F35293AECB1836A51AD9531FD41005DA80FC87BB669A1 +DE4797C6 +144A9EA221BB2820F691635CEAF7 +533AA8845FC3EA06F67CBFBB43E71B40EE05B99295549D9E35A4FC6A3B1FD0CD55FFCE718656774FA3F7F7352F2A59E8A53CAFA4A50A2B49D0450B37292472C167A76F3531A554645C7730F2ADE022D4386F9E7D1703793C294AE83ED46A6DDA41DBE4E7B37F2F5BBE3F658ABC1872164D69923A534BE1203CB9A0E0310A +63E71A29 +4209452E9850B2D698B63A67B51A +E8B12E5B4E776562DC71CB3620ACA3B879D45C37A2F6DA5CF847449939DC9957F9807FAF927C0FF5774D336D387A1E71A090C7637324CD22FC749CAD5CCDBA45731EB84C1B546FC4AF60ED1E1ED7E089AC27F8AD00D60AD1A1C2C7C8A9BE550A28A426E7A036B8C6A08AF7D637C762370F6142FE2B31BE0C4D23 +29171DFD +496043B20F32710B6358C1DFC3E4 +4012F882B796BE6B9E86A97C20C663E0793C7F5D16055184D01293DB9C41BAE75992C61FF482DF14015E13415CA917B3932702F1582B86C480484C149A5CF1F4F03B34F3CA746BBE380B89E4401B43841EF3134A7B22DA62E957E402C5EDF24546597EAB7A6D6B449E9FB81A05C79D918E83C7BFC81537866199B774B70E +864F +878D1EF23C715FFA6ECFC6 +05E2C26A +F78BE5D0B00B56217E03EDE66E +6557E7BD1AA208072D8C60C55F483FC5AA17F21D7D3FB4DAA347912C63B90738C302E8AF40F45E6DD1E1404BA89D274D7D9FFBC27136BB76FDD4BC +FD598614 +E071837C05F1CFFB27FB5B4CCA82 +5DCC6DC5DF309BB0FADBE9D1274A0734CD85BF99E04E566268C6C2214618C6BF145A564411F49F21E5872AA58A6580DCB9F370802CDBED07E60536D17AE3A9F45229512FC6C278BE393BEE218FA5208F13BD6BEE7827A551CEE708357F49AD9ACE3CDBE26EA8D38DF66C8A056837A3 +6D45A3BF +1FE631AD9028E8AB5209E83E33 +6BA0A926D2962ECE6302923D45180E445D61D12B235664E699D1BDF2D9ECEECEF731F80978D08EA06858FDFB0E11F6FE40D8170EEEF2A973EE094E77641FD4071FC00BE5C4D786229D970DD1706DD4732B6341A78C465E8900EC90DC +A7C9A8BF +039F75B7CA4CD98AAB53C403EC +4BCD0B756ED658636A7600707422180B5ADEF7C3E3EC8F976BF3DA29EE80380CC7131AF487FA27191820CC1BEB07F846CCF0F7EB9F2B17D291A95B5B30B5A9ADB57E6FBC2FE6999C6F3FD65806159C7A261331 +90745B82 +06F1358548B85B8329701B7423FF +43EBA4579003890D9ADA19EF71F4A3ADCA2BA1EFD7611E3FFC9308740923A16569FDFBD392EFB8EDF13320BC8B6AA9254F1FD79848B0C95C40B78FED2772FC2279E57DF0A070E0D967F7DF90346F1D06516DD309BCECE61E05E20D93EBA0BA7D58228AB26F4CBBA61C19 +E0E97FE1 +6841503BDB698D6701B09126E617 +9FF4C5DDE4AFBA7DAB5D091EFFD1B5D9D0D45BFF38E6E3ACEA4A5E097CF633EE809F0A6F01713F80B7CE2B85B661E457E24BF5872377D0B722A91D95A15C424015A3A6C0C1A6F4D86E5629F521F4839E6E5929261D4DCFB35318947681E8636EF3C614F1054467C8F6F11EFA7B6FFE74F83ABB6F9F5518B4F79B80F65494 +1CC2BAD3 +B15BC11F2D1547029C949C106FFC +54EFC06FCD2399169D48BD6FB2DDF4F8F63AE9B347CEEFE898F3AEB2ABA53FF95380B4156A92D9AFDADD7087D6B720F68DDCBCDE9BDD87423CAF652D4D9FCE2E6767B9C9EFC443CE4797C18EF589325A5F1736887462BA0CDD0B6F0A2300D86690CD6CBD226BEC638ECF27A6522C0614FE017AA995B88989219C466788D8 +7E4D +3A1E4E +AD299734 +96255177AD38F395C46EBC444E +CDA998E7E499B89E5D8DA8B1EACEFF6BE72990B84B3F0B81D422EC14C31A13F8656BA7359430B9A32BE36E638F97687845771E8B6877FB0339388BF8196AC3760609FCA4F5E666155F8C0949E4EEE50952 +4FA7B3E5 +B64EEB0CB4815129BDEDBAD5B649 +4BEDC9B96D760CD98BE3820D00692CA6E3F50834906B2AE847981D703E80A66790E1869BF7711A0ABEBA651C1E3BA075EA079E4A957548A93F0434BE709E936B727EDCFAFD853C73EF41144A108708DF704FEB010FBCBD1EFA67DE3870E73036B31B0511 +473B578F +3DDF36F7C67A2F31E4DE517463D4 +0106D9B73B325E02A17AE3E0AF4DC2D0977B78D69FCDF3349A2CCC609150642417EF3927B623B78169F70FB0F2E082129609A9B9E9124CB8AF042EEF27B3854065A3DC12FED74048940FE1666BD2996D1BF5DB7FC480EDCF27E3E218B83CE220EE8E864352CDDD569D7876E614BA2C62D09B3D781C16EDD4A620E6552546 +CFB5 +95E1FE80D1B2CB1FB10F67813FCF9FD66F0720BB88B6FF6BD9AFB7B0F077AA428303F0DF33EE23 +831C9CB7 +4B2B6A35CACA0BFC16C5DC5DED +743A7ED49E138455BC995C3F69065B4F42BCE82065BD +43FDF9E3 +0ED2CB38492A0BE58750AF15E6F6 +6D5889AA8BAF6F44255B8BFDA0E12CCA6D4848A700B7ADB0CEEC644F2AD788FD27B01509C97CEFAD607ADD6B1F55F9D968310B288EF173F7FF94B657952F71D896AC3A158CCA5469DFB4432F93012EBAFB4FD20DF10EF645C558FB1DE7E379C8C52331E35316D08D0B2C7B9A7F0A10147A5D233568DBAD8347E7A63C0B1B +F30B +72253D +35582262 +9C76DA965AE5E42C039C740446 +C3D311F79C573079EE790A22B96ADA600E708126FC6CDD08CBA8D743C3944CF8343E07C585385AA59340001F33C874F19E0A10032297827F1D217772F0C7EF0364AF28C65422598F99DE1B009C66F809E9EF2A2622D5B39F +5C7FAF43 +3B6996E06DEF2F09C5AD128A62 +475A39458A3A01CC72EE4CF7D4FAD46AED5EDB9BD7609FB4172CBD6CCFB7B8B92A3579496E9133D0BF70F732BC8689F6D226F031AB497B6C006E8950C0A6D59DDAFF386DFAE37FE399C6217D71FA6ABF8EAD +012715D1 +9FAB321516A26332D541AFBDC3C6 +DA722ECF34542EBE20861B9E6EC42966028439A7DB3B85799471B184D666827C009B9146722AD04DE686E1B59571F3C9D64A5E3CBDDB9028B0D389DC00B9325E1579CC9621A13AB4BBAD454871685A39B750AF51AD7C7C25933CC03F7328E7627AE4CA6003B3E97D5EB9138B1CA6 +60A086B1 +B35633628B1DA36BEC774A65EB +9D4782B0033D19F35A6A045C2EDB7E8BF44649A1B951E4AE0B6AC17007C66BAB6F3631A455D5B335F8D6459352D4B634235D68F50B22780D18ECEA97B569228C168FD53E5DDB8FED7D0B574A93DD9AB4FFA0F898CB58C8284A +7584044A +F095319F831AC8E7B6080089A0 +9EF7487CCEFD2E8959BFC4FF53F2CFD1C7C40B7A4D8EC3FB2D8A4050B8359252B485E2832B95F5E22FE164E8DB2517B25BBFBACF528E2B3BA8E6D33D13FDA1FB18EFEE0B25E7C00DA0194E55B05E99B57169C8AA5EEA61AE282D14B2 +4E7A2A9D +5D1923EF6A024A03D6287938562B +2203565F4608B2E000E095AC5441FAE2A35B13FE7EF291859A49F42F0D35C178FAAF64B74F798B0A298592590C1B0C62A1AD017589D3DE681AB119F2B427BB4247EE679D51C870EFB9B82EB4691904EE41D5BB33075DDF4B5C38F687A384F9524F9F2C87D7E624D01ED1EB69FD2C38211D893930FDA125946652FF2410E0 +D3E7 +B02C15D26CA581B687F35D111C6C703051E759541BD3DA0228FDB8BABD27B11CB9808B79D63220FD60332A88C677B4 +1980C73F +50D390CDABF42D9299D0574B0504 +3CEDD701F4402EC219B25247D7C2AB18E3F56317AD6E6462CA67B57B9CEA82F92E119669289FB97480B2978DEAF68E35C79A7E171371F3BC922FF884467AA3C7E4545F90226922846D66BCF048C6C6D8E1537B3E8FB2E63E8E446F7526D61E7C82BD8D901E7CA6C631C19140B9 +FBD5DF35 +398A3F8A71FDC0CDAFA02E4DA5 +335ECFFC02723EC97DC4D7474A1E0E6452F88DC0BB8E88990963BDE49CE30EA9E8690D55BC4E619AAC87C6C855FA4DCF2A0973A58B7CC3486BE8AA7086C6102C760B8CBB8A5B06695AD55CC048870601 +BA50885F +06B3C2D77E4EFF9C73B86E4DD3C7 +51E3FD6A3AF6E5CC2A74CFBF6E8F801D6DDE730EB40157ACF25914E9656F1C8F7FCD72D7ADDC498282D2C5DBA511E985E0C8A7750D582A5253BEB1498B40955D3D534B604BC44FF40961B1DAF3032EF1C54AA07D234AFD15983593405619D7768FB99C0A2483082A25EE3A6BCECD2562D45C195E0F8A4EB707E18EEE712A +BE4F +1367F070EF7B9FE1C47D53B2BAF37D71B872EAF41C70995A727D487389B1A23EC11088 +C3B1E315 +CCD831C1E8DBB8CA5E62D185F0 +51EC5EA76AB44ABB763E834649EA06A06BA537E06FF2C0C70F260468D2435F615F3241CA96C211BBDA47EF440D4EBAA1912BBB13ABA5 +CEA82E8C +45E23315154F35333316FE2B9E87 +2DD99B668C118DBF3445FEACD98329F926E7AF2E9B6149A4069A44FC1E8FE9CB87EEB494D4709023764A9309E24DB2FFD535340A933A5A765A6BE2FE39DFE902214A81FC22DFA5C45663DDA03D8A1A7663DE42AE42DE5330B4733EA988DE5F2BE45A77B28DA263D40E90C42B63FC6179C10F2A7E52F62D2CB874BB8DB6C2 +FB76 +4771135D7714FF413B7F1E8AB382B2B913AC9387927C865AEC1B81F397F085 +A72C30E1 +2956E342AF6CDC7BD39A4C660A27 +F619ABC04AD32B12618B90E1C43B0C3B4026AF632A3EB49D14C0620664B7D19D8F989BCFCD250D7BA20ABE0E83FD410DE74A7D1DDA98CA48D816C321671034A3C41AA73B0CBAD41D2DEEAB7A2A56E8DC3F3AD7653FC61766BC407B202C88A1BC19208312E60C5C626EA407B4 +C305466C +94841BC71F46EE936701C7DA9C +846205E582FC84A070D53E48985892E0BBC158CA2AA1715D016AF6E7245CB2B3944A301308753EC8F9A095C4D9B447C9B1DDC60476E58B40F68639FCA26EB739A083217D60A3 +AB2E30E1 +7CEB95ED67776F2EA6A76FC6D10A +F305373E85747D5AF2486DD949F76C179B858F1669661DA65822D6B34BBAF2AF3F495294ABA91CD4E48985C287B4BC49C698487B46D3358C23B71039A92CD31E0037E67C29D87623EAB1938C6D0A5E3931002EDA0743137E35F307774D9BF8BE7B7E28425EDCC1EAE06CB1FF66CBD6E2F5A9E2959F3425 +B32F787D +FF0310664D966A5A5EA467EC7EF8 +F34D00DFBAC99D48B5DE39430EDD9B334B8168D7EF55A5F5C11B38812622415CF8F6703F5508826B92D4D1A705A54D6A3F8B4C22453AD61E5ABDC98ACF902772EA494917CF952C8139FAF918CA081893947C80B46479B767127DBD8E947156898D8A818C8EDAEB28962F +EFA8F7B4 +BCF5A00E74EE39E6F0881E4C77 +381AE42DDA53F2C1F1BDC8CE6EA03A14809B7024EE25B441292847EC1EFF1AC3B4577BE36EBB46C289B9EE3076E5160174C03305979AB06FCCB529B3103EF4D41CC689E84321B278AEC2DA202AA9F53D9CE26EB0A19B29 +05AC6B0B +50C24D9399A98BBA8EC5D53EEB44 +0910361E8AC2B6EA45A167E28C3EF8C556610066EC14A3D0778D4940AB81CCBB2C4E665EA11623A4B1CB6DB390982E5CEB29172CC933698134D6A6AB20D89E49747EA59677E0DC1EFA47AA6FD07011FA48ACB8091C378E3F425BF579AF5865ADA8330F33D81D29DF2A1470C6F27B3252787C926AAC40448273DE4021 +43A94523 +A23103EDE813E045897A57EFDD +6BABBB2BBE157D1A2D53018C0742CBB6CA67FB0EF18266EF34A0AFABB4676195786815A68F5D6544B1AD18F58CA681084DF362F02ADABF4EA1E2CBC2B28C81AB1C96C74DE2 +6164F5AE +382B7492870FE23A471E65E65A +8ED13E0AF6508A5D4C998BF9A82AC92C3B5069B5AFB7249567A6CDDCBB9214D2BA89213D6D1F05AF8EB9BA2FE1BF224B92F5B452D4612C9F3783FF719DE2D3A096B444619F68A23AA41277D680631363EC40DB8EDA5F3F869D8D9BA4E4EF95B288F1 +D24C3E24 +799E1774B54103F78233B5A321 +3250E4B4E325F4DF074A467999EEB7E2173411734ABF30FEEC661A0BF3EDC938476868C9A4FBAE02D7D06A7169452A370A1B867838DF2C9886FFC735CC84A30F7763B2E3BEB9EFC444981382E981BCDF20095AEA7A13EECDB9 +84AC12BD +D6BCA0684F11B82D99A41644BF12 +3DA78DD66C276944634E6ADFC67EE9CBEBEC8A6A622393E498927ED4F72E5872EE1F6E50185BDC7597D7FBE7286665DC62055D74E87207C9F42EF9A82EE6AD8A45DC9F27B8AB5596EF5CDB94DF7AF9E0C6EE57B7C41603057C2EFEAC7459BA260886F0E72BFD6E3E299D5231A92FA8D9D7BF1049CEC327ABB7CCE8C8FBE1 +A007 +4D618652DDE48F00F3F83A26A5B8 +7895B860 +CE2A32CC0EEECFE20A1A9AC73B31 +E33AE09B8FBB473EA6A17E14C6C0E1B63451931302FA4D71070065D9F763F1C1799D0C28D0758710096AD3827AEA148F0269865CC61C456C002F8FC4F81B1EEF079450F6FB7FCF21CAD192AD5C7B6607AC48E3A5EC7B7413A58FE65784584A7C94453B0CB0C99A9960CFB499A85F8A194579D0BC614B8BC6AA2478EC6D81 +65C4 +AA7C1786B92CD21A66FC907E1C3D4A8BA424EFBC738B70D38D +1F5A39BE +6AB4006E33E3EDCD9D8C96F901BF +6D9816FFDED54E39B0B6561262FC4A862773B5C79D45BBF2F28C86711A07BA2C914EC18A0DDA9B3FFC7FA512BAC23DFD8924F32D0E8C3B3F0868BF667B90F43E65F166FF4F5842055278343F040CE47954213BD96C4ADAEF22D04777B7340D006182F78F2680F45065CA975F101202E53D060D15C48B013EB5BF21C29E11 +FEAE +BD7DDA44 +B43FF5C5E5E9FFF8E2CE08C395 +3F99A36164C9C775EB4BE77C542835CB83DE64B145385F1D4F7806D317081A4A9A9F39D23FCFC4DC1AC8BF15877E2CCEF797D2E3E01D4A6BC9090344BE66AF +DA63EBA0 +179BD7D01F282BA1E3DF1F701837 +6F68D27A7DF21D4ECCA4683AEAD00933C5BCE263A6DF91A64286F154A37A3875E532E3BCD986935EA7E38460E5285962E950AFFF11E71B1B043194FDE2749D0A37B803EB3F63E806D321C593EAD111863972D0F5EA661D9F6E371E4AEFCAD25648582DC6F815AD2AEC +4891E48A +91088B4DCC4F4ACE98FC4CF5D9 +7E5C253E7BF52CC7E9EAA1A62F4DC39317A25A6FE983 +1C349FC8 +B55785BC9E4663FF6142F4B0E5BA +DB6E56F734E6C39E +C063E38A +7B1F879E50CAB4FA3EFC9359950570D97E683BF7E43C338F704578846BBA3546BBBE +6FE358C1ADBBC280B51AEC12318EA32E2F99EC65A527C9CF13EFB947531F9FF7B733E466739A +EC0984FD34FFA7EA84C2B93E66F01565FD9ED245A90A96C2C575D7 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +%Defining font PSOwstdutchb +%!FontType1-1.0: PSOwstdutchb +10 dict begin +/FontName /PSOwstdutchb def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001000 0 0 0.001000 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 1 /C0032 put +dup 2 /C0045 put +dup 3 /C0047 put +dup 4 /C0049 put +dup 5 /C0050 put +dup 6 /C0053 put +dup 7 /C0054 put +dup 8 /C0056 put +dup 9 /C0060 put +dup 10 /C0062 put +dup 11 /C0068 put +dup 12 /C0072 put +dup 13 /C0080 put +dup 14 /C0082 put +dup 15 /C0085 put +dup 16 /C0086 put +dup 17 /C0097 put +dup 18 /C0098 put +dup 19 /C0099 put +dup 20 /C0100 put +dup 21 /C0101 put +dup 22 /C0102 put +dup 23 /C0103 put +dup 24 /C0104 put +dup 25 /C0105 put +dup 26 /C0107 put +dup 27 /C0108 put +dup 28 /C0109 put +dup 29 /C0110 put +dup 30 /C0111 put +dup 31 /C0112 put +dup 32 /C0114 put +dup 33 /C0115 put +dup 34 /C0116 put +dup 35 /C0117 put +dup 36 /C0118 put +dup 37 /C0119 put +dup 38 /C0121 put +readonly def +/FontBBox [-21 -209 798 694] readonly def +currentdict end +currentfile eexec +D9D66F633B846A989B9974B0179FC6CC445BC7C8A959A39A32E9DCE7FAEF17EE3BEC9F +50E1A6FCA651FC4B3769A0A91041557502E25A5D6180FE25A3D11BF079E1DF66E54EE9B7C229AF891739707A2A0EC140306B5E43E52B79BFB89E459E50 +6EC6F610A70775A31C460976C4F79449D86E57ACE491E5C6BF20CC4307B1DAF7630252 +E9AF8CFB69B50EDAE9D36A6104AFEF8832F920FD2346B2C7104CD11E3BEE999CFA9F5A +49DB3173EE48D1C82994237F360407B022E0B4 +502E94EA8B493651EF2D03F0B513D655047568325B512AE6 +6AC6F53F3848CF70DE25481CC65D8B1A5793AA +3C4282D111112BEE28AFCA7A3808D4444C4669CA +84EAAAF989219F51AB3476A1B0B5F2246BC306E6 +625C6679C417ED2A8E9BD010DE37D40265074C26842744B36D3511219816A5C27D3502C6187BCE +3912C71DBF05223FFCC33D67 +A75F80439D9C9AA951 +8032BD10 +FD5AFCD177D9EF083EA3CE8A94 +3EB45532D6EF293C6818FBD1CEB4EF93541AE403A4D4FD +B36A7639 +D5E40E84F2A27439DEB50EC74C +20E497DFFE29579044EFD8FEBF892C5F8D3468F13FCFCB528145 +52E341B9 +59EB6A13CB325E1C6E2558C0BA +02DE051BA9B70D1D069DF9F06D73B32E05C33FAF159F20532C6A0CC08DF95AB2275020F28D3B0FDEE5DA3C5E25F76B747A61031A4AC30F0B490EE779 +3E7F3D2E +E6D8CAA9080416CD2128C2FABE +2E9DC3B5E3F3C917F86449B08F856B69D0FBDFEC16D380D4CCE15F65B37DB34B65423EBAB5D8C817A5DBEC0558834F4E5AC2BF65EA646947330E2020C4F404FEA57A71AF9155954BEEF98CF33257F3C079C8921F +BAE00F0E +F716C7EEB0ACB7414B2AB45A87 +B7902B284D1906A8F914E768A278EDF82E5642C2599FC82648C61BFA6DFE8A5AD16C273CA9D8ABF6083FFCAFC97088A61BD923087EE9AD675DDC9688833F7842F0886DC62ADCEFEF64A3F72A068C33796D7D5AEE3FBB +9B3C356C +A8D9209AB0A496C6014A1A9E8FC6 +24FF44D24A904A3669A3F8FAB722BEF9ADA99F3AC642E6F8764523C81467DC646BC5296F8C5DDAA2A1FA23D82C36E744FEA78E971BCC4F0E2850891FB5AE9F8A4221FF038DA16966720CB53207B31585FB88A831057BEE1048AAF6DE21350109F20EBB64 +8A4F3A7D +C0A98A70CE9A41F96EC98BFC7E10 +7366EB90B005C270899F564CCDFB3583B2ED1B6ECFA5E2467B8F55BA5A646B3AAB98BD62B5E92040238211B0B0E4195E9090468D810AACE7ABBC7AE9FCFBB6A191846710ECF100F0D1D89AA772E3B85D0E686972DC5F768AECD8B2AEE6D6914C53E1BE47ED4206432298D16D6D7B5EE063AFDACF02C668847BB3 +7BBFB985 +B96339C1E5998C65F99460BCB8 +1A078A0DC0580CA635B7753ECFA3B6029E59120EF08A24B3C3B6073B4364B49F39E2D721772FD3D059 +B38A5F19 +3CDD6025831CBF4006ECFCE687 +6E4E770C2B48F2598DDC7360BC244BF220173DE244CC8720956FEDDF40D2968D77A1869DD7A1B2 +30D6D598 +2E9A9714047EFBD92594CA348F +F578A21DA106F9241ED8748C9DFBF23275D85A12CF552D135A12AC6146280309D61FA61F1AB5E73894F098DB9D8DCEDF92D8115865F7BCD2949F47330C027A82671520B34657979DEA015CDC3CDCDF14039D1C18A7CC12 +16C1F22D +B221DC0E2A5A06F6D6537BEAC939 +D78296077C6C5D2ADBF764426D6D2A470B873C44248A2CC0813664090338380001F7C29AA10478E562E68CC691F30DCB48574CCCB2586996EC479A0463D89AFAB5B7F8BF914F0E31CB55D1E9C18E69B77C6D20AF399CD430F2731B20A09D8E044C746B4659AE58649201DB8D942B87B294E28D6779603D +978FB4A8 +4EDB237C6E8673697477FD4AB321 +6DF6AC300A3233773BBB38AF0EE55FCA9A8E53BBDE4B3BBA6243E034A38CA2269D2BBAE767929FFBABE625F335FBBB0EBEB2C33D001E6E43CA312B76259BA559BE8DE5E76BB9197B3B2C96ABA6D45BBB73C564D58104DAB23941990071D5FEC804D7288A +26D8DE2C +E6D91E062AB059FD119E399F7581 +1DBA593E53F47DE0A620DD5BD94C99E6F29ACFADA70A2A27F14508610EA60063D4A2C027A4CBCB21663394E433A52D3EB3ED7D983B490E2C61C0D32F42B4D6DFBEE827B0AE67D0403366480935E102CFADB5CFF8049CC05C7E383C39E7C09B9FF19D3DDBE5FB2F9D5B769797C22EC75B6107C84A90 +3716DEB3 +C2147DEBCFEC39EF6646B7457C36 +BF9A08460A84D442089F1300DEC24ED9FCF4C9EA5AA9B7C095D0A06382A360971EF76A4C5027154CFD8A1BB83F1B7ACFCEE8040AA331EF81F83A6971A8851F6D132CC5DEC163859D39C1F67AB28D9CBC5F7DBB5F60CADEE4095CDFB7C3F3C1995BBC3BDB020BC2 +C6C8B024 +AE0A311B8C1BA5B14377F6BBDC +352DDD6E476CEB301EA4309DD62DCF75E9F992BB3676CF565174F5EC2320710108C01EFFC81292EE87C3EF00DF2F834A1950B85F6FBD4EAD3D9A7EC934E6224D032E2DBE90C7432FDFB5DEE314F5E50CB3D1641A15FCEE82 +1A754A77 +98CB055AF023D60CA1FE89377808 +FAA8E354BA2ACBB78C1F038D5F4B2CFE28B03BBE57C2E2041C06A8AA027189867AEBDD4A02CC2DD9C21AE5E1062682FAA964082D6570F84A8CAECD949327464F86F9F7B0A5FE85C4A585F01DF4A8D6C645C467DD31C50CF3CE885B7B8AAA50A773ED4D9E3A7A1460740134CBF0A64CDF65194098A38B413E82A0F8CA803E +D1B2 +2F288A9C +5392A114 +AC7BF81AE30CA9CAE203135E00 +AE34388231DD4CF293143974846FBBF514E9BE9BFDEA79783A4DBEF0E62B9429E80348E9239575259C65708D37B4B8C110A1FB19651CFE1C79E2F501532E08F60CC41F4B54327D3D4EFC990DEAE0F8023AB95FBCEE2F57DA22B79054A8EA +0786A0A0 +68D5AAB660286C85BD23B66124 +203536CBA7825F0A766F9F4F00FCAEB803D4B959CF3AA364DAA8904B99439ABACF0D5F45CBA9FFD587E6EE737E4B9F559026857237A821CE0A9D04D8E8C618024B448DEAF0F84CE230B483BC878A835E1A67 +3E12D5DC +0306FEF9EB10178992AF24FEF55B +06A6036A7E13B5A65680448AB4539D0F7684430F106EB4901ABF47AA87145EB200597DA8E9A6260A1BFCBF5FE1721C343D82E44C64CF8C4D634EBC8D61CC42C16040229F89C8A807FA6EB4E4F68AAFED649EC42C9D8CC9BF17DA0C4D6E4B96456F466E18BC4CB5C2E53B1C46 +15A3708E +849EAE6C792DC4FDD8AB0C6514 +07A581025BA58CC34A92E8B89F462C486EC0B003D3B167C31F1656E10330DC603125CC2CC36942D795D5CBD9E90AB2EDB6BFD5A3F03288571C7337532CC053E05FE685EDECA2F0452C439BC15141AE2FEAEF4CCDEB6E18FEC920B9CD +ADDC6253 +5C28B065AB04624C26CA5BDF2C +C4DEF46F7E537EE95F80BA580EFF9BC40F3A0DC8CCCF8D6FD52189CF6282643374F89FB227C162E4DEB63F8E54716596F4A6D18D99755ADB68CD52903888E9F7B8A90E3F7D3C2EBFB344739E1895DA5CCB951F75F9D528BC2EEB76511D +DCADA35B +5AF8F64CC0D592CECE6D2945F28F +1190BE3FD63169C0F2620C3604A8C870FD1BFF61C6A41A329910846E26F1E539ACC3FDDAF1B26FCDD8BD40759E0E3A7FDB815C11515BCB8AED7E7945BFF3401A05F419CDB758B84B9A9DCE5C9DA440EA9625921A1448713A05168B2CD9774CC2AF145F623867F2EA80EBBA562746306D1B33995B55A95717F86AD77ACFCA +6430 +CB4CE401392BFB8FE66B748757CA674F1D411241A725CAD122D52083281357E77BF56D6FAD +B7F07896 +A4B3233F0A23894C077790BF7B6E +45B4F867E74AB05C9566A4966388EC5BC6950A7335015EB4C022F9C41CEEBD419C8339C71C4B98B68F5258A80A8EDAD7D1B155298AFD28A34A064AD95F1382067B7B6F7180DA5E03C0979145282CF9312437A7454587F86C7B661C916D88A53B00F265669AABAEBC +940F2688 +2FBC0E46199FC2F5E6703BC736 +6ABEDC188884393FDD07353BB01BA54B8DB94EF537A803BC40F9F20C4FE01BD0AE578B8D76155E0B86EE2AA2288E8EF2F7EB7732E81BF6DD6D1D2C9C82113BF4AE187BD08E637DB2D60F6503882A +7ECC61E8 +BE5C2A1E9ABE7CE9B3BCB17F3714 +CECB3E580EF0FDB2C3AEFA51A4E3E0E9F247C3C644E74732C52BFB84D0441BE8E72FC76F264A7855E1495C756F326758F34FFB23E0369752D6C35D7813972067291C40E8816CC990AB70F496D21E541A7D95879C88305EF0366A7CEB300F44F2FAC305014D6C67D635BF1CBFA03B49621833BFC3956A8D90B8A2484130CA +15AB +12ED +20AFDE86 +2177D09AF017B0AA948ED8DA31 +BAEEBE73325830850E03C5F6BBA6C888A8F8D8237EEAB80B911FD99260763E477B6641083FC6B343BB3008798831FC6CE81F7D2B +6B55CE51 +F152837822230D6B23F31929DD72 +27108EFCB362F5150043F3C3697738317A7FA9CEBA901356130583F73CE7C2C32F0531EFC4C44630C5F3CF8B3D0BB8873E4B9111E0755D91AF0AC1603AB40234F943D605EECF7D65F58CEEDBA767E171E7753BD851B09230D129699BC9C193DB37C33BEC82D96ECC974C773BD05793EB71440993838EEE4C761EB91FB85D +8E28 +C51879A3FBB9C6EAA0DE4487AFA02C332D71D588DA693A0920F5B88E +4949138C +7227C01ABAD32E426CA9DAD20407 +6F8CCF23A49F15B3931AADED4ACF80BB89940E76A3A891A34B6A653120E6E34101050208AFCCC68C2D70F0F186850310024DA8985740D09FBFB798F7304CCFBE86E884C6F78189F7A780B89998865ABCD033843FEDACD59B9D77DBAB29D905C5A4373A3E0AA7ED +11518F55 +29D345B7F0273D3E797715A70A +BD45850783B195B27F0FEAB7587755A45B27F4F26AB06656F365806E45061B3E9B909D231324403E73FB099EED0D2FFD3B41A6EA43C8764611A577D3B8F48A035CA8A19EC720 +5B0F13FD +476218FA658144261B41D95025D9 +B717498E520E66C1F0288C72C7B20D897ADDAA20D189C7E78604983597D69145A15C068B24A213F58EB95FC890BDD77C9E1595F12F07E35AAF90347298A7FBCC9BD40D44D2D2C1D7739CE248C34F2D3036DC32894FBED2A6437A483F20AD0D521EF1429127E3A5E24DB70B6BD42DCA5CF9 +D5269092 +D0CD38934A3150FC98EBE1BDF9 +8378FC18727FE41081777F5131F28D7DE73E1EAFBD060721352BFF2264430E2BE059077311DEFF2FED088FDF13E9924914952CCF8F61BAB21A6085176D6FE42BE476D45779F9821640F23968277E7EACD019582EA7BB701A9A +1C35B329 +6190A150EB8098D3E6591D40A984 +E6E75ABAE4558923109CE54202FFE40B51462001138D16E8F00571AEB6BC6FC36283C263EEECE209FCF30942C584AD741BE8F02347A9DFA0209EA454926C7E5545B2D65527F629ECF6483F793AF287BB6C78718AEF3F5815BA7EB0435E4A0694FC784506F40DD76B0968F8BAE28939F0FB457B3D8B92D5A594 +ECE01FF9 +73268D3B36D44BB3B6728B11CF +5D824D9B1A0875955F69F131CE62EA47BDEC4A91128CDC1D654EF0A3BC2E5BF59754E170BF43BE019FEE7010D47E6607DEEDE7748FAB9A80085BD206F9BFF310750C1749 +5A8E5CC8 +79826230385B3ED0C32721564B +8709C55F0FE6DDA77F157AE6BE2B8704F7BF2905784AAAD043F2BC4C3AE0E072F647FF8BAC0423B12C4F8ADDB17DF2BFE05043BE1917EB903836F2906244DA15CB29C6F50CEE2F59781E74B1F7DDEEF040DFE2A4A2F64C6E231CAF +143CD9E7 +08C4F28302FFA58E1765E8C41C +EFA4148AA40A6A00F1616E2D17DE438C7C9972F10B4845541CE7AC8A29FC41FB9E90029F3E16731626A2AA74E5056A00461EDD7046C78E54EE72738E677CED664A5244FCEA553D804AB3F6FA88A2FEDC79A43AF58BD44910EE63FF48 +06F3D4D6 +90CA51CA188BE6D8C32692EC4DD0 +41943F33F1B89C4031CCD84FC5923A9E8DA8A988997D20665BF238B1E512CAA1C8D728E54DDF6B84AFF9411D601364EEA7CC7B0615DC0F474FB2A7AE7AD0BEE64F81406213B75001677399504FB00F84D3BBDF4EFCD588A031F20E08E6CEAC0FA39B2B4CEB1C26224EF30C61B94133DCA74BC94A4B67BA6D2B177A9814DE +979F +833B08C448CC2574A8A228 +0793726A +3E29D08919CCCD6303B23EBFFBFF +D909356986BC7EF02C9B3D9ECE72196543265A045647A8876C344F4B8A18F0F84E970E501BA158E0CA3F792276A1ABF1893C541F7E4716C39115DDDA604030A4B3321E78BD03CB9F2F1D6B85002AB83AD9AE2B96F0BD006FDDEE90130D897A08E13ABB3C8B810DDB57FF58A0982AE622B1EA7BE56FD26CF90C7BFDFCAF67 +B848 +C7 +A16C9EE9 +BBC661E025435908FB7E377558FB +DC1A504365B81E4D +12FACA8E +7A8338048084E1ED96F2482290B1F16D60F87113B0304A91E9DCDBC2C634233DB5C2 +4108FC0F2156DE7EB93519847B6137F13522D72425445B249D2461F4CB3A69401B3DBB474994 +B59C00100FD722AA7652FC5B34DEF49A23019D2EA361FDE44A2ACF +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +%Defining font PSOwstdutchi +%!FontType1-1.0: PSOwstdutchi +10 dict begin +/FontName /PSOwstdutchi def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001000 0 0 0.001000 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 1 /C0032 put +dup 2 /C0046 put +dup 3 /C0047 put +dup 4 /C0099 put +dup 5 /C0100 put +dup 6 /C0101 put +dup 7 /C0102 put +dup 8 /C0105 put +dup 9 /C0110 put +dup 10 /C0111 put +dup 11 /C0112 put +dup 12 /C0114 put +dup 13 /C0115 put +dup 14 /C0116 put +dup 15 /C0118 put +dup 16 /C0262 put +readonly def +/FontBBox [-144 -228 513 724] readonly def +currentdict end +currentfile eexec +D9D66F633B846A989B9974B0179FC6CC445BC7C8A959A39A32E9DCE7FAEF17EE3BEC9F +50E1A6FCA651FC4B3769A0A91041557502E25A5D6180FE25A3D11BF079E1DF66E54EE9B7C229AF891739707A2A0EC140306B5E43E52B79BFB89E459E50 +6EC6F610A70775A31C460976C4F79449D86E57ACE491E5C6BF20CC4307B1DAF7630252 +E9AF8CFB69B50EDAE9D36A6104AFEF8832F920FD2346B2C7104CD11E3BEE999CFA9F5A +49DB3173EE48D1C82994237F360407B022E0B4 +502E94EA8B493651EF2D03F0B513D655047568325B512AE6 +6AC6F53F3848CF70DE25481CC65D8B1A5793AA +3C4282D111112BEE28AFCA7A3808D4444C4669CA +84EAAAF989219F51AB3476A1B0B5F2246BC306E6 +625C6679C417ED2A8E9BD010DE37D40265074C268425D7C73E0D9FBC2C51FC5D7A4C8466A0ACF3 +EF6A51E852ED0077B2894802 +F6E0E5B330993F73EE +0777F375 +11FFC827436FEEDF46428460AC +283786C06FF4BE317A706870BD8E4E31C6D7A32AB15C24D4A365D0C5696B79 +53A17EE3 +658EBDF535BA48126D4E0072FC +B2A68715F12ACD23CDF8729640334A81E2AE55C931228540C4 +E4786B73 +D1480CAEB99C3DB225AB90EE57 +BC17191EF5E11906AB66795A1E55A92493BC699D34A9B047227E8036353311D267E02BE1DD32D67DF15CA17961F9FDB669389D4834B9A400B2273A2AB5321EC2F98C6B37536157D3AD3F9EDFE42F4B741A58B9D919EBD96446D53AB1AF5C37BA +A8CE7824 +C7FD4F7907058373C0E937046A42 +AC005815EA0CE755F328178989CC2C12804BBB6974BAA80A7D58ABB396A0397962B42E5CA0F9DC1107855FB16D457395C7EEA2BFDAB2BBBC97E82C246A0EA0A9F6E8398C3369DF82E5D48F114617F26B947DD6742795DE56028C0EFC605F9CEDF113DBACB18A160BF15E5E2BBE9175F0A26BEE78392DA1CE0CE951F13588 +E399 +2ACCE0F43CE6739D4AE10BDD0D98CF40E864C3D2755F25A00F14DD6B1F22F1C45EE05A0407EF4A33C55695375F2A0F75 +773D29E3 +75F83C40166AC7B537EB60984DBB +147C7E2F4F8CBF69CE7F03EF935806AF3DF17C56889C5A589DB144728EAF4C1EBB111F686D873DFFC14BC2DF96EC962B5EE2C4029DA617E6DE6C41B2593ACF6DA637DEBC9CF2F7CD3F56A2DFA07305B1C0E9F43C0A7F5EEE3D16DB26A6C0507232DC3AFF98 +EF05B31B +4E27DE456D3022C6797862D21FC0 +6688AB93C682850E627DE0BD2E6EDCF28632AA6A5BA8AA04D484F5BA607A183CB9A897EB54CED9FE344FCCEB4841E213EA990CBB5F3908FD6019F574D3750248FF7335AB7A6C9342964F9D3891812B10F07B9441F833EC66655F6E20C6A2B66E31309053416F5C82E657BF8CB8B6804AD634FDE605130F563DAD7E33DD14 +7FCD +722ED3C8 +3662DE5D +4B0A79F2EFEB7EE239F0CDC435EC +AE7B8342B639400F324CFBC8CB8CEC28C46306A9357B80C97EDC11CF0954E5CB0D4B3D5E4B20E80BB790BDB6682C240BD10CA8C4F0739D19A5A1B06BD9E553DBC1F8591E1A0E26DECDA8F8767050EC3B887B41EED659E7A7EB03B51572701D290A7192DE82799D4242126A33BA876BF3E9659D0C9AA696F33C +735DE321 +38AC9651570E6852CD6D063A416A +CB95507973E95452A3CB362BDFEF2F938987EDDC32F882B7B8084B147A8DD3EA6473FC098DAC7D657C449C0277AFBA195331EAFB7B73D9EF9BA2EB0240EB3F036EA622F25BB629B8632320AE23A35E537220846AAEBB998AF663ADAE46909714D473764AAB0AB31F94CE1BEA0229FFFBC5A6AFCE25123035B466C054B8A1 +CBCA +677BDC0A1DB5634ACE52D10B79B4BD2998415116C1C2296651 +39558375 +C9C465A71C7F90A0D77727D38B +9EE253F3957FC5168507BF9447752AFD47EB16D5B7F854EEDB87CB35E31C23DBCFFED61213991D851F9A899212B7F18085E0E7BF7DD081A20DF70ED5155C8B62C5A65ECF02E5F4C845FA3A4313D5569C81B41698B1C8DCF65920118D68FDBE +4595E361 +AA0F0BDFEE407F109EFB68CAE798 +98785FA39074F79CC70FEB073609DCDDA9ADF7685DC14756FE906E6DD650BD18E6655FA34D97BA5196C0A7103B3F0B6B739CFB0CFD2195A402081FCDDCC0A3A87D91D1F7C0A1E1A4C5868DB745F6AEFCD89CC3AA8F9AA6707A65621CD6F3D848BD445BE04BB6FBB582C6D7D7FAB49326D90618EDE2C5B280F0CA6B1FFF84 +D671 +AC42AB66FDE8F2A952311BBD7BCE58FC5A85A6B72086FBB9179C3E90BB4BEBF3D65BCEF8641758586819 +F45AEA8C +FC2558922CE3D079CCD71DAD38 +C0EF448DB3A75A579E09A02D89A7215CE7D592BE566BD46EA79BA1EAF3CD5CA3AE0519655018E173BC23DA58456704318C2B9233AE2303DADC2367445627DEF464EC8755980E4FB2B07409F01D5B39930C05E1D30A75AF7A8F3B64 +8ED19457 +45C8D7F881684A77C417723A236A +EDFF5676CD4D6827827DBBBEA0150C950BE1E969CA9A4D2F05A4EDA54D06AD1CE42FFAE4ED02A66FB4075687ADC6353B19FE6082BF79CC46C44E940AEC8505676573F380904C20F6A7ECD78789EB00986A6EEB0E9AF69B79AE622EBCB668DD7AC81B4252023177884FFDD7017E79100DA1C97518273D +103EE633 +24B108E8A88FC7CE5FE92278F3 +1B2E573F5D7B7A0142223ADC63D5B5F8A6B312915AC7597334E131A5626209F0C3C0E6F7642F46025A4456A0D147BFD7EBB917974399148167D6B71E0F72F84D2A0A8DFD20E4508EF992B497A9698A80780087442499E6 +FF61B6FE +CEAD2A2F3B12F2AF4B08F74DC7 +1B56B74D0EAE1C8812740231D5ACE80E7F0CD3A506C654CD3E9D312A78DDB2379CFF4D3B8F8C0E87BB53D96729D1DBC4837763EB72CB8217C98361352F24FDEBBE0FFD82AB11C524A90471684FDCF0B6EF597D95F64FB0847606 +F968D3E8 +223A62D558D62E40456DAE934A +AE1C8B84A7FEE7E0EA855D85E53BF487DAC2BE94EC889A83 +BCFF7475 +9926ED2514A70AFF31C280B61524 +827F3870890A460E +17B99898 +7CA435388A80497A5CA2B9FEC2115097F0243233995FE4DC407F346265C4B8BF7705 +D162D03F3C0FE594C0F3735E7C79DDC9AF9822F9A8C1AE21D031CA847F9E31AB3060EA32A451 +C787C0A1E81428620623F66B869DF17A88A10942917DA0FE725DCF +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +%Defining font PSOsymclas +%!FontType1-1.0: PSOsymclas +10 dict begin +/FontName /PSOsymclas def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001000 0 0 0.001000 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 1 /C0069 put +readonly def +/FontBBox [106 45 775 713] readonly def +currentdict end +currentfile eexec +D9D66F633B846A989B9974B0179FC6CC445BC7C8A959A39A32E9DCE7FAEF17EE3BEC9F +50E1A6FCA651FC4B3769A0A91041557502E25A5D6180FE25A3D11BF079E1DF66E54EE9B7C229AF891739707A2A0EC140306B5E43E52B79BFB89E459E50 +6EC6F610A70775A31C460976C4F79449D86E57ACE491E5C6BF20CC4307B1DAF7630252 +E9AF8CFB69B50EDAE9D36A6104AFEF8832F920FD2346B2C7104CD11E3BEE999CFA9F5A +49DB3173EE48D1C82994237F360407B022E0B4 +502E94EA8B493651EF2D03F0B513D655047568325B512AE6 +6AC6F53F3848CF70DE25481CC65D8B1A5793AA +3C4282D111112BEE28AFCA7A3808D4444C4669CA +84EAAAF989219F51AB3476A1B0B5F2246BC306E6 +625C6679C417ED2A8E9BD010DE37D40265074C2684268F16195489648993B9C4D3B534FA887C +DEF605FA87B991F4D20A8F78DACE +5A54C070E03D5C59D9D2D3E06B09CEE028D68B62AB3AEC43C1DD20BA70D288597D9BD8E06818FF764EBAB436723988E8D7CA59E16D39032516BFC5D552ACDEEC6BE938BEF2F43CFFBC811C3626C4DF5F8CF080676520B51C60CEDAD1FE6C92D1431C702174CE517A8FA9377D075A0B6833DAB101DB65397F1419EF5F0016 +004F +6F0824F9657BB4F1C8F981709956865F6855EFAE +9242AD55 +91BBBEE163D844DDA894E13190C9 +2480439E4C71CADA +BD043A9B +A315CAF72652AA7FE6DB2E84D82A6111CE4DE90C02DA0AFFE2620922262A45AB4ED0 +EEC9F4520DD12703442F7D028D4526BD8B771E09FBE11B2749E2D3906894E8D4BFD3F379F14C +3C874F550606965E22FE487B247B5C2D06728490C8F2A3B588CDFC +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +/DPIx 1270 def /DPIy 1270 def +72 DPIx div 72 DPIy div neg scale +0 -13970 translate +1.00 1.00 scale +/wst:dutch12 12.00 /PSOwstdutch newFont def +/wst:dutch12b 12.00 /PSOwstdutchb newFont def +/wst:dutch12i 12.00 /PSOwstdutchi newFont def +/wst:dutch10 10.00 /PSOwstdutch newFont def +/wst:dutch14 14.00 /PSOwstdutch newFont def +%%IncludeResource: font Helvetica +/wst:helvps10 10.00 /Helvetica /wst:helvps ILEncoding 0 declareNFont def +/sym:clas10 10.00 /PSOsymclas newFont def +%%EndPageSetup +GS +0 13978 10801 13978 10801 0 0 0 clp +wst:dutch14 SF +0.00 0.00 0.00 1.00 setcmykcolor +<1a2735312733280e01110112272f252a2e23332c01283033011927233436332b2f29011a27353830332c011c> 2207 558 0 7384 -1 s +<27332830332e232f2527> 7375 558 0 8593 -1 s +wst:dutch10 SF +<0d> 9434 13300 0 9522 -1 s +wst:helvps10 SF +<4e6574706572663a> 1322 13280 0 1949 -1 s +<205265766973696f6e20322e313b20436f7079726967687420> 1949 13280 4 3868 32 s +sym:clas10 SF +<01> 3868 13280 0 4019 -1 s +wst:helvps10 SF +<2031393933b131393935204865776c657474b15061636b61726420436f6d70616e79> 4019 13280 3 7133 32 s +wst:dutch12 SF +<1b2f2527> 1271 1431 0 1757 -1 s +<00352a27002e232c27282b2d27002b340025363435302e2b3b2726002334002f27272627260600342b2e312d3a00272f35273300352a270025302e2e232f260e> 1757 1431 10 7723 0 s +<03> 1398 1778 0 1504 -1 s +wst:dutch12b SF +<001c111a1500191d2122111b1b> 1504 1778 2 2683 0 s +wst:dutch12 SF +<2833302e> 1271 2124 0 1712 -1 s +<00382b352a2b2f00352a27002f2735312733280034303633252700262b3327253530333a08001f2a27002f2735312733280027392725363523242d273400382b2d2d0024270025302e312b2d272600232f26002530312b2726> 1712 2124 13 9531 0 s +<2b2f353000> 1271 2369 1 1666 0 s +wst:dutch12i SF +<030a0b0e0309060e0b060c07> 1666 2369 0 2656 -1 s +wst:dutch12 SF +<00303300352a27002d302523352b302f00343127252b282b2726002b2f00352a27002e232c27282b2d27080019232c2700382b2d2d00232d3430002530313a00352a270034232e312d27003425332b3135> 2656 2369 14 9531 0 s +<282b2d2734> 1271 2614 0 1643 -1 s +<002b2f353000352a270034232e2700312d23252700232f26003727332b283a00352a233500352a273a00233327003427350035300024270027392725363523242d2708> 1643 2614 13 7474 0 s +<1828> 1271 2961 0 1422 -1 s +<003a3036002630002f3035002a23372700333030350023252527343406003033002630002f303500382b342a003530002b2f3435232d2d002f273531273328002334002300252a2b2d26003028002b2f2735260600342c2b3100353000352a27> 1422 2961 21 9531 0 s +<343624342725352b302f> 1271 3206 0 2219 -1 s +<00352b352d2726003c1d> 2219 3206 2 3062 0 s +<362f2f2b2f29002f27353427333727330023340023003435232f26232d302f27001423272e302f080200> 3054 3206 6 7053 0 s +wst:dutch12 SF +<1a3038> 1271 3552 0 1693 -1 s +<00352a233500352a270027392725363523242d2734002a233727002427272f002533272335272606> 1693 3552 6 5238 0 s +<002b35002b34002f272527343423333a0035300027262b3500352a27> 5238 3552 6 7450 0 s +wst:dutch12i SF +<0003060e04030d060c0f0804060d> 7450 3552 1 8506 0 s +wst:dutch12 SF +<00232f2600> 8506 3552 2 8930 0 s +wst:dutch12i SF +<03060e04030809> 8930 3552 0 9461 -1 s +<10> 9461 3552 0 9531 -1 s +<060e0502040a0907> 1271 3797 0 1969 -1 s +wst:dutch12 SF +<00282b2d273408001828003a3036002a233727002627252b262726003530002c27273100352a27002f2735312733280027392725363523242d27340034302e27312d2325270030352a273300352a232f00> 1969 3797 14 9138 0 s +wst:dutch12i SF +<030a0b0e03> 9138 3797 0 9531 -1 s +<09060e0b060c07> 1271 4042 0 1868 -1 s +wst:dutch12 SF +<06> 1868 4042 0 1921 -1 s +<00232d35273300352a273427002d2b2f2734002325253033262b2f292d3a08001f2a2b340027262b352b2f2900343527310029272f2733232d2d3a00332732362b33273400333030350023252527343408> 1921 4042 11 8854 0 s +<11> 1271 4388 0 1434 -1 s +<262600352a2b34002d2b2f2700353000352a2700> 1430 4388 5 3063 0 s +wst:dutch12i SF +<03060e04030d060c0f0804060d> 3063 4388 0 4076 -1 s +wst:dutch12 SF +<00282b2d270e> 4076 4388 1 4478 0 s +wst:dutch12b SF +<1d15221f152016> 1398 4735 0 2055 -1 s +<04050807060322131f> 2669 4735 0 3538 -1 s +wst:dutch12 SF +<1f2a272f0023262600352a2b34002d2b2f2700353000352a2700> 1271 5082 6 3538 0 s +wst:dutch12i SF +<03060e04030809060e0502040a0907> 3538 5082 0 4767 -1 s +wst:dutch12 SF +<00282b2d270e> 4767 5082 1 5169 0 s +wst:dutch12b SF +<1d15221f1520160021222015111c0022131f001d1e2511192200201e1e2200031e1f22031d15221f152016031d1522211520241520001d1522211520241520> 1398 5428 6 7087 0 s +wst:dutch12 SF +<1d> 1271 5775 0 1434 -1 s +<362f2f2b2f29> 1426 5775 0 2051 -1 s +<0023340033303035002b34003133302423242d3a002f30002d302f29273300332732362b3327260004183500382334003634272600302f00302d26273300372733342b302f34003028002f27353127332800382a2b252a> 2051 5775 16 9531 0 s +<33272326> 1271 6020 0 1678 -1 s +<002833302e0009262737092c2e272e05003430> 1678 6020 3 3582 0 s +<002b28003a30360023332700362f25302e2830333523242d270033362f2f2b2f29002f2735342733372733002334003330303506003a30360025232f00312b252c> 3582 6020 11 9531 0 s +<232f30352a2733> 1271 6264 0 1979 -1 s +<002b2608001b2f252700352a2700282b2d2734002a233727002427272f0027262b35272606002b35002b34002f272527343423333a003530002a233727002b2f2735260033270725302f282b29363327002b3534272d2808> 1979 6264 15 9531 0 s +<1b2f00232f00171c07202100343a3435272e0600352a2b34002b3400232525302e312d2b342a272600382b352a00352a270025302e2e232f260e> 1271 6509 9 7053 0 s +<03> 1398 6856 0 1504 -1 s +wst:dutch12b SF +<000315221303191d152214000213> 1504 6856 2 2721 0 s +wst:dutch12 SF +<1b2f> 1271 7202 0 1559 -1 s +<0034302e2700343a3435272e34002b35002b3400313034342b242d2700353000292735002b2f2735260035300033270725302f282b29363327002b3534272d2800243a> 1559 7202 12 7176 0 s +<0034272f262b2f29002b350023001e181617201c00382b352a> 7176 7202 5 9531 0 s +<352a27> 1271 7447 0 1561 -1 s +<002c2b2d2d040c050025302e2e232f260e> 1561 7447 2 3171 0 s +<03> 1398 7794 0 1504 -1 s +wst:dutch12b SF +<001a191b1b00020c0f0d00091f1914001e1600191d1522140a> 1504 7794 5 3991 0 s +wst:dutch12 SF +<1b2f> 1271 8140 0 1559 -1 s +<0030352a273300343a3435272e34002b35002e2b292a35002427002f272527343423333a003530002c2b2d2d00232f2600332707343523333500352a27002b2f2735002623272e302f080011> 1559 8140 14 8124 0 s +<3500352a2b340031302b2f35060033303035> 8119 8140 3 9531 0 s +<232525273434> 1271 8385 0 1829 -1 s +<002b34002f30002d302f292733002f272726272600232f26003a30360025232f003133302527272600353000352a27003727332b282b2523352b302f003435273108> 1829 8385 12 7712 0 s +wst:dutch12b SF +<10> 1271 8872 0 1406 -1 s +<1520191626191d17002218150012192221> 1388 8872 2 2818 0 s +wst:dutch12 SF +<1f> 1271 9294 0 1410 -1 s +<30003727332b283a00352a27002b2f3435232d2d23352b302f003028002f2735312733280600342b2e312d3a002739272536352700352a270025302e2e232f26> 1379 9294 9 7130 0 s +wst:dutch12b SF +<00031e1f22031d15221f152016031d15221f152016> 1398 9641 1 3231 0 s +wst:dutch12 SF +<11> 1271 9987 0 1434 -1 s +<001f131c221e1f1d1511190035273435003028000b0a00342725302f26340026363323352b302f00342a30362d26002427003127332830332e2726003037273300352a27002d3030312423252c002b2f352733> 1434 9987 13 9461 0 s +<3d> 9461 9987 0 9531 -1 s +<2823252708> 1271 10232 0 1697 -1 s +wst:dutch12b SF +<0e> 1271 10719 0 1420 -1 s +<231d1d191d17> 1416 10719 0 2060 -1 s +<001d15222115202415200011210011002122111d14111b1e1d15000b11151c1e1d> 2060 10719 5 5244 0 s +wst:dutch12 SF +<1828> 1271 11141 0 1422 -1 s +<003a30360025232f2f3035002b2f3435232d2d002f273531273328002334002300252a2b2d26> 1422 11141 7 4604 0 s +<003028002b2f27352606003a30360025232f0033362f00352a27002f27353427333727330023340023003435232f26232d302f2700262327> 4604 11141 11 9461 0 s +<3d> 9461 11141 0 9531 -1 s +<2e302f08> 1271 11386 0 1730 -1 s +<001e2b2e312d3a> 1730 11386 1 2391 0 s +<0027392725363527002f273534273337273300382b352a00352a27003c0731000f31303335002f362e2427331002003031352b302f00232f26002b3500382b2d2d002a2331312b2d3a003435233335> 2391 11386 13 9531 0 s +<2325252731352b2f29> 1271 11631 0 2129 -1 s +<00332732362734353400302f00352a270031303335002f362e242733003a303600343127252b283a08> 2129 11631 7 5741 0 s +<001828003a303600343127252b283a00230031303335002f362e2427330030352a273300352a232f00352a27> 5741 11631 9 9531 0 s +<2f30332e232d> 1271 11876 0 1921 -1 s +<002f2735312733280031303335002f362e24273306003a3036> 1921 11876 4 4314 0 s +<00342a30362d260033272e272e24273300353000232d343000343127252b283a003c0731000f313033352f362e10020023340023> 4314 11876 9 9531 0 s +<292d3024232d> 1271 12121 0 1824 -1 s +<0025302e2e232f26002d2b2f27003031352b302f003028002f27353127332808> 1824 12121 5 4812 0 s +GR +eop +%%PageTrailer +%%PageResources: font Helvetica +%%PageProcessColors: Black +%%PageCustomColors: +%%Page: (7) 7 +%%PageResources: (atend) +%%PageProcessColors: (atend) +%%PageCustomColors: (atend) +%%BeginPageSetup +bop +%Defining font PSOwstdutch +%!FontType1-1.0: PSOwstdutch +10 dict begin +/FontName /PSOwstdutch def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001000 0 0 0.001000 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 1 /C0032 put +dup 2 /C0044 put +dup 3 /C0046 put +dup 4 /C0055 put +dup 5 /C0058 put +dup 6 /C0065 put +dup 7 /C0066 put +dup 8 /C0073 put +dup 9 /C0077 put +dup 10 /C0078 put +dup 11 /C0080 put +dup 12 /C0084 put +dup 13 /C0097 put +dup 14 /C0098 put +dup 15 /C0099 put +dup 16 /C0100 put +dup 17 /C0101 put +dup 18 /C0102 put +dup 19 /C0103 put +dup 20 /C0104 put +dup 21 /C0105 put +dup 22 /C0107 put +dup 23 /C0108 put +dup 24 /C0109 put +dup 25 /C0110 put +dup 26 /C0111 put +dup 27 /C0112 put +dup 28 /C0114 put +dup 29 /C0115 put +dup 30 /C0116 put +dup 31 /C0117 put +dup 32 /C0118 put +dup 33 /C0119 put +dup 34 /C0121 put +readonly def +/FontBBox [-25 -238 920 722] readonly def +currentdict end +currentfile eexec +D9D66F633B846A989B9974B0179FC6CC445BC7C8A959A39A32E9DCE7FAEF17EE3BEC9F +50E1A6FCA651FC4B3769A0A91041557502E25A5D6180FE25A3D11BF079E1DF66E54EE9B7C229AF891739707A2A0EC140306B5E43E52B79BFB89E459E50 +6EC6F610A70775A31C460976C4F79449D86E57ACE491E5C6BF20CC4307B1DAF7630252 +E9AF8CFB69B50EDAE9D36A6104AFEF8832F920FD2346B2C7104CD11E3BEE999CFA9F5A +49DB3173EE48D1C82994237F360407B022E0B4 +502E94EA8B493651EF2D03F0B513D655047568325B512AE6 +6AC6F53F3848CF70DE25481CC65D8B1A5793AA +3C4282D111112BEE28AFCA7A3808D4444C4669CA +84EAAAF989219F51AB3476A1B0B5F2246BC306E6 +625C6679C417ED2A8E9BD010DE37D40265074C26842748ED533AEB96B269D1612D0907811D0185 +3C8491E8FD1E7DBB515A4CCE +0A21281DB16CBBE685 +309C72BF +D7C117E1A2343200DFE741CAD6 +773679934C033EBD34F184B853C7BB6246B6D48FD3934BD8486687A0226A319B68025E37AC44B9750913A74309D64D8980867E5B296F17CB30 +65E60481 +D8E2091E206805CCE8AD6962C3 +17C1306D8AFB02ABD32B65017468B58D0DA736117AAAD12FA6EB25FC056580 +84AB3473 +45078D6591A5CEDBE8398F16E0 +9681886C7B04294A4B894CC9F757F5F7D02DB6D63F0EC697CEF34148DF30B8B68FAB485B0AA21A2D9867D9 +8C5C093C +7B03C7E38F079520B4EAC79E8C +71C2C7845AB6483F421CDCE73A30CC7E7244943EB031727C81A1B2E9ED9FD9C58B4C2773A2B4D14F26601DABAC85E6E9EC10799246D2 +7381E2AF +FA597981E7C45F0F2E09AB770962 +6F52CC429449F0BD2B5DA086C7D646D4C6083555653ACEF0E93159D5669CCDD729F721A2B7F65718639042D590E0CDF14935F8404BF99E37A7D17171D052CEBD8C3A148C3D9C8B9128107F74A2B4C0FF5232352E271978AB80D77D1DADA7A9E20D194076248A2EAF5EE79B71CF78D4154102FC +C1FDD36C +C38540409AB99D377EAC1A8040DE +1CB0C684618EF8F8C63CF94ECD6F50B14D3B672A9FA66FC553DBE661A12ADFCEC2394483FFF39AB56A4EDEBCD794FB8E8C644A2DCFDC7849E0B3F0AB9D7DB774EBF03DB23D3AC460B8ACDFC7B5ED61C4D3C818E3985D9F3D0BFE510E4FCD8840DECB6B4EC81C33B321A6BBCECB5E14F17F8F3926146D27C07F206B2AAF8D +2FEA +E2 +3D06E333 +9424EF5D92876FDE0D91FF42EF +52D058EC1BA9982DF1B16B7B05B051864AD1BFB1E4B55A184F706A10F02BCFB0B9977D651CD2A3B92E36E1063A7CBACE3E99229ABBB3BC34025B65 +4530C363 +AB8CA55DBB5DD8DA067051C9296C +2100009DF3862E466B90A252B438816992820D9F978552035425AE15F9BC1B699D715087B05C2BD621AD00AAB1A9EAB10AD9DED84535A834C929E65F93FE1653C4AE71C60E7B848E2F26B9F1394F0D5E008FD5273B3304A47C69E2BE837DBC1C12C855376BAC3F0771CD4EEB6FB4D9 +491E944D +ACD8A19204843EC7B5658907CD +ACFCF46A3BFCBEAD9A7FB8ACF055C6D6DDC64B58CC3273C5200E7EDF13C92A5AE4D79A940658540453B4A9A2D5F8A778C7E4456922D99DE4A19CD0E3111ED37B44CCCA1C0C32CEF8B35662B7345861493F8F03551CF27EDC7BAE53A4 +BBBF2DC2 +9F981AD60727B3DBA9D4CC62FDEA +43428C6FD6EFA1E17AAA17E1773D6CEE3AEEB7BB1D149A467DE696B59811D5276CDB4BD0747B563F12307D5AD32E1E71749682CF345F35AFD3C6009BFB362693EF1CA7452B56777F94401C36DAED841CB99B0646F490A2B72E73CBAAA6ED04D16220C7264E1460A95BB7 +B96700A6 +07A4B92077E66EBF2C3E72EC44 +7BADD5BDC850C2001A011B45A2D9C2426CF088F779454A5994C65EFBFDBFE79045207FC4D5BA2F5E2C5F81E60A0BF1364F490D32F4A19731D3CA2DE05DE5E9FD29D20522DA6E056905C244DA799503691F +93B50926 +D7EC5AC343EEFB25930E737FFC90 +7836765AD75AB77CE12CBA106715B5CE1C4645B06EE1618917DFA5148E329CEFA1B512EA791046B11DFCEA2C3FDCEEF544D2CD092614FA760A3EFF6EAD41FA13DF23E8CC853E609D2AAC8AA0F5AD63616FD50058727631AD20DD35C991FBB576196E7F4EA24752232C0603B68B7679AB28176AB0ADE3BB53E3359CF584BE +302C +92A016 +3F442F5F +28F335879E5A618367C1DDC11E +23572F8AAF7A4A6F4950EA9D21AA78BAB6980CC5C356BC162232001C955F7A7CB84EA368ACBDE0E6C4349A626C80E7E13A73ED9A7013DAAB7C6C367CB1AB8369FF3EF5A4DDB8F527F64F320751AF456607B3A740DEB2C96F +0509624B +6E709F6D866B65F635778EE114 +FDAAB49643B52F6732F54A6E130C0CC4D33083DCB04C66423F1C48293D4E4C8503B52CE2CECAC31367A898BC69AC810C935B168DDC839AC30002624EE0DF8B370D142847925CBBDFA77D91029EC51996FB22 +714CAF3D +B431EDA2F4A486895F1A469A35FD +6BE1B6477DA9AF179800EFEC032404B49B2541CFB5ADA1C1B160597C729DFDE960A7323E62C7C888C61241DA66588A0D94B2AE86E02B524785402842619DED1873849E3CAFD30ADE7E0F91F60F3C573908E12497ADB8B71D28372630776E6A3C1A91F651D044ECF42F21991125C2 +E7C3A86E +9CC6CABEBD675C334C752399F9 +9D1DEC54CF916C8E8CEF593043E60E552B6B18E6BDE0A9114540AC58016D9077C218A6862625255FD4B80B21474ED24FE964F768FAAA6C05314BAEA692B7C3697128E3DD31CFC4D9F254A2D083DFF86DACCEF9BCB22A49C0F1 +6B443B87 +0C5FE1D8AB558B44448C13AAF1 +AD1906A8DDC14158A4597FA50B7A53AD0AD5B2196B8ACD53109B7FA4F80C24BE471F7FFB970C645073C5F95DF370878607E9A4DB7B74ED24C44CE3E190216DD8D8771603A48692D486DF56A9AC47BF62B2869D80B82B226E759AF0A7 +6FB24B21 +C8CC4E2B5EF83F44DA7D1C12433E +D9CE0AF5D84D09BC87176CFB0C67CE88609C1A3E28C8FCBAE79984B52E7A5E3DB7E571034C0E019E2F450F84E03C7FC7E9E2F2C1A437E1BC532180DB75AF14FC99CDB3D05014E2FDED8C39F747F3F38EB52F6777470F4346FFE1B2FD13671BF337FBB9D9E865F11C9438C767EC2B455D63A2BDF12EB06B97210F44F50FBA +0543 +AC8FB3D136EB7D03AE373F1C086F8342CA3A4C5C4FA1F5E588E606A0C46AB401E51414BCF279F336ADCD65ACE1114F +CB7BF545 +2006F992BC7274C7A12CE774AFCB +D2BA61C6A0FB4978BE3B1318E225AF2B84D8D614B51F237ED40BFA06EFB39E8BDE8E9FBEC484BF4F215DCED6C97EF4B94AFF3D557B2EEA5DFA83C2BCD787F910B6DD798E6CF420AEA097BA9B51399FA024D09568AFE769252D95295D9A2156613E99FB23FE5193F738FADF8008 +ADE0E581 +4897BB0ABC43198B5E8CC6FE26 +8840400B710318932EDDBBD49B1C6D628BBBD9A5D38931B636A04A79666CB8FC0814BFB4D6D2B37AD46D0082F11B77F4BAE034A392A64126CAB97FF2DF35002DB76E18482DEB8351DBC11F0C357A635D +8C44AB27 +C092E5BC93A9B66F97ED60286FC8 +CBB71095B05B2C3BC1E41594F49E80B94AF29513548089B08124028CBF6E8B001485240997C4B9F59A715C85388A1EA05016442C5BABFC470235FBB10B9D5125083B0755F1895B437B7E456E707EA95BAFFB711DDC7DBA01A4D8C936E6BFE55A458F1D6091A1B0F222075D3050F8381E8FB26F719C8B1F9D1BF9E016556C +90FE +49E5D222BFA90CC3138EFA275D945E27D5287E4CE86996D0A814F371CF6BD695F715DC +DC02A84C +0F7B988044EB772CBFB17C1146 +3A393EF26D893D16EFE1C6413459C23C0186761067274F8F23EBD3036F4A1C8E14E52F78B96356D10AC8D8DDEACDBB7AC46DA3A821EF +02053493 +D4BB3A98DC601059560C89676139 +B95B617035F515C0299340DB4DF2422BA1365EF0FF941189AB4243BB5C6975159B2BE91DCEE4D6E8CB88A3F6FA7B98E963A9292E03F42B5548FD4882E972FEA0B00EA8EC0EC1382224CDFE1CA343A89AD96E5E4043580C37A07C8D5A21EAF23532538534F356C1AC63C6B2CD7BEBAC4DB3C975BAA4692A71C0D6C49FDAEE +F4A4 +913579BFF760B989C79AEFEF44539971AB9456F510FAB797023D328B653AB0 +FFC5ED91 +2CC06277DD36AF105D2906037E2B +86C88F3E28CDD1277E31FDE3AC97BC04B452BA26B92BBF7BD40922756AB6A2744A7CF6E6E6851BA9A867C0A0EBE025C1D57FD7B74419DC4DC38514194B620E9CCD35E432374E1B9508D67936B6E3F80A1DD704B9E530B88FE4BC9233683DC3087D838E5F0EDD7BBFB9DD1CA4 +940C00BE +A82051A7BB02368425A9D8AED0 +89AF77F0651543D5F9445285457BABAF24868DF8876104B1B55A636E0AF63C46A47209D3BE6A09A3EC2E53B14A2B1C4E4CF507A4456A4AB8A09631080FA68FA7A0D494B99E3A +63B65F2B +2B94042628AA56077924D197E739 +C1A1EC70E84FE8932DA89FA8217BB1768C9070802A0A6181EFFF6567E2D8E477038AE144D46AA2857A3BC89F67AE2F96B0F7FEC9361B7E5C6E0F3879E8EF7AE98474276C5D137F1CCB2F9FD59FE535FFC540B0B9700D32E27664DBCED4387B5EF50693A0F2AB72C05DA3CE799F161C4B50B10FB7BF5ADE +0ACC5256 +9712B60EA8EC87B350682BEE7E +D59D4B2FC88337F5E0D36D2D343FA18450CF81058AA3BD5FA148FBBFE9DD443BF4DB74F5BE86C7AE68197EA267FF1AB93417AF55462A9306F52E5903889FAEB273FFC551F4BB00C80AA665F7358D4E6D9727BE34B1A305 +7AC35B44 +5C4E188E3471447A01EE2DF8E452 +3812293A6EA45D66155B64AC545CA2D11DF5A2012F1F4EC86C5B5D84568958040F8F2BE26E098D1670BF7E79F9F6683929F9D735E3244B32266C1950EE226988C25B208A2B4485FE25F96C4FEAD3A32C9733F2538EAC75E6C7620768DE7750186384484CE3ED6536A61166937DEFB16B4D21A7420563621356C0CBF9 +B9F8EEC1 +ADB0D3EEF6482258A71944BDDA +E1FB609FC90D84BB2DE3C4E63A2DBF74DD909B3473F2250D47F1662A55C9A39BAF0FE95809DCA8DCE940AD629666BFB3637E3B95B4A085A619964340F17D03B8D61D86AA3E +5BD65614 +B861366187121EFA9FAD2AB352 +8E7F851CE6855083F2E1E6039F46AF2D511C9A8B4EBC8E565217E93F689662050DC0956EF399FC42D6E87263FD602C4021F2343E2A1BF87D2F35D8B9CDCA9FEB1FBE4D06F342CBCFBE686F06A4CEDB7A8169739B48A0B3825CA204D53CAD0BE7E592 +2312CECD +D84C7A1060030A483A999482BF +45A003B867FDB5CF88719A49640F174CE99A4D1FAC7D6E9E807C108EC609A638D8CEE5A1788E051FFE06E2FDC4BA035C60FEF7187A69D6E4FEAFB735A111BDEE127F37FC38E2C95FB5C43B5BAA97551B284D68AE1AD0875896 +977896CE +840A81E07D3FD46DBA1B70D04605 +9DD207EB4C3009751C5BD09A08C8A6A730A22336EC3874067B4E6CB40166CBA274AE068C9C435C5B9A7B4BA960C4C553886A83DE40C662C7DEE98101B96F8CC7C0946B86BFEDDDF949917DBF11CA9FE15FBE156FAB08F847531C31F2B81F26D5B23237B34FD4926F47029FD1605ED46FBD3296FAC0289B1711B542321926 +C1F1 +883FC0A45FB8DC9DCA7CEAC7F095 +81EC643E +6C90D59CC6617BCF847851CE86D4 +E2DB76078EBD785D501741E25BF7CA093894E0E50A7A341E10D2B86705A16A051A145A876E2613D75822D040771EEF23E2DF51167D89BDFF711AB22DD33676F126C672862CBF440B978E0ED2DF419B53B3965C3821D74AF1FCE665588D41316B745220E8592416F3ADDEDA45F6F6DF7F90EAA0B21EBD4C64437E8182C633 +2C86 +94C233E7 +5AB48FC29C5D608C90135A77B668 +EDFE028C1C869E12 +4CB7ACE0 +036911E42146F342FE773DF59E4EE1E8A6B5CD8ED09BC6CAD69C3D7793493F6B0D69 +868C1976CD9A4B226AE321F18FDD8E61D7CDBB7E22124D8884F3C580A73122A6627FDF6275CF +BBFF8C71266B4EF89D6FD6D1FFB86E19D231FC20F7754C2F402477 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +%Defining font PSOwstdutchb +%!FontType1-1.0: PSOwstdutchb +10 dict begin +/FontName /PSOwstdutchb def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001000 0 0 0.001000 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 1 /C0032 put +dup 2 /C0047 put +dup 3 /C0061 put +dup 4 /C0067 put +dup 5 /C0069 put +dup 6 /C0070 put +dup 7 /C0072 put +dup 8 /C0077 put +dup 9 /C0078 put +dup 10 /C0079 put +dup 11 /C0084 put +dup 12 /C0097 put +dup 13 /C0099 put +dup 14 /C0101 put +dup 15 /C0102 put +dup 16 /C0105 put +dup 17 /C0108 put +dup 18 /C0109 put +dup 19 /C0110 put +dup 20 /C0111 put +dup 21 /C0112 put +dup 22 /C0114 put +dup 23 /C0115 put +dup 24 /C0116 put +dup 25 /C0117 put +dup 26 /C0121 put +dup 27 /C0122 put +readonly def +/FontBBox [-18 -209 919 694] readonly def +currentdict end +currentfile eexec +D9D66F633B846A989B9974B0179FC6CC445BC7C8A959A39A32E9DCE7FAEF17EE3BEC9F +50E1A6FCA651FC4B3769A0A91041557502E25A5D6180FE25A3D11BF079E1DF66E54EE9B7C229AF891739707A2A0EC140306B5E43E52B79BFB89E459E50 +6EC6F610A70775A31C460976C4F79449D86E57ACE491E5C6BF20CC4307B1DAF7630252 +E9AF8CFB69B50EDAE9D36A6104AFEF8832F920FD2346B2C7104CD11E3BEE999CFA9F5A +49DB3173EE48D1C82994237F360407B022E0B4 +502E94EA8B493651EF2D03F0B513D655047568325B512AE6 +6AC6F53F3848CF70DE25481CC65D8B1A5793AA +3C4282D111112BEE28AFCA7A3808D4444C4669CA +84EAAAF989219F51AB3476A1B0B5F2246BC306E6 +625C6679C417ED2A8E9BD010DE37D40265074C26842697C64AA1341376544BC83CAB3F1D3DC53F +CCE6DA147CD7539424E5308F +85563A985DE93ADB17 +9A9AF889 +F2B5A459E50C65F7B2C7B596DB +B8AF64EC67E72E2A3DA94E7C843BE448E2170061BD6AFE3B4C8B +FDB95E0C +3E0066A626E05031EA7DEBE396 +116230FE8FBDC851AED2513E813DDA332D0D058F629F66CA95378B206D96CC4D01849912 +3665FCBB +4D312ECE1AB5A93870F71AB70AD1 +C6615B5131DB66469FAA8CA3A7DA3D2303E75AAE0F1B0514A2B71EC7573B88D36D17CE8CF65D2B3F6DDC1A2872EAC0D4766532FFDA6D707CB2709C5DF96A5D638891089B1EDBFA8F47029D01F5005B7E1B2F8208C0DF3FD547A8E417410C3A48FE344A6DF21E0AE7 +CF1B4D2A +A081BFAD1C2C88525943BE26D2B0 +60C26316257A2E3B58A30324E436DD6FFA83F6CF643DBE14595DFC79172D88FAF18C4A71C3FCA96195420B54626AFA47A51FBCB188D017E9822DF658C5641546647853A870C65AC3C9E6062518F0B98FBE215DCAFF1AF422D895F445FB0DB12E60B9100A66CD35A6F9619B77E8DF +B53934F0 +F431791724AD21385CDCCAF70948 +A4492B982DC84B07CA752141328CF572C71DABDBA2B142C374BCFCA2E5BDB3B468C93DCE4C76447915F70FA2E84277741656DFD5FA0083B3D5120344CD6EB701C4A9DBBADD700C64CDDEDE9CA7842B62F092AD0F08AEEEC3D9644D119C582E8C36F34CD7 +E455460C +26A6B7EA7C78615561E00E5B42D5 +6879A4D4537B3DBCB9036A331F4A9E17175FF735B057F82CDDBE44852BDA8A8D7935DB7043C5EE28CF4DACC442247F2C86973D866572703950404F5F08B99A6DB072F92569AE865588ABF67FA96CB7F1F23A68EF973342628389A07E3E0B73B2889DB88CF4DE37976C3479C633918441749D507571B211 +B10E01D8 +76A52BE9557D73BA77CE061BD48E +6FB8014BD65C63845269EE519CA0344895D218D5F54541FE89ADFDF7980D24F73A1BAC69C126F73B4DF56F9A08A9E153E5F6EDF354FBAF632C065FC43400917CCDF808CB71EF3BDA7B7C0687F1087D708CB885F9FF67CD3F1C0F4701492FADF10909F64F16B0DE2C26F50F1927 +2378D81F +8657D16DF87FA72C2FF87F9F8A +CC096D50AC07250752785EA257C9C1F8C90BF32C4F2B4098E7BF93AE13171A33A8ECD5E7357341BDA5AFCFE28F8E4D2B15FC5F457F870A1A4C09DBD44E6A9F6A9239B5F4C1406FC5DA46E9EDDD0A0254D53BEDD785603543941A78460EFC4E +075560A2 +9928DBB2852F15E550C2A15E2F73 +9D73D493A15DFFD0FC64318ED1ACAFAF512403A6225C26348F38BD01607E74B3B737F00C8EFB86EF6626EA815BAB49312A5CC92B66B38CAE400AA454F2A7E0886264DFD2C80E6C5CA24A1BDA7DB64AAB858B86259E2A040D79A3EA917639FC66C4721FBF2E1C2FD683 +1FBB7BF6 +A68B3D07FDCA5EB736549FE1AB +E58BC629EBC5BFFEF38B19FCDDDA5089C30008C4C7962FA13A1FCF90F60F0C6725B4DE7AC8524B4C5A3F0E92850C84FD338FEACB14B3480AAA326053CA37D42054C53D7F1B116FB214 +FDFBA1B0 +C70144645655E868C3D99B1068A4 +AC9924F5597237E1990BD1BB6644444AB6C0DB70AAE6470A826519DF7934408186A1B69C3473EB4BD86B6A6093E83BE496095E6ABBFE3477A3430DAD6CEA519D3E5EB98761E796D74842D1036E636F9623BEE5FADBEDE9432B4748D041205E5B462FD5464645F9888AF2A564AEC20FAE26501783CDC69C23ED9EBB081EA3 +6DB9 +46AD0D1C +9A7D1275 +333FAE0AA0512D160D28A6B212 +6EC9DB9019A734E197AE8DC507760A6813AFBA4725B7A8D2EF197E5679408DB33D63995DB6473C979A80F99A684FA733766E5400AD92973D06AE6E85DE32B26DF028DF61DCFCB984A576E1AD4ED3443249B9 +5C013D23 +964D201738B41C9649C115F1D1 +E455CA8CFFD25E611B496E65E9E3107D7A7B22B244AF5F86CBAA46366F2DEFFF16C152199408E067B815107A65C8938340B1BE121005E11CACCEAA155236F97A9CDB8494804466AA0EE960FB5654BD99B8AECF4DA62CB30170C2294C +3353512B +2763B61FC982AABCB4DE62566D +C837A28F743E8E8CC1809473DDDC904FEBBC878A0C061BB71CF8A5B9467C796EA6E519C00A121076C0EF700C815DD9BE560A69F17A7688A10A648F113F584CD189755BBF17083E47CD83F5782C4087A827C492F989FAE5AF5CD937FA3D +5B7A8E91 +96C9019C3C2064C158F320A298 +E24A387EFC5CD9BDF9D71767DEBC8124741863E12044C36F3BB359CD4054C170B83B0196D962EE269DD75C87EC608543FA30C64A1E4C4D7501BBE47A06419C51188ED80CC0C9E46B0D80BE541390 +F2E83D95 +4ED96EB24B2493E94B89CDA3C7 +19DA2D9A5684E9B42808BC578959786EDEB0E55D6F4E7DDD00E6F6ECD8D04256D40E086103F31391FFA0B17469A9560D28C20C32 +CFFFB21E +2D7349E376CF886FCE87FE02F29A +08B5EACD8611EFCE22583BE93ABD15F88070A4AF94A36A605DC2656149AD9CFEC9213E1ACE75A4302976B0B57DC21A188EE17F9AADD9CF95211DC9BD35E577BDEB900AC7B185CA923C5F7EF43DF86371BB6685BFA74B9DB2977759BBF9A4D38D15592FD35BBE89D0EE154579C49375717F7C10C12DF73152AC292F0356DE +D393 +6D3E57B4A95CA2D6CAD714AD6A61FAE5B2694EB30E703D7C4EA5D995 +97996081 +1124869FAB6D47C29D5FC4DE58DB +D2DFDCFCAE0BA7740A24F8D64A0F8EE81AA6A644F975117C618661ED8F33F8C29A5417C4D93D567F8ED6E25559106CBD3F4B2135FE224B1E22E48FF674797E978D5B4748BA0E85C9B1D58205DE50702A23FE22FDD3B64B42CA4AD5630EC4C1D9F691E73650B1E5 +394F0EA4 +0D1063607A166302A67B48585F +B0D0EB60AAC734932284AF2184DD7D6EF5AAFA30816B8C5E72A9B00D7CD4E255F59F05EA307634A8A9DBDD539CEA3DEF84D16B84C05B1A87D4509FDEDE72C52A5F866731769A +82023C1A +303A9DC5FE321450874C5C3CC689 +5C0717E2897CCA5CAED43FC7640F0AFF3F113E197B87AC81C3BA135583906875E3305212E4821EC229AE32609F8D8164518BCA92A2C3B2505C051BEE316D5B1697A216B1E11D6BE772D8B6B0CD23AA474E39CBA1B9BC820A5097B0D642A94EBC88EAE70833CAE1ADF0C335A6E2C68457E4 +5D1C62E7 +82BBC381F19903A9A4C76F4F6F +7298116ED2664599C6C7E553277E5DDF3DE6990DA58D33EF1715D9919C4E6760140C1B267AE29DFF72E9102AEE3973C9E73BE983C91F5947DCA49FA9283B7A02EC5119A33AA5A1819B43A68934A3E3A156AAC9FED836ECA5F3 +A0331A05 +074A6490BCA08CC9B93416C4CF81 +249AF3DD9BECCA4D431E2206760284E0F22DB0767FBD155012E02A890BCC81D870330BE3E7BC756B90CF083C100C47B4CFD05D50747ABD3BB464BDE16CC9264CA058CD23D0691092BA049483D092E6FAFF135B07262AE3D7A02E1FA890BA4731D00EAFB25A31A7E256E93565B4E1115827DA00E9D18235B034 +803DC3B7 +B2D19203916F5E762DA1979C1A +E02943C194624864653F736F47C33ED9005E8943877DD796B55C9A8AA8BCAAC7313E4E7E858F29313F0A0F59921764E04603308C8B551340A5C54E125E25C93CCD6ED096 +1B446091 +0217C0E10B40827C1081E03FA1 +F4F4880880A9EA7ABB91EBF9475D0F39AD726DC580E529764B6207B81991517C8E0B3A983943AD1AFF93F0AD92A04FB6738B846866DD7989B178930B984C15DC9BCC4F53356D1928245ECD9FFE400EB1A575FB352310DF1971C29F +9D9F04E4 +CB4B88F0EBBBBD50B72255A016EA +9291D932D9C32E5567C85F1F4DF6AB4CF9D152A13736B1B75EABF155E4891BBD92A607E63F0E15F3E4DFE60ABED35329DC0464B20041D6C32C965B251AEA71C224AC74DEB9A56EDF85B4BA99B61CECF40D65DEDACA8D2DCE5FA3D4EDBF171BE4BB0D2CD4B25D286FEAFCD23A09F85FCED7F81B6C7E4A0D618E3BED0E76B1 +2AF6 +FE +429F8950 +CFCCE07BB00AD81E0CD1293ACE +84852AF3165E41C6BE25928C01FDD9E1F214A3E1DDFB9DEEA6E6CA7D6CB016B58ABD614B43C1A026A03CBBC7C76F3853DD6685FDDA097FA8907C7B3233 +8FDED4C3 +1FD04D3F24FA44621187E0062A6E +77F33EB409ACC3BA +1327EF14 +1DDE85D4CD3F42001BC1FC8C9844A6302C7E2C83263AAAA81A79C1F4222E318693CF +7BAF9833D5B709B75DEFA7AF02023D36C2971DA7DB23F1878450CF1C29BC189F9C835BB114CF +97BD140BA85A035706F8854D7AC91BFB74DBAA595C0416D641B1CE +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +%Defining font PSOwstdutchi +%!FontType1-1.0: PSOwstdutchi +10 dict begin +/FontName /PSOwstdutchi def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001000 0 0 0.001000 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 1 /C0047 put +dup 2 /C0101 put +dup 3 /C0102 put +dup 4 /C0110 put +dup 5 /C0111 put +dup 6 /C0112 put +dup 7 /C0114 put +dup 8 /C0116 put +readonly def +/FontBBox [-144 -228 480 724] readonly def +currentdict end +currentfile eexec +D9D66F633B846A989B9974B0179FC6CC445BC7C8A959A39A32E9DCE7FAEF17EE3BEC9F +50E1A6FCA651FC4B3769A0A91041557502E25A5D6180FE25A3D11BF079E1DF66E54EE9B7C229AF891739707A2A0EC140306B5E43E52B79BFB89E459E50 +6EC6F610A70775A31C460976C4F79449D86E57ACE491E5C6BF20CC4307B1DAF7630252 +E9AF8CFB69B50EDAE9D36A6104AFEF8832F920FD2346B2C7104CD11E3BEE999CFA9F5A +49DB3173EE48D1C82994237F360407B022E0B4 +502E94EA8B493651EF2D03F0B513D655047568325B512AE6 +6AC6F53F3848CF70DE25481CC65D8B1A5793AA +3C4282D111112BEE28AFCA7A3808D4444C4669CA +84EAAAF989219F51AB3476A1B0B5F2246BC306E6 +625C6679C417ED2A8E9BD010DE37D40265074C26842D74828FF73C7EC70F5370B1BB98EBDDAC +4E0BFC7144E495CB175BB3BA70 +303F2C001A68709C9F679552E1B511E3F340851F299D964617 +3F655308 +773A5B7EAD8F938622D6A364E65B +AAFD767F464CF202A4E316FEE1BF39E07643FDA1E8A4F007015572A2761C0A29C8C2E68135A35C70F3347A0BF6CE358963EBBC87FE22A0073AA4D09219626CDDFC10ED0C2A26EB9BBAD1837E7F325B2EA419B1F5AC91F18A3A9902671BF3AA42DD88364CAF +AE244492 +3BB0545BC7DA7024D4D6192D110D +083804ED5B550F8FE306277964E5EACC1365639496C5B0D5D4B147DAE8A966014C907C99EF51418BE4C0D34002C0B90AF4422468D13F1EE3699F7AABCB3251CB23291CDD88AEA48D5811E69253519C9CB664BE7D3734CEC27FE7DD1388921C6C29AD5D08F3A4B532297DE4071804D64FA03211548CDA465DE5B94080530F +5C05 +FFC2A177 +42FAE414 +369E5B5ED10669B244B88FBE932F +21EE27EF59280E955F7DA0ABD13E57460AFA622BE2B1CED7C36AF73A80E9F8AC86F02502DA3F6A9F432495C2C50F40E527A1A6102B9C5B89DE59A6AD38AC9B5220478AA193D65F18DB74E75DD80BBB544021AB8A11D780828844873743BD901869CF7AF3B8AFDD2B3E3E3DC1E270C50B66F30BDBAA1D5D0DB590B451B701 +2DED +A69338A98912F9BB7E626E64BE3E6E26A9D83447EFC1C6367F +D1092793 +B29D3E6C2475D998B87B3FDA2C +C3472D6DCEB3F19403F98277BD229233AEB7689DCE6EA27F3120CA6119AA6EB60E71835C17C2134B96E9F2DB7F9C257FDEE2B6B94C691B0F600E4AABA9F91D772F4679B2998375063E1E5696A1E4A78C4E6A40DCCC7BA2EC7BEE25BFA89F1A +A0138AF0 +62B2E7F9B93EDE36019540E36AA7 +1D4111CBB17D40D15FD11CC7A66C2DDC598C7E9467EA444F8435900CBBCDED7980E9559C9732D55A5EC894210D13AA23D4C134AF045AC9ABB982FAF688D33A1746E5F585EDD3659975A72A071E0292514CE4B8DFD3BDAAB782C8853D6B9C9F9AFDE3C099228C786F39C8853AB190BE511ADDCA18D474A73573F8181CFB42 +5336 +96FDC787601C6E2B61DFA1630D3E4A63D1A3AB47951E0D01E6C44CFE2EBBE4DA4D0BBF1FE70C578BE62A +A486119E +2C96DA0747C96DB9EF070F64EC +B9A68081FFB6DDF7021FA4DD2511DE902CDF43B4B584973EAB327F983500DBD5174A8CCA1491093DABE8E411294BB77D77178622868F0A51788CA9373F0599FBA1C99F7A6A227A143643A674F3203FA2C4FDFB18C3B05DEFD06039 +96B06F78 +7DF12BFB4953E0E78C5E300A39 +4A9E1DD2D2C3AC8A2E8DCDC3C7D4834F00C59826C34EABE8761065161338388E9B72BA88865A94B3FEA693FDC98DC6AD0032C46B31C2CA16769D37ED4C81907320C1B7333D3A7E273504A139CA91C6DF515F7945B2D3E3 +FB6D2EFE +7549FC2ED81F603070AEF5E40246 +DE10DF2B747F942B +4FA6CA9E +A4446E87F940FBA8D4254936379D102DE431AFE984402279385A73E1C630E8B2FA98 +34854FF28FDF3BAB9160E7367ED5E51B2491D120EA7940A9CC0D13F1EAF3F7DB8F7A6E2C5E51 +066CDE2857B899116964844BFA456021638E835B344BDF81BDB606 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +%Defining font PSOsymclas +%!FontType1-1.0: PSOsymclas +10 dict begin +/FontName /PSOsymclas def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001000 0 0 0.001000 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 1 /C0069 put +readonly def +/FontBBox [106 45 775 713] readonly def +currentdict end +currentfile eexec +D9D66F633B846A989B9974B0179FC6CC445BC7C8A959A39A32E9DCE7FAEF17EE3BEC9F +50E1A6FCA651FC4B3769A0A91041557502E25A5D6180FE25A3D11BF079E1DF66E54EE9B7C229AF891739707A2A0EC140306B5E43E52B79BFB89E459E50 +6EC6F610A70775A31C460976C4F79449D86E57ACE491E5C6BF20CC4307B1DAF7630252 +E9AF8CFB69B50EDAE9D36A6104AFEF8832F920FD2346B2C7104CD11E3BEE999CFA9F5A +49DB3173EE48D1C82994237F360407B022E0B4 +502E94EA8B493651EF2D03F0B513D655047568325B512AE6 +6AC6F53F3848CF70DE25481CC65D8B1A5793AA +3C4282D111112BEE28AFCA7A3808D4444C4669CA +84EAAAF989219F51AB3476A1B0B5F2246BC306E6 +625C6679C417ED2A8E9BD010DE37D40265074C2684268F16195489648993B9C4D3B534FA887C +DEF605FA87B991F4D20A8F78DACE +5A54C070E03D5C59D9D2D3E06B09CEE028D68B62AB3AEC43C1DD20BA70D288597D9BD8E06818FF764EBAB436723988E8D7CA59E16D39032516BFC5D552ACDEEC6BE938BEF2F43CFFBC811C3626C4DF5F8CF080676520B51C60CEDAD1FE6C92D1431C702174CE517A8FA9377D075A0B6833DAB101DB65397F1419EF5F0016 +004F +6F0824F9657BB4F1C8F981709956865F6855EFAE +9242AD55 +91BBBEE163D844DDA894E13190C9 +2480439E4C71CADA +BD043A9B +A315CAF72652AA7FE6DB2E84D82A6111CE4DE90C02DA0AFFE2620922262A45AB4ED0 +EEC9F4520DD12703442F7D028D4526BD8B771E09FBE11B2749E2D3906894E8D4BFD3F379F14C +3C874F550606965E22FE487B247B5C2D06728490C8F2A3B588CDFC +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +/DPIx 1270 def /DPIy 1270 def +72 DPIx div 72 DPIy div neg scale +0 -13970 translate +1.00 1.00 scale +/wst:dutch12 12.00 /PSOwstdutch newFont def +/wst:dutch12b 12.00 /PSOwstdutchb newFont def +/wst:dutch12i 12.00 /PSOwstdutchi newFont def +/wst:dutch10 10.00 /PSOwstdutch newFont def +/wst:dutch14 14.00 /PSOwstdutch newFont def +%%IncludeResource: font Helvetica +/wst:helvps10 10.00 /Helvetica /wst:helvps ILEncoding 0 declareNFont def +/sym:clas10 10.00 /PSOsymclas newFont def +%%EndPageSetup +GS +0 13978 10801 13978 10801 0 0 0 clp +wst:dutch14 SF +0.00 0.00 0.00 1.00 setcmykcolor +<0a111e1b111c12050106010711190f14180d1c1601121a1c0109110d1d1f1c151913010a111e211a1c16010b> 2207 558 0 7384 -1 s +<111c121a1c180d190f11> 7375 558 0 8593 -1 s +wst:dutch10 SF +<04> 9434 13385 0 9522 -1 s +wst:helvps10 SF +<4e6574706572663a> 1322 13267 0 1949 -1 s +<205265766973696f6e20322e313b20436f7079726967687420> 1949 13267 4 3868 32 s +sym:clas10 SF +<01> 3868 13267 0 4019 -1 s +wst:helvps10 SF +<2031393933b131393935204865776c657474b15061636b61726420436f6d70616e79> 4019 13267 3 7133 32 s +wst:dutch12b SF +<0610130c11> 1271 1431 0 1754 -1 s +<00041917181412101b0c18101413> 1754 1431 1 3142 0 s +wst:dutch12 SF +<0c1411> 1271 1854 0 1631 -1 s +<001d0f1c151b1e1d001b1c1a20151011100021151e14001e14110019111e1b111c120010151d1e1c150e1f1e151a19000d1c1100211c151e1e11190021151e14001e1411000d1d1d1f181b1e151a19001e140d1e> 1631 1854 12 8834 0 s +<0019111e1b111c12> 8834 1854 1 9531 0 s +<151d> 1271 2099 0 1410 -1 s +<0015191d1e0d1717111000151900> 1410 2099 3 2470 0 s +wst:dutch12i SF +<010506080104020806020703> 2470 2099 0 3460 -1 s +wst:dutch12 SF +<0300081200221a1f00140d20110010110f15101110001e1a0015191d1e0d17170019111e1b111c12001519000d0010151212111c11191e00171a0f0d1e151a190200221a1f0021151717> 3460 2099 13 9531 0 s +<19111110> 1271 2344 0 1713 -1 s +<001e1a001110151e00110d0f14001a12001e1411001d0f1c151b1e00121517111d000d1910000d171e111c001e14151d001715191105> 1713 2344 11 6068 0 s +wst:dutch12b SF +<09050b070a0805030214151802130e18150e160f> 1398 2690 0 3740 -1 s +wst:dutch12 SF +<1a1c001a1911001715161100151e02001e1a000e11001d1a18111e14151913001715161105> 1271 3037 7 4417 0 s +wst:dutch12b SF +<09050b070a08050302121a02130e18150e160f0211140d0c18101413> 1398 3384 0 4504 -1 s +GR +eop +%%PageTrailer +%%PageResources: font Helvetica +%%PageProcessColors: Black +%%PageCustomColors: +%%Page: (8) 8 +%%PageResources: (atend) +%%PageProcessColors: (atend) +%%PageCustomColors: (atend) +%%BeginPageSetup +bop +%Defining font PSOwstdutch +%!FontType1-1.0: PSOwstdutch +10 dict begin +/FontName /PSOwstdutch def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001000 0 0 0.001000 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 1 /C0032 put +dup 2 /C0033 put +dup 3 /C0034 put +dup 4 /C0039 put +dup 5 /C0040 put +dup 6 /C0041 put +dup 7 /C0042 put +dup 8 /C0044 put +dup 9 /C0045 put +dup 10 /C0046 put +dup 11 /C0048 put +dup 12 /C0049 put +dup 13 /C0056 put +dup 14 /C0058 put +dup 15 /C0063 put +dup 16 /C0065 put +dup 17 /C0066 put +dup 18 /C0067 put +dup 19 /C0068 put +dup 20 /C0069 put +dup 21 /C0070 put +dup 22 /C0071 put +dup 23 /C0072 put +dup 24 /C0073 put +dup 25 /C0075 put +dup 26 /C0076 put +dup 27 /C0077 put +dup 28 /C0078 put +dup 29 /C0079 put +dup 30 /C0080 put +dup 31 /C0082 put +dup 32 /C0083 put +dup 33 /C0084 put +dup 34 /C0085 put +dup 35 /C0086 put +dup 36 /C0087 put +dup 37 /C0088 put +dup 38 /C0089 put +dup 39 /C0095 put +dup 40 /C0097 put +dup 41 /C0098 put +dup 42 /C0099 put +dup 43 /C0100 put +dup 44 /C0101 put +dup 45 /C0102 put +dup 46 /C0103 put +dup 47 /C0104 put +dup 48 /C0105 put +dup 49 /C0107 put +dup 50 /C0108 put +dup 51 /C0109 put +dup 52 /C0110 put +dup 53 /C0111 put +dup 54 /C0112 put +dup 55 /C0113 put +dup 56 /C0114 put +dup 57 /C0115 put +dup 58 /C0116 put +dup 59 /C0117 put +dup 60 /C0118 put +dup 61 /C0119 put +dup 62 /C0120 put +dup 63 /C0121 put +dup 64 /C0122 put +dup 65 /C0127 put +dup 66 /C0262 put +readonly def +/FontBBox [-25 -256 978 739] readonly def +currentdict end +currentfile eexec +D9D66F633B846A989B9974B0179FC6CC445BC7C8A959A39A32E9DCE7FAEF17EE3BEC9F +50E1A6FCA651FC4B3769A0A91041557502E25A5D6180FE25A3D11BF079E1DF66E54EE9B7C229AF891739707A2A0EC140306B5E43E52B79BFB89E459E50 +6EC6F610A70775A31C460976C4F79449D86E57ACE491E5C6BF20CC4307B1DAF7630252 +E9AF8CFB69B50EDAE9D36A6104AFEF8832F920FD2346B2C7104CD11E3BEE999CFA9F5A +49DB3173EE48D1C82994237F360407B022E0B4 +502E94EA8B493651EF2D03F0B513D655047568325B512AE6 +6AC6F53F3848CF70DE25481CC65D8B1A5793AA +3C4282D111112BEE28AFCA7A3808D4444C4669CA +84EAAAF989219F51AB3476A1B0B5F2246BC306E6 +625C6679C417ED2A8E9BD010DE37D40265074C26842242D2C7C52988A16D3AD63FA0A6A531F598 +82C7FDFCF9F77A295F11CFFB +5B12FD403323523254 +4E86BA9F +872D4E553847200B488A5FAEE7 +01E74385C35D49FB3B6DDED1A522A0FADA18C1AA4E23B8C070C0FA297B23AD82279D08F991EF1040915452FF200BE62F435015E4F90719B8C599F7C2095FDF70620059BC6B +54B433B3 +A9A2C4F2B301A3317EB2A63862D6 +5AF4E8D4235F536AF982ACA47E168132A5128B9D4FCD92629DC0B0711385886F891446D120475C112BDA8F290D0B9AE2A536C8868C12DB77C94413081F74217C8CB835F4CA6787F9CFEFE8254D60FC36BEE8B2CA3E9A68B4D09D352FE8F23060609BC43A450F68 +ED3A8D95 +59137EA683D30BF16FC51C86FE +BB15424BA06162DD5595E7D5CC5DB8359E6B6D294A3087A5061AC20A9C39B9B89CD3B57BFA369E7CAEF01F62E530448A2315658AF7236C60 +4D7990DE +B797AC1BA169DCAF2649400B4D +9A8BEA50E962CB61FB22FBCA9B5E1AF613EEEB3B7A454BF4403C2C58346D713477107F8658DF2071FC2FC11E0D8C9772AA739268B6F87780F8BDCEA377160BAB +6BAED373 +E164303DC3BB754A08B58740DC +C4BA984C9597D0477E61672FE3E5F777CDBCE640F7A0758E1D58FB05D1729215EFBE1D24A92C9F8E5BF12CF67454C27E58A9751CE583AA961CB1919EDAC606 +0E7D5BD3 +8D06CB0FA18047898A4808F4AFE4 +61E5A2EFED1D9D0C6B6E4AC6E0696B314BDFA7137553C4E7CFA1F325B4DE4D49CBF09B1A88A03FDE0286DB8CF7DA2B3A4F301D7FFE8E3A2EE03853B9402145C5BC4C2B7754F3331C267B882083D9640D9411B85DE25100A59DD0ED1AE020839F0E7086DA2071B9B8B9C57CEACE17D208EB6762AE2C9606F8FCCB98B13CAD +91DC +E7B18CEFCE141D4BB9189979C172F60A5CCD6AA81D6F16B95A5B055E8D4468C8E82D16E4C0690AAA620A3504722D1AB9CF74143F860A008DEB952DA1829501 +6FDB9513 +A3DB442888AA4D6772697E79A5 +F4F65FDC8C14E201E08747DA2721DC0038FA3592E2A193DE9BCB9C9BA9EE0ECC397AC8ED374F3D901EEA2AD7586674D99DFD97582F7ECD5DC6 +78D824C8 +5FFD632F215EC7EDC559A9D237 +2D5BE1E0E6A79C2D586E197C6932DAAB9B8D16C60B94E6 +A3CDE2D1 +09BF17793A76694E559F7B5323 +7A6BF090AA8AEDE486F0202FDCD1BAEC62406F9418D46EE84B17D807E1D85D +C8D30775 +3FE13EDE8444F8671F248D02EA +353EA834426BDEEFB893A5CCC6A1B5AD2517247A777026628B04EF622D9570F57D1E028BE3BBE056D31352ABAD57A2DF15941D69694CCDE27EFADF96362CB6E5AC5C1A5CBCA8237343C1 +6FDB9513 +A3DB442888A722E0026666AD30 +B65C11C3A90040662AAF054E523DCCC83B9B38FE9A3EFF266BD4CAB6B086CA6CF43291B8580E8BE35D17181DE7B36A335BBBD92B99AD4BACA15CDC36311990 +4533E1C9 +DA564880FD682C574A531D361743 +9C0069B5E5A695F574242574358B83676BA83148D94AC7DE1DE8DEB041CB1CE25AAF6F0117797D93A62EE90F69007D8E74E2F1E6A6F614D723A898BA90CCF007E8EC00EAD4494154F4F740AB500DC4CBEF7D4C5D49B65B2B482FC1158362B9706D719D085AD64A42E7A7E899AC38943AA5D1B056108BF24F36E3 +DD52E785 +0E5E613C96DC86F8F2BD83B2EB +3BCB16D69F434B84EAD4CC37D9E928A324594E9D7F3D536F79FF6315859C3DA5DBDF06C1CCE39781BBB0864F858C828D35F9480EF9B5 +872884A5 +9754373DC4BA1C9D09B81EC67FB1 +76F2ED90A44DFF2E532DBC80B024CBB247E8658E82566E7954554CFB3EE09451C2F9C33EB7567B47E037E3C592075090269EFE24BEBA0C7514FAA01CBE4F8B2CBECCF81599B5FBABF95883E3F734740D108A5085DB2B71AE831CF20F49474E5B9350ECF1160C144C +33B1FDB3 +8B9AB10CFCC9E4FA02B7F4DD63E3 +011779EA7FA43B7E637B7F712498E50530203F7981A451E75CB33501283E2D073F37885C321F4BCC4D09B1AAE3095EF951D08E569BB8A57980712EFB9197983FC09438455ABF94EECBDF712343DB3E89BFCDBC965EE46F41DF7208B0B550438E25127D077BF9182A9FE562613D9DBB55C4CB68 +45E31FFE +9EFF444F19F4FADE09E6E9B82942 +67C7B7CFC31BCCB03E727555D2CE19E555E517663629F45A426B1DF4B508BF012F9910ABBDEBD01A062F7A94693B172F611519EAD87808459106A35BD46B7B1B0622F79C432F0F48B0705AC05D57BA57E96CFC353A645A04F970AE8E771AC90E6B4AF369F8F93C70AC876CA967CCD3169B2F6BB14A7CCAEE1B8CC4BF7BDB +2584 +74 +255D9ADA +13C6FE045C50B2DA5657C0CC70 +B58A501840785C0A318C411E690A1F9FA56A69C870F97ED8896694AC7BAFD9BBCACEA4F159EE1CEB231834EBF504EC3E33136EC3670311C618EA39EBD0F1C2508A91AF12613FCF265C296FE8D0E83F4382D0B454062A38F1AB4F5D60DD41ACCE91 +55A6CE41 +C0CBC47D8CC79406016C7042DD +FF33A954755258B87AC846BB33B427855477A04B1E60A957E04DD4CE1A5BBB6BEC2EC1A1BD621CB1D1C371D6DE095B3103EFF20F9CC19D7A3AD1F64B7D7AD04A33BDA5E28DA489FB6FB7A9D2FA81D75433F64A384D671778470ABC21FDECB025676178 +4721F623 +58E1EF19FE61DEE051CBB0DDF9A3 +963D0B11CB59B3CF78778BAC5811F73528EDDE1669CEAEFC7A9934D16AC6AAEA88D06681342EF67614A605595451BD45A8CCAC6A74BE0E0021CE669AFB86D31EAD4B704B643408E1967C0BDC2728E9D4D493C076E4B0314155DB1166766375D28477CA94D52DF9FAAC2409D54C1CA9CDE48417D0D295A49386F12DD2444F +FEE45B59 +500BB46CC35B586B1EFC258A343C +72A87D51E8697099F8C0A2D6E827A8F80325A3C00ADD8CF818EF2CC6FB779D10CED11C5B3F90D3487DF5D61717FD9E046C43CF7AEDFCA21D03D5155C826292EEDA46447C59C57EFA581E6451BE3E2D50B7A8E7177BAE5FD2318D329575BF37F36982059844F8922DCC +A84CEF0A +1022CC506C70F747EA640A7BA34D +7C656227384EAF5BC797667DA7E9E24AD6D8C56A6A72D78A40534DBCA1997EB864C0C2F73F109AE479AD3442409CA2E151E0C1943C3C439A10AAEF3D35182685401031109D044DF44C5F7D1DB8E52CC1F606F1DC3DDD8D506BE6F0628E13332E84562D442C17925A3A93C6B05928B5427C98AC1C4B9FF49628F5 +3C99BC2E +DF3366C6F659ECF3D96296BB76E3 +60801E60265E290B9EF6BBD3CB4E5CF712B5712D93947FC12BE5B450766A640735DB0E0F623AF44B452E93E56B2ED32EEAF2410F3130C14301B82FC922D0090D4082D40A5CCB09134A7422FFA84979E58FF5E85800F4F46C267938F3F63FABB40E8E5318C3C35D390B193D75169AEB3E4CDCAC593D6E25008F87DE81ACE9 +D9C1 +C240AEDC455EDFB4D65AB6 +159DF3A7 +EF514A061DF6DC525B8423B70E +D44AC6EF45FAE978DF677D756547590A6F213A5652FA8AB1A5225BD61DB9F93FC305B36737F1E9F80F5534DE79C89967F7E53855910CDDA4540CE4 +2E9A7076 +628AFF8A0E0BEA1B6F6B05F0751F +9A6B49624325F509058846AA35C59B4E8E509D491811A9863871945BAF0458256C20C8258509EF327C1072DA97C0FBFCDE4618A3C1AA0FCB21351C17BA4353B976D7F9963A90669C32FA29CA176FD615D1DA981E0B16EBF3D571D466552FCB9422CF0C5EF58182074ACF3CB4809A6DCD65082638F8D25EDF3E364AF778F5 +8C44 +93EEDFDEA7BBE594D79CBCC8EA21FF33EF813FAFAF6C5E9C0C50A356E08BD6 +D4A2E9B3 +68B1974A50DB9AEF4A320CB26E +2BD241B93CC461A9199AF8ADA3344779B6D742BF44FA4072B6B3C27C64C1BC132E88C3395CF330A157D9AA73F0BE30627E032A7272151C1399EC2934A8E504EF3411D78347BB05 +D0BD6F19 +94426C5A4D5304A2EECE2CA74B5D +AFA70C383C7E7C7207CCE9761BCDE53C1C1B9F0B24AD9167604A1879EC3DC0F83292F21AC6AC357754AB2AA8B806EF2AB08AFFCECA10382CAE0D911CF02C30517C149DE91D346023AA08564F43352BA2F5DBDBC4F471561E3691B1F8CE2AA90A9960D904D67DD92851179B726DF7A7 +B736153D +42E1B02374A9802D91F62E89B5 +45CC8CE82335183FF277A2504347A81FF8C2DA0EDA41347466D0D036F90D1F7E4B2695E1C972B023336B6BAA1A1753B76328FF66FEB1F72A87BE44B742C8DDCD62718ABB5BE2487690EBB37951A8C7AD3A13EDEB9E8DEC084657D607 +5C6C9A26 +0349E1A0703BA908368DC00DE7 +254DC9D6E0D8A7B3835377DD9052FA2252FF6EE41F1EBB5926066D65BB6EC4122DF6A7BE6CF3B643C862377AC864067C396F97D151F2AC5FE657900D9B6B37076D1AEA20618778E99922165D1580B9C5C90D87 +83F0DDB6 +A160E7E8E3384C37B53D128481FF +D5458C1DF48A90BC5C27810457047A34F96CC948CB785C7B5B01A623ECD5A0D5BB5D7F075B857F259A98BFB2DE0E60696168C7525205C961A4C3A6F286A1FCE86B0F4D2225DAC439488873F858BAA1FE33AE8FB0B08BC75BA900D65208B2EE283595EE3847B9FCCFE238 +4DEA1836 +6CC2F1D89EEA48091156B75E31AF +8F5E1604EED7E987B7D1395D262A2384BD4BE09C4E26152847832670C2D1AE7D22FBD0D4384727B41C40D664AAC9981F4A8F32B161F741F07C91E24B0FA6E5877F2A0F2372428CB2737BD91FD542D419C56BB2E757FDE86C35DB41A8A5E237E0757E9CB54D1DEFE79E95D92BBCC1C3FB847D86D3A3DE1D1B41DE032F59AC +15CC86E7 +A2F625B83F785179E921C567A694 +29EA3D1EC4A04D99B51725CE2D692A4BCB1218E77B32033A4E8B55A1D501AD9044E91E443BB21E273879FF4E9869D54F1060E1A5D69B8D4238F678EACB6B94BA0C4B180CC3112BF8A58A4EEF9B770925C7C960C9C63F6FDC79E1017DC1ABFAC75B09604FE44A72711AF27430BD80512BCB6151C5CCD83BE8A1E13C8C6ED9 +9EE9 +69C739 +F6A14A6F +AB5C5FA65E9707989105EA3B58 +A38A3AC2733CBC78BBC5F7645717AA2B6F2AE33F1D085C2E76F7A41FC5BAFAEC7A2098255CACD7F8CC973EF1E7B7D1FB8DC8EDC0815062A3355D91FF7AAC98D15A926253F7C0B470D3030A608C70D4C763 +06B73B38 +870E5F99E2B839F60C033CF404AC +2E77E5E360FAA893B987358B22C72983F0D490C1503FA982DDF8C9EE6FD0D148C54A5A3D6A3BB456D5D64ABA86647BF5379273920E9DA78A4F41E60F0B03AA49D632099AC22BAA85D37D4BFB9E9D013CC324A97C2FC67A5D5CE6C7D5A6120A542241EACB +3DF05689 +7B142EC726259E7E6746DBE661 +C9F8F4676BFB200063137479E85C277A4104CBB3243F5BA130E4907D1E235BC84D1F87560CBC2255227CA4B3EDD850A9094EAA9FA6C4EF51394A10558FD31849F9076918E10BEF0BF39FCA69711191E733152178E92C94B357 +1FB2F07A +F56294DC91B951835808A61C15F4 +6FD36A7144301DC3CE21BF1DEB712D1FD78B79D84E7806056ACC534A959EADBCCE8C746A38A81B0682C07E4C1003C917C76A81582D72B3B72E6F018DF60E363D1C4AA66ED4C71E466DC3D094951BB2A9DC73F89612ACB8DAAAC6DF775A784713E720E0846C5EFAFF92D515145CED1DB2D916E6D790603FC72A8AC7DE76DC +2787 +2D01E30D16073A67825C77C0F9D6A765 +34CA4E44 +46209A7A777AF747BD50682BEE7E +D59D4B2FFE74A513DBF7D309BDEDEEA45961F974295393B60BF6DD33C04CDFC2B64BDEAB0C0F6755CDF958B0ECA9CB99CF436E3157A7D8F2979DD90916A578E1DEFA720D446CF9BDB5E5E577413463A30FF9CE355554289F7FBA187376F96B5EC50DA745500304AEA3EF4DEAAB5F31C7011EC6B3CB455A2B87B291830486 +86C7 +B7B463F210C46D99728B27E04768862F943BBC557C9C6F9EEC38AE43D85A1ADD081400BF9B55C6 +50A292FE +F43535CA51442AD76645D950EB67 +D443394E190E6D991B912F8850C82B58DEEF9B7EFD970ADE986F720C38D62B8F2DA4A1FDE9C4384DF4BB810344E1B64D74D8E7E262CAAD81E3160CCC4A0516779D10BBB977ACDA06AF8549C9116B78A9D8E29EB43C37E7D2EF0BC3F45EC443D91E8565F8792E44F7391A072006C4B3CAE94C97 +818FDD67 +B5F7C3A2B9CFBABF6354C526D8 +9B6B4629D0E1D0C4617E013E10377B494B9875CF5D93 +EC0F2EF3 +64E5B72F1DA81BABD28502765094 +5A5FD5CD352D22419636057C6887B54E39D8A06BB7D1B45B77C8A8C8FFC96BFEADAFF667805A0D2BEFDBF724E17A0EC6FDCD730DDDF7C56F0B93ECC6E4E7CED77088F70C6B957BD5DA48BC095F99C6E759B1ADC5F419CCD35E9C9E8A6845D1F89185C8705AE7A9EEC3330376692246501FEE6A6331A2986CA5F0E274DF33 +8855 +F79ABD +F2A6EB4A +84308717D9A8361D07F2F22969 +804D5A88CCCD45C0218D9379E74EA472DB8199C8F5CA79803DCEE40C8EF57D191081AA1DCB50D30BA16B465032B562CF3736D7790C8C9AED5CB87F5A84AE81A5CA478E1D43710273BA0891AA65537CDBB7C2262695C510D0 +38661459 +BF5DAC748B46880A73FFBC77AE +08490A2C15F8C54D64DFCFC8D731BD1C911B9EB43D15C9958F9EBA2747F676A4B3D3BBA34A2E60C160E0C1E4E6AA0DADF805C8EFF5974A7EC4696C6AD40C578AA4319FBD9E632F2E4CD86BC1DBEB59791402 +9D1ED1CA +AF0A7ED9C81C0389A77DB618B457 +D710C2B86547D7C1CAD9C5FB929EEC0717C4FD3B8ECF2C32298D91BE3616F788DC97605DC68E147F2EADA8DAD6983D385C095FF5E9B419B6005A62FC781CABC40492E1F502FEAF1149A1B9A1689688A869AF178CCFF88FAF8590937F0A2D1C4ECCE7E0409C1A6FEBFC4F66B1E4F5 +20DEE111 +593A12ABE90A83C91E624B76F5 +86D52B661DD959B8A06A1D7D685405FB2525C43A6D16A4C4EED52CFDD8D02E2C06C9C1AD68BAD4019558CE384CB844BD9DFF06647C82BA262A6EA10192999387AB6844B4BE080A06E5493D57AD6B5B2849FFC0D8D2CF9C2684 +7B1C3569 +C80D6ACCCFA061F59275819DDF +023FF06ACA205548FBE0F10F5D4E718A2D8E3A428EE89162DC691B6E61F9277B5A3B7A195677BC17D2EE390EEA4635D3819EE0AEB482636332A8E1D6C38715B4D7E6F2991A222A3EC2C2026557DACE530784408DCEDCFE14B388A4B1 +9EDEA869 +3E2A2464AAFF539437EF5F67871F +AD992447638ECAFAB0ACA19A99FE7CA134A5D4148E93A03415C0E4DB904125DA41BC27C6B3A0E07F0125C279A22BCAAC6D925108EC36C696E6F0DF60AFF2DA1C0D3ADEB865B964B70BC19E03D64CAE18047876BB7037268F42B55B19A6C4324AAB8D2173E4A4E331C1FD24974E57CD57C7EBAC0C7CEAEFC558788A31B02E +F7CA +FCBF4D5EF5BA7B2B430E106C22195FE9EB742E21E0171ED224ED8AA965524DDB166FA2E5CD867BF69242D62C165E66 +DCEAD537 +4391FA736CBDE55B291514911413 +4BFB10D16619F8B2B2ABCF882ACEF570D938B7F383B5403AD1615A2FEF62BE7EBCB5B0FF3DE8F9B2AC1E04E412660B6BACE4EB699E5D49F7896AC2197B8E7FA01FD94D4B6EEF5E8EC7B12E8928B9AA1EA5C77AA72230062E9C885333449C0A244A50A7124C60C7C23F11429C48 +8B6873E9 +2924C709676699E42FC91E30C0 +6E10EB0EC1D42CD6CFE1832FE95A70B48B7B3842155418C31A4FE65D5B2177BA7BB21A2105AA9D6D5CE41BE9833D904E2CEB45DD9D1EBAA4C9DF2CF8A16060151F002A4A8E692DD582E21D34F1367800 +7AB2FE29 +F0924AFBAB87013B1F8014C5B184 +B42EA514C09670AABDA7D1B1DDE316F8572F57EFB5EB5938E7170DE225DA055E7D49D80344D8828FBEB56CA0404D01373E9ECA1596CE760B225AE2AC257231DFC69BED3359B15306D2B4D2F91A0484A54C3CDA4049DA3FD369856C0D37153D4C704C956E4983A7D0462F23B2B965161B4F926A08647D34F1557BFFBAF4E2 +DC04 +1FF196DAF34CE14A0FEEC0B7616854B89C608A72C061160DAAED79F4E6ADAABD5E8C72 +013CD527 +52A6337052C4CC0DD1B4A6833B +ACE8D08A745CF88FCEBE183A903869050FCAA8AB9DF9560C284B6640C1F2283FA7E3ADD18918FD08B943E5BAC4A13F3A3552C6CA33E8 +2BD4D6A7 +22289E301E6CE7D1CC3C56560C55 +438755D2D746D608CDBB4B4570E28B7E72ACB1B6859D70DF3B9E457AC5A065D9C37080FBF2CBDDD1719ECF33404397F5FFD8B24BF9F733749B351721D48142BAB97BD720133BE5ECC9FF2F324C1515DA83972F8EE4F58C87D6C5888A4F54002ECB3CD069612D1C633F333611B08F5DD8194E3AFB862CFAD3639DA54D45CE +4593 +D1DCF191D581CE143A5EC6BD2BF2C888F1300CE61BC9CC0ADCFDF7248A58A5 +548004FA +1378477760DE3A63758C14C49D63 +0E6E1FB475136579CAC6823902900DF2E282D6B6685E4044E70E52EC6F29DB9970446DBE6B065D4B268AF878AB4FE1957E3F3B4644B73EC5818F0FCE0D5E90BCAF314E716A2CE50B6770010CDCC6CCE10A4B27B4F7CA56D481779E20B61C574DEC870CCFC878AD88C1C057B3 +188D504E +15F47D7DD3361096CDC8299532 +C5940356D358746B8E80282ABB7B7D435A8F0EBEB03E5DFADC850A1D29183422C56B234E9F1723FB88F04500EBC4505FD22F750D4FEA2AC693A86BC46348A52D9DB1EEC874B8 +8698EA1D +616B29F1FB31CA9E19259C3D4F7F +4116B07F88A5C2F26EC1D21E025D77247A3FC66F67CD9E75A18C1B4819FAE03B6FE608502412848ADE377F08D46913B8CB215EFBCD5B9A44B40CA1DAB4538999DCDCF38CBB00E6750D3054AEB0B74C2BC88279482905540A13A67DE1F4A11797AA5CB39F831BDB9158E52F1CBA5E334C6E0BD89F69A8C5 +7E49E8AF +AC4EB3B2D03DAD7B270889B07BD0 +4EC6CCC66CF8666E797A578DC4067CECA5855472B2BAD3782F6548D06BEDA128C11306AB343C957C0E35E9B31AABB62FAB0228339EBB0A603C93E3ACBC480F4DDA6F1D9069F2CFC0139E57B8154E3CB4CE9B6A9A98174E13166FF2895DF5E5C6273C75146B27C2B53CBF +7AA5ADFC +51E06969C3E7D7D4CCB7BE8A5C +27AE952FE3E0BDA43D1C321CC5DE70467ECC13EA8680A038009820E8526FA7517027921764D5BF4116DF76AE808D8C5253EB203FF1EE4134A8DEB3102B67D22F93560346A1E8CC7CC3759264C68D93B3193E1DD0CFA15C +9445FCF1 +711D46A3166BBCD4E3F2BA2F3D1C +14EC30CB5C30840F799CFE784BC89039B7081407636B74AA32F20D131F82CB0DB9983648397A5AA331AFF86F545BBC22A36D394F7ADC3F3EA68C25C84B8B21EA0B0D5A5963998CA1A86183FC8A32224BB6B0DA9EDC11FB9DAEA27E259D845A621D64C1C76B05314FA315799E3B2CB3B01E105E1DC49998BE11704530 +C7953A1B +19EF6BBB443FAC4958D49D5206 +11165AAF9CE81AEA107B203B8B97D98EC6432E79B1A0266DCC7055BD0137E9D5666B6CC5C3980F0367415929B537C915357C651064852EE06687ED016AA72CFA5FCE8691E5 +31E23EBC +BE485F0FF5DBB169954B249611 +BEAEE18037402791306C4419567016CC6908ACF30223FA13A25F8702187D7CD5A5A0CA0E86B21991CB85B7D134085472ADFE35C3D95ECE80CAE64C51C7FD12C4C56446F6155AB294EE0E32EFB4A076BDA4B4659307825E41553B825F5072D764E908 +17346FE2 +FD4B6E611A97D0E571149B38A0 +D7E4E43452030F753B3D1971D7111E4E4AE04BB86D5964E9B87498C3BBDF7A35837004D85260A1943EDF4F8B5C1604F59E2735E4B9CE56C7A89959603D78143B31CD2ECE7E1015E92071B3E32279D27DD9FBEC05AD44D39B5A +17F87F4D +2BC97A7BCB992DDCF35DA48B228C +F68EE00352809455C2234B29596A6FC18DA6E2EA573D8C6B84EB3FDD6DB676CEDA21BC533DBF3B67669C40A3F863147F8B6D5C594349BBE1818C86D82BC3933AA0085A423E74D9001E9EA4BFA91F899E2F631EA91D87D130A0B19703A0F090C636B96984A363B31D64E24B7DBC5DD71407AC89F12A2229D857B3F292E04D +B62F +10035B718C4DA4D1C5A7318DDB23 +618E1E3B +4FDFFF68D9E814CC786C4A17B5C3 +E9DAF063C31352E406D224D2E51675B96D618F7DFEAB5A63CD7F4D64A61533C27FB3E1231BD8DE217E82120C52E5FD331DFDBBBD532F625508AB5F28A3250B3250F4F9380520E753504BECA0913DE92FFEB9EF3C5FD6792324457327A166DAED301DB9F00A1FACD1B4D73BE8B655971DBB5F1FC0E8092B7DEC9D46F0CDD1 +3FA3 +B61DA957546A367725E74FE428644EEF78A98F5554D0CD2AC2 +49A7BF14 +A2857CBD6344DD8AD41B898E28BD +BB4E975DE7ADE13EC4D8B5A104FC552915A067048314C32DCA575C159224BE99F95C8A042F730A5F70B88830AF0F862E483A691172F19CAE1ED4122807E6A6D0A01F201F00829574984DAAD4228F7696BD546B3A903C7B8B9B49F83B2470DE434612A3AA92ADB4B3EBD068E1C43AAC6EC14A20C7EA1C6A5D98530F5BFFA8 +8980 +F83E68EE +D218264C37764CF4A52F971FDC +88ED82449B93D6B7FA5A5EF61F40388AA45D685FD1CA0FB7BB41295BA874482EFC63040CA0FBBFDFB3232382B379866816B6C55EC7872AC348637BD498896F +A2B8CF1B +BC3EA6F31876BD790BC5F00137C6 +AF584002D3E26E0A062542450B6B6DBD412694EE447ED65B55BEC6DBBAB9E0225E0BDB8F8D7AE09290419B5535A04EC5EDC4C33066197442E65C66CA1BC46ADBAE8C7B74D376E351345FD3EE37B82B9BE4BB450D48325A1572E202CD5A207263C35B583FB72CC98F2C +DB25ADDA +C70F6D635522A767B2C6494E5E +3B14FA0952345959DE98F4DDD19E1BF9431CF9371215 +4B10E106 +F365D2363521892DD032A827EC09 +C4A5745787227EE1 +81E2EABF +1489BA1C4131103FC0B3B02FE9DE51630ACA3C65F4ABD12E4D6094A85C1BBFE9DF4C +D0CED210AE014AF4133D77E4AA5691DE80A72A9F85EB669E3FED0BBB86760634588774E5AD44 +6A5BCB4E70E6D24D69290D26497C4B5A50AC666184D95F29F9C33F +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +%Defining font PSOwstdutchb +%!FontType1-1.0: PSOwstdutchb +10 dict begin +/FontName /PSOwstdutchb def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001000 0 0 0.001000 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 1 /C0032 put +dup 2 /C0046 put +dup 3 /C0051 put +dup 4 /C0058 put +dup 5 /C0066 put +dup 6 /C0067 put +dup 7 /C0068 put +dup 8 /C0069 put +dup 9 /C0078 put +dup 10 /C0079 put +dup 11 /C0080 put +dup 12 /C0083 put +dup 13 /C0084 put +dup 14 /C0085 put +dup 15 /C0097 put +dup 16 /C0099 put +dup 17 /C0101 put +dup 18 /C0102 put +dup 19 /C0103 put +dup 20 /C0104 put +dup 21 /C0105 put +dup 22 /C0108 put +dup 23 /C0110 put +dup 24 /C0111 put +dup 25 /C0112 put +dup 26 /C0114 put +dup 27 /C0115 put +dup 28 /C0116 put +dup 29 /C0122 put +readonly def +/FontBBox [0 -209 742 694] readonly def +currentdict end +currentfile eexec +D9D66F633B846A989B9974B0179FC6CC445BC7C8A959A39A32E9DCE7FAEF17EE3BEC9F +50E1A6FCA651FC4B3769A0A91041557502E25A5D6180FE25A3D11BF079E1DF66E54EE9B7C229AF891739707A2A0EC140306B5E43E52B79BFB89E459E50 +6EC6F610A70775A31C460976C4F79449D86E57ACE491E5C6BF20CC4307B1DAF7630252 +E9AF8CFB69B50EDAE9D36A6104AFEF8832F920FD2346B2C7104CD11E3BEE999CFA9F5A +49DB3173EE48D1C82994237F360407B022E0B4 +502E94EA8B493651EF2D03F0B513D655047568325B512AE6 +6AC6F53F3848CF70DE25481CC65D8B1A5793AA +3C4282D111112BEE28AFCA7A3808D4444C4669CA +84EAAAF989219F51AB3476A1B0B5F2246BC306E6 +625C6679C417ED2A8E9BD010DE37D40265074C2684274DF5CA2235B505452EF82C19378A786E0B +30288B05492EE4BB6123C04C +3FB31E3DA5151DECA4 +238032FA +D2FA7FB1824D5B65B72B33E7D9 +023B3B8C45A9D80B2FB65F9BEEA3CF7435B74F2AA261EE7A8B8E6CAF4F16A3 +77D2B03D +67DB68A102A2187EEAEC40920F7E +B24EC803FF899334D22407980DF11C03FBF457FF4915BBAD772428B153C571F8C15B58B3EEDA50F2F0FA7FFB9999ACDA28FDA294D77CA99CE146D611F92021BB1EE3799C8BB8E59A651C9D3FD4D40B3FAD73A53645C951DF91634C2D59E7F5B71DCCD9422EE27EE0C99C8D2F7218AC4A6E9C38 +7BE0D4C4 +E22E5581E26BBA3721462258D5 +DFBFD7DA400BC76880C1DEF24363BAB22C53F7B3A8B411454AA96722A51AE6B597954DA51D6ED154AB68C551FE9D247B6C0D42856999 +A8AB2D61 +E5C1246DA4DBEE2FC06F5A6750E1 +2464F7725AFB096B763B43E83C4C8C64ABF3B358C31CDE69A7B9EF14CD408393D766B8C3F8602AA6663961BDD7939A2B2DB938A16AC4D8E7DCA1F2EC4587D9A9F7883487C0EADA360C971503AF7C2E9E00F2BCFAD44D1BDE8CCF14AB82C52B2FD31B018D3E15589BA54AAEEFE899235A32E6D5AE8817899636E6 +D10F9433 +311D3AF9D071DA8D914DF64802A8 +2227ED890E40470CBD5B0DE74EBD9BC99DCEC14D47CC09983BE3B371BF504455FD489831EC465694CA4EC9C892701D842102DFE5DAD1C650276E5134A197FEDF984C9CE2DB482552A0968D441F2C5C194907411AC9A9360841D3C390B5C02D0B3CE98E48E5A67401 +5C83FB23 +FAB11A0D46F8C554251AFCF83E +A09EC1FE7C84B0FB4EDD1D28028EE833C2586A1C1E9E6AA5579D8D7CF2027B7AD60EACAD8AB1A1043C78FF9FA4914D4E201759A47A5F09AB8A0C267BAEF567F3E80DF65779871C5FF7306DCF76E3C34DBDC7D8847A74B0 +DD16D64B +212A534CB4BB034A1A200C17C02A +844CD9F4817C3B32826A14F0096AFFC90D02846B0E5AFD777D99EA9534EB747377558C6AC5FB79769F115401F6DB68D155DD9190B0A1FAE40F9B351A9A207734FB3A983D3DF4F71B6C9FDFFA1C18D4DA9435BEA406EF2167B8AE6AB76244B56A52A0D1F0221ECC53B4B7A4951996 +C9FA6320 +FAB29B060DDF09B6184694442A +ADDBB4DE0262762759280B5534DC23DA2C25E1586F3438D1391D7EDD955A9F5E714D423C6A4314E5905953F70FE6DF954A63CA4A746B9370283B1ED451AD54AF9B2B7B8EA8D8B909527D9D9E0865A766A76C7F6B01BA66E963BADB701C7387 +98D45D21 +BB40C5D00AD5C6DB6EAD6A5C182C +775FD887325114B39801F543C7712243F7F6E9A911DE73760FDB1CC9D6350154D9552AD20116E0BC12528AE37A84060B1CF12DACC354F1CC89488A55DE044B3FEDDB34D442229008910468F4B078E5300D19BAC2AF053485AF09029E37952E105330399ED50E4DBAB0 +89DD0CA0 +489B77F1128856DD55E7633E3DC1 +86ABA08F793FC6C49EBA5369A1BB90BF85B05C7D204BBF46BB4A76FEE24A0033B873D80D23716FDCC4AFFF46C4BC2B36B3F98462FCA5A765499FDAA878B216F0F2D1D4D9232FBCEEF68AD5BC82C4B8D5555FA020A3396C1E666E976F30565C4A7BF15FF1 +0C37DABD +3C3BB20583325637034B728049B1 +16F1096A198B135EB1EB818BE48E7CE6850091F548D963217710DE53674B112B48A401F0957F49CDD0B2B5F04FB5AF36E7560A10AA2B2A0B587B062FCFB90FB8B101E4D798A5A57994A76C79CE17E1F68304E9490BE2BFB56390C3ED3062909B025FB555F35EFC7A85C3A5648399966550DF44A1D172D13E4DFBBA3A8671 +0DA5 +265FD62D +C54D11535A118AC1026ABD2F6E +793C31EB657ABBF29915B4B8CD92DD8F6E244A841D45DFE2ECB6828D301B633658F291BDF2FE4DF0CA1FFBC98B8FDE38CD1B965F44972D513C51CAF6E310557EA84FA4DE9A0B94342F +C907F7D5 +A3999AF4D3E5E5B4E18ACBE3F6B3 +06D1B8B9217D3277A7DC9174E76500C8F6815F1962CC1B3D0F219DC7F6DEE976467702B64E62F3778DA0BF047722383099477958D4F8EF9270D854AC5087D95C7E4B3FA7D739F6E7501F7653A7527CA62E095E2CBCDEBD7FB7624FF994F67F9CC644433F4F7D55 +1345A4C7 +9B97659E93891A07B8C00968AEFB +7F45C8508C7E620B0F7CBED65A1E3AF18F5E3893CCCB56B1C6FC0CBB72CAE2C9542F3EDB527E9957B59D269336E0C204C53A51DED7ECB44159FF20F6A2F36C178753AAF4861F0D6214B73F7AE6C4FF7BC9494F49FC5E837689E738C6506D2C7356983DACE29F185290FE9AB2839DC62A93F6041FA60796227AA29234FDFD +2CBF +46F25922 +B688213D +E9683E44AA2325D6BD428CD872 +25C7FF285E7EEC86CDC28E9801CE714653ECFD7F83757D3F0F7E3FC5511AB7283292633B9BF08A959AF3FD1AE5C741F085BFC97C1666BEDE34709794EB6B38A2E429E482F793A1E99640FA92457B5D28E6EB +D6B2DE4F +579A1165485B222C76E7D74C36 +412F614B604AAE105AEF7F9E1A61CD5521795967B26C38D0C62E1F1B7CD5C934F45A20096042C4A58C70D0FEBC92EC054204AA0325C676D4E91402C7BBD8B4A076489259052BCD494BD8AA858A03F89C593B38B51D4953FD33029C6E +CD2662FC +1428F1EFA376820C245B675738 +91636ABD489D9A812CD21F96D16FBC8515E89425D49996A6570D03253F17122BCC0D75185A99C20720BB709435C3AAC11469248835C8819C1E6DF6AB7C5AB69FB615C68C1344317F5FFB7ED206A5F050969B1D5C7A81192392AC253BCD +41796E1F +023CF263FF7351AD10D303CEEF0D +9E89E666A6E55DEAAE8595DACBD8E6884288F414A27D8B23A9C9B784BF9E184A28F2680191A2ED1F1D86D3A60B1005FAF299F624A70489CF9DDFED8C5527F68EFC09B7BD7D369F3B0277B578444408DF4BFEE95FBD6478FCEB21AB0D72C6C7A663AD1C0857610091D819C55C5EB7E32591FA5FFE1963CF7448F424986623 +9A5C +3AAAFC9525F09E0EA02D4B5625F4BC47F354850C8E3E0C9D3C2DAAA3122831D685262F5BEE +F6ED0E37 +2A1EB37B88185C985839FB71E7AB +E6EFEB2ACC3833BB9B9EEA8077CA42F77D5DCD9D02700718F430820F6E56605B459E372D1DB477A2B6D165948BBD48E3AD3D68E6F11E6291E11CF0E1A0D2A32D821D5E95D2B9D6550CE13C12122A48AC534DF625E06C99F913D72DC37D19B7D79B0B425F2995D3A2 +A281FC86 +EA32437AEC26006AEAC4F91333 +D6CD3899DAD73AF7865E47FA9CC63555B44161680E5FB8BBBD5D729D0CEC42F9CDEC8D492BF5E83BC439B0F2136C8D76D5A95ED7CDB21C5AC2DAA2F52E7DFBA030FCE708F4269D55D95F63DD6773 +976B459D +8B67115C730FD9718A3A164A0A +1FAEC299D0D380DD5C7C4D43D9C56024B974D4BD8210453F4E28BDEEEF3E18195C8CF9D1E6565FB09642C8DA42EA33937FA841C4 +C1EDED5D +EFD87D740658B14843CB4A743DE6 +3B7A83955BABFA1A57E770F3382BDC5CD2E3C45594FFE96280DE5C06D9957CFD6FCC3B38B8DB21049029965E318700DB2153B0E362D7EE7494FC01A35ABF6BE7894A42C0DB6536F3F15DAF5E0AEBE5BE7DD4A1FA18BFD4DB0E86C063A4285E3E6BBD3A03378445 +712726EC +94AD573FCE5D2ECDB1D2539696 +73DFF8AB6219E1C2E336F9AD9210DC8E35779A0BAC103860E3F379A4CCD460B543C343865C58FB0425801C528F29F3E600BB744E4FA8C1D65A8BFC8A50FB7256C280A43381B8 +026A2324 +D236DEFE60466DCBAE520110BAE0 +1E67A6F3F4170D77D76ABC5B2F6DC54848225F6A0874509ADC10FD4986EA82EBE8555F8A0B78D0BB4D3277D3C4776799D9D3F2ECE99A412D81CBE788639713E7A3FDAD7A459F19650020DBF46C1446F6D98993EF09F5717E44919C36E27F88C5D0E2780E50374378D5E3DD32AE583B18BE +864B8C0F +331296B32784FF821862384D0B +6BCA5C7739A339D4B1582E81AC623F4B3A1F1159F6D11BC894B497A4EEAF42F6C9AED15F36B4A833E0A9AD7D2E324BE9DECCA12B08B929A3923A7FDBA6BD24BDBA795233BDF30E254C967FF8F09183F1B2ADE04AEF1F85E9C7 +F4BA1086 +DC49229C644E07BB556077A763C3 +178F38BBFD140088C7239510DAAB4685E936B859B92E9E020A9BCBBAA2FB64776D800264C1E5B31DD821957BB42E332657C71503E3004A96F8C554458EC744B8305E0548CD53B73C34020A349D9668C0903C2897278F8452E03FE9A9C23D0039CB5BD5C68D0004304950E87B5A7CDCBE067EAADDE6F3ACB512 +7CA6C6DE +AA5FC279833F686249A201EED8 +B4E96B5CBB5458E62E7CB9555A47B9A23AF559DC8861C13BDC88F699ECC0A31B64F2E28EC8238C6600BB3AF7537D381F5DDC6C3E0A95BA60E8C3F4C4F6862592D5067321 +93EA3C8F +CB7A87588519DE880081939745 +F9D5EEEC1D2244C905423357F56885F15976509825027874A1F4648CD665EF6BF8317B1394F97D0AB2974905A364DE883E2F7CB15AA131AB71E3F4A861 +D2C6D8D1 +E8AA4A67CDD53D8BAFF3ED1FCD70 +B4A6855EA1E490A4 +1C0B76E3 +F876612374BFB7FB171A76D76E47F8F8327D990733A3D361A3BEA6BB0CCD09BE735D +810E7E0518C506E7741E9E4EB46FC380B70B3A1B96755B807636DA451E382EF3A7C50971C385 +424DC125D33973FEEDCAE43E50AA1B371DD8551155B6E291DE3036 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +%Defining font PSOsymclas +%!FontType1-1.0: PSOsymclas +10 dict begin +/FontName /PSOsymclas def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001000 0 0 0.001000 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 1 /C0069 put +readonly def +/FontBBox [106 45 775 713] readonly def +currentdict end +currentfile eexec +D9D66F633B846A989B9974B0179FC6CC445BC7C8A959A39A32E9DCE7FAEF17EE3BEC9F +50E1A6FCA651FC4B3769A0A91041557502E25A5D6180FE25A3D11BF079E1DF66E54EE9B7C229AF891739707A2A0EC140306B5E43E52B79BFB89E459E50 +6EC6F610A70775A31C460976C4F79449D86E57ACE491E5C6BF20CC4307B1DAF7630252 +E9AF8CFB69B50EDAE9D36A6104AFEF8832F920FD2346B2C7104CD11E3BEE999CFA9F5A +49DB3173EE48D1C82994237F360407B022E0B4 +502E94EA8B493651EF2D03F0B513D655047568325B512AE6 +6AC6F53F3848CF70DE25481CC65D8B1A5793AA +3C4282D111112BEE28AFCA7A3808D4444C4669CA +84EAAAF989219F51AB3476A1B0B5F2246BC306E6 +625C6679C417ED2A8E9BD010DE37D40265074C2684268F16195489648993B9C4D3B534FA887C +DEF605FA87B991F4D20A8F78DACE +5A54C070E03D5C59D9D2D3E06B09CEE028D68B62AB3AEC43C1DD20BA70D288597D9BD8E06818FF764EBAB436723988E8D7CA59E16D39032516BFC5D552ACDEEC6BE938BEF2F43CFFBC811C3626C4DF5F8CF080676520B51C60CEDAD1FE6C92D1431C702174CE517A8FA9377D075A0B6833DAB101DB65397F1419EF5F0016 +004F +6F0824F9657BB4F1C8F981709956865F6855EFAE +9242AD55 +91BBBEE163D844DDA894E13190C9 +2480439E4C71CADA +BD043A9B +A315CAF72652AA7FE6DB2E84D82A6111CE4DE90C02DA0AFFE2620922262A45AB4ED0 +EEC9F4520DD12703442F7D028D4526BD8B771E09FBE11B2749E2D3906894E8D4BFD3F379F14C +3C874F550606965E22FE487B247B5C2D06728490C8F2A3B588CDFC +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +/DPIx 1270 def /DPIy 1270 def +72 DPIx div 72 DPIy div neg scale +0 -13970 translate +1.00 1.00 scale +/wst:dutch12 12.00 /PSOwstdutch newFont def +/wst:dutch12b 12.00 /PSOwstdutchb newFont def +/wst:dutch14b 14.00 /PSOwstdutchb newFont def +/wst:dutch10 10.00 /PSOwstdutch newFont def +/wst:dutch14 14.00 /PSOwstdutch newFont def +%%IncludeResource: font Helvetica +/wst:helvps10 10.00 /Helvetica /wst:helvps ILEncoding 0 declareNFont def +/sym:clas10 10.00 /PSOsymclas newFont def +%%EndPageSetup +GS +0 13978 10801 13978 10801 0 0 0 clp +wst:dutch14 SF +0.00 0.00 0.00 1.00 setcmykcolor +<1c2c3a362c382d0e011001112c342a2f33283831012d3538011b2c28393b3830342e011c2c3a3d353831011e> 2207 558 0 7384 -1 s +<2c382d35383328342a2c> 7375 558 0 8593 -1 s +wst:dutch10 SF +<0d> 9434 13300 0 9522 -1 s +wst:helvps10 SF +<4e6574706572663a> 1322 13280 0 1949 -1 s +<205265766973696f6e20322e313b20436f7079726967687420> 1949 13280 4 3868 32 s +sym:clas10 SF +<01> 3868 13280 0 4019 -1 s +wst:helvps10 SF +<2031393933b131393935204865776c657474b15061636b61726420436f6d70616e79> 4019 13280 3 7133 32 s +wst:dutch14b SF +<0c11101c151817> 1271 1458 0 2055 -1 s +<000302000d14110007111b1513170018120009111c19111a12> 2055 1458 5 4703 0 s +wst:dutch12b SF +<07111b151317> 1271 2007 0 1899 -1 s +<00050f1b15101b> 1899 2007 1 2539 0 s +wst:dutch12 SF +<1c2c3a362c382d> 1271 2353 0 1980 -1 s +<003039002b2c39302e342c2b002838353b342b003a2f2c00292839302a002a32302c343a09392c383c2c380033352b2c320a00212f2c382c0028382c003a3d35002c3e2c2a3b3a2829322c39000900342c3a> 1980 2353 13 9461 0 s +<42> 9461 2353 0 9531 -1 s +<362c382d> 1271 2598 0 1643 -1 s +<0028342b00342c3a392c383c2c380a00162c342c382832323f003f353b003d303232003534323f002c3e2c2a3b3a2c003a2f2c00342c3a362c382d003638352e3828330009003a2f2c00342c3a392c383c2c3800363835> 1643 2598 14 9461 0 s +<42> 9461 2598 0 9531 -1 s +<2e382833> 1271 2843 0 1734 -1 s +<003d30323200292c0030343c35312c2b00293f003a2f2c00353a2f2c3800393f393a2c3304390030342c3a2b0a> 1734 2843 8 5651 0 s +<242f2c34> 1271 3146 0 1817 -1 s +<003f353b002c3e2c2a3b3a2c00342c3a362c382d08003a2f2c002d3038393a003a2f30342e003a2f283a003d303232002f2836362c34003039003a2f2c002c393a28293230392f332c343a00352d> 1817 3146 13 8288 0 s +<0028002a35343a383532002a3534> 8288 3146 3 9461 0 s +<42> 9461 3146 0 9531 -1 s +<342c2a3a303534> 1271 3391 0 1944 -1 s +<003a35003a2f2c00382c33353a2c00393f393a2c330a00212f3039002a3534342c2a3a303534003d30323200292c003b392c2b003a350036283939003a2c393a002a35342d302e3b38283a3035340030342d35383328> 1944 3391 14 9461 0 s +<42> 9461 3391 0 9531 -1 s +<3a303534> 1271 3635 0 1630 -1 s +<0028342b00382c393b323a39003a350028342b002d383533003a2f2c00382c33353a2c00393f393a2c330a001f> 1630 3635 9 5759 0 s +<2c2e28382b322c393900352d003a2f2c003a3f362c00352d003a2c393a00292c30342e00383b3408> 5751 3635 7 9189 0 s +<003a2f2c> 9189 3635 1 9531 0 s +<2a35343a383532002a3534342c2a3a303534003d30323200292c00280021121e002a3534342c2a3a303534003b3930342e001120130039352a312c3a390a> 1271 3880 9 7064 0 s +<1d342a2c> 1271 4183 0 1757 -1 s +<003a2f2c002a35343a383532002a3534342c2a3a303534003039003b360028342b003a2f2c002a35342d302e3b38283a3035340030342d353833283a303534002f283900292c2c3400362839392c2b08002800392c3628> 1757 4183 14 9461 0 s +<42> 9461 4183 0 9531 -1 s +<38283a2c> 1271 4428 0 1631 -1 s +<002a3534342c2a3a303534003d30323200292c0035362c342c2b002d3538003a2f2c00332c28393b382c332c343a00303a392c322d003b3930342e003a2f2c00101e18390028342b003638353a352a353239002836> 1631 4428 14 9461 0 s +<42> 9461 4428 0 9531 -1 s +<363835363830283a2c> 1271 4673 0 2118 -1 s +<002d3538003a2f2c003a2c393a0a00212f2c003a2c393a003d30323200292c00362c382d3538332c2b080028342b003a2f2c00382c393b323a39003d30323200292c002b30393632283f2c2b0a> 2118 4673 14 8686 0 s +<1c2c3a362c382d> 1271 4976 0 1980 -1 s +<003632282a2c39003435003a38282d2d302a003534003a2f2c002a35343a383532002a3534342c2a3a303534003d2f30322c0028> 1980 4976 9 6412 0 s +<003a2c393a003039003034003638352e382c39390a00122c383a2830340021121e003536> 6412 4976 7 9461 0 s +<42> 9461 4976 0 9531 -1 s +<3a3035343908> 1271 5221 0 1764 -1 s +<00393b2a2f> 1764 5221 1 2202 0 s +<00283900201d271914141e> 2202 5221 2 3426 0 s +<101a1823140800302d00392c3a002839003f353b3800393f393a2c330439002b2c2d283b323a080033283f00363b3a0036282a312c3a3900353b3a003534003a2f2c002a3534> 3399 5221 13 9461 0 s +<42> 9461 5221 0 9531 -1 s +<3a383532> 1271 5466 0 1595 -1 s +<002a3534342c2a3a3035340a> 1595 5466 1 2699 0 s +wst:dutch12b SF +<060b0e000e1c1516151d0f1c151817> 1271 5848 1 2737 0 s +wst:dutch12 SF +<121e22> 1271 6194 0 1723 -1 s +<003b3a30323040283a303534> 1723 6194 1 2687 0 s +<0030390028002d382c373b2c343a323f00382c373b2c393a2c2b00332c3a38302a00352d00342c3a3d35383130342e00362c382d35383328342a2c0a0022342d35383a3b34283a2c323f08> 2687 6194 9 9531 0 s +<303a> 1271 6439 0 1398 -1 s +<002a2834002832393500292c0035342c00352d003a2f2c003335393a002b302d2d302a3b323a00332c3a38302a39003a3500332c28393b382c> 1398 6439 11 6458 0 s +<00282a2a3b38283a2c323f0a001c2c3a362c382d003039002b2c39302e342c2b003a35> 6458 6439 5 9531 0 s +<3b392c> 1271 6684 0 1573 -1 s +<0035342c00352d00392c3c2c3828320005362c382f283639003632283a2d353833002b2c362c342b2c343a0600121e22003b3a30323040283a30353400332c28393b382c332c343a00392a2f2c332c390a> 1573 6684 10 9148 0 s +<00132c> 9148 6684 1 9461 0 s +<42> 9461 6684 0 9531 -1 s +<362c342b30342e> 1271 6929 0 2001 -1 s +<003534003a2f2c00121e22003b3a30323040283a30353400332c28393b382c332c343a003a2c2a2f3430373b2c003b392c2b080028003b3430373b2c003930342e322c09322c3a3a2c38002a352b2c> 2001 6929 11 9183 0 s +<003d303232> 9183 6929 1 9531 0 s +<292c> 1271 7174 0 1489 -1 s +<0030342a323b2b2c2b003034003a2f2c00121e22003635383a30353400352d003a2f2c003a2c393a00292834342c38002d35380029353a2f003a2f2c0032352a28320028342b00382c33353a2c00393f393a2c33390a> 1489 7174 16 9266 0 s +<212f2c> 1271 7477 0 1631 -1 s +<002b2c2d283b323a00121e2200332c28393b382c332c343a> 1631 7477 3 4049 0 s +<003a2c2a2f3430373b2c003039002928392c2b003534003a2f2c003b392c00352d0041323535362c383903003d2f302a2f003d3032320039303a003034003a302e2f3a> 4049 7477 13 9531 0 s +<32303a3a322c003235353639002a3534393b3330342e0028343f00121e2200322c2d3a00353c2c3800293f003a2f2c00342c3a3d35383130342e0a00212f3039> 1271 7722 10 6898 0 s +<00332c3a2f352b> 6898 7722 1 7627 0 s +<0030390034353a003d303a2f353b3a00303a3900282b2b> 7627 7722 5 9461 0 s +<42> 9461 7722 0 9531 -1 s +<2c2b> 1271 7966 0 1492 -1 s +<00353c2c382f2c282b0800293b3a003d2f2c382c3c2c3800363539393029322c08002a28382c002f283900292c2c34003a28312c34003a3500312c2c36003a2f283a00353c2c382f2c282b003a3500280033303430333b330a> 1492 7966 15 9531 0 s +<182d> 1271 8211 0 1422 -1 s +<003f353b003d353b322b003230312c003a35002e2c3a002834002c393a3033283a2c00352d003a2f2c00353c2c382f2c282b0800383b340035342c003a2c393a003d303a2f00121e22003b3a30323040283a303534080028342b0035342c> 1422 8211 18 9531 0 s +<3a2c393a> 1271 8456 0 1595 -1 s +<003d303a2f353b3a080028342b002a35333628382c003a2f2c003a2f38353b2e2f363b3a390a0022392c00352d00323535362c383900303400332c28393b3830342e00121e22003b3a30323040283a303534003039> 1595 8456 13 9249 0 s +<003034> 9249 8456 1 9461 0 s +<42> 9461 8456 0 9531 -1 s +<2b302a283a2c2b> 1271 8701 0 1933 -1 s +<00293f003a2f2c00322c3a3a2c38002a352b2c00411a0a03> 1933 8701 5 4000 0 s +wst:dutch12b SF +<090a0d08> 1271 9004 0 1866 -1 s +<04> 1870 9004 0 1928 -1 s +<00> 1928 9004 1 1966 0 s +wst:dutch12 SF +<0015> 1966 9004 1 2135 0 s +<353800282a2a3b38283a2c00121e22003b3a30323040283a303534003534001b1e00393f393a2c33390800303a00303900072a383b2a30283207003a2f283a00342c3a362c382d0028342b00342c3a392c383c2c38> 2127 9004 13 9531 0 s +<3134353d> 1271 9249 0 1756 -1 s +<003a2f2c00343b33292c3800352d003638352a2c3939353839003534003a2f2c00393f393a2c330a0015> 1756 9249 8 5519 0 s +<3538003935332c00393f393a2c33390005171e09222506003a2f3039002a283400292c002b2c3a2c38> 5511 9249 7 9461 0 s +<42> 9461 9249 0 9531 -1 s +<3330342c2b> 1271 9494 0 1840 -1 s +<003638352e38283333283a302a2832323f0a001d3a2f2c3800393f393a2c333900382c373b30382c003a2f2c003b392c00352d003a2f2c0041093403002e3235292832002a35333328342b003230342c> 1840 9494 12 9233 0 s +<002838> 9233 9494 1 9461 0 s +<42> 9461 9494 0 9531 -1 s +<2e3b332c343a0a> 1271 9739 0 2007 -1 s +<171e092225> 1271 10041 0 2087 -1 s +<000c0b0a2500352d2d2c3839002800402c383500282b2b303a303534283200353c2c382f2c282b08003c2c383f00282a2a3b38283a2c00121e22003b3a30323040283a30353400332c2a2f2834303933> 2087 10041 11 9531 0 s +<2928392c2b> 1271 10286 0 1791 -1 s +<003534003a2f2c0036393a283a050600393f393a2c33002a2832320a00182d003f353b0028382c002a353336303230342e00353400171e092225000c0b08003f353b00392f353b322b00382c3632282a2c003a2f2c> 1791 10286 16 9531 0 s +<410913222014271a1d1d1e141f> 1271 10531 0 3181 -1 s +<03> 3169 10531 0 3268 -1 s +<003034003a2f2c003328312c2d30322c003d303a2f00410913222014271e2021> 3268 10531 5 6678 0 s +<10> 6658 10531 0 6821 -1 s +<21> 6801 10531 0 6940 -1 s +<030028342b00382c2a35333630322c0a00242f2c34003a2f3039> 6944 10531 4 9531 0 s +<332c3a2f352b> 1271 10776 0 1967 -1 s +<00303900292c30342e003b392c2b08003a2f2c00322c3a3a2c38002a352b2c00411803003d30323200292c002b30393632283f2c2b0a> 1967 10776 10 6526 0 s +<1d3a2f2c38002a352b2c390033283f00292c0030342a323b2b2c2b0030340032283a2c38003c2c38393035343900352d00342c3a362c382d0a00242f2c34003a2f2c00121e22003b3a30323040283a30353400332c2a2f28> 1271 11079 14 9461 0 s +<42> 9461 11079 0 9531 -1 s +<34303933003039003b343134353d3408002c303a2f2c38002800412203003538002800410f03003d30323200292c002b30393632283f2c2b0a> 1271 11324 11 6361 0 s +<16382c283a> 1271 11627 0 1803 -1 s +<002a28382c00392f353b322b00292c002c3e2c382a30392c2b003d2f2c34003235353130342e00283a00121e22003b3a30323040283a3035340a00112c002a2c383a283034003f353b0028382c002d28333032302838> 1803 11627 14 9531 0 s +<3d303a2f> 1271 11871 0 1657 -1 s +<003a2f2c003a2c2a2f3430373b2c00292c30342e003b392c2b080028342b00303a39000030333632302a283a303534390a0015> 1657 11871 9 6087 0 s +<3538002c3e283336322c08002800332c2a2f2834303933003a2f283a003039002928392c2b> 6079 11871 6 9531 0 s +<3935322c323f00353400121e22002a2f28382e2c2b003a35003a2f2c00342c3a362c382d0005342c3a392c383c2c3806003638352a2c393900283235342c003d303232003230312c323f003b342b2c3809382c3635383a003a2f2c> 1271 12116 13 9531 0 s +<382c2832> 1271 12361 0 1620 -1 s +<00121e22003b3a30323040283a303534> 1620 12361 2 3069 0 s +<002018161c18151812101c211a> 3069 12361 1 4685 0 s +<260a001b3b2a2f00342c3a3d353831003638352a2c393930342e003a28312c39003632282a2c00283d283f002d383533003a2f2c> 4650 12361 8 9531 0 s +<3b392c38> 1271 12606 0 1654 -1 s +<003638352a2c3939002a35343a2c3e3a0a0012283c2c283a00112c342a2f332838312c3802> 1654 12606 4 5184 0 s +GR +eop +%%PageTrailer +%%PageResources: font Helvetica +%%PageProcessColors: Black +%%PageCustomColors: +%%Page: (9) 9 +%%PageResources: (atend) +%%PageProcessColors: (atend) +%%PageCustomColors: (atend) +%%BeginPageSetup +bop +%Defining font PSOwstdutch +%!FontType1-1.0: PSOwstdutch +10 dict begin +/FontName /PSOwstdutch def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001000 0 0 0.001000 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 1 /C0032 put +dup 2 /C0034 put +dup 3 /C0039 put +dup 4 /C0040 put +dup 5 /C0041 put +dup 6 /C0044 put +dup 7 /C0045 put +dup 8 /C0046 put +dup 9 /C0047 put +dup 10 /C0048 put +dup 11 /C0049 put +dup 12 /C0055 put +dup 13 /C0057 put +dup 14 /C0058 put +dup 15 /C0060 put +dup 16 /C0062 put +dup 17 /C0065 put +dup 18 /C0066 put +dup 19 /C0067 put +dup 20 /C0068 put +dup 21 /C0069 put +dup 22 /C0073 put +dup 23 /C0076 put +dup 24 /C0077 put +dup 25 /C0078 put +dup 26 /C0079 put +dup 27 /C0080 put +dup 28 /C0083 put +dup 29 /C0084 put +dup 30 /C0089 put +dup 31 /C0091 put +dup 32 /C0093 put +dup 33 /C0095 put +dup 34 /C0097 put +dup 35 /C0098 put +dup 36 /C0099 put +dup 37 /C0100 put +dup 38 /C0101 put +dup 39 /C0102 put +dup 40 /C0103 put +dup 41 /C0104 put +dup 42 /C0105 put +dup 43 /C0106 put +dup 44 /C0107 put +dup 45 /C0108 put +dup 46 /C0109 put +dup 47 /C0110 put +dup 48 /C0111 put +dup 49 /C0112 put +dup 50 /C0114 put +dup 51 /C0115 put +dup 52 /C0116 put +dup 53 /C0117 put +dup 54 /C0118 put +dup 55 /C0119 put +dup 56 /C0120 put +dup 57 /C0121 put +dup 58 /C0122 put +dup 59 /C0124 put +dup 60 /C0127 put +dup 61 /C0262 put +readonly def +/FontBBox [-50 -256 920 764] readonly def +currentdict end +currentfile eexec +D9D66F633B846A989B9974B0179FC6CC445BC7C8A959A39A32E9DCE7FAEF17EE3BEC9F +50E1A6FCA651FC4B3769A0A91041557502E25A5D6180FE25A3D11BF079E1DF66E54EE9B7C229AF891739707A2A0EC140306B5E43E52B79BFB89E459E50 +6EC6F610A70775A31C460976C4F79449D86E57ACE491E5C6BF20CC4307B1DAF7630252 +E9AF8CFB69B50EDAE9D36A6104AFEF8832F920FD2346B2C7104CD11E3BEE999CFA9F5A +49DB3173EE48D1C82994237F360407B022E0B4 +502E94EA8B493651EF2D03F0B513D655047568325B512AE6 +6AC6F53F3848CF70DE25481CC65D8B1A5793AA +3C4282D111112BEE28AFCA7A3808D4444C4669CA +84EAAAF989219F51AB3476A1B0B5F2246BC306E6 +625C6679C417ED2A8E9BD010DE37D40265074C26842247DA7FC91B9FEBA82925C7B7A9B0D22DD1 +7C0E9A7093608F1410546F00 +09F98531B5959B588C +79CC3103 +04952A259B81E452111B161889F2 +3347D5B60BCBEE9DEA320EC36F8F8E4485C03CD6EEB3F882180086CE0471E1CA1A4F2EB1D79854FAEC9E095FE26CFBCA133E36124CDEBB7D8A85300AD1F0F916EE730CB9C210361B827FF637510A47A20B477D6788D0C4E48B1195C329378AA1D8574A6FD6BE84 +8C1C7C8C +88054795FFE8E6D847339C2037 +CF6834EBF57E559A541BC41D4355A7B901BD6BEA1380E49F95F59E06C54029D7D3E25F5C79CF02BE50380609FBCEBA700B3412273EF8C1D0 +CB5F9C5B +36DC4E45191E492F37AA19EA66 +4C06312CB899F76226E5CD4872619D8724B0A63B3939394AFD6507ECDEC8F809353F219F8B4C55B0A069B766C89A6901D401A3C7E212F85300D5E9A6BDCF98BF +7F7DA7DB +7ADD8C6F9571E1A31560B02B19 +15CF48CDED5418EAA6F218A1FC21EABCCD54C48C89D07C5C6C67F93556ADCA634F522BA59FC60378E8C6EC45D5B9FA2547EA85FCA6D36339578E5A9B1272B7 +5B6B00F6 +17DD865D766161250A6BE43727 +89A5E4A80650CC858C80B0F32234A2C14647404A779294A0AE08AD3B3597D8CE397B4F0E0B7E1B81E4A2F8A1445B49CEB3574C5021160280CF +587626DF +C5D71AFB150469E609AB750E41 +B77997BBAB288994BE952C462F1F8429CDC51CB2872916 +D43E776C +36B4FFFDD06DC65B05462693C3 +2FE5B20EED8C90559B0F5E4A3571BCD6F232546FFA3E32CFEC7EFF5F695D08 +ACDD06BD +C194ECA77A408D6E7A149F7CDD +EFDF6AD4360051B32D0AB7EE2EC9D2BF22CBE0841DF26008A97D08C6 +4B872D6E +F3836BA5C5A9AC32D1A365FAFC +6638976156E445F5978B725A51BB4661EC1316811D3D4918B08BBE522412B6D273BE93C7C31B04DDFB9B3F5789C07A2681758C85C9647C7E6FDD45F297FFB1308893A293312ECC9751FD +AEAB2131 +B5B2DEC8EE69E7D55464EE7B1D +BF351FD92E0F573091ADBA308F279079E6E3F1A0E1D33730A46650AA0B8A1FAB249ED3370CE20B085CE2186086FC6885FCE89C9335EF9D17EED3352066BE0E +DA054FF3 +F5E40A76F256788300FA3F81E2 +97E7AEA3FE1AA6A94EE8EFCB82EECD8CE1343D569C57BE299C95D9EC93B8B6B528CA67DFC382AE998AD814 +DAB52C53 +F1233D5727108E81936338BCB61B +03E6DE12D8A07FF69703B47273DDE0543B667FEF9D934913A91D07E505D53ACB6B79C2110F6D38C90B6502C063AF70836F1F6E78DF85CBC82D3ACC093E02F47DA13A81E49F0D2DCC7BDC2682FB530E88C50BFAD605A7776E01C2520404FF0AA2BC841999F8 +7E95EF91 +9A01557F8893944FF8384AF056 +2C85694C266DE368DE784F3132021C8F7DF9AAAE105D2C1D92A11EAB27A05B7106A3073026C2DE8E8DE364C13976EDFA3A5D17E92996 +138EBA90 +70F90CE6416044C2D5E74709C7 +38989E932312981F6494FC4FBBBE4450085CA9119CBB63C21EEDC273463F3D4D68CFC1A6C086DF9351 +B81392B5 +4CD8EB8F8A4BD38E377029E6C5 +78F5239701896530EB4AE6A50E7D5EE67C695DB0BBF47763AD0EC76DEDC8B793DA9D57B9DB4E27 +11D40023 +D7BEA3CB314BFB9053DB2A31AAA7 +432D7D3BDFE39C2F3EFDFA4BCA22EE74A3815DD3CF243C97EDBD5FB94763C73A37268D7DA392E8C12FEAB0E4E8F130C58706816DC6F9C786A5998A117B0D8EEBA94A12F7D72F7A5FEBC52674C555B349916DD44CF35D5083BBFB9E890FA3C26517FCA1842F8398B158745E1FA8986751755F5E +13B36106 +2C0D510EAF48D0FD7FCA39B43E07 +9AA71F5C9DB69DD99C72E4AAF8BA8D7918598298B969B36D607C7D4A9186C275F67F4B64F487CD13354400C389A30515F8E3DC8B7A19DD2A0281016F52269C5C2475FBAF061F2C7B563182E61381D6419B4F6FE4546818EE4D54A47AB7258472054FA6B4E5C7943BBBE930F3CD46093318A07A0F8C55A1BBA8119E050EB8 +0C48 +7A +A5A10279 +5BB2B98C633FA9E6E8602B0D2C +1E4F78F0714018263D0CC22DD21B9D62F4952AA50D33D66FF564BCFB33E5961C92F5003ACC3E60A4A38EAE59642F901EFC6A971A8610C92195FA31D67E66E9FF5F418E031809AE0E5F1147E3379E0DF90A2B21543447C0E32660CB02860CDBEFC6 +B049F89E +FB02AC76DF566732A076124A59 +410EF51828E37ACC2C2603C21742FD2AD2F5F5E0D41F8CACC9A58641A78C95EB0B35E27FDCBC0E4895BD8B0D81783EE95D8E7D2E2C0403EF9468B0690FE23AF35775B29FC05E657C0193750F4E893AB665BCA243276BCAB16C7862ED9761071BC726AA +A8884C88 +A32B8E140DE3AF8EE4842D158E88 +EE3F5909A5F83845761BC4AD9744142518E12B66B264460D6AE569BDF7536F080BDF84160F550076E091766C2E02852202C581A3AA644EF5124482CAFF0666E9F8746A24240151DD70DD05C222F4D3E875B0AEB113BCF40C5EC05F961081B693A1A6BA84F13A3825CB71A171620A8321CF76CC944B1E052FBEEFC8D7B462 +DBFCC725 +31BCC6CEFF22D48FCC3E3D6921 +2E49DF0503A9729952F5DB70286AB197D55F1120E47E9DCE3A27830C294A6A01767FA5C918872AD32D44A23ED1833C9F2E549A9710F589A1C1B748 +242EDBC0 +94A48B9B1F74BCE966E25A8AA3 +F115026A75458C637F9DD153D9E459C02D740EFD4D3C77AB3EAA42BE8E900B16C4E3545409BFD28032250F755077CB03D46B364AAF23EC81C19FB9073AC5E5B87E6EDF380BA446 +1F402EE0 +11C9389537EDC2E5ABF3FABDDB6C +50DF24850CFB9ECC77379E05066A0C4857D04111DC81DD1922A9C80FDA90820793596B9C8935038D2D6A2BD33C3FED158B8D112B9AB4F44554941F8E1514736F53658C65474ABA82A344338767603B4593133E2D0BABB73C27A2AC5F93D733FB0E002A34968744A56EA457B9E6F9A9 +93128566 +CDA591ECBDD333C1DB4B61BD20 +023FF06ACB4B4F24292D387B14E8720F206F89E90E40D4AC574BE80ACA9256725C3609899F27B3AB3886529C9400CC27F98246484C2AD17E1A4FEBDDF829F44E608EF461828D055A1CB4AD2E2837C3304C09BEE362455140A8C5D2D4 +8A84FC85 +03699F53D24F88BD69CEB33E58 +A669E704A353A3210FBB8983A92D453EE1CBDAF27BDEE66ACE293AC98BEBA0D803A504807B6DD51F0882A42F5C79110C9AABC41115FAD71757617647D7FDECA699F0631A1445F94A470D2D775EE0F3B376CDF0 +822DD23C +42E0CF2E0CC34CCAE4E2A5468249 +EBCC78274421B483478B6A9D64D3F015896E7C1683F4108A8C24CDCF02F09E35ADB409DFD861BCCD63CDD35A5AA7025761AD0B24501A230D829BAFFBC7CBDA7D7852D9B5CABFD051705D72C52CF77F9C99C3A445FA6C846735FBDD52A8140403360ECCD9B7AE26532B44 +3016A8AE +FA58F8158DA94E8CDAEEE3FBE028 +D514C87AD35D07368848419528A5E00CEE0B2832C1506AD4E0BCE946592084E5D7C7A862D5EE4153CAF64A81A29B469DC8701BF5706C9DBA1783731F8DED1F78757EA1B424670745BF600554212A4E8923F1EF1B565A7DF233482B7CDDCDA54F8B62FACC2935442FD981729CC2583EC8B43FECABC5378E78A41068192007 +1394 +15703E +E9006352 +7903994BBA6ED8E5C47FABD595 +9EB539EAF77E8524FC09D13E264FB84C7956083BD26C1721520368C5F223E4D8DB9265AC253E664A8D1946EB96141DC101D118DC61E2A19B69945ADA59EA1E40CA114C1846F680190146AB30BB71589D82 +16D11CFD +48E1B4FF68A3585DB6A619EA936D +0B6239F7B70C54C8B7682715E362EC34A83968B51ABEA0FCA473B692BB0F713C90B6922DCAC48EA2ECF489AC6107805A6CFF40DEBC92998748AB7A001130C26EE704A3EDDDC7CE4757A72B62B23491D2CA5BBEED4D71B5A0A24A969DE9B0DA9A00E95A1B381F730786DCCB66CC8EA57826A929 +83F93697 +9A02A8BA5AE7D88CAD559BAC06 +FE38E3D37E042854485D43916C3160FCD03D3CB337BEA57CC1ECE9591C78548DF5A66F7954F6034F4D79 +97B3BF7D +3844B9F7B1AAAE0357D3371153 +69B5CFD2C245C629CE2A63CAFECD51FED4C14ED3FE71D766DEACB06FB71975DF0DF7208BF4F781DD695AAEF0 +930059A3 +0C61BAD93B223CDFBCD955C2F3 +34AC79C63DA8433F8D29EF294E2A86E3DDF399882B78 +F0481E47 +60F66AFEEB4ADD5993327642EEAE +54372558431D3997DD320608A1C168AACDFEB75181D6D1112751043183948A217BBE40C98B49BC9E7E94DE21E0ABC1D745293381E28025F42D040E76C91FB8E5FE5CFB82708A59FEAB0FBCB76FB38782CC8DA07B6952CB78603206456E6CE3B2F55AEF913A12497B4CF9ECADA365BB165CA65FBCE7E2367C5E89669C86D2 +49E2 +AEC069 +2DFFEA6F +3CF19D30DB5A6CBCF41C45816B +9AC1146B9B0660CB689C5A7DE9CBD1C5FF8DF8B5FF006413182BF91E561B910D9F618B615939C2D6AD02D8EE69C734D62A33FE967DCE0A35FF387C1ECD36DDB23A33CDB030CC30715CE86379195762F24E60B74071D73FD7 +D71F2A97 +98CF93AF83BA415DF449157850 +C07ABAB328E66DB7501A5F4D2880B863DFDBDCB1282EAB69E571FFD2FD16F96B6FED35226AC070B9454097D037DA735661119EE27BA5DD1FE0356493EAECD6C8CAF408858142EC1B4E853F76E89B1D451B25 +B75CB111 +11D84500E4A4213F1FB0B88C188D +46282036561B4E1CE0BAC3C55EFDB4301B3BFC94EA5E7C7538E2E31DCE67301437BE98ABA69C6AFDF5086E1CD9D080B4B34F09D41D794B7F94CE83C4C99B07E9582D8755E98B333DCAADA10B3CDFD3A25B04E7ED4E303FFEC24622EA3030C2F9F9FDA3F7A873CE144815DBC3FB7C +4343AA1A +B7D195E397475A052BDEE41869 +26592E09688504D70866FFC781943443FE1BFE5811101FE1FC18ED7FB99495D75DE243554B24B8593DBA3FBACCBF09FEF8A4E30251505CCAED042C5526BA6EF82243650DD454BEC4ECED397BAA4FD87FCD57068F9A5C4B99BE +FAC8D2E3 +92DF721CE7053A5590C3636CC2 +8E812175AF2DC91E9054FEFFE2BFAD5D4BCF9720C5FE0B9ED3E791AA70AF0296B587E08291E123D63AA261FEBC4887922E7FBB983CB56ED7888031AF3E97C7AF6F4400CB59A11870CE2BCA9DAAAF08106F85BEA321A543403CBC6585 +AF282E55 +CBC5E7C82EB541558FEC8C4702F8 +9F660AD31EFE997BEC5EA7B72DA86882CF9CD454563F53FAFCA8017FDB2BD5D37041041F3A83456AD32039DA95773A482EE609C45377651497204E4EA7EFCA52DB1FE524E70F9710CA7C4B82100A3DFF6C99BAC0FB5F842765BCD03E85BD7E6DBC61D4AFEAC117235135BE5985D9F27D1CFD476C5FAF6485188CCA51E004 +8B4F +138DB50C63CCC8ADCF362E10480AD276EB5F1E6D046CCA341A7A8EDFAB9668F120590BD753C9E4F6088D0376F96A52 +DCD67355 +FC4255D2BEDE75AF942D74B47309 +4763770144FDB29A0BD55AD622B27D59E9E2CEBEAA28B397BA172A294E19C2B537D2B3C7D2A2BF977903EA5A5935F39361C26BAFFC92E78BDB08BB9938DCE1521A8E885CF0804F079EEA4CD70452EEFC5116DD5A2AF646A06B31D84970897AFF2D283C583BF525B1550F6FE4F6 +2B575B15 +73848ABD2E8DF30CEAA5424D24 +3AA8BC7E289D09794556851E2DB804B57C5EE12FD25E81CF5C7B527F1EE72EA69AD24ED0F5569F1EF79E51CB46F29E2ED6A5E2B482AD74BC1599599ACFC4BEAC49CDB95EE829AF07FC2A6C4FF68FA428 +D4D9ECD7 +CC6CFFBD18D097B0840F4DA405 +3549A93001F255823F9BCECF781AB9AD2F8EBB62A486B7C0A37CAFEADD58F8E4C6565E0C31E1F5BDAFC794C38D6E89C9253A62E28A1EA829C67F5374A627CFADBC8D6F114E2C3E1962855C82176E7E07055039B6A40439351D4E008AAF9ED089FF9518 +69D8404B +A43ED8B870DD4FDFD810581287CA +52C91C95EDD469FAB9CA255C283859CCF1B5855F356D5FA4EFF00EC384B7C790F761E51DC35A52544302337FA83ABBF6ED49A87A4B655C644B287A8FE83E586EC01D0D443FE9EB9B9C63346580A063B6CCB37E044338C054DD4355BB5928FB68ECD01BA1C8EC9C41EF8667B851CBDB275C019DBE7160EDEFE33F2DA77F46 +3132 +4BC0F35BA670F189C20B047CACA211DB59EF4A7815FDEB53072BB7C59DC0BF6603981A +85070EC3 +3A8C27F60E533F3048F64A0CA1 +C46310F4FFC6D16C435545FF57DDCCEAE8A8BC493CEA59AD8D29A89E856110AA47DD5219EE47CD8952ECC756F73B246DBFDD605EEB77 +3D754CF7 +CAA053979BE9B283172AE4860C36 +1B431507CF217E37BD98A774EBB5C44F1E75C7F55C667578112EC0C927054EE64CFE121F9ECC5010DEED0C9911692F3197B0416E8AE72677B43A61853E36D06A9F4713EAC5D4A82A23A5A6F4D8BB41D2D828D78D63D3EBC9F77B1D2AFB11E3A1729E081BF4A4F425981578DA9011FBCED8C63C3EE4669137DEF2E27CA40F +EF64 +0166E072C09215C399826954CA6446F87CDD9681517C7A38FF8CA923F8B513 +73E9FF70 +4BF348BE87EFA22E964A440CF952 +3D3BF23FC06137ACAE096EB3566C5786BD198EF86DBB09A23459A335D398B5BDD4B0BB3BD392BFE6DF63F1E5AE07C1AAA58CA74A71639E2E618C0D04274DE0521B0D1103D019128F9F5523FCC6C97D6B101EA43B2B3A5DF0AD12675A9073E6D097D2397B7EC16E0AB6CA8A54 +26E37360 +B108615DE4AEDC823AAC62D205 +1CCCC0A32914AE049ABA95E72610F38941EED847F9A38019359B1F3EB9F24074765633EEE04B4EF3D45EEB6440BF8AC219FC094AA054A262C3113F70B70DAC6B3A56FC7F0D8E +AF2A2878 +91ACD47BEB9962C1C6D6ED535A8E +130B46D35727BECB94ECE8A0804FC1058C0C851FC13C20D28324F78470D82EEBB453B0851CA23267F150A0B50DA36BB9E61383A28F64B3CD068E1B825BA6AE8969D68504DF4C0C7438D9428874DB1D51DB2FF91902FEA0DCD75A8F4F68FDC31D95B443E85CD5D24A27AACF4EE9FBACC5FB502BF88663AE +86C05CB8 +487ABFFB974F2ADF2058C75011 +0A03208A2BE754AB068961BA5964CA792DA44A29717676C4EC5838929C43F66AC9B181FA012DDAC6CD515AAAAD2CC12D3C6433707CC0E3715ECF2C423E65DC8CEBA99C508963FFD8DA896A1F4DB703FD802223C134E8BB +7E41CEBA +C9DB06D1F473C05AAC77A177E4C9 +6297767888F8F3AC6C5ABA02984F60695F789522183C8B57E2D3757069E7CDCA58DCC1E733CC6E05DFD1C06E15B84607F452541820C21550EA487BE7D470C8CF7EB78CC6F272409386136BF2F6C43D47F338DE0D4E891893916563FB5FF97766BA4355B86D0FF2FD6DA1DCF5BE18F8B36B9695EA4F902E378F4519D4 +3E0584A3 +9EE73DE08E77BC1A598FD8D9D5 +B7478A9AB2E4FD71B7BD3572CC071AA787DFC9C20B141A37B4CD787EDB6A139F9F388B9D196385F4663CFBD046B0BF83D762031B07588AAE598BAE76D631C549044A9D3F05 +054896B9 +487B20B917B7AF7219B228B69F +BCB0E5DD3A2D1EDFD6BBCA8D741D5AC408B950650E2C3F96B94A5BE120E7080F75248067089A4C53C6500F6DA98CAFDEE1DF0A6E34938FB4C3B770E91698A6ED4183E023E02590B101A6E877FC05C88368881E96ACE0FD7B55FB5A1D80EDB3EAC94F +5790A4B3 +7921B452857FEEAA782A7B748B +AD4C7AC5A0DBE231514CAC285906565720FF6C3307E8A9C82FB28B49B7BC0BD186C55C415E66DD6B20B8509FBB3EDC66505EFD4D9B64214BBB6FB016789C840DFBD94FFC2CAF4CE8BC08262FEB99A4025624BC6150647CA151 +A2C9AB5C +EFDF0F4004AB0E901C195CF85A18 +C47CC16DD89BA300FAA776C483C01BE9B645D70E035F243032B958A30AE86D1C5FB1088E80529FB1AD5824322B24DE1957A7BA8959A8452BF62517E9359C836D9AF153F32B337DF23CE167E4923C1850D4F5402B37D8E76C0F2769D297363CBBB7077C7560B534DB906F26F77584BB9C9294A8413B8A1E7B8DE991DD17EB +4E20 +EBFC3ECF7420035195150EE61A80 +A9CCC312 +7793438A539834C711BDF55B076E +157727BBF38FDE0E8B633D868F831B7BD38D0F98DA44E4E0DEAA57DFFAAA80EBFDBF97C815E0C0E32CBB688A1445F58E6703B1B9BEE7222685C82CEA16C5376CCE567FF123E4A5FC25D30C506E1A77B0C7FAD4790F7B566F98D2FCAB71BD7D2DD8048AC62BF201B9F0973E396454E88FAC0573604890487C4C8ABDADF43F +F4EB +38E05968636507D8E6DF64685DC4C98F1A2FD81E20C0C4AEC4 +E00FFBFB +51E4F898B26FB73C6A917DF82323 +22B09B23FEFB35949C930FF52D6D1A12EC22E3FFE74C1D6B2E378C36C6935B1B22973FDC7C568FDDECFE432702A123166CDC00DF4D14501E41A1ED73E0B59AEB07490069EF40CC0CFA9C246E37B39907BEB0FC6DBF5C8A5E230D272CDDBCD06D2E2CBF4BCDD38E8B721FDA2809474A1AC7575C1F88B25DD8DDD9D4FDEC55 +1B5B +32AB7916 +D45EAEF8A40E9FF3F1BF0A301E +C9F7A07D7643CFDA4017CCF97CCAF479EA3AAB273B185A20CF09C54A3389017CBD042CB4C5D609555FD7044E5F0D48CC47C4316848752AAC32950ABBE6B8F5 +1309C64F +40BF71B3C5602DE7D5D8330D96 +CD8F687E758B84B0B19B4E9BA78219DFB12ACBF178B242 +1460D86D +2B031F1ACB67C102E95F8B28BE16 +2717CB62ABD4C309FC2926DE7A32F76E47AA3C5456E16A77277E34706EE9E67C67660FD4866E154B4DFD5C4D180CD1B360B4171CB4E2C7C40FD9952402FF05654C2FF4DA8D3C6073D37A34C5AF2CD5A87768179DE47AA2FC93FBF778F36F760A766CF55CA0A7BC9324 +A0B57A85 +2D1A264C6406FE1A78ACB98941 +6E6AA9FABA5DC1BFFBBA843D79F1E8941D3FFBBA434D +FE98295D +2C486EAA2550B21011B1957F62A6 +53018E98205E6092 +02FB0BF0 +16BB5961627279393BD6222B232185F0480017BD67106DFBC6D63500FC985F87B50E +3687052DA428D23578FE8100C3F216EF1A54F8E59FEDF424096AA8FEDDB4A2EC052CCF07B663 +538895DD8E86333B66B21CDEAE927310DF9052CEF283720BC5CF7A +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +%Defining font PSOwstdutchb +%!FontType1-1.0: PSOwstdutchb +10 dict begin +/FontName /PSOwstdutchb def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001000 0 0 0.001000 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 1 /C0032 put +dup 2 /C0045 put +dup 3 /C0046 put +dup 4 /C0047 put +dup 5 /C0052 put +dup 6 /C0067 put +dup 7 /C0072 put +dup 8 /C0078 put +dup 9 /C0080 put +dup 10 /C0083 put +dup 11 /C0084 put +dup 12 /C0085 put +dup 13 /C0097 put +dup 14 /C0098 put +dup 15 /C0099 put +dup 16 /C0100 put +dup 17 /C0101 put +dup 18 /C0102 put +dup 19 /C0103 put +dup 20 /C0105 put +dup 21 /C0107 put +dup 22 /C0108 put +dup 23 /C0109 put +dup 24 /C0110 put +dup 25 /C0111 put +dup 26 /C0112 put +dup 27 /C0114 put +dup 28 /C0115 put +dup 29 /C0116 put +dup 30 /C0117 put +readonly def +/FontBBox [-18 -209 798 694] readonly def +currentdict end +currentfile eexec +D9D66F633B846A989B9974B0179FC6CC445BC7C8A959A39A32E9DCE7FAEF17EE3BEC9F +50E1A6FCA651FC4B3769A0A91041557502E25A5D6180FE25A3D11BF079E1DF66E54EE9B7C229AF891739707A2A0EC140306B5E43E52B79BFB89E459E50 +6EC6F610A70775A31C460976C4F79449D86E57ACE491E5C6BF20CC4307B1DAF7630252 +E9AF8CFB69B50EDAE9D36A6104AFEF8832F920FD2346B2C7104CD11E3BEE999CFA9F5A +49DB3173EE48D1C82994237F360407B022E0B4 +502E94EA8B493651EF2D03F0B513D655047568325B512AE6 +6AC6F53F3848CF70DE25481CC65D8B1A5793AA +3C4282D111112BEE28AFCA7A3808D4444C4669CA +84EAAAF989219F51AB3476A1B0B5F2246BC306E6 +625C6679C417ED2A8E9BD010DE37D40265074C2684274C264E5F45F0286BD1B23D26C34626E07A +5B039DB36C18005EE32CFA64 +906B285CB8BD7F0968 +D47F5242 +22DA29BB63EA29AC1293D9F365 +FDD092686CF0D739DAE7B4EBECDFE21B8B5810B15B35D7 +8B1BDB66 +02B6ED886A783C9F2E2959DACA +9F8C687CAC50F98DD3D99C91A3816894F5A2231814056F2805E451F66B5923 +79B434DB +F70638B9F2044F3ABEA1123528 +14FB6FABE370F6494A54BD1740E96D8698DF36DD8313B05B556E +E0432436 +DC00618FDC4E86C8E585E5476F +A451BBD97D0D36A62950246F56EB06F7323604EE93D45BF63CD3686365E9D16FFD6DC0A2479C876438EC2DF6F826AC5D6F952BF2D089252FD914 +E817E4A6 +611A1EFA8321BB9E6FC214505BE9 +4706322F616F6998B99A09CE79F5E89861C1BF8B3BAFFD07B37BB10E7F9010D88D8311563A7559BDAAA47227BFFD61711213423EB4AFF5706B152D44058C6AEF8E07B1B5469E73E5CBDBA089F1ECD1EF940CC4FF5F36E1A05DC2C2B51D70030D53B162ABA378A506 +C242E8AB +3A5D42595EF63C17836D3FA92BD4 +3CFFF6D00762818B8A58D405A0CA89F30107B58589373236005EEA99FF61F8B333DA73B493812328B7AA491A201D4444400A4EC40D21FD84BBB998BD070F42469709EE79963D13207BBE1170D31CE7525856CC356707944C6BE6F5FED8757F3792D300CED3DB92D64EA0C40B8F9CB1F75E2C7E791AE317 +38F37777 +45B72A2A485B66A8B7657E7B29 +1E803D14830190995B75101A72224242E42C1BE74BDE86C39755EBC2D27D18DAAFB31D642EAA1615CB4AA7FC1CC32A73DAF9096A8E98A8F93CACB28E1A174A9C5A5AF40CC23F9F691BD662F5390FD1E68EC560580358C3CC053AD58EDC15F2 +427849BB +09DA1233C68202151A7DE81CF88E +F1B4ABF13ACA44C4A13AD52B5DBA1E37AE3218D4DF272D3061DD3B262B06CC5116E5CF7D1149ED082CD390D9B3BC53E5B671995A7BB56B6ED250AD3C9C26FEFFFFBFD9B6FE6E9CE8EB87615365CA461A063B73365C99BB1FAE77E968734FEA40F983A948 +192CEF7A +02B1DDEBBE0B571E2E94D39EF436 +CBA30F8E718767F96F10B974437AF8190CBB730BC86CE2F34E85BD646DA73C0454F24768C0E000070621D6EBCBD3C3853B465ABB7725A286A31F43B4E73A0E101998DDF4E8336D56745A04E8552848F48910CC719031383C2D4625A255A8FA48D29D1B28EE3C8C9A3CA7DD82BD94D8E5AF19A40D41F82C5E76F380C97327 +A142 +3A058624 +5FCE37B7B758A8A15541320F1B +C615E42A809DB53D5F33D2289025613E3FE30E36D0C0A6DDA3F67B1E8B5F9ACD600157D16F64F423B42A412DC253DB8D632A6435E91BBD16C044D3F58F2CEA4D5D24BAC7AE510F2171 +4F6DD8B1 +1825B908842EC2711D95201FDE2D +2E1EA73434ECAEDEB63E5A0DCFDA800911E0C5D7D397BE9A4896BCFE344292C107A0756D9D469073AF483CB9658FF575C6885B2FA424CFB0B19468876D4450076AD7F12CAC1744E6F20093741C1056E42049D317F074F558ADF3EDE432D5369EE2272CE07348F5 +1F8076B6 +92CBD41BC59A8E090D55A6E26D52 +BEC23C214EC2CDD29DAE852F0710B8AD76F67055CB56E53BA639322ED7FC372640A9645CD63BEE031BA3E1CD92FF3DE8D798B60C7118B0B6B55776B429BA7DE2E66125D634A63E9052908FFF958C3714F32EFE9C3F21A211C501FDAFCAE353A2248CEB4DFAEB60A06F9AD5512B1A561349AFE22107E96B7791BB0B790E16 +F402 +6D9BD35F +9ECD20BB +B2A4346B396533FBF2D11D7F08 +293CDEB5B0D2168EB02F3C8EAA2C8B6D2327156F746362DDA637D3AB53B1EBDF64212874BF2B873FDBAFADA29CD55EF5C6497860B6421DE06604EE4DF6F37CD2C4EC5457C42D50E8DF62A0700E70D0B1CE4A79228D19BB62C48510650121 +7CB42BFF +09F5F31D44A2776204F6FDF3D9 +0D232B56DB2D5E1ED4185028E60BFE82E0A4316A93F4216EF296985EF5F72970081EAE5954353EAEB0A29EB723B48DFCC1B30ADA5DC4A5914319FADE438F659E859DAA18E84E48B07CF0504058EA64E05140 +E5608B5A +7FBC36D86D001111FA616A01AF6C +1A517F867166144D5BE1982F8F1CD2A1FA6B603496DA6E187E33201A4E1AE3E611DD882C6D75150096EAB897554035BD9CEE522D0776E8E2D2DAC7ACF54C1D2ECBACB2FFE3796E1E70C3017266819BE5029933C14A376B54848573C81994B99C003EFD2D2E170E30A4B7597D +4DA69958 +850DDCD4D613C816147376364B +AA5845DF3F9745F22AB1F2583F0D6E9BBD2916FF9AA73133B700C9BA292844EF768E6AADA0EC7029FF5A3B46F63CA7309AA0898739810607F1DE261D5E09E9BAB9B67A53640A092B05D0DADDDF139F838CC1CA44018FC10C8FA4B12B +61B62ED5 +5C039EAEA7A0515AFC10C69AD5 +034FC985CBD0472CBFC3775B683E422DF030EA13E908EB8C43F1EF29E80F9F11FAD3A25F5123BEE7D7F51CFD4A58131FAF0920101BCE759D3E63AE20F38E6220B1751A34D1298467E9A5CE38FAC208F32EB7AB37733B2E0B9F010043D6 +D995CF00 +4B71D5E1ECDAB646A8521E7C994D +1D49ECEC2107D49781F725EE7950BAEF322D2042F4376511FAE91E7AE0C98AB9849A63FD593AB5FEF0085946AE09F22A7AF167F3A2F4FEB99E89ABDDD6BD85E9D3F0CAE3825576B8CB044EBC93919920A109F94FA1A1080227C9585173CA9B5734DFCA3FADD6956687802A76838FBCB8111BA23992AC6346E58129C9615D +739A +D44CEA3942EBECF81D109FA12D334FF222AA3FC344BB56121D3272BC67D70136348EE3B701 +3C9A9A68 +B71B4AAEB99DEE834115A410AC +5AC35FCB9AFFD315C7B0F5C7BFE80368C2BEC984F380ED084A3C87D87ABC4D4035D0CB292EEFA2C054E52B51A98F2B069101826219B0A11FDE7A942D5F08C106FAD22D2D3CA9D5D27EAAC9FA9F23 +8DC6C542 +F3F955F664D04570B01695ED67AD +441581D70ACEB3BDA180F80158560DE563299392A62C0508D63343B902FDA4CA1042FC0BF6287F7349B304DAF009FF0DF6BE3E0A987BBDFD417033674B026357AFC0CFCE1629406EF9AEFB3BF7A4DCC07DF02D423124AA4C36F0CDBF390782DE81AF9871728071404335F4407C325EFBC4C1CAC499F2CA0602EEBFFFFA61 +ED89 +1176 +2CB8557E +27A537CD8AA259BD0210E592C5 +67EF824533C2A8329B034047617E96E38E39D68F8B8940CCADB644EC11A3ECB6F40FDB73F34CE875B87F3910F01157B995B75D74 +EA362400 +2D921E72CB06807F194AF802FECA +58D6E39ABD7D47423C6DD15028A4185BC1B0C2E9A8C4CA9B528AC90EB3B2FEC84D6F2367AD4E4F2680F2FB998B25A2A52EA7AE9DF453FB732BFD654F896D0CF9D39D41FCFD947814A8E52E70F286599E6FF182F4BC2BCCCDCD7694F1F63F269737875584A8185867E133A600FB99351A817F86053A6D5B0CD15C4B3B5424 +CACF +A46EAD4C7A7575125DA0177FAE750226CBB3FAFD92C9A9EFFB2B0767 +58DB71D7 +475ACD5099D3E676D51BE6369D13 +F15D202F294433C34933EC35CF6F1B0663C6F28B1961E0F98D6757204A6DA781AA3385F9206328513755901173F9EC50C7395FE3FF4BBBD657D82C390A26E73531E61FDA8A1262EF7C1AB117DD0E9F4D3C1B7C66A29A0BB5C4D4F3B3A2605F55319DFFA8BEF216 +68D40AD2 +B640C20E563627FB8A1BF07FCE +3AB280E399E92E96776DD31C307DDB2D71FA7C6E7ABB2A42B071F42057EE126556791CFC7A13DE0496C5523EA23324F02D17FA9331B72516ED3776D03CDD56357179E58C7E12 +885A093F +5D7B8B432767960B418AE9656321 +9F82D9EE01A69BBB879F3741B42E832EAF11F372D753E5A033BFD6A0DAEBD58F3D9895B47EE6AEF114EED33746E642AD28A12927B6B423DBC91637E3442FAA6ECAF23B80B4208B85BD4ED71DB7C73F8D2B0433179FA23CF283C37377EF27C91D48C8BB1E2532234AD3C83F70AEEF516D32 +390554DA +634C3E8A7073848FC1560B3DF5 +EE5FFD82C34F685E34CD6D98F24B2AED7793FDFB880DCEBB1BC110F154443E1E32E06A54DA368AB223D1D86A432E87ED587167FE33A5B3A0F430AA70465EA9C421165A196ABFBD2AC09733EC33AE03067DF1A9ACA3077E1E93 +CB520C74 +8CDE3648DFAF2373295346D5A01E +478B28ED79782ECA41907AD6BA7AE3BA0238BB5577B55B4BDC08CDE4B711A2BBFC3DC0732980DC3D373852796B2288B74001A1501C651C4F54A299AE80DECEBB6BABD81EA047A6C4A5EB82B1CF7B6F9E8A88D17CFB4622F71890080BF02837D9B48CEDEEB5C67ED5E96A917E3B6A6A4AC1E6BFF6D3065F14A9 +C4F04104 +65C3C0D26E0147B80F31DE743A +60BC0E0452D7BBADC347212A4BEF7CFFE7D18500EECB3EACCA2EE6538304FA8A0ABC34998CCD8358D1E40E0D48F058DEF2957509123C0268474505EB0CF052F46329CE18 +A49F8BD4 +05B61C43A5992E8B8F2B3F92EC +CD38463326732E7746D2E289FA3493D3208FAB4D3060FD57DC9CB23D3C181B5C5F6D120760346564FC7615420031EF70E8D061CCDB32B5305BCD79C639383717809852DCBCF657C62318F9D66E0DBA4AEFD645058EB9EF54361A48 +30000760 +658BC6F9B0DAF79A3FBE82BC332F +D121959302D9B794 +394040B0 +89A8CD1EFF20F28BAE5D6CF8107DBAE010A48FB1DA8D74D908ADB839D40031EE970D +09EFB60C034C53B178C9A32148DE08DC9D92D4F62C5A215E13D8449D7FC31EF2BD24CD59F143 +29139B90180EC17A32A308DD64D34AD5ABC2F21A4522CE8C01178C +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +%Defining font PSOwstdutchi +%!FontType1-1.0: PSOwstdutchi +10 dict begin +/FontName /PSOwstdutchi def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001000 0 0 0.001000 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 1 /C0032 put +dup 2 /C0084 put +dup 3 /C0095 put +dup 4 /C0097 put +dup 5 /C0099 put +dup 6 /C0101 put +dup 7 /C0103 put +dup 8 /C0104 put +dup 9 /C0105 put +dup 10 /C0108 put +dup 11 /C0109 put +dup 12 /C0110 put +dup 13 /C0111 put +dup 14 /C0112 put +dup 15 /C0114 put +dup 16 /C0115 put +dup 17 /C0116 put +dup 18 /C0117 put +dup 19 /C0118 put +dup 20 /C0122 put +dup 21 /C0262 put +readonly def +/FontBBox [-144 -236 757 728] readonly def +currentdict end +currentfile eexec +D9D66F633B846A989B9974B0179FC6CC445BC7C8A959A39A32E9DCE7FAEF17EE3BEC9F +50E1A6FCA651FC4B3769A0A91041557502E25A5D6180FE25A3D11BF079E1DF66E54EE9B7C229AF891739707A2A0EC140306B5E43E52B79BFB89E459E50 +6EC6F610A70775A31C460976C4F79449D86E57ACE491E5C6BF20CC4307B1DAF7630252 +E9AF8CFB69B50EDAE9D36A6104AFEF8832F920FD2346B2C7104CD11E3BEE999CFA9F5A +49DB3173EE48D1C82994237F360407B022E0B4 +502E94EA8B493651EF2D03F0B513D655047568325B512AE6 +6AC6F53F3848CF70DE25481CC65D8B1A5793AA +3C4282D111112BEE28AFCA7A3808D4444C4669CA +84EAAAF989219F51AB3476A1B0B5F2246BC306E6 +625C6679C417ED2A8E9BD010DE37D40265074C2684269D9C8B20E874214EF2F9A8F94F52343F51 +309DD617C1EAA0D4F0077664 +EC97FD2959FA884353 +65D72991 +687967341F5E8692E9A8818E4F0C +865FCD7835DB7916CA3B97F908AEF1A50A6D8F48C640A0AF5EA89087C802A46236C73640A88F269B33A3D6A7C297058606F3650A03FE30640CB27769AEABB9BAEC1A167B2A8C80260E858D8FECBD03EC12AC2BF162B3EFE345D9C6A4C1C0E3C21395E589F61E686749944B1D6C1E4A2B69 +1A28B6BE +5D23700A111B6EC800D742C3BC +581F463BB9AEA71F551284D83DA7786BB7718C2607E9 +86E53871 +3D7EB5282F630F7E1AD5A68A0C34 +96BCA7687EC8CC7DF8DEE6C9572616DECF606591FDD20D5F54200F9840943A22C08F61CB79F4CB64092566DA8D5AFB1ED272BA0D110D81713483C7E6189D989C37FF1A0D262D33AFE31A093A7BF76B39BE0F19DCFD0A986540AD48937995E66F97B29D55C8DFAAA2FA1C7E425AF73903F78AC51D463AABD74A0CB00F7F36 +3216 +A33EB4D05231E0A72D70A22A4A +3B93CF03 +1A71E3487D79E3F5F0214DC47D +57754E554F475EB224D703049C41982A97095095093268515B57545FC804774DE39D82B4167440852E7BB02F26EB2FE67F33C75DC7A1C6C4D54024BE4CDC48B2667AABB2E629BA8B8FFF277679EE12AF4ED0EBA84F2FFA0FADCEE20C9775147D +B73D63B4 +2052F48C509018C8BE70C6FCB236 +E69C385138790B45AD6AFA0824DDFD4279017104E2937F5551A69F4A0FF3862DFBE09D814233E2AE668B3521742FB1F471E3E025521857536352815969B156DCA2B3E0235217070FA5F5256D13849847E4975890A671EC9768D8B75AB059B04E3DA4EC6ED8 +4E4CB520 +3B30E43125929D518A92B4850BDD +181EB8A95F5AC2CB786B2B16FD4B8722080AF7AC3E71B75BC230600F65F203611556F142B4498618CD0816ACDFA5ECA071F3A477A06AEABF095AB5918F63367DD0FC0F7525D2133309F221FA2D38A056963807F35F961B976E6CBA44E106F581FA840B3FF7D2337FF01BD93C6E0CF0A324005B65E6A6A3FFD8DE1E8A7E9B +F801 +401070C474F333BD0D4944D4F4AD4CC4E3759D2B8EFE5AE92713B6D849F0EB29582E0C7A86F92EB146EA +CF66A898 +5A64BB30F7367AFD5C7D46D286CE +EFBB71E507D76FDB40EA74220E68953C74884D4AA57026E0943EBE4F0C76A413B3B312DEF8F2D87B384F649191C5A02E4FC06A39EA32FD58A675A64BA94BEBCC8BD58FB27331D409537B556C195E94AE5BD029F6FDEF0DC7F460DFD2ED1C5C20852259760229264D7E92593E7CFE9D0CC972605C9043868C231CC6FE7EB2 +C0C8 +A5139046AAE7A35E5AD537D4AA8B669F9E88F503462C6F1A42E9A1 +E5667982 +CFACA9A3BE160CAF739C47E91581 +D4CE0FB235CEB98DE32EB93E85B91D4F1CF69D345149CE5EF57D4978BD6B8815094735D8D4EB60A215D357B0BC106B94BD6CBBAFF2C88FCDE897A22003E63364664CA92F87F30534D67FFD9F332E22391F9967CA622A89AA5729DC2022687F173CA196746FDE139AF2C0DF51B4593545D339E1EC82D80F8494 +F65D8F0B +714E2DF3CFED33DF4BDA2F6F2B8D +BE85E4FF3FA2AA4991D31E9543D77D0822E77A120DC66E44F4ECF4FF083FB4D5B9B1B45BE9BE296B20F205E1A668C0EC5E27C91CCA59A8B0CD743726A8DCB11A168A532DB535A1D5A85A0876BC8E578EC9EB366AFD9773B02B84544C0DC6FBA82A88213343 +503E4BAD +DF046CB7893DAA78CBDE778162E5 +5A8533C82794DFEE2A00E7DA058856B0232D5B14AD22DA60120C17AA3F5438ED46EF221DC8E06A2F4010EB45B7EDE2FAC46D5D9B5A46C3F8B26D32CE4BC34AADC722877B43715E610E62210A5F505EDDBFE6889B9351CDC5AA18EBE7EAA4202BCE60F24493FEBA25985FA058B694FBCB484225AAF2A1C3E0DDF93CA96823 +6A4F +B35AF8D6B5436B05BEF53EE285EB94DCD4D35F236EA16BC2080787FEB6A7AFFE94E0104C9A3C6465861BD7EA0255ECA8DE2DBF26F87D9BFF3F45CC0724DEB6106DB3B04865A333EF4E55A6 +9AE159C1 +D01312DB2D43F4D7A31560C711A4 +0FE7FE50FEA4942C1F86B056EBC1DFA20F5A0B48E09AAFFCF6C2B5109E8E21587978A60EEC683648AFE4766139DFE9400EE45D3ECCA08840582490A8D6B0202EAE9F6083C79616C40F865582930D9D6DD31136AEFEDBC527F9599EF93DA2E35DDC49AF2B8556CEF9B3E9D122EE5A41A9A60612F28E33C48FD2B74153638D +F2FD +37B0972B237B1F6FF7BB5B24D3D89C1F7FA62BAF8D1B87070E +B1BB41C4 +6604E17D89CB003104610E4F73 +0DAF2F2DD49C11C0E14FFB8260AB3EF56862650337A69F71ADD3D81E7F531FA5115316E5D959BCECCEA5EE7B34D64306EF89D260D540B44DCD93B0A6F9FC455CF76267824746C413BAC9364C3003C5C7AB14EA334F49F460F9453DC84C4D8E +CDC5171E +5B8E0DCF83C2B00371224A7CB5AC +380B1B20F6DC42F7A9FCCC3D51584FF4CC41790E67BC10905ECDE102CF3E666269A7E82CFA5AFD3661217186AD26E30864F76463AA39FB506E81153A3EB6998AA7E282C09A3880DF589C4E561B94200BE22FEA24612DAC36F25A5E65577E7C362BD1A9891F27E7074908CF687CD1460664D601644473A4140145DE96F245 +48E6 +25D51E26E10D27727D990C6B63D290BB7BEBCDFA643DFB978E948B80B0566AFD7F2EC218B6F22F280C9E +C9270013 +25336E5F871E9AAD0A1A40B44A +D657AFF9180FDD23AB6AA4745DC9D0BE23FDE5D01FCDB96914C88E2DC8BAFD2C8EC8DEF8B91306C34DFC6E17987F07F07A42C1E93E852E4BD2B564EC9A4566025B33FDCDE550F72F0BD9A70B5AB1B470A67A6B066AEAB41956E8B2 +C19A656A +29CCB36BBDCEE4FDDA1B86696A7A +3DC4DBE072EA432077452920FB159913E9EF4C691C27760FC4D7A2A8F0E65377DA491B22F225299C0F2A24D015C42395697EE34E594BD1499A5101BA9A6E7B1F639F4F18E6D8CAC03E9259D2DD2EE722EE2B99B36B3346D6C62550A8C7BE1DB6B521D533A2EA3FE809518AD81D2EEA3D31908F8461B2 +16A6947D +9A9FFB66871688F93A3DFB5DA7 +A5A97407765EF2E8D0752650A8EF8F967467CA5D2A041C660D2FDD40FD955FC98D9B2364EDF1621B6EBB5AB4921FBD7055DDE4882ECC44235157CDC5065CE18826F1259B7952901BF2B0617545890F3BBCB052650CCFC8 +317E442D +99D01981FF20502C20AFCADD7621 +2A375956F76381F58980C56AC63D79A578CFBD1FB87B7BDE82CFA4AB2F57CE37D9AB2D39A58AA4247A30DC407217B916384F8E8E73C231B9F8622F89CA6FDD6B03E243569551707B55D520308BF2143FEC8DF53064F98479B5EBB87C51F84C1FBBCB38F8CFF84E89A12757B0257CC0A13355C90D9AA005431C58799FFF6B +2507 +AC0EB2068A17B0394CBBB02683CEFAF6F8A8A3B3B74960 +67D965F8 +AD144E6A6D58D2A07DB440F45F +C2E60732B0D2776ADFF802BAA5AF00950FD7CE1D49AB9DDC40E78654F78BB357232F1A85B1D05B0AD3C4D86BE06A8CF244D5954171C3F2F1336FC6505E2B5B1C2C6D854AB81F3F8D7D1B5486F020FFAAB6ADF1B0D6A7CEA91D20 +59C9D416 +5CBF0E491DCD738E2A88A5581957 +F2D88406D3D7116FCE5A7077FCA62650DAA71EAD71227EC5C7A68168B01BDF14E8D8C8DE5CFF56A32A8F17CA8A16C6F8EAC639405DC430B3D0BF5364A44CE07B04C638AFB8537170E6E509D08C505B0F5DE856EE0835BFE24CC736A6C0240DDDB3B7A988FEB6ADEB89251A7FD579855A2A5C13EA224FBDD714793E8FAFEC +EAE4 +E8F5991C2EDA83777E +835508CD +139BD56E373FB3B9D12CBFF670 +18A565B9D59ED0E38D7EC2834ECFEBD4ACCBCB6F63AF24EB +18E7BBF3 +54F6DD72D0F9AF61F421A75144E7 +0BEA368AB5517FE4 +1E132682 +F6D5208D287B74FD2A99F298EE4EAD8855E01AC938D225B01924D532EEEBC66EBA9A +1619C6D87F7A02D9E3B324F2F8DF310AB8F16DB146EDCAE361E740A6D57F82B137BF0EB5922A +B0FC86CD4927F977FB9AC95C137EA40E6E0A6E31028B82454B2CFD +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +%Defining font PSOsymclas +%!FontType1-1.0: PSOsymclas +10 dict begin +/FontName /PSOsymclas def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001000 0 0 0.001000 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 1 /C0069 put +readonly def +/FontBBox [106 45 775 713] readonly def +currentdict end +currentfile eexec +D9D66F633B846A989B9974B0179FC6CC445BC7C8A959A39A32E9DCE7FAEF17EE3BEC9F +50E1A6FCA651FC4B3769A0A91041557502E25A5D6180FE25A3D11BF079E1DF66E54EE9B7C229AF891739707A2A0EC140306B5E43E52B79BFB89E459E50 +6EC6F610A70775A31C460976C4F79449D86E57ACE491E5C6BF20CC4307B1DAF7630252 +E9AF8CFB69B50EDAE9D36A6104AFEF8832F920FD2346B2C7104CD11E3BEE999CFA9F5A +49DB3173EE48D1C82994237F360407B022E0B4 +502E94EA8B493651EF2D03F0B513D655047568325B512AE6 +6AC6F53F3848CF70DE25481CC65D8B1A5793AA +3C4282D111112BEE28AFCA7A3808D4444C4669CA +84EAAAF989219F51AB3476A1B0B5F2246BC306E6 +625C6679C417ED2A8E9BD010DE37D40265074C2684268F16195489648993B9C4D3B534FA887C +DEF605FA87B991F4D20A8F78DACE +5A54C070E03D5C59D9D2D3E06B09CEE028D68B62AB3AEC43C1DD20BA70D288597D9BD8E06818FF764EBAB436723988E8D7CA59E16D39032516BFC5D552ACDEEC6BE938BEF2F43CFFBC811C3626C4DF5F8CF080676520B51C60CEDAD1FE6C92D1431C702174CE517A8FA9377D075A0B6833DAB101DB65397F1419EF5F0016 +004F +6F0824F9657BB4F1C8F981709956865F6855EFAE +9242AD55 +91BBBEE163D844DDA894E13190C9 +2480439E4C71CADA +BD043A9B +A315CAF72652AA7FE6DB2E84D82A6111CE4DE90C02DA0AFFE2620922262A45AB4ED0 +EEC9F4520DD12703442F7D028D4526BD8B771E09FBE11B2749E2D3906894E8D4BFD3F379F14C +3C874F550606965E22FE487B247B5C2D06728490C8F2A3B588CDFC +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +/DPIx 1270 def /DPIy 1270 def +72 DPIx div 72 DPIy div neg scale +0 -13970 translate +1.00 1.00 scale +/wst:dutch12 12.00 /PSOwstdutch newFont def +/wst:dutch12b 12.00 /PSOwstdutchb newFont def +/wst:dutch12i 12.00 /PSOwstdutchi newFont def +/wst:dutch14b 14.00 /PSOwstdutchb newFont def +/wst:dutch10 10.00 /PSOwstdutch newFont def +/wst:dutch14 14.00 /PSOwstdutch newFont def +%%IncludeResource: font Helvetica +/wst:helvps10 10.00 /Helvetica /wst:helvps ILEncoding 0 declareNFont def +/sym:clas10 10.00 /PSOsymclas newFont def +%%EndPageSetup +GS +0 13978 10801 13978 10801 0 0 0 clp +wst:dutch14 SF +0.00 0.00 0.00 1.00 setcmykcolor +<192634312632270e01110112262f24292e22322c01273032011826223335322a2f28011926343730322c011b> 2207 558 0 7384 -1 s +<26322730322e222f2426> 7375 558 0 8593 -1 s +wst:dutch10 SF +<0d> 9434 13385 0 9522 -1 s +wst:helvps10 SF +<4e6574706572663a> 1322 13267 0 1949 -1 s +<205265766973696f6e20322e313b20436f7079726967687420> 1949 13267 4 3868 32 s +sym:clas10 SF +<01> 3868 13267 0 4019 -1 s +wst:helvps10 SF +<2031393933b131393935204865776c657474b15061636b61726420436f6d70616e79> 4019 13267 3 7133 32 s +wst:dutch14b SF +<0a110f1d141918> 1271 1458 0 2055 -1 s +<000503000c1c1418130008111d1a111b12001d190017110d1c1e1b11000e1e161500100d1d0d001d1b0d181c12111b001a111b12191b170d180f11> 2055 1458 9 8497 0 s +wst:dutch12 SF +<1d2926> 1271 2086 0 1631 -1 s +<002e3033340024302e2e302f00353326003027> 1631 2086 4 3504 0 s +<002f263431263227002a33002e26223335322a2f280023352d2c0025223422003432222f33272632003126322730322e222f242608001d292a33002a3300222d3330003226> 3504 2086 11 9461 0 s +<3d> 9461 2086 0 9531 -1 s +<272632322625> 1271 2330 0 1829 -1 s +<003430002233003c33343226222e02003032003c352f2a252a322624342a302f222d0033343226222e02003126322730322e222f24260800153333262f342a222d2d390600342926332600342633343300372a2d2d> 1829 2330 11 9531 0 s +<2e262233353226> 1271 2575 0 2038 -1 s +<00293037002722333400302f260033393334262e0024222f0033262f25002522342200343000222f303429263200222f2509303200293037002722333400342922340030342926320033393334262e0024222f> 2038 2575 16 9531 0 s +<322624262a3626> 1271 2820 0 1914 -1 s +<002a3408> 1914 2820 1 2147 0 s +wst:dutch12b SF +<0b0609000a1d1b110d170009> 1271 3307 2 2588 0 s +<111b12191b170d180f11> 2580 3307 0 3622 -1 s +wst:dutch12 SF +<1d2926> 1271 3729 0 1631 -1 s +<001d131b0033343226222e003126322730322e222f24260034263334002a33003429260025262722352d34003426333400343931260027303200342926002f263431263227003132302832222e08001d292600332a2e312d263334> 1631 3729 15 9531 0 s +<34263334> 1271 3974 0 1595 -1 s +<002a33003126322730322e262500233900262f3426322a2f28003429260024302e2e222f250e> 1595 3974 6 5219 0 s +wst:dutch12b SF +<04191a1d0418111d1a111b120418111d1a111b1200020700> 1398 4321 2 3626 0 s +wst:dutch12i SF +<0f060b0d1106080d1011> 3626 4321 0 4585 -1 s +wst:dutch12 SF +<37292a2429> 1271 4667 0 1797 -1 s +<00372a2d2d003126322730322e0022000b0a00332624302f250034263334002326343726262f00342926002d3024222d0033393334262e00222f25003429260033393334262e002a25262f342a272a262500233900> 1797 4667 16 9014 0 s +wst:dutch12i SF +<0f060b0d> 9014 4667 0 9461 -1 s +<15> 9461 4667 0 9531 -1 s +<1106080d1011> 1271 4912 0 1783 -1 s +wst:dutch12 SF +<08> 1783 4912 0 1836 -1 s +<001d2926003330242c2634002335272726323300302f00262a3429263200262f2500372a2d2d00232600332a3a2625002224243032252a2f28003430003429260033393334262e33030025262722352d3400222f2500222d2d> 1836 4912 16 9531 0 s +<1d131b> 1271 5157 0 1688 -1 s +<003031342a302f33000426082808001d131b21191a14151711> 1688 5157 3 4390 0 s +<1e0500372a2d2d002326002234003429262a320025262722352d3400332634342a2f283308> 4367 5157 6 7440 0 s +<1d> 1271 5504 0 1410 -1 s +<30> 1379 5504 0 1495 -1 s +<002233332a3334002a2f002e26223335322a2f28001d131b0033343226222e003126322730322e222f24260600343730> 1495 5504 7 5945 0 s +<003324322a313400272a2d26330022322600313230362a25262500372a342900342926002f263431263227> 5945 5504 7 9531 0 s +<252a3334322a2335342a302f08> 1271 5748 0 2375 -1 s +<001d292639> 2375 5748 1 2906 0 s +<0022322600> 2906 5748 2 3348 0 s +wst:dutch12i SF +<11050e0310110f06040b0310050f090e11> 3348 5748 0 4866 -1 s +wst:dutch12 SF +<00222f2500> 4866 5748 2 5354 0 s +wst:dutch12i SF +<11050e030f040c07060310050f090e11> 5354 5748 0 6766 -1 s +wst:dutch12 SF +<0800> 6766 5748 1 6894 0 s +wst:dutch12i SF +<02> 6894 5748 0 7027 -1 s +<050e0310110f06040b0310050f090e11> 7003 5748 0 8462 -1 s +wst:dutch12 SF +<00372a2d2d002a2f36302c26> 8462 5748 2 9531 0 s +<2f263431263227> 1271 5993 0 1933 -1 s +<002322332625> 1933 5993 1 2594 0 s +<00302f0034292600332634342a2f28003027003324322a3134003622322a22232d26330024302f3432302d2d2a2f28003330242c263400222f250033262f2500332a3a263308> 2594 5993 11 9531 0 s +wst:dutch12i SF +<02> 1271 6238 0 1404 -1 s +<050e030f040c07060310050f090e11> 1380 6238 0 2733 -1 s +wst:dutch12 SF +<00372a2d2d003126322730322e002200332a2e2a2d2232003326340030270034263334330600372a34290034292600252a27272632262f24260023262a2f280034292234003729263226> 2733 6238 13 9531 0 s +wst:dutch12i SF +<11050e0310110f06040b0310050f090e11> 1271 6483 0 2789 -1 s +wst:dutch12 SF +<00342633343300333126242a272a24002522342231302a2f34330600> 2789 6483 4 5068 0 s +wst:dutch12i SF +<11050e030f040c07060310050f090e11> 5068 6483 0 6480 -1 s +wst:dutch12 SF +<00372a2d2d003126322730322e0034263334330022340031302a2f343300372a34292a2f> 6480 6483 6 9531 0 s +<22> 1271 6728 0 1376 -1 s +<00333126242a272a26250032222f282608> 1376 6728 2 2847 0 s +<1627> 1271 7075 0 1422 -1 s +<00393035003730352d25002d2a2c26003430003126322730322e003426333433003034292632003429222f0034293033260025302f2600233900342926003324322a31343306003930350024222f002a2f36302c26002f263431263227> 1422 7075 17 9531 0 s +<2e222f35222d2d3908> 1271 7319 0 2151 -1 s +<001c302e2600302700342926003031342a302f330039303500372a2d2d002d2a2c262d390037222f340034300026383126322a2e262f3400372a3429002232260e> 2151 7319 12 7950 0 s +<0733> 1589 7666 0 1847 -1 s +wst:dutch12i SF +<10091406100e0605> 2033 7666 0 2712 -1 s +wst:dutch12 SF +<37292a2429> 3177 7666 0 3703 -1 s +<00372a2d2d0033263400342926002d3024222d0033262f2500222f2500322624262a3626003330242c26340023352727263200332a3a263300343000342926> 3703 7666 12 8895 0 s +<36222d3526043305> 3177 7911 0 3900 -1 s +<00333126242a272a262508001f14262722352d340e0033393334262e0025262722352d34003330242c26340023352727263200332a3a263320> 3900 7911 7 8806 0 s +<071c> 1589 8257 0 1882 -1 s +wst:dutch12i SF +<10091406100e0605> 2033 8257 0 2712 -1 s +wst:dutch12 SF +<37292a24290023262922362633002b353334002d2a2c260007330023353400273032003429260032262e3034260033393334262e> 3177 8257 9 7923 0 s +<072e> 1589 8604 0 1940 -1 s +wst:dutch12i SF +<13040a1206> 2033 8604 0 2495 -1 s +wst:dutch12 SF +<332634> 3177 8604 0 3432 -1 s +<00342926002d3024222d> 3432 8604 2 4234 0 s +<0033262f2500332a3a2600343000> 4234 8604 4 5335 0 s +wst:dutch12i SF +<13040a1206> 5335 8604 0 5797 -1 s +wst:dutch12 SF +<00233934263308001f14262722352d340e002d3024222d003330242c263400233527272632> 5797 8604 5 8895 0 s +<332a3a2620> 3177 8849 0 3582 -1 s +<0718> 1589 9195 0 1967 -1 s +wst:dutch12i SF +<13040a1206> 2033 9195 0 2495 -1 s +wst:dutch12 SF +<37292a2429> 3177 9195 0 3703 -1 s +<0023262922362633002d2a2c2600072e0600332634342a2f280034292600322624262a362600332a3a260027303200342926> 3703 9195 9 8180 0 s +<0032262e303426> 8180 9195 1 8895 0 s +<33393334262e08> 3177 9440 0 3835 -1 s +<001f14262722352d340e0032262e30342600322624262a3626003330242c26340023352727263200332a3a2620> 3835 9440 6 7801 0 s +<072d> 1589 9787 0 1824 -1 s +wst:dutch12i SF +<13040a1206> 2033 9787 0 2495 -1 s +wst:dutch12 SF +<332634> 3177 9787 0 3432 -1 s +<003429260034263334002d262f283429003430> 3432 9787 4 4966 0 s +wst:dutch12i SF +<0013040a1206> 4966 9787 1 5470 0 s +wst:dutch12 SF +<00332624302f2533003729262f0036222d3526002a330010000a00222f25003430003b> 5470 9787 9 8569 0 s +wst:dutch12i SF +<13040a> 8569 9787 0 8825 -1 s +<15> 8825 9787 0 8895 -1 s +<1206> 3177 10032 0 3383 -1 s +wst:dutch12 SF +<3b> 3383 10032 0 3489 -1 s +<002339342633003729262f0036222d3526002a33000f000a> 3489 10032 6 5652 0 s +<0714> 1589 10378 0 1937 -1 s +<33263400342926001d131b21191a14151711> 3177 10378 2 5304 0 s +<1e003031342a302f003430003432352600302f00233034290033393334262e33> 5281 10378 6 8240 0 s +<1d292a33> 1271 10725 0 1665 -1 s +<002a33002f303400220024302e312d263426002d2a3334003027003031342a302f3300342922340024222f00222727262434001d131b0033343226222e003126322730322e222f24260600233534002a340025302633002430362632> 1665 10725 17 9531 0 s +<3429303326> 1271 10970 0 1758 -1 s +<003031342a302f330034292234> 1758 10970 2 2867 0 s +<002232260035332625002e30333400302734262f0800110024302e312d263426002d2a3334003027002f263431263227003031342a302f330024222f002326002730352f25002a2f001c2624> 2867 10970 15 9461 0 s +<3d> 9461 10970 0 9531 -1 s +<342a302f> 1271 11215 0 1630 -1 s +<000c08> 1630 11215 1 1842 0 s +GR +eop +%%PageTrailer +%%PageResources: font Helvetica +%%PageProcessColors: Black +%%PageCustomColors: +%%Page: (10) 10 +%%PageResources: (atend) +%%PageProcessColors: (atend) +%%PageCustomColors: (atend) +%%BeginPageSetup +bop +%Defining font PSOwstdutch +%!FontType1-1.0: PSOwstdutch +10 dict begin +/FontName /PSOwstdutch def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001000 0 0 0.001000 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 1 /C0032 put +dup 2 /C0034 put +dup 3 /C0036 put +dup 4 /C0039 put +dup 5 /C0040 put +dup 6 /C0041 put +dup 7 /C0044 put +dup 8 /C0045 put +dup 9 /C0046 put +dup 10 /C0047 put +dup 11 /C0048 put +dup 12 /C0049 put +dup 13 /C0050 put +dup 14 /C0052 put +dup 15 /C0058 put +dup 16 /C0065 put +dup 17 /C0066 put +dup 18 /C0067 put +dup 19 /C0068 put +dup 20 /C0069 put +dup 21 /C0070 put +dup 22 /C0071 put +dup 23 /C0072 put +dup 24 /C0073 put +dup 25 /C0076 put +dup 26 /C0077 put +dup 27 /C0078 put +dup 28 /C0079 put +dup 29 /C0080 put +dup 30 /C0082 put +dup 31 /C0083 put +dup 32 /C0084 put +dup 33 /C0085 put +dup 34 /C0086 put +dup 35 /C0087 put +dup 36 /C0088 put +dup 37 /C0089 put +dup 38 /C0095 put +dup 39 /C0097 put +dup 40 /C0098 put +dup 41 /C0099 put +dup 42 /C0100 put +dup 43 /C0101 put +dup 44 /C0102 put +dup 45 /C0103 put +dup 46 /C0104 put +dup 47 /C0105 put +dup 48 /C0107 put +dup 49 /C0108 put +dup 50 /C0109 put +dup 51 /C0110 put +dup 52 /C0111 put +dup 53 /C0112 put +dup 54 /C0113 put +dup 55 /C0114 put +dup 56 /C0115 put +dup 57 /C0116 put +dup 58 /C0117 put +dup 59 /C0118 put +dup 60 /C0119 put +dup 61 /C0120 put +dup 62 /C0121 put +dup 63 /C0122 put +dup 64 /C0127 put +dup 65 /C0262 put +readonly def +/FontBBox [-25 -256 978 766] readonly def +currentdict end +currentfile eexec +D9D66F633B846A989B9974B0179FC6CC445BC7C8A959A39A32E9DCE7FAEF17EE3BEC9F +50E1A6FCA651FC4B3769A0A91041557502E25A5D6180FE25A3D11BF079E1DF66E54EE9B7C229AF891739707A2A0EC140306B5E43E52B79BFB89E459E50 +6EC6F610A70775A31C460976C4F79449D86E57ACE491E5C6BF20CC4307B1DAF7630252 +E9AF8CFB69B50EDAE9D36A6104AFEF8832F920FD2346B2C7104CD11E3BEE999CFA9F5A +49DB3173EE48D1C82994237F360407B022E0B4 +502E94EA8B493651EF2D03F0B513D655047568325B512AE6 +6AC6F53F3848CF70DE25481CC65D8B1A5793AA +3C4282D111112BEE28AFCA7A3808D4444C4669CA +84EAAAF989219F51AB3476A1B0B5F2246BC306E6 +625C6679C417ED2A8E9BD010DE37D40265074C26842243E0EC59344CEF369650A037B4383B03D6 +24C306E87EFDD4775EC78742 +FEFCE44B765574466C +D1AF7A82 +CFE19FEC07055171803BE35FB61F +DFA5A4C739A4E3957EB7C66233844AC51A6A91B45B75E6AF1F76779A4EA39D554C671F039F6EA0902EEABC13363BDDA5101CA12BB8156EEC5AF0BF9E6FFD41E3E8297895E1554F57314DE5E5E70C32DA47FD30A8525D7EE9C60607EDB6FD9F816BBA9417276F85 +60F5DDB4 +A3948B33ECD70515EFB0F25E7766 +23F737A06578D2C501971D21A1AD0DFB46CF5287869182444F411FF11823026670B907FF382665F39F94C09E0E1E76DC0B02A4BF09FB8F2E5BE909CD4C41833EB22E0FEA75A40D35D7700DE134E6C556D6A7CE512D6327F1F175C4A19C0F64AE61E00DCA03F8F5E64A5A235E5D73BAC487E3CEF5CEE4A4CDE1A68DBB5C77 +212D +08FBF8079BE5531B761799E3 +CAC71CE7 +915BC5DA0A2F9DE91351B1D86F +85C68C372290A0645AAB57F9B173E2F99B0E90B2916AD1498AEAC13F6B99790AA057294D2C0592BA131F35E37806812E2EABA27598DAD6AC +5EE52177 +55A0A46CA9D1C48CD503CD56EC +5D3671C90C70AC95D20ACA2B81472736DFA5A57B6735BA52094C35A893354B3EE27EDCE2117276D4FFC3539577CB3855CF0F576C4B331331E41B5772A260A808 +38CEFA48 +7E622ED9B5E19C6135B06E3DF0 +CA28D962CFF8C6A4DE27BC43303A8E9E7CBAA8002BA67708868A065CFFDD1FCD389B9AE937F905CDE2CB74D7D8C6B5E38EBAFFCDE5CA74CD5F37CACDF99673 +AA4AE3C5 +6F745CCF6BB1672083B4631B33 +64AFA54E00330DC3A83349D8D8D8EA3823D57D16D9D3A49E0488D1A46EDDC3D1E050F97B6884BDFE362B3C11CCD565AB192F1B4005BC8CCF57 +701C5608 +8778759B9A0168846AA041375A +2F3581805F1A9F503B2F895B8D60239B6B908E66F07DC9 +4C02FC6D +2446D184958E59BEFCD85907DF +F2849E4CFC4EF24387B04D098365E07CCD6F257B95BDDD1418D235050D067D +15798C1F +247CE56AB04CCAE9D3FA0040F7 +18517EB22B6A687796D8037C985D35EA284C02D42BBC344E758356BC +09ACA463 +69E8F4DA1C7C8A9AAEE9D26BFF +842E087583D169BC15B239D9E4D7F9C33D63F0449322FFFE87F2E3AC6FD22F1BC464936F5399E00B88509467675A8D6A285C298BCBD04831D7674130231E60F6ED4974489ECAAE3768B0 +EB33800B +9FD9439E55D1FE26D8837B5516 +50E889288A043D5E05A51B71247ECE82EFDB99ED181EB516AECDEFC183CB2E41E800206FBD643C2B9EC4378E4244E8F71FA7FB6B1515167289FAAF3A0EBA71 +EC219689 +C8479DF709F8FB80B75832107B +BECC4E11EFC5AD70E977E56A3798F4437DEEBE520BBCBE75C3A117E935D1695AA048AA9BC8B936D494FA770B0A5967D44DF79919936D9656B0C7511D2D9ECBD2AE62F55BCFCEA824D079D6983870CD66D249AA3E56CA77AB5C6D +ECCAAB5D +06E2A7A1917E53F9D242CD3B50 +2C8190F3198EABB139C2C7407782D9C09F3D972406F29C464C659A53DBEF0657D86DE8AA9838388D76B913997AA7C08EB20D3386AA94246A310F +1AA689BA +7F2CB750D4AB969DD5E9C9A6A5 +AE154E1F3AFCA25C2AE9270A68A82FFA44E22B3B8C4BACF4C8D0F1C3AF456F3B9D11C37F155AE20A8C5445140D81C127E429643F9BDA +190A5300 +C71B7221665C3F62F1BD6AE19091 +2DAC612F433C55BA67262A9324FA0E79C32301DADDB81D34ECFB6CBCF71DC34C4DECDEDCB3D74280BE831AB880E67FE4C0962191306E1DE87D51BE33046C0F583F98D67B977340284BD7ECC5EE38E78677D3A462A0C7BC169370E6163C204A6DAAAB66F8EC83520F22C86B754A198B279D0D41 +0151F9BD +37B1A6C0D8144583F041643758B7 +B210BC4EC4FD8F6AC14D1C2036189821A8987FD68E800D106189C782B8929F0CDFC178652E1CC76A4F11A84070EAFBD564F0214A38D66DA8BCE8A119235FA8A75930F252D37A2AF4D1288F1D09F531F0FAAE495C9A8D77DEA706F71AFDB8D27682E2BB50F6EC12A5D2F854BAC08767192EB3843346533D0BF012D8ED4426 +47C9 +96 +EEE7A625 +A028B677CDBA4CE51304741A6C +9845338FBF5F8B92BE31C4DAA334CB7492C1ECC58F9C3A769ADBFE8AAF5DCA81751C6ED29FDA5A471CB0885CD065E3E717F7C492D7D74D62CE912C393A88B544914E656A5435A0A0DDEDB699437FF7269F907121FEEB7082C01B011BC339CBEA29 +E3BB51B7 +FC6500419E7E27BF51945DD019 +7A2B910B6872F3CDF7399FDF661D62252410FFDBE95CA6F9FA368E7D3269B644D784BC8EA0BECADF125210AA4BB36A33F5414AE24C6A2DDB730F121F10130CE81B732D5DFD6EE936E1ED7AC8A3834E8AEDB64FA5E0850BF5D63F123A882ADE0C9FDDB8 +7A662A30 +F1EA984CABBBFDE45B11D2896B73 +C164C32D11FC09F71753E131EEA87BD36F451E452E1F0F56F984433F14039B43097F00EECE957DD7BF52DC541440C664234741EC066E9D3196F255C4B85CA5E3AB21D5ADEF9BBEB23F44352BAFC43E1FB29156B194A6E2DB64FD08B55E82736FFCC94FA9C10EDB2B8B0C9D824755944782D400F6E2B1210F7ACF35E5A5AE +1A490224 +BA3CD0F3A7BFAD1344AB01AF9AE5 +3F3EC9593AFD12C960F4FE5E75DDD86B177905891B95064AE6A9164FC49B522CA6E630220216BB07C28A9248342E0D070655325AE2D6868A96EFE22E08114BC216412C3C2F5FB5B596E8AAC921B41D2B77E6640B033766514BC43BC70D38ACC95CC06B32A5F5AFD441 +E6FAFB67 +D1EDA9439997E2FE0FAB6564A337 +1420EA9E1B505270768A0E97C65D246C3B6163A17E15777058166F44253B6F4EBCA64A9C741569790E751DFE75D41D91F6FF84B9BFEF2EF137C596C5D64C380DEB9765335721BFCD4B19A5A8FFBD70A46D4499726A1D303270DE0BA58F56820171A84927FF561E4965AFBB9AF6C7DE17AC8737F8C8994C71BA8D +96E04040 +D1BAB6FA1D76F261958D0591B0C9 +2761BC2071FC811D793EB87D6681218BE575342F9C614BAFA6306B16CD503A6A2B754FAB2CA1C5C355B476F5DDEF2525B7E2D63D9012AF9B46CD6C7EEA7A39C7C8CA0F0822BCA40E1FDFEE213943E53E99E32C068A9003D8401FC92AC830E4284248E64BF3CE813C93746B1FD24AA4247997D46AA3CE11639644609BA288 +C6D7 +4D7405FAC133E258B4B7A1 +4792C3D0 +7B8E09A02F2920FD4A93001729 +7841A20A2DA978129DA790D48C6F6C2EA162C82595B645717E2C670F6DF57FF06325B2E438D02790D8E1315B1E3E8564285DEEE3C40B7210525534 +8FE33008 +E5F1A300C676B1228795130A44 +E89C39D21E8445733BE30FD3FBA07D9F5A143B240E459CEE267B39D9AAA8C7505181F27A69BE359286F60D60508397CE9F687E09BF4720E33C89B89417254BDCE572D3D5D27CA4 +BA1164C0 +BBA3E2784C1AD84DB0CA0C68DF3D +CF39C650879BB559A34901F39CF4A5CC418910C321D27A64B86E9D4FC28627408EF398EB5CBEFF9A6EA6376CDE73F4E8A760232E91F3A939948BBA4B85F29579E9CA26E05C744AF09A1B4D25E49219BC8D7767421F79F813993C576C53CAF02AAB9A80427F90E595AEFA4E88FAB69F +946EDB57 +88A098DD42B5FB7033E749426F +A209CB1F255AA11EF0265B1F059CD6F5A37FC014CBC5045A9955912F7B5C84978EAB3D00234B220B212910D22F6267D03DEF9A781B8C4FC7696C80B0B91A75ACFD84CF92E9B2A54EFDF7519BB03CBC208223DF74DE599337B04B3886 +142CB8F8 +E05D381463B5AB02FF23002CEF +A1CB9EDEF1103A06B8D0AA9A0353B573B3CE53CC8DFA9296FDCA142FC399E6518B2B2A0A714A105ADDE1B3A92AB341D756197706A1A35946A57A130EFCF1B7B64BF0A57B1DDEA938B018F7A41404C0E0041AE8 +E1259A4C +5819200D8E8ECDD7617A54B51246 +3A86B16294B613BFD108264ACF21BF9AC78368ED15978CB6665CB3D641008A945A2A78AC9FFEEDE4AF62B82898FB4D64E292F0CDC1D9F6DC20F15862E137AB74EAFFEAB422A6A1172A7529E287DDC8C0F8CEB580525B80A926E36CC93CEC72F9E6D8AE43A165D2633E95 +6D720C3E +88C325F7628648E3D935FA09D383 +749CE7FBDAFA57FAEA3142B20711132AAEBF6B24BCE197A6B47C9189601AE71AE9B4B96F587EE7F7EA976FBF8C3ECCA7BE1DECC4EF0395F5796BE2441CFA2C4508AB843204BB4A735E2B085CD5DFCF5F4C6C2FCD1FB64E7844282BBC6F5965EC973B4454CD542DF8FD525BEE05C853C644B9D4903BBBA76CF4CFBF8020BB +EF71C2EA +475B01002585E6D65881192393C6 +82B739EBF8F2AF1E3CB45DBBC2B40DEF8CEBE9438EF88793D518BC81C116485979EF5CA388DD5F8253F4077D2F0DB4CD8A9EC3E1614BF7A46DD7A22947657A3C7B255323C105774883517B88140F801D0BC73525B5C1B25766B07505731D33E9929D28C26380D59242E6A4ACEF83BFAB8A88A55F7CAB00401F5C3EB5F44A +53E7 +3A69FD +ECCD4971 +6946AD95083893B9CC43465430 +1BF2589713CA0B95AC8F283E12D24EFACF915D6948F490C66380BAB1416818EEE8DC44846B049D5FF194361266C9FFBE3B7294164D3C2DAB366507DE3EC9C07125A9B45E0368A31D678EE77BB1558AE20A +0DCB6952 +2A20B9091DC1E14C700FDFB7D4AE +2DE1288FAE2ED29062A8A717D7242EC8811AFF21B3CA603E9A306215C0665DE21143435D741BA61D9C50DAEE3D3DE80FCFD41AC714A60B6B382906A24866D12BD1D0EF6A5A5CF728CBCF28519386F46531CABBB24F129FAD23AC329A9A36FE59A829839B +35E8A048 +9888D98B64B8AC3FC5DAF1AED8 +01D6239CE65A242CBB71FF323108A4EB20B15323D457A373042AA2438A3D8B59B349C3F89107D522B86EBD438FD6EAD9C1DDB3537BEEA0497E16B1E10ECC6058C198786117633A4EF03C8A6F75DB81808B7EEAC46501AFD531 +A7EA206C +058A58F35CFB0B3D3F9088CA821F +AB51B44488991E15BE16E1539DCD2357C288CF23C880F73F1AF65F98682F03D5A7C635ED87A8838F2607655EA75A4104FE5606482B56B25FBE44BA2CDAE012CC4F238E71CA14F077A8B7A8D95369DC21186BA8EAB0440D1AB3B05CD16E45BF1C2CC1492C431F2F4FEC6EBCF369B8CD0B35893B74B03EE3D0EF7D46525C67 +7A1F +457FE3EBED6B36E6D030570C29C32A2F +4BA50034 +18C8E8F4C67D42228B6DC7807A0C +B53E4329C81D828606118EB665B34C3DD5374AF74E55AF44F4629F7BFBE5534725945C32E3B42236433364D269FFDF2428002542663409B2709D1C7F0CE04B532DB04203E402F3EC3B11196F7C294E7CA3D0F888FB01A10CE4988BAE4B12BAC809271B801DC6D8BF776046D4931F62C9BC84EFBF878D885F97BB97B1F5AC +03E0 +50CB03E5B3CD7FC3A0717BDA4014C7523CA2FB3CFDAB466189B4A235A5BC6CB5F5D0864BDC0918 +AE354EE4 +F943A7859B4CA4E49693AD2B57A3 +5AA33B5B960AA0FA1C2EA737F1C5C8ECF93D34F7586040269C87109F42105B225517D08743392780283C969A97D4797931215A3D98A125404767021F96AA03C167B88E79B1A7B551FF5E2262B71C03F12134582B4E5FFA2732147BD31D44777B53D3E9905EA3DB7AA7D3C5AB683404595F8EB5 +34887BE0 +0697E084C1F035F82286B006A0 +1A109A8CA4418F86420301BDD45815890220388986C2 +75601633 +6B0C7C230D21E3865E3E5A3E7D8A +11C02F599B67E235F5A5C95328C5B67A7BE095A1ACF10F43A42748AEEC196F23566EF5E057CDF69C9E0F4547BA1A556F9F71D3B7DF0960B2E2B77F7085954606BDBD551C380CC43C493423F32AFB9293A9EDF1671C156D8171E1B806D050F5E093902141CA592210A21724B8F6B3E178AA16D6A6B85B71F68D7528E2FB20 +810D +9A8B86 +A3B7B5C0 +AE36F41BC1CA27F82D87A89E5F +2534B32DBA0B78B6E11983A035D7AC17F729E2349AF0170A42CCA1D7BA8F58C43EACEC0BE644C78CD8838202833D571456F35183DFAE40DAAEEC41A3524911B8672635F62DF22C1FD7A4648B889B6888A87F666E0F7CD038 +F9D7DB83 +32B733AD9FE209DB52D046D0C8 +BBE8B77A92EFA12C7040B53126C86B5D750C3DAB730C12948F9E694DD9C5227D55A9D937EB5F59E9788017D736A5B28CC41F4324BA50C0CEA81E74041C882B14FF70A90BC51CCF31FF95C3E5F209EF4B77B0 +A66DE145 +4BDFFC3797B5C833C33FF121144C +3038D3B44F673BA6E0214B7DA80CB0453190BE9CDED5DF52A59AF5247B69E248E756E47153DDE0E3E808988344234A08EF5903D27A90301FD4FC19E53A70C04FAB840221B5C3DCD8F2E08080665CA5BAFE5E0BE24F0E85059E7111B6398C7FDAF7F9B4212FDB262ED6B7AEFD31AD +15C328DF +B84B91A0B20C44A56CB3F7CEC1 +B38E56DAA15BF621990906FE0D3CE42E9469A7C399EA83353DE0FE95D603E4B909BE37B3F001055BDE05097A40D750EA1222565AB28F20CDBD3EF194836778A3046BE402CB8BCBA957312EC6D6D2623C31677C3468A01B38BE +6B6DAC90 +7A9C153D6DD694014B4A1E09D4 +671353EA7E1E6086911DB85E4F66864E78B145F9D6DD2A498A0D368166064B3193B6AACE3479563BA2B64F0535C3F582842DFC3E083B6178360D7FC3CBE22E18B34FF4ACEBABC7E125AB6777A3AB9ED11752A2C844128803550CC31E +A3FC4EA4 +474B727876432199F7E3C276E3A5 +117350E8E38E910A279E525900B3E7D32D0922F30C51C7780A5D97E1CDF955DF6F111EF552A90927AB5A650FF92803FA8BC2F033349FF64CC5A14013CF2F3E4B13E36DF6218EE9FDE85B0FDEDC3F8100B9EAAF69C2A8EC5B01D58A0820685DA463141F5757827FFFD3CCC92E072C78B7B8A8DD4D0E281E166DB66FDAA563 +FBB7 +36D18DEF5F073E4F3FC68AEA984EA01B904119CF6A5D83CC7F05EB22F327DADC90857DA166C1935B82CD6C098CCD9D +DEC3EFDB +BA4EEDF0BCC98460222CBF39D2C3 +956923C9760641DF11E73159B30634D60B743B375ACDB9B25512D7717D6C2A5E0E1443880952DE76BC87EE7E9DB636455010E7E516749D132205E7C174B3DCFB1860BACFB8F6B774155834AF2A178C520D2F915E02C3F7ECE6DDB503DB61C39517778F8E6389A5BA066CE50456 +21B553A9 +CE37863B6942D6299C29DDADA4 +13EE3589E5466BED40E9508493DDF9D77A3A153D7E5A59D5C4B38AEAA92A62C5A7472DBE061506137C719A0005AAA31E497D05D10AD0CB6AD726FB8BACA15F9C6A20DFB30191D59572BF08517F8F7114 +D03BDD5C +D319A8A3EB25263FEB104A87AB4C +ED4A8489813BE194DB96A9B908A0191D4F3982EF89FB477D3593195CDAD0951E4D2F894CB749401944C2E260BACDB248F76D5E525BBBEBB7D23B59EED9A7273227648EAA9373822670B3BAA2BA26E148F8113E24A713FE64BEA0078E6E5475ED40315B41C5D847CFC2AC88C665CD64D5F8F77E3FD227FBFD13F086223E94 +9350 +A2F3BF5A4878EC675B9CCC36A0BCDADF6337B0FF49E2D1CB4B21A7059DB4F568C798DE +7B120839 +2DA4E72A9F3F90044A4F73CF06 +6C2B9C5D62BC127A68CA8C1330216968A62BC5BD2DBE22106D2297779213DC297B260639FC66A3DE53CBA1BF7C19CE60FE1A077305C3 +03151A50 +4E3D35994081CC2A8C9800C1A59C +EF4C877047999687E87034B82358C5C23F9DE0744C3E01328B323FE2B78EE64E2F943E2A33352A7F81CA81CF47A511DFB06BD22F02723C53C4E757FC36A824A08D90EDBC8CFD3C564BE7E2F18877FE1D7BFBC404EF4BABE799348756640DE7A4A2D170AF96AD2A4437782AF9BEF1FB046C00479F6F77884270A70EE2686D +C797 +B41B889826C2A2185A240BD66280F19018910386939950336E3317D5E7868B +5C12F1F6 +2CE69113FCECCB57F272C3E93DD7 +3B6963AB5978C6F1BDAEEC3C30EFF58A42A649AF0E261BCE58F4298C1959FD882866E3BF9415D804F80B70879872083EB21A168BF3CBB8CF57B7BD94A05882D158746EAFB5326CAB2D64ED015920FA7F8C28A698F37AA50E36D8AC8455F3E51229F0314C28E450174DD68218 +7635BA74 +A52FF9364400F44C82DD7823FC +10CC77242DB96396AB68C85707F60F9F60BC82044C760221E5B22C41FAF16C57971D4E755B258B5609ED5524506A1679CEFB997D56C8BFE29F32EF0D0A6885D969387945578B +5C7851D6 +66E70DD9AFBBB382910B35CAD736 +32F8EE9793B926D2B94317C1B9AEBFC40BDA046772C6969D0FAF153560FC4984B862DD4E3F65AE030E9E9F4E8250C0B295832359E844E95E7946BFC36725E8E17CC2812E58BFF273F7F2033C8A398E8CA4BC86831A87F6D777A6E758ACA6DC9064E911476380F91490350095FBD02F1B7939CB5D4E5C4B +3E553328 +76BFD9FDAFE3318B44B6F8AD8635 +0958A9E7C08C2C1FFDA92661154416D4A2C2A449EC74E2BDD24D57AAF08D7A384C35B3B55C86D975B0F107AF6C08E8BEC88B406E2A5754385BC6E2DBD19E806473243B73475D0DE7097CB2B7CA7C18EA5C6F5332CA54D1A18F246F3B75E5AAD5A7A555A91C65D707C2AA +596A6E03 +3D82AAD93E90781B4470C92D72 +36CD1D193676C7E7EF38FAA27E720552F614AD56820B9696E19ABE5A1373CEC5289881130661BB9E3A2473C3520FE0F496587144FFCB3A794B9DEA3A0636BB81939F1A67FF2C74BAA075BD72647449822A742A821C5C50 +3804ECCD +8000D781537FCFDE742683DCEA90 +AC383E44E27A23B1DA6CA7CC608147911F403F42DA286046F11CA3AEB5A2B9DB58D1F476059D415DF4560514B09F04ED6471A5C45F9FCF41641F4DC48A8E32603298322B3C290EEEDDC2B93C96D205316240E90595E09E7DD70D2628E3AA93ABA94230208A1F6D87EB338E1BD22FFC7EA8B8193F6D4ACC5A1555A6C0 +74FCBCB4 +D2EB1EEEEE216B677B84E9FB3C +39EDD64DF27615C0A1E9ED8437D55A5C1A364A38B4AD268FEBAA7078056880CBD899F558EC05414B94736CACC5249C4F01E84BCAC6941053B61D6A78C472AD2C3AF7A20ADF +54E2DF93 +73B2B018B918728FAF2F967BCB +97046EA35745C06587AA69695E7E2772A60B4C76D1D113BAB15CEAFD2164F5C87E11811C8E3F895C93120C09091FB428DD49D89C264B64EBEFE21D3919D8690CA6E74E28B143E246EA2ADE36333F85BADE2E693720DCBFCE3FC5ED2C1363CE00FF81 +E1836375 +2653A6C4C6A72CEA24E33707E0 +68070B1F851B95C85E5C2A481D11DBACE64F348327675A133723995DF57FC7D099030115195804EB28125A35D6540CC0C495617FA47669B01A440ACF5369C09DCF48521CD023C80E524A07D11D7996699C178E839F3A211D4E +BDD24B02 +DFFB1599170E05AA62E3648BBD1E +BF369E76EF80B660FFDB0BC69C6D76604DAB67486AB676E07277F61F4B42BD61FA48720E8B89607C01F38AD738A869028CB4821EEDBDCC03D21FC7E1C6D0E9EF4948BD116F66DE483381361B05CBBF23E71F777745E8E14F1C025B765A4B379A3E19293BFFF545ED82B3180E935DDD191BDA90F51D0503482B76A6D5DBBE +6BB2 +96D20547B7B6C258394C6E44EE79 +C04E66D4 +DF17B157C1D01E964373DCC36BCD +73D1637A8FE43AADA930A87C173B9164BD8708276E87623265C6FED61AA8CA27A2FA98BE34445792B1A5D6D8ED6A382B117CA18C42A0F15238FAF8B095BD0D2AEC927D1871391F0F28F6C018269AC433CED843DE72240CC9A3CEAB92962069E253FF53C466B1DFF007C10C1D045B9C6B413C9A393578A4AD1149DDD73765 +756C +5FE348F7DD7A8EAB2381DB2DB27780D661E4AB2534D8CC635B +2A5764A4 +906A52C2CC1C4C881CA5B5A48059 +28907FDF35771381B5E1968022091EEFB86E7210A0C59BEE3061B7D16AE925073CF0177B00B9B1537C9BF69DCC0AA0926E68D9CDF97B7ABF05E73533EACF48545DBA5269B69651E8B592C837A140A68160EDB87A1E1F09FAEB2D572632162CF466B1291C2E6753DE0D6B2247DBE9238E842140C9B205181B2C358FA92A1B +3E19 +AFC369B2 +2AC5BD98F02A0272D892FD4781 +BDCC4EDEC24B966C70D10CD1A3B6F5B54CC2538275A48AD4C62C333BFA705FC5E26CB80A8351C0B80960A9BCFB9791A152A81A669E083D1777BE66C96937E0 +A2853478 +9431A3475D5827AD395D18692597 +1163B3545EEA6F3CEA8FFEB6DA79258E76ABDD67761F265B64431FBA1F52E1F0B1043D570B0DC6D0E81401CA3DB9964755221598E173B28FBFA4DEEEBD22B09F5B70B622122271D8632F6AF9847CE3F16FB9EE944BCB51F764D20A68EADFB84086B9A41D599364A96E +C9FE685A +EC2A7AD0DFA88E1E956E779A09 +F2EE7F662A5B154514693467F67D6A93261C8DF000A7 +EFCEE0AF +FA46F357BCAD57A679CF6F5AE4C4 +5D6027A522AB739B +30C4E4B6 +58732273BFB3888C1CA3A71137C613A5C2A3B23F2E2AEBD6E1EB915E8B45EC32DAA5 +74CBE1D273205BAFED1A4844E8C341E18412AA78C53CD1B610539FF71780211211A5E5807507 +0521F32EF3DBEAD715D9D9D893A222F459B887FD95966AFFD7BA7F +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +%Defining font PSOwstdutchb +%!FontType1-1.0: PSOwstdutchb +10 dict begin +/FontName /PSOwstdutchb def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001000 0 0 0.001000 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 1 /C0032 put +dup 2 /C0045 put +dup 3 /C0047 put +dup 4 /C0058 put +dup 5 /C0067 put +dup 6 /C0068 put +dup 7 /C0069 put +dup 8 /C0072 put +dup 9 /C0073 put +dup 10 /C0078 put +dup 11 /C0079 put +dup 12 /C0080 put +dup 13 /C0083 put +dup 14 /C0084 put +dup 15 /C0085 put +dup 16 /C0088 put +dup 17 /C0097 put +dup 18 /C0099 put +dup 19 /C0101 put +dup 20 /C0102 put +dup 21 /C0103 put +dup 22 /C0104 put +dup 23 /C0108 put +dup 24 /C0109 put +dup 25 /C0110 put +dup 26 /C0111 put +dup 27 /C0112 put +dup 28 /C0114 put +dup 29 /C0115 put +dup 30 /C0116 put +dup 31 /C0119 put +dup 32 /C0121 put +readonly def +/FontBBox [-18 -209 798 694] readonly def +currentdict end +currentfile eexec +D9D66F633B846A989B9974B0179FC6CC445BC7C8A959A39A32E9DCE7FAEF17EE3BEC9F +50E1A6FCA651FC4B3769A0A91041557502E25A5D6180FE25A3D11BF079E1DF66E54EE9B7C229AF891739707A2A0EC140306B5E43E52B79BFB89E459E50 +6EC6F610A70775A31C460976C4F79449D86E57ACE491E5C6BF20CC4307B1DAF7630252 +E9AF8CFB69B50EDAE9D36A6104AFEF8832F920FD2346B2C7104CD11E3BEE999CFA9F5A +49DB3173EE48D1C82994237F360407B022E0B4 +502E94EA8B493651EF2D03F0B513D655047568325B512AE6 +6AC6F53F3848CF70DE25481CC65D8B1A5793AA +3C4282D111112BEE28AFCA7A3808D4444C4669CA +84EAAAF989219F51AB3476A1B0B5F2246BC306E6 +625C6679C417ED2A8E9BD010DE37D40265074C2684274E833863450411E9158CE660E3A7F7EF77 +1D72660BA976700535161A71 +4F070388D3B5FF24B4 +C644E8A8 +D81F97790092FDBAD6359C2701 +51A55191DF57F16AA13D92E0E6E6077B697DF86BD99ADB +64AB09DF +CFFB28E9501E86053F3FB19266 +1D2DD29E8BED032540BF8836D351C39239B69C2D2FE4852342CD +2445C458 +175600262E6E851AC19A81BDB0 +82FA513410022E1236A2AD24B669007ED57D7798FD69AD75D19B8AE387CFB807311C5DE93C77C534613EB07D704BA8DA948023CA5577 +4719C416 +3723FB1F5477FD8644FB9C056045 +A0369FF72867CD351A48F33C336AF06DD61192A3DCEE32893D863F5566BA59861E0E770FCA23A92B2CCD145A189693FE0F55C236E513178FD44136F6D2827C5990772A0F1F7BFBE3E5E0932784F20F73238600D0958C816460FD0C1609FC24AC74301CB8446060C4 +3037DC3D +FB5F8A61DC710C3B2A8B318E8D +3296CFD6048B5D8319843165414E3DF89B9059BE62786B0472FB87A114DBDF85F985D07B30719906D91F0F404531B6F58F8E9FA249ED5D3C184C4DB32F6EA3B6D1A43040A819305F56337887C4E78BE6427AD9421F3233 +42A50EAF +4D56757645BF168A9457D42C8B38 +06FA0618A420BAF4A53D699825DF326359DF9FDF67C48F04E1F58A66D365875AAC4304A631E55672EC7214DAEC9F409E847EF2AC3CB111F8FCE1805BB7500595822E5ADAFB9F0DD644D9317B146DAF8D58B7C9A80249A66975AFDC06CBBDFDBA7488C9FFB13C7CF81DF6887A26DF +DB55850A +B9AF86B33BD680BCD2C8E5DAEDBD +08EDBCBC926B6A86119D555434C5B3067FD35694705597B65068DF4C770A8F4629B66ED35D1AF049DCF5DCC2A1503A244831152768E1B2711E7A011202E9DC3552E1688B21C3291DB71494E80AB4D6D4C98FCD914CFEDF67B41A16BD0C92BF6C2614C995DD33B4F040ED11275A1EC2865CFF2A59360493 +D31E1116 +9825805E981A18B705764D0020 +3C21F1D0C5635ABC0B8D68CF0AD9C526C98C4D564E00D9B1E100F3461508680FDDC2854FBE1BC333B4B65756120034F4492FBD9CE413867F5822FA4C691B +0188AE55 +9255B5561594CF2985DFFD5EBE +EF83D6966D4E5B9B7AFF1ABD6099EB680DC3EC6B7F362FE4BD78284702E124B170B5B68CA58B0B5279C850BFAEDBAEEE564BD302207F0B9F004B70E9BE30A9D07E53EBE7911DE6CA48ED2B3B223250A18CA16E7A20945FD5A43E9DD9AE642A +48884165 +4913C34314B12CF9A7C029A71A1B +F21301662FF081CD91409316895657C2EABD0F19768B00C8BE73257AFE337A7824B9B1EA273DC083AB76A7E46DA128758784A5EED4FADA6059018438E02C6FE1F5FD74BA9D6FD9931F04461D996C7DCA20E917137BA12766ECD60373315BC0360AD53D565C853D67F7 +C422309D +0E3DA9248CE6D0BF5223AB90EE57 +BC17191EDDF94CB1EC548D66DE4FFE2B9D9EB7F6BD2FC0A338045CBE8B6BC327F77042797E91318269CCCCABC62AB5B595ABC2605C38896B6AD246133548C347717272C4784A65F7ECDCD1C5099AC3ABED727A4A867B3318434CE0A3AF698D435E706169 +6537E224 +988398B5DF72D8E41106983A7CFD +19B9DB650BFD1226DC22178991AE0ABB2AE03891491124D11FFE46AF87DF9A796076D8E35A5546EC276F1234B0C317375481D1375FB118179C833873826404195BA0F579F12077C67D11B7AAB7B79D7899A69DE706841B2B8979B9FEB7C417307584EEDB644AC7A0A7B7CE223233E36BC8E304F6DA72819BC5A5A0DBD3D1 +F10E +CD7A03F2 +54C8722F3057B42AECC896C9E5 +0A85C1E6B025390590A7542676C4872C792A165EBE73059335806984A90692B89E685F5226DB6EE61C9D75956859AD06F0F8CA4A53F5929484AF5D99F6547AE1AA7D501874B9136CAB +835F35FD +0D2E1A57F278BCBBD1E4212BCB11 +5345D433475C2F849A89B2AFE46B325BEDC6432A86B3965DC3CF802E838FA8124DCAD0CE288C15F86D9DB4840A0EDF49F265D686C852E011EC24277C1AF0E25F8FDFAE0D292DC83AB018B1C15478477331C032421D25B03DBD686E8001581A6DBEA85C9878F033 +F6FE9700 +506D002EAB1C6C2617D462FE5B24 +916FFEE9ADAB2933EA6921CA152BDE18A6C5C29BF4C42CCAA8510CC13366EF5E05AF8CDE821A182F0A3570691FA01F74FFE76F0528DD30969DEB68BB86931A0A80B247E128519265C426C9B9E46B6DEEBC488C97A5AEF5ADB9B3372D284AA90537DA674A2320056DC2016C4EA2F3E15393103C52A9B318D950FE8AFC5CA2 +FC87 +7A74931121F64CB0FDC5C057485DB912BB7BA7C27665B4C2DBE06358347DE35074AB5F +077E4EDC +78DA03701E3CD3C11D1958BC51E2 +5FDEDE60520B7EC8A379702EEA002913364A17F8843AFC672172E6DF253999821DC8E042B371F9AE58260AA814CC020D9C0098D067C58E2185BA56FAD05701607878420C3543A268A5535128BA78332266DA81A5A7AB3C279105B609FD5F655409E2756919B615EBFA38928558E2E955C4CDDAFAF01F67B303F46232DF9D +1EE2 +5F73DE84 +D918D3FE +4274FCD623F2A473A357F1244C +6B5E423835D5486F6E7D9ACEAD698817666AE8087E400131D4104730512848F5EDBA5FCB3C93D3DF3A1272880D91FDA799DB7906ECFA1FB85EB583C5E117AD62FF5A4022DEB13C28E48B2F3F584407C19069 +EF9DA17B +7BBE8900C106D08833B8E5E2BC +EF8282AC137FC68E07FD556F3C481BBF01D06548800DBEAD093A5A942D2D1CD8B1D8E6999F79F19E1F68DFB899DA4610746D8DB8F3A7642CD0FA289F1E4307A61287AD0FB0A4457C42B00E1C8775A9E79AB2B817DEE989A030363A49 +3A63F7D3 +A9DBF6F94C6145FBBEC7C68077 +AEF5B994C3A2EB5F562CC5A26587EA255E0EBD60D60AF9430116D7CB17C29584D2B92F7F858BD0FBCA252A54663A8891BB6D05298CC59948512BCF28D9051A021A53CEC5B9049FB848CFC720968A2EAADDAE1DFFCF30DF1977273D7486 +F633660C +90AF573E4E7208D6EC6D2412BFB5 +783DB3C05DD2B98490A6AE6D687256193D3A2ED6D338F908155E0BCEA0317AFB1708B5EF49A4CEF8566776EB6B7E8A7CCA9B10AF6E7666BC00511D1CB12CD4C29B5769E624CF74ECEA52E12606EA9EBF843C52939A663C546FDEFC437B38DA7A3AD4084D5B2A6062B7EF4CCE3FDDFF7F948967EE5672ABC9DE0770979F6D +AE8B +24F5BFCC2D736E4C31ED9616442E47E0AA1C8F5ED65675D02009BCCDECE969681595E6524F +F8B3BA5C +335B57412A77D8B7A9F666E7D0E4 +EA7556A98A89CA99D1AA996E10FFE354EBFE37365E7188C179FD04C90E9EE09CE90D8F5B24DF1846DFA168F39EFB815F1F8A62649B1C17145C29E15ECD27AA11FB54189BDDC69848CF4F394AB1AA49EEA8BC376D3C363D7FEB547D9B07E8EAD1C18015E0EEE10956 +2E9A7076 +628AFF8B388FECEC36BB07679E +B2ABDE89F3FA778ACDCDF6C55680B418675FFEF7372392F5F196CEAC8E0DCBB4046099B4EE12A2E2B5882D615CB7F39C1A5C73AD +1AD34EA9 +ABCFD1B875F83DA09940F2328C58 +DC3A2E27E417E6DC3D7F31B23A76D03147FEF942E817BEBD938236852453882405805F355C881150B684C6F76609DAB4F1D43075F38E2BD30C597695903F30B9B872178411801E70E35E2EACC27F6B6887F219FE51B9AA82BB1647A51997F142F95CDB92A0E66FDE66EB768E1E2A2B80CD622105ABED6C3DDB914392897A +FAD8 +28BE4C5B567D8435E4ADF8EC9816217E64B2E053511477E670D3E9C0 +FBFFDA7C +A6033508B122075DF047C7882C84 +30F9530AE4CBBA65B9E3BB38E7AB05FC5A7AB6FBEDDB644B5A05DC49F1D2110F012B4B97B894070D5268D73CEFBB95A919EC3378AAE78965F6D93AD3794829DA492A66DC312CE44CAD490B2EE6468372C2775BEEEE037B65D7C03D8CFD060887D192D8017F2CFF +E192BF79 +8674B9E9A54E443FD54E84C65A +F8E73FD34760CE6A5C529B5C077CF9A6A35F7D8FFABBF3E46CD2022E3C29CD01A3B5837C60CAA6F5C437EBF99308456FD4EF7A7B540A0C1C008B4A259E33029345DAEAF75B0A +0AFCD2F7 +478CED3478EAD555065F9829376A +B867F43B815C5DEC83F0642392F3DBE0FA74DCF10915D2687ABFE565AC491130A095137088546DBF5B8A45BE1750C8824743439AB2AAB0C999232FFE45A367B792F0EC108BE1A0BFCB3B2E6170D1A4FCED662FC390E5B1A42B6F0269FB085CB159281F02F8F9A0A1089B95E77ED0838858 +D1C74211 +B62C91525C9A59D99A29B0275A +F422EB54DBF17F0148B7676622917B99B336FEC2B623EC31F2ED73A3F1498084CCA1E5640E41FE68A8CF9DAD1A5F0D8FD3347466374F8EBB549991A653E1C37A9D339657B14C9639A75FF46CA1710D40DE4D12771ED70FDEB5 +44351FEE +3F815824C1D6B92B47989AE9523A +A6DBBB52A2A379FD3F7CA9802EB51D47BA4062C9B2BEEC01A526D5954F4AFB84CD6395B99A047909DCE9B318145EEE2CD2BDABBA76655832E01D1E6EDE6EE9198502C8B81BEC104C9A4712759496C8167B23A37F8FE5B65C6F98B04ABA45039089C59AD13BCCDE2AEDA18394DCE034E008DCC660C26F692C9B +44BFEE83 +E6F8BA26EDE571EF7E3811FE1F +00D6221A9DFAF9C8B2817268EB110864529FA53F8CF7CBFBAD9ECB0D39484C1E00D4F305002F9E44E2579F78B73FA8330D8A1885F484952C5014D6BBA2C4FFA15370DBAC +386D62D0 +1D15DB492A062A1AA0C95F6D7C5A +DF691D4C66749962A47808D38783655A7B4E6E09D98DAE0012A5C141D6DD1771D07FD71A7C4E8B895CB44CEBE5D784B32D117BF08C5D6D14CF336ADD993BFAC50ABF41E50B2148A44D0C6A4C90CF24545CAD09CF6B719D1D44538E0801AFECA3C3C23FCF04FD918F6428227C37833E44C48C1F5404FDE20ED5AC7FDFE092 +0E6C +AE5B73F8C02D593B6193A9 +B3CB089C +8E18C1AB485C247BA34113EDB9EC +511D2259010AE6EA4B3018B1FD672AB2DD17F5194B287665D988769C5310ABD968C61365257369BA8E927B7BD36C2B257A4AA1CDBD7BB50ACB3E7DEC2357CABFE64F0655DDF20BEDA2F1EA57A5E990FD86977F93F3F9142B847BA042B7A8659B54B36BA5D57CDF00FBBD62F52AFB6D5135DDA59C04B15165BBB3E43461E3 +372A +9A +3BCF9C16 +F4F44F3D3BB8B01A8D348224D50B +111990D17497885D +1EBB045F +C3152258CDB5F6C604858B4A17EC96DA7F436B00EC016BEB0463821EA00F5959105E +5A426C7860262B76E4CA53074E84D52866CCEAD469AD3B6F02EFAB1E30B7A5685FA683F8D8B7 +68E0F1972BB819F7112F0396EB8EF2BBD05FE8F19DAD2C4815EDEF +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +%Defining font PSOwstdutchi +%!FontType1-1.0: PSOwstdutchi +10 dict begin +/FontName /PSOwstdutchi def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001000 0 0 0.001000 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 1 /C0095 put +dup 2 /C0097 put +dup 3 /C0099 put +dup 4 /C0100 put +dup 5 /C0101 put +dup 6 /C0104 put +dup 7 /C0105 put +dup 8 /C0109 put +dup 9 /C0110 put +dup 10 /C0111 put +dup 11 /C0112 put +dup 12 /C0114 put +dup 13 /C0115 put +dup 14 /C0116 put +dup 15 /C0117 put +dup 16 /C0118 put +dup 17 /C0262 put +readonly def +/FontBBox [-144 -236 757 723] readonly def +currentdict end +currentfile eexec +D9D66F633B846A989B9974B0179FC6CC445BC7C8A959A39A32E9DCE7FAEF17EE3BEC9F +50E1A6FCA651FC4B3769A0A91041557502E25A5D6180FE25A3D11BF079E1DF66E54EE9B7C229AF891739707A2A0EC140306B5E43E52B79BFB89E459E50 +6EC6F610A70775A31C460976C4F79449D86E57ACE491E5C6BF20CC4307B1DAF7630252 +E9AF8CFB69B50EDAE9D36A6104AFEF8832F920FD2346B2C7104CD11E3BEE999CFA9F5A +49DB3173EE48D1C82994237F360407B022E0B4 +502E94EA8B493651EF2D03F0B513D655047568325B512AE6 +6AC6F53F3848CF70DE25481CC65D8B1A5793AA +3C4282D111112BEE28AFCA7A3808D4444C4669CA +84EAAAF989219F51AB3476A1B0B5F2246BC306E6 +625C6679C417ED2A8E9BD010DE37D40265074C268425D895C799469DEE44BDFEEB38E2D389FF80 +DFCC1B0744CFCA300AF2A0805C +9B140D8C6BE5F7BE997FFC18B5D8E74EB9B2E9E81099 +3C76AB87 +C136A269C772A44727E1D0C0F7D8 +416730AFC14B87CB156ACE565EA322DC7FCBF0BDC357B396C634FCD60F82EB6E10227389D02F08CE0008A82E6ABE731BAED40925B1C752EC5BD698F30975F441EF78F36AFADC4E2DB3DB31B9E3B8B50968DABF502E232B2ADD06DECABCD55FFC95CAB40166A0757F6CA2CEC5A5445E033D019FACCE77D698F563C2AEED0E +BAB0 +F2D636695360F1EE0FB9E495B2 +184437C7 +C9DDDF7D327EE3FE0E6E0B528C +C121CED14A7B19669020101AEB5E9FD5C166EEC344517F3D86AB6CF0B47A7D9A59C36AB1B2E7547F2D7A3193CED7B99AAAAD62AC6779A44ACE7D7ADE9E82C0B6E9E6D144315BC4933343026580CB587B5320A40F30AEBCC75B0C8BFF78CFA4E1 +CCA2BB1D +395B5B1D8BF7C607F1A9B8C78E9E +CFDDDE7F37293625199AFA716B461E44AD5444EA2428CFF40E831562761240F4C614BDE11E15B8235CE2FAC0E30D4E262005A2DDDA945EE361CD664965B7AF5C4FFA2AF470F1347B6743C2BBFB4C1996F4B3DC5A1525B2F9A62769AD1EB62323CAC6B5CBAC8172E101D8F0357BD55AFB4083D0871C0696A587DA5CFB07BA +4DA9 +BF004AD54EB43D83FA4ED07B227CDF1379A4A60A7956383757D0B04D5FC87DC09ED74A6E84A442EA8DF3889419EE0CE2 +EF5EF316 +F71DDD9803AA92D65032CAFD866D +00AD8F5EF2F49382FD8F57F2099D546D710B27C9BF087D2D2A417698B13478D0B11BD19AA1A12C2870C24ABDCE9A540A1968B353124AA4EC91FC6C7AFEE859AEA5DE9CFAB4D5F0C160D6CEBAE1AD91F5D8AA424495AD8832897FADBE18F6D068A3A4355421 +D8BB6790 +3DB767D81464F80A96768F80764D +94FE8A7417A062A44CEAC156C4EBEC8E2B0279049AFFBBB2B925F93B3724A6034C54DB2A6278CA7A1734588AC83DF2CD568D9B361C6C60A7DB11E15A907F823E2100861204DC0C3632C3473CCA80A8D78AC0F72A005B7E020D468FC99B0D6928CDE6FB459B4489274B98C9E882C9339FCC17E203B5651E4DE24CA32A2B3E +5753 +21367C2F24348866C8340E93168189E4EDDE1B1381AE311FDC3C75 +933014C1 +ED5707175CC7384F5D5AF46B077F +00A027FFCECC13E674777ACB678F2F63822264065F5E5C00BF3F16084BA181274510C00E122B80ED295903D889823251A7BA5BC786AEBBD6AE44A3B7E52037821908997A036D09C1A888D2D9FAFC8A5881B203319AD4CF1717F59F9B0B71D4C6F16465DC81815C8887CC66B5530D5763F82FDE38100C96D321 +791447D7 +78D7C8575D4324C71FF68C5B690E +DF00F3FE451D2F31757BC8F6C355EC2F93D7AAAA542531827AC609F0FF2BA3A4124CDCCD263D12EB9CE5BCF7A68696FF764EE63DFE7A72EA565F795F291B1F940E27379832A0057972951651546155FB48F2797A30BBDBE6FF6F549BDEC22ED40EA39102CFE90DC3AE3B3F2506F50DA39004C770FEB5A8BD91D64CF261CB +7C47 +62DAEB29C560FD82FEC515BE98648A314E300AEBB5A22918A773D87304E842FFF041D96CF856585477F51E5C16C4A7E87FE0B0A18AE52146B0AC062B7323E9FB5FB752AF22E5BFA545464B +8E65DE52 +FC459018BDDA3CBD75903C235A59 +BC191B84CB566B0C00071EC02AC640F8F3466549B17C3CCBA34EF8A6C4D65D17688C795EB7133641A5D9988BF442670ABBE77D4D2F92AA03033A4DCDA31ACAA4E912DE700A4FC0872913DF3DD9D798F5112D880876410963D57710B76D14AF4A3AC979EF0220BAA548AC26030875101A2D544847B042EFF9903DA698F5E2 +704F +50A5D7B127406938C729E35DCA865ECD0F1D82499751DC923F +6EC1FA94 +81224B594D3180AD0161092DB8 +C5BFD39E77B0A75C12ADA096206F4346E603606FBD9C2FC00FAFEBCBCBEC3AFC2AED6EB719AC7C9C08FF0BD2DD1D685EDCA60A27EF834E56241E850AB260A6591F0A78767FD97422C4D75246C6113FEDEB6D68F0D6C9479BA9BC4F87408234 +53F0CCBB +7F622F348493476CBEA35F4894A7 +8BC7DCE5C9A19894F6F676EE28E0A2F02931FD3E37988EAD23A883325049CE17CD7950F9920637511B79026A562D2AB96F0A2601E46DA778C03BB021AB59DD288176D8275A264E49C80B7311DE5E0755DED53AA472D44350D866727D547E7A306C5CA5CE5D886D6DD89DFE6067F9194DFD6BEE5549C4BF16D11027BC0330 +6B4A +51F7099EF5F9B10677C92369F4E17A63BF45783E27E7E2CA96F1D7DE04723ADB55769C18EAB3A4A8729A +FED3D305 +B652A6C549FCF1322F8E51F67A +14B5B2C68B980E43608C53B385C5D8966C4F7DD5BC7BCF4C89EDAA76527875826C7DB0EEE5C13A272269EF9885E593EC2EF526EDD182E1CF4640BD81BD97F01F65D94ACF01AE146FE7FBFBE27C573ADD3E0183E4FEBBCD0C90666F +48A26CCF +A445B616311D4AB46CB6CEBDBC0C +99138A50847FBB379D694932146D252077CF668D5EDD10977FBAC43651C00A84148D22C497C3C526EE6ADC55861A588CDBE65E107D1F16713E03DB0A1318082D6F18AAAC4824AC8D8BFABD225EA1FD5FCCA4E24BB38CB2F466C303B0771B1A2931686F7526A041AFD84BD579FE87AC25D82ECB9C2161 +B1F20611 +27321BB1594F47C220A4362A89 +E46F7DC99E7B314FDA69FC46EAC02EAB6246C5B458966A765E535876488AA2F692B573787061716F5AECAE8E187265AB20743A3F591525EA01E045D97D28B14B64DBA4803805858DC9A1D33D3609B13285B605ACA51724 +935B262A +2B9B1648954ABEE24D7D6451A79F +4041BAF24ADAA1E3D5FB167B00AA55CCA63C3CEE71612EE6DC048E5D65766127BE526F36F6E2D0B1D72ADAA440399FA04BD7B4310EA924FADBB658668DBFE854D6F244947891E733BDBE450D2F3D9643F4EF3A4F8694C5E9FA119EF7DE49805941897E4A99EEBF61A95BA9CAE30B56CA37672A296CB9B84921046E399C2C +6C83 +B8EE4CBCC5881568BA5F01C8AA94F04FD2BCD3FB522C1A +27A4FFEC +1FF55FF705B3CBA6A29B9F49B4 +B605A6BB22041F6A1D5DD2E91271B7D62A52BD0A52F4BF0C8834920689522F2E8C1DC17E422783B26C345DACF1481F79C915C214547A28038FF5417657EA45CC39B0861FBB2F698A79B7569FAFD0DC5E53D0946C7852912C1A6B +D4B2DFA4 +C7A762848EE346342A897E24D2 +897D849A81559492B1B9F4053A075AA10A37A9DC9BBADDA4 +5FDE3B1E +F94BD3138B8160146A64E4BC3EF4 +F26630E038065A17 +F60B5652 +29BC17D3A4202C2FDDCD8655B4F94D33A85FE666753E2A5DCFE9312AB022F9C73D74 +C796978468A1BA845E2A2DDACAC05D94EEEE3DDD476D7B82F14299907EA94784D7C6F2F2007A +D3495ED1CCAFC209812ADB96C0FD089B5559F070954CF0C15ECA01 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +%Defining font PSOsymclas +%!FontType1-1.0: PSOsymclas +10 dict begin +/FontName /PSOsymclas def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001000 0 0 0.001000 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 1 /C0069 put +readonly def +/FontBBox [106 45 775 713] readonly def +currentdict end +currentfile eexec +D9D66F633B846A989B9974B0179FC6CC445BC7C8A959A39A32E9DCE7FAEF17EE3BEC9F +50E1A6FCA651FC4B3769A0A91041557502E25A5D6180FE25A3D11BF079E1DF66E54EE9B7C229AF891739707A2A0EC140306B5E43E52B79BFB89E459E50 +6EC6F610A70775A31C460976C4F79449D86E57ACE491E5C6BF20CC4307B1DAF7630252 +E9AF8CFB69B50EDAE9D36A6104AFEF8832F920FD2346B2C7104CD11E3BEE999CFA9F5A +49DB3173EE48D1C82994237F360407B022E0B4 +502E94EA8B493651EF2D03F0B513D655047568325B512AE6 +6AC6F53F3848CF70DE25481CC65D8B1A5793AA +3C4282D111112BEE28AFCA7A3808D4444C4669CA +84EAAAF989219F51AB3476A1B0B5F2246BC306E6 +625C6679C417ED2A8E9BD010DE37D40265074C2684268F16195489648993B9C4D3B534FA887C +DEF605FA87B991F4D20A8F78DACE +5A54C070E03D5C59D9D2D3E06B09CEE028D68B62AB3AEC43C1DD20BA70D288597D9BD8E06818FF764EBAB436723988E8D7CA59E16D39032516BFC5D552ACDEEC6BE938BEF2F43CFFBC811C3626C4DF5F8CF080676520B51C60CEDAD1FE6C92D1431C702174CE517A8FA9377D075A0B6833DAB101DB65397F1419EF5F0016 +004F +6F0824F9657BB4F1C8F981709956865F6855EFAE +9242AD55 +91BBBEE163D844DDA894E13190C9 +2480439E4C71CADA +BD043A9B +A315CAF72652AA7FE6DB2E84D82A6111CE4DE90C02DA0AFFE2620922262A45AB4ED0 +EEC9F4520DD12703442F7D028D4526BD8B771E09FBE11B2749E2D3906894E8D4BFD3F379F14C +3C874F550606965E22FE487B247B5C2D06728490C8F2A3B588CDFC +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +/DPIx 1270 def /DPIy 1270 def +72 DPIx div 72 DPIy div neg scale +0 -13970 translate +1.00 1.00 scale +/wst:dutch12 12.00 /PSOwstdutch newFont def +/wst:dutch12b 12.00 /PSOwstdutchb newFont def +/wst:dutch12i 12.00 /PSOwstdutchi newFont def +/wst:dutch10 10.00 /PSOwstdutch newFont def +/wst:dutch14 14.00 /PSOwstdutch newFont def +%%IncludeResource: font Helvetica +/wst:helvps10 10.00 /Helvetica /wst:helvps ILEncoding 0 declareNFont def +/sym:clas10 10.00 /PSOsymclas newFont def +%%EndPageSetup +GS +0 13978 10801 13978 10801 0 0 0 clp +wst:dutch14 SF +0.00 0.00 0.00 1.00 setcmykcolor +<1b2b39352b372c0f011001112b33292e32273730012c3437011a2b27383a372f332d011b2b393c343730011d> 2207 558 0 7384 -1 s +<2b372c3437322733292b> 7375 558 0 8593 -1 s +wst:dutch10 SF +<0c0b> 9346 13300 0 9522 -1 s +wst:helvps10 SF +<4e6574706572663a> 1322 13280 0 1949 -1 s +<205265766973696f6e20322e313b20436f7079726967687420> 1949 13280 4 3868 32 s +sym:clas10 SF +<01> 3868 13280 0 4019 -1 s +wst:helvps10 SF +<2031393933b131393935204865776c657474b15061636b61726420436f6d70616e79> 4019 13280 3 7133 32 s +wst:dutch12b SF +<100e09> 1271 1431 0 1636 -1 s +<000e050c000d1e1c131118000c> 1636 1431 3 3006 0 s +<131c141a1c1811191213> 2998 1431 0 4040 -1 s +wst:dutch12 SF +<202e2b> 1271 1797 0 1631 -1 s +<002420180020121d003839372b273200352b372c3437322733292b00392b383900363a2f392b00382f322f312737003934> 1631 1797 8 6099 0 s +<00392e2b0020121d261f201e14101a00392b3839090024201800372b363a2f372b38> 6099 1797 5 9531 0 s +<27> 1271 2042 0 1376 -1 s +<002a2b3b2f292b002c2f312b00282b0034352b332b2a000800273800392e2b002a2b3b2f292b002c2f312b002f3800353127292b2a002f33002a2f2c2c2b372b33390031342927392f343338003433002a2f2c2c2b372b333900383e38392b323807> 1376 2042 17 9531 0 s +<2f39> 1271 2287 0 1398 -1 s +<002d2b332b372731313e00323a383900282b0038352b292f2c2f2b2a0900202e2b00382f3235312b3839002420180020121d003839372b273200392b383900343300171d082124002f3800352b372c3437322b2a> 1398 2287 14 9531 0 s +<283e> 1271 2532 0 1479 -1 s +<002b33392b372f332d00392e2b002934323227332a0f> 1479 2532 3 3633 0 s +wst:dutch12b SF +<031a1b1e0319131e1b131c140319131e1b131c1400020800> 1398 2845 2 3626 0 s +wst:dutch12i SF +<0c05080a0e05060a0d0e> 3626 2845 0 4585 -1 s +wst:dutch12 SF +<00> 4585 2845 1 4638 0 s +wst:dutch12b SF +<021e> 4638 2845 0 4887 -1 s +wst:dutch12 SF +<002420182620121d261f201e14101a00> 4887 2845 2 6935 0 s +wst:dutch12b SF +<0202000210> 6935 2845 1 7668 0 s +wst:dutch12 SF +<000a2a2b3b0a2f332b392629343938> 7668 2845 1 8967 0 s +<3c2e2f292e> 1271 3159 0 1797 -1 s +<003c2f313100352b372c3437320027000c0b00382b2934332a00392b383900282b393c2b2b3300392e2b00313429273100383e38392b320027332a00392e2b00383e38392b32002f2a2b33392f2c2f2b2a00283e00> 1797 3159 16 9014 0 s +wst:dutch12i SF +<0c05080a> 9014 3159 0 9461 -1 s +<11> 9461 3159 0 9531 -1 s +<0e05060a0d0e> 1271 3404 0 1783 -1 s +wst:dutch12 SF +<09> 1783 3404 0 1836 -1 s +<00202e2b00383429302b3900283a2c2c2b3738003433002b2f392e2b37002b332a003c2f313100282b00382f3f2b2a0027292934372a2f332d00393400392e2b00383e38392b323804002a2b2c273a31390027332a00273131> 1836 3404 16 9531 0 s +<20121d> 1271 3649 0 1688 -1 s +<003435392f34333800052b092d090020121d261b1c13141910> 1688 3649 3 4390 0 s +<2506003c2f313100282b00273900392e2b2f37002a2b2c273a313900382b39392f332d3809> 4367 3649 6 7440 0 s +<202e2b> 1271 3963 0 1631 -1 s +<00392b38390035273727322b392b3738002c3437002733002420182620121d261f201e14101a00392b38390027372b00392e2b003827322b002738002c343700270020121d261f201e14101a> 1631 3963 13 9178 0 s +<00392b3839> 9178 3963 1 9531 0 s +<3c2f392e> 1271 4208 0 1657 -1 s +<00392e2b00272a2a2f392f343300342c0f> 1657 4208 3 3104 0 s +<0824> 1589 4522 0 1929 -1 s +wst:dutch12i SF +<0405100d0b0503> 2033 4522 0 2700 -1 s +wst:dutch12 SF +<382b3900392e2b0031342927310a372b3234392b00242018002a2b3b2f292b002c2f312b003327322b002c3734320000> 3177 4522 9 7525 0 s +wst:dutch12i SF +<0405100d0b0503> 7525 4522 0 8192 -1 s +wst:dutch12 SF +<09> 8192 4522 0 8245 -1 s +wst:dutch12b SF +<0f060c000d1e1c131118000c> 1271 4930 2 2617 0 s +<131c141a1c1811191213> 2609 4930 0 3651 -1 s +wst:dutch12 SF +<10> 1271 5296 0 1434 -1 s +<0021131d003839372b273200352b372c3437322733292b00392b3839002f38003b2b373e00382f322f31273700393400270020121d003839372b273200392b383909001c332b002a2f2c2c2b372b33292b002f3800392e2739> 1434 5296 16 9531 0 s +<392e2b> 1271 5541 0 1561 -1 s +<00382b332a> 1561 5541 1 2042 0 s +<00382f3f2b0029273333343900282b003127372d2b3700392e273300392e2b0038322731312b3700342c00392e2b0031342927310027332a00372b3234392b00383429302b3900283a2c2c2b3700382f3f2b3809> 2042 5541 15 9531 0 s +<232e2739> 1271 5786 0 1770 -1 s +<00392e2f3800322b273338002f3800392e2739003e343a00323a3839003227302b00292b3739272f3300392e2739003c2e2b33003e343a0038352b292f2c3e00392e2b000832003435392f343307003e343a003a382b> 1770 5786 17 9531 0 s +<27> 1271 6031 0 1376 -1 s +<003b27313a2b00392e2739002f3800312b383800392e2733003437002b363a273100393400392e2b00383429302b3900283a2c2c2b3700382f3f2b38000508380027332a00081f060900103138340700382f33292b00392e2b0021131d> 1376 6031 19 9531 0 s +<1f39372b2732> 1271 6275 0 1921 -1 s +<00392b3839002f380033343900392e2b002a2b2c273a313900392b38390700392e2b00083900> 1921 6275 9 4878 0 s +wst:dutch12i SF +<0e050d0e09020805> 4878 6275 0 5653 -1 s +wst:dutch12 SF +<003435392f343300323a383900282b0038352b292f2c2f2b2a07003c2f392e00392e2b00392b38393327322b> 5653 6275 7 9531 0 s +<382b39> 1271 6520 0 1526 -1 s +<0039340021131d261f201e14101a09001f3407002700382f3235312b0021131d003839372b273200392b3839002934323227332a00322f2d2e390031343430003834322b392e2f332d00312f302b> 1526 6520 13 9531 0 s +<392e2f380f> 1271 6765 0 1653 -1 s +<03> 1398 7079 0 1504 -1 s +wst:dutch12b SF +<00031a1b1e0319131e1b131c140319131e1b131c1400020800> 1504 7079 3 3785 0 s +wst:dutch12i SF +<0c05080a0e05060a0d0e> 3785 7079 0 4744 -1 s +wst:dutch12b SF +<00021e00> 4744 7079 2 5099 0 s +wst:dutch12 SF +<21131d261f201e14101a00080800> 5099 7079 2 7068 0 s +wst:dutch12b SF +<0218> 7068 7079 0 7420 -1 s +wst:dutch12 SF +<000c0b0d0e> 7420 7079 1 7897 0 s +<202e2b372b> 1271 7393 0 1817 -1 s +<002f380027003829372f3539003537343b2f2a2b2a00392e273900352b372c34373238003b27372f343a380021131d003839372b273200352b372c3437322733292b00392b38393809001839002f3800292731312b2a> 1817 7393 14 9531 0 s +wst:dutch12i SF +<0f040b010d0e0c050208010d030c070b0e> 1271 7638 0 2863 -1 s +wst:dutch12 SF +<09> 2863 7638 0 2916 -1 s +<001038003c2f392e0020121d003839372b273200352b372c3437322733292b07003e343a> 2916 7638 6 6390 0 s +<00292733003a382b00392e2b003829372f3539003537343b2f2a2b2a0700343700352b37> 6390 7638 7 9461 0 s +<41> 9461 7638 0 9531 -1 s +<2c343732> 1271 7883 0 1712 -1 s +<00392b383938003e343a37382b312c003934002d2b39002a27392735342f333938003334390029343b2b372b2a00283e00392e2b003829372f353909> 1712 7883 10 6844 0 s +wst:dutch12b SF +<0a0b0e07> 1271 8197 0 1866 -1 s +wst:dutch12 SF +<0f0021131d002f38002733003a33372b312f2728312b00353734393429343109001839002f38002f323534373927333900392e2739003e343a002b3d27322f332b00392e2b00372b383a313938002927372b2c3a31313e> 1866 8197 14 9531 0 s +<2738> 1271 8441 0 1457 -1 s +<00392e2b00372b353437392b2a00382b332a003727392b0029273300282b00323a292e002e2f2d2e2b3700392e273300392e2b002729393a273100372b292b2f3b2b003727392b090016372b2739002927372b00382e343a312a> 1457 8441 16 9531 0 s +<282b> 1271 8686 0 1489 -1 s +<003927302b33003c2e2b33> 1489 8686 2 2586 0 s +<00372b353437392f332d0021131d261f201e14101a00392b383900372b383a313938003934003227302b00383a372b00392e2b3e0027372b0033343900322f38312b272a2f332d09> 2586 8686 11 9531 0 s +<15> 1271 8931 0 1402 -1 s +<3437> 1394 8931 0 1591 -1 s +<002b3d273235312b070034332b00382e343a312a00> 1591 8931 4 3845 0 s +wst:dutch12b SF +<11171f11201d> 3845 8931 0 4449 -1 s +wst:dutch12 SF +<00372b35343739002834392e00382b332a0027332a00372b292b2f3b2b003727392b3800> 4449 8931 7 8152 0 s +wst:dutch12b SF +<1e1a15131e16131c> 8152 8931 0 8906 -1 s +wst:dutch12 SF +<002c34370027> 8906 8931 2 9531 0 s +<21131d261f201e14101a> 1271 9176 0 2780 -1 s +<00392b38390900182c003e343a0027372b002d342f332d00393400372b35343739002700382f332d312b00333a32282b3707003e343a00382e343a312a00372b3534373900392e2b00372b292b2f3b2b> 2780 9176 15 9531 0 s +<3727392b09> 1271 9421 0 1684 -1 s +wst:dutch12b SF +<0a0b0e07> 1271 9735 0 1866 -1 s +<04> 1870 9735 0 1928 -1 s +<00> 1928 9735 1 1981 0 s +wst:dutch12 SF +<00182c003e343a003c343a312a00312f302b00393400403527292b0200392e2b00382b332a003727392b00342c00392e2b0021131d261f201e14101a00392b38390700272a2a0027000813181b> 1981 9735 16 9461 0 s +<41> 9461 9735 0 9531 -1 s +<20141e> 1271 9980 0 1721 -1 s +<22> 1698 9980 0 1860 -1 s +<10191f> 1837 9980 0 2252 -1 s +<003934> 2252 9980 1 2480 0 s +<00392e2b003227302b2c2f312b07002a34002700403227302b0029312b2733020027332a00372b08293432352f312b090025> 2480 9980 9 7131 0 s +<343a0029273300392e2b33003a382b00392e2b0008280027332a> 7105 9980 6 9531 0 s +<083c> 1271 10225 0 1591 -1 s +<00002d3134282731003435392f34333800393400382b3900392e2b00283a37383900382f3f2b0005382b332a38060027332a003c272f3900392f322b0005322f31312f382b2934332a380600372b38352b29392f3b2b313e09> 1591 10225 14 9254 0 s +wst:dutch12b SF +<100e09000f060c000d1e1c131118000c> 1271 10633 3 3035 0 s +<131c141a1c1811191213> 3027 10633 0 4069 -1 s +wst:dutch12 SF +<202e2b> 1271 10999 0 1631 -1 s +<002420180021131d003839372b273200352b372c3437322733292b00392b383900363a2f392b00382f322f31273700393400392e2b0021131d261f201e14101a00392b3839090024201800372b363a2f372b38> 1631 10999 13 9531 0 s +<27> 1271 11244 0 1376 -1 s +<002a2b3b2f292b002c2f312b00282b0034352b332b2a0900103800392e2b002a2b3b2f292b002c2f312b002f3800353127292b2a002f33002a2f2c2c2b372b33390031342927392f343338003433002a2f2c2c2b372b333900383e38392b323807> 1376 11244 16 9531 0 s +<2f39> 1271 11489 0 1398 -1 s +<002d2b332b372731313e00323a383900282b0038352b292f2c2f2b2a0900202e2b00382f3235312b3839002420180021131d003839372b273200392b383900343300171d082124002f3800352b372c3437322b2a> 1398 11489 14 9531 0 s +<283e002b33392b372f332d00392e2b002934323227332a0f> 1271 11734 3 3633 0 s +wst:dutch12b SF +<031a1b1e0319131e1b131c140319131e1b131c1400020800> 1398 12047 2 3626 0 s +wst:dutch12i SF +<0c05080a0e05060a0d0e> 3626 12047 0 4585 -1 s +wst:dutch12 SF +<00> 4585 12047 1 4638 0 s +wst:dutch12b SF +<021e> 4638 12047 0 4887 -1 s +wst:dutch12 SF +<002420182621131d261f201e14101a00> 4887 12047 2 6991 0 s +wst:dutch12b SF +<0202000210> 6991 12047 1 7724 0 s +wst:dutch12 SF +<000a2a2b3b0a2f332b392629313938> 7724 12047 1 8965 0 s +<202e2b> 1271 12361 0 1631 -1 s +<00392b38390035273727322b392b3738> 1631 12361 2 3075 0 s +<002c3437002733002420182621131d261f201e14101a00392b38390027372b00392e2b003827322b002738002c343700270021131d261f201e14101a> 3075 12361 11 9531 0 s +<392b3839> 1271 12606 0 1595 -1 s +<003c2f392e00392e2b00272a2a2f392f343300342c0f> 1595 12606 4 3481 0 s +GR +eop +%%PageTrailer +%%PageResources: font Helvetica +%%PageProcessColors: Black +%%PageCustomColors: +%%Page: (11) 11 +%%PageResources: (atend) +%%PageProcessColors: (atend) +%%PageCustomColors: (atend) +%%BeginPageSetup +bop +%Defining font PSOwstdutch +%!FontType1-1.0: PSOwstdutch +10 dict begin +/FontName /PSOwstdutch def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001000 0 0 0.001000 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 1 /C0032 put +dup 2 /C0034 put +dup 3 /C0036 put +dup 4 /C0039 put +dup 5 /C0040 put +dup 6 /C0041 put +dup 7 /C0044 put +dup 8 /C0045 put +dup 9 /C0046 put +dup 10 /C0047 put +dup 11 /C0048 put +dup 12 /C0049 put +dup 13 /C0050 put +dup 14 /C0052 put +dup 15 /C0056 put +dup 16 /C0058 put +dup 17 /C0061 put +dup 18 /C0065 put +dup 19 /C0066 put +dup 20 /C0067 put +dup 21 /C0068 put +dup 22 /C0069 put +dup 23 /C0070 put +dup 24 /C0071 put +dup 25 /C0072 put +dup 26 /C0073 put +dup 27 /C0076 put +dup 28 /C0077 put +dup 29 /C0078 put +dup 30 /C0079 put +dup 31 /C0080 put +dup 32 /C0082 put +dup 33 /C0083 put +dup 34 /C0084 put +dup 35 /C0085 put +dup 36 /C0086 put +dup 37 /C0087 put +dup 38 /C0088 put +dup 39 /C0089 put +dup 40 /C0095 put +dup 41 /C0096 put +dup 42 /C0097 put +dup 43 /C0098 put +dup 44 /C0099 put +dup 45 /C0100 put +dup 46 /C0101 put +dup 47 /C0102 put +dup 48 /C0103 put +dup 49 /C0104 put +dup 50 /C0105 put +dup 51 /C0107 put +dup 52 /C0108 put +dup 53 /C0109 put +dup 54 /C0110 put +dup 55 /C0111 put +dup 56 /C0112 put +dup 57 /C0113 put +dup 58 /C0114 put +dup 59 /C0115 put +dup 60 /C0116 put +dup 61 /C0117 put +dup 62 /C0118 put +dup 63 /C0119 put +dup 64 /C0120 put +dup 65 /C0121 put +dup 66 /C0122 put +dup 67 /C0127 put +dup 68 /C0262 put +readonly def +/FontBBox [-25 -256 978 766] readonly def +currentdict end +currentfile eexec +D9D66F633B846A989B9974B0179FC6CC445BC7C8A959A39A32E9DCE7FAEF17EE3BEC9F +50E1A6FCA651FC4B3769A0A91041557502E25A5D6180FE25A3D11BF079E1DF66E54EE9B7C229AF891739707A2A0EC140306B5E43E52B79BFB89E459E50 +6EC6F610A70775A31C460976C4F79449D86E57ACE491E5C6BF20CC4307B1DAF7630252 +E9AF8CFB69B50EDAE9D36A6104AFEF8832F920FD2346B2C7104CD11E3BEE999CFA9F5A +49DB3173EE48D1C82994237F360407B022E0B4 +502E94EA8B493651EF2D03F0B513D655047568325B512AE6 +6AC6F53F3848CF70DE25481CC65D8B1A5793AA +3C4282D111112BEE28AFCA7A3808D4444C4669CA +84EAAAF989219F51AB3476A1B0B5F2246BC306E6 +625C6679C417ED2A8E9BD010DE37D40265074C2684224C22A511BD5CA25D46542453920A678147 +AFC21FA7F4F5862CF1709F6C +BF8C3ECCBFE4507DB5 +612E491F +087A12D0ADB82F28DA93FC23F52C +CEAF524940C77625947ABC17220384663B647815F94C97322EE3AA265BF180CAB3B718279AFE22F9CADE8CCD09858F70BA644F1412CDC6DAF6F810D2EA6C5020CD3D66D1E0DD45B76A301C06B1CF9602829F54913BF787A0A3F9310924D89F5C22CA6BB573DBEA +572C228A +9C7DD0944C14C69B096DD569B2BA +9FD4066A6C3EB0C1DC25D95A6534151F8A9FD134EFEA26B8187C562806A410905E736B8D8019D1FB69B014CB890B9EB8AD38313ED6E9C10951DC8FD973948C19BE876D023A27B869E12812F6570E725A3CA2060EDD650C8D68726F2A70C462833BE6F7649F5630E2BB887C26449D9E5704EDB56B8B774621B1AF0382726A +D913 +B78DADD91F8CECD2D5FFB19F +10BA8311 +F1E6DDF465A68FC27C95210E59 +D0EEA9C3F7B9BE534F9794B23D61D32921CCF1BC1B29FEBA7372FD295EB78762B3CE7C3B2FC857C75BCD4E2B741B0D97F1B51E3B20ACC674 +F2D05F6A +259BE50B405DF68AFBF6C2EA8F +4349C9D418EAD702BF3DD3C53FC64ACEE14342BBC9927943B46C72946CB9B5F1D625576A7E47A9778599C125F09AC64C7E1B1C5D8AFD549DDBCE95E01CAFAF14 +633096D5 +6B983FF8F3388E9D5B571280B3 +333419C6D2C1B983BE9C4DCBB47D12B8D450B047019E1449992548D741111DAE828F3FBB0E607699FC3C95CD3C8600CF78A619DADE7BEE204FF69E30E0828F +4E67A65C +4D0FB79C01D059DB24FE20D669 +E65AD7D48E9D71B8D22DD78DC8C43B462F15ABD8C66A71A4AADFD797D7C8CD58CD236CEB89671E8630B972842CE58E65AB2084E504FDEA8AAE +F1A6EB87 +AEFA15970876FFADE9A5424D24 +3AA8BC7E7B3D93AB90EB562AEBE477AE9B922190780DF7 +7FDFA0E0 +9A1B03E59B8488713805DA8960 +309A86FFB4A524FDED2544E268C129140108E8B536352C9B9E24A7A8A20537 +B146AFEC +A04708040E80E4500F9011D852 +6850A860E02A9A4F98A1533AE6D5FFB7A39CE3AF5098519791441F8A +97C66902 +DA3DB42B8C3E61700DD30285E1 +AB798394A9643DF575C93A1E4FA54AB50C92320777C16A8CEDD051E42C525A2F76D530263905794F79EAEC31F396AC731434484C111EBC74070049FB9D059E099B705ABF881C881B9F1C +4C8A40AB +A562EC813780CB87B0847516F9 +1852E1FA9A02DEB52E679702D335543ED1E3107A07D43B8C3DE3B96FF5263E145DEEDED8DB82C5E7B7DB8001A44C6495CB76559BB09275C1324E105EA437BF +D9578140 +6C68065100CE16DE9A4E4A3C20 +2A378409571E4F64F877494B238F57659DB50422F18074BB30939D414952A6E4FA22364393595A1F3DE826957204AAA662077B2F50C8E1E6CC7523FA81832CAB414AF2EA82AD03B2E05BD8EC9919E1D68E091FC2C80EFDBF6EFC +1F7141ED +9DD380E035AC549BCDAF2AB276 +75CA5228632AA4C18CACD9D7B9D3186719931C8E6652F80B56E5FFF9178C4800207F776343A84717380879654B075A37C7A1B2FA361859053C63 +F53C3D9A +D4DB70759D20505DBEE4D0134F6C +1FC758396CAE272B48CCFD1E4301FDA24B9127B9A110051D96F94374F44CA7556475D1AC6FFEEBAF9DE8EE3671785E04C8D4742D85B66D00E956A167AC2BF65C1286C0ADED0FBB45EFCD721C96A2B56360C5D23F64CE694ADA706AB4D81068C12B23FA1CCF66DD0B0AC13872879212C28C07DAB99465A91F6E24 +D40AEA92 +6313087BD870E17653B9A0FC60 +05FF40970C0EF3CFD79F0CA40DFE510884ACE03A89993D908100106BB78EBB2565DF34B9468884CC5E93A509C06B1FB2571BB618060E +A6CBAB5D +F3550CCC9B4D49D2C7D89269E8 +88FBA1E2A89F742DC47F4E8AD4B520D00BB697A655B3E48F8F3842BAC7385BC6E4D5E2A9 +0B34C5E6 +2AD680FD1BB8FF378228D96F2191 +AEB4D4EDFD1A53A6026262E97DB62D80879C21E10E0D8535EAB43EB51751104B5DDC01914FEB029BB9BE2CA4BA7961BF24025E5222795DD3346FBC7E2E9AEB359774D153399060B2BBB4C726E3F0C41DC373290B5FF2D6D8BD5BFB9A0196927670DB335CF54AD22032EB8FAA9513B8F9EDAF85 +A3CCCF42 +A721A4B44413824F70E0A4A7C3C2 +1E322AE66AB737CBD49F7056EDB835AFDE2DB88FF761CD1E486E61DFE54159DAA3AB414D98A8449C968BACB436779C372450013C41FF970B9A072846DF7D953B8869369CD1740135036DFE78575474CA37155DC7E912C6B40B853B21EAD6E53C1BC112F3B06D42928B97720664D783EC85ACB07ECFA2780C71FD249B831F +007D +B3 +1BE9F709 +7CF12A9F3E18593EE343E39A8E +59A9490D11AAC175567660FCCDBAB3E17A57BB1B36D6733D7C3299D0D7400751D0CE73C80F6507408E25F53821097BD3CF46BF0F437995A319B3A22B0248E9CAEC28033CD929D02F82807286C7C0B9430B308091416041B8D710E6256A1E0B19B4 +911B0AB7 +BD7B4165BB97313C464F81A557 +7BD4B25565736735F8977A153FF9FA79193A29BF97D137362B1E08D4A9E20FFCD5A470871BDB1AA41930523116C25261A91BD11BB8D6AEC58D4B96E3EEE188477E40581FB25C4D5CF4E73FA8F68D58C63A7C41280C8DFB514050B7DA693DB2A9F423DC +4147E3C6 +F6577012B9D355D083AB62C1D10B +EF7FE76C66A6C510711CDD6184F551886CFA21ED676F3EC981F06F10F64970785792BEBE3D21814881B6118083CE3C37D56EE3D7D5D9ED1163750762D0E442431DD922B46405E6E9627419879E720B6CBEBE227DE2D9B893010FD7AF9222EAF2FB73DA832D221EB70FBB938C65B32BC2989721FB5880D66A60FC3B7CA045 +DADEEC25 +FEE6A0D575CFDCE92050A47EBE4D +D5C1A4A7E87024DD605669DCB2D640D06748158EAA5551F7B0D814B0078D7287F04F840A4F0F8E891E04F7B66436D725249241DC51A4B17044D116A185E7EAFAC7288B31D9C3EB5BE2C32310EA7EA7C1B034EF7C5248563F915FFC19B51EA7424D28C759E3B5A97521 +B9701A5F +721731E630CD4DF5CC29655CE94E +0768F4E95EDA4F8D6B53C1AD50CDB87924630C1B528FDBA676C88B2D31828ACC320D33C642FBE3210D3CCCA29CDEC13963D344C4A3E130E34A9F7F586F24B2018977FD0E1FE4652C7EF24DBDFC5FC0F83746F4D198984BB396DBC015E13F36B01BAD0612B981081A7E8F7C50BE3D4FB591DFE8F85393A9AEA1D3 +44C97C9E +64C418DACB2AC03A08F023069DF8 +D162A2B4A853ED0593B0BC5191281C1EA6075F4D6FF6A2924F43B2950564952E9A2BF0CF4B8B41167FF29C7E7D128475D129BBABEA4BE39904D5BB9371266FEC47B4DD6F13C8F0DB1404F52A6DF4A4E402C3BF2B35B8A4B23D2742B9FE403DF7F196CAE9022C35E0FED8902B14D00100ED272E5681D3B1CFF387D1FFF928 +49EA +3AF0082C752658EEE29674 +A0776F25 +865856639D698145287502747D +6F4CA1BAD7A906A0DA2A11B77CD1E0B8397D294F743E47A28B0CBC5F67A765ACFDE0FB973665E8EEEDDF5926BA02B5792E9699BE3B993D6DF2596B +7B898778 +AEF14A224F92E546D094682B8F +F65D3F5920D163A66EBE93A75EF8C8E8A67A46C57DD41C82774473B3903D510D92F306D1CD4A9F0FE6F9069541AEE97478662CF5EFB25D15C78E2B3AF6DB8A269CA1207D8D178F +E0C7EC3E +E5361C7C6985905D779785A57F93 +83AA2357B07EE1AEE9BD3ED67EDF7D1907C6C0B994106DD916D72DB30FBCB3362AD147DEE232D22951FD3BF0C3B1E032B9008A1F6B2BA6F57EFC50B7C12B0CD22828A2AB2A0AAA36587CC221851F275D542E61FD52C2CEB6872CA89CDD78B3F530444A31A52D36C9A0FA232CABF350 +DCD515E1 +B0E1A004CB09BDD4E63458A43B +D42366D5DD5FB5F757000D45868A546998C7D4D03920B0C25C9DE9CB88899AE58C71446777AEF648C2D1447D4E7D01FAC5C03A5E9A25BACBC8B03D5F27A0A5B4242CE75F791E6E4F3CD84634DEEE6B90920E73BDF551BEF3DC5F4F63 +30F9B671 +10C937B9F0DA50365835043900 +CF3BC8D61229C78BF6CBE3A2D98F01A41E19D9D0B4A869A5769DC0B2A8D4E02F253BD623246AB0B4AF8FCF56686DBEA40905191DEA0A11DF5F96C45BA94AD6BBCEBAC85F6CF7E56A4838AC0985092CFA1E7FC9 +98BF2B42 +AD5FC44F6D9ACE98D57C8876AD95 +40ED7DAF9C2EF563BB4BBCF82C5747603A3D5AB77F0CA89FD2FAC5A8C995B28561A963C63240AEED50BA95EB76F950CF37048E9B28AC046CC6F5E8901421ECB0274BCE41802E82E2D504C2B1C5A59CB5C1FEB1ED3C295B8F44CC166EC43733CD7BA04F61A8C324713E81 +86A92843 +C2CF810B366E455E037545355991 +B4511E397C0DC5EDBA1AC61FEA75761F77849F899466D4188C924FF8B1297481A26CCC07DB730AF6D8A5F01505EE0C2A343E3479B8154A132A00F2FFF4A0EA17822C815D56587354FB0916D54A464F2C3C33EDCEE832CBFAED7E7E82FAC6803E08C3E4F2453B1328C402A873E688F6D7F71DBBA49860AFB826C71CB98B3A +CF150B8D +E3C5B1467EC43672C1EF84C85718 +6645C46757D4C30B7F10549EA09ADDB65705C45CCB6F5052FE5A012410B5A4DEFC35E825152090F4832988B43145F1E886D692ACAC939764C3C6B371A2A970E4DF7469D527F090621F69E9EA4F7C8A7DF5C9BAE1F0F977273A06F7DFDE33160FD4C575A2F0E05F25C902035EEE4F8268EAE7523A30231B09319A69ED8EF3 +5F24 +3A0619 +A72D9976 +A52DF6834639C5BC9CF103318B +37BD96C93C54B359D0F0F9B96C9954E742115BFB8A39E64D38E78BA2D78BE6EB1912AD0EBB5CCAAB03E95848B6EF8A367ACACA1CF5907477143D3D92D3957472CB839660CEF0D8037CE0F104A85463057B +0D02B95B +515B0BEF60B3A29AACF8DE1DA1C8 +62C9BDC30811332AC8B0A7445D41BD5190EDB9A053BCEA7B9C74EBA9B5339E48BD5F45CDC463B089619D9D219B8E14ECACF7505FA21DBF3F6234743D37430A4B656465B0E458CFE5961303E6C0703FD41E7B3C6BA0FB63505927B26CFFE7B2CD3E5DADBC +B86AA534 +3989BE1FCB061817849B7D6498 +A0F0C3556801361B26F19AFD63D88978C89FB32A55BA113F360A1F6BB98EC67D0BB185D2DB1DD2D5371F7EDF65E3C7E8875721583E83A55300A0A99AA009AE445B1D5247BD05E8E9E48A15C0BEAF51985966E48D31A3110981 +52403DB7 +DC2BEC2990B0594D6E7E539FB780 +27C7FCD0624832900AD3A57517BC03ED75A78D4E9C3B2279EA51D19F4F24151025EFC332673D90CAA50E0069C9B68E03E212281E07B39E83E0E67ED2C672275F5D58CFF1F519036882C82815B775FC41A6B9AEBC19504B6273B95C073176F91917D925B891E3B23062FEB019B50ED511656BF3828638617F068E7A58AF39 +67C3 +2445354A6B249FFEFF0FB59B0DCF6A59 +3035A617 +7A474AE9EB118A97F38DD85221D5 +F92139BD6D3B0F23CB78B0AD1BEC334BA6B917F9CE933E2DFD122B2CD8E34B8E76CF6ADFC64DE61BF9FD68E47F3F0BB111D30AE85667481714D7BCA7DD940E5AE12AA87B95FACC2685FD2F460D87C9A2D013588B3901154BB335F5D70362151ACEC8DECD6175E6212F6B84158D83102601728F57B218B4627F08F485D299 +5E01 +D1D71FCAE5197BC8AE893B88293FD619313DAF2D8EF1BC7C807F9ECAA8457321D12A3905D85D20 +3A319385 +CC5A17314EAA3947C6F036B7A36F +EBD489C076FFF58B58CCC16D4DB562761797E76326A66415BB7907B3CD176754D331A9C734B8F9EA2FB376544D9BF9F370B8DD4BBF0826B16159DB0F65177288D5F34F55A0E9C34F175AD85984E512F636814DE6373DDEF6BFD904C99BDF465EC87035A7535FF95A65A9B6116BE2DE2726BC1F +6C0791F7 +FA9E30710BC4825DE36C02C72E +13688BC58A86B886A2DD8CD8E35758288021D2E287C9 +E29F791B +E54D5A54DD3107F4D88247DE6E +D8D91F3255F1DC3EF0C2E9A529E7CCA047D7ACD40B48E527F67507009F73FEFCE76BA6D1C57CE0B4C4EF21BC5107DDD6D23C12E90D2CADBBE470 +77AF1919 +E4C8393D9DE22E27070C6E047F04 +3F4D780E29445A9B49FADD35821BC9D06A6310DBF7BA81D5FE7597D8B72C9084CDBB10B26003324268E9C07D16B2D41ED6E8E9A6963A35E90C1CA54CA28581ACC21C674550A92A6C873257029873A4DED8B6535A472BA2A12104CE042B2A73484EDECFF8597C249767A20BBAB523CBE089C8EE12BFA90BCEBA8E327ABF7A +E401 +711E4D +3E46657A +87F8E5B34CF64501C6E05C9289 +D4A14E9971C43359E2FCFD3980E1848C653D1BB1365A96AFCF742EFA4E632207CC81710B0C6E34B74336AA53CC0823199DE7C8CBB96C4BDC9396D18B49E23001BF48827249ADD98112393091D238E64BA1F8955C7A9D0F14 +E9108D9C +5375992B24E4FACE8C9D34331B +FA9C9A0811A6F784E3DED27DC75A46DC26EADD20C2921A9E2CD292B23C1A4BCEA3B8355322FA9C5DF9AE05632572A96E185501637C79CCF68CA79E157F4635536D83952DCF5E1649DEB63EC61BF5C9DA0A0A +1B78ECB1 +BBC7F4B7B9DEF904535DE93F2E2D +3DDB352291B707952CB6F6CB026DBE03907B54CE78D2654F7FEB3B12B4A84D07F5A685779CD06C454E3FA7D003FDAEBA69666305C0C6885C42F428C24398B032B700E6C822FEE693FD90C9091CF8ABC72D471FE8578AEA7799D80E2802255AAA654DC3BEF28C5F89D5F738C098B5 +547C5BD0 +AB0F0C3BD2FC4FD1B121E3F9CB +72B99D5BC9D383B06B8D5399ACCB62027BD689523D8270D19BF252DC5257A504D791EA2E6C5B7C783BC7386D36179BB908DCFEAB1BDE89B31925252CC3C21415E646CD4A5814266B5D56ED1AAD1C0E7B665CF520E63F4A7C77 +B6262708 +5F68A726099B497B9FF103318B +37BD96C9393A21C79C74B04375BE601FC2BF63FF9688AFFBE5E2B0BEDCFA12D80D9C2F190819DEE8D37D001CEFA71F17F0F739B07D54F901759C61EF003451A9FD6F5EDA89237D389ACE4A23AE343A8C7AE3DE065D3011BBF2F47D3F +75513A76 +3642FE6C977BA445B956BA0FDFF1 +E76B74CE667BE2B1079725B8679D397C17E7E4DE85B3CD0807CC1745CA2DC1CA5587594E7A132A54BFDDC6BF845DF689F0C4CE8F7663C664D724951F34CE5FD1C8AB4B202D311EE13FF4468BC2FB204380B46978EE899A2EC943BEFECB56F18A368688F4866915E5F84231A56ECBD86C19D93B79B31BB0A18249F609D420 +70A1 +D6DCC4DBB677F9688F4478D44B2CC68415EBB49FB211884FC33B3CDFDF48BA5D5BFA5B2FF3851F07FEA667CC70C27B +C95CF8F8 +4D6FEFCCB7D76A17F509B0CDD5AE +2CFCAF3A5AE671796DE4016EDB83A45FE468EEC0F8E804175C745F7F12D5372DA0EFB7BFD98072B7AD017D8999C5CE9F79C9018AAC55845FB4C7B355B784BA22F03379EE6D18BBC93A642600F618E10AA5654CE2B02EBD59EFE51B89AF2379369A33B056C7BF6D1512FBF3C8F0 +CBF2F282 +24F8C79EE2B0D40EF730A314B3 +E55EDA5ECED507F1672AA3C29D79C66DA8FCD30B5FD11DF79E28C663B1222EEE262D3372F742F3169E9C84CDD1A6AE1BD3319815359BF6BE06C56D5734569379A3EBB29F6CD6EA4C4839890CFA6C8413 +F5170E2E +9850A9747EDD3908BDCB52CF9919 +C19E97817C187CDB1752BB20AFAA3C004481A9FA83A9ADE07E83071258DBCF081CE196AD4FD06798AE366C8B8E68E7F994D789A4041097CF58D73C93782A3D235ACC9D9292E18FAD1D60883132A968A41123FD293A03D79E47AF8A9EC70028D93697EA3092B3DC9E466B37F6EE6021E92814D783FA77F9A287C9811860F5 +42A3 +C5A06234D5E174372C668353C9E703A1774C1AD5321073AE21E2DA56506CC821C37499 +BF571519 +0F3511B0B8EDC6D5DDDF3F3316 +02FE0FC1AC22E3BDB562BD2FB650995B83D9AB4A94220CDC4EE5CBEFE480BC85E67C20A5BEF48BE803C99C85123E558204766F841D53 +57BD4461 +D5252AA6DEBA50DA84F315EED28A +636809D153D23E318D75F845BBFEBF0E58331462AF77471A10603A7F5ADF393ACCACC68DCF5EC32C7DC85B461D0CB6FC35CE1A5FE4A0632FFA72B4A8DD45E27486F08D4C5884558AE739F5ECC805DF8BC730277BF49A48D5ADC54FC6166E700B5540447E3F90B77B0DA98BFC59C9325F85286236B4B3B7A8B4E68D445AA3 +FE1A +A4B9C4079578907F36298FB6FF840593684C833CC273CB1DE34A5AAF9CCE34 +A7637627 +759A2C7A2896E3DA462DAE333DA3 +792EE6F902B7EC8B67E65EB4DFEC5C071F5F4874611DCCCE3176DEF28AFC415DB392A631B889CDB03CCED8804D8178E10954458167D3F69271131FCA9237DE888DD50A2DD2CB7C9F697C602424C83EBD03F61DF06714BF80FCB14B78370D0F5ECB669DC240AB1345D22097CC +0C24D58A +3B7467624EC90A324719E0EF17 +2C72ADE93EBB1BC4426B88776282A98DB08371A75ABB51EB0EA07F44183275CDE8940655302FD25F9972C5C887FD8BB8F474D98A11F34A5E16DAD8565FF647943640694BF4F1 +196E32BC +BA4502C310BC29E633AE79C60649 +618BE2D92FBA92DB8F55FA402B81B9CCC93DB07C19A3E588881494BDD251ADCA0C23F0310F76D741CF356EF6007BB89966E66BE2952167D18C5CA20DC8496B4042AF845077C9E4126F5CA685DA7A1F7115138FA358675D9A907981EC056808C9D480481AC35B1617C132BAC3E0DCE26912537B50C2313E +27ED1F9F +E2EDE6C5D47420189F87E6656CFE +6D2A1A687E0D1ADE2DEACB6E152794D7FE0C089980BB5B59CB0604611F34404ECD724CB90532A30117064E6763B311200E6998E770ECFFB7C08451709A3DDBFC81207AE9CAAEB157EC11DD2573A79F1569DE5028724EB14783C9630A2B5D2E3A67AA08F6A537931289E8 +0202DBB5 +8C4AFB5A77C088583D128456F9 +8B8120A1A33CC28B0A33AA16E6C3CA89A2707EA81D386322570380CB2A939245C8673CAF84CBF0C6C7ECB882FCFAEAE5ACD2328C5D467CEEE21BCFB7DB5D3F794981B3A89834D3E306B659A5BA4407CFCD1A930EEC8E53 +B6EC86A9 +32EDAE7B40D4CDABF8D2C2604EF5 +2210F343637473808EA6ACE2129233A2CCA029BDF54ABAB96EEE95F99B6F9C95BD76F71F142B132F2C6DD89AC4AAD6D8B523873E2E459C62EF02F89FF654C5064860BCA745945F2F1BB1A77947AB42560F11D02EB932F59B82258600453469BA003219CD340A1DFAFA9B9250ECCAFC47D815DC88C59F95FC7BE9AADD +C7A00988 +D964812D849D361D900EF93504 +2D304986DC3EC8DB8DC74ECE47AF10E5B718867B719A262E077456EE7E4DF1594D6B8A92EB473215AEDEB6BABB5457E1A37196AB8EF55041C46D3718D94C7FF394319C5CE7 +F69F0C6C +0B7504B9BCBB4E2AE3E5621069 +98F7FBFA6469BE8866DC9F34CEE9163C7129AEA946DEEB114FE2E655A942DF9282261506E11EA2B4AA88A3BE49C79668CD3D794EC72E3A0176EF6B9E833962E1A31D3D8049133DC44614E3CB1CF9D0D5C8BC1A2D87ACF36A678634924ED0D00AE609 +2983D43D +08AD05B8693C6C598BA50DCA2E +BEE2FB9367BBDD29CD626AC54AFEEDA062AA3628CE4B1AC3CDAA9A8332D3D0939F2A11868BBFDCA445F7F148AB31A914076D41AE4C250A47117E9957B9FA6B7F4EA33C0CFC0203690AE3F1389B24E025C7D0203BA45BBFB973 +9C5B862A +08D480FA16502F550B4BEB512EAB +95AC899D02E9D800D4780AFC24C7002026216286765040340D3B18D3E46DB7829F2B5788AE84F5729FADFF7D35E2E695ECE3DC8252A55C0F199007107AF5812C6859B5E4268A5E50A11067F71DE4750031E9089493B214C60F10FD7F5E55456CDE6AF36EAD6478206CD897248DDF29816FD160B4A98B44FB407E892935FE +5380 +C8BA4F1066E898028F452B911CDC +8A8045DE +82E1DDF76ECD5FD8E0BE60E131ED +9AE9AE51F6FD31557142CC33A0D1BCA2E1FE97BFAD85D32D913E8A1CC03FFADBF89AC15716F0BC37823D7FA6213A65774913E7B83AADF97D8A06C7C50267D1AB2A9620CC538D1590E03856C4FA64D297FBDF43DDF407E7180E63E2B91638AA381BB4A7190E180A0436EAF5F3330D9638F23577529F822A7574619078A73B +C4EF +11E53453685A42FD41E4401388761521D0249E7E5C6ECDFF27 +414492F2 +D225FBECB573D149258CF53CB3E5 +2794376921E9C5A75C66FA0FC1FE9D6FF496553A2947A50BA90A9AF5DA8631E4E6B5D095C2B664BB1C556CFDDAD38D659A8F6751C206167A4E210E173BA75A9490A8A590C23BEC048386E4B8E32C7E8E3005C5B45371FACF2B11F60C1F47F75F3CE8CC4C6515CA0FE7EF388C79F6028B8BC39DF7D685C851C6F80FC7F1DB +5E62 +1E8271E0 +53B89C80161C3FA1A58E7D327F +0F4C117FA8E34D75C6D74FF47F977725908FCF5A54A6CC3422B4AA6F2904219FB1E6E8DAB7F9C30857D0419A28833F1CB96EA43833FBF5CC1A97FDD1D1D660 +34751F7D +A737C4738CE2E81301BA428CD872 +25C7FF2843D6D7D0BAE99CC80BB863680AD268E46017E1AEE468BA7D1C50A948BF56C1C097DE933B5A5F1FD20E172817E7FE584AA573F6B8544666C2DED9951041432B1F31ED15897C5766519FE2501DCC981D494E9714BFA002CAFAC40ED5C4E71A7C96FF26DB5B49 +7ABEA640 +66327AA26A3022765C63CF391A +DA2DF440D8E20B980DC77E58144BF2AD7A54930AF9B3 +14EADA12 +4E3C09B357CF517FE4BBFCEBC579 +9B4807511B565FA5 +685D0CDB +11D92138F4D648115128F1A59460A109E4376FF07C47D4C63095241C36CDCBDD58B7 +B9CBF2CC2260891638EF1BBF5B0DA6CCB4EE6F280CD206EAB5F8C2FB77DAAEF1DEFC6E740686 +36AB10F34CEBE87D2A6989C92221BD21A583C4D975F9345E64C23A +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +%Defining font PSOwstdutchb +%!FontType1-1.0: PSOwstdutchb +10 dict begin +/FontName /PSOwstdutchb def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001000 0 0 0.001000 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 1 /C0032 put +dup 2 /C0045 put +dup 3 /C0047 put +dup 4 /C0058 put +dup 5 /C0067 put +dup 6 /C0068 put +dup 7 /C0069 put +dup 8 /C0072 put +dup 9 /C0073 put +dup 10 /C0076 put +dup 11 /C0078 put +dup 12 /C0079 put +dup 13 /C0080 put +dup 14 /C0083 put +dup 15 /C0084 put +dup 16 /C0097 put +dup 17 /C0099 put +dup 18 /C0100 put +dup 19 /C0101 put +dup 20 /C0102 put +dup 21 /C0103 put +dup 22 /C0104 put +dup 23 /C0105 put +dup 24 /C0108 put +dup 25 /C0109 put +dup 26 /C0110 put +dup 27 /C0111 put +dup 28 /C0112 put +dup 29 /C0114 put +dup 30 /C0115 put +dup 31 /C0116 put +dup 32 /C0119 put +dup 33 /C0121 put +readonly def +/FontBBox [-18 -209 798 694] readonly def +currentdict end +currentfile eexec +D9D66F633B846A989B9974B0179FC6CC445BC7C8A959A39A32E9DCE7FAEF17EE3BEC9F +50E1A6FCA651FC4B3769A0A91041557502E25A5D6180FE25A3D11BF079E1DF66E54EE9B7C229AF891739707A2A0EC140306B5E43E52B79BFB89E459E50 +6EC6F610A70775A31C460976C4F79449D86E57ACE491E5C6BF20CC4307B1DAF7630252 +E9AF8CFB69B50EDAE9D36A6104AFEF8832F920FD2346B2C7104CD11E3BEE999CFA9F5A +49DB3173EE48D1C82994237F360407B022E0B4 +502E94EA8B493651EF2D03F0B513D655047568325B512AE6 +6AC6F53F3848CF70DE25481CC65D8B1A5793AA +3C4282D111112BEE28AFCA7A3808D4444C4669CA +84EAAAF989219F51AB3476A1B0B5F2246BC306E6 +625C6679C417ED2A8E9BD010DE37D40265074C26842749BBE43AC12A7C13B47C299D89481C69DB +94D526DD7141BCD67A20FF9A +D7A658A8B872307EEA +65FEDB9B +E62B4ACAD05AF1A4D9DA1A5752 +B5222EDD6C9C89087396D6BB9E2F892B535D7CE1910669 +30693027 +E93C93721C30E33C31AAA97953 +60C83D530FDF663AF95CAC2777ADAAB0630CE180C3B153582C8D +09DF6028 +BC94590CF7C8E2DC18AD1D5E5C +5F47775AD47715893E2CB8B6528E6C7072CF7CB823526439F05CCABE5E595EA898BB27AF86E8C34611E1E2AF6F870B884072FA00A557 +6AF69B7D +71C4B06A893A3FD0DDB5A1C147BB +46821BA69020A7C9BF3AF5C5BCB320F23D71716018853214B15BBAA5B5953130224C5E09FD02D73291D61F78C1EFA300A6287F17119C47FBA8D746308A41C231A94DF82A9FB6EAC1796770BF2C6B01ABE66997EB55498E5DAF12571869F85AF7D9612369B14AE241 +9A6DF028 +E8DC87B8A072A3323F518F52A2 +3D605155D2D642E1BFC60DB45D659F36D75ADD604BD4F609B8B2AFD3DE09139C82F6DEDA7A117D1C503C83972BA8BE62606D46C8CE6D566C37B940A098D1B0EC9FFBA417F88F4D861D8DADF069D8D1CF63444F270F0D74 +75656166 +2DB1BBC3D459B6924C0BDF67D836 +92F9E18E9A1714B1F7BDE560937FFC025C9FB93D4FC7F476E06C23E30C50DE0D88CA846D4EC32F8DB5541DC222C90C70A6717CE936CB89B4FF046D3CA46BD6A7A0F91760132819F689822BC940C1677C48EE61DD064C1AE2EB1EE24D272C061A33FB77B638A4866B833CFFEA5C58 +E3A414EC +4E4157570E4B3C3E574E2069E658 +09B7A1A5D63CD08D79862589FA067ADDFEFA8BF82E0AEB648371D63E60312A438D2E4EDD9167609182236958F8D7A8F6E1A3B3BE6AAF57A4C59EEDA475100792C5AACC6CC86C034D1DFCBC3CBB6454D2255F30C81F1F9491C18436D0D94AF009811E1B9A45972CCAE36E8926A579F097CC6B14380398FD +9E2DD94E +22D854C4D1456A6F891EA6472B +994806D0BB906FF704B12DD1286821F7A9349943E789B407A19E8AEC04F56513A99DC4648B59877958DF421A275B7387893E8D5025798774119B6058CBB9 +4072E620 +D100CD47BCAE0C2EF50014FE1D +C8921C0E0D9E61FFFCE44576B7D08D10EB914D0E4E8AED61F840692904454108B4D97A842929DFB3E0AF1BC6FDD7A34E347A5C494D608EA9EE2E00D1702621DE6AD95A543BC1CAF35C +85355020 +54A90F0B73F9CDAFB7D5F265BE +BDCA4C5872D39BA70029C02295BE1CDA9ED3982EB7D4825673264F5ABBAA23D2BDDDCA72B9FE231BCECFF1E3831A39432BD9C36F91C8F51DC8D464EB59F94B3CD0DCB58AB4FB52D72E8D4DC64A2215B4C773E1A297AF849F4CF478FB27AE67 +B9AAECFF +CC7B08726D843DA5D99B501F212C +04DDCF143D270973146B56D5E13F61570D5F75CCBD21F1506CDCF95FEFCA2099E3BBF80182A2C9BED3D31EF20228ACA7CFB5E360A21B7F311436A03368C0CD699A94C7F005423C7D7A9383F05E690034650EF6A427ED19C5B13338159C4B6AC96BD99BD252853F65A3 +1345A4C7 +9B97659E92DFD83F038CB209749C +D859634631B04AC06D2188C04FA119D81B8CF072E17D0A9D3E2C82E2B15CE60539BB1B5FB5E8E17D32B20F9D94D820BC4CC9CCF854A7DF4A88487A5578407FE9006E2D3B2480C1203DA3B85C974E559B909E7F387615B841B96AEA9DE25D15B9F2B2A2CE +794DF014 +5D6C34F37CBA71F1BB7080A903CC +41926860E0AC72BC8FC92C37FD8EDC147F7385030F0D599FEE5D0491BA88C7A1CCEBC9A08C278890CE319AF97ECAB43132C1517D87168C94B5D0DC510AD3A8D96C7269D697476E6796E8EDA5027A05E52E7FAD640A11378D277F1FFEE2374A9D2937CF98D5A69EEAA6E8CA4B348146FC5BCFE3BA54019F7923B231A82E76 +CE13 +26C405AB +68AA819E24F64BB64BC9937EA9 +FFAF8C07EA1B9FF98C7E421CAECF9D83291995153E0362F45D62E8656DBD8B38773F9554C7C5B0950532C426732F9CCFF01E5AE2F6E8A6F3AA42EADB2F9A8D52D1F204DB3F4A1156B6 +26D9F1B3 +DBAA081CE4016244916D90F5C92C +686F122DFB3346D38C3FDE677AB18D94CFDBB50DF9AD63FB23D789DB64364E4A40ED35BD0E619B221B7956897ED8664086D772B774BEB4C62BAEEB8DC8B26D53CAB7B1F1A53493281C3A04594FBC10C90224573F1C68B87B3723452FD1FCE08B64D941125CE71C19694EEA7602E6122CB11F3A747BD4AE995A59D33742C8 +49B3 +3B981D77 +AE742D25 +4BA6CBFE5830495D468650AD20 +A77AB23CDCFD92DBEAA1DE697BF68EDE290186A8B44F1276F80A7D630E847438A4A8D1A3DE469CEB9CDF56AE59732EC7585B27FC47E694BE3489985E42CD16BA55A1816B90FFB24262DD68E3F4EB923EA903 +961F461E +821FBE53D272B6DDFE3D0FD44C35 +250329D519791A774D60EB5BA31CDD79B14489349E4AD4CB38095B1386027EA7004CD49AA124F4F164EFE30A49BFDCDACBD7BBF7FDE0FB62EA8C5F050FD9621876FF3ACF3FDA47FD05541724D3BE9328123DEC8C58078D78AF53E48A3191671F514E53588B11A54C5CD435D9 +765DE1FE +E54B81547C5B808988C5EC8F1C +085D2EB9F9840FACA5340FC25B088364F7278DE1D49BF9DBCF72FD084C365DCF2B8366C3351DCBED0807D8B92DDF736B9E7C4747E1C51F45B0548A5AFE62A80E900CAC36F551D62D1FDE5109FDAEA157EEA00BE91F405CE0D8B9DB0F +00596981 +C4B99BD2C6C53D68CD4D90B606 +8A5235A9EEC601B95C7FF582E68A82FD0A17F71171E9C71632F56CEFC802A828D58C7286F39E5C358950479E2153C287E170614604A26B9FD070332A6EDA80B5C3A2113FAE7ACD7F3B3391FB1F56851232ACE33B9E686E945DFEB7BF26 +BA75740F +150AD672D0677B9F42B0F0D6DDDE +2D630E6080E72D3DFB79AF9950DADB155187606F329659475ED5A5C5EB5FF42BAE524D77CDE488E477DE413D7D5E013F8D0307383EBA0D3E30F917336BB8FF72985C9F514671BA0BAC49BD0858DEBE7BF7561DF45D9703EC85319354E0D626A3583215C376ADD3A2A65EDB81DC4B4FBE1F7F90537257D6B613741F5D941E +AA37 +482D7DB95D24E0B9AE907B7C103180E4A7E9303B6B15651E739EAC23F26C6CCCAEFDC51C45 +541885B7 +749A2B1E99598B1A5F7518DB062B +540FD96A5E11D71A20669ED66980200CCE22F775D80530AEF23479935E4E0130E453D3E91C9CE4A1E71C93641D578A1565CAEEE8DD8608A34E4A1A0D6FE5BE3FA2047F8BE272722B84C21126A3C4CFE033ED01E655B080163A6F9865355CBA2AFCADE55735B2FD45 +462A4D76 +C4DDAEDE4F6C3176AD7DCCF0DE +54B996C78537A3210E114E0AE7A3586FD21C5374C2B63C7F379A1F8F9C0F4AD4BC40D45F094BEA738E0454013FF874B5408C3FBD96FC801A5A2427C4EDA297B3E0FCFDA1FC8F4583B132C6805F9A +A2D76D11 +2FA22FA99372FFAE1401D73911 +27468DD26490EC2462570D23F56D6B452B60BAECC6F7DEA2A9E1BB4B1AD7CE6210D5DC26A62D7E85C7A8663284CD8F023F16DAA2 +56B5D6C5 +C7D9021508D3DF5CB92D9414A86A +C30CD7913589706C7DEF8DB4C53AD2FA195877F5FF996492375ACC9C094831147F0623200C20B5FFAFDF2A488B140265B1E1DBD9E5BDD4725A4BEA79F8EE88F92EC5843B67B8E67C1464DE81AE37270AEE018074DA5EBA4538ED82B7E422883611E20F439B817FE11BD5011874A50DEDB59C90C230C920A1CB2F26065809 +4A4A +9908F6BA407ABBCC97EA744061E6FB1C7471604E23EEF3CAC4EE1EA9 +9C4AF3B4 +BF7940DA80A18C79A7FC1E1EA8D9 +3C4F30EAA4F51201C9E631E704FA9B3AD1C3A14C4B7E3CC5BA62BA90A4745C4EB37248A89090395CAD38A359B16777CEDCA43C8FECDA7AEE7D0A7312A2CDA863A1682AE97EF59EE0D40427175BFE43C66B564ED6251F73A69F3380B2610577F9746BAE8323C100 +01227538 +F03940947E6BEB7CDE4CAC9D33 +FC49E85E6B56A3293C2CBB48E739CC87675EE28B444030AB08D163FBE210A0B5B7256CE498E53DBD456ED0DBFE6F2FFA8E3E6461D52781CCB8A5FBA2036A07FE707FF49EB39E +82B29139 +A7497352794C3581445D50B31650 +CB2FE423DAC31C43C20E82D2E08983B986C53514E3092C56EAFC79F67208B5F0515FEB77F6CC0D37E888C0E3ED677D913756EB6AE0A10DA700B7730D2A75C156EBB3146F998A97E485FEA04851EB8C6E50F1B56ADFDB8FE8CC022A9BA8792BE6F5218DDCB7905D055A6A1869A37D904EC0 +92E12B20 +C09010BB88D2A7CAB05928AE68 +403AC7D2BA788FD5B54F6F76C6DE3E1EF4AFD797B3DF87BD5D42C4BD815C8421631EE3329F5A6B7D66130DD2503C40804FA28211EB5CF44937BEA27DBBF63906B3352EA1C0F2B61FF19321D0E08997546922E1D1E48A380579 +1B88B5B1 +8125327DF8E52FB306DE907A1786 +8AACF322579C824A696C7E848DFEEC9A8B0F3D7C6688FA2E3F7C149263AE50F5A07BD8941F9E777AD2C1D28703B190B9B2D46011792E49870B788E1AA53A6092E24BA1347C140A2D295ACFA2E96AFA41B97AC999A1098D99423B1324964BC6FE6874AE2C00B5272BDDEED932AD010018B700ECE63CC863CDDB +8FAD59D0 +AA88E9AB409F42D04D50DD4313 +E4E95EF7A0F5C8759E81D5BCC2D564C384F3C8F5D229F1BC8574AE800BEB05806E2B49D74DC73FCC5502744D5147E66340C896F49E0FD996BB579C7D7140F02525652EE9 +FC21690B +AFF506D43156BE467FDB5A595F0D +4A93B656C4B6B745FF66BA3A797DDFEAC142FAB98CBC9E54EBC1354819A5E354CB5B7790F512A1A6A15C407AAA07703CBD8BD4436D194F2E648E2738F3B26BBC7497DBEB142ED642927E9B1CED9B3A7EC41CF8F9A36666537D6DB92C67740E58A03EF5617EFC2E8BF63B16488F564BF7429933AEF4407284EC416EC250BB +3F8A +5B023EDA2ACD4011C9F591 +071D8F64 +A34C4B90C005CC74F48A02238917 +E270FF6B18821EF9E6F1D577E99810F657CD4AE1BED49A690A490A37E15B452E2E6821BC033DD702E02A5679CB313D4EBBDC9D9BD24E625493C633F886D5E07EAF01056A9E812B6F4D2FED47B4A27434975BEB655B3D76F9E2972A815C06214F1B2335ACC3E4FF7197062E0CC12043D59F37BB5FBD21874C4820570B7180 +8D5E +4A +F4E79A0A +60B0196D4E25CD7D1DC33D1DD83D +CED5B0D12E97E390 +56CD0E8D +AAABA52A67F80E83764F67AA3E6425E3455A21246EDE5E71483A222EA665D5225B9C +FF28B33E7155B0B4F709F6E985660B3DF0389B26F69B6D456EF3A80DA8EAAF6064DB67AC2D25 +D715E8BBF241D26DAB769C82AA670C843176204AE42E9CD3150C0B +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +%Defining font PSOwstdutchi +%!FontType1-1.0: PSOwstdutchi +10 dict begin +/FontName /PSOwstdutchi def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001000 0 0 0.001000 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 1 /C0097 put +dup 2 /C0099 put +dup 3 /C0100 put +dup 4 /C0101 put +dup 5 /C0104 put +dup 6 /C0105 put +dup 7 /C0108 put +dup 8 /C0109 put +dup 9 /C0111 put +dup 10 /C0112 put +dup 11 /C0114 put +dup 12 /C0115 put +dup 13 /C0116 put +dup 14 /C0117 put +dup 15 /C0118 put +dup 16 /C0122 put +readonly def +/FontBBox [-144 -227 757 728] readonly def +currentdict end +currentfile eexec +D9D66F633B846A989B9974B0179FC6CC445BC7C8A959A39A32E9DCE7FAEF17EE3BEC9F +50E1A6FCA651FC4B3769A0A91041557502E25A5D6180FE25A3D11BF079E1DF66E54EE9B7C229AF891739707A2A0EC140306B5E43E52B79BFB89E459E50 +6EC6F610A70775A31C460976C4F79449D86E57ACE491E5C6BF20CC4307B1DAF7630252 +E9AF8CFB69B50EDAE9D36A6104AFEF8832F920FD2346B2C7104CD11E3BEE999CFA9F5A +49DB3173EE48D1C82994237F360407B022E0B4 +502E94EA8B493651EF2D03F0B513D655047568325B512AE6 +6AC6F53F3848CF70DE25481CC65D8B1A5793AA +3C4282D111112BEE28AFCA7A3808D4444C4669CA +84EAAAF989219F51AB3476A1B0B5F2246BC306E6 +625C6679C417ED2A8E9BD010DE37D40265074C268425D7C73E0D9FBC2C51FC5D7A4C8466A0ACF3 +EF6A51E85881893F5F8BC8430208 +87F3103F7721E137FA1F5E0AA668B92FD52279E66C1F88E225F1D00525B03625600EEE9AA0F3BC774875C78C8DA3485F17675C49575996A73AFCDFC5C043FF15240F2766D360B295D9F35757882F20231CD23D4B1D44649FAC2F946C5244A22F62F98DC8900497DB880EE30BEC4BE3011C108BB1603FC9E45087B4C3F7B4 +380E +DB7BEDDFD810BFE55A51FA92E7 +C5E02760 +2FEA6E1C7BC816B379B9BB690B +3F1F8D5D13B2FA0CA13B32E231AD6701F85E724E73EE5CAB752A1F01924E57EC33256147A9D15C2BED13E5B9868E463D0CF97CF79520D198EF7E9A4E8433615D43ADB42E79570068860AF8163DFA32E1F1AA9D84A0589C316A75510753214517 +65B024EA +2CAE33DEAFE2FCFEC055BCC6E807 +8A53B445D923820C0B3C3B775BFA1858B494A3E1ED579B4B7021B2747CA7DB9BA810D03C123860AF732D6CEC7A174E5ADB2DF2C48459B7DA91099B9EA4DFD27060070047B8FED57852BA56F0C75B09D95315841A1D637002612F731AF8EE4047DED5D8E53BA552BEEF5D79070B6CAC2B68F8C835BBE415D9474FE29393F9 +AFB7 +3168F8BACEE4F753E5374F9DD54F816F2FB16569CBDFFE6BEF28AFFBA96E6D1D41790B9AD5A71AC47EBBF08AFD654A41 +BBB9B934 +32CD3EA43C3D75650A026F94EE07 +8C9CD2519EF572156B2F34DEB76DC76BA9B2709A6DD78C558978CDC791BF43681BB7AE9328BAA7B284BEE5A7454C72A5CF2C9BDE94805A59FF843BE51CCDBFE69C9361EC6C491C18FA2616C75B772E614F13C38B3A7CAE3986D2B142CDDD1DA052556B0B80 +CD009F6A +B2638750700D66D0AA5810213141 +AC008781F399DF1A8043DBAEBAFC2B4AB596DA1071F3D505655C8C9E80FD9A1E0FB5F70DB8A227FC5D87E25B5985462D2E4DD446F8872432FA4BF7889A6B81AAC9CB8B818141C4D237D7DB1FC5D51A559CD13C935BF1AE639E261B83427841B5641084F6F43D44CB7DD60A0FF47E94CA86D71FC6EEF3AC18930CE91B00C9 +BD70 +67198EF0F55953DD826A0C981C7193E5CB53591FD92D5E3EE4FA3E +90B8AFD3 +BD7D1A65145E62B247484DBEFD7F +9A354A8CB2B1916981F3B04C446E91F9D7890C99E768D9FC4EA626D698A0A3099937CE0E16D26D38BFC8AF24914C1CAE2967D79EFDE69EF86E23739B46BE7C837D9D30688FD3748649FBF68082FA4D71603F483B057FA6DE45EF31154B6259F3B633EFB3D6A3573B473EBA1F01DF2CEDB0267012DC453BA300 +C113799C +D73D058FD325CCDFF91C7ECFC0ED +F5C1A835FADD3A33F90C6D40BE35C4C44C1E74A06BA5C213AC3C32207333F41924B722B467C4A262257C21398E3C5E1ECA06D9A0009E669507070150690D999B4B9DED64DEA22AA62FCCB06D0CFFF30CD6A3F21685F8AF43382540C00024B76FB86C21BD8F +14B44FEE +D45309CB76638A360CC3C52C3768 +33CC9C07A2C94C292258711A2E2684BD770223EE87E8E51500E66C413C885DD8F7B591D616E035D0A4D2422B02A87ACA35910E20483353B8AED8FD027ED84DADC927F04AC5FE290B2411BABE9819A1B5455C4675C02D586FBC946DC0D8C0D4565D47A4BA1E01767AC01BC99D380E26EAEF2811140DA4BCB2B6CDC145E023 +5577 +40C8C53F6C1D23B66FB4C547785165511FE75EFF5DF08E3A890D269542C74E76DCDB27338F578F7749E1BC5649B49C35D6EB07D8B2206582EF4DA5C871AFF0DC73D364F571B9C1A55CAD69 +A3C897FF +6AF3F0EFA51F761CEB5A096396 +CA62ADD641BBEB7F15BF71EE60A0769746359E6ED502D86221686F5387FAD1C99FC79EC3B67D26DE4791AB7C2E3A878F100DEDC77079DE9354CAEE593159DC4804840B346C0B63AF3042A8F55ED2CDD681AE02A5645E4271908645E64434C8 +6EC1FA94 +81224B594D324EEC22B18CF2FFEC +C694D26DA4B01EAC17E81BD0A1201B0733F1A238069CE685B61AB7C0372DF527FE13E9C4F02FA4A2A7BE9F63068EBB5852C9FB7C0B0DC480699AE2B9577DC4353799D0287CD9A5E6A09A0A725F591EB131ACD72F98D79199B7B3B42CFA5E54F1E7DB1F92EA4D6055FCF627C4E2CE90046A8E4C38E997457959AF4C53165E +AA0C +1EEFE42B3AF218C199BF1B97FF9F9B6EB63253BC3554E8CA2B39F2CDD331E73CD77F84039348851032E7 +26E8CCA2 +F9D4AB9099648F165944AD02EE +83A494FAD10601FCF54C0665F0B4787B56E8F0AD22D814EBB6554B622A30AC57E466AB4681F5678DC5E63C7C447C0ECD2B7078507E91BCF725CEF508D6C40E89FD8A2669DDAFC1EFD2A0D52434A82440516C391B57AB169A0D3527 +274A5949 +BECC37B7C4A95529BB33F2C0EA8E +279DC6700EDE0CE850A9177C6E851D01D67B1FAA0EE446FE947B16A24B99C1C2E8D8141337D7056995F4BA9D1246551587AAEF5E8FEA8C8127BBDDA6294ABA6B37B4DB63D93BEDAA30FC12BD50129A0A83BF32440C7F4816C47972ADA35D3DCAC651190BA1931004E7771C93F43764148B1D6BA2FDA7 +8365AAC2 +164D07464A95C1C11288EC1863 +53B9C4B298E49C0950C8F52058CAEF1A34199F853B79DE7E0710E4B12497BF156F813B0521E72F699358CFBD14A9D56C8DC8CF5F56D6DA181E1FE4D6496D24297BEBA81CDF42F498C0228919A0DBC51C868639925F9E16 +013CD527 +52A6337053FC8E0C4D5869B29620 +BEBF01FDE1279BBAFBB9C95FF68EA78975E9CFCC5B55F1ABA4222C5F9F36DC17938A29C73B252193AF33E547898A38A6AD3BA1A61A56D7D853FE2DF429F84C3C67F96ABF21C9E897860BE9F978622A51B39B0B107EBBA0326E008170847B38B385B268AF5D03A11D589D4922948261BA452EC10963E2D51821EBA7D02BFA +EF36 +2D3AA90B6951C967A9C9887E747B2531CFAB39692475A4 +E0E0F454 +CC4B89ED9F742F955470A0DB6B +C7D12AE114BBE7B26E1A897C731703C2E46EF5BD927835056BAE681AEEDF072723394C9A1AC2F9CCDDA88B272880F39F9C7A940970AB9F77C713C4000BCF101E5AF761BFB9775DD76A4AC0E96712C684B25F90A64F68F8C92EF0 +67ED835E +3E4E375067FCA6B11A129AB7631B +321258285A91BA87CCB93A9829342162FCC2285E018016AD1A28294BFA357E8F71874312FD97EA3A42D1314BC9233A28F681BCE856D7B7749A11EEEF73B6FEF343AD2894E7E5050C32CF8DAF35DE551706C4E06564A939C3E67CE3B16E9B3B21A2290FE047B156F96428C8205B42A95C5F83B862637443F3E50B6BC49ACC +F0A1 +42E8E1B688AD6CBC4F +BA5D4B3E +C7943FA2DDB74F93D3DDF6B53340 +8F3D7332672DE15B +E7E183BB +D8F2F7B41E4363FF42244CE829AA73CC4A79D33F2B9F0839F89E36E300DB4857F052 +1F35DD3F5FA2BD1EC4A1C8F4951F797EF2C0B2C82418278D87FBBF498D2D2FABF87CA6FDAC99 +58624E435E800292174BD0EA60CDB71B326C73EF7AAE32FDF27D51 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +%Defining font PSOsymclas +%!FontType1-1.0: PSOsymclas +10 dict begin +/FontName /PSOsymclas def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001000 0 0 0.001000 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 1 /C0069 put +readonly def +/FontBBox [106 45 775 713] readonly def +currentdict end +currentfile eexec +D9D66F633B846A989B9974B0179FC6CC445BC7C8A959A39A32E9DCE7FAEF17EE3BEC9F +50E1A6FCA651FC4B3769A0A91041557502E25A5D6180FE25A3D11BF079E1DF66E54EE9B7C229AF891739707A2A0EC140306B5E43E52B79BFB89E459E50 +6EC6F610A70775A31C460976C4F79449D86E57ACE491E5C6BF20CC4307B1DAF7630252 +E9AF8CFB69B50EDAE9D36A6104AFEF8832F920FD2346B2C7104CD11E3BEE999CFA9F5A +49DB3173EE48D1C82994237F360407B022E0B4 +502E94EA8B493651EF2D03F0B513D655047568325B512AE6 +6AC6F53F3848CF70DE25481CC65D8B1A5793AA +3C4282D111112BEE28AFCA7A3808D4444C4669CA +84EAAAF989219F51AB3476A1B0B5F2246BC306E6 +625C6679C417ED2A8E9BD010DE37D40265074C2684268F16195489648993B9C4D3B534FA887C +DEF605FA87B991F4D20A8F78DACE +5A54C070E03D5C59D9D2D3E06B09CEE028D68B62AB3AEC43C1DD20BA70D288597D9BD8E06818FF764EBAB436723988E8D7CA59E16D39032516BFC5D552ACDEEC6BE938BEF2F43CFFBC811C3626C4DF5F8CF080676520B51C60CEDAD1FE6C92D1431C702174CE517A8FA9377D075A0B6833DAB101DB65397F1419EF5F0016 +004F +6F0824F9657BB4F1C8F981709956865F6855EFAE +9242AD55 +91BBBEE163D844DDA894E13190C9 +2480439E4C71CADA +BD043A9B +A315CAF72652AA7FE6DB2E84D82A6111CE4DE90C02DA0AFFE2620922262A45AB4ED0 +EEC9F4520DD12703442F7D028D4526BD8B771E09FBE11B2749E2D3906894E8D4BFD3F379F14C +3C874F550606965E22FE487B247B5C2D06728490C8F2A3B588CDFC +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +/DPIx 1270 def /DPIy 1270 def +72 DPIx div 72 DPIy div neg scale +0 -13970 translate +1.00 1.00 scale +/wst:dutch12 12.00 /PSOwstdutch newFont def +/wst:dutch12b 12.00 /PSOwstdutchb newFont def +/wst:dutch12i 12.00 /PSOwstdutchi newFont def +/wst:dutch10 10.00 /PSOwstdutch newFont def +/wst:dutch14 14.00 /PSOwstdutch newFont def +%%IncludeResource: font Helvetica +/wst:helvps10 10.00 /Helvetica /wst:helvps ILEncoding 0 declareNFont def +/sym:clas10 10.00 /PSOsymclas newFont def +%%EndPageSetup +GS +0 13978 10801 13978 10801 0 0 0 clp +wst:dutch14 SF +0.00 0.00 0.00 1.00 setcmykcolor +<1d2e3c382e3a2f10011201132e362c31352a3a33012f373a011c2e2a3b3d3a323630011d2e3c3f373a33011f> 2207 558 0 7384 -1 s +<2e3a2f373a352a362c2e> 7375 558 0 8593 -1 s +wst:dutch10 SF +<0c0c> 9346 13385 0 9522 -1 s +wst:helvps10 SF +<4e6574706572663a> 1322 13267 0 1949 -1 s +<205265766973696f6e20322e313b20436f7079726967687420> 1949 13267 4 3868 32 s +sym:clas10 SF +<01> 3868 13267 0 4019 -1 s +wst:helvps10 SF +<2031393933b131393935204865776c657474b15061636b61726420436f6d70616e79> 4019 13267 3 7133 32 s +wst:dutch12 SF +<0826> 1589 1431 0 1929 -1 s +wst:dutch12i SF +<03040f0c0a0402> 2033 1431 0 2700 -1 s +wst:dutch12 SF +<3b2e3c> 3177 1431 0 3432 -1 s +<003c312e0034372c2a340a3a2e35373c2e0026221a002d2e3e322c2e002f32342e00362a352e002f3a37350000> 3432 1431 9 7525 0 s +wst:dutch12i SF +<03040f0c0a0402> 7525 1431 0 8192 -1 s +wst:dutch12 SF +<09> 8192 1431 0 8245 -1 s +wst:dutch12b SF +<0b0c0f07> 1271 1778 0 1866 -1 s +wst:dutch12 SF +<100023151f00323b002a36003d363a2e34322a2b342e00383a373c372c373409001a3c00323b00323538373a3c2a363c003c312a3c0041373d002e402a3532362e003c312e003a2e3b3d343c3b002c2a3a2e2f3d343441> 1866 1778 14 9531 0 s +<2a3b> 1271 2023 0 1457 -1 s +<003c312e003a2e38373a3c2e2d003b2e362d003a2a3c2e002c2a36002b2e00353d2c3100313230312e3a003c312a36003c312e002a2c3c3d2a34003a2e2c2e323e2e003a2a3c2e0900183a2e2a3c002c2a3a2e003b31373d342d> 1457 2023 16 9531 0 s +<2b2e> 1271 2268 0 1489 -1 s +<003c2a332e36003f312e36003a2e38373a3c3236300026221a2823151f2821222016121c003c2e3b3c003a2e3b3d343c3b003c3700352a332e003b3d3a2e003c312e41002a3a2e0036373c> 1489 2268 12 8727 0 s +<0035323b342e2a2d> 8727 2268 1 9461 0 s +<44> 9461 2268 0 9531 -1 s +<32363009> 1271 2513 0 1601 -1 s +<0017> 1601 2513 1 1826 0 s +<373a> 1818 2513 0 2015 -1 s +<002e402a3538342e070037362e003b31373d342d00> 2015 2513 4 4139 0 s +wst:dutch12b SF +<10182010211e> 4139 2513 0 4743 -1 s +wst:dutch12 SF +<003a2e38373a3c002b373c31003b2e362d002a362d003a2e2c2e323e2e003a2a3c2e3b00> 4743 2513 7 8218 0 s +wst:dutch12b SF +<1f1b15131f16131d> 8218 2513 0 8972 -1 s +wst:dutch12 SF +<002f373a002a> 8972 2513 2 9531 0 s +<26221a2823151f2821222016121c> 1271 2757 0 3269 -1 s +<003c2e3b3c09001a2f0041373d002a3a2e003037323630> 3269 2757 5 5161 0 s +<003c37003a2e38373a3c002a003b323630342e00363d352b2e3a070041373d003b31373d342d003a2e38373a3c003c312e> 5161 2757 9 9531 0 s +<3a2e2c2e323e2e> 1271 3002 0 1914 -1 s +<003a2a3c2e09> 1914 3002 1 2380 0 s +wst:dutch12b SF +<0b0c0f07> 1271 3349 0 1866 -1 s +<04> 1870 3349 0 1928 -1 s +<00> 1928 3349 1 1996 0 s +wst:dutch12 SF +<001a2f0041373d003f373d342d003432332e> 1996 3349 4 3626 0 s +<003c370043382a2c2e02003c312e003b2e362d003a2a3c2e00372f003c312e0026221a2823151f2821222016121c003c2e3b3c07002a2d2d002a> 3626 3349 11 9531 0 s +<08151a1d221620> 1271 3594 0 2313 -1 s +<24> 2290 3594 0 2452 -1 s +<121b21> 2429 3594 0 2844 -1 s +<003c37003c312e00352a332e2f32342e07002d37002a0043352a332e002c342e2a3602002a362d003a2e082c37353832342e090027> 2844 3594 10 7808 0 s +<373d002c2a36003c312e36003d3b2e003c312e> 7782 3594 4 9531 0 s +<082b> 1271 3839 0 1561 -1 s +<002a362d00083f00003034372b2a340037383c3237363b003c37003b2e3c003c312e002b3d3a3b3c003b32422e00053b2e362d3b06002a362d003f2a323c003c32352e000535323434323b2e2c37362d3b06003a2e3b382e2c3c323e2e> 1561 3839 16 9461 0 s +<44> 9461 3839 0 9531 -1 s +<344109> 1271 4084 0 1477 -1 s +wst:dutch12b SF +<060a0d09> 1271 4570 0 1776 -1 s +<00051b1a1a13111f171b1a000c1d17131a1f1312000e1f1d131019000d> 1776 4570 4 4647 0 s +<131d141b1d19101a1113> 4639 4570 0 5681 -1 s +<0b0c0f07> 1271 4993 0 1866 -1 s +<04> 1870 4993 0 1928 -1 s +<00> 1928 4993 1 1959 0 s +wst:dutch12 SF +<00151b1f1a003c2e3b3c3b002a3a2e0036373c002c37353832342e2d083236002b41002d2e2f2a3d343c003f323c3100362e3c382e3a2f09001a2f0041373d003f323b31003c3700352e2a3b3d3a2e00382e3a2f373a> 1959 4993 15 9461 0 s +<44> 9461 4993 0 9531 -1 s +<352a362c2e> 1271 5238 0 1864 -1 s +<00373e2e3a00151b1f1a070041373d003f32343400362e2e2d003c37002a2d2d002a000815151e28151b1f1a003c37003c312e00352a332e2f32342e002a362d00382e3a312a383b002a2d2d003c37> 1864 5238 16 9531 0 s +<3c312e0029291b1a13211102002a362d003a2e082c37353832342e00362e3c382e3a2f002a362d00362e3c3b2e3a3e2e3a09> 1271 5482 6 6050 0 s +<12> 1271 5829 0 1434 -1 s +<00151b1f1a00143736362e2c3c323736001e3a322e363c2e2d00213c3a2e2a35003c2e3b3c0005151b141e2821222016121c0600343737333b003e2e3a41003b323532342a3a003c37002a0022141f> 1434 5829 12 9531 0 s +<213c3a2e2a35> 1271 6074 0 1921 -1 s +<003c2e3b3c0008003c312e41002b373c31003d3b2e003a2e34322a2b342e07> 1921 6074 6 4643 0 s +<002c3736362e2c3c32373600373a322e363c2e2d00383a373c372c37343b090022312e00151b1f1a003c2e3b3c002d322f2f2e3a3b> 4643 6074 7 9531 0 s +<2f3a3735> 1271 6319 0 1712 -1 s +<003c312e0022141f003c2e3b3c003236003c312a3c003c312e00352e3b3b2a302e003b32422e00353d3b3c002a343f2a413b002b2e00342e3b3b003c312a3600373a002e393d2a34003c37003c312e0034372c2a340032363c2e3a> 1712 6319 19 9461 0 s +<44> 9461 6319 0 9531 -1 s +<2f2a2c2e043b> 1271 6564 0 1778 -1 s +<001c2223000800151b1f1a002d372e3b0036373c00383a373e322d2e0022141f083b3c41342e003b2e30352e363c2a3c323736002a362d003a2e2a3b3b2e352b344109> 1778 6564 10 8529 0 s +<22312e003b323538342e3b3c00151b1f1a00143736362e2c3c323736001e3a322e363c2e2d00213c3a2e2a35003c2e3b3c003f373d342d0034373733003b37352e3c31323630003432332e003c31323b10> 1271 6910 11 8923 0 s +<03> 1398 7257 0 1504 -1 s +wst:dutch12b SF +<00031b1c1f031a131f1c131d14031a131f1c131d1400020800> 1504 7257 3 3785 0 s +wst:dutch12i SF +<0b0408090d0405090c0d> 3785 7257 0 4744 -1 s +wst:dutch12b SF +<00021f00> 4744 7257 2 5099 0 s +wst:dutch12 SF +<151b141e2821222016121c00080800> 5099 7257 2 7224 0 s +wst:dutch12b SF +<021900> 7224 7257 1 7629 0 s +wst:dutch12 SF +<0c0b0d0e> 7629 7257 0 8053 -1 s +wst:dutch12 SF +<192e3a2e002a3a2e003b37352e00372f003c312e00151b1f1a083b382e2c322f322c002c3735352a362d003432362e0037383c3237363b10> 1271 7603 8 6731 0 s +<0815> 1589 7950 0 1937 -1 s +wst:dutch12i SF +<03040f0c0a0402> 2033 7950 0 2700 -1 s +wst:dutch12 SF +<3b382e2c322f41> 3177 7950 0 3795 -1 s +<003c312e0034372c2a34002a362d0a373a003a2e35373c2e00151b1f1a002d2e3e322c2e002f32342e00362a352e053b0600052f3d34344108> 3795 7950 9 8895 0 s +<393d2a34322f322e2d0609> 3177 8195 0 4112 -1 s +<002141363c2a4000323b003c312e003b2a352e002a3b003c312a3c00372f002a00> 4112 8195 9 6914 0 s +wst:dutch12i SF +<0c0610040c0a0402> 6914 8195 0 7593 -1 s +wst:dutch12 SF +<09> 7593 8195 0 7646 -1 s +<0835> 1589 8541 0 1940 -1 s +wst:dutch12i SF +<0f01070e04> 2033 8541 0 2495 -1 s +wst:dutch12 SF +<3b382e2c322f41> 3177 8541 0 3795 -1 s +<003c312e003b2e362d003b32422e07003236002b413c2e3b07002f373a003c312e0034372c2a34003b413b3c2e3509002231323b00353d3b3c002b2e> 3795 8541 12 8895 0 s +<342e3b3b> 3177 8786 0 3502 -1 s +<003c312a3600373a002e393d2a34003c37003c312e0034323633001c222309> 3502 8786 7 6359 0 s +<081c> 1589 9133 0 1967 -1 s +wst:dutch12i SF +<0f01070e04> 2033 9133 0 2495 -1 s +wst:dutch12 SF +<3f31322c31> 3177 9133 0 3703 -1 s +<002b2e312a3e2e3b003432332e00083507003b2e3c3c323630003c312e003a2e2c2e323e2e003b32422e002f373a003c312e> 3703 9133 9 8180 0 s +<003a2e35373c2e> 8180 9133 1 8895 0 s +<3b413b3c2e3509> 3177 9378 0 3835 -1 s +<0838> 1589 9724 0 1882 -1 s +wst:dutch12i SF +<0a0a010c0a0402> 2033 9724 0 2725 -1 s +wst:dutch12 SF +<3b2e3c> 3177 9724 0 3432 -1 s +<003c312e0034372c2a34> 3432 9724 2 4266 0 s +<002a362d0a373a003a2e35373c2e00151b1f1a001f1f> 4266 9724 4 6506 0 s +<12053b0609002141363c2a4000323b003c312e003b2a352e002a3b> 6479 9724 5 8895 0 s +<3c312a3c> 3177 9969 0 3536 -1 s +<00372f002a00> 3536 9969 3 3986 0 s +wst:dutch12i SF +<0c0610040c0a0402> 3986 9969 0 4665 -1 s +wst:dutch12 SF +<09> 4665 9969 0 4718 -1 s +<083a> 1589 10315 0 1847 -1 s +wst:dutch12i SF +<0f01070e04> 2033 10315 0 2495 -1 s +wst:dutch12 SF +<3b382e2c322f41003c312e003a2e393d2e3b3c003b32422e07003236002b413c2e3b07002f373a003c312e003c2e3b3c09> 3177 10315 8 7194 0 s +<0820> 1589 10662 0 1929 -1 s +wst:dutch12i SF +<0f01070e04> 2033 10662 0 2495 -1 s +wst:dutch12 SF +<3b382e2c322f41003c312e003a2e3b3837363b2e003b32422e07003236002b413c2e3b07002f373a003c312e003c2e3b3c09> 3177 10662 8 7323 0 s +<083b> 1589 11009 0 1847 -1 s +wst:dutch12i SF +<0f01070e04> 2033 11009 0 2495 -1 s +wst:dutch12 SF +<3b382e2c322f41> 3177 11009 0 3795 -1 s +<003c312e000f0b0d090d0021> 3795 11009 3 4852 0 s +<121f002f373a003c312e003c2e3b3c09002231323b003b31373d342d0036373c002c37362f34322c3c003f323c31> 4846 11009 8 8895 0 s +<2a3641> 3177 11253 0 3493 -1 s +<002a3b3b3230362e2d0021> 3493 11253 2 4480 0 s +<121f> 4474 11253 0 4765 -1 s +<043b09> 4769 11253 0 4956 -1 s +<083f> 1589 11600 0 1909 -1 s +wst:dutch12i SF +<0c0610040c0a0402> 2033 11600 0 2712 -1 s +wst:dutch12 SF +<3b382e2c322f41> 3177 11600 0 3795 -1 s +<003c312e0034372c2a34003b2e362d0a3a2e2c3e003f32362d373f003b32422e3b003236002f3a2a352e3b00053f312e3a2e002a3e2a3234> 3795 11600 9 8825 0 s +<44> 8825 11600 0 8895 -1 s +<2a2b342e0609> 3177 11845 0 3692 -1 s +<0825> 1589 12191 0 1975 -1 s +wst:dutch12i SF +<0c0610040c0a0402> 2033 12191 0 2712 -1 s +wst:dutch12 SF +<3b382e2c322f41> 3177 12191 0 3795 -1 s +<003c312e003a2e35373c2e003b2e362d0a3a2e2c3e003f32362d373f003b32422e3b003236002f3a2a352e3b00053f312e3a2e> 3795 12191 8 8372 0 s +<002a3e2a3234> 8372 12191 1 8825 0 s +<44> 8825 12191 0 8895 -1 s +<2a2b342e0609> 3177 12436 0 3692 -1 s +GR +eop +%%PageTrailer +%%PageResources: font Helvetica +%%PageProcessColors: Black +%%PageCustomColors: +%%Page: (12) 12 +%%PageResources: (atend) +%%PageProcessColors: (atend) +%%PageCustomColors: (atend) +%%BeginPageSetup +bop +%Defining font PSOwstdutch +%!FontType1-1.0: PSOwstdutch +10 dict begin +/FontName /PSOwstdutch def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001000 0 0 0.001000 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 1 /C0032 put +dup 2 /C0034 put +dup 3 /C0036 put +dup 4 /C0039 put +dup 5 /C0040 put +dup 6 /C0041 put +dup 7 /C0044 put +dup 8 /C0045 put +dup 9 /C0046 put +dup 10 /C0047 put +dup 11 /C0048 put +dup 12 /C0049 put +dup 13 /C0050 put +dup 14 /C0052 put +dup 15 /C0056 put +dup 16 /C0058 put +dup 17 /C0061 put +dup 18 /C0065 put +dup 19 /C0066 put +dup 20 /C0067 put +dup 21 /C0068 put +dup 22 /C0069 put +dup 23 /C0072 put +dup 24 /C0073 put +dup 25 /C0076 put +dup 26 /C0077 put +dup 27 /C0078 put +dup 28 /C0079 put +dup 29 /C0080 put +dup 30 /C0082 put +dup 31 /C0083 put +dup 32 /C0084 put +dup 33 /C0085 put +dup 34 /C0087 put +dup 35 /C0088 put +dup 36 /C0095 put +dup 37 /C0096 put +dup 38 /C0097 put +dup 39 /C0098 put +dup 40 /C0099 put +dup 41 /C0100 put +dup 42 /C0101 put +dup 43 /C0102 put +dup 44 /C0103 put +dup 45 /C0104 put +dup 46 /C0105 put +dup 47 /C0107 put +dup 48 /C0108 put +dup 49 /C0109 put +dup 50 /C0110 put +dup 51 /C0111 put +dup 52 /C0112 put +dup 53 /C0113 put +dup 54 /C0114 put +dup 55 /C0115 put +dup 56 /C0116 put +dup 57 /C0117 put +dup 58 /C0118 put +dup 59 /C0119 put +dup 60 /C0120 put +dup 61 /C0121 put +dup 62 /C0122 put +dup 63 /C0262 put +readonly def +/FontBBox [-25 -256 978 766] readonly def +currentdict end +currentfile eexec +D9D66F633B846A989B9974B0179FC6CC445BC7C8A959A39A32E9DCE7FAEF17EE3BEC9F +50E1A6FCA651FC4B3769A0A91041557502E25A5D6180FE25A3D11BF079E1DF66E54EE9B7C229AF891739707A2A0EC140306B5E43E52B79BFB89E459E50 +6EC6F610A70775A31C460976C4F79449D86E57ACE491E5C6BF20CC4307B1DAF7630252 +E9AF8CFB69B50EDAE9D36A6104AFEF8832F920FD2346B2C7104CD11E3BEE999CFA9F5A +49DB3173EE48D1C82994237F360407B022E0B4 +502E94EA8B493651EF2D03F0B513D655047568325B512AE6 +6AC6F53F3848CF70DE25481CC65D8B1A5793AA +3C4282D111112BEE28AFCA7A3808D4444C4669CA +84EAAAF989219F51AB3476A1B0B5F2246BC306E6 +625C6679C417ED2A8E9BD010DE37D40265074C268422410489591588B6E7823D3D74C2EA32FE93 +9EB88AAB3B591575462F2E96 +55B8435E1419699E83 +41112633 +B0FA1A4EC92787CD7A26A873D7BD +1ECF175AD4EA48B87AEC3ACC8B38E3B38F1DDFC5780D2B090942E997D679A13082F0CF57FA7735299F5C2F7C05FFA5BE30F9B2BE51D6A4A2DE8DA7F543ADEC29BF50B705243FAFB502A8CCB53B9974BF5B4AF682BB3EFE56A659A712EFE75706728F3042834B1A +FBCB223E +715E8F189A7657ED770C7D8FF96C +E8A5C8F9496C39E3C7F84A92EA62138CA35B573C7A2FD44E7F86BF250CDBBA6E2C2C4478AD81025A82215C00245599827C4BCB7D5C13A5EEC0B35F967C8624B5BFC39670C29D9FC3160AFE5BA6EF03D105CFEA7F724C686CF2883ECDC74C32C79560A40E2D1FE81E19E8A16E940BED2C8B6802FD676B18128573AB953910 +E183 +13B614BA3B1CA7BE20B91905 +47D1F16C +DE190A1F1C218E61F78BA251E0 +0806A73DB4603E907929BF548A288C4B0356E1FA0AD5B33C07287C7467A17B6608EB43A2EFB0C52D070B7756A84429AC4B2E5D361ACEA55C +AA526226 +BCC0E30F05FFAB61766B375C6F +AE55DC2F2D18B9D78A20A25021E0E9AE8D11A81E43D44F8E6877A14FB21BAA25F19ADD90B999657ED156EA25035B6C7FACF646B4A4A37FEA427EC0DB57B9D191 +27EF549E +B6A436D0AC658423A2BB8B2A51 +EC3649375FE82663F00130987E14C0E992132BBFE2EF9554EDC3987F315996C501337783A3BF55BF9A38677C4488421B5AFE394CCFD29217152A8F6E2DE5AB +FFC92697 +75E7A86EB04DF012E87B61DABB +252EF91E58733052EC9BF021C8769B210130DCD54AE252A067DFF45004C1F1AB967CC8F1F38F213F786A7F6FF4635AE6A0E1A568FD434A8778 +62B2214F +4576E1C12772565D8E18E0E8FF +AC59C2A48E1236E81B839E99C32E5410CFEEB6FBFA7155 +9C7A722E +72001066D53432D5596AAE6208 +F189D8CBCEC3C49FC7B38470064177D8D99F7B19D550CE83722C9564988EFA +B793F0B3 +DA2BECFB637C5283E9AEA452AA +B51A8187C501369F1B7830CD4B94565E10C970866EA82BC927066F18 +054896B9 +487B20B86C483658704534463F +25D7CB284267DFC26DE0CD20A17874E787A8DA1BC87C74501C9E371232AF55534B415A762F0AAE79D77C6FA1AD368481A479C5B7101174B5178F26CF80C0144E0ECA51541E99B1491033 +46AB464C +055025CAF0402F89C6D7063F30 +CAEE917FD452579219349097F706C637E61828D00DC275102CD703DFA4D1507181CC5139AFAA675590AA3A3452D9F6D57906D8CAC54A77CB5CF672B59AAF8B +AE92AFD8 +CB408DD92476913EA3886CC434 +55C6C44E3D96645E72BD9A78B2923B11661E6AFB8222D781CD2DFFB91A4A739D478F59AD047DF482BAD1E636786B29AC948C3C4BC0FE8E87B25B41D220EE546AC33445EC6447AB2ED2D80396628073300FFAC8F914D15F6A1EB0 +0CA0F292 +D53948FFC685905C7AFE83EB16 +0ECB4DDA6D181C76A18EEABD5F65ED4D0C5BE491261FCAE3AF9C7D285D73060C304EC064911E94B93CD845F506473AB2A41F70B3E63B5B0DA4B0 +8EB03A72 +847130882184E9B8B82F1B2437BB +C4295CCD132916733090C02AFC98793AF3F79E3D40B37338456C42717021770A9B93E9427E5F8F80346FC8E481F9C1CE0F0B740404B900C0AF1E5B674CC55854171BFCE3DF4911C4DD43EDF4EC5386E3E02C3D4F6DF676F1D39B1017E5FF5A909904CD95503D5EA18C100D932DFD0285637B1773766CE8807F09 +D4DF5196 +0883444CE9812737D7544595D1 +EA95290120904283FAC63D4EE8F736EFFAC6D62C40E518274FF9F3ABD46A021755FDE144F4063D4A12E55E3A4DB1CE61137012D53F44 +4FCA3938 +D89DB237EA3D631E455EA9D63C +064A8F59AB7394BCD5A4C4B68A2BF0083ED977A5B0D96994434E15EF199541954B905513 +AEBD4E10 +023FC89BD2763B03292ABDC14DAE +A66002AA4C74B2A2242BCC4AB9EC30DF6AF2E2932293683C8D6C823A12F404257AC79516E1556BC296234044826F559A2E10A5225EB42A1578A42DE26BE594FA641224F3CF1F307212F5AAD36CBE771EC5BDB48F71A4CA83556A57CD3A05570B9BA154A8AA9399BEAAE5C56028D059CCDD02DD +F1B8E5AF +0A2C437CF01E0D860FA8F671E3A6 +0CBB746D9E5E4650E2D6916ED8427C6B4C6E0075E60E19D0C894757EA70B008753D7D04601091E6CAD4974278579C2CA94953D8AD65C0A5E21CA82E60DE65831A516938D840DF10599300C444AAD686A66B764CC9FF67DF4ADE103951236D373E5F9FDF869A6998E9DFD01448174F0F3014F4B49AD1AA31F860EDF23EBA5 +A890 +DD +62B0EB9D +F20DCBDB35EDC076C555DDF363 +79673B7F3EE89B9AC57AF5F15D4B99E39F9CAADF6AD4136A2D22FFE5C409F8303E829E32CC8032DDF7A2CF18C9AC97B98F8496115343E1845FBF15149EE2EF43698A50F92DA0E690ACEACC0E3E121F836343D85969A1C65EEC4BCFC5A909DB5F56 +D4BC843E +FD62C683B953C590FC8D774693 +C4537361BAA94A7F8F99846C9CACDF8787C0D6C9D2A04333530B982432DCE3DFE3EC6A2CF71FCE86B283FE056B06348F9470412BD1F781FCE71E248A4A6F25F04D12C03EE753A89ED69DEEE55296EC753741302097CE0F7CEFF6E4AAABEACC42BE650F +9E37951E +60B56EC565F09D2356894CBEFE5B +D31C5B141A45FF7065287159A5BD6DFE1EC4259402437080E3559BF8B0CF3C65EBB47FABC52222782C1EBC6054C6CE334800B435BED9E2E4F8841A189BDD5EA96247C23E04E20818A57289578C2BABBAACA5A0F4D8F3634EC6963D12DA7B5C6B8E80DAC571AAD3D3B35F21E5E2EC91107C1CCE85CF032F9625A077C1ADA5 +BBF980B5 +25BF12146B313E28757D104202FB +3F677DC45B3E5D71186B905B867E105F6CC4FD794A6EF5E331E604C85D2FF09D8AB822F484339F00718B946AD698395809E56F21F0CF5D097D2CD188CE082C35FCB1A5674BC3929E836493E373E7C1F4CB1DCDE0CCB03AB20CB908C8111F89A7DDA41DA3A324A3CB8E2051E745C077C55CA686D823DD07F28AFAEAD1E981 +A55B +D32E257465DFD4A65E9659 +B7A1E5FD +AF4A27B55129E96F1683149BDB +16A1AFE77036BF604C748CA1ACED488CA752253ABBF58CD2D2A40ADF75365A0AF38C3F8C6029A6034F465F4FC6F894E73A97691307C528E2FF8B82 +12EADB3E +33F36D418CC9BDEB3A1DF278C4 +6A4F26DE811338DE15892A89C7F4787C949409800660D262D11D8966165C5740A2CD8BED226EDEBAF543FA079593A0CCFB5DD2E52A57B1D6227A7BE8BD2C31A6581070DE343699 +12055C4D +B25B0FABE96F72FD5E335A901414 +67A71207FD500CBE6FB5989675E03B11DCC7CFF31932C6931D8EF3CA2D1E3225F169F473E87356BE69D28C92B8A1BC4139F8F8E22CB9F783B831054C2BE1C47C903AEC3285C7D272CF1AC180CA8F580A71445B290270BBCEDAE33D58DCF16EEC1DFB6A9460987C9069C7D77CE758AC +3690FA6D +968AADD808DCA6B2D15125D8A1 +89FBED432BE53141BC1EC9FFEE89A2094D8E7D3FEEFDE7C576C8E0E3BA58875C519CCA9557F018C40F50726A45119F8C32795C692A4E2C53A6C2BF665E0C3A7D0BF6BC3E50E4CF86C5D31D7652039C5A77260195707F8E8BB7F41682 +35963C99 +4DF85C133C7A9AA4CE274C24B6 +B3A684DD049585B0A4F58BF36FFE7D3C8B213AE45D6DF029A1E8D09A7345C59BB4E409E782443E212F7247F340B324A6DE05027774AB389C690408DD04C633D1025635F4C7D90185880E930BAB9B0CE187E1B1 +759DFECA +C9B06199EDAC577E78609C7EFD39 +38553AEA1984A20373E914CCF702DD196DBE6E71F2BC61860C1698ED9CF85C337031A3CCEDBA4A7301C1B1EF348DBC99775171284C19DBDB976EE8A4AE6DAA0E7DBD1EE0A2DD7C8F07B1E0D1DCBDFBED127E870BCB6C239669B3D223683877484CDE61BDF0D4340A6AA1 +B933228D +FA201A8BF198EC4D2D1F2B6EE7B3 +7D178BD4354045A5FBAAEE99933B132D88E3DBCF8378A3503D037B3DFFF0AE3706D92A86ADD02F077EDBBE2D565C7E1582D42A5F642693F10231AC96E9B5C6B79B2188E3F03075FCDA2CB13B34CD7F040AFA9469BF22F122598C6D5EE59A7C4DB803AE1F3EFD0BD516402E66CD886A9E31966989D76CBDB47B4B4D37D915 +8A812E25 +38AE6BC649239252F489036EE892 +512430539A20674D132AB7C79B2C202242B5E556B59964F3660A226E651B9105328DD7C26852E02B31128CBAFAF6E0D6F0F2F4EA2DBE7E85E6E97E3717C66ECC03DD43742BD167B691EFB8F077C10D560E3B3682B47B5592F9B4624293ECEE7E515099DE64E617BD391AFAB540609D74FC7DDFDF06A72A35ABC703C0ABA9 +22C8 +489BF1 +DBB20DE9 +4FC6055C76E8AADE13C87D7082 +371D3D4814F5CD4B40E305BB4177825D9629FB6A47EFB31983BDBF3C08479367A9F70460B44F5652123759C75DD66B687AA6B69D9CE9F0521BAAB73B6376FCFC9E688AE6289163E6951EB5235A4F5AAA16 +B649FC41 +2EFDB718D2BC0C8C4E1D349FC6ED +24879F0203C255C3C383C2B2385AE2C08BF91082EEADA822511190008FC1811966A646182E71E517C000C75BFE956DFA4CAA25C33FDB4FFBD14F0EC6543F845BBEAB37C4B081D9A9984A4BEDB580AC31845E7D7648D293D78EB9799860E554C5595A9525 +A0A30989 +3DDEE21ABE796E81B4C2CA5680F6 +221172524C03D51AC631EE60B68EB0B44B57FCAD50C86A30A667BB11F0FD66E1F9086322E632DF39D1CDF6285CCD3AF06C0C351279BCBBC30F47B8518CCA88B7D75062053D67CE00FD7EFDE69F657734CAC7AD847B3D4ED6EFB1A75B948D033BC0729CEDE9F7809F66B6F4550699EADCBDB060A144A81E356F725328D154 +AFCB +D4F4E206588AB9CCFB14DAA47FC3E2A8 +65917D2F +5760FEF5830DCD6ED57ED9CC027E +E23F3B3B5AD2738DB649B3C674A9C58CBD127074458E832FDADC2D8ED12649C0B2B8A35DE5178F07E7634D5A13C437205F9D2A06A43266964B3025896BFE4B512F7C49DF7F627909DF30B89E0556D30DA118758FF748D42EF7144B6145161910632D7681BF338DE26BBBF07C3B9EB919B569611F0B1F20DE132A7C52D899 +FD35 +118CC1708A82A8F7D6DAF43790A0F1D4A054F1799431EE6D2F5E9B3518ABC6A92053EBD82E3B20 +321BF9CF +947BB79076020809AF6FB3AD6A +C55575E6E7FFDDC08AAB28F78CC3BECFFCDDF1809301 +269E7A71 +786538B533E38EDC1874C3E020 +5E0BBE0320A3E02732AACD76A228C71D9EB1A563F5D1335781BE1F9E1B5B3BFD9EC68D8A20F9101B366E23DE69B0BC63C6D2ABACA9BC7F21E65A +D414A66D +42F7A3D26A4F30ED16ED5DFDB1DA +E428DEA1A72955C9309D87295EA289D91EF5A8386014D71B5A69795A61583F35D0DB013C680B775C514F7C36C1C8605F9421EB20F1D6DB3A05DE834F45D9AE523140FF22204C05D99ABBB5E0C5EDF3D0AE7CB110AD3634FB2020B22E09988289C6402F99E6514197D9DEFE2E70B3B40FBD878EB5F866C1DC08A7DE718262 +0A75 +D2F30C +14DAEBC2 +E4305DE7C85F5F81AE85CEC705 +A2EB89D77310C0A678E651C92DB92B41F144F4ECF49F6479698E042F35AC6B54C9BD1EF24455B6E5576C54441753E0456BBDB45CAD2AB17510DF773B35EE0ED115B92A84AC4DE886574090105016465F5ADACF83CF1AFD87 +0EE5154C +6FF272B5F176BB5526CFB33D7C +6D034EB8FF0AD42B75D89989A33ADC8F5CCF7F63A7852E5123AF2C04843DBA64AFC9539FCE21119962699D05807AC0A7296EEC53D62F194FBC2CB2F84315A86AF784044A336B797D4D820EEB4231A85FB67A +7795B98C +B3446F5D4FB1E86C9A061A30A0F8 +7D7BAF53F76D4DE2F6296ABA441EF3915B09DD2856CBF99BB9515C71D5224DDDD5BA950E8D656AE79E16900105EB1204BA86FB6E1205FB6098B57B01C921E6C4B5C50DDA15D43BC41C5CEA3837133C90683D2826AFFFAFC3CB91938DF31DB598B4A807876B34CE4B1A6FF4E1E86E +FF680239 +296CB462A38EF3DAB9E24F51F3 +B7FC5C8709BAA1FB5574ACF24E033C4AF93E2241F6B65CD9ABCDE90A7A4E52F04F909F162E6E6A3FFD2DF5BB9B760ECB9F93A6503AA230E45F76CD4F4C9F2CCF5C14C26AE218A960FD1E0C6B4AF4839C56FAB362132F9241EA +B30AC889 +516B1ACCDE6772222AC5B0B838 +3ACFEE3BFCE225A3519634D094EA94EAA18AC5A8EC359F6A4990E684A072C386E98CA795E0DC3574B3B3409F28F997F90D6C7C3A6A5AD9A3914B8A517D2A6B4E9E4124E46293F849B9D718F48A41056326509CCFACDF9767FCBD3B31 +8FAD59D0 +AA88E9AB4144BBE075939B8A1306 +AA744841837FAB63CB86C854F4651DBE24CF93578FE8FC0CA7B9878FC2E5EFE8047478FD54523E0859481ADB65F66A4FDE537A986112BF1D62854B3180CCB69F2CD63C9E644555351A7EFF8864C4B3B52D6F8492F0DD5374F567A6A98587F32919E4366EC6C33682F561E817E6EE9AE3D3CCFD7C0BF110D0899A12DE64FB +A2DF +5E4CBC772A23AC0E960FEE63389408B64FCB3BF5362AD6C1C899E081FAA315957CEA3150E64194C6283140062073D5 +C7E488D3 +F4FFE6ACF4758FE2E2D27E2CDA94 +DF2AC0F905518317CC4C482EBE9C62D79ED004D68A046F5D33E32D5C8CFC9E271C18A52D82FC2E2E03969523D0312D8F8778FE143261CAE5443866195B4CB681E9691A80A7F7C3199561510032E19B8055CDA7CC7893B775962D1BA7D4959C9341C835F231FE52BDE7F3167011 +C3FBD07D +6944D83E66E1FCB874D9F3A906 +8D32ACDBE821610F617C3F7D2E5EC421E5B7EBF9E862580E3BCD4BD834180EDCB6BBF6C295B7E3640310E33C28D2EAF82000080ED3026EF41459C9E86C29E0441F365BBBA0F7F84B2D524AC683CF857E +ECA40FCA +47226F1F77B1AB0FFC9EF716E605 +799F380054AAD4BE27D10C1DF193AB01F422E4E8AA760F5299F4AFD20CF14A8931959F217131E5AB8711367A71B85C5572A0C0C38B4924BDBDB30B5D98CBC4230B58217338857652B4260CA960F4205EDFA620F9206827CB036BCA1BE92F0AA897A863F5436271B2AC8A2D4BD5718703535F4EB31A893A2179D94F017285 +0A3E +C0A5FA0352A2D24824F8FA320BDE033D6ED7E4D8CAB1C5F6BD35FB5053BFFF326BF811 +544CDBAC +27B5C660E91A11432058B7FF16 +6C507B493EB4528675C25BA0C34F19B2D133E776A7741115E33B198DFEC2F7083B37E8A1BD1D73C92E58BF2D2F3F00F4566FDD210CDC +3E573D11 +3AD4395A32C2B2F68114C044731B +6DB80077DD324BBB4BE735E0B93C94FDFEB0E5515B136ACF85337A8EBBC04CA5B609EF14B732B6BFED24471DF0F2290162EBCD08CCB0E45BC82264E0545DCD5E7E2568A75E826D33B3929C53485E35A0C5452BD7BE1438BB59B6EF146A606AFA934DED9B620471A19E8B724876A9FC2C67F20636BEAF0495A7ADEC6B6AF7 +072E +D4F170DBC9ECB11D0CA3632E0AB4271427F585696912C01B1EC069AA597BEB +80E589FE +54982C78D338487B82D4B3D5003D +79CDA61313C2EBDB3D85C15E5EF6B4A88B69122573644E286F3A622D1A79B0F85D1761AA9EB07212604BDC14CB34DBF9640FB377839C4E109E646D82B791FB7C62DFD7863D663D7F0AE4D1FCD43DA77CF2143AB786135694A3D7821751B6AE4617E7D0684D5C87ABCA45F1AF +41AB4179 +27A564DD52B48F0AEB6E66D203 +97C46FEA3B7F7D0B6B2AAEC0F613FD014BCE1E4FA0EC3CEFE4E8941A24A42D622645276077A07A9C90B9121E49DE587496EF4E3C0F6B523BC4363B3FD3EB3D2A8869B0281430 +E28E766A +3CF6DBAA7BF3E518C34A364D9C8E +8A7E042A3D468991DEE447738B23A27262411670AB992EC78E90B467FD332279BCE9B9F14E64C7959BDCDAC8BCF70BB619EBE4CC5E36FA717A1AE5A42FC0B88B582FFCDCAB4AA3B679FF38E13A7E4A636E2A2CF104F0CC2C01CD679B12F7011978F897BA0D61718DDE0BE0E2B01A1833F03C1380821A45 +B5F2B74C +E0D55EC5259B96316DB10F0D8EDE +5E0BEC40B34A4146C2541D3317676D082DACA6C60C94C7AC9F5CBFC120A8E488503D8B7B36E9BD3F821958D82D70D6D52F78A8D11093B01D3CBFA62F02B6D8AD7D9E58DE275E304BE4BB51AE67667CE4439E072F2FBA32072EA0980D633A8A03DC7220AA11DDDD597E40 +BF0D4316 +C23A7ECB61630289D7E57FC502 +03EE6EC6C8CEEC10CE72304E5421F3763F2803FD09D7F1F4E77BAF6606425D680A904B01BE0BC986013711C4635932F8E60B06354C2FE1E3EA4F18119B94910E2D88DEA70D513CFFBB77CFC39A616172D09E379112C106 +8854A47C +DABD24B7AE0687CE7F365D3328E0 +CBE8D4C55A40FC9F3D84E04CD78801DAF49D63781A232EACF32861158DFFBE3CF14FE52569B29BBC71ED22247A34BCD6CA98B6CCACC55102D6372066CDF56E7309D6B043A9C8E90CE10FAE59239BEE265AA264EA8E473B09C84D3970C569FB7175256EA3A504D9F06E3B1250C5AB7C823DE20228481CC29F6135D637 +1D21D9E5 +0B4913DB2A8D2A628FB6356A4F +1B01317B09E24CF25128D77A879D254E3B456AC4F39C520BC40CE1CA7C1A53AFE017679749E5CD84B49F18E26125EE6AF4204272396728E4B131E081D4BE846DE341BAFF64 +C3129799 +A739CBCE232BA8F687BE6C6510 +4B2BC60D5ED635F9B9CE3BF8D9DE2A6FF23E449110195B06A7DD8FA3A4D53EDA5BFC9B921D9E5BBF87E8ABF735C20424C95DDBE13CE457DFA4F6E9E0B466423AD1E77D884A2C60E6FA19D1463D8A61EEEC95A944471BE37C2AECA3666E169F15E021 +BDEA294D +3AE884A222F6D7D7A5ACE30573 +3BF769E794E86A6F6EE26821706B794AB7D610B5FF99F83F55D22784CBECCEF2F02D31350DD90AF5869C71A0CE403758B734B9B1034473A96786618F02AA059E522D1A99326358433681F0857867931CA5B1B3B4A689C3A1C6 +8655B94A +5BA12994BDFF8D159B49B4749884 +F96854C20E172898659198D1D9A982C3E1A644831BB9335D75709F646328489F4ABD2D1652E1CF6DF3182478A996DC11BE6B7DA41822862CC8FB87E22C7CF89B00816487F42B98180EE39AF44A197E701BA9DFE952FC932BC5484ED49DACAE58DC9221FCB9009AE87756A8DAAA488FF375D348244803412EBF36BA13301F +EC09 +5FBAB9F1478D7549D3010CF1CD01 +0772A02C +BA911DE8DF40F32B0760103E6455 +B244B9BFEC0DE8F8E05853DBB320EB742F6AD3F9E865C691B886919B48A437F7BCB35DB06C27CDDFAFE0E0523725CA21A2C3190818A53F1F2B3EC717FAE067F8CB89EA43FCC6E4EE2610EE64A3EE44E08F3B76DD13E20F6BEDA7BB02C06882524988E7ED899E035DEAFD2BD2F2135010BE92D3E78AFBA3A05F40FCEB9927 +C6A4 +0ECA817530866ED377B86412E57F2E457F7DC04BA739698510 +0D21060E +046442276787021394BE5717DFE8 +746921455D510E9BA0369170132375A1C5FBB7D3804D4CEADB932F9A21798109BBBA92D403872A26E00C823553D65430D926F09472D5E4888463CB072C60720F9303B97B1CF74E0036D7EFFF8C96FACB32BD88B3B9B8B0C664DB5ED38DB2379ADDCAEBF71AF9BBA2622679B95C75B21DD5FD5AF6941ADA38B2D845262873 +FAB3 +06D0A562 +F3FDE3CD99C525DD7E0932C8A8 +8AB1CAC05FC7C657621805A554B5B7A4FB42FCC2A14D8BB6C95F4118EDC24E8C5DAFE27CA4172A3FF2DAC3B1B8C4C2B5DF55E0985C6094C4597FC0474BC7EA +29D3BDC5 +2918216A91470DB2B1413766DD +E50E614E9D4A8324D35C0E3DC79AF42FD5D646C1ABF4 +EC560D96 +191E93C9A8D5693DB5E0DDDD7AE2 +A28CF1A28F2A0061 +774D4713 +F81934CA1C03259739EAB1009573B7D02116C52A25645EB0DDC4D1DFEF3B2942560E +108D1A9FF7AA760618C674B64BCB4A4FC34EA68410D82E076B1BE186AC7CB82BABC2A1FF91E1 +BE5BD85804AC3500940BA02BBEBB1912DA7910694225CBF2866C5A +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +%Defining font PSOwstdutchb +%!FontType1-1.0: PSOwstdutchb +10 dict begin +/FontName /PSOwstdutchb def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001000 0 0 0.001000 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 1 /C0032 put +dup 2 /C0045 put +dup 3 /C0047 put +dup 4 /C0058 put +dup 5 /C0067 put +dup 6 /C0068 put +dup 7 /C0069 put +dup 8 /C0072 put +dup 9 /C0073 put +dup 10 /C0076 put +dup 11 /C0078 put +dup 12 /C0079 put +dup 13 /C0080 put +dup 14 /C0083 put +dup 15 /C0084 put +dup 16 /C0085 put +dup 17 /C0097 put +dup 18 /C0099 put +dup 19 /C0101 put +dup 20 /C0102 put +dup 21 /C0105 put +dup 22 /C0107 put +dup 23 /C0108 put +dup 24 /C0109 put +dup 25 /C0110 put +dup 26 /C0111 put +dup 27 /C0112 put +dup 28 /C0114 put +dup 29 /C0115 put +dup 30 /C0116 put +dup 31 /C0120 put +readonly def +/FontBBox [-18 -207 798 694] readonly def +currentdict end +currentfile eexec +D9D66F633B846A989B9974B0179FC6CC445BC7C8A959A39A32E9DCE7FAEF17EE3BEC9F +50E1A6FCA651FC4B3769A0A91041557502E25A5D6180FE25A3D11BF079E1DF66E54EE9B7C229AF891739707A2A0EC140306B5E43E52B79BFB89E459E50 +6EC6F610A70775A31C460976C4F79449D86E57ACE491E5C6BF20CC4307B1DAF7630252 +E9AF8CFB69B50EDAE9D36A6104AFEF8832F920FD2346B2C7104CD11E3BEE999CFA9F5A +49DB3173EE48D1C82994237F360407B022E0B4 +502E94EA8B493651EF2D03F0B513D655047568325B512AE6 +6AC6F53F3848CF70DE25481CC65D8B1A5793AA +3C4282D111112BEE28AFCA7A3808D4444C4669CA +84EAAAF989219F51AB3476A1B0B5F2246BC306E6 +625C6679C417ED2A8E9BD010DE37D40265074C2684274F521011A4FAB2239CC4C91F3E8514A0B1 +D56D6AC921B6CB9A95B5862C +96EA1243D6ADB73380 +FBA81AD5 +E671873831753B062D54870AC3 +7B86DA813713423C616B752F5B478535EA51AB336BF262 +0C12A9B7 +403688BEE1DF831990D942C145 +C2204CFCA477A2FAC1D6FFE48FB95A72E07E007A65A551329FB6 +E5CEBCA4 +21AA703D56FA9FAFC5608660AD +B1585D757C69A9EE103F01E2132F3737A9D187F0AF5A534303F5DAF1811F42120ED37E37F991F2C317DD6B92A06AFA1799FE91B6647A +427E8C13 +CF60AE48B5D903CCC2A571E90243 +3EFBF02E0CAF3725E0447BF9116C5E8796E814AB8CD1D60F5EAD1CB6DA3F72AD1453D6A3B7FC37AA9F3C1F673C557CF175AB19DFF8F452F21DB9C2391C109FFE647F7C72542C4EBE73286F582056F2ACA45770FDC609415CBADCD01BED4DBE47CA0C9E3EC29BF07B +981F45F3 +0285EC0D9156FBAB8E4AEB40D6 +8457BC8DA71322B792B7BF4DF72AAD0C9345756144DBD263BEFC4B0459BC36FAC365B2CD2F6DBCA6D1FF1FE49440C52CB0B278480204707FDCD84B2EAED85852BCC34A45C21FE958A0E4AE303C55CB735D322CEFF5A9D3 +A150332B +052343C0B15B7ADE5334A5217D77 +295DE5EADD586D73C511A9CEA8DC02ECFCEE966FF3D5738719490C6E1E636CE0D33E3D8481420CF1E07FBD6BCFE69F321B0320114C92FED2B69A83AD5C1E5C31D667EDB7E54112B35162235CFCED5CA6D5BB7140C151B873E3CA8E0BD78038A90AE89FA31532A8920E38A36BD94E +201B2094 +1534C53E83D40769D38884D515C0 +D9BC826E558A2C9DE8BB6CC1A442524685E3FB5B5847273D8105A38FEFEC19B0A02707F9E4C433A8EF9A570EEE4B97429CD7064C51CAAC67A8D831708E1ADD02F1DA86DEE0CEACF2A84303A0AADB3C0CF91AA4852BCCF2D1CB645091946FA7F6172339B08B85F1EFA5734509AAF6F2AC352F1C3703FF6C +B5E84E5A +EFAED557567D0267EDE57C27B1 +DAB7F691C64104213BEF6884CF749D2A5D81697FAC66784BFDA32A6AEBEC2B1145B4E3410C705735B95FF488873A43A269877CD9A4B1BE4E6423AE16E4C3 +6702414E +04D095B4FA98DEA2200FB1758B +AC67E1429D4432F6C35E05B6A4A71C1ED8572C91510466D1A29EE19B40D69791E68852149629E2FA3E0D78D7BB6E9391211DFCA50049C534AB15ECDBC32BEDB04F9818F5DA86A43E2D +F2D05F6A +259BE50B43E0671E33C148B5A0 +52196AB02B9C9F419DB2656FDEBC17FFC788076895DFF67274E565091383104A257B9AC93C94636CEEAEDE3535B76CAAAE6DBBBD40D0566AD927B54066D980B0BB3C52675FD8DBF1D80B14DC2CB2303FCE51096CB03BEBF5024F18990D12B0 +BC221E67 +F07479593189ADE9A16B4B33575A +0CE6AC3E83412C4B0B63DFF024434F447D14255F2C6192E1CB8190688E70EF481D9AEDBBD7DF6D8A81927B5F3B28A86F1A1968C5285FC1545E1119AE6D284FEC3B6F6D46B6983E96B0D46EF8F74E045FE35777ACC44B43353FE3E5E3EF249FA9660C6F6DC39F68D442 +2D0959A4 +EE9EC51DB6A0FC55D2715A2E1EE8 +BB1E27177438DD60E3E377A4D6431D9ED50A8A80BF3FD0993B955D5B58776EF2C396840E74E98EDE772C00B63FDE9DDA57A0DBF55CBCD5BE6B570336895F76F9644917DBD61ABDC3F77F5F0D02D3D744832FB984E09519AC3507F71FDCB645F72D1C2E5F +C806DC2C +E55AE10907EE80EE6E6A75EF2CBE +D9F50511D03075DEF23C05C2C38D116AF653FBEE2E56C50749F2047788C4E09886FB3441588F2FCA8E148993329F4408B992215DBB883D67EED25600CA65F059F1C81A6E247F3490BA2D3A0403E6387E0469D35FA5EC6288C5D852FED3683A10371704925FA274C28B481804233BBF7B3F49A619191F8736D4273FC1A59A +DD6C +FE248CDD +7B5FA42B2BA29971D5561EBCBF +76153BDF2110F26CCF789F57FAD656C41FFD4E73FF4E5946B0A9449CA5D6E3D5C89F4640AF084C66706FB6C05A5C1C9A5A9D9EE69C121057B5394D7BC85795CD2105E3BFFE128D95FC +E4804C3A +1EDF8DFA0FF8DAA14815A8292504 +F21D932C0DAB2230AC5CED2F3EEC6BED0AFB45BEB9C5E3210B1F7CD61A0FA063358D8F6F1A174FF3CFF1053023F7FB1BB587F8FAE14FE0120B90D0E8E24969931D81EC20FFE56EED4AAE376D2BF4C96DCC3EED95DBCBD6BA9873FA7A1833CA1566C3E95926C53F +64E47BEE +2673173B1CF1657876E4A7C5FE24 +04D77480D7D26469114CAB950A0C00DA2F51281FC29CEAC5953776062F6A95D19AAAB00AD9A6DA6299877E4650B8450377497456A5B3F1A8AAAACCAC603C518B93F2E674FC1F6C72B26FE8B8FF054D60B0C1842468B1F01E42C4E40F7C52E8DE26211EDCB7D283C3AA9B741D1C3C0611F7599C0368C91CB5757C9660A970 +E23B +1EA40D4E +B5D18CEF +D7D0A4A4ADB1AAEC4F97555E41 +856D173C4EB2D4AB007822B263E92E3D9E1886A03D46B8ABABD6925E2480097A7AF2C2902D0926A75D9ABDD895EB16AE4A195E248292AFD7917C95C6B59964E7F8DB71D093018DBFA16038E6DD703FFC7082 +94BDF830 +DB530D872972D0652F0866A0E6 +E9123448946D240AB15BC097045B06569D4ACCA01E0729300667C68EDC9A61936276AF4970811B728266BE4F9FC96D14DFF78A74D547E8D638F9F325818C67E4BC31263CB5C8BF728DBDDEA8A59760684F5C526D53FC58A17AF2D3F8 +BF2FDF88 +908A7CBB2ACFDE64758D19260E +8053E9723009F86754C230BA777252DE21EB63E7DB19025527BF25B0EAA166B3E389A4569301BB104D5A7634068625F3F02880D9B0621A4996956FAF84E3E3897E616ED974A8B7A30BB197D41F217D7F2C3558C30C1F4BFB3356579C7F +630DA61A +143009FFDBC59AE1AFE54676F8 +26D7C8EF4DEC42B0C72FDAA7FB4435AB3FC20BDD5F8A431C2B0D5FBC15B20CADA36B53B8108E9C45E12BF3F0AAF07DB001A75BDFF66B66988579D80012EADFB3FA5EDB40E96EBAFEAA15E86C9214 +01F5A683 +A78DF7C361C01B21660936FD60FA +010DE7B0A20242BFF0643B55CDCFEA5C1A0F7BAA8417A89AA5DC966CE4F49E416E4871465A25E67772E80CF90CF9F8317392DF7AFCCF6C61D5836574A36CFC3A07635E174EC9F209439654C2446F17D4F767FA7762C57C71BFB5567FA0E1AB79B754E7E70FD832B2B69A6105A9ACD6B2510151D0A116D1B040419F9D9E12 +77B8 +44BC +5EC3968D +8CBEFF4A5562B36189AEBE2A5C +045F150136D7D0BC12F0B0DA14D420C08B4BA5B6925DC37E66A3EF4AFAB497038C135869C29A9700F142B59A07C9A2191333CC07 +CEC94F6D +FE275C51985B7C42444B8A39B1B0 +F1EBFB46D8AED46B42DA4996742C748656FA973B65568182FDC374F09E18F3495A40149D06F92AA1D9D2DE8DC1AF152F58226B5A24FB5470798E60CFA880255CC4632594DC689A4A960ACEFB3399D748806625D241F0211F9C3405106778DE6A88F77BD69C5F2142B7D606BB96D5B87B6AB32D82D1E526E198DE1382AFEC +0DFE +CFF09A19522D8A2BD59F70198F47C46F4C65896EE3A2B1F3C927A520 +12BC389C +9C0BA325B7AF22E7B8A92D6CDB42 +9757D2C2E17BF6080F4E021C90D3C12FC662633AFA78CF37CC315290093DFAC727B8C3BC84C5A0975AC1E15FF9EA5D9DDB8BB99DE8CE203AA2BF6AE196A4468B77D35D7074B0287EDE1327C3373A850E192CE8F83C27CF6D0D588D0519EB056236F1D3D06BB198 +1B949F38 +34A5506351DFB25D96AA8B50BB +A0F69C640F0F9819336301154A484306EAF5076DF9B266543C749C2B99B62C9A408114A6BF33DECE7A2A6CCAE401DA1E84542EFFD2DE6B264579BFE23885DC0741AF7504FFF5 +C6B8E840 +147233689C8FE18C9FA6A5F41929 +D75D3B1EDFD19AFD2CDA1F69C418D5BFD2941A8745A2A6045757A79041E08C35FFD9502E00CE541A7BCD47F27795D629B280A38B7D6F494AE61C73E802A6B0A7F17010E0412C964A5BB7397A82842125805B93DA088D9D4AC582FBB54626968AD5D7E0665295FE08B2CB292F6B16C69281 +F4E83C89 +5C8E0D7AFF7183A53638D11BF9 +A3E8B0E5A561C225128BD9247A2A5979478F20894A8AF3EB38832C4758E4D919EB102EEC54AA34559E97C574769428459DFE0C98EDD5B1D5A1F21B210E18D6A8B68212F5D10DCA3011D871012D2AC4BABC0B14CC00C1D578DE +BA686FDC +228C2CDD9599F0D8AE2E8DB58351 +615E25ECB209EAD429DFDE573CB6FEB80AABAC22CBFDF59D1B3FA4533FFA53B27E3B279BDE26C662A3A0075893750ECB1BC773EBAB727D6CC7F056D945488281A4319ADD379EEB1A632ABC6CCE0E5A08BD0425166039CD8E9736BAE387E3449F1BB1DEC0164B4D6AA86C82048F35A6157A15DDDCB0D4015CB7 +35C2DDA6 +B07520E6813138E002C42E6D43 +38EE5895AE4743FD26BCDD579732EC528D246BC226F9800F021F8FE624FF89F70B6B854F212B9E171B0DA54B1814E8C124FBCE8BEBE41308BA468726ABCEFFF292957EB6 +1D0A518F +3FDD627C6F0BDB4877FEE9DD3855 +05F1A58957324ADB27EDE6DFCC99C685E6BBCE3A6C8128BE911C08CBA3A0AD8FEB5248C881FAAD3ACC0B1E0C5DC551CF7BB27EFF648FDC8446B1027AC729492B50056E37FABCA4C58E737C3C03CDF79CF5EB7D43B2F982903021DBB4AED0E65684E53D99C6F8A396DF53A60C30DF78AA4FAB1CA3816E6EC5E925C62EBA62 +793C +1668536F209D0C41BE95CF8C2AF2CE6B287DC6C757CD +9E594FE3 +176BF3EC8E4A445F40099EACDB88 +F80734E7790E5F66 +BC05A365 +C82C725009BE481AC42E9FC33D4A9483EB589A4419F61B68FEC5572A7D8129CA5E08 +D50778A50C2882CA1CE136914408567390FAC1624E1F7C1B5D8E1D03F41B31F5FA113427D8AD +7303E6D75AC639BD2BDE7BA81831129C0FBFA8DC30FC228B2637D6 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +%Defining font PSOwstdutchi +%!FontType1-1.0: PSOwstdutchi +10 dict begin +/FontName /PSOwstdutchi def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001000 0 0 0.001000 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 1 /C0097 put +dup 2 /C0099 put +dup 3 /C0100 put +dup 4 /C0101 put +dup 5 /C0104 put +dup 6 /C0105 put +dup 7 /C0108 put +dup 8 /C0109 put +dup 9 /C0111 put +dup 10 /C0112 put +dup 11 /C0114 put +dup 12 /C0115 put +dup 13 /C0116 put +dup 14 /C0117 put +dup 15 /C0118 put +dup 16 /C0122 put +readonly def +/FontBBox [-144 -227 757 728] readonly def +currentdict end +currentfile eexec +D9D66F633B846A989B9974B0179FC6CC445BC7C8A959A39A32E9DCE7FAEF17EE3BEC9F +50E1A6FCA651FC4B3769A0A91041557502E25A5D6180FE25A3D11BF079E1DF66E54EE9B7C229AF891739707A2A0EC140306B5E43E52B79BFB89E459E50 +6EC6F610A70775A31C460976C4F79449D86E57ACE491E5C6BF20CC4307B1DAF7630252 +E9AF8CFB69B50EDAE9D36A6104AFEF8832F920FD2346B2C7104CD11E3BEE999CFA9F5A +49DB3173EE48D1C82994237F360407B022E0B4 +502E94EA8B493651EF2D03F0B513D655047568325B512AE6 +6AC6F53F3848CF70DE25481CC65D8B1A5793AA +3C4282D111112BEE28AFCA7A3808D4444C4669CA +84EAAAF989219F51AB3476A1B0B5F2246BC306E6 +625C6679C417ED2A8E9BD010DE37D40265074C268425D7C73E0D9FBC2C51FC5D7A4C8466A0ACF3 +EF6A51E85881893F5F8BC8430208 +87F3103F7721E137FA1F5E0AA668B92FD52279E66C1F88E225F1D00525B03625600EEE9AA0F3BC774875C78C8DA3485F17675C49575996A73AFCDFC5C043FF15240F2766D360B295D9F35757882F20231CD23D4B1D44649FAC2F946C5244A22F62F98DC8900497DB880EE30BEC4BE3011C108BB1603FC9E45087B4C3F7B4 +380E +DB7BEDDFD810BFE55A51FA92E7 +C5E02760 +2FEA6E1C7BC816B379B9BB690B +3F1F8D5D13B2FA0CA13B32E231AD6701F85E724E73EE5CAB752A1F01924E57EC33256147A9D15C2BED13E5B9868E463D0CF97CF79520D198EF7E9A4E8433615D43ADB42E79570068860AF8163DFA32E1F1AA9D84A0589C316A75510753214517 +65B024EA +2CAE33DEAFE2FCFEC055BCC6E807 +8A53B445D923820C0B3C3B775BFA1858B494A3E1ED579B4B7021B2747CA7DB9BA810D03C123860AF732D6CEC7A174E5ADB2DF2C48459B7DA91099B9EA4DFD27060070047B8FED57852BA56F0C75B09D95315841A1D637002612F731AF8EE4047DED5D8E53BA552BEEF5D79070B6CAC2B68F8C835BBE415D9474FE29393F9 +AFB7 +3168F8BACEE4F753E5374F9DD54F816F2FB16569CBDFFE6BEF28AFFBA96E6D1D41790B9AD5A71AC47EBBF08AFD654A41 +BBB9B934 +32CD3EA43C3D75650A026F94EE07 +8C9CD2519EF572156B2F34DEB76DC76BA9B2709A6DD78C558978CDC791BF43681BB7AE9328BAA7B284BEE5A7454C72A5CF2C9BDE94805A59FF843BE51CCDBFE69C9361EC6C491C18FA2616C75B772E614F13C38B3A7CAE3986D2B142CDDD1DA052556B0B80 +CD009F6A +B2638750700D66D0AA5810213141 +AC008781F399DF1A8043DBAEBAFC2B4AB596DA1071F3D505655C8C9E80FD9A1E0FB5F70DB8A227FC5D87E25B5985462D2E4DD446F8872432FA4BF7889A6B81AAC9CB8B818141C4D237D7DB1FC5D51A559CD13C935BF1AE639E261B83427841B5641084F6F43D44CB7DD60A0FF47E94CA86D71FC6EEF3AC18930CE91B00C9 +BD70 +67198EF0F55953DD826A0C981C7193E5CB53591FD92D5E3EE4FA3E +90B8AFD3 +BD7D1A65145E62B247484DBEFD7F +9A354A8CB2B1916981F3B04C446E91F9D7890C99E768D9FC4EA626D698A0A3099937CE0E16D26D38BFC8AF24914C1CAE2967D79EFDE69EF86E23739B46BE7C837D9D30688FD3748649FBF68082FA4D71603F483B057FA6DE45EF31154B6259F3B633EFB3D6A3573B473EBA1F01DF2CEDB0267012DC453BA300 +C113799C +D73D058FD325CCDFF91C7ECFC0ED +F5C1A835FADD3A33F90C6D40BE35C4C44C1E74A06BA5C213AC3C32207333F41924B722B467C4A262257C21398E3C5E1ECA06D9A0009E669507070150690D999B4B9DED64DEA22AA62FCCB06D0CFFF30CD6A3F21685F8AF43382540C00024B76FB86C21BD8F +14B44FEE +D45309CB76638A360CC3C52C3768 +33CC9C07A2C94C292258711A2E2684BD770223EE87E8E51500E66C413C885DD8F7B591D616E035D0A4D2422B02A87ACA35910E20483353B8AED8FD027ED84DADC927F04AC5FE290B2411BABE9819A1B5455C4675C02D586FBC946DC0D8C0D4565D47A4BA1E01767AC01BC99D380E26EAEF2811140DA4BCB2B6CDC145E023 +5577 +40C8C53F6C1D23B66FB4C547785165511FE75EFF5DF08E3A890D269542C74E76DCDB27338F578F7749E1BC5649B49C35D6EB07D8B2206582EF4DA5C871AFF0DC73D364F571B9C1A55CAD69 +A3C897FF +6AF3F0EFA51F761CEB5A096396 +CA62ADD641BBEB7F15BF71EE60A0769746359E6ED502D86221686F5387FAD1C99FC79EC3B67D26DE4791AB7C2E3A878F100DEDC77079DE9354CAEE593159DC4804840B346C0B63AF3042A8F55ED2CDD681AE02A5645E4271908645E64434C8 +6EC1FA94 +81224B594D324EEC22B18CF2FFEC +C694D26DA4B01EAC17E81BD0A1201B0733F1A238069CE685B61AB7C0372DF527FE13E9C4F02FA4A2A7BE9F63068EBB5852C9FB7C0B0DC480699AE2B9577DC4353799D0287CD9A5E6A09A0A725F591EB131ACD72F98D79199B7B3B42CFA5E54F1E7DB1F92EA4D6055FCF627C4E2CE90046A8E4C38E997457959AF4C53165E +AA0C +1EEFE42B3AF218C199BF1B97FF9F9B6EB63253BC3554E8CA2B39F2CDD331E73CD77F84039348851032E7 +26E8CCA2 +F9D4AB9099648F165944AD02EE +83A494FAD10601FCF54C0665F0B4787B56E8F0AD22D814EBB6554B622A30AC57E466AB4681F5678DC5E63C7C447C0ECD2B7078507E91BCF725CEF508D6C40E89FD8A2669DDAFC1EFD2A0D52434A82440516C391B57AB169A0D3527 +274A5949 +BECC37B7C4A95529BB33F2C0EA8E +279DC6700EDE0CE850A9177C6E851D01D67B1FAA0EE446FE947B16A24B99C1C2E8D8141337D7056995F4BA9D1246551587AAEF5E8FEA8C8127BBDDA6294ABA6B37B4DB63D93BEDAA30FC12BD50129A0A83BF32440C7F4816C47972ADA35D3DCAC651190BA1931004E7771C93F43764148B1D6BA2FDA7 +8365AAC2 +164D07464A95C1C11288EC1863 +53B9C4B298E49C0950C8F52058CAEF1A34199F853B79DE7E0710E4B12497BF156F813B0521E72F699358CFBD14A9D56C8DC8CF5F56D6DA181E1FE4D6496D24297BEBA81CDF42F498C0228919A0DBC51C868639925F9E16 +013CD527 +52A6337053FC8E0C4D5869B29620 +BEBF01FDE1279BBAFBB9C95FF68EA78975E9CFCC5B55F1ABA4222C5F9F36DC17938A29C73B252193AF33E547898A38A6AD3BA1A61A56D7D853FE2DF429F84C3C67F96ABF21C9E897860BE9F978622A51B39B0B107EBBA0326E008170847B38B385B268AF5D03A11D589D4922948261BA452EC10963E2D51821EBA7D02BFA +EF36 +2D3AA90B6951C967A9C9887E747B2531CFAB39692475A4 +E0E0F454 +CC4B89ED9F742F955470A0DB6B +C7D12AE114BBE7B26E1A897C731703C2E46EF5BD927835056BAE681AEEDF072723394C9A1AC2F9CCDDA88B272880F39F9C7A940970AB9F77C713C4000BCF101E5AF761BFB9775DD76A4AC0E96712C684B25F90A64F68F8C92EF0 +67ED835E +3E4E375067FCA6B11A129AB7631B +321258285A91BA87CCB93A9829342162FCC2285E018016AD1A28294BFA357E8F71874312FD97EA3A42D1314BC9233A28F681BCE856D7B7749A11EEEF73B6FEF343AD2894E7E5050C32CF8DAF35DE551706C4E06564A939C3E67CE3B16E9B3B21A2290FE047B156F96428C8205B42A95C5F83B862637443F3E50B6BC49ACC +F0A1 +42E8E1B688AD6CBC4F +BA5D4B3E +C7943FA2DDB74F93D3DDF6B53340 +8F3D7332672DE15B +E7E183BB +D8F2F7B41E4363FF42244CE829AA73CC4A79D33F2B9F0839F89E36E300DB4857F052 +1F35DD3F5FA2BD1EC4A1C8F4951F797EF2C0B2C82418278D87FBBF498D2D2FABF87CA6FDAC99 +58624E435E800292174BD0EA60CDB71B326C73EF7AAE32FDF27D51 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +%Defining font PSOsymclas +%!FontType1-1.0: PSOsymclas +10 dict begin +/FontName /PSOsymclas def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001000 0 0 0.001000 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 1 /C0069 put +readonly def +/FontBBox [106 45 775 713] readonly def +currentdict end +currentfile eexec +D9D66F633B846A989B9974B0179FC6CC445BC7C8A959A39A32E9DCE7FAEF17EE3BEC9F +50E1A6FCA651FC4B3769A0A91041557502E25A5D6180FE25A3D11BF079E1DF66E54EE9B7C229AF891739707A2A0EC140306B5E43E52B79BFB89E459E50 +6EC6F610A70775A31C460976C4F79449D86E57ACE491E5C6BF20CC4307B1DAF7630252 +E9AF8CFB69B50EDAE9D36A6104AFEF8832F920FD2346B2C7104CD11E3BEE999CFA9F5A +49DB3173EE48D1C82994237F360407B022E0B4 +502E94EA8B493651EF2D03F0B513D655047568325B512AE6 +6AC6F53F3848CF70DE25481CC65D8B1A5793AA +3C4282D111112BEE28AFCA7A3808D4444C4669CA +84EAAAF989219F51AB3476A1B0B5F2246BC306E6 +625C6679C417ED2A8E9BD010DE37D40265074C2684268F16195489648993B9C4D3B534FA887C +DEF605FA87B991F4D20A8F78DACE +5A54C070E03D5C59D9D2D3E06B09CEE028D68B62AB3AEC43C1DD20BA70D288597D9BD8E06818FF764EBAB436723988E8D7CA59E16D39032516BFC5D552ACDEEC6BE938BEF2F43CFFBC811C3626C4DF5F8CF080676520B51C60CEDAD1FE6C92D1431C702174CE517A8FA9377D075A0B6833DAB101DB65397F1419EF5F0016 +004F +6F0824F9657BB4F1C8F981709956865F6855EFAE +9242AD55 +91BBBEE163D844DDA894E13190C9 +2480439E4C71CADA +BD043A9B +A315CAF72652AA7FE6DB2E84D82A6111CE4DE90C02DA0AFFE2620922262A45AB4ED0 +EEC9F4520DD12703442F7D028D4526BD8B771E09FBE11B2749E2D3906894E8D4BFD3F379F14C +3C874F550606965E22FE487B247B5C2D06728490C8F2A3B588CDFC +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +/DPIx 1270 def /DPIy 1270 def +72 DPIx div 72 DPIy div neg scale +0 -13970 translate +1.00 1.00 scale +/wst:dutch12 12.00 /PSOwstdutch newFont def +/wst:dutch12b 12.00 /PSOwstdutchb newFont def +/wst:dutch12i 12.00 /PSOwstdutchi newFont def +/wst:dutch10 10.00 /PSOwstdutch newFont def +/wst:dutch14 14.00 /PSOwstdutch newFont def +%%IncludeResource: font Helvetica +/wst:helvps10 10.00 /Helvetica /wst:helvps ILEncoding 0 declareNFont def +/sym:clas10 10.00 /PSOsymclas newFont def +%%EndPageSetup +GS +0 13978 10801 13978 10801 0 0 0 clp +wst:dutch14 SF +0.00 0.00 0.00 1.00 setcmykcolor +<1b2a38342a362b10011201132a32282d3126362f012b3336011a2a263739362e322c011b2a383b33362f011d> 2207 558 0 7384 -1 s +<2a362b3336312632282a> 7375 558 0 8593 -1 s +wst:dutch10 SF +<0c0d> 9346 13300 0 9522 -1 s +wst:helvps10 SF +<4e6574706572663a> 1322 13280 0 1949 -1 s +<205265766973696f6e20322e313b20436f7079726967687420> 1949 13280 4 3868 32 s +sym:clas10 SF +<01> 3868 13280 0 4019 -1 s +wst:helvps10 SF +<2031393933b131393935204865776c657474b15061636b61726420436f6d70616e79> 4019 13280 3 7133 32 s +wst:dutch12b SF +<060a0d09> 1271 1431 0 1776 -1 s +<00051a191913121e151a1917131d1d000e1e1c131118> 1776 1431 2 3930 0 s +<0b0c0f07> 1271 1826 0 1866 -1 s +<04> 1870 1826 0 1928 -1 s +<00> 1928 1826 1 1959 0 s +wst:dutch12 SF +<0015191d1800382a3738370026362a0032333800283331342e302a29082e3200273d00292a2b26393038003b2e382d00322a38342a362b0900182b003d3339003b2e372d00383300312a263739362a00342a362b3336> 1959 1826 15 9461 0 s +<3f> 9461 1826 0 9531 -1 s +<312632282a> 1271 2071 0 1864 -1 s +<00333a2a360015191d1807003d3339003b2e303000322a2a29003833002629290026000815151c2415191d1800383300382d2a0031262f2a2b2e302a0026322900342a362d26343700262929003833> 1864 2071 16 9531 0 s +<382d2a0025251918131f11020026322900362a08283331342e302a00322a38342a362b0026322900322a38372a363a2a3609> 1271 2316 6 6050 0 s +<12> 1271 2646 0 1434 -1 s +<0015191d1800143332322a28382e3332302a3737001f38362a263100382a3738000515191419241f201e16121a06002e370026322630332c33393700383300260021151d241f201e16121a> 1434 2646 10 9531 0 s +<382a373809> 1271 2891 0 1648 -1 s +<00202d2a3d002733382d0031262f2a0039372a00332b003932362a302e2627302a0700283332322a28382e3332302a373700383626323734333638370900202d2a0015191d1800382a373800292e2b2b2a3637002b363331> 1648 2891 13 9531 0 s +<382d2a> 1271 3136 0 1561 -1 s +<0021151d00382a3738002e3200382d263800382d2a00312a3737262c2a00372e3e2a00313937380026303b263d3700272a00302a373700382d2632003336002a35392630> 1561 3136 14 7741 0 s +<00383300382d2a00302e322f001a20210008> 7741 3136 5 9531 0 s +<15191d18> 1271 3381 0 1787 -1 s +<0029332a3700323338003436333a2e292a00181d08302e2f2a00372a2c312a323826382e33320026322900362a2637372a3127303d002b393228382e333226302e383d070026322900382d2a00322a38342a362b> 1787 3381 11 9531 0 s +<272a32282d3126362f0029332a37003233380034362a3739312a003833003436333a2e292a0033322a09> 1271 3625 6 5362 0 s +<202d2a> 1271 3956 0 1631 -1 s +<00372e3134302a37380015191d1800143332322a28382e3332302a3737001f38362a263100382a3738002833313126322900302e322a003b33393029003033332f003733312a382d2e322c00302e2f2a00382d2e3710> 1631 3956 12 9531 0 s +<03> 1398 4286 0 1504 -1 s +wst:dutch12b SF +<00031a1b1e0319131e1b131c140319131e1b131c1400020800> 1504 4286 3 3785 0 s +wst:dutch12i SF +<0b0408090d0405090c0d> 3785 4286 0 4744 -1 s +wst:dutch12b SF +<00021e00> 4744 4286 2 5099 0 s +wst:dutch12 SF +<15191419241f201e16121a00080800> 5099 4286 2 7188 0 s +wst:dutch12b SF +<021800> 7188 4286 1 7593 0 s +wst:dutch12 SF +<0c0b0d0e> 7593 4286 0 8017 -1 s +wst:dutch12 SF +<172a362a0026362a003733312a00332b00382d2a0015191d180837342a282e2b2e28002833313126322900302e322a003334382e333237002b333600382d2a0015191419241f201e16121a00382a373810> 1271 4616 12 9453 0 s +<0815> 1589 4947 0 1937 -1 s +wst:dutch12i SF +<03040f0c0a0402> 2033 4947 0 2700 -1 s +wst:dutch12 SF +<37342a282e2b3d> 3177 4947 0 3795 -1 s +<00382d2a003033282630002632290a333600362a3133382a0015191d1800292a3a2e282a002b2e302a003226312a05370600052b3930303d08> 3795 4947 9 8895 0 s +<353926302e2b2e2a290609> 3177 5192 0 4112 -1 s +<001f3d3238263c002e3700382d2a003726312a00263700382d263800332b002600> 4112 5192 9 6914 0 s +wst:dutch12i SF +<0c0610040c0a0402> 6914 5192 0 7593 -1 s +wst:dutch12 SF +<09> 7593 5192 0 7646 -1 s +<0831> 1589 5522 0 1940 -1 s +wst:dutch12i SF +<0f01070e04> 2033 5522 0 2495 -1 s +wst:dutch12 SF +<37342a282e2b3d> 3177 5522 0 3795 -1 s +<00382d2a00372a322900372e3e2a07002e3200273d382a3707002b333600382d2a00303328263000373d37382a310900202d2e37003139373800272a> 3795 5522 12 8895 0 s +<302a3737> 3177 5767 0 3502 -1 s +<00382d2632003336002a3539263000383300382d2a00302e322f001a202109> 3502 5767 7 6359 0 s +<081a> 1589 6097 0 1967 -1 s +wst:dutch12i SF +<0f01070e04> 2033 6097 0 2495 -1 s +wst:dutch12 SF +<3b2d2e282d> 3177 6097 0 3703 -1 s +<00272a2d263a2a3700302e2f2a0008310700372a38382e322c00382d2a00362a282a2e3a2a00372e3e2a002b333600382d2a> 3703 6097 9 8180 0 s +<00362a3133382a> 8180 6097 1 8895 0 s +<373d37382a3109> 3177 6342 0 3835 -1 s +<0834> 1589 6672 0 1882 -1 s +wst:dutch12i SF +<0a0a010c0a0402> 2033 6672 0 2725 -1 s +wst:dutch12 SF +<372a38> 3177 6672 0 3432 -1 s +<00382d2a003033282630> 3432 6672 2 4266 0 s +<002632290a333600362a3133382a0015191d18001d1d> 4266 6672 4 6506 0 s +<1205370609001f3d3238263c002e3700382d2a003726312a002637> 6479 6672 5 8895 0 s +<382d2638> 3177 6917 0 3536 -1 s +<00332b002600> 3536 6917 3 3986 0 s +wst:dutch12i SF +<0c0610040c0a0402> 3986 6917 0 4665 -1 s +wst:dutch12 SF +<09> 4665 6917 0 4718 -1 s +<0837> 1589 7248 0 1847 -1 s +wst:dutch12i SF +<0f01070e04> 2033 7248 0 2495 -1 s +wst:dutch12 SF +<37342a282e2b3d> 3177 7248 0 3795 -1 s +<00382d2a000f0b0d090d001f> 3795 7248 3 4852 0 s +<121d002b333600382d2a00382a37380900202d2e3700372d3339302900323338002833322b302e2838003b2e382d> 4846 7248 8 8895 0 s +<26323d> 3177 7493 0 3493 -1 s +<002637372e2c322a29001f> 3493 7493 2 4480 0 s +<121d> 4474 7493 0 4765 -1 s +<043709> 4769 7493 0 4956 -1 s +<083b> 1589 7823 0 1909 -1 s +wst:dutch12i SF +<0c0610040c0a0402> 2033 7823 0 2712 -1 s +wst:dutch12 SF +<37342a282e2b3d> 3177 7823 0 3795 -1 s +<00382d2a00303328263000372a32290a362a283a003b2e3229333b00372e3e2a37002e32002b3626312a3700053b2d2a362a00263a262e30> 3795 7823 9 8825 0 s +<3f> 8825 7823 0 8895 -1 s +<2627302a0609> 3177 8068 0 3692 -1 s +<0822> 1589 8398 0 1975 -1 s +wst:dutch12i SF +<0c0610040c0a0402> 2033 8398 0 2712 -1 s +wst:dutch12 SF +<37342a282e2b3d> 3177 8398 0 3795 -1 s +<00382d2a00362a3133382a00372a32290a362a283a003b2e3229333b00372e3e2a37002e32002b3626312a3700053b2d2a362a> 3795 8398 8 8372 0 s +<00263a262e30> 8372 8398 1 8825 0 s +<3f> 8825 8398 0 8895 -1 s +<2627302a0609> 3177 8643 0 3692 -1 s +wst:dutch12b SF +<1019151f> 1271 9091 0 1710 -1 s +<00061a18111519000e1e1c131118000e1a1216131e1d> 1710 9091 3 3956 0 s +<0b0c0f07> 1271 9485 0 1866 -1 s +<04> 1870 9485 0 1928 -1 s +<00> 1928 9485 1 1960 0 s +wst:dutch12 SF +<0021322e3c00153331262e32001f33282f2a3800382a3738370026362a0032333800283331342e302a29002e32383300322a38342a362b00273d00292a2b263930380900182b003d3339003b2e372d003833> 1960 9485 15 9046 0 s +<00312a26> 9046 9485 1 9461 0 s +<3f> 9461 9485 0 9531 -1 s +<3739362a00382d2a00342a362b3336312632282a00332b0021322e3c00153331262e32001f33282f2a383707003d3339003139373800362a283331342e302a00322a38342a362b00263229> 1271 9730 11 8241 0 s +<00322a38372a363a2a36> 8241 9730 1 9113 0 s +<003b2e382d> 9113 9730 1 9531 0 s +<0815151c24211b1823> 1271 9975 0 2649 -1 s +<002629292a2900383300382d2a0031262f2a2b2e302a09> 2649 9975 4 4732 0 s +<12> 1271 10305 0 1434 -1 s +<0021322e3c00153331262e32001f38362a2631001f33282f2a38001f38362a263100382a373800051f201e16121a241f201e16121a06002e37003a2a363d003139282d00302e2f2a> 1434 10305 11 9335 0 s +<0026> 9335 10305 1 9531 0 s +<20141d241f201e16121a> 1271 10550 0 2724 -1 s +<00382a373809> 2724 10550 1 3154 0 s +<202d2a> 1271 10880 0 1631 -1 s +<001f2e3134302a37380021322e3c00153331262e32001f38362a2631001f33282f2a38001f38362a263100382a3738002833313126322900302e322a003b33393029003033332f003733312a382d2e322c> 1631 10880 12 9531 0 s +<302e2f2a> 1271 11125 0 1602 -1 s +<00382d2e3710> 1602 11125 1 2037 0 s +<03> 1398 11456 0 1504 -1 s +wst:dutch12b SF +<00031a1b1e0319131e1b131c140319131e1b131c1400021e00> 1504 11456 3 3692 0 s +wst:dutch12 SF +<1f201e16121a241f201e16121a> 3692 11456 0 5658 -1 s +<202d2a> 1271 11786 0 1631 -1 s +<000817002c3033272630002833313126322900302e322a001c34382e3332002e3700323338003a26302e29002b333600260021322e3c00153331262e32001f33282f2a3800382a37380026322900372d33393029> 1631 11786 16 9531 0 s +<323338> 1271 12031 0 1572 -1 s +<00272a0037342a282e2b2e2a2909> 1572 12031 2 2751 0 s +<172a362a> 1271 12361 0 1736 -1 s +<0026362a003733312a00332b00382d2a0021322e3c00153331262e320837342a282e2b2e28002833313126322900302e322a003334382e333237002b333600382d2a> 1736 12361 11 9531 0 s +<1f201e16121a241f201e16121a> 1271 12606 0 3237 -1 s +<00382a373810> 3237 12606 1 3672 0 s +GR +eop +%%PageTrailer +%%PageResources: font Helvetica +%%PageProcessColors: Black +%%PageCustomColors: +%%Page: (13) 13 +%%PageResources: (atend) +%%PageProcessColors: (atend) +%%PageCustomColors: (atend) +%%BeginPageSetup +bop +%Defining font PSOwstdutch +%!FontType1-1.0: PSOwstdutch +10 dict begin +/FontName /PSOwstdutch def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001000 0 0 0.001000 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 1 /C0032 put +dup 2 /C0036 put +dup 3 /C0040 put +dup 4 /C0041 put +dup 5 /C0044 put +dup 6 /C0045 put +dup 7 /C0046 put +dup 8 /C0049 put +dup 9 /C0051 put +dup 10 /C0058 put +dup 11 /C0065 put +dup 12 /C0066 put +dup 13 /C0067 put +dup 14 /C0068 put +dup 15 /C0069 put +dup 16 /C0070 put +dup 17 /C0071 put +dup 18 /C0072 put +dup 19 /C0073 put +dup 20 /C0077 put +dup 21 /C0078 put +dup 22 /C0079 put +dup 23 /C0080 put +dup 24 /C0082 put +dup 25 /C0083 put +dup 26 /C0084 put +dup 27 /C0085 put +dup 28 /C0088 put +dup 29 /C0091 put +dup 30 /C0093 put +dup 31 /C0095 put +dup 32 /C0097 put +dup 33 /C0098 put +dup 34 /C0099 put +dup 35 /C0100 put +dup 36 /C0101 put +dup 37 /C0102 put +dup 38 /C0103 put +dup 39 /C0104 put +dup 40 /C0105 put +dup 41 /C0106 put +dup 42 /C0107 put +dup 43 /C0108 put +dup 44 /C0109 put +dup 45 /C0110 put +dup 46 /C0111 put +dup 47 /C0112 put +dup 48 /C0114 put +dup 49 /C0115 put +dup 50 /C0116 put +dup 51 /C0117 put +dup 52 /C0118 put +dup 53 /C0119 put +dup 54 /C0120 put +dup 55 /C0121 put +dup 56 /C0122 put +dup 57 /C0262 put +readonly def +/FontBBox [-50 -256 920 766] readonly def +currentdict end +currentfile eexec +D9D66F633B846A989B9974B0179FC6CC445BC7C8A959A39A32E9DCE7FAEF17EE3BEC9F +50E1A6FCA651FC4B3769A0A91041557502E25A5D6180FE25A3D11BF079E1DF66E54EE9B7C229AF891739707A2A0EC140306B5E43E52B79BFB89E459E50 +6EC6F610A70775A31C460976C4F79449D86E57ACE491E5C6BF20CC4307B1DAF7630252 +E9AF8CFB69B50EDAE9D36A6104AFEF8832F920FD2346B2C7104CD11E3BEE999CFA9F5A +49DB3173EE48D1C82994237F360407B022E0B4 +502E94EA8B493651EF2D03F0B513D655047568325B512AE6 +6AC6F53F3848CF70DE25481CC65D8B1A5793AA +3C4282D111112BEE28AFCA7A3808D4444C4669CA +84EAAAF989219F51AB3476A1B0B5F2246BC306E6 +625C6679C417ED2A8E9BD010DE37D40265074C2684219F75E53AC2AB7524E61DD2942AD43C860C +2E17ECF00C883B66A330B97B +FB4A6AA6EA10AEC651 +C9333FCA +568CDAB7BA8DF6B41FF5C0172F32 +136BC107DEA671D5A04DF05029CEFA6E4EAC0365F10CAC00B5A109CF563C99977597A81210462EEFE9C811501444827A70FFFB229296DC954930A207FFE9AD3BC7A16200A623E518941A374D6282D9F6CF62B36E4B6C952F540E8EB37F94F95AB2D2FBA809C735490684C22AC365F32A9F24967FEC10C744FFC8C65AD144 +FE84 +9A9A5AA6A99FDE09D96C86F8 +AD832244 +F32A62BC4BCE6F32E89F06F87D +1352E5899AE01C9553B10FF0CF388DEB75429F1EAD1BC652C39A8B91E9F847C496C5E6B5DBA4FEE8D83590B1EFBBA1AE35EEF040E08456B290F4765F46C36A8E +73BC750D +183DC0D551C18B667AAD54D823 +50F8D5FED8FD4D5E6F5EB079A7DB81B12314F93F622145F160E91BB83917FE7157B146FADA85A6077F1115DFF71A4F55791F3C7A6A369A2368452A6F6EE253 +6ED55C05 +90D9B1FF66ACF1CF56EECBD736 +C596D6FC0F181AFFA796F2A82BE90136CD043C85E12C79FC2AA3D57853D111ACE9CC0E2FDA7A63819D3C90F134E149400F4A635147144117E7 +302BEA47 +3B98CEF2181CDD96E6DB0B0BF5 +8CE30E4602E28AB25061E145C191356E3FAB09A8ECBBF9 +F4F85E47 +CD6CE0EA517275530DC30DBBC1 +0E1086651BDE15047100F1AB07B9EE68CE13017CF3CDCB980A1FC4AD09AD71 +C054DBA5 +9B5F345A8C251DCC21A31944C1 +0E1086650517DF20780CDDC4AFEE4DB85CF2A5ACDA6F003769F5C60529F5625D03C5D62DFAC12ADB6EB37D4618181CEA056C0674B85F45428287D0FA39F799 +1D6FCA58 +CD9C9968D917807784F18A87186D +E1B496C46AA4B2325E9B226C48B7D08D7EC2DCE3241CA2B8A0D4DE045872043C8A74A55A0E25B64830135EF041D8DA7F093C39390D6ECB855033ACFCF3D4E119F350E59FFB8A6C917A6438ABBE3BF4B048D032BDB3510D752A3B5DC0065B7A4B9A923321A51B3E06A92A43550D229E +E1E389F9 +F7B9AF4D6C679F4F4C299F6716 +8AF7E61FC459CE66A4353BC21DF33A5E9223C3C6412B49CB63BABF7302F4FB8E91788B6014D723D0608F30A4F8463C542E08768F1119 +ABF40D21 +89175954D37140BE9C488E75BBF5 +97DB49E37909BB01A351A5F02DC0F7AB0C4449DA1C789D3B8751456AFB74BE08EF91D9568CED5E64218212FC78377016366D2D5ECFECFBE28026714CA0F58F37468431DA78D00AE6512DBF4B72E6B64A154DD28978AE34437EF1044D992834DF1BC1E2958C1FF314D1455E737895C852E16C29 +8A2E6F9E +8E1E52335C600407B372E5FD1996 +F8AAE79157DB47276D40CE3EFB46C92B951A9A04E4D4301FA21411B48DB73D957CBFB7BDEF90AB6948449FCA7FC998E1158B23686068F0AE77BF10A194BA8C3B293B968F83BDD9871160AA7054610E6C21849333496B0A07F533D9CA0C98A6F0373B4CB1FFEFDF09EA21692D154C09C1B04B7A552B8EEBE712586978D1EB +1832 +C4 +10A97BAA +F0BAFFFB9B294624C18DD1D43E +8C7B81DEF3755D8E482EDC4BC6F15AA09A327BDF229B54B39D1676789878CDAD49011CAC05DB52887152D84517B3FEDC770040E1438ADFAF2B0DECBBC616A929682B257E3899AB7CBF49ED23BE67618F01BBDE80338AFC88DC2AA166AE59E72518 +322291B8 +D38F75EF8153B676B2037BAFBC +79F33E071BB3D8B853F5676561AF7E6CD18024B1860AA2B77C5ED18FB4935864E684CAC81B917122141824F7D0BDDA6246FEF5216281820BDEDDC47B60401D4C646B0DB0B8C33B872A3DB2308BC448B098BFEACC80531A1560B0AB4AE15FC0E15033BC +754FFDB2 +A61D15032494C2427564078B0597 +5B4625D5152B86F8852193B3F742086F74A2C72F0CDC65689AEEE3C31FF5B0046DAC439CA62DB991DB959786FB48763411BA22ACA07AF6A336EAE0C9EEC42EB41341D880F2E57A404309D6F9F2C86F5162618D9373F74B6D1CEA91A8C0055CE4E3DA52ABAF77BC7C554358D184455A4F31B325603A7B97DCF5BEFE236921 +4DB36B02 +89AEED3AD846334C371941F0AAD3 +273533F04E631362D011A398DB2C35B69FB38D19CDFE20F66ECCC620B3418EEE569CC8250A5215DE14676787EC957B194518EBB533AC27681F0D241563B1E77563EE2C5E240E2F8CB391137573A6F8B73496D0EE57F41ABAFFCC9FE764B1010976D4A143C7616193E1 +D8BD9DBF +FC3BF8A7C297FDB8A79344EF5548 +E7BA21E4113F55F3CD2897F566704E69D5D834C7FB1E3CEBD346DD0AB7BA86C677F1C93DA1E628401ADEBB759762EB2330FA9D99AC70829827F8B3AADDA320160E208F99B3453F313659BB04AC265B19A42AA6651BDA5EA0D6E3F013D6717D44154EE661CEDFDF1F184C22CC4E3FDED437A3651613AF64BD12D4 +BEEF04D7 +E9F4E1FA744577964D6D7D60C5F1 +E0C780128E9026EF034871ED0E5B456E5CF7CCEF0E0A1D2AD9CA50F0803F2463E77AFF5AD95E13D291F84274DCDBCD1514239008F683A5974D66562D7E6DBE30446ED7A98F8B51EA81A05B49B52522CD2C77EAB98315758856D5F686F7E16F76B7C4101BE4AC5BB3EF669E2DE1F8E16FB939851BB682AD9F6FC0B82F7E06 +599B +A68E7B1FA5474287292290 +DFABA70D +42D2F5CFE4046E9DFA56CAF198 +F1073B7B598830197E8592AFD4B441655EDFE0A7FA79E7169E419EEDE4BDE005E3DEA4DB78F3BE11FA0C4367B22155F4835DAC972219A2934B7018 +9108CA0C +6FB4B1C3B47EA97AD7F250F767A5 +3A82F9D8907896CA51E6E185E9A3A31940BBF17D4935F2D08F2F23307B11566AF3AC6EBDE8B30E73621D745C45CCD01F4C5316BFACA3F79F82A82EF3A56C0909E3538DDA8859A19B6B4CFA2132CE7DC489E022149BA6091687484F063FC6B6C1AA8029E96B7266280C132FE6B36B1C +CC7261CC +932B2E345E9CE791BCFDD27F19 +E63578119E8DE71CD41224F4F1FF689648D2BAF01F7ABCDC2E29693989B28A6CA1AFB15B4D81AD75B08B59A6A4FCFD5FD989F662E79D132FA033DDD096F5F13175DF8481B2EF6D0CBC0601C47FBB389413F7C102089C8875E5E665B5 +665D0E03 +E6A1ED6F3E8D666064BE3CAECA +B7F3FB4B2C107E791CAE90525CEDB395D765A4E9F6CD457F5E606BBE122E88D46E50CE2531CF9798C4F119F732354B2ACAB4E7CEE1502721C34A27811267B9B5D0DE1ACDADE23518EA251CF19DB76BAC171BAB +9DE9CED5 +0635FEE972DD71D0CE4701CF5235 +CF67B5DB52C005DC3D2841FF4AE8EF9031C273F3E84F6100FE4F29BFD6B27596FF6B2E10C57C8C389EC25D134A051C95C6A1C3D9B5A5303A335506EA4B575FFD7F9F383E27DF1CF8BA624C8903DABB911409D5BD75D008A13CE8772199AEA9B0128BFD86B48219BFA87F +AA72F377 +6F32AD4394845A9885A1E5957BCA +0EE326B9A817209EF759655D5FD7EAADDE812C679051658B23D2B24BED71ACD44F40BB74C7FCE51ABB375F515CBEAAB3BEBF496DF7CE4EE540A01AA6F35E11264A2D95F95F87A690FFAF9EB66E2697CCE941FEABFF843C1F49DD42F32C11D2A0C42567CC2B28EFDC990C6D208DDE44D921B36C34681D7598765C3E0B5859 +8D941CBF +81298FC18248516B00594228A594 +9744FF4008C4EDAABEFEA82CD72345D06CE116CFE96B1ABDD0949365CA0DEBBAC6B0B0FF049A9CE65A7149944C487917CB825175B46C5E9405B0099541358DB61EBE51042977A1ADF012A0DE20D4F87329485E1052F1D21E206BADA9FE89363708F1E6EA55D942A50EFD0687A7A88853EA260A3CA9035B41272663E4468E +0A57 +1F57EC +8F4B31EB +5879596D6F187A1740FA7AF1CD +28488C1FB0812C75C8FE9265BAFC1E56805A804E89F6F9135E94E350DD2AE405A2FC60A38D56B35D1BBBFB9E72A7E3CFAF0AA9840F159EBFBBE6757863327C0673850CBB1AF8F722FD18C37D6C6BBAA19E +C75F9FF8 +3638CBCEFD0AEC9F94409AAFFBA7 +50A16A4933C3E46FFD0AD8E84836170C842EDA547FD30CAB152EA3D9F44B9FADF2708582131F9C4F657DF7474ADEF67748F76E728FB9A2ABD67DC2AEC2200660F694FEBCB2C24CE81E362A4D252545FE440A8FAD79BA7DF2156F29644D8389A7E0C2A11C +72EE498B +75DD5B31E71F9619FC937A093530 +3EC18238B9009ACD92307EACF1B9DC6615199B25173161FFAAAB4A6F4FE6BC7335964CD5ADEB99DE3E37EE496D6FCB08B4BFACED50F73A4E5FC310FE0A838D34B45927DDAA6B0C55F7B391E0C4221851FA21CB625A3005B65EDEBF3D44A801DCE6F0078043657FE70C33F56EDC9D7529B156414F8F667CD3ED45FE48F1B7 +C4D0 +784708BB88C5DABFEBBA248188BB0F20F20B0482E93D7E2E709A86C5EF463607CFDC5C8FE76326 +4842C682 +666FE7B5C0D5E5EA09A445684F +4A27716580E7732FC49F39506432ABF6A6D0CA9F6826D7F176B21D8CF08C192355EEDDEFE15EF34A85CB +E78EA633 +573F213E837C35A9F2AC9421A4 +6A3FA3F619B38ACAFC42BCA26CC0DA781934EF7F9EE755001728E07CDD33520F81233D946A9A6427147A5499 +424A075B +C731C317A5799E378324E76D01 +937F9CFEBCC2BE8534A3346D3BE9DA66B399E82599E8 +D8BF9F31 +E8E41ED0C5A2358858ACD5F5B248 +E01621525266E3B7D9C0DB734078690A27A55B42A8D287AA7D4F907893FBF24862FAE46F05320EB9E72FD9F7524742A8E3C590BF2235D6FC86D3A6DD34D8A203031955FD7556988EEF5BCA71CCCFA0568AE0F2A11737F16AA6CED82AD9442173EF45A3200C764914A99E3412A3ED6F53E6F03ABBEE453AF6834EF24B57C8 +7638 +D6DDCC +B72C8B18 +02C3086C135F1E16A5B5A48059 +28907FDFCB21076EC33D45D16513643C6734751FD8BB1C98A7E1EDF1A990A5A9444A9C764B2B5D1E34B75875C3004BFCB68A64AF9B4496ED31BA3663DAEC8088EC2E43F000952AD35C760E6350C16E92B13DFE357F2B1001 +66CC5845 +F1F05B3C931698347F8DABE303 +F21C10B6545DA965EA11692CE122BDBB92EE99A37890AF75B3244546346BCF255929598E05EB79378270FB816C0D70CC454ED1714F1914E4E74B269DABB7A79AEA707D359DF6D2A27E243E9952B8F5F48CB0 +9089CC1B +CCB1B70611F6BDE0C5051879C9C3 +C80618377B83AB358FF6D7A890E26254FE21877F6EAE5D59394C6EE13115DC98228176CF9C7BAAB7E1A29BDFB83E1D17D4C7500CC34F8FA4F4D44218D04380777F3662AC4924B172CEA43227941318256AB50A25DBA659FD4DA260B9735532CDFD2AECC827756EF406AEC310B544 +01230884 +6C0412BB874CB41C752BA310AF +FA57355AA72335C2AD2D9FA6F21B774FDAE14D9317CFF4F77ED5E168BB7183361DDACB95F1886CE8A4789B090FBBF6FD5A9DDAA611FB7E91DF843C686C728A4F5EE252B59772D96F193F0662EB5B3155A43CA86FE3B96BFDA1 +04DD363D +0D64F501E0E8E8EBB30BF4ADAD +86EF5BEE17769303B16346A906ABE52012CBFD7EE3B93254C4B757CF9C928BFFF5462C98C95A21F5588DA3C0C080EF04990EDCA56F5592629D83549562204CDD49B80132AF38422D831517C441D3AFD7C02473F56A40B4CC06128D75 +22485A54 +4C3AF983D10893D1975CC77C5D7D +66DFE43159C54139C3529822B922023CD5F627EC6C3BE74F6ABE5EC23DAB0ED25CD43CEFCA54D5E67FE944A635A4778728BEF16730EE682070AA7BD61C61809A70B226E96C765355D0E43D15FBE7C5268E136F8DA5E98B848FB266ACEA993E5E6347AF40DB4E1E15173E6964E620E7A6E4C183EC03CE356653AD96A90581 +808D +3E402CD5778BEF8315B615B345C81E6B1874B1BB1C177515E675720B025582E054CB703D43E5ADDD96E32FB9FBAF97 +7E28E2DF +7B5E5020B7DACF1FF9A38347DD13 +37681126148DF8E0CE52D9EA57608CE93DD69A12720108F45935E32E5A33A4923C8643091A21E5690177219AF0DB5155B97A1D78032F17CF938714A7DE493E7A1493182BA5FF48F644756CB3CB8E2007A8A30F87531D71476372A392EB8CB0DA2F727BE285BA058CC621B8B8AA +AD517922 +CEBD8B840B8B7813872DA479E4 +279465A664E633AE1452BCE7845EED9FA05D3F0E8B17E2B448B19FF5B9C26F51A64323E985F35C1F03D3848D99B2A7061E982A9C0271056AE4FE0760A72293852FD4FAA892E386185C9F1AB9970A0E08 +FBB52020 +BF4BC33A77E702114B77A5362A +2A8AA3CACDA1FF1E811B558C2FBACDA8F9F17A92992A9F8EF9283F5D08218EC8BF0B3846567964A8D2D2A3BC22949B339A0AF90503902852973CE5746FF83798B6DFEE3220146AAF890546C5871C1006B9547999247DF781A09CFD2CD77D4024B6860F +CBB78541 +8059A78CCF11F665699FAAD5D324 +BCC6F790FB1DB18C9044494CAEA8B383C9E2D22CB578AAED1200302EDF93DF350A46DE37BEC2CE6B5A1A220E5F14F9957F4B2B898CCA666A472ADAF978190FADFE6696F9AF4C73D951FD267B50E720A450FC7ED82E0370D3F25F477FC4828C6A5E5AF253628DF8B1C99CF0E4649ED7438F6E36AA5FC1A770DC688D1C90B0 +7B61 +68F2D9830EE3AD2EFC3FA74BF5A41AB50CE38EFC2D0832EEED42B6793BCF678ADAB813 +45638F02 +FC7DA712AFD9750A3598A8A37B +F1F9C5C0E10DE9CCC3E252EFA11C2D1E83952A5E14F07CBC695BFB37C4F6D3AAA1242FC442A5C7491315E3F854FFD39404DDF49497D9 +995D8191 +9317424607AD4423086618DC9B42 +E3255D9FCFAE985DDA7E7F7CD81FEAA7FBB15E6FCB74B02C8424BC53BE1A4B5482DEE65A7A4436ABB0C862606BCAB5A4A3D6F11DB2876C49F5D68E3F71CAFDE39AE5DF32A5845697518DDE3808462A408D67515810FFCBE04F5ED584AA1471BAA36AFBBE88589A1E0AAB4252489A60D7BDD7815C2C05CD5DBC8CC785F483 +7DBC +A4353BA5B70F9BF5B0E61A3EE82BE157289BC8CE3BAE54BCBF2DAADE8124A5 +A3A1D194 +D2030328AC1F6F24D85387EC197F +07C4D191E1410F6EA3D394C8A29A66BA83BBF0BFBE52F2D65212D45782ACE21DFDBEF2D8FB66796DEE13589BE327494027560C5267C2F3E5E1DCFD6E784BD6F81B7D2A51008E77417D51C559E7BD27223BE187C2B0637642274F618F7EE9C14209C6F55561CBD4E8A7D45D6F +9F54AE2F +4DAC410D0F84330F04A7EE1865 +6AAC3D7318F702D357D9C6194CADD713B257E575CFBCF7CF0790A86E13C06730844F624257EA710B956839A036E4E3D3FAC98906D71BFA0C15EAE9BB38D39DAA3B45401C6265 +D42D18DB +AF14B0CA1C5C1B0CCCC336A6E4AB +567E41FE31A5FC668155934AFBBAA4A42FFB40665AEC8D1FF58B84B10D60564F0D5FEBD5A6F91647F5E263AAF26C2EE7519A85821E4DC22C6832AA28B7FB8307A32E06525C31B9FEB75BC4609E5F5C96C7C80BF2CA853BE75A3326B39F004C0EC6B7594A4261931C1810A3D93C1AEFF2BBA51E3CC790C5 +DA5349A3 +E7B1FDA9EDCC27572D8F3CD66B +6B62484D728DE2D4CECE5B64A764745F3894DAD789C57779947D49B9527DFC21C11BDDDFF909B1B350D52D511656F4FFB0848CFFA1CA86ED1C14671E864007817B7688E9685A39A02782C9AF68ED324AA8B2455FE159B9 +06328B10 +5F7731E32B06F2C75E04E77FC5F4 +80C8F3032B4159FD3FB40EAA7B5133E6F9C3E501B651C8874F952E065BF9CA149367ABB5D22C8B08E13471DBF18DAC0B3EE942C60EAB2536FF9F8A17C26F4096467B1A708322797745D2113100AE4B64D271058F2380364E4922A24C0AAE8E8811F6B29EBBEBA43DC8E3561B016A3AB5DD44DF1573DC1F85FBD4258A +B5168680 +2E68FB119BCDDAC6DDABFDDAE4 +49FE6818F8596D155C2CCC467AB372E9666B1AF4ED7D8B42EE28D5B49445A4F001D6EA22BCBC99E006B101302F01A1FC23FAADB163F6679C1801D8E18414397EE26FB5F338 +7C234D23 +143880F791BCDB79912708CB5A +55F4ED9168E0DD77A95A300742B6768F91D5BE0B827CA923A16996013D08DBC6483FC5F1B6F68623A7436FE5BC224BB3E17401617F3C93C81E240E3AD6B57E0650E3CDBB2A0F2E26ED787D4A70AEC58DAA28C4F1708A3543C6A2660EBCA08479D6C1 +B2E1FDFB +AD1B40C166253BB8C655BE5D1F +91FFBA4A5D4D72FEB87571A94A1385DC22A1B168B1056862F3BFF6B949A31B2A651E79F15EB2B31AE861FEB5654980C86EB0A162E9DC6BB990D44CAB0C58CADA65EE64B89FA9091FBBE18AA571C9A2AAADC195FB8D8F7C068E +9BA34D45 +FD992386075EEE78FF23E035D446 +8AE5C7304FD0373538E52739F0EAAFA2C638419CDE1ED81C27D6222DAC5DBAD56D3C40AA3154CAF73F545877D5AFFE724B46696227D7F93E7AF98088EAAFF290E1E70146C6854852CD8799E87D3E16AE197CDD57A3234D7F38CDA2E987A91689822FDA104E9223B1DD7B25AF145FE88F5DF9A7D3C8E363FD44C5CA8C6257 +0DAF +CBB687C16E31BFE0833A3BBFE96F +0164BF80 +90802FD0DF2EFA53CC193C144EC0 +BFA85297F739ED8D5B3230C86C3502CCFC42152CA3612A1D872882382612BD6BF205A69EF0364F06A8057BAC5BCF31A6B84609444FB69F87356804D9171B7703028941F01B5AA6CAEF91D8B1C012B0A46840CDBACF4FCE65BC13C47FB8018DB405A0F707EE2B55184F7B64112CEF3F9651C415E8CD5F71DD1207077000CB +349B +F1C6F3D59199C2E0F064E462AFED92B4F0FBC99C26AEFB0BD9 +CEBE57F6 +08731CD363DADA7952295BD5AA1A +57DC0E95142643A3B260C19D5F783C39B8E0ACAEECFA12B79CEAB503F7170F9F781CBA8FA7E5AD8B4E1A9186421C4FBFA290AE129B9FF887D45010FEE909580314A573B0F2BFB1DF4CB3A04EFB264DFA9A822EAA851BEF3DA51F32EEBE5F0F348F08DA66B35141237B60FCAD88F282587B7F63163E438BC5B4AE6A608FB0 +9786 +18F6C1E5 +348B7066002E8A7F8F742286B3 +620DC94ACD9BA38CD08A079A4E63D9DBE16501587462ED21AAA668141BE36D22DBC20FC9EDBD3FBAFB352CF74E6F027575D30D4A486EA6F1F0FE6935D17EC8 +810EA9BC +21D46B002C1747D548177EA0EB +C1EADF96700D2DE2546DD084974F811EA34708B4789B +E78C69CC +46F2CF4169E962522E03E02F9B9B +8774237E71C91A8F +EF2FBD19 +384A32D1E18FC772917DA4E739D7E7D60C526AEC7D3E9DE0493B19C477719A6495F4 +719F2DB441D578C667321709AC63773E607A43E39DBA2C850240B3A12D65DB5E075E8B0D809B +FDB9FFC301C9B0167E515207BD2D402715551840FAF1995E2EE327 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +%Defining font PSOwstdutchb +%!FontType1-1.0: PSOwstdutchb +10 dict begin +/FontName /PSOwstdutchb def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001000 0 0 0.001000 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 1 /C0032 put +dup 2 /C0045 put +dup 3 /C0047 put +dup 4 /C0058 put +dup 5 /C0065 put +dup 6 /C0068 put +dup 7 /C0069 put +dup 8 /C0070 put +dup 9 /C0073 put +dup 10 /C0077 put +dup 11 /C0078 put +dup 12 /C0079 put +dup 13 /C0080 put +dup 14 /C0083 put +dup 15 /C0084 put +dup 16 /C0085 put +dup 17 /C0097 put +dup 18 /C0099 put +dup 19 /C0101 put +dup 20 /C0102 put +dup 21 /C0103 put +dup 22 /C0104 put +dup 23 /C0105 put +dup 24 /C0107 put +dup 25 /C0108 put +dup 26 /C0109 put +dup 27 /C0110 put +dup 28 /C0111 put +dup 29 /C0112 put +dup 30 /C0114 put +dup 31 /C0115 put +dup 32 /C0116 put +dup 33 /C0119 put +dup 34 /C0120 put +dup 35 /C0121 put +dup 36 /C0262 put +readonly def +/FontBBox [-18 -209 919 694] readonly def +currentdict end +currentfile eexec +D9D66F633B846A989B9974B0179FC6CC445BC7C8A959A39A32E9DCE7FAEF17EE3BEC9F +50E1A6FCA651FC4B3769A0A91041557502E25A5D6180FE25A3D11BF079E1DF66E54EE9B7C229AF891739707A2A0EC140306B5E43E52B79BFB89E459E50 +6EC6F610A70775A31C460976C4F79449D86E57ACE491E5C6BF20CC4307B1DAF7630252 +E9AF8CFB69B50EDAE9D36A6104AFEF8832F920FD2346B2C7104CD11E3BEE999CFA9F5A +49DB3173EE48D1C82994237F360407B022E0B4 +502E94EA8B493651EF2D03F0B513D655047568325B512AE6 +6AC6F53F3848CF70DE25481CC65D8B1A5793AA +3C4282D111112BEE28AFCA7A3808D4444C4669CA +84EAAAF989219F51AB3476A1B0B5F2246BC306E6 +625C6679C417ED2A8E9BD010DE37D40265074C2684274A4A9876BC4642DE5DECF943C06630BA10 +42DEC8514ACD3F0E57627ABE +75639369AABE52E257 +3E1F97ED +8DE2F2377C433C6C8D8A851E1B +210C3AABA60D0EED97A80975BF65DADDFB8F4A2A23875A +AA2209A0 +3855C9971CEE343544DDEFB609 +2A54D21380C6955ADF83F23180DC726C9481EB65E62953B52ED6 +2974D044 +C14B27E3449899901BE3ED3B06 +0EA6EEA504024DE250CBF1B007BE5F9C38AE699A713FE35B992F8001E8EF13E2EEFC7C9B854105715EB78E66B8023BE18EA8F4B2B7BA +EA9851B3 +37B2274C5CFBE2021206C5B83051 +BC46076F74069655CCB7CF8240AB7CB31A688748F482711EF61C72D5436261071FBA3494EB6360A1BFA70C1E165AAA891FD8293968F4C9E76C4B35225F605A98EB4C53ED1EDD5FCB8AE688FB83BB154A5AB5CFFFB8529ACCC39B4C09830DCBA805A3F2BF11C44656852A0C +1A14083F +5CF4695358364C8D82CFEFD1AD +0E56EEB3A65259DBFF31BEB89BAD909AFF1D3394640702A4DFA60C7B334CB616D8722BE919DCC359CEE3F37EB1793360C7B5F5149E1D79209765310DBB3FA0ECC2FB305D18FFC821F91C02027A2EA1CD70BCAFD19038AD +AD2A2AA3 +C4F2FB98D27CFAF77E6D6F7A74D9 +85BEC53642D9E974CEC0A7D93743E0CD07D966205D4F3AB387FEFB68379E4EAE93A0300DD701A5F162D779D4E2C3A42A4612EE9700C79BA641A392A3D735188D3CCEC645AA29A84BB84459744A0DFB523BC244C4B9AE950555C99B4D79514BB9AAA943AAAD72BD624CE6D5D17987 +D5B84C9E +C36508D90CAB0E7F80553CE425C1 +502DC3E1E1792E6463592C585F28611BBF58A68491B2C884E7109965A5B7062FB080A71A44C893440622EFBCDD63454F2CF29221E3EFD155288577CBB5B5122521269F0DB2294F0DF87E6DF3AEC2CBFC54E37C2821932B706E1DA153253551A55CC09E4A +89B879CE +568F5DA98E55359138B2230FB6 +89F0DB5E8BB9660329580E6680FE422B391FF0CC8280B1BFEECCC86A2397E71F709CBF23413EAD42CD24728FE0928572E8C176A477F5F4ACE2A4299870F6 +C31D24AE +B2C91B0A2A5C8A6E1B1FA13E707E +88CBC5B260146D3902E81B71ECF793972DE34CC6D3627D9AC2ADDE679DE766870623DE1288419120E9E1AC53283503A01FC4B97107B90C6C2D2279AC3E110890FA32AE73C1AA04C1EE370C8B4DE0FA38AE86FAF1D444B20C783D82C382CFFE5D364625D2F68B4F0AEDA61D5613 +E7FC30F5 +9FD8C2119D72FBE6936CBD583D +A8259E1191E8A663233B08DD4D66DBE7439229972A19DD5EC206A342B6DB01F3DB74B4B6B960DA64E86FDB5EC6987EC5AF4F5F1C3BACBABEEFA20177C9BE4BF1AA138D29648E017355F09EC2106C7C1707B85D6CF23BAE4872B23F3F1B0A9A +1378BF3F +8484E0391E0A47A0F5CAEB8A21B1 +D95224B734B5E7A6F0C4B62A3BFA37FC95C47F47D8454840A37157FDF2FA7CE74B5429F6980FC4BFCB4BDA45490B0D1833F9AB3482EEC21E1C1C204DCD623628199D8E0F30CEE7E8287D092903743873DB90B4FB99F658ED7ABC6D34336E4EEED848CBBE6AB4296D25 +A8FA404C +06042BCCCFEC6ED7F137B67C1619 +5DE9D59AA6FE9544C9E727BA08CF7F4512078F9791615062721F7C73AC331054F33701C353E9862EF8A37B1FD888C79FBF1AE1F215F2EBA19C5C7B763816E460EE9BCDEFEB33F7F771D6A599FBD073B845F2199ECEFCDE0749D9DEB75AD001669D900C35 +F184598F +91047C55C3B29F1F8556C93058B9 +C90395986BC5776DD035E3E2AFFF8F4367B96462A0E7EA262D9614749CF85C81A6F5EB5986E3A2D108D8DCD727CB6F02161EB81378E304DEAC4E4DD6A6C8055294C12A8D011E3CB158B74CB76F525FF06EB6E6F86A680B373F8688E0A7E97A3E3FF4C7545F602A61839907E5C66E015CACA46AA5875C8190ED8DAB4F7EEC +FD52 +96F78D02 +FA7F7BAD3649CC69725256DC9C +88264BA95E6D0CCA16BB0A31DA67F2429763756D03C293C9F189CE916E700C021DE20384986A65336E644CC6E0873109FB0A58916475122D46A068F928272B610F3CCFD159D5B81DF9 +7E91B0A9 +0241689E9FB6EE7E8EFC8371D3C4 +FEA5ABADFAA8430B05CC675DE1354615C2BB5DA4A2C2D7FDE23C5169211C99DBF1B2AA37EA67256A46F3337F64A1DF7423211909D2693E20B50D1A3A8175C23C984C0E6E5565DCEFF50EC97A272E565F3E5652E609A0E1D42A17302A614A310480ADA273509F0B +DF6CF029 +CC0F5014F3531968888F3EE21D9B +D24B48E473F36B58E57EA0EDBF6F010ADE1204F631649B9B29A9B675AF569BD3A606249211C2F40A112471E6C68CB376EEFD63AB3458E260ECBB3A01F37F2BD1FD0D5F8093B35E967949860FFCBE295A5D277993AB47C8D843FDD9B080EFA0A9539B8AF5EBC8AC102973F4C02E52563944A0A9B335DE60D0BCCB511ACCCF +DBBF +8A13B5A2 +251CBED8 +A2ED2C06811635A2DF964E0ADE +352E5C7E210DC2DE4ED54688089870C435C03E61BB2FB002D39B117DE94F73D7A057B4B654702CD54099A241776154CC6D2E85959BCB278894D0B596529D6820D15F573B3AB25C538A39A9A4233E4924F75A +F4F58F34 +232DAEEFEEFB9BB598306B44A7 +BDD35F63DEB1B12099DEBB9FDF08AA954A6FE34EEC23DDF4523AC6242A85D3EA3872A7A923FF8F7F9315655EAF311CA4847ECF4DAA0AB46B05F07CB24708C8938213CC2E71EF1218C6979B5CBB4ECFCE74B1CF474864EE405D75A62E +A6724258 +220627708BE0662914CA44A739 +2D8E791D74BF203C818C28ED5E70B4D989E2420EF9EC2C37F850FEFB277B3D8FA3F54F214ADB9E708ADF93E8A678D7F413E30B5B1F62506BEFBD3BA5725E752BAACA54FD3922CF3F7D207B6935B7BCF291CB74322DA59E9667059EFF97 +9DF53171 +38473CE9889C5B26B7B4C5E0A129 +5DFA75CC872DC6DF45C96036937D3CE2B9A7D25CB4706FBFB2571B947364960D80C5FCF417590570C60A04B205D3D341FA2EC795E082B461E98976001F9F196CDC215535092D1FB0F81DA8029CB1D109A1110ABBD970DE9EC769C8279CFEC0EC459D2DF50405F5D01F775C41F19C80C6AEB04FDE845F23098EE4C235DF40 +9B16 +64B89DF3B13E0D5C4935A5F0804846207FB493C2F7C64D79EB2AF8B4BAB959E204205719BD +FA66D04B +90E94087187D6794DBB962B9F111 +E663E753226CA8221C1A969F93361198F826C617E13857E96D73D7163AD9FA3E251A0E2B011D75D5D2E5B663086967FC9C2A17C5D47E802734CB5CAA44A3F4EAA49DD654DF9742B6C8770F3D93EF652A5ABC03C91AD7689DB11098DF663C949C8DD985D314075E38 +5EE8F0F3 +4C1B8AF1696B8CDC32F880A6B2 +1DE38CFF6F5611ACE1093110063D6A7377E151711B48B04C456725E3EDB015AB57A42558D8842FF6254F969BE12C36EBD8380152151049999CF9ACA60A49B94910D9D7B02401B837E76E294AC51A +A6613ADD +C1CD9E59BB5AE1C722377F01B283 +971E81896DDE849DDADD059184945A1413F00C99BE6ABB8E77D072BADB4AA4B7A6C36D94BB4A178FC8616C274F2610A0FA353E53246E94716368121CBBC6A44A85BD1AFBC688379B86FE7A68A1432C85DE7569C8429C1D495EC64EF3C37AFADFB44AE516DB875D8132562DB9CFEA0D2CD967666F77F787045E63324C6868 +089B +5730 +3840FCF0 +DA611902C4B1DA13F17CC71FCB +5081AF3DFC01C344CA0087B027C1B62A927AEFBE465E536C85931F6680849E025FA406EFBAC3E9728FB92FC2684BCB5E2FE4C836 +CA921B44 +01FFADBA50A8AAFF87FD65ABCDAA +308258FC70AF079D8174488718EFA557AF6BAC3518B66C0525BD8BDE64D6CB173867D2E8B5FB1436E6BC03A1183028162D07402C7A41CFE1560677DE409A54853B8BA2FA42BD9FA04C144BDE7DBA3D55B7FECACD0E49F644F5747E3F8FF1DF6DAFEC596B227CCC37FD8C70882F531398DF2F1DAEDD5439A417F06B9E302F +C724 +C1E722EF79BAD297B7542C383866264A3BB6235608B9D4B8B0F0FD35 +B9722447 +642F3E1FB157615B725985685735 +F0B0A47BD808394E6494E9F3A06D56B3A3DFC9BDBCC82AF0BBF87A52C886DC278B749BC73AB9C87BCF02026F319566786FAC402C3E3BB99EFBAB69C8542CB492909FA683E9481F1EC99A7E94D8AEBD5A7F5F69706DA6343BC5BE46E85DC0955C9B022C35AFAC14 +75798FBF +065026241B43C328C2D9899A31 +07DA4861AC99C7774B80A4ACBBF30A3FCE02AEE805B396D5AB7D2A56ABF1A8260867C066141D24EC978E94CB7155F4239B82319BBA119E326AD5BF86A88D2C733C375F7DE470 +F5B344C0 +F19E9D53A93C84C86D0DEEB425D3 +760296EEBD2A677C2DD01BF51DD42AD9B47D387A22AEBB8B9BFC2EEA69BBBC8E21614D2EAAD97CCF8B8C56A3E794AAF9C4AA569EEAA1015DAA5D4A6308939387CEC2176D9ED01461AB18AC0FDD751FDB310D9E68EF363FCDBCC25A188B94D67499E32D77CADB0ED1B800FB2629189DE9A8 +BDFD3E6E +19320EC532FA037E0B8192F374 +63DF15E750855B5BF0080E64D9E228AF33B9393E2E68C16C14F89B8A94F3268D4B095EEF907E17E3CE055117F9F447CD8214B3ADC2B7D8F98909794C2AB6875FC40B60A520E141C52075FBC371B1A7B45973480548884FD352 +3E99B270 +FB79EAB05D06B8F65161077533ED +98A070186669D72E1FD6375085E99CA938F9FD742410F04939540D52D5CCCAA9F4680FA63BDC9F59C3A1DAD2291AD50950F36AB681C0DA2599239C2419110E2FF85DFC6B5D0E08702D3CB6A151A5FFA261F7E86DCDF727553572FF583CF4E0CA93A21D1770AA3824C9A285CA4D4A574CD019A81F1B0AEF5581 +F720269F +E6258C909A64B439EEF7F57BC5 +8432C12D1873A424130BFDE43C240790F497B8DEE4A970D2DCCC089A381FF2DBF00601A8CD7EDD8491ED377B8475EDFB18509CEE727B8897F15446BDEDC224303F25EE25 +19196417 +3E0E0F6D96426144C39A44EEEC64 +39D7AD0860F9CD6C488B1F32C50ED2962BD727197370FCA9C8B0F8827BD435DBA6720A5B652FA2E31EEF503758836069C39DED4E2E7029F998A6E60CB1D4B6CE7E1E3654B3A5D2D7F9B915A9408DEC9FF4F80B52CFD4B13B94C7D7105E83DD12966576737CD67FC5AF78C5EF0229E4190A326B2EB55538A704A6A060E418 +63C9 +3BE193BC9087BDEF9A5412 +0BA90677 +EA565666A5EB2FD0A71F8430F7C7 +563E306B1F5A6FE5F879B9F0A9A076A41815B55F82DD35894926B2F0913656BA301499354BC19CD4065B3E8B08097894CC3129DF4A2C4E2C4EB463BB4553C5B398A6FA828DF69653D6C9A18FD2BE7CB998EE117121F9D7B8EB9F4C89D51AD6EEF18053988F7F86BFDDDFEF3D4ED0DBF59B37E3A55FDF070D99EC4F0E2B2B +6608 +599E66DE6A92E337B61677E8C0BABB95E72D70C44071 +D3C8DA6B +D346B4C19D64595D0B844860A45F +F4F28683DB3A183686E73B1D29D45ED73AB1FC3D70FAB2940F322602B5F6B68337AED9716EBCCFBA7EEA207B281C138FDF13B9562762B69BFCC435F6F08EE7B290AEFAAB817070BECEAD9F4829690EA81D6FC7116A99B86E11786F6387BF3EE1044DC695CDD2B42FCE8441A68D61F115115BC9F8B0E9C89C44D60C28044E +93E4 +96 +6510B60D +53F70CE8A06F74CD8D49CF7407 +34665C583A5F25FBF57FE78CC2E99387A19A92255C36A44A +63044DC8 +D5F24C109D91F8A20247D5A26906 +47943BF7A26C6336 +27F39DAD +4AC678A2B9DD7E4AA91278EE45A5A4D837EB63B87C2D058898CFB5D04A69F2044A5F +903AEB0234CDB5E2DECC5CF4472DA25E7227A9E3E9923774EA75D4EA04816061355A5F580DE4 +3E3A342E374BFE75F5251FEC1617669C214D575E917182F88F8DEB +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +%Defining font PSOwstdutchi +%!FontType1-1.0: PSOwstdutchi +10 dict begin +/FontName /PSOwstdutchi def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001000 0 0 0.001000 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 1 /C0097 put +dup 2 /C0099 put +dup 3 /C0100 put +dup 4 /C0101 put +dup 5 /C0105 put +dup 6 /C0108 put +dup 7 /C0112 put +dup 8 /C0114 put +dup 9 /C0115 put +dup 10 /C0117 put +dup 11 /C0118 put +dup 12 /C0122 put +readonly def +/FontBBox [-144 -227 513 728] readonly def +currentdict end +currentfile eexec +D9D66F633B846A989B9974B0179FC6CC445BC7C8A959A39A32E9DCE7FAEF17EE3BEC9F +50E1A6FCA651FC4B3769A0A91041557502E25A5D6180FE25A3D11BF079E1DF66E54EE9B7C229AF891739707A2A0EC140306B5E43E52B79BFB89E459E50 +6EC6F610A70775A31C460976C4F79449D86E57ACE491E5C6BF20CC4307B1DAF7630252 +E9AF8CFB69B50EDAE9D36A6104AFEF8832F920FD2346B2C7104CD11E3BEE999CFA9F5A +49DB3173EE48D1C82994237F360407B022E0B4 +502E94EA8B493651EF2D03F0B513D655047568325B512AE6 +6AC6F53F3848CF70DE25481CC65D8B1A5793AA +3C4282D111112BEE28AFCA7A3808D4444C4669CA +84EAAAF989219F51AB3476A1B0B5F2246BC306E6 +625C6679C417ED2A8E9BD010DE37D40265074C268425D38D48EC7466FFEBA5C7142506D78DF24F +060B3D6F22F43C1605F7E610CEE0 +821C68FB13C01DCAB5D07ED3C9CA63CA4581AEE2EFDA66E4F9CBF723BB2C2673F2B11B7D38F02CC9F9A2C6025D8E959DFA89E9EA116A6AE1B47510D60570DEB71EE01F57DA8765EA6503F97F935E60A71E32AC94455B0EC0E65CA33F394477EDCB36A8E71070AB03C6DC21B89D580BBD51193BBBAE3DA6B767ADA66EF889 +A4B0 +F4D4CA8F7F808E66AE66AEB842 +06E2C14E +2BCF8BDA455D135FA82C81845D +E64C387FBB5DC0824E803571D4BAD4983C55C9B9C16EBB89BDA0CBEB648F02BFB0778CFABF59255975374030831E0055E4F8068875E953D8FAF8D32643FC8CAC16DA4F5DB515F675F1809B0B76C64C18F81417F8582E6B543D0A1BFE7A02B169 +00A88C47 +34AFEA5A92FECC14AC93C3B35853 +7D4D860FC0836A48D3770FDDC48D85F4DD624A95362F64A568EBBA4A127F9EB054F1759C4DC7256FCF470FCFE74B794CCF62359A11D5630E22D79AC4F98F34DD8FB549C504CA9E401891F3D95D7D5DCB4585E8450714A6A0CA2FE7B7728E9F125215E51E591F3A68A8889ACD1DA57F13FA466577873A009802BA7AB076AD +8560 +FAE23309E6FF404FA1585DBF6AF8CD0E0CFE39E344D9255E016858FA654467B7D42D1DE4ECBFF98B8C717BDD5ABA7C59 +B475C574 +4D209E659E9B5E366D041A3144CA +A1C4F19CB0023291FEA07365F07CF7738D0AC14DD6436FC6F663075C1CDFD5146A80F4D957DADA7EFF03136161F0A79B59CB4DFB02FAFB580788DAEB7EFBA0CC7F33981F9E13E0205DED63007C617D87AEC422BFE7085F18F8DD419EAF49E4F915F984D96B +CDB93259 +DAD462AE15670BA4F64F891D65AB +0E87927B961BABC2ECE37D681C6DF5C3E4B1F7386FD77B1090DD3588A6470303531F67608D92C8F7BB7BF16FE6E25BBA14B081F0C4912302770008ED3FE26D869D5718EA356031E6D37C4317FE704931F22401EE21E66F4BCD03B253DAF492F1E53EB5DC96CD54BBD9E141285A834D867E453DB9BE063FA3B1 +2D74D564 +E138D2A61EBDC31A1E861CEDEFB4 +941ACB640A72FB436C6D0210B0B491D1A083BF079DE47EEB82E3FC37B1F87168F13AB56BC4680FC5762C50B979B3DAE6C5CC91A2E5DB4F7366F09F510789D648FEEB6844E5EA7ABA57D7470E43D632B49DC47B2709B00A9A5911B2EE72D810F415DB25EFC5 +B35F5298 +F7C857DC0A9D01690311360B4D3E +D785EC76C6F6D5B3C716E1060B8CD5283ABB1C437C5A3ABCD48B31D93F9426B01F9680D57054B179C5420FA65A53FA2CDD572E1F9F8B366DFB91D1A722EE31E49B54F7404DCD4E381D167B3C8F35ED9A38F1B2441968D7956339F35CAB79D9591CA038577D5A8437072B147E14DE4786D4AEDA03AE56EB5EEB65C5AF19AC +71C0 +6A6980D6796C034FD5220781D694EEEFAEE2B52D5C362BA61548EF86D24D2F1F43C1489BF7249051DF5A +DD44F25B +4B0E35A6A7AC1BA699BE673E1D +7C76577E47CFE52988087C8B909757CDBA53637740AFEEEC3EFD95CBB63DEF39239B53D245EC7443519F9807EE54C76E3B010EB49F5EBB64529EDAF433130ADA45A229E3B32162AF317B14E40CAEA319DC0B56467DBE0C5630FA6E +4D8AF23C +0CE4644E9B2AF0823F2FD580DFDF +477821A9F078DFB8D17F61F80F4BE7658B9A6ABD0E198622FD862D0334F216BC7522AB29136EA62870E8F09AD786865DE2D309C113C453E8B51E5FFC50D560C80955F4C4A34DF47EA1CF5F5F88338EC0CE802B9ECAF81E70DA5DC48A9C62AE59C807A45637E12E4F398E011E670919AC8D3DFE37F03B +38EDF238 +9A31D413DB2BF7F5F84F7668B9D7 +1129FCD5BD108EA1E835D7C1715061ACEB45BDA632C0CAF9E5FDF65F16015FAE4D7F78A76DCA2BF357BA802F9E8C00E0516C0B2FAA3133BA1E8749765C1CCDF061ACCC56B86DF5E0937F6428CC95EC555A43EB999B16CD10DC628485835A334251082A78D99C5FDE1E39D51A9797389B5AF4B06B282BA42E98F3FF8C645F +F141 +B422667D981C65ADACB0E0355B51F759B3728A1E63068B +0CA42B90 +F20E1FB9EC24F448BC16381A96 +F746C29080AEA0259522E6917CBEE0303885B82170F141A431BB19C043167DFA8FF6925248EB21A1DEC82159A1C720B2EDCB71A3ED5F98E4B6431C7375E3050C86B22E7323CEEF20E39AE02108C13D0E9A4B645D2D167B22B495 +2EC0729D +9D8B405F22013D3E566CD037138B +3294CD511AA7DA0A62618ADE291928190FACF84E4279A51D19E0C8706719F33A7B154EC9F36ABDA3336740BA2187DD329354D4EC65262F8059925C075ADD54F9262D033E212183BF2C02EC0541A06AE76815E22F9B161298C5569AB74031974F223294B589E58502D080EB3A06FAD1BAC9D6BD7AC3D9AC498AB63F7C0AC5 +4BB3 +58A47FC6D4A3695B5C +E4E5C5F6 +DB7A68DEC5A750C70F5EF2579337 +B95BAC501DC9415A +1B1CFFBC +98ED8FAF7CA22B3F3E6760CC8FD2E7191702A30A8D64D30FC543F315604BE6760BD6 +01B4C2213CD7C9607CD048991841D11DABD216A2512CF4B0E43962CDEE9A1E31FE5A38712526 +CBED0843198973B3B25FB6DF65BD6344A2E8D20F440BF07B991114 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +%Defining font PSOsymclas +%!FontType1-1.0: PSOsymclas +10 dict begin +/FontName /PSOsymclas def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001000 0 0 0.001000 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 1 /C0069 put +readonly def +/FontBBox [106 45 775 713] readonly def +currentdict end +currentfile eexec +D9D66F633B846A989B9974B0179FC6CC445BC7C8A959A39A32E9DCE7FAEF17EE3BEC9F +50E1A6FCA651FC4B3769A0A91041557502E25A5D6180FE25A3D11BF079E1DF66E54EE9B7C229AF891739707A2A0EC140306B5E43E52B79BFB89E459E50 +6EC6F610A70775A31C460976C4F79449D86E57ACE491E5C6BF20CC4307B1DAF7630252 +E9AF8CFB69B50EDAE9D36A6104AFEF8832F920FD2346B2C7104CD11E3BEE999CFA9F5A +49DB3173EE48D1C82994237F360407B022E0B4 +502E94EA8B493651EF2D03F0B513D655047568325B512AE6 +6AC6F53F3848CF70DE25481CC65D8B1A5793AA +3C4282D111112BEE28AFCA7A3808D4444C4669CA +84EAAAF989219F51AB3476A1B0B5F2246BC306E6 +625C6679C417ED2A8E9BD010DE37D40265074C2684268F16195489648993B9C4D3B534FA887C +DEF605FA87B991F4D20A8F78DACE +5A54C070E03D5C59D9D2D3E06B09CEE028D68B62AB3AEC43C1DD20BA70D288597D9BD8E06818FF764EBAB436723988E8D7CA59E16D39032516BFC5D552ACDEEC6BE938BEF2F43CFFBC811C3626C4DF5F8CF080676520B51C60CEDAD1FE6C92D1431C702174CE517A8FA9377D075A0B6833DAB101DB65397F1419EF5F0016 +004F +6F0824F9657BB4F1C8F981709956865F6855EFAE +9242AD55 +91BBBEE163D844DDA894E13190C9 +2480439E4C71CADA +BD043A9B +A315CAF72652AA7FE6DB2E84D82A6111CE4DE90C02DA0AFFE2620922262A45AB4ED0 +EEC9F4520DD12703442F7D028D4526BD8B771E09FBE11B2749E2D3906894E8D4BFD3F379F14C +3C874F550606965E22FE487B247B5C2D06728490C8F2A3B588CDFC +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +/DPIx 1270 def /DPIy 1270 def +72 DPIx div 72 DPIy div neg scale +0 -13970 translate +1.00 1.00 scale +/wst:dutch12 12.00 /PSOwstdutch newFont def +/wst:dutch12b 12.00 /PSOwstdutchb newFont def +/wst:dutch12i 12.00 /PSOwstdutchi newFont def +/wst:dutch10 10.00 /PSOwstdutch newFont def +/wst:dutch14 14.00 /PSOwstdutch newFont def +%%IncludeResource: font Helvetica +/wst:helvps10 10.00 /Helvetica /wst:helvps ILEncoding 0 declareNFont def +/sym:clas10 10.00 /PSOsymclas newFont def +%%EndPageSetup +GS +0 13978 10801 13978 10801 0 0 0 clp +wst:dutch14 SF +0.00 0.00 0.00 1.00 setcmykcolor +<1524322f2430250a010b010c242d22272c20302a01252e3001142420313330282d2601152432352e302a0117> 2207 558 0 7384 -1 s +<2430252e302c202d2224> 7375 558 0 8593 -1 s +wst:dutch10 SF +<0809> 9346 13385 0 9522 -1 s +wst:helvps10 SF +<4e6574706572663a> 1322 13267 0 1949 -1 s +<205265766973696f6e20322e313b20436f7079726967687420> 1949 13267 4 3868 32 s +sym:clas10 SF +<01> 3868 13267 0 4019 -1 s +wst:helvps10 SF +<2031393933b131393935204865776c657474b15061636b61726420436f6d70616e79> 4019 13267 3 7133 32 s +wst:dutch12 SF +<062c> 1589 1431 0 1940 -1 s +wst:dutch12i SF +<0b01060a04> 2033 1431 0 2495 -1 s +wst:dutch12 SF +<312432> 3177 1431 0 3432 -1 s +<00322724002b2e22202b> 3432 1431 2 4234 0 s +<0031242d23003128382400322e00> 4234 1431 4 5335 0 s +wst:dutch12i SF +<0b01060a04> 5335 1431 0 5797 -1 s +wst:dutch12 SF +<00213732243107001d0e242520332b320a002b2e22202b00312e222a243200213325252430> 5797 1431 5 8895 0 s +<312838241e> 3177 1676 0 3582 -1 s +<0614> 1589 1980 0 1967 -1 s +wst:dutch12i SF +<0b01060a04> 2033 1980 0 2495 -1 s +wst:dutch12 SF +<3527282227> 3177 1980 0 3703 -1 s +<0021242720342431002b282a2400062c050031243232282d26003227240030242224283424003128382400252e3000322724> 3703 1980 9 8180 0 s +<0030242c2e3224> 8180 1980 1 8895 0 s +<31373132242c07> 3177 2225 0 3835 -1 s +<001d0e242520332b320a0030242c2e3224003024222428342400312e222a24320021332525243000312838241e> 3835 2225 6 7801 0 s +<062f> 1589 2530 0 1882 -1 s +wst:dutch12i SF +<03050809070402> 2033 2530 0 2642 -1 s +wst:dutch12 SF +<312432> 3177 2530 0 3432 -1 s +<00322724002328302422322e3037003527243024002f282f24310035282b2b002124002230242032242307001d0e242520332b320a0031373132242c002324> 3432 2530 10 8825 0 s +<39> 8825 2530 0 8895 -1 s +<2520332b32> 3177 2774 0 3595 -1 s +<00252e30003227240032242c2f2d202c03040022202b2b1e> 3595 2774 4 5768 0 s +<0631> 1589 3079 0 1847 -1 s +wst:dutch12i SF +<09050c0409070402> 2033 3079 0 2712 -1 s +wst:dutch12 SF +<3527282227> 3177 3079 0 3703 -1 s +<0035282b2b0031243200322724002b2e22202b0031242d2300202d23003024222428342400312e222a24320021332525243000312838243100322e00322724> 3703 3079 12 8895 0 s +<34202b3324033104> 3177 3324 0 3900 -1 s +<00312f2422282528242307001d0e242520332b320a0031373132242c0023242520332b3200312e222a2432002133252524300031283824311e> 3900 3324 7 8806 0 s +<0619> 1589 3628 0 1882 -1 s +wst:dutch12i SF +<09050c0409070402> 2033 3628 0 2712 -1 s +wst:dutch12 SF +<352728222700212427203424310029333132002b282a240006310021333200252e30003227240030242c2e32240031373132242c> 3177 3628 9 7923 0 s +wst:dutch12b SF +<101b172200061c1a11171b0006112011151e111a000e1c121813201f> 1271 4014 3 4215 0 s +<0b0c0f07> 1271 4362 0 1866 -1 s +<04> 1870 4362 0 1928 -1 s +<00> 1928 4362 1 1960 0 s +wst:dutch12 SF +<001b2d2836000e2e2c20282d00192e222a243200322431323100203024002d2e3200222e2c2f282b242300282d322e002d24322f2430250021370023242520332b320700132500372e33003528312700322e> 1960 4362 15 9046 0 s +<002c2420> 9046 4362 1 9461 0 s +<39> 9461 4362 0 9531 -1 s +<3133302400322724002f2430252e302c202d2224002e25001b2d2836000e2e2c20282d00192e222a2432310500372e33002c333132003024222e2c2f282b24002d24322f24302500202d23> 1271 4607 11 8241 0 s +<002d2432312430342430> 8241 4607 1 9113 0 s +<0035283227> 9113 4607 1 9531 0 s +<060e0e161f1b15131c> 1271 4852 0 2649 -1 s +<00202323242300322e00322724002c202a2425282b2407> 2649 4852 4 4732 0 s +<0b> 1271 5156 0 1434 -1 s +<001b2d2836000e2e2c20282d000e2032202630202c00192e222a24320019323024202c003224313200030e111f191a180f0b14040028310034243037002c332227002b282a24> 1434 5156 11 9308 0 s +<0020> 9308 5156 1 9531 0 s +<1a0d171f191a180f0b14> 1271 5401 0 2724 -1 s +<003224313200243622242f320032272032002c24313120262400212e332d23203028243100203024002f302431243034242307> 2724 5401 7 7351 0 s +<1a2724> 1271 5705 0 1631 -1 s +<0019282c2f2b243132001b2d2836000e2e2c20282d000e2032202630202c00192e222a24320019323024202c003224313200222e2c2c202d23002b282d2400352e332b23002b2e2e2a> 1631 5705 11 8926 0 s +<00312e2c24> 8926 5705 1 9461 0 s +<39> 9461 5705 0 9531 -1 s +<3227282d26> 1271 5950 0 1733 -1 s +<002b282a2400322728310a> 1733 5950 2 2552 0 s +<02> 1398 6254 0 1504 -1 s +wst:dutch12b SF +<00031c1d20031b13201d131e14031b13201d131e1400022000> 1504 6254 3 3692 0 s +wst:dutch12 SF +<0e111f191a180f0b14> 3692 6254 0 5071 -1 s +<1a2724> 1271 6559 0 1631 -1 s +<00061200262b2e21202b00222e2c2c202d23002b282d24002e2f32282e2d> 1631 6559 5 4632 0 s +<002831002d2e320034202b282300252e300020001b2d2836000e2e2c20282d00192e222a2432003224313200202d230031272e332b23> 4632 6559 11 9531 0 s +<2d2e32> 1271 6804 0 1572 -1 s +<00212400312f242228252824230700122430240020302400312e2c24002e25> 1572 6804 6 4543 0 s +<00322724003224313200312f24222825282200222e2c2c202d23002b282d24002e2f32282e2d3100203420282b20212b2400282d0020> 4543 6804 9 9531 0 s +<0e111f191a180f0b14> 1271 7048 0 2650 -1 s +<003224313207> 2650 7048 1 3080 0 s +<062c> 1589 7353 0 1940 -1 s +wst:dutch12i SF +<0b01060a04> 2033 7353 0 2495 -1 s +wst:dutch12 SF +<312432> 3177 7353 0 3432 -1 s +<00322724002b2e22202b> 3432 7353 2 4234 0 s +<0031242d23003128382400322e00> 4234 7353 4 5335 0 s +wst:dutch12i SF +<0b01060a04> 5335 7353 0 5797 -1 s +wst:dutch12 SF +<00213732243107001d0e242520332b320a002b2e22202b00312e222a243200213325252430> 5797 7353 5 8895 0 s +<312838241e> 3177 7598 0 3582 -1 s +<0614> 1589 7902 0 1967 -1 s +wst:dutch12i SF +<0b01060a04> 2033 7902 0 2495 -1 s +wst:dutch12 SF +<3527282227> 3177 7902 0 3703 -1 s +<0021242720342431002b282a2400062c050031243232282d26003227240030242224283424003128382400252e3000322724> 3703 7902 9 8180 0 s +<0030242c2e3224> 8180 7902 1 8895 0 s +<31373132242c07> 3177 8147 0 3835 -1 s +<001d0e242520332b320a0030242c2e3224003024222428342400312e222a24320021332525243000312838241e> 3835 8147 6 7801 0 s +<062f> 1589 8451 0 1882 -1 s +wst:dutch12i SF +<03050809070402> 2033 8451 0 2642 -1 s +wst:dutch12 SF +<312432> 3177 8451 0 3432 -1 s +<00322724002328302422322e3037003527243024002f282f24310035282b2b002124002230242032242307001d0e242520332b320a0031373132242c002324> 3432 8451 10 8825 0 s +<39> 8825 8451 0 8895 -1 s +<2520332b32> 3177 8696 0 3595 -1 s +<00252e30003227240032242c2f2d202c03040022202b2b1e> 3595 8696 4 5768 0 s +<0631> 1589 9000 0 1847 -1 s +wst:dutch12i SF +<09050c0409070402> 2033 9000 0 2712 -1 s +wst:dutch12 SF +<3527282227> 3177 9000 0 3703 -1 s +<0035282b2b0031243200322724002b2e22202b0031242d2300202d23003024222428342400312e222a24320021332525243000312838243100322e00322724> 3703 9000 12 8895 0 s +<34202b3324033104> 3177 9245 0 3900 -1 s +<00312f2422282528242307001d0e242520332b320a0031373132242c0023242520332b3200312e222a2432002133252524300031283824311e> 3900 9245 7 8806 0 s +<0619> 1589 9549 0 1882 -1 s +wst:dutch12i SF +<09050c0409070402> 2033 9549 0 2712 -1 s +wst:dutch12 SF +<352728222700212427203424310029333132002b282a240006310021333200252e30003227240030242c2e32240031373132242c> 3177 9549 9 7923 0 s +wst:dutch12b SF +<08> 1271 9935 0 1399 -1 s +<1c1e130005> 1389 9935 1 1872 0 s +<0f0a00050d09000e201e13111a> 1867 9935 2 3324 0 s +<0b0c0f07> 1271 10284 0 1866 -1 s +<04> 1870 10284 0 1928 -1 s +<00> 1928 10284 1 1972 0 s +wst:dutch12 SF +<0010> 1972 10284 1 2147 0 s +<2e3024000b> 2139 10284 1 2648 0 s +<1a14000b1713> 2628 10284 1 3384 0 s +<00322431323100203024002d2e3200222e2c2f282b242300282d322e002d24322f2430250021370023242520332b320700132500372e33003528312700322e002c242031333024> 3384 10284 13 9531 0 s +<322724> 1271 10528 0 1561 -1 s +<002f2430252e302c202d2224002e2500222e2d2d242232282e2d31002e342430003227240010> 1561 10528 6 5017 0 s +<2e3024000b> 5009 10528 1 5509 0 s +<1a14000b17130500372e33002c333132003024222e2c2f282b24002d24322f24302500202d23002d2432> 5489 10528 7 9461 0 s +<39> 9461 10528 0 9531 -1 s +<312430342430> 1271 10773 0 1820 -1 s +<003528322700060e0e161f1016180f00202323242300322e00322724002c202a2425282b2407> 1820 10773 6 5806 0 s +<0b0010> 1271 11078 1 1618 0 s +<2e3024000b> 1610 11078 1 2128 0 s +<1a14000b17130019323024202c003224313200031016180f1f191a180f0b14040028310034243037002c332227002b282a240020001b0e171f191a180f0b14003224313207> 2108 11078 11 9526 0 s +wst:dutch12b SF +<0b0c0f07> 1271 11382 0 1866 -1 s +wst:dutch12 SF +<0a> 1866 11382 0 1924 -1 s +<001a27240010> 1924 11382 2 2517 0 s +<2e3024000b> 2509 11382 1 3025 0 s +<1a14000b17130024362f2e30323100202d00332d30242b2820212b24002f302e322e222e2b0700133200283100282c2f2e3032202d32003227203200372e33002436202c282d24> 3005 11382 11 9531 0 s +<322724> 1271 11627 0 1561 -1 s +<00302431332b3231002220302425332b2b37002031003227240030242f2e303224230031242d2300302032240022202d002124002c33222700272826272430003227202d003227240020223233202b0030242224283424003020322407> 1561 11627 16 9531 0 s +<1130242032> 1271 11871 0 1803 -1 s +<00222030240031272e332b230021240032202a242d003527242d0030242f2e3032282d26001016180f1f191a180f0b14003224313200302431332b323100322e002c202a2400313330240032272437> 1803 11871 13 9531 0 s +<203024> 1271 12116 0 1562 -1 s +<002d2e32002c28312b242023282d26070010> 1562 12116 3 3129 0 s +<2e30002436202c2f2b2405002e2d240031272e332b2300> 3121 12116 4 5214 0 s +wst:dutch12b SF +<11192111231f> 5214 12116 0 5818 -1 s +wst:dutch12 SF +<0030242f2e303200212e32270031242d2300202d23003024222428342400302032243100> 5818 12116 7 8894 0 s +wst:dutch12b SF +<201c15132016> 8894 12116 0 9462 -1 s +<24> 9462 12116 0 9531 -1 s +<131e> 1271 12361 0 1457 -1 s +wst:dutch12 SF +<00252e300020001016180f1f191a180f0b1400322431320700132500372e330020302400262e282d2600322e0030242f2e303200200031282d262b24002d332c2124300500372e330031272e332b230030242f2e3032> 1457 12361 16 9531 0 s +<322724> 1271 12606 0 1561 -1 s +<0030242224283424003020322407> 1561 12606 2 2723 0 s +GR +eop +%%PageTrailer +%%PageResources: font Helvetica +%%PageProcessColors: Black +%%PageCustomColors: +%%Page: (14) 14 +%%PageResources: (atend) +%%PageProcessColors: (atend) +%%PageCustomColors: (atend) +%%BeginPageSetup +bop +%Defining font PSOwstdutch +%!FontType1-1.0: PSOwstdutch +10 dict begin +/FontName /PSOwstdutch def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001000 0 0 0.001000 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 1 /C0032 put +dup 2 /C0036 put +dup 3 /C0044 put +dup 4 /C0045 put +dup 5 /C0046 put +dup 6 /C0047 put +dup 7 /C0048 put +dup 8 /C0049 put +dup 9 /C0051 put +dup 10 /C0052 put +dup 11 /C0053 put +dup 12 /C0058 put +dup 13 /C0062 put +dup 14 /C0065 put +dup 15 /C0066 put +dup 16 /C0068 put +dup 17 /C0069 put +dup 18 /C0070 put +dup 19 /C0072 put +dup 20 /C0073 put +dup 21 /C0076 put +dup 22 /C0077 put +dup 23 /C0078 put +dup 24 /C0079 put +dup 25 /C0080 put +dup 26 /C0082 put +dup 27 /C0083 put +dup 28 /C0084 put +dup 29 /C0085 put +dup 30 /C0091 put +dup 31 /C0093 put +dup 32 /C0095 put +dup 33 /C0097 put +dup 34 /C0098 put +dup 35 /C0099 put +dup 36 /C0100 put +dup 37 /C0101 put +dup 38 /C0102 put +dup 39 /C0103 put +dup 40 /C0104 put +dup 41 /C0105 put +dup 42 /C0107 put +dup 43 /C0108 put +dup 44 /C0109 put +dup 45 /C0110 put +dup 46 /C0111 put +dup 47 /C0112 put +dup 48 /C0114 put +dup 49 /C0115 put +dup 50 /C0116 put +dup 51 /C0117 put +dup 52 /C0118 put +dup 53 /C0119 put +dup 54 /C0121 put +dup 55 /C0122 put +dup 56 /C0262 put +readonly def +/FontBBox [-25 -238 920 766] readonly def +currentdict end +currentfile eexec +D9D66F633B846A989B9974B0179FC6CC445BC7C8A959A39A32E9DCE7FAEF17EE3BEC9F +50E1A6FCA651FC4B3769A0A91041557502E25A5D6180FE25A3D11BF079E1DF66E54EE9B7C229AF891739707A2A0EC140306B5E43E52B79BFB89E459E50 +6EC6F610A70775A31C460976C4F79449D86E57ACE491E5C6BF20CC4307B1DAF7630252 +E9AF8CFB69B50EDAE9D36A6104AFEF8832F920FD2346B2C7104CD11E3BEE999CFA9F5A +49DB3173EE48D1C82994237F360407B022E0B4 +502E94EA8B493651EF2D03F0B513D655047568325B512AE6 +6AC6F53F3848CF70DE25481CC65D8B1A5793AA +3C4282D111112BEE28AFCA7A3808D4444C4669CA +84EAAAF989219F51AB3476A1B0B5F2246BC306E6 +625C6679C417ED2A8E9BD010DE37D40265074C268421901DE48B643CFB857CFBB85E253EE2EA5A +17559F68A849A879FFBD0B99 +CFDA88F0C12453164E +1381B4F5 +F516C6F24D6DE7BE4AD031472249 +C8FDCE5D99A8876BE1E0B7DBCAA7A6A16B2C2B1442F344AFF480F183FD3CEA05D17301E5D412190BF8FF06F9ADA8C89133677A3F164413905FD9AB232FF3C6B152617DD5761B867378214F80AF7E62AEBAFBF0836DB16F3960A45518711600B2A7F0D4D3DBA8E6A434DB5F632A30635BFD7DE018796383481D79347B713A +5962 +877DB4669C7582257ED3B462 +1976B18A +1AEF6C96D49B30DC740E8BAB3C +99BCA591DF2CE87D3A586BE404993C4DC7BAF2B70115880497E4415EB5BDB708F530BD1F3D5C2466494ED9AF30DFC02224510ECCFD60F89245 +E84148EE +681035A39D4F4E3507B45966A9 +F6C2FDA06F52ED7EBCFAEAE063AA690A2A3BFE314FA254 +904F693E +8FF817ED4FFC49C4FA62F4E106 +93029CE0458D8498685012CCEB60A35E91259AB2FFF5B5CD8D9BD2C1FC11FF +CEFFB33A +F92FA3F86485739A6DE0D67A43 +23F17D91F2FD682A1241B16EA1BA80DD92B2A33317D88D8E1F45589C +EB961B94 +1130DA244FB2CAB32F84058A6B +27BF3542D510A8C6A3D88A9A2CB1BBE59FB86AF11356826CB75B97B9E10037D29BB666F3EB48DB322065A462BD44EC61C22746546CDDF74CE1463570B985A710E4A6232727643017DDDF +7E2F6BD6 +7FC059460A53F1D13DA9DCE374 +762E175D1DC9902BED3616E9AA88DCB1716B9994B3B4FF08EA5EC0A59516830495E3BA6F27E2EF06F2B3F269383556DEE76B3FE818ED5B80E2B3299EAE3C3B +224A645D +C2AA0D34159223DEAE327779008B +D866C81AE4E7B60DC967A227C95BC85BC2BBF75316CCE0B973C32C39810055923FD68F2772DEAE34572ED7455BE063F45DACF129AFB104068FD14060C3EF05AC2FE417B6F7AA5B0934B9A4A7DF6CAFBD5B2DB90880893BD0716E6D0B9D356D8939A356A5DD2389D17D33C0143EA690 +C3377356 +41C4ECE026F123907087585797 +FBD853402A0710C0CB4ED296B0FCD096834E6B1EA7C41A80C2308E901CB8741DB77C7376E94C9E55500C278BB7F7AC8761A910CF60B8DAF6FFEC +452145BA +4F366D84FFA16E23DEAC2807EB +52000FA916ADE759A97FA0226D1F9A6425C93C76DFFF249CBC269907545514508E9956ECF54F4575853DE8871F3BBDF82ED5B6503E379951F78348E7E4EC6FAE349C195589A52E7BC8FEF1D3BE4FE81E87B9A8BCCE27D0A62BC55B754226E8A14A +561BD522 +89E08D480FD79AE287E59FFD88 +E0AAB56ACEA3F3BD00480802845FD214DDCB84B47740018D0EC86531DD09C1DC4DD46F83B1C245D96CD3F0BB625316A9912D8D85D0DF +1577571C +2ABB86D1DA496F1EE94A5D3FD3 +AB69E24750521F2EBFCE36C20D5FDB03259E2AC31C312B2B6CFF91F54E83A3064CE1A16435B8A9 +88215A71 +8E16DB48AC2B891D18F17B7ED3B1 +9BBC746D69E319DF8609EA7DFE97E75E00F07B9EC9958AAE0F34105B803A936891282709D3648E68553CBFDF029155B88854AEADB97B0DA0BE37210308365507FCB3658984E1F49F45DBE07CD6D17E054342C67DBA79A000BF10DD8E92FF3872BCEA27B8E267A7E43520B4F0B4D5EFB5348052 +BC82E2FE +E6CA3DFAC9CF5410816CBD01F527 +175A702D092C5BBEA26C941CB7F525CBE6D6ED51D2E0BFC19E5E5F2EC8D0A0D85F4F7F7FBC5D9ECB3D78630701AA6E048F78A308BFA7DEE0F26106125013C7B8A38F3BB231ED9F29A8CC799AC42278DC63A04842FF782325879240F898867AF83EF329AB38087421426A3B2EF42957D91D146C210FB0BDC1282CD928A363 +6E37 +14 +A42B9855 +4FED3944A006133841DFA29EF3 +8C14A7D3B7A1A3C366F7C4474B5E9C2DB74CD41E975FC38CAB8A3FA4A1CDD92712697098213C71B189AA670AFB81F0165F008E0AA0D03B4D412BE1C1003A988D64B2FA717E61C783FEAA9B546EBADF8985C6470B6442F9A634B139D14491F59AE1AEA3 +E5DEA381 +ADC4D7FDDBB2219E03CBED0FEF53 +FFB91E2198C47E366D9A6F8EDD6D91595E909384A91B3A9F5953AA7CC87C6E039A139B35D5AB150FF0EA34141D4074423BE3BCF948F3F7AAD392CB420947CABCB0DD5869808E29822A88B1941D41C3F22CAD41CAE00CEB769C8F84F0EBCCE4FE03EAA16C61CC9D81E3BFE88A8597CFB4E2324F832A9F6BF2F3DAF922B9EB +EB09F556 +B71F064245AAF225C383E6B58BC8 +79DC734D45CBFB9585C9CDD193AB398F4AE178C252F054EEC92D3FFA71EF841D6862A28E8BB986B4D5C161D0254CA6E1E9CB9F18631F5AD250CBB1759F400FAB5B1E33E461AC20B18ACBB3F4F056AEDF2176B2434E415005EF7F406A9AF6AA832B64CC7F36742697CA +DB08E330 +C5258F71F179A69BFE7434649308 +0868F56AF2AAB58F0A963C75B4450EABCEFE79B2324883F4C6EFF630A0844D2F580F89CE2F0F42BE178D9DFCD5639F8B884F3F7F34AD227D10D207A94BA99DB9783E7581438452BBA8E8D6A28F8047E164948AE956284F529988685400DD2A048CAF7449CC8C778C8285DAECF2B0D42B48710E5301F3BA08DFD7658E38B1 +BC19 +03E5A28DC9D3D7033E9340 +3E40F0C0 +E91E25234347F01FA9DEC25650 +7EB05706FA6209D6E2369F24C48C5F8EC52021E621F509CADA1EC786D913EF014E53D79E58851DE7178D341F151749729159D885A11B070F2D14C1 +43C85962 +B6C670DCBEF1DF8F89E7532BD1 +9CFDD6922A308C89AE76052F7C19796A41C176EC0491CF1DF619D98A3D5B139A2F1DAC467B23EDCB65E0B3F77F59E9B153F02AF7A3686372F9014A7249C8FE4A4EE455BC4BB487 +0C2E4786 +F12C3A13DD8F41167C78D210AFD2 +C02131252A27CC86DD32EA41D422DC1C6A086F6345EC036935A7D0C26DD9319625196C6ECFEE10EDAF316370F30F1D8C3B42C0B59AE473BF9A6F4BBD2815982FD6228E1A36483B24FEA8D49479280106C1F3DEF7FB845B408B4BF328F7E8DB2AA301218E28D21A3536F586940D8BE1 +6EAE0339 +2AF2B5A4DC8C53A4D0902FC0E9 +67F6DECAE69AF376B49B123527B8BD71BF3EE792A440902F494EF02AE6D62F49F023EBEE6B18C276C53409637FCD490536B9ED9A2EA32EDA9F33EC976729746D82C7CCC9DB4B52FE87E5CE00DB276FF33A377621A37DBA97F955BD15 +63D0DDB3 +C1956D14FC78E8C9BFE8E93797 +1E94C01C00CD75EBAF34C4733DF8C7DC7828F624CA4DC102E8014FE9DF7E5C8563DE27C695A71C31507A29561F9A1ACAE063BEFE18B806F88AAF29FDDB447A08FD3B6DAC5FB00402A17808E9AA7F3548D9BFBA +03C6BFF1 +E6740F613683B8DCA8F2D4A26A62 +D71FAF1F74FB29294C2D5ECC8EF7A89695287B626D6D6300C0E3F7D9C39187B84B04772A21BF493A63D2B611949DAE6DF8A07A846F5445EE46BD91E77760E1197E61C57060DFDFF0AF011948FC6F5E45A902A8D4F1DB8214BE836BF8832B536B66BDAFE7139D49D4BE70 +A932ABF2 +98BC149705173B1C401E96881C95 +C05D865475A327717B9D098B7489C9DA0E215AFAA3DBC93B24DE941042D0095271568AF9F92E4C0AAAFF16FACC0D27C8D7FBC6106D3A47A2C851896E611CC3C25BFF7ECF87CFC747C3CE7515010DD546CDC89E230EAAD5A1AEC6F725A2EB5847BE7AFDE6158A28C8C3BFF32BB5D3FF4DDD5DC92337FABB089F07591A8FD9 +0BD09A5E +47D050BB87B3A402543DE8B0B205 +3E697EC9D0F579ADEE8FA501D42B072EB1BC1AE8CAB8029886548B7E76778FC006EAAFB2BAA87F9CCA5E77046E2BDB1E07FB77C4B81F87F15FBAD1E0806F4687FFDF55CD35C9E3EC8E6BEC0B4B5E433EEE6772F475EF43A12C750066BB6808CE397E85E429820488A1D2B5243272EDC612F3740D99514F3137E4265FAD7D +1657 +B23415 +0FA5CCCF +8186B35862A55070A8A5F6565B +966BF6501389811EB9AA480738D33F22E512BB6679C4EE2CEC5151E1257C784B8AB00AB8740A3B592368FD2A2AEA2040EA0485911087EBA3BD658E2739802F6D68BC84405291DD9E3666CC547DBCF989CF +A9B6C04A +6687D53465F149789B9CC982B6A3 +84D354402A55BF947C0BD62DCEDAC75A09B76F8A00D8CD992CFDBCE7577BB6C6861A90FE16D880C0BA929B5C2A9B7079B16F09DCEFF22596BDC32AA2278242F06F69EDB8EEC045BAFE92E6D6E683E14D836D3D49B49A2BE53B16FE56DBBC39A3103CCF4D +9903AE3E +1AD773D8F242D05AD34FA65150 +7C6739FA556259D8C86796763A8DC2C2A4415446C77658A6850C3DA7D20A74BCAA01BA3298AE094461C0 +016DC2D0 +7A0FED1F850E523CE25CB6D949 +F4FD9B131393DD0C78B1B73301F887CB49CFC1D5138E0B60D1231E03F9D818ACCFE2F034FA301F11691EBA81 +A3D0172A +87B0A6DF995708AFC41F9E8C66 +735C59EAB8324160A9909A265A5368017D408E1A4440 +8F353740 +E58F04881B7E47AA4704638DF7E3 +599F62B09BB75169BDE3ECD1C5DC21738376A2A76308B9E3EADC2F73D110265F8838B1C6FCC1FEA151971C72217F3B69EF01A43DB1225CF39A7AAAF54A11C7F649B03D3248423C234EB1AF9E0F1C8E6EF548C4ABC71B6AE21F7B7041CF3C6C38BBC832E748492169FC99CA94FC8001C9B422D4D5CF032ED680E920EEDAEF +40D9 +4377A6 +31C4DB27 +F5F59B1B07DE2BE93AADBE66A5 +3BE748C467DA6420B7232709DA26FF96F3BF6914F58FCA8B2B3DE8416508125F1195CEB3207B4D291329D234E73A23A02EC693CD2EF5BAEBA1CA9BDB41B28A684E7DFEA6B0E2A254397D80472E3A38F1430F5579A97E384A +E66EBC81 +F2E75F5C32752341799C9CAA75 +8C3C211FCA6F9D763A537B0DCEF74494EC0F04F1981DD57A829BA7DA6B3199F4770469F6AD5E6D3421734B093E2A9B98015C9723A43092FA5E259C3F3CBFA15925467962538798DF316D75557F8A79AC971E +D7805385 +B271931A447B8A6B0F89BD26D38B +CBF23B4C7AB895C924048A648695E6F770F6B94DBD35C882969EBC345B80A8623C116028AB976F714146042A4148165ACC7BF18685B69A903E453B52D4E0C858F0196FFB198EF916EC07C5143AB59D4C3DCB034B1A72021EF3082A4D2D45C1E959B4EB23F088853E6AFEEFC23AFC +8D4D3D1B +A8950F1E6DA8B05799A9938EF2 +36F4147C9EEE691463FDBC69E1E2C4FB606FC048AFFB9D8C9A77331842BD805122BEAA352596AE81677D1D83C8DDFCC9F2CF563C1CC2818CB700203E97D0251037B750A8A28C98A644FD0AB70EFADB2633F33E41C046D370A3 +7EE2008E +9543EE4E4CBA55F951826B7786 +F35D21E39C76EBE51567680002B2366DA4C5FE5E53CEED09D86188572CC44E2E3BF88CADE21B1E8698BC1612E9E7246074AB1993E86D53C39A1C9E01E48BCE010A5ABE5C09885A8B2FD52E217839016636755374469821CC776D8C89 +25969416 +CF6290015A29599E9C793A259DAD +2B970B9D3697C2D6D8E47A9C49F1DE6AD759EC65191C21106357E8AE2E72CDD82A160BBA28780E48330740A0726B97578617817118FEBB2DCE5191B7549365D8C9D6F48536D741E4504C32742EE76721857B875F8D5485B6303B986EF1106ABCCAC601A23FEA740D7AE9645423C1E65F1DB4682A07133AE4F454859D5FF9 +458D +5BDEB2B01913B7A19390C63AD5F11BE7395C52F8B0ABE40449FF23D1B36A41F940CD2AD0AB7C5FFCA1850192079F47 +D314A789 +6EA87D3C70403C6EC618DF7F0434 +C9599D05F6F20B3FBC6D8B79955A201FD8A6B70D702D1A5C87BF335A1D98ECD9158FBA7B3522946D3F1792EE7AD780D3704D2ACC3B19A02E02FD9430CDF6EC1EF353158665E2E2D44E7F3FF89AF00F681A7525FC1DF823F60D107EC2060DD80D0DDCCB544C3C112E50E4B2B237 +BF8FDE83 +41ABA79D9CDD8313FFFC82D1B9 +423D48BA655790FD2875427B1E8B77F1F7A6E1CBF778AF9A244CEB1EF11D7E002CDD62C088CE16882B0A4748E8699D319ADEFB8CDBBD153CED4AE91A94FA9157BC0B4CA6D3B5A26570DB539103262952 +D5F421D3 +92CDAD1AF51A3020446F74529CD7 +8CADC41D0AAB87D3868671AC502647755F56C29888C0D03E78FD41D69BF8DD9AA5C75FF911226A5718CC14F9825A6DCB0514C23EE1D15E6FE6313E3951DB2452EF00B6D9C3B54CAC016D9039447C0F8E39BD25A1BA1C00A30621512382C286CF7A1097338F3759E8690B79622A1FDFFB77C14069452064D1D959BCB50628 +5656 +22D7871F4D1D2FDC8CBD0EE1E427546D7C7CBEECE0F2A80145BFFE8308C115AC32F7D3 +D3496E09 +E26DC9818C824D6DB1B8DC46F0 +BD3A5958A31509330EC2F5FC7FEB26DC4F3ED3F0573C2D45746EC64D530F9F0AA0871AE720EFCA9522D5283F67E52F63BDC164CEADBF +2FF89345 +5BC876EDD5348E984D0ECB88228B +DB94B48095C064C5267DB98736C292D1EED5CE889C5CAAD85DEAC1D0083A3DADA73DA2899DBD16925C401E3ADD7BCE40A778AD7FDB6DE82B77F6855D3DC3945F0796DA9E1D2519C8B6539F4EF42D5366687A8F20C9A749E59A6F1875FBF06B5756F946F1F1830691811DF8176828645DA8ACB0309E8C7AD34470B2D8D318 +94F4 +05238D72E5041C48FC89EE2F41658E11F4A0CEC192992257FA02EB93531A5B +38640A50 +29A2FE6B94C8E14A8BE5A7AA9D45 +889CD4D61D670591504C23BA944BFD70D45024E76E905011BB6C5A88980D2BE786CD2EBF52F0663180F616B839E23B2B2C2E978792E298C33493F837AC42808D6265E965F6204BFC44E82EB39857E5B87C70096EF49BB8175287CD84ED6884446B8C06ACFFC9BD199E4E74F0 +C704D343 +61C618DB298612274E6005BEEF +F3FA45A31004E015458E7FD1BA12CBC53C70186EB5760CD04550F5627D4078B775D13B5815EE064D9C40E407CA3474698BC4AA6CC667D65CB33411EFE73A7C82EDB3CEE72F7F +8B55BE19 +72D81CCF66F5FB390B0E5D2261A9 +87048B8D32A5A2072234917F3DCFB10FFDDC9268086E3C93ADDE3AE4BDF5DF0206C5785EC481993C1FE5D5EC04B9A2358E94579A99AA67FB4BDCBFA0200EE09E3D5D72530D8CA8ECC78C91AF3ECF2967A77B02AA277190A75C7B3E1B99AD9FC98AB744000B18D193812E78794C6CE09356FC84ADC51027 +3771E506 +0310CF6649032C3ACACD0019B1 +0BF800040C1288908B6A53B236B0BCAFB60696A3CE07CBBA0F0F50E9A5E827188564053EB122CE4FAFD25145430A549C7053DABA43BD9D66FE842A88ED1915BE1D717046F4600DC4DCB2396FE8CE13679668282908907A +7EED5B5D +14CDF57FA3405DEF1B517ABF3F1E +973E8B4F99D868710D6B5C4A6532CD9BA37824D2C618F15764707FC2B6E7BD2858F8A60DA38702E4551BA2AEADF55B87611FCBB18BCC94CE6371A97DEA56658214D337993DCE61647E356FECBA2BEB2894C44D4A8537DEF40D055BA35F3C71C504974EF6C7E3186F85D1653F5AFE31EC854FA6EEEC879585D4BE8C71 +8F396EC5 +388A3F5FDFD91E356A0E66A45D +BC1BEE2AC7161E7642BE86635875DBE5AD4172F4786A4F282EA1E51623F5E96BE0899F1714F2936A7F9510A968529A1AA18E34BFD52012A49A2C6FC4A0A28E4B735BC9BC2D +E8B07CCB +057EBE9A7757398AD1D1515964 +B4D13ACD5BAF2E06AAC623B06A721A039BF717F290A4E3F37000EC7D947947914A494D50480D634FABAF3AC72559A56894F1277B3FC0A186F16E4EEB338CF3914661041263EB4EDC60FF18ADB2B5C9CA5481B80A32AAFE5187158245E638BA46ADC4 +AB1EC1D8 +EACF7DD8F49D75BACDC005CE38 +BD1FA73504A7AAC94C7E1DFC3A25EFDBB98FE0509CC4EBE15FE60D28FC0FA5C8B0DFE31917DBC754E9C73E57A3F9125D27646E1517B2CCF158AC0DA16F83A6963DBD56C55E73E91DC34D07AE15D237DE8D6D339CE5CFD3CF02 +53907499 +D40A49EB8C8EC4957FC65BD25D51 +283D153DFEB6F30D77707624319596B807DF66B0CFF00783C33E92F59000EED9BC6C209928BCCDDFF5B290F4EC1F3A405983E6A9BE766CEB9DF1A429FD1EE98542ECBFA7720E910FA90EDA6FAEE00B53B24ED4ED5ED16CD4C3879CAD8F909D4C5E41110F9C97395FC312A8866EB5A439A99AB860A7CEEC680068F2E352FA +E748 +9333E06E5EEC3DDD6331887184CE +D9228814 +547D12A1EF0440023348800DD13C +04021FC95AF192B70DE52CB7487EAA6B53538894E836780D47DFD0286E1384972CADD6EC07E61904446C9757A6C95DA676D4F970D88FADD8168BC525A4CC29C06C1B36654D4C9476D7EECF185F302159F5B44E6753B83B9FE3906ED278286BC3599E97DF00FEE4AB27C7835E9C64DBFA9483B90ECF13AF3F1299816DDA36 +3D7B +189ED8FF +A913C7D0BBCC7EBC7172934E2A +0C643BCF0F2335EC7D9DED6C2BBC8861AD513D45628FEADF89D8C4D6051B1CE9B050C00C85A0439472B7D51C4D76B9788AFACD196FBB3A96FC346D376F15A7 +789E161F +BE6C384DF2DF38FCF8D5E8FC13 +3B2DD912A8D46C7E063ADE810E7700B3E1CCAC41188E +A1429C5E +9641FD389499D089DE39A527EE40 +BE9CDE2560C07632 +79018100 +47E5868AEF14B265D6BD41D8A198B9BC52ABB458E5961CCC4F498423226EDFC7DB93 +03AEF1A9257D006C04857721960CEA54EDF271F128AF2C52C06A1606E9B4D68B8E700035D917 +8803A499EF55D4D876B20BA0A9A9394DB687D24D3AF7E42841C8DC +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +%Defining font PSOwstdutchb +%!FontType1-1.0: PSOwstdutchb +10 dict begin +/FontName /PSOwstdutchb def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001000 0 0 0.001000 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 1 /C0032 put +dup 2 /C0045 put +dup 3 /C0047 put +dup 4 /C0072 put +dup 5 /C0101 put +dup 6 /C0102 put +dup 7 /C0110 put +dup 8 /C0111 put +dup 9 /C0112 put +dup 10 /C0114 put +dup 11 /C0116 put +readonly def +/FontBBox [-18 -207 755 694] readonly def +currentdict end +currentfile eexec +D9D66F633B846A989B9974B0179FC6CC445BC7C8A959A39A32E9DCE7FAEF17EE3BEC9F +50E1A6FCA651FC4B3769A0A91041557502E25A5D6180FE25A3D11BF079E1DF66E54EE9B7C229AF891739707A2A0EC140306B5E43E52B79BFB89E459E50 +6EC6F610A70775A31C460976C4F79449D86E57ACE491E5C6BF20CC4307B1DAF7630252 +E9AF8CFB69B50EDAE9D36A6104AFEF8832F920FD2346B2C7104CD11E3BEE999CFA9F5A +49DB3173EE48D1C82994237F360407B022E0B4 +502E94EA8B493651EF2D03F0B513D655047568325B512AE6 +6AC6F53F3848CF70DE25481CC65D8B1A5793AA +3C4282D111112BEE28AFCA7A3808D4444C4669CA +84EAAAF989219F51AB3476A1B0B5F2246BC306E6 +625C6679C417ED2A8E9BD010DE37D40265074C268425D2FF1A9D4C7BCF55FDC1F91B21773209FC +8852C3885A612BA738EA66E3 +05A8046EA4F9161C30 +234E9362 +1F9FC67A2D9A6EE1A74DF4431D +B3E8171FAC9BC11200E5AA53FE5CA210E8A7BF4545E8CE +A4B05EBE +0C8D97F646D72B10074625B586 +3BB09F2D5CC2175056BEA0A3CC52B8663B9CA1FD75C9EDC98D11 +168EEBD6 +5948852F001FB6D0575A506723A8 +F726BE1B5A9848A7543BF59367A1358E5FE8CB9DEBE43B7DE9D71575DD868ABB7A6BD17E119B5899FE102703AF10B1679DAA95D9CEF8BF827C936B6A8E1E9E2E7E7C64094AC562E5C1D6133680A384E32ABB8F6EA5F6CC76DBF1111B3F36A024CA1B6A6ED02EC50C4822AC52940F61474A0D64452B6395 +3A82C6C4 +5D59EBD6F30FA999718AFF1C80 +468551E88623360ECC2D2A7625BE31014FE4751EE134A0D199BBE788273943C1A1A1DB20474160ADEF0D02A14347EC3869322D2D964DE9232BB700B42803C2B7CC30089A2A8026521B6E67D2F9827FC25A367404E216B958BF959070 +2511ABF8 +5D8E0E5637116F529957FEA489 +603A9D2379814827638E307682290BBF549024534313DD3E1FEE98FE592BF9942C450FEF8295DFD3A87FD8DB242152DDC5E4F66CF7946C7B2CE27C018FC6EB7E2508007928567FAF9A9AB9DDCA177CF4A73685580139F5E5BEFE9302AA +00C98A56 +B1E17450F2D88477820F67A99702 +382701CDCCCF0E1BC5CBD19C1748B524DD494141D1798B0D07D743AD19F8DE5CC52C6B0476EDECC3BCF642BF5B0B679884247F7801AFA2F325BB0DC455CA743B771BCA83A7EEC8DC504324D990C08C28EBD2A3C68217FE1FD2BEEDA772D33D928B8C0437C685D8 +8A0E0943 +1928F44FC7C20F1B5285DF8F0B +1D342FA4B8D1D566AF978B127B1D2482D00926DA5757D393FFEC1627ABA8EB6B2D1C642B3F38A763C4B22343F13922C34A435C3D23123E337289E314A0CE78857BA08AA6AAA6 +A1BACA35 +44105C34FD97FF3F49FCA8E50F91 +A710D45B1E95B6E1E93EE3C23E639485467F0E48569C1490670F710E7A0A87470DC7D9D6D27F635DFB943E034ABF3F4111145F55B9AA565AD2F252DD600B603E68C4EFAD3CEFF58A82035B283A0CB9444175366FC63C44C984FC75214A35D318DDC270B93F34A9ED406D8C13F13F6471F6 +0889F70D +21EFC85E529EA4AEDA7FCDC5BF +FCC5CE9CD53E0D9B2329ECC82AB796865423778E2337A40857B9C38063D95E0A3CE1B8560668D89F6B3EE8B27F3AD46207923E6CE28D0A6CFAE8CCD03C9782A08447265D3EED11497E24A677ADF508FDCE30336408DCD13012 +C8EDE006 +F289FF887E8581D338343E2368 +69175728BD7ED8DAC0585031F1B5301A38EE3606AE39E17ACCB312F2F18D90D6B5846A1ED648D113FFB18658A3E62BD43CF3F08F354A5B6645B64F095184DE70FF976979 +F2BB3537 +99B30B0B7EFE15040AED558439D9 +7094864ED2E137D7 +7BB63603 +1E358B07DD6CB3C7DCBEAEA782755FECA0BF7075B50A2244DC8F2977F1A7F4C4E0A4 +89C3155C483EDC45BD7446F004CF9F7285EEAB1842C485C210B2C44603A5EE7BA6D6F45F4066 +0CC152D9DE264E35D8F5025AE3EEAF238D28174DAC2FF31554CD64 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +%Defining font PSOwstdutchi +%!FontType1-1.0: PSOwstdutchi +10 dict begin +/FontName /PSOwstdutchi def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001000 0 0 0.001000 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 1 /C0065 put +dup 2 /C0076 put +dup 3 /C0097 put +dup 4 /C0099 put +dup 5 /C0100 put +dup 6 /C0101 put +dup 7 /C0104 put +dup 8 /C0105 put +dup 9 /C0108 put +dup 10 /C0109 put +dup 11 /C0111 put +dup 12 /C0112 put +dup 13 /C0114 put +dup 14 /C0115 put +dup 15 /C0116 put +dup 16 /C0117 put +dup 17 /C0118 put +dup 18 /C0122 put +readonly def +/FontBBox [-144 -227 757 728] readonly def +currentdict end +currentfile eexec +D9D66F633B846A989B9974B0179FC6CC445BC7C8A959A39A32E9DCE7FAEF17EE3BEC9F +50E1A6FCA651FC4B3769A0A91041557502E25A5D6180FE25A3D11BF079E1DF66E54EE9B7C229AF891739707A2A0EC140306B5E43E52B79BFB89E459E50 +6EC6F610A70775A31C460976C4F79449D86E57ACE491E5C6BF20CC4307B1DAF7630252 +E9AF8CFB69B50EDAE9D36A6104AFEF8832F920FD2346B2C7104CD11E3BEE999CFA9F5A +49DB3173EE48D1C82994237F360407B022E0B4 +502E94EA8B493651EF2D03F0B513D655047568325B512AE6 +6AC6F53F3848CF70DE25481CC65D8B1A5793AA +3C4282D111112BEE28AFCA7A3808D4444C4669CA +84EAAAF989219F51AB3476A1B0B5F2246BC306E6 +625C6679C417ED2A8E9BD010DE37D40265074C268425D9A4327DA39CB2DFD7488DC30A83BD6536 +5400151DA9825FFF379210637B99 +935074B545C1A5C13FFAEACC1348307F174F895D76BCBF7965B7DCB5B082F069DE386D78D069FB93DD5CD4BFA0DAADFC8682C02512A70DBDB31A49677C7A8FCC67E34E13C533B4253F276D65921EB10FF73890B81F03F8BDE79EB4D111EC23E565F37FD577368BDB8E58D365E9139B8E12A1 +A7A4A58A +F384A30B3E3767B2431A9D769C +699B9CDEA8198DAC008AC8228194C901A9BF02DD5DCC259E6353D113A9ADB64E95C8920E2FB3E0C5145EBF50C696BA2E53146DE6786A4701C3C3153B22F96EA72B58111C7D3132997ABB39486926AB0CAA568501136BEAE7D2F0441BA10980 +9A071058 +0B68B0AA1627A124CCF7270D22EF +A230C26150698367032BC621F388E26D6407D18779A50BB1CC4CB9881CA10F85E186A71558B2C9AD692949FAF427CE3E035080592876220210940030FAC364ADE6B6E9F194633E7B89AFF9FE809C588E73CED5449BC52AC4A481EFCC906489BC53475AA53A1853ACA2505FD7068E7EA50EF30A2D5833A65BD03BFF153810 +8EC1 +ED69EF8547CD07B3EB7CFA6AB8 +BE09152D +51F6892698ABDC3334091B05A3 +BAA49FCA67C1FA7DF8342862F613C53C4DA30E50AAA9309953FA4661E10FB8A7E875185732BFE1CAD4E365437F3713DD8E758CE8742A9F5276ED3737FD164341054A787D3CC02983BBE577C3DBF9CE397DA4B83F414862225667A325C4167DF4 +05C98E6B +7173DB23F48C32FBFC4820BB0849 +0E8968CD77D45CBEB87BBA39A691A4F0DF172B1AF3451394F445D0C3F097C804FA59FA043627CF77E371621BBE34C843B3121F0EB4E9D57F91EA8B73235639615ACF10E80E995495A500BF377ECE8BCAD46727DCBEB42AAD8843AE7F1064CE8BA03AE5D78F22487ACC261250D2C9AD3852628843DF3888A20370E9D379C9 +0213 +716B253D1993EAB30DBF387300EA197B2A7C31946A0D08516617DBF1B8FE5935AEC8717F5CE24F441276B25748BD37C0 +ADFD96E7 +C71126B2517D1A882E286679AE5F +800C4D68726E47342C573E4B699D8A82400660F64141364C55019273AA419880B5B2B971B4CC2563F957D7B684EE3ADE692F1AD119279CF7FAE23535FA212093F9EE286EAC8103F0786ABF1EF04C89B92DFF6262F47B7BE8427073FE3D604EEAAC626FFC35 +FC54E67F +8AAD6D1CA08E26A9AE3E2B65D787 +32C40F1F33B70B4008DC7A9D82F67974F0EC755D759325DA9BA8147E61DB6EAD4616C0176591337F39CB3D7B57C9D8FEE578A19D7FA99B2C0286CF901E044E785690FC928E3FAD28F70A639406F37377AA12D47C82A1CAA16DF640695BEB6517013C9B71C9FD4D07D116825B371D139A726B4573CBD87DB562C340F75D21 +FC26 +30FF873A778EBA1A701FBA1816DDE2A8AFC0E2AB0DFD14E4751A2E +E5B2CD31 +2E559238780E7CF35E5F33821162 +3CB5D6A537C056F50E06815E454C7AAC5F7BCFF028221857AEF47FA3E32F0253A44294F97E969C1C389AB0B0F9346F00F6994ED18888DD7B1A178D6038F2985939D28FCA87B92F3B3284494E46323221DD03EC50EB26595D47B9C12E6D620E36016654CDF20B2D6F6040196CA47F6B80EC5D07A03F9D0B59E8 +FA11C883 +3E5807138069DF0F759888C7611B +6007BCEE4B2C3C269A2FB2185BFE14C9B7E7E417B7F4B7F40C483E72119D68314B5333E3F5AA0AB72C8035EF1E64AF3A6F6C323F300FC33E519784253137CF949CF855CD9D8D18EAA2C6952A0B928E57AA01F1AA0ACFE8B9DEAE5C7F353E5F830BEBEEF8C5 +CDCC1E7C +424CF43A041F0FDD02DBFC8B9FC5 +64104A1295E2BC1EDF8576D0554B525ECCE57D1DB67AF07EBA89600BA5AB71A96B0A5A7E4F7799C070D2692C70347456ACB60A2889DCE7137A5CCDFF49DD716C87DFCF944E23D5ED87BAC6ED6B152FE726786182FF61A1A19D1FFC5B9154DADFE13CB6B599596AC96C724D170103B7AE9471CB868270CF55BB8ECF3C4C99 +FFD3 +4DE9C88E5F3B06DD7861371B0FB7C55F35D051F25918B04513998FB767A9E9FA0E28FEAF037832CF19FD99475F6C5394EF3405279A037F60DB6881209904AAA12C8C6DB35199B898DEABB4 +C4918D64 +A29845AF6BA2BF7F1C25AEF923 +E6760935651ADB3E8732997455AB32B84D7717C2D14A1E3955238BA4E07C71B7856EBFAE2726EE7ABEE2AFA28D9CC5E9A2D5211AEF3D0FC24E23CBA7C64966C6E1D77A4739F43746D9814B7E64F142FEFA5D75ECAC348C8D4650F845EC732A +74C6FAFA +4CE8FAECB66CAD236483227C6499 +DC4E6DE18A8E9A6F2F0D83D5AC82EED27C69C35A90EC5D54E5FBEB240F98DAC8F2644FB13F8313858196D6BB306DFDEB07598F8435C70FC69561828D74BC3A1A8667146CBB2C9F26AD9FDEAB2BB2BDDAB80B69052F7E0531C359F359E4F7C4DBBB8D668DECB0053F9E0B7A7F5C35138EC6D5AD5671289A9647BFC4963D2A +E9BE +F23B56FF202E085371B94DAC6DF5B22E3CC27BAAEBDBD4B79118AFCC83029D7C0182C843AA87F4FD5FE0 +19C528DC +569A100938186474BC3C34AC97 +C66C21F4BDA0D79251AA09D6F83340B7C26E9852D6A7A497A8975B456DA2814CB5E9EE0506CAF09D84136C4E07C958115B5555F4EC89AB02BDA4127E38449B610794D9E5A2955FB39B9CCAB336F0FEEEBACF6488B100CAF76966DE +58ED9DAA +224DE5784839BB3268C3F6A0304C +C43B7F5617912543AFE9CA0A7C234F58CFB31CE145628D0B21C4A97CC29CC8797AC8A3548163FF25B46E3FB749FC7083E6F74C9E1ABF7AAA13011E4C7B90D056725BCD7C280E26DCEEFDE5ADFE8B88BC379EACEB8E92A4A68EF1DAD55C9CF30DDEA2A6BFED92B943754D140A276E53A14330A76F0A2B +660A3145 +7C8AFBCF05A1CDB98DFC2B984B +99A6CA7E82E57948A7D03D45EE6853EE2D36536B298F035F9B271B76DC1E3731010B632E53D875C3A61EEEE65AD71560E97F929607D71DC5E0E092EFA963B0C1D5D0E685B661299F8B6A638F0F4C6B3095E8DE4C365BF0 +A0185B85 +D156428D2B1EAD61BF3598F9B314 +A48BBAFF188D0979EA77D1967D26C5347A82E402179E1E0DDC13172E6385FFEA98B2F469F48F6344A439F8714F45532458B250A8335D5CAEA07453E4562544DA7C35233BA04F2574C1FE5A1E12D324D07BF5AE0E3C315223086D88470F06B820165D066C80F44B308FDE4AD561E3BF22553F896E4B66A903A0BBFFCB59F2 +00F9 +26F28AC400E6431894A20A735327647A013E9A5DE55C3A +4981F41E +C9FA75E284A93D0A8CFF45E41F +467519534D48916FFB23EF22E7D6CAD659D318A3E764C2C5E8A26EC233228CD21E0C017EDFABC58BEE2A395ABB3E31155951F568252546C38062F59A883BC9225A55738641F701178F78A7499317C8817F26112375AD2B5C2F8D +5FE55C60 +C8BF5CBE396A8B10402F42E04AD6 +51074A7FFF252E893B4166D55A1AEED098F3D05BDF8634A48A8C43CAD5A657A3E6A98DCFDCD1A3DB1BC38D973C9B370FC5F5656011879481E81EDEB89A7E300D0C5FC9526773038F7B0FA18BF500BFE91CC0FB31265DFA576E1881810B1E744A75A796A9DC49545A6447FB34EB4EDEBB0C4DB17C966DC923EFAAC6D058A1 +4A12 +11EA9F5AB5A9A4BEE9 +B557E1A8 +66C8C225B79AAECE9CCB465AED57 +BC4ADF0601649337 +80CED7CA +E762332340715F69F2B221646C5117BDA091E531BACB65BDA2C4D79B691C907FE5FC +D81EF9A286D5BA4B9F4B532E412DA3D95DC8B82914596A8B7FC1D584B0BF7462F2A45F8DACA2 +23CA33D7958CC29198C216AAB0A1F8779C7320199C867EFD8E1802 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +%Defining font PSOsymclas +%!FontType1-1.0: PSOsymclas +10 dict begin +/FontName /PSOsymclas def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001000 0 0 0.001000 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 1 /C0069 put +readonly def +/FontBBox [106 45 775 713] readonly def +currentdict end +currentfile eexec +D9D66F633B846A989B9974B0179FC6CC445BC7C8A959A39A32E9DCE7FAEF17EE3BEC9F +50E1A6FCA651FC4B3769A0A91041557502E25A5D6180FE25A3D11BF079E1DF66E54EE9B7C229AF891739707A2A0EC140306B5E43E52B79BFB89E459E50 +6EC6F610A70775A31C460976C4F79449D86E57ACE491E5C6BF20CC4307B1DAF7630252 +E9AF8CFB69B50EDAE9D36A6104AFEF8832F920FD2346B2C7104CD11E3BEE999CFA9F5A +49DB3173EE48D1C82994237F360407B022E0B4 +502E94EA8B493651EF2D03F0B513D655047568325B512AE6 +6AC6F53F3848CF70DE25481CC65D8B1A5793AA +3C4282D111112BEE28AFCA7A3808D4444C4669CA +84EAAAF989219F51AB3476A1B0B5F2246BC306E6 +625C6679C417ED2A8E9BD010DE37D40265074C2684268F16195489648993B9C4D3B534FA887C +DEF605FA87B991F4D20A8F78DACE +5A54C070E03D5C59D9D2D3E06B09CEE028D68B62AB3AEC43C1DD20BA70D288597D9BD8E06818FF764EBAB436723988E8D7CA59E16D39032516BFC5D552ACDEEC6BE938BEF2F43CFFBC811C3626C4DF5F8CF080676520B51C60CEDAD1FE6C92D1431C702174CE517A8FA9377D075A0B6833DAB101DB65397F1419EF5F0016 +004F +6F0824F9657BB4F1C8F981709956865F6855EFAE +9242AD55 +91BBBEE163D844DDA894E13190C9 +2480439E4C71CADA +BD043A9B +A315CAF72652AA7FE6DB2E84D82A6111CE4DE90C02DA0AFFE2620922262A45AB4ED0 +EEC9F4520DD12703442F7D028D4526BD8B771E09FBE11B2749E2D3906894E8D4BFD3F379F14C +3C874F550606965E22FE487B247B5C2D06728490C8F2A3B588CDFC +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +/DPIx 1270 def /DPIy 1270 def +72 DPIx div 72 DPIy div neg scale +0 -13970 translate +1.00 1.00 scale +/wst:dutch12 12.00 /PSOwstdutch newFont def +/wst:dutch12b 12.00 /PSOwstdutchb newFont def +/wst:dutch12i 12.00 /PSOwstdutchi newFont def +/wst:dutch10 10.00 /PSOwstdutch newFont def +/wst:dutch14 14.00 /PSOwstdutch newFont def +%%IncludeResource: font Helvetica +/wst:helvps10 10.00 /Helvetica /wst:helvps ILEncoding 0 declareNFont def +/sym:clas10 10.00 /PSOsymclas newFont def +%%EndPageSetup +GS +0 13978 10801 13978 10801 0 0 0 clp +wst:dutch14 SF +0.00 0.00 0.00 1.00 setcmykcolor +<1725322f2530260c010e010f252d23282c21302a01262e3001162521313330292d2701172532352e302a0119> 2207 558 0 7384 -1 s +<2530262e302c212d2325> 7375 558 0 8593 -1 s +wst:dutch10 SF +<080a> 9346 13300 0 9522 -1 s +wst:helvps10 SF +<4e6574706572663a> 1322 13280 0 1949 -1 s +<205265766973696f6e20322e313b20436f7079726967687420> 1949 13280 4 3868 32 s +sym:clas10 SF +<01> 3868 13280 0 4019 -1 s +wst:helvps10 SF +<2031393933b131393935204865776c657474b15061636b61726420436f6d70616e79> 4019 13280 3 7133 32 s +wst:dutch12 SF +<1c2825> 1271 1431 0 1631 -1 s +<0031292c2f2b2531320012> 1631 1431 2 2610 0 s +<2e3025000e> 2602 1431 1 3120 0 s +<1c16000e1914001b323025212c003225313200232e2c2c212d24002b292d2500352e332b24002b2e2e2a00312e2c253228292d27002b292a2500322829310c> 3100 1431 10 9147 0 s +<02> 1398 1778 0 1504 -1 s +wst:dutch12b SF +<000308090b0307050b09050a060307050b09050a0600020b00> 1504 1778 3 3692 0 s +wst:dutch12 SF +<12181a11201b1c1a110e1600> 3692 1778 1 5395 0 s +wst:dutch12b SF +<0204> 5395 1778 0 5737 -1 s +wst:dutch12 SF +<00> 5737 1778 1 5790 0 s +wst:dutch12i SF +<0d060a0b0f06070b0e0f> 5790 1778 0 6749 -1 s +wst:dutch12 SF +<13253025> 1271 2124 0 1736 -1 s +<0021302500312e2c25002e2600322825003225313200312f25232926292300232e2c2c212d24002b292d25002e2f32292e2d3100212f2f2b292321222b2500322e00210012181a11201b1c1a110e16> 1736 2124 13 9531 0 s +<3225313205> 1271 2369 0 1648 -1 s +<0421> 1589 2716 0 1871 -1 s +wst:dutch12i SF +<010102> 2033 2716 0 2467 -1 s +wst:dutch12 SF +<333125> 3177 2716 0 3479 -1 s +<00322825000e> 3479 2716 2 4014 0 s +<1c16000e> 3994 2716 1 4538 0 s +<24212f322132292e2d0015> 4534 2716 1 5581 0 s +<21362530002d332c2225300021212b> 5585 2716 2 7026 0 s +<00322e00252d23212f31332b213225002f21232a> 7026 2716 3 8825 0 s +<38> 8825 2716 0 8895 -1 s +<25323105> 3177 2961 0 3485 -1 s +<001b2f2523292636292d270009002e30000a0035292b2b003629252b24000e> 3485 2961 7 6163 0 s +<0e1509060a0300212d24000b0035292b2b003629252b24000e> 6159 2961 5 8441 0 s +<0e150b05> 8437 2961 0 8895 -1 s +<1e10252621332b320c> 3177 3206 0 3998 -1 s +<000b00040d000e> 3998 3206 3 4780 0 s +<0e150b1f> 4776 3206 0 5250 -1 s +<0422> 1589 3552 0 1879 -1 s +wst:dutch12i SF +<0e0812060e0c0604> 2033 3552 0 2712 -1 s +wst:dutch12 SF +<312532> 3177 3552 0 3432 -1 s +<00322825002c25212d0022333031320032213027253200212d24062e30002c292d292c332c00292d00332d293231002e26002a292b2e222932002f21232a> 3432 3552 11 8825 0 s +<38> 8825 3552 0 8895 -1 s +<25323105> 3177 3797 0 3485 -1 s +<001c28250026293031320034212b3325002931> 3485 3797 4 4971 0 s +<0032213027253200212d2400322825003125232e2d24002931002c292d292c332c05001e10252621332b320c> 4971 3797 7 8895 0 s +<0703071f> 3177 4042 0 3511 -1 s +<0424> 1589 4388 0 1882 -1 s +wst:dutch12i SF +<0506110e0c0604> 2033 4388 0 2700 -1 s +wst:dutch12 SF +<312532> 3177 4388 0 3432 -1 s +<00322825002d212c25002e2600322825000e> 3432 4388 5 5056 0 s +<1c16002425342923250026292b2500322e002225> 5036 4388 4 6799 0 s +<002e2f252d252405001e10252621332b320c000624253406> 6799 4388 3 8895 0 s +<21322c1f> 3177 4633 0 3594 -1 s +<042c> 1589 4980 0 1940 -1 s +wst:dutch12i SF +<1103091006> 2033 4980 0 2495 -1 s +wst:dutch12 SF +<312532> 3177 4980 0 3432 -1 s +<00322825002b2e23212b0031252d24003129372500322e00> 3432 4980 6 5337 0 s +wst:dutch12i SF +<1103091006> 5337 4980 0 5799 -1 s +wst:dutch12 SF +<00223632253105001c282931002c333132002d2e32002225002b2130272530003228212d> 5799 4980 7 8895 0 s +<322825> 3177 5225 0 3467 -1 s +<000e> 3467 5225 1 3683 0 s +<1c1600161c1d05001e10252621332b320c000e> 3663 5225 3 5713 0 s +<1c1600161c1d1f> 5693 5225 1 6669 0 s +<0416> 1589 5571 0 1967 -1 s +wst:dutch12i SF +<1103091006> 2033 5571 0 2495 -1 s +wst:dutch12 SF +<3528292328> 3177 5571 0 3703 -1 s +<0022252821342531002b292a2500042c030031253232292d27003228250030252325293425003129372500262e3000322825> 3703 5571 9 8180 0 s +<0030252c2e3225> 8180 5571 1 8895 0 s +<31363132252c05> 3177 5816 0 3835 -1 s +<001e10252621332b320c000e> 3835 5816 2 4925 0 s +<1c1600161c1d1f> 4905 5816 1 5881 0 s +<042f> 1589 6163 0 1882 -1 s +wst:dutch12i SF +<0e0812060e0c0604> 2033 6163 0 2712 -1 s +wst:dutch12 SF +<312532> 3177 6163 0 3432 -1 s +<00322825002f25212a0022212d2435292432280032213027253200212d24062e30002c292d292c332c00292d00332d293231002e26> 3432 6163 9 8426 0 s +<002a292b2e> 8426 6163 1 8825 0 s +<38> 8825 6163 0 8895 -1 s +<22293231063105> 3177 6408 0 3690 -1 s +<001c28250026293031320034212b33250029310032213027253200212d2400322825003125232e2d24002932002c292d292c332c05001e1025> 3690 6408 11 8825 0 s +<38> 8825 6408 0 8895 -1 s +<2621332b320c> 3177 6653 0 3653 -1 s +<0007030700040d002d2532352e302a0021313129272d25241f> 3653 6653 4 6058 0 s +<0419> 1589 6999 0 1894 -1 s +wst:dutch12i SF +<0e0812060e0c0604> 2033 6999 0 2712 -1 s +wst:dutch12 SF +<312532> 3177 6999 0 3432 -1 s +<00322825> 3432 6999 1 3774 0 s +<002c25212d0022212d2435292432280032213027253200212d24062e30002c292d292c332c00292d00332d293231002e26002a292b2e> 3774 6999 9 8825 0 s +<38> 8825 6999 0 8895 -1 s +<22293231063105> 3177 7244 0 3690 -1 s +<001c28250026293031320034212b33250029310032213027253200212d2400322825003125232e2d24002931002c292d292c332c05> 3690 7244 10 8426 0 s +<001e1025> 8426 7244 1 8825 0 s +<38> 8825 7244 0 8895 -1 s +<2621332b320c> 3177 7489 0 3653 -1 s +<0007030700040d002d2532352e302a0021313129272d25241f> 3653 7489 4 6058 0 s +GR +eop +%%PageTrailer +%%PageResources: font Helvetica +%%PageProcessColors: Black +%%PageCustomColors: +%%Page: (15) 15 +%%PageResources: (atend) +%%PageProcessColors: (atend) +%%PageCustomColors: (atend) +%%BeginPageSetup +bop +%Defining font PSOwstdutch +%!FontType1-1.0: PSOwstdutch +10 dict begin +/FontName /PSOwstdutch def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001000 0 0 0.001000 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 1 /C0032 put +dup 2 /C0034 put +dup 3 /C0036 put +dup 4 /C0040 put +dup 5 /C0041 put +dup 6 /C0044 put +dup 7 /C0045 put +dup 8 /C0046 put +dup 9 /C0047 put +dup 10 /C0048 put +dup 11 /C0049 put +dup 12 /C0053 put +dup 13 /C0058 put +dup 14 /C0062 put +dup 15 /C0065 put +dup 16 /C0066 put +dup 17 /C0067 put +dup 18 /C0068 put +dup 19 /C0069 put +dup 20 /C0070 put +dup 21 /C0071 put +dup 22 /C0072 put +dup 23 /C0073 put +dup 24 /C0076 put +dup 25 /C0077 put +dup 26 /C0078 put +dup 27 /C0079 put +dup 28 /C0080 put +dup 29 /C0082 put +dup 30 /C0083 put +dup 31 /C0084 put +dup 32 /C0089 put +dup 33 /C0091 put +dup 34 /C0093 put +dup 35 /C0095 put +dup 36 /C0096 put +dup 37 /C0097 put +dup 38 /C0098 put +dup 39 /C0099 put +dup 40 /C0100 put +dup 41 /C0101 put +dup 42 /C0102 put +dup 43 /C0103 put +dup 44 /C0104 put +dup 45 /C0105 put +dup 46 /C0106 put +dup 47 /C0107 put +dup 48 /C0108 put +dup 49 /C0109 put +dup 50 /C0110 put +dup 51 /C0111 put +dup 52 /C0112 put +dup 53 /C0113 put +dup 54 /C0114 put +dup 55 /C0115 put +dup 56 /C0116 put +dup 57 /C0117 put +dup 58 /C0118 put +dup 59 /C0119 put +dup 60 /C0120 put +dup 61 /C0121 put +dup 62 /C0122 put +dup 63 /C0124 put +dup 64 /C0127 put +dup 65 /C0262 put +readonly def +/FontBBox [-50 -256 920 766] readonly def +currentdict end +currentfile eexec +D9D66F633B846A989B9974B0179FC6CC445BC7C8A959A39A32E9DCE7FAEF17EE3BEC9F +50E1A6FCA651FC4B3769A0A91041557502E25A5D6180FE25A3D11BF079E1DF66E54EE9B7C229AF891739707A2A0EC140306B5E43E52B79BFB89E459E50 +6EC6F610A70775A31C460976C4F79449D86E57ACE491E5C6BF20CC4307B1DAF7630252 +E9AF8CFB69B50EDAE9D36A6104AFEF8832F920FD2346B2C7104CD11E3BEE999CFA9F5A +49DB3173EE48D1C82994237F360407B022E0B4 +502E94EA8B493651EF2D03F0B513D655047568325B512AE6 +6AC6F53F3848CF70DE25481CC65D8B1A5793AA +3C4282D111112BEE28AFCA7A3808D4444C4669CA +84EAAAF989219F51AB3476A1B0B5F2246BC306E6 +625C6679C417ED2A8E9BD010DE37D40265074C26842243E0EC59344CEF369650A037B4383B03D6 +24C306E87EFDD4775EC78742 +FEFCE44B765574466C +D1AF7A82 +CFE19FEC07055171803BE35FB61F +DFA5A4C739A4E3957EB7C66233844AC51A6A91B45B75E6AF1F76779A4EA39D554C671F039F6EA0902EEABC13363BDDA5101CA12BB8156EEC5AF0BF9E6FFD41E3E8297895E1554F57314DE5E5E70C32DA47FD30A8525D7EE9C60607EDB6FD9F816BBA9417276F85 +60F5DDB4 +A3948B33ECD70515EFB0F25E7766 +23F737A06578D2C501971D21A1AD0DFB46CF5287869182444F411FF11823026670B907FF382665F39F94C09E0E1E76DC0B02A4BF09FB8F2E5BE909CD4C41833EB22E0FEA75A40D35D7700DE134E6C556D6A7CE512D6327F1F175C4A19C0F64AE61E00DCA03F8F5E64A5A235E5D73BAC487E3CEF5CEE4A4CDE1A68DBB5C77 +212D +08FBF8079BE5531B761799E3 +CAC71CE7 +915BC5DA0DB17FFD4ABDE5111A +09F2F70F6106F3F60ECC4242AE99DC465FD41841E9B7525D5C4B32CEA4DC6FDF1A2165BBFA8A4EF1128FB2FCCFEC878D74E59BD4A4F9B0BEDEFCA9DD265F1FA8 +BFB5B1CE +705E8E3C5B602472007D2FF909 +3CBD678801F52A32B28EDE4923024E25A8795676CC594BC4EC8934E0A7DB874AE00DD507DE5313D4B2DC7A11633AC15E996999BC8CE501DE5DC11EB46F4396 +2F99DEEA +EF2C357CCDDBA7677B622DF0B5 +5C12FD9287FD7D0AEF34BB5E58B5A57F45D645035A33B60E29D60FB936005178251AF10328711FC248E8350EAEA49338756BA4B6F67300F344 +1CB0441D +E802C29EBC459C06C9DAF17C6D +2EB1B8D6D9837F591570D694769A15C7A218595F44419A +D40F8A4B +512CD8EFA6575EDD9C81BB6CE7 +6FAFC31B159889FC2573141E82A128A89FEC2C30E4A733624538555D939E39 +1B20729F +47BC6C5BA2195DF1EA231C3D0A +CE7755A7DABA03394CCC8986CAD22433BC22879D8B7D8B338758833D +0C154F5E +540FBF13F4AD1704D92E4D6E2C +479BC9C7C267F0FC6FD38775759159C985DBB92AB8C9C9B70EF26A2DE4631198EC95F709CAAC33F0FED24B28225B4B5C4D2A500C50776D871C48F0B523E2C7E0A0A46B063855CC30F435 +269CCD2C +0E43CD69F85BE3B73B9062B80F +9C42F94B950BA5B6D3B1D05D4ECA068476CD9BCC0F44297FD4C5FC61B2A3053842F9B013D649DF6EAC03D1A077E1AD203CC4E9BC105F8076F89611A39B1EEC +D88F18FE +D177B43236812372AA82A57957 +CF45F470BEE966D417C9728225810AED28BD3828A2A82F5C9AF368A2E4721E751C8101CDDD6233EE6E8698E6FBA02521C3E23CDDDBB158A9736C0810DA7A716DEEDBED2CF52086B4835A0BB0CA9E96922FE2F6EABFFB4119CE8F148BD8FB42C8BB +D88EB74E +AB5FC3537A8DDC39466A0E2F3C +A21869CCC4836536D87BE8C58236E10A493D765FCB9B7DB08445FC8DBCB229685FA83A29010A409FE937FB3DE0654B376D75D1134790 +A8DC6D67 +E18AC5E413F17D82C1E73C0989 +2E3E65EBD4278F751249F75D98E34F4B25F99F991C88EBB3E0CE609194647AC3C82427B32103BC +94E3678A +BA052D04B65E485A42F897D3B64D +079A3BA824A3C1717282B2F9663C697B005B9C5A2D74E3A62A60384B4ED203BBB3215C738AAB54B2BBCD5F97D472DD9A12353964A1E372942E578CE29BEEA882266905193680ED33E8E9C917B5FF5526BED264D167D3F0AF504E064396D430A3CF2F9ACFDF09C253754639C839B5945D473C10 +024C9D1B +85D60D0F3763522127A0231126A1 +CCB9E7F5C4135367B06ACBB6121497A53C9670FCB0052805C6D0045FCEC6A23F76AE95F85070493E34D88C733356B82D9FCDE77F9DF4562CF2F611EE4A66ACF3BC9FDA53681AE597F3BCCD83DC4F21274CF28D9E0A040C5EFF50EF5B81DCFEC2726E2D22BAF4B3AD3B463840F713661C8DF810B118EE1217CEF95DCFF8B5 +D076 +2D +B8591C7A +9AA3B8C9126CA4F4E04E2B18FA +0D5A7BAA0A5E42DAF07E0DF59CD102F27FC5ECC70A8B5C967493ED28F7ADF5E18560321B55F3BBC7CEEFB7E2A71A7A41C21DF4C2634B7BA5AB4EA7064433D716D3FD3024488C8CE5F3374607B09D3435DA139BD694396E9B21BE2F4B5996885339 +382CB1E9 +B4EECAC398894421851389ADBB +5E2C2A3508EBBB5D6D4EB6C8F0742AB3665EBBF22A75B1FB5DD27BA8A11D5016FEC190EACD7A172AD2169E288F52BCF49ECB8D660073601616728C936FC4CA91C438BC3D261277280B0927140F6ADE87C862854E21C1EB87E3A5B07A43D083BE6CDB60 +AE070410 +146378753E59DB1DDD02A3527310 +A240490429C9A9C703CE34079AF81A378D3642A1FA3EB15F96714F58A62A929B65E54F62A79EABA0A80536A07FAE36B5092DB2A0525ABCD71F3875D9416524E5C7F4DACC4971CF32DFD01E41C62752780D0CBF9D0186A0DE7660B8DC55C683BC0D88C7867D52AAB86B502F15980FBCF8EE2541CC358F3F21970B8FF7BAD2 +1A588FF5 +5CB5F433BC2CA1F1AADD69E8740C +589D604A4CC3C5C47ED0A0B0074D650087B386066E0FF9ABAFDF212AA40AE02C72D46608429DF3293E96DC375795A7DD61308A580556F5EC811FE02C332BCACD509DE6F0E9A8FA80BE7DF8C0F42D2AE199DDE2A6F79F5DB3F44AD83FEC4C85C23605B48CA8D498619A +32C9357A +9232F6551246017DFCEBC7FEEFA8 +41B22745C0FBF89C585364690C5E05F9506A4108B48449787EE2896CDABDB1C55E56C833204BA596A6AFA077BE72A5C0CF453994A570E21D7F401A2371F281000D17533C0EFAE56FE04F80010BF2F6EB3C53F55C1DC0AF88611022CA9B32B0CE96FF283BA6B3C24E10E412BC7D3B3EBC49275026EC98F4942A41 +CC11DD46 +8F876B764A4848F661DB09C03618 +8AF869E87FAD086F86257134A1732E505146F45EAE1652ECEFE77F5CBEFC03F27A0D5E3AA36BA5EB90249B880E142CE663E705CDCD7BA42743DD4DFB51399707D146637CDACF9F63A6CD5DE845A24B7253D50B4C669F9141CD862093985F235043711D9B228A8CBA7411A073288D444D2A649DD3FAA1186889C186B0EDAB +A4BC +43728142EB3FB622EBC6F1 +F3F157E1 +CCCF353372B37A93FD10BB19E1 +8B570DC8400F84A5B644CD2AC7AF5CA7BAC0AB385EEA9FC34B8BF4D14BBD6075D706DB15DD89E3EF313C57FF554CA6C437C20CC8173ABFDC218D96 +57DC8B2E +1056A1FD4163CDFF863C9811B3 +B5ED20AD801A94FE93A52DBE870F3E2AB6EBF899061D3A0BD7FC4F1AD5C051B753CA9364C5E9FC3E63AB24AB713E3403C67ECDB039A8CC3DCB7050F74BA9358763A8A53736F1F6 +39EE0BFA +B7CDDA2BBE1007F5D34E0D7F1783 +EAAB803190870FCCEAEE12EE496EB923F8654781735F3A2E2ED27F3CB98B3371E044C998E37EDBAECED3891A9F14A03D3EDAAC286023C908466CFE87217D28154B571AAD04944DDC567AA85D75D937703570E0ECFDA41442FEF1984C377B74DCD03B00D5EA837B7230DDE656B52C17 +B0A71BF3 +B00F73B13BDDFF42324FABA813 +FDA935FA122C9DEFD72653875F88A60D41454AE6B7084C0AC4B026BE17FF1B4FD9CAD9633942C7E1339F9817EC083AE939F1EA9E9789EFE53F9E07D42DBF4C97721226BBD4896645DD85AAB82AB3E00A74BC561A3447F2493A1A7446 +27C518ED +07E6364584BF82D65DBB76C8EC +67F713283428AD8166E4153F0CC0D0DAAC9183B83C8DCA0215F80E6B730DAE27A6FAC90268ECD6DEF7A726CCB8EB08C949F7E91F78540974C228622A711A10B610DE8F0FCCCF721D303048BF75F8C96516D988 +229CC80F +82F06BDB1F52D5DB37CF02DE9C5B +6A9ED25376D17DEF4B423A74C7F892FC435E803DE41C0DFE8407D6F802153BAAFEFF763CD37528F1EA3797F8A02B6CDFF4260997B86D955DA1AA1246A2FC1DD294AF017DA63E0B3C8A2CAAAA6310764E2C31678B5671220527097AECEB2CD439918C9C285BAA9ACBE4B5 +375D7380 +00B4177C9797088BF98EFBFE4423 +72B08A3170F63DC646D7998DF46F7512C0A3D00226A69D07F2F8786CD670F2E48EA165690AFA15BED3221640D1458821431019C38A44ABCCCA15F1D92A65CCABCA846185E5BA2EFC95168ADE3926AD3A0CC58CAC05AED9669A81C1CC36797B0587289AB82181B3834EF64E87985E81DF1AFC4B229D8C067B17D440BF376E +8E069FBB +3906F4FC25A5A40C50CC7FF582C8 +ACF9BF56B92C5F37DE88902B803B47DBE695C4DF3100955DA837418D26D76D9F9A4E36D9A1C2B23B4F8ACCB04A4B2ADA01C0BA93A1C94E800F142FF3EED2DBEA71B67E658F3F91143D51F7E486CAA74040DC68B5B42FFEFD80A13A8A8B2570FCACE5E3A30DA23DA6580CAE4E888438CAB231CA31F173410DED4E3AE26314 +A87B +EE6BD5 +72B36D31 +F11850B09091829CB43B0237C8 +E67D174E1E58D79497981355B61E71F17F4FFF0D4F281457FC96A9D31D1920E027D891A99A39F6A79693FD107A58288E58DEEFBB592A6AB0C284DE9C64E19E60D68827F1187F772A4B83F8ACE94DD83EE9 +C98F4451 +24E4A94753E484AA015892D5BFDC +37A921D1B143D4B6D5F77FC0C37D5899478C57D411972E96197230A3BC570686EF2CD5E1D7889D185C9E1940C50853867647B77CFFCB1255F11A275679F6121E73B9344128FFD12DD160C5C86AE1B8FB81B58DCDB605E0500BD08F16F5E1D945A771EBFEB373FF921493003556220DE7B9B724 +47173914 +4A49BF8871FEE5E7D6C14AE308 +A9DE8E06315C236C5D28366654730718A0B466A12A00C649BD356768EB5166CED0F42CC0BA6BB85FB530 +3A44F84E +EBC83ED524FC346E4D4E5A1318 +F12E614A40E8103117A2D7CA8344610D8A9FBFAF0527609FEFA55D0537D9F65DC74AF4B210598103BDE0449C +3047A416 +145C66D2DD1A428EBCC8AF9626 +B1DF061F7DC5B1DF5C56B14BFF8C5A09E559E913AD2E +5F1C60BF +C41FCC53C55AD2C30D8A038765 +88D352DB0999DCD2CF465F45F511156532BC7C4D2878FCEB1F8031E6E80F35FA4B6E1EEB6A61BF3F00CEC02EEE70199ADDCDF4E1BC7ABCF748D9 +55F0C3DF +B2D8A8CE6EDA634794A90AB05C57 +6853FED04E85A35252AF1216EC4B6BA47C5F4002444D1E533C4A3BA82082E85BB2E5D1E069B28A169C40039CE5CAAF45C14CFB3A0E07AD62B3730D7EBE97850DC1815A39C2792F2E9F6E40801360B69EC06104A2C6C909A6AB05733BC207FED3738975EAF66893CFF9277BE9F42F2767CDC6816ADC0516F48E8D6ACD2FEE +3B29 +4AFBB6 +5359B7B3 +9F71CD2CC7EE5CDC79CCF3D403 +C8992A078CD00D63607281F561401E2ECC36A14834ADED7329AAC4272E9D277767CF9885C7D8DFA769163AABB453145077A16723825C7E9212DFC6376FFF7C095FC882142AE3B990D13767F44E678E309D780E879238D1C1 +AABD4821 +19F0D1DDB8D570FE10E7831D03 +09FC06C662B3FED529F8968FD0574AB926E0C935BE3E279D083A482CFB2B6DB7EB630C4E5969FC276BB0BBEA3CC00B31206B98ABC2657B592988E9029D811AF82366C836C6AD0E51493B1E5E4D4B25E21F4F +F0242F72 +7E6C7ED1FE6AF6524B29A7E70AFF +5B14B02BCCD0F82AF84414EBB4527A8C336D5B0474EBDC4581E3EB471AB0B08F1873489A24EC7F54957321E4BF41D43101837CDCE41CBEDBA7FE97C1A13B8E7D6FBB0296318DE936D09C45E65F8049E25002352690193ABDE28D279270BA59F92F4117260F39A20C950F27243E13 +106413E7 +231A45F69F73755A420557D900 +85D8AFC057052C2E4D0D0BB662F75A1B82E13B50DC6ACB6BA985896247E44A222587EAF43C42849DB7A293EAA63C90CB0429D81FD376A10F80522E2ECB5929DCBCC43C7EE7F9BB7676FEE1B9BCBCC4531D4200749EA05F1639 +5DFD8004 +F104327693072E0340F399E09D +4ED56A733B89B744BAC3C79CE84F8219D1F1DD340849872D71157F7E95150F570394E89169D90A93CAE5206BAE979DE7A6F0FD6D2D2A1F35D210D4A9E6CCBFF8BC0403DB0BFECF3275E3A08259A0CFBAF3FC98C1F5AEEA621F3E48D4 +093494A0 +C1392A93E549D8A24A766B378FE8 +6691BB121750C6406C4C6389CA1D3F96159DA9DFD51F1C8706F3D5F7510979051EAD2152016E5E052E551C56188EBBEDC1171EF7C3843E2E2B0689F54CFEC33CD385A8CD90216F197383304B2A3AF0EA544C5A68A089AFA79C47EFF69998524FDBFA4461D832F44AB24510AE329F0524F6F40784AAEC4ABADE7CEB1FAE8A +25FD +6D1FEE19F3F5739E20E7063F4E12B76AAAB0D252E771C2CFC878FA07E66DD3CB635C18C7DB6129BF08258DC0A6D090 +31B53602 +3D37F8AB2732989815C7A36D7147 +522078C9B649963AB9EBBF05F6CDDDC59A7209D59F408786C079EEAC0230AF5919ADBF441EA6379DC419D1EB3A51172C77F312B2766D4E7FB746175A4C244C61291A84DAAC8C9DE7B4340E5616DC7343E4A3288B10EAF0B6A43E2E39ADDECAC59D442276845B530A5BB018481D +6C84D0C5 +C88D08175BE34BE2E2BA8E5424 +C8D0A8995968F329B3D54561E94FB6C1C663AF57FA981053756B59C40BAD690F98176D6D2FFD51A3697A21A44592F6A2B435517E89E9A79EB10122FCEAAB226051192CE2AFE0D128E790BA89476EAE12 +8B7EA591 +ECC2D72C710E595E019010C431 +E2D5BD26BF8EE7A6170BF91303DBC2010B5A13C449D18AE5BF9A18FB7B650C2055F7B543369A800F7FC83576FE17AA987BAD644E64AC199F190A5DB2035464A4ED3EF8CEEE0541C1855FF39F1FBBA7D3C84D90D3D382138D3D3C9AB4BB11A1F527D11E +E4030C85 +81465E42FC6134D2F06B2F587530 +D12214A358961F7604A616A197E1CDB47975F93B6097DF2D15DB439E328CE68A785C8E77141D4BF31C65012BD7F2ACF07AF25D7BD99FEE2D9A19B52570A22EF3FA1BDF1E894DFC0368067A0ED614CD9C50F5C3186BF222634056E48F8DE0B04142374D850808531112B306F6F9E934F5AB26D9F514AAC57A05C0A23A6921 +08D7 +E7B5D0F771389442F9CC3A7D879C6618F8F447AD87B95D4BB21906DFBAFF20304820AD +28D3BEE1 +F48A629E767A0A2B1FD4903EE1 +43F0FF847745BDF9EF8EB84EAFE691E764BACDAFC6CFBDE3A7E8F1A59D92208BFEC492938F021F60D4F79011F8785C0A4D49E3D09B3C +A7B8CC7A +E9AAE8072C848FCDC259CEDD6B1B +DFD5E9AD7A244C2AE5B4C0FFEEE5EC8F30666240B4C34D3A67A72F34350C21A049A29221AEEB575B37B282A32CEDB1F0DF6D49C8BD7DD126D289D59CE15BC520D40441DBC571A5E5247B66F2E6557395B520B2C467B754A2090C5DB553A6DF380D137FF9FD19DE73BDB63E129EBA947611DAECE8688DAF258C6D698161F6 +2CA2 +8BDE781CA5D9892DEF79880A763ACA7D5E93388982DC22EEED0049F36BF0DF +E4BABD4F +B45FCCC72A5626E53197FAC453F0 +1520EAD199D15AB8C95625901EAC209050947829D650F4EE41DE478A3863210AAF72A23E177F39E718BA8F6DF7C3F125C44549DB5900C06F6C377ABC5D63360E79E3736CD0A2FCABACC089F02E17E417066B62031D3395243A3F2FFBFE8E5A727ABC43C5BEB1BE992E79DC9B +6460B352 +6AC7CDD30F71731BF8A0C0AC39 +2A2F772A3E2E2727CCFC69034F783380414E7D65D195D4B93A8CFAB91235517983AB225B3B18307E5DDA987704D8E52135AAFB83456CF5072BBE655AF75F066F9BF815292B50 +BB2DAC0D +328C4749DCA7E16BCBC5BC9164CB +93BFFF5CCFF8924F8F07B7A90BAB8D984712D62F97497EE96F208FD35568C79050C21F4C4FACACD0E8C74B344E751F77E5E072942AF04DA1DE503722C1063E9A8BCFD35525A298B1E80B2CDEBB90F59E693F12B6B455C409F127D0E2890E8478D6C6852025F35C301D360D2C9A6FB0F4E78ACAEA39A223 +B62D7DF6 +F5E78EA28EE0B01D112C387D01E4 +F56E5EC15FF9A9F6C5608A35C51E2813706EA1C8B2645C7BF1855BC95947D9E04283121C3192BDD7A0A034AF9E3CAA2B472154971987D66C78D79EE2AAEC8FD7B9146DE3544EB25966F5E0D22291AA0E13CBCB378BC8C8C11774B1E5261783073543554A1441E38B26B2 +5546A06E +2903D18EADDB3515E66C02C72E +13688BC5A07F24EF779594928EE6EDF8EE67CD958CAD3BCAE71BAE82EE9834CCFDF45E3200495BF10AA68EEC35EC45B0F11E1D570D9E3B27766E48DE4530E3569F013A9733F9D093F127B34C39E33B8A34B67D07FBBB07 +38A7708D +EA378029CBA4117348C377D22217 +312B0873FFF00A0F50274AD9CBCB87A4064C0682C4B2A008460A00BAEC2872DC4F325C77706BA681D4051BEB54633439D5E24C94C7E156E0DFCB15C7EEDEC14395C8FCF32100A93EE0945D8670516292D04DF827F5893F345A95A479E3C6ED80D6E0B1DF5650885EA9BEC846C896DCEE07E6D36B70B4CF5283E39AA8 +AA0DB95C +45CC93AD04C2CA6524BC2B2B3D +6ED4EC66A2A90DACEC1A1F2C0EBE2587AE1A7516FA291E884BDD9622D03F55F983959FFFC0B5B026F441D9A6ABA5A1A31156CEA586A81B2F4B8F0F7561CD90A9F4544548DD +26C1E00B +83C67C11B239C1F1F9E3A05F05 +F21E123C7CCD62DE538B71AA7C46F4AE5893B5CD85A6438F15496D2C6C37C3FE28FC1F4BEDE8F04F656C145E651F69145C7CD5D374398F9AFA61A9593DB2AB114A1BB6C517E3571D3ED50122BD5DFDB0892368E46C37AC57809E9A8126FD14E56A35 +2ED80313 +28B037689A006B3E4DFA8B6DF5 +F95734D80DBCB447916A4BD3409B24B1A8B5876655C62835CA599E0B99DEDEBE79C00E9AB0C0A572111CDAB83D1206A8E23B7ECEDC05EA120C5C4C32AA271D1ED84F322EE904F0670CAEC23AD2B9216451AFFCFD58B5984DDE +68ABB938 +FF9414727E0006846CB1DE616809 +BB7CEBA63A4A18611EA29ABD7621DCE22DDF818AE90062C43CCB37BAF3EEE0FE99AE3A4307009A7E650D3237BCD301E2E0BBC8601F0575B91B61BE4965AB5D446851C612A7DEB2BD4C75596AC6439E55C68AB15C5585CBFACB31A1BB4AF12934ABC4B90845404AED8154BDF4ABA26CE4EB12DEC266DA5260886660ACFA34 +2343 +730251D7241F314FBABB6BBF1C8B +3882C611 +EEE8DEBED1116E61E5AB0AB05C57 +6853FED08DEB7F64FB12030BB439AA163718837E52461D6E4A593C20B27B2510A766083785E6709D6157E887F7EFE986AEA3C59764561AB7627D543101DECBD641B68858E4D4B87815DBC6F69DD2EC0743E2EB94397F94552AF0E0B7AEF2415E3BC885A4BF1F029FBF0037182E16FD1C42F36BE928028E842DEF7225C039 +68D6 +204023CC360B31471854C89203691DD4CC6E7CB3D361164679 +8AEDAD85 +12DB9CECB08999CAD95FA3424F1B +7995A9722DC6D8AD9A997DB7E8EC505DD008EBD2F55B540625C935454625D7FD36C9FACE3C3AF99498968DFA98EC22700712F60A0F690FCCB92357175164AAF42A333734FE4D65B4835ED4C5793792385E0982C99A7A0656FB70279090476881C5646EF83ACAEBA59F0BAF64AE4A761D12B60678048C7DA83EF19AFA53D5 +A20C +9DD63981 +9CA9CE2F318217DA730956765D +637B7CAB6B01B591C5804FCE798EAE043C39FDDD381FA7F48770B0EBA28C0E442B1E7EF5F00DA9B36D12DC9FD9239D4E1382700326C61CC0CD97D6E0675740 +8B8DCB43 +8E07FA3DDB43D98395F6281F11 +92BFFEDB192807D7B293D74413FFF4752F6E52FC260ED9 +3EF282F9 +050E770D1BBD23D61838734E691B +C16C50358597A8F4D0C4481CF232A3D09001203F9E2B4353F5C6A83B6979E54B64C71F890FD113502396D4C94CB9678C90A5C745F7873E7EC4A59035DE60C8AE272454621D245F503FEC4C3A41B671BC6E6C7F297D216ADB9BBD48D7297FF93C7FA12A8BC90466AA48 +CA6F3E38 +D7E89D603A37E72A2D9B0044B0 +50747E7DEC8FBC6AA83CDE8DFF47971E571988B10CF9 +A33D8A5B +4305ABEDE6EEC72735CC64DFEC11 +5BCDA35935D625FD +DF3194AD +50F54FA3360849A680BA54F003C35078E07C7C98D43A052256FC61F98DB0FE79FAA5 +3ED0299C04F9923429680E99FC5C4F80EE03E146173376E1FE52568FE2EF44259F4B959BC086 +75BD6C1587A9A8C018DC8256F81BBC5B0E49FE1FB79BFE1141083B +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +%Defining font PSOwstdutchb +%!FontType1-1.0: PSOwstdutchb +10 dict begin +/FontName /PSOwstdutchb def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001000 0 0 0.001000 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 1 /C0032 put +dup 2 /C0045 put +dup 3 /C0046 put +dup 4 /C0047 put +dup 5 /C0053 put +dup 6 /C0067 put +dup 7 /C0072 put +dup 8 /C0078 put +dup 9 /C0080 put +dup 10 /C0082 put +dup 11 /C0083 put +dup 12 /C0084 put +dup 13 /C0085 put +dup 14 /C0097 put +dup 15 /C0099 put +dup 16 /C0101 put +dup 17 /C0102 put +dup 18 /C0103 put +dup 19 /C0105 put +dup 20 /C0109 put +dup 21 /C0110 put +dup 22 /C0111 put +dup 23 /C0112 put +dup 24 /C0113 put +dup 25 /C0114 put +dup 26 /C0115 put +dup 27 /C0116 put +dup 28 /C0117 put +readonly def +/FontBBox [-18 -209 798 694] readonly def +currentdict end +currentfile eexec +D9D66F633B846A989B9974B0179FC6CC445BC7C8A959A39A32E9DCE7FAEF17EE3BEC9F +50E1A6FCA651FC4B3769A0A91041557502E25A5D6180FE25A3D11BF079E1DF66E54EE9B7C229AF891739707A2A0EC140306B5E43E52B79BFB89E459E50 +6EC6F610A70775A31C460976C4F79449D86E57ACE491E5C6BF20CC4307B1DAF7630252 +E9AF8CFB69B50EDAE9D36A6104AFEF8832F920FD2346B2C7104CD11E3BEE999CFA9F5A +49DB3173EE48D1C82994237F360407B022E0B4 +502E94EA8B493651EF2D03F0B513D655047568325B512AE6 +6AC6F53F3848CF70DE25481CC65D8B1A5793AA +3C4282D111112BEE28AFCA7A3808D4444C4669CA +84EAAAF989219F51AB3476A1B0B5F2246BC306E6 +625C6679C417ED2A8E9BD010DE37D40265074C26842696372152E316283F409A2BE3FB67B6CB2D +6C35138848401FCF8D64411A +41FB44D0E855AD39C2 +0BCE5C02 +B2E8B72CB0F5F3A6AD54FC694E +E1CCDB927ED71226CBF0C1C0989CD2E164C8726791DE76 +3BAFE591 +27DBAEC30F85699F02EBB58868 +88D4A6C5798D6DE17DBA54B6F0FD1D2C9E5DC98847C3D87DDAAE43E6DF57ED +8F353740 +E58F04881676CF7060E0D6B570 +6557B831E10C1B331DB194A735BE1B9619A4FC58B5D5069505F7 +070FD517 +A1D0F5CDA9109257631FA203AE +3415AEEA9FB3604EA7447EE6166A50839AFC49A88666CA71D591B7CF9907546E26BFF94E305A75D2D5A2B60632C983835A0BF8B234781FE3F87FDB4416B91BC714389D1F4C07FF6A5027BBD620916A1BDE81E5688942 +A79982F0 +B00FC5CA3B9C9E19F51B59552460 +43C8659E3E94CBC526C91CB6D54CD5C5053B5AB8521757D66B098250613C76A203B47A0DAC2485009EFFFB5157B67C4530AB8E26D45532749DB1743AABE4FE99819A64CC0A2413A48EB444D298ED5FBC598B713192C8E79387D412F10B0AC43B2DB2039A5311CE5D +00EF5DD0 +A7D6B8D08AFABDFEBBC870914CF1 +D522123ECBD0DCE34BB6CF12AB026644C44F1C2158F316A65AD92F9DAD7EE77946263DC8197917D927E0E17972C48BEC5D37FCC609278AAF03B2F7ACF0E4C56564ED5BE9EEE528FED157DB7270DBC56BF1535AE5CE2706BD476D68576E2C9DA7A6C469CD0B1EF09EB58603DAA7EC2BBDC9F27FCC40C56F +8C47495B +F529E22CABFC22B163B3F62A42 +66E23A13E8BC1707BF324E38CE32BEB9CECBE6D433004617FDFB8DD91DCB9942B918BC850A6ED6050B1416C900FB5780A1001B783EA27A7B5E22A4F5223ACD319A9BEF7A3CDFD3C89001305DE10502FA07E2E15864EB04A8FDCA59BA4D7703 +008671E7 +269E2025C4E5CF1761368F446210 +484C1AF945991A2BDF9C0FB4AD63D03436513E329277BED07B66C4FA654443DCE657646AEEDAA828B1C55546060BDEDAFB7876FE77269B1A5C1A7F3C3CF305904A5B2CA4ABDD28949B22AF705120F0DC38B583FA5E3E06E04C1D950F6523C624C6989A4C +C54BC7FF +5114B154D5D72447DD524C2A0691 +1A7FB36EF72F94382A6514AE4CE50AE0689CC4B288BB5B282894F1D75397BCE7A42145AC452DF0E22BA8056194AFD98AB0940F95B38AEF728521869D0EAE47044BFD91C130BA2943F7DBBF341368FC96460236F0364AFB6011267FEACA97D8EA9FC6557347465A3C3E0B2ED90F1976BC1D3C18990A +BE5D48EB +88FAE814CD8FAF8BA980A06584BE +2E6A1DFA09BED16574F0F54F0841EE6CB52B9461D959CF4991E2C28211C5325B6F19641979413609FFE5BF9CE9CEE2ED9A87208401FB624824C6A20D3735E090D236B9A5D8C24D379373ACA052D7C9F62FA8A945795A4D2581091323769F5AAE84AEBA6D931CEB4F7C675C15D9BC0F01BFAC1E405AD6F98CE49B0135DF62 +4AD3 +0EC4E115 +1D83E2D0B0E7082DA626619E1E +BB71D616C191D6E90752F4BADA51E39EE57B2C605222E084122D8A59056A1488449C99F0A30C2EE349C95117CBEA67E4085379C6F33CBDA2833E28ABD0A7CCD4DF383BEE57E854685B +63D61778 +991D09F36A46DFC2ECAE2F21FB94 +C2D83DB87EC4A13D27196AC38866D5E62607DAAC402B51D2B7AADD85548D37E212BB729C58661596B689FD77A1332EE7884CFC950E130FBB501F36B12260E21543280CD412F0DBE2010012C923EF4E317465A32E10111958DA71F43E4666D3B5D9237812C56984 +CC438678 +AD722E74EE056B3BB8A2E8EA1D48 +018A4D4D89F06D8F942C3C2976A77C2029114D8F23823B9DC3EB3C17FDE7E200DEC5DC53153496C1DA0AD0CA70BE4F230578FF293BFDF4DDC7BA74F26D8C0D740617EC54BDE69741880468678E1017B6E1990F7C56113E32D8EF89F14798AEFB79D64111DB74DC35A1BDC413E61F89E3D3ED22D60CC0D4494DFC0C0C0D76 +5CB6 +C4AE53DB +26F1603F +207EE56B9909FD64711FB6A5F1 +038371D1B178E1BB011F6721FC990377ED6C35E3E5D2E94E88F8EBFEA32C93A1FD603485C023495336CA48B4163852D155863326617D9D3FD7DA0250ED67770A2E621B7C938011A2D36B450BFD17C78530C1 +6EF3B798 +5F1CACCC5A38A9E75260F2A9F9 +26A5855DE7596C99940036B9F8D119557DADF61900EA124FB931A01B90A38CF2F807BF5DE5DAE5A8EF1190240007B567FE8C4AEBB9C0E42A7C56D6A099477134E6F4CB53BB65771D10BB2169F66F05E28900A77FF89AB1B25C705E37 +5DF54CDC +89CC23AF09023A875A2244A818 +019BBE819336CFC04E2914829741073AD8F6153D602B669631905588BB5FBE85006485C8C0E1239A9157686D9A0B7170494434493A8B66B969401BA24688E08FEC7465BBD4A4C8CC2A6743D73EA815D02629048ACACA5E5AB8C54AC032 +08C8246D +67B41E99E3C17F79B643FB12A003 +8E1479E881D4854B266AD78E349E1B7382798E14C40EA8C5963B65F8549A82D0F0D4100A8614241C44D4CC9E7DCB63BB7379B8F6ACD6FB94544FB8EEC92C496BC6C5AF7FE8993A7E93C07962DA0C5F115E10976C0789BD05A4F845EEE6C121B6B17B31020D5DBABD0EFAB98D9EC440AF3884B6D001A4720ABDD919B0204F +76A4 +A40E07B9360EA47EA685BEDDD7B746E834CC022BE9C1E586ABA9F01E76ECA00BC8E9CECEF0 +C878D1B3 +113A5315A635C1294C415B51E8 +9FC1E488D08AA17265F5938497037F21F96709CBE70ADBEF9332BBC475554C04FE22B1F56F2BFE94E6B59B61F22567E5277ECE3DCEDEDA7137684DDF27DF626B1F45578A3F71A25970361FEBC25D +1B707D9C +68C984EC006E6A901B4EFC5FBFA5 +69DB2DEE31A445619BD1EA189BE913EDDBD17B7CA3892735E4339CF6FEC9DACD0E3C158D2626D8CE184B2FE413A41EFE1D741179BEA303BAA2DDAFCA531660342CF531C1A9F800B6BF86424D73AB3C0D6E2F2956D4B7F08BDFA74F899F9D3EE2D8D669080DEF532CC542FB0FB974BFD44DDE26968270FE17F47AD41B0E34 +A8F6 +B841F3CC4C9B66BE13B06A34E634550AF37037A6FEDBA64BA1283DCD +CC857B90 +E4233105795C79B1F8775EBA1C30 +63499F24C52DFDA920E03D8D14375C19F6C485385972AC5AA17ADA3D044EEB6CEB6D66D84BE6440286FD3D65AE928A712A8239272C433BB4CF38B44F5F9C50A2C610EE760C3030C9CFA6E21CFE48067EC560E3537AE62859D8561F924920048617674BA190E068 +CC500160 +D4A59A131D93C1CD10CF6D405E +6CE9C7320697D03AC2667C832F47C2A6AAF2B29DBA7238F61EF5DC9FB295689ECC8AFF4C108B2E678A151A8154E093F2BE51CD2BCF4A1F0AC650C9F0B75DCA8DBFFF9A21B5F0 +E5A93472 +2E919EE36553F71C8B49D2016CC4 +3256A16E069404A33245244051332808BC2EB26C740D1A57BDB229F94D6289CFDD87B0B2ACBF5A779904B5803CF984F4A05BE90B1E654AF715CE24E899E87426DEC0077C1684DB049B8CD80C69125921D16043E33FC7A29C8C66C97BF547D54647F56C802784864719EFB12A2B7E8301A4 +6E53C105 +A3A855E91C348C448EB480EB5597 +29BAFB502382EB468E5D01270D57410537DC7B16FF144D5F2CA985A9BFBFB5E60729EE22543B580B83FEB8E1F41A3439ACD5B296812F6F8082BDB58A63D797C9106139910C2F403E8FFB34D87D82D92585B82682F5435009015539A686D7142B6579C475FDE9431D68 +FF2F43DE +7473DD78FEF113B0A05EFFB312 +6DE50C70AB2B6A3CA29BD68A1549AC98E40625DA61C9D3EDBF02756C15329FE61F4590349C3AFA992F23040AA0C63F79031F583C9E2D1C9481B9B0E7537D84F0775460289791FA2AAE2F4B1AA145F29DA73C5F0D3043F9ED13 +97F4EEC3 +185399586A314C67F518D0068835 +D69B465129F1A6A13F6450AA87DCC7819BF91C29D81222E1F27818AE959557C36B171756F165305A263EA794E52D99DE89B7A81FD5FDD1B600E5848B001A88045BF3F8737BA8BBCE4E569A6F0B067148D0543187E607CFCED9ADBA0D3DC548D5D978BE7E0C2C146DF92C0FF46946190E7CD087C8C43B68F70C +5F3A444E +011ED67FA44E8C761F0725C03B +4132B7BA87C1FE90C5288F9390BB12B316E9A27DC17B72794944C0DEB52302E035196E3BF77332765DE04E65803AA2FCB2A5CA34DA6F31175077493008A30950142A3AD2 +0C89F588 +39A58181641BE7444ABF6FB5C8 +C1B20D1A47CDCDBC814E21BB15FA8B4D6AA2DE1A3F776F3BB9410EA805526BA9A0C8D3E71AB04A561E8C79B92C88005F1DAB6D47C1943975D4987AB2A1169FB8C60E6A830F9B6276D1187CEB560F540CD782C18C4C15CFBAA9BDC1 +9DBB23C4 +44A908810147C28C1E3EEA39EF3D +2AFE9349B152C0A2 +ED396B39 +998E65DBDECA3313CEAFDFF21969BC1752682CD02DF3ABD0CD61297D849C791992DF +6A0D1E7488C58984433CFACC33C7B2121FCF320580AD97B019B953FA1CCE999F7BA1650D87E7 +F6F0244DDB0D039548D40C221E57EC300CCCC72A8F4F3E5D6D519B +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +%Defining font PSOwstdutchi +%!FontType1-1.0: PSOwstdutchi +10 dict begin +/FontName /PSOwstdutchi def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001000 0 0 0.001000 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 1 /C0032 put +dup 2 /C0044 put +dup 3 /C0095 put +dup 4 /C0097 put +dup 5 /C0099 put +dup 6 /C0101 put +dup 7 /C0104 put +dup 8 /C0105 put +dup 9 /C0108 put +dup 10 /C0109 put +dup 11 /C0110 put +dup 12 /C0111 put +dup 13 /C0112 put +dup 14 /C0114 put +dup 15 /C0115 put +dup 16 /C0116 put +dup 17 /C0117 put +dup 18 /C0118 put +dup 19 /C0120 put +dup 20 /C0122 put +readonly def +/FontBBox [-144 -236 757 728] readonly def +currentdict end +currentfile eexec +D9D66F633B846A989B9974B0179FC6CC445BC7C8A959A39A32E9DCE7FAEF17EE3BEC9F +50E1A6FCA651FC4B3769A0A91041557502E25A5D6180FE25A3D11BF079E1DF66E54EE9B7C229AF891739707A2A0EC140306B5E43E52B79BFB89E459E50 +6EC6F610A70775A31C460976C4F79449D86E57ACE491E5C6BF20CC4307B1DAF7630252 +E9AF8CFB69B50EDAE9D36A6104AFEF8832F920FD2346B2C7104CD11E3BEE999CFA9F5A +49DB3173EE48D1C82994237F360407B022E0B4 +502E94EA8B493651EF2D03F0B513D655047568325B512AE6 +6AC6F53F3848CF70DE25481CC65D8B1A5793AA +3C4282D111112BEE28AFCA7A3808D4444C4669CA +84EAAAF989219F51AB3476A1B0B5F2246BC306E6 +625C6679C417ED2A8E9BD010DE37D40265074C2684269EABC53FF7B263765296D35ED1BA4516BF +4B2D2462FB62E875C5A3AA29 +57EDAE5594C94C6651 +2CC6E059 +28F13302C0A930BA6D76D18855 +CC16896F61CB60D6C777C40DF032DE13487500C191473E46BFC92C879B174A60A66152DC01D045BA252FA1605BCFABF0AD2CA0138B +7C89865C +830A53F63189319D8C82FF1925 +1B1D373536E1A3A31B787F40875F92797280679C2F19 +EF40AFE8 +FCC8874C7FF59101F0B6759825CC +4836DD01D1E8019084355C07E69685A5A4D5455AE80FCE6D52C7B124581D7D27463E65DBA830155AD69E0CCD38597A01EB501580051685DF1F9F77E6658E4BBF41866583281864F1F83874D4F437ED2606C793C25A516CB5A09D0C42D2E1B564B0ABEFDC6BD5BEE9ABC5364AC9CA273BC78DCD8038A7E948A7F7EBEA9E70 +58A2 +1745A0EB9548277D2F2BA29C2B +68F1CB46 +DB5EC0F3D23AB52F19D269BD41 +83F18D163F87632D16B55190A9284D7A2E24D56AA877FCD085CCDAEB019860F9BDD5D8C57BF0CB0B416EF27AAA50D71A2C6389D1816A669D9258409F8DC9D9232CCC6FE60E950EDC4028BF9D46F7871EDD62573AA4491480FCFF87B6DBA2489A +3C4D0168 +988D16FCE9A91AB225495EAA684B +8EADC5D1A3C289FDFD4A568070B98559DFB8CC0A11DDDC043BB0044A302D2AFDFC53BDE2B3B19E97DF43AB14CC91DFD67B7B5EC95C9BEF597347DDA9501DB4B7866D25C45BDBE60D3BBAD0531E68C89FC6577EAF2DE164BF7262A49A3E74E9DE07DB9B7976 +B1B1A580 +97F28BAC8DFD7507714046B29391 +2B31CAF98561A993324CF5873D2C60571079EFBC7F583B5F94DD13D5BFC25318128CFE0F9C4E9855C25D26819C743F2725BC3144FDB8153B5C823CF28C1C6D26F4203C49C326D61EE26ADDCE41AA19126EA550919119553BEAC8E74B40E7FCC799C734E66B70089571A4DF3C2E99C24EB6F2BC581C450B2C7E39A10192EA +012A +9C5BA31831281F6694DD239E30A35F8D48C8D8A089D5C52604534C +294BADF4 +203EF0FE0E50B6914B0B94AEB1E3 +11381ACC017EB85C791972780EDB50A585E96F862F038D805A0D8F1E93C8297A609EB6EDBC615BD5F79BD2C369158D7963695D3D62006CD6991A30D7F9ED0A931B6D53EF654D91BF579693439105E7C2CFE1FED6783504204F88AB1094B208B498D4D2DBB02B163957CE74900A1E39D8969579F00A1C993BBF +4A00402D +9B0BA2C9B34FF3F9E8B182A02294 +4E02CB6D7FD9DEE1E8A72B48AD9ECD192FEF43A00FBE7ABB079528D2E28BEE878057D77E90237F861AFA8231897C3E4E5B33EABC557ABA6BE6967F2669F14E6FD689AC0B5E25300CE4C2B82352C8F9509C0EF07A10111ADF194387626E053321390A2168F8 +90F326A0 +405FAB46AAF63824456F24A2CED9 +1A65032FB98D41A87BF1F6F82E9F19B589D71BC0FC89E2A33B63F62D60FF4EC78A8001E6B164FB5DC7927640F6B37C0BC694D7426881B23C3CC99A19A2B5FEBDD796DFD3BBCFE4225A64683C75583B5A0443D5750CA339553CCE7D5C3F0C7EC67F8889F5546E82B963C11D42CFFC36EFD9F5EE69F98EA4BE97E5E6F02458 +AAF9 +E934093727AB31B6161BDA7F1A83DFCFAADD1B03E2A1E824D56BB7D3BA8967DE7735E15CF37F8EF0EA83FE6A43B2660F1ACBAC4FAC036986A92B73962EAABE8417513A3411453ED364FCF2 +13E50A38 +CAB1B5317D2878AEE6820594030B +26907E5E3257C0C6DF1D897CAD802D533934C0E5F1B3F5C1B371FA57A06AB8E6EE17C0A7862197FA8BEEABFA7BED503F4D058B84388133D2F061D32D00DC26C1B8FE9B7722B833827E9E912754169D351D48FFF6F85E88835B7F1212AE092A86AF01DAD63B378351B6C32F57801F6266A5C0EF6A2AE7D8DD10AF8EA8FD69 +B719 +6C0BFF6CE84BCA7C235C3FE838373F2C799D0CB5B6F6D1743B +216F9594 +954B39D86A1BFB10BD48225E11 +0640A81CF230AE47C823ADB32A0B9653EF76B7B51C58756B67F2A1EB0456294986174E21E0D872BADFE57D19DA0EF9E91E0B664C1E9A729A983CE2EDFC78010F333BCAC58A2F5521178F829589CF1C92F025A44119F9D2F360B4A94685780E +91B1D33A +9C35912145200D6E664FE80C99EC +9B00946744BC62046D80C0254A6E14940BE2EC17E836465A32B5314E39A5CF30A85E7172008D38425A53861D3293291D3E51701DDA7B96810A8A58611FE270374CD802950CF090A09E306BC3AA3DCAC4CAAE08BDE5937BA8A58F9FD4AFB5AD122C372DE6282B7A37CCE40E8F444D65967D25A644E77A8C75898E714018E6 +DDD7 +0EA904A33803338AFF4C6767BD7A631BF02997EE0BC446EA114DC88AF2DF66B958238E5592C65FC0E1D1 +A772420E +93671A31EB716F2612533BAE1B +750318365833983400E90943934274FEDBA8C42AC777C1BF19D54B8BB06E081307BCA364CD9A5C71DD7F2DE62258D636A788919905208682789A541D8DC97CC42CEA13487005ACC273F6518924605D452140F0061114462F30D3A2 +818FDD67 +B5F7C3A37FFAA8868168C338DCAE +28398846AAACF85BC7D4C10C06525DF642439705A57C0294E3F6B3E8ADBE6D5FD05E8138F95942B45C5D9EBD810CE1FBD96C3441319712E10D9C56C09BCE1B41C98619E3AAA494907075B44673BB7270AFC68956171456EF150EA223A6E892402B0E20407FFD3231B88C6788D41B911742E1DBB253CE +25F04DFA +00553207FD8089361EC2B831FA +C8B35A706E25A585FD239F158A20EDCEA08CFC28FB55233BC9481BD49237DB709B0D0C9E2482D10A20C3907F911CC0D55F0EA164552FE8831D1B3B137FEACB3BE870012A11E5AF0DA2F7B98EE686C52553168026814F20 +C140BC3B +11B178D5BF8FCE62576E316F2A64 +A8F46939E4F0552F5CBC4F3FF0E7C93674FAE17FFFA156469D26A6F5F4F957643C5FF0839F56A2A87C745A725E2B0FF5E14FF5B99BF1CAE746A105F29EF9E32829EEC3DEB8F3A5680A40D4D16FDCE2627A47EDE3F6C9E9B34D7C32417A55D4610AD609B3BF0751EFC7DE6742ED34584D86C1268FAEFC465A5725BE9F1E12 +E0ED +546F339F1CF691331BAE76AFBA4F351C0C7A93A25E4F8B +3FCAF16A +C55AE59697FF2203F8FC70C3D5 +8DC484BEDA17A93085B51FB60AE483845697465E6DA81EF3F008AAE00217E5B35F6A7EA5932F2D89F7A60FA2A8DC22E4A37DF983CD58E0648DB9E6A724F5431F0B539534B0189B580CF0672515D1D7F1B4E945E21C9312C83DAC +E7397768 +72F3F94088497797C97013FD9858 +C8219FE26F2A39D96074E319563CC275454B03EED63669732722D19EF5F8CA11B0519F104EF4EED95DBFC1B1782E16C8DB51C689C5093B275D134033B0EF8F89731D0D3598DBCF698499FB8152DB9683A0D65D423E4B22B63B640F1BEC94E4C4A6DD92A59669EAF2AA8EDB493762EE7014E02D3AC4C7FAD00CE1327A5986 +60D9 +7D08DC7C064698752D45EB74CF8BEDBF0EFB45A8A01A854DCE6C29BD336B34CAD7C6F561C020 +F9C7B9B4 +D6EE5B6CB55B31AD859727FF3A91 +D6EFF971218027792FC4245327BA1D4213A2AAE03C4F89663796924F2652AE379611ECAC648BE250DB5D43F95BEEA5875DF78CD128E4595D17CCF405878BD0175369D074752B341F7DD6D89886041D8A9427632BE87DDD8108506A99F7E74442CF528F6A356F3749A20ABD9057535AAEAB7CCB1782033AA126D9F0044C33 +B2E6 +17148E50617D58A3BB +02F7D31E +F1D8A2F44BB06661B3B7EA6C706C +3433977E40EE6751 +CE1AAA21 +5419E604F28D9E19F89403E5DEE028749AAC82B63D2AB0582CD8F60E91C08D7DB082 +D13780ADBD61B74FD56F00B7A3B45AC68296AC2F3D8BBF6A0E0F79337862EEEF0C3C7F726773 +C50751300485350EBD0E928EC16C0FB1A5772444ACCF56C86D643A +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +%Defining font PSOsymclas +%!FontType1-1.0: PSOsymclas +10 dict begin +/FontName /PSOsymclas def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001000 0 0 0.001000 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 1 /C0069 put +readonly def +/FontBBox [106 45 775 713] readonly def +currentdict end +currentfile eexec +D9D66F633B846A989B9974B0179FC6CC445BC7C8A959A39A32E9DCE7FAEF17EE3BEC9F +50E1A6FCA651FC4B3769A0A91041557502E25A5D6180FE25A3D11BF079E1DF66E54EE9B7C229AF891739707A2A0EC140306B5E43E52B79BFB89E459E50 +6EC6F610A70775A31C460976C4F79449D86E57ACE491E5C6BF20CC4307B1DAF7630252 +E9AF8CFB69B50EDAE9D36A6104AFEF8832F920FD2346B2C7104CD11E3BEE999CFA9F5A +49DB3173EE48D1C82994237F360407B022E0B4 +502E94EA8B493651EF2D03F0B513D655047568325B512AE6 +6AC6F53F3848CF70DE25481CC65D8B1A5793AA +3C4282D111112BEE28AFCA7A3808D4444C4669CA +84EAAAF989219F51AB3476A1B0B5F2246BC306E6 +625C6679C417ED2A8E9BD010DE37D40265074C2684268F16195489648993B9C4D3B534FA887C +DEF605FA87B991F4D20A8F78DACE +5A54C070E03D5C59D9D2D3E06B09CEE028D68B62AB3AEC43C1DD20BA70D288597D9BD8E06818FF764EBAB436723988E8D7CA59E16D39032516BFC5D552ACDEEC6BE938BEF2F43CFFBC811C3626C4DF5F8CF080676520B51C60CEDAD1FE6C92D1431C702174CE517A8FA9377D075A0B6833DAB101DB65397F1419EF5F0016 +004F +6F0824F9657BB4F1C8F981709956865F6855EFAE +9242AD55 +91BBBEE163D844DDA894E13190C9 +2480439E4C71CADA +BD043A9B +A315CAF72652AA7FE6DB2E84D82A6111CE4DE90C02DA0AFFE2620922262A45AB4ED0 +EEC9F4520DD12703442F7D028D4526BD8B771E09FBE11B2749E2D3906894E8D4BFD3F379F14C +3C874F550606965E22FE487B247B5C2D06728490C8F2A3B588CDFC +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +/DPIx 1270 def /DPIy 1270 def +72 DPIx div 72 DPIy div neg scale +0 -13970 translate +1.00 1.00 scale +/wst:dutch12 12.00 /PSOwstdutch newFont def +/wst:dutch12b 12.00 /PSOwstdutchb newFont def +/wst:dutch12i 12.00 /PSOwstdutchi newFont def +/wst:dutch14b 14.00 /PSOwstdutchb newFont def +/wst:dutch10 10.00 /PSOwstdutch newFont def +/wst:dutch14 14.00 /PSOwstdutch newFont def +%%IncludeResource: font Helvetica +/wst:helvps10 10.00 /Helvetica /wst:helvps ILEncoding 0 declareNFont def +/sym:clas10 10.00 /PSOsymclas newFont def +%%EndPageSetup +GS +0 13978 10801 13978 10801 0 0 0 clp +wst:dutch14 SF +0.00 0.00 0.00 1.00 setcmykcolor +<1a29383429362a0d010f01102932272c3125362f012a3336011929253739362d322b011a29383b33362f011c> 2207 558 0 7384 -1 s +<29362a33363125322729> 7375 558 0 8593 -1 s +wst:dutch10 SF +<0b0c> 9346 13385 0 9522 -1 s +wst:helvps10 SF +<4e6574706572663a> 1322 13267 0 1949 -1 s +<205265766973696f6e20322e313b20436f7079726967687420> 1949 13267 4 3868 32 s +sym:clas10 SF +<01> 3868 13267 0 4019 -1 s +wst:helvps10 SF +<2031393933b131393935204865776c657474b15061636b61726420436f6d70616e79> 4019 13267 3 7133 32 s +wst:dutch14b SF +<0b100f1b131615> 1271 1458 0 2055 -1 s +<000503000d1a1315120008101b17101911001b160014100e1a1c1910001910181c101a1b0419101a1716151a1000171019111619140e150f10> 2055 1458 7 8364 0 s +wst:dutch12 SF +<1d> 1271 2086 0 1434 -1 s +<293539293738093629373433323729> 1426 2086 0 2876 -1 s +<003429362a33363125322729002d3700382c2900372927333228002536292500382c253800272532002629002d323a2937382d2b25382928003b2d382c003229383429362a0800152932> 2876 2086 12 9461 0 s +<41> 9461 2086 0 9531 -1 s +<29362530303d> 1271 2330 0 1773 -1 s +<00373429252f2d322b06003229383429362a0036293539293738093629373433323729003429362a33363125322729002d3700353933382928002537004038362532372527382d333237093702> 1773 2330 8 8596 0 s +<002a33360025002b2d3a2932> 8596 2330 3 9531 0 s +<36293539293738> 1271 2575 0 1943 -1 s +<0025322800362937343332372900372d3e2908> 1943 2575 3 3626 0 s +<000f0038362532372527382d3332002d370028292a2d32292800253700382c2900293c272c25322b2900332a002500372d322b30290036293539293738002532280025> 3626 2575 13 9531 0 s +<372d322b3029> 1271 2820 0 1792 -1 s +<00362937343332372908> 1792 2820 1 2682 0 s +<0014> 2682 2820 1 2848 0 s +<36333100250038362532372527382d33320036253829060033322900272532002d322a293600333229003b253d002532280036333932280738362d3400253a2936252b29003025382932> 2840 2820 12 9461 0 s +<41> 9461 2820 0 9531 -1 s +<273d08> 1271 3065 0 1512 -1 s +wst:dutch12b SF +<0c0609> 1271 3551 0 1685 -1 s +<000a> 1685 3551 1 1887 0 s +<10181c101a1b040a> 1883 3551 0 2675 -1 s +<101a1716151a100009> 2671 3551 1 3571 0 s +<1019111619140e150f10> 3563 3551 0 4605 -1 s +wst:dutch12 SF +<1f2c29001f111c0036293539293738093629373433323729003829373800272532002629002d323a332f2928> 1271 3974 6 5470 0 s +<003b2d382c003229383429362a00382c33392b2c00382c290039372900332a00382c29000738003334382d3332> 5470 3974 9 9531 0 s +<3b2d382c> 1271 4219 0 1657 -1 s +<0025320025362b393129323800332a001f111c231d1d08001e3306002500242428292a253930380200362935392937380936293734333237290027333131253228003b33393028003033332f0037333129> 1657 4219 12 9461 0 s +<41> 9461 4219 0 9531 -1 s +<382c2d322b> 1271 4464 0 1733 -1 s +<00302d2f2900382c2d370d> 1733 4464 2 2552 0 s +<03> 1398 4811 0 1504 -1 s +wst:dutch12b SF +<000416171b0415101b171019110415101b1710191100020700> 1504 4811 3 3785 0 s +wst:dutch12i SF +<0e060a0c1006070c0f10> 3785 4811 0 4744 -1 s +wst:dutch12b SF +<00021b00> 4744 4811 2 5099 0 s +wst:dutch12 SF +<1f111c231d1d> 5099 4811 0 5948 -1 s +<253228> 1271 5157 0 1608 -1 s +<003b2d30300039372900382c2900373d373829310028292a25393038003733272f29380026392a2a293600372d3e29370600250028292a25393038003629353929373800372d3e2900332a000b00263d382906002532280025> 1608 5157 17 8859 0 s +<0028292a25393038> 8859 5157 1 9531 0 s +<3629373433323729> 1271 5402 0 2072 -1 s +<00372d3e2900332a000b00263d382908> 2072 5402 4 3347 0 s +<0f37> 1271 5748 0 1515 -1 s +<003b2d382c00382c2900373836292531003429362a33363125322729003829373837060025003727362d3438002d3700253a252d3025263029003833002537372d3738> 1515 5748 11 7159 0 s +<003d3339002d32002b2932293625382d322b001f111c003629> 7159 5748 5 9461 0 s +<41> 9461 5748 0 9531 -1 s +<3539293738093629373433323729> 1271 5993 0 2616 -1 s +<003429362a33363125322729003239312629363708001738002d3700272530302928> 2616 5993 5 5706 0 s +wst:dutch12i SF +<0010050d030e0e030f050e080d10> 5706 5993 1 6838 0 s +wst:dutch12 SF +<080016333b293a293606002d2a003d333900372c333930280032292928> 6838 5993 5 9531 0 s +<3833> 1271 6238 0 1456 -1 s +<002b2932293625382900323931262936370025380034332d32383700332a> 1456 6238 5 4127 0 s +<003d333900333b3200272c3333372d322b0600382c293729002733313125322800302d3229003334382d333237003b2d303000262900332a003937290d> 4127 6238 11 9531 0 s +<0736> 1589 6585 0 1847 -1 s +wst:dutch12i SF +<0f0814060f0d0605> 2033 6585 0 2712 -1 s +wst:dutch12 SF +<372938> 3177 6585 0 3432 -1 s +<00382c2900362935392937380025322809333600362937343332372900372d3e293700262537292800333200> 3432 6585 8 7380 0 s +wst:dutch12i SF +<0f0814060f0d0605> 7380 6585 0 8059 -1 s +wst:dutch12 SF +<08> 8059 6585 0 8112 -1 s +<0730> 1589 6931 0 1824 -1 s +wst:dutch12i SF +<1204091106> 2033 6931 0 2495 -1 s +wst:dutch12 SF +<372938> 3177 6931 0 3432 -1 s +<00382c2900382937380028393625382d333200262537292800333200> 3432 6931 6 5869 0 s +wst:dutch12i SF +<1204091106> 5869 6931 0 6331 -1 s +wst:dutch12 SF +<080014> 6331 6931 1 6564 0 s +<333600> 6556 6931 1 6802 0 s +wst:dutch12i SF +<1204091106> 6802 6931 0 7264 -1 s +wst:dutch12 SF +<000e> 7264 6931 1 7490 0 s +<000a0600382937380028393625382d3332> 7490 6931 3 8895 0 s +<3b2d3030> 3177 7176 0 3494 -1 s +<00262900> 3494 7176 2 3860 0 s +wst:dutch12i SF +<1204091106> 3860 7176 0 4322 -1 s +wst:dutch12 SF +<003729273332283708001b382c29363b2d37290600382937380028393625382d3332003b2d3030002629003f> 4322 7176 7 8327 0 s +wst:dutch12i SF +<1204091106> 8327 7176 0 8789 -1 s +wst:dutch12 SF +<3f> 8789 7176 0 8895 -1 s +<38362532372527382d33323708> 3177 7421 0 4320 -1 s +<0737> 1589 7768 0 1847 -1 s +wst:dutch12i SF +<0f0814060f0d0605> 2033 7768 0 2712 -1 s +wst:dutch12 SF +<3b2c2d272c> 3177 7768 0 3703 -1 s +<003b2d30300037293800382c2900303327253000372932280025322800362927292d3a29003733272f29380026392a2a293600372d3e293700383300382c29> 3703 7768 12 8895 0 s +<3a25303929043705> 3177 8013 0 3900 -1 s +<00373429272d2a2d292808002112292a253930380d00373d373829310028292a25393038003733272f29380026392a2a293600372d3e293722> 3900 8013 7 8806 0 s +<071e> 1589 8359 0 1882 -1 s +wst:dutch12i SF +<0f0814060f0d0605> 2033 8359 0 2712 -1 s +wst:dutch12 SF +<3b2c2d272c0026292c253a2937002e39373800302d2f2900073700263938002a333600382c290036293133382900373d37382931> 3177 8359 9 7923 0 s +<0712> 1589 8706 0 1937 -1 s +<37293800382c29001f111c231a1b1213180f> 3177 8706 2 5304 0 s +<20003334382d33320038330038363929003332002633382c00373d3738293137> 5281 8706 6 8240 0 s +<1f2c29> 1271 9052 0 1631 -1 s +<00362935392937380025322800362937343332372900372d3e2937003b2d3030002629> 1631 9052 6 4603 0 s +<00382c290026392a2a293600372d3e29370034333738292800383300372932280025322800362927292d3a2908001f2c2900073100253228> 4603 9052 11 9531 0 s +<0719> 1271 9297 0 1649 -1 s +<003334382d333237002536290032333800312925322d322b2a3930002a33360025001f111c231d1d00382937380808000f37001f111c002d3700250037383629253100343633383327333000253228003233380025> 1649 9297 17 9531 0 s +<31293737252b29> 1271 9542 0 2025 -1 s +<00343633383327333006002d38002d370032292729373725363d003833003033333400333200362927292d3a2937> 2025 9542 8 5854 0 s +<003932382d3000382c29002932382d36290031293737252b29002d37002829302d3a2936292808001f2c29> 5854 9542 7 9531 0 s +<26392a2a2936> 1271 9787 0 1826 -1 s +<0034332d323829360034253737292800383300382c29002a2d36373800362927292d3a29002a3336002532002d32282d3a2d283925300038362532372527382d3332003b2d30300026290025302d2b3229280025322800332a2a372938> 1826 9787 15 9531 0 s +<2537> 1271 10032 0 1457 -1 s +<0036293539293738292800263d00382c29003937293608> 1457 10032 4 3420 0 s +<001738003b2d3030002629002d3227362931293238292800263d00382c290032393126293600332a00263d38293700362927292d3a2928002925272c00382d3129003932382d30> 3420 10032 13 9531 0 s +<382c29> 1271 10277 0 1561 -1 s +<002932382d36290036293539293738093629373433323729002d3700362927292d3a292808001f2c290026392a2a29360034332d32382936003b2d30300026290036290725302d2b3229280025322800332a2a372938002a3336> 1561 10277 13 9531 0 s +<382c29> 1271 10521 0 1561 -1 s +<0032293c380038362532372527382d333208> 1561 10521 2 3113 0 s +wst:dutch12b SF +<0c06090006161515100f1b040a> 1271 11008 1 2698 0 s +<10181c101a1b040a> 2694 11008 0 3486 -1 s +<101a1716151a10> 3482 11008 0 4197 -1 s +wst:dutch12 SF +<1f2c29> 1271 11431 0 1631 -1 s +<001f111c23111d1d0038293738002d3700250038293738003b2c2d272c00312d312d273700382c29002c3838340034363338332733300039372928> 1631 11431 11 6969 0 s +<00263d0031333738003b2926003729363a293637080017323738292528> 6969 11431 5 9531 0 s +<332a> 1271 11675 0 1457 -1 s +<00372d3134303d003129253739362d322b00382c29003429362a3336312532272900332a0036293539293738093629373433323729002d3200382c29003725312900273332322927382d333206002d38002937382526> 1457 11675 12 9461 0 s +<41> 9461 11675 0 9531 -1 s +<302d372c2937> 1271 11920 0 1770 -1 s +<00250032293b00273332322927382d3332002a3336002925272c00362935392937380936293734333237290034252d3608001f2c29003829373807373429272d2a2d27> 1770 11920 9 7798 0 s +<00342536253129382936370025362900382c29> 7798 11920 3 9531 0 s +<37253129> 1271 12165 0 1736 -1 s +<00253700382c29001f111c231d1d003829373806003b2d382c00333229002528282d382d33320d> 1736 12165 7 5344 0 s +<0734> 1589 12512 0 1882 -1 s +wst:dutch12i SF +<0a0413> 2033 12512 0 2403 -1 s +wst:dutch12 SF +<21> 2403 12512 0 2472 -1 s +wst:dutch12i SF +<020a080b> 2472 12512 0 2870 -1 s +wst:dutch12 SF +<22> 2870 12512 0 2939 -1 s +<37293800312d320931253c00343336380032393126293637003937292800263d00382c290027302d29323800372d282908> 3177 12512 8 7631 0 s +GR +eop +%%PageTrailer +%%PageResources: font Helvetica +%%PageProcessColors: Black +%%PageCustomColors: +%%Page: (16) 16 +%%PageResources: (atend) +%%PageProcessColors: (atend) +%%PageCustomColors: (atend) +%%BeginPageSetup +bop +%Defining font PSOwstdutch +%!FontType1-1.0: PSOwstdutch +10 dict begin +/FontName /PSOwstdutch def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001000 0 0 0.001000 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 1 /C0032 put +dup 2 /C0034 put +dup 3 /C0036 put +dup 4 /C0044 put +dup 5 /C0045 put +dup 6 /C0046 put +dup 7 /C0047 put +dup 8 /C0048 put +dup 9 /C0049 put +dup 10 /C0050 put +dup 11 /C0051 put +dup 12 /C0052 put +dup 13 /C0054 put +dup 14 /C0058 put +dup 15 /C0059 put +dup 16 /C0065 put +dup 17 /C0066 put +dup 18 /C0067 put +dup 19 /C0068 put +dup 20 /C0069 put +dup 21 /C0072 put +dup 22 /C0073 put +dup 23 /C0076 put +dup 24 /C0077 put +dup 25 /C0078 put +dup 26 /C0079 put +dup 27 /C0080 put +dup 28 /C0082 put +dup 29 /C0083 put +dup 30 /C0084 put +dup 31 /C0085 put +dup 32 /C0088 put +dup 33 /C0089 put +dup 34 /C0095 put +dup 35 /C0096 put +dup 36 /C0097 put +dup 37 /C0098 put +dup 38 /C0099 put +dup 39 /C0100 put +dup 40 /C0101 put +dup 41 /C0102 put +dup 42 /C0103 put +dup 43 /C0104 put +dup 44 /C0105 put +dup 45 /C0106 put +dup 46 /C0107 put +dup 47 /C0108 put +dup 48 /C0109 put +dup 49 /C0110 put +dup 50 /C0111 put +dup 51 /C0112 put +dup 52 /C0113 put +dup 53 /C0114 put +dup 54 /C0115 put +dup 55 /C0116 put +dup 56 /C0117 put +dup 57 /C0118 put +dup 58 /C0119 put +dup 59 /C0120 put +dup 60 /C0121 put +dup 61 /C0122 put +dup 62 /C0262 put +readonly def +/FontBBox [-50 -238 920 766] readonly def +currentdict end +currentfile eexec +D9D66F633B846A989B9974B0179FC6CC445BC7C8A959A39A32E9DCE7FAEF17EE3BEC9F +50E1A6FCA651FC4B3769A0A91041557502E25A5D6180FE25A3D11BF079E1DF66E54EE9B7C229AF891739707A2A0EC140306B5E43E52B79BFB89E459E50 +6EC6F610A70775A31C460976C4F79449D86E57ACE491E5C6BF20CC4307B1DAF7630252 +E9AF8CFB69B50EDAE9D36A6104AFEF8832F920FD2346B2C7104CD11E3BEE999CFA9F5A +49DB3173EE48D1C82994237F360407B022E0B4 +502E94EA8B493651EF2D03F0B513D655047568325B512AE6 +6AC6F53F3848CF70DE25481CC65D8B1A5793AA +3C4282D111112BEE28AFCA7A3808D4444C4669CA +84EAAAF989219F51AB3476A1B0B5F2246BC306E6 +625C6679C417ED2A8E9BD010DE37D40265074C268422460C01E0C8156E6E2E0FACCEE618170848 +BF8730DB32B5D68060473C23 +9DBA701053746F2663 +395624ED +0A9868CC80E7AA0866DA2F6FF94F +9E1E6F3D751AA0FB2452C121655DB9282D64179923D7FD12CC5146ED4A5A5F72528C55004630933E43CA7E44BB6D3A0AA9524C74EF56E61D6A17504C64B12DF983C5DBB4F1ACEC71364A5337C2A69585CA84A2DE011E908420B5EF740FA88ADADF7A1F6AC91CF9 +06DF6250 +7A30C3EA2AF31619C5F426179525 +96187203D1338EAA4668AF99943F7D3CF80FDC803D1C4BB07099FAC10129F1B47128072044564872FB89B00E0D4E59DE215935EBA923E11974DD79FBA221E4987E2DA7C93CA8CC566BE380B4173029E79BD8FBD281C71E4CD2D35B64A2DEFB29AD860295F4A73441A84F9D5DE0E4E0D2DAABF95CE12B5CE146CEFAEE1CB7 +238A +E33C2454C707147195F2B1CD +2718B017 +9F17F8D4AC659C483DCB2BC115 +43731619F2F1C9F6961A94AA217607A9E63FDCD42E8FB86B538BCE1AE2FE2130E6BF6C67F285AAFE9918F9BE50845CE38BFD740F79675E7418 +DB49CF14 +2077A1E1504EF1C6305FCA2665 +39D77E9C4CE2F74633928D251FAC7AA975BEF31F4DA4D7 +FEF533F4 +BC60B778573680A76CCA71BB04 +D032344517DC08739FA97281A32861B2E94F1DD9276511E40D4F1AD97D8CC6 +D8228930 +60EBC52EE15D31A917FD0F429A +3E06DC3EAA0A3D820369EEB0137D3A87E294DAC7D9F2A3C6D38CF082 +4E974DFD +7E4A87950CC4AA78FFE0ACD951 +1EAF44E182495812FF02BC63642B7346DF0DED276EAD97FB532D3EE1C6682B5D0E68B95A36CAB7CF1BB21A5054B454F6E72E1D43DA44DC8755836D8EADBFE0A412B78201F60AF1ABD275 +39E9BA98 +E0EDB8D93741DEB13809A7514F +41BB6502A81427D5DA993139395EB1F95C6E437707D66E2E96C9FD15CC15D47564767C2DCB0CF51CC142E350157B10A1997921D55A5CBD6CB454F626CF1480 +54E617C7 +1FBFB6F8C639FEFF432F43EF89 +7224867A837C710D521A7D52C369625AE022B9924A8507CF8FFBD677116E0D6B4AD3D0979CF7B7CC4E877D2B9C26CDD29F304A467FA1DA1ADDD141A5764EEDAC23C61AD0354D8CFF5C6CA2CD49189798BF8B34AC73290A80FC3D +FC5B3C09 +B9A975D4F4456A6BFF90973CB642 +1043F7C78FE584415B5C1632E75BC390929E5ED6AEE1E994EBDD21E5881D4AC0C3D5BEA6A22A327C36B9B5991E3C7FA404CEC5A9DD2697B18A9127B80F72316BED9E7C6B34A3D135EAF77F601E1D402643A42B040C95C7662FAAFA32017C722D11F72F4E0EDBDA6D740C6E70A79268 +20A44990 +94957E2E7FE0E81116B6C11FCC +B97085657272D02EF9ED9C0478D88E81F9D26274C4202B7EB7982ED6C764D65783661E8F0E202455EEEAD4059CE6F4AE0A9911F32FC686CC68EB +E472308F +1B9FC3C695E27E172DFB56143AC0 +3A0FD1802AB6DD2DFAA2D93C1BB2540522BE14E36E8FE56B6605B1290890CAE61A0CA337884782126BF02E80F1B452716B79DE3754901E7D2B235252D2BBC05FD1998977D39C79B88A5C0E851E0B3CD267F95CF186CF44091132958B8125857C85E3EC09 +0FA3C2C6 +0B163F70471FCA237363B9F036 +9B66BA6C392F559FDE9BC172566602C0EDC93E42E65123642F54816EE8465A6C3A8DDF9CE5663BF13D3120575E2AC5E82384FE3BE41B +E9EBAFCF +E0FEC8F9EC3F5803BFE98757D5 +32FCD5ADF392B3C1A865DE3E2637AD94303F68FEA1BC8383962B609F35F02A27EC6ACADD8BCB3CDE626A461084C1AE53C27AE02FC3CAA9C55CE3F570AAE326B127BD477A5852CE5FCF9694B9F3428627 +332A07CB +F9DC23C9C1A1DC6779152D94C87A +42A9148E34673AAF3CD9BEE72582504B7275A84EFBC62509053D0B75C40986B1672271EECD79350C2612D2733B47680DFEC69CD61B430CE79AEBF4167C5D6577F69A6F4401E621BB5894B97180A4395F67D8C0674C1CD6FE3ACBB3E90545175C39C21AB3EE05A7AF85083604717764E4EFD3BA +D3DA06BD +8E52741D6083BA12AFC01AA1F4E8 +7F1F184FC0395B5DF6DBA4746D0F8568EAA5FD01698A777698D53D22CBF2642956FACDD7B848949D9C37DA9CF7BF7FDA3B6CC7663B2451EE98230BF2CDF01A549E785800C5CCC1630626C33A3D58DC416F3AA899ECA056D8FE43E2545212F2D68611D1723CB8F0CBB68566373BC9D347396D36A84A3963F1FE48325E2F36 +D8D7 +32 +EBA75864 +7CC3ADFE0B574DDD83A2598C94 +22463D8BAFFEC947334E62F7B4B405440E004BF63BE70133FEFD8640FB800F7DB67E49971D2C5A0FC09EC916CFC0D49EB3C994B3638655729047F47C00FFA03610D6F0D67C8B8D119A9B65FFBC383DD54CE3008006DB3A9FE11703CE32E55F47DF +4DC24BA7 +1A4F0BB1689C3B6C57B61F8E76 +41F58AC1B80EB79539C495ADA9CC84BFA01722635CA0C5AC612BCE06AC95E0D4509CFF5BC96ECBE8453CCC15208AFFB77F01EF5E42FC5B460988B69B5956DAF04C2D5D9914CE791428F414340963D3EDD0C30D53BA04FC2F3BD824C048784CE5E234CA +B2A8B334 +4213DE597318350CA5E236DD0223 +6DF72F195B03449E9981C4983FF03869AA57BF2531D7DF32112D3B409539AC5396399C4E03B875622B01A27790CDC9BA8B6F3284555750814335BC3B6A0DA65D284CC097827F84F19BE803A2B908885AA22FB4885315843585C9CE16D5845887F33FEA37E2B2B5EFB2402A68DA1B67F18C9D3AB1C3836A668EF90B17A61B +A1724E3E +C3F6B66FA40B01EF3720386289EB +D7CCB6313DBA95E993CADB81F52D42672F59F63DE48AFCCE8C48BC408171053EF9C9718F78B0B88E6FC8AFAB0BBE1234F516433C6774A24A1584C537045F0F83EF0147B564D7B3AD3D7FAB8C7C9F0F4A1CBE73D1DBC062C1E374571AE3396644E1398F94522295D6B321F43DCB4EA7BE8AFDBF0BD67DEB9AEE50050CE49D +699B +02333257470F45D1A3AE29 +6C7644DF +E717E0BDF52A9C8B08342FE087 +6C068732B9A06028FF9082EC89AB71B379B848D3B9A6BF3BCC5E1507BB93056E001FFC0A6701A416571A184EEFA8977F8660FB22E6D8259684D88E +FBBF92A9 +5A8D8B66F6EA83B7899B618529 +F7CD8EA0971010E5E58A836BF6BE3FFBD767B3C273E304ED9ED24493403E96E704753023ED02E7B7A4D90A92E699F79955361268F85EFD3639C47F717E0F2685C5F29A358ACFF9 +61044FF0 +933B8FAB33F5B340CB3422A7F459 +CF47F6F60B95DC8B61BA22DDF0DB8723563F7177B101B253494F8770C95C2856654537B3EC585743087F418A8DA44697E5CEB742873C7DC9BBBFFD1013456256B3765E621EE410E14C87F59E67588C91DAD6FD1A921368C2C6FFF71EC180DCB743D9C71FB9CFFC2AFF8C4B95839CB6 +DF2F4F08 +D5D5E0C81466C4DB9BD2E0064E +5832E8606D49C100519AF39A71015D6EBC553ECD67BCE00B9ACC84A7FE47B31BC79C4FDDE6BE924EA59F1D6DC0BFEC2CCAEFE77E1F8A9E191C72700872F0AA429B88D1959C2AF7F81E1CD12F4EAFF3D767AE5D2BB822821716E33B01 +5EB9B341 +93CF90CE65E24443966AEA7645 +1DF62E972844DD5722A7DD702071E106E64C48980054B056AAB3864DFCC01E4B04563A54293F5BB2642E43C36CA9B3E3C04F9ECC07BB460DE9E055A863F69300741B5B8479C254E4A5E4556E4601728EB61533 +96352AF5 +2EE510461C77F99BA30359E4C22C +DA8CF8B8949011F9577184D8A7A4F71D0E0AC293C6D656E40E9797D924CC631FA66160CFC5BBA197AF55B3F8DA0A09B4B34FE2FDB74E30201E160ABECCEDB5BCB0F4256B877BFE829EA1984C926C032EF8EAEF259153C435236C58CBFF910FFE4465294F106CA88D6BE1 +996263A9 +12E0DED1932844D96248F7B7687F +1681D1037339244C5094598F3B5007EC9140F2BDBBCD0F5AFD189F62F0104E9143D336CE31F8655AAD4D94D4B3F56F421BBDA100358A5B38906CB1A0FA534DB3332CB8A590401D313404641E7CAE6ADF8AF2F5D3B7B63FD3AA679639DA1000D75B48A30A5E633922EBAEAA41E4371D10495D4C160B78C86B77EA3C059F45 +78A5AF24 +FCB29C62924EA7E76D40CCE1EB5F +C3CB801426FECA4D321D08B89EE0A898E6078D76618C3EC2300CE50CAD6B5E7512288F0E2D5F911B8DA48E74AEEDE9D2E2D7CADDF1A46595D06F3185874FD585A91E0B7E976B778082572400591EF83360BEF24D2D22DD0F761D3D3D4BDB2D51BCA2F7ED4EEEBFD9EF49CDFABCE9E1DBC382739C4C329D6C7927BF654BA0 +810D +D95FB7 +43068741 +81D8C3BAEE35BA046E8C6A322C +7FB4E132C8EB9579B71C830DF08C0FB482659829C451B87896156D494504DE1C70FBF1B7E4E8F6B583444681DDD1F3205C565E15310B4775EEDE9C158C10D69B31684B4A9389F19F11DF654056065BA84C +B107B599 +A2020404B18152B07FF26093F44A +497312DD4A47E97436DE4D414EAEF11965D14727B7B400B000BE884CB567A0EC2084167A9869B3929116A1A0D7A86E1DD9A0284C9930E27024826AA48BC24E487F35D85C16B1E445E24E67E66A98BE6DD1DDB336904D4978270C9ACEFE59AA878CE97B7E +6606F911 +50CA9848174ED38F4170DAE9C7FC +A9F7EA5AAB2519076B77381BD4DF8E574490CED069F195C5C3E63F17E1B3B14F67AABACC6BAB4DDBD900F14C002987E33F1BD497DEAD18416E5E26B2A39F049379C79023DF98AF17F8B99C1E93B459443E5D0D3F485FC63B2F5A8FDFF6D0E06A1FF8A0A28F45F95F6400F0B2449B809FFEBCD44F0150688EE9CE06D9203D +341F +E61107104AFD881D91BD35EE39627AC612A6558860E22791865FE79946B6B942D80F1ED6D01E27 +25F79B7C +6C7D532AA1F7BA1A2580E431C10B +B4D94A38760FB1ABB1752C52632F4F4BB4F323BB3A5429949C4C99AE67A93B53DFCF5E439113BE89DAC1DBE36A30A0199FC15C74B9D4AF5A1C1B4FCBD849D3C050DB07EB08EBB17F882B626C138213C6DB4AD472D362AA2B95F65177FD5402FD16AA91436003E8873B80C2B66B0C344BF28C0E +A5FD61F9 +B4160BAB17A5E24AE66C506CF0 +03828E7FD3008243A21993BF9A69DA4DE0C2658C0838 +E0CAD58C +34E853D75FB3FF3FCE3D002B98 +69CBC177034A73AB7E2BEFEF631226C4C5103D8AA6052F3216809FDBEF55419E9429FCC888FA88875F8DC85CC1CF6F7DC8D12E6E67CD82C9E35A +84B290C0 +5306A686F9F848BAAC7795916C42 +1D27476E033A6DAC7833968ABDC93047199A03A9583A874DA5F14E1A0F5D7572ED5196A06BE55179C3FEF9694EF159CA042CB31E6378A99F6BA34D50E6E3B5C5BA781E745F7AE376E484936BD7C1C7AF59DB7449C9F9C2F43A40C2691A8948D76215BC3B37DC4271AAA5D72962A9C7A676D7A3C64ABAC30F36B2A3E51C5D +DD25 +8E7C57 +3E15EAE4 +4CEE0B20BEAC7DA7133FCA04C2 +E431EE3FE114FE5DFC7666C2DA316E3A3D3A7CDEF31BAE3C008AC57F54C9949305745AFF0A63E7EE798C8618DD7A0F5556473CDCB6019494B9846E0178EB8AE66F39DBC1CDB7AC8BC488FA89F99ED58848D7B214E84A2FCF +3C620CD3 +2A7F6DC649FB18964C14DBD672 +99AE5B40239759751EB12ABD4A84655B005830E2231750BDE319735328EAC396E16B419E31555A4AA60A12118D2EA82FB727C66CA33A94980199D4AAC3BB3326FF659A04A3508B28930B6BD1FAB11AA9B944 +7AC0456D +0AF7F6FF5E839BB2DC71F9FC08D9 +8CAFC92E19798F484A1D52761ED82356242E8CD7E8B4A86F73D13BA8B09CD6943549DDDA806834BBCE5C5DDD0D945ED582387FFA014AC840D729A975E4F688CB8BECB76D76541E60C36EC69D839A9F72C19E12180C2C515964D19957FD7B26A5ACC24921DE5591F1F832E4AACF28 +70F6CA88 +4EA2BE09B7913DE479858A4445 +ED454DF00B32A3EE19606B7DED20ECBE42B7F9873327E46BD732F7DCDE14C654D038EC6785FDF1CDF879044AB8CDE56FED655AA3B02D0AF9985004A15F3E1297F3CE37C63E5354954C65C21F26BE1701E6D728BD6165D1780D +E0B2C862 +376966BCF938D908E2E31CFB6F +594D326DDDAFF085911CA4FF56BBE47A6894A703126D7457A3A612BA9B26811D0EEF995FE4DAAA3DBC70EE6C83641E3B3EAE0664DEBBFFA15796E4AF4E485AF9B8D8C94796DD6F8831A38ED92A544F25A2ECDA1932A31890D0D3849A +A8FF61FE +DE9E377EFA588A6E1CC0CE5C7251 +2D196F8D8F12884276E4BC7D847207C905ED42B1E6A780E6E733C4CB7CBEFDA2968CDD54775D38F8633891816CD966631F4440A75C55C59CFB1809067A100AB9C5D826469142AE65C9E647F5284FDE5E67AAF7DC0922257CC5DD5D07C5EF4EE702C2EC21BE611A9829E17F16AF69C78B05FC837D230FC108E65422EBD8BF +0AA0 +1C2C3250640E5624730C868EB15E9A8F00B0F168118A6D79603F569C677B60297C3D17938DBEDF1940E5F0AFF971FB +DC37C89A +7BF0D6F546847038B250A2A18E0F +D974135F9310DF1C5510D234E61941E56FA909FD6CD7B1F674DF7CC91555F5F256D2231B282547A06012B2E1FE111A7C2768EC957B8176D8AC654F55C7CAE448D136C032026AC7C5468D0D89770FD4BE5046909418B6A16DBAB8BCFE24270BE621CD95F1A5EB91D92D12F97DDB +884AE8AC +9CE02A62F41D8E5A0D5C51E64C +F72B4AD985D8A5E5784DA22DE800F7E92D0FF9E91135543012CEC43B494F974E39DC27BB1BE8F2362FAB761E9849D2F55B9CA26932A8EB6459D43C1F91E013A612828E65E12C9EC16CF9C045F7D765C7 +F49243F7 +C921363B118561BB531BDEA4D2 +626A0AD66D8CD39DDE64F54DE437D8E344ACEC15F27CE72465F37AD9B0EE5F3C75A4FC74467B825C3931E187C1DDCDA9F8336D61E6AAFBF24B5EE1B006F7491BE3636D757D3905757711BD653951B4FD1F2B9F5789A32298D209AF918BF3755C6524F6 +827680EF +D453DC492AC6160DF8770D3D92EB +644A1E86A9BFFDEAA819EE50521A0BDB53F66A0D2D3D0B012C19CB71AD8889976A4F88433D4269C0063E819566AD9C39622178B3106035D2E4984DFA92943A87337B9FB4A1E1E89C11E912C8F41742469730854A78A2970F8C66C38B8ED9E39765DD7F3AFF695C8B1EE4C3E272A25ABC2D09E418DD67183EB0FDF65D4692 +6D1D +04C212834E825813727E53B4E506F5F313E8E31B325B1E00FF905C8F5478352FBC2DF2 +AFD0F409 +8DEB5E30F212983A6D40B5B910 +E41AF4F99BA3A8E7C3EAE1FA570C84F332AA03153F6862139C48BB55CB95D9D52D15F679B2F346318754334CD7E8C0C6B46CBA56EEEE +2BA62A8A +4EA0BC82945486657BE2479C6E65 +7A4D887489A162F3F48E2D495B1B5B39D3027AE176CFDBF08F54AB5E540E23BC509E3C150C7AEFAAD4FC77082A36F390E3202648A5E9D7E6871BBA560B26F752E2AA148CF6998A97C6ABD8649A9996EB85B34F0D0AE24743B6C099CCEC6AE591549471EAE7DAD871058EF3F27C8EF53E1EB3227BD914E4EF063C3FAD2EAB +45F3 +77992D9C8D1BC9A9823B20DB25F10013F77082CD443C2613CA28789DA3A3EF +D489E0CA +F370BF2A769B8D2F0CCF6944439B +59CDD0C3810E2EE651B487AC766DFB24C8255B658A32BBBC15F94EEED37F0A84477899CE4B43617387152E56765EBDA4E9AE989710520D59C7C99B298DB166768DD2745D5F684FB92EC41D2CBA15BB9E459F44E710A5CFECE8E605E81AC319524763BD8C33AC053890ACCC52 +681C20E7 +4781ED98BBBD2C4FC52DE32391 +7F5A2060E66B9699DD89EC562D21D33631393A13EC465628A1E09EB967253315D7EBA0CE064ECF84E018127B44192CE6CE7CC1E14E51B594C5829278B280C49590282F1CA919 +60ECBAE8 +03B3938E1F854E478DF232744056 +1593F32ABA3F2E3286B092B3FAB22C930822932F53C9878D0329F50C50E030570EEE29723D206F672C360850930D681954EE05666BC0E7FF69546B84CA3A3FFF998614CB69105D5055386A15D75929ED960EAA34D79E66EB22AB91209CE7060392E72B0B92813747225063C7144FCA59E59A6A565EC853 +2902D342 +CA0990A5F1C757F419F60EE635A4 +C8F7A3B63FCD08699926EC9A66939C924B10730821CB7822E5926D8B3BFF516CB9599DD5F44EEAE79AD52820B3033EF17AFC11B3DF1EA8D8E112E10E1E5F366AFAA1BB7A9B563891E592F99395CA89BD6949895FEA80A3C400C6FF4CDAA01C57B5E705D2CFCA53B2DDB7 +2D9282A0 +6D8C1AB91F9EE3D17B5231FB79 +555D037DF00119440BEFA13F3F2B729E3A8661041489351BDC206113AC7EEFAC9E94D02AFAA1C3075CF1AD272CD11B6D8DF9FF6DEA4F4CF0508DA0727EAF13BB2AC99B51AB18A9CDDEBD565469D641A0D63A7DDEB29F1E +BA1EA558 +87407E4ECA1BCD55B88363E48108 +AE87023F02C622D2A99E34072FD37B0FDE4058E51F667C4390A43ABE1C64C923CA5F52D3D9A1083BA6739C3D7A33CBDF66B93DA0A62EB12F7A4E7680492C6EEC82015F3D2CCD5712360C6E2EF01E18D4712D7661DA9D3696D055E6422EB7CD5039C691655CFF67547EF809CE8916C1369E28A9B63E3013F72585D6B5 +3711BF93 +50F34EFEE2BE52297A333C22FE +29D5C49274B8CBFA494C9FACD8C1465946540CD28B3E7A6150A434DCDCEE2BCDA2921A53A35739BA36A78557A1CBF7C46DEF22424254217C05BBFDCD84AE6B50821809D315 +F1A989BB +430D01C0584249B82D1AFE3503 +31379CBF723BB1469F43A934B9586C5E6EA8E3A44FB76FE3FD33884021E938D60E3F075403651DE9D3E428207E964005F10A43D7FCE2A1FEE530CDA3D0F7F1C6D2B2DC04BB26AAA8DF826D195B2636C6F7FEE31BBAC50DC0E27EE9FDF43659B76FC9 +16303106 +E49E911E0054FDF48B26B90179 +0B3780CD3A104728B7FA2403F980D55884B7E19D86ADFACC79BD8A1E466EF65959EAF9185D0158814C2E89980E6A4FCA63EB08C98DE6D3051A3A15ACB22F9DABA7AAA51897D32CE210E1F4E39F9AC4CD1498CA19573C877F0B +C63C904F +C7562AE1AFB985A0B4C0EB28F470 +193CA13D7E26AA1E21E3E55DF8CF6C93775AD9C99EE61E9D52B8C5F1B3E06CCBBD8ABB32D40231083FF2C2DFE9EF78190550349475368D74B0D7FA7026C8F9D40ACD5D8F8EEDA0B96417EA72629F6323CF745FCA1CC5C259F743C61678DD8C07AC5C61CDF2510C557A9E2A5601DBBB709B8E4758F0E019F0D7F0A8B0AEEE +39AE +F9B81323A6B7FF10D0E29CB7C779 +64D2DF34 +D510DE2BDEF19639E0767A651E8B +0FB5B886612F73A1C8FCAA9DE495F88F5C47D1035C355AB0D4461BEB2EB79D23D5A2187FF216FF7A18965A6BC8314F96609F93FD496780AC5DA1489A8BD7494580739A85B56F85E74D5BD2C25E4BB11D08E622490CBC6E1CD8C85D1D152C7CDDBFB485D1863DF91AC8A516D18409282F5ED26D6C7D09DC9C573F7555434E +3129 +A6F39E2E293327AD055BDE2EFE60348E71C40154F5B746010A +0626A1A9 +FE62C7FECCF6158FD1B92E008204 +127AADEDF71977C9D94D192A83599991505C0689BB122C933B6061343A4A4CB36C4BC556144CE26A1C1C831FA34B20030996BF358D772310CC4CF8C370FBBE8D00C4CEB05C7F1A0AEFD5E108C815D39FB2E8BF98D3FB5DAF5916D4CAE9EE301940350C5D2BA6A220844BCA9751D97AD1E6D917B86A33D03C2F3590283AE3 +118D +716968C0 +1011E95E6CE0F30AC781032081 +C0686DA6BA8CCDC37CC23287CEEFF473778CC4F917A5973C469E84A638F9FFD6CEA91CB4B613459C0B63B16BBC0940E45C5D3E48D6A1E357689F735675208E +742D89D0 +9203F78E9BF0E8FB255B675738 +91636ABD5FF694B1CE9D04017F943F5836FBF3A83193 +B1EC81DA +1BDB0FFE965B47FFDAB945704A54 +6A9A1AEA7C55AAA5 +856ACF29 +A871A1E6270DC11B3B0D11019C659F7B7FD480BFDE23BBEA426DCBAB3BDACA4231D3 +636FB9D3AB12C409C9254C83361524A159FE1F0226DA12775347F64CA14C419FBA0D327CE9EB +B05129B79230D7691C205F64C9EE49E04ED0BE415D501637AB4951 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +%Defining font PSOwstdutchb +%!FontType1-1.0: PSOwstdutchb +10 dict begin +/FontName /PSOwstdutchb def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001000 0 0 0.001000 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 1 /C0032 put +dup 2 /C0045 put +dup 3 /C0047 put +dup 4 /C0067 put +dup 5 /C0068 put +dup 6 /C0072 put +dup 7 /C0073 put +dup 8 /C0080 put +dup 9 /C0082 put +dup 10 /C0084 put +dup 11 /C0085 put +dup 12 /C0088 put +dup 13 /C0097 put +dup 14 /C0099 put +dup 15 /C0101 put +dup 16 /C0102 put +dup 17 /C0108 put +dup 18 /C0109 put +dup 19 /C0110 put +dup 20 /C0111 put +dup 21 /C0112 put +dup 22 /C0113 put +dup 23 /C0114 put +dup 24 /C0115 put +dup 25 /C0116 put +dup 26 /C0117 put +readonly def +/FontBBox [-18 -207 798 694] readonly def +currentdict end +currentfile eexec +D9D66F633B846A989B9974B0179FC6CC445BC7C8A959A39A32E9DCE7FAEF17EE3BEC9F +50E1A6FCA651FC4B3769A0A91041557502E25A5D6180FE25A3D11BF079E1DF66E54EE9B7C229AF891739707A2A0EC140306B5E43E52B79BFB89E459E50 +6EC6F610A70775A31C460976C4F79449D86E57ACE491E5C6BF20CC4307B1DAF7630252 +E9AF8CFB69B50EDAE9D36A6104AFEF8832F920FD2346B2C7104CD11E3BEE999CFA9F5A +49DB3173EE48D1C82994237F360407B022E0B4 +502E94EA8B493651EF2D03F0B513D655047568325B512AE6 +6AC6F53F3848CF70DE25481CC65D8B1A5793AA +3C4282D111112BEE28AFCA7A3808D4444C4669CA +84EAAAF989219F51AB3476A1B0B5F2246BC306E6 +625C6679C417ED2A8E9BD010DE37D40265074C268426989413EAC8C610B86B8D55587E5840300D +B7D41E0748AB20D65BD1C45D +2C572976F59A02FD4F +76038E5C +75CA71350C59C0E29D2580B2EA +1F1F89CFA7357C39E63649165192B587111A55E3D218CE +E1315149 +CC0C19768EDA438BDB13BEBF3C +F60F475784C0196A5B044696D8AB60919984F94940258A768306 +62CBC1D5 +55471E35D658A4E853737ABAE056 +847D34338B1AC3A49D62D404FF1146CB7EDFB498F623E7F003BE7294FA692C8F2A4AB5BD314DCF31261B033BC2F56C70E1791C2329523E9FEC920798E894E831FCE1AEF851127BE985C5A9B830ADBFFA0F5A274E9A0E4ACAE13CCC83A579BCA4D2661A365A703156 +E45B2BF6 +B4F6414D714F386C47B7356973 +C2FBABFD0305082B4539840F3357946A939BDB7D1CBF9EEE02D144B36C0FD6DCA0097DEFAD0E89D690260F4BD02F083408386665CE23104D6F6753C233C03B1D594DA821A889CF435021BF39909D12634589F5E56133C3 +3DF080B1 +62C76C72F736B3EF02E28D2E2DBB +374BA8B06AB1EC2F2D43A63055301FEEDA5F9CEAD01133089FCF26F4D89C1FBD741CC5BE325AAA2191565B70F2E7E00FB838E570FBC49A3948AA730A3A2B418848783F8496E48C6F04FC5545FD8AAF888467D1D1CFD2A7E1CC15F0AAC2AF962BD940BAC56399037CE4CA4CFB42B7E40DADA8FFB6EA8000 +0DC14DD4 +C7B50FD54C3F508925EFCF4530 +BFC8481CA2301D3E1824D39387DA27328C639F1DCA6BF0FB8DEAFA901E7BF094645F62727F07A79671EBC8F7AEDCD6490AFBAA0997FD4B9C08237C5FF690 +69ACA703 +D7B9664CEFF0B0E2FECD6996B95C +59BA14D34C8012D92145A1B4911D9E37D53B32AE54E4FAEFE37043DE330D333D97114D7D48D49C36D93712167E4C52A89B8847C3ABD557A2BE6775077C8B1144F85DE50883DB1D7700B543E2E1223BAC45A6E42A353208EE84B34098AD629DDEC2D10051 +5F49EA23 +555DA2A5896ED2AA778FF4024EAD +5CBF3F5E1DD7A43145E39C3A0F854B9992F33FC716DFEEBD0D97CAD8E2F6A6FCB29000C293124652CB5DFB2CDED5B4AED7215F844C8625C8B42E0EB52C7953E8C1915E5D6603E7A81E39ED70ED66B6F9FD74CC4B095BBE3BB737B8122C8365549E064A5F34E19042B284F0199463265D12638D963F +B20F1BB6 +FFE9FBCA9316C444A6E9D6DA42 +978A983D3DFB71AEFDA84618BA464BC30F9D7811B8A51B1BA5FAC69C8D37F85EBD3008D367FA5FC42EFCC72F63B34AA2CECC6B52CCACBCA284BD8BBDFED97B33D16A15B25E0BB7C309 +D269FFAB +5F4B0D8B1A4CC17814F3E5252507 +25A95D1545A94095CED51E71985E932283AC0453FD45DC061C3A0BB15068D691F4563617FB28224BB1389C463A3AC989C428554E1B93C3CA7B86CE33DC5BA37DA60FB0AE14CBE185BE841D39A74F837268E190938ECC89F0520CD8B1F063F8BA7835A6FE9F42C7 +012AA960 +AA0E8A521FE4CCB0F13730FC48E2 +B2AE43AACBDFC0B4DD9ADC38A9E2FB955067BC2419321C7977C13FCF692DECE05C37FE95D8EB34CC53F7F803EDB07D94FCB4FD8958683044732E9C0EB7AB44B1F818EAD2543DC6CED9864FFF301B30FD05DAA58CAE641856A3AE027143FA27425A50FAFDB4D23AB59D7F210E141457A0474CE1BE9F5B8FDAA64A8456BD01 +470B +B2A1A466423207D001B1B9FCC8F2D61DFCB831B5FE4BE22FFCE71DAC02385D01AB20F1 +4570D8C8 +037960C6FCF3F6039C942AAE2881 +6D999955B3F720EC0563E8B773B60F3E57FF54814521ADD1E5853027CB1DB2319349F15E131B5A96D172F7546DE2E258963F4A6C1B71B9BF05AB9FB4E7637E053C0F93209D336508B906199A97C8EAC147BEC22DA2BB1D17A4CD4B12B4AD766D21BDCDA054ACEB67CD72FDAE63F5E9E971796AD6F194E8ECB0E356CD4C82 +35AA +ED35B74A +8B786239 +B302A023A741FEAAAE7C63E467 +0B9126190190383CF5BF11B4180ECE1E98148803E18818F275F7DEAD95FD5553FD8EA51739F52CF6D34542D5C3446C5F49F2D2C8879C70506BEDEDEDCA4DB2062F978615B8E3816950B8F87B3C504ACF6700 +6AF50142 +30C577794792E6B4E684BC32D3 +AEC992B68394021639CAB1FCCC8263EF292D55513A8730E5F843ACD9015EC5AB9EDA3512B44201225316C57F14D5F2C60BE09DD725082C723AE0BBDE974C7C9AFEEC916263EAEFF50830A32A0B4AF6A9C118A98A9E3755377384B658 +5631B919 +74DEDC9CC0C5014B9A8642FBC0 +85461C1FF62E3549039D05333628F48A2CA63C1A55EBD81E6B654F30604A3F56837F6309EA706075625ACEDE2B32A8B58A235BCEAF210819059C27025114F0506B748B3F98690D178A267A083EEFF765D239855ACA92493EF0A747FCAD +3B00AA76 +CBCF34D9EFAABBBEA979C0C759 +6E61997BB1C94B124062C40EC98E8747772367A92E9C71F8869F94AC9140B653D55CC4FAD98558E7760F0ED1C98A997BC9D98AAA +F4FFABB2 +B99250CB9BAF37DECDD430F9FE2F +3B9316FCEC99EC2A21EADA49E1E4FBE0F69232F1D8977202A3E14FC73C4C87AB569BECF014B08A62526BFE337BCEF2E24DC97E81A214F3BC0F8285EEB1003F918437728A165B2C65E3EAA4484B6A7E1DEAD31C79380CC0D6AB56B84CF6BB727F9FE7F4EBED2F2594610A33DA607661BBB469B08F111A4EACE60FFEBB0E69 +63FA +C9B83B4EF9B9740BF1B88C26BAB27B219E4DA9E6D41F3C45477E659D +E5C5E64A +2FD705F9CA775565C0B032ED0C2C +1FB31D3ADF1FC553DB3E96D8265B90E1F489C988E0871C18A3277F350FAE9E8383BB2108AB74585D3EE3E436067F2027794DFAF1AFFB80AFE9E7FF71C31B1262AD87A17E004E321B4FB7CE15C321D00528488BE55E6C9996D2263F1EFBCBD9E350994AE2F20BB2 +90017F22 +1F61D7CB4E0788FBA6AA2CF780 +DADBD2FED0743767CE33522B3F427BCB931956D16FCB445C7CF9DD4145B320B7C4755D304EC1A461325203395F06B423DC78F5B691503D08C4E6DF08F94F041AC431BE5FCDA2 +4185FE19 +DF55774CF8A6D26B69C1C84F3D39 +7E25A739684E862BFDFE5591365F565D052D2F482F07CFCD5C57C457E8EA1A55F255614F6D1A17881F2B592A841CD0D629B0C94518EA505E99A34D9DA0569C2A4ABAB61E1F8D3442E93FBE98964EFF06748B51B4ED0284A43695E94B20A66F5975292C87A166F76BBF4FAF5A43EAC0160C +E463AACC +815110C67E12BDA3BA815137395B +44EFCEFA8BC412D93B7DA437D148118E98FB81776EC1091A3AC0C28491F7F6FAF89042BCE02724FBC7FCC60BE5BCB959B12C863B1437053B44562DA2A7F47DFCE19113E153A16CAC60480A05F809E9DFAB0BC227631FE21268B9564E154D6FE1D499B8D2000CB0060C +EB671091 +1003DD941BC0CF12F2FF21E9AE +53A0E833E3E6572790E25D753F4AFAA605A2E62CBC0948EED47B6C7C56194FDDB2735DBA8ED6220C8524A557001DD01243F4F4162046F4723C55071E4884297CBB55844DBD74C810ED627A3821A87FF1953F916121FFA68C47 +98139EAA +23CC0249B50E38D4C9007C31F0AF +1C2FD75C83BD91698779E188D20A89BA4FB5EAE2FF1B59ACF140F1AC117ADA0AA492D3C600D66D1CA2F918C47A79A51580882F398C50324D672E6B7AD2F657ACB84B601B09EEBFCFBA9F26B02F43E24C48E82958670688C1977978E49E5478B8C8B871E17F94E5FCEAEBA087E228725CFF66A0BA273E159551 +327405D0 +162BC95FD5C405484CA484CF7B +7D56968E3F2F21DC11EABE1593C76A38A4A0ED823D83F137CCFEC3C7C4C7E40420C578F9E92547B7E4D48E4624877843D7FD7BE60556BFDC458DE636FA28E97313DFDCC4 +FF46F779 +6E0058DF71BCABD705CFCAA4BE +E49A6484CCB00123386E0A8FF20DACF86788CA78050B13A5D86EFAB022200E087A9C5B65BEFB49234B2A6FFA52F257262EC2C4B76A0C68398BA029B2685497C203201558BF008F342E8A28A8AF17FC006D5335C9132A6C9A4081CB +FA6F2928 +8297DD096AD1160ABD65D2C86D3A +D2DA8588B654687E +D4C0A507 +D024C5CAE84699EFE73D860ED876D37939335180788572D040DD0B1918CC74865E1B +155C720BE2D470574F248CDAE9BAA7929B1A235F12AF9F2E748D1FCD6857B17D3389FF5FAB5C +0A7401CBAA49700771A4980CF0D77F48D10DA5F7B704C7F8148F9D +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +%Defining font PSOwstdutchi +%!FontType1-1.0: PSOwstdutchi +10 dict begin +/FontName /PSOwstdutchi def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001000 0 0 0.001000 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 1 /C0095 put +dup 2 /C0099 put +dup 3 /C0100 put +dup 4 /C0101 put +dup 5 /C0104 put +dup 6 /C0105 put +dup 7 /C0109 put +dup 8 /C0111 put +dup 9 /C0112 put +dup 10 /C0114 put +dup 11 /C0115 put +dup 12 /C0116 put +dup 13 /C0117 put +dup 14 /C0118 put +readonly def +/FontBBox [-144 -236 757 723] readonly def +currentdict end +currentfile eexec +D9D66F633B846A989B9974B0179FC6CC445BC7C8A959A39A32E9DCE7FAEF17EE3BEC9F +50E1A6FCA651FC4B3769A0A91041557502E25A5D6180FE25A3D11BF079E1DF66E54EE9B7C229AF891739707A2A0EC140306B5E43E52B79BFB89E459E50 +6EC6F610A70775A31C460976C4F79449D86E57ACE491E5C6BF20CC4307B1DAF7630252 +E9AF8CFB69B50EDAE9D36A6104AFEF8832F920FD2346B2C7104CD11E3BEE999CFA9F5A +49DB3173EE48D1C82994237F360407B022E0B4 +502E94EA8B493651EF2D03F0B513D655047568325B512AE6 +6AC6F53F3848CF70DE25481CC65D8B1A5793AA +3C4282D111112BEE28AFCA7A3808D4444C4669CA +84EAAAF989219F51AB3476A1B0B5F2246BC306E6 +625C6679C417ED2A8E9BD010DE37D40265074C268425D56A4C755D97B61FDB4F478C36521A1175 +50EAB5D68B380666C40618363E +875234D5932CF95278CBF24640AC44955FE0C7424A5B +E767E0E8 +44D02155079D14D788F53AB40E +03103A5A98BE123D93B3B1C4E2D988CE39D871249BFC41B8FE5D351D4875786675A3CEBDC191E95C94252E9763A17490ECEBE82C007AB96BAC87CC0E61B226798CB2762535789973390220F55F935E9F42A2625FBC1045AD146020A342DE8A4A +4DE4E6FD +1D1F27A9C6EFCFE3F70E800126FC +145DF78D8CA3751D0F2E5391BAC8739D569C65B3767C3A9B8893DC81FC6874884E32ECA8CE89FD12D974BA8705CD3A20971DF35FACD15684ADCD221AF8F79A68F2F7EEF978C2A13C21E48E7CBD1D465E6D4CB8942C3602D90BEF13F078809EC6722B58421F05B3D88579E6EEC933B940AAA84AC7DFEF54029714F9F98AF7 +982E +D0266DBB3DF3D9FF0E151921C853706A43889EC70017685AEE05D05ABE839731349B172F73E57E4BECE5B278A2153A26 +125C9253 +84381E4E75241CD248AEAA7942D7 +ECAF59DD422679A828D40B461B3E4526CBBC3CF7AFFF31CDA1C6D7E62E984846948AF798DC640883AFE795D232F61498505FA6253DC661DFCA9B31BE645E7E63FAB9F3D7C26C20935BA212912650CF9BDF0C74CCD14F4ECDE9010F446165D108A255CFF274 +F2968427 +BFFAFF2035139C2B1CC556F99D6D +0A7E6D0F0AE58859628F8A3A4835A63F2D0639C62AA5B8BA4B7E317C22FE5F20252D4D3EC33E589BDC0420D7CE07E9EB0459B3B16F7CE142CD4D9064E8BD57E25EA1892C3EB412F8A850389B3C4A7B86A59A60D886EA1404A6E551C9F09395E6585BE9CD208C4B995C58B1632DB22F7151F8AE870A276DB0F17204284057 +7EE4 +BF0B17F91A4E99D7CFD297D64CA4C020B34C18F26C75185822B95D +DB86C508 +08A335F858F6F0C3CC4A57C8F6AA +9362E8A841B069FECF8C4287E6784BC466D6018D6252DBFA3C6D69D2CB3B23EA6E382089FCF00BBD7E8BEC2556852004FDDF9FCCE52BA273CECB08AF713E8FCCAB6B1D8CCC0A2E58EF5DFED80F22C855B5F94E549C418309873F6EAB4BABFEE0189279225C0B5FF1F77A5BA194FA63E37CD33A08F689ED28A6 +B57C90D2 +0FFBB5C55B41EF8D444EE67AEE69 +EFC73CD1568AA2C3B12576BC71610E0D75DC7246DE6CA0D1748DC789829854A401AE40F81195ED13596CE1A74D5C5D2491EFF3BB7B3185AE8D5EC38B2B441B940D0EE63F53EF5785A1085AB5ABDB77A806BECCF49FA23C8B7A3D3F41E32F3BEA921B8FB1D9E9D47E2D380CE69E250F3685E99EEDD465AEF95C529BBDA647 +B892 +F5BD70CCEDD8967DFA70B1C6ACD2DB652B0D106B642DAD21C30836A78326B0B121045345F08520CC4F1B18CD75AD5703933609F221B028F7641046496EC03A20C13DDE6A1E1040643B8D17 +68752EF7 +28AE30AD6A222F99535061B2CC +994D41EFE42B4ED3B1B9DE87EE528C3769BDC16D9DE07DC75991B7CB3C75B5867CBB58B64221A5A14A400C5249BA1F208D343DD93E6D6EA915B7E93971754EF40F6C795F098ACBC96CE2F94F7CF9C317BBAD12869469D0F9DCBFE4AB50DE77 +240C48FE +C63C68BB49CB4686CCB948228918 +1D89CF7409F738B001393DD555BC695D475105890A66E7CAA0C965E65BCFA94FDD54BEFC4E7F2DD0AB1C3D87A96E8C4A1B9F2BA05E40931578DB956D374059BB205BC84E65C89BB45A18035F9F4A35883D2287E501B4AF3770ABB348A8316EC309AE821F2A37D518F3A1A5BDF8ABAA5B8C9A43017A53ECAF2A9FC8956B59 +7508 +5F10AF5414106DB1735F5F9BD49F3DB891DBDBBD2DCAD91AB9AF50D0A79DB3E03A97EA22250411D921D8 +1842354D +3D6D538E44FE77556CA6510AD6 +BD87E9BD7C5042C25D66D524B62CEF7DF2D48DD13CC90A83EF48CCC704824B6EB4DA6924B78BEC4BC4417E60DA2372BF3ECC374529BA0DF655F108CE11D1251B8127B096F4D5CA06E9C50308F1AC22BABF13C6B6D14DAEE7050300 +65C626E0 +BF0DD48AEFD1A462D145722C0564 +4840865A833B770A831D4210268BC5D42480600D7C06F82842A481A3D644085D12BF87B3CE3CD3832DC111189FFC4EF7DD9CFEFC38F1F2F689480C0C831E1DF8D3F7C3066FB3E5833D54E6D14DBD7F7D1DA37DEF0EBCBBA35592663EF5F7316CA14885568950C29456A372F92D7C6BFABE333503D1DA +34D3E173 +04170F66023002D2EDF7F7B0C5 +3F8780D8B9CA01B7F84ECB51F8B82EEA111A85D7E759F05F1BB6404D288F0C06E7B4080A78A893C6A211ED807F4D54E2026FEDCAB0E5ABE178113B6713D1D1B1A2E4D27D41A267144D1C945F1D3267C0460FC7524BCEC7 +58A08A70 +925E00F5BEFA2CD52B3E44D8C1AF +EAB66655B3982EF50AFBBFBED70DCEAAC0B1356C9930E74DC4E01F3EFFE9E954F4D265006ED0CAA81BD02EF62AA2ADD4EDA9BCCD0A7E78A561CD6F978A585A41B11EB1F4342B02280C58EC33DBB97267E8DFF297B5CDA73830B479659B75FA149201AEE76C75D07C1BA60C9654F5375D1072EBA3547E0ED53D4918DDFC5F +2D9E +74C4AD1399DE67E03092630B8669B7A761DF31C8B8386D +826E0111 +29372C494853FBAC5F302ECFB9 +B5F1F97278AF7D9EA8CAECDE645FF94AC4EB892945EEF0221F0A5A913B0B0733B3A4DFE2F8E049984D0EACFE1FC1A8B46040FAAEAAED6A8EDC1F599520EFB48C9026F812BB2DB10427D101F3EFCA03B33B7C1752A1EF396DF7F3 +DD46FC40 +C9548B2FD2EDF7880E2C79EF21F7 +3ABC121D0DE6B5D8 +83ED7FE7 +6071E0520ABC4341812D0B0B9CD9008F529C8B61712B650CD4EC5E8A32973B596D99 +95ABA05771C17A919E7880ACD012759BDB90DEF3380FED49C186A3AB77AB11364DCA1F55C39F +FDE9C67D392ECF77E9095FB6BC980841E377DACC8488664E3E7FC3 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +%Defining font PSOsymclas +%!FontType1-1.0: PSOsymclas +10 dict begin +/FontName /PSOsymclas def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001000 0 0 0.001000 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 1 /C0069 put +readonly def +/FontBBox [106 45 775 713] readonly def +currentdict end +currentfile eexec +D9D66F633B846A989B9974B0179FC6CC445BC7C8A959A39A32E9DCE7FAEF17EE3BEC9F +50E1A6FCA651FC4B3769A0A91041557502E25A5D6180FE25A3D11BF079E1DF66E54EE9B7C229AF891739707A2A0EC140306B5E43E52B79BFB89E459E50 +6EC6F610A70775A31C460976C4F79449D86E57ACE491E5C6BF20CC4307B1DAF7630252 +E9AF8CFB69B50EDAE9D36A6104AFEF8832F920FD2346B2C7104CD11E3BEE999CFA9F5A +49DB3173EE48D1C82994237F360407B022E0B4 +502E94EA8B493651EF2D03F0B513D655047568325B512AE6 +6AC6F53F3848CF70DE25481CC65D8B1A5793AA +3C4282D111112BEE28AFCA7A3808D4444C4669CA +84EAAAF989219F51AB3476A1B0B5F2246BC306E6 +625C6679C417ED2A8E9BD010DE37D40265074C2684268F16195489648993B9C4D3B534FA887C +DEF605FA87B991F4D20A8F78DACE +5A54C070E03D5C59D9D2D3E06B09CEE028D68B62AB3AEC43C1DD20BA70D288597D9BD8E06818FF764EBAB436723988E8D7CA59E16D39032516BFC5D552ACDEEC6BE938BEF2F43CFFBC811C3626C4DF5F8CF080676520B51C60CEDAD1FE6C92D1431C702174CE517A8FA9377D075A0B6833DAB101DB65397F1419EF5F0016 +004F +6F0824F9657BB4F1C8F981709956865F6855EFAE +9242AD55 +91BBBEE163D844DDA894E13190C9 +2480439E4C71CADA +BD043A9B +A315CAF72652AA7FE6DB2E84D82A6111CE4DE90C02DA0AFFE2620922262A45AB4ED0 +EEC9F4520DD12703442F7D028D4526BD8B771E09FBE11B2749E2D3906894E8D4BFD3F379F14C +3C874F550606965E22FE487B247B5C2D06728490C8F2A3B588CDFC +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +/DPIx 1270 def /DPIy 1270 def +72 DPIx div 72 DPIy div neg scale +0 -13970 translate +1.00 1.00 scale +/wst:dutch12 12.00 /PSOwstdutch newFont def +/wst:dutch12b 12.00 /PSOwstdutchb newFont def +/wst:dutch12i 12.00 /PSOwstdutchi newFont def +/wst:dutch10 10.00 /PSOwstdutch newFont def +/wst:dutch14 14.00 /PSOwstdutch newFont def +%%IncludeResource: font Helvetica +/wst:helvps10 10.00 /Helvetica /wst:helvps ILEncoding 0 declareNFont def +/sym:clas10 10.00 /PSOsymclas newFont def +%%EndPageSetup +GS +0 13978 10801 13978 10801 0 0 0 clp +wst:dutch14 SF +0.00 0.00 0.00 1.00 setcmykcolor +<192837332835290e011001112831262b3024352e01293235011828243638352c312a011928373a32352e011b> 2207 558 0 7384 -1 s +<28352932353024312628> 7375 558 0 8593 -1 s +wst:dutch10 SF +<090d> 9346 13300 0 9522 -1 s +wst:helvps10 SF +<4e6574706572663a> 1322 13280 0 1949 -1 s +<205265766973696f6e20322e313b20436f7079726967687420> 1949 13280 4 3868 32 s +sym:clas10 SF +<01> 3868 13280 0 4019 -1 s +wst:helvps10 SF +<2031393933b131393935204865776c657474b15061636b61726420436f6d70616e79> 4019 13280 3 7133 32 s +wst:dutch12 SF +<1637> 1271 1431 0 1421 -1 s +<002c36002c303332353724313700372b243700372b2c360037283637003538310029323500240035282436323124252f28002f28312a372b003229> 1421 1431 11 6488 0 s +<00372c30280005002437002f2824363700373a3200302c313837283606001e2b2c36> 6488 1431 7 9531 0 s +<2c36> 1271 1676 0 1410 -1 s +<0035282f2437282700373200372b280025282b24392c3235003229003924352c323836001e121b002c30332f283028313724372c32313606001629003c323800353831> 1410 1676 11 7374 0 s +<00372b2800372836370029323500362b3235372835003328352c> 7374 1676 5 9461 0 s +<3e> 9461 1676 0 9531 -1 s +<322736> 1271 1921 0 1584 -1 s +<00322900372c30280400372b2800352836382f3736002632382f27002528002b2c2a2b283500372b24310036282831002c3100240036372824273c05363724372800263231272c372c323106001d32040024002a323227> 1584 1921 16 9531 0 s +<1e121b22121c1c> 1271 2166 0 2270 -1 s +<0026323030243127002f2c312800373200362c30382f2437280024003a28250536283539283500302c2a2b37002f32322e002f2c2e280e> 2270 2166 9 7430 0 s +<03> 1398 2505 0 1504 -1 s +wst:dutch12b SF +<000314151903130f19150f171003130f19150f171000021900> 1504 2505 3 3692 0 s +wst:dutch12 SF +<1e121b22121c1c> 3692 2505 0 4691 -1 s +wst:dutch12b SF +<00021100> 4691 2505 2 5037 0 s +wst:dutch12 SF +<090a08> 5037 2505 0 5355 -1 s +wst:dutch12b SF +<00020600> 5355 2505 2 5803 0 s +wst:dutch12i SF +<0a0407080c0405080b0c> 5803 2505 0 6762 -1 s +wst:dutch12b SF +<00020200021700> 6762 2505 3 7543 0 s +wst:dutch12 SF +<0b0a0409080a0c> 7543 2505 0 8232 -1 s +wst:dutch12b SF +<0c0a07000a04080009> 1271 2975 2 2305 0 s +<0f161a0f18190309> 2301 2975 0 3093 -1 s +<0f18151413180f0008> 3089 2975 1 3989 0 s +<0f17101417120d130e0f> 3981 2975 0 5023 -1 s +wst:dutch12 SF +<1e2b28> 1271 3385 0 1631 -1 s +<00201e16> 1631 3385 1 2058 0 s +<001e121b0035283438283637073528363332313628003728363700262431002528002c3139322e2827003a2c372b003128373328352900372b32382a2b00372b280038362800322900372b28000537003233> 2058 3385 15 9461 0 s +<3e> 9461 3385 0 9531 -1 s +<372c3231> 1271 3630 0 1630 -1 s +<003a2c372b0024310024352a383028313700322900201e16221e121b221c1c0600193237> 1630 3630 6 5355 0 s +<00242f2f00363c36372830360033383700372b2800352834382c362c3728002728392c262800292c2f2836002c3100372b28> 5355 3630 9 9531 0 s +<36243028> 1271 3875 0 1736 -1 s +<002f322624372c32310400363204002400232327282924382f37020035283438283637073528363332313628002632303024312700323100151b051f20003a32382f27002f32322e0036323028372b2c312a> 1736 3875 11 9531 0 s +<2f2c2e28> 1271 4120 0 1602 -1 s +<00372b2c360e> 1602 4120 1 2037 0 s +<03> 1398 4459 0 1504 -1 s +wst:dutch12b SF +<000314151903130f19150f171003130f19150f171000020600> 1504 4459 3 3785 0 s +wst:dutch12i SF +<0a0407080c0405080b0c> 3785 4459 0 4744 -1 s +wst:dutch12b SF +<00021900> 4744 4459 2 5099 0 s +wst:dutch12 SF +<201e16221e121b221c1c00050500> 5099 4459 2 6897 0 s +wst:dutch12b SF +<020c> 6897 4459 0 7223 -1 s +wst:dutch12 SF +<0007272839072c3128372226323736> 7223 4459 1 8522 0 s +<243127> 1271 4798 0 1608 -1 s +<003a2c2f2f0038362800372b2800363c363728300027282924382f37003632262e28370025382929283500362c3d28360400240027282924382f37003528343828363700362c3d28003229000900253c372804002431270024> 1608 4798 17 8859 0 s +<0027282924382f37> 8859 4798 1 9531 0 s +<3528363332313628> 1271 5043 0 2072 -1 s +<00362c3d28003229000900253c372806> 2072 5043 4 3347 0 s +<1e2b28> 1271 5383 0 1631 -1 s +<0026323030243127052f2c3128003233372c3231360029323500372b2800201e16221e121b221c1c00372836370024352800372b28003624302800243600372b28001e121b221c1c003728363704003a2c372b> 1631 5383 14 9531 0 s +<372b28> 1271 5627 0 1561 -1 s +<0029322f2f323a2c312a002427272c372c3231360e> 1561 5627 2 3398 0 s +<0520> 1589 5967 0 1929 -1 s +wst:dutch12i SF +<03040e0b090402> 2033 5967 0 2700 -1 s +wst:dutch12 SF +<36283700372b28002f3226242f0735283032372800201e16002728392c262800292c2f28003124302800293532300000> 3177 5967 9 7525 0 s +wst:dutch12i SF +<03040e0b090402> 7525 5967 0 8192 -1 s +wst:dutch12 SF +<06> 8192 5967 0 8245 -1 s +<1e2b28> 1271 6306 0 1631 -1 s +<00352834382836370024312700352836333231362800362c3d2836003a2c2f2f00252800372b280025382929283500362c3d28360033323637282700373200362831270024312700352826282c392806001036001e121b002c36> 1631 6306 17 9531 0 s +<24> 1271 6551 0 1376 -1 s +<0036373528243000333532373226322f002431270031323700240030283636242a2800333532373226322f04002c37002c360031282628363624353c003732002f32323300323100352826282c392836003831372c2f00372b28002831372c3528> 1376 6551 17 9531 0 s +<30283636242a28> 1271 6796 0 2025 -1 s +<002c360027282f2c392835282706001e2b28002538292928350033322c313728350033243636282700373200372b2800292c35363700352826282c392800293235002431002c31272c392c2738242f0037352431362426372c3231> 2025 6796 14 9531 0 s +<3a2c2f2f> 1271 7041 0 1588 -1 s +<00252800242f2c2a31282700243127003229293628370024360035283438283637282700253c00372b28003836283506001637003a2c2f2f002528002c3126352830283137282700253c00372b2800313830252835003229> 1588 7041 17 9531 0 s +<253c372836> 1271 7286 0 1734 -1 s +<00352826282c392827002824262b00372c3028003831372c2f00372b28002831372c35280035283438283637073528363332313628002c3600352826282c39282706001e2b28002538292928350033322c31372835> 1734 7286 12 9169 0 s +<003a2c2f2f> 9169 7286 1 9531 0 s +<2528> 1271 7531 0 1489 -1 s +<00352805242f2c2a31282700243127003229293628370029323500372b280031283b370037352431362426372c323106> 1489 7531 7 5735 0 s +wst:dutch12b SF +<0b05080009> 1271 8000 1 1916 0 s +<0f161a0f18190309> 1912 8000 0 2704 -1 s +<0f18151413180f0008> 2700 8000 1 3600 0 s +<0f17101417120d130e0f> 3592 8000 0 4634 -1 s +wst:dutch12 SF +<1f131b> 1271 8410 0 1744 -1 s +<0035283438283637073528363332313628003328352932353024312628003a32352e36002d383637002f2c2e28001e121b003528343828363707352836333231362800332835293235302431262806> 1744 8410 8 9201 0 s +<00102f2f> 9201 8410 1 9531 0 s +<372b28> 1271 8655 0 1561 -1 s +<003233372c323136002439242c2f24252f2800372b283528002435280033352836283137002b283528003a2c372b00372b2800283b262833372c323100322900372b28000513003233372c32310f> 1561 8655 13 8554 0 s +<001e121b22191a> 8554 8655 1 9461 0 s +<3e> 9461 8655 0 9531 -1 s +<13141710> 1271 8900 0 1889 -1 s +<21> 1866 8900 0 2028 -1 s +<002b243600313200302824312c312a002932350024001f131b003728363706001e> 2028 8900 8 5029 0 s +<32002c3139322e280024001f131b0035283438283637073528363332313628003728363704003836280024310024352a38> 4998 8900 8 9461 0 s +<3e> 9461 8900 0 9531 -1 s +<30283137> 1271 9145 0 1735 -1 s +<003229001f131b221c1c003a2c372b00372b28000537003233372c3231003732003335322738262800240026323030243127002f2c2e280036323028372b2c312a002f2c2e2800372b2c360e> 1735 9145 14 8990 0 s +<03> 1398 9484 0 1504 -1 s +wst:dutch12b SF +<000314151903130f19150f171003130f19150f171000020600> 1504 9484 3 3785 0 s +wst:dutch12i SF +<0a0407080c0405080b0c> 3785 9484 0 4744 -1 s +wst:dutch12b SF +<00021900> 4744 9484 2 5099 0 s +wst:dutch12 SF +<1f131b221c1c> 5099 9484 0 6004 -1 s +<102a242c3104> 1271 9823 0 1869 -1 s +<0024003626352c3337002c3600333532392c272827003a2b2c262b003a2c2f2f002a2831283524372800352836382f373600293235003632302800322900372b28003032352800263230303231> 1869 9823 14 9004 0 s +<0027243724> 9004 9823 1 9461 0 s +<3e> 9461 9823 0 9531 -1 s +<33322c31373606> 1271 10068 0 1880 -1 s +<001637002c3600312430282700> 1880 10068 4 2997 0 s +wst:dutch12i SF +<0d0309010a0a010b020a06090c> 2997 10068 0 4150 -1 s +wst:dutch12 SF +<06> 4150 10068 0 4203 -1 s +wst:dutch12b SF +<0c0a07000b05080009> 1271 10538 2 2334 0 s +<0f161a0f18190309> 2330 10538 0 3122 -1 s +<0f18151413180f0008> 3118 10538 1 4018 0 s +<0f17101417120d130e0f> 4010 10538 0 5052 -1 s +wst:dutch12 SF +<1e2b28> 1271 10948 0 1631 -1 s +<00201e16001f131b0035283438283637073528363332313628003728363700262431002528002c3139322e2827003a2c372b003128373328352900372b32382a2b00372b280038362800322900372b28000537003233> 1631 10948 16 9461 0 s +<3e> 9461 10948 0 9531 -1 s +<372c3231> 1271 11193 0 1630 -1 s +<003a2c372b0024310024352a383028313700322900201e16221f131b221c1c060019323700242f2f00363c36372830360033383700372b2800352834382c362c3728002728392c262800292c2f2836002c31> 1630 11193 14 9192 0 s +<00372b28> 9192 11193 1 9531 0 s +<36243028> 1271 11438 0 1736 -1 s +<002f322624372c32310400363204002400232327282924382f37020035283438283637073528363332313628002632303024312700323100151b051f20003a32382f27002f32322e0036323028372b2c312a> 1736 11438 11 9531 0 s +<2f2c2e28> 1271 11683 0 1602 -1 s +<00372b2c360e> 1602 11683 1 2037 0 s +<03> 1398 12022 0 1504 -1 s +wst:dutch12b SF +<000314151903130f19150f171003130f19150f171000020600> 1504 12022 3 3785 0 s +wst:dutch12i SF +<0a0407080c0405080b0c> 3785 12022 0 4744 -1 s +wst:dutch12b SF +<00021900> 4744 12022 2 5099 0 s +wst:dutch12 SF +<201e16221f131b221c1c00050500> 5099 12022 2 6953 0 s +wst:dutch12b SF +<020c> 6953 12022 0 7279 -1 s +wst:dutch12 SF +<0007272839072c31283722262f3736> 7279 12022 1 8520 0 s +<243127> 1271 12361 0 1608 -1 s +<003a2c2f2f0038362800372b2800363c363728300027282924382f37003632262e28370025382929283500362c3d28360400240027282924382f37003528343828363700362c3d28003229000900253c372804002431270024> 1608 12361 17 8859 0 s +<0027282924382f37> 8859 12361 1 9531 0 s +<3528363332313628> 1271 12606 0 2072 -1 s +<00362c3d28003229000900253c372806> 2072 12606 4 3347 0 s +GR +eop +%%PageTrailer +%%PageResources: font Helvetica +%%PageProcessColors: Black +%%PageCustomColors: +%%Page: (17) 17 +%%PageResources: (atend) +%%PageProcessColors: (atend) +%%PageCustomColors: (atend) +%%BeginPageSetup +bop +%Defining font PSOwstdutch +%!FontType1-1.0: PSOwstdutch +10 dict begin +/FontName /PSOwstdutch def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001000 0 0 0.001000 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 1 /C0032 put +dup 2 /C0036 put +dup 3 /C0039 put +dup 4 /C0040 put +dup 5 /C0041 put +dup 6 /C0044 put +dup 7 /C0045 put +dup 8 /C0046 put +dup 9 /C0047 put +dup 10 /C0048 put +dup 11 /C0049 put +dup 12 /C0050 put +dup 13 /C0055 put +dup 14 /C0056 put +dup 15 /C0058 put +dup 16 /C0065 put +dup 17 /C0066 put +dup 18 /C0067 put +dup 19 /C0068 put +dup 20 /C0072 put +dup 21 /C0073 put +dup 22 /C0076 put +dup 23 /C0077 put +dup 24 /C0078 put +dup 25 /C0079 put +dup 26 /C0080 put +dup 27 /C0082 put +dup 28 /C0083 put +dup 29 /C0084 put +dup 30 /C0085 put +dup 31 /C0087 put +dup 32 /C0088 put +dup 33 /C0095 put +dup 34 /C0097 put +dup 35 /C0098 put +dup 36 /C0099 put +dup 37 /C0100 put +dup 38 /C0101 put +dup 39 /C0102 put +dup 40 /C0103 put +dup 41 /C0104 put +dup 42 /C0105 put +dup 43 /C0107 put +dup 44 /C0108 put +dup 45 /C0109 put +dup 46 /C0110 put +dup 47 /C0111 put +dup 48 /C0112 put +dup 49 /C0113 put +dup 50 /C0114 put +dup 51 /C0115 put +dup 52 /C0116 put +dup 53 /C0117 put +dup 54 /C0118 put +dup 55 /C0119 put +dup 56 /C0120 put +dup 57 /C0121 put +dup 58 /C0122 put +dup 59 /C0262 put +readonly def +/FontBBox [-25 -256 978 766] readonly def +currentdict end +currentfile eexec +D9D66F633B846A989B9974B0179FC6CC445BC7C8A959A39A32E9DCE7FAEF17EE3BEC9F +50E1A6FCA651FC4B3769A0A91041557502E25A5D6180FE25A3D11BF079E1DF66E54EE9B7C229AF891739707A2A0EC140306B5E43E52B79BFB89E459E50 +6EC6F610A70775A31C460976C4F79449D86E57ACE491E5C6BF20CC4307B1DAF7630252 +E9AF8CFB69B50EDAE9D36A6104AFEF8832F920FD2346B2C7104CD11E3BEE999CFA9F5A +49DB3173EE48D1C82994237F360407B022E0B4 +502E94EA8B493651EF2D03F0B513D655047568325B512AE6 +6AC6F53F3848CF70DE25481CC65D8B1A5793AA +3C4282D111112BEE28AFCA7A3808D4444C4669CA +84EAAAF989219F51AB3476A1B0B5F2246BC306E6 +625C6679C417ED2A8E9BD010DE37D40265074C268422457D8CE35980429BB1D919A0AE8BD7E5C8 +FD15F7F61BF0D2836908BFBC +D4CB39198644F31BBE +D73A689F +931B1FD60F630F7F9BED6F1CD559 +38E4C90669B494937A37596E6FD1BCFA08BE98FB22015564BFC01C8B6723955225AB49AFD5D909FA689D59C1E3E36126A47D22BD55B082A4299B1F2DEA251472CFCC06A546DDE5B5E27F36F39834BFEAB472D1CBECC52F0ABF8D2061CE9C369EDA16C0718A15DF6FA2637228C1DA266A6D8166F55802E7E013ACA275F9E5 +6594 +5A50EC478A99CB2F3DA2CFC7 +FA7910F2 +F7E949CC5A845909C956073465 +C3098121BE460783574E423C2319F9AC61BBFB9A3456677EFF25DB43A141E10B57793C3CD0B6A381C5043F5DA2E295F29695C955866F8CA8 +9C087E6A +EE84EA885577B5496F436B3DF2 +4E7DC6ADF5A2D3A7272321494DF463826C6D8EB41EE690DC3256E25392B3FDD67F49B908945196B50A97FFED9C3F1B6083B7F78F112C378E65869AAFE959726D +BE3B9675 +6BFBDBA9D55CF56520572EEE2E +A522F9BB3FFC1C62A5B73A26FF2D748657BB9B26E7FD0EFC9E2A313950BA650F21FA35900041405257F7E1AC339E4E222D04B15F876814D79BD05EF9B46D54 +BEE82E13 +412934B16552FA49A707C675C2 +87908E156DDDE3DAA1E78404D99F9E05D1CFC3AE80098B3C71EBEC01FC372D8CB5CA93E7CD8AD7DC123EEF6A42248219A246589846D5C27B10 +A0724E8B +86D78F640E8F30A6696A01DA72 +24B06AADEA2EB2074B361C9B97BA62A806AB5422EFB21F +93AE23C9 +A84F32BA07284D4A6D453DD157 +B162EC918D80748EF9F3FF1C43A8A7C8158DE7EC997FEB100723F225C223E3 +D116A3C7 +4D3AFAFE6456651BBC37B048F0 +4954ABBB22D65B51CD8DDB371D94E8C678FC9A8706F074EF00E7054C +77C046DA +DFE9FF85568A48E3B2FD81E9DE +850E1F7E54B0330D598C104C0D3A4EC92509BA86076DD1584A5575A2BFA3570BD2B422C70B8AD7A5060DD25F3D0BB11651FA12BE1DDF8CB30F42C1F564EFFD21454D12922A6FD074DB87 +DC3C992F +2B96D92A5AABBF711F84E30EC7 +3AE00E9730B64260BCFAAA011D4425A05C2D4BA3B36C7CD8A635FD5AE8CA1DFD5D613E166D2B6C300B2493C6F2D307ACA7D9A82DE813076042FAA0C12845AF +47F5BAE0 +92D87FFA5EB150D4458B75445A +0099EA0644BEC495DF01E5EDE5F9FC0BD078292FFB8AE279CABD7E9A7D48F0B88BBA2B8717729AFAE72BE9A6DD47069AA71BAB12835711395ADADD119877F6CF4776991E994D73E4B84A8B1BB036BE76ABDF3DB074196B653EF4 +9B40D74E +4E6403F447C8EE4DD9D523FE71 +0FF61D76C3E7309ABC4ED74BDD0587B201EEB4FD1A14C43CC507EBF559B850AFF044620F1EECE3E7EE7F70 +02F908AD +71DAD1D6108403BC88037B15A4A9 +6B2772BA327FF9335762DFDA0B700ADB0443A71DBB686AC9F5C7C72AE5E71B805D76811BF7D798A767D86537CBF9F8CE0790301977C9BBB6269D0A12DBD3FEE8F76F9031F13A519A829537F886CC40B4EA5B0B46071BAC7B776008725874B1B55EC7EF70FFFEB983FE10A5E4FCD74258807A9097E49EBB693975 +8953BDA3 +40293403687938A186ACE9F2A8 +EC2DB98F585FEEF30F449ADAC56683CFAB45D477BB6F706552ABD04A1E84910DE82BEFD1793B16CA5FED8460375EFF06F0BE982D82C2 +EE623BFE +4AE4F002BFCA7C34151001D41BF8 +5A2BADAA73D1584335DF3144C63B678BCF0F23AE77C480B276D681A1D2D14F4F01E03AAFA4B9E9405C3F720FCB9C636B9E928920A0E23F750D6FF26705F5F0102D46F620F8E616A2D05CD5BD8F0F43712825179265456A58957D2038BA33E0EC3260BC18A86EB937717A8040BC50555508AFB0 +E5C6CDB5 +B539650A04A86BE914E5288356FC +2CB43FFCE1411A92D844C1E0A755EACAA3D52452BB3631173A41A8FB26D14A81DE1149BB59C5758A78719D648936D36EE7EE91162D50B92B1C64D56DA99E8CE770F04C0C3F80B6C4CA5F3E37295D84602E041A84EF1699D52E265CF7BB62E2BB3C633436F7B25BE73C077EB18A0E38A531963E6BF615421F4FDB084F3C49 +162B +6B +9564699D +290CEE78EF7BE9815635A542C8 +389853B3519A49D99368A1B8D8B6AC3450D4F7894037697A607EDE776A1A021A155216008B0D7EA109DB2060C9A9334AAAE2F2F1A861DADD1AF513DB3527ADDB1572FA50440BDCA918869734F0A622FCCAC2F09AFCE40E8CF4C1F62A9C23BAFAFC +C1A0DA3B +E5878D1EDCADB96BABC624EA88 +5430175F201A7F260656F98CC15BB75D3D39E78502A50EE0B6A8EF656370055145A15AF306FEC8C7FA05B1EC6130D2516171C72AABF209E952459A5F2CF447152837BB553A786A50C0AA684BD89FE9824E8FE1AA9B0A60D5FE0E20FA341F9D8FA170F8 +CA368EB3 +D007DE8E9B46E0B8BC4AD47B9C7A +7991D1BA0018BB8CEE1B6DBBC0D159D602CF5B06AEA7F8C2EB57EDDF3BC28DDC0965A9473A6B237DC51D3B3ED96263C9448E20B7EE922FD22EBF8DC1F40034B95A48575407ECFCBB51B22932AF15157DFDE213AFFC3D0744FF23F01CFE9D1B442051762F8965CD0F9BFED335584117FD80D81DBC39287708F78190922B80 +2EF4 +97E68B8BFD7D18C3FF7F79 +6BD95BF0 +3B21294F8BE82A3F320A0CBBC2 +2A3CDE08F10B7F4685DD7054C120D868ECF916510CBAD986B1A386FA9B7B1CD98CD462A97F8A4988815AA0C29E78992A02E7CCB8CDB8C78BE80E29 +66F26EE1 +C2596246031036611CC2C88A95 +5A6054DC3FECB3943CA776298DF7543EC3671A4289D36D9166731C889C09DC9A44BF808854AB01E243623E929F3AFEEF7AFD49724DD8978EB7DBAD6C7703AC24D575831C7D2051 +77F87A79 +E9A4576FEBAAF6B1C00090C6F31F +4FE1B03451F93D5498F5F9433C2D27199ACF8C7897E46BA6AE315C92B51B4D28346845C11C261F415882D80D421F06EAE6C2988F990931B3D5EA6BB522878F9D2B89F0F6F09E9D7E942BD86913A9A9CFC13521D25EB0D5892FFC9DA81A618B4F6CC1B19C49D4D70062AD62FF51E5E7 +359F475C +375E94DFCB2D36C2D86BA2E11F +15D300A97308B5B8835ACDACA6DC7264EDB31430874378EF0E846A993CE0B752A694651BCE9FB475C3B0E4BB4D6801A06B10FBD7E7AB5F139D17C08847F461F5EF171E1FF24F1262F2BE29D480530F6A2B6BC9F2912F120A625AED2D +A05870E2 +1D433A94D55FA93BBCBE7F94C0 +E09E6D9F0E7487EAAA6D1F1194E04328533781A0241D6135977FB47331851A4BB51F3264A73A25D3D67AD054EBC23B4C4AB004AC9C8DDC64AA891E34A7FE64B8D91367A9F79D3318EBCE306FCDCDA3F213A7BA +3ADEE87D +61DB37D6B3E5046C5C877C6E2E6A +BE73AAE3949E35505D64787C1494DB68F7F4DDDFE01C7D3C14A39EB44BE449D51732E44BA4666404A9E81F3242FBEB7D171CE5A570061BC2B0C012FACBD6D98445221D1D7F2A4CD0BFA5E7F1395CF6EC33772C29F9F215630F0C6B7CF79D5B6AB20C40EFDE9FF6C84D28 +648F62B3 +5D4C44755283049B9EB1D8A2689D +237E555843E3BCD1D9EE2268D8DDAA97FB01D112179DB7EC7CE050C516FA3EE478D3C3EF5268331C4914B4B7389224203BA6B1B2C8E9D64967E9BE3345A1E6C907A446FC8F405461B6CF4DC941CEEFB29BC0E022D5C32B2B2231CCCF37A78FEF2B4A8E2DB55AFC4C39DA4E6FD1776ABD7F465524DBFDCD99D4F0EDEF2778 +877EA72A +F3154450B09FCDBA46698C6F0A94 +1885A6D4430E360F96F7D0BBFB1C7664517BEB8A88107D3A049EFD5054B6E88F9E536ECC594BE0DD3765DCF1E5E04394C7A1EF149A86591186BA937CAACEDE3D0E142E0B6FF12FDE09F6B46E1D79B35013011F3A19EB7DCFF4DBCB2844AA2CE263C5F5803442F2B753EB3B79AF8A31DA56D0F1137AD5DDE02EA76F0A5726 +3077 +1B93B0 +8B7FB824 +01452404EBDE9DFF3B94CF0C76 +69ED9E36CEFC3E86624548C9908378BEC9CD99B67A0D18040321F3A125C92FD9863D5E92DE72A7DE25DAD297BE5450EF9E3CCDAE6FB7D808AF68577B964AD4B0862BCE5BFFDD24A6020B8DDAE12C55EC36 +B4C90D62 +D4A4186A7226CD9BDB0CC79F2AE5 +A178E37FE5A799B8F1C19ABB6F8B2D068C42843B2A81946A70996265CB30E388F7AA035589D0E8075AD62FC0EBC72B3D6F9609D4583D8D95A9EEB7F02C8863971C32C755EE5CDF8567B4201253ACEDE4C482487E3056643CC119FBFA08FD4AA7299433D2 +AAE38412 +E67DDA63B88904651D047C364EB8 +747A414FC82DAF516FC1BD0820767436DBF198D0A279B4D249E07E79839D8370AEA39F5F42D179BBD36F87C991FAC011A4383433251869370FCAF12E525EC457F0B920C14930FC464343088F1DBA71B512AF46001E5DA1DD89FE7A61E04F3516E47FA4FEEA345DCEF36A73A357581E5B0604D93628A17B441F7107F0E78D +7E3C +85E38C859E8F824487C73717B8B72EB9 +8CB270EA +C0FAC216B94153EE7FFD07008ABC +73E686EE20B4CBB33A7018FA6D06299C0080D520A8E97CB4EF407145944EFA8567EAF227DD9D7F04E696A3022A968464FA1DC4F5AF8747EB1C290038CDD25257E6CAE8C42395FADF4705C76266B53D65F98C48DB80CCC8392835D9A79500E6ED9EC75693F17C52C912DEAEDD3726C4DBE8A01758D43977CC08106EDC88A8 +A0DB +9D2D7FE3EE3994A68E1F9F4573B6CC10D21B4F714C8346CB0674016BCD5812ADAE4D08AAC2F7CA +9D1A992A +02699E779516114732E0922A3C +733FB9D4DF1F45B0498DCE65E2A80EEA4406E3998F28 +D9EFF0F6 +2B6774B6DB009E9CA3CFE5B796DD +F007696650C17FA6205FC83D91DB20BC7FEA9F642999395DF88FDA40EB5B673FB6C8321CC842D78559B972087410613C0F15467B2FAF6FA034FB25E4AEC8667B15AE1B7131519AC71137423B40445127D6AA7E188B9A6403FB6888C5C6CC21EAE26DA422E5961E752CFFC83C4DB7A9A3A8D95EA68D4D4281B758166C186E +1504 +267245 +61A83A65 +F12A61136B5D4A794DC46BDA6A +AC096894075643C8B19BA978542B8E1FB6B932D5939A2DEB27F025512811F067727200E716A360DF2CF227DAA7DD1271793AAAF4557038AFBFC6D33787D3BAF1D42B7400DC8EC48E7826E64DCB1BFB6268DADF92ADBFC10D +77AC7BFA +13784776BADFD5F9E5ECDD3E91 +D91C57D8F9E497B7ED5A945258FF68711542DFE758623072463C2D1BD31FE6B1D57E67421639FE970B33A558C04B21AEAB3063B2BF0A11C593FC0AC4E75EC4AA2DECC991EF0BE773BC0123A34AE69E5F5BBD +169AA286 +09A53CE275BDD044EB3DB15409AB +90833C95C22830B130BB85D74B08FE73B222B9336F0044321977225629734CAF1D628E9311AC3387652BA8AE541B91BD4AD3857D164DB9097051A1D5FACA7010C4B26E1CBDB708881E48427D957685BE35F965986ABCB296A3B575E6C9B7D8417407B7D0184CBDD24CFF69C263A5 +A89D8E21 +E4D743CE0E4609FC00813CAC93 +DCFD9043CB83921DF1C3B7208DA83F8E237A15EAF3133265D9D53E93C6DEB830C0F5E4E9C149D4710088C546831AC97A8444A6316A5A75222D3861E9CAD0CC3BB6981962CE0F2671951CA6BEEE8F35D2E48A94C677B133F92E +30EB410C +959B3DA3674B0173162FA95022 +8EFD70BF2757F0F451FABE2DBF6227CA7B27FB4C4C1666DF0AADA25B41A8D64B80553FFFE03B5053E0BEAAC802B2B65B1616A354BB1ABB0A0D96FD7C8E0189E657A958ECE89B910EA9EFC98C6225D23A7F093E569F9F1D0E8F5740CB +2EB1F8EC +0029A89148B2C86302C48065871D +95F47905EE4FE48D0D12C8D5FDB5D08F96C1323F3E64263BB75641F25C0C7C59C6D45D3681876B3D0900C679A73B17FAE33667889C65B46C667509E5841AF6CE021A7F9897CFDA8F5F67386C4CB2522A09264DA34FC180BD6C9B7F6C5279A0E1B532406519AEB3BD737087D8256DECB668B935E169460A87463B922DFD65 +A4D0 +A3DB6139D22C2BB897E64C3FA9F5522B396BFF7161A1C6FF9F8BEF5175FDD148C8DF3006EA109B64A8A0EC267BFCB0 +879B3A68 +59D79FB10F5F38C7E5CA8065322D +9AAE2D5531B152B1D7508864571A3D5EB2327B28CB067668F0811D12877C6EDCF80AE2D28A2167808ECD425FA8ACB1AC8452AA242B01F73956743CD364CACFEC6195F471EC7D4DF7C2DC01B60DE4E4D676136384F59797FB07BE9900641E228EF2888A170785613C46CAC6FD5E +AD5E0F79 +5E64EB75DD978D86FDAA6FA28A +2B5FB96594B710DD614C8B29FE4D56C15651CCE4C1A82A65B9F898ADB3C96DFF77317CA16D2E610514E94F7187FC04149A1544D8FCD598FD9A3A2966FB658FD857D92615E22C9FA53F444C6A7715609A +334F0AFD +94B8299C33B506FE279923CF5592 +0502D0BCEC9011A6402C8D41D886FCCDE479D1955F0555654AC3326674ED9E47739A4E7418E3D729B6254E46EA0BAEC9CD802A3A12DDE8CCC5203858135A8EF5E63C2498932951BA09EE13A7A6BBD7DA9709634903D2BB5569EBFCF22726838F3C36D87C9442A1358D704B160059AE123E8098B7BC1E5E4F39A6B2D0FAC7 +13D1 +42C5091EA9AD6D29A51FEEF5B9CA04333CDDE3B8BE61A8CD79EFC08E3A7FBFE99618C0 +0D21B14A +3B3E8CC61DB4782F778AA9E226 +9D0AF9518FBBE789A41A3370E3EC7A3EFB7900560AF7C1F766423F24AB92D7DEB430AB42CFDCF856E145FB6955444BB48849A71961EF +48E348C8 +D79C83088A30FEF735CBA4E23C0F +133241F0F276311787667C0D3DA874396D58FEDACBF420CE857DDBEA00B9999BDC9EB9F01ECD1DBB75BDEC2A3E038B1A19AA3651AE420A8D009869F1F2E6F9E61D2CB2069E6475F30F78918F50146557767E9EF0BF4326CFAF4A22DE44915C8CF4076BF1EE0B5586501EAA638069FBFEE6B5F401C37527991A5BBD40A409 +111A +6D130BDEC1CCE07458C87DC10B3F7A2CFC9BAFB44047E4C0671A5B901C5B22 +40B5CC2A +4791FCF6158662AA3D1C57850F48 +A5E0F29976E6A99F661A036088F16780F5B33DB9D4ECA7DB0684CA466F567A88CE6F4DD6A90EB875E83842BE328099075A59F4FD19C0D2FD48A7DCE783FE7514AD9638CAD5C40D6E3EDDAA4519A4A6DEF087F4C3CF68B02AB12DCE4D810987C6FBEAD3E1E91B96EDCB996227 +FFE3C149 +802F1F0EE7751E4D3353373840 +5E9B7AB63DE45B9A633BD0F732D647EFADC8888FDF95D6F050115B19636E132F0BE35CCB13E191F0D6B732C3493B13EC3551DF0226E4E69AC35494F1292A1D88449D032A5E7D +3464DAAB +44370C5F33497AC946340FB5A961 +2F74AC68DCEBC0894898AA8410F41156C0035CE6CCD7521FE63D8F6277B31AE70B9DF546BF433BE7DE5972EAAA90F03E0CDA8B59C78531D2323D6B8E650995378F53CB3853813A949C90D6D123EB5F9E5EFDE705507FF52BEB60BC6A85C5BE125F6463846B9C60DD91EB954842F4FD4C048E94432BFAE3 +3E93CD8E +0C2C448411923B664F41AD48691C +2A47DF054F1F7A8340ACD34BAC6253C1833154FEF7CC0AA7C5CBE846DD1BCC5C655ACBB8C0C7781C42E14BC0D08835EC8879A696E50982E47CA2EC707D8609CE1982160ED38BFD89CE8925970B4024CE30225658E34877387A1574A78DD73491475A64D7B55AB58F7045 +EAD505F6 +A70ACC66F6C3006F47B6AC7F41 +EEDA416BA95018FC819D70E7119FAD63806A505537DC736E6EEE1D636C521CC4D916973DB7B34729FEBD994AB7F9C58D5195DC5370E1F3C92E274C179E11BFD18C6355D27D84CDA22BDD8FCA651151127460BEE98AEE54 +767F7CDA +D1C2675DE0D6B56E13F35F89455E +6E32D6DD0139389B2013F55740A0C0C93D257A70506639555E642262D3EF03C25EE6C960D0E23AB7222A04D79C8689073632032D0B6EF330202773D873BC04DDCC31C2E91881256698A8B99B3C152F2F5996C1E034D51C154BE8099058517F3E2402933B79AEDE49FF336CB15D37E9DBA36E6490A2236E5D938EC069 +E9FAFA0E +7B730F95433B042A2DA0F85893 +CCA9C6D183B96665AC14EB10A649B082AF542E6294497159C44F9819C4E2701BF67120978E60EA381A8DCA51FB76D6F0658D8D801335BEE43AB38D1C0D7BD315BF693EBE6B +AC934CD3 +64B3974A8567E59573D5B36C3A +D33E1B3190816165169C8F26DAF574B2A6A6D95B824E634F8AAD18268D11233E9D8FA93580B3E962E39618F5B4BF30E14FE9B3705DFA6147177F75862531F30AF4B08EF588063487DB349E0E71B112DE1FB122696A3E5A74B63E5AEC9A70CAA10D4C +224C91E8 +E66CF750D6A1507B919865887D +4EF8AA7A98247B26CDD0112CC027D17F92FE12D01EC6D0985084D6B910C5BEC3A3603061B0E217404642683BDD9D1398721E16B74AF2B0C8FC592605425F430248C82A78956B31518F1F0E5EE361EE89A2686EE37C245321D4 +5444A764 +BAAF34691FA02B8BF11A61AE3D35 +108D69FE80811B185E8CEC76C682C267DE9A8A306DDB8799BBE0464DF3A3804528BBAD374A58A326063BE03F1B30BD9202C1B103AC1ACB0EE85167CBCB81B62E2DAFA8E17AD7268864A92BCFE0870C8C63922D8A176F48C56749744C547FA72924F8429BF1A11D23AEB28D389B739B57B629539692F5E08C0D676EDB5870 +B5A5 +BD73B0284A82594AF4B04A42C011 +91238A5F +06E0A53A1001AFB2BEEC94DA0BC7 +3701373BCBC5690EBBE0626236FBAEEDB0777DCBCF9DAE34761D9BC5525259D0CFAFD1D19385DED5DF114BEE67F31726346C4BBF3F442C6300D0401E663C093735CAE27E11FE4A34785E09A8B00AA4C9E407D38D2B31BAA3B62CDE908FBBA933E2C3AF7878B7004B33A6250EE424CFBA0ECB919743B38ACD5C18D75196CC +70A4 +8D90BA0F19DF50E91B500CA1ED6D9C65235AE3B411E4901011 +ED365546 +36B37A5BDDDE66F967D51C2D1749 +DC634574FC2C9A6CDFB6744EEE4510A5ED7F8B2EA6BD62C87E23EDFF25ABCF829561345F927729A7F39250ABDD5020AD9722DBBCC5BB69F030F469D5634BD7C4C8A47B20C6F98E3A2432B001C84371475ABB4C8EA51FE1B0AEBDFA964B8753001F876B81F75AAA3E819C8289960648009A007E68CA98F99748E0E8A55585 +71C9 +37731221 +7F0F1D60D43464AC6F9756F119 +7D8B120ED43ADAD5C7B8165DC399A631CB0DBEE6AA195B1C6909E7611BCD3BD1F71CC42D3E1E094A48211044AE2E30D43BD046D07C8FD6936476F6E385A5A6 +BE7FDBB2 +AE583201F6E84CC1BCD5193878 +AF0D3EE7E8A2FFB21E3E1E6AAD9706C7A0244964FC07 +02F7D31E +F1D8A2F44BB06661B3B7EA6C706C +3433977E40EE6751 +CE1AAA21 +5419E604F28D9E19F89403E5DEE028749AAC82B63D2AB0582CD8F60E91C08D7DB082 +D13780ADBD61B74FD56F00B7A3B45AC68296AC2F3D8BBF6A0E0F79337862EEEF0C3C7F726773 +C50751300485350EBD0E928EC16C0FB1A5772444ACCF56C86D643A +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +%Defining font PSOwstdutchb +%!FontType1-1.0: PSOwstdutchb +10 dict begin +/FontName /PSOwstdutchb def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001000 0 0 0.001000 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 1 /C0032 put +dup 2 /C0045 put +dup 3 /C0047 put +dup 4 /C0058 put +dup 5 /C0067 put +dup 6 /C0068 put +dup 7 /C0069 put +dup 8 /C0072 put +dup 9 /C0073 put +dup 10 /C0076 put +dup 11 /C0078 put +dup 12 /C0079 put +dup 13 /C0080 put +dup 14 /C0082 put +dup 15 /C0084 put +dup 16 /C0097 put +dup 17 /C0099 put +dup 18 /C0100 put +dup 19 /C0101 put +dup 20 /C0102 put +dup 21 /C0105 put +dup 22 /C0108 put +dup 23 /C0109 put +dup 24 /C0110 put +dup 25 /C0111 put +dup 26 /C0112 put +dup 27 /C0113 put +dup 28 /C0114 put +dup 29 /C0115 put +dup 30 /C0116 put +dup 31 /C0117 put +readonly def +/FontBBox [-18 -207 798 694] readonly def +currentdict end +currentfile eexec +D9D66F633B846A989B9974B0179FC6CC445BC7C8A959A39A32E9DCE7FAEF17EE3BEC9F +50E1A6FCA651FC4B3769A0A91041557502E25A5D6180FE25A3D11BF079E1DF66E54EE9B7C229AF891739707A2A0EC140306B5E43E52B79BFB89E459E50 +6EC6F610A70775A31C460976C4F79449D86E57ACE491E5C6BF20CC4307B1DAF7630252 +E9AF8CFB69B50EDAE9D36A6104AFEF8832F920FD2346B2C7104CD11E3BEE999CFA9F5A +49DB3173EE48D1C82994237F360407B022E0B4 +502E94EA8B493651EF2D03F0B513D655047568325B512AE6 +6AC6F53F3848CF70DE25481CC65D8B1A5793AA +3C4282D111112BEE28AFCA7A3808D4444C4669CA +84EAAAF989219F51AB3476A1B0B5F2246BC306E6 +625C6679C417ED2A8E9BD010DE37D40265074C2684274F521011A4FAB2239CC4C91F3E8514A0B1 +D56D6AC921B6CB9A95B5862C +96EA1243D6ADB73380 +FBA81AD5 +E671873831753B062D54870AC3 +7B86DA813713423C616B752F5B478535EA51AB336BF262 +0C12A9B7 +403688BEE1DF831990D942C145 +C2204CFCA477A2FAC1D6FFE48FB95A72E07E007A65A551329FB6 +E5CEBCA4 +21AA703D56FA9FAFC5608660AD +B1585D757C69A9EE103F01E2132F3737A9D187F0AF5A534303F5DAF1811F42120ED37E37F991F2C317DD6B92A06AFA1799FE91B6647A +427E8C13 +CF60AE48B5D903CCC2A571E90243 +3EFBF02E0CAF3725E0447BF9116C5E8796E814AB8CD1D60F5EAD1CB6DA3F72AD1453D6A3B7FC37AA9F3C1F673C557CF175AB19DFF8F452F21DB9C2391C109FFE647F7C72542C4EBE73286F582056F2ACA45770FDC609415CBADCD01BED4DBE47CA0C9E3EC29BF07B +981F45F3 +0285EC0D9156FBAB8E4AEB40D6 +8457BC8DA71322B792B7BF4DF72AAD0C9345756144DBD263BEFC4B0459BC36FAC365B2CD2F6DBCA6D1FF1FE49440C52CB0B278480204707FDCD84B2EAED85852BCC34A45C21FE958A0E4AE303C55CB735D322CEFF5A9D3 +A150332B +052343C0B15B7ADE5334A5217D77 +295DE5EADD586D73C511A9CEA8DC02ECFCEE966FF3D5738719490C6E1E636CE0D33E3D8481420CF1E07FBD6BCFE69F321B0320114C92FED2B69A83AD5C1E5C31D667EDB7E54112B35162235CFCED5CA6D5BB7140C151B873E3CA8E0BD78038A90AE89FA31532A8920E38A36BD94E +201B2094 +1534C53E83D40769D38884D515C0 +D9BC826E558A2C9DE8BB6CC1A442524685E3FB5B5847273D8105A38FEFEC19B0A02707F9E4C433A8EF9A570EEE4B97429CD7064C51CAAC67A8D831708E1ADD02F1DA86DEE0CEACF2A84303A0AADB3C0CF91AA4852BCCF2D1CB645091946FA7F6172339B08B85F1EFA5734509AAF6F2AC352F1C3703FF6C +B5E84E5A +EFAED557567D0267EDE57C27B1 +DAB7F691C64104213BEF6884CF749D2A5D81697FAC66784BFDA32A6AEBEC2B1145B4E3410C705735B95FF488873A43A269877CD9A4B1BE4E6423AE16E4C3 +6702414E +04D095B4FA98DEA2200FB1758B +AC67E1429D4432F6C35E05B6A4A71C1ED8572C91510466D1A29EE19B40D69791E68852149629E2FA3E0D78D7BB6E9391211DFCA50049C534AB15ECDBC32BEDB04F9818F5DA86A43E2D +F2D05F6A +259BE50B43E0671E33C148B5A0 +52196AB02B9C9F419DB2656FDEBC17FFC788076895DFF67274E565091383104A257B9AC93C94636CEEAEDE3535B76CAAAE6DBBBD40D0566AD927B54066D980B0BB3C52675FD8DBF1D80B14DC2CB2303FCE51096CB03BEBF5024F18990D12B0 +BC221E67 +F07479593189ADE9A16B4B33575A +0CE6AC3E83412C4B0B63DFF024434F447D14255F2C6192E1CB8190688E70EF481D9AEDBBD7DF6D8A81927B5F3B28A86F1A1968C5285FC1545E1119AE6D284FEC3B6F6D46B6983E96B0D46EF8F74E045FE35777ACC44B43353FE3E5E3EF249FA9660C6F6DC39F68D442 +2D0959A4 +EE9EC51DB6A0FC55D2715A2E1EE8 +BB1E27177438DD60E3E377A4D6431D9ED50A8A80BF3FD0993B955D5B58776EF2C396840E74E98EDE772C00B63FDE9DDA57A0DBF55CBCD5BE6B570336895F76F9644917DBD61ABDC3F77F5F0D02D3D744832FB984E09519AC3507F71FDCB645F72D1C2E5F +C806DC2C +E55AE10907EF4E1981F9AEAAC3B3 +A5CC1C97ED939AF65F2E7901837F50137410A2252134B1917D0A982C73A0B1BA01AC5DDB2CAE58C8FE3E21C63123C08217961688177D5F4FB9CD9E394A2A35F19B73CB93F374A414BE297D3B65C109FDE7D6324DE7C5E8CC8CFADFFC8C29DD2B1A6B2450F1E05E7517C58B2CEA5849E9EDD88258A6 +BA7CC75C +DE0F396300BD31A8D10F801D02 +ED63B52C30F8950108F68D50FC6B61DA08091F8FAE3BB0EE5296E3440B83AB3FBE6206611088FFCA655C416B591B943552A0FF21B373D95A37467F2F710B7423E69E56F9863AB531AF +57B3CBB0 +5ECC61E58A49E53DDFD7721D1A90 +B7633CB2B60D790C1DA7DC3CD3CE2E0C921A1D7BCD5DC115466B37FFFC5232258C32FC75399C7CF9F2BCB98CEA9CEE29EB9072DE0D5C1103065B8C8B7696F9BD454FA97868D380141B360C36CACAFAF7526FBB397280E4750AF1F622B15C849AAAFBC322D6EF679741B0E59E6F0CBC447CE0E6DE3F8D25BC5A533ED7B808 +FDD6 +06F59323 +B8048AE4 +35BECB1490B923B008857B543B +C64BE31F6BD6DD83D137A2D2B9FFAD978C71E127FB1537BA9B1D8899A90D5368D436DBADBEB262878477721EC22C0A9586F1BD79FEC593BFE4A91A751A7E479D4C804807EE388BE1125C42168C9025122551 +794668CC +4518D428B7D97024AA588D01FBDE +FF342863578E237868D84B5D3D64FA22680EB15EDDEAF12A493F31C920F9796E69D60957D6D3A92B24EBE50E7F64641FC47A9ECBBA8971F09E7E4684279E66657D5E6CF9627DC42AC45660820A234CA4FB756F6A24C977291888B5DE984767268CE6147CD44D351F07CBE35C +2EED4D3C +18D3B6C894B6BFD179A87CECE1 +76E0CA07AB5CD238C929D028DE3DA48AE51062855D73CB821800EF36D9F1DC1723C9D666104C8415D4F372D459CDB6CEF15FCF3B6D0E4E9B6BD5A59AB56DBB65C84128418E0B5F4E3ECEB39778E716561EE8565E500EE8214848A29E +D8B0D21F +D5B3A2B33BA5E492A036700139 +BD2029D04CF4085E99326329602E7368051AD6DF7C7D7A49A592D2AC428C24402CE4763F31C343204F34287FCC1E80CCEC70CBD7AB62A874A772459FE8B4D95BE4DE530919EAF38C9AD0C25B44AE7BFAE7D9FC6707555A13E6A6D54439 +7BA1A056 +8872B3079471D4FD5A63A32415 +FDAB363111A88F1295647272DF78DF3925662852850D9B1736A56014A860D9E7EFC70B9F31B5DF7EE43CE6208AABF7EA1367130CA3E0F33E90E26B7BE015AB83E05933380C5F1D06F59A06C1B9C8 +B67ECD40 +FB6BDE86FF584E354F393E5301 +39BE17DBC7914E32634046FC2FDA354E080D71D82E307303B05AA60C557558C62CDEE3C7ECCACA2084B6DCBA67C4F12CAAD5C185 +53E812F0 +0EA8A76CABDA2E4269192D221E3D +64D048CE9944E0E0982EAF136F5952C1AE12A867507FAD6A9598DD02DCE4F2DE4B58839F56F2429FA8881CA1B5741CA96035A508A5AB762E2E8A19FEAF3BFE451250AFF73866F8F5D9DB994157C32169F0B61FA310FA4A73FF7EFC38F5587BAC2633E40E47CF33EBB589888FCF347958EC6F9C77D909DDBFEAAC1288B1D9 +50EF +63578D5009A6BE83A3E5030FDBA00566AB43757143557794C83B4FEA +472CFA34 +80FFF3ED3CF2A86BB9BF8A957D3D +AE33E425466FB6857D0901674B63A76D8BE1F45133B32B4FAF3B4AC5FEE5442BE5E90BA09F0FEFDB05CF6C89F65D0AC7EB838B7F83E89933C98D69534935BC13694FD4F1F913D13026FC5EFC55AB857A50543605F2D2F466DA12732F1869938FB8AC5793A58F2A +AD0FF498 +971C86316C897445D2CAAB514D +DC66C696C1A12CDB0D9BE0ED28CB1715116968084306B8ED49089D7E617227FD24A75C2EDAF9891FEB2339EE8551B325547BE71C855294CF728F5E90B3E3F408A5D62658F927 +8C66C64B +497E7BACC3DD569DC6B65E061447 +87070E2C69C3D4B049BF15F5B97F3FC1054E70D1DE751435931E65D2301478C03897EA35A580AE40C99F9F785DF2F34D55AA0A83D5C754154B9AC858288B10D4F7B833E035CD6A5021246A3903262F5F7BCF35F5AF5D80FF1DA27BF36E1F7BB193E4C650AA7BA972BEBAE2D998D6214058 +12E8AEA2 +D794B8A8C3C2B86A532A967E4FD4 +1CDD60D646CB018472D5D7013E2784C29520695B82C0153FA9CC34BE2120556607D08BBAF356623DBB3F4FC8640748F39CF9DCD5B03A6F5B0A1D9FBD68A94E9A926F3CCDF5B62103554B8BB1022CB16CB6515C375200583C3BA1657AC45C61A0F455D7096E9AA0E823 +B22C5B33 +1B863C2F9C343BF088BD9484F2 +D6B94F12496CAE0996C48A7387B419BC8E5431F420A3ABE74963EA458EA7B0D06F71AAC8DA48634E5E8FD09E2DE39006D23A79829CA0C4BA7E9B200E26108B026B668C885F22AA536B1761702F2B173BD0E8B6B87CD9B3A33B +D9074A2D +3CB4100C726289DBC27EE08722DC +E6A5762E10FFB511A0B39FC078257A7D2877952B8BE0DC5F5D7954BD17921BAC7F5422CD91384A5190AD104FC0F461F00E0DF9D3F2FE08844BE820AC3EC46360BCFFE524AEC8E9D25943C91C828D5DE9D7EE50F6B67ECF3BE09614FAD0A8EEE42D52C9429084D6D7DD289BBB8080878CD741D8985FD970B903 +64662081 +84C8636DCE03DA57A4A8A77C34 +3B645717B710DB9244221D6CDB1FAB33D7F203F50EEA2194274441CDB13E7A79F44BC9D676DA0ED2A4185D00ED06F045AE042C03E88352F44E9FB1F42ADEF00C7425FBFB +4602F8BA +D9C48012968A9D5E93BFF01FB5 +C81D72065353F4462E7FC31391866D12BBF96F7E336BD7241C7F86BABAA4CA275812C2DD21BDAD2610571050A56FB84E341391CB80978F8358F6105B775CD1963E056062AAF6E88BBB03FD264878162535C30413F544BD2B1948C2 +630DD042 +1B403A8CB5CC16A7C0ADCDD0A541 +C7C798C89207192B +66111E05 +4E5F6D1A2ABE1761BAE99487FA6C4EFB6ECFA6BF69DAA56109D4BB8BEE44B059E0D2 +D09AC4B8C21214DFD92C47EFFA5E3BA6D7148A8C277809964F9F4B07E7F07303BA776D458E37 +8119142BB32E91C4F51C2297941BF9D275BF1A505A30D096ED664A +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +%Defining font PSOwstdutchi +%!FontType1-1.0: PSOwstdutchi +10 dict begin +/FontName /PSOwstdutchi def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001000 0 0 0.001000 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 1 /C0097 put +dup 2 /C0099 put +dup 3 /C0100 put +dup 4 /C0101 put +dup 5 /C0104 put +dup 6 /C0105 put +dup 7 /C0108 put +dup 8 /C0109 put +dup 9 /C0111 put +dup 10 /C0112 put +dup 11 /C0114 put +dup 12 /C0115 put +dup 13 /C0116 put +dup 14 /C0117 put +dup 15 /C0118 put +dup 16 /C0122 put +readonly def +/FontBBox [-144 -227 757 728] readonly def +currentdict end +currentfile eexec +D9D66F633B846A989B9974B0179FC6CC445BC7C8A959A39A32E9DCE7FAEF17EE3BEC9F +50E1A6FCA651FC4B3769A0A91041557502E25A5D6180FE25A3D11BF079E1DF66E54EE9B7C229AF891739707A2A0EC140306B5E43E52B79BFB89E459E50 +6EC6F610A70775A31C460976C4F79449D86E57ACE491E5C6BF20CC4307B1DAF7630252 +E9AF8CFB69B50EDAE9D36A6104AFEF8832F920FD2346B2C7104CD11E3BEE999CFA9F5A +49DB3173EE48D1C82994237F360407B022E0B4 +502E94EA8B493651EF2D03F0B513D655047568325B512AE6 +6AC6F53F3848CF70DE25481CC65D8B1A5793AA +3C4282D111112BEE28AFCA7A3808D4444C4669CA +84EAAAF989219F51AB3476A1B0B5F2246BC306E6 +625C6679C417ED2A8E9BD010DE37D40265074C268425D7C73E0D9FBC2C51FC5D7A4C8466A0ACF3 +EF6A51E85881893F5F8BC8430208 +87F3103F7721E137FA1F5E0AA668B92FD52279E66C1F88E225F1D00525B03625600EEE9AA0F3BC774875C78C8DA3485F17675C49575996A73AFCDFC5C043FF15240F2766D360B295D9F35757882F20231CD23D4B1D44649FAC2F946C5244A22F62F98DC8900497DB880EE30BEC4BE3011C108BB1603FC9E45087B4C3F7B4 +380E +DB7BEDDFD810BFE55A51FA92E7 +C5E02760 +2FEA6E1C7BC816B379B9BB690B +3F1F8D5D13B2FA0CA13B32E231AD6701F85E724E73EE5CAB752A1F01924E57EC33256147A9D15C2BED13E5B9868E463D0CF97CF79520D198EF7E9A4E8433615D43ADB42E79570068860AF8163DFA32E1F1AA9D84A0589C316A75510753214517 +65B024EA +2CAE33DEAFE2FCFEC055BCC6E807 +8A53B445D923820C0B3C3B775BFA1858B494A3E1ED579B4B7021B2747CA7DB9BA810D03C123860AF732D6CEC7A174E5ADB2DF2C48459B7DA91099B9EA4DFD27060070047B8FED57852BA56F0C75B09D95315841A1D637002612F731AF8EE4047DED5D8E53BA552BEEF5D79070B6CAC2B68F8C835BBE415D9474FE29393F9 +AFB7 +3168F8BACEE4F753E5374F9DD54F816F2FB16569CBDFFE6BEF28AFFBA96E6D1D41790B9AD5A71AC47EBBF08AFD654A41 +BBB9B934 +32CD3EA43C3D75650A026F94EE07 +8C9CD2519EF572156B2F34DEB76DC76BA9B2709A6DD78C558978CDC791BF43681BB7AE9328BAA7B284BEE5A7454C72A5CF2C9BDE94805A59FF843BE51CCDBFE69C9361EC6C491C18FA2616C75B772E614F13C38B3A7CAE3986D2B142CDDD1DA052556B0B80 +CD009F6A +B2638750700D66D0AA5810213141 +AC008781F399DF1A8043DBAEBAFC2B4AB596DA1071F3D505655C8C9E80FD9A1E0FB5F70DB8A227FC5D87E25B5985462D2E4DD446F8872432FA4BF7889A6B81AAC9CB8B818141C4D237D7DB1FC5D51A559CD13C935BF1AE639E261B83427841B5641084F6F43D44CB7DD60A0FF47E94CA86D71FC6EEF3AC18930CE91B00C9 +BD70 +67198EF0F55953DD826A0C981C7193E5CB53591FD92D5E3EE4FA3E +90B8AFD3 +BD7D1A65145E62B247484DBEFD7F +9A354A8CB2B1916981F3B04C446E91F9D7890C99E768D9FC4EA626D698A0A3099937CE0E16D26D38BFC8AF24914C1CAE2967D79EFDE69EF86E23739B46BE7C837D9D30688FD3748649FBF68082FA4D71603F483B057FA6DE45EF31154B6259F3B633EFB3D6A3573B473EBA1F01DF2CEDB0267012DC453BA300 +C113799C +D73D058FD325CCDFF91C7ECFC0ED +F5C1A835FADD3A33F90C6D40BE35C4C44C1E74A06BA5C213AC3C32207333F41924B722B467C4A262257C21398E3C5E1ECA06D9A0009E669507070150690D999B4B9DED64DEA22AA62FCCB06D0CFFF30CD6A3F21685F8AF43382540C00024B76FB86C21BD8F +14B44FEE +D45309CB76638A360CC3C52C3768 +33CC9C07A2C94C292258711A2E2684BD770223EE87E8E51500E66C413C885DD8F7B591D616E035D0A4D2422B02A87ACA35910E20483353B8AED8FD027ED84DADC927F04AC5FE290B2411BABE9819A1B5455C4675C02D586FBC946DC0D8C0D4565D47A4BA1E01767AC01BC99D380E26EAEF2811140DA4BCB2B6CDC145E023 +5577 +40C8C53F6C1D23B66FB4C547785165511FE75EFF5DF08E3A890D269542C74E76DCDB27338F578F7749E1BC5649B49C35D6EB07D8B2206582EF4DA5C871AFF0DC73D364F571B9C1A55CAD69 +A3C897FF +6AF3F0EFA51F761CEB5A096396 +CA62ADD641BBEB7F15BF71EE60A0769746359E6ED502D86221686F5387FAD1C99FC79EC3B67D26DE4791AB7C2E3A878F100DEDC77079DE9354CAEE593159DC4804840B346C0B63AF3042A8F55ED2CDD681AE02A5645E4271908645E64434C8 +6EC1FA94 +81224B594D324EEC22B18CF2FFEC +C694D26DA4B01EAC17E81BD0A1201B0733F1A238069CE685B61AB7C0372DF527FE13E9C4F02FA4A2A7BE9F63068EBB5852C9FB7C0B0DC480699AE2B9577DC4353799D0287CD9A5E6A09A0A725F591EB131ACD72F98D79199B7B3B42CFA5E54F1E7DB1F92EA4D6055FCF627C4E2CE90046A8E4C38E997457959AF4C53165E +AA0C +1EEFE42B3AF218C199BF1B97FF9F9B6EB63253BC3554E8CA2B39F2CDD331E73CD77F84039348851032E7 +26E8CCA2 +F9D4AB9099648F165944AD02EE +83A494FAD10601FCF54C0665F0B4787B56E8F0AD22D814EBB6554B622A30AC57E466AB4681F5678DC5E63C7C447C0ECD2B7078507E91BCF725CEF508D6C40E89FD8A2669DDAFC1EFD2A0D52434A82440516C391B57AB169A0D3527 +274A5949 +BECC37B7C4A95529BB33F2C0EA8E +279DC6700EDE0CE850A9177C6E851D01D67B1FAA0EE446FE947B16A24B99C1C2E8D8141337D7056995F4BA9D1246551587AAEF5E8FEA8C8127BBDDA6294ABA6B37B4DB63D93BEDAA30FC12BD50129A0A83BF32440C7F4816C47972ADA35D3DCAC651190BA1931004E7771C93F43764148B1D6BA2FDA7 +8365AAC2 +164D07464A95C1C11288EC1863 +53B9C4B298E49C0950C8F52058CAEF1A34199F853B79DE7E0710E4B12497BF156F813B0521E72F699358CFBD14A9D56C8DC8CF5F56D6DA181E1FE4D6496D24297BEBA81CDF42F498C0228919A0DBC51C868639925F9E16 +013CD527 +52A6337053FC8E0C4D5869B29620 +BEBF01FDE1279BBAFBB9C95FF68EA78975E9CFCC5B55F1ABA4222C5F9F36DC17938A29C73B252193AF33E547898A38A6AD3BA1A61A56D7D853FE2DF429F84C3C67F96ABF21C9E897860BE9F978622A51B39B0B107EBBA0326E008170847B38B385B268AF5D03A11D589D4922948261BA452EC10963E2D51821EBA7D02BFA +EF36 +2D3AA90B6951C967A9C9887E747B2531CFAB39692475A4 +E0E0F454 +CC4B89ED9F742F955470A0DB6B +C7D12AE114BBE7B26E1A897C731703C2E46EF5BD927835056BAE681AEEDF072723394C9A1AC2F9CCDDA88B272880F39F9C7A940970AB9F77C713C4000BCF101E5AF761BFB9775DD76A4AC0E96712C684B25F90A64F68F8C92EF0 +67ED835E +3E4E375067FCA6B11A129AB7631B +321258285A91BA87CCB93A9829342162FCC2285E018016AD1A28294BFA357E8F71874312FD97EA3A42D1314BC9233A28F681BCE856D7B7749A11EEEF73B6FEF343AD2894E7E5050C32CF8DAF35DE551706C4E06564A939C3E67CE3B16E9B3B21A2290FE047B156F96428C8205B42A95C5F83B862637443F3E50B6BC49ACC +F0A1 +42E8E1B688AD6CBC4F +BA5D4B3E +C7943FA2DDB74F93D3DDF6B53340 +8F3D7332672DE15B +E7E183BB +D8F2F7B41E4363FF42244CE829AA73CC4A79D33F2B9F0839F89E36E300DB4857F052 +1F35DD3F5FA2BD1EC4A1C8F4951F797EF2C0B2C82418278D87FBBF498D2D2FABF87CA6FDAC99 +58624E435E800292174BD0EA60CDB71B326C73EF7AAE32FDF27D51 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +%Defining font PSOsymclas +%!FontType1-1.0: PSOsymclas +10 dict begin +/FontName /PSOsymclas def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001000 0 0 0.001000 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 1 /C0069 put +readonly def +/FontBBox [106 45 775 713] readonly def +currentdict end +currentfile eexec +D9D66F633B846A989B9974B0179FC6CC445BC7C8A959A39A32E9DCE7FAEF17EE3BEC9F +50E1A6FCA651FC4B3769A0A91041557502E25A5D6180FE25A3D11BF079E1DF66E54EE9B7C229AF891739707A2A0EC140306B5E43E52B79BFB89E459E50 +6EC6F610A70775A31C460976C4F79449D86E57ACE491E5C6BF20CC4307B1DAF7630252 +E9AF8CFB69B50EDAE9D36A6104AFEF8832F920FD2346B2C7104CD11E3BEE999CFA9F5A +49DB3173EE48D1C82994237F360407B022E0B4 +502E94EA8B493651EF2D03F0B513D655047568325B512AE6 +6AC6F53F3848CF70DE25481CC65D8B1A5793AA +3C4282D111112BEE28AFCA7A3808D4444C4669CA +84EAAAF989219F51AB3476A1B0B5F2246BC306E6 +625C6679C417ED2A8E9BD010DE37D40265074C2684268F16195489648993B9C4D3B534FA887C +DEF605FA87B991F4D20A8F78DACE +5A54C070E03D5C59D9D2D3E06B09CEE028D68B62AB3AEC43C1DD20BA70D288597D9BD8E06818FF764EBAB436723988E8D7CA59E16D39032516BFC5D552ACDEEC6BE938BEF2F43CFFBC811C3626C4DF5F8CF080676520B51C60CEDAD1FE6C92D1431C702174CE517A8FA9377D075A0B6833DAB101DB65397F1419EF5F0016 +004F +6F0824F9657BB4F1C8F981709956865F6855EFAE +9242AD55 +91BBBEE163D844DDA894E13190C9 +2480439E4C71CADA +BD043A9B +A315CAF72652AA7FE6DB2E84D82A6111CE4DE90C02DA0AFFE2620922262A45AB4ED0 +EEC9F4520DD12703442F7D028D4526BD8B771E09FBE11B2749E2D3906894E8D4BFD3F379F14C +3C874F550606965E22FE487B247B5C2D06728490C8F2A3B588CDFC +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +/DPIx 1270 def /DPIy 1270 def +72 DPIx div 72 DPIy div neg scale +0 -13970 translate +1.00 1.00 scale +/wst:dutch12 12.00 /PSOwstdutch newFont def +/wst:dutch12b 12.00 /PSOwstdutchb newFont def +/wst:dutch12i 12.00 /PSOwstdutchi newFont def +/wst:dutch10 10.00 /PSOwstdutch newFont def +/wst:dutch14 14.00 /PSOwstdutch newFont def +%%IncludeResource: font Helvetica +/wst:helvps10 10.00 /Helvetica /wst:helvps ILEncoding 0 declareNFont def +/sym:clas10 10.00 /PSOsymclas newFont def +%%EndPageSetup +GS +0 13978 10801 13978 10801 0 0 0 clp +wst:dutch14 SF +0.00 0.00 0.00 1.00 setcmykcolor +<182634302632270f01100111262e24292d22322b01272f32011726223335322a2e2801182634372f322b011a> 2207 558 0 7384 -1 s +<2632272f322d222e2426> 7375 558 0 8593 -1 s +wst:dutch10 SF +<0b0d> 9346 13385 0 9522 -1 s +wst:helvps10 SF +<4e6574706572663a> 1322 13267 0 1949 -1 s +<205265766973696f6e20322e313b20436f7079726967687420> 1949 13267 4 3868 32 s +sym:clas10 SF +<01> 3868 13267 0 4019 -1 s +wst:helvps10 SF +<2031393933b131393935204865776c657474b15061636b61726420436f6d70616e79> 4019 13267 3 7133 32 s +wst:dutch12 SF +<1d2926> 1271 1431 0 1631 -1 s +<00242f2d2d222e25072c2a2e26002f30342a2f2e3300272f320034292600201d15211e131a211b1b003426333400223226003429260033222d2600223300342926001e131a211b1b003426333406> 1631 1431 13 9531 0 s +<372a3429> 1271 1676 0 1657 -1 s +<0034292600272f2c2c2f372a2e28002225252a342a2f2e330f> 1657 1676 3 3837 0 s +<0720> 1589 1998 0 1929 -1 s +wst:dutch12i SF +<03040f0c0a0402> 2033 1998 0 2700 -1 s +wst:dutch12 SF +<33263400342926002c2f24222c0932262d2f342600201d15002526362a242600272a2c26002e222d260027322f2d0000> 3177 1998 9 7525 0 s +wst:dutch12i SF +<03040f0c0a0402> 7525 1998 0 8192 -1 s +wst:dutch12 SF +<08> 8192 1998 0 8245 -1 s +<1d2926003226313526333400222e2500322633302f2e332600332a3a263300372a2c2c002326003429260023352727263200332a3a263300302f3334262500342f0033262e2500222e2500322624262a362608> 1271 2320 14 8636 0 s +wst:dutch12b SF +<060a0d09000519181813111e151918000c1c1513181e1312000e> 1271 2748 3 3946 0 s +<131b1f131d1e030e> 3942 2748 0 4734 -1 s +<131d1a19181d13000d> 4730 2748 1 5630 0 s +<131c14191c1710181113> 5622 2748 0 6664 -1 s +<0b0c0f07> 1271 3128 0 1866 -1 s +<04> 1870 3128 0 1928 -1 s +<00> 1928 3128 1 1962 0 s +wst:dutch12 SF +<0013161a1500342633343300223226002e2f3400242f2d302a2c2625002a2e342f002e2634302632270023390025262722352c340800152700392f3500372a332900342f> 1962 3128 13 7735 0 s +<002d2622333532260034292600302632272f32> 7735 3128 3 9461 0 s +<3b> 9461 3128 0 9531 -1 s +<2d222e2426> 1271 3373 0 1864 -1 s +<002f270013161a150600392f35002d353334003226242f2d302a2c26002e26343026322700222e25002e263433263236263200372a342900071313192113161a1500222525262500342f00342926> 1864 3373 13 9531 0 s +<2d222b26272a2c2608> 1271 3618 0 2109 -1 s +<100013161a1500122f2e2e2624342a2f2e0019322a262e342625001b> 1271 3940 4 4194 0 s +<263135263334091b> 4186 3940 0 4998 -1 s +<2633302f2e3326> 4990 3940 0 5710 -1 s +<0034263334000413161219211b1b05002c2f2f2b33002d352429003429260033222d26002233> 5710 3940 7 9531 0 s +<222e39> 1271 4185 0 1587 -1 s +<002f34292632> 1587 4185 1 2106 0 s +<003226313526333409322633302f2e332600342633340800153400302632272f322d330022003226313526333409322633302f2e33260034263334002f36263200220032262c2a22232c2600242f2e2e2624342a2f2e08> 2106 4185 11 9531 0 s +<1033> 1271 4429 0 1515 -1 s +<00372a342900342926002f342926320013161a1500342633343306003429263226> 1515 4429 6 4428 0 s +<002a33002e2f003326282d262e3422342a2f2e00222e25003226223333262d232c390600332f00222c2c003226313526333400222e25092f32> 4428 4429 9 9531 0 s +<322633302f2e3326> 1271 4674 0 2072 -1 s +<00332a3a2633002d353334002326002c263333003429222e002f3200263135222c00342f00342926002c2a2e2b00171d1e08> 2072 4674 11 6541 0 s +<1000332a2d302c260013161219211b1b0034263334002a2e362f2422342a2f2e00372f352c25002c2f2f2b00332f2d2634292a2e28002c2a2b260034292a330f> 1271 4996 9 7431 0 s +<02> 1398 5318 0 1504 -1 s +wst:dutch12b SF +<0003191a1e0318131e1a131c140318131e1a131c1400020800> 1504 5318 3 3785 0 s +wst:dutch12i SF +<0b0408090d0405090c0d> 3785 5318 0 4744 -1 s +wst:dutch12b SF +<00021e00> 4744 5318 2 5099 0 s +wst:dutch12 SF +<13161219211b1b> 5099 5318 0 6160 -1 s +<142632260022322600332f2d26002f27003429260013161a1507333026242a272a2400242f2d2d222e25002c2a2e26002f30342a2f2e330f> 1271 5640 8 6731 0 s +<0713> 1589 5962 0 1937 -1 s +wst:dutch12i SF +<03040f0c0a0402> 2033 5962 0 2700 -1 s +wst:dutch12 SF +<333026242a2739> 3177 5962 0 3795 -1 s +<00342926002c2f24222c00222e25092f320032262d2f34260013161a15002526362a242600272a2c26002e222d26043305000427352c2c3907> 3795 5962 9 8895 0 s +<3135222c2a272a26250508> 3177 6207 0 4112 -1 s +<001c392e342238002a33003429260033222d260022330034292234002f27002200> 4112 6207 9 6914 0 s +wst:dutch12i SF +<0c0610040c0a0402> 6914 6207 0 7593 -1 s +wst:dutch12 SF +<08> 7593 6207 0 7646 -1 s +<0730> 1589 6529 0 1882 -1 s +wst:dutch12i SF +<0a0a010c0a0402> 2033 6529 0 2725 -1 s +wst:dutch12 SF +<332634> 3177 6529 0 3432 -1 s +<00342926002c2f24222c> 3432 6529 2 4266 0 s +<00222e25092f320032262d2f34260013161a15001a1a> 4266 6529 4 6506 0 s +<1004330508001c392e342238002a33003429260033222d26002233> 6479 6529 5 8895 0 s +<34292234> 3177 6774 0 3536 -1 s +<002f27002200> 3536 6774 3 3986 0 s +wst:dutch12i SF +<0c0610040c0a0402> 3986 6774 0 4665 -1 s +wst:dutch12 SF +<08> 4665 6774 0 4718 -1 s +<0732> 1589 7096 0 1847 -1 s +wst:dutch12i SF +<0c0610040c0a0402> 2033 7096 0 2712 -1 s +wst:dutch12 SF +<333026242a273900342926003226313526333400222e25092f3200322633302f2e332600332a3a263306002a2e0023393426330600272f3200342926003426333408> 3177 7096 10 8774 0 s +<0733> 1589 7418 0 1847 -1 s +wst:dutch12i SF +<0f01070e04> 2033 7418 0 2495 -1 s +wst:dutch12 SF +<333026242a2739> 3177 7418 0 3795 -1 s +<00342926000e0a0c080c001c> 3795 7418 3 4852 0 s +<101a00272f3200342926003426333408001d292a330033292f352c25002e2f3400242f2e272c2a243400372a3429> 4846 7418 8 8895 0 s +<222e39> 3177 7663 0 3493 -1 s +<002233332a282e2625001c> 3493 7663 2 4480 0 s +<101a> 4474 7663 0 4765 -1 s +<033308> 4769 7663 0 4956 -1 s +<0737> 1589 7985 0 1909 -1 s +wst:dutch12i SF +<0c0610040c0a0402> 2033 7985 0 2712 -1 s +wst:dutch12 SF +<333026242a2739> 3177 7985 0 3795 -1 s +<00342926002c2f24222c0033262e25093226243600372a2e252f3700332a3a2633002a2e002732222d263300043729263226002236222a2c> 3795 7985 9 8825 0 s +<3b> 8825 7985 0 8895 -1 s +<22232c260508> 3177 8230 0 3692 -1 s +<071f> 1589 8551 0 1975 -1 s +wst:dutch12i SF +<0c0610040c0a0402> 2033 8551 0 2712 -1 s +wst:dutch12 SF +<333026242a2739> 3177 8551 0 3795 -1 s +<003429260032262d2f34260033262e25093226243600372a2e252f3700332a3a2633002a2e002732222d263300043729263226> 3795 8551 8 8372 0 s +<002236222a2c> 8372 8551 1 8825 0 s +<3b> 8825 8551 0 8895 -1 s +<22232c260508> 3177 8796 0 3692 -1 s +wst:dutch12b SF +<060a0d09> 1271 9224 0 1776 -1 s +<000519181813111e15191816131d1d000e> 1776 9224 2 3414 0 s +<131b1f131d1e030e> 3410 9224 0 4202 -1 s +<131d1a19181d13000d> 4198 9224 1 5098 0 s +<131c14191c1710181113> 5090 9224 0 6132 -1 s +<0b0c0f07> 1271 9604 0 1866 -1 s +<04> 1870 9604 0 1928 -1 s +<00> 1928 9604 1 1962 0 s +wst:dutch12 SF +<0013161a1500342633343300223226002e2f3400242f2d302a2c2625002a2e342f002e2634302632270023390025262722352c340800152700392f3500372a332900342f> 1962 9604 13 7735 0 s +<002d2622333532260034292600302632272f32> 7735 9604 3 9461 0 s +<3b> 9461 9604 0 9531 -1 s +<2d222e2426> 1271 9849 0 1864 -1 s +<002f270013161a150600392f35002d353334003226242f2d302a2c26002e26343026322700222e25002e263433263236263200372a342900071313192113161a1500222525262500342f00342926> 1864 9849 13 9531 0 s +<2d222b26272a2c2608> 1271 10094 0 2109 -1 s +<10> 1271 10416 0 1434 -1 s +<0013161a1500122f2e2e2624342a2f2e2c263333001b> 1434 10416 3 3595 0 s +<263135263334091b> 3587 10416 0 4399 -1 s +<2633302f2e3326> 4391 10416 0 5111 -1 s +<0034263334000413161216211b1b05002c2f2f2b33002d352429003429260033222d2600223300222e39002f3429> 5111 10416 9 9461 0 s +<3b> 9461 10416 0 9531 -1 s +<2632> 1271 10661 0 1457 -1 s +<003226313526333409322633302f2e332600342633340800153400302632272f322d330022003226313526333409322633302f2e33260034263334002f362632> 1457 10661 8 7169 0 s +<00222e00352e32262c2a22232c2600242f2e2e2624342a2f2e08> 7169 10661 3 9531 0 s +<142f372636263206> 1271 10906 0 2144 -1 s +<002e263430263227> 2144 10906 1 2842 0 s +<00252f2633002e2f34002922362600222e3900332f3234002f270032263432222e332d2a33332a2f2e002d262429222e2a332d0600332f003022242b2634002c2f333300372a34290034292a33> 2842 10906 13 9531 0 s +<34263334> 1271 11150 0 1595 -1 s +<00372a2c2c00322633352c34002a2e002532222d22342a24222c2c39002c2f372632262500302632272f322d222e242600322633352c34330800103300372a3429> 1595 11150 9 7152 0 s +<00342926002f342926320013161a1500342633343306003429263226> 7152 11150 5 9531 0 s +<2a33> 1271 11395 0 1410 -1 s +<002e2f003326282d262e3422342a2f2e00222e25003226223333262d232c390600332f00222c2c003226313526333400222e25092f3200322633302f2e332600332a3a2633002d353334002326002c263333003429222e002f32> 1410 11395 15 9531 0 s +<263135222c00342f00342926002c2a2e2b00171d1e08> 1271 11640 4 3366 0 s +<1000332a2d302c260013161216211b1b0034263334002a2e362f2422342a2f2e00372f352c25002c2f2f2b00332f2d2634292a2e28002c2a2b260034292a330f> 1271 11962 9 7395 0 s +<02> 1398 12284 0 1504 -1 s +wst:dutch12b SF +<0003191a1e0318131e1a131c140318131e1a131c1400020800> 1504 12284 3 3785 0 s +wst:dutch12i SF +<0b0408090d0405090c0d> 3785 12284 0 4744 -1 s +wst:dutch12b SF +<00021e00> 4744 12284 2 5099 0 s +wst:dutch12 SF +<13161216211b1b> 5099 12284 0 6124 -1 s +<142632260022322600332f2d26002f27003429260013161a1507333026242a272a2400242f2d2d222e25002c2a2e26002f30342a2f2e330f> 1271 12606 8 6731 0 s +GR +eop +%%PageTrailer +%%PageResources: font Helvetica +%%PageProcessColors: Black +%%PageCustomColors: +%%Page: (18) 18 +%%PageResources: (atend) +%%PageProcessColors: (atend) +%%PageCustomColors: (atend) +%%BeginPageSetup +bop +%Defining font PSOwstdutch +%!FontType1-1.0: PSOwstdutch +10 dict begin +/FontName /PSOwstdutch def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001000 0 0 0.001000 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 1 /C0032 put +dup 2 /C0036 put +dup 3 /C0039 put +dup 4 /C0040 put +dup 5 /C0041 put +dup 6 /C0044 put +dup 7 /C0045 put +dup 8 /C0046 put +dup 9 /C0047 put +dup 10 /C0048 put +dup 11 /C0049 put +dup 12 /C0050 put +dup 13 /C0056 put +dup 14 /C0058 put +dup 15 /C0065 put +dup 16 /C0066 put +dup 17 /C0067 put +dup 18 /C0068 put +dup 19 /C0069 put +dup 20 /C0071 put +dup 21 /C0072 put +dup 22 /C0073 put +dup 23 /C0076 put +dup 24 /C0077 put +dup 25 /C0078 put +dup 26 /C0079 put +dup 27 /C0080 put +dup 28 /C0082 put +dup 29 /C0083 put +dup 30 /C0084 put +dup 31 /C0085 put +dup 32 /C0087 put +dup 33 /C0088 put +dup 34 /C0091 put +dup 35 /C0093 put +dup 36 /C0095 put +dup 37 /C0097 put +dup 38 /C0098 put +dup 39 /C0099 put +dup 40 /C0100 put +dup 41 /C0101 put +dup 42 /C0102 put +dup 43 /C0103 put +dup 44 /C0104 put +dup 45 /C0105 put +dup 46 /C0107 put +dup 47 /C0108 put +dup 48 /C0109 put +dup 49 /C0110 put +dup 50 /C0111 put +dup 51 /C0112 put +dup 52 /C0113 put +dup 53 /C0114 put +dup 54 /C0115 put +dup 55 /C0116 put +dup 56 /C0117 put +dup 57 /C0118 put +dup 58 /C0119 put +dup 59 /C0120 put +dup 60 /C0121 put +dup 61 /C0122 put +dup 62 /C0262 put +readonly def +/FontBBox [-25 -256 978 766] readonly def +currentdict end +currentfile eexec +D9D66F633B846A989B9974B0179FC6CC445BC7C8A959A39A32E9DCE7FAEF17EE3BEC9F +50E1A6FCA651FC4B3769A0A91041557502E25A5D6180FE25A3D11BF079E1DF66E54EE9B7C229AF891739707A2A0EC140306B5E43E52B79BFB89E459E50 +6EC6F610A70775A31C460976C4F79449D86E57ACE491E5C6BF20CC4307B1DAF7630252 +E9AF8CFB69B50EDAE9D36A6104AFEF8832F920FD2346B2C7104CD11E3BEE999CFA9F5A +49DB3173EE48D1C82994237F360407B022E0B4 +502E94EA8B493651EF2D03F0B513D655047568325B512AE6 +6AC6F53F3848CF70DE25481CC65D8B1A5793AA +3C4282D111112BEE28AFCA7A3808D4444C4669CA +84EAAAF989219F51AB3476A1B0B5F2246BC306E6 +625C6679C417ED2A8E9BD010DE37D40265074C268422460C01E0C8156E6E2E0FACCEE618170848 +BF8730DB32B5D68060473C23 +9DBA701053746F2663 +395624ED +0A9868CC80E5CE3D64E0B07CE7C9 +33BD984E0220EBABB6E4655834798CBF32C8490624606625BC058B6D324FC04CDD30A4350B9C0A246EF2309294F61BC9697CF64CD78C095FF8D28FD86F1E7636C3B5C422170552F247ABE40C98127E0D027ABD61BBD022E750339C9E2E06C4C0214ED65DB9BF61AA14F6501A52ABC49B980EB004A983C893B7097E08DDED +2989 +304F43C68B3179C6CC5C73A5 +AD60541D +5F75CF61671FC50AB5102F19D4 +C26C51B7C4F5699C33FEFDE36DA90FF31F8E7B8A3177601A1A9E070B6925BE44DE22F4793647A43484FE0235A5BCA9C6D07F1F52942699F0 +13C9631C +715BB55532FE2DC9518A313AB9 +EB6E49113EFBA04665DE3EC5C7120491CA3D8B60C9389BCE3727310442448C5BDD706CDE7AA33D64F0DBE8A655162B16353ED0C1A761EF2E50B9543CB18224F5 +94A95225 +7D044E30E433BC441D2393058E +A872F7D617FC24F3350733FDDBC51EB81B15788BE24E9A02DE08318175637F7A029098C0FD0AB7F043386B7B65FFFFD359F0D5EA60E1F800781F1F19935E00 +FBC29F11 +191B6971933D205B6E724A35D2 +B660BABC87EB5357A708B467D7B845A5CF32F0AC480FD2B8DACF61E3E57923EA0571A2EC9DDC91053EB657DDBDBAD20B12E434C21832A7CC02 +E60DFD29 +F05D5381EC851F83F1678220E8 +486A0597690456FB0048EA284F86FDB5D0E937A6C58122 +55A67911 +76438CFF3B061E5CD39BC73BE4 +B39410E9B3DFCC6872428F86D7A052CFEA5FC2B929BE275BD898EB00BFA422 +C87F2FB0 +914AB53A19685A067AF1642F97 +707FC865FD69B39B31A41F15FBEF86EE1A0A7E03B59507744B1EF03F +F9FA8832 +7D0247C61E1FF02412DDF7E2AF +A021A6B548FC509A01C12E90E921A2CE2A1DE308EC932FF2D6C05E91153953FE31C30E9FB021183C77CF73EF81209B81156F5A75D26CC2DF620A2CF928FDCA26E16E91E815568BA59E67 +0E62E7E0 +660ECE0FA7D7C1F23DF446C9FA +F0EE7EE5C53F1F39ED93B2A8A6DBD83CF3AD50C3F3D16A3AF8F3DCE619A45C9BD22E24C81A281A73C329C61CC2BEE86A3EDE102549B828D46CEFEDD243844F +F5D37305 +595F7980809322EA3C5A3CC04D +886FE80BACCC4C8961C200ED6A026A13DAA3EC258264186FB4848650A1FE83178A829B241EF91E42FA2AB70BE5AEC7FFDBC897D40FAA270AAE738DD6765F4D97277B64CA1D5B225890D8EE43FB06BA99DFA94EE2FED4CEADFC4E +18295483 +C6F37DAD8ACF9BAEC73D13F0CA0B +4157121626A858AFEF3E8804C9989806C2A4E31C5AE8D62123C0A608EBF478144A171C1440CE6053DC8B1B0022A4BE6A0909009B320E6EB21B0C3A8A188765EA1D686E848154203F41445A85D5A599872DE9BDFAFA303F161CD1EAFBB4E49DAC6B25953985E9A293C971B08059CC7D63F0555B4EF2AFBFC606F9 +878FD134 +D1DF9D997DEBD6B6D062FC5890 +998A99BF3FA088A07F6F9161F14FF80DC97E4C25DC5975B3587D82F72B2F2806F3A15BD020C5A72A6C71FA2C9249925A597C7D8A878A +A020DA53 +B1B2DC4343D19562C02894A5D3A3 +31145DE676E312BBB81A39918429D656FA89DB59702C80BB6605DDC333747E9BC6C1501A095EA1C055EF8B846032017B9EE48C098F4A7457B9790A8F50FC8C875A7D0889A9A11B3C8AEA9155E430C5BCED4C55C43A61249418718C6B100DE772DB4DEE56A5B27A05DFCD0B1A3D7A4D51D7D3E4 +FAA78132 +79CAA178F4D46FCF3E400A8CCB71 +7FCBA052A029ED4C01ED1F95AF38338B99CFCA1349B371E00CD9FEC082F0463444284C981287CA31CD50FFF0A28F3519E89E0117FEA29232503CA6409F3DD8516F1F3DECEE5F6BC5C9E57082F8BCFC915B26C3AEEE31C84574843F6DDADA3DC111EE80729D56C443BF3490D84875DB5F81A3C7A99399DC8B290A61BAB249 +AF9F +10 +D714A5F4 +4DCADF72766FE1A786BEB0D0F8 +488FE185AC0CE0D695D0D9CF6899B9E887A18389ED07829C95760D6DF4529934D33BED0EF287538A730A186B48E7A1E38BA3B5461877DC0A624ABCD0CF793A03D95BD33BCFEF61B7D0DD44E530511DB3D3EA9AF3444EB1F536329CB03F36E80A03 +8919AFF6 +ECB261C71BD77CCE0981939745 +F9D5EEEC20CF6A1405DCF47906267F691F928DA67A1CE8D426DB5C9BC17DC90D602C4F14846E51BAB8FCBF05FFDD4EEB5A75605EDA8EDDDDA8DC7B1C7BCDE7DB5ADA79D4239558111A0D869144480DED3ADB410811519EAC580C9BB8E72EC9A2BDF26D +13C73681 +27AC7BB6A718FF097CC7E5DAEDBD +08EDBCBC9190E1608B8E3EC5C8BC20F47791128F39180ECF048E462C4DF86B8AF0E3FCDFA501B246E5D3C16CD746C85ADDE0CF1D9F4813AE852DD72F04401A456478D18216E8DB9E9939060FB0696317AB9BD42EC65E48B02399AED464966184A6FE3788CCAE61E5788AF3CC0197E7EAF99B030072424092FDF1157D3816 +A39EF056 +670F4F285F000AF5A1DF279178B9 +9FD3875B7EF4BFC529AA9A9B03181ADB19B5202F060C7FA9284C9173DEF49CB82D9780BE701243FD641E247B3412D98B4B0867E99A0ED579C249B8EEF5D3951410234C7F963416EE1C6FCE90B1A632FB681C23A0FEF022D9AC68B588A8788F971A3DE6DB1A35D46D3630987B9DE936DFAFBF3F2F5B4A7434F641 +44449185 +1D7EB9E43E1DA1FDFDB996CE9A76 +4D8FB1153FF29A15A0C871B4D052147002EED23C91CEC3982F490A83477F8F0E38573AEA568B347992142A9A1E215B40BC29AF1B0DC9DAD59383D705293464A109DEB8CD626594C0CAE9FCBCEA5AC7EBB34E461DE848E77B8E3167F88D72738C003B10538E5EF8876E5CCAE96C289CA69B8816D768D117AE5119353DB9D4 +3945 +E3A86FE10909BF38217C05 +E7EA9406 +10FD721FEB0C53179F92171DBF +9964BBECA4663C86A07D826C1925A5C0023B12BE0E8B625DA72AC90A152D8CA37098628465A5C645BF3B7FF5944DB41C932379C6DAB9D45B325BC1 +A0115D64 +8CB667D8E1C1FFE24F24F711FF +571E754092B55215209327A363F77BAEB3DE56D44B11C627C4AF4DD1FACB933D4D03A4292A6EA032078A63D87BA484132386C2FE7F888AF352FC76574B846391A729DED013913A +245E3C59 +DB8868916E5551638A9D323D8B4F +F8129A8E4BD6BA68D8DB30D5C9C590F6BAFFC197CA32D7F0CC874BD767E7158000AFC3B2B4876BA67B912808C959B1A957771A56105C1C4CEBB67F986E7BCE99DD89A558121713651952F461793B1690B9956E8BA330D7E534B51D0E92A75C745BD50ADCC2870EE7791A0BDC69DCBA +0B2D2EA4 +F7D2A34A6C70AE1A57A2A7CDAD +63A0DB6DC4C52645AB16D590BC31E33E4DB48D2B3567889CCEFB41CDC879B142D14DB11004B3BD273EC37C8E9E83CE80BBFF99630114B2F70B7CEC53BC989BE37F52521CDF98813686D0E9ACBFDC00995C83C60A9962052CC43AD747 +B27C9256 +648B6280550DFE100AF184E678 +3456BFC43EC111CA8DEE7DB085B4301D961F104F439A69C5DABFA07835BEF274399829AF891F86B0717836B7140BEFD33E7D6EE6CF11C9FD1E2A441C40C3654DA3C7C8A00C4216A2BDF6DDC70499C2BF5A18DA +89879351 +87F3D10C0234012CCFA0E3C211A8 +9E16DE5BA3D6044CAFB24A8E4380FF54851DBDA545573CCD6841973C3F9E948E9FC53AB6C6DD0DEB72176DB54E4C7F21A9E7B44667629BCB6AFA8969BE98D0637CDCD9861BE57B731C949A2C31324696A3271D38ADEE04D1C3B7A4C34D8697124EC1D15E9BA04920DC29 +672F6127 +9FEC60136B8138202D6D76D7CF66 +B864BF281499901A80B27497F1DB8006E50A3099F6800F4A09B6E9BF63FF8D474D3798C3E182B8609B1EBEB8E536280865F1AE0ADB59A1424F24CFE13541B2A82E523FFE5E03F2B825C7BC4DCFEBCDA0C034E117F4E21CD09DEA56FBAAFBE9DFBB05D613B9EB50F953C8CC201C2D36122941D1CEC6E146A66013EBB56428 +CC595AB2 +86E240393E3BA76BB9E87F122A63 +5F3870491B8A4418A8A2CF9CD9244D0BBAB08DF804F7147203DCE4B3B325B76DEFF14EEDFB67AFFB489577F1D630570E62B5DFF2FC632851E4A31F91A775C7555349CAD28ED1420853424E8932A10D98D401D23DFF96A177C9336B10CCBD7E39459F54B1B33B07AE76D91E248F837127658800C941F4351D0BCD7880A6B4 +91B5 +3A85AC +7710DE62 +5BD08E09DE68FC6DFFD1AE27A1 +CB55C2F524C757289B26B537922C546B6823D7716B2E6156EAFAC3F70E170BA7688E33607293B02B0F1BA5098D54414D8A0082D8D657D5CE3F64CAFD9B4993BE9655007E2AAAED24F0BF37EE4BCBDC11A6 +D5C9FD35 +34D3B0896D5204A06A58D74CF3E5 +DAA82DA4BDD6C1E1C0F9AC9D5565DA4C724D5ACAC989CB964B22D460633BEF753BED75217D3DE2EE1C093CB45FB5E907595B943CA8721E1CAE8580C45B7E91811EC49A010AD3749138B235CF6A355EC70070B5B2BB48102500770E2D0C8C97DCA60A6373 +C5129620 +3F6F298E36B6258FE5CA082ED099 +58E703F75B144AF32F2ECD59B6962739D4242D24112456E504A2B7F8B0B28A36DA57205D235BACDC5A5503A9D20C7CC88B460E29AFC0B5F10316D37314E86C26810593CA7BBBADF4A04C0655BD5441720AFFE527214311A0A2F25E3270249EC3F3FF7314B2E5B00A734A2C911E58DCBD44A4D9B9D11A7804D094C706CB05 +8F29 +7FC70DA926142133782A2FBD47FFEA15 +E796259C +84740A4ADFDB87DBC7C571C29C58 +37FFFBADDE696AC79AF018C380252D0BCD385E9CFDA82BC82DEA0A06C7AB3AF8F068FC1065E8B9C22CA9F76D17A9BEBC393699E73F8F8D660408AF561BDCDA6CB7ACDF1F9467216DC01977A4CC03EE15F0E0E510357D5EE17C6FE1913B77552F83B9243199D7B1F164927E28136A4CC2DDF8205392DD865E175D9D19098A +4090 +7175F4879445E8F9A1E058977371DB88584A2CF5DF9E794CE2F67B288553E6F5317BCDFD4D7101 +8B899C32 +9F19FEE205DD8886A56FB7E1C0 +9ED409A3A4EA890DB1628AF5155A56CAEC310978B34C7CDCD363FA202D76EEDC91CC59218C3250DF2E5C +11AED49B +0F13E837995868427AE25FB77A +60D04DDEF4684941A8374A255983F53182420BE0F36D6DA4AE91B037CD44309B133DEB554DD2701ECD8CFEEA +365F7E94 +F8F41BABEAD8EF088DB1BDC2EA +8159A3D42B6AAA0A15A0D09BA4F99F9DCF418F3ED3DF +ABD1580D +03E0A3B6C152EAED88A5E71F9F41 +CB8BC1EADF9119A8352A7413481034C3359CF68610EC0F594592DBFEFF151C666F0C9EFBF6753ED48B4C86AFF32C0DE515741413E10590ADF71CC95F8649EB5AE3AAE7355AFECEDBE9785B510C6C6B455B1A5CFF761EFF1528D847810AA3F6C442B75A59EFDC02A9465E5AFA6072E5B468332C4F303C49222F3D7C6FA688 +C507 +7C51EA +BCA0708E +71A7FD0CDB27044F5BB913D069 +E4126743C7C419082EB3F5F31EF53A39A4E21B7F991E1408893511EAC0BD9B5C248C1F77EF7809FB1DADC628A271169BBDAD48C1E353B736E8A459C5930A1C9A32806AA642E2B24B7DA6749E46D78BE4FC24682CAFFBD4D8 +3D1C4725 +6A2CEB9CC3768CB7129C3EB567 +F2E9256799DEDBAEF5D32676011CC0F60E57904D018E37BF45633628C8462319C681C3E69F987DEE87FAFE5AEACD830AA980424F58CA6CFAA5C9E26F9A2DEC9C3E76F2C7E2D0849680B94B6C0A47F30A94D8 +FC50AE28 +FA00A99503DCFF18C802B57A0804 +C7B51094FF7A855A3668F52F143EA20D38F2DF6D0FA1BEECF21CE40480D0DA821504C5C807E66D045F8E4DCF736AEB07DE6EA78DDF5DD207CD15760FD3370C5A68173EB9508DCD455B0DD628E61DFC93B156DBA0323B54AE879F4C8D2BE2EA9FE7D5923025B3A687EF38F91C862C +CC50D795 +47EF5C4B49DA7E09861EA327F5 +E48E1F443484184106E5607CD996DB2B45FE48A0165AC5CAAE784C5457A87C8EF23C594B596D62424D91FD7CB7DD390EAB4C9C0EC296ACFBF279F84DB5A5F7DBC8D2E468628AA8C3F8D1476106DB1CB9F90654DE66070CE12D +A00A763D +99E2FEDC694388B026883665C3 +1B5361DD1664C53F1908DAA8B89D951BED0FC95AF02EF90EF447CAC4D8CB340545B95E1C30910AB586B799112F0F755B533E4134E9B5C8BB4105D650EEC29800236044264EB3578589394C1CFA97F76840959949D53545FB584F078D +B548D915 +18C42DAE549661E94DD63F2CA0FF +6BE3B8CC9D1C5697A0618E21F70D78675F308EC8559DC92D1FBFA478587528F51A677BFA814420182872AE0F015B2B512004E31209795AEC58A8E98C846A4FAE59DB23E842086ED164F36885100BBC5C23C79B045AA7CFCB043835C4696BBB1061DB36109E9B2360DFC04EF6640701B4FA3724493A1BEC1AA7C8E445219B +B244 +07C829CA3C7847C5DA364178300A134ADC97B45A0D6D8ECC181FD337EA3A384DA2A2BA72CEFCA71DC5A85023922601 +55D73BCB +BD7604B83C5608ACBB17158F1DEE +FC669CE63CCCF0D6BEFF5D074913DA79AB8A8183B4816EB098B2A6FCA799E69B848CF690DB3C6CC37749BDB47BB8788F9CFA22529C32C350F72F983DA8FBA3AFC594F37061BEEB7B0CF33DF898F2434CD4E97050B8E868FB209DB0DA80B363CC153285309E7CC829157AE769DE +B953DA4E +235EC9677B90420EA403DA58DE +056B7B0F281B35602D7D3E07F060CCCC7E47C2786508E749F6CE1C248AD74864EFDE09490DE6994E7BA57B0EDD0A77810B76B9707B0C985871D63AD869C5037C4546205FA7972D32D3010630F8C97C82 +4C118408 +BA5CFA6B977C1A8BE1D78D8E2D9E +ADF2632474A646C1B1AA217D6256BE1486EEDACD5D7F9D35FA3DAD97539354F7F73A52531CD9E18A235BDFBD4458C8FAA51F2F2E7E095F6DE1F7FFFDE7E68002D90D739B7F39F58C3AC38029C6D346D29DFFC0854E09D56F424B167BF4170ADE8CDA718D93B7D5F79DC7B7CE81CE9AECC33EC99DE2140C32EB7147C14BF2 +68FA +97E46F2AEE85C90DA7101205C715793D2EC919894752FF3863EAE6D426D9A645C8A410 +6FA9B2DF +337C4DD8E7F53F134394EA45E9 +8F210DEE0486F4D1FDF9873B619AB04C5D532147E6BDA7C903CEC01C0FA497CA9B737F8C55E3866A695BDF7F7D7AFE5D3C20FB775B57 +E1E0EBC5 +C2220537486D41621912F5BA8990 +633918F5366193F69982B4268709FA317990A016925907E455F58AEE856FD5324270AAFAA44C31B6ED203B77860AAC42430BB081AD8BD2D9C5121B249C76D3D7003174C2AE416F796F01497753C6FEA27A8F3E576F024C61435425EE5D69AF53E443548097398FEE2DD53149CF2FC4A381F150148510F88F560EDD063F76 +E787 +6C53DC41DEF43EC92C7BD51CEEBA84C44F4E0859A414E7B6F7353F84A5C99B +70C010B1 +FF1EF1B0558C829FBF7CE8F3983B +031C03D074C361D2A5184DDD73393273356EBE11A0D30D96BF04DD6E30F455463D12A92598218D5BEADA1C3CB97C529A4D87771A0F4B001DE1BABB1C439154EFDEA87280E814ABECC7A2CB81667F334DE57DBE9C3FF3980169ED684374751B3C7F6C540CF2EB5E71286C0C8A +15271875 +37707C6825F9657F7F24C0489B +E85952A6D72F6A20259C89633FE62183C8CFB98B25FBF11900D780AD424728AADDD4D2F6427AD49FD0EF289329CAFD754B45BA4560AB77E20D41C11C2762A0B1678ABFC1AECB +09829993 +E85B91DD48D497E78D038B3BB3E8 +C7295B7709BCB90B3A67E5329C8CD4FECA2995361E246D9D3D2CF47B5153CD6F92FA8EA93E0633CEA1CBF313A5C626B4DBE55C35A73DBE3E8EDB29D701E70845BB91904F55523F78436FDAEC2C95B99D46E5B6155FBD6EA291F64B477BAE50234F5AE72CD74B1DAE536BB1A1999180E03B7C40C6128E69 +647935A3 +B47E3B4DBC1CA9751755DB8E3B0C +01C6D75391D426E38C455E73C3092F3A7018597EC6D565E4FCDA4001AF92B6C757039968D01AF7439C27FDC27E7A95F7847EA2EC3C113A44BE338E40F74A48A56BDB6B22263E2AF5CA7D48E0DD063CA054CBADEC254EA3531332A5B7C363BAE9FFF53DFF7D1E1308195F +4D07CF80 +DB9B4D290939EA21EC965DD763 +1276D516F81679EE067DFD92DEB345FDE54AEBDF2CD92F4F146D4E0DDFCF4396A3D52814330205559241AC7EC0473CC57F61D9CEA775F7841E1827901F950346B1395F9C258535094BF34E84F17C556AF92DD9C2B4CBDD +32943C4F +EC484F6E264F1BD6063B248BC9EF +074637CBA33BE27E624E692345410B16EBE35A01D9A6DD8A48E7D4F813661C57CE603CD996D31D576BF139A7877E91D575AF3ADD2FAB8EDB6D997E79BEABCE5BCBFDA687D396C6C9829DC59E52A08EC7E3ED2A1940688DE23CFB2DC1E113D297CEF442FD66F99715FF5178E9FE5C0F1BA08B8C7A495372A37934391C +875ADFBD +4D2D526CEB814EF589010A0816 +EEBCF04F20FF0DDBE5B9B4C36B1408DE18D7C714749904B97FC754670D832BC1764F25FEAFED83CD171D6B5199A517E241D20C73AA14E0EDDAAA5FDAFCFCCAAF9813348DE2 +F4071F2B +5E223D2808BC0A0E1A829F413D +BF6B1AF53018F2A8B523853D4E279758DAB5EC54BC477D0FF7BFB37404570B3D8CD97873DB36F875473BD03DC35AC2D41AB489B815F9ECADA09384D3CD434C6AFEF2FE3AD2F41D3C1246C0883B13F35BD563B9897789A145958C35B9D66DBA01C67E +104F10E0 +1BBFB4728E86079F966A452BDA +7CE29D9E74D284B4AFE7D2A43AC9952E3D15211BD53D8EE8E2E1EDD4E0B3CCAF7E6DAC3F63E4236481EAB8ACD3B81F76B38AC5984690617B6095BBDFBA4E3A920813EE3AC07FF015F0C349F0BEB8F479D412371C254E4EE7B8 +F556B2EC +C2289A7499131140ED20DF8321C3 +65A5104F638B0A17C8F33A40709943CC962FD5482C2E74353188FCE643C51D878BB2C9480D2BEAD2A9A766DBEDF031A2A9112E851C2D8E9B2A33464652EB2E7448FD1BF764271E5BA326F14CB82990D685FC63EEB0640C772C72C53374D1A2C095D9A7E05F7EE0195176B983A22825BCBBDC81010B0E0EAE58FDFCCF58DD +C630 +51D4A3BDEEBB4141F9F3243BFE05 +A9177648 +AF61CC94E167138D55C43E3F6BA6 +E1C44B5145104225ED930617AF30CE5610349E6B860BF589E6D529536CBC3C518BD1D2F45301E6595AF41EED0749280D146221A44702CFF059AB3FCCA58243EE329975431C22A2FCEA53754EEFED1D309AE49C3021F8A412DAEA51457EA26039833DD836D8A4ECDEDCB5DB471CC805991A4D43CA93F545834DA56FBDD53E +96F7 +B463C77892B2FF88D016CF6AA5CDF6890089E384A28DB33382 +6FEE1834 +A1B836DAD3A790826A0DEC532870 +FD72E53219D52D2B15F064785C79C6B256154A91F2362704CE8FF279F9CFD3C057B95C3317B39032570A4B5341220A9B9E3B8B5EF2F50D7E0F26701CD932CE5DDBD4C6F9027FDD94238EC5F5DE2B8341E34AC3F5D604595CB7F642E0F8AAC0450196A0A4A7F0854DE37F48E01D6FF8893F5E8B329157047F55FA54C76B9D +0333 +467D9A8C +CAF4E5B41E715BA0DF98F3C5BD +A4BB1658078D67D110A1412DAEA06D4665C1CDBF11490E1F28AA48868C17AB3A35AE0F7C5D8EF200B3133503022BD812A3F9EB11DB6426BDD78CF2F9EF2466 +769102C0 +680FB0AF5DAD7E541355F0BD5F +FC7BF430FA0DFF50B61148F0E481CC377D66B5F236C9 +CB2ED359 +8563997733C23571B836EE86E39D +4C8DFA8F4DE38133 +FC3044FA +AAFA388FE9548E2D7421F5B410BB852779A6975E979AEE1240602369DD993F939F9D +FE862B2ACCD7289C72EE97CA2FF66F73F5A012DE956E44F4532C872B53544C2AAFC8B62D49AF +39B2D87F011B64174DD47CBEFDEBFF65C4DDDF6F2EDF21D896D034 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +%Defining font PSOwstdutchb +%!FontType1-1.0: PSOwstdutchb +10 dict begin +/FontName /PSOwstdutchb def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001000 0 0 0.001000 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 1 /C0032 put +dup 2 /C0045 put +dup 3 /C0047 put +dup 4 /C0058 put +dup 5 /C0068 put +dup 6 /C0069 put +dup 7 /C0078 put +dup 8 /C0079 put +dup 9 /C0080 put +dup 10 /C0082 put +dup 11 /C0083 put +dup 12 /C0084 put +dup 13 /C0085 put +dup 14 /C0097 put +dup 15 /C0099 put +dup 16 /C0101 put +dup 17 /C0102 put +dup 18 /C0103 put +dup 19 /C0105 put +dup 20 /C0107 put +dup 21 /C0109 put +dup 22 /C0110 put +dup 23 /C0111 put +dup 24 /C0112 put +dup 25 /C0113 put +dup 26 /C0114 put +dup 27 /C0115 put +dup 28 /C0116 put +dup 29 /C0117 put +dup 30 /C0120 put +readonly def +/FontBBox [-18 -209 798 694] readonly def +currentdict end +currentfile eexec +D9D66F633B846A989B9974B0179FC6CC445BC7C8A959A39A32E9DCE7FAEF17EE3BEC9F +50E1A6FCA651FC4B3769A0A91041557502E25A5D6180FE25A3D11BF079E1DF66E54EE9B7C229AF891739707A2A0EC140306B5E43E52B79BFB89E459E50 +6EC6F610A70775A31C460976C4F79449D86E57ACE491E5C6BF20CC4307B1DAF7630252 +E9AF8CFB69B50EDAE9D36A6104AFEF8832F920FD2346B2C7104CD11E3BEE999CFA9F5A +49DB3173EE48D1C82994237F360407B022E0B4 +502E94EA8B493651EF2D03F0B513D655047568325B512AE6 +6AC6F53F3848CF70DE25481CC65D8B1A5793AA +3C4282D111112BEE28AFCA7A3808D4444C4669CA +84EAAAF989219F51AB3476A1B0B5F2246BC306E6 +625C6679C417ED2A8E9BD010DE37D40265074C2684274C264E5F45F0286BD1B23D26C34626E07A +5B039DB36C18005EE32CFA64 +906B285CB8BD7F0968 +D47F5242 +22DA29BB63EA29AC1293D9F365 +FDD092686CF0D739DAE7B4EBECDFE21B8B5810B15B35D7 +8B1BDB66 +02B6ED886A79CAF56DC024BBCB +DDA25190FAFC3423DD681C3456E9771478F53A927D941FB6FF23 +3A389AFB +19EB903569976D828D6FC92E4D +81CB772312A082E95658CE400A5984BC94F3ECBA3EE65FEBFFF80B70E92F7B12DDA18F85A7AC9012DFDB1083E3382B57A6DBDC3EB44A +46059E4D +CDC2611CD3BDE911CA720511E9 +754F3D3EC252B5100BBEFE27ED66D78EFAC9E2F8EDD1B0004ADDB7B9636727A3CAC0EEA93419FED31A98BFFA489AEAAC363DEDF1B76F144A67EE75A5513CF2389C8FEF63FBA013FA4C0031F652F6E79FB3C3AC82DAA5D7 +C8C3E6FB +56A3FB382750258490CCEC10C2B1 +21966B6802313BF57958F3823AA13B3DF98AADBA255BDAF1979987DFA0F0C26FA9020AE3641C98B121EF209E823946A97943BC6438EFA11D708E56A2D54B7A5C0DB9452839B276CFB3CE834E0AA4F0BEE722BBA93CA3C8E782C7243E4FA56CB2726865FCD3430DC933A2A5D6EB2A +0DD1BC6F +0204FB17DD8DFCF0A4006AB74F +8BD0EC643F4B8E2F12F16EC08B8F88D61C6902946F11E294A9092249FFDAFD5B60E84FDF89B038FA957B4255F22095FEF3B9CBDABB4E425BE9F10BCF057D5C0790F5B67AFA3A834920120DFCB7DB66F76EBA2A4E71276EE2D8D0347176E1C9 +50BCADAF +10AE8F2667DE928010E06E6A1613 +1CA22ABA488BC1757785A3B1E66E316F1327B6A29FE7F91CC6A16AA6EA9CF801C2EBAA7D5B6D947D74CD0A53D2E17DCEA20C45765C936F0649A06F358A7775F7CD2CE15B7091CEABF6A13BF3A66B36EF5CC0AEE6BD656B87BE285203E8575AA9A51E2A71A88283E78B +E82FBA7D +3A4A780BC80B5BADB50CE8A6CDAE +9F7EB8AD51F214E5316434B068C490E240F849BDD5431CCFB12CDDC916E1EB2E45599D2258443CF8EDE115C14234E477860D4BA0F73F439A66FFC8385A4C6821C7D6B2E7A8CF0DF848BE1B4C5170E4D31DA48215D7E9F01549C4F23DB41D5312C9E51AD6 +1AD34EA9 +ABCFD1B92C4D4F11098C617DEDFC +0E407756C44D3D86F46A1181DD96D7FCAB528ADE0AB35AD143D46B9C0AFB887C0F4612C60ECE4BD507ED9C09F8B9C90AE41FE3F7ADB32176CDBEA9D60C93D941AB90D53FE883AD4DF48073EB3396D6578680850E349E533C47A846C2A233CE6F952BE9313D1333DC836AB64152111145D370685FB3 +CFC74CCC +98E17CE86F65F3F766EAA547A5C2 +9288C62820B3D2D41E187147903304C5CE9A1885AA8498AACBA3D991845493F71B438646E81D66340348AF5170CCB068AE34D98A607C53628E2C964DC72B3A41871D46E62831CECCCDA1B87A59665341F15038398AB8508045C79F75C6EF3E9D05BAB641587C59464AC6C5FA6FC80935AA1467A758AFD67644F83317F6C7 +3052 +E442B115 +D50C03181DAED59E84E96BDC5D +82872E305A439B5BF8A0F8574BE5D847AF2CBE746878DAAE2E2BB6590B5B78BCDFD079A292AC3CDAD706055BEA0936476FDBDA2931A736BAB0C06C2D920F0F30BB28BAC9328B55EF95 +041EF03F +BF244C4F123533616FE000F1D9DD +0E0ACD847EB34B3155A21B829C16D6CA00DCACA9F1F0C3C56B45C69E5CBE596EBEA6549D66FCAAA59F752A12720B4E634B4E5E39D6A3A31F0AC62743FDE2493D76DE36AE3335122383D9214FAFD4BEB3F5B07F9ECB996A808E04DD3EDB00BACE472A54220507BB +A8E5806B +8032595AE15DE225ABA7DD76EAC1 +477D781D7DBE2A526C2F5C99EE1111D91C1728B3577706D883DE7DA4874CDD164F096D79CFF031E6907C6CDA7728BEE98A88CDFE4CA7F99F1ACBEE361F6770539493E105CDE632173FA38D13371D3B00FF7D338FCA4A6B691DE0417D9FC6E5BB4BE7A66E7764DDF16C240149DEF59CC3A486C1EE830FCB1630EA433A3FFA +0C90 +85099C8D +D7828885 +18111CA72E94B1DB028317B975 +E878DD5C3A799050F4FBCB89FF2950BBDD9E728BB997C99AF1C61A85056621604769CD3951EF110630BDD8037F6CA660CD63B82F331B5A9ECBA2F389E104C951617B730A18073DEFA3A81FE5000E758084AF +FC73A2A0 +D7953914901F930F189D677552 +B91A9CF7EC6BE40BA5B86218AB21BF2107C1ECB608A9308B4240E1F7A24AB9B5371155B0B65C99D3DCDFBDE0237E5E91B61E1BFF5A5D0E3CBB502D14B5BA89041BA134E76ECE5EE3C4ADFD4C7C075D5914629C06D1B0668B2577E4BD +93FDC1F8 +8C8FB3279F6A18AA6D271326A2 +E7B313EB922E8C66E13A37E8CC4D72B0FA6255D9115D4268D33865BBECD531CE6772D319007D51E18FDA17CDE31AF60223169F72D9076E2DBF5F0847141F8303B89BE0D1799EF9355D60845E5BE0091C1C9E59E0007EB6E50FDFB7269F +F2845860 +B7FA1F673BB72AA5A657ED2C599B +423AC51B8F5F8403CEDCC1F02FB75B7FF9A41DE2EA84E323E789B74AEA2EEFD592B0750B4C0B8DD715A7D200F84382227468E6A11C7F894785F92E2E416DA546A966A158BB18A0E744D923BB378909F1242B8CD3BE9AE307A936C4EDA52EE974D4040108B5AA81208AA04F581FC2A87BFB86C7D9447472F29391779FD76B +EEC7 +47D06BBE7206F75697B2551E5824426E24F10F64CC5FAE888FAC56C7246B946A9F9EE51F91 +53683D72 +D4CCE7692A0FEA4E30F7EAF14E +D4DE5B88E2BD62B671A62E4CB2D6232623B3110952895DEB26BA567B87102AD7761AAADCF9D45B7C010CBAA651DE4849ADD17F8B3B5B16FED5CB7D3FE3038CA89ADD4DB186169FFAA689B576D663 +FD7873FB +841E3F91C229EF7A32C814E65B20 +68CC4034E3623715126F2AE86442445BFB8C0F6CF2C92EBAED993DD5D390B768E201F9FE663549E481822EC7408A7497B4781879B817FDD5BCB7D606412D99BD21B6643D69DFE093B54A4670655EE6532312868EA4B52AEA7FBD4AB8BC2F68BA3FB1FE77CEE0F4A09854EE881610F3C90940A2F578FA26867CDD9664B9D4 +DA60 +FADD +C942EC53 +65DAB8EFE5D3B1603372C47A257E +BC1FA6B4A3F6033F2FFBBBB974970079E9F50E0F491BED34489433402ECD32989C20C5D24C0DFEAC7CEB739C983FFE8EB03B7B430CF7A5599AD261A5589552A188ED8A8C7BD98A26882F711980DD7E9044285378CBA89C8B82305327296B75078603BB9A05E7C9CDA48B6B25896A4914A9DCC5A6D8F912D8FE819DD07D3D +60B0 +3411A287359B6B6BE31FF4E531048A4AAF4C4CEDA4B313BD8AA168D1 +DD81A69F +8D6BEEA782611D8D3DBE20176667 +500E58788C1FADB7A9DAEC99045DB89BBC362A9AF192B3252D5BD6388CEBE3A09F584996EDE85D51BAB86BDA2CC96E1A8DF4FB74E928A0A59B4135C1F4E58D154AA162F92C3E5E5D6122DB2B1E60F5C2F0CD17C4BD9CE358E3A7267DCB39F0A1E7AA99A38F1ADE +939A8592 +8962D3C33A76700E5FBE25F472 +9E57EE064908481448037B5F3B99BABE0D4298A57687B5A001D8DEF3B12DE659654BA2C497A9C39C21343734E15BEA112E779E5A3C2F5E657E8573D87CFB3C87B8772C25C0E0 +5756C119 +CD31C7D23C4207EF82588199D0EE +B9742EB0580970E03BB44BDCDFF0E89E394E29B28576509CDEEA3EDACCBFF830DEB01ED2F709573463CEB9A05C38A0D54FB91525768B1F169C0935C4A5D5E77EDBBBB61F3097011276811D9968622C04055536A03F5A0C5B301E14B76C3995DF02821A0EB26F2315706626855E31209FA7 +71F1AB1F +407B8D9BBC7123FC1587AE6DA5D7 +599098211999D094434F800F922EB0B4B838A9AB5C1DA9EA06A4C8AC4C6182E4E8D87C564F8EDC8D49A99C7D3F020B2264129C25C3DBEFE89499B222AB9769CB85223CF5B83766EA464490E5B86C618857BED74DC593BC37C598314F01A5B14578AD10EFCC767BD565 +C1D1A4F4 +4C4BA3960B2029953A0743F0E8 +7CF2BAE8A5D6B5765FA67065C5848AC95C26C095919D7CF39CDF3BAF3F33A55C7EB62824E27A04D024B695BB396F67E52ABDF40179203E0780B9AF0375867786E6F3325569EC6BEFC4FB6D411B18ABEFD96B9B2AC892F833B8 +1B140F86 +69516074D97EB145D9D17FBC1E64 +70FBE00F342EA4017B437FC98A46A82E4F3EBE4BF7E9406776611BA1C5FE7D2D89C30291966AEE7E9144FBC734C383BEFC7FF9E31198E9703E5A3FD73B9CEAA840244F952FF4B41460DC39C78BB4DC1A3A5E36C589C8F6E7231B33F04E5819B43811AE3528E1A339BFB765911D27CA09552C584E64D00B5D57 +CAB1115E +BAA63CE5CC1F764314F8DAF17D +45D9824F4DE2409539C8B64EBCF3075AD791D625264061367077205E2276F865767394F415702A1B98CE669E7EFDA3BDF4EB5343EE70F8C3B8F356D446FB87EB2DEAFCAA +0D0444E8 +F1A5941E1E358A7851B302DA74 +7B08208D77EA73FC565E99A1DB94D9F0E11A29F63680BD0948F12975D04B1CA6BD7B303F3C5B9354FC64BACDB1A5DD7D52E3B5E2D1D9A4DFE0A5637F152D722FE623200C6390523819DE49DF57FA283CB07AEBA1D1EBA0CB62E350 +732F94E5 +1BE8887F07799825D98DB2085054 +38142BBF85F1965A1CF7EF632EC17498C81B698AEC250A3EC98BB9106871AC58C6A689E1F135C278B6D96429ECDACAC8E4708B1652FDA85F8FE56788CB045B16F479C16A8C4D926FFB94059D54B144B6DA5B72CD9EDAB21C955B594B451A03780016000C1048991FA398D4EAD38676EE3CE1592A4551B93CBFC00EACFB18 +9414 +64A68AB058AE0759A9237532D897D5F0212B1678799C +9252CE51 +BF37465B275CDD3BEEA504CD8096 +16BE434225556FB8 +5CF4A9EB +C658C8C9B57CE5C91C50BCC657ABB2196A3F6F4524E065B2F2D2EC5106CDBC47A355 +07A06D716F499735BDD7256D2701ECED4A7E212E0E03DCC25D2A83E7BD00E0A8F71CDFC9B5B1 +F763E2FB1B5D927D0396B1864CE70D465FFFCDB8BEA057AA161A65 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +%Defining font PSOwstdutchi +%!FontType1-1.0: PSOwstdutchi +10 dict begin +/FontName /PSOwstdutchi def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001000 0 0 0.001000 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 1 /C0097 put +dup 2 /C0099 put +dup 3 /C0100 put +dup 4 /C0101 put +dup 5 /C0105 put +dup 6 /C0108 put +dup 7 /C0112 put +dup 8 /C0114 put +dup 9 /C0115 put +dup 10 /C0117 put +dup 11 /C0118 put +dup 12 /C0122 put +readonly def +/FontBBox [-144 -227 513 728] readonly def +currentdict end +currentfile eexec +D9D66F633B846A989B9974B0179FC6CC445BC7C8A959A39A32E9DCE7FAEF17EE3BEC9F +50E1A6FCA651FC4B3769A0A91041557502E25A5D6180FE25A3D11BF079E1DF66E54EE9B7C229AF891739707A2A0EC140306B5E43E52B79BFB89E459E50 +6EC6F610A70775A31C460976C4F79449D86E57ACE491E5C6BF20CC4307B1DAF7630252 +E9AF8CFB69B50EDAE9D36A6104AFEF8832F920FD2346B2C7104CD11E3BEE999CFA9F5A +49DB3173EE48D1C82994237F360407B022E0B4 +502E94EA8B493651EF2D03F0B513D655047568325B512AE6 +6AC6F53F3848CF70DE25481CC65D8B1A5793AA +3C4282D111112BEE28AFCA7A3808D4444C4669CA +84EAAAF989219F51AB3476A1B0B5F2246BC306E6 +625C6679C417ED2A8E9BD010DE37D40265074C268425D38D48EC7466FFEBA5C7142506D78DF24F +060B3D6F22F43C1605F7E610CEE0 +821C68FB13C01DCAB5D07ED3C9CA63CA4581AEE2EFDA66E4F9CBF723BB2C2673F2B11B7D38F02CC9F9A2C6025D8E959DFA89E9EA116A6AE1B47510D60570DEB71EE01F57DA8765EA6503F97F935E60A71E32AC94455B0EC0E65CA33F394477EDCB36A8E71070AB03C6DC21B89D580BBD51193BBBAE3DA6B767ADA66EF889 +A4B0 +F4D4CA8F7F808E66AE66AEB842 +06E2C14E +2BCF8BDA455D135FA82C81845D +E64C387FBB5DC0824E803571D4BAD4983C55C9B9C16EBB89BDA0CBEB648F02BFB0778CFABF59255975374030831E0055E4F8068875E953D8FAF8D32643FC8CAC16DA4F5DB515F675F1809B0B76C64C18F81417F8582E6B543D0A1BFE7A02B169 +00A88C47 +34AFEA5A92FECC14AC93C3B35853 +7D4D860FC0836A48D3770FDDC48D85F4DD624A95362F64A568EBBA4A127F9EB054F1759C4DC7256FCF470FCFE74B794CCF62359A11D5630E22D79AC4F98F34DD8FB549C504CA9E401891F3D95D7D5DCB4585E8450714A6A0CA2FE7B7728E9F125215E51E591F3A68A8889ACD1DA57F13FA466577873A009802BA7AB076AD +8560 +FAE23309E6FF404FA1585DBF6AF8CD0E0CFE39E344D9255E016858FA654467B7D42D1DE4ECBFF98B8C717BDD5ABA7C59 +B475C574 +4D209E659E9B5E366D041A3144CA +A1C4F19CB0023291FEA07365F07CF7738D0AC14DD6436FC6F663075C1CDFD5146A80F4D957DADA7EFF03136161F0A79B59CB4DFB02FAFB580788DAEB7EFBA0CC7F33981F9E13E0205DED63007C617D87AEC422BFE7085F18F8DD419EAF49E4F915F984D96B +CDB93259 +DAD462AE15670BA4F64F891D65AB +0E87927B961BABC2ECE37D681C6DF5C3E4B1F7386FD77B1090DD3588A6470303531F67608D92C8F7BB7BF16FE6E25BBA14B081F0C4912302770008ED3FE26D869D5718EA356031E6D37C4317FE704931F22401EE21E66F4BCD03B253DAF492F1E53EB5DC96CD54BBD9E141285A834D867E453DB9BE063FA3B1 +2D74D564 +E138D2A61EBDC31A1E861CEDEFB4 +941ACB640A72FB436C6D0210B0B491D1A083BF079DE47EEB82E3FC37B1F87168F13AB56BC4680FC5762C50B979B3DAE6C5CC91A2E5DB4F7366F09F510789D648FEEB6844E5EA7ABA57D7470E43D632B49DC47B2709B00A9A5911B2EE72D810F415DB25EFC5 +B35F5298 +F7C857DC0A9D01690311360B4D3E +D785EC76C6F6D5B3C716E1060B8CD5283ABB1C437C5A3ABCD48B31D93F9426B01F9680D57054B179C5420FA65A53FA2CDD572E1F9F8B366DFB91D1A722EE31E49B54F7404DCD4E381D167B3C8F35ED9A38F1B2441968D7956339F35CAB79D9591CA038577D5A8437072B147E14DE4786D4AEDA03AE56EB5EEB65C5AF19AC +71C0 +6A6980D6796C034FD5220781D694EEEFAEE2B52D5C362BA61548EF86D24D2F1F43C1489BF7249051DF5A +DD44F25B +4B0E35A6A7AC1BA699BE673E1D +7C76577E47CFE52988087C8B909757CDBA53637740AFEEEC3EFD95CBB63DEF39239B53D245EC7443519F9807EE54C76E3B010EB49F5EBB64529EDAF433130ADA45A229E3B32162AF317B14E40CAEA319DC0B56467DBE0C5630FA6E +4D8AF23C +0CE4644E9B2AF0823F2FD580DFDF +477821A9F078DFB8D17F61F80F4BE7658B9A6ABD0E198622FD862D0334F216BC7522AB29136EA62870E8F09AD786865DE2D309C113C453E8B51E5FFC50D560C80955F4C4A34DF47EA1CF5F5F88338EC0CE802B9ECAF81E70DA5DC48A9C62AE59C807A45637E12E4F398E011E670919AC8D3DFE37F03B +38EDF238 +9A31D413DB2BF7F5F84F7668B9D7 +1129FCD5BD108EA1E835D7C1715061ACEB45BDA632C0CAF9E5FDF65F16015FAE4D7F78A76DCA2BF357BA802F9E8C00E0516C0B2FAA3133BA1E8749765C1CCDF061ACCC56B86DF5E0937F6428CC95EC555A43EB999B16CD10DC628485835A334251082A78D99C5FDE1E39D51A9797389B5AF4B06B282BA42E98F3FF8C645F +F141 +B422667D981C65ADACB0E0355B51F759B3728A1E63068B +0CA42B90 +F20E1FB9EC24F448BC16381A96 +F746C29080AEA0259522E6917CBEE0303885B82170F141A431BB19C043167DFA8FF6925248EB21A1DEC82159A1C720B2EDCB71A3ED5F98E4B6431C7375E3050C86B22E7323CEEF20E39AE02108C13D0E9A4B645D2D167B22B495 +2EC0729D +9D8B405F22013D3E566CD037138B +3294CD511AA7DA0A62618ADE291928190FACF84E4279A51D19E0C8706719F33A7B154EC9F36ABDA3336740BA2187DD329354D4EC65262F8059925C075ADD54F9262D033E212183BF2C02EC0541A06AE76815E22F9B161298C5569AB74031974F223294B589E58502D080EB3A06FAD1BAC9D6BD7AC3D9AC498AB63F7C0AC5 +4BB3 +58A47FC6D4A3695B5C +E4E5C5F6 +DB7A68DEC5A750C70F5EF2579337 +B95BAC501DC9415A +1B1CFFBC +98ED8FAF7CA22B3F3E6760CC8FD2E7191702A30A8D64D30FC543F315604BE6760BD6 +01B4C2213CD7C9607CD048991841D11DABD216A2512CF4B0E43962CDEE9A1E31FE5A38712526 +CBED0843198973B3B25FB6DF65BD6344A2E8D20F440BF07B991114 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +%Defining font PSOsymclas +%!FontType1-1.0: PSOsymclas +10 dict begin +/FontName /PSOsymclas def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001000 0 0 0.001000 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 1 /C0069 put +readonly def +/FontBBox [106 45 775 713] readonly def +currentdict end +currentfile eexec +D9D66F633B846A989B9974B0179FC6CC445BC7C8A959A39A32E9DCE7FAEF17EE3BEC9F +50E1A6FCA651FC4B3769A0A91041557502E25A5D6180FE25A3D11BF079E1DF66E54EE9B7C229AF891739707A2A0EC140306B5E43E52B79BFB89E459E50 +6EC6F610A70775A31C460976C4F79449D86E57ACE491E5C6BF20CC4307B1DAF7630252 +E9AF8CFB69B50EDAE9D36A6104AFEF8832F920FD2346B2C7104CD11E3BEE999CFA9F5A +49DB3173EE48D1C82994237F360407B022E0B4 +502E94EA8B493651EF2D03F0B513D655047568325B512AE6 +6AC6F53F3848CF70DE25481CC65D8B1A5793AA +3C4282D111112BEE28AFCA7A3808D4444C4669CA +84EAAAF989219F51AB3476A1B0B5F2246BC306E6 +625C6679C417ED2A8E9BD010DE37D40265074C2684268F16195489648993B9C4D3B534FA887C +DEF605FA87B991F4D20A8F78DACE +5A54C070E03D5C59D9D2D3E06B09CEE028D68B62AB3AEC43C1DD20BA70D288597D9BD8E06818FF764EBAB436723988E8D7CA59E16D39032516BFC5D552ACDEEC6BE938BEF2F43CFFBC811C3626C4DF5F8CF080676520B51C60CEDAD1FE6C92D1431C702174CE517A8FA9377D075A0B6833DAB101DB65397F1419EF5F0016 +004F +6F0824F9657BB4F1C8F981709956865F6855EFAE +9242AD55 +91BBBEE163D844DDA894E13190C9 +2480439E4C71CADA +BD043A9B +A315CAF72652AA7FE6DB2E84D82A6111CE4DE90C02DA0AFFE2620922262A45AB4ED0 +EEC9F4520DD12703442F7D028D4526BD8B771E09FBE11B2749E2D3906894E8D4BFD3F379F14C +3C874F550606965E22FE487B247B5C2D06728490C8F2A3B588CDFC +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +/DPIx 1270 def /DPIy 1270 def +72 DPIx div 72 DPIy div neg scale +0 -13970 translate +1.00 1.00 scale +/wst:dutch12 12.00 /PSOwstdutch newFont def +/wst:dutch12b 12.00 /PSOwstdutchb newFont def +/wst:dutch12i 12.00 /PSOwstdutchi newFont def +/wst:dutch10 10.00 /PSOwstdutch newFont def +/wst:dutch14 14.00 /PSOwstdutch newFont def +%%IncludeResource: font Helvetica +/wst:helvps10 10.00 /Helvetica /wst:helvps ILEncoding 0 declareNFont def +/sym:clas10 10.00 /PSOsymclas newFont def +%%EndPageSetup +GS +0 13978 10801 13978 10801 0 0 0 clp +wst:dutch14 SF +0.00 0.00 0.00 1.00 setcmykcolor +<1929373329352a0e010f01102931272c3025352e012a3235011829253638352d312b011929373a32352e011b> 2207 558 0 7384 -1 s +<29352a32353025312729> 7375 558 0 8593 -1 s +wst:dutch10 SF +<0b0d> 9346 13300 0 9522 -1 s +wst:helvps10 SF +<4e6574706572663a> 1322 13280 0 1949 -1 s +<205265766973696f6e20322e313b20436f7079726967687420> 1949 13280 4 3868 32 s +sym:clas10 SF +<01> 3868 13280 0 4019 -1 s +wst:helvps10 SF +<2031393933b131393935204865776c657474b15061636b61726420436f6d70616e79> 4019 13280 3 7133 32 s +wst:dutch12 SF +<0712> 1589 1431 0 1937 -1 s +wst:dutch12i SF +<03040b09070402> 2033 1431 0 2700 -1 s +wst:dutch12 SF +<363329272d2a3c> 3177 1431 0 3795 -1 s +<00372c29002f3227252f00253128093235003529303237290012171b16002829392d2729002a2d2f29003125302904360500042a382f2f3c07> 3795 1431 9 8895 0 s +<3438252f2d2a2d29280508> 3177 1676 0 4112 -1 s +<001d3c3137253b002d3600372c29003625302900253600372c253700322a002500> 4112 1676 9 6914 0 s +wst:dutch12i SF +<09050c0409070402> 6914 1676 0 7593 -1 s +wst:dutch12 SF +<08> 7593 1676 0 7646 -1 s +<0733> 1589 2023 0 1882 -1 s +wst:dutch12i SF +<07070109070402> 2033 2023 0 2725 -1 s +wst:dutch12 SF +<362937> 3177 2023 0 3432 -1 s +<00372c29002f3227252f> 3432 2023 2 4266 0 s +<00253128093235003529303237290012171b16001b1b> 4266 2023 4 6506 0 s +<0f04360508001d3c3137253b002d3600372c290036253029002536> 6479 2023 5 8895 0 s +<372c2537> 3177 2267 0 3536 -1 s +<00322a002500> 3536 2267 3 3986 0 s +wst:dutch12i SF +<09050c0409070402> 3986 2267 0 4665 -1 s +wst:dutch12 SF +<08> 4665 2267 0 4718 -1 s +<0735> 1589 2614 0 1847 -1 s +wst:dutch12i SF +<09050c0409070402> 2033 2614 0 2712 -1 s +wst:dutch12 SF +<363329272d2a3c00372c2900352934382936370025312809323500352936333231362900362d3d293606002d3100263c37293606002a323500372c29003729363708> 3177 2614 10 8774 0 s +<0736> 1589 2960 0 1847 -1 s +wst:dutch12i SF +<0b01060a04> 2033 2960 0 2495 -1 s +wst:dutch12 SF +<363329272d2a3c> 3177 2960 0 3795 -1 s +<00372c29000d0a0c080c001d> 3795 2960 3 4852 0 s +<0f1b002a323500372c29003729363708001e2c2d3600362c32382f2800313237002732312a2f2d2737003a2d372c> 4846 2960 8 8895 0 s +<25313c> 3177 3205 0 3493 -1 s +<002536362d2b312928001d> 3493 3205 2 4480 0 s +<0f1b> 4474 3205 0 4765 -1 s +<033608> 4769 3205 0 4956 -1 s +<073a> 1589 3551 0 1909 -1 s +wst:dutch12i SF +<09050c0409070402> 2033 3551 0 2712 -1 s +wst:dutch12 SF +<363329272d2a3c> 3177 3551 0 3795 -1 s +<00372c29002f3227252f00362931280935292739003a2d3128323a00362d3d2936002d31002a352530293600043a2c293529002539252d2f> 3795 3551 9 8825 0 s +<3e> 8825 3551 0 8895 -1 s +<25262f290508> 3177 3796 0 3692 -1 s +<0720> 1589 4143 0 1975 -1 s +wst:dutch12i SF +<09050c0409070402> 2033 4143 0 2712 -1 s +wst:dutch12 SF +<363329272d2a3c> 3177 4143 0 3795 -1 s +<00372c290035293032372900362931280935292739003a2d3128323a00362d3d2936002d31002a352530293600043a2c293529> 3795 4143 8 8372 0 s +<002539252d2f> 8372 4143 1 8825 0 s +<3e> 8825 4143 0 8895 -1 s +<25262f290508> 3177 4388 0 3692 -1 s +wst:dutch12b SF +<0d16131e> 1271 4873 0 1710 -1 s +<000517150e1316000b1c1a100e15000b170f14101c000a> 1710 4873 4 4067 0 s +<10191d101b1c030a> 4063 4873 0 4855 -1 s +<101b1817161b100009> 4851 4873 1 5751 0 s +<101a11171a150e160f10> 5743 4873 0 6785 -1 s +<07080c06> 1271 5296 0 1866 -1 s +<04> 1870 5296 0 1928 -1 s +<00> 1928 5296 1 1960 0 s +wst:dutch12 SF +<001f312d3b00123230252d31001d32272e2937003729363736002535290031323700273230332d2f2928002d313732003129373329352a00263c0028292a25382f370800162a003c3238003a2d362c003732> 1960 5296 15 9046 0 s +<00302925> 9046 5296 1 9461 0 s +<3e> 9461 5296 0 9531 -1 s +<3638352900372c29003329352a3235302531272900322a001f312d3b00123230252d31001d32272e29373606003c32380030383637003529273230332d2f29003129373329352a00253128> 1271 5541 11 8241 0 s +<00312937362935392935> 8241 5541 1 9113 0 s +<003a2d372c> 9113 5541 1 9531 0 s +<0712121a241f191621> 1271 5786 0 2649 -1 s +<00252828292800373200372c290030252e292a2d2f2908> 2649 5786 4 4732 0 s +<0f> 1271 6132 0 1434 -1 s +<001f312d3b> 1434 6132 1 1933 0 s +<00123230252d31001d3735292530001d32272e2937001c> 1933 6132 4 4321 0 s +<293438293637091c> 4313 6132 0 5125 -1 s +<29363332313629003729363700041d1e1c130f18241c1c05002d36003929353c003038272c002f2d2e290025> 5117 6132 7 9531 0 s +<1e111b241c1c> 1271 6377 0 2120 -1 s +<003729363708> 2120 6377 1 2550 0 s +<1e2c29001d1e1c130f18241c1c00372936370027323030253128002f2d3129003a32382f28002f32322e0036323029372c2d312b002f2d2e2900372c2d360e> 1271 6723 9 7625 0 s +<02> 1398 7069 0 1504 -1 s +wst:dutch12b SF +<000317181c0316101c18101a110316101c18101a1100021c00> 1504 7069 3 3692 0 s +wst:dutch12 SF +<1d1e1c130f18241c1c> 3692 7069 0 5054 -1 s +<1e2c29> 1271 7416 0 1631 -1 s +<000715002b2f3226252f0027323030253128002f2d3129003233372d3231> 1631 7416 5 4632 0 s +<002d36003132370039252f2d28002a32350025001f312d3b00123230252d31001d32272e293700372936370025312800362c32382f28> 4632 7416 11 9531 0 s +<313237> 1271 7661 0 1572 -1 s +<00262900363329272d2a2d292808> 1572 7661 2 2751 0 s +<15293529> 1271 8007 0 1736 -1 s +<00253529003632302900322a00372c29001f312d3b00123230252d3107363329272d2a2d270027323030253128002f2d3129003233372d323136002a323500372c29> 1736 8007 11 9531 0 s +<1d1e1c130f18241d1e1c130f18> 1271 8252 0 3237 -1 s +<00372936370e> 3237 8252 1 3672 0 s +<0733> 1589 8598 0 1882 -1 s +wst:dutch12i SF +<03050809070402> 2033 8598 0 2642 -1 s +wst:dutch12 SF +<362937> 3177 8598 0 3432 -1 s +<00372c2900282d3529273732353c003a2c29352900332d332936003a2d2f2f002629002735292537292808002212292a25382f370e00363c36372930002829> 3432 8598 10 8825 0 s +<3e> 8825 8598 0 8895 -1 s +<2a25382f37> 3177 8843 0 3595 -1 s +<002a323500372c29003729303331253004050027252f2f23> 3595 8843 4 5768 0 s +<0735> 1589 9190 0 1847 -1 s +wst:dutch12i SF +<09050c0409070402> 2033 9190 0 2712 -1 s +wst:dutch12 SF +<3a2c2d272c> 3177 9190 0 3703 -1 s +<003a2d2f2f0036293700372c29003529343829363700253128003529363332313629> 3703 9190 6 6585 0 s +<00362d3d293600373200372c290039252f382904360500363329272d> 6585 9190 5 8825 0 s +<3e> 8825 9190 0 8895 -1 s +<2a2d292808> 3177 9434 0 3579 -1 s +<002212292a25382f370e000b00263c372923> 3579 9434 3 5116 0 s +wst:dutch12b SF +<0d16131e000517150e131600050e1c0e121a0e15000b170f14101c000a> 1271 9920 4 4326 0 s +<10191d101b1c030a> 4322 9920 0 5114 -1 s +<101b1817161b100009> 5110 9920 1 6010 0 s +<101a11171a150e160f10> 6002 9920 0 7044 -1 s +<07080c06> 1271 10343 0 1866 -1 s +<04> 1870 10343 0 1928 -1 s +<00> 1928 10343 1 1960 0 s +wst:dutch12 SF +<001f312d3b00123230252d31001d32272e2937003729363736002535290031323700273230332d2f2928002d313732003129373329352a00263c0028292a25382f370800162a003c3238003a2d362c003732> 1960 10343 15 9046 0 s +<00302925> 9046 10343 1 9461 0 s +<3e> 9461 10343 0 9531 -1 s +<3638352900372c29003329352a3235302531272900322a001f312d3b00123230252d31001d32272e29373606003c32380030383637003529273230332d2f29003129373329352a00253128> 1271 10588 11 8241 0 s +<00312937362935392935> 8241 10588 1 9113 0 s +<003a2d372c> 9113 10588 1 9531 0 s +<0712121a241f191621> 1271 10832 0 2649 -1 s +<00252828292800373200372c290030252e292a2d2f2908> 2649 10832 4 4732 0 s +<1e2c29> 1271 11179 0 1631 -1 s +<001d2d30332f293637001f312d3b00123230252d3100122537252b352530001d32272e2937001c> 1631 11179 6 5665 0 s +<293438293637091c> 5657 11179 0 6469 -1 s +<2936333231362900041214241c1c0500372936370027323030253128> 6461 11179 3 9531 0 s +<2f2d3129> 1271 11424 0 1608 -1 s +<003a32382f28002f32322e0036323029372c2d312b002f2d2e2900372c2d360e> 1608 11424 5 4473 0 s +<02> 1398 11770 0 1504 -1 s +wst:dutch12b SF +<000317181c0316101c18101a110316101c18101a1100021c00> 1504 11770 3 3692 0 s +wst:dutch12 SF +<1214241d1e1c130f18> 3692 11770 0 5071 -1 s +<1e2c29> 1271 12116 0 1631 -1 s +<000715002b2f3226252f0027323030253128002f2d3129003233372d3231> 1631 12116 5 4632 0 s +<002d36003132370039252f2d28002a32350025001f312d3b00123230252d31001d32272e293700372936370025312800362c32382f28> 4632 12116 11 9531 0 s +<313237> 1271 12361 0 1572 -1 s +<00262900363329272d2a2d292808001529352900253529003632302900322a> 1572 12361 6 4543 0 s +<00372c29003729363700363329272d2a2d270027323030253128002f2d3129003233372d323136002539252d2f25262f29002d310025> 4543 12361 9 9531 0 s +<1214241d1e1c130f18> 1271 12606 0 2650 -1 s +<003729363708> 2650 12606 1 3080 0 s +GR +eop +%%PageTrailer +%%PageResources: font Helvetica +%%PageProcessColors: Black +%%PageCustomColors: +%%Page: (19) 19 +%%PageResources: (atend) +%%PageProcessColors: (atend) +%%PageCustomColors: (atend) +%%BeginPageSetup +bop +%Defining font PSOwstdutch +%!FontType1-1.0: PSOwstdutch +10 dict begin +/FontName /PSOwstdutch def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001000 0 0 0.001000 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 1 /C0032 put +dup 2 /C0036 put +dup 3 /C0040 put +dup 4 /C0041 put +dup 5 /C0044 put +dup 6 /C0045 put +dup 7 /C0046 put +dup 8 /C0047 put +dup 9 /C0048 put +dup 10 /C0049 put +dup 11 /C0051 put +dup 12 /C0052 put +dup 13 /C0053 put +dup 14 /C0057 put +dup 15 /C0058 put +dup 16 /C0062 put +dup 17 /C0065 put +dup 18 /C0066 put +dup 19 /C0068 put +dup 20 /C0069 put +dup 21 /C0070 put +dup 22 /C0072 put +dup 23 /C0073 put +dup 24 /C0076 put +dup 25 /C0077 put +dup 26 /C0078 put +dup 27 /C0079 put +dup 28 /C0080 put +dup 29 /C0082 put +dup 30 /C0083 put +dup 31 /C0084 put +dup 32 /C0085 put +dup 33 /C0091 put +dup 34 /C0093 put +dup 35 /C0095 put +dup 36 /C0097 put +dup 37 /C0098 put +dup 38 /C0099 put +dup 39 /C0100 put +dup 40 /C0101 put +dup 41 /C0102 put +dup 42 /C0103 put +dup 43 /C0104 put +dup 44 /C0105 put +dup 45 /C0107 put +dup 46 /C0108 put +dup 47 /C0109 put +dup 48 /C0110 put +dup 49 /C0111 put +dup 50 /C0112 put +dup 51 /C0113 put +dup 52 /C0114 put +dup 53 /C0115 put +dup 54 /C0116 put +dup 55 /C0117 put +dup 56 /C0118 put +dup 57 /C0119 put +dup 58 /C0121 put +dup 59 /C0122 put +dup 60 /C0262 put +readonly def +/FontBBox [-25 -256 920 766] readonly def +currentdict end +currentfile eexec +D9D66F633B846A989B9974B0179FC6CC445BC7C8A959A39A32E9DCE7FAEF17EE3BEC9F +50E1A6FCA651FC4B3769A0A91041557502E25A5D6180FE25A3D11BF079E1DF66E54EE9B7C229AF891739707A2A0EC140306B5E43E52B79BFB89E459E50 +6EC6F610A70775A31C460976C4F79449D86E57ACE491E5C6BF20CC4307B1DAF7630252 +E9AF8CFB69B50EDAE9D36A6104AFEF8832F920FD2346B2C7104CD11E3BEE999CFA9F5A +49DB3173EE48D1C82994237F360407B022E0B4 +502E94EA8B493651EF2D03F0B513D655047568325B512AE6 +6AC6F53F3848CF70DE25481CC65D8B1A5793AA +3C4282D111112BEE28AFCA7A3808D4444C4669CA +84EAAAF989219F51AB3476A1B0B5F2246BC306E6 +625C6679C417ED2A8E9BD010DE37D40265074C26842244AFFB9E84298AD18DF926E5CD51DF0FDC +343134D0D4E7A16E31DDD2B6 +A02530548D1476270C +F530415F +C733988D465EF59596F6557FFE14 +5590C9120B61E7A5C96A93C136A314AE84D3490E4B8AB72842667C775DDA28927183132A8B55692AF8246C7E09AA37FA45116E7E8AFBA6A6A42073B007038F7F4B673845ABC9E7C6B059AD15304C28FA50492F754373DAE154C84ECF780DA05046258E00B91E7245C36B0443A29AEDB2388A68A5A3FBB6B9CC6B36AE4413 +300E +67974652BC06D58D7C59DB69 +433F893D +B9E8E9D3E3D461A4D2031D08A9 +59102938C09484032B435E8BE23AAE746C87ABCF6E4C8577E79A210850495587311B5A94F9581BBEC07036BC09375D6ADB993A8DEA9F86257B5771A64C689085 +6DE3166A +38BE7A24AAD26C6B31A3A2F5C5 +01AF422A94C6A9DD84E8982738DD402C60012280143C7DC826743705C7F0139848F715DB40B6A9A722ECCD5D8E91EABA4E0E2DC35DA1E69EEDC7424BB9D92E +0C2E4786 +F12C3A13DEB21403948950DED5 +B9C221B0F037880032980F2BC5F1CAD8F9B454E9FA0ADCE10B8564B9045423A7102E2FAEEF337424FBA5D52FA3778EF8A62532BCB857F8FF7A +0962B71B +9E3795FDFB0596B5183E2F47B2 +65EC4F5C9193439ADB5A2F57E33582C96BEAEE167B18A3 +D51E100A +E676C4B7027BA97ACF7D3DDEE3 +5065C08273A6D5B7F4239A050A397A99A5BD2C1C4D257C329810132572076B +F7CF2AA4 +A7C2EC116668C014B2536B65A0 +444036463A3319E10A27F30829269C6EC54D5899BFF4110CE03A0856 +5C182B62 +4F18B5E0AA4030EBBCA2FB7C69 +92B79CD89D3373227928EDA874E90559B8DF5B18C7E84F1EF2B0417364EA44FA48CB58FE2D76D0188B8F11A65BD792960D40A9D978A3AE1E03592E87168AC18EF88FDA6B97887DE6F098 +ABB6C740 +0ABF18544D236B79ED5A5F9D9D +0FDB96581C19948C0361C2046133CF56D9F879531AFFFFB52CAA898DA779D8FF901CD6B2478A5193C999071C87685E9BA2A7E8D9A8897191B8A8E55E0F677B +C10742A5 +FC8A9446CF0A78624E9ABE614D4B +FA8B7DAAA9C862E0AD55F4ABCE212874CC58CCEA7704072F3D8DD8B22EE3650EA4B1CBA53766CE6D3E7663B845FBD98D4E4E5EE54286601A09C5A6ABABBCD484BE053EC501E150B13B715412F6F7C97F786D11EB9DE8530D9AE737D36FB3FE9A9765858C616B672D769BB0BDAADB98 +5C8585E1 +328B0FE3E0B106FB600BC305BD +5820C991EA98E470C2A4D7A0FE4307848409246D4289FE00CEE65405855CE21FCF3B53DD25B9847627F3CB1855590BAFDF8343DB71D11E70B126 +1D6B93C7 +7B2CB5EB8036154372DA5BB2AA +B0A433C49F8AF8F6F5F9643EAC0B4DB751887D402E2667DA4C65765E2E1BB45896F1B266F4215A61841C2BCCC29444554E545C6B65E07B9C052901067A14E38124881769D18FFEC62A6CAA0EAD74F876154B48DF03F368A3C6F9CB77D60B10DC5F +47C22469 +A3F26AE0BC46040CC328119B88B0 +6E588651C5CF7CB3C2F2277DD044A4D0D03ACBAC4D311830E1CFD680BED0F9330C491001676D1AA0070DA3EADCA0F9E20BC7D00DFFCE2257170CF1193C64011CE229B862731770904F48A343960F9D622992DE981B1AF4FD8C3DE8E9BC551260C8B99B9561 +AB978542 +663126B6FA7FA72059592675FF +83CAF282133A8CDA4495410655FDB7EB5056F152EC80DBB4A04D4E2548FC2A10F289B9169C013E227BFDE88A2E666EFADC9303C09CE4 +C6EDE17F +7A3A5C88A26C17401BC0EA5121 +25DC02C16705F3FD5B065E0118E0D659F62E9B1DF014D1BB4DBFEFAB1585E7573BB490E0F24061 +7E9D5E59 +AD397C4437237174D6A67CD65AA5 +3D6253DA40C61ACB6DE629B39640CA198C7E1246AC623BE22F45E5D465854E83C2A5071AA871F22AD74CAA2A1D21B55EC459486E5AC09EC27533DE1E4F3E8FA114BCD409F850168BF655EF0D3E8D9CC39B34FE205CAAF2CCA038A8412138DF19FE03B858E925B1A7BE358ADA194A199C87C162 +3FA455C3 +266A4B982AAB32F73D19A89EA5E8 +9014A1C0E8A2E098FE3D440D834DA041E2C58D5C775C1B773324F19F718CA780E38FB7AE59AF0F1A227AB4D4E1672C387E656B42B08802AD0BD819863BC7FAC90616A8DC84489504B8926D0E9D6579B637BE337408C4D2461BE18057DA78B176CE562503187CF0BBFF43F1BE38E2B69A8717F974F0D992D4EC3F9EF0238C +F75C +F7 +3A4EA464 +CBA1D4DD079DF64299C6807B68 +05524A6D8CF37930B4E1CFE737538E312B4A08B525684C374CC5EE5B4A5636D94D5BA71855BEF7A2CD2E102FE47759B295C13FC415BC05993C696CE886AFEA5740384B4BF25E755DB913EF8C2B598EEB40CCFE0F9ACA61EC6E33FDFD71961E3C8AA021 +9044DB5E +828A0FE28FCB48718469EFE52109 +79A18FAA3C344DA83F258ECA5AC35DDF2561BCE6A4DFE3D536A4E3F44F71137389E160EACF444B3BA1DED5BBEB9E46A155AF353919271227694FF79C35929770FE68E1CB02FB85A91F46D94F5555B9015037A6B6F42E092BFFC13AD9F17ADBD0118AF8A6A9D8DD926A8E9133659E0E54239BB3AC778C2D46436F55C5ECF9 +D2EB0A8E +49E43C569D84B3278DC04F1E0EE7 +251A03EEEDF294F59442F560513B1EBAF7340A5C0EE2C458804D402C54500B689F496DE5C14567FC377C8A96934B356BFDF4998A5F0CDEE58F499253292BB015BF8DCB56E969A4E7235DF354A22E1E5A670B059A28398EF9DF13A6BA693A5BD4B2F32A130D4D53BC52 +CB6511BF +D389B688AC171FEE090FDF6A79C3 +01E0060003B7396A84F0A7A115AC3F17ED8A53FA69F2670DCD7ADB9497E997D2E928C64C0BBB78FC71DABCA5ED23E6F264F82412ACE1B05248DF978553AA6F90B2E9AD12442F5A8A9D0E0CF52577FD4E9C5EDE83EA9534B5996CF558C0E66CA48D0C34142CF7DB38175509DECE98CDADACDA1E5196D12068BD5834B5525C +9E8D +A5FBA803AF5CE65AB04E83 +6286D96E +B25DC80A88BBDBBA6A92D29D19 +C4CAD31A367B437339856EF3925CED0844451C473198445E439517D687BEF0F50C2D411AA3993754CEF2F9CDDF527CA038CAE5CBD0E3E49CAEDF55 +7DB3C39A +783E1712B0924E5DC27E7E0CAC +FCD114B0E822BD783EF2611ED6A42D3E7C38360A1846B68195B1FEDD23B9448E4C5125FF5035E6030EC6673B7ED657CA99F9419A99B1FE9825C81EEF6924B73A91168764B8C6E1 +81F81C0A +E8A966114AF0A6E3C14938019F7D +AA35E82FE0D9D6A53A851BB0FC1F944D432AB0CFFFAA51A7B727EACC69D7790373C210A50849943158FF32E700C9EAEF300666FFC3681718BF6D7F3BA712276A974A2150132B8C2603A4827FF9D28DA6AFDE7FDD35CBFDC855639F8917234347BCCE2AF57F1F71D01790E6C7DFE499 +30C0AC11 +CEE38048EB9D7E2C854562A0E8 +6E19FB8DDDE1240DD5E338CE8458728EAD6588B8BC4CC87F3A8200C52584D0B64558E0E3AE6E0BB53E41420F4EB80E2E79BC143D3BCAAD20C6E57930C8C3C49F4567710183039EE2C645214DD084A65F6BED0726FEA847CF9C64C409 +82D83D4E +76F27ACC614B4AA65E27B86DC2 +8D9CA467ED059F1AED28F822A7755552CF3E541920855437D800DC4A43005A4D14062861BE4D67BCF659498F24C8543614B5BDFBBD41CA2E495D1742D9BD02F9976976BD3608F5017AEF3F2E3EDCABC9F08483 +45CA9578 +F2AAD1CB25C5BAA165A730B69459 +8648D332AD1F50AB0F15AEE0690CC521ED215C10109A7F1FFB722781479B05FDDDAA7649FEE322CB0BE8F4F7021A3026B1808E703AAF172CD52AFA6B720C3ADA2B987B4F1BA641411CF10581D2E1AF41BCB0DC981E74A957FA1F3622CD3455EB79679D1E4B66EFDDFFC0 +DF0D33D9 +FE7155C4A12905D3906B58AC7236 +A130C5BA01733CBA8DF5B9A4BC0BFF2BC890A19A880DD9B2FC476470B73F9DA32CD10727B2A753F472379FC339B23E06520F14E7132AAF4707688CBC6C1C3EE8E265792D0ADC45F1DF02B08E6F46756D919A2DAE19021D180F62C824FD21E8548C277DED2BFE82F90973F27F5B2AA79D08ECB45ECFF3AA1C986A7B515456 +7200EA4E +48FA5B38D6BDE7AF1305DFD581E9 +F3F68DC64F4ECB9AC47AB58271A1CFE3ACAF47FD03A0163B90545FD492ABCA3E57459AE3DB358BC8BB6A02786A988D7131290BD5F5727058F2B1DD69BABF37B002AD46115401B432F67A36DF9452ABF89E8A2220933FAA4D81DB4C26E2E84E17EBD07598F4F03ECEB8AF4928533774529DC4A103EA627A6B22006775ABF3 +E7F0 +14C259 +CB7306FE +861DBE51CFC8299C66250E0BA6 +B7C6277384C20F87987D50D1EB48B2C03A2723F6053BACD09923186E22E773F4D1675379EE29631AB263B08E16EA660AFED38315F7C6F01BA51C508581480492C003E9447A0D0DD2064861D5EC2B10A005 +014ECBB3 +6D68074D0492ABC251FAE5840122 +72E23198965DFD6E8E49899EF97D5B1A73855AE0741275B7E953390E901FBAEA46F92CE8657F369448C0FA2A822190DFC4452923C82C147175AFBBEF34300CA867F452C325D37CE0C07807DAB1085A59E61968DD1B8E4E6F80D9EF7D9D7D386DF26FC7B3 +ED6AAB3F +2FAB272C3FD24A2FD822BCACAC +6B2846EEF1BB81462694D4FA681069DE82F6E7949C2B31A9B378FBBB773767F5283EAB58C823405792A8 +A7637627 +759A2C7BDE3175C12B97C78A25 +C5717BF384935104D8E3AD4D18B7DB26A903EBADC0CAAC5D74CD5947B2AC7F2F37F5560F87F1FBE65AB47933 +1EBA6049 +A3B9B830458E680F20004342D0 +B05283E66792036FCB82B84C0A97F599D980961CCC10 +211D5CFF +80E1DBBEDD5ECE0CD67A78FC3779 +3E289C5BC0DEF4F0C44563FBC4382F2B4458D129A896FA91AAA3C679050FED2215E55A347D72E989387C0E2B1FC8DE63FFD30B5060CC429BAABE254E86ED463ED1547C8DE8454DF99F11C4D999A1C28AE66813528028799CDE37163EDCBAA39C2820C2E4250E2124F762D59FDC42E0652467B287DDD565193B2C55E26E6C +7536 +56BCCB +ED9A8CFE +51E6FA1F5A5C7C4B5E1CAA8410 +28DCD2AC233B28B75575C115D23CC30BB7700C6EE4865D13D9A7050124C6E5AA0D3D359F9D86BADFA2DFFBEE7332140C51A33715F63686D42BCA65A51603756A9FA3F3CCBB4A9FE3330094C128950D5402963483CBD2282C +9CFB6BAA +FE61F3CB5FA81982A4B47E1194 +13DD955653613562B2D83642E8899F679C4A831F913FC5A3E3D1F887D8BDDD92DDA8D40BAD6B5CCBD69C31BD92D6A507D628A5F108BD4486A6B34B33E15EB5034BD166D5DB3E5EC1ACBA39D161E02993BC17 +B132D993 +75B741DA8073CFC205DCFE5CCAD9 +17381670E8B6B84014CEF3500AD88ECA23C8225F8BFFA2C8AC27B9DFFD813D4F0B66E06F1323C25589BE04D806AA756722B83079E1F245B871EE04C9BB620772D129CB853B8D1B29F72B96E7DA39BB5DD9A06828EA6562000093E68873AF4A3F55A47BF85097FC8AFDEC0BF0FA96 +19A8C734 +DD36A0E5E413AFE2BCBC1BF93B +1F0A90C0841DD224B1FDF5F5338E6BF8CBB8E21E11857C8E41B4D8BE7480AC3B3B9D5EDC99024AF87FC78899461C8A4142EFDFFB85034D06471231AABC5699DD11955A83F4615B11D41294CE40F457E0D54F5C122F939708CD +9E07164B +7A297AA57AC5B5816098939F0A +EF7E64F6B4656046A987BB0E1FD2963415C97BCBF0198D69BD8CFC1168F3D58AD4639376EE8AA6B5B5FBE652A40846FD27D79DB0F0930345705A2623A5B2FE3E22F16C8E389C018F76537C40EB105D7CA14201E29F1B8491B6EC6C56 +74A8CE47 +4F164F49ABAF058BFBDA85428419 +DC74E534BB0232553EB045BB24864D9FEDFD0D37DB2D82B70CD278784C17844298130A9D6D78B2D5CD7B317E570AF6CF2D242C65A26B21FAAE37A35E494D5D0FB2C19C6469C5B5C2FBCFB60B6F8880BBDBC690340072B815CB57D6140069886DA7D9F8CD5E604FC4D2B29077D51A0CECB3DB45A2C16935ED99BAE8525178 +BF8F +80F04CCEEB85C4C8531B3C5DFD439D461374DE9BE18EEEC457D0D0F0C8615CE55239892B9CC21AC2A58756D395439F +7B57A355 +91A080D56EA8E49933EA9EDEF3B1 +9FCE4C08607E6572A6384527B0CF6FC00F2ECC45E469967CAA851834E924CFDC4763BA7EAC23E4F712C7A8F54270A401383CD016540B8F63419A6E134775087E6584E1F139FFF2925C9586DD11EDA1860F881D0882DE22A4B87CEA6B1EA87C105101FD4A2ECC74C159A656EF15 +4CF5E9FF +CF2DBA31799CC0067DF334C4E5 +AD44BF7F1AA099C4650FBAC1ED2F6847478EBA3FC15E6E4C82153A059872B0BC925E5C6DDEE9A34B3DD2A090175714412B1AD34DCBE3F44018675751282135D56E11160C90770AB818C62244702D4528 +8CFC2AB5 +BCF572B3C6E2F5126C0B35C693B9 +AD261C3C6476E0AF2EDC08A8FA37BCF478434EE86D4207D0119C57AC64A5C37692D3EAC641D1812529CACD4729EDF81397E671A3D286F3079DF1C1187BD6E01C8571F4F44B41753FF539B9BD8429CCC6C3A515CA851B17FC1F589A3214E06C83E262F2A8879D61365DEF459FED1181C6628B1E97D33C501333C5022C269E +EBCB +001199FFFA8EB66F0799E0A871738C07A4AA8EE9AE62973BC8F8AB5C25DE835C85D5DF +4D7BCD4D +35FC3E97D6502862D8790B301E +9CE62B78AFA6258AD73EA78092E8A1665DCDC716D69B9E848F965D35D3B0C12DBFA336BD0D82D041ECE36883DDCE472541133BD2916F +E74B3A7E +F9CBDC92C3011411FD105CF828AC +B0730F46650C1AD9AAEA0EE56C577E54B7A0ED037E384E22CFFC5922E3E8BA9460894DCAE86B5CB197A521EDFA08B5D75F12FFA2760E0EAAD4EFA3DBE8D97333FB47DAFF6EB3A21B478492279273AC401AFDC64880435308BC47CF0E06A5A3D7F34066BE0C0C43C73DEAAC10861E6A1848905834628E3DD279FEA3D4CB28 +8100 +8E1066ACB40EFD15A780D3D2C4FCC1503D2A1F0EF1462F252C8189489F5D79 +97670DFD +91876F7FF1BBC23D94DA0148E8DD +6A47962A84337F18020CF509FD313F775B831D24331D870E7257C89F8C1327AB3C80856C9CBB155C2CE6458016B9EFB7D79F1F65D0378BAAE76F25FBDB80724F3ECCAF8BAF18CBD357D3E1B48896370AF90ECE6E01CC41AC8C1E354B253D35BC65B175D1640EB980BFCFA31A +2FFCCBE5 +E74D5CAD18BE8021A1EC26ED65 +81AFA8B675BE39CED50D60B77970B7993876AC44B29BD70D84C667BAA2F0148BB76453472636DDA72AC46C1EDD87CE458E553ECB743426A7A622E71597B13CE7543E979381EA +D93EA67B +79B9F85E35CD8461A279AB87E1A5 +11A616433820A6776EA563B287F775E7772DAB59EF6BCBDCA4B692D8167130D1EF1B65E7DACF98F7E5BC03E52C193C9890CD8CB8ADF4FDC54EF0D967E444A0029226F21590639113971E53322E92B032995B9D7325EB70FAA25E58F6E426B64544396CAD54DBBA0E5CF71126FD9C02643CC0ADE88A16F7 +D01274B1 +4673A7F7D407FF75DB2B504BD6F4 +8D79CBBA4B5B6D68690FA92171D233F32EF076943F516E2DC03CA8EC52751188F91BE1D1851E52B3DD1B4ED7F76376A707E7E0ABFAA856E16851216EB71BE9A5165924B4222DB05EA15C66B8AFF716FEF0FBF59CB478EFFC8D64FF1306E83D7BBFE7099DFB70796B7339 +53B39ACF +5E7808C2AA71B45DE1F282ACF4 +715E5D272AF1FA295F4969A761D9D43375C70223FEE77F37E2F44039ED3E056F3B90B58807D900CE48F30C0A9DB8BEC69C0848F8351055EB8AA4250AE8B9FB90EDAEB4A00A389A84B7511881607E4A62BA7A9AA8D6C205 +31C2D9AD +5C7782D3140ED50994E94867FDE6 +F40B8EF91A9F4679547CBDCD38703D5BE90BB427F18616511E4CCEAA9C5F717CFF985D7F80433C6F802DB08720547262F4E902B7861753A92E3A4B6C1D39B17D713109674887224915AC2338A479A8342D8292B1C05C3E981AA7EA9EB85DE45F8609E33604120E4A2BBD9DE91E70EBC345E967C98E6D827C6E7687FF +029E0159 +CB6AF8B02245E4C1EA7FC31403 +7C7E13F37A7568CCF0625468CF801E833F456F879C4EFA3B9DA450DA45C42FE866C2C004CB721076BDB669E9E3BECF3312AADDCE0BF9F9BFFBB031E43C9486CD37DEF47B12 +31D7E8DD +61F8513A2585B7EAD7C84D3300 +202FAB289F5390E12773DA7D3550A40AFBF16741825065A53BF425A7C0528B8B849AEBD2A9E35330B956DEF99B555C7A6B908FB328B7FD18F88A9BC27DD42E76B38BF43A22BE7498367D73AD3FDDB7BA7D749AB2D8837F1C83FB77E27ECB66623D1A +A340C2C5 +A5778B442BF9AAE794F103318B +37BD96C9D25A7DEBA985C8C60FF1915AA514B4F3FAD83C8E8185D95B8D161A2BE57C7FF7440A9CB12675BC3265B6684C8D421204CB476EB88A517ECF81B2F42F21A36698E349472BD31D3349FF5D1AB9D04A90488DA7656F30 +953A8453 +8EDC627DEEAE844E8B3D52A656B1 +A57D8BDB442C9C0894EB8538B75D1D5EE365F7E96D052A1EB549CAACFDE81D538E42CBCF7CCF0D3ACF4BB1A8F4FE908DE36273594D42D0514DEA6A038CF67ACFADC30BE158C4B6AEE78CA88672E86798AF20B514AED6B1D776A47C84FBBED11F3FF2BCB3633A0A9A20BE73CA44BA08226C0C8636CE93D76911D05BCA2B62 +AF91 +2BD1C8728C4D5610F55A7783CB1C +3470CC81 +7052E98472AA2F44A084AFE8DD9E +0B1844B1688F4E21172F8F8EE6698A11DC7E719BAEB5E66AEDD0DD4400CB24587F412CC84309AB4BC4F99EFE85310BD92EE1AC8255B350936F2975474916C75EA2D44F05FA00595C7B4634379723A9426591B97C5883EFB4A2572673B7E4E8D05CA7F820F3BD66EC41248D15812F5911393CCFA40A616232A33BC75CADA2 +F619 +5477C46E +CA410E19ADC6D3D09B75D2F066 +48428B6B76A9747FD7C342CF317AD62DE491A478E5B8E992CDF587A3BEB0DB0CC3032AB3B163319FFDD8917FDBC450418CAB9F8E15A0AD08C869DAC21DEE10 +80D45492 +4081E9DF14812734C8EB7A1DC6 +A7028A0A609D9D53D4C1C9F5876AE7906A840573CD20 +20CB5E36 +F8BBB9523928C070D48FE0F489D7 +2EF60183582725CF +F722532B +62087128F5B0D1269B48EE361985B9632C8C75EF666D461941E2BDCBC6E25B979BE8 +B4E0C2805227D095A9DC8FBE5D8DC6BFD24A3A66AFAF112B5AB2847CE2FC94C70199E19A19AF +0B3FAE4A691A81996F20079E61E21DA2D6457B293A2350AFD83030 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +%Defining font PSOwstdutchb +%!FontType1-1.0: PSOwstdutchb +10 dict begin +/FontName /PSOwstdutchb def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001000 0 0 0.001000 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 1 /C0032 put +dup 2 /C0045 put +dup 3 /C0047 put +dup 4 /C0058 put +dup 5 /C0065 put +dup 6 /C0069 put +dup 7 /C0070 put +dup 8 /C0072 put +dup 9 /C0073 put +dup 10 /C0077 put +dup 11 /C0078 put +dup 12 /C0079 put +dup 13 /C0080 put +dup 14 /C0082 put +dup 15 /C0084 put +dup 16 /C0097 put +dup 17 /C0099 put +dup 18 /C0101 put +dup 19 /C0102 put +dup 20 /C0109 put +dup 21 /C0110 put +dup 22 /C0111 put +dup 23 /C0112 put +dup 24 /C0113 put +dup 25 /C0114 put +dup 26 /C0115 put +dup 27 /C0116 put +dup 28 /C0117 put +readonly def +/FontBBox [-18 -207 919 694] readonly def +currentdict end +currentfile eexec +D9D66F633B846A989B9974B0179FC6CC445BC7C8A959A39A32E9DCE7FAEF17EE3BEC9F +50E1A6FCA651FC4B3769A0A91041557502E25A5D6180FE25A3D11BF079E1DF66E54EE9B7C229AF891739707A2A0EC140306B5E43E52B79BFB89E459E50 +6EC6F610A70775A31C460976C4F79449D86E57ACE491E5C6BF20CC4307B1DAF7630252 +E9AF8CFB69B50EDAE9D36A6104AFEF8832F920FD2346B2C7104CD11E3BEE999CFA9F5A +49DB3173EE48D1C82994237F360407B022E0B4 +502E94EA8B493651EF2D03F0B513D655047568325B512AE6 +6AC6F53F3848CF70DE25481CC65D8B1A5793AA +3C4282D111112BEE28AFCA7A3808D4444C4669CA +84EAAAF989219F51AB3476A1B0B5F2246BC306E6 +625C6679C417ED2A8E9BD010DE37D40265074C26842696372152E316283F409A2BE3FB67B6CB2D +6C35138848401FCF8D64411A +41FB44D0E855AD39C2 +0BCE5C02 +B2E8B72CB0F5F3A6AD54FC694E +E1CCDB927ED71226CBF0C1C0989CD2E164C8726791DE76 +3BAFE591 +27DBAEC30F845ACB53B8850958 +B3ABDF0ABF2C6482F1E51966C0FCA15946514BCEF9735B4E7007 +6EF6CB94 +603F9E3EAC39457C0087ACD1D9 +A52D5C7D156B374E83EC087F30BDE6BE850DDBF2E0F0E6B6418255651E4A5571DE4EACCC5E2ECD7C2F24C0C0D00C07D9A95DA34B30C9 +1450E91D +2EEC5430FE77B6DDFE3271B8B14A +6550AA385F69356FC6F9145134458B318DDE2A785AECBEF1004FBA35E4F26DBB8E61D9ABB11797189746F255A29EC2F6780E256058284429D31ADF56B030FFE1BC251FE2EF6E7B6EFAB11085831932169ABCB17DBB43FD2514E2668E867A3418C9733F85BCC4AB32F84F25 +A89957AD +8F74EC8AD2A6C4AD659257ACC0CF +4F29C33168B7F912FE47D781E76EBA5FDD7F611FC2918F378CC7BF2E81D9D7889F28A1F94462ED60396079ED98B4DA57B19DEF9E7DECEC2B68BB3BDFBDB69380DEA5F42D9F813E005E385FF8FA733D87A1E0CE80F1A61F477453BD01BAD9D3C464622F7722490DBD54D11B61A3E5 +2766B24B +CDC63DFD973F78C3B5305E2D35E3 +3B794FD8E746100FCD75234F04328A0AEBD33E50AC0E6DE6BBDCC8B0BDEF490267C9888595DB0F4DE3641429C250175F375A6DBFB46F31C1810FDD0C8B38B1A96F7724BBF5C643EC080F80A1584EAB79F505489018240BCEDB2A54F91DCFAB4CE9CCCB3D +BF8213C3 +5D2932CCD828A09753D2B38717C0 +D90AB4060BCC3C1A4985A3264AF282480A46C240371B183EA54D2DAA4AB30C931EBD7170AC9AA5B2D6137B3A4114501428EE9FEF22DC9267A956D279C7976DDECF30A5CECFED6E0A8764421AB3EDB24D266922309EB6FF569FD57FCC374845A11AF9DEA91CB8DFBF3B68180866C5EA3DBF5FD618024357 +8ADC9AFD +C080015C6798CEC3D8BC3B09DA +7A66E754B2AA6AEF279B0B69012D179AEA137D1C83E14470BFF64FDE8781D2EACC4356A8F2B1A278D0F7D5F40367504577E41EDE674D48C0ADE0E460E85B +30A42CF5 +2AADFDD867E35D305B1A9101F88B +511FF83861021BDF40273E6CB6F14A1D54C0B0569E45A6C5E018D638E3F2B94399FECA737C0C7168BE35841F185E0DA4A7D15410C99284665170BEFFEE39C9354ED4716CF1EC334A74CC9DFDD32D7192E2DC23B661BBE6A6B9E41CFD17837F38982E068BF83DC04D759DF8B382 +ED21956D +3C20D6CD65E46E0A2FB01AB333 +B3FE8ECF051B05B1113B3BF50FC1EDF6735E20C8E1807D117CB84FC70616A2CB94D27AD6384488CA60FD8A4128A127DBA170D7D1BEF0EC9F07399C7E0F04B32E2F097D104E346F180A0EA795D4A782685D5BD9E0D1D04BFB5027582AFD219D +D9386C41 +E2D6C00B4CBAD4B554ABE68C2A01 +8FAA8C576CF4D0112E764A51D7F75C8A544A04BDAFE55D54534C6985AC3976E9B509314D620FCC007417FDB49170A4B391B41F21C1C0994661B94BDE5442F3824DD1CB863FD3FC0E5050F302BADB373F810405BC6B746B6A88C829B8F5611E363ACEA72E9591D55069 +704EAA6F +E18D009E7C4F3D17815AD2AAE351 +AA5C1A5E02BE3E2CEBDBB106D5CC26E9EFACC4F147658F7D03C9B4824C9E99E281CE404AAAFB96E3C9EB5FF1070FA60AE0A43E6384C62F8BED726F2AD220FEFBB414D8BB002116A23E31E99B941BD206AD54117A02D0137CBDE2F0C616946D32DED71342 +38ECDEDB +14FBBC608411A4F029630E61CF5F +7C8B15461EFD6C06C162FEF533F68064D02F3D40F0D76F0A8DD3B3E1577E14A2C5B10D696C5693588D3527D5BCCC24278680885289D88E3FE18852CE02DE9234BB92A59478B5C11D7BD0FB3017A3FA725393A8B804310E48921C07454C5AF7997E0BC4A1EDEFB026DC2B2CDFEAD8AE485225B7DD72 +13FDE8D4 +ECAF27FC08445860294D29ECF7 +85404270A9D6BAAE4301792A6A40C3B55045460EDC35A61DF7D09878296A5D28A26126F02F52001A78959C15DF44319C80B6DB6597BBF93FC1A7300E67C19D8040CA976B7856E732B1 +17D6B2B5 +35A8AB56157C31D5FDBB8471D2E9 +93F52957B13DF8F9B2A998171CB238DFE25F42438C9E985F3FED28ECDE6B96D5EF0EA21894193A298261DC440721BABDF7C30B46205B5EF8B7791D599D978DC3B240B9CADEDE57930BEEBDB7B0D446A86255AD316818299F1CAE2CCE98C3597584E07C0EDC637FACEF5AC71C505D3490AF986553740DEB847D472BFA6145 +2659 +7C18395C +0962E21D +8E77223FECD4B3EC1B992B3061 +D71E2CA99FC7477D857038A009F507E8DD8C53DBFC21AFE4FA87B3317A8D341B4AC8FE238ABA4863265E1FD51ED6A9F12D4C292199676A6DE1EB168C90BDE09147079994AD91B8A2B5C113C6FBB5FC253A4C +A1E00786 +B6AF852B4B7D6246EFFB43AD7C +EBAA1E8A6A400F60F49AD060D506866609241E6C4A8DC0F5DF5D9D2FB65C7EFABB61EA85D95889CD80581D728FE3CA52C83D64B1C9468DE82E81B78ED3BD4E5A46C23E8C96F171DB949633AB764E25B8A3208B3FBF1C6EDDE7D57CD9 +0F9439FC +9E2E9C4A81D3F9B31970D0F141 +65FDEF1CBC7E7548474CF2C4EE3E64B2656EF0E063FB15DD74FBC507CEFC7055EC371918007E75282B2B43775B955E9F84FAD2BF59670403910CFF23C3B6942D6E87869D701A0D71AD198984B47C0CB7D9C9190EFFA38EE839CDF484BE +BFBA0228 +67CD129409E7B95A03552991AA89 +0A8B6CB78DCE59274A6145BF6DF152856BC6B9267A970397E178B79FB337BD800CCD146AC76E6B5FFB5EC8B0373FBB7D360EB0D96E2243E3C3693F050DA7C2C37F76B7669893AB4FF4991057CBA7753CC8D8A8A61EAE802CB9295934D46FA8AA04F5AB4CAB4AAFE272C2424EEE016BE1DECB212B9E46FC9C3C71872EFD80 +C257 +7A8C05C0544C87A78F01DA77C8527571F1335DF19FF67074C5FE2A04 +7E4BEA20 +865D94DF9E15DA623D8E36D4F76E +939EA1ADA93F3D509492783CE77BC7D0C9ED3002D0A8F46D266F3AA41245F6ADB028C97DC27FEDD98640D0BC7B3F29AA5F0B27292AAE44FB6EE799665A2FE948B88D32CA27F487604D76B1BF74447A56B912E6FEC8233628456380A779B70A16F50763AA986C25 +97AD8FE5 +ABE7CA7718FA738737CE3B50F0 +179B0131FC9F1CAF00E4E8B28080D2CB054225AE62923A45BF0BF93CF1BF2DF38DFE2262CBC5D39677ACAB4E77988B63BE05C22B3CE6E2474C9B28D089A507ED7A81ED897F97 +55569722 +3EBAA21E13621CDFEFC70F8DECD8 +B6327AE61AFF13D68DE5100CA53EC9EBE4242528D0BC8DD8BF77DF9C877D61E4C945E17685CEABF113E2B3F2255EA224465F5EFF22061DC3C66EFE2A34BF3D50F3CB38F2FA012D9E0214850DA8D54ADEE6C4999E6C3B02658A30AFEDC1CB717B0612D87A458F8BD55427E62E1A33B38F02 +02D07548 +AEE23C86B69F81DB736A011123C4 +CDFDCD5A6CE962B520BD38607A5E05424FF94009435C560D2A154E8EBF0339A2FF5FD1083F02BEAF34327E0A5BD4D0F2E9AD3CE4DEB3EF3F51A78FA563DD52ECCF5600322D1F885A1B56E3E00F4CD9167DAD4774485DACF88466088FEF1113F2C8B5D8F0F15D80BE24 +0BF2353B +45692C6EC7DBF6AC1CB9D4931D +81DC972C084CFF96622AFEAA9D54CA79C1DDCC2383F2FBAF279C4C5387153F4A1A1E54BBF092C5F7741D747972D23C97C229CC6047056AB812F7215F190EB27D185A79D4727F721FB5259F3B71D94261EA88F6AA54E7A36A52 +19BBD4E3 +EE0E476207A652FA5E2AB3B549BB +128053BC9C318F8BA3046F728203A4C2AA2821106EBF3002E826251B6C57262A6B31A4690D4E00FCED479F319BE2ED0A3B5469C61833E6E7D95D077A7368291C9A4FF458ABB8F606C8BC0C636371CE98BB8FD5A989696872ECB8DE1B7EE7A6839A773248E2B9F872FA0780A8F4B22AC56A3DFCCF230D71FE22 +C8B11381 +61B2E69D28FE6A29AA28EBA6AA +858A62BA962F11AA82C9B1327DE8E15B299D821CC83AAC7C3F5EF9C05343D90A2140CB5A51402063454E736C9059131818C372B6524F8084C854E9F713CB4AB60E38965A +6637E119 +B700EEAC43269700C7ABEE1E14 +C643529001F426D7146A698634BE722A3B0E45761F31C99593050E64588A312507F3336E2B658035D3E1ED6888207CBF6F8C29DB9C9334B2EF7F5AB45578DF99D0E6C84443CBD79268276382A81D345D6C80DBE0CA85D7B822CC11 +93163DDC +0C1884228E0B4214DFCC1AA4157F +7CC1119159783D11 +E34FC103 +E300A926972AAEE4C9CD244C02301EB63A3E98DF2DF60FB0B288D165CD0A3798C412 +0A64C82915BF23E45EBAAA7DDDD97B67D6A64548E71A676C13C8572E282E95793C16703E6A22 +4139AFB0B755E0A3110411519839ABE79A35E059036E3B88F6FC02 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +%Defining font PSOwstdutchi +%!FontType1-1.0: PSOwstdutchi +10 dict begin +/FontName /PSOwstdutchi def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001000 0 0 0.001000 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 1 /C0097 put +dup 2 /C0099 put +dup 3 /C0100 put +dup 4 /C0101 put +dup 5 /C0104 put +dup 6 /C0105 put +dup 7 /C0108 put +dup 8 /C0109 put +dup 9 /C0111 put +dup 10 /C0112 put +dup 11 /C0114 put +dup 12 /C0115 put +dup 13 /C0116 put +dup 14 /C0118 put +dup 15 /C0122 put +readonly def +/FontBBox [-144 -227 757 728] readonly def +currentdict end +currentfile eexec +D9D66F633B846A989B9974B0179FC6CC445BC7C8A959A39A32E9DCE7FAEF17EE3BEC9F +50E1A6FCA651FC4B3769A0A91041557502E25A5D6180FE25A3D11BF079E1DF66E54EE9B7C229AF891739707A2A0EC140306B5E43E52B79BFB89E459E50 +6EC6F610A70775A31C460976C4F79449D86E57ACE491E5C6BF20CC4307B1DAF7630252 +E9AF8CFB69B50EDAE9D36A6104AFEF8832F920FD2346B2C7104CD11E3BEE999CFA9F5A +49DB3173EE48D1C82994237F360407B022E0B4 +502E94EA8B493651EF2D03F0B513D655047568325B512AE6 +6AC6F53F3848CF70DE25481CC65D8B1A5793AA +3C4282D111112BEE28AFCA7A3808D4444C4669CA +84EAAAF989219F51AB3476A1B0B5F2246BC306E6 +625C6679C417ED2A8E9BD010DE37D40265074C268425D63815BEF15AC9919F29F88A722E509700 +1EAA97FDB9800CE1CC6DACA5771B +DD5AB3A11EDA665863BF16B0FE19CEC84057AA46E95913FF4E7C55B12F710257F2B76485C41958A723508E3D098D80B795DD08B01D0CABB23F1CB8563F685F91F682ED84659581592BE82BAD244D4A7C2B3207451BFB3A3F06762AE3C4BE49B6006C4FFFCC735BB60F502DC39C070408A3D4A576C987B7DDC703351ED35A +DB38 +7C7D948512E73384984D099C08 +BDE35EAA +565A3A9C634510F67C7101DDCE +5EE69C1F06CF15239624505F6AE73440ED9BA2E1D64B06668DADC37FE075A64BAD7E45ABC9C43CCE5A85BBFD1CEF14672D5EC1D9598D7CA79FCFFC4F14F7268F4C08E09F143A2D9B6FDF99D077C7576AED42D0E993DFF79B0762C03FDAAB9C8F +6CAED257 +D6C82CB0E8555F8B77969DFCD700 +263CC05F3CA3BD3B4AA188942C3E8031A9D3B1B42001DDB49928E114BD5D3EC001886D97D9A1C841E061853103DABF63E10611F36CA6AC494C9F4CB526619AB5C36142EA1F06E6C5A5E144F773802E641DA6894B60E2FB47389D246AC548DC9735E2D98A7AED5E10693DB9E53AEBE4E6F1053ADE159E0AFDF54AEC8015C1 +7F0C +8E10D45B1A844E63E5D5E39C4C36582A804575EA260D78F7CBC515EE2EB51D7AF89A1374AB4C9850FC8CCBFAC9F31D02 +6E522E4C +6702289C34AFB02FB4C907360D94 +4875E8BCAE6DBAA276909B7FD0DDE628EDA07664E10EA22B981ED586F81FCFCC8401B69321E7CDFA7F086B9F1C92D1F1B2D5F1938F5E62D9DD10E1ADD84377A9C79D9D0908E77F230A2D564B7D38AC0934269F163E05376A722B79612B834A0B3DD41BBCEC +21B4BF72 +FCFF1922CEFA05FB1118B84A9EA4 +B7C4250DBB145BD25BBDC0AAC026973340A52E857FFBE7C26C143FFD535A1F93E3B4CD4D1DAD1DF20F9305F93CAFA062AC3AD6FBA23A84F94004CAD8D496C026E1AE9C308C18BBB055FDEDA1463B4DA096D419818F4A065B4DC1D9066A24DE0C76D08B32186B021FB2A3681897DBBBF2F321513C6AF127079EA9E1113ADE +147A +A4DB7CCF38943026F32F620484D724590F7DF6E25133980531B545 +12AECB08 +ABF29CD41C22112912A10B02C5AA +368E0EA4DDAB05E76641A14FA10E65FA3F8996977FD0AEDE15A6CE2BFB9D092A64F81E5630EB814E7B8D397B0EE4E20732A7E0714C1CF067009D1A2B99026C0B3C396736D512C8DE63A725F9A20F2B88908FD0748E374D86A9753CF76087CD5115B23E361DDEDEF4B8E38CB1FA4122E4A0BA5E0651AD5BAB18 +80CFEA59 +9C68848B31905E38A5EF1227A012 +3488E56117CC6CB707B29A031AA2FEBD41E2B082FE63ADDFDAA461E88AAB7955A2278B62B44632EE744A67C97ED915EA3EFAE57992CA2205A6E3BE27115628B5854571BA72E3FEA568B362CACD26BE36EF60683DB51258A5C1EE9928DF56C40EB2EB552B9D +AC3A194D +96507A2EAA3544BE18D59F538634 +EEF10C25BA62E7299185920D9879AD288B0C42158BB5BE6B90E17BB2A6AC8B3E0270FFB306D369140048ED7405A7A52F37AAB56E68BD29BC82ECA1DE877A407A5A11EFC83202A6950E8A83C96B1F3B7F3AEAF762BB3CD163467809B9B0E938B029CEDD2A8585B66AF2A31EE75C5B64627C3F48F62E1C0BFA74323493BE1E +B499 +81C8539BA89822BEABB993B70965DA01A2684A713D19823C30EDA9E43EBDEB22E6F5BADCDE03221112EE317C911AE2E300348AE224B9E9E4CE5A3CE0B83C0E64030F044FB9F678F6FCF30A +B77BA8E5 +157D851F3A35FE2FA3181C7F09 +44360D3730264C394517D4522DB88EF766AAA2CEA9D1C2C8DE050C527DE114C88EA7F76F902798A3A01746C28DB9208F31964BF86EE13F1087008341E37687DB3899F1EAF58882657BEB5C72E7E208062852D794BFEB1E9378674E23DB17AC +7E4505C2 +D0E35851C941A35C86BD9E23E9B0 +6A948F4626120FAE7420CA5144471BF55586CD13E8863A5F06F9AD34C72D97F71687DECCCDA606FB23D2B714282204A387EE1C7D255E5ADCC5E9BE1394900B455C3159F4CA84C8CEB89C99C8449B4BBF02C75235D79055213CD5CE5F1819B77D142F661F668CD6603D834E90A2F71A2A1B0FB108F5CA57DAA32853459087 +BFD2 +17293D2AB6DC7255898ECB5CA83E2854A9F8C95AAEEBFA068E1665E451B8F1D9714D26765B027E4550BB +85E85DDC +2F3588BCDA5C92E1B57E3209DF +9F8156773430213BA000FDD41F0E4821021104EA0EDB4FF105C3B48E43EAF1E0A0F8BC95DA5A319CDBA3284071DA57E2539CA15C3C492B062A02258F52581C944F999627E05BC56DF05250FCB92361DCDBDA542E2E319262217344 +18F49469 +77D84D6D24701E489C4B5ADE0940 +2C8FFBF20F2B3AE4465E86D10FE1F804171608C7DA9F007BFDE365498CE46855CB56B626E5F17128378356A9A4B52DFC2CF3A040452D6FD1B1D7F3A2D167C8087A0DF5058EFB901A2E38CD31BE9421B6E50E67761417CA333AD3EA3F87AF4DF26DDFED371481A4D4A3CD24778FF17975B002FDAB7FF3 +5E5A7C12 +6DDF2735B8CCFC0B291CC3D8A8 +E589C4A440A08A0C4027F20C84B922C6CCBF022D505ECBFF766D3F427DB4DB5ABC491815E98850BFB42363701F2F250AE921234DB31D0499A7A88F84625F6C5CBF17E0BB254F88992C4DD53117335A5B6122C8D71B6605 +20F9D31C +F3E9469888D22973FD7CA64CC2 +F7B1F429029D1521C0CEE5780EB70A0E0913C62558D685DB64A5F0DD6A9238CD95EEB16FD60CA24E754C2B92001DBDB1F6D8F8308A9D84EED47225A618426A86A0B7AC914155A4CE3F863CAEAFCF5772909EE824115A9DA1935D +53B39ACF +5E7808C2A94490CC461528BCD3F6 +C1BFD503925893AE086DD816EA5AD7E63E2512AC18DF719ED3329D01C237D2D8ADBC0E67C7BFE6C94A5786EA959AD4F8009E5C6E63077E17509AE622D2850CA6D70AE00501808BB467A4415AE977A733628FBB02B4D1D370864409A3AF25D1CE8D194686CDD930E8F3CA2B89305490C76E73BABEFBCC4E1415CAA28AD3DA +1F77 +791EB50AD51126D17C +A1EE2827 +374303F9202BC3AB42A2240C096E +A124FDA5389C8566 +6EF17AD9 +A3F7708F17504F7E99883788B70AD405257FB348B54F5A42513D55C8DBAFDF6BE8F9 +A39CFD45E209DB2901D602E67837A30DEEDBF98C5326CAA3592CF46F8B03D7F4EDCFC78403D0 +24DBC72986913E267CB32BAB5608C59D3259177A2628C6748438CB +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +%Defining font PSOsymclas +%!FontType1-1.0: PSOsymclas +10 dict begin +/FontName /PSOsymclas def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001000 0 0 0.001000 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 1 /C0069 put +readonly def +/FontBBox [106 45 775 713] readonly def +currentdict end +currentfile eexec +D9D66F633B846A989B9974B0179FC6CC445BC7C8A959A39A32E9DCE7FAEF17EE3BEC9F +50E1A6FCA651FC4B3769A0A91041557502E25A5D6180FE25A3D11BF079E1DF66E54EE9B7C229AF891739707A2A0EC140306B5E43E52B79BFB89E459E50 +6EC6F610A70775A31C460976C4F79449D86E57ACE491E5C6BF20CC4307B1DAF7630252 +E9AF8CFB69B50EDAE9D36A6104AFEF8832F920FD2346B2C7104CD11E3BEE999CFA9F5A +49DB3173EE48D1C82994237F360407B022E0B4 +502E94EA8B493651EF2D03F0B513D655047568325B512AE6 +6AC6F53F3848CF70DE25481CC65D8B1A5793AA +3C4282D111112BEE28AFCA7A3808D4444C4669CA +84EAAAF989219F51AB3476A1B0B5F2246BC306E6 +625C6679C417ED2A8E9BD010DE37D40265074C2684268F16195489648993B9C4D3B534FA887C +DEF605FA87B991F4D20A8F78DACE +5A54C070E03D5C59D9D2D3E06B09CEE028D68B62AB3AEC43C1DD20BA70D288597D9BD8E06818FF764EBAB436723988E8D7CA59E16D39032516BFC5D552ACDEEC6BE938BEF2F43CFFBC811C3626C4DF5F8CF080676520B51C60CEDAD1FE6C92D1431C702174CE517A8FA9377D075A0B6833DAB101DB65397F1419EF5F0016 +004F +6F0824F9657BB4F1C8F981709956865F6855EFAE +9242AD55 +91BBBEE163D844DDA894E13190C9 +2480439E4C71CADA +BD043A9B +A315CAF72652AA7FE6DB2E84D82A6111CE4DE90C02DA0AFFE2620922262A45AB4ED0 +EEC9F4520DD12703442F7D028D4526BD8B771E09FBE11B2749E2D3906894E8D4BFD3F379F14C +3C874F550606965E22FE487B247B5C2D06728490C8F2A3B588CDFC +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +/DPIx 1270 def /DPIy 1270 def +72 DPIx div 72 DPIy div neg scale +0 -13970 translate +1.00 1.00 scale +/wst:dutch12 12.00 /PSOwstdutch newFont def +/wst:dutch12b 12.00 /PSOwstdutchb newFont def +/wst:dutch12i 12.00 /PSOwstdutchi newFont def +/wst:dutch10 10.00 /PSOwstdutch newFont def +/wst:dutch14 14.00 /PSOwstdutch newFont def +%%IncludeResource: font Helvetica +/wst:helvps10 10.00 /Helvetica /wst:helvps ILEncoding 0 declareNFont def +/sym:clas10 10.00 /PSOsymclas newFont def +%%EndPageSetup +GS +0 13978 10801 13978 10801 0 0 0 clp +wst:dutch14 SF +0.00 0.00 0.00 1.00 setcmykcolor +<1a2836322834290f011101122830262b2f24342d01293134011928243537342c302a011a28363931342d011c> 2207 558 0 7384 -1 s +<28342931342f24302628> 7375 558 0 8593 -1 s +wst:dutch10 SF +<0a0e> 9346 13385 0 9522 -1 s +wst:helvps10 SF +<4e6574706572663a> 1322 13267 0 1949 -1 s +<205265766973696f6e20322e313b20436f7079726967687420> 1949 13267 4 3868 32 s +sym:clas10 SF +<01> 3868 13267 0 4019 -1 s +wst:helvps10 SF +<2031393933b131393935204865776c657474b15061636b61726420436f6d70616e79> 4019 13267 3 7133 32 s +wst:dutch12 SF +<0632> 1589 1431 0 1882 -1 s +wst:dutch12i SF +<03060b0c0a0402> 2033 1431 0 2642 -1 s +wst:dutch12 SF +<352836> 3177 1431 0 3432 -1 s +<00362b2800272c3428263631343a00392b28342800322c32283500392c2e2e002528002634282436282707002113282924372e360f00353a3536282f002728> 3432 1431 10 8825 0 s +<3c> 8825 1431 0 8895 -1 s +<2924372e36> 3177 1676 0 3595 -1 s +<0029313400362b280036282f3230242f03040026242e2e22> 3595 1676 4 5768 0 s +<0634> 1589 2023 0 1847 -1 s +wst:dutch12i SF +<0c060f040c0a0402> 2033 2023 0 2712 -1 s +wst:dutch12 SF +<352836> 3177 2023 0 3432 -1 s +<00362b2800342833372835360024302708313400342835323130352800352c3b283500363100362b280038242e3728033504> 3432 2023 8 7970 0 s +<00353228262c292c282707> 7970 2023 1 8895 0 s +<2113282924372e360f> 3177 2268 0 3998 -1 s +<000a00253a362822> 3998 2268 2 4661 0 s +wst:dutch12b SF +<07> 1271 2754 0 1399 -1 s +<1619120005> 1389 2754 1 1872 0 s +<0f0a00050d09000e> 1867 2754 2 2808 0 s +<12181c121a1b030e> 2804 2754 0 3596 -1 s +<121a1716151a12000d> 3592 2754 1 4492 0 s +<12191316191410151112> 4484 2754 0 5526 -1 s +<0b0c0f06> 1271 3177 0 1866 -1 s +<04> 1870 3177 0 1928 -1 s +<00> 1928 3177 1 1972 0 s +wst:dutch12 SF +<0015> 1972 3177 1 2147 0 s +<3134280011> 2139 3177 1 2648 0 s +<1f1900111c17> 2628 3177 1 3384 0 s +<00362835363500243428003031360026312f322c2e2827002c303631003028363228342900253a0027282924372e3607001729003a313700392c352b003631002f282435373428> 3384 3177 13 9531 0 s +<362b28> 1271 3422 0 1561 -1 s +<003228342931342f2430262800312900263130302826362c313035003138283400362b280015> 1561 3422 6 5017 0 s +<3134280011> 5009 3422 1 5509 0 s +<1f1900111c1705003a3137002f37353600342826312f322c2e2800302836322834290024302700302836> 5489 3422 7 9461 0 s +<3c> 9461 3422 0 9531 -1 s +<352834382834> 1271 3667 0 1820 -1 s +<00392c362b000613131b23151b1d1400242727282700363100362b28002f242d28292c2e2807> 1820 3667 6 5806 0 s +<110015> 1271 4013 1 1618 0 s +<3134280011> 1610 4013 1 2128 0 s +<1f1900111c17001d> 2108 4013 2 3089 0 s +<283337283536081d> 3081 4013 0 3893 -1 s +<2835323130352800362835360003151b1d14231d1d04002c35003828343a002f37262b002e2c2d2800240020131c231d1d003628353607> 3885 4013 9 9347 0 s +<1f2b2800352c2f322e28353600151b1d14231d1d00362835360026312f2f243027002e2c3028003931372e27002e31312d0035312f28362b2c302a002e2c2d2800362b2c350f> 1271 4360 10 8104 0 s +<02> 1398 4706 0 1504 -1 s +wst:dutch12b SF +<000316171b0315121b171219130315121b1712191300021b00> 1504 4706 3 3692 0 s +wst:dutch12 SF +<151b1d14231d1d00> 3692 4706 1 4791 0 s +wst:dutch12b SF +<0208> 4791 4706 0 5133 -1 s +wst:dutch12 SF +<00> 5133 4706 1 5186 0 s +wst:dutch12i SF +<0b0408090d0405090c0d> 5186 4706 0 6145 -1 s +wst:dutch12 SF +<16283428> 1271 5053 0 1736 -1 s +<002434280035312f2800312900362b28003628353600353228262c292c260026312f2f243027002e2c3028003132362c313035002432322e2c2624252e28003631002400151b1d14231e1f1d141119> 1736 5053 13 9531 0 s +<3628353607> 1271 5298 0 1648 -1 s +<0624> 1589 5644 0 1871 -1 s +wst:dutch12i SF +<010107> 2033 5644 0 2303 -1 s +wst:dutch12 SF +<373528> 3177 5644 0 3479 -1 s +<00362b280011> 3479 5644 2 4014 0 s +<1f190011> 3994 5644 1 4538 0 s +<2724323624362c31300018> 4534 5644 1 5581 0 s +<243a28340030372f2528340024242e> 5585 5644 2 7026 0 s +<00363100283026243235372e243628003224262d> 7026 5644 3 8825 0 s +<3c> 8825 5644 0 8895 -1 s +<28363507> 3177 5889 0 3485 -1 s +<001e3228262c293a2c302a000b003134000c00392c2e2e003a2c282e270011> 3485 5889 7 6163 0 s +<11180b080c0500243027000d00392c2e2e003a2c282e270011> 6159 5889 5 8441 0 s +<11180d07> 8437 5889 0 8895 -1 s +<2113282924372e360f> 3177 6134 0 3998 -1 s +<000d0006100011> 3998 6134 3 4780 0 s +<11180d22> 4776 6134 0 5250 -1 s +<0625> 1589 6480 0 1879 -1 s +wst:dutch12i SF +<0c060f040c0a0402> 2033 6480 0 2712 -1 s +wst:dutch12 SF +<352836> 3177 6480 0 3432 -1 s +<00362b28002f282430002537343536003624342a283600243027083134002f2c302c2f372f002c300037302c3635003129002d2c2e31252c36003224262d> 3432 6480 11 8825 0 s +<3c> 8825 6480 0 8895 -1 s +<28363507> 3177 6725 0 3485 -1 s +<001f2b2800292c3435360038242e3728002c35> 3485 6725 4 4971 0 s +<003624342a28360024302700362b2800352826313027002c35002f2c302c2f372f07002113282924372e360f> 4971 6725 7 8895 0 s +<09050922> 3177 6970 0 3511 -1 s +<0627> 1589 7317 0 1882 -1 s +wst:dutch12i SF +<03040e0c0a0402> 2033 7317 0 2700 -1 s +wst:dutch12 SF +<352836> 3177 7317 0 3432 -1 s +<00362b280030242f2800312900362b280011> 3432 7317 5 5056 0 s +<1f19002728382c262800292c2e28003631002528> 5036 7317 4 6799 0 s +<0031322830282707002113282924372e360f000827283808> 6799 7317 3 8895 0 s +<24362f22> 3177 7562 0 3594 -1 s +<0632> 1589 7908 0 1882 -1 s +wst:dutch12i SF +<0c060f040c0a0402> 2033 7908 0 2712 -1 s +wst:dutch12 SF +<352836> 3177 7908 0 3432 -1 s +<00362b28003228242d0025243027392c27362b003624342a283600243027083134002f2c302c2f372f002c300037302c3635003129> 3432 7908 9 8426 0 s +<002d2c2e31> 8426 7908 1 8825 0 s +<3c> 8825 7908 0 8895 -1 s +<252c3635083507> 3177 8153 0 3690 -1 s +<001f2b2800292c3435360038242e3728002c35003624342a28360024302700362b2800352826313027002c36002f2c302c2f372f0700211328> 3690 8153 11 8825 0 s +<3c> 8825 8153 0 8895 -1 s +<2924372e360f> 3177 8398 0 3653 -1 s +<00090509000610003028363931342d002435352c2a30282722> 3653 8398 4 6058 0 s +<061c> 1589 8745 0 1894 -1 s +wst:dutch12i SF +<0c060f040c0a0402> 2033 8745 0 2712 -1 s +wst:dutch12 SF +<352836> 3177 8745 0 3432 -1 s +<00362b28> 3432 8745 1 3774 0 s +<002f2824300025243027392c27362b003624342a283600243027083134002f2c302c2f372f002c300037302c3635003129002d2c2e31> 3774 8745 9 8825 0 s +<3c> 8825 8745 0 8895 -1 s +<252c3635083507> 3177 8989 0 3690 -1 s +<001f2b2800292c3435360038242e3728002c35003624342a28360024302700362b2800352826313027002c35002f2c302c2f372f07> 3690 8989 10 8426 0 s +<00211328> 8426 8989 1 8825 0 s +<3c> 8825 8989 0 8895 -1 s +<2924372e360f> 3177 9234 0 3653 -1 s +<00090509000610003028363931342d002435352c2a30282722> 3653 9234 4 6058 0 s +<0634> 1589 9581 0 1847 -1 s +wst:dutch12i SF +<0c060f040c0a0402> 2033 9581 0 2712 -1 s +wst:dutch12 SF +<352836> 3177 9581 0 3432 -1 s +<00362b2800342833372835360024302708313400342835323130352800352c3b283500363100362b28> 3432 9581 7 6987 0 s +<0038242e37283500353228262c292c282700211328> 6987 9581 3 8825 0 s +<3c> 8825 9581 0 8895 -1 s +<2924372e360f> 3177 9826 0 3653 -1 s +<000a00253a362822> 3653 9826 2 4316 0 s +GR +eop +%%PageTrailer +%%PageResources: font Helvetica +%%PageProcessColors: Black +%%PageCustomColors: +%%Page: (20) 20 +%%PageResources: (atend) +%%PageProcessColors: (atend) +%%PageCustomColors: (atend) +%%BeginPageSetup +bop +%Defining font PSOwstdutch +%!FontType1-1.0: PSOwstdutch +10 dict begin +/FontName /PSOwstdutch def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001000 0 0 0.001000 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 1 /C0032 put +dup 2 /C0034 put +dup 3 /C0036 put +dup 4 /C0040 put +dup 5 /C0041 put +dup 6 /C0042 put +dup 7 /C0044 put +dup 8 /C0045 put +dup 9 /C0046 put +dup 10 /C0048 put +dup 11 /C0049 put +dup 12 /C0050 put +dup 13 /C0052 put +dup 14 /C0057 put +dup 15 /C0058 put +dup 16 /C0061 put +dup 17 /C0065 put +dup 18 /C0066 put +dup 19 /C0067 put +dup 20 /C0069 put +dup 21 /C0070 put +dup 22 /C0071 put +dup 23 /C0072 put +dup 24 /C0073 put +dup 25 /C0076 put +dup 26 /C0077 put +dup 27 /C0078 put +dup 28 /C0079 put +dup 29 /C0080 put +dup 30 /C0082 put +dup 31 /C0083 put +dup 32 /C0084 put +dup 33 /C0085 put +dup 34 /C0087 put +dup 35 /C0088 put +dup 36 /C0089 put +dup 37 /C0095 put +dup 38 /C0096 put +dup 39 /C0097 put +dup 40 /C0098 put +dup 41 /C0099 put +dup 42 /C0100 put +dup 43 /C0101 put +dup 44 /C0102 put +dup 45 /C0103 put +dup 46 /C0104 put +dup 47 /C0105 put +dup 48 /C0107 put +dup 49 /C0108 put +dup 50 /C0109 put +dup 51 /C0110 put +dup 52 /C0111 put +dup 53 /C0112 put +dup 54 /C0113 put +dup 55 /C0114 put +dup 56 /C0115 put +dup 57 /C0116 put +dup 58 /C0117 put +dup 59 /C0118 put +dup 60 /C0119 put +dup 61 /C0120 put +dup 62 /C0121 put +dup 63 /C0122 put +dup 64 /C0127 put +dup 65 /C0262 put +readonly def +/FontBBox [-25 -256 978 766] readonly def +currentdict end +currentfile eexec +D9D66F633B846A989B9974B0179FC6CC445BC7C8A959A39A32E9DCE7FAEF17EE3BEC9F +50E1A6FCA651FC4B3769A0A91041557502E25A5D6180FE25A3D11BF079E1DF66E54EE9B7C229AF891739707A2A0EC140306B5E43E52B79BFB89E459E50 +6EC6F610A70775A31C460976C4F79449D86E57ACE491E5C6BF20CC4307B1DAF7630252 +E9AF8CFB69B50EDAE9D36A6104AFEF8832F920FD2346B2C7104CD11E3BEE999CFA9F5A +49DB3173EE48D1C82994237F360407B022E0B4 +502E94EA8B493651EF2D03F0B513D655047568325B512AE6 +6AC6F53F3848CF70DE25481CC65D8B1A5793AA +3C4282D111112BEE28AFCA7A3808D4444C4669CA +84EAAAF989219F51AB3476A1B0B5F2246BC306E6 +625C6679C417ED2A8E9BD010DE37D40265074C26842243E0EC59344CEF369650A037B4383B03D6 +24C306E87EFDD4775EC78742 +FEFCE44B765574466C +D1AF7A82 +CFE19FEC07055171803BE35FB61F +DFA5A4C739A4E3957EB7C66233844AC51A6A91B45B75E6AF1F76779A4EA39D554C671F039F6EA0902EEABC13363BDDA5101CA12BB8156EEC5AF0BF9E6FFD41E3E8297895E1554F57314DE5E5E70C32DA47FD30A8525D7EE9C60607EDB6FD9F816BBA9417276F85 +60F5DDB4 +A3948B33ECD70515EFB0F25E7766 +23F737A06578D2C501971D21A1AD0DFB46CF5287869182444F411FF11823026670B907FF382665F39F94C09E0E1E76DC0B02A4BF09FB8F2E5BE909CD4C41833EB22E0FEA75A40D35D7700DE134E6C556D6A7CE512D6327F1F175C4A19C0F64AE61E00DCA03F8F5E64A5A235E5D73BAC487E3CEF5CEE4A4CDE1A68DBB5C77 +212D +08FBF8079BE5531B761799E3 +CAC71CE7 +915BC5DA0DB17FFD4ABDE5111A +09F2F70F6106F3F60ECC4242AE99DC465FD41841E9B7525D5C4B32CEA4DC6FDF1A2165BBFA8A4EF1128FB2FCCFEC878D74E59BD4A4F9B0BEDEFCA9DD265F1FA8 +BFB5B1CE +705E8E3C5B602472007D2FF909 +3CBD678801F52A32B28EDE4923024E25A8795676CC594BC4EC8934E0A7DB874AE00DD507DE5313D4B2DC7A11633AC15E996999BC8CE501DE5DC11EB46F4396 +2F99DEEA +EF2C357CCDDD0378B6012FF4A76D +691AAD979E98DAEFE0EA34773FB3A8A0F99E66F7D23C2FAF079A800599152FBC9B2958DB033CF1652F776E70CFAD3DC83934C124CC198743E162526BC157439B951B466A295405F97F89E4671CDCDC66B88BBD45983BE0A7AA6757EDD5F52352B46C4D3662A742AE57439AED40E04DB6F4E8629AF77F0AD9E3D6F40648BE +7C70 +9F970C57E256DC30909993D74CDBB72852A70FFD4EBCADF899B77E9693DF9D5E60AF02A5A4281A168A93C641C18564E8C85E829CB3A375E4DB445BEF408C00 +A63FC651 +CC1BA35F263228000C93B2E5BB +2497BD9BD87835A2B5E1B2B69D56334D67B9E3CCF6FE096E390AF8B7196E39422491E55B085D6778F84F72028B5721073601C4F38494D0E8A5 +7115FA9A +384C306167ECAC2DB743CE5C2E +92F4A9C7702057B326B93E35D5C3A214DD84DDC66DF51F +003AD4C9 +C579D45391B169AB64508A7BD6 +8F0D68963A879A991FC02521FFD47FD642AD5961871016FB5BBA7982D90270 +1D45C8CE +6D9513EA4C408A8C8A430846E1 +37E6CA0BF74FEF805C6CDAC484A97489F7EFF21B6CA4032D5C8CAA0B6E95B472A38C07670E0D639624D6E6CC22747C2FE524AC7239C57DA96DA4682BB8990957CBD2222133E0B57223EE +0C6E8F54 +C559649E9ED30E52B8254FC47E +726FFAAEF25B0E00ABD346A53C875D2958B8A1567E8CF9E7D5D5DE18FD7A580F625B033381D679DFE013E62F4C4D99C0132365C615473AEFEABB03B1745D9E +29CF3A97 +3DB1D64FCCD3AE3A400BC8DF60 +00D7A571CB55120BA1DC9AB207DD1F03AFF954183785DF8915A43B4DB0EBC0227522EC37E08D7C4C96CFB65E9F208F9A2D7845A5A45B752EBDB7F4AD6519047B9FF060BCD8C933070F6543F53457CE30940194F110470B46FEF2 +B90BE74A +2F05098B106377C068DFDE675D +073F4152DE59E0E06C1E44A07DD44C687D4494EEE04FD03798B4382F0BAA76B96042893B07B3411CBADF27BB70E47BAE8132CBCF482303DE2BB8 +6FFF5D88 +C9C5B8E2E6441B0BC96D1ED180DD +93E65C3EF19787680DCCC1016CCDAC21FE29D34DFD71872D43C2FA22AA0117FE6B0B5104963D03507BCCD3F8DAFB4D4F10D91E872353EB6C3723A274BF8465F074E68E48AE8FD4D1475CB0209ED7AF9E190D0A95A065B1C51C9142342C45319CAC9D4259F1 +0291C032 +C5F6B74BF9DE601DE36E65F4C5 +01E2088521518AB14B5A342027B0E5CE5F41BFC36A5C98E63470E192076DD526DBF923F46390F9C432D2CC753004C30613BB1A34D69A +A1ABFF3C +0F9E2AF45CD9DE6016A7E23217 +6C51FAE6233DCD7A2EBE98C5BBCAB4C5510366C63AD2D3B13DEB091049D031D0947D3A92 +29FDBF54 +81B7B4A562BD5C2A0A3B924460D9 +FB6C2AC201B78E46ECD223ABD664CCD42AC4C191D0ECD91AB487B4BB343D4CABC33F1D6909114CD9B34CA1031E49395F6459AB8261755851252A1C175690EA7B3171AB79BE79384A5AE00C141354F44EA3B150F95FC65B271FA8A516A0A77A239F6D96BA6DDABD24E3D2FAAE773C1251B98E8B +9F06711E +407A0C806FBAB020AAF1881EFF28 +DFE535D6570641BEDAFDBF8B3C5716F0F97B641BF0418463136B0BDEF1F1D704553F0DBA3751631DD37F0F81BC36C265A8F684D05F13A2E2C8D33371F70EAA4D4F33D1ECA0012C68D4092C0F519A4C328D08B818BB0FD69AE1B9CEA473B34B58BD2E2FFEEAD06146C2DC5C3420729B2AE8933E6767E22C1804A8F4D9621A +B27D +75 +F3356366 +9BF10C19DBC8B2FC940BFB314E +1BCD175935C1372C10ABE3700683ADD76D374FFE7C7C26D797796221778E42F1F21DAFE3C3890799298B946DBD2C5811363AD6511FDD4D910D73D6A9A18ABBEF9E5162B328A79AF5B115B0BB0DDA919E620591EDD8141A739DE1412743A03BE3E1 +D8D8795E +A34BC69BD078F02A86986477A04A +0A7893B24DB05CECBAE5F0FD237BE889B61E2D9792075DB2FA8B288C6D47DE7BBD094492F3A9440FC17A90050AA07179FF39FA82C1F081B84BA241A6BCF6A03BF4692E865128245BBD06C6A4293811227632220A5BBE37AB6014413A015C247AEBCD5E365DA5333C9B5ED9EEF4E6CD414FB81CD2A2A05B75F130EEE81755 +53B1984A +916F62E19DB2651D38B49A5828DD +1E2C9F43621FAC84BE35C2DAE94CCC3A24FE89513F255CADB973C43989E6787A870A23667C4605280DAEB082BFECD2180C0B8EA3F27A7A0B1E2701484E4DD983331E57F520E23C1D9CE8797D9D93A4112EF9F9EC5C08EDB428BC954BE42C9700EF88AA78C9453C82F2 +53A6C805 +14371B010A85B57CFAE083860170 +9849377AA723B558B7F6EEF593BF8623AA2607160DAB181541879804C3DAFBDA2088AC9A77034E8B0B5E2528423CA0C68B6CBF947C1D94064E03921289B7AA0315A06FEE6E2C4BDF1D2C28B392E47510E4A41075F20D34E8FFF369E6DC732909DD70C5534D8B2ECDE0B48FAE6532689E1728D3D0D8D29105B62D +C137C25A +18D43BDF2C354EBA7D0EF6FCDFB8 +87A83C426D2CACED0E3C030B31007FE19F45495C7CB5B89990845E1692D6AD40DDFA64BA61C75650987C6CFDAD57901A15432E32E5CE28186854A9169F16892D19A3DDCCB2D78623C142FA1BD9E863DF462D1CB6521E5C048412901C271F27234E35BB18D47FA415B90E5CEC194EB781639446B088503381255738110476 +E987 +5F8E41697F7A2215D7B952 +55758E43 +7164B211E91E72825064EEB60A +467F7DDB1B04A030374C1AD59A43FA09C8F60715DD68258642F1ADA54646B4D252F3C76E73BE7ECFA69380E03064B899903712426C388000BCB392 +2819182F +031846D14861B76878DFC36995 +ABA4380389D6805AC7C2394B01402975F843294A0DA920D8AB45ACA5BA923E57903E6F6F33B65320D5971FC9578B1CDA8B542B5149DD0CB43B3EDA5E6112F5EEC359569F4F7389 +E28F0A80 +A9C19A7E3DEFB1C6FDCAD702FA11 +B262ECE37354CE2AA04D43795D2927A85BD37830FBDA666279261A9A7F54BBECD389358E12335FDB86C6B658443535088BB9162B956E18EE16591901D3A105A5588A80014F1CE5AEC7285F1AD8F113F3CA235FD623527FF07424F1EC0158B929A940BAF3C2FC8ADD8A453E77C0F2A7 +68CA5C0F +1E7AFE2CDB3F3E2F31950A8F3D +2E43029030DA88C57C16234C6EFBFD7597BA9BB22A9B95A625D16F3FFECEAF6B58F109F6D135AEECBC6D61D9DB13C26916AE6173DCDC1992C97B237705E6928A051DDE166EBA17A3EAC4CE4A1087FE28965FB857FE2E24B07183ADDF +17C20B9D +949B8F8EAD6CB5E48A69FA557D +D87D25E88D840731DFBFE2FFB4847E18028F2CD630CF9042F99A7E9A3755A2918FA1BB7EC5432C4FA4487AC40318BE9477F0D71BBC31DAC2DFFEF62087B4FE1DF5C4C01FE701F113B68D1EB6A1C45EB43D9190 +61AEAF88 +FBA4F46A12AA98EA999E2571426A +9D9F41C26CA5683ED3394EC16C69F95CA3007988CEB27F00AA9B59B75F086D5EA5BF6D35394C2F2821E494B8802822BB9B1278F38BAF5CEC9051FEBA15A1837A2D33099428170216ED68B1FD00D1D47F39C0E66A0A52B1D097270BEDFD533131993AD784E0A74B837D6B +DBB1F42F +DEAD459BF891E30A7979FE7DC380 +7891D0390AD5E6AF55062F888565B3AF195929430BB4295779A1228FBA6C7F65F2D4541DE8BE704464348DE855A4E0CA9FE219FAAED8915782334EB5EDE6F54AB949382EEACA52DB0B0A31874B72021E3BDE6037D87F69E87E057E5FAF5D1481C8AEB0BF872153DA2E7E51F2E932F5BAFEA0CC42DD532F44D8738169505A +30E8A3E9 +DEC0C83C1673B5E0A04A890380CE +A0B0E0CD31F1CBB5B1BD707B80094BB16650D65EA3E4B46ADBD80CFF6821E34008CE27C7BDA6BD8B556F4A5C74D232E7B67829230F862A88B024DE39E1E0323422CFD2D3D9C85BD4944ED3BB17866826F1B0E4C0A922374B208A899E547C4C93CB32FDA41CE13BC6F8B3BD4C62195D7C0362A32C4F798655B1C816592FD3 +7FD0 +319526 +14562C1B +0313059C57933C19B129297E4E +8AEB9E340635728CE6EDE55F03B39A6A5004ADB4DBDEC2567D2AB8A8F2B5670452DEEB8C9BAE37CA0C6FB9058A228988920F29A77FF6B689E9CE6FB14E22C4ACA6277C71CE4A7FF4A9F56556A844801AE3 +56616753 +5A2A04A8D80B75556B139101F88B +511FF8386002AECE496659FFAF399769FCCC7256F74A0C8A2AA4D4B538DA18FDAF7E8CBC13D1D5D533F3DC36F2546D3F671CC1092DBBCE3A3A7BDDC41355A1C782A7253C09776B0A8D0B9AD1ED3603195AF934D48156F9A5D59ED5DFD029A514E86EAC37 +CC694902 +104DD55A380FFBB7A73D87CFD96F +84E221791BC984D6695ED130D60515E2A899AE182FC0AE865EE15236BCF60BE9ADBF87EE2880B2D2D788F6917C5A7F265D125278AD344B033F1D8CA2D2518F7D3909174B1E5C0B8FDF20FD2C67C302E1552C4D0FC98B2D27F4A6B63C3DAD171BBBA5CF2AB83FE64CDBF59B959E389490834577A1A5FD23FD4F61173E226F +6E95 +D90E2D265CDECA3B2FD0AB5BC7FDB6BB +200C4A73 +D401B0C1C7F9A3B21861160F3F2A +F7CD4035B573284E897D2B238FF5AB50833AFD00AEFF53E87DD32BE7A2C295805E014D82663E5AE38953B5622F779AF733547D5BB2CC7916D35D4E6ED2C5EBA571A33EB6F872A7C33CD06EB87CCCE38C4F8B1E5CB039F3432C16F6924C0B6926CDA0AD0445C8F66CDAD3F5B09AD628DC3840ECFC9AE888B212CBC7E9571C +2AF5 +AA9AC994840FC12D172CEC10353FD53EC64ED29EE59E9CB978466975FA06162BD3C00C58583346 +F86B2DD2 +7D92C6DB6C369227F3366557171F +2F72AAE31EDB7F2415A312FD130A27593C761FAA8437F71B85C9AC3031A0F9C4313F1D2F050FD97B50849BB446D0AD3B35B4B8416D88A6E873A6DE1AC4FFBC54E14AD88BE807FB777553E61514AA7C9FD9B783FCAA820925FCFB73D8B025A00DA2442041AB51D8D712BE805D58D762875CECA1 +5209787A +810DAC93C3972B55459D19F939 +C8C597C31A5612F2389378DBB8AD920547B45AB9CE2F +DC0D3E90 +A6E4436812001D37C96BCC1E5C +AB15FF19B44A4B39D85503DF02447A9ACB45BF8AC9DEE5F93B9705C3B29407DDCBE68BFA2280379E08B1DCA51085C04972A40ABF55AA3653C708 +67B18C02 +FACA5B9AC12E97A861B3727CACD9 +3ECB15809C064AE19422D373F3CF62C66B87B6A5DB38FA709CFE2DA40DAB7C7350109FEA44ACC5BB22E8232BBEEFEC13372866A5D7F0EC7D027CDAC2CC8E08C056C26924D4AABF9F05336E2FCB6FF171D94A0A3F92E443F096325516BE835D1961FCE0698A6FFE2352F0AE87580B0C126326094EBC302B897DF8746F059E +4059 +7EC540 +61D813B1 +E1D1835FF17D820CF2D1AD8EAD +CFEE7E92E35B18A436F80A04140ABC18590A787E449BE5919BB30A416B7E1475825AF83A2342719C8675E9522319BD428F252132A97B71BE03BD51A18B95506E2B3FF16CBD5536E69E02E884468F172354D835EB42205F3D +061E2100 +D0480BB2409D83F922D896AC09 +9E3A80CFA083D47F4E9ADA805DBF8B6E65B10F595C96ED3F834CA8CDA98A7585169876D4B8E9B3132831681F15D9A28BBA65FD197C0795D324646A8A029D5198C980D136DE0AC87B80DB4602F302988635F0 +B3F6BD82 +EC364DC6431047065A254F03427D +0C1ED063402ACBA889B597FF2980397AC6E05DE87ED8EC8C3229F681E6BA925DA77555DA0A423C718BB9C0324AA06A56C8B1DA1A71C364EFEBD807F5E7FFB6D4DCF210EEA01EC7396FFB55CFFE7712D36FAA51E97F3CFD5114B6CBDFCA6412D8A0D1CC089234B64CF25A6851319E +97DF1ED8 +9EFAB5C52D8B3EC7EC65F785A5 +18971A3BEA057ED878CBEBA92E60701B94C75BA99C2A246EED1B17C786FA725DB11EBEE778565C98C9A9CCFE7CC2AC2949AF9F74272D3FA1484FB5E0944427BAF8712B1B612EB7211897590BD20249E667C244740FBF0AC4BD +26957268 +215C726399E68A17DEECB58F80 +95D33B830345CD7438AE989A43F1357C31DE069C54653E77AEB31B09AB4D313B7C0C668FE9FB21D8AF789066B6B00384A758B1EA42580A9A0169B2832004DF486546892714FF07BDDC830B24A967B7DF48767169542025B59D8FEE44 +A7E78308 +BF14EB6776FD8BAAEAEC31351C18 +F0C93A1B59A8CBCEF9473EB701D9EAB4FD92A372EDD70B88E90C07ED557CC2BF9D4FB2ABF5E9E38BB083F63FE587719EDCC467FAB8CD0A606051CE7E2AB83F4666623C1A03054B38E20D93B64915486DCE181A38EA78C026C26B5033593B44D4D8FBEC504FB5D89B7F9C9D6E6B2A2F950E2C0FE55D86B70C4377698447F9 +EA46 +3DE84857E620A3F3F33D9CBBB93FE07E63FE0C618DBC3A98BE7DA75EBA44A34026F48D2924FC3BD679CCC1535B9D83 +77B167F3 +1F4C39A6A471C66ED8BD5ACB8BF1 +1769DABF81141B6853776AE9F1C34F6F6BD4EC50B55C1A8334A21FA522017C451F0FA6BC82B0D5A50C73E7EFD3957A0AAAC203573F3C56F60D84D6238EC72E7919D91CED7F0D07D21064FE42365168DD1B4BDE8B6EE2AA04ADFFAB26C5333FB1A5B470310AE128BA6E434161AC +6E542852 +EFD9FE0F0403753CAB4EEF3435 +43AA94AB86CF53ADECF6CBB381EFE6214DBD1EF42949ABADA39DE8D3FF57E1DA3D1010713D5CB1465AA3830A31CA994BB3B4B583BEE6C1A963C9A67E17707ACA968F063F61472ACC4B5403EC07BB85D0 +3BAFE591 +27DBAEC25DCA9BADC7EF2A5B16F4 +212BA51329C152BA413C9F0546065D15025BB8A0F81C2A64CB2C81EE6F9BD2739A3C4FE274EE462C544462260B786FB6CD3A6AB4867E81FDBD1CB3A7B311E94A43C73C56E0820A7C92D54E49F3823C60E45D78B6B48978C9A2E976E6C4B38148653E88616EE96E8A58E2F9A16CDA114110F3625D3218E028696809A9C954 +4D45 +5FC50C5100EDACC7C871C4A6F2925782E10506AF2CDB90B8214E1C22A9AC2C113469D9 +96A6B2DE +2F867A39378AD587490C41EB82 +41AB194C9C79F6C76CAE74DB8DDED99B37A17E8A4C25D83979AC8ACDB2BFB5EA144F23708C68FFFC6EACFD4EEDE5A9FED6B320909C2B +8986FF3A +4822504D62A16020E49099CD0635 +E33CB76EC98203C4223876FB7872C584112C6DBA6238E89D867B93A7141DF0BF3096FD8A406796983EA2BE1F0AAC496A042A09E5671B7DC970EEC531BD59419F8A7C8606E9A7B916E7403098DD426F936123884EB835484E3E827020FC5CA585B7A0D69D063F55BD7050E00E7131660F9DC8F40C368449EFD72B59949C25 +5C4C +6823F621B3646F038375D5CFA802D8660743D00188D81371EE10583B273548 +CE5CFCFC +427530876CAFBEE49EE854EC0AAC +8B981AE89C7FC527D7D572A484D6F7785607992C5B16AAFA07BD917554BC9939C28C9A44F85CEED4967030A88595B149FEBB3D994F09F92F3CA220EB37D0A88CF0BAD52DBE98F633053644338401DA319B9EADF22BA360F596491D0EEF182519FEC48888D4B6939F0C6014A8 +39D94B01 +78EB65ABAAB217EFC1E19EE407 +FF50F4D284607BA55C702E491174451334ED1BA4D92F36450C7C6BE7165BDBA86135C421A2E078AE83AC194828DC1CE9108F1DC13EA0031B2FC1A70EAEB2FD08AF2BF6C62886 +91AD8B32 +2C213CCCD89D87195FCF2C1A64E1 +CFAD9C24F5C415DB64E5F7CFCE1C9777DAF54BCDFFBF1B09C4503066B15E1471DB4B345CE9354837AFC50F7CD2C64CD28EFB41CCECB2016BD4EA3AB33293C92D97D8529D66C60150CC7A266E79FFC429DCBDF713ADD640261D64D359D1A16D87D79A122B4F37F6F82A345FB0840A253F9BD99F287CD3EA +04AA6A9D +2A939EE2E20BAEF95F1660B46831 +3DDD88F27DF7AB5A839DFBFA6E8BCE7ED0A76A87B1C532F2057626DCEAAB6E623239D297211CF93D436EF399A169F7018FA40C813EEB7D9BA8A553F2D4C037A167A89F784ABE695B0317169C8437FDBC2371C18E3579A3BD0AC00F5B702843A832F588369D770A189BA8 +20C2CB36 +7DB2E41627082F6914F356294A +FFB34491B7FF78CDF3F2C3F3F9E5ADC0006C21E2066257E644E2E87DB859E1C90F56431D1ED70A22509F9095A52CC664B525E0CE021CA731BC763C1A5CD9F2A42A319A124BB53FAA42729A9E40F76FD617738151A9505B +70A02E39 +96F9817FB6EE3FE17FC509694225 +85DFBDDA141102793899E3D199B23DC95750B7C6F76485FC18228418F56978421DC49E44B37F9CFE95FC1993631AB4FF76C1D23952E953FFFDB3FB23588CE6112B2881E8D5D98F752DF1481469D6DCEB2137533A49D17D843D2BC114AF3976EE7646A2AB8A716844699A904D42F1DBFA88FEEC116BFBEE776A8E4A00 +9BF73CD6 +99393D5E5F27A846E13896DBCB +BA53D12F3E358AA49793BCACB1809DF9DC92416B4DC550E5AAE6CFF8F20C25CB4415A6CA2B246C4788A8E5F711E43C8FD8A83B3702CA2A5BA8EFD961150DB08D2F19A0AAF8 +46A2331A +3084CE879A9D3D0275901EF29C +8C1E3662206D27ED6895590980D4955021A3929869A497F2907A55E96783E54710BF79CCDB13BD2B99DF20FFE3D2BCF8B742E91761B817CAF2FC57505398851F0BBF930391F9E04D37130E0046F101D1691F719C357F0C55263ADCF8863730C63719 +01BE604C +CF75FA53AF3935BF66710C206B +78D6B9EB1408D267B69826221B2A83619A2119643DAC53B3760790B1ABF566E2FEB172A6869CE5CC32CF13CC5FFB0EE0D0C411A87E921F2E29B01F2B1D7CE930CC65870AA718E27489587030EC57F1D4DAC6C46472D78AFA1A +4B10E106 +F3088F0B2C3E8EC83C98A7641615 +5347AB0633CBAF38500C30B326838143C286922710B1CC8E613233F6F5AFEF295558EB6834D459225C34C32CB9FF3112A195EDFEFED6C0E7D8D03ACDAB4617F118E3C1E4A3BE184C64EEF689D6614AC8FDA5D0AF2ED24A9B92C2125054CF575B84EFA7B42B34C0034B3CB059E1C5AE8D3137284721DB267092D14721F6ED +F500 +B4610E328F9F3DE64501B215A365 +3890F83A +36A92D3FD4D954F704B4A7D3A467 +98F5F975D2E2F8A81C2809E8BA4D92700FF8DCE59FC96F6F1CFA44B14AAF265293228CEFC543634D60A3A05F1CDD362A32A21BE83B1B491751D8EB0422DF024D0AFD8459A59142DA1F0B3FAFA74F77F5A4206A1FFB283C4BEAF245148D9D9D3781A2CFCDA2CA5DCA5655BD309EFB2CC3AC6CBE5C95035AC3A551F06A7C0A +884B +BCA5956C5870BEDDD63CB3E7A95CEFE01509A64427C55C81C9 +A95E0A59 +BEA9A6737F5F7CE3729888C85593 +6EF155DCEECECDE71906092099CBC7FBCEAD4E7690CA49DC819EA56DB201DC1C2D196DCF5F6F8E68F9A06A4E75B4EABF16803D133AFBAC237CD87F7BEDEE0FDD60691C77D93814056488AC1A6C07978C6E39E193DE8555B19C019408453597031377C4B44277CEF26C040BDAF4D05A13BF0D410AEC03BC32CA67910F0FF3 +6B2D +306343CE +952FEAA3CB5C0BAD435805FD5C +CE647F9992A472409724B5C4D4B5913DF96C002E6B753131797F61F3CCD0D0AA0A7F45AD855CFB76870671A55203C1B0182A045BF4C88053A515E6B9F5E302 +97702795 +789A5A9229E5512CF73D4934F65C +216EB6C318A7A3E3C5CAD693DBF09383CBB1E2D9C4E070F1012E81C38F1306BD6884DDE3618B67E46DA934304D353FCA197D6E49CFEEB8E06126956414CAAA12B4C2FB1C6DE3D77E9F8B5B41171C9FBA72CF6A20973DB8022EC97E5625E53D19D070D6B6DAD71F305F +4DA06795 +C5C5B67FE15621CFC442AF0EDE +656CDF7EE464663C801E0FFB0BFEFFB27D4F8EE48E10 +4679630B +FDEA5162F3FB2C1649BCA463F3F2 +DC46DD4CF826D332 +196D9F41 +D3D041F118C3F23CB4D04E5ABE086B6BACAE1CCED0E6D6AD6899F08F81FB6D7525F8 +F0748C75D6D73EF2B19BE2C4F4CC0E7FA6D270C65A5FEF379AFC1CB87A01A98191B1D2A19FCE +0EF87C54B2515F3FB851BFFC1448B10E78069E35BE8F688F2ADC8F +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +%Defining font PSOwstdutchb +%!FontType1-1.0: PSOwstdutchb +10 dict begin +/FontName /PSOwstdutchb def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001000 0 0 0.001000 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 1 /C0032 put +dup 2 /C0045 put +dup 3 /C0046 put +dup 4 /C0047 put +dup 5 /C0054 put +dup 6 /C0058 put +dup 7 /C0067 put +dup 8 /C0069 put +dup 9 /C0072 put +dup 10 /C0078 put +dup 11 /C0079 put +dup 12 /C0080 put +dup 13 /C0083 put +dup 14 /C0084 put +dup 15 /C0085 put +dup 16 /C0096 put +dup 17 /C0097 put +dup 18 /C0098 put +dup 19 /C0099 put +dup 20 /C0101 put +dup 21 /C0102 put +dup 22 /C0104 put +dup 23 /C0105 put +dup 24 /C0108 put +dup 25 /C0110 put +dup 26 /C0111 put +dup 27 /C0112 put +dup 28 /C0114 put +dup 29 /C0115 put +dup 30 /C0116 put +readonly def +/FontBBox [-18 -207 755 694] readonly def +currentdict end +currentfile eexec +D9D66F633B846A989B9974B0179FC6CC445BC7C8A959A39A32E9DCE7FAEF17EE3BEC9F +50E1A6FCA651FC4B3769A0A91041557502E25A5D6180FE25A3D11BF079E1DF66E54EE9B7C229AF891739707A2A0EC140306B5E43E52B79BFB89E459E50 +6EC6F610A70775A31C460976C4F79449D86E57ACE491E5C6BF20CC4307B1DAF7630252 +E9AF8CFB69B50EDAE9D36A6104AFEF8832F920FD2346B2C7104CD11E3BEE999CFA9F5A +49DB3173EE48D1C82994237F360407B022E0B4 +502E94EA8B493651EF2D03F0B513D655047568325B512AE6 +6AC6F53F3848CF70DE25481CC65D8B1A5793AA +3C4282D111112BEE28AFCA7A3808D4444C4669CA +84EAAAF989219F51AB3476A1B0B5F2246BC306E6 +625C6679C417ED2A8E9BD010DE37D40265074C2684274C264E5F45F0286BD1B23D26C34626E07A +5B039DB36C18005EE32CFA64 +906B285CB8BD7F0968 +D47F5242 +22DA29BB63EA29AC1293D9F365 +FDD092686CF0D739DAE7B4EBECDFE21B8B5810B15B35D7 +8B1BDB66 +02B6ED886A783C9F2E2959DACA +9F8C687CAC50F98DD3D99C91A3816894F5A2231814056F2805E451F66B5923 +79B434DB +F70638B9F2044F3ABEA1123528 +14FB6FABE370F6494A54BD1740E96D8698DF36DD8313B05B556E +E0432436 +DC00618FDC48F0E9CCBC9B83BF35 +C8C3C0F09B05E08F79985D14864D913C5D7BC268B6BCBF77E21E34751DF20D7C13EDF71ECC5EA956A298A7447FC1E3CF353CB35AD64AAEAECC309B253DCD88C4DB567B417C8F6EE8BA379C4AB91748934824A3AE7275984BAF226F3FA23A7C733B0C4BEF +2D084547 +F52FA0445FB3D8D8B6BCCB72D6 +E2DD788CF6F7B941D3AE3FD3B7FA3803847E8B480CBCF4C31FF87840EF0D6FF5F019B2E0302CF794BBE69EA40B0069420B9E0F4F8C9D +50AEB93F +850A541FA79CB4B5713DC1994503 +46ADEBEF55F0F7029EAB3A48EE4266A1A9E1BC82CAF17610D752C3E39FDA1CF7348169B5FDCE6CBF436FA494E4E3BA1982AE7EFA79B6A7A2DF1EF4F431B07F3FD8B8FB0184F4BA10A00137C67300230F8BE7853AA0FD42E9058DB2F90DA065755B36665724D47950 +32CC49C3 +767A023117E52C71A1D1A688023B +F4933D7BEA814EE8A9700895739A780E5A18647A952A5846E4CC3F624EE60B6C0B36CA3FFC06EB5559D607684C30A53B83970CB0A5C708CAC8660001BE38614183298C530D30F10A4CAB0B634E3105BCF8E4EEF29B457D0E8E73C3E5E7F8A17CDE4FA595BA0410EB20C072EF5D33 +D987A82B +8A6A6B5593B5F1AECF188C2FC26E +7F7C2F3624EFE5353CE717F31A9268BC9C15E5E151CB6D941E9EB6832DD651A1F6F276B094B608CA1C9C9B837760CB64079AC86C5C955005D1432CD786D12B3814F0513F5020C3226E7BBA58638D288795BBB406285CCC964BB9F5CEE665F97DD7F9EF849D0119827EF13A7585AF8806540278BC766D37 +DBD5160D +C262CD3F4A5530477B1E742187 +1F8648C12A6B67D45DA7F2A5FDE2997BE58F418520E9FB4FE1208B9786655984D515C4A8CBF5EE0200EC4BE05C75178B65AC2DE83856F6FCC5C9AC1D1354B53619B56A080CB8211C97720E5E1C7523C5F27B68F6C9120DD6542FD2AD96304C +AF62815C +71C73566EC1C94945CF91C45816B +9AC1146BA4F99D95EBC71F91C934044D3B9AF0D8B42D7429FFDE780A27C31C9AED8D9EFB8D4DD57DE0C637C60A021DD833657476FFDB37E598E5BA1E69AF41F7AA462225006906CD2733A602EC38969B099ADD8FD89F406E449F66D16BC0C423B8CE425E1AB4187E05 +045A803B +1F8CE1E330A9BA2FD3715A7D2C3B +8999507CC9BD3FAACFA543F7C94B9F0B1021C27F41D973D6A04902ECE1101DFF258CB970E84F2B52589708B437A794F656F7F8A94BD36E2625876B955471268837DF8C0AE42459342D6A5D582741D9B6943CE9CE4E845A7993F6484EE1E397C756D3D094 +5855AF4A +35525F0A01D9A88F9B077BF6EB03 +9F4D5DC118F8545E1B3291372BF5D61F2C590BC0A5DCD20ABC3E755126B26184191D81FAFDD47F563B4E33FCE3FA3B9C2676EFDFE52C717CE57948FCFDD565D8DA7FE668A77C55AE4345CF28E07B70AA108E6280FCB189B90BA2B856980C209A0412F2A3FF20BC6A33C688C948E0DD5504EA49CEA94DB7A69A348134025E +21A1 +7AC35B44 +5C4E188FEB5B648FE6730E2148 +AD363D406C88B0B093B0A23594E293AEE49D63F321C9522D0BD62155725BE0322EA4A873F7599A5C289EC9ABEF96A24043CF202EEC3CB731ACFA2304E96764DE7D8960B7FFE8E161D4 +1C6DC9E2 +DA39F8A6B44319821C348DC3238D +11C2E2B27DF4B8FAEDA5F4A8577DAC1B43E896B31B76DBB440ACDD8448BF494E58AE30B67BBC4E108B39EE82841806DA4C00DB9435DDCC0239310BE306BB658268661A52D009A64BA535D178E196C18451820241D90F9E786D4405A5FF72386FB854EAB9AD6CA4 +5E14F213 +A9463A646AC32B18A9DC0B4586 +C3992FC5991FF61434DFA74507E0553B35112797E1121EF388632655037ACCAB1327BE1B705B577E62ED287FC7240D51CDCC2AF33D7C7697DEDE1B +952FB6BD +F6FE67EC48B099DB7859BFB0D710 +C83BCF6A3AF7FD9D8C062223CD3F2B46BEB995C895B4B27DD661495226773B88437EE158A6D3ED12FA0534AD2E3D34F1411B8479BE6B59B7A8E63200051F998233A00766EE230DAF0AC56AD6DD099FB4B1BE3852090C9FC5F3A3FE9FE5C4D2C48E07149DF9BE8BA9EB108063634FF87E5546889C405BEC3C7871EF0AC757 +0F13 +C662F67D +2C9C7CA7 +B733D1B318BB2138811972EB6C +8B045A9C35C41706B818377465A41A5B4B15AEF69BA2FA65FE379D3C940A60B64D7761AA1321332EB9CD7D4A99419312105C18B936A929C0FEB0BEF3DF90911AFC0AE849881E499F6CC31348DAF4808F5585878A7E4E6FEDAA5E000B7C42 +2BE3A349 +FEF3743AF9DBD5FB69D605A56D +D7F4307DC8165E611021F0655C9D2BDF3F20887F2DAE955A93EB06E7506275665868641E0845F56880D088CAA644B07EE8BF38314069FEE4412E14E333E440141635FD46518815B03BD58F47A8EF485AEE0B +C8FBD476 +5DE253B9DC92D32682D08E9034 +1B411382064BB54CFCF73E79812474ABA75A3052DC7C874812FE5608C08F6D4DA8BEDD5FE495404D98A378D9C38AABC53801F89E7908E14D529FD184B3823655A026AF1BA74CE9D5B473DB42C6CEC411AF294565FEA1D3BA3029FFD5 +B93D9C79 +DB8DA4635F94BD220290C6F31F +4FE1B0345C333165797E38CCB863F29B0D787090D6C249E9BE971327815B226CDF9E82CB12E12C61D77C583E6B5F333EEFA78AD3923C6A86A2D335412561C1CC2A305297A2B8DC6CDE0C3626CF66DFECCF161361E5886EE9D803F8755D +44178818 +010EC7011D7F5B75FA38C0FF5C49 +D1AD996ACAFD649D25885CCE8B790C69E547395452D778F19DA62A8049204528AA0306CF03CC94C520F994963AB2E871045B33F2C0C3269540669014AC43038C899CCEED76B47385C422FE58C072143E85274A3D99CD4F855B88F0900FF9A89ECD75D02AA74B1136 +0D9EB441 +218BD4A9D63E033574F5CFB937 +1D3FF527683AA6B766DD6E9E0788752FAD87DCF60B5044A599EB77D91F8F4D2113A22D60ED4EDA1A9BD881C4EE41CFAC8B558A1972488D33A52FBEE99E649119A9857033C651401B48E555053F9D +3BC1EBC1 +1DB924E7D285E0612E3180E51F +1800FFB01C09A4E40458D209A7C90CF7A503729B5FC282E973C6DFA58C2A626A75FD507EB4B76DD140B5EB62440262CFF73CED83 +7C0DD984 +25A8703D270629533CCEA6C144DB +AC1FC39D142CDB57D943D22994F4D98E2F7289A45E8725B77BFC860EFA7B42D731B2B8420D265A88D42C47A0610503795F4128DD9D1633175C7BB5869982ABA78865008316EDD5A57A118B33E4CE7199E6434AC4C2E32CE6C35BCF81A2706CD69328BAA0D0712D +57898DB8 +B12619615BAF8FCF2280BFA07D +77178F1050646FCD9BFD4D52E09B98611465F7BAC2F864157462D3878155093204C2341793A04B2387386CA922CC301005FB40431B9620A0ED1B0BD74DDBCBE032CE5975587A +EBECC6B2 +E68E847974081A51A923361ECCC8 +11521394E9904C53E97587C0C45CF3958131E0E367DC63268C09B371C67281FA9AAF2C5EE3DC9AF37EB3090A4F2DE0A40ED7E6DA03C21F083F96496CEE9CF4328538B3FC1B61B2B71DCF5637A2E5C522CDE99C7EF2968B02B9841A78F693F8B03AFB0584B94E416929A70F4582DCAEC3E0 +B39F6F54 +22E0BFA8914C4E31ACA371A51F +64CDC4E0C2C3605DFD769F0D841E2BCC61EFBE13E5B2EB2DB6E658AB8D3763DF22093F66DBB0F85C060013ED7CB2CC99E19A9AE41ADDAAEDD4754EEA2C383F32C383C56AF5179D014914EBEE5974F66ADCE04ECD3019DCAE79 +8F3E8DE5 +A9E10B54E30EC1EA68A7FC408EC6 +25E310DAF5E64B9DCEED17577F8CF140A29E2AB668243131E2787DD82078BB6A794ADD572C91CD75D07BA7046703B15726C32D47C5757CEA2F9927C81085CFFEB5DCD4CF14EC4E3405AEB9F7B9DC4561DFA2A2DAA909E3CBFC319AA8BA7B247C275EFD48397D44C8F2B168A1515BB0EB5FB9D47958A6AF49EA +535172C6 +7342DB315A63612634E359701C +F821383B1BAD4CEB98D10EC28477E764E72176DF92EAA41B6C2DCE062B3EA97F27EEC8C0918047D6F79718DEAED01F4AB8F25B033FC7AC5C189B98C63B69740332C7CFA5 +5FDFAC13 +B9DA09B829654189EA59FA9F874E +31EC370C0D02EE4E +EF52CBB4 +4843952CFD687F6C6E290390953F56B300866CC3343C4C26B5C35202FADF3B336870 +E21F3AD9B1C64E61E8041F751A6CED0EE6A26D79AE2934BC7848823E103BDFC6357B2587F848 +29A56BB3AB66F256141EA0C846628435A289006A2459AA1E07F142 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +%Defining font PSOwstdutchi +%!FontType1-1.0: PSOwstdutchi +10 dict begin +/FontName /PSOwstdutchi def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001000 0 0 0.001000 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 1 /C0032 put +dup 2 /C0101 put +dup 3 /C0104 put +dup 4 /C0109 put +dup 5 /C0111 put +dup 6 /C0115 put +dup 7 /C0116 put +readonly def +/FontBBox [-33 -13 757 723] readonly def +currentdict end +currentfile eexec +D9D66F633B846A989B9974B0179FC6CC445BC7C8A959A39A32E9DCE7FAEF17EE3BEC9F +50E1A6FCA651FC4B3769A0A91041557502E25A5D6180FE25A3D11BF079E1DF66E54EE9B7C229AF891739707A2A0EC140306B5E43E52B79BFB89E459E50 +6EC6F610A70775A31C460976C4F79449D86E57ACE491E5C6BF20CC4307B1DAF7630252 +E9AF8CFB69B50EDAE9D36A6104AFEF8832F920FD2346B2C7104CD11E3BEE999CFA9F5A +49DB3173EE48D1C82994237F360407B022E0B4 +502E94EA8B493651EF2D03F0B513D655047568325B512AE6 +6AC6F53F3848CF70DE25481CC65D8B1A5793AA +3C4282D111112BEE28AFCA7A3808D4444C4669CA +84EAAAF989219F51AB3476A1B0B5F2246BC306E6 +625C6679C417ED2A8E9BD010DE37D40265074C26842CA5AA11586DCFF47D870C5FEB929EC5C9 +8B7ACD2871E4A9F69E8E87EA +EF22D1E6074F7A0124 +F1FC65A1 +3164253439099248199883229C55 +98E2574F3AA7520C24280259318C0A4A10B1DADC3B4C25E0F5C283812788F5568BBC7E18F7AFBD8C7931B3E2D2E9359092D53BC3CFF4DDF64992117FA05233D627D08C4CD635D0FAF4F3FDBC9FB8497AF559575E9C76078F067EA6C11608CACFC095060E3A +1B1CFFBC +D20B9B9C060DB9EE9BF11064986D +DA53A77FC6D972F85714FFCACF3887F3E3C53FE200EE7A87C14AF3E5D7C43B581FEB570B88E34A06E1E682AC873C9AEC0CC537B80123285FB26CFB82DADF910C813DA72C9D5CDADDF455B2EC1BB3ADA3371A7715B1008D6AEF73B70B19130B85A7EF509372ABA718C4FE3F31279A095B0D9E5F9766E9946FB989FEDA709C +6850 +631A5DD4E37856C52A9474F1D7CC43F7C4BFD34A562564975322BF +09AA6F60 +6ED5DCCE8792CADF4D43E1F5AC04 +7A8204F417C4E7BD19F6FFFD7FD575D2742AF12857EFDA2EF5A082C32F58C18561B9BA71BCB02DB33677C74B15CC12638915CD5F661724B4AB042C2362F96DCB8CAC259FB216E2952DAFB9D3E74857B95A7B01D51B5257204517C1D891B01BA97AA60000F6DEEF278606AA2DBE7E8A0FFBD4C8AB8BFBC9C7E5132933655A +9F31 +26E16072F7A90FCCCA5D9D3D2D991BFDE4383C4FFAEE1161809D765CBB8B622CDD629E6F180D773A6F265A5B26A32DD7A6A3D55171CA3A6C4D35F92574D067FE5E5F8C210868FB53D8AAE4 +ED50CAA8 +DDD5E6DAFE9117E7AF88BE6DC1 +91A3FB5A5039F93B94DE4DBEE44521D9539E3D53C7CC4656DD0D26E60B8434D62E1B0D8024CBB49385A1D71E16645760AF0B71B73E8BB1A876CA50E69202CE04FCCA4AB18C31E51ECE1A23739AB86647DB30FCA9CC17DF2371DB465DCCEE81 +894D38FB +3BF6ADA1365F9FE9932438B39984 +8B8F0A692D519B6833DA45246FEF9D38493473B7C295E82307040A00C34DED6D5075E8355FDAB10505174F142509B22E755A40727B9D6F85B46C8D713F4C1AA9A7999559FC72FD8ADD71A81A2B430B9B7F7143E1D427D2B02C02DE5A1587372DE0A0D66D628B13204C1FDE0A5088EB24BB83A594ABCE +20D71602 +747CDA34968E082C6A07D768CF +FAB4CB96EE726431CF15227A6EE961AC1812ED7F3BC567EFFA72DB169C9CFF6875138092250EB1FF3186ABD0DF675ED93D35260C5E1D2B1C0D894F5CDDF1597988989E6C7BF139FA3F441FD99673FDB6D8156C20C6254B +CF2CD5D8 +40E3A455537D18AEBBA0AA2EF193 +AD1E8F14B881D5DD +C6FDD0CF +3D2B6143A7BC893CF85DF208D92503B009FA469F423C82FF6B7E73AB155EEEF271BF +51B3D1E198B4B1CB01F25C3ADCC0FE68A50CB2B1A43D2F3DC90A32B4C9F73AF809F743F9E66F +676CFBC68C633A34954D78F8429C5559E7BB5B1DEF7555B0186F85 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +%Defining font PSOsymclas +%!FontType1-1.0: PSOsymclas +10 dict begin +/FontName /PSOsymclas def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001000 0 0 0.001000 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 1 /C0069 put +readonly def +/FontBBox [106 45 775 713] readonly def +currentdict end +currentfile eexec +D9D66F633B846A989B9974B0179FC6CC445BC7C8A959A39A32E9DCE7FAEF17EE3BEC9F +50E1A6FCA651FC4B3769A0A91041557502E25A5D6180FE25A3D11BF079E1DF66E54EE9B7C229AF891739707A2A0EC140306B5E43E52B79BFB89E459E50 +6EC6F610A70775A31C460976C4F79449D86E57ACE491E5C6BF20CC4307B1DAF7630252 +E9AF8CFB69B50EDAE9D36A6104AFEF8832F920FD2346B2C7104CD11E3BEE999CFA9F5A +49DB3173EE48D1C82994237F360407B022E0B4 +502E94EA8B493651EF2D03F0B513D655047568325B512AE6 +6AC6F53F3848CF70DE25481CC65D8B1A5793AA +3C4282D111112BEE28AFCA7A3808D4444C4669CA +84EAAAF989219F51AB3476A1B0B5F2246BC306E6 +625C6679C417ED2A8E9BD010DE37D40265074C2684268F16195489648993B9C4D3B534FA887C +DEF605FA87B991F4D20A8F78DACE +5A54C070E03D5C59D9D2D3E06B09CEE028D68B62AB3AEC43C1DD20BA70D288597D9BD8E06818FF764EBAB436723988E8D7CA59E16D39032516BFC5D552ACDEEC6BE938BEF2F43CFFBC811C3626C4DF5F8CF080676520B51C60CEDAD1FE6C92D1431C702174CE517A8FA9377D075A0B6833DAB101DB65397F1419EF5F0016 +004F +6F0824F9657BB4F1C8F981709956865F6855EFAE +9242AD55 +91BBBEE163D844DDA894E13190C9 +2480439E4C71CADA +BD043A9B +A315CAF72652AA7FE6DB2E84D82A6111CE4DE90C02DA0AFFE2620922262A45AB4ED0 +EEC9F4520DD12703442F7D028D4526BD8B771E09FBE11B2749E2D3906894E8D4BFD3F379F14C +3C874F550606965E22FE487B247B5C2D06728490C8F2A3B588CDFC +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +/DPIx 1270 def /DPIy 1270 def +72 DPIx div 72 DPIy div neg scale +0 -13970 translate +1.00 1.00 scale +/wst:dutch12 12.00 /PSOwstdutch newFont def +/wst:dutch12b 12.00 /PSOwstdutchb newFont def +/wst:dutch12i 12.00 /PSOwstdutchi newFont def +/wst:dutch14b 14.00 /PSOwstdutchb newFont def +/wst:dutch10 10.00 /PSOwstdutch newFont def +/wst:dutch14 14.00 /PSOwstdutch newFont def +%%IncludeResource: font Helvetica +/wst:helvps10 10.00 /Helvetica /wst:helvps ILEncoding 0 declareNFont def +/sym:clas10 10.00 /PSOsymclas newFont def +%%EndPageSetup +GS +0 13978 10801 13978 10801 0 0 0 clp +wst:dutch14 SF +0.00 0.00 0.00 1.00 setcmykcolor +<1b2b39352b372c0f011101122b33292e32273730012c3437011a2b27383a372f332d011b2b393c343730011d> 2207 558 0 7384 -1 s +<2b372c3437322733292b> 7375 558 0 8593 -1 s +wst:dutch10 SF +<0c0a> 9346 13300 0 9522 -1 s +wst:helvps10 SF +<4e6574706572663a> 1322 13280 0 1949 -1 s +<205265766973696f6e20322e313b20436f7079726967687420> 1949 13280 4 3868 32 s +sym:clas10 SF +<01> 3868 13280 0 4019 -1 s +wst:helvps10 SF +<2031393933b131393935204865776c657474b15061636b61726420436f6d70616e79> 4019 13280 3 7133 32 s +wst:dutch14b SF +<0d14131e171a19> 1271 1458 0 2055 -1 s +<000503000b1e16141c000a141e1b141c15001e141d1e1d> 2055 1458 4 4424 0 s +wst:dutch12 SF +<1135273739> 1271 2086 0 1805 -1 s +<002c37343200392e2b003a383a273100352b372c3437322733292b00392b3839380700332b39352b372c0029343339272f3338003834322b00392b38393800392e27390029273300282b003a382b2a003934> 1805 2086 14 9531 0 s +<3839372b2732312f332b> 1271 2330 0 2223 -1 s +<00322b27383a372b322b33393809> 2223 2330 1 3621 0 s +<00202e2b382b00392b383938003727332d2b002c37343200131d21003727392b002927312f283727392f3433000435372b382b333905003934002e343839002f2a2b33> 3621 2330 11 9461 0 s +<41> 9461 2330 0 9531 -1 s +<392f2c2f2927392f3433> 1271 2575 0 2083 -1 s +<00042c3a393a372b002b332e2733292b322b33390509> 2083 2575 2 4181 0 s +wst:dutch12b SF +<070c0f001c111e140013111817121c111e171a19> 1271 3062 2 3182 0 s +<0a0b0e08> 1271 3484 0 1866 -1 s +<06> 1870 3484 0 1928 -1 s +<00> 1928 3484 1 1964 0 s +wst:dutch12 SF +<001d> 1964 3484 1 2128 0 s +<372b3b2f343a3800372b3b2f382f34333800342c00392e2b003227333a27310032273e002e273b2b002a2f38293a38382b2a00392e2b00171d00302b37332b31002f2a312b0029343a33392b37090022> 2124 3484 13 9296 0 s +<2f392e> 9288 3484 0 9531 -1 s +<392e2b> 1271 3729 0 1561 -1 s +<00372b312b27382b00342c00171d082123000b0a090a0700392e2f3800322b292e27332f3832002e273800282b2b3300372b353127292b2a003c2f392e002733002b363a2731313e002729293a3727392b0034332b> 1561 3729 14 9531 0 s +<2827382b2a> 1271 3974 0 1791 -1 s +<003433002f332c34373227392f343300372b393a37332b2a002c37343200392e2b003538392739040500383e38392b3200292731310900202e2f38002729293a3727392b003538392739082827382b2a00322b292e27> 1791 3974 12 9461 0 s +<41> 9461 3974 0 9531 -1 s +<332f3832> 1271 4219 0 1700 -1 s +<002f3800063334390600273b272f312728312b002f3300171d082123000e09230700333437002f330033343308171d> 1700 4219 9 6185 0 s +<0034352b3727392f332d00383e38392b3238090015> 6185 4219 3 8039 0 s +<343700392e34382b00383e38392b323807> 8031 4219 2 9531 0 s +<2700131d21003a392f312f3f27392f343300322b27383a372b322b3339002827382b2a00343300392e2b003a382b00342c> 1271 4464 8 5816 0 s +<0040313434352b373802> 5816 4464 1 6727 0 s +<002f38002b323531343e2b2a09001427292e00372b363a2f372b3800292731> 6727 4464 5 9461 0 s +<41> 9461 4464 0 9531 -1 s +<2f283727392f343309> 1271 4709 0 2040 -1 s +<1833> 1271 5055 0 1468 -1 s +<00392e2b00293433392b3d3900342c00332b39352b372c07002700131d21003727392b002f38002b3d35372b38382b2a00333439002f33002931342930002c372b363a2b33292f2b3807001a181d1f003437001a15191c1d1f07> 1468 5055 16 9531 0 s +<283a39> 1271 5300 0 1569 -1 s +<00382f3235313e002e343c002c27383900392e2b00383e38392b32002927330029343a33390900202e2b372b0027372b00393c3400131d21> 1569 5300 11 6724 0 s +<003727392b002927312f283727392f34333800392b3839380900202e2b002c2f373839> 6724 5300 5 9531 0 s +<322b27383a372b38> 1271 5545 0 2119 -1 s +<0027332a002a2f383531273e3800392e2b00131d21003727392b002c343700392e2b00313429273100383e38392b3209001839002f3800292731312b2a00191c1325131d210900202e2b00382b2934332a> 2119 5545 15 9531 0 s +<392b383907> 1271 5790 0 1648 -1 s +<001e141a25131d2107002f38002b3d272939313e00392e2b003827322b07002b3d292b353900392e2739002f39003c3437303800343300392e2b00383e38392b320038352b292f2c2f2b2a003c2f392e00392e2b> 1648 5790 15 9141 0 s +<000817> 9141 5790 1 9531 0 s +<2934323227332a> 1271 6035 0 2165 -1 s +<00312f332b003435392f343309> 2165 6035 2 3252 0 s +<1833> 1271 6381 0 1468 -1 s +<0027332a00342c00392e2b32382b313b2b380700392e2b382b00393c3400392b3839380027372b003433313e0027372927332b313e002f33392b372b38392f332d090017343c2b3b2b370700392e2b3e0029273300282b003a382b2a> 1468 6381 15 9531 0 s +<3934> 1271 6626 0 1456 -1 s +<002d372b2739313e0038352b2b2a083a3500392b3839003829372f35393809001e> 1456 6626 5 4433 0 s +<2b322b32282b3700392e2739002c343700131d21> 4425 6626 3 6546 0 s +<00322b27383a372b322b33393807002f39002f3800332b292b383827373e003934> 6546 6626 5 9531 0 s +<26262927312f283727392b02> 1271 6871 0 2263 -1 s +<00392e2b00131d21003437002a2b392b37322f332b002e343c> 2263 6871 5 4746 0 s +<002c273839002f39002927330029343a33390900202e2f3800353734292b3838003927302b3800273900312b273839002c3437393e00040d0a05> 4746 6871 11 9531 0 s +<382b2934332a38> 1271 7116 0 1979 -1 s +<002c343700392e2b00313429273100383e38392b320027332a002c3437393e00040d0a0500382b2934332a38002c343700392e2b00372b3234392b> 1979 7116 11 7222 0 s +<00383e38392b3209001c332b002927330038273b2b00392e2b> 7222 7116 5 9531 0 s +<372b383a313938> 1271 7361 0 1862 -1 s +<00342c00392e2b00131d2100392b383938002f3300382e2b3131003b27372f2728312b380027332a00392e2b33003a382b00392e2b320027380027372d3a322b33393800393400392e2b0008290027332a000813> 1862 7361 18 9531 0 s +<2934323227332a> 1271 7606 0 2165 -1 s +<00312f332b003435392f34333809001d> 2165 7606 3 3508 0 s +<2738382f332d082f330027003727392b003c2f392e00392e2b> 3500 7606 4 5740 0 s +<000829003437000813003435392f343300392b31313800332b39352b372c00392e2739003e343a002731> 5740 7606 9 9461 0 s +<41> 9461 7606 0 9531 -1 s +<372b272a3e> 1271 7851 0 1773 -1 s +<003033343c> 1773 7851 1 2299 0 s +<00392e2b00131d21003727392b07003834002f39002927330038302f3500392e2b002927312f283727392f34330038392b3538090015> 2299 7851 11 6800 0 s +<3437002b3d273235312b0700392e2b002c343131343c2f332d0021332f3d> 6792 7851 4 9531 0 s +<382e2b3131> 1271 8096 0 1689 -1 s +<002c37272d322b3339003c2f3131002a2b392b37322f332b00392e2b00313429273100131d21003727392b0027332a003a382b00392e2739002c343700383a28382b363a2b333900392b3839380f> 1689 8096 13 8724 0 s +<03> 1398 8442 0 1504 -1 s +wst:dutch12b SF +<00> 1504 8442 1 1557 0 s +wst:dutch12 SF +<191c13251e> 1557 8442 0 2284 -1 s +<11> 2276 8442 0 2439 -1 s +<201410> 2419 8442 0 2883 -1 s +wst:dutch12b SF +<10041a1b1e0419141e1b141c150419141e1b141c1500021e00> 2883 8442 2 5071 0 s +wst:dutch12 SF +<191c1325131d21> 5071 8442 0 6087 -1 s +wst:dutch12b SF +<10> 6087 8442 0 6140 -1 s +wst:dutch12 SF +<03> 1398 8789 0 1504 -1 s +wst:dutch12b SF +<00041a1b1e0419141e1b141c150419141e1b141c1500020900> 1504 8789 3 3785 0 s +wst:dutch12i SF +<060504020305060700> 3785 8789 1 4654 0 s +wst:dutch12b SF +<021300> 4654 8789 1 4977 0 s +wst:dutch12 SF +<03191c13251e> 4977 8789 0 5810 -1 s +<11> 5802 8789 0 5965 -1 s +<2014> 5945 8789 0 6232 -1 s +<24> 1271 9135 0 1433 -1 s +<343a> 1407 9135 0 1639 -1 s +<00382e343a312a00372b322b32282b3700392e273900131d21003727392b38003c2f3131003b27373e002c37343200383e38392b3200393400383e38392b320900162b332b372731313e0700392e2b00282b3839> 1639 9135 14 9531 0 s +<3937272a2b08342c2c> 1271 9380 0 2180 -1 s +<00282b393c2b2b3300392f322b0027332a002729293a3727293e002f3800393400352b372c34373200392e2b002927312f283727392f343338003433292b002f33002b27292e003829372f353900343700382b38> 2180 9380 15 9461 0 s +<41> 9461 9380 0 9531 -1 s +<382f343309> 1271 9625 0 1695 -1 s +<00202e2b002a2b2c273a3139003829372f353938003537343b2f2a2b2a003c2f3131003a382b00392e2b> 1695 9625 7 5301 0 s +<00191c1325131d210027332a001e141a25131d2100392b38393800393400372b2a3a292b00392e2b> 5301 9625 7 9531 0 s +<392f322b> 1271 9870 0 1677 -1 s +<00343b2b372e2b272a00342c00131d21002927312f283727392f343309> 1677 9870 4 4392 0 s +wst:dutch12b SF +<0a0b0e08> 1271 10217 0 1866 -1 s +<06> 1870 10217 0 1928 -1 s +<00> 1928 10217 1 1966 0 s +wst:dutch12 SF +<0015> 1966 10217 1 2135 0 s +<3437002729293a3727392b00131d21003a392f312f3f27392f3433003433001a1d00383e38392b323807002f39002f38000629373a292f27310600392e273900332b39352b372c0027332a00332b39382b373b2b37> 2127 10217 13 9531 0 s +<3033343c> 1271 10461 0 1756 -1 s +<00392e2b00333a32282b3700342c00353734292b383834373800343300392e2b00383e38392b32090015> 1756 10461 8 5519 0 s +<3437003834322b00383e38392b32380004171d0821230500392e2f380029273300282b002a2b392b37> 5511 10461 7 9461 0 s +<41> 9461 10461 0 9531 -1 s +<322f332b2a> 1271 10706 0 1840 -1 s +<003537342d3727323227392f292731313e09001c392e2b3700383e38392b323800372b363a2f372b00392e2b003a382b00342c00392e2b0040083302002d3134282731002934323227332a00312f332b> 1840 10706 12 9233 0 s +<002737> 9233 10706 1 9461 0 s +<41> 9461 10706 0 9531 -1 s +<2d3a322b333909> 1271 10951 0 2007 -1 s +<00202e2b00273a392e3437380027372b0027313c273e3800313434302f332d002c343700383a35353437392b2a002927313138003934002c2f332a00392e2b00333a32282b37> 2007 10951 12 8072 0 s +<00342c002729392f3b2b00353734292b38> 8072 10951 3 9461 0 s +<41> 9461 10951 0 9531 -1 s +<38343738> 1271 11196 0 1630 -1 s +<002f33002700383e38392b3209> 1630 11196 3 2726 0 s +GR +eop +%%PageTrailer +%%PageResources: font Helvetica +%%PageProcessColors: Black +%%PageCustomColors: +%%Page: (21) 21 +%%PageResources: (atend) +%%PageProcessColors: (atend) +%%PageCustomColors: (atend) +%%BeginPageSetup +bop +%Defining font PSOwstdutch +%!FontType1-1.0: PSOwstdutch +10 dict begin +/FontName /PSOwstdutch def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001000 0 0 0.001000 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 1 /C0032 put +dup 2 /C0034 put +dup 3 /C0040 put +dup 4 /C0041 put +dup 5 /C0044 put +dup 6 /C0045 put +dup 7 /C0046 put +dup 8 /C0047 put +dup 9 /C0048 put +dup 10 /C0049 put +dup 11 /C0050 put +dup 12 /C0051 put +dup 13 /C0052 put +dup 14 /C0054 put +dup 15 /C0056 put +dup 16 /C0057 put +dup 17 /C0058 put +dup 18 /C0065 put +dup 19 /C0066 put +dup 20 /C0067 put +dup 21 /C0068 put +dup 22 /C0069 put +dup 23 /C0070 put +dup 24 /C0071 put +dup 25 /C0073 put +dup 26 /C0076 put +dup 27 /C0077 put +dup 28 /C0078 put +dup 29 /C0080 put +dup 30 /C0082 put +dup 31 /C0083 put +dup 32 /C0084 put +dup 33 /C0085 put +dup 34 /C0086 put +dup 35 /C0091 put +dup 36 /C0093 put +dup 37 /C0095 put +dup 38 /C0096 put +dup 39 /C0097 put +dup 40 /C0098 put +dup 41 /C0099 put +dup 42 /C0100 put +dup 43 /C0101 put +dup 44 /C0102 put +dup 45 /C0103 put +dup 46 /C0104 put +dup 47 /C0105 put +dup 48 /C0107 put +dup 49 /C0108 put +dup 50 /C0109 put +dup 51 /C0110 put +dup 52 /C0111 put +dup 53 /C0112 put +dup 54 /C0113 put +dup 55 /C0114 put +dup 56 /C0115 put +dup 57 /C0116 put +dup 58 /C0117 put +dup 59 /C0118 put +dup 60 /C0119 put +dup 61 /C0120 put +dup 62 /C0121 put +dup 63 /C0122 put +dup 64 /C0127 put +dup 65 /C0262 put +readonly def +/FontBBox [-25 -256 920 739] readonly def +currentdict end +currentfile eexec +D9D66F633B846A989B9974B0179FC6CC445BC7C8A959A39A32E9DCE7FAEF17EE3BEC9F +50E1A6FCA651FC4B3769A0A91041557502E25A5D6180FE25A3D11BF079E1DF66E54EE9B7C229AF891739707A2A0EC140306B5E43E52B79BFB89E459E50 +6EC6F610A70775A31C460976C4F79449D86E57ACE491E5C6BF20CC4307B1DAF7630252 +E9AF8CFB69B50EDAE9D36A6104AFEF8832F920FD2346B2C7104CD11E3BEE999CFA9F5A +49DB3173EE48D1C82994237F360407B022E0B4 +502E94EA8B493651EF2D03F0B513D655047568325B512AE6 +6AC6F53F3848CF70DE25481CC65D8B1A5793AA +3C4282D111112BEE28AFCA7A3808D4444C4669CA +84EAAAF989219F51AB3476A1B0B5F2246BC306E6 +625C6679C417ED2A8E9BD010DE37D40265074C26842243E0EC59344CEF369650A037B4383B03D6 +24C306E87EFDD4775EC78742 +FEFCE44B765574466C +D1AF7A82 +CFE19FEC07055171803BE35FB61F +DFA5A4C739A4E3957EB7C66233844AC51A6A91B45B75E6AF1F76779A4EA39D554C671F039F6EA0902EEABC13363BDDA5101CA12BB8156EEC5AF0BF9E6FFD41E3E8297895E1554F57314DE5E5E70C32DA47FD30A8525D7EE9C60607EDB6FD9F816BBA9417276F85 +60F5DDB4 +A3948B33EB22B827DF681DBB19 +2993B553C6D17076B4B9FB193A79C8A36EECD5D4EF0F532434292DEF98BC0B7ED78FD8401CBE88325807A34B9ECE7D312908B2BD6A5654090DB46D637406668C +51FF586B +0A455727C3D821E5379B18E7CF +73A0BE843CB8405CC41A75A80486DF95591401AB247D9FBAAEE6F1EE55AFCAB16739F92C17F9DC431730A8479507AFD959AC919F6A16978CDD4C0D1467D6E1 +3962DC2A +ECE603DBF7417C4A5C39407E71 +E8A81EDC1FC629A1B0D25B6B5E74F459D542FDA8D60FB0A351282C95F0CA5A93EBEA6A22E762D54555B05B1898BBF15D80F94A81DD2D08FD18 +A220D9FA +4E2282C6D36A8D6146B91CEEDB +54EB0838B4880ED0E6AC455D1AAE04C644F83CF84E3C51 +B9D53931 +8C70E1C37F8B46C93B56E6CF78 +0B37CE393631A096E624B5EF91388F69EEA2BE1409A2EBBCE55EB8A241F0ED +1F29F915 +1513EF53C2D28912FCF980D05D +8533158AF737601C7ACD032615A98076B1A4E8A29EB1F7533CD88AF1 +B91C68D5 +292A866F91B111A3916A3996F3 +FEB1422CA5EF938A5FC80E1B09943FC0D36E37D02739FE4E18FB91CA29427752844B6E48EDEDE3E39DAB96DD566CB9EF95D9349567B08F5676F679836F91EEA1167ED3B5A3BD0204EE92 +D93D0CFE +8A568097F5ED772F9AC41AFF77 +00001FC8E6FF0CFC8FF996CE5DC390D39366E3E01530452CB5D977470E15F56A5C5DF67CB81F1D289F46DFC0A1831045E08AF7812B3645F735B2DADD3E2816 +CFAF7BFB +775DEDFE9F116253FE0D10ED15 +17489C3E7BFBEA8020F822A8B7B9D43CE47881F4A6D5C3B973B5F021A421609247291CE7F849CFCE5722A93C15E40D1A86A8BB7A6EB263D8B1D24EFAF571F8CFABA4D089F409D2EA95D913B58EE8FF4BA0E65D834684020B5747 +22A1342C +36C8E3DDE2F3B6F4D1CBF149F643 +EC607E699A6AD5FC3D443339268970EDB787EEEBD3BD9D9A1885F54671F19255B76DEFD231A010B6781E6185CFE41F7319AF4AAC65033AE1815164FCB0BD6EB43E6698958C58000415D4C74D84ED4D65B68CB0FC9E85A76F626A7BD2A118F58B7D7ADAA959DA82EDE19495F6EA78E4 +DE4E9E24 +E8BE05D5FA587AA82CF7319AB8 +13E2A1EA7360C2B4F577EFB827F11DFF0DEEDB0EB2C8C1E7A7F3C8AC23E426A0D57A2637FF274648659A9615206AAFE233D9426AF0B62D851802 +1AC24447 +F4A81ECD5917658D8AD0EE21179F +DFFF655EF4A4DF0D143873C6B5B73C8DD498DCC4CC784BFF25A48D875D0B1ED5D487CD3E443FE06902D8B92449C5C9FFF1C8C6D1A60314D55F924C2FC81DF0E8090B8233A952C5362293E231B52A0313524FBB5045A72994A306C9BDE5C7806D73552A1F +6D752211 +936DAF0F459516454A8CB5ABDAB0 +0E5722E2923F9E073562FC1A1A3CEB8103F99DF3EA907E9C5EC9FB7234356A7250EECBF1FE4F37B06F93B61E794BC942B5EF3D9544CE0C0016AB02453169469490356FC805E554297C9637F907583C2457FEE651DD387E62C1ADE04C10FB674DEC8A57ACC0FFE079871BA33300D73E6D404D9637E04118256E90 +3A463543 +C58133BDB0EF9AFC3B81E9D98442 +2D428200396FE10355A16C10412F697A98A211948D543C8E3A27014A62CC1BA9A770AFDFA4AF647BAD12BBA3043612CAEC858AFBA69DA0E9C23FC802DFFB619E7415056F3B106A44E884BF69436F8A098D5B64F26F9634798BF9ADE6910C335013209683B8 +152CE98B +19693E459A4B5A0A818785ED46 +B2205D9B172532BD5ACA8D8AD4ABC3318A70DDE13D05A544D48E0E90EF4736251C5A8BD48EDD06229513769F871C82D93E5D196D7FB0 +C2B1ECA4 +698480ED7876CB06704400D0E077 +AA632858CC9DBB844F8E3621AF4DA56F2CCA0D122F69E121DD757FB1CBC113F23C25D2EEACF54162E96345A21919282F704CA8BE981F7D2E9360835E70AB99C7E2738C402DAE354216CC53F7056511CB97F5C647432D0B24EE86971B8FFC34C030D89AE057EEFFBECD56858C52A663954FC63A +01041167 +1FC81A2EA1A0D34568FCC4521DA2 +8864D7351A0591723C6296645BC85A239ECEFB12BAC71A08188E9EB01C358438885BBC89B7D3CF0A620C6224EFB23300DF72200BCC2ED5C6F759871BE5DF24391679861334DEC631891C3DE252E2FB2316CDB0E55A953DFB60F8554B74063E486550B447E426F8615AA707C15EB8C03D75203208F998301A26EF939027FE +83CC +3B +769E10D3 +4CE1E421E7238491ED4CA1856F +591A0C69F87DC6B36F2E3B3CD338068AE41F686762451B73CF66EB96E68D68424EF85D256E947FA29251FC3F084DE0AE7F80A63C658C09BE6FEE8FB8B9884E792AF623ACF7115FBC4CEBEC9EF54E31628265BD946178AF92C744A92835D09E7844 +D5F97CAF +7AC9215A5520CFA835976E9A13 +8108F567551F06C9392377830D94129F4E5B783C6BB215BC53938015E0F5F30AFB22EB1CCEB96BA56557E61E7AD4D7F4BE7BA1A1B3F666B9814190FBC1BDDCE07CE9616A680FA0267F67A2982854B99EA4C2F7A139424C1BE87E9D507C5F9651741CE0 +929D692B +3EBEACBEF91F2EEF981265E9D8BD +AC9197ECE06CC8F4FDED8E22280FAFD7AE2E8A9B33CF5658C667BC50BF199A3BE5E5950551C3A7F9A5053300EB14BC146AB6F3DE84528F5430A034B6329113D648D3A7B0141EB802C0F78D77910630C793D626B14FD12B5EA455AE3162D85A5907352208F29AD562B99230A442EEFBE9FC39FF9D5F06F4B9227ABB035D04 +58406C70 +1EF7134303460F35A2BB9862EE64 +378E0F257EC61C7C9F92FC5F22CA698B7A6453C4F559255BE9F66D66B230D4FC9F6C1590730F8CF41B8006ECD6AAC1A48B100F9C044EA13359A065966395F924A2157864C53729BB8A747B44F494144D329F3DC229E320007C68F80C088DF40635CD021864B35E2ED5 +4A491333 +DCD129A05501DC07FDD925DC9422 +24F8089B6D971F72A14D6E0ACF812519AD9B05D7AB47FB6A6AE3A0C3182B382B25BC250DD681986549330F219D6926636E3AE2BE70AB3CF2AF5A20B825050B4564D974A6746A23A433976C7A0E203E0FC0D2941936878D0C5279013C5E9F3C479B8569A1D6AA83A6343A2A4DF5A109C50DC67C84F7696B26322E +4EA7BC74 +A1F6245CAF77001411534A63B8 +0CAEACF14407136F538BFE71F209CBB09E75F5834625FE705FE7EB585F906914E29EEFD8E03A87C9E8EB2700614BFA0711148E1C94965AD7DD2CB3 +2A968902 +AA6FA446A834798605A0FFB1DB +0040AC58D968D4C22CEF8B4C7ED5C495D9C3C1BA39EB82AE9D2EF81D29B6F114FEDE7ED692D88649ABAF1A9ADACA5890E9E23153C53D24B96ABD130DFFECCE000E6E3DA59F0F9A +7DDE8ECB +71103F71EC2EDE55A63645AA60D4 +04B3187DA8BA80070A4C23AE80114430EA62A4428AD9CA05EEDA1BB31A61576B7504A0064192DBDAFB2A921725D88B1E94DC29AB5BE071722AEC395BB014CE10BFF89B8F07A716672C3454D08928F5F0308685C2C292B65E7BE3DF42CDEB17CAAF0D02DD79C8BA4072F29DA3610C89 +D2E23166 +E5C2A5666B2B701209BC62B5AA +E1C61E6A1FFABD9893AD32C7493F8EF644B91365CF28AF4A3A430547AE5B030147065ECDE2AB60E7FE8610531D2C60AF725007579AF44D9A6E9124CD2D478D5F664301493D7F78864B7052584F5B43139FC73736D41B068AA7DA077D +75E8159D +430408AFD409661FBCFDFF21E9AE +53A0E833E1A8DC81045E1CF091BC05B374FB9860B7EBC5B525D78345A31CB2DA02832C8CFEA60FD1607555D747AA086AAFB5586745996FBCBC3DB056642A702253A7070BB603E152C97236B54EF73503A00314860571D25514BE3BC6CF4389265B1E9B2E1B2196E9FD36 +4885F29C +5F1E61F69681F91B31381AAC8C76 +42DA07EF8B524853ED2D5B3BDACDC78EA1AAE4297BDE2BDAB52B037550D555A6597DDF5DAB58C46B2B7E2CF26B32428C7C98EEE51A1FD99928555DFF79A122E51AAF1A65890E3F654B06846151F8B289BF981E9BE79CC21172296979170ED5EF389731B63B6DD1301B5835D100FC7A4101D6BF79925D56BE6DF1BB292C71 +22C205AA +044525AD38C9CB2C0CEE1AB910FF +575138105FF5F6EBF3C23D8CF02C1808F6E38B23A02FCDA72B600CD07A561F66AC6F2C14F693B02DF4E60BDFA9D18E1887DA5666CA173EE20752C49ABE5769FEC4097075DDFA098D30C75CBF08EAEF188526B8C488070DFABAC9D5073ABACBD5D24FD3CE1293075EC3BF5BFC0BDF5DE96D2A22353632A7A38AF1472B1113 +58A7 +128975 +A46A92B8 +6602FB1B9EA51AED2F801E4AF8 +9319F6B02506F0E5062DBDBDC9771BBBA1EF94EA460A1C9E33C74E90C53CD28D4472D34AED8FD98FEEE0C240FD3B0CF8FF105F0B4A75D79F3F57BBC2D34D34D0D435FD8A22009D357572EE78BC21E934C5 +848DD02B +006440A2641EB373ACC834EC6F25 +EBEDE4E7BD92413B2371DC6FCA52B640D52163F16411B3753C5724C92DBB0169F2BC362C6BFE1689D2CF049548CD17DF22D0C786C31749A1B7899F34D5D1CF52A263EBCE80660FF1007BF5ACEC6F9EDCAAD8B265FC8C89F73693B19AF682CFC450F6C19E +3D6FCF2C +0FC1BB45B116677A108701545E +CA6EF2169DF116E273D47C4FAEDF4C59460A22D126834540100F81224A767F4248A49481F259F8442A338F205DED1444982390845448E0B67F10A2DC74C72E4FCCFF7FD0B499647817DFB713F771E57276C1E0AA5E582376C5 +6FF293F7 +FB5236735C712403A33FE53F10 +0DE329F248A9269BCC84F3021FF90DB857B45603ED3C41617A35028F177E6F6EF4EA43C2CCAEE8E4DE5A +D9E9BD71 +1580790BC98FFF230193B619E5 +1942C0298AFB9E5CD90A4D7BE89FF99899A892FCD5F75C7874902EA1776A87B639A5508D39DEA6110D8E4D74 +4F0629DE +55E5A948BF06BF114C8FDD306B +66B9355ED97067B96F2BB19E056538971E6CAA7886F0 +EAD461E1 +12489AE5116D23E0ADAF078126 +540BD2D48B61B5A40B26A794C9ED8829A8EAD9EE3CA2D18AD02FC0064D4D28376B954978F37841301C34D43C6052EEF74A268122ACA9E409232B +5DC19517 +679D79C4D94885A30B138F4EDB8D +D0AC194D47710F058CEFAEB65BAEB0F2333E21D672DA9032A6C8C61DDE5EEC5E510E17ADB288EB6D035AE3B54F7AFB1F5983438FFBA1D26BACA80F164D11B1BE5555A73F501E7514079724B0D9A93CDFC526D8CDF8B41F725A21FCC43CE71495CE8367126DE70F6EE1E2ECE7A27C446F1B080A2A7291D3517A67F17513AF +35B4 +658CE9 +27D9F097 +0FEE2E5D5923B15B6B4D68434F +B79C7068319EBAEACAA924BD86CE7587D0814A595847B1B07A0324E43A76B96DF1350B87DC49DF29961D0AF825323F7FDB98B65867AB8A33538AEE44FB8F30A9815582788C66F1111DEB702CE63F7FEE3A9D4970E5D68C47 +62CA2D42 +FCE878F99842B2D652BCC4EE35 +00EC9AF9BB3FBAD28851AA0EC661A0F56BAEB4AD6FFBA6E563B151339C63B1EFF250D1BE85693F869A52861E8BA0073241E9035FF06CDC583AEA0EC923E9F6DE328355D760DAB48BE09876F7DA194048020C +67FADCFE +43FBAC40976411E5524CA2ADBA75 +E7143885B3DAC6EE3C9F054123DEA0114FC0E116F8DE2A1AD099D53172DE9FE3315C18524E45E10DD0EFF967344C44CA898281A4046845EEBDE8E88C46CAE27790AA3F8F5E25C0BCCB6AD82AB9CB523192FFD33E03E84548BC902EFE5BDCB2C792068348A1092839CE245206B859 +C287D1E1 +271C4E38A5EF124DB1F387FB03 +FAA5AD1297F3A71E9354C93EB9505FEA492362FFDAD7BDED8D61A418DFC26C650429A6B6E9B5090A5B06EE97AA1F963631FB22B3C3099CC2C18C794CDB3E7A873D24B024C9BACB58521789A5C0A88E63F3A93773DF06B9A213 +863BC42B +F953B6E25F4CE77AAF8F147851 +FCD850077C311A192030741733F1B3516DD6EEAA9C2BA97E24E3691AAC15925E879EBAC6D7AC30C66C4718D40CA71DAB4D9A40310E3776B44EA6EFAE2F78CD8555F4414B5D0C21B5122FE7C3DCE1B202280FCCA31C61C01527CA4420 +942E9381 +08F0B574C57837E66880FC9B4384 +EE6F9A15BC5560327B4F6743AD2727A4911552C1E0217F243CF1FC2551194D9B3BE06F9865D47336CDB17BA33D62A454B0424FBC593FDDC30E76B019A3B4B604388426FE93E451D96C8F58B3CE08826C6AA2D0422E28FDEA08E795F076D193C233E1A06DEDFE2EC5B3796C4A77AA6A65F7ACE47708DFA634621BE116F2A4 +A79C +479A387B004F6FD79C6A0D5764A7080898BFA72CA0083B51F04A9C1570E6D1418CB6969CDF39E309EC4B1AB661D5D2 +94C5D177 +A4AF68678C71B734D18DC23D2B9D +8D0304DBBC3407C4C92032CAAB38176962F3402CD76A51A1380A6BD24962936FDEFA581EC0F91CD7B259775F5D8880EE81A342DDB9174CCA1B1CF9561A21F9A2FC5D07BCAF8BE76CCD0D053A3A9A31EB4C9E94B38F44B7435FF3AEE3C72E651894F55DE3763972E7D95E2778C4 +84EFAB57 +404631F1F1976CC9817B7220B0 +71C88194A25679279B0BEFC8986DA7693F0F57007BA32AB1D24C7C97DD0AF52035AFF46A0CADF36D02655FE8475FA504983A78FB50B2A3A771F4322CB57D2B75E17CE341D8E371177287AB416E5AE1CF +4C522BA0 +E3791CEA42C9CA83A126BF4C061D +7029C0F857EC61342C0AA7107398AC77F8BD5236046BBD833F19B6B1E74F3A7D78C679193A760F56EAA823A9E822B51187F6DDF65E66E5DE061C2964F4A44E5575E4C82BE4C4DB31A0BF949C2793B455628F5F917129E169F3F1851EB7E861217B22FCEE0BCBF19BB0F63B562D838B1F6CB5E29B0659FD0FA8DD81FD782A +0C4A +3963441F08542FA781B86C8E044F9737F67F74CEDAF805422D754D8A1A7227B66E42CB +D4383C78 +47DB3E703D884CA549562F814A +74DA72CB01B69D8832D45CEBE899BDF4E95DADE97C7B660096E815231F20F95DB819E6367B1086A200EC33691AAE5609F82E6AD28109 +608109C1 +3E7AFB4CAF6CB15C3885A7C2DC60 +4FE2331DD30D15B8A1D2BFC69B160EC637B585AC39C155AB824B006966CC695C39D68E4D6C1FBDE51155435E71AD61405631A3B25E1A02788DD354A189EDBCC339E7A012867E9F31F7159A36CD1FDF823C249A12099B132569274974ADA8D191261E7948F6DFEAA658D7687D9B4796955F6054DA174B5F5675D31D4BEBEA +9538 +61AD269B7AF244DC3E67538C858F9B101D442B160438569DF3923FE702F4F9 +441C5A7F +E1359761A08BC7C5BC35279A4429 +B2939059FA1EB18F17EB7CC848F74973651E6179AA443B53EE59B14360B062E40F394DEA5868DA6E23B2E5FE5B9C9D04130FD4AFA54DC29BC24B32B6B1B6C9831B1A60F306BA238297ADD6026E8960206DC39227637DACCCC0B6212AC4F4AB613C2D158A387EB6CA2CC9300A +93A6BC75 +85217AD6A12E232FD48D7BF944 +66B0F6E06F44DBE9B729F3AF13B275CF29CAE414309FA59A9E589C5E71D744C452290533C7314CB39E139B97600000541318FC08620A1D35DDCEAA1B17C25D5F82FEC2797CB2 +408813C7 +01A04D4754BDAEBA358E6D378DB1 +8B9B53B5353CF1E1432A3DFF8DC567DC925DB510CE0A6C7E53863B6A11ABC0EA90C9918255B344179C32C6ED21C4CBC41CCB73E5E59FDF3079CA2C22D9A0C567E0B6BA92AE1B18002D25282354C4BC0F995EE50E720E8D1285B2C62FCB61824C1D9C64E204C76594E11C50EC51F00250978C5DBEE39091 +92238933 +42E284D7D19C0C136212F0305001 +6897C740ED688175DB1DC3E7F97FB19E335CE4506FFF6AA474281AD9EB2F518F3B6C2D6A1A11CA392AFDEEDA707818B7FDE8C381F9C9F1903D043AD895EE3CB1B0A88D5F12092AE795FE3CF1CDEE918E49C9A386150DF21A5694966029AF9F840604D8FEF7751317DEF1 +C46F880C +D45085FC3F2A843F33B10B777D +6D0303D8CD397CCC7074134087528A27810A70A2811A257284F7C30E1A072E9388E492BB9128B17A7A3AAE51301B93A032FF878FE19046BE6CE6BB434FC457B156250DA74F351FB6B0396E554204C73BC0A601D067E516 +CD4B744F +74ED3C25CFA9022A4956D49D8D33 +53FC7DF3D688D6DEDB00BB5A3CBB698532C15B469905C89678C86C046889A221592E77C99F1A1B4A70F392375DB75C75667D40DD9403C578A2F4D45870B573EEBED4CF5BFCB6684E558E8609F0E65B6DA35A7094D6B29B139EE3D62EAB053904DB412A59D44D6994F2C8C856DF27BC1856920DEE8C6BF8D998FE3881 +EAB1DBAD +5E75CE0427AF3ABB07753618A3 +74051DF4A2FAFD7FE0864E95EE387AD27F418B355AF697EC782AD02DE8603AFF85AB1322366BE5C917ADF4959E3D899E78F540DE3C71D18BA9080A7511A48B21B530F0EA42 +E6204374 +C5921581E1F964E282514629E5 +A25C4FDEC2E9FC114BEE20C21DA06E3830CFDC2DB4F4FAF81EBEFFB18114DBC39719D27BFD1FDAF16438F6394D793C062D5F75DC21655A52FD7B0E78121BB0374412EA7512CB85F4B7799CC0188410345A6FC87E0437959276A8619660B4545079C5 +00A24ABE +56678FE72CDF511F01D6F6D4F4 +FC37AE9584102A0B71E4A24EE5F223917726DF4AED4B101E3E825591C057FED1CC207F0AD82BBF122D098210559FC3373541623BD2C90AA667579EEE1E13FEEBEE3ADF3261562FB71163DB7563370BA98ECE6B8A6F008B9670 +8B168F61 +C407A5D951E8D915F25326761F4D +258EAAC33772EC05F4672F6B45BBEDCA7E3BABB3743807A453D7ADD7AB9AB68DED08C1C0219C94FA9971E19475A3413DF70F0347A1EE219D51CA925D20C5C615EC2986D4EB904A8D27FBDE1A494C366401D49F9257DC275BD4868E59FB1F6C5B2A01BF894BDE483DA165A2C423CD587EF0574537CC544CF86C34AC202278 +601E +D5D72885B02D17A9978231B4D067 +517BC345 +83D8C497EC1171C195144BF3FC0B +A485E050AF1CE853FDB2FAD0795E29100F49ED0F4A74BA2D34C3755BF5466D18A51B25609A11938E4E4DAF3715172B3AAA23EAA09A8961EDC5C4BB71E5645209978DC016278227ECF32650A9C9228AC874126033B97EA2A3ADA23DB54C7555DCC49CBFE8D277D404749C07A78C6D53F36F5680507C95C14BD7C6360903D3 +5243 +816C2C51CF9B2D586E11E48A61BA5D1CEFB0F5E37D0C0D7031 +A0F0766B +00D7A4A5275E49B5EDED7CA2BB35 +988541C9118923E973DC30536FEABB0CD8D62C7A9971AFC1DFCAB3C9D3C13A673CA973738ECC1A44032CA3BDF2BE9088D68E3BCBD3299AC48A8623FA84AADA62632FB7B4667ED97E61331093317CFD8CEC12B699401B299A7DC1BFA98F56EB2E49375D6C73A32A0AF68AFDA9471DBADDDDD6E839FDFBB7A1538BBBF55D20 +CC29 +C7C27DA7 +B760B499A5914036DC2470A8B6 +38AC7741BB8602E057CE0D971F4480056DE4115261D89F5541BE8DC8A01BFF698E7B201EB48E8F38CE30E8B0739FC22F6D6CBFA43B50851F645F1938FFBE4B +AE381DF7 +83C47AAB0E8ACF2F989F9CA02930 +6E7E1E45D667CC05BFC29734BBE5F15C6277D78C1D1FB2AB56B2DADF26F0984984833C4D0E19E1D9571CF4FD61DB6C798D16021E291E26AF2B51029DCA982D30E569498DD1A526D4C210944626CCB2D13D4F491A4EDCD44263B133FC9C51BB0A359DDC4C9DD36FCF6F +AE3C555A +937F73149A442B61ABBCF38CC4 +A173A9ADEEF9B2F6BAB19CF6CA7652A4F2AD8B387F4E +4C590164 +9803B5DAE39A0CB1496D7364D550 +859170B44A583C9C +46DFD711 +79744D537275F2BBFA70C0B01E9578E82DE1CF1B8112448F61DB9ACAEA1BEE1F71F4 +AC51BA4EE00154A03B4A5613779348D371E77D7468DC8BF75861391AB6FD4083CCAF7A1BF685 +71B451B1157B9A50B7E7D5437444D5EE743C0F272CB7A2597FCF35 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +%Defining font PSOwstdutchb +%!FontType1-1.0: PSOwstdutchb +10 dict begin +/FontName /PSOwstdutchb def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001000 0 0 0.001000 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 1 /C0032 put +dup 2 /C0045 put +dup 3 /C0046 put +dup 4 /C0055 put +dup 5 /C0067 put +dup 6 /C0071 put +dup 7 /C0078 put +dup 8 /C0079 put +dup 9 /C0082 put +dup 10 /C0083 put +dup 11 /C0097 put +dup 12 /C0098 put +dup 13 /C0099 put +dup 14 /C0100 put +dup 15 /C0101 put +dup 16 /C0102 put +dup 17 /C0105 put +dup 18 /C0108 put +dup 19 /C0109 put +dup 20 /C0110 put +dup 21 /C0111 put +dup 22 /C0112 put +dup 23 /C0114 put +dup 24 /C0115 put +dup 25 /C0116 put +dup 26 /C0120 put +dup 27 /C0121 put +readonly def +/FontBBox [-10 -209 798 694] readonly def +currentdict end +currentfile eexec +D9D66F633B846A989B9974B0179FC6CC445BC7C8A959A39A32E9DCE7FAEF17EE3BEC9F +50E1A6FCA651FC4B3769A0A91041557502E25A5D6180FE25A3D11BF079E1DF66E54EE9B7C229AF891739707A2A0EC140306B5E43E52B79BFB89E459E50 +6EC6F610A70775A31C460976C4F79449D86E57ACE491E5C6BF20CC4307B1DAF7630252 +E9AF8CFB69B50EDAE9D36A6104AFEF8832F920FD2346B2C7104CD11E3BEE999CFA9F5A +49DB3173EE48D1C82994237F360407B022E0B4 +502E94EA8B493651EF2D03F0B513D655047568325B512AE6 +6AC6F53F3848CF70DE25481CC65D8B1A5793AA +3C4282D111112BEE28AFCA7A3808D4444C4669CA +84EAAAF989219F51AB3476A1B0B5F2246BC306E6 +625C6679C417ED2A8E9BD010DE37D40265074C26842697C64AA1341376544BC83CAB3F1D3DC53F +CCE6DA147CD7539424E5308F +85563A985DE93ADB17 +9A9AF889 +F2B5A459E50EC2C5F74D56DF7C +21D7CDACAACFBAC6D3A5E4F02E0C6A5B6DD31793EE0464 +A8C48F24 +32C23E08D4D4272B6A1D3A4BD9 +F0B7E0B23A94EAE7B8DC531296C9D575D6B11CBC686CFE26F26E5E9581692B +FF362FDF +B7C40F292210E327D337569345 +F676ECF8BDC0D8F41FBA2ECD2A54B00C28775A7CCE7A11AB86F8BB778B8DC54B3B61EB3C5B481948D0DD24AE +7007C12E +0955652917D22BE349992820B11E +A1FFAD64BFC10FB7B79E1A4452832D542E4AF445F2C03A0E0941A7860C47DF87DDC8A14726CA2F007E0A8456ADBE96CDAA727E5A50CB8FA3551FCD39B86EB0B3AB277AB49440A0CC2A86F0BCE3867DEB48C0372131DB05014059BF4C1C2B23B7CE53911B928B27B2 +8B24FC66 +1A109C4413374BDA30D3D24C4CD8 +D9B4A0217F654723ED1C1B589F110CAB1F55C688E9025572BCE5DC6B20BB1A875C3D9D83A258F892AB0ACE94D23CB4DCA80B94996A860EA73273EB6B679AF95FE413DB11EF2B57FAF0FA2A4E6E0AE838FBADC8CC3E11A00251FA0135884325419317F60ADF8F4DA77FA25F7656BE7407BAC3B94E7E6BE7 +36E26E9A +CA27479A941DE32A67F1C389CD +51E7B2BC41D079B4C3E73730DCBEA23A72AC15D90B11BE25038DD198663BCC3AA96AE63723AAC338C6EA6E52280506089797C0AAD9D2B89B3B29ED09AA4BCA21ECB076F45B02935476C73D7698EF2228CC727C3F9F0499C3A3CEC839C5AF8D +64CBC07C +E0B65B48437F35926717801BFF29 +280E8DF8686E35A5C28E566B21D707EF5929BD0D99411B7A1EDAC93801669B8D162A6E30CDE29896FF70C7343A9E5E3863AB6FCDE00362F5FD52B2DF9594DCA5D390EE0A89501A9B1801DF00E4EEC0620A72D0BB33759E5E00D49E871813E8AEB080CBFF20A7B87650 +B3F3184E +8ED6A0BA8EB50B931E4A506E87CD +85E84C544D42B61F3ECEC2097F1F8A597DB77CA4955B7EA20FCBEB122A2547BDF8D5E96DD71F49C08D651D4171CBA9101D0D01B0D95A3FB534B1879F89F4718BBD4ABC12643477CA56BC4BEC27C65A86B3866495870C2A630874052CE45A910140170C4D524FBCC2080BF643337C2B2334EEC144AC +F0B6DBF0 +C2804F74C1A7F178FA199AB5368F +F41481D6780E00E372D10513107EACFEBF21C1AAA76BBCB5AAD58E36FF6C70DC36AA3E877CAF78A7D1121B161A5A1D927B8979419698A2DF7323BB2E6989FC9F88AF30BBD7B2B23A4B4DB93211A3904143A397A3D6252925614BB8F52D1738F47D8C313D51F05C945FA8ED07B83516B057E00D505711CCF56AE74AEAA798 +0807 +BD5EE254 +18B73B2408EFD55504E204FC210E +9E3DD63FA2F3CA2986D85DC36D1B79ADDA315DA9B00248A598D57A9B50338404805C8DFC39F1F756DA3D1FB38405839A163BFB2ABF2EBA1EE7F5E9CA3E4DE71054448257E9DFBF360699EDE5C0554BABCC4F799AF8DCE013FCED08B4D31E0E8D74EA079D523BD5CE53A64251A835C36F782BD2F42919E082D46797A4FD7C +0218 +399DC764 +C685D48C +336AE532F3C49C81303032C031 +B298E84E3A4AD8CD9B93F0BA6307E3BBABE21BB9D238F6516A2960F92BD93A9F6759890B6A4CBDD06908A45126CF3235D73215DD7E34D85E7FE478DFF0C9769AC04A71F397CCC3570D5B7F16F31814DC1C85BB475AE98D184CFEE58F79BC +39F3766B +536B1B56976695F300B89AC522 +0EDA163A861D2C40D9F70EFEB884C072B0D03B01C1387EB0594D99F2B7FB0C5532115567FAD04FA1F8865E51F5636B57DB1316C7EDED728E2B7B73B90A2701667941D3F13D23E9EB0081BA930D4D85C6915A +F04E8373 +CF0505CEE1D4657F89C08674717E +87E64817A266D2AE95A43AE7678B9CC73C32659467F6ECD6D345BEC2BEA013C12216EFAE2C3DEAB05616D18751A52892C1F2BB0E69A026167CF5047AA98306972665849FA8435671FA8566B9A5B9C146CEE4DD8560EFE0F1EB2848B8B8717D72D7216F6FAEF584D696BDC626 +AE46A8D6 +CA6D320EF2D4A30EA5F8048550 +B79DF3DE4817B83E9F07E9B7E929DA6A48667F110D30D607647C5BE5106296158879E56BADF5B6578A44136A55F2A4ACE14D1D87EBDF6CDEA1495B675EF38B39B09760CB9216EB962E7147FC39586998D05C850E0B7F19777311114F +A49406D8 +879F5F1A8363F96F347C52C12A +5656C7B3ACE757A10A5DC506DF3A361449B77423E5FD3AFEAC5DA620FD9F3515D59BA7286B1ADA6EA1F92926F20BD5CDCC3783407F168A03CDF44FEB85668D036D61117ADECA5553DCD988D416C0B02F3B8EC21753D302B5735982F5EE +72DB8B2B +C3EA62C9271F8B39ABE98111D3 +19AFF4276F42BF4F4F9DF2444F05E64DAB30000C739B01AB33F65E2F35145B07CFEE8ED7FF2010513053FB40DEF92DC8696E80086631FDAD04B7EDF38861FFAFC508E4F753F950CA41841170A36F +D8B841C7 +480334E023321D948CD8AF3E5E +B9BC7BE12237EAE79014B0DC1D32A84CD5CBFAB0C3F76D65841973045AD264E2B75E7047325557F7FF32E0E6ECF81A3852775D80 +7B96D026 +3CE4C91883998579DC3452CAFC5F +902D6E00576D6EF361DDCA551CA2476352114B0A2D2958918BCBAF900181CBF7745EF0EA083B2F1C22B4C69746F5B6734E25CC3E5340CACF6189322E978C72CAF332115105A0BF8F381DF5DE5369818F7D01079F3F9CF0F38719D6BCA36AAB63D07CD907574DA3D1A5CDA04165D3E7ACC9A0B8671C439CF29E397D5CC643 +D851 +B5D485E2A06F2919BA85739720C48ADE3B64D1278B998E42DC8F7CEE +EDA20C15 +EF9F47E47B4FEC2BB47BF09B1882 +9BE2523F24C0BBFBF18817A6AAAD4B098436539627644243DE9AE879E480107BB8B9A9A68558060AF21121CF7E8546F69527BD6FC1DC3E46E1583DB0F0F402F195D3E0D1B9FA2C7C572513631A7965D00C5A2D6F49390347DD9D9319D87614B7CDAFD62E2FC24C +2EE3A106 +6640ED242C93A61728D876BA28 +29A4D55D9ACD054A9028F1D303411AC7B278029A98B6F3063A5CF0C577BBF2E74463DC9A9348517ECF1A0BEE75774E7B064BE1208D9BFA16508F85447DBD58E31C77125E1FBF +1363FF5A +D8A08CF87FBDA59B2A7D997EFF71 +C0B00B95B4BD53239E4DBC241BA7B4D6B552FA1A9DE22BCCB7A39047014D24B62C5402E3DEFF11C83D756301039C6D9C3C6D71183066B6CBC3E757321FF54580E0989577706C26B1E4A08D02A9FAEF2863243B6CC3C9AA7C6219E7EC65D30CCD0422F6BD1E9AD6F0B9D8FFDC65AA6F8D97 +FF5984ED +6793281E9AE22906896C1CD7DE +9E9C0848C4CF3B48BAE89B32848372CE8225792F846B3C5543E376C0A5472D603D97E7C3EBA582A6A90CD8F05CAC8F4A06A9AFBB88AE4ACC8869F1216A84E3395929105E976A0DDC19641A1C54F54A56B6468D6EE8DD80E152 +E1D63F70 +85F1ED7CD333580A06E4C0F28E3C +C64BB493F64E1AB9A26018BF3DB445CCF7BF30DB8EE225A3D158FECF8B3E0B0D95797678C8E344C8430513C0254E42613FE03CA495C3C0123C2001A3C33EC40A54AE2B64CFFF9A924713890CE67154F3FB26DA040650BF8BCD5352F8EA4A9EA694952CDCB27713EAAFA2A23104352DDF669AEE9267FF06EFCF +11AED49B +0F13E836E026AD7ED02746DAB7 +6A6600D7D8313FC81E6E3F5DF94729668C3A962F3B645A4DDE91CF4DE35FA13CD586C4E1B871C754057EEEAD42B98C08D6FD7A61F29141936FBF976171463075445FEE4F +4491B450 +BB210F85A1A230D223A8080F5B1C +CDBA6786BA42181CD8393BE4FC2B97D791F62022B4DB2F56CA964B1D4E06F2B4096A53CDDFCA3D3E0FC0D5CEF9FE98A079E12E38253F6361EC07AD3970A8936FB31BD06054A78D33217546C95B521304504D3FD3E2CB729B79DC90B75C095B8474A32818C51DACD56502482A0214DCDC92BC053CCB28BCAF4373C903E95E +1647 +738C4E6154E1A45273801F2F24DA057717FC8215FCC4 +D492FA63 +6B229CE12CB466C8D951F46905F9 +EB828410D68DBE14B11094379BD46503361A2B79ACB734ACB5FDE207F63F4C5672FFCA2641E383E81F31B584B2DD6BE8CFC141A882D9C3AA3D7EF33859BB6BE892B68B541C7C639ED1EEFE5572D0AE84545184DE4A6D314C5001DD65DDC1EE5B4C902B40261F38EBD761ED088DEA1AAF43503F207C4DEA520D04BC27BA91 +729C +0A +F1D37D0D +CB3F326E1213082DE9818EB11C41 +14060FAD4E1DC8B7 +1DF4C436 +93F430C6DE222AFD666D549356677DB85465CDB5B31C2F4BEA9D1D8908B01AD4CEA4 +C4D7424DAB8BB0D1D062AEE68E0172085DF3D731B20C86915744EA5ACF93A3D9736B853035CE +4AC8D778A0C94319DED046602D3DF67069AEC517DF85CCADC735CD +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +%Defining font PSOsymclas +%!FontType1-1.0: PSOsymclas +10 dict begin +/FontName /PSOsymclas def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001000 0 0 0.001000 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 1 /C0069 put +readonly def +/FontBBox [106 45 775 713] readonly def +currentdict end +currentfile eexec +D9D66F633B846A989B9974B0179FC6CC445BC7C8A959A39A32E9DCE7FAEF17EE3BEC9F +50E1A6FCA651FC4B3769A0A91041557502E25A5D6180FE25A3D11BF079E1DF66E54EE9B7C229AF891739707A2A0EC140306B5E43E52B79BFB89E459E50 +6EC6F610A70775A31C460976C4F79449D86E57ACE491E5C6BF20CC4307B1DAF7630252 +E9AF8CFB69B50EDAE9D36A6104AFEF8832F920FD2346B2C7104CD11E3BEE999CFA9F5A +49DB3173EE48D1C82994237F360407B022E0B4 +502E94EA8B493651EF2D03F0B513D655047568325B512AE6 +6AC6F53F3848CF70DE25481CC65D8B1A5793AA +3C4282D111112BEE28AFCA7A3808D4444C4669CA +84EAAAF989219F51AB3476A1B0B5F2246BC306E6 +625C6679C417ED2A8E9BD010DE37D40265074C2684268F16195489648993B9C4D3B534FA887C +DEF605FA87B991F4D20A8F78DACE +5A54C070E03D5C59D9D2D3E06B09CEE028D68B62AB3AEC43C1DD20BA70D288597D9BD8E06818FF764EBAB436723988E8D7CA59E16D39032516BFC5D552ACDEEC6BE938BEF2F43CFFBC811C3626C4DF5F8CF080676520B51C60CEDAD1FE6C92D1431C702174CE517A8FA9377D075A0B6833DAB101DB65397F1419EF5F0016 +004F +6F0824F9657BB4F1C8F981709956865F6855EFAE +9242AD55 +91BBBEE163D844DDA894E13190C9 +2480439E4C71CADA +BD043A9B +A315CAF72652AA7FE6DB2E84D82A6111CE4DE90C02DA0AFFE2620922262A45AB4ED0 +EEC9F4520DD12703442F7D028D4526BD8B771E09FBE11B2749E2D3906894E8D4BFD3F379F14C +3C874F550606965E22FE487B247B5C2D06728490C8F2A3B588CDFC +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +/DPIx 1270 def /DPIy 1270 def +72 DPIx div 72 DPIy div neg scale +0 -13970 translate +1.00 1.00 scale +/wst:dutch12 12.00 /PSOwstdutch newFont def +/wst:dutch12b 12.00 /PSOwstdutchb newFont def +/wst:dutch14b 14.00 /PSOwstdutchb newFont def +/wst:dutch10 10.00 /PSOwstdutch newFont def +/wst:dutch14 14.00 /PSOwstdutch newFont def +%%IncludeResource: font Helvetica +/wst:helvps10 10.00 /Helvetica /wst:helvps ILEncoding 0 declareNFont def +/sym:clas10 10.00 /PSOsymclas newFont def +%%EndPageSetup +GS +0 13978 10801 13978 10801 0 0 0 clp +wst:dutch14 SF +0.00 0.00 0.00 1.00 setcmykcolor +<1c2b39352b372c11011201132b33292e32273730012c3437011b2b27383a372f332d011c2b393c343730011d> 2207 558 0 7384 -1 s +<2b372c3437322733292b> 7375 558 0 8593 -1 s +wst:dutch10 SF +<0b0a> 9346 13385 0 9522 -1 s +wst:helvps10 SF +<4e6574706572663a> 1322 13267 0 1949 -1 s +<205265766973696f6e20322e313b20436f7079726967687420> 1949 13267 4 3868 32 s +sym:clas10 SF +<01> 3868 13267 0 4019 -1 s +wst:helvps10 SF +<2031393933b131393935204865776c657474b15061636b61726420436f6d70616e79> 4019 13267 3 7133 32 s +wst:dutch14b SF +<0a0f0d19111514> 1271 1458 0 2055 -1 s +<00040300070f19160f171000051513130b140e021211140f00081619111514180009> 2055 1458 5 6101 0 s +<0f100f170f140d0f> 6097 1458 0 6974 -1 s +wst:dutch12 SF +<202e2f38> 1271 2005 0 1665 -1 s +<00382b29392f3433002a2b3829372f282b38002b27292e00342c00392e2b002d3134282731> 1665 2005 6 4842 0 s +<002934323227332a06312f332b003435392f34333800273b272f312728312b002f3300392e2b00332b39352b372c00353734> 4842 2005 7 9461 0 s +<41> 9461 2005 0 9531 -1 s +<2d37273207> 1271 2249 0 1787 -1 s +<001638382b33392f2731313e05002f39002f38002733002b3d3527332a2b2a003b2b37382f343300342c00392e2b003a38272d2b002f332c34373227392f3433002a2f383531273e2b2a00283e00332b39352b372c003c2e2b33> 1787 2249 14 9531 0 s +<2f333b34302b2a> 1271 2494 0 1988 -1 s +<003c2f392e00392e2b00062e003435392f3433002f33002d3134282731002934323227332a00312f332b003435392f34330027372b2707> 1988 2494 10 7076 0 s +wst:dutch12b SF +<051513130b140e021211140f0008161911151418000a1b14190b1a> 1271 2928 2 4200 0 s +wst:dutch12 SF +<1e> 1271 3311 0 1434 -1 s +<2b3b2f382f3433> 1426 3311 0 2056 -1 s +<000a070f00342c00332b39352b372c002f333937342a3a292b2a002b33343a2d2e> 2056 3311 5 5057 0 s +<00332b3c002c3a3329392f343327312f393e00393400343b2b37373a3300392e2b0016332d312f382e002731352e27282b39> 5057 3311 7 9531 0 s +<2c3437> 1271 3556 0 1538 -1 s +<0032332b3234332f29002934323227332a00312f332b003435392f3433003327322b38070017> 1538 3556 6 5270 0 s +<343700392e2f3800372b2738343305002934323227332a06312f332b003435392f343338003c2b372b003835312f39> 5262 3556 6 9531 0 s +<2f33> 1271 3801 0 1445 -1 s +<001e> 1445 3801 1 1660 0 s +<2b3b2f382f3433000a070f0700202e2f38003835312f3900372b32272f3338002f33001e> 1652 3801 6 4745 0 s +<2b3b2f382f3433000a07102731352e270700202e2b372b0027372b00393c3400393e352b38> 4737 3801 5 8076 0 s +<00342c00332b39352b372c00293432> 8076 3801 3 9461 0 s +<41> 9461 3801 0 9531 -1 s +<3227332a06312f332b> 1271 4046 0 2296 -1 s +<003435392f3433380700202e2b3e0027372b0026262d3134282731020027332a002626392b38390638352b292f2c2f290702001334392e00393e352b380027372b> 2296 4046 9 8110 0 s +<002b33392b372b2a00343300392e2b> 8110 4046 3 9531 0 s +<3827322b> 1271 4291 0 1736 -1 s +<002934323227332a00312f332b0500283a3900392e2b3e00323a383900282b00382b35273727392b2a00283e0027002626060602002c343700293437372b293900352737382f332d070018313428273100293432> 1736 4291 15 9461 0 s +<41> 9461 4291 0 9531 -1 s +<3227332a> 1271 4536 0 1782 -1 s +<00312f332b003435392f343338002934322b002c2f37383905002c343131343c2b2a00283e00392b38390638352b292f2c2f290700192c003433313e00392b38390638352b292f2c2f29003435392f3433380027372b003934> 1782 4536 13 9275 0 s +<00282b> 9275 4536 1 9531 0 s +<38352b292f2c2f2b2a05> 1271 4781 0 2126 -1 s +<00392e2b3e00323a383900282b0035372b292b2a2b2a00283e00262606060200343700392e2b00372b383a313938003c2f313100282b003a332a2b2c2f332b2a07> 2126 4781 12 7993 0 s +wst:dutch12b SF +<0612150c0b120008161911151418> 1271 5214 1 2674 0 s +wst:dutch12 SF +<0627> 1589 5598 0 1871 -1 s +<382f3f2b38352b29> 2033 5598 0 2764 -1 s +<202e2f38> 3177 5598 0 3571 -1 s +<003435392f343300273131343c38003e343a003934002731392b3700392e2b00382b332a0027332a00372b292b2f3b2b00283a2c2c2b370027312f2d33> 3571 5598 11 8825 0 s +<41> 8825 5598 0 8895 -1 s +<322b333938> 3177 5843 0 3722 -1 s +<00343300392e2b00313429273100383e38392b320700142e27332d2f332d00392e2b0027312f2d33322b333900342c00392e2b00283a2c2c2b3738> 3722 5843 10 8895 0 s +<292733> 3177 6087 0 3491 -1 s +<002c3437292b00392e2b00383e38392b32003934003a382b002a2f2c2c2b372b3339002934353e2f332d0038292e2b322b3805003c2e2f292e00292733> 3491 6087 10 8895 0 s +<2e273b2b> 3177 6332 0 3599 -1 s +<002700322b27383a372728312b002f323527293900343300352b372c3437322733292b0700192c00392e2b0035272d2b00382f3f2b002c3437> 3599 6332 10 8895 0 s +<392e2b> 3177 6577 0 3467 -1 s +<00383e38392b32003c2738> 3467 6577 2 4507 0 s +<000d09100e00283e392b38050027332a003e343a003c2733392b2a00393400352738380035272d2b0027312f2d332b2a> 4507 6577 9 8895 0 s +<283a2c2c2b3738> 3177 6822 0 3813 -1 s +<00282b2d2f33332f332d0034330035272d2b0028343a332a27372f2b3805003e343a0029343a312a003a382b0026260627000d09100e0207> 3813 6822 9 8895 0 s +<202e2b> 3177 7067 0 3537 -1 s +<003a332f3938002c343700392e2f38003435392f34330027372b003c2e34312b00283e392b38070023152b2c273a313911000f00283e392b3824> 3537 7067 10 8493 0 s +<0612> 1589 7391 0 1929 -1 s +<382f3f2b38352b29> 2033 7391 0 2764 -1 s +<202e2f38> 3177 7391 0 3571 -1 s +<003435392f3433002f38002f2a2b33392f29273100393400392e2b000627003435392f3433003c2f392e00392e2b002b3d292b35392f343300392e2739> 3571 7391 11 8895 0 s +<392e2b> 3177 7636 0 3467 -1 s +<0027312f2d33322b3339380027372b002731392b372b2a002c343700392e2b00372b3234392b00383e38392b3207> 3467 7636 7 7618 0 s +<0628> 1589 7960 0 1879 -1 s +<382f3f2b> 2033 7960 0 2369 -1 s +<202e2f38> 3177 7960 0 3571 -1 s +<003435392f343300030615191c20161e> 3571 7960 2 5381 0 s +<22> 5358 7960 0 5520 -1 s +<121a1f00293432352f3127392f3433003433313e0400382b393800392e2b00382f3f2b00342c> 5497 7960 6 8895 0 s +<27> 3177 8205 0 3282 -1 s +<00283a37383900342c00352729302b3938002f33> 3282 8205 4 4921 0 s +<002700251f201e16121b00392b38390700202e2f380029273300282b003a382b2a00393400403527292b02> 4921 8205 9 8895 0 s +<392e2b> 3177 8450 0 3467 -1 s +<00382b332a003727392b003c2e2b3300392e2b372b> 3467 8450 4 5357 0 s +<002f38003334002c31343c0629343339373431003537343b2f2a2b2a00283e00392e2b00353734> 5357 8450 7 8825 0 s +<41> 8825 8450 0 8895 -1 s +<3934293431> 3177 8695 0 3629 -1 s +<00282b2f332d00322b27383a372b2a07> 3629 8695 2 5166 0 s +<0629> 1589 9019 0 1859 -1 s +<233727392b24> 2033 9019 0 2531 -1 s +<202e2f38> 3177 9019 0 3571 -1 s +<003435392f3433003c2f313100372b363a2b383900141d21003a392f312f3f27392f34330027332a00382b373b2f292b002a2b3227332a00292731> 3571 9019 9 8825 0 s +<41> 8825 9019 0 8895 -1 s +<293a3127392f343338> 3177 9264 0 3989 -1 s +<002c343700392e2b003134292731> 3989 9264 3 5165 0 s +<00383e38392b320700192c00392e2b003435392f34332731003727392b0035273727322b392b37002f38> 5165 9264 7 8895 0 s +<38352b292f2c2f2b2a05> 3177 9509 0 4032 -1 s +<00332b39352b372c003c2f3131003a382b> 4032 9509 3 5484 0 s +<00392e2739002f3338392b272a00342c00292731293a3127392f332d00392e2b003727392b002f39> 5484 9509 7 8825 0 s +<41> 8825 9509 0 8895 -1 s +<382b312c07> 3177 9754 0 3544 -1 s +<0017> 3544 9754 1 3756 0 s +<3437003234372b002f332c34373227392f3433003433> 3748 9754 3 5975 0 s +<00141d21003a392f312f3f27392f343300322b27383a372b322b333938> 5975 9754 3 8895 0 s +<3c2f392e> 3177 9999 0 3563 -1 s +<00332b39352b372c050035312b27382b00293433383a3139001f2b29392f3433000c070023152b2c273a31391100333400141d2100322b27> 3563 9999 9 8825 0 s +<41> 8825 9999 0 8895 -1 s +<383a372b322b33393824> 3177 10244 0 4174 -1 s +<0614> 1589 10568 0 1916 -1 s +<233727392b24> 2033 10568 0 2531 -1 s +<202e2f38> 3177 10568 0 3571 -1 s +<003435392f3433002f38002f2a2b33392f29273100393400392e2b000629003435392f3433003c2f392e00392e2b002b3d292b35392f343300392e2739> 3571 10568 11 8895 0 s +<2f3900372b363a2b38393800141d21003a392f312f3f27392f3433002c343700392e2b00372b3234392b00383e38392b3207> 3177 10813 7 7660 0 s +<062a> 1589 11137 0 1882 -1 s +<202e2f38> 3177 11137 0 3571 -1 s +<003435392f3433003c2f3131002f3329372b27382b00392e2b00363a2733392f393e00342c002a2b283a2d2d2f332d00343a39353a39> 3571 11137 8 8505 0 s +<002a2f38> 8505 11137 1 8825 0 s +<41> 8825 11137 0 8895 -1 s +<3531273e2b2a> 3177 11382 0 3772 -1 s +<002a3a372f332d002700392b38390700192c002a2b283a2d2d2f332d002f3800382b39002e2f2d2e002b33343a2d2e05002f390032273e002e273b2b> 3772 11382 12 8895 0 s +<27> 3177 11627 0 3282 -1 s +<00322b27383a372728312b> 3282 11627 1 4399 0 s +<002f323527293900343300352b372c3437322733292b0700152b283a2d2d2f332d002f332c34373227392f3433> 4399 11627 5 8895 0 s +<2c3437> 3177 11871 0 3444 -1 s +<00392e2b00313429273100383e38392b320003392e2b0034332b00373a33332f332d00332b39352b372c04002f380035372f33392b2a0039340038392a343a3907> 3444 11871 11 8895 0 s +<152b283a2d2d2f332d> 3177 12116 0 4165 -1 s +<002f332c34373227392f3433002c343700392e2b00372b3234392b00383e38392b320003392e2b0034332b00373a33332f332d> 4165 12116 8 8895 0 s +<332b39382b373b2b3704> 3177 12361 0 4097 -1 s +<002f3800382b333900393400392e2b002c2f312b000839323508332b39352b372c072a2b283a2d0023152b2c273a313911003334002a2b> 4097 12361 9 8825 0 s +<41> 8825 12361 0 8895 -1 s +<283a2d2d2f332d24> 3177 12606 0 3958 -1 s +GR +eop +%%PageTrailer +%%PageResources: font Helvetica +%%PageProcessColors: Black +%%PageCustomColors: +%%Page: (22) 22 +%%PageResources: (atend) +%%PageProcessColors: (atend) +%%PageCustomColors: (atend) +%%BeginPageSetup +bop +%Defining font PSOwstdutch +%!FontType1-1.0: PSOwstdutch +10 dict begin +/FontName /PSOwstdutch def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001000 0 0 0.001000 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 1 /C0032 put +dup 2 /C0034 put +dup 3 /C0039 put +dup 4 /C0040 put +dup 5 /C0041 put +dup 6 /C0044 put +dup 7 /C0045 put +dup 8 /C0046 put +dup 9 /C0047 put +dup 10 /C0048 put +dup 11 /C0049 put +dup 12 /C0050 put +dup 13 /C0051 put +dup 14 /C0052 put +dup 15 /C0054 put +dup 16 /C0057 put +dup 17 /C0058 put +dup 18 /C0065 put +dup 19 /C0066 put +dup 20 /C0067 put +dup 21 /C0068 put +dup 22 /C0071 put +dup 23 /C0072 put +dup 24 /C0073 put +dup 25 /C0075 put +dup 26 /C0077 put +dup 27 /C0078 put +dup 28 /C0079 put +dup 29 /C0080 put +dup 30 /C0083 put +dup 31 /C0084 put +dup 32 /C0085 put +dup 33 /C0087 put +dup 34 /C0088 put +dup 35 /C0089 put +dup 36 /C0091 put +dup 37 /C0093 put +dup 38 /C0096 put +dup 39 /C0097 put +dup 40 /C0098 put +dup 41 /C0099 put +dup 42 /C0100 put +dup 43 /C0101 put +dup 44 /C0102 put +dup 45 /C0103 put +dup 46 /C0104 put +dup 47 /C0105 put +dup 48 /C0106 put +dup 49 /C0107 put +dup 50 /C0108 put +dup 51 /C0109 put +dup 52 /C0110 put +dup 53 /C0111 put +dup 54 /C0112 put +dup 55 /C0113 put +dup 56 /C0114 put +dup 57 /C0115 put +dup 58 /C0116 put +dup 59 /C0117 put +dup 60 /C0118 put +dup 61 /C0119 put +dup 62 /C0120 put +dup 63 /C0121 put +dup 64 /C0122 put +dup 65 /C0124 put +dup 66 /C0262 put +readonly def +/FontBBox [-50 -256 978 764] readonly def +currentdict end +currentfile eexec +D9D66F633B846A989B9974B0179FC6CC445BC7C8A959A39A32E9DCE7FAEF17EE3BEC9F +50E1A6FCA651FC4B3769A0A91041557502E25A5D6180FE25A3D11BF079E1DF66E54EE9B7C229AF891739707A2A0EC140306B5E43E52B79BFB89E459E50 +6EC6F610A70775A31C460976C4F79449D86E57ACE491E5C6BF20CC4307B1DAF7630252 +E9AF8CFB69B50EDAE9D36A6104AFEF8832F920FD2346B2C7104CD11E3BEE999CFA9F5A +49DB3173EE48D1C82994237F360407B022E0B4 +502E94EA8B493651EF2D03F0B513D655047568325B512AE6 +6AC6F53F3848CF70DE25481CC65D8B1A5793AA +3C4282D111112BEE28AFCA7A3808D4444C4669CA +84EAAAF989219F51AB3476A1B0B5F2246BC306E6 +625C6679C417ED2A8E9BD010DE37D40265074C26842242D2C7C52988A16D3AD63FA0A6A531F598 +82C7FDFCF9F77A295F11CFFB +5B12FD403323523254 +4E86BA9F +872D4E5538407B54B82E4D287BF3 +AC834D9BC0FD6BFC81BB715ABB4BBD607B01EC7BC65255207A5A1FEB4F62003E77C881F998D36FEAC8F869D9B0BA2345695CE363794847517F8684AF2969A272643B83A4D48A7A4C21A800388C7BA473EE8624FA022F342D4954637BDD0F96619BDC2394687B3C +911BDF29 +075739A4F1B7FC51C345CC50FE +6111CCB4582232183D658CB8E2CA78EF520D16202978DF7E19F6A23EE7A86010E4ED7555C0DCD97826F4DC8361AD8068AF2FA17B72AFBA70 +798278F3 +C43AAD10FD475C424242768A1B +BDEB38414BD766779C2FD0C1C98CA4997E820D2A0EE39CECC13ADA3A7FC1E5CD7ED93960F65EDBA1DC4CBBA11465B99A6AA72328021CA48415F509E76F3DF42D +29FDBF54 +81B7B4A560DA8A0E7A1865E2E3 +FBAD3BBCB6F93777B667359AA58239628EA9A29AAA38E90462DDCF2E3D2CBA1D5B1CD116C9CAED14717F0E2C4CE37126384C9CC571C2E2E90E39D657601A27 +E9804116 +C0356D31019D75B5339C3433A8 +52EB0B3EE7696889C59830C648CE51033B1A11DCBF77695133F3CFB252E44E5B84C03BB31D268E3A7F7B989A41573BA5D74A20A80E040623F8 +B27C9256 +648B6280563776221906080262 +C0D9BE2C0081DE170BA67BD08E6E47729DADEB3B3770F7 +FA0713F8 +6C2B95408D02E260808F038485 +EE701DFED5984C8F2E7CB896DEA448E16FEA8E5E9924CA93537C0C08624D8B +5D048C2B +11D4896EB3FC414DBE338A8928 +39466E317B3CFAD65BAA16AD3D5BCA55A6DBAA9F7E6203686F7F6CE5 +6861879A +3B06F633BE54713E3EAB47D4BF +85FFA62345E9D70266A11A63F5645E8BCA73B2DE7DD1B8FBF08986B7805CC6B57C45B3499ED1C59B1D21B384055E36220BEF137B5F140D574BDBFAFCB5B1982C338062C9C5577DA54384 +9D51D801 +F5422359CCB5389A29C4949E9D +7C1D19CF49811A6234807A4354DB629C6478C1ABFF7C0B7E221284C96182F22C9222C4EDAE112D91A93F78F771AFA22D5A3A7AEEED8E93573474A4B65F53C3 +3C6758D1 +8E86E9AE6AA4A6FAF17356D0AD +0FBAF2577D573C91E9C0D331A999B39EF5DF9DBAD6E5CA8F27C0BB8EE76C013596A7D67477F3F3762BEFDEBB8DF47700517D280FE93072014AC3AA020B553E63394C3153127CBEC1C9152719E8AC3ADF98B828AA0825C15FB45B +EB376AC3 +202C2C4C2F9BDF30C422CFB01F22 +A944EF21597D2F37E98AF8365EFE798EE7AA5FD1F07161EB130BCA0247161C7AC7940706A4BFF010858F4756485E89975DA60687AAE37885D76E3D5775311A1ED1A1BF32E45C6FE3941B88361E4501F3278670297C3596EF28E8123CE2A1F05936CE649A193BFB87C2786A3BD1A2BE +5888E959 +2E283327E3949BED13FD3262B7 +11994EE72E9FD292B11211CDFE8A3D47D0C606CE8FB0EA1ACE9A8C6BFD69825D6234FF44A5FB94B693291753BDD9143B4FC3FDDA8B38BF99F35B +185C961A +CF3584E201C8E6330D3CB7150B5C +009A6DEF7A1798DD421DAEA117D88EA2622020CFB3366C171BC48CB6CD5244FBEFF18DFF9876C002CE86CF00AE0FB46081EBB947AE3A5E411BCBE01D56A43A63DE0E7288466E68C98DF9F5CC6D55E361E8BA69266DAA2A75353380B30E5C4087E8992EF8 +34F7A925 +C1476C2B61755F37A140DBD4BD58 +CD7D2FE4F7BE9FB4845EA407FE0977E559F684ACDB4D48338A7A7A78D0CA555C50C96358CA8BDE523C56C5733F94AC0C6B5866555857787B3D121B766EABAD936E3501347BDE7FCD6CE43575E86540C6D9DD9B0EB0F2009F5C636672315E980D482674189A +9CD8C4DC +FEA03AAE88F8DC5F2677D5CC84 +335A776E1C5F70A0E66DCFB5800FDB0274C5D41144EE73EA73606C53FAE3F22F3AE1508F49E53FAFA089B2682F57F52BBB0AF51114F2 +67AB0EFF +90D2E8F0744BB8D1A8806C19B7E9 +E550F096A72E2D520B345B2460188F64C4F99B4EC8EC1D0735A2E22126471E710DD66BA8D88CFFF0035A109184C68AA65B99A2ECF8D3D634A14523164572B3E846C4DEE79EACF80EFAE7922143DD3B0CE0C8194FDD3C5ED98D16BF95D9889AD621B31FD91D5FE1DB37EE47BA4B55DC0E3A1306 +4F5ACB1B +BF434B752E02C7118332481BEAB5 +4023EDD9132B6A22E40C671C0A492DBC33F02DBEB93EB6F371939EBEFE813FA4ADC1E5D2E82146176CDFA7049AF5F9373FBBF90E6DE5E0D2C74287EB5163E213B9076260758819ACF46900E8EFF0ECB8AC1914D23BE2B7784E77A2C58B862754869BD079C118A9475DDE6D055222F53F596C628096E562D981927616E1B4 +6970 +6B +726887E9 +A5CFA0EDAE77BD707148574CCF +9343ADDABA5DC42D6FF64F0384642BA89424811D21AF3E100A7BB2CD298CCA48FD54D0FF5CC6138458975124E4755DC9FE6C951BF3FECCD49BF83B31FC5B04FB56265FA93CD5856DAAC3299C9D15D1978525738F3748EA8D5BF3763CAD9AF26C01 +B5D85850 +D9801C5293EF04369946A7C7BA +03C39E2BF1338B8F96B50FC0E9CEDE05A65D2B38A1CFF07D1243E4D1CD4683A724FB0C5CA02778BAB065F4DD627102BCF3E1DBD69E050CFF80181F0CE753A473574E896B8A4EA87C44220271B1D767AAF38CB3E167FBFF28902215F7DC4B79D26563FE +C9458203 +DDF7864662E0FA7A9F4D70145D46 +7EDCC008E40681B82584FDEB18ADD74631019AB3ED519F8E124B7CE82C236ABEE86C12942B0D62B1A9F58B0CA6B4BDEC39492674FA67D947968768CF120C0A1DDA0D4B27137BE09F771C3A88DAFDEF22B915B760C197D00F16D5A88447379329D5C97BEC3808588F8CA285CB39BDD665722D7D3C685B60772C0A +D2A6F765 +B03934EC9C9F8106E80D7673C78E +33FB53B8A0DC2D2AC19565507F822B2FEA2840FBB6F164836C99411E5316BCE90DC7A83FAB5339E03ED2EC2C248E41556E1E280BF2DAA1318D73A4FAC6A6A76FC63956E11713AA7441CDAC2194EDA75D5AA852F3003BE0876C99DF7592D56D29522D9B27A434734E1BD3513FEA6628A5FF336562AA2FC77627F6904F5FBE +98EE +E11A277A39FF1A649249FF +F503E7E4 +9810B3DBEFBF5228B46B2C0288 +64FE51368196762805F7BFDDBBDB7F28B603DB63C6F71119EDEDAC87B09CF30D1B6B8C2CCE1F463CC865BC934EB3DABBDBD2270B08359E8AE98C4C +E5338C3B +CF6F3755E8FCCFF9EABF24002360 +5ED2F848479B20954D8BF678CED1B72009CE58BC43B69A837DA686EBF60A0ED59278D6049200C9621BD6AC4280C87AAC345120854B364052100FAC4DDA6C1DFFBB8BA13A4D65B39C717DF8A8A6A20194E8F99E939334C0065E2CA380EC0337B09FD84BEF3F7D7350E360B8FFC83D40EE9026FF18D05B31413A1DB26E5CA9 +05E4 +A63C4F22E5AA6C056990EA53EA17C3760F09F9B2F6A2331394903B75AF10E5 +E9CD4B0A +4F7D2B7F93071E5E4E8030B571D1 +DE58FC6F85C7381BBFF5C16FB8E905558832C67F41EFF91F2BAA70EB1A260339A128400EB5E4695FB72FF6D35514309A4EEDD868F70EC47525BCDB58CDB50548B04F114384B997DE739690C676A1C6B7CC353FAEFDC655B449173F336FE44CF9F6878D5398769F28149A0D7A01AA82 +3B1E4373 +62882A87851D3FD398A20DD499 +5A622BAF6A17F465A172F011004B308ECB6D050A24812186A0B48BE51942B3198E148DD0CB2A1000F972D426A2DD5F8B7D976DF0AA29D054E6EB0E886FAB365FFBECBA357D0677849588611CF82EAB4CBC9C9A9B7E8504DDA343C841 +781B9DDD +80DDD32AF76AE31EA692B9C46D +B5891C5BF988A1D9E9F54C26D18F0C17CB66E27DC60A8158BAC25E6A3188F6942D98C2E93B08E57127E8C728D743AB9402A7EAA1B223678ED65CA7E8D170170226BF711B298E585DD3A86CFEA60E52CC15605D +584944CE +91F616F508F21C5BA3FE5442EBD1 +557B0BBD4EDAB8FD6502F113091C39CB1A739A32991154AB215AD4B147E9C7AD0D1E59FEA4E24181CBC533D7B2B4BAF5CC7591AD55268908CB04F16F3582BE6B34E39443F22FB525EE0E7380CE3DC1F4C2664293E4F535CA8BB80AEA20670F7AD18C0866400C336D275E +00E6C901 +51EC0FFB13B3724DC6E80EEEAC5B +338AB828D8CDEA55BFFDC08874A3F9DF2AD19F599E238BC9553E67803AC576FE2D17205BA3D5AE930EF7898F41EC4C7D7C382E6D9FF37CEA3F92E49E05D7FD2F531C1339CA0E9FAF8841EE24551E53EA1108BA9DC7898C55825375C8A054BC4361AEF03CA5299A768E64B369252F4DE908727ED0293ACCB34DEA3C3D47F5 +651A +6117E2 +BBBF2DC2 +9F981AD607237983841BF75188 +06C6D29505EE27B191ECADE6A26F8254E6C755CD6C17F406C00FCBDA9EC4C7713BE56861DFB46E77C2CABDBDACC0C358832AD4FBE35A425D7C490215DA1E87A85B6431AA71FE762173E748C29E7121D0B2 +41ECF0F6 +9972EF9CC0C9F818CEE97CF2B7AD +52EE40313115EEA5A529CDE737BE4699D262C1F9BE07C2537A1FF2CDA84C53791F14B90160D11D30CAB3FF276672372D8E195C0ACC8121DCE5D68B012868020276F88B4BF12B0D4DFF583282E9BBA74DE176CF78748D8FBCE4134C33CA4E44B35DBE75B2 +C91089D7 +B8F6F1C6A817E44E41C6D6D521E9 +D0A70DB93F73BF560157D2D3EAFAF450EBCB990BF663D5E195BEDA0F71C2F5DBEBBE038650D75CCB62CA6569F6E37EC6F3BE08FD59E4245EB03809DC7244AC9820CF8F83849A242B57150891951EFC4F8F1BEEE5C55E6CD916C4F439CEBFAA8AB8125693350FBBAB2F5A95C3979C81F1FB41FE819D16FFFF553291AB869C +98AA +CAC049B9F4794617E39334E72454F6BE +EEE9A04B +FAB99233EF7097C85E9B90EF6C92 +7B65657FB9C159410C45DBC4F84E806D1F75190E58DFF35E456CCD744C4AD5C13D56AA476E19F8C2987F51E64755EB143514BD594B8198CA552DD32471B7D28F2CFF7604768D2EA09B8E3C0FD96E244380D449C005AC860BA1D0BED90CA401325C29259310A1CA633BC3BC4D95162849D9B55D01A446D145E573D61CA3FD +5A38 +79C798037EF1E6FA873E45E37A84277ED45224DE9778358AC5D4EE0893E4D847AF11C2169C285C +E5A3F241 +7F0CC62385BA40CD1EC77CFA2FC6 +D465F9F7044CB643DFDACC6A11F4878F10C7CC4C726B2EA92D5BCFC06D0361AF92C23234F5C83D5814CAA3C268881FF8297B499368B1B95C76EB12C555A2F0B9E0109BB40A5D7A2BF5BBA9750CC2F525541BA4F8B121C3BEF28D07C2BCCB46F0630938180A249E69877AD6ECFA4AE87A617852 +CE8FF460 +3968E62D8C2FC9AEB7FA618171 +6DAEF1BF5ABA3F17AAE8CD800C1FF37A1E83F6F9B4A7B979BBD3F36F5F54690CE36D261F3DFCC8160963 +94FA224C +64FD903F32E9741C2090DC1D98 +7F2D63012A20EB3C57993DB422729059892DBA81F7A4EEB6E2C59AE3734DE8B5C3D77CAB7CD464DF3F2D69EC +A194009C +DB7666092F8B781EDB3141B1ED +A0E6FFD166373217FB5AD4E6E23C7712D78E2886E4DF2ED7A43DE12314B790747F9EE699E9AFB4175664AFA073A4FD67E9B7B54DCC31E2711478 +C1CEF56D +73A2A13BCA995F1021D9A97AAAE9 +56C340D405A59633F4387A7A16F48D562660A76CA92CB357077C8860FF77CFFBE980104FE5E1CF729F02AE6EDE8E955C5535FA234DEEE16DC6C72340D1E5DC3F7F3722947D274B121E9C8F69D4F96D49A3B8CFA1AC704034BF20DF073B74787B335D42AC7DA97025F12F540F6724FCD75DE0FBDFBA0AC1FD51D2856935DB +900D +AC9900 +AF4CE2BE +876660AEE0CF08B9410670E527 +BC95332D9302518567D85B9890E0A8F80BE435D10646698BB8DC95C0EFEDA8105600585FA623285E9DA053BC141350CF9C0B277E974848F74660426F110D259746024037ACC9307718668E9D7BF249BB9421AC1F99B36806 +925091E2 +2065DE89EC10FAF9E2D7BC788E +ABD2A745375D39D74694D693FC47D38E6661A7A0364C9EC629A7FB2DC084494FE6445DABB812AB18FE7E5E967AFF633F837D588E5A765D08B9D613715542E38832E599FA93F7F03D08AB249815CC69E39960 +7FB1C74C +7F11047043093BB77C5C76B26B23 +63262545CAEB804F58F9CB2901453B3A9869B24D6957848BCB56A1AC730D7F17B0CC0CB782EB67E1DD76A5FDBFE1674F30793B349EFF23DDA0771B9A5AC8366A3BE0A9D88FB8E64C47A8493CDE8CB1C4A6F7349EE46883507057AFCB89D634600B60D33C63049593608A2C7CF91E +47E982E2 +9C4D51E0B5CC34566566C4A23F +3F497403DE753C3EC8B3831C4EAC3F886246C785D25CA028955879B18371F919E4FE74B85030E1483F607089A3D69F43FE6A5CF0576CA4E5A53492F6A97A247670493C09A2A002336A8A69BA61EA3A0803E74662D8BCB79373 +86F0DC59 +8543B314FA64A02C5E147D08F2 +5BBF3EDDAC1A101D781724190D155967B0498B678D3A9673E89B6514EBF12598C4E58DD441CA6C92FBE6A70F4E65D8F2104E1E692C85890904042D2180D3170AEDE0976CB51AFC1AF521F8F93BA70E87A926A623F7E2B74D5981415F +FCA93D01 +094DEDF13DB9E3D4B4D9A8EF33DE +988FD370E13A7237F88D87707061FEDF019AA4EA1063A460907324F7F5668ECE2BFBE0CB038B73CB230BBDBFB6E4CD7364D9AE20C62C54B724E0BB5C72356AD985B0CF4B4E116F0712FAD1498B94EDE92BF50535FC733F1B0261F056BD827A45B1E5C1038C32C453BBACFC43FF77B50AD0A0A70DF41B9D036EEFD0601BD9 +4223 +9A59BF3AB889268EE3763C4B952D37486DEA2A0A490FE8F9FE7E958573BA9CB9B848891D975FF38F029FFD80DFAF50 +C1AE83C8 +A15C2BA996A9DA4E06E007FFC5DB +8427CF5628612FD59DEDFF8C7F7ED0901BAFF98B626DB68F3BB00B6B9083CE53DB9DEFE8B15F1A762E0841372F8B56420FB07B4CE3FAE5D772D1ADD91B4EFDE7B13754FA4A43B104CFB15C2FD49F323EC279948FF13258C21429387FD1BC38E900DE6F929C8593B2CDDAAD699E +5855AF4A +35525F0B38EB550EDD65A8FC80 +69D4D1F60B0919BB2DC20E0309726F9FF9500A42CBF812D004D1C952875D336A86A7A6F5132BB932555F24F45F93EED4DDB4BD754161FAEE7BED6FA924F717C30E1858FC05962B6406489BAF843220A1 +9F5BFB9A +39D3E078F996B1012B6F42B859 +B9EB3AC67D816B9FAEE23CC3C51CF375EFFB14E1F7A7E7B3E9E896C95A31B14170A76625E3E945EA7E3C9FC478C83644F97FD062F64F8E31791BA6857D2ED4F0061C9D72436F085FCCCE82901FBA8BB84EC11773D7A3D7320BA369FB48511744359DAE +BC7E7CDB +36866283588DF430D7E850338773 +13FF557283CB22A5E05C92F4A51B43D163B50645C41D06D557A34D15B6ECE48B574239711FA605C8AAB699176C3F754D76B29E85B21D16CEA74A96617A72E96C6C6B7B40ECF220446495E96C68E6ACE570D02017D802E48446878DCEA892A7C090DA66A5A36D2814842C3BDADD9C833FF6A0121316EE197864A651EFB233 +B04D +96B4AC212098DF2CEA152AE5A2AA78B5D4C01F65D2E43654F0F7CF40E451E42AD2BAFF +4F6CC450 +39C11CC4456097611525C9DA4B +0B2A389C8C7D5305FECDB17FF2F7C3D04370915BC40B66E61C236A299C65C14A4BC329645DDF578F9C4058D4762206EE1286711F8528 +CCC4AF06 +D7BB683088FC76650CBB2AC7033A +D78319D017E36523096FB92DDC66F849E1105409327276D08BC6F44C6BE27BA5AB5BB8C38F532D7EBBC034FFFC6CE8C2CFF8B8F186B35C8E38AAAF4B023C004F260A10D95CCD5A08F838CB631CD61317096EA7EFA7F54A3F6BA9D66DDDD079F541CA9565ECEDC189A651BCCD9F9212302C60FD4FD731B3CBA3A8AC4B6919 +9DFD +BB09BC6D593F47F606A8ABCD476736F7AB6DA3C1D4461539D152BE3E32FBD1 +11752560 +2E36DC7BB9D40B2404EAEF60BA44 +3FE0DFE368FC6F2EEE5293EA3EB11D6E0460A31B1B3F742C28A9AD3294DC9186CE3EE682697A1CED8471EBED33BCB4EF5A1DE7E6128D0CDB554D3A006FA85366C9D48C1EBA3E8919DFF7341681860B5A8F66BEF0D5E17F67C81B7501AB4BC71CA0B1B2CA7624BBB45BF7E5D6 +604ACA47 +72E5A3B4F1A9123B2DE33707E0 +68070B1F5B211BE59BA1EE59978390C9CF039ED585327D5C70F7208ABDBDCA36B548F41AC17C728AAA8D6A107D3B721144E2B97C0E2E2E29BC74FB2CD9952F2FB5053F180D6A +CE31322D +1EAC50CED4C19988C9D12E70DC54 +A2A26B1DE67FC581D40D2449B762A146717917B21E52DB7FCA62EBD25191E096C5A9CB260AE8DB603E42856C6BBDF89AF67A5ACA1AC86BAEC88C3D7750F20692FC629BA942E20203E4B1657DF601B978D3AE9A88398B0D5D6553B3148D31195B1F5D6E7BA7122310C65D08B88E03307011E49508C8A91B +15F8CE31 +2FD4CE94B5AFEE66571D5024C51C +A1FDABFFC73FBE06AE9C00C7048835CDAFA0AF74636CDB89FB65AFA600E94DA0A88B9B5B86DD1936593A9BEE486B6ED2FF5D26D231FBA397A3C9058DF68E12B38364E5EADC90FF250AEDCB4095C5441D45DC2E76FB3EAB6F844EBE718F300CF78ECF7F0FDB61D13BA8ED +64E2CE85 +E37716DCFE66B8466320D581E9 +F3F68DC65E0D1A73479AD25E5446C1CE0B0B6906327503E7E2C2D559274FAF8900B02AD745F42CACECA406EB7D97C1016227E1E5833467F281899F0239E2722B4AFCC117716C63B0BECB28A73AF79EE49575E79764C77B +A905CABF +94CC5B697C39A76937EB31440CA2 +2DBF82503228696D06E1CED0C932BFF722208B9389276FCFE37EEC47F6A1C8481D17F1BB095E6B5B4642259FF2AD3BF8AB8151F41E5D97EF729911D4894CBF1175E9AEBF848B47FC338DF1347E2A829E09B129DC3CC07F6593505CD2E5B4861769628B0A3E5AFEB0D20C7B4EC6189C59888EDAB20FADC94E5F9F7897 +9D2132C6 +E666621386A75F2D61E46CC1E5 +7DD4B2A8293CDAAEB074552E7E07D39FDF505D84B89B834899E54A3052EF6ABEC82D782D3D4FE3C5D88AFAA1B366740DE4B6672E17DCB1A3EB4A99FDE01887B4F6FEE8F2BD +06754600 +BEC7F7E8FF4DA4BD610EB176E7 +3C609F8D9D6A48036992D1A2C03F137098F63C775493551B195F56ACBD06027C754A23F7AB9DFF96DBE7B79C36ABF6A269B68A41C2D6BA2E1841AAC7AB52A153A5B0E1E3FE014C09FBD037D5133CD129A51E6B4C6FB3D84A3CFB0A54F18A13D5C5B9 +1810D233 +4F0AA8064A0EBCB9CA0882E920 +EB1C184DDE5CC71DF42EC5D15D0382B9591F410198D44437F38543890575DA02FA57B8DC35783CF2D5309C5947D8898CB699B1A5D0606410C6637766AE9302C925BABF1E382B5D6B32274F5638BE9386DEF7F9038EBCB49315 +467D9A8C +CAF4E5B41D4C2B6514D891C6F3D2 +1FBBAAD07627DDC3F14237BB407D2859CD5C8050AE95A3E5BDE042B1FE4FE65F8C2EA13CEB8D637491C7DA65CC09863D9A05A8089FEFA5E7236F113D890298AC82C7F9BC106D7FE7C634F3ABF1C0D4230733533C6FD4D416A51E354B4B1F5B00C576A9BF5183A81D1948FF948899F7F87DAEFB937FFA55036046078CD553 +8A71 +B9D6A5EB2028DC1B7485A60764EF +A80902E3 +8770FE119B5192ED357A58F79507 +103371193740C65611E612A4DA3B5C2FE099C453E74C620542521FDFB91197B72DE42412ECB4EEFD23F615393D987E27ABC52B02C09F07AAFC75B38F10668892BA1A8A352DF6E098883E6A102DFB574F96D2408B6076BA628EC44F0ABAD2244D438CA7AF8C8A7A91D6510C68114F847DE64755571BC64379AA76F5F09F34 +099B +5B64541B67C46C1C4AC832015833A59724EFBC08285F443E9D +BE768332 +797F41344E9C04CBDC307256D189 +48A1809D53BC96AEBE5BDB265DCC1516FE3F799CB62F815ADADAD07BB3C5E2E93AAB7F83399829E09428F16D3B584383E427C7ED66D142A59B9E15BDB0E043FA0F20CB1B7B9D4242472DA4B6A9AF56DEEFD1FD9604DEE0E7705BD9F3E6678580C2ABBB544329D730A375C130A23E3DF603FA8289E4F275A6A705C6D7094D +3843 +2FD5EE18 +56D59B448D32F974B5350F8194 +910480F06E4FFCFA5A3EAAA96E371AE29657AD0BA992740B0FA3604F19FA80D6FC5420F4FF66B7C16EAF5301C65CC4DC6FA18AD8B60E05053242BA674E475F +741D9A80 +95ECCC1880AE59BAF60014433A +1D8E062DAE9AE11781E657E182E6C8ACD612EC1FFF4620 +D2C8DB76 +340F2F5AEED5D7CA16B6B5FA34 +108CE615A053C252F54A36E40C455E9E924CDB5283FA +D3869002 +AF4AB03B5BF338CA186FE7C32A29 +313EAAB8C9D787C7 +CE6F3CA7 +3615E4BDD0A24BFD6228570303F4A352DDD2E93EB0C82F59225E7D4A61ACAE1CCEFA +024038216BD6216B55C577FF830253810D869A188658DBA9EF87B6CFBA0BBCACD165E39107E5 +AD24431795E02389131C89FF7A0F7E2A4C0D2D45C166371D521FE1 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +%Defining font PSOsymclas +%!FontType1-1.0: PSOsymclas +10 dict begin +/FontName /PSOsymclas def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001000 0 0 0.001000 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 1 /C0069 put +readonly def +/FontBBox [106 45 775 713] readonly def +currentdict end +currentfile eexec +D9D66F633B846A989B9974B0179FC6CC445BC7C8A959A39A32E9DCE7FAEF17EE3BEC9F +50E1A6FCA651FC4B3769A0A91041557502E25A5D6180FE25A3D11BF079E1DF66E54EE9B7C229AF891739707A2A0EC140306B5E43E52B79BFB89E459E50 +6EC6F610A70775A31C460976C4F79449D86E57ACE491E5C6BF20CC4307B1DAF7630252 +E9AF8CFB69B50EDAE9D36A6104AFEF8832F920FD2346B2C7104CD11E3BEE999CFA9F5A +49DB3173EE48D1C82994237F360407B022E0B4 +502E94EA8B493651EF2D03F0B513D655047568325B512AE6 +6AC6F53F3848CF70DE25481CC65D8B1A5793AA +3C4282D111112BEE28AFCA7A3808D4444C4669CA +84EAAAF989219F51AB3476A1B0B5F2246BC306E6 +625C6679C417ED2A8E9BD010DE37D40265074C2684268F16195489648993B9C4D3B534FA887C +DEF605FA87B991F4D20A8F78DACE +5A54C070E03D5C59D9D2D3E06B09CEE028D68B62AB3AEC43C1DD20BA70D288597D9BD8E06818FF764EBAB436723988E8D7CA59E16D39032516BFC5D552ACDEEC6BE938BEF2F43CFFBC811C3626C4DF5F8CF080676520B51C60CEDAD1FE6C92D1431C702174CE517A8FA9377D075A0B6833DAB101DB65397F1419EF5F0016 +004F +6F0824F9657BB4F1C8F981709956865F6855EFAE +9242AD55 +91BBBEE163D844DDA894E13190C9 +2480439E4C71CADA +BD043A9B +A315CAF72652AA7FE6DB2E84D82A6111CE4DE90C02DA0AFFE2620922262A45AB4ED0 +EEC9F4520DD12703442F7D028D4526BD8B771E09FBE11B2749E2D3906894E8D4BFD3F379F14C +3C874F550606965E22FE487B247B5C2D06728490C8F2A3B588CDFC +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +/DPIx 1270 def /DPIy 1270 def +72 DPIx div 72 DPIy div neg scale +0 -13970 translate +1.00 1.00 scale +/wst:dutch12 12.00 /PSOwstdutch newFont def +/wst:dutch10 10.00 /PSOwstdutch newFont def +/wst:dutch14 14.00 /PSOwstdutch newFont def +%%IncludeResource: font Helvetica +/wst:helvps10 10.00 /Helvetica /wst:helvps ILEncoding 0 declareNFont def +/sym:clas10 10.00 /PSOsymclas newFont def +/wst:dutch9.5 9.50 /PSOwstdutch newFont def +%%EndPageSetup +GS +0 13978 10801 13978 10801 0 0 0 clp +wst:dutch14 SF +0.00 0.00 0.00 1.00 setcmykcolor +<1b2b3a362b382c11011201132b34292e33273831012c3538011a2b27393b382f342d011b2b3a3d353831011d> 2207 558 0 7384 -1 s +<2b382c3538332734292b> 7375 558 0 8593 -1 s +wst:dutch10 SF +<0c0c> 9346 13300 0 9522 -1 s +wst:helvps10 SF +<4e6574706572663a> 1322 13280 0 1949 -1 s +<205265766973696f6e20322e313b20436f7079726967687420> 1949 13280 4 3868 32 s +sym:clas10 SF +<01> 3868 13280 0 4019 -1 s +wst:helvps10 SF +<2031393933b131393935204865776c657474b15061636b61726420436f6d70616e79> 4019 13280 3 7133 32 s +wst:dutch12 SF +<072c> 1589 1431 0 1836 -1 s +<161a192d3331> 2033 1431 0 2950 -1 s +<1f2e2f39> 3177 1431 0 3571 -1 s +<0035363a2f35340029273400282b003b392b2a003a3500292e27342d2b003a2e2b003b342f3a3900352c00332b27393b382b002c3538> 3571 1431 11 8248 0 s +<00393a382b2733> 8248 1431 1 8895 0 s +<3a2b393a3908> 3177 1676 0 3635 -1 s +<001f2e2b0026261602060026261a02060027342a> 3635 1676 4 5389 0 s +<00262619020027382d3b332b343a39003d2f323200392b3a003a2e2b00353b3a363b3a003b342f3a39> 5389 1676 7 8895 0 s +<3a35000c> 3177 1921 1 3509 0 s +wst:dutch9.5 SF +<0d> 3509 1853 0 3593 -1 s +<0a> 3593 1853 0 3677 -1 s +wst:dutch12 SF +<06000c> 3677 1921 1 3877 0 s +wst:dutch9.5 SF +<0c> 3877 1853 0 3961 -1 s +<0a> 3961 1853 0 4045 -1 s +wst:dutch12 SF +<060027342a000c> 4045 1921 2 4623 0 s +wst:dutch9.5 SF +<0b> 4623 1853 0 4707 -1 s +<0a> 4707 1853 0 4791 -1 s +wst:dutch12 SF +<00283f3a2b39093900382b39362b293a2f3c2b323f08001f2e2b0026262d0206002626330206> 4791 1921 5 7866 0 s +<0027342a0026263102002738> 7866 1921 3 8825 0 s +<42> 8825 1921 0 8895 -1 s +<2d3b332b343a39> 3177 2166 0 3941 -1 s +<003d2f323200392b3a003a2e2b00353b3a363b3a003b342f3a39003a35000b0a> 3941 2166 7 6488 0 s +wst:dutch9.5 SF +<10> 6488 2098 0 6572 -1 s +wst:dutch12 SF +<06000b0a> 6572 2166 1 6872 0 s +wst:dutch9.5 SF +<0f> 6872 2098 0 6956 -1 s +wst:dutch12 SF +<060027342a000b0a> 6956 2166 2 7629 0 s +wst:dutch9.5 SF +<0d> 7629 2098 0 7713 -1 s +wst:dutch12 SF +<00282f3a39093900382b39362b29> 7713 2166 2 8825 0 s +<42> 8825 2166 0 8895 -1 s +<3a2f3c2b323f08> 3177 2411 0 3711 -1 s +<0024152b2c273b323a1100330007000b0a> 3711 2411 4 5307 0 s +wst:dutch9.5 SF +<0f> 5307 2343 0 5391 -1 s +wst:dutch12 SF +<00282f3a3909390525> 5391 2411 1 6054 0 s +<072e> 1589 2757 0 1882 -1 s +<1f2e2f390035363a2f35340029273b392b3900342b3a362b382c003a35002a2f393632273f002f3a39003b39272d2b00393a382f342d0027342a002b3e2f3a08> 3177 2757 10 8691 0 s +<0717> 1589 3104 0 1940 -1 s +<382b33353a2b2e35393a> 2033 3104 0 3065 -1 s +<1f2e2f39> 3177 3104 0 3571 -1 s +<0035363a2f3534> 3571 3104 1 4214 0 s +<00392b3a39003a2e2b003427332b00352c003a2e2b00382b33353a2b00393f393a2b330800183a0029273400282b0039362b292f> 4214 3104 11 8825 0 s +<42> 8825 3104 0 8895 -1 s +<2c2f2b2a> 3177 3349 0 3526 -1 s +<002739002b2f3a2e2b380027002e35393a3427332b00042b082d08002c353508282738082827400500353800273400181d00272a2a382b393900042b082d08> 3526 3349 11 8895 0 s +<0b080c080d080e0508> 3177 3594 0 3894 -1 s +<0024152b2c273b323a110032352927322e35393a25> 3894 3594 2 5702 0 s +<0732> 1589 3940 0 1824 -1 s +<3a2b393a322b34> 2033 3940 0 2636 -1 s +<21> 3177 3940 0 3386 -1 s +<2f3a2e> 3378 3940 0 3621 -1 s +<003a2e2f390035363a2f3534003f353b00292734002935343a383532003a2e2b00322b342d3a2e00352c003a2e2b003a2b393a0800182c003f353b0039362b29> 3621 3940 13 8825 0 s +<42> 8825 3940 0 8895 -1 s +<2f2c3f> 3177 4185 0 3400 -1 s +<0027003635392f3a2f3c2b003c27323b2b002c3538003a2b393a322b3406003a2e2b003a2b393a003d2f323200383b34002c353800003a2e273a003327343f00392b> 3400 4185 14 8825 0 s +<42> 8825 4185 0 8895 -1 s +<2935342a3908> 3177 4430 0 3752 -1 s +<00182c003f353b0039362b292f2c3f002700342b2d273a2f3c2b003c27323b2b06003a2e2b003a2b393a003d2f323200383b34002c3538003a2e273a> 3752 4430 12 8895 0 s +<3327343f> 3177 4675 0 3667 -1 s +<003a3827343927293a2f353439002c3538002700382b373b2b393a09382b39363534392b003a2b393a06003538> 3667 4675 6 7468 0 s +<003a2e273a003327343f00283f3a2b39> 7468 4675 3 8895 0 s +<2c3538> 3177 4920 0 3444 -1 s +<002700393a382b2733003a2b393a08001e35332b003a2b393a3900292734003534323f> 3444 4920 7 6541 0 s +<00282b003a2f332b2a080024152b2c273b323a11000b0a00392b> 6541 4920 5 8825 0 s +<42> 8825 4920 0 8895 -1 s +<2935342a3925> 3177 5165 0 3768 -1 s +<0734> 1589 5511 0 1882 -1 s +<3c27323b2b> 2033 5511 0 2513 -1 s +<1f2e2b> 3177 5511 0 3537 -1 s +<003c27323b2b00362739392b2a072f34003d2f323200282b003b392b2a002739003a2e2b00343b33282b3800352c00141d200339002f34003a2e2b> 3537 5511 12 8895 0 s +<393f393a2b33> 3177 5756 0 3782 -1 s +<002c3538003a2e2b00363b383635392b3900352c00141d20003b3a2f322f40273a2f353408001f2e2f39002f3900382b373b2f382b2a002c3538> 3782 5756 10 8895 0 s +<1a1d> 3177 6001 0 3506 -1 s +<00393f393a2b3339003d2e2b382b00342b3a362b382c0029273434353a002a2b3a2b38332f342b003a2e2b00343b33282b3800352c0036383529> 3506 6001 9 8825 0 s +<42> 8825 6001 0 8895 -1 s +<2b3939353839> 3177 6246 0 3722 -1 s +<003638352d38273333273a2f292732323f0800183a002f390034353a00342b2b2a2b2a00353400171d072022000b0a082208> 3722 6246 8 8444 0 s +<0024152b> 8444 6246 1 8825 0 s +<42> 8825 6246 0 8895 -1 s +<2c273b323a11> 3177 6491 0 3653 -1 s +<000b00363835292b3939353825> 3653 6491 2 4804 0 s +<0735> 1589 6837 0 1882 -1 s +<392f402b39362b29> 2033 6837 0 2764 -1 s +<1f2e2b> 3177 6837 0 3537 -1 s +<003c27323b2b00362739392b2a003d2f3a2e003a2e2f390035363a2f3534003d2f323200282b003b392b2a00273900273400352c2c392b3a002c383533> 3537 6837 12 8895 0 s +<3a2e2b> 3177 7082 0 3467 -1 s +<0027322f2d34332b343a0039362b292f2c2f2b2a003d2f3a2e003a2e2b0007270035363a2f3534080021> 3467 7082 7 7288 0 s +<2f3a2e003a2e2f390035363a2f3534003f353b> 7280 7082 3 8895 0 s +<29353b322a06> 3177 7327 0 3729 -1 s +<002c3538002b3e273336322b06003627393900283b2c2c2b3839003a35003a2e2b00393f393a2b33003a2e273a00282b2d2734000d00283f3a2b39> 3729 7327 11 8895 0 s +<272c3a2b38> 3177 7572 0 3607 -1 s +<003a2e2b00282b2d2f34342f342d00352c0027000e19130036272d2b00040727000e0a100f000735000d050024152b2c273b323a11000a00283f> 3607 7572 13 8825 0 s +<42> 8825 7572 0 8895 -1 s +<3a2b3925> 3177 7817 0 3501 -1 s +<071c> 1589 8163 0 1938 -1 s +<392f402b39362b29> 2033 8163 0 2764 -1 s +<1f2e2f39> 3177 8163 0 3571 -1 s +<0035363a2f353400282b2e273c2b3900303b393a00322f312b003a2e2b0007350035363a2f353400283b3a003534003a2e2b00382b33353a2b00393f39> 3571 8163 12 8825 0 s +<42> 8825 8163 0 8895 -1 s +<3a2b3308> 3177 8408 0 3578 -1 s +<00183a003d35383139002f3400293534303b34293a2f3534003d2f3a2e003a2e2b0007120035363a2f3534080024152b2c273b323a11000a00283f> 3578 8408 11 8825 0 s +<42> 8825 8408 0 8895 -1 s +<3a2b3925> 3177 8653 0 3501 -1 s +<0736> 1589 9000 0 1882 -1 s +<3635383a343b33> 2033 9000 0 2821 -1 s +<23> 3177 9000 0 3339 -1 s +<353b> 3313 9000 0 3545 -1 s +<00392e353b322a003b392b003a2e2f390035363a2f3534003d2e2b34003a2e2b00342b3a392b383c2b38003638352d382733003d2f323200282b> 3545 9000 10 8895 0 s +<3d272f3a2f342d> 3177 9245 0 3829 -1 s +<00273a0027003635383a00353a2e2b38003a2e2734003a2e2b002a2b2c273b323a08001f2e2f3900332f2d2e3a00282b> 3829 9245 10 7957 0 s +<003a2e2b002927392b002f2c> 7957 9245 3 8895 0 s +<3f353b> 3177 9489 0 3504 -1 s +<00383b3400342b3a392b383c2b38002739002700393a27342a273235342b00363835292b39390038273a2e2b38003a2e2734002700292e2f322a> 3504 9489 10 8656 0 s +<00352c> 8656 9489 1 8895 0 s +<2f342b3a2a08> 3177 9734 0 3694 -1 s +<071d> 1589 10081 0 1894 -1 s +<0a410b> 2033 10081 0 2351 -1 s +<182c003f353b002a350034353a003d27343a003a2e2b003a2b393a00282734342b38003a35> 3177 10081 8 6480 0 s +<00282b002a2f393632273f2b2a06003a2e2b34003b392b003a2e2f39> 6480 10081 5 8895 0 s +<35363a2f3534> 3177 10326 0 3768 -1 s +<003d2f3a2e0027340027382d3b332b343a00352c000a0800123400392f3a3b273a2f3534003d2e2b382b003a2e2f3900332f2d2e3a00282b> 3768 10326 11 8895 0 s +<3b392b2c3b32> 3177 10571 0 3723 -1 s +<003d353b322a00282b003d2e2b382b003f353b00382b362b273a003a2e2b003927332b003a2b393a002935342c2f2d3b38273a2f3534> 3723 10571 9 8514 0 s +<00392b3c> 8514 10571 1 8825 0 s +<42> 8825 10571 0 8895 -1 s +<2b382732> 3177 10816 0 3526 -1 s +<003a2f332b390027342a002a350034353a003d27343a003a2e2b00282734342b38390029323b3a3a2b382f342d003a2e2f342d39003b3608> 3526 10816 10 8439 0 s +<0024152b> 8439 10816 1 8825 0 s +<42> 8825 10816 0 8895 -1 s +<2c273b323a11> 3177 11060 0 3653 -1 s +<000b0007002a2f393632273f003a2b393a00282734342b383925> 3653 11060 5 5940 0 s +GR +eop +%%PageTrailer +%%PageResources: font Helvetica +%%PageProcessColors: Black +%%PageCustomColors: +%%Page: (23) 23 +%%PageResources: (atend) +%%PageProcessColors: (atend) +%%PageCustomColors: (atend) +%%BeginPageSetup +bop +%Defining font PSOwstdutch +%!FontType1-1.0: PSOwstdutch +10 dict begin +/FontName /PSOwstdutch def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001000 0 0 0.001000 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 1 /C0032 put +dup 2 /C0040 put +dup 3 /C0041 put +dup 4 /C0044 put +dup 5 /C0045 put +dup 6 /C0046 put +dup 7 /C0048 put +dup 8 /C0050 put +dup 9 /C0051 put +dup 10 /C0057 put +dup 11 /C0058 put +dup 12 /C0065 put +dup 13 /C0066 put +dup 14 /C0067 put +dup 15 /C0068 put +dup 16 /C0069 put +dup 17 /C0070 put +dup 18 /C0071 put +dup 19 /C0072 put +dup 20 /C0073 put +dup 21 /C0076 put +dup 22 /C0077 put +dup 23 /C0078 put +dup 24 /C0079 put +dup 25 /C0080 put +dup 26 /C0082 put +dup 27 /C0083 put +dup 28 /C0084 put +dup 29 /C0085 put +dup 30 /C0086 put +dup 31 /C0088 put +dup 32 /C0089 put +dup 33 /C0091 put +dup 34 /C0093 put +dup 35 /C0095 put +dup 36 /C0097 put +dup 37 /C0098 put +dup 38 /C0099 put +dup 39 /C0100 put +dup 40 /C0101 put +dup 41 /C0102 put +dup 42 /C0103 put +dup 43 /C0104 put +dup 44 /C0105 put +dup 45 /C0106 put +dup 46 /C0107 put +dup 47 /C0108 put +dup 48 /C0109 put +dup 49 /C0110 put +dup 50 /C0111 put +dup 51 /C0112 put +dup 52 /C0113 put +dup 53 /C0114 put +dup 54 /C0115 put +dup 55 /C0116 put +dup 56 /C0117 put +dup 57 /C0118 put +dup 58 /C0119 put +dup 59 /C0121 put +dup 60 /C0122 put +dup 61 /C0262 put +readonly def +/FontBBox [-50 -256 920 739] readonly def +currentdict end +currentfile eexec +D9D66F633B846A989B9974B0179FC6CC445BC7C8A959A39A32E9DCE7FAEF17EE3BEC9F +50E1A6FCA651FC4B3769A0A91041557502E25A5D6180FE25A3D11BF079E1DF66E54EE9B7C229AF891739707A2A0EC140306B5E43E52B79BFB89E459E50 +6EC6F610A70775A31C460976C4F79449D86E57ACE491E5C6BF20CC4307B1DAF7630252 +E9AF8CFB69B50EDAE9D36A6104AFEF8832F920FD2346B2C7104CD11E3BEE999CFA9F5A +49DB3173EE48D1C82994237F360407B022E0B4 +502E94EA8B493651EF2D03F0B513D655047568325B512AE6 +6AC6F53F3848CF70DE25481CC65D8B1A5793AA +3C4282D111112BEE28AFCA7A3808D4444C4669CA +84EAAAF989219F51AB3476A1B0B5F2246BC306E6 +625C6679C417ED2A8E9BD010DE37D40265074C26842247DA7FC91B9FEBA82925C7B7A9B0D22DD1 +7C0E9A7093608F1410546F00 +09F98531B5959B588C +79CC3103 +04952A259CB45E63AE73CD67F6 +B33A8D5710F1627447C7DE860FDEFDC1D34551BFA6450C8FBECCBCA61E141A1FBD259A822E4C27E18E14DA7FCF34A20FB6672B2B107496B2057534DC4057A7CD +AD95F944 +7E8F394959AB8406438A5C88DA +8147804BF5CCEE48E4E4A512E8183B630FBB7FA3DBA934ED801D2609D91DBFE30919D26B9A4A6F47E7DE341387F0DDCE6F4BA601D799EEB28DE637E597387C +952226EE +9128A8DD2E6CD1B75F6DCE4ABF +6067377553CB68A82AF5ACBA95935472A2546864266626ED1A5BA4DF39BB4E7166903DA2A98ED83CBF6523ACB79810E956321A71D34E4DDF28 +07F7038B +3771FD634E1C33863369911E10 +0A036EF56C70F4BF6F16F5376D3C192110822FDBEF8550 +6189F8D3 +AF11C71DB8A4DF99985B3A8E7D +70F350CEFD5AA56CEF1D03502DFB01FDB4F24C02D0D64A66F3D2A9B68960C7 +5FA5149D +951A9E973BF42FB279225DEF89 +BFE7329F88965675CAFFD846AD83DF8A8E0ABFFD33A826A11705A7908FE436BA070FF31F1491B758FC694DBE6B05BE97EF093C0240A340E224C1F6FD30DC4D0E04525A2792E3EDC03FEB +81D83E55 +10C731AA60D8F824424ACC5591 +E9EAAE52C191ECA34C53B64775A44393C904DBC9E49517754A2FA95B893C1B204D5DDE3484CA7E52C85947B551294CD8FC1299A02C627E3D2D0372C7EE515C564C1D0D23F29162A2F363086423CC39FE23F65119CAC089C4F8EB +13E10CBB +B960B4C58D5ED6818C6577A0DEC6 +33BC4444CBABC3101EDF020E3DD9281E9E74A0FFBF12ECF1BF60F6BB45D61399B7A85985753179F4AFA96D26242E931171AC9B8086216C89C7FF4FE3903FFE2EB0892E30B2D75E3654906E4AE0CCDE5CEC49617384A0E28BBFD317C034131F819D86C9214B6F4AA190BB1FAE712EC3 +866A7AF9 +8B0904D12122AE50EC2F6ECD37DD +AC21C503C57509A0EBE30A545E8D2F15AF98418983B90E70787DF18BF6747CCD6502A949E69C71C165166B435E836636D21B01FBDD37EB4BCBF57B3F0F9294CC22100BABDE5CCB472B51545C4CA759B1231B69839E0A5E4D7C1A7C533C4DB4751A3845679F +F28A929A +0F12673EE3C1E758A0890B785D +302C38EF51DE4E3B744AC627CE166F1652519A87D068754FEFE8059315B5F400DC4E14D5DA8151BDDC61B13804DDA87B92CBCB2DDC78 +00AA39A8 +CA339B211629685173B9982C5712 +93D7F36770CD0FA00B040774F4AC44C8F40F6102AE02DC01B69A5D6B615CE613E4798B32F4E7032B47CD67E5773D3FFD9C3A18260D0FCDD67CA3D3A996DBD6B84B577AA468499EE415115D98EAE0F742F1031B8B2B4378CC970FE1CE156E79E399180DBF1762AD13551AA3DD59C582DB7705F9 +76B9D730 +BEA12E4C2E773265FD9B0F37562F +B1B21A332F15FF053ECF96E537095BE8DF8DC2DEF12E473F75C01F534129DFBF3552CBEB5B2BF1A0C447B28FFB8F75B6E72FBDC0AA2DE84962691409980DA68F8799B402E6B3BEA1E090AEAB924D2999F87AD9DD1388B9750A1D02CE053A283A8CDB5FE35C5EC7542CD08A4AFE7DDCBEDEE706DE3E83E2FC022F9BEF200B +9E42 +0B +8C3A57D9 +9EFA07CFAB6F138203B01D5D33 +49B6F86884B57A3BE3AC16709BE639EE1F29B9A419189538641645170462E1EFD8DA51A33E8513198723C11D99B57877998B158A18D9548D9B442F2347E68436EAE31D8F4FF31BBBDE76B55FACB958F53DF3ADB431219037B929B0C3A31187CA7D +318C0218 +76E26BEEC57CC8DA1C41A6FCD1 +E20CAC6012CCBA8DED5F4E27AAE357116C6FEFDB047CAB6BF54A02C9D0B31C2AF725BD9F5B239BBC081EA8474582C2C9E1B1A67D7C117448171CE31B189EFEE40C970F93146D67841F006CC060452E4471CAD9D02266AED8D2217A12EC18C18EA88FE4 +CD540EBD +60C76CC40FF39C99642EFB9D84ED +B11E86C8C6C72B4E9D67E23938E6C18D609F7005CC76112384816E9740F3508032B7D460BBCCCD42F8413C1039156C1083292397010A065EB261B94C72D1E7ABD6FFBB6BAE3A3FAD346B5E2688AA57E5F5CFE8F63BB0783EF68F22485EF39E0883FCA0ADC4EBA7AE87375A84B5B8332741DF91F34E954A8718A468154EF7 +F2123C61 +09729B936180406CEB67E4109D5E +0A6DCDDC1A271B6F7E3E8B5EF13B33A124AFDBB85A71E698937E76DDE7B252516AA49933942F9364C584EC8C4D50ABDD112044A04FD0FB89CB74DF841637C76F56F36306A4D3954CBE3CA9226082B50C644FBB7480AA9B121DE639C77A9C347D92C1134250C133D910 +F9F187CE +606DE17445B6AFC83660F02786B0 +C20CD610211E9CA141AA2C8753DDC6648568D95D45DBEB6547DCCFAEBCFBF5023D517325F5712B44D8567BE9330CDD87F18791C0FCF5018D846348E6386348A322A0C861EDD714859F0CC0A67E8D9E964562BDF9DEBA15577769F81033184013E56194E793B3A360D5B441900C2DACA541A48CF9D8E46A287407 +292E0A62 +851BE476C2A0B5A9E35BE07CF0A0 +966ECF945AAE5B7CCC24CA09A9B100F3C701562C5B3FD22C850BBE59B6B436D67C4CE7C02AB274AFE160E87705B853EFEA66C77194049598B480E517625490F6DADF4CA2E1AB42A1A799153747F411D06EF80AD153C88AF547B0BB1FDEDB3DC49247876FF0BFF22E5842FDAC4AFE0505CE3A4439A2A2E7F050F5445F6519 +DB6B +52028C8A729C93C0C850BB +8930B55E +5B7987856E88509E45D77B928F +1470EA70830F189629D3CDA6218226132E01E3AEE9AA5D1A142F7FB144128EFD7EB58B21B3BB8C56EA878E79E484CC809348CF96A9544192D38D2A +A6927AD2 +12F2A2F7B4D1662D7D009C4B38 +93DF4E251809305D7B3A86D475C886FA10D5E76097C8D9AFCFD3D4CE49D6C4F0F6E3B0C775B491676DF538CF15BC3F2455EEECDA6D9979161854696A01E7445F22B625F9D6DE4A +81A9F8D7 +C0F80DC1A25E06F759A269A78FDC +06810D5EF312835570D2C28BE33A86FD54F4089070FE77594765233A67D55C84EAA6C6C135854EF199D0919BB5D6067B71D74EC8F9944B244911354639BBCEC2DDB2765C93B4B763CF28FE68CF444646BA1988C600A623DEDDC6304E03FC0ED1649BF56F877D7EC10592C3DE5FDFB6 +49A1CA48 +DCB2800FFD43E49CBAF8A8AE4E +95E3D9D2299D8D050D43148AD1DF3129EE941987878ACDE983A3CF3316FD54E6BEB04C73E224D259043E585FEACE96310E137B034820EBBAFD8E76A54E88442AAABC5BD22C19EEBC1DD0BB1E3B427662AA11A44A14A41CA0C44C9515 +FF01DE06 +1EAB18691879985E961F57E05B +A8B4D8296E1CEA10848053E9144847D334B58DEFF3768FE41ACD7D9E7C3109C1CD7C2DF53998A2B4B34FB07CFFB014770858A964C77D2AD6397C89E4D46DB844FACFA53A2C291A50356A6402AECE855EFEB2D5 +1823E682 +D07073F6693922C2BE73F486122E +E08A4870EA41491263D0FAA8A867821711DA26F25D0E944F8A703444D9E63A96508286B8CA9258356FAC0B074107ABEC3CB0CA4A60A6059B7788BC34202E74675623681D03C2CD6DD5B943D70D4B6A9455E90BE1CCE2377D1582D8774E1D3A76B613AD5BCB47B83B38A5 +476338AB +99FEDF61C0E4508087CC1E33F6EC +39837B20EBADF13D5B1795A56E7CF4FE02A43C4FD2ADB5436CB28F5642282B86CC14EDF43D6633C317D0895A5C1EC16224B60A40EAC9A02C8D4D975A9436C8A1ECF0EC68C604E63105D0F98B14D8B84DAB894074B2934AE966ED78904E9EC233198DB3A0215EBF2C8C51B2A5C2D70D8A485199CB02D6F37A824D2B9F8CB8 +D6DF5039 +6C97E8EEF606818F57F92D03A1BA +252D76A8FD5E930EE922A3B6335D3AABC8C98C6A4F446D54C29A2E977CFA7394701C32E2AE2AF95343B98AB1B68C23DB5436C5DA962EE75477B931CE0B76DE0005225BDBD009D42E54A346162512AB4B88960918A16B301C375551F0201222EEE2919F3D0EEF20644278EF0AF58FAD93AFA27657DD72CB49CB4BFEDCFA30 +1084 +FFD54E +53604DB6 +2284C2B3439D518264F8B9A15A +195A0ECD9A8018DFEF3DFF3C8BB1ECB147FEA9ABBD5CCD251D9D1FEB594C7DDF1F3C2AB391F48D7BE4DEF6FB78EFC9F190B28A2ABAD9DBD25B47FE2B3098838E6505FC148024A0E7BDF24DB33537A3064D +54211940 +5C4C4319C29CEAC972DD8388082E +54DEA065EE59E5C5974987E2DD3373607E18635451EF060DB84912FA319B61E21B3E86E05BA31FC5D0DC044302CED573DE301DE0C011F5B7E36F7AE0F51CD73BB1D9DCDC6B5CE50E49C792E5C03DF690E60AAD339D85D67BFD17FE55F63BA7BC4003E6ED +7D86E71D +8D43E68B3C58BE4FE2EA5A8D3E +4AA152E552783EFCFC261E770F8D44EF011082D7830BF0FEBBBB89F93C92919C10365E7EE9075880011F8A7BAA65DA221D6C516A4345E3AB72ABDE8035264AEA9214C09F7DD6D326A945B911C4B531B85853ACFCBE1E2CABE0 +28B939A5 +2F5104E4AB335F77C9142CFBFA86 +0BEDBD70AD5204F4DE4C57B5DF11F28A943F4639FDCE2905367E19C03F9029A47C754E22D1BF609F695849D3F251F083556219FFB2AFB9CC24A8409873D176CF8496E9920964982E4E515CB0DD506C644DFF3E9E89B26F60B742AD4E7A0AE02CF5815F4E140C9F0E9DD33F42B237F5C2C24419C42650C033BE6FA2261A84 +7E8F +DF99ECD5C1EE06B627B1329191458820D855C1C603B99AC7DB7E6844F48939DEEC058F50FD4511 +615E70E6 +C1A5CFB9215686627917B10C94D1 +EBF9CA1F2C67C219A4FA0D1FE135A7FB76BD5A2581F1CE656075E1B5832006FC09DD5008FC1409C14C07482DAA6F58EDFEA966B0C8673AA89AB26612E07D3041E06317786303DD2F9EAFA410F0C37F748FD847E5627505DF5C41239C512BD8C8725D454462A7305341D8615E1E2C44989F7530 +1338A262 +F6B7A84396B923016878580E7C +0E668F000E21E3223A5C3F9E592AFECB80D07D4554D9D4B0028DB3E709A40318A4F2D503FF1DA95F1258 +41E1ECEC +0C9DA6D4ECB8A26F209F339C39 +CF69081EB909784A6057ACDBCDA88CF5207A4EF60AF277EAB9B84494588C390D4993794CF8CE3FCC9D464396 +F46C17F2 +F66A2C502B869415A085B966F2 +F87215158518FD06C2BABCC78DB518B7DC26D4DDD897 +870ED87E +A2C9E07D6DC891AE7BE64FC7238B +6D3A663EE37D2137F95700B2C604CD0FF78E2CE51A35C50A962D3206F52CDF7E4051C15C54AA1FA081C4409412AC2781A2DC759F0823AAC03B8FCBDE7DE6C2873F3D9CDF49889E8081B69DF812268D46F65E108F0EF7577E4150867B43371961C7A5A9E1ED93E19748865CE8DE4EC5DEF3D5545B49E1FC1F8C77D01B6AC6 +DB8A +B37904 +6A428E3D +CAE21DF8468A4EFE1F8EE29FA1 +4441B9BC6BD480FF06040363C504C9D98C23750B7ECFB9A85DDBA811144D2F202A303B5E217C15202463FD6FD665DEEC5AE508762DCE1BCD7BB20DC7A045C855693C88CFCDD8CA79C4745DDCB1FCBC3E6F3802360D20B2AD +B6163034 +B89B687B9AE108F2A1BCF7C05A +89281F243E565275758752759FCFF7EEF3DAFB4F757C8CC768537D06C73802F8564954B8BC0509CDBC3D70DE58ADC1450C88150715C5A4AC88C1FB1616452EDD39CC01CC5C823E4EB4C7461F7534F41CCB48 +C2B953F9 +DE685F70001BE74F96006AA2B775 +5C4BCE15089D28BE91CFFA14A9CEEB30EE1A7D1D097F3A980C56193EF2E2ACF87A1B3748D20998910F0BF6C56ECC82B7EB48D958E3F247F1F89D244C3300D69693C7C3649314E72A0EB82E3449A6C007CF226F529F680FF4CF5AE1666691EC517269120B570547DB55C0B8D3DDE7 +56CEA7E2 +44CC65A088761C795B1E2D4018 +0A087B0AE5C9727267125C5A390C53BECD73F55DF939EC26C66C90BF488001AAC683D74E4D30E3FD0576C64F2E4FC819AFA3B6D40BF49D233082E26C4F8749E6473E1D0E5E731E6D0AD6622482923B182112CC5126191D782E +185FB460 +AC0C3680A83ACBFEAE4A526B99 +38774C9F90C2E886A4CF9D86D3652C320FBFDE054285CA9BC7D8ACF5CE5741721104C0CAE1088F80AC64405C90E7D3EA7EAAB42E1FDC5C9183C1CA463E7534D8A9248D1B3BEAFDE6022EDB2CE8DBD4881000233408D6F8894E9FD3FE +8B0F2C7F +C79AAE9D6A1269483B0DCA22B640 +D87E79D2D894F208A651BE6AD4CC86DCF9663F86CE34FA75E947F1590121060EF981237E479785712636B01926F7CA4EC5C2BFEEC77FCEE9ACD31D9D9A510B82475B75F811132DD3CA086BEAB190F28381E53395E65CC156295D0D30FD92F893DAF29B5937BB8A4EA82066437D6CCB1FFE0A8737ABA813C7A778D4790290 +BD21 +ECB6908134C6C912447B70F4E527A1E7C4B311BD36CCBDD67E12DDE7D78F4716DF244B8A9A6412E7B4F3190799CD97 +3360DD31 +73C37ADA7BE2B98F861DA2D878FB +2541B56105DE93EDAA9B31FCF3A5121C223C9416BF1574CF3A9D3D034EFFBA5EC2819FB33D192570E8E898E00D781C077035638AD8E3E8D4EC1D691195AD5651238F3AB26B5B82C4D181EB30DFD3569B08E43122861D61AB3E79F841B75D90CA9B327D76292C888C2E5A03A3C3 +CEF59690 +D182BFAF2456500DE58ECE7455 +EDEA610DA082BB7105963E70EF380BE0CCA7808C67249864A3E2627BC0CF88A4FDD081D67007201412514E645A94196F5F0CBEFA221528505F3F0B400838DDA5BA3869A6D58F2E2F5FEAFDE5E5559684 +0FC14339 +B7BA57884FAEEF4CA0068A62E2 +B9D20DFD87ED246817A6A4CE38C56BC41B471E32B9322FF42A89FDDA9859C205332328D6619506387E0ABFFDDF7BEC2D6CD4FA510AE4F12D9DFF00DB11ED7DAD8A4B89562D3A8E50C78610C013E555A6D31C924129026358B6D2C3A9EA9C6E4E24AB12 +F33BA4E3 +F9405117FFE8C51283B8EC2A214E +ED19C0940BAE6AFE63315E14697544F92B435F9656E893DF0F6E62B6EB0855E362F528307B9BAF05AB24C51EFA4C1EE26B849F0B97B2CAC38C446AA7AE15B4019CFB4B3377EDD760A5963CF68FD301A36F0C5C99E627B0A55D0B6294DA8776E5B09EFD878BB2B21EA83CFBDA1A0638884D91749EF7DAA530BC2274749EA0 +7454 +317DC481AE802CEF99751E667BB7593B6B4C1751E5C8AE7FE6EDC5440BA5AF9329DE28 +84C49564 +14DB9E25BDE78BC0219BF77FCC +B5ABDC057D369E498133C29F67B504EBEA966CB9EB36E2C6685DAD16D22A011C3951C7485E4A1770A3BD9F1CB0AEB774347CC02DE9F7 +8B4312C6 +3CC09D903285FC498AAA120EEB29 +9C276199C4CBD3EFE19F6AB2DB90E1800D38E4199443B4768D7B424FE2F88F80A4A6493A1896E18057472B2A812093445D4B23724DC41576C9107286E084D3B93BCC7EBA81A50E02A907C076E67D06E3FF0D1A273444A4D42EAE81952EECD1CD8133966AABE8D69FDC0C828AC23EFFA81DCEDADDC59BA1AC16AF39DA308D +C635 +B2E351FA9B5EA72B08BBFBD965A84D45809266A74A66F8B164D461855EBC65 +C550A180 +47E23471A42C0E16BB3929013B86 +BE815AB3284602DFA74C17CAF77C010935289EF9D451D0675FF47864C9EB3AD7F0F1EAE025EDD95154F226806C5E6540E11ECE0F6E7C000EAC069F9956ED8D7A0EEAA44645BFF5BFDB2E61F07DC19E3E5D89969E41E6B70B7852E83D8ACE96091201710293C3B8669C6AC578 +AE20BFFF +861E3FDF4F3DF2A65A1CFAF1E6 +F7EBF70ADBDED4B1F009D609518362681176B4D78E8E10B7D08359432CC4422DB6F00BF90AD9D28380B25D1BF9ECB31C39F0AD971C6C8F1DCBF07B2AF834CD560D6126CA8D91 +2DE08C4B +E0A4F7CBF88E7F0A1D6479766508 +21E6960C3706FDBAF993410F3D4D43EAE217919698BAF680EE7D4E3C29914471E3EE9001F61EB3D0F298E87901861299D9FF8B934F0A430A7F38689290C6AC4C546E48680B140B9E61E540BBEBFC8C32374565533862051ECBE78F63CA02A63EEAEE17507F4EFA740C7DCE109BD2D3A30290209C1F7603 +BA6CA650 +17807B43A95ABCA1641E91512710 +D7F85D588C2C63BB0CD9E736F1540D7209EF8F5E03F7CB7269835C1D3179BC5B7C1BC8142C2525D33864BFE48ABD6E9B3B27188F2465BF106F8008D5775C0B57F1A08FA842944DB7230D425A2CBDE8C201C5DBBA4A5B83F3F734E8DF59E6181E32BDB15952288C736003 +06DF6250 +7A30C3EBD9483E7CCA78C5ECFD +97E10345DC08D37CE9C5C6B9CA8E38074356FD8EB11A4F914263364A997892885042F8BF22DFB478F30AC384DBD2EE16742FC424E3F4E9724930E98EB9F6F2EE601C5994C8330F98594295BCEF83590EEA42E14252C70B +1183B7E7 +C5DF91F3E457163671FCE2D74F96 +310471B905AA2BC1955B438667B89691BDF40F43C4069FF908117CD9674D9668322299A4E2B11AFA617E0CC9171C9F5B1DF661AA03CC0DD25352620E6F334EA7A2E809C3039C08393FCC666C2E8FD098E325B0371870BFF5E15BD3384C56FD3583815B8D38BE6854CA00197952E48CE36F61822E048AE4B5488D8359 +6664244B +D10F565584F336D342DC533A57 +5B32E6A90EA77D9F79332EEA14C035A68D104FE0797B8BF3F4AA4F2910665776D044994179CA36CBA2EA4D465256DB7D5F6D548518EEECFB058268F835902A5AC366EC4B6C +F2717C27 +2609643CDF482219E6E3F8C28E +C36BA0E3A2A5AFCA579E57C1AAEB5ABB63BB8570E52BD8D011EC5EE99075E04D544E7F915EFD6FF0CFBD76E47460C0A07E9CAD1AC5A4F491D3E047CFB5D56531F1D55AA4483C10976E3B1542384EAF1443B7742FAB6722EDE49070E848C578F17678 +250B362B +55FD8256E18C99C6A0D937150B +85ACF42655934195BBA8259254035F2F05D96EB04BEF1A50738579680F0EB1834DF33FE1069672294161AC659A4EA2EEEE487C30A64D9C8A07DD5B6D94D5569758EB5BB581FF60FC3D874F0BBE3E3B5FBF0667B12E685BEFFC +8BCF48A4 +4949BEADEFD95661B5901B19A226 +EA899562F6499E2E24FF276C00FC30EA8F7B737A01FDC863CF5ABD3BDE64310A203CF9C8C0DD55D1DE7EE33D16405E32453D6F2E4252BA0C45B2B72218F778436091E284ED871B940A7EC2DE902003186B2CA72E2E39237E31D0187BC479DC89FD9CAEB623715FFAD12F8AF2C31F39F2A6DB974A0ACF8DA6B392A6DE36FA +14CD +596C4F3A657845FB2E0C89441945 +6930C4C4 +5D24F5AC2E495911D6C028D96A02 +8BE7C67D62E1D3A5BFC1A89618EB69DB832B7138AB592672A59031C339111060EBA084B680F1690F41247CA5EEFE72DAB43122C6F678645CD7F4B09FDB6E8C5CE8E430A299590EA671E1DFFEE81A806C16D071E63A30E65C53B9B488A3B28F0ABF485B938809D21DF3737B4DF9DA6D92E3A52E184BB2E16C09F6829827E1 +26D9 +C24157BE +07D6552541BB11A2E54B887B63 +2DF95672FC2F7449F38F98EF6BFA2ECED9205C32D7641B73667D680120348815FB702EA35142FA539BE4BEE2FAA08A317791375AACFD98EFF164E6ABE12CED +EFC50AC0 +88F3D26A7123CA392AA9684942 +17E7F75A323484846282DF65DA2B3A665F8B2B6B4D6F +CFDE0E3A +C5943FEF6D3C8ACE02FDD4F06414 +757F9924EC3FED02 +FAEA98C6 +8DB967F39AAED87D71DCACEE7D5A417ABC01AFDAC13917F9F80A7C693E80DBC8CD93 +70DA9C9AF77A2F074E2E3EC1C29D3B1846613E0A9E98EB180162F509078EB85BFF13BA7818F8 +F36B77080FC89BFAA94B85CF56929C63F6FE8F2ACF974DC3F7900F +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +%Defining font PSOsymclas +%!FontType1-1.0: PSOsymclas +10 dict begin +/FontName /PSOsymclas def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001000 0 0 0.001000 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 1 /C0069 put +readonly def +/FontBBox [106 45 775 713] readonly def +currentdict end +currentfile eexec +D9D66F633B846A989B9974B0179FC6CC445BC7C8A959A39A32E9DCE7FAEF17EE3BEC9F +50E1A6FCA651FC4B3769A0A91041557502E25A5D6180FE25A3D11BF079E1DF66E54EE9B7C229AF891739707A2A0EC140306B5E43E52B79BFB89E459E50 +6EC6F610A70775A31C460976C4F79449D86E57ACE491E5C6BF20CC4307B1DAF7630252 +E9AF8CFB69B50EDAE9D36A6104AFEF8832F920FD2346B2C7104CD11E3BEE999CFA9F5A +49DB3173EE48D1C82994237F360407B022E0B4 +502E94EA8B493651EF2D03F0B513D655047568325B512AE6 +6AC6F53F3848CF70DE25481CC65D8B1A5793AA +3C4282D111112BEE28AFCA7A3808D4444C4669CA +84EAAAF989219F51AB3476A1B0B5F2246BC306E6 +625C6679C417ED2A8E9BD010DE37D40265074C2684268F16195489648993B9C4D3B534FA887C +DEF605FA87B991F4D20A8F78DACE +5A54C070E03D5C59D9D2D3E06B09CEE028D68B62AB3AEC43C1DD20BA70D288597D9BD8E06818FF764EBAB436723988E8D7CA59E16D39032516BFC5D552ACDEEC6BE938BEF2F43CFFBC811C3626C4DF5F8CF080676520B51C60CEDAD1FE6C92D1431C702174CE517A8FA9377D075A0B6833DAB101DB65397F1419EF5F0016 +004F +6F0824F9657BB4F1C8F981709956865F6855EFAE +9242AD55 +91BBBEE163D844DDA894E13190C9 +2480439E4C71CADA +BD043A9B +A315CAF72652AA7FE6DB2E84D82A6111CE4DE90C02DA0AFFE2620922262A45AB4ED0 +EEC9F4520DD12703442F7D028D4526BD8B771E09FBE11B2749E2D3906894E8D4BFD3F379F14C +3C874F550606965E22FE487B247B5C2D06728490C8F2A3B588CDFC +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +/DPIx 1270 def /DPIy 1270 def +72 DPIx div 72 DPIy div neg scale +0 -13970 translate +1.00 1.00 scale +/wst:dutch12 12.00 /PSOwstdutch newFont def +/wst:dutch10 10.00 /PSOwstdutch newFont def +/wst:dutch14 14.00 /PSOwstdutch newFont def +%%IncludeResource: font Helvetica +/wst:helvps10 10.00 /Helvetica /wst:helvps ILEncoding 0 declareNFont def +/sym:clas10 10.00 /PSOsymclas newFont def +%%EndPageSetup +GS +0 13978 10801 13978 10801 0 0 0 clp +wst:dutch14 SF +0.00 0.00 0.00 1.00 setcmykcolor +<172837332835290b010c010d2831262b3024352e01293235011628243638352c312a011728373a32352e0119> 2207 558 0 7384 -1 s +<28352932353024312628> 7375 558 0 8593 -1 s +wst:dutch10 SF +<0809> 9346 13385 0 9522 -1 s +wst:helvps10 SF +<4e6574706572663a> 1322 13267 0 1949 -1 s +<205265766973696f6e20322e313b20436f7079726967687420> 1949 13267 4 3868 32 s +sym:clas10 SF +<01> 3868 13267 0 4019 -1 s +wst:helvps10 SF +<2031393933b131393935204865776c657474b15061636b61726420436f6d70616e79> 4019 13267 3 7133 32 s +wst:dutch12 SF +<0537> 1589 1431 0 1835 -1 s +<3728363731243028> 2033 1431 0 2857 -1 s +<20> 3177 1431 0 3339 -1 s +<3238> 3313 1431 0 3545 -1 s +<00362b32382f270038362800372b2c36003233372c323100373200363328262c293b00372b280037283637003b3238003a2c362b003732> 3545 1431 11 8066 0 s +<003328352932353006> 8066 1431 1 8895 0 s +<0c36> 3177 1676 0 3421 -1 s +<00322900372b2c36003a352c372c312a0400372b280039242f2c270037283637312430283600243528001c0e19231b1c1a100c1604> 3421 1676 8 8895 0 s +<1c0e19231a1a04> 3177 1921 0 4079 -1 s +<001d0f19231b1c1a100c1604001d0f19231a1a04> 4079 1921 2 6985 0 s +<000f150e18231b1c1a100c1604> 6985 1921 1 8895 0 s +<0f150e18231a1a04> 3177 2166 0 4291 -1 s +<000f150e15231b1c1a100c1604000f150e15231a1a04> 4291 2166 2 8895 0 s +<1b1c1a100c16231b1c1a100c1604> 3177 2411 0 5196 -1 s +<001b1c1a100c16231a1a04000f12231b1c1a100c1604> 5196 2411 2 8895 0 s +<0f12231a1a04> 3177 2656 0 4005 -1 s +<0011181a10231b1c1a100c16040011181a10231a1a04> 4005 2656 2 7079 0 s +<001314191914231b1c1a100c1604> 7079 2656 1 8895 0 s +<1314191914231a1a> 3177 2901 0 4201 -1 s +<0015180e230e191d0400243127001a1016230e191d0600210f282924382f370b> 4201 2901 4 8895 0 s +<1c0e19231b1c1a100c1622> 3177 3146 0 4699 -1 s +<0539> 1589 3492 0 1862 -1 s +<3928352532362c373b> 2033 3492 0 2847 -1 s +<1c2b2c36> 3177 3492 0 3571 -1 s +<003233372c32310026243100252800383628270037320036283700372b28003928352532362c373b002f2839282f0029323500372b28003728363706001437> 3571 3492 13 8895 0 s +<262431> 3177 3737 0 3491 -1 s +<0025280038362827002c31002632312d383126372c3231003a2c372b00372b28000519003233372c32310600142900372b28003928352532362c373b002c36> 3491 3737 12 8895 0 s +<362837> 3177 3982 0 3432 -1 s +<00373200070400372b28310032312f3b00372b2800352836382f3700322900372b280037283637003a2c2f2f00252800272c36332f243b282706001429000e191d> 3432 3982 14 8895 0 s +<38372c2f2c3c24372c3231> 3177 4227 0 4092 -1 s +<003138302528353600243528003528343828363728270029323500372b28002f3226242f00363b363728300400372b2800352836382f37> 4092 4227 9 8895 0 s +<3229> 3177 4472 0 3363 -1 s +<00372b280037283637003a2c2f2f002528> 3363 4472 4 4652 0 s +<002f3226242f00362835392c2628002728302431270600142900352830323728000e191d0038372c2f2c3c24372c3231> 4652 4472 7 8895 0 s +<2c36> 3177 4717 0 3316 -1 s +<003528343828363728270400372b283100372b2800352836382f37003a2c2f2f0025280035283032372800362835392c26280027283024312706> 3316 4717 9 8895 0 s +<18372b28353a2c362804> 3177 4961 0 4160 -1 s +<00372b2800352836382f37003a2c2f2f00252800372b2800302824363835282700372b353833383706> 4160 4961 7 7775 0 s +<051e> 1589 5308 0 1928 -1 s +<1c2b2c36> 3177 5308 0 3571 -1 s +<003233372c3231003a2c2f2f002437372830333700373200283124252f2800372b28002632333b052439322c2724312628002928243738352836> 3571 5308 8 8895 0 s +<3229> 3177 5553 0 3363 -1 s +<001319051d1f000a0607003128373a32352e2c312a0600210f282924382f370b003132002632333b052439322c2724312628002437> 3363 5553 7 8825 0 s +<3d> 8825 5553 0 8895 -1 s +<3728303337282722> 3177 5798 0 4000 -1 s +<053a> 1589 6144 0 1909 -1 s +<372c3028> 2033 6144 0 2439 -1 s +<1c2b2c36> 3177 6144 0 3571 -1 s +<003233372c3231> 3571 6144 1 4216 0 s +<0002050f14171c101a> 4216 6144 1 5392 0 s +<1e> 5369 6144 0 5531 -1 s +<0c151b00263230332c2f24372c32310032312f3b03003a2c2f2f0036283700372b28002c31> 5508 6144 6 8825 0 s +<3d> 8825 6144 0 8895 -1 s +<372835052538353637> 3177 6389 0 4069 -1 s +<00372c30280000373200372c302800302c2f2f2c3628263231273606001c2b280024263738242f003a242c3700372c30280030243b> 4069 6389 10 8895 0 s +<272c29292835> 3177 6634 0 3677 -1 s +<002728332831272c312a00323100372b2800352836322f38372c323100322900372c3028353600323100372b2800363b363728300025282c312a> 3677 6634 10 8895 0 s +<302824363835282706> 3177 6879 0 4113 -1 s +GR +eop +%%PageTrailer +%%PageResources: font Helvetica +%%PageProcessColors: Black +%%PageCustomColors: +%%Page: (24) 24 +%%PageResources: (atend) +%%PageProcessColors: (atend) +%%PageCustomColors: (atend) +%%BeginPageSetup +bop +%Defining font PSOwstdutch +%!FontType1-1.0: PSOwstdutch +10 dict begin +/FontName /PSOwstdutch def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001000 0 0 0.001000 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 1 /C0032 put +dup 2 /C0044 put +dup 3 /C0045 put +dup 4 /C0046 put +dup 5 /C0050 put +dup 6 /C0052 put +dup 7 /C0058 put +dup 8 /C0065 put +dup 9 /C0066 put +dup 10 /C0067 put +dup 11 /C0069 put +dup 12 /C0070 put +dup 13 /C0077 put +dup 14 /C0078 put +dup 15 /C0080 put +dup 16 /C0082 put +dup 17 /C0083 put +dup 18 /C0084 put +dup 19 /C0095 put +dup 20 /C0097 put +dup 21 /C0098 put +dup 22 /C0099 put +dup 23 /C0100 put +dup 24 /C0101 put +dup 25 /C0102 put +dup 26 /C0103 put +dup 27 /C0104 put +dup 28 /C0105 put +dup 29 /C0106 put +dup 30 /C0107 put +dup 31 /C0108 put +dup 32 /C0109 put +dup 33 /C0110 put +dup 34 /C0111 put +dup 35 /C0112 put +dup 36 /C0114 put +dup 37 /C0115 put +dup 38 /C0116 put +dup 39 /C0117 put +dup 40 /C0118 put +dup 41 /C0119 put +dup 42 /C0120 put +dup 43 /C0121 put +dup 44 /C0122 put +readonly def +/FontBBox [-50 -238 920 722] readonly def +currentdict end +currentfile eexec +D9D66F633B846A989B9974B0179FC6CC445BC7C8A959A39A32E9DCE7FAEF17EE3BEC9F +50E1A6FCA651FC4B3769A0A91041557502E25A5D6180FE25A3D11BF079E1DF66E54EE9B7C229AF891739707A2A0EC140306B5E43E52B79BFB89E459E50 +6EC6F610A70775A31C460976C4F79449D86E57ACE491E5C6BF20CC4307B1DAF7630252 +E9AF8CFB69B50EDAE9D36A6104AFEF8832F920FD2346B2C7104CD11E3BEE999CFA9F5A +49DB3173EE48D1C82994237F360407B022E0B4 +502E94EA8B493651EF2D03F0B513D655047568325B512AE6 +6AC6F53F3848CF70DE25481CC65D8B1A5793AA +3C4282D111112BEE28AFCA7A3808D4444C4669CA +84EAAAF989219F51AB3476A1B0B5F2246BC306E6 +625C6679C417ED2A8E9BD010DE37D40265074C268420ED804BA1359DB1C4E9E9947D0F22B9D142 +B8C7F32D6FBDC19925279536 +814044F42EE104E6D1 +E21CCB75 +F53F4F1A475E9E89CF9C5A5BE5 +8B59C0200560DCBF7F6C260B6C83E9A9417ED3847B81998A6473292D24286137F35BAD54DBA892140B3BF048F3C1C70845D99D11851BFF4394 +5680B68E +6F5DE40B41BDA0170B75E77A06 +A2EC0B716F418DDAE3AB73F1B9D06AA8531747ABB3C2B5 +DBA18595 +5454A8171C3610964E9E46C0D9 +4B3911FF6418BE188DAFD2D123110417283635961C4F694E6B15D9E19779E6 +7BCD0656 +36081E5EE2AB2D0446FC0EAF8C +7F57EBFA474F5FD8D08259FBF71F1D94E36B1924618A9D3FAA07A59FDED9DCACDAFF5ED6EA1B9A653C9B968437B3EE0733F4C7EE4603727F27ABF4A7A3841900391360004CBEFB936DED3371E5F8D337DE66BBC89B92E6FE1305 +F4BD3650 +42490D8A32A12B3EEFD537102A +9309D9661896677D4ECC5C81B20BE7749307F609150DCC878E3DE39D0B724BC7D658B7FF1FC36D724DFFE48765246F649EB858967DBDA0933481 +42F545C2 +BDA7BE06B422FD302492316FB2 +3745EE6E3D64F2A83C9D8F5ABC97C8A73FC7E5251807E35C7E2446494EACC7F841F8258611B97A356376D519F486C2A94DC40C424A03 +BE0CA890 +2A8C5E838D0C815F10300D51C912 +BE7CBA621A2ABF910F129A851AB2BD3C03015D8A6B3395E976267B0EA0711DEE5A53A860833ED418BB423ABA5BF4E0EE924E55B936270D068C1DF0E5AE806B10B46E8EA2BBDE9D86BBC18B18691D518BAFDF95A3EE363E10ED57216D5D85E33105E12157A73ECAFACF2E16B8EFA50D3C655256 +984D61B1 +914B36A67EA3DBDC5EE9F7ABF8CA +57F2147AF48F41931F98D715A78FDC2DBE3C8BD783473B778875B213BB3FE2B7226F6A90D01AA66873252E7D9F6172A6C434518C51DF20651F1F66A7581CA7F58D8208A1D74315292E962B1503D69540E09898BB10F3A417705E80D84DA9F03C009A68B5DE8CEAE8BA9B61C1265B327FE505680DF109AD2646864985E8E0 +F8DD +B0 +D9208D34 +22AE9FC5FBCD3484833E02672F +EBF3700B5DA1ED44E254A3754D48E0562E8B57F33932A44703446CAB9DB7FC1D851D77FAA3935F138974A6A5F43CC362B730006EAC1C0546956E8B9AB2CCBC79CA68325FD6395B81EDD85EB46EB409BCF98BAD213B6DD6257E93559FB4F86C38E1 +7A065189 +7D4FC414CD1F02DFE51BCC1B963D +FC1D7F5B356740F367F30393E6D1BF582066E5C97AECFF25B740E8CD1B1DA6DE53C19C1E82BE3D6F83FEAB3BA03F4B48AB032548B54A1CDAE344B28EE8A21C125AF3F3C4D0CA848EB8D533AE9201A4AB2E39F815B2427FB6A614F2B5B86EA1987CC5697A67A122C24EC5D3C80022BEF07F4CFEA419E06190271106C4A7A8 +EA3EC6A3 +D9CF6E16789A1F84220380F01E5A +27AC93A9CA1D9027B53691A1F09D05B80CBF35943200A5673E6923943845B98D697B717F1674B852E936E20BE1B4851EB218D8B108FB8D0E10CFFA8E556B8E9B836D504B8FF166FF9E78999B2871FF8A1854BA83D380A724690AA32E29EED6587B9287534CE37DD01C +9A146175 +244DE7B01551DA43B5BD7DA3233D +0DEF0EFBFBF34D64CF0557789F5BE2B0B8034CF24724254163B13C09879BC8AF274101DD8C4E1EAE61B4DFB59F0768D4C0AE70403ABBC40C5ECD35125FA4B70749ED6017466185B85D32D4624C1FCF42A3E355DCC8F130F1DCE13F5F1F659093FA82ACFCD578B5334F1E73D78DD4FE +83CBE3FF +CBF4E6910432D3C8120CF2A6A2 +0E81D819971070D28A6A34031B5C1123B9CDD9B03F8BC03A6868280FBC152A9E0AA7D72B2B19124FE8D0B48F5CA7BA381A94B0E43578B71337CCCB8E89F25F0E99525556008355C6EADC2A9712939A81667C1B84EFF2F99266C72B79 +DAD1AC7C +8CE08FCD98C0BAD02717C795B0C7 +A30B9E187719EA9EF9FA250DFB363BB00875C30D0DE0656C8C45BFBF50429B0F1749C12EBF457B017EE9B251E544323FCB528ED168343666E3A5823233ADE8922C17E3EE14C15034956F5CBFC965DEFF42F34B46E2333642361C1F824A570EEA6057896AA7FF5E00E4AD +C5965DED +92A81916796A985EC41AF49EE8C7 +89A9BC7FC7764DC3F8A6E88EF594C72BC0E8D3A65A46302445864370E2C6745EBD973EC9A8EF8BBCECD4CDB1542B1D21C4EB001CFBB54A77CC9C0CF726FD5CCDD16DFC672E192DDA0E54D69610A97AF1963CDF8553457FD2BC8CA1381A2E8BAE1D56265C5FD59893A7FFE4E77B9576BAD838B80FB3A90ABC0B4C12DEE83A +EA0E1456 +59A66538DCF532183A8BE6C56C20 +62C0AAB9893E2A611388B44141B7D584B69B6884EE51A249DB62D85A53F481546CF0F6E608A7E7B1E95ED8EEF15F788CE5555F9477E09415523D5048A611C28A7B75FAD62A177D69450B99AB65109A91A6219CC6B3D36FFC34D5A3B0EB4A7369B1A2F6843FF2E6A707265A23515232244E6FFF0CEF55BCBAFDA23F6AF23E +683A +246ED6 +776E6816 +8FF10121CEF8D3BAE3D247EAA5 +BF1BEC534DB4CE1A1E7C1EED9E9F6CCCE5BB211B2C0B3BF9E7CEFD407B0D7911F85A52AFE3F703E31F6894B4A71C4F2740973E1C04363ED49DE023B84B32D8DD7B17075E808D5232301A8EA2D7C0AEA94B +8B070290 +55AAF1894D256DE8C33006C79E +D4C963C7201C9C028E2775D8D9C4E0E6094A203C910A +5AAF563D +D02FC6FC14DEB89FD03B4D72FAF2 +D79EC8F46709E23DB119E927F6570D55C0151A77B03F4EFFB4F89CE238C42AE028F35367E0FD65086B4ADEE587F2E1067CAAC7208FA041E108A7060D1BAFD2A7B81718893F39E1940A106AB8FE01CD631760C7D509C07F53F2B829315D655BAF5E5A3FB126A9EAD252E467B2F90A9817B4653D5024564DD31481552411BF +5B5B +20A70D +5F55DDEB +05B05E29107C89A94A797DF580 +DA0E0A4F93DA544ECFD7AB1F36526277B603396B3921000E8B67727086BABCD5CAD0F44506530BD1014D1FE967C93AC89365B7993F71968419AA0AFFBA6C4F47CDBE197D6593E5E3C3E809BE3A175473AA75F7332D6ACFB6 +8CE76AD0 +CF2BB422EE1A5F7763998F74B3 +2F2DC260EFC68B675D99545683BABAA75D0ACCCE5E4001E7A7345F8C428B6F19D7E61E4A3BC8AC0F7ABE3EB451A062178259F77E7B7141268B1A75489B5EAF9419DF45ED2DFE362E428922A944EDB7F6676C +0199B048 +3D7290BA6E174B90D53206A4BC08 +DD6698ABC1165691B16BFEACB0A36CFC38E7D1B5E119094F1EF2556D3369F6F668861E6D006262208DA8B46B51CB9B327DE18C017E13F11F136C3E17B492F85615662D667651BE84223875BF3971B720243A610BD189D49533E47AFBAFFCB31969CFADEEE43A69197F4BF79D4478 +37F896E0 +747A00FBB2CDB7A6F76A9C3687 +7D0B777E545242FE8BA9EAF3A4819E21B564258E18C43CB071524787A99CE8A451F80108996A61CDACEFAD2739C9899F60E6FB716908713EF70422313924BD0D4C4ED2F7BD99D593288559A8A5C4062DFEF7C360240D36D770 +646C5A69 +41C1918A444DC0E59243F0A89C +4DF01C433767F700AA3041EB64CF697C0359372321AEA1AF4B16CAD5D63D1E23EFC74439730BA13D0C61FB83AF1FB21FD926D59B07F4685457413B8C7B57ED03463F8FA982925CF29E8C6CD1D1A3F16A79365CB4CB3DFC00C42EF20D +754232A1 +B96471A66388E18ED15DA4791C5C +AD5D6C71BC76F4B2DC802D50A851C1DAD8B8D93C34FCE617053A82EEAB0A3F1AF40E0BB500915955E0ECA72457EF6D4837D64C7F2BDE1390DF9820D68A699F639BA0022D12A5FCE51056D9F5A06EA3EA9631B7AA96281F1329A1E97EBB516D4D84B7A3AD8E642670C186F6DEACC87A023D8408B654FC794C440E33653730 +A15C +6D893C1E863C51063A4006AE06DF0B207131B43A1887DB68EE0A2A35120140214A23C48A72FEFF348FC68EC8878151 +D6174437 +16CABC0FF9C1BB9D6C9F0295F6BE +F10FF79D8C6578CE9EF913DDB2701B43C9F05D693AFF46EA3D09B5EAEA8110933A3A2C3E6FBB7CF8F4104BC92AC799C523C1ADCE684BFA82E258B27E445E8F370B57DAEB0C9AA8D1D3628F92475E09EA62000777B4E5708B55994919D52CBCD20E2C26F45E080E476F2D146160 +4C840EE5 +7071D8404121B7CD08AA0822F3 +31CCCD4B223CC2127F6EFE5CED0644F7527982E505D601144722F51FA9C60B93107A6EB2AC776B7CFDB2C451363461B6DA857AF04FEB4572E1B185B67F0FE87AC0743168C10DE14D561A8536BDDDB4E6 +488D6144 +40B524E956DE2972A030C3CC71 +D1B6A8BBAFA732DD0454F43862FEFC9F53119103F26F5F8A11707F66597A81C1424BD35AFE05040152C84E5A93698DC608A4A9EA546D7DCF201B020AEAF0A3AAF9AB279D6D3D4F007F222DCEEAD2EBDD89A284331D2203D1A068903EF8B549F8BDDA93 +FE56E7D5 +1E974D594ACD6F36C87E15C6CAEE +EAC922B8B7616D89AD88CA6C76DF9618DDCE5FCF296C3DB2B079C4273F6926CEEA49F54068347B7A4BC9FA63A897F56AA6F9629EC7F55F58437829FB0CE47482B6FCD7FC88E462F45C9E1F49C812C3E6D0D00F507E9DBACB34EEAA310CA13BB52BB2516C6B967E6720844CC015F573BEA9F420D6E9FA1D0D5C6B30D15348 +5902 +B54CE0D926386AC3FDEB0F70C6CDE07F1DDF28C49FBEB6DD4910358669917CEF29878D +C90D6418 +89DA785E1BB956186AEAB2EF6A +77F16BBBFAE0AC14981698DDD525CC961496896F4228D00D1D1E663F24E35810675583CD11895F74DDA1C657DB3D1F1033CCE2CE15ED +DCA76972 +CC53D3D4DC2C1A9D0FC4F587351A +0F3247030DF8D38FE0434E1C866B09397357CB009171B1DDA92B42211DB5A5E4BE0B5913A4C17FCF97318BF354781975E793ED3D3527DF47619B6AEAA4FC2669AA4C6C34EAD718F4F7506A0F39195245FCBBA5E63A79F19294CFC9AB69CF3BC4DC841457FFD5AF21C54599C8CD5F1137BD891DB9CC634791A6939C730DCD +228C +64B557F756AD2D1F057D3DB2816EA882E7D0ACAFF59514F44D242CC7CFF8F3 +D19C755B +A11750E0B44B3B953C509B390B0F +B0E5C3F460A30B9FBDD1F9CD4B4F2FA1C1A1825D7A65F8306D0DE5CCF3756443DDBDAA3F3A8240F5E496F09D1AA13E0BBAFDD18ECBDD17D94E868109937E21E596D07094F3D791628ED2D4B6500D19F656B3543D0E634B203102DF1F54F32A6E37C00BDE5DF49CE66B2CD19B +61C0BD2C +C29BFF27487873EF9AE57277BE +17AB3EC8527E5C49220D837D91E8F0C77B444F7648CC2849E208774D77BCFF48C67B0DBB7CEE0E3E1760D19E964028C9C977CC8AF37EFAEA68391E95C5BC9DB6188970F49A16 +D5C10D1C +E9359D75EA1C25C84E0F48F857B3 +2920AD49ABC1F74D6556B50353002A114C504B5059D120400CD87553079E5C3E7944F1DBFE229D40149920BD7AE822936D088F81198E5B8BE27E306057BBB201BAA92D403615803F2451FBF5DB50E71F4CB00DB20EEF9EEBBE55A4300A74B5CF915DEB3DAF37B90C96A8325745472C07D577A842F460D3 +04DF63C9 +E2824E1BA1BECF63030094DC21 +1CB2CB94085C4DAC90A2E0CCFD434518C5F539F1F1F88EE5C55EBE2BDB7BAB5DF34D2E849176A6E737C74B7D9DA88A22AFC58C8B4F551D115768873EC623DBD21A3F3146B116F20A91BCE718EFA2A5E34466C5D480AFF0 +E887C9CB +C1C0761F0EE2A9FF817582D67DDF +250E3AABAD61AC2C292AA712F7F04992525249C8D7B1434FC81E5C3A1F1D8F21BFA31AA50D1D82F209F63246B2A485026D770531BE351E08FE6C4705DAAC08A4451727867BF5038DE1EA247014D6924CE3C8DB97112866E2F2D1965035A6173C678C603D2FA2CB39BBA105B4CBB3EDC69055D7B473BB83889C88DCC6 +6D1B3F05 +CEB62293EB170A5FE1981AECE8 +D13DC6537EC1DA765E9CCC8A5802BE195E1FD23229B4790055DAC8154C2EDEDD836C26AF5825B8E2871C669256588BD7AE43A17DFB341E4AFDC8983A4480D583B643BE2681 +BEB7EF58 +C8B033AFA0B2058828073CFAC9 +39FDF750A29B44A26CC2536966A29633266CF5C7F7D6244276C5CA4BE9014DB5DA94EB007118B5089E064284B1973B3D1AA93CE130D285D06D03F86D706514283C3BC1FA82460D1969BD87A0EEBFA1BE69D9E05B5CB16EBE06DCDEECBE3773EF4A42 +CA8FF6E5 +53E96322508A969418C6F913E6 +66C27F0854C7042FBF81C752C2DF1A6C0290C31163286839716F0120C8AC34CBA5C3D18C01D49DB36CD0554CC87BFDC4DB128A9829468C9FA1856F26397A9CF25A0260EE78AB5A2DAC12517BF93211BC19A35C91194BD45F60 +AC94E602 +5F99C1F0A6408E474177264C5098 +160CC644E9E03B5FEF2B29855CD81725147C5581387804F03CA390A24AD395FCF0B1E87E958EABB5BC3BD45547938FBF5AE50EC2546834B01A00FB1A77ACB7FA1651F0868C94275540685DD6E05A30C04D5B934A754015B0148FC124DB0B8DFBA2893F80028A42B971DC003F0D0EE2553B72C9F990EA44AE9A87310EA70E +DB21 +92FCD581C69BFE17C1FE84AFA78A +52735304 +8BDDB4E00BEC9A4CA73DE4774F66 +DF77395F33D93405D440BA1872A87F93D2077DF3FF1A1E78BABC3CEB260F1816616BCFC8718EB60F39D284E3BA9FD679056EA48A4BDEAE9745CCC99158275FA618C98F1E049CBFD269053E63E61C293D41133B06ED4145202FD27FC7A69A7BA038DBF9FD4200B72B4181019DE70F01FD515A57CBB3372EA9DDCBD94188C1 +DC9F +2654C057AC73BC43C7D4483B766DC212B42991751E520CEBD7 +DCE029AC +D61BAD5A06D79A1BCD6F9AA70CEC +4B9A451A6F07F31892264DA4788008A1E0367772950A9C90F44A9600A59F2E93007393AC038E5F06AAF5329B42450BCEB8982F40E30E7B74B238A761A204B545486A47013F6EDD6FCC68CA092C9A26F0E3CBD26E0535FE25E35CAE69B1850D83FCF1DFB027BEA0F04306376CD994EF92BB2BE5E2F3973AA35208EC6AED32 +9842 +4BBBE4D2 +3EA0F498FD54BEFF088B4909C3 +7CEBACEEEEBA2FE70DC9AC7AD3A34219CB43E2B658E5F030508C832E9D4A9582C4829E00A63FFF3ADF8B8466A0058E4D76418051C3C1AC42646798C64C9999 +BE657AE4 +CAA9FE95456491C0CDE56A783BD5 +E0935B9A6010A407 +B3663E99 +71A1DDFA2700071066AA9A2555CF3E3D1F932E6EE07A1F88948C47F079674899A1B5 +00D54F9D10B0C22E6CCDB95CB2584F826B89BBE578E1409C4FCE89882472B82753E2D87033D8 +CAF4CE536577FB0A5B8764093217681F0D1E9BA8D1A56E57D8E76B +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +%Defining font PSOwstdutchb +%!FontType1-1.0: PSOwstdutchb +10 dict begin +/FontName /PSOwstdutchb def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001000 0 0 0.001000 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 1 /C0032 put +dup 2 /C0046 put +dup 3 /C0056 put +dup 4 /C0058 put +dup 5 /C0069 put +dup 6 /C0078 put +dup 7 /C0079 put +dup 8 /C0083 put +dup 9 /C0084 put +dup 10 /C0097 put +dup 11 /C0099 put +dup 12 /C0101 put +dup 13 /C0102 put +dup 14 /C0105 put +dup 15 /C0108 put +dup 16 /C0109 put +dup 17 /C0110 put +dup 18 /C0111 put +dup 19 /C0112 put +dup 20 /C0114 put +dup 21 /C0115 put +dup 22 /C0116 put +dup 23 /C0120 put +readonly def +/FontBBox [0 -207 798 694] readonly def +currentdict end +currentfile eexec +D9D66F633B846A989B9974B0179FC6CC445BC7C8A959A39A32E9DCE7FAEF17EE3BEC9F +50E1A6FCA651FC4B3769A0A91041557502E25A5D6180FE25A3D11BF079E1DF66E54EE9B7C229AF891739707A2A0EC140306B5E43E52B79BFB89E459E50 +6EC6F610A70775A31C460976C4F79449D86E57ACE491E5C6BF20CC4307B1DAF7630252 +E9AF8CFB69B50EDAE9D36A6104AFEF8832F920FD2346B2C7104CD11E3BEE999CFA9F5A +49DB3173EE48D1C82994237F360407B022E0B4 +502E94EA8B493651EF2D03F0B513D655047568325B512AE6 +6AC6F53F3848CF70DE25481CC65D8B1A5793AA +3C4282D111112BEE28AFCA7A3808D4444C4669CA +84EAAAF989219F51AB3476A1B0B5F2246BC306E6 +625C6679C417ED2A8E9BD010DE37D40265074C2684269B008BDEA74560252260FB40E310D1737A +85450CDE23E8A2496758B49C +4B75E970A67937FCDD +BDD4550B +55F974593DA407A0C2E2C88FA9 +336082C8D0820B4444FCC128F7AADC032BF8155F022E8721F027C2D7517B3F +C4F12A63 +5396521E42A2D26B6AF2261558B2 +DB9CC40ABA525E48C5DB7F562A77428AD1819166647390256FB460A517FB479AA4E22133C926D905CF1D798CC8633B33F6495C9159D2C12E8B97B8DE71E14EB61F9D4EE91964531A8135FCEAB5226985F137CA97C9E9DAFD22F03281B8F43AFD4F9330F6130053F6A548FF3031EDCE57520A8502282920EF2728 +C10D84F1 +2340113500B3CB6480C5905A60 +24BD32084D87FE83B206F7B6BC6069C5A0286D2E446D29AF9F3BFF91F3A3E25EA55EB1172173F1F4C7D296D91E6038CFDCB5BBB1B7BA +376842F1 +07F38BAE91E73843B8F7A80550E3 +A89AA8A125FB256E209233437A20B5B7668573629634303F3D3F690DFC77EE522379086FB7B59716C07BB84636F92703C0158374CE47F58C7FB3BFD40219004B9B14419706699F53644070248BA1568A83F783C0D5ADA2B1228FEDEB569239CC515FCCB296200CE6D28CD859B30E +561B9A31 +EAE92FE9253FF1FFFD95C829BA +1924733AC18839962752F1E4AB7E8C9D7586205EBDD1D60425CCDFDD24A144D52074A9A16EA676110702C2B5FA6C4E4B6941EB35E61C467797BF355BB823986189ECBB2D7ADDA329EB578EC354EB822CEBBA0D3BEC3D117C6CCA853C2C5F06 +E5E2265A +AC0BB18BBBB96B11E1D2FDA7B851 +6FF32957DB9B25AFADC47C5EFDDBE059B43D0B688999FF9B01312DB96925D60CE612E9CB9B9F44CDC86B6BB2D52F4B8373154804A16FD6DCAAE554D96A475AFF201D62B249BE03F5A41A2C556EE6EE59D46ECC1AEDBCC218DC8770857E2F21DCD5B3637FE7F99BB69E +797F722C +74B40A3EE8D65D6D278916824E45 +E6541AACFBD4981985372A2A9A7DC1A571E599F90F88A674F7221DFE6A74DC95507753B80E591254257B690DF4BEC3487F3AADAEBCCAF346A2EE5C6889F8C0B248293CBD8DF0B0A84E1C21385643E19F1B72C5321191C103E74D4BC77978668C39BB09828D3191C8180BB350F551529372914F3EF2FB85B1291D581CC96C +3462 +06D7F2D9 +11C2F4B87825ACE848F64B20C2 +4ADEAAB49D277F6AD0C65F62701454CD4969A4A2CA48BBCA5ACA55CA603469AC6A437CECCC9D026E5E4C5F6924D69315CD44104E62942ED78DE88A57BCF224C0E473E5D997C5AD0E57 +B5C431BD +9FC2BEF8984B0178A2982DCB4533 +12073C7E039CB5A1A9AF63C4BFF4A5F36C8469E9E92A949FDA0FCEA69ECB713883FD91233291C5FACB44E652332C27CA08C1537D6167BF5C0DAB2A4BD00F41348B2070E7ECFC0D3DEF791B439EDFDC7BCD81EEC286DB19F97E5B77612365095979F46C712780561CFEB5A87FABA765BE31FA2D3944CAA63CEF955D6FD4EF +180A +BFCEF0B1 +D02704DA +84B7B6FDF255F93791F94F94A5 +74D4E727CC7D1C9BA57276754008547F6513E21004CA37DB872C44103280B048FCB91DE15A6920FF0C531E1B6B2894BDD5795B7FF952B379A3FA51CF590CCB007C5425C74555937633F72607692FFF08E4B0 +8E17A269 +4DEAFD4F9373D752072255701F +2BADE283F429EE336A3C3926D59BA2817F86395E5E93E37949AFFD4CC8DD9C90C865ABA14922F0BC1806A1596C62DF51B037BDE3448995CC56BE7DFF0D43635DBFBA2160E48D1A8A1DE5CEFED91E28212AE8F069E1108FD86E6AB455 +F7CADE10 +4E52E74F3266AFD08E426DC433 +391AB622FA77DCF19FA1128AEA3311CFF7D3ED2F4620E849E89B76C74C7EAFF256D549BCCD9CB766D62F71DCA553FA438134708EE0CA20CA5FD3DDE9CC3BCD55831A8504D2416BA28C2105558D7BD71AB8AC69014740DA959649131394 +457B9844 +27C2340D8EF666839D8ED9FE79 +59EE2EE584647B3F023845A6CD5913129445D917E2BF1EF3490C181E3991A4D74C10C7D643A0C7B916C4DE93049B23DBA38E5634AA16555891273CF558911EA03D544A7CC9A0A11FF2695C2E998D +BD06C4CA +0632D1FEC45F5DB4061D51718A +417DAA97DE9ECDDFA269ACD6DE57621895171B678D5732312F82C34403588FE2DE7F9CF6E3F18E0B62FEB1D2DFF3EDC4E801D4E8 +D7C5F625 +1F5D1B8B4BE5A0DBB842F078106D +54A33F9752D76D4C6CE5A1267D56EAD47405738C00C26D982DE60E8FC132E8BAB40E77BF45B392FB038F979A1E8BE0D488B7EFDC5DF4AC4329EC6A32345ED4A9A3AB5CB937C6AD751C0E505BCDA25FC697309B49AAD4EBBA3DCF7BC4FD44AB95664880E5423AE8DB2949902ED1EC0466D347CEF3CAD42404AE3312598BE1 +ABB4 +11EBDE9FEB7832FE485D932492C6C38E9089D1859645917D2A1F1567 +3E6AF37E +BB5F7EB6EAD57AF719F3552D8020 +421EDE0DD2975C18EF8C094D87D129A8A9AC2EF23E2FE33E3C614C71CEC90BC4FA883A9B2FD1F8B47A1F1E50F6C286AC34F680AAC1380AE08FD28825806E96A95076A240A35D3EA19A232BDE93888C023E2C8556BBD39D3A1FCDEB203A287BB10FA7D59C232D4A +756999B5 +7063CC963BCF822E703E86F8A3 +C4326C4CAAA69F36A1C0877D166E7D2373CBAB5D6D556A79DDE5ADDBE847B1F28F32B40D8C2A0EF0725D66AFEE7189A4D8EA95651DC40E2A582BDD9D3A3322B181D83279AF21 +25B5505A +436FBCFC9A8610BFE12A3919755C +48B4F711992E604D4F958199B4003384F0A940A459F80125DE2D07ECC2ABBD4A4600CD500BE10C43327169CC36766124D7301F2A6A76D1A64B159DD528D6388603993428841912371217ED7BA324056B3D5A701F2F400545CCEC47800E65D93AECACDD97E99D2E7D578192F79CAFBB64F0 +3156F7C4 +ADE7CC4CCC875761BDD8A06DFD +70CDDB93C2D71DE1767141E5D60A8394E9FBD987DCB57E84CB668CE782B57E8EF7B3F8E85FB193B17BFDBB07C17D4B82A18C9CCC8112643E764636E76549370EAADF7F694EC82A15D2B17731B18491F16A7BFF55148CD76548 +23887604 +8420F80E35D8C098BBC3B676CB4C +CA7B5AE8BA734E5C280AB396A5966543D297809ECBDECA40727940DFB24F5467F925E8ED926D6784B08FD393E9EF7644266877E56F686A9B72C8B9F8BE1C332E8C53E6E5D760B2151F6DA9701EF1D223627BD6485C586D88B45D19D3461F03D2C3522A8562350FE3AD9F8B082383C48766E017D86E9A42E036 +CC5D9137 +A6C198FB9FC513DE7FAFDF3784 +DC26B85B7F0ACA38824D9646DCD42B99B1BCF7F0DD2E7385B3BA60071DE73A59F932617542DF98CE113BB4E8BA026BA251780F32B8532631D4E72F52B4EDAA425D56FE0E +563C4C00 +A22D4767419773CC31CA97B0D86F +F2BC399B70A3DE18DD4AB1DBB8011DF1396B49030FB2774651B23D292E932E6689B53CF0D4003E5AF9C7DC6A002EDCB3D6F133A0A663D10002E6914F9612A47CD045A71AA28DC36D411C4C8D4313F94775036522A4606250E52F9FA862A4C2654515ADEC1349F168FCEB86AFC93EC43B5E6AE368D4020AAE9F4E8A0DF1AF +51C0 +BE970BB23531E6F66EC29FB4125470458885CB670485 +E65E4D0E +433A7E81C557605AA7523CE185C2 +DCEBF14AE5FAAB63 +8B7DBE16 +263781598BFF5063ADE5ED703E1D9C06E82E3D6B3994595CAC98C1A357BB7B4E4F63 +08D41B37F46C3D92867E9D71C6D378AAD22B01FEC49DFEDF0953FF059E3C70142145B1FBBEFE +173F955AC3D038D929608321877736D5BA17EC0C3626DA761E04D1 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +%Defining font PSOsymclas +%!FontType1-1.0: PSOsymclas +10 dict begin +/FontName /PSOsymclas def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001000 0 0 0.001000 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 1 /C0069 put +readonly def +/FontBBox [106 45 775 713] readonly def +currentdict end +currentfile eexec +D9D66F633B846A989B9974B0179FC6CC445BC7C8A959A39A32E9DCE7FAEF17EE3BEC9F +50E1A6FCA651FC4B3769A0A91041557502E25A5D6180FE25A3D11BF079E1DF66E54EE9B7C229AF891739707A2A0EC140306B5E43E52B79BFB89E459E50 +6EC6F610A70775A31C460976C4F79449D86E57ACE491E5C6BF20CC4307B1DAF7630252 +E9AF8CFB69B50EDAE9D36A6104AFEF8832F920FD2346B2C7104CD11E3BEE999CFA9F5A +49DB3173EE48D1C82994237F360407B022E0B4 +502E94EA8B493651EF2D03F0B513D655047568325B512AE6 +6AC6F53F3848CF70DE25481CC65D8B1A5793AA +3C4282D111112BEE28AFCA7A3808D4444C4669CA +84EAAAF989219F51AB3476A1B0B5F2246BC306E6 +625C6679C417ED2A8E9BD010DE37D40265074C2684268F16195489648993B9C4D3B534FA887C +DEF605FA87B991F4D20A8F78DACE +5A54C070E03D5C59D9D2D3E06B09CEE028D68B62AB3AEC43C1DD20BA70D288597D9BD8E06818FF764EBAB436723988E8D7CA59E16D39032516BFC5D552ACDEEC6BE938BEF2F43CFFBC811C3626C4DF5F8CF080676520B51C60CEDAD1FE6C92D1431C702174CE517A8FA9377D075A0B6833DAB101DB65397F1419EF5F0016 +004F +6F0824F9657BB4F1C8F981709956865F6855EFAE +9242AD55 +91BBBEE163D844DDA894E13190C9 +2480439E4C71CADA +BD043A9B +A315CAF72652AA7FE6DB2E84D82A6111CE4DE90C02DA0AFFE2620922262A45AB4ED0 +EEC9F4520DD12703442F7D028D4526BD8B771E09FBE11B2749E2D3906894E8D4BFD3F379F14C +3C874F550606965E22FE487B247B5C2D06728490C8F2A3B588CDFC +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +/DPIx 1270 def /DPIy 1270 def +72 DPIx div 72 DPIy div neg scale +0 -13970 translate +1.00 1.00 scale +/wst:dutch12 12.00 /PSOwstdutch newFont def +/wst:dutch12b 12.00 /PSOwstdutchb newFont def +/wst:dutch14b 14.00 /PSOwstdutchb newFont def +/wst:dutch10 10.00 /PSOwstdutch newFont def +%%IncludeResource: font Courier +/wst:courps10 10.00 /Courier /wst:courps ILEncoding 0 declareNFont def +/wst:dutch14 14.00 /PSOwstdutch newFont def +%%IncludeResource: font Helvetica +/wst:helvps10 10.00 /Helvetica /wst:helvps ILEncoding 0 declareNFont def +/sym:clas10 10.00 /PSOsymclas newFont def +%%EndPageSetup +GS +0 13978 10801 13978 10801 0 0 0 clp +wst:dutch14 SF +0.00 0.00 0.00 1.00 setcmykcolor +<0e18262318241907010801091821161b2014241e01192224010d18142527241c211a010e18262922241e010f> 2207 558 0 7384 -1 s +<18241922242014211618> 7375 558 0 8593 -1 s +wst:dutch10 SF +<0506> 9346 13300 0 9522 -1 s +wst:helvps10 SF +<4e6574706572663a> 1322 13280 0 1949 -1 s +<205265766973696f6e20322e313b20436f7079726967687420> 1949 13280 4 3868 32 s +sym:clas10 SF +<01> 3868 13280 0 4019 -1 s +wst:helvps10 SF +<2031393933b131393935204865776c657474b15061636b61726420436f6d70616e79> 4019 13280 3 7133 32 s +wst:dutch14b SF +<080c0b160e1211> 1271 1458 0 2055 -1 s +<00030200060c16130c140d000c170a10130f0c15> 2055 1458 3 4222 0 s +wst:dutch12b SF +<06070905> 1271 2086 0 1866 -1 s +<04> 1870 2086 0 1928 -1 s +<00> 1928 2086 1 1984 0 s +wst:dutch12 SF +<00121b18251800182a1420231f182500142418001924222000142100221f17182400281824251c2221002219002118262318241900142117001722002122260024182324182518212600261b180025231f1c26> 1984 2086 15 9531 0 s +<15182629181821> 1271 2330 0 2027 -1 s +<001a1f2215141f00142117002618252600252318161c191c160016222020142117001f1c2118002223261c22212504> 2027 2330 7 6242 0 s +<121b18> 1271 2677 0 1631 -1 s +<0021182a26001918290023141a18250016222126141c21001421212226142618170025162418182100172720232500221900182a1420231f18002118262318241900242721250400081926182400182a14201c211c211a> 1631 2677 13 9531 0 s +<261b182518> 1271 2922 0 1747 -1 s +<00182a1420231f182502002b222700251b22271f17001b14281800140019141c241f2b001a222217001c171814002219001b2229002622002418141700261b1800222726232726002219002118262318241900142117> 1747 2922 17 9531 0 s +<291b1426001819191816260016182426141c21002223261c222125001b14281800222100261b14260022272623272604000c1c2425260200120a0f131112100b080d00261825262504> 1271 3167 10 8097 0 s +GR +GS +1263 10477 9522 10477 9522 3370 1263 3370 clp +wst:courps10 SF +0.00 0.00 0.00 1.00 setcmykcolor +<24> 1449 3504 0 1555 -1 s +<206e65747065726620b174205443505f53545245414d20b1482068706973726471> 1555 3504 5 5053 32 s +<5443502053545245414d205445535420746f2068706973726471> 1449 3680 4 4205 32 s +<5265637620202053656e642020202053656e64> 1449 3856 7 3463 32 s +<536f636b657420536f636b657420204d6573736167652020456c6170736564> 1449 4031 5 4735 32 s +<53697a6520202053697a652020202053697a65202020202054696d6520202020205468726f756768707574> 1449 4207 17 6007 32 s +<627974657320206279746573202020627974657320202020736563732e2020202031305e36626974732f736563> 1449 4383 13 6219 32 s +<20203831393220202038313932202020383139322020202031302e303020202020202020372e3134> 1449 4735 19 5689 32 s +<24206e65747065726620b174205443505f53545245414d20b148206870697372647120b1b120b17320313633383420b1532031364b20b16d20314b> 1449 6181 12 7703 32 s +<5443502053545245414d205445535420746f2068706973726471> 1449 6357 4 4205 32 s +<5265637620202053656e642020202053656e64> 1449 6533 7 3463 32 s +<536f636b657420536f636b657420204d6573736167652020456c6170736564> 1449 6709 5 4735 32 s +<53697a6520202053697a652020202053697a65202020202054696d6520202020205468726f756768707574> 1449 6885 17 6007 32 s +<627974657320206279746573202020627974657320202020736563732e2020202031305e36626974732f736563> 1449 7061 13 6219 32 s +<20313633383420203136333834202020313032342020202031302e303120202020202020372e3332> 1449 7412 17 5689 32 s +<24206e65747065726620b174205443505f53545245414d20b148206870697372647120b1502030> 1449 9035 7 5583 32 s +<20203831393220202038313932202020383139322020202031302e303020202020202020382e3037> 1449 9210 19 5689 32 s +<24206e65747065726620b174205443505f53545245414d20b148206870697372647120b150203020b1762030> 1449 10072 9 6113 32 s +<202020372e3035> 1449 10248 3 2191 32 s +17 LW +N +1931 4886 M +1931 5394 L +dp +N +1984 5082 M +1879 5082 L +1879 5082 L +1931 4886 L +C +{} -1.0 -1.0 solidFill +dp +0 LW +N +1931 4886 M +C +wst:dutch12 SF +<241816181c2818012522161e18260115271919182401251c2c1801222101261b180124182022261801252b25261820> 1856 5648 0 6112 -1 s +17 LW +N +2532 4886 M +2532 5140 L +dp +N +2585 5082 M +2480 5082 L +2480 5082 L +2532 4886 L +C +{} -1.0 -1.0 solidFill +dp +0 LW +N +2532 4886 M +C +<25182117012522161e18260115271919182401251c2c1801222101261b18011f2216141f01252b25261820> 2457 5394 0 6268 -1 s +17 LW +N +4438 3615 M +6015 3615 L +dp +N +4634 3562 M +4634 3668 L +4634 3668 L +4438 3615 L +C +{} -1.0 -1.0 solidFill +dp +0 LW +N +4438 3615 M +C +<261b18012618252601262b23180114211701171825261c2114261c2221> 6090 3666 0 8647 -1 s +17 LW +N +5886 4716 M +6862 4716 L +dp +N +6082 4664 M +6082 4769 L +6082 4769 L +5886 4716 L +C +{} -1.0 -1.0 solidFill +dp +0 LW +N +5886 4716 M +C +<261b18012318241922242014211618> 6937 4767 0 8442 -1 s +17 LW +N +1862 7512 M +1862 8020 L +dp +N +1914 7708 M +1809 7708 L +1809 7708 L +1862 7512 L +C +{} -1.0 -1.0 solidFill +dp +0 LW +N +1862 7512 M +C +<161b14211a181701152b010311> 1787 8291 0 3148 -1 s +17 LW +N +2536 7512 M +2536 7766 L +dp +N +2588 7708 M +2483 7708 L +2483 7708 L +2536 7512 L +C +{} -1.0 -1.0 solidFill +dp +0 LW +N +2536 7512 M +C +<161b14211a181701152b010325> 2457 8020 0 3783 -1 s +17 LW +N +3675 7512 M +3988 7851 L +dp +N +3851 7614 M +3777 7688 L +3777 7688 L +3675 7512 L +C +{} -1.0 -1.0 solidFill +dp +0 LW +N +3675 7512 M +C +<161b14211a181701152b010320> 4067 7936 0 5486 -1 s +17 LW +N +5878 8901 M +7305 8901 L +dp +N +6075 8849 M +6075 8954 L +6075 8954 L +5878 8901 L +C +{} -1.0 -1.0 solidFill +dp +0 LW +N +5878 8901 M +C +<21220126182526011b181417182425> 7455 8952 0 8826 -1 s +17 LW +N +6336 10003 M +7387 10003 L +dp +N +6532 9950 M +6532 10055 L +6532 10055 L +6336 10003 L +C +{} -1.0 -1.0 solidFill +dp +0 LW +N +6336 10003 M +C +<1d27252601251b222901261b1801241825271f26> 7612 10053 0 9350 -1 s +GR +eop +%%PageTrailer +%%PageResources: font Courier +%%+ font Helvetica +%%PageProcessColors: Black +%%PageCustomColors: +%%Page: (25) 25 +%%PageResources: (atend) +%%PageProcessColors: (atend) +%%PageCustomColors: (atend) +%%BeginPageSetup +bop +%Defining font PSOwstdutch +%!FontType1-1.0: PSOwstdutch +10 dict begin +/FontName /PSOwstdutch def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001000 0 0 0.001000 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 1 /C0032 put +dup 2 /C0034 put +dup 3 /C0040 put +dup 4 /C0041 put +dup 5 /C0044 put +dup 6 /C0045 put +dup 7 /C0046 put +dup 8 /C0050 put +dup 9 /C0053 put +dup 10 /C0058 put +dup 11 /C0065 put +dup 12 /C0066 put +dup 13 /C0068 put +dup 14 /C0069 put +dup 15 /C0070 put +dup 16 /C0077 put +dup 17 /C0078 put +dup 18 /C0079 put +dup 19 /C0080 put +dup 20 /C0082 put +dup 21 /C0083 put +dup 22 /C0084 put +dup 23 /C0085 put +dup 24 /C0089 put +dup 25 /C0095 put +dup 26 /C0096 put +dup 27 /C0097 put +dup 28 /C0098 put +dup 29 /C0099 put +dup 30 /C0100 put +dup 31 /C0101 put +dup 32 /C0102 put +dup 33 /C0103 put +dup 34 /C0104 put +dup 35 /C0105 put +dup 36 /C0107 put +dup 37 /C0108 put +dup 38 /C0109 put +dup 39 /C0110 put +dup 40 /C0111 put +dup 41 /C0112 put +dup 42 /C0114 put +dup 43 /C0115 put +dup 44 /C0116 put +dup 45 /C0117 put +dup 46 /C0118 put +dup 47 /C0119 put +dup 48 /C0120 put +dup 49 /C0121 put +dup 50 /C0122 put +readonly def +/FontBBox [-25 -256 920 739] readonly def +currentdict end +currentfile eexec +D9D66F633B846A989B9974B0179FC6CC445BC7C8A959A39A32E9DCE7FAEF17EE3BEC9F +50E1A6FCA651FC4B3769A0A91041557502E25A5D6180FE25A3D11BF079E1DF66E54EE9B7C229AF891739707A2A0EC140306B5E43E52B79BFB89E459E50 +6EC6F610A70775A31C460976C4F79449D86E57ACE491E5C6BF20CC4307B1DAF7630252 +E9AF8CFB69B50EDAE9D36A6104AFEF8832F920FD2346B2C7104CD11E3BEE999CFA9F5A +49DB3173EE48D1C82994237F360407B022E0B4 +502E94EA8B493651EF2D03F0B513D655047568325B512AE6 +6AC6F53F3848CF70DE25481CC65D8B1A5793AA +3C4282D111112BEE28AFCA7A3808D4444C4669CA +84EAAAF989219F51AB3476A1B0B5F2246BC306E6 +625C6679C417ED2A8E9BD010DE37D40265074C2684219633BFD75335C2975FAF42911E36B88625 +11B789B4EA32C03B98F900A4 +67910D503B3F7E49B1 +C357F8AA +288B05E7D61F15EEBE0902AB660F +2FCD056388F103A8C0E6481CF6F380EE9E185C00E47793AC00E782135F9DE46626A4E2CC2FAF36A80BF99B8AD9C40DCEF713276896B093498E3CD3A4D01E85F74FFA4E365F3E4E8DACF26B945730B3888DCF46A9278A13288AC8386D2A16A6772534CA3345BA48 +DCBD92AB +570FA1EAC34A0F83DDBEF33E2B +13994C10A272FA0B061F3EB088FD1D40860B96A870CD249CD2D7B0FD2C0D86D2014603E02402E3CC5B207ADE7BCBE652F82CE09A53560A462F68395F829A2745 +485F4586 +F0AD2A5B1F8C5E571512C29069 +BEA65011A0D30FE7832E8BC0C0418076789BDA1DB8C98A7E9ACA6BCE4FD7DF6CB09520192A6131D0F943734010063E8E394ED1C58B069575C2E28E6CE22A1D +BDE82F3F +0679AFDA41F488ABD4C9C2FE76 +B83BDDB273F197D3382428E3E3B7A41CB2DE8A95B62C074A510B580683C323386E229F9C63D746F820D368837D606E7690DC38FBC1D99252F4 +5659E082 +D0A56AEF3BBE4457DD854398BA +98AFAEC9ADCF08D0E4AF38A1518842D34D868623534EC7 +F0B8E5F8 +87A3ED50905B6BFB93E1E54D62 +049C3E6445768EB8A33110E39E0B6C1A680B75EC04170C63255F22A60387C6 +695D0C8E +98C71C970DF9665B0BD88BA505 +3465DD489DE5D3F38C3ED714EC7BCA725DFB40FB95A8946F3FB6B0B6693E6EAAE77061732D2227F508B97A1A96F16813C11041298219DF35237B2D28596E8A39C61CA18AC70F82311E6466C65F9570375112239842EA77571E87 +28D29AA9 +0C65768CDFB042B850C9349C36 +2FD595A418DC2E226859EE543A84E42B108EA3AB88FEC36EE363F99140893DDABEA879A3C287F3576F8B532FE58B6135030C94D9D2399881EF7F308DC728B62387C70ADC78C323664AC4B480E19CBBB2D94CAF81F1ADC28B9B3475F710B539A29C +15291A0F +6213DBF91B1219A9D422DD7FB5 +C5BC6F1F4CF24DB1E1022A57E829F26BB188035EBA3B90F178A4F5975A0F50FE33C83B03D825C49B1CAB88470E66B8B0BB7EE796CED5 +3506E926 +476C958172153056C4D02D5B14BC +98B19001FE57C0B27A7E4135F9F6D9FAFC6A678AA8457AFD0D8F98391EC5745191C89A0888962B5E87677EC898C920A62014EBA353851327CB1F4846B8FB3EE227BEF00A909D907A11EC34B4A8DFFDD34308566EDBAC20FF0B07045DB5A9525832E4D15078EDF11609CCC80EB8E7798774CD5B +0B987C57 +A7F96263A8367C6382C6A7FFE098 +97138C27DF14F1BE92714CAD3BA0233AFCDA37D1043AD9AA7CF8F507B77E1A2B168FAB3A3534509EB4823CB734047918007044CE4C4349EA6165589DCE0F39E6D0F06FFDD96DB379C8C1374B80B5C4F8A011D87D15975AE8C2038BEC6716B8862F699332EA38FC652E751217BD717EA5AE9A15EA591797D73033EE0C25D1 +5A2D +B5 +73164D15 +2AE6AF88C7AD68E00ABF71A39E +F59C9E97C46322F5615F144ADBCF14AF1E940B476D5CF91038FB40D7D1D1966F20ABACB521F42DF6B3A9AD61FAA3B7478F3DCF10993A9C6A08C74A0EC3906E273BA7B28FB17030AB32527593455711667B9A32492F254F1A769E6F2021BA7CBCD8AFB5 +CB9DDA21 +456DE8AFFEEBA196D22725A1B493 +6A5FC42D6C77BE7FEF79D7A4F8D1DAC4EC3C32921E50CC18562BC8AAC811C67ECB9D124F9C52873DF90523EE5D7CE0712A2698D5A2394036FE83B18F6ACA848B282CF8A836026E1A1BBB5E49C48A5B570F7AC54824B6D669C5B4B4C28C4D8C1E1B19FED9985420352235623AFF918E7588BADC6F895229C2ABE955BD0AB2 +FE6A0D4D +81A8FDDB94EE2D6B50B5912A1A40 +87B40585594B350B3B7A97F062BF0A38D6ED06DC5C71E38ACB6E0468361B3D1D2D5E65A9A641DA6D6B59353F0F99F24751FE5963FE2144D206AFBB542CB155FBD8310C2F06B587D5C4182A620197128535227547D459EDCD34018B511215A2F861353689F4B0F17D2C +23640709 +FACF98469CB903EBCBE4028B00C4 +38969C2E1F15B5A1744CDA69F94872F781B8C745EC8767ACED4B2F121FAE07E71B094A2638EF2D5B2F2BC7DCB92806867719AFA1EE7EDB8F5F30D41C60EB8FD002C479EC0E9ECD68D56B0D6BB4D2CF53AD4B8FA0053EA289A91B3D336C3FCEFC6C4ACA83D934C7CBD3DE1558B4D994 +F5F620B5 +C830437A75EA0B82B49F8C8409 +CD1231C13E9660CADBD7E9F77A31A76783C9B6FAD4934A97B37370590045E9C1FC261BC264D11A1E9CAA837ADAB9AD9C00176744C3E51F961E6E76A6A8EA01ADEDA48688AAA51C831FEF7350F0A4E6F81859CAB72A92AE9BDCB853A8 +6FEAE12D +6C3513884C9513B83B911E2C01 +E031D3025983F526BB3B7909E382011370895A90EC4C5171DFC6F002C69512B9DC2B53BAACEB9402D6B2DB83941DAAA29108E2A44C90F59DEDACF430694F6BE0E7180A025199A5AF3C9C127DD0135454BC1197 +1EBB045F +89F42B4ADB176181E73806017CA6 +40FF1CA7BF2EF1DB6D5FE1C9FAB82AFB7DAF24C00239896FA274D8A61444DF34342DA0CF39F2DD181EB6F47E95207C2E5DA19DC2F68F7D5D0D3A558700694481A21E35704AB66795B00522076BDE91E4D2A846B5AB8A5EBEB86A6B2EF5B17ED9EBF5995A2B7167BCABDD +785DE73A +3E1A42174E74C74B90BBE53AD1E9 +C1EA0ABCA658AD3D06861D99382056F41918D095A64509D358199565846EEFA045C313A4BEA59ED433694E621D7C5B0DC72735B16076488997A69A3B60B64413C932A97492412E7AB9D50EE2900BC88350DA08174D86CDF9BDFDAE82CF4A639C22950B874C5806286D053C9B47BB5FC0870AAF6A2D9DA724BCBFB7F56E75 +72D75C1A +D3B2205D3BBAB75E737F9C2D6860 +81DE6A264179D71157A5501DE8F9A349080E2A4A0E44AA2747993814B749A2385C5D8D76022B2B7ACE9A9BB7967C22916AD6FAEB418238159C531F3CF69D0E2D18AB21D7E5BDF70AC6B5324939D71E4A87BA900AF17B12E983310EC192FBFAA8838D55D869D5FE03D4A02178756669872BB57246C61C25AE9A6B22F36EDF +DECC +4354CC +D3ABC108 +0AD657A933198CE2BA3B1EC026 +9ADC9B695DF7EB46576B3F0A4905C7B3267CAB406572B56074EA17371F8F84378D36397AD0E80E46F7871F0A816A755B70EB6F3FAC93D5720679D7619DD4615BE327996EEEACF85A84766F0CC9FE3C9DF6 +395D7264 +75D10859943FC78C242AF180A3D7 +E8EA917D3C761DA34645B32D11CDDECD2D4F02AEC0864D3F6DA0892D5195B3648F194EF06E8228E5EFFAE9C77CB2B928249F32751B4CF58C363322B25764A52D78E080C09B5C59062B99F4A678183A4135CD5B5A9E831D817CE5DBA19FC12EC82977EE19 +3DB6F319 +DD22D5D3BA4E261FE29840FFB6EE +0B0A7D70307075B9A6512393008E37B2F2855D4DD08101F16CB90C06CCE34DB26D03ED09E676809597C119CDE435F1E1FF2D459FB8B93848F6D91A5A1A01E0099BDACD29CB851C2E8C894550E7003A9FD5A9CAC7918FB9ED096C583B62E85549FE7878FD590E8551C66A1D9D67F09CE54A3200 +EDA95980 +5A3A13867A761FD69D8BC565D2 +CEB7E3B8168BBFC5C486AF2DDFF398978EBA70AB8BF0 +ED746055 +54E9641F0F6515A557CD4F6DD2 +9CFE584CEC7AF15B56F56924A5FA194DC0D0910D161F8852F19AF6A72C0EC980905D2A9CE48196D67A074866151C01FA8B34785E94DFA09D5396 +5CC42935 +2BCCB5A1A19B2E82F98C2E5CA986 +6BEE012420BBCF9D3C293DC93545D533118C5E6879AF92E6C0DCD616746672E8B968BF88E99793164248D4E966650E1224267DA49FFA88983F2860F56DEFB2222A6916491B197078E870C82321D528D7EEF3DB78C655A6933F2763AF09F22C9DDF74350A60AACDF586B1EBC6A93B620026C06A6F1BCD2C7A4831B2E667B2 +2241 +D68813 +6D4D1267 +007CB9B6C79D33E4D9E49663A5 +CA73CA34FEF610B5950EC4F5F4BA3BE22B1E0B6E36C769D294EF76E1574045EAB9B409E34FC17CF4CC27E48611B709FC0B9EBB870BFC6608F9402964256BDFFD0FDFF48BC3EEB29118889309409470712D131262349361A4 +643F5208 +77848C2143E6A3B0525DD496AC +6209BFD5252576BCFCDACFCA6C3CB588D98CD818648366EE1DBA1BD2FB5F6EB0E4EFEAD44B00B8AB6B3CF58814DFECF9A864DF9E4109DF935C3A201F85960A2B3DB50692DB709F8AFD436AC79B1182401EAC +A4EBC547 +2FB3BF81AF55E1CAA85E856A8C34 +BC6B1DFB0CBDA6970F40DB312106D17622DE69556F4D1C75719055D5607FB3E909FD13A46F048989828DB19789F6584778BFE2C7B9FD89E47AA1311032029EE8241E53234376C26D0A9D6E7E12F04F180065A5EFBD42C14DBBA272D511FEDA67F7ADCCD366735DED68C30D175F43 +09AD0D84 +6AD11D5D5EA30B77B2037BAFBC +79F33E07087C5449D26C1AD40216B4DB494892B603B00BA8AA9A3138A0D8E64B980073DF3DCFC7ECA96ECD173FBE4CD4DD02FB5BF96962B311610DFDBBF2B61A1ABC1C521E910BFB28541F84A4A69103F746EB30D26B16D46B +CDC07761 +2646D133C6CE0E49FD88A8C849 +9A8917CA2749C534F4AAF0A21BE542267152F53984DB5830305240134B40DCBEF02F92438E9C09A8A1604C30242189CB19ECF90E85607B47AF244EBDAAC5D8CDDC07BD10B6EE85F07D8481C4956474F1F3E42A6391011F0F0F8A81A2 +91A6BDE2 +5AA83F1228C6995B59BEA72D599A +27C0EED6CD4DE0F71AF2576A3994AA61DF6FDABC153689630BC9E1533EAA2980654458C499101C3E2B2A9E6E4E1BE7981A40B80429EE70D90110DA8420F25C7BA9C9D3F842A5CE5F9894A200E82EC90CF61F873E014973C892CCF969B1C8904CC9170C14D0030AE72A875789C1766312812AE90D84F3DA344187F5B952F1 +6804 +51A33592EE26E65855E6099B28749A9595F00DEC295D3718DF12FF907CECC63CF8F0F6659E6C32C241FD5862F50C1A +A9C57767 +54449938C69E248821F378DA9833 +8CA7B9A3F2293B8701905EB828439CB0E01BEF31C1AAC13FC3BDB4D6775406EF6ABB2CC40F0AE83F681B11B13616E297091BA7C393260522D627D6B373AA2F1B9F7866086B9D5E6D8DBE9B2875F59CBBD7DE4595F9DCB77816E97533F74F10B426B9AC29111FC2C87A785E056D +22458A8A +FFAE708CB998B4BB4D74E464AD +B3D3F07F0DDFC8913D5A6BF43850574DEAF9DDDCFE591CCFE0820A942486FCD21CF7385E3AE55F80C1A0BCED72B60DE23F57BD73C0F1DF0DE6DBDF61BCFA75FA1C35BF5937272755A67385C07F0D3842 +9A85383B +395CC0F0D564722DA400548D553D +4A6EDB246A613951D41B7C26FFC681507171E3EE6880EBDA422949579046FC728C4730C183E70BABD04B18AE52ABB2D2F8E124F28CF63BCE41FAB81C4E5EE963E911B8293E57E0643924823724814A5C65C78E0789DE562385CE03AC8157B92AB66110692A6E1804BE9319E9900559A741519ED3ED8DB15FEA43B3A2BA92 +23A2 +0307A4BFC3D6FC056B52C7E48238D99D08A3A6E59D7A4EA2A1A7AC6E9ECDCE7AF4E4E9 +5BE20EE0 +A7B3265081E21B3F5E80E23A8F +5206C8177382EA8AE1CA57D3F6C477607DEFCF5E6052C86B547CD8C7BFD773A87845A5D715450EF32CC0FF4B0C22966FCDDC12705C60 +245C8780 +2FEFAB9A9448E833DBDEB0652C35 +B5C82BB07E6A8238BAE4579370A3CC10A449F955AB80F93E71C169072CB504DF0AC35EAAD90212ACFF77F2DA1B95FF7581F19ADC78CF907F4E3F6B92C3A1AF466A557608D216C98692ED35A19DB835306AF32726D75EF25C56070D1BB55DC0FF0CBA94144AC7D6D181434CB3F08A2DF326B2876B77F96FFEA887BE5BACC9 +4139 +2C70AED672A1BFAD0006939289F181BF7D597C3E1B50C58CC31CAF924950D1 +4F3D31A4 +19C96A5DB3698398FD475DD8C926 +95818BA49EBCD473BFBF7DE8BA96219ABF12FAEB314EDAEE7C44C3CBD6F828D9FF7E0552BF093F49088D52FB6202849D55700A1ACC58AB7022AA012C8159E20CA02A6691F9109E7E1B451AA5A9F195B862686D4F4D7DA4BAA00328A16C66DAF5925456CAAB3D1F19B9FE33A5 +A144C9EA +4B8CEFBB7DAF8A167AE939BD9F +4A12191BB5E3625429478538D2D556784AABD96C2533C23198C553CDBBB81A14FB9E5A2C88202C02B4A1A9E0D3B261FEA65EC6EC11AFD2F07AAC567FA2B4C461193BDCC30300 +CCEEA92D +72B740B366626B3EF4616DA61B84 +D00CBC9F30B43EDB6EC95A5EA74973C33CCFCC79BC0DD9BDA4E1E6BCEEB1F441C508DAB5D2418C04AC36D3A93EF41990C7E1090651E479C978D9F51EB7F1A726FC1AC8A671FFFF508A52959C78E3F8B94E26BA1A8AE18CD846B5B95548E34658E998C69AA5B97BC6BF7A00A03EE25ED3F4C427EA5A3E16 +F40806AB +D6EB0155C581AEC83650462AC1 +FB753A41723B6EE926EB1F3998121E9BBAA706B5E93494911DF33201525FCBE0E0EA0056F34B4833F5722F767C51292A97CFE29C831D4288DCF58451AA8493E7302A35FE4965C7AE700729CD14F401DA182D22358BDA8E +9A5B8667 +D2A25E8E11783407EB32DC86FE53 +5B622BE2DCE47FD3E766DF890956F4FB470FE053E9885E0A000475D55C7722BF4555DA8564A0506AF8252DF999A8235EBF182BA0C7838E67CE6C56466B7EC53081823C15FD1E45492B75103E0F5F5C47109826E249117E523EC8D2ED9F8B50023877F11B04262968589CBFF636B6DAE1A00E636620E20B6C70D336B9 +3D014C5C +E76E4DEC40F0AE7D38A1E8AB45 +FFE334538423A2FE603F0C19A61F58B9ED8405385F6FDA8CD3D9D97042703BD46FA4EE439E8BD262A8EB78D67171D36A37CEFBBCCFEA6448157BDE5040D09CDEDB55B38EEF +0EBEC440 +08B959C198D3337342A2527C9F +05D84934DA7818D9E5892162A62F99C3E969D47403643CD8553F60F9970577F6AF67686D4B83DBCDA098A836F419A8669F1AC04EEA1F4A62769EB7074578ADD73773FC61B261F55316670495AE319B6E66CC93F8070AC80AAB7FE863631DDB4BA598 +8F1369AD +880A8367D38B8A41B0229E49B5 +D231FE5E5869A0EB5A5FCECF63CA69963F7FFBB135F96EF2089A107838DC706E5E488DC445C8C46BD6CCAA321FAE73E81FC52D489B6227B988877BF192BA294673648C6846DF58E95EF0D1407F7A03ACD4D715C43AEC1F9720 +98218223 +FF690B08701A6F5A2AFBFC861589 +2C4304681DCD8476B5140B6B4C49DC7DF167D688BF505BD55DD0A18A091AB092BABC98F525335A5A1DB90EEF03E6FE2C64B4D36BCC1AE6C81785AE3224C74D88E29B8D4BCA4397EB5B838E673BDB4DF0E755AB4FB7E48167D66F3068BAA7885910BB9397805A2AC2A6554629C7A5A84E17EDDE8D9A7DD21041F8ABE7EFFA +60F6 +C7AEA543FF828777260B5458FD73 +5FDA83A0 +A00BEF879510568CA2718F803BA0 +6826F2D73CCEDA351B37D7F5E75107FC6182DAF9489B829152B3FC18969944E57C18BEC29BF680138F9817839FAED7BDC818F8DA52A8C5B44B427FFF624F5BF08EBAD15871FFD7F045BD02D0DD9D2D8137C322B5504975D2C7BAE176B302E45CFF6BF32A738698923DE4AB4891E39157764FFA29F10F1E84AFCFAB89E240 +BE9A +FF8F6A25284F03B80B92A4E23CFA6A65F25838D61318C2077C +AD1FDB65 +6919CF3483609C4C717B67A58DE4 +AB7B8519BEE03A01DFEEAA3FDA360898D820C0CE306FEB3CD549FDAB3A2804B86C9FA7504C4BACDCFA00725E7CB05D5683EB21A77BC05945C264E972B148494E9D93D989BE438C5689D503E01835A0E36D0B58DD50ED8ED6F3CB512E09727C0E3E5C97929D8022D5DF0B422A5468053A9CD25A472A214DF9BE16D21C1ED9 +537B +8F80F41F +2D6CB6E618ABCC21C518ECD565 +2B7FA2CEB10FC110463D88D6719ED428192A3BD951041F70B04DCC1FAB5E5F92B9354F6875CD719EEBFEF7EE89F6B60FF9AA05852CDE234D831B2C0B0BA170 +7EFD84CC +B35DCA52FF8440DEF2F3185C146C +3B2548A3815A4325 +9203AB93 +B1FD4E9AF17EA3827E8AF12B0C5A2EFEAD04A40859BEB90195FD7DDAF3E82D59078A +3AF8A963314CB015C226788C0FAA7AD0D1C863A3E39AFA65293A8DB68231DC184B01FD4A7227 +25606377F1B31955B476F75EFB9945F8F2724EB1C4167B13E4C748 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +%Defining font PSOsymclas +%!FontType1-1.0: PSOsymclas +10 dict begin +/FontName /PSOsymclas def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001000 0 0 0.001000 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 1 /C0069 put +readonly def +/FontBBox [106 45 775 713] readonly def +currentdict end +currentfile eexec +D9D66F633B846A989B9974B0179FC6CC445BC7C8A959A39A32E9DCE7FAEF17EE3BEC9F +50E1A6FCA651FC4B3769A0A91041557502E25A5D6180FE25A3D11BF079E1DF66E54EE9B7C229AF891739707A2A0EC140306B5E43E52B79BFB89E459E50 +6EC6F610A70775A31C460976C4F79449D86E57ACE491E5C6BF20CC4307B1DAF7630252 +E9AF8CFB69B50EDAE9D36A6104AFEF8832F920FD2346B2C7104CD11E3BEE999CFA9F5A +49DB3173EE48D1C82994237F360407B022E0B4 +502E94EA8B493651EF2D03F0B513D655047568325B512AE6 +6AC6F53F3848CF70DE25481CC65D8B1A5793AA +3C4282D111112BEE28AFCA7A3808D4444C4669CA +84EAAAF989219F51AB3476A1B0B5F2246BC306E6 +625C6679C417ED2A8E9BD010DE37D40265074C2684268F16195489648993B9C4D3B534FA887C +DEF605FA87B991F4D20A8F78DACE +5A54C070E03D5C59D9D2D3E06B09CEE028D68B62AB3AEC43C1DD20BA70D288597D9BD8E06818FF764EBAB436723988E8D7CA59E16D39032516BFC5D552ACDEEC6BE938BEF2F43CFFBC811C3626C4DF5F8CF080676520B51C60CEDAD1FE6C92D1431C702174CE517A8FA9377D075A0B6833DAB101DB65397F1419EF5F0016 +004F +6F0824F9657BB4F1C8F981709956865F6855EFAE +9242AD55 +91BBBEE163D844DDA894E13190C9 +2480439E4C71CADA +BD043A9B +A315CAF72652AA7FE6DB2E84D82A6111CE4DE90C02DA0AFFE2620922262A45AB4ED0 +EEC9F4520DD12703442F7D028D4526BD8B771E09FBE11B2749E2D3906894E8D4BFD3F379F14C +3C874F550606965E22FE487B247B5C2D06728490C8F2A3B588CDFC +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +/DPIx 1270 def /DPIy 1270 def +72 DPIx div 72 DPIy div neg scale +0 -13970 translate +1.00 1.00 scale +/wst:dutch12 12.00 /PSOwstdutch newFont def +/wst:dutch10 10.00 /PSOwstdutch newFont def +%%IncludeResource: font Courier +/wst:courps10 10.00 /Courier /wst:courps ILEncoding 0 declareNFont def +/wst:dutch14 14.00 /PSOwstdutch newFont def +%%IncludeResource: font Helvetica +/wst:helvps10 10.00 /Helvetica /wst:helvps ILEncoding 0 declareNFont def +/sym:clas10 10.00 /PSOsymclas newFont def +%%EndPageSetup +GS +0 13978 10801 13978 10801 0 0 0 clp +wst:dutch14 SF +0.00 0.00 0.00 1.00 setcmykcolor +<111f2c291f2a200a010b010c1f271d22261b2a240120282a01101f1b2b2d2a23272101111f2c2f282a240113> 2207 558 0 7384 -1 s +<1f2a20282a261b271d1f> 7375 558 0 8593 -1 s +wst:dutch10 SF +<0809> 9346 13385 0 9522 -1 s +wst:helvps10 SF +<4e6574706572663a> 1322 13267 0 1949 -1 s +<205265766973696f6e20322e313b20436f7079726967687420> 1949 13267 4 3868 32 s +sym:clas10 SF +<01> 3868 13267 0 4019 -1 s +wst:helvps10 SF +<2031393933b131393935204865776c657474b15061636b61726420436f6d70616e79> 4019 13267 3 7133 32 s +wst:dutch12 SF +<1622232b> 1271 1431 0 1665 -1 s +<00271f302c002b1f2c002820001f301b2629251f2b00232b002c1b241f2700202a2826002b28261f00170d13191516140e0b10002c1f2b2c2b070018> 1665 1431 11 7584 0 s +<282d002b22282d251e0027282c231d1f002a2321222c> 7558 1431 3 9531 0 s +<1b2f1b31> 1271 1676 0 1719 -1 s +<002c221b2c002c221f00282d2c292d2c0020282a261b2c00232b002b252321222c2531001e2320201f2a1f272c001b2b002c221f2a1f001d1b27001c1f00170d13002b1f271e2b002c221b2c001a1a201b232502> 1719 1676 15 8803 0 s +<002f232c22282d2c> 8803 1676 1 9531 0 s +<2c221f2a1f> 1271 1921 0 1747 -1 s +<001c1f232721001b001d2827271f1d2c2328270025282b2b07000b252b2805002b23271d1f001f2e1f2a3100170d13001e1b2c1b212a1b26002b1f272c00232b0027282c001b252f1b312b001a1a2b1f272c0200282a> 1747 1921 15 9531 0 s +<2a1f1d1f232e1f1e05> 1271 2166 0 2083 -1 s +<002c221f2a1f001b2a1f0026282a1f002b2c1b2c232b2c231d2b001e232b29251b311f1e00060028271f002523271f0020282a0025281d1b25002b2c1b2c232b2c231d2b001b271e001b> 2083 2166 13 8188 0 s +<002b1f1d28271e002523271f0020282a> 8188 2166 3 9531 0 s +<2a1f26282c1f> 1271 2411 0 1921 -1 s +<002b2c1b2c232b2c231d2b07> 1921 2411 1 2791 0 s +GR +GS +1263 10577 9522 10577 9522 2538 1263 2538 clp +wst:courps10 SF +0.00 0.00 0.00 1.00 setcmykcolor +<24> 1449 2672 0 1555 -1 s +<202e2f6e65747065726620b174205544505f53545245414d> 1555 2672 3 4099 32 s +<55445020554e49444952454354494f4e414c2053454e44205445535420746f206c6f63616c686f7374> 1449 2848 5 5795 32 s +<536f636b657420204d6573736167652020456c61707365642020202020204d65737361676573> 1449 3024 10 5477 32 s +<53697a652020202053697a65202020202054696d652020202020202020204f6b6179204572726f72732020205468726f756768707574> 1449 3199 22 7173 32 s +<627974657320202062797465732020202073656373202020202020202020202020232020202020202320202031305e36626974732f736563> 1449 3375 28 7385 32 s +<2020393231362020202039323136202020392e3939202020202020202031303530302020202020203020202020202037372e3437> 1449 3727 29 6961 32 s +<2020393336302020202020202020202020392e3939202020202020202031303331342020202020202020202020202037362e3130> 1449 3903 34 6961 32 s +<24202e2f6e65747065726620b174205544505f53545245414d20b166204b> 1449 5701 5 4629 32 s +<55445020554e49444952454354494f4e414c2053454e44205445535420746f206c6f63616c686f7374> 1449 5877 5 5795 32 s +<536f636b657420204d6573736167652020456c61707365642020202020204d65737361676573> 1449 6053 10 5477 32 s +<53697a652020202053697a65202020202054696d652020202020202020204f6b6179204572726f72732020205468726f756768707574> 1449 6229 22 7173 32 s +<62797465732020206279746573202020207365637320202020202020202020202023202020202020232020204b42797465732f736563> 1449 6404 28 7173 32 s +<202039323136202020203932313620202031302e30302020202020202020393832322020202020203020202020383833392e3036> 1449 6756 27 6961 32 s +<202039333630202020202020202020202031302e30302020202020202020393533342020202020202020202020383537392e3838> 1449 6932 32 6961 32 s +<24202e2f6e65747065726620b174205544505f53545245414d20b148206870696e64696f20b1b120b16d2031343732> 1449 8554 8 6431 32 s +<55445020554e49444952454354494f4e414c2053454e44205445535420746f206870696e64696f> 1449 8730 5 5583 32 s +<536f636b657420204d6573736167652020456c61707365642020202020204d65737361676573> 1449 8906 10 5477 32 s +<53697a652020202053697a65202020202054696d652020202020202020204f6b6179204572726f72732020205468726f756768707574> 1449 9082 22 7173 32 s +<627974657320202062797465732020202073656373202020202020202020202020232020202020202320202031305e36626974732f736563> 1449 9258 28 7385 32 s +<202039323136202020203134373220202031302e30302020202020202020373633342020343535323520202020202020382e3939> 1449 9609 26 6961 32 s +<202039333630202020202020202020202031302e30302020202020202020373537322020202020202020202020202020382e3932> 1449 9785 35 6961 32 s +17 LW +N +6142 2817 M +7719 2817 L +dp +N +6338 2764 M +6338 2870 L +6338 2870 L +6142 2817 L +C +{} -1.0 -1.0 solidFill +dp +0 LW +N +6142 2817 M +C +wst:dutch12 SF +<2c1f2b2c012c31291f011b271e011e1f2b2c> 7794 2868 0 9370 -1 s +17 LW +N +2750 3857 M +3135 4308 L +dp +N +2926 3959 M +2851 4033 L +2851 4033 L +2750 3857 L +C +{} -1.0 -1.0 solidFill +dp +0 LW +N +2750 3857 M +C +<261f2b2b1b211f012b23321f> 2729 4562 0 3872 -1 s +17 LW +N +6439 5324 M +7260 5324 L +dp +N +6635 5272 M +6635 5377 L +6635 5377 L +6439 5324 L +C +{} -1.0 -1.0 solidFill +dp +0 LW +N +6439 5324 M +C +<2b1f271e01291f2a20282a261b271d1f> 7710 4393 0 9343 -1 s +17 LW +N +5209 3654 M +5676 4138 L +dp +N +5385 3755 M +5310 3830 L +5310 3830 L +5209 3654 L +C +{} -1.0 -1.0 solidFill +dp +0 LW +N +5209 3654 M +C +<2b2d1d1d1f2b2b202d25011d1b25252b012c28012b1f271e> 5442 4359 0 7493 -1 s +17 LW +N +7201 3715 M +7669 4200 L +dp +N +7377 3817 M +7303 3891 L +7303 3891 L +7201 3715 L +C +{} -1.0 -1.0 solidFill +dp +0 LW +N +7201 3715 M +C +17 LW +N +1864 7104 M +1864 7612 L +dp +N +1917 7300 M +1812 7300 L +1812 7300 L +1864 7104 L +C +{} -1.0 -1.0 solidFill +dp +0 LW +N +1864 7104 M +C +<2a1f1d1f232e1f012b281d241f2c012b23321f012827012a1f26282c1f> 1796 7866 0 4443 -1 s +17 LW +N +5592 9730 M +5592 10238 L +dp +N +5644 9926 M +5539 9926 L +5539 9926 L +5592 9730 L +C +{} -1.0 -1.0 solidFill +dp +0 LW +N +5592 9730 M +C +<201b23251f1e012b1f271e011d1b25252b01030e11120c170f1504> 5523 10492 0 8218 -1 s +17 LW +N +7174 6883 M +8065 6883 L +dp +N +7370 6831 M +7370 6936 L +7370 6936 L +7174 6883 L +C +{} -1.0 -1.0 solidFill +dp +0 LW +N +7174 6883 M +C +<2a1f1d1f232e1f01291f2a20> 8133 6934 0 9201 -1 s +17 LW +N +4999 7009 M +5253 7273 L +dp +N +5175 7110 M +5101 7185 L +5101 7185 L +4999 7009 L +C +{} -1.0 -1.0 solidFill +dp +0 LW +N +4999 7009 M +C +<2b2d1d1d1f2b2b202d25011d1b25252b012c28012a1f1d2e> 5253 7527 0 7261 -1 s +GR +eop +%%PageTrailer +%%PageResources: font Courier +%%+ font Helvetica +%%PageProcessColors: Black +%%PageCustomColors: +%%Page: (26) 26 +%%PageResources: (atend) +%%PageProcessColors: (atend) +%%PageCustomColors: (atend) +%%BeginPageSetup +bop +%Defining font PSOwstdutch +%!FontType1-1.0: PSOwstdutch +10 dict begin +/FontName /PSOwstdutch def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001000 0 0 0.001000 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 1 /C0032 put +dup 2 /C0042 put +dup 3 /C0044 put +dup 4 /C0045 put +dup 5 /C0046 put +dup 6 /C0048 put +dup 7 /C0049 put +dup 8 /C0050 put +dup 9 /C0052 put +dup 10 /C0053 put +dup 11 /C0054 put +dup 12 /C0058 put +dup 13 /C0065 put +dup 14 /C0066 put +dup 15 /C0068 put +dup 16 /C0069 put +dup 17 /C0077 put +dup 18 /C0078 put +dup 19 /C0080 put +dup 20 /C0082 put +dup 21 /C0083 put +dup 22 /C0084 put +dup 23 /C0085 put +dup 24 /C0095 put +dup 25 /C0097 put +dup 26 /C0098 put +dup 27 /C0099 put +dup 28 /C0100 put +dup 29 /C0101 put +dup 30 /C0102 put +dup 31 /C0103 put +dup 32 /C0104 put +dup 33 /C0105 put +dup 34 /C0107 put +dup 35 /C0108 put +dup 36 /C0109 put +dup 37 /C0110 put +dup 38 /C0111 put +dup 39 /C0112 put +dup 40 /C0113 put +dup 41 /C0114 put +dup 42 /C0115 put +dup 43 /C0116 put +dup 44 /C0117 put +dup 45 /C0118 put +dup 46 /C0119 put +dup 47 /C0120 put +dup 48 /C0121 put +dup 49 /C0122 put +dup 50 /C0262 put +readonly def +/FontBBox [-25 -238 920 722] readonly def +currentdict end +currentfile eexec +D9D66F633B846A989B9974B0179FC6CC445BC7C8A959A39A32E9DCE7FAEF17EE3BEC9F +50E1A6FCA651FC4B3769A0A91041557502E25A5D6180FE25A3D11BF079E1DF66E54EE9B7C229AF891739707A2A0EC140306B5E43E52B79BFB89E459E50 +6EC6F610A70775A31C460976C4F79449D86E57ACE491E5C6BF20CC4307B1DAF7630252 +E9AF8CFB69B50EDAE9D36A6104AFEF8832F920FD2346B2C7104CD11E3BEE999CFA9F5A +49DB3173EE48D1C82994237F360407B022E0B4 +502E94EA8B493651EF2D03F0B513D655047568325B512AE6 +6AC6F53F3848CF70DE25481CC65D8B1A5793AA +3C4282D111112BEE28AFCA7A3808D4444C4669CA +84EAAAF989219F51AB3476A1B0B5F2246BC306E6 +625C6679C417ED2A8E9BD010DE37D40265074C2684219633BFD75335C2975FAF42911E36B88625 +11B789B4EA32C03B98F900A4 +67910D503B3F7E49B1 +C357F8AA +288B05E7D111C7F4CD7B15B1A449 +1290BFA0B8B7328DC5967954B83363C540B8FEE73653528D8AD5F9D471555383869FA9A995DDC29A03BDB2D160D21B0B2C285BE5C279010060370FCAD92162D8E20734DDBDB49EEE2EAD3452E65D820A8F1264C52710D6358DFABEB7CD20D6EBCC532CEF4073C336D2ABE51E0A97D89B7BE6B841427FDEA5E26FDE327D1D +024C +E5F912E7786A78AC5FFF93FBD021698604C9242154CF257CC5686485884D185CBC47DA8600BFD20AFAF18077374850A97F7267D244E9325932C56895BD2077 +CE2CD6E4 +727616DCB5FB3823901B1A3BDA +D73A5E976C926279FEA2CEB27ECAD483926DE35490114E50517A81EE4DA5E264AD19192CC41A747D7C76FA67AE1F46B92C43C138E20ACFF5E2 +D45DC758 +195B113F0588D314D0A36B6B58 +8ED0ED383AEE745C837B21314B7658A83991E27D4151D9 +82570B62 +869A01455756716E2D1DA84FC4 +0DFB8532D1454BA2002467FE3226D2C85A317B431C35540DB192F596B731DB +0716B13D +D51BAC7FFDB1B7585EE08E8641 +C30244BCE05DF2E1037A771748E313DB53D7DB056B2C9CF916C7D5260AB6D76F17F802F6439ACE3B4B0A2B0B7125B906D0A2196248C350CEF5D491B082966C562787EF55428AE5A7A761 +682A4038 +50D1DB036045A1D5CC3FD626CC +47D247CCBF1B8D49E9FFE203FCE5A416575D3D7952A09222FC589543DEEF14A6B7596B29D1D86C65D6EC90A4BD344438E3338F5D39B5F0759122390DC7A09E +5D0CC053 +CB9B128E899B088FB2835E97EB +66928F4548079559F5241598E410C7E2A9883923CBC56A403C7F344C30CDA339AF15B621DCB0EF0EF9D270C95D9ECEB0F01118BE99E0BDE4749316E69E12E4F1222345087A02568D76C49DBC199AC1E17015F6AF3FCD6537E191 +AFDF07DE +37BBF24D3BE2E1225A2D2DB7F7 +BD8C205682EC872D510EC70CEE76CD9EE624BBE19F1C651AABA282E58059B6F7E7E9D2266EFDCF4DC0B4FFF31E4ACCC7D6780B8D03B088FBC1D4 +7AA08D1D +27372B6D75A2DD4D1BEB6A3E1B +F76F90C66BF0D3DFD5D5F0E3CAB977482B7A44B72ADD19E028C2616D17B8922C93F669DEC7A7E576FBD1A1C520BF3C03173282D2BA37B650D0514E553665472185F9A77727B3B0600F6794284581D9765FA84716F5779016564A394262823B1294 +DF8CA879 +2F15EB66F00D3BB77D0B800320CE +9D1388EBB0A0DE5AC48C706706EB8C0F33A2ECF32D59AED5725BE5524E6FDE37D51559192F456FAA1FB8433D2F2C6A8B17E856A9B7204A3E571CA10472F6A44BBD2447B987F7835F8ACA4597FD65C66A548F29C7EBD26BE5D3922870378F9175D087E501 +294450A6 +39D5B97905D9AAA3802141083A +67AE20012C6FC543F543EEF50136C7FD0A118C69331EA21495D314CFE3AF854463CBDAAEB2561B98279CFC73588FF4C6481D4EF8FE75 +11BC38E9 +5F656DDC77C89DE21E74DDFEF1E4 +7302C690D56416277B4518DB9395275E97CC7586B71B74314360C0F9C8CD48BF9C9F8E5DB070D56DDFE019CD45100BB489935D04AE9DE34803BFF933C826FD6736309439043A3B5B3BAA37DC9C151E3E22A7BC46A32AB6816FC1BB7D31C7D72AACD3A9F4568D836912094DD7998700DB4EDC52 +F759826D +482D22FDABCD710C66C6343E2368 +69175728B7B6D7B3595E13B98BC449538B2CCC8B7157CF35F6F51CF23569930E741D17B8F07B81EA92058916129F4297087D43961D9B1AEB9248BB1B5FC02BE75E448536E9D74B3E13EA1CF6A97B311DA2C872516D5C74559E6E67E26477458D7B4C519F5C05E128D90B10FB8DD2D7AAC8779A6686CFADE0EF2EBA0F4E2E +D0F0 +CE +EAE21B36 +6EC03DFE8D7800489D630F9C4A +607450E88D54F30065A1DF717F082E2BA49E4D95C3626ED95C2BD203A582FBADB744BA3FAE1CEBA6382730085D7EB54F758E91F7FCBA024A4830CC2F999A54B994BE15F900D75550D7A9F5CFCCC2DC38B6CD1C3A2F86CE44E85181EDDBB88A2AD11105 +C28CA28A +F6BEBF3D4F786F5EEBF240E43A7E +A1495801981280C4E1267E856DF114A6F8145C1EDA76BC37B73AED6BD002B3DCAC8D55B4AC90ABCC5EF4125E4BB758900FA1E046D7D40B6835C34255ED7D376DD7098FB01DE9A5F8AC58797BEEAD5EACBA97BE3F06F8684763D70D52A924622B169F7FF590C0747C4FC0EAE95F810DD9E7CCA8BEFECF0BCC4147D841AF81 +70851B4B +D08833B7A5E7CD0E5B75502CBDEB +3982F8578A3321E1786CE99BFEB06F453431D85273FCF0CF7954CC4A500B81EB04674BEB6049F60308CA51A9C5AE751C59CDC0DB123A28F07B5E8A316F4CFC773581AC9C9F76DD66ED1EB021CB95C48E583D6217FCCE115CD1CFD5C8BBE37BD9725A521FCAEAAA9FEE41DC96663749 +E2145B81 +A0D24A6D860A81F9F78E13E483 +D3EB22637CE5023582F9EBA2343D4240E0B933F47B44C76F1D09CCCD4E2FEC6BAB58DC37CA29EF37CA8E4543D1B1BE344A7530FBAF051BB0B27679E21DD23014F69CD8BE7B0D9B83360F2F5FECB8D3C95C6C9D452EDCEA3CAD0D5697 +7F0454DB +47FF6BA87C454E69CDF98508290E +2C6D80A601AB2818191C1033EC7ED0B7F820AC4817EDA9B8B0ABFBD4624711CBE33637C677E8DB12167ECE7D6D2FD9482623E51787AFF3F5DCBC2B57982C8523BC5A94A2E346EF4526D11B6457D4CF89C85407393DED5FFE2A7ADF7FFA7A2FB63B5B4B24EE83FE0CF4E0 +9AB4D733 +4D04E9F3D93B0080ADF129C7D109 +D80B8B7202BD7E8D4ADAC5A618EF47B3179F40EC88E591E945DBC51A5AD6B87E774A7224944D22452A5FC93D1C443B0EB3A9C4049BE52F1ABB6FEFE334BFA6E3FDE42C985578B032419817D77524DA0C2F2F852DD77421131436374D140627C92CD16D9AEC494ACBF037067125B678F86F17FB2D7F04BD1DB6BAAF3CB2EB +0C1312EB +EF635BEA7DCFE5D709D5115ADF2D +E08AF7B3AF4BD66EB6192879A8781E8C8F355970419FBC4715A4C0F4F9E6F29696D3BDB480E19990ED9ACFA8F3F3E0D4FF9D32B4F1866DCC0E49E88D76A4EBDF3A5389948E640EAF5C097675FCC798FBBF523A210B34B6DCB493C27FF4E4122EE6970E54547AA665E6C53AFED4E20A2C60DD6015FA36074CFBD9938E9284 +617B +CB4640 +65CE96D7 +6965CA2EBDBC9FE506B7FB07FD +785518D605144E1BE93893C604CF2C6683E1CD59E7A810E64C07535F6639167BF5CDB8215FFE89C7C53C8A30F4CB0CEAEC875A0018528A3692DBFD11A5F3A9A5BE2043103AE58A42681A410A1F30C3893B +620FDC21 +94496307D90DA788054B2679399D +EAA3C4BCB302291F849E9594F81D023B5FD814586CA6ABD2C8272CAB00BF9541ECE42D17158479871DD94A599C720A97FCEE2B778A83DEB55F1581C73BD4DAEBDE526632C1DA494FB4932B8595CEB4DE2752C6803D5F84B23A96D0F9886DB7DF62275CAF +6583BB6A +7E9A5E6FB33515F82634253C04 +FCEE9CB2B36FA783AA49156B39ECF2C4FC7BF775EB93 +B0C04A48 +35812427096020B53CD773E578CE +394EFFA17D9DDBC89189043727465863A6E29918C9F55695984F4C594CB41072D644D43F2DA9836DB9DE1284DBEADABA4D564ACA19C5B3C430499CEBC9291A7CB51E0B832E7FB02CED012FD6E96C61AAE749988311EEE4300EF58450B3C1C98B040D220273170240D8FF8457CF6DEB52A0C44501D4677C4A1B384E76A2BF +4EAE +C0A4B5 +7C298745 +46206CBC12CFCFE329D2D1E8ED +86030B6F8F93976A5B033DF4007CA0871A597F29CAB207981C570404FA18FD09E345F558127D87EA7ADD3F4D677ED0648DF786FDEBE42A07D392603499766DE44C8E9375A840B268185D3BD2CDBD4C1A49D1C30C3E0C8F62 +0A849BDB +8BA11AD2BAFC67F6377933FDFB +4E9E1B6D43F5674B103E0B0CE76A606363BF0AB355A7EF09748266C6A219F968CFEC2A6DE5ABD75D389DCDFDB8AB7F13B2A56A9ED8BBD3D1CBF49D2419117C2BFC37B1619193B64596A14935FC2AAFD6FFE9 +A95FF311 +AC792316B4966446141071A3F8A9 +D704FDFC04C40BC91105AB7653BA7F2E927F0D74B3C98238D496810ACFF6ACA3AFBDA53DEECD6A2A57E3F7DFB43EBFFA84F537F0B5589003C0CFF130DEBE4576D265F78E8AACC5AA9AADB36430EA0BCE01E005AEF657DE9DCDECA6C79C1EA7F7B033C43045FB343173C58A0B5B1D +2810C018 +3B283F7B0D1748777EC04F8876 +134E5B5DE699F46D6358FD135CB8CFB41AD87B6377C7D487D54366A09D59A136008951701D115CFD4CCA2A397A84E96F30745ADA79A630B498E3800904329241AE634545BD54B67CFE26A925EE6CD40F2D4E22FBA790415565 +75CFD2E6 +7275955157B9F1A5E73B34DF5E +BB3885DDF6945A77758B2F4B1C99B1C27E5CEFA7A35696D175DEB9EAFBC40B5E573DA8427F72F8B4936871DF0AF417AE5EE29CA1DE9FF092112AB6A44457A926088BAB4E7619357E882AB153C87B29D4FF8403E9F4B502B8D17B174D +5197FD5E +9BEA76A2A4741990B179945BCA6A +71E4329D23BCA9F2D0EB64ECFD66A0C35C5FA7741D4A82D0392DFD007387869BA2DF8161B6864DD167EB14609D143A6F4397A4038A9408DFB115910964F0E4653460E9271204D85C1BD686C5A07B18E292F21F56690C4988454AA948B5003C73DF1C7FD7C32A2727FB5BB5F9D1E16F1276B47FD04AA3E593F7E5B2691131 +0F19 +A134EF039625612C52B212516EBA40B41F2616B7FCAABB37E48E25351D152FCB509F9AC5EB1CB004555AF9383E7C91 +2C6D3FF5 +70CE9D7CE1CEC06235AA6E9F04D1 +6AF1561246549A7E934AB9A2D7363D38EEA77696FB72D48304E7CC6FB98A5424FDA89628555CA391C38040A207FF6A115E8B9AC144D09866D0292A66D3C770DE9098006FCA3D3D14980E793889B2C4629508C217CFF74BF299199793AD9A34A12972AACBFC6799884F17CFD3DA +79E5F6EF +8FB15973093F4AF5AE21E97643 +C5FF3296691D7FEA119D38B1277CA7C3D75762C3F50302D6EFEF377F411B29B2D788CAADD1EC54A860B22E8A61CA6ECF2E45364B8B190170A9062D1983229C270EAC269181FFA28E0A00C4DDB162136D +9AC8A449 +0DC77855CD4E370660279537AC98 +E1666C769D82F239D08FC8516D6E8512BE1ECAF17C257213E446EFD60ABD8C483A70B210BF2E0779E9B171B79CC31FE5AE4204113416B7F0A917066E8FAD7B35CCC389D44D99E1C7BE5595CC97D5B197AAEF14968292409582AA1F315A9B4B05F0345DB5F0969D3EB0D799C85DC73D34B704F8BB671CE9A0DC50B62D6DEB +9EC7 +7AD853C14E767AF01F0A273656137FAAF2BB66A76B33FBA92E4A018255FA576F969036 +50042EAC +68A672A57FF7EFB7876ED15BCF +2FBA48D1C73A3FCFE884032C9054D551771202B09ECD59A712C7A434A112FB4D4AB47F4A8DFB94F60B00EC351D94D7B0058E8982E855 +99D3759A +BCE76689695A3340E1AF5AA12FDE +3B3BF525DA27E2A9B0CC17A48AEDE99955C8D3AE8663C7033C40CC48C37F92321EA6C5DE951F076034A2B2445D3A81311C5A344567AA8637B2A56EC6D23DCB9BE4CBCC0D98C820274D36C7C7681A73A4CB71EA04C16249A6B4F670B9B836BF9CE502F7CFE91BF21BB48E715F7AE8632DC0C59D9857D686D0092C40ABFAE0 +384F +CE15A245D1B0626604B6D8C40038734FD51FD402B9A371D7666585E1721B93 +E21DEEF2 +B447D308FA9E049A48D8A80DC8A9 +A5AB7918510FBBAF5783B7334E374C669F07F697EF1407CB435FA5CF44E2D2E50E246F66ED536188AF819856327133EB4043AFAF200514B7A3897917E40BAB5F609A1765D07667349B3AEAE5F4C9D95D603F9180EA44924B025D43F3A6079BCD554F36B4A6B8BD0AC39D0EA2 +825475B2 +2DFFB99CFF572AB823BE03212A +80871108996353E9C323C67C266B90422FA5A9AFD5326E91CDFAEEE6E922FCE376A2D0DA7443355776F3922857AA0F1E8F16AB07831364909725D7A9120711607A96ABEF4D57 +CDE48C9B +F0DEF238CFC288819679C35DE27F +2042678B99EFA2C7CAAA349843E922D4C0241F8038516FC38802086B274F0A987B6F73D4D4A613FCC46EABC402B31073F1698CC6D13F37E2C2E10E3565A7795449065CD6FCF6E59E782037E55FD09DDD777997CBFC007CE88663BAE88C4157CD11CED8804FF23C6856C1462F2968CC511B51F20D90CE7D +9A3FD418 +5DC7209195D1FF4CC86B1C19DCF7 +2A684B3742ECAEFAC0FA64F8A1B797083E341BEDA5232C0422309CA1F98949EDC210BABD163AD16D3D8269BF1A0C9A6BC403E32E4EEFFA70083A9DC353C1F5C30DF9CCDA13CE967678B3C9D9DD73CEF307E81912E4D56AA9E257370497591E38D1A9748CC022C34F3716 +9504C350 +EBA1D0033FC6F8F24A701570D9 +563168F0C6873EEC959FC0C1EA4646D57BB8FE583438C829119C8F0A34F879632ED5002C016252C95E139E58F29F940A27B55EC38FA8D442A3319F2F3904A16428F929368CC2232650C330AE4051453752D9BF5B843952 +46C7706E +E2DE5853019A78B0A7C7E888F5FC +DB35D70EA83E3DE57F825BD4449CB5CA016E95CCB5AF571090EC282378B3824B8A4B9BE5F37D523B62EEAFF7B80B249DA4DCE091EA0CE081AA75F9CA568116004EA02CB1793C9ACDE9257EE6A4E6ABAACA2A401C9146ED47001E2108F59304073057C0B43EC9CE08D13BE825BAE3C080A7A1A2B582FBBEF75123D1EE +81A743AD +6D92AB6EFE2A6E965EC9E6425D +4FA67A18527B6720A9951C076E2F889C227689BA28D1BD0A9846BD0AE8FAD98DEDB442402EC5776ACDA67A25A9410942385FC78D25E3041A3B3B2B4DB9AE0CD6AEBCCE8E03 +85DA3E6A +54E93771A2D2A7CAEFCC80A917 +B83F955C93C77AB939A840163AAAB2C73DC7818D41B0D64E3774B64F8B200A38A0765E785DBC1996A1D97A1674E5EA4D5C602BF8B6F5C17B98935177F71634BD3D2CC8FF4028F8FF9BAB06035860C54AE1E018DFA7EFD248F1CFCE5501F8F006AAB0 +D4BC494D +DD6149449E95AF6688EE337093 +F5C8B64F32718AB2170168B91BFA4409569342C6EB6DEA174244F0BF8B5466C0D51663F0299720957BC5804D76A5C4790F5BB9CF18A2BD6C92FD1C21EC2754EFDE1C07E8ACEAFCA6326586EEB5D33F703121A87B590934A404 +E666CD96 +8D957696158A68A1BB6150887883 +B3C9AC239BDA0A2A3159F9C92AAC9F059014C84EF2F6C3420F5F2F633AAB661307DFF01678939C625881CBCD80F7F85B0AC703897B171F0B90E007BF21667DEF63447F3041362D34E8DCB9DEFB8BACF13F3D6EA7EAC25647DE5D56EAC4FBC0BBF693C67A07898C87E69AF129BA934F66FB2E605E4D37B9FFB8A55EA1B37A +E061 +BEB26A5ED42988A9BB7BF9DA77ED +0FF492E9 +CB1EFD5970FFC5F907BFC7C7A4BF +4DF6D6E065B3DDA7562E2A730FB66E4973B9657A024CD08F58E0B7E958F3E730FD794DA7F9060E9A8D4BF803138CF1EED1C574DE20C9ADFC67D6BE1DD97DECE433B9790710F222824D3135B5F08847B1D1A83C1147913643AB8B909D2E77F044F1071706D76061A4826F447ECC66A3DF9A45F2004D1E13D0363894C8065C +023F +B7BB408DB8A0B9275EDAFA1007FFE25241B7D5AAB63C0F97E2 +E8509B9D +C0E33DE59D61D2C09CD4C27C58AA +432F30076A755479822A3628AC51445FF682C05CCDAA69C4E668C5CCF9B26DFD6481DF8CB6971EA49D53493F969F3EDC4C0C115A10DF3B9F92D20986E4C7CE34C8B26EC1447356D711EA94BDCFD27259EEC68D6072C88E2B35D70C7CB41C9A2734FDB0A1C305B7B3B972BBAC92C78B044A0BB442A2593BA35389F22CE6DB +F8BB +B6340B81 +8EF3D6257EC09D1136DF26FC38 +1D8D871D91D17CB7D564EACE1CA872A17BA2A95FF045DA2F5B41F3B770248B562FE8C7BCDB9E05D0F6480FB0541605FE03EEAC693FFC5096889A298C8E05CA +E01CD451 +A340780D263F1CB1CA892B5DE3 +77790862E3FC50393298FD86BBC3D4C1F5690A910924 +076939CA +577EFAEC743063CFB5991B1E7F57 +3D8C09649920842E +903B69BA +116FEF1D1C5D0EA2D7CAE7579F5F27FA5E25E9F575A03831AB7F4F2F235B834C8F38 +B5B3BDC9AA325441EC4B0D567AA6F1FEFB6C803608251F27B92023690BE24A3BE3FB86C1CFFC +719292E60DEADA151AC13E2F0F0EC4EED96A635FC68AAAC789D75C +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +%Defining font PSOsymclas +%!FontType1-1.0: PSOsymclas +10 dict begin +/FontName /PSOsymclas def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001000 0 0 0.001000 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 1 /C0069 put +readonly def +/FontBBox [106 45 775 713] readonly def +currentdict end +currentfile eexec +D9D66F633B846A989B9974B0179FC6CC445BC7C8A959A39A32E9DCE7FAEF17EE3BEC9F +50E1A6FCA651FC4B3769A0A91041557502E25A5D6180FE25A3D11BF079E1DF66E54EE9B7C229AF891739707A2A0EC140306B5E43E52B79BFB89E459E50 +6EC6F610A70775A31C460976C4F79449D86E57ACE491E5C6BF20CC4307B1DAF7630252 +E9AF8CFB69B50EDAE9D36A6104AFEF8832F920FD2346B2C7104CD11E3BEE999CFA9F5A +49DB3173EE48D1C82994237F360407B022E0B4 +502E94EA8B493651EF2D03F0B513D655047568325B512AE6 +6AC6F53F3848CF70DE25481CC65D8B1A5793AA +3C4282D111112BEE28AFCA7A3808D4444C4669CA +84EAAAF989219F51AB3476A1B0B5F2246BC306E6 +625C6679C417ED2A8E9BD010DE37D40265074C2684268F16195489648993B9C4D3B534FA887C +DEF605FA87B991F4D20A8F78DACE +5A54C070E03D5C59D9D2D3E06B09CEE028D68B62AB3AEC43C1DD20BA70D288597D9BD8E06818FF764EBAB436723988E8D7CA59E16D39032516BFC5D552ACDEEC6BE938BEF2F43CFFBC811C3626C4DF5F8CF080676520B51C60CEDAD1FE6C92D1431C702174CE517A8FA9377D075A0B6833DAB101DB65397F1419EF5F0016 +004F +6F0824F9657BB4F1C8F981709956865F6855EFAE +9242AD55 +91BBBEE163D844DDA894E13190C9 +2480439E4C71CADA +BD043A9B +A315CAF72652AA7FE6DB2E84D82A6111CE4DE90C02DA0AFFE2620922262A45AB4ED0 +EEC9F4520DD12703442F7D028D4526BD8B771E09FBE11B2749E2D3906894E8D4BFD3F379F14C +3C874F550606965E22FE487B247B5C2D06728490C8F2A3B588CDFC +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +/DPIx 1270 def /DPIy 1270 def +72 DPIx div 72 DPIy div neg scale +0 -13970 translate +1.00 1.00 scale +/wst:dutch12 12.00 /PSOwstdutch newFont def +/wst:dutch10 10.00 /PSOwstdutch newFont def +%%IncludeResource: font Courier +/wst:courps10 10.00 /Courier /wst:courps ILEncoding 0 declareNFont def +/wst:dutch14 14.00 /PSOwstdutch newFont def +%%IncludeResource: font Helvetica +/wst:helvps10 10.00 /Helvetica /wst:helvps ILEncoding 0 declareNFont def +/sym:clas10 10.00 /PSOsymclas newFont def +%%EndPageSetup +GS +0 13978 10801 13978 10801 0 0 0 clp +wst:dutch14 SF +0.00 0.00 0.00 1.00 setcmykcolor +<121d2b271d291e0c010d010e1d251b2024192922011e262901111d192a2c2921251f01121d2b2e2629220113> 2207 558 0 7384 -1 s +<1d291e26292419251b1d> 7375 558 0 8593 -1 s +wst:dutch10 SF +<080b> 9346 13300 0 9522 -1 s +wst:helvps10 SF +<4e6574706572663a> 1322 13280 0 1949 -1 s +<205265766973696f6e20322e313b20436f7079726967687420> 1949 13280 4 3868 32 s +sym:clas10 SF +<01> 3868 13280 0 4019 -1 s +wst:helvps10 SF +<2031393933b131393935204865776c657474b15061636b61726420436f6d70616e79> 4019 13280 3 7133 32 s +wst:dutch12 SF +<1620212a> 1271 1431 0 1665 -1 s +<00002b2021291c002a1d2b00261e001d2f192427231d2a00212a002b19221d25001e292624002a26241d000002181414002b1d2a2b2a05000016201d2a1d002b1d2a2b2a002c2a1d0019002b2e26042321251d00291d2a2c232b2a> 1665 1431 19 9531 0 s +<1e262924192b> 1271 1676 0 1886 -1 s +<00242c1b20002321221d002b20192b00261e002b201d00170f1318151614100d11002b1d2a2b2a050016201d0026252330001d2f1b1d272b21262500212a002b20192b002b201d291d0019291d00252600272926> 1886 1676 16 9461 0 s +<32> 9461 1676 0 9531 -1 s +<2d212a2126252a> 1271 1921 0 1877 -1 s +<0024191c1d001e2629001c212a2723193021251f0023262a2b0027191b221d2b2a0300192a002b201d291d0019291d0025262b002b26001a1d001925300500> 1877 1921 13 7321 0 s +GR +GS +1263 7816 9522 7816 9522 2048 1263 2048 clp +wst:courps10 SF +0.00 0.00 0.00 1.00 setcmykcolor +<24> 1449 2182 0 1555 -1 s +<202e2f6e65747065726620b174205443505f5252> 1555 2182 3 3675 32 s +<54435020524551554553542f524553504f4e5345205445535420746f206c6f63616c686f7374> 1449 2358 4 5477 32 s +<4c6f63616c202f52656d6f7465> 1449 2534 1 2827 32 s +<536f636b65742053697a65202020526571756573742020526573702e202020456c617073656420205472616e732e> 1449 2709 11 6325 32 s +<53656e642020205265637620202053697a65202020202053697a652020202054696d65202020202052617465> 1449 2885 20 6113 32 s +<62797465732020427974657320206279746573202020206279746573202020736563732e2020202070657220736563> 1449 3061 16 6431 32 s +<3831393220202038313932202020312020202020202020312020202020202031302e303020202020313438302e3535> 1449 3413 25 6431 32 s +<3831393220202038313932> 1449 3589 3 2615 32 s +<24202e2f6e65747065726620b174205544505f525220b1b120b17220313032342c323536> 1449 5211 6 5265 32 s +<55445020524551554553542f524553504f4e5345205445535420746f206c6f63616c686f7374> 1449 5387 4 5477 32 s +<4c6f63616c202f52656d6f7465> 1449 5563 1 2827 32 s +<536f636b65742053697a65202020526571756573742020526573702e202020456c617073656420205472616e732e> 1449 5739 11 6325 32 s +<53656e642020205265637620202053697a65202020202053697a652020202054696d65202020202052617465> 1449 5914 20 6113 32 s +<62797465732020427974657320206279746573202020206279746573202020736563732e2020202070657220736563> 1449 6090 16 6431 32 s +<3932313620202039333630202020313032342020202020323536202020202031302e303020202020313432312e3335> 1449 6442 20 6431 32 s +<3932313620202039333630> 1449 6618 3 2615 32 s +17 LW +N +6720 3394 M +7455 3394 L +dp +N +6916 3342 M +6916 3447 L +6916 3447 L +6720 3394 L +C +{} -1.0 -1.0 solidFill +dp +0 LW +N +6720 3394 M +C +wst:dutch12 SF +<2b201d01291d2a2c232b> 7512 3445 0 8365 -1 s +17 LW +N +2705 3367 M +3050 3818 L +dp +N +2881 3469 M +2807 3543 L +2807 3543 L +2705 3367 L +C +{} -1.0 -1.0 solidFill +dp +0 LW +N +2705 3367 M +C +<23261b192301291d1b1d212d1d012a261b221d2b012a21311d> 2734 4072 0 4876 -1 s +17 LW +N +1950 3360 M +2560 4157 L +dp +N +2126 3462 M +2052 3537 L +2052 3537 L +1950 3360 L +C +{} -1.0 -1.0 solidFill +dp +0 LW +N +1950 3360 M +C +<23261b1923012a1d251c012a261b221d2b011a2c1e1e1d29012a21311d> 2182 4411 0 4707 -1 s +17 LW +N +1610 6783 M +1610 7545 L +dp +N +1663 6979 M +1557 6979 L +1557 6979 L +1610 6783 L +C +{} -1.0 -1.0 solidFill +dp +0 LW +N +1610 6783 M +C +<291d24262b1d012a1d251c012a261b221d2b012a21311d> 1544 7800 0 3681 -1 s +17 LW +N +2480 6818 M +2881 7269 L +dp +N +2656 6920 M +2582 6994 L +2582 6994 L +2480 6818 L +C +{} -1.0 -1.0 solidFill +dp +0 LW +N +2480 6818 M +C +<291d24262b1d01291d1b1d212d1d012a261b221d2b012a21311d> 2830 7523 0 5192 -1 s +<2c2a1d0107060809011a302b1d01291d282c1d2a2b2a0119251c> 6525 5004 0 8935 -1 s +<080a0b011a302b1d2a01291d2a2726252a1d2a> 6525 5207 0 8294 -1 s +17 LW +N +5592 5173 M +6327 5173 L +dp +N +5788 5121 M +5788 5226 L +5788 5226 L +5592 5173 L +C +{} -1.0 -1.0 solidFill +dp +0 LW +N +5592 5173 M +C +GR +eop +%%PageTrailer +%%PageResources: font Courier +%%+ font Helvetica +%%PageProcessColors: Black +%%PageCustomColors: +%%Page: (27) 27 +%%PageResources: (atend) +%%PageProcessColors: (atend) +%%PageCustomColors: (atend) +%%BeginPageSetup +bop +%Defining font PSOwstdutch +%!FontType1-1.0: PSOwstdutch +10 dict begin +/FontName /PSOwstdutch def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001000 0 0 0.001000 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 1 /C0032 put +dup 2 /C0034 put +dup 3 /C0044 put +dup 4 /C0045 put +dup 5 /C0046 put +dup 6 /C0047 put +dup 7 /C0050 put +dup 8 /C0055 put +dup 9 /C0058 put +dup 10 /C0065 put +dup 11 /C0066 put +dup 12 /C0068 put +dup 13 /C0071 put +dup 14 /C0072 put +dup 15 /C0073 put +dup 16 /C0077 put +dup 17 /C0078 put +dup 18 /C0079 put +dup 19 /C0080 put +dup 20 /C0082 put +dup 21 /C0083 put +dup 22 /C0084 put +dup 23 /C0097 put +dup 24 /C0098 put +dup 25 /C0099 put +dup 26 /C0100 put +dup 27 /C0101 put +dup 28 /C0102 put +dup 29 /C0103 put +dup 30 /C0104 put +dup 31 /C0105 put +dup 32 /C0107 put +dup 33 /C0108 put +dup 34 /C0109 put +dup 35 /C0110 put +dup 36 /C0111 put +dup 37 /C0112 put +dup 38 /C0113 put +dup 39 /C0114 put +dup 40 /C0115 put +dup 41 /C0116 put +dup 42 /C0117 put +dup 43 /C0118 put +dup 44 /C0119 put +dup 45 /C0121 put +dup 46 /C0127 put +dup 47 /C0262 put +readonly def +/FontBBox [-25 -238 920 722] readonly def +currentdict end +currentfile eexec +D9D66F633B846A989B9974B0179FC6CC445BC7C8A959A39A32E9DCE7FAEF17EE3BEC9F +50E1A6FCA651FC4B3769A0A91041557502E25A5D6180FE25A3D11BF079E1DF66E54EE9B7C229AF891739707A2A0EC140306B5E43E52B79BFB89E459E50 +6EC6F610A70775A31C460976C4F79449D86E57ACE491E5C6BF20CC4307B1DAF7630252 +E9AF8CFB69B50EDAE9D36A6104AFEF8832F920FD2346B2C7104CD11E3BEE999CFA9F5A +49DB3173EE48D1C82994237F360407B022E0B4 +502E94EA8B493651EF2D03F0B513D655047568325B512AE6 +6AC6F53F3848CF70DE25481CC65D8B1A5793AA +3C4282D111112BEE28AFCA7A3808D4444C4669CA +84EAAAF989219F51AB3476A1B0B5F2246BC306E6 +625C6679C417ED2A8E9BD010DE37D40265074C268420E0054E87EC3C41CD6B9E50D89E086195FD +DBE7F567E59D6EEAF6DCF9A3 +C3CED684AC8CD7B335 +847363F7 +B370137D29F4153E8B3C86621421 +E2B0DE3A8185BFBD6A0C5FED759015801F89835BC0751574978BA25769226CA2A392112B857A122C996819F1DA4B9B44EC6843C4A4DBAD6D529207B2A5B701E7C7B7873A546E05E0270EF7771EF5786A43265121652041AC02111D6E46DF9D5B31A06AA8E3A611 +0E31A7E3 +A831B48EE9453B70DAC96EAA02 +F137C213F762DCBD3039BFA81BBD79FFE4FB1A90611B68AAB86DB18CA02E78648CEF537FE8377EF70ABE9F4CCEACF21C8646EC9BD2D7CDA6A9 +ECF15CC9 +5E7F477553A2EB356BE9470F03 +7FDD15E6ED379EAC05D4EBBE0D3CCF16DE2F2F58758023 +B0759552 +BCDB135D3B39205908800002B4 +74ABB0AD98B6B855CD008419613DA7524592DEC462C6054E3504D734560E6E +9AB9F712 +435C843E7C13D2EE038F851307 +C6204A77BAC6C05FDD05BE9CCE5CB2F7CFCC401B14148099A6F1A0FA +68C739E8 +28A56537FD11661F0B1CC4C351 +14DEE607D13E86E91381AB38998A525A3F2D535E86B0EEF9476C73DDF24E6D9C811430FFFA417235CD1C85E7ADDD6E586796B67CBA028DAEA6DD446EAD5603E14A5145E239758EB2DF94951ACAF3094195520CFE372E2FC100B0 +C6B4B0A3 +EF2163CA4AC98C2239FF7C2F9B +79EF6630A6B982C33699215710EA06708041BBCCA7DC404D6D93093F405E28169F0B7B8FB724AC8BC2D800 +74C56185 +D58EF58BC310622D8007A98B61 +2A4BC3C2356D4FD5BABA6211AE20EE9014B81914C842604B9BAD908E6AEBAFFEE14961E53B34B2ECFD0EF6B72B8511AD2BED0152CBD3 +2BA4FD6B +2B07DC09700A851709828F520F38 +50EDC06E07F2A8E6D4A4A56C427A906F4F366B1184F3A72FFB2A85E0774245512D3A4E86D5449059EF3B818CCC0B23FA8B41D6A8B05F5B52514A9B25742EE8108D2872277E979E4C9D59B1B8D1B15309EB81E4E0EBE325D524E47552A16BE7EDC1901271BC94413A986FD11065E506B5500C01 +7950249C +83F57BF8005FA33F37FFF83AAAA3 +F4F68A8E2139F40016380BA71BCBF54D1A36BF978DE087A5CD2D71BDF052F00B3D4641038D806D1665C93316AA432B74EF2B180E3B77C40ABBC5BD24F96D2EF67DE527D47A587219DA38A2B98D814C3B616214936F94191E377241740674663957A69948AACC81EEA66B6D4F8C96C0D503CFFCEE0F415194174EE8ADD5DC +F0E4 +E0 +34FACD2B +AC7567645C2554EF41BD5A2DF2 +13D85A56194FAA04DC14FF7F6352D4F582463754B95D859C13EC0F867362C94582FA16699321DA40483DB6AED49DBD846F910F9C08B12217789F43D91E7760C987EBD47BC77AD3F3D95808955A5CA80B13D6F2F183F8B210C2B8D4102CB18F01C99959 +3F957AD3 +76D7C77A52EF007F6136E6AF2EAF +E4760B0CCA5F965980EA06AF6E664BFD6A479E6E9692ED23CBA51746C0A389F27263B46D2284D8DD1D527F90827CA62919D35198BCD00601BA756A28714340DE837581FC1283000B273980D196E7D84CD8F0BB7EABBF87D1896D8B5C3CB56C99C1ADF285590264B30ED2B234E54EB1BEDB76CD194792F5D72F0F +0B91A00B +4993E0864ACADAC352A03ADF0223 +DA6C5472CBE6B74547FA21A86987B4C6F7967397C051AFAA80AA80DEE1F2853BEA5908DCD2F7E8782B4486D9D227E7C92F68C1609A2BEAE917A8683A8726EC91FFD9A726A87040002FE42DC9337ECA54AF4F3982B497F040594DEDABD1D6E9CCC28BCE4F8052D5424BFF8FF479CD1DB113B6E2495897D76E6C81C0F86F36 +89C0 +FE0B5B5A253958EA5A7471 +5DE32019 +5557FFE20C77DB134C7DC950C0 +1E31D9156143F44047A3C77147EF3E00F43EA03701229AC73C5A9AE69EABD352CAEC30EF16B4BA3A95CC7132F63551C14875242AAA98C514D27550 +DEA76805 +37F6AA0C17C882282DE28060A81E +14EE323027802C60C935947568A02865304F7C8CC08AF0174D9D8846D4191F8B0DADB030AFEA86CCD194411E986D04F5ECDAD626D418DB6CED0246099705764E5FB11BDC0322B3C5965113969ED11420274FB15A327D1661D2F9EF9AD84111D3034F5DC6534602860BAB9F7E494DB3 +489CEFE4 +4ABBE99D528A4752814E9788B3 +C1295FB315B351805FE9FF655F79EF864FE35C66365AC7745433196FBADCDF35BE888E8AABAB884EA1530CFDE97396863DA6945582E7684F409CCC2BFBCA706A63779B254574F5F6657181897048F5BF96DDB7F8A71F1074E6BF1F91 +A7EDC660 +99BE1778C47FCEED3618482C30 +DE54253803D1272727C855E7575FA66B8FB82B3F3063921FFB0B2186D5A9D7C8E99FB6F60108B5E0FF729EFCD12F2A4E287AF078FFDB22D4647C009A6681869F87B0982C81B9070FFDF9E9196FA4DEEA812631 +2E7E4654 +85EFE76E0773041B2B757A6AF4C4 +E67B407B8E5738C05FBC124740A2EB7237F359BA32718A00E98596E8F00929E2A12E72D433DBC459B2ED5254664D5441F4F50B0A47E8664DA3CED39501AEC6D96D9A173E884B79B38CF1D9296030550D05DAC04057E1936326F15315352297A097E2D2DC32FF94F6A336 +04EF5219 +4C23017A1CD731231B43EB00EC54 +4A2B74217FA817005C18DF8641EA8FCAD476DBF9C7654B8AAC041138CDBEFB990E065B18F1043C66D3A9AF3C371E9D397909410C510C64F3BD589D67D1A0E45768227DFD4EE3E461FF30722E046ACA3A47CACB114EF27C598D75B1D16CD7BC67117B5C97075D92EC562B6C6E283E824A519226EC3377968FD85EB09DE913 +EA049AD7 +8B038FECB7D7657F8AF7BA2F3D1C +14EC30CB430485273DD035EEA068E10C9C3D936D9536036A0CD5AFA5BE204FDBE8AB39C8A89061F1F9EC7ED42D83D622FE45E0CA53C6BE6FEA97BA2E4B606659BF47B8477B7C74C867560CE4479E996A416FCFF76144E44D6AFE21356D4DFC286011679987104B875722F005CDA10E0105CF942733D482F827A9128EC83C +E01D +B42A7F +2776A19B +CA565A2225CB2FAD7CE81CF88E +F1B4ABF103094802C1FC66111A500E220DE65031A28B82B7FB9D60B3C65BB5AC571CD4B35105A5321B5F76B1957BCD47A505B4BD796C89847748FB087F1D3B36B11A4B82CAAA0FFC01ACE8A734EE265BD1 +0F1C199B +7102139AE7216C5C975EBE25F472 +9E57EE0656E78AE48550C6ACB6AF91E34AC0A0CA7E5E1D124E8317E78553F2FF9CF6E9FE614B5087FB49DEE5F1DFE1F5E6C0D7CB7376077B72F160A65ED494ED42AFF0403B5E501F29E91C3D113E77C1D58F0250EBB570AD9B034B27A59934C932C5D4397594C7462B4BE1A1F970A77103C71A8CE7EF90CC25F11B6FEE43 +0157 +2721D4 +AF72F0D7 +6E231FA44CE3C792C3BD8D3032 +A07CBB36386D7D95D680565BAF5F10D84BACFB4F7960DF6AEFEF86BFAB1C0F2E8B831F766DA0D12818C44DD06D82EA8220E762959ACE9F95871A1985FC5BD4660D1BBF169DB63DF8C398EC2A8157EB6BEB7F8AA6F7925A0B +56F47A29 +99D6D74621F06EE22BB45644E6 +10A3C02DDA9292D70DA6311049573B52F9C1A4786A32C7D86C0558FC69A63A397FA576C6F04EFE13C7647134EDD1F9F0C55A6A339D258B50424953E8A029DF98E603F2316CF5FF2EBFC8F7F7FCD71DABB871 +82876D26 +BDF43F50327FBB5C881ECD36CFB0 +020B11D17500119AFB4CD3E5AA768EF330DECD9526F98E78783DD82C9DAFC45C39714AC0BE6DBB4E5D96D842B9678644B57732E4C81E5BD41C197FC110817C80B7C95EDD0C4E67FAB19582AE234DEB4F34B8DD40E76FDA345D6F51E27413B8F1D2F7AA5769F8CF4C07D834FA2C70 +BED36E3E +8DFAECA2478DEA693FD1EE6F74 +FFBDD658EA5AE74E971966ACEF8F68867C4D0C259BB2280B4DC9FFDC6CB66167B72821D2ED7038074F307F7A526BE98ABD5516257995B81432DF2963BF7B6299558BB917208EC56FE1A141F597A9164117ABED91C1D1B0BDCC +993C3797 +9B81C5164F54A9684C2FEE740B +CF8F66A792F3154EDDBC7A65FBE671DA21C169F26B5EAC312BCC3436F32B6394EFF7BD4BDD6ED593D01A196D3626675CEE61D294654E307E61D4612E812CC3C79F58E0AA8957C9E2EDDC56A889CD463753EA8A63018648B02AD2C8BD +8ADEA4FA +E494188336E10DC346C1F89AA9AB +1F8C02D048C53C15CA3D9E1F95DED6D1DC92D92490BBA4740D3ECCA5658DC23A6E8DFAA3712F220D23944B501ECF3185AF8B79DDD29A072E8B0786DEE21CC5C1E2B568B63A72013A86FE28E648AB4DB99EB79DCF2F88A3CC122A57244883053983B496E3DEEA397FDB9DD9233A827BB9F527DE58D3F6B99BF6610673E40F +F1AC +8460C0BFB1709DAA1AED076A824E174BED8BD8538F4918D3A488C7E9CF66A4F21C9F0AB6D376BD4F62B7405FE67894 +8F09EF63 +175D16D391EAF5E1B1B6821F31DB +2754D497F086378237F50609AA279F06723B5513A259A39C9850EF66B56C6AE84513A41497717DBA45674E801A7DA5DFF3593804418F7EE4BAEED33A93873D8011A3F9F8C57CC242031281DF1A4C320CD75C5160F0594E92F0DC98A1ED11604A856BFDA97101B796A08D52D2C8 +5891BF78 +6F8687DC60EBFC14C67FAA3116 +71BCD21B86047ED6BCA77F93FCC54F04E1198B18BDABCF302D1ED0E2E53AD0AD08B70238D5BBD7BD61EBC15AEA7848DC4D63EBE3721A1284B6BC174D0F5BA3947CAFE62BA44EB091E20DB46B1353649F +20F36EE0 +FE78989E8C3F7A4ADD4923DE906C +129679CF4EE011243C40DF63276F9776ABBA418FB66D65FAD32E41B614D92F401055318036F28DA1AE3EE3F2B87027E7A103958E493B685D73F5CDFB2CA29DECED5532B7EEDA19D1258871EC8938D539FCB723BB36DCF36AAB8C7A135513E496FB8EC020251B711E1C3CB5185881776F28C2369C0F3833019A2D27079063 +694F +1E5335B332CF1C9E54AC031F0A5FA78E74195AFF245060A439E7C7730EEC7C9C859397 +D1575C3D +81D382641A66B2DC2FE4D03A6F +CEC593873415822AB972D1AFDF2E23A06402C558202288319C10E8DC59C64FF8D44DD50CA793925B27D27A4003EDE5C54D7D0927B1C6 +F2A357F4 +5D3B96D68552E95E36B958376819 +8AF9E885F93B958FAE023AA4F253BDFFE628587893C2F2E04D68F8DD81969AF1897933BAAF97AA1CB300988C63AE8E4658B1304C0489758764930B49F83BA8BA016B302B92440651FC25513971D128892438D6B3E7AF8BE3172D47AA6C313A2797324BC8E68647837148AF5396EA0B4142C26878D165E255E6EA3AC2E44E +447B +56198281882A234FC6F665E54DFB514D11FAC8B98913D1104375028F2C6223 +1352F421 +EC47CA5BEB52FD5CE7C9166E4224 +6934DD006B66F165B7FA9A28C412678941CFA72AD1C86C44505824F5FED58F95CF7EDE8639C84B479CFDE4C506A3DFC07CC33CD7D536730FAE7C55D0AAA15DF9BDD6BF9551385B9BDB979CE908C24F207B3BD1F3875EFCCDB60480073155AFBD2F4D16098A7FB678F9A32E91 +E0E18883 +519421B3D7B3F0E41465E9D8BD +AC9197ECEAB363F896BEEEA0FEC78D1C4F6FBDAA824722D27180696567E1C5599FC361EAEFBEC47ACBAFFDE24D67621B4EBF74E5960D1AF0BA649B42DCF9553097356ECEE8FE +FC37CD6E +BD803C2E1D91FF3EC69F700FC74B +0439374FBB67B8721412BFB2B4716475BC56471B24C1DCB346E0C9E8A3488DCBC47C25386F70A456795B8FCB886C6AA888739149CF5A18A9F6106B14C87044826BFEB223E4CBDBC868F62AEE58ABEF899B7E24980F65848DD259FB415CF6D63498B525AD9AD648DF15C275B08FD2C73F6A32D3712ED8F0 +883B3B04 +5ADD14B4C5582DEE1AD5A97910BA +A4B9435FC9D39E80B4F4162EE04AF8FB38923AEEEFE5D67450E7B19036A683523ABAA9A8F35EBE27564E18C1B4F5DF374460EB888EBF23189F09D4713D4FD9B085AE8AD0D0C9D168B3155D452BF6EC74B79684B3E11B56EE7B61C93F9BE5B36E8EBEAC7031B5765C4DCC +4A621B69 +F5801610DAAF72BB68D047F410 +CD1709FFE01AC47F281B8667B10326D3FA2FDA5AEBEBA069FD2B58D946467911EBE87A16D78A22B87F486B492B66FFB4B433836EE59A30DEC2B1B731447746D60016BCDDE475AFF583B7ABA712EFF1B628FEB9D48233DE +EA2C6830 +EFA09F79A4FC03A72EFEB505365B +B9BA797CCCA8ACEF84B18F55C8F2BE6CE201683EB68900D648170D82E7E32630FC91F8740193F455EC1722EDCD11BD2CBAA4C155EAA29F27337E1A2D9F6B91BB8E1E6E647B38E670195C70C2B2A8DD67FC357633546A6DB4108C7CDFF7FD8CF40A4A8383C35FA124BDF0D0DFE330B78C290A4B2B5FFCA9CEB5925687 +545CCAFC +24C48B0AAFABC9427B7853B47D +D59CC846BEE65D90E308DB93AFF7CFD1D62C3D5152ACFEFB9A0D3092671BE49EA2615C62905BEE0C62DB89F88ACBCF0143634B9E0A6C22EA1AFE9E49F9474816F21987B3A3 +61AB0A34 +CB92471818253C04EA0E091803 +D9D140373F66F7061E01E3516F41385000ADD98F32A1A7ED094B2E1F6CED56896251A8B5701171B06444667D855FA568215EA45CD2E2EC44C6FA0B9ADB48448C8EA7C62B3ABDA2CD556E379FA621542A52B83253A48E917450D8A951492D72DFF4AD +23E37D68 +239728EEE7EB597ECF7B6FC3DD +D73B925333ECD3782AC79BF9A376B2EBB7F51F309317D74FB0B90E2CF72CFA7A34BA062CB9BE20AEAE62E8DD82FDCEE6D483BEAA690EAF62DE6459BECD198B26C4378A599B636867780E2875A4BD85ADC475D81964E44A6EA9 +764ED929 +F5493A321793170C78FEAEABB441 +23F0FAC8203C14E5A4AAEA9BC25103F4403115EF5C24A2AFA71D4D27F22116A29EFE984B0A5D368F4D88121D2699108E1B0AA943B8C4C3DD546D358242A98A6A80072C77E9CF957E697585F2F0C2D742DB8610CD4442BF6D8FB7B1F1FBA9987BE875E7E65FCF673C95C6C7F566BD234217D3F96A88D891C2C1A12EC81F46 +5DB1 +3450DE8C1C438A7AE2B4BCCD83E5 +7E28E2DF +7B5E5020B5607AA59718CBD1BA0B +0C2EF18672CAF4A8A3172285557F80B118864CFADFF93ECA670B4866B15D2AEAB0895804728BF0555EEDCD7E5B66E880FE913CC8B3CA1C6C9F494F7DC3EF8E79367087D34C151999A691C34C79E0D076A97452D692FB9AEF573B6CB7F7691BD4492BB182F8FABBA32E8688106DBA1A708C8F04DFCA028F132FEDA08FC327 +9AED +5DD73D4B +299A66F74BA89382665476D38BE9 +527F7087AD85E81F2EF6DC1F3CE145CEF740F6E56311A48C89DE65A62A7F8F45AFE4FD28F98A6F5A5C9C304122F592F394AC095E0FA32711966D58F54269EF30501B552DD451053901321B7CA58021B5B2860199003D329A91D2044314D93863E8AB504221087F39CF +9B0B1D95 +84D40AAF66DFBC55988BB5520F +841891A481641222E52D79C4FACD1716E7753249EE89 +40686406 +2864D98C96631C15C1A20BFD6BD2 +2B450926363F93BB +1D2B8513 +5473FFC5DFA04D7C1A9DC7F4CFA79BA7B27F3FFA4ACAFFAFBD8F35402470E594724F +22C2D72A67C3AF0E13F8FBE10B7AFDD3A7CD957D504DDA6202EBD4C054285611B5A82B545758 +A9CE05E281E10BC4C7F72125DC174ECE47DFE2E2AC7D73E73B2B5D +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +%Defining font PSOsymclas +%!FontType1-1.0: PSOsymclas +10 dict begin +/FontName /PSOsymclas def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001000 0 0 0.001000 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 1 /C0069 put +readonly def +/FontBBox [106 45 775 713] readonly def +currentdict end +currentfile eexec +D9D66F633B846A989B9974B0179FC6CC445BC7C8A959A39A32E9DCE7FAEF17EE3BEC9F +50E1A6FCA651FC4B3769A0A91041557502E25A5D6180FE25A3D11BF079E1DF66E54EE9B7C229AF891739707A2A0EC140306B5E43E52B79BFB89E459E50 +6EC6F610A70775A31C460976C4F79449D86E57ACE491E5C6BF20CC4307B1DAF7630252 +E9AF8CFB69B50EDAE9D36A6104AFEF8832F920FD2346B2C7104CD11E3BEE999CFA9F5A +49DB3173EE48D1C82994237F360407B022E0B4 +502E94EA8B493651EF2D03F0B513D655047568325B512AE6 +6AC6F53F3848CF70DE25481CC65D8B1A5793AA +3C4282D111112BEE28AFCA7A3808D4444C4669CA +84EAAAF989219F51AB3476A1B0B5F2246BC306E6 +625C6679C417ED2A8E9BD010DE37D40265074C2684268F16195489648993B9C4D3B534FA887C +DEF605FA87B991F4D20A8F78DACE +5A54C070E03D5C59D9D2D3E06B09CEE028D68B62AB3AEC43C1DD20BA70D288597D9BD8E06818FF764EBAB436723988E8D7CA59E16D39032516BFC5D552ACDEEC6BE938BEF2F43CFFBC811C3626C4DF5F8CF080676520B51C60CEDAD1FE6C92D1431C702174CE517A8FA9377D075A0B6833DAB101DB65397F1419EF5F0016 +004F +6F0824F9657BB4F1C8F981709956865F6855EFAE +9242AD55 +91BBBEE163D844DDA894E13190C9 +2480439E4C71CADA +BD043A9B +A315CAF72652AA7FE6DB2E84D82A6111CE4DE90C02DA0AFFE2620922262A45AB4ED0 +EEC9F4520DD12703442F7D028D4526BD8B771E09FBE11B2749E2D3906894E8D4BFD3F379F14C +3C874F550606965E22FE487B247B5C2D06728490C8F2A3B588CDFC +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +/DPIx 1270 def /DPIy 1270 def +72 DPIx div 72 DPIy div neg scale +0 -13970 translate +1.00 1.00 scale +/wst:dutch12 12.00 /PSOwstdutch newFont def +/wst:dutch10 10.00 /PSOwstdutch newFont def +/wst:dutch14 14.00 /PSOwstdutch newFont def +%%IncludeResource: font Helvetica +/wst:helvps10 10.00 /Helvetica /wst:helvps ILEncoding 0 declareNFont def +/sym:clas10 10.00 /PSOsymclas newFont def +%%IncludeResource: font Courier +/wst:courps9 9.00 /Courier /wst:courps ILEncoding 0 declareNFont def +%%EndPageSetup +GS +0 13978 10801 13978 10801 0 0 0 clp +wst:dutch14 SF +0.00 0.00 0.00 1.00 setcmykcolor +<111b29251b271c09010a010b1b23191e22172720011c242701101b17282a271f231d01111b292c2427200113> 2207 558 0 7384 -1 s +<1b271c2427221723191b> 7375 558 0 8593 -1 s +wst:dutch10 SF +<0708> 9346 13385 0 9522 -1 s +wst:helvps10 SF +<4e6574706572663a> 1322 13267 0 1949 -1 s +<205265766973696f6e20322e313b20436f7079726967687420> 1949 13267 4 3868 32 s +sym:clas10 SF +<01> 3868 13267 0 4019 -1 s +wst:helvps10 SF +<2031393933b131393935204865776c657474b15061636b61726420436f6d70616e79> 4019 13267 3 7133 32 s +wst:dutch12 SF +<0f1c> 1271 1431 0 1422 -1 s +<002d242a001e172b1b00192422251f211b1a00231b29251b271c002c1f291e00040c0e0f1516120d14> 1422 1431 6 5672 0 s +<0a1003001f29001f2800252428281f18211b002924001d1b290017001e1f2829241d27172200241c001f231a1f> 5664 1431 9 9461 0 s +<2f> 9461 1431 0 9531 -1 s +<2b1f1a2a1721> 1271 1676 0 1820 -1 s +<00271b28252423281b00291f221b28001c2427001700271b262a1b282906271b28252423281b00291b2829050016> 1820 1676 7 5870 0 s +<24001b231718211b00291e1b001e1f2829241d2717220019241a1b03002d242a00231b1b1a002924> 5839 1676 7 9531 0 s +<28251b191f1c2d> 1271 1921 0 1889 -1 s +<0017002b1b271824281f292d00211b2b1b2100241c00292c24002427002224271b002c1f291e00291e1b002e042b02001d2124181721001924222217231a0500> 1889 1921 13 7753 0 s +wst:courps9 SF +<24> 1140 2168 0 1235 -1 s +<202e2f6e65747065726620b16c20363020b174205443505f525220b148206870696e64696f20b1762032> 1235 2168 9 5225 32 s +<54435020524551554553542f524553504f4e5345205445535420746f206870696e64696f203a20686973746f6772616d> 1140 2326 6 5700 32 s +<4c6f63616c202f52656d6f7465> 1140 2484 1 2375 32 s +<536f636b65742053697a65202020526571756573742020526573702e202020456c617073656420205472616e732e> 1140 2642 11 5510 32 s +<53656e642020205265637620202053697a65202020202053697a652020202054696d65202020202052617465> 1140 2801 20 5320 32 s +<62797465732020427974657320206279746573202020206279746573202020736563732e2020202070657220736563> 1140 2959 16 5605 32 s +<3831393220202038313932202020312020202020202020312020202020202036302e303020202020203737392e3535> 1140 3275 26 5605 32 s +<3831393220202038313932> 1140 3434 3 2185 32 s +<416c69676e6d656e742020202020204f6666736574> 1140 3592 6 3135 32 s +<4c6f63616c202052656d6f746520204c6f63616c202052656d6f7465> 1140 3750 6 3800 32 s +<53656e64202020526563762020202053656e6420202052656376> 1140 3908 10 3610 32 s +<202020203820202020202030202020202020203020202020202030> 1140 4067 23 3705 32 s +<486973746f6772616d206f6620726571756573742f726573706f6e73652074696d6573> 1140 4225 3 4465 32 s +<54454e54485f4d534543202020203a20202020303a20202020303a20202020303a20202020303a20202020303a20202020303a20202020303a20202020303a202020303a2020202030> 1140 4383 43 8075 32 s +<554e49545f4d534543> 1140 4541 0 1995 -1 s +<20202020203a20202020303a2034353737313a20203538323a20203134313a20202034323a20202034383a20202034383a2020> 1995 4541 25 6790 32 s +<2033383a20202032343a2020203130> 6790 4541 7 8197 32 s +<54454e5f4d534543> 1140 4700 0 1900 -1 s +<2020202020203a20202020303a20202035313a20202020383a20202020313a20202020313a20202020303a20202020303a20202020313a20202020313a2020202030> 1900 4700 45 8170 32 s +<48554e445245445f4d53454320203a20202020303a20202020323a20202020303a20202020303a20202020303a20202020313a20202020303a20202020303a20202020303a2020202030> 1140 4858 42 8170 32 s +<554e49545f5345432020202020203a20202020303a20202020303a20202020303a20202020303a20202020303a20202020303a20202020303a20202020303a20202020303a2020202030> 1140 5016 46 8170 32 s +<54454e5f534543202020202020203a20202020303a20202020303a20202020303a20202020303a20202020303a20202020303a20202020303a20202020303a20202020303a2020202030> 1140 5174 47 8170 32 s +<3e3130305f534543533a2030> 1140 5333 1 2280 32 s +<484953545f544f54414c3a2020202020203436373730> 1140 5491 6 3230 32 s +17 LW +N +6524 2327 M +7259 2327 L +dp +N +6720 2274 M +6720 2380 L +6720 2380 L +6524 2327 L +C +{} -1.0 -1.0 solidFill +dp +0 LW +N +6524 2327 M +C +wst:dutch12 SF +<192422251f211b1a> 7316 2378 0 8152 -1 s +<040c0e0f1516120d14> 7316 2581 0 8681 -1 s +<0a10> 8673 2581 0 9037 -1 s +GR +eop +%%PageTrailer +%%PageResources: font Courier +%%+ font Helvetica +%%PageProcessColors: Black +%%PageCustomColors: +%%Page: (28) 28 +%%PageResources: (atend) +%%PageProcessColors: (atend) +%%PageCustomColors: (atend) +%%BeginPageSetup +bop +%Defining font PSOwstdutch +%!FontType1-1.0: PSOwstdutch +10 dict begin +/FontName /PSOwstdutch def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001000 0 0 0.001000 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 1 /C0032 put +dup 2 /C0034 put +dup 3 /C0040 put +dup 4 /C0041 put +dup 5 /C0042 put +dup 6 /C0044 put +dup 7 /C0045 put +dup 8 /C0046 put +dup 9 /C0047 put +dup 10 /C0049 put +dup 11 /C0050 put +dup 12 /C0051 put +dup 13 /C0053 put +dup 14 /C0054 put +dup 15 /C0056 put +dup 16 /C0057 put +dup 17 /C0058 put +dup 18 /C0065 put +dup 19 /C0066 put +dup 20 /C0067 put +dup 21 /C0068 put +dup 22 /C0069 put +dup 23 /C0070 put +dup 24 /C0072 put +dup 25 /C0073 put +dup 26 /C0076 put +dup 27 /C0077 put +dup 28 /C0078 put +dup 29 /C0079 put +dup 30 /C0080 put +dup 31 /C0082 put +dup 32 /C0083 put +dup 33 /C0084 put +dup 34 /C0085 put +dup 35 /C0086 put +dup 36 /C0087 put +dup 37 /C0088 put +dup 38 /C0095 put +dup 39 /C0097 put +dup 40 /C0098 put +dup 41 /C0099 put +dup 42 /C0100 put +dup 43 /C0101 put +dup 44 /C0102 put +dup 45 /C0103 put +dup 46 /C0104 put +dup 47 /C0105 put +dup 48 /C0107 put +dup 49 /C0108 put +dup 50 /C0109 put +dup 51 /C0110 put +dup 52 /C0111 put +dup 53 /C0112 put +dup 54 /C0113 put +dup 55 /C0114 put +dup 56 /C0115 put +dup 57 /C0116 put +dup 58 /C0117 put +dup 59 /C0118 put +dup 60 /C0119 put +dup 61 /C0120 put +dup 62 /C0121 put +dup 63 /C0122 put +dup 64 /C0127 put +dup 65 /C0262 put +readonly def +/FontBBox [-25 -256 978 739] readonly def +currentdict end +currentfile eexec +D9D66F633B846A989B9974B0179FC6CC445BC7C8A959A39A32E9DCE7FAEF17EE3BEC9F +50E1A6FCA651FC4B3769A0A91041557502E25A5D6180FE25A3D11BF079E1DF66E54EE9B7C229AF891739707A2A0EC140306B5E43E52B79BFB89E459E50 +6EC6F610A70775A31C460976C4F79449D86E57ACE491E5C6BF20CC4307B1DAF7630252 +E9AF8CFB69B50EDAE9D36A6104AFEF8832F920FD2346B2C7104CD11E3BEE999CFA9F5A +49DB3173EE48D1C82994237F360407B022E0B4 +502E94EA8B493651EF2D03F0B513D655047568325B512AE6 +6AC6F53F3848CF70DE25481CC65D8B1A5793AA +3C4282D111112BEE28AFCA7A3808D4444C4669CA +84EAAAF989219F51AB3476A1B0B5F2246BC306E6 +625C6679C417ED2A8E9BD010DE37D40265074C26842243E0EC59344CEF369650A037B4383B03D6 +24C306E87EFDD4775EC78742 +FEFCE44B765574466C +D1AF7A82 +CFE19FEC07055171803BE35FB61F +DFA5A4C739A4E3957EB7C66233844AC51A6A91B45B75E6AF1F76779A4EA39D554C671F039F6EA0902EEABC13363BDDA5101CA12BB8156EEC5AF0BF9E6FFD41E3E8297895E1554F57314DE5E5E70C32DA47FD30A8525D7EE9C60607EDB6FD9F816BBA9417276F85 +60F5DDB4 +A3948B33EB22B827DF681DBB19 +2993B553C6D17076B4B9FB193A79C8A36EECD5D4EF0F532434292DEF98BC0B7ED78FD8401CBE88325807A34B9ECE7D312908B2BD6A5654090DB46D637406668C +51FF586B +0A455727C3D821E5379B18E7CF +73A0BE843CB8405CC41A75A80486DF95591401AB247D9FBAAEE6F1EE55AFCAB16739F92C17F9DC431730A8479507AFD959AC919F6A16978CDD4C0D1467D6E1 +3962DC2A +ECE603DBF7471294ADD2CD198B29 +532908C4A5265A4F7463ECD59BDA55D34C6AA46EBBA99B417F5C4CD907F121DF03F7B4022701EF74B81B2976C86ACFF955A578ADD8B8A97FF7153E5024C1D16EEC46C49C8161E80908F674E4D982B7EE838816E34B470B4298AA950F91C73847AE513BD928E1AC3BB5B7EC545CAF8549F9A3D3C651CE098F8CBD3CA1DAC9 +B1EA +D11F53F29E6836D3D5B28564CAE639322DFBC99C4E0935BDAE765952B70D50A54E0B2320B66020301960FC76B867FA85F1F91F3294F083E3684814E3217F04 +B35EBE6D +59D242D66DC9B47E498861F1B9 +AAF83F392F47301340B2D0140EEA5DCE2DE473CDED42721C28ED10E828D7462071F4C869EADB5FDA241C9F6B88C7744E9D23B7F683955DCBF3 +2808157E +5A2C0B65F9B55DBBEE9817433A +4A9F9F198E614C01252236B914EF3FE167C3100A365ACD +4E9D860B +9E5A27D0C7D642C02589D2681F +CADC8E04DBBC6A6D75BB48BE19C98FD7B13D35219F0ABF7ABC0CEE8171435A +9A1ED3F2 +6DA67504D01AE8AA9681BB9F60 +DAFE125817E7CBEED49DFE97495620A55FABD9CED68A6C27523597E3 +86E2EF82 +831A62D458C63DC9F33229A3A1 +A11491A2672B640A71D002D9774D3DF90E77813907688E5B9FA24480B405C0764ACE7C5796CCF5AEC5FC93D2DA95819F4B572634A73D9FC9CB0C8EB2E9159A +FC5F6B1E +EEF3ACF4BA76ACD44AF08B39D7 +383D271340F68E0617D3F60E750C3862A683D25BFD8B51F4B80682CA4D20976CF415F3CABAA19AEB7240A4E20459CA6AA7539D36E32E07A3C5FCEED70B78FD24C528C5CCAC179AA5AFF7F6D5EC73B17529BDFD3CB2B12ACAA339 +9D4F9241 +29C6F0FADD6A0B734E610E649AA4 +B5498ED75C036DA814B85B968344FAF5BC7E09E0A5E8A8B5739D16C9D9A5D9119B2FF2658F266BFB6764291D639E04B6617F07AB3E8E9BD7D3E3BA420267C2D668435D31687279AA58126132AC59A1B696AA7E8271B8B2C58D78EE24D42180F73ADC48DCA47AC7A6E028CC09E2993D +6845AEC3 +8B773FBABAE54E4333E0EFC7FA +91D2E9ABFF0EF08E1225C8B6D4821808ACC7E6F2158D1A673078082B5093534288E0A164C72BC20E0E7D02A03568647401D40024A2D918D330267358FE7001FDAC5A9084A3C219051A79D1313218C6A33F7AD20C78BF720CC3BEE186A269FBC856 +F0FA2833 +D1DC4729E39195D621ED519A5898 +A31DA17324AEF776EF9AFD365B3903B4EEFC10B3E3F87ED9F27AF3C5F90915C401A59D4CDCAD781401D0CB59C73A2BD6751E6C5DC224A55EC6AA362906FE23295A2B9B9C7FBAA3513A2D67A1CF1C2D59F8558D354DE0896E93D2AADBF7A0CFBEE3916ED4 +273E7B2C +79A152BB8AA8EE640212B985BB2D +00197AEE85CE3FEE3B5192DBC8D119AD93F18C99DC31096F9EF504E8AA41F8B2097E76045004B8719117EF1DC0B9E821A1CA74F7BFDB94B8314E5ADC7F3DBC5E5504353710C9EB9AFFC4AD969FBF9AA7583607D6556482FE3B7526E68CF65BC7F144F7AFCD5F768F3EB3774AB8DA57F07591B1893495EDD3A9E3 +FAC8D2E3 +92DF721D909D4E29EC355E2E1C63 +5618BBFE52B2CB35CF5F9CBB77BD79D513C4AA76AD80E69F17F992683B97033A72A9E6DC45162A8E76320325E01E7DBF08EED796314CA12639BB3F828340D062714CF2369B22DB3491AF702A07E2FF4BB7E6F7C15AE0B7E9032EEE1C3790F84E93BC1738F0 +76FB19B8 +FFBD506A628A2A9219AB9B7BC8 +F7037F43E7F8F256A9F373B7277F62EF83FC03200A32DF64DEB6EB236D21667EC3C91FD8F45BC401F709764162833D98AAE1AE196685 +01BF7B46 +038314DCE6A7F4ACF4EEAD68F99F +8E35E5A83775D299EB215CE703424FB94DF1832E390FA52C43D0BB486DDA7F4EE50EFD4C692834AD05B19BE96BBA0E1F265BBBA10DF5629E4E3A2EBD54A214FF4DB8238FF2AEBAB1215D9E23BB0236B7E9D4F4979E752C687ECB5C611D686FCC596ACCF362E818C55AD479CDB87014A7CAC6E3 +0EB21EAB +2DF7F4A822FCB8C7C9B27E5CF1C6 +CDFE4C69713C7AD5CBB146C022AB8D6CF0E0BAC10B68973B6E1849A749491471209EDE8D0B183CEE215231211E138EBE1F2E2498CD94156D2F8D9E2E54E3D7F12C6FD88A95D836308388E2B919B2D5064F43A14DBEBC568B559822C1F6A10AE2588BCB15DF7828B09FB6F5AD1828AD866B5903C4D10E6245CB80D2EA25F3 +3730 +2F +2B74D680 +8D3EC25A9DC98835F6552CECF6 +3C84F805E28742A762E1E989539A23296A86ACB4AFFAEB235A7C0C45F541536387BA70CDD80CD1DF87B145C039128E5AE364263E8B2D63A5B30A8BA08B452C61A1A54FE3A3E81A0AA39FFFAF2403907A72349D62D774340C9E44ED52DBF01FF083 +F3166B76 +7F23E8521A9B829FB2B9F7C291 +641E6625BB48E36F4E58F30022E71496264B543A25B26D51E59C49DD7120CF697524C3145C5A251D95FA02B751BA83687F9D4AACEB824C198AB80ED5F9D54D314DA5F34AE23047568776A1F8CAB3289DF4CE56ED186A48A43B0EB748F6E2EA0F86BB88 +45B13BEA +287701D9BB145B0EDC1290BBC0B7 +63C1FEA3E825B8A70D1DCFF4E1659858795EFC9E0F445D0FB5B20F5832845C7D4D9457E45B49FC47448C2D0132E6EB9A51B4A4B8423F1A497A6699DBFFA9CF8DBE7F54409ADE32C953D7CC78C57CFAEF7D09042784D57BA5B64F1F8D27799A5E3E1661A14E7D7D33FFB0702736AF1BBB141EB1F0EA7044C5AD5556D4800E +5FF315AA +16E9D9888A28F6C990F8EAFEE102 +D755AB6AA597B39D62A572A8274B3E49436C82DC358D9C6BA0A9BB243BAD44C0F3BD8310D5EE6C65ACD8CCE0CA8353C1FFFE62C174D2E720CB1757D476AB7FCBC759E3A89424190F60CC311C0F8E033819299655186BED24A8D551EBD50EFF4A19E5CD0AF5A44ED5D2 +FE1F222F +F748B9F40289F88D0A3A8C2AEBE2 +6D3157EE2F61637025F2B01DCAF7AA58A9353E321231E02B1E13A7F26BD813C76DBEF60ABBBE2462297910BDE018B4B2FC28C1F4DAC9187C2DB0A1F3A1592F5F197D167DF02BA9D5260612B37273AA231216D8F409AFFAB7C8DACE8F4304068FDABC196F053D7FCBD4B7E86B1BBE0479CF42BDD9BE8D76524FBCB76A3E81 +E7CB +BA3E49D8DCDDA2A8FE0542 +BFF5F99D +153F93745728B9EF940227CD94 +D475968AF7B8483FE408C987647EB2D397A6EC8DAD9AD9835126D897FC845BAE1ADF32843D5361E51457BB4A83BB124397307925860B9F96D6CBBD +6E4F4ECE +451F14FCB9EEB9582D6AB7EDE2 +DE6A51B6386C816982E8DE26A7AD48A5EB3CFAA3D0A24B0121F154BCACFDAA9337FE41FE190D0B645BE6D4779155CA5EDF453AE07C08252D75B3605FD4C12B7A80C6F8AEB54361 +CD7C0EB5 +02F91DE01E10986EE4706F7366B3 +855C49CB248B053B429D527D4E24A7663C1B9B9D232D3C2E2F53E2166C6E6F1991934C072A0F3155C4D538A56036F089C18EC30674CF8324D100F80B4FE8ABD1DF48049C2154AB838EBADB0CCB9C800E371C4DEC23F35B1AF5CBD44B12BE7845F7CF2778B5E0921D580DD2AE19DCF2 +02C11947 +637B39CA51ADE3A8990980EEF2 +7FF33ACBC09C415BB8AADF0BC5CC4151B9AE4628CDC95939366F46A0BF82FC8DE826060C881A9FDEB56C7657B97C9D89EB64CF3108174D79FACCB99497529B50C3A7E81D80637132ACD7FC31BB5315FD86BFE8A2CBB37773D417B42E +6C947269 +058F68900A460E7048D3E9908B +59DB3B35B7F433613CBE7C8D5695B9EE0EE6902B44ED84AEBF99448C47207A0DFCF5B4183F8DD070D45D8F7378E429AB4DD9C49130A3DF12D2787007BEE8BEFB36EBE512DF011564FCCD188CA27873AFCE2A62 +F205E33D +1F8825A20E9540806AE64041F97A +726D270842ED91FC2D52CF0143BCCC947F5320382B56E6846FDC2C94B851C6D7F64AD26609B458FDDD635B7AE8E5A4F09C0E407708EE69AA62DA548EA43FB95CD8EA8C6FF834D1470E65A16EA91F81D08946D8162C24F2E3E1C2ABFEF65CD076551DB6139DFB8AD4CAC0 +CCFA61F8 +AF4F6461218261B2F1B79B21BD4D +D57414958486BB59E412201F65A456D3CB0FC0437FE2438A0CFF13782224C1561A0DA8932D1AD8A70B0AA6A6B811FC6D7A5A2EC9D9B0C26D5FFD24D3AB9DBAF50C28C2E4B9F82365FFFF9E179A0256DCDF9C102CA611152A16D0AD88DE9020F38C455988C75D0625CD0797B143A4B5EE365FE29FE88F747B2735B299AEAB +3BCCFEF3 +3D54F84411B52DD4AF0FF72B68B2 +C84DB441DB61E190E89FE54B371E35724114EE539E82EF76D3EF37903EEF76E474226484A3C4465A7486B06273FB1F9E6133643D8D01E85B2E5A97073EC69FE26BDB9C3FD56BE2A9D5D2D0A4B78139FC6739ABD90C7FBEFDF34EA918CD66B0686E2AA6F37DB10755B6EDBDDEE17BDD54648DCFDE9DECADFDB89C92D4CA33 +649C +8ED86D +06F23054 +0811E19A2FE080472DD27C8018 +BECD829A5B4D65DA30B76E854FCDE8245EEDA84157E486132BDAC65366D4BF54D55F8FD59BD02AEE44CC04A13D73B19D2C6DCA8BA7FBE20399386CFF443DAE3102BAECADBE3D3AE01F59BA2540B86C6B65 +43586BC9 +E7B9C75A636B8BE1E2DD05D3FB30 +54DFF46F2931F0A265BBD8D2A9985A4E56A5F03AF18A2AC439F205EA594F97F627D9758CC6D85951062B4D0A241E7ACAFAA27842D5379DE07A488B20EEE5E06FF3358E2BD16B5516A189AE6118E1AFB116F1D314589113D1AD26E0B02FDD0482C6BBF8D2 +5D8D6B40 +4F157B9552178C457AA496FE37 +B34D462EE89C6BEF8D00A5AC389DCE596E022E32ECD827C8E26CE1E92201856368BF5D94B73355702A27F87054B64B8F52488DC46405D1170475E6537EE7FD618EB2E132DF6547DA4C9A8CF27BE4E181B5754B3DF36F6E2839 +7739F109 +7EF7E9A0CC59304C3DA949C5F2F5 +7D79D8807C1A1BE93F06DBFB3A9295F0BB75BAC8BDC1AE574DB4E15D5D7CA4272F5EF8EF656B58EBA3890A748E35E502B7620B656E2149F267A1573D41DD091C78F1A42F785DA45823F23A55A220D1BA24B79B8F19B68120CF2EC4ED030887A6E6360E5D30E84DD36B679D91C1AC1C9EAFF3420CA68200571186AAC35CE9 +16DE +82B6D9B04BCE52FE92D56272C43FCEAA +E41CCA69 +C356FBF940491579284F2220BD4E +F12017FA5192EEB58003B9C0642605FF2BFFFB7AA4EDDEE3F512149175E9102FF8DEE5C347DAF670EF4641434450DFBEBE0118E716F653D5B01B4B3580B82593C3DA95A941C740336E5DDF3FEB879BAD21F599B1A096077890D8DC5895E62330DCCB0273BDE70C80950EEA2DBEDF75C6E1A7323BC00EB9CE76A67EF26296 +3CC5 +D0005513C858DB8AE0A1B1C0E55697697CDBCCE7CEA6C31FD011F270A222800162A03282D60D2C +1751833A +EABD321D01C729CA4D49B2CC47 +17EACDF3BAEF99940F4D7DF994BAD0F0D9B67F9E75EE +BA5D4B3E +C7F9F23F86BE94F555F033C70649 +34FB530B866FAA83B91DFF4BC53CE22560713B51085CFA837413E7C96D58E10FD9FA15078C4D256C8725F6572AFF76D980A271AA2D1BCD2C47E76D0DBCD25CBF25D5390A7EAEA53AEB550DF1F46B2AD335FD9799040FD3718C95079F622D4FB29370E97F7222BDC9826AE16B296AD734795A46CE3BADB8A064CF999C31C2 +A60F +19F3E7 +AA378684 +402068E0B345AE0AD49A8A1C95 +0D8D2057968CD2AA67A66C2CAA0A88DC62FC36A9A818A207BD745D8C35898207E8379746FD3044810287C8C8D29BCA26AD106C0273FD88E944CF8C23A03B6E6A644D08D5793EC8F4F1CDECD8EF423E8DBC91FAE711C00F0B +90A603EA +D42323BDD996284985F85EA515 +D665F6BE5164AC067D3C3D5D71A4DCAF4B4FAC6EEDA40D168BBB28FA9B512089AA6CCED3BAEE70F49E05175C0099C2A5557C3C23E800E150EF4F43B6A2353DCB729012C071CF0F9B6913D778BE2A67B97CD4 +8BA40C64 +9BF30F4C2B3A7D2B89D942009DF9 +CD5B6E991221107099207F34F7C753169710C3014441D149C3B9A4520BAB0234FEA260311E896BDEF29D2DD98DFEEC01252D44EB22A9C20D74A5AF5DCBFE904CA2304F544D5F1B3AA4275E45899A6CAA4F81485B3A4FE739DB15CF306E6156222F655D58DD27BE687FC9E2EB0FEC +525BEC0C +684A686D9F4218A1BC1029A878 +2D21FC239D6D44003FA85FB6C0933179999E419F9EE36E9BAD197FE4F6EC704AA3F3D6AFCB3E64E47B8CA1E7E91A2E3DC88E9F786A43A3B7AC7B135764FDAC9445F74B03C1DD3337440905A1058E1F3641D61681031AFA6DEB +BAD1334C +8A9F40F68227075274A91F6451 +F6CA0AF35C5108800961BCC4306984EC8D28DFA2F7942754A3A4473095605479AC8EE6938AE7143919247251FA6D94A5002F5DE39471232CE991BF11F00DE8C70114B9BDF89BF4691897E66F3065040D90D34416536292C0C9FE91C5 +8FA0CA49 +212BD4444DC4F6738E963EFAB955 +2ABC4F1439138A5D713AC4229D273175CD42DA166B89CD79D98BD260BBE3D5E0C87BAF60063E76EA51FD50745522A904F46822A629CC637EC75F93499E7C43F5285295E365051C3D9E87CEC5B9FABF7FA27DF485AFB51EA406ADCD31BB113579C962B26F7C1DFCC2276F0A3A373AE5A8D20EF9B6BA9E9F1EC6570F3928D0 +C077 +E4F06D5A8B0BB9ACE77C2C35DE421CE687BB740F846E686CDC604CBC8C13B0804445291BEDBFECEABFACC8BABF9C47 +85CF1AB5 +17A19A4034D51C10C445308B73EB +F4DC5A0606108C0FD64FC11FB972B24A55306DE69F5317A8B83B8171B44B64FEE99240768593A6BEEADC9D3843DE7C4D329F025B3A1360B9EB49F26A1237F419C5F9876C9639427ED2C18B7956FDD99BD14D1E37E4F6EA475FA3BEFA62174337E8319F3D670A81361D8EBD4C38 +A56A919D +6CB786D292CCB7D5C44CA858E8 +2DA35191DB01739EB8A3C26E80187DB3B158DC1BD69597FE14120FD5FD588537FF66C4E2C10963B970B5CFCEB22BAACEC9FFDCD43DA1006B6193A49AA540405577BB2A65C1DC14C71CC979C1CE55832E +A396BC2E +8C9EC143E7961B7DE0CFD9D5522C +EE519304B7A4668A5C0C6D131D879545BD05C8C6FD69D00E8249B9A2E1AB79D75DA908FBDE7D5ADA4FA6B1228CE3CF5C0D0315A30E54BE6DE5B2B426D853003C824C81D963B529FD8550E4B2E543CA5EB94FD24985E635E171B35D4B4C01B01B7768F8E2D60B685EDC8D94E215A0261B1065FD868FA614CA3862DCC676D1 +BDC4 +63A7809A043A5FE373163E103A6E1AA87D633422901B13A4DC85528235292F9D7FC73A +4AFB2D06 +0EBA0B1990141A83D661C6AF98 +B2DACF65E7A1457D067B1F5AA90350E47FFD6674948E58953CA6A5908DA0B7582A6FFB0E50108E299F4B7CC98DEBE18535CCE33A2ECB +AB3C2451 +54B91E6820070DF060754AB92226 +C4DA3F708040A0FD3555DF3677B33891CD80A644EBCA89752818EC2A799834CF0D8EB558D9B92829A3AD0AC3179DD11D2541FC83B25FEA08DF314A18A9274A86FE39DDD44C93E0BA1D0CFD9B4899860A3FB7D63B8457EB575E17707239F5C294202B318334F7C93E863B9AFF93EFD62C91ED4F269FC9E292FDDA33337E26 +5BC9 +B5B339535293C544286DAFBC4F8039BB0920E60198A9333B4F837AC90E7742 +9EA931D6 +96B51DBC2822299EEFEC61B8DECC +065CAE2992D820C09C846AFD9484A844CBF7784DA277F497147146EC63BDB9A89696A63648D0048EA73CA018B72F7C39EF849977957E74EA8D0B93CEDF2C44976C68DCCC90CE6A3D9C695EB340BCE1D2E27BC553B2B45856DBB52BBE1FDB79FF676A1FFA684C9AB1435A4D3B +E22A3FB2 +34F86234F49D9F7429E776E4CA +9D43CA26B94E2E8B0DBFE631A57A17E38E431FB7E346A501A013CAF7D3A58CD3D0AA8A0023188BE48D2541995FDB629B6D698E4C913A1D2B888B8FB41863F40242D025962CD4 +C0CABEE9 +655D03262B62FDF479A62524F7D3 +3DE2C3F29C9260B5EF7AB8E029A7330751C7D914900A895EE2CD390D8CB6F721F3583DE6300BD5A9947FB8FE42AA9F4444CD4E72FE6CD7C5A9FD459E58944F8922F2F0E905DA133F687C11BC362086A763BCC530F0784EA8075B8018FF88347488E16B526422B5715267F1B22FFE93FF144744F9614190 +8C63A244 +2DAE61CB7E2CDA66F9CB8F3BE3CF +03FE0C88151DD414F4FE9E5015E4870B1AEE4D648823735DEBB4F0BA4C936A6A6A9EE852E158585C0EFB9F235BC1970238D5B1D0369CDD8B6C565A8531CF9E7A5938DEA16AEE1A5E3C1B3D68A5E00DD69F01C416E8E18F54185B1B50C84066980CEC7F03EE66E155DC60 +2BF0FCEE +1B0EC3456B049A7BF6A23A6E53 +060729851C1E7CD6ACDBAD696E3FED8B276BE3807B6274BA9E444FDDE127D09044C4B986D8B2769B68B42DB50E62E2D286752BEF97923977703B1402A3D569F6AAEACCE54ADCD9D37EA03FB4B260D9926C1906084F8744 +79624078 +C2AC736D66DEC21F5EDB2470A8B6 +38AC7741832D9F6EF06EE706D68DE2E9C7883A274C3C41E832B639B2731470A1D9D512ED5D29490CBB71612FBAE4477F66DA8940A8536B7FA2F17409B7DFC6E87E28C0E3576F3423DA8487F44DD09F452CCB921A86636067CDF9C349408EF54782A697A03D85E621748DAE47C7F5FF73D68AE406CCE152CB71198566 +31316E76 +8E175C344ED4C430320DE35AC5 +CE15B364AA16381D139E89CEED0B06A781C80184FE61136148D5559C3BC0F8D4AB336FE7B21A6A2A555F74E07FD51C7EF7C2C73642BCC383D5BB02DD0DEE0E9EDD7384585A +6D7C2977 +07CB83F250DD53657B6F3C65AF +CA94D0E8DF073860ED76D0F823DC0774A515F1F1C68F0315F2649489889339E4E8EAC5EAB50AE552E08F3222646A2D7E5B2DE85C3A326B77EE5D544DBD603FBC1357BD8B4864CF53296EA0F63FE5C5B42BFD3CAA4A197BB4A6433351C350884D308E +B28BC146 +BA7400FD8B32E8DC351003DDCF +A7A2678E1AEFBFE6EA53A71F8F328EF77D1C59CF5EF8FEC5D810548B2ED938105C45BB0152DF29F860B6E1047F2D57ED3E29AE0F6FC3B3619F0390B94345210E1C47108E724ED240A7EA4A3E42FB0F7D1801BFCE02F5B28801 +0A62E1F6 +7556A73C69E233AC0745DC03CE3C +79CC277729954859F5BC89F15FC03E433D5D354D4DF51D3C23C96AD5179C66B459DEC578574360C53FAE3EE530DC1301891018716ED3F7BB6ECAD4F836AC708416797A558D3A5A40850C679C29B4474DE78B8A4C36FE972DCC35DBF37085F98E990B1B7F40D71735F0C93FCCD3F1DA7582BD6463B6A5BC718C9E5C3EE854 +E956 +69A3D373505C4CD69EC09818691C +16F6C32C +5FD172FFAA6D491A8236140CE83A +F772E98EFC0CB1817A21046FB3A500CA7FEA1BAD0CA01E3CAA4E7D8BE5BD97C1BB9CD654A5C577A12B6A2E4ECF6E4EB00D80F8BB7A65AF441A759C79C470B37AA068B53DEB8587B32E800D74946EC0EF010C6F93E37367309522098EC5CCA02887EB3052CED59B69CDC9E31A7716D45603768C6E4168CED1C559979DFEEB +6AA0 +C64387B1FE7D2B14B7E406FDC9466049BCC97019D55548A45F +0DFFF699 +30DE1F7E1CB0C5315D7B89C00F6B +704D3CBC6EA786F9069806D2F440FF3397B1D748B91CAB8D141735230FDBB093D7D0C76B68C1BC754239A6D59F9E470F7BDCDEDE75D2024B2D0E1DB72FB6FD5DC9A679748CE24A43906426871CC426471E446A1085A19A18293DE4D87BCCB9EFB3F553709E0F998A5C2E31D5A6394E09FFDF0978B518EC6197C8DC2A40E3 +268A +4FD8F3FA +9A45D83E961D4196F24D54A2CA +B96E83FFB82B93ECE6172EE7593ECB1DA7068A2EBE0423320A64A22EC67FD972F2079583A52AA9651C5ECE70D6E204FB792E0FB85D32DDAEF748D7FDBA1331 +888793A2 +B07BFF0840E312F97A30FDA8DE67 +7CCA20E1FF1CB5BBE29461D0137E5C2DA7B1C54F43D0899CAC20937BA91C39685F757D1E1F62194320F8B97BBA262BF889A7354C934E96DD86B500D3AC6561F14A24A61DB7A604B7ECF61D32385E47050AB5AF24ACE2ECEC05CA22B6E2C40D3FBC0F4B6E6DDC858127 +B58F7FAF +29BA04FEB0A03611CAA6B6B837 +1E23402A527C474925B1BC464C9C0C5100C230B2F028 +EB07EA9F +BC7D6FBA861A286590B8109E5B29 +1B20B8571113A557 +B79CF9AB +47D5A3FD5A398DD7847D7E686216DC3D909DF26F1D95696A36EBF17393992F727CA8 +0E3B3A614B794411632F75950BFBF486D0FF6B8BF18F49995EA30005FE4B5E573CCB4464E1B6 +8C96ADDD20CB675CDF04F6AC6BC38F9578580E16B15FEF08724ED0 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +%Defining font PSOwstdutchb +%!FontType1-1.0: PSOwstdutchb +10 dict begin +/FontName /PSOwstdutchb def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001000 0 0 0.001000 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 1 /C0032 put +dup 2 /C0046 put +dup 3 /C0057 put +dup 4 /C0067 put +dup 5 /C0070 put +dup 6 /C0078 put +dup 7 /C0082 put +dup 8 /C0083 put +dup 9 /C0097 put +dup 10 /C0099 put +dup 11 /C0100 put +dup 12 /C0101 put +dup 13 /C0102 put +dup 14 /C0103 put +dup 15 /C0104 put +dup 16 /C0105 put +dup 17 /C0108 put +dup 18 /C0110 put +dup 19 /C0111 put +dup 20 /C0112 put +dup 21 /C0114 put +dup 22 /C0115 put +dup 23 /C0116 put +dup 24 /C0120 put +readonly def +/FontBBox [0 -209 715 694] readonly def +currentdict end +currentfile eexec +D9D66F633B846A989B9974B0179FC6CC445BC7C8A959A39A32E9DCE7FAEF17EE3BEC9F +50E1A6FCA651FC4B3769A0A91041557502E25A5D6180FE25A3D11BF079E1DF66E54EE9B7C229AF891739707A2A0EC140306B5E43E52B79BFB89E459E50 +6EC6F610A70775A31C460976C4F79449D86E57ACE491E5C6BF20CC4307B1DAF7630252 +E9AF8CFB69B50EDAE9D36A6104AFEF8832F920FD2346B2C7104CD11E3BEE999CFA9F5A +49DB3173EE48D1C82994237F360407B022E0B4 +502E94EA8B493651EF2D03F0B513D655047568325B512AE6 +6AC6F53F3848CF70DE25481CC65D8B1A5793AA +3C4282D111112BEE28AFCA7A3808D4444C4669CA +84EAAAF989219F51AB3476A1B0B5F2246BC306E6 +625C6679C417ED2A8E9BD010DE37D40265074C2684269A711773B1F062EFDCE93198A765F8F55A +6E9F60B43AD213B6F99675D4 +AE976E2319012DB96B +33CB37FC +2AB7CB1AA9E7C6D1A60ECC1036 +78173A5EDBFA71F1EBD0C032CCD138B6D4CE66801DCDFEB6BD820A11ED36DC +8E4D3CFC +9B74D73542067C526069B30732E5 +02C92D350773A0F13043F7E7F2FD2365C811B111DED6308425424425C85ED4ECF83DAD9A69D6DC0B326B66D5D60982C25F797415E5E04295D8B828016AC3492B7C9BE617E2746AF2E9524DCD33945DC65D94B2E03D0D7132593EDC67A4B202AC870EF1C6 +EA790287 +4ACB5F56FD4DA68D1640355195B9 +D19C7961DAA79000D46EC3F291DA2E2B19AC6CB630B105E3E139E919879E8148C655BF27873C24022B33089612C488CE90E254D1C75FC36BDA12D0337B32C607E50DA16554C04792537EC2195E8067DC19C334EBDA274F00D80EC09D7C5680830F0E24D8ED6CC9A2 +CDFB04E2 +F1D7FD17DD5859F41867D88DDEAE +F972E7B75655A7EEA90B92DB316D0AB4FDD399BB32238B9E4688EE8C20691903DEE3D1451C039DD31C343F7682C59755FA7FA00427CC66B6562819461DFCD383676BA230FE8114C0F6365C8772EB875812A04739463F555EE16444668E4BC3F9E48F33F9 +84A5F175 +1078182F3769E7DA175252997B +2568FB7D85FD2C70D74F49F31AC69728A7E7806320E4D2A2EED163FDE8C3C12EC79CCC641DBD1A0184767D1798755315ED1A73A0CACCD82BF33B046799C70F9961C8203B70A351C8CB598F46979CB8D30696E7567DA60991E086229D633F50 +AF9D3DB8 +F88199AF8EEDC512846E9B90F80A +589C2C8EC2753CD984DD1BED6A124E9C30F029F74409D4B6E4D5516D1A212760A1D8EC8E0F523F3D7118D544ED5D2E7D065E4188522C6EF0543B93418A0C0CB8748797D2D93B833C6D8937BE7B8E6EE84798DF94C79ACD39D833C1F2950621E4ABD6C7B130A550E5B7FA15FAFC9B91FE1C4A587DFF +C2216DB2 +7AD57432AE38A5E51AA5C686F4E4 +A3F2972342A4532DECBFFD348DDFE4DD94B83D8B240B3E175F74B71CDD392C03B790CD66EC1E9B41270145FCF3EDB18398C3DF34042C4A1874D1EAC6571F82E9A522DA7BC5ED67F00DE6EB58342A68E1F94A79FE2C28FD6F36A1816F44AE8F565C14EDD8C44C7CA3C88D99179B575BD9DC636C306EDF16D3B3AA371DDE8D +1BB7 +ADEC51A3 +59BFDF8FFE0CC683D4F18112638E +A01C20D513AE1F5580EE472FAAF1B03ACA13467A4C42B48B36236FE41ACE7C397D63E3529095128D2B06EA5A24485C1643041BCA34E8505BD643242D76047FEA68164AB94008A92B23F9649D8043B76C1835635F69BDA3E3B529AD98E536DBBE024F0B223CC3AF23894EEF424FFDD0F238451923FC4DFEF33EEF67D4A6AB +5368 +2FB7B1BC +540FEC10 +2478563963D6819A331C8A74C4 +C04BE75C535D087ACD08BA9929787CD850B28DB74E91EC44DA52C5C7FE35DE7A9481D6183EDE26B5F78E0565ACA86923C5EF1496E949C20D42583D072C7D507EF1F7A0FFBE53953926265B35FD57E6CF04CF +39416408 +2ADC436C05380E2DEE010904CD90 +19197ED80F88FB77D5AD65074AD5CC7EE4952F5DBCE2D8C3B2F6F9A396A2BFB1FFAED18FD99CFA4F9BF584B0B03CD5B7F3EA9B9416F99A6A829E3D5E6E7AEB82D25A325F3C3BF4C1F2C36B186EEA532F1F1C92A14DAF091F30F726FB08DC3B26D674AE9F083BB524AAD6C6A9 +7DED5BAF +2F25FA45C7A5A3497418D42CFE +278CA686C81C9B31846D489A1386E187E0BDAA6B70CD4BB0FE4159F4C603242CA4B6FB84432A6DD3F03181467A42274EE0BC1CC0ECBE9874850EEBA57F73625743E0876519E58598867C2BFB7E099525EB32AE513C3BF144597D15FF +30B2115C +CFD2BF0EC93954424D6005BEEF +F3FA45A31AD5D191B752E443EF4E49D73C4D2DA5965FB604FA420566800ACD1C23568A1DA699366F1BEFFBAA1B96BEE742615C35067A2993A8329B2195D98FA3C1AEE9C7AA682C807B905CCD0D9EDD74A47A044D257F66ABC668D433F0 +50FCBB53 +21316979E17843EF143F344A4039 +51D22E3EB801C487CB542C25982CF04DFB4822F43618099A5E71A1E64C89807F04487FF5BDF2868ABC0CA443E56725377B6CEB6483D051A77888771DA8F15E1777F456FD4739DD978267607649A9DFA277E1EFC211C4A6E3F3D7727C7F3C9295F7CC27310DF95B3677664F525D5661221B1B7308295FF9EEC6EFD9189063 +9E0D +A509F0F2E3E48BCCA290A0FCB36D5B423EF1528A11019199167D0F71E25D84EB98A3C413B5 +9E2BA323 +A923A870A35109860F4D47A8648A +567A8955A2FE005E0530B0AD0057623C914ADA537F2B932CD004DBC3E0F24B7EB2E5ED99A2806DC2B35817F5627B5F1FAC5585FEB3F96DB525C2224F93589283DFDB010743C9705681C54935D228D82A33AB5B474EB17582A3B44F5A142FDE139195DA134996B672 +5BA3D91D +890A8440802C20FEB7F7DEFB9C +EC1E1B34CED42F495E2B1059C5A1586CCF8695E90054214835D6ED160D8F16D5B1B72BFB78A50B7A0EE7B20CD11C169F5E44A839C5774146DD15750AC584D0BDF110DBFD46347D8246412F94B14D +1911F49C +EEC492B712CF628F8C6E7C7CF2 +E2432A65173F58D8CA845F26DD88A3EA3DB53ED5E8B831A0DF9869ABB9C809945D896590AFF7D0606B2196DA86C04E3736797006 +C052AE29 +DFFD1C5446BD6E2C5022049F99B8 +40F337BE2662887E0A9531433DF39F976CCB416754CEAF1DAFC0A8BD14708F7C39DBC04D0A9253EBB9F6F28ECB726946097B2F6428D57503238FF12E4C7096A26AB022A14F0540AC83820140F93017D23D19B5A583F83651FCE2114B049AD10CD310ED27C36D48 +ABD590A2 +8EF65DBE3B9694FE475C26A601 +78B8E8F8B06EC441260624A13D5593036331D8200EC3BFDFE252E6C65F2E6B9E1EEDC3DCF7512EFC5466A72CE365AACB07175CF8347BC1C24580918FBCFBE68CAFC95FE03D65 +8FA95D48 +EA14D9C336B98EE1FEAAD7B363AA +EF5CA4DAA15A9140A65715254B8C55F9FBE3426796777A2A1374B48894AE3B3664AB4D857315902FE76017FCF277024F23CB82BFBE5963C66364F2B573E6530094858A4B6163CF23FE771B8E3B11DA085A8DB5F93E7C4FE85F50F690E0C6E4008476E12789EF4FB2408EE7E1EBADDE1D0A +31CC4AEF +3B49F8FB801CA6CD12E72C2ADE +CBAC1F0DA0392BCE13FFE68E74C44483E55C11E5CFCEABE0AC5264CF452366B3F8066768993FD7117726514E086C6F1B898B075DCC02BB1AC6E5E3063FEF1BD2CB88E52B65265399E6AAF2321B26BF58CA59D11C9B63B8F845 +CB60C637 +EC1DA68F34A634AE58CDAE0B7073 +90C2CBC0092CFDB1727D8ED58DCF28049030F7F442F39DEA20DA53B0C3D0C503A0DBD8F7CB86119D2FF4A5F662D353EBC707307F0EF4BE68961CA19397C6D5BB0B7D1F910003B5784CD828F83FFCDF6B01AE52E0620F63AFD728A652674B3B28F43E4CF5D2AF9E151B98D1B6A77811DEFEC0CF4DE2B81930C1 +B2DB7833 +C3F179A2746456F88DF684DB64 +D969015B39C2C9E7F487F62E3FD9CCD4F8AFE44E581477434166D1362A539D749DC8315A289AD2AAB3455A25CCC901BBCBE6DE22DC914BFF13B9834608D2DBC11F656CAA +8CF126A3 +A2089A73940C5E0A05B4731ACC17 +C5615AD087E001889B18814A0EF270A7811B7CB515DEF989B176645D69B21A81058FE40242ECF62506D9E609A50B6B653476249BA25E68CCAD7DB94E3EB1B60C84F2285AE70AA82B05496B137172829351358B3BB02476251625A959B48C6C87AC1823C645AF3BC31C5D9E283090C7E540BF76E6F08B3E81FBBF0A1D1BBC +9D12 +59390D3857F901118DCC3899E91A165008B60FB2F0D8 +1D8E191B +AEBEDEF371A43E2ABE37C603C44D +8AEA1F98A14D29BF +4C820C63 +720179C0DEF39969607D44D464D7ACCFDF2E727D9EF4FA89BDC5891EF0F5DADA689C +EBC3315EC4165BD9AC8AE4EB6E474A319315A70AAC62A73D408563C0996C973082BAFFBB860A +C813795005FB043A7FF2E24B1E5DD47858278B08DFE39A1DAA7F4E +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +%Defining font PSOsymclas +%!FontType1-1.0: PSOsymclas +10 dict begin +/FontName /PSOsymclas def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001000 0 0 0.001000 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 1 /C0069 put +dup 2 /C0083 put +readonly def +/FontBBox [50 45 775 713] readonly def +currentdict end +currentfile eexec +D9D66F633B846A989B9974B0179FC6CC445BC7C8A959A39A32E9DCE7FAEF17EE3BEC9F +50E1A6FCA651FC4B3769A0A91041557502E25A5D6180FE25A3D11BF079E1DF66E54EE9B7C229AF891739707A2A0EC140306B5E43E52B79BFB89E459E50 +6EC6F610A70775A31C460976C4F79449D86E57ACE491E5C6BF20CC4307B1DAF7630252 +E9AF8CFB69B50EDAE9D36A6104AFEF8832F920FD2346B2C7104CD11E3BEE999CFA9F5A +49DB3173EE48D1C82994237F360407B022E0B4 +502E94EA8B493651EF2D03F0B513D655047568325B512AE6 +6AC6F53F3848CF70DE25481CC65D8B1A5793AA +3C4282D111112BEE28AFCA7A3808D4444C4669CA +84EAAAF989219F51AB3476A1B0B5F2246BC306E6 +625C6679C417ED2A8E9BD010DE37D40265074C2684275DD89A8790EAD18EFC77D3FFAE84DA5D +312074C4D542DD5BEC70968F75DC +250C3954E8DFB8F4857BFEF092EBA49D248955A858C5A5F55F7B987EA06EC8428D939084C88F5B157D80AB2D706A7EB936C3429173588D2ABA6A27DC94C0B484F316663555797004CBFA79E7B8545C810BF9CA92F61ABD9E202ED9E95943DF7A5ABBF3C20BDE3B6EEC9C0B95A4C9C1D38AA7C6786ADBBB79EE183BDDF194 +1953 +6449DBB7AE47E9FC6F3ABF1DCD7A1E274E87DAE9 +A22737FA +6404B215A27BFAF6D0B50E94D2 +07123A5BB380C86DB5033EE743181BBFCC0356571F7297A207C23F1E588257FDEF5DF229 +CABF3B3C +9E0988C63B358ACA4B4FEB033DFB +E2E387A06A23CACA +8E104B90 +DFDBD41F063E8A8DFA0ABA4DD7443015526AE5255315597779E04D85849305EA4F31 +5CDAD06E5841E1B8074760C99702B8CF443D752174D996C94E690797A9587CF5017DEB11E5FE +02576E9E08B39688BBE99A186AA8FC7E222F5E52B29A7FDF379EF5 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +/DPIx 1270 def /DPIy 1270 def +72 DPIx div 72 DPIy div neg scale +0 -13970 translate +1.00 1.00 scale +/wst:dutch12 12.00 /PSOwstdutch newFont def +/sym:clas12 12.00 /PSOsymclas newFont def +/wst:dutch14b 14.00 /PSOwstdutchb newFont def +/wst:dutch10 10.00 /PSOwstdutch newFont def +/wst:dutch14 14.00 /PSOwstdutch newFont def +%%IncludeResource: font Helvetica +/wst:helvps10 10.00 /Helvetica /wst:helvps ILEncoding 0 declareNFont def +/sym:clas10 10.00 /PSOsymclas newFont def +%%EndPageSetup +GS +0 13978 10801 13978 10801 0 0 0 clp +wst:dutch14 SF +0.00 0.00 0.00 1.00 setcmykcolor +<1c2b39352b372c11011201132b33292e32273730012c3437011b2b27383a372f332d011c2b393c343730011e> 2207 558 0 7384 -1 s +<2b372c3437322733292b> 7375 558 0 8593 -1 s +wst:dutch10 SF +<0b0f> 9346 13300 0 9522 -1 s +wst:helvps10 SF +<4e6574706572663a> 1322 13280 0 1949 -1 s +<205265766973696f6e20322e313b20436f7079726967687420> 1949 13280 4 3868 32 s +sym:clas10 SF +<01> 3868 13280 0 4019 -1 s +wst:helvps10 SF +<2031393933b131393935204865776c657474b15061636b61726420436f6d70616e79> 4019 13280 3 7133 32 s +wst:dutch14b SF +<080c0a17101312> 1271 1458 0 2055 -1 s +<00030200040f09120e0c160009120b000510180c1600101200170f10160007> 2055 1458 7 5338 0 s +<0c110c09160c00130d00060c17140c150d> 5334 1458 2 7109 0 s +wst:dutch12 SF +<1f> 1271 2086 0 1434 -1 s +<2b3b2f382f3433> 1426 2086 0 2056 -1 s +<000b080a00342c00332b39352b372c0029343339272f333800392e2b002c343131343c2f332d00292e27332d2b380027332a002c2f3d2b3811> 2056 2086 9 7050 0 s +sym:clas12 SF +<02> 1271 2432 0 1359 -1 s +wst:dutch12 SF +<1c2b39352b372c> 1589 2432 0 2298 -1 s +<0033343c00383a35353437393800372b3b2f382f3433000c080d0a00342c> 2298 2432 5 5037 0 s +<00392e2b0024> 5037 2432 2 5663 0 s +<2f332a343c38001c210034352b3727392f332d00383e38392b32000321141e0027332a> 5655 2432 5 9213 0 s +<22151e> 1589 2677 0 2062 -1 s +<00383429302b3900392b383938003433313e040800212e2b003827322b0029342a2b09282f3327372f2b380032273e002729393a2731313e00373a33003a332a2b370024> 2062 2677 11 8326 0 s +<2f332a343c38100d06> 8318 2677 0 9213 -1 s +<283a39> 1589 2922 0 1887 -1 s +<00392e2739002f38003a33392b38392b2a00273800342c00392e2f38003c372f392f332d08> 1887 2922 7 4910 0 s +sym:clas12 SF +<02> 1271 3268 0 1359 -1 s +wst:dutch12 SF +<212e2b> 1589 3268 0 1949 -1 s +<0025211900392b383900383a2f392b002f380033343c0029343235312b392b0027332a00383a35353437392b2a0003273900312b27383900343300181e072225040800212e2f38002f38002c343700252119> 1949 3268 16 9213 0 s +<23> 1589 3513 0 1751 -1 s +<2b37382f3433> 1728 3513 0 2285 -1 s +<000b0800030715151d2625211900293432352f3127392f3433003433313e04> 2285 3513 4 5462 0 s +sym:clas12 SF +<02> 1271 3860 0 1359 -1 s +wst:dutch12 SF +<172f3d2b3800392e27390029273300272c2c2b2939000715222016261a1d1d1e161f00141e22003a392f312f3f27392f343308> 1589 3860 6 6792 0 s +sym:clas12 SF +<02> 1271 4206 0 1359 -1 s +wst:dutch12 SF +<203a3535343739> 1589 4206 0 2319 -1 s +<002c34370021141e0027332a0022151e00343b2b37> 2319 4206 5 4776 0 s +<00191e3b0e0003191e> 4776 4206 2 5702 0 s +<332d04003a382f332d00392e2b0013201500383429302b3938002f33392b372c27292b> 5698 4206 5 9213 0 s +<030715151d26191e230e> 1589 4451 0 2944 -1 s +<00293432352f3127392f3433003433313e04> 2944 4451 2 4595 0 s +sym:clas12 SF +<02> 1271 4798 0 1359 -1 s +wst:dutch12 SF +<143432352f312b37> 1589 4798 0 2447 -1 s +<00383a3535343739002c3437002700403134332d003134332d02002a27392700393e352b002f38003433313e00372b363a2f372b2a002c3437000715222016261e2021> 2447 4798 12 8469 0 s +<12> 8449 4798 0 8612 -1 s +<2100293432> 8592 4798 1 9143 0 s +<41> 9143 4798 0 9213 -1 s +<352f3127392f3433> 1589 5043 0 2285 -1 s +<00343300181e07222508> 2285 5043 2 3492 0 s +sym:clas12 SF +<02> 1271 5389 0 1359 -1 s +wst:dutch12 SF +<212e2b> 1589 5389 0 1949 -1 s +<00273333343927392b2a> 1949 5389 1 2904 0 s +<002b3d273235312b38002f3300392e2b003227333a27310027372b003334003134332d2b37002f3235312b322b33392b2a003c2f392e003829372b2b33002a3a32353806> 2904 5389 11 9213 0 s +<3227302f332d> 1589 5634 0 2255 -1 s +<00392e2b003227333a27310005323a292e050038322731312b3708> 2255 5634 4 4857 0 s +GR +eop +%%PageTrailer +%%PageResources: font Helvetica +%%PageProcessColors: Black +%%PageCustomColors: +%%Page: (29) 29 +%%PageResources: (atend) +%%PageProcessColors: (atend) +%%PageCustomColors: (atend) +%%BeginPageSetup +bop +%Defining font PSOwstdutch +%!FontType1-1.0: PSOwstdutch +10 dict begin +/FontName /PSOwstdutch def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001000 0 0 0.001000 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 1 /C0032 put +dup 2 /C0034 put +dup 3 /C0040 put +dup 4 /C0041 put +dup 5 /C0044 put +dup 6 /C0045 put +dup 7 /C0046 put +dup 8 /C0049 put +dup 9 /C0050 put +dup 10 /C0051 put +dup 11 /C0057 put +dup 12 /C0058 put +dup 13 /C0059 put +dup 14 /C0065 put +dup 15 /C0066 put +dup 16 /C0067 put +dup 17 /C0068 put +dup 18 /C0069 put +dup 19 /C0070 put +dup 20 /C0071 put +dup 21 /C0072 put +dup 22 /C0073 put +dup 23 /C0076 put +dup 24 /C0077 put +dup 25 /C0078 put +dup 26 /C0079 put +dup 27 /C0080 put +dup 28 /C0082 put +dup 29 /C0083 put +dup 30 /C0084 put +dup 31 /C0085 put +dup 32 /C0086 put +dup 33 /C0087 put +dup 34 /C0088 put +dup 35 /C0095 put +dup 36 /C0096 put +dup 37 /C0097 put +dup 38 /C0098 put +dup 39 /C0099 put +dup 40 /C0100 put +dup 41 /C0101 put +dup 42 /C0102 put +dup 43 /C0103 put +dup 44 /C0104 put +dup 45 /C0105 put +dup 46 /C0107 put +dup 47 /C0108 put +dup 48 /C0109 put +dup 49 /C0110 put +dup 50 /C0111 put +dup 51 /C0112 put +dup 52 /C0113 put +dup 53 /C0114 put +dup 54 /C0115 put +dup 55 /C0116 put +dup 56 /C0117 put +dup 57 /C0118 put +dup 58 /C0119 put +dup 59 /C0120 put +dup 60 /C0121 put +dup 61 /C0122 put +dup 62 /C0127 put +dup 63 /C0262 put +readonly def +/FontBBox [-25 -256 978 739] readonly def +currentdict end +currentfile eexec +D9D66F633B846A989B9974B0179FC6CC445BC7C8A959A39A32E9DCE7FAEF17EE3BEC9F +50E1A6FCA651FC4B3769A0A91041557502E25A5D6180FE25A3D11BF079E1DF66E54EE9B7C229AF891739707A2A0EC140306B5E43E52B79BFB89E459E50 +6EC6F610A70775A31C460976C4F79449D86E57ACE491E5C6BF20CC4307B1DAF7630252 +E9AF8CFB69B50EDAE9D36A6104AFEF8832F920FD2346B2C7104CD11E3BEE999CFA9F5A +49DB3173EE48D1C82994237F360407B022E0B4 +502E94EA8B493651EF2D03F0B513D655047568325B512AE6 +6AC6F53F3848CF70DE25481CC65D8B1A5793AA +3C4282D111112BEE28AFCA7A3808D4444C4669CA +84EAAAF989219F51AB3476A1B0B5F2246BC306E6 +625C6679C417ED2A8E9BD010DE37D40265074C268422410489591588B6E7823D3D74C2EA32FE93 +9EB88AAB3B591575462F2E96 +55B8435E1419699E83 +41112633 +B0FA1A4EC92787CD7A26A873D7BD +1ECF175AD4EA48B87AEC3ACC8B38E3B38F1DDFC5780D2B090942E997D679A13082F0CF57FA7735299F5C2F7C05FFA5BE30F9B2BE51D6A4A2DE8DA7F543ADEC29BF50B705243FAFB502A8CCB53B9974BF5B4AF682BB3EFE56A659A712EFE75706728F3042834B1A +FBCB223E +715E8F189D9CCA0F2A999CB46D +339DDD22F3E36D5DCD9BFD9D93192A71CC77C169C2E9E0FF074A69B175A02F0359AA907C220A12742A0ED5C86C5C18AD8F4D574A8A575F20F65C2566CF3261C1 +A220D9FA +4E2282C6D36EC7B462DA350A36 +AA9D2D42B90B169DC326628DECD8E60398583B2DF01BA17414C998D8023BFD1C5BAE674D52A4EC038B0A0B61007E60B6116628D956023738954CA5FFBDEA67 +7BB6604B +6EC373A0F09ED3F8A7CEBDEEF8 +7161DE49D60E5794D11CB36B6767D157D47D06DD2649DFDC6330E2D06FAD968EA5EA780C2F135153E697F2893AD2A540D7A089106C63BEF9FD +FBCD2DF1 +B82E952F1D5B9C0725DC7D7B9A +FC3EBCAF3325236BCAFC28BC450510F87C7FAAB0406EE9 +EC7ED22F +C69E69264A83DE707DA35B3929 +6D48E85D1BA70DD207414AB9C9C211E4CB76DD7480BDA8CE8E0389F37D3316 +CFA58A77 +65BC67A4EC92BF79974AFC8AE0 +EDD3B2A7478EA1973CC22D29B88E7499303F91E916E93B42965CCCF1D58BC98B718462378BEC42DA9E0D25A24D183051F7CDEFAE52AA94624E28353AFCDC94 +24E37D1F +A692330685553C8FE72A0BEFE3 +8B588C64EE71665A38CFAAF4709F64D66F292DD42433544430497B82C6E36007B9F5D3E406BE0694B9443CA1B5721EDF103147CEDD380746A2E06C0B1E6162E80D32022396DDADC6AADF68970C49A8FBB49930B38449DEA14774 +CB290189 +4B1EC4DB63567E6B16AEE36FE01A +3E5E6CC43F92DE77009D03DE4730504711B0145910B5A7FF69914E55340EA2C6215C9C38743A8BE7945523D3CB623C9660F9A760359824751ED46E71C264B067075D2A1C2A6E5BF82D317CE810BAF7D00B2EDB74EBAF0536BCDAC5F9C25547CC440D7408FE8DF0E0505F687A196C0E +52EE8707 +D2FDE6AC1CFF53C521080CFA1EFB +2B4F9BECF3ACF942BE912C83FBBA714C052DDFA93105C095BF402F4AC2CB121C7C9E55EC4CE011A1C2184F75DF5A6D683894163421193EB9C9C50BA0AD5930CA1721598C6A7C410D8D16A93B623D4F4CE5B96736D9A021D5B787CDDE3AE638E8AC8C643308 +84B290C0 +5306A686F5AE7397F9B7DE41DE +1B4C25869F8B0B707CF95198351CBFA5E9D0F80B36647ADCD0F59E74874500B130C370A6E37E5C5C9BDA1F64A618FFEFA879EE814540 +F0C7147F +F0D4788E15BE1C9522A87086EA +10A597E1AAF581A5C9056EEFCCCC51E2513C36F065636A6CC161BC709F2BA4678FBF4BE754902B1648B12869A7F519DA62E5C8BE9D63B2A1E7E55B9181BA05B6D45284E07A6789809925AEBB2590E5AA +F28C9C82 +2246EF7B1D5F5259FE49C4B5909F +E549B79839595CFEBB1729CD182C2D71FFBE9F4D7CF51FD5378DC816E5809F65734EEF4E96B056C81DFF9D07D5779E4A330D445D76B2C0E90E22371F61AA6F7FD48A35860FA7D5A9B6D7BDEAF2E6505D5DA3E1CBF6D5F34EC6C8D711160A0304DD82DC6F6F9B81466DAAFFC2ECF8BC8A13B10E +54A804F3 +C7BEDAD7DBA51D16D5348C23E494 +DEC64AD1F9135F49CC29068190EB90454231881AEB3114843DA1FBD1BE32AAB41D7A9AB7B92C6C69ACB5D3BAD32DD5EAC7F01D7B8E2C8E8D332CB6CC3BC97E9C4325979B585C2CC898E397ACC62ABD1951C84330DC2684C1DA93CF5F39C443C050F86A36B96F14C17BD952B8C43D51F57EA9EAC500A1C97830A6B7DB1088 +23CA +27 +8C34E227 +FAACDDED3CBB697E066A6F68F5 +F70F441EE8909EE7C27512A409BECC4DD37EC50AE431962C3D78820034C27825C7B6CB7B993E9061F7F534333B0023991E00487604BF98C441F550054C6DE35F7C593F85F3A98E21B7605D6B87C616A909DF39165E1ADF4ABCCFAB58B44D8898C0 +F1C1D243 +6047FB8B9245B5B4FA4F6E80B5 +B84E991583C4FFF1A0F587322083AD28B672AB6CFFB3BF9773BB589A5561E8555B04525C8E11DC626FBEB64598FF515EAF18C2B4AC0FB23DB73520EA7AE8F83F05364221F7D44A0CEA8485A1616468067013CA8ED77B5A26356AA182E26139C6C49778 +25C8BD72 +FBCBDD8FFF9D98B6994B3BF1AAD3 +FAB74C2BC373CEDC59807CEC5798A0DFC3D8933C00492EA4B521E6664087182B9CE2F57818D52E8FA9A217F15B21C162D7ACD78C25108F260153685EFEB4CE1AAA465EABB7398D8B944EE09761E513267AF4F0E569991D0AE12A7B2D73452FB46022022218967532D5B12AE9EBCA3B21FB3A7D0B39D300BE2AE53BCE0CE5 +BAF5498D +4F51679009CEC395CF2BE90A92E2 +F1DBDDCE1811860AEBA6C4024E4F00ECA5DF41EB32183EE8790D7E2034F897D107BFC12D6F002527A0C2763369F4602FADDECE3584AAEF239F2C5256DF27C299E15B24BEC98B2746FF4E7E9CD22A3270B9A195621808CE262968C4657286BCD38F7181469A6A3F1517 +EB1C78C4 +792F8A29C382E3782D28B29ECAAD +60C12F5AA5A32443D6F377FC0CD3D2F5B1329DC61C7DCD916EBC029C25FB0A024E0EC7CD36B750C48E4143F5AE769A5F3488FB207E409EBF09F74D50E970D0FA73D295B82CD621C7B7F8CCF7E159D4924B528E47BFD05F576505EDBCEBBFFA34D446E458ECC89B951EA485787CEF085AB234ADBAD0975D0652EE +234E9362 +1F9FC67A2E4C23B87B46F93B4D59 +44EEFAC638FCEBFD90A4A3713901F5DBB190FB32876F00544BF26133931F10879477999DE5B6ACC3A82B8B340CF2C6732101A21FE444798239D080D6DB12FEE3B9CC54ED2C7A9615346230F4A09287BFFF188258C14D1FCCAAEF4041FB73C8E734DC8663AB41F25CE8BF8F3E57BD1654898EF956B3A7D677C08E89951605 +6C36 +A52E7B32C371FDC33123F1 +66DD637E +3DCCD05B5A8D254FD8F4E1E2CC +64E1E88E79DC7312209F22343FFB30C5DB7BE601C1F9603B9A3B1E5446552AA5BFFF825202869B8E08F49F002361C047628E8CC229C8D5A768202C +EDE4567D +41CE669E9E7970D05969B3A9B3 +9695AC4C3A9F7541D7D501E97739949B339FA2A67B2DF1EDE91696AA3EE417004FF54FD1F407C31B1EB89CF9462C888F5FB0529F13B44FFC6F867AE276399A5E2E3F26CBFC8FE1 +190E94E6 +34890E596C9632F5BAF523F67EF1 +9870CEC10DF9C70D955E09316412B37E5DF4BB11E5F8C9F267F7D749430BE252DE3A013EEF1739FF622DEC896F260CCDFA6F043F9A11B3D46432F4AD394D81E3F5D18C1D170CEABF4C65ECDEC1595F1CE58494E3519770B0F83A9191EBEDFEAAEF9AF0A0AD6BCC0F1064E66DE67272 +9742DC60 +EFB63FE01341216C864C13706A +FDA1D383673941D4AFD1CD986F4A530C99DE8A23440DCF5F832525EE7124E1C3C724122E4C569BC9B47C4A97D04BFE0D03D880D73599F06AC73F2AEEA5301BB1AB81B6FB75BEAB5E167744044CA223C04ABCF236656AD379778AA5A5 +8D6083D3 +F0F416F3CED0AC4209372F115C +1C884CCB626A26FD424F43E1E1C51D8FFEDAD303556A6E39A8EF709BA6874E489B0082D78327C526A6C1928DBD68007621CE28908655BC6DAE924ABB86D94C688E719F92438D966FE7B53CE0700753EB281409 +E463AACC +815110C725C73FB831A1FE1B6C18 +912CECB84D3046884A3D7888FE0C7FF26AC4C38CB8BAFF66E866A746F15682550ED6D738495AA88AABEAE886009A1CB500BAA6D59A58F5ABF80240D61CFDB4E247FC0E9CB13D3D6EE75FA2442F865DBD7F52CCE59F0CDDEFAF66A15153E9FB776FF7B7508DA181986A75 +F12BB7DA +BBCC895495442B37270C423A30C7 +9C5CFA489E19FF17095A9854BFD37EE4DBF1DE5E1401D3101B067C91B5CC96CC7536E5BB8C4423BF0648E6A372A5248CAE190570122C587B10A2AE17927CC6F144D331B72B6D7E4876E2C91C8C7DD71A5D1E6D7B2576DDA456C197C827C63549A0A44E8A758794E1109F0DA21D81679A5CAE308D52895397EE7BFEDDB107 +46024D79 +2A2904A7FC36FE27E6F4BA2C1FC2 +BD60B7E1A7050F83FCDFA0C36108534AFAB10524C8AD14DB71E879F3D144C981774A65A086B4EFEAD5FA2084EF11CF9D1C75D7FF3DF7084149D3E09F793278820A8BF28CEA06200F32E89E57B3AD79E63BFF2F0743C8EF1FB7E4AF365EC93741A6E63980C4AA0203859ED85A8CCEF962D8A01BF9CD9BF7E600BACE675420 +3DD4 +D7BFB5 +6F74B9A3 +425C56335FED9348E6F3B97181 +AEDC88F14888A30050B0B06D02DF0C7176F8B132433825B53DE1FE0CB70C8EBE46DA93A5C07362B374223A3181B8AB327A9AB45C5651F2107292506AB7CFDDB030FB83C39DF1EB3F68D7A33839A2551210 +8C046351 +5FE3030BDE38C78AED9D359074FA +AC55DEE7A6674312F08A953B179C1B2412AECCD3D069952191DA5E939404E740A1B07654C6FE44BFA7FBEA3C875AA7EB00AC8087D2EAD130C559D36A5C4D11D6D7F32EB88322567AEAAB0103EB98D6F93F412E4591005509C4075AD49433764EA481DD2B +F6705D0F +1FF86C326AD4A46D606E5D31AD +786B21469EFF3E8404DDF323B6F0BA315EF26F409255FE16E5F26876DE4FEBE867ACCCB5DB8C4DAA866D5B600749079CBAF7722FA55049CD536C5F49D116AC86109D00E19F42A571D70D0213A96B185070C92BD2A8CDECF0AA +83FE8762 +0AF7499853DABC2B1298F998AE7D +06DE000BDFF7E32E001CB7972FA1E9152705CCAA4018CF9715C3C9ABB63D74A3E7242EB1FDC5A3A94F1BF79F17E4C194DC0ECB0400755C204E82BC6B72C2878AA0BDD46DC9F3595A94CD0E854D9771FC5C8D7C878477B28D6E14C7B2B72DBF27FCB1F49B9E1499B7562FD83941819627E8FAAEA2C105A23DCFF2C7D4235C +D754 +6A268655A902A96583D9C9503AF92DD3 +546E7689 +25CED8D4A42A81387F1AC8DF726B +18D5D5329C36C64F4527D4B7CDF8205C5FF42FD7F79A74FD1D502DF8BCD218F40B2569156E35AFC43CCE0731364FEA4FA7035807F0C3620E4696B9D12998E5F1074603665C9B65CC49A41A52155F0B289BECE5C0581316126E3B01B02E36D39EEDEAC9B877761EA227CBD297D667F03968A27441F72F648F75A3F4A46467 +5AC8 +AFF632BC8581E6B60B960D6D24B470674BF6FBB594201607F0617BF9147FE026375C88E774117D +DF7B4E8F +4A98F528BAE68A1D225951E05D +E00CDDA4F6999F6439E1A25129C5A970057A12C88DB9 +676424FE +8167FD99C73B7BA125F79199CC +91C5017419E0C20FAF405B1A0C8CD6C284B6DBF2F2122BAC4BA35CF6ABD2408F38DEC6C5684E4D0B902DBAB2F8807BDE7CB8B20C413CB826411F +1B9BF5D5 +A19489FB9A866D87470AA498309B +D9EF487780436E2A1660E316B4402725F03DB27901FF219333AE52AE3DDC3B82D058312A65C5E3108D7C8BE8B3E4092D817E2241B803FFEC5BCBBE86E7159E4316783E96C5812CD641EBD93B3E83A59F85091C4E2EF9EEC193D27DACC30CD8E98F22FD2D35AD3E12C83C9EE1F8B884E30391A7AFECAE8D23CEBBB5CB5CDF +F56E +D9CFB5 +74BEA299 +CD085EECFE78EB7C0FD87AFE17 +F524BFEE5660DCB7BD05BD6566EEE6C3F19CB7B8058C6A8D040A4BA2F033E699EEDAE9676C5565F4C48870185A127EC2C344C8590D09B6CE5993CCA06B6401314975B9E88CE41B8A3097B090775033E5C8B3128D90C39AAA +340DC76E +B94F6E3023EA351E9B7DF82323 +22B09B232CF54609D5FC76CEAE94FAC0011231784E66E34DCE8B54C2BCFD6FA0F73B7B3F3845CFC00D51CC37E699CA12B14D77C54AA8A77AFCE498132C48AAA38D6C86087C8FC343AB87FB3A51F8E8E6117B +DF6ABB29 +67CE93AF5D093F7311147D866ED4 +D240E2EACFE2ADB4759DF53FAAED7DB04B2AF0BC3C31BF1F4014AF71769465645FD021BEAB12202302834BD2FAA984626E23A3010BC0318C9E23FFE0B78B881814D9396786DACA24A3122A7F11DCF9A4563E9CFC1658B7B40D483762E602F38ACB4C6E6A859B53A7300B0821502A +F7BC435E +E4B4352E4E7ED6C2A0DBB83971 +73FE341A5E32BF15073310D0375031E39622D821CF17B7CBCF9E6656C3A4B7AA1800AB7E4CDA84141FC8F743C3D1A8592D22455D8EF540FF7F20CFE8CAA61A5A450C4A943300170A030D4B3E44A50A2D0FC933726A2C6F7489 +B293F353 +DC0BCF9AF4D8AB67B0B1D37BA1 +3752B6C9F3DA009825382A5FF44EFD96C7B1AE1C147390AD24F8C4D1D9479A3FF580228FB5C407F28CC1C0F52774F5AB2651AAA38068FC84A7E08F145910468B04369782768372B4C5D54BA8B4EF499B3F9FFC652164746D3729E7EB +5DA2C447 +9BEE7F12B4C6A603D0562FE4F387 +C6C79B0076A20EFA7CA6C79A75721214491B2772C682AEA3AD1BC28DCFAE5CE3C5F935E7103A08CD554A0FEA97568C6F09F81C66ACDD04087A88D13A02E37321864CB64BD0E142CD1A035BB3CDFB26CC1F8706E2F9E2FB0F460410B307E770CCC97EC60D6EBA75F06CD38EBCA41FE501BE24A403A797E7296180410CCD78 +9FA9 +B49BD661CDEB57505DA84146DFD92C89DD790CBB5C6FE932CD874A9250B404457FC08D8CFAF8226F69A9B96BBE160E +406C9317 +D8978F3F44A78E4FAF6C64E24F38 +960B7FF55C5C1EE71084E19ABB04E4AE50856885C604A90D9E10ACC70D673B96594F7200B5CC0B5F841CEBF959551140DB83308CF4CE64EE2056A0E0B66E4D24DB990068F8F54533115884BFDD80CA89DB7C4265248D20355438E6FB40FDEFA97DB54B6B31AFB7D5514CC3A270 +FD5A1F18 +9E3767213D95C0AAAB84621619 +1026A9BEF30E0A5288552F8257DC0002CC828EE13603972B38CD4A59699A19BD386D8DB533A3272353FD9C6E97EC68B02ADB8AE8AEA7871E44A09E06BA3C59602BFCFC8540F3FF33F33FF1027B276B0F +C8E5A398 +EA5C1828C27DF4B2C32F9C3D4F7F +4116B07F84A9BA3606FEC0FAA652BFF2B3E20949D53CBDBF4F4B174DAC079647818D68F10FB0943C9CDA05D3DEDF934B85DDFA7F8433C99CFE9F1BF724828063F042829C497E97C34F5B596AE850A6A27E81D78DFD3D9E73B4742C0A66FCB4279EDAD5C224C4821BDBDEB0185BF198C5D3AD8FB6433ADB557CDB9B11660B +266D +A80CABADE025C062AC1335AAAD196AA382047F556C430A2D1B82ECADF7FD13B72B89BF +D1846492 +38FFA49B47FD4B4AF3D0B770F7 +DC166C85D48916FF89A361553156470B52D76EF3787A8E4A2CC2589858B4F1FC9843CEE006765B0E98D0EC26406621DFE65DEAFB1A18 +37011E6D +B546536D3EBF37A50FCDE6062E25 +A581FADB73255BB36C471C325F616EB90F654168FBD88AA3D8A6C3B9E018992A2D8A27D03F1D0259BDC1DCC5AB276973DF45C3479C036DE3716CF8C0DA5C74541A442E9EE45EAF1E68160066716439654FE38D8995C84D98D15C569C332F69D3782466770FDD437E286468B71FDF76B051DA5619FD18DE93D82BAF42DA41 +48DF +7EF68DA94750E9A07D7E95453D707E01A93CBDC459B1D3305F4CCDBB89D846 +8361C00A +F5E04E42E866E6474E2ABC9F127F +79622FEB912B2FCE69FF6BBF244A807F5F18FEE41FC2C2F7A1E66EBE153408459F9F0E31CE028FDBCEDAA8F99549A05EC45ED4CED28146584DEDC71B978568D2FF15E337BD3D3B14D7A16C1E8FB53D1EA0E09696C8CDDB30D143CDF87F1C16C75D8264CFC0CBF60BA5FFA3B7 +C0B75283 +B87DEA036E31C769A2222BCA35 +1A5EC765D6758F7CB540CFD9ADD4CAB6FFEB10B03DC2603818E4E145A4ADFC6D3F074F00EF4C781B56BAD7868377DD2CFE287D85B3D71F7554C32030711ABF807B5F4278C2A9 +791641E5 +6D7B6C1BEBC7EB48D2DF45102C54 +FE220813B78EC3C98105CC7915C34304257EEBDFA64D06A44D6FC3780DBCDAE1264ADA27995525660373C18553693A063A57E15DCEB150B53E95559DFEB534019654CE8D4A6D4B28994F1D8A2A74B398C2D876B4C92D2F9175404C70165C5E9B7EC4E89844913F6A1D049C965BB5A254F1697EF895BD11 +08F431C2 +21B25A9D7AA9BFC5152195363B94 +09C8A791DAC7B6F75795F5B0F7ADA4B3933FC1EFADB1A211FC5091AA1E23F7A7AE46A7EF94FF7880CC1C3492300A1D76E32BAFA20830A65114F335466EDBE02179D1BB8D1616EBBE9D4245B7E740089AED1C030282DEBC6B558E8332CB6E07A01BC86F62E05DA720276C +E2629023 +031A1B462C42CC88819FA2646B +ED8080D4E84A7DF63D2C5094953780A920273103E14AE8247506BA172CAB621329944DDA32DEF0CCD24839EA3FE755FC5C267B60668F193D91ABC73A1125ECF5E9C6E625E24FBEEE5D80803B7F463E95013B9C70C52215 +33FBB79D +67F88287A5FFFC10B10A34888EFA +8DCA131B6073EF2D36BE42BBB9E044A0BA12C007BD22734007F8543490E4C290C0ABF13EB733385887DAB32030D46DA986F769FD9A0BEE4B89985BC3675927416CB47EFF4D9E5706C672149373BB6C352F8339014C0BC0B504A63D1EACA46851B6A7B665B63958BE946062515C08088C3046E444353CEADE11137F2C +F7999E12 +FF5EB9E15B41A279D2A7F01622 +1CB34AA440570DEA431C21AA326C6CD20BC8FAD80A57252B7B3FAB809308277E80B5FE8C04E3F43413862E28C1BA8286211EFC054657BA82BC814B69D0F0E0395818F01272 +22ECD428 +4E329074CD1F293FB250C8401F +3906C080AC003E96B098AAC80BD10A54EBC6ED8BB94DD3EC5D19BD408F4613CF8A035141C2108C24B5FCAEF1F56B2D7DDC3D9E892CF2DCA1E059ED64E60FBAC6127EAF96F70B8BAC49CC2F717DB8B967AF5F72EC04AA5EEF8EE7B3B5B9E461ABCA25 +9EFDA7FD +C4840C027C9F33E3FC9CAAA37C +EDF28E1A8769EAD7D04A483E883CFF0BC8D6559D0326C733D0C27FDB8C538412B5EFF0E2F69EAB9FAC959E7A810B3A535BFA6FD917AB1D953020B8FDB34263DA55C5A595A74784CB5665691C88EDF1F0DCC6D802AEC0F8A894 +F7FFA98B +8C0D0E71624F5554E9CE06AB9675 +F3719709314D0875AEA61D7D08904902E0E017FBAD74BA715EE67D25BC514D5FB1EE7DFA382AB4CF2460CD1419E73BF4175EB8819A8738C1E9388C508350779A7B829AE9B476510653F93DC0457A9C5CDED0666CAD33B6DFEEB722EFC1AFF2D61D9BE12B82816D228EA5DD9DF88471169D4AFB000E8272CEA1606ED966D1 +2CC3 +5EC232EBF094C3754602FD6AC9E8 +FA935A4D +637FF50BFE0498386717F8884803 +12792A772FB4E5245944F989C393076DB4E49E04DC1B9D43375423E96903F02FD34F46A225913CD8F662A031FB075461884B81BF5BF168EC5B47FEBC06943165CA33C9B8F7FBF7068B7E20C37C7F9ED1682F2CD80FEAF8C8ED16AA36C0C666492CC13F689B49F2A652E906EA7A843217A385A2A4C2EFDC857130D0D105A5 +3948 +8947829EEDD4C4830A145C2A4FE3AE15D089F232AF65E5493C +108D22A8 +A12A0CF384B21D29F912373D3A63 +E8D2340E7ECE98C621151555E809D816C178D78A1C7BA229D754FB16BEFAC6040D3EE4A3D2B5A499F120BA68BB3BE594E061B7FD750E2B92411DAAB939B1466F2C5029997638793FC32E1433616C6EE3168CA201811E65EBCB34295BF49EBDE73E45D872A8DA3F33A1FF974F3C9F7955B1A0098BE6F2C341858C8F27B0AC +034D +C3B2045A +E1875DDD591CA73B1C438AD167 +AD6C39AAB3C2D28DE3768614F59AB0ECD5902A52A24E87AFABBA901B464BA17AD29289815A760419A2247F4BDD38CB6FF98573563593BEBEF7EFA909552BF4 +5D2D74BD +68B0440FF32D563EEA1560B46831 +3DDD88F27AED52E44CD08FE195424810B53A82EC650D38987F195787803BDFC3BB1051AD351A11E553B91321D6BB69462CA2EEFCF84447C716BB4B34D776DA2A85C547D0D6B247A43F0043DF73117694E4BADE84814FCFFFA69E38D4BC280267464EEC788D417EBEBE +CD7A03F2 +54C8722D5D459BF5CEEFC793B9 +60637F99EE58E491061B7B9CF0B2B1FA50006F15F046 +EC4A1BF5 +89DCAB1A9C1E3D4888531A22FE80 +3AFB21717EF88234 +84704D1D +103C2242A00D198FE2AF3C92EDCDDB3802D75263CB4D9886241ED4BDAD254022C141 +3584CD0A68FBD7324A05173E552FC1A6CFECB3A18A0C8FECB3094D72B08F01D3A89B964B8847 +405DD1BE27D85EEDFFF9495EB5DA6E125E9AFE3057B4287FFB1ED4 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +%Defining font PSOwstdutchb +%!FontType1-1.0: PSOwstdutchb +10 dict begin +/FontName /PSOwstdutchb def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001000 0 0 0.001000 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 1 /C0032 put +dup 2 /C0046 put +dup 3 /C0048 put +dup 4 /C0049 put +dup 5 /C0066 put +dup 6 /C0075 put +dup 7 /C0077 put +dup 8 /C0083 put +dup 9 /C0097 put +dup 10 /C0099 put +dup 11 /C0100 put +dup 12 /C0101 put +dup 13 /C0102 put +dup 14 /C0103 put +dup 15 /C0105 put +dup 16 /C0110 put +dup 17 /C0111 put +dup 18 /C0114 put +dup 19 /C0115 put +dup 20 /C0116 put +dup 21 /C0117 put +dup 22 /C0119 put +readonly def +/FontBBox [-16 -209 919 694] readonly def +currentdict end +currentfile eexec +D9D66F633B846A989B9974B0179FC6CC445BC7C8A959A39A32E9DCE7FAEF17EE3BEC9F +50E1A6FCA651FC4B3769A0A91041557502E25A5D6180FE25A3D11BF079E1DF66E54EE9B7C229AF891739707A2A0EC140306B5E43E52B79BFB89E459E50 +6EC6F610A70775A31C460976C4F79449D86E57ACE491E5C6BF20CC4307B1DAF7630252 +E9AF8CFB69B50EDAE9D36A6104AFEF8832F920FD2346B2C7104CD11E3BEE999CFA9F5A +49DB3173EE48D1C82994237F360407B022E0B4 +502E94EA8B493651EF2D03F0B513D655047568325B512AE6 +6AC6F53F3848CF70DE25481CC65D8B1A5793AA +3C4282D111112BEE28AFCA7A3808D4444C4669CA +84EAAAF989219F51AB3476A1B0B5F2246BC306E6 +625C6679C417ED2A8E9BD010DE37D40265074C2684269CCEC1A9912691012A4BB5400F24BB2A19 +ECB8F6076FA44F109BE31002 +111487965EB846A9FB +16D27A61 +9A739E73C457D0209278766556 +ACA88EDA1F268FF3C2B8C90A23D0A6383D5A5A061FD3511E1D0E72BD5FAEC1 +1976B18A +1AEF6C96D497F61F6E70C7F476 +591F47BCEEAFF20A340F115FCBE4D8EABB1E830D34D309CE870A5FCCADBD9C27CC47B5453E93CCA46DB3FDF60C03E69CF0B326AFFDA4D42DEDB705AA33260EB732D3E63852AA668E675AED40906C56 +745FED2E +F54ABBCCF68DFD057715B7DAA4 +2865754BEA1701DE3532B985CFBD10BF19AACD4C667337797947261F5136E408078BD0F321C196CBFD4CDAE3826B19DC1DE5E7D369F4DFE6403A0046 +6CAED257 +D6C82CB191EE817ADDD99C0C761E +7D5C532902A3F5987B24416E1ED1CECF12F956F093735A2579D3F54677C7AF3967844D14267F08C39971922A97705E674F0BE20B33062322399BEB0C6131A318F4D4D537A7F242FBA0C7096BFFE3CB0DB404677723BE3BD453BE9E798B8C6301DF57F2357F6DA8BC0CD3FBC0C9CA5F3665FB25E4C7DBDD8931C5 +DC4359FA +A7DCCDDAAD5C180B7CB6B2C8FDB9 +A87D88D583287E16D08304341154F49C3BB66989D0B0239599DE10CED44281450CE9A2F3DF9CC6E5402718C56B6E5DE4FBCC656CBE90F2BEC9AF8D176DBED9C3FA66063FB345B1EB9AE70873230D7AD9D4026A0DD657D0DDCA14EA37A5D5834A7EEC42533AE9F3500590A6092B54E47D26BD33DF202B2A18E932C4AAF0E4 +E34E +A0605E2983222260E65575BA +5FA943A3 +E3789B7F12287E71678A7731416D +6C47683F91116A9754B4F2561B7B9BDCF8DF007031C7FF95CEFB5C8221D66356301ADF98FFBEC079DCB27FDE500F3745490E3D3FDD871ED766AD44EFB7B5F2473230EFD19E6B15A56953FF95ED5AD868C6DE34526CCF78051C4D0EC9E5A42B5ADEFBDC1D3FA6D233B2B8B60305 +D2FC923F +6A5E3459A4053040E4D1862F93B0 +3A24C941F1E7CBDCE2129F92776AFDA1FD7804CF52B82C3669DDDB1E3812C6B791E650DCEF5D804370607AE9507E9DE91DC1F44B67F86325E289E22DE66BA093E498FE191F697842456415FE1FCB41EA7CA0F6B2924FA08AADA814606532797024EE476E82FB93DC73CE8FEA8BD05E2E84AA115A69E7D3D1A38FA53CEA11 +9EF4 +930A06A8 +07782F3D97DC9B73334C689DCAAC +17040818FC1FF156D202D4269DBDE25B8FAE4186114B54D7CF7ECAE50C17B4045D83EAE9E6D350152DF43562C267252BFFF9CC23AC70366EE237AC8A25EA2A62D65A400F59E9C035766D17B6FA6FB51A8F56DBFE223DED74105ED6C0154D7A88BB007E54273952CF68F03BAD701D78B47ED325837155D343909A48DED11F +B6CF +DB446045 +95AB8E8F +D760970E8CBE019F32F0FDFF08 +0176C321542C5D76D4134F8B6BD069D9BEB718FD04AA889DF3C456F1CF47AB640C62D9CCF7D67C2B3B070E0E5B86C3A87CE7EA0CC7F083318EC963D81C7236E32E75BFF27FF81716BD5E83FADE36BC36B38E +739FFA00 +094C6CF696CC5C7B8D3C4C04B754 +6244474FF2384026697215BD4E68C2D53A6981FBF6346F4BDC086777798392DD5CEEF138321D26B03BD2B2E0B9B76530D374ECB3BEE811D42963CCC6607C663D959293B5EA17BF672B1F0E5A01F9C240B4B2048CFD4462BA656809E4FBBFE7463B4A751440A31741E05A3ABF +20BE2A27 +E584B7E4950CEBAAEFC6131B4F +0D752C4CC993BF5A99E190424A6CAA5E65A9C5BA40C79162180F9A65DAD81756132C8DD5B0F20DB944B630F1AD5140D3245053AAD50A1D8064D59A7665FECE672F9079E85DF0328AB9CB19F5DFE26A56067643965402D63897085338 +E76D5582 +501532927B8E17AE540C5AAF13 +2A27B809AB30CE40FEB60F7B477D00BAFDD260D738F4C015B463F7115C17DDCD1FC3513D8B966380C6B8C3647FB6936048079D2A57378503BE105C4FAA121C88011E15E6C15AAB5A8CB8B645D4EAEA3B4DABA5A9B38DAD01D5CB36D39E +EDBD33B4 +0BBADC10EF624C2EAAC1CDF4692D +601ADE5D2897F965615B1158B4CB01F903FFF379FFD7F1211ADDDBCB741B44461254166F4BC09F3960366DD52B91B6B0DD8DA70C0C2982C2FAEE8D9E0FAC248698FE819D032DB358DDF4B2580193D191E54E6634BA10E0AFDF34F3D6F3126BE12163832AF0D058949BE52E138D3BA770B66EC57FF508AE84B7F2F4A1A4E5 +27F0 +FB359965E87A25EBDBBC38B1E35D2FB9DEB3A5B46727948FC7B7610E92F83568F4974FB6E5 +78E2D139 +34A6D17A6B2E5297A4D691A53B +D33F9AED98B84C2FFAD47485E0188394744C2757EBC22BE71305A850258C58ED43F1D1F701B3031A6753CAB06F28DC882494381E78C6B9EA5E1B992AD084DAB9E263CB88424BE6468EC4B05D1A91 +AE35F921 +0F3DD6351B55B331993DEE86E39D +4C8DFA8F600807E9615039BE9CC652DBA095E5472A31028E534B9BAB5B9DC241CBE9040CF93522B335074AF6B5B53106632C72663D4FE8EB79C37C3DE888BC8457D8278DEBD208ED8B999C20CD8F6B360B1FCCC2A4548D3EBFD7FD8EDFFAC4E16148CDF1B61CF3 +A90DB9AE +00BC6165B83E13951DE8CA3802 +75D93F8FCA23529AEA5D127274982DEB0F5A225CF872AF3290433673464706D42584481A847D336340292289F23E52A02FE3C150A709DFA1EF66ECCD517C676091D8CB3547D2 +94C233E7 +5AD9868DB591CF2D8065BE4CC7 +1CBA58BD23D0ADA3587B7DAAA710F9A6042345D875217D820372FE44A53C6DFFCC7411A6AC5C4A76FA8761181A9175EDD80D25820A5CA3D601420376EA04E0438F059A6D0D40A7A490981F77E22E759F9AE668E21C82BA6DEF +E5F215AA +A99A4CCDD904AA6FC4E34E2EB935 +991C9D7A48E3DC9758B0AA9DB99300AB5DFC01C7284A7ED962B8D39DD88149F3073CC081398A97801520A3E8A71EAABB98411CCF62983A146D86DF595FC8AF752214648C936B51D832401E25A8C208B8CEAABA1D91DCCF659DDA5214C78EA9DCF32AD9DAF56095A964776E97D8A8D43CE2E1807E3769635C96 +F7399866 +B343EA46395E283F3510023951 +48E0AEF141D4FCE719AF43E70549469C45453475872B31E62285815F308CBD417130577249288F55A944B704E5B3E700706DA785743B38000B238FB5834C4183850539DC +3D7D3372 +D34D4AB740677B88E1EE4ADF48 +6DA47F26C82A2CFF585E382128EB7F375EF8A34CE2C94D44E3562CAEEFD718717C31BAF51167FE944DFB3224CEE789132AD217EDC073D555F78BC9D183671B3DF9CA5A7655C7F57FC02DB20759BE36C12857FA4A33D03399EC9D06 +3400041D +ADFD50918804900E9DEB5AE288A8 +1702B5D54DABE3B64D02839F3AF02A920C439506CD1EF15282476CD0F9F036784E730803DF87702258ACD16C3D170DCD6FAF7797986392B9B5B043C368FA5131B06BD26DA9B115E853AE6E65E73847A10917680DEBC91A4A34C968EAF26AA0556009B29ABBD0933F524661BC0B6D35A7E3F6BB67D63CCB131CC771F338A7 +A8B0 +DF11CFA4ADC4FA8B922588 +6C4D1383 +2C59D3B927778E903A380305B273 +03AB8B01EB83C42E +3DBFCB56 +86F69A488ED48F6FD93CDC77D5730235F676554905F9E827498BC99D5773555683F2 +D78950A8E3C3F8B5F0A126AA31E89A489C339F1E165693F5027735027A833748D06AC8A8445D +28FB7D316CB46EF6407DB52998357FDB568BA87E5560B8CD1BFED2 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +%Defining font PSOsymclas +%!FontType1-1.0: PSOsymclas +10 dict begin +/FontName /PSOsymclas def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001000 0 0 0.001000 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 1 /C0069 put +dup 2 /C0083 put +readonly def +/FontBBox [50 45 775 713] readonly def +currentdict end +currentfile eexec +D9D66F633B846A989B9974B0179FC6CC445BC7C8A959A39A32E9DCE7FAEF17EE3BEC9F +50E1A6FCA651FC4B3769A0A91041557502E25A5D6180FE25A3D11BF079E1DF66E54EE9B7C229AF891739707A2A0EC140306B5E43E52B79BFB89E459E50 +6EC6F610A70775A31C460976C4F79449D86E57ACE491E5C6BF20CC4307B1DAF7630252 +E9AF8CFB69B50EDAE9D36A6104AFEF8832F920FD2346B2C7104CD11E3BEE999CFA9F5A +49DB3173EE48D1C82994237F360407B022E0B4 +502E94EA8B493651EF2D03F0B513D655047568325B512AE6 +6AC6F53F3848CF70DE25481CC65D8B1A5793AA +3C4282D111112BEE28AFCA7A3808D4444C4669CA +84EAAAF989219F51AB3476A1B0B5F2246BC306E6 +625C6679C417ED2A8E9BD010DE37D40265074C2684275DD89A8790EAD18EFC77D3FFAE84DA5D +312074C4D542DD5BEC70968F75DC +250C3954E8DFB8F4857BFEF092EBA49D248955A858C5A5F55F7B987EA06EC8428D939084C88F5B157D80AB2D706A7EB936C3429173588D2ABA6A27DC94C0B484F316663555797004CBFA79E7B8545C810BF9CA92F61ABD9E202ED9E95943DF7A5ABBF3C20BDE3B6EEC9C0B95A4C9C1D38AA7C6786ADBBB79EE183BDDF194 +1953 +6449DBB7AE47E9FC6F3ABF1DCD7A1E274E87DAE9 +A22737FA +6404B215A27BFAF6D0B50E94D2 +07123A5BB380C86DB5033EE743181BBFCC0356571F7297A207C23F1E588257FDEF5DF229 +CABF3B3C +9E0988C63B358ACA4B4FEB033DFB +E2E387A06A23CACA +8E104B90 +DFDBD41F063E8A8DFA0ABA4DD7443015526AE5255315597779E04D85849305EA4F31 +5CDAD06E5841E1B8074760C99702B8CF443D752174D996C94E690797A9587CF5017DEB11E5FE +02576E9E08B39688BBE99A186AA8FC7E222F5E52B29A7FDF379EF5 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +/DPIx 1270 def /DPIy 1270 def +72 DPIx div 72 DPIy div neg scale +0 -13970 translate +1.00 1.00 scale +/wst:dutch12 12.00 /PSOwstdutch newFont def +/sym:clas12 12.00 /PSOsymclas newFont def +/wst:dutch14b 14.00 /PSOwstdutchb newFont def +/wst:dutch10 10.00 /PSOwstdutch newFont def +/wst:dutch14 14.00 /PSOwstdutch newFont def +%%IncludeResource: font Helvetica +/wst:helvps10 10.00 /Helvetica /wst:helvps ILEncoding 0 declareNFont def +/sym:clas10 10.00 /PSOsymclas newFont def +%%EndPageSetup +GS +0 13978 10801 13978 10801 0 0 0 clp +wst:dutch14 SF +0.00 0.00 0.00 1.00 setcmykcolor +<1929373329352a0c010e010f2931272c3025352e012a3235011829253638352d312b011929373a32352e011b> 2207 558 0 7384 -1 s +<29352a32353025312729> 7375 558 0 8593 -1 s +wst:dutch10 SF +<090b> 9346 13385 0 9522 -1 s +wst:helvps10 SF +<4e6574706572663a> 1322 13267 0 1949 -1 s +<205265766973696f6e20322e313b20436f7079726967687420> 1949 13267 4 3868 32 s +sym:clas10 SF +<01> 3868 13267 0 4019 -1 s +wst:helvps10 SF +<2031393933b131393935204865776c657474b15061636b61726420436f6d70616e79> 4019 13267 3 7133 32 s +wst:dutch14b SF +<080c0a140f1110> 1271 1458 0 2055 -1 s +<000403020006101116100005150e130009100b00070f130d0c091415120c13> 2055 1458 5 5629 0 s +wst:dutch12 SF +<1c> 1271 2086 0 1434 -1 s +<29392d362d3231> 1426 2086 0 2056 -1 s +<0009070800322a003129373329352a0027323137252d313600372c29002a322f2f323a2d312b002e31323a310026382b360025312800302d362a292537383529360c> 2056 2086 10 8035 0 s +sym:clas12 SF +<02> 1271 2432 0 1359 -1 s +wst:dutch12 SF +<20> 1589 2432 0 1751 -1 s +<293526323629> 1728 2432 0 2329 -1 s +<001a3837333837000600372c29002f322b2d27002a3235002b35292537293500372c2531003637253128253528003929352632362d373c002d36002a2f253a2928002d3100252f2f00372936373600293b> 2329 2432 15 9143 0 s +<3f> 9143 2432 0 9213 -1 s +<27293337> 1589 2677 0 1972 -1 s +<00372c29001e101b231d1e1c120e18003729363707001e2c29003929352632362900323837333837002a323500372c29001e101b231d1e1c120e180037293637002732382f28> 1972 2677 11 9213 0 s +<383629> 1589 2922 0 1891 -1 s +<0036323029002a3235302537372d312b002c292f330700212c2931002732312a2d2829312729002d3137293539252f3600253529003529343829363729280500372c29003929352632362900323837> 1891 2922 11 9143 0 s +<3f> 9143 2922 0 9213 -1 s +<333837> 1589 3167 0 1890 -1 s +<003a2d2f2f002f2d2e292f3c002629002a2f253a292807> 1890 3167 4 3771 0 s +sym:clas12 SF +<02> 1271 3513 0 1359 -1 s +wst:dutch12 SF +<1a31> 1589 3513 0 1877 -1 s +<003632302900363c36372930360500372c29001f111b231c1c0037293637003a2d2f2f002a252d2f003a2d372c003a2d372c00372c29> 1877 3513 10 6651 0 s +<0030293636252b2900242436293128233828332335350c0028253725> 6651 3513 3 9213 0 s +<35292739> 1589 3758 0 1964 -1 s +<0029353532350c00103231312927372d3231001c> 1964 3758 3 3818 0 s +<292a383629280702001637002d360038312e31323a31002d2a00372c2d36002d3600250026382b002d3100372c32362900363c3637293036002a323500273231> 3810 3758 13 9143 0 s +<3f> 9143 3758 0 9213 -1 s +<312927372928> 1589 4003 0 2193 -1 s +<001f111b003632272e2937360500323500250026382b002d31003129373329352a07> 2193 4003 7 5268 0 s +sym:clas12 SF +<02> 1271 4350 0 1359 -1 s +wst:dutch12 SF +<1d32302900372936370036382d3729360036383333323537002a32350031292d372c2935002c2d3637322b3525303600313235002732312a2d2829312729002d3137293539252f3607> 1589 4350 9 8130 0 s +sym:clas12 SF +<02> 1271 4696 0 1359 -1 s +wst:dutch12 SF +<1e2c29> 1589 4696 0 1949 -1 s +<00262931272c3025352e002d3600313237003a352d37372931003732000e191d160010070015323a2939293505002531000e191d16001000273230332d2f2935002d3600352934382d352928> 1949 4696 14 9213 0 s +<2a3235> 1589 4941 0 1856 -1 s +<00061115161d1e1a141c> 1856 4941 1 3292 0 s +<0e1800273230332d2f25372d3231070013> 3284 4941 2 5053 0 s +<383738352900392935362d323136> 5045 4941 1 6337 0 s +<00322a00372c2900262931272c3025352e0030253c00352934382d3529> 6337 4941 5 9213 0 s +<0e191d16> 1589 5186 0 2112 -1 s +<0010002a3235> 2112 5186 2 2645 0 s +<00252f2f00303228293600322a00273230332d2f25372d3231070006111f1d12231b1d1e> 2645 5186 5 6338 0 s +<0e> 6318 5186 0 6481 -1 s +<1e00273230332d2f25372d323100323100151b061f22003529> 6461 5186 4 9143 0 s +<3f> 9143 5186 0 9213 -1 s +<34382d352936> 1589 5431 0 2145 -1 s +<0036383333323537002a323500372c29003e2f32312b002f32312b02002825372500373c332907> 2145 5431 7 5585 0 s +sym:clas12 SF +<02> 1271 5777 0 1359 -1 s +wst:dutch12 SF +<1e2c290030253138252f00283229360031323700362c323a00293b2530332f2936002a32350037293637360032372c293500372c2531001f111b003235001e101b> 1589 5777 12 7924 0 s +<07> 7889 5777 0 7942 -1 s +sym:clas12 SF +<02> 1271 6124 0 1359 -1 s +wst:dutch12 SF +<1e2c29> 1589 6124 0 1949 -1 s +<0011171b16001e> 1949 6124 2 2746 0 s +<293637360025352900313237> 2715 6124 2 3785 0 s +<002a382f2f3c00282926382b2b2928002a32350030382f372d392931283235003235003132310612372c2935312937002931392d353231> 3785 6124 7 9143 0 s +<3f> 9143 6124 0 9213 -1 s +<302931373607> 1589 6369 0 2187 -1 s +sym:clas12 SF +<02> 1271 6715 0 1359 -1 s +wst:dutch12 SF +<1e2c29> 1589 6715 0 1949 -1 s +<0013> 1949 6715 1 2133 0 s +<323529000e1b16001e> 2125 6715 2 3044 0 s +<29363736003129292800262937372935002c29252829353607> 3013 6715 3 5254 0 s +sym:clas12 SF +<02> 1271 7062 0 1359 -1 s +wst:dutch12 SF +<1e2c29> 1589 7062 0 1949 -1 s +<00293535323536003529333235372928002a323500352930323729003129373329352a00293535323536002d3100250013> 1949 7062 9 6271 0 s +<323529000e1b160037293637003a2d2f2f00252f303236370027293537252d312f3c> 6263 7062 5 9213 0 s +<2629> 1589 7307 0 1807 -1 s +<003a3532312b002536003129373329352a00283229360031323700282d36372d312b382d362c002629373a292931002531> 1807 7307 8 6250 0 s +<0025373023293535313200253128002500363725312825352800293535313207> 6250 7307 5 9213 0 s +sym:clas12 SF +<02> 1271 7653 0 1359 -1 s +wst:dutch12 SF +<1e2c29> 1589 7653 0 1949 -1 s +<0030253138252f003129292836002528282d372d3231252f0037353238262f29362c3232372d312b00293b2530332f293607> 1949 7653 5 6652 0 s +sym:clas12 SF +<02> 1271 8000 0 1359 -1 s +wst:dutch12 SF +<101b1f0038372d2f2d3d25372d323100302925363835293029313736002d310021> 1589 8000 4 4863 0 s +<2d310a09000306111f1d1223171a1a1b121c0400312929280027252f2d263525372d323107> 4855 8000 3 8840 0 s +<162a003c323800253529002a29292f2d312b00252839293137383532383605002a2d3b2936002a323500372c29362900333532262f293036003a32382f28002629002b352925372f3c002533333529272d25372928000d0604> 1271 8346 13 9277 0 s +GR +eop +%%PageTrailer +%%PageResources: font Helvetica +%%PageProcessColors: Black +%%PageCustomColors: +%%Page: (30) 30 +%%PageResources: (atend) +%%PageProcessColors: (atend) +%%PageCustomColors: (atend) +%%BeginPageSetup +bop +%Defining font PSOwstdutch +%!FontType1-1.0: PSOwstdutch +10 dict begin +/FontName /PSOwstdutch def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001000 0 0 0.001000 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 1 /C0032 put +dup 2 /C0040 put +dup 3 /C0041 put +dup 4 /C0044 put +dup 5 /C0045 put +dup 6 /C0046 put +dup 7 /C0047 put +dup 8 /C0048 put +dup 9 /C0051 put +dup 10 /C0058 put +dup 11 /C0065 put +dup 12 /C0066 put +dup 13 /C0067 put +dup 14 /C0068 put +dup 15 /C0069 put +dup 16 /C0070 put +dup 17 /C0072 put +dup 18 /C0073 put +dup 19 /C0076 put +dup 20 /C0077 put +dup 21 /C0078 put +dup 22 /C0080 put +dup 23 /C0082 put +dup 24 /C0083 put +dup 25 /C0084 put +dup 26 /C0085 put +dup 27 /C0086 put +dup 28 /C0087 put +dup 29 /C0088 put +dup 30 /C0089 put +dup 31 /C0095 put +dup 32 /C0097 put +dup 33 /C0098 put +dup 34 /C0099 put +dup 35 /C0100 put +dup 36 /C0101 put +dup 37 /C0102 put +dup 38 /C0103 put +dup 39 /C0104 put +dup 40 /C0105 put +dup 41 /C0106 put +dup 42 /C0107 put +dup 43 /C0108 put +dup 44 /C0109 put +dup 45 /C0110 put +dup 46 /C0111 put +dup 47 /C0112 put +dup 48 /C0113 put +dup 49 /C0114 put +dup 50 /C0115 put +dup 51 /C0116 put +dup 52 /C0117 put +dup 53 /C0118 put +dup 54 /C0119 put +dup 55 /C0120 put +dup 56 /C0121 put +dup 57 /C0122 put +dup 58 /C0262 put +readonly def +/FontBBox [-50 -256 978 739] readonly def +currentdict end +currentfile eexec +D9D66F633B846A989B9974B0179FC6CC445BC7C8A959A39A32E9DCE7FAEF17EE3BEC9F +50E1A6FCA651FC4B3769A0A91041557502E25A5D6180FE25A3D11BF079E1DF66E54EE9B7C229AF891739707A2A0EC140306B5E43E52B79BFB89E459E50 +6EC6F610A70775A31C460976C4F79449D86E57ACE491E5C6BF20CC4307B1DAF7630252 +E9AF8CFB69B50EDAE9D36A6104AFEF8832F920FD2346B2C7104CD11E3BEE999CFA9F5A +49DB3173EE48D1C82994237F360407B022E0B4 +502E94EA8B493651EF2D03F0B513D655047568325B512AE6 +6AC6F53F3848CF70DE25481CC65D8B1A5793AA +3C4282D111112BEE28AFCA7A3808D4444C4669CA +84EAAAF989219F51AB3476A1B0B5F2246BC306E6 +625C6679C417ED2A8E9BD010DE37D40265074C2684219EA75CAE87A4407084723F57DC4DF76DE1 +A7AC1300404622F8933A7F5E +2B732F30F9087EAA25 +DA7CB062 +196255A938E05363DBDA17371D +616CC08719D0C520826FAC95FA8FAD8E5FBEA485740EE8935B7EA8F5DD026B813B7A59D9443F6EFEF5E4A4E53E077A9343DE421E006B0A84769BF4533FF0C416 +899DC44E +7BAA6BC8C1CBFB21A82F2774E3 +AF8C5A154B36F46194F073CA0B592D3CED65A8197FC5482C77373FE0F5BEEC2B47164CD1743A5A297133ECC5BB60F0F30420C9158D02DDBFCC379B287D8E89 +257DF8AD +06F4C2188C85F7C1C036A4D9E4 +4AE3E5B4F669C37C220F5D2D20DF85025C93F6CCADF0AD5D9A350D52EE32B74725AF4EE462FB36F15CA2DE432FD3E7C420AA708246DCD42C0F +81BEB99A +FD05E898B9119E93F453A769F6 +124346CD05271611C569FFD7D8626F5E6ED5C284A0102D +9D300DB1 +5ECC34D6EDEC8EAAC556FBCAF9 +D5F433638F48DB27B9F9988CAF0789CB628C53737269299BEF70D8EB946D8B +E6A966DC +4F98250BD5CB4B0DFCB082396A +17F087028EA78B95B203CD99B7EF7BC79732C3EB5556D6F79F2E8E3C +2FF77A2E +24AB46285AAB198F43C8F43A22 +7EFC9EED26529DE643473D2A92F1E9E8EA5AFB9553F4B5A3EE254E563EBF19E6C1570093617A01189B6E45996CF94ABCBFB255C19ABF6CACD65936DA3E2CC06F31CE8E4573115F99D122 +53C16135 +C555A81871FA7A8EF9B1B470642E +3F575F4C00E36AC1879CC10B27FDBD083812735A3D83B4C579A823D7539223FE0EC01483C0ED32B7FC80D5EF14893043CFF4FA1702A0D712783653F964259328C9FBF57F4BF3C0F6D17B9AC8EE60A659B8061FEB9BE6E98DC095F708392C6DE5784A9975CF340175E1B24E2B9AFB28 +BAB69BEE +C9E4D57B12315A4554316E16C3 +790BA720E9BB4226B50A63750D885F76DFB85E36E1EB017D40041EF6F83A0F5DCB55A3045028D17EA6B488322BAA27A96C8052CA889B +20747044 +E40A2AA2D00C96049E74F609DDBB +9635FA05DC930407947E144341F57DB01010B5B0C419A0D2F61CECE41983A7C5CF77B6971B9DE9BEB7FC38207A32BEEA7B420BE579227F777D0316C6ED699A33F67FBB1654516A523AEE62AAD368B495AD909E59D9C2C76C0B87E98BF9C2E8DE598C306896AE233155F2D29A7DC3799D978C21 +E2FB9A54 +D982D1A7C8B759B14D04D352F1A9 +09AAD94A51143CC157B3F50EEFE7E7377E5FBAEDD5FBE635FE9ADFCEDB287D04D98FB9E19B00E4FAFD6E1121D7BC75BA54DC79C856CD06916E79550A344985FFEFDF5A7773E5C16BA9198366FEF164654EE2BDB3FE55E26F352BE0F2BB6721BFB0BFD9A2A992CBBB313A0A1EBDCECA41250AA71AD1CEB6E8CC11409458DF +B530 +56 +6582A7F5 +53469B718D58F1AFFE52D90EA1 +C3CCD41E6A76A1C99B4D1FAA9B1D8A8ED68C4A3147521A499F457250480334742FEC17EE40154EF258A780B72A871599FD7FDB3D9FF4DC54E31FDBBAECA97072A8D466199484EBA769B82DF937D863B8DEF75308899581FC69BD681C8B9D94D025 +70196DBA +EB1BEC40F192D7B010E2FA78B2 +91B952FC24FA8CD02D11375E97405C7FCB391434745AF633654442257906161B79311D3DBBF2013D8EE81349E27D1DB56814780C68B81BCA6C1C37D9E00B543F4B29444F49430DA45E66DFC72B4C3F391B825E8C2744822F00F96C303F9198D97C33B3 +0FDF9759 +48567296EF8464B18C74ED282661 +7D5DA713114DC6F2B156BF585A43CDE4ECF563DE01699E4DDDA109C16BF49D8FB36D39C77FDA31C91095D7178A21D6A8C44D05D064AD339D77E5B75A5097FCCDA058CA0EDDD8DC0B871ADD5AA7778218A76ACAF1930B8110FAE73E699CB93643DC03305EAA936C3FCB377D67FCA867C327D4DE1C08DA792E3985043DF27E +7A6C6CD9 +94D728428C81BBBE2C4A91948FCA +E03F3DF34E3073A7589CF47B22737C1D192B13A5A26B8B61A86C076C790FA8902793970E072F5F2848ECE0CE85E7C592D0C8B61CF60E1902C895C3028A9DA6A26B1331EE54D763473912801A964EA28F8393990C1D03A4D57213F594B269024FA0BC01CA031062FB92 +50F7247C +338D7676450ABDAAB276A1D0570F +F3D68301B4B45BD7D039555F58158D2267A410FC8B096DA3F017742D24048472B1D4616103357C18CB82C99B853C482894488FB14E6CE1DF674A15CA37EAC7399468B912F145857325C6115951AD987C0F2A413D38F1C85306C86FCE69FD16700CD600F0B9E3B3C7F6C834947997E69CADE49545442D228A8C23AF785704 +4341 +A0B3C36614DF722622D9A6 +4D20D692 +BC12E2241251561C2F8F2315A9 +E94E8D31243657B096A93875D3E90C75EE780D57FB5AFE9C25582705ACE4B044F7B5B4B862BF46DB8A5D54F1673D9C2377046169E4BE3DC67B8FA2 +CD8907E8 +676241CF396EC2CB5BF943AFB3 +C5EE9263C4AFC115A43E583F171B9362992AD346BB43C2822C83EB3AD66CD60F73D638D7B9944AF99A657DB91A6D8F4230FB00C38FDEC4DB0FBDF37DC99DD1AFB13E3996B5A7AE +A130C956 +CB958165CE5DE4A9D32F6AB17358 +5B33697263F5D21F8F2ABA2FE436148D25B3E42A442DDC6DE5B1D552CF91B83A585BD1E12CDE4ADC3E7E6788C01CA4C69B26C19F7DE981A36A6CA9D7A3B705BBB75B37D8018CB4B27FF3F0CBFD55F6117B4D9AA4F6F0A30E88D6A9B92A624EDCB6A0E23D0FDAD12A5990A8574AD48A +DD8D12B9 +118841B84D23B887A2F80839F0 +C7FB7B8DBAA636D23A8B7B0F5C0F77DF158D23F214884CE32E5F69C437102E0AF623EFAA175C34C2428ECB0DE02888C2C5738F1E08EC4A319E3452C43717D5430AA035105BDD78A4D16DF796863B41121CF76884F527568372F354E8 +474D54BC +5A99DEDEC1E0390051B0E4038F50 +162676F678B27D22C59492C0EB505BF690A62E4BAC8E6507EE7E9C034027922F07BE43B45FDAEFE111B57B4A32434253B16AD2221A3AF885250F74F5FEE9E30DE9A920F2ACE6DEE2B39F0246A07366C3B7B06C0380388236F68D9A67344956C3FD62F4F1228994B66B02 +5F6FBDAC +53D25EC7DE907A9881EA678ACA19 +ABFFCD5BFDA4F2217FA92D9DEF86641712B6C7E4ECF7D5BC683825C1BEEE8FD5D0DBC134ACCFA4D439FD150E1211BB1878D8F618116F95DE6F1C2AA8E33F7E6BA833C707B96DFF2993D664EA494A032D00537B514E6E5A2CFE007CAE49A000566C774BC10D60B4CD7150A031C50BD31AF72DAAD4EE69A5B1E639E4BC1CBE +95F82712 +8A3F42BE555927DDAA9E412BBBC8 +6A1FE55FE84131F66AB33FE0A94C6603A21C091E77AFC22B57D5905063B18E350C0BD881F640CDBDA7FD7CF7457452F747DDC9E016031CA705A78892A77444A395FE16C98F1813367F79B84FD72FDA8A249B14A104AACC9BD02631BF0F4CABB66E82B496A904CF9498413FCA672DB46FF102FE7D5F8AEBDBCB1487EE6EDC +D8B2 +C92092 +323EAEE3 +1A3F96D4084D2C188D742286B3 +620DC94AC10FF685D6D075EAA8A4B61E193101904A44A02085087769B3DE819D3E948AF4E563D41834041C360643AC706F3FC374D1C1AB4706B9B652AF85CA3CC2066FB467F96A3D47E2FA80294A255713 +A7307F82 +CE2D0C8FE75B8382CB3BE2A25A73 +66BEC1FBDC4AA1B0C839DDB176025BB2719F3752F6C899867EC62672F11DBDE76C70AE289A7C335CB4EDF5EB68D1E1B44D5BFC3B2F4F3743F234FA0A8D2C215816DF0A0C9CF87B615C9FC5306FAC4F4CFCC8A555F9843B35B1482F4486EA8DE9DBAB25B5 +50604891 +0A800FE64E070CC3FA1C4E6087 +B3CCE265402C3A7D50AD6CFF8B70931BD5895DF59EE254BF8242EC8846426BC8436E96FC839F737BBFDC2795EEAC417B5F7958C4AFF3B951F9E660F5B0CA4AC09DD53FDD3F8C45408CDA8E562C20DFE5035DF339C019C124B8 +43A90B01 +EB8FB6594D7F8E54AFFE9CFAC92B +4C43DA4542DCE047F869AECCE943745723095817F638A60D978020E42AD0E5226FE61826D0D417012F09F331700C5A889C34D8E5EA2CB4B5A6C8C50042271CB3EAE0CE5E2A1BC176DB6D3DBD3F11655F67447B815A948074BD41EF0D75FADCE69479D15C3E5461F11DA905FE4B4100007D351F54E7F72BEDDC023583251F +4A82 +911CFDD645170A58D4B92F3810B056F5 +1B470638 +1668BAA627351B2AB54B497D48C8 +C7F268631C267EAA059C67B57A4B22A34D5270C1AA6E3986A5A545CEA3B7B556D0AF059C0B96E5B493A3363268CDFF4937032C4FA1CE693585E0595B6CC093C160DE7CC86BA7651F2058CD9F904CDC3F9CE6207DD16B6AC67991F7C405D33A7D686C77BBA44466792F2A3D0CD12ADF24C2D519468FB48C5D7BF091172F58 +47B2 +B641F03DACAA6A05E441925062D5E73CF7D8AB54F50593C72A5D2ED23346C0C7907C7FC7B0168D +694D1D3E +9BB0C33073545F56F027BBE03BEA +8601B453C4946B47E3A45D7B89CB9AE577C3BB546D2C71C02C86BC3941ACBAC81982F1AB49EDF6F9535993706AB1999DB93BDDB3000F38D717DA6F02A1B51431488F400A00E8026822B1FC62D22B2AC245531A8A43D2F63E52D4F91907B9A8CBA9A0D5C34F71F66194E9AAB9299F5A44B6D9B2 +D716D280 +8F71643410D9351C22E6097A20 +6C910893D523F39333B0E8404AD8C2905181FB10C6F8 +5F563BE3 +498456BDCAB2B4E0A75C2BF4A17E +92DFB106E1CCA828ECB379549B3E85AF04B00C658E0ABA9AB2D115F8941960DBCB45C770345BB4CA544C37771C5D09320700770C681D0A8A9191D9E203F07C64094E4D26A2A50A2B5BB6CF3D032A32B762A9E60C8E0E7A6BB7FC383EE6BE4F3F44C1DCA3C9EB6A8680F8990966AF6283D540C0B16F3BD3761B2B55ADE1D8 +8A52 +F9262C +96E242DA +8FD9281136D78528F14FB95130 +181253E98ECC48A2A5E506B1B189B76092ACBBE122E6350ABAF0066070667E21BAF4B885996676CB21179D5639B244CF916DF25E61D99DF353C1F2A5654F73DBBD643EF0E9E7956550A9B2F6EAB7DCFAF2E863191E75F08D +66B01B5B +8F822D9B7390C470261C603B83 +4BB03CF46C9B6699AE1747A9C7753B099F64BF0A9ECE88B81DF13F0653ADC6AD50AA898E3A8D2C01F306BEA1BB50BC4C5F0B7021A436D6D249AFBCAF264713A4C02A51E786671DB4055F462B8CC574D46697 +9032106B +1EEF9CD95A82832FA11D4EA331A8 +81C43BEC94238DB93BF73CAD99423B74CED5B9B55BC15DC1861F162CDFE2189DBECF8069BDB7CBC0C42AB8C1E093EAA3B891E30EB11C86C7FE3CD8BA79662D0487D7BBF2470304F7CC926D4F8DA9C0A929565229C68BCC1E9DFCB5C5ED2725E7FE274EF3CF8B8C2D816FD8CCEB0B +8917AD7D +922E3A15118BEF122C88318851 +7EB0289A47D65079C6245CFB15B67CFD01BEAEDDCF154AE2A50A0EF635C9F06217D8E2C8CFAFEA8AEF9C2C6CA6D9CAB580C42B15E986C90F8BE1125E51ED54E277C35857C7A67766280AD15B5A12E66B7ED0867785810C5817 +84A0A693 +586335074DB89FE203318FE113 +C2FEE0BE0F8424C79B5D8483961F166EA4C3861A7A4363392CB7FB2886A029ED3FD41E2891DD3B087CB1DEB6D5710EF83DA280003F762BA641B98F2EBB8156FCA8D7958270F4ADA9CDAA094F06D64E12A3C28E43F6F7FC46E5119898 +5B3723AF +471984FDA0A4EB3610363874F62F +6E7E4DB1F03A98D5FC105FC672C64F082E230B5B2350B85F6C486554E198EF5E48AA64B4EFDD857F4F43D84D32FCB57EBCC3B5E15440E3B9970DA6AD1D2D2F17C8C6948BC3E66AD0465848046A1904BCAD5E40E1DEF692D4B53F0A710902914DE4CCBB46653B86FA58DBB4B434B3FAA00DA079A701DBE6A4CAD2E6B7F7BD +36A4 +8496AB9D0A3B636B3CDD645D13EA2A909541140AE08D77A36E7C15A29A89AFBC568799540F64C092675B84180189E7 +9A999296 +42368AF77CB869768E1860B49A9C +1002E4C327F9E84EAC8B8E65897348B7EA65114A2BC4ED4469AFFEBBCF3F918B8BC576EFCDEF0A62EF47EC2079238B8BF7F14EC9FE8552713590F3CED85C0D5694687A55EAA3373E1897A0795D62B78ECA0EB00A90258884868AB12DF515C523DCD46C558DEE918E8C8789501E +CE6D87EF +D41EE61C38B51BAEFAF31273BD +8C22F124C8CEDAB85270A880045B931F99DF0389161783BC8AAB4D93314EFA313F948C8A3A04FD0E024B86CBE92ACAB98C0D5673FEDFB469B01F2562E84DFBD894D170A1C3246207CA980EDD74EFAC64 +940F5182 +53997F06526610820FF8B56D11 +61CAF14D90A7F57355B3094061A5CF266925D9509819309068A4930DC868943D9E2CA0C2FB4E3254491C31162B122759507764F95E9D9CBED12D248B8D96465E5A691C8113606E213C20F168E61BA1A320800DD249B447D26C4D7182DF23F8BB3F0104 +5EE1EA6F +4E9F3761850CACBEF7289B06FAC2 +DE33D3B104DA85F8456A102900AFE6783D1787BE1FDA2410CD5618391EF13C5FA1FDBC4573CC06B6F2146ED89B24210B391C29908CD2EE35F306857763CCCA10F1C64DEA5EF997FAD9F880203977B4FF7ECB42DC09D7CCB409F17EE91E30B44D2E0C2B23F682FBC660831D0C60B3BC0A9E004DB11EE099ECF7C5BF727F7D +2111 +2803789D1BA38CED346CD87D83C45F0BEAEF03DCA8998B1E72EDB93C002BBE3F54EBC8 +4B487F04 +776739DE7E1E4706DC8A6BA568 +E04DBF11318EC0917FC4674673A2E8A6C0C1C934AE90C8368BA5196E985C6C77149DF4AAA1F12AE7410AD4E05281B062D358CD900F63 +A6689663 +B30CF1E9902FFBE1058C0AC8ADC2 +206AB306C7974EE3F32862385038E7FAEB3C7962C14E02553C2E755CA23090F7232525A30BC4EEA29AA00E6254E58C4DBFC5C37D256A0519E6BAE1D3A45C06FA24828B183DEF95010BBE845DCBA98CA295F777EAB7C25561A354D8BF237012CB692AAFE914D3D55BA3A9472B04459ECAFC7D04ED3F16E343989A75CE3D66 +5A24 +D18E7111BC7E8D86C5877A9DF0662AD5B5D00EE81F849A50957976CFA1F2AE +1B24A910 +072BAFCFE563562BF0C3D4E2B235 +CBA28CA5CB07F24950C60C9CEB1CA03A5A8F482C04032BDA7FA15AB80882637E8AF503C0FCF437A668281AAFA6B1927B141E4493C331F72AA48826068A24D4A512D65C76ED6B3D8F341E0E64A5363C0151C67D0DF8053E5065063755529C55F30C5B64209338CCAACA131357 +26E05D89 +6081E500C66D1FDB8B7B2D4EBE +B45D64F92122F7F3AFB07224C2BC3DD9F89CF5577FF8DD40015730A7487F55AA528FC45AB136AEEA31FDB71B82C6BA20DDB9469A1DA3F1A1AA90C14534080212C3067635B9AA +5FC39630 +D05EAB472DCAF8493EE055D57B5D +C09C95C9308666CC6FE2E9118E1F1DB8ABA12B5574E62A9BB43D7440770BEBD3A8D2ED7328663EA0006321FF151B9E6E3E6AB94AA69201744A7C3B2AF85090B3B10344B78DA05501D30C47640A1A8FD5F35F3642FF56779BC4940BC05D37CA8A953F3141C8463B9B1F2FD91790540B2C4D33BEE3194002 +559C114A +187F8A36FD97B26341263E24FF4A +A72AD911C3EDBD8CD562AE8170C3C1D1A2CEBAFAA6F4396BB2FF2B2500B2F868219B0539416C4F109F00D3412DEBE7372041C4FA8CE1BB3CAD99BC411D46EDA85039A07CA70983A3AA201DFFC445C7ACDEEFE43C3EBA969543C8AC330166CBF772D46321E0004DD0A747 +CE04D6EF +C5AC75A2A5573715F816D59787 +9F762BF764D41CD8365EDFA261C64D192CC78EE444F33BB4150E79622477ADDB1794FCD6BB6336C4EF97D6C58BDF5928EA25B1B8BE246C6E2D3314AD0DBDA525D4844997D45FF4E811614B814F13AC182F1F6483E7B269 +BD016B8B +73ABBA1A5D45231C2E99B6E803A0 +A99CABA8D9D7B205A513A8DA6FA368AF9DAEE74FEA862FEFBF3D82CC72C76F0E002D7580AC803E5160D820867DE85CE17097DCAA6BBC53D72A6C6CE1667766A4A5FD6194C55AA7321814C25F80B9D7F4A43DAE781CF09F3DA642091B93CDE9EF352F8A22AE553B5DEC13EFFAFB9D2FFE291F6A36E5765DF38932CB8D +E0B2C862 +376966BCF80D93A546D1666090 +276C020DA248D3348F867E6203066F5D87CD5489DEF9BC84B09AB2327F996C5ECA40538A1443B32BB140157DDB79640A097CD0051FF9E46713C1C1B8E806035BA2AC3D994B +16E6DC43 +617B38EFCD3EB3B4FD557CD847 +704791EB83E366C680BFEBCF69350F4B8ED81D1D0D5C60CAEDE58CF67C75547D6C5B132D9F36352172A4606A34108015406E95F4C2FF3BBB2F734CDD8A87E85006B4CB79129B5EDDEAA1BA132973C15D8D51AF97B4BA35E4AC2EE5F48FD4D519C819 +6D1E8E5F +04AD0334F0C9FFE10BF30DE0CF +72BCD39D1065C5CB520530B819CCF3B9E4618A3D10137C6BEFA85CEA38A3465E44A3785E78558584F50FED5DC302F0D3CEAE080DD090E5801EAB4870B066AB60B61E3CF4CD309AEF36D0EB641D5DA299AEDE8625144EF577FA +80256CE7 +836864398222A8FE4B8717BB4FF7 +79B615A41C77A18D3EBAFAD2D01D0E38E35302AAA66AA3CC271E574BE0E1DA2E2804E78897337665810E7609C09BFED0688A2919D6C5BBA92FF9E214764E959AA266F789C157396F3E45D00FAB1F88FA3EAF202565B1F6E886E037C368B3ABEC597EC300DBC7C811B5CE70F07F85351B3BBE7436DF6EA409AD1E76384F13 +6D0B +BFEBD46F7DC8A73BE54C7DEA3092 +3306E970 +9517449E9CB1FAB291919E292B3B +57E1F7A98BD06A638515B5934E183BF0FCE485E00C581D8ECE81DDCBE72C31B62EE03DA35D70501357811CA4502DD7545F2EC71164AED6BB2B5E81340F0CCD35DD8648E13DA151380F5506B0EF243C123D7A0504EBB6C0D2AED71D89C580C6FE51D1B7FB23607FF9134B84833B29A7DB23FD260BC38EAFBFE08E3EB9534C +A639 +3795F04C07DACC57A2DACD33D0AC7C5EAADA015C2F03B0141F +C3F563D2 +C838DBEC0F7277A9501BF2BA8BC7 +5D30E26CB09BA3A271C57CB75E8191DE447B5E4CA1B40C129EBCA481BAADAA4FA33CB696CCF988D975B21F4A60E53D4F4BA21EA41F7F3F0BAE53E1C47A9F89BC6D495223DD5D5793FEB20383ECAD8F58FE1513758E2D9FD94652AF9D4F2FF18A620B4BD986927F616C84E5E3BB715597775F30C08D063B48A94A83E838AA +356E +C2D90A2D +E2A1BD2D7CD831F773348A88CC +361FF06E04E242FB319918155B2573A378759C1389CE9038494C43AC6A725ABE8E68F84F02CBB21D6810E326B15680569859C8F383E140918E8B6AFC0810F4 +C2746B7D +099F797105549F1A771C1041B8 +A59CAF372CF58F58AD13D3B64733C1A33DBB14BA9E35 +71EBFBCE +7D56DB2A2F6E63F68E47E6754336 +416227A60E8B6F9E +8E384BA9 +5171F3940BD06F6260DDCBF6BA1DAB4F3D7C09C3A3B98C84D46456892C28DA072F14 +D55E83043A029FB7DAACD402ACCFAF56F9D8FA817CD0F9436AEA450A1BFF024762A161C9973F +F220CDE7D88F22E50556A8659A930E68E52262BC22162DAC6A7CF2 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +%Defining font PSOwstdutchb +%!FontType1-1.0: PSOwstdutchb +10 dict begin +/FontName /PSOwstdutchb def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001000 0 0 0.001000 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 1 /C0032 put +dup 2 /C0044 put +dup 3 /C0045 put +dup 4 /C0046 put +dup 5 /C0047 put +dup 6 /C0048 put +dup 7 /C0049 put +dup 8 /C0050 put +dup 9 /C0053 put +dup 10 /C0054 put +dup 11 /C0058 put +dup 12 /C0061 put +dup 13 /C0067 put +dup 14 /C0069 put +dup 15 /C0077 put +dup 16 /C0078 put +dup 17 /C0083 put +dup 18 /C0084 put +dup 19 /C0095 put +dup 20 /C0097 put +dup 21 /C0098 put +dup 22 /C0099 put +dup 23 /C0100 put +dup 24 /C0101 put +dup 25 /C0102 put +dup 26 /C0103 put +dup 27 /C0104 put +dup 28 /C0105 put +dup 29 /C0107 put +dup 30 /C0108 put +dup 31 /C0109 put +dup 32 /C0110 put +dup 33 /C0111 put +dup 34 /C0112 put +dup 35 /C0114 put +dup 36 /C0115 put +dup 37 /C0116 put +dup 38 /C0117 put +dup 39 /C0118 put +dup 40 /C0119 put +dup 41 /C0121 put +readonly def +/FontBBox [-18 -236 919 694] readonly def +currentdict end +currentfile eexec +D9D66F633B846A989B9974B0179FC6CC445BC7C8A959A39A32E9DCE7FAEF17EE3BEC9F +50E1A6FCA651FC4B3769A0A91041557502E25A5D6180FE25A3D11BF079E1DF66E54EE9B7C229AF891739707A2A0EC140306B5E43E52B79BFB89E459E50 +6EC6F610A70775A31C460976C4F79449D86E57ACE491E5C6BF20CC4307B1DAF7630252 +E9AF8CFB69B50EDAE9D36A6104AFEF8832F920FD2346B2C7104CD11E3BEE999CFA9F5A +49DB3173EE48D1C82994237F360407B022E0B4 +502E94EA8B493651EF2D03F0B513D655047568325B512AE6 +6AC6F53F3848CF70DE25481CC65D8B1A5793AA +3C4282D111112BEE28AFCA7A3808D4444C4669CA +84EAAAF989219F51AB3476A1B0B5F2246BC306E6 +625C6679C417ED2A8E9BD010DE37D40265074C268420EA157C62583FAA018F369F10C267E5A689 +14B3CF05D7E3E7301A1D113C +B87969B0B7A33DFDE5 +61041C8A +79E0C55F075199031370610430 +0D19993C66A904E0A393097C33E2B533C751B03DB292D3F16A37AEE640B3CB8F7D47F2E44B2ABFB4C83CFE179622890516BEC9EC41E287FAB18F +46752A98 +B524197F79749498F1B81B499E +5B173784DF8DA9E453CD0839B33BA0D67E613FCB416EEE +9A51DA49 +4646622F22B13473EBDF96A0DA +8A349322E8D94CD0E91C99EA0C3BC09462899C6BDDE61874BCDB50101C49F1 +E1743DDB +AA28EA75BD596206B5A4634001 +0DBFCC4D7325F9C894847082C9A033D53D535913A2EE52F5E5D1 +8B719787 +C76C4EC775873B38A9643FD07D +8F6E3727FF481191764AE061BE6A01C69B4096F0F28D6D24E4B1F1FF3E9F2F112344270D0B9903BCCEFFB1963EC2C7FB824872799A75130542EF4E5F6CC7B345371701E6D25ED10DD4EAE2DAD35038 +3D093C19 +AA943C4837971EA17C5A88AD6F +BC2E7095A034415DABA956EA6E4B80E286684034439440B52E332E5A7E6D38805642272A912779D512024D21B61C08A1FD0743DE5DC5D165E53BA220 +9CF14F2C +68FC5E67267B1A82A1FBA50CEB +E2BE28FD12A75107D67272B35C6DE13DCD6A4622CAB65218BC13085DF6091E8A464A8693A6F2246785F7049AEB7CD6DB50D1566145BAA8C72EFF060EE84779A4C137545B19517D4C7D34E8FF72C5CFA7E9323DD2 +307F5882 +053CF4BA4234E5AB998A29528E +45C47F096D435114AE96925731B47F43CC90090B967800D124136C39DFA33E6B5BA7CAD8B0F4F19B93B7B53D42BB0EC589707367CA3620FB64F34234BB9EF20BFF9F2EA05EB3E147FDD83478EB15D7F57E44194110AF +C70C420B +3461EC80DD6044979A858F1D8B26 +E038E11B291BDC0AF7615A89E5A9576E3FED2C2EC4018BF87F4DBE187C8FE9923D42DE52E8A079C88309092C426F20EC3F4C127802990510413B17E215BD071B507906FECD04B857036A3CD29C29A9A7F0DBB75C375B63044F7D3F8CF48DFD57881BCA33 +D94A37DB +A6F7A836FF62458B8F141775ED +7DA74734FB3C4A53BCF935EA6E42D6B6641A0AF43A9EABD066F4731BA9E3BB24596D469DF89DD8099FB976E7ECF32FDC3D65A70F8A22 +F4170E7B +5BB138F3C25C0E0F46E1F5AC04 +7A8204F4986A50CA3116C07C88BDB4FCAEC69AB1BD624C43005DCAA9AE74C97F6CA4EBF3 +25E1720A +3D85134F83CAF5E45E566A523D33 +6C8523AA7543DC023C5345BAA16871A86FD1BD503C2D538AB59C620D72E831CE23E43001A74ED8D08B77F56327D454555FD49B95B983DAEE9994F47EE1600C736F28939E8C2E0D01B44D346108A545B4ACDFD172EA23306E03F799479F3785ED6188FD0DBBBE26AD +6E02F79A +969C766439539FE9932CAB3DBEAB +AA2246EA4F27A09CFDAACA525FB12C6EFC033189ADE59517121CECF64CD797C7D3702DCD7F27E446E047D4D81830B98198B53F1B163FE79074FB2AC30EDECE6CA72D3CCC8AB871BD95E64CFC4EB215C668522A4D73B092EEA683EFF5BC7D4A398B342CD6A37D22E0CB92C1DA9729 +56ED6316 +8C3F42EB6BDED7C72EEDEA0897B4 +F8DF6310D7AD7D4693E7E56962E6DE34C1CE037E1EFA1A84B741B4E3C5611B1D695B62C281AAA28B82C99FE262898266E9299738857957E9F2147859A9ACE95CE99B7F9EBC126321D5791EED144B1C2452B74B86433B142E6E36EA28A6352F8FB9870287F4CCB60A9FA92C2220 +5A0BA96C +9FF934CA806EA5D57B9DC97331 +9C4730E59F63C0ABDDB84CC03ED580DB3F9AE6E07ACDEC5AAE59BD0100C6EC47376A3E88E6A59CE569BBF6469F5EDFBB57EFFCB2E005317629BBFDD7C889A47F5C07FE7FEFF61721AC6E72F6E78492E7D7731CB7626A62F3D005CCB2465913 +29F0FD47 +5D024B81D983224F5790BF020D89 +506CD127CC900848888BE0F9A2F929018A5A6EA547E5C6A21D8EF66AC112EA061D88EE5B331AF15F11ACB58C64544331B37653CE5CF725E6B9CF48C419A443F221178D96D95544C4602352F5FBC55E0EC0110CBA0C880BFD0969B4625617CCA46405F7CAB49A8E0948974A7196F28920A94BF064A40582B6F4C453497D1C +7639 +FFF56DDA +7B2D88D0F600108229B1E3B543 +7964E2438F1BF81ACE1A2DE8B920115807D489B7E3C64C165DFA3CCD341D65E8C49F451AF8D62C8BBEB514D76A02437420AE7E6C1396CD44312ACBA934D7C7EE7A00D7D820A348A8B0 +C253401C +8650DFF8297ED4F78E8EB349CD +BE1919CCB77B9712920FEFFFF517F1E06583D93BDD03 +A3F0A7A9 +FDDC525DF0258B340A2F54DAA7B5 +4F9E1814862EC3CA1627B39A9D54D62553F17FA82CFACCE5E83AA49F16C54BC7478BACC360FAB492392CE34413D16A566122DF913A4186816B5D6B319286E980B22D757949458D366A95301C7C884D3A5E94B4BEA47786613F162D327B25650BFD118A208E6D4ABFC5C4CEA1D03672D2CECEC206522A3E7A0CC98285F096 +5B26 +05492412 +F7E1661C +4E57F76B7AF751276EF8C8669E +B2DE84B72AA35900CDB0F27D0C1A3EC5DF1C1C35187B1BF96D4314BB30DDAC7C7BFB8CCB1D0F83F695BE257630E8374109465FF7C63238FF12C88E2B80A285503DEDA7A81642A9D99D567A7C421FD02441EE83749630A6C588E755D2D122 +74CA80A5 +474460D6C8FAAF8D5B032629C8 +5724CC1BD009BF8552DF2B010F11F540157AF7D84180CCB82A8A6DAAB5F1ABE13C37D53C87EAD6D00C2433F577241858F5A134314F59B37D67A3FD0AE1ECA3A7A6F7288532E6FAD110CEE9B82AEF6EDEB925 +BD2B7695 +69285D184DEFE4F47061E46FE7B2 +426A09D32FEBEF5CA30772B0132B8C348EE0288913D684D65DD25CA4A3404B297DC69F6A6740634FE579DBE6BDECCB8370D51C04ABD695705A7A1E1CD49752A20C97564529B078D52F759D355ED1BC24E0597BCF6B3173A5F3762A902158F93740EC0AA44EB08BBF4A757700 +21C1E3AB +37AB10D395AB905ABBF6273537 +9ACF33097E82ADD0A4454DC69058D7F73B600890B97AE3E252943C66F9701ECF6CC47A377AAC6A313CD2D9045E3BD987E0977FCCF6D9A34CD88962E9C6F75071C2A3F7514EC486C8C2A8BCEC1C7E6AB72F9BA7A5CD65454118754546 +0C45A069 +4C6B419C49C9432F2C1CC2C5D6 +ADB354B0783D02CC599B9E6E51DAC4AB828A1026E2CE0289E7AA2D0F4345217380050DF734F561D9D054E44E90A7DF2E900B5E7F4530A2894372B10E6DEA805ACC3EDBDA9DF8BE8E078C4C25F138EF544D1D590B5AF6D30F9FD0E3E912 +268CDFAE +224FBAEE628AE4515DD6E3F5A259 +B0CC129B9F5AE8904A842D7173A22F0D868D448CBA274446D885EC5A15797FA6808413192B7901FD5AF670D9F5CCD11FA089F5074A924A5C2079DF83B8B0C961F51D42A8FDB29D9BF870AEF620B026C6BBB6357BF36EF6222BD40CBCA3B9CF4366F9103F7CC484F321C3DF0F38AFC728453C79E0C4B7726ECFB14AB205B7 +A831 +FD40DAC22555719EF2FB196354EDA0EF1E510DBC31180EE1F0C3CBDA2433450CA6D06CB2EB +641E5951 +3EF895049190F9FFF839DEEB728C +C5B35F80BBAFF0C73ECE4DD702CE9181F46E8B80EFCB310B339C317780AD84164458FB0276E1BCF3C43BC89381915C30912904097F8A21A0A0E830CF131082B618301BC33786904A286CC2907B6942B3ABF6A91401FEFC1D2F3E207B88DF6D1B490999F76F56CB59 +25D30D78 +783BDD52E1648CB91A388F17FB +9C8895B4F564DB0C688FB7368F1E6D1C1FA7268066C2B7F31AA40F004B3ED72338516D89DCD75AAC72DF28054AD75D1B551576D1AF9C5944F82CC22395FD58A0A1E2C292960D5ABAA39D11C2542B +7D281DA8 +1E5B41AEEB8AECB98FF185AFF1AB +405004CAA3FFDAB6BE516600BAE209B1CDD982838CE322D847FC587F86996244B0180D0446EACFC726ADAFD75C4D56DB8F5E40EFF9BE5BA48F37E35CAC22F610876E756572CA82333F4D09BF4AA3CD458560692A9BDF73722A79DA74EF9D36535B873D8A932F024182E13F62618AB2D6DD29AF66F0889949B0A57F486818 +F4F0 +D1B1 +C91AB535 +A23F59F93AAFF583F3B3203DFD +65D580C8CD741FA6732CB0E5510E46654182C1BE1D06E6F7FC9525F71CCE6F542E8886F8C76744F1C8707EF6E5A93CD41DBDBC07 +50601D9F +3390037A5FCEAA91FBE6AD891937 +6E03009F66289ABAB24198D24E161C74831C1BCB9E7085C394A441D87CB292C31C542E05E2AAD36428E6D08A05C85FA20CD08459610B7C03A9C0CE27F9293C9CF5CBD248BB66AE86A2FA0E997A880347D9370083E0B2D509B4F97BD49FCF6400FC43CD10556FD8B6FFD29FA282CCEE06D57DDA5AD0DE74C0F60966D66B49 +CC4B +3D7231AC80476892B75A5D0906D5121A68B21CFCFF96005F9C6BC003 +EEBA1CB6 +0C6D8E2812471EB83561BDF0ED84 +C9A57353C5DFCE1B69D837EF98DFFDF29FA2566EFF3BAC49198B3FC23735E56D3EE0B56B55F6B6479E85C03C336611A2BB7FADD20F9D95E7E050AB14BF83276CA7485B44B1C5611279C4B58A99BE1925B09E760D3F37AA54DC28446A39AAEC5D7E681181778E70 +AC427279 +3617D5B70EA8F863F1A76D7775 +162D043854B545C38A39505F4E41570CC224BD73F8D749D856AC1A7BFC895375FF09A90D54405B9938E4846658C1922B6AEA121539D4862051583E44E537C19B7AD6637800BA +90238AA8 +8350DDA0AB65F8ADC6193E2F1438 +FF2C98CF1095B49FC86B2104560847288A1E19FB6FA727AF75A6D3F5828658FBDA903E379ACB19BED633CA9089E9C2C7185D9CA314AA9CA38425C8135CE4B21E10FF758520912E9F80F11C6EB40CC5801B57AA7C67533C58DC93F8474822DFE28579081C85318FCCBFDF3DB0E7F72CD7F0 +F675A8E1 +51BBD166F0832370F2C4FD57B0 +891FBA2ED8D375BC253F452F63421A49F7C27F180B59D8256306BE6155F9FF4B685B7645CFA5FE0923F232F5BC7C2078D90FED9E9ACB6BED4030C21967A4769149382A97A5E7DE9276903A57EBCA47B6585DEDCF268E3CB938 +F78024C4 +93272497A4DB3A348B4DE71727BB +69D19BB46210ED657F9BB0B172F8233952C89BCC772CE2EFE88F90470DB67B3B90BB838F346B4C6C81B4B7B1E48BC8D52C6740303A7F85CCA6D35BAF6719A870B3ED774426CBE24C75FE5BB87013572BD6BAF42291F301A7F4AE2934D23960A43C7829797FC5FAA8CEC2E4F8A450221096DA1ADB194361D00F +F2F15099 +6E0594AEDAF49D2043FC5ED60A +F6B276719CA9678AEFC3E1F1CECEB72757DCCCCE54FD5429B20E70BF4D47E3D39E7B2B75654A6F5DC2FFA98E114A1C1B41F50D0DA8A30366CFB0814DFD3641D4C56CEEE5 +FEEDB3D9 +85652A1B5E43B9A5274A79DA80 +62B027444E022D17ECA62C39D648616457938D3D77D43AA2E5A719094FA8DA12B7D1006F23F55CF0673F105B2A0D0EC18749C384D3C4A502F7B33F1E5AE1A9506AD20EA1CABC95F299C670C13B88ED7D16262E0854A1D6EA2146A5 +079EB169 +91D0E767A7E72B1ABC27F26A5A +3389398C765FABE0B70372D7B3F9DA59F3B8336118E4EC64E47BCFD79D21E70800C58137B36E6CBC07E94AD824A5933B360552251A9B8CDF7815AAEE56D6793A74495A760B21C062A6C40D89AB0C06E1FCFA0B61666FF41AB9AAC2F6 +9BBD2FF4 +C7EFA229734B7F109AAB7CD77EED +DCF5D5FCC4C70A3B5180E86AA247DDFF96360D1200ACD5C9A83C9718B27B8AFE1645E8032510E99EE3F9FAAAB982597E345623C21B44D8BD66CBA8E0C7A59E30B2DD552DC80D0CF14B9692524583888B34FE8E6CBA42D6B964758D45B21B37984A222DA630CE12F462FD1AE5FB34DA53E3A4CB5E1768DF90D06B984E38D3 +25B8 +7578B2F1AF3516AFC2C147 +F4213B55 +C121836F6BE86E04EC9DE3BF0F9F +31D7909572D2DEB3D0BBBF7C7720A569639EE37D525F931B5FC742785C1E1FCFE3B971CED2B418DF5E3EE78DEF51EA725239DDB1B3D4D92CA4584066283C2842D53974A964C423929483FD530616D4717378AD452CB420CCD378FB2E3261C91A0F3BF1FC9719BB267063374590B2216FCEAEAC65D66BC958311A2A903E79 +83A6 +D1 +AA5BF593 +499C87FB462EE8FF358D1E168543 +480A39A586EAED31 +98D68ABD +403BF3E211609D5F4BD402F7B99F354DED6ECACE93D4B00449FCC3E7D418D839BA59 +D373C1221FFBC01199C5679DE5C67C4CD0DB2D1C6405416A989FA8EA74CF9C1ADAE20D1D74C3 +C117B006E5D1BC322A7BAE0799EBDF26A8E2C6A527D30D4C86EAA7 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +%Defining font PSOwstdutchi +%!FontType1-1.0: PSOwstdutchi +10 dict begin +/FontName /PSOwstdutchi def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001000 0 0 0.001000 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 1 /C0046 put +dup 2 /C0047 put +dup 3 /C0099 put +dup 4 /C0100 put +dup 5 /C0101 put +dup 6 /C0102 put +dup 7 /C0105 put +dup 8 /C0110 put +dup 9 /C0111 put +dup 10 /C0114 put +dup 11 /C0115 put +dup 12 /C0116 put +dup 13 /C0118 put +readonly def +/FontBBox [-136 -228 513 724] readonly def +currentdict end +currentfile eexec +D9D66F633B846A989B9974B0179FC6CC445BC7C8A959A39A32E9DCE7FAEF17EE3BEC9F +50E1A6FCA651FC4B3769A0A91041557502E25A5D6180FE25A3D11BF079E1DF66E54EE9B7C229AF891739707A2A0EC140306B5E43E52B79BFB89E459E50 +6EC6F610A70775A31C460976C4F79449D86E57ACE491E5C6BF20CC4307B1DAF7630252 +E9AF8CFB69B50EDAE9D36A6104AFEF8832F920FD2346B2C7104CD11E3BEE999CFA9F5A +49DB3173EE48D1C82994237F360407B022E0B4 +502E94EA8B493651EF2D03F0B513D655047568325B512AE6 +6AC6F53F3848CF70DE25481CC65D8B1A5793AA +3C4282D111112BEE28AFCA7A3808D4444C4669CA +84EAAAF989219F51AB3476A1B0B5F2246BC306E6 +625C6679C417ED2A8E9BD010DE37D40265074C268425D45B1129312D100C38E38C9BA49A1662AD +DE5066B483A35AC76DAE2919D5 +FECA0738C1293E92BB77CECC82E7F29BD4F2F112EB58741E538E5FA95AD969 +E7B1E558 +149C2E4EA9A150760E7E15D5EB +486CD83D4C6B249A0E5F9A7F47ABE22854C259B2A8720F95B9 +859B895D +0965C680D65C5BC7CC772CB574 +2104AAF777B1A0126F7BE76847E1492A4EC9A977D79DF1366F7D9114916791E46E275A62C904977248C8AA6FB0256C00960030CF929D8309D6589D851D886B0A90AA7D81585CDBD1CC1B72B858D2B7B23C6C686D958CA99A88830F89A8FF30A5 +78F2C089 +313540990FFF155A53FE359AEE06 +232DA7EBB1516054E58A59E515FDB8E8F8F54BC298005EBA840E1E4C4A34DC3EF749A9B787E743EED0A2A628D4974FFCBF0C7D2DDDD3DA78283680ED144A944464EBE0C909B6FCB65500A92DC46CCF829CA913B6AE847951839A6292B5408A0C615EB9232A209E323530CC8DBDF1435A1E30D5F03AD19CDD869100D6F5E9 +F617 +D3E5E0091432345E1AC3A9BCC7B98DEA4E9142B09F2D8B0FADF5C9CC1B169B046E02F5E42FF6D4F454DF87AD6C47F2C4 +FE92F71B +6BA8CE2C7BD6626E6B425247CC08 +127C60B9C4F3B4B33F7877ECCCEEAB4264FEC966BDD54B74A28E67CAE9F4BE0A17737CD68329883D4B40DF9CB5A36B483991A5880A7ED610D38736BC9B488D3DF15F6C2E0DCC30D770497300D92F8EAB5EBAEB8C91A8B935F99BCB210A51E080EFC8335DC8 +50656871 +D2C82ACC750F34EA2E01E81524DA +D37599C31CB40BDB3C8246CA0E8DF41794A5DB01CD5CBA3443D28961CF591C1B3606996453E8B8E182DA14AD205518646139DF89CA4CF6CB126D956848F04C777476A3894280A2184E6C681CF5D9B94AB0E549DBBD592D407857FD7D86F86D6EF065393BC5DB223C06BD31879CC1C287B49FD8C7B75E5C9A91F3F8BC8EE4 +5D34 +CC950861 +F2AA2379 +58F975E3078F4038EF515385DEC0 +F3EC7AA8C2392D1B8F4AFF0C95C6E68CA5DE1C683306C97AF6780A7B39A2E6E4F3700421F2ACC26B82163E809F169D6DD255B2B7D29CC3326B9FDBA56F688FF637420FFB8F89FE35D829059488218DA2995F140C0A1F2182384A22FC394A82245ABED61D96B8965285919F9FF83A32219F3D4F79AA0580B9EB +8F815D33 +AA7FB3A5392F6AD36031F6F37D97 +8D7F85C9399739D7B14E7A401419C7311E7BDBB783742CC74E8E423A979F15C8084B018B1E1112DBF20299FE8552040C40E4A31D0B179C16AD5AB369DE9FB6BE58C773BE22F99DB532C661B7656E615C22ED124C29D3A0F12A2468F050051C855FD49ED4431E38381AD255B32F69392B6D30766751A0C9620B842E5ABB1F +0338 +345C6B699BBB858607734471B91C2D1D71C368D93C5845FFBA +A8ABF2E1 +5F61646D83249CF87F406C22EC +02CE64CE1156E1A35DCDE8E75436DB9B6660A963A76EBADD8CE0B72AD136C8716BA2726AE6DCAB06A4D385EFC0113ABE2BB4EE0284044D2646BA730CD762E208C8DEDBEF204BB0D3B0A8C423B087532A48B0E8EB1034B2CED4996E031CCED5 +59B507AE +B7808AED5140F2969ADC0D4302 +F9400975ADF8EBFC9B0B285616E98057FB63B5D5FF927EBB2C5F247153EDF993E20190089CB7A2BA8A2222EDF6FA182065B59477F34E9CD47FF325C6ADEA4EF5CAAD1287BDF38670E079BF383D6A82F8F6A4412DDF9C7F6BF42156 +9917D52F +C29B2CA99486C61DA6706A14598F +301B6A7EF6674B33EECC43339C54F5AAB3581B357A1C2527F7092B32B5F27E6A38D491D0CC29323D41C6258509ED2FE48421F0690043A40F1DDEB80F39F7C34F815BB787FD431EDC21CEF5E6FF94BDCDE5F6762E8D66F8285CADD1F5B5A607FE70EAB539672F3C0BA7457C2B8B1639AFBBD95F967AD7 +835B43B1 +2940434F0183C859E838232A73 +2EB571E1B66D887603A412B2489DB6349067D0AEDE347953C06E48207EB1535FBC47E7BD198145C685561CA9E393647D47803C26EC4403DCB8F0181E3C80095447D6215A9EE3729DC9C4D3AE25A077D20B23703AFA489C +5BE759C5 +94D4A5516827BE96ADC1AF60D1 +63801D29E1C4B3AC4BDBEC7A330E30DD2F231F01407D81EA63B272E80F0E18FEDC40EC28AF5B803EC33173B31800C1EACCAF02FC09117AD995C013C63BA0AAA0307343CE6192EB02C5C7E624F05F34FDD03B3B87D9A25684E5EC +6F8524DA +4D0772BD5BDBAC65F9079ACDB172 +BAB4BC14C921E69F +62DE5433 +EE402057E8C395C50C3D4A3995017B1929B4B456A988A5713A2310C62B4786F48F46 +A68FC8928FD068D9B1C18A88FABF966FCC67141091B5B274DD9F31347A5B988182EEBB7DD065 +FFC69DA9D3B5AFBC01E0EBC94461886F7A19A1511E2C06AEF91ED5 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +%Defining font PSOsymclas +%!FontType1-1.0: PSOsymclas +10 dict begin +/FontName /PSOsymclas def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001000 0 0 0.001000 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 1 /C0069 put +dup 2 /C0083 put +readonly def +/FontBBox [50 45 775 713] readonly def +currentdict end +currentfile eexec +D9D66F633B846A989B9974B0179FC6CC445BC7C8A959A39A32E9DCE7FAEF17EE3BEC9F +50E1A6FCA651FC4B3769A0A91041557502E25A5D6180FE25A3D11BF079E1DF66E54EE9B7C229AF891739707A2A0EC140306B5E43E52B79BFB89E459E50 +6EC6F610A70775A31C460976C4F79449D86E57ACE491E5C6BF20CC4307B1DAF7630252 +E9AF8CFB69B50EDAE9D36A6104AFEF8832F920FD2346B2C7104CD11E3BEE999CFA9F5A +49DB3173EE48D1C82994237F360407B022E0B4 +502E94EA8B493651EF2D03F0B513D655047568325B512AE6 +6AC6F53F3848CF70DE25481CC65D8B1A5793AA +3C4282D111112BEE28AFCA7A3808D4444C4669CA +84EAAAF989219F51AB3476A1B0B5F2246BC306E6 +625C6679C417ED2A8E9BD010DE37D40265074C2684275DD89A8790EAD18EFC77D3FFAE84DA5D +312074C4D542DD5BEC70968F75DC +250C3954E8DFB8F4857BFEF092EBA49D248955A858C5A5F55F7B987EA06EC8428D939084C88F5B157D80AB2D706A7EB936C3429173588D2ABA6A27DC94C0B484F316663555797004CBFA79E7B8545C810BF9CA92F61ABD9E202ED9E95943DF7A5ABBF3C20BDE3B6EEC9C0B95A4C9C1D38AA7C6786ADBBB79EE183BDDF194 +1953 +6449DBB7AE47E9FC6F3ABF1DCD7A1E274E87DAE9 +A22737FA +6404B215A27BFAF6D0B50E94D2 +07123A5BB380C86DB5033EE743181BBFCC0356571F7297A207C23F1E588257FDEF5DF229 +CABF3B3C +9E0988C63B358ACA4B4FEB033DFB +E2E387A06A23CACA +8E104B90 +DFDBD41F063E8A8DFA0ABA4DD7443015526AE5255315597779E04D85849305EA4F31 +5CDAD06E5841E1B8074760C99702B8CF443D752174D996C94E690797A9587CF5017DEB11E5FE +02576E9E08B39688BBE99A186AA8FC7E222F5E52B29A7FDF379EF5 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +/DPIx 1270 def /DPIy 1270 def +72 DPIx div 72 DPIy div neg scale +0 -13970 translate +1.00 1.00 scale +/wst:dutch12 12.00 /PSOwstdutch newFont def +/sym:clas12 12.00 /PSOsymclas newFont def +/wst:dutch12b 12.00 /PSOwstdutchb newFont def +/wst:dutch12i 12.00 /PSOwstdutchi newFont def +/wst:dutch14b 14.00 /PSOwstdutchb newFont def +/wst:dutch10 10.00 /PSOwstdutch newFont def +/wst:dutch14 14.00 /PSOwstdutch newFont def +%%IncludeResource: font Helvetica +/wst:helvps10 10.00 /Helvetica /wst:helvps ILEncoding 0 declareNFont def +/sym:clas10 10.00 /PSOsymclas newFont def +%%EndPageSetup +GS +0 13978 10801 13978 10801 0 0 0 clp +wst:dutch14 SF +0.00 0.00 0.00 1.00 setcmykcolor +<1524332f2431250a010b010c242d22272c20312a01252e3101142420323431282d2601152433362e312a0116> 2207 558 0 7384 -1 s +<2431252e312c202d2224> 7375 558 0 8593 -1 s +wst:dutch10 SF +<0908> 9346 13300 0 9522 -1 s +wst:helvps10 SF +<4e6574706572663a> 1322 13280 0 1949 -1 s +<205265766973696f6e20322e313b20436f7079726967687420> 1949 13280 4 3868 32 s +sym:clas10 SF +<01> 3868 13280 0 4019 -1 s +wst:helvps10 SF +<2031393933b131393935204865776c657474b15061636b61726420436f6d70616e79> 4019 13280 3 7133 32 s +wst:dutch14b SF +<111816251c2120> 1271 1458 0 2055 -1 s +<000707040012> 2055 1458 2 2645 0 s +<232126151e18241b2121251c201a> 2621 1458 0 4217 -1 s +wst:dutch12 SF +<1524332f243125> 1271 1984 0 1980 -1 s +<0028320020003120332724310032282c2f2b2400332e2e2b0400322e00283332002431312e3100222e2d232833282e2d320036282b2b> 1980 1984 10 6310 0 s +<0021240031242b20332835242b380032282c2f2b2400202d230025243600282d002d342c> 6310 1984 7 9461 0 s +<3a> 9461 1984 0 9531 -1 s +<21243106> 1271 2229 0 1623 -1 s +<0000192728320032242233282e2d0036282b2b00222e35243100322e2c24002e2500332724002c2e312400222e2c2c2e2d002431312e31002c2432322026243200202d2300322833342033282e2d3200382e34002c28262733> 1623 2229 16 9531 0 s +<322424> 1271 2474 0 1562 -1 s +<00202d23002e25252431320020233528222400203200332e0036272033002c282627330021240036312e2d2600202d23> 1562 2474 10 5823 0 s +<00272e3600332e00222e3131242233002833060000192724002431312e31002c2432322026243200232832> 5823 2474 9 9461 0 s +<3a> 9461 2474 0 9531 -1 s +<2f2b20382423> 1271 2719 0 1866 -1 s +<002e2d002d2e2d051116051a1d0032383233242c32002c28262733002d2e33002124003327240032202c2406> 1866 2719 8 6396 0 s +wst:dutch12b SF +<18242514151e1c241b131621202523211e0b001621202523211e002421161d182500162120201816250019141c1e18170b000d2120201816251c21200023181926241817> 1271 3139 6 7431 0 s +wst:dutch12 SF +<1c27242d0033272832002c243232202624002832002328322f2b20382423040028330022202d002c24202d002e2d24002e250033272400252e2b2b2e36282d260a> 1271 3513 11 7170 0 s +sym:clas12 SF +<02> 1271 3831 0 1359 -1 s +wst:dutch12 SF +<1524332f243125> 1589 3831 0 2298 -1 s +<00272032002d2e33002124242d00282d3233202b2b2423002e2d003327240031242c2e33240032383233242c04002e3100382e3400252e31262e3300332e0031342d00332724002d2433322431352431> 2298 3831 15 9213 0 s +<2f312e2631202c> 1589 4076 0 2365 -1 s +<0024372f2b282228332b3806000f283327243100282d3233202b2b002d24332f24312500252e2b2b2e36282d260033272400282d323331342233282e2d320020330033272400212426282d2d282d26002e25> 2365 4076 11 9213 0 s +<33272832> 1589 4321 0 1913 -1 s +<00232e22342c242d3304002e310031342d002d24333224313524310024372f2b282228332b38002e2d003327240031242c2e33240032383233242c06> 1913 4321 9 7331 0 s +sym:clas12 SF +<02> 1271 4640 0 1359 -1 s +wst:dutch12 SF +<1e> 1589 4640 0 1751 -1 s +<2e34> 1725 4640 0 1957 -1 s +<002c20232400200033382f2e00282d003327240025282b243200> 1957 4640 7 4137 0 s +wst:dutch12i SF +<02050c03020b050a0d0703050b> 4137 4640 0 5150 -1 s +wst:dutch12 SF +<04002e3100> 5150 4640 2 5499 0 s +wst:dutch12i SF +<02050c03020708050c040103090806> 5499 4640 0 6728 -1 s +wst:dutch12 SF +<06000d2724222a00382e343100242d333128243200202620282d3233> 6728 4640 4 9213 0 s +<33272e3224> 1589 4885 0 2076 -1 s +<00282d0033272400282d3233202b2b2033282e2d0032242233282e2d06001225002227202d26243200203124002d242423242304> 2076 4885 8 6541 0 s +<002c202a24003327242c00202d23003327242d003124222e2d2528> 6541 4885 5 9143 0 s +<3a> 9143 4885 0 9213 -1 s +<2634312400282d2433230020320023243222312821242300282d0033272400282d3233202b2b2033282e2d0032242233282e2d06> 1589 5130 7 6047 0 s +sym:clas12 SF +<02> 1271 5448 0 1359 -1 s +wst:dutch12 SF +<1e> 1589 5448 0 1751 -1 s +<2e34> 1725 5448 0 1957 -1 s +<00252e31262e3300332e003124222e2d25282634312400282d243323060017> 1957 5448 5 4751 0 s +<24222e2d25282634312400282d24332300252e2b2b2e36282d260033272400282d323331342233282e2d3200282d00332724> 4743 5448 6 9213 0 s +<282d3233202b2b2033282e2d> 1589 5693 0 2598 -1 s +<0032242233282e2d06> 2598 5693 1 3342 0 s +sym:clas12 SF +<02> 1271 6012 0 1359 -1 s +wst:dutch12 SF +<1e> 1589 6012 0 1751 -1 s +<2e34> 1725 6012 0 1957 -1 s +<00322f242228252824230020> 1957 6012 2 2962 0 s +<002f2e3133002d342c21243100362833270033272400052f002e2f33282e2d00332e002d24332f2431250033272033002832002d2e33003327240032202c2400203200332724> 2962 6012 15 9213 0 s +<2f2e3133> 1589 6256 0 1971 -1 s +<002d342c212431002124282d26003432242300213800332724002d2433322431352431002f312e2631202c002e2d003327240031242c2e33240032383233242c06> 1971 6256 11 8115 0 s +sym:clas12 SF +<02> 1271 6575 0 1359 -1 s +wst:dutch12 SF +<122d243323> 1589 6575 0 2076 -1 s +<003224223431283338002e2d003327240031242c2e33240032383233242c002832002d2e3300222e2d2528263431242300332e> 2076 6575 9 6492 0 s +<00202b2b2e3600222e2d2d242233282e2d320025312e2c00332724002b2e> 6492 6575 5 9143 0 s +<3a> 9143 6575 0 9213 -1 s +<22202b> 1589 6820 0 1845 -1 s +<0032383233242c060010> 1845 6820 2 2740 0 s +<2e2b2b2e360033272400282d323331342233282e2d3200282d00332724002c202d2f20262400252e3100282d2433230632242206> 2732 6820 7 7342 0 s +sym:clas12 SF +<02> 1271 7139 0 1359 -1 s +wst:dutch12 SF +<1524332f243125> 1589 7139 0 2298 -1 s +<00272033243200382e34060012330027203200202b3620383200272033242300382e3406000d2e2d32342b330033272400292e21002b283233282d263200282d002c28322206292e2132062e252524312423> 2298 7139 13 9213 0 s +<202d23> 1589 7383 0 1926 -1 s +<00323320313300382e3431002b282524002e352431000a03> 1926 7383 5 3832 0 s +wst:dutch12b SF +<26172213241820170b001714251400241820170018232321230b000f182424141a1800252121001e21201a00> 1271 7803 7 5403 0 s +<03212303> 1271 8048 0 1822 -1 s +<24182017132617221323230b001714251400241820170018232321230b000f182424141a1800252121001e21201a> 1271 8293 6 5638 0 s +wst:dutch12 SF +<1927243224002c2432322026243200282d2328222033240033272400252e2b2b2e36282d260a> 1271 8667 4 4770 0 s +sym:clas12 SF +<02> 1271 8986 0 1359 -1 s +wst:dutch12 SF +<1e> 1589 8986 0 1751 -1 s +<2e34> 1725 8986 0 1957 -1 s +<00272035240031243034243233242300200032242d2300322839240002052c002e2f33282e2d03002e31> 1957 8986 8 5824 0 s +<0031243034243233003228392400020531002e2f33282e2d030033272033002832002b2031262431> 5824 8986 7 9213 0 s +<3327202d> 1589 9231 0 1995 -1 s +<00332724002b2e22202b00322e222a24330032242d23> 1995 9231 4 3863 0 s +<00213425252431003228392400020532002e2f33282e2d0300362833270020001a0e161f1819170f0b14002e31001a0e161f1717> 3863 9231 9 9213 0 s +<33243233> 1589 9475 0 1913 -1 s +<00020533002e2f33282e2d0306001e> 1913 9475 3 3283 0 s +<2e340032272e342b230024283327243100282d223124203224003327240032283924002e250033272400322e222a24330021342525243104002e31> 3257 9475 10 8371 0 s +<002324223124203224> 8371 9475 1 9213 0 s +<332724> 1589 9720 0 1879 -1 s +<0032283924002e25003327240032242d23073124303424323306> 1879 9720 4 4104 0 s +wst:dutch12b SF +<222625131621202523211e0b0014161d2021281e18171a181f18202500182323212300281420251817000a001a21250009> 1271 10140 6 5941 0 s +<201825221823190b00171e13212218200b001621261e17002021250024182025001621202523211e001f182424141a1802001823232021000c0006> 1271 10385 9 6667 0 s +<201825221823190b002418201713171e221c1316211324252318141f0b00171e221c1324252318141f00171425140017182416231c222521230b000e232321230006> 1271 10630 6 7419 0 s +wst:dutch12 SF +<192728320032333124202c002e25002c2432322026243200282d232822203324320033272400252e2b2b2e36282d260a> 1271 11004 6 5606 0 s +sym:clas12 SF +<02> 1271 11323 0 1359 -1 s +wst:dutch12 SF +<1e> 1589 11323 0 1751 -1 s +<2e34> 1725 11323 0 1957 -1 s +<0027203524> 1957 11323 1 2426 0 s +<00322f242228252824230020000e131612001616> 2426 11323 4 4291 0 s +<0b0033272033002832002d2e330035202b282306001b> 4264 11323 5 6106 0 s +<24312825380033272400222e3131242233001616> 6083 11323 3 7816 0 s +<0b00202d230033313800202620282d06> 7789 11323 3 9213 0 s +<1b> 1589 11567 0 1751 -1 s +<2031282033282e2d32> 1724 11567 0 2513 -1 s +<002e2d00332728320032333124202c002e25002c243232202624320022202d002124003224242d00252e310024202227002e2500332724000e13161200332432333206> 2513 11567 14 8522 0 s +wst:dutch12b SF +<201825221823190b00171e13212218200b00212218200021190005171827051921210019141c1e181702001823232021000c0008> 1271 11987 8 5858 0 s +<201825221823190b002418201713171e221c1316211324252318141f0b00171e221c0024252318141f00171425140017182416231c222521230b001021002426161b00191c1e1800212300171c23181625212329> 1271 12232 10 8893 0 s +wst:dutch12 SF +<192728320032333124202c002e25002c2432322026243200282d232822203324320033272400252e2b2b2e36282d260a> 1271 12606 6 5606 0 s +GR +eop +%%PageTrailer +%%PageResources: font Helvetica +%%PageProcessColors: Black +%%PageCustomColors: +%%Page: (31) 31 +%%PageResources: (atend) +%%PageProcessColors: (atend) +%%PageCustomColors: (atend) +%%BeginPageSetup +bop +%Defining font PSOwstdutch +%!FontType1-1.0: PSOwstdutch +10 dict begin +/FontName /PSOwstdutch def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001000 0 0 0.001000 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 1 /C0032 put +dup 2 /C0042 put +dup 3 /C0044 put +dup 4 /C0045 put +dup 5 /C0046 put +dup 6 /C0047 put +dup 7 /C0049 put +dup 8 /C0051 put +dup 9 /C0058 put +dup 10 /C0064 put +dup 11 /C0065 put +dup 12 /C0066 put +dup 13 /C0068 put +dup 14 /C0069 put +dup 15 /C0070 put +dup 16 /C0072 put +dup 17 /C0073 put +dup 18 /C0076 put +dup 19 /C0077 put +dup 20 /C0078 put +dup 21 /C0079 put +dup 22 /C0080 put +dup 23 /C0082 put +dup 24 /C0083 put +dup 25 /C0084 put +dup 26 /C0086 put +dup 27 /C0089 put +dup 28 /C0097 put +dup 29 /C0098 put +dup 30 /C0099 put +dup 31 /C0100 put +dup 32 /C0101 put +dup 33 /C0102 put +dup 34 /C0103 put +dup 35 /C0104 put +dup 36 /C0105 put +dup 37 /C0107 put +dup 38 /C0108 put +dup 39 /C0109 put +dup 40 /C0110 put +dup 41 /C0111 put +dup 42 /C0112 put +dup 43 /C0113 put +dup 44 /C0114 put +dup 45 /C0115 put +dup 46 /C0116 put +dup 47 /C0117 put +dup 48 /C0118 put +dup 49 /C0119 put +dup 50 /C0120 put +dup 51 /C0121 put +dup 52 /C0262 put +readonly def +/FontBBox [-25 -238 920 722] readonly def +currentdict end +currentfile eexec +D9D66F633B846A989B9974B0179FC6CC445BC7C8A959A39A32E9DCE7FAEF17EE3BEC9F +50E1A6FCA651FC4B3769A0A91041557502E25A5D6180FE25A3D11BF079E1DF66E54EE9B7C229AF891739707A2A0EC140306B5E43E52B79BFB89E459E50 +6EC6F610A70775A31C460976C4F79449D86E57ACE491E5C6BF20CC4307B1DAF7630252 +E9AF8CFB69B50EDAE9D36A6104AFEF8832F920FD2346B2C7104CD11E3BEE999CFA9F5A +49DB3173EE48D1C82994237F360407B022E0B4 +502E94EA8B493651EF2D03F0B513D655047568325B512AE6 +6AC6F53F3848CF70DE25481CC65D8B1A5793AA +3C4282D111112BEE28AFCA7A3808D4444C4669CA +84EAAAF989219F51AB3476A1B0B5F2246BC306E6 +625C6679C417ED2A8E9BD010DE37D40265074C2684219457CAB33537EC3AD02717A7C0E941C986 +445FDB89179B7E2A12D12215 +8C723C692CE6DABF40 +61682CB1 +0700504798DCD182FDEBF572CA73 +E4E558E25EC5B58C71755956EC7A500F809092054AFDD7D54F8EF8CD632C0987AA4D5FD4E5C990A59805BE6380B76C4C290E099CC31DED816A5D60FC183CE5B00E5F1F0D6D52562B5B3BD872E3F84B47A020A18154A4D6B6EC093DF08BBCB49043023E94E329C68F04336D896BCDE0C499536D49B113431E7CBB3B7A758E +7B94 +5E063D9C41C6EE47DD7CD681D42EBC4923B3F38F1723A07C1AEA294AAFE6B0B4DEE01BD84492E0D45A7ED812340925B65B318ACA629985DC26CA7B761851DA +BA19CB76 +5C5C5277A077029380FF494BC2 +F3EE7C2D463B3131A93C4DB73492B678DE91035FDC69FC3A2BEFDC63768B078855853FC4455A3D453B53E2C72BBFBA124E5304644FAC7844EC +82637E52 +4C3EB5B5066626F552A42E429F +A8975232D12AF11CCE100E97C8AFBCF61A949A20A08258 +4CCCC6BF +3FF3823B9DC5A49C88B9EABED1 +4DE2329C0B4EC39F99D55732F23929B103260C8FA293A1584E6F4ED7C87F69 +A131ECDF +7C12562463519A63BF3C38E06E +376282C9C0AAC590E1F94D88BB4FB9E4ECEB04A19A07527FE621E340 +DDE69D97 +A998F7ACF9D18B94E46789B12E +DD6E57CB065726CB66F348EB5A1418F77F7B19ED4185234441BFD115ADE67EEF25B12B45F936E539CD39B655646648BEA8E3ED071253038CACDB516C8F347D +F77F19D1 +751C7473156C4F2C27A15F4E0503 +D39165A5932CF172F49BE34ACB1282E0020D7AA4EBC894C5338D733ADC5B360108FFE80FD74F488F91FA8458E634BC797E056BD2B28DF86984E1150F5E48FE3DD5A10E66A3AE6C66D7B64981E1B32A293DFB0E250186EC11F74CF090FF595B225AF20EE805366546434FAFFB6F1689 +168B5675 +9E02D8FDD999DEDFDA2F68A75F +F2AA16F22DE2FDF91202AAE783FE03F19949B2D6D35FE7FA43583F72683180DAB94C8770377F387FD3CBE63DEBA870E051B520670BA3 +EC1174B3 +31C77B8726B2BAF61841FEB04431 +DCD86F32063BDF408079CBC3A4C72F52C91FAFC9898051EBBA566FCD3CFEDB65DDDE9F4A38A5E1F866F4ADC9BF373EE51AFBB2FAFFE7D752157A543207C178F9021F0A76138FDC771D571F146FD4FD05D75BF6BD6BEF3F652E18D48B872DBF8A4572644A402C2CDD740A269E3882CDD2B4EA4A48DFC5026A679102C0ED7A +6C5C +2B7553AF59D6743E31C0B5521E0591378479FB99FDCC5C47CDB25DD9487B15572CA2A9E52C860C46A335E0FC86AFB79469B416F2D3BCD2E43A3B3FC223F5FFD8E3D9CAFF66E456A22E7984664E6F82FB78008429389889E593A913648B86F5B0625D747A2B307E3E34EB8B7D7F2EAD23DF82D2A6B58B2256519518779243 +C7 +FF770A09 +AFF65ADFBA469D7FD5BF1502696A +2FC6C88A1B8ABDA5A7701CCFB7B5107965F12FC14E3E3E0C34D84AD3F51078423476537A3F142B26E4E9EDD624539BDC0FCBBCA231AF18A75E6E7411790EA83D889745556FB88647FC6F711C74B5C84E0AF3DFD348C0C526A01C92A684BC747FF400AF81688B53E6F4CF4E6D16327205B76664 +C43FB724 +AED568A3590D1F0709C3F265C212 +EFD14EC12B02853D949B4E502EB2377E99FEB3640F5EA7B4B92063C457063E10642F0E646375C4731F4A13DE0DC3278E94E5EDD3469C4C3B7E4909265FCE9A9DBEC9904B00618940F60D16A2B604840377C6F19C2438C4DB35537EA2F2764413D596EBF504ADACA097D2ADFAEAD1B8EED4C8D8A6339B370FA90C810E6DB5 +813A +08 +D29BD3C4 +53B6C3816C834721544F9424F3 +AF64A6F001606983883C58BFDB0E7CAA68E3B757324B1CC53E094598DCE08540BC4A8375AF23A3F0EFA96CC48FA0FEAE04F4E0E8C7B33BA8FEC2532827E1BAD192E83B40DBD476321E98011243F586D68782D2C2B57B78F2677AB304134E46976DB57D +AC3E5190 +4638F34088C207527029119754DA +EB4C88C65CB18758FFD195C85365A411CA81CB7EECE9C9DC349C9D399CF314E91A4951B2AC912A3C8A2D644A68FCC51EE83FFF0FF44968C3A0CB11529AD38D187106669D21E520B91C5AE5BAD76E3021EC8E7243DD344C25A648360ED9013932BEB425007CE5A74FAB5336F0F783290DBF8F5F251FA90A2FD15FF4BDBBC8 +2650DF1C +F66D66BB248DD7A432685D87B84E +CF2551787AEB609DEDA033C1A593F4AD77EEFFBFCF125AE6446986CEA32D120C013EF63EE745FD3D3465660572D8DC24B5FA31C874615FF38C6903DF6FA24FF1C670EA3D4FB446682103E81C7D25440E59C1BBF396A4F92C70B0A65B71FC6B9784D207C06CDEDB880C +769102C0 +680FB0ADF907027B7AA8A1BC869B +CFDBDCFA242D84B502C578C50B1546E000346F8C1A15B04D96893EE1132B7B1B123F4BA61A6438A6AA76D42EEB0DA860EEF0892B844031BF499AA39E9B640F329BD569E41F66536F43382035F9F49C28A3223CBC2C843F20CC964194A57068E4C6AF66DFE68F2F87C4B518A5A12BC330D94981766AC4D75706651620ED2A +9DE5 +AC5C74B032E7B0AEE48332 +2413E107 +D7BB3B229B0A88FFD18EA7AE9E +F32168ABE7DAE9AED8265CCCFA6EA26A54DCADDEA45DDEACC0FB625268BEFE5BEE840A912403B26E3746D551F2A01D859068D98EFCBE244072B18E +2AA62AC7 +1883FF3DD23657477DB6CA2FF8 +E541262848AE36751D3FBD4B38D2FDC3BAAB0451B20CD3FD826162E59BBC6E59590DEE0BEC52B332B988F03C83EDB60D1022D53ECCA5F92A68747234FD89601743D31D2FA834D5 +D8359D83 +077097D6508C7364369C8A2FCCD9 +1BFCEA5E6356EFA4BF1A7F837C2E7DFD15F1724633D1939511A5DD738FD805C4DB5C9078C70BB603F43A31FC4E7377A923543A7C225E738E37EF568DD545CB15DAF49BD53805ADF1D43DF353104EE9B05DB05B5F15A976B26536F1482D863B56BDE9FB608AAB54D3C61593EC55DE43 +653F51EC +DEC34B2E696A749832014DC7DC +EB4DDDFF209013558A4778BBF02820F1E168232D93919FCD8E7BBD9561078D3C21BC49D55CCF6E66197E87F534654F45ED4FC9E6403DAFA4BC1D51441A53C3712D9DD38D2611C700B8199ADB13E0F5FDE0FC6C11B98ED0BDF5C71EFD +A4ACE474 +37C26FA63C48BA828B36DBC927 +B1ADC31A8B6E8FAE35665C959849FFC0C11CEE800E813B3D9DA0C0BB3F9E045801C62B6C2398B9A7DB7632E7E1FBAA806B7B7ADC1FB11FC517DF4CD2C629F348E748892D4128AC75750784FFBB12E592E9AA1E +C2D6747D +0A1E09F456A3E60363DEDDB86B8F +6978F44E0253152F4284CD7AC6A0F89BA4ABF7AE1E642DED5DDFE624A5721AAAB0D5644474B4DF5690747109E862B1DBAA0C9F2D29D0EC3B21AB51C17BD0F07482A181BA35D469F3425915E9CB0ECE3E6F681A0FBF750E9565798757197472245BAF478BAB0E62F47871 +55CA68FA +CCCAF7E6C4280BE7D937AF76A51E +49D3987D412D604C77FEC5EAE6ACCC97E030BF61D7A56EC6E732866529A421646532415DCAFFBC5C9FFBB853B68CA89406DA613EA8D43738F100C9B5C6C4CB94DE21F36BE32A958188B1B6512178799537C9E5754129C7309243AEA6797E78D8E581153AC19E94F9E6F67EF5601DD77D182BDF87C0E3FF8CB66AD99F9C56 +185BAF9B +BCE0546508C49F98E0085081A47B +223BF13CB6BBEE47D2B8A79C975E710E55BAEF5EF402EB9476CB6303A2AE283DA5E7BE53C52C4799CA5D2B6FF08109826188FDCA5875D452EAE48805EF735D3D58E1B3948788D3A6C5135144376765B3DD1AB3E41DEC903164E3FD4BF446D9C365030C9921A0E80B9B8A7B25EC2B917EAD88EE59A818A33523CFEB9A72F7 +3EF4 +983443 +1BA9AF3A +560E6D6092FF13BCF5273293AB +153B6EB6D55E325E53592394D9E6CCAA2C9197865C589527B0B85709067250135EEC2E68CD220156B4129162F9D7B4D9C286F66682E5671B21D5CA70DB46E45C5185C4022D9DEF7F9B5FFE73C04B412FA7 +3DF080B1 +62C76C72F8E56AF35AB0333D16 +019A6A97B8FD962FFA7E3753714C9D04B52D36B04A60BF24AF42980BC7A3E04383F0E04D12D98DD0AD3B454B7DD7C9A8FD29AA28BEF6AFAF9AA901101D86A242F31EBF9B49BECCD08497C20D41AA3A0F2A89888679E7AA6B36 +3563F20C +8BE781743274F0F4DA12C6F5DEEE +483B14BAD1D51E8DECE6E21D3FC40565ABDF0795846345BED23D918900B8F55A93F2A026D12DC3494580C5422D5012ABC41BB450D1B21EBE69C55F364582D998643CD68810937E96F0F985D0ACC8A37CCA7B2FC74F83FC8F7A059F876BAA4EA304B52262EC0314A23FD086D47818829C2DCA5F +F1245968 +7C61AB1687F0D25B1F6831138546 +BB8DA5830B274117E1FCA896998C650D0A08BDFB3A912AE76497D7BC517CEEDC3AED356E4C17E5A8E789C1A8123308C1DEBCF15336D842FCD549FD11A416EDA2A9A401763F0C7499D00EEA0204A11A2FDE255F4C6947AD6C928F1D91F21DCDE8CD5991A877969D4FD73D608C9B95AE3F148BD382CDA4CF3E46BF08804E30 +2B88 +B481CE +92CFFF1F +821F71953232AFE9E1F573EEBB +83E6F9DEB91BB53C970D7AA11B21D76F9B2996C157F82AAD399F4C6586D662F74AAB26F7CD1CC0E799FE862C8683FD84D61DBD5746CEEE0328AF96175F5289692DBCE16A62E7A1811D696C8822D991156A1470DDED3F8F17 +E0856F68 +9FFEC370553E572608F5C38EE0 +EF4E5A8984E6A01C023FD516BD6ECD36A7613334C7EC3BE8FFF1182BF582EA0ED803F60406F71275F60109A2DD4B9DCF5F72DDBCBF6763B8C38AEF5A41E06E903D9F62E3CCCC93111BA3AECE1C38D101A762 +7CE3EA6D +716F1FE31DE99C35F9DAF84EF1B0 +37F6E8831D98A9BAB245FE77B6DA63306414376D060648FD349BFB6683E2BA6FE4D74E646480D4D474F529E5E8D7874537CF764086F506A36FE57E7C57B40D19D98A16E7ACE40537208D8B614703670AB304B48333EC92AD0C25B225B0BB06D0D7D8EA005A537EC96C72EBEC95DB +34986A31 +A28F4980524B3AB1942E347B5A +6E2F5210D03692D3C309460943F0BF966B4155D46C4C4EB7A263243A2E6B3226ACD3A896735312C136FB0B4F555E5E0B408D0A5E45C5119116547A6EA23FD9D78BF23B036304606F81F50500F589A7196C3295D224F2F2CC24 +D933927F +490F0702607AD36792A9938EF2 +36F4147CB006F58158871F44AED4129DC41E4BDD3218B881A1EF0BB2AD2B80C0F388C2F6A6D24198BA5B31DA7082B26CD4DA2EA646F1D4235537C637FCEF7CEF81BC8679AFF6EC5D4FC7744C69EE503EE50161F6C973F4F45016085C +844951C0 +C65F23137A4954CB34527E081797 +48C47D32A75AFA5D82351AA1EB5F82CFBE5CAFC4DCB5C53C1C8847FEC76B18D578632192B366F350694968908A6FB362870F31E61EBA03BC710513578EFC9BE8BD680C9E7B3B8B908DCBA568DE710D5C1798E93CBBD3C6D16A842AFD9B6F1D83DA5AB7706C1626B9BEECAA7C3B1EB4ED08A2E52184CC909A940E6B0AF65D +DECF +D4F224539C4B84FD54479280920A48707F1680411C3860C894324C36F90E40C5EACC50400E39D31B6ECB523F6AEE2C +DA1A0FD4 +7C08095BA5797D068E2A83129C91 +2ACDB47A47F28DA9563EE540646812794D0756E8C082CE9EB32C150341855DEFFD5F8D56560206A271155BFF5077282AC56ECA669BD491C53D8C859E4EC2BFB9C301E93BB9A680C9F72063B85CBB5D8BD85114157FC429E9E8F386E3BE933287241A917150C6332145E31DD238 +433ABE82 +5A8B84A9E487E73D04572D861C +7A2D64044434698373861371701D2300CC8342EB72E5FE58E2DD3D822EA8328486FBAB6D74A7511AD897A183FFCDFBF5BFD970B807131E034745373D952F21D0E0A0E743D8E05371D1F161F76F13A055 +A1E552B5 +32F7FB974BB43EC3FEAB5C2468B3 +515B4E5CF8FB2A5E1EDD51A32DED8C9738ABF02774AF069FBAFFE46E4B3A6748AD60482FDD6D7FF269F4A14C072DEF84650D896B833DC80C8DFF54ECB915D99C3810A5A50F9AD1D52DCB490ADB806D18EEB01BEEC6F8AC83E7BF5B9EB8AD9BB9F2F58EE48FDFCC6A4167FBC6CB626BE3F4C96A2DAAB14294036C6AD8D53D +52FA +DACB1D14FE99C7B71968AC812C4F8CAAE405B6D6FCECB796FFB424770C47B3DC075526 +1F49B17A +691982797649056CA835354C7F +42AD18795745B1A5E712362AEE9FF88A8839B1DED7966446F57B6B0FB1B6B0F3DE1646F2AE73D89C3BA055EDD85E446B485BCD2685EA +E80DFCB0 +FBB0C691AC50AA2CFA4E3D79C383 +ABB001999E04C3E978A3D72A380AB2F6F196383969169C65F1FE06C98F4333A65482436CC7E38C62C0B9493F174C53739586A9D2D619ED7A569BAA78203485F2F6D008D2F17CA2B7B149D2A26ECACB05BFD606ECAA7AA831CDC14E2DE480157211550AD5E0E9D71FAC3C0A7F81EEAAC50A9B3F21EA273F0FBA4796824793 +7852 +85F52A91876E5A35271C7081C740F55F5C29B2F3ABA1E004779C27FC0805A7 +CF983E10 +844D83A9E4306612E8CCA83904F0 +0C6F8129482E253B1C477BE2A07C486348BDEE80C71BAF25B1D6A023E699233D7498F15ADF5F949F6DD4C751F0C3A3668D7775D3B73342A981E197093C473FF0B32E7093D7EB0D215F269340EDFB42C0EE22D499F57F63D8DAA34C85A8CF14C75C016D903413E1865BC74977 +03F43DA0 +563B650AFCD5433B1E9364F00E +4602A8702B430A4E4B2CAB7996B5653C9CD37416053C110658FE6FDB71FEB3579BAF289E692A12835FD00D335A60193712D36382208E4893FAEA8DC295D71C4B50A94A4361FD +1A7787E5 +F83D4FEA09AC13150639D7522163 +B2871DDBE8011A200EDCEC7F6FD310F19163F7FFF506A3C9E3CE832C4DA60C64D2E2457B5D0DF417E0F816BB213D1F3753CFA21D14BE54BB321B56718F6161455EA7CC2585BB08DF9760E029FABC6FD21A2F871DDAD00CE4FF9BF8F24F88788C21AD90C52D9EA0C3D10CDDDE958EE7B9078A5A9833C2C9 +878443FA +526B48395674F8BF69783F1F1427 +F5826F5DB9080FC622C028B0D3D2AC46AB6282B377B7F264C86B43C2B4D75595A27C30A0BC9BFEC521FE5E5B6A6696B8691150BE14BACCE34EFD63FDBA1F2B53FF2FEB6BA61BA1712CB4291B871433C2C2041CF7F9D1F00C1841BDBF6AD2123141F9A0CCD5EF7C1FE014 +6733E455 +8B5BDE6DEE0B82BE4D3D785A31 +C1CF5B247BDAEB615860126AC1332440EDE22E6FB89C3E631BDAEB0FCDEDD9C131AED6E784FF673C75E74FEBC73B6009697B9FB996AE1ADB008C34A78F7CB28D6F935DE4AF990621E033E48E4FB309565AFC216CF6E593 +0AC14F1F +5989CFB3E851D80D210832F6D281 +F0F9C45F3D7DBB2D73D1F4A93C54E244EE367E6D4C07E56F5B58692626511F2B861225DD88D2EC69F483A7A014074FEA457F84F59A7D9EA28F16993991BAE3A3AA917F2FF66A101A489CA8CEF4B9B9D1212B62DDA448DABD85E71ACBB5EABBB8C2106F69F8F35F10E7B811902AF52FA4A7FD1B8CEC65CD46B4E195A7 +BA7BAE21 +AED414B8805960CAF918E225C5 +ECBBBFCBD608F6B6DA34A6104F20E464A142FD8FC021D3A880A977BC8D2FA0680F8FE9A1001DD83BEC15FC804D43F892B612AB9D432782AB4A7DA833D0841D17FC496D3766 +07544C4D +6DED34ACE603688F008961F05D +5B83CE0E20BBD124B074EE741540536C2681D6A0223263EC1278F78319D5E0DDD5D8B609D4B8EEBF035F7906AB3C8D6944A594F704711A0DED9B8B77D11476AFE8CCE25EB75CCB93488C672090D888A1F955B60A86E6107ABA343EDC90623C750336 +A75B442A +CD8DB8DD4057C95A948A2FCCD9 +1BFCEA5EBA6FBFBCF41382D120A3F3138933C8BE50EBA2A13A68D611A8253B0A2ACA597452B4D2A0202FA108664C1D22E18EFC3D1D9EF65940D45FB60CEC1EE384B6C3C0E9D85AB0B0B36BA38301C81BFD3F674D930266B5B4 +C584312E +E4A5A8F8AB5DCAE3F75FA8B1E1C2 +D6AB9227067C8FCD1FC84B5514AADB1D848E89513961228C81104D97ADC1382FA9A5A2C6B797632FE986F2653ADA6F07E04461F0AC9E02AE6319EB316F84644092966B860A06C09A598D010AD3A3ABD6C4F32B4FDED7D59AF196B80A424700CE2D476E5A6E4685CD77EF53F85A39B25599490776DE221731B6B67C2719C4 +0954 +0E2FFEFA9AF87AD3DAFA52720AEA +066557B3 +492B6A86AC3DF5014D8D9161510B +36B230EF4E76D550B6B9294C4FBF47E0FE1528BF365108FDB5808196F9691B5455E7FC290C85F881C842CDEDD06EE07CFBED57BB535DA29A03E05CD929B33CD6663A68BE5058AEFD09D5226903A522D85523ACF9E8802AD0444F4E1DBA65FB0229D99B7908CF22AD18C25C45C7CE74D2CEF2C1EAADB8D505360F94BC72E7 +2E8C +D32936C1AD01DA899D299C9D337C0763ECA70227AD486F64B2 +3B8EE3B8 +C6509956E40CFCAF19CEF3F02E3B +8751E0782F77CF29E82A95016145AB4912A1D56FBFC5E392519E454D2DA0498D6BF1EB65934D54A290E24EF69DD1ACC4E40BE206449C3880D1F6E8941D1B78A2F3E768920C3AEECE3D703E4B589366DDFDFA6378682C111B556025AA39D12A2EDAB54EF1A6A691892D582D5555DA9FDEB4143E529BAE88BA009B566CFB10 +A10A +295765C0 +BC22F100DD9C1D1C159D6424BF +2615C9FCE2BE1A161F35A45162010645C3F369833B5E +0E9CA93D +63CFEE1079E4B52477A11C55B507 +A6B130EED272C7E0 +2D433C5F +0070E8CB34DC1EB8907DA758134918AACE7C687D363EB7E503A824299A0419CDF3D1 +148AC9EA8FAD1779049BDEACD7D0BD7A108A0667FBAA6BE89BBFA2FBADB3E02BB13207271A8D +BE788F7E942AABE130F00D1F851AD4BD5844D70FF50DB9881EC38B +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +%Defining font PSOwstdutchb +%!FontType1-1.0: PSOwstdutchb +10 dict begin +/FontName /PSOwstdutchb def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001000 0 0 0.001000 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 1 /C0032 put +dup 2 /C0046 put +dup 3 /C0058 put +dup 4 /C0064 put +dup 5 /C0095 put +dup 6 /C0097 put +dup 7 /C0099 put +dup 8 /C0100 put +dup 9 /C0101 put +dup 10 /C0102 put +dup 11 /C0104 put +dup 12 /C0105 put +dup 13 /C0106 put +dup 14 /C0109 put +dup 15 /C0110 put +dup 16 /C0111 put +dup 17 /C0112 put +dup 18 /C0114 put +dup 19 /C0115 put +dup 20 /C0116 put +dup 21 /C0117 put +dup 22 /C0118 put +readonly def +/FontBBox [-83 -236 922 712] readonly def +currentdict end +currentfile eexec +D9D66F633B846A989B9974B0179FC6CC445BC7C8A959A39A32E9DCE7FAEF17EE3BEC9F +50E1A6FCA651FC4B3769A0A91041557502E25A5D6180FE25A3D11BF079E1DF66E54EE9B7C229AF891739707A2A0EC140306B5E43E52B79BFB89E459E50 +6EC6F610A70775A31C460976C4F79449D86E57ACE491E5C6BF20CC4307B1DAF7630252 +E9AF8CFB69B50EDAE9D36A6104AFEF8832F920FD2346B2C7104CD11E3BEE999CFA9F5A +49DB3173EE48D1C82994237F360407B022E0B4 +502E94EA8B493651EF2D03F0B513D655047568325B512AE6 +6AC6F53F3848CF70DE25481CC65D8B1A5793AA +3C4282D111112BEE28AFCA7A3808D4444C4669CA +84EAAAF989219F51AB3476A1B0B5F2246BC306E6 +625C6679C417ED2A8E9BD010DE37D40265074C2684269CCEC1A9912691012A4BB5400F24BB2A19 +ECB8F6076FA44F109BE31002 +111487965EB846A9FB +16D27A61 +9A739E73C457D0209278766556 +ACA88EDA1F268FF3C2B8C90A23D0A6383D5A5A061FD3511E1D0E72BD5FAEC1 +1976B18A +1AEF6C96D545724B7458AA398E +37BF984F200CE51C4E17D1386334C937E894B524B7B2EB5F03E89CEFA81176A2F077837B540B69E45D4243CF6CFF2358CBE192751D56 +20014775 +7A66E7B983683984CEE9D9800F98 +038B815C9A0972844BA2BF14DC01AF42E56668F350AB470CEE3589920B086CE2C21F87A3A5653AAA046998735D60DD958900802E2B1F15E5D29E31E8EC0F922D4B820160F90128070D8FD1DCDF8FC3C3F956F600823B93CBB7702A38777678E1EBB183CDC55CE8DF67454184E31A384F0CFC0BBCBB12B165097409DAFFEE +495E +23780330A1C88EE49BD56ACB59D371909210715A1D3418880FFADA0ACB6B149E9F28D7218CF0CD29F3D6F3E5CDD2E96B919FB60E207AB1364B886548B465EDBAED98ABA2B24C4545F7812C86AB0E2A5CF019977127A78406A148305FE7F1091788A178943EDE2FD6604686620C3FCA4D5E105E +B46432BA +A204DD91051C86D8B5CD8A2335 +B62CA1D8B86B43A23BF73C9A8277058CE131C9D46F2C +0CED4A90 +95140DE1A6EFE1F5F02C0861CBE8 +A9827B3F3CBF45A88EA6099BD26D30EF42836C6000263BFDABDC7B25F23AD0B1AB01D02C1E8190BDC2ADF4E3668AED3AB04C3BCBB657A367C3D52D6E0901A2628DBB5126BB8CBF2755ABABC12E849E2FDAA65D975E2F95BAFA2E926CCD40CA06F6A902534B749043D3EF8916B47BDBF24DE12390304FB7F74B079942A5FB +0947 +CF005141 +2CCC1BD0 +DE953ECD8FEB55E075048904BB +D47D276DE4DEC0E0FEB495B24907605779C0DBA461581B72E5CE7E92B4B8249212EC3A636C9919F167EA709CA4A9F7B1131BA8B552CD0310357C75B7080F6F43C09ECAFC12A02764A6B8BD57B99CC21ECC74 +7F0A39CC +1E8F36E8B956F310E7E2BFFCCAF6 +34AE7A1D8207FA9FFAB4A24964CAC96448B4EA201A4795FD69A646D2B4C9599BFA69BFF08D9EC6F8B6D6999ACEB9F2B5CE793B1BA2A71FFB466134A352B46878F114D89F44AF20EB3CAF00BFDCBC0930F411CDEECFFCF330A7E1DD4F82E75C04343FA7D0BAE9B0DF6DCABC0A +424492A1 +29EBBE4B1D55D7194D3AD4F4DA +C719BDB5EEDA76D8E9F039B644B7D419D92668DE372F27079E4E75FE106667E989C321FF93117175EC9486403FF89D23C1956C1EC1B2782129EDAC88FC3CA120EB431FC038FCF5E651FDDC4A2DF858FA882BF09F9E95720042EAA744 +9E420221 +DAA64C681660A50510AF8B554E +270A35179947B29FDB4AA199F22531D9A128D30A7DB4168233C8E93314A29DAE8FACF14356EDF7BFC6B9E6ED909244AB10C4E89581D99A96C2EA35F2337B36E52BB7393CF2C47BBD6D38794E642A8D9974B4CE050491FF876B211F07AB +CC2504DA +71BFD61DA723EEB0F237344E84B6 +03738B27DBC0BCFE8EB61B0DB9317FFF62BE75CD37F27B95FE1C524347500CD829CBC388644F307EC825ECB11D197DD96CEE2556AA1742F3D3FB6CBE4E3973320F600F534DED67C884C700325605E9CF92EE3844015FA67B9AA46313669505AB6215A5DF807E03E1 +6E6B751C +25FC83B3F1D2A2FA97EAA6C3C3 +3ADEBB5493BE8CCCFD1CC2D016BB5CF9FEE05CDC9AE23D9F687790C3582CC8A16B7D92A7202F5C48CB819D199480FC97431E3ABB8F91B67F8CA4DBFDFC063F5CFF2BB76E52AB419FF2B304D61F92 +875DFD1B +DCA37382BBB006F5D20D18649F +1C1EB75364A22C6B00CB39B719E31CF368FE23E08707FD4C3CA7DF57210FD64D2CDB9570F0A5F2DE87034887293AB02CD4441EC4AAE292AD05F18A493AE2B2E261A3FE5188FD532667D2E8C709BE8428588C8AB87E0549C0BB8D630B535BA6 +3481AF7F +91AF576D3A2E09901ECBF14BF056 +FF0804DEDB7B909D7F6E2E961764EE18AF1397A119BC580D5FA5352DB6BD9A5C6EDD94812AEBF5ABB9D55872A4CE5844B157A36FF066A02150D696E7E0B28BB8E0077A057B0C436811A320D54FA723F2E8F0352EC0D254F7638ECFF7D0B7C0B4E495F2F6EBB2FB3086CE66EB1AECB761D41665BB856B4FDE2A646D85ECB8 +8DAC +789B02E85E2E6B40FE63583DAA9CCAEE32287579DC5AB8D1D9883A37 +1FDA1FE1 +64098FB96F74630B964A3A856187 +457294048EB2678D3524C00ABF806519CD7B165EBBB28CB17E3004780C1A9C991783E5D862EC9B9BCA521429E24EFF72D87BF74867FA6CDB247373E18E3C670B5DC2C0736381C70EE4E9674510B39FF71DFB85E80D4F0D973243589F60A66E5AA6C8D7221F6027 +B96AA428 +072141896EE46101534DC7F2F6 +9873047610FD13CA6D216A5F8C869602092A0D5610702856D5BF206087A42D8E287D68C40E2178EF9A16AC41A00F6F369DD4F297D45AF13F6FA2CA1141570A24E9445DA7514E +23843E64 +EA2F0911491808EF83DF51766E9C +DC1DA90BDC5D22004E1532264F7B09CABD151BE2DF07FD46149BE1629C655E58B26FB4B6A76E7E0237FFA96CF15AAA6D33F16BD582268F6467B3EA03AA69A3CE5FD8B2B425B31E33E12BED0F4F3C0B20F27ECE56365B7A7FC80F999C57B07F9BA799BA81EAA0ED8397185C5B7912D0DD35 +3BCE2B12 +2D6EB91A8B4F36F5E076FE3383 +700A594A734426DDF968BDCC1CB7532EB52937BF4788946C0419AB4AFBCE98D46C93DFCFE627FD984121805FF01CED9B61FC1417A311B52C0FE7277A99E448EB7DE48EB22DAD81E20F957896206340CE03D8B6AAE7F5B5E3A2 +836BEC6B +869D5CBBE15CD808E779DAE8237E +4A34D9C4D8EBCF8FA103908244EF2E2328E36C883655E842F053470999A3C6677CE86734181F13CB1D144636F366584C2EEC890E31C52813AA57ADA650770613F3DC405B3E31C8E0C8206188EA95987E25DE8296464790CFEC2034FC2D4475E7FAC48061D839CEBCCAA1DCA48F172C83535B52F1AEE920EE33 +934A4E7F +59AEFCFC55E5054C14F5B53CCF +11576A5B9F326A785FF000CE176793632589C63E52A253966CDB6ED5F7127F507728EC38A2F75CD19ECAF8D176FC7EFDAD80C97FD554CA17CA6269C682EF8E47DA751A3C +9E25695B +BF2EC6FA72ED6CC7AB05EE7FD5 +9641A99DA247458FA7B47B425DB0C5EF7F495EAA49A48B506B900BF0B06C606942A686E39C4281E18FE35E776023A054FA9A7D3297F56C754B86637BCDC31B0E09C97F05FFF563EB6F4BC090F3DBA72736AD2DEBB8DEC5AC62725B +36A85865 +93B0910851A1C9FDA8DBBBDF75 +C60D2808671365CA6DBA5410E5F2D8F2F2E14DDA75F46EE14E52069704CA390B784532D02C1940F527061FC2FCCFB0ED7FE082085BD6CA55F5855D4E6962277BCE159A2AA52807E0E7E7686AE936C3BCB43FBC0E14A0B9AA83216B6B +9F9A28E5 +4E804A7204E05F7D9DE0418F2926 +916FB3093346B62B +978019B1 +183858DE7DA2348E61C46E9483DE63C23B2E7BC036E5EAFF89465E5AD63FB316B4BE +0645A187BFA2E7B27E8BD0C397EE7CB652FEA94F7951483FC34C1F33591DF32A72474016C2ED +860FCAA063A2B300C94ADD95EAA55BA2A5D4FB38E346B91EA8F67D +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +%Defining font PSOsymclas +%!FontType1-1.0: PSOsymclas +10 dict begin +/FontName /PSOsymclas def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001000 0 0 0.001000 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 1 /C0069 put +dup 2 /C0083 put +readonly def +/FontBBox [50 45 775 713] readonly def +currentdict end +currentfile eexec +D9D66F633B846A989B9974B0179FC6CC445BC7C8A959A39A32E9DCE7FAEF17EE3BEC9F +50E1A6FCA651FC4B3769A0A91041557502E25A5D6180FE25A3D11BF079E1DF66E54EE9B7C229AF891739707A2A0EC140306B5E43E52B79BFB89E459E50 +6EC6F610A70775A31C460976C4F79449D86E57ACE491E5C6BF20CC4307B1DAF7630252 +E9AF8CFB69B50EDAE9D36A6104AFEF8832F920FD2346B2C7104CD11E3BEE999CFA9F5A +49DB3173EE48D1C82994237F360407B022E0B4 +502E94EA8B493651EF2D03F0B513D655047568325B512AE6 +6AC6F53F3848CF70DE25481CC65D8B1A5793AA +3C4282D111112BEE28AFCA7A3808D4444C4669CA +84EAAAF989219F51AB3476A1B0B5F2246BC306E6 +625C6679C417ED2A8E9BD010DE37D40265074C2684275DD89A8790EAD18EFC77D3FFAE84DA5D +312074C4D542DD5BEC70968F75DC +250C3954E8DFB8F4857BFEF092EBA49D248955A858C5A5F55F7B987EA06EC8428D939084C88F5B157D80AB2D706A7EB936C3429173588D2ABA6A27DC94C0B484F316663555797004CBFA79E7B8545C810BF9CA92F61ABD9E202ED9E95943DF7A5ABBF3C20BDE3B6EEC9C0B95A4C9C1D38AA7C6786ADBBB79EE183BDDF194 +1953 +6449DBB7AE47E9FC6F3ABF1DCD7A1E274E87DAE9 +A22737FA +6404B215A27BFAF6D0B50E94D2 +07123A5BB380C86DB5033EE743181BBFCC0356571F7297A207C23F1E588257FDEF5DF229 +CABF3B3C +9E0988C63B358ACA4B4FEB033DFB +E2E387A06A23CACA +8E104B90 +DFDBD41F063E8A8DFA0ABA4DD7443015526AE5255315597779E04D85849305EA4F31 +5CDAD06E5841E1B8074760C99702B8CF443D752174D996C94E690797A9587CF5017DEB11E5FE +02576E9E08B39688BBE99A186AA8FC7E222F5E52B29A7FDF379EF5 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +/DPIx 1270 def /DPIy 1270 def +72 DPIx div 72 DPIy div neg scale +0 -13970 translate +1.00 1.00 scale +/wst:dutch12 12.00 /PSOwstdutch newFont def +/sym:clas12 12.00 /PSOsymclas newFont def +/wst:dutch12b 12.00 /PSOwstdutchb newFont def +/wst:dutch10 10.00 /PSOwstdutch newFont def +/wst:dutch14 14.00 /PSOwstdutch newFont def +%%IncludeResource: font Helvetica +/wst:helvps10 10.00 /Helvetica /wst:helvps ILEncoding 0 declareNFont def +/sym:clas10 10.00 /PSOsymclas newFont def +%%EndPageSetup +GS +0 13978 10801 13978 10801 0 0 0 clp +wst:dutch14 SF +0.00 0.00 0.00 1.00 setcmykcolor +<14202e2a202c2109010b010c20281e23271c2c250121292c0113201c2d2f2c2428220114202e31292c250116> 2207 558 0 7384 -1 s +<202c21292c271c281e20> 7375 558 0 8593 -1 s +wst:dutch10 SF +<0807> 9346 13385 0 9522 -1 s +wst:helvps10 SF +<4e6574706572663a> 1322 13267 0 1949 -1 s +<205265766973696f6e20322e313b20436f7079726967687420> 1949 13267 4 3868 32 s +sym:clas10 SF +<01> 3868 13267 0 4019 -1 s +wst:helvps10 SF +<2031393933b131393935204865776c657474b15061636b61726420436f6d70616e79> 4019 13267 3 7133 32 s +sym:clas12 SF +<02> 1271 1431 0 1359 -1 s +wst:dutch12 SF +<1b> 1589 1431 0 1751 -1 s +<292f> 1725 1431 0 1957 -1 s +<00231c3020002d2a201e242124201f> 1957 1431 2 3267 0 s +<001c000d121611001f2030241e200021242620002e231c2e00242d0028292e00301c26241f05001a> 3267 1431 9 6581 0 s +<202c242133002e2320001f2030241e20002124262000281c272000001c281f> 6558 1431 6 9213 0 s +<2e2c33> 1589 1676 0 1834 -1 s +<001c221c242805000d20211c2f262e2d0021292c000d121611001f2030241e2000212426202d003124262600301c2c3300212c2927001518002e2900151805001a> 1834 1676 13 7774 0 s +<1c2c241c2e2429282d002928002e23242d> 7747 1676 2 9213 0 s +<2d2e2c201c27> 1589 1921 0 2204 -1 s +<0029210027202d2d1c22202d001e1c28001d20002d2020280021292c00201c1e23002921002e2320000d121611002e202d2e2d05> 2204 1921 11 6883 0 s +wst:dutch12b SF +<0f09141109120a0300120907090c16090512091311100f130903000f100012091311100f130900120907090c160908> 1271 2407 4 5575 0 s +wst:dutch12 SF +<1923242d> 1271 2830 0 1665 -1 s +<0027202d2d1c22200024281f241e1c2e202d002e231c2e0028202e2a202c2100311c2d0020322a201e2e242822002e29> 1665 2830 7 5901 0 s +<002c201e20243020001c002c202d2a29282d2000292800242e2d001e29282e2c2926001e292828201e> 5901 2830 7 9461 0 s +<34> 9461 2830 0 9531 -1 s +<2e24292803> 1271 3075 0 1683 -1 s +<001d2f2e002829282000311c2d002c201e202430201f> 1683 3075 4 3706 0 s +<0031242e232428002e2320002e242720292f2e002a202c24291f0500112800002d292720001e1c2d202d03002e23242d001e292f261f001d20002e2320002c202d2f262e> 3706 3075 13 9531 0 s +<2921> 1271 3320 0 1457 -1 s +<002e232000292a202c1c2e242822002d332d2e2027002c202d2e1c2c2e242822002d332d2e2027001e1c26262d002e231c2e0028202e2a202c210628202e2d202c30202c0020322a201e2e2d002e29002032242e0031242e23001c28> 1457 3320 13 9531 0 s +<202c2c2829> 1271 3565 0 1770 -1 s +<002921000e1114191705> 1770 3565 2 2809 0 s +<1521> 1271 3911 0 1513 -1 s +<001e292f2c2d2003002e23202c2000271c33001d2000292e23202c002a2c291d2620272d002e231c2e> 1513 3911 7 5245 0 s +<001c2c200028292e001e2930202c201f001d33002e23242d002d201e2e24292805000f> 5245 3911 7 8228 0 s +<292c00212f2c2e23202c002d2f2a> 8220 3911 2 9461 0 s +<34> 9461 3911 0 9531 -1 s +<2a292c2e03> 1271 4156 0 1706 -1 s +<0033292f001e1c28001f242c201e2e0020271c2426002b2f202d2e2429282d002e29002e2320001c2f2e23292c09> 1706 4156 8 5786 0 s +wst:dutch12b SF +<12060d04071511020b110207100e> 1906 4643 0 3426 -1 s +wst:dutch12 SF +<1923202c20> 1271 5129 0 1817 -1 s +<00242d001c262d29001c280011282e202c28202e00271c24262428220026242d2e001f2030292e201f002e29002e2320> 1817 5129 9 5775 0 s +<001f242d1e2f2d2d2429280029210028202e2a202c210500112e00242d001e1c2626201f0028202e2a202c2104> 5775 5129 7 9531 0 s +<2e1c2625> 1271 5374 0 1613 -1 s +<001c281f00242d0023292d2e201f0029280028202e2a202c21051e2f2a05232a051e2927050019> 1613 5374 6 5226 0 s +<29002d2f1d2d1e2c241d2003002d20281f001c280020271c24260027202d2d1c2220002e290028202e2a202c2104> 5195 5374 7 9531 0 s +<2e1c2625042c202b2f202d2e0a28202e2a202c21051e2f2a05232a051e292705> 1271 5619 0 4485 -1 s +<001626201c2d20001f29000228292e02002d20281f002d2f1d2d1e2c242a2e242928002c202b2f202d2e2d002e290028202e2a202c2104> 4485 5619 8 9531 0 s +<2e1c262500242e2d20262105> 1271 5864 1 2160 0 s +<0b262e202c281c2e243020263303> 1271 6210 0 2502 -1 s +<002e2320001c2f2e23292c2d0029210028202e2a202c21001f29002e2c33002e29002c201c1f002e2320> 2502 6210 9 6241 0 s +<0011282e202c28202e002820312d222c292f2a2d001e29272a052d332d05232a050203> 6241 6210 3 9531 0 s +<1e29272a052a2c292e291e29262d052e1e2a04242a03> 1271 6455 0 3404 -1 s +<001e29272a051d20281e23271c2c252d001c281f002e23200010160024282e202c281c26002820312d222c292f2a2d002a202c2e1c2428242822002e29> 3404 6455 8 9137 0 s +<0028202e> 9137 6455 1 9461 0 s +<34> 9461 6455 0 9531 -1 s +<31292c25242822> 1271 6700 0 1998 -1 s +<001c281f002a202c21292c271c281e2005000b2d00262425202633001c2d0028292e03002e2320330031242626001c262d29002d2020002a292d2e2d001c1d292f2e0028202e2a202c2100242800292e23202c> 1998 6700 15 9531 0 s +<222c292f2a2d> 1271 6945 0 1884 -1 s +<001c2d003120262605> 1884 6945 2 2593 0 s +GR +eop +%%PageTrailer +%%PageResources: font Helvetica +%%PageProcessColors: Black +%%PageCustomColors: +%%Page: (32) 32 +%%PageResources: (atend) +%%PageProcessColors: (atend) +%%PageCustomColors: (atend) +%%BeginPageSetup +bop +%Defining font PSOwstdutch +%!FontType1-1.0: PSOwstdutch +10 dict begin +/FontName /PSOwstdutch def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001000 0 0 0.001000 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 1 /C0032 put +dup 2 /C0034 put +dup 3 /C0040 put +dup 4 /C0041 put +dup 5 /C0044 put +dup 6 /C0045 put +dup 7 /C0046 put +dup 8 /C0047 put +dup 9 /C0048 put +dup 10 /C0050 put +dup 11 /C0051 put +dup 12 /C0052 put +dup 13 /C0058 put +dup 14 /C0065 put +dup 15 /C0066 put +dup 16 /C0067 put +dup 17 /C0068 put +dup 18 /C0070 put +dup 19 /C0073 put +dup 20 /C0076 put +dup 21 /C0077 put +dup 22 /C0078 put +dup 23 /C0079 put +dup 24 /C0080 put +dup 25 /C0082 put +dup 26 /C0083 put +dup 27 /C0084 put +dup 28 /C0085 put +dup 29 /C0086 put +dup 30 /C0088 put +dup 31 /C0096 put +dup 32 /C0097 put +dup 33 /C0098 put +dup 34 /C0099 put +dup 35 /C0100 put +dup 36 /C0101 put +dup 37 /C0102 put +dup 38 /C0103 put +dup 39 /C0104 put +dup 40 /C0105 put +dup 41 /C0106 put +dup 42 /C0107 put +dup 43 /C0108 put +dup 44 /C0109 put +dup 45 /C0110 put +dup 46 /C0111 put +dup 47 /C0112 put +dup 48 /C0114 put +dup 49 /C0115 put +dup 50 /C0116 put +dup 51 /C0117 put +dup 52 /C0118 put +dup 53 /C0119 put +dup 54 /C0120 put +dup 55 /C0121 put +dup 56 /C0122 put +dup 57 /C0262 put +readonly def +/FontBBox [-50 -256 920 739] readonly def +currentdict end +currentfile eexec +D9D66F633B846A989B9974B0179FC6CC445BC7C8A959A39A32E9DCE7FAEF17EE3BEC9F +50E1A6FCA651FC4B3769A0A91041557502E25A5D6180FE25A3D11BF079E1DF66E54EE9B7C229AF891739707A2A0EC140306B5E43E52B79BFB89E459E50 +6EC6F610A70775A31C460976C4F79449D86E57ACE491E5C6BF20CC4307B1DAF7630252 +E9AF8CFB69B50EDAE9D36A6104AFEF8832F920FD2346B2C7104CD11E3BEE999CFA9F5A +49DB3173EE48D1C82994237F360407B022E0B4 +502E94EA8B493651EF2D03F0B513D655047568325B512AE6 +6AC6F53F3848CF70DE25481CC65D8B1A5793AA +3C4282D111112BEE28AFCA7A3808D4444C4669CA +84EAAAF989219F51AB3476A1B0B5F2246BC306E6 +625C6679C417ED2A8E9BD010DE37D40265074C2684219F75E53AC2AB7524E61DD2942AD43C860C +2E17ECF00C883B66A330B97B +FB4A6AA6EA10AEC651 +C9333FCA +568CDAB7BA8F537B6DAC13715DDF +6F7034D05DC13534AFFFEF22F0C3B2BDD22A183609277BA43594134A9AD3C8199EF4C0F06EA0B85EE68814F7CF36A61ADDEF33144615E547935B6419D8485DC837E72588946BEC5C48E0E434ED2345C12CED1CB70BD5F7639308478960119EA9E05D32008EF694 +14098B01 +C51634191A4F3470B8BA924CF3 +EC150BB5D59E93C478A54D38D4146AF9EC898AB29D702C5F8B8FFA7EE3A10703B7714A1291BB1B5AA5307877544E91FB3E41F1B8C71E8ACB1D74A25B58DCDED5 +0D0B9263 +6233F9358BD4A6BC955285DFDC +A777CE73B8F4BEBEC01A058B9BA409695D1C9A2E30C78C1B6E91A43D7C7EAC29E40B88704505DF14AB3C5535D729C921EB4CE4158B3E2E9BBBE5FB5A5453A6 +46F745C3 +8180F53F8A1C10626773D5CE09 +0C2DBDCA2EA00D0EDCE1455AB5B2DB1A8E93DFEA31D1C0AAEBCB7728AB9125E85FB22B75410761FC5E51515BF9E54B9DA794D0518E0875149C +93D9ABBB +0E91819459CE2D5260B0540A87 +A937BE61076C2A9BA04B0A6D057AA7E614EBC85E31BDD4 +CC945683 +C8F0FB97FCD539B8DD50E9BACA +EFEC61BC3F79368796AD692065243732DC86F77243DD663B8D5C21C9763F84 +4756337B +A805F03F3AB5A40045393E5301 +39BE17DBE0CAD8372CD7489C140442ABC310D89B1D88F3CD664B3C31 +2EBC8CA1 +86071A34F29265749676BF8F6E +C91CF0BF7E08A94EC3875CE1050AD5265539BC4F8BFA036281823D3BE0C1B7422025A07F1CD861211B2D6BFF7A56CAB7B67961B32635A7C5949B266552B39375D2036D9A2324D259EEE6 +597382C6 +BE5694BE4948EE9A9FFBAD3625 +73965B495268A9F3C9A9BD5918907B98C12971A88021BF904850FD2D53BEAF61BA325AD833E3BBDA8CCDF1CA1C5BB70147AF151A40CAC50CBC4654BBB8F709371B26FD17F1B7B2D5CE713401EB33A85697C34777DACDF1F8EEE1 +4C6EC1CA +F7A81F566B674B820DC7A83B0675 +726AD125E78B40DEC55D006066AEC40446A9403CA61FB2FEAB7D6EE4BFC38B4204331005C9A4CE327076A4C7C7D1FE78A1C8F7F7A39FBB7590B3E6E30F8900152C2F0D5674208932EAF2BCFDDFC8C3953518C51A6D301A922B848EDDB91075068BBE49766DB93A3D4A235B6A870AA2 +6C0791F7 +FA9E307107854B164F914AD121 +4B8BFB43BACD2A3E79D5ECFE10ECE2287DD9D19DDBBE71B58773A5A6469D9F82462FB64F4CA01F631704059E9E3A6D7079BED762CDF87B615D0F +4B9F3E17 +AAC72B88F8EBEBF6C4A83FBA02 +2CCA3181AF178A2E8D5226BE8E85CA9F8D88C202258C2675D6ED0DE14B1B9D0FCAC66DEBAABB99FE6360B2F3A230E8DEA9103E50809B +7281E2F8 +775DBF207D13AA31CD8A4A3A66DC +9C5296DF5342043E57AE813533BE92494EAC422F35CAF0514D72C74E2A6EC24256051130472424E27FEBC99DEAB760E98878DDB049FF8E946FC98F1605E3D38FD34114BBC1F8DA753194B1CE59E9DE45D06CCB1F3C8DB78901C68294C0B8129D0F533DE1BFED3ADE40C73C2A7238DC0206F4B2 +C0EBB0EF +2269C8A7316BB81B78B25406E7BC +10B8386B8D7EB419D2F9E693BC802A724BAFD2E4EF12E7CC29E0D4B29B4B5361991B8F6E1F008DB577D6C290721F1CCA617DDE04B32F0AD4D9B1908594760804D782C46859787B7EA445B34F12DCAFB3368EC61E6FA1B02780CE8C6CD6A20AE000028B7071E1086625700BFB871A5476EC74610830482B4F811384131300 +24A6 +68 +3A35CBE8 +4FC584D0E4D26294C446E9169D +885AF04AD0E503EE027C02E782E52DD1D4413E018F35F9FDFB23F0A346FC4180DA0F6AB5BD84B7467954819166D9284DE9FCEC69A27E2572A3EFF9E943FC5DDE36374589E80AA5CBC3E2C26F19960142DB6BE83C47D304D286DB4199A30435070B +F1E68174 +E39AA85C58839FD5320568A928 +CFC41192D804E71C6B2FD7221C2BFBEEBB524B1B67835DC766EF1CC57D03B7A97D9EBF3CFE1661EEFE381EA78497ABE9AB0E622A8E0F6FE6AB02621B6172220FEBEA9D14066A2B3F785C683ABB059A3241C3801AB03E5FAA9DF70C36ED5018689AA2C1 +82A7FDA5 +931C844B1AC8B5863DE899339842 +E65247934ACD970C83D4D9EAAEE4A53CC1C003AD93F6019DE41FE25D45AAC50B0F8A4AC96507C7B714D6A83340775BCDD8888CF44C93883CEB10BC31E5EFB7D547B45A12B1C51A21C042FE4E7BD72F91D39BC17854D7E41C4EBD142AA51C47AB71065AC2F7986EA870 +BAD88FD2 +EEB12FC32369032DC40057AA35 +3E9112BFCD54BA42A47CA3D8676FF73ABAA9239CEF8A7B7DEE2A51A8FDCC3A6B976711F86108A10D12C7B6AF2898C9CBAF03639A28F3749BC66BEF +FFC6D411 +31E51659659CFAD15FAA486A85 +DBC2F455C9D9EFC5916818EEEFD679A8F021B0632AAC0D93942346A5689C28E8F2E999CE470AB95EC6560C58C1443EB019F24C38C34F212D258F1B1408D6A5478F86184BAD3BB4 +2F131468 +3973E1720C270C74B00DB9C2B636 +562C5C7C1A0E5BFA7CBEBE489E2B513A604F24C9BF6EEC8D96EF6DE57C4F6CC418FE2282404FBF858E66FB11FBE299E4BFC90C5F76B5625616D384BAB0DDB6820D7BC0583262A0A843E05871E085AE8956B9FFC7B326C94E9306F03B13A1C9CE6AAAAF2C28F0F6BD95DD1559D1A429 +95F4EFEF +DC3C34BB7A47776C18E1D956E1 +254970C7923C825CD524181FF09C853F03FE9FC13C93E6E5631854F5918BE1910E1F14DFA40845929C432FB3BD745E8FCEC14D0B11E12E125592A014100FF3AB6A45D164175182015F2A1A130EC9D32DBD4E6DC235B9251059C1EF27 +66DA4D87 +D990FECD7E8ADB9CC957932BA4 +C9DB0F154B96D4A4099CE406823EDCFE68C4B0EEA189BC70D45268F926EF5F4C36C099A9CE8702A23247E3D2236E72EB185EC73384728B8D9B6A214838D3245CDC9D6E2401DBB2F385FA68C507FEAB9E0D88AC +04D9FE0E +79385926E10FC041758F4FC2D4E9 +C449E147F2CD4C393E1E0EF38842290111D09718165D6D57F7FD958F0B0B9EAE2652F4F08219331A362ECD63F8679EDD18A16DAC018560BE5E72B5E013E13858BA0058F781DC009CE2987638AAB933658DE7E1B9F73C911D7356EA94DDC2B8E080907EDBAC0072D1E581 +937BB6A9 +01C259F5A372B3AB6459A04FEDEF +DF24B580A58BC2583F9C2E6EF0377A200B6CCA8740E98E4C2DF24506D64FE37654901C8C8BBEE11AB9E8D4D9D4D86105E442D855CCCDA1C261968B97202AC533E403FB93BFA116DD7114CD34E8AD3A002B3E9734E1705DFA73E1F3698F13BB51AB6D8028E29620E02930283C666B5ED698C6AD78F48DC415CE199758E37A +BB043BF0 +1862268F41D2DE94B7087ADED394 +31033CCE0E04ED1FE22DB8E0F184A8F901EBC1AC167EFFBE48468F4BF62040791AFFFE77C7E1F7918680A444255721BEE5825B29161EE22821FC0C6E719A6461FB2E822CFC0E381B2165E9E8CA45013708BABF99F85F4DB98216CCDF8817B8B9FE8D9B8056B6C5DE52AB6CF66CADD4039C3C231768B6A2A861E7ECED547F +E08E +0FA60C +52144F5F +B86C873A0573881EED0F845199 +31D3DB4462F1945AADE2EBCFBE5DB1D7C1FEC6283A1A42A217F9FA3D50002A0A8366B447522378A60CD7E337E075B44743A4B82D168F329D6C1F2397FF569D9951C6E9D197C5FC1A10884395B5A26D838D +99213CCE +185043E91DB6D7E698BE5A17DE7F +C301C20103CD79931E4393A0C881694DC063E7F4982D1F6AFDC14034D23D30AF25E07C8FCA6A880679A141A9005C821F1A1EC4C586ED10879BEA15211F3F347C7E82AF78CA9371D17A4B1E0D858B77005FAC839A22201EB6166E15960B7EBC240C10E1A3 +D3FBAB63 +7A8D355FB7528D3BCCA59BD583 +78602CE4DE34318A5D09E8B5AD0A96BCE8856E29C3C3496C20D2426CA9F2E8C3A051B7BF23D03E5A2EE1BAA1BAFBC83EF589DDA8849B2527ABF27E188C9844C644D0FA991BDA4106E9C79F014D2284835C52C04E10F4A2B476 +BD8654F2 +94B9AA96A3B1A5CDA3D4A97910BA +A4B9435FECBCEA8A8B9DB9A37FCA35C460F03154B51141372CD2D040EFDED6AB4D445F8B0778E60DC0F1AF87536F6EB8E74E083B5182080C122C8E315A99E41AD72FB69460146628C9DBFC5062564F51705C95834DF0BFFDFFBD11795BBF3304353D32E0D6A5537167F2D61940F57C048FE2565478E5E0AEA30FF0B6D22E +A37C +00EC9C5454C44A3E78511DF2F37FCE1A5DEABD0C1A5464D43387B3039E1DE004760BF1E1FD9EAC +B2F51BEF +07E66402303C8169B72B5CAB0B +6342F1B41D3BCC1E8DDA7EEDFFB374B6A9F0463C3B3776600299F2EC649635A543F8BD8110C440C223450772237FB92ABFDD0349384CFC7F65AB +E8C7E756 +14C8B8B14CB5833D046BE2EA1990 +E5255A4623909D5C2DC26B15ACD866D9BE142B7CB1771684AD6A4E92272FAF85C481B4775F12C7DFFD2E87A428AFDB67A6AC5C9FBB7AE433AFB9D6677B9DE5064D4B6C69CE5334CE3AD11B03F451AD1D4542F15B4979B48653768A3178DD4209E1B48B32B915B590421EA4FA23ACDEF7E9669854C10E47B0396FD4E56A62 +55EB +80383A +0EB56EAC +A2D98F32F85E25806864E63E44 +48BD86AA76EAAAEDC55B90AE94C95E226CE6FEEE2C89ABEC7FA4C14D4ABEC56CBE7218CED843924974A3B6CEA24ADB78C4A062FB5F6A9975F4EE4D1D51D5543EBDF6B82A27BEC936892CD2BA1D5792C93941993FE7513CAA +62C58F27 +143A556C07CE5A2DBE40FBC00A +9912B63D04BC738C40CB2C4C1B9F43F13F5227979E1EDE0C86932D81D9537AD9CB6C770890B4D393BFC7B2E62FB9D3ECF4628296403D5BCF40D5157E064D0A8991E17E8C64B775295BF39351000C3CA2521A +EBBB878F +D2A9548C0D93AAEAA603AF66467C +135210AEDA96FDB90D3A6D173973AFDC4B207A8A5E29874220081EAD38E0274A8DA54F082CA0C3FF4E0FF4DA4FB529E956E77DB4280605DB7438FF19787D8208449D1B17B5F6DDF34A324640E3065D242631F6621A9148A90A96F7D89558B1E6FD3FD38F5B948FC29A5AE75776B1 +7AAEB7F0 +9C2B407AEE7B0C3A3B00E456F6 +ECE4D25EA888FF21247CA9D956E026E33C362233B14D474932C7139F0F108F6D47572633A78A5A874E5A6989F12B99FA7C89AED17D62166F0D35E17B388F3C81062FF6A058B38DF98A6E46C8CDAAF87356F23A9E2ECA0CA547 +F8B2D1F1 +85C9E540559C48EF29B451EFDF +A251E9C42DD0E3EBF9BE30B449045F7147C46C0D0C972A8AEEA6BDDB2BE2ABC4869D1C581FC1C557242021E2AAB22D50A715923E27995A55CDA11BCA95156F4D71B91EEC2A3EDFB5F8FE2D057EAA767E073872D25E76C7CBF12FE22D +AE9B32E1 +2B542EBB37BAB5DA219CF06A6E34 +DF084EBB276D4CDD96A9D8D1C474589112B6A97358DD1489B924DC13BB9A2CA1D0788324ABDE9512A6C374849E6E70CA855AE1BF278F614F38F0C7FFFABC85737DF494EBEE4C72D448C52D4D05FBD701CC476E67ABAF0989B706E60EFA9A7F3941EE6E6FBF1B1A01ECE475F7EBCEA8C39DC40A2749DEE162D4B987123FA4 +DFFB +0D3191E93BC025F9BA6B12CEBA96EB1C818416CA3D109AFB16CC383B5ADFE80EA5559B90532C53D710F84C5F8462B9 +DD6403F5 +7F7B89DF379D633D24097991478C +D587D085DD98C9941DDA702E6CBBA2ABDBD821CCA092DCD79DABAEAA1C9F5C5E21D24F12E0E169D848E0CC7007B6617B028AD88F174FCC7228EFD171C92D05B98FBCB8FD6DF2793EF249E6C18580772E7CDD22898B160FC061D0CDF04DE31250CF980272162180A1F80B07AF4A +9AE35B5B +1B8D322DFA6E8D6EE823AF9D42 +E7E92E355C2BA87E68BDE2F2FCE89EFBC3CDAB8796DA2CF3B68DEC0D4ED47616AFBCDBB16D4BC40E636F28061A6E46F7E70E538656BDA83DE4EF4091DE57B20BBFED3F438972302ED9CCAC5E68A8335E +E12486EF +D39FD647D74466D4285E8BF37C +FB4BED1C44F95BEA7640135680D9A8E81A546A24EB16A7A0BA54FF199B74EC77C7483279AD54CEF3969F24A927B420B8DF229D331BD1AB50A95070C1E5CB010702C3E4F960F4661D996837DD3D2A41A0A00ED19FF99665E120EB18FCA95829B391D1CD +DD2D13A6 +1BCD276A0DF8638E88F742BF6DC0 +75F7F924208DE9D8400B4F10053B4125566135582C65728069D471F4A2805027D9E660D057F905A33265343BDAFBE33CB185A77A254B384301E4B1664FB1B86578ED897264163EA599B38ADD944FECFD59058C69F38055A226DB72943D55D9EDD816A867A009312B7C4E0CFA881E41DB8A776AFCA81E875E7141304E28C5 +D619 +F1B872D298F33C6C081D9FCC8B41CB584D19526CF74127DE45EB99DE6DC4AF775B1A02 +44F8D8E4 +269FA13F52D5C6DCEB78C1E449 +853FA9B640C1E2E670B36295F840B3ABF1862DE1E957105937D68B0227BCE9D2628CBBAF0C751CDB1417BC954AA9226B699A1CB51C6C +B79D62CF +A391B014FD909CC21029518B4804 +0D40CBF9DA1112C6C2F896E82955022CCA1948C0CA7D6F17A8FFAB297EDA12619E38140FAE736CA32B8CA53D875C2CC432C9467CE2AE62AF6A1193064E3AE509B8C06CB8A35B2B532A26EEE82CDEF1660EBF5F5F6DFF089E085D4B727F9ADC795EA651BBF500854653F64F03E3AB4032472684E850EAF3E44E6F0F5F2B4E +070C +215D0B46599D3D71BF45EA114A2EA1079BBAF4F2EBD4A5ED4AB04EBB7ECFA8 +160F7EBA +3194DEC14EB96087FAB292DF6C74 +2EB6F09D7DA6958211AC62A7882E8AB945F133C7BBC65520D9D5AA4DFBC31E43250829E47C5E9F1D056683C84273D50719FAC8D5B22B8A5A90F56FC9B1390C47405832ACF91C0A5C5C9D76644B126E50D5883DAA4F960830977D6BB6FB2360BC7641DBE2B6AB79840E54B357 +C34C5AA7 +F167EED7C43DDE8D87AF596196 +38A93EC68A10FB926A7ADE4D3D2B50EFC2D8E59E33AC7275AA6BB8B0D7F568FF4A20B896AE38D14CB377281A8FA3FE263A5C7A05C77F3FAB4CAD0A699586CAE9D50D1C0FA48E +716213E6 +8C5E19070028CC0C027594044948 +57CA9A4E2AB219A29ACB03BD82EFEFDDF924F1A16725798B929831C1AA17915B67D5A46459AEC9F103F55343C56DD494CD786EB78CB06D4D2BCA1C05A38703B970870E571E73D9C50741DA3ECAA9EB4FA51DAE965D03782DEAE642F3D5BEFD8146BC53AA966C46FD3FC698BE158E1DAEF040891E694EBF +1A4ED33A +9C35912145262383C6E569A1AF +7B997F72C264C1CBC2E89200F7640B8F394463DB62BA57264B8E257B2D8DBF7DCB06CCD68A3A5349BCBD544A936140F150574C44F98A3F89F7051C9A26119D13A7B570226D2A0230CA029171646A4114E697E488A91354 +2AC11182 +1815D8E67D81245421AB6C1226A2 +5547A8CEDE7DC36CD60DCD0B4590012556DF8BCF1BF0F23E937F769CEA783AB3CE331F67FFD180A3057ABB0F7B5BC42F90E8431118EA6FC0481705B561FC4CC6C26B02731AF31DE8F9ABDE63DD626DE54E85A6DB64912DAE9F1D714F08D9922137A791D2FB928A488A45D0AE4F3E34BED06AC5DE1DBF8C3142236AB6 +1F8076B6 +92CBD41A1CFB993090E8937288 +DBC4F966CAD8C58FC633D9F4B37406A08F2E5479161B50988DF34A9DC9ED41064B92CA2DA44D9F63BDD4E891789CC49E3EFB9DCE9EF789A9EF8FEEB4D1895B0EEBE6ADCDEF +E2883C30 +A4C16A8EF9B74B2FF5F92DA0B1 +B3A34E9B2AADCB9FAB6BDE1E4BAA1AC57E25C89430FEB3306239CAFF2E54D88C3C78FF5E2518565D9B9D47D22CA518A3F634870265F67AF5B38B41EDCDBF5023E6FE9C420065E2EEF810DE2887441C6D123811C6C3649239AF88E8A6BE76C46F1C5B +A2764AC6 +84B47F0DE77E3AF08B76A96ACE +6FCBDD6918F1527C49E4D12A998F4B0DB0AE6950F3F9FD45BE3BD53E55A11B2BE25E196631268A017553E4775AF86871215676CA456D9909D56405D8967E249A5C3393C46DF4BF8A1C2C5E87C9A28650519C474D9F7AB32A54 +172CE812 +913939543EF5FD0A67B0C69F2BC1 +FA11191A50EB6DE2DA9D76FD9E9E39239DFEC70CFAB782E937F475377D1842937EB38B842CDF796671D2BEBCDDBD1684C00342F952BC3291DC21B2D780C1E70967F6E0D0545FFB3BFA33FEC7714A9F38C92C8533384BE297F017FAC03472AD4AF63DF5940485FB59FC50CAB3691FD600D9E2BD64696CFC2CD961A5FDD267 +662B +673D71455CF807D75D895F0CFF8E +4F0396C4 +16494B951D51A72CE4665E119D5D +EED4875CDA0E03D809E3E3C45DE0D456FC69BB6C66764CA96C746A473A25E6D6DCF7AAABFA66D700196714393CB73DB4433DE48B9C37B8BA6888388A423A0EF3AF294659623BC7750B6474A4BA77BD82104E6FDB1F3CA69C0BBE5A61D2E7E02049CB8C54749A7F19B1875B795BB031AFA30FC1A9D2D038BC9A9C059E9BB5 +0CDD +8848199382C370C02C16354C465CA583076AAC30F2B382666D +190A5300 +C71B7220B04BF0E849CEBBF97AE7 +C6C44258FD14FFA104FA33846A97A49F0D79BF68E5E425DA2A6F8587C77BF06BBAF3D2014F47DBF2AAF8DB4CBE68CD635CD780E1EBD944F8F9104115B3361146A7AF249EC4E391E34F8809BE9994D5BBB0F4254AF1571301BB56FABA36ED445C784AE760295A3216D9AC60410C8259E331DCD2610EE8EED801212FC0FF22 +12F7 +48685E12 +A48FF771149F394BD4226F568B +A8A3E67E2F028B9FE3C91DD6ED710EBE9DFF01D28E40512FD27429005661E0D12BCB2BCE519E8EFCB07A6F6CA2EAA483003BBB06E201787AEC5F61E99B6BEB +2B6C244C +B3D92A94EE90911FF3E000B8C4 +D09F4E99FF6232B50AE19E3E428264A7E2DA79C10A10 +AF0DBD51 +73AA3885A6F7C788A9E072A0DAC2 +08D1B93A87F5568F +1E62BA62 +87AA9BC693B820942965B93D83A33B707886AD74392D220EC5432C3906BE03B6E76A +513A78A3C38DDD1D66D1905E01CAB5C9E3710F2DD4EEA60203573AE2468761FA639873A63A60 +958536A597AD8110DF145776A6905631B10DCB2BF393D0B2A381AC +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +%Defining font PSOwstdutchb +%!FontType1-1.0: PSOwstdutchb +10 dict begin +/FontName /PSOwstdutchb def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001000 0 0 0.001000 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 1 /C0032 put +dup 2 /C0046 put +dup 3 /C0049 put +dup 4 /C0050 put +dup 5 /C0067 put +dup 6 /C0068 put +dup 7 /C0071 put +dup 8 /C0073 put +dup 9 /C0076 put +dup 10 /C0080 put +dup 11 /C0083 put +dup 12 /C0084 put +dup 13 /C0085 put +dup 14 /C0097 put +dup 15 /C0099 put +dup 16 /C0101 put +dup 17 /C0105 put +dup 18 /C0108 put +dup 19 /C0110 put +dup 20 /C0111 put +dup 21 /C0114 put +dup 22 /C0115 put +dup 23 /C0116 put +dup 24 /C0121 put +readonly def +/FontBBox [-10 -209 745 694] readonly def +currentdict end +currentfile eexec +D9D66F633B846A989B9974B0179FC6CC445BC7C8A959A39A32E9DCE7FAEF17EE3BEC9F +50E1A6FCA651FC4B3769A0A91041557502E25A5D6180FE25A3D11BF079E1DF66E54EE9B7C229AF891739707A2A0EC140306B5E43E52B79BFB89E459E50 +6EC6F610A70775A31C460976C4F79449D86E57ACE491E5C6BF20CC4307B1DAF7630252 +E9AF8CFB69B50EDAE9D36A6104AFEF8832F920FD2346B2C7104CD11E3BEE999CFA9F5A +49DB3173EE48D1C82994237F360407B022E0B4 +502E94EA8B493651EF2D03F0B513D655047568325B512AE6 +6AC6F53F3848CF70DE25481CC65D8B1A5793AA +3C4282D111112BEE28AFCA7A3808D4444C4669CA +84EAAAF989219F51AB3476A1B0B5F2246BC306E6 +625C6679C417ED2A8E9BD010DE37D40265074C2684269A711773B1F062EFDCE93198A765F8F55A +6E9F60B43AD213B6F99675D4 +AE976E2319012DB96B +33CB37FC +2AB7CB1AA9E7C6D1A60ECC1036 +78173A5EDBFA71F1EBD0C032CCD138B6D4CE66801DCDFEB6BD820A11ED36DC +8E4D3CFC +9B74D73543C6E8B2D45B77B6DA +54B7C3CD189D2206A152D6ECD0CF40754F73DACD28C6FED9BC298E40C5C21DEA25561B44FA9D29ED7AFB7A4EBCE93BC13969B8205D22AE36295387DF +A8F1B869 +9688D8625397D56BAB98854725 +87284CAEDAC3E4733F404DAEAB8300A9ADA01E1749C87ADFABE436B08C24AD5A8C3435AEF552FFF7862186A022A2A12AE3A5AD77B865BF5EE3E16127E5E42CABF39E7EBE07B3FB360442D199345600253FC5957C +0460B0B3 +4D63CA5F0656AF76E9F73B59B384 +B2E592B0A6787F934266671963A6773092FFBB489635FE81CF5B90A2C3D107A0235576C7D150B3AB5BBD57E424D91476D215CE436DBBFC07F34395D3534EBC603835508DFDFBD1C8F315D82A11CB35E62377A6E727DB5FF586388856FF448325DFB62EA39A7F3ABD +CE627223 +6042BF3BC39CDED13D98F57EEF +40E66F95C46525258D63D195B4AA909B9BB3B7010ED7CBBDD9BC73D62B790D2A968B1097164111A49944D602A8DCA142B2B6B6442761F29D5D85B8754E7634D10476CB66646EF5A4FD31E01A22EEB86F7D362699BDCF4D +E9C91355 +A5F5A55523E641EC8914B0F3594F +A089BAFF6DBF59328EA1CB855CB41EB02CC487F042B1FE080D68BEC34882189FC4BD7DB2A17CB3F1EBBE1FF7BA6268A6E51E60C75AAF8AEF3BBBF124290D9C069FB80E07270D6AF58B6ACE591E5A54AD097B5F5AD7A273C349F6B28961D7847A861078E686A1F3E0FBE6A5762DB7565E0AF57108755E41 +9644DF01 +F4C314B0DB14A2B1D078C3E6CE +58D9397D2D169E741FCC5A1405578D48A5205CB8D9D264E52C8AA8596328A3C74EC2CB0E24FCF8850D8F4DF650FEAA40E804717FE2647F4914C33B879963 +ACFB5A9C +6EBB15240F02BDA9DB7C1B1429 +79D80DAF3F849838243322158FA125535B2F7EAA5029B963E5B8CEF04DBD3177C95F989E31136C8A9F81361C1FC11A9945DCACE165DC96D131313CE24D36DFDDBA66CEFAE93A65D6B8 +9BA4B52B +8E6DA725E8A3C7A15CF0E1E9809C +E9BEF6436B9765B6AE14898B1636D940C35A57E51AA0646148DE3E72353FC929244B2CA0AAAB739846533CAB7F789777D80301CD31B4E994DB533DCDA5D96A3DB33F24DBBAA3D58EE9176167BA2782C9713B60512565CC64330D0BD7D22F50CB9AE70CC3 +45D3283A +7D05CFC9A691E2E2ECBA5ABA1EB5 +C901DEF3211E75755886FD0E8BC3FEB5177595E4500A308CE30A02E00973A0A32EA78340F7690A0E409D4998BB4BBE6F03598D91DFB4D3B1F9496AF98336B18CC4A60390729419EA27079234BE58A0969F7D947B81DE51BB230CBF930C9EB9D7B05D2BE36388EDCD175FBC5394AC5B56AD67236C2FF0C1E19C41D78A9CD5 +BCBD +B0EC82E1 +368E4C6145E40A96324E8EBFE1 +3BAA70CBD3BB21F46F137F3E8010D97E97F076BC571B497658CF6B6DF08CD415FB003C6AA453B7FC4BE4D6333EC833AE2D8354FE77B201680B9125B4FDF468ED4DE3D1FDEC7564EACB +29A99E79 +8A7E88B29A7F897112BC752A7C18 +39B5075C29D4AA75755B84F7F4E6CFCC6A8B533C85EF2B6B0E99A8E81B335D337D95764D2108DC5C4BD25DA052D07263F719CCF9F0DFDB35DD12B7EBB746824E91EC3C9730B78009BE083341EC9C836DC2CE6F97840252E3E24367D2B6E50E76E53296814F4661 +97E12883 +7454D219FFBBFEDA1CC96A7D12A1 +6E34AD907640570CFA111B801C3DBCE298D2434108D45BCDE4DFF60AD7E2227B7058C09E17A9E814FF6A412A531E2F4A92253EC7F5676D4EB5E04C2323B6D9FC53F5570FB9E815B0F4EB156836342513553FC5B0EAAB7D688DE60CF3CC7B8B6DBB068840206E49955B1892CB7D827C38D3A94B30F9B1904AAA5F9700D2EB +515A +044618DF +AD124B96 +044A6308C5612C8FFB9D963D76 +9A957C8AB2092D0308D0E183D841939B523F575B4F14829AEF05C4977FB8D31408CD6D798522812A07A769945797894885E8DAEC2056119D0BADD5A1CBCBEED3AE1ADDC4B6AFCF4F956F407C1930EDD18694 +87B08BFB +F5BAE2AF4FA03BC2A89B2935E6 +6E18A783A824394D0475BA2FA3FEEC442685E10C12E4A93132A4D425F24AAC48E8351B0F467319AA2B003EE33D6A8487215383F57274DCCABCB20461C51C95CE97E8C990C80FA5E64AB32202A1080F19159C71096769B10CBD29ACAB +EA0C0A69 +AF9B319CCAC639D1E4A0B810C0 +D8253B24E3412D8154DA5F4D1CA8E010B913DF314F10391BF31A8267A2D09F1349656BD23538706BB11AE4F5A1F60039396BF817F2685CD1C02BBC15D17577113F994EFE21C3BBC92ECE1ED22522 +56B4325A +F32BB6A70D0652324B2C720ADB +C23EE202E296FF398C3031C1DD6A5DDDD9851F4AC1C5725CA09FCF6029F71D0B771D3190BCC8DAC1A0C728370B869EE2D47FC26D +8B5D2E93 +63416D09464A760DB4CEDE0FF82A +43D64F4621A9940EA8DAEC465BE9CB0F37E7C17FD8768B12A83129804977C2904CFA4E3D0FFD2EE0987F38B73CBC81352C469B0F9C89F2B9E164325C8625D8EA63405E12D56F1F1A92511751F81A4F26346BDD408AD0DFD7DAD9C912CE7BDDF738795337F54CF2 +C8C2C2A3 +DC530EE3B8D8A18729B403FDA0 +26198186CFAF468665D44086F2CF7AC6E704FD8572BA00435AD8A23B10623B3A2963DE9DF01E4B7F2FC4339F788989BAC1C4AD3CB491AC6161EE8603143C8F7C30B0DD7D0D02 +A71427AF +987A66D8431D15D8520BCF31E3 +CBE9282288BD9B41336CEC85F6B7F060300E52F8CDCAE4D18ACF45331DAE09DD0043B688C2BC148E05F32610508FCF2FA7FE4F18E8CF7576C0E4B026699977ECCC94513EC3236E64DFDF5D22D096189AB92E487CCD4F8DD03B +80177877 +38F52A6EC68E51222A0675E46460 +F6DBAAB3B94C5586E99724057DEA774136625BA8D0CA772452757B1488E1DBA9588EFE2726D1F159F09024A92ABB8770D4DAB1216608BE7B08BC0CE9F111CBA9C6540D2C6E45B46AA2C272055A07D70E55EAB7E570B2D275BAEE61D074D16F64E78C36FCAE33996EF550BA30E9F319759BED895E7990479F1A +39346366 +2E304A94CAA4EB3C0A43870527 +9946B3AD08CB9E9BEB67ABE30B8BA459F1F7343DD1476AAB3C1FEDBCFE1C5DE687E3131AA8CC36F3A1A16E4174B52BB7BDDFF7702FA69015449E2EE62172AA224B1F73F2 +DDC80FAA +A5616B86AF1AE577550A0219D48D +74707A3F6A7D47C14A173051604E936CBBC2BBE32D6C461041A4128E0B28E78CED92C2DF61E540DDC6E513A5C662A19993792ADA4995E0A2875A8DED055487744B0A38329CAA7FC74842DB0DA7AEF5EDE003E8523525C8581E01F2C631CD0467FB9A150B08D3B42EEA37568005B787C2DC4F9647A91466794830B671C0C4 +FB20 +57 +E3B3E20F +48D122D7E519A447041076243E89 +8F2442AF05D10770 +FAC107DC +731E7EDF1BAB23D9ED197FC926986C248AC53F138CF6513F1BE3B4B290E80F2C01F8 +2CEEAFFFE3BD13034B8F162173CB43513108FDC71A06D9354F7B09BF8C3506AB9B0A2845CC8A +1A78F851A03F8E6A0E0E589945EA8A0E25D61FC1E93E817B664E8B +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +%Defining font PSOsymclas +%!FontType1-1.0: PSOsymclas +10 dict begin +/FontName /PSOsymclas def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001000 0 0 0.001000 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 1 /C0069 put +readonly def +/FontBBox [106 45 775 713] readonly def +currentdict end +currentfile eexec +D9D66F633B846A989B9974B0179FC6CC445BC7C8A959A39A32E9DCE7FAEF17EE3BEC9F +50E1A6FCA651FC4B3769A0A91041557502E25A5D6180FE25A3D11BF079E1DF66E54EE9B7C229AF891739707A2A0EC140306B5E43E52B79BFB89E459E50 +6EC6F610A70775A31C460976C4F79449D86E57ACE491E5C6BF20CC4307B1DAF7630252 +E9AF8CFB69B50EDAE9D36A6104AFEF8832F920FD2346B2C7104CD11E3BEE999CFA9F5A +49DB3173EE48D1C82994237F360407B022E0B4 +502E94EA8B493651EF2D03F0B513D655047568325B512AE6 +6AC6F53F3848CF70DE25481CC65D8B1A5793AA +3C4282D111112BEE28AFCA7A3808D4444C4669CA +84EAAAF989219F51AB3476A1B0B5F2246BC306E6 +625C6679C417ED2A8E9BD010DE37D40265074C2684268F16195489648993B9C4D3B534FA887C +DEF605FA87B991F4D20A8F78DACE +5A54C070E03D5C59D9D2D3E06B09CEE028D68B62AB3AEC43C1DD20BA70D288597D9BD8E06818FF764EBAB436723988E8D7CA59E16D39032516BFC5D552ACDEEC6BE938BEF2F43CFFBC811C3626C4DF5F8CF080676520B51C60CEDAD1FE6C92D1431C702174CE517A8FA9377D075A0B6833DAB101DB65397F1419EF5F0016 +004F +6F0824F9657BB4F1C8F981709956865F6855EFAE +9242AD55 +91BBBEE163D844DDA894E13190C9 +2480439E4C71CADA +BD043A9B +A315CAF72652AA7FE6DB2E84D82A6111CE4DE90C02DA0AFFE2620922262A45AB4ED0 +EEC9F4520DD12703442F7D028D4526BD8B771E09FBE11B2749E2D3906894E8D4BFD3F379F14C +3C874F550606965E22FE487B247B5C2D06728490C8F2A3B588CDFC +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +/DPIx 1270 def /DPIy 1270 def +72 DPIx div 72 DPIy div neg scale +0 -13970 translate +1.00 1.00 scale +/wst:dutch12 12.00 /PSOwstdutch newFont def +/wst:dutch12b 12.00 /PSOwstdutchb newFont def +/wst:dutch14b 14.00 /PSOwstdutchb newFont def +/wst:dutch10 10.00 /PSOwstdutch newFont def +/wst:dutch14 14.00 /PSOwstdutch newFont def +%%IncludeResource: font Helvetica +/wst:helvps10 10.00 /Helvetica /wst:helvps ILEncoding 0 declareNFont def +/sym:clas10 10.00 /PSOsymclas newFont def +%%EndPageSetup +GS +0 13978 10801 13978 10801 0 0 0 clp +wst:dutch14 SF +0.00 0.00 0.00 1.00 setcmykcolor +<1624322f2430250d010e010f242d22272c20302a01252e3001152420313330282d2601162432352e302a0118> 2207 558 0 7384 -1 s +<2430252e302c202d2224> 7375 558 0 8593 -1 s +wst:dutch10 SF +<0b0a> 9346 13300 0 9522 -1 s +wst:helvps10 SF +<4e6574706572663a> 1322 13280 0 1949 -1 s +<205265766973696f6e20322e313b20436f7079726967687420> 1949 13280 4 3868 32 s +sym:clas10 SF +<01> 3868 13280 0 4019 -1 s +wst:helvps10 SF +<2031393933b131393935204865776c657474b15061636b61726420436f6d70616e79> 4019 13280 3 7133 32 s +wst:dutch14b SF +<0b100f17111413> 1271 1458 0 2055 -1 s +<000304020007121416160e1518> 2055 1458 2 3427 0 s +wst:dutch12 SF +<11141813> 1589 2086 0 2105 -1 s +wst:dutch12b SF +<06> 3177 2086 0 3333 -1 s +wst:dutch12 SF +<203220> 3333 2086 0 3612 -1 s +<00> 3612 2086 1 3650 0 s +wst:dutch12b SF +<09> 3650 2086 0 3785 -1 s +wst:dutch12 SF +<282d2a00> 3785 2086 1 4107 0 s +wst:dutch12b SF +<0a> 4107 2086 0 4239 -1 s +wst:dutch12 SF +<302e342823243000> 4235 2086 1 4926 0 s +wst:dutch12b SF +<08> 4926 2086 0 5008 -1 s +wst:dutch12 SF +<2d3224302520222407001b2728310028310020003132202d23203023283824230014282d2a0614> 5008 2086 5 8527 0 s +<2434242b> 8531 2086 0 8895 -1 s +<0e> 3177 2330 0 3340 -1 s +<2222243131> 3336 2330 0 3789 -1 s +<000314> 3789 2330 1 4040 0 s +<2434242b000a002e250032272400171a13> 4044 2330 4 5495 0 s +<0019> 5495 2330 1 5691 0 s +<24252430242d222400152e23242b04000e181307001b27283100282d32243025202224> 5683 2330 4 8895 0 s +<2831> 3177 2575 0 3316 -1 s +<0023283122333131242300282d002c202d3700212e2e2a31002e2d001a323024202c31002f302e2630202c2c282d2607001b2724> 3316 2575 8 8334 0 s +<0011141813> 8334 2575 1 8895 0 s +<1d> 3177 2820 0 3339 -1 s +<243031282e2d> 3316 2820 0 3873 -1 s +<000a0019> 3873 2820 2 4254 0 s +<24252430242d2224> 4246 2820 0 5026 -1 s +<0022202d002124003024323028243424230034282000202d2e2d372c2e333100121b180025302e2c> 5026 2820 7 8895 0 s +<222e2b07272f07222e2c07> 3177 3065 0 4218 -1 s +<1b1018> 1589 3412 0 2006 -1 s +wst:dutch12b SF +<0c> 3177 3412 0 3311 -1 s +wst:dutch12 SF +<30202d312c283131282e2d> 3284 3412 0 4351 -1 s +<00> 4351 3412 1 4432 0 s +wst:dutch12b SF +<05> 4432 3412 0 4580 -1 s +wst:dutch12 SF +<2e2d32302e2b00> 4580 3412 1 5217 0 s +wst:dutch12b SF +<0a> 5217 3412 0 5349 -1 s +wst:dutch12 SF +<302e322e222e2b07001b27283100232425282d2431> 5345 3412 2 7254 0 s +<00200030242b2820212b2405002137322406> 7254 3412 3 8895 0 s +<31323024202c> 3177 3657 0 3792 -1 s +<002f302e322e222e2b00252e300024362227202d26282d2600282d252e302c2032282e2d002124323524242d0032352e00272e31323107> 3792 3657 7 8883 0 s +<1c1118> 1589 4003 0 2062 -1 s +wst:dutch12b SF +<0d> 3177 4003 0 3332 -1 s +wst:dutch12 SF +<312430> 3332 4003 0 3599 -1 s +<00> 3599 4003 1 3657 0 s +wst:dutch12b SF +<06> 3657 4003 0 3813 -1 s +wst:dutch12 SF +<2032202630202c00> 3813 4003 1 4613 0 s +wst:dutch12b SF +<0a> 4613 4003 0 4745 -1 s +wst:dutch12 SF +<302e322e222e2b07> 4741 4003 0 5443 -1 s +<001b27283100232425282d243100202d00332d30242b2820212b2405002c24313120262406> 5443 4003 5 8895 0 s +<2e3028242d322423> 3177 4248 0 3943 -1 s +<002f302e322e222e2b00252e300024362227202d26282d2600282d252e302c2032282e2d002124323524242d0032352e00272e31323107> 3943 4248 7 8895 0 s +<1b1413> 1589 4595 0 1945 -1 s +wst:dutch12b SF +<0c> 3177 4595 0 3311 -1 s +wst:dutch12 SF +<30202d312f2e3032> 3284 4595 0 4049 -1 s +<00> 4049 4595 1 4092 0 s +wst:dutch12b SF +<09> 4092 4595 0 4227 -1 s +wst:dutch12 SF +<2037243000> 4231 4595 1 4660 0 s +wst:dutch12b SF +<08> 4660 4595 0 4742 -1 s +wst:dutch12 SF +<2d3224302520222407001b2728310028310020003132202d2320302328382423001b> 4742 4595 5 7692 0 s +<30202d312f2e3032002b2434242b> 7665 4595 1 8895 0 s +<0314> 3177 4839 0 3394 -1 s +<2434242b> 3398 4839 0 3762 -1 s +<000c002e250032272400171a130019> 3762 4839 5 5066 0 s +<24252430242d222400152e23242b04000e181307001b27283100282d322430252022240022202d> 5058 4839 5 8640 0 s +<002124> 8640 4839 1 8895 0 s +<33312423> 3177 5084 0 3595 -1 s +<00282d00222e2d29332d2232282e2d0035283227002c202d3700232825252430242d32003230202d312f2e3032002f302e322e222e2b310500282d> 3595 5084 8 8825 0 s +<39> 8825 5084 0 8895 -1 s +<222b3323282d26> 3177 5329 0 3837 -1 s +<001b1018> 3837 5329 1 4305 0 s +<0500202d230032272400171a13001b> 4270 5329 4 5662 0 s +<30202d312f2e30323100031b1809003227302e332627001b180c040700172532242d> 5635 5329 4 8895 0 s +<252e332d23> 3177 5574 0 3711 -1 s +<00282d001a323024202c3100282c2f2b242c242d322032282e2d3107> 3711 5574 3 6348 0 s +<1e1b13> 1589 5921 0 1972 -1 s +<1e08172f242d> 3177 5921 0 3907 -1 s +<001b> 3907 5921 1 4097 0 s +<30202d312f2e303200132d3224302520222407001b2728310028310020001b1413062b282a24000334243037001b1413062b282a24> 4070 5921 7 8895 0 s +<20223233202b2b3704> 3177 6165 0 3957 -1 s +<001b> 3957 6165 1 4178 0 s +<30202d312f2e3032002b2434242b000e181307001b272400232425282d2832282e2d002e25001e1b13002831002c20282d> 4151 6165 8 8825 0 s +<39> 8825 6165 0 8895 -1 s +<3220282d2423> 3177 6410 0 3746 -1 s +<002137001e08172f242d07> 3746 6410 2 4843 0 s +<1318> 1589 6757 0 1798 -1 s +wst:dutch12b SF +<08> 3177 6757 0 3259 -1 s +wst:dutch12 SF +<2d3224302d2432> 3259 6757 0 3920 -1 s +<00> 3920 6757 1 3953 0 s +wst:dutch12b SF +<0a> 3953 6757 0 4085 -1 s +wst:dutch12 SF +<302e322e222e2b07001b272831002f302e322e222e2b00283100322724001f1f262b332402002124323524242d001b1018081c1118> 4081 6757 7 8895 0 s +<202d23> 3177 7002 0 3514 -1 s +<003227240014282d2a0614> 3514 7002 2 4607 0 s +<2434242b07001332002f302e342823243100322724003124303428222431002e2500302e3332282d2600202d23002f20222a> 4611 7002 8 8825 0 s +<39> 8825 7002 0 8895 -1 s +<2432> 3177 7247 0 3351 -1 s +<003124262c242d322032282e2d00202d23003024203131242c212b3700322e0024362f2e30320032272400282b2b3331282e2d002e2500200031282d262b24> 3351 7247 10 8895 0 s +<272e2c2e26242d2e3331> 3177 7492 0 4336 -1 s +<002d2432352e302a00322e0032272400272826272430002f302e322e222e2b3107> 4336 7492 5 7294 0 s +GR +eop +%%PageTrailer +%%PageResources: font Helvetica +%%PageProcessColors: Black +%%PageCustomColors: +%%Page: (33) 33 +%%PageResources: (atend) +%%PageProcessColors: (atend) +%%PageCustomColors: (atend) +%%BeginPageSetup +bop +%Defining font PSOwstdutch +%!FontType1-1.0: PSOwstdutch +10 dict begin +/FontName /PSOwstdutch def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001000 0 0 0.001000 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 1 /C0032 put +dup 2 /C0033 put +dup 3 /C0044 put +dup 4 /C0045 put +dup 5 /C0046 put +dup 6 /C0051 put +dup 7 /C0058 put +dup 8 /C0065 put +dup 9 /C0066 put +dup 10 /C0070 put +dup 11 /C0073 put +dup 12 /C0076 put +dup 13 /C0077 put +dup 14 /C0078 put +dup 15 /C0080 put +dup 16 /C0082 put +dup 17 /C0084 put +dup 18 /C0085 put +dup 19 /C0087 put +dup 20 /C0097 put +dup 21 /C0098 put +dup 22 /C0099 put +dup 23 /C0100 put +dup 24 /C0101 put +dup 25 /C0102 put +dup 26 /C0103 put +dup 27 /C0104 put +dup 28 /C0105 put +dup 29 /C0107 put +dup 30 /C0108 put +dup 31 /C0109 put +dup 32 /C0110 put +dup 33 /C0111 put +dup 34 /C0112 put +dup 35 /C0114 put +dup 36 /C0115 put +dup 37 /C0116 put +dup 38 /C0117 put +dup 39 /C0118 put +dup 40 /C0119 put +dup 41 /C0121 put +readonly def +/FontBBox [-25 -238 978 722] readonly def +currentdict end +currentfile eexec +D9D66F633B846A989B9974B0179FC6CC445BC7C8A959A39A32E9DCE7FAEF17EE3BEC9F +50E1A6FCA651FC4B3769A0A91041557502E25A5D6180FE25A3D11BF079E1DF66E54EE9B7C229AF891739707A2A0EC140306B5E43E52B79BFB89E459E50 +6EC6F610A70775A31C460976C4F79449D86E57ACE491E5C6BF20CC4307B1DAF7630252 +E9AF8CFB69B50EDAE9D36A6104AFEF8832F920FD2346B2C7104CD11E3BEE999CFA9F5A +49DB3173EE48D1C82994237F360407B022E0B4 +502E94EA8B493651EF2D03F0B513D655047568325B512AE6 +6AC6F53F3848CF70DE25481CC65D8B1A5793AA +3C4282D111112BEE28AFCA7A3808D4444C4669CA +84EAAAF989219F51AB3476A1B0B5F2246BC306E6 +625C6679C417ED2A8E9BD010DE37D40265074C268420EA157C62583FAA018F369F10C267E5A689 +14B3CF05D7E3E7301A1D113C +B87969B0B7A33DFDE5 +61041C8A +79E0C55F00F30185782D9B5C02 +540547A3473460ABFFA0E495F53E7584BF4DD5BFCFF260A149BC1644FF5736DF562588F2A791747A0B4FEAA38E7C4D6A2179B1324CA331C3A1DA1841FFDFAF1C9C77B2C236 +51AF2134 +C26D9F515482584653E3D2772F +46B84E9031A9CC791F2E91337D622AAC657612E451E5E44D6EA140E8709732DE64357AB97F38BB27AC2ACB5C2751A030EEF06CCF2B99C5551D +A55ED9C1 +F70AF4F9FEFA44E2B6394B8BD9 +364298FE11022982702C831136924FD659F12F86D0E94D +4234054D +2E833FF15FD994D037911F9592 +B816C726DAC7A8548982824253A4C3385022D702E6C5B77E21D5E47724A9B2 +22867483 +B0C20463AF12BD72F6AF00B028B9 +FEF09C60C4E0993F1B777DBDE12E2103A76F3E40944EB67DD1E3F09BE8377387788C9B4CC9E69446334251EE0BB9CC37CCC4023E9A680E5EED18A3EEA7B58DDA41B1E96A807F30313B56802FBAC427DF4D0A70620313BF488A4B02E1846B433EA76A5E573FA43FACCAD463A913979C +052C169C +7F5943E52ED20BF16D684EC5E7 +511AECA56B362A903CDC23C5C2D74EA9039EB35B16D24FFF402C16C2478EC3821F95B664AB1C81D5DEE963F652385B81DF77866201F4 +2CB0E6B6 +14ED6654BADACB8E79C50DF812D8 +CF9F07F4E931E27D104A9DCF92BB3AA27A9E4BE29D795C4154E8987CEC0FE5A65FD171A60DC12512FB267ACD6707BED422779B2DA97CA8667974EFABB4C25F6A196883C1F9A8DDEDED1343012C2E971A1D2FE9AABEFBE58F94835B62AFDFB31DB354F205FC6FC28AA17B3D8DCEBC601FE837B2 +56E40B96 +CA82B7168414D54F88EFC1E93F0E +88DC65E58E51D9717CAA1C9F289A545A5047B06B679A79D4513AD9FE0A341FC765C8D13A99AAF91F7CBC1E503556B4615178E78CCE9A1262A0A4586677A73079D19FC5E51145DF7D80B11888C9DF3192401C2FE358AF2E281DA5F6EBBED2C689C722719F2A423733C1D8044A43BD9DEA1FD31F717098CB1A83684C958B91 +BF86 +D5 +4CBAC048 +BB4F6F59270EF29085373CB0F8C0 +88F35F2C1E3062071BC2E9D3E43311E010F55E5C48B2B1BA4131978F31795ABE5F1AB33A7E8FC3067C726497CC5CB3F412A0F3094A1242791E28E365A674AE7462C38C15D977499F2D7B73CD62388F7BF45BF7A64311D7C92778176D8AC6B154DB3197E110CDB94664 +D1F221D2 +8D0678C7B74E04AEA9E8EA1D48 +018A4D4D8CF0270573259439303C90FA49A1A73A839A1C1C4EA16BC32B88DDB9D0E91B7AFEC18A14B1500FE483E7608D411ED20169E38704E136F9 +E1CBE8C6 +A6F45246B8D662879D942B3C03 +C01091F26265C43020C7DFA30DA1DE62DC75F8678803994F729C9A84B0BF56AE9D6D29848220D202992E41422F9E744BFA6D229DDB44FBF5AADB9E02003A021B5E776D8B7BA93F +85B2C153 +CC1A2197065A6E56810A60BF304F +643C6EB786EBE97C8043BE396F58E909B7F9EDD4A9B2D91219F593200E18ECB1DB06FCB6D0604DC46764CF5E6767A8C5303CBF0DF2AA19B739D1FEA29D48508FCCED092AD223A9D1E83E4C54A88A415889C07F8506CA020459CDE3D0DB48B193B1274D5109D1790E15732963874382 +97297308 +206D5573E15211E7AC9FB5659A +F715D3083C8D0B4391A050949D435A66397F1D1E5767EAF49837C19EAE1949C6248D2B141962005BB9206C1D37EEA794434157FF71A21F0E6E16625FF32DB40C296D407F60B8C3F5950E821D7DD2EF5BE0C32A80F67660A802530C88 +78A08F44 +D46EBDD7F18D0B52700E59E6CC25 +7CB562199CA8D06AA3488B98817D0D5C34294153D673BD808CC89BF2BED30AE5BFB19F02386B21F6ECFE21D62C6A930F80513B06529B84CDE64875075E499EBEA776B99D150CFA6696C3D8F1DE3C9B05DEB7039E03963A999D84C380816A583E6396B48FB9F8C4B172BB +23223DEB +5BFEB4E6A9E1DF27EA05B7F9CAF7 +9D1D1A0591689B02AC7C782A33BB66AE349657F35E3A4E63F37F727610443A5AB6EDAC93FC920BE63600013F62CD1D40793625B5C07B423CC057537ABC804FFEC37F2CFE4AA5F090D13894BE8AD896A04A5715383D22D9BD6335F7EA99699DA06ADB4800CDAA37D3C71B86FA1E423AB0F272B4D911414B66D43C5782075E +C18D1439 +D02D71CFC4FFDAA9B7E7A25F06 +EE17DFDD635D2D77C6E190392A18DB777A2ED979E7AD8F6D9129824032AE05579F0AC4AAB7916B35293037D6023713A261333AEE952F6CE355A00D7036CC61E69B172A8F50776EA86626176039CD5A821E +8198F6F0 +681D5DFDFB9FE2FC88330E4DA561 +84BE96777997F67462AD43B5E17DF6C1709F3636DB4D3E87A6706237EF49FC60077A75712E22B6F2F83EDF472F0B3694E591EC7328D9A7C7A797D336066B4C2B4A3D8A61D17253C65348ED8E1543347C82748873E5E81FB64B7BFB98B838309F776AC861 +BFBC0C11 +2B6A4E788E2B35BFFDC22482BDFF +964A0D659D96F19A196A240F742B35698D76628D5873E59ADA0A3E26C624E0A4925BB5EF15743331A0EAAF2A1514D0C75237EA85430118790C0D11799E51F53EF06979CC9539B799D7D75790271AC7A7BB023D006CDD21D18196C94E400B5283A5216AAE2DE4109155634BCC1D152AFC6CD284384DCBB7876B403DA636F9 +FE20 +917BB81CE24581221004E5CB0622F3BE +EC6D856B +9DF8B262AD5D850B259DA7BAF325 +6EDDFCE543CEF0507D7DB8604280C508E5FD686952037C3CD55F5067326715108F67ECA91FE410935B58A305513C8EE231584DC6ED3A703F4228A3A07AEA5010753726DF90562903E5C659C6C1412DD136DAD1B5E2E74DE9E669A9DC48C162521AF667B9D17E298A571D99E9177962CF7FDC04FE03EAA6603D955E4BDB8C +50CB +8F3C2C +286C26C1 +34579C8953C3112ABD0ADA8E33 +534A2FD4F03786EDB18582D7BF2A3AE1AA391170B2AB0461D3590C78D900550612223DF9B71F8276C018C4A5FA2D8667B3FBC132D3CF319022EE8E25ACEBA2CF85558C7758D99A5045CA88FD05C65FAEB8551EF74B9C2611 +B27C9256 +648B62805B330088F415EDB95F +F9CEC0A5FDD0FD461B1D327EC9D411ED11C7F6F1D33066A387E756CB8DD65C36E24D4B365CD6A0249DA1620CC7EB8A8584DCC39A0DDF1DAD9B2FAB0DDF2278F79DFB47962DC5143D029C10DB53E717D57E49 +E8BB819C +E3A26DB3CD0109991582A7B6BF4F +EBD03132403827498D06031247C6F6EA880D865C4D21F50020F3E9E552D2EE5E676BAD9F832344B3DC45E9D15930FDAFDC7EF5FF013A20B3E5AF0FEFD80E138384F87F676B41AC42BC262911BF116DAD0626C84085610190901AE2AE211E8A5B4193B8719A23BED852F56F55EF59 +635C74A8 +E1C90C4648E0AECECA83DB5579 +1D218D0C19223C050B4E171F7B1DC985559B13A2843400AFB733AFA05D91459EFB1A9E07CA25C69D78329D343CF27BD509C7251C0EE8B59E46DEBE059574CFE1BCF40325C88947F7CA48371643D1749945572ADC6787EE7BBF +A47BA476 +A76019D466169ADC78016B4990 +CFB9B733CFA4FEF6463B2F037AC285F04DD4B1C4492D9262DDE87E70B123AD5FAEC35BA90FE9269CEAD8E33E8A656471E6BEDA5D18889371EE5552AA516C43A4461BFB5290AB84BF811C755425C40F18F83ACF4843B3E35EF15D61AE +0E5BC87A +597D150171778A9C0085444BA37F +8C8FDC0B3D52133617FE0D325507D36F04062E750228169DC0AD101B0232400DF73E4F9027279B97633789299870F04BE9BBC319B95E026CEACEF0D694C45D898EFBDEF654463496F152733623A6C3BA06CB94A03081697DB80FA7515AF43ACB76F59C4E4526CC9BC937C89E363ED3E2583636EDBC7CE095709FF02D9A92 +C3DA +7B75DABBF418860F980A293A60BED3A479A9311504BD9729EC11DFB138D5E1BD158EAF16E57B8287C7DD2434B64B47 +0E795E79 +4FF9DF629FF2C60675978A2E285A +CE63FCB01A10589E6C078B5447D44E94F063008D04F3F2B9BD87343581EAD29B78FBBED89EFACB506B284B6D33D77BE3D287AA3EA174C92A76A7D7BFFF03FDB8932B262FAE77AFADD5013E7BF1AEE32A4641FADD10FFFF2425A07D517D8E7B9132263CF91FDA41DF44581F1F9C +F52FECDA +543626093F0EBDA19444E9162A +946DFAAD3A6ECBB608FF9F476062053F5F913E6DDA5F1788314E01FC88FE6CE7115DCF503E3881B2E8AC32383C0450AE583D2E597E5553A6E0C46912C48D2137CA116AF66D7250404A3F85F1407A7138 +1517FF6E +8D54CC7696E11ECB756466B49E54 +0D79100A9C86049D3E682AF067940AC87E41340A3CAC432C6D5937A060B522AB359197D8D4D3E9AE2A44AFCD1EC437885714F85C91B98DA383B850CE45DBFC214CB58351699F06CD5E5A9E3399FF8883E24598483481D28F85514CE4984FCA99950687E674D22C820014948E6F0856D5E8100AF2AB99200F1C1840C76AB3 +384A +FB8D8385F3BDD91A5E00CF1D356F356C7B95D9B2A8FFD2E77254C97BD83B48CD36F1EF +E361A956 +7BB161C6226C54A0C5B1ADE33F +D14670C6FB7F7D7E03CA31CAAB87C97C1D1411A1DDDED0E69CB046EF5B6D0C97D488808B4932B6764FA9D5CF58F29353CCEBE4F69FEC +6F5A9C5A +9F20F4E116F20F4ABC947B713930 +C957C6326822A1C88003C07A95FC2BD314FA05F04BEFD248F275A75CD3B785A069603B9C7AD1D94726B29158AEE1AE91CA4CAE3911769C00BB76901EF696EFEECFD3EBBD1F26C9E837FD252D87EA07E8BFCD0D597AC49C87339DCD24CEDB93E45CF0B2F5CB1E912BCA8FD5EDF3CF218A898FEF6A8F30CBF9B866F0C5C78D +427D +1D7A3A2A56B24B79EA459C17CB1EBD27B81781833079245879883CBBB40FD0 +85AA1783 +7CC4E545648D420ED543EAB78BC9 +94D6BFFDA01FD799C69EDA389360FDDCF58B3D801DA5656187C5F38EB6711F151405FE8FCDEBA4EB82A6E1E9466F92BEAD93F4BC1514CDCFE95E1269CF4E3A61AF29CE2581915BAABDA1F853ED124DB6E33823C565E2B4DB4C58946D57109381ED64A6FB0E8887E61C66B008 +F78024C4 +93272497A4DF73520E692CD097 +005D15001F34226AE8107207E7CEE7D1B4B5944F18EBEF00DA8F340FA7E71FFC2A34E224F84970A88F96E334C5E467F01E2A09B430BA1A99126C4D67CD2A552AD9FB84BD3A04 +D2AD7F50 +823B531425355276106AC6E93CAE +2558AFA7010AEAF17EEE6692A7AD40C1E6E66537E20DBBDC916D2B730F5F375911B5055B8D9C58C50C3809D5449C47E4BA6C12EBFBAD29897874F26B42DD7B6760939CB56523850FFCA0830EB9FC78961FC9EDD6F11D37AC47609CB70C0C93363998D772FE5D415100ECE9B7DC91172DD3C55EBEE2CC8C +F8AB3AB7 +DFDDAB7F4C427DA263262BC8B0 +012694C34586F9FCDB8149F374B0277833A0183ADAAA2E771DC8BEAD79757482D118645032F5480319B64AB710A4644E35563A254614F3FFBC6095FD30FFEFD537610827622018584BED3C027080BA0B6E6F56935A4B5B +834AEB4D +AF91E5BD15CC4F7B52F6A808F1DD +37AAA08E50F394C75306915FB8D65D8AB1CB2E7C4831A92EA4FC74C9B64710EB998D2137B2F0E0EDC54DB6DC19CC53A2D87312C00F9636324D8C7217C910BE2ED0CDB28363E7EBE77355AB561405F2F0E6644BD01029E08C7795AE55C0A39AAB09A9819D2D35B780FD92EFD2F3B243316E1DB5331003C4AC82B29AC8 +2F54F66E +DAB2512881457545DBFF2FD101 +409F3089E6E5FA0A5069F2C7021A02C719F9A18FD0826AB46CBFC53EEBE86DEDA0123EE06BC7EC45EF5D3B62BAF7290D9FFD426522ED8C2138F5C5D7F4A8A624BF5B8BD08E +E2A610E8 +8CFD2504114D6B4B870C2CCBC0 +94031C71AAD48A8BF29C7D933FB9A8A2B14F2A017158FF93C1176BD8309D13642AD206E9CB25ED44B7D14030942A76580990EAE12E4B31C8C27A5832083E109AE41F8831334DB7FDF95FE35B2E44E2ED4B20DF8F46273CFA65FF3ADB9213867AD4DA +CAA244B7 +E708565405511BB52732BE0179 +DEBACAC5D8D2B656BAFDC3EFC6A613794AD761A48F9D1F257B1BD574BFEE3AB9624D3A557919CD00CB292D57450F63694FAF03CA358B802CB0BBF262DFF28C8CF2EDE708FF32EDCD4A8F65B90B8F5CDB233F60DD6C918D5F4A +5659E082 +D0A56AEE70978C31CA091A0D3251 +BA7D3E82827E2FF9509F23C4B7EB1C16C45CD37A905DECD8606FC39B31788F5151BFA1BEC8A3C6F754BE9D0710913E6B872156574A8FEF27D2528D9BE1C934AB7CD9ADBF3344DB7D99B45E2834247ECBD51A147DF49352B417FB7C15619177EB3AF4E4C61AE2969ED20060447B77691DE1D1482691AD91F4461AF66B6B71 +F7FC +33B7DF41307909F61583D6FE2950 +1F929292 +D1813E959C13097D4987053D9F36 +2D8D2513EEB18960489E03248E58F5E21031228BAB2290721853DA9EFC461BC24CE62148365BAABC3600E4CF4DCFBC390A72F59FB8AB8F2E9ADF4B3EE698541305FEE70FF7E6DE5C2C9E6519A25DEB2C1CE152E48F8B4AC45A393A16FC31C19C6A2E616EF1DB471DDD050BD977916D2252C40BF720E60B583856DFD90B1A +9879 +35747A40 +9420AB13D9305AB7E095C99D2E5C +078B519928E8FF49 +789E161F +F4D4131232F5F7B5E581868AE0F53D55FB575B9D5BBB841904C4941B841036F5302E +DECFA2686832A233C654ED2F7D1689B279D54303FFCC1DAB4930688FA953D63AD9D05B9A3AC6 +05E6EAB6CCE2BE155338EEDC8BCA76FE454A4CC0D3DC9F3EE56C24 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +%Defining font PSOwstdutchb +%!FontType1-1.0: PSOwstdutchb +10 dict begin +/FontName /PSOwstdutchb def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001000 0 0 0.001000 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 1 /C0032 put +dup 2 /C0046 put +dup 3 /C0047 put +dup 4 /C0049 put +dup 5 /C0051 put +dup 6 /C0058 put +dup 7 /C0068 put +dup 8 /C0078 put +dup 9 /C0080 put +dup 10 /C0083 put +dup 11 /C0084 put +dup 12 /C0097 put +dup 13 /C0098 put +dup 14 /C0099 put +dup 15 /C0101 put +dup 16 /C0102 put +dup 17 /C0103 put +dup 18 /C0104 put +dup 19 /C0105 put +dup 20 /C0108 put +dup 21 /C0109 put +dup 22 /C0110 put +dup 23 /C0111 put +dup 24 /C0112 put +dup 25 /C0114 put +dup 26 /C0115 put +dup 27 /C0116 put +dup 28 /C0117 put +dup 29 /C0119 put +readonly def +/FontBBox [-18 -209 798 694] readonly def +currentdict end +currentfile eexec +D9D66F633B846A989B9974B0179FC6CC445BC7C8A959A39A32E9DCE7FAEF17EE3BEC9F +50E1A6FCA651FC4B3769A0A91041557502E25A5D6180FE25A3D11BF079E1DF66E54EE9B7C229AF891739707A2A0EC140306B5E43E52B79BFB89E459E50 +6EC6F610A70775A31C460976C4F79449D86E57ACE491E5C6BF20CC4307B1DAF7630252 +E9AF8CFB69B50EDAE9D36A6104AFEF8832F920FD2346B2C7104CD11E3BEE999CFA9F5A +49DB3173EE48D1C82994237F360407B022E0B4 +502E94EA8B493651EF2D03F0B513D655047568325B512AE6 +6AC6F53F3848CF70DE25481CC65D8B1A5793AA +3C4282D111112BEE28AFCA7A3808D4444C4669CA +84EAAAF989219F51AB3476A1B0B5F2246BC306E6 +625C6679C417ED2A8E9BD010DE37D40265074C2684274DF5CA2235B505452EF82C19378A786E0B +30288B05492EE4BB6123C04C +3FB31E3DA5151DECA4 +238032FA +D2FA7FB1824D5B65B72B33E7D9 +023B3B8C45A9D80B2FB65F9BEEA3CF7435B74F2AA261EE7A8B8E6CAF4F16A3 +77D2B03D +67DB68A103559B8E347FF6243E +9B38814FEEBEF65BD5D0B4C9119755511780E62A6B7CE2E4F529 +164F4646 +924961305B9F5B817BE7668528 +DB216195DCBA07F1FA0F4B764DC9A734C83AD0A50FAEA9E002E44159FA086816114E50D6C4F6E3A23943DE14922257ECD64140D2D45C90DEE714A268 +75545F83 +BB37AF98FACD8D037A456D189245 +F75ABB8B707AD5E1FECB4A3A89FBFBC2BC910909639C3A9E6700F23CE30C872B41AE11666A7B111466314CC518994552BF9C52A9F387D7FDFAE381679A6D46DDA147639A5A0E49239338A45B9212FA1FF6CBFC7DB9E352725D4768099900EA31A5DB8CFB394C9BEE7B7DEDBF14A438A05DB0A0 +59D93BC8 +5B454C3F909E4E292505647551 +9E20504792492C276D9014162A50FBFCAF7F9FE5F54FBEFF8A0CD68FC04A18C63731EA300E0C4AA6B72F53807286BADCE255582CFDEA +BA0B11B7 +A2E08530EB41C56AEC543B7320 +DE2F49D8EA8435B2C18CC73A48F900E502CEFB76E9EF834B3F570D1462588E9838967B20612BF0022CAD79C2217DBE736AC5B22F1FA87A7998E26BEBD77E1C9829E69520346E80571E30021DD6430C96F7F5E5125C8DCD +32BB9A12 +E1461466E85511E5528CCA877F +264F9CD0043BF1E02C4BF6EA550B8F547DDF9464125F5DE8DA5759348F60D4C1C9AD924657E27515F1C2365DD0CEE1CB04023F1DDE106DBB0C7ECB4424B829DAD58D71FCD3FE76E354A64074C9FA61523B15B2E44BE64AA94D684D0DE520EE +7AFCB084 +E2F1A2F70DA8FF55D03A801263DB +7DC7EBCD70304E7B96CC5E70B9BA6266787AA1AE992F14D65D0357CF4CDA8D71102B35AD35F408B1DD888DBB7B927089306FB8689BF06B30A92E9B6C1CC15DC5935BC1C0F726CA6816F12E17ED21FF17F678E236DA85FAEBA121524796DD420ED0BF50D0 +28313989 +0C3357D6C36ACA14DBF47C119297 +6B4797ABF6BFC0C62D674E01418FB5CCCCC50CA4FD6B4AA9B86589776451A5FAFD04A905DF7ECCAC94FAAF4B839CA0429B3DDDBB4E4159A94C7DD832112CD6C3F75B909764CD4AB278C22DC7828541CCDA05935F5B317977E1F0C77FAC09D616D028927B2FC08C0AF0F6D62F8E550281DE744B16C47DFC29E8F9CA032FB8 +BBBB +FC0CE380 +D55EDCE440FB9933492B51619B +1001652719CE363AD0D3F29BB81B41EE3C49A122356632A3A3ABBAF6F014CC602979DCDD6F6671A6AA0C348E18A4DA892FD429DBF1E9537C4E3ADAC4C48490CF7F6BEFC56E98200CAA +F84CFB3C +326DF1128D798E25BE9CEC7E5041 +89315DE04BADAC0D43DC63F0ED98DC943E1A90407B096D82AA8484BD843451115CAB601B4128892E60A49094CE50D0F24126DEA26B0C38EC4BE1CC447DA8A0F840363B6287F5351F8DB5DFE290020FF4A1C4AC3D85BF1F5CB55382C7F840A6BDBA6562CA859DAE5326F066BF278464F52568C83A4C43E4FF55F73CA7AF72 +75E4 +0414990C +6FE74CC3 +86B83C1B5988125BD6E9C8821D +945DAED767D0F5B25D892AA31DDA997BF29D4327540DDD500D72922DBA76200DC4E5FD8326E8257F71DD1EAC3F622E934795FC7466EBA646EA6C99C660A70396517D0018F1D60C6C61CB53A28F34B2A0D664BAF3DF1995E2DBDC12DDFF44 +CD9A88E4 +46B19AFC5A7B91322983697425 +E75CD601FF5F6F12FD6CF9D903DFBFCE98DFD6D89F2AC4BF087A2409588DFF74396CF533983FAAC04EC07B08F24A316E1077B33CA1ED1C7523775DAC498C0044BA864495C721FE0C7B585C44FF512B98BA58 +AE1568D0 +CFF6EA9A2111341B8E01E76B80 +E3B89A016C7593B1547C16989CCEE749A3BC300D8C3E4E7017189EC09DFEB963FCF95915F48D73F7784F50A55C5045EF8BD458E1B3B11CF7E3987E670521E8DAF19A5461C22054AB9133F0135906697AA3DD5D5DFC63BFCDC1A1D6DF +9D9DCF56 +1D38334301972077EF5DFDB1DA +E428DEA1BE5C34E41B66D326B7D190BEAB2D76EDF8305720ACBC2432B183CA38183AE58698BE181867DAF34F1EEA6FF84E9FA9DE120E85C313ED370F79834346BC9F9B0ED8223FBF140B5F4B70D71B332C26BB428F08E8AD57B77D297A +1D28E7FC +39212852D72A036E923F19B70A1E +36D8E39C73F6A94EBA98039F65EC912E15D476982A99E01F7CA1BF17861F9CAF12B955A87EC71C69C9EC18B7CE95D5A714D99C40E85C982FF8A13467BE271C98F08B39700394FDA71FE64327F04326426075BF5EA44A039F012AD14A31CDAE6DEDC4A0E05F53964A32F078114F03711AF87BAC31455AA43E25403FD9FC0E +A486 +8CDFFF981B8EAA893C59D2E46C833626A9C21CEEA1D5266415261D35FF70039C4C4A0BFA57 +070E3194 +BABE4282DAFAEDCF044FAE60D6FC +05A0F71CB2012074F137D79A5A403224362FB405B153F32A3B10918191410D4E9D13CCD86A73EEC7E3765DD5FE097DC7D2C8B84D82CD96989C4F27F46C421160261ABF629F52F1D65C6B9A46951B418DC26CD2ADA731804ECB7031ED489275D222C0A9FF7BC0021B +C6263CC2 +23B0860070128B27923107DA23 +2FE1FB9290A56C8E33F0E4F35AE9928D94DB168BA78CAE14913FC57340892079E664296010BA97E658EEF778DBC33CA2CCA1719A37433DE67D8543987AE803B8372FF3CE9F94B8BB400EFFB3A461 +DC11B0C0 +1C3907741D6DC400E76A9B977F +81A7EC2150127925BCCDBF9AEA4C6C4193DA0FBE8F15DC829CE756CC2A94FE8B3AA1DF579D295556775DB4B5A3614A597138B12A +C1703C6C +1960527471A573AF901E58A242CD +10719D1C8A08199DF5F3DAB1D90F81F93E695AC0B274FA9A306E24B0AF8D7DB14F91F0868E43D9F97221C38472DC1B9EF4C803B2325CBD9987AA339FB3F50E93926125935B61A6AB6B92D9AC937D86E04E35FFF13BB058EBF291EAB1364413630022E1D08B702CA0CC0FB8552DD8F6746DDFC7DD022801E7973A44232181 +0B50 +D510FE461BE6C132853F4E0C556B2B2A1A0152CDF06F15C221363B0B +7EFD84CC +B3306B4E68E7B941EDD1CAAB514D +DC66C696C003EC458953A2FE4724EA003C61FD8B4384ECD47895158920B6A80B26FCF9B8BDDDA399C021D6C5236362D426B69FF63A85D44A9E86C298E70D6C5C896B36C99E12CB79C848EBBE2E922DCE4C9B6938B2997E87BEB9D4768EF30E4249F9FB045BF188 +E9560F2B +3987E5011AC8C42758FF018B97 +90210993F8A36EAB659D641BBAE52F708A61D120D877B06626FF3C8D9586A3152EC860F1EC1F7415930085DEFD4E597FEE671BE1AE4FEAFC075DCC3914262BD9F0D61D7C729D +FAC09EBB +3887E425C082FC2BA387D69EEA4B +6603E088D031DA7CC72BCED6C972EEF3DA1682E0EB2F56762F3285CD64AE03EF79AB23D75E070529C0614529AFB5CC83CB9F225F2126FDBD8BDBB948AB7AA92B84E30AF372080B0F8D0A6D460CA5F02FB4A2864A23218E6472753832C06171F761CD86ABEE87A768F1FB4287A956A23235 +1CDF74C3 +2232EB6C341754BC09F74E474F +B917184AED2DC4F37247F4D68850568B3CAA8C60211B50D496DB2C538AB5DE8E8AAC8BD63DBE13305A87F0D6B39D74504704EA21BEF07C02EBA5CD70E91DC6DCA895F71F42D4640B05CB9BDD8C2013A2F94443AAD0DBF0D0A2 +242032C7 +CA91C5B3EE90B4B9CF4C8FC2B871 +9A92261A44A80C34BD76CC2890A32A086AF8DBB7862C43692D4DEE77A29CF235861EC7D76F13AFF6934EFEC18A6BB2E9D3955040843EC6B4EF327EA0A9AB3620ECCFBDFD913D6ECFADB5D116D8CB87D66269B54686C7DE9F9C9B3FC5F379BA79EF4FFA68DA60AAB6C7A05F413A8E10963C28892B862118D324 +474B1FBD +86E1DF7A8674F100F1F4F8A5E5 +3DF6E447083F5DCB85571D166E7C7FF081FAC028C606F148A0FEE2D77CA77C50C725B24EC8B06013B0FD14D4F29BF294950E587631D1178064A785B9980EFFBC4C966B27 +C65CF951 +8F63580B6B443015E59393688B +1DDB7F1F3481F3D5E4AB05762389E489213F841F0F4CF94E72993497B31D645518F629E2502919C25538AB3965D2D3089EA20F200839C0F3ED69BE0FDFA15C6B23F3B60B67D402182D06B47001A2F588122B4A02CF575646BD63B0 +0B60ABEB +8E37CC8B2A93ABC3A69B527506CA +0C9A886431167A8D4782E5C5BD85747D5955C2A5618E2AAD495299099E8B8BF7D28B99084D78FBA6EDC24D5790860651D85970C6C3214E13F3CB8F1846F82440F3818508FFAE304139EC82B9925481AA2F7BFABBEBEDA0960CAFE6849321AE682F9360D71BE051A808006EB3D865FB5088CACFD8A48A9DE4579FC8A547C3 +C8CB +A9A9B788974DF36248D731 +FC4E60E5 +D6909A124AD06BF7579B2894CBDA +32FF2B7032BFB3A7 +F8DF4B56 +6FE81227FD67E677209FB25289BDD03A760CFC3C924CBF80C03C1C9B2FC53DB65AF1 +E843C3B7FDB28D71A453CA5D2055320F27D84A178073CADC12D4056FBB7405B6C9C87FAF96DE +C83CE268A6EC5F00FDB188E1BEFB5107F236A52C1AEE59ABC9B479 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +%Defining font PSOsymclas +%!FontType1-1.0: PSOsymclas +10 dict begin +/FontName /PSOsymclas def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001000 0 0 0.001000 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 1 /C0069 put +readonly def +/FontBBox [106 45 775 713] readonly def +currentdict end +currentfile eexec +D9D66F633B846A989B9974B0179FC6CC445BC7C8A959A39A32E9DCE7FAEF17EE3BEC9F +50E1A6FCA651FC4B3769A0A91041557502E25A5D6180FE25A3D11BF079E1DF66E54EE9B7C229AF891739707A2A0EC140306B5E43E52B79BFB89E459E50 +6EC6F610A70775A31C460976C4F79449D86E57ACE491E5C6BF20CC4307B1DAF7630252 +E9AF8CFB69B50EDAE9D36A6104AFEF8832F920FD2346B2C7104CD11E3BEE999CFA9F5A +49DB3173EE48D1C82994237F360407B022E0B4 +502E94EA8B493651EF2D03F0B513D655047568325B512AE6 +6AC6F53F3848CF70DE25481CC65D8B1A5793AA +3C4282D111112BEE28AFCA7A3808D4444C4669CA +84EAAAF989219F51AB3476A1B0B5F2246BC306E6 +625C6679C417ED2A8E9BD010DE37D40265074C2684268F16195489648993B9C4D3B534FA887C +DEF605FA87B991F4D20A8F78DACE +5A54C070E03D5C59D9D2D3E06B09CEE028D68B62AB3AEC43C1DD20BA70D288597D9BD8E06818FF764EBAB436723988E8D7CA59E16D39032516BFC5D552ACDEEC6BE938BEF2F43CFFBC811C3626C4DF5F8CF080676520B51C60CEDAD1FE6C92D1431C702174CE517A8FA9377D075A0B6833DAB101DB65397F1419EF5F0016 +004F +6F0824F9657BB4F1C8F981709956865F6855EFAE +9242AD55 +91BBBEE163D844DDA894E13190C9 +2480439E4C71CADA +BD043A9B +A315CAF72652AA7FE6DB2E84D82A6111CE4DE90C02DA0AFFE2620922262A45AB4ED0 +EEC9F4520DD12703442F7D028D4526BD8B771E09FBE11B2749E2D3906894E8D4BFD3F379F14C +3C874F550606965E22FE487B247B5C2D06728490C8F2A3B588CDFC +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +/DPIx 1270 def /DPIy 1270 def +72 DPIx div 72 DPIy div neg scale +0 -13970 translate +1.00 1.00 scale +/wst:dutch12 12.00 /PSOwstdutch newFont def +/wst:dutch12b 12.00 /PSOwstdutchb newFont def +/wst:dutch14b 14.00 /PSOwstdutchb newFont def +/wst:dutch10 10.00 /PSOwstdutch newFont def +/wst:dutch14 14.00 /PSOwstdutch newFont def +%%IncludeResource: font Helvetica +/wst:helvps10 10.00 /Helvetica /wst:helvps ILEncoding 0 declareNFont def +/sym:clas10 10.00 /PSOsymclas newFont def +%%EndPageSetup +GS +0 13978 10801 13978 10801 0 0 0 clp +wst:dutch14 SF +0.00 0.00 0.00 1.00 setcmykcolor +<0e18252218231907010801091820161b1f14231d01192123010d18142426231c201a010e18252821231d010f> 2207 558 0 7384 -1 s +<18231921231f14201618> 7375 558 0 8593 -1 s +wst:dutch10 SF +<0606> 9346 13385 0 9522 -1 s +wst:helvps10 SF +<4e6574706572663a> 1322 13267 0 1949 -1 s +<205265766973696f6e20322e313b20436f7079726967687420> 1949 13267 4 3868 32 s +sym:clas10 SF +<01> 3868 13267 0 4019 -1 s +wst:helvps10 SF +<2031393933b131393935204865776c657474b15061636b61726420436f6d70616e79> 4019 13267 3 7133 32 s +wst:dutch14b SF +<0a0f0e1b131716> 1271 1458 0 2055 -1 s +<00040502000b120f00080f1b180f191000070c1b0c0d0c1a0f> 2055 1458 4 4824 0 s +wst:dutch12 SF +<0820> 1271 2086 0 1550 -1 s +<0021201e1c2018001714251415142418002119002018252218231900231824261e2524001c24001427141c1e14151e180025210014202921201800281c251b> 1550 2086 10 7203 0 s +<0014001921231f240416142214151e1800131313> 7203 2086 3 9531 0 s +<15232128241823> 1271 2330 0 1991 -1 s +<001420170014161618242400252100251b18000b202518232018250500111b180012100c0025210019211e1e2128001c2407> 1991 2330 10 6462 0 s +wst:dutch12b SF +<121b1b180603031d1d1d> 1398 2677 0 2362 -1 s +<020e1c18021218020e171503160f1b180f191003080f1b180f191009> 2345 2677 0 5039 -1 s +<0c110f02121b1514> 5031 2677 0 5821 -1 s +wst:dutch12 SF +<0a> 1271 3024 0 1402 -1 s +<23211f> 1394 3024 0 1765 -1 s +<00251b18231800292126001614200024181423161b0021230015232128241800251b1800171425141514241803> 1765 3024 8 5801 0 s +<002123001518252518230024251c1e1e03002426151f1c250020261f151823240200111b18231800142318> 5801 3024 7 9531 0 s +<1417171c251c2120141e> 1271 3268 0 2188 -1 s +<001e1c201d2400281b1c161b00281c1e1e00141e1e21280029212600252100172128201e211417001621221c182400211900251b1800151820161b1f14231d00212300191c20170021251b1823> 2188 3268 14 9531 0 s +<24212623161824> 1271 3513 0 1944 -1 s +<002119002018252821231d002218231921231f14201618001c201921231f14251c212005> 1944 3513 4 5376 0 s +GR +eop +%%PageTrailer +%%PageResources: font Helvetica +%%PageProcessColors: Black +%%PageCustomColors: +%%Page: (34) 34 +%%PageResources: (atend) +%%PageProcessColors: (atend) +%%PageCustomColors: (atend) +%%BeginPageSetup +bop +%Defining font PSOwstdutch +%!FontType1-1.0: PSOwstdutch +10 dict begin +/FontName /PSOwstdutch def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001000 0 0 0.001000 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 1 /C0032 put +dup 2 /C0044 put +dup 3 /C0045 put +dup 4 /C0046 put +dup 5 /C0049 put +dup 6 /C0050 put +dup 7 /C0051 put +dup 8 /C0052 put +dup 9 /C0058 put +dup 10 /C0065 put +dup 11 /C0066 put +dup 12 /C0068 put +dup 13 /C0070 put +dup 14 /C0072 put +dup 15 /C0073 put +dup 16 /C0076 put +dup 17 /C0077 put +dup 18 /C0078 put +dup 19 /C0080 put +dup 20 /C0083 put +dup 21 /C0084 put +dup 22 /C0085 put +dup 23 /C0097 put +dup 24 /C0098 put +dup 25 /C0099 put +dup 26 /C0100 put +dup 27 /C0101 put +dup 28 /C0102 put +dup 29 /C0103 put +dup 30 /C0104 put +dup 31 /C0105 put +dup 32 /C0107 put +dup 33 /C0108 put +dup 34 /C0109 put +dup 35 /C0110 put +dup 36 /C0111 put +dup 37 /C0112 put +dup 38 /C0114 put +dup 39 /C0115 put +dup 40 /C0116 put +dup 41 /C0117 put +dup 42 /C0118 put +dup 43 /C0119 put +dup 44 /C0120 put +dup 45 /C0121 put +dup 46 /C0262 put +readonly def +/FontBBox [-25 -238 920 722] readonly def +currentdict end +currentfile eexec +D9D66F633B846A989B9974B0179FC6CC445BC7C8A959A39A32E9DCE7FAEF17EE3BEC9F +50E1A6FCA651FC4B3769A0A91041557502E25A5D6180FE25A3D11BF079E1DF66E54EE9B7C229AF891739707A2A0EC140306B5E43E52B79BFB89E459E50 +6EC6F610A70775A31C460976C4F79449D86E57ACE491E5C6BF20CC4307B1DAF7630252 +E9AF8CFB69B50EDAE9D36A6104AFEF8832F920FD2346B2C7104CD11E3BEE999CFA9F5A +49DB3173EE48D1C82994237F360407B022E0B4 +502E94EA8B493651EF2D03F0B513D655047568325B512AE6 +6AC6F53F3848CF70DE25481CC65D8B1A5793AA +3C4282D111112BEE28AFCA7A3808D4444C4669CA +84EAAAF989219F51AB3476A1B0B5F2246BC306E6 +625C6679C417ED2A8E9BD010DE37D40265074C268420EF1DF4B83663DE01034AA39E98F862619B +68CD13F14451A96BA472830F +DBEF494BE4CB5E803F +DB46FE8B +CE31C8CFD69C06B48875D86D9F +7C1E986C904A8C416558A61886C547F5FE9923178C5CBCBF307D6D475FF14B13A085EBB779643F8E1CFD299FF3D9B1DECE5A29D2794CA285AE +033AC9F7 +42A71947D91EE74C0FA560A1C2 +900D93C7248959F70CC0A8C8656E28BFF8EDF77498E6F7 +27F2F99C +318CF461A3751662D323FB557C +BC51ED00E73BBD40CB5E0D728A2C80BF0007F3E3629C1437A659F851F6DBFE +182F8EA5 +3885E2BEE87D40B99682F6530C +501595FE3FEB27D1664A603789B519FF00173467276799F6C8F1BAAF042126F44B7773F42ADEBBC70E996CDC33EC0669D0FDD16697E0CAA7B44640C6135AD3 +7D155F49 +BD4D9BDEE9050FA1BB5E02D7DC +4613C87A1805295626DAF6F3FE8142B150DBD9B4748EC0B7CA60C6C898AD231FE5C9B7483BF5131480E9870A6EAAF54F8320115B0BD7CF5325BD9B6C20DCF2657386A0C41BC53B602372E574F3859C2D8F32AC2568D03A977974 +B7785F85 +6261DCE1E2382930C1BA062ED102 +7C7D902A8076DFD1999BB2EE7C6521C3D84728EB9CF4B5E24DE677F51110F82CBEE9C46EEC71BF1D9EF5E5F0CDD41E06E72D0BD985AB04D19AAA397F60D1B64E3418F252DB08A3B52D0DC4D7C1813338B7B88752E49C556B9912C2A3DBA0C8EE529AE5BA51306AE91982DE89101D02 +1745D4F9 +452D20A6C08FFC42F5DC950822 +00446434AAFF0CC7A7135FBF026DB0554DA88F9366FF26EDD04BFF9D622A4DA425A2E0CA836477CBF104B8B46B12ADF942B16630EC4B9E28E660 +D52495B2 +BE49C059A4C539A7DA6D77D612 +4D75B84C456613D410B6B49DAB219B662AB9CC2A545CC5BC2A7900DD6A8D9FC7FB868ED9F65636A2C1018E5ED573B3475086C9D13B11 +2CD6D71C +04C3094855F7742E77E9D8E6EB5E +A71F7208005C68DED641AD4ECBAF7CA7CDC7D2A2606191B6D667E7D4D4BBE6F3030F281EED8DD8D06ADD5F3C3AB85AE8E73E0CA904CFC5AD72F06D32D5FFD79AA7625FD776315B81B757D0D6087BF6BD0E75A3A4345F7E0E5A55B3BA2FD955F349D4E155FC5A5D7F429F368E4B44FF117F1D40 +6549E027 +F8AF40E4798784086CFD36B48D49 +E89F0F8BA45FC72803119295284BE0B2CC2E17277F3E2FFF8D2CD1A367D9775155168E435E202ED8FD6B7D03A8B4C2BD14F27314AD72A7CB6FED88D0B8E1F465A92D6AB1C611E9D817763AD261C7AA9A1FE1C5CE24524A269A57893D0AF16D0C330368C5A87FEFD29CAA4AB3F3CFC95F9DB187B660A98F08C147B74ADDB8 +126E +6B +D7534BEB +77807E222163C6511D992E5164 +53EC5F7B8A11E9ECB297674BBDC39176B1C2472F626FBA3AC2D6ED29B0D4A84FB8277E46F3436A46097F23CF9C019F06CFC9839D3D2C2515312BA9262CA2614F26FE529F76959C4B12EEC4BAB89E46910B2BAAA2FBC6638E60AEEDA352F4760BA31133 +2AD06CA4 +428D3E32BE2F020E491B35BA7E1B +6B3DEDD19A038AE6FDEB205EA0940F2FE8EDBE47337EB1D34D597FDF821EB57B65F9CB7AAEC23EB4338E2EDFCD333E4CBADAD0BFEFEFCCB4601F9C425ED88DF9CFB0813E8B1CEDA0DF4AA67134FB07B779ADE1E37345FDE45C00C351E85B02581A7D8ACEFDD26E69DD +6F079733 +3323F99A5E025988BF82D6285646 +AFB0D1631F2998222FBD0DFE355492D919AECAD178AB7EE4F698B7C88FAC4CE781D1D30294B0999E19CEEA0A6B32D38C3A1A5D6108A59130EB921DC37325F5C584E94D20F448CC041AF037C93F2ED3AA215A544F21D954665025EF13A2526071B1810534AE41FF973D08CAF1D0BFB80A9E823C9876B33BE9D58A78E9D52A +D89D +DD109BBB02E23815C90E8D +670E6F21 +C29750C7BE40C8C3B00A6BFF8E +F29877FAB454F994082863CBA3C5E680EE80A5BAE152D28E9A68024A1C11E68CB527C0E5EE66590E998E8906EBF598D94C12B3AFDB02B4984D0667 +05402784 +63E70B535E23011D8ADB00FEBB +FEF05180C4E3C7C77CF2F54477CF1DC752E564AF7D105A5981A14215B9419E47EBA9D9E3BE06357821F09573CC040E5976CDAFCE2629795FB793887A4A05DFA123E4A633CC54A3 +2C249F6D +5D0A95898C2E689EAB3EAE3772C8 +2AC0ED80E50DF695A2E68E1D109280CA12F6B32688B75B1B0F5CAB9F26BC56DE1C9A932DB53E3DB3518B18DE8978FE01B80B0522C70868B8C74FD68C02F7CD11D0686470C63BF6DFAC99B86D76E42CEE06D15C14214B8F0AD20242D1EAFBEA59605979128CAB8538716D4E086AE9F9 +4D3B869A +3BD12C1F40CECB19E7D3B01D5D +350745ED61F551C3D3FC031573B0073F2B742D596980BEFD986ADE52D6D1EBB77FE7F45D5C4696FAB6CEF54FDEA79D79838EB8984AA7B98F7F613CC095B27113770DE465ED70A8EB98475AD7AD8CBDCC501ABE07E4697F283919F7FE +3513BBE8 +0432A34784B8B2A92F48E55ECC5B +A2A7A3C514667A467020FA4D80FC97B8C3836A3647F8F7184FF217D43DEFF9B97C8E3EEC9C086298595D6525C19207DC422CD5B6A08A5DBAC840E1BD697DE783860131B99841A9960CD98134B2D63B43EB7738FC7B59C376AE567CAF0202C52C25C978E4F14ECCD18BBD +1E24AF5C +EDA459D44C900B6D7C953B557896 +224771487CC634B0427BF1391C125BBDE5E72CD0325791D2DB3258F8E9574F41C0AFF6A89566FC35C8C6E039798ED7FDAC6E1E1502F4DEEDFBD90F26B7D1D21B686BE802E855D46FF2796346EE6E808E7ED746FDA813D912A28065040A0ECC80F7A237EFF2872A84B2E2097AEFC4BFE91E0669C494E6A09D69AE9674E9AB +D584 +6F101E +BC96446F +F4B7A7674E63A74844222126B2 +F695F1A7720D3B6383A62B8531FACEC52F6E72C54921DFF45C42C496A456214E7E435419ECC1B9CECD2D7FECAA34192FC23F4BE9ECEDA377D33CE21B538D07DDFC0277D1A429C33826C9BA7A64034D3252 +F415D166 +AFC6DBB935634AA95FF1FC740725 +418AD8CC40170F2902F168EF3B17026C813B6380DA4FC0CB58E0BBC1053022B23391044091AFD51C6D9FA066A6BD4FBAB766463C9FA1D8861F01B856C669FCF0B038A1D5C512DFC3AD142D3636B7A1DE9AF44B088E2C10D8F03965106DD0C1978575AB29 +B109B713 +DB19089A0F4B808C9F9F1BA41463 +88D15056D17A75D851C0279476FC1B870BF5F10129227A3FBED6211E30580E6367CC4DDC6FD12B7754A37B2B5A59F40D3F51D0D9B452336080FFD25AB025F8ABDFE429DDCB573DA55E5E56C1CD1AD6E26A643E42A9B5EF0576958E78DA72340CED62CCA2B3803FE1457B9AC6B65191DC0F691C34C7B7C8C0CBE75F50D094 +6E9B +3BE5CC +AE8003D2 +C507D3C39D238DD26605AD9E0E +1972EBF28B08374BA90C4E14CC2F4C03D305A4A1ADF27952DF6B7C2D2A8C46EB8EE143C86FD5933C16D77CBCBFAAA9901BFF9232B3F91A2EFEF2ACA29F3CAC88F8C4142AEAAEA92E5EACBFADD190BBFD345A8DE011C18954 +E3C491BC +98D72BF5EBE9D6EA214CE02983 +116E19A1AF45B55DFF8F8BF6D5E788ABFEE63DC9A480E9139B971D53CE6C520DEBEBDB29775A1B975E409499A7FA85746BE7B0CAAE16E739D84E51E92166AE2C1E7C7A4BF36892B3F7E2EC4C7A4161E4A99C +F3BB3428 +720750476F08879E8C65844638B9 +EC5214EB326966229EAD150AC5F99E92E7B536FFC1FC91C11C4DD09BB9E24B168009CA93DE69E265DE067B6F590A0A8D43D697885793B0F2BA824727DAAA5E83ED15D9AFC10557023B9F50D5A89054AD7C31486378C449B0FE52C6B7CE36E35A4A9C9FF86F6D2EDAE840B2F4E23A +C96CEFBC +7AA6AF14E1A7751E2CD821F125 +DD9B4396492D1A44EDC7F9E9155D8DF8D07A6DAFDB628B710A8D58154E9E523BB8A22889F1846D8561E9271EEAFA3526B3B0C37B025C1E890375C11405E64F4ECB455426DE1BB1EE375787DACD4DA6314E0CF26B1CEA6DC2B2 +3B081A08 +EE16DE29854EC53AD41D68B15F +2B74914B6D733400C79F8A3F3E3AB72073D5265485BB9ADCE0DC6E4F403C03CD7FC24CAA1D535C61C7BFF57C066245881ED732A25694762140FADD0D476A9A1F4F8529B3CC5E4F329C9F7E8200F24D362D60AEF32753E68AC4F3D1E7 +8FE881C7 +D5CB62729F58D1EA8261508B1E19 +EAFA4C67F1425A7E1DAF6FADA334B9CE9AC3070CEC6605C87017CA1F2668ED9141258215410484EFE9F3ED9C2CA94D94D9A0C340BEE3971B50D884CF9092EC556F18C50721BE3A456F6F4DB76F6925334A377980EEBA6449FD3790FF914112BE8BCB93C986ABA247E4C4ADA92EE3C08FFB0CF443683A3C3687AD823F3949 +5B2F +12E2799D1A2AB36EA405DFAD87CCC9F4CE3588815A5664F1562EE6C2CA8CF7B4720E5D0ADEC76D58C9D356967E502B +2CE7DAC2 +5EAF61CAFE55BE2B1497D4CBBDF2 +276A4F747586004F1716D7220EA44CE408B787D8D29F528DA03831AF743F17A683A465297D6A95F2CCE9D562E2396B2977424C7B55E613C7522BF6F9077ED3073F89153B5AFCC6A55CFFF9BA412D52DFD46C6CC644D85A3AE9D0B19718FCB2D8F5AF0547143713CF6BBD5AB0B3 +E6CD1AB7 +156DF72424A59A8B766019D131 +ED8B94E25330901AB894882DB758249576E85494ED649790A726BECCC12A75C614DA0C3DFD254C6C07068138BBC7747B2B6F3AF6C1BA96A15C89E6A9BD34E6B747B6AA570171100E1A067F4A04F93524 +9FA2DA39 +E73B5A052867C68C23AA33605FFF +98C7D01148026EABED2757FBBFA1F9567E9284F4A928C6D24F771B38CB95A3530E7BB4A6EEC3481A3DAB65AA9A9EEB57CA071B9F8502056E58477B343D816D260DEA6829CBDECECDB1439B56EC5C549EAE00E589E98F11884B05453F0D498203E6402D8043A29248E8DC57185F0D1B3237962DEF470176630B5FEA580265 +B406 +5DB5F720A39C4868BDD24CE4081FD73741DA42D964796A8DD3392E114014E82FCA38D8 +697A43B5 +EE74A1B06388F58B0D0091B3AA +B0710DC099706D9CB7701B171C47CB4DC8392581C2B6B748ED1A769E0B58EEC719E841672EDE987BCEAA97D1E7B3EB3379D474EB2140 +A7975459 +FAE2E18E71FFB5681B677EFF0576 +6E9640AD2B520ED855EEF211A443BEBEF664EF652BCF3F179E6DC26689E79210B0CAD4053BB5BFEF040E2A53E8BCA9B03B22F8ED5AFA995E0FA2907C5B12022F83356AFE150528E4292711A90A0E7DA90F1FC5BB092ED058320416E05A9B894C25D86480FB8F227CD675C9497A53C9F5C0AFB70F8250B7CDEA7210B46B75 +5EC8 +F9552E689E01C7920CFA4D228F73993BC2299263240251454F56234B19327D +EFAE2AD8 +93570BD39DF4CAC50D885EE5DA52 +3977FB143E6A7E36DF9E917D8ACF41F3B53027023B278480061D079F154FFEFBFF70F431A8AAB85417CF178F06D568630709C97878DAFDE8DCFFAE17A3B9413A88DB4EDE043715B6995DDBDC380C0E83B173AE5E73DD4667689C743F8ACFC2567F3CF0F04199C074EA20C56A +44BE05CB +F828907889CACC0FE0A7C9320D +907438DB836BEC2E50D2FB1C14F2FF78AD45DE2596D71395E62A5F63C2D37D7E4F3BB710AA88BC8444CE6D8F42D0E38E3C295704BACB4C474D850B5FF6DBE6474DED60C97DB1 +65E60481 +D8E2091FD37D6841276FE46DE52C +C01A232CBA3E4AE1607E894FCFB31DDF143FEAA902198645290CED42DCC86F0E70D9E49127274441131B1F491A40D6BA83C109D185F9BFB668A9316E9F0EB70B47B1C4CB21854649B1D1E62C9B59180A35E92990783436E00B67D5888017ABB8E84E434E8E157C33CB727AC1D160A8E129D7D60CB8BB6D +866C04BC +A821D2BEB4F7769B3350435FFC +F92A77796C481DF41855617FBD9933FEDFD41AB6FED150DE3395DB33172DCF652A6C9082EF79533A4341CB2527BC519D42B721BD1F1316413D78C6A9D9F3403C21196D8E36CC4BA45B34ED84CEE65DE6CF022B8E9BE5C8 +34217EC9 +09B08E6DB0702B73FA12C56D1365 +DA81125AB46D13EBA6EBCC817DD58652C642C4C9080DBA2D312BB47755B94532BF06C8AB73D778AD004E494E69AF42E1236E638C2BFC2EEBEE0A8B0835696F66BA842AB52363ED311814B12C7C45FAD8EA434CA40EF075560BECDEC0EC6DBF76099794117A1FCA7D3C8C34E737F60237B40AABB4B9D2E6F619933DB9 +52D2EA07 +8A5D96433D10925AE0C7FEEFA8 +41B22745DB0E44657AA65C9A2E5D3324BDCD5C341EEAFC4252EE77FFC23EA88AF8BCC40EB3AB457DCF045B782A37A61EC63431F04C446FE6D742A7C00CC723068F9C72760D +F6225364 +8C013A3E686FE92CBD085676EA +DB90FCF6694822CB456502CA150A361FD5997EDB826093D0B9DF5673CD3A6406B466586D64D0F5B00FDAC3B424CD44FFFEABBFB65B596DA2EB5CB2E1FE8674779926A63BEBDC4EB84437231EA8DB754D39E15405F1AB6074F360876459FCFB2CDDE6 +9B335FF2 +36696543C62D47B42FF0EA43B6 +3EEC52D3506DE1C879E5E74E1378B76037EFB46F0284C19E76019DD11F169DDF7B53DA720EDBDEEC29923DF9DF85C33DAE2D654A7E97566449B1E8B1583E6C6F8FB1E3B1881955DF2BF4583BD671BFE2FF7D91098B7E9C5710 +660E3DC7 +CD1693EE6BC6E351581AEDED6F24 +CFC1AC710B488E3D44393440A6D592408FC6953B8B2E346BA606903645B24C490243938758A0EBD6626FE8D6EC1BD170BEA15ABC63A013CBCBC1CE5BE4D168F69E32A1925422F82F6A63A3773C9B6086707471E8953C7C228FEE5625CAB21D677672B4D94FA45F58F261FF9C19679A81F726714C8F60B262CDAE7EE1881A +5AB0 +B67CE2DF3F035ECDC90504914B9F +C9C0C771 +EF0C44CE0FC8D072B98430C4611B +33767D2973E880BF046C1452CE3B357DE6958038F17DDD83D2EF44162D6BFA7495D091A432E2114768EE174CBADBC6D424F2126AC2F50EF36A6480F5169BC05E1E8AFEDFA1247CAF9900EFED234BE53387B33E43AB3856DABFD7B56C6DD1F546A84005CE4CA0ACFC2D95CF37F4AF1C46C70E948DE63365737CE59ACA0C1E +609F +BB5DC95A9ECEB1662DC3268B727C931AA4A47F7542F500EB7B +4F450BB5 +F377B18171343CA203CFBD7D5FC1 +3534168DA57B98FF4137CD775F7747CFE0E06B24F4E80BE7ACB0E157D046E71A2413855E7147619E81C920EC75076E1073680951520051A946D35F09468BEA89BDF71894FA82654DA9432D301F8BC2CE53D9AEC4E48E2699B8705ADC381D03DD48A157A9A1400B60E3729FF96650AA7422999C79BEB9A67637F2831D71D3 +E8EC +7B516933 +BF2730FA3E04304373BAFA9CA1 +468929A07232E5CB54655B62F0E870AA1ABC93900BA0 +6BAA9BD3 +C7D7B1CE641E6CB4C133676A125C +AE42E92D436D14A8 +A6E78C9B +49F40608F8BDC6AC12F7EAD2336051F53DF30C132CA80F84F0343C8BB46EAC5CA5EF +C166DFD52EBFE2C0A70ED13423FEE5420979BFF44E2848323F983724BB1F4255E1BDB085D12D +FEDE7A806D10B1574F9CAD52B6F53B9D6BFACE2E74C58317E8326A +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +%Defining font PSOwstdutchb +%!FontType1-1.0: PSOwstdutchb +10 dict begin +/FontName /PSOwstdutchb def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001000 0 0 0.001000 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 1 /C0032 put +dup 2 /C0046 put +dup 3 /C0049 put +dup 4 /C0052 put +dup 5 /C0070 put +dup 6 /C0078 put +dup 7 /C0083 put +dup 8 /C0099 put +dup 9 /C0101 put +dup 10 /C0102 put +dup 11 /C0105 put +dup 12 /C0110 put +dup 13 /C0111 put +dup 14 /C0112 put +dup 15 /C0114 put +dup 16 /C0115 put +dup 17 /C0116 put +dup 18 /C0117 put +readonly def +/FontBBox [0 -207 714 694] readonly def +currentdict end +currentfile eexec +D9D66F633B846A989B9974B0179FC6CC445BC7C8A959A39A32E9DCE7FAEF17EE3BEC9F +50E1A6FCA651FC4B3769A0A91041557502E25A5D6180FE25A3D11BF079E1DF66E54EE9B7C229AF891739707A2A0EC140306B5E43E52B79BFB89E459E50 +6EC6F610A70775A31C460976C4F79449D86E57ACE491E5C6BF20CC4307B1DAF7630252 +E9AF8CFB69B50EDAE9D36A6104AFEF8832F920FD2346B2C7104CD11E3BEE999CFA9F5A +49DB3173EE48D1C82994237F360407B022E0B4 +502E94EA8B493651EF2D03F0B513D655047568325B512AE6 +6AC6F53F3848CF70DE25481CC65D8B1A5793AA +3C4282D111112BEE28AFCA7A3808D4444C4669CA +84EAAAF989219F51AB3476A1B0B5F2246BC306E6 +625C6679C417ED2A8E9BD010DE37D40265074C268425D9A4327DA39CB2DFD7488DC30A83BD6536 +5400151DAC104266BE4EBCAE +4B08321016E28AB4C8 +D564DD37 +35505D841146976EDFB4BD729A +2F49DCCD6B4ECE1DAC32EA5679613B7894EE61C72050B6DCA08334000C4A16 +680A3781 +2832EF2992B04206872A04965B +DC89A31C159AF7876EFDE9C566C038C68F3700C676CF6C0A355B73E0D91F6B9800797107DF57C0102E29B3333E99D6A3ABEA7D4404EA3C1F37246A8C +76B86EA3 +AE31E559BF3EDE8F6CDE73497A +3B48229E41D2A19CB431FC70509621E4F35C13A3465D70DFAD019F6D512BDE6EE14E2AA9D7ECE836C960C05A2F580BD2E58E9590281D0CBEF193 +3B8F5440 +739F67D06852217A6FE60CD562DB +316843A0F8A150F56117A49EF131AE85F32010C16B29F4FE2AA5F4811F24F233EE45B6594B8FAA3909681993A5E34C3E0D12FC12053AE4FB8F739E9A5F6974E510F71F22463E40693D64C047B703BBC8A7A486DFDD38C656F396B8CDB0CC8ED9EF3DDEFA +CCCCEC8F +6CD996ABCB775949AE7B9B6AFD +4DBB80962CAA21ABBB8E263390C78DF6E3880EACCF2FB4053CD794C07E5A1439F4F1822AB2A0F353DEC423027E7C5665896C49F8BF690970A254155E93AAFC2B6E4AA4B76CE65F1EC7F33B4BC932DD14BE25AAF01A445FA4CB118A25B5A90F +4BFC463C +A6C554ADF0E48B79A5B8FBCDB3F5 +36F6EBDCAF7B0290F985627BD389297FE08B571E27831EDD31EE7079AAD7FE057B908FAD87501D527BDD07ABB4B85702A8CE3456F12745BA71F287A605C74C42C9F3457D754FFFBDD1E308C6B6659E1B384478DEBDB319C9C8D3C8D331A723FD99DE47D127A8638DE89E69B54B231391917168DFE6FBEDF53CCDFC8A67EF +0B42 +CAD3061C +4A1F175CC8A06EF1EEF820D2B1 +C9B1598B0DCD0CC1CC06476E687971CDFAFEECC5C76DD1BD85A0BCF25E4DC5660031BD9AB6858CDA1DEE2BCBE66BF455A74B1F9474DB65B4115535611638A039B80BAE4386F39754CC339F0B7154B0276398 +D1825AAA +064A63B4644DD4EFAC31F8140B +F306B6DBEFE1871E5E8C799C82E1C51CD65C1130386C6283C2F6BDE83CC5A161496654B3E646A4792A9173AEF23227EAC36F819F4EB8091C4858E05CCEB00BAB47F9618467E859446DC90A4BAAD36877E5E3751996C9B9151BC9E309 +4ACDAF57 +5E5DA78B7973C93B24994D21D9 +B4EAEAF8B63393FD858A23852C07DD58B6ADFB5FF9FD26581FDCCC99FC7EB85FA5B877406C89A04D2A8A34C07140D68A4C50EB9EAC6064F7FE0A2D4287CF2CC6392CF31D6052A1726BF9F16343C9E50A75DA3207290889A56A013C5BCE +E6E65DDF +FFF172B54BFB3DD9694C3FBC75 +583A79434084FAA0F85413F66EB3376E0A96FFD08BCD62B070DEA3F8C80B123A78DD8594FBBBFEC9518714C8BF6C18AA42CB9E82D4DBA15595E96E6F635C5E0FC7D3140854807BB2D43489A6E515 +491A5CFE +BC8780EE34CBA548F8A52B5B1598 +D198A1A9153CE89BE19ED7CA13228E4689A3DDD965075677C4155318ECCE58F6F511B0F58D88418F638CECEF0B0A301AC54BD5FE8B0BC27656D05B4986880E22CE4107A14265BEBF48FEE7300D359B336A93298F9416C6B71CAC98184998EC31530E475E42E602 +2FAE9ECF +5BF46879E304947AD2171BAF72 +5B98274CB1F972D1AFAAC69024636815B780CC213E07108E7844FA96C75F4180EE4B8CEA450548E46FFACAAF53000AE9CC2AABF80A3C5B5C524FE57033E39F37F86442856278 +3A6759FC +A1A313B64B4DAE01219996AD4984 +EAAB559FA3F1B1CB9755BAAA5729851D7D11CAC03D5301BE0DDA1DB7D33DC9E960576375E38192B00B8E7AFFDDFA20EBBBDC8B58E2FCF37B9A380E23631B70A1975FB78247EAA06877296BBAE4964D4E269E8778DDBF86F2A4F8E77BAF4FF9ABAB473DA127CD5D939226F8CF5E2710337B +7FF4A3E4 +0D83472C47C1F51F6EBD000C1F +8359A11D15723C44A5FB25677860602E110D6BA694038175CD2C91D4ECCFBDA28E7C3E417366AE10E0668B95E52574E81C64586EB2E57BDC02B21E4E6E30DCBDC9969AB4F35C4CD571F8713D9B7B95829F0B69607E5227270C +31A0F4C1 +1E3834BF5F204565D07985D710E0 +C35F5B50676AEC0CABD666380CA4C63AB2A40741C78C362C5EE61BF5502396A07027388EC36175F6B8CD7AA0574E72AD5AFA293C0BEABEC96BDCD42B3615CBB768A07C6DCB1639F34CACF71EBF75D2C71D82139B03120B2808C393C3F227CCBD9AD84EFB2ACCA7B3EBD04430DFD3A2ACFFB167C943F425CEA4 +8114590D +03150C872B1B8486C775A4130B +81E97C2A39D4965C59EF24C2EA49001BAF5A6D42F4E42071EE7EE6F567FF3A461427C9819E20E55C7B79E7C06337E5FFB63F8486E8F8A84E52C3DCAAF654C6CF4BFCAD0F +29433ED3 +3A69958583E048001FC2C8C582 +E13D3963DC178FED6AC98005B9B42A8010648E5405A0AD1DFBC13255B1D5320597AB2E508CB1F897BE6B33F956B82B060443DA088A2D17DAB38F1A17F93F575DF4EBAA3021BFE3AD87773E35625DB1219759A87E32B0A199386EF5 +4B45DA3D +AC6E3F39DDC3E86DB49F5BE5E43D +9E9731AA509F3EFF +AA1DAF46 +031927C881C0F23BD92FB5D2AC8386FA2E208C424564CD90527F9F60EE4B6B3EC378 +B10EC2C53F879EEEAE758BCC7A850821C5D67E5978C53161C70DA5A1FB710E1602E562B0AB84 +A88B5585D4307822E5194D0D75DD4B78D689F6FC98BAE1D558A9F1 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +%Defining font PSOsymclas +%!FontType1-1.0: PSOsymclas +10 dict begin +/FontName /PSOsymclas def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001000 0 0 0.001000 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 1 /C0069 put +dup 2 /C0083 put +readonly def +/FontBBox [50 45 775 713] readonly def +currentdict end +currentfile eexec +D9D66F633B846A989B9974B0179FC6CC445BC7C8A959A39A32E9DCE7FAEF17EE3BEC9F +50E1A6FCA651FC4B3769A0A91041557502E25A5D6180FE25A3D11BF079E1DF66E54EE9B7C229AF891739707A2A0EC140306B5E43E52B79BFB89E459E50 +6EC6F610A70775A31C460976C4F79449D86E57ACE491E5C6BF20CC4307B1DAF7630252 +E9AF8CFB69B50EDAE9D36A6104AFEF8832F920FD2346B2C7104CD11E3BEE999CFA9F5A +49DB3173EE48D1C82994237F360407B022E0B4 +502E94EA8B493651EF2D03F0B513D655047568325B512AE6 +6AC6F53F3848CF70DE25481CC65D8B1A5793AA +3C4282D111112BEE28AFCA7A3808D4444C4669CA +84EAAAF989219F51AB3476A1B0B5F2246BC306E6 +625C6679C417ED2A8E9BD010DE37D40265074C2684275DD89A8790EAD18EFC77D3FFAE84DA5D +312074C4D542DD5BEC70968F75DC +250C3954E8DFB8F4857BFEF092EBA49D248955A858C5A5F55F7B987EA06EC8428D939084C88F5B157D80AB2D706A7EB936C3429173588D2ABA6A27DC94C0B484F316663555797004CBFA79E7B8545C810BF9CA92F61ABD9E202ED9E95943DF7A5ABBF3C20BDE3B6EEC9C0B95A4C9C1D38AA7C6786ADBBB79EE183BDDF194 +1953 +6449DBB7AE47E9FC6F3ABF1DCD7A1E274E87DAE9 +A22737FA +6404B215A27BFAF6D0B50E94D2 +07123A5BB380C86DB5033EE743181BBFCC0356571F7297A207C23F1E588257FDEF5DF229 +CABF3B3C +9E0988C63B358ACA4B4FEB033DFB +E2E387A06A23CACA +8E104B90 +DFDBD41F063E8A8DFA0ABA4DD7443015526AE5255315597779E04D85849305EA4F31 +5CDAD06E5841E1B8074760C99702B8CF443D752174D996C94E690797A9587CF5017DEB11E5FE +02576E9E08B39688BBE99A186AA8FC7E222F5E52B29A7FDF379EF5 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +/DPIx 1270 def /DPIy 1270 def +72 DPIx div 72 DPIy div neg scale +0 -13970 translate +1.00 1.00 scale +/wst:dutch12 12.00 /PSOwstdutch newFont def +/sym:clas12 12.00 /PSOsymclas newFont def +/wst:dutch14b 14.00 /PSOwstdutchb newFont def +/wst:dutch10 10.00 /PSOwstdutch newFont def +/wst:dutch14 14.00 /PSOwstdutch newFont def +%%IncludeResource: font Helvetica +/wst:helvps10 10.00 /Helvetica /wst:helvps ILEncoding 0 declareNFont def +/sym:clas10 10.00 /PSOsymclas newFont def +%%EndPageSetup +GS +0 13978 10801 13978 10801 0 0 0 clp +wst:dutch14 SF +0.00 0.00 0.00 1.00 setcmykcolor +<121b28251b261c09010a010b1b23191e22172620011c242601111b172729261f231d01121b282b2426200113> 2207 558 0 7384 -1 s +<1b261c2426221723191b> 7375 558 0 8593 -1 s +wst:dutch10 SF +<0708> 9346 13300 0 9522 -1 s +wst:helvps10 SF +<4e6574706572663a> 1322 13280 0 1949 -1 s +<205265766973696f6e20322e313b20436f7079726967687420> 1949 13280 4 3868 32 s +sym:clas10 SF +<01> 3868 13280 0 4019 -1 s +wst:helvps10 SF +<2031393933b131393935204865776c657474b15061636b61726420436f6d70616e79> 4019 13280 3 7133 32 s +wst:dutch14b SF +<070908110b0d0c> 1271 1458 0 2055 -1 s +<00030402000609110e090f0a0005> 2055 1458 3 3510 0 s +<1211120f0910> 3506 1458 0 4189 -1 s +wst:dutch12 SF +<151e1b> 1271 2086 0 1631 -1 s +<00231b28251b261c00181b23191e22172620001f2700181b1924221f231d002a1b262d002117261d1b04000f23001c17192802001f28001f2700172122242728002117261d1b001b2324291d1e00282400181b> 1631 2086 15 8893 0 s +<002923281b23> 8893 2086 1 9461 0 s +<2e> 9461 2086 0 9531 -1 s +<1718211b> 1271 2330 0 1652 -1 s +<0003001f2800191b2628171f23212d001725251b172627001a172923281f231d0028240017232d24231b002b1f271e1f231d0028240025242628001f2800282400231b2b> 1652 2330 13 7624 0 s +<00252117281c242622270400142402002923211b2727> 7624 2330 3 9531 0 s +<242a1b262b1e1b21221f231d> 1271 2575 0 2542 -1 s +<00261b27252423271b001f2700261b191b1f2a1b1a001f230027292525242628> 2542 2575 5 5365 0 s +<00241c00281e1b001c242121242b1f231d00281b27280027291f281b270200261b2a1f271f242300060405002b1f212100181b> 5365 2575 9 9531 0 s +<281e1b> 1271 2820 0 1561 -1 s +<002117272800261b211b17271b00241c00231b28251b261c002b1f281e00281e1b001c242121242b1f231d00281b27282709> 1561 2820 8 5763 0 s +sym:clas12 SF +<02> 1271 3167 0 1359 -1 s +wst:dutch12 SF +<16231f2c000c2422171f2300142419201b2827> 1589 3167 2 3567 0 s +sym:clas12 SF +<02> 1271 3513 0 1359 -1 s +wst:dutch12 SF +<0e13000e1f13130f0010100a> 1589 3513 2 3001 0 s +<0d> 1271 3860 0 1402 -1 s +<2926281e1b260200281e1b001c242121242b1f231d0017261b001721272400221f211a212d0029231a1b2600192423271f1a1b2617281f2423001c242600261b22242a1721001f2300281e1b001c292829261b09> 1394 3860 12 8834 0 s +sym:clas12 SF +<02> 1271 4206 0 1359 -1 s +wst:dutch12 SF +<0d> 1589 4206 0 1720 -1 s +<24261b000a> 1712 4206 1 2230 0 s +<1511000a130f> 2210 4206 1 2975 0 s +<0a> 1271 4553 0 1434 -1 s +<001d24241a002b172d00282400271e242b00242a1b262b1e1b21221f231d0027292525242628001c24260017232d00241c00281e1b> 1434 4553 10 6384 0 s +<00281b27280027291f281b2700211f27281b1a001718242a1b002b2429211a00181b002824> 6384 4553 7 9531 0 s +<272918221f28> 1271 4798 0 1882 -1 s +<00261b27292128270029271f231d00281e24271b0027291f281b2700282400281e1b00231b28251b261c00261b2729212827001a1728171817271b04> 1882 4798 9 7001 0 s +GR +eop +%%PageTrailer +%%PageResources: font Helvetica +%%PageProcessColors: Black +%%PageCustomColors: +%%Page: (35) 35 +%%PageResources: (atend) +%%PageProcessColors: (atend) +%%PageCustomColors: (atend) +%%BeginPageSetup +bop +%Defining font PSOwstdutch +%!FontType1-1.0: PSOwstdutch +10 dict begin +/FontName /PSOwstdutch def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001000 0 0 0.001000 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 1 /C0032 put +dup 2 /C0034 put +dup 3 /C0036 put +dup 4 /C0040 put +dup 5 /C0041 put +dup 6 /C0044 put +dup 7 /C0045 put +dup 8 /C0046 put +dup 9 /C0049 put +dup 10 /C0050 put +dup 11 /C0051 put +dup 12 /C0053 put +dup 13 /C0058 put +dup 14 /C0059 put +dup 15 /C0065 put +dup 16 /C0066 put +dup 17 /C0068 put +dup 18 /C0069 put +dup 19 /C0070 put +dup 20 /C0073 put +dup 21 /C0077 put +dup 22 /C0078 put +dup 23 /C0079 put +dup 24 /C0080 put +dup 25 /C0083 put +dup 26 /C0084 put +dup 27 /C0085 put +dup 28 /C0089 put +dup 29 /C0097 put +dup 30 /C0098 put +dup 31 /C0099 put +dup 32 /C0100 put +dup 33 /C0101 put +dup 34 /C0102 put +dup 35 /C0103 put +dup 36 /C0104 put +dup 37 /C0105 put +dup 38 /C0107 put +dup 39 /C0108 put +dup 40 /C0109 put +dup 41 /C0110 put +dup 42 /C0111 put +dup 43 /C0112 put +dup 44 /C0113 put +dup 45 /C0114 put +dup 46 /C0115 put +dup 47 /C0116 put +dup 48 /C0117 put +dup 49 /C0118 put +dup 50 /C0119 put +dup 51 /C0120 put +dup 52 /C0121 put +dup 53 /C0127 put +dup 54 /C0262 put +readonly def +/FontBBox [-25 -256 920 766] readonly def +currentdict end +currentfile eexec +D9D66F633B846A989B9974B0179FC6CC445BC7C8A959A39A32E9DCE7FAEF17EE3BEC9F +50E1A6FCA651FC4B3769A0A91041557502E25A5D6180FE25A3D11BF079E1DF66E54EE9B7C229AF891739707A2A0EC140306B5E43E52B79BFB89E459E50 +6EC6F610A70775A31C460976C4F79449D86E57ACE491E5C6BF20CC4307B1DAF7630252 +E9AF8CFB69B50EDAE9D36A6104AFEF8832F920FD2346B2C7104CD11E3BEE999CFA9F5A +49DB3173EE48D1C82994237F360407B022E0B4 +502E94EA8B493651EF2D03F0B513D655047568325B512AE6 +6AC6F53F3848CF70DE25481CC65D8B1A5793AA +3C4282D111112BEE28AFCA7A3808D4444C4669CA +84EAAAF989219F51AB3476A1B0B5F2246BC306E6 +625C6679C417ED2A8E9BD010DE37D40265074C26842192FA8DE8926C9A5E7B70CD3387DC965ED3 +80DE5496E8CDADD459C9885E +7F6A0CAD41BF0F8AF1 +6074E51A +AD53F15B5A08F66F3EB729796ADF +C7E958E483684D19788095B6BD8E53B909A6914E1A75A165232666D4B51EBEDBC793630C75EE310100F2DA622ACB36C07BAD9A6A67AF796AD1377B57C6C25C761910271EA51B0E4C5533A7CD0ACE4AF699B940769661A7B24692A217C17376AE01E9313B898C16 +410137E3 +269C6B7C8EE76F95F9A6A930E838 +72D8BFACAEAD728A819C659F159819B873B6C4C46E489EAA54A650DDCEB193529695DE801934C02C3823B8AECEB751F0A933CFDC02D14BA5CDCA9E7035445BEF74766235BB3232521CC2CC07E7F7DBD738E1B586B4C90F50CC6E04129F27A31C859DC898F0C60A6E84C4D2946A5B275F05C7351EE2D295A16BD0788A4743 +FF2B +FD3DB9F8C8656BAB3ECF236B +DF6ABB29 +67CE93AEAA857114B2D4677A6D +2AED7340FED5A11EEF13B80D9085FCAA9E876D273EF6665E07279240838FAA17F46A7063D8A1AF55123A7BA41D4698FB9E77BB0E3B1A02CFD22BF223248508D0 +8ACF49C0 +14494AB813A2FD06D2C5714622 +E75955FF9B63C89BADC0B9C43B6466A810143FD1C8F61983603755258329F6783EB3017BCA3CDBDFFD02C7BD57FB5EDE3A34788026C2022D2FFD7BC2A55791 +59773910 +850189AB3CB327C7CF5DE7E5A6 +7D422015B4B4DC54C6CEF7A3342D44CBB81BEEDB225EFEE63684E68CEE9E79D70A4B50683B2A07850D02AF226A815B4FFDAAE50A21D6B6C5E3 +4BEC2466 +EFE584D345FF085F9A89E3BED6 +25BB7CE4C2C05F00FDE3AFAFC353592640990F8451DB02 +A3EA22E1 +86F22208A4A9F7D447C622B160 +945F93BAAFAFCD8CB7F106C06F5AA1FE3F203F2E13C097482C27D17C141A08 +D4205E39 +DEDBA47430AD743A30A894F1EB +AEAC18CB95E1D9B0EB1C6902CECC7CD89AA6238FD8AA9024CEF7F890A4C3FE81189790FBE1AA01FA228081E91714E473A821465C5D81E94E4D09A0AEDDA228 +3C0819ED +07143B066BC8861F9BD7DAFE7A +A2AAF8B3B09FE3A9301D9A09282BBC62781C72D4E73BAE1CB300F2AB52F9F5B3D0163F4039A50E1B692F009E8E427D3E67008B3F0A2F7D077D096A877184E9F1964CC0B80338D1D279CD77BE02FE52F90307DFDB15B199011906 +2F9C73DA +D18D7112BB0B9FF6F91C8C88BD1E +7273E1A48CDD042B2B87E1FC483126ADB6D11B82CF59785E1B9A6CAE1C8F78B386A1F103B9E99B0F11303ABBA424C8AE132206AF8637C456EC35AC8DBD3C1131D9DCF824A4B127BA7B4877A5FF5B7AA20D3B33A5189A10ACCEE7F2533CD0F6E31484E636E1F09A2ABF9BA9E1A915C3 +4430CCF2 +C8720D5BEA52AD368AFB09D2A8 +E94D0ADB8749A2EBC4541DB88EB241CAA29BD7F3A57CE582EC7D840F89B631A2D64EA99DB90BB30244AC2DF25C9096C366B941183222809A263630A81639C1938A1DB0659C4EF8BA73E381D10F27DB822958309BD90A7F17EB73C52F6B072DF31D +A9E61A2E +ED944AF624AA8CCFC82869148D +BAC1EA484F648682D24D187294DA73876198CDCDCF520D0BBDABB88283EA9DAE482ADF1265515720D356A79E1545EA9A2F42D201B901 +62E1B5BB +0F4587975A5BBE21F72AACF2D3 +3AB5D9FEB3DBA51DD0DF22C72E7AEDF4240DAEB1F667334181C479AE33834EDBA7D2F8A4DAA764F993A7A7583148904F4842523C94490CBA8895B2B4F6F09D8419A39B6D07F39CB9A4395CFA99C9137A +AC0190D7 +6A19302CCB406BF3209D7561B43F +3859F3829F2700584D1554F6AB94AD677421E0BE0AED032715CA26D291C91A32D00A1BF8D202D665290B75E0C3F1941A221C8BA569460F8944763CD697F52A512B8C9374014DB918D5B12745AA422261BEFE20F5DC5784794ABBD7067250DD75B8405C694CD2FBE15EDF8927B078FFAC7066A3 +D662A728 +08D5D4E5D0959021E2F9F7024C75 +B312709B80B7E8B968EB83F113661AE84BC86F24676F509CC341890E66AB066492E40B697D4E13CECF76F2F073B486E87D459CB0AFE72936862A48FAE9F0A17CF610F7F8B19AC04C11A17B3C3619DDF2DF2051F4C5FEE823393DA2E24764A6F3D79731C8329C0FC3E0D7D09607C53AEA7EA315879F2E99D0E11223808728 +D2BB +29 +E508A25D +01F54024350694944989A02570 +51C547167A78593EDC1FF27AF97861073E62B0257A354E5CB10444D3160CA72129A3D4EF87FF61E70493C90934381C89BEF3898250B73756695CC0E8D875A0B3E1622A9B6FDBC706558C76AF3A98586A8FE7B7387761F9DEF128BB96E04DD66355D656 +7FEB5F51 +3D797958AB103BEF3A31FB261682 +CFE36CAE5A1A6AC3EBAA62EFD3BB0ACDC0220D5926A286DCD370B19CBD79FC1DEA52C8B1C6025294E735BC682811595047C5C7D8796A7CA3B1A291E8AC9E37FD04396146EBDEB1AD0A61B256F681DA5A88D8E817822C37294070BB57E448E38835B47EC86FE4820291DF49054C00579B188C98121DDF1872E78189D9A34E +CC37A0E8 +0A9DA5F95CD5AF5ABA361965E187 +6B223B74FD83B134DE98D6D31D8DBB595B2D8FD149434673894A333DE5DDA8E0E432F9EDBEE766BE2D16E8486766154921CAE004622EE856BFCBEB332B16FA14C58181923344D19BA1DA934A43A1774114D068E7B17B22BEB064248C14856632BD6C0A4CBB2B61D18D +E46F52E7 +7D6B2610C21E7C50A26E95576C +7F7A2A25258AB3A888F4D15CC00969D8FFA7A3A37424E7545A19208C7E79ABE20AC8699BF74CF788C9DE71D98CE13AC8D11A189831C518F0BA97E0 +FE3F00CC +5C7B5D57027EE0170E183D30681A +1387AD17F24807E8C1718F31BA1A0705826D0F823F77BE7AAABC3A8F02173795A061CBCA398FAA1DB4891C643B3430D0677AED0E1F02B6DFF8BC2956DE075377A6FBCEC85FA6CEAC3E1357AEC49C542D4E08AC7B3FE9E63400714EC1A7E371A506C08545F2CEFE9C7B3705BDCB16A7 +9C0B1C89 +928929ACA34B522CF0C6D5F9A8 +BB59A81352C053A5819FF7D03C6B65A862B39D8BE79FB95D22F07DAB7138916E513CCB8E33E9E63F306DE54C7C5B3C4497A47A0C6C63F4E8F07AE76796DC1716EC04F43C060527CB76AFFD306E1C9986159574F9FCDEF1107172A790 +D5F18DBD +591A755321ECBC290BDCB63267 +A9A7701D64F9749A0464CE019097425D6498EF12D6D1B22B68435C4F4552A6059914E98E773142907BF1CF06C6FB67CB6437ACB37FBBFB3D224E7A4519623675F73EBCBF96FF4F0BF98445D87664A58EDD0968 +F768DD87 +056D5C62059E81D80D32A3BD98C5 +361B6622C17C082B52E05A1F1DB6A6CF0F82A7C63CA6465426C82FF8FC795122DA838F336508C7327F6DD9675F7A900414994C1D1E536F501766BB4971F3DF4D1FF9F69385D0ED4A4F0492E671AF41C536BEFED4B78A43B1278D8F3DBDD31216FC290019202E418B19BC +AD089E9D +10D303D0C11541C2CC4BD8C13852 +D265FBCEA3AED2A0BB03382662D6F898AE1C0C9BCF71D715FA86408CA0F9A7B5623DF676B9E10480B98E84D0B803FC44147FBDC47A585F19F47EA53E6E9F7A9F56ACA884EB18142B6403875908F277D9652F9DA5F56E15B272F02E5625C5E6FF5FD82FE4D2C34CDC81E44CAC97843059F49B65BD9F89232412F772A8751A +54B6 +A7B73E +16DAEA55 +2F0816C68856225FEB4332B860 +6F8473AA2E53EEC1D16FA2DB6FC81553EE833DCA527807A6AD3A9F14F4A4F16FC00822824B713F51B61F425886AB923885F588B0C1D5E8585AEBAD7DB018F9387E4974BC46697C1FA99E43AAB6DD5468FF +61F50FA5 +DFB65E28F845E8330BE57CA2BB35 +988541C9C545952571041E014C509C277794EA1B4FBBF20446C4517279046EA9543DCCE23DBA0D9775BFA115DC6BF2FA17B4B4586D07A775BC686C7105F3B3970DFD90765AE34E696BB4752500DE0384A56F8DA85B9FFE07B33E40F09C7744E103057E67 +E58A3D5C +BCA5BBA53AE8A7ABC904B89BD943 +B49ABF541C8EE1686EDAB1A76644E924390B82A952BC3FA85FD0BB5E1370FF31131C44EF57A61D318B84F906C2CF60439737DF5133ECE1786770CBCB52BA864C6BF0BA7916AE6DC390C9F5ED816C54ED070C343DF638B5B5E4E41CE34CC2E0402605115DAB535CBC52538AF39CCC09845E5096 +58D2EECE +68DEA3E84B75A39BFC7A211127BD +A0F71F4D43B55BBC435C4B12B8F00026779A20699395EB172B58FB131DC19E894078AF0F17AD8F531DE0FDA17C04F7D8E9932453574C74E75AF02DC7145FCAE9EC05DBB1CCF29CA684A9191BD3D8593708DB3D8CE6D83A4A69EF66705ACFA1647740AE05F6F8D7CCB48E8315A92EA34C52439AE58AD3F094B4DF290995BE +C9ED +396C1C +648D3527 +E80857B14BF410DB36C6CD1111 +9603EE13228E25ECF3D1D5D2304D261AB95F016870EFCF3B595FC211BB291B9DD3394FD56586B3733B1D869AB23E38F5B8F6F86AB238EED48F0F11763CF284C9788E49766DE3740DFFA0DB66A30F75553069B3FE7CDC97F3 +EDE9A157 +EDD6752F809D7DC28A94854212 +C9219CAA40D028CA94ADE9781EA42010CB8EE691F1C29D9D6C9BEBEE1E528976BB0EF8EF884873EB12C37AE57AEFB70DBA384BAE6E92750E21DEFD562827D09E23D79FE0A24C8885161086F665FE8558769B +E31893D4 +0A6D5FC3ECAE7DCF876EA9F1280C +A84AA8CFAC6C507958A34C560354E0882E5A438C75E36E5227A62178FD12905B9974094BEB73581F94EF0E631C2EFE35B122A64BFBF128353D8E43E89A7F6F8CE8C25E6F332626BA36977C2E7FFEE1061456BAE7F5E27A11F09DEB595E89732C16822E8A823F6640BEE5AD0EFC6E +AABF4B75 +2E3C9E3DD3D6511F01D6F6D4F4 +FC37AE9541A45BD1B34F7B62295E95D67FB66BC987AD6169368F121AC3B527CFFD6D5ED24A9CEF8B07538EAD5FD0DDDF6EFF49F1BC74E3423099D5B7D042C3D02738E1B5CCB0D050942442C156F22915E576317704B075D527 +48ADF1DB +DBB11EC953CCD9BC61E413B344 +914CBF1163E60681D9DA80A29903863BF926B4EF39028D902B2F85D87C149691580A97CF4EF102216C6592626D47994E37EE3F434E0F4EFE6B2187ED1013974408336778CB7AF4F1656D627C1A978B84A3138B1F800FA4C62B6C43AC +543816AB +8E443E3FBAEE9718A243C622B160 +945F93BAFB6D02B29386AC8BADBF4189767899D9F620311DBC7A393CD36C7698795F6CB1FADB3F77071BF6002AEE04ADC8A9D858643CF47905F12C6004D6BBE70D31ED3FF6E803CAE8F0A4A8177173F1C96950D1CC6432093A3C9515DCA0994DBB8060A3CDCE4F53618131E959A2AC506A028BA2D7F420ED432137062956 +A420 +799A3F3BFA2E6B46C86DE9DA79A0B6A21AEA241F83B062DCFC28580BC8ED93BA7438C335322A55EDF8D615E10F8B4D +A591E1EE +07E5E2E99D5111D07782AC3A9319 +C5612F3D9DCE571A5DBD3520B0C83AD1CD38CF39E7803BE2EDD76C5DB323382B173E20C6D2A19BDFFF52742ADB8410EF81A2C1A94CF5D5234729078415F78D15303149F65E173ED84051A798C11559CFE4299633B3D39D954D29FD3A7DA160C9614E1EADEA70D778DEFD4CE094 +AD67A367 +4C963DA43D1DE8A30E769FA91A +58C18B300938BB4A49E80A4008596F77AE39524B4CCC0E238165A6D560252434CF296E86F4F8C391034EFC66EBD1593EE82E6E6C122724F0662C7C2DA6E8B77A7EB718D1BDA94F3D300ABB8AAD3148B7 +E06EB8DE +80AEBBC76190D9F37D3C0885C659 +DC3B91507D8406EB0AE39CB1AC26A46320E5AA3C2050E4E5E450306677D7784D204D6E224AB9DDAB27C6C058C27AD6C7CB570B76A37F5EA5E90125A1D13F7D3301325BF57255DEA5C42AE982F4DB1AE7F5A12EC5F04FBB20D9F9D7DF1036D0303DF853A1098831028A3F533180C11D777B01439E357C192ED1E5E38A11C0 +61A4 +75E28DFF9DAB9317A68B97DB109620638E68F75415B4CD453860C414D26AABECF5EAD9 +AD2E6124 +BDF5A16A85DF735C2AEA26EE8E +974027A896C0B62B8355E9A1ABD687198CB1946D17EFEE353A0842211CF07643B2C79F641AC9B94B6E75B8CB6CCCD6238B35EFE683A7 +5C3CF381 +5E7375CE1CE8CAAE33624F3E9E69 +4D6D56496115936F5170C719D257BE63EA9EC0B1886DBBDDADE702FE0EFE887DB663B646AA24E483467A39A969D49CDD816BC3B9556A6E8B1E8CED03D30319B063E9C61055C7840D91B0A7AD3F8F202B9EBFA2CA83B508A83804FA1BD1BCDDAF76F4C53862E618D04754512E08B84A83220D17CB0F30222D4B9345A21E1C +16AB +78DE68C2206531599CBB7F35435E8490E38C40AECD3FE86C98CE59F8C4C59D +224D7A37 +886EF84E142B6774B821504F45CA +A0E02507A83EDC23066BA9405507A4653C3744B097A6DA72492F8B207220F4E4B23BF98B01B2C4C5489EE0C2D35EDC47565F6A535C0BD942CAE7EB5175B3C3102D057B05FF62EA157857672C071CE0DA6BC6839C3223B0651634F95595F0BF8E6D4885651153F0B2EDF7C81C +D57A064C +CABE0A8D6A265D5A282ED00D99 +3F9C24F63273FCA080381F14653B2852872B7AFCC3BB7449B8D11E619AED4710E195B101D52F1BF67DD1876C276EE93321EAD82D65DF24E1C3FA319D53BAD915C63C6F3B0A6A +CE822885 +3BD0AB921D48803AFFB2DD974478 +86FE244E7AC9B7AA4770374456E1BE17A244F38FDA54BEA3E795375C1AE8479323F3AB983C8A91A9241EF117DB9FB8D479BAA95617CFAAC416920A3F647A395070F46CECB39CE2BD9D827ED8153FA1A5E25B95FC50F44C59675F36B16D9F4B3687F898DB104E914143A8F77D8DC399BB9BF25099AE679F +FFAD6BB9 +F64FF8F89D5C8FD7D3B79FB32C71 +4816D0B12F7FB340C102347299FB60F6749043E3D0B2372B8D49E017FA0B33F206F5DB8822AC3DAD3654606E9C0D705E184CCE0BB3E6DA9257B7B77168EF834109546CDD00427434504466EA748C82BABA5822DA3DFF2EA218D0BBBC0B4A25BC3ABD6435835F49FF159B +E94586CB +9FA3E8B95614D6A3661CF27920 +6DF52D94914FE374C01CFC8B8AB304ACFAB9269AE7461A5E3931CAF0150DEF0D91BC52A63C6B85AF3A8FE6BE639C9ACD2A31880173815CC68365E799F1E591232EA0A0B7A1BF722FD6671D1CDAFD4E46DD1A3F7E04FA2D +24CF8BC3 +B12CAEA137DE3B5E2A681A46E94A +4BBB826EE5ADE4F69E8D1D9B3F94C1D92F4BB4FD201C20151D8ADF04209460E862FDF3D9846EFC28220F3B1676052DC38B208FB63DC404442AB863C1F556380C699697BF80115A83BE8C167B916E57E14CD6D85F1F3400F08064403C10123BFF7B80886E342CDD8D2DA149DA29F52FF7521E410293CA2218EE8A7454 +14F691C2 +510014F5D4031FB141A7743A09 +AFECA6DC2B8033E389333DA9F6C7A0EE83414748A8FB9D72F3CBAB2019BDE20981B93A60D46E313EB320E3C54EA3F9FEBB9EA48874F943810C2D600D6F67030182E0F14BC2 +12F17C59 +A802B6D578E26E01901EC954B8 +03C19DD466A6254E87EE1F48C8EB0F662C43274A00FF45A7BDB2F263261E8D91094599444A7B273D79E0A0113C350B2E46854830F38ADA973C3F62740FD6663CA57C9EE1760BAC8E52FE25B0BDD024AE61A4E8AD620109E127A0E699D2BE0483F8A7 +E0137EBD +DC2FA98B79CB18878298C38155 +6B32D9C306253D126FBB30357647ED2A197C8322DBDFEB10B9B4412D935B42233DE1BE9C783311602068EDF86CDB725B8D29E92AA860D79A78662C02CBB80BBBF9D8807EC3AC0F695448011E93AEF388D95B877E1BF271441E +6F9AAA0E +49C2451BD2E97119C3A2B6E6CAA4 +CDA0371D3CE16B0D04B9A523E1B6F00D80B94BC7CA9854732C5B78301FAF0037054117A2E5DC198549E2EB34235D8B51487CDF261D8C6A76B41049E7AD00AD75A019875BF2AD5049C40CF0827F561A2A0B8BDDA3AF09CAF1B5224EE71B79A1C9EA59C0414E0B8105FF20D30702ED2DE13C09259BBD9DD128739EFFE1B2AB +1CDD +9B6DC4937F5A2F13BA6C04048E68 +9C8DD9BE +D4BD20FBFE865FFEB07001D85E19 +50B7C532DD1EA037EAEC75B8134E3A8AC7DA207782FF3B90FD66B287F64B9E0D335FDCDFB1829109806CAC467A9B8A1B9D06D48761E88BA584D4D6F37BD55B4AEBC8A330F485E37C0FF8330ADE0E0600967B5237A10B608187DCF987C4F506B0F59997ECD9D6424A75018DBA7564A9A375BA9A11AFC0B0A9E8A83FD87979 +A5BB +2AC1C5CD057C550DF00E057DE42A07A7B6F98228EFA7AEF603 +3D8CB5B7 +42692BC7E12FCE405FFA4CCFA549 +11ACD0FF687E0BFAE507060721DBAA4829B1F251688A8A55CEEEEED2D4811ED6F3A6B9B7700AF63B310AD91B5A9D5C269B16E562834649FCD2AF1CBD6F01FA3364790BBCEED864CBC2FD61CE6A1CE350FD0129B637C3DBE937CF9370B4AC379DDB4CC99174A63FBA3CC6AC301A62FA2146A246DDEC6F5B7105A0BE6705BD +52B7 +E0F96E31 +F29F1F3BB6BD558F7F4B62DDE381 +2AA8D9488FA7F375553E1F781384CA1250928E5A1722E24B99E2F6FD84F82AE5AABC3598867CF973E91B0730733712086A4A0D5C4484EE62C2637F034ECD4938E087E1A0041DB88C3F09D0E8FBA875A403ACBCF42192A5D0394E03091D1073351E11E30D8B9980AFE6 +78761BC8 +5E7EC68B296C9DC4C494C0B30C +2D821084D70EB1B375B8F20B275F4BEAAB9569F1D40C +0C2C4432 +3BFE3FB87119EEFE8E15DF8A379C +22193172B167DC5A +3ABA3428 +CE743BF82F891D1D1F7DF913138A4EB3378E962EECDACECF27967CED957067FDDDBC +C79AD6DB681BEC2FA5755C13A4F38612BC16434C5894A5A1801FB5A399682F67792533A472B3 +6129F4FA2ECEDC3CA19C9A99DE7A4560AF42679FBEA8CFE0ABE8CB +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +%Defining font PSOwstdutchb +%!FontType1-1.0: PSOwstdutchb +10 dict begin +/FontName /PSOwstdutchb def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001000 0 0 0.001000 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 1 /C0032 put +dup 2 /C0037 put +dup 3 /C0040 put +dup 4 /C0041 put +dup 5 /C0043 put +dup 6 /C0045 put +dup 7 /C0046 put +dup 8 /C0047 put +dup 9 /C0048 put +dup 10 /C0049 put +dup 11 /C0050 put +dup 12 /C0051 put +dup 13 /C0052 put +dup 14 /C0053 put +dup 15 /C0054 put +dup 16 /C0056 put +dup 17 /C0065 put +dup 18 /C0066 put +dup 19 /C0078 put +dup 20 /C0080 put +dup 21 /C0084 put +dup 22 /C0097 put +dup 23 /C0100 put +dup 24 /C0101 put +dup 25 /C0102 put +dup 26 /C0105 put +dup 27 /C0108 put +dup 28 /C0110 put +dup 29 /C0111 put +dup 30 /C0112 put +dup 31 /C0114 put +dup 32 /C0115 put +dup 33 /C0116 put +dup 34 /C0118 put +dup 35 /C0120 put +readonly def +/FontBBox [-18 -207 764 696] readonly def +currentdict end +currentfile eexec +D9D66F633B846A989B9974B0179FC6CC445BC7C8A959A39A32E9DCE7FAEF17EE3BEC9F +50E1A6FCA651FC4B3769A0A91041557502E25A5D6180FE25A3D11BF079E1DF66E54EE9B7C229AF891739707A2A0EC140306B5E43E52B79BFB89E459E50 +6EC6F610A70775A31C460976C4F79449D86E57ACE491E5C6BF20CC4307B1DAF7630252 +E9AF8CFB69B50EDAE9D36A6104AFEF8832F920FD2346B2C7104CD11E3BEE999CFA9F5A +49DB3173EE48D1C82994237F360407B022E0B4 +502E94EA8B493651EF2D03F0B513D655047568325B512AE6 +6AC6F53F3848CF70DE25481CC65D8B1A5793AA +3C4282D111112BEE28AFCA7A3808D4444C4669CA +84EAAAF989219F51AB3476A1B0B5F2246BC306E6 +625C6679C417ED2A8E9BD010DE37D40265074C2684274B1821568DCA2EA47D261DDBD89B39A938 +20CF56E0D448A4BD79DA98E6 +5C015DD211D962A529 +48947FF0 +35E4C52FC29C24372BCF678DF44F +20E71854CCEF80E34AC29C9A96F7378677269E299707A863180C0B254B63BD83A32E922005F5510E88FA75DF971BD03DEFBC7C416C37C8121D91DAC8F73C98EEEFDCB27DC32C79736FC0156782ECF7874649500F24BFFDE29AAE9EF340EB0D97E42253DAD3A0EECC1EBB6230DE1DD10BD78B6E641BCB9812941ED4F56C60 +2E5C +2A8005CE5C9D21014EF58C5F4B94DE3A374EB90AE62FBC0606A4649C3F43ECBD94E71F036E851D54D5272EC589F3D24E4DD327FF3471C16EAE4D62EF46D4DC4112916DFF6C63CB1B69F9A4D89040C0B07AAC38455A25D90E1D8E3381F73856F2CDBD12F4D1 +BDC466BA +3A84AF5E600A1332E44907573C +2C7A684FB737EB8FF2ADA51CB14FB38D174185AA6DB43AFD1F00A33DC13B1137767EDAAD038264B134A42C5B0F82A70BD16CFE891570140526C79DDC90293C +C7F5608F +30B732B194BCB5DE5969C1D5C2 +AADF0E96A31863A7FC90A481EE5140956747A792F40205AD1C010084C0C4F5693D3FC72DCF19F7FE33E491B8B16F37B4139EF70680DA1C47C60AF8728F +19711220 +C80145409CC41844118130F18B +83D8AE0CA7A0460A99F0A7C0072386B3AC7C680FC1AA496DB674BA8B3FDC67AD5D65314438BFF8677C9ED2693679B5 +C97300B2 +2056B0A0B4C6CF198E3B0F301B +2962F17E44F27029686C19D62C129C17A90B5CEC5F913E +C4F04104 +65C3C0D31A23440A700391B201 +63EEB322EB00B651B31E02E5D25795679173D1C1171E53FF3064068FDF9836 +E8993B25 +40B169114F02758A1EF12E9489 +05E2D850A4253EAB6835F9FE65A9D5A87B112E27E8636B736838 +AFA6D5AD +E8361D85B37AB6DB0854B314CB +F25CBEF57AFE07680713008CD5C29D30D50685305A431C375173A2C7F8FD9919E99B040DC715EC1119AF198351531C181AF231B4E2F7D0DB6AC572E6E6B4F60E87112A8A0370CA2A4C00DD116E21D3 +E2BCF476 +06168FD7B810E046A71324819C +E85AD51CDA6ADC818817A9E1A35A0498B05BC3630CD26B793F550D7E4EF72B901E80CBB7CE037B63CC4E28766143B45B8EB9EE004AC7B26390B37988 +6751669F +20EDC4CF077B1E4D0733327021 +FB716289AD0210CA67AAF2AE10A021FBD27A27312542A9C40E2A17E4DFC85F3D03435E1D857C5A22B90E9A0237E7B4857C7CA462909D3265DC55E01D65B6396E22ECA942839CAE8057EEC8ED26EEA7E7827A2082 +976AA18C +BCB47699430ED14AFCABB511D068 +C9183BC0984DB8E27112DDE85164AF7C443B5808811284DFF28402D24E7D9B9F619689CC5A4ED0330A010193F856F92C4D71D07B299DFA90E7A78A8C03D9A9F2BD77CD0247E68BD3B2CEC4881DF04D65E13F12E3FDE41EB2BC6DDFA95056EE1F5349C603283A31BE0E4F1E35A867B713E9822D +BE2BA725 +6E644CF5C1AFC7DA94FFEE5B7F +B9F34A319295BE7674A94264B36EA4B05C7999FADB2C68D206380FBBC5FC67FFA4D80095F7206EC514C9BB7BC8BA7D765A6F93A5577A1221067E +8DDED60A +ABBC2591DBF7E068C7E569A1AF +7B997F72C064D899F76FF6E262747FB9028E166FDC39233666EB31C5EE24BC507849F05FD5A02B16EC9287AC7F1354C17B4DC278986F87BFE6220D04BE319E3B1C153854EFD7A765131FAC840CC44226F3CC6DBA3BE0 +F3A4EF4E +46F49CA47A203446248130B571D1 +DE58FC6F84489C9BABDFA3304A35C12988C99DD11D7D2E249796B2A0692163E201B6BD8406400F0BF96C840C23D0ABC2D8867DE98FDF3ACC8BDF533466C964154A45B92407BB9E3EA68656C244A3A93F787C756C8A02E5F4620648BDBD632FE5CA986488 +8EA720DA +3DF75D73024BCC6F2A30B9806C9E +41A58AEF06CFF618D0135AA98B2AD5ED48BF4AC2981EB82EB6336D66A60A746336CA47F163D3C3E02291DF9DFD20B0C096E7D07F4707DB9B10889FC0A8C7D761FFBD49EDA77E70D4B4DA1031303A2B1D23FABD83A426B44A16B6EE0FEFA6D87D9E6EF701911F2F0D7B4EB8275FA44D42A542CC032A70AD71092A +6607624A +F786A85160F19BA13C38A26341AA +5AC2DCE293096AF212CD373D351017F845B5EF867A4FD6B5957AC44FA1E5AEBE9C5DB2C9E531078A03B35C16737E9744E7471F4F1AB17087E5830BAED74AA360FE178E77DAF38C2889EE3E1D1A73DE298EFA629B47AC78EB6B184179DC1C0BAFC08AA993D2399215BD66D2 +0551297B +F4DCF238870D8B2A7CD90DA8F409 +92ED9BCE8E86BC59278C2040866EB5F1340AA89ED92825106DB5732E89588652B4CCC4818B364F62465375E3DECEF5BD0521EA670ADB1D33E197D3D10AA0EAAAB49375053B59BC3C4C49897864C6AD03007FC7BD8A491BD89F65FDE1C9AF53160CAE89AE50816AE02A22F5F3454A62DF2C5828A1CBDF326C5D76 +30FED591 +82724F213B5FA68953EC402B6B +D68E2A538B0E3771287A55B2801F9244CC8CAE302A8592210ABD05563BEF69AF7590EB6E3A70C746DE66401BA5C45215EDC89B4865D0A9278B90D5277F0D40E164D40FB107F80447EDC43C2D1FB097C58A587DF8A06B49CF9E49236E9D88D7 +5C517446 +FF9C7FD736A7322681F1DAB7A5A3 +2ADF28C10B09FAE3D5EAB9232089CCC8D745F4A159D1483FFA64A2D214D65EC8AC4E787C7012ECEB1A1C701F8A67EE25377601718DF14138E0BE283F424FC3F596BA469E0CEBBFE0247E33A62E7FAD905B88EF367004CFCA81CD6D33D74954CC84581F1D +B9CA9BBC +4B2EA57B67561BE855E80422F5 +B5B56F6DBEAAE762CA5DAFB08DB8B32AC32487E7653BC90AFEEE53401FFC341F6C4C80CAF6E0E1CE7FCEA0C634E2F040B0EBD5E753D10744983C330B92C4D1919B2BA481AF9EAA0AFE +807BDDE3 +41488B22DD7614FFDCC69BBDACAB +70E1FF20D741AA33611C3496BFE72ABF82D9AC4D3FD12790C7B2B30846DBFB0CEBA2C2AB92CA2E734F2A180F245EE9CC98029CDE7A384199323D8792099F4B65B18BC56EB07A49B6F73744C15D11744FB42EBC7AD37BA4888027941313D7B1FC0F6C053CD3B39C912AAB62124774B2DDA62A8CB895AA04725251928A96D4 +ADB5 +1313627E +54E14632 +3C12C954565C7E66D90735A7F819 +0B6D9FD1311C23B62410B28E6EAAECEE40A19362722B5456DAC83D0D6BD79A8FA0B3844F0952A21EEA27F66E7D2D826FBC6DA29456B1D798994C238AE5FAAFECCB00E0F0252A7E4A0EC69FFDC28EEB19DA473C403657BA7D3F038315DC3F71C5FC89ED15FE7815F95D703C15 +CB933DA6 +C626C4A8F0E44446A0484F1768 +7D2F39001AF51A055542DB58936EB219910047824C91C5A9DD3E8B63F6F08FD35B074F0C74DF3BF9395A314AAB405C627B5A65EAC0B74A27FFCA64B12B3075CF617B76013F7A340D50E1187FBB141D1CC735D22CBF42CDFDE153D74C +01D109B3 +0BBF19B187E3466A7CD744042B +565746C2BB9CDE033473CF4C737AE618D625F0F9F91B00C93AF9F39F0B0850434786B330D9EBFDF8138BA56A55DEBD0D32F43E5585F432ED638E121F33230109970F249393C86609377319688958D622644967846B39503D328104A8B5 +8A8DD4D2 +2C7C1785BB0DE35B3972074E1C +95F4A4B7CCB48A366BC3728F908BDB638320059C8C0931AAA3A971E413ADE9DDAF99D5BACBA3524E6265AB1A0EC17A92846E8B3643AD8B69DEDCDAB5C229A1EFB4FAC041CA564402C0D834DF84B2 +38011D41 +F1403E2043104B94E2616B55B1 +147525E3B9CEACE8C540D95470071B1C7D6E425E7B993E3C56003ABBA793882AAFF7B875E43E3154078F799026AAB795CF3D3CDD +6A114F0E +44D6FF9A54AEC3B0FC33242F0D9C +C02F1BEDF26B3DB13CD943E89808A002567979855F5A34F0C5A909E2AF93FC1F9D3914224B819E504A0D794BD6085B81BB34A9A838E1E462575BF36AEF7CE16034B104DE3F638E04F2AE1AE957DC037A6B8E3DB28C90F676E586AF55BFFA0A55CF1D19C9542090 +209778A9 +BB3814E17BB384101FF5B44B01 +6B77A1183FC2D49D94D88CF9F095B10E991BF3A4BCA3280C9178057E9A5CFE3722AE51C3C2AC713A9673CA245696FB16AE80D5F3100FD02576E11513FEE4D2E4E61703BFA594 +FCF18535 +E6E1951CC69968D36772E46654E6 +4BC9B2F3CF24B2A5394AF3B215ED17785DA3028BF98AC8B6907CED663A83B6E650C2505D7F5420AAB9A55D054D2A7BCCB8B48A37142E7B7150F8CC766171CFD7FCFF076BEE5FE3E90927183AF4CF3CD9B08674211FB66550643A0442A687588009E80964833C522972C14C1EC538EF4005 +82657860 +61ADD7DAED8B14CD5D8B2CF2ED +E51F8138897E61C12520D749C9FD8A7243BCA8B965238DB3E02156634FE2F8A8FCDFB4018CF5DFF8E0EB66E88D387C769CDC4A2052F2047754B596873592ABC87E7AC1392CE896CA36E6661179386D0EAB3758889390EB0482 +A1E00786 +B6AF852B4A4B760B32325A932A3B +571361319EBE7D548857A5A3681A90749FD5695F3464D727A5908DFCFA0BE08435D79F30013FDA46D15E24993B683567CE64286853AB4FE39FF13C672F8E58D60BB12DF9188E33542A3D93744FF492D5BB9074793FFF5D1F64044F8E667E1BE485BC202AD322FA8890D8C86E44B8D779705EF935C211D0B5B0 +52EF9B64 +CB6CFE41DA8716E69408E4FB3F +DA3303E61EFFFFF36BFE825373C81DFB7FC3B91263FA066978FFF9BDC6EE6B2A8AC29A6DD68504FAF59ABA4C88D4CD67550F4A9A491E12C40F97DD0728B758215DFF422D +1647D79E +91E0F645C8739F180D8B4B4675 +E598639F9248299E78C8C923B213BD7FE6BAC81D5F505D0F9711DF03560659DD4B2FC8E5F02AC79E45201974BF1B4B59B243498CD05E7981F35C7B7B0F0EC8BF06C00AFC08329E4BFF72C07FF12BA41362B140E4F2863197F76DC4F7 +CB8FF5D9 +A0E8EE8AD057906598B7EEAD5218 +376B67958A4A00C5E516EAC3782BA1A55B27567F817B8DFF9CE536295FFCF361F2D48FE9D653697AE1A2F5043D7E4C25095F7B068BDF701E25B6BC2D4F0CFC6C5DAF33BAFD1CF8D7F2C5A93D46BB9408B556E1E619596889CF5C7D0FA91E4215C5B14A5F6EFDDAD794C412B70B34C75697D412B42A2CCD0DBFF13679289F +09E4 +4BECCEF5B37875C11A10FFD4797F0AAFCF44192BD332 +A47F0E04 +4882BB262EFB8C255A43DC533A57 +5B32E6A925C2E4A5 +437FA609 +D735CAF3ED36815A7B8E282A4337B71F1FE85348261ED03634896EFB118D2278EAC5 +F7D1E8667E599B00380C47A14E3302352B917545BD035912CEB922DAADBFD2475EF10A41C9D7 +53043C02AF9644F19581C1C6872ABACE6F5D9E9AAA8724D826243E +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +%Defining font PSOsymclas +%!FontType1-1.0: PSOsymclas +10 dict begin +/FontName /PSOsymclas def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001000 0 0 0.001000 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 1 /C0069 put +readonly def +/FontBBox [106 45 775 713] readonly def +currentdict end +currentfile eexec +D9D66F633B846A989B9974B0179FC6CC445BC7C8A959A39A32E9DCE7FAEF17EE3BEC9F +50E1A6FCA651FC4B3769A0A91041557502E25A5D6180FE25A3D11BF079E1DF66E54EE9B7C229AF891739707A2A0EC140306B5E43E52B79BFB89E459E50 +6EC6F610A70775A31C460976C4F79449D86E57ACE491E5C6BF20CC4307B1DAF7630252 +E9AF8CFB69B50EDAE9D36A6104AFEF8832F920FD2346B2C7104CD11E3BEE999CFA9F5A +49DB3173EE48D1C82994237F360407B022E0B4 +502E94EA8B493651EF2D03F0B513D655047568325B512AE6 +6AC6F53F3848CF70DE25481CC65D8B1A5793AA +3C4282D111112BEE28AFCA7A3808D4444C4669CA +84EAAAF989219F51AB3476A1B0B5F2246BC306E6 +625C6679C417ED2A8E9BD010DE37D40265074C2684268F16195489648993B9C4D3B534FA887C +DEF605FA87B991F4D20A8F78DACE +5A54C070E03D5C59D9D2D3E06B09CEE028D68B62AB3AEC43C1DD20BA70D288597D9BD8E06818FF764EBAB436723988E8D7CA59E16D39032516BFC5D552ACDEEC6BE938BEF2F43CFFBC811C3626C4DF5F8CF080676520B51C60CEDAD1FE6C92D1431C702174CE517A8FA9377D075A0B6833DAB101DB65397F1419EF5F0016 +004F +6F0824F9657BB4F1C8F981709956865F6855EFAE +9242AD55 +91BBBEE163D844DDA894E13190C9 +2480439E4C71CADA +BD043A9B +A315CAF72652AA7FE6DB2E84D82A6111CE4DE90C02DA0AFFE2620922262A45AB4ED0 +EEC9F4520DD12703442F7D028D4526BD8B771E09FBE11B2749E2D3906894E8D4BFD3F379F14C +3C874F550606965E22FE487B247B5C2D06728490C8F2A3B588CDFC +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +/DPIx 1270 def /DPIy 1270 def +72 DPIx div 72 DPIy div neg scale +0 -13970 translate +1.00 1.00 scale +/wst:dutch12 12.00 /PSOwstdutch newFont def +/wst:dutch12b 12.00 /PSOwstdutchb newFont def +/wst:dutch14b 14.00 /PSOwstdutchb newFont def +/wst:dutch10 10.00 /PSOwstdutch newFont def +/wst:dutch14 14.00 /PSOwstdutch newFont def +%%IncludeResource: font Helvetica +/wst:helvps10 10.00 /Helvetica /wst:helvps ILEncoding 0 declareNFont def +/sym:clas10 10.00 /PSOsymclas newFont def +%%EndPageSetup +GS +0 13978 10801 13978 10801 0 0 0 clp +wst:dutch14 SF +0.00 0.00 0.00 1.00 setcmykcolor +<16212f2b212d220d010f011021291f24281d2d2601222a2d0115211d2e302d2529230116212f322a2d260118> 2207 558 0 7384 -1 s +<212d222a2d281d291f21> 7375 558 0 8593 -1 s +wst:dutch10 SF +<0b0c> 9346 13385 0 9522 -1 s +wst:helvps10 SF +<4e6574706572663a> 1322 13267 0 1949 -1 s +<205265766973696f6e20322e313b20436f7079726967687420> 1949 13267 4 3868 32 s +sym:clas10 SF +<01> 3868 13267 0 4019 -1 s +wst:helvps10 SF +<2031393933b131393935204865776c657474b15061636b61726420436f6d70616e79> 4019 13267 3 7133 32 s +wst:dutch14b SF +<111e1e181c171a23> 1271 1458 0 2283 -1 s +<0011> 2283 1458 1 2506 0 s +<07001318211e181f19001d1c001315> 2515 1458 3 4175 0 s +wst:dutch12 SF +<16212f2b212d22> 1271 2086 0 1980 -1 s +<00252e00292a2f002d3029002c30252f21002f2421002e1d2821002a2900161a001d2e00252f00252e00302920212d001b29253308001a24212e210020252222212d21291f212e002e2f212800222d2a28001d> 1980 2086 18 9531 0 s +<042b212d1f212531212005> 1271 2330 0 2308 -1 s +<00271d1f26002a22001f212d2f1d2529002e212d31251f212e002a22001b292533000700291d28212734002f2421002529212f2008001a242100271d1f26002a22002529212f20002e302b2b2a2d2f> 2308 2330 15 9531 0 s +<28211d292e> 1271 2575 0 1852 -1 s +<002f241d2f0029212f2e212d31212d0028302e2f001e21002d30290021332b27251f252f273400222a2d> 1852 2575 7 5358 0 s +<00211d1f24002529312a1f1d2f252a29002a220029212f2b212d220800172921002e25282b27210028211f241d> 5358 2575 7 9461 0 s +<36> 9461 2575 0 9531 -1 s +<29252e28> 1271 2820 0 1700 -1 s +<002f2a002e1d3121002f25282100252e002f2a00302e21002f24210035222a2d02002230291f2f252a291d27252f34002a22002f242100151907111719001f2a28281d2920002e242127270d> 1700 2820 14 8739 0 s +<03> 1398 3167 0 1504 -1 s +wst:dutch12b SF +<00191d1f00021a001a1c00030a000b000c0007070700130400171d001c182120181f22181f00061e000a0b100f0e> 1504 3167 12 5506 0 s +wst:dutch12 SF +<3224251f24> 1271 3513 0 1797 -1 s +<0032252727002d302900160029212f2e212d31212d2e002529002e301f1f212e2e252a2906002a2921001d222f212d002f2421002a2f24212d08001c> 1797 3513 11 6975 0 s +<2a30001f1d29002f242129002d30290016002e301f1f212e2e253121> 6949 3513 5 9531 0 s +<25292e2f1d291f212e> 1271 3758 0 2095 -1 s +<002a220029212f2b212d22002a29002a2f24212d002e342e2f21282e001e21222a2d2100241d31252923002f2a002d21072d30290029212f2e212d31212d00281d29301d2727340800142200342a30001d2d21> 2095 3758 14 9531 0 s +<302e252923> 1271 4003 0 1745 -1 s +<002e1f2d252b2f2e0600342a3000281d340032252e24002f2a0025292f2d2a20301f21> 1745 4003 6 4711 0 s +<002e2a2821002021271d342e001e212f322121290025292025312520301d27002529312a1f1d2f252a292e002a220029212f2b212d2208> 4711 4003 7 9531 0 s +<12332b212d252821292f1d2f252a29> 1271 4248 0 2801 -1 s +<00241d2e002e242a3229002f241d2f00161a00281d3400292a2f001e21001d1e2721002f2a0023212f002f2421002921332f0029212f2e212d31212d002d302929252923001e21222a2d21> 2801 4248 15 9531 0 s +<2f2421> 1271 4493 0 1561 -1 s +<002921332f0029212f2b212d22001f2a28212e001d272a292308000f002b1d302e21002a22002f322a002e211f2a29202e002a2d002e2a002e242a302720001e21002e302222251f2521292f08> 1561 4493 14 8481 0 s +<1422> 1271 4839 0 1422 -1 s +<00342a300032252e24002f2a002d3029001f2a291f302d2d21292f0025292e2f1d291f212e002a220029212f2b212d220600252f00252e0029211f212e2e1d2d34002f2a001f2a281e252921002f24210035222a2d02001d2920> 1422 4839 16 9531 0 s +<352e2f1d2d2f02> 1271 5084 0 1874 -1 s +<001f2a28281d29202e002a22002f242100151907111719001f2a28281d2920002e2421272708001729002f2421002e342e2f2128002d3029292529230029212f2e212d31212d00342a30> 1874 5084 12 9531 0 s +<322a302720> 1271 5329 0 1820 -1 s +<0021292f212d0e> 1820 5329 1 2407 0 s +<03> 1398 5676 0 1504 -1 s +wst:dutch12b SF +<00191d1f00021a001a1c00030a0b100f0e000a0b100f0f00070707000a0b100f0e05130400171d002021161f21000812001c182120181f22181f00061e00021a> 1504 5676 13 7340 0 s +wst:dutch12 SF +<3224251f24> 1271 6022 0 1797 -1 s +<0032252727002d30290016002b1d2d1d272721270025292e2f1d291f212e002a22002f24210029212f2e212d31212d0600211d1f2400321d252f252923001d2f002f2421252d002a3229002b2a2d2f002930281e212d08001a2421> 1797 6022 16 9531 0 s +<2b2a2d2f> 1271 6267 0 1653 -1 s +<002930281e212d2e00342a3000302e21001d2d2100302b002f2a00342a3006001e302f002f2421340028302e2f00281d2f1f24> 1653 6267 11 6441 0 s +<002f242a2e2100342a3000302e21002529002f2421002529312a1f1d2f252a29002a22> 6441 6267 7 9531 0 s +<29212f2b212d2208> 1271 6512 0 1986 -1 s +<0013> 1986 6512 1 2153 0 s +<2a2d0021331d282b27210600252200342a30001d272e2a00321d292f2120002f2a002d3029> 2145 6512 7 5371 0 s +<0016002b1d2d1d272721270029212f2b212d222e00042b212d241d2b2e002f2a0028211d2e302d21001d23232d21> 5371 6512 7 9461 0 s +<36> 9461 6512 0 9531 -1 s +<231d2f2100272a2a2b1e1d1f26002b212d222a2d281d291f210500342a3000322a302720002133211f302f21002f242100222a27272a32252923002529001d292a2f24212d00151907111719001f2a28281d2920> 1271 6757 11 9531 0 s +<2e242127270d> 1271 7002 0 1747 -1 s +<03> 1398 7348 0 1504 -1 s +wst:dutch12b SF +<00191d1f00021a001a1c00030a0b100f0e000a0b100f0f00070707000a0b100f0e05130400171d002021161f21000812001c18211e181f1900061e00021a000006140009000622000900061b000b0d09> 1504 7348 20 8874 0 s +wst:dutch12 SF +<1d2920> 1271 7695 0 1608 -1 s +<002f24212900281d29301d272734002f1d1e30271d2f21002f2421002d212e30272f2e0007001d222f212d001e21252923001f212d2f1d2529002f241d2f001d2727002f212e2f2e00222529252e242120001f272a2e212734002f2a> 1608 7695 15 9531 0 s +<2a2921> 1271 7940 0 1608 -1 s +<001d292a2f24212d08> 1608 7940 1 2422 0 s +<162a2921> 1271 8286 0 1771 -1 s +<002a22002f2421002e1f2d252b2f2e002b2d2a31252021200032252f240029212f2b212d2200241d3121001e212129002b2a2d2f2120002f2a00151907111719001f2a28281d292000222527212e00222a2d> 1771 8286 14 9531 0 s +<2f2421> 1271 8531 0 1561 -1 s +<000a0809002d2127211d2e2108000f2934001d2e2e252e2f1d291f21> 1561 8531 4 3911 0 s +<00342a3000282523242f001e21001d1e2721002f2a002b2d2a31252021002529002f241d2f001d2d211d00322a302720001e2100232d211d2f2734001d2b2b2d21> 3911 8531 13 9461 0 s +<36> 9461 8531 0 9531 -1 s +<1f251d2f2120> 1271 8776 0 1817 -1 s +<001e34002f2421001d302f242a2d2e08> 1817 8776 3 3211 0 s +GR +eop +%%PageTrailer +%%PageResources: font Helvetica +%%PageProcessColors: Black +%%PageCustomColors: +%%Trailer +Ileaf_6.0.0 /terminate get exec +%%Pages: 35 +%%DocumentNeededResources: font Courier +%%+ font Helvetica +%%DocumentSuppliedResources: +%%DocumentProcessColors: Black +%%DocumentCustomColors: +%%EOF diff --git a/doc/netserver.man b/doc/netserver.man new file mode 100644 index 0000000..556eecf --- /dev/null +++ b/doc/netserver.man @@ -0,0 +1,56 @@ +.TH netserver 1 "" +.SH NAME + +netserver \- a network performance benchmark server + +.SH SYNOPSIS + +.B netserver +[-p portnum] +[-n numcpus] + +.SH DESCRIPTION +.B Netserver +listens for connections from a +.C netperf +benchmark, and responds accordingly. +It can either be run from +.C inetd +or as a standalone daemon (with the -p flag). If run from +.C inetd +the -p option should not be used. + +.SS OPTIONS +.TP +.B \-h +Display a usage string, and exit. +.TP +.B \-n numcpus +Specify the number of CPU's in the system on those systems for which +netperf has no way to find the number of CPU's programatically. +.TP +.B \-p portnum +Listen on the specified port. +This is used when running as a standalone daemon. + +.SH BUGS +No known bugs at this time. If you think you have found a bug, please send email to Rick Jones . + +.SH SEE ALSO +.C netperf +.br +.I +Netperf: A Network Performance Benchmark +.br +http://www.netperf.org/ + +.SH AUTHORS +HP Information Networks Division - Networking Performance Team. +.br +Rick Jones +.br +Karen Choy HP IND +.br +Dave Shield (man pages) +.br +Others too numerous to mention here - see the ACKNWLDGMNTS file diff --git a/doc/texinfo.tex b/doc/texinfo.tex new file mode 100644 index 0000000..d5c8121 --- /dev/null +++ b/doc/texinfo.tex @@ -0,0 +1,6744 @@ +% texinfo.tex -- TeX macros to handle Texinfo files. +% +% Load plain if necessary, i.e., if running under initex. +\expandafter\ifx\csname fmtname\endcsname\relax\input plain\fi +% +\def\texinfoversion{2003-10-06.08} +% +% Copyright (C) 1985, 1986, 1988, 1990, 1991, 1992, 1993, 1994, 1995, +% 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. +% +% This texinfo.tex file is free software; you can redistribute it and/or +% modify it under the terms of the GNU General Public License as +% published by the Free Software Foundation; either version 2, or (at +% your option) any later version. +% +% This texinfo.tex file is distributed in the hope that it will be +% useful, but WITHOUT ANY WARRANTY; without even the implied warranty +% of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +% General Public License for more details. +% +% You should have received a copy of the GNU General Public License +% along with this texinfo.tex file; see the file COPYING. If not, write +% to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +% Boston, MA 02111-1307, USA. +% +% In other words, you are welcome to use, share and improve this program. +% You are forbidden to forbid anyone else to use, share and improve +% what you give them. Help stamp out software-hoarding! +% +% Please try the latest version of texinfo.tex before submitting bug +% reports; you can get the latest version from: +% ftp://ftp.gnu.org/gnu/texinfo/texinfo.tex +% (and all GNU mirrors, see http://www.gnu.org/order/ftp.html) +% ftp://tug.org/tex/texinfo.tex +% (and all CTAN mirrors, see http://www.ctan.org), +% and /home/gd/gnu/doc/texinfo.tex on the GNU machines. +% +% The GNU Texinfo home page is http://www.gnu.org/software/texinfo. +% +% The texinfo.tex in any given Texinfo distribution could well be out +% of date, so if that's what you're using, please check. +% +% Send bug reports to bug-texinfo@gnu.org. Please include including a +% complete document in each bug report with which we can reproduce the +% problem. Patches are, of course, greatly appreciated. +% +% To process a Texinfo manual with TeX, it's most reliable to use the +% texi2dvi shell script that comes with the distribution. For a simple +% manual foo.texi, however, you can get away with this: +% tex foo.texi +% texindex foo.?? +% tex foo.texi +% tex foo.texi +% dvips foo.dvi -o # or whatever; this makes foo.ps. +% The extra TeX runs get the cross-reference information correct. +% Sometimes one run after texindex suffices, and sometimes you need more +% than two; texi2dvi does it as many times as necessary. +% +% It is possible to adapt texinfo.tex for other languages, to some +% extent. You can get the existing language-specific files from the +% full Texinfo distribution. + +\message{Loading texinfo [version \texinfoversion]:} + +% If in a .fmt file, print the version number +% and turn on active characters that we couldn't do earlier because +% they might have appeared in the input file name. +\everyjob{\message{[Texinfo version \texinfoversion]}% + \catcode`+=\active \catcode`\_=\active} + +\message{Basics,} +\chardef\other=12 + +% We never want plain's \outer definition of \+ in Texinfo. +% For @tex, we can use \tabalign. +\let\+ = \relax + +% Save some plain tex macros whose names we will redefine. +\let\ptexb=\b +\let\ptexbullet=\bullet +\let\ptexc=\c +\let\ptexcomma=\, +\let\ptexdot=\. +\let\ptexdots=\dots +\let\ptexend=\end +\let\ptexequiv=\equiv +\let\ptexexclam=\! +\let\ptexgtr=> +\let\ptexhat=^ +\let\ptexi=\i +\let\ptexindent=\indent +\let\ptexnoindent=\noindent +\let\ptexlbrace=\{ +\let\ptexless=< +\let\ptexplus=+ +\let\ptexrbrace=\} +\let\ptexslash=\/ +\let\ptexstar=\* +\let\ptext=\t + +% If this character appears in an error message or help string, it +% starts a new line in the output. +\newlinechar = `^^J + +% Set up fixed words for English if not already set. +\ifx\putwordAppendix\undefined \gdef\putwordAppendix{Appendix}\fi +\ifx\putwordChapter\undefined \gdef\putwordChapter{Chapter}\fi +\ifx\putwordfile\undefined \gdef\putwordfile{file}\fi +\ifx\putwordin\undefined \gdef\putwordin{in}\fi +\ifx\putwordIndexIsEmpty\undefined \gdef\putwordIndexIsEmpty{(Index is empty)}\fi +\ifx\putwordIndexNonexistent\undefined \gdef\putwordIndexNonexistent{(Index is nonexistent)}\fi +\ifx\putwordInfo\undefined \gdef\putwordInfo{Info}\fi +\ifx\putwordInstanceVariableof\undefined \gdef\putwordInstanceVariableof{Instance Variable of}\fi +\ifx\putwordMethodon\undefined \gdef\putwordMethodon{Method on}\fi +\ifx\putwordNoTitle\undefined \gdef\putwordNoTitle{No Title}\fi +\ifx\putwordof\undefined \gdef\putwordof{of}\fi +\ifx\putwordon\undefined \gdef\putwordon{on}\fi +\ifx\putwordpage\undefined \gdef\putwordpage{page}\fi +\ifx\putwordsection\undefined \gdef\putwordsection{section}\fi +\ifx\putwordSection\undefined \gdef\putwordSection{Section}\fi +\ifx\putwordsee\undefined \gdef\putwordsee{see}\fi +\ifx\putwordSee\undefined \gdef\putwordSee{See}\fi +\ifx\putwordShortTOC\undefined \gdef\putwordShortTOC{Short Contents}\fi +\ifx\putwordTOC\undefined \gdef\putwordTOC{Table of Contents}\fi +% +\ifx\putwordMJan\undefined \gdef\putwordMJan{January}\fi +\ifx\putwordMFeb\undefined \gdef\putwordMFeb{February}\fi +\ifx\putwordMMar\undefined \gdef\putwordMMar{March}\fi +\ifx\putwordMApr\undefined \gdef\putwordMApr{April}\fi +\ifx\putwordMMay\undefined \gdef\putwordMMay{May}\fi +\ifx\putwordMJun\undefined \gdef\putwordMJun{June}\fi +\ifx\putwordMJul\undefined \gdef\putwordMJul{July}\fi +\ifx\putwordMAug\undefined \gdef\putwordMAug{August}\fi +\ifx\putwordMSep\undefined \gdef\putwordMSep{September}\fi +\ifx\putwordMOct\undefined \gdef\putwordMOct{October}\fi +\ifx\putwordMNov\undefined \gdef\putwordMNov{November}\fi +\ifx\putwordMDec\undefined \gdef\putwordMDec{December}\fi +% +\ifx\putwordDefmac\undefined \gdef\putwordDefmac{Macro}\fi +\ifx\putwordDefspec\undefined \gdef\putwordDefspec{Special Form}\fi +\ifx\putwordDefvar\undefined \gdef\putwordDefvar{Variable}\fi +\ifx\putwordDefopt\undefined \gdef\putwordDefopt{User Option}\fi +\ifx\putwordDeftypevar\undefined\gdef\putwordDeftypevar{Variable}\fi +\ifx\putwordDeffunc\undefined \gdef\putwordDeffunc{Function}\fi +\ifx\putwordDeftypefun\undefined\gdef\putwordDeftypefun{Function}\fi + +% In some macros, we cannot use the `\? notation---the left quote is +% in some cases the escape char. +\chardef\colonChar = `\: +\chardef\commaChar = `\, +\chardef\dotChar = `\. +\chardef\equalChar = `\= +\chardef\exclamChar= `\! +\chardef\questChar = `\? +\chardef\semiChar = `\; +\chardef\spaceChar = `\ % +\chardef\underChar = `\_ + +% Ignore a token. +% +\def\gobble#1{} + +% True if #1 is the empty string, i.e., called like `\ifempty{}'. +% +\def\ifempty#1{\ifemptyx #1\emptymarkA\emptymarkB}% +\def\ifemptyx#1#2\emptymarkB{\ifx #1\emptymarkA}% + +% Hyphenation fixes. +\hyphenation{ap-pen-dix} +\hyphenation{eshell} +\hyphenation{mini-buf-fer mini-buf-fers} +\hyphenation{time-stamp} +\hyphenation{white-space} + +% Margin to add to right of even pages, to left of odd pages. +\newdimen\bindingoffset +\newdimen\normaloffset +\newdimen\pagewidth \newdimen\pageheight + +% Sometimes it is convenient to have everything in the transcript file +% and nothing on the terminal. We don't just call \tracingall here, +% since that produces some useless output on the terminal. We also make +% some effort to order the tracing commands to reduce output in the log +% file; cf. trace.sty in LaTeX. +% +\def\gloggingall{\begingroup \globaldefs = 1 \loggingall \endgroup}% +\def\loggingall{% + \tracingstats2 + \tracingpages1 + \tracinglostchars2 % 2 gives us more in etex + \tracingparagraphs1 + \tracingoutput1 + \tracingmacros2 + \tracingrestores1 + \showboxbreadth\maxdimen \showboxdepth\maxdimen + \ifx\eTeXversion\undefined\else % etex gives us more logging + \tracingscantokens1 + \tracingifs1 + \tracinggroups1 + \tracingnesting2 + \tracingassigns1 + \fi + \tracingcommands3 % 3 gives us more in etex + \errorcontextlines\maxdimen +}% + +% add check for \lastpenalty to plain's definitions. If the last thing +% we did was a \nobreak, we don't want to insert more space. +% +\def\smallbreak{\ifnum\lastpenalty<10000\par\ifdim\lastskip<\smallskipamount + \removelastskip\penalty-50\smallskip\fi\fi} +\def\medbreak{\ifnum\lastpenalty<10000\par\ifdim\lastskip<\medskipamount + \removelastskip\penalty-100\medskip\fi\fi} +\def\bigbreak{\ifnum\lastpenalty<10000\par\ifdim\lastskip<\bigskipamount + \removelastskip\penalty-200\bigskip\fi\fi} + +% For @cropmarks command. +% Do @cropmarks to get crop marks. +% +\newif\ifcropmarks +\let\cropmarks = \cropmarkstrue +% +% Dimensions to add cropmarks at corners. +% Added by P. A. MacKay, 12 Nov. 1986 +% +\newdimen\outerhsize \newdimen\outervsize % set by the paper size routines +\newdimen\cornerlong \cornerlong=1pc +\newdimen\cornerthick \cornerthick=.3pt +\newdimen\topandbottommargin \topandbottommargin=.75in + +% Main output routine. +\chardef\PAGE = 255 +\output = {\onepageout{\pagecontents\PAGE}} + +\newbox\headlinebox +\newbox\footlinebox + +% \onepageout takes a vbox as an argument. Note that \pagecontents +% does insertions, but you have to call it yourself. +\def\onepageout#1{% + \ifcropmarks \hoffset=0pt \else \hoffset=\normaloffset \fi + % + \ifodd\pageno \advance\hoffset by \bindingoffset + \else \advance\hoffset by -\bindingoffset\fi + % + % Do this outside of the \shipout so @code etc. will be expanded in + % the headline as they should be, not taken literally (outputting ''code). + \setbox\headlinebox = \vbox{\let\hsize=\pagewidth \makeheadline}% + \setbox\footlinebox = \vbox{\let\hsize=\pagewidth \makefootline}% + % + {% + % Have to do this stuff outside the \shipout because we want it to + % take effect in \write's, yet the group defined by the \vbox ends + % before the \shipout runs. + % + \escapechar = `\\ % use backslash in output files. + \indexdummies % don't expand commands in the output. + \normalturnoffactive % \ in index entries must not stay \, e.g., if + % the page break happens to be in the middle of an example. + \shipout\vbox{% + % Do this early so pdf references go to the beginning of the page. + \ifpdfmakepagedest \pdfmkdest{\the\pageno}\fi + % + \ifcropmarks \vbox to \outervsize\bgroup + \hsize = \outerhsize + \vskip-\topandbottommargin + \vtop to0pt{% + \line{\ewtop\hfil\ewtop}% + \nointerlineskip + \line{% + \vbox{\moveleft\cornerthick\nstop}% + \hfill + \vbox{\moveright\cornerthick\nstop}% + }% + \vss}% + \vskip\topandbottommargin + \line\bgroup + \hfil % center the page within the outer (page) hsize. + \ifodd\pageno\hskip\bindingoffset\fi + \vbox\bgroup + \fi + % + \unvbox\headlinebox + \pagebody{#1}% + \ifdim\ht\footlinebox > 0pt + % Only leave this space if the footline is nonempty. + % (We lessened \vsize for it in \oddfootingxxx.) + % The \baselineskip=24pt in plain's \makefootline has no effect. + \vskip 2\baselineskip + \unvbox\footlinebox + \fi + % + \ifcropmarks + \egroup % end of \vbox\bgroup + \hfil\egroup % end of (centering) \line\bgroup + \vskip\topandbottommargin plus1fill minus1fill + \boxmaxdepth = \cornerthick + \vbox to0pt{\vss + \line{% + \vbox{\moveleft\cornerthick\nsbot}% + \hfill + \vbox{\moveright\cornerthick\nsbot}% + }% + \nointerlineskip + \line{\ewbot\hfil\ewbot}% + }% + \egroup % \vbox from first cropmarks clause + \fi + }% end of \shipout\vbox + }% end of group with \normalturnoffactive + \advancepageno + \ifnum\outputpenalty>-20000 \else\dosupereject\fi +} + +\newinsert\margin \dimen\margin=\maxdimen + +\def\pagebody#1{\vbox to\pageheight{\boxmaxdepth=\maxdepth #1}} +{\catcode`\@ =11 +\gdef\pagecontents#1{\ifvoid\topins\else\unvbox\topins\fi +% marginal hacks, juha@viisa.uucp (Juha Takala) +\ifvoid\margin\else % marginal info is present + \rlap{\kern\hsize\vbox to\z@{\kern1pt\box\margin \vss}}\fi +\dimen@=\dp#1 \unvbox#1 +\ifvoid\footins\else\vskip\skip\footins\footnoterule \unvbox\footins\fi +\ifr@ggedbottom \kern-\dimen@ \vfil \fi} +} + +% Here are the rules for the cropmarks. Note that they are +% offset so that the space between them is truly \outerhsize or \outervsize +% (P. A. MacKay, 12 November, 1986) +% +\def\ewtop{\vrule height\cornerthick depth0pt width\cornerlong} +\def\nstop{\vbox + {\hrule height\cornerthick depth\cornerlong width\cornerthick}} +\def\ewbot{\vrule height0pt depth\cornerthick width\cornerlong} +\def\nsbot{\vbox + {\hrule height\cornerlong depth\cornerthick width\cornerthick}} + +% Parse an argument, then pass it to #1. The argument is the rest of +% the input line (except we remove a trailing comment). #1 should be a +% macro which expects an ordinary undelimited TeX argument. +% +\def\parsearg#1{% + \let\next = #1% + \begingroup + \obeylines + \futurelet\temp\parseargx +} + +% If the next token is an obeyed space (from an @example environment or +% the like), remove it and recurse. Otherwise, we're done. +\def\parseargx{% + % \obeyedspace is defined far below, after the definition of \sepspaces. + \ifx\obeyedspace\temp + \expandafter\parseargdiscardspace + \else + \expandafter\parseargline + \fi +} + +% Remove a single space (as the delimiter token to the macro call). +{\obeyspaces % + \gdef\parseargdiscardspace {\futurelet\temp\parseargx}} + +{\obeylines % + \gdef\parseargline#1^^M{% + \endgroup % End of the group started in \parsearg. + % + % First remove any @c comment, then any @comment. + % Result of each macro is put in \toks0. + \argremovec #1\c\relax % + \expandafter\argremovecomment \the\toks0 \comment\relax % + % + % Call the caller's macro, saved as \next in \parsearg. + \expandafter\next\expandafter{\the\toks0}% + }% +} + +% Since all \c{,omment} does is throw away the argument, we can let TeX +% do that for us. The \relax here is matched by the \relax in the call +% in \parseargline; it could be more or less anything, its purpose is +% just to delimit the argument to the \c. +\def\argremovec#1\c#2\relax{\toks0 = {#1}} +\def\argremovecomment#1\comment#2\relax{\toks0 = {#1}} + +% \argremovec{,omment} might leave us with trailing spaces, though; e.g., +% @end itemize @c foo +% will have two active spaces as part of the argument with the +% `itemize'. Here we remove all active spaces from #1, and assign the +% result to \toks0. +% +% This loses if there are any *other* active characters besides spaces +% in the argument -- _ ^ +, for example -- since they get expanded. +% Fortunately, Texinfo does not define any such commands. (If it ever +% does, the catcode of the characters in questionwill have to be changed +% here.) But this means we cannot call \removeactivespaces as part of +% \argremovec{,omment}, since @c uses \parsearg, and thus the argument +% that \parsearg gets might well have any character at all in it. +% +\def\removeactivespaces#1{% + \begingroup + \ignoreactivespaces + \edef\temp{#1}% + \global\toks0 = \expandafter{\temp}% + \endgroup +} + +% Change the active space to expand to nothing. +% +\begingroup + \obeyspaces + \gdef\ignoreactivespaces{\obeyspaces\let =\empty} +\endgroup + + +\def\flushcr{\ifx\par\lisppar \def\next##1{}\else \let\next=\relax \fi \next} + +%% These are used to keep @begin/@end levels from running away +%% Call \inENV within environments (after a \begingroup) +\newif\ifENV \ENVfalse \def\inENV{\ifENV\relax\else\ENVtrue\fi} +\def\ENVcheck{% +\ifENV\errmessage{Still within an environment; press RETURN to continue} +\endgroup\fi} % This is not perfect, but it should reduce lossage + +% @begin foo is the same as @foo, for now. +\newhelp\EMsimple{Press RETURN to continue.} + +\outer\def\begin{\parsearg\beginxxx} + +\def\beginxxx #1{% +\expandafter\ifx\csname #1\endcsname\relax +{\errhelp=\EMsimple \errmessage{Undefined command @begin #1}}\else +\csname #1\endcsname\fi} + +% @end foo executes the definition of \Efoo. +% +\def\end{\parsearg\endxxx} +\def\endxxx #1{% + \removeactivespaces{#1}% + \edef\endthing{\the\toks0}% + % + \expandafter\ifx\csname E\endthing\endcsname\relax + \expandafter\ifx\csname \endthing\endcsname\relax + % There's no \foo, i.e., no ``environment'' foo. + \errhelp = \EMsimple + \errmessage{Undefined command `@end \endthing'}% + \else + \unmatchedenderror\endthing + \fi + \else + % Everything's ok; the right environment has been started. + \csname E\endthing\endcsname + \fi +} + +% There is an environment #1, but it hasn't been started. Give an error. +% +\def\unmatchedenderror#1{% + \errhelp = \EMsimple + \errmessage{This `@end #1' doesn't have a matching `@#1'}% +} + +% Define the control sequence \E#1 to give an unmatched @end error. +% +\def\defineunmatchedend#1{% + \expandafter\def\csname E#1\endcsname{\unmatchedenderror{#1}}% +} + + +%% Simple single-character @ commands + +% @@ prints an @ +% Kludge this until the fonts are right (grr). +\def\@{{\tt\char64}} + +% This is turned off because it was never documented +% and you can use @w{...} around a quote to suppress ligatures. +%% Define @` and @' to be the same as ` and ' +%% but suppressing ligatures. +%\def\`{{`}} +%\def\'{{'}} + +% Used to generate quoted braces. +\def\mylbrace {{\tt\char123}} +\def\myrbrace {{\tt\char125}} +\let\{=\mylbrace +\let\}=\myrbrace +\begingroup + % Definitions to produce \{ and \} commands for indices, + % and @{ and @} for the aux file. + \catcode`\{ = \other \catcode`\} = \other + \catcode`\[ = 1 \catcode`\] = 2 + \catcode`\! = 0 \catcode`\\ = \other + !gdef!lbracecmd[\{]% + !gdef!rbracecmd[\}]% + !gdef!lbraceatcmd[@{]% + !gdef!rbraceatcmd[@}]% +!endgroup + +% Accents: @, @dotaccent @ringaccent @ubaraccent @udotaccent +% Others are defined by plain TeX: @` @' @" @^ @~ @= @u @v @H. +\let\, = \c +\let\dotaccent = \. +\def\ringaccent#1{{\accent23 #1}} +\let\tieaccent = \t +\let\ubaraccent = \b +\let\udotaccent = \d + +% Other special characters: @questiondown @exclamdown +% Plain TeX defines: @AA @AE @O @OE @L (plus lowercase versions) @ss. +\def\questiondown{?`} +\def\exclamdown{!`} + +% Dotless i and dotless j, used for accents. +\def\imacro{i} +\def\jmacro{j} +\def\dotless#1{% + \def\temp{#1}% + \ifx\temp\imacro \ptexi + \else\ifx\temp\jmacro \j + \else \errmessage{@dotless can be used only with i or j}% + \fi\fi +} + +% Be sure we're in horizontal mode when doing a tie, since we make space +% equivalent to this in @example-like environments. Otherwise, a space +% at the beginning of a line will start with \penalty -- and +% since \penalty is valid in vertical mode, we'd end up putting the +% penalty on the vertical list instead of in the new paragraph. +{\catcode`@ = 11 + % Avoid using \@M directly, because that causes trouble + % if the definition is written into an index file. + \global\let\tiepenalty = \@M + \gdef\tie{\leavevmode\penalty\tiepenalty\ } +} + +% @: forces normal size whitespace following. +\def\:{\spacefactor=1000 } + +% @* forces a line break. +\def\*{\hfil\break\hbox{}\ignorespaces} + +% @/ allows a line break. +\let\/=\allowbreak + +% @. is an end-of-sentence period. +\def\.{.\spacefactor=3000 } + +% @! is an end-of-sentence bang. +\def\!{!\spacefactor=3000 } + +% @? is an end-of-sentence query. +\def\?{?\spacefactor=3000 } + +% @w prevents a word break. Without the \leavevmode, @w at the +% beginning of a paragraph, when TeX is still in vertical mode, would +% produce a whole line of output instead of starting the paragraph. +\def\w#1{\leavevmode\hbox{#1}} + +% @group ... @end group forces ... to be all on one page, by enclosing +% it in a TeX vbox. We use \vtop instead of \vbox to construct the box +% to keep its height that of a normal line. According to the rules for +% \topskip (p.114 of the TeXbook), the glue inserted is +% max (\topskip - \ht (first item), 0). If that height is large, +% therefore, no glue is inserted, and the space between the headline and +% the text is small, which looks bad. +% +% Another complication is that the group might be very large. This can +% cause the glue on the previous page to be unduly stretched, because it +% does not have much material. In this case, it's better to add an +% explicit \vfill so that the extra space is at the bottom. The +% threshold for doing this is if the group is more than \vfilllimit +% percent of a page (\vfilllimit can be changed inside of @tex). +% +\newbox\groupbox +\def\vfilllimit{0.7} +% +\def\group{\begingroup + \ifnum\catcode13=\active \else + \errhelp = \groupinvalidhelp + \errmessage{@group invalid in context where filling is enabled}% + \fi + % + % The \vtop we start below produces a box with normal height and large + % depth; thus, TeX puts \baselineskip glue before it, and (when the + % next line of text is done) \lineskip glue after it. (See p.82 of + % the TeXbook.) Thus, space below is not quite equal to space + % above. But it's pretty close. + \def\Egroup{% + \egroup % End the \vtop. + % \dimen0 is the vertical size of the group's box. + \dimen0 = \ht\groupbox \advance\dimen0 by \dp\groupbox + % \dimen2 is how much space is left on the page (more or less). + \dimen2 = \pageheight \advance\dimen2 by -\pagetotal + % if the group doesn't fit on the current page, and it's a big big + % group, force a page break. + \ifdim \dimen0 > \dimen2 + \ifdim \pagetotal < \vfilllimit\pageheight + \page + \fi + \fi + \copy\groupbox + \endgroup % End the \group. + }% + % + \setbox\groupbox = \vtop\bgroup + % We have to put a strut on the last line in case the @group is in + % the midst of an example, rather than completely enclosing it. + % Otherwise, the interline space between the last line of the group + % and the first line afterwards is too small. But we can't put the + % strut in \Egroup, since there it would be on a line by itself. + % Hence this just inserts a strut at the beginning of each line. + \everypar = {\strut}% + % + % Since we have a strut on every line, we don't need any of TeX's + % normal interline spacing. + \offinterlineskip + % + % OK, but now we have to do something about blank + % lines in the input in @example-like environments, which normally + % just turn into \lisppar, which will insert no space now that we've + % turned off the interline space. Simplest is to make them be an + % empty paragraph. + \ifx\par\lisppar + \edef\par{\leavevmode \par}% + % + % Reset ^^M's definition to new definition of \par. + \obeylines + \fi + % + % Do @comment since we are called inside an environment such as + % @example, where each end-of-line in the input causes an + % end-of-line in the output. We don't want the end-of-line after + % the `@group' to put extra space in the output. Since @group + % should appear on a line by itself (according to the Texinfo + % manual), we don't worry about eating any user text. + \comment +} +% +% TeX puts in an \escapechar (i.e., `@') at the beginning of the help +% message, so this ends up printing `@group can only ...'. +% +\newhelp\groupinvalidhelp{% +group can only be used in environments such as @example,^^J% +where each line of input produces a line of output.} + +% @need space-in-mils +% forces a page break if there is not space-in-mils remaining. + +\newdimen\mil \mil=0.001in + +\def\need{\parsearg\needx} + +% Old definition--didn't work. +%\def\needx #1{\par % +%% This method tries to make TeX break the page naturally +%% if the depth of the box does not fit. +%{\baselineskip=0pt% +%\vtop to #1\mil{\vfil}\kern -#1\mil\nobreak +%\prevdepth=-1000pt +%}} + +\def\needx#1{% + % Ensure vertical mode, so we don't make a big box in the middle of a + % paragraph. + \par + % + % If the @need value is less than one line space, it's useless. + \dimen0 = #1\mil + \dimen2 = \ht\strutbox + \advance\dimen2 by \dp\strutbox + \ifdim\dimen0 > \dimen2 + % + % Do a \strut just to make the height of this box be normal, so the + % normal leading is inserted relative to the preceding line. + % And a page break here is fine. + \vtop to #1\mil{\strut\vfil}% + % + % TeX does not even consider page breaks if a penalty added to the + % main vertical list is 10000 or more. But in order to see if the + % empty box we just added fits on the page, we must make it consider + % page breaks. On the other hand, we don't want to actually break the + % page after the empty box. So we use a penalty of 9999. + % + % There is an extremely small chance that TeX will actually break the + % page at this \penalty, if there are no other feasible breakpoints in + % sight. (If the user is using lots of big @group commands, which + % almost-but-not-quite fill up a page, TeX will have a hard time doing + % good page breaking, for example.) However, I could not construct an + % example where a page broke at this \penalty; if it happens in a real + % document, then we can reconsider our strategy. + \penalty9999 + % + % Back up by the size of the box, whether we did a page break or not. + \kern -#1\mil + % + % Do not allow a page break right after this kern. + \nobreak + \fi +} + +% @br forces paragraph break + +\let\br = \par + +% @dots{} output an ellipsis using the current font. +% We do .5em per period so that it has the same spacing in a typewriter +% font as three actual period characters. +% +\def\dots{% + \leavevmode + \hbox to 1.5em{% + \hskip 0pt plus 0.25fil minus 0.25fil + .\hss.\hss.% + \hskip 0pt plus 0.5fil minus 0.5fil + }% +} + +% @enddots{} is an end-of-sentence ellipsis. +% +\def\enddots{% + \leavevmode + \hbox to 2em{% + \hskip 0pt plus 0.25fil minus 0.25fil + .\hss.\hss.\hss.% + \hskip 0pt plus 0.5fil minus 0.5fil + }% + \spacefactor=3000 +} + +% @page forces the start of a new page. +% +\def\page{\par\vfill\supereject} + +% @exdent text.... +% outputs text on separate line in roman font, starting at standard page margin + +% This records the amount of indent in the innermost environment. +% That's how much \exdent should take out. +\newskip\exdentamount + +% This defn is used inside fill environments such as @defun. +\def\exdent{\parsearg\exdentyyy} +\def\exdentyyy #1{{\hfil\break\hbox{\kern -\exdentamount{\rm#1}}\hfil\break}} + +% This defn is used inside nofill environments such as @example. +\def\nofillexdent{\parsearg\nofillexdentyyy} +\def\nofillexdentyyy #1{{\advance \leftskip by -\exdentamount +\leftline{\hskip\leftskip{\rm#1}}}} + +% @inmargin{WHICH}{TEXT} puts TEXT in the WHICH margin next to the current +% paragraph. For more general purposes, use the \margin insertion +% class. WHICH is `l' or `r'. +% +\newskip\inmarginspacing \inmarginspacing=1cm +\def\strutdepth{\dp\strutbox} +% +\def\doinmargin#1#2{\strut\vadjust{% + \nobreak + \kern-\strutdepth + \vtop to \strutdepth{% + \baselineskip=\strutdepth + \vss + % if you have multiple lines of stuff to put here, you'll need to + % make the vbox yourself of the appropriate size. + \ifx#1l% + \llap{\ignorespaces #2\hskip\inmarginspacing}% + \else + \rlap{\hskip\hsize \hskip\inmarginspacing \ignorespaces #2}% + \fi + \null + }% +}} +\def\inleftmargin{\doinmargin l} +\def\inrightmargin{\doinmargin r} +% +% @inmargin{TEXT [, RIGHT-TEXT]} +% (if RIGHT-TEXT is given, use TEXT for left page, RIGHT-TEXT for right; +% else use TEXT for both). +% +\def\inmargin#1{\parseinmargin #1,,\finish} +\def\parseinmargin#1,#2,#3\finish{% not perfect, but better than nothing. + \setbox0 = \hbox{\ignorespaces #2}% + \ifdim\wd0 > 0pt + \def\lefttext{#1}% have both texts + \def\righttext{#2}% + \else + \def\lefttext{#1}% have only one text + \def\righttext{#1}% + \fi + % + \ifodd\pageno + \def\temp{\inrightmargin\righttext}% odd page -> outside is right margin + \else + \def\temp{\inleftmargin\lefttext}% + \fi + \temp +} + +% @include file insert text of that file as input. +% Allow normal characters that we make active in the argument (a file name). +\def\include{\begingroup + \catcode`\\=\other + \catcode`~=\other + \catcode`^=\other + \catcode`_=\other + \catcode`|=\other + \catcode`<=\other + \catcode`>=\other + \catcode`+=\other + \parsearg\includezzz} +% Restore active chars for included file. +\def\includezzz#1{\endgroup\begingroup + % Read the included file in a group so nested @include's work. + \def\thisfile{#1}% + \let\value=\expandablevalue + \input\thisfile +\endgroup} + +\def\thisfile{} + +% @center line +% outputs that line, centered. +% +\def\center{\parsearg\docenter} +\def\docenter#1{{% + \ifhmode \hfil\break \fi + \advance\hsize by -\leftskip + \advance\hsize by -\rightskip + \line{\hfil \ignorespaces#1\unskip \hfil}% + \ifhmode \break \fi +}} + +% @sp n outputs n lines of vertical space + +\def\sp{\parsearg\spxxx} +\def\spxxx #1{\vskip #1\baselineskip} + +% @comment ...line which is ignored... +% @c is the same as @comment +% @ignore ... @end ignore is another way to write a comment + +\def\comment{\begingroup \catcode`\^^M=\other% +\catcode`\@=\other \catcode`\{=\other \catcode`\}=\other% +\commentxxx} +{\catcode`\^^M=\other \gdef\commentxxx#1^^M{\endgroup}} + +\let\c=\comment + +% @paragraphindent NCHARS +% We'll use ems for NCHARS, close enough. +% NCHARS can also be the word `asis' or `none'. +% We cannot feasibly implement @paragraphindent asis, though. +% +\def\asisword{asis} % no translation, these are keywords +\def\noneword{none} +% +\def\paragraphindent{\parsearg\doparagraphindent} +\def\doparagraphindent#1{% + \def\temp{#1}% + \ifx\temp\asisword + \else + \ifx\temp\noneword + \defaultparindent = 0pt + \else + \defaultparindent = #1em + \fi + \fi + \parindent = \defaultparindent +} + +% @exampleindent NCHARS +% We'll use ems for NCHARS like @paragraphindent. +% It seems @exampleindent asis isn't necessary, but +% I preserve it to make it similar to @paragraphindent. +\def\exampleindent{\parsearg\doexampleindent} +\def\doexampleindent#1{% + \def\temp{#1}% + \ifx\temp\asisword + \else + \ifx\temp\noneword + \lispnarrowing = 0pt + \else + \lispnarrowing = #1em + \fi + \fi +} + +% @firstparagraphindent WORD +% If WORD is `none', then suppress indentation of the first paragraph +% after a section heading. If WORD is `insert', then do indent at such +% paragraphs. +% +% The paragraph indentation is suppressed or not by calling +% \suppressfirstparagraphindent, which the sectioning commands do. +% We switch the definition of this back and forth according to WORD. +% By default, we suppress indentation. +% +\def\suppressfirstparagraphindent{\dosuppressfirstparagraphindent} +\newdimen\currentparindent +% +\def\insertword{insert} +% +\def\firstparagraphindent{\parsearg\dofirstparagraphindent} +\def\dofirstparagraphindent#1{% + \def\temp{#1}% + \ifx\temp\noneword + \let\suppressfirstparagraphindent = \dosuppressfirstparagraphindent + \else\ifx\temp\insertword + \let\suppressfirstparagraphindent = \relax + \else + \errhelp = \EMsimple + \errmessage{Unknown @firstparagraphindent option `\temp'}% + \fi\fi +} + +% Here is how we actually suppress indentation. Redefine \everypar to +% \kern backwards by \parindent, and then reset itself to empty. +% +% We also make \indent itself not actually do anything until the next +% paragraph. +% +\gdef\dosuppressfirstparagraphindent{% + \gdef\indent{% + \restorefirstparagraphindent + \indent + }% + \gdef\noindent{% + \restorefirstparagraphindent + \noindent + }% + \global\everypar = {% + \kern -\parindent + \restorefirstparagraphindent + }% +} + +\gdef\restorefirstparagraphindent{% + \global \let \indent = \ptexindent + \global \let \noindent = \ptexnoindent + \global \everypar = {}% +} + + +% @asis just yields its argument. Used with @table, for example. +% +\def\asis#1{#1} + +% @math outputs its argument in math mode. +% We don't use $'s directly in the definition of \math because we need +% to set catcodes according to plain TeX first, to allow for subscripts, +% superscripts, special math chars, etc. +% +\let\implicitmath = $%$ font-lock fix +% +% One complication: _ usually means subscripts, but it could also mean +% an actual _ character, as in @math{@var{some_variable} + 1}. So make +% _ within @math be active (mathcode "8000), and distinguish by seeing +% if the current family is \slfam, which is what @var uses. +% +{\catcode\underChar = \active +\gdef\mathunderscore{% + \catcode\underChar=\active + \def_{\ifnum\fam=\slfam \_\else\sb\fi}% +}} +% +% Another complication: we want \\ (and @\) to output a \ character. +% FYI, plain.tex uses \\ as a temporary control sequence (why?), but +% this is not advertised and we don't care. Texinfo does not +% otherwise define @\. +% +% The \mathchar is class=0=ordinary, family=7=ttfam, position=5C=\. +\def\mathbackslash{\ifnum\fam=\ttfam \mathchar"075C \else\backslash \fi} +% +\def\math{% + \tex + \mathcode`\_="8000 \mathunderscore + \let\\ = \mathbackslash + \mathactive + \implicitmath\finishmath} +\def\finishmath#1{#1\implicitmath\Etex} + +% Some active characters (such as <) are spaced differently in math. +% We have to reset their definitions in case the @math was an +% argument to a command which set the catcodes (such as @item or @section). +% +{ + \catcode`^ = \active + \catcode`< = \active + \catcode`> = \active + \catcode`+ = \active + \gdef\mathactive{% + \let^ = \ptexhat + \let< = \ptexless + \let> = \ptexgtr + \let+ = \ptexplus + } +} + +% @bullet and @minus need the same treatment as @math, just above. +\def\bullet{\implicitmath\ptexbullet\implicitmath} +\def\minus{\implicitmath-\implicitmath} + +% @refill is a no-op. +\let\refill=\relax + +% If working on a large document in chapters, it is convenient to +% be able to disable indexing, cross-referencing, and contents, for test runs. +% This is done with @novalidate (before @setfilename). +% +\newif\iflinks \linkstrue % by default we want the aux files. +\let\novalidate = \linksfalse + +% @setfilename is done at the beginning of every texinfo file. +% So open here the files we need to have open while reading the input. +% This makes it possible to make a .fmt file for texinfo. +\def\setfilename{% + \iflinks + \readauxfile + \fi % \openindices needs to do some work in any case. + \openindices + \fixbackslash % Turn off hack to swallow `\input texinfo'. + \global\let\setfilename=\comment % Ignore extra @setfilename cmds. + % + % If texinfo.cnf is present on the system, read it. + % Useful for site-wide @afourpaper, etc. + % Just to be on the safe side, close the input stream before the \input. + \openin 1 texinfo.cnf + \ifeof1 \let\temp=\relax \else \def\temp{\input texinfo.cnf }\fi + \closein1 + \temp + % + \comment % Ignore the actual filename. +} + +% Called from \setfilename. +% +\def\openindices{% + \newindex{cp}% + \newcodeindex{fn}% + \newcodeindex{vr}% + \newcodeindex{tp}% + \newcodeindex{ky}% + \newcodeindex{pg}% +} + +% @bye. +\outer\def\bye{\pagealignmacro\tracingstats=1\ptexend} + + +\message{pdf,} +% adobe `portable' document format +\newcount\tempnum +\newcount\lnkcount +\newtoks\filename +\newcount\filenamelength +\newcount\pgn +\newtoks\toksA +\newtoks\toksB +\newtoks\toksC +\newtoks\toksD +\newbox\boxA +\newcount\countA +\newif\ifpdf +\newif\ifpdfmakepagedest + +\ifx\pdfoutput\undefined + \pdffalse + \let\pdfmkdest = \gobble + \let\pdfurl = \gobble + \let\endlink = \relax + \let\linkcolor = \relax + \let\pdfmakeoutlines = \relax +\else + \pdftrue + \pdfoutput = 1 + \input pdfcolor + \pdfcatalog{/PageMode /UseOutlines}% + \def\dopdfimage#1#2#3{% + \def\imagewidth{#2}% + \def\imageheight{#3}% + % without \immediate, pdftex seg faults when the same image is + % included twice. (Version 3.14159-pre-1.0-unofficial-20010704.) + \ifnum\pdftexversion < 14 + \immediate\pdfimage + \else + \immediate\pdfximage + \fi + \ifx\empty\imagewidth\else width \imagewidth \fi + \ifx\empty\imageheight\else height \imageheight \fi + \ifnum\pdftexversion<13 + #1.pdf% + \else + {#1.pdf}% + \fi + \ifnum\pdftexversion < 14 \else + \pdfrefximage \pdflastximage + \fi} + \def\pdfmkdest#1{{\normalturnoffactive \pdfdest name{#1} xyz}} + \def\pdfmkpgn#1{#1} + \let\linkcolor = \Blue % was Cyan, but that seems light? + \def\endlink{\Black\pdfendlink} + % Adding outlines to PDF; macros for calculating structure of outlines + % come from Petr Olsak + \def\expnumber#1{\expandafter\ifx\csname#1\endcsname\relax 0% + \else \csname#1\endcsname \fi} + \def\advancenumber#1{\tempnum=\expnumber{#1}\relax + \advance\tempnum by 1 + \expandafter\xdef\csname#1\endcsname{\the\tempnum}} + % + % #1 is the section text. #2 is the pdf expression for the number + % of subentries (or empty, for subsubsections). #3 is the node + % text, which might be empty if this toc entry had no + % corresponding node. #4 is the page number. + % + \def\dopdfoutline#1#2#3#4{% + % Generate a link to the node text if that exists; else, use the + % page number. We could generate a destination for the section + % text in the case where a section has no node, but it doesn't + % seem worthwhile, since most documents are normally structured. + \def\pdfoutlinedest{#3}% + \ifx\pdfoutlinedest\empty \def\pdfoutlinedest{#4}\fi + % + \pdfoutline goto name{\pdfmkpgn{\pdfoutlinedest}}#2{#1}% + } + % + \def\pdfmakeoutlines{% + \openin 1 \jobname.toc + \ifeof 1\else\begingroup + \closein 1 + % Thanh's hack / proper braces in bookmarks + \edef\mylbrace{\iftrue \string{\else}\fi}\let\{=\mylbrace + \edef\myrbrace{\iffalse{\else\string}\fi}\let\}=\myrbrace + % + % Read toc silently, to get counts of subentries for \pdfoutline. + \def\numchapentry##1##2##3##4{\def\thischapnum{##2}}% + \def\numsecentry##1##2##3##4{% + \def\thissecnum{##2}% + \advancenumber{chap\thischapnum}}% + \def\numsubsecentry##1##2##3##4{% + \def\thissubsecnum{##2}% + \advancenumber{sec\thissecnum}}% + \def\numsubsubsecentry##1##2##3##4{\advancenumber{subsec\thissubsecnum}}% + % + % use \def rather than \let here because we redefine \chapentry et + % al. a second time, below. + \def\appentry{\numchapentry}% + \def\appsecentry{\numsecentry}% + \def\appsubsecentry{\numsubsecentry}% + \def\appsubsubsecentry{\numsubsubsecentry}% + \def\unnchapentry{\numchapentry}% + \def\unnsecentry{\numsecentry}% + \def\unnsubsecentry{\numsubsecentry}% + \def\unnsubsubsecentry{\numsubsubsecentry}% + \input \jobname.toc + % + % Read toc second time, this time actually producing the outlines. + % The `-' means take the \expnumber as the absolute number of + % subentries, which we calculated on our first read of the .toc above. + % + % We use the node names as the destinations. + \def\numchapentry##1##2##3##4{% + \dopdfoutline{##1}{count-\expnumber{chap##2}}{##3}{##4}}% + \def\numsecentry##1##2##3##4{% + \dopdfoutline{##1}{count-\expnumber{sec##2}}{##3}{##4}}% + \def\numsubsecentry##1##2##3##4{% + \dopdfoutline{##1}{count-\expnumber{subsec##2}}{##3}{##4}}% + \def\numsubsubsecentry##1##2##3##4{% count is always zero + \dopdfoutline{##1}{}{##3}{##4}}% + % + % Make special characters normal for writing to the pdf file. + \indexnofonts + \turnoffactive + \input \jobname.toc + \endgroup\fi + } + % + \def\makelinks #1,{% + \def\params{#1}\def\E{END}% + \ifx\params\E + \let\nextmakelinks=\relax + \else + \let\nextmakelinks=\makelinks + \ifnum\lnkcount>0,\fi + \picknum{#1}% + \startlink attr{/Border [0 0 0]} + goto name{\pdfmkpgn{\the\pgn}}% + \linkcolor #1% + \advance\lnkcount by 1% + \endlink + \fi + \nextmakelinks + } + \def\picknum#1{\expandafter\pn#1} + \def\pn#1{% + \def\p{#1}% + \ifx\p\lbrace + \let\nextpn=\ppn + \else + \let\nextpn=\ppnn + \def\first{#1} + \fi + \nextpn + } + \def\ppn#1{\pgn=#1\gobble} + \def\ppnn{\pgn=\first} + \def\pdfmklnk#1{\lnkcount=0\makelinks #1,END,} + \def\addtokens#1#2{\edef\addtoks{\noexpand#1={\the#1#2}}\addtoks} + \def\skipspaces#1{\def\PP{#1}\def\D{|}% + \ifx\PP\D\let\nextsp\relax + \else\let\nextsp\skipspaces + \ifx\p\space\else\addtokens{\filename}{\PP}% + \advance\filenamelength by 1 + \fi + \fi + \nextsp} + \def\getfilename#1{\filenamelength=0\expandafter\skipspaces#1|\relax} + \ifnum\pdftexversion < 14 + \let \startlink \pdfannotlink + \else + \let \startlink \pdfstartlink + \fi + \def\pdfurl#1{% + \begingroup + \normalturnoffactive\def\@{@}% + \let\value=\expandablevalue + \leavevmode\Red + \startlink attr{/Border [0 0 0]}% + user{/Subtype /Link /A << /S /URI /URI (#1) >>}% + % #1 + \endgroup} + \def\pdfgettoks#1.{\setbox\boxA=\hbox{\toksA={#1.}\toksB={}\maketoks}} + \def\addtokens#1#2{\edef\addtoks{\noexpand#1={\the#1#2}}\addtoks} + \def\adn#1{\addtokens{\toksC}{#1}\global\countA=1\let\next=\maketoks} + \def\poptoks#1#2|ENDTOKS|{\let\first=#1\toksD={#1}\toksA={#2}} + \def\maketoks{% + \expandafter\poptoks\the\toksA|ENDTOKS| + \ifx\first0\adn0 + \else\ifx\first1\adn1 \else\ifx\first2\adn2 \else\ifx\first3\adn3 + \else\ifx\first4\adn4 \else\ifx\first5\adn5 \else\ifx\first6\adn6 + \else\ifx\first7\adn7 \else\ifx\first8\adn8 \else\ifx\first9\adn9 + \else + \ifnum0=\countA\else\makelink\fi + \ifx\first.\let\next=\done\else + \let\next=\maketoks + \addtokens{\toksB}{\the\toksD} + \ifx\first,\addtokens{\toksB}{\space}\fi + \fi + \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi + \next} + \def\makelink{\addtokens{\toksB}% + {\noexpand\pdflink{\the\toksC}}\toksC={}\global\countA=0} + \def\pdflink#1{% + \startlink attr{/Border [0 0 0]} goto name{\pdfmkpgn{#1}} + \linkcolor #1\endlink} + \def\done{\edef\st{\global\noexpand\toksA={\the\toksB}}\st} +\fi % \ifx\pdfoutput + + +\message{fonts,} +% Font-change commands. + +% Texinfo sort of supports the sans serif font style, which plain TeX does not. +% So we set up a \sf analogous to plain's \rm, etc. +\newfam\sffam +\def\sf{\fam=\sffam \tensf} +\let\li = \sf % Sometimes we call it \li, not \sf. + +% We don't need math for this one. +\def\ttsl{\tenttsl} + +% Default leading. +\newdimen\textleading \textleading = 13.2pt + +% Set the baselineskip to #1, and the lineskip and strut size +% correspondingly. There is no deep meaning behind these magic numbers +% used as factors; they just match (closely enough) what Knuth defined. +% +\def\lineskipfactor{.08333} +\def\strutheightpercent{.70833} +\def\strutdepthpercent {.29167} +% +\def\setleading#1{% + \normalbaselineskip = #1\relax + \normallineskip = \lineskipfactor\normalbaselineskip + \normalbaselines + \setbox\strutbox =\hbox{% + \vrule width0pt height\strutheightpercent\baselineskip + depth \strutdepthpercent \baselineskip + }% +} + +% Set the font macro #1 to the font named #2, adding on the +% specified font prefix (normally `cm'). +% #3 is the font's design size, #4 is a scale factor +\def\setfont#1#2#3#4{\font#1=\fontprefix#2#3 scaled #4} + +% Use cm as the default font prefix. +% To specify the font prefix, you must define \fontprefix +% before you read in texinfo.tex. +\ifx\fontprefix\undefined +\def\fontprefix{cm} +\fi +% Support font families that don't use the same naming scheme as CM. +\def\rmshape{r} +\def\rmbshape{bx} %where the normal face is bold +\def\bfshape{b} +\def\bxshape{bx} +\def\ttshape{tt} +\def\ttbshape{tt} +\def\ttslshape{sltt} +\def\itshape{ti} +\def\itbshape{bxti} +\def\slshape{sl} +\def\slbshape{bxsl} +\def\sfshape{ss} +\def\sfbshape{ss} +\def\scshape{csc} +\def\scbshape{csc} + +\newcount\mainmagstep +\ifx\bigger\relax + % not really supported. + \mainmagstep=\magstep1 + \setfont\textrm\rmshape{12}{1000} + \setfont\texttt\ttshape{12}{1000} +\else + \mainmagstep=\magstephalf + \setfont\textrm\rmshape{10}{\mainmagstep} + \setfont\texttt\ttshape{10}{\mainmagstep} +\fi +% Instead of cmb10, you may want to use cmbx10. +% cmbx10 is a prettier font on its own, but cmb10 +% looks better when embedded in a line with cmr10 +% (in Bob's opinion). +\setfont\textbf\bfshape{10}{\mainmagstep} +\setfont\textit\itshape{10}{\mainmagstep} +\setfont\textsl\slshape{10}{\mainmagstep} +\setfont\textsf\sfshape{10}{\mainmagstep} +\setfont\textsc\scshape{10}{\mainmagstep} +\setfont\textttsl\ttslshape{10}{\mainmagstep} +\font\texti=cmmi10 scaled \mainmagstep +\font\textsy=cmsy10 scaled \mainmagstep + +% A few fonts for @defun, etc. +\setfont\defbf\bxshape{10}{\magstep1} %was 1314 +\setfont\deftt\ttshape{10}{\magstep1} +\def\df{\let\tentt=\deftt \let\tenbf = \defbf \bf} + +% Fonts for indices, footnotes, small examples (9pt). +\setfont\smallrm\rmshape{9}{1000} +\setfont\smalltt\ttshape{9}{1000} +\setfont\smallbf\bfshape{10}{900} +\setfont\smallit\itshape{9}{1000} +\setfont\smallsl\slshape{9}{1000} +\setfont\smallsf\sfshape{9}{1000} +\setfont\smallsc\scshape{10}{900} +\setfont\smallttsl\ttslshape{10}{900} +\font\smalli=cmmi9 +\font\smallsy=cmsy9 + +% Fonts for small examples (8pt). +\setfont\smallerrm\rmshape{8}{1000} +\setfont\smallertt\ttshape{8}{1000} +\setfont\smallerbf\bfshape{10}{800} +\setfont\smallerit\itshape{8}{1000} +\setfont\smallersl\slshape{8}{1000} +\setfont\smallersf\sfshape{8}{1000} +\setfont\smallersc\scshape{10}{800} +\setfont\smallerttsl\ttslshape{10}{800} +\font\smalleri=cmmi8 +\font\smallersy=cmsy8 + +% Fonts for title page: +\setfont\titlerm\rmbshape{12}{\magstep3} +\setfont\titleit\itbshape{10}{\magstep4} +\setfont\titlesl\slbshape{10}{\magstep4} +\setfont\titlett\ttbshape{12}{\magstep3} +\setfont\titlettsl\ttslshape{10}{\magstep4} +\setfont\titlesf\sfbshape{17}{\magstep1} +\let\titlebf=\titlerm +\setfont\titlesc\scbshape{10}{\magstep4} +\font\titlei=cmmi12 scaled \magstep3 +\font\titlesy=cmsy10 scaled \magstep4 +\def\authorrm{\secrm} +\def\authortt{\sectt} + +% Chapter (and unnumbered) fonts (17.28pt). +\setfont\chaprm\rmbshape{12}{\magstep2} +\setfont\chapit\itbshape{10}{\magstep3} +\setfont\chapsl\slbshape{10}{\magstep3} +\setfont\chaptt\ttbshape{12}{\magstep2} +\setfont\chapttsl\ttslshape{10}{\magstep3} +\setfont\chapsf\sfbshape{17}{1000} +\let\chapbf=\chaprm +\setfont\chapsc\scbshape{10}{\magstep3} +\font\chapi=cmmi12 scaled \magstep2 +\font\chapsy=cmsy10 scaled \magstep3 + +% Section fonts (14.4pt). +\setfont\secrm\rmbshape{12}{\magstep1} +\setfont\secit\itbshape{10}{\magstep2} +\setfont\secsl\slbshape{10}{\magstep2} +\setfont\sectt\ttbshape{12}{\magstep1} +\setfont\secttsl\ttslshape{10}{\magstep2} +\setfont\secsf\sfbshape{12}{\magstep1} +\let\secbf\secrm +\setfont\secsc\scbshape{10}{\magstep2} +\font\seci=cmmi12 scaled \magstep1 +\font\secsy=cmsy10 scaled \magstep2 + +% Subsection fonts (13.15pt). +\setfont\ssecrm\rmbshape{12}{\magstephalf} +\setfont\ssecit\itbshape{10}{1315} +\setfont\ssecsl\slbshape{10}{1315} +\setfont\ssectt\ttbshape{12}{\magstephalf} +\setfont\ssecttsl\ttslshape{10}{1315} +\setfont\ssecsf\sfbshape{12}{\magstephalf} +\let\ssecbf\ssecrm +\setfont\ssecsc\scbshape{10}{\magstep1} +\font\sseci=cmmi12 scaled \magstephalf +\font\ssecsy=cmsy10 scaled 1315 +% The smallcaps and symbol fonts should actually be scaled \magstep1.5, +% but that is not a standard magnification. + +% In order for the font changes to affect most math symbols and letters, +% we have to define the \textfont of the standard families. Since +% texinfo doesn't allow for producing subscripts and superscripts except +% in the main text, we don't bother to reset \scriptfont and +% \scriptscriptfont (which would also require loading a lot more fonts). +% +\def\resetmathfonts{% + \textfont0=\tenrm \textfont1=\teni \textfont2=\tensy + \textfont\itfam=\tenit \textfont\slfam=\tensl \textfont\bffam=\tenbf + \textfont\ttfam=\tentt \textfont\sffam=\tensf +} + +% The font-changing commands redefine the meanings of \tenSTYLE, instead +% of just \STYLE. We do this so that font changes will continue to work +% in math mode, where it is the current \fam that is relevant in most +% cases, not the current font. Plain TeX does \def\bf{\fam=\bffam +% \tenbf}, for example. By redefining \tenbf, we obviate the need to +% redefine \bf itself. +\def\textfonts{% + \let\tenrm=\textrm \let\tenit=\textit \let\tensl=\textsl + \let\tenbf=\textbf \let\tentt=\texttt \let\smallcaps=\textsc + \let\tensf=\textsf \let\teni=\texti \let\tensy=\textsy \let\tenttsl=\textttsl + \resetmathfonts \setleading{\textleading}} +\def\titlefonts{% + \let\tenrm=\titlerm \let\tenit=\titleit \let\tensl=\titlesl + \let\tenbf=\titlebf \let\tentt=\titlett \let\smallcaps=\titlesc + \let\tensf=\titlesf \let\teni=\titlei \let\tensy=\titlesy + \let\tenttsl=\titlettsl + \resetmathfonts \setleading{25pt}} +\def\titlefont#1{{\titlefonts\rm #1}} +\def\chapfonts{% + \let\tenrm=\chaprm \let\tenit=\chapit \let\tensl=\chapsl + \let\tenbf=\chapbf \let\tentt=\chaptt \let\smallcaps=\chapsc + \let\tensf=\chapsf \let\teni=\chapi \let\tensy=\chapsy \let\tenttsl=\chapttsl + \resetmathfonts \setleading{19pt}} +\def\secfonts{% + \let\tenrm=\secrm \let\tenit=\secit \let\tensl=\secsl + \let\tenbf=\secbf \let\tentt=\sectt \let\smallcaps=\secsc + \let\tensf=\secsf \let\teni=\seci \let\tensy=\secsy \let\tenttsl=\secttsl + \resetmathfonts \setleading{16pt}} +\def\subsecfonts{% + \let\tenrm=\ssecrm \let\tenit=\ssecit \let\tensl=\ssecsl + \let\tenbf=\ssecbf \let\tentt=\ssectt \let\smallcaps=\ssecsc + \let\tensf=\ssecsf \let\teni=\sseci \let\tensy=\ssecsy \let\tenttsl=\ssecttsl + \resetmathfonts \setleading{15pt}} +\let\subsubsecfonts = \subsecfonts % Maybe make sssec fonts scaled magstephalf? +\def\smallfonts{% + \let\tenrm=\smallrm \let\tenit=\smallit \let\tensl=\smallsl + \let\tenbf=\smallbf \let\tentt=\smalltt \let\smallcaps=\smallsc + \let\tensf=\smallsf \let\teni=\smalli \let\tensy=\smallsy + \let\tenttsl=\smallttsl + \resetmathfonts \setleading{10.5pt}} +\def\smallerfonts{% + \let\tenrm=\smallerrm \let\tenit=\smallerit \let\tensl=\smallersl + \let\tenbf=\smallerbf \let\tentt=\smallertt \let\smallcaps=\smallersc + \let\tensf=\smallersf \let\teni=\smalleri \let\tensy=\smallersy + \let\tenttsl=\smallerttsl + \resetmathfonts \setleading{9.5pt}} + +% Set the fonts to use with the @small... environments. +\let\smallexamplefonts = \smallfonts + +% About \smallexamplefonts. If we use \smallfonts (9pt), @smallexample +% can fit this many characters: +% 8.5x11=86 smallbook=72 a4=90 a5=69 +% If we use \smallerfonts (8pt), then we can fit this many characters: +% 8.5x11=90+ smallbook=80 a4=90+ a5=77 +% For me, subjectively, the few extra characters that fit aren't worth +% the additional smallness of 8pt. So I'm making the default 9pt. +% +% By the way, for comparison, here's what fits with @example (10pt): +% 8.5x11=71 smallbook=60 a4=75 a5=58 +% +% I wish we used A4 paper on this side of the Atlantic. +% +% --karl, 24jan03. + + +% Set up the default fonts, so we can use them for creating boxes. +% +\textfonts + +% Define these so they can be easily changed for other fonts. +\def\angleleft{$\langle$} +\def\angleright{$\rangle$} + +% Count depth in font-changes, for error checks +\newcount\fontdepth \fontdepth=0 + +% Fonts for short table of contents. +\setfont\shortcontrm\rmshape{12}{1000} +\setfont\shortcontbf\bxshape{12}{1000} +\setfont\shortcontsl\slshape{12}{1000} +\setfont\shortconttt\ttshape{12}{1000} + +%% Add scribe-like font environments, plus @l for inline lisp (usually sans +%% serif) and @ii for TeX italic + +% \smartitalic{ARG} outputs arg in italics, followed by an italic correction +% unless the following character is such as not to need one. +\def\smartitalicx{\ifx\next,\else\ifx\next-\else\ifx\next.\else + \ptexslash\fi\fi\fi} +\def\smartslanted#1{{\ifusingtt\ttsl\sl #1}\futurelet\next\smartitalicx} +\def\smartitalic#1{{\ifusingtt\ttsl\it #1}\futurelet\next\smartitalicx} + +\let\i=\smartitalic +\let\var=\smartslanted +\let\dfn=\smartslanted +\let\emph=\smartitalic +\let\cite=\smartslanted + +\def\b#1{{\bf #1}} +\let\strong=\b + +% We can't just use \exhyphenpenalty, because that only has effect at +% the end of a paragraph. Restore normal hyphenation at the end of the +% group within which \nohyphenation is presumably called. +% +\def\nohyphenation{\hyphenchar\font = -1 \aftergroup\restorehyphenation} +\def\restorehyphenation{\hyphenchar\font = `- } + +% Set sfcode to normal for the chars that usually have another value. +% Can't use plain's \frenchspacing because it uses the `\x notation, and +% sometimes \x has an active definition that messes things up. +% +\catcode`@=11 + \def\frenchspacing{% + \sfcode\dotChar =\@m \sfcode\questChar=\@m \sfcode\exclamChar=\@m + \sfcode\colonChar=\@m \sfcode\semiChar =\@m \sfcode\commaChar =\@m + } +\catcode`@=\other + +\def\t#1{% + {\tt \rawbackslash \frenchspacing #1}% + \null +} +\let\ttfont=\t +\def\samp#1{`\tclose{#1}'\null} +\setfont\keyrm\rmshape{8}{1000} +\font\keysy=cmsy9 +\def\key#1{{\keyrm\textfont2=\keysy \leavevmode\hbox{% + \raise0.4pt\hbox{\angleleft}\kern-.08em\vtop{% + \vbox{\hrule\kern-0.4pt + \hbox{\raise0.4pt\hbox{\vphantom{\angleleft}}#1}}% + \kern-0.4pt\hrule}% + \kern-.06em\raise0.4pt\hbox{\angleright}}}} +% The old definition, with no lozenge: +%\def\key #1{{\ttsl \nohyphenation \uppercase{#1}}\null} +\def\ctrl #1{{\tt \rawbackslash \hat}#1} + +% @file, @option are the same as @samp. +\let\file=\samp +\let\option=\samp + +% @code is a modification of @t, +% which makes spaces the same size as normal in the surrounding text. +\def\tclose#1{% + {% + % Change normal interword space to be same as for the current font. + \spaceskip = \fontdimen2\font + % + % Switch to typewriter. + \tt + % + % But `\ ' produces the large typewriter interword space. + \def\ {{\spaceskip = 0pt{} }}% + % + % Turn off hyphenation. + \nohyphenation + % + \rawbackslash + \frenchspacing + #1% + }% + \null +} + +% We *must* turn on hyphenation at `-' and `_' in \code. +% Otherwise, it is too hard to avoid overfull hboxes +% in the Emacs manual, the Library manual, etc. + +% Unfortunately, TeX uses one parameter (\hyphenchar) to control +% both hyphenation at - and hyphenation within words. +% We must therefore turn them both off (\tclose does that) +% and arrange explicitly to hyphenate at a dash. +% -- rms. +{ + \catcode`\-=\active + \catcode`\_=\active + % + \global\def\code{\begingroup + \catcode`\-=\active \let-\codedash + \catcode`\_=\active \let_\codeunder + \codex + } + % + % If we end up with any active - characters when handling the index, + % just treat them as a normal -. + \global\def\indexbreaks{\catcode`\-=\active \let-\realdash} +} + +\def\realdash{-} +\def\codedash{-\discretionary{}{}{}} +\def\codeunder{% + % this is all so @math{@code{var_name}+1} can work. In math mode, _ + % is "active" (mathcode"8000) and \normalunderscore (or \char95, etc.) + % will therefore expand the active definition of _, which is us + % (inside @code that is), therefore an endless loop. + \ifusingtt{\ifmmode + \mathchar"075F % class 0=ordinary, family 7=ttfam, pos 0x5F=_. + \else\normalunderscore \fi + \discretionary{}{}{}}% + {\_}% +} +\def\codex #1{\tclose{#1}\endgroup} + +% @kbd is like @code, except that if the argument is just one @key command, +% then @kbd has no effect. + +% @kbdinputstyle -- arg is `distinct' (@kbd uses slanted tty font always), +% `example' (@kbd uses ttsl only inside of @example and friends), +% or `code' (@kbd uses normal tty font always). +\def\kbdinputstyle{\parsearg\kbdinputstylexxx} +\def\kbdinputstylexxx#1{% + \def\arg{#1}% + \ifx\arg\worddistinct + \gdef\kbdexamplefont{\ttsl}\gdef\kbdfont{\ttsl}% + \else\ifx\arg\wordexample + \gdef\kbdexamplefont{\ttsl}\gdef\kbdfont{\tt}% + \else\ifx\arg\wordcode + \gdef\kbdexamplefont{\tt}\gdef\kbdfont{\tt}% + \else + \errhelp = \EMsimple + \errmessage{Unknown @kbdinputstyle option `\arg'}% + \fi\fi\fi +} +\def\worddistinct{distinct} +\def\wordexample{example} +\def\wordcode{code} + +% Default is `distinct.' +\kbdinputstyle distinct + +\def\xkey{\key} +\def\kbdfoo#1#2#3\par{\def\one{#1}\def\three{#3}\def\threex{??}% +\ifx\one\xkey\ifx\threex\three \key{#2}% +\else{\tclose{\kbdfont\look}}\fi +\else{\tclose{\kbdfont\look}}\fi} + +% For @url, @env, @command quotes seem unnecessary, so use \code. +\let\url=\code +\let\env=\code +\let\command=\code + +% @uref (abbreviation for `urlref') takes an optional (comma-separated) +% second argument specifying the text to display and an optional third +% arg as text to display instead of (rather than in addition to) the url +% itself. First (mandatory) arg is the url. Perhaps eventually put in +% a hypertex \special here. +% +\def\uref#1{\douref #1,,,\finish} +\def\douref#1,#2,#3,#4\finish{\begingroup + \unsepspaces + \pdfurl{#1}% + \setbox0 = \hbox{\ignorespaces #3}% + \ifdim\wd0 > 0pt + \unhbox0 % third arg given, show only that + \else + \setbox0 = \hbox{\ignorespaces #2}% + \ifdim\wd0 > 0pt + \ifpdf + \unhbox0 % PDF: 2nd arg given, show only it + \else + \unhbox0\ (\code{#1})% DVI: 2nd arg given, show both it and url + \fi + \else + \code{#1}% only url given, so show it + \fi + \fi + \endlink +\endgroup} + +% rms does not like angle brackets --karl, 17may97. +% So now @email is just like @uref, unless we are pdf. +% +%\def\email#1{\angleleft{\tt #1}\angleright} +\ifpdf + \def\email#1{\doemail#1,,\finish} + \def\doemail#1,#2,#3\finish{\begingroup + \unsepspaces + \pdfurl{mailto:#1}% + \setbox0 = \hbox{\ignorespaces #2}% + \ifdim\wd0>0pt\unhbox0\else\code{#1}\fi + \endlink + \endgroup} +\else + \let\email=\uref +\fi + +% Check if we are currently using a typewriter font. Since all the +% Computer Modern typewriter fonts have zero interword stretch (and +% shrink), and it is reasonable to expect all typewriter fonts to have +% this property, we can check that font parameter. +% +\def\ifmonospace{\ifdim\fontdimen3\font=0pt } + +% Typeset a dimension, e.g., `in' or `pt'. The only reason for the +% argument is to make the input look right: @dmn{pt} instead of @dmn{}pt. +% +\def\dmn#1{\thinspace #1} + +\def\kbd#1{\def\look{#1}\expandafter\kbdfoo\look??\par} + +% @l was never documented to mean ``switch to the Lisp font'', +% and it is not used as such in any manual I can find. We need it for +% Polish suppressed-l. --karl, 22sep96. +%\def\l#1{{\li #1}\null} + +% Explicit font changes: @r, @sc, undocumented @ii. +\def\r#1{{\rm #1}} % roman font +\def\sc#1{{\smallcaps#1}} % smallcaps font +\def\ii#1{{\it #1}} % italic font + +% @acronym downcases the argument and prints in smallcaps. +\def\acronym#1{{\smallcaps \lowercase{#1}}} + +% @pounds{} is a sterling sign. +\def\pounds{{\it\$}} + +% @registeredsymbol - R in a circle. For now, only works in text size; +% we'd have to redo the font mechanism to change the \scriptstyle and +% \scriptscriptstyle font sizes to make it look right in headings. +% Adapted from the plain.tex definition of \copyright. +% +\def\registeredsymbol{% + $^{{\ooalign{\hfil\raise.07ex\hbox{$\scriptstyle\rm R$}\hfil\crcr\Orb}}% + }$% +} + + +\message{page headings,} + +\newskip\titlepagetopglue \titlepagetopglue = 1.5in +\newskip\titlepagebottomglue \titlepagebottomglue = 2pc + +% First the title page. Must do @settitle before @titlepage. +\newif\ifseenauthor +\newif\iffinishedtitlepage + +% Do an implicit @contents or @shortcontents after @end titlepage if the +% user says @setcontentsaftertitlepage or @setshortcontentsaftertitlepage. +% +\newif\ifsetcontentsaftertitlepage + \let\setcontentsaftertitlepage = \setcontentsaftertitlepagetrue +\newif\ifsetshortcontentsaftertitlepage + \let\setshortcontentsaftertitlepage = \setshortcontentsaftertitlepagetrue + +\def\shorttitlepage{\parsearg\shorttitlepagezzz} +\def\shorttitlepagezzz #1{\begingroup\hbox{}\vskip 1.5in \chaprm \centerline{#1}% + \endgroup\page\hbox{}\page} + +\def\titlepage{\begingroup \parindent=0pt \textfonts + \let\subtitlerm=\tenrm + \def\subtitlefont{\subtitlerm \normalbaselineskip = 13pt \normalbaselines}% + % + \def\authorfont{\authorrm \normalbaselineskip = 16pt \normalbaselines + \let\tt=\authortt}% + % + % Leave some space at the very top of the page. + \vglue\titlepagetopglue + % + % Now you can print the title using @title. + \def\title{\parsearg\titlezzz}% + \def\titlezzz##1{\leftline{\titlefonts\rm ##1} + % print a rule at the page bottom also. + \finishedtitlepagefalse + \vskip4pt \hrule height 4pt width \hsize \vskip4pt}% + % No rule at page bottom unless we print one at the top with @title. + \finishedtitlepagetrue + % + % Now you can put text using @subtitle. + \def\subtitle{\parsearg\subtitlezzz}% + \def\subtitlezzz##1{{\subtitlefont \rightline{##1}}}% + % + % @author should come last, but may come many times. + \def\author{\parsearg\authorzzz}% + \def\authorzzz##1{\ifseenauthor\else\vskip 0pt plus 1filll\seenauthortrue\fi + {\authorfont \leftline{##1}}}% + % + % Most title ``pages'' are actually two pages long, with space + % at the top of the second. We don't want the ragged left on the second. + \let\oldpage = \page + \def\page{% + \iffinishedtitlepage\else + \finishtitlepage + \fi + \oldpage + \let\page = \oldpage + \hbox{}}% +% \def\page{\oldpage \hbox{}} +} + +\def\Etitlepage{% + \iffinishedtitlepage\else + \finishtitlepage + \fi + % It is important to do the page break before ending the group, + % because the headline and footline are only empty inside the group. + % If we use the new definition of \page, we always get a blank page + % after the title page, which we certainly don't want. + \oldpage + \endgroup + % + % Need this before the \...aftertitlepage checks so that if they are + % in effect the toc pages will come out with page numbers. + \HEADINGSon + % + % If they want short, they certainly want long too. + \ifsetshortcontentsaftertitlepage + \shortcontents + \contents + \global\let\shortcontents = \relax + \global\let\contents = \relax + \fi + % + \ifsetcontentsaftertitlepage + \contents + \global\let\contents = \relax + \global\let\shortcontents = \relax + \fi +} + +\def\finishtitlepage{% + \vskip4pt \hrule height 2pt width \hsize + \vskip\titlepagebottomglue + \finishedtitlepagetrue +} + +%%% Set up page headings and footings. + +\let\thispage=\folio + +\newtoks\evenheadline % headline on even pages +\newtoks\oddheadline % headline on odd pages +\newtoks\evenfootline % footline on even pages +\newtoks\oddfootline % footline on odd pages + +% Now make Tex use those variables +\headline={{\textfonts\rm \ifodd\pageno \the\oddheadline + \else \the\evenheadline \fi}} +\footline={{\textfonts\rm \ifodd\pageno \the\oddfootline + \else \the\evenfootline \fi}\HEADINGShook} +\let\HEADINGShook=\relax + +% Commands to set those variables. +% For example, this is what @headings on does +% @evenheading @thistitle|@thispage|@thischapter +% @oddheading @thischapter|@thispage|@thistitle +% @evenfooting @thisfile|| +% @oddfooting ||@thisfile + +\def\evenheading{\parsearg\evenheadingxxx} +\def\oddheading{\parsearg\oddheadingxxx} +\def\everyheading{\parsearg\everyheadingxxx} + +\def\evenfooting{\parsearg\evenfootingxxx} +\def\oddfooting{\parsearg\oddfootingxxx} +\def\everyfooting{\parsearg\everyfootingxxx} + +{\catcode`\@=0 % + +\gdef\evenheadingxxx #1{\evenheadingyyy #1@|@|@|@|\finish} +\gdef\evenheadingyyy #1@|#2@|#3@|#4\finish{% +\global\evenheadline={\rlap{\centerline{#2}}\line{#1\hfil#3}}} + +\gdef\oddheadingxxx #1{\oddheadingyyy #1@|@|@|@|\finish} +\gdef\oddheadingyyy #1@|#2@|#3@|#4\finish{% +\global\oddheadline={\rlap{\centerline{#2}}\line{#1\hfil#3}}} + +\gdef\everyheadingxxx#1{\oddheadingxxx{#1}\evenheadingxxx{#1}}% + +\gdef\evenfootingxxx #1{\evenfootingyyy #1@|@|@|@|\finish} +\gdef\evenfootingyyy #1@|#2@|#3@|#4\finish{% +\global\evenfootline={\rlap{\centerline{#2}}\line{#1\hfil#3}}} + +\gdef\oddfootingxxx #1{\oddfootingyyy #1@|@|@|@|\finish} +\gdef\oddfootingyyy #1@|#2@|#3@|#4\finish{% + \global\oddfootline = {\rlap{\centerline{#2}}\line{#1\hfil#3}}% + % + % Leave some space for the footline. Hopefully ok to assume + % @evenfooting will not be used by itself. + \global\advance\pageheight by -\baselineskip + \global\advance\vsize by -\baselineskip +} + +\gdef\everyfootingxxx#1{\oddfootingxxx{#1}\evenfootingxxx{#1}} +% +}% unbind the catcode of @. + +% @headings double turns headings on for double-sided printing. +% @headings single turns headings on for single-sided printing. +% @headings off turns them off. +% @headings on same as @headings double, retained for compatibility. +% @headings after turns on double-sided headings after this page. +% @headings doubleafter turns on double-sided headings after this page. +% @headings singleafter turns on single-sided headings after this page. +% By default, they are off at the start of a document, +% and turned `on' after @end titlepage. + +\def\headings #1 {\csname HEADINGS#1\endcsname} + +\def\HEADINGSoff{ +\global\evenheadline={\hfil} \global\evenfootline={\hfil} +\global\oddheadline={\hfil} \global\oddfootline={\hfil}} +\HEADINGSoff +% When we turn headings on, set the page number to 1. +% For double-sided printing, put current file name in lower left corner, +% chapter name on inside top of right hand pages, document +% title on inside top of left hand pages, and page numbers on outside top +% edge of all pages. +\def\HEADINGSdouble{ +\global\pageno=1 +\global\evenfootline={\hfil} +\global\oddfootline={\hfil} +\global\evenheadline={\line{\folio\hfil\thistitle}} +\global\oddheadline={\line{\thischapter\hfil\folio}} +\global\let\contentsalignmacro = \chapoddpage +} +\let\contentsalignmacro = \chappager + +% For single-sided printing, chapter title goes across top left of page, +% page number on top right. +\def\HEADINGSsingle{ +\global\pageno=1 +\global\evenfootline={\hfil} +\global\oddfootline={\hfil} +\global\evenheadline={\line{\thischapter\hfil\folio}} +\global\oddheadline={\line{\thischapter\hfil\folio}} +\global\let\contentsalignmacro = \chappager +} +\def\HEADINGSon{\HEADINGSdouble} + +\def\HEADINGSafter{\let\HEADINGShook=\HEADINGSdoublex} +\let\HEADINGSdoubleafter=\HEADINGSafter +\def\HEADINGSdoublex{% +\global\evenfootline={\hfil} +\global\oddfootline={\hfil} +\global\evenheadline={\line{\folio\hfil\thistitle}} +\global\oddheadline={\line{\thischapter\hfil\folio}} +\global\let\contentsalignmacro = \chapoddpage +} + +\def\HEADINGSsingleafter{\let\HEADINGShook=\HEADINGSsinglex} +\def\HEADINGSsinglex{% +\global\evenfootline={\hfil} +\global\oddfootline={\hfil} +\global\evenheadline={\line{\thischapter\hfil\folio}} +\global\oddheadline={\line{\thischapter\hfil\folio}} +\global\let\contentsalignmacro = \chappager +} + +% Subroutines used in generating headings +% This produces Day Month Year style of output. +% Only define if not already defined, in case a txi-??.tex file has set +% up a different format (e.g., txi-cs.tex does this). +\ifx\today\undefined +\def\today{% + \number\day\space + \ifcase\month + \or\putwordMJan\or\putwordMFeb\or\putwordMMar\or\putwordMApr + \or\putwordMMay\or\putwordMJun\or\putwordMJul\or\putwordMAug + \or\putwordMSep\or\putwordMOct\or\putwordMNov\or\putwordMDec + \fi + \space\number\year} +\fi + +% @settitle line... specifies the title of the document, for headings. +% It generates no output of its own. +\def\thistitle{\putwordNoTitle} +\def\settitle{\parsearg\settitlezzz} +\def\settitlezzz #1{\gdef\thistitle{#1}} + + +\message{tables,} +% Tables -- @table, @ftable, @vtable, @item(x), @kitem(x), @xitem(x). + +% default indentation of table text +\newdimen\tableindent \tableindent=.8in +% default indentation of @itemize and @enumerate text +\newdimen\itemindent \itemindent=.3in +% margin between end of table item and start of table text. +\newdimen\itemmargin \itemmargin=.1in + +% used internally for \itemindent minus \itemmargin +\newdimen\itemmax + +% Note @table, @vtable, and @vtable define @item, @itemx, etc., with +% these defs. +% They also define \itemindex +% to index the item name in whatever manner is desired (perhaps none). + +\newif\ifitemxneedsnegativevskip + +\def\itemxpar{\par\ifitemxneedsnegativevskip\nobreak\vskip-\parskip\nobreak\fi} + +\def\internalBitem{\smallbreak \parsearg\itemzzz} +\def\internalBitemx{\itemxpar \parsearg\itemzzz} + +\def\internalBxitem "#1"{\def\xitemsubtopix{#1} \smallbreak \parsearg\xitemzzz} +\def\internalBxitemx "#1"{\def\xitemsubtopix{#1} \itemxpar \parsearg\xitemzzz} + +\def\internalBkitem{\smallbreak \parsearg\kitemzzz} +\def\internalBkitemx{\itemxpar \parsearg\kitemzzz} + +\def\kitemzzz #1{\dosubind {kw}{\code{#1}}{for {\bf \lastfunction}}% + \itemzzz {#1}} + +\def\xitemzzz #1{\dosubind {kw}{\code{#1}}{for {\bf \xitemsubtopic}}% + \itemzzz {#1}} + +\def\itemzzz #1{\begingroup % + \advance\hsize by -\rightskip + \advance\hsize by -\tableindent + \setbox0=\hbox{\itemfont{#1}}% + \itemindex{#1}% + \nobreak % This prevents a break before @itemx. + % + % If the item text does not fit in the space we have, put it on a line + % by itself, and do not allow a page break either before or after that + % line. We do not start a paragraph here because then if the next + % command is, e.g., @kindex, the whatsit would get put into the + % horizontal list on a line by itself, resulting in extra blank space. + \ifdim \wd0>\itemmax + % + % Make this a paragraph so we get the \parskip glue and wrapping, + % but leave it ragged-right. + \begingroup + \advance\leftskip by-\tableindent + \advance\hsize by\tableindent + \advance\rightskip by0pt plus1fil + \leavevmode\unhbox0\par + \endgroup + % + % We're going to be starting a paragraph, but we don't want the + % \parskip glue -- logically it's part of the @item we just started. + \nobreak \vskip-\parskip + % + % Stop a page break at the \parskip glue coming up. (Unfortunately + % we can't prevent a possible page break at the following + % \baselineskip glue.) However, if what follows is an environment + % such as @example, there will be no \parskip glue; then + % the negative vskip we just would cause the example and the item to + % crash together. So we use this bizarre value of 10001 as a signal + % to \aboveenvbreak to insert \parskip glue after all. + % (Possibly there are other commands that could be followed by + % @example which need the same treatment, but not section titles; or + % maybe section titles are the only special case and they should be + % penalty 10001...) + \penalty 10001 + \endgroup + \itemxneedsnegativevskipfalse + \else + % The item text fits into the space. Start a paragraph, so that the + % following text (if any) will end up on the same line. + \noindent + % Do this with kerns and \unhbox so that if there is a footnote in + % the item text, it can migrate to the main vertical list and + % eventually be printed. + \nobreak\kern-\tableindent + \dimen0 = \itemmax \advance\dimen0 by \itemmargin \advance\dimen0 by -\wd0 + \unhbox0 + \nobreak\kern\dimen0 + \endgroup + \itemxneedsnegativevskiptrue + \fi +} + +\def\item{\errmessage{@item while not in a table}} +\def\itemx{\errmessage{@itemx while not in a table}} +\def\kitem{\errmessage{@kitem while not in a table}} +\def\kitemx{\errmessage{@kitemx while not in a table}} +\def\xitem{\errmessage{@xitem while not in a table}} +\def\xitemx{\errmessage{@xitemx while not in a table}} + +% Contains a kludge to get @end[description] to work. +\def\description{\tablez{\dontindex}{1}{}{}{}{}} + +% @table, @ftable, @vtable. +\def\table{\begingroup\inENV\obeylines\obeyspaces\tablex} +{\obeylines\obeyspaces% +\gdef\tablex #1^^M{% +\tabley\dontindex#1 \endtabley}} + +\def\ftable{\begingroup\inENV\obeylines\obeyspaces\ftablex} +{\obeylines\obeyspaces% +\gdef\ftablex #1^^M{% +\tabley\fnitemindex#1 \endtabley +\def\Eftable{\endgraf\afterenvbreak\endgroup}% +\let\Etable=\relax}} + +\def\vtable{\begingroup\inENV\obeylines\obeyspaces\vtablex} +{\obeylines\obeyspaces% +\gdef\vtablex #1^^M{% +\tabley\vritemindex#1 \endtabley +\def\Evtable{\endgraf\afterenvbreak\endgroup}% +\let\Etable=\relax}} + +\def\dontindex #1{} +\def\fnitemindex #1{\doind {fn}{\code{#1}}}% +\def\vritemindex #1{\doind {vr}{\code{#1}}}% + +{\obeyspaces % +\gdef\tabley#1#2 #3 #4 #5 #6 #7\endtabley{\endgroup% +\tablez{#1}{#2}{#3}{#4}{#5}{#6}}} + +\def\tablez #1#2#3#4#5#6{% +\aboveenvbreak % +\begingroup % +\def\Edescription{\Etable}% Necessary kludge. +\let\itemindex=#1% +\ifnum 0#3>0 \advance \leftskip by #3\mil \fi % +\ifnum 0#4>0 \tableindent=#4\mil \fi % +\ifnum 0#5>0 \advance \rightskip by #5\mil \fi % +\def\itemfont{#2}% +\itemmax=\tableindent % +\advance \itemmax by -\itemmargin % +\advance \leftskip by \tableindent % +\exdentamount=\tableindent +\parindent = 0pt +\parskip = \smallskipamount +\ifdim \parskip=0pt \parskip=2pt \fi% +\def\Etable{\endgraf\afterenvbreak\endgroup}% +\let\item = \internalBitem % +\let\itemx = \internalBitemx % +\let\kitem = \internalBkitem % +\let\kitemx = \internalBkitemx % +\let\xitem = \internalBxitem % +\let\xitemx = \internalBxitemx % +} + +% This is the counter used by @enumerate, which is really @itemize + +\newcount \itemno + +\def\itemize{\parsearg\itemizezzz} + +\def\itemizezzz #1{% + \begingroup % ended by the @end itemize + \itemizey {#1}{\Eitemize} +} + +\def\itemizey#1#2{% + \aboveenvbreak + \itemmax=\itemindent + \advance\itemmax by -\itemmargin + \advance\leftskip by \itemindent + \exdentamount=\itemindent + \parindent=0pt + \parskip=\smallskipamount + \ifdim\parskip=0pt \parskip=2pt \fi + \def#2{\endgraf\afterenvbreak\endgroup}% + \def\itemcontents{#1}% + % @itemize with no arg is equivalent to @itemize @bullet. + \ifx\itemcontents\empty\def\itemcontents{\bullet}\fi + \let\item=\itemizeitem +} + +% \splitoff TOKENS\endmark defines \first to be the first token in +% TOKENS, and \rest to be the remainder. +% +\def\splitoff#1#2\endmark{\def\first{#1}\def\rest{#2}}% + +% Allow an optional argument of an uppercase letter, lowercase letter, +% or number, to specify the first label in the enumerated list. No +% argument is the same as `1'. +% +\def\enumerate{\parsearg\enumeratezzz} +\def\enumeratezzz #1{\enumeratey #1 \endenumeratey} +\def\enumeratey #1 #2\endenumeratey{% + \begingroup % ended by the @end enumerate + % + % If we were given no argument, pretend we were given `1'. + \def\thearg{#1}% + \ifx\thearg\empty \def\thearg{1}\fi + % + % Detect if the argument is a single token. If so, it might be a + % letter. Otherwise, the only valid thing it can be is a number. + % (We will always have one token, because of the test we just made. + % This is a good thing, since \splitoff doesn't work given nothing at + % all -- the first parameter is undelimited.) + \expandafter\splitoff\thearg\endmark + \ifx\rest\empty + % Only one token in the argument. It could still be anything. + % A ``lowercase letter'' is one whose \lccode is nonzero. + % An ``uppercase letter'' is one whose \lccode is both nonzero, and + % not equal to itself. + % Otherwise, we assume it's a number. + % + % We need the \relax at the end of the \ifnum lines to stop TeX from + % continuing to look for a . + % + \ifnum\lccode\expandafter`\thearg=0\relax + \numericenumerate % a number (we hope) + \else + % It's a letter. + \ifnum\lccode\expandafter`\thearg=\expandafter`\thearg\relax + \lowercaseenumerate % lowercase letter + \else + \uppercaseenumerate % uppercase letter + \fi + \fi + \else + % Multiple tokens in the argument. We hope it's a number. + \numericenumerate + \fi +} + +% An @enumerate whose labels are integers. The starting integer is +% given in \thearg. +% +\def\numericenumerate{% + \itemno = \thearg + \startenumeration{\the\itemno}% +} + +% The starting (lowercase) letter is in \thearg. +\def\lowercaseenumerate{% + \itemno = \expandafter`\thearg + \startenumeration{% + % Be sure we're not beyond the end of the alphabet. + \ifnum\itemno=0 + \errmessage{No more lowercase letters in @enumerate; get a bigger + alphabet}% + \fi + \char\lccode\itemno + }% +} + +% The starting (uppercase) letter is in \thearg. +\def\uppercaseenumerate{% + \itemno = \expandafter`\thearg + \startenumeration{% + % Be sure we're not beyond the end of the alphabet. + \ifnum\itemno=0 + \errmessage{No more uppercase letters in @enumerate; get a bigger + alphabet} + \fi + \char\uccode\itemno + }% +} + +% Call itemizey, adding a period to the first argument and supplying the +% common last two arguments. Also subtract one from the initial value in +% \itemno, since @item increments \itemno. +% +\def\startenumeration#1{% + \advance\itemno by -1 + \itemizey{#1.}\Eenumerate\flushcr +} + +% @alphaenumerate and @capsenumerate are abbreviations for giving an arg +% to @enumerate. +% +\def\alphaenumerate{\enumerate{a}} +\def\capsenumerate{\enumerate{A}} +\def\Ealphaenumerate{\Eenumerate} +\def\Ecapsenumerate{\Eenumerate} + +% Definition of @item while inside @itemize. + +\def\itemizeitem{% +\advance\itemno by 1 +{\let\par=\endgraf \smallbreak}% +\ifhmode \errmessage{In hmode at itemizeitem}\fi +{\parskip=0in \hskip 0pt +\hbox to 0pt{\hss \itemcontents\hskip \itemmargin}% +\vadjust{\penalty 1200}}% +\flushcr} + +% @multitable macros +% Amy Hendrickson, 8/18/94, 3/6/96 +% +% @multitable ... @end multitable will make as many columns as desired. +% Contents of each column will wrap at width given in preamble. Width +% can be specified either with sample text given in a template line, +% or in percent of \hsize, the current width of text on page. + +% Table can continue over pages but will only break between lines. + +% To make preamble: +% +% Either define widths of columns in terms of percent of \hsize: +% @multitable @columnfractions .25 .3 .45 +% @item ... +% +% Numbers following @columnfractions are the percent of the total +% current hsize to be used for each column. You may use as many +% columns as desired. + + +% Or use a template: +% @multitable {Column 1 template} {Column 2 template} {Column 3 template} +% @item ... +% using the widest term desired in each column. +% +% For those who want to use more than one line's worth of words in +% the preamble, break the line within one argument and it +% will parse correctly, i.e., +% +% @multitable {Column 1 template} {Column 2 template} {Column 3 +% template} +% Not: +% @multitable {Column 1 template} {Column 2 template} +% {Column 3 template} + +% Each new table line starts with @item, each subsequent new column +% starts with @tab. Empty columns may be produced by supplying @tab's +% with nothing between them for as many times as empty columns are needed, +% ie, @tab@tab@tab will produce two empty columns. + +% @item, @tab, @multitable or @end multitable do not need to be on their +% own lines, but it will not hurt if they are. + +% Sample multitable: + +% @multitable {Column 1 template} {Column 2 template} {Column 3 template} +% @item first col stuff @tab second col stuff @tab third col +% @item +% first col stuff +% @tab +% second col stuff +% @tab +% third col +% @item first col stuff @tab second col stuff +% @tab Many paragraphs of text may be used in any column. +% +% They will wrap at the width determined by the template. +% @item@tab@tab This will be in third column. +% @end multitable + +% Default dimensions may be reset by user. +% @multitableparskip is vertical space between paragraphs in table. +% @multitableparindent is paragraph indent in table. +% @multitablecolmargin is horizontal space to be left between columns. +% @multitablelinespace is space to leave between table items, baseline +% to baseline. +% 0pt means it depends on current normal line spacing. +% +\newskip\multitableparskip +\newskip\multitableparindent +\newdimen\multitablecolspace +\newskip\multitablelinespace +\multitableparskip=0pt +\multitableparindent=6pt +\multitablecolspace=12pt +\multitablelinespace=0pt + +% Macros used to set up halign preamble: +% +\let\endsetuptable\relax +\def\xendsetuptable{\endsetuptable} +\let\columnfractions\relax +\def\xcolumnfractions{\columnfractions} +\newif\ifsetpercent + +% #1 is the part of the @columnfraction before the decimal point, which +% is presumably either 0 or the empty string (but we don't check, we +% just throw it away). #2 is the decimal part, which we use as the +% percent of \hsize for this column. +\def\pickupwholefraction#1.#2 {% + \global\advance\colcount by 1 + \expandafter\xdef\csname col\the\colcount\endcsname{.#2\hsize}% + \setuptable +} + +\newcount\colcount +\def\setuptable#1{% + \def\firstarg{#1}% + \ifx\firstarg\xendsetuptable + \let\go = \relax + \else + \ifx\firstarg\xcolumnfractions + \global\setpercenttrue + \else + \ifsetpercent + \let\go\pickupwholefraction + \else + \global\advance\colcount by 1 + \setbox0=\hbox{#1\unskip\space}% Add a normal word space as a + % separator; typically that is always in the input, anyway. + \expandafter\xdef\csname col\the\colcount\endcsname{\the\wd0}% + \fi + \fi + \ifx\go\pickupwholefraction + % Put the argument back for the \pickupwholefraction call, so + % we'll always have a period there to be parsed. + \def\go{\pickupwholefraction#1}% + \else + \let\go = \setuptable + \fi% + \fi + \go +} + +% @multitable ... @end multitable definitions: +% +\def\multitable{\parsearg\dotable} +\def\dotable#1{\bgroup + \vskip\parskip + \let\item=\crcrwithfootnotes + % A \tab used to include \hskip1sp. But then the space in a template + % line is not enough. That is bad. So let's go back to just & until + % we encounter the problem it was intended to solve again. --karl, + % nathan@acm.org, 20apr99. + \let\tab=&% + \let\startfootins=\startsavedfootnote + \tolerance=9500 + \hbadness=9500 + \setmultitablespacing + \parskip=\multitableparskip + \parindent=\multitableparindent + \overfullrule=0pt + \global\colcount=0 + \def\Emultitable{% + \global\setpercentfalse + \crcrwithfootnotes\crcr + \egroup\egroup + }% + % + % To parse everything between @multitable and @item: + \setuptable#1 \endsetuptable + % + % \everycr will reset column counter, \colcount, at the end of + % each line. Every column entry will cause \colcount to advance by one. + % The table preamble + % looks at the current \colcount to find the correct column width. + \everycr{\noalign{% + % + % \filbreak%% keeps underfull box messages off when table breaks over pages. + % Maybe so, but it also creates really weird page breaks when the table + % breaks over pages. Wouldn't \vfil be better? Wait until the problem + % manifests itself, so it can be fixed for real --karl. + \global\colcount=0\relax}}% + % + % This preamble sets up a generic column definition, which will + % be used as many times as user calls for columns. + % \vtop will set a single line and will also let text wrap and + % continue for many paragraphs if desired. + \halign\bgroup&\global\advance\colcount by 1\relax + \multistrut\vtop{\hsize=\expandafter\csname col\the\colcount\endcsname + % + % In order to keep entries from bumping into each other + % we will add a \leftskip of \multitablecolspace to all columns after + % the first one. + % + % If a template has been used, we will add \multitablecolspace + % to the width of each template entry. + % + % If the user has set preamble in terms of percent of \hsize we will + % use that dimension as the width of the column, and the \leftskip + % will keep entries from bumping into each other. Table will start at + % left margin and final column will justify at right margin. + % + % Make sure we don't inherit \rightskip from the outer environment. + \rightskip=0pt + \ifnum\colcount=1 + % The first column will be indented with the surrounding text. + \advance\hsize by\leftskip + \else + \ifsetpercent \else + % If user has not set preamble in terms of percent of \hsize + % we will advance \hsize by \multitablecolspace. + \advance\hsize by \multitablecolspace + \fi + % In either case we will make \leftskip=\multitablecolspace: + \leftskip=\multitablecolspace + \fi + % Ignoring space at the beginning and end avoids an occasional spurious + % blank line, when TeX decides to break the line at the space before the + % box from the multistrut, so the strut ends up on a line by itself. + % For example: + % @multitable @columnfractions .11 .89 + % @item @code{#} + % @tab Legal holiday which is valid in major parts of the whole country. + % Is automatically provided with highlighting sequences respectively marking + % characters. + \noindent\ignorespaces##\unskip\multistrut}\cr +} + +\def\setmultitablespacing{% test to see if user has set \multitablelinespace. +% If so, do nothing. If not, give it an appropriate dimension based on +% current baselineskip. +\ifdim\multitablelinespace=0pt +\setbox0=\vbox{X}\global\multitablelinespace=\the\baselineskip +\global\advance\multitablelinespace by-\ht0 +%% strut to put in table in case some entry doesn't have descenders, +%% to keep lines equally spaced +\let\multistrut = \strut +\else +%% FIXME: what is \box0 supposed to be? +\gdef\multistrut{\vrule height\multitablelinespace depth\dp0 +width0pt\relax} \fi +%% Test to see if parskip is larger than space between lines of +%% table. If not, do nothing. +%% If so, set to same dimension as multitablelinespace. +\ifdim\multitableparskip>\multitablelinespace +\global\multitableparskip=\multitablelinespace +\global\advance\multitableparskip-7pt %% to keep parskip somewhat smaller + %% than skip between lines in the table. +\fi% +\ifdim\multitableparskip=0pt +\global\multitableparskip=\multitablelinespace +\global\advance\multitableparskip-7pt %% to keep parskip somewhat smaller + %% than skip between lines in the table. +\fi} + +% In case a @footnote appears inside an alignment, save the footnote +% text to a box and make the \insert when a row of the table is +% finished. Otherwise, the insertion is lost, it never migrates to the +% main vertical list. --kasal, 22jan03. +% +\newbox\savedfootnotes +% +% \dotable \let's \startfootins to this, so that \dofootnote will call +% it instead of starting the insertion right away. +\def\startsavedfootnote{% + \global\setbox\savedfootnotes = \vbox\bgroup + \unvbox\savedfootnotes +} +\def\crcrwithfootnotes{% + \crcr + \ifvoid\savedfootnotes \else + \noalign{\insert\footins{\box\savedfootnotes}}% + \fi +} + +\message{conditionals,} +% Prevent errors for section commands. +% Used in @ignore and in failing conditionals. +\def\ignoresections{% + \let\appendix=\relax + \let\appendixsec=\relax + \let\appendixsection=\relax + \let\appendixsubsec=\relax + \let\appendixsubsection=\relax + \let\appendixsubsubsec=\relax + \let\appendixsubsubsection=\relax + %\let\begin=\relax + %\let\bye=\relax + \let\centerchap=\relax + \let\chapter=\relax + \let\contents=\relax + \let\section=\relax + \let\smallbook=\relax + \let\subsec=\relax + \let\subsection=\relax + \let\subsubsec=\relax + \let\subsubsection=\relax + \let\titlepage=\relax + \let\top=\relax + \let\unnumbered=\relax + \let\unnumberedsec=\relax + \let\unnumberedsection=\relax + \let\unnumberedsubsec=\relax + \let\unnumberedsubsection=\relax + \let\unnumberedsubsubsec=\relax + \let\unnumberedsubsubsection=\relax +} + +% Ignore @ignore, @ifhtml, @ifinfo, and the like. +% +\def\direntry{\doignore{direntry}} +\def\documentdescriptionword{documentdescription} +\def\documentdescription{\doignore{documentdescription}} +\def\html{\doignore{html}} +\def\ifhtml{\doignore{ifhtml}} +\def\ifinfo{\doignore{ifinfo}} +\def\ifnottex{\doignore{ifnottex}} +\def\ifplaintext{\doignore{ifplaintext}} +\def\ifxml{\doignore{ifxml}} +\def\ignore{\doignore{ignore}} +\def\menu{\doignore{menu}} +\def\xml{\doignore{xml}} + +% @dircategory CATEGORY -- specify a category of the dir file +% which this file should belong to. Ignore this in TeX. +\let\dircategory = \comment + +% Ignore text until a line `@end #1', keeping track of nested conditionals. +% +% A count to remember the depth of nesting. +\newcount\doignorecount + +\def\doignore#1{\begingroup + % Don't complain about control sequences we have declared \outer. + \ignoresections + % + % Make sure that spaces turn into tokens that match what \doignoretext wants. + \catcode\spaceChar = 10 + % + % Ignore braces, so mismatched braces don't cause trouble. + \catcode`\{ = 9 + \catcode`\} = 9 + % + % Count number of #1's that we've seen. + \doignorecount = 0 + % + % Swallow text until we reach the matching `@end #1'. + \expandafter \dodoignore \csname#1\endcsname {#1}% +} + +{ \catcode`@=11 % We want to use \ST@P which cannot appear in texinfo source. + \obeylines % + % + \gdef\dodoignore#1#2{% + % #1 contains, e.g., \ifinfo, a.k.a. @ifinfo. + % #2 contains the string `ifinfo'. + % + % Define a command to find the next `@end #2', which must be on a line + % by itself. + \long\def\doignoretext##1^^M\end #2{\doignoretextyyy##1^^M#1\ST@P}% + % And this command to find another #1 command, at the beginning of a + % line. (Otherwise, we would consider a line `@c @ifset', for + % example, to count as an @ifset for nesting.) + \long\def\doignoretextyyy##1^^M#1##2\ST@P{\doignoreyyy{##2}\ST@P}% + % + % And now expand that command. + \obeylines % + \doignoretext ^^M% + }% +} + +\def\doignoreyyy#1{% + \def\temp{#1}% + \ifx\temp\empty % Nothing found. + \let\next\doignoretextzzz + \else % Found a nested condition, ... + \advance\doignorecount by 1 + \let\next\doignoretextyyy % ..., look for another. + % If we're here, #1 ends with ^^M\ifinfo (for example). + \fi + \next #1% the token \ST@P is present just after this macro. +} + +% We have to swallow the remaining "\ST@P". +% +\def\doignoretextzzz#1{% + \ifnum\doignorecount = 0 % We have just found the outermost @end. + \let\next\enddoignore + \else % Still inside a nested condition. + \advance\doignorecount by -1 + \let\next\doignoretext % Look for the next @end. + \fi + \next +} + +% Finish off ignored text. +\def\enddoignore{\endgroup\ignorespaces} + + +% @set VAR sets the variable VAR to an empty value. +% @set VAR REST-OF-LINE sets VAR to the value REST-OF-LINE. +% +% Since we want to separate VAR from REST-OF-LINE (which might be +% empty), we can't just use \parsearg; we have to insert a space of our +% own to delimit the rest of the line, and then take it out again if we +% didn't need it. Make sure the catcode of space is correct to avoid +% losing inside @example, for instance. +% +\def\set{\begingroup\catcode` =10 + \catcode`\-=12 \catcode`\_=12 % Allow - and _ in VAR. + \parsearg\setxxx} +\def\setxxx#1{\setyyy#1 \endsetyyy} +\def\setyyy#1 #2\endsetyyy{% + \def\temp{#2}% + \ifx\temp\empty \global\expandafter\let\csname SET#1\endcsname = \empty + \else \setzzz{#1}#2\endsetzzz % Remove the trailing space \setxxx inserted. + \fi + \endgroup +} +% Can't use \xdef to pre-expand #2 and save some time, since \temp or +% \next or other control sequences that we've defined might get us into +% an infinite loop. Consider `@set foo @cite{bar}'. +\def\setzzz#1#2 \endsetzzz{\expandafter\gdef\csname SET#1\endcsname{#2}} + +% @clear VAR clears (i.e., unsets) the variable VAR. +% +\def\clear{\parsearg\clearxxx} +\def\clearxxx#1{\global\expandafter\let\csname SET#1\endcsname=\relax} + +% @value{foo} gets the text saved in variable foo. +{ + \catcode`\_ = \active + % + % We might end up with active _ or - characters in the argument if + % we're called from @code, as @code{@value{foo-bar_}}. So \let any + % such active characters to their normal equivalents. + \gdef\value{\begingroup + \catcode`\-=\other \catcode`\_=\other + \indexbreaks \let_\normalunderscore + \valuexxx} +} +\def\valuexxx#1{\expandablevalue{#1}\endgroup} + +% We have this subroutine so that we can handle at least some @value's +% properly in indexes (we \let\value to this in \indexdummies). Ones +% whose names contain - or _ still won't work, but we can't do anything +% about that. The command has to be fully expandable (if the variable +% is set), since the result winds up in the index file. This means that +% if the variable's value contains other Texinfo commands, it's almost +% certain it will fail (although perhaps we could fix that with +% sufficient work to do a one-level expansion on the result, instead of +% complete). +% +\def\expandablevalue#1{% + \expandafter\ifx\csname SET#1\endcsname\relax + {[No value for ``#1'']}% + \message{Variable `#1', used in @value, is not set.}% + \else + \csname SET#1\endcsname + \fi +} + +% @ifset VAR ... @end ifset reads the `...' iff VAR has been defined +% with @set. +% +\def\ifset{\parsearg\doifset} +\def\doifset#1{% + \expandafter\ifx\csname SET#1\endcsname\relax + \let\next=\ifsetfail + \else + \let\next=\ifsetsucceed + \fi + \next +} +\def\ifsetsucceed{\conditionalsucceed{ifset}} +\def\ifsetfail{\doignore{ifset}} +\defineunmatchedend{ifset} + +% @ifclear VAR ... @end ifclear reads the `...' iff VAR has never been +% defined with @set, or has been undefined with @clear. +% +\def\ifclear{\parsearg\doifclear} +\def\doifclear#1{% + \expandafter\ifx\csname SET#1\endcsname\relax + \let\next=\ifclearsucceed + \else + \let\next=\ifclearfail + \fi + \next +} +\def\ifclearsucceed{\conditionalsucceed{ifclear}} +\def\ifclearfail{\doignore{ifclear}} +\defineunmatchedend{ifclear} + +% @iftex, @ifnothtml, @ifnotinfo, @ifnotplaintext always succeed; we +% read the text following, through the first @end iftex (etc.). Make +% `@end iftex' (etc.) valid only after an @iftex. +% +\def\iftex{\conditionalsucceed{iftex}} +\def\ifnothtml{\conditionalsucceed{ifnothtml}} +\def\ifnotinfo{\conditionalsucceed{ifnotinfo}} +\def\ifnotplaintext{\conditionalsucceed{ifnotplaintext}} +\defineunmatchedend{iftex} +\defineunmatchedend{ifnothtml} +\defineunmatchedend{ifnotinfo} +\defineunmatchedend{ifnotplaintext} + +% True conditional. Since \set globally defines its variables, we can +% just start and end a group (to keep the @end definition undefined at +% the outer level). +% +\def\conditionalsucceed#1{\begingroup + \expandafter\def\csname E#1\endcsname{\endgroup}% +} + +% @defininfoenclose. +\let\definfoenclose=\comment + + +\message{indexing,} +% Index generation facilities + +% Define \newwrite to be identical to plain tex's \newwrite +% except not \outer, so it can be used within \newindex. +{\catcode`\@=11 +\gdef\newwrite{\alloc@7\write\chardef\sixt@@n}} + +% \newindex {foo} defines an index named foo. +% It automatically defines \fooindex such that +% \fooindex ...rest of line... puts an entry in the index foo. +% It also defines \fooindfile to be the number of the output channel for +% the file that accumulates this index. The file's extension is foo. +% The name of an index should be no more than 2 characters long +% for the sake of vms. +% +\def\newindex#1{% + \iflinks + \expandafter\newwrite \csname#1indfile\endcsname + \openout \csname#1indfile\endcsname \jobname.#1 % Open the file + \fi + \expandafter\xdef\csname#1index\endcsname{% % Define @#1index + \noexpand\doindex{#1}} +} + +% @defindex foo == \newindex{foo} +% +\def\defindex{\parsearg\newindex} + +% Define @defcodeindex, like @defindex except put all entries in @code. +% +\def\defcodeindex{\parsearg\newcodeindex} +% +\def\newcodeindex#1{% + \iflinks + \expandafter\newwrite \csname#1indfile\endcsname + \openout \csname#1indfile\endcsname \jobname.#1 + \fi + \expandafter\xdef\csname#1index\endcsname{% + \noexpand\docodeindex{#1}}% +} + + +% @synindex foo bar makes index foo feed into index bar. +% Do this instead of @defindex foo if you don't want it as a separate index. +% +% @syncodeindex foo bar similar, but put all entries made for index foo +% inside @code. +% +\def\synindex#1 #2 {\dosynindex\doindex{#1}{#2}} +\def\syncodeindex#1 #2 {\dosynindex\docodeindex{#1}{#2}} + +% #1 is \doindex or \docodeindex, #2 the index getting redefined (foo), +% #3 the target index (bar). +\def\dosynindex#1#2#3{% + % Only do \closeout if we haven't already done it, else we'll end up + % closing the target index. + \expandafter \ifx\csname donesynindex#2\endcsname \undefined + % The \closeout helps reduce unnecessary open files; the limit on the + % Acorn RISC OS is a mere 16 files. + \expandafter\closeout\csname#2indfile\endcsname + \expandafter\let\csname\donesynindex#2\endcsname = 1 + \fi + % redefine \fooindfile: + \expandafter\let\expandafter\temp\expandafter=\csname#3indfile\endcsname + \expandafter\let\csname#2indfile\endcsname=\temp + % redefine \fooindex: + \expandafter\xdef\csname#2index\endcsname{\noexpand#1{#3}}% +} + +% Define \doindex, the driver for all \fooindex macros. +% Argument #1 is generated by the calling \fooindex macro, +% and it is "foo", the name of the index. + +% \doindex just uses \parsearg; it calls \doind for the actual work. +% This is because \doind is more useful to call from other macros. + +% There is also \dosubind {index}{topic}{subtopic} +% which makes an entry in a two-level index such as the operation index. + +\def\doindex#1{\edef\indexname{#1}\parsearg\singleindexer} +\def\singleindexer #1{\doind{\indexname}{#1}} + +% like the previous two, but they put @code around the argument. +\def\docodeindex#1{\edef\indexname{#1}\parsearg\singlecodeindexer} +\def\singlecodeindexer #1{\doind{\indexname}{\code{#1}}} + +% Take care of Texinfo commands that can appear in an index entry. +% Since there are some commands we want to expand, and others we don't, +% we have to laboriously prevent expansion for those that we don't. +% +\def\indexdummies{% + \def\@{@}% change to @@ when we switch to @ as escape char in index files. + \def\ {\realbackslash\space }% + % Need these in case \tex is in effect and \{ is a \delimiter again. + % But can't use \lbracecmd and \rbracecmd because texindex assumes + % braces and backslashes are used only as delimiters. + \let\{ = \mylbrace + \let\} = \myrbrace + % + % \definedummyword defines \#1 as \realbackslash #1\space, thus + % effectively preventing its expansion. This is used only for control + % words, not control letters, because the \space would be incorrect + % for control characters, but is needed to separate the control word + % from whatever follows. + % + % For control letters, we have \definedummyletter, which omits the + % space. + % + % These can be used both for control words that take an argument and + % those that do not. If it is followed by {arg} in the input, then + % that will dutifully get written to the index (or wherever). + % + \def\definedummyword##1{% + \expandafter\def\csname ##1\endcsname{\realbackslash ##1\space}% + }% + \def\definedummyletter##1{% + \expandafter\def\csname ##1\endcsname{\realbackslash ##1}% + }% + % + % Do the redefinitions. + \commondummies +} + +% For the aux file, @ is the escape character. So we want to redefine +% everything using @ instead of \realbackslash. When everything uses +% @, this will be simpler. +% +\def\atdummies{% + \def\@{@@}% + \def\ {@ }% + \let\{ = \lbraceatcmd + \let\} = \rbraceatcmd + % + % (See comments in \indexdummies.) + \def\definedummyword##1{% + \expandafter\def\csname ##1\endcsname{@##1\space}% + }% + \def\definedummyletter##1{% + \expandafter\def\csname ##1\endcsname{@##1}% + }% + % + % Do the redefinitions. + \commondummies +} + +% Called from \indexdummies and \atdummies. \definedummyword and +% \definedummyletter must be defined first. +% +\def\commondummies{% + % + \normalturnoffactive + % + % Control letters and accents. + \definedummyletter{_}% + \definedummyletter{,}% + \definedummyletter{"}% + \definedummyletter{`}% + \definedummyletter{'}% + \definedummyletter{^}% + \definedummyletter{~}% + \definedummyletter{=}% + \definedummyword{u}% + \definedummyword{v}% + \definedummyword{H}% + \definedummyword{dotaccent}% + \definedummyword{ringaccent}% + \definedummyword{tieaccent}% + \definedummyword{ubaraccent}% + \definedummyword{udotaccent}% + \definedummyword{dotless}% + % + % Other non-English letters. + \definedummyword{AA}% + \definedummyword{AE}% + \definedummyword{L}% + \definedummyword{OE}% + \definedummyword{O}% + \definedummyword{aa}% + \definedummyword{ae}% + \definedummyword{l}% + \definedummyword{oe}% + \definedummyword{o}% + \definedummyword{ss}% + % + % Although these internal commands shouldn't show up, sometimes they do. + \definedummyword{bf}% + \definedummyword{gtr}% + \definedummyword{hat}% + \definedummyword{less}% + \definedummyword{sf}% + \definedummyword{sl}% + \definedummyword{tclose}% + \definedummyword{tt}% + % + % Texinfo font commands. + \definedummyword{b}% + \definedummyword{i}% + \definedummyword{r}% + \definedummyword{sc}% + \definedummyword{t}% + % + \definedummyword{TeX}% + \definedummyword{acronym}% + \definedummyword{cite}% + \definedummyword{code}% + \definedummyword{command}% + \definedummyword{dfn}% + \definedummyword{dots}% + \definedummyword{emph}% + \definedummyword{env}% + \definedummyword{file}% + \definedummyword{kbd}% + \definedummyword{key}% + \definedummyword{math}% + \definedummyword{option}% + \definedummyword{samp}% + \definedummyword{strong}% + \definedummyword{uref}% + \definedummyword{url}% + \definedummyword{var}% + \definedummyword{verb}% + \definedummyword{w}% + % + % Assorted special characters. + \definedummyword{bullet}% + \definedummyword{copyright}% + \definedummyword{dots}% + \definedummyword{enddots}% + \definedummyword{equiv}% + \definedummyword{error}% + \definedummyword{expansion}% + \definedummyword{minus}% + \definedummyword{pounds}% + \definedummyword{point}% + \definedummyword{print}% + \definedummyword{result}% + % + % Handle some cases of @value -- where the variable name does not + % contain - or _, and the value does not contain any + % (non-fully-expandable) commands. + \let\value = \expandablevalue + % + % Normal spaces, not active ones. + \unsepspaces + % + % No macro expansion. + \turnoffmacros +} + +% If an index command is used in an @example environment, any spaces +% therein should become regular spaces in the raw index file, not the +% expansion of \tie (\leavevmode \penalty \@M \ ). +{\obeyspaces + \gdef\unsepspaces{\obeyspaces\let =\space}} + + +% \indexnofonts is used when outputting the strings to sort the index +% by, and when constructing control sequence names. It eliminates all +% control sequences and just writes whatever the best ASCII sort string +% would be for a given command (usually its argument). +% +\def\indexdummytex{TeX} +\def\indexdummydots{...} +% +\def\indexnofonts{% + \def\ { }% + \def\@{@}% + % how to handle braces? + \def\_{\normalunderscore}% + % + \let\,=\asis + \let\"=\asis + \let\`=\asis + \let\'=\asis + \let\^=\asis + \let\~=\asis + \let\==\asis + \let\u=\asis + \let\v=\asis + \let\H=\asis + \let\dotaccent=\asis + \let\ringaccent=\asis + \let\tieaccent=\asis + \let\ubaraccent=\asis + \let\udotaccent=\asis + \let\dotless=\asis + % + % Other non-English letters. + \def\AA{AA}% + \def\AE{AE}% + \def\L{L}% + \def\OE{OE}% + \def\O{O}% + \def\aa{aa}% + \def\ae{ae}% + \def\l{l}% + \def\oe{oe}% + \def\o{o}% + \def\ss{ss}% + \def\exclamdown{!}% + \def\questiondown{?}% + % + % Don't no-op \tt, since it isn't a user-level command + % and is used in the definitions of the active chars like <, >, |, etc. + % Likewise with the other plain tex font commands. + %\let\tt=\asis + % + % Texinfo font commands. + \let\b=\asis + \let\i=\asis + \let\r=\asis + \let\sc=\asis + \let\t=\asis + % + \let\TeX=\indexdummytex + \let\acronym=\asis + \let\cite=\asis + \let\code=\asis + \let\command=\asis + \let\dfn=\asis + \let\dots=\indexdummydots + \let\emph=\asis + \let\env=\asis + \let\file=\asis + \let\kbd=\asis + \let\key=\asis + \let\math=\asis + \let\option=\asis + \let\samp=\asis + \let\strong=\asis + \let\uref=\asis + \let\url=\asis + \let\var=\asis + \let\verb=\asis + \let\w=\asis +} + +\let\indexbackslash=0 %overridden during \printindex. +\let\SETmarginindex=\relax % put index entries in margin (undocumented)? + +% Most index entries go through here, but \dosubind is the general case. +% +\def\doind#1#2{\dosubind{#1}{#2}{}} + +% Workhorse for all \fooindexes. +% #1 is name of index, #2 is stuff to put there, #3 is subentry -- +% \empty if called from \doind, as we usually are. The main exception +% is with defuns, which call us directly. +% +\def\dosubind#1#2#3{% + \iflinks + {% + % Store the main index entry text (including the third arg). + \toks0 = {#2}% + % If third arg is present, precede it with space. + \def\thirdarg{#3}% + \ifx\thirdarg\empty \else + \toks0 = \expandafter{\the\toks0 \space #3}% + \fi + % + \edef\writeto{\csname#1indfile\endcsname}% + % + \ifvmode + \dosubindsanitize + \else + \dosubindwrite + \fi + }% + \fi +} + +% Write the entry to the index file: +% +\def\dosubindwrite{% + % Put the index entry in the margin if desired. + \ifx\SETmarginindex\relax\else + \insert\margin{\hbox{\vrule height8pt depth3pt width0pt \the\toks0}}% + \fi + % + % Remember, we are within a group. + \indexdummies % Must do this here, since \bf, etc expand at this stage + \escapechar=`\\ + \def\rawbackslashxx{\indexbackslash}% \indexbackslash isn't defined now + % so it will be output as is; and it will print as backslash. + % + % Process the index entry with all font commands turned off, to + % get the string to sort by. + {\indexnofonts + \edef\temp{\the\toks0}% need full expansion + \xdef\indexsorttmp{\temp}% + }% + % + % Set up the complete index entry, with both the sort key and + % the original text, including any font commands. We write + % three arguments to \entry to the .?? file (four in the + % subentry case), texindex reduces to two when writing the .??s + % sorted result. + \edef\temp{% + \write\writeto{% + \string\entry{\indexsorttmp}{\noexpand\folio}{\the\toks0}}% + }% + \temp +} + +% Take care of unwanted page breaks: +% +% If a skip is the last thing on the list now, preserve it +% by backing up by \lastskip, doing the \write, then inserting +% the skip again. Otherwise, the whatsit generated by the +% \write will make \lastskip zero. The result is that sequences +% like this: +% @end defun +% @tindex whatever +% @defun ... +% will have extra space inserted, because the \medbreak in the +% start of the @defun won't see the skip inserted by the @end of +% the previous defun. +% +% But don't do any of this if we're not in vertical mode. We +% don't want to do a \vskip and prematurely end a paragraph. +% +% Avoid page breaks due to these extra skips, too. +% +\def\dosubindsanitize{% + % \lastskip and \lastpenalty cannot both be nonzero simultaneously. + \skip0 = \lastskip + \count255 = \lastpenalty + % + % If \lastskip is nonzero, that means the last item was a + % skip. And since a skip is discardable, that means this + % -\skip0 glue we're inserting is preceded by a + % non-discardable item, therefore it is not a potential + % breakpoint, therefore no \nobreak needed. + \ifdim\lastskip = 0pt \else \vskip-\skip0 \fi + % + \dosubindwrite + % + \ifdim\skip0 = 0pt + % if \lastskip was zero, perhaps the last item was a + % penalty, and perhaps it was >=10000, e.g., a \nobreak. + % In that case, we want to re-insert the penalty; since we + % just inserted a non-discardable item, any following glue + % (such as a \parskip) would be a breakpoint. For example: + % @deffn deffn-whatever + % @vindex index-whatever + % Description. + % would allow a break between the index-whatever whatsit + % and the "Description." paragraph. + \ifnum\count255>9999 \nobreak \fi + \else + % On the other hand, if we had a nonzero \lastskip, + % this make-up glue would be preceded by a non-discardable item + % (the whatsit from the \write), so we must insert a \nobreak. + \nobreak\vskip\skip0 + \fi +} + +% The index entry written in the file actually looks like +% \entry {sortstring}{page}{topic} +% or +% \entry {sortstring}{page}{topic}{subtopic} +% The texindex program reads in these files and writes files +% containing these kinds of lines: +% \initial {c} +% before the first topic whose initial is c +% \entry {topic}{pagelist} +% for a topic that is used without subtopics +% \primary {topic} +% for the beginning of a topic that is used with subtopics +% \secondary {subtopic}{pagelist} +% for each subtopic. + +% Define the user-accessible indexing commands +% @findex, @vindex, @kindex, @cindex. + +\def\findex {\fnindex} +\def\kindex {\kyindex} +\def\cindex {\cpindex} +\def\vindex {\vrindex} +\def\tindex {\tpindex} +\def\pindex {\pgindex} + +\def\cindexsub {\begingroup\obeylines\cindexsub} +{\obeylines % +\gdef\cindexsub "#1" #2^^M{\endgroup % +\dosubind{cp}{#2}{#1}}} + +% Define the macros used in formatting output of the sorted index material. + +% @printindex causes a particular index (the ??s file) to get printed. +% It does not print any chapter heading (usually an @unnumbered). +% +\def\printindex{\parsearg\doprintindex} +\def\doprintindex#1{\begingroup + \dobreak \chapheadingskip{10000}% + % + \smallfonts \rm + \tolerance = 9500 + \everypar = {}% don't want the \kern\-parindent from indentation suppression. + \indexbreaks + % + % See if the index file exists and is nonempty. + % Change catcode of @ here so that if the index file contains + % \initial {@} + % as its first line, TeX doesn't complain about mismatched braces + % (because it thinks @} is a control sequence). + \catcode`\@ = 11 + \openin 1 \jobname.#1s + \ifeof 1 + % \enddoublecolumns gets confused if there is no text in the index, + % and it loses the chapter title and the aux file entries for the + % index. The easiest way to prevent this problem is to make sure + % there is some text. + \putwordIndexNonexistent + \else + % + % If the index file exists but is empty, then \openin leaves \ifeof + % false. We have to make TeX try to read something from the file, so + % it can discover if there is anything in it. + \read 1 to \temp + \ifeof 1 + \putwordIndexIsEmpty + \else + % Index files are almost Texinfo source, but we use \ as the escape + % character. It would be better to use @, but that's too big a change + % to make right now. + \def\indexbackslash{\rawbackslashxx}% + \catcode`\\ = 0 + \escapechar = `\\ + \begindoublecolumns + \input \jobname.#1s + \enddoublecolumns + \fi + \fi + \closein 1 +\endgroup} + +% These macros are used by the sorted index file itself. +% Change them to control the appearance of the index. + +\def\initial#1{{% + % Some minor font changes for the special characters. + \let\tentt=\sectt \let\tt=\sectt \let\sf=\sectt + % + % Remove any glue we may have, we'll be inserting our own. + \removelastskip + % + % We like breaks before the index initials, so insert a bonus. + \penalty -300 + % + % Typeset the initial. Making this add up to a whole number of + % baselineskips increases the chance of the dots lining up from column + % to column. It still won't often be perfect, because of the stretch + % we need before each entry, but it's better. + % + % No shrink because it confuses \balancecolumns. + \vskip 1.67\baselineskip plus .5\baselineskip + \leftline{\secbf #1}% + \vskip .33\baselineskip plus .1\baselineskip + % + % Do our best not to break after the initial. + \nobreak +}} + +% This typesets a paragraph consisting of #1, dot leaders, and then #2 +% flush to the right margin. It is used for index and table of contents +% entries. The paragraph is indented by \leftskip. +% +\def\entry#1#2{\begingroup + % + % Start a new paragraph if necessary, so our assignments below can't + % affect previous text. + \par + % + % Do not fill out the last line with white space. + \parfillskip = 0in + % + % No extra space above this paragraph. + \parskip = 0in + % + % Do not prefer a separate line ending with a hyphen to fewer lines. + \finalhyphendemerits = 0 + % + % \hangindent is only relevant when the entry text and page number + % don't both fit on one line. In that case, bob suggests starting the + % dots pretty far over on the line. Unfortunately, a large + % indentation looks wrong when the entry text itself is broken across + % lines. So we use a small indentation and put up with long leaders. + % + % \hangafter is reset to 1 (which is the value we want) at the start + % of each paragraph, so we need not do anything with that. + \hangindent = 2em + % + % When the entry text needs to be broken, just fill out the first line + % with blank space. + \rightskip = 0pt plus1fil + % + % A bit of stretch before each entry for the benefit of balancing columns. + \vskip 0pt plus1pt + % + % Start a ``paragraph'' for the index entry so the line breaking + % parameters we've set above will have an effect. + \noindent + % + % Insert the text of the index entry. TeX will do line-breaking on it. + #1% + % The following is kludged to not output a line of dots in the index if + % there are no page numbers. The next person who breaks this will be + % cursed by a Unix daemon. + \def\tempa{{\rm }}% + \def\tempb{#2}% + \edef\tempc{\tempa}% + \edef\tempd{\tempb}% + \ifx\tempc\tempd\ \else% + % + % If we must, put the page number on a line of its own, and fill out + % this line with blank space. (The \hfil is overwhelmed with the + % fill leaders glue in \indexdotfill if the page number does fit.) + \hfil\penalty50 + \null\nobreak\indexdotfill % Have leaders before the page number. + % + % The `\ ' here is removed by the implicit \unskip that TeX does as + % part of (the primitive) \par. Without it, a spurious underfull + % \hbox ensues. + \ifpdf + \pdfgettoks#2.\ \the\toksA % The page number ends the paragraph. + \else + \ #2% The page number ends the paragraph. + \fi + \fi% + \par +\endgroup} + +% Like \dotfill except takes at least 1 em. +\def\indexdotfill{\cleaders + \hbox{$\mathsurround=0pt \mkern1.5mu ${\it .}$ \mkern1.5mu$}\hskip 1em plus 1fill} + +\def\primary #1{\line{#1\hfil}} + +\newskip\secondaryindent \secondaryindent=0.5cm +\def\secondary#1#2{{% + \parfillskip=0in + \parskip=0in + \hangindent=1in + \hangafter=1 + \noindent\hskip\secondaryindent\hbox{#1}\indexdotfill + \ifpdf + \pdfgettoks#2.\ \the\toksA % The page number ends the paragraph. + \else + #2 + \fi + \par +}} + +% Define two-column mode, which we use to typeset indexes. +% Adapted from the TeXbook, page 416, which is to say, +% the manmac.tex format used to print the TeXbook itself. +\catcode`\@=11 + +\newbox\partialpage +\newdimen\doublecolumnhsize + +\def\begindoublecolumns{\begingroup % ended by \enddoublecolumns + % Grab any single-column material above us. + \output = {% + % + % Here is a possibility not foreseen in manmac: if we accumulate a + % whole lot of material, we might end up calling this \output + % routine twice in a row (see the doublecol-lose test, which is + % essentially a couple of indexes with @setchapternewpage off). In + % that case we just ship out what is in \partialpage with the normal + % output routine. Generally, \partialpage will be empty when this + % runs and this will be a no-op. See the indexspread.tex test case. + \ifvoid\partialpage \else + \onepageout{\pagecontents\partialpage}% + \fi + % + \global\setbox\partialpage = \vbox{% + % Unvbox the main output page. + \unvbox\PAGE + \kern-\topskip \kern\baselineskip + }% + }% + \eject % run that output routine to set \partialpage + % + % Use the double-column output routine for subsequent pages. + \output = {\doublecolumnout}% + % + % Change the page size parameters. We could do this once outside this + % routine, in each of @smallbook, @afourpaper, and the default 8.5x11 + % format, but then we repeat the same computation. Repeating a couple + % of assignments once per index is clearly meaningless for the + % execution time, so we may as well do it in one place. + % + % First we halve the line length, less a little for the gutter between + % the columns. We compute the gutter based on the line length, so it + % changes automatically with the paper format. The magic constant + % below is chosen so that the gutter has the same value (well, +-<1pt) + % as it did when we hard-coded it. + % + % We put the result in a separate register, \doublecolumhsize, so we + % can restore it in \pagesofar, after \hsize itself has (potentially) + % been clobbered. + % + \doublecolumnhsize = \hsize + \advance\doublecolumnhsize by -.04154\hsize + \divide\doublecolumnhsize by 2 + \hsize = \doublecolumnhsize + % + % Double the \vsize as well. (We don't need a separate register here, + % since nobody clobbers \vsize.) + \vsize = 2\vsize +} + +% The double-column output routine for all double-column pages except +% the last. +% +\def\doublecolumnout{% + \splittopskip=\topskip \splitmaxdepth=\maxdepth + % Get the available space for the double columns -- the normal + % (undoubled) page height minus any material left over from the + % previous page. + \dimen@ = \vsize + \divide\dimen@ by 2 + \advance\dimen@ by -\ht\partialpage + % + % box0 will be the left-hand column, box2 the right. + \setbox0=\vsplit255 to\dimen@ \setbox2=\vsplit255 to\dimen@ + \onepageout\pagesofar + \unvbox255 + \penalty\outputpenalty +} +% +% Re-output the contents of the output page -- any previous material, +% followed by the two boxes we just split, in box0 and box2. +\def\pagesofar{% + \unvbox\partialpage + % + \hsize = \doublecolumnhsize + \wd0=\hsize \wd2=\hsize + \hbox to\pagewidth{\box0\hfil\box2}% +} +% +% All done with double columns. +\def\enddoublecolumns{% + \output = {% + % Split the last of the double-column material. Leave it on the + % current page, no automatic page break. + \balancecolumns + % + % If we end up splitting too much material for the current page, + % though, there will be another page break right after this \output + % invocation ends. Having called \balancecolumns once, we do not + % want to call it again. Therefore, reset \output to its normal + % definition right away. (We hope \balancecolumns will never be + % called on to balance too much material, but if it is, this makes + % the output somewhat more palatable.) + \global\output = {\onepageout{\pagecontents\PAGE}}% + }% + \eject + \endgroup % started in \begindoublecolumns + % + % \pagegoal was set to the doubled \vsize above, since we restarted + % the current page. We're now back to normal single-column + % typesetting, so reset \pagegoal to the normal \vsize (after the + % \endgroup where \vsize got restored). + \pagegoal = \vsize +} +% +% Called at the end of the double column material. +\def\balancecolumns{% + \setbox0 = \vbox{\unvbox255}% like \box255 but more efficient, see p.120. + \dimen@ = \ht0 + \advance\dimen@ by \topskip + \advance\dimen@ by-\baselineskip + \divide\dimen@ by 2 % target to split to + %debug\message{final 2-column material height=\the\ht0, target=\the\dimen@.}% + \splittopskip = \topskip + % Loop until we get a decent breakpoint. + {% + \vbadness = 10000 + \loop + \global\setbox3 = \copy0 + \global\setbox1 = \vsplit3 to \dimen@ + \ifdim\ht3>\dimen@ + \global\advance\dimen@ by 1pt + \repeat + }% + %debug\message{split to \the\dimen@, column heights: \the\ht1, \the\ht3.}% + \setbox0=\vbox to\dimen@{\unvbox1}% + \setbox2=\vbox to\dimen@{\unvbox3}% + % + \pagesofar +} +\catcode`\@ = \other + + +\message{sectioning,} +% Chapters, sections, etc. + +% \unnumberedno is an oxymoron, of course. But we count the unnumbered +% sections so that we can refer to them unambiguously in the pdf +% outlines by their "section number". We avoid collisions with chapter +% numbers by starting them at 10000. (If a document ever has 10000 +% chapters, we're in trouble anyway, I'm sure.) +\newcount\unnumberedno \unnumberedno = 10000 +\newcount\chapno +\newcount\secno \secno=0 +\newcount\subsecno \subsecno=0 +\newcount\subsubsecno \subsubsecno=0 + +% This counter is funny since it counts through charcodes of letters A, B, ... +\newcount\appendixno \appendixno = `\@ +% +% \def\appendixletter{\char\the\appendixno} +% We do the following ugly conditional instead of the above simple +% construct for the sake of pdftex, which needs the actual +% letter in the expansion, not just typeset. +% +\def\appendixletter{% + \ifnum\appendixno=`A A% + \else\ifnum\appendixno=`B B% + \else\ifnum\appendixno=`C C% + \else\ifnum\appendixno=`D D% + \else\ifnum\appendixno=`E E% + \else\ifnum\appendixno=`F F% + \else\ifnum\appendixno=`G G% + \else\ifnum\appendixno=`H H% + \else\ifnum\appendixno=`I I% + \else\ifnum\appendixno=`J J% + \else\ifnum\appendixno=`K K% + \else\ifnum\appendixno=`L L% + \else\ifnum\appendixno=`M M% + \else\ifnum\appendixno=`N N% + \else\ifnum\appendixno=`O O% + \else\ifnum\appendixno=`P P% + \else\ifnum\appendixno=`Q Q% + \else\ifnum\appendixno=`R R% + \else\ifnum\appendixno=`S S% + \else\ifnum\appendixno=`T T% + \else\ifnum\appendixno=`U U% + \else\ifnum\appendixno=`V V% + \else\ifnum\appendixno=`W W% + \else\ifnum\appendixno=`X X% + \else\ifnum\appendixno=`Y Y% + \else\ifnum\appendixno=`Z Z% + % The \the is necessary, despite appearances, because \appendixletter is + % expanded while writing the .toc file. \char\appendixno is not + % expandable, thus it is written literally, thus all appendixes come out + % with the same letter (or @) in the toc without it. + \else\char\the\appendixno + \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi + \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi} + +% Each @chapter defines this as the name of the chapter. +% page headings and footings can use it. @section does likewise. +% However, they are not reliable, because we don't use marks. +\def\thischapter{} +\def\thissection{} + +\newcount\absseclevel % used to calculate proper heading level +\newcount\secbase\secbase=0 % @raisesections/@lowersections modify this count + +% @raisesections: treat @section as chapter, @subsection as section, etc. +\def\raisesections{\global\advance\secbase by -1} +\let\up=\raisesections % original BFox name + +% @lowersections: treat @chapter as section, @section as subsection, etc. +\def\lowersections{\global\advance\secbase by 1} +\let\down=\lowersections % original BFox name + +% Choose a numbered-heading macro +% #1 is heading level if unmodified by @raisesections or @lowersections +% #2 is text for heading +\def\numhead#1#2{\absseclevel=\secbase\advance\absseclevel by #1 +\ifcase\absseclevel + \chapterzzz{#2}% + \or \seczzz{#2}% + \or \numberedsubseczzz{#2}% + \or \numberedsubsubseczzz{#2}% + \else + \ifnum \absseclevel<0 \chapterzzz{#2}% + \else \numberedsubsubseczzz{#2}% + \fi + \fi + \suppressfirstparagraphindent +} + +% like \numhead, but chooses appendix heading levels +\def\apphead#1#2{\absseclevel=\secbase\advance\absseclevel by #1 +\ifcase\absseclevel + \appendixzzz{#2}% + \or \appendixsectionzzz{#2}% + \or \appendixsubseczzz{#2}% + \or \appendixsubsubseczzz{#2}% + \else + \ifnum \absseclevel<0 \appendixzzz{#2}% + \else \appendixsubsubseczzz{#2}% + \fi + \fi + \suppressfirstparagraphindent +} + +% like \numhead, but chooses numberless heading levels +\def\unnmhead#1#2{\absseclevel=\secbase\advance\absseclevel by #1 + \ifcase\absseclevel + \unnumberedzzz{#2}% + \or \unnumberedseczzz{#2}% + \or \unnumberedsubseczzz{#2}% + \or \unnumberedsubsubseczzz{#2}% + \else + \ifnum \absseclevel<0 \unnumberedzzz{#2}% + \else \unnumberedsubsubseczzz{#2}% + \fi + \fi + \suppressfirstparagraphindent +} + +% @chapter, @appendix, @unnumbered. +% +\outer\def\chapter{\parsearg\chapteryyy} +\def\chapteryyy#1{\numhead0{#1}} % normally numhead0 calls chapterzzz +\def\chapterzzz#1{% + \secno=0 \subsecno=0 \subsubsecno=0 \advance\chapno by 1 + \message{\putwordChapter\space \the\chapno}% + % + % Write the actual heading. + \chapmacro{#1}{Ynumbered}{\the\chapno}% + % + % So @section and the like are numbered underneath this chapter. + \global\let\section = \numberedsec + \global\let\subsection = \numberedsubsec + \global\let\subsubsection = \numberedsubsubsec +} + +\outer\def\appendix{\parsearg\appendixyyy} +\def\appendixyyy#1{\apphead0{#1}} % normally apphead0 calls appendixzzz +\def\appendixzzz#1{% + \secno=0 \subsecno=0 \subsubsecno=0 \advance\appendixno by 1 + \def\appendixnum{\putwordAppendix\space \appendixletter}% + \message{\appendixnum}% + \chapmacro{#1}{Yappendix}{\appendixletter}% + \global\let\section = \appendixsec + \global\let\subsection = \appendixsubsec + \global\let\subsubsection = \appendixsubsubsec +} + +% @centerchap is like @unnumbered, but the heading is centered. +\outer\def\centerchap{\parsearg\centerchapyyy} +\def\centerchapyyy#1{{\unnumberedyyy{#1}}} + +% @top is like @unnumbered. +\outer\def\top{\parsearg\unnumberedyyy} + +\outer\def\unnumbered{\parsearg\unnumberedyyy} +\def\unnumberedyyy#1{\unnmhead0{#1}} % normally unnmhead0 calls unnumberedzzz +\def\unnumberedzzz#1{% + \secno=0 \subsecno=0 \subsubsecno=0 \advance\unnumberedno by 1 + % + % This used to be simply \message{#1}, but TeX fully expands the + % argument to \message. Therefore, if #1 contained @-commands, TeX + % expanded them. For example, in `@unnumbered The @cite{Book}', TeX + % expanded @cite (which turns out to cause errors because \cite is meant + % to be executed, not expanded). + % + % Anyway, we don't want the fully-expanded definition of @cite to appear + % as a result of the \message, we just want `@cite' itself. We use + % \the to achieve this: TeX expands \the only once, + % simply yielding the contents of . (We also do this for + % the toc entries.) + \toks0 = {#1}\message{(\the\toks0)}% + % + \chapmacro{#1}{Ynothing}{\the\unnumberedno}% + % + \global\let\section = \unnumberedsec + \global\let\subsection = \unnumberedsubsec + \global\let\subsubsection = \unnumberedsubsubsec +} + +% Sections. +\outer\def\numberedsec{\parsearg\secyyy} +\def\secyyy#1{\numhead1{#1}} % normally calls seczzz +\def\seczzz#1{% + \subsecno=0 \subsubsecno=0 \advance\secno by 1 + \sectionheading{#1}{sec}{Ynumbered}{\the\chapno.\the\secno}% +} + +\outer\def\appendixsection{\parsearg\appendixsecyyy} +\outer\def\appendixsec{\parsearg\appendixsecyyy} +\def\appendixsecyyy#1{\apphead1{#1}} % normally calls appendixsectionzzz +\def\appendixsectionzzz#1{% + \subsecno=0 \subsubsecno=0 \advance\secno by 1 + \sectionheading{#1}{sec}{Yappendix}{\appendixletter.\the\secno}% +} + +\outer\def\unnumberedsec{\parsearg\unnumberedsecyyy} +\def\unnumberedsecyyy#1{\unnmhead1{#1}} % normally calls unnumberedseczzz +\def\unnumberedseczzz#1{% + \subsecno=0 \subsubsecno=0 \advance\secno by 1 + \sectionheading{#1}{sec}{Ynothing}{\the\unnumberedno.\the\secno}% +} + +% Subsections. +\outer\def\numberedsubsec{\parsearg\numberedsubsecyyy} +\def\numberedsubsecyyy#1{\numhead2{#1}} % normally calls numberedsubseczzz +\def\numberedsubseczzz#1{% + \subsubsecno=0 \advance\subsecno by 1 + \sectionheading{#1}{subsec}{Ynumbered}{\the\chapno.\the\secno.\the\subsecno}% +} + +\outer\def\appendixsubsec{\parsearg\appendixsubsecyyy} +\def\appendixsubsecyyy#1{\apphead2{#1}} % normally calls appendixsubseczzz +\def\appendixsubseczzz#1{% + \subsubsecno=0 \advance\subsecno by 1 + \sectionheading{#1}{subsec}{Yappendix}% + {\appendixletter.\the\secno.\the\subsecno}% +} + +\outer\def\unnumberedsubsec{\parsearg\unnumberedsubsecyyy} +\def\unnumberedsubsecyyy#1{\unnmhead2{#1}} %normally calls unnumberedsubseczzz +\def\unnumberedsubseczzz#1{% + \subsubsecno=0 \advance\subsecno by 1 + \sectionheading{#1}{subsec}{Ynothing}% + {\the\unnumberedno.\the\secno.\the\subsecno}% +} + +% Subsubsections. +\outer\def\numberedsubsubsec{\parsearg\numberedsubsubsecyyy} +\def\numberedsubsubsecyyy#1{\numhead3{#1}} % normally numberedsubsubseczzz +\def\numberedsubsubseczzz#1{% + \advance\subsubsecno by 1 + \sectionheading{#1}{subsubsec}{Ynumbered}% + {\the\chapno.\the\secno.\the\subsecno.\the\subsubsecno}% +} + +\outer\def\appendixsubsubsec{\parsearg\appendixsubsubsecyyy} +\def\appendixsubsubsecyyy#1{\apphead3{#1}} % normally appendixsubsubseczzz +\def\appendixsubsubseczzz#1{% + \advance\subsubsecno by 1 + \sectionheading{#1}{subsubsec}{Yappendix}% + {\appendixletter.\the\secno.\the\subsecno.\the\subsubsecno}% +} + +\outer\def\unnumberedsubsubsec{\parsearg\unnumberedsubsubsecyyy} +\def\unnumberedsubsubsecyyy#1{\unnmhead3{#1}} %normally unnumberedsubsubseczzz +\def\unnumberedsubsubseczzz#1{% + \advance\subsubsecno by 1 + \sectionheading{#1}{subsubsec}{Ynothing}% + {\the\unnumberedno.\the\secno.\the\subsecno.\the\subsubsecno}% +} + +% These are variants which are not "outer", so they can appear in @ifinfo. +% Actually, they are now be obsolete; ordinary section commands should work. +\def\infotop{\parsearg\unnumberedzzz} +\def\infounnumbered{\parsearg\unnumberedzzz} +\def\infounnumberedsec{\parsearg\unnumberedseczzz} +\def\infounnumberedsubsec{\parsearg\unnumberedsubseczzz} +\def\infounnumberedsubsubsec{\parsearg\unnumberedsubsubseczzz} + +\def\infoappendix{\parsearg\appendixzzz} +\def\infoappendixsec{\parsearg\appendixseczzz} +\def\infoappendixsubsec{\parsearg\appendixsubseczzz} +\def\infoappendixsubsubsec{\parsearg\appendixsubsubseczzz} + +\def\infochapter{\parsearg\chapterzzz} +\def\infosection{\parsearg\sectionzzz} +\def\infosubsection{\parsearg\subsectionzzz} +\def\infosubsubsection{\parsearg\subsubsectionzzz} + +% These macros control what the section commands do, according +% to what kind of chapter we are in (ordinary, appendix, or unnumbered). +% Define them by default for a numbered chapter. +\let\section = \numberedsec +\let\subsection = \numberedsubsec +\let\subsubsection = \numberedsubsubsec + +% Define @majorheading, @heading and @subheading + +% NOTE on use of \vbox for chapter headings, section headings, and such: +% 1) We use \vbox rather than the earlier \line to permit +% overlong headings to fold. +% 2) \hyphenpenalty is set to 10000 because hyphenation in a +% heading is obnoxious; this forbids it. +% 3) Likewise, headings look best if no \parindent is used, and +% if justification is not attempted. Hence \raggedright. + + +\def\majorheading{% + {\advance\chapheadingskip by 10pt \chapbreak }% + \parsearg\chapheadingzzz +} + +\def\chapheading{\chapbreak \parsearg\chapheadingzzz} +\def\chapheadingzzz#1{% + {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000 + \parindent=0pt\raggedright + \rm #1\hfill}}% + \bigskip \par\penalty 200\relax + \suppressfirstparagraphindent +} + +% @heading, @subheading, @subsubheading. +\def\heading{\parsearg\doheading} +\def\subheading{\parsearg\dosubheading} +\def\subsubheading{\parsearg\dosubsubheading} +\def\doheading#1{\sectionheading{#1}{sec}{Yomitfromtoc}{} + \suppressfirstparagraphindent} +\def\dosubheading#1{\sectionheading{#1}{subsec}{Yomitfromtoc}{} + \suppressfirstparagraphindent} +\def\dosubsubheading#1{\sectionheading{#1}{subsubsec}{Yomitfromtoc}{} + \suppressfirstparagraphindent} + +% These macros generate a chapter, section, etc. heading only +% (including whitespace, linebreaking, etc. around it), +% given all the information in convenient, parsed form. + +%%% Args are the skip and penalty (usually negative) +\def\dobreak#1#2{\par\ifdim\lastskip<#1\removelastskip\penalty#2\vskip#1\fi} + +\def\setchapterstyle #1 {\csname CHAPF#1\endcsname} + +%%% Define plain chapter starts, and page on/off switching for it +% Parameter controlling skip before chapter headings (if needed) + +\newskip\chapheadingskip + +\def\chapbreak{\dobreak \chapheadingskip {-4000}} +\def\chappager{\par\vfill\supereject} +\def\chapoddpage{\chappager \ifodd\pageno \else \hbox to 0pt{} \chappager\fi} + +\def\setchapternewpage #1 {\csname CHAPPAG#1\endcsname} + +\def\CHAPPAGoff{% +\global\let\contentsalignmacro = \chappager +\global\let\pchapsepmacro=\chapbreak +\global\let\pagealignmacro=\chappager} + +\def\CHAPPAGon{% +\global\let\contentsalignmacro = \chappager +\global\let\pchapsepmacro=\chappager +\global\let\pagealignmacro=\chappager +\global\def\HEADINGSon{\HEADINGSsingle}} + +\def\CHAPPAGodd{% +\global\let\contentsalignmacro = \chapoddpage +\global\let\pchapsepmacro=\chapoddpage +\global\let\pagealignmacro=\chapoddpage +\global\def\HEADINGSon{\HEADINGSdouble}} + +\CHAPPAGon + +\def\CHAPFplain{% +\global\let\chapmacro=\chfplain +\global\let\centerchapmacro=\centerchfplain} + +% Normal chapter opening. +% +% #1 is the text, #2 is the section type (Ynumbered, Ynothing, +% Yappendix, Yomitfromtoc), #3 the chapter number. +% +% To test against our argument. +\def\Ynothingkeyword{Ynothing} +\def\Yomitfromtockeyword{Yomitfromtoc} +\def\Yappendixkeyword{Yappendix} +% +\def\chfplain#1#2#3{% + \pchapsepmacro + {% + \chapfonts \rm + % + % Have to define \thissection before calling \donoderef, because the + % xref code eventually uses it, as \Ytitle. On the other hand, it + % has to be called after \pchapsepmacro, or the headline will change + % too soon. + \gdef\thissection{#1}% + \gdef\thischaptername{#1}% + % + % Only insert the separating space if we have a chapter/appendix + % number, and don't print the unnumbered ``number''. + \def\temptype{#2}% + \ifx\temptype\Ynothingkeyword + \setbox0 = \hbox{}% + \def\toctype{unnchap}% + \def\thischapter{#1}% + \else\ifx\temptype\Yomitfromtockeyword + \setbox0 = \hbox{}% contents like unnumbered, but no toc entry + \def\toctype{omit}% + \xdef\thischapter{}% + \else\ifx\temptype\Yappendixkeyword + \setbox0 = \hbox{\putwordAppendix{} #3\enspace}% + \def\toctype{app}% + % We don't substitute the actual chapter name into \thischapter + % because we don't want its macros evaluated now. And we don't + % use \thissection because that changes with each section. + % + \xdef\thischapter{\putwordAppendix{} \appendixletter: + \noexpand\thischaptername}% + \else + \setbox0 = \hbox{#3\enspace}% + \def\toctype{numchap}% + \xdef\thischapter{\putwordChapter{} \the\chapno: + \noexpand\thischaptername}% + \fi\fi\fi + % + % Write the toc entry for this chapter. Must come before the + % \donoderef, because we include the current node name in the toc + % entry, and \donoderef resets it to empty. + \writetocentry{\toctype}{#1}{#3}% + % + % For pdftex, we have to write out the node definition (aka, make + % the pdfdest) after any page break, but before the actual text has + % been typeset. If the destination for the pdf outline is after the + % text, then jumping from the outline may wind up with the text not + % being visible, for instance under high magnification. + \donoderef{#2}% + % + % Typeset the actual heading. + \vbox{\hyphenpenalty=10000 \tolerance=5000 \parindent=0pt \raggedright + \hangindent=\wd0 \centerparametersmaybe + \unhbox0 #1\par}% + }% + \nobreak\bigskip % no page break after a chapter title + \nobreak +} + +% @centerchap -- centered and unnumbered. +\let\centerparametersmaybe = \relax +\def\centerchfplain#1{{% + \def\centerparametersmaybe{% + \advance\rightskip by 3\rightskip + \leftskip = \rightskip + \parfillskip = 0pt + }% + \chfplain{#1}{Ynothing}{}% +}} + +\CHAPFplain % The default + +% I don't think this chapter style is supported any more, so I'm not +% updating it with the new noderef stuff. We'll see. --karl, 11aug03. +% +\def\unnchfopen #1{% +\chapoddpage {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000 + \parindent=0pt\raggedright + \rm #1\hfill}}\bigskip \par\nobreak +} + +\def\chfopen #1#2{\chapoddpage {\chapfonts +\vbox to 3in{\vfil \hbox to\hsize{\hfil #2} \hbox to\hsize{\hfil #1} \vfil}}% +\par\penalty 5000 % +} + +\def\centerchfopen #1{% +\chapoddpage {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000 + \parindent=0pt + \hfill {\rm #1}\hfill}}\bigskip \par\nobreak +} + +\def\CHAPFopen{% +\global\let\chapmacro=\chfopen +\global\let\centerchapmacro=\centerchfopen} + + +% Section titles. These macros combine the section number parts and +% call the generic \sectionheading to do the printing. +% +\newskip\secheadingskip +\def\secheadingbreak{\dobreak \secheadingskip{-1000}} + +% Subsection titles. +\newskip\subsecheadingskip +\def\subsecheadingbreak{\dobreak \subsecheadingskip{-500}} + +% Subsubsection titles. +\def\subsubsecheadingskip{\subsecheadingskip} +\def\subsubsecheadingbreak{\subsecheadingbreak} + + +% Print any size, any type, section title. +% +% #1 is the text, #2 is the section level (sec/subsec/subsubsec), #3 is +% the section type for xrefs (Ynumbered, Ynothing, Yappendix), #4 is the +% section number. +% +\def\sectionheading#1#2#3#4{% + {% + % Switch to the right set of fonts. + \csname #2fonts\endcsname \rm + % + % Insert space above the heading. + \csname #2headingbreak\endcsname + % + % Only insert the space after the number if we have a section number. + \def\sectionlevel{#2}% + \def\temptype{#3}% + % + \ifx\temptype\Ynothingkeyword + \setbox0 = \hbox{}% + \def\toctype{unn}% + \gdef\thissection{#1}% + \else\ifx\temptype\Yomitfromtockeyword + % for @headings -- no section number, don't include in toc, + % and don't redefine \thissection. + \setbox0 = \hbox{}% + \def\toctype{omit}% + \let\sectionlevel=\empty + \else\ifx\temptype\Yappendixkeyword + \setbox0 = \hbox{#4\enspace}% + \def\toctype{app}% + \gdef\thissection{#1}% + \else + \setbox0 = \hbox{#4\enspace}% + \def\toctype{num}% + \gdef\thissection{#1}% + \fi\fi\fi + % + % Write the toc entry (before \donoderef). See comments in \chfplain. + \writetocentry{\toctype\sectionlevel}{#1}{#4}% + % + % Write the node reference (= pdf destination for pdftex). + % Again, see comments in \chfplain. + \donoderef{#3}% + % + % Output the actual section heading. + \vbox{\hyphenpenalty=10000 \tolerance=5000 \parindent=0pt \raggedright + \hangindent=\wd0 % zero if no section number + \unhbox0 #1}% + }% + % Add extra space after the heading -- half of whatever came above it. + % Don't allow stretch, though. + \kern .5 \csname #2headingskip\endcsname + % + % Do not let the kern be a potential breakpoint, as it would be if it + % was followed by glue. + \nobreak + % + % We'll almost certainly start a paragraph next, so don't let that + % glue accumulate. (Not a breakpoint because it's preceded by a + % discardable item.) + \vskip-\parskip + % + % This \nobreak is purely so the last item on the list is a \penalty + % of 10000. This is so other code, for instance \parsebodycommon, can + % check for and avoid allowing breakpoints. Otherwise, it would + % insert a valid breakpoint between: + % @section sec-whatever + % @deffn def-whatever + \nobreak +} + + +\message{toc,} +% Table of contents. +\newwrite\tocfile + +% Write an entry to the toc file, opening it if necessary. +% Called from @chapter, etc. +% +% Example usage: \writetocentry{sec}{Section Name}{\the\chapno.\the\secno} +% We append the current node name (if any) and page number as additional +% arguments for the \{chap,sec,...}entry macros which will eventually +% read this. The node name is used in the pdf outlines as the +% destination to jump to. +% +% We open the .toc file for writing here instead of at @setfilename (or +% any other fixed time) so that @contents can be anywhere in the document. +% But if #1 is `omit', then we don't do anything. This is used for the +% table of contents chapter openings themselves. +% +\newif\iftocfileopened +\def\omitkeyword{omit}% +% +\def\writetocentry#1#2#3{% + \edef\writetoctype{#1}% + \ifx\writetoctype\omitkeyword \else + \iftocfileopened\else + \immediate\openout\tocfile = \jobname.toc + \global\tocfileopenedtrue + \fi + % + \iflinks + \toks0 = {#2}% + \toks2 = \expandafter{\lastnode}% + \edef\temp{\write\tocfile{\realbackslash #1entry{\the\toks0}{#3}% + {\the\toks2}{\noexpand\folio}}}% + \temp + \fi + \fi + % + % Tell \shipout to create a pdf destination on each page, if we're + % writing pdf. These are used in the table of contents. We can't + % just write one on every page because the title pages are numbered + % 1 and 2 (the page numbers aren't printed), and so are the first + % two pages of the document. Thus, we'd have two destinations named + % `1', and two named `2'. + \ifpdf \global\pdfmakepagedesttrue \fi +} + +\newskip\contentsrightmargin \contentsrightmargin=1in +\newcount\savepageno +\newcount\lastnegativepageno \lastnegativepageno = -1 + +% Prepare to read what we've written to \tocfile. +% +\def\startcontents#1{% + % If @setchapternewpage on, and @headings double, the contents should + % start on an odd page, unlike chapters. Thus, we maintain + % \contentsalignmacro in parallel with \pagealignmacro. + % From: Torbjorn Granlund + \contentsalignmacro + \immediate\closeout\tocfile + % + % Don't need to put `Contents' or `Short Contents' in the headline. + % It is abundantly clear what they are. + \def\thischapter{}% + \chapmacro{#1}{Yomitfromtoc}{}% + % + \savepageno = \pageno + \begingroup % Set up to handle contents files properly. + \catcode`\\=0 \catcode`\{=1 \catcode`\}=2 \catcode`\@=11 + % We can't do this, because then an actual ^ in a section + % title fails, e.g., @chapter ^ -- exponentiation. --karl, 9jul97. + %\catcode`\^=7 % to see ^^e4 as \"a etc. juha@piuha.ydi.vtt.fi + \raggedbottom % Worry more about breakpoints than the bottom. + \advance\hsize by -\contentsrightmargin % Don't use the full line length. + % + % Roman numerals for page numbers. + \ifnum \pageno>0 \global\pageno = \lastnegativepageno \fi +} + + +% Normal (long) toc. +\def\contents{% + \startcontents{\putwordTOC}% + \openin 1 \jobname.toc + \ifeof 1 \else + \closein 1 + \input \jobname.toc + \fi + \vfill \eject + \contentsalignmacro % in case @setchapternewpage odd is in effect + \pdfmakeoutlines + \endgroup + \lastnegativepageno = \pageno + \global\pageno = \savepageno +} + +% And just the chapters. +\def\summarycontents{% + \startcontents{\putwordShortTOC}% + % + \let\numchapentry = \shortchapentry + \let\appentry = \shortchapentry + \let\unnchapentry = \shortunnchapentry + % We want a true roman here for the page numbers. + \secfonts + \let\rm=\shortcontrm \let\bf=\shortcontbf + \let\sl=\shortcontsl \let\tt=\shortconttt + \rm + \hyphenpenalty = 10000 + \advance\baselineskip by 1pt % Open it up a little. + \def\numsecentry##1##2##3##4{} + \let\appsecentry = \numsecentry + \let\unnsecentry = \numsecentry + \let\numsubsecentry = \numsecentry + \let\appsubsecentry = \numsecentry + \let\unnsubsecentry = \numsecentry + \let\numsubsubsecentry = \numsecentry + \let\appsubsubsecentry = \numsecentry + \let\unnsubsubsecentry = \numsecentry + \openin 1 \jobname.toc + \ifeof 1 \else + \closein 1 + \input \jobname.toc + \fi + \vfill \eject + \contentsalignmacro % in case @setchapternewpage odd is in effect + \endgroup + \lastnegativepageno = \pageno + \global\pageno = \savepageno +} +\let\shortcontents = \summarycontents + +% Typeset the label for a chapter or appendix for the short contents. +% The arg is, e.g., `A' for an appendix, or `3' for a chapter. +% +\def\shortchaplabel#1{% + % This space should be enough, since a single number is .5em, and the + % widest letter (M) is 1em, at least in the Computer Modern fonts. + % But use \hss just in case. + % (This space doesn't include the extra space that gets added after + % the label; that gets put in by \shortchapentry above.) + % + % We'd like to right-justify chapter numbers, but that looks strange + % with appendix letters. And right-justifying numbers and + % left-justifying letters looks strange when there is less than 10 + % chapters. Have to read the whole toc once to know how many chapters + % there are before deciding ... + \hbox to 1em{#1\hss}% +} + +% These macros generate individual entries in the table of contents. +% The first argument is the chapter or section name. +% The last argument is the page number. +% The arguments in between are the chapter number, section number, ... + +% Chapters, in the main contents. +\def\numchapentry#1#2#3#4{\dochapentry{#2\labelspace#1}{#4}} +% +% Chapters, in the short toc. +% See comments in \dochapentry re vbox and related settings. +\def\shortchapentry#1#2#3#4{% + \tocentry{\shortchaplabel{#2}\labelspace #1}{\doshortpageno\bgroup#4\egroup}% +} + +% Appendices, in the main contents. +% Need the word Appendix, and a fixed-size box. +% +\def\appendixbox#1{% + % We use M since it's probably the widest letter. + \setbox0 = \hbox{\putwordAppendix{} M}% + \hbox to \wd0{\putwordAppendix{} #1\hss}} +% +\def\appentry#1#2#3#4{\dochapentry{\appendixbox{#2}\labelspace#1}{#4}} + +% Unnumbered chapters. +\def\unnchapentry#1#2#3#4{\dochapentry{#1}{#4}} +\def\shortunnchapentry#1#2#3#4{\tocentry{#1}{\doshortpageno\bgroup#4\egroup}} + +% Sections. +\def\numsecentry#1#2#3#4{\dosecentry{#2\labelspace#1}{#4}} +\let\appsecentry=\numsecentry +\def\unnsecentry#1#2#3#4{\dosecentry{#1}{#4}} + +% Subsections. +\def\numsubsecentry#1#2#3#4{\dosubsecentry{#2\labelspace#1}{#4}} +\let\appsubsecentry=\numsubsecentry +\def\unnsubsecentry#1#2#3#4{\dosubsecentry{#1}{#4}} + +% And subsubsections. +\def\numsubsubsecentry#1#2#3#4{\dosubsubsecentry{#2\labelspace#1}{#4}} +\let\appsubsubsecentry=\numsubsubsecentry +\def\unnsubsubsecentry#1#2#3#4{\dosubsubsecentry{#1}{#4}} + +% This parameter controls the indentation of the various levels. +\newdimen\tocindent \tocindent = 2pc + +% Now for the actual typesetting. In all these, #1 is the text and #2 is the +% page number. +% +% If the toc has to be broken over pages, we want it to be at chapters +% if at all possible; hence the \penalty. +\def\dochapentry#1#2{% + \penalty-300 \vskip1\baselineskip plus.33\baselineskip minus.25\baselineskip + \begingroup + \chapentryfonts + \tocentry{#1}{\dopageno\bgroup#2\egroup}% + \endgroup + \nobreak\vskip .25\baselineskip plus.1\baselineskip +} + +\def\dosecentry#1#2{\begingroup + \secentryfonts \leftskip=\tocindent + \tocentry{#1}{\dopageno\bgroup#2\egroup}% +\endgroup} + +\def\dosubsecentry#1#2{\begingroup + \subsecentryfonts \leftskip=2\tocindent + \tocentry{#1}{\dopageno\bgroup#2\egroup}% +\endgroup} + +\def\dosubsubsecentry#1#2{\begingroup + \subsubsecentryfonts \leftskip=3\tocindent + \tocentry{#1}{\dopageno\bgroup#2\egroup}% +\endgroup} + +% Final typesetting of a toc entry; we use the same \entry macro as for +% the index entries, but we want to suppress hyphenation here. (We +% can't do that in the \entry macro, since index entries might consist +% of hyphenated-identifiers-that-do-not-fit-on-a-line-and-nothing-else.) +\def\tocentry#1#2{\begingroup + \vskip 0pt plus1pt % allow a little stretch for the sake of nice page breaks + % Do not use \turnoffactive in these arguments. Since the toc is + % typeset in cmr, characters such as _ would come out wrong; we + % have to do the usual translation tricks. + \entry{#1}{#2}% +\endgroup} + +% Space between chapter (or whatever) number and the title. +\def\labelspace{\hskip1em \relax} + +\def\dopageno#1{{\rm #1}} +\def\doshortpageno#1{{\rm #1}} + +\def\chapentryfonts{\secfonts \rm} +\def\secentryfonts{\textfonts} +\def\subsecentryfonts{\textfonts} +\def\subsubsecentryfonts{\textfonts} + + +\message{environments,} +% @foo ... @end foo. + +% @point{}, @result{}, @expansion{}, @print{}, @equiv{}. +% +% Since these characters are used in examples, it should be an even number of +% \tt widths. Each \tt character is 1en, so two makes it 1em. +% +\def\point{$\star$} +\def\result{\leavevmode\raise.15ex\hbox to 1em{\hfil$\Rightarrow$\hfil}} +\def\expansion{\leavevmode\raise.1ex\hbox to 1em{\hfil$\mapsto$\hfil}} +\def\print{\leavevmode\lower.1ex\hbox to 1em{\hfil$\dashv$\hfil}} +\def\equiv{\leavevmode\lower.1ex\hbox to 1em{\hfil$\ptexequiv$\hfil}} + +% The @error{} command. +% Adapted from the TeXbook's \boxit. +% +\newbox\errorbox +% +{\tentt \global\dimen0 = 3em}% Width of the box. +\dimen2 = .55pt % Thickness of rules +% The text. (`r' is open on the right, `e' somewhat less so on the left.) +\setbox0 = \hbox{\kern-.75pt \tensf error\kern-1.5pt} +% +\global\setbox\errorbox=\hbox to \dimen0{\hfil + \hsize = \dimen0 \advance\hsize by -5.8pt % Space to left+right. + \advance\hsize by -2\dimen2 % Rules. + \vbox{ + \hrule height\dimen2 + \hbox{\vrule width\dimen2 \kern3pt % Space to left of text. + \vtop{\kern2.4pt \box0 \kern2.4pt}% Space above/below. + \kern3pt\vrule width\dimen2}% Space to right. + \hrule height\dimen2} + \hfil} +% +\def\error{\leavevmode\lower.7ex\copy\errorbox} + +% @tex ... @end tex escapes into raw Tex temporarily. +% One exception: @ is still an escape character, so that @end tex works. +% But \@ or @@ will get a plain tex @ character. + +\def\tex{\begingroup + \catcode `\\=0 \catcode `\{=1 \catcode `\}=2 + \catcode `\$=3 \catcode `\&=4 \catcode `\#=6 + \catcode `\^=7 \catcode `\_=8 \catcode `\~=\active \let~=\tie + \catcode `\%=14 + \catcode `\+=\other + \catcode `\"=\other + \catcode `\==\other + \catcode `\|=\other + \catcode `\<=\other + \catcode `\>=\other + \escapechar=`\\ + % + \let\b=\ptexb + \let\bullet=\ptexbullet + \let\c=\ptexc + \let\,=\ptexcomma + \let\.=\ptexdot + \let\dots=\ptexdots + \let\equiv=\ptexequiv + \let\!=\ptexexclam + \let\i=\ptexi + \let\indent=\ptexindent + \let\noindent=\ptexnoindent + \let\{=\ptexlbrace + \let\+=\tabalign + \let\}=\ptexrbrace + \let\/=\ptexslash + \let\*=\ptexstar + \let\t=\ptext + % + \def\endldots{\mathinner{\ldots\ldots\ldots\ldots}}% + \def\enddots{\relax\ifmmode\endldots\else$\mathsurround=0pt \endldots\,$\fi}% + \def\@{@}% +\let\Etex=\endgroup} + +% Define @lisp ... @end lisp. +% @lisp does a \begingroup so it can rebind things, +% including the definition of @end lisp (which normally is erroneous). + +% Amount to narrow the margins by for @lisp. +\newskip\lispnarrowing \lispnarrowing=0.4in + +% This is the definition that ^^M gets inside @lisp, @example, and other +% such environments. \null is better than a space, since it doesn't +% have any width. +\def\lisppar{\null\endgraf} + +% Make each space character in the input produce a normal interword +% space in the output. Don't allow a line break at this space, as this +% is used only in environments like @example, where each line of input +% should produce a line of output anyway. +% +{\obeyspaces % +\gdef\sepspaces{\obeyspaces\let =\tie}} + +% Define \obeyedspace to be our active space, whatever it is. This is +% for use in \parsearg. +{\sepspaces% +\global\let\obeyedspace= } + +% This space is always present above and below environments. +\newskip\envskipamount \envskipamount = 0pt + +% Make spacing and below environment symmetrical. We use \parskip here +% to help in doing that, since in @example-like environments \parskip +% is reset to zero; thus the \afterenvbreak inserts no space -- but the +% start of the next paragraph will insert \parskip. +% +\def\aboveenvbreak{{% + % =10000 instead of <10000 because of a special case in \itemzzz, q.v. + \ifnum \lastpenalty=10000 \else + \advance\envskipamount by \parskip + \endgraf + \ifdim\lastskip<\envskipamount + \removelastskip + % it's not a good place to break if the last penalty was \nobreak + % or better ... + \ifnum\lastpenalty>10000 \else \penalty-50 \fi + \vskip\envskipamount + \fi + \fi +}} + +\let\afterenvbreak = \aboveenvbreak + +% \nonarrowing is a flag. If "set", @lisp etc don't narrow margins. +\let\nonarrowing=\relax + +% @cartouche ... @end cartouche: draw rectangle w/rounded corners around +% environment contents. +\font\circle=lcircle10 +\newdimen\circthick +\newdimen\cartouter\newdimen\cartinner +\newskip\normbskip\newskip\normpskip\newskip\normlskip +\circthick=\fontdimen8\circle +% +\def\ctl{{\circle\char'013\hskip -6pt}}% 6pt from pl file: 1/2charwidth +\def\ctr{{\hskip 6pt\circle\char'010}} +\def\cbl{{\circle\char'012\hskip -6pt}} +\def\cbr{{\hskip 6pt\circle\char'011}} +\def\carttop{\hbox to \cartouter{\hskip\lskip + \ctl\leaders\hrule height\circthick\hfil\ctr + \hskip\rskip}} +\def\cartbot{\hbox to \cartouter{\hskip\lskip + \cbl\leaders\hrule height\circthick\hfil\cbr + \hskip\rskip}} +% +\newskip\lskip\newskip\rskip + +\def\cartouche{% +\par % can't be in the midst of a paragraph. +\begingroup + \lskip=\leftskip \rskip=\rightskip + \leftskip=0pt\rightskip=0pt %we want these *outside*. + \cartinner=\hsize \advance\cartinner by-\lskip + \advance\cartinner by-\rskip + \cartouter=\hsize + \advance\cartouter by 18.4pt % allow for 3pt kerns on either +% side, and for 6pt waste from +% each corner char, and rule thickness + \normbskip=\baselineskip \normpskip=\parskip \normlskip=\lineskip + % Flag to tell @lisp, etc., not to narrow margin. + \let\nonarrowing=\comment + \vbox\bgroup + \baselineskip=0pt\parskip=0pt\lineskip=0pt + \carttop + \hbox\bgroup + \hskip\lskip + \vrule\kern3pt + \vbox\bgroup + \hsize=\cartinner + \kern3pt + \begingroup + \baselineskip=\normbskip + \lineskip=\normlskip + \parskip=\normpskip + \vskip -\parskip +\def\Ecartouche{% + \endgroup + \kern3pt + \egroup + \kern3pt\vrule + \hskip\rskip + \egroup + \cartbot + \egroup +\endgroup +}} + + +% This macro is called at the beginning of all the @example variants, +% inside a group. +\def\nonfillstart{% + \aboveenvbreak + \inENV % This group ends at the end of the body + \hfuzz = 12pt % Don't be fussy + \sepspaces % Make spaces be word-separators rather than space tokens. + \let\par = \lisppar % don't ignore blank lines + \obeylines % each line of input is a line of output + \parskip = 0pt + \parindent = 0pt + \emergencystretch = 0pt % don't try to avoid overfull boxes + % @cartouche defines \nonarrowing to inhibit narrowing + % at next level down. + \ifx\nonarrowing\relax + \advance \leftskip by \lispnarrowing + \exdentamount=\lispnarrowing + \let\exdent=\nofillexdent + \let\nonarrowing=\relax + \fi +} + +% Define the \E... control sequence only if we are inside the particular +% environment, so the error checking in \end will work. +% +% To end an @example-like environment, we first end the paragraph (via +% \afterenvbreak's vertical glue), and then the group. That way we keep +% the zero \parskip that the environments set -- \parskip glue will be +% inserted at the beginning of the next paragraph in the document, after +% the environment. +% +\def\nonfillfinish{\afterenvbreak\endgroup} + +% @lisp: indented, narrowed, typewriter font. +\def\lisp{\begingroup + \nonfillstart + \let\Elisp = \nonfillfinish + \tt + \let\kbdfont = \kbdexamplefont % Allow @kbd to do something special. + \gobble % eat return +} + +% @example: Same as @lisp. +\def\example{\begingroup \def\Eexample{\nonfillfinish\endgroup}\lisp} + +% @smallexample and @smalllisp: use smaller fonts. +% Originally contributed by Pavel@xerox. +\def\smalllisp{\begingroup + \def\Esmalllisp{\nonfillfinish\endgroup}% + \def\Esmallexample{\nonfillfinish\endgroup}% + \smallexamplefonts + \lisp +} +\let\smallexample = \smalllisp + + +% @display: same as @lisp except keep current font. +% +\def\display{\begingroup + \nonfillstart + \let\Edisplay = \nonfillfinish + \gobble +} +% +% @smalldisplay: @display plus smaller fonts. +% +\def\smalldisplay{\begingroup + \def\Esmalldisplay{\nonfillfinish\endgroup}% + \smallexamplefonts \rm + \display +} + +% @format: same as @display except don't narrow margins. +% +\def\format{\begingroup + \let\nonarrowing = t + \nonfillstart + \let\Eformat = \nonfillfinish + \gobble +} +% +% @smallformat: @format plus smaller fonts. +% +\def\smallformat{\begingroup + \def\Esmallformat{\nonfillfinish\endgroup}% + \smallexamplefonts \rm + \format +} + +% @flushleft (same as @format). +% +\def\flushleft{\begingroup \def\Eflushleft{\nonfillfinish\endgroup}\format} + +% @flushright. +% +\def\flushright{\begingroup + \let\nonarrowing = t + \nonfillstart + \let\Eflushright = \nonfillfinish + \advance\leftskip by 0pt plus 1fill + \gobble +} + + +% @quotation does normal linebreaking (hence we can't use \nonfillstart) +% and narrows the margins. +% +\def\quotation{% + \begingroup\inENV %This group ends at the end of the @quotation body + {\parskip=0pt \aboveenvbreak}% because \aboveenvbreak inserts \parskip + \parindent=0pt + % We have retained a nonzero parskip for the environment, since we're + % doing normal filling. So to avoid extra space below the environment... + \def\Equotation{\parskip = 0pt \nonfillfinish}% + % + % @cartouche defines \nonarrowing to inhibit narrowing at next level down. + \ifx\nonarrowing\relax + \advance\leftskip by \lispnarrowing + \advance\rightskip by \lispnarrowing + \exdentamount = \lispnarrowing + \let\nonarrowing = \relax + \fi +} + + +% LaTeX-like @verbatim...@end verbatim and @verb{...} +% If we want to allow any as delimiter, +% we need the curly braces so that makeinfo sees the @verb command, eg: +% `@verbx...x' would look like the '@verbx' command. --janneke@gnu.org +% +% [Knuth]: Donald Ervin Knuth, 1996. The TeXbook. +% +% [Knuth] p.344; only we need to do the other characters Texinfo sets +% active too. Otherwise, they get lost as the first character on a +% verbatim line. +\def\dospecials{% + \do\ \do\\\do\{\do\}\do\$\do\&% + \do\#\do\^\do\^^K\do\_\do\^^A\do\%\do\~% + \do\<\do\>\do\|\do\@\do+\do\"% +} +% +% [Knuth] p. 380 +\def\uncatcodespecials{% + \def\do##1{\catcode`##1=12}\dospecials} +% +% [Knuth] pp. 380,381,391 +% Disable Spanish ligatures ?` and !` of \tt font +\begingroup + \catcode`\`=\active\gdef`{\relax\lq} +\endgroup +% +% Setup for the @verb command. +% +% Eight spaces for a tab +\begingroup + \catcode`\^^I=\active + \gdef\tabeightspaces{\catcode`\^^I=\active\def^^I{\ \ \ \ \ \ \ \ }} +\endgroup +% +\def\setupverb{% + \tt % easiest (and conventionally used) font for verbatim + \def\par{\leavevmode\endgraf}% + \catcode`\`=\active + \tabeightspaces + % Respect line breaks, + % print special symbols as themselves, and + % make each space count + % must do in this order: + \obeylines \uncatcodespecials \sepspaces +} + +% Setup for the @verbatim environment +% +% Real tab expansion +\newdimen\tabw \setbox0=\hbox{\tt\space} \tabw=8\wd0 % tab amount +% +\def\starttabbox{\setbox0=\hbox\bgroup} +\begingroup + \catcode`\^^I=\active + \gdef\tabexpand{% + \catcode`\^^I=\active + \def^^I{\leavevmode\egroup + \dimen0=\wd0 % the width so far, or since the previous tab + \divide\dimen0 by\tabw + \multiply\dimen0 by\tabw % compute previous multiple of \tabw + \advance\dimen0 by\tabw % advance to next multiple of \tabw + \wd0=\dimen0 \box0 \starttabbox + }% + } +\endgroup +\def\setupverbatim{% + % Easiest (and conventionally used) font for verbatim + \tt + \def\par{\leavevmode\egroup\box0\endgraf}% + \catcode`\`=\active + \tabexpand + % Respect line breaks, + % print special symbols as themselves, and + % make each space count + % must do in this order: + \obeylines \uncatcodespecials \sepspaces + \everypar{\starttabbox}% +} + +% Do the @verb magic: verbatim text is quoted by unique +% delimiter characters. Before first delimiter expect a +% right brace, after last delimiter expect closing brace: +% +% \def\doverb'{'#1'}'{#1} +% +% [Knuth] p. 382; only eat outer {} +\begingroup + \catcode`[=1\catcode`]=2\catcode`\{=12\catcode`\}=12 + \gdef\doverb{#1[\def\next##1#1}[##1\endgroup]\next] +\endgroup +% +\def\verb{\begingroup\setupverb\doverb} +% +% +% Do the @verbatim magic: define the macro \doverbatim so that +% the (first) argument ends when '@end verbatim' is reached, ie: +% +% \def\doverbatim#1@end verbatim{#1} +% +% For Texinfo it's a lot easier than for LaTeX, +% because texinfo's \verbatim doesn't stop at '\end{verbatim}': +% we need not redefine '\', '{' and '}'. +% +% Inspired by LaTeX's verbatim command set [latex.ltx] +%% Include LaTeX hack for completeness -- never know +%% \begingroup +%% \catcode`|=0 \catcode`[=1 +%% \catcode`]=2\catcode`\{=12\catcode`\}=12\catcode`\ =\active +%% \catcode`\\=12|gdef|doverbatim#1@end verbatim[ +%% #1|endgroup|def|Everbatim[]|end[verbatim]] +%% |endgroup +% +\begingroup + \catcode`\ =\active + \obeylines % + % ignore everything up to the first ^^M, that's the newline at the end + % of the @verbatim input line itself. Otherwise we get an extra blank + % line in the output. + \gdef\doverbatim#1^^M#2@end verbatim{#2\end{verbatim}}% +\endgroup +% +\def\verbatim{% + \def\Everbatim{\nonfillfinish\endgroup}% + \begingroup + \nonfillstart + \advance\leftskip by -\defbodyindent + \begingroup\setupverbatim\doverbatim +} + +% @verbatiminclude FILE - insert text of file in verbatim environment. +% +% Allow normal characters that we make active in the argument (a file name). +\def\verbatiminclude{% + \begingroup + \catcode`\\=\other + \catcode`~=\other + \catcode`^=\other + \catcode`_=\other + \catcode`|=\other + \catcode`<=\other + \catcode`>=\other + \catcode`+=\other + \parsearg\doverbatiminclude +} +\def\setupverbatiminclude{% + \begingroup + \nonfillstart + \advance\leftskip by -\defbodyindent + \begingroup\setupverbatim +} +% +\def\doverbatiminclude#1{% + % Restore active chars for included file. + \endgroup + \begingroup + \let\value=\expandablevalue + \def\thisfile{#1}% + \expandafter\expandafter\setupverbatiminclude\input\thisfile + \endgroup + \nonfillfinish + \endgroup +} + +% @copying ... @end copying. +% Save the text away for @insertcopying later. Many commands won't be +% allowed in this context, but that's ok. +% +% We save the uninterpreted tokens, rather than creating a box. +% Saving the text in a box would be much easier, but then all the +% typesetting commands (@smallbook, font changes, etc.) have to be done +% beforehand -- and a) we want @copying to be done first in the source +% file; b) letting users define the frontmatter in as flexible order as +% possible is very desirable. +% +\def\copying{\begingroup + % Define a command to swallow text until we reach `@end copying'. + % \ is the escape char in this texinfo.tex file, so it is the + % delimiter for the command; @ will be the escape char when we read + % it, but that doesn't matter. + \long\def\docopying##1\end copying{\gdef\copyingtext{##1}\enddocopying}% + % + % We must preserve ^^M's in the input file; see \insertcopying below. + \catcode`\^^M = \active + \docopying +} + +% What we do to finish off the copying text. +% +\def\enddocopying{\endgroup\ignorespaces} + +% @insertcopying. Here we must play games with ^^M's. On the one hand, +% we need them to delimit commands such as `@end quotation', so they +% must be active. On the other hand, we certainly don't want every +% end-of-line to be a \par, as would happen with the normal active +% definition of ^^M. On the third hand, two ^^M's in a row should still +% generate a \par. +% +% Our approach is to make ^^M insert a space and a penalty1 normally; +% then it can also check if \lastpenalty=1. If it does, then manually +% do \par. +% +% This messes up the normal definitions of @c[omment], so we redefine +% it. Similarly for @ignore. (These commands are used in the gcc +% manual for man page generation.) +% +% Seems pretty fragile, most line-oriented commands will presumably +% fail, but for the limited use of getting the copying text (which +% should be quite simple) inserted, we can hope it's ok. +% +{\catcode`\^^M=\active % +\gdef\insertcopying{\begingroup % + \parindent = 0pt % looks wrong on title page + \def^^M{% + \ifnum \lastpenalty=1 % + \par % + \else % + \space \penalty 1 % + \fi % + }% + % + % Fix @c[omment] for catcode 13 ^^M's. + \def\c##1^^M{\ignorespaces}% + \let\comment = \c % + % + % Don't bother jumping through all the hoops that \doignore does, it + % would be very hard since the catcodes are already set. + \long\def\ignore##1\end ignore{\ignorespaces}% + % + \copyingtext % +\endgroup}% +} + +\message{defuns,} +% @defun etc. + +\newskip\defbodyindent \defbodyindent=.4in +\newskip\defargsindent \defargsindent=50pt +\newskip\deflastargmargin \deflastargmargin=18pt + +\newcount\parencount + +% We want ()&[] to print specially on the defun line. +% +\def\activeparens{% + \catcode`\(=\active \catcode`\)=\active + \catcode`\&=\active + \catcode`\[=\active \catcode`\]=\active +} + +% Make control sequences which act like normal parenthesis chars. +\let\lparen = ( \let\rparen = ) + +{\activeparens % Now, smart parens don't turn on until &foo (see \amprm) + +% Be sure that we always have a definition for `(', etc. For example, +% if the fn name has parens in it, \boldbrax will not be in effect yet, +% so TeX would otherwise complain about undefined control sequence. +\global\let(=\lparen \global\let)=\rparen +\global\let[=\lbrack \global\let]=\rbrack + +\gdef\functionparens{\boldbrax\let&=\amprm\parencount=0 } +\gdef\boldbrax{\let(=\opnr\let)=\clnr\let[=\lbrb\let]=\rbrb} +% This is used to turn on special parens +% but make & act ordinary (given that it's active). +\gdef\boldbraxnoamp{\let(=\opnr\let)=\clnr\let[=\lbrb\let]=\rbrb\let&=\ampnr} + +% Definitions of (, ) and & used in args for functions. +% This is the definition of ( outside of all parentheses. +\gdef\oprm#1 {{\rm\char`\(}#1 \bf \let(=\opnested + \global\advance\parencount by 1 +} +% +% This is the definition of ( when already inside a level of parens. +\gdef\opnested{\char`\(\global\advance\parencount by 1 } +% +\gdef\clrm{% Print a paren in roman if it is taking us back to depth of 0. + % also in that case restore the outer-level definition of (. + \ifnum \parencount=1 {\rm \char `\)}\sl \let(=\oprm \else \char `\) \fi + \global\advance \parencount by -1 } +% If we encounter &foo, then turn on ()-hacking afterwards +\gdef\amprm#1 {{\rm\}\let(=\oprm \let)=\clrm\ } +% +\gdef\normalparens{\boldbrax\let&=\ampnr} +} % End of definition inside \activeparens +%% These parens (in \boldbrax) actually are a little bolder than the +%% contained text. This is especially needed for [ and ] +\def\opnr{{\sf\char`\(}\global\advance\parencount by 1 } +\def\clnr{{\sf\char`\)}\global\advance\parencount by -1 } +\let\ampnr = \& +\def\lbrb{{\bf\char`\[}} +\def\rbrb{{\bf\char`\]}} + +% Active &'s sneak into the index arguments, so make sure it's defined. +{ + \catcode`& = \active + \global\let& = \ampnr +} + +% \defname, which formats the name of the @def (not the args). +% #1 is the function name. +% #2 is the type of definition, such as "Function". +% +\def\defname#1#2{% + % How we'll output the type name. Putting it in brackets helps + % distinguish it from the body text that may end up on the next line + % just below it. + \ifempty{#2}% + \def\defnametype{}% + \else + \def\defnametype{[\rm #2]}% + \fi + % + % Get the values of \leftskip and \rightskip as they were outside the @def... + \dimen2=\leftskip + \advance\dimen2 by -\defbodyindent + % + % Figure out values for the paragraph shape. + \setbox0=\hbox{\hskip \deflastargmargin{\defnametype}}% + \dimen0=\hsize \advance \dimen0 by -\wd0 % compute size for first line + \dimen1=\hsize \advance \dimen1 by -\defargsindent % size for continuations + \parshape 2 0in \dimen0 \defargsindent \dimen1 + % + % Output arg 2 ("Function" or some such) but stuck inside a box of + % width 0 so it does not interfere with linebreaking. + \noindent + % + {% Adjust \hsize to exclude the ambient margins, + % so that \rightline will obey them. + \advance \hsize by -\dimen2 + \dimen3 = 0pt % was -1.25pc + \rlap{\rightline{\defnametype\kern\dimen3}}% + }% + % + % Allow all lines to be underfull without complaint: + \tolerance=10000 \hbadness=10000 + \advance\leftskip by -\defbodyindent + \exdentamount=\defbodyindent + {\df #1}\enskip % output function name + % \defunargs will be called next to output the arguments, if any. +} + +% Common pieces to start any @def... +% #1 is the \E... control sequence to end the definition (which we define). +% #2 is the \...x control sequence (which our caller defines). +% #3 is the control sequence to process the header, such as \defunheader. +% +\def\parsebodycommon#1#2#3{% + \begingroup\inENV + % If there are two @def commands in a row, we'll have a \nobreak, + % which is there to keep the function description together with its + % header. But if there's nothing but headers, we need to allow a + % break somewhere. Check for penalty 10002 (inserted by + % \defargscommonending) instead of 10000, since the sectioning + % commands insert a \penalty10000, and we don't want to allow a break + % between a section heading and a defun. + \ifnum\lastpenalty=10002 \penalty2000 \fi + % + % Similarly, after a section heading, do not allow a break. + % But do insert the glue. + \ifnum\lastpenalty<10000 \medbreak + \else \medskip % preceded by discardable penalty, so not a breakpoint + \fi + % + % Define the \E... end token that this defining construct specifies + % so that it will exit this group. + \def#1{\endgraf\endgroup\medbreak}% + % + \parindent=0in + \advance\leftskip by \defbodyindent + \exdentamount=\defbodyindent +} + +% Common part of the \...x definitions. +% +\def\defxbodycommon{% + % As with \parsebodycommon above, allow line break if we have multiple + % x headers in a row. It's not a great place, though. + \ifnum\lastpenalty=10002 \penalty2000 \fi + % + \begingroup\obeylines +} + +% Process body of @defun, @deffn, @defmac, etc. +% +\def\defparsebody#1#2#3{% + \parsebodycommon{#1}{#2}{#3}% + \def#2{\defxbodycommon \activeparens \spacesplit#3}% + \catcode\equalChar=\active + \begingroup\obeylines\activeparens + \spacesplit#3% +} + +% #1, #2, #3 are the common arguments (see \parsebodycommon above). +% #4, delimited by the space, is the class name. +% +\def\defmethparsebody#1#2#3#4 {% + \parsebodycommon{#1}{#2}{#3}% + \def#2##1 {\defxbodycommon \activeparens \spacesplit{#3{##1}}}% + \begingroup\obeylines\activeparens + % The \empty here prevents misinterpretation of a construct such as + % @deffn {whatever} {Enharmonic comma} + % See comments at \deftpparsebody, although in our case we don't have + % to remove the \empty afterwards, since it is empty. + \spacesplit{#3{#4}}\empty +} + +% Used for @deftypemethod and @deftypeivar. +% #1, #2, #3 are the common arguments (see \defparsebody). +% #4, delimited by a space, is the class name. +% #5 is the method's return type. +% +\def\deftypemethparsebody#1#2#3#4 #5 {% + \parsebodycommon{#1}{#2}{#3}% + \def#2##1 ##2 {\defxbodycommon \activeparens \spacesplit{#3{##1}{##2}}}% + \begingroup\obeylines\activeparens + \spacesplit{#3{#4}{#5}}% +} + +% Used for @deftypeop. The change from \deftypemethparsebody is an +% extra argument at the beginning which is the `category', instead of it +% being the hardwired string `Method' or `Instance Variable'. We have +% to account for this both in the \...x definition and in parsing the +% input at hand. Thus also need a control sequence (passed as #5) for +% the \E... definition to assign the category name to. +% +\def\deftypeopparsebody#1#2#3#4#5 #6 {% + \parsebodycommon{#1}{#2}{#3}% + \def#2##1 ##2 ##3 {\def#4{##1}% + \defxbodycommon \activeparens \spacesplit{#3{##2}{##3}}}% + \begingroup\obeylines\activeparens + \spacesplit{#3{#5}{#6}}% +} + +% For @defop. +\def\defopparsebody #1#2#3#4#5 {% + \parsebodycommon{#1}{#2}{#3}% + \def#2##1 ##2 {\def#4{##1}% + \defxbodycommon \activeparens \spacesplit{#3{##2}}}% + \begingroup\obeylines\activeparens + \spacesplit{#3{#5}}% +} + +% These parsing functions are similar to the preceding ones +% except that they do not make parens into active characters. +% These are used for "variables" since they have no arguments. +% +\def\defvarparsebody #1#2#3{% + \parsebodycommon{#1}{#2}{#3}% + \def#2{\defxbodycommon \spacesplit#3}% + \catcode\equalChar=\active + \begingroup\obeylines + \spacesplit#3% +} + +% @defopvar. +\def\defopvarparsebody #1#2#3#4#5 {% + \parsebodycommon{#1}{#2}{#3}% + \def#2##1 ##2 {\def#4{##1}% + \defxbodycommon \spacesplit{#3{##2}}}% + \begingroup\obeylines + \spacesplit{#3{#5}}% +} + +\def\defvrparsebody#1#2#3#4 {% + \parsebodycommon{#1}{#2}{#3}% + \def#2##1 {\defxbodycommon \spacesplit{#3{##1}}}% + \begingroup\obeylines + \spacesplit{#3{#4}}% +} + +% This loses on `@deftp {Data Type} {struct termios}' -- it thinks the +% type is just `struct', because we lose the braces in `{struct +% termios}' when \spacesplit reads its undelimited argument. Sigh. +% \let\deftpparsebody=\defvrparsebody +% +% So, to get around this, we put \empty in with the type name. That +% way, TeX won't find exactly `{...}' as an undelimited argument, and +% won't strip off the braces. +% +\def\deftpparsebody #1#2#3#4 {% + \parsebodycommon{#1}{#2}{#3}% + \def#2##1 {\defxbodycommon \spacesplit{#3{##1}}}% + \begingroup\obeylines + \spacesplit{\parsetpheaderline{#3{#4}}}\empty +} + +% Fine, but then we have to eventually remove the \empty *and* the +% braces (if any). That's what this does. +% +\def\removeemptybraces\empty#1\relax{#1} + +% After \spacesplit has done its work, this is called -- #1 is the final +% thing to call, #2 the type name (which starts with \empty), and #3 +% (which might be empty) the arguments. +% +\def\parsetpheaderline#1#2#3{% + #1{\removeemptybraces#2\relax}{#3}% +}% + +% Split up #2 (the rest of the input line) at the first space token. +% call #1 with two arguments: +% the first is all of #2 before the space token, +% the second is all of #2 after that space token. +% If #2 contains no space token, all of it is passed as the first arg +% and the second is passed as empty. +% +{\obeylines % + \gdef\spacesplit#1#2^^M{\endgroup\spacesplitx{#1}#2 \relax\spacesplitx}% + \long\gdef\spacesplitx#1#2 #3#4\spacesplitx{% + \ifx\relax #3% + #1{#2}{}% + \else % + #1{#2}{#3#4}% + \fi}% +} + +% Define @defun. + +% This is called to end the arguments processing for all the @def... commands. +% +\def\defargscommonending{% + \interlinepenalty = 10000 + \advance\rightskip by 0pt plus 1fil + \endgraf + \nobreak\vskip -\parskip + \penalty 10002 % signal to \parsebodycommon and \defxbodycommon. +} + +% This expands the args and terminates the paragraph they comprise. +% +\def\defunargs#1{\functionparens \sl +% Expand, preventing hyphenation at `-' chars. +% Note that groups don't affect changes in \hyphenchar. +% Set the font temporarily and use \font in case \setfont made \tensl a macro. +{\tensl\hyphenchar\font=0}% +#1% +{\tensl\hyphenchar\font=45}% +\ifnum\parencount=0 \else \errmessage{Unbalanced parentheses in @def}\fi% + \defargscommonending +} + +\def\deftypefunargs #1{% +% Expand, preventing hyphenation at `-' chars. +% Note that groups don't affect changes in \hyphenchar. +% Use \boldbraxnoamp, not \functionparens, so that & is not special. +\boldbraxnoamp +\tclose{#1}% avoid \code because of side effects on active chars + \defargscommonending +} + +% Do complete processing of one @defun or @defunx line already parsed. + +% @deffn Command forward-char nchars + +\def\deffn{\defmethparsebody\Edeffn\deffnx\deffnheader} + +\def\deffnheader #1#2#3{\doind {fn}{\code{#2}}% +\begingroup\defname {#2}{#1}\defunargs{#3}\endgroup % +\catcode\equalChar=\other % Turn off change made in \defparsebody +} + +% @defun == @deffn Function + +\def\defun{\defparsebody\Edefun\defunx\defunheader} + +\def\defunheader #1#2{\doind {fn}{\code{#1}}% Make entry in function index +\begingroup\defname {#1}{\putwordDeffunc}% +\defunargs {#2}\endgroup % +\catcode\equalChar=\other % Turn off change made in \defparsebody +} + +% @deftypefun int foobar (int @var{foo}, float @var{bar}) + +\def\deftypefun{\defparsebody\Edeftypefun\deftypefunx\deftypefunheader} + +% #1 is the data type. #2 is the name and args. +\def\deftypefunheader #1#2{\deftypefunheaderx{#1}#2 \relax} +% #1 is the data type, #2 the name, #3 the args. +\def\deftypefunheaderx #1#2 #3\relax{% +\doind {fn}{\code{#2}}% Make entry in function index +\begingroup\defname {\defheaderxcond#1\relax$.$#2}{\putwordDeftypefun}% +\deftypefunargs {#3}\endgroup % +\catcode\equalChar=\other % Turn off change made in \defparsebody +} + +% @deftypefn {Library Function} int foobar (int @var{foo}, float @var{bar}) + +\def\deftypefn{\defmethparsebody\Edeftypefn\deftypefnx\deftypefnheader} + +% \defheaderxcond#1\relax$.$ +% puts #1 in @code, followed by a space, but does nothing if #1 is null. +\def\defheaderxcond#1#2$.${\ifx#1\relax\else\code{#1#2} \fi} + +% #1 is the classification. #2 is the data type. #3 is the name and args. +\def\deftypefnheader #1#2#3{\deftypefnheaderx{#1}{#2}#3 \relax} +% #1 is the classification, #2 the data type, #3 the name, #4 the args. +\def\deftypefnheaderx #1#2#3 #4\relax{% +\doind {fn}{\code{#3}}% Make entry in function index +\begingroup +\normalparens % notably, turn off `&' magic, which prevents +% at least some C++ text from working +\defname {\defheaderxcond#2\relax$.$#3}{#1}% +\deftypefunargs {#4}\endgroup % +\catcode\equalChar=\other % Turn off change made in \defparsebody +} + +% @defmac == @deffn Macro + +\def\defmac{\defparsebody\Edefmac\defmacx\defmacheader} + +\def\defmacheader #1#2{\doind {fn}{\code{#1}}% Make entry in function index +\begingroup\defname {#1}{\putwordDefmac}% +\defunargs {#2}\endgroup % +\catcode\equalChar=\other % Turn off change made in \defparsebody +} + +% @defspec == @deffn Special Form + +\def\defspec{\defparsebody\Edefspec\defspecx\defspecheader} + +\def\defspecheader #1#2{\doind {fn}{\code{#1}}% Make entry in function index +\begingroup\defname {#1}{\putwordDefspec}% +\defunargs {#2}\endgroup % +\catcode\equalChar=\other % Turn off change made in \defparsebody +} + +% @defop CATEGORY CLASS OPERATION ARG... +% +\def\defop #1 {\def\defoptype{#1}% +\defopparsebody\Edefop\defopx\defopheader\defoptype} +% +\def\defopheader#1#2#3{% + \dosubind{fn}{\code{#2}}{\putwordon\ \code{#1}}% function index entry + \begingroup + \defname{#2}{\defoptype\ \putwordon\ #1}% + \defunargs{#3}% + \endgroup +} + +% @deftypeop CATEGORY CLASS TYPE OPERATION ARG... +% +\def\deftypeop #1 {\def\deftypeopcategory{#1}% + \deftypeopparsebody\Edeftypeop\deftypeopx\deftypeopheader + \deftypeopcategory} +% +% #1 is the class name, #2 the data type, #3 the operation name, #4 the args. +\def\deftypeopheader#1#2#3#4{% + \dosubind{fn}{\code{#3}}{\putwordon\ \code{#1}}% entry in function index + \begingroup + \defname{\defheaderxcond#2\relax$.$#3} + {\deftypeopcategory\ \putwordon\ \code{#1}}% + \deftypefunargs{#4}% + \endgroup +} + +% @deftypemethod CLASS TYPE METHOD ARG... +% +\def\deftypemethod{% + \deftypemethparsebody\Edeftypemethod\deftypemethodx\deftypemethodheader} +% +% #1 is the class name, #2 the data type, #3 the method name, #4 the args. +\def\deftypemethodheader#1#2#3#4{% + \dosubind{fn}{\code{#3}}{\putwordon\ \code{#1}}% entry in function index + \begingroup + \defname{\defheaderxcond#2\relax$.$#3}{\putwordMethodon\ \code{#1}}% + \deftypefunargs{#4}% + \endgroup +} + +% @deftypeivar CLASS TYPE VARNAME +% +\def\deftypeivar{% + \deftypemethparsebody\Edeftypeivar\deftypeivarx\deftypeivarheader} +% +% #1 is the class name, #2 the data type, #3 the variable name. +\def\deftypeivarheader#1#2#3{% + \dosubind{vr}{\code{#3}}{\putwordof\ \code{#1}}% entry in variable index + \begingroup + \defname{\defheaderxcond#2\relax$.$#3} + {\putwordInstanceVariableof\ \code{#1}}% + \defvarargs{#3}% + \endgroup +} + +% @defmethod == @defop Method +% +\def\defmethod{\defmethparsebody\Edefmethod\defmethodx\defmethodheader} +% +% #1 is the class name, #2 the method name, #3 the args. +\def\defmethodheader#1#2#3{% + \dosubind{fn}{\code{#2}}{\putwordon\ \code{#1}}% entry in function index + \begingroup + \defname{#2}{\putwordMethodon\ \code{#1}}% + \defunargs{#3}% + \endgroup +} + +% @defcv {Class Option} foo-class foo-flag + +\def\defcv #1 {\def\defcvtype{#1}% +\defopvarparsebody\Edefcv\defcvx\defcvarheader\defcvtype} + +\def\defcvarheader #1#2#3{% + \dosubind{vr}{\code{#2}}{\putwordof\ \code{#1}}% variable index entry + \begingroup + \defname{#2}{\defcvtype\ \putwordof\ #1}% + \defvarargs{#3}% + \endgroup +} + +% @defivar CLASS VARNAME == @defcv {Instance Variable} CLASS VARNAME +% +\def\defivar{\defvrparsebody\Edefivar\defivarx\defivarheader} +% +\def\defivarheader#1#2#3{% + \dosubind{vr}{\code{#2}}{\putwordof\ \code{#1}}% entry in var index + \begingroup + \defname{#2}{\putwordInstanceVariableof\ #1}% + \defvarargs{#3}% + \endgroup +} + +% @defvar +% First, define the processing that is wanted for arguments of @defvar. +% This is actually simple: just print them in roman. +% This must expand the args and terminate the paragraph they make up +\def\defvarargs #1{\normalparens #1% + \defargscommonending +} + +% @defvr Counter foo-count + +\def\defvr{\defvrparsebody\Edefvr\defvrx\defvrheader} + +\def\defvrheader #1#2#3{\doind {vr}{\code{#2}}% +\begingroup\defname {#2}{#1}\defvarargs{#3}\endgroup} + +% @defvar == @defvr Variable + +\def\defvar{\defvarparsebody\Edefvar\defvarx\defvarheader} + +\def\defvarheader #1#2{\doind {vr}{\code{#1}}% Make entry in var index +\begingroup\defname {#1}{\putwordDefvar}% +\defvarargs {#2}\endgroup % +} + +% @defopt == @defvr {User Option} + +\def\defopt{\defvarparsebody\Edefopt\defoptx\defoptheader} + +\def\defoptheader #1#2{\doind {vr}{\code{#1}}% Make entry in var index +\begingroup\defname {#1}{\putwordDefopt}% +\defvarargs {#2}\endgroup % +} + +% @deftypevar int foobar + +\def\deftypevar{\defvarparsebody\Edeftypevar\deftypevarx\deftypevarheader} + +% #1 is the data type. #2 is the name, perhaps followed by text that +% is actually part of the data type, which should not be put into the index. +\def\deftypevarheader #1#2{% +\dovarind#2 \relax% Make entry in variables index +\begingroup\defname {\defheaderxcond#1\relax$.$#2}{\putwordDeftypevar}% + \defargscommonending +\endgroup} +\def\dovarind#1 #2\relax{\doind{vr}{\code{#1}}} + +% @deftypevr {Global Flag} int enable + +\def\deftypevr{\defvrparsebody\Edeftypevr\deftypevrx\deftypevrheader} + +\def\deftypevrheader #1#2#3{\dovarind#3 \relax% +\begingroup\defname {\defheaderxcond#2\relax$.$#3}{#1} + \defargscommonending +\endgroup} + +% Now define @deftp +% Args are printed in bold, a slight difference from @defvar. + +\def\deftpargs #1{\bf \defvarargs{#1}} + +% @deftp Class window height width ... + +\def\deftp{\deftpparsebody\Edeftp\deftpx\deftpheader} + +\def\deftpheader #1#2#3{\doind {tp}{\code{#2}}% +\begingroup\defname {#2}{#1}\deftpargs{#3}\endgroup} + +% These definitions are used if you use @defunx (etc.) +% anywhere other than immediately after a @defun or @defunx. +% +\def\defcvx#1 {\errmessage{@defcvx in invalid context}} +\def\deffnx#1 {\errmessage{@deffnx in invalid context}} +\def\defivarx#1 {\errmessage{@defivarx in invalid context}} +\def\defmacx#1 {\errmessage{@defmacx in invalid context}} +\def\defmethodx#1 {\errmessage{@defmethodx in invalid context}} +\def\defoptx #1 {\errmessage{@defoptx in invalid context}} +\def\defopx#1 {\errmessage{@defopx in invalid context}} +\def\defspecx#1 {\errmessage{@defspecx in invalid context}} +\def\deftpx#1 {\errmessage{@deftpx in invalid context}} +\def\deftypefnx#1 {\errmessage{@deftypefnx in invalid context}} +\def\deftypefunx#1 {\errmessage{@deftypefunx in invalid context}} +\def\deftypeivarx#1 {\errmessage{@deftypeivarx in invalid context}} +\def\deftypemethodx#1 {\errmessage{@deftypemethodx in invalid context}} +\def\deftypeopx#1 {\errmessage{@deftypeopx in invalid context}} +\def\deftypevarx#1 {\errmessage{@deftypevarx in invalid context}} +\def\deftypevrx#1 {\errmessage{@deftypevrx in invalid context}} +\def\defunx#1 {\errmessage{@defunx in invalid context}} +\def\defvarx#1 {\errmessage{@defvarx in invalid context}} +\def\defvrx#1 {\errmessage{@defvrx in invalid context}} + + +\message{macros,} +% @macro. + +% To do this right we need a feature of e-TeX, \scantokens, +% which we arrange to emulate with a temporary file in ordinary TeX. +\ifx\eTeXversion\undefined + \newwrite\macscribble + \def\scanmacro#1{% + \begingroup \newlinechar`\^^M + % Undo catcode changes of \startcontents and \doprintindex + \catcode`\@=0 \catcode`\\=\other \escapechar=`\@ + % Append \endinput to make sure that TeX does not see the ending newline. + \toks0={#1\endinput}% + \immediate\openout\macscribble=\jobname.tmp + \immediate\write\macscribble{\the\toks0}% + \immediate\closeout\macscribble + \let\xeatspaces\eatspaces + \input \jobname.tmp + \endgroup +} +\else +\def\scanmacro#1{% +\begingroup \newlinechar`\^^M +% Undo catcode changes of \startcontents and \doprintindex +\catcode`\@=0 \catcode`\\=\other \escapechar=`\@ +\let\xeatspaces\eatspaces\scantokens{#1\endinput}\endgroup} +\fi + +\newcount\paramno % Count of parameters +\newtoks\macname % Macro name +\newif\ifrecursive % Is it recursive? +\def\macrolist{} % List of all defined macros in the form + % \do\macro1\do\macro2... + +% Utility routines. +% Thisdoes \let #1 = #2, except with \csnames. +\def\cslet#1#2{% +\expandafter\expandafter +\expandafter\let +\expandafter\expandafter +\csname#1\endcsname +\csname#2\endcsname} + +% Trim leading and trailing spaces off a string. +% Concepts from aro-bend problem 15 (see CTAN). +{\catcode`\@=11 +\gdef\eatspaces #1{\expandafter\trim@\expandafter{#1 }} +\gdef\trim@ #1{\trim@@ @#1 @ #1 @ @@} +\gdef\trim@@ #1@ #2@ #3@@{\trim@@@\empty #2 @} +\def\unbrace#1{#1} +\unbrace{\gdef\trim@@@ #1 } #2@{#1} +} + +% Trim a single trailing ^^M off a string. +{\catcode`\^^M=\other \catcode`\Q=3% +\gdef\eatcr #1{\eatcra #1Q^^MQ}% +\gdef\eatcra#1^^MQ{\eatcrb#1Q}% +\gdef\eatcrb#1Q#2Q{#1}% +} + +% Macro bodies are absorbed as an argument in a context where +% all characters are catcode 10, 11 or 12, except \ which is active +% (as in normal texinfo). It is necessary to change the definition of \. + +% It's necessary to have hard CRs when the macro is executed. This is +% done by making ^^M (\endlinechar) catcode 12 when reading the macro +% body, and then making it the \newlinechar in \scanmacro. + +\def\macrobodyctxt{% + \catcode`\~=\other + \catcode`\^=\other + \catcode`\_=\other + \catcode`\|=\other + \catcode`\<=\other + \catcode`\>=\other + \catcode`\+=\other + \catcode`\{=\other + \catcode`\}=\other + \catcode`\@=\other + \catcode`\^^M=\other + \usembodybackslash} + +\def\macroargctxt{% + \catcode`\~=\other + \catcode`\^=\other + \catcode`\_=\other + \catcode`\|=\other + \catcode`\<=\other + \catcode`\>=\other + \catcode`\+=\other + \catcode`\@=\other + \catcode`\\=\other} + +% \mbodybackslash is the definition of \ in @macro bodies. +% It maps \foo\ => \csname macarg.foo\endcsname => #N +% where N is the macro parameter number. +% We define \csname macarg.\endcsname to be \realbackslash, so +% \\ in macro replacement text gets you a backslash. + +{\catcode`@=0 @catcode`@\=@active + @gdef@usembodybackslash{@let\=@mbodybackslash} + @gdef@mbodybackslash#1\{@csname macarg.#1@endcsname} +} +\expandafter\def\csname macarg.\endcsname{\realbackslash} + +\def\macro{\recursivefalse\parsearg\macroxxx} +\def\rmacro{\recursivetrue\parsearg\macroxxx} + +\def\macroxxx#1{% + \getargs{#1}% now \macname is the macname and \argl the arglist + \ifx\argl\empty % no arguments + \paramno=0% + \else + \expandafter\parsemargdef \argl;% + \fi + \if1\csname ismacro.\the\macname\endcsname + \message{Warning: redefining \the\macname}% + \else + \expandafter\ifx\csname \the\macname\endcsname \relax + \else \errmessage{Macro name \the\macname\space already defined}\fi + \global\cslet{macsave.\the\macname}{\the\macname}% + \global\expandafter\let\csname ismacro.\the\macname\endcsname=1% + % Add the macroname to \macrolist + \toks0 = \expandafter{\macrolist\do}% + \xdef\macrolist{\the\toks0 + \expandafter\noexpand\csname\the\macname\endcsname}% + \fi + \begingroup \macrobodyctxt + \ifrecursive \expandafter\parsermacbody + \else \expandafter\parsemacbody + \fi} + +\def\unmacro{\parsearg\dounmacro} +\def\dounmacro#1{% + \if1\csname ismacro.#1\endcsname + \global\cslet{#1}{macsave.#1}% + \global\expandafter\let \csname ismacro.#1\endcsname=0% + % Remove the macro name from \macrolist: + \begingroup + \expandafter\let\csname#1\endcsname \relax + \let\do\unmacrodo + \xdef\macrolist{\macrolist}% + \endgroup + \else + \errmessage{Macro #1 not defined}% + \fi +} + +% Called by \do from \dounmacro on each macro. The idea is to omit any +% macro definitions that have been changed to \relax. +% +\def\unmacrodo#1{% + \ifx#1\relax + % remove this + \else + \noexpand\do \noexpand #1% + \fi +} + +% This makes use of the obscure feature that if the last token of a +% is #, then the preceding argument is delimited by +% an opening brace, and that opening brace is not consumed. +\def\getargs#1{\getargsxxx#1{}} +\def\getargsxxx#1#{\getmacname #1 \relax\getmacargs} +\def\getmacname #1 #2\relax{\macname={#1}} +\def\getmacargs#1{\def\argl{#1}} + +% Parse the optional {params} list. Set up \paramno and \paramlist +% so \defmacro knows what to do. Define \macarg.blah for each blah +% in the params list, to be ##N where N is the position in that list. +% That gets used by \mbodybackslash (above). + +% We need to get `macro parameter char #' into several definitions. +% The technique used is stolen from LaTeX: let \hash be something +% unexpandable, insert that wherever you need a #, and then redefine +% it to # just before using the token list produced. +% +% The same technique is used to protect \eatspaces till just before +% the macro is used. + +\def\parsemargdef#1;{\paramno=0\def\paramlist{}% + \let\hash\relax\let\xeatspaces\relax\parsemargdefxxx#1,;,} +\def\parsemargdefxxx#1,{% + \if#1;\let\next=\relax + \else \let\next=\parsemargdefxxx + \advance\paramno by 1% + \expandafter\edef\csname macarg.\eatspaces{#1}\endcsname + {\xeatspaces{\hash\the\paramno}}% + \edef\paramlist{\paramlist\hash\the\paramno,}% + \fi\next} + +% These two commands read recursive and nonrecursive macro bodies. +% (They're different since rec and nonrec macros end differently.) + +\long\def\parsemacbody#1@end macro% +{\xdef\temp{\eatcr{#1}}\endgroup\defmacro}% +\long\def\parsermacbody#1@end rmacro% +{\xdef\temp{\eatcr{#1}}\endgroup\defmacro}% + +% This defines the macro itself. There are six cases: recursive and +% nonrecursive macros of zero, one, and many arguments. +% Much magic with \expandafter here. +% \xdef is used so that macro definitions will survive the file +% they're defined in; @include reads the file inside a group. +\def\defmacro{% + \let\hash=##% convert placeholders to macro parameter chars + \ifrecursive + \ifcase\paramno + % 0 + \expandafter\xdef\csname\the\macname\endcsname{% + \noexpand\scanmacro{\temp}}% + \or % 1 + \expandafter\xdef\csname\the\macname\endcsname{% + \bgroup\noexpand\macroargctxt + \noexpand\braceorline + \expandafter\noexpand\csname\the\macname xxx\endcsname}% + \expandafter\xdef\csname\the\macname xxx\endcsname##1{% + \egroup\noexpand\scanmacro{\temp}}% + \else % many + \expandafter\xdef\csname\the\macname\endcsname{% + \bgroup\noexpand\macroargctxt + \noexpand\csname\the\macname xx\endcsname}% + \expandafter\xdef\csname\the\macname xx\endcsname##1{% + \expandafter\noexpand\csname\the\macname xxx\endcsname ##1,}% + \expandafter\expandafter + \expandafter\xdef + \expandafter\expandafter + \csname\the\macname xxx\endcsname + \paramlist{\egroup\noexpand\scanmacro{\temp}}% + \fi + \else + \ifcase\paramno + % 0 + \expandafter\xdef\csname\the\macname\endcsname{% + \noexpand\norecurse{\the\macname}% + \noexpand\scanmacro{\temp}\egroup}% + \or % 1 + \expandafter\xdef\csname\the\macname\endcsname{% + \bgroup\noexpand\macroargctxt + \noexpand\braceorline + \expandafter\noexpand\csname\the\macname xxx\endcsname}% + \expandafter\xdef\csname\the\macname xxx\endcsname##1{% + \egroup + \noexpand\norecurse{\the\macname}% + \noexpand\scanmacro{\temp}\egroup}% + \else % many + \expandafter\xdef\csname\the\macname\endcsname{% + \bgroup\noexpand\macroargctxt + \expandafter\noexpand\csname\the\macname xx\endcsname}% + \expandafter\xdef\csname\the\macname xx\endcsname##1{% + \expandafter\noexpand\csname\the\macname xxx\endcsname ##1,}% + \expandafter\expandafter + \expandafter\xdef + \expandafter\expandafter + \csname\the\macname xxx\endcsname + \paramlist{% + \egroup + \noexpand\norecurse{\the\macname}% + \noexpand\scanmacro{\temp}\egroup}% + \fi + \fi} + +\def\norecurse#1{\bgroup\cslet{#1}{macsave.#1}} + +% \braceorline decides whether the next nonwhitespace character is a +% {. If so it reads up to the closing }, if not, it reads the whole +% line. Whatever was read is then fed to the next control sequence +% as an argument (by \parsebrace or \parsearg) +\def\braceorline#1{\let\next=#1\futurelet\nchar\braceorlinexxx} +\def\braceorlinexxx{% + \ifx\nchar\bgroup\else + \expandafter\parsearg + \fi \next} + +% We mant to disable all macros during \shipout so that they are not +% expanded by \write. +\def\turnoffmacros{\begingroup \def\do##1{\let\noexpand##1=\relax}% + \edef\next{\macrolist}\expandafter\endgroup\next} + + +% @alias. +% We need some trickery to remove the optional spaces around the equal +% sign. Just make them active and then expand them all to nothing. +\def\alias{\begingroup\obeyspaces\parsearg\aliasxxx} +\def\aliasxxx #1{\aliasyyy#1\relax} +\def\aliasyyy #1=#2\relax{\ignoreactivespaces +\edef\next{\global\let\expandafter\noexpand\csname#1\endcsname=% + \expandafter\noexpand\csname#2\endcsname}% +\expandafter\endgroup\next} + + +\message{cross references,} + +\newwrite\auxfile + +\newif\ifhavexrefs % True if xref values are known. +\newif\ifwarnedxrefs % True if we warned once that they aren't known. + +% @inforef is relatively simple. +\def\inforef #1{\inforefzzz #1,,,,**} +\def\inforefzzz #1,#2,#3,#4**{\putwordSee{} \putwordInfo{} \putwordfile{} \file{\ignorespaces #3{}}, + node \samp{\ignorespaces#1{}}} + +% @node's only job in TeX is to define \lastnode, which is used in +% cross-references. +\def\node{\ENVcheck\parsearg\nodezzz} +\def\nodezzz#1{\nodexxx #1,\finishnodeparse} +\def\nodexxx#1,#2\finishnodeparse{\gdef\lastnode{#1}} +\let\nwnode=\node +\let\lastnode=\empty + +% Write a cross-reference definition for the current node. #1 is the +% type (Ynumbered, Yappendix, Ynothing). +% +\def\donoderef#1{% + \ifx\lastnode\empty\else + \expandafter\expandafter\expandafter\setref{\lastnode}{#1}% + \global\let\lastnode=\empty + \fi +} + +% @anchor{NAME} -- define xref target at arbitrary point. +% +\newcount\savesfregister +% +\gdef\savesf{\relax \ifhmode \savesfregister=\spacefactor \fi} +\gdef\restoresf{\relax \ifhmode \spacefactor=\savesfregister \fi} +\gdef\anchor#1{\savesf \setref{#1}{Ynothing}\restoresf \ignorespaces} + +% \setref{NAME}{SNT} defines a cross-reference point NAME (a node or an +% anchor), namely NAME-title (the corresponding @chapter/etc. name), +% NAME-pg (the page number), and NAME-snt (section number and type). +% Called from \foonoderef. +% +% We have to set dummies so commands such as @code in a section title +% aren't expanded. It would be nicer not to expand the titles in the +% first place, but that is hard to do. +% +% Likewise, use \turnoffactive so that punctuation chars such as underscore +% and backslash work in node names. +% +\def\setref#1#2{{% + \atdummies + \pdfmkdest{#1}% + % + \iflinks + \turnoffactive + \dosetq{#1-title}{Ytitle}% + \dosetq{#1-pg}{Ypagenumber}% + \dosetq{#1-snt}{#2}% + \fi +}} + +% @xref, @pxref, and @ref generate cross-references. For \xrefX, #1 is +% the node name, #2 the name of the Info cross-reference, #3 the printed +% node name, #4 the name of the Info file, #5 the name of the printed +% manual. All but the node name can be omitted. +% +\def\pxref#1{\putwordsee{} \xrefX[#1,,,,,,,]} +\def\xref#1{\putwordSee{} \xrefX[#1,,,,,,,]} +\def\ref#1{\xrefX[#1,,,,,,,]} +\def\xrefX[#1,#2,#3,#4,#5,#6]{\begingroup + \unsepspaces + \def\printedmanual{\ignorespaces #5}% + \def\printednodename{\ignorespaces #3}% + \setbox1=\hbox{\printedmanual}% + \setbox0=\hbox{\printednodename}% + \ifdim \wd0 = 0pt + % No printed node name was explicitly given. + \expandafter\ifx\csname SETxref-automatic-section-title\endcsname\relax + % Use the node name inside the square brackets. + \def\printednodename{\ignorespaces #1}% + \else + % Use the actual chapter/section title appear inside + % the square brackets. Use the real section title if we have it. + \ifdim \wd1 > 0pt + % It is in another manual, so we don't have it. + \def\printednodename{\ignorespaces #1}% + \else + \ifhavexrefs + % We know the real title if we have the xref values. + \def\printednodename{\refx{#1-title}{}}% + \else + % Otherwise just copy the Info node name. + \def\printednodename{\ignorespaces #1}% + \fi% + \fi + \fi + \fi + % + % If we use \unhbox0 and \unhbox1 to print the node names, TeX does not + % insert empty discretionaries after hyphens, which means that it will + % not find a line break at a hyphen in a node names. Since some manuals + % are best written with fairly long node names, containing hyphens, this + % is a loss. Therefore, we give the text of the node name again, so it + % is as if TeX is seeing it for the first time. + \ifpdf + \leavevmode + \getfilename{#4}% + {\turnoffactive \otherbackslash + \ifnum\filenamelength>0 + \startlink attr{/Border [0 0 0]}% + goto file{\the\filename.pdf} name{#1}% + \else + \startlink attr{/Border [0 0 0]}% + goto name{\pdfmkpgn{#1}}% + \fi + }% + \linkcolor + \fi + % + \ifdim \wd1 > 0pt + \putwordsection{} ``\printednodename'' \putwordin{} \cite{\printedmanual}% + \else + % _ (for example) has to be the character _ for the purposes of the + % control sequence corresponding to the node, but it has to expand + % into the usual \leavevmode...\vrule stuff for purposes of + % printing. So we \turnoffactive for the \refx-snt, back on for the + % printing, back off for the \refx-pg. + {\turnoffactive \otherbackslash + % Only output a following space if the -snt ref is nonempty; for + % @unnumbered and @anchor, it won't be. + \setbox2 = \hbox{\ignorespaces \refx{#1-snt}{}}% + \ifdim \wd2 > 0pt \refx{#1-snt}\space\fi + }% + % output the `[mynode]' via a macro. + \xrefprintnodename\printednodename + % + % But we always want a comma and a space: + ,\space + % + % output the `page 3'. + \turnoffactive \otherbackslash \putwordpage\tie\refx{#1-pg}{}% + \fi + \endlink +\endgroup} + +% This macro is called from \xrefX for the `[nodename]' part of xref +% output. It's a separate macro only so it can be changed more easily, +% since not square brackets don't work in some documents. Particularly +% one that Bob is working on :). +% +\def\xrefprintnodename#1{[#1]} + +% \dosetq is called from \setref to do the actual \write (\iflinks). +% +\def\dosetq#1#2{% + \edef\next{\write\auxfile{\internalsetq{#1}{#2}}}% + \next +} + +% \internalsetq{foo}{page} expands into +% CHARACTERS @xrdef{foo}{...expansion of \page...} +\def\internalsetq#1#2{@xrdef{#1}{\csname #2\endcsname}} + +% Things to be expanded by \internalsetq. +% +\def\Ypagenumber{\noexpand\folio} +\def\Ytitle{\thissection} +\def\Ynothing{} +\def\Yomitfromtoc{} +\def\Ynumbered{% + \ifnum\secno=0 + \putwordChapter@tie \the\chapno + \else \ifnum\subsecno=0 + \putwordSection@tie \the\chapno.\the\secno + \else \ifnum\subsubsecno=0 + \putwordSection@tie \the\chapno.\the\secno.\the\subsecno + \else + \putwordSection@tie \the\chapno.\the\secno.\the\subsecno.\the\subsubsecno + \fi\fi\fi +} +\def\Yappendix{% + \ifnum\secno=0 + \putwordAppendix@tie @char\the\appendixno{}% + \else \ifnum\subsecno=0 + \putwordSection@tie @char\the\appendixno.\the\secno + \else \ifnum\subsubsecno=0 + \putwordSection@tie @char\the\appendixno.\the\secno.\the\subsecno + \else + \putwordSection@tie + @char\the\appendixno.\the\secno.\the\subsecno.\the\subsubsecno + \fi\fi\fi +} + +% Use TeX 3.0's \inputlineno to get the line number, for better error +% messages, but if we're using an old version of TeX, don't do anything. +% +\ifx\inputlineno\thisisundefined + \let\linenumber = \empty % Pre-3.0. +\else + \def\linenumber{\the\inputlineno:\space} +\fi + +% Define \refx{NAME}{SUFFIX} to reference a cross-reference string named NAME. +% If its value is nonempty, SUFFIX is output afterward. +% +\def\refx#1#2{% + {% + \indexnofonts + \otherbackslash + \expandafter\global\expandafter\let\expandafter\thisrefX + \csname X#1\endcsname + }% + \ifx\thisrefX\relax + % If not defined, say something at least. + \angleleft un\-de\-fined\angleright + \iflinks + \ifhavexrefs + \message{\linenumber Undefined cross reference `#1'.}% + \else + \ifwarnedxrefs\else + \global\warnedxrefstrue + \message{Cross reference values unknown; you must run TeX again.}% + \fi + \fi + \fi + \else + % It's defined, so just use it. + \thisrefX + \fi + #2% Output the suffix in any case. +} + +% This is the macro invoked by entries in the aux file. +% +\def\xrdef#1{\expandafter\gdef\csname X#1\endcsname} + +% Read the last existing aux file, if any. No error if none exists. +\def\readauxfile{\begingroup + \catcode`\^^@=\other + \catcode`\^^A=\other + \catcode`\^^B=\other + \catcode`\^^C=\other + \catcode`\^^D=\other + \catcode`\^^E=\other + \catcode`\^^F=\other + \catcode`\^^G=\other + \catcode`\^^H=\other + \catcode`\^^K=\other + \catcode`\^^L=\other + \catcode`\^^N=\other + \catcode`\^^P=\other + \catcode`\^^Q=\other + \catcode`\^^R=\other + \catcode`\^^S=\other + \catcode`\^^T=\other + \catcode`\^^U=\other + \catcode`\^^V=\other + \catcode`\^^W=\other + \catcode`\^^X=\other + \catcode`\^^Z=\other + \catcode`\^^[=\other + \catcode`\^^\=\other + \catcode`\^^]=\other + \catcode`\^^^=\other + \catcode`\^^_=\other + % It was suggested to set the catcode of ^ to 7, which would allow ^^e4 etc. + % in xref tags, i.e., node names. But since ^^e4 notation isn't + % supported in the main text, it doesn't seem desirable. Furthermore, + % that is not enough: for node names that actually contain a ^ + % character, we would end up writing a line like this: 'xrdef {'hat + % b-title}{'hat b} and \xrdef does a \csname...\endcsname on the first + % argument, and \hat is not an expandable control sequence. It could + % all be worked out, but why? Either we support ^^ or we don't. + % + % The other change necessary for this was to define \auxhat: + % \def\auxhat{\def^{'hat }}% extra space so ok if followed by letter + % and then to call \auxhat in \setq. + % + \catcode`\^=\other + % + % Special characters. Should be turned off anyway, but... + \catcode`\~=\other + \catcode`\[=\other + \catcode`\]=\other + \catcode`\"=\other + \catcode`\_=\other + \catcode`\|=\other + \catcode`\<=\other + \catcode`\>=\other + \catcode`\$=\other + \catcode`\#=\other + \catcode`\&=\other + \catcode`\%=\other + \catcode`+=\other % avoid \+ for paranoia even though we've turned it off + % + % Make the characters 128-255 be printing characters + {% + \count 1=128 + \def\loop{% + \catcode\count 1=\other + \advance\count 1 by 1 + \ifnum \count 1<256 \loop \fi + }% + }% + % + % Turn off \ as an escape so we do not lose on + % entries which were dumped with control sequences in their names. + % For example, @xrdef{$\leq $-fun}{page ...} made by @defun ^^ + % Reference to such entries still does not work the way one would wish, + % but at least they do not bomb out when the aux file is read in. + \catcode`\\=\other + % + % @ is our escape character in .aux files. + \catcode`\{=1 + \catcode`\}=2 + \catcode`\@=0 + % + \openin 1 \jobname.aux + \ifeof 1 \else + \closein 1 + \input \jobname.aux + \global\havexrefstrue + \fi + % Open the new aux file. TeX will close it automatically at exit. + \openout\auxfile=\jobname.aux +\endgroup} + + +% Footnotes. + +\newcount \footnoteno + +% The trailing space in the following definition for supereject is +% vital for proper filling; pages come out unaligned when you do a +% pagealignmacro call if that space before the closing brace is +% removed. (Generally, numeric constants should always be followed by a +% space to prevent strange expansion errors.) +\def\supereject{\par\penalty -20000\footnoteno =0 } + +% @footnotestyle is meaningful for info output only. +\let\footnotestyle=\comment + +\let\ptexfootnote=\footnote + +{\catcode `\@=11 +% +% Auto-number footnotes. Otherwise like plain. +\gdef\footnote{% + \let\indent=\ptexindent + \let\noindent=\ptexnoindent + \global\advance\footnoteno by \@ne + \edef\thisfootno{$^{\the\footnoteno}$}% + % + % In case the footnote comes at the end of a sentence, preserve the + % extra spacing after we do the footnote number. + \let\@sf\empty + \ifhmode\edef\@sf{\spacefactor\the\spacefactor}\ptexslash\fi + % + % Remove inadvertent blank space before typesetting the footnote number. + \unskip + \thisfootno\@sf + \dofootnote +}% + +% Don't bother with the trickery in plain.tex to not require the +% footnote text as a parameter. Our footnotes don't need to be so general. +% +% Oh yes, they do; otherwise, @ifset and anything else that uses +% \parseargline fail inside footnotes because the tokens are fixed when +% the footnote is read. --karl, 16nov96. +% +% The start of the footnote looks usually like this: +\gdef\startfootins{\insert\footins\bgroup} +% +% ... but this macro is redefined inside @multitable. +% +\gdef\dofootnote{% + \startfootins + % We want to typeset this text as a normal paragraph, even if the + % footnote reference occurs in (for example) a display environment. + % So reset some parameters. + \hsize=\pagewidth + \interlinepenalty\interfootnotelinepenalty + \splittopskip\ht\strutbox % top baseline for broken footnotes + \splitmaxdepth\dp\strutbox + \floatingpenalty\@MM + \leftskip\z@skip + \rightskip\z@skip + \spaceskip\z@skip + \xspaceskip\z@skip + \parindent\defaultparindent + % + \smallfonts \rm + % + % Because we use hanging indentation in footnotes, a @noindent appears + % to exdent this text, so make it be a no-op. makeinfo does not use + % hanging indentation so @noindent can still be needed within footnote + % text after an @example or the like (not that this is good style). + \let\noindent = \relax + % + % Hang the footnote text off the number. Use \everypar in case the + % footnote extends for more than one paragraph. + \everypar = {\hang}% + \textindent{\thisfootno}% + % + % Don't crash into the line above the footnote text. Since this + % expands into a box, it must come within the paragraph, lest it + % provide a place where TeX can split the footnote. + \footstrut + \futurelet\next\fo@t +} +}%end \catcode `\@=11 + +% @| inserts a changebar to the left of the current line. It should +% surround any changed text. This approach does *not* work if the +% change spans more than two lines of output. To handle that, we would +% have adopt a much more difficult approach (putting marks into the main +% vertical list for the beginning and end of each change). +% +\def\|{% + % \vadjust can only be used in horizontal mode. + \leavevmode + % + % Append this vertical mode material after the current line in the output. + \vadjust{% + % We want to insert a rule with the height and depth of the current + % leading; that is exactly what \strutbox is supposed to record. + \vskip-\baselineskip + % + % \vadjust-items are inserted at the left edge of the type. So + % the \llap here moves out into the left-hand margin. + \llap{% + % + % For a thicker or thinner bar, change the `1pt'. + \vrule height\baselineskip width1pt + % + % This is the space between the bar and the text. + \hskip 12pt + }% + }% +} + +% For a final copy, take out the rectangles +% that mark overfull boxes (in case you have decided +% that the text looks ok even though it passes the margin). +% +\def\finalout{\overfullrule=0pt} + +% @image. We use the macros from epsf.tex to support this. +% If epsf.tex is not installed and @image is used, we complain. +% +% Check for and read epsf.tex up front. If we read it only at @image +% time, we might be inside a group, and then its definitions would get +% undone and the next image would fail. +\openin 1 = epsf.tex +\ifeof 1 \else + \closein 1 + % Do not bother showing banner with epsf.tex v2.7k (available in + % doc/epsf.tex and on ctan). + \def\epsfannounce{\toks0 = }% + \input epsf.tex +\fi +% +% We will only complain once about lack of epsf.tex. +\newif\ifwarnednoepsf +\newhelp\noepsfhelp{epsf.tex must be installed for images to + work. It is also included in the Texinfo distribution, or you can get + it from ftp://tug.org/tex/epsf.tex.} +% +\def\image#1{% + \ifx\epsfbox\undefined + \ifwarnednoepsf \else + \errhelp = \noepsfhelp + \errmessage{epsf.tex not found, images will be ignored}% + \global\warnednoepsftrue + \fi + \else + \imagexxx #1,,,,,\finish + \fi +} +% +% Arguments to @image: +% #1 is (mandatory) image filename; we tack on .eps extension. +% #2 is (optional) width, #3 is (optional) height. +% #4 is (ignored optional) html alt text. +% #5 is (ignored optional) extension. +% #6 is just the usual extra ignored arg for parsing this stuff. +\newif\ifimagevmode +\def\imagexxx#1,#2,#3,#4,#5,#6\finish{\begingroup + \catcode`\^^M = 5 % in case we're inside an example + \normalturnoffactive % allow _ et al. in names + % If the image is by itself, center it. + \ifvmode + \imagevmodetrue + \nobreak\bigskip + % Usually we'll have text after the image which will insert + % \parskip glue, so insert it here too to equalize the space + % above and below. + \nobreak\vskip\parskip + \nobreak + \line\bgroup\hss + \fi + % + % Output the image. + \ifpdf + \dopdfimage{#1}{#2}{#3}% + \else + % \epsfbox itself resets \epsf?size at each figure. + \setbox0 = \hbox{\ignorespaces #2}\ifdim\wd0 > 0pt \epsfxsize=#2\relax \fi + \setbox0 = \hbox{\ignorespaces #3}\ifdim\wd0 > 0pt \epsfysize=#3\relax \fi + \epsfbox{#1.eps}% + \fi + % + \ifimagevmode \hss \egroup \bigbreak \fi % space after the image +\endgroup} + + +\message{localization,} +% and i18n. + +% @documentlanguage is usually given very early, just after +% @setfilename. If done too late, it may not override everything +% properly. Single argument is the language abbreviation. +% It would be nice if we could set up a hyphenation file here. +% +\def\documentlanguage{\parsearg\dodocumentlanguage} +\def\dodocumentlanguage#1{% + \tex % read txi-??.tex file in plain TeX. + % Read the file if it exists. + \openin 1 txi-#1.tex + \ifeof1 + \errhelp = \nolanghelp + \errmessage{Cannot read language file txi-#1.tex}% + \let\temp = \relax + \else + \def\temp{\input txi-#1.tex }% + \fi + \temp + \endgroup +} +\newhelp\nolanghelp{The given language definition file cannot be found or +is empty. Maybe you need to install it? In the current directory +should work if nowhere else does.} + + +% @documentencoding should change something in TeX eventually, most +% likely, but for now just recognize it. +\let\documentencoding = \comment + + +% Page size parameters. +% +\newdimen\defaultparindent \defaultparindent = 15pt + +\chapheadingskip = 15pt plus 4pt minus 2pt +\secheadingskip = 12pt plus 3pt minus 2pt +\subsecheadingskip = 9pt plus 2pt minus 2pt + +% Prevent underfull vbox error messages. +\vbadness = 10000 + +% Don't be so finicky about underfull hboxes, either. +\hbadness = 2000 + +% Following George Bush, just get rid of widows and orphans. +\widowpenalty=10000 +\clubpenalty=10000 + +% Use TeX 3.0's \emergencystretch to help line breaking, but if we're +% using an old version of TeX, don't do anything. We want the amount of +% stretch added to depend on the line length, hence the dependence on +% \hsize. We call this whenever the paper size is set. +% +\def\setemergencystretch{% + \ifx\emergencystretch\thisisundefined + % Allow us to assign to \emergencystretch anyway. + \def\emergencystretch{\dimen0}% + \else + \emergencystretch = .15\hsize + \fi +} + +% Parameters in order: 1) textheight; 2) textwidth; 3) voffset; +% 4) hoffset; 5) binding offset; 6) topskip; 7) physical page height; 8) +% physical page width. +% +% We also call \setleading{\textleading}, so the caller should define +% \textleading. The caller should also set \parskip. +% +\def\internalpagesizes#1#2#3#4#5#6#7#8{% + \voffset = #3\relax + \topskip = #6\relax + \splittopskip = \topskip + % + \vsize = #1\relax + \advance\vsize by \topskip + \outervsize = \vsize + \advance\outervsize by 2\topandbottommargin + \pageheight = \vsize + % + \hsize = #2\relax + \outerhsize = \hsize + \advance\outerhsize by 0.5in + \pagewidth = \hsize + % + \normaloffset = #4\relax + \bindingoffset = #5\relax + % + \ifpdf + \pdfpageheight #7\relax + \pdfpagewidth #8\relax + \fi + % + \setleading{\textleading} + % + \parindent = \defaultparindent + \setemergencystretch +} + +% @letterpaper (the default). +\def\letterpaper{{\globaldefs = 1 + \parskip = 3pt plus 2pt minus 1pt + \textleading = 13.2pt + % + % If page is nothing but text, make it come out even. + \internalpagesizes{46\baselineskip}{6in}% + {\voffset}{.25in}% + {\bindingoffset}{36pt}% + {11in}{8.5in}% +}} + +% Use @smallbook to reset parameters for 7x9.5 (or so) format. +\def\smallbook{{\globaldefs = 1 + \parskip = 2pt plus 1pt + \textleading = 12pt + % + \internalpagesizes{7.5in}{5in}% + {\voffset}{.25in}% + {\bindingoffset}{16pt}% + {9.25in}{7in}% + % + \lispnarrowing = 0.3in + \tolerance = 700 + \hfuzz = 1pt + \contentsrightmargin = 0pt + \defbodyindent = .5cm +}} + +% Use @afourpaper to print on European A4 paper. +\def\afourpaper{{\globaldefs = 1 + \parskip = 3pt plus 2pt minus 1pt + \textleading = 13.2pt + % + % Double-side printing via postscript on Laserjet 4050 + % prints double-sided nicely when \bindingoffset=10mm and \hoffset=-6mm. + % To change the settings for a different printer or situation, adjust + % \normaloffset until the front-side and back-side texts align. Then + % do the same for \bindingoffset. You can set these for testing in + % your texinfo source file like this: + % @tex + % \global\normaloffset = -6mm + % \global\bindingoffset = 10mm + % @end tex + \internalpagesizes{51\baselineskip}{160mm} + {\voffset}{\hoffset}% + {\bindingoffset}{44pt}% + {297mm}{210mm}% + % + \tolerance = 700 + \hfuzz = 1pt + \contentsrightmargin = 0pt + \defbodyindent = 5mm +}} + +% Use @afivepaper to print on European A5 paper. +% From romildo@urano.iceb.ufop.br, 2 July 2000. +% He also recommends making @example and @lisp be small. +\def\afivepaper{{\globaldefs = 1 + \parskip = 2pt plus 1pt minus 0.1pt + \textleading = 12.5pt + % + \internalpagesizes{160mm}{120mm}% + {\voffset}{\hoffset}% + {\bindingoffset}{8pt}% + {210mm}{148mm}% + % + \lispnarrowing = 0.2in + \tolerance = 800 + \hfuzz = 1.2pt + \contentsrightmargin = 0pt + \defbodyindent = 2mm + \tableindent = 12mm +}} + +% A specific text layout, 24x15cm overall, intended for A4 paper. +\def\afourlatex{{\globaldefs = 1 + \afourpaper + \internalpagesizes{237mm}{150mm}% + {\voffset}{4.6mm}% + {\bindingoffset}{7mm}% + {297mm}{210mm}% + % + % Must explicitly reset to 0 because we call \afourpaper. + \globaldefs = 0 +}} + +% Use @afourwide to print on A4 paper in landscape format. +\def\afourwide{{\globaldefs = 1 + \afourpaper + \internalpagesizes{241mm}{165mm}% + {\voffset}{-2.95mm}% + {\bindingoffset}{7mm}% + {297mm}{210mm}% + \globaldefs = 0 +}} + +% @pagesizes TEXTHEIGHT[,TEXTWIDTH] +% Perhaps we should allow setting the margins, \topskip, \parskip, +% and/or leading, also. Or perhaps we should compute them somehow. +% +\def\pagesizes{\parsearg\pagesizesxxx} +\def\pagesizesxxx#1{\pagesizesyyy #1,,\finish} +\def\pagesizesyyy#1,#2,#3\finish{{% + \setbox0 = \hbox{\ignorespaces #2}\ifdim\wd0 > 0pt \hsize=#2\relax \fi + \globaldefs = 1 + % + \parskip = 3pt plus 2pt minus 1pt + \setleading{\textleading}% + % + \dimen0 = #1 + \advance\dimen0 by \voffset + % + \dimen2 = \hsize + \advance\dimen2 by \normaloffset + % + \internalpagesizes{#1}{\hsize}% + {\voffset}{\normaloffset}% + {\bindingoffset}{44pt}% + {\dimen0}{\dimen2}% +}} + +% Set default to letter. +% +\letterpaper + + +\message{and turning on texinfo input format.} + +% Define macros to output various characters with catcode for normal text. +\catcode`\"=\other +\catcode`\~=\other +\catcode`\^=\other +\catcode`\_=\other +\catcode`\|=\other +\catcode`\<=\other +\catcode`\>=\other +\catcode`\+=\other +\catcode`\$=\other +\def\normaldoublequote{"} +\def\normaltilde{~} +\def\normalcaret{^} +\def\normalunderscore{_} +\def\normalverticalbar{|} +\def\normalless{<} +\def\normalgreater{>} +\def\normalplus{+} +\def\normaldollar{$}%$ font-lock fix + +% This macro is used to make a character print one way in ttfont +% where it can probably just be output, and another way in other fonts, +% where something hairier probably needs to be done. +% +% #1 is what to print if we are indeed using \tt; #2 is what to print +% otherwise. Since all the Computer Modern typewriter fonts have zero +% interword stretch (and shrink), and it is reasonable to expect all +% typewriter fonts to have this, we can check that font parameter. +% +\def\ifusingtt#1#2{\ifdim \fontdimen3\font=0pt #1\else #2\fi} + +% Same as above, but check for italic font. Actually this also catches +% non-italic slanted fonts since it is impossible to distinguish them from +% italic fonts. But since this is only used by $ and it uses \sl anyway +% this is not a problem. +\def\ifusingit#1#2{\ifdim \fontdimen1\font>0pt #1\else #2\fi} + +% Turn off all special characters except @ +% (and those which the user can use as if they were ordinary). +% Most of these we simply print from the \tt font, but for some, we can +% use math or other variants that look better in normal text. + +\catcode`\"=\active +\def\activedoublequote{{\tt\char34}} +\let"=\activedoublequote +\catcode`\~=\active +\def~{{\tt\char126}} +\chardef\hat=`\^ +\catcode`\^=\active +\def^{{\tt \hat}} + +\catcode`\_=\active +\def_{\ifusingtt\normalunderscore\_} +% Subroutine for the previous macro. +\def\_{\leavevmode \kern.07em \vbox{\hrule width.3em height.1ex}\kern .07em } + +\catcode`\|=\active +\def|{{\tt\char124}} +\chardef \less=`\< +\catcode`\<=\active +\def<{{\tt \less}} +\chardef \gtr=`\> +\catcode`\>=\active +\def>{{\tt \gtr}} +\catcode`\+=\active +\def+{{\tt \char 43}} +\catcode`\$=\active +\def${\ifusingit{{\sl\$}}\normaldollar}%$ font-lock fix + +% Set up an active definition for =, but don't enable it most of the time. +{\catcode`\==\active +\global\def={{\tt \char 61}}} + +\catcode`+=\active +\catcode`\_=\active + +% If a .fmt file is being used, characters that might appear in a file +% name cannot be active until we have parsed the command line. +% So turn them off again, and have \everyjob (or @setfilename) turn them on. +% \otherifyactive is called near the end of this file. +\def\otherifyactive{\catcode`+=\other \catcode`\_=\other} + +\catcode`\@=0 + +% \rawbackslashxx outputs one backslash character in current font, +% as in \char`\\. +\global\chardef\rawbackslashxx=`\\ + +% \rawbackslash defines an active \ to do \rawbackslashxx. +% \otherbackslash defines an active \ to be a literal `\' character with +% catcode other. +{\catcode`\\=\active + @gdef@rawbackslash{@let\=@rawbackslashxx} + @gdef@otherbackslash{@let\=@realbackslash} +} + +% \realbackslash is an actual character `\' with catcode other. +{\catcode`\\=\other @gdef@realbackslash{\}} + +% \normalbackslash outputs one backslash in fixed width font. +\def\normalbackslash{{\tt\rawbackslashxx}} + +\catcode`\\=\active + +% Used sometimes to turn off (effectively) the active characters +% even after parsing them. +@def@turnoffactive{% + @let"=@normaldoublequote + @let\=@realbackslash + @let~=@normaltilde + @let^=@normalcaret + @let_=@normalunderscore + @let|=@normalverticalbar + @let<=@normalless + @let>=@normalgreater + @let+=@normalplus + @let$=@normaldollar %$ font-lock fix +} + +% Same as @turnoffactive except outputs \ as {\tt\char`\\} instead of +% the literal character `\'. (Thus, \ is not expandable when this is in +% effect.) +% +@def@normalturnoffactive{@turnoffactive @let\=@normalbackslash} + +% Make _ and + \other characters, temporarily. +% This is canceled by @fixbackslash. +@otherifyactive + +% If a .fmt file is being used, we don't want the `\input texinfo' to show up. +% That is what \eatinput is for; after that, the `\' should revert to printing +% a backslash. +% +@gdef@eatinput input texinfo{@fixbackslash} +@global@let\ = @eatinput + +% On the other hand, perhaps the file did not have a `\input texinfo'. Then +% the first `\{ in the file would cause an error. This macro tries to fix +% that, assuming it is called before the first `\' could plausibly occur. +% Also back turn on active characters that might appear in the input +% file name, in case not using a pre-dumped format. +% +@gdef@fixbackslash{% + @ifx\@eatinput @let\ = @normalbackslash @fi + @catcode`+=@active + @catcode`@_=@active +} + +% Say @foo, not \foo, in error messages. +@escapechar = `@@ + +% These look ok in all fonts, so just make them not special. +@catcode`@& = @other +@catcode`@# = @other +@catcode`@% = @other + +@c Set initial fonts. +@textfonts +@rm + + +@c Local variables: +@c eval: (add-hook 'write-file-hooks 'time-stamp) +@c page-delimiter: "^\\\\message" +@c time-stamp-start: "def\\\\texinfoversion{" +@c time-stamp-format: "%:y-%02m-%02d.%02H" +@c time-stamp-end: "}" +@c End: diff --git a/inet_ntop.c b/inet_ntop.c new file mode 100644 index 0000000..1fe542d --- /dev/null +++ b/inet_ntop.c @@ -0,0 +1 @@ +#include "missing\inet_ntop.c" \ No newline at end of file diff --git a/install-sh b/install-sh new file mode 100755 index 0000000..6ce63b9 --- /dev/null +++ b/install-sh @@ -0,0 +1,294 @@ +#!/bin/sh +# +# install - install a program, script, or datafile +# +# This originates from X11R5 (mit/util/scripts/install.sh), which was +# later released in X11R6 (xc/config/util/install.sh) with the +# following copyright and license. +# +# Copyright (C) 1994 X Consortium +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to +# deal in the Software without restriction, including without limitation the +# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +# sell copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- +# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# Except as contained in this notice, the name of the X Consortium shall not +# be used in advertising or otherwise to promote the sale, use or other deal- +# ings in this Software without prior written authorization from the X Consor- +# tium. +# +# +# FSF changes to this file are in the public domain. +# +# Calling this script install-sh is preferred over install.sh, to prevent +# `make' implicit rules from creating a file called install from it +# when there is no Makefile. +# +# This script is compatible with the BSD install script, but was written +# from scratch. It can only install one file at a time, a restriction +# shared with many OS's install programs. + + +# set DOITPROG to echo to test this script + +# Don't use :- since 4.3BSD and earlier shells don't like it. +doit="${DOITPROG-}" + + +# put in absolute paths if you don't have them in your path; or use env. vars. + +mvprog="${MVPROG-mv}" +cpprog="${CPPROG-cp}" +chmodprog="${CHMODPROG-chmod}" +chownprog="${CHOWNPROG-chown}" +chgrpprog="${CHGRPPROG-chgrp}" +stripprog="${STRIPPROG-strip}" +rmprog="${RMPROG-rm}" +mkdirprog="${MKDIRPROG-mkdir}" + +transformbasename="" +transform_arg="" +instcmd="$mvprog" +chmodcmd="$chmodprog 0755" +chowncmd="" +chgrpcmd="" +stripcmd="" +rmcmd="$rmprog -f" +mvcmd="$mvprog" +src="" +dst="" +dir_arg="" + +while [ x"$1" != x ]; do + case $1 in + -c) instcmd=$cpprog + shift + continue;; + + -d) dir_arg=true + shift + continue;; + + -m) chmodcmd="$chmodprog $2" + shift + shift + continue;; + + -o) chowncmd="$chownprog $2" + shift + shift + continue;; + + -g) chgrpcmd="$chgrpprog $2" + shift + shift + continue;; + + -s) stripcmd=$stripprog + shift + continue;; + + -t=*) transformarg=`echo $1 | sed 's/-t=//'` + shift + continue;; + + -b=*) transformbasename=`echo $1 | sed 's/-b=//'` + shift + continue;; + + *) if [ x"$src" = x ] + then + src=$1 + else + # this colon is to work around a 386BSD /bin/sh bug + : + dst=$1 + fi + shift + continue;; + esac +done + +if [ x"$src" = x ] +then + echo "$0: no input file specified" >&2 + exit 1 +else + : +fi + +if [ x"$dir_arg" != x ]; then + dst=$src + src="" + + if [ -d "$dst" ]; then + instcmd=: + chmodcmd="" + else + instcmd=$mkdirprog + fi +else + +# Waiting for this to be detected by the "$instcmd $src $dsttmp" command +# might cause directories to be created, which would be especially bad +# if $src (and thus $dsttmp) contains '*'. + + if [ -f "$src" ] || [ -d "$src" ] + then + : + else + echo "$0: $src does not exist" >&2 + exit 1 + fi + + if [ x"$dst" = x ] + then + echo "$0: no destination specified" >&2 + exit 1 + else + : + fi + +# If destination is a directory, append the input filename; if your system +# does not like double slashes in filenames, you may need to add some logic + + if [ -d "$dst" ] + then + dst=$dst/`basename "$src"` + else + : + fi +fi + +## this sed command emulates the dirname command +dstdir=`echo "$dst" | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` + +# Make sure that the destination directory exists. +# this part is taken from Noah Friedman's mkinstalldirs script + +# Skip lots of stat calls in the usual case. +if [ ! -d "$dstdir" ]; then +defaultIFS=' + ' +IFS="${IFS-$defaultIFS}" + +oIFS=$IFS +# Some sh's can't handle IFS=/ for some reason. +IFS='%' +set - `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'` +IFS=$oIFS + +pathcomp='' + +while [ $# -ne 0 ] ; do + pathcomp=$pathcomp$1 + shift + + if [ ! -d "$pathcomp" ] ; + then + $mkdirprog "$pathcomp" + else + : + fi + + pathcomp=$pathcomp/ +done +fi + +if [ x"$dir_arg" != x ] +then + $doit $instcmd "$dst" && + + if [ x"$chowncmd" != x ]; then $doit $chowncmd "$dst"; else : ; fi && + if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "$dst"; else : ; fi && + if [ x"$stripcmd" != x ]; then $doit $stripcmd "$dst"; else : ; fi && + if [ x"$chmodcmd" != x ]; then $doit $chmodcmd "$dst"; else : ; fi +else + +# If we're going to rename the final executable, determine the name now. + + if [ x"$transformarg" = x ] + then + dstfile=`basename "$dst"` + else + dstfile=`basename "$dst" $transformbasename | + sed $transformarg`$transformbasename + fi + +# don't allow the sed command to completely eliminate the filename + + if [ x"$dstfile" = x ] + then + dstfile=`basename "$dst"` + else + : + fi + +# Make a couple of temp file names in the proper directory. + + dsttmp=$dstdir/_inst.$$_ + rmtmp=$dstdir/_rm.$$_ + +# Trap to clean up temp files at exit. + + trap 'status=$?; rm -f "$dsttmp" "$rmtmp" && exit $status' 0 + trap '(exit $?); exit' 1 2 13 15 + +# Move or copy the file name to the temp name + + $doit $instcmd "$src" "$dsttmp" && + +# and set any options; do chmod last to preserve setuid bits + +# If any of these fail, we abort the whole thing. If we want to +# ignore errors from any of these, just make sure not to ignore +# errors from the above "$doit $instcmd $src $dsttmp" command. + + if [ x"$chowncmd" != x ]; then $doit $chowncmd "$dsttmp"; else :;fi && + if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "$dsttmp"; else :;fi && + if [ x"$stripcmd" != x ]; then $doit $stripcmd "$dsttmp"; else :;fi && + if [ x"$chmodcmd" != x ]; then $doit $chmodcmd "$dsttmp"; else :;fi && + +# Now remove or move aside any old file at destination location. We try this +# two ways since rm can't unlink itself on some systems and the destination +# file might be busy for other reasons. In this case, the final cleanup +# might fail but the new file should still install successfully. + +{ + if [ -f "$dstdir/$dstfile" ] + then + $doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null || + $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null || + { + echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2 + (exit 1); exit + } + else + : + fi +} && + +# Now rename the file to the real destination. + + $doit $mvcmd "$dsttmp" "$dstdir/$dstfile" + +fi && + +# The final little trick to "correctly" pass the exit status to the exit trap. + +{ + (exit 0); exit +} diff --git a/m4/.svn/all-wcprops b/m4/.svn/all-wcprops new file mode 100644 index 0000000..f5f3a00 --- /dev/null +++ b/m4/.svn/all-wcprops @@ -0,0 +1,5 @@ +K 25 +svn:wc:ra_dav:version-url +V 35 +/svn/netperf2/!svn/ver/266/trunk/m4 +END diff --git a/m4/.svn/entries b/m4/.svn/entries new file mode 100644 index 0000000..f5edbfd --- /dev/null +++ b/m4/.svn/entries @@ -0,0 +1,31 @@ +8 + +dir +299 +http://www.netperf.org/svn/netperf2/trunk/m4 +http://www.netperf.org/svn/netperf2 + + + +2008-03-18T21:08:56.012824Z +266 +raj + + +svn:special svn:externals svn:needs-lock + + + + + + + + + + + +5bbd99f3-5903-0410-b283-f1d88047b228 + +m4 +dir + diff --git a/m4/.svn/format b/m4/.svn/format new file mode 100644 index 0000000..45a4fb7 --- /dev/null +++ b/m4/.svn/format @@ -0,0 +1 @@ +8 diff --git a/m4/m4/.svn/all-wcprops b/m4/m4/.svn/all-wcprops new file mode 100644 index 0000000..5d69b02 --- /dev/null +++ b/m4/m4/.svn/all-wcprops @@ -0,0 +1,23 @@ +K 25 +svn:wc:ra_dav:version-url +V 38 +/svn/netperf2/!svn/ver/266/trunk/m4/m4 +END +salen.m4 +K 25 +svn:wc:ra_dav:version-url +V 47 +/svn/netperf2/!svn/ver/266/trunk/m4/m4/salen.m4 +END +sockaddrin6.m4 +K 25 +svn:wc:ra_dav:version-url +V 52 +/svn/netperf2/!svn/ver/33/trunk/m4/m4/sockaddrin6.m4 +END +sockinttypes.m4 +K 25 +svn:wc:ra_dav:version-url +V 53 +/svn/netperf2/!svn/ver/33/trunk/m4/m4/sockinttypes.m4 +END diff --git a/m4/m4/.svn/entries b/m4/m4/.svn/entries new file mode 100644 index 0000000..e4f4884 --- /dev/null +++ b/m4/m4/.svn/entries @@ -0,0 +1,64 @@ +8 + +dir +299 +http://www.netperf.org/svn/netperf2/trunk/m4/m4 +http://www.netperf.org/svn/netperf2 + + + +2008-03-18T21:08:56.012824Z +266 +raj + + +svn:special svn:externals svn:needs-lock + + + + + + + + + + + +5bbd99f3-5903-0410-b283-f1d88047b228 + +salen.m4 +file + + + + +2008-03-18T18:36:22.000000Z +0a5ed6a330cac1af2398fb47a8b2e3f8 +2008-03-18T21:08:56.012824Z +266 +raj + +sockaddrin6.m4 +file + + + + +2007-06-01T22:05:59.000000Z +19d9c4f1138e5876254228d1b554c13d +2005-10-17T22:25:24.828295Z +33 +raj + +sockinttypes.m4 +file + + + + +2007-06-01T22:05:59.000000Z +d5b12afdcfa72f3b6846639f0f91dd5f +2005-10-17T22:25:24.828295Z +33 +raj + diff --git a/m4/m4/.svn/format b/m4/m4/.svn/format new file mode 100644 index 0000000..45a4fb7 --- /dev/null +++ b/m4/m4/.svn/format @@ -0,0 +1 @@ +8 diff --git a/m4/m4/.svn/text-base/salen.m4.svn-base b/m4/m4/.svn/text-base/salen.m4.svn-base new file mode 100644 index 0000000..6e858da --- /dev/null +++ b/m4/m4/.svn/text-base/salen.m4.svn-base @@ -0,0 +1,32 @@ +dnl Copyright (c) 1995, 1996, 1997, 1998 +dnl tising materials mentioning +dnl dnl features or use of this software display the following acknowledgement: +dnl dnl ``This product includes software developed by the University of California, +dnl dnl Lawrence Berkeley Laboratory and its contributors.'' Neither the name of +dnl dnl the University nor the names of its contributors may be used to endorse +dnl dnl or promote products derived from this software without specific prior +dnl dnl written permission. +dnl dnl THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED +dnl dnl WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF +dnl dnl MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +dnl dnl +dnl dnl LBL autoconf macros +dnl dnl +dnl +dnl +dnl Checks to see if the sockaddr struct has the 4.4 BSD sa_len member +dnl borrowed from LBL libpcap +AC_DEFUN(AC_CHECK_SA_LEN, [ + AC_MSG_CHECKING(if sockaddr struct has sa_len member) + AC_CACHE_VAL($1, + AC_TRY_COMPILE([ +# include +# include ], + [u_int i = sizeof(((struct sockaddr *)0)->sa_len)], + $1=yes, + $1=no)) + AC_MSG_RESULT($$1) + if test $$1 = yes ; then + AC_DEFINE([HAVE_SOCKADDR_SA_LEN],1,[Define if struct sockaddr has the sa_len member]) + fi +]) diff --git a/m4/m4/.svn/text-base/sockaddrin6.m4.svn-base b/m4/m4/.svn/text-base/sockaddrin6.m4.svn-base new file mode 100644 index 0000000..c4270f3 --- /dev/null +++ b/m4/m4/.svn/text-base/sockaddrin6.m4.svn-base @@ -0,0 +1,60 @@ +dnl * +dnl * Copyright (c) 2001 Motoyuki Kasahara +dnl * +dnl * Redistribution and use in source and binary forms, with or without +dnl * modification, are permitted provided that the following conditions +dnl * are met: +dnl * 1. Redistributions of source code must retain the above copyright +dnl * notice, this list of conditions and the following disclaimer. +dnl * 2. Redistributions in binary form must reproduce the above copyright +dnl * notice, this list of conditions and the following disclaimer in the +dnl * documentation and/or other materials provided with the distribution. +dnl * 3. Neither the name of the project nor the names of its contributors +dnl * may be used to endorse or promote products derived from this software +dnl * without specific prior written permission. +dnl * +dnl * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND +dnl * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +dnl * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +dnl * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORSBE +dnl * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +dnl * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +dnl * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +dnl * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +dnl * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +dnl * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +dnl * THE POSSIBILITY OF SUCH DAMAGE. +dnl * + +dnl * +dnl * Check for struct sockaddr_in6 +dnl * +AC_DEFUN([AC_STRUCT_SOCKADDR_IN6], +[AC_CACHE_CHECK(for struct sockaddr_in6, ac_cv_struct_sockaddr_in6, +[AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#include +#include +#include ]], [[ +struct sockaddr_in6 address; +]])],[ac_cv_struct_sockaddr_in6=yes],[ac_cv_struct_sockaddr_in6=no])]) +if test "$ac_cv_struct_sockaddr_in6" = yes; then + AC_DEFINE(HAVE_STRUCT_SOCKADDR_IN6, 1, +[Define to 1 if defines `struct sockaddr_in6']) +fi]) + +dnl * +dnl * Check for struct sockaddr_storage +dnl * +AC_DEFUN([AC_STRUCT_SOCKADDR_STORAGE], +[AC_CACHE_CHECK(for struct sockaddr_storage, ac_cv_struct_sockaddr_storage, +[AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#include +#include +#include ]], [[ +struct sockaddr_storage address; +]])],[ac_cv_struct_sockaddr_storage=yes],[ac_cv_struct_sockaddr_storage=no])]) +if test "$ac_cv_struct_sockaddr_storage" = yes; then + AC_DEFINE(HAVE_STRUCT_SOCKADDR_STORAGE, 1, +[Define to 1 if defines `struct sockaddr_storage']) +fi]) + diff --git a/m4/m4/.svn/text-base/sockinttypes.m4.svn-base b/m4/m4/.svn/text-base/sockinttypes.m4.svn-base new file mode 100644 index 0000000..6d94063 --- /dev/null +++ b/m4/m4/.svn/text-base/sockinttypes.m4.svn-base @@ -0,0 +1,154 @@ +dnl * +dnl * Copyright (c) 2001, 2003 Motoyuki Kasahara +dnl * +dnl * Redistribution and use in source and binary forms, with or without +dnl * modification, are permitted provided that the following conditions +dnl * are met: +dnl * 1. Redistributions of source code must retain the above copyright +dnl * notice, this list of conditions and the following disclaimer. +dnl * 2. Redistributions in binary form must reproduce the above copyright +dnl * notice, this list of conditions and the following disclaimer in the +dnl * documentation and/or other materials provided with the distribution. +dnl * 3. Neither the name of the project nor the names of its contributors +dnl * may be used to endorse or promote products derived from this software +dnl * without specific prior written permission. +dnl * +dnl * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND +dnl * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +dnl * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +dnl * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORSBE +dnl * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +dnl * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +dnl * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +dnl * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +dnl * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +dnl * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +dnl * THE POSSIBILITY OF SUCH DAMAGE. +dnl * + +dnl * +dnl * Check for socklen_t. +dnl * +AC_DEFUN([AC_TYPE_SOCKLEN_T], +[AC_CACHE_CHECK([for socklen_t], ac_cv_type_socklen_t, +[AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#include +#include ]], [[ +socklen_t socklen; +]])],[ac_cv_type_socklen_t=yes],[ac_cv_type_socklen_t=no])]) +if test "$ac_cv_type_socklen_t" != yes; then + AC_DEFINE(socklen_t, int, +[Define to `int' if or does not define.]) +fi]) + +dnl * +dnl * Check for in_port_t. +dnl * +AC_DEFUN([AC_TYPE_IN_PORT_T], +[AC_CACHE_CHECK([for in_port_t], ac_cv_type_in_port_t, +[AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#include +#include +#include ]], [[ +in_port_t in_port; +]])],[ac_cv_type_in_port_t=yes],[ac_cv_type_in_port_t=no])]) +if test "$ac_cv_type_in_port_t" != yes; then + ac_cv_sin_port_size=unknown + AC_RUN_IFELSE([AC_LANG_SOURCE([[ + #include + #include + #include + int main() { + struct sockaddr_in addr; + return (sizeof(addr.sin_port) == sizeof(long)) ? 0 : 1; + } + ]])],[ac_cv_sin_port_size=long],[],[]) + AC_RUN_IFELSE([AC_LANG_SOURCE([[ + #include + #include + #include + int main() { + struct sockaddr_in addr; + return (sizeof(addr.sin_port) == sizeof(int)) ? 0 : 1; + } + ]])],[ac_cv_sin_port_size=int],[],[]) + AC_RUN_IFELSE([AC_LANG_SOURCE([[ + #include + #include + #include + int main() { + struct sockaddr_in addr; + return (sizeof(addr.sin_port) == sizeof(short)) ? 0 : 1; + } + ]])],[ac_cv_sin_port_size=short],[],[]) + AC_RUN_IFELSE([AC_LANG_SOURCE([[ + #include + #include + #include + int main() { + struct sockaddr_in addr; + return (sizeof(addr.sin_port) == sizeof(char)) ? 0 : 1; + } + ]])],[ac_cv_sin_port_size=char],[],[]) + if test "$ac_cv_sin_port_size" = unknown; then + AC_MSG_ERROR([Failed to get size of sin_port in struct sockaddr_in.]) + fi + AC_DEFINE_UNQUOTED(in_port_t, unsigned $ac_cv_sin_port_size, +[Define to `unsigned char', `unsigned short', `unsigned int' or +`unsigned long' according with size of `sin_port' in `struct sockaddr_in', +if , or does not define +`in_port_t'.]) +fi]) + +dnl * +dnl * Check for sa_family_t. +dnl * +AC_DEFUN([AC_TYPE_SA_FAMILY_T], +[AC_CACHE_CHECK([for sa_family_t], ac_cv_type_sa_family_t, +[AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#include +#include ]], [[ +sa_family_t sa_family; +]])],[ac_cv_type_sa_family_t=yes],[ac_cv_type_sa_family_t=no])]) +if test "$ac_cv_type_sa_family_t" != yes; then + ac_cv_sa_family_size=unknown + AC_RUN_IFELSE([AC_LANG_SOURCE([[ + #include + #include + int main() { + struct sockaddr addr; + return (sizeof(addr.sa_family) == sizeof(long)) ? 0 : 1; + } + ]])],[ac_cv_sa_family_size=long],[],[]) + AC_RUN_IFELSE([AC_LANG_SOURCE([[ + #include + #include + int main() { + struct sockaddr addr; + return (sizeof(addr.sa_family) == sizeof(int)) ? 0 : 1; + } + ]])],[ac_cv_sa_family_size=int],[],[]) + AC_RUN_IFELSE([AC_LANG_SOURCE([[ + #include + #include + int main() { + struct sockaddr addr; + return (sizeof(addr.sa_family) == sizeof(short)) ? 0 : 1; + } + ]])],[ac_cv_sa_family_size=short],[],[]) + AC_RUN_IFELSE([AC_LANG_SOURCE([[ + #include + #include + int main() { + struct sockaddr addr; + return (sizeof(addr.sa_family) == sizeof(char)) ? 0 : 1; + } + ]])],[ac_cv_sa_family_size=char],[],[]) + if test "$ac_cv_sa_family_size" = unknown; then + AC_MSG_ERROR([Failed to get size of sa_family in struct sockaddr.]) + fi + AC_DEFINE_UNQUOTED(sa_family_t, unsigned $ac_cv_sa_family_size, +[Define to `unsigned char', `unsigned short', `unsigned int' or +`unsigned long' according with size of `sa_family' in `struct sockaddr', +if or does not define `sa_family_t'.]) +fi]) diff --git a/m4/m4/salen.m4 b/m4/m4/salen.m4 new file mode 100644 index 0000000..6e858da --- /dev/null +++ b/m4/m4/salen.m4 @@ -0,0 +1,32 @@ +dnl Copyright (c) 1995, 1996, 1997, 1998 +dnl tising materials mentioning +dnl dnl features or use of this software display the following acknowledgement: +dnl dnl ``This product includes software developed by the University of California, +dnl dnl Lawrence Berkeley Laboratory and its contributors.'' Neither the name of +dnl dnl the University nor the names of its contributors may be used to endorse +dnl dnl or promote products derived from this software without specific prior +dnl dnl written permission. +dnl dnl THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED +dnl dnl WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF +dnl dnl MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +dnl dnl +dnl dnl LBL autoconf macros +dnl dnl +dnl +dnl +dnl Checks to see if the sockaddr struct has the 4.4 BSD sa_len member +dnl borrowed from LBL libpcap +AC_DEFUN(AC_CHECK_SA_LEN, [ + AC_MSG_CHECKING(if sockaddr struct has sa_len member) + AC_CACHE_VAL($1, + AC_TRY_COMPILE([ +# include +# include ], + [u_int i = sizeof(((struct sockaddr *)0)->sa_len)], + $1=yes, + $1=no)) + AC_MSG_RESULT($$1) + if test $$1 = yes ; then + AC_DEFINE([HAVE_SOCKADDR_SA_LEN],1,[Define if struct sockaddr has the sa_len member]) + fi +]) diff --git a/m4/m4/sockaddrin6.m4 b/m4/m4/sockaddrin6.m4 new file mode 100644 index 0000000..c4270f3 --- /dev/null +++ b/m4/m4/sockaddrin6.m4 @@ -0,0 +1,60 @@ +dnl * +dnl * Copyright (c) 2001 Motoyuki Kasahara +dnl * +dnl * Redistribution and use in source and binary forms, with or without +dnl * modification, are permitted provided that the following conditions +dnl * are met: +dnl * 1. Redistributions of source code must retain the above copyright +dnl * notice, this list of conditions and the following disclaimer. +dnl * 2. Redistributions in binary form must reproduce the above copyright +dnl * notice, this list of conditions and the following disclaimer in the +dnl * documentation and/or other materials provided with the distribution. +dnl * 3. Neither the name of the project nor the names of its contributors +dnl * may be used to endorse or promote products derived from this software +dnl * without specific prior written permission. +dnl * +dnl * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND +dnl * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +dnl * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +dnl * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORSBE +dnl * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +dnl * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +dnl * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +dnl * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +dnl * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +dnl * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +dnl * THE POSSIBILITY OF SUCH DAMAGE. +dnl * + +dnl * +dnl * Check for struct sockaddr_in6 +dnl * +AC_DEFUN([AC_STRUCT_SOCKADDR_IN6], +[AC_CACHE_CHECK(for struct sockaddr_in6, ac_cv_struct_sockaddr_in6, +[AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#include +#include +#include ]], [[ +struct sockaddr_in6 address; +]])],[ac_cv_struct_sockaddr_in6=yes],[ac_cv_struct_sockaddr_in6=no])]) +if test "$ac_cv_struct_sockaddr_in6" = yes; then + AC_DEFINE(HAVE_STRUCT_SOCKADDR_IN6, 1, +[Define to 1 if defines `struct sockaddr_in6']) +fi]) + +dnl * +dnl * Check for struct sockaddr_storage +dnl * +AC_DEFUN([AC_STRUCT_SOCKADDR_STORAGE], +[AC_CACHE_CHECK(for struct sockaddr_storage, ac_cv_struct_sockaddr_storage, +[AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#include +#include +#include ]], [[ +struct sockaddr_storage address; +]])],[ac_cv_struct_sockaddr_storage=yes],[ac_cv_struct_sockaddr_storage=no])]) +if test "$ac_cv_struct_sockaddr_storage" = yes; then + AC_DEFINE(HAVE_STRUCT_SOCKADDR_STORAGE, 1, +[Define to 1 if defines `struct sockaddr_storage']) +fi]) + diff --git a/m4/m4/sockinttypes.m4 b/m4/m4/sockinttypes.m4 new file mode 100644 index 0000000..6d94063 --- /dev/null +++ b/m4/m4/sockinttypes.m4 @@ -0,0 +1,154 @@ +dnl * +dnl * Copyright (c) 2001, 2003 Motoyuki Kasahara +dnl * +dnl * Redistribution and use in source and binary forms, with or without +dnl * modification, are permitted provided that the following conditions +dnl * are met: +dnl * 1. Redistributions of source code must retain the above copyright +dnl * notice, this list of conditions and the following disclaimer. +dnl * 2. Redistributions in binary form must reproduce the above copyright +dnl * notice, this list of conditions and the following disclaimer in the +dnl * documentation and/or other materials provided with the distribution. +dnl * 3. Neither the name of the project nor the names of its contributors +dnl * may be used to endorse or promote products derived from this software +dnl * without specific prior written permission. +dnl * +dnl * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND +dnl * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +dnl * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +dnl * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORSBE +dnl * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +dnl * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +dnl * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +dnl * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +dnl * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +dnl * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +dnl * THE POSSIBILITY OF SUCH DAMAGE. +dnl * + +dnl * +dnl * Check for socklen_t. +dnl * +AC_DEFUN([AC_TYPE_SOCKLEN_T], +[AC_CACHE_CHECK([for socklen_t], ac_cv_type_socklen_t, +[AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#include +#include ]], [[ +socklen_t socklen; +]])],[ac_cv_type_socklen_t=yes],[ac_cv_type_socklen_t=no])]) +if test "$ac_cv_type_socklen_t" != yes; then + AC_DEFINE(socklen_t, int, +[Define to `int' if or does not define.]) +fi]) + +dnl * +dnl * Check for in_port_t. +dnl * +AC_DEFUN([AC_TYPE_IN_PORT_T], +[AC_CACHE_CHECK([for in_port_t], ac_cv_type_in_port_t, +[AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#include +#include +#include ]], [[ +in_port_t in_port; +]])],[ac_cv_type_in_port_t=yes],[ac_cv_type_in_port_t=no])]) +if test "$ac_cv_type_in_port_t" != yes; then + ac_cv_sin_port_size=unknown + AC_RUN_IFELSE([AC_LANG_SOURCE([[ + #include + #include + #include + int main() { + struct sockaddr_in addr; + return (sizeof(addr.sin_port) == sizeof(long)) ? 0 : 1; + } + ]])],[ac_cv_sin_port_size=long],[],[]) + AC_RUN_IFELSE([AC_LANG_SOURCE([[ + #include + #include + #include + int main() { + struct sockaddr_in addr; + return (sizeof(addr.sin_port) == sizeof(int)) ? 0 : 1; + } + ]])],[ac_cv_sin_port_size=int],[],[]) + AC_RUN_IFELSE([AC_LANG_SOURCE([[ + #include + #include + #include + int main() { + struct sockaddr_in addr; + return (sizeof(addr.sin_port) == sizeof(short)) ? 0 : 1; + } + ]])],[ac_cv_sin_port_size=short],[],[]) + AC_RUN_IFELSE([AC_LANG_SOURCE([[ + #include + #include + #include + int main() { + struct sockaddr_in addr; + return (sizeof(addr.sin_port) == sizeof(char)) ? 0 : 1; + } + ]])],[ac_cv_sin_port_size=char],[],[]) + if test "$ac_cv_sin_port_size" = unknown; then + AC_MSG_ERROR([Failed to get size of sin_port in struct sockaddr_in.]) + fi + AC_DEFINE_UNQUOTED(in_port_t, unsigned $ac_cv_sin_port_size, +[Define to `unsigned char', `unsigned short', `unsigned int' or +`unsigned long' according with size of `sin_port' in `struct sockaddr_in', +if , or does not define +`in_port_t'.]) +fi]) + +dnl * +dnl * Check for sa_family_t. +dnl * +AC_DEFUN([AC_TYPE_SA_FAMILY_T], +[AC_CACHE_CHECK([for sa_family_t], ac_cv_type_sa_family_t, +[AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#include +#include ]], [[ +sa_family_t sa_family; +]])],[ac_cv_type_sa_family_t=yes],[ac_cv_type_sa_family_t=no])]) +if test "$ac_cv_type_sa_family_t" != yes; then + ac_cv_sa_family_size=unknown + AC_RUN_IFELSE([AC_LANG_SOURCE([[ + #include + #include + int main() { + struct sockaddr addr; + return (sizeof(addr.sa_family) == sizeof(long)) ? 0 : 1; + } + ]])],[ac_cv_sa_family_size=long],[],[]) + AC_RUN_IFELSE([AC_LANG_SOURCE([[ + #include + #include + int main() { + struct sockaddr addr; + return (sizeof(addr.sa_family) == sizeof(int)) ? 0 : 1; + } + ]])],[ac_cv_sa_family_size=int],[],[]) + AC_RUN_IFELSE([AC_LANG_SOURCE([[ + #include + #include + int main() { + struct sockaddr addr; + return (sizeof(addr.sa_family) == sizeof(short)) ? 0 : 1; + } + ]])],[ac_cv_sa_family_size=short],[],[]) + AC_RUN_IFELSE([AC_LANG_SOURCE([[ + #include + #include + int main() { + struct sockaddr addr; + return (sizeof(addr.sa_family) == sizeof(char)) ? 0 : 1; + } + ]])],[ac_cv_sa_family_size=char],[],[]) + if test "$ac_cv_sa_family_size" = unknown; then + AC_MSG_ERROR([Failed to get size of sa_family in struct sockaddr.]) + fi + AC_DEFINE_UNQUOTED(sa_family_t, unsigned $ac_cv_sa_family_size, +[Define to `unsigned char', `unsigned short', `unsigned int' or +`unsigned long' according with size of `sa_family' in `struct sockaddr', +if or does not define `sa_family_t'.]) +fi]) diff --git a/missing b/missing new file mode 100755 index 0000000..fc54c64 --- /dev/null +++ b/missing @@ -0,0 +1,336 @@ +#! /bin/sh +# Common stub for a few missing GNU programs while installing. +# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003 Free Software Foundation, Inc. +# Originally by Fran,cois Pinard , 1996. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +if test $# -eq 0; then + echo 1>&2 "Try \`$0 --help' for more information" + exit 1 +fi + +run=: + +# In the cases where this matters, `missing' is being run in the +# srcdir already. +if test -f configure.ac; then + configure_ac=configure.ac +else + configure_ac=configure.in +fi + +case "$1" in +--run) + # Try to run requested program, and just exit if it succeeds. + run= + shift + "$@" && exit 0 + ;; +esac + +# If it does not exist, or fails to run (possibly an outdated version), +# try to emulate it. +case "$1" in + + -h|--h|--he|--hel|--help) + echo "\ +$0 [OPTION]... PROGRAM [ARGUMENT]... + +Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an +error status if there is no known handling for PROGRAM. + +Options: + -h, --help display this help and exit + -v, --version output version information and exit + --run try to run the given command, and emulate it if it fails + +Supported PROGRAM values: + aclocal touch file \`aclocal.m4' + autoconf touch file \`configure' + autoheader touch file \`config.h.in' + automake touch all \`Makefile.in' files + bison create \`y.tab.[ch]', if possible, from existing .[ch] + flex create \`lex.yy.c', if possible, from existing .c + help2man touch the output file + lex create \`lex.yy.c', if possible, from existing .c + makeinfo touch the output file + tar try tar, gnutar, gtar, then tar without non-portable flags + yacc create \`y.tab.[ch]', if possible, from existing .[ch]" + ;; + + -v|--v|--ve|--ver|--vers|--versi|--versio|--version) + echo "missing 0.4 - GNU automake" + ;; + + -*) + echo 1>&2 "$0: Unknown \`$1' option" + echo 1>&2 "Try \`$0 --help' for more information" + exit 1 + ;; + + aclocal*) + if test -z "$run" && ($1 --version) > /dev/null 2>&1; then + # We have it, but it failed. + exit 1 + fi + + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified \`acinclude.m4' or \`${configure_ac}'. You might want + to install the \`Automake' and \`Perl' packages. Grab them from + any GNU archive site." + touch aclocal.m4 + ;; + + autoconf) + if test -z "$run" && ($1 --version) > /dev/null 2>&1; then + # We have it, but it failed. + exit 1 + fi + + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified \`${configure_ac}'. You might want to install the + \`Autoconf' and \`GNU m4' packages. Grab them from any GNU + archive site." + touch configure + ;; + + autoheader) + if test -z "$run" && ($1 --version) > /dev/null 2>&1; then + # We have it, but it failed. + exit 1 + fi + + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified \`acconfig.h' or \`${configure_ac}'. You might want + to install the \`Autoconf' and \`GNU m4' packages. Grab them + from any GNU archive site." + files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}` + test -z "$files" && files="config.h" + touch_files= + for f in $files; do + case "$f" in + *:*) touch_files="$touch_files "`echo "$f" | + sed -e 's/^[^:]*://' -e 's/:.*//'`;; + *) touch_files="$touch_files $f.in";; + esac + done + touch $touch_files + ;; + + automake*) + if test -z "$run" && ($1 --version) > /dev/null 2>&1; then + # We have it, but it failed. + exit 1 + fi + + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'. + You might want to install the \`Automake' and \`Perl' packages. + Grab them from any GNU archive site." + find . -type f -name Makefile.am -print | + sed 's/\.am$/.in/' | + while read f; do touch "$f"; done + ;; + + autom4te) + if test -z "$run" && ($1 --version) > /dev/null 2>&1; then + # We have it, but it failed. + exit 1 + fi + + echo 1>&2 "\ +WARNING: \`$1' is needed, and you do not seem to have it handy on your + system. You might have modified some files without having the + proper tools for further handling them. + You can get \`$1' as part of \`Autoconf' from any GNU + archive site." + + file=`echo "$*" | sed -n 's/.*--output[ =]*\([^ ]*\).*/\1/p'` + test -z "$file" && file=`echo "$*" | sed -n 's/.*-o[ ]*\([^ ]*\).*/\1/p'` + if test -f "$file"; then + touch $file + else + test -z "$file" || exec >$file + echo "#! /bin/sh" + echo "# Created by GNU Automake missing as a replacement of" + echo "# $ $@" + echo "exit 0" + chmod +x $file + exit 1 + fi + ;; + + bison|yacc) + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified a \`.y' file. You may need the \`Bison' package + in order for those modifications to take effect. You can get + \`Bison' from any GNU archive site." + rm -f y.tab.c y.tab.h + if [ $# -ne 1 ]; then + eval LASTARG="\${$#}" + case "$LASTARG" in + *.y) + SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` + if [ -f "$SRCFILE" ]; then + cp "$SRCFILE" y.tab.c + fi + SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` + if [ -f "$SRCFILE" ]; then + cp "$SRCFILE" y.tab.h + fi + ;; + esac + fi + if [ ! -f y.tab.h ]; then + echo >y.tab.h + fi + if [ ! -f y.tab.c ]; then + echo 'main() { return 0; }' >y.tab.c + fi + ;; + + lex|flex) + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified a \`.l' file. You may need the \`Flex' package + in order for those modifications to take effect. You can get + \`Flex' from any GNU archive site." + rm -f lex.yy.c + if [ $# -ne 1 ]; then + eval LASTARG="\${$#}" + case "$LASTARG" in + *.l) + SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` + if [ -f "$SRCFILE" ]; then + cp "$SRCFILE" lex.yy.c + fi + ;; + esac + fi + if [ ! -f lex.yy.c ]; then + echo 'main() { return 0; }' >lex.yy.c + fi + ;; + + help2man) + if test -z "$run" && ($1 --version) > /dev/null 2>&1; then + # We have it, but it failed. + exit 1 + fi + + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified a dependency of a manual page. You may need the + \`Help2man' package in order for those modifications to take + effect. You can get \`Help2man' from any GNU archive site." + + file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'` + if test -z "$file"; then + file=`echo "$*" | sed -n 's/.*--output=\([^ ]*\).*/\1/p'` + fi + if [ -f "$file" ]; then + touch $file + else + test -z "$file" || exec >$file + echo ".ab help2man is required to generate this page" + exit 1 + fi + ;; + + makeinfo) + if test -z "$run" && (makeinfo --version) > /dev/null 2>&1; then + # We have makeinfo, but it failed. + exit 1 + fi + + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified a \`.texi' or \`.texinfo' file, or any other file + indirectly affecting the aspect of the manual. The spurious + call might also be the consequence of using a buggy \`make' (AIX, + DU, IRIX). You might want to install the \`Texinfo' package or + the \`GNU make' package. Grab either from any GNU archive site." + file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'` + if test -z "$file"; then + file=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` + file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $file` + fi + touch $file + ;; + + tar) + shift + if test -n "$run"; then + echo 1>&2 "ERROR: \`tar' requires --run" + exit 1 + fi + + # We have already tried tar in the generic part. + # Look for gnutar/gtar before invocation to avoid ugly error + # messages. + if (gnutar --version > /dev/null 2>&1); then + gnutar "$@" && exit 0 + fi + if (gtar --version > /dev/null 2>&1); then + gtar "$@" && exit 0 + fi + firstarg="$1" + if shift; then + case "$firstarg" in + *o*) + firstarg=`echo "$firstarg" | sed s/o//` + tar "$firstarg" "$@" && exit 0 + ;; + esac + case "$firstarg" in + *h*) + firstarg=`echo "$firstarg" | sed s/h//` + tar "$firstarg" "$@" && exit 0 + ;; + esac + fi + + echo 1>&2 "\ +WARNING: I can't seem to be able to run \`tar' with the given arguments. + You may want to install GNU tar or Free paxutils, or check the + command line arguments." + exit 1 + ;; + + *) + echo 1>&2 "\ +WARNING: \`$1' is needed, and you do not seem to have it handy on your + system. You might have modified some files without having the + proper tools for further handling them. Check the \`README' file, + it often tells you about the needed prerequisites for installing + this package. You may also peek at any GNU archive site, in case + some other package would contain this missing \`$1' program." + exit 1 + ;; +esac + +exit 0 diff --git a/mkinstalldirs b/mkinstalldirs new file mode 100755 index 0000000..d2d5f21 --- /dev/null +++ b/mkinstalldirs @@ -0,0 +1,111 @@ +#! /bin/sh +# mkinstalldirs --- make directory hierarchy +# Author: Noah Friedman +# Created: 1993-05-16 +# Public domain + +errstatus=0 +dirmode="" + +usage="\ +Usage: mkinstalldirs [-h] [--help] [-m mode] dir ..." + +# process command line arguments +while test $# -gt 0 ; do + case $1 in + -h | --help | --h*) # -h for help + echo "$usage" 1>&2 + exit 0 + ;; + -m) # -m PERM arg + shift + test $# -eq 0 && { echo "$usage" 1>&2; exit 1; } + dirmode=$1 + shift + ;; + --) # stop option processing + shift + break + ;; + -*) # unknown option + echo "$usage" 1>&2 + exit 1 + ;; + *) # first non-opt arg + break + ;; + esac +done + +for file +do + if test -d "$file"; then + shift + else + break + fi +done + +case $# in + 0) exit 0 ;; +esac + +case $dirmode in + '') + if mkdir -p -- . 2>/dev/null; then + echo "mkdir -p -- $*" + exec mkdir -p -- "$@" + fi + ;; + *) + if mkdir -m "$dirmode" -p -- . 2>/dev/null; then + echo "mkdir -m $dirmode -p -- $*" + exec mkdir -m "$dirmode" -p -- "$@" + fi + ;; +esac + +for file +do + set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'` + shift + + pathcomp= + for d + do + pathcomp="$pathcomp$d" + case $pathcomp in + -*) pathcomp=./$pathcomp ;; + esac + + if test ! -d "$pathcomp"; then + echo "mkdir $pathcomp" + + mkdir "$pathcomp" || lasterr=$? + + if test ! -d "$pathcomp"; then + errstatus=$lasterr + else + if test ! -z "$dirmode"; then + echo "chmod $dirmode $pathcomp" + lasterr="" + chmod "$dirmode" "$pathcomp" || lasterr=$? + + if test ! -z "$lasterr"; then + errstatus=$lasterr + fi + fi + fi + fi + + pathcomp="$pathcomp/" + done +done + +exit $errstatus + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# End: +# mkinstalldirs ends here diff --git a/netperf.spec.in b/netperf.spec.in new file mode 100644 index 0000000..9f8639a --- /dev/null +++ b/netperf.spec.in @@ -0,0 +1,55 @@ +Summary: Network Performance Testing Tool +Name: netperf +Version: @VERSION@ +Release: 1 +Copyright: Unknown +Group: System Environment/Base +URL: http://www.netperf.org/ +Packager: Martin A. Brown +Source: ftp://ftp.netperf.org/netperf/%{name}-%{version}.tar.gz +BuildRoot: %{_tmppath}/%{name}-root +Prefix: /usr + +%description +Many different network benchmarking tools are collected in this package, +maintained by Rick Jones of HP. + +%prep +%setup + +%build +#%patch0 -p1 +./configure \ + --prefix=%{_prefix} \ + --mandir=%{_mandir} \ + --infodir=%{_infodir} +make + +%install +test "$RPM_BUILD_ROOT" = "/" || rm -rf $RPM_BUILD_ROOT +make DESTDIR=${RPM_BUILD_ROOT} install + +# -- .svn directory only needed by developers; blowing it away +# in our BUILD/ directory, so that we do not package it +# +rm -rf doc/examples/.svn + +%clean +test "$RPM_BUILD_ROOT" = "/" || rm -rf $RPM_BUILD_ROOT + +# %post + +%files +%defattr(-,root,root) +%doc README AUTHORS ChangeLog INSTALL COPYING +%doc README.* Release_Notes +%doc doc/examples +%{_mandir}/man1/* +%{_infodir}/* +%{_bindir}/netperf +%{_bindir}/netserver + + +%changelog +* Sat Jun 17 2006 Martin A. Brown +- initial contributed specfile for netperf package (v2.4.2) diff --git a/src/Makefile.am b/src/Makefile.am new file mode 100644 index 0000000..dc4a121 --- /dev/null +++ b/src/Makefile.am @@ -0,0 +1,27 @@ +SUBDIRS = missing + +CLEANFILES = netperf_version.h + +bin_PROGRAMS = netperf netserver + +AM_CFLAGS = $(NETPERF_CFLAGS) + +USE_CPU_SOURCE=netcpu_@NETCPU_SOURCE@.c +USE_RT_SOURCE=netrt_@NETRTLKUP_SOURCE@.c +USE_DRV_SOURCE=netdrv_@NETDRVLKUP_SOURCE@.c +USE_SLOT_SOURCE=netslot_@NETSLOTLKUP_SOURCE@.c +USE_SYS_SOURCE=netsys_@NETSYSLKUP_SOURCE@.c +USE_SEC_SOURCE=netsec_@NETSECLKUP_SOURCE@.c + +EXTRA_DIST = netcpu_none.c netcpu_looper.c netcpu_pstat.c netcpu_pstatnew.c netcpu_perfstat.c netcpu_procstat.c netcpu_kstat.c netcpu_kstat10.c netcpu_sysctl.c netcpu_ntperf.c netcpu_osx.c dirs NetPerfDir/* NetServerDir/* netperf_version.h.in netrt_rtnetlink.c netrt_none.c netrt_rtmget.c netdrv_ethtool.c netdrv_none.c netslot_linux.c netslot_none.c netsys_none.c netsys_hpux11i.c netsys_linux.c netsys_solaris.c netdrv_solaris.c netslot_solaris.c netsec_linux.c netsec_none.c Makefile.uw + +COMMON_SRC = hist.h netlib.c netlib.h netcpu.h netsh.c netsh.h nettest_bsd.c nettest_bsd.h nettest_dlpi.c nettest_dlpi.h nettest_unix.c nettest_unix.h nettest_xti.c nettest_xti.h nettest_sctp.c nettest_sctp.h netperf_version.h nettest_sdp.c nettest_sdp.h nettest_omni.c net_uuid.c + +netperf_SOURCES = netperf.c $(COMMON_SRC) $(USE_CPU_SOURCE) $(USE_RT_SOURCE) $(USE_DRV_SOURCE) $(USE_SLOT_SOURCE) $(USE_SYS_SOURCE) $(USE_SEC_SOURCE) +netserver_SOURCES = netserver.c $(COMMON_SRC) $(USE_CPU_SOURCE) $(USE_RT_SOURCE) $(USE_DRV_SOURCE) $(USE_SLOT_SOURCE) $(USE_SYS_SOURCE) $(USE_SEC_SOURCE) + +# if there are any "missing" routines, the libobjs should cover it +if NEED_LIBCOMPAT +netperf_LDADD = missing/libcompat.a +netserver_LDADD = missing/libcompat.a +endif diff --git a/src/Makefile.in b/src/Makefile.in new file mode 100644 index 0000000..cf0da98 --- /dev/null +++ b/src/Makefile.in @@ -0,0 +1,586 @@ +# Makefile.in generated by automake 1.7.9 from Makefile.am. +# @configure_input@ + +# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 +# Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +top_builddir = .. + +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +INSTALL = @INSTALL@ +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +host_triplet = @host@ +ACLOCAL = @ACLOCAL@ +AMDEP_FALSE = @AMDEP_FALSE@ +AMDEP_TRUE = @AMDEP_TRUE@ +AMTAR = @AMTAR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +GREP = @GREP@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +NEED_LIBCOMPAT_FALSE = @NEED_LIBCOMPAT_FALSE@ +NEED_LIBCOMPAT_TRUE = @NEED_LIBCOMPAT_TRUE@ +NETCPU_SOURCE = @NETCPU_SOURCE@ +NETDRVLKUP_SOURCE = @NETDRVLKUP_SOURCE@ +NETRTLKUP_SOURCE = @NETRTLKUP_SOURCE@ +NETSECLKUP_SOURCE = @NETSECLKUP_SOURCE@ +NETSLOTLKUP_SOURCE = @NETSLOTLKUP_SOURCE@ +NETSYSLKUP_SOURCE = @NETSYSLKUP_SOURCE@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +ac_ct_CC = @ac_ct_CC@ +am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ +am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +sysconfdir = @sysconfdir@ +target = @target@ +target_alias = @target_alias@ +target_cpu = @target_cpu@ +target_os = @target_os@ +target_vendor = @target_vendor@ +SUBDIRS = missing + +CLEANFILES = netperf_version.h + +bin_PROGRAMS = netperf netserver + +AM_CFLAGS = $(NETPERF_CFLAGS) + +USE_CPU_SOURCE = netcpu_@NETCPU_SOURCE@.c +USE_RT_SOURCE = netrt_@NETRTLKUP_SOURCE@.c +USE_DRV_SOURCE = netdrv_@NETDRVLKUP_SOURCE@.c +USE_SLOT_SOURCE = netslot_@NETSLOTLKUP_SOURCE@.c +USE_SYS_SOURCE = netsys_@NETSYSLKUP_SOURCE@.c +USE_SEC_SOURCE = netsec_@NETSECLKUP_SOURCE@.c + +EXTRA_DIST = netcpu_none.c netcpu_looper.c netcpu_pstat.c netcpu_pstatnew.c netcpu_perfstat.c netcpu_procstat.c netcpu_kstat.c netcpu_kstat10.c netcpu_sysctl.c netcpu_ntperf.c netcpu_osx.c dirs NetPerfDir/* NetServerDir/* netperf_version.h.in netrt_rtnetlink.c netrt_none.c netrt_rtmget.c netdrv_ethtool.c netdrv_none.c netslot_linux.c netslot_none.c netsys_none.c netsys_hpux11i.c netsys_linux.c netsys_solaris.c netdrv_solaris.c netslot_solaris.c netsec_linux.c netsec_none.c Makefile.uw + +COMMON_SRC = hist.h netlib.c netlib.h netcpu.h netsh.c netsh.h nettest_bsd.c nettest_bsd.h nettest_dlpi.c nettest_dlpi.h nettest_unix.c nettest_unix.h nettest_xti.c nettest_xti.h nettest_sctp.c nettest_sctp.h netperf_version.h nettest_sdp.c nettest_sdp.h nettest_omni.c net_uuid.c + +netperf_SOURCES = netperf.c $(COMMON_SRC) $(USE_CPU_SOURCE) $(USE_RT_SOURCE) $(USE_DRV_SOURCE) $(USE_SLOT_SOURCE) $(USE_SYS_SOURCE) $(USE_SEC_SOURCE) +netserver_SOURCES = netserver.c $(COMMON_SRC) $(USE_CPU_SOURCE) $(USE_RT_SOURCE) $(USE_DRV_SOURCE) $(USE_SLOT_SOURCE) $(USE_SYS_SOURCE) $(USE_SEC_SOURCE) + +# if there are any "missing" routines, the libobjs should cover it +@NEED_LIBCOMPAT_TRUE@netperf_LDADD = missing/libcompat.a +@NEED_LIBCOMPAT_TRUE@netserver_LDADD = missing/libcompat.a +subdir = src +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = netperf_version.h +bin_PROGRAMS = netperf$(EXEEXT) netserver$(EXEEXT) +PROGRAMS = $(bin_PROGRAMS) + +am__objects_1 = netlib.$(OBJEXT) netsh.$(OBJEXT) nettest_bsd.$(OBJEXT) \ + nettest_dlpi.$(OBJEXT) nettest_unix.$(OBJEXT) \ + nettest_xti.$(OBJEXT) nettest_sctp.$(OBJEXT) \ + nettest_sdp.$(OBJEXT) nettest_omni.$(OBJEXT) net_uuid.$(OBJEXT) +am__objects_2 = netcpu_@NETCPU_SOURCE@.$(OBJEXT) +am__objects_3 = netrt_@NETRTLKUP_SOURCE@.$(OBJEXT) +am__objects_4 = netdrv_@NETDRVLKUP_SOURCE@.$(OBJEXT) +am__objects_5 = netslot_@NETSLOTLKUP_SOURCE@.$(OBJEXT) +am__objects_6 = netsys_@NETSYSLKUP_SOURCE@.$(OBJEXT) +am__objects_7 = netsec_@NETSECLKUP_SOURCE@.$(OBJEXT) +am_netperf_OBJECTS = netperf.$(OBJEXT) $(am__objects_1) $(am__objects_2) \ + $(am__objects_3) $(am__objects_4) $(am__objects_5) \ + $(am__objects_6) $(am__objects_7) +netperf_OBJECTS = $(am_netperf_OBJECTS) +@NEED_LIBCOMPAT_TRUE@netperf_DEPENDENCIES = missing/libcompat.a +@NEED_LIBCOMPAT_FALSE@netperf_DEPENDENCIES = +netperf_LDFLAGS = +am_netserver_OBJECTS = netserver.$(OBJEXT) $(am__objects_1) \ + $(am__objects_2) $(am__objects_3) $(am__objects_4) \ + $(am__objects_5) $(am__objects_6) $(am__objects_7) +netserver_OBJECTS = $(am_netserver_OBJECTS) +@NEED_LIBCOMPAT_TRUE@netserver_DEPENDENCIES = missing/libcompat.a +@NEED_LIBCOMPAT_FALSE@netserver_DEPENDENCIES = +netserver_LDFLAGS = + +DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +@AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/net_uuid.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/netcpu_@NETCPU_SOURCE@.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/netdrv_@NETDRVLKUP_SOURCE@.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/netlib.Po ./$(DEPDIR)/netperf.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/netrt_@NETRTLKUP_SOURCE@.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/netsec_@NETSECLKUP_SOURCE@.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/netserver.Po ./$(DEPDIR)/netsh.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/netslot_@NETSLOTLKUP_SOURCE@.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/netsys_@NETSYSLKUP_SOURCE@.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/nettest_bsd.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/nettest_dlpi.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/nettest_omni.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/nettest_sctp.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/nettest_sdp.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/nettest_unix.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/nettest_xti.Po +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +DIST_SOURCES = $(netperf_SOURCES) $(netserver_SOURCES) + +RECURSIVE_TARGETS = info-recursive dvi-recursive pdf-recursive \ + ps-recursive install-info-recursive uninstall-info-recursive \ + all-recursive install-data-recursive install-exec-recursive \ + installdirs-recursive install-recursive uninstall-recursive \ + check-recursive installcheck-recursive +DIST_COMMON = $(srcdir)/Makefile.in Makefile.am netperf_version.h.in +DIST_SUBDIRS = $(SUBDIRS) +SOURCES = $(netperf_SOURCES) $(netserver_SOURCES) + +all: all-recursive + +.SUFFIXES: +.SUFFIXES: .c .o .obj +$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.ac $(ACLOCAL_M4) + cd $(top_srcdir) && \ + $(AUTOMAKE) --gnu src/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe) +netperf_version.h: $(top_builddir)/config.status netperf_version.h.in + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ +binPROGRAMS_INSTALL = $(INSTALL_PROGRAM) +install-binPROGRAMS: $(bin_PROGRAMS) + @$(NORMAL_INSTALL) + $(mkinstalldirs) $(DESTDIR)$(bindir) + @list='$(bin_PROGRAMS)'; for p in $$list; do \ + p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \ + if test -f $$p \ + ; then \ + f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \ + echo " $(INSTALL_PROGRAM_ENV) $(binPROGRAMS_INSTALL) $$p $(DESTDIR)$(bindir)/$$f"; \ + $(INSTALL_PROGRAM_ENV) $(binPROGRAMS_INSTALL) $$p $(DESTDIR)$(bindir)/$$f || exit 1; \ + else :; fi; \ + done + +uninstall-binPROGRAMS: + @$(NORMAL_UNINSTALL) + @list='$(bin_PROGRAMS)'; for p in $$list; do \ + f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \ + echo " rm -f $(DESTDIR)$(bindir)/$$f"; \ + rm -f $(DESTDIR)$(bindir)/$$f; \ + done + +clean-binPROGRAMS: + -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS) +netperf$(EXEEXT): $(netperf_OBJECTS) $(netperf_DEPENDENCIES) + @rm -f netperf$(EXEEXT) + $(LINK) $(netperf_LDFLAGS) $(netperf_OBJECTS) $(netperf_LDADD) $(LIBS) +netserver$(EXEEXT): $(netserver_OBJECTS) $(netserver_DEPENDENCIES) + @rm -f netserver$(EXEEXT) + $(LINK) $(netserver_LDFLAGS) $(netserver_OBJECTS) $(netserver_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) core *.core + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/net_uuid.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/netcpu_@NETCPU_SOURCE@.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/netdrv_@NETDRVLKUP_SOURCE@.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/netlib.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/netperf.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/netrt_@NETRTLKUP_SOURCE@.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/netsec_@NETSECLKUP_SOURCE@.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/netserver.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/netsh.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/netslot_@NETSLOTLKUP_SOURCE@.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/netsys_@NETSYSLKUP_SOURCE@.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nettest_bsd.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nettest_dlpi.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nettest_omni.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nettest_sctp.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nettest_sdp.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nettest_unix.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nettest_xti.Po@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \ +@am__fastdepCC_TRUE@ -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \ +@am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \ +@am__fastdepCC_TRUE@ fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `test -f '$<' || echo '$(srcdir)/'`$< + +.c.obj: +@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \ +@am__fastdepCC_TRUE@ -c -o $@ `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi`; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \ +@am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \ +@am__fastdepCC_TRUE@ fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi` +uninstall-info-am: + +# This directory's subdirectories are mostly independent; you can cd +# into them and run `make' without going through this Makefile. +# To change the values of `make' variables: instead of editing Makefiles, +# (1) if the variable is set in `config.status', edit `config.status' +# (which will cause the Makefiles to be regenerated when you run `make'); +# (2) otherwise, pass the desired values on the `make' command line. +$(RECURSIVE_TARGETS): + @set fnord $$MAKEFLAGS; amf=$$2; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +mostlyclean-recursive clean-recursive distclean-recursive \ +maintainer-clean-recursive: + @set fnord $$MAKEFLAGS; amf=$$2; \ + dot_seen=no; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + rev=''; for subdir in $$list; do \ + if test "$$subdir" = "."; then :; else \ + rev="$$subdir $$rev"; \ + fi; \ + done; \ + rev="$$rev ."; \ + target=`echo $@ | sed s/-recursive//`; \ + for subdir in $$rev; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ + done && test -z "$$fail" +tags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ + done +ctags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ + done + +ETAGS = etags +ETAGSFLAGS = + +CTAGS = ctags +CTAGSFLAGS = + +tags: TAGS + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + mkid -fID $$unique + +TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + if (etags --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + else \ + include_option=--include; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test -f $$subdir/TAGS && \ + tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(ETAGS_ARGS)$$tags$$unique" \ + || $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$tags $$unique + +ctags: CTAGS +CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(CTAGS_ARGS)$$tags$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$tags $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && cd $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) $$here + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) + +top_distdir = .. +distdir = $(top_distdir)/$(PACKAGE)-$(VERSION) + +distdir: $(DISTFILES) + $(mkinstalldirs) $(distdir)/NetPerfDir $(distdir)/NetServerDir + @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ + list='$(DISTFILES)'; for file in $$list; do \ + case $$file in \ + $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ + $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ + esac; \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test "$$dir" != "$$file" && test "$$dir" != "."; then \ + dir="/$$dir"; \ + $(mkinstalldirs) "$(distdir)$$dir"; \ + else \ + dir=''; \ + fi; \ + if test -d $$d/$$file; then \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test -d $(distdir)/$$subdir \ + || mkdir $(distdir)/$$subdir \ + || exit 1; \ + (cd $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$(top_distdir)" \ + distdir=../$(distdir)/$$subdir \ + distdir) \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-recursive +all-am: Makefile $(PROGRAMS) +installdirs: installdirs-recursive +installdirs-am: + $(mkinstalldirs) $(DESTDIR)$(bindir) + +install: install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-recursive +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -rm -f $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-recursive + +clean-am: clean-binPROGRAMS clean-generic mostlyclean-am + +distclean: distclean-recursive + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-recursive + +dvi-am: + +info: info-recursive + +info-am: + +install-data-am: + +install-exec-am: install-binPROGRAMS + +install-info: install-info-recursive + +install-man: + +installcheck-am: + +maintainer-clean: maintainer-clean-recursive + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-recursive + +mostlyclean-am: mostlyclean-compile mostlyclean-generic + +pdf: pdf-recursive + +pdf-am: + +ps: ps-recursive + +ps-am: + +uninstall-am: uninstall-binPROGRAMS uninstall-info-am + +uninstall-info: uninstall-info-recursive + +.PHONY: $(RECURSIVE_TARGETS) CTAGS GTAGS all all-am check check-am clean \ + clean-binPROGRAMS clean-generic clean-recursive ctags \ + ctags-recursive distclean distclean-compile distclean-generic \ + distclean-recursive distclean-tags distdir dvi dvi-am \ + dvi-recursive info info-am info-recursive install install-am \ + install-binPROGRAMS install-data install-data-am \ + install-data-recursive install-exec install-exec-am \ + install-exec-recursive install-info install-info-am \ + install-info-recursive install-man install-recursive \ + install-strip installcheck installcheck-am installdirs \ + installdirs-am installdirs-recursive maintainer-clean \ + maintainer-clean-generic maintainer-clean-recursive mostlyclean \ + mostlyclean-compile mostlyclean-generic mostlyclean-recursive \ + pdf pdf-am pdf-recursive ps ps-am ps-recursive tags \ + tags-recursive uninstall uninstall-am uninstall-binPROGRAMS \ + uninstall-info-am uninstall-info-recursive uninstall-recursive + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/src/Makefile.uw b/src/Makefile.uw new file mode 100644 index 0000000..24288c8 --- /dev/null +++ b/src/Makefile.uw @@ -0,0 +1,106 @@ +# User-world netperf Makefile. +# Copyright 2008, VMware, Inc. +# Portions Copyright 2008, Hewlett-Packard Company. +# +# Assume we're building in a DDK universe. +# +BORA_ROOT = /build/toolchain/lin32 + +# +# userworld library paths, relative to bora-root +# +UWGCC_ROOT = $(BORA_ROOT)/gcc-3.3.3 +UWGLIBC_TOP_DIR = $(BORA_ROOT)/uwglibc-2.2.5 +UWGLIBC_LIB_DIR = $(UWGLIBC_TOP_DIR)/lib +UWGLIBC_USR_DIR = $(UWGLIBC_TOP_DIR)/usr/lib +UWGLIBC_DEST_DIR = /usr/lib/vmware/lib + +# +# userworld include paths +# +GCC_INCLUDES = -isystem $(UWGCC_ROOT)/lib/gcc-lib/i686-linux/3.3.3/include +GLIBC_INCLUDES = -isystem $(BORA_ROOT)/glibc-2.2.5-44/usr/include + +# +# userworld compiler environment +# +CC = GCC_EXEC_PREFIX="$(UWGCC_ROOT)/lib/gcc-lib/" \ + KROOT=$(BORA_ROOT) \ + PATH="$(UWGCC_ROOT)/bin:$(BORA_ROOT)/binutils-2.16.1-vt/bin:/bin:/sbin:/usr/sbin:/usr/bin" \ + $(UWGCC_ROOT)/bin/i686-linux-gcc + +CC_INCLUDES = -nostdinc $(GCC_INCLUDES) $(GLIBC_INCLUDES) $(UWVER_INCLUDES) + +# +# userworld shared libraries +# +UWGLIBC_LDLINUX_SO = ld-linux.so.2 + +UWGLIBC_LINK_OPTS = -nostdlib -nostartfiles \ + -Xlinker --dynamic-linker=$(UWGLIBC_DEST_DIR)/$(UWGLIBC_LDLINUX_SO) \ + -Xlinker -z -Xlinker nodefaultlib \ + -Xlinker -rpath -Xlinker $(UWGLIBC_DEST_DIR) \ + -L$(UWGLIBC_USR_DIR) \ + -L$(UWGLIBC_LIB_DIR) + +UWGLIBC_LINK_CRTS = \ + ${UWGLIBC_TOP_DIR}/usr/lib/crt1.o \ + ${UWGLIBC_TOP_DIR}/usr/lib/crti.o \ + ${UWGCC_ROOT}/lib/gcc-lib/i686-linux/3.3.3/crtbegin.o \ + ${UWGCC_ROOT}/lib/gcc-lib/i686-linux/3.3.3/crtend.o \ + ${UWGLIBC_TOP_DIR}/usr/lib/crtn.o + +CFLAGS = -DVMWARE_UW $(CC_INCLUDES) -g -O -mcpu=pentiumpro +CFLAGS += -DDEBUG_LOG_FILE=\"/dev/null\" -DDO_FIRST_BURST -DDO_UNIX + +UWGLIBC_LINK_LIBS = -lm -ldl -lpthread -lresolv -lnss_nis -lnss_nisplus \ + -lnss_files -lnss_compat -lnss_dns -lnsl -lc -lc_nonshared -lgcc +LDFLAGS = $(UWGLIBC_LINK_OPTS) $(UWGLIBC_LINK_CRTS) \ + $(UWGLIBC_LINK_LIBS) ${UWGLIBC_LIB_DIR}/${UWGLIBC_LDLINUX_SO} + +NETSERVER_OBJS = netserver.o nettest_bsd.o nettest_dlpi.o \ + nettest_unix.o netlib.o netsh.o \ + nettest_xti.o nettest_ipv6.o \ + netcpu_none.c \ + nettest_dns.o + +NETPERF_OBJS = netperf.o netsh.o netlib.o nettest_bsd.o \ + nettest_dlpi.o nettest_unix.o \ + nettest_xti.o nettest_ipv6.o \ + netcpu_none.c \ + nettest_dns.o + +all: netperf-uw netserver-uw + +netperf-uw: $(NETPERF_OBJS) + $(CC) -o $@ $(NETPERF_OBJS) $(LDFLAGS) + strip $@ + +netserver-uw: $(NETSERVER_OBJS) + $(CC) -o $@ $(NETSERVER_OBJS) $(LDFLAGS) + strip $@ + +netperf.o: netperf.c netsh.h Makefile.uw + +netsh.o: netsh.c netsh.h nettest_bsd.h netlib.h Makefile.uw + +netlib.o: netlib.c netlib.h netsh.h Makefile.uw + +nettest_bsd.o: nettest_bsd.c nettest_bsd.h netlib.h netsh.h Makefile.uw + +nettest_dlpi.o: nettest_dlpi.c nettest_dlpi.h netlib.h netsh.h Makefile.uw + +nettest_unix.o: nettest_unix.c nettest_unix.h netlib.h netsh.h Makefile.uw + +nettest_xti.o: nettest_xti.c nettest_xti.h netlib.h netsh.h Makefile.uw + +nettest_ipv6.o: nettest_ipv6.c nettest_ipv6.h netlib.h netsh.h Makefile.uw + +nettest_dns.o: nettest_dns.c nettest_dns.h netlib.h netsh.h Makefile.uw + +netcpu_none.o: netcpu_none.c netsh.h netlib.h + +netserver.o: netserver.c nettest_bsd.h netlib.h Makefile.uw + +clean: + rm -f *.o netperf-uw netserver-uw diff --git a/src/NetPerfDir/inet_ntop.c b/src/NetPerfDir/inet_ntop.c new file mode 100644 index 0000000..f644e4a --- /dev/null +++ b/src/NetPerfDir/inet_ntop.c @@ -0,0 +1,6 @@ +#if !defined(InetNtop) + +/* +*+ Why isn't this in the winsock headers yet? */ + +#include "..\missing\inet_ntop.c" +#endif diff --git a/src/NetPerfDir/makefile b/src/NetPerfDir/makefile new file mode 100644 index 0000000..b90b71d --- /dev/null +++ b/src/NetPerfDir/makefile @@ -0,0 +1,7 @@ +# +# DO NOT EDIT THIS FILE!!! Edit .\sources. if you want to add a new source +# file to this component. This file merely indirects to the real make file +# that is shared by all the driver components of the Windows NT DDK +# + +!INCLUDE $(NTMAKEENV)\makefile.def \ No newline at end of file diff --git a/src/NetPerfDir/sources b/src/NetPerfDir/sources new file mode 100644 index 0000000..5a6eb81 --- /dev/null +++ b/src/NetPerfDir/sources @@ -0,0 +1,29 @@ +TARGETNAME=netperf +TARGETPATH=OBJ +TARGETTYPE=PROGRAM + +LINKLIBS= \ + $(SDK_LIB_PATH)\kernel32.lib \ + $(SDK_LIB_PATH)\ws2_32.lib \ + $(SDK_LIB_PATH)\wsock32.lib + +USE_MSVCRT=1 +UMTYPE=console + +INCLUDES=$(SDK_INC_PATH);. + +MSC_WARNING_LEVEL=/W3 /WX + +C_DEFINES=$(C_DEFINES) -D_CONSOLE_ -DHAVE_STRUCT_SOCKADDR_STORAGE -DHAVE_GETADDRINFO -DHAVE_GETNAMEINFO -DSTDC_HEADERS + +#USER_C_FLAGS=$(USER_C_FLAGS) /E + +SOURCES= \ + ..\netcpu_ntperf.c \ + ..\netlib.c \ + ..\netsh.c \ + ..\nettest_bsd.c \ + ..\netperf.c \ + ..\inet_ntop.c + + diff --git a/src/NetPerfDir/sources~ b/src/NetPerfDir/sources~ new file mode 100644 index 0000000..57d231b --- /dev/null +++ b/src/NetPerfDir/sources~ @@ -0,0 +1,27 @@ +TARGETNAME=netperf +TARGETPATH=OBJ +TARGETTYPE=PROGRAM + +LINKLIBS= \ + $(SDK_LIB_PATH)\kernel32.lib \ + $(SDK_LIB_PATH)\ws2_32.lib \ + $(SDK_LIB_PATH)\wsock32.lib + +USE_CRTDLL=1 +UMTYPE=console + +INCLUDES=$(SDK_INC_PATH);. + +MSC_WARNING_LEVEL=/W3 /WX + +C_DEFINES=$(C_DEFINES) -D_CONSOLE_ -DHAVE_GETADDRINFO -DHAVE_GETNAMEINFO -DSTDC_HEADERS + +SOURCES= \ + ..\netcpu_ntperf.c \ + ..\netlib.c \ + ..\netsh.c \ + ..\nettest_bsd.c \ + inet_ntop.c \ + ..\netperf.c + + diff --git a/src/NetServerDir/inet_ntop.c b/src/NetServerDir/inet_ntop.c new file mode 100644 index 0000000..f644e4a --- /dev/null +++ b/src/NetServerDir/inet_ntop.c @@ -0,0 +1,6 @@ +#if !defined(InetNtop) + +/* +*+ Why isn't this in the winsock headers yet? */ + +#include "..\missing\inet_ntop.c" +#endif diff --git a/src/NetServerDir/makefile b/src/NetServerDir/makefile new file mode 100644 index 0000000..b90b71d --- /dev/null +++ b/src/NetServerDir/makefile @@ -0,0 +1,7 @@ +# +# DO NOT EDIT THIS FILE!!! Edit .\sources. if you want to add a new source +# file to this component. This file merely indirects to the real make file +# that is shared by all the driver components of the Windows NT DDK +# + +!INCLUDE $(NTMAKEENV)\makefile.def \ No newline at end of file diff --git a/src/NetServerDir/sources b/src/NetServerDir/sources new file mode 100644 index 0000000..5a04c2a --- /dev/null +++ b/src/NetServerDir/sources @@ -0,0 +1,28 @@ +TARGETNAME=netserver +TARGETPATH=OBJ +TARGETTYPE=PROGRAM + +LINKLIBS= \ + $(SDK_LIB_PATH)\kernel32.lib \ + $(SDK_LIB_PATH)\ws2_32.lib \ + $(SDK_LIB_PATH)\wsock32.lib + +USE_MSVCRT=1 +UMTYPE=console + +INCLUDES=$(SDK_INC_PATH);. + +MSC_WARNING_LEVEL=/W3 /WX + +C_DEFINES=$(C_DEFINES) -D_CONSOLE_ -DHAVE_STRUCT_SOCKADDR_STORAGE -DHAVE_GETADDRINFO -DHAVE_GETNAMEINFO -DSTDC_HEADERS + +#USER_C_FLAGS=$(USER_C_FLAGS) /E + +SOURCES= \ + ..\netcpu_ntperf.c \ + ..\netlib.c \ + ..\netsh.c \ + ..\nettest_bsd.c \ + ..\netserver.c \ + ..\inet_ntop.c + diff --git a/src/NetServerDir/sources~ b/src/NetServerDir/sources~ new file mode 100644 index 0000000..69117cf --- /dev/null +++ b/src/NetServerDir/sources~ @@ -0,0 +1,26 @@ +TARGETNAME=netserver +TARGETPATH=OBJ +TARGETTYPE=PROGRAM + +LINKLIBS= \ + $(SDK_LIB_PATH)\kernel32.lib \ + $(SDK_LIB_PATH)\ws2_32.lib \ + $(SDK_LIB_PATH)\wsock32.lib + +USE_CRTDLL=1 +UMTYPE=console + +INCLUDES=$(SDK_INC_PATH);. + +MSC_WARNING_LEVEL=/W3 /WX + +C_DEFINES=$(C_DEFINES) -D_CONSOLE_ -DHAVE_GETADDRINFO -DHAVE_GETNAMEINFO -DSTDC_HEADERS + +SOURCES= \ + ..\netcpu_ntperf.c \ + ..\netlib.c \ + ..\netsh.c \ + ..\nettest_bsd.c \ + inet_ntop.c \ + ..\netserver.c + diff --git a/src/dirs b/src/dirs new file mode 100644 index 0000000..47972b1 --- /dev/null +++ b/src/dirs @@ -0,0 +1,3 @@ +DIRS= \ + NetPerfDir \ + NetServerDir \ No newline at end of file diff --git a/src/hist.h b/src/hist.h new file mode 100644 index 0000000..b2ed22b --- /dev/null +++ b/src/hist.h @@ -0,0 +1,116 @@ +#if TIME_WITH_SYS_TIME +# include +# include +#else +# if HAVE_SYS_TIME_H +# include +# else +# include +# endif +#endif + +/* hist.h + + Given a time difference in microseconds, increment one of 61 + different buckets: + + 0 - 9 in increments of 1 usec + 0 - 9 in increments of 10 usecs + 0 - 9 in increments of 100 usecs + 0 - 9 in increments of 1 msec + 0 - 9 in increments of 10 msecs + 0 - 9 in increments of 100 msecs + 0 - 9 in increments of 1 sec + 0 - 9 in increments of 10 sec + > 100 secs + + This will allow any time to be recorded to within an accuracy of + 10%, and provides a compact representation for capturing the + distribution of a large number of time differences (e.g. + request-response latencies). + + Colin Low 10/6/93 + Rick Jones 2004-06-15 - extend to 1 and 10 usec +*/ +#ifndef _HIST_INCLUDED +#define _HIST_INCLUDED + +#ifdef IRIX +#include +#endif /* IRIX */ + +#if defined(HAVE_GET_HRT) +#include "hrt.h" +#endif + +struct histogram_struct { + int unit_usec[10]; + int ten_usec[10]; + int hundred_usec[10]; + int unit_msec[10]; + int ten_msec[10]; + int hundred_msec[10]; + int unit_sec[10]; + int ten_sec[10]; + int ridiculous; + int total; +}; + +typedef struct histogram_struct *HIST; + +/* + HIST_new - return a new, cleared histogram data type +*/ + +HIST HIST_new(void); + +/* + HIST_clear - reset a histogram by clearing all totals to zero +*/ + +void HIST_clear(HIST h); + +/* + HIST_add - add a time difference to a histogram. Time should be in + microseconds. +*/ + +void HIST_add(register HIST h, int time_delta); + +/* + HIST_report - create an ASCII report on the contents of a histogram. + Currently printsto standard out +*/ + +void HIST_report(HIST h); + +/* + HIST_timestamp - take a timestamp suitable for use in a histogram. +*/ + +#ifdef HAVE_GETHRTIME +void HIST_timestamp(hrtime_t *timestamp); +#elif defined(HAVE_GET_HRT) +void HIST_timestamp(hrt_t *timestamp); +#elif defined(WIN32) +void HIST_timestamp(LARGE_INTEGER *timestamp); +#else +void HIST_timestamp(struct timeval *timestamp); +#endif + +/* + delta_micro - calculate the difference in microseconds between two + timestamps +*/ +#ifdef HAVE_GETHRTIME +int delta_micro(hrtime_t *begin, hrtime_t *end); +#elif defined(HAVE_GET_HRT) +int delta_micro(hrt_t *begin, hrt_t *end); +#elif defined(WIN32) +int delta_micro(LARGE_INTEGER *begin, LARGE_INTEGER *end); +#else +int delta_micro(struct timeval *begin, struct timeval *end); +#endif + +#endif + diff --git a/src/missing/Makefile.am b/src/missing/Makefile.am new file mode 100644 index 0000000..2972cca --- /dev/null +++ b/src/missing/Makefile.am @@ -0,0 +1,7 @@ +SUBDIRS = m4 + +if NEED_LIBCOMPAT +noinst_LIBRARIES = libcompat.a +libcompat_a_SOURCES = getaddrinfo.h +libcompat_a_LIBADD = $(LIBOBJS) $(ALLOCA) +endif diff --git a/src/missing/Makefile.in b/src/missing/Makefile.in new file mode 100644 index 0000000..3423b9a --- /dev/null +++ b/src/missing/Makefile.in @@ -0,0 +1,491 @@ +# Makefile.in generated by automake 1.7.9 from Makefile.am. +# @configure_input@ + +# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 +# Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +top_builddir = ../.. + +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +INSTALL = @INSTALL@ +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +host_triplet = @host@ +ACLOCAL = @ACLOCAL@ +AMDEP_FALSE = @AMDEP_FALSE@ +AMDEP_TRUE = @AMDEP_TRUE@ +AMTAR = @AMTAR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +GREP = @GREP@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +NEED_LIBCOMPAT_FALSE = @NEED_LIBCOMPAT_FALSE@ +NEED_LIBCOMPAT_TRUE = @NEED_LIBCOMPAT_TRUE@ +NETCPU_SOURCE = @NETCPU_SOURCE@ +NETDRVLKUP_SOURCE = @NETDRVLKUP_SOURCE@ +NETRTLKUP_SOURCE = @NETRTLKUP_SOURCE@ +NETSECLKUP_SOURCE = @NETSECLKUP_SOURCE@ +NETSLOTLKUP_SOURCE = @NETSLOTLKUP_SOURCE@ +NETSYSLKUP_SOURCE = @NETSYSLKUP_SOURCE@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +ac_ct_CC = @ac_ct_CC@ +am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ +am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +sysconfdir = @sysconfdir@ +target = @target@ +target_alias = @target_alias@ +target_cpu = @target_cpu@ +target_os = @target_os@ +target_vendor = @target_vendor@ +SUBDIRS = m4 + +@NEED_LIBCOMPAT_TRUE@noinst_LIBRARIES = libcompat.a +@NEED_LIBCOMPAT_TRUE@libcompat_a_SOURCES = getaddrinfo.h +@NEED_LIBCOMPAT_TRUE@libcompat_a_LIBADD = $(LIBOBJS) $(ALLOCA) +subdir = src/missing +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +LIBRARIES = $(noinst_LIBRARIES) + +libcompat_a_AR = $(AR) cru +@NEED_LIBCOMPAT_TRUE@libcompat_a_DEPENDENCIES = @LIBOBJS@ +@NEED_LIBCOMPAT_FALSE@libcompat_a_DEPENDENCIES = +am__libcompat_a_SOURCES_DIST = getaddrinfo.h +@NEED_LIBCOMPAT_TRUE@am_libcompat_a_OBJECTS = +libcompat_a_OBJECTS = $(am_libcompat_a_OBJECTS) + +DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +@AMDEP_TRUE@DEP_FILES = $(DEPDIR)/getaddrinfo.Po $(DEPDIR)/inet_ntop.Po +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +DIST_SOURCES = $(am__libcompat_a_SOURCES_DIST) + +RECURSIVE_TARGETS = info-recursive dvi-recursive pdf-recursive \ + ps-recursive install-info-recursive uninstall-info-recursive \ + all-recursive install-data-recursive install-exec-recursive \ + installdirs-recursive install-recursive uninstall-recursive \ + check-recursive installcheck-recursive +DIST_COMMON = $(srcdir)/Makefile.in Makefile.am getaddrinfo.c \ + inet_ntop.c +DIST_SUBDIRS = $(SUBDIRS) +SOURCES = $(libcompat_a_SOURCES) + +all: all-recursive + +.SUFFIXES: +.SUFFIXES: .c .o .obj +$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.ac $(ACLOCAL_M4) + cd $(top_srcdir) && \ + $(AUTOMAKE) --gnu src/missing/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe) + +AR = ar + +clean-noinstLIBRARIES: + -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) +libcompat.a: $(libcompat_a_OBJECTS) $(libcompat_a_DEPENDENCIES) + -rm -f libcompat.a + $(libcompat_a_AR) libcompat.a $(libcompat_a_OBJECTS) $(libcompat_a_LIBADD) + $(RANLIB) libcompat.a + +mostlyclean-compile: + -rm -f *.$(OBJEXT) core *.core + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/getaddrinfo.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/inet_ntop.Po@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \ +@am__fastdepCC_TRUE@ -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \ +@am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \ +@am__fastdepCC_TRUE@ fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `test -f '$<' || echo '$(srcdir)/'`$< + +.c.obj: +@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \ +@am__fastdepCC_TRUE@ -c -o $@ `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi`; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \ +@am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \ +@am__fastdepCC_TRUE@ fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi` +uninstall-info-am: + +# This directory's subdirectories are mostly independent; you can cd +# into them and run `make' without going through this Makefile. +# To change the values of `make' variables: instead of editing Makefiles, +# (1) if the variable is set in `config.status', edit `config.status' +# (which will cause the Makefiles to be regenerated when you run `make'); +# (2) otherwise, pass the desired values on the `make' command line. +$(RECURSIVE_TARGETS): + @set fnord $$MAKEFLAGS; amf=$$2; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +mostlyclean-recursive clean-recursive distclean-recursive \ +maintainer-clean-recursive: + @set fnord $$MAKEFLAGS; amf=$$2; \ + dot_seen=no; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + rev=''; for subdir in $$list; do \ + if test "$$subdir" = "."; then :; else \ + rev="$$subdir $$rev"; \ + fi; \ + done; \ + rev="$$rev ."; \ + target=`echo $@ | sed s/-recursive//`; \ + for subdir in $$rev; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ + done && test -z "$$fail" +tags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ + done +ctags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ + done + +ETAGS = etags +ETAGSFLAGS = + +CTAGS = ctags +CTAGSFLAGS = + +tags: TAGS + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + mkid -fID $$unique + +TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + if (etags --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + else \ + include_option=--include; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test -f $$subdir/TAGS && \ + tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(ETAGS_ARGS)$$tags$$unique" \ + || $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$tags $$unique + +ctags: CTAGS +CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(CTAGS_ARGS)$$tags$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$tags $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && cd $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) $$here + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) + +top_distdir = ../.. +distdir = $(top_distdir)/$(PACKAGE)-$(VERSION) + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ + list='$(DISTFILES)'; for file in $$list; do \ + case $$file in \ + $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ + $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ + esac; \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test "$$dir" != "$$file" && test "$$dir" != "."; then \ + dir="/$$dir"; \ + $(mkinstalldirs) "$(distdir)$$dir"; \ + else \ + dir=''; \ + fi; \ + if test -d $$d/$$file; then \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test -d $(distdir)/$$subdir \ + || mkdir $(distdir)/$$subdir \ + || exit 1; \ + (cd $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$(top_distdir)" \ + distdir=../$(distdir)/$$subdir \ + distdir) \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-recursive +all-am: Makefile $(LIBRARIES) +installdirs: installdirs-recursive +installdirs-am: + +install: install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-recursive +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -rm -f $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-recursive + +clean-am: clean-generic clean-noinstLIBRARIES mostlyclean-am + +distclean: distclean-recursive + -rm -rf $(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-recursive + +dvi-am: + +info: info-recursive + +info-am: + +install-data-am: + +install-exec-am: + +install-info: install-info-recursive + +install-man: + +installcheck-am: + +maintainer-clean: maintainer-clean-recursive + -rm -rf $(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-recursive + +mostlyclean-am: mostlyclean-compile mostlyclean-generic + +pdf: pdf-recursive + +pdf-am: + +ps: ps-recursive + +ps-am: + +uninstall-am: uninstall-info-am + +uninstall-info: uninstall-info-recursive + +.PHONY: $(RECURSIVE_TARGETS) CTAGS GTAGS all all-am check check-am clean \ + clean-generic clean-noinstLIBRARIES clean-recursive ctags \ + ctags-recursive distclean distclean-compile distclean-generic \ + distclean-recursive distclean-tags distdir dvi dvi-am \ + dvi-recursive info info-am info-recursive install install-am \ + install-data install-data-am install-data-recursive \ + install-exec install-exec-am install-exec-recursive \ + install-info install-info-am install-info-recursive install-man \ + install-recursive install-strip installcheck installcheck-am \ + installdirs installdirs-am installdirs-recursive \ + maintainer-clean maintainer-clean-generic \ + maintainer-clean-recursive mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-recursive pdf pdf-am \ + pdf-recursive ps ps-am ps-recursive tags tags-recursive \ + uninstall uninstall-am uninstall-info-am \ + uninstall-info-recursive uninstall-recursive + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/src/missing/getaddrinfo.c b/src/missing/getaddrinfo.c new file mode 100644 index 0000000..f6f2916 --- /dev/null +++ b/src/missing/getaddrinfo.c @@ -0,0 +1,605 @@ +/* + * Copyright (c) 2001, 02 Motoyuki Kasahara + * + * 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. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT 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 PROJECT 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. + */ + +/* + * This program provides getaddrinfo() and getnameinfo() described in + * RFC2133, 2553 and 3493. These functions are mainly used for IPv6 + * application to resolve hostname or address. + * + * This program is designed to be working on traditional IPv4 systems + * which don't have those functions. Therefore, this implementation + * supports IPv4 only. + * + * This program is useful for application which should support both IPv6 + * and traditional IPv4 systems. Use genuine getaddrinfo() and getnameinfo() + * provided by system if the system supports IPv6. Otherwise, use this + * implementation. + * + * This program is intended to be used in combination with GNU Autoconf. + * + * This program also provides freeaddrinfo() and gai_strerror(). + * + * To use this program in your application, insert the following lines to + * C source files after including `sys/types.h', `sys/socket.h' and + * `netdb.h'. `getaddrinfo.h' defines `struct addrinfo' and AI_, NI_, + * EAI_ macros. + * + * #ifndef HAVE_GETADDRINFO + * #include "getaddrinfo.h" + * #endif + * + * Restriction: + * getaddrinfo() and getnameinfo() of this program are NOT thread + * safe, unless the cpp macro ENABLE_PTHREAD is defined. + */ + +/* + * Add the following code to your configure.ac (or configure.in). + * AC_C_CONST + * AC_HEADER_STDC + * AC_CHECK_HEADERS(string.h memory.h stdlib.h) + * AC_CHECK_FUNCS(memcpy) + * AC_REPLACE_FUNCS(memset) + * AC_TYPE_SOCKLEN_T + * AC_TYPE_IN_PORT_T + * AC_DECL_H_ERRNO + * + * AC_CHECK_FUNCS(getaddrinfo getnameinfo) + * if test "$ac_cv_func_getaddrinfo$ac_cv_func_getnameinfo" != yesyes ; then + * LIBOBJS="$LIBOBJS getaddrinfo.$ac_objext" + * fi + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include + +#ifdef WIN32 +#include +#include +#ifdef DO_IPV6 +#include +#endif /* DO_IPV6 */ +#include +#else +#include +#endif + + +#include +#include +#include + +#if defined(STDC_HEADERS) || defined(HAVE_STRING_H) +#include +#if !defined(STDC_HEADERS) && defined(HAVE_MEMORY_H) +#include +#endif /* not STDC_HEADERS and HAVE_MEMORY_H */ +#else /* not STDC_HEADERS and not HAVE_STRING_H */ +#include +#endif /* not STDC_HEADERS and not HAVE_STRING_H */ + +#ifdef HAVE_STDLIB_H +#include +#endif + +#ifdef ENABLE_PTHREAD +#include +#endif + +#ifdef ENABLE_NLS +#include +#endif + +#ifndef HAVE_MEMCPY +#define memcpy(d, s, n) bcopy((s), (d), (n)) +#ifdef __STDC__ +void *memchr(const void *, int, size_t); +int memcmp(const void *, const void *, size_t); +void *memmove(void *, const void *, size_t); +void *memset(void *, int, size_t); +#else /* not __STDC__ */ +char *memchr(); +int memcmp(); +char *memmove(); +char *memset(); +#endif /* not __STDC__ */ +#endif /* not HAVE_MEMCPY */ + +#ifndef H_ERRNO_DECLARED +extern int h_errno; +#endif + +#include "getaddrinfo.h" + +#ifdef ENABLE_NLS +#define _(string) gettext(string) +#ifdef gettext_noop +#define N_(string) gettext_noop(string) +#else +#define N_(string) (string) +#endif +#else +#define gettext(string) (string) +#define _(string) (string) +#define N_(string) (string) +#endif + +/* + * Error messages for gai_strerror(). + */ +static char *eai_errlist[] = { + N_("Success"), + + /* EAI_ADDRFAMILY */ + N_("Address family for hostname not supported"), + + /* EAI_AGAIN */ + N_("Temporary failure in name resolution"), + + /* EAI_BADFLAGS */ + N_("Invalid value for ai_flags"), + + /* EAI_FAIL */ + N_("Non-recoverable failure in name resolution"), + + /* EAI_FAMILY */ + N_("ai_family not supported"), + + /* EAI_MEMORY */ + N_("Memory allocation failure"), + + /* EAI_NONAME */ + N_("hostname nor servname provided, or not known"), + + /* EAI_OVERFLOW */ + N_("An argument buffer overflowed"), + + /* EAI_SERVICE */ + N_("servname not supported for ai_socktype"), + + /* EAI_SOCKTYPE */ + N_("ai_socktype not supported"), + + /* EAI_SYSTEM */ + N_("System error returned in errno") +}; + +/* + * Default hints for getaddrinfo(). + */ +static struct addrinfo default_hints = { + 0, PF_UNSPEC, 0, 0, 0, NULL, NULL, NULL +}; + +/* + * Mutex. + */ +#ifdef ENABLE_PTHREAD +static pthread_mutex_t gai_mutex = PTHREAD_MUTEX_INITIALIZER; +#endif + +/* + * Declaration of static functions. + */ +#ifdef __STDC__ +static int is_integer(const char *); +static int is_address(const char *); +static int itoa_length(int); +#else +static int is_integer(); +static int is_address(); +static int itoa_length(); +#endif + +/* + * gai_strerror(). + */ +const char * +gai_strerror(ecode) + int ecode; +{ + if (ecode < 0 || ecode > EAI_SYSTEM) + return _("Unknown error"); + + return gettext(eai_errlist[ecode]); +} + +/* + * freeaddrinfo(). + */ +void +freeaddrinfo(ai) + struct addrinfo *ai; +{ + struct addrinfo *next_ai; + + while (ai != NULL) { + if (ai->ai_canonname != NULL) + free(ai->ai_canonname); + if (ai->ai_addr != NULL) + free(ai->ai_addr); + next_ai = ai->ai_next; + free(ai); + ai = next_ai; + } +} + +/* + * Return 1 if the string `s' represents an integer. + */ +static int +is_integer(s) + const char *s; +{ + if (*s == '-' || *s == '+') + s++; + if (*s < '0' || '9' < *s) + return 0; + + s++; + while ('0' <= *s && *s <= '9') + s++; + + return (*s == '\0'); +} + +/* + * Return 1 if the string `s' represents an IPv4 address. + * Unlike inet_addr(), it doesn't permit malformed nortation such + * as "192.168". + */ +static int +is_address(s) + const char *s; +{ + const static char delimiters[] = {'.', '.', '.', '\0'}; + int i, j; + int octet; + + for (i = 0; i < 4; i++) { + if (*s == '0' && *(s + 1) != delimiters[i]) + return 0; + for (j = 0, octet = 0; '0' <= *s && *s <= '9' && j < 3; s++, j++) + octet = octet * 10 + (*s - '0'); + if (j == 0 || octet > 255 || *s != delimiters[i]) + return 0; + s++; + } + + return 1; +} + +/* + * Calcurate length of the string `s', where `s' is set by + * sprintf(s, "%d", n). + */ +static int +itoa_length(n) + int n; +{ + int result = 1; + + if (n < 0) { + n = -n; + result++; + } + + while (n >= 10) { + result++; + n /= 10; + } + + return result; +} + +/* + * getaddrinfo(). + */ +int +getaddrinfo(nodename, servname, hints, res) + const char *nodename; + const char *servname; + const struct addrinfo *hints; + struct addrinfo **res; +{ + struct addrinfo *head_res = NULL; + struct addrinfo *tail_res = NULL; + struct addrinfo *new_res; + struct sockaddr_in *sa_in; + struct in_addr **addr_list; + struct in_addr *addr_list_buf[2]; + struct in_addr addr_buf; + struct in_addr **ap; + struct servent *servent; + struct hostent *hostent; + const char *canonname = NULL; + in_port_t port; + int saved_h_errno; + int result = 0; + +#ifdef ENABLE_PTHREAD + pthread_mutex_lock(&gai_mutex); +#endif + + saved_h_errno = h_errno; + + if (nodename == NULL && servname == NULL) { + result = EAI_NONAME; + goto end; + } + + if (hints != NULL) { + if (hints->ai_family != PF_INET && hints->ai_family != PF_UNSPEC) { + result = EAI_FAMILY; + goto end; + } + if (hints->ai_socktype != SOCK_DGRAM + && hints->ai_socktype != SOCK_STREAM + && hints->ai_socktype != 0) { + result = EAI_SOCKTYPE; + goto end; + } + } else { + hints = &default_hints; + } + + if (servname != NULL) { + if (is_integer(servname)) + port = htons(atoi(servname)); + else { + if (hints->ai_flags & AI_NUMERICSERV) { + result = EAI_NONAME; + goto end; + } + + if (hints->ai_socktype == SOCK_DGRAM) + servent = getservbyname(servname, "udp"); + else if (hints->ai_socktype == SOCK_STREAM) + servent = getservbyname(servname, "tcp"); + else if (hints->ai_socktype == 0) + servent = getservbyname(servname, "tcp"); + else { + result = EAI_SOCKTYPE; + goto end; + } + + if (servent == NULL) { + result = EAI_SERVICE; + goto end; + } + port = servent->s_port; + } + } else { + port = htons(0); + } + + if (nodename != NULL) { + if (is_address(nodename)) { + addr_buf.s_addr = inet_addr(nodename); + addr_list_buf[0] = &addr_buf; + addr_list_buf[1] = NULL; + addr_list = addr_list_buf; + + if (hints->ai_flags & AI_CANONNAME + && !(hints->ai_flags & AI_NUMERICHOST)) { + hostent = gethostbyaddr((char *)&addr_buf, + sizeof(struct in_addr), AF_INET); + if (hostent != NULL) + canonname = hostent->h_name; + else + canonname = nodename; + } + } else { + if (hints->ai_flags & AI_NUMERICHOST) { + result = EAI_NONAME; + goto end; + } + + hostent = gethostbyname(nodename); + if (hostent == NULL) { + switch (h_errno) { + case HOST_NOT_FOUND: + case NO_DATA: + result = EAI_NONAME; + goto end; + case TRY_AGAIN: + result = EAI_AGAIN; + goto end; + default: + result = EAI_FAIL; + goto end; + } + } + addr_list = (struct in_addr **)hostent->h_addr_list; + + if (hints->ai_flags & AI_CANONNAME) + canonname = hostent->h_name; + } + } else { + if (hints->ai_flags & AI_PASSIVE) + addr_buf.s_addr = htonl(INADDR_ANY); + else + addr_buf.s_addr = htonl(0x7F000001); + addr_list_buf[0] = &addr_buf; + addr_list_buf[1] = NULL; + addr_list = addr_list_buf; + } + + for (ap = addr_list; *ap != NULL; ap++) { + new_res = (struct addrinfo *)malloc(sizeof(struct addrinfo)); + if (new_res == NULL) { + if (head_res != NULL) + freeaddrinfo(head_res); + result = EAI_MEMORY; + goto end; + } + + new_res->ai_family = PF_INET; + new_res->ai_socktype = hints->ai_socktype; + new_res->ai_protocol = hints->ai_protocol; + new_res->ai_addr = NULL; + new_res->ai_addrlen = sizeof(struct sockaddr_in); + new_res->ai_canonname = NULL; + new_res->ai_next = NULL; + + new_res->ai_addr = (struct sockaddr *) + malloc(sizeof(struct sockaddr_in)); + if (new_res->ai_addr == NULL) { + free(new_res); + if (head_res != NULL) + freeaddrinfo(head_res); + result = EAI_MEMORY; + goto end; + } + + sa_in = (struct sockaddr_in *)new_res->ai_addr; + memset(sa_in, 0, sizeof(struct sockaddr_in)); + sa_in->sin_family = PF_INET; + sa_in->sin_port = port; + memcpy(&sa_in->sin_addr, *ap, sizeof(struct in_addr)); + + if (head_res == NULL) + head_res = new_res; + else + tail_res->ai_next = new_res; + tail_res = new_res; + } + + if (canonname != NULL && head_res != NULL) { + head_res->ai_canonname = (char *)malloc(strlen(canonname) + 1); + if (head_res->ai_canonname != NULL) + strcpy(head_res->ai_canonname, canonname); + } + + *res = head_res; + + end: + h_errno = saved_h_errno; +#ifdef ENABLE_PTHREAD + pthread_mutex_unlock(&gai_mutex); +#endif + return result; +} + +/* + * getnameinfo(). + */ +int +getnameinfo(sa, salen, node, nodelen, serv, servlen, flags) + const struct sockaddr *sa; + socklen_t salen; + char *node; + socklen_t nodelen; + char *serv; + socklen_t servlen; + int flags; +{ + const struct sockaddr_in *sa_in = (const struct sockaddr_in *)sa; + struct hostent *hostent; + struct servent *servent; + char *ntoa_address; + int saved_h_errno; + int result = 0; + +#ifdef ENABLE_PTHREAD + pthread_mutex_lock(&gai_mutex); +#endif + + saved_h_errno = h_errno; + + if (sa_in->sin_family != PF_INET) { + result = EAI_FAMILY; + goto end; + } else if (node == NULL && serv == NULL) { + result = EAI_NONAME; + goto end; + } + + if (serv != NULL && servlen > 0) { + if (flags & NI_NUMERICSERV) + servent = NULL; + else if (flags & NI_DGRAM) + servent = getservbyport(sa_in->sin_port, "udp"); + else + servent = getservbyport(sa_in->sin_port, "tcp"); + + if (servent != NULL) { + if (servlen <= strlen(servent->s_name)) { + result = EAI_OVERFLOW; + goto end; + } + strcpy(serv, servent->s_name); + } else { + if (servlen <= itoa_length(ntohs(sa_in->sin_port))) { + result = EAI_OVERFLOW; + goto end; + } + sprintf(serv, "%d", ntohs(sa_in->sin_port)); + } + } + + if (node != NULL && nodelen > 0) { + if (flags & NI_NUMERICHOST) + hostent = NULL; + else { + hostent = gethostbyaddr((char *)&sa_in->sin_addr, + sizeof(struct in_addr), AF_INET); + } + if (hostent != NULL) { + if (nodelen <= strlen(hostent->h_name)) { + result = EAI_OVERFLOW; + goto end; + } + strcpy(node, hostent->h_name); + } else { + if (flags & NI_NAMEREQD) { + result = EAI_NONAME; + goto end; + } + ntoa_address = inet_ntoa(sa_in->sin_addr); + if (nodelen <= strlen(ntoa_address)) { + result = EAI_OVERFLOW; + goto end; + } + strcpy(node, ntoa_address); + } + + } + + end: + h_errno = saved_h_errno; +#ifdef ENABLE_PTHREAD + pthread_mutex_unlock(&gai_mutex); +#endif + return result; +} + diff --git a/src/missing/getaddrinfo.h b/src/missing/getaddrinfo.h new file mode 100644 index 0000000..f965a8b --- /dev/null +++ b/src/missing/getaddrinfo.h @@ -0,0 +1,238 @@ +/* + * Copyright (c) 2001, 02 Motoyuki Kasahara + * + * 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. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT 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 PROJECT 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 GETADDRINFO_H +#define GETADDRINFO_H + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#ifdef WIN32 +#include +#include +#ifdef DO_IPV6 +#include +#endif /* DO_IPV6 */ +#include +#else +#include +#include +#endif + + +/********************************************************************/ +/* + * Undefine all the macros. + * might defines some of them. + */ +#ifdef EAI_ADDRFAMILY +#undef EAI_ADDRFAMILY +#endif +#ifdef EAI_AGAIN +#undef EAI_AGAIN +#endif +#ifdef EAI_BADFLAGS +#undef EAI_BADFLAGS +#endif +#ifdef EAI_FAIL +#undef EAI_FAIL +#endif +#ifdef EAI_FAMILY +#undef EAI_FAMILY +#endif +#ifdef EAI_MEMORY +#undef EAI_MEMORY +#endif +#ifdef EAI_NONAME +#undef EAI_NONAME +#endif +#ifdef EAI_OVERFLOW +#undef EAI_OVERFLOW +#endif +#ifdef EAI_SERVICE +#undef EAI_SERVICE +#endif +#ifdef EAI_SOCKTYPE +#undef EAI_SOCKTYPE +#endif +#ifdef EAI_SYSTEM +#undef EAI_SYSTEM +#endif + +#ifdef AI_PASSIVE +#undef AI_PASSIVE +#endif +#ifdef AI_CANONNAME +#undef AI_CANONNAME +#endif +#ifdef AI_NUMERICHOST +#undef AI_NUMERICHOST +#endif +#ifdef AI_NUMERICSERV +#undef AI_NUMERICSERV +#endif +#ifdef AI_V4MAPPED +#undef AI_V4MAPPED +#endif +#ifdef AI_ALL +#undef AI_ALL +#endif +#ifdef AI_ADDRCONFIG +#undef AI_ADDRCONFIG +#endif +#ifdef AI_DEFAULT +#undef AI_DEFAULT +#endif + +#ifdef NI_NOFQDN +#undef NI_NOFQDN +#endif +#ifdef NI_NUMERICHOST +#undef NI_NUMERICHOST +#endif +#ifdef NI_NAMEREQD +#undef NI_NAMEREQD +#endif +#ifdef NI_NUMERICSERV +#undef NI_NUMERICSERV +#endif +#ifdef NI_NUMERICSCOPE +#undef NI_NUMERICSCOPE +#endif + +#ifdef NI_DGRAM +#undef NI_DGRAM +#endif +#ifdef NI_MAXHOST +#undef NI_MAXHOST +#endif +#ifdef NI_MAXSERV +#undef NI_MAXSERV +#endif + +/* + * Fake struct and function names. + * might declares all or some of them. + */ +#if defined(HAVE_GETADDRINFO) || defined(HAVE_GETNAMEINFO) +#define addrinfo my_addrinfo +#define gai_strerror my_gai_strerror +#define freeaddrinfo my_freeaddrinfo +#define getaddrinfo my_getaddrinfo +#define getnameinfo my_getnameinfo +#endif + +/********************************************************************/ +/* + * Error codes. + */ +#define EAI_ADDRFAMILY 1 +#define EAI_AGAIN 2 +#define EAI_BADFLAGS 3 +#define EAI_FAIL 4 +#define EAI_FAMILY 5 +#define EAI_MEMORY 6 +#define EAI_NONAME 7 +#define EAI_OVERFLOW 8 +#define EAI_SERVICE 9 +#define EAI_SOCKTYPE 10 +#define EAI_SYSTEM 11 + +/* + * Flags for getaddrinfo(). + */ +#define AI_ADDRCONFIG 0x0001 +#define AI_ALL 0x0002 +#define AI_CANONNAME 0x0004 +#define AI_NUMERICHOST 0x0008 +#define AI_NUMERICSERV 0x0010 +#define AI_PASSIVE 0x0020 +#define AI_V4MAPPED 0x0040 +#define AI_DEFAULT (AI_V4MAPPED | AI_ADDRCONFIG) + +/* + * Flags for getnameinfo(). + */ +#define NI_DGRAM 0x0001 +#define NI_NAMEREQD 0x0002 +#define NI_NOFQDN 0x0004 +#define NI_NUMERICHOST 0x0008 +#define NI_NUMERICSCOPE 0x0010 +#define NI_NUMERICSERV 0x0020 + +/* + * Maximum length of FQDN and servie name for getnameinfo(). + */ +#define NI_MAXHOST 1025 +#define NI_MAXSERV 32 + +/* + * Address families and Protocol families. + */ +#ifndef AF_UNSPEC +#define AF_UNSPEC AF_INET +#endif +#ifndef PF_UNSPEC +#define PF_UNSPEC PF_INET +#endif + +/* + * struct addrinfo. + */ +struct addrinfo { + int ai_flags; + int ai_family; + int ai_socktype; + int ai_protocol; + socklen_t ai_addrlen; + char *ai_canonname; + struct sockaddr *ai_addr; + struct addrinfo *ai_next; +}; + +/* + * Functions. + */ +#ifdef __STDC__ +const char *gai_strerror(int); +void freeaddrinfo(struct addrinfo *); +int getaddrinfo(const char *, const char *, const struct addrinfo *, + struct addrinfo **); +int getnameinfo(const struct sockaddr *, socklen_t, char *, + socklen_t, char *, socklen_t, int); +#else +const char *gai_strerror(); +void freeaddrinfo(); +int getaddrinfo(); +int getnameinfo(); +#endif + +#endif /* not GETADDRINFO_H */ diff --git a/src/missing/inet_ntop.c b/src/missing/inet_ntop.c new file mode 100644 index 0000000..77a4455 --- /dev/null +++ b/src/missing/inet_ntop.c @@ -0,0 +1,140 @@ +/* + * Copyright (c) 1999 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * 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. + * + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the Kungliga Tekniska + * Högskolan and its contributors. + * + * 4. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE 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 INSTITUTE 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. + */ + +/* $Id: inet_ntop.c,v 1.7 2003/11/16 09:36:50 guy Exp $ */ + +#ifndef lint +static const char rcsid[] = + "@(#) $Header: /tcpdump/master/tcpdump/missing/inet_ntop.c,v 1.7 2003/11/16 09:36:50 guy Exp $"; +#endif + +/* we aren't tcpdump :) */ +#ifdef notdef +#include +#endif + +#include +#include + +#ifndef WIN32 +#include +#include +#include + +#else /* WIN32 */ +#include +#include +#ifdef DO_IPV6 +#include +#endif /* DO_IPV6 */ +#include + +/* The below are copied from netlib.h */ +#ifdef errno +/* delete the one from stdlib.h */ +/*#define errno (*_errno()) */ +#undef errno +#endif +#define errno GetLastError() +#define Set_errno(num) SetLastError((num)) + +/* INVALID_SOCKET == INVALID_HANDLE_VALUE == (unsigned int)(~0) */ +/* SOCKET_ERROR == -1 */ +#define ENOTSOCK WSAENOTSOCK +#define EINTR WSAEINTR +#define ENOBUFS WSAENOBUFS +#define EWOULDBLOCK WSAEWOULDBLOCK +#define EAFNOSUPPORT WSAEAFNOSUPPORT +/* from public\sdk\inc\crt\errno.h */ +#define ENOSPC 28 +#endif /* WIN32 */ + +/* + * + */ + +#ifndef INET_ADDRSTRLEN +#define INET_ADDRSTRLEN 16 +#endif + +static const char * +inet_ntop_v4 (const void *src, char *dst, size_t size) +{ + const char digits[] = "0123456789"; + int i; + struct in_addr *addr = (struct in_addr *)src; + u_long a = ntohl(addr->s_addr); + const char *orig_dst = dst; + + if (size < INET_ADDRSTRLEN) { + Set_errno(ENOSPC); + return NULL; + } + for (i = 0; i < 4; ++i) { + int n = (a >> (24 - i * 8)) & 0xFF; + int non_zerop = 0; + + if (non_zerop || n / 100 > 0) { + *dst++ = digits[n / 100]; + n %= 100; + non_zerop = 1; + } + if (non_zerop || n / 10 > 0) { + *dst++ = digits[n / 10]; + n %= 10; + non_zerop = 1; + } + *dst++ = digits[n]; + if (i != 3) + *dst++ = '.'; + } + *dst++ = '\0'; + return orig_dst; +} + +const char * +inet_ntop(int af, const void *src, char *dst, size_t size) +{ + switch (af) { + case AF_INET : + return inet_ntop_v4 (src, dst, size); + default : + Set_errno(EAFNOSUPPORT); + return NULL; + } +} diff --git a/src/missing/m4/Makefile.am b/src/missing/m4/Makefile.am new file mode 100644 index 0000000..7bcfad9 --- /dev/null +++ b/src/missing/m4/Makefile.am @@ -0,0 +1 @@ +EXTRA_DIST = *.m4 diff --git a/src/missing/m4/Makefile.in b/src/missing/m4/Makefile.in new file mode 100644 index 0000000..c621e5d --- /dev/null +++ b/src/missing/m4/Makefile.in @@ -0,0 +1,274 @@ +# Makefile.in generated by automake 1.7.9 from Makefile.am. +# @configure_input@ + +# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 +# Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +top_builddir = ../../.. + +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +INSTALL = @INSTALL@ +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +host_triplet = @host@ +ACLOCAL = @ACLOCAL@ +AMDEP_FALSE = @AMDEP_FALSE@ +AMDEP_TRUE = @AMDEP_TRUE@ +AMTAR = @AMTAR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +GREP = @GREP@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +NEED_LIBCOMPAT_FALSE = @NEED_LIBCOMPAT_FALSE@ +NEED_LIBCOMPAT_TRUE = @NEED_LIBCOMPAT_TRUE@ +NETCPU_SOURCE = @NETCPU_SOURCE@ +NETDRVLKUP_SOURCE = @NETDRVLKUP_SOURCE@ +NETRTLKUP_SOURCE = @NETRTLKUP_SOURCE@ +NETSECLKUP_SOURCE = @NETSECLKUP_SOURCE@ +NETSLOTLKUP_SOURCE = @NETSLOTLKUP_SOURCE@ +NETSYSLKUP_SOURCE = @NETSYSLKUP_SOURCE@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +ac_ct_CC = @ac_ct_CC@ +am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ +am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +sysconfdir = @sysconfdir@ +target = @target@ +target_alias = @target_alias@ +target_cpu = @target_cpu@ +target_os = @target_os@ +target_vendor = @target_vendor@ +EXTRA_DIST = *.m4 +subdir = src/missing/m4 +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +DIST_SOURCES = +DIST_COMMON = $(srcdir)/Makefile.in Makefile.am +all: all-am + +.SUFFIXES: +$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.ac $(ACLOCAL_M4) + cd $(top_srcdir) && \ + $(AUTOMAKE) --gnu src/missing/m4/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe) +uninstall-info-am: +tags: TAGS +TAGS: + +ctags: CTAGS +CTAGS: + +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) + +top_distdir = ../../.. +distdir = $(top_distdir)/$(PACKAGE)-$(VERSION) + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ + list='$(DISTFILES)'; for file in $$list; do \ + case $$file in \ + $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ + $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ + esac; \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test "$$dir" != "$$file" && test "$$dir" != "."; then \ + dir="/$$dir"; \ + $(mkinstalldirs) "$(distdir)$$dir"; \ + else \ + dir=''; \ + fi; \ + if test -d $$d/$$file; then \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile + +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -rm -f $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic mostlyclean-am + +distclean: distclean-am + -rm -f Makefile +distclean-am: clean-am distclean-generic + +dvi: dvi-am + +dvi-am: + +info: info-am + +info-am: + +install-data-am: + +install-exec-am: + +install-info: install-info-am + +install-man: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-generic + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-info-am + +.PHONY: all all-am check check-am clean clean-generic distclean \ + distclean-generic distdir dvi dvi-am info info-am install \ + install-am install-data install-data-am install-exec \ + install-exec-am install-info install-info-am install-man \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-generic pdf pdf-am ps ps-am uninstall uninstall-am \ + uninstall-info-am + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/src/missing/m4/herrno.m4 b/src/missing/m4/herrno.m4 new file mode 100644 index 0000000..f0c0d9b --- /dev/null +++ b/src/missing/m4/herrno.m4 @@ -0,0 +1,41 @@ +dnl * +dnl * Copyright (c) 2001 Motoyuki Kasahara +dnl * +dnl * Redistribution and use in source and binary forms, with or without +dnl * modification, are permitted provided that the following conditions +dnl * are met: +dnl * 1. Redistributions of source code must retain the above copyright +dnl * notice, this list of conditions and the following disclaimer. +dnl * 2. Redistributions in binary form must reproduce the above copyright +dnl * notice, this list of conditions and the following disclaimer in the +dnl * documentation and/or other materials provided with the distribution. +dnl * 3. Neither the name of the project nor the names of its contributors +dnl * may be used to endorse or promote products derived from this software +dnl * without specific prior written permission. +dnl * +dnl * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND +dnl * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +dnl * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +dnl * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORSBE +dnl * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +dnl * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +dnl * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +dnl * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +dnl * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +dnl * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +dnl * THE POSSIBILITY OF SUCH DAMAGE. +dnl * + +dnl * +dnl * Check for h_errno. +dnl * +AC_DEFUN([AC_DECL_H_ERRNO], +[AC_CACHE_CHECK(for h_errno declaration in netdb.h, ac_cv_decl_h_errno, +[AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#include ]], [[ +h_errno = 0; +]])],[ac_cv_decl_h_errno=yes],[ac_cv_decl_h_errno=no])]) +if test "$ac_cv_decl_h_errno" = yes; then + AC_DEFINE(H_ERRNO_DECLARED, 1, +[Define to 1 if `h_errno' is declared by ]) +fi]) diff --git a/src/missing/m4/in6addr.m4 b/src/missing/m4/in6addr.m4 new file mode 100644 index 0000000..fd6e82f --- /dev/null +++ b/src/missing/m4/in6addr.m4 @@ -0,0 +1,89 @@ +dnl * +dnl * Copyright (c) 2001 Motoyuki Kasahara +dnl * +dnl * Redistribution and use in source and binary forms, with or without +dnl * modification, are permitted provided that the following conditions +dnl * are met: +dnl * 1. Redistributions of source code must retain the above copyright +dnl * notice, this list of conditions and the following disclaimer. +dnl * 2. Redistributions in binary form must reproduce the above copyright +dnl * notice, this list of conditions and the following disclaimer in the +dnl * documentation and/or other materials provided with the distribution. +dnl * 3. Neither the name of the project nor the names of its contributors +dnl * may be used to endorse or promote products derived from this software +dnl * without specific prior written permission. +dnl * +dnl * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND +dnl * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +dnl * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +dnl * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORSBE +dnl * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +dnl * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +dnl * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +dnl * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +dnl * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +dnl * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +dnl * THE POSSIBILITY OF SUCH DAMAGE. +dnl * + +dnl * +dnl * Check for struct in6_addr +dnl * +AC_DEFUN([AC_STRUCT_IN6_ADDR], +[AC_CACHE_CHECK(for struct in6_addr, ac_cv_struct_in6_addr, +[AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#include +#include +#include ]], [[ +struct in6_addr address; +]])],[ac_cv_struct_in6_addr=yes],[ac_cv_struct_in6_addr=no])]) +if test "$ac_cv_struct_in6_addr" = yes; then + AC_DEFINE(HAVE_STRUCT_IN6_ADDR, 1, +[Define to 1 if defines `struct in6_addr']) +fi]) + +dnl * +dnl * Check for in6addr_any. +dnl * +AC_DEFUN([AC_DECL_IN6ADDR_ANY], +[AC_REQUIRE([AC_STRUCT_IN6_ADDR]) +if test $ac_cv_struct_in6_addr = no; then + ac_cv_decl_in6addr_any=no +else + AC_CACHE_CHECK(for in6addr_any declaration in netinet/in.h, + ac_cv_decl_in6addr_any, + [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#include +#include +#include ]], [[ +unsigned char *address; +address = (char *)&in6addr_any; +]])],[ac_cv_decl_in6addr_any=yes],[ac_cv_decl_in6addr_any=no])]) + if test "$ac_cv_decl_in6addr_any" = yes; then + AC_DEFINE(IN6ADDR_ANY_DECLARED, 1, +[Define to 1 if `in6addr_any' is declared by ]) + fi +fi]) + +dnl * +dnl * Check for in6addr_loopback. +dnl * +AC_DEFUN([AC_DECL_IN6ADDR_LOOPBACK], +[AC_REQUIRE([AC_STRUCT_IN6_ADDR]) +if test $ac_cv_struct_in6_addr = no; then + ac_cv_decl_in6addr_loopback=no +else + AC_CACHE_CHECK(for in6addr_loopback declaration in netinet/in.h, + ac_cv_decl_in6addr_loopback, + [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#include +#include +#include ]], [[ +unsigned char *address; +address = (char *)&in6addr_loopback; +]])],[ac_cv_decl_in6addr_loopback=yes],[ac_cv_decl_in6addr_loopback=no])]) + if test "$ac_cv_decl_in6addr_loopback" = yes; then + AC_DEFINE(IN6ADDR_LOOPBACK_DECLARED, 1, +[Define to 1 if `in6addr_loopback' is declared by ]) + fi +fi]) diff --git a/src/missing/m4/salen.m4 b/src/missing/m4/salen.m4 new file mode 100644 index 0000000..6e858da --- /dev/null +++ b/src/missing/m4/salen.m4 @@ -0,0 +1,32 @@ +dnl Copyright (c) 1995, 1996, 1997, 1998 +dnl tising materials mentioning +dnl dnl features or use of this software display the following acknowledgement: +dnl dnl ``This product includes software developed by the University of California, +dnl dnl Lawrence Berkeley Laboratory and its contributors.'' Neither the name of +dnl dnl the University nor the names of its contributors may be used to endorse +dnl dnl or promote products derived from this software without specific prior +dnl dnl written permission. +dnl dnl THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED +dnl dnl WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF +dnl dnl MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +dnl dnl +dnl dnl LBL autoconf macros +dnl dnl +dnl +dnl +dnl Checks to see if the sockaddr struct has the 4.4 BSD sa_len member +dnl borrowed from LBL libpcap +AC_DEFUN(AC_CHECK_SA_LEN, [ + AC_MSG_CHECKING(if sockaddr struct has sa_len member) + AC_CACHE_VAL($1, + AC_TRY_COMPILE([ +# include +# include ], + [u_int i = sizeof(((struct sockaddr *)0)->sa_len)], + $1=yes, + $1=no)) + AC_MSG_RESULT($$1) + if test $$1 = yes ; then + AC_DEFINE([HAVE_SOCKADDR_SA_LEN],1,[Define if struct sockaddr has the sa_len member]) + fi +]) diff --git a/src/missing/m4/sockaddrin6.m4 b/src/missing/m4/sockaddrin6.m4 new file mode 100644 index 0000000..c4270f3 --- /dev/null +++ b/src/missing/m4/sockaddrin6.m4 @@ -0,0 +1,60 @@ +dnl * +dnl * Copyright (c) 2001 Motoyuki Kasahara +dnl * +dnl * Redistribution and use in source and binary forms, with or without +dnl * modification, are permitted provided that the following conditions +dnl * are met: +dnl * 1. Redistributions of source code must retain the above copyright +dnl * notice, this list of conditions and the following disclaimer. +dnl * 2. Redistributions in binary form must reproduce the above copyright +dnl * notice, this list of conditions and the following disclaimer in the +dnl * documentation and/or other materials provided with the distribution. +dnl * 3. Neither the name of the project nor the names of its contributors +dnl * may be used to endorse or promote products derived from this software +dnl * without specific prior written permission. +dnl * +dnl * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND +dnl * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +dnl * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +dnl * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORSBE +dnl * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +dnl * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +dnl * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +dnl * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +dnl * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +dnl * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +dnl * THE POSSIBILITY OF SUCH DAMAGE. +dnl * + +dnl * +dnl * Check for struct sockaddr_in6 +dnl * +AC_DEFUN([AC_STRUCT_SOCKADDR_IN6], +[AC_CACHE_CHECK(for struct sockaddr_in6, ac_cv_struct_sockaddr_in6, +[AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#include +#include +#include ]], [[ +struct sockaddr_in6 address; +]])],[ac_cv_struct_sockaddr_in6=yes],[ac_cv_struct_sockaddr_in6=no])]) +if test "$ac_cv_struct_sockaddr_in6" = yes; then + AC_DEFINE(HAVE_STRUCT_SOCKADDR_IN6, 1, +[Define to 1 if defines `struct sockaddr_in6']) +fi]) + +dnl * +dnl * Check for struct sockaddr_storage +dnl * +AC_DEFUN([AC_STRUCT_SOCKADDR_STORAGE], +[AC_CACHE_CHECK(for struct sockaddr_storage, ac_cv_struct_sockaddr_storage, +[AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#include +#include +#include ]], [[ +struct sockaddr_storage address; +]])],[ac_cv_struct_sockaddr_storage=yes],[ac_cv_struct_sockaddr_storage=no])]) +if test "$ac_cv_struct_sockaddr_storage" = yes; then + AC_DEFINE(HAVE_STRUCT_SOCKADDR_STORAGE, 1, +[Define to 1 if defines `struct sockaddr_storage']) +fi]) + diff --git a/src/missing/m4/sockinttypes.m4 b/src/missing/m4/sockinttypes.m4 new file mode 100644 index 0000000..6d94063 --- /dev/null +++ b/src/missing/m4/sockinttypes.m4 @@ -0,0 +1,154 @@ +dnl * +dnl * Copyright (c) 2001, 2003 Motoyuki Kasahara +dnl * +dnl * Redistribution and use in source and binary forms, with or without +dnl * modification, are permitted provided that the following conditions +dnl * are met: +dnl * 1. Redistributions of source code must retain the above copyright +dnl * notice, this list of conditions and the following disclaimer. +dnl * 2. Redistributions in binary form must reproduce the above copyright +dnl * notice, this list of conditions and the following disclaimer in the +dnl * documentation and/or other materials provided with the distribution. +dnl * 3. Neither the name of the project nor the names of its contributors +dnl * may be used to endorse or promote products derived from this software +dnl * without specific prior written permission. +dnl * +dnl * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND +dnl * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +dnl * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +dnl * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORSBE +dnl * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +dnl * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +dnl * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +dnl * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +dnl * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +dnl * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +dnl * THE POSSIBILITY OF SUCH DAMAGE. +dnl * + +dnl * +dnl * Check for socklen_t. +dnl * +AC_DEFUN([AC_TYPE_SOCKLEN_T], +[AC_CACHE_CHECK([for socklen_t], ac_cv_type_socklen_t, +[AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#include +#include ]], [[ +socklen_t socklen; +]])],[ac_cv_type_socklen_t=yes],[ac_cv_type_socklen_t=no])]) +if test "$ac_cv_type_socklen_t" != yes; then + AC_DEFINE(socklen_t, int, +[Define to `int' if or does not define.]) +fi]) + +dnl * +dnl * Check for in_port_t. +dnl * +AC_DEFUN([AC_TYPE_IN_PORT_T], +[AC_CACHE_CHECK([for in_port_t], ac_cv_type_in_port_t, +[AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#include +#include +#include ]], [[ +in_port_t in_port; +]])],[ac_cv_type_in_port_t=yes],[ac_cv_type_in_port_t=no])]) +if test "$ac_cv_type_in_port_t" != yes; then + ac_cv_sin_port_size=unknown + AC_RUN_IFELSE([AC_LANG_SOURCE([[ + #include + #include + #include + int main() { + struct sockaddr_in addr; + return (sizeof(addr.sin_port) == sizeof(long)) ? 0 : 1; + } + ]])],[ac_cv_sin_port_size=long],[],[]) + AC_RUN_IFELSE([AC_LANG_SOURCE([[ + #include + #include + #include + int main() { + struct sockaddr_in addr; + return (sizeof(addr.sin_port) == sizeof(int)) ? 0 : 1; + } + ]])],[ac_cv_sin_port_size=int],[],[]) + AC_RUN_IFELSE([AC_LANG_SOURCE([[ + #include + #include + #include + int main() { + struct sockaddr_in addr; + return (sizeof(addr.sin_port) == sizeof(short)) ? 0 : 1; + } + ]])],[ac_cv_sin_port_size=short],[],[]) + AC_RUN_IFELSE([AC_LANG_SOURCE([[ + #include + #include + #include + int main() { + struct sockaddr_in addr; + return (sizeof(addr.sin_port) == sizeof(char)) ? 0 : 1; + } + ]])],[ac_cv_sin_port_size=char],[],[]) + if test "$ac_cv_sin_port_size" = unknown; then + AC_MSG_ERROR([Failed to get size of sin_port in struct sockaddr_in.]) + fi + AC_DEFINE_UNQUOTED(in_port_t, unsigned $ac_cv_sin_port_size, +[Define to `unsigned char', `unsigned short', `unsigned int' or +`unsigned long' according with size of `sin_port' in `struct sockaddr_in', +if , or does not define +`in_port_t'.]) +fi]) + +dnl * +dnl * Check for sa_family_t. +dnl * +AC_DEFUN([AC_TYPE_SA_FAMILY_T], +[AC_CACHE_CHECK([for sa_family_t], ac_cv_type_sa_family_t, +[AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#include +#include ]], [[ +sa_family_t sa_family; +]])],[ac_cv_type_sa_family_t=yes],[ac_cv_type_sa_family_t=no])]) +if test "$ac_cv_type_sa_family_t" != yes; then + ac_cv_sa_family_size=unknown + AC_RUN_IFELSE([AC_LANG_SOURCE([[ + #include + #include + int main() { + struct sockaddr addr; + return (sizeof(addr.sa_family) == sizeof(long)) ? 0 : 1; + } + ]])],[ac_cv_sa_family_size=long],[],[]) + AC_RUN_IFELSE([AC_LANG_SOURCE([[ + #include + #include + int main() { + struct sockaddr addr; + return (sizeof(addr.sa_family) == sizeof(int)) ? 0 : 1; + } + ]])],[ac_cv_sa_family_size=int],[],[]) + AC_RUN_IFELSE([AC_LANG_SOURCE([[ + #include + #include + int main() { + struct sockaddr addr; + return (sizeof(addr.sa_family) == sizeof(short)) ? 0 : 1; + } + ]])],[ac_cv_sa_family_size=short],[],[]) + AC_RUN_IFELSE([AC_LANG_SOURCE([[ + #include + #include + int main() { + struct sockaddr addr; + return (sizeof(addr.sa_family) == sizeof(char)) ? 0 : 1; + } + ]])],[ac_cv_sa_family_size=char],[],[]) + if test "$ac_cv_sa_family_size" = unknown; then + AC_MSG_ERROR([Failed to get size of sa_family in struct sockaddr.]) + fi + AC_DEFINE_UNQUOTED(sa_family_t, unsigned $ac_cv_sa_family_size, +[Define to `unsigned char', `unsigned short', `unsigned int' or +`unsigned long' according with size of `sa_family' in `struct sockaddr', +if or does not define `sa_family_t'.]) +fi]) diff --git a/src/missing/m4/socklent.m4 b/src/missing/m4/socklent.m4 new file mode 100644 index 0000000..6849925 --- /dev/null +++ b/src/missing/m4/socklent.m4 @@ -0,0 +1,81 @@ +dnl This comes from libcurl's acinclude.m4. it is not clear if this +dnl is original libcurl code, or other code, so we include the libcurl +dnl copyright here +dnl +dnl +dnl Copyright (c) 1996 - 2005, Daniel Stenberg, . +dnl +dnl All rights reserved. +dnl +dnl Permission to use, copy, modify, and distribute this software for any purpose +dnl with or without fee is hereby granted, provided that the above copyright +dnl notice and this permission notice appear in all copies. +dnl +dnl THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +dnl IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +dnl FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN +dnl NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +dnl DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +dnl OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE +dnl OR OTHER DEALINGS IN THE SOFTWARE. +dnl +dnl Except as contained in this notice, the name of a copyright holder shall not +dnl be used in advertising or otherwise to promote the sale, use or other dealings +dnl in this Software without prior written authorization of the copyright holder. + +dnl Check for socklen_t: historically on BSD it is an int, and in +dnl POSIX 1g it is a type of its own, but some platforms use different +dnl types for the argument to getsockopt, getpeername, etc. So we +dnl have to test to find something that will work. + +dnl Remove the AC_CHECK_TYPE - on HP-UX it would find a socklen_t, but the +dnl function prototypes for getsockopt et al will not actually use +dnl socklen_t args unless _XOPEN_SOURCE_EXTENDED is defined. so, the +dnl AC_CHECK_TYPE will find a socklen_t and think all is happiness and +dnl joy when you will really get warnings about mismatch types - type +dnl mismatches that would be possibly Bad (tm) in a 64-bit compile. +dnl raj 2005-05-11 this change may be redistributed at will + +dnl also, added "extern" to the "int getpeername" in an attempt to resolve +dnl an issue with this code under Solaris 2.9. this too may be +dnl redistributed at will + +AC_DEFUN([OLD_TYPE_SOCKLEN_T], +[ + AC_MSG_CHECKING([for socklen_t equivalent]) + AC_CACHE_VAL([curl_cv_socklen_t_equiv], + [ + # Systems have either "struct sockaddr *" or + # "void *" as the second argument to getpeername + curl_cv_socklen_t_equiv= + for arg2 in "struct sockaddr" void; do + for t in int size_t unsigned long "unsigned long" socklen_t; do + AC_TRY_COMPILE([ + #ifdef HAVE_SYS_TYPES_H + #include + #endif + #ifdef HAVE_SYS_SOCKET_H + #include + #endif + + extern int getpeername (int, $arg2 *, $t *); + ],[ + $t len; + getpeername(0,0,&len); + ],[ + curl_cv_socklen_t_equiv="$t" + break + ]) + done + done + + if test "x$curl_cv_socklen_t_equiv" = x; then + # take a wild guess + curl_cv_socklen_t_equiv="socklen_t" + AC_MSG_WARN([Cannot find a type to use in place of socklen_t, guessing socklen_t]) + fi + ]) + AC_MSG_RESULT($curl_cv_socklen_t_equiv) + AC_DEFINE_UNQUOTED(netperf_socklen_t, $curl_cv_socklen_t_equiv, + [type to use in place of socklen_t if not defined]) +]) diff --git a/src/missing/m4/type_socklen_t.m4 b/src/missing/m4/type_socklen_t.m4 new file mode 100644 index 0000000..349aad8 --- /dev/null +++ b/src/missing/m4/type_socklen_t.m4 @@ -0,0 +1,25 @@ +dnl @synopsis TYPE_SOCKLEN_T +dnl +dnl Check whether sys/socket.h defines type socklen_t. Please note that +dnl some systems require sys/types.h to be included before sys/socket.h +dnl can be compiled. +dnl +dnl @category Misc +dnl @author Lars Brinkhoff +dnl @version 2005-01-11 +dnl @license GPLWithACException + +AC_DEFUN([TYPE_SOCKLEN_T], +[AC_CACHE_CHECK([for socklen_t], ac_cv_type_socklen_t, +[ + AC_TRY_COMPILE( + [#include + #include ], + [socklen_t len = 42; return 0;], + ac_cv_type_socklen_t=yes, + ac_cv_type_socklen_t=no) +]) + if test $ac_cv_type_socklen_t != yes; then + AC_DEFINE(socklen_t, int, [Substitute for socklen_t]) + fi +]) diff --git a/src/net_uuid.c b/src/net_uuid.c new file mode 100644 index 0000000..2efd231 --- /dev/null +++ b/src/net_uuid.c @@ -0,0 +1,336 @@ +/* what follows is a somewhat stripped-down version of the sample + implementation of UUID generation from RFC 4122. */ + +/* +** Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc. +** Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & +** Digital Equipment Corporation, Maynard, Mass. +** Copyright (c) 1998 Microsoft. +** To anyone who acknowledges that this file is provided "AS IS" +** without any express or implied warranty: permission to use, copy, +** modify, and distribute this file for any purpose is hereby +** granted without fee, provided that the above copyright notices and +** this notice appears in all source code copies, and that none of +** the names of Open Software Foundation, Inc., Hewlett-Packard +** Company, Microsoft, or Digital Equipment Corporation be used in +** advertising or publicity pertaining to distribution of the software +** without specific, written prior permission. Neither Open Software +** Foundation, Inc., Hewlett-Packard Company, Microsoft, nor Digital +** Equipment Corporation makes any representations about the +** suitability of this software for any purpose. +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include + +/* set the following to the number of 100ns ticks of the actual + resolution of your system's clock */ +#define UUIDS_PER_TICK 1024 + +#ifdef WIN32 +#include +#else +#include +#include +#include +#endif + +/* system dependent call to get the current system time. Returned as + 100ns ticks since UUID epoch, but resolution may be less than + 100ns. */ + +#ifdef WIN32 +#define I64(C) C +#else +#define I64(C) C##LL +#endif + +typedef uint64_t uuid_time_t; + +typedef struct { + char nodeID[6]; +} uuid_node_t; + +#undef uuid_t +typedef struct { + uint32_t time_low; + uint16_t time_mid; + uint16_t time_hi_and_version; + uint8_t clock_seq_hi_and_reserved; + uint8_t clock_seq_low; + uint8_t node[6]; +} uuid_t; + +/* some forward declarations. kind of wimpy to do that but heck, we + are all friends here right? raj 20081024 */ +static uint16_t true_random(void); + + + +#ifdef WIN32 + +static void get_system_time(uuid_time_t *uuid_time) +{ + ULARGE_INTEGER time; + + /* NT keeps time in FILETIME format which is 100ns ticks since + Jan 1, 1601. UUIDs use time in 100ns ticks since Oct 15, 1582. + The difference is 17 Days in Oct + 30 (Nov) + 31 (Dec) + + 18 years and 5 leap days. */ + GetSystemTimeAsFileTime((FILETIME *)&time); + time.QuadPart += + + (unsigned __int64) (1000*1000*10) // seconds + * (unsigned __int64) (60 * 60 * 24) // days + * (unsigned __int64) (17+30+31+365*18+5); // # of days + *uuid_time = time.QuadPart; +} + +/* Sample code, not for use in production; see RFC 1750 */ +static void get_random_info(char seed[16]) +{ + uint16_t myrand; + int i; + + i = 0; + do { + myrand = true_random(); + seed[i++] = myrand & 0xff; + seed[i++] = myrand >> 8; + } while (i < 14); + +} + +#else + +static void get_system_time(uuid_time_t *uuid_time) +{ + struct timeval tp; + + gettimeofday(&tp, (struct timezone *)0); + + /* Offset between UUID formatted times and Unix formatted times. + UUID UTC base time is October 15, 1582. + Unix base time is January 1, 1970.*/ + *uuid_time = ((uint64_t)tp.tv_sec * 10000000) + + ((uint64_t)tp.tv_usec * 10) + + I64(0x01B21DD213814000); +} + +/* Sample code, not for use in production; see RFC 1750 */ +static void get_random_info(char seed[16]) +{ + FILE *fp; + uint16_t myrand; + int i; + + /* we aren't all that picky, and we would rather not block so we + will use urandom */ + fp = fopen("/dev/urandom","rb"); + + if (NULL != fp) { + fread(seed,sizeof(seed),1,fp); + return; + } + + /* ok, now what? */ + + i = 0; + do { + myrand = true_random(); + seed[i++] = myrand & 0xff; + seed[i++] = myrand >> 8; + } while (i < 14); + +} + +#endif + + +/* true_random -- generate a crypto-quality random number. +**This sample doesn't do that.** */ +static uint16_t true_random(void) +{ + static int inited = 0; + uuid_time_t time_now; + + if (!inited) { + get_system_time(&time_now); + time_now = time_now / UUIDS_PER_TICK; + srand((unsigned int) + (((time_now >> 32) ^ time_now) & 0xffffffff)); + inited = 1; + } + + return rand(); +} + +/* puid -- print a UUID */ +void puid(uuid_t u) +{ + int i; + + printf("%8.8x-%4.4x-%4.4x-%2.2x%2.2x-", u.time_low, u.time_mid, + u.time_hi_and_version, u.clock_seq_hi_and_reserved, + u.clock_seq_low); + for (i = 0; i < 6; i++) + printf("%2.2x", u.node[i]); + printf("\n"); +} + +/* snpuid -- print a UUID in the supplied buffer */ +void snpuid(char *str, size_t size, uuid_t u) { + int i; + char *tmp = str; + + if (size < 38) { + snprintf(tmp,size,"%s","uuid string too small"); + return; + } + + /* perhaps this is a trifle optimistic but what the heck */ + sprintf(tmp, + "%8.8x-%4.4x-%4.4x-%2.2x%2.2x-", + u.time_low, + u.time_mid, + u.time_hi_and_version, + u.clock_seq_hi_and_reserved, + u.clock_seq_low); + tmp += 24; + for (i = 0; i < 6; i++) { + sprintf(tmp,"%2.2x", u.node[i]); + tmp += 2; + } + *tmp = 0; + +} + +/* get-current_time -- get time as 60-bit 100ns ticks since UUID epoch. + Compensate for the fact that real clock resolution is + less than 100ns. */ +static void get_current_time(uuid_time_t *timestamp) +{ + static int inited = 0; + static uuid_time_t time_last; + static uint16_t uuids_this_tick; + uuid_time_t time_now; + + if (!inited) { + get_system_time(&time_now); + uuids_this_tick = UUIDS_PER_TICK; + inited = 1; + } + + for ( ; ; ) { + get_system_time(&time_now); + + /* if clock reading changed since last UUID generated, */ + if (time_last != time_now) { + /* reset count of uuids gen'd with this clock reading */ + uuids_this_tick = 0; + time_last = time_now; + break; + } + if (uuids_this_tick < UUIDS_PER_TICK) { + uuids_this_tick++; + break; + } + /* going too fast for our clock; spin */ + } + /* add the count of uuids to low order bits of the clock reading */ + *timestamp = time_now + uuids_this_tick; +} + + +/* system dependent call to get IEEE node ID. + This sample implementation generates a random node ID. */ +/* netperf mod - don't bother trying to read or write the nodeid */ +static void get_ieee_node_identifier(uuid_node_t *node) +{ + static int inited = 0; + static uuid_node_t saved_node; + char seed[16]; + + if (!inited) { + get_random_info(seed); + seed[0] |= 0x01; + memcpy(&saved_node, seed, sizeof saved_node); + } + inited = 1; + + *node = saved_node; +} + + +/* format_uuid_v1 -- make a UUID from the timestamp, clockseq, + and node ID */ +static void format_uuid_v1(uuid_t* uuid, uint16_t clock_seq, + uuid_time_t timestamp, uuid_node_t node) +{ + /* Construct a version 1 uuid with the information we've gathered + plus a few constants. */ + uuid->time_low = (unsigned long)(timestamp & 0xFFFFFFFF); + uuid->time_mid = (unsigned short)((timestamp >> 32) & 0xFFFF); + uuid->time_hi_and_version = + (unsigned short)((timestamp >> 48) & 0x0FFF); + uuid->time_hi_and_version |= (1 << 12); + uuid->clock_seq_low = clock_seq & 0xFF; + uuid->clock_seq_hi_and_reserved = (clock_seq & 0x3F00) >> 8; + uuid->clock_seq_hi_and_reserved |= 0x80; + memcpy(&uuid->node, &node, sizeof uuid->node); +} + +/* uuid_create -- generator a UUID */ +int uuid_create(uuid_t *uuid) +{ + uuid_time_t timestamp; + uint16_t clockseq; + uuid_node_t node; + + /* get time, node ID, saved state from non-volatile storage */ + get_current_time(×tamp); + get_ieee_node_identifier(&node); + + /* for us clockseq is always to be random as we have no state */ + clockseq = true_random(); + + /* stuff fields into the UUID */ + format_uuid_v1(uuid, clockseq, timestamp, node); + return 1; +} + +void get_uuid_string(char *uuid_str, size_t size) { + uuid_t u; + + uuid_create(&u); + snpuid(uuid_str,size,u); + + return; +} + +#ifdef NETPERF_STANDALONE_DEBUG + +int +main(int argc, char *argv[]) +{ + uuid_t u; + char uuid_str[38]; +#if 0 + uuid_create(&u); + printf("uuid_create(): "); puid(u); + snpuid(uuid_str,sizeof(uuid_str),u); + printf("\nas a string %s\n",uuid_str); +#endif + get_uuid_string(uuid_str,sizeof(uuid_str)); + printf("uuid_str is %s\n",uuid_str); + return 0; +} + + +#endif diff --git a/src/netcpu.h b/src/netcpu.h new file mode 100644 index 0000000..58d1e1c --- /dev/null +++ b/src/netcpu.h @@ -0,0 +1,19 @@ +/* This should define all the common routines etc exported by the + various netcpu_mumble.c files raj 2005-01-26 */ + +extern void cpu_util_init(void); +extern void cpu_util_terminate(void); +extern int get_cpu_method(); + +#ifdef WIN32 +/* +*+ temp until I figure out what header this is in; I know it's + there someplace... */ +typedef unsigned __int64 uint64_t; +#endif + +extern void get_cpu_idle(uint64_t *res); +extern float calibrate_idle_rate(int iterations, int interval); +extern float calc_cpu_util_internal(float elapsed); +extern void cpu_start_internal(void); +extern void cpu_stop_internal(void); + diff --git a/src/netcpu_kstat.c b/src/netcpu_kstat.c new file mode 100644 index 0000000..53902ca --- /dev/null +++ b/src/netcpu_kstat.c @@ -0,0 +1,413 @@ +char netcpu_kstat_id[]="\ +@(#)netcpu_kstat.c Version 2.4.0"; + +#if HAVE_CONFIG_H +# include +#endif + +#include + +#if HAVE_INTTYPES_H +# include +#else +# if HAVE_STDINT_H +# include +# endif +#endif + +#if HAVE_UNISTD_H +# include +#endif +#if HAVE_STRINGS_H +# include +#endif +#if STDC_HEADERS +# include +# include +#else +# if HAVE_STDLIB_H +# include +# endif +#endif + +#include +#include + +#include "netsh.h" +#include "netlib.h" + +/* the lib_start_count and lib_end_count arrays hold the starting + and ending values of whatever is counting when the system is + idle. The rate at which this increments during a test is compared + with a previous calibrarion to arrive at a CPU utilization + percentage. raj 2005-01-26 */ +static uint64_t lib_start_count[MAXCPUS]; +static uint64_t lib_end_count[MAXCPUS]; + +static kstat_t *cpu_ks[MAXCPUS]; /* the addresses that kstat will + need to pull the cpu info from + the kstat interface. at least I + think that is what this is :) raj + 8/2000 */ + +#define UPDKCID(nk,ok) \ +if (nk == -1) { \ + perror("kstat_read "); \ + exit(1); \ +} \ +if (nk != ok)\ + goto kcid_changed; + +static kstat_ctl_t *kc = NULL; +static kid_t kcid = 0; + +/* do the initial open of the kstat interface, get the chain id's all + straightened-out and set-up the addresses for get_kstat_idle to do + its thing. liberally borrowed from the sources to TOP. raj 8/2000 */ + +static int +open_kstat() +{ + kstat_t *ks; + kid_t nkcid; + int i; + int changed = 0; + static int ncpu = 0; + + kstat_named_t *kn; + + if (debug) { + fprintf(where,"open_kstat: enter\n"); + fflush(where); + } + + /* + * 0. kstat_open + */ + + if (!kc) + { + kc = kstat_open(); + if (!kc) + { + perror("kstat_open "); + exit(1); + } + changed = 1; + kcid = kc->kc_chain_id; + } +#ifdef rickwasstupid + else { + fprintf(where,"open_kstat double open!\n"); + fflush(where); + exit(1); + } +#endif + + /* keep doing it until no more changes */ + kcid_changed: + + if (debug) { + fprintf(where,"passing kcid_changed\n"); + fflush(where); + } + + /* + * 1. kstat_chain_update + */ + nkcid = kstat_chain_update(kc); + if (nkcid) + { + /* UPDKCID will abort if nkcid is -1, so no need to check */ + changed = 1; + kcid = nkcid; + } + UPDKCID(nkcid,0); + + if (debug) { + fprintf(where,"kstat_lookup for unix/system_misc\n"); + fflush(where); + } + + ks = kstat_lookup(kc, "unix", 0, "system_misc"); + if (kstat_read(kc, ks, 0) == -1) { + perror("kstat_read"); + exit(1); + } + + + if (changed) { + + /* + * 2. get data addresses + */ + + ncpu = 0; + + kn = kstat_data_lookup(ks, "ncpus"); + if (kn && kn->value.ui32 > lib_num_loc_cpus) { + fprintf(stderr,"number of CPU's mismatch!"); + exit(1); + } + + for (ks = kc->kc_chain; ks; + ks = ks->ks_next) + { + if (strncmp(ks->ks_name, "cpu_stat", 8) == 0) + { + nkcid = kstat_read(kc, ks, NULL); + /* if kcid changed, pointer might be invalid. we'll deal + wtih changes at this stage, but will not accept them + when we are actually in the middle of reading + values. hopefully this is not going to be a big + issue. raj 8/2000 */ + UPDKCID(nkcid, kcid); + + if (debug) { + fprintf(where,"cpu_ks[%d] getting %p\n",ncpu,ks); + fflush(where); + } + + cpu_ks[ncpu] = ks; + ncpu++; + if (ncpu > lib_num_loc_cpus) + { + /* with the check above, would we ever hit this? */ + fprintf(stderr, + "kstat finds too many cpus %d: should be %d\n", + ncpu,lib_num_loc_cpus); + exit(1); + } + } + } + /* note that ncpu could be less than ncpus, but that's okay */ + changed = 0; + } +} + +/* return the value of the idle tick counter for the specified CPU */ +static long +get_kstat_idle(cpu) + int cpu; +{ + cpu_stat_t cpu_stat; + kid_t nkcid; + + if (debug) { + fprintf(where, + "get_kstat_idle reading with kc %x and ks %p\n", + kc, + cpu_ks[cpu]); + } + + nkcid = kstat_read(kc, cpu_ks[cpu], &cpu_stat); + /* if kcid changed, pointer might be invalid, fail the test */ + UPDKCID(nkcid, kcid); + + return(cpu_stat.cpu_sysinfo.cpu[CPU_IDLE]); + + kcid_changed: + perror("kcid changed midstream and I cannot deal with that!"); + exit(1); +} + +void +cpu_util_init(void) +{ + open_kstat(); + return; +} + +void +cpu_util_terminate(void) +{ + return; +} + +int +get_cpu_method(void) +{ + return KSTAT; +} + +void +get_cpu_idle(uint64_t *res) +{ + + int i; + + /* this open may be redundant */ + open_kstat(); + + for (i = 0; i < lib_num_loc_cpus; i++){ + res[i] = get_kstat_idle(i); + } + return; +} + +float +calibrate_idle_rate(int iterations, int interval) +{ + + long + firstcnt[MAXCPUS], + secondcnt[MAXCPUS]; + + float + elapsed, + temp_rate, + rate[MAXTIMES], + local_maxrate; + + long + sec, + usec; + + int + i, + j; + + struct timeval time1, time2 ; + struct timezone tz; + + if (debug) { + fprintf(where,"calling open_kstat from calibrate_kstat\n"); + fflush(where); + } + + open_kstat(); + + if (iterations > MAXTIMES) { + iterations = MAXTIMES; + } + + local_maxrate = (float)-1.0; + + for(i = 0; i < iterations; i++) { + rate[i] = (float)0.0; + for (j = 0; j < lib_num_loc_cpus; j++) { + firstcnt[j] = get_kstat_idle(j); + } + gettimeofday (&time1, &tz); + sleep(interval); + gettimeofday (&time2, &tz); + + if (time2.tv_usec < time1.tv_usec) + { + time2.tv_usec += 1000000; + time2.tv_sec -=1; + } + sec = time2.tv_sec - time1.tv_sec; + usec = time2.tv_usec - time1.tv_usec; + elapsed = (float)sec + ((float)usec/(float)1000000.0); + + if(debug) { + fprintf(where, "Calibration for kstat counter run: %d\n",i); + fprintf(where,"\tsec = %ld usec = %ld\n",sec,usec); + fprintf(where,"\telapsed time = %g\n",elapsed); + } + + for (j = 0; j < lib_num_loc_cpus; j++) { + secondcnt[j] = get_kstat_idle(j); + if(debug) { + /* I know that there are situations where compilers know about */ + /* long long, but the library functions do not... raj 4/95 */ + fprintf(where, + "\tfirstcnt[%d] = 0x%8.8lx%8.8lx secondcnt[%d] = 0x%8.8lx%8.8lx\n", + j, + firstcnt[j], + firstcnt[j], + j, + secondcnt[j], + secondcnt[j]); + } + /* we assume that it would wrap no more than once. we also */ + /* assume that the result of subtracting will "fit" raj 4/95 */ + temp_rate = (secondcnt[j] >= firstcnt[j]) ? + (float)(secondcnt[j] - firstcnt[j])/elapsed : + (float)(secondcnt[j]-firstcnt[j]+MAXLONG)/elapsed; + if (temp_rate > rate[i]) rate[i] = temp_rate; + if(debug) { + fprintf(where,"\trate[%d] = %g\n",i,rate[i]); + fflush(where); + } + if (local_maxrate < rate[i]) local_maxrate = rate[i]; + } + } + if(debug) { + fprintf(where,"\tlocal maxrate = %g per sec. \n",local_maxrate); + fflush(where); + } + return local_maxrate; +} + +float +calc_cpu_util_internal(float elapsed_time) +{ + int i; + float correction_factor; + float actual_rate; + + lib_local_cpu_util = (float)0.0; + /* It is possible that the library measured a time other than */ + /* the one that the user want for the cpu utilization */ + /* calculations - for example, tests that were ended by */ + /* watchdog timers such as the udp stream test. We let these */ + /* tests tell up what the elapsed time should be. */ + + if (elapsed_time != 0.0) { + correction_factor = (float) 1.0 + + ((lib_elapsed - elapsed_time) / elapsed_time); + } + else { + correction_factor = (float) 1.0; + } + + for (i = 0; i < lib_num_loc_cpus; i++) { + + /* it would appear that on some systems, in loopback, nice is + *very* effective, causing the looper process to stop dead in its + tracks. if this happens, we need to ensure that the calculation + does not go south. raj 6/95 and if we run completely out of idle, + the same thing could in theory happen to the USE_KSTAT path. raj + 8/2000 */ + + if (lib_end_count[i] == lib_start_count[i]) { + lib_end_count[i]++; + } + + actual_rate = (lib_end_count[i] > lib_start_count[i]) ? + (float)(lib_end_count[i] - lib_start_count[i])/lib_elapsed : + (float)(lib_end_count[i] - lib_start_count[i] + + MAXLONG)/ lib_elapsed; + if (debug) { + fprintf(where, + "calc_cpu_util: actual_rate on processor %d is %f start %lx end %lx\n", + i, + actual_rate, + lib_start_count[i], + lib_end_count[i]); + } + lib_local_per_cpu_util[i] = (lib_local_maxrate - actual_rate) / + lib_local_maxrate * 100; + lib_local_per_cpu_util[i] *= correction_factor; + lib_local_cpu_util += lib_local_per_cpu_util[i]; + } + /* we want the average across all n processors */ + lib_local_cpu_util /= (float)lib_num_loc_cpus; + + return lib_local_cpu_util; +} + +void +cpu_start_internal(void) +{ + get_cpu_idle(lib_start_count); + return; +} + +void +cpu_stop_internal(void) +{ + get_cpu_idle(lib_end_count); +} diff --git a/src/netcpu_kstat10.c b/src/netcpu_kstat10.c new file mode 100644 index 0000000..7ff8470 --- /dev/null +++ b/src/netcpu_kstat10.c @@ -0,0 +1,600 @@ +char netcpu_kstat10_id[]="\ +@(#)netcpu_kstat10.c (c) Copyright 2005-2007, Hewlett-Packard Company Version 2.4.3"; + +#if HAVE_CONFIG_H +# include +#endif + +#include + +#if HAVE_INTTYPES_H +# include +#else +# if HAVE_STDINT_H +# include +# endif +#endif + +#if HAVE_UNISTD_H +# include +#endif +#if HAVE_STRINGS_H +# include +#endif +#if STDC_HEADERS +# include +# include +#else +# if HAVE_STDLIB_H +# include +# endif +#endif + +#include + +#include +#include + +#include "netsh.h" +#include "netlib.h" + +static kstat_ctl_t *kc = NULL; +static kid_t kcid = 0; + +typedef struct cpu_time_counters { + uint64_t idle; + uint64_t user; + uint64_t kernel; + uint64_t interrupt; +} cpu_time_counters_t; + +static cpu_time_counters_t starting_cpu_counters[MAXCPUS]; +static cpu_time_counters_t ending_cpu_counters[MAXCPUS]; +static cpu_time_counters_t delta_cpu_counters[MAXCPUS]; +static cpu_time_counters_t corrected_cpu_counters[MAXCPUS]; + +static void +print_cpu_time_counters(char *name, int instance, cpu_time_counters_t *counters) +{ + fprintf(where,"%s[%d]:\n",name,instance); + fprintf(where, + "\t idle %llu\n",counters[instance].idle); + fprintf(where, + "\t user %llu\n",counters[instance].user); + fprintf(where, + "\t kernel %llu\n",counters[instance].kernel); + fprintf(where, + "\t interrupt %llu\n",counters[instance].interrupt); +} + +void +cpu_util_init(void) +{ + kstat_t *ksp; + int i; + kc = kstat_open(); + + if (kc == NULL) { + fprintf(where, + "cpu_util_init: kstat_open: errno %d %s\n", + errno, + strerror(errno)); + fflush(where); + exit(-1); + } + + /* lets flesh-out a CPU instance number map since it seems that some + systems, not even those which are partitioned, can have + non-contiguous CPU numbers. discovered "the hard way" on a + T5220. raj 20080804 */ + i = 0; + for (ksp = kc->kc_chain, i = 0; + (ksp != NULL) && (i < MAXCPUS); + ksp = ksp->ks_next) { + if ((strcmp(ksp->ks_module,"cpu") == 0) && + (strcmp(ksp->ks_name,"sys") == 0)) { + if (debug) { + fprintf(where,"Mapping CPU instance %d to entry %d\n", + ksp->ks_instance,i); + fflush(where); + } + lib_cpu_map[i++] = ksp->ks_instance; + } + } + + if (MAXCPUS == i) { + fprintf(where, + "Sorry, this system has more CPUs (%d) than netperf can handle (%d).\n", + i, + MAXCPUS); + fprintf(where, + "Please alter MAXCPUS in netlib.h and recompile.\n"); + fflush(where); + exit(1); + } + + return; +} + +void +cpu_util_terminate(void) +{ + kstat_close(kc); + return; +} + +int +get_cpu_method(void) +{ + return KSTAT_10; +} + +static void +print_unexpected_statistic_warning(char *who, char *what, char *why) +{ + if (why) { + fprintf(where, + "WARNING! WARNING! WARNING! WARNING!\n"); + fprintf(where, + "%s found an unexpected %s statistic %.16s\n", + who, + why, + what); + } + else { + fprintf(where, + "%s is ignoring statistic %.16s\n", + who, + what); + } +} + +static void +get_cpu_counters(int cpu_num, cpu_time_counters_t *counters) +{ + + kstat_t *ksp; + int found=0; + kid_t nkcid; + kstat_named_t *knp; + int i; + + ksp = kstat_lookup(kc, "cpu", lib_cpu_map[cpu_num], "sys"); + if ((ksp) && (ksp->ks_type == KSTAT_TYPE_NAMED)) { + /* happiness and joy, keep going */ + nkcid = kstat_read(kc, ksp, NULL); + if (nkcid != -1) { + /* happiness and joy, keep going. we could consider adding a + "found < 3" to the end conditions, but then we wouldn't + search to the end and find that Sun added some nsec. we + probably want to see if they add an nsec. raj 2005-01-28 */ + for (i = ksp->ks_ndata, knp = ksp->ks_data; + i > 0; + knp++,i--) { + /* we would be hosed if the same name could appear twice */ + if (!strcmp("cpu_nsec_idle",knp->name)) { + found++; + counters[cpu_num].idle = knp->value.ui64; + } + else if (!strcmp("cpu_nsec_user",knp->name)) { + found++; + counters[cpu_num].user = knp->value.ui64; + } + else if (!strcmp("cpu_nsec_kernel",knp->name)) { + found++; + counters[cpu_num].kernel = knp->value.ui64; + } + else if (!strcmp("cpu_nsec_intr",knp->name)) { + if (debug >= 2) { + fprintf(where, + "Found a cpu_nsec_intr but it doesn't do what we want\n"); + fflush(where); + } + } + else if (strstr(knp->name,"nsec")) { + /* finding another nsec here means Sun have changed + something and we need to warn the user. raj 2005-01-28 */ + print_unexpected_statistic_warning("get_cpu_counters", + knp->name, + "nsec"); + } + else if (debug >=2) { + + /* might want to tell people about what we are skipping. + however, only display other names debug >=2. raj + 2005-01-28 + */ + + print_unexpected_statistic_warning("get_cpu_counters", + knp->name, + NULL); + } + } + if (3 == found) { + /* happiness and joy */ + return; + } + else { + fprintf(where, + "get_cpu_counters could not find one or more of the expected counters!\n"); + fflush(where); + exit(-1); + } + } + else { + /* the kstat_read returned an error or the chain changed */ + fprintf(where, + "get_cpu_counters: kstat_read failed or chain id changed %d %s\n", + errno, + strerror(errno)); + fflush(where); + exit(-1); + } + } + else { + /* the lookup failed or found the wrong type */ + fprintf(where, + "get_cpu_counters: kstat_lookup failed for module 'cpu' number %d instance %d name 'sys' and KSTAT_TYPE_NAMED: errno %d %s\n", + cpu_num, + lib_cpu_map[cpu_num], + errno, + strerror(errno)); + fflush(where); + exit(-1); + } +} + +static void +get_interrupt_counters(int cpu_num, cpu_time_counters_t *counters) +{ + kstat_t *ksp; + int found=0; + kid_t nkcid; + kstat_named_t *knp; + int i; + + ksp = kstat_lookup(kc, "cpu", lib_cpu_map[cpu_num], "intrstat"); + + counters[cpu_num].interrupt = 0; + if ((ksp) && (ksp->ks_type == KSTAT_TYPE_NAMED)) { + /* happiness and joy, keep going */ + nkcid = kstat_read(kc, ksp, NULL); + if (nkcid != -1) { + /* happiness and joy, keep going. we could consider adding a + "found < 15" to the end conditions, but then we wouldn't + search to the end and find that Sun added some "time." we + probably want to see if they add a "nsec." raj 2005-01-28 */ + for (i = ksp->ks_ndata, knp = ksp->ks_data; + i > 0; + knp++,i--) { + if (strstr(knp->name,"time")) { + found++; + counters[cpu_num].interrupt += knp->value.ui64; + } + else if (debug >=2) { + + /* might want to tell people about what we are skipping. + however, only display other names debug >=2. raj + 2005-01-28 + */ + + print_unexpected_statistic_warning("get_cpu_counters", + knp->name, + NULL); + } + } + if (15 == found) { + /* happiness and joy */ + return; + } + else { + fprintf(where, + "get_cpu_counters could not find one or more of the expected counters!\n"); + fflush(where); + exit(-1); + } + } + else { + /* the kstat_read returned an error or the chain changed */ + fprintf(where, + "get_cpu_counters: kstat_read failed or chain id changed %d %s\n", + errno, + strerror(errno)); + fflush(where); + exit(-1); + } + } + else { + /* the lookup failed or found the wrong type */ + fprintf(where, + "get_cpu_counters: kstat_lookup failed for module 'cpu' %d instance %d class 'intrstat' and KSTAT_TYPE_NAMED: errno %d %s\n", + cpu_num, + lib_cpu_map[cpu_num], + errno, + strerror(errno)); + fflush(where); + exit(-1); + } + +} + +static void +get_cpu_time_counters(cpu_time_counters_t *counters) +{ + + int i; + + for (i = 0; i < lib_num_loc_cpus; i++){ + get_cpu_counters(i, counters); + get_interrupt_counters(i, counters); + } + + return; +} + +/* the kstat10 mechanism, since it is based on actual nanosecond + counters is not going to use a comparison to an idle rate. so, the + calibrate_idle_rate routine will be rather simple :) raj 2005-01-28 + */ + +float +calibrate_idle_rate(int iterations, int interval) +{ + return 0.0; +} + +float +calc_cpu_util_internal(float elapsed_time) +{ + int i; + float correction_factor; + float actual_rate; + + uint64_t total_cpu_nsec; + + /* multiply by 100 and divide by total and you get whole + percentages. multiply by 1000 and divide by total and you get + tenths of percentages. multiply by 10000 and divide by total and + you get hundredths of percentages. etc etc etc raj 2005-01-28 */ + +#define CALC_PERCENT 100 +#define CALC_TENTH_PERCENT 1000 +#define CALC_HUNDREDTH_PERCENT 10000 +#define CALC_THOUSANDTH_PERCENT 100000 +#define CALC_ACCURACY CALC_THOUSANDTH_PERCENT + + uint64_t fraction_idle; + uint64_t fraction_user; + uint64_t fraction_kernel; + uint64_t fraction_interrupt; + + uint64_t interrupt_idle; + uint64_t interrupt_user; + uint64_t interrupt_kernel; + + lib_local_cpu_util = (float)0.0; + + /* It is possible that the library measured a time other than */ + /* the one that the user want for the cpu utilization */ + /* calculations - for example, tests that were ended by */ + /* watchdog timers such as the udp stream test. We let these */ + /* tests tell up what the elapsed time should be. */ + + if (elapsed_time != 0.0) { + correction_factor = (float) 1.0 + + ((lib_elapsed - elapsed_time) / elapsed_time); + } + else { + correction_factor = (float) 1.0; + } + + for (i = 0; i < lib_num_loc_cpus; i++) { + + /* this is now the fun part. we have the nanoseconds _allegedly_ + spent in user, idle and kernel. We also have nanoseconds spent + servicing interrupts. Sadly, in the developer's finite wisdom, + the interrupt time accounting is in parallel with the other + accounting. this means that time accounted in user, kernel or + idle will also include time spent in interrupt. for netperf's + porpoises we do not really care about that for user and kernel, + but we certainly do care for idle. the $64B question becomes - + how to "correct" for this? + + we could just subtract interrupt time from idle. that has the + virtue of simplicity and also "punishes" Sun for doing + something that seems to be so stupid. however, we probably + have to be "fair" even to the allegedly stupid so the other + mechanism, suggested by a Sun engineer is to subtract interrupt + time from each of user, kernel and idle in proportion to their + numbers. then we sum the corrected user, kernel and idle along + with the interrupt time and use that to calculate a new idle + percentage and thus a CPU util percentage. + + that is what we will attempt to do here. raj 2005-01-28 + + of course, we also have to wonder what we should do if there is + more interrupt time than the sum of user, kernel and idle. + that is a theoretical possibility I suppose, but for the + time-being, one that we will blythly ignore, except perhaps for + a quick check. raj 2005-01-31 + */ + + /* we ass-u-me that these counters will never wrap during a + netperf run. this may not be a particularly safe thing to + do. raj 2005-01-28 */ + delta_cpu_counters[i].idle = ending_cpu_counters[i].idle - + starting_cpu_counters[i].idle; + delta_cpu_counters[i].user = ending_cpu_counters[i].user - + starting_cpu_counters[i].user; + delta_cpu_counters[i].kernel = ending_cpu_counters[i].kernel - + starting_cpu_counters[i].kernel; + delta_cpu_counters[i].interrupt = ending_cpu_counters[i].interrupt - + starting_cpu_counters[i].interrupt; + + if (debug) { + print_cpu_time_counters("delta_cpu_counters",i,delta_cpu_counters); + } + + /* for this summation, we do not include interrupt time */ + total_cpu_nsec = + delta_cpu_counters[i].idle + + delta_cpu_counters[i].user + + delta_cpu_counters[i].kernel; + + if (debug) { + fprintf(where,"total_cpu_nsec %llu\n",total_cpu_nsec); + } + + if (delta_cpu_counters[i].interrupt > total_cpu_nsec) { + /* we are not in Kansas any more Toto, and I am not quite sure + the best way to get our tails out of here so let us just + punt. raj 2005-01-31 */ + fprintf(where, + "WARNING! WARNING! WARNING! WARNING! WARNING! \n"); + fprintf(where, + "calc_cpu_util_internal: more interrupt time than others combined!\n"); + fprintf(where, + "\tso CPU util cannot be estimated\n"); + fprintf(where, + "\t delta[%d].interrupt %llu\n",i,delta_cpu_counters[i].interrupt); + fprintf(where, + "\t delta[%d].idle %llu\n",i,delta_cpu_counters[i].idle); + fprintf(where, + "\t delta[%d].user %llu\n",i,delta_cpu_counters[i].user); + fprintf(where, + "\t delta[%d].kernel %llu\n",i,delta_cpu_counters[i].kernel); + fflush(where); + + lib_local_cpu_util = -1.0; + lib_local_per_cpu_util[i] = -1.0; + return -1.0; + } + + /* and now some fun with integer math. i initially tried to + promote things to long doubled but that didn't seem to result + in happiness and joy. raj 2005-01-28 */ + + fraction_idle = + (delta_cpu_counters[i].idle * CALC_ACCURACY) / total_cpu_nsec; + + fraction_user = + (delta_cpu_counters[i].user * CALC_ACCURACY) / total_cpu_nsec; + + fraction_kernel = + (delta_cpu_counters[i].kernel * CALC_ACCURACY) / total_cpu_nsec; + + /* ok, we have our fractions, now we want to take that fraction of + the interrupt time and subtract that from the bucket. */ + + interrupt_idle = ((delta_cpu_counters[i].interrupt * fraction_idle) / + CALC_ACCURACY); + + interrupt_user = ((delta_cpu_counters[i].interrupt * fraction_user) / + CALC_ACCURACY); + + interrupt_kernel = ((delta_cpu_counters[i].interrupt * fraction_kernel) / + CALC_ACCURACY); + + if (debug) { + fprintf(where, + "\tfraction_idle %llu interrupt_idle %llu\n", + fraction_idle, + interrupt_idle); + fprintf(where, + "\tfraction_user %llu interrupt_user %llu\n", + fraction_user, + interrupt_user); + fprintf(where,"\tfraction_kernel %llu interrupt_kernel %llu\n", + fraction_kernel, + interrupt_kernel); + } + + corrected_cpu_counters[i].idle = delta_cpu_counters[i].idle - + interrupt_idle; + + corrected_cpu_counters[i].user = delta_cpu_counters[i].user - + interrupt_user; + + corrected_cpu_counters[i].kernel = delta_cpu_counters[i].kernel - + interrupt_kernel; + + corrected_cpu_counters[i].interrupt = delta_cpu_counters[i].interrupt; + + if (debug) { + print_cpu_time_counters("corrected_cpu_counters", + i, + corrected_cpu_counters); + } + + /* I was going to checkfor going less than zero, but since all the + calculations are in unsigned quantities that would seem to be a + triffle silly... raj 2005-01-28 */ + + /* ok, now we sum the numbers again, this time including interrupt + */ + + total_cpu_nsec = + corrected_cpu_counters[i].idle + + corrected_cpu_counters[i].user + + corrected_cpu_counters[i].kernel + + corrected_cpu_counters[i].interrupt; + + /* and recalculate our fractions we are really only going to use + fraction_idle, but lets calculate the rest just for the heck of + it. one day we may want to display them. raj 2005-01-28 */ + + /* multiply by 100 and divide by total and you get whole + percentages. multiply by 1000 and divide by total and you get + tenths of percentages. multiply by 10000 and divide by total + and you get hundredths of percentages. etc etc etc raj + 2005-01-28 */ + fraction_idle = + (corrected_cpu_counters[i].idle * CALC_ACCURACY) / total_cpu_nsec; + + fraction_user = + (corrected_cpu_counters[i].user * CALC_ACCURACY) / total_cpu_nsec; + + fraction_kernel = + (corrected_cpu_counters[i].kernel * CALC_ACCURACY) / total_cpu_nsec; + + fraction_interrupt = + (corrected_cpu_counters[i].interrupt * CALC_ACCURACY) / total_cpu_nsec; + + if (debug) { + fprintf(where,"\tfraction_idle %lu\n",fraction_idle); + fprintf(where,"\tfraction_user %lu\n",fraction_user); + fprintf(where,"\tfraction_kernel %lu\n",fraction_kernel); + fprintf(where,"\tfraction_interrupt %lu\n",fraction_interrupt); + } + + /* and finally, what is our CPU utilization? */ + lib_local_per_cpu_util[i] = 100.0 - (((float)fraction_idle / + (float)CALC_ACCURACY) * 100.0); + lib_local_per_cpu_util[i] *= correction_factor; + if (debug) { + fprintf(where, + "lib_local_per_cpu_util[%d] %g cf %f\n", + i, + lib_local_per_cpu_util[i], + correction_factor); + } + lib_local_cpu_util += lib_local_per_cpu_util[i]; + } + /* we want the average across all n processors */ + lib_local_cpu_util /= (float)lib_num_loc_cpus; + + return lib_local_cpu_util; +} + +void +cpu_start_internal(void) +{ + get_cpu_time_counters(starting_cpu_counters); + return; +} + +void +cpu_stop_internal(void) +{ + get_cpu_time_counters(ending_cpu_counters); +} diff --git a/src/netcpu_looper.c b/src/netcpu_looper.c new file mode 100644 index 0000000..f184691 --- /dev/null +++ b/src/netcpu_looper.c @@ -0,0 +1,655 @@ +char netcpu_looper_id[]="\ +@(#)netcpu_looper.c (c) Copyright 2005-2007. Version 2.4.3"; + +/* netcpu_looper.c + + Implement the soaker process specific portions of netperf CPU + utilization measurements. These are broken-out into a separate file + to make life much nicer over in netlib.c which had become a maze of + twisty, CPU-util-related, #ifdefs, all different. raj 2005-01-26 + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include + +#ifdef HAVE_FCNTL_H +# include +#endif +#if HAVE_UNISTD_H +# include +#endif +#if defined(HAVE_MMAP) || defined(HAVE_SYS_MMAN_H) +# include +#else +# error netcpu_looper requires mmap +#endif + +#if TIME_WITH_SYS_TIME +# include +# include +#else +# if HAVE_SYS_TIME_H +# include +# else +# include +# endif +#endif + +#if HAVE_SYS_TYPES_H +# include +#endif + +#if HAVE_SYS_WAIT_H +# include +#endif + +#ifdef HAVE_SIGNAL_H +#include +#endif + +#ifdef HAVE_ERRNO_H +#include +#endif + +#include "netsh.h" +#include "netlib.h" + +#define PAGES_PER_CHILD 2 + +/* the lib_start_count and lib_end_count arrays hold the starting + and ending values of whatever is counting when the system is + idle. The rate at which this increments during a test is compared + with a previous calibrarion to arrive at a CPU utilization + percentage. raj 2005-01-26 */ +static uint64_t lib_start_count[MAXCPUS]; +static uint64_t lib_end_count[MAXCPUS]; + +static int *cpu_mappings; + +static int lib_idle_fd; +static uint64_t *lib_idle_address[MAXCPUS]; +static long *lib_base_pointer; +static pid_t lib_idle_pids[MAXCPUS]; +static int lib_loopers_running=0; + +/* we used to use this code to bind the loopers, but since we have + decided to enable processor affinity for the actual + netperf/netserver processes we will use that affinity routine, + which happens to know about more systems than this */ + +#ifdef NOTDEF +static void +bind_to_processor(int child_num) +{ + /* This routine will bind the calling process to a particular */ + /* processor. We are not choosy as to which processor, so it will be */ + /* the process id mod the number of processors - shifted by one for */ + /* those systems which name processor starting from one instead of */ + /* zero. on those systems where I do not yet know how to bind a */ + /* process to a processor, this routine will be a no-op raj 10/95 */ + + /* just as a reminder, this is *only* for the looper processes, not */ + /* the actual measurement processes. those will, should, MUST float */ + /* or not float from CPU to CPU as controlled by the operating */ + /* system defaults. raj 12/95 */ + +#ifdef __hpux +#include +#include + + int old_cpu = -2; + + if (debug) { + fprintf(where, + "child %d asking for CPU %d as pid %d with %d CPUs\n", + child_num, + (child_num % lib_num_loc_cpus), + getpid(), + lib_num_loc_cpus); + fflush(where); + } + + SETPROCESS((child_num % lib_num_loc_cpus), getpid()); + return; + +#else +#if defined(__sun) && defined(__SVR4) + /* should only be Solaris */ +#include +#include + + int old_binding; + + if (debug) { + fprintf(where, + "bind_to_processor: child %d asking for CPU %d as pid %d with %d CPUs\n", + child_num, + (child_num % lib_num_loc_cpus), + getpid(), + lib_num_loc_cpus); + fflush(where); + } + + if (processor_bind(P_PID, + getpid(), + (child_num % lib_num_loc_cpus), + &old_binding) != 0) { + fprintf(where,"bind_to_processor: unable to perform processor binding\n"); + fprintf(where," errno %d\n",errno); + fflush(where); + } + return; +#else +#ifdef WIN32 + + if (!SetThreadAffinityMask(GetCurrentThread(), (ULONG_PTR)1 << (child_num % lib_num_loc_cpus))) { + perror("SetThreadAffinityMask failed"); + fflush(stderr); + } + + if (debug) { + fprintf(where, + "bind_to_processor: child %d asking for CPU %d of %d CPUs\n", + child_num, + (child_num % lib_num_loc_cpus), + lib_num_loc_cpus); + fflush(where); + } + +#endif + return; +#endif /* __sun && _SVR4 */ +#endif /* __hpux */ +} +#endif + + /* sit_and_spin will just spin about incrementing a value */ + /* this value will either be in a memory mapped region on Unix shared */ + /* by each looper process, or something appropriate on Windows/NT */ + /* (malloc'd or such). This routine is reasonably ugly in that it has */ + /* priority manipulating code for lots of different operating */ + /* systems. This routine never returns. raj 1/96 */ + +static void +sit_and_spin(int child_index) + +{ + uint64_t *my_counter_ptr; + + /* only use C stuff if we are not WIN32 unless and until we */ + /* switch from CreateThread to _beginthread. raj 1/96 */ +#ifndef WIN32 + /* we are the child. we could decide to exec some separate */ + /* program, but that doesn't really seem worthwhile - raj 4/95 */ + if (debug > 1) { + fprintf(where, + "Looper child %d is born, pid %d\n", + child_index, + getpid()); + fflush(where); + } + +#endif /* WIN32 */ + + /* reset our base pointer to be at the appropriate offset */ + my_counter_ptr = (uint64_t *) ((char *)lib_base_pointer + + (netlib_get_page_size() * + PAGES_PER_CHILD * child_index)); + + /* in the event we are running on an MP system, it would */ + /* probably be good to bind the soaker processes to specific */ + /* processors. I *think* this is the most reasonable thing to */ + /* do, and would be closes to simulating the information we get */ + /* on HP-UX with pstat. I could put all the system-specific code */ + /* here, but will "abstract it into another routine to keep this */ + /* area more readable. I'll probably do the same thine with the */ + /* "low pri code" raj 10/95 */ + + /* since we are "flying blind" wrt where we should bind the looper + processes, we want to use the cpu_map that was prepared by netlib + rather than assume that the CPU ids on the system start at zero + and are contiguous. raj 2006-04-03 */ + bind_to_specific_processor(child_index % lib_num_loc_cpus,1); + + for (*my_counter_ptr = 0L; + ; + (*my_counter_ptr)++) { + if (!(*lib_base_pointer % 1)) { + /* every once and again, make sure that our process priority is */ + /* nice and low. also, by making system calls, it may be easier */ + /* for us to be pre-empted by something that needs to do useful */ + /* work - like the thread of execution actually sending and */ + /* receiving data across the network :) */ +#ifdef _AIX + int pid,prio; + + prio = PRIORITY; + pid = getpid(); + /* if you are not root, this call will return EPERM - why one */ + /* cannot change one's own priority to lower value is beyond */ + /* me. raj 2/26/96 */ + setpri(pid, prio); +#else /* _AIX */ +#ifdef __sgi + int pid,prio; + + prio = PRIORITY; + pid = getpid(); + schedctl(NDPRI, pid, prio); + sginap(0); +#else /* __sgi */ +#ifdef WIN32 + SetThreadPriority(GetCurrentThread(),THREAD_PRIORITY_IDLE); +#else /* WIN32 */ +#if defined(__sun) && defined(__SVR4) +#include +#include +#include +#include + /* I would *really* like to know how to use priocntl to make the */ + /* priority low for this looper process. however, either my mind */ + /* is addled, or the manpage in section two for priocntl is not */ + /* terribly helpful - for one, it has no examples :( so, if you */ + /* can help, I'd love to hear from you. in the meantime, we will */ + /* rely on nice(39). raj 2/26/96 */ + nice(39); +#else /* __sun && __SVR4 */ + nice(39); +#endif /* __sun && _SVR4 */ +#endif /* WIN32 */ +#endif /* __sgi */ +#endif /* _AIX */ + } + } +} + + + + /* this routine will start all the looper processes or threads for */ + /* measuring CPU utilization. */ + +static void +start_looper_processes() +{ + + unsigned int i, file_size; + + /* we want at least two pages for each processor. the */ + /* child for any one processor will write to the first of his two */ + /* pages, and the second page will be a buffer in case there is page */ + /* prefetching. if your system pre-fetches more than a single page, */ + /* well, you'll have to modify this or live with it :( raj 4/95 */ + + file_size = ((netlib_get_page_size() * PAGES_PER_CHILD) * + lib_num_loc_cpus); + +#ifndef WIN32 + + /* we we are not using WINDOWS NT (or 95 actually :), then we want */ + /* to create a memory mapped region so we can see all the counting */ + /* rates of the loopers */ + + /* could we just use an anonymous memory region for this? it is */ + /* possible that using a mmap()'ed "real" file, while convenient for */ + /* debugging, could result in some filesystem activity - like */ + /* metadata updates? raj 4/96 */ + lib_idle_fd = open("/tmp/netperf_cpu",O_RDWR | O_CREAT | O_EXCL); + + if (lib_idle_fd == -1) { + fprintf(where,"create_looper: file creation; errno %d\n",errno); + fflush(where); + exit(1); + } + + if (chmod("/tmp/netperf_cpu",0644) == -1) { + fprintf(where,"create_looper: chmod; errno %d\n",errno); + fflush(where); + exit(1); + } + + /* with the file descriptor in place, lets be sure that the file is */ + /* large enough. */ + + if (truncate("/tmp/netperf_cpu",file_size) == -1) { + fprintf(where,"create_looper: truncate: errno %d\n",errno); + fflush(where); + exit(1); + } + + /* the file should be large enough now, so we can mmap it */ + + /* if the system does not have MAP_VARIABLE, just define it to */ + /* be zero. it is only used/needed on HP-UX (?) raj 4/95 */ +#ifndef MAP_VARIABLE +#define MAP_VARIABLE 0x0000 +#endif /* MAP_VARIABLE */ +#ifndef MAP_FILE +#define MAP_FILE 0x0000 +#endif /* MAP_FILE */ + if ((lib_base_pointer = (long *)mmap(NULL, + file_size, + PROT_READ | PROT_WRITE, + MAP_FILE | MAP_SHARED | MAP_VARIABLE, + lib_idle_fd, + 0)) == (long *)-1) { + fprintf(where,"create_looper: mmap: errno %d\n",errno); + fflush(where); + exit(1); + } + + + if (debug > 1) { + fprintf(where,"num CPUs %d, file_size %d, lib_base_pointer %p\n", + lib_num_loc_cpus, + file_size, + lib_base_pointer); + fflush(where); + } + + /* we should have a valid base pointer. lets fork */ + + for (i = 0; i < (unsigned int)lib_num_loc_cpus; i++) { + switch (lib_idle_pids[i] = fork()) { + case -1: + perror("netperf: fork"); + exit(1); + case 0: + /* we are the child. we could decide to exec some separate */ + /* program, but that doesn't really seem worthwhile - raj 4/95 */ + + signal(SIGTERM, SIG_DFL); + sit_and_spin(i); + + /* we should never really get here, but if we do, just exit(0) */ + exit(0); + break; + default: + /* we must be the parent */ + lib_idle_address[i] = (uint64_t *) ((char *)lib_base_pointer + + (netlib_get_page_size() * + PAGES_PER_CHILD * i)); + if (debug) { + fprintf(where,"lib_idle_address[%d] is %p\n", + i, + lib_idle_address[i]); + fflush(where); + } + } + } +#else + /* we are compiled -DWIN32 */ + if ((lib_base_pointer = malloc(file_size)) == NULL) { + fprintf(where, + "create_looper_process could not malloc %d bytes\n", + file_size); + fflush(where); + exit(1); + } + + /* now, create all the threads */ + for(i = 0; i < (unsigned int)lib_num_loc_cpus; i++) { + long place_holder; + if ((lib_idle_pids[i] = CreateThread(0, + 0, + (LPTHREAD_START_ROUTINE)sit_and_spin, + (LPVOID)(ULONG_PTR)i, + 0, + &place_holder)) == NULL ) { + fprintf(where, + "create_looper_process: CreateThread failed\n"); + fflush(where); + /* I wonder if I need to look for other threads to kill? */ + exit(1); + } + lib_idle_address[i] = (long *) ((char *)lib_base_pointer + + (netlib_get_page_size() * + PAGES_PER_CHILD * i)); + if (debug) { + fprintf(where,"lib_idle_address[%d] is %p\n", + i, + lib_idle_address[i]); + fflush(where); + } + } +#endif /* WIN32 */ + + /* we need to have the looper processes settled-in before we do */ + /* anything with them, so lets sleep for say 30 seconds. raj 4/95 */ + + sleep(30); +} + +void +cpu_util_init(void) +{ + cpu_method = LOOPER; + + /* we want to get the looper processes going */ + if (!lib_loopers_running) { + start_looper_processes(); + lib_loopers_running = 1; + } + + return; +} + +/* clean-up any left-over CPU util resources - looper processes, + files, whatever. raj 2005-01-26 */ +void +cpu_util_terminate() { + +#ifdef WIN32 + /* it would seem that if/when the process exits, all the threads */ + /* will go away too, so I don't think I need any explicit thread */ + /* killing calls here. raj 1/96 */ +#else + + int i; + + /* now go through and kill-off all the child processes */ + for (i = 0; i < lib_num_loc_cpus; i++){ + /* SIGKILL can leave core files behind - thanks to Steinar Haug */ + /* for pointing that out. */ + kill(lib_idle_pids[i],SIGTERM); + } + lib_loopers_running = 0; + /* reap the children */ + while(waitpid(-1, NULL, WNOHANG) > 0) { } + + /* finally, unlink the mmaped file */ + munmap((caddr_t)lib_base_pointer, + ((netlib_get_page_size() * PAGES_PER_CHILD) * + lib_num_loc_cpus)); + unlink("/tmp/netperf_cpu"); +#endif + return; +} + +int +get_cpu_method(void) +{ + return LOOPER; +} + + /* calibrate_looper */ + + /* Loop a number of iterations, sleeping interval seconds each and */ + /* count how high the idle counter gets each time. Return the */ + /* measured cpu rate to the calling routine. raj 4/95 */ + +float +calibrate_idle_rate (int iterations, int interval) +{ + + uint64_t + firstcnt[MAXCPUS], + secondcnt[MAXCPUS]; + + float + elapsed, + temp_rate, + rate[MAXTIMES], + local_maxrate; + + long + sec, + usec; + + int + i, + j; + + struct timeval time1, time2 ; + struct timezone tz; + + if (iterations > MAXTIMES) { + iterations = MAXTIMES; + } + + local_maxrate = (float)-1.0; + + for(i = 0; i < iterations; i++) { + rate[i] = (float)0.0; + for (j = 0; j < lib_num_loc_cpus; j++) { + firstcnt[j] = *(lib_idle_address[j]); + } + gettimeofday (&time1, &tz); + sleep(interval); + gettimeofday (&time2, &tz); + + if (time2.tv_usec < time1.tv_usec) + { + time2.tv_usec += 1000000; + time2.tv_sec -=1; + } + sec = time2.tv_sec - time1.tv_sec; + usec = time2.tv_usec - time1.tv_usec; + elapsed = (float)sec + ((float)usec/(float)1000000.0); + + if(debug) { + fprintf(where, "Calibration for counter run: %d\n",i); + fprintf(where,"\tsec = %ld usec = %ld\n",sec,usec); + fprintf(where,"\telapsed time = %g\n",elapsed); + } + + for (j = 0; j < lib_num_loc_cpus; j++) { + secondcnt[j] = *(lib_idle_address[j]); + if(debug) { + /* I know that there are situations where compilers know about */ + /* long long, but the library fucntions do not... raj 4/95 */ + fprintf(where, + "\tfirstcnt[%d] = 0x%8.8lx%8.8lx secondcnt[%d] = 0x%8.8lx%8.8lx\n", + j, + (uint32_t)(firstcnt[j]>>32), + (uint32_t)(firstcnt[j]&0xffffffff), + j, + (uint32_t)(secondcnt[j]>>32), + (uint32_t)(secondcnt[j]&0xffffffff)); + } + /* we assume that it would wrap no more than once. we also */ + /* assume that the result of subtracting will "fit" raj 4/95 */ + temp_rate = (secondcnt[j] >= firstcnt[j]) ? + (float)(secondcnt[j] - firstcnt[j])/elapsed : + (float)(secondcnt[j]-firstcnt[j]+MAXLONG)/elapsed; + if (temp_rate > rate[i]) rate[i] = temp_rate; + if(debug) { + fprintf(where,"\trate[%d] = %g\n",i,rate[i]); + fflush(where); + } + if (local_maxrate < rate[i]) local_maxrate = rate[i]; + } + } + if(debug) { + fprintf(where,"\tlocal maxrate = %g per sec. \n",local_maxrate); + fflush(where); + } + return local_maxrate; +} + + +void +get_cpu_idle (uint64_t *res) +{ + int i; + + for (i = 0; i < lib_num_loc_cpus; i++){ + res[i] = *lib_idle_address[i]; + } + +} + +float +calc_cpu_util_internal(float elapsed_time) +{ + int i; + float correction_factor; + float actual_rate; + + lib_local_cpu_util = (float)0.0; + /* It is possible that the library measured a time other than */ + /* the one that the user want for the cpu utilization */ + /* calculations - for example, tests that were ended by */ + /* watchdog timers such as the udp stream test. We let these */ + /* tests tell up what the elapsed time should be. */ + + if (elapsed_time != 0.0) { + correction_factor = (float) 1.0 + + ((lib_elapsed - elapsed_time) / elapsed_time); + } + else { + correction_factor = (float) 1.0; + } + + for (i = 0; i < lib_num_loc_cpus; i++) { + + /* it would appear that on some systems, in loopback, nice is + *very* effective, causing the looper process to stop dead in its + tracks. if this happens, we need to ensure that the calculation + does not go south. raj 6/95 and if we run completely out of idle, + the same thing could in theory happen to the USE_KSTAT path. raj + 8/2000 */ + + if (lib_end_count[i] == lib_start_count[i]) { + lib_end_count[i]++; + } + + actual_rate = (lib_end_count[i] > lib_start_count[i]) ? + (float)(lib_end_count[i] - lib_start_count[i])/lib_elapsed : + (float)(lib_end_count[i] - lib_start_count[i] + + MAXLONG)/ lib_elapsed; + if (debug) { + fprintf(where, + "calc_cpu_util: actual_rate on processor %d is %f start 0x%8.8lx%8.8lx end 0x%8.8lx%8.8lx\n", + i, + actual_rate, + (uint32_t)(lib_start_count[i]>>32), + (uint32_t)(lib_start_count[i]&0xffffffff), + (uint32_t)(lib_end_count[i]>>32), + (uint32_t)(lib_end_count[i]&0xffffffff)); + } + lib_local_per_cpu_util[i] = (lib_local_maxrate - actual_rate) / + lib_local_maxrate * 100; + lib_local_per_cpu_util[i] *= correction_factor; + lib_local_cpu_util += lib_local_per_cpu_util[i]; + } + /* we want the average across all n processors */ + lib_local_cpu_util /= (float)lib_num_loc_cpus; + + return lib_local_cpu_util; +} + +void +cpu_start_internal(void) +{ + get_cpu_idle(lib_start_count); + return; +} + +void +cpu_stop_internal(void) +{ + get_cpu_idle(lib_end_count); +} diff --git a/src/netcpu_none.c b/src/netcpu_none.c new file mode 100644 index 0000000..f71b240 --- /dev/null +++ b/src/netcpu_none.c @@ -0,0 +1,67 @@ +char netcpu_none_id[]="\ +@(#)netcpu_none.c (c) Copyright 2005, Hewlett-Packard Company, Version 2.4.0"; + +#if HAVE_CONFIG_H +# include +#endif + +#include + +#if HAVE_INTTYPES_H +# include +#else +# if HAVE_STDINT_H +# include +# endif +#endif + +#include "netsh.h" +#include "netlib.h" + +void +cpu_util_init(void) +{ + return; +} + +void +cpu_util_terminate(void) +{ + return; +} + +int +get_cpu_method(void) +{ + return CPU_UNKNOWN; +} + +void +get_cpu_idle(uint64_t *res) +{ + return; +} + +float +calibrate_idle_rate(int iterations, int interval) +{ + return 0.0; +} + +float +calc_cpu_util_internal(float elapsed_time) +{ + return -1.0; +} + +void +cpu_start_internal(void) +{ + return; +} + +void +cpu_stop_internal(void) +{ + return; +} diff --git a/src/netcpu_ntperf.c b/src/netcpu_ntperf.c new file mode 100644 index 0000000..72fb621 --- /dev/null +++ b/src/netcpu_ntperf.c @@ -0,0 +1,485 @@ +char netcpu_ntperf_id[]="\ +@(#)netcpu_ntperf.c (c) Copyright 2005-2007, Hewlett-Packard Company, Version 2.4.3"; + +#if HAVE_CONFIG_H +# include +#endif + +#include + +#if HAVE_INTTYPES_H +# include +#else +# if HAVE_STDINT_H +# include +# endif +#endif + +#include +#include + +#include +#include + +#include +// If you are trying to compile on Windows 2000 or NT 4.0 you may +// need to define DONT_IPV6 in the "sources" files. +#ifndef DONT_IPV6 +#include +#endif + +#include "netsh.h" +#include "netlib.h" + +// +// System CPU time information class. +// Used to get CPU time information. +// +// SDK\inc\ntexapi.h +// Function x8: SystemProcessorPerformanceInformation +// DataStructure: SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION +// + +#define SystemProcessorPerformanceInformation 0x08 + +typedef struct +{ + LARGE_INTEGER IdleTime; + LARGE_INTEGER KernelTime; + LARGE_INTEGER UserTime; + LARGE_INTEGER DpcTime; + LARGE_INTEGER InterruptTime; + LONG InterruptCount; +} SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION, *PSYSTEM_PROCESSOR_PERFORMANCE_INFORMATION; + +// +// Calls to get the information +// +typedef ULONG (__stdcall *NT_QUERY_SYSTEM_INFORMATION)( + ULONG SystemInformationClass, + PVOID SystemInformation, + ULONG SystemInformationLength, + PULONG ReturnLength + ); + +NT_QUERY_SYSTEM_INFORMATION NtQuerySystemInformation = NULL; + + +static LARGE_INTEGER TickHz = {{0,0}}; + +_inline LARGE_INTEGER ReadPerformanceCounter(VOID) +{ + LARGE_INTEGER Counter; + QueryPerformanceCounter(&Counter); + + return(Counter); +} // ReadperformanceCounter + + +/* The NT performance data is accessed through the NtQuerySystemInformation + call. References to the PDH.DLL have been deleted. This structure + is the root for these data structures. */ + +typedef struct sPerfObj +{ + LARGE_INTEGER StartTime; + LARGE_INTEGER EndTime; + SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION StartInfo[MAXCPUS +1]; + SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION EndInfo[MAXCPUS +1]; +} PerfObj, *PPerfObj; + +static PerfObj *PerfCntrs; + +// Forward declarations + +PerfObj *InitPerfCntrs(); +void RestartPerfCntrs(PerfObj *PerfCntrs); +double ReportPerfCntrs(PerfObj *PerfCntrs); /* returns CPU utilization */ +void ClosePerfCntrs(PerfObj *PerfCntrs); + + +void +cpu_util_init(void) +{ + if (NtQuerySystemInformation == NULL) { + // Open the performance counter interface + PerfCntrs = InitPerfCntrs(); + } + return; +} + +void +cpu_util_terminate(void) +{ + return; +} + +int +get_cpu_method(void) +{ + return NT_METHOD; +} + +typedef unsigned __int64 uint64_t; + +void +get_cpu_idle(uint64_t *res) +{ + RestartPerfCntrs(PerfCntrs); + return; +} + +float +calibrate_idle_rate(int iterations, int interval) +{ + return (float)0.0; +} + + +/* + InitPerfCntrs() - + + Changed to no longer access the NT performance registry interfaces. + A direct call to NtQuerySystemInformation (an undocumented NT API) + is made instead. Parameters determined by decompilation of ntkrnlmp + and ntdll. +*/ + + +PerfObj *InitPerfCntrs() +{ + PerfObj *NewPerfCntrs; + DWORD NTVersion; + DWORD status; + SYSTEM_INFO SystemInfo; + + GetSystemInfo(&SystemInfo); + + NewPerfCntrs = (PerfObj *)GlobalAlloc(GPTR, sizeof(PerfObj)); + assert(NewPerfCntrs != NULL); + + ZeroMemory((PCHAR)NewPerfCntrs, sizeof(PerfObj)); + + // get NT version + NTVersion = GetVersion(); + if (NTVersion >= 0x80000000) + { + fprintf(stderr, "Not running on Windows NT\n"); + exit(1); + } + + // locate the calls we need in NTDLL + //Lint + NtQuerySystemInformation = + (NT_QUERY_SYSTEM_INFORMATION)GetProcAddress( GetModuleHandle("ntdll.dll"), + "NtQuerySystemInformation" ); + + if ( !(NtQuerySystemInformation) ) + { + //Lint + status = GetLastError(); + fprintf(stderr, "GetProcAddressFailed, status: %lX\n", status); + exit(1); + } + + // setup to measure timestamps with the high resolution timers. + if (QueryPerformanceFrequency(&TickHz) == FALSE) + { + fprintf(stderr,"MAIN - QueryPerformanceFrequency Failed!\n"); + exit(2); + } + + RestartPerfCntrs(NewPerfCntrs); + + return(NewPerfCntrs); +} /* InitPerfCntrs */ + +/* + RestartPerfCntrs() - + + The Performance counters must be read twice to produce rate and + percentage results. This routine is called before the start of a + benchmark to establish the initial counters. It must be called a + second time after the benchmark completes to collect the final state + of the performance counters. ReportPerfCntrs is called to print the + results after the benchmark completes. +*/ + +void RestartPerfCntrs(PerfObj *PerfCntrs) +{ + DWORD returnLength = 0; //Lint + DWORD returnNumCPUs; //Lint + DWORD i; + + DWORD status; + SYSTEM_INFO SystemInfo; + + GetSystemInfo(&SystemInfo); + + // Move previous data from EndInfo to StartInfo. + CopyMemory((PCHAR)&PerfCntrs->StartInfo[0], + (PCHAR)&PerfCntrs->EndInfo[0], + sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION)*(MAXCPUS +1)); + + PerfCntrs->StartTime = PerfCntrs->EndTime; + + // get the current CPUTIME information + if ( (status = NtQuerySystemInformation( SystemProcessorPerformanceInformation, + (PCHAR)&PerfCntrs->EndInfo[0], sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION)*MAXCPUS, + &returnLength )) != 0) + { + fprintf(stderr, "NtQuery failed, status: %lX\n", status); + exit(1); + } + + PerfCntrs->EndTime = ReadPerformanceCounter(); + + // Validate that NtQuery returned a reasonable amount of data + if ((returnLength % sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION)) != 0) + { + fprintf(stderr, "NtQuery didn't return expected amount of data\n"); + fprintf(stderr, "Expected a multiple of %i, returned %lu\n", + sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION), returnLength); + exit(1); + } + returnNumCPUs = returnLength / sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION); + + if (returnNumCPUs != (int)SystemInfo.dwNumberOfProcessors) + { + fprintf(stderr, "NtQuery didn't return expected amount of data\n"); + fprintf(stderr, "Expected data for %i CPUs, returned %lu\n", + (int)SystemInfo.dwNumberOfProcessors, returnNumCPUs); + exit(1); + } + + // Zero entries not returned by NtQuery + ZeroMemory((PCHAR)&PerfCntrs->EndInfo[returnNumCPUs], + sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION)* + (MAXCPUS +1 - returnNumCPUs)); + + // Total all of the CPUs + // KernelTime needs to be fixed-up; it includes both idle & + // true kernel time + // Note that kernel time also includes DpcTime & InterruptTime, but + // I like this. + for (i=0; i < returnNumCPUs; i++) + { + PerfCntrs->EndInfo[i].KernelTime.QuadPart -= PerfCntrs->EndInfo[i].IdleTime.QuadPart; + PerfCntrs->EndInfo[MAXCPUS].IdleTime.QuadPart += PerfCntrs->EndInfo[i].IdleTime.QuadPart; + PerfCntrs->EndInfo[MAXCPUS].KernelTime.QuadPart += PerfCntrs->EndInfo[i].KernelTime.QuadPart; + PerfCntrs->EndInfo[MAXCPUS].UserTime.QuadPart += PerfCntrs->EndInfo[i].UserTime.QuadPart; + PerfCntrs->EndInfo[MAXCPUS].DpcTime.QuadPart += PerfCntrs->EndInfo[i].DpcTime.QuadPart; + PerfCntrs->EndInfo[MAXCPUS].InterruptTime.QuadPart += PerfCntrs->EndInfo[i].InterruptTime.QuadPart; + PerfCntrs->EndInfo[MAXCPUS].InterruptCount += PerfCntrs->EndInfo[i].InterruptCount; + } + +} /* RestartPerfCntrs */ + +/* + ReportPerfCntrs() - + This routine reports the results of the various performance + counters. +*/ + +double ReportPerfCntrs(PerfObj *PerfCntrs) +{ + double tot_CPU_Util; + int i; + double duration; // in milliseconds + + LARGE_INTEGER ActualDuration; + + SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION DeltaInfo[MAXCPUS +1]; + + LARGE_INTEGER TotalCPUTime[MAXCPUS +1]; + + SYSTEM_INFO SystemInfo; + + GetSystemInfo(&SystemInfo); + + for (i=0; i <= MAXCPUS; i++) + { + DeltaInfo[i].IdleTime.QuadPart = PerfCntrs->EndInfo[i].IdleTime.QuadPart - + PerfCntrs->StartInfo[i].IdleTime.QuadPart; + DeltaInfo[i].KernelTime.QuadPart = PerfCntrs->EndInfo[i].KernelTime.QuadPart - + PerfCntrs->StartInfo[i].KernelTime.QuadPart; + DeltaInfo[i].UserTime.QuadPart = PerfCntrs->EndInfo[i].UserTime.QuadPart - + PerfCntrs->StartInfo[i].UserTime.QuadPart; + DeltaInfo[i].DpcTime.QuadPart = PerfCntrs->EndInfo[i].DpcTime.QuadPart - + PerfCntrs->StartInfo[i].DpcTime.QuadPart; + DeltaInfo[i].InterruptTime.QuadPart = PerfCntrs->EndInfo[i].InterruptTime.QuadPart - + PerfCntrs->StartInfo[i].InterruptTime.QuadPart; + DeltaInfo[i].InterruptCount = PerfCntrs->EndInfo[i].InterruptCount - + PerfCntrs->StartInfo[i].InterruptCount; + + TotalCPUTime[i].QuadPart = + DeltaInfo[i].IdleTime.QuadPart + + DeltaInfo[i].KernelTime.QuadPart + + DeltaInfo[i].UserTime.QuadPart; + // KernelTime already includes DpcTime & InterruptTime! + // + DeltaInfo[i].DpcTime.QuadPart + + // DeltaInfo[i].InterruptTime.QuadPart; + } + + tot_CPU_Util = 100.0*(1.0 - (double)DeltaInfo[MAXCPUS].IdleTime.QuadPart/(double)TotalCPUTime[MAXCPUS].QuadPart); //Lint + + // Re-calculate duration, since we may have stoped early due to cntr-C. + ActualDuration.QuadPart = PerfCntrs->EndTime.QuadPart - + PerfCntrs->StartTime.QuadPart; + + // convert to 100 usec (1/10th milliseconds) timebase. + ActualDuration.QuadPart = (ActualDuration.QuadPart*10000)/TickHz.QuadPart; + duration = (double)ActualDuration.QuadPart/10.0; // duration in ms + + if (verbosity > 1) + { + fprintf(where,"ActualDuration (ms): %d\n", (int)duration); + } + + if (verbosity > 1) + { + fprintf(where, "%% CPU _Total"); + if ((int)SystemInfo.dwNumberOfProcessors > 1) + { + for (i=0; i < (int)SystemInfo.dwNumberOfProcessors; i++) + { + fprintf(where, "\t CPU %i", i); + } + } + fprintf(where, "\n"); + + fprintf(where, "Busy %5.2f", tot_CPU_Util); + if ((int)SystemInfo.dwNumberOfProcessors > 1) + { + for (i=0; i < (int)SystemInfo.dwNumberOfProcessors; i++) + { + fprintf(where, "\t %5.2f", + 100.0*(1.0 - (double)DeltaInfo[i].IdleTime.QuadPart/(double)TotalCPUTime[i].QuadPart)); //Lint + } + } + fprintf(where, "\n"); + + fprintf(where, "Kernel %5.2f", + 100.0*(double)DeltaInfo[MAXCPUS].KernelTime.QuadPart/(double)TotalCPUTime[MAXCPUS].QuadPart); //Lint + + if ((int)SystemInfo.dwNumberOfProcessors > 1) + { + for (i=0; i < (int)SystemInfo.dwNumberOfProcessors; i++) + { + fprintf(where, "\t %5.2f", + 100.0*(double)DeltaInfo[i].KernelTime.QuadPart/(double)TotalCPUTime[i].QuadPart); //Lint + } + } + fprintf(where, "\n"); + + fprintf(where, "User %5.2f", + 100.0*(double)DeltaInfo[MAXCPUS].UserTime.QuadPart/(double)TotalCPUTime[MAXCPUS].QuadPart); + + if ((int)SystemInfo.dwNumberOfProcessors > 1) + { + for (i=0; i < (int)SystemInfo.dwNumberOfProcessors; i++) + { + fprintf(where, "\t %5.2f", + 100.0*(double)DeltaInfo[i].UserTime.QuadPart/TotalCPUTime[i].QuadPart); //Lint + } + } + fprintf(where, "\n"); + + fprintf(where, "Dpc %5.2f", + 100.0*(double)DeltaInfo[MAXCPUS].DpcTime.QuadPart/(double)TotalCPUTime[MAXCPUS].QuadPart); //Lint + + if ((int)SystemInfo.dwNumberOfProcessors > 1) + { + for (i=0; i < (int)SystemInfo.dwNumberOfProcessors; i++) + { + fprintf(where, "\t %5.2f", + 100.0*(double)DeltaInfo[i].DpcTime.QuadPart/(double)TotalCPUTime[i].QuadPart); //Lint + } + } + fprintf(where, "\n"); + + fprintf(where, "Interrupt %5.2f", + 100.0*(double)DeltaInfo[MAXCPUS].InterruptTime.QuadPart/(double)TotalCPUTime[MAXCPUS].QuadPart); //Lint + + if ((int)SystemInfo.dwNumberOfProcessors > 1) + { + for (i=0; i < (int)SystemInfo.dwNumberOfProcessors; i++) + { + fprintf(where, "\t %5.2f", + 100.0*(double)DeltaInfo[i].InterruptTime.QuadPart/TotalCPUTime[i].QuadPart); //Lint + } + } + fprintf(where, "\n\n"); + + fprintf(where, "Interrupt/Sec. %5.1f", + (double)DeltaInfo[MAXCPUS].InterruptCount*1000.0/duration); + + if ((int)SystemInfo.dwNumberOfProcessors > 1) + { + for (i=0; i < (int)SystemInfo.dwNumberOfProcessors; i++) + { + fprintf(where, "\t %5.1f", + (double)DeltaInfo[i].InterruptCount*1000.0/duration); + } + } + fprintf(where, "\n\n"); + fflush(where); + } + + return (tot_CPU_Util); + +} /* ReportPerfCntrs */ + +/* + ClosePerfCntrs() - + + This routine cleans up the performance counter APIs. +*/ + +void ClosePerfCntrs(PerfObj *PerfCntrs) +{ + GlobalFree(PerfCntrs); + + NtQuerySystemInformation = NULL; +} /* ClosePerfCntrs */ + +void +cpu_start_internal(void) +{ + RestartPerfCntrs(PerfCntrs); +} + +void +cpu_stop_internal(void) +{ + RestartPerfCntrs(PerfCntrs); +} + +float +calc_cpu_util_internal(float elapsed_time) +{ + float correction_factor; + lib_local_cpu_util = (float)0.0; + /* It is possible that the library measured a time other than */ + /* the one that the user want for the cpu utilization */ + /* calculations - for example, tests that were ended by */ + /* watchdog timers such as the udp stream test. We let these */ + /* tests tell up what the elapsed time should be. */ + + if (elapsed_time != 0.0) { + correction_factor = (float) 1.0 + + ((lib_elapsed - elapsed_time) / elapsed_time); + } + else { + correction_factor = (float) 1.0; + } + + if (debug) { + fprintf(where, "correction factor: %f\n", correction_factor); + } + + lib_local_cpu_util = (float)ReportPerfCntrs(PerfCntrs); + lib_local_cpu_util *= correction_factor; + return lib_local_cpu_util; + +} diff --git a/src/netcpu_osx.c b/src/netcpu_osx.c new file mode 100644 index 0000000..2132be1 --- /dev/null +++ b/src/netcpu_osx.c @@ -0,0 +1,149 @@ +char netcpu_sysctl_id[]="\ +@(#)netcpu_osx.c Version 2.4.3"; + +#if HAVE_CONFIG_H +# include +#endif + +#include + +#if HAVE_INTTYPES_H +# include +#else +# if HAVE_STDINT_H +# include +# endif +#endif + +#if TIME_WITH_SYS_TIME +# include +# include +#else +# if HAVE_SYS_TIME_H +# include +# else +# include +# endif +#endif +#if HAVE_LIMITS_H +# include +# ifndef LONG_LONG_MAX +# define LONG_LONG_MAX LLONG_MAX +# endif /* LONG_LONG_MAX */ +#endif + + +#include + +#include +#include +/* it would seem that on 10.3.9 mach_msg_type_number_t is in + so we'll see about including that one too. + hopefully it still exists in 10.4. if not, we will need to add some + .h file checks in configure so we can use "HAVE_mumble" ifdefs + here */ +#include + +#include "netsh.h" +#include "netlib.h" + +#define UNSIGNED_DIFFERENCE(x,y) (x >= y ? x - y : (0 - y) + x ) + +static host_cpu_load_info_data_t lib_start_ticks; +static host_cpu_load_info_data_t lib_end_ticks; + +static mach_port_t lib_host_port; + +void +cpu_util_init(void) +{ + lib_host_port = mach_host_self(); + return; +} + +void +cpu_util_terminate(void) +{ + mach_port_deallocate(lib_host_port); + return; +} + +int +get_cpu_method(void) +{ + return OSX; +} + +void +get_cpu_idle(uint64_t *res) +{ + return; +} + +void +get_host_ticks(host_cpu_load_info_t info) +{ + mach_msg_type_number_t count; + + count = HOST_CPU_LOAD_INFO_COUNT; + host_statistics(lib_host_port, HOST_CPU_LOAD_INFO, (host_info_t)info, &count); + return; +} + +/* calibrate_sysctl - perform the idle rate calculation using the + sysctl call - typically on BSD */ + +float +calibrate_idle_rate(int iterations, int interval) +{ + return (float)0.0; +} + +float +calc_cpu_util_internal(float elapsed_time) +{ + float correction_factor; + natural_t userticks, systicks, idleticks, totalticks; + + lib_local_cpu_util = (float)0.0; + /* It is possible that the library measured a time other than */ + /* the one that the user want for the cpu utilization */ + /* calculations - for example, tests that were ended by */ + /* watchdog timers such as the udp stream test. We let these */ + /* tests tell up what the elapsed time should be. */ + + if (elapsed_time != 0.0) { + correction_factor = (float) 1.0 + + ((lib_elapsed - elapsed_time) / elapsed_time); + } + else { + correction_factor = (float) 1.0; + } + + if (debug) { + fprintf(where, "correction factor: %f\n", correction_factor); + } + + userticks = UNSIGNED_DIFFERENCE((lib_end_ticks.cpu_ticks[CPU_STATE_USER] + lib_end_ticks.cpu_ticks[CPU_STATE_NICE]), + (lib_start_ticks.cpu_ticks[CPU_STATE_USER] + lib_start_ticks.cpu_ticks[CPU_STATE_NICE])); + systicks = UNSIGNED_DIFFERENCE(lib_end_ticks.cpu_ticks[CPU_STATE_SYSTEM], lib_start_ticks.cpu_ticks[CPU_STATE_SYSTEM]); + idleticks = UNSIGNED_DIFFERENCE(lib_end_ticks.cpu_ticks[CPU_STATE_IDLE], lib_start_ticks.cpu_ticks[CPU_STATE_IDLE]); + totalticks = userticks + systicks + idleticks; + + lib_local_cpu_util = ((float)userticks + (float)systicks)/(float)totalticks * 100.0f; + lib_local_cpu_util *= correction_factor; + + return lib_local_cpu_util; + +} +void +cpu_start_internal(void) +{ + get_host_ticks(&lib_start_ticks); +} + +void +cpu_stop_internal(void) +{ + get_host_ticks(&lib_end_ticks); +} diff --git a/src/netcpu_perfstat.c b/src/netcpu_perfstat.c new file mode 100644 index 0000000..f928a25 --- /dev/null +++ b/src/netcpu_perfstat.c @@ -0,0 +1,351 @@ +char netcpu_perfstat_id[]="\ +@(#)netcpu_perfstat.c Version 2.4.0"; + +#if HAVE_CONFIG_H +# include +#endif + +#include + +#if HAVE_INTTYPES_H +# include +#else +# if HAVE_STDINT_H +# include +# endif +#endif + +#if TIME_WITH_SYS_TIME +# include +# include +#else +# if HAVE_SYS_TIME_H +# include +# else +# include +# endif +#endif + +#if HAVE_LIMITS_H +# include +# ifndef LONG_LONG_MAX +# define LONG_LONG_MAX LLONG_MAX +# endif /* LONG_LONG_MAX */ +#endif + +#include + +#include "netsh.h" +#include "netlib.h" + +/* the lib_start_count and lib_end_count arrays hold the starting + and ending values of whatever is counting when the system is + idle. The rate at which this increments during a test is compared + with a previous calibration to arrive at a CPU utilization + percentage. raj 2005-01-26 */ +static uint64_t lib_start_count[MAXCPUS]; +static uint64_t lib_end_count[MAXCPUS]; + + +void +cpu_util_init(void) +{ + return; +} + +void +cpu_util_terminate(void) +{ + return; +} + +int +get_cpu_method(void) +{ + return PERFSTAT; +} + +void +get_cpu_idle(uint64_t *res) +{ + perfstat_cpu_t *perfstat_buffer; + perfstat_cpu_t *per_cpu_pointer; + perfstat_id_t name; + int i,ret; + + /* a name of "" will cause us to start from the beginning */ + strcpy(name.name,""); + perfstat_buffer = (perfstat_cpu_t *)malloc(lib_num_loc_cpus * + sizeof(perfstat_cpu_t)); + if (perfstat_buffer == NULL) { + fprintf(where, + "cpu_start: malloc failed errno %d\n", + errno); + fflush(where); + exit(-1); + } + + /* happiness and joy, keep going */ + ret = perfstat_cpu(&name, + perfstat_buffer, + sizeof(perfstat_cpu_t), + lib_num_loc_cpus); + + if ((ret == -1) || + (ret != lib_num_loc_cpus)) { + fprintf(where, + "cpu_start: perfstat_cpu failed/count off; errno %d cpus %d count %d\n", + errno, + lib_num_loc_cpus, + ret); + fflush(where); + exit(-1); + } + + per_cpu_pointer = perfstat_buffer; + for (i = 0; i < lib_num_loc_cpus; i++){ + res[i] = per_cpu_pointer->idle; + per_cpu_pointer++; + } + free(perfstat_buffer); + + return; +} + +float +calibrate_idle_rate(int iterations, int interval) +{ + unsigned long long + firstcnt[MAXCPUS], + secondcnt[MAXCPUS]; + + float + elapsed, + temp_rate, + rate[MAXTIMES], + local_maxrate; + + long + sec, + usec; + + int + i, + j; + + struct timeval time1, time2 ; + struct timezone tz; + + perfstat_cpu_t *perfstat_buffer; + perfstat_cpu_t *per_cpu_pointer; + perfstat_id_t name; + int ret; + + if (debug) { + fprintf(where,"enter calibrate_perfstat\n"); + fflush(where); + } + + if (iterations > MAXTIMES) { + iterations = MAXTIMES; + } + + local_maxrate = (float)-1.0; + + perfstat_buffer = (perfstat_cpu_t *)malloc(lib_num_loc_cpus * + sizeof(perfstat_cpu_t)); + if (perfstat_buffer == NULL) { + fprintf(where, + "calibrate_perfstat: malloc failed errno %d\n", + errno); + fflush(where); + exit(-1); + } + + for(i = 0; i < iterations; i++) { + rate[i] = (float)0.0; + /* a name of "" will cause us to start from the beginning */ + strcpy(name.name,""); + + /* happiness and joy, keep going */ + ret = perfstat_cpu(&name, + perfstat_buffer, + sizeof(perfstat_cpu_t), + lib_num_loc_cpus); + + if ((ret == -1) || + (ret != lib_num_loc_cpus)) { + fprintf(where, + "calibrate_perfstat: perfstat_cpu failed/count off; errno %d cpus %d count %d\n", + errno, + lib_num_loc_cpus, + ret); + fflush(where); + exit(-1); + } + + per_cpu_pointer = perfstat_buffer; + for (j = 0; j < lib_num_loc_cpus; j++) { + firstcnt[j] = per_cpu_pointer->idle; + per_cpu_pointer++; + } + gettimeofday (&time1, &tz); + sleep(interval); + gettimeofday (&time2, &tz); + + if (time2.tv_usec < time1.tv_usec) + { + time2.tv_usec += 1000000; + time2.tv_sec -=1; + } + sec = time2.tv_sec - time1.tv_sec; + usec = time2.tv_usec - time1.tv_usec; + elapsed = (float)sec + ((float)usec/(float)1000000.0); + + /* happiness and joy, keep going */ + ret = perfstat_cpu(&name, + perfstat_buffer, + sizeof(perfstat_cpu_t), + lib_num_loc_cpus); + + if ((ret == -1) || + (ret != lib_num_loc_cpus)) { + fprintf(where, + "calibrate_perfstat: perfstat_cpu failed/count off; errno %d cpus %d count %d\n", + errno, + lib_num_loc_cpus, + ret); + fflush(where); + exit(-1); + } + + per_cpu_pointer = perfstat_buffer; + + if(debug) { + fprintf(where, "Calibration for perfstat counter run: %d\n",i); + fprintf(where,"\tsec = %ld usec = %ld\n",sec,usec); + fprintf(where,"\telapsed time = %g\n",elapsed); + } + + for (j = 0; j < lib_num_loc_cpus; j++) { + secondcnt[j] = per_cpu_pointer->idle; + per_cpu_pointer++; + if(debug) { + /* I know that there are situations where compilers know about */ + /* long long, but the library functions do not... raj 4/95 */ + fprintf(where, + "\tfirstcnt[%d] = 0x%8.8lx%8.8lx secondcnt[%d] = 0x%8.8lx%8.8lx\n", + j, + firstcnt[j], + firstcnt[j], + j, + secondcnt[j], + secondcnt[j]); + } + /* we assume that it would wrap no more than once. we also */ + /* assume that the result of subtracting will "fit" raj 4/95 */ + temp_rate = (secondcnt[j] >= firstcnt[j]) ? + (float)(secondcnt[j] - firstcnt[j])/elapsed : + (float)(secondcnt[j]-firstcnt[j]+MAXLONG)/elapsed; + if (temp_rate > rate[i]) rate[i] = temp_rate; + if(debug) { + fprintf(where,"\trate[%d] = %g\n",i,rate[i]); + fflush(where); + } + if (local_maxrate < rate[i]) local_maxrate = rate[i]; + } + } + if(debug) { + fprintf(where,"\tlocal maxrate = %g per sec. \n",local_maxrate); + fflush(where); + } + free(perfstat_buffer); + return local_maxrate; +} + +float +calc_cpu_util_internal(float elapsed_time) +{ + int i; + + float actual_rate; + float correction_factor; + + lib_local_cpu_util = (float)0.0; + /* It is possible that the library measured a time other than */ + /* the one that the user want for the cpu utilization */ + /* calculations - for example, tests that were ended by */ + /* watchdog timers such as the udp stream test. We let these */ + /* tests tell up what the elapsed time should be. */ + + if (elapsed_time != 0.0) { + correction_factor = (float) 1.0 + + ((lib_elapsed - elapsed_time) / elapsed_time); + } + else { + correction_factor = (float) 1.0; + } + + /* this looks just like the looper case. at least I think it */ + /* should :) raj 4/95 */ + for (i = 0; i < lib_num_loc_cpus; i++) { + + /* we assume that the two are not more than a long apart. I */ + /* know that this is bad, but trying to go from long longs to */ + /* a float (perhaps a double) is boggling my mind right now. */ + /* raj 4/95 */ + + long long + diff; + + if (lib_end_count[i] >= lib_start_count[i]) { + diff = lib_end_count[i] - lib_start_count[i]; + } + else { + diff = lib_end_count[i] - lib_start_count[i] + LONG_LONG_MAX; + } + actual_rate = (float) diff / lib_elapsed; + lib_local_per_cpu_util[i] = (lib_local_maxrate - actual_rate) / + lib_local_maxrate * 100; + lib_local_cpu_util += lib_local_per_cpu_util[i]; + if (debug) { + fprintf(where, + "calc_cpu_util: actual_rate on cpu %d is %g max_rate %g cpu %6.2f\n", + i, + actual_rate, + lib_local_maxrate, + lib_local_per_cpu_util[i]); + } + } + + /* we want the average across all n processors */ + lib_local_cpu_util /= (float)lib_num_loc_cpus; + + if (debug) { + fprintf(where, + "calc_cpu_util: average across CPUs is %g\n",lib_local_cpu_util); + } + + lib_local_cpu_util *= correction_factor; + + if (debug) { + fprintf(where, + "calc_cpu_util: returning %g\n",lib_local_cpu_util); + } + + return lib_local_cpu_util; + +} +void +cpu_start_internal(void) +{ + get_cpu_idle(lib_start_count); + return; +} + +void +cpu_stop_internal(void) +{ + get_cpu_idle(lib_end_count); +} + diff --git a/src/netcpu_procstat.c b/src/netcpu_procstat.c new file mode 100644 index 0000000..0d59a8c --- /dev/null +++ b/src/netcpu_procstat.c @@ -0,0 +1,353 @@ +char netcpu_procstat_id[]="\ +@(#)netcpu_procstat.c (c) Copyright 2005-2007 Version 2.4.3"; + +/* netcpu_procstat.c + + Implement the /proc/stat specific portions of netperf CPU + utilization measurements. These are broken-out into a separate file + to make life much nicer over in netlib.c which had become a maze of + twisty, CPU-util-related, #ifdefs, all different. raj 2005-01-26 + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include + +#ifdef HAVE_FCNTL_H +# include +#endif +#if HAVE_UNISTD_H +# include +#endif +#if STDC_HEADERS +# include +# include +#else +# if HAVE_STDLIB_H +# include +# endif +#endif + +#include + +#include "netsh.h" +#include "netlib.h" + +/* the lib_start_count and lib_end_count arrays hold the starting + and ending values of whatever is counting when the system is + idle. The rate at which this increments during a test is compared + with a previous calibrarion to arrive at a CPU utilization + percentage. raj 2005-01-26 */ + +#define IDLE_IDX 4 +#define CPU_STATES 9 + +typedef struct cpu_states +{ + uint64_t user; + uint64_t nice; + uint64_t sys; + uint64_t idle; + uint64_t iowait; + uint64_t hard_irq; + uint64_t soft_irq; + uint64_t steal; + uint64_t guest; +} cpu_states_t; + +static cpu_states_t lib_start_count[MAXCPUS]; +static cpu_states_t lib_end_count[MAXCPUS]; + + +/* The max. length of one line of /proc/stat cpu output */ +#define CPU_LINE_LENGTH ((CPU_STATES * sizeof (long) / 3 + 1) * 4 + 8) +#define PROC_STAT_FILE_NAME "/proc/stat" +#define N_CPU_LINES(nr) (nr == 1 ? 1 : 1 + nr) + +static int proc_stat_fd = -1; +static char *proc_stat_buf = NULL; +static int proc_stat_buflen = 0; + +void +cpu_util_init(void) +{ + + if (debug) { + fprintf(where, + "cpu_util_init enter, proc_stat_fd %d proc_stat_buf %p\n", + proc_stat_fd, + proc_stat_buf); + fflush(where); + } + if (proc_stat_fd < 0) { + proc_stat_fd = open (PROC_STAT_FILE_NAME, O_RDONLY, NULL); + if (proc_stat_fd < 0) { + fprintf (stderr, "Cannot open %s!\n", PROC_STAT_FILE_NAME); + exit (1); + }; + }; + + if (!proc_stat_buf) { + proc_stat_buflen = N_CPU_LINES (lib_num_loc_cpus) * CPU_LINE_LENGTH; + if (debug) { + fprintf(where, + "lib_num_loc_cpus %d lines %d CPU_LINE_LENGTH %d proc_stat_buflen %d\n", + lib_num_loc_cpus, + N_CPU_LINES(lib_num_loc_cpus), + CPU_LINE_LENGTH, + proc_stat_buflen); + fflush(where); + } + proc_stat_buf = (char *)malloc (proc_stat_buflen); + if (!proc_stat_buf) { + fprintf (stderr, "Cannot allocate buffer memory!\n"); + exit (1); + } + } + return; +} + +void +cpu_util_terminate(void) +{ + close(proc_stat_fd); + proc_stat_fd = -1; + free(proc_stat_buf); + proc_stat_buf = NULL; + return; +} + +int +get_cpu_method() +{ + return PROC_STAT; +} + +float +calibrate_idle_rate (int iterations, int interval) +{ + if (proc_stat_fd < 0) { + proc_stat_fd = open (PROC_STAT_FILE_NAME, O_RDONLY, NULL); + if (proc_stat_fd < 0) { + fprintf (stderr, "Cannot open %s!\n", PROC_STAT_FILE_NAME); + exit (1); + }; + }; + + if (!proc_stat_buf) { + proc_stat_buflen = N_CPU_LINES (lib_num_loc_cpus) * CPU_LINE_LENGTH; + if (debug) { + fprintf(where, + "calibrate: lib_num_loc_cpus %d lines %d CPU_LINE_LENGTH %d proc_stat_buflen %d\n", + lib_num_loc_cpus, + N_CPU_LINES(lib_num_loc_cpus), + CPU_LINE_LENGTH, + proc_stat_buflen); + fflush(where); + } + proc_stat_buf = (char *)malloc (proc_stat_buflen); + if (!proc_stat_buf) { + fprintf (stderr, "Cannot allocate buffer memory!\n"); + exit (1); + }; + }; + + return sysconf (_SC_CLK_TCK); +} + +static void +get_cpu (cpu_states_t *res) +{ + int space; + int i; + int n = lib_num_loc_cpus; + char *p = proc_stat_buf; + + lseek (proc_stat_fd, 0, SEEK_SET); + read (proc_stat_fd, p, proc_stat_buflen); + + if (debug) { + fprintf(where,"proc_stat_buf '%.*s'\n",proc_stat_buflen,p); + fflush(where); + } + /* Skip first line (total) on SMP */ + if (n > 1) p = strchr (p, '\n'); + + for (i = 0; i < n; i++) { + memset(&res[i], 0, sizeof (&res[i])); + p = strchr (p, ' '); + sscanf(p, "%llu %llu %llu %llu %llu %llu %llu %llu %llu", + (unsigned long long *)&res[i].user, + (unsigned long long *)&res[i].nice, + (unsigned long long *)&res[i].sys, + (unsigned long long *)&res[i].idle, + (unsigned long long *)&res[i].iowait, + (unsigned long long *)&res[i].hard_irq, + (unsigned long long *)&res[i].soft_irq, + (unsigned long long *)&res[i].steal, + (unsigned long long *)&res[i].guest); + if (debug) { + fprintf(where,"res[%d] is %llu %llu %llu %llu %llu %llu %llu %llu %llu\n", + i, + (unsigned long long)res[i].user, + (unsigned long long)res[i].nice, + (unsigned long long)res[i].sys, + (unsigned long long)res[i].idle, + (unsigned long long)res[i].iowait, + (unsigned long long)res[i].hard_irq, + (unsigned long long)res[i].soft_irq, + (unsigned long long)res[i].steal, + (unsigned long long)res[i].guest); + fflush(where); + } + p = strchr (p, '\n'); + }; + +} + +/* take the initial timestamp and start collecting CPU utilization if + requested */ + +void +measure_cpu_start() +{ + cpu_method = PROC_STAT; + get_cpu(lib_start_count); +} + +/* collect final CPU utilization raw data */ +void +measure_cpu_stop() +{ + get_cpu(lib_end_count); +} + +static uint64_t +tick_subtract(uint64_t start, uint64_t end) +{ + uint64_t ret; + + if (end >= start || (start & 0xffffffff00000000ULL)) + return (end - start); + + /* + * We wrapped, and it is likely that the kernel is suppling 32-bit + * counters, because "start" is less than 32-bits wide. If that's + * the case, then handle the wrap by subtracting off everything but + * the lower 32-bits so as to get back to unsigned 32-bit + * arithmetic. + */ + return (end - start + 0xffffffff00000000ULL); +} + +float +calc_cpu_util_internal(float elapsed_time) +{ + int i, j; + + float correction_factor; + cpu_states_t diff; + uint64_t total_ticks; + + lib_local_cpu_util = (float)0.0; + + /* It is possible that the library measured a time other than the + one that the user want for the cpu utilization calculations - for + example, tests that were ended by watchdog timers such as the udp + stream test. We let these tests tell up what the elapsed time + should be. */ + + if (elapsed_time != 0.0) { + correction_factor = (float) 1.0 + + ((lib_elapsed - elapsed_time) / elapsed_time); + } + else { + correction_factor = (float) 1.0; + } + + if (debug) { + fprintf(where, + "lib_local_maxrate = %f\n", lib_local_maxrate); + } + for (i = 0; i < lib_num_loc_cpus; i++) { + + /* it would appear that on some systems, in loopback, nice is + *very* effective, causing the looper process to stop dead in its + tracks. if this happens, we need to ensure that the calculation + does not go south. raj 6/95 and if we run completely out of idle, + the same thing could in theory happen to the USE_KSTAT path. raj + 8/2000 */ + + /* Find the difference in all CPU stat fields */ + diff.user = + tick_subtract(lib_start_count[i].user, lib_end_count[i].user); + diff.nice = + tick_subtract(lib_start_count[i].nice, lib_end_count[i].nice); + diff.sys = + tick_subtract(lib_start_count[i].sys, lib_end_count[i].sys); + diff.idle = + tick_subtract(lib_start_count[i].idle, lib_end_count[i].idle); + diff.iowait = + tick_subtract(lib_start_count[i].iowait, lib_end_count[i].iowait); + diff.hard_irq = + tick_subtract(lib_start_count[i].hard_irq, lib_end_count[i].hard_irq); + diff.soft_irq = + tick_subtract(lib_start_count[i].soft_irq, lib_end_count[i].soft_irq); + diff.steal = + tick_subtract(lib_start_count[i].steal, lib_end_count[i].steal); + diff.guest = + tick_subtract(lib_start_count[i].guest, lib_end_count[i].guest); + total_ticks = diff.user + diff.nice + diff.sys + diff.idle + diff.iowait + + diff.hard_irq + diff.soft_irq + diff.steal + diff.guest; + + /* calculate idle time as a percentage of all CPU states */ + if (total_ticks == 0) { + fprintf(stderr, "Total ticks 0 on CPU %d, charging nothing!\n", i); + lib_local_per_cpu_util[i] = 100.0; + } else { + lib_local_per_cpu_util[i] = 100.0 * + ((float) diff.idle / (float) total_ticks); + } + /* invert percentage to reflect non-idle time */ + lib_local_per_cpu_util[i] = 100.0 - lib_local_per_cpu_util[i]; + + /* apply correction factor */ + lib_local_per_cpu_util[i] *= correction_factor; + if (debug) { + fprintf(where, + "calc_cpu_util: util on processor %d, diff = %llu %llu %llu %llu %llu %llu %llu %llu %llu util %f cf %f\n", + i, + (unsigned long long)diff.user, + (unsigned long long)diff.nice, + (unsigned long long)diff.sys, + (unsigned long long)diff.idle, + (unsigned long long)diff.iowait, + (unsigned long long)diff.hard_irq, + (unsigned long long)diff.soft_irq, + (unsigned long long)diff.steal, + (unsigned long long)diff.guest, + lib_local_per_cpu_util[i], + correction_factor); + } + lib_local_cpu_util += lib_local_per_cpu_util[i]; + } + /* we want the average across all n processors */ + lib_local_cpu_util /= (float)lib_num_loc_cpus; + + return lib_local_cpu_util; +} + +void +cpu_start_internal(void) +{ + get_cpu(lib_start_count); + return; +} + +void +cpu_stop_internal(void) +{ + get_cpu(lib_end_count); +} diff --git a/src/netcpu_pstat.c b/src/netcpu_pstat.c new file mode 100644 index 0000000..043f822 --- /dev/null +++ b/src/netcpu_pstat.c @@ -0,0 +1,302 @@ +char netcpu_pstat_id[]="\ +@(#)netcpu_pstat.c (c) Copyright 2005, Hewlett-Packard Company, Version 2.4.0"; + +#if HAVE_CONFIG_H +# include +#endif + +#include + +#if HAVE_INTTYPES_H +# include +#else +# if HAVE_STDINT_H +# include +# endif +#endif + +#if HAVE_LIMITS_H +# include +#endif + +#include +#include + +#ifndef PSTAT_IPCINFO +# error Sorry, pstat() CPU utilization on 10.0 and later only +#endif + +#include "netsh.h" +#include "netlib.h" + +/* the lib_start_count and lib_end_count arrays hold the starting + and ending values of whatever is counting when the system is + idle. The rate at which this increments during a test is compared + with a previous calibrarion to arrive at a CPU utilization + percentage. raj 2005-01-26 */ +static uint64_t lib_start_count[MAXCPUS]; +static uint64_t lib_end_count[MAXCPUS]; + +void +cpu_util_init(void) +{ + return; +} + +void +cpu_util_terminate(void) +{ + return; +} + +int +get_cpu_method(void) +{ + return HP_IDLE_COUNTER; +} + +void +get_cpu_idle(uint64_t *res) +{ + /* get the idle sycle counter for each processor */ + struct pst_processor *psp; + union overlay_u { + long long full; + long word[2]; + } *overlay; + + psp = (struct pst_processor *)malloc(lib_num_loc_cpus * sizeof(*psp)); + if (psp == NULL) { + printf("malloc(%d) failed!\n", lib_num_loc_cpus * sizeof(*psp)); + exit(1); + } + if (pstat_getprocessor(psp, sizeof(*psp), lib_num_loc_cpus, 0) != -1) { + int i; + for (i = 0; i < lib_num_loc_cpus; i++) { + overlay = (union overlay_u *)&(res[i]); + overlay->word[0] = psp[i].psp_idlecycles.psc_hi; + overlay->word[1] = psp[i].psp_idlecycles.psc_lo; + if(debug) { + fprintf(where, + "\tres[%d] = 0x%8.8x%8.8x\n", + i, + hi_32(&res[i]), + lo_32(&res[i])); + fflush(where); + } + } + free(psp); + } +} + +/* calibrate_pstat + Loop a number of iterations, sleeping wait_time seconds each and + count how high the idle counter gets each time. Return the measured + cpu rate to the calling routine. */ + +float +calibrate_idle_rate(int iterations, int interval) +{ + + uint64_t + firstcnt[MAXCPUS], + secondcnt[MAXCPUS]; + + float + elapsed, + temp_rate, + rate[MAXTIMES], + local_maxrate; + + long + sec, + usec; + + int + i, + j; + + long count; + + struct timeval time1, time2; + struct timezone tz; + + struct pst_processor *psp; + + if (iterations > MAXTIMES) { + iterations = MAXTIMES; + } + + local_maxrate = -1.0; + + psp = (struct pst_processor *)malloc(lib_num_loc_cpus * sizeof(*psp)); + if (psp == NULL) { + printf("malloc(%d) failed!\n", lib_num_loc_cpus * sizeof(*psp)); + exit(1); + } + + for(i = 0; i < iterations; i++) { + rate[i] = 0.0; + /* get the idle sycle counter for each processor */ + if (pstat_getprocessor(psp, sizeof(*psp), lib_num_loc_cpus, 0) != -1) { + for (j = 0; j < lib_num_loc_cpus; j++) { + union overlay_u { + long long full; + long word[2]; + } *overlay; + overlay = (union overlay_u *)&(firstcnt[j]); + overlay->word[0] = psp[j].psp_idlecycles.psc_hi; + overlay->word[1] = psp[j].psp_idlecycles.psc_lo; + } + } + else { + fprintf(where,"pstat_getprocessor failure errno %d\n",errno); + fflush(where); + exit(1); + } + + gettimeofday (&time1, &tz); + sleep(interval); + gettimeofday (&time2, &tz); + + if (time2.tv_usec < time1.tv_usec) + { + time2.tv_usec += 1000000; + time2.tv_sec -=1; + } + sec = time2.tv_sec - time1.tv_sec; + usec = time2.tv_usec - time1.tv_usec; + elapsed = (float)sec + ((float)usec/(float)1000000.0); + + if(debug) { + fprintf(where, "Calibration for counter run: %d\n",i); + fprintf(where,"\tsec = %ld usec = %ld\n",sec,usec); + fprintf(where,"\telapsed time = %g\n",elapsed); + } + + if (pstat_getprocessor(psp, sizeof(*psp), lib_num_loc_cpus, 0) != -1) { + for (j = 0; j < lib_num_loc_cpus; j++) { + union overlay_u { + long long full; + long word[2]; + } *overlay; + overlay = (union overlay_u *)&(secondcnt[j]); + overlay->word[0] = psp[j].psp_idlecycles.psc_hi; + overlay->word[1] = psp[j].psp_idlecycles.psc_lo; + if(debug) { + /* I know that there are situations where compilers know about */ + /* long long, but the library fucntions do not... raj 4/95 */ + fprintf(where, + "\tfirstcnt[%d] = 0x%8.8x%8.8x secondcnt[%d] = 0x%8.8x%8.8x\n", + j, + hi_32(&firstcnt[j]), + lo_32(&firstcnt[j]), + j, + hi_32(&secondcnt[j]), + lo_32(&secondcnt[j])); + } + temp_rate = (secondcnt[j] >= firstcnt[j]) ? + (float)(secondcnt[j] - firstcnt[j] )/elapsed : + (float)(secondcnt[j] - firstcnt[j] + LONG_LONG_MAX)/elapsed; + if (temp_rate > rate[i]) rate[i] = temp_rate; + if(debug) { + fprintf(where,"\trate[%d] = %g\n",i,rate[i]); + fflush(where); + } + if (local_maxrate < rate[i]) local_maxrate = rate[i]; + } + } + else { + fprintf(where,"pstat failure; errno %d\n",errno); + fflush(where); + exit(1); + } + } + if(debug) { + fprintf(where,"\tlocal maxrate = %g per sec. \n",local_maxrate); + fflush(where); + } + return local_maxrate; + +} + +float +calc_cpu_util_internal(float elapsed_time) +{ + int i; + + float actual_rate; + float correction_factor; + + lib_local_cpu_util = (float)0.0; + /* It is possible that the library measured a time other than */ + /* the one that the user want for the cpu utilization */ + /* calculations - for example, tests that were ended by */ + /* watchdog timers such as the udp stream test. We let these */ + /* tests tell up what the elapsed time should be. */ + + if (elapsed_time != 0.0) { + correction_factor = (float) 1.0 + + ((lib_elapsed - elapsed_time) / elapsed_time); + } + else { + correction_factor = (float) 1.0; + } + + /* this looks just like the looper case. at least I think it */ + /* should :) raj 4/95 */ + for (i = 0; i < lib_num_loc_cpus; i++) { + + /* we assume that the two are not more than a long apart. I */ + /* know that this is bad, but trying to go from long longs to */ + /* a float (perhaps a double) is boggling my mind right now. */ + /* raj 4/95 */ + + long long + diff; + + if (lib_end_count[i] >= lib_start_count[i]) { + diff = lib_end_count[i] - lib_start_count[i]; + } + else { + diff = lib_end_count[i] - lib_start_count[i] + LONG_LONG_MAX; + } + actual_rate = (float) diff / lib_elapsed; + lib_local_per_cpu_util[i] = (lib_local_maxrate - actual_rate) / + lib_local_maxrate * 100; + lib_local_per_cpu_util[i] *= correction_factor; + lib_local_cpu_util += lib_local_per_cpu_util[i]; + if (debug) { + fprintf(where, + "calc_cpu_util: actual_rate on cpu %d is %g max_rate %g cpu %6.2f cf %f\n", + i, + actual_rate, + lib_local_maxrate, + lib_local_per_cpu_util[i], + correction_factor); + } + } + + /* we want the average across all n processors */ + lib_local_cpu_util /= (float)lib_num_loc_cpus; + + if (debug) { + fprintf(where, + "calc_cpu_util: average across CPUs is %g\n",lib_local_cpu_util); + } + + return lib_local_cpu_util; + +} +void +cpu_start_internal(void) +{ + get_cpu_idle(lib_start_count); + return; +} + +void +cpu_stop_internal(void) +{ + get_cpu_idle(lib_end_count); +} diff --git a/src/netcpu_pstatnew.c b/src/netcpu_pstatnew.c new file mode 100644 index 0000000..c342baa --- /dev/null +++ b/src/netcpu_pstatnew.c @@ -0,0 +1,398 @@ +char netcpu_pstatnew_id[]="\ +@(#)netcpu_pstatnew.c (c) Copyright 2005, Hewlett-Packard Company, Version 2.4.1"; + +/* since we "know" that this interface is available only on 11.23 and + later, and that 11.23 and later are strictly 64-bit kernels, we can + arbitrarily set _PSTAT64 here and not have to worry about it up in + the configure script and makefiles. raj 2005/09/06 */ + +#if HAVE_CONFIG_H +# include +#endif + +#include + +#if HAVE_INTTYPES_H +# include +#else +# if HAVE_STDINT_H +# include +# endif +#endif + +#include + +#if HAVE_LIMITS_H +# include +#endif + +#include +#include + +/* HP-UX 11.23 seems to have added three other cycle counters to the + original psp_idlecycles - one for user, one for kernel and one for + interrupt. so, we can now use those to calculate CPU utilization + without requiring any calibration phase. raj 2005-02-16 */ + +#ifndef PSTAT_IPCINFO +# error Sorry, pstat() CPU utilization on 10.0 and later only +#endif + +typedef struct cpu_time_counters { + uint64_t idle; + uint64_t user; + uint64_t kernel; + uint64_t interrupt; +} cpu_time_counters_t; + +uint64_t lib_iticksperclktick; + +#include "netsh.h" +#include "netlib.h" + +/* the lib_start_count and lib_end_count arrays hold the starting + and ending values of whatever is counting when the system is + idle. The rate at which this increments during a test is compared + with a previous calibrarion to arrive at a CPU utilization + percentage. raj 2005-01-26 */ + +static cpu_time_counters_t starting_cpu_counters[MAXCPUS]; +static cpu_time_counters_t ending_cpu_counters[MAXCPUS]; +static cpu_time_counters_t delta_cpu_counters[MAXCPUS]; + +void +cpu_util_init(void) +{ + return; +} + +void +cpu_util_terminate(void) +{ + return; +} + +int +get_cpu_method(void) +{ + return HP_IDLE_COUNTER; +} + +void +get_cpu_counters(cpu_time_counters_t *res) +{ + /* get the idle sycle counter for each processor. now while on a + 64-bit kernel the ".psc_hi" and ".psc_lo" fields are 64 bits, + only the bottom 32-bits are actually valid. don't ask me + why, that is just the way it is. soo, we shift the psc_hi + value by 32 bits and then just sum-in the psc_lo value. raj + 2005/09/06 */ + struct pst_processor *psp; + + psp = (struct pst_processor *)malloc(lib_num_loc_cpus * sizeof(*psp)); + if (psp == NULL) { + printf("malloc(%d) failed!\n", lib_num_loc_cpus * sizeof(*psp)); + exit(1); + } + if (pstat_getprocessor(psp, sizeof(*psp), lib_num_loc_cpus, 0) != -1) { + int i; + /* we use lib_iticksperclktick in our sanity checking. we + ass-u-me it is the same value for each CPU - famous last + words no doubt. raj 2005/09/06 */ + lib_iticksperclktick = psp[0].psp_iticksperclktick; + for (i = 0; i < lib_num_loc_cpus; i++) { + res[i].idle = (((uint64_t)psp[i].psp_idlecycles.psc_hi << 32) + + psp[i].psp_idlecycles.psc_lo); + if(debug) { + fprintf(where, + "\tidle[%d] = 0x%"PRIx64" ", + i, + res[i].idle); + fflush(where); + } + res[i].user = (((uint64_t)psp[i].psp_usercycles.psc_hi << 32) + + psp[i].psp_usercycles.psc_lo); + if(debug) { + fprintf(where, + "user[%d] = 0x%"PRIx64" ", + i, + res[i].user); + fflush(where); + } + res[i].kernel = (((uint64_t)psp[i].psp_systemcycles.psc_hi << 32) + + psp[i].psp_systemcycles.psc_lo); + if(debug) { + fprintf(where, + "kern[%d] = 0x%"PRIx64" ", + i, + res[i].kernel); + fflush(where); + } + res[i].interrupt = (((uint64_t)psp[i].psp_interruptcycles.psc_hi << 32) + + psp[i].psp_interruptcycles.psc_lo); + if(debug) { + fprintf(where, + "intr[%d] = 0x%"PRIx64"\n", + i, + res[i].interrupt); + fflush(where); + } + } + free(psp); + } +} + +/* calibrate_pstatnew + there really isn't anything much to do here since we have all the + counters and use their ratios for CPU util measurement. raj + 2005-02-16 */ + +float +calibrate_idle_rate(int iterations, int interval) +{ + return 0.0; +} + +static void +print_cpu_time_counters(char *name, int instance, cpu_time_counters_t *counters) +{ + fprintf(where,"%s[%d]:\n",name,instance); + fprintf(where, + "\t idle %llu\n",counters[instance].idle); + fprintf(where, + "\t user %llu\n",counters[instance].user); + fprintf(where, + "\t kernel %llu\n",counters[instance].kernel); + fprintf(where, + "\t interrupt %llu\n",counters[instance].interrupt); +} + +float +calc_cpu_util_internal(float elapsed_time) +{ + int i; + + uint64_t total_cpu_cycles; + uint64_t sanity_cpu_cycles; + +#ifndef USE_INTEGER_MATH + double fraction_idle; + double fraction_user; + double fraction_kernel; + double fraction_interrupt; + double estimated_fraction_interrupt; +#else + uint64_t fraction_idle; + uint64_t fraction_user; + uint64_t fraction_kernel; + uint64_t fraction_interrupt; + uint64_t estimated_fraction_interrupt; + +#define CALC_PERCENT 100 +#define CALC_TENTH_PERCENT 1000 +#define CALC_HUNDREDTH_PERCENT 10000 +#define CALC_THOUSANDTH_PERCENT 100000 +#define CALC_ACCURACY CALC_THOUSANDTH_PERCENT + +#endif /* USE_INTEGER_MATH */ + float actual_rate; + float correction_factor; + + lib_local_cpu_util = (float)0.0; + + /* It is possible that the library measured a time other than */ + /* the one that the user want for the cpu utilization */ + /* calculations - for example, tests that were ended by */ + /* watchdog timers such as the udp stream test. We let these */ + /* tests tell up what the elapsed time should be. */ + + if (elapsed_time != 0.0) { + correction_factor = (float) 1.0 + + ((lib_elapsed - elapsed_time) / elapsed_time); + } + else { + correction_factor = (float) 1.0; + } + + /* calculate our sanity check on cycles */ + if (debug) { + fprintf(where, + "lib_elapsed %g _SC_CLK_TCK %d lib_iticksperclktick %"PRIu64"\n", + lib_elapsed, + sysconf(_SC_CLK_TCK), + lib_iticksperclktick); + } + + /* Ok, elsewhere I may have said that HP-UX 11.23 does the "right" + thing in measuring user, kernel, interrupt and idle all together + instead of overlapping interrupt with the others like an OS that + shall not be named. However.... it seems there is a bug in the + accounting for interrupt cycles, whereby the cycles do not get + properly accounted. The sum of user, kernel, interrupt and idle + does not equal the clock rate multiplied by the elapsed time. + Some cycles go missing. + + Since we see agreement between netperf and glance/vsar with the + old "pstat" mechanism, we can presume that the accounting for + idle cycles is sufficiently accurate. So, while we will still do + math with user, kernel and interrupt cycles, we will only + caculate CPU utilization based on the ratio of idle to _real_ + total cycles. I am told that a "future release" of HP-UX will + fix the interupt cycle accounting. raj 2005/09/14 */ + + /* calculate what the sum of CPU cycles _SHOULD_ be */ + sanity_cpu_cycles = (uint64_t) ((double)lib_elapsed * + (double) sysconf(_SC_CLK_TCK) * (double)lib_iticksperclktick); + + /* this looks just like the looper case. at least I think it */ + /* should :) raj 4/95 */ + for (i = 0; i < lib_num_loc_cpus; i++) { + + /* we ass-u-me that these counters will never wrap during a + netperf run. this may not be a particularly safe thing to + do. raj 2005-01-28 */ + delta_cpu_counters[i].idle = ending_cpu_counters[i].idle - + starting_cpu_counters[i].idle; + delta_cpu_counters[i].user = ending_cpu_counters[i].user - + starting_cpu_counters[i].user; + delta_cpu_counters[i].kernel = ending_cpu_counters[i].kernel - + starting_cpu_counters[i].kernel; + delta_cpu_counters[i].interrupt = ending_cpu_counters[i].interrupt - + starting_cpu_counters[i].interrupt; + + if (debug) { + print_cpu_time_counters("delta_cpu_counters",i,delta_cpu_counters); + } + + /* now get the sum, which we ass-u-me does not overflow a 64-bit + counter. raj 2005-02-16 */ + total_cpu_cycles = + delta_cpu_counters[i].idle + + delta_cpu_counters[i].user + + delta_cpu_counters[i].kernel + + delta_cpu_counters[i].interrupt; + + if (debug) { + fprintf(where, + "total_cpu_cycles %"PRIu64" sanity_cpu_cycles %"PRIu64" missing %"PRIu64"\n", + total_cpu_cycles, + sanity_cpu_cycles, + sanity_cpu_cycles - total_cpu_cycles); + } + + /* since HP-UX 11.23 does the _RIGHT_ thing and idle/user/kernel + does _NOT_ overlap with interrupt, we do not have to apply any + correction kludge. raj 2005-02-16 */ + +#ifndef USE_INTEGER_MATH + /* when the accounting for interrupt time gets its act together, + we can use total_cpu_cycles rather than sanity_cpu_cycles, but + until then, use sanity_cpu_ccles. raj 2005/09/14 */ + + fraction_idle = (double)delta_cpu_counters[i].idle / + (double)sanity_cpu_cycles; + + fraction_user = (double)delta_cpu_counters[i].user / + (double)sanity_cpu_cycles; + + fraction_kernel = (double) delta_cpu_counters[i].kernel / + (double)sanity_cpu_cycles; + + fraction_interrupt = (double)delta_cpu_counters[i].interrupt / + (double)sanity_cpu_cycles; + + /* ass-u-me that it is only interrupt that is bogus, and assign + all the "missing" cycles to it. raj 2005/09/14 */ + estimated_fraction_interrupt = ((double)delta_cpu_counters[i].interrupt + + (sanity_cpu_cycles - total_cpu_cycles)) / + (double)sanity_cpu_cycles; + + if (debug) { + fprintf(where,"\tfraction_idle %g\n",fraction_idle); + fprintf(where,"\tfraction_user %g\n",fraction_user); + fprintf(where,"\tfraction_kernel %g\n",fraction_kernel); + fprintf(where,"\tfraction_interrupt %g WARNING, possibly under-counted!\n",fraction_interrupt); + fprintf(where,"\testimated_fraction_interrupt %g\n", + estimated_fraction_interrupt); + } + + /* and finally, what is our CPU utilization? */ + lib_local_per_cpu_util[i] = 100.0 - (fraction_idle * 100.0); +#else + /* and now some fun with integer math. i initially tried to + promote things to long doubled but that didn't seem to result + in happiness and joy. raj 2005-01-28 */ + + /* multiply by 100 and divide by total and you get whole + percentages. multiply by 1000 and divide by total and you get + tenths of percentages. multiply by 10000 and divide by total + and you get hundredths of percentages. etc etc etc raj + 2005-01-28 */ + + /* when the accounting for interrupt time gets its act together, + we can use total_cpu_cycles rather than sanity_cpu_cycles, but + until then, use sanity_cpu_ccles. raj 2005/09/14 */ + + fraction_idle = + (delta_cpu_counters[i].idle * CALC_ACCURACY) / sanity_cpu_cycles; + + fraction_user = + (delta_cpu_counters[i].user * CALC_ACCURACY) / sanity_cpu_cycles; + + fraction_kernel = + (delta_cpu_counters[i].kernel * CALC_ACCURACY) / sanity_cpu_cycles; + + fraction_interrupt = + (delta_cpu_counters[i].interrupt * CALC_ACCURACY) / sanity_cpu_cycles; + + + estimated_fraction_interrupt = + ((delta_cpu_counters[i].interrupt + + (sanity_cpu_cycles - total_cpu_cycles)) * + CALC_ACCURACY) / sanity_cpu_cycles; + + if (debug) { + fprintf(where,"\tfraction_idle %"PRIu64"\n",fraction_idle); + fprintf(where,"\tfraction_user %"PRIu64"\n",fraction_user); + fprintf(where,"\tfraction_kernel %"PRIu64"\n",fraction_kernel); + fprintf(where,"\tfraction_interrupt %"PRIu64"WARNING, possibly under-counted!\n",fraction_interrupt); + fprintf(where,"\testimated_fraction_interrupt %"PRIu64"\n", + estimated_fraction_interrupt); + } + + /* and finally, what is our CPU utilization? */ + lib_local_per_cpu_util[i] = 100.0 - (((float)fraction_idle / + (float)CALC_ACCURACY) * 100.0); +#endif + lib_local_per_cpu_util[i] *= correction_factor; + if (debug) { + fprintf(where, + "lib_local_per_cpu_util[%d] %g cf %f\n", + i, + lib_local_per_cpu_util[i], + correction_factor); + } + lib_local_cpu_util += lib_local_per_cpu_util[i]; + } + /* we want the average across all n processors */ + lib_local_cpu_util /= (float)lib_num_loc_cpus; + + if (debug) { + fprintf(where, + "calc_cpu_util: returning %g\n",lib_local_cpu_util); + } + + return lib_local_cpu_util; + +} +void +cpu_start_internal(void) +{ + get_cpu_counters(starting_cpu_counters); +} + +void +cpu_stop_internal(void) +{ + get_cpu_counters(ending_cpu_counters); +} diff --git a/src/netcpu_sysctl.c b/src/netcpu_sysctl.c new file mode 100644 index 0000000..4786096 --- /dev/null +++ b/src/netcpu_sysctl.c @@ -0,0 +1,132 @@ +char netcpu_sysctl_id[]="\ +@(#)netcpu_sysctl.c Version 2.4.3"; + +#if HAVE_CONFIG_H +# include +#endif + +#include +#include + +#if HAVE_INTTYPES_H +# include +#else +# if HAVE_STDINT_H +# include +# endif +#endif + +#if TIME_WITH_SYS_TIME +# include +# include +#else +# if HAVE_SYS_TIME_H +# include +# else +# include +# endif +#endif +#if HAVE_LIMITS_H +# include +# ifndef LONG_LONG_MAX +# define LONG_LONG_MAX LLONG_MAX +# endif /* LONG_LONG_MAX */ +#endif + +#ifdef __NetBSD__ +#define CP_TIME_TYPE uint64_t +#else +#define CP_TIME_TYPE long +#endif + +#include + +/* need to have some sort of check for sys/sysctl.h versus sysctl.h */ +#include + + +/* this has been liberally cut and pasted from on + FreeBSD. in general, this would be a bad idea, but I don't want to + have to do a _KERNEL define to get these and that is what + sys/resource.h seems to want. raj 2002-03-03 */ +#define CP_USER 0 +#define CP_NICE 1 +#define CP_SYS 2 +#define CP_INTR 3 +#define CP_IDLE 4 +#define CPUSTATES 5 + + +#include "netsh.h" +#include "netlib.h" + +static CP_TIME_TYPE lib_start_count[CPUSTATES]; +static CP_TIME_TYPE lib_end_count[CPUSTATES]; + +void +cpu_util_init(void) +{ + return; +} + +void +cpu_util_terminate(void) +{ + return; +} + +int +get_cpu_method(void) +{ + return SYSCTL; +} + +static void +get_cpu_time(CP_TIME_TYPE *cpu_time) +{ + size_t cpu_time_len = CPUSTATES * sizeof (cpu_time[0]); + + if (sysctlbyname("kern.cp_time", cpu_time, &cpu_time_len, NULL, 0) == -1) { + fprintf (stderr, "Cannot get CPU time!\n"); + exit (1); + } +} + +/* calibrate_sysctl - perform the idle rate calculation using the + sysctl call - typically on BSD */ + +float +calibrate_idle_rate(int iterations, int interval) +{ + return sysconf (_SC_CLK_TCK); +} + +float +calc_cpu_util_internal(float elapsed_time) +{ + CP_TIME_TYPE sum_idle, sum_busy; + int i; + + for (sum_busy = 0, i = 0; i < CPUSTATES; i++) { + if (i != CP_IDLE) + sum_busy += lib_end_count[i] - lib_start_count[i]; + } + + sum_idle = lib_end_count[CP_IDLE] - lib_start_count[CP_IDLE]; + lib_local_cpu_util = (float)sum_busy / (float)(sum_busy + sum_idle); + lib_local_cpu_util *= 100.0; + + return lib_local_cpu_util; + +} +void +cpu_start_internal(void) +{ + get_cpu_time(lib_start_count); +} + +void +cpu_stop_internal(void) +{ + get_cpu_time(lib_end_count); +} diff --git a/src/netdrv_ethtool.c b/src/netdrv_ethtool.c new file mode 100644 index 0000000..f8d4661 --- /dev/null +++ b/src/netdrv_ethtool.c @@ -0,0 +1,119 @@ +#if defined(HAVE_CONFIG_H) +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* alas, direct inclusion of ethtool.h depends on some types not + normally found in nature, which we must provide or things will be + quite unhappy. newer ethtool.h include files will it seems be happy + with our including linux/types.h which will give us __umumble */ + +#include + +/* older ethtool.h includes want them without the leading underscores */ +typedef unsigned long long u64; +typedef unsigned int u32; +typedef unsigned short u16; +typedef unsigned char u8; + +/* ostensibly at this point we should be covered for any ethtool.h? */ +#include + +void +find_driver_info(char *ifname, char *driver, char *version, char *firmware, char *bus, int len) { + + int s; + int ret; + struct ifreq ifr; + struct ethtool_drvinfo drvinfo; + + if (len < 32) return; + + if (!strcmp(ifname,"lo")) { + /* special case loopback */ + strncpy(driver,"loopback",len); + strncpy(version,"system",len); + strncpy(firmware,"N/A",len); + strncpy(bus,"N/A",len); + driver[len-1] = 0; + version[len-1] = 0; + firmware[len-1] = 0; + bus[len-1] = 0; + return; + } + + s = socket(AF_INET,SOCK_DGRAM,0); + + if (s < 0) { + strncpy(driver,"SocketFailure",len); + strncpy(version,"SocketFailure",len); + strncpy(firmware,"SocketFailure",len); + strncpy(bus,"SocketFailure",len); + driver[len-1] = 0; + version[len-1] = 0; + firmware[len-1] = 0; + bus[len-1] = 0; + return; + } + + memset(&ifr, 0, sizeof(ifr)); + drvinfo.cmd = ETHTOOL_GDRVINFO; + strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)-1); + ifr.ifr_data = (caddr_t)&drvinfo; + + ret = ioctl(s, SIOCETHTOOL, &ifr); + + if (ret == -1) { + strncpy(driver,"IoctlFailure",len); + strncpy(version,"IoctlFailure",len); + strncpy(firmware,"IoctlFailure",len); + strncpy(bus,"IoctlFailure",len); + driver[len-1] = 0; + version[len-1] = 0; + firmware[len-1] = 0; + bus[len-1] = 0; + return; + } + strncpy(driver,drvinfo.driver,len); + strncpy(version,drvinfo.version,len); + strncpy(firmware,drvinfo.fw_version,len); + strncpy(bus,drvinfo.bus_info,len); + driver[len-1] = 0; + version[len-1] = 0; + firmware[len-1] = 0; + bus[len-1] = 0; + + return; +} + +#if defined(NETPERF_STANDALONE_DEBUG) +int +main(int argc, char *argv[]) { + + char driver[32]; + char version[32]; + char firmware[32]; + char businfo[32]; + + if (argc != 2) { + fprintf(stderr,"%s \n",argv[0]); + return -1; + } + + find_driver_info(argv[1],driver, version, firmware, businfo, 32); + + printf("For %s driver %s version %s firmware %s businfo %s\n", + argv[1],driver, version, firmware, businfo); + + return 0; +} +#endif diff --git a/src/netdrv_none.c b/src/netdrv_none.c new file mode 100644 index 0000000..3ec6657 --- /dev/null +++ b/src/netdrv_none.c @@ -0,0 +1,15 @@ +#include + +void +find_driver_info(char *ifname, char *driver, char *version, char *firmware, char *bus, int len) { + + strncpy(driver,"Unavailable",len); + strncpy(version,"Unavailable",len); + strncpy(firmware,"Unavailable",len); + strncpy(bus,"Unavailable",len); + driver[len-1] = 0; + version[len-1] = 0; + firmware[len-1] = 0; + bus[len-1] = 0; + return; +} diff --git a/src/netdrv_solaris.c b/src/netdrv_solaris.c new file mode 100644 index 0000000..e6fb1ec --- /dev/null +++ b/src/netdrv_solaris.c @@ -0,0 +1,67 @@ +#if defined(HAVE_CONFIG_H) +#include +#endif + +#include +#include + +#if defined(NETPERF_STANDALONE_DEBUG) +#include +#include +#endif + +void +find_driver_info(char *ifname, char *driver, char *version, char *firmware, char *bus, int len) { + + /* until something better comes along, we will use the expedient + that the interface name, up to but not including the instance + number is the driver name. raj 2008-03-19 */ + int i; + + strncpy(driver,ifname,len); + driver[len-1] = 0; + + /* work backwards nuking numbers and punctuation */ + for (i = strlen(driver) - 1; ((isdigit(driver[i])) || + (ispunct(driver[i]))) && (i >= 0); i--) { + driver[i] = 0; + } + + /* on the off chance we managed to toast the entire string, we + should probably mention that somehow. raj 2008-03-19 */ + if (strlen(driver) == 0) + strncpy(driver,"NoAlpha",len); + + strncpy(version,"Unavailable",len); + strncpy(firmware,"Unavailable",len); + strncpy(bus,"Unavailable",len); + version[len-1] = 0; + firmware[len-1] = 0; + bus[len-1] = 0; + return; +} + +#if defined(NETPERF_STANDALONE_DEBUG) +int +main(int argc, char *argv[]) { + +#define MYLEN 32 + char driver[MYLEN]; + char version[MYLEN]; + char firmware[MYLEN]; + char bus[MYLEN]; + + if (argc != 2) { + fprintf(stderr,"%s \n",argv[0]); + exit(-1); + } + + find_driver_info(argv[1],driver, version, firmware, bus, MYLEN); + + printf("Interface %s driver %s version %s firmware %s bus %s\n", + argv[1], driver, version, firmware, bus); + + return 0; + +} +#endif diff --git a/src/netlib.c b/src/netlib.c new file mode 100644 index 0000000..7e6f178 --- /dev/null +++ b/src/netlib.c @@ -0,0 +1,4506 @@ +char netlib_id[]="\ +@(#)netlib.c (c) Copyright 1993-2007 Hewlett-Packard Company. Version 2.4.3"; + + +/****************************************************************/ +/* */ +/* netlib.c */ +/* */ +/* the common utility routines available to all... */ +/* */ +/* establish_control() establish the control socket */ +/* calibrate_local_cpu() do local cpu calibration */ +/* calibrate_remote_cpu() do remote cpu calibration */ +/* send_request() send a request to the remote */ +/* recv_response() receive a response from remote */ +/* send_response() send a response to the remote */ +/* recv_request() recv a request from the remote */ +/* dump_request() dump request contents */ +/* dump_response() dump response contents */ +/* cpu_start() start measuring cpu */ +/* cpu_stop() stop measuring cpu */ +/* calc_cpu_util() calculate the cpu utilization */ +/* calc_service_demand() calculate the service demand */ +/* calc_thruput() calulate the tput in units */ +/* calibrate() really calibrate local cpu */ +/* identify_local() print local host information */ +/* identify_remote() print remote host information */ +/* format_number() format the number (KB, MB,etc) */ +/* format_units() return the format in english */ +/* msec_sleep() sleep for some msecs */ +/* start_timer() start a timer */ +/* */ +/* the routines you get when WANT_DLPI is defined... */ +/* */ +/* dl_open() open a file descriptor and */ +/* attach to the card */ +/* dl_mtu() find the MTU of the card */ +/* dl_bind() bind the sap do the card */ +/* dl_connect() sender's have of connect */ +/* dl_accpet() receiver's half of connect */ +/* dl_set_window() set the window size */ +/* dl_stats() retrieve statistics */ +/* dl_send_disc() initiate disconnect (sender) */ +/* dl_recv_disc() accept disconnect (receiver) */ +/****************************************************************/ + +/****************************************************************/ +/* */ +/* Global include files */ +/* */ +/****************************************************************/ + +#ifdef HAVE_CONFIG_H +#include +#endif + + /* It would seem that most of the includes being done here from */ + /* "sys/" actually have higher-level wrappers at just /usr/include. */ + /* This is based on a spot-check of a couple systems at my disposal. */ + /* If you have trouble compiling you may want to add "sys/" raj 10/95 */ +#include +#include +#ifdef MPE +# define NSIG _NSIG +#endif /* MPE */ +#include +#include +#include +#include +#include +#include +#include +#ifdef HAVE_ENDIAN_H +#include +#endif + + +#ifndef WIN32 + /* at some point, I would like to get rid of all these "sys/" */ + /* includes where appropriate. if you have a system that requires */ + /* them, speak now, or your system may not compile later revisions of */ + /* netperf. raj 1/96 */ +#include +#include +#include +#ifndef MPE +#include +#include +#endif /* MPE */ +#include +#include +#include +#include +#include +#include +#if !defined(MPE) && !defined(__VMS) +#include +#endif /* MPE */ + +#else /* WIN32 */ + +#include +#include +#include +#define netperf_socklen_t socklen_t +#include + +/* the only time someone should need to define DONT_IPV6 in the + "sources" file is if they are trying to compile on Windows 2000 or + NT4 and I suspect this may not be their only problem :) */ +#ifndef DONT_IPV6 +#include +#endif + +#include + +#define strdup _strdup + +#define SIGALRM (14) +#define sleep(x) Sleep((x)*1000) + +#endif /* WIN32 */ + +#ifdef HAVE_UNAME +#include +#endif + +#ifdef _AIX +#include +#include +#include +#define PRIORITY PRI_LOW +#else/* _AIX */ +#ifdef __sgi +#include +#include +#define PRIORITY NDPLOMIN +#endif /* __sgi */ +#endif /* _AIX */ + +#ifdef WANT_DLPI +#include +#include +#include +#ifdef __osf__ +#include +#else /* __osf__ */ +#include +#ifdef __hpux +#include +#endif /* __hpux */ +#endif /* __osf__ */ +#endif /* WANT_DLPI */ + +#ifdef HAVE_MPCTL +#include +#endif + +#if !defined(HAVE_GETADDRINFO) || !defined(HAVE_GETNAMEINFO) +# include "missing/getaddrinfo.h" +#endif + + +#ifdef WANT_HISTOGRAM +#include "hist.h" +#endif /* WANT_HISTOGRAM */ +/****************************************************************/ +/* */ +/* Local Include Files */ +/* */ +/****************************************************************/ +#define NETLIB +#include "netlib.h" +#include "netsh.h" +#include "netcpu.h" + +/****************************************************************/ +/* */ +/* Global constants, macros and variables */ +/* */ +/****************************************************************/ + +#if defined(WIN32) || defined(__VMS) +struct timezone { + int dummy ; + } ; +#ifndef __VMS +SOCKET win_kludge_socket = INVALID_SOCKET; +SOCKET win_kludge_socket2 = INVALID_SOCKET; +#endif /* __VMS */ +#endif /* WIN32 || __VMS */ + +#ifndef LONG_LONG_MAX +#define LONG_LONG_MAX 9223372036854775807LL +#endif /* LONG_LONG_MAX */ + + /* older versions of netperf knew about the HP kernel IDLE counter. */ + /* this is now obsolete - in favor of either pstat(), times, or a */ + /* process-level looper process. we also now require support for the */ + /* "long" integer type. raj 4/95. */ + +int + lib_num_loc_cpus, /* the number of cpus in the system */ + lib_num_rem_cpus; /* how many we think are in the remote */ + +int + lib_local_peak_cpu_id, /* the CPU number of the most utilized CPU */ + lib_remote_peak_cpu_id; +double + lib_local_peak_cpu_util, /* its utilization */ + lib_remote_peak_cpu_util; + +#define PAGES_PER_CHILD 2 + +int lib_use_idle; +int cpu_method; + +struct timeval time1, time2; +struct timezone tz; +float lib_elapsed, + lib_local_maxrate, + lib_remote_maxrate, + lib_local_cpu_util, + lib_remote_cpu_util; + +float lib_local_per_cpu_util[MAXCPUS]; +int lib_cpu_map[MAXCPUS]; + +int *request_array; +int *response_array; + +/* INVALID_SOCKET == INVALID_HANDLE_VALUE == (unsigned int)(~0) == -1 */ +SOCKET netlib_control = INVALID_SOCKET; +SOCKET server_sock = INVALID_SOCKET; + +/* global variables to hold the value for processor affinity */ +int local_proc_affinity = -1,remote_proc_affinity = -1; + +/* these are to allow netperf to be run easily through those evil, + end-to-end breaking things known as firewalls */ +char local_data_port[10]; +char remote_data_port[10]; + +char *local_data_address=NULL; +char *remote_data_address=NULL; + +char *local_sysname, *remote_sysname; +char *local_release, *remote_release; +char *local_version, *remote_version; +char *local_machine, *remote_machine; + +int local_data_family=AF_UNSPEC; +int remote_data_family=AF_UNSPEC; + + /* in the past, I was overlaying a structure on an array of ints. now */ + /* I am going to have a "real" structure, and point an array of ints */ + /* at it. the real structure will be forced to the same alignment as */ + /* the type "double." this change will mean that pre-2.1 netperfs */ + /* cannot be mixed with 2.1 and later. raj 11/95 */ + +union netperf_request_struct netperf_request; +union netperf_response_struct netperf_response; + +FILE *where; + +char libfmt = '?'; + +#ifdef WANT_DLPI +/* some stuff for DLPI control messages */ +#define DLPI_DATA_SIZE 2048 + +unsigned long control_data[DLPI_DATA_SIZE]; +struct strbuf control_message = {DLPI_DATA_SIZE, 0, (char *)control_data}; + +#endif /* WANT_DLPI */ + +#ifdef WIN32 +HANDLE hAlarm = INVALID_HANDLE_VALUE; +#endif + +int times_up; + +#ifdef WIN32 + /* we use a getopt implementation from net.sources */ +/* + * get option letter from argument vector + */ +int + opterr = 1, /* should error messages be printed? */ + optind = 1, /* index into parent argv vector */ + optopt; /* character checked for validity */ +char + *optarg; /* argument associated with option */ + +#define EMSG "" + +#endif /* WIN32 */ + +static int measuring_cpu; +int +netlib_get_page_size(void) { + + /* not all systems seem to have the sysconf for page size. for + those which do not, we will assume that the page size is 8192 + bytes. this should be more than enough to be sure that there is + no page or cache thrashing by looper processes on MP + systems. otherwise that's really just too bad - such systems + should define _SC_PAGE_SIZE - raj 4/95 */ + +#ifndef _SC_PAGE_SIZE +#ifdef WIN32 + +SYSTEM_INFO SystemInfo; + + GetSystemInfo(&SystemInfo); + + return SystemInfo.dwPageSize; +#else + return(8192L); +#endif /* WIN32 */ +#else + return(sysconf(_SC_PAGE_SIZE)); +#endif /* _SC_PAGE_SIZE */ + +} + + +#ifdef WANT_INTERVALS +static unsigned int usec_per_itvl; + + +void +stop_itimer() + +{ + + struct itimerval new_interval; + struct itimerval old_interval; + + new_interval.it_interval.tv_sec = 0; + new_interval.it_interval.tv_usec = 0; + new_interval.it_value.tv_sec = 0; + new_interval.it_value.tv_usec = 0; + if (setitimer(ITIMER_REAL,&new_interval,&old_interval) != 0) { + /* there was a problem arming the interval timer */ + perror("netperf: setitimer"); + exit(1); + } + return; +} +#endif /* WANT_INTERVALS */ + + + +#ifdef WIN32 +static void +error(char *pch) +{ + if (!opterr) { + return; /* without printing */ + } + fprintf(stderr, "%s: %s: %c\n", + (NULL != program) ? program : "getopt", pch, optopt); +} + +int +getopt(int argc, char **argv, char *ostr) +{ + static char *place = EMSG; /* option letter processing */ + register char *oli; /* option letter list index */ + + if (!*place) { + /* update scanning pointer */ + if (optind >= argc || *(place = argv[optind]) != '-' || !*++place) { + return EOF; + } + if (*place == '-') { + /* found "--" */ + ++optind; + place = EMSG ; /* Added by shiva for Netperf */ + return EOF; + } + } + + /* option letter okay? */ + if ((optopt = (int)*place++) == (int)':' + || !(oli = strchr(ostr, optopt))) { + if (!*place) { + ++optind; + } + error("illegal option"); + return BADCH; + } + if (*++oli != ':') { + /* don't need argument */ + optarg = NULL; + if (!*place) + ++optind; + } else { + /* need an argument */ + if (*place) { + optarg = place; /* no white space */ + } else if (argc <= ++optind) { + /* no arg */ + place = EMSG; + error("option requires an argument"); + return BADCH; + } else { + optarg = argv[optind]; /* white space */ + } + place = EMSG; + ++optind; + } + return optopt; /* return option letter */ +} +#endif /* WIN32 */ + +/*---------------------------------------------------------------------------- + * WIN32 implementation of perror, does not deal very well with WSA errors + * The stdlib.h version of perror only deals with the ancient XENIX error codes. + * + * +*+SAF Why can't all WSA errors go through GetLastError? Most seem to... + *--------------------------------------------------------------------------*/ + +#ifdef WIN32 +void PrintWin32Error(FILE *stream, LPSTR text) +{ + LPSTR szTemp; + DWORD dwResult; + DWORD dwError; + + dwError = GetLastError(); + dwResult = FormatMessage( + FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM |FORMAT_MESSAGE_ARGUMENT_ARRAY, + NULL, + dwError, + LANG_NEUTRAL, + (LPTSTR)&szTemp, + 0, + NULL ); + + if (dwResult) + fprintf(stream, "%s: %s\n", text, szTemp); + else + fprintf(stream, "%s: error 0x%x\n", text, dwError); + fflush(stream); + + if (szTemp) + LocalFree((HLOCAL)szTemp); +} +#endif /* WIN32 */ + +char * +nsec_enabled_to_str(int enabled) { + switch (enabled) { + case NSEC_UNKNOWN: + return("Unknown"); + case NSEC_DISABLED: + return("Disabled"); + case NSEC_PERMISSIVE: + return("Permissive"); + case NSEC_ENFORCING: + return("Enforcing"); + default: + return("UNKNOWN MODE"); + } +} + +char * nsec_type_to_str(int type) { + switch (type) { + case NSEC_TYPE_UNKNOWN: + return("Unknown"); + case NSEC_TYPE_SELINUX: + return("SELinux"); + default: + return("UNKNOWN TYPE"); + } +} + + +char * +inet_ttos(int type) +{ + switch (type) { + case SOCK_DGRAM: + return("SOCK_DGRAM"); + break; + case SOCK_STREAM: + return("SOCK_STREAM"); + break; +#ifdef SOCK_DCCP + case SOCK_DCCP: + return "SOCK_DCCP"; +#endif + default: + return("SOCK_UNKNOWN"); + } +} + + + +char unknown[32]; + +char * +inet_ptos(int protocol) { + switch (protocol) { + case IPPROTO_TCP: + return("IPPROTO_TCP"); + break; + case IPPROTO_UDP: + return("IPPROTO_UDP"); + break; +#if defined(IPPROTO_SCTP) + case IPPROTO_SCTP: + return("IPPROTO_SCTP"); + break; +#endif +#if defined(IPPROTO_DCCP) + case IPPROTO_DCCP: + return "IPPROTO_DCCP"; + break; +#endif + default: + snprintf(unknown,sizeof(unknown),"IPPROTO_UNKNOWN(%d)",protocol); + return(unknown); + } +} + +/* one of these days, this should not be required */ +#ifndef AF_INET_SDP +#define AF_INET_SDP 27 +#define PF_INET_SDP AF_INET_SDP +#endif + +char * +inet_ftos(int family) +{ + switch(family) { + case AF_INET: + return("AF_INET"); + break; +#if defined(AF_INET6) + case AF_INET6: + return("AF_INET6"); + break; +#endif +#if defined(AF_INET_SDP) + case AF_INET_SDP: + return("AF_INET_SDP"); + break; +#endif + default: + return("AF_UNSPEC"); + } +} + +int +inet_nton(int af, const void *src, char *dst, int cnt) + +{ + + switch (af) { + case AF_INET: + /* magic constants again... :) */ + if (cnt >= 4) { + memcpy(dst,src,4); + return 4; + } + else { + Set_errno(ENOSPC); + return(-1); + } + break; +#if defined(AF_INET6) + case AF_INET6: + if (cnt >= 16) { + memcpy(dst,src,16); + return(16); + } + else { + Set_errno(ENOSPC); + return(-1); + } + break; +#endif + default: + Set_errno(EAFNOSUPPORT); + return(-1); + } +} + +double +ntohd(double net_double) + +{ + /* we rely on things being nicely packed */ + union { + double whole_thing; + unsigned int words[2]; + unsigned char bytes[8]; + } conv_rec; + + unsigned char scratch; + int i; + + /* on those systems where ntohl is a no-op, we want to return the */ + /* original value, unchanged */ + + if (ntohl(1L) == 1L) { + return(net_double); + } + + conv_rec.whole_thing = net_double; + + /* we know that in the message passing routines that ntohl will have */ + /* been called on the 32 bit quantities. we need to put those back */ + /* the way they belong before we swap */ + conv_rec.words[0] = htonl(conv_rec.words[0]); + conv_rec.words[1] = htonl(conv_rec.words[1]); + + /* now swap */ + for (i=0; i<= 3; i++) { + scratch = conv_rec.bytes[i]; + conv_rec.bytes[i] = conv_rec.bytes[7-i]; + conv_rec.bytes[7-i] = scratch; + } + +#if defined(__FLOAT_WORD_ORDER) && defined(__BYTE_ORDER) + if (__FLOAT_WORD_ORDER != __BYTE_ORDER) { + /* Fixup mixed endian floating point machines */ + unsigned int scratch = conv_rec.words[0]; + conv_rec.words[0] = conv_rec.words[1]; + conv_rec.words[1] = scratch; + } +#endif + + return(conv_rec.whole_thing); + +} + +double +htond(double host_double) + +{ + /* we rely on things being nicely packed */ + union { + double whole_thing; + unsigned int words[2]; + unsigned char bytes[8]; + } conv_rec; + + unsigned char scratch; + int i; + + /* on those systems where ntohl is a no-op, we want to return the */ + /* original value, unchanged */ + + if (ntohl(1L) == 1L) { + return(host_double); + } + + conv_rec.whole_thing = host_double; + + /* now swap */ + for (i=0; i<= 3; i++) { + scratch = conv_rec.bytes[i]; + conv_rec.bytes[i] = conv_rec.bytes[7-i]; + conv_rec.bytes[7-i] = scratch; + } + +#if defined(__FLOAT_WORD_ORDER) && defined(__BYTE_ORDER) + if (__FLOAT_WORD_ORDER != __BYTE_ORDER) { + /* Fixup mixed endian floating point machines */ + unsigned int scratch = conv_rec.words[0]; + conv_rec.words[0] = conv_rec.words[1]; + conv_rec.words[1] = scratch; + } +#endif + + /* we know that in the message passing routines htonl will */ + /* be called on the 32 bit quantities. we need to set things up so */ + /* that when this happens, the proper order will go out on the */ + /* network */ + conv_rec.words[0] = htonl(conv_rec.words[0]); + conv_rec.words[1] = htonl(conv_rec.words[1]); + + return(conv_rec.whole_thing); + +} + + +/* one of these days, this should be abstracted-out just like the CPU + util stuff. raj 2005-01-27 */ +int +get_num_cpus() + +{ + + /* on HP-UX, even when we use the looper procs we need the pstat */ + /* call */ + + int temp_cpus; + +#ifdef __hpux +#include + + struct pst_dynamic psd; + + if (pstat_getdynamic((struct pst_dynamic *)&psd, + (size_t)sizeof(psd), (size_t)1, 0) != -1) { + temp_cpus = psd.psd_proc_cnt; + } + else { + temp_cpus = 1; + } + +#else + /* MW: was included for non-Windows systems above. */ + /* Thus if _SC_NPROC_ONLN is defined, we should be able to use sysconf. */ +#ifdef _SC_NPROCESSORS_ONLN + temp_cpus = sysconf(_SC_NPROCESSORS_ONLN); + +#ifdef USE_PERFSTAT + temp_cpus = perfstat_cpu(NULL,NULL, sizeof(perfstat_cpu_t), 0); +#endif /* USE_PERFSTAT */ + +#else /* no _SC_NPROCESSORS_ONLN */ + +#ifdef WIN32 + SYSTEM_INFO SystemInfo; + GetSystemInfo(&SystemInfo); + + temp_cpus = SystemInfo.dwNumberOfProcessors; +#else + /* we need to know some other ways to do this, or just fall-back on */ + /* a global command line option - raj 4/95 */ + temp_cpus = shell_num_cpus; +#endif /* WIN32 */ +#endif /* _SC_NPROCESSORS_ONLN */ +#endif /* __hpux */ + + if (temp_cpus > MAXCPUS) { + fprintf(where, + "Sorry, this system has more CPUs (%d) than I can handle (%d).\n", + temp_cpus, + MAXCPUS); + fprintf(where, + "Please alter MAXCPUS in netlib.h and recompile.\n"); + fflush(where); + exit(1); + } + + return(temp_cpus); + +} + +#ifdef WIN32 +#ifdef __GNUC__ + #define S64_SUFFIX(x) x##LL +#else + #define S64_SUFFIX(x) x##i64 +#endif + +/* + * Number of 100 nanosecond units from 1/1/1601 to 1/1/1970 + */ +#define EPOCH_BIAS S64_SUFFIX(116444736000000000) + +/* + * Union to facilitate converting from FILETIME to unsigned __int64 + */ +typedef union { + unsigned __int64 ft_scalar; + FILETIME ft_struct; +} FT; + +void +gettimeofday( struct timeval *tv , struct timezone *not_used ) +{ + FT nt_time; + __int64 UnixTime; /* microseconds since 1/1/1970 */ + + GetSystemTimeAsFileTime( &(nt_time.ft_struct) ); + + UnixTime = ((nt_time.ft_scalar - EPOCH_BIAS) / S64_SUFFIX(10)); + tv->tv_sec = (long)(time_t)(UnixTime / S64_SUFFIX(1000000)); + tv->tv_usec = (unsigned long)(UnixTime % S64_SUFFIX(1000000)); +} +#endif /* WIN32 */ + + + +/************************************************************************/ +/* */ +/* signal catcher */ +/* */ +/************************************************************************/ + +void +#if defined(__hpux) +catcher(sig, code, scp) + int sig; + int code; + struct sigcontext *scp; +#else +catcher(int sig) +#endif /* __hpux || __VMS */ +{ + +#ifdef __hpux + if (debug > 2) { + fprintf(where,"caught signal %d ",sig); + if (scp) { + fprintf(where,"while in syscall %d\n", + scp->sc_syscall); + } + else { + fprintf(where,"null scp\n"); + } + fflush(where); + } +#endif /* RAJ_DEBUG */ + + switch(sig) { + + case SIGINT: + fprintf(where,"netperf: caught SIGINT\n"); + fflush(where); + exit(1); + break; + case SIGALRM: + if (--test_len_ticks == 0) { + /* the test is over */ + if (times_up != 0) { + fprintf(where,"catcher: timer popped with times_up != 0\n"); + fflush(where); + } + times_up = 1; +#if defined(WANT_INTERVALS) && !defined(WANT_SPIN) + stop_itimer(); +#endif /* WANT_INTERVALS */ + break; + } + else { +#ifdef WANT_INTERVALS +#ifdef __hpux + /* the test is not over yet and we must have been using the */ + /* interval timer. if we were in SYS_SIGSUSPEND we want to */ + /* re-start the system call. Otherwise, we want to get out of */ + /* the sigsuspend call. I NEED TO KNOW HOW TO DO THIS FOR OTHER */ + /* OPERATING SYSTEMS. If you know how, please let me know. rick */ + /* jones */ + if (scp->sc_syscall != SYS_SIGSUSPEND) { + if (debug > 2) { + fprintf(where, + "catcher: Time to send burst > interval!\n"); + fflush(where); + } + scp->sc_syscall_action = SIG_RESTART; + } +#endif /* __hpux */ +#else /* WANT_INTERVALS */ + fprintf(where, + "catcher: interval timer running unexpectedly!\n"); + fflush(where); + times_up = 1; +#endif /* WANT_INTERVALS */ + break; + } + } + return; +} + + +void +install_signal_catchers() + +{ + /* just a simple little routine to catch a bunch of signals */ + +#ifndef WIN32 + struct sigaction action; + int i; + + fprintf(where,"installing catcher for all signals\n"); + fflush(where); + + sigemptyset(&(action.sa_mask)); + action.sa_handler = catcher; + +#ifdef SA_INTERRUPT + action.sa_flags = SA_INTERRUPT; +#else /* SA_INTERRUPT */ + action.sa_flags = 0; +#endif /* SA_INTERRUPT */ + + + for (i = 1; i <= NSIG; i++) { + switch (i) { + case SIGALRM: + case SIGPROF: + case SIGSTOP: + case SIGKILL: + break; + default: + if (sigaction(i,&action,NULL) != 0) { + fprintf(where, + "Could not install signal catcher for sig %d, errno %d\n", + i, + errno); + fflush(where); + + } + } + } +#else + return; +#endif /* WIN32 */ +} + + +#ifdef WIN32 +#define SIGALRM (14) +void +emulate_alarm( int seconds ) +{ + DWORD ErrorCode; + DWORD HandlesClosedFlags = 0; + + /* Wait on this event for parm seconds. */ + + ErrorCode = WaitForSingleObject(hAlarm, seconds*1000); + if (ErrorCode == WAIT_FAILED) + { + perror("WaitForSingleObject failed"); + exit(1); + } + + if (ErrorCode == WAIT_TIMEOUT) + { + /* WaitForSingleObject timed out; this means the timer + wasn't canceled. */ + + times_up = 1; + + /* Give the other threads time to notice that times_up has + changed state before taking the harsh step of closing the + sockets. */ + + if (WaitForSingleObject(hAlarm, PAD_TIME/2*1000) == + WAIT_TIMEOUT) { + /* We have yet to find a good way to fully emulate + the effects of signals and getting EINTR from + system calls under winsock, so what we do here is + close the socket out from under the other thread. + It is rather kludgy, but should be sufficient to + get this puppy shipped. The concept can be + attributed/blamed :) on Robin raj 1/96 */ + + if (win_kludge_socket != INVALID_SOCKET) { + HandlesClosedFlags |= 1; + closesocket(win_kludge_socket); + } + if (win_kludge_socket2 != INVALID_SOCKET) { + HandlesClosedFlags |= 2; + closesocket(win_kludge_socket2); + } + } + if(debug) { + fprintf(where, + "emulate_alarm - HandlesClosedFlags: %x\n", + HandlesClosedFlags); + fflush(where); + } + } +} + + +#endif /* WIN32 */ + +void +start_timer(int time) +{ + +#ifdef WIN32 + /*+*+SAF What if StartTimer is called twice without the first timer */ + /*+*+SAF expiring? */ + + DWORD thread_id ; + HANDLE tHandle; + + if (hAlarm == (HANDLE) INVALID_HANDLE_VALUE) + { + /* Create the Alarm event object */ + hAlarm = CreateEvent( + (LPSECURITY_ATTRIBUTES) NULL, /* no security */ + FALSE, /* auto reset event */ + FALSE, /* init. state = reset */ + (void *)NULL); /* unnamed event object */ + if (hAlarm == (HANDLE) INVALID_HANDLE_VALUE) + { + perror("CreateEvent failure"); + exit(1); + } + } + else + { + ResetEvent(hAlarm); + } + + + tHandle = CreateThread(0, + 0, + (LPTHREAD_START_ROUTINE)emulate_alarm, + (LPVOID)(ULONG_PTR)time, + 0, + &thread_id ) ; + CloseHandle(tHandle); + +#else /* not WIN32 */ + +struct sigaction action; +int ret; + +if (debug) { + fprintf(where,"About to start a timer for %d seconds.\n",time); + fflush(where); +} + + action.sa_handler = catcher; + sigemptyset(&(action.sa_mask)); + sigaddset(&(action.sa_mask),SIGALRM); + +#ifdef SA_INTERRUPT + /* on some systems (SunOS 4.blah), system calls are restarted. we do */ + /* not want that */ + action.sa_flags = SA_INTERRUPT; +#else /* SA_INTERRUPT */ + action.sa_flags = 0; +#endif /* SA_INTERRUPT */ + + if (sigaction(SIGALRM, &action, NULL) < 0) { + fprintf(where,"start_timer: error installing alarm handler "); + fprintf(where,"errno %d\n",errno); + fflush(where); + exit(1); + } + + /* this is the easy case - just set the timer for so many seconds */ + ret = alarm(time); + if (ret != 0) { + fprintf(where, + "error starting alarm timer, ret %d errno %d\n", + ret, + errno); + fflush(where); + } +#endif /* WIN32 */ + + test_len_ticks = 1; + +} + + + /* this routine will disable any running timer */ +void +stop_timer() +{ +#ifndef WIN32 + alarm(0); +#else + /* at some point we may need some win32 equivalent */ + if (hAlarm != (HANDLE) INVALID_HANDLE_VALUE) + { + SetEvent(hAlarm); + } +#endif /* WIN32 */ + +} + + +#ifdef WANT_INTERVALS + /* this routine will enable the interval timer and set things up so */ + /* that for a timed test the test will end at the proper time. it */ + /* should detect the presence of POSIX.4 timer_* routines one of */ + /* these days */ +void +start_itimer(unsigned int interval_len_msec ) +{ + + unsigned int ticks_per_itvl; + + struct itimerval new_interval; + struct itimerval old_interval; + + /* if -DWANT_INTERVALS was used, we will use the ticking of the itimer to */ + /* tell us when the test is over. while the user will be specifying */ + /* some number of milliseconds, we know that the interval timer is */ + /* really in units of 1/HZ. so, to prevent the test from running */ + /* "long" it would be necessary to keep this in mind when calculating */ + /* the number of itimer events */ + + ticks_per_itvl = ((interval_wate * sysconf(_SC_CLK_TCK) * 1000) / + 1000000); + + if (ticks_per_itvl == 0) ticks_per_itvl = 1; + + /* how many usecs in each interval? */ + usec_per_itvl = ticks_per_itvl * (1000000 / sysconf(_SC_CLK_TCK)); + + /* how many times will the timer pop before the test is over? */ + if (test_time > 0) { + /* this was a timed test */ + test_len_ticks = (test_time * 1000000) / usec_per_itvl; + } + else { + /* this was not a timed test, use MAXINT */ + test_len_ticks = INT_MAX; + } + + if (debug) { + fprintf(where,"setting the interval timer to %d sec %d usec ", + usec_per_itvl / 1000000, + usec_per_itvl % 1000000); + fprintf(where,"test len %d ticks\n", + test_len_ticks); + fflush(where); + } + + /* if this was not a timed test, then we really aught to enable the */ + /* signal catcher raj 2/95 */ + + new_interval.it_interval.tv_sec = usec_per_itvl / 1000000; + new_interval.it_interval.tv_usec = usec_per_itvl % 1000000; + new_interval.it_value.tv_sec = usec_per_itvl / 1000000; + new_interval.it_value.tv_usec = usec_per_itvl % 1000000; + if (setitimer(ITIMER_REAL,&new_interval,&old_interval) != 0) { + /* there was a problem arming the interval timer */ + perror("netperf: setitimer"); + exit(1); + } +} +#endif /* WANT_INTERVALS */ + +void +netlib_init_cpu_map() { + + int i; +#ifdef HAVE_MPCTL + int num; + i = 0; + /* I go back and forth on whether this should be the system-wide set + of calls, or if the processor set versions (sans the _SYS) should + be used. at the moment I believe that the system-wide version + should be used. raj 2006-04-03 */ + num = mpctl(MPC_GETNUMSPUS_SYS,0,0); + lib_cpu_map[i] = mpctl(MPC_GETFIRSTSPU_SYS,0,0); + for (i = 1;((i < num) && (i < MAXCPUS)); i++) { + lib_cpu_map[i] = mpctl(MPC_GETNEXTSPU_SYS,lib_cpu_map[i-1],0); + } + /* from here, we set them all to -1 because if we launch more + loopers than actual CPUs, well, I'm not sure why :) */ + for (; i < MAXCPUS; i++) { + lib_cpu_map[i] = -1; + } + +#else + /* we assume that there is indeed a contiguous mapping */ + for (i = 0; i < MAXCPUS; i++) { + lib_cpu_map[i] = i; + } +#endif +} + +void +get_local_system_info() +{ +#ifdef HAVE_UNAME + struct utsname buf; + /* the linux manpage for uname says 0 means success, everyone else + says non-negative. at least they all agree that -1 means + error */ + if (uname(&buf) != -1) { + local_sysname = strdup(buf.sysname); + local_release = strdup(buf.release); + local_version = strdup(buf.version); + local_machine = strdup(buf.machine); + } + else { + local_sysname = strdup("UnknownSystem"); + local_release = strdup("UnknownRelease"); + local_version = strdup("UnknownVersion"); + local_machine = strdup("UnknownMachine"); + } +#else +#ifdef WIN32 + local_sysname = strdup("Windows"); +#else + local_sysname = strdup("UnknownSystem"); +#endif + local_release = strdup("UnknownRelease"); + local_version = strdup("UnknownVersion"); + local_machine = strdup("UnknownMachine"); + +#endif +} + + +/****************************************************************/ +/* */ +/* netlib_init() */ +/* */ +/* initialize the performance library... */ +/* */ +/****************************************************************/ + +void +netlib_init() +{ + int i; + + where = stdout; + + request_array = (int *)(&netperf_request); + response_array = (int *)(&netperf_response); + + for (i = 0; i < MAXCPUS; i++) { + lib_local_per_cpu_util[i] = -1.0; + } + + lib_local_peak_cpu_id = -1; + lib_local_peak_cpu_util = -1.0; + lib_remote_peak_cpu_id = -1; + lib_remote_peak_cpu_util = -1.0; + + /* retrieve the local system information */ + get_local_system_info(); + + /* on those systems where we know that CPU numbers may not start at + zero and be contiguous, we provide a way to map from a + contiguous, starting from 0 CPU id space to the actual CPU ids. + at present this is only used for the netcpu_looper stuff because + we ass-u-me that someone setting processor affinity from the + netperf commandline will provide a "proper" CPU identifier. raj + 2006-04-03 */ + + netlib_init_cpu_map(); + + if (debug) { + fprintf(where, + "netlib_init: request_array at %p\n", + request_array); + fprintf(where, + "netlib_init: response_array at %p\n", + response_array); + + fflush(where); + } + +} + + /* this routine will conver the string into an unsigned integer. it */ + /* is used primarily for the command-line options taking a number */ + /* (such as the socket size) which could be rather large. If someone */ + /* enters 32M, then the number will be converted to 32 * 1024 * 1024. */ + /* If they inter 32m, the number will be converted to 32 * 1000 * */ + /* 1000 */ +unsigned int +convert(char *string) + +{ + unsigned int base; + base = atoi(string); + if (strstr(string,"K")) { + base *= 1024; + } + if (strstr(string,"M")) { + base *= (1024 * 1024); + } + if (strstr(string,"G")) { + base *= (1024 * 1024 * 1024); + } + if (strstr(string,"k")) { + base *= (1000); + } + if (strstr(string,"m")) { + base *= (1000 * 1000); + } + if (strstr(string,"g")) { + base *= (1000 * 1000 * 1000); + } + return(base); +} + +/* this routine is like convert, but it is used for an interval time + specification instead of stuff like socket buffer or send sizes. + it converts everything to microseconds for internal use. if there + is an 'm' at the end it assumes the user provided milliseconds, s + will imply seconds, u will imply microseconds. in the future n + will imply nanoseconds but for now it will be ignored. if there is + no suffix or an unrecognized suffix, it will be assumed the user + provided milliseconds, which was the long-time netperf default. one + of these days, we should probably revisit that nanosecond business + wrt the return value being just an int rather than a uint64_t or + something. raj 2006-02-06 */ + +unsigned int +convert_timespec(char *string) { + + unsigned int base; + base = atoi(string); + if (strstr(string,"m")) { + base *= 1000; + } + else if (strstr(string,"u")) { + base *= (1); + } + else if (strstr(string,"s")) { + base *= (1000 * 1000); + } + else { + base *= (1000); + } + return(base); +} + + + /* this routine will allocate a circular list of buffers for either */ + /* send or receive operations. each of these buffers will be aligned */ + /* and offset as per the users request. the circumference of this */ + /* ring will be controlled by the setting of send_width. the buffers */ + /* will be filled with data from the file specified in fill_file. if */ + /* fill_file is an empty string, the buffers will not be filled with */ + /* any particular data */ + +struct ring_elt * +allocate_buffer_ring(int width, int buffer_size, int alignment, int offset) +{ + + struct ring_elt *first_link = NULL; + struct ring_elt *temp_link = NULL; + struct ring_elt *prev_link; + + int i; + int malloc_size; + int bytes_left; + int bytes_read; + int do_fill; + + FILE *fill_source; + char default_fill[] = "netperf"; + int fill_cursor = 0; + + malloc_size = buffer_size + alignment + offset; + + /* did the user wish to have the buffers pre-filled with data from a */ + /* particular source? */ + if (strcmp(fill_file,"") == 0) { + do_fill = 0; + fill_source = NULL; + } + else { + do_fill = 1; + fill_source = (FILE *)fopen(fill_file,"r"); + if (fill_source == (FILE *)NULL) { + perror("Could not open requested fill file"); + exit(1); + } + } + + assert(width >= 1); + + prev_link = NULL; + for (i = 1; i <= width; i++) { + /* get the ring element */ + temp_link = (struct ring_elt *)malloc(sizeof(struct ring_elt)); + if (temp_link == NULL) { + printf("malloc(%u) failed!\n", sizeof(struct ring_elt)); + exit(1); + } + /* remember the first one so we can close the ring at the end */ + if (i == 1) { + first_link = temp_link; + } + temp_link->buffer_base = (char *)malloc(malloc_size); + if (temp_link == NULL) { + printf("malloc(%d) failed!\n", malloc_size); + exit(1); + } + +#ifndef WIN32 + temp_link->buffer_ptr = (char *)(( (long)(temp_link->buffer_base) + + (long)alignment - 1) & + ~((long)alignment - 1)); +#else + temp_link->buffer_ptr = (char *)(( (ULONG_PTR)(temp_link->buffer_base) + + (ULONG_PTR)alignment - 1) & + ~((ULONG_PTR)alignment - 1)); +#endif + temp_link->buffer_ptr += offset; + /* is where the buffer fill code goes. */ + if (do_fill) { + char *bufptr = temp_link->buffer_ptr; + bytes_left = buffer_size; + while (bytes_left) { + if (((bytes_read = (int)fread(bufptr, + 1, + bytes_left, + fill_source)) == 0) && + (feof(fill_source))){ + rewind(fill_source); + } + bufptr += bytes_read; + bytes_left -= bytes_read; + } + } + else { + /* use the default fill to ID our data traffic on the + network. it ain't exactly pretty, but it should work */ + int j; + char *bufptr = temp_link->buffer_ptr; + for (j = 0; j < buffer_size; j++) { + bufptr[j] = default_fill[fill_cursor]; + fill_cursor += 1; + /* the Windows DDK compiler with an x86_64 target wants a cast + here */ + if (fill_cursor > (int)strlen(default_fill)) { + fill_cursor = 0; + } + } + + } + temp_link->next = prev_link; + prev_link = temp_link; + } + if (first_link) { /* SAF Prefast made me do it... */ + first_link->next = temp_link; + } + + return(first_link); /* it's a circle, doesn't matter which we return */ +} + +/* this routine will dirty the first dirty_count bytes of the + specified buffer and/or read clean_count bytes from the buffer. it + will go N bytes at a time, the only question is how large should N + be and if we should be going continguously, or based on some + assumption of cache line size */ + +void +access_buffer(char *buffer_ptr,int length, int dirty_count, int clean_count) { + + char *temp_buffer; + char *limit; + int i, dirty_totals; + + temp_buffer = buffer_ptr; + limit = temp_buffer + length; + dirty_totals = 0; + + for (i = 0; + ((i < dirty_count) && (temp_buffer < limit)); + i++) { + *temp_buffer += (char)i; + dirty_totals += *temp_buffer; + temp_buffer++; + } + + for (i = 0; + ((i < clean_count) && (temp_buffer < limit)); + i++) { + dirty_totals += *temp_buffer; + temp_buffer++; + } + + if (debug > 100) { + fprintf(where, + "This was here to try to avoid dead-code elimination %d\n", + dirty_totals); + fflush(where); + } +} + + +#ifdef HAVE_ICSC_EXS + +#include +#include + + /* this routine will allocate a circular list of buffers for either */ + /* send or receive operations. each of these buffers will be aligned */ + /* and offset as per the users request. the circumference of this */ + /* ring will be controlled by the setting of send_width. the buffers */ + /* will be filled with data from the file specified in fill_file. if */ + /* fill_file is an empty string, the buffers will not be filled with */ + /* any particular data */ + +struct ring_elt * +allocate_exs_buffer_ring (int width, int buffer_size, int alignment, int offset, exs_mhandle_t *mhandlep) +{ + + struct ring_elt *first_link; + struct ring_elt *temp_link; + struct ring_elt *prev_link; + + int i; + int malloc_size; + int bytes_left; + int bytes_read; + int do_fill; + + FILE *fill_source; + + int mmap_size; + char *mmap_buffer, *mmap_buffer_aligned; + + malloc_size = buffer_size + alignment + offset; + + /* did the user wish to have the buffers pre-filled with data from a */ + /* particular source? */ + if (strcmp (fill_file, "") == 0) { + do_fill = 0; + fill_source = NULL; + } else { + do_fill = 1; + fill_source = (FILE *) fopen (fill_file, "r"); + if (fill_source == (FILE *) NULL) { + perror ("Could not open requested fill file"); + exit (1); + } + } + + assert (width >= 1); + + if (debug) { + fprintf (where, "allocate_exs_buffer_ring: " + "width=%d buffer_size=%d alignment=%d offset=%d\n", + width, buffer_size, alignment, offset); + } + + /* allocate shared memory */ + mmap_size = width * malloc_size; + mmap_buffer = (char *) mmap ((caddr_t)NULL, mmap_size+NBPG-1, + PROT_READ|PROT_WRITE, + MAP_SHARED|MAP_ANONYMOUS, -1, 0); + if (mmap_buffer == NULL) { + perror ("allocate_exs_buffer_ring: mmap failed"); + exit (1); + } + mmap_buffer_aligned = (char *) ((uintptr_t)mmap_buffer & ~(NBPG-1)); + if (debug) { + fprintf (where, "allocate_exs_buffer_ring: " + "mmap buffer size=%d address=0x%p aligned=0x%p\n", + mmap_size, mmap_buffer, mmap_buffer_aligned); + } + + /* register shared memory */ + *mhandlep = exs_mregister ((void *)mmap_buffer_aligned, (size_t)mmap_size, 0); + if (*mhandlep == EXS_MHANDLE_INVALID) { + perror ("allocate_exs_buffer_ring: exs_mregister failed"); + exit (1); + } + if (debug) { + fprintf (where, "allocate_exs_buffer_ring: mhandle=%d\n", + *mhandlep); + } + + /* allocate ring elements */ + first_link = (struct ring_elt *) malloc (width * sizeof (struct ring_elt)); + if (first_link == NULL) { + printf ("malloc(%d) failed!\n", width * sizeof (struct ring_elt)); + exit (1); + } + + /* initialize buffer ring */ + prev_link = first_link + width - 1; + + for (i = 0, temp_link = first_link; i < width; i++, temp_link++) { + + temp_link->buffer_base = (char *) mmap_buffer_aligned + (i*malloc_size); +#ifndef WIN32 + temp_link->buffer_ptr = (char *) + (((long)temp_link->buffer_base + (long)alignment - 1) & + ~((long)alignment - 1)); +#else + temp_link->buffer_ptr = (char *) + (((ULONG_PTR)temp_link->buffer_base + (ULONG_PTR)alignment - 1) & + ~((ULONG_PTR)alignment - 1)); +#endif + temp_link->buffer_ptr += offset; + + if (debug) { + fprintf (where, "allocate_exs_buffer_ring: " + "buffer: index=%d base=0x%p ptr=0x%p\n", + i, temp_link->buffer_base, temp_link->buffer_ptr); + } + + /* is where the buffer fill code goes. */ + if (do_fill) { + bytes_left = buffer_size; + while (bytes_left) { + if (((bytes_read = (int) fread (temp_link->buffer_ptr, + 1, + bytes_left, + fill_source)) == 0) && + (feof (fill_source))) { + rewind (fill_source); + } + bytes_left -= bytes_read; + } + } + + /* do linking */ + prev_link->next = temp_link; + prev_link = temp_link; + } + + return (first_link); /* it's a circle, doesn't matter which we return */ +} + +#endif /* HAVE_ICSC_EXS */ + + + +#ifdef HAVE_SENDFILE +/* this routine will construct a ring of sendfile_ring_elt structs + that the routine sendfile_tcp_stream() will use to get parameters + to its calls to sendfile(). It will setup the ring to point at the + file specified in the global -F option that is already used to + pre-fill buffers in the send() case. 08/2000 + + if there is no file specified in a global -F option, we will create + a tempoarary file and fill it with random data and use that + instead. raj 2007-08-09 */ + +struct sendfile_ring_elt * +alloc_sendfile_buf_ring(int width, + int buffer_size, + int alignment, + int offset) + +{ + + struct sendfile_ring_elt *first_link = NULL; + struct sendfile_ring_elt *temp_link = NULL; + struct sendfile_ring_elt *prev_link; + + int i; + int fildes; + struct stat statbuf; + + /* if the user has not specified a file with the -F option, we will + fail the test. otherwise, go ahead and try to open the + file. 08/2000 */ + if (strcmp(fill_file,"") == 0) { + /* use an temp file for the fill file */ + char temp_file[] = {"netperfXXXXXX\0"}; + int *temp_buffer; + + /* make sure we have at least an ints worth, even if the user is + using an insane buffer size for a sendfile test. we are + ass-u-me-ing that malloc will return something at least aligned + on an int boundary... */ + temp_buffer = (int *) malloc(buffer_size + sizeof(int)); + if (temp_buffer) { + /* ok, we have the buffer we are going to write, lets get a + temporary filename */ + fildes = mkstemp(temp_file); + /* no need to call open because mkstemp did it */ + if (-1 != fildes) { + int count; + int *int_ptr; + + /* initialize the random number generator */ + srand(getpid()); + + /* unlink the file so it goes poof when we + exit. unless/until shown to be a problem we will + blissfully ignore the return value. raj 2007-08-09 */ + unlink(temp_file); + + /* now fill-out the file with at least buffer_size * width bytes */ + for (count = 0; count < width; count++) { + /* fill the buffer with random data. it doesn't have to be + really random, just "random enough" :) we do this here rather + than up above because we want each write to the file to be + different random data */ + int_ptr = temp_buffer; + for (i = 0; i <= buffer_size/sizeof(int); i++) { + *int_ptr = rand(); + int_ptr++; + } + if (write(fildes,temp_buffer,buffer_size+sizeof(int)) != + buffer_size + sizeof(int)) { + perror("allocate_sendfile_buf_ring: incomplete write"); + exit(-1); + } + } + } + else { + perror("alloc_sendfile_buf_ring: could not allocate temp name"); + exit(-1); + } + } + else { + perror("alloc_sendfile_buf_ring: could not allocate buffer for file"); + exit(-1); + } + } + else { + /* the user pointed us at a file, so try it */ + fildes = open(fill_file , O_RDONLY); + if (fildes == -1){ + perror("alloc_sendfile_buf_ring: Could not open requested file"); + exit(1); + } + /* make sure there is enough file there to allow us to make a + complete ring. that way we do not need additional logic in the + ring setup to deal with wrap-around issues. we might want that + someday, but not just now. 08/2000 */ + if (stat(fill_file,&statbuf) != 0) { + perror("alloc_sendfile_buf_ring: could not stat file"); + exit(1); + } + if (statbuf.st_size < (width * buffer_size)) { + /* the file is too short */ + fprintf(stderr,"alloc_sendfile_buf_ring: specified file too small.\n"); + fprintf(stderr,"file must be larger than send_width * send_size\n"); + fflush(stderr); + exit(1); + } + } + + /* so, at this point we know that fildes is a descriptor which + references a file of sufficient size for our nefarious + porpoises. raj 2007-08-09 */ + + prev_link = NULL; + for (i = 1; i <= width; i++) { + /* get the ring element. we should probably make sure the malloc() + was successful, but for now we'll just let the code bomb + mysteriously. 08/2000 */ + + temp_link = (struct sendfile_ring_elt *) + malloc(sizeof(struct sendfile_ring_elt)); + if (temp_link == NULL) { + printf("malloc(%u) failed!\n", sizeof(struct sendfile_ring_elt)); + exit(1); + } + + /* remember the first one so we can close the ring at the end */ + + if (i == 1) { + first_link = temp_link; + } + + /* now fill-in the fields of the structure with the apropriate + stuff. just how should we deal with alignment and offset I + wonder? until something better comes-up, I think we will just + ignore them. 08/2000 */ + + temp_link->fildes = fildes; /* from which file do we send? */ + temp_link->offset = offset; /* starting at which offset? */ + offset += buffer_size; /* get ready for the next elt */ + temp_link->length = buffer_size; /* how many bytes to send */ + temp_link->hdtrl = NULL; /* no header or trailer */ + temp_link->flags = 0; /* no flags */ + + /* is where the buffer fill code went. */ + + temp_link->next = prev_link; + prev_link = temp_link; + } + /* close the ring */ + first_link->next = temp_link; + + return(first_link); /* it's a dummy ring */ +} + +#endif /* HAVE_SENDFILE */ + + + /***********************************************************************/ + /* */ + /* dump_request() */ + /* */ + /* display the contents of the request array to the user. it will */ + /* display the contents in decimal, hex, and ascii, with four bytes */ + /* per line. */ + /* */ + /***********************************************************************/ + +void +dump_request() +{ +int counter = 0; +fprintf(where,"request contents:\n"); +for (counter = 0; counter < ((sizeof(netperf_request)/4)-3); counter += 4) { + fprintf(where,"%d:\t%8x %8x %8x %8x \t|%4.4s| |%4.4s| |%4.4s| |%4.4s|\n", + counter, + request_array[counter], + request_array[counter+1], + request_array[counter+2], + request_array[counter+3], + (char *)&request_array[counter], + (char *)&request_array[counter+1], + (char *)&request_array[counter+2], + (char *)&request_array[counter+3]); +} +fflush(where); +} + + + /***********************************************************************/ + /* */ + /* dump_response() */ + /* */ + /* display the content of the response array to the user. it will */ + /* display the contents in decimal, hex, and ascii, with four bytes */ + /* per line. */ + /* */ + /***********************************************************************/ + +void +dump_response() +{ +int counter = 0; + +fprintf(where,"response contents\n"); +for (counter = 0; counter < ((sizeof(netperf_response)/4)-3); counter += 4) { + fprintf(where,"%d:\t%8x %8x %8x %8x \t>%4.4s< >%4.4s< >%4.4s< >%4.4s<\n", + counter, + response_array[counter], + response_array[counter+1], + response_array[counter+2], + response_array[counter+3], + (char *)&response_array[counter], + (char *)&response_array[counter+1], + (char *)&response_array[counter+2], + (char *)&response_array[counter+3]); +} +fflush(where); +} + + /* + + format_number() + + return a pointer to a formatted string containing the value passed + translated into the units specified. It assumes that the base units + are bytes. If the format calls for bits, it will use SI units (10^) + if the format calls for bytes, it will use CS units (2^)... This + routine should look familiar to uses of the latest ttcp... + + we would like to use "t" or "T" for transactions, but probably + should leave those for terabits and terabytes respectively, so for + transactions, we will use "x" which will, by default, do absolutely + nothing to the result. why? so we don't have to special case code + elsewhere such as in the TCP_RR-as-bidirectional test case. + + */ + + +char * +format_number(double number) +{ + static char fmtbuf[64]; + + switch (libfmt) { + case 'K': + snprintf(fmtbuf, sizeof(fmtbuf), "%-7.2f" , number / 1024.0); + break; + case 'M': + snprintf(fmtbuf, sizeof(fmtbuf), "%-7.2f", number / 1024.0 / 1024.0); + break; + case 'G': + snprintf(fmtbuf, sizeof(fmtbuf), "%-7.2f", number / 1024.0 / 1024.0 / 1024.0); + break; + case 'k': + snprintf(fmtbuf, sizeof(fmtbuf), "%-7.2f", number * 8 / 1000.0); + break; + case 'm': + snprintf(fmtbuf, sizeof(fmtbuf), "%-7.2f", number * 8 / 1000.0 / 1000.0); + break; + case 'g': + snprintf(fmtbuf, sizeof(fmtbuf), "%-7.2f", number * 8 / 1000.0 / 1000.0 / 1000.0); + break; + case 'x': + snprintf(fmtbuf, sizeof(fmtbuf), "%-7.2f", number); + break; + default: + snprintf(fmtbuf, sizeof(fmtbuf), "%-7.2f", number / 1024.0); + } + + return fmtbuf; +} + +char +format_cpu_method(int method) +{ + + char method_char; + + switch (method) { + case CPU_UNKNOWN: + method_char = 'U'; + break; + case HP_IDLE_COUNTER: + method_char = 'I'; + break; + case PSTAT: + method_char = 'P'; + break; + case KSTAT: + method_char = 'K'; + break; + case KSTAT_10: + method_char = 'M'; + break; + case PERFSTAT: + method_char = 'E'; + break; + case TIMES: /* historical only, completely unsuitable + for netperf's purposes */ + method_char = 'T'; + break; + case GETRUSAGE: /* historical only, completely unsuitable + for netperf;s purposes */ + method_char = 'R'; + break; + case LOOPER: + method_char = 'L'; + break; + case NT_METHOD: + method_char = 'N'; + break; + case PROC_STAT: + method_char = 'S'; + break; + case SYSCTL: + method_char = 'C'; + break; + case OSX: + method_char = 'O'; + break; + default: + method_char = '?'; + } + + return method_char; + +} + +char * +format_units() +{ + static char unitbuf[64]; + + switch (libfmt) { + case 'K': + strcpy(unitbuf, "KBytes"); + break; + case 'M': + strcpy(unitbuf, "MBytes"); + break; + case 'G': + strcpy(unitbuf, "GBytes"); + break; + case 'k': + strcpy(unitbuf, "10^3bits"); + break; + case 'm': + strcpy(unitbuf, "10^6bits"); + break; + case 'g': + strcpy(unitbuf, "10^9bits"); + break; + case 'x': + strcpy(unitbuf, "Trans"); + break; + + default: + strcpy(unitbuf, "KBytes"); + } + + return unitbuf; +} + + +/****************************************************************/ +/* */ +/* shutdown_control() */ +/* */ +/* tear-down the control connection between me and the server. */ +/****************************************************************/ + +void +shutdown_control() +{ + + char *buf = (char *)&netperf_response; + int buflen = sizeof(netperf_response); + + /* stuff for select, use fd_set for better compliance */ + fd_set readfds; + struct timeval timeout; + + if (debug) { + fprintf(where, + "shutdown_control: shutdown of control connection requested.\n"); + fflush(where); + } + + /* first, we say that we will be sending no more data on the */ + /* connection */ + if (shutdown(netlib_control,1) == SOCKET_ERROR) { + Print_errno(where, + "shutdown_control: error in shutdown"); + fflush(where); + exit(1); + } + + /* Now, we hang on a select waiting for the socket to become */ + /* readable to receive the shutdown indication from the remote. this */ + /* will be "just" like the recv_response() code */ + + /* we only select once. it is assumed that if the response is split */ + /* (which should not be happening, that we will receive the whole */ + /* thing and not have a problem ;-) */ + + FD_ZERO(&readfds); + FD_SET(netlib_control,&readfds); + timeout.tv_sec = 60; /* wait one minute then punt */ + timeout.tv_usec = 0; + + /* select had better return one, or there was either a problem or a */ + /* timeout... */ + if (select(FD_SETSIZE, + &readfds, + 0, + 0, + &timeout) != 1) { + Print_errno(where, + "shutdown_control: no response received"); + fflush(where); + exit(1); + } + + /* we now assume that the socket has come ready for reading */ + recv(netlib_control, buf, buflen,0); + +} + +/* + bind_to_specific_processor will bind the calling process to the + processor in "processor" It has lots of ugly ifdefs to deal with + all the different ways systems do processor affinity. this is a + generalization of work initially done by stephen burger. raj + 2004/12/13 */ + +void +bind_to_specific_processor(int processor_affinity, int use_cpu_map) +{ + + int mapped_affinity; + + /* this is in place because the netcpu_looper processor affinity + ass-u-me-s a contiguous CPU id space starting with 0. for the + regular netperf/netserver affinity, we ass-u-me the user has used + a suitable CPU id even when the space is not contiguous and + starting from zero */ + if (use_cpu_map) { + mapped_affinity = lib_cpu_map[processor_affinity]; + } + else { + mapped_affinity = processor_affinity; + } + +#ifdef HAVE_MPCTL + /* indeed, at some point it would be a good idea to check the return + status and pass-along notification of error... raj 2004/12/13 */ + mpctl(MPC_SETPROCESS_FORCE, mapped_affinity, getpid()); +#elif HAVE_PROCESSOR_BIND +#include +#include +#include + processor_bind(P_PID,P_MYID,mapped_affinity,NULL); +#elif HAVE_BINDPROCESSOR +#include + /* this is the call on AIX. It takes a "what" of BINDPROCESS or + BINDTHRAD, then "who" and finally "where" which is a CPU number + or it seems PROCESSOR_CLASS_ANY there also seems to be a mycpu() + call to return the current CPU assignment. this is all based on + the sys/processor.h include file. from empirical testing, it + would seem that the my_cpu() call returns the current CPU on + which we are running rather than the CPU binding, so it's return + value will not tell you if you are bound vs unbound. */ + bindprocessor(BINDPROCESS,getpid(),(cpu_t)mapped_affinity); +#elif HAVE_SCHED_SETAFFINITY +#include + /* in theory this should cover systems with more CPUs than bits in a + long, without having to specify __USE_GNU. we "cheat" by taking + defines from /usr/include/bits/sched.h, which we ass-u-me is + included by . If they are not there we will just + fall-back on what we had before, which is to use just the size of + an unsigned long. raj 2006-09-14 */ + +#if defined(__CPU_SETSIZE) +#define NETPERF_CPU_SETSIZE __CPU_SETSIZE +#if defined(__CPU_SET_S) +#define NETPERF_CPU_SET(cpu, cpusetp) __CPU_SET_S(cpu, sizeof (cpu_set_t), cpusetp) +#define NETPERF_CPU_ZERO(cpusetp) __CPU_ZERO_S (sizeof (cpu_set_t), cpusetp) +#else +#define NETPERF_CPU_SET(cpu, cpusetp) __CPU_SET(cpu, cpusetp) +#define NETPERF_CPU_ZERO(cpusetp) __CPU_ZERO (cpusetp) +#endif + typedef cpu_set_t netperf_cpu_set_t; +#else +#define NETPERF_CPU_SETSIZE sizeof(unsigned long) +#define NETPERF_CPU_SET(cpu, cpusetp) *cpusetp = 1 << cpu +#define NETPERF_CPU_ZERO(cpusetp) *cpusetp = (unsigned long)0 + typedef unsigned long netperf_cpu_set_t; +#endif + + netperf_cpu_set_t netperf_cpu_set; + unsigned int len = sizeof(netperf_cpu_set); + + if (mapped_affinity < 8*sizeof(netperf_cpu_set)) { + NETPERF_CPU_ZERO(&netperf_cpu_set); + NETPERF_CPU_SET(mapped_affinity,&netperf_cpu_set); + + if (sched_setaffinity(getpid(), len, &netperf_cpu_set)) { + if (debug) { + fprintf(stderr, "failed to set PID %d's CPU affinity errno %d\n", + getpid(),errno); + fflush(stderr); + } + } + } + else { + if (debug) { + fprintf(stderr, + "CPU number larger than pre-compiled limits. Consider a recompile.\n"); + fflush(stderr); + } + } + +#elif HAVE_BIND_TO_CPU_ID + /* this is the one for Tru64 */ +#include +#include +#include + + /* really should be checking a return code one of these days. raj + 2005/08/31 */ + + bind_to_cpu_id(getpid(), mapped_affinity,0); + +#elif WIN32 + + { + ULONG_PTR AffinityMask; + ULONG_PTR ProcessAffinityMask; + ULONG_PTR SystemAffinityMask; + + if ((mapped_affinity < 0) || + (mapped_affinity > MAXIMUM_PROCESSORS)) { + fprintf(where, + "Invalid processor_affinity specified: %d\n", mapped_affinity); fflush(where); + return; + } + + if (!GetProcessAffinityMask( + GetCurrentProcess(), + &ProcessAffinityMask, + &SystemAffinityMask)) + { + perror("GetProcessAffinityMask failed"); + fflush(stderr); + exit(1); + } + + AffinityMask = (ULONG_PTR)1 << mapped_affinity; + + if (AffinityMask & ProcessAffinityMask) { + if (!SetThreadAffinityMask( GetCurrentThread(), AffinityMask)) { + perror("SetThreadAffinityMask failed"); + fflush(stderr); + } + } else if (debug) { + fprintf(where, + "Processor affinity set to CPU# %d\n", mapped_affinity); + fflush(where); + } + } + +#else + if (debug) { + fprintf(where, + "Processor affinity not available for this platform!\n"); + fflush(where); + } +#endif +} + + +/* + * Sets a socket to non-blocking operation. + */ +int +set_nonblock (SOCKET sock) +{ +#ifdef WIN32 + unsigned long flags = 1; + return (ioctlsocket(sock, FIONBIO, &flags) != SOCKET_ERROR); +#else + return (fcntl(sock, F_SETFL, O_NONBLOCK) != -1); +#endif +} + + + +/* send a request, only converting the first n ints-worth of the + test-specific data via htonl() before sending on the + connection. the first two ints, which are before the test-specific + portion are always converted. raj 2008-02-05 */ + +void +send_request_n(int n) +{ + + int counter,count; + + if (n < 0) count = sizeof(netperf_request)/4; + else count = 2 + n; + + /* silently truncate if the caller called for more than we have */ + if (count > sizeof(netperf_request)/4) { + if (debug > 1) { + fprintf(where, + "WARNING, htonl conversion count of %d was larger than netperf_request\n", + count - 2); + fflush(where); + } + count = sizeof(netperf_request)/4; + } + + /* display the contents of the request if the debug level is high */ + /* enough. otherwise, just send the darned thing ;-) */ + + if (debug > 1) { + fprintf(where, + "entered send_request_n...contents before %d htonls:\n", + count); + dump_request(); + } + + /* pass the processor affinity request value to netserver this is a + kludge and I know it. sgb 8/11/04. we keep this here to deal with + there being two paths to this place - direct and via + send_request() */ + + netperf_request.content.dummy = remote_proc_affinity; + + /* put the entire request array into network order. We do this */ + /* arbitrarily rather than trying to figure-out just how much */ + /* of the request array contains real information. this should */ + /* be simpler, and at any rate, the performance of sending */ + /* control messages for this benchmark is not of any real */ + /* concern. */ + + for (counter = 0;counter < count; counter++) { + request_array[counter] = htonl(request_array[counter]); + } + + if (debug > 1) { + fprintf(where,"send_request_n...contents after %d htonls:\n", + count); + dump_request(); + + fprintf(where, + "\nsend_request: about to send %u bytes from %p\n", + sizeof(netperf_request), + &netperf_request); + fflush(where); + } + + if (send(netlib_control, + (char *)&netperf_request, + sizeof(netperf_request), + 0) != sizeof(netperf_request)) { + perror("send_request: send call failure"); + + exit(1); + } +} + + /***********************************************************************/ + /* */ + /* send_request() */ + /* */ + /* send a netperf request on the control socket to the remote half of */ + /* the connection. to get us closer to intervendor interoperability, */ + /* we will call htonl on each of the int that compose the message to */ + /* be sent. the server-half of the connection will call the ntohl */ + /* routine to undo any changes that may have been made... */ + /* */ + /***********************************************************************/ + +void +send_request() +{ + + /* pass the processor affinity request value to netserver */ + /* this is a kludge and I know it. sgb 8/11/04 */ + + netperf_request.content.dummy = remote_proc_affinity; + + /* call send_request_n telling it to convert everything */ + + send_request_n(-1); + +} + +/* send a response, only converting the first n ints-worth of the + test-specific data via htonl() before sending on the + connection. the first two ints, which are before the test-specific + portion are always converted. raj 2008-02-05 */ + +void +send_response_n(int n) +{ + int counter, count; + int bytes_sent; + + if (n < 0) count = sizeof(netperf_request)/4; + else count = 2 + n; + + /* silently truncate if the caller called for more than we have */ + if (count > sizeof(netperf_request)/4) { + if (debug > 1) { + fprintf(where, + "WARNING, htonl conversion count of %d was larger than netperf_request\n", + count - 2); + fflush(where); + } + count = sizeof(netperf_request)/4; + } + + /* display the contents of the request if the debug level is high */ + /* enough. otherwise, just send the darned thing ;-) */ + + if (debug > 1) { + fprintf(where, + "send_response_n: contents of %u ints before %d htonl,\n", + sizeof(netperf_response)/4, + count); + dump_response(); + } + + /* put the entire response_array into network order. We do this */ + /* arbitrarily rather than trying to figure-out just how much of the */ + /* request array contains real information. this should be simpler, */ + /* and at any rate, the performance of sending control messages for */ + /* this benchmark is not of any real concern. */ + + for (counter = 0; counter < count; counter++) { + response_array[counter] = htonl(response_array[counter]); + } + + if (debug > 1) { + fprintf(where, + "send_response_n: contents after htonl\n"); + dump_response(); + fprintf(where, + "about to send %u bytes from %p\n", + sizeof(netperf_response), + &netperf_response); + fflush(where); + } + + /*KC*/ + if ((bytes_sent = send(server_sock, + (char *)&netperf_response, + sizeof(netperf_response), + 0)) != sizeof(netperf_response)) { + perror("send_response_n: send call failure"); + fprintf(where, "BytesSent: %d\n", bytes_sent); + exit(1); + } + +} + +/***********************************************************************/ + /* */ + /* send_response() */ + /* */ + /* send a netperf response on the control socket to the remote half of */ + /* the connection. to get us closer to intervendor interoperability, */ + /* we will call htonl on each of the int that compose the message to */ + /* be sent. the other half of the connection will call the ntohl */ + /* routine to undo any changes that may have been made... */ + /* */ + /***********************************************************************/ + +void +send_response() +{ + + send_response_n(-1); + +} + +/* receive a request, only converting the first n ints-worth of the + test-specific data via htonl() before sending on the + connection. the first two ints, which are before the test-specific + portion are always converted. raj 2008-02-05 */ + +void +recv_request_n(int n) +{ +int tot_bytes_recvd, + bytes_recvd, + bytes_left; +char *buf = (char *)&netperf_request; +int buflen = sizeof(netperf_request); +int counter,count; + + if (n < 0) count = sizeof(netperf_request)/4; + else count = 2 + n; + + /* silently truncate if the caller called for more than we have */ + if (count > sizeof(netperf_request)/4) { + if (debug > 1) { + fprintf(where, + "WARNING, htonl conversion count of %d was larger than netperf_request\n", + count - 2); + fflush(where); + } + count = sizeof(netperf_request)/4; + } + + tot_bytes_recvd = 0; + bytes_recvd = 0; /* nt_lint; bytes_recvd uninitialized if buflen == 0 */ + bytes_left = buflen; + while ((tot_bytes_recvd != buflen) && + ((bytes_recvd = recv(server_sock, buf, bytes_left,0)) > 0 )) { + tot_bytes_recvd += bytes_recvd; + buf += bytes_recvd; + bytes_left -= bytes_recvd; + } + + /* put the request into host order */ + + for (counter = 0; counter < count; counter++) { + request_array[counter] = ntohl(request_array[counter]); + } + + if (debug) { + fprintf(where, + "recv_request: received %d bytes of request.\n", + tot_bytes_recvd); + fflush(where); + } + + if (bytes_recvd == SOCKET_ERROR) { + Print_errno(where, + "recv_request: error on recv"); + fflush(where); + exit(1); + } + + if (bytes_recvd == 0) { + /* the remote has shutdown the control connection, we should shut + it down as well and exit */ + if (debug) { + fprintf(where, + "recv_request: remote requested shutdown of control\n"); + fflush(where); + } + + if (netlib_control != INVALID_SOCKET) { + shutdown_control(); + } + exit(0); + } + + if (tot_bytes_recvd < buflen) { + if (debug > 1) + dump_request(); + + fprintf(where, + "recv_request: partial request received of %d bytes\n", + tot_bytes_recvd); + fflush(where); + exit(1); + } + + if (debug > 1) { + dump_request(); + } + + /* get the processor affinity request value from netperf */ + /* this is a kludge and I know it. sgb 8/11/04 */ + + local_proc_affinity = netperf_request.content.dummy; + + if (local_proc_affinity != -1) { + bind_to_specific_processor(local_proc_affinity,0); + } + +} + + /***********************************************************************/ + /* */ + /* recv_request() */ + /* */ + /* receive the remote's request on the control socket. we will put */ + /* the entire response into host order before giving it to the */ + /* calling routine. hopefully, this will go most of the way to */ + /* insuring intervendor interoperability. if there are any problems, */ + /* we will just punt the entire situation. */ + /* */ + /***********************************************************************/ + +void +recv_request() +{ + + recv_request_n(-1); + +} + +void +recv_response_timed_n(int addl_time, int n) +{ + int tot_bytes_recvd, + bytes_recvd = 0, + bytes_left; + char *buf = (char *)&netperf_response; + int buflen = sizeof(netperf_response); + int counter,count; + + /* stuff for select, use fd_set for better compliance */ + fd_set readfds; + struct timeval timeout; + + tot_bytes_recvd = 0; + bytes_left = buflen; + + if (n < 0) count = sizeof(netperf_request)/4; + else count = 2 + n; + + /* silently truncate if the caller called for more than we have */ + if (count > sizeof(netperf_request)/4) { + if (debug > 1) { + fprintf(where, + "WARNING, htonl conversion count of %d was larger than netperf_response\n", + count - 2); + fflush(where); + } + count = sizeof(netperf_request)/4; + } + + /* zero out the response structure */ + + /* BUG FIX SJB 2/4/93 - should be < not <= */ + for (counter = 0; + counter < sizeof(netperf_response)/sizeof(int); + counter++) { + response_array[counter] = 0; + } + + /* we only select once. it is assumed that if the response is split */ + /* (which should not be happening, that we will receive the whole */ + /* thing and not have a problem ;-) */ + + FD_ZERO(&readfds); + FD_SET(netlib_control,&readfds); + timeout.tv_sec = 120 + addl_time; /* wait at least two minutes + before punting - the + USE_LOOPER CPU stuff may + cause remote's to have a bit + longer time of it than 60 + seconds would allow. + triggered by fix from Jeff + Dwork. */ + timeout.tv_usec = 0; + + /* select had better return one, or there was either a problem or a */ + /* timeout... */ + + if ((counter = select(FD_SETSIZE, + &readfds, + 0, + 0, + &timeout)) != 1) { + fprintf(where, + "netperf: receive_response: no response received. errno %d counter %d\n", + errno, + counter); + exit(1); + } + + while ((tot_bytes_recvd != buflen) && + ((bytes_recvd = recv(netlib_control, buf, bytes_left,0)) > 0 )) { + tot_bytes_recvd += bytes_recvd; + buf += bytes_recvd; + bytes_left -= bytes_recvd; + } + + if (debug) { + fprintf(where,"recv_response: received a %d byte response\n", + tot_bytes_recvd); + fflush(where); + } + + /* put the desired quantity of the response into host order */ + + for (counter = 0; counter < count; counter++) { + response_array[counter] = ntohl(response_array[counter]); + } + + if (bytes_recvd == SOCKET_ERROR) { + perror("recv_response"); + exit(1); + } + if (tot_bytes_recvd < buflen) { + fprintf(stderr, + "recv_response: partial response received: %d bytes\n", + tot_bytes_recvd); + fflush(stderr); + if (debug > 1) + dump_response(); + exit(1); + } + if (debug > 1) { + dump_response(); + } +} + + /* + + recv_response_timed() + + receive the remote's response on the control socket. we will put the + entire response into host order before giving it to the calling + routine. hopefully, this will go most of the way to insuring + intervendor interoperability. if there are any problems, we will just + punt the entire situation. + + The call to select at the beginning is to get us out of hang + situations where the remote gives-up but we don't find-out about + it. This seems to happen only rarely, but it would be nice to be + somewhat robust ;-) + + The "_timed" part is to allow the caller to add (or I suppose + subtract) from the length of timeout on the select call. this was + added since not all the CPU utilization mechanisms require a 40 + second calibration, and we used to have an aribtrary 40 second sleep + in "calibrate_remote_cpu" - since we don't _always_ need that, we + want to simply add 40 seconds to the select() timeout from that call, + but don't want to change all the "recv_response" calls in the code + right away. sooo, we push the functionality of the old + recv_response() into a new recv_response_timed(addl_timout) call, and + have recv_response() call recv_response_timed(0). raj 2005-05-16 + + */ + + +void +recv_response_timed(int addl_time) +{ + + /* -1 => convert all the test-specific data via ntohl */ + recv_response_timed_n(addl_time,-1); + +} + +void +recv_response() +{ + /* 0 => no additional time, -1 => convert all test-specific data */ + recv_response_timed_n(0,-1); +} + +void +recv_response_n(int n) +{ + recv_response_timed_n(0,n); +} + +void +get_remote_system_info() +{ + char delim[2]; + char *token; + + netperf_request.content.request_type = DO_SYSINFO; + send_request(); + recv_response_n(0); + if (!netperf_response.content.serv_errno) { + delim[1] = '\0'; + delim[0] = *(char *)netperf_response.content.test_specific_data; +#if 0 + token = (char *)netperf_response.content.test_specific_data + + (sizeof(netperf_response) - 7); /* OBOB? */ + *token = 0; +#endif + + token = strtok((char *)netperf_response.content.test_specific_data,delim); + if (token) remote_sysname = strdup(token); + else remote_sysname = strdup("UnknownRemoteSysname"); + token = strtok(NULL,delim); + if (token) remote_release = strdup(token); + else remote_release = strdup("UnknownRemoteRelease"); + token = strtok(NULL,delim); + if (token) remote_machine = strdup(token); + else remote_machine = strdup("UnknownRemoteMachine"); + token = strtok(NULL,delim); + if (token) remote_version = strdup(token); + else remote_version = strdup("UnknownRemoteVersion"); + } + else { + remote_sysname = strdup("UnknownRemoteSysname"); + remote_release = strdup("UnknownRemoteRelease"); + remote_machine = strdup("UnknownRemoteMachine"); + remote_version = strdup("UnknownRemoteVersion"); + } + +} + + + +#if defined(USE_PSTAT) || defined (USE_SYSCTL) +int +hi_32(big_int) + long long *big_int; +{ + union overlay_u { + long long dword; + long words[2]; + } *overlay; + + overlay = (union overlay_u *)big_int; + /* on those systems which are byte swapped, we really wish to */ + /* return words[1] - at least I think so - raj 4/95 */ + if (htonl(1L) == 1L) { + /* we are a "normal" :) machine */ + return(overlay->words[0]); + } + else { + return(overlay->words[1]); + } +} + +int +lo_32(big_int) + long long *big_int; +{ + union overlay_u { + long long dword; + long words[2]; + } *overlay; + + overlay = (union overlay_u *)big_int; + /* on those systems which are byte swapped, we really wish to */ + /* return words[0] - at least I think so - raj 4/95 */ + if (htonl(1L) == 1L) { + /* we are a "normal" :) machine */ + return(overlay->words[1]); + } + else { + return(overlay->words[0]); + } +} + +#endif /* USE_PSTAT || USE_SYSCTL */ + + +void libmain() +{ +fprintf(where,"hello world\n"); +fprintf(where,"debug: %d\n",debug); +} + + +void +get_sock_buffer (SOCKET sd, enum sock_buffer which, int *effective_sizep) +{ +#ifdef SO_SNDBUF + int optname = (which == SEND_BUFFER) ? SO_SNDBUF : SO_RCVBUF; + netperf_socklen_t sock_opt_len; + + sock_opt_len = sizeof(*effective_sizep); + if (getsockopt(sd, SOL_SOCKET, optname, (char *)effective_sizep, + &sock_opt_len) < 0) { + fprintf(where, "netperf: get_sock_buffer: getsockopt %s: errno %d\n", + (which == SEND_BUFFER) ? "SO_SNDBUF" : "SO_RCVBUF", errno); + fflush(where); + *effective_sizep = -1; + } + + if (debug) { + fprintf(where, "netperf: get_sock_buffer: " + "%s socket size determined to be %d\n", + (which == SEND_BUFFER) ? "send" : "receive", *effective_sizep); + fflush(where); + } + +#else + *effective_sizep = -1; +#endif +} + +void +set_sock_buffer (SOCKET sd, enum sock_buffer which, int requested_size, int *effective_sizep) +{ +#ifdef SO_SNDBUF + int optname = (which == SEND_BUFFER) ? SO_SNDBUF : SO_RCVBUF; + + /* seems that under Windows, setting a value of zero is how one + tells the stack you wish to enable copy-avoidance. Knuth only + knows what it will do on other stacks, but it might be + interesting to find-out, so we won't bother #ifdef'ing the change + to allow asking for 0 bytes. Courtesy of SAF, 2007-05 raj + 2007-05-31 */ + if (requested_size >= 0) { + if (setsockopt(sd, SOL_SOCKET, optname, + (char *)&requested_size, sizeof(int)) < 0) { + fprintf(where, "netperf: set_sock_buffer: %s option: errno %d\n", + (which == SEND_BUFFER) ? "SO_SNDBUF" : "SO_RCVBUF", + errno); + fflush(where); + exit(1); + } + if (debug > 1) { + fprintf(where, "netperf: set_sock_buffer: %s of %d requested.\n", + (which == SEND_BUFFER) ? "SO_SNDBUF" : "SO_RCVBUF", + requested_size); + fflush(where); + } + } + + /* the getsockopt() call that used to be here has been hoisted into + its own routine to be used on those platforms where the socket + buffer sizes might change from the beginning to the end of the + run. raj 2008-01-15 */ + + get_sock_buffer(sd, which, effective_sizep); + +#else /* SO_SNDBUF */ + *effective_size = -1; +#endif /* SO_SNDBUF */ +} + +void +dump_addrinfo(FILE *dumploc, struct addrinfo *info, + char *host, char *port, int family) +{ + struct sockaddr *ai_addr; + struct addrinfo *temp; + temp=info; + + fprintf(dumploc, "getaddrinfo returned the following for host '%s' ", host); + fprintf(dumploc, "port '%s' ", port); + fprintf(dumploc, "family %s\n", inet_ftos(family)); + while (temp) { + /* seems that Solaris 10 GA bits will not give a canonical name + for ::0 or 0.0.0.0, and their fprintf() cannot deal with a null + pointer, so we have to check for a null pointer. probably a + safe thing to do anyway, eventhough it was not necessary on + linux or hp-ux. raj 2005-02-09 */ + if (temp->ai_canonname) { + fprintf(dumploc, + "\tcannonical name: '%s'\n",temp->ai_canonname); + } + else { + fprintf(dumploc, + "\tcannonical name: '%s'\n","(nil)"); + } + fprintf(dumploc, + "\tflags: %x family: %s: socktype: %s protocol %s addrlen %d\n", + temp->ai_flags, + inet_ftos(temp->ai_family), + inet_ttos(temp->ai_socktype), + inet_ptos(temp->ai_protocol), + temp->ai_addrlen); + ai_addr = temp->ai_addr; + if (ai_addr != NULL) { + fprintf(dumploc, + "\tsa_family: %s sadata: %d %d %d %d %d %d\n", + inet_ftos(ai_addr->sa_family), + (u_char)ai_addr->sa_data[0], + (u_char)ai_addr->sa_data[1], + (u_char)ai_addr->sa_data[2], + (u_char)ai_addr->sa_data[3], + (u_char)ai_addr->sa_data[4], + (u_char)ai_addr->sa_data[5]); + } + temp = temp->ai_next; + } + fflush(dumploc); +} + +/* + establish_control() + +set-up the control connection between netperf and the netserver so we +can actually run some tests. if we cannot establish the control +connection, that may or may not be a good thing, so we will let the +caller decide what to do. + +to assist with pesky end-to-end-unfriendly things like firewalls, we +allow the caller to specify both the remote hostname and port, and the +local addressing info. i believe that in theory it is possible to +have an IPv4 endpoint and an IPv6 endpoint communicate with one +another, but for the time being, we are only going to take-in one +requested address family parameter. this means that the only way +(iirc) that we might get a mixed-mode connection would be if the +address family is specified as AF_UNSPEC, and getaddrinfo() returns +different families for the local and server names. + +the "names" can also be IP addresses in ASCII string form. + +raj 2003-02-27 */ + +SOCKET +establish_control_internal(char *hostname, + char *port, + int remfam, + char *localhost, + char *localport, + int locfam) +{ + int not_connected; + SOCKET control_sock; + int count; + int error; + + struct addrinfo hints; + struct addrinfo *local_res; + struct addrinfo *remote_res; + struct addrinfo *local_res_temp; + struct addrinfo *remote_res_temp; + + if (debug) { + fprintf(where, + "establish_control called with host '%s' port '%s' remfam %s\n", + hostname, + port, + inet_ftos(remfam)); + fprintf(where, + "\t\tlocal '%s' port '%s' locfam %s\n", + localhost, + localport, + inet_ftos(locfam)); + fflush(where); + } + + /* first, we do the remote */ + memset(&hints, 0, sizeof(hints)); + hints.ai_family = remfam; + hints.ai_socktype = SOCK_STREAM; + hints.ai_protocol = IPPROTO_TCP; + hints.ai_flags = 0|AI_CANONNAME; + count = 0; + do { + error = getaddrinfo((char *)hostname, + (char *)port, + &hints, + &remote_res); + count += 1; + if (error == EAI_AGAIN) { + if (debug) { + fprintf(where,"Sleeping on getaddrinfo EAI_AGAIN\n"); + fflush(where); + } + sleep(1); + } + } while ((error == EAI_AGAIN) && (count <= 5)); + + if (error) { + printf("establish control: could not resolve remote '%s' port '%s' af %s", + hostname, + port, + inet_ftos(remfam)); + printf("\n\tgetaddrinfo returned %d %s\n", + error, + gai_strerror(error)); + return(INVALID_SOCKET); + } + + if (debug) { + dump_addrinfo(where, remote_res, hostname, port, remfam); + } + + /* now we do the local */ + memset(&hints, 0, sizeof(hints)); + hints.ai_family = locfam; + hints.ai_socktype = SOCK_STREAM; + hints.ai_protocol = IPPROTO_TCP; + hints.ai_flags = AI_PASSIVE|AI_CANONNAME; + count = 0; + do { + count += 1; + error = getaddrinfo((char *)localhost, + (char *)localport, + &hints, + &local_res); + if (error == EAI_AGAIN) { + if (debug) { + fprintf(where, + "Sleeping on getaddrinfo(%s,%s) EAI_AGAIN count %d \n", + localhost, + localport, + count); + fflush(where); + } + sleep(1); + } + } while ((error == EAI_AGAIN) && (count <= 5)); + + if (error) { + printf("establish control: could not resolve local '%s' port '%s' af %s", + localhost, + localport, + inet_ftos(locfam)); + printf("\n\tgetaddrinfo returned %d %s\n", + error, + gai_strerror(error)); + return(INVALID_SOCKET); + } + + if (debug) { + dump_addrinfo(where, local_res, localhost, localport, locfam); + } + + not_connected = 1; + local_res_temp = local_res; + remote_res_temp = remote_res; + /* we want to loop through all the possibilities. looping on the + local addresses will be handled within the while loop. I suppose + these is some more "C-expert" way to code this, but it has not + lept to mind just yet :) raj 2003-02024 */ + + while (remote_res_temp != NULL) { + + /* I am guessing that we should use the address family of the + local endpoint, and we will not worry about mixed family types + - presumeably the stack or other transition mechanisms will be + able to deal with that for us. famous last words :) raj 2003-02-26 */ + control_sock = socket(local_res_temp->ai_family, + SOCK_STREAM, + 0); + if (control_sock == INVALID_SOCKET) { + /* at some point we'll need a more generic "display error" + message for when/if we use GUIs and the like. unlike a bind + or connect failure, failure to allocate a socket is + "immediately fatal" and so we return to the caller. raj 2003-02-24 */ + if (debug) { + perror("establish_control: unable to allocate control socket"); + } + return(INVALID_SOCKET); + } + + /* if we are going to control the local enpoint addressing, we + need to call bind. of course, we should probably be setting one + of the SO_REUSEmumble socket options? raj 2005-02-04 */ + if (bind(control_sock, + local_res_temp->ai_addr, + local_res_temp->ai_addrlen) == 0) { + if (debug) { + fprintf(where, + "bound control socket to %s and %s\n", + localhost, + localport); + } + + if (connect(control_sock, + remote_res_temp->ai_addr, + remote_res_temp->ai_addrlen) == 0) { + /* we have successfully connected to the remote netserver */ + if (debug) { + fprintf(where, + "successful connection to remote netserver at %s and %s\n", + hostname, + port); + } + not_connected = 0; + /* this should get us out of the while loop */ + break; + } else { + /* the connect call failed */ + if (debug) { + fprintf(where, + "establish_control: connect failed, errno %d %s\n", + errno, + strerror(errno)); + fprintf(where, " trying next address combination\n"); + fflush(where); + } + } + } + else { + /* the bind failed */ + if (debug) { + fprintf(where, + "establish_control: bind failed, errno %d %s\n", + errno, + strerror(errno)); + fprintf(where, " trying next address combination\n"); + fflush(where); + } + } + + if ((local_res_temp = local_res_temp->ai_next) == NULL) { + /* wrap the local and move to the next server, don't forget to + close the current control socket. raj 2003-02-24 */ + local_res_temp = local_res; + /* the outer while conditions will deal with the case when we + get to the end of all the possible remote addresses. */ + remote_res_temp = remote_res_temp->ai_next; + /* it is simplest here to just close the control sock. since + this is not a performance critical section of code, we + don't worry about overheads for socket allocation or + close. raj 2003-02-24 */ + } + close(control_sock); + } + + /* we no longer need the addrinfo stuff */ + freeaddrinfo(local_res); + freeaddrinfo(remote_res); + + /* so, we are either connected or not */ + if (not_connected) { + fprintf(where, "establish control: are you sure there is a netserver listening on %s at port %s?\n",hostname,port); + fflush(where); + return(INVALID_SOCKET); + } + /* at this point, we are connected. we probably want some sort of + version check with the remote at some point. raj 2003-02-24 */ + return(control_sock); +} + +void +establish_control(char *hostname, + char *port, + int remfam, + char *localhost, + char *localport, + int locfam) + +{ + + netlib_control = establish_control_internal(hostname, + port, + remfam, + localhost, + localport, + locfam); + if (netlib_control == INVALID_SOCKET) { + fprintf(where, + "establish_control could not establish the control connection from %s port %s address family %s to %s port %s address family %s\n", + localhost,localport,inet_ftos(locfam), + hostname,port,inet_ftos(remfam)); + fflush(where); + exit(INVALID_SOCKET); + } +} + + + + + /***********************************************************************/ + /* */ + /* get_id() */ + /* */ + /* Return a string to the calling routine that contains the */ + /* identifying information for the host we are running on. This */ + /* information will then either be displayed locally, or returned to */ + /* a remote caller for display there. */ + /* */ + /***********************************************************************/ + +char * +get_id() +{ + static char id_string[80]; +#ifdef WIN32 +char system_name[MAX_COMPUTERNAME_LENGTH+1] ; +DWORD name_len = MAX_COMPUTERNAME_LENGTH + 1 ; +#else +struct utsname system_name; +#endif /* WIN32 */ + +#ifdef WIN32 + SYSTEM_INFO SystemInfo; + GetSystemInfo( &SystemInfo ) ; + if ( !GetComputerName(system_name , &name_len) ) + strcpy(system_name , "no_name") ; +#else + if (uname(&system_name) <0) { + perror("identify_local: uname"); + exit(1); + } +#endif /* WIN32 */ + + snprintf(id_string, sizeof(id_string), +#ifdef WIN32 + "%-15s%-15s%d.%d%d", + "Windows NT", + system_name , + GetVersion() & 0xFF , + GetVersion() & 0xFF00 , + SystemInfo.dwProcessorType + +#else + "%-15s%-15s%-15s%-15s%-15s", + system_name.sysname, + system_name.nodename, + system_name.release, + system_name.version, + system_name.machine +#endif /* WIN32 */ + ); + return (id_string); +} + + + /***********************************************************************/ + /* */ + /* identify_local() */ + /* */ + /* Display identifying information about the local host to the user. */ + /* At first release, this information will be the same as that which */ + /* is returned by the uname -a command, with the exception of the */ + /* idnumber field, which seems to be a non-POSIX item, and hence */ + /* non-portable. */ + /* */ + /***********************************************************************/ + +void +identify_local() +{ + +char *local_id; + +local_id = get_id(); + +fprintf(where,"Local Information \n\ +Sysname Nodename Release Version Machine\n"); + +fprintf(where,"%s\n", + local_id); + +} + + + /***********************************************************************/ + /* */ + /* identify_remote() */ + /* */ + /* Display identifying information about the remote host to the user. */ + /* At first release, this information will be the same as that which */ + /* is returned by the uname -a command, with the exception of the */ + /* idnumber field, which seems to be a non-POSIX item, and hence */ + /* non-portable. A request is sent to the remote side, which will */ + /* return a string containing the utsname information in a */ + /* pre-formatted form, which is then displayed after the header. */ + /* */ + /***********************************************************************/ + +void +identify_remote() +{ + +char *remote_id=""; + +/* send a request for node info to the remote */ +netperf_request.content.request_type = NODE_IDENTIFY; + +send_request(); + +/* and now wait for the reply to come back */ + +recv_response(); + +if (netperf_response.content.serv_errno) { + Set_errno(netperf_response.content.serv_errno); + perror("identify_remote: on remote"); + exit(1); +} + +fprintf(where,"Remote Information \n\ +Sysname Nodename Release Version Machine\n"); + +fprintf(where,"%s", + remote_id); +} + +void +cpu_start(int measure_cpu) +{ + + gettimeofday(&time1, + &tz); + + if (measure_cpu) { + cpu_util_init(); + measuring_cpu = 1; + cpu_method = get_cpu_method(); + cpu_start_internal(); + } +} + + +void +cpu_stop(int measure_cpu, float *elapsed) + +{ + + int sec, + usec; + + if (measure_cpu) { + cpu_stop_internal(); + cpu_util_terminate(); + } + + gettimeofday(&time2, + &tz); + + if (time2.tv_usec < time1.tv_usec) { + time2.tv_usec += 1000000; + time2.tv_sec -= 1; + } + + sec = time2.tv_sec - time1.tv_sec; + usec = time2.tv_usec - time1.tv_usec; + lib_elapsed = (float)sec + ((float)usec/(float)1000000.0); + + *elapsed = lib_elapsed; + +} + + +double +calc_thruput_interval(double units_received,double elapsed) + +{ + double divisor; + + /* We will calculate the thruput in libfmt units/second */ + switch (libfmt) { + case 'K': + divisor = 1024.0; + break; + case 'M': + divisor = 1024.0 * 1024.0; + break; + case 'G': + divisor = 1024.0 * 1024.0 * 1024.0; + break; + case 'k': + divisor = 1000.0 / 8.0; + break; + case 'm': + divisor = 1000.0 * 1000.0 / 8.0; + break; + case 'g': + divisor = 1000.0 * 1000.0 * 1000.0 / 8.0; + break; + case 'x': + divisor = 1.0; + break; + + default: + divisor = 1024.0; + } + + return (units_received / divisor / elapsed); + +} + +double +calc_thruput(double units_received) + +{ + return(calc_thruput_interval(units_received,lib_elapsed)); +} + +/* these "_omni" versions are ones which understand 'x' as a unit, + meaning transactions/s. we have a separate routine rather than + convert the existing routine so we don't have to go and change + _all_ the nettest_foo.c files at one time. raj 2007-06-08 */ + +double +calc_thruput_interval_omni(double units_received,double elapsed) + +{ + double divisor; + + /* We will calculate the thruput in libfmt units/second */ + switch (libfmt) { + case 'K': + divisor = 1024.0; + break; + case 'M': + divisor = 1024.0 * 1024.0; + break; + case 'G': + divisor = 1024.0 * 1024.0 * 1024.0; + break; + case 'k': + divisor = 1000.0 / 8.0; + break; + case 'm': + divisor = 1000.0 * 1000.0 / 8.0; + break; + case 'g': + divisor = 1000.0 * 1000.0 * 1000.0 / 8.0; + break; + case 'x': + divisor = 1.0; + break; + + default: + fprintf(where, + "WARNING calc_throughput_internal_omni: unknown units %c\n", + libfmt); + fflush(where); + divisor = 1024.0; + } + + return (units_received / divisor / elapsed); + +} + +double +calc_thruput_omni(double units_received) + +{ + return(calc_thruput_interval_omni(units_received,lib_elapsed)); +} + + + + + +float +calc_cpu_util(float elapsed_time) +{ + float temp_util; + int i; + temp_util = calc_cpu_util_internal(elapsed_time); + + /* now, what was the most utilized CPU and its util? */ + for (i = 0; i < MAXCPUS; i++) { + if (lib_local_per_cpu_util[i] > lib_local_peak_cpu_util) { + lib_local_peak_cpu_util = lib_local_per_cpu_util[i]; + lib_local_peak_cpu_id = lib_cpu_map[i]; + } + } + + return temp_util; +} + +float +calc_service_demand_internal(double unit_divisor, + double units_sent, + float elapsed_time, + float cpu_utilization, + int num_cpus) + +{ + + double service_demand; + double thruput; + + if (debug) { + fprintf(where,"calc_service_demand called: units_sent = %f\n", + units_sent); + fprintf(where," elapsed_time = %f\n", + elapsed_time); + fprintf(where," cpu_util = %f\n", + cpu_utilization); + fprintf(where," num cpu = %d\n", + num_cpus); + fflush(where); + } + + if (num_cpus == 0) num_cpus = lib_num_loc_cpus; + + if (elapsed_time == 0.0) { + elapsed_time = lib_elapsed; + } + if (cpu_utilization == 0.0) { + cpu_utilization = lib_local_cpu_util; + } + + thruput = (units_sent / + (double) unit_divisor / + (double) elapsed_time); + + /* on MP systems, it is necessary to multiply the service demand by */ + /* the number of CPU's. at least, I believe that to be the case:) */ + /* raj 10/95 */ + + /* thruput has a "per second" component. if we were using 100% ( */ + /* 100.0) of the CPU in a second, that would be 1 second, or 1 */ + /* millisecond, so we multiply cpu_utilization by 10 to go to */ + /* milliseconds, or 10,000 to go to micro seconds. With revision */ + /* 2.1, the service demand measure goes to microseconds per unit. */ + /* raj 12/95 */ + service_demand = (cpu_utilization*10000.0/thruput) * + (float) num_cpus; + + if (debug) { + fprintf(where,"calc_service_demand using: units_sent = %f\n", + units_sent); + fprintf(where," elapsed_time = %f\n", + elapsed_time); + fprintf(where," cpu_util = %f\n", + cpu_utilization); + fprintf(where," num cpu = %d\n", + num_cpus); + fprintf(where,"calc_service_demand got: thruput = %f\n", + thruput); + fprintf(where," servdem = %f\n", + service_demand); + fflush(where); + } + return (float)service_demand; +} + +float calc_service_demand(double units_sent, + float elapsed_time, + float cpu_utilization, + int num_cpus) + +{ + + double unit_divisor = (double)1024.0; + + return(calc_service_demand_internal(unit_divisor, + units_sent, + elapsed_time, + cpu_utilization, + num_cpus)); +} + +/* use the value of libfmt to determine the unit_divisor */ +float calc_service_demand_fmt(double units_sent, + float elapsed_time, + float cpu_utilization, + int num_cpus) + +{ + double unit_divisor; + + if ('x' == libfmt) unit_divisor = 1.0; + else unit_divisor = 1024.0; + + return(calc_service_demand_internal(unit_divisor, + units_sent, + elapsed_time, + cpu_utilization, + num_cpus)); +} + + + +float +calibrate_local_cpu(float local_cpu_rate) +{ + + lib_num_loc_cpus = get_num_cpus(); + + lib_use_idle = 0; +#ifdef USE_LOOPER + cpu_util_init(); + lib_use_idle = 1; +#endif /* USE_LOOPER */ + + if (local_cpu_rate > 0) { + /* The user think that he knows what the cpu rate is. We assume */ + /* that all the processors of an MP system are essentially the */ + /* same - for this reason we do not have a per processor maxrate. */ + /* if the machine has processors which are different in */ + /* performance, the CPU utilization will be skewed. raj 4/95 */ + lib_local_maxrate = local_cpu_rate; + } + else { + /* if neither USE_LOOPER nor USE_PSTAT are defined, we return a */ + /* 0.0 to indicate that times or getrusage should be used. raj */ + /* 4/95 */ + lib_local_maxrate = (float)0.0; +#if defined(USE_PROC_STAT) || defined(USE_LOOPER) || defined(USE_PSTAT) || defined(USE_KSTAT) || defined(USE_PERFSTAT) || defined(USE_SYSCTL) + lib_local_maxrate = calibrate_idle_rate(4,10); +#endif + } + return lib_local_maxrate; +} + + +float +calibrate_remote_cpu() +{ + float remrate; + + netperf_request.content.request_type = CPU_CALIBRATE; + send_request(); + /* we know that calibration will last at least 40 seconds, so go to */ + /* sleep for that long so the 60 second select in recv_response will */ + /* not pop. raj 7/95 */ + + /* we know that CPU calibration may last as long as 40 seconds, so + make sure we "select" for at least that long while looking for + the response. raj 2005-05-16 */ + recv_response_timed(40); + + if (netperf_response.content.serv_errno) { + /* initially, silently ignore remote errors and pass */ + /* back a zero to the caller this should allow us to */ + /* mix rev 1.0 and rev 1.1 netperfs... */ + return((float)0.0); + } + else { + /* the rate is the first word of the test_specific data */ + bcopy((char *)netperf_response.content.test_specific_data, + (char *)&remrate, + sizeof(remrate)); + bcopy((char *)netperf_response.content.test_specific_data + sizeof(remrate), + (char *)&lib_num_rem_cpus, + sizeof(lib_num_rem_cpus)); +/* remrate = (float) netperf_response.content.test_specific_data[0]; */ + return(remrate); + } +} + + + +#ifndef WIN32 +/* WIN32 requires that at least one of the file sets to select be non-null. */ +/* Since msec_sleep routine is only called by nettest_dlpi & nettest_unix, */ +/* let's duck this issue. */ + +int +msec_sleep( int msecs ) +{ + int rval ; + + struct timeval timeout; + + timeout.tv_sec = msecs / 1000; + timeout.tv_usec = (msecs - (msecs/1000) *1000) * 1000; + if ((rval = select(0, + 0, + 0, + 0, + &timeout))) { + if ( SOCKET_EINTR(rval) ) { + return(1); + } + perror("msec_sleep: select"); + exit(1); + } + return(0); +} +#endif /* WIN32 */ + +#ifdef WANT_HISTOGRAM +/* hist.c + + Given a time difference in microseconds, increment one of 61 + different buckets: + + 0 - 9 in increments of 1 usec + 0 - 9 in increments of 10 usecs + 0 - 9 in increments of 100 usecs + 1 - 9 in increments of 1 msec + 1 - 9 in increments of 10 msecs + 1 - 9 in increments of 100 msecs + 1 - 9 in increments of 1 sec + 1 - 9 in increments of 10 sec + > 100 secs + + This will allow any time to be recorded to within an accuracy of + 10%, and provides a compact representation for capturing the + distribution of a large number of time differences (e.g. + request-response latencies). + + Colin Low 10/6/93 + Rick Jones 2004-06-15 extend to unit and ten usecs +*/ + +/* #include "sys.h" */ + +/*#define HIST_TEST*/ + +HIST +HIST_new(void){ + HIST h; + if((h = (HIST) malloc(sizeof(struct histogram_struct))) == NULL) { + perror("HIST_new - malloc failed"); + exit(1); + } + HIST_clear(h); + return h; +} + +void +HIST_clear(HIST h){ + int i; + for(i = 0; i < 10; i++){ + h->unit_usec[i] = 0; + h->ten_usec[i] = 0; + h->hundred_usec[i] = 0; + h->unit_msec[i] = 0; + h->ten_msec[i] = 0; + h->hundred_msec[i] = 0; + h->unit_sec[i] = 0; + h->ten_sec[i] = 0; + } + h->ridiculous = 0; + h->total = 0; +} + +void +HIST_add(register HIST h, int time_delta){ + register int val; + h->total++; + val = time_delta; + /* check for < 0 added via VMware ESX patches */ + if (val < 0) { + h->ridiculous++; + } + if(val <= 9) h->unit_usec[val]++; + else { + val = val/10; + if(val <= 9) h->ten_usec[val]++; + else { + val = val/10; + if(val <= 9) h->hundred_usec[val]++; + else { + val = val/10; + if(val <= 9) h->unit_msec[val]++; + else { + val = val/10; + if(val <= 9) h->ten_msec[val]++; + else { + val = val/10; + if(val <= 9) h->hundred_msec[val]++; + else { + val = val/10; + if(val <= 9) h->unit_sec[val]++; + else { + val = val/10; + if(val <= 9) h->ten_sec[val]++; + else h->ridiculous++; + } + } + } + } + } + } + } +} + +#define RB_printf printf + +void +output_row(FILE *fd, char *title, int *row){ + register int i; + RB_printf("%s", title); + for(i = 0; i < 10; i++) RB_printf(": %4d", row[i]); + RB_printf("\n"); +} + +int +sum_row(int *row) { + int sum = 0; + int i; + for (i = 0; i < 10; i++) sum += row[i]; + return(sum); +} + +void +HIST_report(HIST h){ +#ifndef OLD_HISTOGRAM + output_row(stdout, "UNIT_USEC ", h->unit_usec); + output_row(stdout, "TEN_USEC ", h->ten_usec); + output_row(stdout, "HUNDRED_USEC ", h->hundred_usec); +#else + h->hundred_usec[0] += sum_row(h->unit_usec); + h->hundred_usec[0] += sum_row(h->ten_usec); + output_row(stdout, "TENTH_MSEC ", h->hundred_usec); +#endif + output_row(stdout, "UNIT_MSEC ", h->unit_msec); + output_row(stdout, "TEN_MSEC ", h->ten_msec); + output_row(stdout, "HUNDRED_MSEC ", h->hundred_msec); + output_row(stdout, "UNIT_SEC ", h->unit_sec); + output_row(stdout, "TEN_SEC ", h->ten_sec); + RB_printf(">100_SECS: %d\n", h->ridiculous); + RB_printf("HIST_TOTAL: %d\n", h->total); +} + +#endif + +/* with the advent of sit-and-spin intervals support, we might as well + make these things available all the time, not just for demo or + histogram modes. raj 2006-02-06 */ +#ifdef HAVE_GETHRTIME + +void +HIST_timestamp(hrtime_t *timestamp) +{ + *timestamp = gethrtime(); +} + +int +delta_micro(hrtime_t *begin, hrtime_t *end) +{ + long nsecs; + nsecs = (*end) - (*begin); + return(nsecs/1000); +} + +#elif defined(HAVE_GET_HRT) +#include "hrt.h" + +void +HIST_timestamp(hrt_t *timestamp) +{ + *timestamp = get_hrt(); +} + +int +delta_micro(hrt_t *begin, hrt_t *end) +{ + + return((int)get_hrt_delta(*end,*begin)); + +} +#elif defined(WIN32) +void HIST_timestamp(LARGE_INTEGER *timestamp) +{ + QueryPerformanceCounter(timestamp); +} + +int delta_micro(LARGE_INTEGER *begin, LARGE_INTEGER *end) +{ + LARGE_INTEGER DeltaTimestamp; + static LARGE_INTEGER TickHz = {{0,0}}; + + if (TickHz.QuadPart == 0) + { + QueryPerformanceFrequency(&TickHz); + } + + /*+*+ Rick; this will overflow after ~2000 seconds, is that + good enough? Spencer: Yes, that should be more than good + enough for histogram support */ + + DeltaTimestamp.QuadPart = (end->QuadPart - begin->QuadPart) * + 1000000/TickHz.QuadPart; + assert((DeltaTimestamp.HighPart == 0) && + ((int)DeltaTimestamp.LowPart >= 0)); + + return (int)DeltaTimestamp.LowPart; +} + +#else + +void +HIST_timestamp(struct timeval *timestamp) +{ + gettimeofday(timestamp,NULL); +} + + /* return the difference (in micro seconds) between two timeval */ + /* timestamps */ +int +delta_micro(struct timeval *begin,struct timeval *end) + +{ + + int usecs, secs; + + if (end->tv_usec < begin->tv_usec) { + /* borrow a second from the tv_sec */ + end->tv_usec += 1000000; + end->tv_sec--; + } + usecs = end->tv_usec - begin->tv_usec; + secs = end->tv_sec - begin->tv_sec; + + usecs += (secs * 1000000); + + return(usecs); + +} +#endif /* HAVE_GETHRTIME */ + + +#ifdef WANT_DLPI + +int +put_control(fd, len, pri, ack) + int fd, len, pri, ack; +{ + int error; + int flags = 0; + dl_error_ack_t *err_ack = (dl_error_ack_t *)control_data; + + control_message.len = len; + + if ((error = putmsg(fd, &control_message, 0, pri)) < 0 ) { + fprintf(where,"put_control: putmsg error %d\n",error); + fflush(where); + return(-1); + } + if ((error = getmsg(fd, &control_message, 0, &flags)) < 0) { + fprintf(where,"put_control: getsmg error %d\n",error); + fflush(where); + return(-1); + } + if (err_ack->dl_primitive != ack) { + fprintf(where,"put_control: acknowledgement error wanted %u got %u \n", + ack,err_ack->dl_primitive); + if (err_ack->dl_primitive == DL_ERROR_ACK) { + fprintf(where," dl_error_primitive: %u\n", + err_ack->dl_error_primitive); + fprintf(where," dl_errno: %u\n", + err_ack->dl_errno); + fprintf(where," dl_unix_errno %u\n", + err_ack->dl_unix_errno); + } + fflush(where); + return(-1); + } + + return(0); +} + +int +dl_open(char devfile[], int ppa) +{ + int fd; + dl_attach_req_t *attach_req = (dl_attach_req_t *)control_data; + + if ((fd = open(devfile, O_RDWR)) == -1) { + fprintf(where,"netperf: dl_open: open of %s failed, errno = %d\n", + devfile, + errno); + return(-1); + } + + attach_req->dl_primitive = DL_ATTACH_REQ; + attach_req->dl_ppa = ppa; + + if (put_control(fd, sizeof(dl_attach_req_t), 0, DL_OK_ACK) < 0) { + fprintf(where, + "netperf: dl_open: could not send control message, errno = %d\n", + errno); + return(-1); + } + return(fd); +} + +int +dl_bind(int fd, int sap, int mode, char *dlsap_ptr, int *dlsap_len) +{ + dl_bind_req_t *bind_req = (dl_bind_req_t *)control_data; + dl_bind_ack_t *bind_ack = (dl_bind_ack_t *)control_data; + + bind_req->dl_primitive = DL_BIND_REQ; + bind_req->dl_sap = sap; + bind_req->dl_max_conind = 1; + bind_req->dl_service_mode = mode; + bind_req->dl_conn_mgmt = 0; + bind_req->dl_xidtest_flg = 0; + + if (put_control(fd, sizeof(dl_bind_req_t), 0, DL_BIND_ACK) < 0) { + fprintf(where, + "netperf: dl_bind: could not send control message, errno = %d\n", + errno); + return(-1); + } + + /* at this point, the control_data portion of the control message */ + /* structure should contain a DL_BIND_ACK, which will have a full */ + /* DLSAP in it. we want to extract this and pass it up so that */ + /* it can be passed around. */ + if (*dlsap_len >= bind_ack->dl_addr_length) { + bcopy((char *)bind_ack+bind_ack->dl_addr_offset, + dlsap_ptr, + bind_ack->dl_addr_length); + *dlsap_len = bind_ack->dl_addr_length; + return(0); + } + else { + return (-1); + } +} + +int +dl_connect(int fd, unsigned char *remote_addr, int remote_addr_len) +{ + dl_connect_req_t *connection_req = (dl_connect_req_t *)control_data; + dl_connect_con_t *connection_con = (dl_connect_con_t *)control_data; + struct pollfd pinfo; + + int flags = 0; + + /* this is here on the off chance that we really want some data */ + u_long data_area[512]; + struct strbuf data_message; + + int error; + + data_message.maxlen = 2048; + data_message.len = 0; + data_message.buf = (char *)data_area; + + connection_req->dl_primitive = DL_CONNECT_REQ; + connection_req->dl_dest_addr_length = remote_addr_len; + connection_req->dl_dest_addr_offset = sizeof(dl_connect_req_t); + connection_req->dl_qos_length = 0; + connection_req->dl_qos_offset = 0; + bcopy (remote_addr, + (unsigned char *)control_data + sizeof(dl_connect_req_t), + remote_addr_len); + + /* well, I would call the put_control routine here, but the sequence */ + /* of connection stuff with DLPI is a bit screwey with all this */ + /* message passing - Toto, I don't think were in Berkeley anymore. */ + + control_message.len = sizeof(dl_connect_req_t) + remote_addr_len; + if ((error = putmsg(fd,&control_message,0,0)) !=0) { + fprintf(where,"dl_connect: putmsg failure, errno = %d, error 0x%x \n", + errno,error); + fflush(where); + return(-1); + }; + + pinfo.fd = fd; + pinfo.events = POLLIN | POLLPRI; + pinfo.revents = 0; + + if ((error = getmsg(fd,&control_message,&data_message,&flags)) != 0) { + fprintf(where,"dl_connect: getmsg failure, errno = %d, error 0x%x \n", + errno,error); + fflush(where); + return(-1); + } + while (control_data[0] == DL_TEST_CON) { + /* i suppose we spin until we get an error, or a connection */ + /* indication */ + if((error = getmsg(fd,&control_message,&data_message,&flags)) !=0) { + fprintf(where,"dl_connect: getmsg failure, errno = %d, error = 0x%x\n", + errno,error); + fflush(where); + return(-1); + } + } + + /* we are out - it either worked or it didn't - which was it? */ + if (control_data[0] == DL_CONNECT_CON) { + return(0); + } + else { + return(-1); + } +} + +int +dl_accept(fd, remote_addr, remote_addr_len) + int fd; + unsigned char *remote_addr; + int remote_addr_len; +{ + dl_connect_ind_t *connect_ind = (dl_connect_ind_t *)control_data; + dl_connect_res_t *connect_res = (dl_connect_res_t *)control_data; + int tmp_cor; + int flags = 0; + + /* hang around and wait for a connection request */ + getmsg(fd,&control_message,0,&flags); + while (control_data[0] != DL_CONNECT_IND) { + getmsg(fd,&control_message,0,&flags); + } + + /* now respond to the request. at some point, we may want to be sure */ + /* that the connection came from the correct station address, but */ + /* will assume that we do not have to worry about it just now. */ + + tmp_cor = connect_ind->dl_correlation; + + connect_res->dl_primitive = DL_CONNECT_RES; + connect_res->dl_correlation = tmp_cor; + connect_res->dl_resp_token = 0; + connect_res->dl_qos_length = 0; + connect_res->dl_qos_offset = 0; + connect_res->dl_growth = 0; + + return(put_control(fd, sizeof(dl_connect_res_t), 0, DL_OK_ACK)); + +} + +int +dl_set_window(fd, window) + int fd, window; +{ + return(0); +} + +void +dl_stats(fd) + int fd; +{ +} + +int +dl_send_disc(fd) + int fd; +{ +} + +int +dl_recv_disc(fd) + int fd; +{ +} +#endif /* WANT_DLPI*/ + + /* these routines for confidence intervals are courtesy of IBM. They */ + /* have been modified slightly for more general usage beyond TCP/UDP */ + /* tests. raj 11/94 I would suspect that this code carries an IBM */ + /* copyright that is much the same as that for the original HP */ + /* netperf code */ +int confidence_iterations; /* for iterations */ + +double + result_confid=-10.0, + loc_cpu_confid=-10.0, + rem_cpu_confid=-10.0, + + measured_sum_result=0.0, + measured_square_sum_result=0.0, + measured_mean_result=0.0, + measured_var_result=0.0, + + measured_sum_local_cpu=0.0, + measured_square_sum_local_cpu=0.0, + measured_mean_local_cpu=0.0, + measured_var_local_cpu=0.0, + + measured_sum_remote_cpu=0.0, + measured_square_sum_remote_cpu=0.0, + measured_mean_remote_cpu=0.0, + measured_var_remote_cpu=0.0, + + measured_sum_local_service_demand=0.0, + measured_square_sum_local_service_demand=0.0, + measured_mean_local_service_demand=0.0, + measured_var_local_service_demand=0.0, + + measured_sum_remote_service_demand=0.0, + measured_square_sum_remote_service_demand=0.0, + measured_mean_remote_service_demand=0.0, + measured_var_remote_service_demand=0.0, + + measured_sum_local_time=0.0, + measured_square_sum_local_time=0.0, + measured_mean_local_time=0.0, + measured_var_local_time=0.0, + + measured_mean_remote_time=0.0, + + measured_fails, + measured_local_results, + confidence=-10.0; +/* interval=0.1; */ + +/************************************************************************/ +/* */ +/* Constants for Confidence Intervals */ +/* */ +/************************************************************************/ +void +init_stat() +{ + measured_sum_result=0.0; + measured_square_sum_result=0.0; + measured_mean_result=0.0; + measured_var_result=0.0; + + measured_sum_local_cpu=0.0; + measured_square_sum_local_cpu=0.0; + measured_mean_local_cpu=0.0; + measured_var_local_cpu=0.0; + + measured_sum_remote_cpu=0.0; + measured_square_sum_remote_cpu=0.0; + measured_mean_remote_cpu=0.0; + measured_var_remote_cpu=0.0; + + measured_sum_local_service_demand=0.0; + measured_square_sum_local_service_demand=0.0; + measured_mean_local_service_demand=0.0; + measured_var_local_service_demand=0.0; + + measured_sum_remote_service_demand=0.0; + measured_square_sum_remote_service_demand=0.0; + measured_mean_remote_service_demand=0.0; + measured_var_remote_service_demand=0.0; + + measured_sum_local_time=0.0; + measured_square_sum_local_time=0.0; + measured_mean_local_time=0.0; + measured_var_local_time=0.0; + + measured_mean_remote_time=0.0; + + measured_fails = 0.0; + measured_local_results=0.0, + confidence=-10.0; +} + + /* this routine does a simple table lookup for some statistical */ + /* function that I would remember if I stayed awake in my probstats */ + /* class... raj 11/94 */ +double +confid(int level, int freedom) +{ +double t99[35],t95[35]; + + t95[1]=12.706; + t95[2]= 4.303; + t95[3]= 3.182; + t95[4]= 2.776; + t95[5]= 2.571; + t95[6]= 2.447; + t95[7]= 2.365; + t95[8]= 2.306; + t95[9]= 2.262; + t95[10]= 2.228; + t95[11]= 2.201; + t95[12]= 2.179; + t95[13]= 2.160; + t95[14]= 2.145; + t95[15]= 2.131; + t95[16]= 2.120; + t95[17]= 2.110; + t95[18]= 2.101; + t95[19]= 2.093; + t95[20]= 2.086; + t95[21]= 2.080; + t95[22]= 2.074; + t95[23]= 2.069; + t95[24]= 2.064; + t95[25]= 2.060; + t95[26]= 2.056; + t95[27]= 2.052; + t95[28]= 2.048; + t95[29]= 2.045; + t95[30]= 2.042; + + t99[1]=63.657; + t99[2]= 9.925; + t99[3]= 5.841; + t99[4]= 4.604; + t99[5]= 4.032; + t99[6]= 3.707; + t99[7]= 3.499; + t99[8]= 3.355; + t99[9]= 3.250; + t99[10]= 3.169; + t99[11]= 3.106; + t99[12]= 3.055; + t99[13]= 3.012; + t99[14]= 2.977; + t99[15]= 2.947; + t99[16]= 2.921; + t99[17]= 2.898; + t99[18]= 2.878; + t99[19]= 2.861; + t99[20]= 2.845; + t99[21]= 2.831; + t99[22]= 2.819; + t99[23]= 2.807; + t99[24]= 2.797; + t99[25]= 2.787; + t99[26]= 2.779; + t99[27]= 2.771; + t99[28]= 2.763; + t99[29]= 2.756; + t99[30]= 2.750; + + if(level==95){ + return(t95[freedom]); + } else if(level==99){ + return(t99[freedom]); + } else{ + return(0); + } +} + +void +calculate_confidence(int confidence_iterations, + float time, + double result, + float loc_cpu, + float rem_cpu, + float loc_sd, + float rem_sd) +{ + + if (debug) { + fprintf(where, + "calculate_confidence: itr %d; time %f; res %f\n", + confidence_iterations, + time, + result); + fprintf(where, + " lcpu %f; rcpu %f\n", + loc_cpu, + rem_cpu); + fprintf(where, + " lsdm %f; rsdm %f\n", + loc_sd, + rem_sd); + fflush(where); + } + + /* the test time */ + measured_sum_local_time += + (double) time; + measured_square_sum_local_time += + (double) time*time; + measured_mean_local_time = + (double) measured_sum_local_time/confidence_iterations; + measured_var_local_time = + (double) measured_square_sum_local_time/confidence_iterations + -measured_mean_local_time*measured_mean_local_time; + + /* the test result */ + measured_sum_result += + (double) result; + measured_square_sum_result += + (double) result*result; + measured_mean_result = + (double) measured_sum_result/confidence_iterations; + measured_var_result = + (double) measured_square_sum_result/confidence_iterations + -measured_mean_result*measured_mean_result; + + /* local cpu utilization */ + measured_sum_local_cpu += + (double) loc_cpu; + measured_square_sum_local_cpu += + (double) loc_cpu*loc_cpu; + measured_mean_local_cpu = + (double) measured_sum_local_cpu/confidence_iterations; + measured_var_local_cpu = + (double) measured_square_sum_local_cpu/confidence_iterations + -measured_mean_local_cpu*measured_mean_local_cpu; + + /* remote cpu util */ + measured_sum_remote_cpu += + (double) rem_cpu; + measured_square_sum_remote_cpu+= + (double) rem_cpu*rem_cpu; + measured_mean_remote_cpu = + (double) measured_sum_remote_cpu/confidence_iterations; + measured_var_remote_cpu = + (double) measured_square_sum_remote_cpu/confidence_iterations + -measured_mean_remote_cpu*measured_mean_remote_cpu; + + /* local service demand */ + measured_sum_local_service_demand += + (double) loc_sd; + measured_square_sum_local_service_demand+= + (double) loc_sd*loc_sd; + measured_mean_local_service_demand = + (double) measured_sum_local_service_demand/confidence_iterations; + measured_var_local_service_demand = + (double) measured_square_sum_local_service_demand/confidence_iterations + -measured_mean_local_service_demand*measured_mean_local_service_demand; + + /* remote service demand */ + measured_sum_remote_service_demand += + (double) rem_sd; + measured_square_sum_remote_service_demand+= + (double) rem_sd*rem_sd; + measured_mean_remote_service_demand = + (double) measured_sum_remote_service_demand/confidence_iterations; + measured_var_remote_service_demand = + (double) measured_square_sum_remote_service_demand/confidence_iterations + -measured_mean_remote_service_demand*measured_mean_remote_service_demand; + + if(confidence_iterations>1){ + result_confid= (double) interval - + 2.0 * confid(confidence_level,confidence_iterations-1)* + sqrt(measured_var_result/(confidence_iterations-1.0)) / + measured_mean_result; + + loc_cpu_confid= (double) interval - + 2.0 * confid(confidence_level,confidence_iterations-1)* + sqrt(measured_var_local_cpu/(confidence_iterations-1.0)) / + measured_mean_local_cpu; + + rem_cpu_confid= (double) interval - + 2.0 * confid(confidence_level,confidence_iterations-1)* + sqrt(measured_var_remote_cpu/(confidence_iterations-1.0)) / + measured_mean_remote_cpu; + + if(debug){ + printf("Conf_itvl %2d: results:%4.1f%% loc_cpu:%4.1f%% rem_cpu:%4.1f%%\n", + confidence_iterations, + (interval-result_confid)*100.0, + (interval-loc_cpu_confid)*100.0, + (interval-rem_cpu_confid)*100.0); + } + + /* if the user has requested that we only wait for the result to + be confident rather than the result and CPU util(s) then do + so. raj 2007-08-08 */ + if (!result_confidence_only) { + confidence = min(min(result_confid,loc_cpu_confid),rem_cpu_confid); + } + else { + confidence = result_confid; + } + } +} + + /* here ends the IBM code */ + +void +retrieve_confident_values(float *elapsed_time, + double *thruput, + float *local_cpu_utilization, + float *remote_cpu_utilization, + float *local_service_demand, + float *remote_service_demand) + +{ + *elapsed_time = (float)measured_mean_local_time; + *thruput = measured_mean_result; + *local_cpu_utilization = (float)measured_mean_local_cpu; + *remote_cpu_utilization = (float)measured_mean_remote_cpu; + *local_service_demand = (float)measured_mean_local_service_demand; + *remote_service_demand = (float)measured_mean_remote_service_demand; +} + +double +get_result_confid() +{ + return (double) (100.0 * (interval - result_confid)); +} + +double +get_loc_cpu_confid() +{ + return (double) (100.0 * (interval - loc_cpu_confid)); +} + +double +get_rem_cpu_confid() +{ + return (double) (100.0 * (interval - rem_cpu_confid)); +} + + /* display_confidence() is called when we could not achieve the */ + /* desirec confidence in the results. it will print the achieved */ + /* confidence to "where" raj 11/94 */ +void +display_confidence() + +{ + fprintf(where, + "!!! WARNING\n"); + fprintf(where, + "!!! Desired confidence was not achieved within "); + fprintf(where, + "the specified iterations.\n"); + fprintf(where, + "!!! This implies that there was variability in "); + fprintf(where, + "the test environment that\n"); + fprintf(where, + "!!! must be investigated before going further.\n"); + fprintf(where, + "!!! Confidence intervals: Throughput : %4.3f%%\n", + 100.0 * (interval - result_confid)); + fprintf(where, + "!!! Local CPU util : %4.3f%%\n", + 100.0 * (interval - loc_cpu_confid)); + fprintf(where, + "!!! Remote CPU util : %4.3f%%\n\n", + 100.0 * (interval - rem_cpu_confid)); +} + diff --git a/src/netlib.h b/src/netlib.h new file mode 100644 index 0000000..927194a --- /dev/null +++ b/src/netlib.h @@ -0,0 +1,675 @@ +/* + Copyright (C) 1993-2005 Hewlett-Packard Company +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#if defined(HAVE_SYS_SOCKET_H) +# include +#endif +#if defined(HAVE_NETDB_H) +# include +#endif +#if !defined(HAVE_GETADDRINFO) || !defined(HAVE_GETNAMEINFO) +# include "missing/getaddrinfo.h" +#endif + +#define PAD_TIME 4 +/* library routine specifc defines */ +#define MAXSPECDATA 62 /* how many ints worth of data */ + /* can tests send... */ +#define MAXTIMES 4 /* how many times may we loop */ + /* to calibrate */ +#define MAXCPUS 256 /* how many CPU's can we track */ +#define MAXMESSAGESIZE 65536 +#define MAXALIGNMENT 16384 +#define MAXOFFSET 4096 +#define DATABUFFERLEN MAXMESSAGESIZE+MAXALIGNMENT+MAXOFFSET + +#define DEBUG_ON 1 +#define DEBUG_OFF 2 +#define DEBUG_OK 3 +#define NODE_IDENTIFY 4 +#define CPU_CALIBRATE 5 + +#define DO_TCP_STREAM 10 +#define TCP_STREAM_RESPONSE 11 +#define TCP_STREAM_RESULTS 12 + +#define DO_TCP_RR 13 +#define TCP_RR_RESPONSE 14 +#define TCP_RR_RESULTS 15 + +#define DO_UDP_STREAM 16 +#define UDP_STREAM_RESPONSE 17 +#define UDP_STREAM_RESULTS 18 + +#define DO_UDP_RR 19 +#define UDP_RR_RESPONSE 20 +#define UDP_RR_RESULTS 21 + +#define DO_DLPI_CO_STREAM 22 +#define DLPI_CO_STREAM_RESPONSE 23 +#define DLPI_CO_STREAM_RESULTS 24 + +#define DO_DLPI_CO_RR 25 +#define DLPI_CO_RR_RESPONSE 26 +#define DLPI_CO_RR_RESULTS 27 + +#define DO_DLPI_CL_STREAM 28 +#define DLPI_CL_STREAM_RESPONSE 29 +#define DLPI_CL_STREAM_RESULTS 30 + +#define DO_DLPI_CL_RR 31 +#define DLPI_CL_RR_RESPONSE 32 +#define DLPI_CL_RR_RESULTS 33 + +#define DO_TCP_CRR 34 +#define TCP_CRR_RESPONSE 35 +#define TCP_CRR_RESULTS 36 + +#define DO_STREAM_STREAM 37 +#define STREAM_STREAM_RESPONSE 38 +#define STREAM_STREAM_RESULTS 39 + +#define DO_STREAM_RR 40 +#define STREAM_RR_RESPONSE 41 +#define STREAM_RR_RESULTS 42 + +#define DO_DG_STREAM 43 +#define DG_STREAM_RESPONSE 44 +#define DG_STREAM_RESULTS 45 + +#define DO_DG_RR 46 +#define DG_RR_RESPONSE 47 +#define DG_RR_RESULTS 48 + +#define DO_FORE_STREAM 49 +#define FORE_STREAM_RESPONSE 50 +#define FORE_STREAM_RESULTS 51 + +#define DO_FORE_RR 52 +#define FORE_RR_RESPONSE 53 +#define FORE_RR_RESULTS 54 + +#define DO_HIPPI_STREAM 55 +#define HIPPI_STREAM_RESPONSE 56 +#define HIPPI_STREAM_RESULTS 57 + +#define DO_HIPPI_RR 52 +#define HIPPI_RR_RESPONSE 53 +#define HIPPI_RR_RESULTS 54 + +#define DO_XTI_TCP_STREAM 55 +#define XTI_TCP_STREAM_RESPONSE 56 +#define XTI_TCP_STREAM_RESULTS 57 + +#define DO_XTI_TCP_RR 58 +#define XTI_TCP_RR_RESPONSE 59 +#define XTI_TCP_RR_RESULTS 60 + +#define DO_XTI_UDP_STREAM 61 +#define XTI_UDP_STREAM_RESPONSE 62 +#define XTI_UDP_STREAM_RESULTS 63 + +#define DO_XTI_UDP_RR 64 +#define XTI_UDP_RR_RESPONSE 65 +#define XTI_UDP_RR_RESULTS 66 + +#define DO_XTI_TCP_CRR 67 +#define XTI_TCP_CRR_RESPONSE 68 +#define XTI_TCP_CRR_RESULTS 69 + +#define DO_TCP_TRR 70 +#define TCP_TRR_RESPONSE 71 +#define TCP_TRR_RESULTS 72 + +#define DO_TCP_NBRR 73 +#define TCP_NBRR_RESPONSE 74 +#define TCP_NBRR_RESULTS 75 + +#define DO_TCPIPV6_STREAM 76 +#define TCPIPV6_STREAM_RESPONSE 77 +#define TCPIPV6_STREAM_RESULTS 78 + +#define DO_TCPIPV6_RR 79 +#define TCPIPV6_RR_RESPONSE 80 +#define TCPIPV6_RR_RESULTS 81 + +#define DO_UDPIPV6_STREAM 82 +#define UDPIPV6_STREAM_RESPONSE 83 +#define UDPIPV6_STREAM_RESULTS 84 + +#define DO_UDPIPV6_RR 85 +#define UDPIPV6_RR_RESPONSE 86 +#define UDPIPV6_RR_RESULTS 87 + +#define DO_TCPIPV6_CRR 88 +#define TCPIPV6_CRR_RESPONSE 89 +#define TCPIPV6_CRR_RESULTS 90 + +#define DO_TCPIPV6_TRR 91 +#define TCPIPV6_TRR_RESPONSE 92 +#define TCPIPV6_TRR_RESULTS 93 + +#define DO_TCP_MAERTS 94 +#define TCP_MAERTS_RESPONSE 95 +#define TCP_MAERTS_RESULTS 96 + +#define DO_OMNI 97 +#define OMNI_RESPONSE 98 +#define OMNI_RESULTS 99 + +#define DO_LWPSTR_STREAM 100 +#define LWPSTR_STREAM_RESPONSE 110 +#define LWPSTR_STREAM_RESULTS 120 + +#define DO_LWPSTR_RR 130 +#define LWPSTR_RR_RESPONSE 140 +#define LWPSTR_RR_RESULTS 150 + +#define DO_LWPDG_STREAM 160 +#define LWPDG_STREAM_RESPONSE 170 +#define LWPDG_STREAM_RESULTS 180 + +#define DO_LWPDG_RR 190 +#define LWPDG_RR_RESPONSE 200 +#define LWPDG_RR_RESULTS 210 + +#define DO_TCP_CC 300 +#define TCP_CC_RESPONSE 301 +#define TCP_CC_RESULTS 302 + +/* The DNS_RR test has been removed from netperf but we leave these + here for historical purposes. Those wanting to do DNS_RR tests + should use netperf4 instead. */ +#define DO_DNS_RR 400 +#define DNS_RR_RESPONSE 401 +#define DNS_RR_RESULTS 402 + +#define DO_SCTP_STREAM 500 +#define SCTP_STREAM_RESPONSE 501 +#define SCTP_STREAM_RESULT 502 + +#define DO_SCTP_STREAM_MANY 510 +#define SCTP_STREAM_MANY_RESPONSE 511 +#define SCTP_STREAM_MANY_RESULT 512 + +#define DO_SCTP_RR 520 +#define SCTP_RR_RESPONSE 521 +#define SCTP_RR_RESULT 502 + +#define DO_SCTP_RR_MANY 530 +#define SCTP_RR_MANY_RESPONSE 531 +#define SCTP_RR_MANY_RESULT 532 + +#define DO_SDP_STREAM 540 +#define SDP_STREAM_RESPONSE 541 +#define SDP_STREAM_RESULTS 542 + +#define DO_SDP_RR 543 +#define SDP_RR_RESPONSE 544 +#define SDP_RR_RESULTS 545 + +#define DO_SDP_MAERTS 546 +#define SDP_MAERTS_RESPONSE 547 +#define SDP_MAERTS_RESULTS 548 + +#define DO_SDP_CRR 549 +#define SDP_CRR_RESPONSE 550 +#define SDP_CRR_RESULTS 551 + +#define DO_SDP_CC 552 +#define SDP_CC_RESPONSE 553 +#define SDP_CC_RESULTS 554 + +#define DO_SYSINFO 600 +#define SYSINFO_RESPONSE 601 + +#if HAVE_INTTYPES_H +# include +#else +# if HAVE_STDINT_H +# include +# endif +#endif + +enum sock_buffer{ + SEND_BUFFER, + RECV_BUFFER +}; + +/* some defines for security types, perhaps these would be better + elsewhere but for now here they are */ + +#define NSEC_UNKNOWN -1 +#define NSEC_DISABLED 0 +#define NSEC_PERMISSIVE 1 +#define NSEC_ENFORCING 2 + +#define NSEC_TYPE_UNKNOWN -1 +#define NSEC_TYPE_SELINUX 1 + +#define NETFW_UNKNOWN -1 +#define NETFW_IPTABLES 1 + + /* some of the fields in these structures are going to be doubles and */ + /* such. so, we probably want to ensure that they will start on */ + /* "double" boundaries. this will break compatability to pre-2.1 */ + /* releases, but then, backwards compatability has never been a */ + /* stated goal of netperf. raj 11/95 */ + +union netperf_request_struct { + struct { + int request_type; + int dummy; + int test_specific_data[MAXSPECDATA]; + } content; + double dummy; +}; + +union netperf_response_struct { + struct { + int response_type; + int serv_errno; + int test_specific_data[MAXSPECDATA]; + } content; + double dummy; +}; + +struct ring_elt { + struct ring_elt *next; /* next element in the ring */ + char *buffer_base; /* in case we have to free it at somepoint */ + char *buffer_ptr; /* the aligned and offset pointer */ +}; + +/* +*+ SAF Sorry about the hacks with errno; NT made me do it :( + + WinNT does define an errno. + It is mostly a legacy from the XENIX days. + + Depending upon the version of the C run time that is linked in, it is + either a simple variable (like UNIX code expects), but more likely it + is the address of a procedure to return the error number. So any + code that sets errno is likely to be overwriting the address of this + procedure. Worse, only a tiny fraction of NT's errors get set + through errno. + + So I have changed the netperf code to use a define Set_errno when + that is it's intent. On non-windows platforms this is just an + assignment to errno. But on NT this calls SetLastError. + + I also define errno (now only used on right side of assignments) + on NT to be GetLastError. + + Similarly, perror is defined on NT, but it only accesses the same + XENIX errors that errno covers. So on NT this is redefined to be + Perror and it expands all GetLastError texts. */ + + +#ifdef WIN32 +/* INVALID_SOCKET == INVALID_HANDLE_VALUE == (unsigned int)(~0) */ +/* SOCKET_ERROR == -1 */ +#define ENOTSOCK WSAENOTSOCK +#define EINTR WSAEINTR +#define ENOBUFS WSAENOBUFS +#define EWOULDBLOCK WSAEWOULDBLOCK +#define EAFNOSUPPORT WSAEAFNOSUPPORT +/* I don't use a C++ style of comment because it upsets some C + compilers, possibly even when it is inside an ifdef WIN32... */ +/* from public\sdk\inc\crt\errno.h */ +#define ENOSPC 28 + +#ifdef errno +/* delete the one from stdlib.h */ +/*#define errno (*_errno()) */ +#undef errno +#endif +#define errno GetLastError() +#define Set_errno(num) SetLastError((num)) + +#define perror(text) PrintWin32Error(stderr, (text)) +#define Print_errno(stream, text) PrintWin32Error((stream), (text)) + +extern void PrintWin32Error(FILE *stream, LPSTR text); + +#if !defined(NT_PERF) && !defined(USE_LOOPER) +#define NT_PERF +#endif +#else +/* Really shouldn't use manifest constants! */ +/*+*+SAF There are other examples of "== -1" and "<0" that probably */ +/*+*+SAF should be cleaned up as well. */ +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 + +#define SOCKET int +#define Set_errno(num) errno = (num) + +#define Print_errno(stream, text) fprintf((stream), "%s errno %d\n", (text), errno) +#endif + +/* Robin & Rick's kludge to try to have a timer signal EINTR by closing */ +/* the socket from another thread can also return several other errors. */ +/* Let's define a macro to hide all of this. */ + +#ifndef WIN32 +#define SOCKET_EINTR(return_value) (errno == EINTR) +#define SOCKET_EADDRINUSE(return_value) (errno == EADDRINUSE) +#define SOCKET_EADDRNOTAVAIL(return_value) (errno == EADDRNOTAVAIL) + +#else + +/* not quite sure I like the extra cases for WIN32 but that is what my + WIN32 expert sugested. I'm not sure what WSA's to put for + EADDRINUSE */ + +#define SOCKET_EINTR(return_value) \ + (((return_value) == SOCKET_ERROR) && \ + ((errno == EINTR) || \ + (errno == WSAECONNABORTED) || \ + (errno == WSAECONNRESET) || \ + (errno == ENOTSOCK) )) +#define SOCKET_EADDRINUSE(return_value) \ + (((return_value) == SOCKET_ERROR) && \ + ((errno == WSAEADDRINUSE) )) +#define SOCKET_EADDRNOTAVAIL(return_value) \ + (((return_value) == SOCKET_ERROR) && \ + ((errno == WSAEADDRNOTAVAIL) )) +#endif + +#ifdef HAVE_SENDFILE + +struct sendfile_ring_elt { + struct sendfile_ring_elt *next; /* next element in the ring */ + int fildes; /* the file descriptor of the source + file */ + off_t offset; /* the offset from the beginning of + the file for this send */ + size_t length; /* the number of bytes to send - + this is redundant with the + send_size variable but I decided + to include it anyway */ + struct iovec *hdtrl; /* a pointer to a header/trailer + that we do not initially use and + so should be set to NULL when the + ring is setup. */ + int flags; /* the flags to pass to sendfile() - + presently unused and should be + set to zero when the ring is + setup. */ +}; + +#endif /* HAVE_SENDFILE */ + + /* the diferent codes to denote the type of CPU utilization */ + /* methods used */ +#define CPU_UNKNOWN 0 +#define HP_IDLE_COUNTER 1 +#define PSTAT 2 +#define TIMES 3 +#define LOOPER 4 +#define GETRUSAGE 5 +#define NT_METHOD 6 +#define KSTAT 7 +#define PROC_STAT 8 +#define SYSCTL 9 +#define PERFSTAT 10 +#define KSTAT_10 11 +#define OSX 12 + +#define BADCH ('?') + +#ifndef NETLIB +#ifdef WIN32 +#ifndef _GETOPT_ +#define _GETOPT_ + +int getopt(int argc, char **argv, char *optstring); + +extern char *optarg; /* returned arg to go with this option */ +extern int optind; /* index to next argv element to process */ +extern int opterr; /* should error messages be printed? */ +extern int optopt; /* */ + +#endif /* _GETOPT_ */ + +extern SOCKET win_kludge_socket, win_kludge_socket2; +#endif /* WIN32 */ + +extern int local_proc_affinity, remote_proc_affinity; + +/* these are to allow netperf to be run easily through those evil, + end-to-end breaking things known as firewalls */ +extern char local_data_port[10]; +extern char remote_data_port[10]; + +extern char *local_data_address; +extern char *remote_data_address; + +extern char *local_sysname, *remote_sysname; +extern char *local_release, *remote_release; +extern char *local_version, *remote_version; +extern char *local_machine, *remote_machine; + +extern int local_data_family; +extern int remote_data_family; + +extern union netperf_request_struct netperf_request; +extern union netperf_response_struct netperf_response; + +extern float lib_local_cpu_util; +extern float lib_elapsed; +extern float lib_local_maxrate; +extern double lib_local_peak_cpu_util; +extern int lib_local_peak_cpu_id; +extern double lib_remote_peak_cpu_util; +extern int lib_remote_peak_cpu_id; + +extern char libfmt; + +extern int cpu_method; +extern int lib_num_loc_cpus; +extern int lib_num_rem_cpus; +extern SOCKET server_sock; +extern int times_up; +extern FILE *where; +extern int loops_per_msec; +extern float lib_local_per_cpu_util[]; + +extern void netlib_init(); +extern int netlib_get_page_size(); +extern void install_signal_catchers(); +extern void establish_control(char hostname[], + char port[], + int af, + char local_hostname[], + char local_port[], + int local_af); +extern void shutdown_control(); +extern void init_stat(); +extern void send_request(); +extern void recv_response(); +extern void send_response(); +extern void recv_request(); +extern void send_request_n(int n); /* convert only the first N ints */ +extern void recv_response_n(int n); /* of the test-specific data via */ +extern void send_response_n(int n); /* htonl/ntonl as required */ +extern void recv_request_n(int n); +extern void dump_request(); +extern void dump_addrinfo(FILE *dumploc, struct addrinfo *info, + char *host, char *port, int family); +extern void start_timer(int time); +extern void stop_timer(); +extern void cpu_start(int measure_cpu); +extern void cpu_stop(int measure_cpu, float *elapsed); +extern void calculate_confidence(int confidence_iterations, + float time, + double result, + float loc_cpu, + float rem_cpu, + float loc_sd, + float rem_sd); +extern void retrieve_confident_values(float *elapsed_time, + double *thruput, + float *local_cpu_utilization, + float *remote_cpu_utilization, + float *local_service_demand, + float *remote_service_demand); +extern double get_result_confid(); +extern double get_loc_cpu_confid(); +extern double get_rem_cpu_confid(); +extern void display_confidence(); +extern void get_sock_buffer(SOCKET sd, + enum sock_buffer which, + int *effective_sizep); +extern void set_sock_buffer(SOCKET sd, + enum sock_buffer which, + int requested_size, + int *effective_sizep); +extern char *format_units(); + +extern void get_remote_system_info(); + +extern char *inet_ftos(int family); +extern char *inet_ttos(int type); +extern char *inet_ptos(int protocol); +extern char *nsec_enabled_to_str(int enabled); +extern char *nsec_type_to_str(int type); +extern double ntohd(double net_double); +extern double htond(double host_double); +extern int inet_nton(int af, const void *src, char *dst, int cnt); +extern void libmain(); +extern double calc_thruput(double units_received); +extern double calc_thruput_interval(double units_received,double elapsed); +extern double calc_thruput_omni(double units_received); +extern double calc_thruput_interval_omni(double units_received,double elapsed); +extern float calibrate_local_cpu(float local_cpu_rate); +extern float calibrate_remote_cpu(); +extern void bind_to_specific_processor(int processor_affinity,int use_cpu_map); +extern int set_nonblock (SOCKET sock); +extern char *find_egress_interface(struct sockaddr *source, struct sockaddr *dest); +extern char *find_interface_slot(char *interface_name); +extern void find_interface_ids(char *interface_name, int *vendor, int *device, int *sub_vend, int *sub_dev); +extern void find_driver_info(char *ifname, char *driver, char *version, char *firmware, char *bus, int len); +extern void find_system_info(char **system_model, char **cpu_model, int *cpu_frequency); + +#ifndef WIN32 + +/* WIN32 requires that at least one of the file sets to select be + non-null. Since msec_sleep routine is only called by nettest_dlpi & + nettest_unix, let's duck this issue. */ + +extern int msec_sleep( int msecs ); +#endif /* WIN32 */ +extern float calc_cpu_util(float elapsed_time); +extern float calc_service_demand(double units_sent, + float elapsed_time, + float cpu_utilization, + int num_cpus); +/* this one determines the unit divisor based on libfmt */ +extern float calc_service_demand_fmt(double units_sent, + float elapsed_time, + float cpu_utilization, + int num_cpus); +#if defined(__hpux) +extern void catcher(int, siginfo_t *,void *); +#else +extern void catcher(int); +#endif /* __hpux */ +extern struct ring_elt *allocate_buffer_ring(); +extern void access_buffer(char *buffer_ptr, + int length, + int dirty_count, + int clean_count); + +#ifdef HAVE_ICSC_EXS +extern struct ring_elt *allocate_exs_buffer_ring(); +#endif /* HAVE_ICSC_EXS */ +#ifdef HAVE_SENDFILE +extern struct sendfile_ring_elt *alloc_sendfile_buf_ring(); +#endif /* HAVE_SENDFILE */ +#ifdef WANT_DLPI +/* it seems that AIX in its finite wisdom has some bogus define in an + include file which defines "rem_addr" which then screws-up this extern + unless we change the names to protect the guilty. reported by Eric + Jones */ +extern int dl_connect(int fd, unsigned char *remote_addr, int remote_addr_len); +extern int dl_bind(int fd, int sap, int mode, char *dlsap_ptr, int *dlsap_len); +extern int dl_open(char devfile[], int ppa); +#endif /* WANT_DLPI */ +extern char format_cpu_method(int method); +extern unsigned int convert(char *string); +extern unsigned int convert_timespec(char *string); + +#ifdef WANT_INTERVALS +extern void start_itimer(unsigned int interval_len_msec); +#endif + /* these are all for the confidence interval stuff */ +extern double confidence; +extern double result_confid; +extern double loc_cpu_confid; +extern double rem_cpu_confid; +extern int lib_cpu_map[]; +#endif + +#ifdef WIN32 +#define close(x) closesocket(x) +#define strcasecmp(a,b) _stricmp(a,b) +#define getpid() ((int)GetCurrentProcessId()) +#endif + +#ifdef WIN32 +#if 0 +/* Should really use safe string functions; but not for now... */ +#include +/* Microsoft has deprecated _snprintf; it isn't guarenteed to null terminate the result buffer. */ +/* They want us to call StringCbPrintf instead; it always null terminates the string. */ +#endif + +#define snprintf _snprintf +#endif + +/* Define a macro to align a buffer with an offset from a power of 2 + boundary. */ + +#ifndef WIN32 +#define ULONG_PTR unsigned long +#endif + +#define ALIGN_BUFFER(BufPtr, Align, Offset) \ + (char *)(( (ULONG_PTR)(BufPtr) + \ + (ULONG_PTR) (Align) -1) & \ + ~((ULONG_PTR) (Align) - 1)) + (ULONG_PTR)(Offset) + + /* if your system has bcopy and bzero, include it here, otherwise, we */ + /* will try to use memcpy aand memset. fix from Bruce Barnett @ GE. */ +#if defined(hpux) || defined (__VMS) +#define HAVE_BCOPY +#define HAVE_BZERO +#endif + +#ifdef WIN32 +#define HAVE_MIN +#else +#define _stdcall +#define _cdecl +#endif + +#ifndef HAVE_BCOPY +#define bcopy(s,d,h) memcpy((d),(s),(h)) +#endif /* HAVE_BCOPY */ + +#ifndef HAVE_BZERO +#define bzero(p,h) memset((p),0,(h)) +#endif /* HAVE_BZERO */ + +#ifndef HAVE_MIN +#define min(a,b) ((a < b) ? a : b) +#endif /* HAVE_MIN */ + +#ifdef USE_PERFSTAT +# include +#endif diff --git a/src/netperf.c b/src/netperf.c new file mode 100644 index 0000000..7848efd --- /dev/null +++ b/src/netperf.c @@ -0,0 +1,295 @@ +/* + + Copyright (C) 1993-2007 Hewlett-Packard Company + ALL RIGHTS RESERVED. + + The enclosed software and documentation includes copyrighted works + of Hewlett-Packard Co. For as long as you comply with the following + limitations, you are hereby authorized to (i) use, reproduce, and + modify the software and documentation, and to (ii) distribute the + software and documentation, including modifications, for + non-commercial purposes only. + + 1. The enclosed software and documentation is made available at no + charge in order to advance the general development of + high-performance networking products. + + 2. You may not delete any copyright notices contained in the + software or documentation. All hard copies, and copies in + source code or object code form, of the software or + documentation (including modifications) must contain at least + one of the copyright notices. + + 3. The enclosed software and documentation has not been subjected + to testing and quality control and is not a Hewlett-Packard Co. + product. At a future time, Hewlett-Packard Co. may or may not + offer a version of the software and documentation as a product. + + 4. THE SOFTWARE AND DOCUMENTATION IS PROVIDED "AS IS". + HEWLETT-PACKARD COMPANY DOES NOT WARRANT THAT THE USE, + REPRODUCTION, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR + DOCUMENTATION WILL NOT INFRINGE A THIRD PARTY'S INTELLECTUAL + PROPERTY RIGHTS. HP DOES NOT WARRANT THAT THE SOFTWARE OR + DOCUMENTATION IS ERROR FREE. HP DISCLAIMS ALL WARRANTIES, + EXPRESS AND IMPLIED, WITH REGARD TO THE SOFTWARE AND THE + DOCUMENTATION. HP SPECIFICALLY DISCLAIMS ALL WARRANTIES OF + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + + 5. HEWLETT-PACKARD COMPANY WILL NOT IN ANY EVENT BE LIABLE FOR ANY + DIRECT, INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES + (INCLUDING LOST PROFITS) RELATED TO ANY USE, REPRODUCTION, + MODIFICATION, OR DISTRIBUTION OF THE SOFTWARE OR DOCUMENTATION. + +*/ +char netperf_id[]="\ +@(#)netperf.c (c) Copyright 1993-2007 Hewlett-Packard Company. Version 2.4.3"; + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#ifdef HAVE_STRINGS_H +#include +#endif + +/* FreeBSD doesn't like socket.h before types are set. */ +#if __FreeBSD__ +# include +#endif + +#ifndef WIN32 +/* this should only be temporary */ +#include +#endif + +#ifdef WIN32 +#include +#include +#endif /* WIN32 */ + +#include "netsh.h" +#include "netlib.h" +#include "nettest_bsd.h" + +#ifdef WANT_UNIX +#include "nettest_unix.h" +#endif /* WANT_UNIX */ + +#ifdef WANT_XTI +#include "nettest_xti.h" +#endif /* WANT_XTI */ + +#ifdef WANT_DLPI +#include "nettest_dlpi.h" +#endif /* WANT_DLPI */ + +#ifdef WANT_SDP +#include "nettest_sdp.h" +#endif + +/* The DNS tests have been removed from netperf2. Those wanting to do + DNS_RR tests should use netperf4 instead. */ + +#ifdef DO_DNS +#error DNS tests have been removed from netperf. Use netperf4 instead +#endif /* DO_DNS */ + +#ifdef WANT_SCTP +#include "nettest_sctp.h" +#endif + + /* this file contains the main for the netperf program. all the other */ + /* routines can be found in the file netsh.c */ + + +int _cdecl +main(int argc, char *argv[]) +{ + +#ifdef WIN32 + WSADATA wsa_data ; + + /* Initialize the winsock lib ( version 2.2 ) */ + if ( WSAStartup(MAKEWORD(2,2), &wsa_data) == SOCKET_ERROR ){ + printf("WSAStartup() failed : %lu\n", GetLastError()) ; + return 1 ; + } +#endif /* WIN32 */ + + netlib_init(); + set_defaults(); + scan_cmd_line(argc,argv); + + if (debug) { + dump_globals(); + install_signal_catchers(); + } + + if (debug) { + printf("remotehost is %s and port %s\n",host_name,test_port); + fflush(stdout); + } + + + if (!no_control) { + establish_control(host_name,test_port,address_family, + local_host_name,local_test_port,local_address_family); + } + + if (strcasecmp(test_name,"TCP_STREAM") == 0) { + send_tcp_stream(host_name); + } + else if (strcasecmp(test_name,"TCP_MAERTS") == 0) { + send_tcp_maerts(host_name); + } + else if (strcasecmp(test_name,"TCP_MSS") == 0) { + send_tcp_mss(host_name); + } +#ifdef HAVE_ICSC_EXS + else if (strcasecmp(test_name,"EXS_TCP_STREAM") == 0) { + send_exs_tcp_stream(host_name); + } +#endif /* HAVE_ICSC_EXS */ +#ifdef HAVE_SENDFILE + else if (strcasecmp(test_name,"TCP_SENDFILE") == 0) { + sendfile_tcp_stream(host_name); + } +#endif /* HAVE_SENDFILE */ + else if (strcasecmp(test_name,"TCP_RR") == 0) { + send_tcp_rr(host_name); + } + else if (strcasecmp(test_name,"TCP_CRR") == 0) { + send_tcp_conn_rr(host_name); + } + else if (strcasecmp(test_name,"TCP_CC") == 0) { + send_tcp_cc(host_name); + } +#ifdef DO_1644 + else if (strcasecmp(test_name,"TCP_TRR") == 0) { + send_tcp_tran_rr(host_name); + } +#endif /* DO_1644 */ +#ifdef DO_NBRR + else if (strcasecmp(test_name,"TCP_NBRR") == 0) { + send_tcp_nbrr(host_name); + } +#endif /* DO_NBRR */ + else if (strcasecmp(test_name,"UDP_STREAM") == 0) { + send_udp_stream(host_name); + } + else if (strcasecmp(test_name,"UDP_RR") == 0) { + send_udp_rr(host_name); + } + else if (strcasecmp(test_name,"LOC_CPU") == 0) { + loc_cpu_rate(); + } + else if (strcasecmp(test_name,"REM_CPU") == 0) { + rem_cpu_rate(); + } +#ifdef WANT_DLPI + else if (strcasecmp(test_name,"DLCO_RR") == 0) { + send_dlpi_co_rr(host_name); + } + else if (strcasecmp(test_name,"DLCL_RR") == 0) { + send_dlpi_cl_rr(host_name); + } + else if (strcasecmp(test_name,"DLCO_STREAM") == 0) { + send_dlpi_co_stream(host_name); + } + else if (strcasecmp(test_name,"DLCL_STREAM") == 0) { + send_dlpi_cl_stream(host_name); + } +#endif /* WANT_DLPI */ +#ifdef WANT_UNIX + else if (strcasecmp(test_name,"STREAM_RR") == 0) { + send_stream_rr(host_name); + } + else if (strcasecmp(test_name,"DG_RR") == 0) { + send_dg_rr(host_name); + } + else if (strcasecmp(test_name,"STREAM_STREAM") == 0) { + send_stream_stream(host_name); + } + else if (strcasecmp(test_name,"DG_STREAM") == 0) { + send_dg_stream(host_name); + } +#endif /* WANT_UNIX */ +#ifdef WANT_XTI + else if (strcasecmp(test_name,"XTI_TCP_STREAM") == 0) { + send_xti_tcp_stream(host_name); + } + else if (strcasecmp(test_name,"XTI_TCP_RR") == 0) { + send_xti_tcp_rr(host_name); + } + else if (strcasecmp(test_name,"XTI_UDP_STREAM") == 0) { + send_xti_udp_stream(host_name); + } + else if (strcasecmp(test_name,"XTI_UDP_RR") == 0) { + send_xti_udp_rr(host_name); + } +#endif /* WANT_XTI */ + +#ifdef WANT_SCTP + else if (strcasecmp(test_name, "SCTP_STREAM") == 0) { + send_sctp_stream(host_name); + } + else if (strcasecmp(test_name, "SCTP_RR") == 0) { + send_sctp_rr(host_name); + } + else if (strcasecmp(test_name, "SCTP_STREAM_MANY") == 0) { + send_sctp_stream_1toMany(host_name); + } + else if (strcasecmp(test_name, "SCTP_RR_MANY") == 0) { + send_sctp_stream_1toMany(host_name); + } +#endif + +#ifdef DO_DNS + else if (strcasecmp(test_name,"DNS_RR") == 0) { + fprintf(stderr, + "DNS tests can now be found in netperf4.\n"); + fflush(stderr); + exit(-1); + } +#endif /* DO_DNS */ +#ifdef WANT_SDP + else if (strcasecmp(test_name,"SDP_STREAM") == 0) { + send_sdp_stream(host_name); + } + else if (strcasecmp(test_name,"SDP_MAERTS") == 0) { + send_sdp_maerts(host_name); + } + else if (strcasecmp(test_name,"SDP_RR") == 0) { + send_sdp_rr(host_name); + } +#endif /* WANT_SDP */ +#ifdef WANT_OMNI + else if (strcasecmp(test_name,"OMNI") == 0) { + send_omni(host_name); + } + else if (strcasecmp(test_name,"UUID") == 0) { + print_uuid(host_name); + } +#endif + else { + printf("The test you requested is unknown to this netperf.\n"); + printf("Please verify that you have the correct test name, \n"); + printf("and that test family has been compiled into this netperf.\n"); + exit(1); + } + + if (!no_control) { + shutdown_control(); + } + +#ifdef WIN32 + /* Cleanup the winsock lib */ + WSACleanup(); +#endif + + return(0); +} + + diff --git a/src/netperf_version.h b/src/netperf_version.h new file mode 100644 index 0000000..2f810c0 --- /dev/null +++ b/src/netperf_version.h @@ -0,0 +1 @@ +#define NETPERF_VERSION "2.4.5" diff --git a/src/netperf_version.h.in b/src/netperf_version.h.in new file mode 100644 index 0000000..8ebd452 --- /dev/null +++ b/src/netperf_version.h.in @@ -0,0 +1 @@ +#define NETPERF_VERSION "@VERSION@" diff --git a/src/netrt_none.c b/src/netrt_none.c new file mode 100644 index 0000000..b44f073 --- /dev/null +++ b/src/netrt_none.c @@ -0,0 +1,17 @@ +#ifdef HAVE_CONFIG_H +#include +#endif + +#ifdef HAVE_SYS_SOCKET_H +#include +#endif + +#ifdef HAVE_STRING_H +#include +#endif + +char * +find_egress_interface(struct sockaddr *source, struct sockaddr *dest) { + return strdup("InterfaceUnavailable"); + +} diff --git a/src/netrt_rtmget.c b/src/netrt_rtmget.c new file mode 100644 index 0000000..c866c1c --- /dev/null +++ b/src/netrt_rtmget.c @@ -0,0 +1,419 @@ +#if defined(HAVE_CONFIG_H) +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(HAVE_SYS_SOCKIO_H) +#include +#endif + +char * +find_egress_interface_by_addr(struct sockaddr *addr, int local_ip_check) { + +#ifdef HAVE_GETIFADDRS +#include + + struct ifaddrs *ifap; + struct ifaddrs *temp; + struct sockaddr_in *sin,*tsin; +#ifdef AF_INET6 + struct sockaddr_in6 *sin6,*tsin6; +#endif + void *addr1,*addr2; + int ret,cmplen; + char temp_name[IFNAMSIZ]; + + sin = (struct sockaddr_in *)addr; + sin6 = (struct sockaddr_in6 *)sin; + + ret = getifaddrs(&ifap); + + if (ret < 0) { + if (local_ip_check) + return NULL; + else + return("ifgetaddrs"); + } + + temp = ifap; + while (temp) { + if ((temp->ifa_flags & IFF_UP) && + (temp->ifa_addr->sa_family == sin->sin_family)) { + sin = (struct sockaddr_in *)temp->ifa_addr; + switch (temp->ifa_addr->sa_family) { +#ifdef AF_INET6 + case AF_INET6: + addr1 = &(sin6->sin6_addr); + tsin6 = (struct sockaddr_in6 *)(temp->ifa_addr); + addr2 = &(tsin6->sin6_addr); + cmplen = sizeof(tsin6->sin6_addr); + break; +#endif + case AF_INET: + addr1 = &(sin->sin_addr.s_addr); + tsin = (struct sockaddr_in *)(temp->ifa_addr); + addr2 = &(tsin->sin_addr.s_addr); + cmplen = sizeof(struct in_addr); + break; + default: + freeifaddrs(ifap); + if (local_ip_check) + return NULL; + else + return strdup("BadAF"); + } + if (memcmp(addr1,addr2,cmplen) == 0) { + strcpy(temp_name,temp->ifa_name); + freeifaddrs(ifap); + return strdup(temp_name); + } + } + temp = temp->ifa_next; + } + freeifaddrs(ifap); + if (local_ip_check) + return NULL; + else + return strdup("NotFound"); + +#else + char *buf,*ptr; + int lastlen,len,cmplen; + int sockfd; + struct ifconf ifc; + struct ifreq *ifr; + struct sockaddr_in *sin,*tsin; +#ifdef AF_INET6 + struct sockaddr_in6 *sin6,*tsin6; +#endif + void *addr1,*addr2; + + sin = (struct sockaddr_in *)addr; +#ifdef AF_INET6 + sin6 = (struct sockaddr_in6 *)sin; +#endif + +#if defined(NETPERF_STANDALONE_DEBUG) + printf("Looking for %s\n",inet_ntoa(sin->sin_addr)); +#endif + + sockfd = socket(AF_INET,SOCK_DGRAM,0); + if (sockfd < 0) { + if (local_ip_check) + return NULL; + else + return strdup("socket"); + } + lastlen = 0; + len = 100 * sizeof(struct ifreq); + while (1) { + buf = malloc(len); + if (NULL == buf) { + if (local_ip_check) + return NULL; + else + return strdup("malloc"); + } + + ifc.ifc_len = len; + ifc.ifc_buf = buf; + + if (ioctl(sockfd, SIOCGIFCONF, &ifc) < 0) { + if (errno != EINVAL || lastlen != 0) { + free(buf); + if (local_ip_check) + return NULL; + else + return strdup("SIOCIFCONF"); + } + } + else { + if (ifc.ifc_len == lastlen) + break; /* the ioctl was happy */ + lastlen = ifc.ifc_len; + } + len += 10 * sizeof(struct ifreq); + free(buf); + } + +#if defined(NETPERF_STANDALONE_DEBUG) + printf("ioctl was OK, len is %d\n", ifc.ifc_len); +#endif + + for (ptr = buf; ptr < buf + ifc.ifc_len; ) { + ifr = (struct ifreq *) ptr; + + switch (ifr->ifr_addr.sa_family) { +#ifdef AF_INET6 + case AF_INET6: + addr1 = &(sin6->sin6_addr); + tsin6 = (struct sockaddr_in6 *)&(ifr->ifr_addr); + addr2 = &(tsin6->sin6_addr); + cmplen = sizeof(tsin6->sin6_addr); + len = sizeof(struct sockaddr_in6); + break; +#endif + case AF_INET: + default: + addr1 = &(sin->sin_addr.s_addr); + tsin = (struct sockaddr_in *)&(ifr->ifr_addr); + addr2 = &(tsin->sin_addr.s_addr); + cmplen = sizeof(struct in_addr); + len = sizeof(struct sockaddr_in); + break; + } + +#if defined(NETPERF_STANDALONE_DEBUG) + printf("hello i am interface %s family %d\n", + ifr->ifr_name, + ifr->ifr_addr.sa_family); +#endif + +#ifdef HAVE_SOCKADDR_SA_LEN + if (sizeof(struct sockaddr) > ifr->ifr_addr.sa_len) + len = sizeof(struct sockaddr); + else + len = ifr->ifr_addr.sa_len; +#endif + + /* we are basicaly ass-u-me-ing that an ifr is only a name and a + sockaddr */ + ptr += sizeof(ifr->ifr_name) + len; + + if (ifr->ifr_addr.sa_family != sin->sin_family) + continue; + else { + +#if defined(NETPERF_STANDALONE_DEBUG) + printf("addr1 %p addr2 %p len %d\n",addr1,addr2,cmplen); +#endif + if (0 == memcmp(addr1,addr2,cmplen)) { + struct ifreq flagsreq; + flagsreq = *ifr; + /* we've gotten this far - ass-u-me this will work? */ + ioctl(sockfd,SIOCGIFFLAGS, &flagsreq); + if (flagsreq.ifr_flags & IFF_UP) { +#if defined(NETPERF_STANDALONE_DEBUG) + printf("Interface name %s family %d\n",ifr->ifr_name,ifr->ifr_addr.sa_family); +#endif + close(sockfd); + /* we should probably close the memory leak one of these days */ + return strdup(ifr->ifr_name); + } + } + } + } + close(sockfd); + free(buf); + if (local_ip_check) + return NULL; + else + return strdup("EgressByAddr"); +#endif +} + +#if defined(AF_LINK) +char * +find_egress_interface_by_link(struct sockaddr_dl *socklink) { + + char buffer[IF_NAMESIZE]; + char *cret; + +#if defined(NETPERF_STANDALONE_DEBUG) + printf("socklink asdf index %d nlen %d alen %d slen %d\n", + socklink->sdl_index, + socklink->sdl_nlen, + socklink->sdl_alen, + socklink->sdl_slen); +#endif + + /* I suspect we could extract the name from the sockaddr_dl + directly, and perhaps should, but I really don't like mucking + about with pointers and offsets and characters so will just punt + to if_indextoname. raj 2008-03-17 */ + if (socklink->sdl_index != 0) { + cret = if_indextoname(socklink->sdl_index,buffer); + if (NULL != cret) + return strdup(cret); + else + return strdup(strerror(errno)); + } + else if (socklink->sdl_nlen > 0) { + /* ok, I might have to care after all */ + strncpy(buffer,socklink->sdl_data,socklink->sdl_nlen); + return strdup(buffer); + } + else + return strdup("noindex"); +} + +#endif + +/* borrows heavily from W Richard Stevens' getrt.c of unp fame */ + +#define BUFLEN (sizeof(struct rt_msghdr) + 512) + +char * +find_egress_interface(struct sockaddr *source, struct sockaddr *dest) { + + int sockfd; + int ret; + struct rt_msghdr *rtm; + int copy_len; + char *buffer; + void *next_hop; + struct sockaddr_storage holdme; + struct sockaddr_in *sin; + struct sockaddr_in6 *sin6; + + /* first, check if the destination address is a local one. if it is, + return "lo0" as the interface because we will ass-u-me the + traffic isn't leaving the host */ + if (NULL != find_egress_interface_by_addr(dest,1)) { +#if defined(NETPERF_STANDALONE_DEBUG) + printf("Destination is a local IP\n"); +#endif + return strdup("lo0"); + } + + + sockfd = socket(AF_ROUTE, SOCK_RAW, 0); + if (sockfd < 0) + return strdup("socket"); + + buffer = calloc(1,BUFLEN); + if (NULL == buffer) + return strdup("calloc"); + + rtm = (struct rt_msghdr *)buffer; + + rtm->rtm_msglen = sizeof(struct rt_msghdr); + sin = (struct sockaddr_in *)dest; + + if (AF_INET == sin->sin_family) { + +#if defined(NETPERF_STANDALONE_DEBUG) + printf("Resolving addr is %s\n",inet_ntoa(sin->sin_addr)); +#endif + + rtm->rtm_msglen += sizeof(struct sockaddr_in); + copy_len = sizeof(struct sockaddr_in); + } +#if defined(AF_INET6) + else if (AF_INET6 == sin->sin_family) { + rtm->rtm_msglen += sizeof(struct sockaddr_in6); + copy_len = sizeof(struct sockaddr_in6); + } +#endif + else { + free(buffer); + return strdup("Unknown AF"); + } + + rtm->rtm_version = RTM_VERSION; + rtm->rtm_type = RTM_GET; + rtm->rtm_addrs = RTA_DST; + rtm->rtm_pid = getpid(); + rtm->rtm_seq = 12865; + + /* point just beyond the rt_msghdr. */ + memcpy((rtm + 1), dest, copy_len); + + /* send the message */ + ret = write(sockfd,rtm,rtm->rtm_msglen); + if (ret != rtm->rtm_msglen) { + free(buffer); + return strdup("write"); + } + + /* seek the reply */ + do { + ret = read(sockfd, rtm, BUFLEN); + if (ret < sizeof(struct rt_msghdr)) { + free(buffer); + return strdup("read"); + } + } while (rtm->rtm_type != RTM_GET || + rtm->rtm_seq != 12865 || + rtm->rtm_pid != getpid()); + if ((rtm->rtm_flags & RTF_GATEWAY) && + (rtm->rtm_addrs & RTA_GATEWAY)) { + /* we have a next hop gateway to resolve. we take advantage of the + observation that if there is a gateway address there "aways" + seems to be an RTA_DST in front of it */ + sin = (struct sockaddr_in *)(rtm + 1); + sin6 = (struct sockaddr_in6 *)sin; + if (AF_INET == sin->sin_family) + return find_egress_interface(NULL,(struct sockaddr *)(sin + 1)); + else + return find_egress_interface(NULL,(struct sockaddr *)(sin6 + 1)); + } + + /* once again, we take "advantage" of the item of interest "always" + being the second in the list. there seem to be two distinct + "camps" here - in one camp are AIX and Solaris (at least 5.3 and + 10 respectively) which only resolve as far down as a local + interface IP address. in the other camp are HP-UX 11iv3 (11.31) + and I'm _guessing_ BSD and OSX, who are kind enough to take + things down to an AF_LINK entry. */ + + sin = (struct sockaddr_in *)(rtm +1); + sin = sin + 1; + sin6 = (struct sockaddr_in6 *)sin; + +#if defined(NETPERF_STANDALONE_DEBUG) + printf("address two %p family %d\n",sin,sin->sin_family); +#endif + + if (AF_INET == sin->sin_family) { + return find_egress_interface_by_addr((struct sockaddr *)sin,0); + } +#if defined(AF_INET6) + else if (AF_INET6 == sin6->sin6_family) { + return find_egress_interface_by_addr((struct sockaddr *)sin6,0); + } +#endif +#if defined(AF_LINK) + else if (AF_LINK == sin->sin_family) { + return find_egress_interface_by_link((struct sockaddr_dl *)sin); + } +#endif + else + return strdup("LastHop AF"); +} + + +#if defined(NETPERF_STANDALONE_DEBUG) +int +main(int argc, char *argv[]) { + + struct sockaddr_storage destination; + struct sockaddr_in *sin; + int ret; + char *egress_if; + + sin = (struct sockaddr_in *)&destination; + sin->sin_family = AF_INET; + sin->sin_addr.s_addr = inet_addr(argv[1]); + sin->sin_len = sizeof(struct sockaddr_in); + printf("address is %s\n",inet_ntoa(sin->sin_addr)); + egress_if = find_egress_interface(NULL,(struct sockaddr *)&destination); + + printf("egress interface %p %s\n",egress_if,egress_if); + +} +#endif diff --git a/src/netrt_rtnetlink.c b/src/netrt_rtnetlink.c new file mode 100644 index 0000000..025d3d6 --- /dev/null +++ b/src/netrt_rtnetlink.c @@ -0,0 +1,250 @@ +#if defined(HAVE_CONFIG_H) +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +char * +find_egress_interface(struct sockaddr *source, struct sockaddr *dest) { + + struct sockaddr_nl me,them; + struct sockaddr_in *in4; + struct sockaddr_in6 *in6; + + int interface_index = -1; + char interface_name[IF_NAMESIZE]; + + int s; + + /* so, in our msghdr we will put the address and an iovec pointing + to our request. that request will consist of a netlink message + header, a routing message header and some routing attributes. + the chalice with the palace holds the pellet with the poison, the + vessel with the pestle holds the brew which is true. i guess it + would have been "too easy" to just have a plain old ioctl that + one calls to get the route for a given destination and + source... raj 2008-02-11 */ + + struct msghdr msg; + + struct iovec iov; + + struct { + struct nlmsghdr nl; + struct rtmsg rt; + char buf[1024]; + } request; + + char reply[1024]; + + struct nlmsghdr *nlp; + struct rtmsg *rtp; + struct rtattr *rtap; + int nll,rtl; + + int ret; + + /* create and bind the netlink socket */ + s = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE); + + memset(&me, 0, sizeof(me)); + me.nl_family = AF_NETLINK; + me.nl_pid = getpid(); + + /* probably should be checking a return value... */ + bind(s, (struct sockaddr *)&me, sizeof(me)); + + /* create the message we are going to send */ + + memset(&request, 0, sizeof(request)); + request.nl.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg)); + request.nl.nlmsg_flags = NLM_F_REQUEST; + request.nl.nlmsg_type = RTM_GETROUTE; + + /* time to add the destination attribute to the request */ + if (dest) { + in4 = (struct sockaddr_in *)dest; + in6 = (struct sockaddr_in6 *)dest; + request.rt.rtm_family = in4->sin_family; + rtap = (struct rtattr *)request.buf; + rtap->rta_type = RTA_DST; + if (AF_INET == in4->sin_family) { + /* while a sin_addr is a multiple of 4 bytes in length, we + should still use RTA_SPACE rather than RTA_LENGTH. kudos to + Thomas Graf for pointing that out */ + rtap->rta_len = RTA_SPACE(sizeof(in4->sin_addr)); + memcpy(RTA_DATA(rtap), &(in4->sin_addr), sizeof(in4->sin_addr)); + } + else if (AF_INET6 == in6->sin6_family) { + rtap->rta_len = RTA_SPACE(sizeof(in6->sin6_addr)); + memcpy(RTA_DATA(rtap), &(in6->sin6_addr), sizeof(in6->sin6_addr)); + } + else { + return strdup("UnknownAddressFamily"); + } + } + else { + /* there must always be a destination */ + printf("No destination specified.\n"); + return strdup("NoDestination"); + } + + /* add the length of our request to our overall message length. it + should already be suitably padded by the previous RTA_SPACE */ + request.nl.nlmsg_len += rtap->rta_len; + + /* now the src */ + if (source) { + /* the source goes after the dest, so we can just increment by the + current value of rta_len */ + in4 = (struct sockaddr_in *)source; + in6 = (struct sockaddr_in6 *)source; + + /* pointer math is fun. silly me initially tried to to rtap += + rtap->rta_len but since rtap isn't pointing at bytes... again + kudos to Thomas Graf for finding that mistake */ + rtap = (struct rtattr *)((char *)rtap + (rtap->rta_len)); + rtap->rta_type = RTA_SRC; + if (AF_INET == in4->sin_family) { + rtap->rta_len = RTA_SPACE(sizeof(in4->sin_addr)); + memcpy(RTA_DATA(rtap), &(in4->sin_addr), sizeof(in4->sin_addr)); + } + else if (AF_INET6 == in6->sin6_family) { + rtap->rta_len = RTA_SPACE(sizeof(in6->sin6_addr)); + memcpy(RTA_DATA(rtap), &(in6->sin6_addr), sizeof(in6->sin6_addr)); + } + else { + return strdup("UnknownAddressFamily"); + } + + + /* add the length of the just added attribute to the overall + message length. it should already be suitably padded by the + previous RTA_SPACE */ + request.nl.nlmsg_len += rtap->rta_len; + } + + /* address it */ + memset(&them, 0, sizeof(them)); + them.nl_family = AF_NETLINK; + + memset(&msg, 0, sizeof(msg)); + msg.msg_name = (void *)&them; + msg.msg_namelen = sizeof(them); + + iov.iov_base = (void *) &request.nl; + iov.iov_len = request.nl.nlmsg_len; + + msg.msg_iov = &iov; + msg.msg_iovlen = 1; + + /* send it */ + ret = sendmsg(s, &msg, 0); + + if (ret < 0) { + return strdup("SendmsgFailure"); + } + + memset(reply,0,sizeof(reply)); + ret = recv(s, reply, sizeof(reply), 0); + + if (ret < 0) { + return strdup("RecvmsgFailure"); + } + + nll = ret; + + /* Since we are looking for a single route, one has to wonder if + this is really necessary, but since all the examples I could find + seemed to be doing it, I'll simply follow along. raj + 2008-02-11 */ + + for (nlp = (struct nlmsghdr *)reply; + NLMSG_OK(nlp,nll); + nlp = NLMSG_NEXT(nlp, nll)) { + /* where oh where might the route header be? */ + rtp = (struct rtmsg *) NLMSG_DATA(nlp); + +#if 0 + /* we will ass-u-me we are only interested in results for the main + routing table */ + if (RT_TABLE_MAIN != rtp->rtm_table) { + printf("skipping table %d\n",rtp->rtm_table); + continue; + } +#endif + + for (rtap = (struct rtattr *) RTM_RTA(rtp), rtl = RTM_PAYLOAD(nlp); + RTA_OK(rtap, rtl); + rtap = RTA_NEXT(rtap,rtl)) { + if (RTA_OIF == rtap->rta_type) { + if (-1 == interface_index){ + interface_index = *((int *) RTA_DATA(rtap)); + } + else { + printf("Found a second interface index, which was not expected!\n"); + return strdup("MultipleInterfacesFound"); + } + } + } + } + + if (interface_index == -1) { + /* we didn't find it */ + return strdup("InterfaceNotFound"); + } + else { + if (NULL == if_indextoname(interface_index,interface_name)) { + return strdup("IfIndexToNameFailure"); + } + else { + return strdup(interface_name); + } + } +} +#if defined(NETPERF_STANDALONE_DEBUG) +int +main(int argc, char *argv[]) { + + struct sockaddr_storage source,destination; + struct sockaddr_in *sin; + int ret; + char *egress_if; + + if ((argc < 2) || (argc > 3)) { + fprintf(stderr,"%s [srcip]\n",argv[0]); + return -1; + } + + sin = (struct sockaddr_in *)&destination; + sin->sin_family = AF_INET; + sin->sin_addr.s_addr = inet_addr(argv[1]); + + printf("destination address is %s\n",inet_ntoa(sin->sin_addr)); + + sin = NULL; + + if (argc == 3) { + sin = (struct sockaddr_in *)&source; + sin->sin_family = AF_INET; + sin->sin_addr.s_addr = inet_addr(argv[2]); + } + + egress_if = find_egress_interface((struct sockaddr *)sin,(struct sockaddr *)&destination); + + printf("egress interface %p %s\n",egress_if,egress_if); + +} +#endif diff --git a/src/netsec_linux.c b/src/netsec_linux.c new file mode 100644 index 0000000..d133b38 --- /dev/null +++ b/src/netsec_linux.c @@ -0,0 +1,148 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#if defined(HAVE_STRING_H) +#include +#endif + +#include +#include +#include +#include + +#include + +void *messiah; /* Handel's... */ + +/* for the NSEC_mumble defines */ +#include "netlib.h" + + +void +find_security_info_selinux(int *enabled, int *type, char **specific){ + + int ret; + int enforcing; + + /* at some point we should probably get these from + selinux/selinux.h? */ + int (*getenforce)(int *); + int (*getpolicy)(char **); + + *enabled = NSEC_UNKNOWN; + *type = NSEC_TYPE_SELINUX; + + getenforce = dlsym(messiah, "selinux_getenforcemode"); + if (NULL == getenforce) { + dlclose(messiah); + *specific = strdup("no getenforcemode"); + return; + } + + ret = (*getenforce)(&enforcing); +#if defined(NETPERF_STANDALONE_DEBUG) + printf("after selinux_getenforcemode() ret is %d\n",ret); +#endif + + switch(enforcing) { + case -1: + *enabled = NSEC_DISABLED; + break; + case 0: + *enabled = NSEC_PERMISSIVE; + break; + case 1: + *enabled = NSEC_ENFORCING; + break; + default: + *enabled = NSEC_UNKNOWN; + } + + getpolicy = dlsym(messiah, "selinux_getpolicytype"); + if (NULL == getpolicy) { + dlclose(messiah); + *specific = strdup("no getpolicytype"); + return; + } + + ret = (*getpolicy)(specific); +#if defined(NETPERF_STANDALONE_DEBUG) + printf("after selinux_getpolicytype ret is %d\n",ret); +#endif + + return; +} + +/* presently we only know about SELinux or nothing. at some point we + probably need to learn about AppArmor and the like. raj + 20081020 */ + +void +find_security_info(int *enabled, int *type, char **specific) { + + /* first, might it be selinux? */ + messiah = dlopen("libselinux.so", RTLD_LAZY); + if (NULL != messiah) { + dlerror(); + return find_security_info_selinux(enabled, type, specific); + } + else { + *enabled = NSEC_UNKNOWN; + *type = NSEC_TYPE_UNKNOWN; + *specific = "unknown"; + return; + } +} + +#if defined(NETPERF_STANDALONE_DEBUG) + +/* these are normally found in src/netlib.c but we put copies here for + the nefaious popoise of standalone debugging */ + +char * +nsec_enabled_to_str(int enabled) { + switch (enabled) { + case NSEC_UNKNOWN: + return("Unknown"); + case NSEC_DISABLED: + return("Disabled"); + case NSEC_PERMISSIVE: + return("Permissive"); + case NSEC_ENFORCING: + return("Enforcing"); + default: + return("UNKNOWN MODE"); + } +} + +char * nsec_type_to_str(int type) { + switch (type) { + case NSEC_TYPE_UNKNOWN: + return("Unknown"); + case NSEC_TYPE_SELINUX: + return("SELinux"); + default: + return("UNKNOWN TYPE"); + } +} + +int +main(int argc, char *argv[]) { + + char *specific; + int enabled; + int type; + + find_security_info(&enabled, &type, &specific); + + printf("Security info: enabled %s (%d) type %s (0x%x) specific %s\n", + nsec_enabled_to_str(enabled), + enabled, + nsec_type_to_str(type), + type, + specific); + + return 0; +} +#endif diff --git a/src/netsec_none.c b/src/netsec_none.c new file mode 100644 index 0000000..556d767 --- /dev/null +++ b/src/netsec_none.c @@ -0,0 +1,37 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#if defined(HAVE_STRING_H) +#include +#endif + +#include +#include "netlib.h" + +void +find_security_info(int *enabled, int *type, char **specific){ + *enabled = NSEC_UNKNOWN; + *type = NSEC_TYPE_UNKNOWN; + *specific = strdup("N/A"); + return; +} + +#if defined(NETPERF_STANDALONE_DEBUG) +int +main(int argc, char *argv[]) { + + char *specific; + int enabled; + int type; + + find_security_info(&enabled, &type, &specific); + + printf("Security info: enabled %d type 0x%x specific %s\n", + enabled, + type, + specific); + + return 0; +} +#endif diff --git a/src/netserver.c b/src/netserver.c new file mode 100644 index 0000000..1170564 --- /dev/null +++ b/src/netserver.c @@ -0,0 +1,1090 @@ +/* + + Copyright (C) 1993-2007 Hewlett-Packard Company + ALL RIGHTS RESERVED. + + The enclosed software and documentation includes copyrighted works + of Hewlett-Packard Co. For as long as you comply with the following + limitations, you are hereby authorized to (i) use, reproduce, and + modify the software and documentation, and to (ii) distribute the + software and documentation, including modifications, for + non-commercial purposes only. + + 1. The enclosed software and documentation is made available at no + charge in order to advance the general development of + high-performance networking products. + + 2. You may not delete any copyright notices contained in the + software or documentation. All hard copies, and copies in + source code or object code form, of the software or + documentation (including modifications) must contain at least + one of the copyright notices. + + 3. The enclosed software and documentation has not been subjected + to testing and quality control and is not a Hewlett-Packard Co. + product. At a future time, Hewlett-Packard Co. may or may not + offer a version of the software and documentation as a product. + + 4. THE SOFTWARE AND DOCUMENTATION IS PROVIDED "AS IS". + HEWLETT-PACKARD COMPANY DOES NOT WARRANT THAT THE USE, + REPRODUCTION, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR + DOCUMENTATION WILL NOT INFRINGE A THIRD PARTY'S INTELLECTUAL + PROPERTY RIGHTS. HP DOES NOT WARRANT THAT THE SOFTWARE OR + DOCUMENTATION IS ERROR FREE. HP DISCLAIMS ALL WARRANTIES, + EXPRESS AND IMPLIED, WITH REGARD TO THE SOFTWARE AND THE + DOCUMENTATION. HP SPECIFICALLY DISCLAIMS ALL WARRANTIES OF + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + + 5. HEWLETT-PACKARD COMPANY WILL NOT IN ANY EVENT BE LIABLE FOR ANY + DIRECT, INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES + (INCLUDING LOST PROFITS) RELATED TO ANY USE, REPRODUCTION, + MODIFICATION, OR DISTRIBUTION OF THE SOFTWARE OR DOCUMENTATION. + +*/ + +#include "netperf_version.h" + +char netserver_id[]="\ +@(#)netserver.c (c) Copyright 1993-2007 Hewlett-Packard Co. Version 2.4.3"; + + /***********************************************************************/ + /* */ + /* netserver.c */ + /* */ + /* This is the server side code for the netperf test package. It */ + /* will operate either stand-alone, or as a child of inetd. In this */ + /* way, we insure that it can be installed on systems with or without */ + /* root permissions (editing inetd.conf). Essentially, this code is */ + /* the analog to the netsh.c code. */ + /* */ + /***********************************************************************/ + + +/************************************************************************/ +/* */ +/* Global include files */ +/* */ +/************************************************************************/ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#if HAVE_STRING_H +# if !STDC_HEADERS && HAVE_MEMORY_H +# include +# endif +# include +#endif +#if HAVE_STRINGS_H +# include +#endif +#if HAVE_LIMITS_H +# include +#endif +#include +#include +#ifndef WIN32 +#include +#include +#endif +#if !defined(WIN32) && !defined(__VMS) && !defined(MSDOS) +#include +#endif /* !defined(WIN32) && !defined(__VMS) && !defined(MSDOS) */ +#include +#ifdef WIN32 +#include +#include +#define netperf_socklen_t socklen_t +/* we need to find some other way to decide to include ws2 */ +/* if you are trying to compile on Windows 2000 or NT 4 you will */ +/* probably have to define DONT_IPV6 */ +#ifndef DONT_IPV6 +#include +#endif /* DONT_IPV6 */ +#include +#define strdup _strdup +#define sleep(x) Sleep((x)*1000) +#else +#ifndef MPE +#include +#endif /* MPE */ +#include +#include +#include +#include +#include +#include +#ifndef DONT_WAIT +#include +#endif /* DONT_WAIT */ +#endif /* WIN32 */ +#include +#ifdef __VMS +#include +#include +#endif /* __VMS */ +#include "netlib.h" +#include "nettest_bsd.h" + +#ifdef WANT_UNIX +#include "nettest_unix.h" +#endif /* WANT_UNIX */ + +#ifdef WANT_DLPI +#include "nettest_dlpi.h" +#endif /* WANT_DLPI */ + +#ifdef WANT_SCTP +#include "nettest_sctp.h" +#endif + +#include "netsh.h" + +#ifndef DEBUG_LOG_FILE +#ifndef WIN32 +#define DEBUG_LOG_FILE "/tmp/netperf.debug" +#else +#define DEBUG_LOG_FILE "c:\\temp\\netperf.debug" +#endif /* WIN32 */ +#endif /* DEBUG_LOG_FILE */ + + /* some global variables */ + +FILE *afp; +char listen_port[10]; +extern char *optarg; +extern int optind, opterr; + +#ifndef WIN32 +#define SERVER_ARGS "dL:n:p:v:V46" +#else +#define SERVER_ARGS "dL:n:p:v:V46I:i:" +#endif + +/* perhaps one day we will use this as part of only opening a debug + log file if debug is set, of course we have to be wary of the base + use of "where" and so probably always need "where" pointing + "somewhere" or other. */ +void +open_debug_file() +{ +#ifndef WIN32 +#ifndef PATH_MAX +#define PATH_MAX MAX_PATH +#endif + char FileName[PATH_MAX]; /* for opening the debug log file */ + strcpy(FileName, DEBUG_LOG_FILE); + + if (where != NULL) fflush(where); + + snprintf(&FileName[strlen(FileName)], sizeof(FileName) - strlen(FileName), "_%d", getpid()); + if ((where = fopen(FileName, "w")) == NULL) { + perror("netserver: debug file"); + exit(1); + } + + chmod(FileName,0644); +#endif + +} + /* This routine implements the "main event loop" of the netperf */ + /* server code. Code above it will have set-up the control connection */ + /* so it can just merrily go about its business, which is to */ + /* "schedule" performance tests on the server. */ + +void +process_requests() +{ + + float temp_rate; + + if (debug) open_debug_file(); + + + while (1) { + recv_request(); + + switch (netperf_request.content.request_type) { + + case DEBUG_ON: + netperf_response.content.response_type = DEBUG_OK; + /* dump_request already present in recv_request; redundant? */ + if (!debug) { + debug++; + open_debug_file(); + dump_request(); + } + send_response(); + break; + + case DEBUG_OFF: + if (debug) + debug--; + netperf_response.content.response_type = DEBUG_OK; + send_response(); + /* +SAF why??? */ + if (!debug) + { + fclose(where); +#if !defined(WIN32) && !defined(MPE) && !defined(__VMS) && !defined(MSDOS) + /* For Unix: reopen the debug write file descriptor to "/dev/null" */ + /* and redirect stdout to it. */ + fflush (stdout); + where = fopen ("/dev/null", "w"); + if (where == NULL) + { + perror ("netserver: reopening debug fp for writing: /dev/null"); + exit (1); + } + if (close (STDOUT_FILENO) == -1) + { + perror ("netserver: closing stdout file descriptor"); + exit (1); + } + if (dup (fileno (where)) == -1) + { + perror ("netserver: duplicate /dev/null write file descr. to stdout"); + exit (1); + } +#endif /* !WIN32 !MPE !__VMS !MSDOS */ + } + break; + + case DO_SYSINFO: + { + char *delims[4]; + int i; + delims[0] = strdup("|"); + delims[1] = strdup(","); + delims[2] = strdup("_"); + delims[3] = strdup(";"); + + netperf_response.content.response_type = SYSINFO_RESPONSE; + for (i = 0; i < 4; i++) { + if ((!strstr(local_sysname,delims[i])) && + (!strstr(local_release,delims[i])) && + (!strstr(local_machine,delims[i])) && + (!strstr(local_version,delims[i]))) { + snprintf((char *)netperf_response.content.test_specific_data, + sizeof(netperf_response) - 7, + "%c%s%c%s%c%s%c%s", + delims[i][0], + local_sysname, + delims[i][0], + local_release, + delims[i][0], + local_machine, + delims[i][0], + local_version); + break; + } + } + if (i == 4) { + /* none of the delimiters were unique, use the last one */ + snprintf((char *)netperf_response.content.test_specific_data, + sizeof(netperf_response) - 7, + "%c%s%c%s%c%s%c%s", + delims[i][0], + "NoDelimUnique", + delims[i][0], + "NoDelimUnique", + delims[i][0], + "NoDelimUnique", + delims[i][0], + "NoDelimUnique"); + } + send_response_n(0); + break; + } + case CPU_CALIBRATE: + netperf_response.content.response_type = CPU_CALIBRATE; + temp_rate = calibrate_local_cpu(0.0); + bcopy((char *)&temp_rate, + (char *)netperf_response.content.test_specific_data, + sizeof(temp_rate)); + bcopy((char *)&lib_num_loc_cpus, + (char *)netperf_response.content.test_specific_data + sizeof(temp_rate), + sizeof(lib_num_loc_cpus)); + if (debug) { + fprintf(where,"netserver: sending CPU information:"); + fprintf(where,"rate is %g num cpu %d\n",temp_rate,lib_num_loc_cpus); + fflush(where); + } + + /* we need the cpu_start, cpu_stop in the looper case to kill the */ + /* child proceses raj 7/95 */ + +#ifdef USE_LOOPER + cpu_start(1); + cpu_stop(1,&temp_rate); +#endif /* USE_LOOPER */ + + send_response(); + break; + + case DO_TCP_STREAM: + recv_tcp_stream(); + break; + + case DO_TCP_MAERTS: + recv_tcp_maerts(); + break; + + case DO_TCP_RR: + recv_tcp_rr(); + break; + + case DO_TCP_CRR: + recv_tcp_conn_rr(); + break; + + case DO_TCP_CC: + recv_tcp_cc(); + break; + +#ifdef DO_1644 + case DO_TCP_TRR: + recv_tcp_tran_rr(); + break; +#endif /* DO_1644 */ + +#ifdef DO_NBRR + case DO_TCP_NBRR: + recv_tcp_nbrr(); + break; +#endif /* DO_NBRR */ + + case DO_UDP_STREAM: + recv_udp_stream(); + break; + + case DO_UDP_RR: + recv_udp_rr(); + break; + +#ifdef WANT_DLPI + + case DO_DLPI_CO_RR: + recv_dlpi_co_rr(); + break; + + case DO_DLPI_CL_RR: + recv_dlpi_cl_rr(); + break; + + case DO_DLPI_CO_STREAM: + recv_dlpi_co_stream(); + break; + + case DO_DLPI_CL_STREAM: + recv_dlpi_cl_stream(); + break; + +#endif /* WANT_DLPI */ + +#ifdef WANT_UNIX + + case DO_STREAM_STREAM: + recv_stream_stream(); + break; + + case DO_STREAM_RR: + recv_stream_rr(); + break; + + case DO_DG_STREAM: + recv_dg_stream(); + break; + + case DO_DG_RR: + recv_dg_rr(); + break; + +#endif /* WANT_UNIX */ + +#ifdef WANT_XTI + case DO_XTI_TCP_STREAM: + recv_xti_tcp_stream(); + break; + + case DO_XTI_TCP_RR: + recv_xti_tcp_rr(); + break; + + case DO_XTI_UDP_STREAM: + recv_xti_udp_stream(); + break; + + case DO_XTI_UDP_RR: + recv_xti_udp_rr(); + break; + +#endif /* WANT_XTI */ + +#ifdef WANT_SCTP + case DO_SCTP_STREAM: + recv_sctp_stream(); + break; + + case DO_SCTP_STREAM_MANY: + recv_sctp_stream_1toMany(); + break; + + case DO_SCTP_RR: + recv_sctp_rr(); + break; + + case DO_SCTP_RR_MANY: + recv_sctp_rr_1toMany(); + break; +#endif + +#ifdef WANT_SDP + case DO_SDP_STREAM: + recv_sdp_stream(); + break; + + case DO_SDP_MAERTS: + recv_sdp_maerts(); + break; + + case DO_SDP_RR: + recv_sdp_rr(); + break; +#endif + +#ifdef WANT_OMNI + case DO_OMNI: + recv_omni(); + break; +#endif + + default: + fprintf(where,"unknown test number %d\n", + netperf_request.content.request_type); + fflush(where); + netperf_response.content.serv_errno=998; + send_response(); + break; + + } + } +} + +/* + set_up_server() + + set-up the server listen socket. we only call this routine if the + user has specified a port number on the command line or we believe we + are not a child of inetd or its platform-specific equivalent */ + +/*KC*/ + +void +set_up_server(char hostname[], char port[], int af) +{ + + struct addrinfo hints; + struct addrinfo *local_res; + struct addrinfo *local_res_temp; + + struct sockaddr_storage peeraddr; + netperf_socklen_t peeraddr_len = sizeof(peeraddr); + + SOCKET server_control; + int on=1; + int count; + int error; + int not_listening; + +#if !defined(WIN32) && !defined(MPE) && !defined(__VMS) && !defined(MSDOS) + FILE *rd_null_fp; /* Used to redirect from "/dev/null". */ + FILE *wr_null_fp; /* Used to redirect to "/dev/null". */ +#endif /* !WIN32 !MPE !__VMS !MDOS */ + + if (debug) { + fprintf(stderr, + "set_up_server called with host '%s' port '%s' remfam %d\n", + hostname, + port, + af); + fflush(stderr); + } + + memset(&hints,0,sizeof(hints)); + hints.ai_family = af; + hints.ai_socktype = SOCK_STREAM; + hints.ai_protocol = IPPROTO_TCP; + hints.ai_flags = AI_PASSIVE; + + count = 0; + do { + error = getaddrinfo((char *)hostname, + (char *)port, + &hints, + &local_res); + count += 1; + if (error == EAI_AGAIN) { + if (debug) { + fprintf(stderr,"Sleeping on getaddrinfo EAI_AGAIN\n"); + fflush(stderr); + } + sleep(1); + } + } while ((error == EAI_AGAIN) && (count <= 5)); + + if (error) { + fprintf(stderr, + "set_up_server: could not resolve remote '%s' port '%s' af %d", + hostname, + port, + af); + fprintf(stderr,"\n\tgetaddrinfo returned %d %s\n", + error, + gai_strerror(error)); + exit(-1); + } + + if (debug) { + dump_addrinfo(stderr, local_res, hostname, port, af); + } + + not_listening = 1; + local_res_temp = local_res; + + while((local_res_temp != NULL) && (not_listening)) { + + fprintf(stderr, + "Starting netserver at port %s\n", + port); + + server_control = socket(local_res_temp->ai_family,SOCK_STREAM,0); + + if (server_control == INVALID_SOCKET) { + perror("set_up_server could not allocate a socket"); + exit(-1); + } + + /* happiness and joy, keep going */ + if (setsockopt(server_control, + SOL_SOCKET, + SO_REUSEADDR, + (char *)&on , + sizeof(on)) == SOCKET_ERROR) { + if (debug) { + perror("warning: set_up_server could not set SO_REUSEADDR"); + } + } + /* still happy and joyful */ + + if ((bind (server_control, + local_res_temp->ai_addr, + local_res_temp->ai_addrlen) != SOCKET_ERROR) && + (listen (server_control,5) != SOCKET_ERROR)) { + not_listening = 0; + break; + } + else { + /* we consider a bind() or listen() failure a transient and try + the next address */ + if (debug) { + perror("warning: set_up_server failed a bind or listen call\n"); + } + local_res_temp = local_res_temp->ai_next; + continue; + } + } + + if (not_listening) { + fprintf(stderr, + "set_up_server could not establish a listen endpoint for %s port %s with family %s\n", + host_name, + port, + inet_ftos(af)); + fflush(stderr); + exit(-1); + } + else { + printf("Starting netserver at hostname %s port %s and family %s\n", + hostname, + port, + inet_ftos(af)); + } + + /* + setpgrp(); + */ + +#if !defined(WIN32) && !defined(MPE) && !defined(__VMS) && !defined(VMWARE_UW) && !defined(MSDOS) + /* Flush the standard I/O file descriptors before forking. */ + fflush (stdin); + fflush (stdout); + fflush (stderr); +#if defined(HAVE_FORK) + switch (fork()) +#else + switch (vfork()) +#endif + { + case -1: + perror("netperf server error"); + exit(1); + + case 0: + /* Redirect stdin from "/dev/null". */ + rd_null_fp = fopen ("/dev/null", "r"); + if (rd_null_fp == NULL) + { + perror ("netserver: opening for reading: /dev/null"); + exit (1); + } + if (close (STDIN_FILENO) == -1) + { + perror ("netserver: closing stdin file descriptor"); + exit (1); + } + if (dup (fileno (rd_null_fp)) == -1) + { + perror ("netserver: duplicate /dev/null read file descr. to stdin"); + exit (1); + } + + /* Redirect stdout to the debug write file descriptor. */ + if (close (STDOUT_FILENO) == -1) + { + perror ("netserver: closing stdout file descriptor"); + exit (1); + } + if (dup (fileno (where)) == -1) + { + perror ("netserver: duplicate the debug write file descr. to stdout"); + exit (1); + } + + /* Redirect stderr to "/dev/null". */ + wr_null_fp = fopen ("/dev/null", "w"); + if (wr_null_fp == NULL) + { + perror ("netserver: opening for writing: /dev/null"); + exit (1); + } + if (close (STDERR_FILENO) == -1) + { + perror ("netserver: closing stderr file descriptor"); + exit (1); + } + if (dup (fileno (wr_null_fp)) == -1) + { + perror ("netserver: dupicate /dev/null write file descr. to stderr"); + exit (1); + } + +#ifndef NO_SETSID + setsid(); +#else + setpgrp(); +#endif /* NO_SETSID */ + + /* some OS's have SIGCLD defined as SIGCHLD */ +#ifndef SIGCLD +#define SIGCLD SIGCHLD +#endif /* SIGCLD */ + + signal(SIGCLD, SIG_IGN); + +#endif /* !WIN32 !MPE !__VMS !MSDOS */ + + for (;;) + { + if ((server_sock=accept(server_control, + (struct sockaddr *)&peeraddr, + &peeraddr_len)) == INVALID_SOCKET) + { + printf("server_control: accept failed errno %d\n",errno); + exit(1); + } +#if defined(MPE) || defined(__VMS) || defined(VMWARE_UW) || defined(MSDOS) + /* + * Since we cannot fork this process , we cant fire any threads + * as they all share the same global data . So we better allow + * one request at at time + */ + process_requests() ; +#elif WIN32 + { + BOOL b; + char *cmdline; + PROCESS_INFORMATION pi; + STARTUPINFO si; + int i; + + /* create the cmdline array based on strlen(program) + 80 chars */ + cmdline = malloc(strlen(program) + 80); + + memset(&si, 0 , sizeof(STARTUPINFO)); + si.cb = sizeof(STARTUPINFO); + + /* Pass the server_sock as stdin for the new process. */ + /* Hopefully this will continue to be created with the OBJ_INHERIT attribute. */ + si.hStdInput = (HANDLE)server_sock; + si.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE); + si.hStdError = GetStdHandle(STD_ERROR_HANDLE); + si.dwFlags = STARTF_USESTDHANDLES; + + /* Build cmdline for child process */ + strcpy(cmdline, program); + if (verbosity > 1) { + snprintf(&cmdline[strlen(cmdline)], sizeof(cmdline) - strlen(cmdline), " -v %d", verbosity); + } + for (i=0; i < debug; i++) { + snprintf(&cmdline[strlen(cmdline)], sizeof(cmdline) - strlen(cmdline), " -d"); + } + snprintf(&cmdline[strlen(cmdline)], sizeof(cmdline) - strlen(cmdline), " -I %x", (int)(UINT_PTR)server_sock); + snprintf(&cmdline[strlen(cmdline)], sizeof(cmdline) - strlen(cmdline), " -i %x", (int)(UINT_PTR)server_control); + snprintf(&cmdline[strlen(cmdline)], sizeof(cmdline) - strlen(cmdline), " -i %x", (int)(UINT_PTR)where); + + b = CreateProcess(NULL, /* Application Name */ + cmdline, + NULL, /* Process security attributes */ + NULL, /* Thread security attributes */ + TRUE, /* Inherit handles */ + 0, /* Creation flags PROCESS_QUERY_INFORMATION, */ + NULL, /* Enviornment */ + NULL, /* Current directory */ + &si, /* StartupInfo */ + &pi); + if (!b) + { + perror("CreateProcessfailure: "); + free(cmdline); /* even though we exit :) */ + exit(1); + } + + /* We don't need the thread or process handles any more; let them */ + /* go away on their own timeframe. */ + + CloseHandle(pi.hThread); + CloseHandle(pi.hProcess); + + /* And close the server_sock since the child will own it. */ + + close(server_sock); + free(cmdline); + } +#else + signal(SIGCLD, SIG_IGN); +#if defined(HAVE_FORK) + switch (fork()) +#else + switch (vfork()) +#endif + { + case -1: + /* something went wrong */ + exit(1); + case 0: + /* we are the child process */ + close(server_control); + process_requests(); + exit(0); + break; + default: + /* we are the parent process */ + close(server_sock); + /* we should try to "reap" some of our children. on some */ + /* systems they are being left as defunct processes. we */ + /* will call waitpid, looking for any child process, */ + /* with the WNOHANG feature. when waitpid return a zero, */ + /* we have reaped all the children there are to reap at */ + /* the moment, so it is time to move on. raj 12/94 */ +#ifndef DONT_WAIT +#ifdef NO_SETSID + /* Only call "waitpid()" if "setsid()" is not used. */ + while(waitpid(-1, NULL, WNOHANG) > 0) { } +#endif /* NO_SETSID */ +#endif /* DONT_WAIT */ + break; + } +#endif /* !WIN32 !MPE !__VMS !MSDOS */ + } /*for*/ +#if !defined(WIN32) && !defined(MPE) && !defined(__VMS) && !defined(VMWARE_UW) && !defined(MSDOS) + break; /*case 0*/ + + default: + exit (0); + + } +#endif /* !WIN32 !MPE !__VMS !MSDOS */ +} + +#ifdef WIN32 + + /* With Win2003, WinNT's POSIX subsystem is gone and hence so is */ + /* fork. */ + + /* But hopefully the kernel support will continue to exist for some */ + /* time. */ + + /* We are not counting on the child address space copy_on_write */ + /* support, since it isn't exposed except through the NT native APIs */ + /* (which is not public). */ + + /* We will try to use the InheritHandles flag in CreateProcess. It */ + /* is in the public API, though it is documented as "must be FALSE". */ + + /* So where we would have forked, we will now create a new process. */ + /* I have added a set of command line switches to specify a list of */ + /* handles that the child should close since they shouldn't have */ + /* been inherited ("-i#"), and a single switch to specify the handle */ + /* for the server_sock ("I#"). */ + + /* A better alternative would be to re-write NetPerf to be */ + /* multi-threaded; i.e., move all of the various NetPerf global */ + /* variables in to thread specific structures. But this is a bigger */ + /* effort than I want to tackle at this time. (And I doubt that the */ + /* HP-UX author sees value in this effort). */ + +#endif + +int _cdecl +main(int argc, char *argv[]) +{ + + int c; + int not_inetd = 0; +#ifdef WIN32 + BOOL child = FALSE; +#endif + char arg1[BUFSIZ], arg2[BUFSIZ]; +#ifndef PATH_MAX +#define PATH_MAX MAX_PATH +#endif + char FileName[PATH_MAX]; /* for opening the debug log file */ + + struct sockaddr name; + netperf_socklen_t namelen = sizeof(name); + + +#ifdef WIN32 + WSADATA wsa_data ; + + /* Initialize the winsock lib ( version 2.2 ) */ + if ( WSAStartup(MAKEWORD(2,2), &wsa_data) == SOCKET_ERROR ){ + printf("WSAStartup() failed : %lu\n", GetLastError()) ; + return 1 ; + } +#endif /* WIN32 */ + + /* Save away the program name */ + program = (char *)malloc(strlen(argv[0]) + 1); + if (program == NULL) { + printf("malloc(%d) failed!\n", strlen(argv[0]) + 1); + return 1 ; + } + strcpy(program, argv[0]); + + netlib_init(); + + /* Scan the command line to see if we are supposed to set-up our own */ + /* listen socket instead of relying on inetd. */ + + /* first set a copy of initial values */ + strncpy(local_host_name,"0.0.0.0",sizeof(local_host_name)); + local_address_family = AF_UNSPEC; + strncpy(listen_port,TEST_PORT,sizeof(listen_port)); + + while ((c = getopt(argc, argv, SERVER_ARGS)) != EOF) { + switch (c) { + case '?': + case 'h': + print_netserver_usage(); + exit(1); + case 'd': + /* we want to set the debug file name sometime */ + debug++; +#ifdef MSDOS + dbug_init(); +#endif + break; + case 'L': + not_inetd = 1; + break_args_explicit(optarg,arg1,arg2); + if (arg1[0]) { + strncpy(local_host_name,arg1,sizeof(local_host_name)); + } + if (arg2[0]) { + local_address_family = parse_address_family(arg2); + /* if only the address family was set, we may need to set the + local_host_name accordingly. since our defaults are IPv4 + this should only be necessary if we have IPv6 support raj + 2005-02-07 */ +#if defined (AF_INET6) + if (!arg1[0]) { + strncpy(local_host_name,"::0",sizeof(local_host_name)); + } +#endif + } + break; + case 'n': + shell_num_cpus = atoi(optarg); + if (shell_num_cpus > MAXCPUS) { + fprintf(stderr, + "netserver: This version can only support %d CPUs. Please", + MAXCPUS); + fprintf(stderr, + " increase MAXCPUS in netlib.h and recompile.\n"); + fflush(stderr); + exit(1); + } + break; + case 'p': + /* we want to open a listen socket at a */ + /* specified port number */ + strncpy(listen_port,optarg,sizeof(listen_port)); + not_inetd = 1; + break; + case '4': + local_address_family = AF_INET; + break; + case '6': +#if defined(AF_INET6) + local_address_family = AF_INET6; + strncpy(local_host_name,"::0",sizeof(local_host_name)); +#else + local_address_family = AF_UNSPEC; +#endif + break; + case 'v': + /* say how much to say */ + verbosity = atoi(optarg); + break; + case 'V': + printf("Netperf version %s\n",NETPERF_VERSION); + exit(0); + break; +#ifdef WIN32 +/*+*+SAF */ + case 'I': + child = TRUE; + /* This is the handle we expect to inherit. */ + /*+*+SAF server_sock = (HANDLE)atoi(optarg); */ + break; + case 'i': + /* This is a handle we should NOT inherit. */ + /*+*+SAF CloseHandle((HANDLE)atoi(optarg)); */ + break; +#endif + + } + } + + /* +*+SAF I need a better way to find inherited handles I should close! */ + /* +*+SAF Use DuplicateHandle to force inheritable attribute (or reset it)? */ + +/* unlink(DEBUG_LOG_FILE); */ + + strcpy(FileName, DEBUG_LOG_FILE); + +#ifndef WIN32 + snprintf(&FileName[strlen(FileName)], sizeof(FileName) - strlen(FileName), "_%d", getpid()); + if ((where = fopen(FileName, "w")) == NULL) { + perror("netserver: debug file"); + exit(1); + } +#else + { + + if (child) { + snprintf(&FileName[strlen(FileName)], sizeof(FileName) - strlen(FileName), "_%x", getpid()); + } + + /* Hopefully, by closing stdout & stderr, the subsequent + fopen calls will get mapped to the correct std handles. */ + fclose(stdout); + + if ((where = fopen(FileName, "w")) == NULL) { + perror("netserver: fopen of debug file as new stdout failed!"); + exit(1); + } + + fclose(stderr); + + if ((where = fopen(FileName, "w")) == NULL) { + fprintf(stdout, "fopen of debug file as new stderr failed!\n"); + exit(1); + } + } +#endif + +#ifndef WIN32 + chmod(DEBUG_LOG_FILE,0644); +#endif + +#if WIN32 + if (child) { + server_sock = (SOCKET)GetStdHandle(STD_INPUT_HANDLE); + } +#endif + + /* if we are not a child of an inetd or the like, then we should + open a socket and hang listens off of it. otherwise, we should go + straight into processing requests. the do_listen() routine will sit + in an infinite loop accepting connections and forking child + processes. the child processes will call process_requests */ + + /* If fd 0 is not a socket then assume we're not being called */ + /* from inetd and start server socket on the default port. */ + /* this enhancement comes from vwelch@ncsa.uiuc.edu (Von Welch) */ + if (not_inetd) { + /* the user specified a port number on the command line */ + set_up_server(local_host_name,listen_port,local_address_family); + } +#ifdef WIN32 + /* OK, with Win2003 WinNT's POSIX subsystem is gone, and hence so is */ + /* fork. But hopefully the kernel support will continue to exist */ + /* for some time. We are not counting on the address space */ + /* copy_on_write support, since it isn't exposed except through the */ + /* NT native APIs (which are not public). We will try to use the */ + /* InheritHandles flag in CreateProcess though since this is public */ + /* and is used for more than just POSIX so hopefully it won't go */ + /* away. */ + else if (TRUE) { + if (child) { + process_requests(); + } else { + strncpy(listen_port,TEST_PORT,sizeof(listen_port)); + set_up_server(local_host_name,listen_port,local_address_family); + } + } +#endif +#if !defined(__VMS) + else if (getsockname(0, &name, &namelen) == SOCKET_ERROR) { + /* we may not be a child of inetd */ + if (errno == ENOTSOCK) { + strncpy(listen_port,TEST_PORT,sizeof(listen_port)); + set_up_server(local_host_name,listen_port,local_address_family); + } + } +#endif /* !defined(__VMS) */ + else { + /* we are probably a child of inetd, or are being invoked via the + VMS auxilliarly server mechanism */ +#if !defined(__VMS) + server_sock = 0; +#else + if ( (server_sock = socket(TCPIP$C_AUXS, SOCK_STREAM, 0)) == INVALID_SOCKET ) + { + perror("Failed to grab aux server socket" ); + exit(1); + } + +#endif /* !defined(__VMS) */ + process_requests(); + } +#ifdef WIN32 + /* Cleanup the winsock lib */ + WSACleanup(); +#endif + + return(0); +} diff --git a/src/netsh.c b/src/netsh.c new file mode 100644 index 0000000..f11ba7e --- /dev/null +++ b/src/netsh.c @@ -0,0 +1,1160 @@ +#include "netperf_version.h" + +char netsh_id[]="\ +@(#)netsh.c (c) Copyright 1993-2007 Hewlett-Packard Company. Version 2.4.3pre"; + + +/****************************************************************/ +/* */ +/* Global include files */ +/* */ +/****************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#ifndef WIN32 +#include +#if !defined(__VMS) && !defined(MSDOS) +#include +#endif /* __VMS/MSDOS */ +#endif /* WIN32 */ +#include +#ifndef WIN32 +#include +#include +#endif /* !WIN32 */ +#include +#include +#include + /* the following four includes should not be needed ?*/ +#ifndef WIN32 +#include +#include +#include +#include +#include +#else +#include +#include +#define netperf_socklen_t socklen_t +#endif + +#ifndef STRINGS +#include +#else /* STRINGS */ +#include +#endif /* STRINGS */ + +#ifdef WIN32 +extern int getopt(int , char **, char *) ; +#else +double atof(const char *); +#endif /* WIN32 */ + +/**********************************************************************/ +/* */ +/* Local Include Files */ +/* */ +/**********************************************************************/ + +#define NETSH +#include "netsh.h" +#include "netlib.h" +#include "nettest_bsd.h" + +#ifdef WANT_UNIX +#include "nettest_unix.h" +#ifndef WIN32 +#include "sys/socket.h" +#endif /* !WIN32 */ +#endif /* WANT_UNIX */ + +#ifdef WANT_XTI +#include "nettest_xti.h" +#endif /* WANT_XTI */ + +#ifdef WANT_DLPI +#include "nettest_dlpi.h" +#endif /* WANT_DLPI */ + +#ifdef WANT_SCTP +#include "nettest_sctp.h" +#endif + + +/************************************************************************/ +/* */ +/* Global constants and macros */ +/* */ +/************************************************************************/ + + /* Some of the args take optional parameters. Since we are using */ + /* getopt to parse the command line, we will tell getopt that they do */ + /* not take parms, and then look for them ourselves */ +#define GLOBAL_CMD_LINE_ARGS "A:a:b:B:CcdDf:F:H:hi:I:k:K:l:L:n:NO:o:P:p:rt:T:v:VW:w:46" + +/************************************************************************/ +/* */ +/* Extern variables */ +/* */ +/************************************************************************/ + +/* +extern int errno; +extern char *sys_errlist[ ]; +extern int sys_nerr; +*/ + +/************************************************************************/ +/* */ +/* Global variables */ +/* */ +/************************************************************************/ + +/* some names and such */ +char *program; /* program invocation name */ +char *command_line; /* a copy of the entire command line */ +char username[BUFSIZ]; /* login name of user */ +char cmd_file[BUFSIZ]; /* name of the commands file */ + +/* stuff to say where this test is going */ +char host_name[HOSTNAMESIZE]; /* remote host name or ip addr */ +char local_host_name[HOSTNAMESIZE]; /* local hostname or ip */ +char test_name[BUFSIZ]; /* which test to run */ +char test_port[PORTBUFSIZE]; /* where is the test waiting */ +char local_test_port[PORTBUFSIZE]; /* from whence we should start */ +int address_family; /* which address family remote */ +int local_address_family; /* which address family local */ + +/* the source of data for filling the buffers */ +char fill_file[BUFSIZ]; + +/* output controlling variables */ +int + debug, /* debugging level */ + print_headers, /* do/don't display headers */ + verbosity; /* verbosity level */ + +/* When specified with -B, this will be displayed at the end of the line + for output that does not include the test header. mostly this is + to help identify a specific netperf result when concurrent netperfs + are run. raj 2006-02-01 */ +char *result_brand = NULL; + +/* cpu variables */ +int + local_cpu_usage, /* you guessed it */ + remote_cpu_usage; /* still right ! */ + +float + local_cpu_rate, + remote_cpu_rate; + +int + shell_num_cpus=1; + +/* the end-test conditions for the tests - either transactions, bytes, */ +/* or time. different vars used for clarity - space is cheap ;-) */ +int + test_time, /* test ends by time */ + test_len_ticks, /* how many times will the timer go off before */ + /* the test is over? */ + test_bytes, /* test ends on byte count */ + test_trans; /* test ends on tran count */ + +/* the alignment conditions for the tests */ +int + local_recv_align, /* alignment for local receives */ + local_send_align, /* alignment for local sends */ + local_send_offset = 0, + local_recv_offset = 0, + remote_recv_align, /* alignment for remote receives */ + remote_send_align, /* alignment for remote sends */ + remote_send_offset = 0, + remote_recv_offset = 0, + remote_send_width = 0, + remote_recv_width = 0; + +/* hoist above the if for omni */ +int + interval_usecs, + interval_wate, + interval_burst, + remote_interval_usecs, + remote_interval_burst; + +#if defined(WANT_INTERVALS) || defined(WANT_DEMO) + +int demo_mode; /* are we actually in demo mode? */ +double demo_interval = 1000000.0; /* what is the desired interval to + display interval results. default + is one second in units of + microseconds */ +double demo_units = 0.0; /* what is our current best guess as + to how many work units must be + done to be near the desired + reporting interval? */ + +double units_this_tick; +#endif + +int loc_dirty_count; +int loc_clean_count; +int rem_dirty_count; +int rem_clean_count; + + /* some of the vairables for confidence intervals... */ + +int confidence_level; +int iteration_min; +int iteration_max; +int result_confidence_only = 0; + +double interval; + + /* stuff to control the "width" of the buffer rings for sending and */ + /* receiving data */ +int send_width; +int recv_width; + +/* address family */ +int af = AF_INET; + +/* did someone request processor affinity? */ +int cpu_binding_requested = 0; + +/* are we not establishing a control connection? */ +int no_control = 0; + +char netserver_usage[] = "\n\ +Usage: netserver [options] \n\ +\n\ +Options:\n\ + -h Display this text\n\ + -d Increase debugging output\n\ + -L name,family Use name to pick listen address and family for family\n\ + -p portnum Listen for connect requests on portnum.\n\ + -4 Do IPv4\n\ + -6 Do IPv6\n\ + -v verbosity Specify the verbosity level\n\ + -V Display version information and exit\n\ +\n"; + +/* netperf_usage done as two concatenated strings to make the MS + compiler happy when compiling for x86_32. fix from Spencer + Frink. */ + +char netperf_usage1[] = "\n\ +Usage: netperf [global options] -- [test options] \n\ +\n\ +Global options:\n\ + -a send,recv Set the local send,recv buffer alignment\n\ + -A send,recv Set the remote send,recv buffer alignment\n\ + -B brandstr Specify a string to be emitted with brief output\n\ + -c [cpu_rate] Report local CPU usage\n\ + -C [cpu_rate] Report remote CPU usage\n\ + -d Increase debugging output\n\ + -D [secs,units] * Display interim results at least every secs seconds\n\ + using units as the initial guess for units per second\n\ + -f G|M|K|g|m|k Set the output units\n\ + -F fill_file Pre-fill buffers with data from fill_file\n\ + -h Display this text\n\ + -H name|ip,fam * Specify the target machine and/or local ip and family\n\ + -i max,min Specify the max and min number of iterations (15,1)\n\ + -I lvl[,intvl] Specify confidence level (95 or 99) (99) \n\ + and confidence interval in percentage (10)\n\ + -l testlen Specify test duration (>0 secs) (<0 bytes|trans)\n\ + -L name|ip,fam * Specify the local ip|name and address family\n\ + -o send,recv Set the local send,recv buffer offsets\n\ + -O send,recv Set the remote send,recv buffer offset\n\ + -n numcpu Set the number of processors for CPU util\n\ + -N Establish no control connection, do 'send' side only\n\ + -p port,lport* Specify netserver port number and/or local port\n\ + -P 0|1 Don't/Do display test headers\n\ + -r Allow confidence to be hit on result only\n\ + -t testname Specify test to perform\n\ + -T lcpu,rcpu Request netperf/netserver be bound to local/remote cpu\n\ + -v verbosity Specify the verbosity level\n\ + -W send,recv Set the number of send,recv buffers\n\ + -v level Set the verbosity level (default 1, min 0)\n\ + -V Display the netperf version and exit\n"; + +char netperf_usage2[] = "\n\ +For those options taking two parms, at least one must be specified;\n\ +specifying one value without a comma will set both parms to that\n\ +value, specifying a value with a leading comma will set just the second\n\ +parm, a value with a trailing comma will set just the first. To set\n\ +each parm to unique values, specify both and separate them with a\n\ +comma.\n\ +\n" +"* For these options taking two parms, specifying one value with no comma\n\ +will only set the first parms and will leave the second at the default\n\ +value. To set the second value it must be preceded with a comma or be a\n\ +comma-separated pair. This is to retain previous netperf behaviour.\n"; + + +/* This routine will return the two arguments to the calling routine. */ +/* If the second argument is not specified, and there is no comma, */ +/* then the value of the second argument will be the same as the */ +/* value of the first. If there is a comma, then the value of the */ +/* second argument will be the value of the second argument ;-) */ +void +break_args(char *s, char *arg1, char *arg2) + +{ + char *ns; + ns = strchr(s,','); + if (ns) { + /* there was a comma arg2 should be the second arg*/ + *ns++ = '\0'; + while ((*arg2++ = *ns++) != '\0'); + } + else { + /* there was not a comma, we can use ns as a temp s */ + /* and arg2 should be the same value as arg1 */ + ns = s; + while ((*arg2++ = *ns++) != '\0'); + }; + while ((*arg1++ = *s++) != '\0'); +} + +/* break_args_explicit + + this routine is somewhat like break_args in that it will separate a + pair of comma-separated values. however, if there is no comma, + this version will not ass-u-me that arg2 should be the same as + arg1. raj 2005-02-04 */ +void +break_args_explicit(char *s, char *arg1, char *arg2) + +{ + char *ns; + ns = strchr(s,','); + if (ns) { + /* there was a comma arg2 should be the second arg*/ + *ns++ = '\0'; + while ((*arg2++ = *ns++) != '\0'); + } + else { + /* there was not a comma, so we should make sure that arg2 is \0 + lest something become confused. raj 2005-02-04 */ + *arg2 = '\0'; + }; + while ((*arg1++ = *s++) != '\0'); + +} + +/* given a string with possible values for setting an address family, + convert that into one of the AF_mumble values - AF_INET, AF_INET6, + AF_UNSPEC as apropriate. the family_string is compared in a + case-insensitive manner */ + +int +parse_address_family(char family_string[]) +{ + + char temp[10]; /* gotta love magic constants :) */ + + strncpy(temp,family_string,10); + + if (debug) { + fprintf(where, + "Attempting to parse address family from %s derived from %s\n", + temp, + family_string); + } +#if defined(AF_INET6) + if (strstr(temp,"6")) { + return(AF_INET6); + } +#endif + if (strstr(temp,"inet") || + strstr(temp,"4")) { + return(AF_INET); + } + if (strstr(temp,"unspec") || + strstr(temp,"0")) { + return(AF_UNSPEC); + } + fprintf(where, + "WARNING! %s not recognized as an address family, using AF_UNPSEC\n", + family_string); + fprintf(where, + "Are you sure netperf was configured for that address family?\n"); + fflush(where); + return(AF_UNSPEC); +} + +int +parse_socket_type(char socket_string[]) { + + char temp[10]; + + strncpy(temp,socket_string,10); + + if (debug) { + fprintf(where, + "Attempting to parse socket type from %s derived from %s\n", + temp, + socket_string); + } + +#ifdef SOCK_STREAM + if (strstr(temp,"stream")) + return SOCK_STREAM; +#endif +#ifdef SOCK_DGRAM + if (strstr(temp,"dgram")) + return SOCK_DGRAM; +#endif + return NST_UNKN; + +} + +int +parse_protocol(char protocol_string[]) +{ + char temp[10]; + + strncpy(temp,protocol_string,10); + + if (debug) { + fprintf(where, + "Attempting to parse protocol from %s derived from %s\n", + temp, + protocol_string); + } + +#ifdef IPPROTO_TCP + if (!strcasecmp(temp,"tcp")){ + socket_type = SOCK_STREAM; + return IPPROTO_TCP; + } +#endif +#ifdef IPPROTO_UDP + if (!strcasecmp(temp,"udp")) { + socket_type = SOCK_DGRAM; + return IPPROTO_UDP; + } +#endif +#ifdef IPPROTO_SCTP + if (!strcasecmp(temp,"sctp")) { + /* it can be more than one socket type */ + return IPPROTO_SCTP; + } +#endif +#ifdef IPPROTO_SDP + if (!strcasecmp(temp,"sdp")) { + socket_type = SOCK_STREAM; + return IPPROTO_SDP; + } +#endif +#ifdef IPPROTO_DCCP + if (!strcasecmp(temp,"dccp")) { + socket_type = SOCK_DCCP; + return IPPROTO_DCCP; + } +#endif + return IPPROTO_IP; +} + + +void +set_defaults() +{ + + /* stuff to say where this test is going */ + strcpy(host_name,""); /* remote host name or ip addr */ + strcpy(local_host_name,""); /* we want it to be INADDR_ANY */ + strcpy(test_name,"TCP_STREAM"); /* which test to run */ + strncpy(test_port,"12865",PORTBUFSIZE); /* where is the test waiting */ + strncpy(local_test_port,"0",PORTBUFSIZE);/* INPORT_ANY as it were */ + address_family = AF_UNSPEC; + local_address_family = AF_UNSPEC; + + /* output controlling variables */ + debug = 0;/* debugging level */ + print_headers = 1;/* do print test headers */ + verbosity = 1;/* verbosity level */ + /* cpu variables */ + local_cpu_usage = 0;/* measure local cpu */ + remote_cpu_usage = 0;/* what do you think ;-) */ + + local_cpu_rate = (float)0.0; + remote_cpu_rate = (float)0.0; + + /* the end-test conditions for the tests - either transactions, bytes, */ + /* or time. different vars used for clarity - space is cheap ;-) */ + test_time = 10; /* test ends by time */ + test_bytes = 0; /* test ends on byte count */ + test_trans = 0; /* test ends on tran count */ + + /* the alignment conditions for the tests */ + local_recv_align = 8; /* alignment for local receives */ + local_send_align = 8; /* alignment for local sends */ + remote_recv_align = 8; /* alignment for remote receives*/ + remote_send_align = 8; /* alignment for remote sends */ + + /* rate controlling stuff, taken out of the #ifdef for omni */ + interval_usecs = 0; + interval_wate = 0; + interval_burst = 0; + remote_interval_usecs = 0; + remote_interval_burst = 0; + +#ifdef DIRTY + /* dirty and clean cache stuff */ + loc_dirty_count = 0; + loc_clean_count = 0; + rem_dirty_count = 0; + rem_clean_count = 0; +#else + loc_dirty_count = -1; + loc_clean_count = -1; + rem_dirty_count = -1; + rem_clean_count = -1; +#endif /* DIRTY */ + + /* some of the vairables for confidence intervals... defaults will be + set as apropriate in the parsing of the command line */ + + confidence_level = 0; + iteration_min = 1; + iteration_max = 1; + interval = 0.0; + + no_control = 0; + strcpy(fill_file,""); +} + + +void +print_netserver_usage() +{ + fwrite(netserver_usage, sizeof(char), strlen(netserver_usage), stderr); +} + + +void +print_netperf_usage() +{ + fwrite(netperf_usage1, sizeof(char), strlen(netperf_usage1), stderr); + fwrite(netperf_usage2, sizeof(char), strlen(netperf_usage2), stderr); +} + +void +scan_cmd_line(int argc, char *argv[]) +{ + extern int optind; /* index of first unused arg */ + extern char *optarg; /* pointer to option string */ + + int cmnd_len; + char *p; + + int c; + + char arg1[BUFSIZ], /* argument holders */ + arg2[BUFSIZ]; + + program = (char *)malloc(strlen(argv[0]) + 1); + if (program == NULL) { + printf("malloc(%d) failed!\n", strlen(argv[0]) + 1); + exit(1); + } + strcpy(program, argv[0]); + + /* brute force, but effective */ + command_line = NULL; + cmnd_len = 0; + for (c = 0; c < argc; c++) { + cmnd_len += strlen(argv[c]); + } + cmnd_len += argc; /* forget thee not the spaces */ + command_line = malloc(cmnd_len+1); + + if (command_line == NULL) { + printf("malloc(%d) failed!\n",cmnd_len); + exit(-1); + } + p = command_line; + for (c = 0; c < argc; c++) { + memcpy(p,argv[c],strlen(argv[c])); + p += strlen(argv[c]); + *p = ' '; + p += 1; + } + *--p = 0; + + /* Go through all the command line arguments and break them */ + /* out. For those options that take two parms, specifying only */ + /* the first will set both to that value. Specifying only the */ + /* second will leave the first untouched. To change only the */ + /* first, use the form first, (see the routine break_args.. */ + + while ((c= getopt(argc, argv, GLOBAL_CMD_LINE_ARGS)) != EOF) { + switch (c) { + case '?': + case 'h': + print_netperf_usage(); + exit(1); + case 'a': + /* set local alignments */ + break_args(optarg,arg1,arg2); + if (arg1[0]) { + local_send_align = convert(arg1); + } + if (arg2[0]) + local_recv_align = convert(arg2); + break; + case 'A': + /* set remote alignments */ + break_args(optarg,arg1,arg2); + if (arg1[0]) { + remote_send_align = convert(arg1); + } + if (arg2[0]) + remote_recv_align = convert(arg2); + break; + case 'c': + /* measure local cpu usage please. the user */ + /* may have specified the cpu rate as an */ + /* optional parm */ + if (argv[optind] && isdigit((unsigned char)argv[optind][0])){ + /* there was an optional parm */ + local_cpu_rate = (float)atof(argv[optind]); + optind++; + } + local_cpu_usage++; + break; + case 'C': + /* measure remote cpu usage please */ + if (argv[optind] && isdigit((unsigned char)argv[optind][0])){ + /* there was an optional parm */ + remote_cpu_rate = (float)atof(argv[optind]); + optind++; + } + remote_cpu_usage++; + break; + case 'd': + debug++; +#ifdef MSDOS + dbug_init(); +#endif + break; + case 'D': +#if (defined WANT_DEMO) + demo_mode++; + if (argv[optind] && isdigit((unsigned char)argv[optind][0])){ + /* there was an optional parm */ + break_args_explicit(argv[optind],arg1,arg2); + optind++; + if (arg1[0]) { + demo_interval = atof(arg1) * 1000000.0; + } + if (arg2[0]) { + demo_units = convert(arg2); + } + } +#else + printf("Sorry, Demo Mode not configured into this netperf.\n"); + printf("please consider reconfiguring netperf with\n"); + printf("--enable-demo=yes and recompiling\n"); +#endif + break; + case 'f': + /* set the thruput formatting */ + libfmt = *optarg; + break; + case 'F': + /* set the fill_file variable for pre-filling buffers */ + strcpy(fill_file,optarg); + break; + case 'i': + /* set the iterations min and max for confidence intervals */ + break_args(optarg,arg1,arg2); + if (arg1[0]) { + iteration_max = convert(arg1); + } + if (arg2[0] ) { + iteration_min = convert(arg2); + } + /* if the iteration_max is < iteration_min make iteration_max + equal iteration_min */ + if (iteration_max < iteration_min) iteration_max = iteration_min; + /* limit minimum to 3 iterations */ + if (iteration_max < 3) iteration_max = 3; + if (iteration_min < 3) iteration_min = 3; + /* limit maximum to 30 iterations */ + if (iteration_max > 30) iteration_max = 30; + if (iteration_min > 30) iteration_min = 30; + if (confidence_level == 0) confidence_level = 99; + if (interval == 0.0) interval = 0.05; /* five percent */ + break; + case 'I': + /* set the confidence level (95 or 99) and width */ + break_args(optarg,arg1,arg2); + if (arg1[0]) { + confidence_level = convert(arg1); + } + if((confidence_level != 95) && (confidence_level != 99)){ + printf("Only 95%% and 99%% confidence level is supported\n"); + exit(1); + } + if (arg2[0] ) { + /* it doesn't make much sense to use convert() here so just + use strtod() instead. raj 2007-10-24 */ + interval = strtod(arg2,NULL)/100.0; + } + /* make sure that iteration_min and iteration_max are at least + at a reasonable default value. if a -i option has previously + been parsed, these will no longer be 1, so we can check + against 1 */ + if (iteration_min == 1) iteration_min = 3; + if (iteration_max == 1) iteration_max = 10; + /* make sure that the interval is set if it isn't at its default + value */ + if (interval == 0.0) interval = 0.05; /* five percent */ + break; + case 'k': + /* local dirty and clean counts */ +#ifdef DIRTY + break_args(optarg,arg1,arg2); + if (arg1[0]) { + loc_dirty_count = convert(arg1); + } + if (arg2[0] ) { + loc_clean_count = convert(arg2); + } +#else + printf("I don't know how to get dirty.\n"); +#endif /* DIRTY */ + break; + case 'K': + /* remote dirty and clean counts */ +#ifdef DIRTY + break_args(optarg,arg1,arg2); + if (arg1[0]) { + rem_dirty_count = convert(arg1); + } + if (arg2[0] ) { + rem_clean_count = convert(arg2); + } +#else + printf("I don't know how to get dirty.\n"); +#endif /* DIRTY */ + break; + case 'n': + shell_num_cpus = atoi(optarg); + break; + case 'N': + no_control = 1; + break; + case 'o': + /* set the local offsets */ + break_args(optarg,arg1,arg2); + if (arg1[0]) + local_send_offset = convert(arg1); + if (arg2[0]) + local_recv_offset = convert(arg2); + break; + case 'O': + /* set the remote offsets */ + break_args(optarg,arg1,arg2); + if (arg1[0]) + remote_send_offset = convert(arg1); + if (arg2[0]) + remote_recv_offset = convert(arg2); + break; + case 'P': + /* to print or not to print, that is */ + /* the header question */ + print_headers = convert(optarg); + break; + case 'r': + /* the user wishes that we declare confidence when hit on the + result even if not yet reached on CPU utilization. only + meaningful if cpu util is enabled */ + result_confidence_only = 1; + break; + case 't': + /* set the test name */ + strcpy(test_name,optarg); + break; + case 'T': + /* We want to set the processor on which netserver or netperf */ + /* will run */ + break_args(optarg,arg1,arg2); + if (arg1[0]) { + local_proc_affinity = convert(arg1); + bind_to_specific_processor(local_proc_affinity,0); + } + if (arg2[0]) { + remote_proc_affinity = convert(arg2); + } + cpu_binding_requested = 1; + break; + case 'W': + /* set the "width" of the user space data buffer ring. This will */ + /* be the number of send_size buffers malloc'd in the tests */ + break_args(optarg,arg1,arg2); + if (arg1[0]) + send_width = convert(arg1); + if (arg2[0]) + recv_width = convert(arg2); + break; + case 'l': + /* determine test end conditions */ + /* assume a timed test */ + test_time = convert(optarg); + test_bytes = test_trans = 0; + if (test_time < 0) { + test_bytes = -1 * test_time; + test_trans = test_bytes; + test_time = 0; + } + break; + case 'v': + /* say how much to say */ + verbosity = convert(optarg); + break; + case 'p': + /* specify an alternate port number we use break_args_explicit + here to maintain backwards compatibility with previous + generations of netperf where having a single value did not + set both remote _and_ local port number. raj 2005-02-04 */ + break_args_explicit(optarg,arg1,arg2); + if (arg1[0]) + strncpy(test_port,arg1,PORTBUFSIZE); + if (arg2[0]) + strncpy(local_test_port,arg2,PORTBUFSIZE); + break; + case 'H': + /* save-off the host identifying information, use + break_args_explicit since passing just one value should not + set both */ + break_args_explicit(optarg,arg1,arg2); + if (arg1[0]) + strncpy(host_name,arg1,sizeof(host_name)); + if (arg2[0]) + address_family = parse_address_family(arg2); + break; + case 'L': + /* save-off the local control socket addressing information. use + break_args_explicit since passing just one value should not + set both */ + break_args_explicit(optarg,arg1,arg2); + if (arg1[0]) + strncpy(local_host_name,arg1,sizeof(local_host_name)); + if (arg2[0]) + local_address_family = parse_address_family(arg2); + break; + case 'w': + /* We want to send requests at a certain wate. Remember that + there are 1000000 usecs in a second, and that the packet rate is + expressed in packets per millisecond. shuffle the #ifdef around + a bit to deal with both netperf and netserver possibly doing + intervals with omni tests */ + break_args_explicit(optarg,arg1,arg2); + if (arg1[0]) { +#ifdef WANT_INTERVALS + interval_usecs = convert_timespec(arg1); + interval_wate = interval_usecs / 1000; +#else + fprintf(where, + "Packet rate control is not compiled in.\n"); +#endif + } + if (arg2[0]) { + /* we pass usecs to the remote and let it deal to cover both + intervals and spin methods. if he wasn't intervals enabled + he will return a suitable value back to us */ + remote_interval_usecs = convert_timespec(arg2); + } + break; + case 'b': + /* we want to have a burst so many packets per */ + /* interval. */ + break_args_explicit(optarg,arg1,arg2); + if (arg1[0]) { +#ifdef WANT_INTERVALS + interval_burst = convert(arg1); + /* set a default in case the user does not include the -w option */ + if (interval_usecs == 0) { + interval_wate = 1; + interval_usecs = 1000; + } +#else + fprintf(where, + "Packet burst size is not compiled in. \n"); +#endif /* WANT_INTERVALS */ + } + /* there is no ifdef here because we are sending this value to + the remote, which may or may not have been compiled for + intervals and we don't have a way of knowing on this side + until we try */ + if (arg2[0]) { + remote_interval_burst = convert(arg2); + if (remote_interval_usecs == 0) { + remote_interval_usecs = 1000; + } + } + break; + case 'B': + result_brand = malloc(strlen(optarg)+1); + if (NULL != result_brand) { + strcpy(result_brand,optarg); + } + else { + fprintf(where, + "Unable to malloc space for result brand\n"); + } + break; + case '4': + address_family = AF_INET; + local_address_family = AF_INET; + break; + case '6': +#if defined(AF_INET6) + address_family = AF_INET6; + local_address_family = AF_INET6; +#else + printf("This netperf was not compiled on an IPv6 capable system!\n"); + exit(-1); +#endif + break; + case 'V': + printf("Netperf version %s\n",NETPERF_VERSION); + exit(0); + break; + }; + } + /* ok, what should our default hostname and local binding info be? + */ + if ('\0' == host_name[0]) { + /* host_name was not set */ + switch (address_family) { + case AF_INET: + strcpy(host_name,"localhost"); + break; + case AF_UNSPEC: + /* what to do here? case it off the local_address_family I + suppose */ + switch (local_address_family) { + case AF_INET: + case AF_UNSPEC: + strcpy(host_name,"localhost"); + break; +#if defined(AF_INET6) + case AF_INET6: + strcpy(host_name,"::1"); + break; +#endif + default: + printf("Netperf does not understand %d as an address family\n", + address_family); + exit(-1); + } + break; +#if defined(AF_INET6) + case AF_INET6: + strcpy(host_name,"::1"); + break; +#endif + default: + printf("Netperf does not understand %d as an address family\n", + address_family); + exit(-1); + } + } + + /* now, having established the name to which the control will + connect, from what should it come? */ + if ('\0' == local_host_name[0]) { + switch (local_address_family) { + case AF_INET: + strcpy(local_host_name,"0.0.0.0"); + break; + case AF_UNSPEC: + switch (address_family) { + case AF_INET: + case AF_UNSPEC: + strcpy(local_host_name,"0.0.0.0"); + break; +#if defined(AF_INET6) + case AF_INET6: + strcpy(local_host_name,"::0"); + break; +#endif + default: + printf("Netperf does not understand %d as an address family\n", + address_family); + exit(-1); + } + break; +#if defined(AF_INET6) + case AF_INET6: + strcpy(local_host_name,"::0"); + break; +#endif + default: + printf("Netperf does not understand %d as an address family\n", + address_family); + exit(-1); + } + } + + /* so, if we aren't even going to establish a control connection we + should set certain "remote" settings to reflect this, regardless + of what else may have been set on the command line */ + if (no_control) { + remote_recv_align = -1; + remote_send_align = -1; + remote_send_offset = -1; + remote_recv_offset = -1; + remote_cpu_rate = (float)-1.0; + remote_cpu_usage = 0; + } + + /* parsing test-specific options used to be conditional on there + being a "--" in the option stream. however, some of the tests + have other initialization happening in their "scan" routines so we + want to call them regardless. raj 2005-02-08 */ + if ((strcasecmp(test_name,"TCP_STREAM") == 0) || +#ifdef HAVE_ICSC_EXS + (strcasecmp(test_name,"EXS_TCP_STREAM") == 0) || +#endif /* HAVE_ICSC_EXS */ +#ifdef HAVE_SENDFILE + (strcasecmp(test_name,"TCP_SENDFILE") == 0) || +#endif /* HAVE_SENDFILE */ + (strcasecmp(test_name,"TCP_MAERTS") == 0) || + (strcasecmp(test_name,"TCP_RR") == 0) || + (strcasecmp(test_name,"TCP_CRR") == 0) || + (strcasecmp(test_name,"TCP_CC") == 0) || + (strcasecmp(test_name,"TCP_MSS") == 0) || +#ifdef DO_1644 + (strcasecmp(test_name,"TCP_TRR") == 0) || +#endif /* DO_1644 */ +#ifdef DO_NBRR + (strcasecmp(test_name,"TCP_TRR") == 0) || +#endif /* DO_NBRR */ + (strcasecmp(test_name,"UDP_STREAM") == 0) || + (strcasecmp(test_name,"UDP_RR") == 0)) + { + scan_sockets_args(argc, argv); + } + +#ifdef WANT_DLPI + else if ((strcasecmp(test_name,"DLCO_RR") == 0) || + (strcasecmp(test_name,"DLCL_RR") == 0) || + (strcasecmp(test_name,"DLCO_STREAM") == 0) || + (strcasecmp(test_name,"DLCL_STREAM") == 0)) + { + scan_dlpi_args(argc, argv); + } +#endif /* WANT_DLPI */ + +#ifdef WANT_UNIX + else if ((strcasecmp(test_name,"STREAM_RR") == 0) || + (strcasecmp(test_name,"DG_RR") == 0) || + (strcasecmp(test_name,"STREAM_STREAM") == 0) || + (strcasecmp(test_name,"DG_STREAM") == 0)) + { + scan_unix_args(argc, argv); + } +#endif /* WANT_UNIX */ + +#ifdef WANT_XTI + else if ((strcasecmp(test_name,"XTI_TCP_RR") == 0) || + (strcasecmp(test_name,"XTI_TCP_STREAM") == 0) || + (strcasecmp(test_name,"XTI_UDP_RR") == 0) || + (strcasecmp(test_name,"XTI_UDP_STREAM") == 0)) + { + scan_xti_args(argc, argv); + } +#endif /* WANT_XTI */ + +#ifdef WANT_SCTP + else if ((strcasecmp(test_name,"SCTP_STREAM") == 0) || + (strcasecmp(test_name,"SCTP_RR") == 0) || + (strcasecmp(test_name,"SCTP_STREAM_MANY") == 0) || + (strcasecmp(test_name,"SCTP_RR_MANY") == 0)) + { + scan_sctp_args(argc, argv); + } +#endif + +#ifdef WANT_SDP + else if((strcasecmp(test_name,"SDP_STREAM") == 0) || + (strcasecmp(test_name,"SDP_MAERTS") == 0) || + (strcasecmp(test_name,"SDP_RR") == 0)) + { + scan_sdp_args(argc, argv); + } +#endif + +#ifdef WANT_OMNI + else if ((strcasecmp(test_name,"OMNI") == 0) || + (strcasecmp(test_name,"UUID") == 0)) { + scan_omni_args(argc, argv); + } +#endif + + /* what is our default value for the output units? if the test + name contains "RR" or "rr" or "Rr" or "rR" then the default is + 'x' for transactions. otherwise it is 'm' for megabits (10^6) + however... if this is an "omni" test then we want to defer + this decision to scan_omni_args */ + + if (strcasecmp(test_name,"omni")) { + if ('?' == libfmt) { + /* we use a series of strstr's here because not everyone has + strcasestr and I don't feel like up or downshifting text */ + if ((strstr(test_name,"RR")) || + (strstr(test_name,"rr")) || + (strstr(test_name,"Rr")) || + (strstr(test_name,"rR"))) { + libfmt = 'x'; + } + else { + libfmt = 'm'; + } + } + else if ('x' == libfmt) { + /* now, a format of 'x' makes no sense for anything other than + an RR test. if someone has been silly enough to try to set + that, we will reset it silently to default - namely 'm' */ + if ((strstr(test_name,"RR") == NULL) && + (strstr(test_name,"rr") == NULL) && + (strstr(test_name,"Rr") == NULL) && + (strstr(test_name,"rR") == NULL)) { + libfmt = 'm'; + } + } + } +} + + +void +dump_globals() +{ + printf("Program name: %s\n", program); + printf("Local send alignment: %d\n",local_send_align); + printf("Local recv alignment: %d\n",local_recv_align); + printf("Remote send alignment: %d\n",remote_send_align); + printf("Remote recv alignment: %d\n",remote_recv_align); + printf("Report local CPU %d\n",local_cpu_usage); + printf("Report remote CPU %d\n",remote_cpu_usage); + printf("Verbosity: %d\n",verbosity); + printf("Debug: %d\n",debug); + printf("Port: %s\n",test_port); + printf("Test name: %s\n",test_name); + printf("Test bytes: %d Test time: %d Test trans: %d\n", + test_bytes, + test_time, + test_trans); + printf("Host name: %s\n",host_name); + printf("\n"); +} diff --git a/src/netsh.h b/src/netsh.h new file mode 100644 index 0000000..7154cdf --- /dev/null +++ b/src/netsh.h @@ -0,0 +1,184 @@ +/* + Copyright (C) 1993,1995 Hewlett-Packard Company +*/ + +/* libraried performance include file */ +/* the define NOPERFEXTERN tels us not to re-define all the */ + +/* defines and defaults */ +#define HOSTNAMESIZE 255 +#define PORTBUFSIZE 10 +#define DEFAULT_SIZE 32768 +#define HOST_NAME "127.0.0.1" +#define TEST_PORT "12865" + +/* output controlling variables */ +#define DEBUG 0 /* debugging level */ +#define VERBOSITY 0 /* verbosity level */ + +/* the end-test conditions for the tests - either transactions, bytes, */ +/* or time. different vars used for clarity - space is cheap ;-) */ +#define TEST_TIME 10 /* test ends by time */ +#define TEST_BYTES 0 /* test ends on byte count */ +#define TEST_TRANS 0 /* test ends on tran count */ + +/* the alignment conditions for the tests */ +#define LOC_RECV_ALIGN 4 /* alignment for local receives */ +#define LOC_SEND_ALIGN 4 /* alignment for local sends */ +#define REM_RECV_ALIGN 4 /* alignment for remote receive */ +#define REM_SEND_ALIGN 4 /* alignment for remote sends */ + +/* misc defines for the hell of it */ +#ifndef MAXLONG +#define MAXLONG 4294967295UL +#endif /* MAXLONG */ + +#ifdef WANT_DCCP + +#ifndef SOCK_DCCP +#define DCCP_WARNING +#define SOCK_DCCP 6 +#endif + +#ifndef IPPROTO_DCCP +#define DCCP_WARNING +#define IPPROTO_DCCP 33 /* defined by the IANA */ +#endif + +#ifndef SOL_DCCP +#define DCCP_WARNING +#define SOL_DCCP 269 +#endif + +#ifdef DCCP_WARNING +#warning This platform is missing one of sock_dccp ipproto_dccp or sol_dccp +#endif + +#endif + +#ifndef NETSH +extern char *program; /* program invocation name */ +extern char *command_line; /* how we were invoked */ + +/* stuff to say where this test is going */ +extern char host_name[HOSTNAMESIZE];/* remote host name or ip addr */ +extern char local_host_name[HOSTNAMESIZE]; +extern char test_port[PORTBUFSIZE]; /* where is the test waiting */ +extern char local_test_port[PORTBUFSIZE]; +extern int address_family; +extern int local_address_family; +extern int parse_address_family(char family_string[]); +extern int parse_socket_type(char socket_string[]); +extern int parse_protocol(char protocol_string[]); +extern void set_defaults(); +extern void scan_cmd_line(int argc, char *argv[]); +extern void dump_globals(); +extern void break_args(char *s, char *arg1, char *arg2); +extern void break_args_explicit(char *s, char *arg1, char *arg2); +extern void print_netserver_usage(); + +/* output controlling variables */ +extern int + debug, /* debugging level */ + print_headers, /* do/don't print test headers */ + verbosity; /* verbosity level */ + +/* the end-test conditions for the tests - either transactions, bytes, */ +/* or time. different vars used for clarity - space is cheap ;-) */ +extern int + test_time, /* test ends by time */ + test_len_ticks, + test_bytes, /* test ends on byte count */ + test_trans; /* test ends on tran count */ + +/* the alignment conditions for the tests */ +extern int + local_recv_align, /* alignment for local receives */ + local_send_align, /* alignment for local sends */ + remote_recv_align, /* alignment for remote receives */ + remote_send_align, /* alignment for remote sends */ + local_send_offset, + local_recv_offset, + remote_send_offset, + remote_recv_offset, + remote_send_width, + remote_recv_width; + +/* hoist these above the #if to deal with either netperf or netserver + configured for it */ + +extern int interval_usecs; +extern int interval_wate; +extern int interval_burst; +extern int remote_interval_usecs; +extern int remote_interval_burst; + +#if defined(WANT_INTERVALS) || defined(WANT_DEMO) + +extern int demo_mode; +extern double demo_interval; +extern double demo_units; +extern double units_this_tick; +#endif + +#ifdef DIRTY +extern int rem_dirty_count; +extern int rem_clean_count; +extern int loc_dirty_count; +extern int loc_clean_count; +#endif /* DIRTY */ + +/* stuff for confidence intervals */ + +extern int confidence_level; +extern int iteration_min; +extern int iteration_max; +extern int result_confidence_only; +extern double interval; +extern double interval_pct; + +extern int cpu_binding_requested; + +/* stuff to controll the bufferspace "width" */ +extern int send_width; +extern int recv_width; + +/* address family */ +extern int af; + +/* different options for other things */ +extern int + local_cpu_usage, + remote_cpu_usage; + +extern float + local_cpu_rate, + remote_cpu_rate; + +extern int + shell_num_cpus; + +extern char + test_name[BUFSIZ]; + +extern char + fill_file[BUFSIZ]; + +extern char * + result_brand; + +extern int + no_control; + +#ifdef WANT_DLPI + +extern int + loc_ppa, + rem_ppa; + +extern int + dlpi_sap; + +#endif /* WANT_DLPI */ + +#endif diff --git a/src/netslot_linux.c b/src/netslot_linux.c new file mode 100644 index 0000000..2ab5f3e --- /dev/null +++ b/src/netslot_linux.c @@ -0,0 +1,162 @@ +#define _XOPEN_SOURCE 500 +#include +#include +#include +#include + +static char interface_match[32]; +static char interface_address[13]; +static char interface_slot[13]="not found"; + +static int +find_slot(const char *fpath, const struct stat *sb, + int tflag, struct FTW *ftwbuf) +{ + char slot_address[11]; + int ret; + FILE *address_file; + char *myfpath; + char *this_tok; + char *last_tok; + + /* so, are we at a point in the tree where the basename is + "address" ? */ + if (strcmp("address",fpath + ftwbuf->base) == 0) { + address_file = fopen(fpath,"r"); + if (address_file == NULL) { + strcpy(interface_slot,"fopen"); + return 0; + } + /* we make the simplifying assumption that PCI domain, bus, slot + and function, with associated separators, are 10 characters or + less */ + ret = fread(slot_address,1,10,address_file); + if (ret != 10) { + strcpy(interface_slot,"fread"); + fclose(address_file); + return 0; + } + slot_address[ret] = 0; + /* the slot address will be a substring of the full bus address of + the interface we seek */ + if (strstr(interface_address,slot_address)) { + myfpath = strdup(fpath); + if (myfpath == NULL) { + strcpy(interface_slot,"strcpy"); + return 1; + } + + this_tok = strtok(myfpath,"/"); + while (strcmp(this_tok,"address")) { + last_tok = this_tok; + this_tok = strtok(NULL,"/"); + } + if (last_tok != NULL) + strcpy(interface_slot,last_tok); + else + strcpy(interface_slot,"last_tok"); + free(myfpath); + fclose(address_file); + return 1; + } + } + return 0; +} + +static int +find_interface(const char *fpath, const struct stat *sb, + int tflag, struct FTW *ftwbuf) +{ + char *myfpath; + char *this_tok; + char *last_tok; + if (strcmp(interface_match,fpath + ftwbuf->base) == 0) { + myfpath = strdup(fpath); + if (myfpath == NULL) { + strcpy(interface_address,"strcpy"); + return 1; + } + this_tok = strtok(myfpath,"/"); + while (strcmp(this_tok,interface_match)) { + last_tok = this_tok; + this_tok = strtok(NULL,"/"); + } + if (last_tok != NULL) + strcpy(interface_address,last_tok); + else + strcpy(interface_address,"last_tok"); + free(myfpath); + return 1; + } + return 0; +} + +char * +find_interface_slot(char *interface_name) { + + int flags = 0; + int ret; + + flags |= FTW_PHYS; /* don't follow symlinks for they will lead us + off the path */ + ret = snprintf(interface_match,31,"net:%s",interface_name); + interface_match[31]=0; + /* having setup the basename we will be seeking, go find it and the + corresponding interface_address */ + nftw("/sys/devices", find_interface, 20, flags); + /* now that we ostensibly have the pci address of the interface + (interface_address, lets find that slot shall we? */ + nftw("/sys/bus/pci/slots", find_slot, 20, flags); + return strdup(interface_slot); +} + +static int +get_val_from_file(char *valsource) { + FILE *valfile; + char buffer[6]; /* 0xabcd */ + int ret; + + valfile = fopen(valsource,"r"); + if (valfile == NULL) return -1; + + ret = fread(buffer,1,sizeof(buffer), valfile); + if (ret != sizeof(buffer)) return -1; + + ret = (int)strtol(buffer,NULL,0); + + return ret; + +} +void +find_interface_ids(char *interface_name, int *vendor, int *device, int *sub_vend, int *sub_dev) { + + int ret; + + char sysfile[128]; /* gotta love constants */ + + /* first the vendor id */ + ret = snprintf(sysfile,127,"/sys/class/net/%s/device/vendor",interface_name); + sysfile[128] = 0; + *vendor = get_val_from_file(sysfile); + + /* next the device */ + ret = snprintf(sysfile,127,"/sys/class/net/%s/device/device",interface_name); + sysfile[128] = 0; + *device = get_val_from_file(sysfile); + + /* next the subsystem vendor */ + ret = snprintf(sysfile,127,"/sys/class/net/%s/device/subsystem_vendor",interface_name); + sysfile[128] = 0; + *sub_vend = get_val_from_file(sysfile); + + /* next the subsystem device */ + ret = snprintf(sysfile,127,"/sys/class/net/%s/device/subsystem_device",interface_name); + sysfile[128] = 0; + *sub_dev = get_val_from_file(sysfile); + +} + + + + + diff --git a/src/netslot_none.c b/src/netslot_none.c new file mode 100644 index 0000000..73a4bf1 --- /dev/null +++ b/src/netslot_none.c @@ -0,0 +1,56 @@ +#if defined(HAVE_CONFIG_H) +#include +#endif + +#if defined(HAVE_STRING_H) +#include +#endif + +#if defined(NETPERF_STANDALONE_DEBUG) +#include +#endif + +char * +find_interface_slot(char *interface_name) { + return strdup("Not Implemented"); +} + +void +find_interface_ids(char *interface_name, int *vendor, int *device, int *sub_vend, int *sub_dev) { + *vendor = 0; + *device = 0; + *sub_vend = 0; + *sub_dev = 0; + return; +} + +#if defined(NETPERF_STANDALONE_DEBUG) +int +main(int argc, char *argv[]) { + + char *slot; + int vendor; + int device; + int subvendor; + int subdevice; + + if (argc != 2) { + fprintf(stderr,"%s \n",argv[0]); + return -1; + } + + slot = find_interface_slot(argv[1]); + + find_interface_ids(argv[1], &vendor, &device, &subvendor, &subdevice); + + printf("%s in in slot %s: vendor %4x device %4x subvendor %4x subdevice %4x\n", + argv[1], + slot, + vendor, + device, + subvendor, + subdevice); + + return 0; +} +#endif diff --git a/src/netslot_solaris.c b/src/netslot_solaris.c new file mode 100644 index 0000000..c471cb1 --- /dev/null +++ b/src/netslot_solaris.c @@ -0,0 +1,280 @@ +#if defined(HAVE_CONFIG_H) +#include +#endif + +#include +#include + +#if defined(NETPERF_STANDALONE_DEBUG) +#include +#endif + +#include +#include +#include +#include + +char * +find_interface_slot(char *interface_name) { + return strdup("Not Implemented"); +} + +static char interface_match[IFNAMSIZ]; +static int found_vendor = 0; +static int found_device = 0; +static int found_subvendor = 0; +static int found_subdevice = 0; + +static char * +set_interface_match(char *interface_name) { + + int i; + char *nukeit; + + strncpy(interface_match,interface_name,IFNAMSIZ); + interface_match[IFNAMSIZ-1] = 0; + + + /* strip away the logical interface information if present we "know" + thanks to the above that we will find a null character to get us + out of the loop */ + for (nukeit = strchr(interface_match,':'); + (NULL != nukeit) && (*nukeit != 0); + nukeit++) { + *nukeit = 0; + } + + if (strlen(interface_match) == 0) + return NULL; + else + return interface_match; + +} + +/* take the binding name for our found node and try to break it up + into pci ids. return the number of IDs we found */ + +static int +parse_binding_name(char *binding_name) { + + char *my_copy; + char *vend; + char *dev; + char *subvend; + char *subdev; + int count; + int i; + + /* we cannot handle "class" :) */ + if (NULL != strstr(binding_name,"class")) + return 0; + + my_copy = strdup(binding_name); + if (NULL == my_copy) + return 0; + + /* we assume something of the form: + + pci14e4,164c or perhaps + pci14e4,164c.103c.7038.12 or + pciex8086,105e.108e.105e.6 or + + where we ass-u-me that the first four hex digits before the comma + are the vendor ID, the next four after the comma are the device + id, the next four after the period are the subvendor id and the + next four after the next dot are the subdevice id. we have + absolutely no idea what the digits after a third dot might be. + + of course these: + + pciex108e,abcd.108e.0.1 + pci14e4,164c.12 + + are somewhat perplexing also. Can we ass-u-me that the id's will + always be presented as four character hex? Until we learn to the + contrary, that is what will be ass-u-me-d here and so we will + naturally ignore those things, which might be revision numbers + raj 2008-03-20 */ + + vend = strtok(my_copy,","); + if (NULL == vend) { + count = 0; + } + else { + /* take only the last four characters */ + if (strlen(vend) < 5) { + count = 0; + } + else { + /* OK, we could just update vend I suppose, but for some reason + I felt the need to blank-out the leading cruft... */ + for (i = 0; i < strlen(vend) - 4; i++) + vend[i] = ' '; + found_vendor = strtol(vend,NULL,16); + /* ok, now check for device */ + dev = strtok(NULL,"."); + if ((NULL == dev) || (strlen(dev) != 4)) { + /* we give-up after vendor */ + count = 1; + } + else { + found_device = strtol(dev,NULL,16); + /* ok, now check for subvendor */ + subvend = strtok(NULL,"."); + if ((NULL == subvend) || (strlen(subvend) != 4)) { + /* give-up after device */ + count = 2; + } + else { + found_subvendor = strtol(subvend,NULL,16); + /* ok, now check for subdevice */ + subdev = strtok(NULL,"."); + if ((NULL == subdev) || (strlen(subdev) != 4)) { + /* give-up after subvendor */ + count = 3; + } + else { + found_subdevice = strtol(subdev,NULL,16); + count = 4; + } + } + } + } + } + return count; +} + +static int +check_node(di_node_t node, void *arg) { + + char *nodename; + char *minorname; + char *propname; + char *bindingname; + di_minor_t minor; + di_prop_t prop; + int *ints; + +#ifdef NETPERF_STANDALONE_DEBUG + nodename = di_devfs_path(node); + /* printf("Checking node named %s\n",nodename); */ + di_devfs_path_free(nodename); +#endif + + minor = DI_MINOR_NIL; + while ((minor = di_minor_next(node,minor)) != DI_MINOR_NIL) { + /* check for a match with the interface_match */ + minorname = di_minor_name(minor); +#ifdef NETPERF_STANDALONE_DEBUG + /* printf("\tminor name %s\n",minorname); */ +#endif + /* do they match? */ + if (strcmp(minorname,interface_match) == 0) { + /* found a match */ + bindingname = di_binding_name(node); +#ifdef NETPERF_STANDALONE_DEBUG + printf("FOUND A MATCH ON %s under node %s with binding name %s\n",interface_match, + nodename, + bindingname); +#endif + + if (parse_binding_name(bindingname) == 4) { + /* we are done */ + return DI_WALK_TERMINATE; + } + + /* ok, getting here means we didn't find all the names we seek, + so try taking a look at the properties of the node. we know + that at least one driver is kind enough to set them in + there... and if we find it, we will allow that to override + anything we may have already found */ + prop = DI_PROP_NIL; + while ((prop = di_prop_next(node,prop)) != DI_PROP_NIL) { + propname = di_prop_name(prop); +#ifdef NETPERF_STANDALONE_DEBUG + printf("\t\tproperty name %s\n",propname); +#endif + /* only bother checking the name if the type is what we expect + and we can get the ints */ + if ((di_prop_type(prop) == DI_PROP_TYPE_INT) && + (di_prop_ints(prop,&ints) > 0)) { + if (strcmp(propname,"subsystem-vendor-id") == 0) + found_subvendor = ints[0]; + else if (strcmp(propname,"subsystem-id") == 0) + found_subdevice = ints[0]; + else if (strcmp(propname,"vendor-id") == 0) + found_vendor = ints[0]; + else if (strcmp(propname,"device-id") == 0) + found_device = ints[0]; + } + } + /* since we found a match on the name, we are done now */ + return DI_WALK_TERMINATE; + } + } + return DI_WALK_CONTINUE; + +} +void +find_interface_ids(char *interface_name, int *vendor, int *device, int *sub_vend, int *sub_dev) { + + di_node_t root; + char *interface_match; + + /* so we have "failure values" ready if need be */ + *vendor = 0; + *device = 0; + *sub_vend = 0; + *sub_dev = 0; + + interface_match = set_interface_match(interface_name); + if (NULL == interface_match) + return; + + /* get the root of all devices, and hope they aren't evil */ + root = di_init("/", DINFOCPYALL); + + if (DI_NODE_NIL == root) + return; + + /* now we start trapsing merrily around the tree */ + di_walk_node(root, DI_WALK_CLDFIRST,NULL,check_node); + + di_fini(root); + *vendor = found_vendor; + *device = found_device; + *sub_vend = found_subvendor; + *sub_dev = found_subdevice; + return; +} + +#if defined(NETPERF_STANDALONE_DEBUG) +int +main(int argc, char *argv[]) { + + char *slot; + int vendor; + int device; + int subvendor; + int subdevice; + + if (argc != 2) { + fprintf(stderr,"%s \n",argv[0]); + return -1; + } + + slot = find_interface_slot(argv[1]); + + find_interface_ids(argv[1], &vendor, &device, &subvendor, &subdevice); + + printf("%s in in slot %s: vendor %4x device %4x subvendor %4x subdevice %4x\n", + argv[1], + slot, + vendor, + device, + subvendor, + subdevice); + + return 0; +} +#endif diff --git a/src/netsys_hpux11i.c b/src/netsys_hpux11i.c new file mode 100644 index 0000000..753e496 --- /dev/null +++ b/src/netsys_hpux11i.c @@ -0,0 +1,56 @@ +#include +#include +#include +#include +#include + +/* tusc can be a very useful thing... */ + +#ifndef _SI_MACHINE_MODEL +#define _SI_MACHINE_MODEL 5 +#endif + +extern int sysinfo(int info, char *buffer, ssize_t len); + + +void +find_system_info(char **system_model, char **cpu_model, int *cpu_frequency) { + char model_str[64]; + int ret; + struct pst_processor processor_info; + + /* first the system model name */ + ret = sysinfo(_SI_MACHINE_MODEL,model_str,64); + model_str[63] = 0; + *system_model = strdup(model_str); + + /* now lets try to find processor frequency. we will for now + ass-u-me that an index of zero will always get us something, + which may not actually be the case but lets see how long it takes + to be noticed :) raj 2008-03-07 */ + ret = pstat_getprocessor(&processor_info, + sizeof(processor_info), + 1, /* one processor, one processor only please */ + 0); + + if (ret > 0) { +#ifdef PSP_MAX_CACHE_LEVELS + /* we can get it "directly" but to help make things reconcile with + what other tools/platforms support, we shouldn't do a simple + integer divide - instead, we should do our division in floating + point and then round */ + *cpu_frequency = rint((double)processor_info.psp_cpu_frequency / + 1000000.0); +#else + /* older OSes were "known" to be on CPUs where the itick was + 1to1 here */ + *cpu_frequency = rint(((double)processor_info.psp_iticksperclktick * + (double)sysconf(_SC_CLK_TCK)) / 1000000.0); +#endif + } + else + *cpu_frequency = -1; + + *cpu_model = strdup("Unknown CPU Model"); +} + diff --git a/src/netsys_linux.c b/src/netsys_linux.c new file mode 100644 index 0000000..37d3524 --- /dev/null +++ b/src/netsys_linux.c @@ -0,0 +1,138 @@ +#ifdef HAVE_CONFIG_H +#include +#endif + +#ifdef NETPERF_STANDALONE_DEBUG +#include +#endif + +#include +#include +#include +#include + +static void +find_cpu_model(char **cpu_model) { + char linebuf[256]; + char *cret; + int ret; + int c; + + FILE *proccpu; + + proccpu = fopen("/proc/cpuinfo","r"); + + if (NULL == proccpu) { + *cpu_model = strdup("fopen"); + return; + } + + do { + cret = fgets(linebuf,256,proccpu); + if (NULL != cret) { + char *target; + /* OK, so does it start with "model name" ? */ + if (strstr(linebuf,"model name") != NULL) { + /* one for the money "model name" */ + target = strtok(linebuf,":"); + /* two for the show (the actual model name) */ + target = strtok(NULL,":"); + /* three to get ready - strip the eol */ + target[strlen(target)-1] = 0; + /* and four to go! */ + *cpu_model = strdup(target+1); + return; + } + } + } while (!feof(proccpu)); + *cpu_model = strdup("model_name"); +} + +static int +find_cpu_freq() { + char linebuf[256]; + char *cret; + int ret; + int c; + + FILE *proccpu; + + proccpu = fopen("/proc/cpuinfo","r"); + + if (NULL == proccpu) { + return -1; + } + + do { + cret = fgets(linebuf,256,proccpu); + if (NULL != cret) { + char *target; + /* OK, so does it start with "model name" ? */ + if (strstr(linebuf,"cpu MHz") != NULL) { + target = strtok(linebuf,":"); + target = strtok(NULL,":"); + return rint(strtod(target+1,NULL)); + } + } + } while (!feof(proccpu)); + return -1; +} + +static void +find_system_model(char **system_model) { +#if defined(HAVE_LIBSMBIOS) +#if defined(HAVE_SMBIOS_SYSTEMINFO_H) +#include +#else + /* take our best shot - the interface seems simple and stable enough + that we don't have to require the -dev package be installed */ + extern const char *SMBIOSGetSystemName(); +#endif + + char *temp_model; + + /* SMBIOSGetSystemModel allocated */ + temp_model = (char *) SMBIOSGetSystemName(); + if (temp_model) + *system_model = temp_model; + else + *system_model = strdup("SMBIOSGetSystemModel"); + +#else + /* we do not even have the library so there isn't much to do here + unless someone wants to teach netperf how to find and parse + SMBIOS all by its lonesome. raj 2008-03-13 */ + *system_model = strdup("Teach Me SMBIOS"); +#endif + return; +} + +void +find_system_info(char **system_model, char **cpu_model, int *cpu_frequency) { + int ret; + + find_system_model(system_model); + find_cpu_model(cpu_model); + *cpu_frequency = find_cpu_freq(); + +} + +#ifdef NETPERF_STANDALONE_DEBUG +int +main(int argc, char *argv[]) { + + char *system_model; + char *cpu_model; + int frequency; + + find_system_info(&system_model,&cpu_model,&frequency); + printf("system_model %s, cpu_model %s, frequency %d\n", + system_model, + cpu_model, + frequency); + + return 0; + +} + +#endif diff --git a/src/netsys_none.c b/src/netsys_none.c new file mode 100644 index 0000000..fe68140 --- /dev/null +++ b/src/netsys_none.c @@ -0,0 +1,8 @@ +#include + +void +find_system_info(char **system_model, char **cpu_model, int *cpu_frequency) { + *system_model = strdup("Unknown System Model"); + *cpu_model = strdup("Unknown CPU Model"); + *cpu_frequency = -1; +} diff --git a/src/netsys_solaris.c b/src/netsys_solaris.c new file mode 100644 index 0000000..15a14a6 --- /dev/null +++ b/src/netsys_solaris.c @@ -0,0 +1,179 @@ +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include +#include + +static kstat_ctl_t *kc = NULL; +static kid_t kcid = 0; + +static void +find_cpu_model_freq(char **cpu_model, int *frequency) { + + kstat_t *ksp; + kid_t nkcid; + kstat_named_t *knp; + int i,found_brand,found_freq; + + + found_brand = 0; + found_freq = 0; + + kc = kstat_open(); + + if (NULL == kc) { + *cpu_model = strdup("kstat_open"); + *frequency = -1; + return; + } + + ksp = kstat_lookup(kc, "cpu_info", 0, NULL); + + if ((NULL == ksp) || + ((ksp) && (KSTAT_TYPE_NAMED != ksp->ks_type))) { + *cpu_model = strdup("kstat_lookup"); + *frequency = -1; + kstat_close(kc); + return; + } + + nkcid = kstat_read(kc, ksp, NULL); + + if (-1 == nkcid) { + *cpu_model = strdup("kstat_read"); + *frequency = -1; + kstat_close(kc); + return; + } + + for (i = ksp->ks_ndata, knp = ksp->ks_data; + i > 0; + knp++, i--) { + if (!strcmp("brand", knp->name)) { + *cpu_model = strdup(KSTAT_NAMED_STR_PTR(knp)); + found_brand = 1; + } + else if (!strcmp("clock_MHz",knp->name)) { + *frequency = (int)knp->value.ui32; + found_freq = 1; + } + } + if (!found_brand) + *cpu_model = strdup("CPU Not Found"); + if (!found_freq) + *frequency = -1; + + kstat_close(kc); +} + +static void +find_system_model_sysinfo(char **system_model) { + +#include + char model_str[37]; + char *token1,*token2; + long ret; + /* sysinfo is kind enough to zero-terminate for us. we will be + ignoring the leading SUNW, if present so use 37 instead of 35 in + case the platform name is long */ + ret = sysinfo(SI_PLATFORM,model_str,37); + if (-1 != ret) { + /* however, it seems to shove potentially redundant information at + us and include a comma, which we have no desire to include, so + we will ass-u-me we can do a couple strtok calls to be rid of + that */ + token1 = strtok(model_str,","); + token2 = strtok(NULL,","); + if (token2) + *system_model = strdup(token2); + else + *system_model = strdup(model_str); + } + else + *system_model = strdup("sysinfo"); + +} + +static void +find_system_model(char **system_model) { + + /* the .h file will be there even on a SPARC system, so we have to + check for both the .h and the libarary... */ +#if defined(HAVE_SYS_SMBIOS_H) && defined(HAVE_LIBSMBIOS) +#include + smbios_hdl_t *smbios_handle; + smbios_info_t info; + + int error; + int ret; + id_t ret_id_t; + + /* much of this is wild guessing based on web searches, sys/smbios.h, and + experimentation. my thanks to a helpful person familiar with libsmbios + who got me started. feel free to make yourself known as you see fit :) + rick jones 2008-03-12 */ + smbios_handle = smbios_open(NULL,SMB_VERSION,0,&error); + if (NULL == smbios_handle) { + /* fall-back on sysinfo for the system model info, we don't really + care why we didn't get a handle, just that we didn't get one */ +#if defined(NETPERF_STANDALONE_DEBUG) + printf("smbios_open returned NULL, error %d errno %d %s\n", + error,errno,strerror(errno)); +#endif + find_system_model_sysinfo(system_model); + return; + } + ret = smbios_info_common(smbios_handle,256,&info); + if (0 == ret) + *system_model = strdup(info.smbi_product); + else { + /* we ass-u-me that while there was smbios on the system it didn't + have the smbi_product information we seek, so once again we + fallback to sysinfo. this is getting tiresome isn't it?-) raj + 2008-03-12 */ +#if defined(NETPERF_STANDALONE_DEBUG) + printf("smbios_info_common returned %d errno %d %s\n", + ret,errno,strerror(errno)); +#endif + find_system_model_sysinfo(system_model); + } + smbios_close(smbios_handle); + +#else + + find_system_model_sysinfo(system_model); + +#endif + + return; +} + +void +find_system_info(char **system_model, char **cpu_model, int *cpu_frequency) { + int ret; + + find_system_model(system_model); + find_cpu_model_freq(cpu_model,cpu_frequency); + +} + +#if defined(NETPERF_STANDALONE_DEBUG) +int +main(int argc, char *argv[]) { + char *system_model; + char *cpu_model; + int frequency; + + find_system_info(&system_model,&cpu_model,&frequency); + printf("system_model %s, cpu_model %s, frequency %d\n", + system_model, + cpu_model, + frequency); +} +#endif + diff --git a/src/nettest_bsd.c b/src/nettest_bsd.c new file mode 100644 index 0000000..8fdb5f0 --- /dev/null +++ b/src/nettest_bsd.c @@ -0,0 +1,13001 @@ +#ifndef lint +char nettest_id[]="\ +@(#)nettest_bsd.c (c) Copyright 1993-2008 Hewlett-Packard Co. Version 2.4.5"; +#endif /* lint */ + + +/****************************************************************/ +/* */ +/* nettest_bsd.c */ +/* */ +/* the BSD sockets parsing routine... */ +/* ...with the addition of Windows NT, this is now also */ +/* a Winsock test... sigh :) */ +/* */ +/* scan_sockets_args() */ +/* */ +/* the actual test routines... */ +/* */ +/* send_tcp_stream() perform a tcp stream test */ +/* recv_tcp_stream() */ +/* send_tcp_maerts() perform a tcp stream test */ +/* recv_tcp_maerts() in the other direction */ +/* send_tcp_rr() perform a tcp request/response */ +/* recv_tcp_rr() */ +/* send_tcp_conn_rr() an RR test including connect */ +/* recv_tcp_conn_rr() */ +/* send_tcp_cc() a connect/disconnect test with */ +/* recv_tcp_cc() no RR */ +/* send_tcp_mss() just report the mss */ +/* send_udp_stream() perform a udp stream test */ +/* recv_udp_stream() */ +/* send_udp_rr() perform a udp request/response */ +/* recv_udp_rr() */ +/* loc_cpu_rate() determine the local cpu maxrate */ +/* rem_cpu_rate() find the remote cpu maxrate */ +/* */ +/****************************************************************/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#if HAVE_SYS_TYPES_H +# include +#endif +#if HAVE_SYS_STAT_H +# include +#endif +#if STDC_HEADERS +# include +# include +#else +# if HAVE_STDLIB_H +# include +# endif +#endif +#if HAVE_STRING_H +# if !STDC_HEADERS && HAVE_MEMORY_H +# include +# endif +# include +#endif +#if HAVE_STRINGS_H +# include +#endif +#if HAVE_INTTYPES_H +# include +#else +# if HAVE_STDINT_H +# include +# endif +#endif +#if HAVE_UNISTD_H +# include +#endif + +#include +#ifndef WIN32 +#include +#include +#endif + +#if TIME_WITH_SYS_TIME +# include +# include +#else +# if HAVE_SYS_TIME_H +# include +# else +# include +# endif +#endif + +#ifdef NOSTDLIBH +#include +#endif /* NOSTDLIBH */ + +#ifdef WANT_SCTP +#include +#endif + +#ifndef WIN32 +#if !defined(__VMS) && !defined(MSDOS) +#include +#endif /* !__VMS && !MSDOS */ +#include +#include +#include +#include +#include +#else /* WIN32 */ +#include +#define netperf_socklen_t socklen_t +#include + +/* while it is unlikely that anyone running Windows 2000 or NT 4 is + going to be trying to compile this, if they are they will want to + define DONT_IPV6 in the sources file */ +#ifndef DONT_IPV6 +#include +#endif +#include + +#define sleep(x) Sleep((x)*1000) + +#define __func__ __FUNCTION__ +#endif /* WIN32 */ + +/* We don't want to use bare constants in the shutdown() call. In the + extremely unlikely event that SHUT_WR isn't defined, we will define + it to the value we used to be passing to shutdown() anyway. raj + 2007-02-08 */ +#if !defined(SHUT_WR) +#define SHUT_WR 1 +#endif + +#if !defined(HAVE_GETADDRINFO) || !defined(HAVE_GETNAMEINFO) +# include "missing/getaddrinfo.h" +#endif + +#include "netlib.h" +#include "netsh.h" +#include "nettest_bsd.h" + +#if defined(WANT_HISTOGRAM) || defined(WANT_DEMO) +#include "hist.h" +#endif /* WANT_HISTOGRAM */ + + +/* make first_burst_size unconditional so we can use it easily enough + when calculating transaction latency for the TCP_RR test. raj + 2007-06-08 however, change its default value so one can tell in + "omni" output whether or not WANT_BURST was enabled. raj + 2008-01-28 */ +#if defined(WANT_FIRST_BURST) +int first_burst_size=0; +#else +int first_burst_size=-1; +#endif + +#if defined(HAVE_SENDFILE) && (defined(__linux) || defined(__sun)) +#include +#endif /* HAVE_SENDFILE && (__linux || __sun) */ + + + +/* these variables are specific to the BSD sockets tests, but can + * be used elsewhere if needed. They are externed through nettest_bsd.h + */ + +int + socket_type, /* used initially by the "omni" tests */ + rss_size_req = -1, /* requested remote socket send buffer size */ + rsr_size_req = -1, /* requested remote socket recv buffer size */ + rss_size, /* initial remote socket send buffer size */ + rsr_size, /* initial remote socket recv buffer size */ + rss_size_end = -1, /* final remote socket send buffer size */ + rsr_size_end = -1, /* final remote socket recv buffer size */ + lss_size_req = -1, /* requested local socket send buffer size */ + lsr_size_req = -1, /* requested local socket recv buffer size */ + lss_size, /* local socket send buffer size */ + lsr_size, /* local socket recv buffer size */ + lss_size_end = -1, /* final local socket send buffer size */ + lsr_size_end = -1, /* final local socket recv buffer size */ + req_size = 1, /* request size */ + rsp_size = 1, /* response size */ + send_size, /* how big are individual sends */ + recv_size; /* how big are individual receives */ + +static int confidence_iteration; +static char local_cpu_method; +static char remote_cpu_method; + +/* these will control the width of port numbers we try to use in the */ +/* TCP_CRR and/or TCP_TRR tests. raj 3/95 */ +static int client_port_min = 5000; +static int client_port_max = 65535; + + /* different options for the sockets */ + +int + loc_nodelay, /* don't/do use NODELAY locally */ + rem_nodelay, /* don't/do use NODELAY remotely */ +#ifdef TCP_CORK + loc_tcpcork=0, /* don't/do use TCP_CORK locally */ + rem_tcpcork=0, /* don't/do use TCP_CORK remotely */ +#else + loc_tcpcork=-1, + rem_tcpcork=-1, +#endif /* TCP_CORK */ + loc_sndavoid, /* avoid send copies locally */ + loc_rcvavoid, /* avoid recv copies locally */ + rem_sndavoid, /* avoid send copies remotely */ + rem_rcvavoid, /* avoid recv_copies remotely */ + local_connected = 0, /* local socket type, connected/non-connected */ + remote_connected = 0; /* remote socket type, connected/non-connected */ + +#ifdef WANT_HISTOGRAM +#ifdef HAVE_GETHRTIME +static hrtime_t time_one; +static hrtime_t time_two; +#elif HAVE_GET_HRT +#include "hrt.h" +static hrt_t time_one; +static hrt_t time_two; +#elif defined(WIN32) +static LARGE_INTEGER time_one; +static LARGE_INTEGER time_two; +#else +static struct timeval time_one; +static struct timeval time_two; +#endif /* HAVE_GETHRTIME */ +static HIST time_hist; +#endif /* WANT_HISTOGRAM */ + +#ifdef WANT_INTERVALS +int interval_count; +#ifndef WANT_SPIN +sigset_t signal_set; +#define INTERVALS_INIT() \ + if (interval_burst) { \ + /* zero means that we never pause, so we never should need the \ + interval timer. we used to use it for demo mode, but we deal \ + with that with a variant on watching the clock rather than \ + waiting for a timer. raj 2006-02-06 */ \ + start_itimer(interval_wate); \ + } \ + interval_count = interval_burst; \ + /* get the signal set for the call to sigsuspend */ \ + if (sigprocmask(SIG_BLOCK, (sigset_t *)NULL, &signal_set) != 0) { \ + fprintf(where, \ + "%s: unable to get sigmask errno %d\n", \ + __func__, \ + errno); \ + fflush(where); \ + exit(1); \ + } + +#define INTERVALS_WAIT() \ + /* in this case, the interval count is the count-down couter \ + to decide to sleep for a little bit */ \ + if ((interval_burst) && (--interval_count == 0)) { \ + /* call sigsuspend and wait for the interval timer to get us \ + out */ \ + if (debug > 1) { \ + fprintf(where,"about to suspend\n"); \ + fflush(where); \ + } \ + if (sigsuspend(&signal_set) == EFAULT) { \ + fprintf(where, \ + "%s: fault with sigsuspend.\n", \ + __func__); \ + fflush(where); \ + exit(1); \ + } \ + interval_count = interval_burst; \ + } +#else +/* first out timestamp */ +#ifdef HAVE_GETHRTIME +static hrtime_t intvl_one; +static hrtime_t intvl_two; +static hrtime_t *intvl_one_ptr = &intvl_one; +static hrtime_t *intvl_two_ptr = &intvl_two; +static hrtime_t *temp_intvl_ptr = &intvl_one; +#elif defined(WIN32) +static LARGE_INTEGER intvl_one; +static LARGE_INTEGER intvl_two; +static LARGE_INTEGER *intvl_one_ptr = &intvl_one; +static LARGE_INTEGER *intvl_two_ptr = &intvl_two; +static LARGE_INTEGER *temp_intvl_ptr = &intvl_one; +#else +static struct timeval intvl_one; +static struct timeval intvl_two; +static struct timeval *intvl_one_ptr = &intvl_one; +static struct timeval *intvl_two_ptr = &intvl_two; +static struct timeval *temp_intvl_ptr = &intvl_one; +#endif + +#define INTERVALS_INIT() \ + if (interval_burst) { \ + HIST_timestamp(intvl_one_ptr); \ + } \ + interval_count = interval_burst; \ + +#define INTERVALS_WAIT() \ + /* in this case, the interval count is the count-down couter \ + to decide to sleep for a little bit */ \ + if ((interval_burst) && (--interval_count == 0)) { \ + /* call sigsuspend and wait for the interval timer to get us \ + out */ \ + if (debug > 1) { \ + fprintf(where,"about to spin suspend\n"); \ + fflush(where); \ + } \ + HIST_timestamp(intvl_two_ptr); \ + while(delta_micro(intvl_one_ptr,intvl_two_ptr) < interval_usecs) { \ + HIST_timestamp(intvl_two_ptr); \ + } \ + temp_intvl_ptr = intvl_one_ptr; \ + intvl_one_ptr = intvl_two_ptr; \ + intvl_two_ptr = temp_intvl_ptr; \ + interval_count = interval_burst; \ + } +#endif +#endif + +#ifdef WANT_DEMO +#ifdef HAVE_GETHRTIME +static hrtime_t demo_one; +static hrtime_t demo_two; +static hrtime_t *demo_one_ptr = &demo_one; +static hrtime_t *demo_two_ptr = &demo_two; +static hrtime_t *temp_demo_ptr = &demo_one; +#elif defined(WIN32) +static LARGE_INTEGER demo_one; +static LARGE_INTEGER demo_two; +static LARGE_INTEGER *demo_one_ptr = &demo_one; +static LARGE_INTEGER *demo_two_ptr = &demo_two; +static LARGE_INTEGER *temp_demo_ptr = &demo_one; +#else +static struct timeval demo_one; +static struct timeval demo_two; +static struct timeval *demo_one_ptr = &demo_one; +static struct timeval *demo_two_ptr = &demo_two; +static struct timeval *temp_demo_ptr = &demo_one; +#endif + +/* for a _STREAM test, "a" should be lss_size and "b" should be + rsr_size. for a _MAERTS test, "a" should be lsr_size and "b" should + be rss_size. raj 2005-04-06 */ +#define DEMO_STREAM_SETUP(a,b) \ + if ((demo_mode) && (demo_units == 0)) { \ + /* take our default value of demo_units to be the larger of \ + twice the remote's SO_RCVBUF or twice our SO_SNDBUF */ \ + if (a > b) { \ + demo_units = 2*a; \ + } \ + else { \ + demo_units = 2*b; \ + } \ + } + +/* now that calc_thruput_interval knows about transactions as a format + we can merge DEMO_STREAM_INTERVAL and DEMO_RR_INTERVAL since the + are the same */ + +#define DEMO_INTERVAL(units) \ + if (demo_mode) { \ + double actual_interval; \ + units_this_tick += units; \ + if (units_this_tick >= demo_units) { \ + /* time to possibly update demo_units and maybe output an \ + interim result */ \ + HIST_timestamp(demo_two_ptr); \ + actual_interval = delta_micro(demo_one_ptr,demo_two_ptr); \ + /* we always want to fine-tune demo_units here whether we \ + emit an interim result or not. if we are short, this \ + will lengthen demo_units. if we are long, this will \ + shorten it */ \ + demo_units = demo_units * (demo_interval / actual_interval); \ + if (actual_interval >= demo_interval) { \ + /* time to emit an interim result */ \ + fprintf(where, \ + "Interim result: %.2f %s/s over %.2f seconds\n", \ + calc_thruput_interval(units_this_tick, \ + actual_interval/1000000.0), \ + format_units(), \ + actual_interval/1000000.0); \ + units_this_tick = 0.0; \ + /* now get a new starting timestamp. we could be clever \ + and swap pointers - the math we do probably does not \ + take all that long, but for now this will suffice */ \ + temp_demo_ptr = demo_one_ptr; \ + demo_one_ptr = demo_two_ptr; \ + demo_two_ptr = temp_demo_ptr; \ + } \ + } \ + } + +#define DEMO_STREAM_INTERVAL(units) DEMO_INTERVAL(units) + +#define DEMO_RR_SETUP(a) \ + if ((demo_mode) && (demo_units == 0)) { \ + /* take whatever we are given */ \ + demo_units = a; \ + } + +#define DEMO_RR_INTERVAL(units) DEMO_INTERVAL(units) + +#endif + +char sockets_usage[] = "\n\ +Usage: netperf [global options] -- [test options] \n\ +\n\ +TCP/UDP BSD Sockets Test Options:\n\ + -b number Send number requests at start of _RR tests\n\ + -C Set TCP_CORK when available\n\ + -D [L][,R] Set TCP_NODELAY locally and/or remotely (TCP_*)\n\ + -h Display this text\n\ + -H name,fam Use name (or IP) and family as target of data connection\n\ + -L name,fam Use name (or IP) and family as source of data connection\n\ + -m bytes Set the send size (TCP_STREAM, UDP_STREAM)\n\ + -M bytes Set the recv size (TCP_STREAM, UDP_STREAM)\n\ + -n Use the connected socket for UDP locally\n\ + -N Use the connected socket for UDP remotely\n\ + -p min[,max] Set the min/max port numbers for TCP_CRR, TCP_TRR\n\ + -P local[,remote] Set the local/remote port for the data socket\n\ + -r req,[rsp] Set request/response sizes (TCP_RR, UDP_RR)\n\ + -s send[,recv] Set local socket send/recv buffer sizes\n\ + -S send[,recv] Set remote socket send/recv buffer sizes\n\ + -4 Use AF_INET (eg IPv4) on both ends of the data conn\n\ + -6 Use AF_INET6 (eg IPv6) on both ends of the data conn\n\ +\n\ +For those options taking two parms, at least one must be specified;\n\ +specifying one value without a comma will set both parms to that\n\ +value, specifying a value with a leading comma will set just the second\n\ +parm, a value with a trailing comma will set just the first. To set\n\ +each parm to unique values, specify both and separate them with a\n\ +comma.\n"; + + + +/* these routines convert between the AF address space and the NF + address space since the numeric values of AF_mumble are not the + same across the platforms. raj 2005-02-08 */ + +int +nf_to_af(int nf) { + switch(nf) { + case NF_INET: + return AF_INET; + break; + case NF_UNSPEC: + return AF_UNSPEC; + break; + case NF_INET6: +#if defined(AF_INET6) + return AF_INET6; +#else + return AF_UNSPEC; +#endif + break; + default: + return AF_UNSPEC; + break; + } +} + +int +af_to_nf(int af) { + + switch(af) { + case AF_INET: + return NF_INET; + break; + case AF_UNSPEC: + return NF_UNSPEC; + break; +#if defined(AF_INET6) + case AF_INET6: + return NF_INET6; + break; +#endif + default: + return NF_UNSPEC; + break; + } +} + + +/* these routines will convert between the hosts' socket types and + those netperf uses. we need this because different platforms can + have different values for SOCK_STREAM, SOCK_DGRAM and the + like... */ + +int +nst_to_hst(int nst) { + switch(nst) { +#ifdef SOCK_STREAM + case NST_STREAM: + return SOCK_STREAM; + break; /* ok, this may not be necessary :) */ +#endif +#ifdef SOCK_DGRAM + case NST_DGRAM: + return SOCK_DGRAM; + break; +#endif +#ifdef SOCK_DCCP + case NST_DCCP: + return SOCK_DCCP; + break; +#endif + default: + return -1; + } +} + +int +hst_to_nst(int hst) { + + switch(hst) { +#ifdef SOCK_STREAM + case SOCK_STREAM: + return NST_STREAM; + break; +#endif +#ifdef SOCK_DGRAM + case SOCK_DGRAM: + return NST_DGRAM; + break; +#endif +#ifdef SOCK_DCCP + case SOCK_DCCP: + return NST_DCCP; + break; +#endif + default: + return NST_UNKN; + } +} +char * +hst_to_str(int hst) { + + switch(hst) { +#ifdef SOCK_STREAM + case SOCK_STREAM: + return "Stream"; + break; +#endif +#ifdef SOCK_DGRAM + case SOCK_DGRAM: + return "Datagram"; + break; +#endif +#ifdef SOCK_DCCP + case SOCK_DCCP: + return "DCCP"; + break; +#endif + default: + return "Unknown"; + } +} + +char * +protocol_to_str(int protocol) { + switch(protocol) { +#ifdef IPPROTO_TCP + case IPPROTO_TCP: + return "TCP"; +#endif +#ifdef IPPROTO_UDP + case IPPROTO_UDP: + return "UDP"; +#endif +#ifdef IPPROTO_SCTP + case IPPROTO_SCTP: + return "SCTP"; +#endif +#ifdef IPPROTO_DCCP + case IPPROTO_DCCP: + return "DCCP"; +#endif +#ifdef IPPROTO_SDP + case IPPROTO_SDP: + return "SDP"; +#endif + default: + return "Unknown Protocol"; + } +} + + + /* This routine is intended to retrieve interesting aspects of tcp */ + /* for the data connection. at first, it attempts to retrieve the */ + /* maximum segment size. later, it might be modified to retrieve */ + /* other information, but it must be information that can be */ + /* retrieved quickly as it is called during the timing of the test. */ + /* for that reason, a second routine may be created that can be */ + /* called outside of the timing loop */ +static +void +get_tcp_info(SOCKET socket, int *mss) +{ + +#ifdef TCP_MAXSEG + netperf_socklen_t sock_opt_len; + + sock_opt_len = sizeof(netperf_socklen_t); + if (getsockopt(socket, + getprotobyname("tcp")->p_proto, + TCP_MAXSEG, + (char *)mss, + &sock_opt_len) == SOCKET_ERROR) { + fprintf(where, + "netperf: get_tcp_info: getsockopt TCP_MAXSEG: errno %d\n", + errno); + fflush(where); + *mss = -1; + } +#else + *mss = -1; +#endif /* TCP_MAXSEG */ +} + + +/* return a pointer to a completed addrinfo chain - prefer + data_address to controlhost and utilize the specified address + family */ + +struct addrinfo * +complete_addrinfo(char *controlhost, char *data_address, char *port, int family, int type, int protocol, int flags) +{ + struct addrinfo hints; + struct addrinfo *res; + struct addrinfo *temp_res; + +#define CHANGED_SOCK_TYPE 0x1 +#define CHANGED_PROTOCOL 0x2 +#define CHANGED_SCTP 0x4 +#define CHANGED_DCCP 0x8 +#define CHANGED_DCCP_SOCK 0x10 + + int change_info = 0; + static int change_warning_displayed = 0; + + int count = 0; + int error = 0; + + char *hostname; + + /* take data-address over controlhost */ + if (data_address) + hostname = data_address; + else + hostname = controlhost; + + if (debug) { + fprintf(where, + "complete_addrinfo using hostname %s port %s family %s type %s prot %s flags 0x%x\n", + hostname, + port, + inet_ftos(family), + inet_ttos(type), + inet_ptos(protocol), + flags); + fflush(where); + } + + memset(&hints, 0, sizeof(hints)); + hints.ai_family = family; + hints.ai_socktype = type; + hints.ai_protocol = protocol; + hints.ai_flags = flags|AI_CANONNAME; + + count = 0; + do { + error = getaddrinfo((char *)hostname, + (char *)port, + &hints, + &res); + count += 1; + if (error == EAI_AGAIN) { + if (debug) { + fprintf(where,"Sleeping on getaddrinfo EAI_AGAIN\n"); + fflush(where); + } + sleep(1); + } + /* while you see this kludge first, it is actually the second, the + first being the one for Solaris below. The need for this kludge + came after implementing the Solaris broken getaddrinfo kludge - + now we see a kludge in Linux getaddrinfo where if it is given + SOCK_STREAM and IPPROTO_SCTP it barfs with a -7 + EAI_SOCKTYPE. so, we check if the error was EAI_SOCKTYPE and if + we were asking for IPPROTO_SCTP and if so, kludge, again... raj + 200?-10-13 and of course, requiring the kludge for SCTP, it is + no surprise that linux needs a kludge for DCCP...actually not + only does it need the ai_protocol kludge, it needs an + ai_socktype kludge too... sigh raj 2008-02-01 */ +#if defined(IPPROTO_SCTP) || defined (IPPROTO_DCCP) + if (EAI_SOCKTYPE == error +#ifdef EAI_BADHINTS + || EAI_BADHINTS == error +#endif + ) { + /* we ass-u-me this is the Linux getaddrinfo bug, clear the + hints.ai_protocol field, and set some state "remembering" + that we did this so the code for the Solaris kludge can do + the fix-up for us. also flip error over to EAI_AGAIN and + make sure we don't "count" this time around the loop. */ +#if defined(IPPROTO_DCCP) + /* only tweak on this one the second time around, after we've + kludged the ai_protocol field */ + if ((hints.ai_socktype == SOCK_DCCP) && + (hints.ai_protocol == 0)) { + change_info |= CHANGED_DCCP_SOCK; + hints.ai_socktype = 0; + /* we need to give it some sort of IPPROTO or it gets unhappy, + so for now, pick one from deep within the colon and use + IPPROTO_TCP */ + hints.ai_protocol = IPPROTO_TCP; + } + + if (hints.ai_protocol == IPPROTO_DCCP) { + change_info |= CHANGED_DCCP; + hints.ai_protocol = 0; + } + +#endif +#if defined(IPPROTO_SCTP) + if (hints.ai_protocol == IPPROTO_SCTP) { + change_info |= CHANGED_SCTP; + hints.ai_protocol = 0; + } +#endif + + error = EAI_AGAIN; + count -= 1; + } +#endif + } while ((error == EAI_AGAIN) && (count <= 5)); + + if (error) { + fprintf(where, + "complete_addrinfo: could not resolve '%s' port '%s' af %d", + hostname, + port, + family); + fprintf(where, + "\n\tgetaddrinfo returned %d %s\n", + error, + gai_strerror(error)); + fflush(where); + exit(-1); + } + + /* there exists at least one platform - Solaris 10 - that does not + seem to completely honor the ai_protocol and/or ai_socktype one + sets in the hints parm to the getaddrinfo call. so, we need to + walk the list of entries returned and if either of those do not + match what we asked for, we need to go ahead and set them + "correctly" this is based in part on some earlier SCTP-only code + from previous revisions. raj 2006-10-09 */ + + temp_res = res; + + while (temp_res) { + + if ((type) && + (temp_res->ai_socktype != type)) { + change_info |= CHANGED_SOCK_TYPE; + if (debug) { + fprintf(where, + "WARNING! Changed bogus getaddrinfo socket type %d to %d\n", + temp_res->ai_socktype, + type); + fflush(where); + } + temp_res->ai_socktype = type; + } + + if ((protocol) && + (temp_res->ai_protocol != protocol)) { + change_info |= CHANGED_PROTOCOL; + if (debug) { + fprintf(where, + "WARNING! Changed bogus getaddrinfo protocol %d to %d\n", + temp_res->ai_protocol, + protocol); + fflush(where); + } + temp_res->ai_protocol = protocol; + } + temp_res = temp_res->ai_next; + } + + if ((change_info & CHANGED_SOCK_TYPE) && + !(change_warning_displayed & CHANGED_SOCK_TYPE)) { + change_warning_displayed |= CHANGED_SOCK_TYPE; + fprintf(where, + "WARNING! getaddrinfo returned a socket type which did not\n"); + fprintf(where, + "match the requested type. Please contact your vendor for\n"); + fprintf(where, + "a fix to this bug in getaddrinfo()\n"); + fflush(where); + } + + /* if we dropped the protocol hint, it would be for a protocol that + getaddrinfo() wasn't supporting yet, not for the bug that it took + our hint and still returned zero. raj 2006-10-16 */ + /* as there is now an open bug against (Open)Solaris (id 6847733) on + this behaviour we will only emit this warning if debug is set + under Solaris and will continue to emit it under any circumstance + on other platforms should it arise. raj 2009-06-03 */ + if ((change_info & CHANGED_PROTOCOL) && + !(change_warning_displayed & CHANGED_PROTOCOL) && +#ifdef __sun + (debug) && +#endif + (hints.ai_protocol != 0)) { + change_warning_displayed |= CHANGED_PROTOCOL; + fprintf(where, + "WARNING! getaddrinfo returned a protocol other than the\n"); + fprintf(where, + "requested protocol. Please contact your vendor for\n"); + fprintf(where, + "a fix to this bug in getaddrinfo()\n"); + fflush(where); + } + + if ((change_info & CHANGED_SCTP) && + !(change_warning_displayed & CHANGED_SCTP)) { + change_warning_displayed |= CHANGED_SCTP; + fprintf(where, + "WARNING! getaddrinfo on this platform does not accept IPPROTO_SCTP!\n"); + fprintf(where, + "Please contact your vendor for a fix to this bug in getaddrinfo().\n"); + fflush(where); + } + + if ((change_info & CHANGED_DCCP) && + !(change_warning_displayed & CHANGED_DCCP)) { + change_warning_displayed |= CHANGED_DCCP; + fprintf(where, + "WARNING! getaddrinfo on this platform does not accept IPPROTO_DCCP!\n"); + fprintf(where, + "Please contact your vendor for a fix to this bug in getaddrinfo().\n"); + fflush(where); + } + + + if (debug) { + dump_addrinfo(where, res, hostname, port, family); + } + + return(res); +} + +void +complete_addrinfos(struct addrinfo **remote,struct addrinfo **local, char remote_host[], int type, int protocol, int flags) { + + *remote = complete_addrinfo(remote_host, + remote_data_address, + remote_data_port, + remote_data_family, + type, + protocol, + flags); + + /* OK, if the user has not specified a local data endpoint address + (test-specific -L), pick the local data endpoint address based on + the remote data family info (test-specific -H or -4 or -6 + option). if the user has not specified remote data addressing + info (test-specific -H, -4 -6) pick something based on the local + control connection address (ie the global -L option). */ + + if (NULL == local_data_address) { + local_data_address = malloc(HOSTNAMESIZE); + if (NULL == remote_data_address) { + if (debug) { + fprintf(where, + "local_data_address not set, using local_host_name of '%s'\n", + local_host_name); + fflush(where); + } + strcpy(local_data_address,local_host_name); + } + else { + if (debug) { + fprintf(where, + "local_data_address not set, using address family info\n"); + fflush(where); + } + /* by default, use 0.0.0.0 - assume IPv4 */ + strcpy(local_data_address,"0.0.0.0"); +#if defined(AF_INET6) + if ((AF_INET6 == local_data_family) || + ((AF_UNSPEC == local_data_family) && + (AF_INET6 == remote_data_family)) || + ((AF_UNSPEC == local_data_family) && + (AF_INET6 == (*remote)->ai_family))) { + strcpy(local_data_address,"::0"); + } +#endif + } + } + + *local = complete_addrinfo("what to put here?", + local_data_address, + local_data_port, + local_data_family, + type, + protocol, + flags|AI_PASSIVE); + + /* OK, at this point, if remote_data_address is NULL, we know that + we used the value of remote_host (the control connection) for the + remote, which means we can/should set remote_data_address to + remote_host so the "omni" output routines can use that global + variable. at least i think I can get away with that :) I'm sure + that at some point I'll find-out that I need to allocate + something for it rather than mess with the pointers, but that can + wait. famous last words of raj 2008-01-25 */ + if (remote_data_address == NULL) + remote_data_address = remote_host; +} + +void +set_hostname_and_port(char *hostname, char *portstr, int family, int port) +{ + strcpy(hostname,"0.0.0.0"); +#if defined AF_INET6 + if (AF_INET6 == family) { + strcpy(hostname,"::0"); + } +#endif + + sprintf(portstr, "%u", port); + +} + +static unsigned short +get_port_number(struct addrinfo *res) +{ + switch(res->ai_family) { + case AF_INET: { + struct sockaddr_in *foo = (struct sockaddr_in *)res->ai_addr; + return(ntohs(foo->sin_port)); + break; + } +#if defined(AF_INET6) + case AF_INET6: { + struct sockaddr_in6 *foo = (struct sockaddr_in6 *)res->ai_addr; + return(ntohs(foo->sin6_port)); + break; + } +#endif + default: + fprintf(where, + "Given Unexpected Address Family of %u\n",res->ai_family); + fflush(where); + exit(-1); + } +} + +static void +extract_inet_address_and_port(struct addrinfo *res, void *addr, int len, int *port) +{ + switch(res->ai_family) { + case AF_INET: { + struct sockaddr_in *foo = (struct sockaddr_in *)res->ai_addr; + *port = foo->sin_port; + memcpy(addr,&(foo->sin_addr),min(len,sizeof(foo->sin_addr))); + break; + } +#if defined(AF_INET6) + case AF_INET6: { + struct sockaddr_in6 *foo = (struct sockaddr_in6 *)res->ai_addr; + *port = foo->sin6_port; + memcpy(addr,&(foo->sin6_addr),min(len,sizeof(foo->sin6_addr))); + break; + } +#endif + default: + *port = 0xDEADBEEF; + strncpy(addr,"UNKN FAMILY",len); + } +} + +/* this routine will set the port number of the sockaddr in the + addrinfo to the specified value, based on the address family */ +void +set_port_number(struct addrinfo *res, unsigned short port) +{ + switch(res->ai_family) { + case AF_INET: { + struct sockaddr_in *foo = (struct sockaddr_in *)res->ai_addr; + foo->sin_port = htons(port); + break; + } +#if defined(AF_INET6) + case AF_INET6: { + struct sockaddr_in6 *foo = (struct sockaddr_in6 *)res->ai_addr; + foo->sin6_port = htons(port); + break; + } +#endif + default: + fprintf(where, + "set_port_number Unexpected Address Family of %u\n",res->ai_family); + fflush(where); + exit(-1); + } +} + +/* stuff the address family, port number and address into a + sockaddr. for now, we will go ahead and zero-out the sockaddr + first */ +void +set_sockaddr_family_addr_port(struct sockaddr_storage *sockaddr, int family, void *addr, int port) { + + memset(sockaddr,0,sizeof(struct sockaddr_storage)); + + switch (family) { + case AF_INET: { + struct sockaddr_in *foo = (struct sockaddr_in *)sockaddr; + foo->sin_port = htons((unsigned short) port); + foo->sin_family = (unsigned short) family; + memcpy(&(foo->sin_addr),addr,sizeof(foo->sin_addr)); + *(int *)addr = htonl(*(int *)addr); + break; + } +#if defined(AF_INET6) + case AF_INET6: { + struct sockaddr_in6 *foo = (struct sockaddr_in6 *)sockaddr; + int *bar; + int i; + foo->sin6_port = htons((unsigned short) port); + foo->sin6_family = (unsigned short) family; + memcpy(&(foo->sin6_addr),addr,sizeof(foo->sin6_addr)); + /* how to put this into "host" order? */ + for (i = sizeof(foo->sin6_addr)/sizeof(int), bar=addr; i > 0; i--) { + bar[i] = htonl(bar[i]); + } + break; + } +#endif + default: + fprintf(where, + "set_sockaddr_family_addr_port Unexpected Address Family of %u\n",family); + fflush(where); + exit(-1); + } +} + +/* pull the port and address out of the sockaddr in host format */ +int +get_sockaddr_family_addr_port(struct sockaddr_storage *sockaddr, int family, void *addr, int *port) +{ + struct sockaddr_in *sin = (struct sockaddr_in *)sockaddr; + + int ret = 0; + if (sin->sin_family != family) { + fprintf(where, + "get_sockaddr_family_addr_port family mismatch %d vs %d\n", + sin->sin_family, + family); + fflush(where); + return -1; + } + + switch(family) { + case AF_INET: { + *port = ntohs(sin->sin_port); + memcpy(addr,&(sin->sin_addr),sizeof(sin->sin_addr)); + if (*(int *)addr == INADDR_ANY) ret = 1; + *(int *)addr = ntohl(*(int *)addr); + break; + } +#ifdef AF_INET6 + case AF_INET6: { + int *foo; + int i; + struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sockaddr; + ret = 0; + *port = ntohs(sin6->sin6_port); + memcpy(addr,&(sin6->sin6_addr), sizeof(sin6->sin6_addr)); + /* how to put this into "host" order? */ + for (i = sizeof(sin6->sin6_addr)/sizeof(int), foo=addr; i > 0; i--) { + if (foo[i] != 0) ret = 1; + foo[i] = ntohl(foo[i]); + } + break; + } +#endif + default: + fprintf(where, + "get_sockaddr_family_addr_port: Unexpected Address Family of %u\n",family); + fflush(where); + exit(-1); + } + return ret; +} + + + /* This routine will create a data (listen) socket with the + apropriate options set and return it to the caller. this replaces + all the duplicate code in each of the test routines and should help + make things a little easier to understand. since this routine can be + called by either the netperf or netserver programs, all output + should be directed towards "where." family is generally AF_INET and + type will be either SOCK_STREAM or SOCK_DGRAM. This routine will + also be used by the "SCTP" tests, hence the slightly strange-looking + SCTP stuff in the classic bsd sockets test file... vlad/raj + 2005-03-15 */ + +SOCKET +create_data_socket(struct addrinfo *res) +{ + + SOCKET temp_socket; + int one; + int on = 1; + + + /*set up the data socket */ + temp_socket = socket(res->ai_family, + res->ai_socktype, + res->ai_protocol); + + if (temp_socket == INVALID_SOCKET){ + fprintf(where, + "netperf: create_data_socket: socket: errno %d fam %s type %s prot %s errmsg %s\n", + errno, + inet_ftos(res->ai_family), + inet_ttos(res->ai_socktype), + inet_ptos(res->ai_protocol), + strerror(errno)); + fflush(where); + exit(1); + } + + if (debug) { + fprintf(where,"create_data_socket: socket %d obtained...\n",temp_socket); + fflush(where); + } + + /* Modify the local socket size. The reason we alter the send buffer + size here rather than when the connection is made is to take care + of decreases in buffer size. Decreasing the window size after + connection establishment is a TCP no-no. Also, by setting the + buffer (window) size before the connection is established, we can + control the TCP MSS (segment size). The MSS is never (well, should + never be) more that 1/2 the minimum receive buffer size at each + half of the connection. This is why we are altering the receive + buffer size on the sending size of a unidirectional transfer. If + the user has not requested that the socket buffers be altered, we + will try to find-out what their values are. If we cannot touch the + socket buffer in any way, we will set the values to -1 to indicate + that. */ + + /* all the oogy nitty gritty stuff moved from here into the routine + being called below, per patches from davidm to workaround the bug + in Linux getsockopt(). raj 2004-06-15 */ + set_sock_buffer (temp_socket, SEND_BUFFER, lss_size_req, &lss_size); + set_sock_buffer (temp_socket, RECV_BUFFER, lsr_size_req, &lsr_size); + + /* now, we may wish to enable the copy avoidance features on the */ + /* local system. of course, this may not be possible... */ + +#ifdef SO_RCV_COPYAVOID + if (loc_rcvavoid) { + if (setsockopt(temp_socket, + SOL_SOCKET, + SO_RCV_COPYAVOID, + (const char *)&loc_rcvavoid, + sizeof(int)) == SOCKET_ERROR) { + fprintf(where, + "netperf: create_data_socket: Could not enable receive copy avoidance"); + fflush(where); + loc_rcvavoid = 0; + } + } +#else + /* it wasn't compiled in... */ + loc_rcvavoid = 0; +#endif /* SO_RCV_COPYAVOID */ + +#ifdef SO_SND_COPYAVOID + if (loc_sndavoid) { + if (setsockopt(temp_socket, + SOL_SOCKET, + SO_SND_COPYAVOID, + (const char *)&loc_sndavoid, + sizeof(int)) == SOCKET_ERROR) { + fprintf(where, + "netperf: create_data_socket: Could not enable send copy avoidance"); + fflush(where); + loc_sndavoid = 0; + } + } +#else + /* it was not compiled in... */ + loc_sndavoid = 0; +#endif + + /* Now, we will see about setting the TCP_NODELAY flag on the local */ + /* socket. We will only do this for those systems that actually */ + /* support the option. If it fails, note the fact, but keep going. */ + /* If the user tries to enable TCP_NODELAY on a UDP socket, this */ + /* will cause an error to be displayed */ + + /* well..... long ago and far away that would have happened, in + particular because we would always use IPPROTO_TCP here. + however, now we are using res->ai_protocol, which will be + IPPROT_UDP, and while HP-UX, and I suspect no-one else on the + planet has a UDP_mumble option that overlaps with TCP_NODELAY, + sure as knuth made little green programs, linux has a UDP_CORK + option that is defined as a value of 1, which is the same a + TCP_NODELAY under Linux. So, when asking for -D and + "TCP_NODELAY" under Linux, we are actually setting UDP_CORK + instead of getting an error like every other OS on the + planet. joy and rupture. this stops a UDP_RR test cold sooo we + have to make sure that res->ai_protocol actually makes sense for + a _NODELAY setsockopt() or a UDP_RR test on Linux where someone + mistakenly sets -D will hang. raj 2005-04-21 */ + +#if defined(TCP_NODELAY) || defined(SCTP_NODELAY) + if ((loc_nodelay) && (res->ai_protocol != IPPROTO_UDP)) { + + /* strictly speaking, since the if defined above is an OR, we + should probably check against TCP_NODELAY being defined here. + however, the likelihood of SCTP_NODELAY being defined and + TCP_NODELAY _NOT_ being defined is, probably :), epsilon. raj + 2005-03-15 */ + + int option = TCP_NODELAY; + + /* I suspect that WANT_SCTP would suffice here since that is the + only time we would have called getaddrinfo with a hints asking + for SCTP, but just in case there is an SCTP implementation out + there _without_ SCTP_NODELAY... raj 2005-03-15 */ + /* change this to IPPROTO_SCTP rather than WANT_SCTP to better fit + with the modus operendi (sp) of the new "omni" tests. raj + 2008-02-04 */ +#if defined(IPPROTO_SCTP) && defined(SCTP_NODELAY) + if (IPPROTO_SCTP == res->ai_protocol) { + option = SCTP_NODELAY; + } +#endif + + one = 1; + if(setsockopt(temp_socket, + res->ai_protocol, + option, + (char *)&one, + sizeof(one)) == SOCKET_ERROR) { + fprintf(where, + "netperf: create_data_socket: nodelay: errno %d\n", + errno); + fflush(where); + } + + if (debug > 1) { + fprintf(where, + "netperf: create_data_socket: [TCP|SCTP]_NODELAY requested...\n"); + fflush(where); + } + } +#else /* TCP_NODELAY */ + + loc_nodelay = 0; + +#endif /* TCP_NODELAY */ + +#if defined(TCP_CORK) + + if (loc_tcpcork > 0) { + /* the user wishes for us to set TCP_CORK on the socket */ + int one = 1; + if (setsockopt(temp_socket, + getprotobyname("tcp")->p_proto, + TCP_CORK, + (char *)&one, + sizeof(one)) == SOCKET_ERROR) { + perror("netperf: create_data_socket: tcp_cork"); + exit(1); + } + if (debug) { + fprintf(where,"create_data_socket: tcp_cork...\n"); + } + } + +#endif /* TCP_CORK */ + + /* since some of the UDP tests do not do anything to cause an + implicit bind() call, we need to be rather explicit about our + bind() call here. even if the address and/or the port are zero + (INADDR_ANY etc). raj 2004-07-20 */ + + if (setsockopt(temp_socket, +#ifdef IPPROTO_DCCP + /* it is REALLY SILLY THAT THIS SHOULD BE NEEDED!! I + should be able to use SOL_SOCKET for this just + like TCP and SCTP */ + /* IT IS EVEN SILLIER THAT THERE COULD BE SYSTEMS + WITH IPPROTO_DCCP and no SOL_DCCP */ +#ifndef SOL_DCCP +#define SOL_DCCP SOL_SOCKET +#define NETPERF_NEED_CLEANUP 1 +#endif + (res->ai_protocol == IPPROTO_DCCP) ? SOL_DCCP : SOL_SOCKET, +#ifdef NETPERF_NEED_CLEANUP +#undef SOL_DCCP +#undef NETPERF_NEED_CLEANUP +#endif + +#else + SOL_SOCKET, +#endif + SO_REUSEADDR, + (const char *)&on, + sizeof(on)) < 0) { + fprintf(where, + "netperf: create_data_socket: SO_REUSEADDR failed %d\n", + errno); + fflush(where); + } + + if (bind(temp_socket, + res->ai_addr, + res->ai_addrlen) < 0) { + if (debug) { + fprintf(where, + "netperf: create_data_socket: data socket bind failed errno %d\n", + errno); + fprintf(where," port: %d\n",get_port_number(res)); + fflush(where); + } + } + + + return(temp_socket); + +} + +#ifdef KLUDGE_SOCKET_OPTIONS + + + /* This routine is for those BROKEN systems which do not correctly */ + /* pass socket attributes through calls such as accept(). It should */ + /* only be called for those broken systems. I *really* don't want to */ + /* have this, but even broken systems must be measured. raj 11/95 */ +void +kludge_socket_options(int temp_socket) +{ + + set_sock_buffer(temp_socket, SEND_BUFFER, lss_size_req, &lss_size); + set_sock_buffer(temp_socket, RECV_BUFFER, lsr_size_req, &lsr_size); + + /* now, we may wish to enable the copy avoidance features on the */ + /* local system. of course, this may not be possible... */ + /* those calls were only valid for HP-UX, and I know that HP-UX is */ + /* written correctly, and so we do not need to include those calls */ + /* in this kludgy routine. raj 11/95 */ + + + /* Now, we will see about setting the TCP_NODELAY flag on the local */ + /* socket. We will only do this for those systems that actually */ + /* support the option. If it fails, note the fact, but keep going. */ + /* If the user tries to enable TCP_NODELAY on a UDP socket, this */ + /* will cause an error to be displayed */ + +#ifdef TCP_NODELAY + if (loc_nodelay) { + one = 1; + if(setsockopt(temp_socket, + getprotobyname("tcp")->p_proto, + TCP_NODELAY, + (char *)&one, + sizeof(one)) == SOCKET_ERROR) { + fprintf(where,"netperf: kludge_socket_options: nodelay: errno %d\n", + errno); + fflush(where); + } + + if (debug > 1) { + fprintf(where, + "netperf: kludge_socket_options: TCP_NODELAY requested...\n"); + fflush(where); + } + } +#else /* TCP_NODELAY */ + + loc_nodelay = 0; + +#endif /* TCP_NODELAY */ + + } + +#endif /* KLUDGE_SOCKET_OPTIONS */ + + +static void * +get_address_address(struct addrinfo *info) +{ + struct sockaddr_in *sin; +#if defined(AF_INET6) + struct sockaddr_in6 *sin6; +#endif + + switch(info->ai_family) { + case AF_INET: + sin = (struct sockaddr_in *)info->ai_addr; + return(&(sin->sin_addr)); + break; +#if defined(AF_INET6) + case AF_INET6: + sin6 = (struct sockaddr_in6 *)info->ai_addr; + return(&(sin6->sin6_addr)); + break; +#endif + default: + fprintf(stderr,"we never expected to get here in get_address_address\n"); + fflush(stderr); + exit(-1); + } +} + +#if defined(WIN32) +#if !defined(InetNtop) +/* +*+ Why isn't this in the winsock headers yet? */ +const char * +inet_ntop(int af, const void *src, char *dst, size_t size); +#endif +#endif + +/* This routine is a generic test header printer for the topmost header */ +void +print_top_test_header(char test_name[], struct addrinfo *source, struct addrinfo *destination) +{ + +#if defined(AF_INET6) + char address_buf[INET6_ADDRSTRLEN]; +#else + char address_buf[16]; /* magic constant */ +#endif + + /* we want to have some additional, interesting information in */ + /* the headers. we know some of it here, but not all, so we will */ + /* only print the test title here and will print the results */ + /* titles after the test is finished */ + fprintf(where,test_name); + address_buf[0] = '\0'; + inet_ntop(source->ai_family,get_address_address(source),address_buf,sizeof(address_buf)); + fprintf(where, + " from %s (%s) port %u %s", + source->ai_canonname, + address_buf, + get_port_number(source), + inet_ftos(source->ai_family)); + address_buf[0] = '\0'; + inet_ntop(destination->ai_family,get_address_address(destination),address_buf,sizeof(address_buf)); + fprintf(where, + " to %s (%s) port %u %s", + destination->ai_canonname, + address_buf, + get_port_number(destination), + inet_ftos(destination->ai_family)); + + if (iteration_max > 1) { + fprintf(where, + " : +/-%.3f%% @ %2d%% conf. %s", + interval/0.02, + confidence_level, + result_confidence_only ? " on result only" : ""); + } + if ((loc_nodelay > 0) || (rem_nodelay > 0)) { + fprintf(where," : nodelay"); + } + if ((loc_sndavoid > 0) || + (loc_rcvavoid > 0) || + (rem_sndavoid > 0) || + (rem_rcvavoid > 0)) { + fprintf(where," : copy avoidance"); + } + + if (no_control) { + fprintf(where," : no control"); + } + +#ifdef WANT_HISTOGRAM + fprintf(where," : histogram"); +#endif /* WANT_HISTOGRAM */ + +#ifdef WANT_INTERVALS +#ifndef WANT_SPIN + fprintf(where," : interval"); +#else + fprintf(where," : spin interval"); +#endif +#endif /* WANT_INTERVALS */ + +#ifdef DIRTY + fprintf(where," : dirty data"); +#endif /* DIRTY */ +#ifdef WANT_DEMO + fprintf(where," : demo"); +#endif +#ifdef WANT_FIRST_BURST + /* a little hokey perhaps, but we really only want this to be + emitted for tests where it actually is used, which means a + "REQUEST/RESPONSE" test. raj 2005-11-10 */ + if (strstr(test_name,"REQUEST/RESPONSE")) { + fprintf(where," : first burst %d",first_burst_size); + } +#endif + if (cpu_binding_requested) { + fprintf(where," : cpu bind"); + } + fprintf(where,"\n"); + +} + + +/* This routine implements the TCP unidirectional data transfer test */ +/* (a.k.a. stream) for the sockets interface. It receives its */ +/* parameters via global variables from the shell and writes its */ +/* output to the standard output. */ + + +void +send_tcp_stream(char remote_host[]) +{ + + char *tput_title = "\ +Recv Send Send \n\ +Socket Socket Message Elapsed \n\ +Size Size Size Time Throughput \n\ +bytes bytes bytes secs. %s/sec \n\n"; + + char *tput_fmt_0 = + "%7.2f %s\n"; + + char *tput_fmt_1 = + "%6d %6d %6d %-6.2f %7.2f %s\n"; + + char *cpu_title = "\ +Recv Send Send Utilization Service Demand\n\ +Socket Socket Message Elapsed Send Recv Send Recv\n\ +Size Size Size Time Throughput local remote local remote\n\ +bytes bytes bytes secs. %-8.8s/s %% %c %% %c us/KB us/KB\n\n"; + + char *cpu_fmt_0 = + "%6.3f %c %s\n"; + + char *cpu_fmt_1 = + "%6d %6d %6d %-6.2f %7.2f %-6.2f %-6.2f %-6.3f %-6.3f %s\n"; + + char *ksink_fmt = "\n\ +Alignment Offset %-8.8s %-8.8s Sends %-8.8s Recvs\n\ +Local Remote Local Remote Xfered Per Per\n\ +Send Recv Send Recv Send (avg) Recv (avg)\n\ +%5d %5d %5d %5d %6.4g %6.2f %6d %6.2f %6d\n"; + + char *ksink_fmt2 = "\n\ +Maximum\n\ +Segment\n\ +Size (bytes)\n\ +%6d\n"; + + + float elapsed_time; + + /* what we want is to have a buffer space that is at least one */ + /* send-size greater than our send window. this will insure that we */ + /* are never trying to re-use a buffer that may still be in the hands */ + /* of the transport. This buffer will be malloc'd after we have found */ + /* the size of the local senc socket buffer. We will want to deal */ + /* with alignment and offset concerns as well. */ + + struct ring_elt *send_ring; + + int len; + unsigned int nummessages = 0; + SOCKET send_socket; + int bytes_remaining; + int tcp_mss = -1; /* possibly uninitialized on printf far below */ + + /* with links like fddi, one can send > 32 bits worth of bytes */ + /* during a test... ;-) at some point, this should probably become a */ + /* 64bit integral type, but those are not entirely common yet */ + + unsigned long long local_bytes_sent = 0; + double bytes_sent = 0.0; + + float local_cpu_utilization; + float local_service_demand; + float remote_cpu_utilization; + float remote_service_demand; + + double thruput; + + struct addrinfo *remote_res; + struct addrinfo *local_res; + + struct tcp_stream_request_struct *tcp_stream_request; + struct tcp_stream_response_struct *tcp_stream_response; + struct tcp_stream_results_struct *tcp_stream_result; + + tcp_stream_request = + (struct tcp_stream_request_struct *)netperf_request.content.test_specific_data; + tcp_stream_response = + (struct tcp_stream_response_struct *)netperf_response.content.test_specific_data; + tcp_stream_result = + (struct tcp_stream_results_struct *)netperf_response.content.test_specific_data; + +#ifdef WANT_HISTOGRAM + if (verbosity > 1) { + time_hist = HIST_new(); + } +#endif /* WANT_HISTOGRAM */ + /* since we are now disconnected from the code that established the */ + /* control socket, and since we want to be able to use different */ + /* protocols and such, we are passed the name of the remote host and */ + /* must turn that into the test specific addressing information. */ + + /* complete_addrinfos will either succede or exit the process */ + complete_addrinfos(&remote_res, + &local_res, + remote_host, + SOCK_STREAM, + IPPROTO_TCP, + 0); + + if ( print_headers ) { + print_top_test_header("TCP STREAM TEST",local_res,remote_res); + } + + send_ring = NULL; + confidence_iteration = 1; + init_stat(); + + /* we have a great-big while loop which controls the number of times */ + /* we run a particular test. this is for the calculation of a */ + /* confidence interval (I really should have stayed awake during */ + /* probstats :). If the user did not request confidence measurement */ + /* (no confidence is the default) then we will only go though the */ + /* loop once. the confidence stuff originates from the folks at IBM */ + + while (((confidence < 0) && (confidence_iteration < iteration_max)) || + (confidence_iteration <= iteration_min)) { + + /* initialize a few counters. we have to remember that we might be */ + /* going through the loop more than once. */ + + nummessages = 0; + bytes_sent = 0.0; + times_up = 0; + + /*set up the data socket */ + send_socket = create_data_socket(local_res); + + if (send_socket == INVALID_SOCKET){ + perror("netperf: send_tcp_stream: tcp stream data socket"); + exit(1); + } + + if (debug) { + fprintf(where,"send_tcp_stream: send_socket obtained...\n"); + } + + /* at this point, we have either retrieved the socket buffer sizes, */ + /* or have tried to set them, so now, we may want to set the send */ + /* size based on that (because the user either did not use a -m */ + /* option, or used one with an argument of 0). If the socket buffer */ + /* size is not available, we will set the send size to 4KB - no */ + /* particular reason, just arbitrary... */ + if (send_size == 0) { + if (lss_size > 0) { + send_size = lss_size; + } + else { + send_size = 4096; + } + } + + /* set-up the data buffer ring with the requested alignment and offset. */ + /* note also that we have allocated a quantity */ + /* of memory that is at least one send-size greater than our socket */ + /* buffer size. We want to be sure that there are at least two */ + /* buffers allocated - this can be a bit of a problem when the */ + /* send_size is bigger than the socket size, so we must check... the */ + /* user may have wanted to explicitly set the "width" of our send */ + /* buffers, we should respect that wish... */ + if (send_width == 0) { + send_width = (lss_size/send_size) + 1; + if (send_width == 1) send_width++; + } + + if (send_ring == NULL) { + /* only allocate the send ring once. this is a networking test, */ + /* not a memory allocation test. this way, we do not need a */ + /* deallocate_buffer_ring() routine, and I don't feel like */ + /* writing one anyway :) raj 11/94 */ + send_ring = allocate_buffer_ring(send_width, + send_size, + local_send_align, + local_send_offset); + } + + /* If the user has requested cpu utilization measurements, we must */ + /* calibrate the cpu(s). We will perform this task within the tests */ + /* themselves. If the user has specified the cpu rate, then */ + /* calibrate_local_cpu will return rather quickly as it will have */ + /* nothing to do. If local_cpu_rate is zero, then we will go through */ + /* all the "normal" calibration stuff and return the rate back. */ + + if (local_cpu_usage) { + local_cpu_rate = calibrate_local_cpu(local_cpu_rate); + } + + if (!no_control) { + /* Tell the remote end to do a listen. The server alters the + socket paramters on the other side at this point, hence the + reason for all the values being passed in the setup + message. If the user did not specify any of the parameters, + they will be passed as 0, which will indicate to the remote + that no changes beyond the system's default should be + used. Alignment is the exception, it will default to 1, which + will be no alignment alterations. */ + + netperf_request.content.request_type = DO_TCP_STREAM; + tcp_stream_request->send_buf_size = rss_size_req; + tcp_stream_request->recv_buf_size = rsr_size_req; + tcp_stream_request->receive_size = recv_size; + tcp_stream_request->no_delay = rem_nodelay; + tcp_stream_request->recv_alignment = remote_recv_align; + tcp_stream_request->recv_offset = remote_recv_offset; + tcp_stream_request->measure_cpu = remote_cpu_usage; + tcp_stream_request->cpu_rate = remote_cpu_rate; + if (test_time) { + tcp_stream_request->test_length = test_time; + } + else { + tcp_stream_request->test_length = test_bytes; + } + tcp_stream_request->so_rcvavoid = rem_rcvavoid; + tcp_stream_request->so_sndavoid = rem_sndavoid; +#ifdef DIRTY + tcp_stream_request->dirty_count = rem_dirty_count; + tcp_stream_request->clean_count = rem_clean_count; +#endif /* DIRTY */ + tcp_stream_request->port = atoi(remote_data_port); + tcp_stream_request->ipfamily = af_to_nf(remote_res->ai_family); + if (debug > 1) { + fprintf(where, + "netperf: send_tcp_stream: requesting TCP stream test\n"); + } + + send_request(); + + /* The response from the remote will contain all of the relevant + socket parameters for this test type. We will put them back + into the variables here so they can be displayed if desired. + The remote will have calibrated CPU if necessary, and will + have done all the needed set-up we will have calibrated the + cpu locally before sending the request, and will grab the + counter value right after the connect returns. The remote + will grab the counter right after the accept call. This saves + the hassle of extra messages being sent for the TCP + tests. */ + + recv_response(); + + if (!netperf_response.content.serv_errno) { + if (debug) + fprintf(where,"remote listen done.\n"); + rsr_size = tcp_stream_response->recv_buf_size; + rss_size = tcp_stream_response->send_buf_size; + rem_nodelay = tcp_stream_response->no_delay; + remote_cpu_usage= tcp_stream_response->measure_cpu; + remote_cpu_rate = tcp_stream_response->cpu_rate; + + /* we have to make sure that the server port number is in + network order */ + set_port_number(remote_res, + (short)tcp_stream_response->data_port_number); + + rem_rcvavoid = tcp_stream_response->so_rcvavoid; + rem_sndavoid = tcp_stream_response->so_sndavoid; + } + else { + Set_errno(netperf_response.content.serv_errno); + fprintf(where, + "netperf: remote error %d", + netperf_response.content.serv_errno); + perror(""); + fflush(where); + + exit(1); + } + } + +#ifdef WANT_DEMO + DEMO_STREAM_SETUP(lss_size,rsr_size) +#endif + + /*Connect up to the remote port on the data socket */ + if (connect(send_socket, + remote_res->ai_addr, + remote_res->ai_addrlen) == INVALID_SOCKET){ + perror("netperf: send_tcp_stream: data socket connect failed"); + exit(1); + } + +#ifdef WIN32 + /* this is used so the timer thread can close the socket out from */ + /* under us, which to date is the easiest/cleanest/least */ + /* Windows-specific way I can find to force the winsock calls to */ + /* return WSAEINTR with the test is over. anything that will run on */ + /* 95 and NT and is closer to what netperf expects from Unix signals */ + /* and such would be appreciated raj 1/96 */ + win_kludge_socket = send_socket; +#endif /* WIN32 */ + + /* Data Socket set-up is finished. If there were problems, either */ + /* the connect would have failed, or the previous response would */ + /* have indicated a problem. I failed to see the value of the */ + /* extra message after the accept on the remote. If it failed, */ + /* we'll see it here. If it didn't, we might as well start pumping */ + /* data. */ + + /* Set-up the test end conditions. For a stream test, they can be */ + /* either time or byte-count based. */ + + if (test_time) { + /* The user wanted to end the test after a period of time. */ + times_up = 0; + bytes_remaining = 0; + /* in previous revisions, we had the same code repeated throught */ + /* all the test suites. this was unnecessary, and meant more */ + /* work for me when I wanted to switch to POSIX signals, so I */ + /* have abstracted this out into a routine in netlib.c. if you */ + /* are experiencing signal problems, you might want to look */ + /* there. raj 11/94 */ + start_timer(test_time); + } + else { + /* The tester wanted to send a number of bytes. */ + bytes_remaining = test_bytes; + times_up = 1; + } + + /* The cpu_start routine will grab the current time and possibly */ + /* value of the idle counter for later use in measuring cpu */ + /* utilization and/or service demand and thruput. */ + + cpu_start(local_cpu_usage); + + /* we only start the interval timer if we are using the + timer-timed intervals rather than the sit and spin ones. raj + 2006-02-06 */ +#if defined(WANT_INTERVALS) + INTERVALS_INIT(); +#endif /* WANT_INTERVALS */ + + /* before we start, initialize a few variables */ + +#ifdef WANT_DEMO + if (demo_mode) { + HIST_timestamp(demo_one_ptr); + } +#endif + + + /* We use an "OR" to control test execution. When the test is */ + /* controlled by time, the byte count check will always return false. */ + /* When the test is controlled by byte count, the time test will */ + /* always return false. When the test is finished, the whole */ + /* expression will go false and we will stop sending data. */ + + while ((!times_up) || (bytes_remaining > 0)) { + +#ifdef DIRTY + access_buffer(send_ring->buffer_ptr, + send_size, + loc_dirty_count, + loc_clean_count); +#endif /* DIRTY */ + +#ifdef WANT_HISTOGRAM + if (verbosity > 1) { + /* timestamp just before we go into send and then again just + after we come out raj 8/94 */ + /* but lets only do this if there is going to be a histogram + displayed */ + HIST_timestamp(&time_one); + } +#endif /* WANT_HISTOGRAM */ + + if((len=send(send_socket, + send_ring->buffer_ptr, + send_size, + 0)) != send_size) { + if ((len >=0) || SOCKET_EINTR(len)) { + /* the test was interrupted, must be the end of test */ + break; + } + perror("netperf: data send error"); + printf("len was %d\n",len); + exit(1); + } + + local_bytes_sent += send_size; + +#ifdef WANT_HISTOGRAM + if (verbosity > 1) { + /* timestamp the exit from the send call and update the histogram */ + HIST_timestamp(&time_two); + HIST_add(time_hist,delta_micro(&time_one,&time_two)); + } +#endif /* WANT_HISTOGRAM */ + +#ifdef WANT_DEMO + DEMO_STREAM_INTERVAL(send_size) +#endif + +#if defined(WANT_INTERVALS) + INTERVALS_WAIT(); +#endif /* WANT_INTERVALS */ + + /* now we want to move our pointer to the next position in the */ + /* data buffer...we may also want to wrap back to the "beginning" */ + /* of the bufferspace, so we will mod the number of messages sent */ + /* by the send width, and use that to calculate the offset to add */ + /* to the base pointer. */ + nummessages++; + send_ring = send_ring->next; + if (bytes_remaining) { + bytes_remaining -= send_size; + } + } + + /* The test is over. Flush the buffers to the remote end. We do a */ + /* graceful release to insure that all data has been taken by the */ + /* remote. */ + + /* but first, if the verbosity is greater than 1, find-out what */ + /* the TCP maximum segment_size was (if possible) */ + if (verbosity > 1) { + tcp_mss = -1; + get_tcp_info(send_socket,&tcp_mss); + } + + if (shutdown(send_socket,SHUT_WR) == SOCKET_ERROR) { + perror("netperf: cannot shutdown tcp stream socket"); + exit(1); + } + + /* hang a recv() off the socket to block until the remote has */ + /* brought all the data up into the application. it will do a */ + /* shutdown to cause a FIN to be sent our way. We will assume that */ + /* any exit from the recv() call is good... raj 4/93 */ + + recv(send_socket, send_ring->buffer_ptr, send_size, 0); + + /* this call will always give us the elapsed time for the test, and */ + /* will also store-away the necessaries for cpu utilization */ + + cpu_stop(local_cpu_usage,&elapsed_time); /* was cpu being */ + /* measured and how */ + /* long did we really */ + /* run? */ + + /* we are finished with the socket, so close it to prevent hitting */ + /* the limit on maximum open files. */ + + close(send_socket); + + if (!no_control) { + /* Get the statistics from the remote end. The remote will have + calculated service demand and all those interesting + things. If it wasn't supposed to care, it will return obvious + values. */ + + recv_response(); + if (!netperf_response.content.serv_errno) { + if (debug) + fprintf(where, + "remote reporting results for %.2f seconds\n", + tcp_stream_result->elapsed_time); + } + else { + Set_errno(netperf_response.content.serv_errno); + fprintf(where, + "netperf: remote error %d", + netperf_response.content.serv_errno); + perror(""); + fflush(where); + + exit(1); + } + + /* We now calculate what our thruput was for the test. In the + future, we may want to include a calculation of the thruput + measured by the remote, but it should be the case that for a + TCP stream test, that the two numbers should be *very* + close... We calculate bytes_sent regardless of the way the + test length was controlled. If it was time, we needed to, + and if it was by bytes, the user may have specified a number + of bytes that wasn't a multiple of the send_size, so we + really didn't send what he asked for ;-) */ + + bytes_sent = ntohd(tcp_stream_result->bytes_received); + } + else { + bytes_sent = (double)local_bytes_sent; + } + + thruput = calc_thruput(bytes_sent); + + if (local_cpu_usage || remote_cpu_usage) { + /* We must now do a little math for service demand and cpu */ + /* utilization for the system(s) */ + /* Of course, some of the information might be bogus because */ + /* there was no idle counter in the kernel(s). We need to make */ + /* a note of this for the user's benefit...*/ + if (local_cpu_usage) { + + local_cpu_utilization = calc_cpu_util(0.0); + local_service_demand = calc_service_demand(bytes_sent, + 0.0, + 0.0, + 0); + } + else { + local_cpu_utilization = (float) -1.0; + local_service_demand = (float) -1.0; + } + + if (remote_cpu_usage) { + + remote_cpu_utilization = tcp_stream_result->cpu_util; + remote_service_demand = calc_service_demand(bytes_sent, + 0.0, + remote_cpu_utilization, + tcp_stream_result->num_cpus); + } + else { + remote_cpu_utilization = (float) -1.0; + remote_service_demand = (float) -1.0; + } + } + else { + /* we were not measuring cpu, for the confidence stuff, we */ + /* should make it -1.0 */ + local_cpu_utilization = (float) -1.0; + local_service_demand = (float) -1.0; + remote_cpu_utilization = (float) -1.0; + remote_service_demand = (float) -1.0; + } + + /* at this point, we want to calculate the confidence information. */ + /* if debugging is on, calculate_confidence will print-out the */ + /* parameters we pass it */ + + calculate_confidence(confidence_iteration, + elapsed_time, + thruput, + local_cpu_utilization, + remote_cpu_utilization, + local_service_demand, + remote_service_demand); + + + confidence_iteration++; + } + + /* at this point, we have finished making all the runs that we */ + /* will be making. so, we should extract what the calcuated values */ + /* are for all the confidence stuff. we could make the values */ + /* global, but that seemed a little messy, and it did not seem worth */ + /* all the mucking with header files. so, we create a routine much */ + /* like calcualte_confidence, which just returns the mean values. */ + /* raj 11/94 */ + + retrieve_confident_values(&elapsed_time, + &thruput, + &local_cpu_utilization, + &remote_cpu_utilization, + &local_service_demand, + &remote_service_demand); + + /* We are now ready to print all the information. If the user */ + /* has specified zero-level verbosity, we will just print the */ + /* local service demand, or the remote service demand. If the */ + /* user has requested verbosity level 1, he will get the basic */ + /* "streamperf" numbers. If the user has specified a verbosity */ + /* of greater than 1, we will display a veritable plethora of */ + /* background information from outside of this block as it it */ + /* not cpu_measurement specific... */ + + if (confidence < 0) { + /* we did not hit confidence, but were we asked to look for it? */ + if (iteration_max > 1) { + display_confidence(); + } + } + + if (local_cpu_usage || remote_cpu_usage) { + local_cpu_method = format_cpu_method(cpu_method); + remote_cpu_method = format_cpu_method(tcp_stream_result->cpu_method); + + switch (verbosity) { + case 0: + if (local_cpu_usage) { + fprintf(where, + cpu_fmt_0, + local_service_demand, + local_cpu_method, + ((print_headers) || + (result_brand == NULL)) ? "" : result_brand); + } + else { + fprintf(where, + cpu_fmt_0, + remote_service_demand, + remote_cpu_method, + ((print_headers) || + (result_brand == NULL)) ? "" : result_brand); + } + break; + case 1: + case 2: + if (print_headers) { + fprintf(where, + cpu_title, + format_units(), + local_cpu_method, + remote_cpu_method); + } + + fprintf(where, + cpu_fmt_1, /* the format string */ + rsr_size, /* remote recvbuf size */ + lss_size, /* local sendbuf size */ + send_size, /* how large were the sends */ + elapsed_time, /* how long was the test */ + thruput, /* what was the xfer rate */ + local_cpu_utilization, /* local cpu */ + remote_cpu_utilization, /* remote cpu */ + local_service_demand, /* local service demand */ + remote_service_demand, /* remote service demand */ + ((print_headers) || + (result_brand == NULL)) ? "" : result_brand); + break; + } + } + else { + /* The tester did not wish to measure service demand. */ + + switch (verbosity) { + case 0: + fprintf(where, + tput_fmt_0, + thruput, + ((print_headers) || + (result_brand == NULL)) ? "" : result_brand); + break; + case 1: + case 2: + if (print_headers) { + fprintf(where,tput_title,format_units()); + } + fprintf(where, + tput_fmt_1, /* the format string */ + rsr_size, /* remote recvbuf size */ + lss_size, /* local sendbuf size */ + send_size, /* how large were the sends */ + elapsed_time, /* how long did it take */ + thruput, /* how fast did it go */ + ((print_headers) || + (result_brand == NULL)) ? "" : result_brand); + break; + } + } + + /* it would be a good thing to include information about some of the */ + /* other parameters that may have been set for this test, but at the */ + /* moment, I do not wish to figure-out all the formatting, so I will */ + /* just put this comment here to help remind me that it is something */ + /* that should be done at a later time. */ + + if (verbosity > 1) { + /* The user wanted to know it all, so we will give it to him. */ + /* This information will include as much as we can find about */ + /* TCP statistics, the alignments of the sends and receives */ + /* and all that sort of rot... */ + + /* this stuff needs to be worked-out in the presence of confidence */ + /* intervals and multiple iterations of the test... raj 11/94 */ + + fprintf(where, + ksink_fmt, + "Bytes", + "Bytes", + "Bytes", + local_send_align, + remote_recv_align, + local_send_offset, + remote_recv_offset, + bytes_sent, + bytes_sent / (double)nummessages, + nummessages, + bytes_sent / (double)tcp_stream_result->recv_calls, + tcp_stream_result->recv_calls); + fprintf(where, + ksink_fmt2, + tcp_mss); + fflush(where); +#ifdef WANT_HISTOGRAM + fprintf(where,"\n\nHistogram of time spent in send() call.\n"); + fflush(where); + HIST_report(time_hist); +#endif /* WANT_HISTOGRAM */ + } + +} + + + +/* This routine implements the netperf-side TCP unidirectional data + transfer test (a.k.a. stream) for the sockets interface where the + data flow is from the netserver to the netperf. It receives its + parameters via global variables from the shell and writes its + output to the standard output. */ + + +void +send_tcp_maerts(char remote_host[]) +{ + + char *tput_title = "\ +Recv Send Send \n\ +Socket Socket Message Elapsed \n\ +Size Size Size Time Throughput \n\ +bytes bytes bytes secs. %s/sec \n\n"; + + char *tput_fmt_0 = + "%7.2f %s\n"; + + char *tput_fmt_1 = + "%6d %6d %6d %-6.2f %7.2f %s\n"; + + char *cpu_title = "\ +Recv Send Send Utilization Service Demand\n\ +Socket Socket Message Elapsed Recv Send Recv Send\n\ +Size Size Size Time Throughput local remote local remote\n\ +bytes bytes bytes secs. %-8.8s/s %% %c %% %c us/KB us/KB\n\n"; + + char *cpu_fmt_0 = + "%6.3f %c %s\n"; + + char *cpu_fmt_1 = + "%6d %6d %6d %-6.2f %7.2f %-6.2f %-6.2f %-6.3f %-6.3f %s\n"; + + char *ksink_fmt = "\n\ +Alignment Offset %-8.8s %-8.8s Recvs %-8.8s Sends\n\ +Local Remote Local Remote Xfered Per Per\n\ +Recv Send Recv Send Recv (avg) Send (avg)\n\ +%5d %5d %5d %5d %6.4g %6.2f %6d %6.2f %6d\n"; + + char *ksink_fmt2 = "\n\ +Maximum\n\ +Segment\n\ +Size (bytes)\n\ +%6d\n"; + + + float elapsed_time; + + /* what we want is to have a buffer space that is at least one */ + /* recv-size greater than our recv window. this will insure that we */ + /* are never trying to re-use a buffer that may still be in the hands */ + /* of the transport. This buffer will be malloc'd after we have found */ + /* the size of the local senc socket buffer. We will want to deal */ + /* with alignment and offset concerns as well. */ + + struct ring_elt *recv_ring; + + int len; + unsigned int nummessages = 0; + SOCKET recv_socket; + int bytes_remaining; + int tcp_mss = -1; /* possibly uninitialized on printf far below */ + + /* with links like fddi, one can recv > 32 bits worth of bytes */ + /* during a test... ;-) at some point, this should probably become a */ + /* 64bit integral type, but those are not entirely common yet */ + double bytes_sent = 0.0; + unsigned long long local_bytes_recvd = 0; + + float local_cpu_utilization; + float local_service_demand; + float remote_cpu_utilization; + float remote_service_demand; + + double thruput; + + struct addrinfo *remote_res; + struct addrinfo *local_res; + + struct tcp_maerts_request_struct *tcp_maerts_request; + struct tcp_maerts_response_struct *tcp_maerts_response; + struct tcp_maerts_results_struct *tcp_maerts_result; + + tcp_maerts_request = + (struct tcp_maerts_request_struct *)netperf_request.content.test_specific_data; + tcp_maerts_response = + (struct tcp_maerts_response_struct *)netperf_response.content.test_specific_data; + tcp_maerts_result = + (struct tcp_maerts_results_struct *)netperf_response.content.test_specific_data; + +#ifdef WANT_HISTOGRAM + if (verbosity > 1) { + time_hist = HIST_new(); + } +#endif /* WANT_HISTOGRAM */ + /* since we are now disconnected from the code that established the */ + /* control socket, and since we want to be able to use different */ + /* protocols and such, we are passed the name of the remote host and */ + /* must turn that into the test specific addressing information. */ + + complete_addrinfos(&remote_res, + &local_res, + remote_host, + SOCK_STREAM, + IPPROTO_TCP, + 0); + + if ( print_headers ) { + print_top_test_header("TCP MAERTS TEST",local_res,remote_res); + } + + recv_ring = NULL; + confidence_iteration = 1; + init_stat(); + + /* we have a great-big while loop which controls the number of times */ + /* we run a particular test. this is for the calculation of a */ + /* confidence interval (I really should have stayed awake during */ + /* probstats :). If the user did not request confidence measurement */ + /* (no confidence is the default) then we will only go though the */ + /* loop once. the confidence stuff originates from the folks at IBM */ + + while (((confidence < 0) && (confidence_iteration < iteration_max)) || + (confidence_iteration <= iteration_min)) { + + /* initialize a few counters. we have to remember that we might be */ + /* going through the loop more than once. */ + + nummessages = 0; + bytes_sent = 0.0; + times_up = 0; + + /*set up the data socket */ + recv_socket = create_data_socket(local_res); + + if (recv_socket == INVALID_SOCKET){ + perror("netperf: send_tcp_maerts: tcp stream data socket"); + exit(1); + } + + if (debug) { + fprintf(where,"send_tcp_maerts: recv_socket obtained...\n"); + } + + /* at this point, we have either retrieved the socket buffer sizes, */ + /* or have tried to set them, so now, we may want to set the recv */ + /* size based on that (because the user either did not use a -m */ + /* option, or used one with an argument of 0). If the socket buffer */ + /* size is not available, we will set the recv size to 4KB - no */ + /* particular reason, just arbitrary... */ + if (recv_size == 0) { + if (lsr_size > 0) { + recv_size = lsr_size; + } + else { + recv_size = 4096; + } + } + + /* set-up the data buffer ring with the requested alignment and offset. */ + /* note also that we have allocated a quantity */ + /* of memory that is at least one recv-size greater than our socket */ + /* buffer size. We want to be sure that there are at least two */ + /* buffers allocated - this can be a bit of a problem when the */ + /* recv_size is bigger than the socket size, so we must check... the */ + /* user may have wanted to explicitly set the "width" of our recv */ + /* buffers, we should respect that wish... */ + if (recv_width == 0) { + recv_width = (lsr_size/recv_size) + 1; + if (recv_width == 1) recv_width++; + } + + if (recv_ring == NULL) { + /* only allocate the recv ring once. this is a networking test, */ + /* not a memory allocation test. this way, we do not need a */ + /* deallocate_buffer_ring() routine, and I don't feel like */ + /* writing one anyway :) raj 11/94 */ + recv_ring = allocate_buffer_ring(recv_width, + recv_size, + local_recv_align, + local_recv_offset); + } + + /* If the user has requested cpu utilization measurements, we must */ + /* calibrate the cpu(s). We will perform this task within the tests */ + /* themselves. If the user has specified the cpu rate, then */ + /* calibrate_local_cpu will return rather quickly as it will have */ + /* nothing to do. If local_cpu_rate is zero, then we will go through */ + /* all the "normal" calibration stuff and return the rate back. */ + + if (local_cpu_usage) { + local_cpu_rate = calibrate_local_cpu(local_cpu_rate); + } + + if (!no_control) { + /* Tell the remote end to do a listen. The server alters the + socket paramters on the other side at this point, hence the + reason for all the values being passed in the setup + message. If the user did not specify any of the parameters, + they will be passed as 0, which will indicate to the remote + that no changes beyond the system's default should be + used. Alignment is the exception, it will default to 1, which + will be no alignment alterations. */ + + netperf_request.content.request_type = DO_TCP_MAERTS; + tcp_maerts_request->send_buf_size = rss_size_req; + tcp_maerts_request->recv_buf_size = rsr_size_req; + tcp_maerts_request->send_size = send_size; + tcp_maerts_request->no_delay = rem_nodelay; + tcp_maerts_request->send_alignment = remote_send_align; + tcp_maerts_request->send_offset = remote_send_offset; + tcp_maerts_request->measure_cpu = remote_cpu_usage; + tcp_maerts_request->cpu_rate = remote_cpu_rate; + if (test_time) { + tcp_maerts_request->test_length = test_time; + } + else { + tcp_maerts_request->test_length = test_bytes; + } + tcp_maerts_request->so_rcvavoid = rem_rcvavoid; + tcp_maerts_request->so_sndavoid = rem_sndavoid; +#ifdef DIRTY + tcp_maerts_request->dirty_count = rem_dirty_count; + tcp_maerts_request->clean_count = rem_clean_count; +#endif /* DIRTY */ + tcp_maerts_request->port = atoi(remote_data_port); + tcp_maerts_request->ipfamily = af_to_nf(remote_res->ai_family); + if (debug > 1) { + fprintf(where, + "netperf: send_tcp_maerts: requesting TCP maerts test\n"); + } + + send_request(); + + /* The response from the remote will contain all of the relevant + socket parameters for this test type. We will put them back + into the variables here so they can be displayed if desired. + The remote will have calibrated CPU if necessary, and will + have done all the needed set-up we will have calibrated the + cpu locally before sending the request, and will grab the + counter value right after the connect returns. The remote + will grab the counter right after the accept call. This saves + the hassle of extra messages being sent for the TCP + tests. */ + + recv_response(); + + if (!netperf_response.content.serv_errno) { + if (debug) + fprintf(where,"remote listen done.\n"); + rsr_size = tcp_maerts_response->recv_buf_size; + rss_size = tcp_maerts_response->send_buf_size; + rem_nodelay = tcp_maerts_response->no_delay; + remote_cpu_usage= tcp_maerts_response->measure_cpu; + remote_cpu_rate = tcp_maerts_response->cpu_rate; + send_size = tcp_maerts_response->send_size; + + /* we have to make sure that the server port number is in + network order */ + set_port_number(remote_res, + (short)tcp_maerts_response->data_port_number); + rem_rcvavoid = tcp_maerts_response->so_rcvavoid; + rem_sndavoid = tcp_maerts_response->so_sndavoid; + } + else { + Set_errno(netperf_response.content.serv_errno); + fprintf(where, + "netperf: remote error %d", + netperf_response.content.serv_errno); + perror(""); + fflush(where); + + exit(1); + } + } + +#ifdef WANT_DEMO + DEMO_STREAM_SETUP(lsr_size,rss_size) +#endif + + /*Connect up to the remote port on the data socket */ + if (connect(recv_socket, + remote_res->ai_addr, + remote_res->ai_addrlen) == INVALID_SOCKET){ + perror("netperf: send_tcp_maerts: data socket connect failed"); + exit(1); + } + +#ifdef WIN32 + /* this is used so the timer thread can close the socket out from */ + /* under us, which to date is the easiest/cleanest/least */ + /* Windows-specific way I can find to force the winsock calls to */ + /* return WSAEINTR with the test is over. anything that will run on */ + /* 95 and NT and is closer to what netperf expects from Unix signals */ + /* and such would be appreciated raj 1/96 */ + win_kludge_socket = recv_socket; +#endif /* WIN32 */ + + /* Data Socket set-up is finished. If there were problems, either */ + /* the connect would have failed, or the previous response would */ + /* have indicated a problem. I failed to see the value of the */ + /* extra message after the accept on the remote. If it failed, */ + /* we'll see it here. If it didn't, we might as well start pumping */ + /* data. */ + + /* Set-up the test end conditions. For a maerts test, they can be */ + /* either time or byte-count based. */ + + if (test_time) { + /* The user wanted to end the test after a period of time. */ + times_up = 0; + bytes_remaining = 0; + /* in previous revisions, we had the same code repeated throught */ + /* all the test suites. this was unnecessary, and meant more */ + /* work for me when I wanted to switch to POSIX signals, so I */ + /* have abstracted this out into a routine in netlib.c. if you */ + /* are experiencing signal problems, you might want to look */ + /* there. raj 11/94 */ + if (!no_control) { + /* this is a netperf to netserver test, netserver will close + to tell us the test is over, so use PAD_TIME to avoid + causing the netserver fits. */ + start_timer(test_time + PAD_TIME); + } + else { + /* this is a netperf to data source test, no PAD_TIME */ + start_timer(test_time); + } + } + else { + /* The tester wanted to recv a number of bytes. we don't do that + in a TCP_MAERTS test. sorry. raj 2002-06-21 */ + printf("netperf: send_tcp_maerts: test must be timed\n"); + exit(1); + } + + /* The cpu_start routine will grab the current time and possibly */ + /* value of the idle counter for later use in measuring cpu */ + /* utilization and/or service demand and thruput. */ + + cpu_start(local_cpu_usage); + +#ifdef WANT_INTERVALS + INTERVALS_INIT(); +#endif /* WANT_INTERVALS */ + + /* before we start, initialize a few variables */ + +#ifdef WANT_DEMO + if (demo_mode) { + HIST_timestamp(demo_one_ptr); + } +#endif + + /* the test will continue until we either get a zero-byte recv() + on the socket or our failsafe timer expires. most of the time + we trust that we get a zero-byte recieve from the socket. raj + 2002-06-21 */ + +#ifdef WANT_HISTOGRAM + if (verbosity > 1) { + /* timestamp just before we go into recv and then again just + after we come out raj 8/94 */ + /* but only if we are actually going to display a histogram. raj + 2006-02-07 */ + HIST_timestamp(&time_one); + } +#endif /* WANT_HISTOGRAM */ + + while ((!times_up) && (len=recv(recv_socket, + recv_ring->buffer_ptr, + recv_size, + 0)) > 0 ) { + +#ifdef WANT_HISTOGRAM + if (verbosity > 1) { + /* timestamp the exit from the recv call and update the histogram */ + HIST_timestamp(&time_two); + HIST_add(time_hist,delta_micro(&time_one,&time_two)); + } +#endif /* WANT_HISTOGRAM */ + +#ifdef DIRTY + access_buffer(recv_ring->buffer_ptr, + recv_size, + loc_dirty_count, + loc_clean_count); +#endif /* DIRTY */ + +#ifdef WANT_DEMO + DEMO_STREAM_INTERVAL(len); +#endif + +#ifdef WANT_INTERVALS + INTERVALS_WAIT(); +#endif /* WANT_INTERVALS */ + + /* now we want to move our pointer to the next position in the */ + /* data buffer...we may also want to wrap back to the "beginning" */ + /* of the bufferspace, so we will mod the number of messages sent */ + /* by the recv width, and use that to calculate the offset to add */ + /* to the base pointer. */ + nummessages++; + recv_ring = recv_ring->next; + if (bytes_remaining) { + bytes_remaining -= len; + } + + local_bytes_recvd += len; + +#ifdef WANT_HISTOGRAM + if (verbosity > 1) { + /* make sure we timestamp just before we go into recv */ + /* raj 2004-06-15 */ + HIST_timestamp(&time_one); + } +#endif /* WANT_HISTOGRAM */ + + } + + /* an EINTR is to be expected when this is a no_control test */ + if (((len < 0) || SOCKET_EINTR(len)) && (!no_control)) { + perror("send_tcp_maerts: data recv error"); + printf("len was %d\n",len); + exit(1); + } + + /* if we get here, it must mean we had a recv return of 0 before + the watchdog timer expired, or the watchdog timer expired and + this was a no_control test */ + + /* The test is over. Flush the buffers to the remote end. We do a + graceful release to tell the remote we have all the data. */ + + /* but first, if the verbosity is greater than 1, find-out what */ + /* the TCP maximum segment_size was (if possible) */ + if (verbosity > 1) { + tcp_mss = -1; + get_tcp_info(recv_socket,&tcp_mss); + } + + if (shutdown(recv_socket,SHUT_WR) == SOCKET_ERROR) { + perror("netperf: cannot shutdown tcp maerts socket"); + exit(1); + } + + stop_timer(); + + /* this call will always give us the local elapsed time for the + test, and will also store-away the necessaries for cpu + utilization */ + + cpu_stop(local_cpu_usage,&elapsed_time); /* was cpu being */ + /* measured and how */ + /* long did we really */ + /* run? */ + + /* we are finished with the socket, so close it to prevent hitting */ + /* the limit on maximum open files. */ + + close(recv_socket); + + if (!no_control) { + /* Get the statistics from the remote end. The remote will have + calculated service demand and all those interesting + things. If it wasn't supposed to care, it will return obvious + values. */ + + recv_response(); + if (!netperf_response.content.serv_errno) { + if (debug) + fprintf(where,"remote results obtained\n"); + } + else { + Set_errno(netperf_response.content.serv_errno); + fprintf(where, + "netperf: remote error %d", + netperf_response.content.serv_errno); + perror(""); + fflush(where); + + exit(1); + } + + /* We now calculate what our thruput was for the test. In the + future, we may want to include a calculation of the thruput + measured by the remote, but it should be the case that for a + TCP maerts test, that the two numbers should be *very* + close... We calculate bytes_sent regardless of the way the + test length was controlled. If it was time, we needed to, + and if it was by bytes, the user may have specified a number + of bytes that wasn't a multiple of the recv_size, so we + really didn't recv what he asked for ;-) */ + + bytes_sent = ntohd(tcp_maerts_result->bytes_sent); + } + else { + bytes_sent = (double)local_bytes_recvd; + } + + + thruput = calc_thruput(bytes_sent); + + if (local_cpu_usage || remote_cpu_usage) { + /* We must now do a little math for service demand and cpu */ + /* utilization for the system(s) */ + /* Of course, some of the information might be bogus because */ + /* there was no idle counter in the kernel(s). We need to make */ + /* a note of this for the user's benefit...*/ + if (local_cpu_usage) { + + local_cpu_utilization = calc_cpu_util(0.0); + local_service_demand = calc_service_demand(bytes_sent, + 0.0, + 0.0, + 0); + } + else { + local_cpu_utilization = (float) -1.0; + local_service_demand = (float) -1.0; + } + + if (remote_cpu_usage) { + + remote_cpu_utilization = tcp_maerts_result->cpu_util; + remote_service_demand = calc_service_demand(bytes_sent, + 0.0, + remote_cpu_utilization, + tcp_maerts_result->num_cpus); + } + else { + remote_cpu_utilization = (float) -1.0; + remote_service_demand = (float) -1.0; + } + } + else { + /* we were not measuring cpu, for the confidence stuff, we */ + /* should make it -1.0 */ + local_cpu_utilization = (float) -1.0; + local_service_demand = (float) -1.0; + remote_cpu_utilization = (float) -1.0; + remote_service_demand = (float) -1.0; + } + + /* at this point, we want to calculate the confidence information. */ + /* if debugging is on, calculate_confidence will print-out the */ + /* parameters we pass it */ + + calculate_confidence(confidence_iteration, + elapsed_time, + thruput, + local_cpu_utilization, + remote_cpu_utilization, + local_service_demand, + remote_service_demand); + + + confidence_iteration++; + } + + /* at this point, we have finished making all the runs that we */ + /* will be making. so, we should extract what the calcuated values */ + /* are for all the confidence stuff. we could make the values */ + /* global, but that seemed a little messy, and it did not seem worth */ + /* all the mucking with header files. so, we create a routine much */ + /* like calcualte_confidence, which just returns the mean values. */ + /* raj 11/94 */ + + retrieve_confident_values(&elapsed_time, + &thruput, + &local_cpu_utilization, + &remote_cpu_utilization, + &local_service_demand, + &remote_service_demand); + + /* We are now ready to print all the information. If the user */ + /* has specified zero-level verbosity, we will just print the */ + /* local service demand, or the remote service demand. If the */ + /* user has requested verbosity level 1, he will get the basic */ + /* "streamperf" numbers. If the user has specified a verbosity */ + /* of greater than 1, we will display a veritable plethora of */ + /* background information from outside of this block as it it */ + /* not cpu_measurement specific... */ + + if (confidence < 0) { + /* we did not hit confidence, but were we asked to look for it? */ + if (iteration_max > 1) { + display_confidence(); + } + } + + if (local_cpu_usage || remote_cpu_usage) { + local_cpu_method = format_cpu_method(cpu_method); + remote_cpu_method = format_cpu_method(tcp_maerts_result->cpu_method); + + switch (verbosity) { + case 0: + if (local_cpu_usage) { + fprintf(where, + cpu_fmt_0, + local_service_demand, + local_cpu_method, + ((print_headers) || + (result_brand == NULL)) ? "" : result_brand); + } + else { + fprintf(where, + cpu_fmt_0, + remote_service_demand, + remote_cpu_method, + ((print_headers) || + (result_brand == NULL)) ? "" : result_brand); + } + break; + case 1: + case 2: + if (print_headers) { + fprintf(where, + cpu_title, + format_units(), + local_cpu_method, + remote_cpu_method); + } + + fprintf(where, + cpu_fmt_1, /* the format string */ + rsr_size, /* remote recvbuf size */ + lss_size, /* local sendbuf size */ + send_size, /* how large were the recvs */ + elapsed_time, /* how long was the test */ + thruput, /* what was the xfer rate */ + local_cpu_utilization, /* local cpu */ + remote_cpu_utilization, /* remote cpu */ + local_service_demand, /* local service demand */ + remote_service_demand, /* remote service demand */ + ((print_headers) || + (result_brand == NULL)) ? "" : result_brand); + break; + } + } + else { + /* The tester did not wish to measure service demand. */ + + switch (verbosity) { + case 0: + fprintf(where, + tput_fmt_0, + thruput, + ((print_headers) || + (result_brand == NULL)) ? "" : result_brand); + break; + case 1: + case 2: + if (print_headers) { + fprintf(where,tput_title,format_units()); + } + fprintf(where, + tput_fmt_1, /* the format string */ + lsr_size, /* local recvbuf size */ + rss_size, /* remot sendbuf size */ + send_size, /* how large were the recvs */ + elapsed_time, /* how long did it take */ + thruput, /* how fast did it go */ + ((print_headers) || + (result_brand == NULL)) ? "" : result_brand); + break; + } + } + + /* it would be a good thing to include information about some of the */ + /* other parameters that may have been set for this test, but at the */ + /* moment, I do not wish to figure-out all the formatting, so I will */ + /* just put this comment here to help remind me that it is something */ + /* that should be done at a later time. */ + + if (verbosity > 1) { + /* The user wanted to know it all, so we will give it to him. */ + /* This information will include as much as we can find about */ + /* TCP statistics, the alignments of the sends and receives */ + /* and all that sort of rot... */ + + /* this stuff needs to be worked-out in the presence of confidence */ + /* intervals and multiple iterations of the test... raj 11/94 */ + + fprintf(where, + ksink_fmt, + "Bytes", + "Bytes", + "Bytes", + local_recv_align, + remote_recv_align, + local_recv_offset, + remote_recv_offset, + bytes_sent, + bytes_sent / (double)nummessages, + nummessages, + bytes_sent / (double)tcp_maerts_result->send_calls, + tcp_maerts_result->send_calls); + fprintf(where, + ksink_fmt2, + tcp_mss); + fflush(where); +#ifdef WANT_HISTOGRAM + fprintf(where,"\n\nHistogram of time spent in recv() call.\n"); + fflush(where); + HIST_report(time_hist); +#endif /* WANT_HISTOGRAM */ + } + +} + + + +/* this routine implements the TCP_MSS test. All it does is pretend + to be a TCP_STREAM test and report the TCP_MSS for the data + connection. No actual data is transferred. raj 2007-11-07 +*/ +void +send_tcp_mss(char remote_host[]) +{ + + char *mss_title = "\ +Maximum\n\ +Segment\n\ +Size (bytes)\n\n"; + + char *mss_fmt_0 = + "%d %s\n"; + + SOCKET send_socket; + int tcp_mss = -1; /* possibly uninitialized on printf far below */ + + struct addrinfo *remote_res; + struct addrinfo *local_res; + + struct tcp_stream_request_struct *tcp_stream_request; + struct tcp_stream_response_struct *tcp_stream_response; + struct tcp_stream_results_struct *tcp_stream_result; + + tcp_stream_request = + (struct tcp_stream_request_struct *)netperf_request.content.test_specific_data; + tcp_stream_response = + (struct tcp_stream_response_struct *)netperf_response.content.test_specific_data; + tcp_stream_result = + (struct tcp_stream_results_struct *)netperf_response.content.test_specific_data; + + /* since we are now disconnected from the code that established the */ + /* control socket, and since we want to be able to use different */ + /* protocols and such, we are passed the name of the remote host and */ + /* must turn that into the test specific addressing information. */ + + /* complete_addrinfos will either succede or exit the process */ + complete_addrinfos(&remote_res, + &local_res, + remote_host, + SOCK_STREAM, + IPPROTO_TCP, + 0); + + if ( print_headers ) { + print_top_test_header("TCP MSS TEST",local_res,remote_res); + } + + /*set up the data socket */ + send_socket = create_data_socket(local_res); + + if (send_socket == INVALID_SOCKET){ + perror("netperf: send_tcp_stream: tcp stream data socket"); + exit(1); + } + + if (debug) { + fprintf(where,"send_tcp_stream: send_socket obtained...\n"); + } + + + if (!no_control) { + /* Tell the remote end to do a listen. The server alters the + socket paramters on the other side at this point, hence the + reason for all the values being passed in the setup + message. If the user did not specify any of the parameters, + they will be passed as 0, which will indicate to the remote + that no changes beyond the system's default should be + used. Alignment is the exception, it will default to 1, which + will be no alignment alterations. */ + + netperf_request.content.request_type = DO_TCP_STREAM; + tcp_stream_request->send_buf_size = rss_size_req; + tcp_stream_request->recv_buf_size = rsr_size_req; + tcp_stream_request->receive_size = recv_size; + tcp_stream_request->no_delay = rem_nodelay; + tcp_stream_request->recv_alignment = remote_recv_align; + tcp_stream_request->recv_offset = remote_recv_offset; + tcp_stream_request->measure_cpu = remote_cpu_usage; + tcp_stream_request->cpu_rate = remote_cpu_rate; + if (test_time) { + tcp_stream_request->test_length = test_time; + } + else { + tcp_stream_request->test_length = test_bytes; + } + tcp_stream_request->so_rcvavoid = rem_rcvavoid; + tcp_stream_request->so_sndavoid = rem_sndavoid; +#ifdef DIRTY + tcp_stream_request->dirty_count = rem_dirty_count; + tcp_stream_request->clean_count = rem_clean_count; +#endif /* DIRTY */ + tcp_stream_request->port = atoi(remote_data_port); + tcp_stream_request->ipfamily = af_to_nf(remote_res->ai_family); + if (debug > 1) { + fprintf(where, + "netperf: send_tcp_mss: requesting TCP stream test\n"); + } + + send_request(); + + /* The response from the remote will contain all of the relevant + socket parameters for this test type. We will put them back + into the variables here so they can be displayed if desired. + The remote will have calibrated CPU if necessary, and will + have done all the needed set-up we will have calibrated the + cpu locally before sending the request, and will grab the + counter value right after the connect returns. The remote + will grab the counter right after the accept call. This saves + the hassle of extra messages being sent for the TCP + tests. */ + + recv_response(); + + if (!netperf_response.content.serv_errno) { + if (debug) + fprintf(where,"remote listen done.\n"); + rsr_size = tcp_stream_response->recv_buf_size; + rss_size = tcp_stream_response->send_buf_size; + rem_nodelay = tcp_stream_response->no_delay; + remote_cpu_usage= tcp_stream_response->measure_cpu; + remote_cpu_rate = tcp_stream_response->cpu_rate; + + /* we have to make sure that the server port number is in + network order */ + set_port_number(remote_res, + (short)tcp_stream_response->data_port_number); + + rem_rcvavoid = tcp_stream_response->so_rcvavoid; + rem_sndavoid = tcp_stream_response->so_sndavoid; + } + else { + Set_errno(netperf_response.content.serv_errno); + fprintf(where, + "netperf: remote error %d", + netperf_response.content.serv_errno); + perror(""); + fflush(where); + + exit(1); + } + } + + /*Connect up to the remote port on the data socket */ + if (connect(send_socket, + remote_res->ai_addr, + remote_res->ai_addrlen) == INVALID_SOCKET){ + perror("netperf: send_tcp_mss: data socket connect failed"); + exit(1); + } + + + /* find-out what the TCP maximum segment_size was (if possible) */ + tcp_mss = -1; + get_tcp_info(send_socket,&tcp_mss); + + /* just go ahead and close the socket, the remote should figure it + out */ + close(send_socket); + + /* statistics? we don't need no stinking statistics */ + + + switch (verbosity) { + case 0: + fprintf(where, + mss_fmt_0, + tcp_mss, + ((print_headers) || + (result_brand == NULL)) ? "" : result_brand); + break; + case 1: + case 2: + if (print_headers) { + fprintf(where,mss_title); + } + fprintf(where, + mss_fmt_0, /* the format string */ + tcp_mss, + ((print_headers) || + (result_brand == NULL)) ? "" : result_brand); + break; + } + + +} + + + +#ifdef HAVE_ICSC_EXS + +#include + + +/* This routine implements the TCP unidirectional data transfer test */ +/* (a.k.a. stream) for the sockets interface. It receives its */ +/* parameters via global variables from the shell and writes its */ +/* output to the standard output. */ + +void +send_exs_tcp_stream(char remote_host[]) +{ + + char *tput_title = "\ +Recv Send Send \n\ +Socket Socket Message Elapsed \n\ +Size Size Size Time Throughput \n\ +bytes bytes bytes secs. %s/sec \n\n"; + + char *tput_fmt_0 = + "%7.2f\n"; + + char *tput_fmt_1 = + "%6d %6d %6d %-6.2f %7.2f \n"; + + char *cpu_title = "\ +Recv Send Send Utilization Service Demand\n\ +Socket Socket Message Elapsed Send Recv Send Recv\n\ +Size Size Size Time Throughput local remote local remote\n\ +bytes bytes bytes secs. %-8.8s/s %% %c %% %c us/KB us/KB\n\n"; + + char *cpu_fmt_0 = + "%6.3f %c\n"; + + char *cpu_fmt_1 = + "%6d %6d %6d %-6.2f %7.2f %-6.2f %-6.2f %-6.3f %-6.3f\n"; + + char *ksink_fmt = "\n\ +Alignment Offset %-8.8s %-8.8s Sends %-8.8s Recvs\n\ +Local Remote Local Remote Xfered Per Per\n\ +Send Recv Send Recv Send (avg) Recv (avg)\n\ +%5d %5d %5d %5d %6.4g %6.2f %6d %6.2f %6d\n"; + + char *ksink_fmt2 = "\n\ +Maximum\n\ +Segment\n\ +Size (bytes)\n\ +%6d\n"; + + + float elapsed_time; + + /* what we want is to have a buffer space that is at least one */ + /* send-size greater than our send window. this will insure that we */ + /* are never trying to re-use a buffer that may still be in the hands */ + /* of the transport. This buffer will be malloc'd after we have found */ + /* the size of the local senc socket buffer. We will want to deal */ + /* with alignment and offset concerns as well. */ + + struct ring_elt *send_ring; + + int len; + unsigned int nummessages = 0; + SOCKET send_socket; + int bytes_remaining; + int tcp_mss = -1; /* possibly uninitialized on printf far below */ + + exs_mhandle_t exs_mhandle; + exs_qhandle_t exs_qhandle; +#define NETPERF_EXS_PENDING 16 + int exs_aio_pending; + int exs_aio_eagain; + int exs_aio_dequeued; + int exs_aio_dequeuecnt; + int exs_evtcnt; +#define NETPERF_EXS_QSIZE 128 + exs_event_t exs_evtvec[NETPERF_EXS_QSIZE]; + + /* with links like fddi, one can send > 32 bits worth of bytes */ + /* during a test... ;-) at some point, this should probably become a */ + /* 64bit integral type, but those are not entirely common yet */ + + double bytes_sent = 0.0; + + float local_cpu_utilization; + float local_service_demand; + float remote_cpu_utilization; + float remote_service_demand; + + double thruput; + + struct addrinfo *remote_res; + struct addrinfo *local_res; + + struct tcp_stream_request_struct *tcp_stream_request; + struct tcp_stream_response_struct *tcp_stream_response; + struct tcp_stream_results_struct *tcp_stream_result; + + tcp_stream_request = + (struct tcp_stream_request_struct *)netperf_request.content.test_specific_data; + tcp_stream_response = + (struct tcp_stream_response_struct *)netperf_response.content.test_specific_data; + tcp_stream_result = + (struct tcp_stream_results_struct *)netperf_response.content.test_specific_data; + +#if 0 /* def WANT_HISTOGRAM */ + time_hist = HIST_new(); +#endif /* WANT_HISTOGRAM */ + /* since we are now disconnected from the code that established the */ + /* control socket, and since we want to be able to use different */ + /* protocols and such, we are passed the name of the remote host and */ + /* must turn that into the test specific addressing information. */ + + /* complete_addrinfos will either succede or exit the process */ + complete_addrinfos(&remote_res, + &local_res, + remote_host, + SOCK_STREAM, + IPPROTO_TCP, + 0); + + if ( print_headers ) { + print_top_test_header("EXS TCP STREAM TEST",local_res,remote_res); + } + + send_ring = NULL; + confidence_iteration = 1; + init_stat(); + + /* initialize EXS API and create event queue */ + if (exs_init (EXS_VERSION) == -1) { + perror ("netperf: send_exs_tcp_stream: exs_init failed"); + exit (1); + } + + if ((exs_qhandle = exs_qcreate (NETPERF_EXS_QSIZE)) == EXS_QHANDLE_INVALID) { + perror ("netperf: send_exs_tcp_stream: exs_qcreate failed"); + exit (1); + } + if (debug) { + fprintf (where, "send_exs_tcp_stream: qhandle=%d\n", exs_qhandle); + } + + /* we have a great-big while loop which controls the number of times */ + /* we run a particular test. this is for the calculation of a */ + /* confidence interval (I really should have stayed awake during */ + /* probstats :). If the user did not request confidence measurement */ + /* (no confidence is the default) then we will only go though the */ + /* loop once. the confidence stuff originates from the folks at IBM */ + + while (((confidence < 0) && (confidence_iteration < iteration_max)) || + (confidence_iteration <= iteration_min)) { + + /* initialize a few counters. we have to remember that we might be */ + /* going through the loop more than once. */ + + nummessages = 0; + bytes_sent = 0.0; + times_up = 0; + + /*set up the data socket */ + send_socket = create_data_socket(local_res); + + if (send_socket == INVALID_SOCKET){ + perror("netperf: send_tcp_stream: tcp stream data socket"); + exit(1); + } + + if (debug) { + fprintf(where,"send_tcp_stream: send_socket obtained...\n"); + } + + /* at this point, we have either retrieved the socket buffer sizes, */ + /* or have tried to set them, so now, we may want to set the send */ + /* size based on that (because the user either did not use a -m */ + /* option, or used one with an argument of 0). If the socket buffer */ + /* size is not available, we will set the send size to 4KB - no */ + /* particular reason, just arbitrary... */ + if (send_size == 0) { + if (lss_size > 0) { + send_size = lss_size; + } + else { + send_size = 4096; + } + } + + /* set-up the data buffer ring with the requested alignment and offset. */ + /* note also that we have allocated a quantity */ + /* of memory that is at least one send-size greater than our socket */ + /* buffer size. We want to be sure that there are at least two */ + /* buffers allocated - this can be a bit of a problem when the */ + /* send_size is bigger than the socket size, so we must check... the */ + /* user may have wanted to explicitly set the "width" of our send */ + /* buffers, we should respect that wish... */ + if (send_width == 0) { + send_width = (lss_size/send_size) + 1; + if (send_width == 1) send_width++; + } + + if (send_ring == NULL) { + /* only allocate the send ring once. this is a networking test, */ + /* not a memory allocation test. this way, we do not need a */ + /* deallocate_buffer_ring() routine, and I don't feel like */ + /* writing one anyway :) raj 11/94 */ + send_ring = allocate_exs_buffer_ring(send_width, + send_size, + local_send_align, + local_send_offset, + &exs_mhandle); + } + + /* If the user has requested cpu utilization measurements, we must */ + /* calibrate the cpu(s). We will perform this task within the tests */ + /* themselves. If the user has specified the cpu rate, then */ + /* calibrate_local_cpu will return rather quickly as it will have */ + /* nothing to do. If local_cpu_rate is zero, then we will go through */ + /* all the "normal" calibration stuff and return the rate back. */ + + if (local_cpu_usage) { + local_cpu_rate = calibrate_local_cpu(local_cpu_rate); + } + + /* Tell the remote end to do a listen. The server alters the socket */ + /* paramters on the other side at this point, hence the reason for */ + /* all the values being passed in the setup message. If the user did */ + /* not specify any of the parameters, they will be passed as 0, which */ + /* will indicate to the remote that no changes beyond the system's */ + /* default should be used. Alignment is the exception, it will */ + /* default to 1, which will be no alignment alterations. */ + + netperf_request.content.request_type = DO_TCP_STREAM; + tcp_stream_request->send_buf_size = rss_size_req; + tcp_stream_request->recv_buf_size = rsr_size_req; + tcp_stream_request->receive_size = recv_size; + tcp_stream_request->no_delay = rem_nodelay; + tcp_stream_request->recv_alignment = remote_recv_align; + tcp_stream_request->recv_offset = remote_recv_offset; + tcp_stream_request->measure_cpu = remote_cpu_usage; + tcp_stream_request->cpu_rate = remote_cpu_rate; + if (test_time) { + tcp_stream_request->test_length = test_time; + } + else { + tcp_stream_request->test_length = test_bytes; + } + tcp_stream_request->so_rcvavoid = rem_rcvavoid; + tcp_stream_request->so_sndavoid = rem_sndavoid; +#ifdef DIRTY + tcp_stream_request->dirty_count = rem_dirty_count; + tcp_stream_request->clean_count = rem_clean_count; +#endif /* DIRTY */ + tcp_stream_request->port = atoi(remote_data_port); + tcp_stream_request->ipfamily = af_to_nf(remote_res->ai_family); + if (debug > 1) { + fprintf(where, + "netperf: send_tcp_stream: requesting TCP stream test\n"); + } + + send_request(); + + /* The response from the remote will contain all of the relevant */ + /* socket parameters for this test type. We will put them back into */ + /* the variables here so they can be displayed if desired. The */ + /* remote will have calibrated CPU if necessary, and will have done */ + /* all the needed set-up we will have calibrated the cpu locally */ + /* before sending the request, and will grab the counter value right*/ + /* after the connect returns. The remote will grab the counter right*/ + /* after the accept call. This saves the hassle of extra messages */ + /* being sent for the TCP tests. */ + + recv_response(); + + if (!netperf_response.content.serv_errno) { + if (debug) + fprintf(where,"remote listen done.\n"); + rsr_size = tcp_stream_response->recv_buf_size; + rss_size = tcp_stream_response->send_buf_size; + rem_nodelay = tcp_stream_response->no_delay; + remote_cpu_usage= tcp_stream_response->measure_cpu; + remote_cpu_rate = tcp_stream_response->cpu_rate; + + /* we have to make sure that the server port number is in */ + /* network order */ + set_port_number(remote_res,(short)tcp_stream_response->data_port_number); + + rem_rcvavoid = tcp_stream_response->so_rcvavoid; + rem_sndavoid = tcp_stream_response->so_sndavoid; + } + else { + Set_errno(netperf_response.content.serv_errno); + fprintf(where, + "netperf: remote error %d", + netperf_response.content.serv_errno); + perror(""); + fflush(where); + + exit(1); + } + +#if 0 /* def WANT_DEMO */ + DEMO_STREAM_SETUP(lss_size,rsr_size) +#endif + + /*Connect up to the remote port on the data socket */ + if (connect(send_socket, + remote_res->ai_addr, + remote_res->ai_addrlen) == INVALID_SOCKET){ + perror("netperf: send_tcp_stream: data socket connect failed"); + exit(1); + } + +#ifdef WIN32 + /* this is used so the timer thread can close the socket out from */ + /* under us, which to date is the easiest/cleanest/least */ + /* Windows-specific way I can find to force the winsock calls to */ + /* return WSAEINTR with the test is over. anything that will run on */ + /* 95 and NT and is closer to what netperf expects from Unix signals */ + /* and such would be appreciated raj 1/96 */ + win_kludge_socket = send_socket; +#endif /* WIN32 */ + + /* Data Socket set-up is finished. If there were problems, either */ + /* the connect would have failed, or the previous response would */ + /* have indicated a problem. I failed to see the value of the */ + /* extra message after the accept on the remote. If it failed, */ + /* we'll see it here. If it didn't, we might as well start pumping */ + /* data. */ + + /* Set-up the test end conditions. For a stream test, they can be */ + /* either time or byte-count based. */ + + if (test_time) { + /* The user wanted to end the test after a period of time. */ + times_up = 0; + bytes_remaining = 0; + /* in previous revisions, we had the same code repeated throught */ + /* all the test suites. this was unnecessary, and meant more */ + /* work for me when I wanted to switch to POSIX signals, so I */ + /* have abstracted this out into a routine in netlib.c. if you */ + /* are experiencing signal problems, you might want to look */ + /* there. raj 11/94 */ + start_timer(test_time); + } + else { + /* The tester wanted to send a number of bytes. */ + bytes_remaining = test_bytes; + times_up = 1; + } + + /* The cpu_start routine will grab the current time and possibly */ + /* value of the idle counter for later use in measuring cpu */ + /* utilization and/or service demand and thruput. */ + + cpu_start(local_cpu_usage); + +#if 0 /* def WANT_INTERVALS */ + INTERVALS_INIT(); +#endif /* WANT_INTERVALS */ + + /* before we start, initialize a few variables */ + +#if 0 /* def WANT_DEMO */ + if (demo_mode) { + HIST_timestamp(demo_one_ptr); + } +#endif + + + /* We use an "OR" to control test execution. When the test is */ + /* controlled by time, the byte count check will always return false. */ + /* When the test is controlled by byte count, the time test will */ + /* always return false. When the test is finished, the whole */ + /* expression will go false and we will stop sending data. */ + + exs_aio_pending = 0; + exs_aio_eagain = 0; + exs_aio_dequeuecnt = 0; + + while ((!times_up) || (bytes_remaining > 0)) { + +#ifdef DIRTY + access_buffer(send_ring->buffer_ptr, + send_size, + loc_dirty_count, + loc_clean_count); +#endif /* DIRTY */ + +#if 0 /* def WANT_HISTOGRAM */ + /* timestamp just before we go into send and then again just after */ + /* we come out raj 8/94 */ + HIST_timestamp(&time_one); +#endif /* WANT_HISTOGRAM */ + + + /* post up to NETPERF_EXS_PENDING I/Os */ + while ((exs_aio_pending < NETPERF_EXS_PENDING) && + (exs_send (send_socket, send_ring->buffer_ptr, send_size, + 0, exs_qhandle, (exs_ahandle_t)-1, exs_mhandle) == 0)) { + exs_aio_pending++; + + /* now we want to move our pointer to the next + position in the data buffer...we may also want to + wrap back to the "beginning" of the bufferspace, so + we will mod the number of messages sent by the send + width, and use that to calculate the offset to add + to the base pointer. */ + + nummessages++; + send_ring = send_ring->next; + if (bytes_remaining) { + bytes_remaining -= send_size; + } + } + + /* check exs_send result */ + if (exs_aio_pending < NETPERF_EXS_PENDING) { + /* standard flow control case */ + if (errno == EAGAIN) + exs_aio_eagain++; + /* case of times_up */ + else if (errno == EINTR) + break; + /* strange, let's stop */ + else { + perror ("netperf: exs_send error"); + exit (1); + } + } + + /* dequeue events with "threshold" on 1/2 posted */ + exs_aio_dequeued = + exs_qdequeue (exs_qhandle, exs_evtvec, + -(exs_aio_pending>>1), NULL); + exs_aio_dequeuecnt++; + + /* check exs_dequeue result */ + if (exs_aio_dequeued < 0) { + /* case of times_up */ + if (errno == EINTR) + break; + /* strange, let's stop */ + else { + perror ("netperf: exs_send error"); + exit (1); + } + } + /* update number of pending I/Os */ + else { + exs_aio_pending -= exs_aio_dequeued; + } + + +#if 0 /* def WANT_HISTOGRAM */ + /* timestamp the exit from the send call and update the histogram */ + HIST_timestamp(&time_two); + HIST_add(time_hist,delta_micro(&time_one,&time_two)); +#endif /* WANT_HISTOGRAM */ + +#if 0 /* def WANT_DEMO */ + DEMO_STREAM_INTERVAL(send_size); +#endif + +#if 0 /* def WANT_INTERVALS */ + INTERVALS_WAIT(); +#endif /* WANT_INTERVALS */ + + } + + /* Collect the last completion events */ + exs_aio_dequeued = + exs_qdequeue (exs_qhandle, exs_evtvec, -exs_aio_pending, NULL); + exs_aio_dequeuecnt++; + /* check exs_dequeue result and update number of pending I/Os */ + if (exs_aio_dequeued < 0) { + perror ("netperf: exs_send error"); + exit (1); + } + exs_aio_pending -= exs_aio_dequeued; + + /* Display some async I/O debug info */ + if (debug) { + fprintf (where, "send_exs_tcp_stream: " + "aio sent=%d eagain=%d dequeue=%d pending=%d\n", + nummessages, exs_aio_eagain, exs_aio_dequeuecnt, exs_aio_pending); + } + + /* The test is over. Flush the buffers to the remote end. We do a */ + /* graceful release to insure that all data has been taken by the */ + /* remote. */ + + /* but first, if the verbosity is greater than 1, find-out what */ + /* the TCP maximum segment_size was (if possible) */ + if (verbosity > 1) { + tcp_mss = -1; + get_tcp_info(send_socket,&tcp_mss); + } + + if (shutdown(send_socket,SHUT_WR) == SOCKET_ERROR) { + perror("netperf: cannot shutdown tcp stream socket"); + exit(1); + } + + /* hang a recv() off the socket to block until the remote has */ + /* brought all the data up into the application. it will do a */ + /* shutdown to cause a FIN to be sent our way. We will assume that */ + /* any exit from the recv() call is good... raj 4/93 */ + + recv(send_socket, send_ring->buffer_ptr, send_size, 0); + + /* this call will always give us the elapsed time for the test, and */ + /* will also store-away the necessaries for cpu utilization */ + + cpu_stop(local_cpu_usage,&elapsed_time); /* was cpu being */ + /* measured and how */ + /* long did we really */ + /* run? */ + + /* we are finished with the socket, so close it to prevent hitting */ + /* the limit on maximum open files. */ + + close(send_socket); + + /* Get the statistics from the remote end. The remote will have */ + /* calculated service demand and all those interesting things. If it */ + /* wasn't supposed to care, it will return obvious values. */ + + recv_response(); + if (!netperf_response.content.serv_errno) { + if (debug) + fprintf(where,"remote results obtained\n"); + } + else { + Set_errno(netperf_response.content.serv_errno); + fprintf(where, + "netperf: remote error %d", + netperf_response.content.serv_errno); + perror(""); + fflush(where); + + exit(1); + } + + /* We now calculate what our thruput was for the test. In the future, */ + /* we may want to include a calculation of the thruput measured by */ + /* the remote, but it should be the case that for a TCP stream test, */ + /* that the two numbers should be *very* close... We calculate */ + /* bytes_sent regardless of the way the test length was controlled. */ + /* If it was time, we needed to, and if it was by bytes, the user may */ + /* have specified a number of bytes that wasn't a multiple of the */ + /* send_size, so we really didn't send what he asked for ;-) */ + + bytes_sent = ntohd(tcp_stream_result->bytes_received); + + thruput = calc_thruput(bytes_sent); + + if (local_cpu_usage || remote_cpu_usage) { + /* We must now do a little math for service demand and cpu */ + /* utilization for the system(s) */ + /* Of course, some of the information might be bogus because */ + /* there was no idle counter in the kernel(s). We need to make */ + /* a note of this for the user's benefit...*/ + if (local_cpu_usage) { + + local_cpu_utilization = calc_cpu_util(0.0); + local_service_demand = calc_service_demand(bytes_sent, + 0.0, + 0.0, + 0); + } + else { + local_cpu_utilization = (float) -1.0; + local_service_demand = (float) -1.0; + } + + if (remote_cpu_usage) { + + remote_cpu_utilization = tcp_stream_result->cpu_util; + remote_service_demand = calc_service_demand(bytes_sent, + 0.0, + remote_cpu_utilization, + tcp_stream_result->num_cpus); + } + else { + remote_cpu_utilization = (float) -1.0; + remote_service_demand = (float) -1.0; + } + } + else { + /* we were not measuring cpu, for the confidence stuff, we */ + /* should make it -1.0 */ + local_cpu_utilization = (float) -1.0; + local_service_demand = (float) -1.0; + remote_cpu_utilization = (float) -1.0; + remote_service_demand = (float) -1.0; + } + + /* at this point, we want to calculate the confidence information. */ + /* if debugging is on, calculate_confidence will print-out the */ + /* parameters we pass it */ + + calculate_confidence(confidence_iteration, + elapsed_time, + thruput, + local_cpu_utilization, + remote_cpu_utilization, + local_service_demand, + remote_service_demand); + + + confidence_iteration++; + } + + /* at this point, we have finished making all the runs that we */ + /* will be making. so, we should extract what the calcuated values */ + /* are for all the confidence stuff. we could make the values */ + /* global, but that seemed a little messy, and it did not seem worth */ + /* all the mucking with header files. so, we create a routine much */ + /* like calcualte_confidence, which just returns the mean values. */ + /* raj 11/94 */ + + retrieve_confident_values(&elapsed_time, + &thruput, + &local_cpu_utilization, + &remote_cpu_utilization, + &local_service_demand, + &remote_service_demand); + + /* We are now ready to print all the information. If the user */ + /* has specified zero-level verbosity, we will just print the */ + /* local service demand, or the remote service demand. If the */ + /* user has requested verbosity level 1, he will get the basic */ + /* "streamperf" numbers. If the user has specified a verbosity */ + /* of greater than 1, we will display a veritable plethora of */ + /* background information from outside of this block as it it */ + /* not cpu_measurement specific... */ + + if (confidence < 0) { + /* we did not hit confidence, but were we asked to look for it? */ + if (iteration_max > 1) { + display_confidence(); + } + } + + if (local_cpu_usage || remote_cpu_usage) { + local_cpu_method = format_cpu_method(cpu_method); + remote_cpu_method = format_cpu_method(tcp_stream_result->cpu_method); + + switch (verbosity) { + case 0: + if (local_cpu_usage) { + fprintf(where, + cpu_fmt_0, + local_service_demand, + local_cpu_method); + } + else { + fprintf(where, + cpu_fmt_0, + remote_service_demand, + remote_cpu_method); + } + break; + case 1: + case 2: + if (print_headers) { + fprintf(where, + cpu_title, + format_units(), + local_cpu_method, + remote_cpu_method); + } + + fprintf(where, + cpu_fmt_1, /* the format string */ + rsr_size, /* remote recvbuf size */ + lss_size, /* local sendbuf size */ + send_size, /* how large were the sends */ + elapsed_time, /* how long was the test */ + thruput, /* what was the xfer rate */ + local_cpu_utilization, /* local cpu */ + remote_cpu_utilization, /* remote cpu */ + local_service_demand, /* local service demand */ + remote_service_demand); /* remote service demand */ + break; + } + } + else { + /* The tester did not wish to measure service demand. */ + + switch (verbosity) { + case 0: + fprintf(where, + tput_fmt_0, + thruput); + break; + case 1: + case 2: + if (print_headers) { + fprintf(where,tput_title,format_units()); + } + fprintf(where, + tput_fmt_1, /* the format string */ + rsr_size, /* remote recvbuf size */ + lss_size, /* local sendbuf size */ + send_size, /* how large were the sends */ + elapsed_time, /* how long did it take */ + thruput);/* how fast did it go */ + break; + } + } + + /* it would be a good thing to include information about some of the */ + /* other parameters that may have been set for this test, but at the */ + /* moment, I do not wish to figure-out all the formatting, so I will */ + /* just put this comment here to help remind me that it is something */ + /* that should be done at a later time. */ + + if (verbosity > 1) { + /* The user wanted to know it all, so we will give it to him. */ + /* This information will include as much as we can find about */ + /* TCP statistics, the alignments of the sends and receives */ + /* and all that sort of rot... */ + + /* this stuff needs to be worked-out in the presence of confidence */ + /* intervals and multiple iterations of the test... raj 11/94 */ + + fprintf(where, + ksink_fmt, + "Bytes", + "Bytes", + "Bytes", + local_send_align, + remote_recv_align, + local_send_offset, + remote_recv_offset, + bytes_sent, + bytes_sent / (double)nummessages, + nummessages, + bytes_sent / (double)tcp_stream_result->recv_calls, + tcp_stream_result->recv_calls); + fprintf(where, + ksink_fmt2, + tcp_mss); + fflush(where); +#if 0 /* def WANT_HISTOGRAM */ + fprintf(where,"\n\nHistogram of time spent in send() call.\n"); + fflush(where); + HIST_report(time_hist); +#endif /* WANT_HISTOGRAM */ + } + +} + +#endif /* HAVE_ICSC_EXS */ + + + +#if defined(HAVE_SENDFILE) + +#if defined(QUICK_SENDPATH) + +/* + * a temporary stub for the sendpath() system call + * which is defined & implemented in the kernel + * but which has no libc stub. + */ +#include +#include +#include + +ssize_t +sendpath(int s, char *path, off_t offset, size_t nbytes, + const struct iovec *hdtrl, int flags) + { + return syscall(SYS_sendpath, s, path, offset, nbytes, hdtrl, flags); + } +#endif /* QUICK_SENDPATH */ + +/* This routine implements the TCP unidirectional data transfer test + (a.k.a. stream) for the sockets interface using the sendfile() + system call - TCP_SENDFILE. It receives its parameters via global + variables from the shell and writes its output to the standard + output. Basically, this is the same test as the send_tcp_stream() + logic and we even tell the remote to do a TCP_STREAM test since for + all it knows, nothig is different. */ + +void +sendfile_tcp_stream(remote_host) + char remote_host[]; +{ + + char *tput_title = "\ +Recv Send Send \n\ +Socket Socket Message Elapsed \n\ +Size Size Size Time Throughput \n\ +bytes bytes bytes secs. %s/sec \n\n"; + + char *tput_fmt_0 = + "%7.2f %s\n"; + + char *tput_fmt_1 = + "%6d %6d %6d %-6.2f %7.2f %s\n"; + + char *cpu_title = "\ +Recv Send Send Utilization Service Demand\n\ +Socket Socket Message Elapsed Send Recv Send Recv\n\ +Size Size Size Time Throughput local remote local remote\n\ +bytes bytes bytes secs. %-8.8s/s %% %c %% %c us/KB us/KB\n\n"; + + char *cpu_fmt_0 = + "%6.3f %c %s\n"; + char *cpu_fmt_1 = + "%6d %6d %6d %-6.2f %7.2f %-6.2f %-6.2f %-6.3f %-6.3f %s\n"; + + char *ksink_fmt = "\n\ +Alignment Offset %-8.8s %-8.8s Sends %-8.8s Recvs\n\ +Local Remote Local Remote Xfered Per Per\n\ +Send Recv Send Recv Send (avg) Recv (avg)\n\ +%5d %5d %5d %5d %6.4g %6.2f %6d %6.2f %6d\n"; + +char *ksink_fmt2 = "\n\ +Maximum\n\ +Segment\n\ +Size (bytes)\n\ +%6d\n"; + + float elapsed_time; + + /* what we want is to have a buffer space that is at least one */ + /* send-size greater than our send window. this will insure that we */ + /* are never trying to re-use a buffer that may still be in the hands */ + /* of the transport. This buffer will be malloc'd after we have found */ + /* the size of the local senc socket buffer. We will want to deal */ + /* with alignment and offset concerns as well. */ + + struct sendfile_ring_elt *send_ring; + + int len; + unsigned int nummessages = 0; + SOCKET send_socket; + int bytes_remaining; + int tcp_mss = -1; /* possibly uninitialized on printf far below */ + + /* with links like fddi, one can send > 32 bits worth of bytes */ + /* during a test... ;-) at some point, this should probably become a */ + /* 64bit integral type, but those are not entirely common yet */ + double bytes_sent = 0.0; + + float local_cpu_utilization; + float local_service_demand; + float remote_cpu_utilization; + float remote_service_demand; + + double thruput; + + struct addrinfo *remote_res; + struct addrinfo *local_res; + struct sockaddr_in server; + +#if defined(__linux) || defined(__sun) + off_t scratch_offset; /* the linux sendfile() call will update + the offset variable, which is + something we do _not_ want to happen + to the value in the send_ring! so, we + have to use a scratch variable. */ +#endif /* __linux || defined(__sun) */ +#if defined (USE_OSX) + off_t scratch_len; /* Darwin 9.x need a value-result parameter */ +#endif +#if defined (__sun) + size_t scratch_len; /* the sun sendfilev() needs a place to + tell us how many bytes were written, + even though it also returns the value */ + sendfilevec_t sv; +#endif /* __sun */ + + struct tcp_stream_request_struct *tcp_stream_request; + struct tcp_stream_response_struct *tcp_stream_response; + struct tcp_stream_results_struct *tcp_stream_result; + + tcp_stream_request = + (struct tcp_stream_request_struct *)netperf_request.content.test_specific_data; + tcp_stream_response = + (struct tcp_stream_response_struct *)netperf_response.content.test_specific_data; + tcp_stream_result = + (struct tcp_stream_results_struct *)netperf_response.content.test_specific_data; + +#ifdef WANT_HISTOGRAM + if (verbosity > 1) { + time_hist = HIST_new(); + } +#endif /* WANT_HISTOGRAM */ + + /* since we are now disconnected from the code that established the */ + /* control socket, and since we want to be able to use different */ + /* protocols and such, we are passed the name of the remote host and */ + /* must turn that into the test specific addressing information. */ + + bzero((char *)&server, + sizeof(server)); + + complete_addrinfos(&remote_res, + &local_res, + remote_host, + SOCK_STREAM, + IPPROTO_TCP, + 0); + + if ( print_headers ) { + /* we want to have some additional, interesting information in */ + /* the headers. we know some of it here, but not all, so we will */ + /* only print the test title here and will print the results */ + /* titles after the test is finished */ +#ifdef QUICK_SENDPATH + print_top_test_header("TCP SENDPATH TEST",local_res,remote_res); +#else + print_top_test_header("TCP SENDFILE TEST",local_res,remote_res); +#endif /* QUICK_SENDPATH */ + } + send_ring = NULL; + confidence_iteration = 1; + init_stat(); + + /* we have a great-big while loop which controls the number of times */ + /* we run a particular test. this is for the calculation of a */ + /* confidence interval (I really should have stayed awake during */ + /* probstats :). If the user did not request confidence measurement */ + /* (no confidence is the default) then we will only go though the */ + /* loop once. the confidence stuff originates from the folks at IBM */ + + while (((confidence < 0) && (confidence_iteration < iteration_max)) || + (confidence_iteration <= iteration_min)) { + + /* initialize a few counters. we have to remember that we might be */ + /* going through the loop more than once. */ + + nummessages = 0; + bytes_sent = 0.0; + times_up = 0; + + /* set up the data socket */ + send_socket = create_data_socket(local_res); + + if (send_socket == INVALID_SOCKET){ + perror("netperf: sendfile_tcp_stream: tcp stream data socket"); + exit(1); + } + + if (debug) { + fprintf(where,"sendfile_tcp_stream: send_socket obtained...\n"); + } + +#if defined(TCP_CORK) + /* should this even be here?!? */ + if (loc_tcpcork > 0) { + /* the user wishes for us to set TCP_CORK on the socket */ + int one = 1; + if (setsockopt(send_socket, + getprotobyname("tcp")->p_proto, + TCP_CORK, + (char *)&one, + sizeof(one)) == SOCKET_ERROR) { + perror("netperf: sendfile_tcp_stream: tcp_cork"); + exit(1); + } + if (debug) { + fprintf(where,"sendfile_tcp_stream: tcp_cork...\n"); + } + } + +#endif /* TCP_CORK */ + + /* at this point, we have either retrieved the socket buffer sizes, */ + /* or have tried to set them, so now, we may want to set the send */ + /* size based on that (because the user either did not use a -m */ + /* option, or used one with an argument of 0). If the socket buffer */ + /* size is not available, we will set the send size to 4KB - no */ + /* particular reason, just arbitrary... */ + + /*check for file size/ min file size here? create file here/ back out???*/ + + if (send_size == 0) { + if (lss_size > 0) { + send_size = lss_size; + } + else { + send_size = 4096; + } + } + + /* set-up the data buffer ring with the requested alignment and + offset. note also that we have allocated a quantity of memory + that is at least one send-size greater than our socket buffer + size. We want to be sure that there are at least two buffers + allocated - this can be a bit of a problem when the send_size + is bigger than the socket size, so we must check... the user + may have wanted to explicitly set the "width" of our send + buffers, we should respect that wish... */ + + /*sendring -> an offset index that will shift the starting point of the*/ + /*section of the file sent throughout the file*/ + + if (send_width == 0) { + send_width = (lss_size/send_size) + 1; + if (send_width == 1) send_width++; + } + + if (send_ring == NULL) { + + /* only allocate the send ring once. this is a networking test, + not a memory allocation test. this way, we do not need a + deallocate_buffer_ring() routine, and I don't feel like + writing one anyway :) raj 11/94 */ + + send_ring = alloc_sendfile_buf_ring(send_width, + send_size, + local_send_align, + local_send_offset); + } + + /* If the user has requested cpu utilization measurements, we must + calibrate the cpu(s). We will perform this task within the + tests themselves. If the user has specified the cpu rate, then + calibrate_local_cpu will return rather quickly as it will have + nothing to do. If local_cpu_rate is zero, then we will go + through all the "normal" calibration stuff and return the rate + back. */ + + if (local_cpu_usage) { + local_cpu_rate = calibrate_local_cpu(local_cpu_rate); + } + + /* Tell the remote end to do a listen. The server alters the + socket paramters on the other side at this point, hence the + reason for all the values being passed in the setup + message. If the user did not specify any of the parameters, + they will be passed as 0, which will indicate to the remote + that no changes beyond the system's default should be + used. Alignment is the exception, it will default to 1, which + will be no alignment alterations. */ + + netperf_request.content.request_type = DO_TCP_STREAM; + tcp_stream_request->send_buf_size = rss_size_req; + tcp_stream_request->recv_buf_size = rsr_size_req; + tcp_stream_request->receive_size = recv_size; + tcp_stream_request->no_delay = rem_nodelay; + tcp_stream_request->recv_alignment = remote_recv_align; + tcp_stream_request->recv_offset = remote_recv_offset; + tcp_stream_request->measure_cpu = remote_cpu_usage; + tcp_stream_request->cpu_rate = remote_cpu_rate; + + if (test_time) { + tcp_stream_request->test_length = test_time; + } + else { + tcp_stream_request->test_length = test_bytes; + } + + tcp_stream_request->so_rcvavoid = rem_rcvavoid; + tcp_stream_request->so_sndavoid = rem_sndavoid; + +#ifdef DIRTY + tcp_stream_request->dirty_count = rem_dirty_count; + tcp_stream_request->clean_count = rem_clean_count; +#endif /* DIRTY */ + tcp_stream_request->port = atoi(remote_data_port); + tcp_stream_request->ipfamily = af_to_nf(remote_res->ai_family); + + if (debug > 1) { + fprintf(where, + "netperf: send_tcp_stream: requesting TCP stream test\n"); + } + + send_request(); + + /* The response from the remote will contain all of the relevant + socket parameters for this test type. We will put them back + into the variables here so they can be displayed if desired. + The remote will have calibrated CPU if necessary, and will have + done all the needed set-up we will have calibrated the cpu + locally before sending the request, and will grab the counter + value right after the connect returns. The remote will grab the + counter right after the accept call. This saves the hassle of + extra messages being sent for the TCP tests. */ + + recv_response(); + + if (!netperf_response.content.serv_errno) { + if (debug) + fprintf(where,"remote listen done.\n"); + rsr_size = tcp_stream_response->recv_buf_size; + rss_size = tcp_stream_response->send_buf_size; + rem_nodelay = tcp_stream_response->no_delay; + remote_cpu_usage= tcp_stream_response->measure_cpu; + remote_cpu_rate = tcp_stream_response->cpu_rate; + + /* we have to make sure that the server port number is in */ + /* network order */ + set_port_number(remote_res,(short)tcp_stream_response->data_port_number); + rem_rcvavoid = tcp_stream_response->so_rcvavoid; + rem_sndavoid = tcp_stream_response->so_sndavoid; + } + else { + Set_errno(netperf_response.content.serv_errno); + fprintf(where, + "netperf: remote error %d", + netperf_response.content.serv_errno); + perror(""); + fflush(where); + + exit(1); + } + +#ifdef WANT_DEMO + DEMO_STREAM_SETUP(lss_size,rsr_size) +#endif + + /*Connect up to the remote port on the data socket */ + if (connect(send_socket, + remote_res->ai_addr, + remote_res->ai_addrlen) == INVALID_SOCKET){ + perror("netperf: send_tcp_stream: data socket connect failed"); + printf(" port: %d\n",ntohs(server.sin_port)); + exit(1); + } + +#ifdef WIN32 + /* this is used so the timer thread can close the socket out from */ + /* under us, which to date is the easiest/cleanest/least */ + /* Windows-specific way I can find to force the winsock calls to */ + /* return WSAEINTR with the test is over. anything that will run on */ + /* 95 and NT and is closer to what netperf expects from Unix signals */ + /* and such would be appreciated raj 1/96 */ + win_kludge_socket = send_socket; +#endif /* WIN32 */ + + /* Data Socket set-up is finished. If there were problems, either + the connect would have failed, or the previous response would + have indicated a problem. I failed to see the value of the + extra message after the accept on the remote. If it failed, + we'll see it here. If it didn't, we might as well start pumping + data. */ + + /* Set-up the test end conditions. For a stream test, they can be */ + /* either time or byte-count based. */ + + if (test_time) { + /* The user wanted to end the test after a period of time. */ + times_up = 0; + bytes_remaining = 0; + + /* in previous revisions, we had the same code repeated throught + all the test suites. this was unnecessary, and meant more + work for me when I wanted to switch to POSIX signals, so I + have abstracted this out into a routine in netlib.c. if you + are experiencing signal problems, you might want to look + there. raj 11/94 */ + + start_timer(test_time); + } + else { + /* The tester wanted to send a number of bytes. */ + bytes_remaining = test_bytes; + times_up = 1; + } + + /* The cpu_start routine will grab the current time and possibly */ + /* value of the idle counter for later use in measuring cpu */ + /* utilization and/or service demand and thruput. */ + + cpu_start(local_cpu_usage); + +#ifdef WANT_INTERVALS + INTERVALS_INIT(); +#endif /* WANT_INTERVALS */ + + + /* before we start, initialize a few variables */ + +#ifdef WANT_DEMO + if (demo_mode) { + HIST_timestamp(demo_one_ptr); + } +#endif + + /* We use an "OR" to control test execution. When the test is + controlled by time, the byte count check will always return + false. When the test is controlled by byte count, the time test + will always return false. When the test is finished, the whole + expression will go false and we will stop sending data. */ + + while ((!times_up) || (bytes_remaining > 0)) { + + /* the sendfile_tcp_stream test does not support making the buffers + dirty. 08/2000 */ + +#ifdef WANT_HISTOGRAM + if (verbosity > 1) { + /* timestamp just before we go into sendfile() and then again + just after we come out raj 08/2000 */ + /* but only if we are actually going to display a histogram */ + HIST_timestamp(&time_one); + } +#endif /* WANT_HISTOGRAM */ + + /* you can look at netlib.h for a description of the fields we + are passing to sendfile(). 08/2000 */ +#ifdef QUICK_SENDPATH + if ((len=sendpath(send_socket, + fill_file, + send_ring->offset, + send_ring->length, + send_ring->hdtrl, + send_ring->flags)) != send_size) +#elif defined(__linux) + scratch_offset = send_ring->offset; + if ((len=sendfile(send_socket, + send_ring->fildes, + &scratch_offset, /* modified after the call! */ + send_ring->length)) != send_size) +#elif defined (__sun) + /* We must call with SFV_NOWAIT and a large file size (>= 16MB) to + get zero-copy, as well as compiling with -D_LARGEFILE_SOURCE + -D_FILE_OFFSET_BITS=64 */ + sv.sfv_fd = send_ring->fildes; + sv.sfv_flag = SFV_NOWAIT; + sv.sfv_off = send_ring->offset; + sv.sfv_len = send_ring->length; + if ((len = sendfilev(send_socket, &sv, 1, &scratch_len)) != send_size) +#elif defined(__FreeBSD__) + /* so close to HP-UX and yet so far away... :) */ + if ((sendfile(send_ring->fildes, + send_socket, + send_ring->offset, + send_ring->length, + NULL, + (off_t *)&len, + send_ring->flags) != 0) || + (len != send_size)) +#elif defined(USE_OSX) + scratch_len = send_ring->length; + if ((sendfile(send_ring->fildes, + send_socket, + send_ring->offset, + (off_t *)&scratch_len, + NULL, + send_ring->flags) != 0) || + (scratch_len != send_size)) +#else /* original sendile HP-UX */ + if ((len=sendfile(send_socket, + send_ring->fildes, + send_ring->offset, + send_ring->length, + send_ring->hdtrl, + send_ring->flags)) != send_size) +#endif /* QUICK_SENDPATH */ + { + /* the test was interrupted, must be the end of test. the + send_tcp_stream code has some WIN32 ifdefs that we do not + need here. */ + if ((len >=0) || SOCKET_EINTR(len)) { + break; + } + perror("netperf: data send error: sendfile"); + fprintf(stderr, + "len was %d send_size was %d\n", + len, + send_size); + fflush(stderr); + exit(1); + } + + /* offset += len;*/ + +#ifdef WANT_HISTOGRAM + if (verbosity > 1) { + /* timestamp the exit from the send call and update the + histogram */ + + HIST_timestamp(&time_two); + HIST_add(time_hist,delta_micro(&time_one,&time_two)); + } +#endif /* WANT_HISTOGRAM */ + +#ifdef WANT_DEMO + DEMO_STREAM_INTERVAL(send_size); +#endif + +#ifdef WANT_INTERVALS + INTERVALS_WAIT(); +#endif /* WANT_INTERVALS */ + + /* now we want to move our pointer to the next position in the */ + /* data buffer...we may also want to wrap back to the "beginning" */ + /* of the bufferspace, so we will mod the number of messages sent */ + /* by the send width, and use that to calculate the offset to add */ + /* to the base pointer. */ + + nummessages++; + send_ring = send_ring->next; + if (bytes_remaining) { + bytes_remaining -= send_size; + } + } + + /* The test is over. Flush the buffers to the remote end. We do a + graceful release to insure that all data has been taken by the + remote. */ + + /* but first, if the verbosity is greater than 1, find-out what */ + /* the TCP maximum segment_size was (if possible) */ + if (verbosity > 1) { + tcp_mss = -1; + get_tcp_info(send_socket,&tcp_mss); + } + + if (shutdown(send_socket,SHUT_WR) == SOCKET_ERROR) { + perror("netperf: cannot shutdown tcp stream socket"); + exit(1); + } + + /* hang a recv() off the socket to block until the remote has */ + /* brought all the data up into the application. it will do a */ + /* shutdown to cause a FIN to be sent our way. We will assume that */ + /* any exit from the recv() call is good... raj 4/93 */ + + /* since we are using sendfile() instead of send, we have no + scratch buffer from the send_ring to use for the + receive. however, since we "know" that the recv should be + returning zero bytes (not that we are making the checks we + should) we can pass the address of the flags field. raj 08/2000 + */ + + recv(send_socket, + &(send_ring->flags), + sizeof(send_ring->flags), + 0); + + /* this call will always give us the elapsed time for the test, and */ + /* will also store-away the necessaries for cpu utilization */ + + cpu_stop(local_cpu_usage,&elapsed_time); /* was cpu being */ + /* measured and how */ + /* long did we really */ + /* run? */ + + /* we are finished with the socket, so close it to prevent hitting */ + /* the limit on maximum open files. */ + + close(send_socket); + + /* Get the statistics from the remote end. The remote will have */ + /* calculated service demand and all those interesting things. If it */ + /* wasn't supposed to care, it will return obvious values. */ + + recv_response(); + + if (!netperf_response.content.serv_errno) { + if (debug) + fprintf(where,"remote results obtained\n"); + } + + else { + Set_errno(netperf_response.content.serv_errno); + fprintf(where, + "netperf: remote error %d", + netperf_response.content.serv_errno); + perror(""); + fflush(where); + + exit(1); + } + + /* We now calculate what our thruput was for the test. In the future, */ + /* we may want to include a calculation of the thruput measured by */ + /* the remote, but it should be the case that for a TCP stream test, */ + /* that the two numbers should be *very* close... We calculate */ + /* bytes_sent regardless of the way the test length was controlled. */ + /* If it was time, we needed to, and if it was by bytes, the user may */ + /* have specified a number of bytes that wasn't a multiple of the */ + /* send_size, so we really didn't send what he asked for ;-) */ + + bytes_sent = ntohd(tcp_stream_result->bytes_received); + + thruput = calc_thruput(bytes_sent); + + if (local_cpu_usage || remote_cpu_usage) { + + /* We must now do a little math for service demand and cpu */ + /* utilization for the system(s) */ + /* Of course, some of the information might be bogus because */ + /* there was no idle counter in the kernel(s). We need to make */ + /* a note of this for the user's benefit...*/ + if (local_cpu_usage) { + + local_cpu_utilization = calc_cpu_util(0.0); + local_service_demand = calc_service_demand(bytes_sent, + 0.0, + 0.0, + 0); + } + else { + local_cpu_utilization = (float) -1.0; + local_service_demand = (float) -1.0; + } + + if (remote_cpu_usage) { + + remote_cpu_utilization = tcp_stream_result->cpu_util; + remote_service_demand = calc_service_demand(bytes_sent, + 0.0, + remote_cpu_utilization, + tcp_stream_result->num_cpus); + } + else { + remote_cpu_utilization = (float) -1.0; + remote_service_demand = (float) -1.0; + } + } + else { + /* we were not measuring cpu, for the confidence stuff, we */ + /* should make it -1.0 */ + local_cpu_utilization = (float) -1.0; + local_service_demand = (float) -1.0; + remote_cpu_utilization = (float) -1.0; + remote_service_demand = (float) -1.0; + } + + /* at this point, we want to calculate the confidence information. */ + /* if debugging is on, calculate_confidence will print-out the */ + /* parameters we pass it */ + + calculate_confidence(confidence_iteration, + elapsed_time, + thruput, + local_cpu_utilization, + remote_cpu_utilization, + local_service_demand, + remote_service_demand); + + confidence_iteration++; + } + + /* at this point, we have finished making all the runs that we */ + /* will be making. so, we should extract what the calcuated values */ + /* are for all the confidence stuff. we could make the values */ + /* global, but that seemed a little messy, and it did not seem worth */ + /* all the mucking with header files. so, we create a routine much */ + /* like calcualte_confidence, which just returns the mean values. */ + /* raj 11/94 */ + + retrieve_confident_values(&elapsed_time, + &thruput, + &local_cpu_utilization, + &remote_cpu_utilization, + &local_service_demand, + &remote_service_demand); + + /* We are now ready to print all the information. If the user */ + /* has specified zero-level verbosity, we will just print the */ + /* local service demand, or the remote service demand. If the */ + /* user has requested verbosity level 1, he will get the basic */ + /* "streamperf" numbers. If the user has specified a verbosity */ + /* of greater than 1, we will display a veritable plethora of */ + /* background information from outside of this block as it it */ + /* not cpu_measurement specific... */ + + if (confidence < 0) { + /* we did not hit confidence, but were we asked to look for it? */ + if (iteration_max > 1) { + display_confidence(); + } + } + + if (local_cpu_usage || remote_cpu_usage) { + local_cpu_method = format_cpu_method(cpu_method); + remote_cpu_method = format_cpu_method(tcp_stream_result->cpu_method); + + switch (verbosity) { + case 0: + + if (local_cpu_usage) { + fprintf(where, + cpu_fmt_0, + local_service_demand, + local_cpu_method, + ((print_headers) || + (result_brand == NULL)) ? "" : result_brand); + } + + else { + fprintf(where, + cpu_fmt_0, + remote_service_demand, + remote_cpu_method, + ((print_headers) || + (result_brand == NULL)) ? "" : result_brand); + } + + break; + + case 1: + case 2: + if (print_headers) { + fprintf(where, + cpu_title, + format_units(), + local_cpu_method, + remote_cpu_method); + } + + fprintf(where, + cpu_fmt_1, /* the format string */ + rsr_size, /* remote recvbuf size */ + lss_size, /* local sendbuf size */ + send_size, /* how large were the sends */ + elapsed_time, /* how long was the test */ + thruput, /* what was the xfer rate */ + local_cpu_utilization, /* local cpu */ + remote_cpu_utilization, /* remote cpu */ + local_service_demand, /* local service demand */ + remote_service_demand, /* remote service demand */ + ((print_headers) || + (result_brand == NULL)) ? "" : result_brand); + break; + } + + } + + else { + /* The tester did not wish to measure service demand. */ + + switch (verbosity) { + + case 0: + + fprintf(where, + tput_fmt_0, + thruput, + ((print_headers) || + (result_brand == NULL)) ? "" : result_brand); + break; + + case 1: + case 2: + + if (print_headers) { + fprintf(where,tput_title,format_units()); + } + + fprintf(where, + tput_fmt_1, /* the format string */ + rsr_size, /* remote recvbuf size */ + lss_size, /* local sendbuf size */ + send_size, /* how large were the sends */ + elapsed_time, /* how long did it take */ + thruput, /* how fast did it go */ + ((print_headers) || + (result_brand == NULL)) ? "" : result_brand); + break; + } + } + + /* it would be a good thing to include information about some of the */ + /* other parameters that may have been set for this test, but at the */ + /* moment, I do not wish to figure-out all the formatting, so I will */ + /* just put this comment here to help remind me that it is something */ + /* that should be done at a later time. */ + + if (verbosity > 1) { + + /* The user wanted to know it all, so we will give it to him. */ + /* This information will include as much as we can find about */ + /* TCP statistics, the alignments of the sends and receives */ + /* and all that sort of rot... */ + + /* this stuff needs to be worked-out in the presence of confidence */ + /* intervals and multiple iterations of the test... raj 11/94 */ + + fprintf(where, + ksink_fmt, + "Bytes", + "Bytes", + "Bytes", + local_send_align, + remote_recv_align, + local_send_offset, + remote_recv_offset, + bytes_sent, + bytes_sent / (double)nummessages, + nummessages, + bytes_sent / (double)tcp_stream_result->recv_calls, + tcp_stream_result->recv_calls); + + fprintf(where, + ksink_fmt2, + tcp_mss); + + fflush(where); + +#ifdef WANT_HISTOGRAM + + fprintf(where,"\n\nHistogram of time spent in send() call.\n"); + fflush(where); + HIST_report(time_hist); +#endif /* WANT_HISTOGRAM */ + } +} + +#endif /* HAVE_SENDFILE */ + +/* This is the server-side routine for the tcp stream test. It is */ +/* implemented as one routine. I could break things-out somewhat, but */ +/* didn't feel it was necessary. */ + +void +recv_tcp_stream() +{ + + struct sockaddr_storage myaddr_in, peeraddr_in; + SOCKET s_listen,s_data; + netperf_socklen_t addrlen; + int len; + unsigned int receive_calls; + float elapsed_time; + double bytes_received; + + struct ring_elt *recv_ring; + + struct addrinfo *local_res; + char local_name[BUFSIZ]; + char port_buffer[PORTBUFSIZE]; + +#ifdef DO_SELECT + fd_set readfds; + struct timeval timeout; +#endif /* DO_SELECT */ + + struct tcp_stream_request_struct *tcp_stream_request; + struct tcp_stream_response_struct *tcp_stream_response; + struct tcp_stream_results_struct *tcp_stream_results; + +#ifdef DO_SELECT + FD_ZERO(&readfds); + timeout.tv_sec = 1; + timeout.tv_usec = 0; +#endif /* DO_SELECT */ + + tcp_stream_request = + (struct tcp_stream_request_struct *)netperf_request.content.test_specific_data; + tcp_stream_response = + (struct tcp_stream_response_struct *)netperf_response.content.test_specific_data; + tcp_stream_results = + (struct tcp_stream_results_struct *)netperf_response.content.test_specific_data; + + if (debug) { + fprintf(where,"netserver: recv_tcp_stream: entered...\n"); + fflush(where); + } + + /* We want to set-up the listen socket with all the desired */ + /* parameters and then let the initiator know that all is ready. If */ + /* socket size defaults are to be used, then the initiator will have */ + /* sent us 0's. If the socket sizes cannot be changed, then we will */ + /* send-back what they are. If that information cannot be determined, */ + /* then we send-back -1's for the sizes. If things go wrong for any */ + /* reason, we will drop back ten yards and punt. */ + + /* If anything goes wrong, we want the remote to know about it. It */ + /* would be best if the error that the remote reports to the user is */ + /* the actual error we encountered, rather than some bogus unexpected */ + /* response type message. */ + + if (debug) { + fprintf(where,"recv_tcp_stream: setting the response type...\n"); + fflush(where); + } + + netperf_response.content.response_type = TCP_STREAM_RESPONSE; + + if (debug) { + fprintf(where,"recv_tcp_stream: the response type is set...\n"); + fflush(where); + } + + /* We now alter the message_ptr variable to be at the desired */ + /* alignment with the desired offset. */ + + if (debug) { + fprintf(where,"recv_tcp_stream: requested alignment of %d\n", + tcp_stream_request->recv_alignment); + fflush(where); + } + + /* create_data_socket expects to find some things in the global */ + /* variables, so set the globals based on the values in the request. */ + /* once the socket has been created, we will set the response values */ + /* based on the updated value of those globals. raj 7/94 */ + lss_size_req = tcp_stream_request->send_buf_size; + lsr_size_req = tcp_stream_request->recv_buf_size; + loc_nodelay = tcp_stream_request->no_delay; + loc_rcvavoid = tcp_stream_request->so_rcvavoid; + loc_sndavoid = tcp_stream_request->so_sndavoid; + + set_hostname_and_port(local_name, + port_buffer, + nf_to_af(tcp_stream_request->ipfamily), + tcp_stream_request->port); + + local_res = complete_addrinfo(local_name, + local_name, + port_buffer, + nf_to_af(tcp_stream_request->ipfamily), + SOCK_STREAM, + IPPROTO_TCP, + 0); + + s_listen = create_data_socket(local_res); + + if (s_listen == INVALID_SOCKET) { + netperf_response.content.serv_errno = errno; + send_response(); + exit(1); + } + +#ifdef WIN32 + /* The test timer can fire during operations on the listening socket, + so to make the start_timer below work we have to move + it to close s_listen while we are blocked on accept. */ + win_kludge_socket2 = s_listen; +#endif + + /* what sort of sizes did we end-up with? */ + if (tcp_stream_request->receive_size == 0) { + if (lsr_size > 0) { + recv_size = lsr_size; + } + else { + recv_size = 4096; + } + } + else { + recv_size = tcp_stream_request->receive_size; + } + + /* we want to set-up our recv_ring in a manner analagous to what we */ + /* do on the sending side. this is more for the sake of symmetry */ + /* than for the needs of say copy avoidance, but it might also be */ + /* more realistic - this way one could conceivably go with a */ + /* double-buffering scheme when taking the data an putting it into */ + /* the filesystem or something like that. raj 7/94 */ + + if (recv_width == 0) { + recv_width = (lsr_size/recv_size) + 1; + if (recv_width == 1) recv_width++; + } + + recv_ring = allocate_buffer_ring(recv_width, + recv_size, + tcp_stream_request->recv_alignment, + tcp_stream_request->recv_offset); + + if (debug) { + fprintf(where,"recv_tcp_stream: receive alignment and offset set...\n"); + fflush(where); + } + + /* Now, let's set-up the socket to listen for connections */ + if (listen(s_listen, 5) == SOCKET_ERROR) { + netperf_response.content.serv_errno = errno; + close(s_listen); + send_response(); + + exit(1); + } + + + /* now get the port number assigned by the system */ + addrlen = sizeof(myaddr_in); + if (getsockname(s_listen, + (struct sockaddr *)&myaddr_in, + &addrlen) == SOCKET_ERROR){ + netperf_response.content.serv_errno = errno; + close(s_listen); + send_response(); + + exit(1); + } + + /* Now myaddr_in contains the port and the internet address this is */ + /* returned to the sender also implicitly telling the sender that the */ + /* socket buffer sizing has been done. */ + + tcp_stream_response->data_port_number = + (int) ntohs(((struct sockaddr_in *)&myaddr_in)->sin_port); + netperf_response.content.serv_errno = 0; + + /* But wait, there's more. If the initiator wanted cpu measurements, */ + /* then we must call the calibrate routine, which will return the max */ + /* rate back to the initiator. If the CPU was not to be measured, or */ + /* something went wrong with the calibration, we will return a -1 to */ + /* the initiator. */ + + tcp_stream_response->cpu_rate = (float)0.0; /* assume no cpu */ + if (tcp_stream_request->measure_cpu) { + tcp_stream_response->measure_cpu = 1; + tcp_stream_response->cpu_rate = + calibrate_local_cpu(tcp_stream_request->cpu_rate); + } + else { + tcp_stream_response->measure_cpu = 0; + } + + /* before we send the response back to the initiator, pull some of */ + /* the socket parms from the globals */ + tcp_stream_response->send_buf_size = lss_size; + tcp_stream_response->recv_buf_size = lsr_size; + tcp_stream_response->no_delay = loc_nodelay; + tcp_stream_response->so_rcvavoid = loc_rcvavoid; + tcp_stream_response->so_sndavoid = loc_sndavoid; + tcp_stream_response->receive_size = recv_size; + + send_response(); + + addrlen = sizeof(peeraddr_in); + + if ((s_data=accept(s_listen, + (struct sockaddr *)&peeraddr_in, + &addrlen)) == INVALID_SOCKET) { + /* Let's just punt. The remote will be given some information */ + close(s_listen); + exit(1); + } + +#ifdef WIN32 + /* this is used so the timer thread can close the socket out from */ + /* under us, which to date is the easiest/cleanest/least */ + /* Windows-specific way I can find to force the winsock calls to */ + /* return WSAEINTR with the test is over. anything that will run on */ + /* 95 and NT and is closer to what netperf expects from Unix signals */ + /* and such would be appreciated raj 1/96 */ + win_kludge_socket = s_data; + win_kludge_socket2 = INVALID_SOCKET; +#endif /* WIN32 */ + + times_up = 0; + + start_timer(tcp_stream_request->test_length + PAD_TIME); + +#ifdef KLUDGE_SOCKET_OPTIONS + /* this is for those systems which *INCORRECTLY* fail to pass */ + /* attributes across an accept() call. Including this goes against */ + /* my better judgement :( raj 11/95 */ + + kludge_socket_options(s_data); + +#endif /* KLUDGE_SOCKET_OPTIONS */ + + /* Now it's time to start receiving data on the connection. We will */ + /* first grab the apropriate counters and then start grabbing. */ + + cpu_start(tcp_stream_request->measure_cpu); + + /* The loop will exit when the sender does a shutdown, which will */ + /* return a length of zero */ + + /* there used to be an #ifdef DIRTY call to access_buffer() here, + but we have switched from accessing the buffer before the recv() + call to accessing the buffer after the recv() call. The + accessing before was, IIRC, related to having dirty data when + doing page-flipping copy avoidance. */ + + bytes_received = 0; + receive_calls = 0; + + while (!times_up && ((len = recv(s_data, recv_ring->buffer_ptr, recv_size, 0)) != 0)) { + if (len == SOCKET_ERROR ) + { + netperf_response.content.serv_errno = errno; + send_response(); + exit(1); + } + bytes_received += len; + receive_calls++; + +#ifdef DIRTY + /* we access the buffer after the recv() call now, rather than before */ + access_buffer(recv_ring->buffer_ptr, + recv_size, + tcp_stream_request->dirty_count, + tcp_stream_request->clean_count); +#endif /* DIRTY */ + + + /* move to the next buffer in the recv_ring */ + recv_ring = recv_ring->next; + +#ifdef PAUSE + sleep(1); +#endif /* PAUSE */ + +#ifdef DO_SELECT + FD_SET(s_data,&readfds); + select(s_data+1,&readfds,NULL,NULL,&timeout); +#endif /* DO_SELECT */ + + } + + /* perform a shutdown to signal the sender that */ + /* we have received all the data sent. raj 4/93 */ + + if (shutdown(s_data,SHUT_WR) == SOCKET_ERROR) { + netperf_response.content.serv_errno = errno; + send_response(); + exit(1); + } + + cpu_stop(tcp_stream_request->measure_cpu,&elapsed_time); + + /* send the results to the sender */ + + if (debug) { + fprintf(where, + "recv_tcp_stream: got %g bytes\n", + bytes_received); + fprintf(where, + "recv_tcp_stream: got %d recvs\n", + receive_calls); + fflush(where); + } + + tcp_stream_results->bytes_received = htond(bytes_received); + tcp_stream_results->elapsed_time = elapsed_time; + tcp_stream_results->recv_calls = receive_calls; + + tcp_stream_results->cpu_method = cpu_method; + tcp_stream_results->num_cpus = lib_num_loc_cpus; + + if (tcp_stream_request->measure_cpu) { + tcp_stream_results->cpu_util = calc_cpu_util(0.0); + }; + + if (debug) { + fprintf(where, + "recv_tcp_stream: test complete, sending results.\n"); + fprintf(where, + " bytes_received %g receive_calls %d\n", + bytes_received, + receive_calls); + fprintf(where, + " len %d\n", + len); + fflush(where); + } + + send_response(); + + /* we are now done with the sockets */ + close(s_data); + close(s_listen); + + } + +/* This is the server-side routine for the tcp maerts test. It is + implemented as one routine. I could break things-out somewhat, but + didn't feel it was necessary. */ + +void +recv_tcp_maerts() +{ + + struct sockaddr_storage myaddr_in, peeraddr_in; + struct addrinfo *local_res; + char local_name[BUFSIZ]; + char port_buffer[PORTBUFSIZE]; + + SOCKET s_listen,s_data; + netperf_socklen_t addrlen; + int len; + unsigned int send_calls; + float elapsed_time; + double bytes_sent = 0.0 ; + + struct ring_elt *send_ring; + + struct tcp_maerts_request_struct *tcp_maerts_request; + struct tcp_maerts_response_struct *tcp_maerts_response; + struct tcp_maerts_results_struct *tcp_maerts_results; + + tcp_maerts_request = + (struct tcp_maerts_request_struct *)netperf_request.content.test_specific_data; + tcp_maerts_response = + (struct tcp_maerts_response_struct *)netperf_response.content.test_specific_data; + tcp_maerts_results = + (struct tcp_maerts_results_struct *)netperf_response.content.test_specific_data; + + if (debug) { + fprintf(where,"netserver: recv_tcp_maerts: entered...\n"); + fflush(where); + } + + /* We want to set-up the listen socket with all the desired + parameters and then let the initiator know that all is ready. If + socket size defaults are to be used, then the initiator will have + sent us 0's. If the socket sizes cannot be changed, then we will + send-back what they are. If that information cannot be + determined, then we send-back -1's for the sizes. If things go + wrong for any reason, we will drop back ten yards and punt. */ + + /* If anything goes wrong, we want the remote to know about it. It + would be best if the error that the remote reports to the user is + the actual error we encountered, rather than some bogus + unexpected response type message. */ + + if (debug) { + fprintf(where,"recv_tcp_maerts: setting the response type...\n"); + fflush(where); + } + + netperf_response.content.response_type = TCP_MAERTS_RESPONSE; + + if (debug) { + fprintf(where,"recv_tcp_maerts: the response type is set...\n"); + fflush(where); + } + + /* We now alter the message_ptr variable to be at the desired */ + /* alignment with the desired offset. */ + + if (debug) { + fprintf(where,"recv_tcp_maerts: requested alignment of %d\n", + tcp_maerts_request->send_alignment); + fflush(where); + } + + /* Grab a socket to listen on, and then listen on it. */ + + if (debug) { + fprintf(where,"recv_tcp_maerts: grabbing a socket...\n"); + fflush(where); + } + + /* create_data_socket expects to find some things in the global */ + /* variables, so set the globals based on the values in the request. */ + /* once the socket has been created, we will set the response values */ + /* based on the updated value of those globals. raj 7/94 */ + lss_size_req = tcp_maerts_request->send_buf_size; + lsr_size_req = tcp_maerts_request->recv_buf_size; + loc_nodelay = tcp_maerts_request->no_delay; + loc_rcvavoid = tcp_maerts_request->so_rcvavoid; + loc_sndavoid = tcp_maerts_request->so_sndavoid; + + set_hostname_and_port(local_name, + port_buffer, + nf_to_af(tcp_maerts_request->ipfamily), + tcp_maerts_request->port); + + local_res = complete_addrinfo(local_name, + local_name, + port_buffer, + nf_to_af(tcp_maerts_request->ipfamily), + SOCK_STREAM, + IPPROTO_TCP, + 0); + + s_listen = create_data_socket(local_res); + + if (s_listen == INVALID_SOCKET) { + netperf_response.content.serv_errno = errno; + send_response(); + exit(1); + } + +#ifdef WIN32 + /* The test timer can fire during operations on the listening socket, + so to make the start_timer below work we have to move + it to close s_listen while we are blocked on accept. */ + win_kludge_socket2 = s_listen; +#endif + + + /* what sort of sizes did we end-up with? */ + if (tcp_maerts_request->send_size == 0) { + if (lss_size > 0) { + send_size = lss_size; + } + else { + send_size = 4096; + } + } + else { + send_size = tcp_maerts_request->send_size; + } + + /* we want to set-up our recv_ring in a manner analagous to what we */ + /* do on the recving side. this is more for the sake of symmetry */ + /* than for the needs of say copy avoidance, but it might also be */ + /* more realistic - this way one could conceivably go with a */ + /* double-buffering scheme when taking the data an putting it into */ + /* the filesystem or something like that. raj 7/94 */ + + if (send_width == 0) { + send_width = (lsr_size/send_size) + 1; + if (send_width == 1) send_width++; + } + + send_ring = allocate_buffer_ring(send_width, + send_size, + tcp_maerts_request->send_alignment, + tcp_maerts_request->send_offset); + + if (debug) { + fprintf(where,"recv_tcp_maerts: receive alignment and offset set...\n"); + fflush(where); + } + + /* Now, let's set-up the socket to listen for connections */ + if (listen(s_listen, 5) == SOCKET_ERROR) { + netperf_response.content.serv_errno = errno; + close(s_listen); + send_response(); + + exit(1); + } + + + /* now get the port number assigned by the system */ + addrlen = sizeof(myaddr_in); + if (getsockname(s_listen, + (struct sockaddr *)&myaddr_in, + &addrlen) == SOCKET_ERROR){ + netperf_response.content.serv_errno = errno; + close(s_listen); + send_response(); + + exit(1); + } + + /* Now myaddr_in contains the port and the internet address this is */ + /* returned to the sender also implicitly telling the sender that the */ + /* socket buffer sizing has been done. */ + + tcp_maerts_response->data_port_number = + (int) ntohs(((struct sockaddr_in *)&myaddr_in)->sin_port); + netperf_response.content.serv_errno = 0; + + /* But wait, there's more. If the initiator wanted cpu measurements, */ + /* then we must call the calibrate routine, which will return the max */ + /* rate back to the initiator. If the CPU was not to be measured, or */ + /* something went wrong with the calibration, we will return a -1 to */ + /* the initiator. */ + + tcp_maerts_response->cpu_rate = (float)0.0; /* assume no cpu */ + if (tcp_maerts_request->measure_cpu) { + tcp_maerts_response->measure_cpu = 1; + tcp_maerts_response->cpu_rate = + calibrate_local_cpu(tcp_maerts_request->cpu_rate); + } + else { + tcp_maerts_response->measure_cpu = 0; + } + + /* before we send the response back to the initiator, pull some of */ + /* the socket parms from the globals */ + tcp_maerts_response->send_buf_size = lss_size; + tcp_maerts_response->recv_buf_size = lsr_size; + tcp_maerts_response->no_delay = loc_nodelay; + tcp_maerts_response->so_rcvavoid = loc_rcvavoid; + tcp_maerts_response->so_sndavoid = loc_sndavoid; + tcp_maerts_response->send_size = send_size; + + send_response(); + + addrlen = sizeof(peeraddr_in); + + /* we will start the timer before the accept() to be somewhat + analagous to the starting of the timer before the connect() call + in the TCP_STREAM test. raj 2002-06-21 */ + + start_timer(tcp_maerts_request->test_length); + + /* Now it's time to start receiving data on the connection. We will + first grab the apropriate counters and then start grabbing. */ + + cpu_start(tcp_maerts_request->measure_cpu); + + + if ((s_data=accept(s_listen, + (struct sockaddr *)&peeraddr_in, + &addrlen)) == INVALID_SOCKET) { + /* Let's just punt. The remote will be given some information */ + close(s_listen); + exit(1); + } + +#ifdef WIN32 + /* this is used so the timer thread can close the socket out from */ + /* under us, which to date is the easiest/cleanest/least */ + /* Windows-specific way I can find to force the winsock calls to */ + /* return WSAEINTR with the test is over. anything that will run on */ + /* 95 and NT and is closer to what netperf expects from Unix signals */ + /* and such would be appreciated raj 1/96 */ + win_kludge_socket = s_data; + win_kludge_socket2 = INVALID_SOCKET; +#endif /* WIN32 */ + +#ifdef KLUDGE_SOCKET_OPTIONS + + /* this is for those systems which *INCORRECTLY* fail to pass + attributes across an accept() call. Including this goes against + my better judgement :( raj 11/95 */ + + kludge_socket_options(s_data); + +#endif /* KLUDGE_SOCKET_OPTIONS */ + + /* The loop will exit when the sender does a shutdown, which will */ + /* return a length of zero */ + + bytes_sent = 0.0; + send_calls = 0; + + len = 0; /* nt-lint; len is not initialized (printf far below) if + times_up initially true.*/ + times_up = 0; /* must remember to initialize this little beauty */ + while (!times_up) { + +#ifdef DIRTY + /* we want to dirty some number of consecutive integers in the buffer */ + /* we are about to send. we may also want to bring some number of */ + /* them cleanly into the cache. The clean ones will follow any dirty */ + /* ones into the cache. */ + + access_buffer(send_ring->buffer_ptr, + send_size, + tcp_maerts_request->dirty_count, + tcp_maerts_request->clean_count); + +#endif /* DIRTY */ + + if((len=send(s_data, + send_ring->buffer_ptr, + send_size, + 0)) != send_size) { + if ((len >=0) || SOCKET_EINTR(len)) { + /* the test was interrupted, must be the end of test */ + break; + } + netperf_response.content.serv_errno = errno; + send_response(); + exit(1); + } + + bytes_sent += len; + send_calls++; + + /* more to the next buffer in the send_ring */ + send_ring = send_ring->next; + + } + + /* perform a shutdown to signal the sender that */ + /* we have received all the data sent. raj 4/93 */ + + if (shutdown(s_data,SHUT_WR) == SOCKET_ERROR) { + netperf_response.content.serv_errno = errno; + send_response(); + exit(1); + } + + /* hang a recv() off the socket to block until the remote has + brought all the data up into the application. it will do a + shutdown to cause a FIN to be sent our way. We will assume that + any exit from the recv() call is good... raj 4/93 */ + + recv(s_data, send_ring->buffer_ptr, send_size, 0); + + + cpu_stop(tcp_maerts_request->measure_cpu,&elapsed_time); + + /* send the results to the sender */ + + if (debug) { + fprintf(where, + "recv_tcp_maerts: got %g bytes\n", + bytes_sent); + fprintf(where, + "recv_tcp_maerts: got %d sends\n", + send_calls); + fflush(where); + } + + tcp_maerts_results->bytes_sent = htond(bytes_sent); + tcp_maerts_results->elapsed_time = elapsed_time; + tcp_maerts_results->send_calls = send_calls; + + if (tcp_maerts_request->measure_cpu) { + tcp_maerts_results->cpu_util = calc_cpu_util(0.0); + }; + + if (debug) { + fprintf(where, + "recv_tcp_maerts: test complete, sending results.\n"); + fprintf(where, + " bytes_sent %g send_calls %d\n", + bytes_sent, + send_calls); + fprintf(where, + " len %d\n", + len); + fflush(where); + } + + tcp_maerts_results->cpu_method = cpu_method; + tcp_maerts_results->num_cpus = lib_num_loc_cpus; + send_response(); + + /* we are now done with the sockets */ + close(s_data); + close(s_listen); + + } + + + /* this routine implements the sending (netperf) side of the TCP_RR */ + /* test. */ + +void +send_tcp_rr(char remote_host[]) +{ + + char *tput_title = "\ +Local /Remote\n\ +Socket Size Request Resp. Elapsed Trans.\n\ +Send Recv Size Size Time Rate \n\ +bytes Bytes bytes bytes secs. per sec \n\n"; + + char *tput_title_band = "\ +Local /Remote\n\ +Socket Size Request Resp. Elapsed \n\ +Send Recv Size Size Time Throughput \n\ +bytes Bytes bytes bytes secs. %s/sec \n\n"; + + char *tput_fmt_0 = + "%7.2f %s\n"; + + char *tput_fmt_1_line_1 = "\ +%-6d %-6d %-6d %-6d %-6.2f %7.2f %s\n"; + char *tput_fmt_1_line_2 = "\ +%-6d %-6d\n"; + + char *cpu_title = "\ +Local /Remote\n\ +Socket Size Request Resp. Elapsed Trans. CPU CPU S.dem S.dem\n\ +Send Recv Size Size Time Rate local remote local remote\n\ +bytes bytes bytes bytes secs. per sec %% %c %% %c us/Tr us/Tr\n\n"; + + char *cpu_title_tput = "\ +Local /Remote\n\ +Socket Size Request Resp. Elapsed Tput CPU CPU S.dem S.dem\n\ +Send Recv Size Size Time %-8.8s local remote local remote\n\ +bytes bytes bytes bytes secs. per sec %% %c %% %c us/Tr us/Tr\n\n"; + + char *cpu_title_latency = "\ +Local /Remote\n\ +Socket Size Request Resp. Elapsed Latency CPU CPU S.dem S.dem\n\ +Send Recv Size Size Time usecs local remote local remote\n\ +bytes bytes bytes bytes secs. per tran %% %c %% %c us/Tr us/Tr\n\n"; + + char *cpu_fmt_0 = + "%6.3f %c %s\n"; + + char *cpu_fmt_1_line_1 = "\ +%-6d %-6d %-6d %-6d %-6.2f %-6.2f %-6.2f %-6.2f %-6.3f %-6.3f %s\n"; + + char *cpu_fmt_1_line_2 = "\ +%-6d %-6d\n"; + + char *ksink_fmt = "\ +Alignment Offset RoundTrip Trans Throughput\n\ +Local Remote Local Remote Latency Rate %-8.8s/s\n\ +Send Recv Send Recv usec/Tran per sec Outbound Inbound\n\ +%5d %5d %5d %5d %-6.3f %-6.3f %-6.3f %-6.3f\n"; + + + int timed_out = 0; + float elapsed_time; + + int len; + char *temp_message_ptr; + int nummessages; + SOCKET send_socket; + int trans_remaining; + double bytes_xferd; + + struct ring_elt *send_ring; + struct ring_elt *recv_ring; + + int rsp_bytes_left; + int rsp_bytes_recvd; + + float local_cpu_utilization; + float local_service_demand; + float remote_cpu_utilization; + float remote_service_demand; + double thruput; + + struct addrinfo *local_res; + struct addrinfo *remote_res; + + struct tcp_rr_request_struct *tcp_rr_request; + struct tcp_rr_response_struct *tcp_rr_response; + struct tcp_rr_results_struct *tcp_rr_result; + +#ifdef WANT_FIRST_BURST +#define REQUEST_CWND_INITIAL 2 + /* "in the beginning..." the WANT_FIRST_BURST stuff was like both + Unix and the state of New Jersey - both were simple an unspoiled. + then it was realized that some stacks are quite picky about + initial congestion windows and a non-trivial initial burst of + requests would not be individual segments even with TCP_NODELAY + set. so, we have to start tracking a poor-man's congestion window + up here in window space because we want to try to make something + happen that frankly, we cannot guarantee with the specification + of TCP. ain't that grand?-) raj 2006-01-30 */ + int requests_outstanding = 0; + int request_cwnd = REQUEST_CWND_INITIAL; /* we ass-u-me that having + three requests + outstanding at the + beginning of the test + is ok with TCP stacks + of interest. the first + two will come from our + first_burst loop, and + the third from our + regularly scheduled + send */ +#endif + + tcp_rr_request = + (struct tcp_rr_request_struct *)netperf_request.content.test_specific_data; + tcp_rr_response= + (struct tcp_rr_response_struct *)netperf_response.content.test_specific_data; + tcp_rr_result = + (struct tcp_rr_results_struct *)netperf_response.content.test_specific_data; + +#ifdef WANT_HISTOGRAM + if (verbosity > 1) { + time_hist = HIST_new(); + } +#endif /* WANT_HISTOGRAM */ + + /* since we are now disconnected from the code that established the */ + /* control socket, and since we want to be able to use different */ + /* protocols and such, we are passed the name of the remote host and */ + /* must turn that into the test specific addressing information. */ + + complete_addrinfos(&remote_res, + &local_res, + remote_host, + SOCK_STREAM, + IPPROTO_TCP, + 0); + + if ( print_headers ) { + print_top_test_header("TCP REQUEST/RESPONSE TEST",local_res,remote_res); + } + + /* initialize a few counters */ + + send_ring = NULL; + recv_ring = NULL; + confidence_iteration = 1; + init_stat(); + + /* we have a great-big while loop which controls the number of times */ + /* we run a particular test. this is for the calculation of a */ + /* confidence interval (I really should have stayed awake during */ + /* probstats :). If the user did not request confidence measurement */ + /* (no confidence is the default) then we will only go though the */ + /* loop once. the confidence stuff originates from the folks at IBM */ + + while (((confidence < 0) && (confidence_iteration < iteration_max)) || + (confidence_iteration <= iteration_min)) { + + /* initialize a few counters. we have to remember that we might be */ + /* going through the loop more than once. */ + + nummessages = 0; + bytes_xferd = 0.0; + times_up = 0; + timed_out = 0; + trans_remaining = 0; + +#ifdef WANT_FIRST_BURST + /* we have to remember to reset the number of transactions + outstanding and the "congestion window for each new + iteration. raj 2006-01-31 */ + requests_outstanding = 0; + request_cwnd = REQUEST_CWND_INITIAL; +#endif + + + /* set-up the data buffers with the requested alignment and offset. */ + /* since this is a request/response test, default the send_width and */ + /* recv_width to 1 and not two raj 7/94 */ + + if (send_width == 0) send_width = 1; + if (recv_width == 0) recv_width = 1; + + if (send_ring == NULL) { + send_ring = allocate_buffer_ring(send_width, + req_size, + local_send_align, + local_send_offset); + } + + if (recv_ring == NULL) { + recv_ring = allocate_buffer_ring(recv_width, + rsp_size, + local_recv_align, + local_recv_offset); + } + + /*set up the data socket */ + send_socket = create_data_socket(local_res); + + if (send_socket == INVALID_SOCKET){ + perror("netperf: send_tcp_rr: tcp stream data socket"); + exit(1); + } + + if (debug) { + fprintf(where,"send_tcp_rr: send_socket obtained...\n"); + } + + /* If the user has requested cpu utilization measurements, we must */ + /* calibrate the cpu(s). We will perform this task within the tests */ + /* themselves. If the user has specified the cpu rate, then */ + /* calibrate_local_cpu will return rather quickly as it will have */ + /* nothing to do. If local_cpu_rate is zero, then we will go through */ + /* all the "normal" calibration stuff and return the rate back.*/ + + if (local_cpu_usage) { + local_cpu_rate = calibrate_local_cpu(local_cpu_rate); + } + + if (!no_control) { + /* Tell the remote end to do a listen. The server alters the + socket paramters on the other side at this point, hence the + reason for all the values being passed in the setup + message. If the user did not specify any of the parameters, + they will be passed as 0, which will indicate to the remote + that no changes beyond the system's default should be + used. Alignment is the exception, it will default to 8, which + will be no alignment alterations. */ + + netperf_request.content.request_type = DO_TCP_RR; + tcp_rr_request->recv_buf_size = rsr_size_req; + tcp_rr_request->send_buf_size = rss_size_req; + tcp_rr_request->recv_alignment = remote_recv_align; + tcp_rr_request->recv_offset = remote_recv_offset; + tcp_rr_request->send_alignment = remote_send_align; + tcp_rr_request->send_offset = remote_send_offset; + tcp_rr_request->request_size = req_size; + tcp_rr_request->response_size = rsp_size; + tcp_rr_request->no_delay = rem_nodelay; + tcp_rr_request->measure_cpu = remote_cpu_usage; + tcp_rr_request->cpu_rate = remote_cpu_rate; + tcp_rr_request->so_rcvavoid = rem_rcvavoid; + tcp_rr_request->so_sndavoid = rem_sndavoid; + if (test_time) { + tcp_rr_request->test_length = test_time; + } + else { + tcp_rr_request->test_length = test_trans * -1; + } + tcp_rr_request->port = atoi(remote_data_port); + tcp_rr_request->ipfamily = af_to_nf(remote_res->ai_family); + + if (debug > 1) { + fprintf(where,"netperf: send_tcp_rr: requesting TCP rr test\n"); + } + + send_request(); + + /* The response from the remote will contain all of the relevant + socket parameters for this test type. We will put them back + into the variables here so they can be displayed if desired. + The remote will have calibrated CPU if necessary, and will + have done all the needed set-up we will have calibrated the + cpu locally before sending the request, and will grab the + counter value right after the connect returns. The remote + will grab the counter right after the accept call. This saves + the hassle of extra messages being sent for the TCP + tests. */ + + recv_response(); + + if (!netperf_response.content.serv_errno) { + if (debug) + fprintf(where,"remote listen done.\n"); + rsr_size = tcp_rr_response->recv_buf_size; + rss_size = tcp_rr_response->send_buf_size; + rem_nodelay = tcp_rr_response->no_delay; + remote_cpu_usage = tcp_rr_response->measure_cpu; + remote_cpu_rate = tcp_rr_response->cpu_rate; + /* make sure that port numbers are in network order */ + set_port_number(remote_res,(short)tcp_rr_response->data_port_number); + } + else { + Set_errno(netperf_response.content.serv_errno); + fprintf(where, + "netperf: remote error %d", + netperf_response.content.serv_errno); + perror(""); + fflush(where); + + exit(1); + } + } + +#ifdef WANT_DEMO + DEMO_RR_SETUP(1000) +#endif + + /*Connect up to the remote port on the data socket */ + if (connect(send_socket, + remote_res->ai_addr, + remote_res->ai_addrlen) == INVALID_SOCKET){ + perror("netperf: data socket connect failed"); + + exit(1); + } + +#ifdef WIN32 + /* this is used so the timer thread can close the socket out from */ + /* under us, which to date is the easiest/cleanest/least */ + /* Windows-specific way I can find to force the winsock calls to */ + /* return WSAEINTR with the test is over. anything that will run on */ + /* 95 and NT and is closer to what netperf expects from Unix signals */ + /* and such would be appreciated raj 1/96 */ + win_kludge_socket = send_socket; +#endif /* WIN32 */ + + /* Data Socket set-up is finished. If there were problems, either the */ + /* connect would have failed, or the previous response would have */ + /* indicated a problem. I failed to see the value of the extra */ + /* message after the accept on the remote. If it failed, we'll see it */ + /* here. If it didn't, we might as well start pumping data. */ + + /* Set-up the test end conditions. For a request/response test, they */ + /* can be either time or transaction based. */ + + if (test_time) { + /* The user wanted to end the test after a period of time. */ + times_up = 0; + trans_remaining = 0; + start_timer(test_time); + } + else { + /* The tester wanted to send a number of bytes. */ + trans_remaining = test_bytes; + times_up = 1; + } + + /* The cpu_start routine will grab the current time and possibly */ + /* value of the idle counter for later use in measuring cpu */ + /* utilization and/or service demand and thruput. */ + + cpu_start(local_cpu_usage); + +#ifdef WANT_INTERVALS + INTERVALS_INIT(); +#endif /* WANT_INTERVALS */ + + /* We use an "OR" to control test execution. When the test is */ + /* controlled by time, the byte count check will always return false. */ + /* When the test is controlled by byte count, the time test will */ + /* always return false. When the test is finished, the whole */ + /* expression will go false and we will stop sending data. I think I */ + /* just arbitrarily decrement trans_remaining for the timed test, but */ + /* will not do that just yet... One other question is whether or not */ + /* the send buffer and the receive buffer should be the same buffer. */ + +#ifdef WANT_DEMO + if (demo_mode) { + HIST_timestamp(demo_one_ptr); + } +#endif + + while ((!times_up) || (trans_remaining > 0)) { + /* send the request. we assume that if we use a blocking socket, */ + /* the request will be sent at one shot. */ + +#ifdef WANT_FIRST_BURST + /* we can inject no more than request_cwnd, which will grow with + time, and no more than first_burst_size. we don't use <= to + account for the "regularly scheduled" send call. of course + that makes it more a "max_outstanding_ than a + "first_burst_size" but for now we won't fix the names. also, + I suspect the extra check against < first_burst_size is + redundant since later I expect to make sure that request_cwnd + can never get larger than first_burst_size, but just at the + moment I'm feeling like a belt and suspenders kind of + programmer. raj 2006-01-30 */ + while ((first_burst_size > 0) && + (requests_outstanding < request_cwnd) && + (requests_outstanding < first_burst_size)) { + if (debug) { + fprintf(where, + "injecting, req_outstndng %d req_cwnd %d burst %d\n", + requests_outstanding, + request_cwnd, + first_burst_size); + } + if ((len = send(send_socket, + send_ring->buffer_ptr, + req_size, + 0)) != req_size) { + /* we should never hit the end of the test in the first burst */ + perror("send_tcp_rr: initial burst data send error"); + exit(-1); + } + requests_outstanding += 1; + } + +#endif /* WANT_FIRST_BURST */ + +#ifdef WANT_HISTOGRAM + if (verbosity > 1) { + /* timestamp just before our call to send, and then again just + after the receive raj 8/94 */ + /* but only if we are actually going to display one. raj + 2007-02-07 */ + + HIST_timestamp(&time_one); + } +#endif /* WANT_HISTOGRAM */ + + if ((len = send(send_socket, + send_ring->buffer_ptr, + req_size, + 0)) != req_size) { + if (SOCKET_EINTR(len) || (errno == 0)) { + /* we hit the end of a */ + /* timed test. */ + timed_out = 1; + break; + } + perror("send_tcp_rr: data send error"); + exit(1); + } + send_ring = send_ring->next; + +#ifdef WANT_FIRST_BURST + requests_outstanding += 1; +#endif + + /* receive the response */ + rsp_bytes_left = rsp_size; + temp_message_ptr = recv_ring->buffer_ptr; + while(rsp_bytes_left > 0) { + if((rsp_bytes_recvd=recv(send_socket, + temp_message_ptr, + rsp_bytes_left, + 0)) == SOCKET_ERROR || rsp_bytes_recvd == 0) { + if ( SOCKET_EINTR(rsp_bytes_recvd) ) { + /* We hit the end of a timed test. */ + timed_out = 1; + break; + } + perror("send_tcp_rr: data recv error"); + exit(1); + } + rsp_bytes_left -= rsp_bytes_recvd; + temp_message_ptr += rsp_bytes_recvd; + } + recv_ring = recv_ring->next; + +#ifdef WANT_FIRST_BURST + /* so, since we've gotten a response back, update the + bookkeeping accordingly. there is one less request + outstanding and we can put one more out there than before. */ + requests_outstanding -= 1; + if (request_cwnd < first_burst_size) { + request_cwnd += 1; + if (debug) { + fprintf(where, + "incr req_cwnd to %d first_burst %d reqs_outstndng %d\n", + request_cwnd, + first_burst_size, + requests_outstanding); + } + } +#endif + if (timed_out) { + /* we may have been in a nested while loop - we need */ + /* another call to break. */ + break; + } + +#ifdef WANT_HISTOGRAM + if (verbosity > 1) { + HIST_timestamp(&time_two); + HIST_add(time_hist,delta_micro(&time_one,&time_two)); + } +#endif /* WANT_HISTOGRAM */ + +#ifdef WANT_DEMO + DEMO_RR_INTERVAL(1); +#endif + +#ifdef WANT_INTERVALS + INTERVALS_WAIT(); +#endif /* WANT_INTERVALS */ + + nummessages++; + if (trans_remaining) { + trans_remaining--; + } + + if (debug > 3) { + if ((nummessages % 100) == 0) { + fprintf(where, + "Transaction %d completed\n", + nummessages); + fflush(where); + } + } + } + + /* At this point we used to call shutdown on the data socket to be + sure all the data was delivered, but this was not germane in a + request/response test, and it was causing the tests to "hang" + when they were being controlled by time. So, I have replaced + this shutdown call with a call to close that can be found later + in the procedure. */ + + /* this call will always give us the elapsed time for the test, + and will also store-away the necessaries for cpu utilization */ + + cpu_stop(local_cpu_usage,&elapsed_time); /* was cpu being */ + /* measured? how long */ + /* did we really run? */ + + if (!no_control) { + /* Get the statistics from the remote end. The remote will have + calculated CPU utilization. If it wasn't supposed to care, it + will return obvious values. */ + + recv_response(); + if (!netperf_response.content.serv_errno) { + if (debug) + fprintf(where,"remote results obtained\n"); + } + else { + Set_errno(netperf_response.content.serv_errno); + fprintf(where,"netperf: remote error %d", + netperf_response.content.serv_errno); + perror(""); + fflush(where); + exit(1); + } + } + + /* We now calculate what our "throughput" was for the test. */ + + bytes_xferd = (req_size * nummessages) + (rsp_size * nummessages); + thruput = nummessages/elapsed_time; + + if (local_cpu_usage || remote_cpu_usage) { + /* We must now do a little math for service demand and cpu + utilization for the system(s) Of course, some of the + information might be bogus because there was no idle counter in + the kernel(s). We need to make a note of this for the user's + benefit... */ + if (local_cpu_usage) { + local_cpu_utilization = calc_cpu_util(0.0); + /* since calc_service demand is doing ms/Kunit we will + multiply the number of transaction by 1024 to get "good" + numbers */ + local_service_demand = calc_service_demand((double) nummessages*1024, + 0.0, + 0.0, + 0); + } + else { + local_cpu_utilization = (float) -1.0; + local_service_demand = (float) -1.0; + } + + if (remote_cpu_usage) { + remote_cpu_utilization = tcp_rr_result->cpu_util; + /* since calc_service demand is doing ms/Kunit we will + multiply the number of transaction by 1024 to get "good" + numbers */ + remote_service_demand = calc_service_demand((double) nummessages*1024, + 0.0, + remote_cpu_utilization, + tcp_rr_result->num_cpus); + } + else { + remote_cpu_utilization = (float) -1.0; + remote_service_demand = (float) -1.0; + } + + } + else { + /* we were not measuring cpu, for the confidence stuff, we */ + /* should make it -1.0 */ + local_cpu_utilization = (float) -1.0; + local_service_demand = (float) -1.0; + remote_cpu_utilization = (float) -1.0; + remote_service_demand = (float) -1.0; + } + + /* at this point, we want to calculate the confidence information. + if debugging is on, calculate_confidence will print-out the + parameters we pass it */ + + calculate_confidence(confidence_iteration, + elapsed_time, + thruput, + local_cpu_utilization, + remote_cpu_utilization, + local_service_demand, + remote_service_demand); + + + confidence_iteration++; + + /* we are now done with the socket, so close it */ + close(send_socket); + + } + + retrieve_confident_values(&elapsed_time, + &thruput, + &local_cpu_utilization, + &remote_cpu_utilization, + &local_service_demand, + &remote_service_demand); + + /* We are now ready to print all the information. If the user has + specified zero-level verbosity, we will just print the local + service demand, or the remote service demand. If the user has + requested verbosity level 1, he will get the basic "streamperf" + numbers. If the user has specified a verbosity of greater than 1, + we will display a veritable plethora of background information + from outside of this block as it it not cpu_measurement + specific... */ + + if (confidence < 0) { + /* we did not hit confidence, but were we asked to look for it? */ + if (iteration_max > 1) { + display_confidence(); + } + } + + if (local_cpu_usage || remote_cpu_usage) { + local_cpu_method = format_cpu_method(cpu_method); + remote_cpu_method = format_cpu_method(tcp_rr_result->cpu_method); + + switch (verbosity) { + case 0: + if (local_cpu_usage) { + fprintf(where, + cpu_fmt_0, + local_service_demand, + local_cpu_method, + ((print_headers) || + (result_brand == NULL)) ? "" : result_brand); + } + else { + fprintf(where, + cpu_fmt_0, + remote_service_demand, + remote_cpu_method, + ((print_headers) || + (result_brand == NULL)) ? "" : result_brand); + } + break; + case 1: + case 2: + if (print_headers) { + if ('x' == libfmt) { + fprintf(where, + cpu_title, + local_cpu_method, + remote_cpu_method); + } + else { + fprintf(where, + cpu_title_tput, + format_units(), + local_cpu_method, + remote_cpu_method); + } + } + + fprintf(where, + cpu_fmt_1_line_1, /* the format string */ + lss_size, /* local sendbuf size */ + lsr_size, + req_size, /* how large were the requests */ + rsp_size, /* guess */ + elapsed_time, /* how long was the test */ + ('x' == libfmt) ? thruput : + calc_thruput_interval_omni(thruput * (req_size+rsp_size), + 1.0), + local_cpu_utilization, /* local cpu */ + remote_cpu_utilization, /* remote cpu */ + local_service_demand, /* local service demand */ + remote_service_demand, /* remote service demand */ + ((print_headers) || + (result_brand == NULL)) ? "" : result_brand); + fprintf(where, + cpu_fmt_1_line_2, + rss_size, + rsr_size); + break; + } + } + else { + /* The tester did not wish to measure service demand. */ + + switch (verbosity) { + case 0: + fprintf(where, + tput_fmt_0, + ('x' == libfmt) ? thruput : + calc_thruput_interval_omni(thruput * (req_size+rsp_size), + 1.0), + ((print_headers) || + (result_brand == NULL)) ? "" : result_brand); + break; + case 1: + case 2: + if (print_headers) { + fprintf(where, + ('x' == libfmt) ? tput_title : tput_title_band, + format_units()); + } + + fprintf(where, + tput_fmt_1_line_1, /* the format string */ + lss_size, + lsr_size, + req_size, /* how large were the requests */ + rsp_size, /* how large were the responses */ + elapsed_time, /* how long did it take */ + /* are we trans or do we need to convert to bytes then + bits? at this point, thruput is in our "confident" + transactions per second. we can convert to a + bidirectional bitrate by multiplying that by the sum + of the req_size and rsp_size. we pass that to + calc_thruput_interval_omni with an elapsed time of + 1.0 s to get it converted to [kmg]bits/s or + [KMG]Bytes/s */ + ('x' == libfmt) ? thruput : + calc_thruput_interval_omni(thruput * (req_size+rsp_size), + 1.0), + ((print_headers) || + (result_brand == NULL)) ? "" : result_brand); + fprintf(where, + tput_fmt_1_line_2, + rss_size, /* remote recvbuf size */ + rsr_size); + + break; + } + } + + /* it would be a good thing to include information about some of the */ + /* other parameters that may have been set for this test, but at the */ + /* moment, I do not wish to figure-out all the formatting, so I will */ + /* just put this comment here to help remind me that it is something */ + /* that should be done at a later time. */ + + /* how to handle the verbose information in the presence of */ + /* confidence intervals is yet to be determined... raj 11/94 */ + if (verbosity > 1) { + /* The user wanted to know it all, so we will give it to him. */ + /* This information will include as much as we can find about */ + /* TCP statistics, the alignments of the sends and receives */ + /* and all that sort of rot... */ + + /* normally, you might think that if we were messing about with + the value of libfmt we would need to put it back again, but + since this is basically the last thing we are going to do with + it, it does not matter. so there :) raj 2007-06-08 */ + /* if the user was asking for transactions, then we report + megabits per second for the unidirectional throughput, + otherwise we use the desired units. */ + if ('x' == libfmt) { + libfmt = 'm'; + } + + fprintf(where, + ksink_fmt, + format_units(), + local_send_align, + remote_recv_offset, + local_send_offset, + remote_recv_offset, + /* if the user has enable burst mode, we have to remember + to account for that in the number of transactions + outstanding at any one time. otherwise we will + underreport the latency of individual + transactions. learned from saf by raj 2007-06-08 */ + (((double)1.0/thruput)*(double)1000000.0) * + (double) (1 + ((first_burst_size > 0) ? first_burst_size : 0)), + thruput, + calc_thruput_interval_omni(thruput * (double)req_size,1.0), + calc_thruput_interval_omni(thruput * (double)rsp_size,1.0)); + +#ifdef WANT_HISTOGRAM + fprintf(where,"\nHistogram of request/response times\n"); + fflush(where); + HIST_report(time_hist); +#endif /* WANT_HISTOGRAM */ + + } + +} + +void +send_udp_stream(char remote_host[]) +{ + /**********************************************************************/ + /* */ + /* UDP Unidirectional Send Test */ + /* */ + /**********************************************************************/ + +#define UDP_LENGTH_MAX 0XFFFF - 28 + + char *tput_title = "\ +Socket Message Elapsed Messages \n\ +Size Size Time Okay Errors Throughput\n\ +bytes bytes secs # # %s/sec\n\n"; + + char *tput_fmt_0 = + "%7.2f\n"; + + char *tput_fmt_1 = "\ +%6d %6d %-7.2f %7d %6d %7.2f\n\ +%6d %-7.2f %7d %7.2f\n\n"; + + + char *cpu_title = "\ +Socket Message Elapsed Messages CPU Service\n\ +Size Size Time Okay Errors Throughput Util Demand\n\ +bytes bytes secs # # %s/sec %% %c%c us/KB\n\n"; + + char *cpu_fmt_0 = + "%6.2f %c\n"; + + char *cpu_fmt_1 = "\ +%6d %6d %-7.2f %7d %6d %7.1f %-6.2f %-6.3f\n\ +%6d %-7.2f %7d %7.1f %-6.2f %-6.3f\n\n"; + + unsigned int messages_recvd; + unsigned int messages_sent; + unsigned int failed_sends; + + float elapsed_time, + local_cpu_utilization, + remote_cpu_utilization; + + float local_service_demand, remote_service_demand; + double local_thruput, remote_thruput; + double bytes_sent; + double bytes_recvd; + + + int len; + struct ring_elt *send_ring; + SOCKET data_socket; + + unsigned int sum_messages_sent; + unsigned int sum_messages_recvd; + unsigned int sum_failed_sends; + double sum_local_thruput; + + struct addrinfo *local_res; + struct addrinfo *remote_res; + + struct udp_stream_request_struct *udp_stream_request; + struct udp_stream_response_struct *udp_stream_response; + struct udp_stream_results_struct *udp_stream_results; + + udp_stream_request = + (struct udp_stream_request_struct *)netperf_request.content.test_specific_data; + udp_stream_response = + (struct udp_stream_response_struct *)netperf_response.content.test_specific_data; + udp_stream_results = + (struct udp_stream_results_struct *)netperf_response.content.test_specific_data; + +#ifdef WANT_HISTOGRAM + if (verbosity > 1) { + time_hist = HIST_new(); + } +#endif /* WANT_HISTOGRAM */ + + /* since we are now disconnected from the code that established the */ + /* control socket, and since we want to be able to use different */ + /* protocols and such, we are passed the name of the remote host and */ + /* must turn that into the test specific addressing information. */ + + complete_addrinfos(&remote_res, + &local_res, + remote_host, + SOCK_DGRAM, + IPPROTO_UDP, + 0); + + if ( print_headers ) { + print_top_test_header("UDP UNIDIRECTIONAL SEND TEST",local_res,remote_res); + } + + send_ring = NULL; + confidence_iteration = 1; + init_stat(); + sum_messages_sent = 0; + sum_messages_recvd = 0; + sum_failed_sends = 0; + sum_local_thruput = 0.0; + + /* we have a great-big while loop which controls the number of times */ + /* we run a particular test. this is for the calculation of a */ + /* confidence interval (I really should have stayed awake during */ + /* probstats :). If the user did not request confidence measurement */ + /* (no confidence is the default) then we will only go though the */ + /* loop once. the confidence stuff originates from the folks at IBM */ + + while (((confidence < 0) && (confidence_iteration < iteration_max)) || + (confidence_iteration <= iteration_min)) { + + /* initialize a few counters. we have to remember that we might be */ + /* going through the loop more than once. */ + messages_sent = 0; + messages_recvd = 0; + failed_sends = 0; + times_up = 0; + + /*set up the data socket */ + data_socket = create_data_socket(local_res); + + if (data_socket == INVALID_SOCKET){ + perror("udp_send: data socket"); + exit(1); + } + + /* now, we want to see if we need to set the send_size */ + if (send_size == 0) { + if (lss_size > 0) { + send_size = (lss_size < UDP_LENGTH_MAX ? lss_size : UDP_LENGTH_MAX); + } + else { + send_size = 4096; + } + } + + + /* set-up the data buffer with the requested alignment and offset, */ + /* most of the numbers here are just a hack to pick something nice */ + /* and big in an attempt to never try to send a buffer a second time */ + /* before it leaves the node...unless the user set the width */ + /* explicitly. */ + if (send_width == 0) send_width = 32; + + if (send_ring == NULL ) { + send_ring = allocate_buffer_ring(send_width, + send_size, + local_send_align, + local_send_offset); + } + + + /* if the user supplied a cpu rate, this call will complete rather */ + /* quickly, otherwise, the cpu rate will be retured to us for */ + /* possible display. The Library will keep it's own copy of this data */ + /* for use elsewhere. We will only display it. (Does that make it */ + /* "opaque" to us?) */ + + if (local_cpu_usage) + local_cpu_rate = calibrate_local_cpu(local_cpu_rate); + + if (!no_control) { + /* Tell the remote end to set up the data connection. The server + sends back the port number and alters the socket parameters + there. Of course this is a datagram service so no connection + is actually set up, the server just sets up the socket and + binds it. */ + + netperf_request.content.request_type = DO_UDP_STREAM; + udp_stream_request->recv_buf_size = rsr_size_req; + udp_stream_request->message_size = send_size; + udp_stream_request->recv_connected = remote_connected; + udp_stream_request->recv_alignment = remote_recv_align; + udp_stream_request->recv_offset = remote_recv_offset; + udp_stream_request->measure_cpu = remote_cpu_usage; + udp_stream_request->cpu_rate = remote_cpu_rate; + udp_stream_request->test_length = test_time; + udp_stream_request->so_rcvavoid = rem_rcvavoid; + udp_stream_request->so_sndavoid = rem_sndavoid; + udp_stream_request->port = atoi(remote_data_port); + udp_stream_request->ipfamily = af_to_nf(remote_res->ai_family); + + send_request(); + + recv_response(); + + if (!netperf_response.content.serv_errno) { + if (debug) + fprintf(where,"send_udp_stream: remote data connection done.\n"); + } + else { + Set_errno(netperf_response.content.serv_errno); + perror("send_udp_stream: error on remote"); + exit(1); + } + + /* Place the port number returned by the remote into the sockaddr */ + /* structure so our sends can be sent to the correct place. Also get */ + /* some of the returned socket buffer information for user display. */ + + /* make sure that port numbers are in the proper order */ + set_port_number(remote_res,(short)udp_stream_response->data_port_number); + + rsr_size = udp_stream_response->recv_buf_size; + rss_size = udp_stream_response->send_buf_size; + remote_cpu_rate = udp_stream_response->cpu_rate; + } + +#ifdef WANT_DEMO + DEMO_STREAM_SETUP(lss_size,rsr_size) +#endif + + /* We "connect" up to the remote post to allow is to use the send */ + /* call instead of the sendto call. Presumeably, this is a little */ + /* simpler, and a little more efficient. I think that it also means */ + /* that we can be informed of certain things, but am not sure */ + /* yet...also, this is the way I would expect a client to behave */ + /* when talking to a server */ + if (local_connected) { + if (connect(data_socket, + remote_res->ai_addr, + remote_res->ai_addrlen) == INVALID_SOCKET){ + perror("send_udp_stream: data socket connect failed"); + exit(1); + } else if (debug) { + fprintf(where,"send_udp_stream: connected data socket.\n"); + fflush(where); + } + } + +#ifdef WIN32 + /* this is used so the timer thread can close the socket out from */ + /* under us, which to date is the easiest/cleanest/least */ + /* Windows-specific way I can find to force the winsock calls to */ + /* return WSAEINTR with the test is over. anything that will run on */ + /* 95 and NT and is closer to what netperf expects from Unix signals */ + /* and such would be appreciated raj 1/96 */ + win_kludge_socket = data_socket; +#endif /* WIN32 */ + + /* set up the timer to call us after test_time. one of these days, */ + /* it might be nice to figure-out a nice reliable way to have the */ + /* test controlled by a byte count as well, but since UDP is not */ + /* reliable, that could prove difficult. so, in the meantime, we */ + /* only allow a UDP_STREAM test to be a timed test. */ + + if (test_time) { + times_up = 0; + start_timer(test_time); + } + else { + fprintf(where,"Sorry, UDP_STREAM tests must be timed.\n"); + fflush(where); + } + + /* Get the start count for the idle counter and the start time */ + + cpu_start(local_cpu_usage); + +#ifdef WANT_INTERVALS + INTERVALS_INIT(); +#endif /* WANT_INTERVALS */ + +#ifdef WANT_DEMO + if (demo_mode) { + HIST_timestamp(demo_one_ptr); + } +#endif + + /* Send datagrams like there was no tomorrow. at somepoint it might */ + /* be nice to set this up so that a quantity of bytes could be sent, */ + /* but we still need some sort of end of test trigger on the receive */ + /* side. that could be a select with a one second timeout, but then */ + /* if there is a test where none of the data arrives for awile and */ + /* then starts again, we would end the test too soon. something to */ + /* think about... */ + while (!times_up) { + +#ifdef DIRTY + /* we want to dirty some number of consecutive integers in the buffer */ + /* we are about to send. we may also want to bring some number of */ + /* them cleanly into the cache. The clean ones will follow any dirty */ + /* ones into the cache. */ + + access_buffer(send_ring->buffer_ptr, + send_size, + loc_dirty_count, + loc_clean_count); +#endif /* DIRTY */ + +#ifdef WANT_HISTOGRAM + if (verbosity > 1) { + HIST_timestamp(&time_one); + } +#endif /* WANT_HISTOGRAM */ + + if (local_connected) { + len = send(data_socket, + send_ring->buffer_ptr, + send_size, + 0); + } else { + len = sendto(data_socket, + send_ring->buffer_ptr, + send_size, + 0, + remote_res->ai_addr, + remote_res->ai_addrlen); + } + + if (len != send_size) { + if ((len >= 0) || + SOCKET_EINTR(len)) + break; + if (errno == ENOBUFS) { + failed_sends++; + continue; + } + perror("udp_send: data send error"); + exit(1); + } + messages_sent++; + + /* now we want to move our pointer to the next position in the */ + /* data buffer... */ + + send_ring = send_ring->next; + + +#ifdef WANT_HISTOGRAM + if (verbosity > 1) { + /* get the second timestamp */ + HIST_timestamp(&time_two); + HIST_add(time_hist,delta_micro(&time_one,&time_two)); + } +#endif /* WANT_HISTOGRAM */ + +#ifdef WANT_DEMO + DEMO_STREAM_INTERVAL(send_size) +#endif + +#ifdef WANT_INTERVALS + INTERVALS_WAIT(); +#endif /* WANT_INTERVALS */ + + } + + /* This is a timed test, so the remote will be returning to us after */ + /* a time. We should not need to send any "strange" messages to tell */ + /* the remote that the test is completed, unless we decide to add a */ + /* number of messages to the test. */ + + /* the test is over, so get stats and stuff */ + cpu_stop(local_cpu_usage, + &elapsed_time); + + if (!no_control) { + /* Get the statistics from the remote end */ + recv_response(); + if (!netperf_response.content.serv_errno) { + if (debug) + fprintf(where,"send_udp_stream: remote results obtained\n"); + } + else { + Set_errno(netperf_response.content.serv_errno); + perror("send_udp_stream: error on remote"); + exit(1); + } + messages_recvd = udp_stream_results->messages_recvd; + bytes_recvd = (double) send_size * (double) messages_recvd; + } + else { + /* since there was no control connection, we've no idea what was + actually received. raj 2007-02-08 */ + messages_recvd = -1; + bytes_recvd = -1.0; + } + + bytes_sent = (double) send_size * (double) messages_sent; + local_thruput = calc_thruput(bytes_sent); + + + /* we asume that the remote ran for as long as we did */ + + remote_thruput = calc_thruput(bytes_recvd); + + /* print the results for this socket and message size */ + + if (local_cpu_usage || remote_cpu_usage) { + /* We must now do a little math for service demand and cpu */ + /* utilization for the system(s) We pass zeros for the local */ + /* cpu utilization and elapsed time to tell the routine to use */ + /* the libraries own values for those. */ + if (local_cpu_usage) { + local_cpu_utilization = calc_cpu_util(0.0); + /* shouldn't this really be based on bytes_recvd, since that is */ + /* the effective throughput of the test? I think that it should, */ + /* so will make the change raj 11/94 */ + local_service_demand = calc_service_demand(bytes_recvd, + 0.0, + 0.0, + 0); + } + else { + local_cpu_utilization = (float) -1.0; + local_service_demand = (float) -1.0; + } + + /* The local calculations could use variables being kept by */ + /* the local netlib routines. The remote calcuations need to */ + /* have a few things passed to them. */ + if (remote_cpu_usage) { + remote_cpu_utilization = udp_stream_results->cpu_util; + remote_service_demand = calc_service_demand(bytes_recvd, + 0.0, + remote_cpu_utilization, + udp_stream_results->num_cpus); + } + else { + remote_cpu_utilization = (float) -1.0; + remote_service_demand = (float) -1.0; + } + } + else { + /* we were not measuring cpu, for the confidence stuff, we */ + /* should make it -1.0 */ + local_cpu_utilization = (float) -1.0; + local_service_demand = (float) -1.0; + remote_cpu_utilization = (float) -1.0; + remote_service_demand = (float) -1.0; + } + + /* at this point, we want to calculate the confidence information. */ + /* if debugging is on, calculate_confidence will print-out the */ + /* parameters we pass it */ + + calculate_confidence(confidence_iteration, + elapsed_time, + remote_thruput, + local_cpu_utilization, + remote_cpu_utilization, + local_service_demand, + remote_service_demand); + + /* since the routine calculate_confidence is rather generic, and */ + /* we have a few other parms of interest, we will do a little work */ + /* here to caclulate their average. */ + sum_messages_sent += messages_sent; + sum_messages_recvd += messages_recvd; + sum_failed_sends += failed_sends; + sum_local_thruput += local_thruput; + + confidence_iteration++; + + /* this datapoint is done, so we don't need the socket any longer */ + close(data_socket); + + } + + /* we should reach this point once the test is finished */ + + retrieve_confident_values(&elapsed_time, + &remote_thruput, + &local_cpu_utilization, + &remote_cpu_utilization, + &local_service_demand, + &remote_service_demand); + + /* some of the interesting values aren't covered by the generic */ + /* confidence routine */ + messages_sent = sum_messages_sent / (confidence_iteration -1); + messages_recvd = sum_messages_recvd / (confidence_iteration -1); + failed_sends = sum_failed_sends / (confidence_iteration -1); + local_thruput = sum_local_thruput / (confidence_iteration -1); + + /* We are now ready to print all the information. If the user */ + /* has specified zero-level verbosity, we will just print the */ + /* local service demand, or the remote service demand. If the */ + /* user has requested verbosity level 1, he will get the basic */ + /* "streamperf" numbers. If the user has specified a verbosity */ + /* of greater than 1, we will display a veritable plethora of */ + /* background information from outside of this block as it it */ + /* not cpu_measurement specific... */ + + + if (confidence < 0) { + /* we did not hit confidence, but were we asked to look for it? */ + if (iteration_max > 1) { + display_confidence(); + } + } + + if (local_cpu_usage || remote_cpu_usage) { + local_cpu_method = format_cpu_method(cpu_method); + remote_cpu_method = format_cpu_method(udp_stream_results->cpu_method); + + switch (verbosity) { + case 0: + if (local_cpu_usage) { + fprintf(where, + cpu_fmt_0, + local_service_demand, + local_cpu_method); + } + else { + fprintf(where, + cpu_fmt_0, + remote_service_demand, + local_cpu_method); + } + break; + case 1: + case 2: + if (print_headers) { + fprintf(where, + cpu_title, + format_units(), + local_cpu_method, + remote_cpu_method); + } + + fprintf(where, + cpu_fmt_1, /* the format string */ + lss_size, /* local sendbuf size */ + send_size, /* how large were the sends */ + elapsed_time, /* how long was the test */ + messages_sent, + failed_sends, + local_thruput, /* what was the xfer rate */ + local_cpu_utilization, /* local cpu */ + local_service_demand, /* local service demand */ + rsr_size, + elapsed_time, + messages_recvd, + remote_thruput, + remote_cpu_utilization, /* remote cpu */ + remote_service_demand); /* remote service demand */ + break; + } + } + else { + /* The tester did not wish to measure service demand. */ + switch (verbosity) { + case 0: + fprintf(where, + tput_fmt_0, + local_thruput); + break; + case 1: + case 2: + if (print_headers) { + fprintf(where,tput_title,format_units()); + } + fprintf(where, + tput_fmt_1, /* the format string */ + lss_size, /* local sendbuf size */ + send_size, /* how large were the sends */ + elapsed_time, /* how long did it take */ + messages_sent, + failed_sends, + local_thruput, + rsr_size, /* remote recvbuf size */ + elapsed_time, + messages_recvd, + remote_thruput); + break; + } + } + + fflush(where); +#ifdef WANT_HISTOGRAM + if (verbosity > 1) { + fprintf(where,"\nHistogram of time spent in send() call\n"); + fflush(where); + HIST_report(time_hist); + } +#endif /* WANT_HISTOGRAM */ + +} + + + /* this routine implements the receive side (netserver) of the */ + /* UDP_STREAM performance test. */ + +void +recv_udp_stream() +{ + struct ring_elt *recv_ring; + struct addrinfo *local_res; + char local_name[BUFSIZ]; + char port_buffer[PORTBUFSIZE]; + + struct sockaddr_storage myaddr_in; + SOCKET s_data; + netperf_socklen_t addrlen; + struct sockaddr_storage remote_addr; + netperf_socklen_t remote_addrlen; + + int len = 0; + unsigned int bytes_received = 0; + float elapsed_time; + + int message_size; + unsigned int messages_recvd = 0; + + struct udp_stream_request_struct *udp_stream_request; + struct udp_stream_response_struct *udp_stream_response; + struct udp_stream_results_struct *udp_stream_results; + + udp_stream_request = + (struct udp_stream_request_struct *)netperf_request.content.test_specific_data; + udp_stream_response = + (struct udp_stream_response_struct *)netperf_response.content.test_specific_data; + udp_stream_results = + (struct udp_stream_results_struct *)netperf_response.content.test_specific_data; + + if (debug) { + fprintf(where,"netserver: recv_udp_stream: entered...\n"); + fflush(where); + } + + /* We want to set-up the listen socket with all the desired */ + /* parameters and then let the initiator know that all is ready. If */ + /* socket size defaults are to be used, then the initiator will have */ + /* sent us 0's. If the socket sizes cannot be changed, then we will */ + /* send-back what they are. If that information cannot be determined, */ + /* then we send-back -1's for the sizes. If things go wrong for any */ + /* reason, we will drop back ten yards and punt. */ + + /* If anything goes wrong, we want the remote to know about it. It */ + /* would be best if the error that the remote reports to the user is */ + /* the actual error we encountered, rather than some bogus unexpected */ + /* response type message. */ + + if (debug > 1) { + fprintf(where,"recv_udp_stream: setting the response type...\n"); + fflush(where); + } + + netperf_response.content.response_type = UDP_STREAM_RESPONSE; + + if (debug > 2) { + fprintf(where,"recv_udp_stream: the response type is set...\n"); + fflush(where); + } + + /* We now alter the message_ptr variable to be at the desired */ + /* alignment with the desired offset. */ + + if (debug > 1) { + fprintf(where,"recv_udp_stream: requested alignment of %d\n", + udp_stream_request->recv_alignment); + fflush(where); + } + + if (recv_width == 0) recv_width = 1; + + recv_ring = allocate_buffer_ring(recv_width, + udp_stream_request->message_size, + udp_stream_request->recv_alignment, + udp_stream_request->recv_offset); + + if (debug > 1) { + fprintf(where,"recv_udp_stream: receive alignment and offset set...\n"); + fflush(where); + } + + /* Grab a socket to listen on, and then listen on it. */ + + if (debug > 1) { + fprintf(where,"recv_udp_stream: grabbing a socket...\n"); + fflush(where); + } + + /* create_data_socket expects to find some things in the global */ + /* variables, so set the globals based on the values in the request. */ + /* once the socket has been created, we will set the response values */ + /* based on the updated value of those globals. raj 7/94 */ + lsr_size_req = udp_stream_request->recv_buf_size; + loc_rcvavoid = udp_stream_request->so_rcvavoid; + loc_sndavoid = udp_stream_request->so_sndavoid; + local_connected = udp_stream_request->recv_connected; + + set_hostname_and_port(local_name, + port_buffer, + nf_to_af(udp_stream_request->ipfamily), + udp_stream_request->port); + + local_res = complete_addrinfo(local_name, + local_name, + port_buffer, + nf_to_af(udp_stream_request->ipfamily), + SOCK_DGRAM, + IPPROTO_UDP, + 0); + + s_data = create_data_socket(local_res); + + if (s_data == INVALID_SOCKET) { + netperf_response.content.serv_errno = errno; + send_response(); + exit(1); + } + + udp_stream_response->test_length = udp_stream_request->test_length; + + /* now get the port number assigned by the system */ + addrlen = sizeof(myaddr_in); + if (getsockname(s_data, + (struct sockaddr *)&myaddr_in, + &addrlen) == SOCKET_ERROR){ + netperf_response.content.serv_errno = errno; + close(s_data); + send_response(); + + exit(1); + } + + /* Now myaddr_in contains the port and the internet address this is */ + /* returned to the sender also implicitly telling the sender that the */ + /* socket buffer sizing has been done. */ + + udp_stream_response->data_port_number = + (int) ntohs(((struct sockaddr_in *)&myaddr_in)->sin_port); + netperf_response.content.serv_errno = 0; + + /* But wait, there's more. If the initiator wanted cpu measurements, */ + /* then we must call the calibrate routine, which will return the max */ + /* rate back to the initiator. If the CPU was not to be measured, or */ + /* something went wrong with the calibration, we will return a -1 to */ + /* the initiator. */ + + udp_stream_response->cpu_rate = (float)0.0; /* assume no cpu */ + udp_stream_response->measure_cpu = 0; + if (udp_stream_request->measure_cpu) { + /* We will pass the rate into the calibration routine. If the */ + /* user did not specify one, it will be 0.0, and we will do a */ + /* "real" calibration. Otherwise, all it will really do is */ + /* store it away... */ + udp_stream_response->measure_cpu = 1; + udp_stream_response->cpu_rate = + calibrate_local_cpu(udp_stream_request->cpu_rate); + } + + message_size = udp_stream_request->message_size; + test_time = udp_stream_request->test_length; + + /* before we send the response back to the initiator, pull some of */ + /* the socket parms from the globals */ + udp_stream_response->send_buf_size = lss_size; + udp_stream_response->recv_buf_size = lsr_size; + udp_stream_response->so_rcvavoid = loc_rcvavoid; + udp_stream_response->so_sndavoid = loc_sndavoid; + + send_response(); + + /* Now it's time to start receiving data on the connection. We will */ + /* first grab the apropriate counters and then start grabbing. */ + + cpu_start(udp_stream_request->measure_cpu); + +#ifdef WIN32 + /* this is used so the timer thread can close the socket out from */ + /* under us, which to date is the easiest/cleanest/least */ + /* Windows-specific way I can find to force the winsock calls to */ + /* return WSAEINTR with the test is over. anything that will run on */ + /* 95 and NT and is closer to what netperf expects from Unix signals */ + /* and such would be appreciated raj 1/96 */ + win_kludge_socket = s_data; +#endif /* WIN32 */ + + /* The loop will exit when the timer pops, or if we happen to recv a */ + /* message of less than send_size bytes... */ + + times_up = 0; + + start_timer(test_time + PAD_TIME); + + if (debug) { + fprintf(where,"recv_udp_stream: about to enter inner sanctum.\n"); + fflush(where); + } + + /* We "connect" up to the remote post to allow us to use the recv */ + /* call instead of the recvfrom call. Presumeably, this is a little */ + /* simpler, and a little more efficient. */ + + if (local_connected) { + + /* Receive the first message using recvfrom to find the remote address */ + remote_addrlen = sizeof(remote_addr); + len = recvfrom(s_data, recv_ring->buffer_ptr, + message_size, 0, + (struct sockaddr*)&remote_addr, &remote_addrlen); + if (len != message_size) { + if ((len == SOCKET_ERROR) && !SOCKET_EINTR(len)) { + netperf_response.content.serv_errno = errno; + send_response(); + exit(1); + } + } + messages_recvd++; + recv_ring = recv_ring->next; + + + /* Now connect with the remote socket address */ + if (connect(s_data, + (struct sockaddr*)&remote_addr, + remote_addrlen )== INVALID_SOCKET) { + netperf_response.content.serv_errno = errno; + close(s_data); + send_response(); + exit(1); + } + + if (debug) { + fprintf(where,"recv_udp_stream: connected data socket\n"); + fflush(where); + } + } + + while (!times_up) { + if(local_connected) { + len = recv(s_data, + recv_ring->buffer_ptr, + message_size, + 0); + } else { + len = recvfrom(s_data, + recv_ring->buffer_ptr, + message_size, + 0,0,0); + } + + if (len != message_size) { + if ((len == SOCKET_ERROR) && !SOCKET_EINTR(len)) { + netperf_response.content.serv_errno = errno; + send_response(); + exit(1); + } + break; + } + messages_recvd++; + recv_ring = recv_ring->next; + } + + if (debug) { + fprintf(where,"recv_udp_stream: got %d messages.\n",messages_recvd); + fflush(where); + } + + + /* The loop now exits due timer or < send_size bytes received. in */ + /* reality, we only really support a timed UDP_STREAM test. raj */ + /* 12/95 */ + + cpu_stop(udp_stream_request->measure_cpu,&elapsed_time); + + if (times_up) { + /* we ended on a timer, subtract the PAD_TIME */ + elapsed_time -= (float)PAD_TIME; + } + else { + stop_timer(); + } + + if (debug) { + fprintf(where,"recv_udp_stream: test ended in %f seconds.\n",elapsed_time); + fflush(where); + } + + + /* We will count the "off" message that got us out of the loop */ + bytes_received = (messages_recvd * message_size) + len; + + /* send the results to the sender */ + + if (debug) { + fprintf(where, + "recv_udp_stream: got %d bytes\n", + bytes_received); + fflush(where); + } + + netperf_response.content.response_type = UDP_STREAM_RESULTS; + udp_stream_results->bytes_received = htonl(bytes_received); + udp_stream_results->messages_recvd = messages_recvd; + udp_stream_results->elapsed_time = elapsed_time; + udp_stream_results->cpu_method = cpu_method; + udp_stream_results->num_cpus = lib_num_loc_cpus; + if (udp_stream_request->measure_cpu) { + udp_stream_results->cpu_util = calc_cpu_util(elapsed_time); + } + else { + udp_stream_results->cpu_util = (float) -1.0; + } + + if (debug > 1) { + fprintf(where, + "recv_udp_stream: test complete, sending results.\n"); + fflush(where); + } + + send_response(); + + close(s_data); + +} + +void +send_udp_rr(char remote_host[]) +{ + + char *tput_title = "\ +Local /Remote\n\ +Socket Size Request Resp. Elapsed Trans.\n\ +Send Recv Size Size Time Rate \n\ +bytes Bytes bytes bytes secs. per sec \n\n"; + + char *tput_title_band = "\ +Local /Remote\n\ +Socket Size Request Resp. Elapsed \n\ +Send Recv Size Size Time Throughput \n\ +bytes Bytes bytes bytes secs. %s/sec \n\n"; + + char *tput_fmt_0 = + "%7.2f %s\n"; + + char *tput_fmt_1_line_1 = "\ +%-6d %-6d %-6d %-6d %-6.2f %7.2f %s\n"; + + char *tput_fmt_1_line_2 = "\ +%-6d %-6d\n"; + + char *cpu_title = "\ +Local /Remote\n\ +Socket Size Request Resp. Elapsed Trans. CPU CPU S.dem S.dem\n\ +Send Recv Size Size Time Rate local remote local remote\n\ +bytes bytes bytes bytes secs. per sec %% %c %% %c us/Tr us/Tr\n\n"; + + char *cpu_title_tput = "\ +Local /Remote\n\ +Socket Size Request Resp. Elapsed Tput CPU CPU S.dem S.dem\n\ +Send Recv Size Size Time %-8.8s local remote local remote\n\ +bytes bytes bytes bytes secs. per sec %% %c %% %c us/Tr us/Tr\n\n"; + + char *cpu_fmt_0 = + "%6.3f %c %s\n"; + + char *cpu_fmt_1_line_1 = "\ +%-6d %-6d %-6d %-6d %-6.2f %-6.2f %-6.2f %-6.2f %-6.3f %-6.3f %s\n"; + + char *cpu_fmt_1_line_2 = "\ +%-6d %-6d\n"; + + float elapsed_time; + + struct ring_elt *send_ring; + struct ring_elt *recv_ring; + + int len; + int nummessages; + SOCKET send_socket; + int trans_remaining; + int bytes_xferd; + + int rsp_bytes_recvd; + + float local_cpu_utilization; + float local_service_demand; + float remote_cpu_utilization; + float remote_service_demand; + double thruput; + + struct addrinfo *local_res; + struct addrinfo *remote_res; + + struct udp_rr_request_struct *udp_rr_request; + struct udp_rr_response_struct *udp_rr_response; + struct udp_rr_results_struct *udp_rr_result; + + udp_rr_request = + (struct udp_rr_request_struct *)netperf_request.content.test_specific_data; + udp_rr_response = + (struct udp_rr_response_struct *)netperf_response.content.test_specific_data; + udp_rr_result = + (struct udp_rr_results_struct *)netperf_response.content.test_specific_data; + +#ifdef WANT_HISTOGRAM + if (verbosity > 1) { + time_hist = HIST_new(); + } +#endif + + /* since we are now disconnected from the code that established the */ + /* control socket, and since we want to be able to use different */ + /* protocols and such, we are passed the name of the remote host and */ + /* must turn that into the test specific addressing information. */ + + complete_addrinfos(&remote_res, + &local_res, + remote_host, + SOCK_DGRAM, + IPPROTO_UDP, + 0); + + if ( print_headers ) { + print_top_test_header("UDP REQUEST/RESPONSE TEST",local_res,remote_res); + } + + /* initialize a few counters */ + + send_ring = NULL; + recv_ring = NULL; + nummessages = 0; + bytes_xferd = 0; + times_up = 0; + confidence_iteration = 1; + init_stat(); + + /* we have a great-big while loop which controls the number of times */ + /* we run a particular test. this is for the calculation of a */ + /* confidence interval (I really should have stayed awake during */ + /* probstats :). If the user did not request confidence measurement */ + /* (no confidence is the default) then we will only go though the */ + /* loop once. the confidence stuff originates from the folks at IBM */ + + while (((confidence < 0) && (confidence_iteration < iteration_max)) || + (confidence_iteration <= iteration_min)) { + + nummessages = 0; + bytes_xferd = 0; + times_up = 0; + trans_remaining = 0; + + /* set-up the data buffers with the requested alignment and offset */ + + if (send_width == 0) send_width = 1; + if (recv_width == 0) recv_width = 1; + + if (send_ring == NULL) { + send_ring = allocate_buffer_ring(send_width, + req_size, + local_send_align, + local_send_offset); + } + + if (recv_ring == NULL) { + recv_ring = allocate_buffer_ring(recv_width, + rsp_size, + local_recv_align, + local_recv_offset); + } + + /*set up the data socket */ + send_socket = create_data_socket(local_res); + + if (send_socket == INVALID_SOCKET){ + perror("netperf: send_udp_rr: udp rr data socket"); + exit(1); + } + + if (debug) { + fprintf(where,"send_udp_rr: send_socket obtained...\n"); + } + + /* If the user has requested cpu utilization measurements, we must */ + /* calibrate the cpu(s). We will perform this task within the tests */ + /* themselves. If the user has specified the cpu rate, then */ + /* calibrate_local_cpu will return rather quickly as it will have */ + /* nothing to do. If local_cpu_rate is zero, then we will go through */ + /* all the "normal" calibration stuff and return the rate back. If */ + /* there is no idle counter in the kernel idle loop, the */ + /* local_cpu_rate will be set to -1. */ + + if (local_cpu_usage) { + local_cpu_rate = calibrate_local_cpu(local_cpu_rate); + } + + if (!no_control) { + /* Tell the remote end to do a listen. The server alters the + socket paramters on the other side at this point, hence the + reason for all the values being passed in the setup + message. If the user did not specify any of the parameters, + they will be passed as 0, which will indicate to the remote + that no changes beyond the system's default should be + used. Alignment is the exception, it will default to 8, which + will be no alignment alterations. */ + + netperf_request.content.request_type = DO_UDP_RR; + udp_rr_request->recv_buf_size = rsr_size_req; + udp_rr_request->send_buf_size = rss_size_req; + udp_rr_request->recv_alignment = remote_recv_align; + udp_rr_request->recv_offset = remote_recv_offset; + udp_rr_request->send_alignment = remote_send_align; + udp_rr_request->send_offset = remote_send_offset; + udp_rr_request->request_size = req_size; + udp_rr_request->response_size = rsp_size; + udp_rr_request->measure_cpu = remote_cpu_usage; + udp_rr_request->cpu_rate = remote_cpu_rate; + udp_rr_request->so_rcvavoid = rem_rcvavoid; + udp_rr_request->so_sndavoid = rem_sndavoid; + if (test_time) { + udp_rr_request->test_length = test_time; + } + else { + udp_rr_request->test_length = test_trans * -1; + } + udp_rr_request->port = atoi(remote_data_port); + udp_rr_request->ipfamily = af_to_nf(remote_res->ai_family); + + if (debug > 1) { + fprintf(where,"netperf: send_udp_rr: requesting UDP r/r test\n"); + } + + send_request(); + + /* The response from the remote will contain all of the relevant + socket parameters for this test type. We will put them back + into the variables here so they can be displayed if desired. + The remote will have calibrated CPU if necessary, and will + have done all the needed set-up we will have calibrated the + cpu locally before sending the request, and will grab the + counter value right after the connect returns. The remote + will grab the counter right after the accept call. This saves + the hassle of extra messages being sent for the UDP + tests. */ + + recv_response(); + + if (!netperf_response.content.serv_errno) { + if (debug) + fprintf(where,"remote listen done.\n"); + rsr_size = udp_rr_response->recv_buf_size; + rss_size = udp_rr_response->send_buf_size; + remote_cpu_usage = udp_rr_response->measure_cpu; + remote_cpu_rate = udp_rr_response->cpu_rate; + /* port numbers in proper order */ + set_port_number(remote_res,(short)udp_rr_response->data_port_number); + } + else { + Set_errno(netperf_response.content.serv_errno); + fprintf(where, + "netperf: remote error %d", + netperf_response.content.serv_errno); + perror(""); + fflush(where); + exit(1); + } + } + +#ifdef WANT_DEMO + DEMO_RR_SETUP(100) +#endif + + /* Connect up to the remote port on the data socket. This will set */ + /* the default destination address on this socket. With UDP, this */ + /* does make a performance difference as we may not have to do as */ + /* many routing lookups, however, I expect that a client would */ + /* behave this way. raj 1/94 */ + + if ( connect(send_socket, + remote_res->ai_addr, + remote_res->ai_addrlen) == INVALID_SOCKET ) { + perror("netperf: data socket connect failed"); + exit(1); + } + +#ifdef WIN32 + /* this is used so the timer thread can close the socket out from */ + /* under us, which to date is the easiest/cleanest/least */ + /* Windows-specific way I can find to force the winsock calls to */ + /* return WSAEINTR with the test is over. anything that will run on */ + /* 95 and NT and is closer to what netperf expects from Unix signals */ + /* and such would be appreciated raj 1/96 */ + win_kludge_socket = send_socket; +#endif /* WIN32 */ + + /* Data Socket set-up is finished. If there were problems, either the */ + /* connect would have failed, or the previous response would have */ + /* indicated a problem. I failed to see the value of the extra */ + /* message after the accept on the remote. If it failed, we'll see it */ + /* here. If it didn't, we might as well start pumping data. */ + + /* Set-up the test end conditions. For a request/response test, they */ + /* can be either time or transaction based. */ + + if (test_time) { + /* The user wanted to end the test after a period of time. */ + times_up = 0; + trans_remaining = 0; + start_timer(test_time); + } + else { + /* The tester wanted to send a number of bytes. */ + trans_remaining = test_bytes; + times_up = 1; + } + + /* The cpu_start routine will grab the current time and possibly */ + /* value of the idle counter for later use in measuring cpu */ + /* utilization and/or service demand and thruput. */ + + cpu_start(local_cpu_usage); + +#ifdef WANT_DEMO + if (demo_mode) { + HIST_timestamp(demo_one_ptr); + } +#endif + +#ifdef WANT_INTERVALS + INTERVALS_INIT(); +#endif /* WANT_INTERVALS */ + + /* We use an "OR" to control test execution. When the test is */ + /* controlled by time, the byte count check will always return */ + /* false. When the test is controlled by byte count, the time test */ + /* will always return false. When the test is finished, the whole */ + /* expression will go false and we will stop sending data. I think */ + /* I just arbitrarily decrement trans_remaining for the timed */ + /* test, but will not do that just yet... One other question is */ + /* whether or not the send buffer and the receive buffer should be */ + /* the same buffer. */ + +#ifdef WANT_FIRST_BURST + { + int i; + for (i = 0; i < first_burst_size; i++) { + if((len=send(send_socket, + send_ring->buffer_ptr, + req_size, + 0)) != req_size) { + /* we should never hit the end of the test in the first burst */ + perror("send_udp_rr: initial burst data send error"); + exit(-1); + } + } + } +#endif /* WANT_FIRST_BURST */ + + while ((!times_up) || (trans_remaining > 0)) { + /* send the request */ +#ifdef WANT_HISTOGRAM + if (verbosity > 1) { + HIST_timestamp(&time_one); + } +#endif + if((len=send(send_socket, + send_ring->buffer_ptr, + req_size, + 0)) != req_size) { + if (SOCKET_EINTR(len)) { + /* We likely hit */ + /* test-end time. */ + break; + } + perror("send_udp_rr: data send error"); + exit(1); + } + send_ring = send_ring->next; + + /* receive the response. with UDP we will get it all, or nothing */ + + if((rsp_bytes_recvd=recv(send_socket, + recv_ring->buffer_ptr, + rsp_size, + 0)) != rsp_size) { + if (SOCKET_EINTR(rsp_bytes_recvd)) + { + /* Again, we have likely hit test-end time */ + break; + } + perror("send_udp_rr: data recv error"); + exit(1); + } + recv_ring = recv_ring->next; + +#ifdef WANT_HISTOGRAM + if (verbosity > 1) { + HIST_timestamp(&time_two); + HIST_add(time_hist,delta_micro(&time_one,&time_two)); + } + +#endif + + /* at this point, we may wish to sleep for some period of */ + /* time, so we see how long that last transaction just took, */ + /* and sleep for the difference of that and the interval. We */ + /* will not sleep if the time would be less than a */ + /* millisecond. */ + +#ifdef WANT_DEMO + DEMO_RR_INTERVAL(1); +#endif + +#ifdef WANT_INTERVALS + INTERVALS_WAIT(); +#endif /* WANT_INTERVALS */ + + nummessages++; + if (trans_remaining) { + trans_remaining--; + } + + if (debug > 3) { + if ((nummessages % 100) == 0) { + fprintf(where,"Transaction %d completed\n",nummessages); + fflush(where); + } + } + + } + + /* for some strange reason, I used to call shutdown on the UDP */ + /* data socket here. I'm not sure why, because it would not have */ + /* any effect... raj 11/94 */ + + /* this call will always give us the elapsed time for the test, and */ + /* will also store-away the necessaries for cpu utilization */ + + cpu_stop(local_cpu_usage,&elapsed_time); /* was cpu being */ + /* measured? how long */ + /* did we really run? */ + + if (!no_control) { + /* Get the statistics from the remote end. The remote will have + calculated service demand and all those interesting + things. If it wasn't supposed to care, it will return obvious + values. */ + + recv_response(); + if (!netperf_response.content.serv_errno) { + if (debug) + fprintf(where,"remote results obtained\n"); + } + else { + Set_errno(netperf_response.content.serv_errno); + fprintf(where, + "netperf: remote error %d", + netperf_response.content.serv_errno); + perror(""); + fflush(where); + exit(1); + } + } + + /* We now calculate what our thruput was for the test. In the */ + /* future, we may want to include a calculation of the thruput */ + /* measured by the remote, but it should be the case that for a */ + /* UDP rr test, that the two numbers should be *very* close... */ + /* We calculate bytes_sent regardless of the way the test length */ + /* was controlled. */ + + bytes_xferd = (req_size * nummessages) + (rsp_size * nummessages); + thruput = nummessages / elapsed_time; + + if (local_cpu_usage || remote_cpu_usage) { + + /* We must now do a little math for service demand and cpu */ + /* utilization for the system(s) Of course, some of the */ + /* information might be bogus because there was no idle counter */ + /* in the kernel(s). We need to make a note of this for the */ + /* user's benefit by placing a code for the metod used in the */ + /* test banner */ + + if (local_cpu_usage) { + local_cpu_utilization = calc_cpu_util(0.0); + + /* since calc_service demand is doing ms/Kunit we will */ + /* multiply the number of transaction by 1024 to get */ + /* "good" numbers */ + + local_service_demand = calc_service_demand((double) nummessages*1024, + 0.0, + 0.0, + 0); + } + else { + local_cpu_utilization = (float) -1.0; + local_service_demand = (float) -1.0; + } + + if (remote_cpu_usage) { + remote_cpu_utilization = udp_rr_result->cpu_util; + + /* since calc_service demand is doing ms/Kunit we will */ + /* multiply the number of transaction by 1024 to get */ + /* "good" numbers */ + + remote_service_demand = calc_service_demand((double) nummessages*1024, + 0.0, + remote_cpu_utilization, + udp_rr_result->num_cpus); + } + else { + remote_cpu_utilization = (float) -1.0; + remote_service_demand = (float) -1.0; + } + } + else { + /* we were not measuring cpu, for the confidence stuff, we */ + /* should make it -1.0 */ + local_cpu_utilization = (float) -1.0; + local_service_demand = (float) -1.0; + remote_cpu_utilization = (float) -1.0; + remote_service_demand = (float) -1.0; + } + + /* at this point, we want to calculate the confidence information. */ + /* if debugging is on, calculate_confidence will print-out the */ + /* parameters we pass it */ + + calculate_confidence(confidence_iteration, + elapsed_time, + thruput, + local_cpu_utilization, + remote_cpu_utilization, + local_service_demand, + remote_service_demand); + + + confidence_iteration++; + + /* we are done with the socket */ + close(send_socket); + } + + /* at this point, we have made all the iterations we are going to */ + /* make. */ + retrieve_confident_values(&elapsed_time, + &thruput, + &local_cpu_utilization, + &remote_cpu_utilization, + &local_service_demand, + &remote_service_demand); + + /* We are now ready to print all the information. If the user */ + /* has specified zero-level verbosity, we will just print the */ + /* local service demand, or the remote service demand. If the */ + /* user has requested verbosity level 1, he will get the basic */ + /* "streamperf" numbers. If the user has specified a verbosity */ + /* of greater than 1, we will display a veritable plethora of */ + /* background information from outside of this block as it it */ + /* not cpu_measurement specific... */ + + if (confidence < 0) { + /* we did not hit confidence, but were we asked to look for it? */ + if (iteration_max > 1) { + display_confidence(); + } + } + + if (local_cpu_usage || remote_cpu_usage) { + local_cpu_method = format_cpu_method(cpu_method); + remote_cpu_method = format_cpu_method(udp_rr_result->cpu_method); + + switch (verbosity) { + case 0: + if (local_cpu_usage) { + fprintf(where, + cpu_fmt_0, + local_service_demand, + local_cpu_method, + ((print_headers) || + (result_brand == NULL)) ? "" : result_brand); + + } + else { + fprintf(where, + cpu_fmt_0, + remote_service_demand, + remote_cpu_method, + ((print_headers) || + (result_brand == NULL)) ? "" : result_brand); + + } + break; + case 1: + case 2: + if (print_headers) { + if ('x' == libfmt) { + fprintf(where, + cpu_title, + local_cpu_method, + remote_cpu_method); + } + else { + fprintf(where, + cpu_title_tput, + format_units(), + local_cpu_method, + remote_cpu_method); + } + } + + fprintf(where, + cpu_fmt_1_line_1, /* the format string */ + lss_size, /* local sendbuf size */ + lsr_size, + req_size, /* how large were the requests */ + rsp_size, /* guess */ + elapsed_time, /* how long was the test */ + ('x' == libfmt) ? thruput : + calc_thruput_interval_omni(thruput * (req_size+rsp_size), + 1.0), + local_cpu_utilization, /* local cpu */ + remote_cpu_utilization, /* remote cpu */ + local_service_demand, /* local service demand */ + remote_service_demand, /* remote service demand */ + ((print_headers) || + (result_brand == NULL)) ? "" : result_brand); + fprintf(where, + cpu_fmt_1_line_2, + rss_size, + rsr_size); + break; + } + } + else { + /* The tester did not wish to measure service demand. */ + switch (verbosity) { + case 0: + fprintf(where, + tput_fmt_0, + ('x' == libfmt) ? thruput : + calc_thruput_interval_omni(thruput * (req_size+rsp_size), + 1.0), + ((print_headers) || + (result_brand == NULL)) ? "" : result_brand); + break; + case 1: + case 2: + if (print_headers) { + fprintf(where, + ('x' == libfmt) ? tput_title : tput_title_band, + format_units()); + } + + fprintf(where, + tput_fmt_1_line_1, /* the format string */ + lss_size, + lsr_size, + req_size, /* how large were the requests */ + rsp_size, /* how large were the responses */ + elapsed_time, /* how long did it take */ + ('x' == libfmt) ? thruput : + calc_thruput_interval_omni(thruput * (req_size+rsp_size), + 1.0), + ((print_headers) || + (result_brand == NULL)) ? "" : result_brand); + fprintf(where, + tput_fmt_1_line_2, + rss_size, /* remote recvbuf size */ + rsr_size); + + break; + } + } + fflush(where); + + /* it would be a good thing to include information about some of the */ + /* other parameters that may have been set for this test, but at the */ + /* moment, I do not wish to figure-out all the formatting, so I will */ + /* just put this comment here to help remind me that it is something */ + /* that should be done at a later time. */ + + /* how to handle the verbose information in the presence of */ + /* confidence intervals is yet to be determined... raj 11/94 */ + + if (verbosity > 1) { + /* The user wanted to know it all, so we will give it to him. */ + /* This information will include as much as we can find about */ + /* UDP statistics, the alignments of the sends and receives */ + /* and all that sort of rot... */ + +#ifdef WANT_HISTOGRAM + fprintf(where,"\nHistogram of request/reponse times.\n"); + fflush(where); + HIST_report(time_hist); +#endif /* WANT_HISTOGRAM */ + } +} + + /* this routine implements the receive side (netserver) of a UDP_RR */ + /* test. */ +void +recv_udp_rr() +{ + + struct ring_elt *recv_ring; + struct ring_elt *send_ring; + + struct addrinfo *local_res; + char local_name[BUFSIZ]; + char port_buffer[PORTBUFSIZE]; + + struct sockaddr_storage myaddr_in; + struct sockaddr_storage peeraddr; + SOCKET s_data; + netperf_socklen_t addrlen; + int trans_received; + int trans_remaining; + int request_bytes_recvd; + int response_bytes_sent; + float elapsed_time; + + struct udp_rr_request_struct *udp_rr_request; + struct udp_rr_response_struct *udp_rr_response; + struct udp_rr_results_struct *udp_rr_results; + + udp_rr_request = + (struct udp_rr_request_struct *)netperf_request.content.test_specific_data; + udp_rr_response = + (struct udp_rr_response_struct *)netperf_response.content.test_specific_data; + udp_rr_results = + (struct udp_rr_results_struct *)netperf_response.content.test_specific_data; + + if (debug) { + fprintf(where,"netserver: recv_udp_rr: entered...\n"); + fflush(where); + } + + /* We want to set-up the listen socket with all the desired */ + /* parameters and then let the initiator know that all is ready. If */ + /* socket size defaults are to be used, then the initiator will have */ + /* sent us 0's. If the socket sizes cannot be changed, then we will */ + /* send-back what they are. If that information cannot be determined, */ + /* then we send-back -1's for the sizes. If things go wrong for any */ + /* reason, we will drop back ten yards and punt. */ + + /* If anything goes wrong, we want the remote to know about it. It */ + /* would be best if the error that the remote reports to the user is */ + /* the actual error we encountered, rather than some bogus unexpected */ + /* response type message. */ + + if (debug) { + fprintf(where,"recv_udp_rr: setting the response type...\n"); + fflush(where); + } + + netperf_response.content.response_type = UDP_RR_RESPONSE; + + if (debug) { + fprintf(where,"recv_udp_rr: the response type is set...\n"); + fflush(where); + } + + /* We now alter the message_ptr variables to be at the desired */ + /* alignments with the desired offsets. */ + + if (debug) { + fprintf(where,"recv_udp_rr: requested recv alignment of %d offset %d\n", + udp_rr_request->recv_alignment, + udp_rr_request->recv_offset); + fprintf(where,"recv_udp_rr: requested send alignment of %d offset %d\n", + udp_rr_request->send_alignment, + udp_rr_request->send_offset); + fflush(where); + } + + if (send_width == 0) send_width = 1; + if (recv_width == 0) recv_width = 1; + + recv_ring = allocate_buffer_ring(recv_width, + udp_rr_request->request_size, + udp_rr_request->recv_alignment, + udp_rr_request->recv_offset); + + send_ring = allocate_buffer_ring(send_width, + udp_rr_request->response_size, + udp_rr_request->send_alignment, + udp_rr_request->send_offset); + + if (debug) { + fprintf(where,"recv_udp_rr: receive alignment and offset set...\n"); + fflush(where); + } + + /* Grab a socket to listen on, and then listen on it. */ + + if (debug) { + fprintf(where,"recv_udp_rr: grabbing a socket...\n"); + fflush(where); + } + + + /* create_data_socket expects to find some things in the global */ + /* variables, so set the globals based on the values in the request. */ + /* once the socket has been created, we will set the response values */ + /* based on the updated value of those globals. raj 7/94 */ + lss_size_req = udp_rr_request->send_buf_size; + lsr_size_req = udp_rr_request->recv_buf_size; + loc_rcvavoid = udp_rr_request->so_rcvavoid; + loc_sndavoid = udp_rr_request->so_sndavoid; + + set_hostname_and_port(local_name, + port_buffer, + nf_to_af(udp_rr_request->ipfamily), + udp_rr_request->port); + + local_res = complete_addrinfo(local_name, + local_name, + port_buffer, + nf_to_af(udp_rr_request->ipfamily), + SOCK_DGRAM, + IPPROTO_UDP, + 0); + + s_data = create_data_socket(local_res); + + if (s_data == INVALID_SOCKET) { + netperf_response.content.serv_errno = errno; + send_response(); + + exit(1); + } + + /* now get the port number assigned by the system */ + addrlen = sizeof(myaddr_in); + if (getsockname(s_data, + (struct sockaddr *)&myaddr_in, + &addrlen) == SOCKET_ERROR){ + netperf_response.content.serv_errno = errno; + close(s_data); + send_response(); + + exit(1); + } + + /* Now myaddr_in contains the port and the internet address this is */ + /* returned to the sender also implicitly telling the sender that the */ + /* socket buffer sizing has been done. */ + + udp_rr_response->data_port_number = + (int) ntohs(((struct sockaddr_in *)&myaddr_in)->sin_port); + netperf_response.content.serv_errno = 0; + + if (debug) { + fprintf(where, + "recv port number %d\n", + ((struct sockaddr_in *)&myaddr_in)->sin_port); + fflush(where); + } + + /* But wait, there's more. If the initiator wanted cpu measurements, */ + /* then we must call the calibrate routine, which will return the max */ + /* rate back to the initiator. If the CPU was not to be measured, or */ + /* something went wrong with the calibration, we will return a 0.0 to */ + /* the initiator. */ + + udp_rr_response->cpu_rate = (float)0.0; /* assume no cpu */ + udp_rr_response->measure_cpu = 0; + if (udp_rr_request->measure_cpu) { + udp_rr_response->measure_cpu = 1; + udp_rr_response->cpu_rate = calibrate_local_cpu(udp_rr_request->cpu_rate); + } + + /* before we send the response back to the initiator, pull some of */ + /* the socket parms from the globals */ + udp_rr_response->send_buf_size = lss_size; + udp_rr_response->recv_buf_size = lsr_size; + udp_rr_response->so_rcvavoid = loc_rcvavoid; + udp_rr_response->so_sndavoid = loc_sndavoid; + + send_response(); + + + /* Now it's time to start receiving data on the connection. We will */ + /* first grab the apropriate counters and then start grabbing. */ + + cpu_start(udp_rr_request->measure_cpu); + +#ifdef WIN32 + /* this is used so the timer thread can close the socket out from */ + /* under us, which to date is the easiest/cleanest/least */ + /* Windows-specific way I can find to force the winsock calls to */ + /* return WSAEINTR with the test is over. anything that will run on */ + /* 95 and NT and is closer to what netperf expects from Unix signals */ + /* and such would be appreciated raj 1/96 */ + win_kludge_socket = s_data; +#endif /* WIN32 */ + + if (udp_rr_request->test_length > 0) { + times_up = 0; + trans_remaining = 0; + start_timer(udp_rr_request->test_length + PAD_TIME); + } + else { + times_up = 1; + trans_remaining = udp_rr_request->test_length * -1; + } + + addrlen = sizeof(peeraddr); + bzero((char *)&peeraddr, addrlen); + + trans_received = 0; + + while ((!times_up) || (trans_remaining > 0)) { + + /* receive the request from the other side */ + if ((request_bytes_recvd = recvfrom(s_data, + recv_ring->buffer_ptr, + udp_rr_request->request_size, + 0, + (struct sockaddr *)&peeraddr, + &addrlen)) != udp_rr_request->request_size) { + if ( SOCKET_EINTR(request_bytes_recvd) ) + { + /* we must have hit the end of test time. */ + break; + } + netperf_response.content.serv_errno = errno; + send_response(); + exit(1); + } + recv_ring = recv_ring->next; + + /* Now, send the response to the remote */ + if ((response_bytes_sent = sendto(s_data, + send_ring->buffer_ptr, + udp_rr_request->response_size, + 0, + (struct sockaddr *)&peeraddr, + addrlen)) != + udp_rr_request->response_size) { + if ( SOCKET_EINTR(response_bytes_sent) ) + { + /* we have hit end of test time. */ + break; + } + netperf_response.content.serv_errno = errno; + send_response(); + exit(1); + } + send_ring = send_ring->next; + + trans_received++; + if (trans_remaining) { + trans_remaining--; + } + + if (debug) { + fprintf(where, + "recv_udp_rr: Transaction %d complete.\n", + trans_received); + fflush(where); + } + + } + + + /* The loop now exits due to timeout or transaction count being */ + /* reached */ + + cpu_stop(udp_rr_request->measure_cpu,&elapsed_time); + + if (times_up) { + /* we ended the test by time, which was at least 2 seconds */ + /* longer than we wanted to run. so, we want to subtract */ + /* PAD_TIME from the elapsed_time. */ + elapsed_time -= PAD_TIME; + } + /* send the results to the sender */ + + if (debug) { + fprintf(where, + "recv_udp_rr: got %d transactions\n", + trans_received); + fflush(where); + } + + udp_rr_results->bytes_received = (trans_received * + (udp_rr_request->request_size + + udp_rr_request->response_size)); + udp_rr_results->trans_received = trans_received; + udp_rr_results->elapsed_time = elapsed_time; + udp_rr_results->cpu_method = cpu_method; + udp_rr_results->num_cpus = lib_num_loc_cpus; + if (udp_rr_request->measure_cpu) { + udp_rr_results->cpu_util = calc_cpu_util(elapsed_time); + } + + if (debug) { + fprintf(where, + "recv_udp_rr: test complete, sending results.\n"); + fflush(where); + } + + send_response(); + + /* we are done with the socket now */ + close(s_data); + + } + + + /* this routine implements the receive (netserver) side of a TCP_RR */ + /* test */ +void +recv_tcp_rr() +{ + + struct ring_elt *send_ring; + struct ring_elt *recv_ring; + + struct addrinfo *local_res; + char local_name[BUFSIZ]; + char port_buffer[PORTBUFSIZE]; + + struct sockaddr_storage myaddr_in, + peeraddr_in; + SOCKET s_listen,s_data; + netperf_socklen_t addrlen; + char *temp_message_ptr; + int trans_received; + int trans_remaining; + int bytes_sent; + int request_bytes_recvd; + int request_bytes_remaining; + int timed_out = 0; + int sock_closed = 0; + float elapsed_time; + + struct tcp_rr_request_struct *tcp_rr_request; + struct tcp_rr_response_struct *tcp_rr_response; + struct tcp_rr_results_struct *tcp_rr_results; + + tcp_rr_request = + (struct tcp_rr_request_struct *)netperf_request.content.test_specific_data; + tcp_rr_response = + (struct tcp_rr_response_struct *)netperf_response.content.test_specific_data; + tcp_rr_results = + (struct tcp_rr_results_struct *)netperf_response.content.test_specific_data; + + if (debug) { + fprintf(where,"netserver: recv_tcp_rr: entered...\n"); + fflush(where); + } + + /* We want to set-up the listen socket with all the desired */ + /* parameters and then let the initiator know that all is ready. If */ + /* socket size defaults are to be used, then the initiator will have */ + /* sent us 0's. If the socket sizes cannot be changed, then we will */ + /* send-back what they are. If that information cannot be determined, */ + /* then we send-back -1's for the sizes. If things go wrong for any */ + /* reason, we will drop back ten yards and punt. */ + + /* If anything goes wrong, we want the remote to know about it. It */ + /* would be best if the error that the remote reports to the user is */ + /* the actual error we encountered, rather than some bogus unexpected */ + /* response type message. */ + + if (debug) { + fprintf(where,"recv_tcp_rr: setting the response type...\n"); + fflush(where); + } + + netperf_response.content.response_type = TCP_RR_RESPONSE; + + if (debug) { + fprintf(where,"recv_tcp_rr: the response type is set...\n"); + fflush(where); + } + + /* allocate the recv and send rings with the requested alignments */ + /* and offsets. raj 7/94 */ + if (debug) { + fprintf(where,"recv_tcp_rr: requested recv alignment of %d offset %d\n", + tcp_rr_request->recv_alignment, + tcp_rr_request->recv_offset); + fprintf(where,"recv_tcp_rr: requested send alignment of %d offset %d\n", + tcp_rr_request->send_alignment, + tcp_rr_request->send_offset); + fflush(where); + } + + /* at some point, these need to come to us from the remote system */ + if (send_width == 0) send_width = 1; + if (recv_width == 0) recv_width = 1; + + send_ring = allocate_buffer_ring(send_width, + tcp_rr_request->response_size, + tcp_rr_request->send_alignment, + tcp_rr_request->send_offset); + + recv_ring = allocate_buffer_ring(recv_width, + tcp_rr_request->request_size, + tcp_rr_request->recv_alignment, + tcp_rr_request->recv_offset); + + + /* Grab a socket to listen on, and then listen on it. */ + + if (debug) { + fprintf(where,"recv_tcp_rr: grabbing a socket...\n"); + fflush(where); + } + + /* create_data_socket expects to find some things in the global */ + /* variables, so set the globals based on the values in the request. */ + /* once the socket has been created, we will set the response values */ + /* based on the updated value of those globals. raj 7/94 */ + lss_size_req = tcp_rr_request->send_buf_size; + lsr_size_req = tcp_rr_request->recv_buf_size; + loc_nodelay = tcp_rr_request->no_delay; + loc_rcvavoid = tcp_rr_request->so_rcvavoid; + loc_sndavoid = tcp_rr_request->so_sndavoid; + + set_hostname_and_port(local_name, + port_buffer, + nf_to_af(tcp_rr_request->ipfamily), + tcp_rr_request->port); + + local_res = complete_addrinfo(local_name, + local_name, + port_buffer, + nf_to_af(tcp_rr_request->ipfamily), + SOCK_STREAM, + IPPROTO_TCP, + 0); + + s_listen = create_data_socket(local_res); + + if (s_listen == INVALID_SOCKET) { + netperf_response.content.serv_errno = errno; + send_response(); + + exit(1); + } + + +#ifdef WIN32 + /* The test timer can fire during operations on the listening socket, + so to make the start_timer below work we have to move + it to close s_listen while we are blocked on accept. */ + win_kludge_socket2 = s_listen; +#endif + + + /* Now, let's set-up the socket to listen for connections */ + if (listen(s_listen, 5) == SOCKET_ERROR) { + netperf_response.content.serv_errno = errno; + close(s_listen); + send_response(); + + exit(1); + } + + + /* now get the port number assigned by the system */ + addrlen = sizeof(myaddr_in); + if (getsockname(s_listen, + (struct sockaddr *)&myaddr_in, + &addrlen) == SOCKET_ERROR) { + netperf_response.content.serv_errno = errno; + close(s_listen); + send_response(); + + exit(1); + } + + /* Now myaddr_in contains the port and the internet address this is */ + /* returned to the sender also implicitly telling the sender that the */ + /* socket buffer sizing has been done. */ + + tcp_rr_response->data_port_number = + (int) ntohs(((struct sockaddr_in *)&myaddr_in)->sin_port); + netperf_response.content.serv_errno = 0; + + /* But wait, there's more. If the initiator wanted cpu measurements, */ + /* then we must call the calibrate routine, which will return the max */ + /* rate back to the initiator. If the CPU was not to be measured, or */ + /* something went wrong with the calibration, we will return a 0.0 to */ + /* the initiator. */ + + tcp_rr_response->cpu_rate = (float)0.0; /* assume no cpu */ + tcp_rr_response->measure_cpu = 0; + + if (tcp_rr_request->measure_cpu) { + tcp_rr_response->measure_cpu = 1; + tcp_rr_response->cpu_rate = calibrate_local_cpu(tcp_rr_request->cpu_rate); + } + + + /* before we send the response back to the initiator, pull some of */ + /* the socket parms from the globals */ + tcp_rr_response->send_buf_size = lss_size; + tcp_rr_response->recv_buf_size = lsr_size; + tcp_rr_response->no_delay = loc_nodelay; + tcp_rr_response->so_rcvavoid = loc_rcvavoid; + tcp_rr_response->so_sndavoid = loc_sndavoid; + tcp_rr_response->test_length = tcp_rr_request->test_length; + send_response(); + + addrlen = sizeof(peeraddr_in); + + if ((s_data = accept(s_listen, + (struct sockaddr *)&peeraddr_in, + &addrlen)) == INVALID_SOCKET) { + /* Let's just punt. The remote will be given some information */ + close(s_listen); + + exit(1); + } + +#ifdef KLUDGE_SOCKET_OPTIONS + /* this is for those systems which *INCORRECTLY* fail to pass */ + /* attributes across an accept() call. Including this goes against */ + /* my better judgement :( raj 11/95 */ + + kludge_socket_options(s_data); + +#endif /* KLUDGE_SOCKET_OPTIONS */ + +#ifdef WIN32 + /* this is used so the timer thread can close the socket out from */ + /* under us, which to date is the easiest/cleanest/least */ + /* Windows-specific way I can find to force the winsock calls to */ + /* return WSAEINTR with the test is over. anything that will run on */ + /* 95 and NT and is closer to what netperf expects from Unix signals */ + /* and such would be appreciated raj 1/96 */ + win_kludge_socket = s_data; + win_kludge_socket2 = INVALID_SOCKET; +#endif /* WIN32 */ + + if (debug) { + fprintf(where,"recv_tcp_rr: accept completes on the data connection.\n"); + fflush(where); + } + + /* Now it's time to start receiving data on the connection. We will */ + /* first grab the apropriate counters and then start grabbing. */ + + cpu_start(tcp_rr_request->measure_cpu); + + /* The loop will exit when we hit the end of the test time, or when */ + /* we have exchanged the requested number of transactions. */ + + if (tcp_rr_request->test_length > 0) { + times_up = 0; + trans_remaining = 0; + start_timer(tcp_rr_request->test_length + PAD_TIME); + } + else { + times_up = 1; + trans_remaining = tcp_rr_request->test_length * -1; + } + + trans_received = 0; + + while ((!times_up) || (trans_remaining > 0)) { + temp_message_ptr = recv_ring->buffer_ptr; + request_bytes_remaining = tcp_rr_request->request_size; + while(request_bytes_remaining > 0) { + if((request_bytes_recvd=recv(s_data, + temp_message_ptr, + request_bytes_remaining, + 0)) == SOCKET_ERROR) { + if (SOCKET_EINTR(request_bytes_recvd)) + { + timed_out = 1; + break; + } + + netperf_response.content.serv_errno = errno; + send_response(); + exit(1); + } + else if( request_bytes_recvd == 0 ) { + if (debug) { + fprintf(where,"zero is my hero\n"); + fflush(where); + } + sock_closed = 1; + break; + } + else { + request_bytes_remaining -= request_bytes_recvd; + temp_message_ptr += request_bytes_recvd; + } + } + + recv_ring = recv_ring->next; + + if ((timed_out) || (sock_closed)) { + /* we hit the end of the test based on time - or the socket + closed on us along the way. bail out of here now... */ + if (debug) { + fprintf(where,"yo5\n"); + fflush(where); + } + break; + } + + /* Now, send the response to the remote */ + if((bytes_sent=send(s_data, + send_ring->buffer_ptr, + tcp_rr_request->response_size, + 0)) == SOCKET_ERROR) { + if (SOCKET_EINTR(bytes_sent)) { + /* the test timer has popped */ + timed_out = 1; + fprintf(where,"yo6\n"); + fflush(where); + break; + } + netperf_response.content.serv_errno = 992; + send_response(); + exit(1); + } + + send_ring = send_ring->next; + + trans_received++; + if (trans_remaining) { + trans_remaining--; + } + } + + + /* The loop now exits due to timeout or transaction count being */ + /* reached */ + + cpu_stop(tcp_rr_request->measure_cpu,&elapsed_time); + + stop_timer(); + + if (timed_out) { + /* we ended the test by time, which was at least 2 seconds */ + /* longer than we wanted to run. so, we want to subtract */ + /* PAD_TIME from the elapsed_time. */ + elapsed_time -= PAD_TIME; + } + + /* send the results to the sender */ + + if (debug) { + fprintf(where, + "recv_tcp_rr: got %d transactions\n", + trans_received); + fflush(where); + } + + tcp_rr_results->bytes_received = (trans_received * + (tcp_rr_request->request_size + + tcp_rr_request->response_size)); + tcp_rr_results->trans_received = trans_received; + tcp_rr_results->elapsed_time = elapsed_time; + tcp_rr_results->cpu_method = cpu_method; + tcp_rr_results->num_cpus = lib_num_loc_cpus; + if (tcp_rr_request->measure_cpu) { + tcp_rr_results->cpu_util = calc_cpu_util(elapsed_time); + } + + if (debug) { + fprintf(where, + "recv_tcp_rr: test complete, sending results.\n"); + fflush(where); + } + + /* we are now done with the sockets */ + close(s_data); + close(s_listen); + + send_response(); + +} + + +void +loc_cpu_rate() +{ +#if defined(USE_LOOPER) + float dummy; +#endif + + /* a rather simple little test - it merely calibrates the local cpu */ + /* and prints the results. There are no headers to allow someone to */ + /* find a rate and use it in other tests automagically by setting a */ + /* variable equal to the output of this test. We ignore any rates */ + /* that may have been specified. In fact, we ignore all of the */ + /* command line args! */ + + fprintf(where, + "%g", + calibrate_local_cpu(0.0)); + + if (verbosity > 1) + fprintf(where, + "\nThere %s %d local %s\n", + (lib_num_loc_cpus > 1) ? "are" : "is", + lib_num_loc_cpus, + (lib_num_loc_cpus > 1) ? "cpus" : "cpu"); + + /* we need the cpu_start, cpu_stop in the looper case to kill the */ + /* child proceses raj 4/95 */ + +#ifdef USE_LOOPER + cpu_start(1); + cpu_stop(1,&dummy); +#endif /* USE_LOOPER */ + +} + +void +rem_cpu_rate() +{ + /* this test is much like the local variant, except that it works for */ + /* the remote system, so in this case, we do pay attention to the */ + /* value of the '-H' command line argument. */ + + fprintf(where, + "%g", + calibrate_remote_cpu()); + + if (verbosity > 1) + fprintf(where, + "\nThere %s %d remote %s\n", + (lib_num_rem_cpus > 1) ? "are" : "is", + lib_num_rem_cpus, + (lib_num_rem_cpus > 1) ? "cpus" : "cpu"); + +} + + + /* this test is intended to test the performance of establishing a + connection, exchanging a request/response pair, and repeating. it + is expected that this would be a good starting-point for + comparision of T/TCP with classic TCP for transactional workloads. + it will also look (can look) much like the communication pattern + of http for www access. */ + +void +send_tcp_conn_rr(char remote_host[]) +{ + + char *tput_title = "\ +Local /Remote\n\ +Socket Size Request Resp. Elapsed Trans.\n\ +Send Recv Size Size Time Rate \n\ +bytes Bytes bytes bytes secs. per sec \n\n"; + + char *tput_fmt_0 = + "%7.2f\n"; + + char *tput_fmt_1_line_1 = "\ +%-6d %-6d %-6d %-6d %-6.2f %7.2f \n"; + char *tput_fmt_1_line_2 = "\ +%-6d %-6d\n"; + + char *cpu_title = "\ +Local /Remote\n\ +Socket Size Request Resp. Elapsed Trans. CPU CPU S.dem S.dem\n\ +Send Recv Size Size Time Rate local remote local remote\n\ +bytes bytes bytes bytes secs. per sec %% %% us/Tr us/Tr\n\n"; + + char *cpu_fmt_0 = + "%6.3f\n"; + + char *cpu_fmt_1_line_1 = "\ +%-6d %-6d %-6d %-6d %-6.2f %-6.2f %-6.2f %-6.2f %-6.3f %-6.3f\n"; + + char *cpu_fmt_1_line_2 = "\ +%-6d %-6d\n"; + + char *ksink_fmt = "\n\ +Alignment Offset\n\ +Local Remote Local Remote\n\ +Send Recv Send Recv\n\ +%5d %5d %5d %5d\n"; + + + int timed_out = 0; + float elapsed_time; + + int len; + struct ring_elt *send_ring; + struct ring_elt *recv_ring; + char *temp_message_ptr; + int nummessages; + SOCKET send_socket; + int trans_remaining; + double bytes_xferd; + int rsp_bytes_left; + int rsp_bytes_recvd; + + float local_cpu_utilization; + float local_service_demand; + float remote_cpu_utilization; + float remote_service_demand; + double thruput; + + struct addrinfo *local_res; + struct addrinfo *remote_res; + + int myport; + int ret; + + struct tcp_conn_rr_request_struct *tcp_conn_rr_request; + struct tcp_conn_rr_response_struct *tcp_conn_rr_response; + struct tcp_conn_rr_results_struct *tcp_conn_rr_result; + + tcp_conn_rr_request = + (struct tcp_conn_rr_request_struct *)netperf_request.content.test_specific_data; + tcp_conn_rr_response = + (struct tcp_conn_rr_response_struct *)netperf_response.content.test_specific_data; + tcp_conn_rr_result = + (struct tcp_conn_rr_results_struct *)netperf_response.content.test_specific_data; + + +#ifdef WANT_HISTOGRAM + if (verbosity > 1) { + time_hist = HIST_new(); + } +#endif /* WANT_HISTOGRAM */ + + /* since we are now disconnected from the code that established the */ + /* control socket, and since we want to be able to use different */ + /* protocols and such, we are passed the name of the remote host and */ + /* must turn that into the test specific addressing information. */ + + complete_addrinfos(&remote_res, + &local_res, + remote_host, + SOCK_STREAM, + IPPROTO_TCP, + 0); + + if ( print_headers ) { + print_top_test_header("TCP Connect/Request/Response TEST",local_res,remote_res); + } + + /* initialize a few counters */ + + nummessages = 0; + bytes_xferd = 0.0; + times_up = 0; + + /* set-up the data buffers with the requested alignment and offset */ + if (send_width == 0) send_width = 1; + if (recv_width == 0) recv_width = 1; + + send_ring = allocate_buffer_ring(send_width, + req_size, + local_send_align, + local_send_offset); + + recv_ring = allocate_buffer_ring(recv_width, + rsp_size, + local_recv_align, + local_recv_offset); + + + if (debug) { + fprintf(where,"send_tcp_conn_rr: send_socket obtained...\n"); + } + + /* If the user has requested cpu utilization measurements, we must */ + /* calibrate the cpu(s). We will perform this task within the tests */ + /* themselves. If the user has specified the cpu rate, then */ + /* calibrate_local_cpu will return rather quickly as it will have */ + /* nothing to do. If local_cpu_rate is zero, then we will go through */ + /* all the "normal" calibration stuff and return the rate back.*/ + + if (local_cpu_usage) { + local_cpu_rate = calibrate_local_cpu(local_cpu_rate); + } + + if (!no_control) { + + /* Tell the remote end to do a listen. The server alters the + socket paramters on the other side at this point, hence the + reason for all the values being passed in the setup message. If + the user did not specify any of the parameters, they will be + passed as 0, which will indicate to the remote that no changes + beyond the system's default should be used. Alignment is the + exception, it will default to 8, which will be no alignment + alterations. */ + + netperf_request.content.request_type = DO_TCP_CRR; + tcp_conn_rr_request->recv_buf_size = rsr_size_req; + tcp_conn_rr_request->send_buf_size = rss_size_req; + tcp_conn_rr_request->recv_alignment = remote_recv_align; + tcp_conn_rr_request->recv_offset = remote_recv_offset; + tcp_conn_rr_request->send_alignment = remote_send_align; + tcp_conn_rr_request->send_offset = remote_send_offset; + tcp_conn_rr_request->request_size = req_size; + tcp_conn_rr_request->response_size = rsp_size; + tcp_conn_rr_request->no_delay = rem_nodelay; + tcp_conn_rr_request->measure_cpu = remote_cpu_usage; + tcp_conn_rr_request->cpu_rate = remote_cpu_rate; + tcp_conn_rr_request->so_rcvavoid = rem_rcvavoid; + tcp_conn_rr_request->so_sndavoid = rem_sndavoid; + if (test_time) { + tcp_conn_rr_request->test_length = test_time; + } + else { + tcp_conn_rr_request->test_length = test_trans * -1; + } + tcp_conn_rr_request->port = atoi(remote_data_port); + tcp_conn_rr_request->ipfamily = af_to_nf(remote_res->ai_family); + + if (debug > 1) { + fprintf(where,"netperf: send_tcp_conn_rr: requesting TCP crr test\n"); + } + + send_request(); + + /* The response from the remote will contain all of the relevant + socket parameters for this test type. We will put them back + into the variables here so they can be displayed if desired. + The remote will have calibrated CPU if necessary, and will have + done all the needed set-up we will have calibrated the cpu + locally before sending the request, and will grab the counter + value right after the connect returns. The remote will grab the + counter right after the accept call. This saves the hassle of + extra messages being sent for the TCP tests. */ + + recv_response(); + + if (!netperf_response.content.serv_errno) { + rsr_size = tcp_conn_rr_response->recv_buf_size; + rss_size = tcp_conn_rr_response->send_buf_size; + rem_nodelay = tcp_conn_rr_response->no_delay; + remote_cpu_usage = tcp_conn_rr_response->measure_cpu; + remote_cpu_rate = tcp_conn_rr_response->cpu_rate; + /* make sure that port numbers are in network order */ + set_port_number(remote_res, + (unsigned short)tcp_conn_rr_response->data_port_number); + + if (debug) { + fprintf(where,"remote listen done.\n"); + fprintf(where,"remote port is %u\n",get_port_number(remote_res)); + fflush(where); + } + } + else { + Set_errno(netperf_response.content.serv_errno); + fprintf(where, + "netperf: remote error %d", + netperf_response.content.serv_errno); + perror(""); + fflush(where); + exit(1); + } + } +#ifdef WANT_DEMO + DEMO_RR_SETUP(100) +#endif + + /* pick a nice random spot between client_port_min and */ + /* client_port_max for our initial port number */ + srand(getpid()); + if (client_port_max - client_port_min) { + myport = client_port_min + + (rand() % (client_port_max - client_port_min)); + } + else { + myport = client_port_min; + } + /* there will be a ++ before the first call to bind, so subtract one */ + myport--; + /* Set-up the test end conditions. For a request/response test, they */ + /* can be either time or transaction based. */ + + if (test_time) { + /* The user wanted to end the test after a period of time. */ + times_up = 0; + trans_remaining = 0; + start_timer(test_time); + } + else { + /* The tester wanted to send a number of bytes. */ + trans_remaining = test_bytes; + times_up = 1; + } + + /* The cpu_start routine will grab the current time and possibly */ + /* value of the idle counter for later use in measuring cpu */ + /* utilization and/or service demand and thruput. */ + + + cpu_start(local_cpu_usage); + +#ifdef WANT_DEMO + if (demo_mode) { + HIST_timestamp(demo_one_ptr); + } +#endif + + /* We use an "OR" to control test execution. When the test is */ + /* controlled by time, the byte count check will always return false. */ + /* When the test is controlled by byte count, the time test will */ + /* always return false. When the test is finished, the whole */ + /* expression will go false and we will stop sending data. I think I */ + /* just arbitrarily decrement trans_remaining for the timed test, but */ + /* will not do that just yet... One other question is whether or not */ + /* the send buffer and the receive buffer should be the same buffer. */ + + while ((!times_up) || (trans_remaining > 0)) { + +#ifdef WANT_HISTOGRAM + if (verbosity > 1) { + /* timestamp just before our call to create the socket, and then */ + /* again just after the receive raj 3/95 */ + HIST_timestamp(&time_one); + } +#endif /* WANT_HISTOGRAM */ + +newport: + /* pick a new port number */ + myport++; + + /* wrap the port number when we get to client_port_max. NOTE, some */ + /* broken TCP's might treat the port number as a signed 16 bit */ + /* quantity. we aren't interested in testing such broken */ + /* implementations :) so we won't make sure that it is below 32767 */ + /* raj 8/94 */ + if (myport >= client_port_max) { + myport = client_port_min; + } + + /* we do not want to use the port number that the server is */ + /* sitting at - this would cause us to fail in a loopback test. we */ + /* could just rely on the failure of the bind to get us past this, */ + /* but I'm guessing that in this one case at least, it is much */ + /* faster, given that we *know* that port number is already in use */ + /* (or rather would be in a loopback test) */ + + if (myport == get_port_number(remote_res)) myport++; + + if (debug) { + if ((nummessages % 100) == 0) { + printf("port %d\n",myport); + } + } + + /* set up the data socket */ + set_port_number(local_res, (unsigned short)myport); + send_socket = create_data_socket(local_res); + + if (send_socket == INVALID_SOCKET) { + perror("netperf: send_tcp_conn_rr: tcp stream data socket"); + exit(1); + } + + + /* we used to call bind here, but that is now taken-care-of by the + create_data_socket routine. */ + + /* Connect up to the remote port on the data socket */ + if ((ret = connect(send_socket, + remote_res->ai_addr, + remote_res->ai_addrlen)) == INVALID_SOCKET){ + if (SOCKET_EINTR(ret)) + { + /* we hit the end of a */ + /* timed test. */ + timed_out = 1; + break; + } + if ((SOCKET_EADDRINUSE(ret)) || SOCKET_EADDRNOTAVAIL(ret)) { + /* likely something our explicit bind() would have caught in + the past, so go get another port, via create_data_socket. + yes, this is a bit more overhead than before, but the + condition should be rather rare. raj 2005-02-08 */ + close(send_socket); + goto newport; + } + perror("netperf: data socket connect failed"); + printf("\tattempted to connect on socket %d to port %d", + send_socket, + get_port_number(remote_res)); + printf(" from port %d \n",get_port_number(local_res)); + exit(1); + } + + + /* send the request */ + if((len=send(send_socket, + send_ring->buffer_ptr, + req_size, + 0)) != req_size) { + if (SOCKET_EINTR(len)) + { + /* we hit the end of a */ + /* timed test. */ + timed_out = 1; + break; + } + perror("send_tcp_conn_rr: data send error"); + exit(1); + } + send_ring = send_ring->next; + + /* receive the response */ + rsp_bytes_left = rsp_size; + temp_message_ptr = recv_ring->buffer_ptr; + + + do { + rsp_bytes_recvd = recv(send_socket, + temp_message_ptr, + rsp_bytes_left, + 0); + if (rsp_bytes_recvd > 0) { + rsp_bytes_left -= rsp_bytes_recvd; + temp_message_ptr += rsp_bytes_recvd; + } + else { + break; + } + } while (rsp_bytes_left); + + + /* OK, we are out of the loop - now what? */ + if (rsp_bytes_recvd < 0) { + /* did the timer hit, or was there an error? */ + if (SOCKET_EINTR(rsp_bytes_recvd)) + { + /* We hit the end of a timed test. */ + timed_out = 1; + break; + } + perror("send_tcp_conn_rr: data recv error"); + exit(1); + } + + /* if this is a no_control test, we initiate connection close, + otherwise the remote netserver does it to remain just like + previous behaviour. raj 2007-27-08 */ + if (!no_control) { + shutdown(send_socket,SHUT_WR); + } + + /* we are expecting to get either a return of zero indicating + connection close, or an error. */ + rsp_bytes_recvd = recv(send_socket, + temp_message_ptr, + 1, + 0); + + /* our exit from the while loop should generally be when */ + /* tmp_bytes_recvd is equal to zero, which implies the connection */ + /* has been closed by the server side. By waiting until we get the */ + /* zero return we can avoid race conditions that stick us with the */ + /* TIME_WAIT connection and not the server. raj 8/96 */ + +#ifdef VMWARE_UW + /* why this should be for VMware I'm not sure, but it was given as + part of the patches, so we include it here, but put it under an + ifdef VMWARE_UW. raj 2008-07-25 */ + if (sp_bytes_recvd < 0 && errno == ECONNRESET) { + rsp_bytes_recvd = 0; + } +#endif /* VMWARE_UW */ + + if (rsp_bytes_recvd == 0) { + /* connection close, call close. we assume that the requisite */ + /* number of bytes have been received */ + recv_ring = recv_ring->next; + +#ifdef WANT_HISTOGRAM + if (verbosity > 1) { + HIST_timestamp(&time_two); + HIST_add(time_hist,delta_micro(&time_one,&time_two)); + } +#endif /* WANT_HISTOGRAM */ + +#ifdef WANT_DEMO + DEMO_RR_INTERVAL(1) +#endif + + nummessages++; + if (trans_remaining) { + trans_remaining--; + } + + if (debug > 3) { + fprintf(where, + "Transaction %d completed on local port %d\n", + nummessages, + get_port_number(local_res)); + fflush(where); + } + + close(send_socket); + + } + else { + /* it was less than zero - an error occured */ + if (SOCKET_EINTR(rsp_bytes_recvd)) + { + /* We hit the end of a timed test. */ + timed_out = 1; + break; + } + perror("send_tcp_conn_rr: data recv error"); + exit(1); + } + + } + + + /* this call will always give us the elapsed time for the test, and */ + /* will also store-away the necessaries for cpu utilization */ + + cpu_stop(local_cpu_usage,&elapsed_time); /* was cpu being measured? */ + /* how long did we really run? */ + + if (!no_control) { + /* Get the statistics from the remote end. The remote will have + calculated service demand and all those interesting things. If + it wasn't supposed to care, it will return obvious values. */ + + recv_response(); + if (!netperf_response.content.serv_errno) { + if (debug) + fprintf(where,"remote results obtained\n"); + } + else { + Set_errno(netperf_response.content.serv_errno); + fprintf(where, + "netperf: remote error %d", + netperf_response.content.serv_errno); + perror(""); + fflush(where); + + exit(1); + } + } + + /* We now calculate what our thruput was for the test. In the future, */ + /* we may want to include a calculation of the thruput measured by */ + /* the remote, but it should be the case that for a TCP stream test, */ + /* that the two numbers should be *very* close... We calculate */ + /* bytes_sent regardless of the way the test length was controlled. */ + /* If it was time, we needed to, and if it was by bytes, the user may */ + /* have specified a number of bytes that wasn't a multiple of the */ + /* send_size, so we really didn't send what he asked for ;-) We use */ + /* Kbytes/s as the units of thruput for a TCP stream test, where K = */ + /* 1024. A future enhancement *might* be to choose from a couple of */ + /* unit selections. */ + + bytes_xferd = (req_size * nummessages) + (rsp_size * nummessages); + thruput = calc_thruput(bytes_xferd); + + if (local_cpu_usage || remote_cpu_usage) { + /* We must now do a little math for service demand and cpu */ + /* utilization for the system(s) */ + /* Of course, some of the information might be bogus because */ + /* there was no idle counter in the kernel(s). We need to make */ + /* a note of this for the user's benefit...*/ + if (local_cpu_usage) { + if (local_cpu_rate == 0.0) { + fprintf(where, + "WARNING WARNING WARNING WARNING WARNING WARNING WARNING!\n"); + fprintf(where, + "Local CPU usage numbers based on process information only!\n"); + fflush(where); + } + local_cpu_utilization = calc_cpu_util(0.0); + /* since calc_service demand is doing ms/Kunit we will */ + /* multiply the number of transaction by 1024 to get */ + /* "good" numbers */ + local_service_demand = calc_service_demand((double) nummessages*1024, + 0.0, + 0.0, + 0); + } + else { + local_cpu_utilization = (float) -1.0; + local_service_demand = (float) -1.0; + } + + if (remote_cpu_usage) { + if (remote_cpu_rate == 0.0) { + fprintf(where, + "DANGER DANGER DANGER DANGER DANGER DANGER DANGER!\n"); + fprintf(where, + "Remote CPU usage numbers based on process information only!\n"); + fflush(where); + } + remote_cpu_utilization = tcp_conn_rr_result->cpu_util; + /* since calc_service demand is doing ms/Kunit we will */ + /* multiply the number of transaction by 1024 to get */ + /* "good" numbers */ + remote_service_demand = calc_service_demand((double) nummessages*1024, + 0.0, + remote_cpu_utilization, + tcp_conn_rr_result->num_cpus); + } + else { + remote_cpu_utilization = (float) -1.0; + remote_service_demand = (float) -1.0; + } + + /* We are now ready to print all the information. If the user */ + /* has specified zero-level verbosity, we will just print the */ + /* local service demand, or the remote service demand. If the */ + /* user has requested verbosity level 1, he will get the basic */ + /* "streamperf" numbers. If the user has specified a verbosity */ + /* of greater than 1, we will display a veritable plethora of */ + /* background information from outside of this block as it it */ + /* not cpu_measurement specific... */ + + switch (verbosity) { + case 0: + if (local_cpu_usage) { + fprintf(where, + cpu_fmt_0, + local_service_demand); + } + else { + fprintf(where, + cpu_fmt_0, + remote_service_demand); + } + break; + case 1: + case 2: + + if (print_headers) { + fprintf(where, + cpu_title, + local_cpu_method, + remote_cpu_method); + } + + fprintf(where, + cpu_fmt_1_line_1, /* the format string */ + lss_size, /* local sendbuf size */ + lsr_size, + req_size, /* how large were the requests */ + rsp_size, /* guess */ + elapsed_time, /* how long was the test */ + nummessages/elapsed_time, + local_cpu_utilization, /* local cpu */ + remote_cpu_utilization, /* remote cpu */ + local_service_demand, /* local service demand */ + remote_service_demand); /* remote service demand */ + fprintf(where, + cpu_fmt_1_line_2, + rss_size, + rsr_size); + break; + } + } + else { + /* The tester did not wish to measure service demand. */ + switch (verbosity) { + case 0: + fprintf(where, + tput_fmt_0, + nummessages/elapsed_time); + break; + case 1: + case 2: + if (print_headers) { + fprintf(where,tput_title,format_units()); + } + + fprintf(where, + tput_fmt_1_line_1, /* the format string */ + lss_size, + lsr_size, + req_size, /* how large were the requests */ + rsp_size, /* how large were the responses */ + elapsed_time, /* how long did it take */ + nummessages/elapsed_time); + fprintf(where, + tput_fmt_1_line_2, + rss_size, /* remote recvbuf size */ + rsr_size); + + break; + } + } + + /* it would be a good thing to include information about some of the */ + /* other parameters that may have been set for this test, but at the */ + /* moment, I do not wish to figure-out all the formatting, so I will */ + /* just put this comment here to help remind me that it is something */ + /* that should be done at a later time. */ + + if (verbosity > 1) { + /* The user wanted to know it all, so we will give it to him. */ + /* This information will include as much as we can find about */ + /* TCP statistics, the alignments of the sends and receives */ + /* and all that sort of rot... */ + + fprintf(where, + ksink_fmt, + local_send_align, + remote_recv_offset, + local_send_offset, + remote_recv_offset); + +#ifdef WANT_HISTOGRAM + fprintf(where,"\nHistogram of request/response times\n"); + fflush(where); + HIST_report(time_hist); +#endif /* WANT_HISTOGRAM */ + + } + +} + + +void +recv_tcp_conn_rr() +{ + + char *message; + struct addrinfo *local_res; + char local_name[BUFSIZ]; + char port_buffer[PORTBUFSIZE]; + + struct sockaddr_storage myaddr_in, peeraddr_in; + SOCKET s_listen,s_data; + netperf_socklen_t addrlen; + char *recv_message_ptr; + char *send_message_ptr; + char *temp_message_ptr; + int trans_received; + int trans_remaining; + int bytes_sent; + int request_bytes_recvd; + int request_bytes_remaining; + int timed_out = 0; + float elapsed_time; + + struct tcp_conn_rr_request_struct *tcp_conn_rr_request; + struct tcp_conn_rr_response_struct *tcp_conn_rr_response; + struct tcp_conn_rr_results_struct *tcp_conn_rr_results; + + tcp_conn_rr_request = + (struct tcp_conn_rr_request_struct *)netperf_request.content.test_specific_data; + tcp_conn_rr_response = + (struct tcp_conn_rr_response_struct *)netperf_response.content.test_specific_data; + tcp_conn_rr_results = + (struct tcp_conn_rr_results_struct *)netperf_response.content.test_specific_data; + + if (debug) { + fprintf(where,"netserver: recv_tcp_conn_rr: entered...\n"); + fflush(where); + } + + /* We want to set-up the listen socket with all the desired */ + /* parameters and then let the initiator know that all is ready. If */ + /* socket size defaults are to be used, then the initiator will have */ + /* sent us 0's. If the socket sizes cannot be changed, then we will */ + /* send-back what they are. If that information cannot be determined, */ + /* then we send-back -1's for the sizes. If things go wrong for any */ + /* reason, we will drop back ten yards and punt. */ + + /* If anything goes wrong, we want the remote to know about it. It */ + /* would be best if the error that the remote reports to the user is */ + /* the actual error we encountered, rather than some bogus unexpected */ + /* response type message. */ + + if (debug) { + fprintf(where,"recv_tcp_conn_rr: setting the response type...\n"); + fflush(where); + } + + netperf_response.content.response_type = TCP_CRR_RESPONSE; + + if (debug) { + fprintf(where,"recv_tcp_conn_rr: the response type is set...\n"); + fflush(where); + } + + /* set-up the data buffer with the requested alignment and offset */ + message = (char *)malloc(DATABUFFERLEN); + if (message == NULL) { + printf("malloc(%d) failed!\n", DATABUFFERLEN); + exit(1); + } + + /* We now alter the message_ptr variables to be at the desired */ + /* alignments with the desired offsets. */ + + if (debug) { + fprintf(where, + "recv_tcp_conn_rr: requested recv alignment of %d offset %d\n", + tcp_conn_rr_request->recv_alignment, + tcp_conn_rr_request->recv_offset); + fprintf(where, + "recv_tcp_conn_rr: requested send alignment of %d offset %d\n", + tcp_conn_rr_request->send_alignment, + tcp_conn_rr_request->send_offset); + fflush(where); + } + + recv_message_ptr = ALIGN_BUFFER(message, tcp_conn_rr_request->recv_alignment, tcp_conn_rr_request->recv_offset); + + send_message_ptr = ALIGN_BUFFER(message, tcp_conn_rr_request->send_alignment, tcp_conn_rr_request->send_offset); + + if (debug) { + fprintf(where,"recv_tcp_conn_rr: receive alignment and offset set...\n"); + fflush(where); + } + + /* Grab a socket to listen on, and then listen on it. */ + + if (debug) { + fprintf(where,"recv_tcp_conn_rr: grabbing a socket...\n"); + fflush(where); + } + + /* create_data_socket expects to find some things in the global */ + /* variables, so set the globals based on the values in the request. */ + /* once the socket has been created, we will set the response values */ + /* based on the updated value of those globals. raj 7/94 */ + lss_size_req = tcp_conn_rr_request->send_buf_size; + lsr_size_req = tcp_conn_rr_request->recv_buf_size; + loc_nodelay = tcp_conn_rr_request->no_delay; + loc_rcvavoid = tcp_conn_rr_request->so_rcvavoid; + loc_sndavoid = tcp_conn_rr_request->so_sndavoid; + + set_hostname_and_port(local_name, + port_buffer, + nf_to_af(tcp_conn_rr_request->ipfamily), + tcp_conn_rr_request->port); + + local_res = complete_addrinfo(local_name, + local_name, + port_buffer, + nf_to_af(tcp_conn_rr_request->ipfamily), + SOCK_STREAM, + IPPROTO_TCP, + 0); + + s_listen = create_data_socket(local_res); + + if (s_listen == INVALID_SOCKET) { + netperf_response.content.serv_errno = errno; + send_response(); + if (debug) { + fprintf(where,"could not create data socket\n"); + fflush(where); + } + exit(1); + } + +#ifdef WIN32 + /* The test timer can fire during operations on the listening socket, + so to make the start_timer below work we have to move + it to close s_listen while we are blocked on accept. */ + win_kludge_socket2 = s_listen; +#endif + + + /* Now, let's set-up the socket to listen for connections */ + if (listen(s_listen, 5) == SOCKET_ERROR) { + netperf_response.content.serv_errno = errno; + close(s_listen); + send_response(); + if (debug) { + fprintf(where,"could not listen\n"); + fflush(where); + } + exit(1); + } + + /* now get the port number assigned by the system */ + addrlen = sizeof(myaddr_in); + if (getsockname(s_listen, + (struct sockaddr *)&myaddr_in, + &addrlen) == SOCKET_ERROR){ + netperf_response.content.serv_errno = errno; + close(s_listen); + send_response(); + if (debug) { + fprintf(where,"could not getsockname\n"); + fflush(where); + } + exit(1); + } + + /* Now myaddr_in contains the port and the internet address this is */ + /* returned to the sender also implicitly telling the sender that the */ + /* socket buffer sizing has been done. */ + + tcp_conn_rr_response->data_port_number = + (int) ntohs(((struct sockaddr_in *)&myaddr_in)->sin_port); + if (debug) { + fprintf(where,"telling the remote to call me at %d\n", + tcp_conn_rr_response->data_port_number); + fflush(where); + } + netperf_response.content.serv_errno = 0; + + /* But wait, there's more. If the initiator wanted cpu measurements, */ + /* then we must call the calibrate routine, which will return the max */ + /* rate back to the initiator. If the CPU was not to be measured, or */ + /* something went wrong with the calibration, we will return a 0.0 to */ + /* the initiator. */ + + tcp_conn_rr_response->cpu_rate = (float)0.0; /* assume no cpu */ + if (tcp_conn_rr_request->measure_cpu) { + tcp_conn_rr_response->measure_cpu = 1; + tcp_conn_rr_response->cpu_rate = + calibrate_local_cpu(tcp_conn_rr_request->cpu_rate); + } + + + + /* before we send the response back to the initiator, pull some of */ + /* the socket parms from the globals */ + tcp_conn_rr_response->send_buf_size = lss_size; + tcp_conn_rr_response->recv_buf_size = lsr_size; + tcp_conn_rr_response->no_delay = loc_nodelay; + tcp_conn_rr_response->so_rcvavoid = loc_rcvavoid; + tcp_conn_rr_response->so_sndavoid = loc_sndavoid; + + send_response(); + + addrlen = sizeof(peeraddr_in); + + /* Now it's time to start receiving data on the connection. We will */ + /* first grab the apropriate counters and then start grabbing. */ + + cpu_start(tcp_conn_rr_request->measure_cpu); + + /* The loop will exit when the sender does a shutdown, which will */ + /* return a length of zero */ + + if (tcp_conn_rr_request->test_length > 0) { + times_up = 0; + trans_remaining = 0; + start_timer(tcp_conn_rr_request->test_length + PAD_TIME); + } + else { + times_up = 1; + trans_remaining = tcp_conn_rr_request->test_length * -1; + } + + trans_received = 0; + + while ((!times_up) || (trans_remaining > 0)) { + + /* accept a connection from the remote */ +#ifdef WIN32 + /* The test timer will probably fire during this accept, + so to make the start_timer above work we have to move + it to close s_listen while we are blocked on accept. */ + win_kludge_socket = s_listen; +#endif + if ((s_data=accept(s_listen, + (struct sockaddr *)&peeraddr_in, + &addrlen)) == INVALID_SOCKET) { + if (errno == EINTR) { + /* the timer popped */ + timed_out = 1; + break; + } + fprintf(where,"recv_tcp_conn_rr: accept: errno = %d\n",errno); + fflush(where); + close(s_listen); + + exit(1); + } + + if (debug) { + fprintf(where,"recv_tcp_conn_rr: accepted data connection.\n"); + fflush(where); + } + +#ifdef WIN32 + /* this is used so the timer thread can close the socket out from */ + /* under us, which to date is the easiest/cleanest/least */ + /* Windows-specific way I can find to force the winsock calls to */ + /* return WSAEINTR with the test is over. anything that will run on */ + /* 95 and NT and is closer to what netperf expects from Unix signals */ + /* and such would be appreciated raj 1/96 */ + win_kludge_socket = s_data; +#endif /* WIN32 */ + +#ifdef KLUDGE_SOCKET_OPTIONS + /* this is for those systems which *INCORRECTLY* fail to pass */ + /* attributes across an accept() call. Including this goes against */ + /* my better judgement :( raj 11/95 */ + + kludge_socket_options(s_data); + +#endif /* KLUDGE_SOCKET_OPTIONS */ + + temp_message_ptr = recv_message_ptr; + request_bytes_remaining = tcp_conn_rr_request->request_size; + + /* receive the request from the other side */ + while (!times_up && (request_bytes_remaining > 0)) { + if((request_bytes_recvd=recv(s_data, + temp_message_ptr, + request_bytes_remaining, + 0)) == SOCKET_ERROR) { + if (SOCKET_EINTR(request_bytes_recvd)) + { + /* the timer popped */ + timed_out = 1; + break; + } + netperf_response.content.serv_errno = errno; + send_response(); + exit(1); + } + else { + request_bytes_remaining -= request_bytes_recvd; + temp_message_ptr += request_bytes_recvd; + } + } + + if (timed_out) { + /* we hit the end of the test based on time - lets */ + /* bail out of here now... */ + fprintf(where,"yo5\n"); + fflush(where); + break; + } + + /* Now, send the response to the remote */ + if((bytes_sent=send(s_data, + send_message_ptr, + tcp_conn_rr_request->response_size, + 0)) == SOCKET_ERROR) { + if (errno == EINTR) { + /* the test timer has popped */ + timed_out = 1; + fprintf(where,"yo6\n"); + fflush(where); + break; + } + netperf_response.content.serv_errno = 99; + send_response(); + exit(1); + } + + trans_received++; + if (trans_remaining) { + trans_remaining--; + } + + if (debug) { + fprintf(where, + "recv_tcp_conn_rr: Transaction %d complete\n", + trans_received); + fflush(where); + } + + /* close the connection. the server will likely do a graceful */ + /* close of the connection, insuring that all data has arrived at */ + /* the client. for this it will call shutdown(), and then recv() and */ + /* then close(). I'm reasonably confident that this is the */ + /* appropriate sequence of calls - I would like to hear of */ + /* examples in web servers to the contrary. raj 10/95*/ +#ifdef TCP_CRR_SHUTDOWN + shutdown(s_data,SHUT_WR); + recv(s_data, + recv_message_ptr, + 1, + 0); + close(s_data); +#else + close(s_data); +#endif /* TCP_CRR_SHUTDOWN */ + + } + + + /* The loop now exits due to timeout or transaction count being */ + /* reached */ + + cpu_stop(tcp_conn_rr_request->measure_cpu,&elapsed_time); + + if (timed_out) { + /* we ended the test by time, which was at least 2 seconds */ + /* longer than we wanted to run. so, we want to subtract */ + /* PAD_TIME from the elapsed_time. */ + elapsed_time -= PAD_TIME; + } + /* send the results to the sender */ + + if (debug) { + fprintf(where, + "recv_tcp_conn_rr: got %d transactions\n", + trans_received); + fflush(where); + } + + tcp_conn_rr_results->bytes_received = (trans_received * + (tcp_conn_rr_request->request_size + + tcp_conn_rr_request->response_size)); + tcp_conn_rr_results->trans_received = trans_received; + tcp_conn_rr_results->elapsed_time = elapsed_time; + if (tcp_conn_rr_request->measure_cpu) { + tcp_conn_rr_results->cpu_util = calc_cpu_util(elapsed_time); + } + + if (debug) { + fprintf(where, + "recv_tcp_conn_rr: test complete, sending results.\n"); + fflush(where); + } + + send_response(); + +} + + +#ifdef DO_1644 + + /* this test is intended to test the performance of establishing a */ + /* connection, exchanging a request/response pair, and repeating. it */ + /* is expected that this would be a good starting-point for */ + /* comparision of T/TCP with classic TCP for transactional workloads. */ + /* it will also look (can look) much like the communication pattern */ + /* of http for www access. */ + +int +send_tcp_tran_rr(char remote_host[]) +{ + + char *tput_title = "\ +Local /Remote\n\ +Socket Size Request Resp. Elapsed Trans.\n\ +Send Recv Size Size Time Rate \n\ +bytes Bytes bytes bytes secs. per sec \n\n"; + + char *tput_fmt_0 = + "%7.2f\n"; + + char *tput_fmt_1_line_1 = "\ +%-6d %-6d %-6d %-6d %-6.2f %7.2f \n"; + char *tput_fmt_1_line_2 = "\ +%-6d %-6d\n"; + + char *cpu_title = "\ +Local /Remote\n\ +Socket Size Request Resp. Elapsed Trans. CPU CPU S.dem S.dem\n\ +Send Recv Size Size Time Rate local remote local remote\n\ +bytes bytes bytes bytes secs. per sec %% %% us/Tr us/Tr\n\n"; + + char *cpu_fmt_0 = + "%6.3f\n"; + + char *cpu_fmt_1_line_1 = "\ +%-6d %-6d %-6d %-6d %-6.2f %-6.2f %-6.2f %-6.2f %-6.3f %-6.3f\n"; + + char *cpu_fmt_1_line_2 = "\ +%-6d %-6d\n"; + + char *ksink_fmt = "\n\ +Alignment Offset\n\ +Local Remote Local Remote\n\ +Send Recv Send Recv\n\ +%5d %5d %5d %5d\n"; + + + int one = 1; + int timed_out = 0; + float elapsed_time; + + int len; + struct ring_elt *send_ring; + struct ring_elt *recv_ring; + char *temp_message_ptr; + int nummessages; + SOCKET send_socket; + int trans_remaining; + double bytes_xferd; + int sock_opt_len = sizeof(int); + int rsp_bytes_left; + int rsp_bytes_recvd; + + float local_cpu_utilization; + float local_service_demand; + float remote_cpu_utilization; + float remote_service_demand; + double thruput; + + struct hostent *hp; + struct sockaddr_in server; + struct sockaddr_in *myaddr; + unsigned int addr; + int myport; + + struct tcp_tran_rr_request_struct *tcp_tran_rr_request; + struct tcp_tran_rr_response_struct *tcp_tran_rr_response; + struct tcp_tran_rr_results_struct *tcp_tran_rr_result; + + tcp_tran_rr_request = + (struct tcp_tran_rr_request_struct *)netperf_request.content.test_specific_data; + tcp_tran_rr_response = + (struct tcp_tran_rr_response_struct *)netperf_response.content.test_specific_data; + tcp_tran_rr_result = + (struct tcp_tran_rr_results_struct *)netperf_response.content.test_specific_data; + + +#ifdef WANT_HISTOGRAM + if (verbosity > 1) { + time_hist = HIST_new(); + } +#endif /* WANT_HISTOGRAM */ + + /* since we are now disconnected from the code that established the */ + /* control socket, and since we want to be able to use different */ + /* protocols and such, we are passed the name of the remote host and */ + /* must turn that into the test specific addressing information. */ + + myaddr = (struct sockaddr_storage *)malloc(sizeof(struct sockaddr_storage)); + if (myaddr == NULL) { + printf("malloc(%d) failed!\n", sizeof(struct sockaddr_storage)); + exit(1); + } + + bzero((char *)&server, + sizeof(server)); + bzero((char *)myaddr, + sizeof(struct sockaddr_storage)); + myaddr->sin_family = AF_INET; + + complete_addrinfos(&remote_res, + &local_res, + remote_host, + SOCK_STREAM, + IPPROTO_TCP, + 0); + + if ( print_headers ) { + print_top_test_header("TCP Transactional/Request/Response TEST",local_res,remote_res); + } + + /* initialize a few counters */ + + nummessages = 0; + bytes_xferd = 0.0; + times_up = 0; + + /* set-up the data buffers with the requested alignment and offset */ + if (send_width == 0) send_width = 1; + if (recv_width == 0) recv_width = 1; + + send_ring = allocate_buffer_ring(send_width, + req_size, + local_send_align, + local_send_offset); + + recv_ring = allocate_buffer_ring(recv_width, + rsp_size, + local_recv_align, + local_recv_offset); + + + if (debug) { + fprintf(where,"send_tcp_tran_rr: send_socket obtained...\n"); + } + + /* If the user has requested cpu utilization measurements, we must */ + /* calibrate the cpu(s). We will perform this task within the tests */ + /* themselves. If the user has specified the cpu rate, then */ + /* calibrate_local_cpu will return rather quickly as it will have */ + /* nothing to do. If local_cpu_rate is zero, then we will go through */ + /* all the "normal" calibration stuff and return the rate back.*/ + + if (local_cpu_usage) { + local_cpu_rate = calibrate_local_cpu(local_cpu_rate); + } + + /* Tell the remote end to do a listen. The server alters the socket */ + /* paramters on the other side at this point, hence the reason for */ + /* all the values being passed in the setup message. If the user did */ + /* not specify any of the parameters, they will be passed as 0, which */ + /* will indicate to the remote that no changes beyond the system's */ + /* default should be used. Alignment is the exception, it will */ + /* default to 8, which will be no alignment alterations. */ + + netperf_request.content.request_type = DO_TCP_TRR; + tcp_tran_rr_request->recv_buf_size = rsr_size_req; + tcp_tran_rr_request->send_buf_size = rss_size_req; + tcp_tran_rr_request->recv_alignment = remote_recv_align; + tcp_tran_rr_request->recv_offset = remote_recv_offset; + tcp_tran_rr_request->send_alignment = remote_send_align; + tcp_tran_rr_request->send_offset = remote_send_offset; + tcp_tran_rr_request->request_size = req_size; + tcp_tran_rr_request->response_size = rsp_size; + tcp_tran_rr_request->no_delay = rem_nodelay; + tcp_tran_rr_request->measure_cpu = remote_cpu_usage; + tcp_tran_rr_request->cpu_rate = remote_cpu_rate; + tcp_tran_rr_request->so_rcvavoid = rem_rcvavoid; + tcp_tran_rr_request->so_sndavoid = rem_sndavoid; + if (test_time) { + tcp_tran_rr_request->test_length = test_time; + } + else { + tcp_tran_rr_request->test_length = test_trans * -1; + } + tcp_tran_rr_request->port = atoi(remote_data_port); + tcp_tran_rr_request->ipfamily = af_to_nf(remote_res->ai_family); + + if (debug > 1) { + fprintf(where,"netperf: send_tcp_tran_rr: requesting TCP_TRR test\n"); + } + + send_request(); + + /* The response from the remote will contain all of the relevant */ + /* socket parameters for this test type. We will put them back into */ + /* the variables here so they can be displayed if desired. The */ + /* remote will have calibrated CPU if necessary, and will have done */ + /* all the needed set-up we will have calibrated the cpu locally */ + /* before sending the request, and will grab the counter value right */ + /* after the connect returns. The remote will grab the counter right */ + /* after the accept call. This saves the hassle of extra messages */ + /* being sent for the TCP tests. */ + + recv_response(); + + if (!netperf_response.content.serv_errno) { + rsr_size = tcp_tran_rr_response->recv_buf_size; + rss_size = tcp_tran_rr_response->send_buf_size; + rem_nodelay = tcp_tran_rr_response->no_delay; + remote_cpu_usage= tcp_tran_rr_response->measure_cpu; + remote_cpu_rate = tcp_tran_rr_response->cpu_rate; + /* make sure that port numbers are in network order */ + server.sin_port = tcp_tran_rr_response->data_port_number; + server.sin_port = htons(server.sin_port); + if (debug) { + fprintf(where,"remote listen done.\n"); + fprintf(where,"remote port is %d\n",ntohs(server.sin_port)); + fflush(where); + } + } + else { + Set_errno(netperf_response.content.serv_errno); + fprintf(where, + "netperf: remote error %d", + netperf_response.content.serv_errno); + perror(""); + fflush(where); + exit(1); + } + + /* pick a nice random spot between client_port_min and */ + /* client_port_max for our initial port number. if they are the */ + /* same, then just set to _min */ + if (client_port_max - client_port_min) { + srand(getpid()); + myport = client_port_min + + (rand() % (client_port_max - client_port_min)); + } + else { + myport = client_port_min; + } + + /* there will be a ++ before the first call to bind, so subtract one */ + myport--; + myaddr->sin_port = htons((unsigned short)myport); + + /* Set-up the test end conditions. For a request/response test, they */ + /* can be either time or transaction based. */ + + if (test_time) { + /* The user wanted to end the test after a period of time. */ + times_up = 0; + trans_remaining = 0; + start_timer(test_time); + } + else { + /* The tester wanted to send a number of bytes. */ + trans_remaining = test_bytes; + times_up = 1; + } + + /* The cpu_start routine will grab the current time and possibly */ + /* value of the idle counter for later use in measuring cpu */ + /* utilization and/or service demand and thruput. */ + + cpu_start(local_cpu_usage); + + /* We use an "OR" to control test execution. When the test is */ + /* controlled by time, the byte count check will always return false. */ + /* When the test is controlled by byte count, the time test will */ + /* always return false. When the test is finished, the whole */ + /* expression will go false and we will stop sending data. I think I */ + /* just arbitrarily decrement trans_remaining for the timed test, but */ + /* will not do that just yet... One other question is whether or not */ + /* the send buffer and the receive buffer should be the same buffer. */ + + while ((!times_up) || (trans_remaining > 0)) { + +#ifdef WANT_HISTOGRAM + if (verbosity > 1) { + /* timestamp just before our call to create the socket, and then */ + /* again just after the receive raj 3/95 */ + HIST_timestamp(&time_one); + } +#endif /* WANT_HISTOGRAM */ + + /* set up the data socket - is this really necessary or can I just */ + /* re-use the same socket and move this cal out of the while loop. */ + /* it does introcudea *boatload* of system calls. I guess that it */ + /* all depends on "reality of programming." keeping it this way is */ + /* a bit more conservative I imagine - raj 3/95 */ + send_socket = create_data_socket(local_res); + + if (send_socket == INVALID_SOCKET) { + perror("netperf: send_tcp_tran_rr: tcp stream data socket"); + exit(1); + } + + /* we set SO_REUSEADDR on the premis that no unreserved port */ + /* number on the local system is going to be already connected to */ + /* the remote netserver's port number. One thing that I might */ + /* try later is to have the remote actually allocate a couple of */ + /* port numbers and cycle through those as well. depends on if we */ + /* can get through all the unreserved port numbers in less than */ + /* the length of the TIME_WAIT state raj 8/94 */ + one = 1; + if(setsockopt(send_socket, SOL_SOCKET, SO_REUSEADDR, + (char *)&one, sock_opt_len) == SOCKET_ERROR) { + perror("netperf: send_tcp_tran_rr: so_reuseaddr"); + exit(1); + } + +newport: + /* pick a new port number */ + myport = ntohs(myaddr->sin_port); + myport++; + + /* we do not want to use the port number that the server is */ + /* sitting at - this would cause us to fail in a loopback test. we */ + /* could just rely on the failure of the bind to get us past this, */ + /* but I'm guessing that in this one case at least, it is much */ + /* faster, given that we *know* that port number is already in use */ + /* (or rather would be in a loopback test) */ + + if (myport == ntohs(server.sin_port)) myport++; + + /* wrap the port number when we get to 65535. NOTE, some broken */ + /* TCP's might treat the port number as a signed 16 bit quantity. */ + /* we aren't interested in testing such broken implementations :) */ + /* raj 8/94 */ + if (myport >= client_port_max) { + myport = client_port_min; + } + myaddr->sin_port = htons((unsigned short)myport); + + if (debug) { + if ((nummessages % 100) == 0) { + printf("port %d\n",myport); + } + } + + /* we want to bind our socket to a particular port number. */ + if (bind(send_socket, + (struct sockaddr *)myaddr, + sizeof(struct sockaddr_storage)) == SOCKET_ERROR) { + /* if the bind failed, someone else must have that port number */ + /* - perhaps in the listen state. since we can't use it, skip to */ + /* the next port number. we may have to do this again later, but */ + /* that's just too bad :) */ + if (debug > 1) { + fprintf(where, + "send_tcp_tran_rr: tried to bind to port %d errno %d\n", + ntohs(myaddr->sin_port), + errno); + fflush(where); + } + /* yes, goto's are supposed to be evil, but they do have their */ + /* uses from time to time. the real world doesn't always have */ + /* to code to ge tthe A in CS 101 :) raj 3/95 */ + goto newport; + } + + /* Connect up to the remote port on the data socket. Since this is */ + /* a test for RFC_1644-style transactional TCP, we can use the */ + /* sendto() call instead of calling connect and then send() */ + + /* send the request */ + if((len=sendto(send_socket, + send_ring->buffer_ptr, + req_size, + MSG_EOF, + (struct sockaddr *)&server, + sizeof(server))) != req_size) { + if (SOCKET_EINTR(len)) + { + /* we hit the end of a */ + /* timed test. */ + timed_out = 1; + break; + } + perror("send_tcp_tran_rr: data send error"); + exit(1); + } + send_ring = send_ring->next; + + /* receive the response */ + rsp_bytes_left = rsp_size; + temp_message_ptr = recv_ring->buffer_ptr; + while(rsp_bytes_left > 0) { + if((rsp_bytes_recvd=recv(send_socket, + temp_message_ptr, + rsp_bytes_left, + 0)) == SOCKET_ERROR) { + if (SOCKET_EINTR(rsp_bytes_recvd)) + { + /* We hit the end of a timed test. */ + timed_out = 1; + break; + } + perror("send_tcp_tran_rr: data recv error"); + exit(1); + } + rsp_bytes_left -= rsp_bytes_recvd; + temp_message_ptr += rsp_bytes_recvd; + } + recv_ring = recv_ring->next; + + if (timed_out) { + /* we may have been in a nested while loop - we need */ + /* another call to break. */ + break; + } + + close(send_socket); + +#ifdef WANT_HISTOGRAM + if (verbosity > 1) { + HIST_timestamp(&time_two); + HIST_add(time_hist,delta_micro(&time_one,&time_two)); + } +#endif /* WANT_HISTOGRAM */ + + nummessages++; + if (trans_remaining) { + trans_remaining--; + } + + if (debug > 3) { + fprintf(where, + "Transaction %d completed on local port %d\n", + nummessages, + ntohs(myaddr->sin_port)); + fflush(where); + } + + + } + + /* this call will always give us the elapsed time for the test, and */ + /* will also store-away the necessaries for cpu utilization */ + + cpu_stop(local_cpu_usage,&elapsed_time); /* was cpu being measured? */ + /* how long did we really run? */ + + /* Get the statistics from the remote end. The remote will have */ + /* calculated service demand and all those interesting things. If it */ + /* wasn't supposed to care, it will return obvious values. */ + + recv_response(); + if (!netperf_response.content.serv_errno) { + if (debug) + fprintf(where,"remote results obtained\n"); + } + else { + Set_errno(netperf_response.content.serv_errno); + fprintf(where, + "netperf: remote error %d", + netperf_response.content.serv_errno); + perror(""); + fflush(where); + exit(1); + } + + /* We now calculate what our thruput was for the test. In the future, */ + /* we may want to include a calculation of the thruput measured by */ + /* the remote, but it should be the case that for a TCP stream test, */ + /* that the two numbers should be *very* close... We calculate */ + /* bytes_sent regardless of the way the test length was controlled. */ + /* If it was time, we needed to, and if it was by bytes, the user may */ + /* have specified a number of bytes that wasn't a multiple of the */ + /* send_size, so we really didn't send what he asked for ;-) We use */ + /* Kbytes/s as the units of thruput for a TCP stream test, where K = */ + /* 1024. A future enhancement *might* be to choose from a couple of */ + /* unit selections. */ + + bytes_xferd = (req_size * nummessages) + (rsp_size * nummessages); + thruput = calc_thruput(bytes_xferd); + + if (local_cpu_usage || remote_cpu_usage) { + /* We must now do a little math for service demand and cpu */ + /* utilization for the system(s) */ + /* Of course, some of the information might be bogus because */ + /* there was no idle counter in the kernel(s). We need to make */ + /* a note of this for the user's benefit...*/ + if (local_cpu_usage) { + if (local_cpu_rate == 0.0) { + fprintf(where,"WARNING WARNING WARNING WARNING WARNING WARNING WARNING!\n"); + fprintf(where,"Local CPU usage numbers based on process information only!\n"); + fflush(where); + } + local_cpu_utilization = calc_cpu_util(0.0); + /* since calc_service demand is doing ms/Kunit we will */ + /* multiply the number of transaction by 1024 to get */ + /* "good" numbers */ + local_service_demand = calc_service_demand((double) nummessages*1024, + 0.0, + 0.0, + 0); + } + else { + local_cpu_utilization = (float) -1.0; + local_service_demand = (float) -1.0; + } + + if (remote_cpu_usage) { + if (remote_cpu_rate == 0.0) { + fprintf(where,"DANGER DANGER DANGER DANGER DANGER DANGER DANGER!\n"); + fprintf(where,"Remote CPU usage numbers based on process information only!\n"); + fflush(where); + } + remote_cpu_utilization = tcp_tran_rr_result->cpu_util; + /* since calc_service demand is doing ms/Kunit we will */ + /* multiply the number of transaction by 1024 to get */ + /* "good" numbers */ + remote_service_demand = calc_service_demand((double) nummessages*1024, + 0.0, + remote_cpu_utilization, + tcp_tran_rr_result->num_cpus); + } + else { + remote_cpu_utilization = (float) -1.0; + remote_service_demand = (float) -1.0; + } + + /* We are now ready to print all the information. If the user */ + /* has specified zero-level verbosity, we will just print the */ + /* local service demand, or the remote service demand. If the */ + /* user has requested verbosity level 1, he will get the basic */ + /* "streamperf" numbers. If the user has specified a verbosity */ + /* of greater than 1, we will display a veritable plethora of */ + /* background information from outside of this block as it it */ + /* not cpu_measurement specific... */ + + switch (verbosity) { + case 0: + if (local_cpu_usage) { + fprintf(where, + cpu_fmt_0, + local_service_demand); + } + else { + fprintf(where, + cpu_fmt_0, + remote_service_demand); + } + break; + case 1: + case 2: + + if (print_headers) { + fprintf(where, + cpu_title, + local_cpu_method, + remote_cpu_method); + } + + fprintf(where, + cpu_fmt_1_line_1, /* the format string */ + lss_size, /* local sendbuf size */ + lsr_size, + req_size, /* how large were the requests */ + rsp_size, /* guess */ + elapsed_time, /* how long was the test */ + nummessages/elapsed_time, + local_cpu_utilization, /* local cpu */ + remote_cpu_utilization, /* remote cpu */ + local_service_demand, /* local service demand */ + remote_service_demand); /* remote service demand */ + fprintf(where, + cpu_fmt_1_line_2, + rss_size, + rsr_size); + break; + } + } + else { + /* The tester did not wish to measure service demand. */ + switch (verbosity) { + case 0: + fprintf(where, + tput_fmt_0, + nummessages/elapsed_time); + break; + case 1: + case 2: + if (print_headers) { + fprintf(where,tput_title,format_units()); + } + + fprintf(where, + tput_fmt_1_line_1, /* the format string */ + lss_size, + lsr_size, + req_size, /* how large were the requests */ + rsp_size, /* how large were the responses */ + elapsed_time, /* how long did it take */ + nummessages/elapsed_time); + fprintf(where, + tput_fmt_1_line_2, + rss_size, /* remote recvbuf size */ + rsr_size); + + break; + } + } + + /* it would be a good thing to include information about some of the */ + /* other parameters that may have been set for this test, but at the */ + /* moment, I do not wish to figure-out all the formatting, so I will */ + /* just put this comment here to help remind me that it is something */ + /* that should be done at a later time. */ + + if (verbosity > 1) { + /* The user wanted to know it all, so we will give it to him. */ + /* This information will include as much as we can find about */ + /* TCP statistics, the alignments of the sends and receives */ + /* and all that sort of rot... */ + + fprintf(where, + ksink_fmt, + local_send_align, + remote_recv_offset, + local_send_offset, + remote_recv_offset); + +#ifdef WANT_HISTOGRAM + fprintf(where,"\nHistogram of request/response times\n"); + fflush(where); + HIST_report(time_hist); +#endif /* WANT_HISTOGRAM */ + + } + +} + + +int +recv_tcp_tran_rr() +{ + + char *message; + struct sockaddr_in myaddr_in, + peeraddr_in; + SOCKET s_listen,s_data; + netperf_socklen_t addrlen; + int NoPush = 1; + + char *recv_message_ptr; + char *send_message_ptr; + char *temp_message_ptr; + int trans_received; + int trans_remaining; + int bytes_sent; + int request_bytes_recvd; + int request_bytes_remaining; + int timed_out = 0; + float elapsed_time; + + struct tcp_tran_rr_request_struct *tcp_tran_rr_request; + struct tcp_tran_rr_response_struct *tcp_tran_rr_response; + struct tcp_tran_rr_results_struct *tcp_tran_rr_results; + + tcp_tran_rr_request = + (struct tcp_tran_rr_request_struct *)netperf_request.content.test_specific_data; + tcp_tran_rr_response = + (struct tcp_tran_rr_response_struct *)netperf_response.content.test_specific_data; + tcp_tran_rr_results = + (struct tcp_tran_rr_results_struct *)netperf_response.content.test_specific_data; + + if (debug) { + fprintf(where,"netserver: recv_tcp_tran_rr: entered...\n"); + fflush(where); + } + + /* We want to set-up the listen socket with all the desired */ + /* parameters and then let the initiator know that all is ready. If */ + /* socket size defaults are to be used, then the initiator will have */ + /* sent us 0's. If the socket sizes cannot be changed, then we will */ + /* send-back what they are. If that information cannot be determined, */ + /* then we send-back -1's for the sizes. If things go wrong for any */ + /* reason, we will drop back ten yards and punt. */ + + /* If anything goes wrong, we want the remote to know about it. It */ + /* would be best if the error that the remote reports to the user is */ + /* the actual error we encountered, rather than some bogus unexpected */ + /* response type message. */ + + if (debug) { + fprintf(where,"recv_tcp_tran_rr: setting the response type...\n"); + fflush(where); + } + + netperf_response.content.response_type = TCP_TRR_RESPONSE; + + if (debug) { + fprintf(where,"recv_tcp_tran_rr: the response type is set...\n"); + fflush(where); + } + + /* set-up the data buffer with the requested alignment and offset */ + message = (char *)malloc(DATABUFFERLEN); + if (message == NULL) { + printf("malloc(%d) failed!\n", DATABUFFERLEN); + exit(1); + } + + /* We now alter the message_ptr variables to be at the desired */ + /* alignments with the desired offsets. */ + + if (debug) { + fprintf(where, + "recv_tcp_tran_rr: requested recv alignment of %d offset %d\n", + tcp_tran_rr_request->recv_alignment, + tcp_tran_rr_request->recv_offset); + fprintf(where, + "recv_tcp_tran_rr: requested send alignment of %d offset %d\n", + tcp_tran_rr_request->send_alignment, + tcp_tran_rr_request->send_offset); + fflush(where); + } + + recv_message_ptr = ALIGN_BUFFER(message, tcp_tran_rr_request->recv_alignment, tcp_tran_rr_request->recv_offset); + + send_message_ptr = ALIGN_BUFFER(message, tcp_tran_rr_request->send_alignment, tcp_tran_rr_request->send_offset); + + if (debug) { + fprintf(where,"recv_tcp_tran_rr: receive alignment and offset set...\n"); + fflush(where); + } + + /* Let's clear-out our sockaddr for the sake of cleanlines. Then we */ + /* can put in OUR values !-) At some point, we may want to nail this */ + /* socket to a particular network-level address, but for now, */ + /* INADDR_ANY should be just fine. */ + + bzero((char *)&myaddr_in, + sizeof(myaddr_in)); + myaddr_in.sin_family = AF_INET; + myaddr_in.sin_addr.s_addr = INADDR_ANY; + myaddr_in.sin_port = htons((unsigned short)tcp_tran_rr_request->port); + + /* Grab a socket to listen on, and then listen on it. */ + + if (debug) { + fprintf(where,"recv_tcp_tran_rr: grabbing a socket...\n"); + fflush(where); + } + + /* create_data_socket expects to find some things in the global */ + /* variables, so set the globals based on the values in the request. */ + /* once the socket has been created, we will set the response values */ + /* based on the updated value of those globals. raj 7/94 */ + lss_size_req = tcp_tran_rr_request->send_buf_size; + lsr_size_req = tcp_tran_rr_request->recv_buf_size; + loc_nodelay = tcp_tran_rr_request->no_delay; + loc_rcvavoid = tcp_tran_rr_request->so_rcvavoid; + loc_sndavoid = tcp_tran_rr_request->so_sndavoid; + + set_hostname_and_port(local_name, + port_buffer, + nf_to_af(tcp_tran_rr_request->ipfamily), + tcp_tran_rr_request->port); + + local_res = complete_addrinfo(local_name, + local_name, + port_buffer, + nf_to_af(tcp_tran_rr_request->ipfamily), + SOCK_STREAM, + IPPROTO_TCP, + 0); + + s_listen = create_data_socket(local_res); + + if (s_listen == INVALID_SOCKET) { + netperf_response.content.serv_errno = errno; + send_response(); + if (debug) { + fprintf(where,"could not create data socket\n"); + fflush(where); + } + exit(1); + } + +#ifdef WIN32 + /* The test timer can fire during operations on the listening socket, + so to make the start_timer below work we have to move + it to close s_listen while we are blocked on accept. */ + win_kludge_socket2 = s_listen; +#endif + + + /* Let's get an address assigned to this socket so we can tell the */ + /* initiator how to reach the data socket. There may be a desire to */ + /* nail this socket to a specific IP address in a multi-homed, */ + /* multi-connection situation, but for now, we'll ignore the issue */ + /* and concentrate on single connection testing. */ + + if (bind(s_listen, + (struct sockaddr *)&myaddr_in, + sizeof(myaddr_in)) == SOCKET_ERROR) { + netperf_response.content.serv_errno = errno; + close(s_listen); + send_response(); + if (debug) { + fprintf(where,"could not bind\n"); + fflush(where); + } + exit(1); + } + + /* we want to disable the implicit PUSH on all sends. at some point, */ + /* this might want to be a parm to the test raj 3/95 */ + if (setsockopt(s_listen, + IPPROTO_TCP, + TCP_NOPUSH, + (const char *)&NoPush, + sizeof(int)) == SOCKET_ERROR) { + fprintf(where, + "recv_tcp_tran_rr: could not set TCP_NOPUSH errno %d\n", + errno); + fflush(where); + netperf_response.content.serv_errno = errno; + close(s_listen); + send_response(); + } + + /* Now, let's set-up the socket to listen for connections */ + if (listen(s_listen, 5) == SOCKET_ERROR) { + netperf_response.content.serv_errno = errno; + close(s_listen); + send_response(); + if (debug) { + fprintf(where,"could not listen\n"); + fflush(where); + } + exit(1); + } + + /* now get the port number assigned by the system */ + addrlen = sizeof(myaddr_in); + if (getsockname(s_listen, + (struct sockaddr *)&myaddr_in, + &addrlen) == SOCKET_ERROR){ + netperf_response.content.serv_errno = errno; + close(s_listen); + send_response(); + if (debug) { + fprintf(where,"could not geetsockname\n"); + fflush(where); + } + exit(1); + } + + /* Now myaddr_in contains the port and the internet address this is */ + /* returned to the sender also implicitly telling the sender that the */ + /* socket buffer sizing has been done. */ + + tcp_tran_rr_response->data_port_number = (int) ntohs(myaddr_in.sin_port); + if (debug) { + fprintf(where,"telling the remote to call me at %d\n", + tcp_tran_rr_response->data_port_number); + fflush(where); + } + netperf_response.content.serv_errno = 0; + + /* But wait, there's more. If the initiator wanted cpu measurements, */ + /* then we must call the calibrate routine, which will return the max */ + /* rate back to the initiator. If the CPU was not to be measured, or */ + /* something went wrong with the calibration, we will return a 0.0 to */ + /* the initiator. */ + + tcp_tran_rr_response->cpu_rate = 0.0; /* assume no cpu */ + if (tcp_tran_rr_request->measure_cpu) { + tcp_tran_rr_response->measure_cpu = 1; + tcp_tran_rr_response->cpu_rate = + calibrate_local_cpu(tcp_tran_rr_request->cpu_rate); + } + + + + /* before we send the response back to the initiator, pull some of */ + /* the socket parms from the globals */ + tcp_tran_rr_response->send_buf_size = lss_size; + tcp_tran_rr_response->recv_buf_size = lsr_size; + tcp_tran_rr_response->no_delay = loc_nodelay; + tcp_tran_rr_response->so_rcvavoid = loc_rcvavoid; + tcp_tran_rr_response->so_sndavoid = loc_sndavoid; + + send_response(); + + addrlen = sizeof(peeraddr_in); + + /* Now it's time to start receiving data on the connection. We will */ + /* first grab the apropriate counters and then start grabbing. */ + + cpu_start(tcp_tran_rr_request->measure_cpu); + + /* The loop will exit when the sender does a shutdown, which will */ + /* return a length of zero */ + + if (tcp_tran_rr_request->test_length > 0) { + times_up = 0; + trans_remaining = 0; + start_timer(tcp_tran_rr_request->test_length + PAD_TIME); + } + else { + times_up = 1; + trans_remaining = tcp_tran_rr_request->test_length * -1; + } + + trans_received = 0; + + while ((!times_up) || (trans_remaining > 0)) { + + /* accept a connection from the remote */ + if ((s_data=accept(s_listen, + (struct sockaddr *)&peeraddr_in, + &addrlen)) == INVALID_SOCKET) { + if (errno == EINTR) { + /* the timer popped */ + timed_out = 1; + break; + } + fprintf(where,"recv_tcp_tran_rr: accept: errno = %d\n",errno); + fflush(where); + close(s_listen); + + exit(1); + } + + if (debug) { + fprintf(where,"recv_tcp_tran_rr: accepted data connection.\n"); + fflush(where); + } + +#ifdef WIN32 + /* this is used so the timer thread can close the socket out from */ + /* under us, which to date is the easiest/cleanest/least */ + /* Windows-specific way I can find to force the winsock calls to */ + /* return WSAEINTR with the test is over. anything that will run on */ + /* 95 and NT and is closer to what netperf expects from Unix signals */ + /* and such would be appreciated raj 1/96 */ + win_kludge_socket = s_data; +#endif /* WIN32 */ + +#ifdef KLUDGE_SOCKET_OPTIONS + /* this is for those systems which *INCORRECTLY* fail to pass */ + /* attributes across an accept() call. Including this goes against */ + /* my better judgement :( raj 11/95 */ + + kludge_socket_options(s_data); + +#endif /* KLUDGE_SOCKET_OPTIONS */ + + temp_message_ptr = recv_message_ptr; + request_bytes_remaining = tcp_tran_rr_request->request_size; + + /* receive the request from the other side. we can just receive */ + /* until we get zero bytes, but that would be a slight structure */ + /* change in the code, with minimal perfomance effects. If */ + /* however, I has variable-length messages, I would want to do */ + /* this to avoid needing "double reads" - one for the message */ + /* length, and one for the rest of the message raj 3/95 */ + while(request_bytes_remaining > 0) { + if((request_bytes_recvd=recv(s_data, + temp_message_ptr, + request_bytes_remaining, + 0)) == SOCKET_ERROR) { + if ( SOCKET_EINTR(request_bytes_recvd) ) + { + /* the timer popped */ + timed_out = 1; + break; + } + netperf_response.content.serv_errno = errno; + send_response(); + exit(1); + } + else { + request_bytes_remaining -= request_bytes_recvd; + temp_message_ptr += request_bytes_recvd; + } + } + + if (timed_out) { + /* we hit the end of the test based on time - lets */ + /* bail out of here now... */ + fprintf(where,"yo5\n"); + fflush(where); + break; + } + + /* Now, send the response to the remote we can use sendto here to */ + /* help remind people that this is an rfc 1644 style of test */ + if((bytes_sent=sendto(s_data, + send_message_ptr, + tcp_tran_rr_request->response_size, + MSG_EOF, + (struct sockaddr *)&peeraddr_in, + sizeof(struct sockaddr_storage))) == SOCKET_ERROR) { + if (SOCKET_EINTR(bytes_sent)) { + /* the test timer has popped */ + timed_out = 1; + fprintf(where,"yo6\n"); + fflush(where); + break; + } + netperf_response.content.serv_errno = 99; + send_response(); + exit(1); + } + + trans_received++; + if (trans_remaining) { + trans_remaining--; + } + + if (debug) { + fprintf(where, + "recv_tcp_tran_rr: Transaction %d complete\n", + trans_received); + fflush(where); + } + + /* close the connection. since we have disable PUSH on sends, the */ + /* FIN should be tacked-onto our last send instead of being */ + /* standalone */ + close(s_data); + + } + + + /* The loop now exits due to timeout or transaction count being */ + /* reached */ + + cpu_stop(tcp_tran_rr_request->measure_cpu,&elapsed_time); + + if (timed_out) { + /* we ended the test by time, which was at least 2 seconds */ + /* longer than we wanted to run. so, we want to subtract */ + /* PAD_TIME from the elapsed_time. */ + elapsed_time -= PAD_TIME; + } + /* send the results to the sender */ + + if (debug) { + fprintf(where, + "recv_tcp_tran_rr: got %d transactions\n", + trans_received); + fflush(where); + } + + tcp_tran_rr_results->bytes_received = (trans_received * + (tcp_tran_rr_request->request_size + + tcp_tran_rr_request->response_size)); + tcp_tran_rr_results->trans_received = trans_received; + tcp_tran_rr_results->elapsed_time = elapsed_time; + if (tcp_tran_rr_request->measure_cpu) { + tcp_tran_rr_results->cpu_util = calc_cpu_util(elapsed_time); + } + + if (debug) { + fprintf(where, + "recv_tcp_tran_rr: test complete, sending results.\n"); + fflush(where); + } + + send_response(); + +} +#endif /* DO_1644 */ + +#ifdef DO_NBRR + /* this routine implements the sending (netperf) side of the TCP_RR */ + /* test using POSIX-style non-blocking sockets. */ + +void +send_tcp_nbrr(char remote_host[]) +{ + + char *tput_title = "\ +Local /Remote\n\ +Socket Size Request Resp. Elapsed Trans.\n\ +Send Recv Size Size Time Rate \n\ +bytes Bytes bytes bytes secs. per sec \n\n"; + + char *tput_fmt_0 = + "%7.2f\n"; + + char *tput_fmt_1_line_1 = "\ +%-6d %-6d %-6d %-6d %-6.2f %7.2f \n"; + char *tput_fmt_1_line_2 = "\ +%-6d %-6d\n"; + + char *cpu_title = "\ +Local /Remote\n\ +Socket Size Request Resp. Elapsed Trans. CPU CPU S.dem S.dem\n\ +Send Recv Size Size Time Rate local remote local remote\n\ +bytes bytes bytes bytes secs. per sec %% %c %% %c us/Tr us/Tr\n\n"; + + char *cpu_fmt_0 = + "%6.3f %c\n"; + + char *cpu_fmt_1_line_1 = "\ +%-6d %-6d %-6d %-6d %-6.2f %-6.2f %-6.2f %-6.2f %-6.3f %-6.3f\n"; + + char *cpu_fmt_1_line_2 = "\ +%-6d %-6d\n"; + + char *ksink_fmt = "\ +Alignment Offset\n\ +Local Remote Local Remote\n\ +Send Recv Send Recv\n\ +%5d %5d %5d %5d\n"; + + + int timed_out = 0; + float elapsed_time; + + int len; + char *temp_message_ptr; + int nummessages; + SOCKET send_socket; + int trans_remaining; + double bytes_xferd; + + struct ring_elt *send_ring; + struct ring_elt *recv_ring; + + int rsp_bytes_left; + int rsp_bytes_recvd; + + float local_cpu_utilization; + float local_service_demand; + float remote_cpu_utilization; + float remote_service_demand; + double thruput; + + struct hostent *hp; + struct sockaddr_storage server; + unsigned int addr; + + struct tcp_rr_request_struct *tcp_rr_request; + struct tcp_rr_response_struct *tcp_rr_response; + struct tcp_rr_results_struct *tcp_rr_result; + + struct addrinfo *remote_res; + struct addrinfo *local_res; + + tcp_rr_request = + (struct tcp_rr_request_struct *)netperf_request.content.test_specific_data; + tcp_rr_response= + (struct tcp_rr_response_struct *)netperf_response.content.test_specific_data; + tcp_rr_result = + (struct tcp_rr_results_struct *)netperf_response.content.test_specific_data; + +#ifdef WANT_HISTOGRAM + if (verbosity > 1) { + time_hist = HIST_new(); + } +#endif /* WANT_HISTOGRAM */ + + /* since we are now disconnected from the code that established the */ + /* control socket, and since we want to be able to use different */ + /* protocols and such, we are passed the name of the remote host and */ + /* must turn that into the test specific addressing information. */ + + bzero((char *)&server, + sizeof(server)); + + complete_addrinfos(&remote_res, + &local_res, + remote_host, + SOCK_STREAM, + IPPROTO_TCP, + 0); + + if ( print_headers ) { + print_top_test_header("TCP Non-Blocking REQUEST/RESPONSE TEST",local_res,remote_res); + } + + /* initialize a few counters */ + + send_ring = NULL; + recv_ring = NULL; + confidence_iteration = 1; + init_stat(); + + /* we have a great-big while loop which controls the number of times */ + /* we run a particular test. this is for the calculation of a */ + /* confidence interval (I really should have stayed awake during */ + /* probstats :). If the user did not request confidence measurement */ + /* (no confidence is the default) then we will only go though the */ + /* loop once. the confidence stuff originates from the folks at IBM */ + + while (((confidence < 0) && (confidence_iteration < iteration_max)) || + (confidence_iteration <= iteration_min)) { + + /* initialize a few counters. we have to remember that we might be */ + /* going through the loop more than once. */ + + nummessages = 0; + bytes_xferd = 0.0; + times_up = 0; + timed_out = 0; + trans_remaining = 0; + + /* set-up the data buffers with the requested alignment and offset. */ + /* since this is a request/response test, default the send_width and */ + /* recv_width to 1 and not two raj 7/94 */ + + if (send_width == 0) send_width = 1; + if (recv_width == 0) recv_width = 1; + + if (send_ring == NULL) { + send_ring = allocate_buffer_ring(send_width, + req_size, + local_send_align, + local_send_offset); + } + + if (recv_ring == NULL) { + recv_ring = allocate_buffer_ring(recv_width, + rsp_size, + local_recv_align, + local_recv_offset); + } + + /*set up the data socket */ + send_socket = create_data_socket(local_res); + + if (send_socket == INVALID_SOCKET){ + perror("netperf: send_tcp_nbrr: tcp stream data socket"); + exit(1); + } + + if (debug) { + fprintf(where,"send_tcp_nbrr: send_socket obtained...\n"); + } + + /* If the user has requested cpu utilization measurements, we must */ + /* calibrate the cpu(s). We will perform this task within the tests */ + /* themselves. If the user has specified the cpu rate, then */ + /* calibrate_local_cpu will return rather quickly as it will have */ + /* nothing to do. If local_cpu_rate is zero, then we will go through */ + /* all the "normal" calibration stuff and return the rate back.*/ + + if (local_cpu_usage) { + local_cpu_rate = calibrate_local_cpu(local_cpu_rate); + } + + /* Tell the remote end to do a listen. The server alters the socket */ + /* paramters on the other side at this point, hence the reason for */ + /* all the values being passed in the setup message. If the user did */ + /* not specify any of the parameters, they will be passed as 0, which */ + /* will indicate to the remote that no changes beyond the system's */ + /* default should be used. Alignment is the exception, it will */ + /* default to 8, which will be no alignment alterations. */ + + netperf_request.content.request_type = DO_TCP_NBRR; + tcp_rr_request->recv_buf_size = rsr_size_req; + tcp_rr_request->send_buf_size = rss_size_req; + tcp_rr_request->recv_alignment = remote_recv_align; + tcp_rr_request->recv_offset = remote_recv_offset; + tcp_rr_request->send_alignment = remote_send_align; + tcp_rr_request->send_offset = remote_send_offset; + tcp_rr_request->request_size = req_size; + tcp_rr_request->response_size = rsp_size; + tcp_rr_request->no_delay = rem_nodelay; + tcp_rr_request->measure_cpu = remote_cpu_usage; + tcp_rr_request->cpu_rate = remote_cpu_rate; + tcp_rr_request->so_rcvavoid = rem_rcvavoid; + tcp_rr_request->so_sndavoid = rem_sndavoid; + if (test_time) { + tcp_rr_request->test_length = test_time; + } + else { + tcp_rr_request->test_length = test_trans * -1; + } + + if (debug > 1) { + fprintf(where,"netperf: send_tcp_nbrr: requesting TCP rr test\n"); + } + + send_request(); + + /* The response from the remote will contain all of the relevant */ + /* socket parameters for this test type. We will put them back into */ + /* the variables here so they can be displayed if desired. The */ + /* remote will have calibrated CPU if necessary, and will have done */ + /* all the needed set-up we will have calibrated the cpu locally */ + /* before sending the request, and will grab the counter value right*/ + /* after the connect returns. The remote will grab the counter right*/ + /* after the accept call. This saves the hassle of extra messages */ + /* being sent for the TCP tests. */ + + recv_response(); + + if (!netperf_response.content.serv_errno) { + if (debug) + fprintf(where,"remote listen done.\n"); + rsr_size = tcp_rr_response->recv_buf_size; + rss_size = tcp_rr_response->send_buf_size; + rem_nodelay = tcp_rr_response->no_delay; + remote_cpu_usage = tcp_rr_response->measure_cpu; + remote_cpu_rate = tcp_rr_response->cpu_rate; + /* make sure that port numbers are in network order */ + server.sin_port = (unsigned short)tcp_rr_response->data_port_number; + server.sin_port = htons(server.sin_port); + } + else { + Set_errno(netperf_response.content.serv_errno); + fprintf(where, + "netperf: remote error %d", + netperf_response.content.serv_errno); + perror(""); + fflush(where); + exit(1); + } + + /*Connect up to the remote port on the data socket */ + if (connect(send_socket, + remote_res->ai_addr, + remote_res->ai_addrlen) == INVALID_SOCKET){ + perror("netperf: data socket connect failed"); + + exit(1); + } + + /* now that we are connected, mark the socket as non-blocking */ + if (!set_nonblock(send_socket)) { + perror("netperf: set_nonblock"); + exit(1); + } + +#ifdef WIN32 + /* this is used so the timer thread can close the socket out from */ + /* under us, which to date is the easiest/cleanest/least */ + /* Windows-specific way I can find to force the winsock calls to */ + /* return WSAEINTR with the test is over. anything that will run on */ + /* 95 and NT and is closer to what netperf expects from Unix signals */ + /* and such would be appreciated raj 1/96 */ + win_kludge_socket = send_socket; +#endif /* WIN32 */ + + /* Data Socket set-up is finished. If there were problems, either the */ + /* connect would have failed, or the previous response would have */ + /* indicated a problem. I failed to see the value of the extra */ + /* message after the accept on the remote. If it failed, we'll see it */ + /* here. If it didn't, we might as well start pumping data. */ + + /* Set-up the test end conditions. For a request/response test, they */ + /* can be either time or transaction based. */ + + if (test_time) { + /* The user wanted to end the test after a period of time. */ + times_up = 0; + trans_remaining = 0; + start_timer(test_time); + } + else { + /* The tester wanted to send a number of bytes. */ + trans_remaining = test_bytes; + times_up = 1; + } + + /* The cpu_start routine will grab the current time and possibly */ + /* value of the idle counter for later use in measuring cpu */ + /* utilization and/or service demand and thruput. */ + + cpu_start(local_cpu_usage); + +#ifdef WANT_INTERVALS + INTERVALS_INIT(); +#endif /* WANT_INTERVALS */ + + /* We use an "OR" to control test execution. When the test is */ + /* controlled by time, the byte count check will always return false. */ + /* When the test is controlled by byte count, the time test will */ + /* always return false. When the test is finished, the whole */ + /* expression will go false and we will stop sending data. I think I */ + /* just arbitrarily decrement trans_remaining for the timed test, but */ + /* will not do that just yet... One other question is whether or not */ + /* the send buffer and the receive buffer should be the same buffer. */ + + while ((!times_up) || (trans_remaining > 0)) { + /* send the request. we assume that if we use a blocking socket, */ + /* the request will be sent at one shot. */ + +#ifdef WANT_HISTOGRAM + if (verbosity > 1) { + /* timestamp just before our call to send, and then again just */ + /* after the receive raj 8/94 */ + HIST_timestamp(&time_one); + } +#endif /* WANT_HISTOGRAM */ + + /* even though this is a non-blocking socket, we will assume for */ + /* the time being that we will be able to send an entire request */ + /* without getting an EAGAIN */ + if((len=send(send_socket, + send_ring->buffer_ptr, + req_size, + 0)) != req_size) { + if (SOCKET_EINTR(len)) { + /* we hit the end of a */ + /* timed test. */ + timed_out = 1; + break; + } + perror("send_tcp_nbrr: data send error"); + exit(1); + } + send_ring = send_ring->next; + + /* receive the response. since we are using non-blocking I/O, we */ + /* will "spin" on the recvs */ + rsp_bytes_left = rsp_size; + temp_message_ptr = recv_ring->buffer_ptr; + while(rsp_bytes_left > 0) { + if((rsp_bytes_recvd=recv(send_socket, + temp_message_ptr, + rsp_bytes_left, + 0)) == SOCKET_ERROR) { + if (SOCKET_EINTR(rsp_bytes_recvd)) + { + /* We hit the end of a timed test. */ + timed_out = 1; + break; + } +#ifndef WIN32 // But what does WinNT indicate in this situation... + else if (errno == EAGAIN) { + Set_errno(0); + continue; + } +#endif + else { + perror("send_tcp_nbrr: data recv error"); + exit(1); + } + } + rsp_bytes_left -= rsp_bytes_recvd; + temp_message_ptr += rsp_bytes_recvd; + } + recv_ring = recv_ring->next; + + if (timed_out) { + /* we may have been in a nested while loop - we need */ + /* another call to break. */ + break; + } + +#ifdef WANT_HISTOGRAM + if (verbosity > 1) { + HIST_timestamp(&time_two); + HIST_add(time_hist,delta_micro(&time_one,&time_two)); + } +#endif /* WANT_HISTOGRAM */ +#ifdef WANT_INTERVALS + INTERVALS_WAIT(); +#endif /* WANT_INTERVALS */ + + nummessages++; + if (trans_remaining) { + trans_remaining--; + } + + if (debug > 3) { + if ((nummessages % 100) == 0) { + fprintf(where, + "Transaction %d completed\n", + nummessages); + fflush(where); + } + } + } + + /* At this point we used to call shutdown on the data socket to be */ + /* sure all the data was delivered, but this was not germane in a */ + /* request/response test, and it was causing the tests to "hang" when */ + /* they were being controlled by time. So, I have replaced this */ + /* shutdown call with a call to close that can be found later in the */ + /* procedure. */ + + /* this call will always give us the elapsed time for the test, and */ + /* will also store-away the necessaries for cpu utilization */ + + cpu_stop(local_cpu_usage,&elapsed_time); /* was cpu being */ + /* measured? how long */ + /* did we really run? */ + + /* Get the statistics from the remote end. The remote will have */ + /* calculated service demand and all those interesting things. If it */ + /* wasn't supposed to care, it will return obvious values. */ + + recv_response(); + if (!netperf_response.content.serv_errno) { + if (debug) + fprintf(where,"remote results obtained\n"); + } + else { + Set_errno(netperf_response.content.serv_errno); + fprintf(where, + "netperf: remote error %d", + netperf_response.content.serv_errno); + perror(""); + fflush(where); + + exit(1); + } + + /* We now calculate what our thruput was for the test. */ + + bytes_xferd = (req_size * nummessages) + (rsp_size * nummessages); + thruput = nummessages/elapsed_time; + + if (local_cpu_usage || remote_cpu_usage) { + /* We must now do a little math for service demand and cpu */ + /* utilization for the system(s) */ + /* Of course, some of the information might be bogus because */ + /* there was no idle counter in the kernel(s). We need to make */ + /* a note of this for the user's benefit...*/ + if (local_cpu_usage) { + local_cpu_utilization = calc_cpu_util(0.0); + /* since calc_service demand is doing ms/Kunit we will */ + /* multiply the number of transaction by 1024 to get */ + /* "good" numbers */ + local_service_demand = calc_service_demand((double) nummessages*1024, + 0.0, + 0.0, + 0); + } + else { + local_cpu_utilization = (float) -1.0; + local_service_demand = (float) -1.0; + } + + if (remote_cpu_usage) { + remote_cpu_utilization = tcp_rr_result->cpu_util; + /* since calc_service demand is doing ms/Kunit we will */ + /* multiply the number of transaction by 1024 to get */ + /* "good" numbers */ + remote_service_demand = calc_service_demand((double) nummessages*1024, + 0.0, + remote_cpu_utilization, + tcp_rr_result->num_cpus); + } + else { + remote_cpu_utilization = (float) -1.0; + remote_service_demand = (float) -1.0; + } + + } + else { + /* we were not measuring cpu, for the confidence stuff, we */ + /* should make it -1.0 */ + local_cpu_utilization = (float) -1.0; + local_service_demand = (float) -1.0; + remote_cpu_utilization = (float) -1.0; + remote_service_demand = (float) -1.0; + } + + /* at this point, we want to calculate the confidence information. */ + /* if debugging is on, calculate_confidence will print-out the */ + /* parameters we pass it */ + + calculate_confidence(confidence_iteration, + elapsed_time, + thruput, + local_cpu_utilization, + remote_cpu_utilization, + local_service_demand, + remote_service_demand); + + + confidence_iteration++; + + /* we are now done with the socket, so close it */ + close(send_socket); + + } + + retrieve_confident_values(&elapsed_time, + &thruput, + &local_cpu_utilization, + &remote_cpu_utilization, + &local_service_demand, + &remote_service_demand); + + /* We are now ready to print all the information. If the user */ + /* has specified zero-level verbosity, we will just print the */ + /* local service demand, or the remote service demand. If the */ + /* user has requested verbosity level 1, he will get the basic */ + /* "streamperf" numbers. If the user has specified a verbosity */ + /* of greater than 1, we will display a veritable plethora of */ + /* background information from outside of this block as it it */ + /* not cpu_measurement specific... */ + + if (confidence < 0) { + /* we did not hit confidence, but were we asked to look for it? */ + if (iteration_max > 1) { + display_confidence(); + } + } + + if (local_cpu_usage || remote_cpu_usage) { + local_cpu_method = format_cpu_method(cpu_method); + remote_cpu_method = format_cpu_method(tcp_rr_result->cpu_method); + + switch (verbosity) { + case 0: + if (local_cpu_usage) { + fprintf(where, + cpu_fmt_0, + local_service_demand, + local_cpu_method); + } + else { + fprintf(where, + cpu_fmt_0, + remote_service_demand, + remote_cpu_method); + } + break; + case 1: + case 2: + if (print_headers) { + fprintf(where, + cpu_title, + local_cpu_method, + remote_cpu_method); + } + + fprintf(where, + cpu_fmt_1_line_1, /* the format string */ + lss_size, /* local sendbuf size */ + lsr_size, + req_size, /* how large were the requests */ + rsp_size, /* guess */ + elapsed_time, /* how long was the test */ + thruput, + local_cpu_utilization, /* local cpu */ + remote_cpu_utilization, /* remote cpu */ + local_service_demand, /* local service demand */ + remote_service_demand); /* remote service demand */ + fprintf(where, + cpu_fmt_1_line_2, + rss_size, + rsr_size); + break; + } + } + else { + /* The tester did not wish to measure service demand. */ + + switch (verbosity) { + case 0: + fprintf(where, + tput_fmt_0, + thruput); + break; + case 1: + case 2: + if (print_headers) { + fprintf(where,tput_title,format_units()); + } + + fprintf(where, + tput_fmt_1_line_1, /* the format string */ + lss_size, + lsr_size, + req_size, /* how large were the requests */ + rsp_size, /* how large were the responses */ + elapsed_time, /* how long did it take */ + thruput); + fprintf(where, + tput_fmt_1_line_2, + rss_size, /* remote recvbuf size */ + rsr_size); + + break; + } + } + + /* it would be a good thing to include information about some of the */ + /* other parameters that may have been set for this test, but at the */ + /* moment, I do not wish to figure-out all the formatting, so I will */ + /* just put this comment here to help remind me that it is something */ + /* that should be done at a later time. */ + + /* how to handle the verbose information in the presence of */ + /* confidence intervals is yet to be determined... raj 11/94 */ + if (verbosity > 1) { + /* The user wanted to know it all, so we will give it to him. */ + /* This information will include as much as we can find about */ + /* TCP statistics, the alignments of the sends and receives */ + /* and all that sort of rot... */ + + fprintf(where, + ksink_fmt, + local_send_align, + remote_recv_offset, + local_send_offset, + remote_recv_offset); + +#ifdef WANT_HISTOGRAM + fprintf(where,"\nHistogram of request/response times\n"); + fflush(where); + HIST_report(time_hist); +#endif /* WANT_HISTOGRAM */ + + } + +} + + /* this routine implements the receive (netserver) side of a TCP_RR */ + /* test */ +void +recv_tcp_nbrr() +{ + + struct ring_elt *send_ring; + struct ring_elt *recv_ring; + + struct sockaddr_in myaddr_in, + peeraddr_in; + SOCKET s_listen,s_data; + netperf_socklen_t addrlen; + char *temp_message_ptr; + int trans_received; + int trans_remaining; + int bytes_sent; + int request_bytes_recvd; + int request_bytes_remaining; + int timed_out = 0; + float elapsed_time; + + struct addrinfo *local_res; + char local_name[BUFSIZ]; + char port_buffer[PORTBUFSIZE]; + + struct tcp_rr_request_struct *tcp_rr_request; + struct tcp_rr_response_struct *tcp_rr_response; + struct tcp_rr_results_struct *tcp_rr_results; + + tcp_rr_request = + (struct tcp_rr_request_struct *)netperf_request.content.test_specific_data; + tcp_rr_response = + (struct tcp_rr_response_struct *)netperf_response.content.test_specific_data; + tcp_rr_results = + (struct tcp_rr_results_struct *)netperf_response.content.test_specific_data; + + if (debug) { + fprintf(where,"netserver: recv_tcp_nbrr: entered...\n"); + fflush(where); + } + + /* We want to set-up the listen socket with all the desired */ + /* parameters and then let the initiator know that all is ready. If */ + /* socket size defaults are to be used, then the initiator will have */ + /* sent us 0's. If the socket sizes cannot be changed, then we will */ + /* send-back what they are. If that information cannot be determined, */ + /* then we send-back -1's for the sizes. If things go wrong for any */ + /* reason, we will drop back ten yards and punt. */ + + /* If anything goes wrong, we want the remote to know about it. It */ + /* would be best if the error that the remote reports to the user is */ + /* the actual error we encountered, rather than some bogus unexpected */ + /* response type message. */ + + if (debug) { + fprintf(where,"recv_tcp_nbrr: setting the response type...\n"); + fflush(where); + } + + netperf_response.content.response_type = TCP_RR_RESPONSE; + + if (debug) { + fprintf(where,"recv_tcp_nbrr: the response type is set...\n"); + fflush(where); + } + + /* allocate the recv and send rings with the requested alignments */ + /* and offsets. raj 7/94 */ + if (debug) { + fprintf(where,"recv_tcp_nbrr: requested recv alignment of %d offset %d\n", + tcp_rr_request->recv_alignment, + tcp_rr_request->recv_offset); + fprintf(where,"recv_tcp_nbrr: requested send alignment of %d offset %d\n", + tcp_rr_request->send_alignment, + tcp_rr_request->send_offset); + fflush(where); + } + + /* at some point, these need to come to us from the remote system */ + if (send_width == 0) send_width = 1; + if (recv_width == 0) recv_width = 1; + + send_ring = allocate_buffer_ring(send_width, + tcp_rr_request->response_size, + tcp_rr_request->send_alignment, + tcp_rr_request->send_offset); + + recv_ring = allocate_buffer_ring(recv_width, + tcp_rr_request->request_size, + tcp_rr_request->recv_alignment, + tcp_rr_request->recv_offset); + + + /* Let's clear-out our sockaddr for the sake of cleanlines. Then we */ + /* can put in OUR values !-) At some point, we may want to nail this */ + /* socket to a particular network-level address, but for now, */ + /* INADDR_ANY should be just fine. */ + + bzero((char *)&myaddr_in, + sizeof(myaddr_in)); + myaddr_in.sin_family = AF_INET; + myaddr_in.sin_addr.s_addr = INADDR_ANY; + myaddr_in.sin_port = htons((unsigned short)tcp_rr_request->port); + + /* Grab a socket to listen on, and then listen on it. */ + + if (debug) { + fprintf(where,"recv_tcp_nbrr: grabbing a socket...\n"); + fflush(where); + } + + /* create_data_socket expects to find some things in the global */ + /* variables, so set the globals based on the values in the request. */ + /* once the socket has been created, we will set the response values */ + /* based on the updated value of those globals. raj 7/94 */ + lss_size_req = tcp_rr_request->send_buf_size; + lsr_size_req = tcp_rr_request->recv_buf_size; + loc_nodelay = tcp_rr_request->no_delay; + loc_rcvavoid = tcp_rr_request->so_rcvavoid; + loc_sndavoid = tcp_rr_request->so_sndavoid; + + set_hostname_and_port(local_name, + port_buffer, + nf_to_af(tcp_rr_request->ipfamily), + tcp_rr_request->port); + + local_res = complete_addrinfo(local_name, + local_name, + port_buffer, + nf_to_af(tcp_rr_request->ipfamily), + SOCK_STREAM, + IPPROTO_TCP, + 0); + + s_listen = create_data_socket(local_res); + + if (s_listen == INVALID_SOCKET) { + netperf_response.content.serv_errno = errno; + send_response(); + + exit(1); + } + + /* Let's get an address assigned to this socket so we can tell the */ + /* initiator how to reach the data socket. There may be a desire to */ + /* nail this socket to a specific IP address in a multi-homed, */ + /* multi-connection situation, but for now, we'll ignore the issue */ + /* and concentrate on single connection testing. */ + + if (bind(s_listen, + (struct sockaddr *)&myaddr_in, + sizeof(myaddr_in)) == SOCKET_ERROR) { + netperf_response.content.serv_errno = errno; + close(s_listen); + send_response(); + + exit(1); + } + + /* Now, let's set-up the socket to listen for connections */ + if (listen(s_listen, 5) == SOCKET_ERROR) { + netperf_response.content.serv_errno = errno; + close(s_listen); + send_response(); + + exit(1); + } + + + /* now get the port number assigned by the system */ + addrlen = sizeof(myaddr_in); + if (getsockname(s_listen, + (struct sockaddr *)&myaddr_in, &addrlen) == SOCKET_ERROR){ + netperf_response.content.serv_errno = errno; + close(s_listen); + send_response(); + + exit(1); + } + + /* Now myaddr_in contains the port and the internet address this is */ + /* returned to the sender also implicitly telling the sender that the */ + /* socket buffer sizing has been done. */ + + tcp_rr_response->data_port_number = (int) ntohs(myaddr_in.sin_port); + netperf_response.content.serv_errno = 0; + + /* But wait, there's more. If the initiator wanted cpu measurements, */ + /* then we must call the calibrate routine, which will return the max */ + /* rate back to the initiator. If the CPU was not to be measured, or */ + /* something went wrong with the calibration, we will return a 0.0 to */ + /* the initiator. */ + + tcp_rr_response->cpu_rate = 0.0; /* assume no cpu */ + tcp_rr_response->measure_cpu = 0; + + if (tcp_rr_request->measure_cpu) { + tcp_rr_response->measure_cpu = 1; + tcp_rr_response->cpu_rate = calibrate_local_cpu(tcp_rr_request->cpu_rate); + } + + + /* before we send the response back to the initiator, pull some of */ + /* the socket parms from the globals */ + tcp_rr_response->send_buf_size = lss_size; + tcp_rr_response->recv_buf_size = lsr_size; + tcp_rr_response->no_delay = loc_nodelay; + tcp_rr_response->so_rcvavoid = loc_rcvavoid; + tcp_rr_response->so_sndavoid = loc_sndavoid; + tcp_rr_response->test_length = tcp_rr_request->test_length; + send_response(); + + addrlen = sizeof(peeraddr_in); + + if ((s_data = accept(s_listen, + (struct sockaddr *)&peeraddr_in, + &addrlen)) == INVALID_SOCKET) { + /* Let's just punt. The remote will be given some information */ + close(s_listen); + exit(1); + } + + if (debug) { + fprintf(where,"recv_tcp_nbrr: accept completes on the data connection.\n"); + fflush(where); + } + +#ifdef KLUDGE_SOCKET_OPTIONS + /* this is for those systems which *INCORRECTLY* fail to pass */ + /* attributes across an accept() call. Including this goes against */ + /* my better judgement :( raj 11/95 */ + + kludge_socket_options(s_data); + +#endif /* KLUDGE_SOCKET_OPTIONS */ + + /* now that we are connected, mark the socket as non-blocking */ + if (!set_nonblock(s_data)) { + close(s_data); + exit(1); + } + + + /* Now it's time to start receiving data on the connection. We will */ + /* first grab the apropriate counters and then start grabbing. */ + + cpu_start(tcp_rr_request->measure_cpu); + +#ifdef WIN32 + /* this is used so the timer thread can close the socket out from */ + /* under us, which to date is the easiest/cleanest/least */ + /* Windows-specific way I can find to force the winsock calls to */ + /* return WSAEINTR with the test is over. anything that will run on */ + /* 95 and NT and is closer to what netperf expects from Unix signals */ + /* and such would be appreciated raj 1/96 */ + win_kludge_socket = s_data; +#endif /* WIN32 */ + + /* The loop will exit when the sender does a shutdown, which will */ + /* return a length of zero */ + + if (tcp_rr_request->test_length > 0) { + times_up = 0; + trans_remaining = 0; + start_timer(tcp_rr_request->test_length + PAD_TIME); + } + else { + times_up = 1; + trans_remaining = tcp_rr_request->test_length * -1; + } + + trans_received = 0; + + while ((!times_up) || (trans_remaining > 0)) { + temp_message_ptr = recv_ring->buffer_ptr; + request_bytes_remaining = tcp_rr_request->request_size; + while(request_bytes_remaining > 0) { + if((request_bytes_recvd=recv(s_data, + temp_message_ptr, + request_bytes_remaining, + 0)) == SOCKET_ERROR) { + if ( SOCKET_EINTR(request_bytes_recvd)) + { + /* the timer popped */ + timed_out = 1; + break; + } +#ifndef WIN32 // But what does WinNT indicate in this situation... + else if (errno == EAGAIN) { + Set_errno(0); + if (times_up) { + timed_out = 1; + break; + } + continue; + } +#endif + else { + netperf_response.content.serv_errno = errno; + send_response(); + exit(1); + } + } + else { + request_bytes_remaining -= request_bytes_recvd; + temp_message_ptr += request_bytes_recvd; + } + } + + recv_ring = recv_ring->next; + + if (timed_out) { + /* we hit the end of the test based on time - lets */ + /* bail out of here now... */ + fprintf(where,"yo5\n"); + fflush(where); + break; + } + + /* Now, send the response to the remote */ + if((bytes_sent=send(s_data, + send_ring->buffer_ptr, + tcp_rr_request->response_size, + 0)) == SOCKET_ERROR) { + if (SOCKET_EINTR(bytes_sent)) { + /* the test timer has popped */ + timed_out = 1; + fprintf(where,"yo6\n"); + fflush(where); + break; + } + netperf_response.content.serv_errno = 992; + send_response(); + exit(1); + } + + send_ring = send_ring->next; + + trans_received++; + if (trans_remaining) { + trans_remaining--; + } + } + + + /* The loop now exits due to timeout or transaction count being */ + /* reached */ + + cpu_stop(tcp_rr_request->measure_cpu,&elapsed_time); + + stop_timer(); + + if (timed_out) { + /* we ended the test by time, which was at least 2 seconds */ + /* longer than we wanted to run. so, we want to subtract */ + /* PAD_TIME from the elapsed_time. */ + elapsed_time -= PAD_TIME; + } + + /* send the results to the sender */ + + if (debug) { + fprintf(where, + "recv_tcp_nbrr: got %d transactions\n", + trans_received); + fflush(where); + } + + tcp_rr_results->bytes_received = (trans_received * + (tcp_rr_request->request_size + + tcp_rr_request->response_size)); + tcp_rr_results->trans_received = trans_received; + tcp_rr_results->elapsed_time = elapsed_time; + tcp_rr_results->cpu_method = cpu_method; + tcp_rr_results->num_cpus = lib_num_loc_cpus; + if (tcp_rr_request->measure_cpu) { + tcp_rr_results->cpu_util = calc_cpu_util(elapsed_time); + } + + if (debug) { + fprintf(where, + "recv_tcp_nbrr: test complete, sending results.\n"); + fflush(where); + } + + /* we are done with the socket, free it */ + close(s_data); + + send_response(); + +} + +#endif /* DO_NBRR */ + + + /* this test is intended to test the performance of establishing a */ + /* connection, and then closing it again. this test is of somewhat */ + /* arcane interest since no packets are exchanged between the */ + /* user-space processes, but it will show the raw overhead of */ + /* establishing a TCP connection. that service demand could then be */ + /* compared with the sum of the service demands of a TCP_CRR and */ + /* TCP_RR test - presumeably, they would all relate */ + +void +send_tcp_cc(char remote_host[]) +{ + + char *tput_title = "\ +Local /Remote\n\ +Socket Size Request Resp. Elapsed Trans.\n\ +Send Recv Size Size Time Rate \n\ +bytes Bytes bytes bytes secs. per sec \n\n"; + + char *tput_fmt_0 = + "%7.2f\n"; + + char *tput_fmt_1_line_1 = "\ +%-6d %-6d %-6d %-6d %-6.2f %7.2f \n"; + char *tput_fmt_1_line_2 = "\ +%-6d %-6d\n"; + + char *cpu_title = "\ +Local /Remote\n\ +Socket Size Request Resp. Elapsed Trans. CPU CPU S.dem S.dem\n\ +Send Recv Size Size Time Rate local remote local remote\n\ +bytes bytes bytes bytes secs. per sec %% %% us/Tr us/Tr\n\n"; + + char *cpu_fmt_0 = + "%6.3f\n"; + + char *cpu_fmt_1_line_1 = "\ +%-6d %-6d %-6d %-6d %-6.2f %-6.2f %-6.2f %-6.2f %-6.3f %-6.3f\n"; + + char *cpu_fmt_1_line_2 = "\ +%-6d %-6d\n"; + + char *ksink_fmt = "\n\ +Alignment Offset\n\ +Local Remote Local Remote\n\ +Send Recv Send Recv\n\ +%5d %5d %5d %5d\n"; + + + int timed_out = 0; + float elapsed_time; + + char temp_message_ptr[1]; + int nummessages; + SOCKET send_socket; + int trans_remaining; + double bytes_xferd; + int rsp_bytes_left = 1; + int rsp_bytes_recvd; + + float local_cpu_utilization; + float local_service_demand; + float remote_cpu_utilization; + float remote_service_demand; + double thruput; + + struct addrinfo *local_res; + struct addrinfo *remote_res; + + int myport; + int ret; + + struct tcp_cc_request_struct *tcp_cc_request; + struct tcp_cc_response_struct *tcp_cc_response; + struct tcp_cc_results_struct *tcp_cc_result; + + tcp_cc_request = + (struct tcp_cc_request_struct *)netperf_request.content.test_specific_data; + tcp_cc_response = + (struct tcp_cc_response_struct *)netperf_response.content.test_specific_data; + tcp_cc_result = + (struct tcp_cc_results_struct *)netperf_response.content.test_specific_data; + + +#ifdef WANT_HISTOGRAM + if (verbosity > 1) { + time_hist = HIST_new(); + } +#endif /* WANT_HISTOGRAM */ + + /* since we are now disconnected from the code that established the */ + /* control socket, and since we want to be able to use different */ + /* protocols and such, we are passed the name of the remote host and */ + /* must turn that into the test specific addressing information. */ + + complete_addrinfos(&remote_res, + &local_res, + remote_host, + SOCK_STREAM, + IPPROTO_TCP, + 0); + + if ( print_headers ) { + print_top_test_header("TCP Connect/Close TEST",local_res,remote_res); + } + + /* initialize a few counters */ + + nummessages = 0; + bytes_xferd = 0.0; + times_up = 0; + + /* since there are no data buffers in this test, we need no send or */ + /* recv rings */ + + if (debug) { + fprintf(where,"send_tcp_cc: send_socket obtained...\n"); + } + + /* If the user has requested cpu utilization measurements, we must */ + /* calibrate the cpu(s). We will perform this task within the tests */ + /* themselves. If the user has specified the cpu rate, then */ + /* calibrate_local_cpu will return rather quickly as it will have */ + /* nothing to do. If local_cpu_rate is zero, then we will go through */ + /* all the "normal" calibration stuff and return the rate back.*/ + + if (local_cpu_usage) { + local_cpu_rate = calibrate_local_cpu(local_cpu_rate); + } + + /* Tell the remote end to do a listen. The server alters the socket */ + /* paramters on the other side at this point, hence the reason for */ + /* all the values being passed in the setup message. If the user did */ + /* not specify any of the parameters, they will be passed as 0, which */ + /* will indicate to the remote that no changes beyond the system's */ + /* default should be used. Alignment is the exception, it will */ + /* default to 8, which will be no alignment alterations. */ + + netperf_request.content.request_type = DO_TCP_CC; + tcp_cc_request->recv_buf_size = rsr_size_req; + tcp_cc_request->send_buf_size = rss_size_req; + tcp_cc_request->recv_alignment = remote_recv_align; + tcp_cc_request->recv_offset = remote_recv_offset; + tcp_cc_request->send_alignment = remote_send_align; + tcp_cc_request->send_offset = remote_send_offset; + tcp_cc_request->request_size = req_size; + tcp_cc_request->response_size = rsp_size; + tcp_cc_request->no_delay = rem_nodelay; + tcp_cc_request->measure_cpu = remote_cpu_usage; + tcp_cc_request->cpu_rate = remote_cpu_rate; + tcp_cc_request->so_rcvavoid = rem_rcvavoid; + tcp_cc_request->so_sndavoid = rem_sndavoid; + if (test_time) { + tcp_cc_request->test_length = test_time; + } + else { + tcp_cc_request->test_length = test_trans * -1; + } + tcp_cc_request->port = atoi(remote_data_port); + tcp_cc_request->ipfamily = af_to_nf(remote_res->ai_family); + + if (debug > 1) { + fprintf(where,"netperf: send_tcp_cc: requesting TCP crr test\n"); + } + + send_request(); + + /* The response from the remote will contain all of the relevant */ + /* socket parameters for this test type. We will put them back into */ + /* the variables here so they can be displayed if desired. The */ + /* remote will have calibrated CPU if necessary, and will have done */ + /* all the needed set-up we will have calibrated the cpu locally */ + /* before sending the request, and will grab the counter value right */ + /* after the connect returns. The remote will grab the counter right */ + /* after the accept call. This saves the hassle of extra messages */ + /* being sent for the TCP tests. */ + + recv_response(); + + if (!netperf_response.content.serv_errno) { + rsr_size = tcp_cc_response->recv_buf_size; + rss_size = tcp_cc_response->send_buf_size; + rem_nodelay = tcp_cc_response->no_delay; + remote_cpu_usage= tcp_cc_response->measure_cpu; + remote_cpu_rate = tcp_cc_response->cpu_rate; + /* make sure that port numbers are in network order */ + set_port_number(remote_res,(unsigned short)tcp_cc_response->data_port_number); + + if (debug) { + fprintf(where,"remote listen done.\n"); + fprintf(where,"remote port is %d\n",get_port_number(remote_res)); + fflush(where); + } + } + else { + Set_errno(netperf_response.content.serv_errno); + fprintf(where, + "netperf: remote error %d", + netperf_response.content.serv_errno); + perror(""); + fflush(where); + exit(1); + } + +#ifdef WANT_DEMO + DEMO_RR_SETUP(100) +#endif + + /* pick a nice random spot between client_port_min and */ + /* client_port_max for our initial port number */ + srand(getpid()); + if (client_port_max - client_port_min) { + myport = client_port_min + + (rand() % (client_port_max - client_port_min)); + } + else { + myport = client_port_min; + } + /* there will be a ++ before the first call to bind, so subtract one */ + myport--; + + /* Set-up the test end conditions. For a request/response test, they */ + /* can be either time or transaction based. */ + + if (test_time) { + /* The user wanted to end the test after a period of time. */ + times_up = 0; + trans_remaining = 0; + start_timer(test_time); + } + else { + /* The tester wanted to send a number of bytes. */ + trans_remaining = test_bytes; + times_up = 1; + } + + /* The cpu_start routine will grab the current time and possibly */ + /* value of the idle counter for later use in measuring cpu */ + /* utilization and/or service demand and thruput. */ + + cpu_start(local_cpu_usage); + +#ifdef WANT_DEMO + if (demo_mode) { + HIST_timestamp(demo_one_ptr); + } +#endif + + /* We use an "OR" to control test execution. When the test is */ + /* controlled by time, the byte count check will always return false. */ + /* When the test is controlled by byte count, the time test will */ + /* always return false. When the test is finished, the whole */ + /* expression will go false and we will stop sending data. I think I */ + /* just arbitrarily decrement trans_remaining for the timed test, but */ + /* will not do that just yet... One other question is whether or not */ + /* the send buffer and the receive buffer should be the same buffer. */ + + while ((!times_up) || (trans_remaining > 0)) { + +#ifdef WANT_HISTOGRAM + if (verbosity > 1) { + /* timestamp just before our call to create the socket, and then */ + /* again just after the receive raj 3/95 */ + HIST_timestamp(&time_one); + } +#endif /* WANT_HISTOGRAM */ + + /* set up the data socket */ + /* newport: is this label really required any longer? */ + /* pick a new port number */ + myport++; + + /* wrap the port number when we get to client_port_max. NOTE, some */ + /* broken TCP's might treat the port number as a signed 16 bit */ + /* quantity. we aren't interested in testing such broken */ + /* implementations :) so we won't make sure that it is below 32767 */ + /* raj 8/94 */ + if (myport >= client_port_max) { + myport = client_port_min; + } + + /* we do not want to use the port number that the server is */ + /* sitting at - this would cause us to fail in a loopback test. we */ + /* could just rely on the failure of the bind to get us past this, */ + /* but I'm guessing that in this one case at least, it is much */ + /* faster, given that we *know* that port number is already in use */ + /* (or rather would be in a loopback test) */ + + if (myport == get_port_number(remote_res)) myport++; + + if (debug) { + if ((nummessages % 100) == 0) { + printf("port %d\n",myport); + } + } + set_port_number(local_res, (unsigned short)myport); + send_socket = create_data_socket(local_res); + + if (send_socket == INVALID_SOCKET) { + perror("netperf: send_tcp_cc: tcp stream data socket"); + exit(1); + } + +#ifdef WIN32 + /* this is used so the timer thread can close the socket out from */ + /* under us, which to date is the easiest/cleanest/least */ + /* Windows-specific way I can find to force the winsock calls to */ + /* return WSAEINTR with the test is over. anything that will run on */ + /* 95 and NT and is closer to what netperf expects from Unix signals */ + /* and such would be appreciated raj 1/96 */ + win_kludge_socket = send_socket; +#endif /* WIN32 */ + + /* we used to have a call to bind() here, but that is being + taken care of by create_data_socket(). raj 2005-02-08 */ + + /* Connect up to the remote port on the data socket */ + if ((ret = connect(send_socket, + remote_res->ai_addr, + remote_res->ai_addrlen)) == INVALID_SOCKET){ + if (SOCKET_EINTR(ret)) + { + /* we hit the end of a */ + /* timed test. */ + timed_out = 1; + break; + } + perror("netperf: data socket connect failed"); + printf("\tattempted to connect on socket %d to port %d", + send_socket, + get_port_number(remote_res)); + printf(" from port %u \n",get_port_number(local_res)); + exit(1); + } + + /* we hang in a recv() to get the remote's close indication */ + + rsp_bytes_recvd=recv(send_socket, + temp_message_ptr, + rsp_bytes_left, + 0); + + + if (rsp_bytes_recvd == 0) { + /* connection close, call close. we assume that the requisite */ + /* number of bytes have been received */ + +#ifdef WANT_HISTOGRAM + if (verbosity > 1) { + HIST_timestamp(&time_two); + HIST_add(time_hist,delta_micro(&time_one,&time_two)); + } +#endif /* WANT_HISTOGRAM */ + +#ifdef WANT_DEMO + DEMO_RR_INTERVAL(1) +#endif + + nummessages++; + if (trans_remaining) { + trans_remaining--; + } + + if (debug > 3) { + fprintf(where, + "Transaction %d completed on local port %u\n", + nummessages, + get_port_number(local_res)); + fflush(where); + } + + close(send_socket); + + } + else { + /* it was less than zero - an error occured */ + if (SOCKET_EINTR(rsp_bytes_recvd)) + { + /* We hit the end of a timed test. */ + timed_out = 1; + break; + } + perror("send_tcp_cc: data recv error"); + exit(1); + } + + } + + + /* this call will always give us the elapsed time for the test, and */ + /* will also store-away the necessaries for cpu utilization */ + + cpu_stop(local_cpu_usage,&elapsed_time); /* was cpu being measured? */ + /* how long did we really run? */ + + /* Get the statistics from the remote end. The remote will have */ + /* calculated service demand and all those interesting things. If it */ + /* wasn't supposed to care, it will return obvious values. */ + + recv_response(); + if (!netperf_response.content.serv_errno) { + if (debug) + fprintf(where,"remote results obtained\n"); + } + else { + Set_errno(netperf_response.content.serv_errno); + fprintf(where, + "netperf: remote error %d", + netperf_response.content.serv_errno); + perror(""); + fflush(where); + + exit(1); + } + + /* We now calculate what our thruput was for the test. In the future, */ + /* we may want to include a calculation of the thruput measured by */ + /* the remote, but it should be the case that for a TCP stream test, */ + /* that the two numbers should be *very* close... We calculate */ + /* bytes_sent regardless of the way the test length was controlled. */ + /* If it was time, we needed to, and if it was by bytes, the user may */ + /* have specified a number of bytes that wasn't a multiple of the */ + /* send_size, so we really didn't send what he asked for ;-) We use */ + /* Kbytes/s as the units of thruput for a TCP stream test, where K = */ + /* 1024. A future enhancement *might* be to choose from a couple of */ + /* unit selections. */ + + bytes_xferd = (req_size * nummessages) + (rsp_size * nummessages); + thruput = calc_thruput(bytes_xferd); + + if (local_cpu_usage || remote_cpu_usage) { + /* We must now do a little math for service demand and cpu */ + /* utilization for the system(s) */ + /* Of course, some of the information might be bogus because */ + /* there was no idle counter in the kernel(s). We need to make */ + /* a note of this for the user's benefit...*/ + if (local_cpu_usage) { + if (local_cpu_rate == 0.0) { + fprintf(where,"WARNING WARNING WARNING WARNING WARNING WARNING WARNING!\n"); + fprintf(where,"Local CPU usage numbers based on process information only!\n"); + fflush(where); + } + local_cpu_utilization = calc_cpu_util(0.0); + /* since calc_service demand is doing ms/Kunit we will */ + /* multiply the number of transaction by 1024 to get */ + /* "good" numbers */ + local_service_demand = calc_service_demand((double) nummessages*1024, + 0.0, + 0.0, + 0); + } + else { + local_cpu_utilization = (float) -1.0; + local_service_demand = (float) -1.0; + } + + if (remote_cpu_usage) { + if (remote_cpu_rate == 0.0) { + fprintf(where,"DANGER DANGER DANGER DANGER DANGER DANGER DANGER!\n"); + fprintf(where,"Remote CPU usage numbers based on process information only!\n"); + fflush(where); + } + remote_cpu_utilization = tcp_cc_result->cpu_util; + /* since calc_service demand is doing ms/Kunit we will */ + /* multiply the number of transaction by 1024 to get */ + /* "good" numbers */ + remote_service_demand = calc_service_demand((double) nummessages*1024, + 0.0, + remote_cpu_utilization, + tcp_cc_result->num_cpus); + } + else { + remote_cpu_utilization = (float) -1.0; + remote_service_demand = (float) -1.0; + } + + /* We are now ready to print all the information. If the user */ + /* has specified zero-level verbosity, we will just print the */ + /* local service demand, or the remote service demand. If the */ + /* user has requested verbosity level 1, he will get the basic */ + /* "streamperf" numbers. If the user has specified a verbosity */ + /* of greater than 1, we will display a veritable plethora of */ + /* background information from outside of this block as it it */ + /* not cpu_measurement specific... */ + + switch (verbosity) { + case 0: + if (local_cpu_usage) { + fprintf(where, + cpu_fmt_0, + local_service_demand); + } + else { + fprintf(where, + cpu_fmt_0, + remote_service_demand); + } + break; + case 1: + case 2: + + if (print_headers) { + fprintf(where, + cpu_title, + local_cpu_method, + remote_cpu_method); + } + + fprintf(where, + cpu_fmt_1_line_1, /* the format string */ + lss_size, /* local sendbuf size */ + lsr_size, + req_size, /* how large were the requests */ + rsp_size, /* guess */ + elapsed_time, /* how long was the test */ + nummessages/elapsed_time, + local_cpu_utilization, /* local cpu */ + remote_cpu_utilization, /* remote cpu */ + local_service_demand, /* local service demand */ + remote_service_demand); /* remote service demand */ + fprintf(where, + cpu_fmt_1_line_2, + rss_size, + rsr_size); + break; + } + } + else { + /* The tester did not wish to measure service demand. */ + switch (verbosity) { + case 0: + fprintf(where, + tput_fmt_0, + nummessages/elapsed_time); + break; + case 1: + case 2: + if (print_headers) { + fprintf(where,tput_title,format_units()); + } + + fprintf(where, + tput_fmt_1_line_1, /* the format string */ + lss_size, + lsr_size, + req_size, /* how large were the requests */ + rsp_size, /* how large were the responses */ + elapsed_time, /* how long did it take */ + nummessages/elapsed_time); + fprintf(where, + tput_fmt_1_line_2, + rss_size, /* remote recvbuf size */ + rsr_size); + + break; + } + } + + /* it would be a good thing to include information about some of the */ + /* other parameters that may have been set for this test, but at the */ + /* moment, I do not wish to figure-out all the formatting, so I will */ + /* just put this comment here to help remind me that it is something */ + /* that should be done at a later time. */ + + if (verbosity > 1) { + /* The user wanted to know it all, so we will give it to him. */ + /* This information will include as much as we can find about */ + /* TCP statistics, the alignments of the sends and receives */ + /* and all that sort of rot... */ + + fprintf(where, + ksink_fmt, + local_send_align, + remote_recv_offset, + local_send_offset, + remote_recv_offset); + +#ifdef WANT_HISTOGRAM + fprintf(where,"\nHistogram of request/response times\n"); + fflush(where); + HIST_report(time_hist); +#endif /* WANT_HISTOGRAM */ + + } + +} + + +void +recv_tcp_cc() +{ + + char *message; + + struct addrinfo *local_res; + char local_name[BUFSIZ]; + char port_buffer[PORTBUFSIZE]; + + struct sockaddr_storage myaddr_in, peeraddr_in; + SOCKET s_listen,s_data; + netperf_socklen_t addrlen; + char *recv_message_ptr; + char *send_message_ptr; + int trans_received; + int trans_remaining; + int timed_out = 0; + float elapsed_time; + + struct tcp_cc_request_struct *tcp_cc_request; + struct tcp_cc_response_struct *tcp_cc_response; + struct tcp_cc_results_struct *tcp_cc_results; + + tcp_cc_request = + (struct tcp_cc_request_struct *)netperf_request.content.test_specific_data; + tcp_cc_response = + (struct tcp_cc_response_struct *)netperf_response.content.test_specific_data; + tcp_cc_results = + (struct tcp_cc_results_struct *)netperf_response.content.test_specific_data; + + if (debug) { + fprintf(where,"netserver: recv_tcp_cc: entered...\n"); + fflush(where); + } + + /* We want to set-up the listen socket with all the desired */ + /* parameters and then let the initiator know that all is ready. If */ + /* socket size defaults are to be used, then the initiator will have */ + /* sent us 0's. If the socket sizes cannot be changed, then we will */ + /* send-back what they are. If that information cannot be determined, */ + /* then we send-back -1's for the sizes. If things go wrong for any */ + /* reason, we will drop back ten yards and punt. */ + + /* If anything goes wrong, we want the remote to know about it. It */ + /* would be best if the error that the remote reports to the user is */ + /* the actual error we encountered, rather than some bogus unexpected */ + /* response type message. */ + + if (debug) { + fprintf(where,"recv_tcp_cc: setting the response type...\n"); + fflush(where); + } + + netperf_response.content.response_type = TCP_CC_RESPONSE; + + if (debug) { + fprintf(where,"recv_tcp_cc: the response type is set...\n"); + fflush(where); + } + + /* set-up the data buffer with the requested alignment and offset */ + message = (char *)malloc(DATABUFFERLEN); + if (message == NULL) { + printf("malloc(%d) failed!\n", DATABUFFERLEN); + exit(1); + } + + /* We now alter the message_ptr variables to be at the desired */ + /* alignments with the desired offsets. */ + + if (debug) { + fprintf(where, + "recv_tcp_cc: requested recv alignment of %d offset %d\n", + tcp_cc_request->recv_alignment, + tcp_cc_request->recv_offset); + fprintf(where, + "recv_tcp_cc: requested send alignment of %d offset %d\n", + tcp_cc_request->send_alignment, + tcp_cc_request->send_offset); + fflush(where); + } + + recv_message_ptr = ALIGN_BUFFER(message, tcp_cc_request->recv_alignment, tcp_cc_request->recv_offset); + + send_message_ptr = ALIGN_BUFFER(message, tcp_cc_request->send_alignment, tcp_cc_request->send_offset); + + if (debug) { + fprintf(where,"recv_tcp_cc: receive alignment and offset set...\n"); + fflush(where); + } + + /* Grab a socket to listen on, and then listen on it. */ + + if (debug) { + fprintf(where,"recv_tcp_cc: grabbing a socket...\n"); + fflush(where); + } + + /* create_data_socket expects to find some things in the global */ + /* variables, so set the globals based on the values in the request. */ + /* once the socket has been created, we will set the response values */ + /* based on the updated value of those globals. raj 7/94 */ + lss_size_req = tcp_cc_request->send_buf_size; + lsr_size_req = tcp_cc_request->recv_buf_size; + loc_nodelay = tcp_cc_request->no_delay; + loc_rcvavoid = tcp_cc_request->so_rcvavoid; + loc_sndavoid = tcp_cc_request->so_sndavoid; + + set_hostname_and_port(local_name, + port_buffer, + nf_to_af(tcp_cc_request->ipfamily), + tcp_cc_request->port); + + local_res = complete_addrinfo(local_name, + local_name, + port_buffer, + nf_to_af(tcp_cc_request->ipfamily), + SOCK_STREAM, + IPPROTO_TCP, + 0); + + s_listen = create_data_socket(local_res); + + if (s_listen == INVALID_SOCKET) { + netperf_response.content.serv_errno = errno; + send_response(); + if (debug) { + fprintf(where,"could not create data socket\n"); + fflush(where); + } + exit(1); + } + +#ifdef WIN32 + /* The test timer can fire during operations on the listening socket, + so to make the start_timer below work we have to move + it to close s_listen while we are blocked on accept. */ + win_kludge_socket2 = s_listen; +#endif + + + /* Now, let's set-up the socket to listen for connections */ + if (listen(s_listen, 5) == SOCKET_ERROR) { + netperf_response.content.serv_errno = errno; + close(s_listen); + send_response(); + if (debug) { + fprintf(where,"could not listen\n"); + fflush(where); + } + exit(1); + } + + /* now get the port number assigned by the system */ + addrlen = sizeof(myaddr_in); + if (getsockname(s_listen, + (struct sockaddr *)&myaddr_in, + &addrlen) == SOCKET_ERROR){ + netperf_response.content.serv_errno = errno; + close(s_listen); + send_response(); + if (debug) { + fprintf(where,"could not geetsockname\n"); + fflush(where); + } + exit(1); + } + + /* Now myaddr_in contains the port and the internet address this is */ + /* returned to the sender also implicitly telling the sender that the */ + /* socket buffer sizing has been done. */ + + tcp_cc_response->data_port_number = + (int) ntohs(((struct sockaddr_in *)&myaddr_in)->sin_port); + if (debug) { + fprintf(where,"telling the remote to call me at %d\n", + tcp_cc_response->data_port_number); + fflush(where); + } + netperf_response.content.serv_errno = 0; + + /* But wait, there's more. If the initiator wanted cpu measurements, */ + /* then we must call the calibrate routine, which will return the max */ + /* rate back to the initiator. If the CPU was not to be measured, or */ + /* something went wrong with the calibration, we will return a 0.0 to */ + /* the initiator. */ + + tcp_cc_response->cpu_rate = (float)0.0; /* assume no cpu */ + if (tcp_cc_request->measure_cpu) { + tcp_cc_response->measure_cpu = 1; + tcp_cc_response->cpu_rate = + calibrate_local_cpu(tcp_cc_request->cpu_rate); + } + + + + /* before we send the response back to the initiator, pull some of */ + /* the socket parms from the globals */ + tcp_cc_response->send_buf_size = lss_size; + tcp_cc_response->recv_buf_size = lsr_size; + tcp_cc_response->no_delay = loc_nodelay; + tcp_cc_response->so_rcvavoid = loc_rcvavoid; + tcp_cc_response->so_sndavoid = loc_sndavoid; + + send_response(); + + addrlen = sizeof(peeraddr_in); + + /* Now it's time to start receiving data on the connection. We will */ + /* first grab the apropriate counters and then start grabbing. */ + + cpu_start(tcp_cc_request->measure_cpu); + + /* The loop will exit when the sender does a shutdown, which will */ + /* return a length of zero */ + + if (tcp_cc_request->test_length > 0) { + times_up = 0; + trans_remaining = 0; + start_timer(tcp_cc_request->test_length + PAD_TIME); + } + else { + times_up = 1; + trans_remaining = tcp_cc_request->test_length * -1; + } + + trans_received = 0; + + while ((!times_up) || (trans_remaining > 0)) { +#ifdef WIN32 + /* The test timer will probably fire during this accept, + so to make the start_timer above work we have to move + it to close s_listen while we are blocked on accept. */ + win_kludge_socket = s_listen; +#endif + /* accept a connection from the remote */ + if ((s_data=accept(s_listen, + (struct sockaddr *)&peeraddr_in, + &addrlen)) == INVALID_SOCKET) { + if (errno == EINTR) { + /* the timer popped */ + timed_out = 1; + break; + } + fprintf(where,"recv_tcp_cc: accept: errno = %d\n",errno); + fflush(where); + close(s_listen); + + exit(1); + } + +#ifdef KLUDGE_SOCKET_OPTIONS + /* this is for those systems which *INCORRECTLY* fail to pass */ + /* attributes across an accept() call. Including this goes against */ + /* my better judgement :( raj 11/95 */ + + kludge_socket_options(s_data); + +#endif /* KLUDGE_SOCKET_OPTIONS */ + +#ifdef WIN32 + /* this is used so the timer thread can close the socket out from */ + /* under us, which to date is the easiest/cleanest/least */ + /* Windows-specific way I can find to force the winsock calls to */ + /* return WSAEINTR with the test is over. anything that will run on */ + /* 95 and NT and is closer to what netperf expects from Unix signals */ + /* and such would be appreciated raj 1/96 */ + win_kludge_socket = s_data; +#endif /* WIN32 */ + + if (debug) { + fprintf(where,"recv_tcp_cc: accepted data connection.\n"); + fflush(where); + } + + + /* close the connection. the server will likely do a graceful */ + /* close of the connection, insuring that all data has arrived at */ + /* the client. for this it will call shutdown(), and then recv() and */ + /* then close(). I'm reasonably confident that this is the */ + /* appropriate sequence of calls - I would like to hear of */ + /* examples in web servers to the contrary. raj 10/95*/ + close(s_data); + + trans_received++; + if (trans_remaining) { + trans_remaining--; + } + + if (debug) { + fprintf(where, + "recv_tcp_cc: Transaction %d complete\n", + trans_received); + fflush(where); + } + + } + + + /* The loop now exits due to timeout or transaction count being */ + /* reached */ + + cpu_stop(tcp_cc_request->measure_cpu,&elapsed_time); + + if (timed_out) { + /* we ended the test by time, which was at least 2 seconds */ + /* longer than we wanted to run. so, we want to subtract */ + /* PAD_TIME from the elapsed_time. */ + elapsed_time -= PAD_TIME; + } + /* send the results to the sender */ + + if (debug) { + fprintf(where, + "recv_tcp_cc: got %d transactions\n", + trans_received); + fflush(where); + } + + tcp_cc_results->bytes_received = (trans_received * + (tcp_cc_request->request_size + + tcp_cc_request->response_size)); + tcp_cc_results->trans_received = trans_received; + tcp_cc_results->elapsed_time = elapsed_time; + if (tcp_cc_request->measure_cpu) { + tcp_cc_results->cpu_util = calc_cpu_util(elapsed_time); + } + + if (debug) { + fprintf(where, + "recv_tcp_cc: test complete, sending results.\n"); + fflush(where); + } + + send_response(); + +} + +void +print_sockets_usage() +{ + + fwrite(sockets_usage, sizeof(char), strlen(sockets_usage), stdout); + exit(1); + +} + +void +scan_sockets_args(int argc, char *argv[]) + +{ + +#define SOCKETS_ARGS "b:CDnNhH:L:m:M:p:P:r:s:S:T:Vw:W:z46" + + extern char *optarg; /* pointer to option string */ + + int c; + + char + arg1[BUFSIZ], /* argument holders */ + arg2[BUFSIZ]; + + if (debug) { + int i; + printf("%s called with the following argument vector\n", + __func__); + for (i = 0; i< argc; i++) { + printf("%s ",argv[i]); + } + printf("\n"); + } + + strncpy(local_data_port,"0",sizeof(local_data_port)); + strncpy(remote_data_port,"0",sizeof(remote_data_port)); + + /* Go through all the command line arguments and break them */ + /* out. For those options that take two parms, specifying only */ + /* the first will set both to that value. Specifying only the */ + /* second will leave the first untouched. To change only the */ + /* first, use the form "first," (see the routine break_args.. */ + + while ((c= getopt(argc, argv, SOCKETS_ARGS)) != EOF) { + switch (c) { + case '?': + case '4': + remote_data_family = AF_INET; + local_data_family = AF_INET; + break; + case '6': +#if defined(AF_INET6) + remote_data_family = AF_INET6; + local_data_family = AF_INET6; +#else + fprintf(stderr, + "This netperf was not compiled on an IPv6 capable host!\n"); + fflush(stderr); + exit(-1); +#endif + break; + case 'h': + print_sockets_usage(); + exit(1); + case 'b': +#ifdef WANT_FIRST_BURST + first_burst_size = atoi(optarg); +#else /* WANT_FIRST_BURST */ + printf("Initial request burst functionality not compiled-in!\n"); +#endif /* WANT_FIRST_BURST */ + break; + case 'C': +#ifdef TCP_CORK + /* set TCP_CORK */ + loc_tcpcork = 1; + rem_tcpcork = 1; /* however, at first, we ony have cork affect loc */ +#else + printf("WARNING: TCP_CORK not available on this platform!\n"); +#endif /* TCP_CORK */ + break; + case 'D': + /* set the TCP nodelay flag */ + loc_nodelay = 1; + rem_nodelay = 1; + break; + case 'H': + break_args_explicit(optarg,arg1,arg2); + if (arg1[0]) { + /* make sure we leave room for the NULL termination boys and + girls. raj 2005-02-82 */ + remote_data_address = malloc(strlen(arg1)+1); + strncpy(remote_data_address,arg1,strlen(arg1)); + } + if (arg2[0]) + remote_data_family = parse_address_family(arg2); + break; + case 'L': + break_args_explicit(optarg,arg1,arg2); + if (arg1[0]) { + /* make sure we leave room for the NULL termination boys and + girls. raj 2005-02-82 */ + local_data_address = malloc(strlen(arg1)+1); + strncpy(local_data_address,arg1,strlen(arg1)); + } + if (arg2[0]) + local_data_family = parse_address_family(arg2); + break; + case 's': + /* set local socket sizes */ + break_args(optarg,arg1,arg2); + if (arg1[0]) + lss_size_req = convert(arg1); + if (arg2[0]) + lsr_size_req = convert(arg2); + break; + case 'S': + /* set remote socket sizes */ + break_args(optarg,arg1,arg2); + if (arg1[0]) + rss_size_req = convert(arg1); + if (arg2[0]) + rsr_size_req = convert(arg2); + break; + case 'r': + /* set the request/response sizes */ + break_args(optarg,arg1,arg2); + if (arg1[0]) + req_size = convert(arg1); + if (arg2[0]) + rsp_size = convert(arg2); + break; + case 'm': + /* set the send size */ + send_size = convert(optarg); + break; + case 'M': + /* set the recv size */ + recv_size = convert(optarg); + break; + case 'n': + /* set the local socket type*/ + local_connected = 1; + break; + case 'N': + /* set the remote socket type*/ + remote_connected = 1; + break; + case 'p': + /* set the min and max port numbers for the TCP_CRR and TCP_TRR */ + /* tests. */ + break_args(optarg,arg1,arg2); + if (arg1[0]) + client_port_min = atoi(arg1); + if (arg2[0]) + client_port_max = atoi(arg2); + break; + case 'P': + /* set the local and remote data port numbers for the tests to + allow them to run through those blankety blank end-to-end + breaking firewalls. raj 2004-06-15 */ + break_args(optarg,arg1,arg2); + if (arg1[0]) + strncpy(local_data_port,arg1,sizeof(local_data_port)); + if (arg2[0]) + strncpy(remote_data_port,arg2,sizeof(remote_data_port)); + break; + case 't': + /* set the test name */ + strcpy(test_name,optarg); + break; + case 'W': + /* set the "width" of the user space data */ + /* buffer. This will be the number of */ + /* send_size buffers malloc'd in the */ + /* *_STREAM test. It may be enhanced to set */ + /* both send and receive "widths" but for now */ + /* it is just the sending *_STREAM. */ + send_width = convert(optarg); + break; + case 'V' : + /* we want to do copy avoidance and will set */ + /* it for everything, everywhere, if we really */ + /* can. of course, we don't know anything */ + /* about the remote... */ +#ifdef SO_SND_COPYAVOID + loc_sndavoid = 1; +#else + loc_sndavoid = 0; + printf("Local send copy avoidance not available.\n"); +#endif +#ifdef SO_RCV_COPYAVOID + loc_rcvavoid = 1; +#else + loc_rcvavoid = 0; + printf("Local recv copy avoidance not available.\n"); +#endif + rem_sndavoid = 1; + rem_rcvavoid = 1; + break; + }; + } + +#if defined(WANT_FIRST_BURST) +#if defined(WANT_HISTOGRAM) + /* if WANT_FIRST_BURST and WANT_HISTOGRAM are defined and the user + indeed wants a non-zero first burst size, and we would emit a + histogram, then we should emit a warning that the two are not + compatible. raj 2006-01-31 */ + if ((first_burst_size > 0) && (verbosity >= 2)) { + fprintf(stderr, + "WARNING! Histograms and first bursts are incompatible!\n"); + fflush(stderr); + } +#endif +#endif + + /* we do not want to make remote_data_address non-NULL because if + the user has not specified a remote adata address, we want to + take it from the hostname in the -H global option. raj + 2005-02-08 */ + + /* so, if there is to be no control connection, we want to have some + different settings for a few things */ + + if (no_control) { + + if (strcmp(remote_data_port,"0") == 0) { + /* we need to select either the discard port, echo port or + chargen port dedepending on the test name. raj 2007-02-08 */ + if (strstr(test_name,"STREAM") || + strstr(test_name,"SENDFILE")) { + strncpy(remote_data_port,"discard",sizeof(remote_data_port)); + } + else if (strstr(test_name,"RR")) { + strncpy(remote_data_port,"echo",sizeof(remote_data_port)); + } + else if (strstr(test_name,"MAERTS")) { + strncpy(remote_data_port,"chargen",sizeof(remote_data_port)); + } + else { + printf("No default port known for the %s test, please set one yourself\n",test_name); + exit(-1); + } + } + remote_data_port[sizeof(remote_data_port) - 1] = '\0'; + + /* I go back and forth on whether these should become -1 or if + they should become 0 for a no_control test. what do you think? + raj 2006-02-08 */ + + rem_rcvavoid = -1; + rem_sndavoid = -1; + rss_size_req = -1; + rsr_size_req = -1; + rem_nodelay = -1; + + if (strstr(test_name,"STREAM") || + strstr(test_name,"SENDFILE")) { + recv_size = -1; + } + else if (strstr(test_name,"RR")) { + /* I am however _certain_ that for a no control RR test the + response size must equal the request size since 99 times out + of ten we will be speaking to the echo service somewhere */ + rsp_size = req_size; + } + else if (strstr(test_name,"MAERTS")) { + send_size = -1; + } + else { + printf("No default port known for the %s test, please set one yourself\n",test_name); + exit(-1); + } + } +} diff --git a/src/nettest_bsd.h b/src/nettest_bsd.h new file mode 100644 index 0000000..12cc0c2 --- /dev/null +++ b/src/nettest_bsd.h @@ -0,0 +1,635 @@ +/* + Copyright (C) 1993-2004 Hewlett-Packard Company +*/ + + /* This file contains the test-specific definitions for netperf's BSD */ + /* sockets tests */ + +/* well boys and girls, seems that while AF_INET is "2" and AF_UNSPEC + is "0" the world over, AF_INET6 is different values depending on + the platform... grrr. On HP-UX 11i it is "22" and on Linux 2.6 it + is "10" sooooo... we have to define our own space for netperf to + enable us to pass values around from machine to machine. raj + 2005-02-08 */ +#define NF_UNSPEC 0 +#define NF_INET 4 +#define NF_INET6 6 + +/* it would also seem that the socket type defines differ from + platform to platform, which means we need to define our own values + to pass between netperf and netserver so they can be translated to + the local versions. NST == Netperf Socket Type raj 2008-01-14 */ +#define NST_UNKN -1 +#define NST_STREAM 1 +#define NST_DGRAM 2 +#define NST_DCCP 3 + + +#ifdef WANT_OMNI +struct omni_request_struct { + int32_t send_buf_size; /* SO_SNDBUF */ + uint32_t send_size; /* bytes per send() call */ + uint32_t send_alignment; /* alignment of send buffer */ + uint32_t send_offset; /* offset from send alignment */ + uint32_t send_width; /* number of send buffers to use */ + int32_t request_size; /* size of a request */ + + int32_t recv_buf_size; /* SO_RCVBUF */ + uint32_t receive_size; /* size of buffers in recv */ + uint32_t recv_alignment; /* alignment of recv buffer */ + uint32_t recv_offset; /* offset from recv alignment */ + uint32_t recv_width; /* number of recv buffers to use */ + int32_t response_size; /* size of a response */ + + uint32_t no_delay; /* do we set mumble_NODELAY? */ + uint32_t use_sendfile; /* use sendfile rather than send? */ + uint32_t connect_test; /* does the test include connect? */ + + uint32_t measure_cpu; /* do we measure CPU? */ + float cpu_rate; /* do we know how fast the cpu is already? */ + + int32_t test_length; /* how long is the test? */ + + uint32_t so_rcvavoid; /* avoid copies on recv? */ + uint32_t so_sndavoid; /* avoid copies on send? */ + uint32_t send_dirty_count; /* bytes to dirty before calling send */ + uint32_t recv_dirty_count; /* bytes to dirty before calling recv */ + uint32_t recv_clean_count; /* bytes to access before calling recv */ + + uint32_t checksum_off; /* should checksums be disabled? */ + uint32_t data_port; /* what port number should netserver use? */ + uint32_t ipfamily; /* address family of the data connection */ + uint32_t socket_type; /* dgram? stream? other? */ + uint32_t protocol; /* the protocol of the data connection */ + uint32_t direction; /* which way flows the data? */ + uint32_t netperf_port; /* when netserver needs netperf's data port */ + uint32_t interval_burst;/* how many things to do each interval */ + uint32_t interval_usecs;/* how long each interval should be */ + uint32_t ipaddr[4]; /* when netserver needs netperf's data IP */ +}; + +struct omni_response_struct { + int32_t recv_buf_size; + uint32_t receive_size; + int32_t recv_width; + + int32_t send_buf_size; + uint32_t send_size; + int32_t send_width; + + uint32_t no_delay; + uint32_t use_sendfile; + + uint32_t measure_cpu; + float cpu_rate; + + uint32_t test_length; + + uint32_t so_rcvavoid; + uint32_t so_sndavoid; + + uint32_t data_port; /* connect to this port number */ + + uint32_t interval_burst;/* how many things to do each interval */ + uint32_t interval_usecs;/* how long each interval should be */ + /* there are 16 ints above here, and we have 248 - (16*4) or 184 bytes + remaining */ + /* these are here because they can be checked before actual data + connections are made, and the omni_results_struct is already + full */ + uint32_t cpu_frequency; /* this should be megahertz */ + uint32_t security_info; +#define OMNI_RESPONSE_CONV_CUTOFF 18 + char system_model[33]; + char cpu_model[80]; /* seems like an awful lot doesn't + it. some clever person at Intel + decided to give Montecito processors a + name that long - and still didn't + include the 9NNN model number! */ + char security_string[16]; + /* 48 bytes left */ + +}; + +struct omni_results_struct { + uint32_t bytes_received_hi; /* why? because we cannot easily send */ + uint32_t bytes_received_lo; /* uint64_t or doubles between endianess */ + uint32_t recv_calls; + int32_t recv_buf_size; /* SO_RCVBUF at end of test */ + + uint32_t bytes_sent_hi; + uint32_t bytes_sent_lo; + uint32_t send_calls; + int32_t send_buf_size; /* SO_SNDBUF at end of test */ + uint32_t failed_sends; + uint32_t trans_received; + + float elapsed_time; /* length of test in seconds */ + + float cpu_util; + float serv_dem; + uint32_t cpu_method; /* how was CPU util measured? */ + uint32_t num_cpus; /* number of CPUs in remote */ + + int32_t peak_cpu_id; /* ID of the most utilized CPU */ + float peak_cpu_util; /* its individual utilization */ + int32_t vendor; + int32_t device; /* pci device id of the probable egress + interface */ + int32_t subvendor; + int32_t subdevice; + #define OMNI_RESULTS_CONF_CUTOFF 21 + /* this is the 22dn 32-bit word and we have 248-(17*4) bytes + available from here */ + char ifname[16]; /* the probable egress interface */ + char driver[32]; /* size based on linux/ethtool.h */ + char version[32]; + char firmware[32]; + char bus[32]; + char ifslot[16]; /* slot id of the probable egress interface */ + /* only 4 bytes left... */ +}; + +#endif /* WANT_OMNI */ + +struct tcp_stream_request_struct { + int send_buf_size; + int recv_buf_size; /* how big does the client want it - the */ + /* receive socket buffer that is */ + int receive_size; /* how many bytes do we want to receive at one */ + /* time? */ + int recv_alignment; /* what is the alignment of the receive */ + /* buffer? */ + int recv_offset; /* and at what offset from that alignment? */ + int no_delay; /* do we disable the nagle algorithm for send */ + /* coalescing? */ + int measure_cpu; /* does the client want server cpu utilization */ + /* measured? */ + float cpu_rate; /* do we know how fast the cpu is already? */ + int test_length; /* how long is the test? */ + int so_rcvavoid; /* do we want the remote to avoid copies on */ + /* receives? */ + int so_sndavoid; /* do we want the remote to avoid send copies? */ + int dirty_count; /* how many integers in the receive buffer */ + /* should be made dirty before calling recv? */ + int clean_count; /* how many integers should be read from the */ + /* recv buffer before calling recv? */ + int port; /* the port to which the recv side should bind + to allow netperf to run through those evil + firewall things */ + int ipfamily; /* the address family of ipaddress */ +}; + +struct tcp_stream_response_struct { + int recv_buf_size; /* how big does the client want it */ + int receive_size; + int no_delay; + int measure_cpu; /* does the client want server cpu */ + int test_length; /* how long is the test? */ + int send_buf_size; + int data_port_number; /* connect to me here */ + float cpu_rate; /* could we measure */ + int so_rcvavoid; /* could the remote avoid receive copies? */ + int so_sndavoid; /* could the remote avoid send copies? */ +}; + +struct tcp_stream_results_struct { + double bytes_received; + unsigned int recv_calls; + float elapsed_time; /* how long the test ran */ + float cpu_util; /* -1 if not measured */ + float serv_dem; /* -1 if not measured */ + int cpu_method; /* how was cpu util measured? */ + int num_cpus; /* how many CPUs had the remote? */ + int recv_buf_size; /* how large was it at the end? */ + int send_buf_size; /* how large was it at the end? */ +}; + +struct tcp_maerts_request_struct { + int send_buf_size; + int recv_buf_size; /* how big does the client want it - the */ + /* receive socket buffer that is */ + int send_size; /* how many bytes do we want netserver to send + at one time? */ + int send_alignment; /* what is the alignment of the send */ + /* buffer? */ + int send_offset; /* and at what offset from that alignment? */ + int no_delay; /* do we disable the nagle algorithm for send */ + /* coalescing? */ + int measure_cpu; /* does the client want server cpu utilization */ + /* measured? */ + float cpu_rate; /* do we know how fast the cpu is already? */ + int test_length; /* how long is the test? */ + int so_rcvavoid; /* do we want the remote to avoid copies on */ + /* receives? */ + int so_sndavoid; /* do we want the remote to avoid send copies? */ + int dirty_count; /* how many integers in the send buffer */ + /* should be made dirty before calling recv? */ + int clean_count; /* how many integers should be read from the */ + /* recv buffer before calling recv? */ + int port; /* the port to which the recv side should bind + to allow netperf to run through those evil + firewall things */ + int ipfamily; +}; + +struct tcp_maerts_response_struct { + int recv_buf_size; /* how big does the client want it */ + int send_size; + int no_delay; + int measure_cpu; /* does the client want server cpu */ + int test_length; /* how long is the test? */ + int send_buf_size; + int data_port_number; /* connect to me here */ + float cpu_rate; /* could we measure */ + int so_rcvavoid; /* could the remote avoid receive copies? */ + int so_sndavoid; /* could the remote avoid send copies? */ +}; + +struct tcp_maerts_results_struct { + double bytes_sent; + unsigned int send_calls; + float elapsed_time; /* how long the test ran */ + float cpu_util; /* -1 if not measured */ + float serv_dem; /* -1 if not measured */ + int cpu_method; /* how was cpu util measured? */ + int num_cpus; /* how many CPUs had the remote? */ +}; + +struct tcp_rr_request_struct { + int recv_buf_size; /* how big does the client want it */ + int send_buf_size; + int recv_alignment; + int recv_offset; + int send_alignment; + int send_offset; + int request_size; + int response_size; + int no_delay; + int measure_cpu; /* does the client want server cpu */ + float cpu_rate; /* do we know how fast the cpu is? */ + int test_length; /* how long is the test? */ + int so_rcvavoid; /* do we want the remote to avoid receive */ + /* copies? */ + int so_sndavoid; /* do we want the remote to avoid send copies? */ + int port; /* the port to which the recv side should bind + to allow netperf to run through those evil + firewall things */ + int ipfamily; +}; + +struct tcp_rr_response_struct { + int recv_buf_size; /* how big does the client want it */ + int no_delay; + int measure_cpu; /* does the client want server cpu */ + int test_length; /* how long is the test? */ + int send_buf_size; + int data_port_number; /* connect to me here */ + float cpu_rate; /* could we measure */ + int so_rcvavoid; /* could the remote avoid receive copies? */ + int so_sndavoid; /* could the remote avoid send copies? */ +}; + +struct tcp_rr_results_struct { + unsigned int bytes_received; /* ignored initially */ + unsigned int recv_calls; /* ignored initially */ + unsigned int trans_received; /* not ignored */ + float elapsed_time; /* how long the test ran */ + float cpu_util; /* -1 if not measured */ + float serv_dem; /* -1 if not measured */ + int cpu_method; /* how was cpu util measured? */ + int num_cpus; /* how many CPUs had the remote? */ +}; + +struct tcp_conn_rr_request_struct { + int recv_buf_size; /* how big does the client want it */ + int send_buf_size; + int recv_alignment; + int recv_offset; + int send_alignment; + int send_offset; + int request_size; + int response_size; + int no_delay; + int measure_cpu; /* does the client want server cpu */ + float cpu_rate; /* do we know how fast the cpu is? */ + int test_length; /* how long is the test? */ + int so_rcvavoid; /* do we want the remote to avoid receive */ + /* copies? */ + int so_sndavoid; /* do we want the remote to avoid send copies? */ + int port; /* the port to which the recv side should bind + to allow netperf to run through those evil + firewall things */ + int ipfamily; +}; + + +struct tcp_conn_rr_response_struct { + int recv_buf_size; /* how big does the client want it */ + int no_delay; + int measure_cpu; /* does the client want server cpu */ + int test_length; /* how long is the test? */ + int send_buf_size; + int data_port_number; /* connect to me here */ + float cpu_rate; /* could we measure */ + int so_rcvavoid; /* could the remote avoid receive copies? */ + int so_sndavoid; /* could the remote avoid send copies? */ +}; + +struct tcp_conn_rr_results_struct { + unsigned int bytes_received; /* ignored initially */ + unsigned int recv_calls; /* ignored initially */ + unsigned int trans_received; /* not ignored */ + float elapsed_time; /* how long the test ran */ + float cpu_util; /* -1 if not measured */ + float serv_dem; /* -1 if not measured */ + int cpu_method; /* how was cpu util measured? */ + int num_cpus; /* how many CPUs had the remote? */ +}; + +struct tcp_tran_rr_request_struct { + int recv_buf_size; /* how big does the client want it */ + int send_buf_size; + int recv_alignment; + int recv_offset; + int send_alignment; + int send_offset; + int request_size; + int response_size; + int no_delay; + int measure_cpu; /* does the client want server cpu */ + float cpu_rate; /* do we know how fast the cpu is? */ + int test_length; /* how long is the test? */ + int so_rcvavoid; /* do we want the remote to avoid receive */ + /* copies? */ + int so_sndavoid; /* do we want the remote to avoid send copies? */ + int port; /* the port to which the recv side should bind + to allow netperf to run through those evil + firewall things */ + int ipfamily; +}; + + +struct tcp_tran_rr_response_struct { + int recv_buf_size; /* how big does the client want it */ + int no_delay; + int measure_cpu; /* does the client want server cpu */ + int test_length; /* how long is the test? */ + int send_buf_size; + int data_port_number; /* connect to me here */ + float cpu_rate; /* could we measure */ + int so_rcvavoid; /* could the remote avoid receive copies? */ + int so_sndavoid; /* could the remote avoid send copies? */ +}; + +struct tcp_tran_rr_results_struct { + unsigned int bytes_received; /* ignored initially */ + unsigned int recv_calls; /* ignored initially */ + unsigned int trans_received; /* not ignored */ + float elapsed_time; /* how long the test ran */ + float cpu_util; /* -1 if not measured */ + float serv_dem; /* -1 if not measured */ + int cpu_method; /* how was cpu util measured? */ + int num_cpus; /* how many CPUs had the remote? */ + +}; + +struct udp_stream_request_struct { + int recv_buf_size; + int message_size; + int recv_connected; + int recv_alignment; + int recv_offset; + int checksum_off; + int measure_cpu; + float cpu_rate; + int test_length; + int so_rcvavoid; /* do we want the remote to avoid receive */ + /* copies? */ + int so_sndavoid; /* do we want the remote to avoid send copies? */ + int port; /* the port to which the recv side should bind + to allow netperf to run through those evil + firewall things */ + int ipfamily; + +}; + +struct udp_stream_response_struct { + int recv_buf_size; + int send_buf_size; + int measure_cpu; + int test_length; + int data_port_number; + float cpu_rate; + int so_rcvavoid; /* could the remote avoid receive copies? */ + int so_sndavoid; /* could the remote avoid send copies? */ +}; + +struct udp_stream_results_struct { + unsigned int messages_recvd; + unsigned int bytes_received; + float elapsed_time; + float cpu_util; + int cpu_method; /* how was cpu util measured? */ + int num_cpus; /* how many CPUs had the remote? */ +}; + + +struct udp_rr_request_struct { + int recv_buf_size; /* how big does the client want it */ + int send_buf_size; + int recv_alignment; + int recv_offset; + int send_alignment; + int send_offset; + int request_size; + int response_size; + int no_delay; + int measure_cpu; /* does the client want server cpu */ + float cpu_rate; /* do we know how fast the cpu is? */ + int test_length; /* how long is the test? */ + int so_rcvavoid; /* do we want the remote to avoid receive */ + /* copies? */ + int so_sndavoid; /* do we want the remote to avoid send copies? */ + int port; /* the port to which the recv side should bind + to allow netperf to run through those evil + firewall things */ + int ipfamily; +}; + +struct udp_rr_response_struct { + int recv_buf_size; /* how big does the client want it */ + int no_delay; + int measure_cpu; /* does the client want server cpu */ + int test_length; /* how long is the test? */ + int send_buf_size; + int data_port_number; /* connect to me here */ + float cpu_rate; /* could we measure */ + int so_rcvavoid; /* could the remote avoid receive copies? */ + int so_sndavoid; /* could the remote avoid send copies? */ +}; + +struct udp_rr_results_struct { + unsigned int bytes_received; /* ignored initially */ + unsigned int recv_calls; /* ignored initially */ + unsigned int trans_received; /* not ignored */ + float elapsed_time; /* how long the test ran */ + float cpu_util; /* -1 if not measured */ + float serv_dem; /* -1 if not measured */ + int cpu_method; /* how was cpu util measured? */ + int num_cpus; /* how many CPUs had the remote? */ +}; + +struct tcp_cc_request_struct { + int recv_buf_size; /* how big does the client want it */ + int send_buf_size; + int recv_alignment; + int recv_offset; + int send_alignment; + int send_offset; + int request_size; + int response_size; + int no_delay; + int measure_cpu; /* does the client want server cpu */ + float cpu_rate; /* do we know how fast the cpu is? */ + int test_length; /* how long is the test? */ + int so_rcvavoid; /* do we want the remote to avoid receive */ + /* copies? */ + int so_sndavoid; /* do we want the remote to avoid send copies? */ + int port; /* the port to which the recv side should bind + to allow netperf to run through those evil + firewall things */ + int ipfamily; +}; + + +struct tcp_cc_response_struct { + int recv_buf_size; /* how big does the client want it */ + int no_delay; + int measure_cpu; /* does the client want server cpu */ + int test_length; /* how long is the test? */ + int send_buf_size; + int data_port_number; /* connect to me here */ + float cpu_rate; /* could we measure */ + int so_rcvavoid; /* could the remote avoid receive copies? */ + int so_sndavoid; /* could the remote avoid send copies? */ +}; + +struct tcp_cc_results_struct { + unsigned int bytes_received; /* ignored initially */ + unsigned int recv_calls; /* ignored initially */ + unsigned int trans_received; /* not ignored */ + float elapsed_time; /* how long the test ran */ + float cpu_util; /* -1 if not measured */ + float serv_dem; /* -1 if not measured */ + int cpu_method; /* how was cpu util measured? */ + int num_cpus; /* how many CPUs had the remote? */ +}; + +extern int + socket_type, /* initially used by the "omni" tests */ + rss_size_req, /* requested remote socket send buffer size */ + rsr_size_req, /* requested remote socket recv buffer size */ + rss_size, /* remote socket send buffer size */ + rsr_size, /* remote socket recv buffer size */ + rsr_size_end, + rss_size_end, + lss_size_req, /* requested local socket send buffer size */ + lsr_size_req, /* requested local socket recv buffer size */ + lss_size, /* local socket send buffer size */ + lsr_size, /* local socket recv buffer size */ + lss_size_end, + lsr_size_end, + req_size, /* request size */ + rsp_size, /* response size */ + send_size, /* how big are individual sends */ + recv_size, /* how big are individual receives */ + loc_nodelay, /* don't/do use NODELAY locally */ + rem_nodelay, /* don't/do use NODELAY remotely */ + loc_sndavoid, /* avoid send copies locally */ + loc_rcvavoid, /* avoid recv copies locally */ + rem_sndavoid, /* avoid send copies remotely */ + rem_rcvavoid; /* avoid recv_copies remotely */ + + +#ifdef WANT_OMNI +extern void scan_omni_args(int argc, char *argv[]); +#endif +extern void scan_sockets_args(int argc, char *argv[]); +extern struct addrinfo *complete_addrinfo(char *controlhost, + char *data_address, + char *port, + int family, + int type, + int protocol, + int flags); +extern void complete_addrinfos(struct addrinfo **remote, + struct addrinfo **local, + char remote_host[], + int type, + int protocol, + int flags); +extern int af_to_nf(int af); +extern int nf_to_af(int nf); +extern int nst_to_hst(int nst); +extern int hst_to_nst(int hst); +extern char *hst_to_str(int hst); +extern char *protocol_to_str(int protocol); +extern void print_top_test_header(char test_name[], + struct addrinfo *source, + struct addrinfo *destination); +extern void set_port_number(struct addrinfo *res, + unsigned short port); +extern void set_hostname_and_port(char *hostname, + char *portstr, + int family, + int port); +extern void set_sockaddr_family_addr_port(struct sockaddr_storage *sockaddr, + int family, + void *addr, + int port); +extern int get_sockaddr_family_addr_port(struct sockaddr_storage *sockaddr, + int family, + void *addr, + int *port); +extern void send_tcp_mss(char remote_host[]); +extern void send_tcp_stream(char remote_host[]); +extern void send_tcp_maerts(char remote_host[]); +extern void send_tcp_rr(char remote_host[]); +extern void send_tcp_conn_rr(char remote_host[]); +extern void send_tcp_cc(char remote_host[]); +extern void send_udp_stream(char remote_host[]); +extern void send_udp_rr(char remote_host[]); + +extern void send_omni(char remote_host[]); +extern void print_uuid(char remote_host[]); +extern void recv_omni(); + +extern void recv_tcp_stream(); +extern void recv_tcp_maerts(); +extern void recv_tcp_rr(); +extern void recv_tcp_conn_rr(); +extern void recv_tcp_cc(); +extern void recv_udp_stream(); +extern void recv_udp_rr(); + +extern void loc_cpu_rate(); +extern void rem_cpu_rate(); + +#ifdef HAVE_ICSC_EXS +extern void send_exs_tcp_stream(char remotehost[]); +#endif /* HAVE_ICSC_EXS */ + +#ifdef HAVE_SENDFILE +extern void sendfile_tcp_stream(char remotehost[]); +#endif /* HAVE_SENDFILE */ + +#if !defined(HAVE_STRUCT_SOCKADDR_STORAGE) && !defined(sockaddr_storage) +#define sockaddr_storage sockaddr_in +#endif + +#ifdef DO_NBRR +extern void send_tcp_nbrr(char remote_host[]); + +extern void recv_tcp_nbrr(); +#endif diff --git a/src/nettest_dlpi.c b/src/nettest_dlpi.c new file mode 100644 index 0000000..ab3e79f --- /dev/null +++ b/src/nettest_dlpi.c @@ -0,0 +1,3798 @@ + +/****************************************************************/ +/* */ +/* nettest_dlpi.c */ +/* */ +/* the actual test routines... */ +/* */ +/* send_dlpi_co_stream() perform a CO DLPI stream test */ +/* recv_dlpi_co_stream() */ +/* send_dlpi_co_rr() perform a CO DLPI req/res */ +/* recv_dlpi_co_rr() */ +/* send_dlpi_cl_stream() perform a CL DLPI stream test */ +/* recv_dlpi_cl_stream() */ +/* send_dlpi_cl_rr() perform a CL DLPI req/res */ +/* recv_dlpi_cl_rr() */ +/* */ +/****************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef WANT_DLPI +char nettest_dlpi_id[]="\ +@(#)nettest_dlpi.c (c) Copyright 1993,1995,2004 Hewlett-Packard Co. Version 2.4.3"; + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef __osf__ +#include +#else /* __osf__ */ +#include +#ifdef __hpux__ +#include +#endif /* __hpux__ */ +#endif /* __osf__ */ + +#include "netlib.h" +#include "netsh.h" +#include "nettest_dlpi.h" + +/* these are some variables global to all the DLPI tests. declare */ +/* them static to make them global only to this file */ + +static int + rsw_size, /* remote send window size */ + rrw_size, /* remote recv window size */ + lsw_size, /* local send window size */ + lrw_size, /* local recv window size */ + req_size = 100, /* request size */ + rsp_size = 200, /* response size */ + send_size, /* how big are individual sends */ + recv_size; /* how big are individual receives */ + +int + loc_ppa = 4, /* the ppa for the local interface, */ + /* as shown as the NM Id in lanscan */ + rem_ppa = 4, /* the ppa for the remote interface */ + dlpi_sap = 84; /* which 802.2 SAP should we use? */ + +char loc_dlpi_device[32] = "/dev/dlpi"; +char rem_dlpi_device[32] = "/dev/dlpi"; + +char dlpi_usage[] = "\n\ +Usage: netperf [global options] -- [test options] \n\ +\n\ +CO/CL DLPI Test Options:\n\ + -D dev[,dev] Set the local/remote DLPI device file name\n\ + -h Display this text\n\ + -M bytes Set the recv size (DLCO_STREAM, DLCL_STREAM)\n\ + -m bytes Set the send size (DLCO_STREAM, DLCL_STREAM)\n\ + -p loc[,rem] Set the local/remote PPA for the test\n\ + -R bytes Set response size (DLCO_RR, DLCL_RR)\n\ + -r bytes Set request size (DLCO_RR, DLCL_RR)\n\ + -s sap Set the 802.2 sap for the test\n\ + -W send[,recv] Set remote send/recv window sizes\n\ + -w send[,recv] Set local send/recv window sizes\n\ +\n\ +For those options taking two parms, at least one must be specified;\n\ +specifying one value without a comma will set both parms to that\n\ +value, specifying a value with a leading comma will set just the second\n\ +parm, a value with a trailing comma will set just the first. To set\n\ +each parm to unique values, specify both and separate them with a\n\ +comma.\n"; + + +/* This routine implements the CO unidirectional data transfer test */ +/* (a.k.a. stream) for the sockets interface. It receives its */ +/* parameters via global variables from the shell and writes its */ +/* output to the standard output. */ + + +void +send_dlpi_co_stream() +{ + + char *tput_title = "\ +Recv Send Send \n\ +Window Window Message Elapsed \n\ +Size Size Size Time Throughput \n\ +frames frames bytes secs. %s/sec \n\n"; + + char *tput_fmt_0 = + "%7.2f\n"; + + char *tput_fmt_1 = + "%5d %5d %6d %-6.2f %7.2f \n"; + + char *cpu_title = "\ +Recv Send Send Utilization Service Demand\n\ +Window Window Message Elapsed Send Recv Send Recv\n\ +Size Size Size Time Throughput local remote local remote\n\ +frames frames bytes secs. %-8.8s/s %% %% us/KB us/KB\n\n"; + + char *cpu_fmt_0 = + "%6.3f\n"; + + char *cpu_fmt_1 = + "%5d %5d %6d %-6.2f %7.2f %-6.2f %-6.2f %-6.3f %-6.3f\n"; + + char *ksink_fmt = "\n\ +Alignment Offset %-8.8s %-8.8s Sends %-8.8s Recvs\n\ +Local Remote Local Remote Xfered Per Per\n\ +Send Recv Send Recv Send (avg) Recv (avg)\n\ +%5d %5d %5d %5d %6.4g %6.2f %6d %6.2f %6d\n"; + + + float elapsed_time; + +#ifdef WANT_INTERVALS + int interval_count; +#endif /* WANT_INTERVALS */ + + /* what we want is to have a buffer space that is at least one */ + /* send-size greater than our send window. this will insure that we */ + /* are never trying to re-use a buffer that may still be in the hands */ + /* of the transport. This buffer will be malloc'd after we have found */ + /* the size of the local senc socket buffer. We will want to deal */ + /* with alignment and offset concerns as well. */ + + struct ring_elt *send_ring; + char *message; + char *message_ptr; + struct strbuf send_message; + char dlsap[BUFSIZ]; + int dlsap_len; + int *message_int_ptr; + int message_offset; + int malloc_size; + + int len; + int nummessages; + int send_descriptor; + int bytes_remaining; + /* with links like fddi, one can send > 32 bits worth of bytes */ + /* during a test... ;-) */ + double bytes_sent; + +#ifdef DIRTY + int i; +#endif /* DIRTY */ + + float local_cpu_utilization; + float local_service_demand; + float remote_cpu_utilization; + float remote_service_demand; + double thruput; + + struct dlpi_co_stream_request_struct *dlpi_co_stream_request; + struct dlpi_co_stream_response_struct *dlpi_co_stream_response; + struct dlpi_co_stream_results_struct *dlpi_co_stream_result; + + dlpi_co_stream_request = + (struct dlpi_co_stream_request_struct *)netperf_request.content.test_specific_data; + dlpi_co_stream_response = + (struct dlpi_co_stream_response_struct *)netperf_response.content.test_specific_data; + dlpi_co_stream_result = + (struct dlpi_co_stream_results_struct *)netperf_response.content.test_specific_data; + + if ( print_headers ) { + fprintf(where,"DLPI CO STREAM TEST\n"); + if (local_cpu_usage || remote_cpu_usage) + fprintf(where,cpu_title,format_units()); + else + fprintf(where,tput_title,format_units()); + } + + /* initialize a few counters */ + + nummessages = 0; + bytes_sent = 0.0; + times_up = 0; + + /*set up the data descriptor */ + send_descriptor = dl_open(loc_dlpi_device,loc_ppa); + if (send_descriptor < 0){ + perror("netperf: send_dlpi_co_stream: dlpi stream data descriptor"); + exit(1); + } + + /* bind the puppy and get the assigned dlsap */ + dlsap_len = BUFSIZ; + if (dl_bind(send_descriptor, + dlpi_sap, DL_CODLS, dlsap, &dlsap_len) != 0) { + fprintf(where,"send_dlpi_co_rr: bind failure\n"); + fflush(where); + exit(1); + } + + if (debug) { + fprintf(where,"send_dlpi_co_stream: send_descriptor obtained...\n"); + } + +#ifdef DL_HP_SET_LOCAL_WIN_REQ + if (lsw_size > 0) { + if (debug > 1) { + fprintf(where,"netperf: send_dlpi_co_stream: window send size altered from system default...\n"); + fprintf(where," send: %d\n",lsw_size); + } + } + if (lrw_size > 0) { + if (debug > 1) { + fprintf(where, + "netperf: send_dlpi_co_stream: window recv size altered from system default...\n"); + fprintf(where," recv: %d\n",lrw_size); + } + } + + + /* Now, we will find-out what the size actually became, and report */ + /* that back to the user. If the call fails, we will just report a -1 */ + /* back to the initiator for the recv buffer size. */ + + + if (debug) { + fprintf(where, + "netperf: send_dlpi_co_stream: window sizes determined...\n"); + fprintf(where," send: %d recv: %d\n",lsw_size,lrw_size); + ffluch(where); + } + +#else /* DL_HP_SET_LOCAL_WIN_REQ */ + + lsw_size = -1; + lrw_size = -1; + +#endif /* DL_HP_SET_LOCAL_WIN_REQ */ + + /* we should pick a default send_size, it should not be larger than */ + /* the min of the two interface MTU's, and should perhaps default to */ + /* the Interface MTU, but for now, we will default it to 1024... if */ + /* someone wants to change this, the should change the corresponding */ + /* lines in the recv_dlpi_co_stream routine */ + + if (send_size == 0) { + send_size = 1024; + } + + /* set-up the data buffer with the requested alignment and offset. */ + /* After we have calculated the proper starting address, we want to */ + /* put that back into the message variable so we go back to the */ + /* proper place. note that this means that only the first send is */ + /* guaranteed to be at the alignment specified by the -a parameter. I */ + /* think that this is a little more "real-world" than what was found */ + /* in previous versions. note also that we have allocated a quantity */ + /* of memory that is at least one send-size greater than our socket */ + /* buffer size. We want to be sure that there are at least two */ + /* buffers allocated - this can be a bit of a problem when the */ + /* send_size is bigger than the socket size, so we must check... the */ + /* user may have wanted to explicitly set the "width" of our send */ + /* buffers, we should respect that wish... */ + if (send_width == 0) { + send_width = (lsw_size/send_size) + 1; + if (send_width == 1) send_width++; + } + + send_ring = allocate_buffer_ring(send_width, + send_size, + local_send_align, + local_send_offset); + + send_message.maxlen = send_size; + send_message.len = send_size; + send_message.buf = send_ring->buffer_ptr; + + /* If the user has requested cpu utilization measurements, we must */ + /* calibrate the cpu(s). We will perform this task within the tests */ + /* themselves. If the user has specified the cpu rate, then */ + /* calibrate_local_cpu will return rather quickly as it will have */ + /* nothing to do. If local_cpu_rate is zero, then we will go through */ + /* all the "normal" calibration stuff and return the rate back.*/ + + if (local_cpu_usage) { + local_cpu_rate = calibrate_local_cpu(local_cpu_rate); + } + + /* Tell the remote end to do a listen. The server alters the socket */ + /* paramters on the other side at this point, hence the reason for */ + /* all the values being passed in the setup message. If the user did */ + /* not specify any of the parameters, they will be passed as 0, which */ + /* will indicate to the remote that no changes beyond the system's */ + /* default should be used. */ + + netperf_request.content.request_type = DO_DLPI_CO_STREAM; + dlpi_co_stream_request->send_win_size = rsw_size; + dlpi_co_stream_request->recv_win_size = rrw_size; + dlpi_co_stream_request->receive_size = recv_size; + dlpi_co_stream_request->recv_alignment= remote_recv_align; + dlpi_co_stream_request->recv_offset = remote_recv_offset; + dlpi_co_stream_request->measure_cpu = remote_cpu_usage; + dlpi_co_stream_request->cpu_rate = remote_cpu_rate; + dlpi_co_stream_request->ppa = rem_ppa; + dlpi_co_stream_request->sap = dlpi_sap; + dlpi_co_stream_request->dev_name_len = strlen(rem_dlpi_device); + strcpy(dlpi_co_stream_request->dlpi_device, + rem_dlpi_device); + +#ifdef __alpha + + /* ok - even on a DEC box, strings are strings. I didn't really want */ + /* to ntohl the words of a string. since I don't want to teach the */ + /* send_ and recv_ _request and _response routines about the types, */ + /* I will put "anti-ntohl" calls here. I imagine that the "pure" */ + /* solution would be to use XDR, but I am still leary of being able */ + /* to find XDR libs on all platforms I want running netperf. raj */ + { + int *charword; + int *initword; + int *lastword; + + initword = (int *) dlpi_co_stream_request->dlpi_device; + lastword = initword + ((strlen(rem_dlpi_device) + 3) / 4); + + for (charword = initword; + charword < lastword; + charword++) { + + *charword = ntohl(*charword); + } + } +#endif /* __alpha */ + + if (test_time) { + dlpi_co_stream_request->test_length = test_time; + } + else { + dlpi_co_stream_request->test_length = test_bytes; + } +#ifdef DIRTY + dlpi_co_stream_request->dirty_count = rem_dirty_count; + dlpi_co_stream_request->clean_count = rem_clean_count; +#endif /* DIRTY */ + + + if (debug > 1) { + fprintf(where, + "netperf: send_dlpi_co_stream: requesting DLPI CO stream test\n"); + } + + send_request(); + + /* The response from the remote will contain all of the relevant */ + /* parameters for this test type. We will put them back into */ + /* the variables here so they can be displayed if desired. The */ + /* remote will have calibrated CPU if necessary, and will have done */ + /* all the needed set-up we will have calibrated the cpu locally */ + /* before sending the request, and will grab the counter value right */ + /* after the connect returns. The remote will grab the counter right */ + /* after the accept call. This saves the hassle of extra messages */ + /* being sent for the TCP tests. */ + + recv_response(); + + if (!netperf_response.content.serv_errno) { + if (debug) + fprintf(where,"remote listen done.\n"); + rrw_size = dlpi_co_stream_response->recv_win_size; + rsw_size = dlpi_co_stream_response->send_win_size; + remote_cpu_usage= dlpi_co_stream_response->measure_cpu; + remote_cpu_rate = dlpi_co_stream_response->cpu_rate; + } + else { + Set_errno(netperf_response.content.serv_errno); + perror("netperf: remote error"); + exit(1); + } + + /* Connect up to the remote port on the data descriptor */ + if(dl_connect(send_descriptor, + dlpi_co_stream_response->station_addr, + dlpi_co_stream_response->station_addr_len) != 0) { + fprintf(where,"recv_dlpi_co_stream: connect failure\n"); + fflush(where); + exit(1); + } + + /* Data Socket set-up is finished. If there were problems, either the */ + /* connect would have failed, or the previous response would have */ + /* indicated a problem. I failed to see the value of the extra */ + /* message after the accept on the remote. If it failed, we'll see it */ + /* here. If it didn't, we might as well start pumping data. */ + + /* Set-up the test end conditions. For a stream test, they can be */ + /* either time or byte-count based. */ + + if (test_time) { + /* The user wanted to end the test after a period of time. */ + times_up = 0; + bytes_remaining = 0; + start_timer(test_time); + } + else { + /* The tester wanted to send a number of bytes. */ + bytes_remaining = test_bytes; + times_up = 1; + } + + /* The cpu_start routine will grab the current time and possibly */ + /* value of the idle counter for later use in measuring cpu */ + /* utilization and/or service demand and thruput. */ + + cpu_start(local_cpu_usage); + + /* We use an "OR" to control test execution. When the test is */ + /* controlled by time, the byte count check will always return false. */ + /* When the test is controlled by byte count, the time test will */ + /* always return false. When the test is finished, the whole */ + /* expression will go false and we will stop sending data. */ + +#ifdef DIRTY + /* initialize the random number generator for putting dirty stuff */ + /* into the send buffer. raj */ + srand((int) getpid()); +#endif /* DIRTY */ + + while ((!times_up) || (bytes_remaining > 0)) { + +#ifdef DIRTY + /* we want to dirty some number of consecutive integers in the buffer */ + /* we are about to send. we may also want to bring some number of */ + /* them cleanly into the cache. The clean ones will follow any dirty */ + /* ones into the cache. */ + message_int_ptr = (int *)message_ptr; + for (i = 0; i < loc_dirty_count; i++) { + *message_int_ptr = rand(); + message_int_ptr++; + } + for (i = 0; i < loc_clean_count; i++) { + loc_dirty_count = *message_int_ptr; + message_int_ptr++; + } +#endif /* DIRTY */ + + if((putmsg(send_descriptor, + 0, + &send_message, + 0)) != 0) { + if (errno == EINTR) + break; + perror("netperf: data send error"); + exit(1); + } + send_ring = send_ring->next; + send_message.buf = send_ring->buffer_ptr; +#ifdef WANT_INTERVALS + for (interval_count = 0; + interval_count < interval_wate; + interval_count++); +#endif /* WANT_INTERVALS */ + + if (debug > 4) { + fprintf(where,"netperf: send_clpi_co_stream: putmsg called "); + fprintf(where,"len is %d\n",send_message.len); + fflush(where); + } + + nummessages++; + if (bytes_remaining) { + bytes_remaining -= send_size; + } + } + + /* The test is over. Flush the buffers to the remote end. We do a */ + /* graceful release to insure that all data has been taken by the */ + /* remote. this needs a little work - there is no three-way */ + /* handshake with type two as there is with TCP, so there really */ + /* should be a message exchange here. however, we will finesse it by */ + /* saying that the tests shoudl run for a while. */ + + if (debug) { + fprintf(where,"sending test end signal \n"); + fflush(where); + } + + send_message.len = (send_size - 1); + if (send_message.len == 0) send_message.len = 2; + + if((putmsg(send_descriptor, + 0, + &send_message, + 0)) != 0) { + perror("netperf: data send error"); + exit(1); + } + + /* this call will always give us the elapsed time for the test, and */ + /* will also store-away the necessaries for cpu utilization */ + + cpu_stop(local_cpu_usage,&elapsed_time); /* was cpu being measured? */ + /* how long did we really run? */ + + /* Get the statistics from the remote end. The remote will have */ + /* calculated service demand and all those interesting things. If it */ + /* wasn't supposed to care, it will return obvious values. */ + + recv_response(); + if (!netperf_response.content.serv_errno) { + if (debug) + fprintf(where,"remote results obtained\n"); + } + else { + Set_errno(netperf_response.content.serv_errno); + perror("netperf: remote error"); + + exit(1); + } + + /* We now calculate what our thruput was for the test. In the future, */ + /* we may want to include a calculation of the thruput measured by */ + /* the remote, but it should be the case that for a TCP stream test, */ + /* that the two numbers should be *very* close... We calculate */ + /* bytes_sent regardless of the way the test length was controlled. */ + /* If it was time, we needed to, and if it was by bytes, the user may */ + /* have specified a number of bytes that wasn't a multiple of the */ + /* send_size, so we really didn't send what he asked for ;-) */ + + bytes_sent = ((double) send_size * (double) nummessages) + (double) len; + thruput = calc_thruput(bytes_sent); + + if (local_cpu_usage || remote_cpu_usage) { + /* We must now do a little math for service demand and cpu */ + /* utilization for the system(s) */ + /* Of course, some of the information might be bogus because */ + /* there was no idle counter in the kernel(s). We need to make */ + /* a note of this for the user's benefit...*/ + if (local_cpu_usage) { + if (local_cpu_rate == 0.0) { + fprintf(where, + "WARNING WARNING WARNING WARNING WARNING WARNING WARNING!\n"); + fprintf(where, + "Local CPU usage numbers based on process information only!\n"); + fflush(where); + } + local_cpu_utilization = calc_cpu_util(0.0); + local_service_demand = calc_service_demand(bytes_sent, + 0.0, + 0.0, + 0); + } + else { + local_cpu_utilization = -1.0; + local_service_demand = -1.0; + } + + if (remote_cpu_usage) { + if (remote_cpu_rate == 0.0) { + fprintf(where, + "DANGER DANGER DANGER DANGER DANGER DANGER DANGER!\n"); + fprintf(where, + "Remote CPU usage numbers based on process information only!\n"); + fflush(where); + } + remote_cpu_utilization = dlpi_co_stream_result->cpu_util; + remote_service_demand = calc_service_demand(bytes_sent, + 0.0, + remote_cpu_utilization, + dlpi_co_stream_result->num_cpus); + } + else { + remote_cpu_utilization = -1.0; + remote_service_demand = -1.0; + } + + /* We are now ready to print all the information. If the user */ + /* has specified zero-level verbosity, we will just print the */ + /* local service demand, or the remote service demand. If the */ + /* user has requested verbosity level 1, he will get the basic */ + /* "streamperf" numbers. If the user has specified a verbosity */ + /* of greater than 1, we will display a veritable plethora of */ + /* background information from outside of this block as it it */ + /* not cpu_measurement specific... */ + + switch (verbosity) { + case 0: + if (local_cpu_usage) { + fprintf(where, + cpu_fmt_0, + local_service_demand); + } + else { + fprintf(where, + cpu_fmt_0, + remote_service_demand); + } + break; + case 1: + case 2: + fprintf(where, + cpu_fmt_1, /* the format string */ + rrw_size, /* remote recvbuf size */ + lsw_size, /* local sendbuf size */ + send_size, /* how large were the sends */ + elapsed_time, /* how long was the test */ + thruput, /* what was the xfer rate */ + local_cpu_utilization, /* local cpu */ + remote_cpu_utilization, /* remote cpu */ + local_service_demand, /* local service demand */ + remote_service_demand); /* remote service demand */ + break; + } + } + else { + /* The tester did not wish to measure service demand. */ + switch (verbosity) { + case 0: + fprintf(where, + tput_fmt_0, + thruput); + break; + case 1: + case 2: + fprintf(where, + tput_fmt_1, /* the format string */ + rrw_size, /* remote recvbuf size */ + lsw_size, /* local sendbuf size */ + send_size, /* how large were the sends */ + elapsed_time, /* how long did it take */ + thruput);/* how fast did it go */ + break; + } + } + + /* it would be a good thing to include information about some of the */ + /* other parameters that may have been set for this test, but at the */ + /* moment, I do not wish to figure-out all the formatting, so I will */ + /* just put this comment here to help remind me that it is something */ + /* that should be done at a later time. */ + + if (verbosity > 1) { + /* The user wanted to know it all, so we will give it to him. */ + /* This information will include as much as we can find about */ + /* TCP statistics, the alignments of the sends and receives */ + /* and all that sort of rot... */ + + fprintf(where, + ksink_fmt, + "Bytes", + "Bytes", + "Bytes", + local_send_align, + remote_recv_align, + local_send_offset, + remote_recv_offset, + bytes_sent, + bytes_sent / (double)nummessages, + nummessages, + bytes_sent / (double)dlpi_co_stream_result->recv_calls, + dlpi_co_stream_result->recv_calls); + } + +} + + +/* This is the server-side routine for the tcp stream test. It is */ +/* implemented as one routine. I could break things-out somewhat, but */ +/* didn't feel it was necessary. */ + +int + recv_dlpi_co_stream() +{ + + int data_descriptor; + int flags = 0; + int measure_cpu; + int bytes_received; + int receive_calls; + float elapsed_time; + + struct ring_elt *recv_ring; + char *message_ptr; + char *message; + int *message_int_ptr; + struct strbuf recv_message; + int dirty_count; + int clean_count; + int i; + + struct dlpi_co_stream_request_struct *dlpi_co_stream_request; + struct dlpi_co_stream_response_struct *dlpi_co_stream_response; + struct dlpi_co_stream_results_struct *dlpi_co_stream_results; + + dlpi_co_stream_request = (struct dlpi_co_stream_request_struct *)netperf_request.content.test_specific_data; + dlpi_co_stream_response = (struct dlpi_co_stream_response_struct *)netperf_response.content.test_specific_data; + dlpi_co_stream_results = (struct dlpi_co_stream_results_struct *)netperf_response.content.test_specific_data; + + if (debug) { + fprintf(where,"netserver: recv_dlpi_co_stream: entered...\n"); + fflush(where); + } + + /* We want to set-up the listen socket with all the desired */ + /* parameters and then let the initiator know that all is ready. If */ + /* socket size defaults are to be used, then the initiator will have */ + /* sent us 0's. If the socket sizes cannot be changed, then we will */ + /* send-back what they are. If that information cannot be determined, */ + /* then we send-back -1's for the sizes. If things go wrong for any */ + /* reason, we will drop back ten yards and punt. */ + + /* If anything goes wrong, we want the remote to know about it. It */ + /* would be best if the error that the remote reports to the user is */ + /* the actual error we encountered, rather than some bogus unexpected */ + /* response type message. */ + + netperf_response.content.response_type = DLPI_CO_STREAM_RESPONSE; + + /* We now alter the message_ptr variable to be at the desired */ + /* alignment with the desired offset. */ + + if (debug > 1) { + fprintf(where,"recv_dlpi_co_stream: requested alignment of %d\n", + dlpi_co_stream_request->recv_alignment); + fflush(where); + } + + + /* Grab a descriptor to listen on, and then listen on it. */ + + if (debug > 1) { + fprintf(where,"recv_dlpi_co_stream: grabbing a descriptor...\n"); + fflush(where); + } + + + +#ifdef __alpha + + /* ok - even on a DEC box, strings are strings. I din't really want */ + /* to ntohl the words of a string. since I don't want to teach the */ + /* send_ and recv_ _request and _response routines about the types, */ + /* I will put "anti-ntohl" calls here. I imagine that the "pure" */ + /* solution would be to use XDR, but I am still leary of being able */ + /* to find XDR libs on all platforms I want running netperf. raj */ + { + int *charword; + int *initword; + int *lastword; + + initword = (int *) dlpi_co_stream_request->dlpi_device; + lastword = initword + ((dlpi_co_stream_request->dev_name_len + 3) / 4); + + for (charword = initword; + charword < lastword; + charword++) { + + *charword = htonl(*charword); + } + } +#endif /* __alpha */ + + data_descriptor = dl_open(dlpi_co_stream_request->dlpi_device, + dlpi_co_stream_request->ppa); + if (data_descriptor < 0) { + netperf_response.content.serv_errno = errno; + send_response(); + exit(1); + } + + /* Let's get an address assigned to this descriptor so we can tell the */ + /* initiator how to reach the data descriptor. There may be a desire to */ + /* nail this descriptor to a specific address in a multi-homed, */ + /* multi-connection situation, but for now, we'll ignore the issue */ + /* and concentrate on single connection testing. */ + + /* bind the sap and retrieve the dlsap assigned by the system */ + dlpi_co_stream_response->station_addr_len = 14; /* arbitrary */ + if (dl_bind(data_descriptor, + dlpi_co_stream_request->sap, + DL_CODLS, + (char *)dlpi_co_stream_response->station_addr, + &dlpi_co_stream_response->station_addr_len) != 0) { + fprintf(where,"recv_dlpi_co_stream: bind failure\n"); + fflush(where); + exit(1); + } + + /* The initiator may have wished-us to modify the socket buffer */ + /* sizes. We should give it a shot. If he didn't ask us to change the */ + /* sizes, we should let him know what sizes were in use at this end. */ + /* If none of this code is compiled-in, then we will tell the */ + /* initiator that we were unable to play with the socket buffer by */ + /* setting the size in the response to -1. */ + +#ifdef DL_HP_SET_LOCAL_WIN_REQ + + if (dlpi_co_stream_request->recv_win_size) { + } + /* Now, we will find-out what the size actually became, and report */ + /* that back to the user. If the call fails, we will just report a -1 */ + /* back to the initiator for the recv buffer size. */ + +#else /* the system won't let us play with the buffers */ + + dlpi_co_stream_response->recv_win_size = -1; + +#endif /* DL_HP_SET_LOCAL_WIN_REQ */ + + /* what sort of sizes did we end-up with? */ + /* this bit of code whould default to the Interface MTU */ + if (dlpi_co_stream_request->receive_size == 0) { + recv_size = 1024; + } + else { + recv_size = dlpi_co_stream_request->receive_size; + } + + /* tell the other fellow what our receive size became */ + dlpi_co_stream_response->receive_size = recv_size; + + /* just a little prep work for when we may have to behave like the */ + /* sending side... */ + message = (char *)malloc(recv_size * 2); + if (message == NULL) { + printf("malloc(%d) failed!\n", recv_size * 2); + exit(1); + } + + message_ptr = ALIGN_BUFFER(message, dlpi_co_stream_request->recv_alignment, dlpi_co_stream_request->recv_offset); + recv_message.maxlen = recv_size; + recv_message.len = 0; + recv_message.buf = message_ptr; + + if (debug > 1) { + fprintf(where, + "recv_dlpi_co_stream: receive alignment and offset set...\n"); + fflush(where); + } + + netperf_response.content.serv_errno = 0; + + /* But wait, there's more. If the initiator wanted cpu measurements, */ + /* then we must call the calibrate routine, which will return the max */ + /* rate back to the initiator. If the CPU was not to be measured, or */ + /* something went wrong with the calibration, we will return a -1 to */ + /* the initiator. */ + + dlpi_co_stream_response->cpu_rate = 0.0; /* assume no cpu */ + if (dlpi_co_stream_request->measure_cpu) { + dlpi_co_stream_response->measure_cpu = 1; + dlpi_co_stream_response->cpu_rate = + calibrate_local_cpu(dlpi_co_stream_request->cpu_rate); + } + + send_response(); + + /* accept a connection on this file descriptor. at some point, */ + /* dl_accept will "do the right thing" with the last two parms, but */ + /* for now it ignores them, so we will pass zeros. */ + + if(dl_accept(data_descriptor, 0, 0) != 0) { + fprintf(where, + "recv_dlpi_co_stream: error in accept, errno %d\n", + errno); + fflush(where); + netperf_response.content.serv_errno = errno; + send_response(); + exit(1); + } + + if (debug) { + fprintf(where,"netserver:recv_dlpi_co_stream: connection accepted\n"); + fflush(where); + } + + /* Now it's time to start receiving data on the connection. We will */ + /* first grab the apropriate counters and then start grabbing. */ + + cpu_start(dlpi_co_stream_request->measure_cpu); + +#ifdef DIRTY + /* we want to dirty some number of consecutive integers in the buffer */ + /* we are about to recv. we may also want to bring some number of */ + /* them cleanly into the cache. The clean ones will follow any dirty */ + /* ones into the cache. */ + + dirty_count = dlpi_co_stream_request->dirty_count; + clean_count = dlpi_co_stream_request->clean_count; + message_int_ptr = (int *)message_ptr; + for (i = 0; i < dirty_count; i++) { + *message_int_ptr = rand(); + message_int_ptr++; + } + for (i = 0; i < clean_count; i++) { + dirty_count = *message_int_ptr; + message_int_ptr++; + } +#endif /* DIRTY */ + + recv_message.len = recv_size; + while (recv_message.len == recv_size) { + if (getmsg(data_descriptor, + 0, + &recv_message, + &flags) != 0) { + netperf_response.content.serv_errno = errno; + send_response(); + exit(1); + } + bytes_received += recv_message.len; + receive_calls++; + + if (debug) { + fprintf(where, + "netserver:recv_dlpi_co_stream: getmsg accepted %d bytes\n", + recv_message.len); + fflush(where); + } + + +#ifdef DIRTY + message_int_ptr = (int *)message_ptr; + for (i = 0; i < dirty_count; i++) { + *message_int_ptr = rand(); + message_int_ptr++; + } + for (i = 0; i < clean_count; i++) { + dirty_count = *message_int_ptr; + message_int_ptr++; + } +#endif /* DIRTY */ + + } + + /* The loop now exits due to zero bytes received. */ + /* should perform a disconnect to signal the sender that */ + /* we have received all the data sent. */ + + if (close(data_descriptor) == -1) { + netperf_response.content.serv_errno = errno; + send_response(); + exit(1); + } + + cpu_stop(dlpi_co_stream_request->measure_cpu,&elapsed_time); + + /* send the results to the sender */ + + if (debug) { + fprintf(where, + "recv_dlpi_co_stream: got %d bytes\n", + bytes_received); + fprintf(where, + "recv_dlpi_co_stream: got %d recvs\n", + receive_calls); + fflush(where); + } + + dlpi_co_stream_results->bytes_received = bytes_received; + dlpi_co_stream_results->elapsed_time = elapsed_time; + dlpi_co_stream_results->recv_calls = receive_calls; + + if (dlpi_co_stream_request->measure_cpu) { + dlpi_co_stream_results->cpu_util = calc_cpu_util(0.0); + }; + + if (debug > 1) { + fprintf(where, + "recv_dlpi_co_stream: test complete, sending results.\n"); + fflush(where); + } + + send_response(); +} + +/*********************************/ + +int send_dlpi_co_rr(char remote_host[]) +{ + + char *tput_title = "\ + Local /Remote\n\ + Window Size Request Resp. Elapsed Trans.\n\ + Send Recv Size Size Time Rate \n\ + frames frames bytes bytes secs. per sec \n\n"; + + char *tput_fmt_0 = + "%7.2f\n"; + + char *tput_fmt_1_line_1 = "\ + %-6d %-6d %-6d %-6d %-6.2f %7.2f \n"; + char *tput_fmt_1_line_2 = "\ + %-6d %-6d\n"; + + char *cpu_title = "\ + Local /Remote\n\ + Window Size Request Resp. Elapsed Trans. CPU CPU S.dem S.dem\n\ + Send Recv Size Size Time Rate local remote local remote\n\ + frames frames bytes bytes secs. per sec %% %% us/Tr us/Tr\n\n"; + + char *cpu_fmt_0 = + "%6.3f\n"; + + char *cpu_fmt_1_line_1 = "\ + %-6d %-6d %-6d %-6d %-6.2f %-6.2f %-6.2f %-6.2f %-6.3f %-6.3f\n"; + + char *cpu_fmt_1_line_2 = "\ + %-6d %-6d\n"; + + char *ksink_fmt = "\ + Alignment Offset\n\ + Local Remote Local Remote\n\ + Send Recv Send Recv\n\ + %5d %5d %5d %5d\n"; + + + int timed_out = 0; + float elapsed_time; + int dlsap_len; + char dlsap[BUFSIZ]; + + int flags = 0; + char *send_message_ptr; + char *recv_message_ptr; + char *temp_message_ptr; + struct strbuf send_message; + struct strbuf recv_message; + + int nummessages; + int send_descriptor; + int trans_remaining; + double bytes_xferd; + + int rsp_bytes_left; + + /* we assume that station adresses fit within two ints */ + unsigned int remote_address[1]; + + float local_cpu_utilization; + float local_service_demand; + float remote_cpu_utilization; + float remote_service_demand; + double thruput; + + struct dlpi_co_rr_request_struct *dlpi_co_rr_request; + struct dlpi_co_rr_response_struct *dlpi_co_rr_response; + struct dlpi_co_rr_results_struct *dlpi_co_rr_result; + + dlpi_co_rr_request = + (struct dlpi_co_rr_request_struct *)netperf_request.content.test_specific_data; + dlpi_co_rr_response = + (struct dlpi_co_rr_response_struct *)netperf_response.content.test_specific_data; + dlpi_co_rr_result = + (struct dlpi_co_rr_results_struct *)netperf_response.content.test_specific_data; + + /* since we are now disconnected from the code that established the */ + /* control socket, and since we want to be able to use different */ + /* protocols and such, we are passed the name of the remote host and */ + /* must turn that into the test specific addressing information. */ + + if ( print_headers ) { + fprintf(where,"DLPI CO REQUEST/RESPONSE TEST\n"); + if (local_cpu_usage || remote_cpu_usage) + fprintf(where,cpu_title,format_units()); + else + fprintf(where,tput_title,format_units()); + } + + /* initialize a few counters */ + + nummessages = 0; + bytes_xferd = 0.0; + times_up = 0; + + /* set-up the data buffers with the requested alignment and offset */ + temp_message_ptr = (char *)malloc(req_size+MAXALIGNMENT+MAXOFFSET); + if (temp_message_ptr == NULL) { + printf("malloc(%d) failed!\n", req_size+MAXALIGNMENT+MAXOFFSET); + exit(1); + } + send_message_ptr = (char *)(( (long) temp_message_ptr + + (long) local_send_align - 1) & + ~((long) local_send_align - 1)); + send_message_ptr = send_message_ptr + local_send_offset; + send_message.maxlen = req_size+MAXALIGNMENT+MAXOFFSET; + send_message.len = req_size; + send_message.buf = send_message_ptr; + + temp_message_ptr = (char *)malloc(rsp_size+MAXALIGNMENT+MAXOFFSET); + if (temp_message_ptr == NULL) { + printf("malloc(%d) failed!\n", rsp_size+MAXALIGNMENT+MAXOFFSET); + exit(1); + } + recv_message_ptr = (char *)(( (long) temp_message_ptr + + (long) local_recv_align - 1) & + ~((long) local_recv_align - 1)); + recv_message_ptr = recv_message_ptr + local_recv_offset; + recv_message.maxlen = rsp_size+MAXALIGNMENT+MAXOFFSET; + recv_message.len = 0; + recv_message.buf = send_message_ptr; + + /*set up the data socket */ + + send_descriptor = dl_open(loc_dlpi_device,loc_ppa); + if (send_descriptor < 0){ + perror("netperf: send_dlpi_co_rr: tcp stream data descriptor"); + exit(1); + } + + if (debug) { + fprintf(where,"send_dlpi_co_rr: send_descriptor obtained...\n"); + } + + /* bind the puppy and get the assigned dlsap */ + + dlsap_len = BUFSIZ; + if (dl_bind(send_descriptor, + dlpi_sap, DL_CODLS, dlsap, &dlsap_len) != 0) { + fprintf(where,"send_dlpi_co_rr: bind failure\n"); + fflush(where); + exit(1); + } + + /* Modify the local socket size. The reason we alter the send buffer */ + /* size here rather than when the connection is made is to take care */ + /* of decreases in buffer size. Decreasing the window size after */ + /* connection establishment is a TCP no-no. Also, by setting the */ + /* buffer (window) size before the connection is established, we can */ + /* control the TCP MSS (segment size). The MSS is never more that 1/2 */ + /* the minimum receive buffer size at each half of the connection. */ + /* This is why we are altering the receive buffer size on the sending */ + /* size of a unidirectional transfer. If the user has not requested */ + /* that the socket buffers be altered, we will try to find-out what */ + /* their values are. If we cannot touch the socket buffer in any way, */ + /* we will set the values to -1 to indicate that. */ + +#ifdef DL_HP_SET_LOCAL_WIN_REQ + if (lsw_size > 0) { + if (debug > 1) { + fprintf(where,"netperf: send_dlpi_co_rr: socket send size altered from system default...\n"); + fprintf(where," send: %d\n",lsw_size); + } + } + if (lrw_size > 0) { + if (debug > 1) { + fprintf(where,"netperf: send_dlpi_co_rr: socket recv size altered from system default...\n"); + fprintf(where," recv: %d\n",lrw_size); + } + } + + + /* Now, we will find-out what the size actually became, and report */ + /* that back to the user. If the call fails, we will just report a -1 */ + /* back to the initiator for the recv buffer size. */ + + + if (debug) { + fprintf(where,"netperf: send_dlpi_co_rr: socket sizes determined...\n"); + fprintf(where," send: %d recv: %d\n",lsw_size,lrw_size); + } + +#else /* DL_HP_SET_LOCAL_WIN_REQ */ + + lsw_size = -1; + lrw_size = -1; + +#endif /* DL_HP_SET_LOCAL_WIN_REQ */ + + /* If the user has requested cpu utilization measurements, we must */ + /* calibrate the cpu(s). We will perform this task within the tests */ + /* themselves. If the user has specified the cpu rate, then */ + /* calibrate_local_cpu will return rather quickly as it will have */ + /* nothing to do. If local_cpu_rate is zero, then we will go through */ + /* all the "normal" calibration stuff and return the rate back.*/ + + if (local_cpu_usage) { + local_cpu_rate = calibrate_local_cpu(local_cpu_rate); + } + + /* Tell the remote end to do a listen. The server alters the socket */ + /* paramters on the other side at this point, hence the reason for */ + /* all the values being passed in the setup message. If the user did */ + /* not specify any of the parameters, they will be passed as 0, which */ + /* will indicate to the remote that no changes beyond the system's */ + /* default should be used. Alignment is the exception, it will */ + /* default to 8, which will be no alignment alterations. */ + + netperf_request.content.request_type = DO_DLPI_CO_RR; + dlpi_co_rr_request->recv_win_size = rrw_size; + dlpi_co_rr_request->send_win_size = rsw_size; + dlpi_co_rr_request->recv_alignment = remote_recv_align; + dlpi_co_rr_request->recv_offset = remote_recv_offset; + dlpi_co_rr_request->send_alignment = remote_send_align; + dlpi_co_rr_request->send_offset = remote_send_offset; + dlpi_co_rr_request->request_size = req_size; + dlpi_co_rr_request->response_size = rsp_size; + dlpi_co_rr_request->measure_cpu = remote_cpu_usage; + dlpi_co_rr_request->cpu_rate = remote_cpu_rate; + dlpi_co_rr_request->ppa = rem_ppa; + dlpi_co_rr_request->sap = dlpi_sap; + dlpi_co_rr_request->dev_name_len = strlen(rem_dlpi_device); + strcpy(dlpi_co_rr_request->dlpi_device, + rem_dlpi_device); +#ifdef __alpha + + /* ok - even on a DEC box, strings are strings. I din't really want */ + /* to ntohl the words of a string. since I don't want to teach the */ + /* send_ and recv_ _request and _response routines about the types, */ + /* I will put "anti-ntohl" calls here. I imagine that the "pure" */ + /* solution would be to use XDR, but I am still leary of being able */ + /* to find XDR libs on all platforms I want running netperf. raj */ + { + int *charword; + int *initword; + int *lastword; + + initword = (int *) dlpi_co_rr_request->dlpi_device; + lastword = initword + ((strlen(rem_dlpi_device) + 3) / 4); + + for (charword = initword; + charword < lastword; + charword++) { + + *charword = ntohl(*charword); + } + } +#endif /* __alpha */ + + if (test_time) { + dlpi_co_rr_request->test_length = test_time; + } + else { + dlpi_co_rr_request->test_length = test_trans * -1; + } + + if (debug > 1) { + fprintf(where,"netperf: send_dlpi_co_rr: requesting TCP stream test\n"); + } + + send_request(); + + /* The response from the remote will contain all of the relevant */ + /* socket parameters for this test type. We will put them back into */ + /* the variables here so they can be displayed if desired. The */ + /* remote will have calibrated CPU if necessary, and will have done */ + /* all the needed set-up we will have calibrated the cpu locally */ + /* before sending the request, and will grab the counter value right */ + /* after the connect returns. The remote will grab the counter right */ + /* after the accept call. This saves the hassle of extra messages */ + /* being sent for the TCP tests. */ + + recv_response(); + + if (!netperf_response.content.serv_errno) { + if (debug) + fprintf(where,"remote listen done.\n"); + rrw_size = dlpi_co_rr_response->recv_win_size; + rsw_size = dlpi_co_rr_response->send_win_size; + remote_cpu_usage= dlpi_co_rr_response->measure_cpu; + remote_cpu_rate = dlpi_co_rr_response->cpu_rate; + + } + else { + Set_errno(netperf_response.content.serv_errno); + perror("netperf: remote error"); + + exit(1); + } + + /*Connect up to the remote port on the data descriptor */ + + if(dl_connect(send_descriptor, + dlpi_co_rr_response->station_addr, + dlpi_co_rr_response->station_addr_len) != 0) { + fprintf(where,"send_dlpi_co_rr: connect failure\n"); + fflush(where); + exit(1); + } + + /* Data Socket set-up is finished. If there were problems, either the */ + /* connect would have failed, or the previous response would have */ + /* indicated a problem. I failed to see the value of the extra */ + /* message after the accept on the remote. If it failed, we'll see it */ + /* here. If it didn't, we might as well start pumping data. */ + + /* Set-up the test end conditions. For a request/response test, they */ + /* can be either time or transaction based. */ + + if (test_time) { + /* The user wanted to end the test after a period of time. */ + times_up = 0; + trans_remaining = 0; + start_timer(test_time); + } + else { + /* The tester wanted to send a number of bytes. */ + trans_remaining = test_bytes; + times_up = 1; + } + + /* The cpu_start routine will grab the current time and possibly */ + /* value of the idle counter for later use in measuring cpu */ + /* utilization and/or service demand and thruput. */ + + cpu_start(local_cpu_usage); + + /* We use an "OR" to control test execution. When the test is */ + /* controlled by time, the byte count check will always return false. */ + /* When the test is controlled by byte count, the time test will */ + /* always return false. When the test is finished, the whole */ + /* expression will go false and we will stop sending data. I think I */ + /* just arbitrarily decrement trans_remaining for the timed test, but */ + /* will not do that just yet... One other question is whether or not */ + /* the send buffer and the receive buffer should be the same buffer. */ + + while ((!times_up) || (trans_remaining > 0)) { + /* send the request */ + if((putmsg(send_descriptor, + 0, + &send_message, + 0)) != 0) { + if (errno == EINTR) { + /* we hit the end of a */ + /* timed test. */ + timed_out = 1; + break; + } + perror("send_dlpi_co_rr: putmsg error"); + exit(1); + } + + if (debug) { + fprintf(where,"recv_message.len %d\n",recv_message.len); + fprintf(where,"send_message.len %d\n",send_message.len); + fflush(where); + } + + /* receive the response */ + /* this needs some work with streams buffers if we are going to */ + /* support requests and responses larger than the MTU of the */ + /* network, but this can wait until later */ + rsp_bytes_left = rsp_size; + recv_message.len = rsp_size; + while(rsp_bytes_left > 0) { + if((getmsg(send_descriptor, + 0, + &recv_message, + &flags)) < 0) { + if (errno == EINTR) { + /* We hit the end of a timed test. */ + timed_out = 1; + break; + } + perror("send_dlpi_co_rr: data recv error"); + exit(1); + } + rsp_bytes_left -= recv_message.len; + } + + if (timed_out) { + /* we may have been in a nested while loop - we need */ + /* another call to break. */ + break; + } + + nummessages++; + if (trans_remaining) { + trans_remaining--; + } + + if (debug > 3) { + fprintf(where, + "Transaction %d completed\n", + nummessages); + fflush(where); + } + } + + /* At this point we used to call shutdown onthe data socket to be */ + /* sure all the data was delivered, but this was not germane in a */ + /* request/response test, and it was causing the tests to "hang" when */ + /* they were being controlled by time. So, I have replaced this */ + /* shutdown call with a call to close that can be found later in the */ + /* procedure. */ + + /* this call will always give us the elapsed time for the test, and */ + /* will also store-away the necessaries for cpu utilization */ + + cpu_stop(local_cpu_usage,&elapsed_time); /* was cpu being measured? */ + /* how long did we really run? */ + + /* Get the statistics from the remote end. The remote will have */ + /* calculated service demand and all those interesting things. If it */ + /* wasn't supposed to care, it will return obvious values. */ + + recv_response(); + if (!netperf_response.content.serv_errno) { + if (debug) + fprintf(where,"remote results obtained\n"); + } + else { + Set_errno(netperf_response.content.serv_errno); + perror("netperf: remote error"); + + exit(1); + } + + /* We now calculate what our thruput was for the test. In the future, */ + /* we may want to include a calculation of the thruput measured by */ + /* the remote, but it should be the case that for a TCP stream test, */ + /* that the two numbers should be *very* close... We calculate */ + /* bytes_sent regardless of the way the test length was controlled. */ + /* If it was time, we needed to, and if it was by bytes, the user may */ + /* have specified a number of bytes that wasn't a multiple of the */ + /* send_size, so we really didn't send what he asked for ;-) We use */ + /* Kbytes/s as the units of thruput for a TCP stream test, where K = */ + /* 1024. A future enhancement *might* be to choose from a couple of */ + /* unit selections. */ + + bytes_xferd = (req_size * nummessages) + (rsp_size * nummessages); + thruput = calc_thruput(bytes_xferd); + + if (local_cpu_usage || remote_cpu_usage) { + /* We must now do a little math for service demand and cpu */ + /* utilization for the system(s) */ + /* Of course, some of the information might be bogus because */ + /* there was no idle counter in the kernel(s). We need to make */ + /* a note of this for the user's benefit...*/ + if (local_cpu_usage) { + if (local_cpu_rate == 0.0) { + fprintf(where,"WARNING WARNING WARNING WARNING WARNING WARNING WARNING!\n"); + fprintf(where,"Local CPU usage numbers based on process information only!\n"); + fflush(where); + } + local_cpu_utilization = calc_cpu_util(0.0); + /* since calc_service demand is doing ms/Kunit we will */ + /* multiply the number of transaction by 1024 to get */ + /* "good" numbers */ + local_service_demand = calc_service_demand((double) nummessages*1024, + 0.0, + 0.0, + 0); + } + else { + local_cpu_utilization = -1.0; + local_service_demand = -1.0; + } + + if (remote_cpu_usage) { + if (remote_cpu_rate == 0.0) { + fprintf(where,"DANGER DANGER DANGER DANGER DANGER DANGER DANGER!\n"); + fprintf(where,"Remote CPU usage numbers based on process information only!\n"); + fflush(where); + } + remote_cpu_utilization = dlpi_co_rr_result->cpu_util; + /* since calc_service demand is doing ms/Kunit we will */ + /* multiply the number of transaction by 1024 to get */ + /* "good" numbers */ + remote_service_demand = calc_service_demand((double) nummessages*1024, + 0.0, + remote_cpu_utilization, + dlpi_co_rr_result->num_cpus); + } + else { + remote_cpu_utilization = -1.0; + remote_service_demand = -1.0; + } + + /* We are now ready to print all the information. If the user */ + /* has specified zero-level verbosity, we will just print the */ + /* local service demand, or the remote service demand. If the */ + /* user has requested verbosity level 1, he will get the basic */ + /* "streamperf" numbers. If the user has specified a verbosity */ + /* of greater than 1, we will display a veritable plethora of */ + /* background information from outside of this block as it it */ + /* not cpu_measurement specific... */ + + switch (verbosity) { + case 0: + if (local_cpu_usage) { + fprintf(where, + cpu_fmt_0, + local_service_demand); + } + else { + fprintf(where, + cpu_fmt_0, + remote_service_demand); + } + break; + case 1: + fprintf(where, + cpu_fmt_1_line_1, /* the format string */ + lsw_size, /* local sendbuf size */ + lrw_size, + req_size, /* how large were the requests */ + rsp_size, /* guess */ + elapsed_time, /* how long was the test */ + nummessages/elapsed_time, + local_cpu_utilization, /* local cpu */ + remote_cpu_utilization, /* remote cpu */ + local_service_demand, /* local service demand */ + remote_service_demand); /* remote service demand */ + fprintf(where, + cpu_fmt_1_line_2, + rsw_size, + rrw_size); + break; + } + } + else { + /* The tester did not wish to measure service demand. */ + switch (verbosity) { + case 0: + fprintf(where, + tput_fmt_0, + nummessages/elapsed_time); + break; + case 1: + fprintf(where, + tput_fmt_1_line_1, /* the format string */ + lsw_size, + lrw_size, + req_size, /* how large were the requests */ + rsp_size, /* how large were the responses */ + elapsed_time, /* how long did it take */ + nummessages/elapsed_time); + fprintf(where, + tput_fmt_1_line_2, + rsw_size, /* remote recvbuf size */ + rrw_size); + + break; + } + } + + /* it would be a good thing to include information about some of the */ + /* other parameters that may have been set for this test, but at the */ + /* moment, I do not wish to figure-out all the formatting, so I will */ + /* just put this comment here to help remind me that it is something */ + /* that should be done at a later time. */ + + if (verbosity > 1) { + /* The user wanted to know it all, so we will give it to him. */ + /* This information will include as much as we can find about */ + /* TCP statistics, the alignments of the sends and receives */ + /* and all that sort of rot... */ + + fprintf(where, + ksink_fmt); + } + /* The test is over. Kill the data descriptor */ + + if (close(send_descriptor) == -1) { + perror("send_dlpi_co_rr: cannot shutdown tcp stream descriptor"); + } + +} + +void + send_dlpi_cl_stream(char remote_host[]) +{ + /************************************************************************/ + /* */ + /* UDP Unidirectional Send Test */ + /* */ + /************************************************************************/ + char *tput_title = + "Window Message Elapsed Messages \n\ +Size Size Time Okay Errors Throughput\n\ +frames bytes secs # # %s/sec\n\n"; + + char *tput_fmt_0 = + "%7.2f\n"; + + char *tput_fmt_1 = + "%5d %5d %-7.2f %7d %6d %7.2f\n\ +%5d %-7.2f %7d %7.2f\n\n"; + + + char *cpu_title = + "Window Message Elapsed Messages CPU Service\n\ +Size Size Time Okay Errors Throughput Util Demand\n\ +frames bytes secs # # %s/sec %% us/KB\n\n"; + + char *cpu_fmt_0 = + "%6.2f\n"; + + char *cpu_fmt_1 = + "%5d %5d %-7.2f %7d %6d %7.1f %-6.2f %-6.3f\n\ +%5d %-7.2f %7d %7.1f %-6.2f %-6.3f\n\n"; + + int messages_recvd; + float elapsed_time, + local_cpu_utilization, + remote_cpu_utilization; + + float local_service_demand, remote_service_demand; + double local_thruput, remote_thruput; + double bytes_sent; + double bytes_recvd; + + + int *message_int_ptr; + char *message_ptr; + char *message; + char sctl_data[BUFSIZ]; + struct strbuf send_message; + struct strbuf sctl_message; + dl_unitdata_req_t *data_req = (dl_unitdata_req_t *)sctl_data; + + char dlsap[BUFSIZ]; + int dlsap_len; + int message_offset; + int message_max_offset; + int failed_sends; + int failed_cows; + int messages_sent; + int data_descriptor; + + +#ifdef WANT_INTERVALS + int interval_count; +#endif /* WANT_INTERVALS */ +#ifdef DIRTY + int i; +#endif /* DIRTY */ + + struct dlpi_cl_stream_request_struct *dlpi_cl_stream_request; + struct dlpi_cl_stream_response_struct *dlpi_cl_stream_response; + struct dlpi_cl_stream_results_struct *dlpi_cl_stream_results; + + dlpi_cl_stream_request = (struct dlpi_cl_stream_request_struct *)netperf_request.content.test_specific_data; + dlpi_cl_stream_response = (struct dlpi_cl_stream_response_struct *)netperf_response.content.test_specific_data; + dlpi_cl_stream_results = (struct dlpi_cl_stream_results_struct *)netperf_response.content.test_specific_data; + + if ( print_headers ) { + printf("DLPI CL UNIDIRECTIONAL SEND TEST\n"); + if (local_cpu_usage || remote_cpu_usage) + printf(cpu_title,format_units()); + else + printf(tput_title,format_units()); + } + + failed_sends = 0; + messages_sent = 0; + times_up = 0; + + /*set up the data descriptor */ + + data_descriptor = dl_open(loc_dlpi_device,loc_ppa); + if (data_descriptor < 0){ + perror("send_dlpi_cl_stream: data descriptor"); + exit(1); + } + + /* bind the puppy and get the assigned dlsap */ + dlsap_len = BUFSIZ; + if (dl_bind(data_descriptor, + dlpi_sap, DL_CLDLS, dlsap, &dlsap_len) != 0) { + fprintf(where,"send_dlpi_cl_stream: bind failure\n"); + fflush(where); + exit(1); + } + + /* Modify the local socket size (SNDBUF size) */ + +#ifdef DL_HP_SET_LOCAL_WIN_REQ + if (lsw_size > 0) { + if (debug > 1) { + fprintf(where,"netperf: send_dlpi_cl_stream: descriptor send size altered from system default...\n"); + fprintf(where," send: %d\n",lsw_size); + } + } + if (lrw_size > 0) { + if (debug > 1) { + fprintf(where,"netperf: send_dlpi_cl_stream: descriptor recv size altered from system default...\n"); + fprintf(where," recv: %d\n",lrw_size); + } + } + + + /* Now, we will find-out what the size actually became, and report */ + /* that back to the user. If the call fails, we will just report a -1 */ + /* back to the initiator for the recv buffer size. */ + +#else /* DL_HP_SET_LOCAL_WIN_REQ */ + + lsw_size = -1; + lrw_size = -1; + +#endif /* DL_HP_SET_LOCAL_WIN_REQ */ + + /* now, we want to see if we need to set the send_size */ + if (send_size == 0) { + send_size = 1024; + } + + + /* set-up the data buffer with the requested alignment and offset, */ + /* most of the numbers here are just a hack to pick something nice */ + /* and big in an attempt to never try to send a buffer a second time */ + /* before it leaves the node...unless the user set the width */ + /* explicitly. */ + if (send_width == 0) send_width = 32; + message = (char *)malloc(send_size * (send_width + 1) + local_send_align + local_send_offset); + if (message == NULL) { + printf("malloc(%d) failed!\n", send_size * (send_width + 1) + local_send_align + local_send_offset); + exit(1); + } + message_ptr = (char *)(( (long) message + + (long) local_send_align - 1) & + ~((long) local_send_align - 1)); + message_ptr = message_ptr + local_send_offset; + message = message_ptr; + send_message.maxlen = send_size; + send_message.len = send_size; + send_message.buf = message; + + sctl_message.maxlen = BUFSIZ; + sctl_message.len = 0; + sctl_message.buf = sctl_data; + + /* if the user supplied a cpu rate, this call will complete rather */ + /* quickly, otherwise, the cpu rate will be retured to us for */ + /* possible display. The Library will keep it's own copy of this data */ + /* for use elsewhere. We will only display it. (Does that make it */ + /* "opaque" to us?) */ + + if (local_cpu_usage) + local_cpu_rate = calibrate_local_cpu(local_cpu_rate); + + /* Tell the remote end to set up the data connection. The server */ + /* sends back the port number and alters the socket parameters there. */ + /* Of course this is a datagram service so no connection is actually */ + /* set up, the server just sets up the socket and binds it. */ + + netperf_request.content.request_type = DO_DLPI_CL_STREAM; + dlpi_cl_stream_request->recv_win_size = rrw_size; + dlpi_cl_stream_request->message_size = send_size; + dlpi_cl_stream_request->recv_alignment = remote_recv_align; + dlpi_cl_stream_request->recv_offset = remote_recv_offset; + dlpi_cl_stream_request->measure_cpu = remote_cpu_usage; + dlpi_cl_stream_request->cpu_rate = remote_cpu_rate; + dlpi_cl_stream_request->ppa = rem_ppa; + dlpi_cl_stream_request->sap = dlpi_sap; + dlpi_cl_stream_request->dev_name_len = strlen(rem_dlpi_device); + strcpy(dlpi_cl_stream_request->dlpi_device, + rem_dlpi_device); + +#ifdef __alpha + + /* ok - even on a DEC box, strings are strings. I din't really want */ + /* to ntohl the words of a string. since I don't want to teach the */ + /* send_ and recv_ _request and _response routines about the types, */ + /* I will put "anti-ntohl" calls here. I imagine that the "pure" */ + /* solution would be to use XDR, but I am still leary of being able */ + /* to find XDR libs on all platforms I want running netperf. raj */ + { + int *charword; + int *initword; + int *lastword; + + initword = (int *) dlpi_cl_stream_request->dlpi_device; + lastword = initword + ((strlen(rem_dlpi_device) + 3) / 4); + + for (charword = initword; + charword < lastword; + charword++) { + + *charword = ntohl(*charword); + } + } +#endif /* __alpha */ + + if (test_time) { + dlpi_cl_stream_request->test_length = test_time; + } + else { + dlpi_cl_stream_request->test_length = test_bytes * -1; + } + + + send_request(); + + recv_response(); + + if (!netperf_response.content.serv_errno) { + if (debug) + fprintf(where,"send_dlpi_cl_stream: remote data connection done.\n"); + } + else { + Set_errno(netperf_response.content.serv_errno); + perror("send_dlpi_cl_stream: error on remote"); + exit(1); + } + + /* place some of the remote's addressing information into the send */ + /* structure so our sends can be sent to the correct place. Also get */ + /* some of the returned socket buffer information for user display. */ + + /* set-up the destination addressing control info */ + data_req->dl_primitive = DL_UNITDATA_REQ; + bcopy((char *)(dlpi_cl_stream_response->station_addr), + ((char *)data_req + sizeof(dl_unitdata_req_t)), + dlpi_cl_stream_response->station_addr_len); + data_req->dl_dest_addr_offset = sizeof(dl_unitdata_req_t); + data_req->dl_dest_addr_length = dlpi_cl_stream_response->station_addr_len; + /* there is a dl_priority structure too, but I am ignoring it for */ + /* the time being. */ + /* however... it is best to put some value in there lest some code + get grumpy about it - fix from Nicolas Thomas */ + data_req->dl_priority.dl_min = DL_QOS_DONT_CARE; + data_req->dl_priority.dl_max = DL_QOS_DONT_CARE; + + sctl_message.len = sizeof(dl_unitdata_req_t) + + data_req->dl_dest_addr_length; + + rrw_size = dlpi_cl_stream_response->recv_win_size; + rsw_size = dlpi_cl_stream_response->send_win_size; + remote_cpu_rate = dlpi_cl_stream_response->cpu_rate; + + + /* set up the timer to call us after test_time */ + start_timer(test_time); + + /* Get the start count for the idle counter and the start time */ + + cpu_start(local_cpu_usage); + +#ifdef WANT_INTERVALS + interval_count = interval_burst; +#endif /* WANT_INTERVALS */ + + /* Send datagrams like there was no tomorrow */ + while (!times_up) { +#ifdef DIRTY + /* we want to dirty some number of consecutive integers in the buffer */ + /* we are about to send. we may also want to bring some number of */ + /* them cleanly into the cache. The clean ones will follow any dirty */ + /* ones into the cache. */ + message_int_ptr = (int *)message_ptr; + for (i = 0; i < loc_dirty_count; i++) { + *message_int_ptr = 4; + message_int_ptr++; + } + for (i = 0; i < loc_clean_count; i++) { + loc_dirty_count = *message_int_ptr; + message_int_ptr++; + } +#endif /* DIRTY */ + if (putmsg(data_descriptor, + &sctl_message, + &send_message, + 0) != 0) { + if (errno == EINTR) { + break; + } + if (errno == ENOBUFS) { + /* we might not ever hit this with STREAMS, it would probably */ + /* be better to do a getinfo request at the end of the test to */ + /* get all sorts of gory statistics. in the meantime, we will */ + /* keep this code in place. */ + failed_sends++; + continue; + } + perror("send_dlpi_cl_stream: data send error"); + if (debug) { + fprintf(where,"messages_sent %u\n",messages_sent); + fflush(where); + } + exit(1); + } + messages_sent++; + + /* now we want to move our pointer to the next position in the */ + /* data buffer...since there was a successful send */ + + +#ifdef WANT_INTERVALS + /* in this case, the interval count is the count-down couter */ + /* to decide to sleep for a little bit */ + if ((interval_burst) && (--interval_count == 0)) { + /* call the sleep routine for some milliseconds, if our */ + /* timer popped while we were in there, we want to */ + /* break out of the loop. */ + if (msec_sleep(interval_wate)) { + break; + } + interval_count = interval_burst; + } + +#endif /* WANT_INTERVALS */ + + } + + /* This is a timed test, so the remote will be returning to us after */ + /* a time. We should not need to send any "strange" messages to tell */ + /* the remote that the test is completed, unless we decide to add a */ + /* number of messages to the test. */ + + /* the test is over, so get stats and stuff */ + cpu_stop(local_cpu_usage, + &elapsed_time); + + /* Get the statistics from the remote end */ + recv_response(); + if (!netperf_response.content.serv_errno) { + if (debug) + fprintf(where,"send_dlpi_cl_stream: remote results obtained\n"); + } + else { + Set_errno(netperf_response.content.serv_errno); + perror("send_dlpi_cl_stream: error on remote"); + exit(1); + } + + bytes_sent = send_size * messages_sent; + local_thruput = calc_thruput(bytes_sent); + + messages_recvd = dlpi_cl_stream_results->messages_recvd; + bytes_recvd = send_size * messages_recvd; + + /* we asume that the remote ran for as long as we did */ + + remote_thruput = calc_thruput(bytes_recvd); + + /* print the results for this descriptor and message size */ + + if (local_cpu_usage || remote_cpu_usage) { + /* We must now do a little math for service demand and cpu */ + /* utilization for the system(s) We pass zeros for the local */ + /* cpu utilization and elapsed time to tell the routine to use */ + /* the libraries own values for those. */ + if (local_cpu_usage) { + if (local_cpu_rate == 0.0) { + fprintf(where,"WARNING WARNING WARNING WARNING WARNING WARNING WARNING!\n"); + fprintf(where,"Local CPU usage numbers based on process information only!\n"); + fflush(where); + } + + local_cpu_utilization = calc_cpu_util(0.0); + local_service_demand = calc_service_demand(bytes_sent, + 0.0, + 0.0, + 0); + } + else { + local_cpu_utilization = -1.0; + local_service_demand = -1.0; + } + + /* The local calculations could use variables being kept by */ + /* the local netlib routines. The remote calcuations need to */ + /* have a few things passed to them. */ + if (remote_cpu_usage) { + if (remote_cpu_rate == 0.0) { + fprintf(where,"DANGER DANGER DANGER DANGER DANGER DANGER DANGER!\n"); + fprintf(where,"REMOTE CPU usage numbers based on process information only!\n"); + fflush(where); + } + + remote_cpu_utilization = dlpi_cl_stream_results->cpu_util; + remote_service_demand = calc_service_demand(bytes_recvd, + 0.0, + remote_cpu_utilization, + dlpi_cl_stream_results->num_cpus); + } + else { + remote_cpu_utilization = -1.0; + remote_service_demand = -1.0; + } + + /* We are now ready to print all the information. If the user */ + /* has specified zero-level verbosity, we will just print the */ + /* local service demand, or the remote service demand. If the */ + /* user has requested verbosity level 1, he will get the basic */ + /* "streamperf" numbers. If the user has specified a verbosity */ + /* of greater than 1, we will display a veritable plethora of */ + /* background information from outside of this block as it it */ + /* not cpu_measurement specific... */ + + switch (verbosity) { + case 0: + if (local_cpu_usage) { + fprintf(where, + cpu_fmt_0, + local_service_demand); + } + else { + fprintf(where, + cpu_fmt_0, + remote_service_demand); + } + break; + case 1: + fprintf(where, + cpu_fmt_1, /* the format string */ + lsw_size, /* local sendbuf size */ + send_size, /* how large were the sends */ + elapsed_time, /* how long was the test */ + messages_sent, + failed_sends, + local_thruput, /* what was the xfer rate */ + local_cpu_utilization, /* local cpu */ + local_service_demand, /* local service demand */ + rrw_size, + elapsed_time, + messages_recvd, + remote_thruput, + remote_cpu_utilization, /* remote cpu */ + remote_service_demand); /* remote service demand */ + break; + } + } + else { + /* The tester did not wish to measure service demand. */ + switch (verbosity) { + case 0: + fprintf(where, + tput_fmt_0, + local_thruput); + break; + case 1: + fprintf(where, + tput_fmt_1, /* the format string */ + lsw_size, /* local sendbuf size */ + send_size, /* how large were the sends */ + elapsed_time, /* how long did it take */ + messages_sent, + failed_sends, + local_thruput, + rrw_size, /* remote recvbuf size */ + elapsed_time, + messages_recvd, + remote_thruput + ); + break; + } + } +} + +int + recv_dlpi_cl_stream() +{ + + char *message; + int data_descriptor; + int len; + char *message_ptr; + char rctl_data[BUFSIZ]; + struct strbuf recv_message; + struct strbuf rctl_message; + int flags = 0; + /* these are to make reading some of the DLPI control messages easier */ + dl_unitdata_ind_t *data_ind = (dl_unitdata_ind_t *)rctl_data; + dl_uderror_ind_t *uder_ind = (dl_uderror_ind_t *)rctl_data; + + int bytes_received = 0; + float elapsed_time; + + int message_size; + int messages_recvd = 0; + int measure_cpu; + + struct dlpi_cl_stream_request_struct *dlpi_cl_stream_request; + struct dlpi_cl_stream_response_struct *dlpi_cl_stream_response; + struct dlpi_cl_stream_results_struct *dlpi_cl_stream_results; + + dlpi_cl_stream_request = (struct dlpi_cl_stream_request_struct *)netperf_request.content.test_specific_data; + dlpi_cl_stream_response = (struct dlpi_cl_stream_response_struct *)netperf_response.content.test_specific_data; + dlpi_cl_stream_results = (struct dlpi_cl_stream_results_struct *)netperf_response.content.test_specific_data; + + if (debug) { + fprintf(where,"netserver: recv_dlpi_cl_stream: entered...\n"); + fflush(where); + } + + /* We want to set-up the listen descriptor with all the desired */ + /* parameters and then let the initiator know that all is ready. If */ + /* socket size defaults are to be used, then the initiator will have */ + /* sent us 0's. If the socket sizes cannot be changed, then we will */ + /* send-back what they are. If that information cannot be determined, */ + /* then we send-back -1's for the sizes. If things go wrong for any */ + /* reason, we will drop back ten yards and punt. */ + + /* If anything goes wrong, we want the remote to know about it. It */ + /* would be best if the error that the remote reports to the user is */ + /* the actual error we encountered, rather than some bogus unexpected */ + /* response type message. */ + + if (debug > 1) { + fprintf(where,"recv_dlpi_cl_stream: setting the response type...\n"); + fflush(where); + } + + netperf_response.content.response_type = DLPI_CL_STREAM_RESPONSE; + + if (debug > 2) { + fprintf(where,"recv_dlpi_cl_stream: the response type is set...\n"); + fflush(where); + } + + /* set-up the data buffer with the requested alignment and offset */ + message = (char *)malloc(DATABUFFERLEN); + if (message == NULL) { + printf("malloc(%d) failed!\n", DATABUFFERLEN); + exit(1); + } + + /* We now alter the message_ptr variable to be at the desired */ + /* alignment with the desired offset. */ + + if (debug > 1) { + fprintf(where,"recv_dlpi_cl_stream: requested alignment of %d\n", + dlpi_cl_stream_request->recv_alignment); + fflush(where); + } + + message_ptr = ALIGN_BUFFER(message, dlpi_cl_stream_request->recv_alignment, dlpi_cl_stream_request->recv_offset); + + if (dlpi_cl_stream_request->message_size > 0) { + recv_message.maxlen = dlpi_cl_stream_request->message_size; + } + else { + recv_message.maxlen = 4096; + } + recv_message.len = 0; + recv_message.buf = message_ptr; + + rctl_message.maxlen = BUFSIZ; + rctl_message.len = 0; + rctl_message.buf = rctl_data; + + if (debug > 1) { + fprintf(where, + "recv_dlpi_cl_stream: receive alignment and offset set...\n"); + fflush(where); + } + + if (debug > 1) { + fprintf(where,"recv_dlpi_cl_stream: grabbing a descriptor...\n"); + fflush(where); + } + +#ifdef __alpha + + /* ok - even on a DEC box, strings are strings. I din't really want */ + /* to ntohl the words of a string. since I don't want to teach the */ + /* send_ and recv_ _request and _response routines about the types, */ + /* I will put "anti-ntohl" calls here. I imagine that the "pure" */ + /* solution would be to use XDR, but I am still leary of being able */ + /* to find XDR libs on all platforms I want running netperf. raj */ + { + int *charword; + int *initword; + int *lastword; + + initword = (int *) dlpi_cl_stream_request->dlpi_device; + lastword = initword + ((dlpi_cl_stream_request->dev_name_len + 3) / 4); + + for (charword = initword; + charword < lastword; + charword++) { + + *charword = htonl(*charword); + } + } +#endif /* __alpha */ + + data_descriptor = dl_open(dlpi_cl_stream_request->dlpi_device, + dlpi_cl_stream_request->ppa); + if (data_descriptor < 0) { + netperf_response.content.serv_errno = errno; + send_response(); + exit(1); + } + + /* The initiator may have wished-us to modify the window */ + /* sizes. We should give it a shot. If he didn't ask us to change the */ + /* sizes, we should let him know what sizes were in use at this end. */ + /* If none of this code is compiled-in, then we will tell the */ + /* initiator that we were unable to play with the sizes by */ + /* setting the size in the response to -1. */ + +#ifdef DL_HP_SET_LOCAL_WIN_REQ + + if (dlpi_cl_stream_request->recv_win_size) { + dlpi_cl_stream_response->recv_win_size = -1; + } + +#else /* the system won't let us play with the buffers */ + + dlpi_cl_stream_response->recv_win_size = -1; + +#endif /* DL_HP_SET_LOCAL_WIN_REQ */ + + dlpi_cl_stream_response->test_length = dlpi_cl_stream_request->test_length; + + /* bind the sap and retrieve the dlsap assigned by the system */ + dlpi_cl_stream_response->station_addr_len = 14; /* arbitrary */ + if (dl_bind(data_descriptor, + dlpi_cl_stream_request->sap, + DL_CLDLS, + (char *)dlpi_cl_stream_response->station_addr, + &dlpi_cl_stream_response->station_addr_len) != 0) { + fprintf(where,"send_dlpi_cl_stream: bind failure\n"); + fflush(where); + exit(1); + } + + netperf_response.content.serv_errno = 0; + + /* But wait, there's more. If the initiator wanted cpu measurements, */ + /* then we must call the calibrate routine, which will return the max */ + /* rate back to the initiator. If the CPU was not to be measured, or */ + /* something went wrong with the calibration, we will return a -1 to */ + /* the initiator. */ + + dlpi_cl_stream_response->cpu_rate = 0.0; /* assume no cpu */ + if (dlpi_cl_stream_request->measure_cpu) { + /* We will pass the rate into the calibration routine. If the */ + /* user did not specify one, it will be 0.0, and we will do a */ + /* "real" calibration. Otherwise, all it will really do is */ + /* store it away... */ + dlpi_cl_stream_response->measure_cpu = 1; + dlpi_cl_stream_response->cpu_rate = calibrate_local_cpu(dlpi_cl_stream_request->cpu_rate); + } + + message_size = dlpi_cl_stream_request->message_size; + test_time = dlpi_cl_stream_request->test_length; + + send_response(); + + /* Now it's time to start receiving data on the connection. We will */ + /* first grab the apropriate counters and then start grabbing. */ + + cpu_start(dlpi_cl_stream_request->measure_cpu); + + /* The loop will exit when the timer pops, or if we happen to recv a */ + /* message of less than send_size bytes... */ + + times_up = 0; + start_timer(test_time + PAD_TIME); + + if (debug) { + fprintf(where,"recv_dlpi_cl_stream: about to enter inner sanctum.\n"); + fflush(where); + } + + while (!times_up) { + if((getmsg(data_descriptor, + &rctl_message, + &recv_message, + &flags) != 0) || + (data_ind->dl_primitive != DL_UNITDATA_IND)) { + if (errno == EINTR) { + /* Again, we have likely hit test-end time */ + break; + } + fprintf(where, + "dlpi_recv_cl_stream: getmsg failure: errno %d primitive 0x%x\n", + errno, + data_ind->dl_primitive); + fflush(where); + netperf_response.content.serv_errno = 996; + send_response(); + exit(1); + } + messages_recvd++; + } + + if (debug) { + fprintf(where,"recv_dlpi_cl_stream: got %d messages.\n",messages_recvd); + fflush(where); + } + + + /* The loop now exits due timer or < send_size bytes received. */ + + cpu_stop(dlpi_cl_stream_request->measure_cpu,&elapsed_time); + + if (times_up) { + /* we ended on a timer, subtract the PAD_TIME */ + elapsed_time -= (float)PAD_TIME; + } + else { + stop_timer(); + } + + if (debug) { + fprintf(where,"recv_dlpi_cl_stream: test ended in %f seconds.\n",elapsed_time); + fflush(where); + } + + + /* We will count the "off" message */ + bytes_received = (messages_recvd * message_size) + len; + + /* send the results to the sender */ + + if (debug) { + fprintf(where, + "recv_dlpi_cl_stream: got %d bytes\n", + bytes_received); + fflush(where); + } + + netperf_response.content.response_type = DLPI_CL_STREAM_RESULTS; + dlpi_cl_stream_results->bytes_received = bytes_received; + dlpi_cl_stream_results->messages_recvd = messages_recvd; + dlpi_cl_stream_results->elapsed_time = elapsed_time; + if (dlpi_cl_stream_request->measure_cpu) { + dlpi_cl_stream_results->cpu_util = calc_cpu_util(elapsed_time); + } + else { + dlpi_cl_stream_results->cpu_util = -1.0; + } + + if (debug > 1) { + fprintf(where, + "recv_dlpi_cl_stream: test complete, sending results.\n"); + fflush(where); + } + + send_response(); + +} + +int send_dlpi_cl_rr(char remote_host[]) +{ + + char *tput_title = "\ +Local /Remote\n\ +Window Size Request Resp. Elapsed Trans.\n\ +Send Recv Size Size Time Rate \n\ +frames frames bytes bytes secs. per sec \n\n"; + + char *tput_fmt_0 = + "%7.2f\n"; + + char *tput_fmt_1_line_1 = "\ +%-6d %-6d %-6d %-6d %-6.2f %7.2f \n"; + char *tput_fmt_1_line_2 = "\ +%-6d %-6d\n"; + + char *cpu_title = "\ +Local /Remote\n\ +Window Size Request Resp. Elapsed Trans. CPU CPU S.dem S.dem\n\ +Send Recv Size Size Time Rate local remote local remote\n\ +frames frames bytes bytes secs. per sec %% %% us/Tr us/Tr\n\n"; + + char *cpu_fmt_0 = + "%6.3f\n"; + + char *cpu_fmt_1_line_1 = "\ +%-6d %-6d %-6d %-6d %-6.2f %-6.2f %-6.2f %-6.2f %-6.3f %-6.3f\n"; + + char *cpu_fmt_1_line_2 = "\ +%-6d %-6d\n"; + + char *ksink_fmt = "\ +Alignment Offset\n\ +Local Remote Local Remote\n\ +Send Recv Send Recv\n\ +%5d %5d %5d %5d\n"; + + + float elapsed_time; + + int dlsap_len; + int flags = 0; + char *send_message_ptr; + char *recv_message_ptr; + char *temp_message_ptr; + char sctl_data[BUFSIZ]; + char rctl_data[BUFSIZ]; + char dlsap[BUFSIZ]; + struct strbuf send_message; + struct strbuf recv_message; + struct strbuf sctl_message; + struct strbuf rctl_message; + + /* these are to make reading some of the DLPI control messages easier */ + dl_unitdata_ind_t *data_ind = (dl_unitdata_ind_t *)rctl_data; + dl_unitdata_req_t *data_req = (dl_unitdata_req_t *)sctl_data; + dl_uderror_ind_t *uder_ind = (dl_uderror_ind_t *)rctl_data; + + int nummessages; + int send_descriptor; + int trans_remaining; + int bytes_xferd; + + float local_cpu_utilization; + float local_service_demand; + float remote_cpu_utilization; + float remote_service_demand; + double thruput; + +#ifdef WANT_INTERVALS + /* timing stuff */ +#define MAX_KEPT_TIMES 1024 + int time_index = 0; + int unused_buckets; + int kept_times[MAX_KEPT_TIMES]; + int sleep_usecs; + unsigned int total_times=0; + struct timezone dummy_zone; + struct timeval send_time; + struct timeval recv_time; + struct timeval sleep_timeval; +#endif /* WANT_INTERVALS */ + + struct dlpi_cl_rr_request_struct *dlpi_cl_rr_request; + struct dlpi_cl_rr_response_struct *dlpi_cl_rr_response; + struct dlpi_cl_rr_results_struct *dlpi_cl_rr_result; + + dlpi_cl_rr_request = + (struct dlpi_cl_rr_request_struct *)netperf_request.content.test_specific_data; + dlpi_cl_rr_response = + (struct dlpi_cl_rr_response_struct *)netperf_response.content.test_specific_data; + dlpi_cl_rr_result = + (struct dlpi_cl_rr_results_struct *)netperf_response.content.test_specific_data; + + /* we want to zero out the times, so we can detect unused entries. */ +#ifdef WANT_INTERVALS + time_index = 0; + while (time_index < MAX_KEPT_TIMES) { + kept_times[time_index] = 0; + time_index += 1; + } + time_index = 0; +#endif /* WANT_INTERVALS */ + + if (print_headers) { + fprintf(where,"DLPI CL REQUEST/RESPONSE TEST\n"); + if (local_cpu_usage || remote_cpu_usage) + fprintf(where,cpu_title,format_units()); + else + fprintf(where,tput_title,format_units()); + } + + /* initialize a few counters */ + + nummessages = 0; + bytes_xferd = 0; + times_up = 0; + + /* set-up the data buffer with the requested alignment and offset */ + temp_message_ptr = (char *)malloc(req_size+MAXALIGNMENT+MAXOFFSET); + if (temp_message_ptr == NULL) { + printf("malloc(%d) failed!\n", req_size+MAXALIGNMENT+MAXOFFSET); + exit(1); + } + send_message_ptr = (char *)(( (long)temp_message_ptr + + (long) local_send_align - 1) & + ~((long) local_send_align - 1)); + send_message_ptr = send_message_ptr + local_send_offset; + send_message.maxlen = req_size; + send_message.len = req_size; + send_message.buf = send_message_ptr; + + temp_message_ptr = (char *)malloc(rsp_size+MAXALIGNMENT+MAXOFFSET); + if (temp_message_ptr == NULL) { + printf("malloc(%d) failed!\n", rsp_size+MAXALIGNMENT+MAXOFFSET); + exit(1); + } + recv_message_ptr = (char *)(( (long)temp_message_ptr + + (long) local_recv_align - 1) & + ~((long) local_recv_align - 1)); + recv_message_ptr = recv_message_ptr + local_recv_offset; + recv_message.maxlen = rsp_size; + recv_message.len = 0; + recv_message.buf = recv_message_ptr; + + sctl_message.maxlen = BUFSIZ; + sctl_message.len = 0; + sctl_message.buf = sctl_data; + + rctl_message.maxlen = BUFSIZ; + rctl_message.len = 0; + rctl_message.buf = rctl_data; + + /* lets get ourselves a file descriptor */ + + send_descriptor = dl_open(loc_dlpi_device,loc_ppa); + if (send_descriptor < 0){ + perror("netperf: send_dlpi_cl_rr: dlpi cl rr send descriptor"); + exit(1); + } + + if (debug) { + fprintf(where,"send_dlpi_cl_rr: send_descriptor obtained...\n"); + } + + /* bind the sap to the descriptor and get the dlsap */ + dlsap_len = BUFSIZ; + if (dl_bind(send_descriptor, + dlpi_sap, + DL_CLDLS, + dlsap, + &dlsap_len) != 0) { + fprintf(where,"send_dlpi_cl_rr: bind failure\n"); + fflush(where); + exit(1); + } + + /* Modify the local socket size. If the user has not requested that */ + /* the socket buffers be altered, we will try to find-out what their */ + /* values are. If we cannot touch the socket buffer in any way, we */ + /* will set the values to -1 to indicate that. The receive socket */ + /* must have enough space to hold addressing information so += a */ + /* sizeof struct sockaddr_in to it. */ + + /* this is actually nothing code, and should be replaced with the */ + /* alalagous calls in the STREAM test where the window size is set */ + /* with the HP DLPI Extension. raj 8/94 */ +#ifdef SO_SNDBUF + if (lsw_size > 0) { + if (debug > 1) { + fprintf(where,"netperf: send_dlpi_cl_rr: local window size altered from system default...\n"); + fprintf(where," window: %d\n",lsw_size); + } + } + if (lrw_size > 0) { + if (debug > 1) { + fprintf(where,"netperf: send_dlpi_cl_rr: remote window size altered from system default...\n"); + fprintf(where," remote: %d\n",lrw_size); + } + } + + + /* Now, we will find-out what the size actually became, and report */ + /* that back to the user. If the call fails, we will just report a -1 */ + /* back to the initiator for the recv buffer size. */ + + if (debug) { + fprintf(where,"netperf: send_dlpi_cl_rr: socket sizes determined...\n"); + fprintf(where," send: %d recv: %d\n",lsw_size,lrw_size); + } + +#else /* SO_SNDBUF */ + + lsw_size = -1; + lrw_size = -1; + +#endif /* SO_SNDBUF */ + + /* If the user has requested cpu utilization measurements, we must */ + /* calibrate the cpu(s). We will perform this task within the tests */ + /* themselves. If the user has specified the cpu rate, then */ + /* calibrate_local_cpu will return rather quickly as it will have */ + /* nothing to do. If local_cpu_rate is zero, then we will go through */ + /* all the "normal" calibration stuff and return the rate back. If */ + /* there is no idle counter in the kernel idle loop, the */ + /* local_cpu_rate will be set to -1. */ + + if (local_cpu_usage) { + local_cpu_rate = calibrate_local_cpu(local_cpu_rate); + } + + /* Tell the remote end to do a listen. The server alters the socket */ + /* paramters on the other side at this point, hence the reason for */ + /* all the values being passed in the setup message. If the user did */ + /* not specify any of the parameters, they will be passed as 0, which */ + /* will indicate to the remote that no changes beyond the system's */ + /* default should be used. Alignment is the exception, it will */ + /* default to 8, which will be no alignment alterations. */ + + netperf_request.content.request_type = DO_DLPI_CL_RR; + dlpi_cl_rr_request->recv_win_size = rrw_size; + dlpi_cl_rr_request->send_win_size = rsw_size; + dlpi_cl_rr_request->recv_alignment = remote_recv_align; + dlpi_cl_rr_request->recv_offset = remote_recv_offset; + dlpi_cl_rr_request->send_alignment = remote_send_align; + dlpi_cl_rr_request->send_offset = remote_send_offset; + dlpi_cl_rr_request->request_size = req_size; + dlpi_cl_rr_request->response_size = rsp_size; + dlpi_cl_rr_request->measure_cpu = remote_cpu_usage; + dlpi_cl_rr_request->cpu_rate = remote_cpu_rate; + dlpi_cl_rr_request->ppa = rem_ppa; + dlpi_cl_rr_request->sap = dlpi_sap; + dlpi_cl_rr_request->dev_name_len = strlen(rem_dlpi_device); + strcpy(dlpi_cl_rr_request->dlpi_device, + rem_dlpi_device); + +#ifdef __alpha + + /* ok - even on a DEC box, strings are strings. I din't really want */ + /* to ntohl the words of a string. since I don't want to teach the */ + /* send_ and recv_ _request and _response routines about the types, */ + /* I will put "anti-ntohl" calls here. I imagine that the "pure" */ + /* solution would be to use XDR, but I am still leary of being able */ + /* to find XDR libs on all platforms I want running netperf. raj */ + { + int *charword; + int *initword; + int *lastword; + + initword = (int *) dlpi_cl_rr_request->dlpi_device; + lastword = initword + ((strlen(rem_dlpi_device) + 3) / 4); + + for (charword = initword; + charword < lastword; + charword++) { + + *charword = ntohl(*charword); + } + } +#endif /* __alpha */ + + if (test_time) { + dlpi_cl_rr_request->test_length = test_time; + } + else { + dlpi_cl_rr_request->test_length = test_trans * -1; + } + + if (debug > 1) { + fprintf(where,"netperf: send_dlpi_cl_rr: requesting DLPI CL request/response test\n"); + } + + send_request(); + + /* The response from the remote will contain all of the relevant */ + /* socket parameters for this test type. We will put them back into */ + /* the variables here so they can be displayed if desired. The */ + /* remote will have calibrated CPU if necessary, and will have done */ + /* all the needed set-up we will have calibrated the cpu locally */ + /* before sending the request, and will grab the counter value right */ + /* after the connect returns. The remote will grab the counter right */ + /* after the accept call. This saves the hassle of extra messages */ + /* being sent for the tests. */ + + recv_response(); + + if (!netperf_response.content.serv_errno) { + if (debug) + fprintf(where,"remote listen done.\n"); + rrw_size = dlpi_cl_rr_response->recv_win_size; + rsw_size = dlpi_cl_rr_response->send_win_size; + remote_cpu_usage= dlpi_cl_rr_response->measure_cpu; + remote_cpu_rate = dlpi_cl_rr_response->cpu_rate; + + /* set-up the destination addressing control info */ + data_req->dl_primitive = DL_UNITDATA_REQ; + bcopy((char *)(dlpi_cl_rr_response->station_addr), + ((char *)data_req + sizeof(dl_unitdata_req_t)), + dlpi_cl_rr_response->station_addr_len); + data_req->dl_dest_addr_offset = sizeof(dl_unitdata_req_t); + data_req->dl_dest_addr_length = dlpi_cl_rr_response->station_addr_len; + /* there is a dl_priority structure too, but I am ignoring it for */ + /* the time being. */ + sctl_message.len = sizeof(dl_unitdata_req_t) + + data_req->dl_dest_addr_length; + /* famous last words - some DLPI providers get unhappy if the + priority stuff is not initialized. fix from Nicolas Thomas. */ + data_req->dl_priority.dl_min = DL_QOS_DONT_CARE; + data_req->dl_priority.dl_max = DL_QOS_DONT_CARE; + + } + else { + Set_errno(netperf_response.content.serv_errno); + perror("netperf: remote error"); + exit(1); + } + + /* Data Socket set-up is finished. If there were problems, either the */ + /* connect would have failed, or the previous response would have */ + /* indicated a problem. I failed to see the value of the extra */ + /* message after the accept on the remote. If it failed, we'll see it */ + /* here. If it didn't, we might as well start pumping data. */ + + /* Set-up the test end conditions. For a request/response test, they */ + /* can be either time or transaction based. */ + + if (test_time) { + /* The user wanted to end the test after a period of time. */ + times_up = 0; + trans_remaining = 0; + start_timer(test_time); + } + else { + /* The tester wanted to send a number of bytes. */ + trans_remaining = test_bytes; + times_up = 1; + } + + /* The cpu_start routine will grab the current time and possibly */ + /* value of the idle counter for later use in measuring cpu */ + /* utilization and/or service demand and thruput. */ + + cpu_start(local_cpu_usage); + + /* We use an "OR" to control test execution. When the test is */ + /* controlled by time, the byte count check will always return false. */ + /* When the test is controlled by byte count, the time test will */ + /* always return false. When the test is finished, the whole */ + /* expression will go false and we will stop sending data. I think I */ + /* just arbitrarily decrement trans_remaining for the timed test, but */ + /* will not do that just yet... One other question is whether or not */ + /* the send buffer and the receive buffer should be the same buffer. */ + while ((!times_up) || (trans_remaining > 0)) { + /* send the request */ +#ifdef WANT_INTERVALS + gettimeofday(&send_time,&dummy_zone); +#endif /* WANT_INTERVALS */ + if(putmsg(send_descriptor, + &sctl_message, + &send_message, + 0) != 0) { + if (errno == EINTR) { + /* We likely hit */ + /* test-end time. */ + break; + } + /* there is more we could do here, but it can wait */ + perror("send_dlpi_cl_rr: data send error"); + exit(1); + } + + /* receive the response. at some point, we will need to handle */ + /* sending responses which are greater than the datalink MTU. we */ + /* may also want to add some DLPI error checking, but for now we */ + /* will ignore that and just let errors stop the test with little */ + /* indication of what might actually be wrong. */ + + if((getmsg(send_descriptor, + &rctl_message, + &recv_message, + &flags) != 0) || + (data_ind->dl_primitive != DL_UNITDATA_IND)) { + if (errno == EINTR) { + /* Again, we have likely hit test-end time */ + break; + } + fprintf(where, + "send_dlpi_cl_rr: recv error: errno %d primitive 0x%x\n", + errno, + data_ind->dl_primitive); + fflush(where); + exit(1); + } +#ifdef WANT_INTERVALS + gettimeofday(&recv_time,&dummy_zone); + + /* now we do some arithmatic on the two timevals */ + if (recv_time.tv_usec < send_time.tv_usec) { + /* we wrapped around a second */ + recv_time.tv_usec += 1000000; + recv_time.tv_sec -= 1; + } + + /* and store it away */ + kept_times[time_index] = (recv_time.tv_sec - send_time.tv_sec) * 1000000; + kept_times[time_index] += (recv_time.tv_usec - send_time.tv_usec); + + /* at this point, we may wish to sleep for some period of */ + /* time, so we see how long that last transaction just took, */ + /* and sleep for the difference of that and the interval. We */ + /* will not sleep if the time would be less than a */ + /* millisecond. */ + if (interval_usecs > 0) { + sleep_usecs = interval_usecs - kept_times[time_index]; + if (sleep_usecs > 1000) { + /* we sleep */ + sleep_timeval.tv_sec = sleep_usecs / 1000000; + sleep_timeval.tv_usec = sleep_usecs % 1000000; + select(0, + 0, + 0, + 0, + &sleep_timeval); + } + } + + /* now up the time index */ + time_index = (time_index +1)%MAX_KEPT_TIMES; +#endif /* WANT_INTERVALS */ + nummessages++; + if (trans_remaining) { + trans_remaining--; + } + + if (debug > 3) { + fprintf(where,"Transaction %d completed\n",nummessages); + fflush(where); + } + + } + + /* this call will always give us the elapsed time for the test, and */ + /* will also store-away the necessaries for cpu utilization */ + + cpu_stop(local_cpu_usage,&elapsed_time); /* was cpu being measured? */ + /* how long did we really run? */ + + /* Get the statistics from the remote end. The remote will have */ + /* calculated service demand and all those interesting things. If it */ + /* wasn't supposed to care, it will return obvious values. */ + + recv_response(); + if (!netperf_response.content.serv_errno) { + if (debug) + fprintf(where,"remote results obtained\n"); + } + else { + Set_errno(netperf_response.content.serv_errno); + perror("netperf: remote error"); + + exit(1); + } + + /* We now calculate what our thruput was for the test. In the future, */ + /* we may want to include a calculation of the thruput measured by */ + /* the remote, but it should be the case that for a UDP stream test, */ + /* that the two numbers should be *very* close... We calculate */ + /* bytes_sent regardless of the way the test length was controlled. */ + /* If it was time, we needed to, and if it was by bytes, the user may */ + /* have specified a number of bytes that wasn't a multiple of the */ + /* send_size, so we really didn't send what he asked for ;-) We use */ + + bytes_xferd = (req_size * nummessages) + (rsp_size * nummessages); + thruput = calc_thruput(bytes_xferd); + + if (local_cpu_usage || remote_cpu_usage) { + /* We must now do a little math for service demand and cpu */ + /* utilization for the system(s) */ + /* Of course, some of the information might be bogus because */ + /* there was no idle counter in the kernel(s). We need to make */ + /* a note of this for the user's benefit...*/ + if (local_cpu_usage) { + if (local_cpu_rate == 0.0) { + fprintf(where,"WARNING WARNING WARNING WARNING WARNING WARNING WARNING!\n"); + fprintf(where,"Local CPU usage numbers based on process information only!\n"); + fflush(where); + } + local_cpu_utilization = calc_cpu_util(0.0); + /* since calc_service demand is doing ms/Kunit we will */ + /* multiply the number of transaction by 1024 to get */ + /* "good" numbers */ + local_service_demand = calc_service_demand((double) nummessages*1024, + 0.0, + 0.0, + 0); + } + else { + local_cpu_utilization = -1.0; + local_service_demand = -1.0; + } + + if (remote_cpu_usage) { + if (remote_cpu_rate == 0.0) { + fprintf(where,"DANGER DANGER DANGER DANGER DANGER DANGER DANGER!\n"); + fprintf(where,"Remote CPU usage numbers based on process information only!\n"); + fflush(where); + } + remote_cpu_utilization = dlpi_cl_rr_result->cpu_util; + /* since calc_service demand is doing ms/Kunit we will */ + /* multiply the number of transaction by 1024 to get */ + /* "good" numbers */ + remote_service_demand = calc_service_demand((double) nummessages*1024, + 0.0, + remote_cpu_utilization, + dlpi_cl_rr_result->num_cpus); + } + else { + remote_cpu_utilization = -1.0; + remote_service_demand = -1.0; + } + + /* We are now ready to print all the information. If the user */ + /* has specified zero-level verbosity, we will just print the */ + /* local service demand, or the remote service demand. If the */ + /* user has requested verbosity level 1, he will get the basic */ + /* "streamperf" numbers. If the user has specified a verbosity */ + /* of greater than 1, we will display a veritable plethora of */ + /* background information from outside of this block as it it */ + /* not cpu_measurement specific... */ + + switch (verbosity) { + case 0: + if (local_cpu_usage) { + fprintf(where, + cpu_fmt_0, + local_service_demand); + } + else { + fprintf(where, + cpu_fmt_0, + remote_service_demand); + } + break; + case 1: + case 2: + fprintf(where, + cpu_fmt_1_line_1, /* the format string */ + lsw_size, /* local sendbuf size */ + lrw_size, + req_size, /* how large were the requests */ + rsp_size, /* guess */ + elapsed_time, /* how long was the test */ + nummessages/elapsed_time, + local_cpu_utilization, /* local cpu */ + remote_cpu_utilization, /* remote cpu */ + local_service_demand, /* local service demand */ + remote_service_demand); /* remote service demand */ + fprintf(where, + cpu_fmt_1_line_2, + rsw_size, + rrw_size); + break; + } + } + else { + /* The tester did not wish to measure service demand. */ + switch (verbosity) { + case 0: + fprintf(where, + tput_fmt_0, + nummessages/elapsed_time); + break; + case 1: + case 2: + fprintf(where, + tput_fmt_1_line_1, /* the format string */ + lsw_size, + lrw_size, + req_size, /* how large were the requests */ + rsp_size, /* how large were the responses */ + elapsed_time, /* how long did it take */ + nummessages/elapsed_time); + fprintf(where, + tput_fmt_1_line_2, + rsw_size, /* remote recvbuf size */ + rrw_size); + + break; + } + } + + /* it would be a good thing to include information about some of the */ + /* other parameters that may have been set for this test, but at the */ + /* moment, I do not wish to figure-out all the formatting, so I will */ + /* just put this comment here to help remind me that it is something */ + /* that should be done at a later time. */ + + if (verbosity > 1) { + /* The user wanted to know it all, so we will give it to him. */ + /* This information will include as much as we can find about */ + /* UDP statistics, the alignments of the sends and receives */ + /* and all that sort of rot... */ + +#ifdef WANT_INTERVALS + kept_times[MAX_KEPT_TIMES] = 0; + time_index = 0; + while (time_index < MAX_KEPT_TIMES) { + if (kept_times[time_index] > 0) { + total_times += kept_times[time_index]; + } + else + unused_buckets++; + time_index += 1; + } + total_times /= (MAX_KEPT_TIMES-unused_buckets); + fprintf(where, + "Average response time %d usecs\n", + total_times); +#endif + } +} + +int + recv_dlpi_cl_rr() +{ + + char *message; + int data_descriptor; + int flags = 0; + int measure_cpu; + + char *recv_message_ptr; + char *send_message_ptr; + char sctl_data[BUFSIZ]; + char rctl_data[BUFSIZ]; + char dlsap[BUFSIZ]; + struct strbuf send_message; + struct strbuf recv_message; + struct strbuf sctl_message; + struct strbuf rctl_message; + + /* these are to make reading some of the DLPI control messages easier */ + dl_unitdata_ind_t *data_ind = (dl_unitdata_ind_t *)rctl_data; + dl_unitdata_req_t *data_req = (dl_unitdata_req_t *)sctl_data; + dl_uderror_ind_t *uder_ind = (dl_uderror_ind_t *)rctl_data; + + int trans_received; + int trans_remaining; + float elapsed_time; + + struct dlpi_cl_rr_request_struct *dlpi_cl_rr_request; + struct dlpi_cl_rr_response_struct *dlpi_cl_rr_response; + struct dlpi_cl_rr_results_struct *dlpi_cl_rr_results; + + dlpi_cl_rr_request = + (struct dlpi_cl_rr_request_struct *)netperf_request.content.test_specific_data; + dlpi_cl_rr_response = + (struct dlpi_cl_rr_response_struct *)netperf_response.content.test_specific_data; + dlpi_cl_rr_results = + (struct dlpi_cl_rr_results_struct *)netperf_response.content.test_specific_data; + + if (debug) { + fprintf(where,"netserver: recv_dlpi_cl_rr: entered...\n"); + fflush(where); + } + + /* We want to set-up the listen descriptor with all the desired */ + /* parameters and then let the initiator know that all is ready. If */ + /* socket size defaults are to be used, then the initiator will have */ + /* sent us 0's. If the descriptor sizes cannot be changed, then we will */ + /* send-back what they are. If that information cannot be determined, */ + /* then we send-back -1's for the sizes. If things go wrong for any */ + /* reason, we will drop back ten yards and punt. */ + + /* If anything goes wrong, we want the remote to know about it. It */ + /* would be best if the error that the remote reports to the user is */ + /* the actual error we encountered, rather than some bogus unexpected */ + /* response type message. */ + + if (debug) { + fprintf(where,"recv_dlpi_cl_rr: setting the response type...\n"); + fflush(where); + } + + netperf_response.content.response_type = DLPI_CL_RR_RESPONSE; + + if (debug) { + fprintf(where,"recv_dlpi_cl_rr: the response type is set...\n"); + fflush(where); + } + + /* set-up the data buffer with the requested alignment and offset */ + message = (char *)malloc(DATABUFFERLEN); + if (message == NULL) { + printf("malloc(%d) failed!\n", DATABUFFERLEN); + exit(1); + } + + /* We now alter the message_ptr variables to be at the desired */ + /* alignments with the desired offsets. */ + + if (debug) { + fprintf(where, + "recv_dlpi_cl_rr: requested recv alignment of %d offset %d\n", + dlpi_cl_rr_request->recv_alignment, + dlpi_cl_rr_request->recv_offset); + fprintf(where, + "recv_dlpi_cl_rr: requested send alignment of %d offset %d\n", + dlpi_cl_rr_request->send_alignment, + dlpi_cl_rr_request->send_offset); + fflush(where); + } + + recv_message_ptr = ALIGN_BUFFER(message, dlpi_cl_rr_request->recv_alignment, dlpi_cl_rr_request->recv_offset); + recv_message.maxlen = dlpi_cl_rr_request->request_size; + recv_message.len = 0; + recv_message.buf = recv_message_ptr; + + send_message_ptr = ALIGN_BUFFER(message, dlpi_cl_rr_request->send_alignment, dlpi_cl_rr_request->send_offset); + send_message.maxlen = dlpi_cl_rr_request->response_size; + send_message.len = dlpi_cl_rr_request->response_size; + send_message.buf = send_message_ptr; + + sctl_message.maxlen = BUFSIZ; + sctl_message.len = 0; + sctl_message.buf = sctl_data; + + rctl_message.maxlen = BUFSIZ; + rctl_message.len = 0; + rctl_message.buf = rctl_data; + + if (debug) { + fprintf(where,"recv_dlpi_cl_rr: receive alignment and offset set...\n"); + fprintf(where,"recv_dlpi_cl_rr: grabbing a socket...\n"); + fflush(where); + } + + +#ifdef __alpha + + /* ok - even on a DEC box, strings are strings. I din't really want */ + /* to ntohl the words of a string. since I don't want to teach the */ + /* send_ and recv_ _request and _response routines about the types, */ + /* I will put "anti-ntohl" calls here. I imagine that the "pure" */ + /* solution would be to use XDR, but I am still leary of being able */ + /* to find XDR libs on all platforms I want running netperf. raj */ + { + int *charword; + int *initword; + int *lastword; + + initword = (int *) dlpi_cl_rr_request->dlpi_device; + lastword = initword + ((dlpi_cl_rr_request->dev_name_len + 3) / 4); + + for (charword = initword; + charword < lastword; + charword++) { + + *charword = htonl(*charword); + } + } +#endif /* __alpha */ + + data_descriptor = dl_open(dlpi_cl_rr_request->dlpi_device, + dlpi_cl_rr_request->ppa); + if (data_descriptor < 0) { + netperf_response.content.serv_errno = errno; + send_response(); + exit(1); + } + + + /* The initiator may have wished-us to modify the window */ + /* sizes. We should give it a shot. If he didn't ask us to change the */ + /* sizes, we should let him know what sizes were in use at this end. */ + /* If none of this code is compiled-in, then we will tell the */ + /* initiator that we were unable to play with the sizes by */ + /* setting the size in the response to -1. */ + +#ifdef DL_HP_SET_LOCAL_WIN_REQ + + if (dlpi_cl_rr_request->recv_win_size) { + } + + if (dlpi_cl_rr_request->send_win_size) { + } + + /* Now, we will find-out what the sizes actually became, and report */ + /* them back to the user. If the calls fail, we will just report a -1 */ + /* back to the initiator for the buffer size. */ + +#else /* the system won't let us play with the buffers */ + + dlpi_cl_rr_response->recv_win_size = -1; + dlpi_cl_rr_response->send_win_size = -1; + +#endif /* DL_HP_SET_LOCAL_WIN_REQ */ + + /* bind the sap and retrieve the dlsap assigned by the system */ + dlpi_cl_rr_response->station_addr_len = 14; /* arbitrary */ + if (dl_bind(data_descriptor, + dlpi_cl_rr_request->sap, + DL_CLDLS, + (char *)dlpi_cl_rr_response->station_addr, + &dlpi_cl_rr_response->station_addr_len) != 0) { + fprintf(where,"send_dlpi_cl_rr: bind failure\n"); + fflush(where); + exit(1); + } + + netperf_response.content.serv_errno = 0; + + /* But wait, there's more. If the initiator wanted cpu measurements, */ + /* then we must call the calibrate routine, which will return the max */ + /* rate back to the initiator. If the CPU was not to be measured, or */ + /* something went wrong with the calibration, we will return a 0.0 to */ + /* the initiator. */ + + dlpi_cl_rr_response->cpu_rate = 0.0; /* assume no cpu */ + if (dlpi_cl_rr_request->measure_cpu) { + dlpi_cl_rr_response->measure_cpu = 1; + dlpi_cl_rr_response->cpu_rate = calibrate_local_cpu(dlpi_cl_rr_request->cpu_rate); + } + + send_response(); + + /* Now it's time to start receiving data on the connection. We will */ + /* first grab the apropriate counters and then start receiving. */ + + cpu_start(dlpi_cl_rr_request->measure_cpu); + + if (dlpi_cl_rr_request->test_length > 0) { + times_up = 0; + trans_remaining = 0; + start_timer(dlpi_cl_rr_request->test_length + PAD_TIME); + } +else { + times_up = 1; + trans_remaining = dlpi_cl_rr_request->test_length * -1; +} + + while ((!times_up) || (trans_remaining > 0)) { + + /* receive the request from the other side. at some point we need */ + /* to handle "logical" requests and responses which are larger */ + /* than the data link MTU */ + + if((getmsg(data_descriptor, + &rctl_message, + &recv_message, + &flags) != 0) || + (data_ind->dl_primitive != DL_UNITDATA_IND)) { + if (errno == EINTR) { + /* Again, we have likely hit test-end time */ + break; + } + fprintf(where, + "dlpi_recv_cl_rr: getmsg failure: errno %d primitive 0x%x\n", + errno, + data_ind->dl_primitive); + fprintf(where, + " recevied %u transactions\n", + trans_received); + fflush(where); + netperf_response.content.serv_errno = 995; + send_response(); + exit(1); + } + + /* Now, send the response to the remote. first copy the dlsap */ + /* information from the receive to the sending control message */ + + data_req->dl_dest_addr_offset = sizeof(dl_unitdata_req_t); + bcopy((char *)data_ind + data_ind->dl_src_addr_offset, + (char *)data_req + data_req->dl_dest_addr_offset, + data_ind->dl_src_addr_length); + data_req->dl_dest_addr_length = data_ind->dl_src_addr_length; + data_req->dl_primitive = DL_UNITDATA_REQ; + /* be sure to initialize the priority fields. fix from Nicholas + Thomas */ + data_req->dl_priority.dl_min = DL_QOS_DONT_CARE; + data_req->dl_priority.dl_max = DL_QOS_DONT_CARE; + + sctl_message.len = sizeof(dl_unitdata_req_t) + + data_ind->dl_src_addr_length; + if(putmsg(data_descriptor, + &sctl_message, + &send_message, + 0) != 0) { + if (errno == EINTR) { + /* We likely hit */ + /* test-end time. */ + break; + } + /* there is more we could do here, but it can wait */ + fprintf(where, + "dlpi_recv_cl_rr: putmsg failure: errno %d\n", + errno); + fflush(where); + netperf_response.content.serv_errno = 993; + send_response(); + exit(1); + } + + trans_received++; + if (trans_remaining) { + trans_remaining--; + } + + if (debug) { + fprintf(where, + "recv_dlpi_cl_rr: Transaction %d complete.\n", + trans_received); + fflush(where); + } + + } + + + /* The loop now exits due to timeout or transaction count being */ + /* reached */ + + cpu_stop(dlpi_cl_rr_request->measure_cpu,&elapsed_time); + + if (times_up) { + /* we ended the test by time, which was at least 2 seconds */ + /* longer than we wanted to run. so, we want to subtract */ + /* PAD_TIME from the elapsed_time. */ + elapsed_time -= PAD_TIME; + } + /* send the results to the sender */ + + if (debug) { + fprintf(where, + "recv_dlpi_cl_rr: got %d transactions\n", + trans_received); + fflush(where); + } + + dlpi_cl_rr_results->bytes_received = (trans_received * + (dlpi_cl_rr_request->request_size + + dlpi_cl_rr_request->response_size)); + dlpi_cl_rr_results->trans_received = trans_received; + dlpi_cl_rr_results->elapsed_time = elapsed_time; + if (dlpi_cl_rr_request->measure_cpu) { + dlpi_cl_rr_results->cpu_util = calc_cpu_util(elapsed_time); + } + + if (debug) { + fprintf(where, + "recv_dlpi_cl_rr: test complete, sending results.\n"); + fflush(where); + } + + send_response(); + +} + +int + recv_dlpi_co_rr() +{ + + char *message; + SOCKET s_listen,data_descriptor; + + int measure_cpu; + + int flags = 0; + char *recv_message_ptr; + char *send_message_ptr; + struct strbuf send_message; + struct strbuf recv_message; + + int trans_received; + int trans_remaining; + int request_bytes_remaining; + int timed_out = 0; + float elapsed_time; + + struct dlpi_co_rr_request_struct *dlpi_co_rr_request; + struct dlpi_co_rr_response_struct *dlpi_co_rr_response; + struct dlpi_co_rr_results_struct *dlpi_co_rr_results; + + dlpi_co_rr_request = (struct dlpi_co_rr_request_struct *)netperf_request.content.test_specific_data; + dlpi_co_rr_response = (struct dlpi_co_rr_response_struct *)netperf_response.content.test_specific_data; + dlpi_co_rr_results = (struct dlpi_co_rr_results_struct *)netperf_response.content.test_specific_data; + + if (debug) { + fprintf(where,"netserver: recv_dlpi_co_rr: entered...\n"); + fflush(where); + } + + /* We want to set-up the listen socket with all the desired */ + /* parameters and then let the initiator know that all is ready. If */ + /* socket size defaults are to be used, then the initiator will have */ + /* sent us 0's. If the socket sizes cannot be changed, then we will */ + /* send-back what they are. If that information cannot be determined, */ + /* then we send-back -1's for the sizes. If things go wrong for any */ + /* reason, we will drop back ten yards and punt. */ + + /* If anything goes wrong, we want the remote to know about it. It */ + /* would be best if the error that the remote reports to the user is */ + /* the actual error we encountered, rather than some bogus unexpected */ + /* response type message. */ + + if (debug) { + fprintf(where,"recv_dlpi_co_rr: setting the response type...\n"); + fflush(where); + } + + netperf_response.content.response_type = DLPI_CO_RR_RESPONSE; + + if (debug) { + fprintf(where,"recv_dlpi_co_rr: the response type is set...\n"); + fflush(where); + } + + /* set-up the data buffer with the requested alignment and offset */ + message = (char *)malloc(DATABUFFERLEN); + if (message == NULL) { + printf("malloc(%d) failed!\n", DATABUFFERLEN); + exit(1); + } + + /* We now alter the message_ptr variables to be at the desired */ + /* alignments with the desired offsets. */ + + if (debug) { + fprintf(where, + "recv_dlpi_co_rr: requested recv alignment of %d offset %d\n", + dlpi_co_rr_request->recv_alignment, + dlpi_co_rr_request->recv_offset); + fprintf(where, + "recv_dlpi_co_rr: requested send alignment of %d offset %d\n", + dlpi_co_rr_request->send_alignment, + dlpi_co_rr_request->send_offset); + fflush(where); + } + + recv_message_ptr = ALIGN_BUFFER(message, dlpi_co_rr_request->recv_alignment, dlpi_co_rr_request->recv_offset); + recv_message.maxlen = dlpi_co_rr_request->request_size; + recv_message.len = 0; + recv_message.buf = recv_message_ptr; + + send_message_ptr = ALIGN_BUFFER(message, dlpi_co_rr_request->send_alignment, dlpi_co_rr_request->send_offset); + send_message.maxlen = dlpi_co_rr_request->response_size; + send_message.len = dlpi_co_rr_request->response_size; + send_message.buf = send_message_ptr; + + if (debug) { + fprintf(where,"recv_dlpi_co_rr: receive alignment and offset set...\n"); + fprintf(where,"recv_dlpi_co_rr: send_message.buf %x .len %d .maxlen %d\n", + send_message.buf,send_message.len,send_message.maxlen); + fprintf(where,"recv_dlpi_co_rr: recv_message.buf %x .len %d .maxlen %d\n", + recv_message.buf,recv_message.len,recv_message.maxlen); + fflush(where); + } + + /* Let's clear-out our sockaddr for the sake of cleanlines. Then we */ + /* can put in OUR values !-) At some point, we may want to nail this */ + /* socket to a particular network-level address, but for now, */ + /* INADDR_ANY should be just fine. */ + + /* Grab a socket to listen on, and then listen on it. */ + + if (debug) { + fprintf(where,"recv_dlpi_co_rr: grabbing a socket...\n"); + fflush(where); + } + + /* lets grab a file descriptor for a particular link */ + +#ifdef __alpha + + /* ok - even on a DEC box, strings are strings. I din't really want */ + /* to ntohl the words of a string. since I don't want to teach the */ + /* send_ and recv_ _request and _response routines about the types, */ + /* I will put "anti-ntohl" calls here. I imagine that the "pure" */ + /* solution would be to use XDR, but I am still leary of being able */ + /* to find XDR libs on all platforms I want running netperf. raj */ + { + int *charword; + int *initword; + int *lastword; + + initword = (int *) dlpi_co_rr_request->dlpi_device; + lastword = initword + ((dlpi_co_rr_request->dev_name_len + 3) / 4); + + for (charword = initword; + charword < lastword; + charword++) { + + *charword = htonl(*charword); + } + } +#endif /* __alpha */ + + if ((data_descriptor = dl_open(dlpi_co_rr_request->dlpi_device, + dlpi_co_rr_request->ppa)) < 0) { + netperf_response.content.serv_errno = errno; + send_response(); + exit(1); + } + + /* bind the file descriptor to a sap and get the resultant dlsap */ + dlpi_co_rr_response->station_addr_len = 14; /*arbitrary needs fixing */ + if (dl_bind(data_descriptor, + dlpi_co_rr_request->sap, + DL_CODLS, + (char *)dlpi_co_rr_response->station_addr, + &dlpi_co_rr_response->station_addr_len) != 0) { + netperf_response.content.serv_errno = errno; + send_response(); + exit(1); + } + + /* The initiator may have wished-us to modify the socket buffer */ + /* sizes. We should give it a shot. If he didn't ask us to change the */ + /* sizes, we should let him know what sizes were in use at this end. */ + /* If none of this code is compiled-in, then we will tell the */ + /* initiator that we were unable to play with the socket buffer by */ + /* setting the size in the response to -1. */ + +#ifdef DL_HP_SET_LOCAL_WIN_REQ + + if (dlpi_co_rr_request->recv_win_size) { + /* SMOP */ + } + + if (dlpi_co_rr_request->send_win_size) { + /* SMOP */ + } + + /* Now, we will find-out what the sizes actually became, and report */ + /* them back to the user. If the calls fail, we will just report a -1 */ + /* back to the initiator for the buffer size. */ + +#else /* the system won't let us play with the buffers */ + + dlpi_co_rr_response->recv_win_size = -1; + dlpi_co_rr_response->send_win_size = -1; + +#endif /* DL_HP_SET_LOCAL_WIN_REQ */ + + /* we may have been requested to enable the copy avoidance features. */ + /* can we actually do this with DLPI, the world wonders */ + + if (dlpi_co_rr_request->so_rcvavoid) { +#ifdef SO_RCV_COPYAVOID + dlpi_co_rr_response->so_rcvavoid = 0; +#else + /* it wasn't compiled in... */ + dlpi_co_rr_response->so_rcvavoid = 0; +#endif + } + + if (dlpi_co_rr_request->so_sndavoid) { +#ifdef SO_SND_COPYAVOID + dlpi_co_rr_response->so_sndavoid = 0; +#else + /* it wasn't compiled in... */ + dlpi_co_rr_response->so_sndavoid = 0; +#endif + } + + netperf_response.content.serv_errno = 0; + + /* But wait, there's more. If the initiator wanted cpu measurements, */ + /* then we must call the calibrate routine, which will return the max */ + /* rate back to the initiator. If the CPU was not to be measured, or */ + /* something went wrong with the calibration, we will return a 0.0 to */ + /* the initiator. */ + + dlpi_co_rr_response->cpu_rate = 0.0; /* assume no cpu */ + if (dlpi_co_rr_request->measure_cpu) { + dlpi_co_rr_response->measure_cpu = 1; + dlpi_co_rr_response->cpu_rate = calibrate_local_cpu(dlpi_co_rr_request->cpu_rate); + } + + send_response(); + + /* accept a connection on this file descriptor. at some point, */ + /* dl_accept will "do the right thing" with the last two parms, but */ + /* for now it ignores them, so we will pass zeros. */ + + if(dl_accept(data_descriptor, 0, 0) != 0) { + fprintf(where, + "recv_dlpi_co_rr: error in accept, errno %d\n", + errno); + fflush(where); + netperf_response.content.serv_errno = errno; + send_response(); + exit(1); + } + + if (debug) { + fprintf(where, + "recv_dlpi_co_rr: accept completes on the data connection.\n"); + fflush(where); + } + + /* Now it's time to start receiving data on the connection. We will */ + /* first grab the apropriate counters and then start grabbing. */ + + cpu_start(dlpi_co_rr_request->measure_cpu); + + /* The loop will exit when the sender does a shutdown, which will */ + /* return a length of zero */ + + if (dlpi_co_rr_request->test_length > 0) { + times_up = 0; + trans_remaining = 0; + start_timer(dlpi_co_rr_request->test_length + PAD_TIME); + } +else { + times_up = 1; + trans_remaining = dlpi_co_rr_request->test_length * -1; +} + + while ((!times_up) || (trans_remaining > 0)) { + request_bytes_remaining = dlpi_co_rr_request->request_size; + + /* receive the request from the other side. there needs to be some */ + /* more login in place for handling messages larger than link mtu, */ + /* but that can wait for later */ + while(request_bytes_remaining > 0) { + if((getmsg(data_descriptor, + 0, + &recv_message, + &flags)) < 0) { + if (errno == EINTR) { + /* the timer popped */ + timed_out = 1; + break; + } + + if (debug) { + fprintf(where,"failed getmsg call errno %d\n",errno); + fprintf(where,"recv_message.len %d\n",recv_message.len); + fprintf(where,"send_message.len %d\n",send_message.len); + fflush(where); + } + + netperf_response.content.serv_errno = errno; + send_response(); + exit(1); + } + else { + request_bytes_remaining -= recv_message.len; + } + } + + if (timed_out) { + /* we hit the end of the test based on time - lets bail out of */ + /* here now... */ + break; + } + + if (debug) { + fprintf(where,"recv_message.len %d\n",recv_message.len); + fprintf(where,"send_message.len %d\n",send_message.len); + fflush(where); + } + + /* Now, send the response to the remote */ + if((putmsg(data_descriptor, + 0, + &send_message, + 0)) != 0) { + if (errno == EINTR) { + /* the test timer has popped */ + timed_out = 1; + break; + } + netperf_response.content.serv_errno = 994; + send_response(); + exit(1); + } + + trans_received++; + if (trans_remaining) { + trans_remaining--; + } + + if (debug) { + fprintf(where, + "recv_dlpi_co_rr: Transaction %d complete\n", + trans_received); + fflush(where); + } + } + + + /* The loop now exits due to timeout or transaction count being */ + /* reached */ + + cpu_stop(dlpi_co_rr_request->measure_cpu,&elapsed_time); + + if (timed_out) { + /* we ended the test by time, which was at least 2 seconds */ + /* longer than we wanted to run. so, we want to subtract */ + /* PAD_TIME from the elapsed_time. */ + elapsed_time -= PAD_TIME; + } + /* send the results to the sender */ + + if (debug) { + fprintf(where, + "recv_dlpi_co_rr: got %d transactions\n", + trans_received); + fflush(where); + } + + dlpi_co_rr_results->bytes_received = (trans_received * + (dlpi_co_rr_request->request_size + + dlpi_co_rr_request->response_size)); + dlpi_co_rr_results->trans_received = trans_received; + dlpi_co_rr_results->elapsed_time = elapsed_time; + if (dlpi_co_rr_request->measure_cpu) { + dlpi_co_rr_results->cpu_util = calc_cpu_util(elapsed_time); + } + + if (debug) { + fprintf(where, + "recv_dlpi_co_rr: test complete, sending results.\n"); + fflush(where); + } + + send_response(); + +} + +/* this routine will display the usage string for the DLPI tests */ +void + print_dlpi_usage() + +{ + fwrite(dlpi_usage, sizeof(char), strlen(dlpi_usage), stdout); +} + + +/* this routine will scan the command line for DLPI test arguments */ +void + scan_dlpi_args(int argc, char *argv[]) +{ + extern int optind, opterrs; /* index of first unused arg */ + extern char *optarg; /* pointer to option string */ + + int c; + + char arg1[BUFSIZ], /* argument holders */ + arg2[BUFSIZ]; + + if (no_control) { + fprintf(where, + "The DLPI tests do not know how to run with no control connection\n"); + exit(-1); + } + + /* Go through all the command line arguments and break them */ + /* out. For those options that take two parms, specifying only */ + /* the first will set both to that value. Specifying only the */ + /* second will leave the first untouched. To change only the */ + /* first, use the form first, (see the routine break_args.. */ + +#define DLPI_ARGS "D:hM:m:p:r:s:W:w:" + + while ((c= getopt(argc, argv, DLPI_ARGS)) != EOF) { + switch (c) { + case '?': + case 'h': + print_dlpi_usage(); + exit(1); + case 'D': + /* set the dlpi device file name(s) */ + break_args(optarg,arg1,arg2); + if (arg1[0]) + strcpy(loc_dlpi_device,arg1); + if (arg2[0]) + strcpy(rem_dlpi_device,arg2); + break; + case 'm': + /* set the send size */ + send_size = atoi(optarg); + break; + case 'M': + /* set the recv size */ + recv_size = atoi(optarg); + break; + case 'p': + /* set the local/remote ppa */ + break_args(optarg,arg1,arg2); + if (arg1[0]) + loc_ppa = atoi(arg1); + if (arg2[0]) + rem_ppa = atoi(arg2); + break; + case 'r': + /* set the request/response sizes */ + break_args(optarg,arg1,arg2); + if (arg1[0]) + req_size = atoi(arg1); + if (arg2[0]) + rsp_size = atoi(arg2); + break; + case 's': + /* set the 802.2 sap for the test */ + dlpi_sap = atoi(optarg); + break; + case 'w': + /* set local window sizes */ + break_args(optarg,arg1,arg2); + if (arg1[0]) + lsw_size = atoi(arg1); + if (arg2[0]) + lrw_size = atoi(arg2); + break; + case 'W': + /* set remote window sizes */ + break_args(optarg,arg1,arg2); + if (arg1[0]) + rsw_size = atoi(arg1); + if (arg2[0]) + rrw_size = atoi(arg2); + break; + }; + } +} + + +#endif /* WANT_DLPI */ diff --git a/src/nettest_dlpi.h b/src/nettest_dlpi.h new file mode 100644 index 0000000..8169237 --- /dev/null +++ b/src/nettest_dlpi.h @@ -0,0 +1,215 @@ +/* + Copyright (C) 1993, Hewlett-Packard Company +*/ + + /* This file contains the test-specific definitions for netperf's */ + /* DLPI tests */ + + +struct dlpi_co_stream_request_struct { + int recv_win_size; + int send_win_size; + int receive_size; /* how many bytes do we want to */ + /* receive at one time? */ + int recv_alignment; /* what is the alignment of the */ + /* receive buffer? */ + int recv_offset; /* and at what offset from that */ + /* alignment? */ + int measure_cpu; /* does the client want server cpu */ + /* utilization measured? */ + float cpu_rate; /* do we know how fast the cpu is */ + /* already? */ + int test_length; /* how long is the test? */ + int so_rcvavoid; /* do we want the remote to avoid */ + /* copies on receives? */ + int so_sndavoid; /* do we want the remote to avoid send copies? */ + int dirty_count; /* how many integers in the receive buffer */ + /* should be made dirty before calling recv? */ + int clean_count; /* how many integers should be read from the */ + /* recv buffer before calling recv? */ + int sap; /* */ + int ppa; /* which device do we wish to use? */ + int dev_name_len; /* the length of the device name string. this */ + /* is used to put it into the proper order on */ + /* @#$% byte-swapped boxes... */ + char dlpi_device[32]; /* the path to the dlpi device */ +}; + +struct dlpi_co_stream_response_struct { + int recv_win_size; /* how big does the client want it */ + int send_win_size; + int receive_size; + int measure_cpu; /* does the client want server cpu */ + int test_length; /* how long is the test? */ + int data_port_number; /* connect to me here */ + float cpu_rate; /* could we measure */ + int so_rcvavoid; /* could the remote avoid receive copies? */ + int so_sndavoid; /* could the remote avoid send copies? */ + int station_addr_len; + int station_addr[1];/* what is the station address for the */ + /* specified ppa? */ +}; + +struct dlpi_co_stream_results_struct { + int bytes_received; /* ignored initially */ + int recv_calls; /* ignored initially */ + float elapsed_time; /* how long the test ran */ + float cpu_util; /* -1 if not measured */ + float serv_dem; /* -1 if not measured */ + int cpu_method; /* how was CPU util measured? */ + int num_cpus; /* how many CPUs were there? */ +}; + +struct dlpi_co_rr_request_struct { + int recv_win_size; /* how big does the client want it */ + int send_win_size; + int recv_alignment; + int recv_offset; + int send_alignment; + int send_offset; + int request_size; + int response_size; + int measure_cpu; /* does the client want server cpu */ + float cpu_rate; /* do we know how fast the cpu is? */ + int test_length; /* how long is the test? */ + int so_rcvavoid; /* do we want the remote to avoid receive copies? */ + int so_sndavoid; /* do we want the remote to avoid send copies? */ + int ppa; /* which device do we wish to use? */ + int sap; /* which sap should be used? */ + int dev_name_len; /* the length of the device name string. this */ + /* is used to put it into the proper order on */ + /* @#$% byte-swapped boxes... */ + char dlpi_device[32]; /* the path to the dlpi device */ +}; + +struct dlpi_co_rr_response_struct { + int recv_win_size; /* how big does the client want it */ + int send_win_size; + int measure_cpu; /* does the client want server cpu */ + int test_length; /* how long is the test? */ + int data_port_number; /* connect to me here */ + float cpu_rate; /* could we measure */ + int so_rcvavoid; /* could the remote avoid receive copies? */ + int so_sndavoid; /* could the remote avoid send copies? */ + int station_addr_len; /* the length of the station address */ + int station_addr[1]; /* the remote's station address */ +}; + +struct dlpi_co_rr_results_struct { + int bytes_received; /* ignored initially */ + int recv_calls; /* ignored initially */ + int trans_received; /* not ignored */ + float elapsed_time; /* how long the test ran */ + float cpu_util; /* -1 if not measured */ + float serv_dem; /* -1 if not measured */ + int cpu_method; /* how was CPU util measured? */ + int num_cpus; /* how many CPUs were there? */ +}; + +struct dlpi_cl_stream_request_struct { + int recv_win_size; + int message_size; + int recv_alignment; + int recv_offset; + int checksum_off; + int measure_cpu; + float cpu_rate; + int test_length; + int so_rcvavoid; /* do we want the remote to avoid receive copies? */ + int so_sndavoid; /* do we want the remote to avoid send copies? */ + int ppa; /* which device do we wish to use? */ + int sap; + int dev_name_len; /* the length of the device name string. this */ + /* is used to put it into the proper order on */ + /* @#$% byte-swapped boxes... */ + char dlpi_device[32]; /* the path to the dlpi device */ +}; + +struct dlpi_cl_stream_response_struct { + int recv_win_size; + int send_win_size; + int measure_cpu; + int test_length; + int data_port_number; + float cpu_rate; + int so_rcvavoid; /* could the remote avoid receive copies? */ + int so_sndavoid; /* could the remote avoid send copies? */ + int station_addr_len; /* the length of the station address */ + int station_addr[1]; /* the remote's station address */ +}; + +struct dlpi_cl_stream_results_struct { + int messages_recvd; + int bytes_received; + float elapsed_time; + float cpu_util; + int num_cpus; +}; + + +struct dlpi_cl_rr_request_struct { + int recv_win_size; /* how big does the client want it */ + int send_win_size; + int recv_alignment; + int recv_offset; + int send_alignment; + int send_offset; + int request_size; + int response_size; + int no_delay; + int measure_cpu; /* does the client want server cpu */ + float cpu_rate; /* do we know how fast the cpu is? */ + int test_length; /* how long is the test? */ + int so_rcvavoid; /* do we want the remote to avoid receive */ + /* copies? */ + int so_sndavoid; /* do we want the remote to avoid send copies? */ + int ppa; /* which device do we wish to use? */ + int sap; /* which sap? */ + int dev_name_len; /* the length of the device name string. this */ + /* is used to put it into the proper order on */ + /* @#$% byte-swapped boxes... */ + char dlpi_device[32]; /* the path to the dlpi device */ +}; + +struct dlpi_cl_rr_response_struct { + int recv_win_size; /* how big does the client want it */ + int send_win_size; + int no_delay; + int measure_cpu; /* does the client want server cpu */ + int test_length; /* how long is the test? */ + int data_port_number; /* connect to me here */ + float cpu_rate; /* could we measure */ + int so_rcvavoid; /* could the remote avoid receive copies? */ + int so_sndavoid; /* could the remote avoid send copies? */ + int station_addr_len; /* the length of the station address */ + int station_addr[1]; /* the remote's station address */ +}; + +struct dlpi_cl_rr_results_struct { + int bytes_received; /* ignored initially */ + int recv_calls; /* ignored initially */ + int trans_received; /* not ignored */ + float elapsed_time; /* how long the test ran */ + float cpu_util; /* -1 if not measured */ + float serv_dem; /* -1 if not measured */ + int cpu_method; /* how was CPU util measured? */ + int num_cpus; /* how many CPUs were there? */ +}; + +extern void send_dlpi_co_stream(); + +extern int recv_dlpi_co_stream(); + +extern int send_dlpi_co_rr(char remote_host[]); + +extern void send_dlpi_cl_stream(char remote_host[]); + +extern int recv_dlpi_cl_stream(); + +extern int send_dlpi_cl_rr(char remote_host[]); + +extern int recv_dlpi_cl_rr(); + +extern int recv_dlpi_co_rr(); + +extern void scan_dlpi_args(int argc, char *argv[]); diff --git a/src/nettest_omni.c b/src/nettest_omni.c new file mode 100644 index 0000000..58b2560 --- /dev/null +++ b/src/nettest_omni.c @@ -0,0 +1,6127 @@ +#ifdef HAVE_CONFIG_H +#include +#endif + +#ifdef WANT_OMNI +char nettest_omni_id[]="\ +@(#)nettest_omni.c (c) Copyright 2008 Hewlett-Packard Co. Version 2.5.0pre"; + +#include +#if HAVE_SYS_TYPES_H +# include +#endif +#if HAVE_SYS_STAT_H +# include +#endif +#if STDC_HEADERS +# include +# include +#else +# if HAVE_STDLIB_H +# include +# endif +#endif +#if HAVE_STRING_H +# if !STDC_HEADERS && HAVE_MEMORY_H +# include +# endif +# include +#endif +#if HAVE_STRINGS_H +# include +#endif +#if HAVE_INTTYPES_H +# include +#else +# if HAVE_STDINT_H +# include +# endif +#endif +#if HAVE_UNISTD_H +# include +#endif + +#include +#ifndef WIN32 +#include +#include +#endif + +#if TIME_WITH_SYS_TIME +# include +# include +#else +# if HAVE_SYS_TIME_H +# include +# else +# include +# endif +#endif + +#include + +#ifdef NOSTDLIBH +#include +#endif /* NOSTDLIBH */ + +#ifdef WANT_SCTP +#include +#endif + +#ifndef WIN32 +#if !defined(__VMS) +#include +#endif /* !defined(__VMS) */ +#include +#include +#include +#include +#include +#else /* WIN32 */ +#include +#define netperf_socklen_t socklen_t +#include + +/* while it is unlikely that anyone running Windows 2000 or NT 4 is + going to be trying to compile this, if they are they will want to + define DONT_IPV6 in the sources file */ +#ifndef DONT_IPV6 +#include +#endif +#include + +#define sleep(x) Sleep((x)*1000) + +#define __func__ __FUNCTION__ +#endif /* WIN32 */ + +/* We don't want to use bare constants in the shutdown() call. In the + extremely unlikely event that SHUT_WR isn't defined, we will define + it to the value we used to be passing to shutdown() anyway. raj + 2007-02-08 */ +#if !defined(SHUT_WR) +#define SHUT_WR 1 +#endif + +#if !defined(HAVE_GETADDRINFO) || !defined(HAVE_GETNAMEINFO) +# include "missing/getaddrinfo.h" +#endif + +#include "netlib.h" +#include "netsh.h" +#include "nettest_bsd.h" + +#if defined(WANT_HISTOGRAM) || defined(WANT_DEMO) +#include "hist.h" +#endif /* WANT_HISTOGRAM */ + +#ifdef WANT_HISTOGRAM +#ifdef HAVE_GETHRTIME +static hrtime_t time_one; +static hrtime_t time_two; +#elif HAVE_GET_HRT +#include "hrt.h" +static hrt_t time_one; +static hrt_t time_two; +#elif defined(WIN32) +static LARGE_INTEGER time_one; +static LARGE_INTEGER time_two; +#else +static struct timeval time_one; +static struct timeval time_two; +#endif /* HAVE_GETHRTIME */ +static HIST time_hist; +#endif /* WANT_HISTOGRAM */ + +#ifdef WANT_DEMO +#ifdef HAVE_GETHRTIME +static hrtime_t demo_one; +static hrtime_t demo_two; +static hrtime_t *demo_one_ptr = &demo_one; +static hrtime_t *demo_two_ptr = &demo_two; +static hrtime_t *temp_demo_ptr = &demo_one; +#elif defined(WIN32) +static LARGE_INTEGER demo_one; +static LARGE_INTEGER demo_two; +static LARGE_INTEGER *demo_one_ptr = &demo_one; +static LARGE_INTEGER *demo_two_ptr = &demo_two; +static LARGE_INTEGER *temp_demo_ptr = &demo_one; +#else +static struct timeval demo_one; +static struct timeval demo_two; +static struct timeval *demo_one_ptr = &demo_one; +static struct timeval *demo_two_ptr = &demo_two; +static struct timeval *temp_demo_ptr = &demo_one; +#endif + +/* for a _STREAM test, "a" should be lss_size and "b" should be + rsr_size. for a _MAERTS test, "a" should be lsr_size and "b" should + be rss_size. raj 2005-04-06 */ +#define DEMO_STREAM_SETUP(a,b) \ + if ((demo_mode) && (demo_units == 0)) { \ + /* take our default value of demo_units to be the larger of \ + twice the remote's SO_RCVBUF or twice our SO_SNDBUF */ \ + if (a > b) { \ + demo_units = 2*a; \ + } \ + else { \ + demo_units = 2*b; \ + } \ + } + +#define DEMO_INTERVAL(units) \ + if (demo_mode) { \ + double actual_interval; \ + units_this_tick += units; \ + if (units_this_tick >= demo_units) { \ + /* time to possibly update demo_units and maybe output an \ + interim result */ \ + HIST_timestamp(demo_two_ptr); \ + actual_interval = delta_micro(demo_one_ptr,demo_two_ptr); \ + /* we always want to fine-tune demo_units here whether we \ + emit an interim result or not. if we are short, this \ + will lengthen demo_units. if we are long, this will \ + shorten it */ \ + demo_units = demo_units * (demo_interval / actual_interval); \ + if (actual_interval >= demo_interval) { \ + /* time to emit an interim result */ \ + fprintf(where, \ + "Interim result: %7.2f %s/s over %.2f seconds\n", \ + calc_thruput_interval(units_this_tick, \ + actual_interval/1000000.0), \ + format_units(), \ + actual_interval/1000000.0); \ + units_this_tick = 0.0; \ + /* now get a new starting timestamp. we could be clever \ + and swap pointers - the math we do probably does not \ + take all that long, but for now this will suffice */ \ + temp_demo_ptr = demo_one_ptr; \ + demo_one_ptr = demo_two_ptr; \ + demo_two_ptr = temp_demo_ptr; \ + } \ + } \ + } + +#define DEMO_STREAM_INTERVAL(units) DEMO_INTERVAL(units) + +#define DEMO_RR_SETUP(a) \ + if ((demo_mode) && (demo_units == 0)) { \ + /* take whatever we are given */ \ + demo_units = a; \ + } + +#define DEMO_RR_INTERVAL(units) DEMO_INTERVAL(units) + +#endif + +#ifdef WANT_INTERVALS +int interval_count; +#ifndef WANT_SPIN +sigset_t signal_set; +#define INTERVALS_INIT() \ + if (interval_burst) { \ + /* zero means that we never pause, so we never should need the \ + interval timer. we used to use it for demo mode, but we deal \ + with that with a variant on watching the clock rather than \ + waiting for a timer. raj 2006-02-06 */ \ + start_itimer(interval_wate); \ + } \ + interval_count = interval_burst; \ + /* get the signal set for the call to sigsuspend */ \ + if (sigprocmask(SIG_BLOCK, (sigset_t *)NULL, &signal_set) != 0) { \ + fprintf(where, \ + "%s: unable to get sigmask errno %d\n", \ + __func__, \ + errno); \ + fflush(where); \ + exit(1); \ + } + +#define INTERVALS_WAIT() \ + /* in this case, the interval count is the count-down couter \ + to decide to sleep for a little bit */ \ + if ((interval_burst) && (--interval_count == 0)) { \ + /* call sigsuspend and wait for the interval timer to get us \ + out */ \ + if (debug > 1) { \ + fprintf(where,"about to suspend\n"); \ + fflush(where); \ + } \ + if (sigsuspend(&signal_set) == EFAULT) { \ + fprintf(where, \ + "%s: fault with sigsuspend.\n", \ + __func__); \ + fflush(where); \ + exit(1); \ + } \ + interval_count = interval_burst; \ + } +#else +/* first out timestamp */ +#ifdef HAVE_GETHRTIME +static hrtime_t intvl_one; +static hrtime_t intvl_two; +static hrtime_t *intvl_one_ptr = &intvl_one; +static hrtime_t *intvl_two_ptr = &intvl_two; +static hrtime_t *temp_intvl_ptr = &intvl_one; +#elif defined(WIN32) +static LARGE_INTEGER intvl_one; +static LARGE_INTEGER intvl_two; +static LARGE_INTEGER *intvl_one_ptr = &intvl_one; +static LARGE_INTEGER *intvl_two_ptr = &intvl_two; +static LARGE_INTEGER *temp_intvl_ptr = &intvl_one; +#else +static struct timeval intvl_one; +static struct timeval intvl_two; +static struct timeval *intvl_one_ptr = &intvl_one; +static struct timeval *intvl_two_ptr = &intvl_two; +static struct timeval *temp_intvl_ptr = &intvl_one; +#endif + +#define INTERVALS_INIT() \ + if (interval_burst) { \ + HIST_timestamp(intvl_one_ptr); \ + } \ + interval_count = interval_burst; \ + +#define INTERVALS_WAIT() \ + /* in this case, the interval count is the count-down couter \ + to decide to sleep for a little bit */ \ + if ((interval_burst) && (--interval_count == 0)) { \ + /* call sigsuspend and wait for the interval timer to get us \ + out */ \ + if (debug > 1) { \ + fprintf(where,"about to spin suspend\n"); \ + fflush(where); \ + } \ + HIST_timestamp(intvl_two_ptr); \ + while(delta_micro(intvl_one_ptr,intvl_two_ptr) < interval_usecs) { \ + HIST_timestamp(intvl_two_ptr); \ + } \ + temp_intvl_ptr = intvl_one_ptr; \ + intvl_one_ptr = intvl_two_ptr; \ + intvl_two_ptr = temp_intvl_ptr; \ + interval_count = interval_burst; \ + } +#endif +#endif + +#define NETPERF_WAITALL 0x1 +#define NETPERF_XMIT 0x2 +#define NETPERF_RECV 0x4 + +#define NETPERF_IS_RR(x) (((x & NETPERF_XMIT) && (x & NETPERF_RECV)) || \ + (!((x & NETPERF_XMIT) || (x & NETPERF_RECV)))) + +#define NETPERF_RECV_ONLY(x) ((x & NETPERF_RECV) && !(x & NETPERF_XMIT)) + +#define NETPERF_XMIT_ONLY(x) ((x & NETPERF_XMIT) && !(x & NETPERF_RECV)) + +#define NETPERF_CC(x) (!(x & NETPERF_XMIT) && !(x & NETPERF_RECV)) + +extern void get_uuid_string(char *string, size_t size); + +/* a boatload of globals while I settle things out */ +char *csv_selection_file = NULL; +char *human_selection_file = NULL; +char *keyword_selection_file = NULL; + +char test_uuid[38]; + +double result_confid_pct = -1.0; +double loc_cpu_confid_pct = -1.0; +double rem_cpu_confid_pct = -1.0; +double interval_pct = -1.0; + +int protocol; +int direction; +int remote_send_size = -1; +int remote_recv_size = -1; +int remote_send_size_req = -1; +int remote_recv_size_req = -1; +int remote_use_sendfile; +#if 0 +int remote_send_dirty_count; +int remote_recv_dirty_count; +int remote_recv_clean_count; +#endif +extern int loc_dirty_count; +extern int loc_clean_count; +extern int rem_dirty_count; +extern int rem_clean_count; +int remote_checksum_off; +int connection_test; +int need_to_connect; +int need_connection; +int bytes_to_send; +double bytes_per_send; +int failed_sends; +int bytes_to_recv; +double bytes_per_recv; +int null_message_ok = 0; +int csv = 0; +int keyword = 0; +uint64_t trans_completed = 0; +uint64_t units_remaining; +uint64_t bytes_sent = 0; +uint64_t bytes_received = 0; +uint64_t local_send_calls = 0; +uint64_t local_receive_calls = 0; +uint64_t remote_bytes_sent; +uint64_t remote_bytes_received; +uint64_t remote_send_calls; +uint64_t remote_receive_calls; +double bytes_xferd; +double remote_bytes_xferd; +double remote_bytes_per_recv; +double remote_bytes_per_send; +float elapsed_time; +float local_cpu_utilization; +float local_service_demand; +float remote_cpu_utilization; +float remote_service_demand; +double thruput; +double local_send_thruput; +double local_recv_thruput; +double remote_send_thruput; +double remote_recv_thruput; + +/* kludges for omni output */ +double elapsed_time_double; +double local_cpu_utilization_double; +double local_service_demand_double; +double remote_cpu_utilization_double; +double remote_service_demand_double; +double transaction_rate = 1.0; +double rtt_latency = -1.0; +int32_t transport_mss = -2; +char *local_interface_name=NULL; +char *remote_interface_name=NULL; +char local_driver_name[32]=""; +char local_driver_version[32]=""; +char local_driver_firmware[32]=""; +char local_driver_bus[32]=""; +char remote_driver_name[32]=""; +char remote_driver_version[32]=""; +char remote_driver_firmware[32]=""; +char remote_driver_bus[32]=""; +char *local_interface_slot=NULL; +char *remote_interface_slot=NULL; +int remote_interface_vendor; +int remote_interface_device; +int remote_interface_subvendor; +int remote_interface_subdevice; +int local_interface_vendor; +int local_interface_device; +int local_interface_subvendor; +int local_interface_subdevice; +char *local_system_model; +char *local_cpu_model; +int local_cpu_frequency; +char *remote_system_model; +char *remote_cpu_model; +int remote_cpu_frequency; + +int local_security_type_id; +int local_security_enabled_num; +char *local_security_type; +char *local_security_enabled; +char *local_security_specific; +int remote_security_type_id; +int remote_security_enabled_num; +char *remote_security_enabled; +char *remote_security_type; +char *remote_security_specific; + +int printing_initialized = 0; + +char *sd_str; +char *thruput_format_str; + +char *socket_type_str; +char *protocol_str; +char *direction_str; + +extern int first_burst_size; + +#if defined(HAVE_SENDFILE) && (defined(__linux) || defined(__sun)) +#include +#endif /* HAVE_SENDFILE && (__linux || __sun) */ + +static int confidence_iteration; + +static int local_cpu_method; +static int remote_cpu_method; + +/* these will control the width of port numbers we try to use in the */ +/* TCP_CRR and/or TCP_TRR tests. raj 3/95 */ +static int client_port_min = 5000; +static int client_port_max = 65535; + + /* different options for the sockets */ + +int + loc_nodelay, /* don't/do use NODELAY locally */ + rem_nodelay, /* don't/do use NODELAY remotely */ + loc_sndavoid, /* avoid send copies locally */ + loc_rcvavoid, /* avoid recv copies locally */ + rem_sndavoid, /* avoid send copies remotely */ + rem_rcvavoid; /* avoid recv_copies remotely */ + +extern int + loc_tcpcork, + rem_tcpcork, + local_connected, + remote_connected; + +/* you should add to this in the order in which they should appear in + the default csv (everything) output */ + +enum netperf_output_name { + OUTPUT_NONE, + SOCKET_TYPE, + PROTOCOL, + DIRECTION, + ELAPSED_TIME, + THROUGHPUT, + THROUGHPUT_UNITS, + LSS_SIZE_REQ, + LSS_SIZE, + LSS_SIZE_END, + LSR_SIZE_REQ, + LSR_SIZE, + LSR_SIZE_END, + RSS_SIZE_REQ, + RSS_SIZE, + RSS_SIZE_END, + RSR_SIZE_REQ, + RSR_SIZE, + RSR_SIZE_END, + LOCAL_SEND_SIZE, + LOCAL_RECV_SIZE, + REMOTE_SEND_SIZE, + REMOTE_RECV_SIZE, + REQUEST_SIZE, + RESPONSE_SIZE, + LOCAL_CPU_UTIL, + LOCAL_CPU_METHOD, + LOCAL_SD, + REMOTE_CPU_UTIL, + REMOTE_CPU_METHOD, + REMOTE_SD, + SD_UNITS, + CONFIDENCE_LEVEL, + CONFIDENCE_INTERVAL, + CONFIDENCE_ITERATION, + THROUGHPUT_CONFID, + LOCAL_CPU_CONFID, + REMOTE_CPU_CONFID, + TRANSACTION_RATE, + RT_LATENCY, + BURST_SIZE, + TRANSPORT_MSS, + LOCAL_SEND_THROUGHPUT, + LOCAL_RECV_THROUGHPUT, + REMOTE_SEND_THROUGHPUT, + REMOTE_RECV_THROUGHPUT, + LOCAL_CPU_BIND, + LOCAL_CPU_COUNT, + LOCAL_CPU_PEAK_UTIL, + LOCAL_CPU_PEAK_ID, + LOCAL_CPU_MODEL, + LOCAL_CPU_FREQUENCY, + REMOTE_CPU_BIND, + REMOTE_CPU_COUNT, + REMOTE_CPU_PEAK_UTIL, + REMOTE_CPU_PEAK_ID, + REMOTE_CPU_MODEL, + REMOTE_CPU_FREQUENCY, + SOURCE_PORT, + SOURCE_ADDR, + SOURCE_FAMILY, + DEST_PORT, + DEST_ADDR, + DEST_FAMILY, + LOCAL_SEND_CALLS, + LOCAL_RECV_CALLS, + LOCAL_BYTES_PER_RECV, + LOCAL_BYTES_PER_SEND, + LOCAL_BYTES_SENT, + LOCAL_BYTES_RECVD, + LOCAL_BYTES_XFERD, + LOCAL_SEND_OFFSET, + LOCAL_RECV_OFFSET, + LOCAL_SEND_ALIGN, + LOCAL_RECV_ALIGN, + LOCAL_SEND_WIDTH, + LOCAL_RECV_WIDTH, + LOCAL_SEND_DIRTY_COUNT, + LOCAL_RECV_DIRTY_COUNT, + LOCAL_RECV_CLEAN_COUNT, + LOCAL_NODELAY, + LOCAL_CORK, + REMOTE_SEND_CALLS, + REMOTE_RECV_CALLS, + REMOTE_BYTES_PER_RECV, + REMOTE_BYTES_PER_SEND, + REMOTE_BYTES_SENT, + REMOTE_BYTES_RECVD, + REMOTE_BYTES_XFERD, + REMOTE_SEND_OFFSET, + REMOTE_RECV_OFFSET, + REMOTE_SEND_ALIGN, + REMOTE_RECV_ALIGN, + REMOTE_SEND_WIDTH, + REMOTE_RECV_WIDTH, + REMOTE_SEND_DIRTY_COUNT, + REMOTE_RECV_DIRTY_COUNT, + REMOTE_RECV_CLEAN_COUNT, + REMOTE_NODELAY, + REMOTE_CORK, + LOCAL_SYSNAME, + LOCAL_SYSTEM_MODEL, + LOCAL_RELEASE, + LOCAL_VERSION, + LOCAL_MACHINE, + REMOTE_SYSNAME, + REMOTE_SYSTEM_MODEL, + REMOTE_RELEASE, + REMOTE_VERSION, + REMOTE_MACHINE, + LOCAL_INTERFACE_NAME, + LOCAL_INTERFACE_VENDOR, + LOCAL_INTERFACE_DEVICE, + LOCAL_INTERFACE_SUBVENDOR, + LOCAL_INTERFACE_SUBDEVICE, + LOCAL_DRIVER_NAME, + LOCAL_DRIVER_VERSION, + LOCAL_DRIVER_FIRMWARE, + LOCAL_DRIVER_BUS, + LOCAL_INTERFACE_SLOT, + REMOTE_INTERFACE_NAME, + REMOTE_INTERFACE_VENDOR, + REMOTE_INTERFACE_DEVICE, + REMOTE_INTERFACE_SUBVENDOR, + REMOTE_INTERFACE_SUBDEVICE, + REMOTE_DRIVER_NAME, + REMOTE_DRIVER_VERSION, + REMOTE_DRIVER_FIRMWARE, + REMOTE_DRIVER_BUS, + REMOTE_INTERFACE_SLOT, + LOCAL_INTERVAL_USECS, + LOCAL_INTERVAL_BURST, + REMOTE_INTERVAL_USECS, + REMOTE_INTERVAL_BURST, + LOCAL_SECURITY_TYPE_ID, + LOCAL_SECURITY_TYPE, + LOCAL_SECURITY_ENABLED_NUM, + LOCAL_SECURITY_ENABLED, + LOCAL_SECURITY_SPECIFIC, + REMOTE_SECURITY_TYPE_ID, + REMOTE_SECURITY_TYPE, + REMOTE_SECURITY_ENABLED_NUM, + REMOTE_SECURITY_ENABLED, + REMOTE_SECURITY_SPECIFIC, + RESULT_BRAND, + UUID, + COMMAND_LINE, + OUTPUT_END, + NETPERF_OUTPUT_MAX +}; + +typedef struct netperf_output_elt { + enum netperf_output_name output_name; /* belt and suspenders */ + int max_line_len; /* length of the longest of the "lines" */ + int tot_line_len; /* total length of all lines, including spaces */ + char *line[4]; + char *brief; /* the brief name of the value */ + char *format; /* format to apply to value */ + void *display_value; /* where to find the value */ +} netperf_output_elt_t; + +netperf_output_elt_t netperf_output_source[NETPERF_OUTPUT_MAX]; + +/* the list of things we will emit for CSV output. I suppose we could + at some point try to make this a special case of output_human_list, + or at least use some of that space... but for now we won't worry + about it. that can come after things are actually working :) raj + 2008-01-23 */ +enum netperf_output_name output_csv_list[NETPERF_OUTPUT_MAX]; + +/* the list of things we will emit for "human" output. up to + NETPERF_MAX_BLOCKS of output (groups of lines) each out to + NETPERF_OUTPUT_MAX entries. that should more than cover it */ + +#define NETPERF_MAX_BLOCKS 4 +enum netperf_output_name output_human_list[NETPERF_MAX_BLOCKS][NETPERF_OUTPUT_MAX]; + +char *direction_to_str(int direction) { + if (NETPERF_RECV_ONLY(direction)) return "Receive"; + if (NETPERF_XMIT_ONLY(direction)) return "Send"; + if (NETPERF_CC(direction)) return "Connection"; + else return "Send|Recv"; +} + +static unsigned short +get_port_number(struct addrinfo *res) +{ + switch(res->ai_family) { + case AF_INET: { + struct sockaddr_in *foo = (struct sockaddr_in *)res->ai_addr; + return(ntohs(foo->sin_port)); + break; + } +#if defined(AF_INET6) + case AF_INET6: { + struct sockaddr_in6 *foo = (struct sockaddr_in6 *)res->ai_addr; + return(ntohs(foo->sin6_port)); + break; + } +#endif + default: + fprintf(where, + "Unexpected Address Family %u\n",res->ai_family); + fflush(where); + exit(-1); + } +} + +static void +extract_inet_address_and_port(struct addrinfo *res, void *addr, int len, int *port) +{ + switch(res->ai_family) { + case AF_INET: { + struct sockaddr_in *foo = (struct sockaddr_in *)res->ai_addr; + *port = foo->sin_port; + memcpy(addr,&(foo->sin_addr),min(len,sizeof(foo->sin_addr))); + break; + } +#if defined(AF_INET6) + case AF_INET6: { + struct sockaddr_in6 *foo = (struct sockaddr_in6 *)res->ai_addr; + *port = foo->sin6_port; + memcpy(addr,&(foo->sin6_addr),min(len,sizeof(foo->sin6_addr))); + break; + } +#endif + default: + *port = 0xDEADBEEF; + strncpy(addr,"UNKN FAMILY",len); + } +} + +void +pick_next_port_number(struct addrinfo *local_res, struct addrinfo *remote_res) { + + static int myport_init = 0; + static unsigned short myport = 0; + + if (0 == myport_init) { + /* pick a nice random spot between client_port_min and + client_port_max for our initial port number, but only for a + connection oriented test. otherwise, we will want to set myport + to a specific port provided by the user if they have so provided + a specific port :) raj 2008-01-08 */ + srand(getpid()); + if (client_port_max - client_port_min) { + myport = client_port_min + + (rand() % (client_port_max - client_port_min)); + } + else { + myport = client_port_min; + } + /* there will be a ++ before the first call to bind, so subtract one */ + myport--; + myport_init = 1; + } + + newport: + /* pick a new port number */ + myport++; + + /* check to see if we are using the port number on which the + server is sitting _before_ we check against the boundaries lest + the server sits at the upper boundary. if this happens to be a + loopback test, trying to use the same portnumber would lead to + unsatisfying results and should be avoided. if this isn't a + loopback test, avoiding using the same port number doesn't + seriously affect anything anyway */ + + if (myport == get_port_number(remote_res)) myport++; + + /* wrap the port number when we reach the upper bound. for + students of networking history, some ancient stacks (1980's and + early 1990's perhaps) mistakenly treated these port numbers as + signed 16 bit quantities. we make no effort here to support + such stacks. raj 2008-01-08 */ + if (myport >= client_port_max) { + myport = client_port_min; + } + + /* set up the data socket */ + set_port_number(local_res, (unsigned short)myport); +} + +char * +netperf_output_enum_to_str(enum netperf_output_name output_name) +{ + switch (output_name) { + case OUTPUT_NONE: + return "OUTPUT_NONE"; + case COMMAND_LINE: + return "COMMAND_LINE"; + case UUID: + return "UUID"; + case RESULT_BRAND: + return "RESULT_BRAND"; + case SOCKET_TYPE: + return "SOCKET_TYPE"; + case DIRECTION: + return "DIRECTION"; + case PROTOCOL: + return "PROTOCOL"; + case ELAPSED_TIME: + return "ELAPSED_TIME"; + case SOURCE_PORT: + return "SOURCE_PORT"; + case SOURCE_ADDR: + return "SOURCE_ADDR"; + case SOURCE_FAMILY: + return "SOURCE_FAMILY"; + case DEST_PORT: + return "DEST_PORT"; + case DEST_ADDR: + return "DEST_ADDR"; + case DEST_FAMILY: + return "DEST_FAMILY"; + case THROUGHPUT: + return "THROUGHPUT"; + case LOCAL_SEND_THROUGHPUT: + return "LOCAL_SEND_THROUGHPUT"; + case LOCAL_RECV_THROUGHPUT: + return "LOCAL_RECV_THROUGHPUT"; + case REMOTE_SEND_THROUGHPUT: + return "REMOTE_SEND_THROUGHPUT"; + case REMOTE_RECV_THROUGHPUT: + return "REMOTE_RECV_THROUGHPUT"; + case THROUGHPUT_UNITS: + return "THROUGHPUT_UNITS"; + case CONFIDENCE_LEVEL: + return "CONFIDENCE_LEVEL"; + case CONFIDENCE_INTERVAL: + return "CONFIDENCE_INTERVAL"; + case CONFIDENCE_ITERATION: + return "CONFIDENCE_ITERATION"; + case THROUGHPUT_CONFID: + return "THROUGHPUT_CONFID"; + case LOCAL_CPU_CONFID: + return "LOCAL_CPU_CONFID"; + case REMOTE_CPU_CONFID: + return "REMOTE_CPU_CONFID"; + case RT_LATENCY: + return "RT_LATENCY"; + case TRANSACTION_RATE: + return "TRANSACTION_RATE"; + case BURST_SIZE: + return "BURST_SIZE"; + case TRANSPORT_MSS: + return "TRANSPORT_MSS"; + case REQUEST_SIZE: + return "REQUEST_SIZE"; + case RESPONSE_SIZE: + return "RESPONSE_SIZE"; + case LSS_SIZE_REQ: + return "LSS_SIZE_REQ"; + case LSS_SIZE: + return "LSS_SIZE"; + case LSS_SIZE_END: + return "LSS_SIZE_END"; + case LSR_SIZE_REQ: + return "LSR_SIZE_REQ"; + case LSR_SIZE: + return "LSR_SIZE"; + case LSR_SIZE_END: + return "LSR_SIZE_END"; + case LOCAL_SEND_SIZE: + return "LOCAL_SEND_SIZE"; + case LOCAL_RECV_SIZE: + return "LOCAL_RECV_SIZE"; + case LOCAL_SEND_CALLS: + return "LOCAL_SEND_CALLS"; + case LOCAL_RECV_CALLS: + return "LOCAL_RECV_CALLS"; + case LOCAL_BYTES_PER_RECV: + return "LOCAL_BYTES_PER_RECV"; + case LOCAL_BYTES_PER_SEND: + return "LOCAL_BYTES_PER_SEND"; + case LOCAL_BYTES_SENT: + return "LOCAL_BYTES_SENT"; + case LOCAL_BYTES_RECVD: + return "LOCAL_BYTES_RECVD"; + case LOCAL_BYTES_XFERD: + return "LOCAL_BYTES_XFERD"; + case LOCAL_SEND_OFFSET: + return "LOCAL_SEND_OFFSET"; + case LOCAL_RECV_OFFSET: + return "LOCAL_RECV_OFFSET"; + case LOCAL_RECV_ALIGN: + return "LOCAL_RECV_ALIGN"; + case LOCAL_SEND_ALIGN: + return "LOCAL_SEND_ALIGN"; + case LOCAL_SEND_WIDTH: + return "LOCAL_SEND_WIDTH"; + case LOCAL_RECV_WIDTH: + return "LOCAL_RECV_WIDTH"; + case LOCAL_SEND_DIRTY_COUNT: + return "LOCAL_SEND_DIRTY_COUNT"; + case LOCAL_RECV_DIRTY_COUNT: + return "LOCAL_RECV_DIRTY_COUNT"; + case LOCAL_RECV_CLEAN_COUNT: + return "LOCAL_RECV_CLEAN_COUNT"; + case LOCAL_CPU_UTIL: + return "LOCAL_CPU_UTIL"; + case LOCAL_CPU_BIND: + return "LOCAL_CPU_BIND"; + case LOCAL_SD: + return "LOCAL_SD"; + case SD_UNITS: + return "SD_UNITS"; + case LOCAL_CPU_METHOD: + return "LOCAL_CPU_METHOD"; + case LOCAL_CPU_COUNT: + return "LOCAL_CPU_COUNT"; + case LOCAL_CPU_PEAK_UTIL: + return "LOCAL_CPU_PEAK_UTIL"; + case LOCAL_CPU_PEAK_ID: + return "LOCAL_CPU_PEAK_ID"; + case LOCAL_NODELAY: + return "LOCAL_NODELAY"; + case LOCAL_CORK: + return "LOCAL_CORK"; + case RSS_SIZE_REQ: + return "RSS_SIZE_REQ"; + case RSS_SIZE: + return "RSS_SIZE"; + case RSS_SIZE_END: + return "RSS_SIZE_END"; + case RSR_SIZE_REQ: + return "RSR_SIZE_REQ"; + case RSR_SIZE: + return "RSR_SIZE"; + case RSR_SIZE_END: + return "RSR_SIZE_END"; + case REMOTE_SEND_SIZE: + return "REMOTE_SEND_SIZE"; + case REMOTE_RECV_SIZE: + return "REMOTE_RECV_SIZE"; + case REMOTE_SEND_CALLS: + return "REMOTE_SEND_CALLS"; + case REMOTE_RECV_CALLS: + return "REMOTE_RECV_CALLS"; + case REMOTE_BYTES_PER_RECV: + return "REMOTE_BYTES_PER_RECV"; + case REMOTE_BYTES_PER_SEND: + return "REMOTE_BYTES_PER_SEND"; + case REMOTE_BYTES_SENT: + return "REMOTE_BYTES_SENT"; + case REMOTE_BYTES_RECVD: + return "REMOTE_BYTES_RECVD"; + case REMOTE_BYTES_XFERD: + return "REMOTE_BYTES_XFERD"; + case REMOTE_SEND_OFFSET: + return "REMOTE_SEND_OFFSET"; + case REMOTE_RECV_OFFSET: + return "REMOTE_RECV_OFFSET"; + case REMOTE_RECV_ALIGN: + return "REMOTE_RECV_ALIGN"; + case REMOTE_SEND_ALIGN: + return "REMOTE_SEND_ALIGN"; + case REMOTE_SEND_WIDTH: + return "REMOTE_SEND_WIDTH"; + case REMOTE_RECV_WIDTH: + return "REMOTE_RECV_WIDTH"; + case REMOTE_SEND_DIRTY_COUNT: + return "REMOTE_SEND_DIRTY_COUNT"; + case REMOTE_RECV_DIRTY_COUNT: + return "REMOTE_RECV_DIRTY_COUNT"; + case REMOTE_RECV_CLEAN_COUNT: + return "REMOTE_RECV_CLEAN_COUNT"; + case REMOTE_CPU_UTIL: + return "REMOTE_CPU_UTIL"; + case REMOTE_CPU_BIND: + return "REMOTE_CPU_BIND"; + case REMOTE_SD: + return "REMOTE_SD"; + case REMOTE_CPU_METHOD: + return "REMOTE_CPU_METHOD"; + case REMOTE_CPU_COUNT: + return "REMOTE_CPU_COUNT"; + case REMOTE_CPU_PEAK_UTIL: + return "REMOTE_CPU_PEAK_UTIL"; + case REMOTE_CPU_PEAK_ID: + return "REMOTE_CPU_PEAK_ID"; + case REMOTE_NODELAY: + return "REMOTE_NODELAY"; + case REMOTE_CORK: + return "REMOTE_CORK"; + case LOCAL_INTERFACE_SLOT: + return "LOCAL_INTERFACE_SLOT"; + case REMOTE_INTERFACE_SLOT: + return "REMOTE_INTERFACE_SLOT"; + case REMOTE_INTERFACE_SUBDEVICE: + return "REMOTE_INTERFACE_SUBDEVICE"; + case REMOTE_INTERFACE_SUBVENDOR: + return "REMOTE_INTERFACE_SUBVENDOR"; + case REMOTE_INTERFACE_DEVICE: + return "REMOTE_INTERFACE_DEVICE"; + case REMOTE_INTERFACE_VENDOR: + return "REMOTE_INTERFACE_VENDOR"; + case LOCAL_INTERFACE_SUBDEVICE: + return "LOCAL_INTERFACE_SUBDEVICE"; + case LOCAL_INTERFACE_SUBVENDOR: + return "LOCAL_INTERFACE_SUBVENDOR"; + case LOCAL_INTERFACE_DEVICE: + return "LOCAL_INTERFACE_DEVICE"; + case LOCAL_INTERFACE_VENDOR: + return "LOCAL_INTERFACE_VENDOR"; + case LOCAL_INTERFACE_NAME: + return "LOCAL_INTERFACE_NAME"; + case REMOTE_INTERFACE_NAME: + return "REMOTE_INTERFACE_NAME"; + case REMOTE_DRIVER_NAME: + return "REMOTE_DRIVER_NAME"; + case REMOTE_DRIVER_VERSION: + return "REMOTE_DRIVER_VERSION"; + case REMOTE_DRIVER_FIRMWARE: + return "REMOTE_DRIVER_FIRMWARE"; + case REMOTE_DRIVER_BUS: + return "REMOTE_DRIVER_BUS"; + case LOCAL_DRIVER_NAME: + return "LOCAL_DRIVER_NAME"; + case LOCAL_DRIVER_VERSION: + return "LOCAL_DRIVER_VERSION"; + case LOCAL_DRIVER_FIRMWARE: + return "LOCAL_DRIVER_FIRMWARE"; + case LOCAL_INTERVAL_USECS: + return "LOCAL_INTERVAL_USECS"; + case LOCAL_INTERVAL_BURST: + return "LOCAL_INTERVAL_BURST"; + case REMOTE_INTERVAL_USECS: + return "REMOTE_INTERVAL_USECS"; + case REMOTE_INTERVAL_BURST: + return "REMOTE_INTERVAL_BURST"; + case LOCAL_SECURITY_TYPE_ID: + return "LOCAL_SECURITY_TYPE_ID"; + case LOCAL_SECURITY_ENABLED_NUM: + return "LOCAL_SECURITY_ENABLED_NUM"; + case LOCAL_SECURITY_TYPE: + return "LOCAL_SECURITY_TYPE"; + case LOCAL_SECURITY_ENABLED: + return "LOCAL_SECURITY_ENABLED"; + case LOCAL_SECURITY_SPECIFIC: + return "LOCAL_SECURITY_SPECIFIC"; + case REMOTE_SECURITY_TYPE_ID: + return "REMOTE_SECURITY_TYPE_ID"; + case REMOTE_SECURITY_ENABLED_NUM: + return "REMOTE_SECURITY_ENABLED_NUM"; + case REMOTE_SECURITY_TYPE: + return "REMOTE_SECURITY_TYPE"; + case REMOTE_SECURITY_ENABLED: + return "REMOTE_SECURITY_ENABLED"; + case REMOTE_SECURITY_SPECIFIC: + return "REMOTE_SECURITY_SPECIFIC"; + case LOCAL_DRIVER_BUS: + return "LOCAL_DRIVER_BUS"; + case REMOTE_SYSNAME: + return "REMOTE_SYSNAME"; + case REMOTE_MACHINE: + return "REMOTE_MACHINE"; + case REMOTE_VERSION: + return "REMOTE_VERSION"; + case REMOTE_RELEASE: + return "REMOTE_RELEASE"; + case LOCAL_SYSNAME: + return "LOCAL_SYSNAME"; + case LOCAL_MACHINE: + return "LOCAL_MACHINE"; + case LOCAL_VERSION: + return "LOCAL_VERSION"; + case LOCAL_RELEASE: + return "LOCAL_RELEASE"; + case REMOTE_CPU_MODEL: + return "REMOTE_CPU_MODEL"; + case REMOTE_CPU_FREQUENCY: + return "REMOTE_CPU_FREQUENCY"; + case REMOTE_SYSTEM_MODEL: + return "REMOTE_SYSTEM_MODEL"; + case LOCAL_CPU_MODEL: + return "LOCAL_CPU_MODEL"; + case LOCAL_CPU_FREQUENCY: + return "LOCAL_CPU_FREQUENCY"; + case LOCAL_SYSTEM_MODEL: + return "LOCAL_SYSTEM_MODEL"; + case OUTPUT_END: + return "OUTPUT_END"; + default: + return "!UNKNOWN OUTPUT SELECTOR!"; + } +} + +void +print_netperf_output_entry(FILE *where, enum netperf_output_name what) +{ +} + +void print_omni_init_list(); + +void +dump_netperf_output_list(FILE *where, int csv) { + int i; + + print_omni_init_list(); + + for (i = OUTPUT_NONE; i < NETPERF_OUTPUT_MAX; i++){ + if (OUTPUT_NONE != i) { + fprintf(where,"%c",(csv) ? ',' : '\n'); + } + fprintf(where, + "%s", + netperf_output_enum_to_str(netperf_output_source[i].output_name)); + } + fprintf(where,"\n"); + fflush(where); +} + +void +dump_netperf_output_source(FILE *where) +{ + int i; + + /* belts and suspenders everyone... */ + for (i = OUTPUT_NONE; i < NETPERF_OUTPUT_MAX; i++) { + fprintf(where, + "Output Name: %s\n", + netperf_output_enum_to_str(netperf_output_source[i].output_name)); + fprintf(where, + "\tmax_line_len %d tot_line_len %d display_value %p\n", + netperf_output_source[i].max_line_len, + netperf_output_source[i].tot_line_len, + netperf_output_source[i].display_value); + fprintf(where, + "\tline[0]: |%s|\n", + (netperf_output_source[i].line[0] == NULL) ? "" : + netperf_output_source[i].line[0]); + fprintf(where, + "\tline[1]: |%s|\n", + (netperf_output_source[i].line[1] == NULL) ? "" : + netperf_output_source[i].line[1]); + fprintf(where, + "\tline[2]: |%s|\n", + (netperf_output_source[i].line[2] == NULL) ? "" : + netperf_output_source[i].line[2]); + fprintf(where, + "\tline[3]: |%s|\n", + (netperf_output_source[i].line[3] == NULL) ? "" : + netperf_output_source[i].line[3]); + fprintf(where, + "\tbrief: |%s|\n", + (netperf_output_source[i].brief == NULL) ? "" : + netperf_output_source[i].brief); + fprintf(where, + "\tformat: |%s|\n", + (netperf_output_source[i].format == NULL) ? "" : + netperf_output_source[i].format); + } + fflush(where); +} + +#define MY_MAX(a,b) ((a > b) ? a : b) + +#define NETPERF_LINE_MAX(x) \ + MY_MAX(MY_MAX(MY_MAX(strlen(netperf_output_source[x].line[0]),\ + strlen(netperf_output_source[x].line[1])),\ + strlen(netperf_output_source[x].line[2])),\ + strlen(netperf_output_source[x].line[3])) + +#define NETPERF_LINE_TOT(x) \ + strlen(netperf_output_source[x].line[0]) +\ + strlen(netperf_output_source[x].line[1]) +\ + strlen(netperf_output_source[x].line[2]) +\ + strlen(netperf_output_source[x].line[3]) + 4 + +enum netperf_output_name +match_string_to_output(char *candidate) +{ + char *h1,*temp; + enum netperf_output_name name; + int k,len; + + /* at some point we may need/want to worry about leading and + trailing spaces, but for now we will leave that onus on the + user. */ + + for (name = OUTPUT_NONE; name < NETPERF_OUTPUT_MAX; name++) { + /* try for a match based on the nmemonic/enum */ + if (!strcasecmp(candidate,netperf_output_enum_to_str(name))) + return name; + + /* try for a match on the actual header text */ + temp = malloc(NETPERF_LINE_TOT(name)); + h1 = temp; + if (h1 != NULL) { + for (k = 0; ((k < 4) && + (NULL != netperf_output_source[name].line[k]) && + (strcmp("",netperf_output_source[name].line[k]))); k++) { + len = sprintf(h1, + "%s", + netperf_output_source[name].line[k]); + *(h1 + len) = ' '; + /* now move to the next starting column. for csv we aren't worried + about alignment between the header and the value lines */ + h1 += len + 1; + } + /* this time we want null termination please */ + *(h1 - 1) = 0; + if (!strcasecmp(candidate,temp)) { + free(temp); + return name; + } + else + free(temp); + } + } + /* if we get here it means there was no match */ + return OUTPUT_NONE; +} + +void +parse_output_csv_selection_file(char *selection_file) { + FILE *selections; + char name[81]; /* best be more than enough */ + int namepos; + int c; + int j; + enum netperf_output_name match; + int line,column; + + selections = fopen(selection_file,"r"); + if (!selections) { + perror("Could Not Open output selection file"); + exit(-1); + } + + /* should this really be necessary? */ + rewind(selections); + + line = 0; + column = 1; + namepos = 0; + name[0] = 0; + name[80] = 0; + j = 0; + /* let's allow the csv to turn the four lines of a human readable + output file to be used to create a single line csv output file by + not worrying about the line count. raj 2008--02-04 */ + while ((c = fgetc(selections)) != EOF) { + if (namepos == 80) { + /* too long */ + + fprintf(where, + "Output selection starting column %d on line %d is too long\n", + line + 1, + column); + fflush(where); + exit(-1); + } + if (c == ',') { + /* time to check for a match, but only if we won't overflow the + current row of the array */ + if (j == NETPERF_OUTPUT_MAX) { + fprintf(where,"Too many output selectors on line %d\n",line); + fflush(where); + exit(-1); + } + name[namepos] = 0; + output_csv_list[j++] = match_string_to_output(name); + namepos = 0; + } + else if (c == '\n') { + /* move to the next line after checking for a match */ + name[namepos] = 0; + output_csv_list[j++] = match_string_to_output(name); + line++; + namepos = 0; + } + else if (isprint(c)) { + name[namepos++] = c; + } + column++; + } + + /* ok, do we need/want to do anything here? at present we will + silently ignore the rest of the file if we exit the loop on line + count */ + if ((c == EOF) && (namepos > 0)) { + name[namepos] = 0; + output_csv_list[j] = match_string_to_output(name); + } +} +void +parse_output_human_selection_file(char *selection_file) { + FILE *selections; + char name[81]; /* best be more than enough */ + int namepos; + char c; + int j; + enum netperf_output_name match; + int line,column; + + selections = fopen(selection_file,"r"); + if (!selections) { + perror("Could Not Open output selection file"); + exit(-1); + } + + line = 0; + column = 1; + namepos = 0; + name[0] = 0; + name[80] = 0; + j = 0; + while (((c = fgetc(selections)) != EOF) && (line < 4)) { + if (namepos == 80) { + /* too long */ + + fprintf(where, + "Output selection starting column %d on line %d is too long\n", + line + 1, + column); + fflush(where); + exit(-1); + } + if (c == ',') { + /* time to check for a match, but only if we won't overflow the + current row of the array */ + if (j == NETPERF_OUTPUT_MAX) { + fprintf(where,"Too many output selectors on line %d\n",line); + fflush(where); + exit(-1); + } + name[namepos] = 0; + output_human_list[line][j++] = match_string_to_output(name); + namepos = 0; + } + else if (c == '\n') { + /* move to the next line after checking for a match */ + name[namepos] = 0; + output_human_list[line++][j++] = match_string_to_output(name); + namepos = 0; + j = 0; + } + else if (isprint(c)) { + name[namepos++] = c; + } + column++; + } + + /* ok, do we need/want to do anything here? at present we will + silently ignore the rest of the file if we exit the loop on line + count */ + if ((c == EOF) && (namepos > 0)) { + name[namepos] = 0; + output_human_list[line][j] = match_string_to_output(name); + } + +} + +void +set_output_csv_list_default() { + + int i = 0; + enum netperf_output_name j; + + /* this should cause us to catch everything unless someone botches + adding an output name to the enum. raj 2008-02-22 */ + for (j = SOCKET_TYPE; j < OUTPUT_END; j++) { + output_csv_list[i++] = j; + } + +} + +void +set_output_human_list_default() { + + int i, j; /* line, column */ + enum netperf_output_name k; + + /* Line One SOCKET_TYPE to RESPONSE_SIZE */ + i = 0; + j = 0; + for (k = SOCKET_TYPE; k <= RESPONSE_SIZE; k++) + output_human_list[i][j++] = k; + + /* Line Two LOCAL_CPU_UTIL to TRANSPORT_MSS */ + i = 1; + j = 0; + for (k = LOCAL_CPU_UTIL; k <= TRANSPORT_MSS; k++) + output_human_list[i][j++] = k; + + /* Line Three LOCAL_SEND_THROUGHPUT throught REMOTE_CORK */ + i = 2; + j = 0; + for (k = LOCAL_SEND_THROUGHPUT; k <= REMOTE_CORK; k++) + output_human_list[i][j++] = k; + + /* Line Four LOCAL_SYSNAME through COMMAND_LINE */ + i = 3; + j = 0; + for (k = LOCAL_SYSNAME; k <= COMMAND_LINE; k++) + output_human_list[i][j++] = k; + +} + +void +print_omni_init_list() { + + int i; + + /* belts and suspenders everyone... */ + for (i = OUTPUT_NONE; i < NETPERF_OUTPUT_MAX; i++) { + netperf_output_source[i].output_name = i; + netperf_output_source[i].max_line_len = 0; + netperf_output_source[i].tot_line_len = 0; + netperf_output_source[i].line[0] = ""; + netperf_output_source[i].line[1] = ""; + netperf_output_source[i].line[2] = ""; + netperf_output_source[i].line[3] = ""; + netperf_output_source[i].brief = ""; + netperf_output_source[i].format = ""; + netperf_output_source[i].display_value = NULL; + } + + netperf_output_source[OUTPUT_NONE].output_name = OUTPUT_NONE; + netperf_output_source[OUTPUT_NONE].line[0] = " "; + netperf_output_source[OUTPUT_NONE].format = "%s"; + netperf_output_source[OUTPUT_NONE].display_value = &" "; + netperf_output_source[OUTPUT_NONE].max_line_len = + NETPERF_LINE_MAX(OUTPUT_NONE); + netperf_output_source[OUTPUT_NONE].tot_line_len = + NETPERF_LINE_TOT(OUTPUT_NONE); + + netperf_output_source[COMMAND_LINE].output_name = COMMAND_LINE; + netperf_output_source[COMMAND_LINE].line[0] = "Command"; + netperf_output_source[COMMAND_LINE].line[1] = "Line"; + netperf_output_source[COMMAND_LINE].format = "\"%s\""; + netperf_output_source[COMMAND_LINE].display_value = command_line; + netperf_output_source[COMMAND_LINE].max_line_len = + NETPERF_LINE_MAX(COMMAND_LINE); + netperf_output_source[COMMAND_LINE].tot_line_len = + NETPERF_LINE_TOT(COMMAND_LINE); + + netperf_output_source[UUID].output_name = UUID; + netperf_output_source[UUID].line[0] = "Test"; + netperf_output_source[UUID].line[1] = "UUID"; + netperf_output_source[UUID].format = "%s"; + netperf_output_source[UUID].display_value = test_uuid; + netperf_output_source[UUID].max_line_len = + NETPERF_LINE_MAX(UUID); + netperf_output_source[UUID].tot_line_len = + NETPERF_LINE_TOT(UUID); + + netperf_output_source[RESULT_BRAND].output_name = RESULT_BRAND; + netperf_output_source[RESULT_BRAND].line[0] = "Result"; + netperf_output_source[RESULT_BRAND].line[1] = "Tag"; + netperf_output_source[RESULT_BRAND].format = "\"%s\""; + netperf_output_source[RESULT_BRAND].display_value = result_brand; + netperf_output_source[RESULT_BRAND].max_line_len = + NETPERF_LINE_MAX(RESULT_BRAND); + netperf_output_source[RESULT_BRAND].tot_line_len = + NETPERF_LINE_TOT(RESULT_BRAND); + + netperf_output_source[SOCKET_TYPE].output_name = SOCKET_TYPE; + netperf_output_source[SOCKET_TYPE].line[0] = "Socket"; + netperf_output_source[SOCKET_TYPE].line[1] = "Type"; + netperf_output_source[SOCKET_TYPE].format = "%s"; + netperf_output_source[SOCKET_TYPE].display_value = socket_type_str; + netperf_output_source[SOCKET_TYPE].max_line_len = + NETPERF_LINE_MAX(SOCKET_TYPE); + netperf_output_source[SOCKET_TYPE].tot_line_len = + NETPERF_LINE_TOT(SOCKET_TYPE); + + netperf_output_source[DIRECTION].output_name = DIRECTION; + netperf_output_source[DIRECTION].line[0] = "Direction"; + netperf_output_source[DIRECTION].line[1] = ""; + netperf_output_source[DIRECTION].format = "%s"; + netperf_output_source[DIRECTION].display_value = direction_str; + netperf_output_source[DIRECTION].max_line_len = + NETPERF_LINE_MAX(DIRECTION); + netperf_output_source[DIRECTION].tot_line_len = + NETPERF_LINE_TOT(DIRECTION); + + netperf_output_source[PROTOCOL].output_name = PROTOCOL; + netperf_output_source[PROTOCOL].line[0] = "Protocol"; + netperf_output_source[PROTOCOL].format = "%s"; + netperf_output_source[PROTOCOL].display_value = protocol_str; + netperf_output_source[PROTOCOL].max_line_len = + NETPERF_LINE_MAX(PROTOCOL); + netperf_output_source[PROTOCOL].tot_line_len = + NETPERF_LINE_TOT(PROTOCOL); + + netperf_output_source[ELAPSED_TIME].output_name = ELAPSED_TIME; + netperf_output_source[ELAPSED_TIME].line[0] = "Elapsed"; + netperf_output_source[ELAPSED_TIME].line[1] = "Time"; + netperf_output_source[ELAPSED_TIME].line[2] = "(sec)"; + netperf_output_source[ELAPSED_TIME].format = "%.2f"; + netperf_output_source[ELAPSED_TIME].display_value = &elapsed_time_double; + netperf_output_source[ELAPSED_TIME].max_line_len = + NETPERF_LINE_MAX(ELAPSED_TIME); + netperf_output_source[ELAPSED_TIME].tot_line_len = + NETPERF_LINE_TOT(ELAPSED_TIME); + + netperf_output_source[SOURCE_PORT].output_name = SOURCE_PORT; + netperf_output_source[SOURCE_PORT].line[0] = "Source"; + netperf_output_source[SOURCE_PORT].line[1] = "Port"; + netperf_output_source[SOURCE_PORT].format = "%s"; + netperf_output_source[SOURCE_PORT].display_value = local_data_port; + netperf_output_source[SOURCE_PORT].max_line_len = + NETPERF_LINE_MAX(SOURCE_PORT); + netperf_output_source[SOURCE_PORT].tot_line_len = + NETPERF_LINE_TOT(SOURCE_PORT); + + netperf_output_source[SOURCE_ADDR].output_name = SOURCE_ADDR; + netperf_output_source[SOURCE_ADDR].line[0] = "Source"; + netperf_output_source[SOURCE_ADDR].line[1] = "Address"; + netperf_output_source[SOURCE_ADDR].format = "%s"; + netperf_output_source[SOURCE_ADDR].display_value = local_data_address; + netperf_output_source[SOURCE_ADDR].max_line_len = + NETPERF_LINE_MAX(SOURCE_ADDR); + netperf_output_source[SOURCE_ADDR].tot_line_len = + NETPERF_LINE_TOT(SOURCE_ADDR); + + netperf_output_source[SOURCE_FAMILY].output_name = SOURCE_FAMILY; + netperf_output_source[SOURCE_FAMILY].line[0] = "Source"; + netperf_output_source[SOURCE_FAMILY].line[1] = "Family"; + netperf_output_source[SOURCE_FAMILY].format = "%d"; + netperf_output_source[SOURCE_FAMILY].display_value = &local_data_family; + netperf_output_source[SOURCE_FAMILY].max_line_len = + NETPERF_LINE_MAX(SOURCE_FAMILY); + netperf_output_source[SOURCE_FAMILY].tot_line_len = + NETPERF_LINE_TOT(SOURCE_FAMILY); + + netperf_output_source[DEST_PORT].output_name = DEST_PORT; + netperf_output_source[DEST_PORT].line[0] = "Destination"; + netperf_output_source[DEST_PORT].line[1] = "Port"; + netperf_output_source[DEST_PORT].format = "%s"; + netperf_output_source[DEST_PORT].display_value = remote_data_port; + netperf_output_source[DEST_PORT].max_line_len = + NETPERF_LINE_MAX(DEST_PORT); + netperf_output_source[DEST_PORT].tot_line_len = + NETPERF_LINE_TOT(DEST_PORT); + + netperf_output_source[DEST_ADDR].output_name = DEST_ADDR; + netperf_output_source[DEST_ADDR].line[0] = "Destination"; + netperf_output_source[DEST_ADDR].line[1] = "Address"; + netperf_output_source[DEST_ADDR].format = "%s"; + netperf_output_source[DEST_ADDR].display_value = remote_data_address; + netperf_output_source[DEST_ADDR].max_line_len = + NETPERF_LINE_MAX(DEST_ADDR); + netperf_output_source[DEST_ADDR].tot_line_len = + NETPERF_LINE_TOT(DEST_ADDR); + + netperf_output_source[DEST_FAMILY].output_name = DEST_FAMILY; + netperf_output_source[DEST_FAMILY].line[0] = "Destination"; + netperf_output_source[DEST_FAMILY].line[1] = "Family"; + netperf_output_source[DEST_FAMILY].format = "%d"; + netperf_output_source[DEST_FAMILY].display_value = &remote_data_family; + netperf_output_source[DEST_FAMILY].max_line_len = + NETPERF_LINE_MAX(DEST_FAMILY); + netperf_output_source[DEST_FAMILY].tot_line_len = + NETPERF_LINE_TOT(DEST_FAMILY); + + netperf_output_source[THROUGHPUT].output_name = THROUGHPUT; + netperf_output_source[THROUGHPUT].line[0] = "Throughput"; + netperf_output_source[THROUGHPUT].line[1] = ""; + netperf_output_source[THROUGHPUT].format = "%.2f"; + netperf_output_source[THROUGHPUT].display_value = &thruput; + netperf_output_source[THROUGHPUT].max_line_len = + NETPERF_LINE_MAX(THROUGHPUT); + netperf_output_source[THROUGHPUT].tot_line_len = + NETPERF_LINE_TOT(THROUGHPUT); + + netperf_output_source[LOCAL_SEND_THROUGHPUT].output_name = LOCAL_SEND_THROUGHPUT; + netperf_output_source[LOCAL_SEND_THROUGHPUT].line[0] = "Local"; + netperf_output_source[LOCAL_SEND_THROUGHPUT].line[1] = "Send"; + netperf_output_source[LOCAL_SEND_THROUGHPUT].line[2] = "Throughput"; + netperf_output_source[LOCAL_SEND_THROUGHPUT].format = "%.2f"; + netperf_output_source[LOCAL_SEND_THROUGHPUT].display_value = &local_send_thruput; + netperf_output_source[LOCAL_SEND_THROUGHPUT].max_line_len = + NETPERF_LINE_MAX(LOCAL_SEND_THROUGHPUT); + netperf_output_source[LOCAL_SEND_THROUGHPUT].tot_line_len = + NETPERF_LINE_TOT(LOCAL_SEND_THROUGHPUT); + + netperf_output_source[LOCAL_RECV_THROUGHPUT].output_name = LOCAL_RECV_THROUGHPUT; + netperf_output_source[LOCAL_RECV_THROUGHPUT].line[0] = "Local"; + netperf_output_source[LOCAL_RECV_THROUGHPUT].line[1] = "Recv"; + netperf_output_source[LOCAL_RECV_THROUGHPUT].line[2] = "Throughput"; + netperf_output_source[LOCAL_RECV_THROUGHPUT].format = "%.2f"; + netperf_output_source[LOCAL_RECV_THROUGHPUT].display_value = &local_recv_thruput; + netperf_output_source[LOCAL_RECV_THROUGHPUT].max_line_len = + NETPERF_LINE_MAX(LOCAL_RECV_THROUGHPUT); + netperf_output_source[LOCAL_RECV_THROUGHPUT].tot_line_len = + NETPERF_LINE_TOT(LOCAL_RECV_THROUGHPUT); + + netperf_output_source[REMOTE_SEND_THROUGHPUT].output_name = REMOTE_SEND_THROUGHPUT; + netperf_output_source[REMOTE_SEND_THROUGHPUT].line[0] = "Remote"; + netperf_output_source[REMOTE_SEND_THROUGHPUT].line[1] = "Send"; + netperf_output_source[REMOTE_SEND_THROUGHPUT].line[2] = "Throughput"; + netperf_output_source[REMOTE_SEND_THROUGHPUT].format = "%.2f"; + netperf_output_source[REMOTE_SEND_THROUGHPUT].display_value = &remote_send_thruput; + netperf_output_source[REMOTE_SEND_THROUGHPUT].max_line_len = + NETPERF_LINE_MAX(REMOTE_SEND_THROUGHPUT); + netperf_output_source[REMOTE_SEND_THROUGHPUT].tot_line_len = + NETPERF_LINE_TOT(REMOTE_SEND_THROUGHPUT); + + netperf_output_source[REMOTE_RECV_THROUGHPUT].output_name = REMOTE_RECV_THROUGHPUT; + netperf_output_source[REMOTE_RECV_THROUGHPUT].line[0] = "Remote"; + netperf_output_source[REMOTE_RECV_THROUGHPUT].line[1] = "Recv"; + netperf_output_source[REMOTE_RECV_THROUGHPUT].line[2] = "Throughput"; + netperf_output_source[REMOTE_RECV_THROUGHPUT].format = "%.2f"; + netperf_output_source[REMOTE_RECV_THROUGHPUT].display_value = &remote_recv_thruput; + netperf_output_source[REMOTE_RECV_THROUGHPUT].max_line_len = + NETPERF_LINE_MAX(REMOTE_RECV_THROUGHPUT); + netperf_output_source[REMOTE_RECV_THROUGHPUT].tot_line_len = + NETPERF_LINE_TOT(REMOTE_RECV_THROUGHPUT); + + netperf_output_source[THROUGHPUT_UNITS].output_name = THROUGHPUT_UNITS; + netperf_output_source[THROUGHPUT_UNITS].line[0] = "Throughput"; + netperf_output_source[THROUGHPUT_UNITS].line[1] = "Units"; + netperf_output_source[THROUGHPUT_UNITS].format = "%s/s"; + netperf_output_source[THROUGHPUT_UNITS].display_value = thruput_format_str; + netperf_output_source[THROUGHPUT_UNITS].max_line_len = + NETPERF_LINE_MAX(THROUGHPUT_UNITS); + netperf_output_source[THROUGHPUT_UNITS].tot_line_len = + NETPERF_LINE_TOT(THROUGHPUT_UNITS); + + netperf_output_source[CONFIDENCE_LEVEL].output_name = CONFIDENCE_LEVEL; + netperf_output_source[CONFIDENCE_LEVEL].line[0] = "Confidence"; + netperf_output_source[CONFIDENCE_LEVEL].line[1] = "Level"; + netperf_output_source[CONFIDENCE_LEVEL].line[2] = "Percent"; + netperf_output_source[CONFIDENCE_LEVEL].format = "%d"; + netperf_output_source[CONFIDENCE_LEVEL].display_value = &confidence_level; + netperf_output_source[CONFIDENCE_LEVEL].max_line_len = + NETPERF_LINE_MAX(CONFIDENCE_LEVEL); + netperf_output_source[CONFIDENCE_LEVEL].tot_line_len = + NETPERF_LINE_TOT(CONFIDENCE_LEVEL); + + netperf_output_source[CONFIDENCE_INTERVAL].output_name = CONFIDENCE_INTERVAL; + netperf_output_source[CONFIDENCE_INTERVAL].line[0] = "Confidence"; + netperf_output_source[CONFIDENCE_INTERVAL].line[1] = "Width"; + netperf_output_source[CONFIDENCE_INTERVAL].line[2] = "Target"; + netperf_output_source[CONFIDENCE_INTERVAL].format = "%f"; + netperf_output_source[CONFIDENCE_INTERVAL].display_value = &interval_pct; + netperf_output_source[CONFIDENCE_INTERVAL].max_line_len = + NETPERF_LINE_MAX(CONFIDENCE_INTERVAL); + netperf_output_source[CONFIDENCE_INTERVAL].tot_line_len = + NETPERF_LINE_TOT(CONFIDENCE_INTERVAL); + + netperf_output_source[CONFIDENCE_ITERATION].output_name = CONFIDENCE_ITERATION; + netperf_output_source[CONFIDENCE_ITERATION].line[0] = "Confidence"; + netperf_output_source[CONFIDENCE_ITERATION].line[1] = "Iterations"; + netperf_output_source[CONFIDENCE_ITERATION].line[2] = "Run"; + netperf_output_source[CONFIDENCE_ITERATION].format = "%d"; + netperf_output_source[CONFIDENCE_ITERATION].display_value = &confidence_iteration; + netperf_output_source[CONFIDENCE_ITERATION].max_line_len = + NETPERF_LINE_MAX(CONFIDENCE_ITERATION); + netperf_output_source[CONFIDENCE_ITERATION].tot_line_len = + NETPERF_LINE_TOT(CONFIDENCE_ITERATION); + + netperf_output_source[THROUGHPUT_CONFID].output_name = THROUGHPUT_CONFID; + netperf_output_source[THROUGHPUT_CONFID].line[0] = "Throughput"; + netperf_output_source[THROUGHPUT_CONFID].line[1] = "Confidence"; + netperf_output_source[THROUGHPUT_CONFID].line[2] = "Width (%)"; + netperf_output_source[THROUGHPUT_CONFID].format = "%.3f"; + netperf_output_source[THROUGHPUT_CONFID].display_value = &result_confid_pct; + netperf_output_source[THROUGHPUT_CONFID].max_line_len = + NETPERF_LINE_MAX(THROUGHPUT_CONFID); + netperf_output_source[THROUGHPUT_CONFID].tot_line_len = + NETPERF_LINE_TOT(THROUGHPUT_CONFID); + + netperf_output_source[LOCAL_CPU_CONFID].output_name = LOCAL_CPU_CONFID; + netperf_output_source[LOCAL_CPU_CONFID].line[0] = "Local"; + netperf_output_source[LOCAL_CPU_CONFID].line[1] = "CPU"; + netperf_output_source[LOCAL_CPU_CONFID].line[2] = "Confidence"; + netperf_output_source[LOCAL_CPU_CONFID].line[3] = "Width (%)"; + netperf_output_source[LOCAL_CPU_CONFID].format = "%.3f"; + netperf_output_source[LOCAL_CPU_CONFID].display_value = &loc_cpu_confid_pct; + netperf_output_source[LOCAL_CPU_CONFID].max_line_len = + NETPERF_LINE_MAX(LOCAL_CPU_CONFID); + netperf_output_source[LOCAL_CPU_CONFID].tot_line_len = + NETPERF_LINE_TOT(LOCAL_CPU_CONFID); + + netperf_output_source[REMOTE_CPU_CONFID].output_name = REMOTE_CPU_CONFID; + netperf_output_source[REMOTE_CPU_CONFID].line[0] = "Remote"; + netperf_output_source[REMOTE_CPU_CONFID].line[1] = "CPU"; + netperf_output_source[REMOTE_CPU_CONFID].line[2] = "Confidence"; + netperf_output_source[REMOTE_CPU_CONFID].line[3] = "Width (%)"; + netperf_output_source[REMOTE_CPU_CONFID].format = "%.3f"; + netperf_output_source[REMOTE_CPU_CONFID].display_value = &rem_cpu_confid_pct; + netperf_output_source[REMOTE_CPU_CONFID].max_line_len = + NETPERF_LINE_MAX(REMOTE_CPU_CONFID); + netperf_output_source[REMOTE_CPU_CONFID].tot_line_len = + NETPERF_LINE_TOT(REMOTE_CPU_CONFID); + + netperf_output_source[RT_LATENCY].output_name = RT_LATENCY; + netperf_output_source[RT_LATENCY].line[0] = "Round"; + netperf_output_source[RT_LATENCY].line[1] = "Trip"; + netperf_output_source[RT_LATENCY].line[2] = "Latency"; + netperf_output_source[RT_LATENCY].line[3] = "usec/tran"; + netperf_output_source[RT_LATENCY].format = "%.3f"; + netperf_output_source[RT_LATENCY].display_value = &rtt_latency; + netperf_output_source[RT_LATENCY].max_line_len = + NETPERF_LINE_MAX(RT_LATENCY); + netperf_output_source[RT_LATENCY].tot_line_len = + NETPERF_LINE_TOT(RT_LATENCY); + + netperf_output_source[TRANSACTION_RATE].output_name = TRANSACTION_RATE; + netperf_output_source[TRANSACTION_RATE].line[0] = "Transaction"; + netperf_output_source[TRANSACTION_RATE].line[1] = "Rate"; + netperf_output_source[TRANSACTION_RATE].line[2] = "Tran/s"; + netperf_output_source[TRANSACTION_RATE].format = "%.3f"; + netperf_output_source[TRANSACTION_RATE].display_value = &transaction_rate; + netperf_output_source[TRANSACTION_RATE].max_line_len = + NETPERF_LINE_MAX(TRANSACTION_RATE); + netperf_output_source[TRANSACTION_RATE].tot_line_len = + NETPERF_LINE_TOT(TRANSACTION_RATE); + + netperf_output_source[TRANSPORT_MSS].output_name = TRANSPORT_MSS; + netperf_output_source[TRANSPORT_MSS].line[0] = "Transport"; + netperf_output_source[TRANSPORT_MSS].line[1] = "MSS"; + netperf_output_source[TRANSPORT_MSS].line[2] = "bytes"; + netperf_output_source[TRANSPORT_MSS].format = "%d"; + netperf_output_source[TRANSPORT_MSS].display_value = &transport_mss; + netperf_output_source[TRANSPORT_MSS].max_line_len = + NETPERF_LINE_MAX(TRANSPORT_MSS); + netperf_output_source[TRANSPORT_MSS].tot_line_len = + NETPERF_LINE_TOT(TRANSPORT_MSS); + + netperf_output_source[REQUEST_SIZE].output_name = REQUEST_SIZE; + netperf_output_source[REQUEST_SIZE].line[0] = "Request"; + netperf_output_source[REQUEST_SIZE].line[1] = "Size"; + netperf_output_source[REQUEST_SIZE].line[2] = "Bytes"; + netperf_output_source[REQUEST_SIZE].format = "%d"; + netperf_output_source[REQUEST_SIZE].display_value = &req_size; + netperf_output_source[REQUEST_SIZE].max_line_len = + NETPERF_LINE_MAX(REQUEST_SIZE); + netperf_output_source[REQUEST_SIZE].tot_line_len = + NETPERF_LINE_TOT(REQUEST_SIZE); + + netperf_output_source[RESPONSE_SIZE].output_name = RESPONSE_SIZE; + netperf_output_source[RESPONSE_SIZE].line[0] = "Response"; + netperf_output_source[RESPONSE_SIZE].line[1] = "Size"; + netperf_output_source[RESPONSE_SIZE].line[2] = "Bytes"; + netperf_output_source[RESPONSE_SIZE].format = "%d"; + netperf_output_source[RESPONSE_SIZE].display_value = &rsp_size; + netperf_output_source[RESPONSE_SIZE].max_line_len = + NETPERF_LINE_MAX(RESPONSE_SIZE); + netperf_output_source[RESPONSE_SIZE].tot_line_len = + NETPERF_LINE_TOT(RESPONSE_SIZE); + + netperf_output_source[BURST_SIZE].output_name = BURST_SIZE; + netperf_output_source[BURST_SIZE].line[0] = "Initial"; + netperf_output_source[BURST_SIZE].line[1] = "Burst"; + netperf_output_source[BURST_SIZE].line[2] = "Requests"; + netperf_output_source[BURST_SIZE].format = "%d"; + netperf_output_source[BURST_SIZE].display_value = &first_burst_size; + netperf_output_source[BURST_SIZE].max_line_len = + NETPERF_LINE_MAX(BURST_SIZE); + netperf_output_source[BURST_SIZE].tot_line_len = + NETPERF_LINE_TOT(BURST_SIZE); + + netperf_output_source[LSS_SIZE_REQ].output_name = LSS_SIZE_REQ; + netperf_output_source[LSS_SIZE_REQ].line[0] = "Local"; + netperf_output_source[LSS_SIZE_REQ].line[1] = "Send Socket"; + netperf_output_source[LSS_SIZE_REQ].line[2] = "Size"; + netperf_output_source[LSS_SIZE_REQ].line[3] = "Requested"; + netperf_output_source[LSS_SIZE_REQ].format = "%d"; + netperf_output_source[LSS_SIZE_REQ].display_value = &lss_size_req; + netperf_output_source[LSS_SIZE_REQ].max_line_len = + NETPERF_LINE_MAX(LSS_SIZE_REQ); + netperf_output_source[LSS_SIZE_REQ].tot_line_len = + NETPERF_LINE_TOT(LSS_SIZE_REQ); + + netperf_output_source[LSS_SIZE].output_name = LSS_SIZE; + netperf_output_source[LSS_SIZE].line[0] = "Local"; + netperf_output_source[LSS_SIZE].line[1] = "Send Socket"; + netperf_output_source[LSS_SIZE].line[2] = "Size"; + netperf_output_source[LSS_SIZE].line[3] = "Initial"; + netperf_output_source[LSS_SIZE].format = "%d"; + netperf_output_source[LSS_SIZE].display_value = &lss_size; + netperf_output_source[LSS_SIZE].max_line_len = + NETPERF_LINE_MAX(LSS_SIZE); + netperf_output_source[LSS_SIZE].tot_line_len = + NETPERF_LINE_TOT(LSS_SIZE); + + netperf_output_source[LSS_SIZE_END].output_name = LSS_SIZE_END; + netperf_output_source[LSS_SIZE_END].line[0] = "Local"; + netperf_output_source[LSS_SIZE_END].line[1] = "Send Socket"; + netperf_output_source[LSS_SIZE_END].line[2] = "Size"; + netperf_output_source[LSS_SIZE_END].line[3] = "Final"; + netperf_output_source[LSS_SIZE_END].format = "%d"; + netperf_output_source[LSS_SIZE_END].display_value = &lss_size_end; + netperf_output_source[LSS_SIZE_END].max_line_len = + NETPERF_LINE_MAX(LSS_SIZE_END); + netperf_output_source[LSS_SIZE_END].tot_line_len = + NETPERF_LINE_TOT(LSS_SIZE_END); + + netperf_output_source[LSR_SIZE_REQ].output_name = LSR_SIZE_REQ; + netperf_output_source[LSR_SIZE_REQ].line[0] = "Local"; + netperf_output_source[LSR_SIZE_REQ].line[1] = "Recv Socket"; + netperf_output_source[LSR_SIZE_REQ].line[2] = "Size"; + netperf_output_source[LSR_SIZE_REQ].line[3] = "Requested"; + netperf_output_source[LSR_SIZE_REQ].format = "%d"; + netperf_output_source[LSR_SIZE_REQ].display_value = &lsr_size_req; + netperf_output_source[LSR_SIZE_REQ].max_line_len = + NETPERF_LINE_MAX(LSR_SIZE_REQ); + netperf_output_source[LSR_SIZE_REQ].tot_line_len = + NETPERF_LINE_TOT(LSR_SIZE_REQ); + + netperf_output_source[LSR_SIZE].output_name = LSR_SIZE; + netperf_output_source[LSR_SIZE].line[0] = "Local"; + netperf_output_source[LSR_SIZE].line[1] = "Recv Socket"; + netperf_output_source[LSR_SIZE].line[2] = "Size"; + netperf_output_source[LSR_SIZE].line[3] = "Initial"; + netperf_output_source[LSR_SIZE].format = "%d"; + netperf_output_source[LSR_SIZE].display_value = &lsr_size; + netperf_output_source[LSR_SIZE].max_line_len = + NETPERF_LINE_MAX(LSR_SIZE); + netperf_output_source[LSR_SIZE].tot_line_len = + NETPERF_LINE_TOT(LSR_SIZE); + + netperf_output_source[LSR_SIZE_END].output_name = LSR_SIZE_END; + netperf_output_source[LSR_SIZE_END].line[0] = "Local"; + netperf_output_source[LSR_SIZE_END].line[1] = "Recv Socket"; + netperf_output_source[LSR_SIZE_END].line[2] = "Size"; + netperf_output_source[LSR_SIZE_END].line[3] = "Final"; + netperf_output_source[LSR_SIZE_END].format = "%d"; + netperf_output_source[LSR_SIZE_END].display_value = &lsr_size_end; + netperf_output_source[LSR_SIZE_END].max_line_len = + NETPERF_LINE_MAX(LSR_SIZE_END); + netperf_output_source[LSR_SIZE_END].tot_line_len = + NETPERF_LINE_TOT(LSR_SIZE_END); + + netperf_output_source[LOCAL_SEND_SIZE].output_name = LOCAL_SEND_SIZE; + netperf_output_source[LOCAL_SEND_SIZE].line[0] = "Local"; + netperf_output_source[LOCAL_SEND_SIZE].line[1] = "Send"; + netperf_output_source[LOCAL_SEND_SIZE].line[2] = "Size"; + netperf_output_source[LOCAL_SEND_SIZE].line[3] = ""; + netperf_output_source[LOCAL_SEND_SIZE].format = "%d"; + netperf_output_source[LOCAL_SEND_SIZE].display_value = &send_size; + netperf_output_source[LOCAL_SEND_SIZE].max_line_len = + NETPERF_LINE_MAX(LOCAL_SEND_SIZE); + netperf_output_source[LOCAL_SEND_SIZE].tot_line_len = + NETPERF_LINE_TOT(LOCAL_SEND_SIZE); + + netperf_output_source[LOCAL_RECV_SIZE].output_name = LOCAL_RECV_SIZE; + netperf_output_source[LOCAL_RECV_SIZE].line[0] = "Local"; + netperf_output_source[LOCAL_RECV_SIZE].line[1] = "Recv"; + netperf_output_source[LOCAL_RECV_SIZE].line[2] = "Size"; + netperf_output_source[LOCAL_RECV_SIZE].line[3] = ""; + netperf_output_source[LOCAL_RECV_SIZE].format = "%d"; + netperf_output_source[LOCAL_RECV_SIZE].display_value = &recv_size; + netperf_output_source[LOCAL_RECV_SIZE].max_line_len = + NETPERF_LINE_MAX(LOCAL_RECV_SIZE); + netperf_output_source[LOCAL_RECV_SIZE].tot_line_len = + NETPERF_LINE_TOT(LOCAL_RECV_SIZE); + + netperf_output_source[LOCAL_SEND_CALLS].output_name = LOCAL_SEND_CALLS; + netperf_output_source[LOCAL_SEND_CALLS].line[0] = "Local"; + netperf_output_source[LOCAL_SEND_CALLS].line[1] = "Send"; + netperf_output_source[LOCAL_SEND_CALLS].line[2] = "Calls"; + netperf_output_source[LOCAL_SEND_CALLS].line[3] = ""; + netperf_output_source[LOCAL_SEND_CALLS].format = "%d"; + netperf_output_source[LOCAL_SEND_CALLS].display_value = &local_send_calls; + netperf_output_source[LOCAL_SEND_CALLS].max_line_len = + NETPERF_LINE_MAX(LOCAL_SEND_CALLS); + netperf_output_source[LOCAL_SEND_CALLS].tot_line_len = + NETPERF_LINE_TOT(LOCAL_SEND_CALLS); + + netperf_output_source[LOCAL_RECV_CALLS].output_name = LOCAL_RECV_CALLS; + netperf_output_source[LOCAL_RECV_CALLS].line[0] = "Local"; + netperf_output_source[LOCAL_RECV_CALLS].line[1] = "Recv"; + netperf_output_source[LOCAL_RECV_CALLS].line[2] = "Calls"; + netperf_output_source[LOCAL_RECV_CALLS].line[3] = ""; + netperf_output_source[LOCAL_RECV_CALLS].format = "%d"; + netperf_output_source[LOCAL_RECV_CALLS].display_value = &local_receive_calls; + netperf_output_source[LOCAL_RECV_CALLS].max_line_len = + NETPERF_LINE_MAX(LOCAL_RECV_CALLS); + netperf_output_source[LOCAL_RECV_CALLS].tot_line_len = + NETPERF_LINE_TOT(LOCAL_RECV_CALLS); + + netperf_output_source[LOCAL_BYTES_PER_RECV].output_name = LOCAL_BYTES_PER_RECV; + netperf_output_source[LOCAL_BYTES_PER_RECV].line[0] = "Local"; + netperf_output_source[LOCAL_BYTES_PER_RECV].line[1] = "Bytes"; + netperf_output_source[LOCAL_BYTES_PER_RECV].line[2] = "Per"; + netperf_output_source[LOCAL_BYTES_PER_RECV].line[3] = "Recv"; + netperf_output_source[LOCAL_BYTES_PER_RECV].format = "%.2f"; + netperf_output_source[LOCAL_BYTES_PER_RECV].display_value = &bytes_per_recv; + netperf_output_source[LOCAL_BYTES_PER_RECV].max_line_len = + NETPERF_LINE_MAX(LOCAL_BYTES_PER_RECV); + netperf_output_source[LOCAL_BYTES_PER_RECV].tot_line_len = + NETPERF_LINE_TOT(LOCAL_BYTES_PER_RECV); + + netperf_output_source[LOCAL_BYTES_PER_SEND].output_name = LOCAL_BYTES_PER_SEND; + netperf_output_source[LOCAL_BYTES_PER_SEND].line[0] = "Local"; + netperf_output_source[LOCAL_BYTES_PER_SEND].line[1] = "Bytes"; + netperf_output_source[LOCAL_BYTES_PER_SEND].line[2] = "Per"; + netperf_output_source[LOCAL_BYTES_PER_SEND].line[3] = "Send"; + netperf_output_source[LOCAL_BYTES_PER_SEND].format = "%.2f"; + netperf_output_source[LOCAL_BYTES_PER_SEND].display_value = &bytes_per_send; + netperf_output_source[LOCAL_BYTES_PER_SEND].max_line_len = + NETPERF_LINE_MAX(LOCAL_BYTES_PER_SEND); + netperf_output_source[LOCAL_BYTES_PER_SEND].tot_line_len = + NETPERF_LINE_TOT(LOCAL_BYTES_PER_SEND); + + netperf_output_source[LOCAL_BYTES_RECVD].output_name = LOCAL_BYTES_RECVD; + netperf_output_source[LOCAL_BYTES_RECVD].line[0] = "Local"; + netperf_output_source[LOCAL_BYTES_RECVD].line[1] = "Bytes"; + netperf_output_source[LOCAL_BYTES_RECVD].line[2] = "Received"; + netperf_output_source[LOCAL_BYTES_RECVD].line[3] = ""; + netperf_output_source[LOCAL_BYTES_RECVD].format = "%lld"; + netperf_output_source[LOCAL_BYTES_RECVD].display_value = &bytes_received; + netperf_output_source[LOCAL_BYTES_RECVD].max_line_len = + NETPERF_LINE_MAX(LOCAL_BYTES_RECVD); + netperf_output_source[LOCAL_BYTES_RECVD].tot_line_len = + NETPERF_LINE_TOT(LOCAL_BYTES_RECVD); + + netperf_output_source[LOCAL_BYTES_SENT].output_name = LOCAL_BYTES_SENT; + netperf_output_source[LOCAL_BYTES_SENT].line[0] = "Local"; + netperf_output_source[LOCAL_BYTES_SENT].line[1] = "Bytes"; + netperf_output_source[LOCAL_BYTES_SENT].line[2] = "Sent"; + netperf_output_source[LOCAL_BYTES_SENT].line[3] = ""; + netperf_output_source[LOCAL_BYTES_SENT].format = "%lld"; + netperf_output_source[LOCAL_BYTES_SENT].display_value = &bytes_sent; + netperf_output_source[LOCAL_BYTES_SENT].max_line_len = + NETPERF_LINE_MAX(LOCAL_BYTES_SENT); + netperf_output_source[LOCAL_BYTES_SENT].tot_line_len = + NETPERF_LINE_TOT(LOCAL_BYTES_SENT); + + netperf_output_source[LOCAL_BYTES_XFERD].output_name = LOCAL_BYTES_XFERD; + netperf_output_source[LOCAL_BYTES_XFERD].line[0] = "Local"; + netperf_output_source[LOCAL_BYTES_XFERD].line[1] = "Bytes"; + netperf_output_source[LOCAL_BYTES_XFERD].line[2] = "Xferred"; + netperf_output_source[LOCAL_BYTES_XFERD].line[3] = ""; + netperf_output_source[LOCAL_BYTES_XFERD].format = "%.0f"; + netperf_output_source[LOCAL_BYTES_XFERD].display_value = &bytes_xferd; + netperf_output_source[LOCAL_BYTES_XFERD].max_line_len = + NETPERF_LINE_MAX(LOCAL_BYTES_XFERD); + netperf_output_source[LOCAL_BYTES_XFERD].tot_line_len = + NETPERF_LINE_TOT(LOCAL_BYTES_XFERD); + + netperf_output_source[LOCAL_SEND_WIDTH].output_name = LOCAL_SEND_WIDTH; + netperf_output_source[LOCAL_SEND_WIDTH].line[0] = "Local"; + netperf_output_source[LOCAL_SEND_WIDTH].line[1] = "Send"; + netperf_output_source[LOCAL_SEND_WIDTH].line[2] = "Width"; + netperf_output_source[LOCAL_SEND_WIDTH].format = "%d"; + netperf_output_source[LOCAL_SEND_WIDTH].display_value = &send_width; + netperf_output_source[LOCAL_SEND_WIDTH].max_line_len = + NETPERF_LINE_MAX(LOCAL_SEND_WIDTH); + netperf_output_source[LOCAL_SEND_WIDTH].tot_line_len = + NETPERF_LINE_TOT(LOCAL_SEND_WIDTH); + + netperf_output_source[LOCAL_RECV_WIDTH].output_name = LOCAL_RECV_WIDTH; + netperf_output_source[LOCAL_RECV_WIDTH].line[0] = "Local"; + netperf_output_source[LOCAL_RECV_WIDTH].line[1] = "Recv"; + netperf_output_source[LOCAL_RECV_WIDTH].line[2] = "Width"; + netperf_output_source[LOCAL_RECV_WIDTH].format = "%d"; + netperf_output_source[LOCAL_RECV_WIDTH].display_value = &recv_width; + netperf_output_source[LOCAL_RECV_WIDTH].max_line_len = + NETPERF_LINE_MAX(LOCAL_RECV_WIDTH); + netperf_output_source[LOCAL_RECV_WIDTH].tot_line_len = + NETPERF_LINE_TOT(LOCAL_RECV_WIDTH); + + netperf_output_source[LOCAL_SEND_OFFSET].output_name = LOCAL_SEND_OFFSET; + netperf_output_source[LOCAL_SEND_OFFSET].line[0] = "Local"; + netperf_output_source[LOCAL_SEND_OFFSET].line[1] = "Send"; + netperf_output_source[LOCAL_SEND_OFFSET].line[2] = "Offset"; + netperf_output_source[LOCAL_SEND_OFFSET].format = "%d"; + netperf_output_source[LOCAL_SEND_OFFSET].display_value = &local_send_offset; + netperf_output_source[LOCAL_SEND_OFFSET].max_line_len = + NETPERF_LINE_MAX(LOCAL_SEND_OFFSET); + netperf_output_source[LOCAL_SEND_OFFSET].tot_line_len = + NETPERF_LINE_TOT(LOCAL_SEND_OFFSET); + + netperf_output_source[LOCAL_RECV_OFFSET].output_name = LOCAL_RECV_OFFSET; + netperf_output_source[LOCAL_RECV_OFFSET].line[0] = "Local"; + netperf_output_source[LOCAL_RECV_OFFSET].line[1] = "Recv"; + netperf_output_source[LOCAL_RECV_OFFSET].line[2] = "Offset"; + netperf_output_source[LOCAL_RECV_OFFSET].format = "%d"; + netperf_output_source[LOCAL_RECV_OFFSET].display_value = &local_recv_offset; + netperf_output_source[LOCAL_RECV_OFFSET].max_line_len = + NETPERF_LINE_MAX(LOCAL_RECV_OFFSET); + netperf_output_source[LOCAL_RECV_OFFSET].tot_line_len = + NETPERF_LINE_TOT(LOCAL_RECV_OFFSET); + + netperf_output_source[LOCAL_RECV_ALIGN].output_name = LOCAL_RECV_ALIGN; + netperf_output_source[LOCAL_RECV_ALIGN].line[0] = "Local"; + netperf_output_source[LOCAL_RECV_ALIGN].line[1] = "Recv"; + netperf_output_source[LOCAL_RECV_ALIGN].line[2] = "Alignment"; + netperf_output_source[LOCAL_RECV_ALIGN].format = "%d"; + netperf_output_source[LOCAL_RECV_ALIGN].display_value = &local_recv_align; + netperf_output_source[LOCAL_RECV_ALIGN].max_line_len = + NETPERF_LINE_MAX(LOCAL_RECV_ALIGN); + netperf_output_source[LOCAL_RECV_ALIGN].tot_line_len = + NETPERF_LINE_TOT(LOCAL_RECV_ALIGN); + + netperf_output_source[LOCAL_SEND_ALIGN].output_name = LOCAL_SEND_ALIGN; + netperf_output_source[LOCAL_SEND_ALIGN].line[0] = "Local"; + netperf_output_source[LOCAL_SEND_ALIGN].line[1] = "Send"; + netperf_output_source[LOCAL_SEND_ALIGN].line[2] = "Alignment"; + netperf_output_source[LOCAL_SEND_ALIGN].format = "%d"; + netperf_output_source[LOCAL_SEND_ALIGN].display_value = &local_send_align; + netperf_output_source[LOCAL_SEND_ALIGN].max_line_len = + NETPERF_LINE_MAX(LOCAL_SEND_ALIGN); + netperf_output_source[LOCAL_SEND_ALIGN].tot_line_len = + NETPERF_LINE_TOT(LOCAL_SEND_ALIGN); + + netperf_output_source[LOCAL_SEND_DIRTY_COUNT].output_name = LOCAL_SEND_DIRTY_COUNT; + netperf_output_source[LOCAL_SEND_DIRTY_COUNT].line[0] = "Local"; + netperf_output_source[LOCAL_SEND_DIRTY_COUNT].line[1] = "Send"; + netperf_output_source[LOCAL_SEND_DIRTY_COUNT].line[2] = "Dirty"; + netperf_output_source[LOCAL_SEND_DIRTY_COUNT].line[3] = "Count"; + netperf_output_source[LOCAL_SEND_DIRTY_COUNT].format = "%d"; + netperf_output_source[LOCAL_SEND_DIRTY_COUNT].display_value = &loc_dirty_count; + netperf_output_source[LOCAL_SEND_DIRTY_COUNT].max_line_len = + NETPERF_LINE_MAX(LOCAL_SEND_DIRTY_COUNT); + netperf_output_source[LOCAL_SEND_DIRTY_COUNT].tot_line_len = + NETPERF_LINE_TOT(LOCAL_SEND_DIRTY_COUNT); + + netperf_output_source[LOCAL_RECV_DIRTY_COUNT].output_name = LOCAL_RECV_DIRTY_COUNT; + netperf_output_source[LOCAL_RECV_DIRTY_COUNT].line[0] = "Local"; + netperf_output_source[LOCAL_RECV_DIRTY_COUNT].line[1] = "Recv"; + netperf_output_source[LOCAL_RECV_DIRTY_COUNT].line[2] = "Dirty"; + netperf_output_source[LOCAL_RECV_DIRTY_COUNT].line[3] = "Count"; + netperf_output_source[LOCAL_RECV_DIRTY_COUNT].format = "%d"; + netperf_output_source[LOCAL_RECV_DIRTY_COUNT].display_value = &loc_dirty_count; + netperf_output_source[LOCAL_RECV_DIRTY_COUNT].max_line_len = + NETPERF_LINE_MAX(LOCAL_RECV_DIRTY_COUNT); + netperf_output_source[LOCAL_RECV_DIRTY_COUNT].tot_line_len = + NETPERF_LINE_TOT(LOCAL_RECV_DIRTY_COUNT); + + netperf_output_source[LOCAL_RECV_CLEAN_COUNT].output_name = LOCAL_RECV_CLEAN_COUNT; + netperf_output_source[LOCAL_RECV_CLEAN_COUNT].line[0] = "Local"; + netperf_output_source[LOCAL_RECV_CLEAN_COUNT].line[1] = "Recv"; + netperf_output_source[LOCAL_RECV_CLEAN_COUNT].line[2] = "Clean"; + netperf_output_source[LOCAL_RECV_CLEAN_COUNT].line[3] = "Count"; + netperf_output_source[LOCAL_RECV_CLEAN_COUNT].format = "%d"; + netperf_output_source[LOCAL_RECV_CLEAN_COUNT].display_value = &loc_clean_count; + netperf_output_source[LOCAL_RECV_CLEAN_COUNT].max_line_len = + NETPERF_LINE_MAX(LOCAL_RECV_CLEAN_COUNT); + netperf_output_source[LOCAL_RECV_CLEAN_COUNT].tot_line_len = + NETPERF_LINE_TOT(LOCAL_RECV_CLEAN_COUNT); + + netperf_output_source[LOCAL_CPU_UTIL].output_name = LOCAL_CPU_UTIL; + netperf_output_source[LOCAL_CPU_UTIL].line[0] = "Local"; + netperf_output_source[LOCAL_CPU_UTIL].line[1] = "CPU"; + netperf_output_source[LOCAL_CPU_UTIL].line[2] = "Util"; + netperf_output_source[LOCAL_CPU_UTIL].line[3] = "%"; + netperf_output_source[LOCAL_CPU_UTIL].format = "%.2f"; + netperf_output_source[LOCAL_CPU_UTIL].display_value = &local_cpu_utilization_double; + netperf_output_source[LOCAL_CPU_UTIL].max_line_len = + NETPERF_LINE_MAX(LOCAL_CPU_UTIL); + netperf_output_source[LOCAL_CPU_UTIL].tot_line_len = + NETPERF_LINE_TOT(LOCAL_CPU_UTIL); + + netperf_output_source[LOCAL_CPU_PEAK_UTIL].output_name = LOCAL_CPU_PEAK_UTIL; + netperf_output_source[LOCAL_CPU_PEAK_UTIL].line[0] = "Local"; + netperf_output_source[LOCAL_CPU_PEAK_UTIL].line[1] = "Peak"; + netperf_output_source[LOCAL_CPU_PEAK_UTIL].line[2] = "Per CPU"; + netperf_output_source[LOCAL_CPU_PEAK_UTIL].line[3] = "Util %"; + netperf_output_source[LOCAL_CPU_PEAK_UTIL].format = "%.2f"; + netperf_output_source[LOCAL_CPU_PEAK_UTIL].display_value = &lib_local_peak_cpu_util; + netperf_output_source[LOCAL_CPU_PEAK_UTIL].max_line_len = + NETPERF_LINE_MAX(LOCAL_CPU_PEAK_UTIL); + netperf_output_source[LOCAL_CPU_PEAK_UTIL].tot_line_len = + NETPERF_LINE_TOT(LOCAL_CPU_PEAK_UTIL); + + netperf_output_source[LOCAL_CPU_PEAK_ID].output_name = LOCAL_CPU_PEAK_ID; + netperf_output_source[LOCAL_CPU_PEAK_ID].line[0] = "Local"; + netperf_output_source[LOCAL_CPU_PEAK_ID].line[1] = "Peak"; + netperf_output_source[LOCAL_CPU_PEAK_ID].line[2] = "Per CPU"; + netperf_output_source[LOCAL_CPU_PEAK_ID].line[3] = "ID"; + netperf_output_source[LOCAL_CPU_PEAK_ID].format = "%d"; + netperf_output_source[LOCAL_CPU_PEAK_ID].display_value = &lib_local_peak_cpu_id; + netperf_output_source[LOCAL_CPU_PEAK_ID].max_line_len = + NETPERF_LINE_MAX(LOCAL_CPU_PEAK_ID); + netperf_output_source[LOCAL_CPU_PEAK_ID].tot_line_len = + NETPERF_LINE_TOT(LOCAL_CPU_PEAK_ID); + + netperf_output_source[LOCAL_CPU_BIND].output_name = LOCAL_CPU_BIND; + netperf_output_source[LOCAL_CPU_BIND].line[0] = "Local"; + netperf_output_source[LOCAL_CPU_BIND].line[1] = "CPU"; + netperf_output_source[LOCAL_CPU_BIND].line[2] = "Bind"; + netperf_output_source[LOCAL_CPU_BIND].line[3] = ""; + netperf_output_source[LOCAL_CPU_BIND].format = "%d"; + netperf_output_source[LOCAL_CPU_BIND].display_value = &local_proc_affinity; + netperf_output_source[LOCAL_CPU_BIND].max_line_len = + NETPERF_LINE_MAX(LOCAL_CPU_BIND); + netperf_output_source[LOCAL_CPU_BIND].tot_line_len = + NETPERF_LINE_TOT(LOCAL_CPU_BIND); + + netperf_output_source[LOCAL_SD].output_name = LOCAL_SD; + netperf_output_source[LOCAL_SD].line[0] = "Local"; + netperf_output_source[LOCAL_SD].line[1] = "Service"; + netperf_output_source[LOCAL_SD].line[2] = "Demand"; + netperf_output_source[LOCAL_SD].line[3] = ""; + netperf_output_source[LOCAL_SD].format = "%.3f"; + netperf_output_source[LOCAL_SD].display_value = &local_service_demand_double; + netperf_output_source[LOCAL_SD].max_line_len = + NETPERF_LINE_MAX(LOCAL_SD); + netperf_output_source[LOCAL_SD].tot_line_len = + NETPERF_LINE_TOT(LOCAL_SD); + + netperf_output_source[SD_UNITS].output_name = SD_UNITS; + netperf_output_source[SD_UNITS].line[0] = "Service"; + netperf_output_source[SD_UNITS].line[1] = "Demand"; + netperf_output_source[SD_UNITS].line[2] = "Units"; + netperf_output_source[SD_UNITS].format = "%s"; + netperf_output_source[SD_UNITS].display_value = sd_str; + netperf_output_source[SD_UNITS].max_line_len = + NETPERF_LINE_MAX(SD_UNITS); + netperf_output_source[SD_UNITS].tot_line_len = + NETPERF_LINE_TOT(SD_UNITS); + + netperf_output_source[LOCAL_CPU_METHOD].output_name = LOCAL_CPU_METHOD; + netperf_output_source[LOCAL_CPU_METHOD].line[0] = "Local"; + netperf_output_source[LOCAL_CPU_METHOD].line[1] = "CPU"; + netperf_output_source[LOCAL_CPU_METHOD].line[2] = "Util"; + netperf_output_source[LOCAL_CPU_METHOD].line[3] = "Method"; + netperf_output_source[LOCAL_CPU_METHOD].format = "%c"; + netperf_output_source[LOCAL_CPU_METHOD].display_value = &local_cpu_method; + netperf_output_source[LOCAL_CPU_METHOD].max_line_len = + NETPERF_LINE_MAX(LOCAL_CPU_METHOD); + netperf_output_source[LOCAL_CPU_METHOD].tot_line_len = + NETPERF_LINE_TOT(LOCAL_CPU_METHOD); + + netperf_output_source[LOCAL_CPU_COUNT].output_name = LOCAL_CPU_COUNT; + netperf_output_source[LOCAL_CPU_COUNT].line[0] = "Local"; + netperf_output_source[LOCAL_CPU_COUNT].line[1] = "CPU"; + netperf_output_source[LOCAL_CPU_COUNT].line[2] = "Count"; + netperf_output_source[LOCAL_CPU_COUNT].format = "%d"; + netperf_output_source[LOCAL_CPU_COUNT].display_value = &lib_num_loc_cpus; + netperf_output_source[LOCAL_CPU_COUNT].max_line_len = + NETPERF_LINE_MAX(LOCAL_CPU_COUNT); + netperf_output_source[LOCAL_CPU_COUNT].tot_line_len = + NETPERF_LINE_TOT(LOCAL_CPU_COUNT); + + netperf_output_source[LOCAL_NODELAY].output_name = LOCAL_NODELAY; + netperf_output_source[LOCAL_NODELAY].line[0] = "Local"; + netperf_output_source[LOCAL_NODELAY].line[1] = "NODELAY"; + netperf_output_source[LOCAL_NODELAY].line[2] = ""; + netperf_output_source[LOCAL_NODELAY].line[3] = ""; + netperf_output_source[LOCAL_NODELAY].format = "%d"; + netperf_output_source[LOCAL_NODELAY].display_value = &loc_nodelay; + netperf_output_source[LOCAL_NODELAY].max_line_len = + NETPERF_LINE_MAX(LOCAL_NODELAY); + netperf_output_source[LOCAL_NODELAY].tot_line_len = + NETPERF_LINE_TOT(LOCAL_NODELAY); + + netperf_output_source[LOCAL_CORK].output_name = LOCAL_CORK; + netperf_output_source[LOCAL_CORK].line[0] = "Local"; + netperf_output_source[LOCAL_CORK].line[1] = "Cork"; + netperf_output_source[LOCAL_CORK].line[2] = ""; + netperf_output_source[LOCAL_CORK].line[3] = ""; + netperf_output_source[LOCAL_CORK].format = "%d"; + netperf_output_source[LOCAL_CORK].display_value = &loc_tcpcork; + netperf_output_source[LOCAL_CORK].max_line_len = + NETPERF_LINE_MAX(LOCAL_CORK); + netperf_output_source[LOCAL_CORK].tot_line_len = + NETPERF_LINE_TOT(LOCAL_CORK); + + netperf_output_source[RSS_SIZE_REQ].output_name = RSS_SIZE_REQ; + netperf_output_source[RSS_SIZE_REQ].line[0] = "Remote"; + netperf_output_source[RSS_SIZE_REQ].line[1] = "Send Socket"; + netperf_output_source[RSS_SIZE_REQ].line[2] = "Size"; + netperf_output_source[RSS_SIZE_REQ].line[3] = "Requested"; + netperf_output_source[RSS_SIZE_REQ].format = "%d"; + netperf_output_source[RSS_SIZE_REQ].display_value = &rss_size_req; + netperf_output_source[RSS_SIZE_REQ].max_line_len = + NETPERF_LINE_MAX(RSS_SIZE_REQ); + netperf_output_source[RSS_SIZE_REQ].tot_line_len = + NETPERF_LINE_TOT(RSS_SIZE_REQ); + + netperf_output_source[RSS_SIZE].output_name = RSS_SIZE; + netperf_output_source[RSS_SIZE].line[0] = "Remote"; + netperf_output_source[RSS_SIZE].line[1] = "Send Socket"; + netperf_output_source[RSS_SIZE].line[2] = "Size"; + netperf_output_source[RSS_SIZE].line[3] = "Initial"; + netperf_output_source[RSS_SIZE].format = "%d"; + netperf_output_source[RSS_SIZE].display_value = &rss_size; + netperf_output_source[RSS_SIZE].max_line_len = + NETPERF_LINE_MAX(RSS_SIZE); + netperf_output_source[RSS_SIZE].tot_line_len = + NETPERF_LINE_TOT(RSS_SIZE); + + netperf_output_source[RSS_SIZE_END].output_name = RSS_SIZE_END; + netperf_output_source[RSS_SIZE_END].line[0] = "Remote"; + netperf_output_source[RSS_SIZE_END].line[1] = "Send Socket"; + netperf_output_source[RSS_SIZE_END].line[2] = "Size"; + netperf_output_source[RSS_SIZE_END].line[3] = "Final"; + netperf_output_source[RSS_SIZE_END].format = "%d"; + netperf_output_source[RSS_SIZE_END].display_value = &rss_size_end; + netperf_output_source[RSS_SIZE_END].max_line_len = + NETPERF_LINE_MAX(RSS_SIZE_END); + netperf_output_source[RSS_SIZE_END].tot_line_len = + NETPERF_LINE_TOT(RSS_SIZE_END); + + netperf_output_source[RSR_SIZE_REQ].output_name = RSR_SIZE_REQ; + netperf_output_source[RSR_SIZE_REQ].line[0] = "Remote"; + netperf_output_source[RSR_SIZE_REQ].line[1] = "Recv Socket"; + netperf_output_source[RSR_SIZE_REQ].line[2] = "Size"; + netperf_output_source[RSR_SIZE_REQ].line[3] = "Requested"; + netperf_output_source[RSR_SIZE_REQ].format = "%d"; + netperf_output_source[RSR_SIZE_REQ].display_value = &rsr_size_req; + netperf_output_source[RSR_SIZE_REQ].max_line_len = + NETPERF_LINE_MAX(RSR_SIZE_REQ); + netperf_output_source[RSR_SIZE_REQ].tot_line_len = + NETPERF_LINE_TOT(RSR_SIZE_REQ); + + netperf_output_source[RSR_SIZE].output_name = RSR_SIZE; + netperf_output_source[RSR_SIZE].line[0] = "Remote"; + netperf_output_source[RSR_SIZE].line[1] = "Recv Socket"; + netperf_output_source[RSR_SIZE].line[2] = "Size"; + netperf_output_source[RSR_SIZE].line[3] = "Initial"; + netperf_output_source[RSR_SIZE].format = "%d"; + netperf_output_source[RSR_SIZE].display_value = &rsr_size; + netperf_output_source[RSR_SIZE].max_line_len = + NETPERF_LINE_MAX(RSR_SIZE); + netperf_output_source[RSR_SIZE].tot_line_len = + NETPERF_LINE_TOT(RSR_SIZE); + + netperf_output_source[RSR_SIZE_END].output_name = RSR_SIZE_END; + netperf_output_source[RSR_SIZE_END].line[0] = "Remote"; + netperf_output_source[RSR_SIZE_END].line[1] = "Recv Socket"; + netperf_output_source[RSR_SIZE_END].line[2] = "Size"; + netperf_output_source[RSR_SIZE_END].line[3] = "Final"; + netperf_output_source[RSR_SIZE_END].format = "%d"; + netperf_output_source[RSR_SIZE_END].display_value = &rsr_size_end; + netperf_output_source[RSR_SIZE_END].max_line_len = + NETPERF_LINE_MAX(RSR_SIZE_END); + netperf_output_source[RSR_SIZE_END].tot_line_len = + NETPERF_LINE_TOT(RSR_SIZE_END); + + netperf_output_source[REMOTE_SEND_SIZE].output_name = REMOTE_SEND_SIZE; + netperf_output_source[REMOTE_SEND_SIZE].line[0] = "Remote"; + netperf_output_source[REMOTE_SEND_SIZE].line[1] = "Send"; + netperf_output_source[REMOTE_SEND_SIZE].line[2] = "Size"; + netperf_output_source[REMOTE_SEND_SIZE].line[3] = ""; + netperf_output_source[REMOTE_SEND_SIZE].format = "%d"; + netperf_output_source[REMOTE_SEND_SIZE].display_value = &remote_send_size; + netperf_output_source[REMOTE_SEND_SIZE].max_line_len = + NETPERF_LINE_MAX(REMOTE_SEND_SIZE); + netperf_output_source[REMOTE_SEND_SIZE].tot_line_len = + NETPERF_LINE_TOT(REMOTE_SEND_SIZE); + + netperf_output_source[REMOTE_RECV_SIZE].output_name = REMOTE_RECV_SIZE; + netperf_output_source[REMOTE_RECV_SIZE].line[0] = "Remote"; + netperf_output_source[REMOTE_RECV_SIZE].line[1] = "Recv"; + netperf_output_source[REMOTE_RECV_SIZE].line[2] = "Size"; + netperf_output_source[REMOTE_RECV_SIZE].line[3] = ""; + netperf_output_source[REMOTE_RECV_SIZE].format = "%d"; + netperf_output_source[REMOTE_RECV_SIZE].display_value = &remote_recv_size; + netperf_output_source[REMOTE_RECV_SIZE].max_line_len = + NETPERF_LINE_MAX(REMOTE_RECV_SIZE); + netperf_output_source[REMOTE_RECV_SIZE].tot_line_len = + NETPERF_LINE_TOT(REMOTE_RECV_SIZE); + + netperf_output_source[REMOTE_SEND_CALLS].output_name = REMOTE_SEND_CALLS; + netperf_output_source[REMOTE_SEND_CALLS].line[0] = "Remote"; + netperf_output_source[REMOTE_SEND_CALLS].line[1] = "Send"; + netperf_output_source[REMOTE_SEND_CALLS].line[2] = "Calls"; + netperf_output_source[REMOTE_SEND_CALLS].line[3] = ""; + netperf_output_source[REMOTE_SEND_CALLS].format = "%lld"; + netperf_output_source[REMOTE_SEND_CALLS].display_value = &remote_send_calls; + netperf_output_source[REMOTE_SEND_CALLS].max_line_len = + NETPERF_LINE_MAX(REMOTE_SEND_CALLS); + netperf_output_source[REMOTE_SEND_CALLS].tot_line_len = + NETPERF_LINE_TOT(REMOTE_SEND_CALLS); + + netperf_output_source[REMOTE_RECV_CALLS].output_name = REMOTE_RECV_CALLS; + netperf_output_source[REMOTE_RECV_CALLS].line[0] = "Remote"; + netperf_output_source[REMOTE_RECV_CALLS].line[1] = "Recv"; + netperf_output_source[REMOTE_RECV_CALLS].line[2] = "Calls"; + netperf_output_source[REMOTE_RECV_CALLS].line[3] = ""; + netperf_output_source[REMOTE_RECV_CALLS].format = "%lld"; + netperf_output_source[REMOTE_RECV_CALLS].display_value = &remote_receive_calls; + netperf_output_source[REMOTE_RECV_CALLS].max_line_len = + NETPERF_LINE_MAX(REMOTE_RECV_CALLS); + netperf_output_source[REMOTE_RECV_CALLS].tot_line_len = + NETPERF_LINE_TOT(REMOTE_RECV_CALLS); + + netperf_output_source[REMOTE_BYTES_PER_RECV].output_name = REMOTE_BYTES_PER_RECV; + netperf_output_source[REMOTE_BYTES_PER_RECV].line[0] = "Remote"; + netperf_output_source[REMOTE_BYTES_PER_RECV].line[1] = "Bytes"; + netperf_output_source[REMOTE_BYTES_PER_RECV].line[2] = "Per"; + netperf_output_source[REMOTE_BYTES_PER_RECV].line[3] = "Recv"; + netperf_output_source[REMOTE_BYTES_PER_RECV].format = "%.2f"; + netperf_output_source[REMOTE_BYTES_PER_RECV].display_value = &remote_bytes_per_recv; + netperf_output_source[REMOTE_BYTES_PER_RECV].max_line_len = + NETPERF_LINE_MAX(REMOTE_BYTES_PER_RECV); + netperf_output_source[REMOTE_BYTES_PER_RECV].tot_line_len = + NETPERF_LINE_TOT(REMOTE_BYTES_PER_RECV); + + netperf_output_source[REMOTE_BYTES_PER_SEND].output_name = REMOTE_BYTES_PER_SEND; + netperf_output_source[REMOTE_BYTES_PER_SEND].line[0] = "Remote"; + netperf_output_source[REMOTE_BYTES_PER_SEND].line[1] = "Bytes"; + netperf_output_source[REMOTE_BYTES_PER_SEND].line[2] = "Per"; + netperf_output_source[REMOTE_BYTES_PER_SEND].line[3] = "Send"; + netperf_output_source[REMOTE_BYTES_PER_SEND].format = "%.2f"; + netperf_output_source[REMOTE_BYTES_PER_SEND].display_value = &remote_bytes_per_send; + netperf_output_source[REMOTE_BYTES_PER_SEND].max_line_len = + NETPERF_LINE_MAX(REMOTE_BYTES_PER_SEND); + netperf_output_source[REMOTE_BYTES_PER_SEND].tot_line_len = + NETPERF_LINE_TOT(REMOTE_BYTES_PER_SEND); + + netperf_output_source[REMOTE_BYTES_RECVD].output_name = REMOTE_BYTES_RECVD; + netperf_output_source[REMOTE_BYTES_RECVD].line[0] = "Remote"; + netperf_output_source[REMOTE_BYTES_RECVD].line[1] = "Bytes"; + netperf_output_source[REMOTE_BYTES_RECVD].line[2] = "Received"; + netperf_output_source[REMOTE_BYTES_RECVD].line[3] = ""; + netperf_output_source[REMOTE_BYTES_RECVD].format = "%lld"; + netperf_output_source[REMOTE_BYTES_RECVD].display_value = &remote_bytes_received; + netperf_output_source[REMOTE_BYTES_RECVD].max_line_len = + NETPERF_LINE_MAX(REMOTE_BYTES_RECVD); + netperf_output_source[REMOTE_BYTES_RECVD].tot_line_len = + NETPERF_LINE_TOT(REMOTE_BYTES_RECVD); + + netperf_output_source[REMOTE_BYTES_SENT].output_name = REMOTE_BYTES_SENT; + netperf_output_source[REMOTE_BYTES_SENT].line[0] = "Remote"; + netperf_output_source[REMOTE_BYTES_SENT].line[1] = "Bytes"; + netperf_output_source[REMOTE_BYTES_SENT].line[2] = "Sent"; + netperf_output_source[REMOTE_BYTES_SENT].line[3] = ""; + netperf_output_source[REMOTE_BYTES_SENT].format = "%lld"; + netperf_output_source[REMOTE_BYTES_SENT].display_value = &remote_bytes_sent; + netperf_output_source[REMOTE_BYTES_SENT].max_line_len = + NETPERF_LINE_MAX(REMOTE_BYTES_SENT); + netperf_output_source[REMOTE_BYTES_SENT].tot_line_len = + NETPERF_LINE_TOT(REMOTE_BYTES_SENT); + + netperf_output_source[REMOTE_BYTES_XFERD].output_name = REMOTE_BYTES_XFERD; + netperf_output_source[REMOTE_BYTES_XFERD].line[0] = "Remote"; + netperf_output_source[REMOTE_BYTES_XFERD].line[1] = "Bytes"; + netperf_output_source[REMOTE_BYTES_XFERD].line[2] = "Xferred"; + netperf_output_source[REMOTE_BYTES_XFERD].line[3] = ""; + netperf_output_source[REMOTE_BYTES_XFERD].format = "%.0f"; + netperf_output_source[REMOTE_BYTES_XFERD].display_value = &remote_bytes_xferd; + netperf_output_source[REMOTE_BYTES_XFERD].max_line_len = + NETPERF_LINE_MAX(REMOTE_BYTES_XFERD); + netperf_output_source[REMOTE_BYTES_XFERD].tot_line_len = + NETPERF_LINE_TOT(REMOTE_BYTES_XFERD); + + netperf_output_source[REMOTE_SEND_WIDTH].output_name = REMOTE_SEND_WIDTH; + netperf_output_source[REMOTE_SEND_WIDTH].line[0] = "Remote"; + netperf_output_source[REMOTE_SEND_WIDTH].line[1] = "Send"; + netperf_output_source[REMOTE_SEND_WIDTH].line[2] = "Width"; + netperf_output_source[REMOTE_SEND_WIDTH].format = "%d"; + netperf_output_source[REMOTE_SEND_WIDTH].display_value = &remote_send_width; + netperf_output_source[REMOTE_SEND_WIDTH].max_line_len = + NETPERF_LINE_MAX(REMOTE_SEND_WIDTH); + netperf_output_source[REMOTE_SEND_WIDTH].tot_line_len = + NETPERF_LINE_TOT(REMOTE_SEND_WIDTH); + + netperf_output_source[REMOTE_RECV_WIDTH].output_name = REMOTE_RECV_WIDTH; + netperf_output_source[REMOTE_RECV_WIDTH].line[0] = "Remote"; + netperf_output_source[REMOTE_RECV_WIDTH].line[1] = "Recv"; + netperf_output_source[REMOTE_RECV_WIDTH].line[2] = "Width"; + netperf_output_source[REMOTE_RECV_WIDTH].format = "%d"; + netperf_output_source[REMOTE_RECV_WIDTH].display_value = &remote_recv_width; + netperf_output_source[REMOTE_RECV_WIDTH].max_line_len = + NETPERF_LINE_MAX(REMOTE_RECV_WIDTH); + netperf_output_source[REMOTE_RECV_WIDTH].tot_line_len = + NETPERF_LINE_TOT(REMOTE_RECV_WIDTH); + + netperf_output_source[REMOTE_SEND_OFFSET].output_name = REMOTE_SEND_OFFSET; + netperf_output_source[REMOTE_SEND_OFFSET].line[0] = "Remote"; + netperf_output_source[REMOTE_SEND_OFFSET].line[1] = "Send"; + netperf_output_source[REMOTE_SEND_OFFSET].line[2] = "Offset"; + netperf_output_source[REMOTE_SEND_OFFSET].format = "%d"; + netperf_output_source[REMOTE_SEND_OFFSET].display_value = &remote_send_offset; + netperf_output_source[REMOTE_SEND_OFFSET].max_line_len = + NETPERF_LINE_MAX(REMOTE_SEND_OFFSET); + netperf_output_source[REMOTE_SEND_OFFSET].tot_line_len = + NETPERF_LINE_TOT(REMOTE_SEND_OFFSET); + + netperf_output_source[REMOTE_RECV_OFFSET].output_name = REMOTE_RECV_OFFSET; + netperf_output_source[REMOTE_RECV_OFFSET].line[0] = "Remote"; + netperf_output_source[REMOTE_RECV_OFFSET].line[1] = "Recv"; + netperf_output_source[REMOTE_RECV_OFFSET].line[2] = "Offset"; + netperf_output_source[REMOTE_RECV_OFFSET].format = "%d"; + netperf_output_source[REMOTE_RECV_OFFSET].display_value = &remote_recv_offset; + netperf_output_source[REMOTE_RECV_OFFSET].max_line_len = + NETPERF_LINE_MAX(REMOTE_RECV_OFFSET); + netperf_output_source[REMOTE_RECV_OFFSET].tot_line_len = + NETPERF_LINE_TOT(REMOTE_RECV_OFFSET); + + netperf_output_source[REMOTE_RECV_ALIGN].output_name = REMOTE_RECV_ALIGN; + netperf_output_source[REMOTE_RECV_ALIGN].line[0] = "Remote"; + netperf_output_source[REMOTE_RECV_ALIGN].line[1] = "Recv"; + netperf_output_source[REMOTE_RECV_ALIGN].line[2] = "Alignment"; + netperf_output_source[REMOTE_RECV_ALIGN].format = "%d"; + netperf_output_source[REMOTE_RECV_ALIGN].display_value = &remote_recv_align; + netperf_output_source[REMOTE_RECV_ALIGN].max_line_len = + NETPERF_LINE_MAX(REMOTE_RECV_ALIGN); + netperf_output_source[REMOTE_RECV_ALIGN].tot_line_len = + NETPERF_LINE_TOT(REMOTE_RECV_ALIGN); + + netperf_output_source[REMOTE_SEND_ALIGN].output_name = REMOTE_SEND_ALIGN; + netperf_output_source[REMOTE_SEND_ALIGN].line[0] = "Remote"; + netperf_output_source[REMOTE_SEND_ALIGN].line[1] = "Send"; + netperf_output_source[REMOTE_SEND_ALIGN].line[2] = "Alignment"; + netperf_output_source[REMOTE_SEND_ALIGN].format = "%d"; + netperf_output_source[REMOTE_SEND_ALIGN].display_value = &remote_send_align; + netperf_output_source[REMOTE_SEND_ALIGN].max_line_len = + NETPERF_LINE_MAX(REMOTE_SEND_ALIGN); + netperf_output_source[REMOTE_SEND_ALIGN].tot_line_len = + NETPERF_LINE_TOT(REMOTE_SEND_ALIGN); + + netperf_output_source[REMOTE_SEND_DIRTY_COUNT].output_name = REMOTE_SEND_DIRTY_COUNT; + netperf_output_source[REMOTE_SEND_DIRTY_COUNT].line[0] = "Remote"; + netperf_output_source[REMOTE_SEND_DIRTY_COUNT].line[1] = "Send"; + netperf_output_source[REMOTE_SEND_DIRTY_COUNT].line[2] = "Dirty"; + netperf_output_source[REMOTE_SEND_DIRTY_COUNT].line[3] = "Count"; + netperf_output_source[REMOTE_SEND_DIRTY_COUNT].format = "%d"; + netperf_output_source[REMOTE_SEND_DIRTY_COUNT].display_value = &rem_dirty_count; + netperf_output_source[REMOTE_SEND_DIRTY_COUNT].max_line_len = + NETPERF_LINE_MAX(REMOTE_SEND_DIRTY_COUNT); + netperf_output_source[REMOTE_SEND_DIRTY_COUNT].tot_line_len = + NETPERF_LINE_TOT(REMOTE_SEND_DIRTY_COUNT); + + netperf_output_source[REMOTE_RECV_DIRTY_COUNT].output_name = REMOTE_RECV_DIRTY_COUNT; + netperf_output_source[REMOTE_RECV_DIRTY_COUNT].line[0] = "Remote"; + netperf_output_source[REMOTE_RECV_DIRTY_COUNT].line[1] = "Recv"; + netperf_output_source[REMOTE_RECV_DIRTY_COUNT].line[2] = "Dirty"; + netperf_output_source[REMOTE_RECV_DIRTY_COUNT].line[3] = "Count"; + netperf_output_source[REMOTE_RECV_DIRTY_COUNT].format = "%d"; + netperf_output_source[REMOTE_RECV_DIRTY_COUNT].display_value = &rem_dirty_count; + netperf_output_source[REMOTE_RECV_DIRTY_COUNT].max_line_len = + NETPERF_LINE_MAX(REMOTE_RECV_DIRTY_COUNT); + netperf_output_source[REMOTE_RECV_DIRTY_COUNT].tot_line_len = + NETPERF_LINE_TOT(REMOTE_RECV_DIRTY_COUNT); + + netperf_output_source[REMOTE_RECV_CLEAN_COUNT].output_name = REMOTE_RECV_CLEAN_COUNT; + netperf_output_source[REMOTE_RECV_CLEAN_COUNT].line[0] = "Remote"; + netperf_output_source[REMOTE_RECV_CLEAN_COUNT].line[1] = "Recv"; + netperf_output_source[REMOTE_RECV_CLEAN_COUNT].line[2] = "Clean"; + netperf_output_source[REMOTE_RECV_CLEAN_COUNT].line[3] = "Count"; + netperf_output_source[REMOTE_RECV_CLEAN_COUNT].format = "%d"; + netperf_output_source[REMOTE_RECV_CLEAN_COUNT].display_value = &rem_clean_count; + netperf_output_source[REMOTE_RECV_CLEAN_COUNT].max_line_len = + NETPERF_LINE_MAX(REMOTE_RECV_CLEAN_COUNT); + netperf_output_source[REMOTE_RECV_CLEAN_COUNT].tot_line_len = + NETPERF_LINE_TOT(REMOTE_RECV_CLEAN_COUNT); + + netperf_output_source[REMOTE_CPU_UTIL].output_name = REMOTE_CPU_UTIL; + netperf_output_source[REMOTE_CPU_UTIL].line[0] = "Remote"; + netperf_output_source[REMOTE_CPU_UTIL].line[1] = "CPU"; + netperf_output_source[REMOTE_CPU_UTIL].line[2] = "Util"; + netperf_output_source[REMOTE_CPU_UTIL].line[3] = "%"; + netperf_output_source[REMOTE_CPU_UTIL].format = "%.2f"; + netperf_output_source[REMOTE_CPU_UTIL].display_value = &remote_cpu_utilization_double; + netperf_output_source[REMOTE_CPU_UTIL].max_line_len = + NETPERF_LINE_MAX(REMOTE_CPU_UTIL); + netperf_output_source[REMOTE_CPU_UTIL].tot_line_len = + NETPERF_LINE_TOT(REMOTE_CPU_UTIL); + + netperf_output_source[REMOTE_CPU_PEAK_UTIL].output_name = REMOTE_CPU_PEAK_UTIL; + netperf_output_source[REMOTE_CPU_PEAK_UTIL].line[0] = "Remote"; + netperf_output_source[REMOTE_CPU_PEAK_UTIL].line[1] = "Peak"; + netperf_output_source[REMOTE_CPU_PEAK_UTIL].line[2] = "Per CPU"; + netperf_output_source[REMOTE_CPU_PEAK_UTIL].line[3] = "Util %"; + netperf_output_source[REMOTE_CPU_PEAK_UTIL].format = "%.2f"; + netperf_output_source[REMOTE_CPU_PEAK_UTIL].display_value = &lib_remote_peak_cpu_util; + netperf_output_source[REMOTE_CPU_PEAK_UTIL].max_line_len = + NETPERF_LINE_MAX(REMOTE_CPU_PEAK_UTIL); + netperf_output_source[REMOTE_CPU_PEAK_UTIL].tot_line_len = + NETPERF_LINE_TOT(REMOTE_CPU_PEAK_UTIL); + + netperf_output_source[REMOTE_CPU_PEAK_ID].output_name = REMOTE_CPU_PEAK_ID; + netperf_output_source[REMOTE_CPU_PEAK_ID].line[0] = "Remote"; + netperf_output_source[REMOTE_CPU_PEAK_ID].line[1] = "Peak"; + netperf_output_source[REMOTE_CPU_PEAK_ID].line[2] = "Per CPU"; + netperf_output_source[REMOTE_CPU_PEAK_ID].line[3] = "ID"; + netperf_output_source[REMOTE_CPU_PEAK_ID].format = "%d"; + netperf_output_source[REMOTE_CPU_PEAK_ID].display_value = &lib_remote_peak_cpu_id; + netperf_output_source[REMOTE_CPU_PEAK_ID].max_line_len = + NETPERF_LINE_MAX(REMOTE_CPU_PEAK_ID); + netperf_output_source[REMOTE_CPU_PEAK_ID].tot_line_len = + NETPERF_LINE_TOT(REMOTE_CPU_PEAK_ID); + + netperf_output_source[REMOTE_CPU_BIND].output_name = REMOTE_CPU_BIND; + netperf_output_source[REMOTE_CPU_BIND].line[0] = "Remote"; + netperf_output_source[REMOTE_CPU_BIND].line[1] = "CPU"; + netperf_output_source[REMOTE_CPU_BIND].line[2] = "Bind"; + netperf_output_source[REMOTE_CPU_BIND].line[3] = ""; + netperf_output_source[REMOTE_CPU_BIND].format = "%d"; + netperf_output_source[REMOTE_CPU_BIND].display_value = &remote_proc_affinity; + netperf_output_source[REMOTE_CPU_BIND].max_line_len = + NETPERF_LINE_MAX(REMOTE_CPU_BIND); + netperf_output_source[REMOTE_CPU_BIND].tot_line_len = + NETPERF_LINE_TOT(REMOTE_CPU_BIND); + + netperf_output_source[REMOTE_SD].output_name = REMOTE_SD; + netperf_output_source[REMOTE_SD].line[0] = "Remote"; + netperf_output_source[REMOTE_SD].line[1] = "Service"; + netperf_output_source[REMOTE_SD].line[2] = "Demand"; + netperf_output_source[REMOTE_SD].line[3] = ""; + netperf_output_source[REMOTE_SD].format = "%.3f"; + netperf_output_source[REMOTE_SD].display_value = &remote_service_demand_double; + netperf_output_source[REMOTE_SD].max_line_len = + NETPERF_LINE_MAX(REMOTE_SD); + netperf_output_source[REMOTE_SD].tot_line_len = + NETPERF_LINE_TOT(REMOTE_SD); + + netperf_output_source[REMOTE_CPU_METHOD].output_name = REMOTE_CPU_METHOD; + netperf_output_source[REMOTE_CPU_METHOD].line[0] = "Remote"; + netperf_output_source[REMOTE_CPU_METHOD].line[1] = "CPU"; + netperf_output_source[REMOTE_CPU_METHOD].line[2] = "Util"; + netperf_output_source[REMOTE_CPU_METHOD].line[3] = "Method"; + netperf_output_source[REMOTE_CPU_METHOD].format = "%c"; + netperf_output_source[REMOTE_CPU_METHOD].display_value = &remote_cpu_method; + netperf_output_source[REMOTE_CPU_METHOD].max_line_len = + NETPERF_LINE_MAX(REMOTE_CPU_METHOD); + netperf_output_source[REMOTE_CPU_METHOD].tot_line_len = + NETPERF_LINE_TOT(REMOTE_CPU_METHOD); + + netperf_output_source[REMOTE_CPU_COUNT].output_name = REMOTE_CPU_COUNT; + netperf_output_source[REMOTE_CPU_COUNT].line[0] = "Remote"; + netperf_output_source[REMOTE_CPU_COUNT].line[1] = "CPU"; + netperf_output_source[REMOTE_CPU_COUNT].line[2] = "Count"; + netperf_output_source[REMOTE_CPU_COUNT].format = "%d"; + netperf_output_source[REMOTE_CPU_COUNT].display_value = &lib_num_rem_cpus; + netperf_output_source[REMOTE_CPU_COUNT].max_line_len = + NETPERF_LINE_MAX(REMOTE_CPU_COUNT); + netperf_output_source[REMOTE_CPU_COUNT].tot_line_len = + NETPERF_LINE_TOT(REMOTE_CPU_COUNT); + + netperf_output_source[REMOTE_NODELAY].output_name = REMOTE_NODELAY; + netperf_output_source[REMOTE_NODELAY].line[0] = "Remote"; + netperf_output_source[REMOTE_NODELAY].line[1] = "NODELAY"; + netperf_output_source[REMOTE_NODELAY].line[2] = ""; + netperf_output_source[REMOTE_NODELAY].line[3] = ""; + netperf_output_source[REMOTE_NODELAY].format = "%d"; + netperf_output_source[REMOTE_NODELAY].display_value = &rem_nodelay; + netperf_output_source[REMOTE_NODELAY].max_line_len = + NETPERF_LINE_MAX(REMOTE_NODELAY); + netperf_output_source[REMOTE_NODELAY].tot_line_len = + NETPERF_LINE_TOT(REMOTE_NODELAY); + + netperf_output_source[REMOTE_CORK].output_name = REMOTE_CORK; + netperf_output_source[REMOTE_CORK].line[0] = "Remote"; + netperf_output_source[REMOTE_CORK].line[1] = "Cork"; + netperf_output_source[REMOTE_CORK].line[2] = ""; + netperf_output_source[REMOTE_CORK].line[3] = ""; + netperf_output_source[REMOTE_CORK].format = "%d"; + netperf_output_source[REMOTE_CORK].display_value = &rem_tcpcork; + netperf_output_source[REMOTE_CORK].max_line_len = + NETPERF_LINE_MAX(REMOTE_CORK); + netperf_output_source[REMOTE_CORK].tot_line_len = + NETPERF_LINE_TOT(REMOTE_CORK); + + netperf_output_source[LOCAL_DRIVER_NAME].output_name = LOCAL_DRIVER_NAME; + netperf_output_source[LOCAL_DRIVER_NAME].line[0] = "Local"; + netperf_output_source[LOCAL_DRIVER_NAME].line[1] = "Driver"; + netperf_output_source[LOCAL_DRIVER_NAME].line[2] = "Name"; + netperf_output_source[LOCAL_DRIVER_NAME].line[3] = ""; + netperf_output_source[LOCAL_DRIVER_NAME].format = "%s"; + netperf_output_source[LOCAL_DRIVER_NAME].display_value = local_driver_name; + netperf_output_source[LOCAL_DRIVER_NAME].max_line_len = + NETPERF_LINE_MAX(LOCAL_DRIVER_NAME); + netperf_output_source[LOCAL_DRIVER_NAME].tot_line_len = + NETPERF_LINE_TOT(LOCAL_DRIVER_NAME); + + netperf_output_source[LOCAL_DRIVER_VERSION].output_name = LOCAL_DRIVER_VERSION; + netperf_output_source[LOCAL_DRIVER_VERSION].line[0] = "Local"; + netperf_output_source[LOCAL_DRIVER_VERSION].line[1] = "Driver"; + netperf_output_source[LOCAL_DRIVER_VERSION].line[2] = "Version"; + netperf_output_source[LOCAL_DRIVER_VERSION].line[3] = ""; + netperf_output_source[LOCAL_DRIVER_VERSION].format = "%s"; + netperf_output_source[LOCAL_DRIVER_VERSION].display_value = local_driver_version; + netperf_output_source[LOCAL_DRIVER_VERSION].max_line_len = + NETPERF_LINE_MAX(LOCAL_DRIVER_VERSION); + netperf_output_source[LOCAL_DRIVER_VERSION].tot_line_len = + NETPERF_LINE_TOT(LOCAL_DRIVER_VERSION); + + netperf_output_source[LOCAL_DRIVER_FIRMWARE].output_name = LOCAL_DRIVER_FIRMWARE; + netperf_output_source[LOCAL_DRIVER_FIRMWARE].line[0] = "Local"; + netperf_output_source[LOCAL_DRIVER_FIRMWARE].line[1] = "Driver"; + netperf_output_source[LOCAL_DRIVER_FIRMWARE].line[2] = "Firmware"; + netperf_output_source[LOCAL_DRIVER_FIRMWARE].line[3] = ""; + netperf_output_source[LOCAL_DRIVER_FIRMWARE].format = "%s"; + netperf_output_source[LOCAL_DRIVER_FIRMWARE].display_value = local_driver_firmware; + netperf_output_source[LOCAL_DRIVER_FIRMWARE].max_line_len = + NETPERF_LINE_MAX(LOCAL_DRIVER_FIRMWARE); + netperf_output_source[LOCAL_DRIVER_FIRMWARE].tot_line_len = + NETPERF_LINE_TOT(LOCAL_DRIVER_FIRMWARE); + + netperf_output_source[LOCAL_DRIVER_BUS].output_name = LOCAL_DRIVER_BUS; + netperf_output_source[LOCAL_DRIVER_BUS].line[0] = "Local"; + netperf_output_source[LOCAL_DRIVER_BUS].line[1] = "Driver"; + netperf_output_source[LOCAL_DRIVER_BUS].line[2] = "Bus"; + netperf_output_source[LOCAL_DRIVER_BUS].line[3] = ""; + netperf_output_source[LOCAL_DRIVER_BUS].format = "%s"; + netperf_output_source[LOCAL_DRIVER_BUS].display_value = local_driver_bus; + netperf_output_source[LOCAL_DRIVER_BUS].max_line_len = + NETPERF_LINE_MAX(LOCAL_DRIVER_BUS); + netperf_output_source[LOCAL_DRIVER_BUS].tot_line_len = + NETPERF_LINE_TOT(LOCAL_DRIVER_BUS); + + netperf_output_source[REMOTE_DRIVER_NAME].output_name = REMOTE_DRIVER_NAME; + netperf_output_source[REMOTE_DRIVER_NAME].line[0] = "Remote"; + netperf_output_source[REMOTE_DRIVER_NAME].line[1] = "Driver"; + netperf_output_source[REMOTE_DRIVER_NAME].line[2] = "Name"; + netperf_output_source[REMOTE_DRIVER_NAME].line[3] = ""; + netperf_output_source[REMOTE_DRIVER_NAME].format = "%s"; + netperf_output_source[REMOTE_DRIVER_NAME].display_value = remote_driver_name; + netperf_output_source[REMOTE_DRIVER_NAME].max_line_len = + NETPERF_LINE_MAX(REMOTE_DRIVER_NAME); + netperf_output_source[REMOTE_DRIVER_NAME].tot_line_len = + NETPERF_LINE_TOT(REMOTE_DRIVER_NAME); + + netperf_output_source[REMOTE_DRIVER_VERSION].output_name = REMOTE_DRIVER_VERSION; + netperf_output_source[REMOTE_DRIVER_VERSION].line[0] = "Remote"; + netperf_output_source[REMOTE_DRIVER_VERSION].line[1] = "Driver"; + netperf_output_source[REMOTE_DRIVER_VERSION].line[2] = "Version"; + netperf_output_source[REMOTE_DRIVER_VERSION].line[3] = ""; + netperf_output_source[REMOTE_DRIVER_VERSION].format = "%s"; + netperf_output_source[REMOTE_DRIVER_VERSION].display_value = remote_driver_version; + netperf_output_source[REMOTE_DRIVER_VERSION].max_line_len = + NETPERF_LINE_MAX(REMOTE_DRIVER_VERSION); + netperf_output_source[REMOTE_DRIVER_VERSION].tot_line_len = + NETPERF_LINE_TOT(REMOTE_DRIVER_VERSION); + + netperf_output_source[REMOTE_DRIVER_FIRMWARE].output_name = REMOTE_DRIVER_FIRMWARE; + netperf_output_source[REMOTE_DRIVER_FIRMWARE].line[0] = "Remote"; + netperf_output_source[REMOTE_DRIVER_FIRMWARE].line[1] = "Driver"; + netperf_output_source[REMOTE_DRIVER_FIRMWARE].line[2] = "Firmware"; + netperf_output_source[REMOTE_DRIVER_FIRMWARE].line[3] = ""; + netperf_output_source[REMOTE_DRIVER_FIRMWARE].format = "%s"; + netperf_output_source[REMOTE_DRIVER_FIRMWARE].display_value = remote_driver_firmware; + netperf_output_source[REMOTE_DRIVER_FIRMWARE].max_line_len = + NETPERF_LINE_MAX(REMOTE_DRIVER_FIRMWARE); + netperf_output_source[REMOTE_DRIVER_FIRMWARE].tot_line_len = + NETPERF_LINE_TOT(REMOTE_DRIVER_FIRMWARE); + + netperf_output_source[REMOTE_DRIVER_BUS].output_name = REMOTE_DRIVER_BUS; + netperf_output_source[REMOTE_DRIVER_BUS].line[0] = "Remote"; + netperf_output_source[REMOTE_DRIVER_BUS].line[1] = "Driver"; + netperf_output_source[REMOTE_DRIVER_BUS].line[2] = "Bus"; + netperf_output_source[REMOTE_DRIVER_BUS].line[3] = ""; + netperf_output_source[REMOTE_DRIVER_BUS].format = "%s"; + netperf_output_source[REMOTE_DRIVER_BUS].display_value = remote_driver_bus; + netperf_output_source[REMOTE_DRIVER_BUS].max_line_len = + NETPERF_LINE_MAX(REMOTE_DRIVER_BUS); + netperf_output_source[REMOTE_DRIVER_BUS].tot_line_len = + NETPERF_LINE_TOT(REMOTE_DRIVER_BUS); + + netperf_output_source[LOCAL_INTERFACE_SUBDEVICE].output_name = LOCAL_INTERFACE_SUBDEVICE; + netperf_output_source[LOCAL_INTERFACE_SUBDEVICE].line[0] = "Local"; + netperf_output_source[LOCAL_INTERFACE_SUBDEVICE].line[1] = "Interface"; + netperf_output_source[LOCAL_INTERFACE_SUBDEVICE].line[2] = "Subdevice"; + netperf_output_source[LOCAL_INTERFACE_SUBDEVICE].line[3] = ""; + netperf_output_source[LOCAL_INTERFACE_SUBDEVICE].format = "0x%.4x"; + netperf_output_source[LOCAL_INTERFACE_SUBDEVICE].display_value = &local_interface_subdevice; + netperf_output_source[LOCAL_INTERFACE_SUBDEVICE].max_line_len = + NETPERF_LINE_MAX(LOCAL_INTERFACE_SUBDEVICE); + netperf_output_source[LOCAL_INTERFACE_SUBDEVICE].tot_line_len = + NETPERF_LINE_TOT(LOCAL_INTERFACE_SUBDEVICE); + + netperf_output_source[LOCAL_INTERFACE_DEVICE].output_name = LOCAL_INTERFACE_DEVICE; + netperf_output_source[LOCAL_INTERFACE_DEVICE].line[0] = "Local"; + netperf_output_source[LOCAL_INTERFACE_DEVICE].line[1] = "Interface"; + netperf_output_source[LOCAL_INTERFACE_DEVICE].line[2] = "Device"; + netperf_output_source[LOCAL_INTERFACE_DEVICE].line[3] = ""; + netperf_output_source[LOCAL_INTERFACE_DEVICE].format = "0x%.4x"; + netperf_output_source[LOCAL_INTERFACE_DEVICE].display_value = &local_interface_device; + netperf_output_source[LOCAL_INTERFACE_DEVICE].max_line_len = + NETPERF_LINE_MAX(LOCAL_INTERFACE_DEVICE); + netperf_output_source[LOCAL_INTERFACE_DEVICE].tot_line_len = + NETPERF_LINE_TOT(LOCAL_INTERFACE_DEVICE); + + netperf_output_source[LOCAL_INTERFACE_SUBVENDOR].output_name = LOCAL_INTERFACE_SUBVENDOR; + netperf_output_source[LOCAL_INTERFACE_SUBVENDOR].line[0] = "Local"; + netperf_output_source[LOCAL_INTERFACE_SUBVENDOR].line[1] = "Interface"; + netperf_output_source[LOCAL_INTERFACE_SUBVENDOR].line[2] = "Subvendor"; + netperf_output_source[LOCAL_INTERFACE_SUBVENDOR].line[3] = ""; + netperf_output_source[LOCAL_INTERFACE_SUBVENDOR].format = "0x%.4x"; + netperf_output_source[LOCAL_INTERFACE_SUBVENDOR].display_value = &local_interface_subvendor; + netperf_output_source[LOCAL_INTERFACE_SUBVENDOR].max_line_len = + NETPERF_LINE_MAX(LOCAL_INTERFACE_SUBVENDOR); + netperf_output_source[LOCAL_INTERFACE_SUBVENDOR].tot_line_len = + NETPERF_LINE_TOT(LOCAL_INTERFACE_SUBVENDOR); + + netperf_output_source[LOCAL_INTERFACE_VENDOR].output_name = LOCAL_INTERFACE_VENDOR; + netperf_output_source[LOCAL_INTERFACE_VENDOR].line[0] = "Local"; + netperf_output_source[LOCAL_INTERFACE_VENDOR].line[1] = "Interface"; + netperf_output_source[LOCAL_INTERFACE_VENDOR].line[2] = "Vendor"; + netperf_output_source[LOCAL_INTERFACE_VENDOR].line[3] = ""; + netperf_output_source[LOCAL_INTERFACE_VENDOR].format = "0x%.4x"; + netperf_output_source[LOCAL_INTERFACE_VENDOR].display_value = &local_interface_vendor; + netperf_output_source[LOCAL_INTERFACE_VENDOR].max_line_len = + NETPERF_LINE_MAX(LOCAL_INTERFACE_VENDOR); + netperf_output_source[LOCAL_INTERFACE_VENDOR].tot_line_len = + NETPERF_LINE_TOT(LOCAL_INTERFACE_VENDOR); + + netperf_output_source[REMOTE_INTERFACE_SUBDEVICE].output_name = REMOTE_INTERFACE_SUBDEVICE; + netperf_output_source[REMOTE_INTERFACE_SUBDEVICE].line[0] = "Remote"; + netperf_output_source[REMOTE_INTERFACE_SUBDEVICE].line[1] = "Interface"; + netperf_output_source[REMOTE_INTERFACE_SUBDEVICE].line[2] = "Subdevice"; + netperf_output_source[REMOTE_INTERFACE_SUBDEVICE].line[3] = ""; + netperf_output_source[REMOTE_INTERFACE_SUBDEVICE].format = "0x%.4x"; + netperf_output_source[REMOTE_INTERFACE_SUBDEVICE].display_value = &remote_interface_subdevice; + netperf_output_source[REMOTE_INTERFACE_SUBDEVICE].max_line_len = + NETPERF_LINE_MAX(REMOTE_INTERFACE_SUBDEVICE); + netperf_output_source[REMOTE_INTERFACE_SUBDEVICE].tot_line_len = + NETPERF_LINE_TOT(REMOTE_INTERFACE_SUBDEVICE); + + netperf_output_source[REMOTE_INTERFACE_DEVICE].output_name = REMOTE_INTERFACE_DEVICE; + netperf_output_source[REMOTE_INTERFACE_DEVICE].line[0] = "Remote"; + netperf_output_source[REMOTE_INTERFACE_DEVICE].line[1] = "Interface"; + netperf_output_source[REMOTE_INTERFACE_DEVICE].line[2] = "Device"; + netperf_output_source[REMOTE_INTERFACE_DEVICE].line[3] = ""; + netperf_output_source[REMOTE_INTERFACE_DEVICE].format = "0x%.4x"; + netperf_output_source[REMOTE_INTERFACE_DEVICE].display_value = &remote_interface_device; + netperf_output_source[REMOTE_INTERFACE_DEVICE].max_line_len = + NETPERF_LINE_MAX(REMOTE_INTERFACE_DEVICE); + netperf_output_source[REMOTE_INTERFACE_DEVICE].tot_line_len = + NETPERF_LINE_TOT(REMOTE_INTERFACE_DEVICE); + + netperf_output_source[REMOTE_INTERFACE_SUBVENDOR].output_name = REMOTE_INTERFACE_SUBVENDOR; + netperf_output_source[REMOTE_INTERFACE_SUBVENDOR].line[0] = "Remote"; + netperf_output_source[REMOTE_INTERFACE_SUBVENDOR].line[1] = "Interface"; + netperf_output_source[REMOTE_INTERFACE_SUBVENDOR].line[2] = "Subvendor"; + netperf_output_source[REMOTE_INTERFACE_SUBVENDOR].line[3] = ""; + netperf_output_source[REMOTE_INTERFACE_SUBVENDOR].format = "0x%.4x"; + netperf_output_source[REMOTE_INTERFACE_SUBVENDOR].display_value = &remote_interface_subvendor; + netperf_output_source[REMOTE_INTERFACE_SUBVENDOR].max_line_len = + NETPERF_LINE_MAX(REMOTE_INTERFACE_SUBVENDOR); + netperf_output_source[REMOTE_INTERFACE_SUBVENDOR].tot_line_len = + NETPERF_LINE_TOT(REMOTE_INTERFACE_SUBVENDOR); + + netperf_output_source[REMOTE_INTERFACE_VENDOR].output_name = REMOTE_INTERFACE_VENDOR; + netperf_output_source[REMOTE_INTERFACE_VENDOR].line[0] = "Remote"; + netperf_output_source[REMOTE_INTERFACE_VENDOR].line[1] = "Interface"; + netperf_output_source[REMOTE_INTERFACE_VENDOR].line[2] = "Vendor"; + netperf_output_source[REMOTE_INTERFACE_VENDOR].line[3] = ""; + netperf_output_source[REMOTE_INTERFACE_VENDOR].format = "0x%.4x"; + netperf_output_source[REMOTE_INTERFACE_VENDOR].display_value = &remote_interface_vendor; + netperf_output_source[REMOTE_INTERFACE_VENDOR].max_line_len = + NETPERF_LINE_MAX(REMOTE_INTERFACE_VENDOR); + netperf_output_source[REMOTE_INTERFACE_VENDOR].tot_line_len = + NETPERF_LINE_TOT(REMOTE_INTERFACE_VENDOR); + + netperf_output_source[LOCAL_INTERFACE_NAME].output_name = LOCAL_INTERFACE_NAME; + netperf_output_source[LOCAL_INTERFACE_NAME].line[0] = "Local"; + netperf_output_source[LOCAL_INTERFACE_NAME].line[1] = "Interface"; + netperf_output_source[LOCAL_INTERFACE_NAME].line[2] = "Name"; + netperf_output_source[LOCAL_INTERFACE_NAME].line[3] = ""; + netperf_output_source[LOCAL_INTERFACE_NAME].format = "%s"; + netperf_output_source[LOCAL_INTERFACE_NAME].display_value = local_interface_name; + netperf_output_source[LOCAL_INTERFACE_NAME].max_line_len = + NETPERF_LINE_MAX(LOCAL_INTERFACE_NAME); + netperf_output_source[LOCAL_INTERFACE_NAME].tot_line_len = + NETPERF_LINE_TOT(LOCAL_INTERFACE_NAME); + + netperf_output_source[REMOTE_INTERFACE_NAME].output_name = REMOTE_INTERFACE_NAME; + netperf_output_source[REMOTE_INTERFACE_NAME].line[0] = "Remote"; + netperf_output_source[REMOTE_INTERFACE_NAME].line[1] = "Interface"; + netperf_output_source[REMOTE_INTERFACE_NAME].line[2] = "Name"; + netperf_output_source[REMOTE_INTERFACE_NAME].line[3] = ""; + netperf_output_source[REMOTE_INTERFACE_NAME].format = "%s"; + netperf_output_source[REMOTE_INTERFACE_NAME].display_value = remote_interface_name; + netperf_output_source[REMOTE_INTERFACE_NAME].max_line_len = + NETPERF_LINE_MAX(REMOTE_INTERFACE_NAME); + netperf_output_source[REMOTE_INTERFACE_NAME].tot_line_len = + NETPERF_LINE_TOT(REMOTE_INTERFACE_NAME); + + netperf_output_source[LOCAL_INTERFACE_SLOT].output_name = LOCAL_INTERFACE_SLOT; + netperf_output_source[LOCAL_INTERFACE_SLOT].line[0] = "Local"; + netperf_output_source[LOCAL_INTERFACE_SLOT].line[1] = "Interface"; + netperf_output_source[LOCAL_INTERFACE_SLOT].line[2] = "Slot"; + netperf_output_source[LOCAL_INTERFACE_SLOT].line[3] = ""; + netperf_output_source[LOCAL_INTERFACE_SLOT].format = "%s"; + netperf_output_source[LOCAL_INTERFACE_SLOT].display_value = local_interface_slot; + netperf_output_source[LOCAL_INTERFACE_SLOT].max_line_len = + NETPERF_LINE_MAX(LOCAL_INTERFACE_SLOT); + netperf_output_source[LOCAL_INTERFACE_SLOT].tot_line_len = + NETPERF_LINE_TOT(LOCAL_INTERFACE_SLOT); + + netperf_output_source[REMOTE_INTERFACE_SLOT].output_name = REMOTE_INTERFACE_SLOT; + netperf_output_source[REMOTE_INTERFACE_SLOT].line[0] = "Remote"; + netperf_output_source[REMOTE_INTERFACE_SLOT].line[1] = "Interface"; + netperf_output_source[REMOTE_INTERFACE_SLOT].line[2] = "Slot"; + netperf_output_source[REMOTE_INTERFACE_SLOT].line[3] = ""; + netperf_output_source[REMOTE_INTERFACE_SLOT].format = "%s"; + netperf_output_source[REMOTE_INTERFACE_SLOT].display_value = remote_interface_slot; + netperf_output_source[REMOTE_INTERFACE_SLOT].max_line_len = + NETPERF_LINE_MAX(REMOTE_INTERFACE_SLOT); + netperf_output_source[REMOTE_INTERFACE_SLOT].tot_line_len = + NETPERF_LINE_TOT(REMOTE_INTERFACE_SLOT); + + netperf_output_source[REMOTE_MACHINE].output_name = REMOTE_MACHINE; + netperf_output_source[REMOTE_MACHINE].line[0] = "Remote"; + netperf_output_source[REMOTE_MACHINE].line[1] = "Machine"; + netperf_output_source[REMOTE_MACHINE].line[2] = ""; + netperf_output_source[REMOTE_MACHINE].line[3] = ""; + netperf_output_source[REMOTE_MACHINE].format = "%s"; + netperf_output_source[REMOTE_MACHINE].display_value = remote_machine; + netperf_output_source[REMOTE_MACHINE].max_line_len = + NETPERF_LINE_MAX(REMOTE_MACHINE); + netperf_output_source[REMOTE_MACHINE].tot_line_len = + NETPERF_LINE_TOT(REMOTE_MACHINE); + + netperf_output_source[REMOTE_VERSION].output_name = REMOTE_VERSION; + netperf_output_source[REMOTE_VERSION].line[0] = "Remote"; + netperf_output_source[REMOTE_VERSION].line[1] = "Version"; + netperf_output_source[REMOTE_VERSION].line[2] = ""; + netperf_output_source[REMOTE_VERSION].line[3] = ""; + netperf_output_source[REMOTE_VERSION].format = "%s"; + netperf_output_source[REMOTE_VERSION].display_value = remote_version; + netperf_output_source[REMOTE_VERSION].max_line_len = + NETPERF_LINE_MAX(REMOTE_VERSION); + netperf_output_source[REMOTE_VERSION].tot_line_len = + NETPERF_LINE_TOT(REMOTE_VERSION); + + netperf_output_source[REMOTE_RELEASE].output_name = REMOTE_RELEASE; + netperf_output_source[REMOTE_RELEASE].line[0] = "Remote"; + netperf_output_source[REMOTE_RELEASE].line[1] = "Release"; + netperf_output_source[REMOTE_RELEASE].line[2] = ""; + netperf_output_source[REMOTE_RELEASE].line[3] = ""; + netperf_output_source[REMOTE_RELEASE].format = "%s"; + netperf_output_source[REMOTE_RELEASE].display_value = remote_release; + netperf_output_source[REMOTE_RELEASE].max_line_len = + NETPERF_LINE_MAX(REMOTE_RELEASE); + netperf_output_source[REMOTE_RELEASE].tot_line_len = + NETPERF_LINE_TOT(REMOTE_RELEASE); + + netperf_output_source[REMOTE_SYSNAME].output_name = REMOTE_SYSNAME; + netperf_output_source[REMOTE_SYSNAME].line[0] = "Remote"; + netperf_output_source[REMOTE_SYSNAME].line[1] = "Sysname"; + netperf_output_source[REMOTE_SYSNAME].line[2] = ""; + netperf_output_source[REMOTE_SYSNAME].line[3] = ""; + netperf_output_source[REMOTE_SYSNAME].format = "%s"; + netperf_output_source[REMOTE_SYSNAME].display_value = remote_sysname; + netperf_output_source[REMOTE_SYSNAME].max_line_len = + NETPERF_LINE_MAX(REMOTE_SYSNAME); + netperf_output_source[REMOTE_SYSNAME].tot_line_len = + NETPERF_LINE_TOT(REMOTE_SYSNAME); + + netperf_output_source[LOCAL_MACHINE].output_name = LOCAL_MACHINE; + netperf_output_source[LOCAL_MACHINE].line[0] = "Local"; + netperf_output_source[LOCAL_MACHINE].line[1] = "Machine"; + netperf_output_source[LOCAL_MACHINE].line[2] = ""; + netperf_output_source[LOCAL_MACHINE].line[3] = ""; + netperf_output_source[LOCAL_MACHINE].format = "%s"; + netperf_output_source[LOCAL_MACHINE].display_value = local_machine; + netperf_output_source[LOCAL_MACHINE].max_line_len = + NETPERF_LINE_MAX(LOCAL_MACHINE); + netperf_output_source[LOCAL_MACHINE].tot_line_len = + NETPERF_LINE_TOT(LOCAL_MACHINE); + + netperf_output_source[LOCAL_VERSION].output_name = LOCAL_VERSION; + netperf_output_source[LOCAL_VERSION].line[0] = "Local"; + netperf_output_source[LOCAL_VERSION].line[1] = "Version"; + netperf_output_source[LOCAL_VERSION].line[2] = ""; + netperf_output_source[LOCAL_VERSION].line[3] = ""; + netperf_output_source[LOCAL_VERSION].format = "%s"; + netperf_output_source[LOCAL_VERSION].display_value = local_version; + netperf_output_source[LOCAL_VERSION].max_line_len = + NETPERF_LINE_MAX(LOCAL_VERSION); + netperf_output_source[LOCAL_VERSION].tot_line_len = + NETPERF_LINE_TOT(LOCAL_VERSION); + + netperf_output_source[LOCAL_RELEASE].output_name = LOCAL_RELEASE; + netperf_output_source[LOCAL_RELEASE].line[0] = "Local"; + netperf_output_source[LOCAL_RELEASE].line[1] = "Release"; + netperf_output_source[LOCAL_RELEASE].line[2] = ""; + netperf_output_source[LOCAL_RELEASE].line[3] = ""; + netperf_output_source[LOCAL_RELEASE].format = "%s"; + netperf_output_source[LOCAL_RELEASE].display_value = local_release; + netperf_output_source[LOCAL_RELEASE].max_line_len = + NETPERF_LINE_MAX(LOCAL_RELEASE); + netperf_output_source[LOCAL_RELEASE].tot_line_len = + NETPERF_LINE_TOT(LOCAL_RELEASE); + + netperf_output_source[LOCAL_SYSNAME].output_name = LOCAL_SYSNAME; + netperf_output_source[LOCAL_SYSNAME].line[0] = "Local"; + netperf_output_source[LOCAL_SYSNAME].line[1] = "Sysname"; + netperf_output_source[LOCAL_SYSNAME].line[2] = ""; + netperf_output_source[LOCAL_SYSNAME].line[3] = ""; + netperf_output_source[LOCAL_SYSNAME].format = "%s"; + netperf_output_source[LOCAL_SYSNAME].display_value = local_sysname; + netperf_output_source[LOCAL_SYSNAME].max_line_len = + NETPERF_LINE_MAX(LOCAL_SYSNAME); + netperf_output_source[LOCAL_SYSNAME].tot_line_len = + NETPERF_LINE_TOT(LOCAL_SYSNAME); + + netperf_output_source[REMOTE_INTERVAL_USECS].output_name = REMOTE_INTERVAL_USECS; + netperf_output_source[REMOTE_INTERVAL_USECS].line[0] = "Remote"; + netperf_output_source[REMOTE_INTERVAL_USECS].line[1] = "Interval"; + netperf_output_source[REMOTE_INTERVAL_USECS].line[2] = "Usecs"; + netperf_output_source[REMOTE_INTERVAL_USECS].line[3] = ""; + netperf_output_source[REMOTE_INTERVAL_USECS].format = "%d"; + netperf_output_source[REMOTE_INTERVAL_USECS].display_value = &remote_interval_usecs; + netperf_output_source[REMOTE_INTERVAL_USECS].max_line_len = + NETPERF_LINE_MAX(REMOTE_INTERVAL_USECS); + netperf_output_source[REMOTE_INTERVAL_USECS].tot_line_len = + NETPERF_LINE_TOT(REMOTE_INTERVAL_USECS); + + netperf_output_source[REMOTE_INTERVAL_BURST].output_name = REMOTE_INTERVAL_BURST; + netperf_output_source[REMOTE_INTERVAL_BURST].line[0] = "Remote"; + netperf_output_source[REMOTE_INTERVAL_BURST].line[1] = "Interval"; + netperf_output_source[REMOTE_INTERVAL_BURST].line[2] = "Burst"; + netperf_output_source[REMOTE_INTERVAL_BURST].line[3] = ""; + netperf_output_source[REMOTE_INTERVAL_BURST].format = "%d"; + netperf_output_source[REMOTE_INTERVAL_BURST].display_value = &remote_interval_burst; + netperf_output_source[REMOTE_INTERVAL_BURST].max_line_len = + NETPERF_LINE_MAX(REMOTE_INTERVAL_BURST); + netperf_output_source[REMOTE_INTERVAL_BURST].tot_line_len = + NETPERF_LINE_TOT(REMOTE_INTERVAL_BURST); + + netperf_output_source[LOCAL_SECURITY_ENABLED].output_name = LOCAL_SECURITY_ENABLED; + netperf_output_source[LOCAL_SECURITY_ENABLED].line[0] = "Local"; + netperf_output_source[LOCAL_SECURITY_ENABLED].line[1] = "OS"; + netperf_output_source[LOCAL_SECURITY_ENABLED].line[2] = "Security"; + netperf_output_source[LOCAL_SECURITY_ENABLED].line[3] = "Enabled"; + netperf_output_source[LOCAL_SECURITY_ENABLED].format = "%s"; + netperf_output_source[LOCAL_SECURITY_ENABLED].display_value = local_security_enabled; + netperf_output_source[LOCAL_SECURITY_ENABLED].max_line_len = + NETPERF_LINE_MAX(LOCAL_SECURITY_ENABLED); + netperf_output_source[LOCAL_SECURITY_ENABLED].tot_line_len = + NETPERF_LINE_TOT(LOCAL_SECURITY_ENABLED); + + netperf_output_source[LOCAL_SECURITY_TYPE].output_name = LOCAL_SECURITY_TYPE; + netperf_output_source[LOCAL_SECURITY_TYPE].line[0] = "Local"; + netperf_output_source[LOCAL_SECURITY_TYPE].line[1] = "OS"; + netperf_output_source[LOCAL_SECURITY_TYPE].line[2] = "Security"; + netperf_output_source[LOCAL_SECURITY_TYPE].line[3] = "Type"; + netperf_output_source[LOCAL_SECURITY_TYPE].format = "%s"; + netperf_output_source[LOCAL_SECURITY_TYPE].display_value = local_security_type; + netperf_output_source[LOCAL_SECURITY_TYPE].max_line_len = + NETPERF_LINE_MAX(LOCAL_SECURITY_TYPE); + netperf_output_source[LOCAL_SECURITY_TYPE].tot_line_len = + NETPERF_LINE_TOT(LOCAL_SECURITY_TYPE); + + netperf_output_source[LOCAL_SECURITY_SPECIFIC].output_name = LOCAL_SECURITY_SPECIFIC; + netperf_output_source[LOCAL_SECURITY_SPECIFIC].line[0] = "Local"; + netperf_output_source[LOCAL_SECURITY_SPECIFIC].line[1] = "OS"; + netperf_output_source[LOCAL_SECURITY_SPECIFIC].line[2] = "Security"; + netperf_output_source[LOCAL_SECURITY_SPECIFIC].line[3] = "Specific"; + netperf_output_source[LOCAL_SECURITY_SPECIFIC].format = "%s"; + netperf_output_source[LOCAL_SECURITY_SPECIFIC].display_value = local_security_specific; + netperf_output_source[LOCAL_SECURITY_SPECIFIC].max_line_len = + NETPERF_LINE_MAX(LOCAL_SECURITY_SPECIFIC); + netperf_output_source[LOCAL_SECURITY_SPECIFIC].tot_line_len = + NETPERF_LINE_TOT(LOCAL_SECURITY_SPECIFIC); + + netperf_output_source[LOCAL_SECURITY_ENABLED_NUM].output_name = LOCAL_SECURITY_ENABLED_NUM; + netperf_output_source[LOCAL_SECURITY_ENABLED_NUM].line[0] = "Local"; + netperf_output_source[LOCAL_SECURITY_ENABLED_NUM].line[1] = "OS"; + netperf_output_source[LOCAL_SECURITY_ENABLED_NUM].line[2] = "Security"; + netperf_output_source[LOCAL_SECURITY_ENABLED_NUM].line[3] = "Enabled Num"; + netperf_output_source[LOCAL_SECURITY_ENABLED_NUM].format = "%d"; + netperf_output_source[LOCAL_SECURITY_ENABLED_NUM].display_value = &local_security_enabled_num; + netperf_output_source[LOCAL_SECURITY_ENABLED_NUM].max_line_len = + NETPERF_LINE_MAX(LOCAL_SECURITY_ENABLED_NUM); + netperf_output_source[LOCAL_SECURITY_ENABLED_NUM].tot_line_len = + NETPERF_LINE_TOT(LOCAL_SECURITY_ENABLED_NUM); + + netperf_output_source[LOCAL_SECURITY_TYPE_ID].output_name = LOCAL_SECURITY_TYPE_ID; + netperf_output_source[LOCAL_SECURITY_TYPE_ID].line[0] = "Local"; + netperf_output_source[LOCAL_SECURITY_TYPE_ID].line[1] = "OS"; + netperf_output_source[LOCAL_SECURITY_TYPE_ID].line[2] = "Security"; + netperf_output_source[LOCAL_SECURITY_TYPE_ID].line[3] = "Type ID"; + netperf_output_source[LOCAL_SECURITY_TYPE_ID].format = "%d"; + netperf_output_source[LOCAL_SECURITY_TYPE_ID].display_value = &local_security_type_id; + netperf_output_source[LOCAL_SECURITY_TYPE_ID].max_line_len = + NETPERF_LINE_MAX(LOCAL_SECURITY_TYPE_ID); + netperf_output_source[LOCAL_SECURITY_TYPE_ID].tot_line_len = + NETPERF_LINE_TOT(LOCAL_SECURITY_TYPE_ID); + + netperf_output_source[REMOTE_SECURITY_ENABLED].output_name = REMOTE_SECURITY_ENABLED; + netperf_output_source[REMOTE_SECURITY_ENABLED].line[0] = "Remote"; + netperf_output_source[REMOTE_SECURITY_ENABLED].line[1] = "OS"; + netperf_output_source[REMOTE_SECURITY_ENABLED].line[2] = "Security"; + netperf_output_source[REMOTE_SECURITY_ENABLED].line[3] = "Enabled"; + netperf_output_source[REMOTE_SECURITY_ENABLED].format = "%s"; + netperf_output_source[REMOTE_SECURITY_ENABLED].display_value = remote_security_enabled; + netperf_output_source[REMOTE_SECURITY_ENABLED].max_line_len = + NETPERF_LINE_MAX(REMOTE_SECURITY_ENABLED); + netperf_output_source[REMOTE_SECURITY_ENABLED].tot_line_len = + NETPERF_LINE_TOT(REMOTE_SECURITY_ENABLED); + + netperf_output_source[REMOTE_SECURITY_TYPE].output_name = REMOTE_SECURITY_TYPE; + netperf_output_source[REMOTE_SECURITY_TYPE].line[0] = "Remote"; + netperf_output_source[REMOTE_SECURITY_TYPE].line[1] = "OS"; + netperf_output_source[REMOTE_SECURITY_TYPE].line[2] = "Security"; + netperf_output_source[REMOTE_SECURITY_TYPE].line[3] = "Type"; + netperf_output_source[REMOTE_SECURITY_TYPE].format = "%s"; + netperf_output_source[REMOTE_SECURITY_TYPE].display_value = remote_security_type; + netperf_output_source[REMOTE_SECURITY_TYPE].max_line_len = + NETPERF_LINE_MAX(REMOTE_SECURITY_TYPE); + netperf_output_source[REMOTE_SECURITY_TYPE].tot_line_len = + NETPERF_LINE_TOT(REMOTE_SECURITY_TYPE); + + netperf_output_source[REMOTE_SECURITY_SPECIFIC].output_name = REMOTE_SECURITY_SPECIFIC; + netperf_output_source[REMOTE_SECURITY_SPECIFIC].line[0] = "Remote"; + netperf_output_source[REMOTE_SECURITY_SPECIFIC].line[1] = "OS"; + netperf_output_source[REMOTE_SECURITY_SPECIFIC].line[2] = "Security"; + netperf_output_source[REMOTE_SECURITY_SPECIFIC].line[3] = "Specific"; + netperf_output_source[REMOTE_SECURITY_SPECIFIC].format = "%s"; + netperf_output_source[REMOTE_SECURITY_SPECIFIC].display_value = remote_security_specific; + netperf_output_source[REMOTE_SECURITY_SPECIFIC].max_line_len = + NETPERF_LINE_MAX(REMOTE_SECURITY_SPECIFIC); + netperf_output_source[REMOTE_SECURITY_SPECIFIC].tot_line_len = + NETPERF_LINE_TOT(REMOTE_SECURITY_SPECIFIC); + + netperf_output_source[REMOTE_SECURITY_ENABLED_NUM].output_name = REMOTE_SECURITY_ENABLED_NUM; + netperf_output_source[REMOTE_SECURITY_ENABLED_NUM].line[0] = "Remote"; + netperf_output_source[REMOTE_SECURITY_ENABLED_NUM].line[1] = "OS"; + netperf_output_source[REMOTE_SECURITY_ENABLED_NUM].line[2] = "Security"; + netperf_output_source[REMOTE_SECURITY_ENABLED_NUM].line[3] = "Enabled"; + netperf_output_source[REMOTE_SECURITY_ENABLED_NUM].format = "%d"; + netperf_output_source[REMOTE_SECURITY_ENABLED_NUM].display_value = &remote_security_enabled_num; + netperf_output_source[REMOTE_SECURITY_ENABLED_NUM].max_line_len = + NETPERF_LINE_MAX(REMOTE_SECURITY_ENABLED_NUM); + netperf_output_source[REMOTE_SECURITY_ENABLED_NUM].tot_line_len = + NETPERF_LINE_TOT(REMOTE_SECURITY_ENABLED_NUM); + + netperf_output_source[REMOTE_SECURITY_TYPE_ID].output_name = REMOTE_SECURITY_TYPE_ID; + netperf_output_source[REMOTE_SECURITY_TYPE_ID].line[0] = "Remote"; + netperf_output_source[REMOTE_SECURITY_TYPE_ID].line[1] = "OS"; + netperf_output_source[REMOTE_SECURITY_TYPE_ID].line[2] = "Security"; + netperf_output_source[REMOTE_SECURITY_TYPE_ID].line[3] = "Type"; + netperf_output_source[REMOTE_SECURITY_TYPE_ID].format = "%d"; + netperf_output_source[REMOTE_SECURITY_TYPE_ID].display_value = &remote_security_type_id; + netperf_output_source[REMOTE_SECURITY_TYPE_ID].max_line_len = + NETPERF_LINE_MAX(REMOTE_SECURITY_TYPE_ID); + netperf_output_source[REMOTE_SECURITY_TYPE_ID].tot_line_len = + NETPERF_LINE_TOT(REMOTE_SECURITY_TYPE_ID); + + netperf_output_source[LOCAL_INTERVAL_USECS].output_name = LOCAL_INTERVAL_USECS; + netperf_output_source[LOCAL_INTERVAL_USECS].line[0] = "Local"; + netperf_output_source[LOCAL_INTERVAL_USECS].line[1] = "Interval"; + netperf_output_source[LOCAL_INTERVAL_USECS].line[2] = "Usecs"; + netperf_output_source[LOCAL_INTERVAL_USECS].line[3] = ""; + netperf_output_source[LOCAL_INTERVAL_USECS].format = "%d"; + netperf_output_source[LOCAL_INTERVAL_USECS].display_value = &interval_usecs; + netperf_output_source[LOCAL_INTERVAL_USECS].max_line_len = + NETPERF_LINE_MAX(LOCAL_INTERVAL_USECS); + netperf_output_source[LOCAL_INTERVAL_USECS].tot_line_len = + NETPERF_LINE_TOT(LOCAL_INTERVAL_USECS); + + netperf_output_source[LOCAL_INTERVAL_BURST].output_name = LOCAL_INTERVAL_BURST; + netperf_output_source[LOCAL_INTERVAL_BURST].line[0] = "Local"; + netperf_output_source[LOCAL_INTERVAL_BURST].line[1] = "Interval"; + netperf_output_source[LOCAL_INTERVAL_BURST].line[2] = "Burst"; + netperf_output_source[LOCAL_INTERVAL_BURST].line[3] = ""; + netperf_output_source[LOCAL_INTERVAL_BURST].format = "%d"; + netperf_output_source[LOCAL_INTERVAL_BURST].display_value = &interval_burst; + netperf_output_source[LOCAL_INTERVAL_BURST].max_line_len = + NETPERF_LINE_MAX(LOCAL_INTERVAL_BURST); + netperf_output_source[LOCAL_INTERVAL_BURST].tot_line_len = + NETPERF_LINE_TOT(LOCAL_INTERVAL_BURST); + + netperf_output_source[REMOTE_SYSTEM_MODEL].output_name = REMOTE_SYSTEM_MODEL; + netperf_output_source[REMOTE_SYSTEM_MODEL].line[0] = "Remote"; + netperf_output_source[REMOTE_SYSTEM_MODEL].line[1] = "System"; + netperf_output_source[REMOTE_SYSTEM_MODEL].line[2] = "Model"; + netperf_output_source[REMOTE_SYSTEM_MODEL].line[3] = ""; + netperf_output_source[REMOTE_SYSTEM_MODEL].format = "%s"; + netperf_output_source[REMOTE_SYSTEM_MODEL].display_value = remote_system_model; + netperf_output_source[REMOTE_SYSTEM_MODEL].max_line_len = + NETPERF_LINE_MAX(REMOTE_SYSTEM_MODEL); + netperf_output_source[REMOTE_SYSTEM_MODEL].tot_line_len = + NETPERF_LINE_TOT(REMOTE_SYSTEM_MODEL); + + netperf_output_source[REMOTE_CPU_MODEL].output_name = REMOTE_CPU_MODEL; + netperf_output_source[REMOTE_CPU_MODEL].line[0] = "Remote"; + netperf_output_source[REMOTE_CPU_MODEL].line[1] = "CPU"; + netperf_output_source[REMOTE_CPU_MODEL].line[2] = "Model"; + netperf_output_source[REMOTE_CPU_MODEL].line[3] = ""; + netperf_output_source[REMOTE_CPU_MODEL].format = "%s"; + netperf_output_source[REMOTE_CPU_MODEL].display_value = remote_cpu_model; + netperf_output_source[REMOTE_CPU_MODEL].max_line_len = + NETPERF_LINE_MAX(REMOTE_CPU_MODEL); + netperf_output_source[REMOTE_CPU_MODEL].tot_line_len = + NETPERF_LINE_TOT(REMOTE_CPU_MODEL); + + netperf_output_source[REMOTE_CPU_FREQUENCY].output_name = REMOTE_CPU_FREQUENCY; + netperf_output_source[REMOTE_CPU_FREQUENCY].line[0] = "Remote"; + netperf_output_source[REMOTE_CPU_FREQUENCY].line[1] = "CPU"; + netperf_output_source[REMOTE_CPU_FREQUENCY].line[2] = "Frequency"; + netperf_output_source[REMOTE_CPU_FREQUENCY].line[3] = "MHz"; + netperf_output_source[REMOTE_CPU_FREQUENCY].format = "%d"; + netperf_output_source[REMOTE_CPU_FREQUENCY].display_value = &remote_cpu_frequency; + netperf_output_source[REMOTE_CPU_FREQUENCY].max_line_len = + NETPERF_LINE_MAX(REMOTE_CPU_FREQUENCY); + netperf_output_source[REMOTE_CPU_FREQUENCY].tot_line_len = + NETPERF_LINE_TOT(REMOTE_CPU_FREQUENCY); + + netperf_output_source[LOCAL_SYSTEM_MODEL].output_name = LOCAL_SYSTEM_MODEL; + netperf_output_source[LOCAL_SYSTEM_MODEL].line[0] = "Local"; + netperf_output_source[LOCAL_SYSTEM_MODEL].line[1] = "System"; + netperf_output_source[LOCAL_SYSTEM_MODEL].line[2] = "Model"; + netperf_output_source[LOCAL_SYSTEM_MODEL].line[3] = ""; + netperf_output_source[LOCAL_SYSTEM_MODEL].format = "%s"; + netperf_output_source[LOCAL_SYSTEM_MODEL].display_value = local_system_model; + netperf_output_source[LOCAL_SYSTEM_MODEL].max_line_len = + NETPERF_LINE_MAX(LOCAL_SYSTEM_MODEL); + netperf_output_source[LOCAL_SYSTEM_MODEL].tot_line_len = + NETPERF_LINE_TOT(LOCAL_SYSTEM_MODEL); + + netperf_output_source[LOCAL_CPU_MODEL].output_name = LOCAL_CPU_MODEL; + netperf_output_source[LOCAL_CPU_MODEL].line[0] = "Local"; + netperf_output_source[LOCAL_CPU_MODEL].line[1] = "CPU"; + netperf_output_source[LOCAL_CPU_MODEL].line[2] = "Model"; + netperf_output_source[LOCAL_CPU_MODEL].line[3] = ""; + netperf_output_source[LOCAL_CPU_MODEL].format = "%s"; + netperf_output_source[LOCAL_CPU_MODEL].display_value = local_cpu_model; + netperf_output_source[LOCAL_CPU_MODEL].max_line_len = + NETPERF_LINE_MAX(LOCAL_CPU_MODEL); + netperf_output_source[LOCAL_CPU_MODEL].tot_line_len = + NETPERF_LINE_TOT(LOCAL_CPU_MODEL); + + netperf_output_source[LOCAL_CPU_FREQUENCY].output_name = LOCAL_CPU_FREQUENCY; + netperf_output_source[LOCAL_CPU_FREQUENCY].line[0] = "Local"; + netperf_output_source[LOCAL_CPU_FREQUENCY].line[1] = "CPU"; + netperf_output_source[LOCAL_CPU_FREQUENCY].line[2] = "Frequency"; + netperf_output_source[LOCAL_CPU_FREQUENCY].line[3] = "MHz"; + netperf_output_source[LOCAL_CPU_FREQUENCY].format = "%d"; + netperf_output_source[LOCAL_CPU_FREQUENCY].display_value = &local_cpu_frequency; + netperf_output_source[LOCAL_CPU_FREQUENCY].max_line_len = + NETPERF_LINE_MAX(LOCAL_CPU_FREQUENCY); + netperf_output_source[LOCAL_CPU_FREQUENCY].tot_line_len = + NETPERF_LINE_TOT(LOCAL_CPU_FREQUENCY); + + netperf_output_source[OUTPUT_END].output_name = OUTPUT_END; + netperf_output_source[OUTPUT_END].line[0] = "This"; + netperf_output_source[OUTPUT_END].line[1] = "Is"; + netperf_output_source[OUTPUT_END].line[2] = "The"; + netperf_output_source[OUTPUT_END].line[3] = "End"; + netperf_output_source[OUTPUT_END].format = "%s"; + netperf_output_source[OUTPUT_END].display_value = NULL; + netperf_output_source[OUTPUT_END].max_line_len = + NETPERF_LINE_MAX(OUTPUT_END); + netperf_output_source[OUTPUT_END].tot_line_len = + NETPERF_LINE_TOT(OUTPUT_END); + +} +/* lots of boring, repetitive code */ +void +print_omni_init() { + + int i,j; + + if (printing_initialized) return; + + printing_initialized = 1; + + print_omni_init_list(); + + /* belts and suspenders */ + for (i = OUTPUT_NONE; i < NETPERF_OUTPUT_MAX; i++) + output_csv_list[i] = OUTPUT_END; + + for (j = 0; j < NETPERF_MAX_BLOCKS; j++) + for (i = OUTPUT_NONE; i < NETPERF_OUTPUT_MAX; i++) + output_human_list[j][i] = OUTPUT_END; + + + /* the default for csv is the kitchen-sink. ultimately it will be + possible to override by providing one's own list in a file */ + + if ((csv) || (keyword)) { + if (csv_selection_file) + /* name of file, list to fill, number of rows/lines */ + parse_output_csv_selection_file(csv_selection_file); + else + set_output_csv_list_default(output_csv_list); + } + else { + if (human_selection_file) + parse_output_human_selection_file(human_selection_file); + else + set_output_human_list_default(output_human_list); + } + + +} + +/* why? because one cannot simply pass a pointer to snprintf :) for + our nefarious porpoises, we only expect to handle single-value + format statements, not a full-blown format */ +int +my_long_long_snprintf(char *buffer, size_t size, const char *format, void *value) +{ + const char *fmt = format; + while (*fmt) + switch (*fmt++) { + case 'd': + case 'i': + return snprintf(buffer, size, format, *(long long *)value); + case 'u': + case 'o': + case 'x': + case 'X': + return snprintf(buffer, size, format, *(unsigned long long *)value); + } + return -1; +} + +int +my_long_snprintf(char *buffer, size_t size, const char *format, void *value) +{ + const char *fmt = format; + while (*fmt) + switch (*fmt++) { + case 'd': + case 'i': + return snprintf(buffer, size, format, *(long *)value); + case 'u': + case 'o': + case 'x': + case 'X': + return snprintf(buffer, size, format, *(unsigned long *)value); + case 'l': + return my_long_long_snprintf(buffer, size, format, value); + } + return -1; +} + +int +my_snprintf(char *buffer, size_t size, const char *format, void *value) +{ + const char *fmt = format; + + while (*fmt) + switch (*fmt++) { + case 'c': + return snprintf(buffer, size, format, *(int *)value); + case 'f': + case 'e': + case 'E': + case 'g': + case 'G': + return snprintf(buffer, size, format, *(double *)value); + case 's': + return snprintf(buffer, size, format, (char *)value); + case 'd': + case 'i': + return snprintf(buffer, size, format, *(int *)value); + case 'u': + case 'o': + case 'x': + case 'X': + return snprintf(buffer, size, format, *(unsigned int *)value); + case 'l': + return my_long_snprintf(buffer, size, format, value); + } + return -1; +} + +void +print_omni_csv() +{ + + int j,k,buflen,vallen; + + char *hdr1 = NULL; + char *val1 = NULL; + char tmpval[1024]; + + buflen = 0; + for (j = 0; + ((j < NETPERF_OUTPUT_MAX) && + (output_csv_list[j] != OUTPUT_END)); + j++) { + if ((netperf_output_source[output_csv_list[j]].format != NULL) && + (netperf_output_source[output_csv_list[j]].display_value != NULL)) { + vallen = + my_snprintf(tmpval, + 1024, + netperf_output_source[output_csv_list[j]].format, + (netperf_output_source[output_csv_list[j]].display_value)); + if (vallen == -1) { + fprintf(where,"my_snprintf failed on %s with format %s\n", + netperf_output_enum_to_str(j), + netperf_output_source[output_csv_list[j]].format); + fflush(where); + } + vallen += 1; /* forget not the terminator */ + } + else + vallen = 0; + + if (vallen > + netperf_output_source[output_csv_list[j]].tot_line_len) + netperf_output_source[output_csv_list[j]].tot_line_len = vallen; + + buflen += + netperf_output_source[output_csv_list[j]].tot_line_len; + } + + if (print_headers) hdr1 = malloc(buflen + 1); + val1 = malloc(buflen + 1); + + if (((hdr1 == NULL) && (print_headers)) || + (val1 == NULL)) { + fprintf(where,"unable to allocate output buffers\n"); + fflush(where); + exit(-1); + } + + if (print_headers) memset(hdr1,' ',buflen + 1); + memset(val1,' ',buflen + 1); + + /* ostensibly, we now "know" that we have enough space in all our + strings, and we have spaces where we want them etc */ + char *h1 = hdr1; + char *v1 = val1; + for (j = 0; + ((j < NETPERF_OUTPUT_MAX) && + (output_csv_list[j] != OUTPUT_END)); + j++) { + int len; + len = 0; + if (print_headers) { + for (k = 0; ((k < 4) && + (NULL != + netperf_output_source[output_csv_list[j]].line[k]) && + (strcmp("",netperf_output_source[output_csv_list[j]].line[k]))); k++) { + + len = sprintf(h1, + "%s", + netperf_output_source[output_csv_list[j]].line[k]); + *(h1 + len) = ' '; + /* now move to the next starting column. for csv we aren't worried + about alignment between the header and the value lines */ + h1 += len + 1; + } + *(h1 - 1) = ','; + } + if ((netperf_output_source[output_csv_list[j]].format != NULL) && + (netperf_output_source[output_csv_list[j]].display_value != NULL)) { + /* tot_line_len is bogus here, but should be "OK" ? */ + len = my_snprintf(v1, + netperf_output_source[output_csv_list[j]].tot_line_len, + netperf_output_source[output_csv_list[j]].format, + netperf_output_source[output_csv_list[j]].display_value); + + /* nuke the trailing \n" from the string routine. */ + *(v1 + len) = ','; + v1 += len + 1; + } + else { + /* we need a ',' even if there is no value */ + *v1 = ','; + v1 += 2; + } + } + + /* ok, _now_ null terminate each line by nuking the last comma. do + we have an OBOB here? */ + if (print_headers) *(h1-1) = 0; + *(v1-1) = 0; + /* and now spit it out, but only if it is going to have something + in it. we don't want a bunch of blank lines or nulls... */ + if (output_csv_list[0] != OUTPUT_END) { + if (print_headers) printf("%s\n",hdr1); + printf("%s\n",val1); + } + + if (hdr1 != NULL) free(hdr1); + if (val1 != NULL) free(val1); + +} + +void +print_omni_keyword() +{ + /* this one should be the simplest of all - no buffers to allocate, + just spit it all out. raj 20080805 */ + + int j; + char tmpval[1024]; + int vallen; + + for (j = 0; + ((j < NETPERF_OUTPUT_MAX) && + (output_csv_list[j] != OUTPUT_END)); + j++) { + if ((netperf_output_source[output_csv_list[j]].format != NULL) && + (netperf_output_source[output_csv_list[j]].display_value != NULL)) { + vallen = + my_snprintf(tmpval, + 1024, + netperf_output_source[output_csv_list[j]].format, + (netperf_output_source[output_csv_list[j]].display_value)); + if (vallen == -1) { + snprintf(tmpval, + 1024, + "my_snprintf failed with format %s\n", + netperf_output_source[output_csv_list[j]].format); + } + fprintf(where, + "%s=%s\n",netperf_output_enum_to_str(output_csv_list[j]), + tmpval); + } + } + fflush(where); +} + +void +print_omni_human() +{ + + int i,j,k,buflen,buflen_max; + + char *hdr[4]; + char *val1 = NULL; + char tmpval[1024]; /* excessive, but we may have the command line */ + int vallen; + + for (k = 0; k < 4; k ++) { + hdr[k] = NULL; + } + + /* decisions, decisions... walk the list twice to only need to + allocate the charcter buffers once, or walk it once and possibly + reallocate them as I go... oh, lets walk it twice just for fun to + start. since only now do we know that the values are around to be + printed, we should try the snprintf for the value and see how + much space it wants and update max_line_len accordingly */ + buflen_max = 0; + for (i = 0; i < NETPERF_MAX_BLOCKS; i++) { + buflen = 0; + for (j = 0; + ((j < NETPERF_OUTPUT_MAX) && + (output_human_list[i][j] != OUTPUT_END)); + j++) { + if ((netperf_output_source[output_human_list[i][j]].format != NULL) && + (netperf_output_source[output_human_list[i][j]].display_value != NULL)) + vallen = my_snprintf(tmpval, + 1024, + netperf_output_source[output_human_list[i][j]].format, + (netperf_output_source[output_human_list[i][j]].display_value)) + 1; /* need to count the \n */ + else + vallen = 0; + + if (vallen > + netperf_output_source[output_human_list[i][j]].max_line_len) + netperf_output_source[output_human_list[i][j]].max_line_len = vallen; + + buflen += + netperf_output_source[output_human_list[i][j]].max_line_len + 1; + } + + if (buflen > buflen_max) + buflen_max = buflen; + } + + /* more belts and suspenders */ + for (k = 0; (k < 4) && (print_headers); k++) { + hdr[k] = malloc(buflen_max+1); + } + val1 = malloc(buflen_max+1); + + /* we could probably be more succinct here but perhaps the compiler + can figure that out for us :) */ + for (k = 0; (k < 4) && (print_headers); k++) { + if (hdr[k] == NULL) { + fprintf(where,"Unable to allocate output buffers\n"); + fflush(where); + exit(-1); + } + } + + /* ostensibly, we now "know" that we have enough space in all our + strings, and we have spaces where we want them etc */ + for (i = 0; i < NETPERF_MAX_BLOCKS; i++) { + char *h[4]; + char *v1 = val1; + + for (k = 0; k < 4; k++) h[k] = hdr[k]; + + /* we want to blank things out each time since we skip around a lot */ + for (k = 0; (k < 4) && (print_headers); k++) { + memset(hdr[k],' ',buflen_max+1); + } + memset(val1,' ',buflen_max+1); + + + for (j = 0; + ((j < NETPERF_OUTPUT_MAX) && + (output_human_list[i][j] != OUTPUT_END)); + j++) { + if (print_headers) { + for (k = 0; k < 4; k++) { + memcpy(h[k], + netperf_output_source[output_human_list[i][j]].line[k], + strlen(netperf_output_source[output_human_list[i][j]].line[k])); + } + } + if ((netperf_output_source[output_human_list[i][j]].format != NULL) && + (netperf_output_source[output_human_list[i][j]].display_value != NULL)) { + int len; + len = my_snprintf(v1, + netperf_output_source[output_human_list[i][j]].max_line_len, + netperf_output_source[output_human_list[i][j]].format, + netperf_output_source[output_human_list[i][j]].display_value); + /* nuke the trailing \n" from the string routine. */ + *(v1 + len) = ' '; + } + /* now move to the next starting column */ + for (k = 0; (k < 4) && (print_headers); k++) { + h[k] += + netperf_output_source[output_human_list[i][j]].max_line_len + 1; + } + v1 += netperf_output_source[output_human_list[i][j]].max_line_len + 1; + } + /* ok, _now_ null terminate each line. do we have an OBOB here? */ + for (k = 0; (k < 4) && (print_headers); k++) { + *h[k] = 0; + } + *v1 = 0; + /* and now spit it out, but only if it is going to have something + in it. we don't want a bunch of blank lines or nulls... at some + point we might want to work backwards collapsine whitespace from + the right but for now, we won't bother */ + if (output_human_list[i][0] != OUTPUT_END) { + if (i > 0) printf("\n"); /* we want a blank line between blocks ? */ + for (k = 0; (k < 4) && (print_headers); k++) { + printf("%s\n",hdr[k]); + } + printf("%s\n",val1); + } + }; + for (k = 0; k < 4; k++) { + if (hdr[k] != NULL) free(hdr[k]); + } +} + +void +print_omni() +{ + + print_omni_init(); + + if (debug > 2) + dump_netperf_output_source(where); + + if (csv) + print_omni_csv(); + else if (keyword) + print_omni_keyword(); + else + print_omni_human(); + +} +/* for the next few routines (connect, accept, send, recv, + disconnect/close) we will use a return of -1 to mean times up, -2 + to mean a transient error (eg ENOBUFS on a UDP send call) and -3 to + mean hard error. this means it is ok for the connect routine to + return a 0 (zero) if that happens to be the fd/SOCKET we get and in + theory we will be able to support zero-length messages on those + protocols which support it. all in theory of course. raj + 2008-01-09 */ + +int +connect_data_socket(SOCKET send_socket, struct addrinfo *remote_res) +{ + int ret; + + /* Connect up to the remote port on the data socket */ + if ((ret = connect(send_socket, + remote_res->ai_addr, + remote_res->ai_addrlen)) == INVALID_SOCKET) { + if (SOCKET_EINTR(ret)) { + /* we interpret this to mean that the test is supposed to be + over, so return a value of -1 to the caller */ + return -1; + } + if ((SOCKET_EADDRINUSE(ret)) || SOCKET_EADDRNOTAVAIL(ret)) { + /* likely something our explicit bind() would have caught in + the past, so go get another port, via create_data_socket. + yes, this is a bit more overhead than before, but the + condition should be rather rare. we only get a new port if + this was a connection-including test like TCP_CRR or + TCP_CC. Otherwise we need to return an error. raj + 2008-01-08 */ + return -2; + } + else + /* -3 means there was an error */ + return -3; + } + return 0; +} + +int +send_data(SOCKET data_socket, struct ring_elt *send_ring, uint32_t bytes_to_send, struct sockaddr *destination, int destlen) { + + int len; + + /* if the user has supplied a destination, we use sendto, otherwise + we use send. we ass-u-me blocking operations always, so no need + to check for eagain or the like. */ + + if (debug > 1) { + fprintf(where, + "send_data sock %d ring %p bytes %d dest %p len %d\n", + data_socket, + send_ring, + bytes_to_send, + destination, + destlen); + fflush(where); + } + + if (destination) { + len = sendto(data_socket, + send_ring->buffer_ptr, + bytes_to_send, + 0, + destination, + destlen); + } + else { + len = send(data_socket, + send_ring->buffer_ptr, + bytes_to_send, + 0); + } + if(len != bytes_to_send) { + /* don't forget that some platforms may do a partial send upon + receipt of the interrupt and not return an EINTR... */ + if (SOCKET_EINTR(len) || (len >= 0)) + { + /* we hit the end of a timed test. */ + return -1; + } + /* if this is UDP it is possible to receive an ENOBUFS on the send + call and it would not be a fatal error. of course if we were + to return 0 then it would make the test think it was over when + it really wasn't. the question becomes what to do. for the + time being, the answer will likely be to return something like + -2 to indicate a non-fatal error happened on the send and let + the caller figure it out :) we won't actually check to see if + this is UDP - it is the author's experience in many, Many, MANY + years that the only time an ENOBUFS has been returned in a + netperf test has been with UDP. famous last words :) */ + if (errno == ENOBUFS) + return -2; + else { + fprintf(where,"send_data: data send error: errno %d",errno); + return -3; + } + } + return len; +} + +int +recv_data(SOCKET data_socket, struct ring_elt *recv_ring, uint32_t bytes_to_recv, struct sockaddr *source, int *sourcelen, uint32_t flags, uint32_t *num_receives) { + + char *temp_message_ptr; + int bytes_left; + int bytes_recvd; + int my_recvs; + + /* receive data off the data_socket, ass-u-me-ing a blocking socket + all the way!-) 2008-01-08 */ + my_recvs = 0; + bytes_left = bytes_to_recv; + temp_message_ptr = recv_ring->buffer_ptr; + + if (debug > 1) { + fprintf(where, + "recv_data sock %d, elt %p, bytes %d source %p srclen %d, flags %x num_recv %p\n", + data_socket, + recv_ring, + bytes_to_recv, + source, + (source != NULL) ? *sourcelen : -1, + flags, + num_receives); + fflush(where); + } + do { + if (source) { + /* call recvfrom it does look a little silly here inside the do + while, but I think it is ok - a UDP or other DGRAM or + SEQPACKET (?) socket, which should be the only time we + pass-in a source pointer will have a semantic that should get + us out of the dowhile on the first call anyway. if it + turns-out not to be the case, then we can hoist the if above + the do and put the dowhile in the else. */ + bytes_recvd = recvfrom(data_socket, + temp_message_ptr, + bytes_left, + 0, + source, + sourcelen); + } + else { + /* just call recv */ + bytes_recvd = recv(data_socket, + temp_message_ptr, + bytes_left, + 0); + } + if (bytes_recvd > 0) { + bytes_left -= bytes_recvd; + temp_message_ptr += bytes_recvd; + } + else { + break; + } + my_recvs++; + } while ((bytes_left > 0) && (flags & NETPERF_WAITALL)); + + *num_receives = my_recvs; + + /* OK, we are out of the loop - now what? */ + if (bytes_recvd < 0) { + /* did the timer hit, or was there an error? */ + if (SOCKET_EINTR(bytes_recvd)) + { + /* We hit the end of a timed test. */ + return -1; + } + /* it was a hard error */ + return -3; + } + + + /* this looks a little funny, but should be correct. if we had + NETPERF_WAITALL set and we got here, it means we got all the + bytes of the request/response. otherwise we would have hit the + error or end of test cases. if NETPERF_WAITALL isn't set, this + is a STREAM test, and we will have only made one call to recv, so + bytes_recvd will be accurate. */ + if (bytes_left) + return bytes_recvd; + else + return bytes_to_recv; + +} + + +int +close_data_socket(SOCKET data_socket, struct sockaddr *peer, int peerlen) +{ + + int ret; + char buffer[4]; + + if (protocol == IPPROTO_UDP) { + int i; + for (i = 0; i < 3; i++) { + if (peer) + ret = sendto(data_socket, + buffer, + 0, + 0, + peer, + peerlen); + else + ret = send(data_socket, + buffer, + 0, + 0); + if (SOCKET_EINTR(ret)) { + close(data_socket); + return -1; + } + } + } + ret = close(data_socket); + + if (SOCKET_EINTR(ret)) { + /* end of test */ + return -1; + } + else if (ret == 0) { + return ret; + } + else + return -3; + +} + +int +disconnect_data_socket(SOCKET data_socket, int initiate, int do_close, struct sockaddr *peer, int peerlen) +{ + + char buffer[4]; + int bytes_recvd; + + if (debug) { + fprintf(where, + "disconnect_d_s sock %d init %d do_close %d protocol %d\n", + data_socket, + initiate, + do_close, + protocol); + fflush(where); + } + + /* at some point we'll need to abstract this a little. for now, if + the protocol is UDP, we try to send some number of zero-length + datagrams to allow the remote to get out of its loop without + having to wait for the padded timer to expire. if it isn't UDP, + we assume a reliable connection and can do the usual graceful + shutdown thing */ + + if (protocol != IPPROTO_UDP) { + if (initiate) + shutdown(data_socket, SHUT_WR); + + /* we are expecting to get either a return of zero indicating + connection close, or an error. */ + bytes_recvd = recv(data_socket, + buffer, + 1, + 0); + + if (bytes_recvd != 0) { + /* connection close, call close. we assume that the requisite */ + /* number of bytes have been received */ + if (SOCKET_EINTR(bytes_recvd)) + { + /* We hit the end of a timed test. */ + return -1; + } + return -3; + } + } + else { + int i; + for (i = 0; i < 3; i++) { + if (peer) + bytes_recvd = sendto(data_socket, + buffer, + 0, + 0, + peer, + peerlen); + else + bytes_recvd = send(data_socket, + buffer, + 0, + 0); + /* we only really care if the timer expired on us */ + if (SOCKET_EINTR(bytes_recvd)) { + if (do_close) close(data_socket); + return -1; + } + } + } + + if (do_close) + close(data_socket); + + return 0; +} + +static void +get_transport_info(SOCKET socket, int *mss, int protocol) +{ + + netperf_socklen_t sock_opt_len; + int option; + sock_opt_len = sizeof(netperf_socklen_t); + + switch (protocol) { +#if defined(IPPROTO_TCP) && defined(TCP_MAXSEG) + case IPPROTO_TCP: + option = TCP_MAXSEG; + break; +#endif + +#if defined(IPPROTO_SCTP) && defined(SCTP_MAXSEG) + case IPPROTO_SCTP: + option = SCTP_MAXSEG; + break; +#endif + default: + *mss = -1; + return; + } + + if (getsockopt(socket, + protocol, + option, + (char *)mss, + &sock_opt_len) == SOCKET_ERROR) { + fprintf(where, + "netperf: get_transport_info: getsockopt: errno %d\n", + errno); + fflush(where); + *mss = -1; + } +} + +/* brain dead simple way to get netperf to emit a uuid. sadly, by this + point we will have already established the control connection but + those are the breaks. we do _NOT_ include a trailing newline + because we want to be able to use this in a script */ + +void +print_uuid(char remote_host[]) +{ + printf("%s",test_uuid); +} + + /* this code is intended to be "the two routines to run them all" for + BSDish sockets. it comes about as part of a desire to shrink the + code footprint of netperf and to avoid having so many blessed + routines to alter as time goes by. the downside is there will be + more "ifs" than there were before. there may be some other + "complications" for things like demo mode or perhaps histograms if + we ever want to track individual RTTs when burst mode is in use + etc etc... raj 2008-01-07 */ + +void +send_omni(char remote_host[]) +{ + + + int len; + int ret,rret; + int connected = 0; + int timed_out = 0; + int pad_time = 0; + + struct ring_elt *send_ring; + struct ring_elt *recv_ring; + + struct sockaddr_storage remote_addr; + struct sockaddr_storage my_addr; + int remote_addr_len = sizeof(remote_addr); + int my_addr_len = sizeof(my_addr); + + SOCKET data_socket; + int need_socket; + + int temp_recvs; + + struct addrinfo *local_res; + struct addrinfo *remote_res; + + struct omni_request_struct *omni_request; + struct omni_response_struct *omni_response; + struct omni_results_struct *omni_result; + +#ifdef WANT_FIRST_BURST +#define REQUEST_CWND_INITIAL 2 + /* "in the beginning..." the WANT_FIRST_BURST stuff was like both + Unix and the state of New Jersey - both were simple an unspoiled. + then it was realized that some stacks are quite picky about + initial congestion windows and a non-trivial initial burst of + requests would not be individual segments even with TCP_NODELAY + set. so, we have to start tracking a poor-man's congestion window + up here in window space because we want to try to make something + happen that frankly, we cannot guarantee with the specification + of TCP. ain't that grand?-) raj 2006-01-30 */ + int requests_outstanding = 0; + int request_cwnd = REQUEST_CWND_INITIAL; /* we ass-u-me that having + three requests + outstanding at the + beginning of the test + is ok with TCP stacks + of interest. the first + two will come from our + first_burst loop, and + the third from our + regularly scheduled + send */ +#endif + + omni_request = + (struct omni_request_struct *)netperf_request.content.test_specific_data; + omni_response = + (struct omni_response_struct *)netperf_response.content.test_specific_data; + omni_result = + (struct omni_results_struct *)netperf_response.content.test_specific_data; + + + /* before we start doing things with our own requests and responses + lets go ahead and find-out about the remote system. at some point + we probably need to put this somewhere else... */ + get_remote_system_info(); + +#ifdef WANT_HISTOGRAM + if (verbosity > 1) { + time_hist = HIST_new(); + } +#endif /* WANT_HISTOGRAM */ + + /* since we are now disconnected from the code that established the + control socket, and since we want to be able to use different + protocols and such, we are passed the name of the remote host and + must turn that into the test specific addressing information. */ + + complete_addrinfos(&remote_res, + &local_res, + remote_host, + socket_type, + protocol, + 0); + + if ( print_headers ) { + print_top_test_header("OMNI TEST",local_res,remote_res); + } + + /* initialize a few counters */ + + need_socket = 1; + + if (connection_test) + pick_next_port_number(local_res,remote_res); + + + /* If the user has requested cpu utilization measurements, we must */ + /* calibrate the cpu(s). We will perform this task within the tests */ + /* themselves. If the user has specified the cpu rate, then */ + /* calibrate_local_cpu will return rather quickly as it will have */ + /* nothing to do. If local_cpu_rate is zero, then we will go through */ + /* all the "normal" calibration stuff and return the rate back.*/ + + if (local_cpu_usage) { + local_cpu_rate = calibrate_local_cpu(local_cpu_rate); + } + + confidence_iteration = 1; + init_stat(); + + send_ring = NULL; + recv_ring = NULL; + + /* you will keep running the test until you get it right! :) */ + while (((confidence < 0) && (confidence_iteration <= iteration_max)) || + (confidence_iteration <= iteration_min)) { + + trans_completed = 0; + bytes_xferd = 0.0; + remote_bytes_xferd = 0.0; + times_up = 0; + bytes_sent = 0; + bytes_received = 0; + local_send_calls = 0; + local_receive_calls = 0; + +#ifdef WANT_FIRST_BURST + /* we have to remember to reset the number of transactions + outstanding and the "congestion window for each new + iteration. raj 2006-01-31 */ + requests_outstanding = 0; + request_cwnd = REQUEST_CWND_INITIAL; +#endif + + + data_socket = create_data_socket(local_res); + + if (data_socket == INVALID_SOCKET) { + perror("netperf: send_omni: unable to create data socket"); + exit(1); + } + need_socket = 0; + + /* we need to consider if this is a request/response test, if we + are receiving, if we are sending, etc, when setting-up our recv + and send buffer rings. we should only need to do this once, and + that would be when the relevant _ring variable is NULL. raj + 2008-01-18 */ + if ((direction & NETPERF_XMIT) && (NULL == send_ring)) { + if (req_size > 0) { + /* request/response test */ + if (send_width == 0) send_width = 1; + bytes_to_send = req_size; + } + else { + /* stream test */ + if (send_size == 0) { + if (lss_size > 0) { + send_size = lss_size; + } + else { + send_size = 4096; + } + } + if (send_width == 0) + send_width = (lss_size/send_size) + 1; + if (send_width == 1) send_width++; + bytes_to_send = send_size; + } + + send_ring = allocate_buffer_ring(send_width, + bytes_to_send, + local_send_align, + local_send_offset); + if (debug) { + fprintf(where, + "send_omni: %d entry send_ring obtained...\n", + send_width); + } + } + + if ((direction & NETPERF_RECV) && (NULL == recv_ring)) { + if (rsp_size > 0) { + if (recv_width == 0) recv_width = 1; + bytes_to_recv = rsp_size; + } + else { + /* stream test */ + if (recv_size == 0) { + if (lsr_size > 0) { + recv_size = lsr_size; + } + else { + recv_size = 4096; + } + } + if (recv_width == 0) { + recv_width = (lsr_size/recv_size) + 1; + if (recv_width == 1) recv_width++; + } + bytes_to_recv = recv_size; + } + + recv_ring = allocate_buffer_ring(recv_width, + bytes_to_recv, + local_recv_align, + local_recv_offset); + if (debug) { + fprintf(where, + "send_omni: %d entry recv_ring obtained...\n", + recv_width); + } + } + + if (!no_control) { /* foo */ + + /* Tell the remote end to do a listen or otherwise prepare for + what is to come. The server alters the socket paramters on the + other side at this point, hence the reason for all the values + being passed in the setup message. If the user did not specify + any of the parameters, they will be passed as values which will + indicate to the remote that no changes beyond the system's + default should be used. Alignment is the exception, it will + default to 8, which will probably be no alignment + alterations. */ + + netperf_request.content.request_type = DO_OMNI; + omni_request->send_buf_size = rss_size_req; + omni_request->send_size = remote_send_size_req; + omni_request->send_alignment = remote_send_align; + omni_request->send_offset = remote_send_offset; + omni_request->send_width = 1; /* FIX THIS */ + omni_request->request_size = req_size; + + omni_request->recv_buf_size = rsr_size_req; + omni_request->receive_size = remote_recv_size_req; + omni_request->recv_alignment = remote_recv_align; + omni_request->recv_offset = remote_recv_offset; + omni_request->recv_width = 1; /* FIX THIS */ + omni_request->response_size = rsp_size; + + omni_request->no_delay = rem_nodelay; + omni_request->use_sendfile = remote_use_sendfile; + omni_request->connect_test = connection_test; + + omni_request->measure_cpu = remote_cpu_usage; + omni_request->cpu_rate = remote_cpu_rate; + if (test_time) + omni_request->test_length = test_time; + else + omni_request->test_length = test_trans * -1; + omni_request->so_rcvavoid = rem_rcvavoid; + omni_request->so_sndavoid = rem_sndavoid; + omni_request->send_dirty_count = rem_dirty_count; + omni_request->recv_dirty_count = rem_dirty_count; + omni_request->recv_clean_count = rem_clean_count; + + omni_request->checksum_off = remote_checksum_off; + omni_request->data_port = atoi(remote_data_port); + omni_request->ipfamily = af_to_nf(remote_res->ai_family); + omni_request->socket_type = hst_to_nst(socket_type); + omni_request->protocol = protocol; + + omni_request->interval_burst = remote_interval_burst; + omni_request->interval_usecs = remote_interval_usecs; + + omni_request->direction = 0; + /* yes, the sense here is correct - if we are transmitting, they + receive, if we are receiving, they are transmitting... */ + if (direction & NETPERF_XMIT) + omni_request->direction |= NETPERF_RECV; + if (direction & NETPERF_RECV) + omni_request->direction |= NETPERF_XMIT; + + /* some tests may require knowledge of our local addressing. such + tests will for the time being require that the user specify a + local IP/name so we can extract them from the data_socket. */ + getsockname(data_socket, (struct sockaddr *)&my_addr, &my_addr_len); + ret = get_sockaddr_family_addr_port(&my_addr, + nf_to_af(omni_request->ipfamily), + omni_request->ipaddr, + &(omni_request->netperf_port)); + + if (debug > 1) { + fprintf(where,"netperf: send_omni: requesting OMNI test\n"); + } + + + send_request(); + + + /* the response from the remote should contain all the relevant + socket and other parameters we need to know for this test. + so, we can shove them back into the relevant variables here + and be on our way. */ + + recv_response_n(OMNI_RESPONSE_CONV_CUTOFF); /* brittle, but functional */ + + if (!netperf_response.content.serv_errno) { + rsr_size = omni_response->recv_buf_size; + remote_recv_size = omni_response->receive_size; + rss_size = omni_response->send_buf_size; + remote_send_size = omni_response->send_size; + rem_nodelay = omni_response->no_delay; + remote_use_sendfile = omni_response->use_sendfile; + remote_cpu_usage = omni_response->measure_cpu; + remote_cpu_rate = omni_response->cpu_rate; + remote_send_width = omni_response->send_width; + remote_recv_width = omni_response->recv_width; + /* make sure that port numbers are in network order because + recv_response will have put everything into host order */ + set_port_number(remote_res, + (unsigned short)omni_response->data_port); + + if (debug) { + fprintf(where,"remote listen done.\n"); + fprintf(where,"remote port is %u\n",get_port_number(remote_res)); + fflush(where); + } + /* just in case the remote didn't null terminate */ + if (NULL == remote_system_model) { + omni_response->system_model[sizeof(omni_response->system_model)-1] = 0; + remote_system_model = strdup(omni_response->system_model); + } + if (NULL == remote_cpu_model) { + omni_response->cpu_model[sizeof(omni_response->cpu_model) -1 ] = 0; + remote_cpu_model = strdup(omni_response->cpu_model); + } + remote_cpu_frequency = omni_response->cpu_frequency; + + if (NULL == remote_security_specific) { + omni_response->security_string[sizeof(omni_response->security_string) - 1] = 0; + remote_security_specific = strdup(omni_response->security_string); + } + /* top bits type, bottom bits enabled */ + remote_security_type_id = (int) omni_response->security_info >> 16; + remote_security_enabled_num = (short)omni_response->security_info; + remote_security_type = nsec_type_to_str(remote_security_type_id); + remote_security_enabled = + nsec_enabled_to_str(remote_security_enabled_num); + } + else { + Set_errno(netperf_response.content.serv_errno); + fprintf(where, + "netperf: remote error %d", + netperf_response.content.serv_errno); + perror(""); + fflush(where); + exit(1); + } + + } + else { + if (NULL == remote_system_model) + remote_system_model = strdup("Unknown System Model"); + if (NULL == remote_cpu_model) + remote_cpu_model = strdup("Unknown CPU Model"); + remote_cpu_frequency = -1; + } + +#ifdef WANT_DEMO + /* at some point we will have to be more clever about this, but + for now we won't */ + + DEMO_RR_SETUP(100); +#endif + + /* if we are not a connectionless protocol, we need to connect. at + some point even if we are a connectionless protocol, we may + still want to "connect" for convenience raj 2008-01-14 */ + need_to_connect = (protocol != IPPROTO_UDP); + + /* Set-up the test end conditions. For tests over a + "reliable/connection-oriented" transport (eg TCP, SCTP, etc) this + can be either time or byte/transaction count based. for + unreliable transport or connection tests it can only be time + based. having said that, we rely entirely on other code to + enforce this before we even get here. raj 2008-01-08 */ + + if (test_time) { + /* The user wanted to end the test after a period of time. if + we are a recv-only test, we need to protect ourself against + the remote going poof, but we want to make sure we don't + give-up before they finish, so we will add a PAD_TIME to the + timer. if we are RR or XMIT, there should be no need for + padding */ + times_up = 0; + units_remaining = 0; + if ((!no_control) && (NETPERF_RECV_ONLY(direction))) + pad_time = PAD_TIME; + start_timer(test_time + pad_time); + } + else { + /* The tester wanted to send a number of bytes or exchange a + number of transactions. */ + if (NETPERF_IS_RR(direction)) + units_remaining = test_trans; + else + units_remaining = test_bytes; + times_up = 1; + } + + /* grab the current time, and if necessary any starting information + for the gathering of CPU utilization at this end. */ + cpu_start(local_cpu_usage); + +#if defined(WANT_INTERVALS) + INTERVALS_INIT(); +#endif /* WANT_INTERVALS */ + +#ifdef WANT_DEMO + if (demo_mode) { + HIST_timestamp(demo_one_ptr); + } +#endif + + /* the "OR" here allows us to control test length by either + byte/transaction count or by timer. when the test is + byte/transaction count based the time test will always evaluate + false. when the test is controlled by time, the byte/transaction + count will always evaluate to false. when the test is finished + the whole expression will go false and we will stop sending + data. at least that is the plan :) raj 2008-01-08 */ + + while ((!times_up) || (units_remaining > 0)) { + +#ifdef WANT_HISTOGRAM + /* only pull the timestamp if we are actually going to use the + results of the work. we put the call here so it can work for + any sort of test - connection, request/response, or stream. + no, it isn't "perfect" for all of them - for some it will + include a few more "if's" than a purpose-written routine, but + it _should_ be the case that the time spent up here is + epsilon compared to time spent elsewhere in the stack so it + should not be a big deal. famous last words of raj + 2008-01-08 */ + if (verbosity > 1) { + HIST_timestamp(&time_one); + } +#endif /* WANT_HISTOGRAM */ + + again: + + if (need_socket) { + if (connection_test) + pick_next_port_number(local_res,remote_res); + + data_socket = create_data_socket(local_res); + + if (data_socket == INVALID_SOCKET) { + perror("netperf: send_omni: unable to create data socket"); + exit(1); + } + need_socket = 0; + } + + /* only connect if and when we need to */ + if (need_to_connect) { + /* assign to data_socket since connect_data_socket returns + SOCKET and not int thanks to Windows. */ + ret = connect_data_socket(data_socket,remote_res); + if (ret == 0) { + connected = 1; + need_to_connect = 0; + } + else if (ret == -1) { + times_up = 1; + timed_out = 1; + break; + } + else if ((ret == -2) && connection_test) { + /* transient error on a connection test means go around and + try again with another local port number */ + fprintf(where,"transient! transient! torpedo in the water!\n"); + fflush(where); + close(data_socket); + connected = 0; /* probably redundant but what the heck... */ + need_socket = 1; + need_to_connect = 1; + /* this will stuff the next local port number within bounds + into our local res, and then when the goto has us + allocating a new socket it will do the right thing with the + bind() call */ + pick_next_port_number(local_res,remote_res); + goto again; + } + else { + /* either this was a hard failure (-3) or a soft failure on + something other than a connection test */ + perror("netperf: send_omni: connect_data_socket failed"); + exit(1); + } + } + +#ifdef WANT_FIRST_BURST + /* we can inject no more than request_cwnd, which will grow with + time, and no more than first_burst_size. we don't use <= to + account for the "regularly scheduled" send call. of course + that makes it more a "max_outstanding_ than a + "first_burst_size" but for now we won't fix the names. also, + I suspect the extra check against < first_burst_size is + redundant since later I expect to make sure that request_cwnd + can never get larger than first_burst_size, but just at the + moment I'm feeling like a belt and suspenders kind of + programmer. raj 2006-01-30 */ + /* we only want to inject the burst if this is a full-on + request/response test. otherwise it doesn't make any sense + anyway. raj 2008-01-25 */ + while ((first_burst_size > 0) && + (requests_outstanding < request_cwnd) && + (requests_outstanding < first_burst_size) && + (NETPERF_IS_RR(direction)) && + (!connection_test)) { + if (debug) { + fprintf(where, + "injecting, req_outstanding %d req_cwnd %d burst %d\n", + requests_outstanding, + request_cwnd, + first_burst_size); + } + if ((ret = send_data(data_socket, + send_ring, + bytes_to_send, + (connected) ? NULL : remote_res->ai_addr, + remote_res->ai_addrlen)) != bytes_to_send) { + /* in theory, we should never hit the end of the test in the + first burst */ + perror("send_omni: initial burst data send error"); + exit(-1); + } + local_send_calls += 1; + requests_outstanding += 1; + } + +#endif /* WANT_FIRST_BURST */ + + /* if we should try to send something, then by all means, let us + try to send something. */ + if (direction & NETPERF_XMIT) { + ret = send_data(data_socket, + send_ring, + bytes_to_send, + (connected) ? NULL : remote_res->ai_addr, + /* if the destination above is NULL, this is ignored */ + remote_res->ai_addrlen); + /* the order of these if's will seem a triffle strange, but they + are my best guess as to order of probabilty and/or importance + to the overhead raj 2008-01-09*/ + if (ret == bytes_to_send) { + /* if this is a send-only test controlled by byte count we + decrement units_remaining by the bytes sent */ + if (!(direction & NETPERF_RECV) && (units_remaining > 0)) { + units_remaining -= ret; + } + bytes_sent += ret; + send_ring = send_ring->next; + local_send_calls++; + } + else if (ret == -2) { + /* what to do here -2 means a non-fatal error - probably + ENOBUFS and so our send didn't happen. in the old code for + UDP_STREAM we would just continue in the while loop. it + isn't clear that is what to do here, so we will simply + increment the failed_sends stat and fall-through. If this + is a UDP_STREAM style of test, the net effect should be the + same. if this is a UDP_RR with a really-big burst count, I + don't think we were checking for ENOBUFS there anyway and + so would have failed. Here we can just let things + slide. */ + failed_sends++; + } + else if (ret == 0) { + /* was this a zero-byte send? if it was, then ostensibly we + would hit the ret == bytes_to_send case which means we'd + never get here as we are using blocking semantics */ + fprintf(where,"HOW DID I GET HERE?\n"); + fflush(where); + } + else if (ret == -1) { + times_up = 1; + timed_out = 1; + break; + } + else { + perror("netperf: send_omni: send_data failed"); + exit(1); + } + + } + +#ifdef WANT_FIRST_BURST + /* it isn't clear we need to check the directions here. the + increment should be cheaper than the conditional, and it + shouldn't hurt the other directions because they'll never + look at them. famous last words of raj 2008-01-25 */ + requests_outstanding += 1; +#endif + + if (direction & NETPERF_RECV) { + rret = recv_data(data_socket, + recv_ring, + bytes_to_recv, + (connected) ? NULL : (struct sockaddr *)&remote_addr, + /* if remote_addr NULL this is ignored */ + &remote_addr_len, + /* if XMIT also set this is RR so waitall */ + (direction & NETPERF_XMIT) ? NETPERF_WAITALL: 0, + &temp_recvs); + if (rret > 0) { + /* if this is a recv-only test controlled by byte count we + decrement the units_remaining by the bytes received */ + if (!(direction & NETPERF_XMIT) && (units_remaining > 0)) { + units_remaining -= rret; + } + bytes_received += rret; + local_receive_calls += temp_recvs; + } + else if (rret == 0) { + /* is this the end of a test, just a zero-byte recv, or + something else? that is an exceedingly good question and + one for which I don't presently have a good answer, but + that won't stop me from guessing :) raj 2008-01-09 */ + if (!((connection_test) || (null_message_ok))) { + /* if it is neither a connection_test nor null_message_ok it + must be the end of the test */ + times_up = 1; /* ostensibly the signal handler did this */ + break; + } + local_receive_calls += temp_recvs; + } + else if (rret == -1) { + /* test timed-out */ + times_up = 1; + timed_out = 1; + break; + } + else { + /* presently at least, -2 and -3 are equally bad on recv */ + perror("netperf: send_omni: recv_data failed"); + exit(1); + } + recv_ring = recv_ring->next; + +#ifdef WANT_FIRST_BURST + /* so, since we've gotten a response back, update the + bookkeeping accordingly. there is one less request + outstanding and we can put one more out there than before. */ + requests_outstanding -= 1; + if ((request_cwnd < first_burst_size) && + (NETPERF_IS_RR(direction))) { + request_cwnd += 1; + if (debug) { + fprintf(where, + "incr req_cwnd to %d first_burst %d reqs_outstndng %d\n", + request_cwnd, + first_burst_size, + requests_outstanding); + } + } +#endif + + } + + /* if this is a connection test, we want to do some stuff about + connection close here in the test loop. raj 2008-01-08 */ + if (connection_test) { + +#ifdef __linux + /* so, "Linux" with autotuning likes to alter the socket buffer + sizes over the life of the connection, but only does so when + one takes the defaults at time of socket creation. if we + took those defaults, we should inquire as to what the values + ultimately became. raj 2008-01-15 */ + if (lsr_size_req < 0) + get_sock_buffer(data_socket, RECV_BUFFER, &lsr_size_end); + else + lsr_size_end = lsr_size; + if (lss_size_req < 0) + get_sock_buffer(data_socket, SEND_BUFFER, &lss_size_end); + else + lss_size_end = lss_size; +#else + lsr_size_end = lsr_size; + lss_size_end = lss_size; +#endif + + /* we will only make this call the one time - after the first + call, the value will be real or -1. if this is a connection + test we want to do this here because later we won't be + connected and the data may no longer be available */ + if (transport_mss == -2) + get_transport_info(data_socket, + &transport_mss, + local_res->ai_protocol); + + + ret = disconnect_data_socket(data_socket, + (no_control) ? 1 : 0, + 1, + NULL, + 0); + if (ret == 0) { + /* we will need a new connection to be established next time + around the loop */ + need_to_connect = 1; + connected = 0; + need_socket = 1; + pick_next_port_number(local_res,remote_res); + } + else if (ret == -1) { + times_up = 1; + timed_out = 1; + break; + } + else { + perror("netperf: send_omni: disconnect_data_socket failed"); + exit(1); + } + } + + +#ifdef WANT_HISTOGRAM + if (verbosity > 1) { + HIST_timestamp(&time_two); + HIST_add(time_hist,delta_micro(&time_one,&time_two)); + } +#endif /* WANT_HISTOGRAM */ + +#ifdef WANT_DEMO + if (NETPERF_IS_RR(direction)) { + DEMO_INTERVAL(1); + } + else if (NETPERF_XMIT_ONLY(direction)) { + DEMO_INTERVAL(bytes_to_send); + } + else { + DEMO_INTERVAL(rret); + } +#endif + +#if defined(WANT_INTERVALS) + INTERVALS_WAIT(); +#endif /* WANT_INTERVALS */ + + + /* was this a "transaction" test? */ + if (NETPERF_IS_RR(direction)) { + trans_completed++; + if (units_remaining) { + units_remaining--; + } + } + + + } + + /* we are now, ostensibly, at the end of this iteration */ + + if (transport_mss == -2) + get_transport_info(data_socket, + &transport_mss, + local_res->ai_protocol); + + + find_security_info(&local_security_enabled_num, + &local_security_type_id, + &local_security_specific); + local_security_enabled = nsec_enabled_to_str(local_security_enabled_num); + local_security_type = nsec_type_to_str(local_security_type_id); + + /* so, if we have/had a data connection, we will want to close it + now, and this will be independent of whether there is a control + connection. */ + + if (connected) { + +#ifdef __linux + /* so, "Linux" with autotuning likes to alter the socket buffer + sizes over the life of the connection, but only does so when + one takes the defaults at time of socket creation. if we took + those defaults, we should inquire as to what the values + ultimately became. raj 2008-01-15 */ + if (lsr_size_req < 0) + get_sock_buffer(data_socket, RECV_BUFFER, &lsr_size_end); + else + lsr_size_end = lsr_size; + if (lss_size_req < 0) + get_sock_buffer(data_socket, SEND_BUFFER, &lss_size_end); + else + lss_size_end = lss_size; +#else + lsr_size_end = lsr_size; + lss_size_end = lss_size; +#endif + /* CHECK PARMS HERE; */ + ret = disconnect_data_socket(data_socket, + 1, + 1, + NULL, + 0); + connected = 0; + need_socket = 1; + + } + else { + /* this is the UDP case at present */ + ret = disconnect_data_socket(data_socket, + 1, + 1, + remote_res->ai_addr, + remote_res->ai_addrlen); + need_socket = 1; + lsr_size_end = lsr_size; + lss_size_end = lss_size; + } + + /* this call will always give us the elapsed time for the test, and + will also store-away the necessaries for cpu utilization */ + + cpu_stop(local_cpu_usage,&elapsed_time); + + find_system_info(&local_system_model, + &local_cpu_model, + &local_cpu_frequency); + + local_interface_name = + find_egress_interface(local_res->ai_addr,remote_res->ai_addr); + + find_driver_info(local_interface_name,local_driver_name,local_driver_version,local_driver_firmware,local_driver_bus,32); + + local_interface_slot = find_interface_slot(local_interface_name); + + find_interface_ids(local_interface_name, + &local_interface_vendor, + &local_interface_device, + &local_interface_subvendor, + &local_interface_subdevice); + + /* if we timed-out, and had padded the timer, we need to subtract + the pad_time from the elapsed time on the assumption that we + were essentially idle for pad_time and just waiting for a timer + to expire on something like a UDP test. if we have not padded + the timer, pad_time will be zero. if we have not timed out + then we want to make sure we stop the timer. */ + if (timed_out) { + if (debug) { + fprintf(where,"Adjusting elapsed_time by %d seconds\n",pad_time); + fflush(where); + } + elapsed_time -= (float)pad_time; + } + else { + stop_timer(); + } + + if (!no_control) { + /* Get the statistics from the remote end. The remote will have + calculated service demand and all those interesting things. If + it wasn't supposed to care, it will return obvious values. */ + + recv_response_n(OMNI_RESULTS_CONF_CUTOFF); + if (!netperf_response.content.serv_errno) { + if (debug) + fprintf(where,"remote results obtained\n"); + remote_cpu_method = format_cpu_method(omni_result->cpu_method); + /* why? because some stacks want to be clever and autotune their + socket buffer sizes, which means that if we accept the defaults, + the size we get from getsockopt() at the beginning of a + connection may not be what we would get at the end of the + connection... */ + lib_num_rem_cpus = omni_result->num_cpus; + lib_remote_peak_cpu_util = (double)omni_result->peak_cpu_util; + lib_remote_peak_cpu_id = omni_result->peak_cpu_id; + rsr_size_end = omni_result->recv_buf_size; + rss_size_end = omni_result->send_buf_size; + remote_bytes_sent = (uint64_t)omni_result->bytes_sent_hi << 32; + remote_bytes_sent += omni_result->bytes_sent_lo; + remote_send_calls = omni_result->send_calls; + remote_bytes_received = (uint64_t)omni_result->bytes_received_hi << 32; + remote_bytes_received += omni_result->bytes_received_lo; + remote_receive_calls = omni_result->recv_calls; + remote_bytes_xferd = remote_bytes_received + remote_bytes_sent; + if (omni_result->recv_calls > 0) + remote_bytes_per_recv = (double) remote_bytes_received / + (double) omni_result->recv_calls; + else + remote_bytes_per_recv = 0.0; + if (omni_result->send_calls > 0) + remote_bytes_per_send = (double) remote_bytes_sent / + (double) omni_result->send_calls; + else + remote_bytes_per_send = 0.0; + omni_result->ifname[15] = 0; /* belt and suspenders */ + remote_interface_name = strdup(omni_result->ifname); + remote_interface_slot = strdup(omni_result->ifslot); + strncpy(remote_driver_name,omni_result->driver,32); + strncpy(remote_driver_version,omni_result->version,32); + strncpy(remote_driver_firmware,omni_result->firmware,32); + strncpy(remote_driver_bus,omni_result->bus,32); + remote_driver_name[31] = 0; + remote_driver_version[31] = 0; + remote_driver_firmware[31] = 0; + remote_driver_bus[31] = 0; + remote_interface_vendor = omni_result->vendor; + remote_interface_device = omni_result->device; + remote_interface_subvendor = omni_result->subvendor; + remote_interface_subdevice = omni_result->subdevice; + } + else { + Set_errno(netperf_response.content.serv_errno); + fprintf(where, + "netperf: remote error %d", + netperf_response.content.serv_errno); + perror(""); + fflush(where); + + exit(1); + } + } + + /* so, what was the end result? */ + local_cpu_method = format_cpu_method(cpu_method); + + if (local_send_calls > 0) + bytes_per_send = (double) bytes_sent / (double) local_send_calls; + else bytes_per_send = 0.0; + + if (local_receive_calls > 0) + bytes_per_recv = (double) bytes_received / (double) local_receive_calls; + else + bytes_per_recv = 0.0; + + bytes_xferd = bytes_sent + bytes_received; + + /* if the output format is 'x' we know the test was + request/response. if the libfmt is something else, it could be + xmit, recv or bidirectional. if we were the receiver then we + can use our byte totals even if it is + UDP/unreliable. otherwise, we use the remote totals - they + should be the same if the protocol is reliable, and if it is + unreliable then we want what was actually received */ + if ('x' == libfmt) + /* it was a request/response test */ + thruput = calc_thruput(trans_completed); + else if (NETPERF_RECV_ONLY(direction)) + thruput = calc_thruput(bytes_xferd); + else + thruput = calc_thruput(remote_bytes_xferd); + + if (NETPERF_IS_RR(direction)) { + char tmpfmt; + if (!connection_test) { + /* calculate the round trip latency, using the transaction rate + whether or not the user was asking for thruput to be in 'x' + units please... however... a connection_test only ever has + one transaction in flight at one time */ + rtt_latency = + (((double)1.0/(trans_completed/elapsed_time)) * (double)1000000.0) * + (double) (1 + ((first_burst_size > 0) ? first_burst_size : 0)); + } + else + rtt_latency = + ((double)1.0/(trans_completed/elapsed_time)) * (double)1000000.0; + tmpfmt = libfmt; + libfmt = 'x'; + transaction_rate = calc_thruput(trans_completed); + libfmt = tmpfmt; + } + + /* ok, time to possibly calculate cpu util and/or service demand */ + if (local_cpu_usage) { + + local_cpu_utilization = calc_cpu_util(elapsed_time); + + /* we need to decide what to feed the service demand beast, + which will, ultimately, depend on what sort of test it is and + whether or not the user asked for something specific - as in + per KB even on a TCP_RR test if it is being (ab)used as a + bidirectional bulk-transfer test. raj 2008-01-14 */ + local_service_demand = + calc_service_demand_fmt(('x' == libfmt) ? (double)trans_completed: bytes_xferd, + 0.0, + 0.0, + 0); + } + else { + local_cpu_utilization = (float) -1.0; + local_service_demand = (float) -1.0; + } + + if (remote_cpu_usage) { + + remote_cpu_utilization = omni_result->cpu_util; + + /* since calc_service demand is doing ms/Kunit we will */ + /* multiply the number of transaction by 1024 to get */ + /* "good" numbers */ + remote_service_demand = + calc_service_demand_fmt(('x' == libfmt) ? (double) trans_completed: bytes_xferd, + 0.0, + remote_cpu_utilization, + omni_result->num_cpus); + } + else { + remote_cpu_utilization = (float) -1.0; + remote_service_demand = (float) -1.0; + } + + /* time to calculate our confidence */ + calculate_confidence(confidence_iteration, + elapsed_time, + thruput, + local_cpu_utilization, + remote_cpu_utilization, + local_service_demand, + remote_service_demand); + + /* this this is the end of the confidence while loop? */ + confidence_iteration++; + } + + /* we end with confidence_iteration one larger than the number of + iterations. if we weren't doing confidence intervals this will + still be reported as one */ + confidence_iteration--; + + /* at some point we may want to actually display some results :) */ + + retrieve_confident_values(&elapsed_time, + &thruput, + &local_cpu_utilization, + &remote_cpu_utilization, + &local_service_demand, + &remote_service_demand); + + /* a kludge for omni printing because I don't know how to tell that + something is a float vs a double in my_snprintf() given what it + is passed and I'm not ready to force all the netlib.c stuff to + use doubles rather than floats. help there would be + appreciated. raj 2008-01-28 */ + elapsed_time_double = (double) elapsed_time; + local_cpu_utilization_double = (double)local_cpu_utilization; + local_service_demand_double = (double)local_service_demand; + remote_cpu_utilization_double = (double)remote_cpu_utilization; + remote_service_demand_double = (double)remote_service_demand; + + if ('x' == libfmt) sd_str = "usec/Tran"; + else sd_str = "usec/KB"; + + if (iteration_max > 1) { + result_confid_pct = get_result_confid(); + loc_cpu_confid_pct = get_loc_cpu_confid(); + rem_cpu_confid_pct = get_rem_cpu_confid(); + interval_pct = interval * 100.0; + } + + /* at some point we need to average these during a confidence + interval run, and when we do do that, we need to make sure we + restore the value of libfmt correctly */ + if ('x' == libfmt) libfmt = 'm'; + local_send_thruput = calc_thruput(bytes_sent); + local_recv_thruput = calc_thruput(bytes_received); + remote_send_thruput = calc_thruput(remote_bytes_sent); + remote_recv_thruput = calc_thruput(remote_bytes_received); + + print_omni(); + +#if defined(DEBUG_OMNI_OUTPUT) + { + /* just something quick to sanity check the output selectors. this + should be gone for "production" :) */ + int i; + print_omni_init(); + output_csv_list[1] = OUTPUT_END; + for (i = OUTPUT_NONE; i < NETPERF_OUTPUT_MAX; i++) { + output_csv_list[0] = i; + print_omni_csv(); + } + } +#endif + + /* likely as not we are going to do something slightly different here */ + if (verbosity > 1) { + +#ifdef WANT_HISTOGRAM + fprintf(where,"\nHistogram of "); + if (NETPERF_RECV_ONLY(direction)) + fprintf(where,"recv"); + if (NETPERF_XMIT_ONLY(direction)) + fprintf(where,"send"); + if (NETPERF_IS_RR(direction)) { + if (connection_test) { + if (NETPERF_CC(direction)) { + fprintf(where,"connect/close"); + } + else { + fprintf(where,"connect/request/response/close"); + } + } + else { + fprintf(where,"request/response"); + } + } + fprintf(where," times\n"); + fflush(where); + HIST_report(time_hist); +#endif /* WANT_HISTOGRAM */ + + } + +} + + + +/* the name is something of a misnomer since this test could send, or + receive, or both, but it matches the historical netperf routine + naming. */ +void +recv_omni() +{ + + char *message; + struct addrinfo *local_res; + char local_name[BUFSIZ]; + char port_buffer[PORTBUFSIZE]; + + struct sockaddr_storage myaddr_in, peeraddr_in; + SOCKET s_listen, data_socket; + netperf_socklen_t addrlen; + + struct ring_elt *send_ring; + struct ring_elt *recv_ring; + + int timed_out = 0; + int pad_time = 0; + int need_to_connect; + int need_to_accept; + int connected; + int ret; + int temp_recvs; + + struct omni_request_struct *omni_request; + struct omni_response_struct *omni_response; + struct omni_results_struct *omni_results; + + omni_request = + (struct omni_request_struct *)netperf_request.content.test_specific_data; + omni_response = + (struct omni_response_struct *)netperf_response.content.test_specific_data; + omni_results = + (struct omni_results_struct *)netperf_response.content.test_specific_data; + + if (debug) { + fprintf(where,"netserver: recv_omni: entered...\n"); + fflush(where); + } + + /* based on what we have been told by the remote netperf, we want to + setup our endpoint for the "data connection" and let the remote + netperf know the situation. */ + + if (debug) { + fprintf(where,"recv_omni: setting the response type...\n"); + fflush(where); + } + + netperf_response.content.response_type = OMNI_RESPONSE; + + if (debug) { + fprintf(where,"recv_omni: the response type is set...\n"); + fflush(where); + } + + /* Grab a socket to listen on, and then listen on it. */ + + if (debug) { + fprintf(where,"recv_omni: grabbing a socket...\n"); + fflush(where); + } + + /* create_data_socket expects to find some things in the global + variables, so set the globals based on the values in the request. + once the socket has been created, we will set the response values + based on the updated value of those globals. raj 7/94 */ + lss_size_req = omni_request->send_buf_size; + lsr_size_req = omni_request->recv_buf_size; + loc_nodelay = omni_request->no_delay; + loc_rcvavoid = omni_request->so_rcvavoid; + loc_sndavoid = omni_request->so_sndavoid; + +#ifdef WANT_INTERVALS + interval_usecs = omni_request->interval_usecs; + interval_wate = interval_usecs / 1000; + interval_burst = omni_request->interval_burst; +#else + interval_usecs = 0; + interval_wate = 1; + interval_burst = 0; +#endif + + connection_test = omni_request->connect_test; + direction = omni_request->direction; + + set_hostname_and_port(local_name, + port_buffer, + nf_to_af(omni_request->ipfamily), + omni_request->data_port); + + local_res = complete_addrinfo(local_name, + local_name, + port_buffer, + nf_to_af(omni_request->ipfamily), + nst_to_hst(omni_request->socket_type), + omni_request->protocol, + 0); + + s_listen = create_data_socket(local_res); + + if (s_listen == INVALID_SOCKET) { + netperf_response.content.serv_errno = errno; + send_response(); + if (debug) { + fprintf(where,"could not create data socket\n"); + fflush(where); + } + exit(1); + } + + /* We now alter the message_ptr variables to be at the desired */ + /* alignments with the desired offsets. */ + + if (debug) { + fprintf(where, + "recv_omni: requested recv alignment of %d offset %d\n", + omni_request->recv_alignment, + omni_request->recv_offset); + fprintf(where, + "recv_omni: requested send alignment of %d offset %d\n", + omni_request->send_alignment, + omni_request->send_offset); + fflush(where); + } + + omni_response->send_size = omni_request->send_size; + omni_response->send_width = omni_request->send_width; + if (omni_request->direction & NETPERF_XMIT) { + if (omni_request->response_size > 0) { + /* request/response_test */ + bytes_to_send = omni_request->response_size; + if (omni_request->send_width == 0) send_width = 1; + else send_width = omni_request->send_width; + } + else { + if (omni_request->send_size == -1) { + if (lss_size > 0) bytes_to_send = lss_size; + else bytes_to_send = 4096; + } + else bytes_to_send = omni_request->send_size; + /* set the send_width */ + if (omni_request->send_width == 0) { + send_width = (lss_size/bytes_to_send) + 1; + if (send_width == 1) send_width++; + } + else + send_width = omni_request->send_width; + } + send_ring = allocate_buffer_ring(send_width, + bytes_to_send, + omni_request->send_alignment, + omni_request->send_offset); + + omni_response->send_width = send_width; + omni_response->send_size = bytes_to_send; + } + + omni_response->receive_size = omni_request->receive_size; + omni_response->recv_width = omni_response->recv_width; + if (omni_request->direction & NETPERF_RECV) { + if (omni_request->request_size > 0) { + /* request/response test */ + bytes_to_recv = omni_request->request_size; + if (omni_request->recv_width == 0) recv_width = 1; + else recv_width = omni_request->recv_width; + } + else { + if (omni_request->receive_size == -1) { + if (lsr_size > 0) bytes_to_recv = lsr_size; + else bytes_to_recv = 4096; + } + else { + bytes_to_recv = omni_request->receive_size; + } + /* set the recv_width */ + if (omni_request->recv_width == 0) { + recv_width = (lsr_size/bytes_to_recv) + 1; + if (recv_width == 1) recv_width++; + } + else + recv_width = omni_request->recv_width; + } + recv_ring = allocate_buffer_ring(recv_width, + bytes_to_recv, + omni_request->recv_alignment, + omni_request->recv_offset); + + omni_response->receive_size = bytes_to_recv; + omni_response->recv_width = recv_width; + } + +#ifdef WIN32 + /* The test timer can fire during operations on the listening socket, + so to make the start_timer below work we have to move + it to close s_listen while we are blocked on accept. */ + win_kludge_socket2 = s_listen; +#endif + + need_to_accept = (omni_request->protocol != IPPROTO_UDP); + + /* we need to hang a listen for everything that needs at least one + accept */ + if (need_to_accept) { + if (listen(s_listen, 5) == SOCKET_ERROR) { + netperf_response.content.serv_errno = errno; + close(s_listen); + send_response(); + if (debug) { + fprintf(where,"could not listen\n"); + fflush(where); + } + exit(1); + } + } + + /* now get the port number assigned by the system */ + addrlen = sizeof(myaddr_in); + if (getsockname(s_listen, + (struct sockaddr *)&myaddr_in, + &addrlen) == SOCKET_ERROR){ + netperf_response.content.serv_errno = errno; + close(s_listen); + send_response(); + if (debug) { + fprintf(where,"could not getsockname\n"); + fflush(where); + } + exit(1); + } + + /* Now myaddr_in contains the port and the internet address this is + returned to the sender also implicitly telling the sender that + the socket buffer sizing has been done. likely as not, the IP + address will be the wildcard - so we only really need to extract + the port number. since send_response is going to call htonl on + all the fields, we want to initially put the port number in there + in host order. */ + + omni_response->data_port = + (int) ntohs(((struct sockaddr_in *)&myaddr_in)->sin_port); + if (debug) { + fprintf(where,"telling the remote to call me at %d\n", + omni_response->data_port); + fflush(where); + } + netperf_response.content.serv_errno = 0; + + /* But wait, there's more. If the initiator wanted cpu measurements, */ + /* then we must call the calibrate routine, which will return the max */ + /* rate back to the initiator. If the CPU was not to be measured, or */ + /* something went wrong with the calibration, we will return a 0.0 to */ + /* the initiator. */ + + omni_response->cpu_rate = (float)0.0; /* assume no cpu */ + omni_response->measure_cpu = 0; + if (omni_request->measure_cpu) { + omni_response->measure_cpu = 1; + omni_response->cpu_rate = + calibrate_local_cpu(omni_request->cpu_rate); + } + + /* before we send the response back to the initiator, pull some of */ + /* the socket parms from the globals */ + omni_response->send_buf_size = lss_size; + omni_response->recv_buf_size = lsr_size; + omni_response->no_delay = loc_nodelay; + omni_response->so_rcvavoid = loc_rcvavoid; + omni_response->so_sndavoid = loc_sndavoid; + omni_response->interval_usecs = interval_usecs; + omni_response->interval_burst = interval_burst; + + find_system_info(&local_system_model,&local_cpu_model,&local_cpu_frequency); + strncpy(omni_response->system_model,local_system_model,sizeof(omni_response->system_model)); + omni_response->system_model[sizeof(omni_response->system_model)-1] = 0; + strncpy(omni_response->cpu_model,local_cpu_model,sizeof(omni_response->cpu_model)); + omni_response->cpu_model[sizeof(omni_response->cpu_model)-1] = 0; + omni_response->cpu_frequency = local_cpu_frequency; + + find_security_info(&local_security_enabled_num, + &local_security_type_id, + &local_security_specific); + /* top bits type, bottom bits enabled */ + omni_response->security_info = local_security_type_id << 16; + omni_response->security_info += local_security_enabled_num & 0xffff; + strncpy(omni_response->security_string, + local_security_specific, + sizeof(omni_response->security_string)); + omni_response->security_string[sizeof(omni_response->security_string)-1] = 0; + + send_response_n(OMNI_RESPONSE_CONV_CUTOFF); /* brittle, but functional */ + + local_send_calls = 0; + local_receive_calls = 0; + + addrlen = sizeof(peeraddr_in); + memset(&peeraddr_in,0,sizeof(peeraddr_in)); + + /* Now it's time to start receiving data on the connection. We will */ + /* first grab the apropriate counters and then start grabbing. */ + + cpu_start(omni_request->measure_cpu); + + /* if the test is timed, set a timer of suitable length. if the + test is by byte/transaction count, we don't need a timer - or + rather we rely on the netperf to only ask us to do transaction + counts over "reliable" protocols. perhaps at some point we + should add a check herebouts to verify that... */ + + if (omni_request->test_length > 0) { + times_up = 0; + units_remaining = 0; + /* if we are the sender and only sending, then we don't need/want + the padding, otherwise, we need the padding */ + if (!(NETPERF_XMIT_ONLY(omni_request->direction))) + pad_time = PAD_TIME; + start_timer(omni_request->test_length + pad_time); + } + else { + times_up = 1; + units_remaining = omni_request->test_length * -1; + } + +#if defined(WANT_INTERVALS) + INTERVALS_INIT(); +#endif /* WANT_INTERVALS */ + + + trans_completed = 0; + bytes_sent = 0; + bytes_received = 0; + connected = 0; + + while ((!times_up) || (units_remaining > 0)) { + + if (need_to_accept) { + /* accept a connection from the remote */ +#ifdef WIN32 + /* The test timer will probably fire during this accept, + so to make the start_timer above work we have to move + it to close s_listen while we are blocked on accept. */ + win_kludge_socket = s_listen; +#endif + if ((data_socket=accept(s_listen, + (struct sockaddr *)&peeraddr_in, + &addrlen)) == INVALID_SOCKET) { + if (errno == EINTR) { + /* the timer popped */ + times_up = 1; /* ostensibly the signal hander dealt with this?*/ + timed_out = 1; + break; + } + fprintf(where,"recv_omni: accept: errno = %d\n",errno); + fflush(where); + close(s_listen); + + exit(1); + } + + if (debug) { + fprintf(where,"recv_omni: accepted data connection.\n"); + fflush(where); + } + need_to_accept = 0; + connected = 1; + +#ifdef KLUDGE_SOCKET_OPTIONS + /* this is for those systems which *INCORRECTLY* fail to pass + attributes across an accept() call. Including this goes + against my better judgement :( raj 11/95 */ + + kludge_socket_options(data_socket); + +#endif /* KLUDGE_SOCKET_OPTIONS */ + + } + else { + /* I wonder if duping would be better here? we also need to set + peeraddr_in so we can send to netperf if this isn't a + request/response test or if we are going to connect() the + socket */ + if (omni_request->protocol == IPPROTO_UDP) { + data_socket = s_listen; + set_sockaddr_family_addr_port(&peeraddr_in, + nf_to_af(omni_request->ipfamily), + omni_request->ipaddr, + omni_request->netperf_port); + } + } + + if (need_to_connect) { + /* initially this will only be used for UDP tests as a TCP or + other connection-oriented test will always have us making an + accept() call raj 2008-01-11 */ + } + +#ifdef WIN32 + /* this is used so the timer thread can close the socket out from + under us, which to date is the easiest/cleanest/least + Windows-specific way I can find to force the winsock calls to + return WSAEINTR with the test is over. anything that will run on + 95 and NT and is closer to what netperf expects from Unix signals + and such would be appreciated raj 1/96 */ + win_kludge_socket = data_socket; +#endif /* WIN32 */ + + /* in recv_omni, we check recv first, and _then_ send, otherwise, + a request/response test will be all messed-up :) and that then + is why there are two routines to rule them all rather than just + one :) */ + if ((omni_request->direction & NETPERF_RECV) && + !times_up) { + ret = recv_data(data_socket, + recv_ring, + bytes_to_recv, + (connected) ? NULL : (struct sockaddr *)&peeraddr_in, + &addrlen, + /* if XMIT also, then this is RR test so waitall */ + (direction & NETPERF_XMIT) ? NETPERF_WAITALL: 0, + &temp_recvs); + if (ret > 0) { + /* if this is a recv-only test controlled by byte count we + decrement the units_remaining by the bytes received */ + if (!(direction & NETPERF_XMIT) && (units_remaining > 0)) { + units_remaining -= ret; + } + bytes_received += ret; + local_receive_calls += temp_recvs; + } + else if (ret == 0) { + /* is this the end of a test, just a zero-byte recv, or + something else? that is an exceedingly good question and + one for which I don't presently have a good answer, but + that won't stop me from guessing :) raj 2008-01-09 */ + fprintf(where,"read zero conn_test %d null_message_ok %d\n", + connection_test,null_message_ok); + fflush(where); + if (!((connection_test) || (null_message_ok))) { + /* if it is neither a connection_test nor null_message_ok it + must be the end of the test */ + times_up = 1; + break; + } + local_receive_calls += temp_recvs; + } + else if (ret == -1) { + /* test timed-out */ + fprintf(where,"YO! TIMESUP!\n"); + fflush(where); + times_up = 1; + timed_out = 1; + break; + } + else { + /* presently at least, -2 and -3 are equally bad on recv */ + /* we need a response message here for the control connection + before we exit! */ + exit(1); + } + recv_ring = recv_ring->next; + } + + /* if we should try to send something, then by all means, let us + try to send something. */ + if ((omni_request->direction & NETPERF_XMIT) && + !times_up) { + ret = send_data(data_socket, + send_ring, + bytes_to_send, + (connected) ? NULL : (struct sockaddr *)&peeraddr_in, + addrlen); + + /* the order of these if's will seem a triffle strange, but they + are my best guess as to order of probabilty and/or importance + to the overhead raj 2008-01-09*/ + if (ret == bytes_to_send) { + /* if this is a send-only test controlled by byte count we + decrement units_remaining by the bytes sent */ + if (!(direction & NETPERF_RECV) && (units_remaining > 0)) { + units_remaining -= ret; + } + bytes_sent += ret; + send_ring = send_ring->next; + local_send_calls++; + } + else if (ret == -2) { + /* what to do here -2 means a non-fatal error - probably + ENOBUFS and so our send didn't happen. in the old code for + UDP_STREAM we would just continue in the while loop. it + isn't clear that is what to do here, so we will simply + increment the failed_sends stat and fall-through. If this + is a UDP_STREAM style of test, the net effect should be the + same. if this is a UDP_RR with a really-big burst count, I + don't think we were checking for ENOBUFS there anyway and + so would have failed. Here we can just let things + slide. */ + failed_sends++; + } + else if (ret == 0) { + /* was this a zero-byte send? if it was, then ostensibly we + would hit the ret == bytes_to_send case which means we'd + never get here as we are using blocking semantics */ + } + else if (ret == -1) { + times_up = 1; + timed_out = 1; + break; + } + else { + /* we need a response message back to netperf here before we + exit */ + /* NEED RESPONSE; */ + exit(1); + } + + } + + if (connection_test) { +#ifdef __linux + /* so, "Linux" with autotuning likes to alter the socket buffer + sizes over the life of the connection, but only does so when + one takes the defaults at time of socket creation. if we + took those defaults, we should inquire as to what the values + ultimately became. raj 2008-01-15 */ + if (lsr_size_req < 0) + get_sock_buffer(data_socket, RECV_BUFFER, &lsr_size_end); + else + lsr_size_end = lsr_size; + if (lss_size_req < 0) + get_sock_buffer(data_socket, SEND_BUFFER, &lss_size_end); + else + lss_size_end = lss_size; +#else + lsr_size_end = lsr_size; + lss_size_end = lss_size; +#endif + ret = close_data_socket(data_socket,NULL,0); + if (ret == -1) { + times_up = 1; + timed_out = 1; + break; + } + else if (ret < 0) { + perror("netperf: recv_omni: close_data_socket failed"); + fflush(where); + exit(1); + } + /* we will need a new connection to be established */ + need_to_accept = 1; + connected = 0; + } + +#if defined(WANT_INTERVALS) + INTERVALS_WAIT(); +#endif /* WANT_INTERVALS */ + + /* was this a "transaction" test? don't for get that a TCP_CC + style test will have no xmit or recv :) so, we check for either + both XMIT and RECV set, or neither XMIT nor RECV set */ + if (NETPERF_IS_RR(omni_request->direction)) { + trans_completed++; + if (units_remaining) { + units_remaining--; + } + } + } + + /* The current iteration loop now exits due to timeout or unit count + being reached */ + + cpu_stop(omni_request->measure_cpu,&elapsed_time); + + if (timed_out) { + /* we ended the test by time, which may have been PAD_TIME seconds + longer than we wanted to run. so, we want to subtract pad_time + from the elapsed_time. if we didn't pad the timer pad_time will + be 0 so we can just subtract it anyway :) */ + if (debug) { + fprintf(where,"Adjusting elapsed time by %d seconds\n",pad_time); + fflush(where); + } + elapsed_time -= pad_time; + } + + if (connected) { +#ifdef __linux + /* so, "Linux" with autotuning likes to alter the socket buffer + sizes over the life of the connection, but only does so when + one takes the defaults at time of socket creation. if we took + those defaults, we should inquire as to what the values + ultimately became. raj 2008-01-15 */ + if (lsr_size_req < 0) + get_sock_buffer(data_socket, RECV_BUFFER, &lsr_size_end); + else + lsr_size_end = lsr_size; + if (lss_size_req < 0) + get_sock_buffer(data_socket, SEND_BUFFER, &lss_size_end); + else + lss_size_end = lss_size; +#else + lsr_size_end = lsr_size; + lss_size_end = lss_size; +#endif + close_data_socket(data_socket,NULL,0); + } + else { + close_data_socket(data_socket,(struct sockaddr *)&peeraddr_in,addrlen); + lsr_size_end = lsr_size; + lss_size_end = lss_size; + } + + /* send the results to the sender */ + + omni_results->send_calls = local_send_calls; + omni_results->bytes_received_lo = bytes_received & 0x00000000FFFFFFFFULL; + omni_results->bytes_received_hi = (bytes_received & 0xFFFFFFFF00000000ULL) >> 32; + omni_results->recv_buf_size = lsr_size_end; + omni_results->recv_calls = local_receive_calls; + omni_results->bytes_sent_lo = bytes_sent & 0x00000000FFFFFFFFULL; + omni_results->bytes_sent_hi = (bytes_sent & 0xFFFFFFFF00000000ULL) >> 32; + omni_results->send_buf_size = lss_size_end; + omni_results->trans_received = trans_completed; + omni_results->elapsed_time = elapsed_time; + omni_results->cpu_method = cpu_method; + omni_results->num_cpus = lib_num_loc_cpus; + if (omni_request->measure_cpu) { + omni_results->cpu_util = calc_cpu_util(elapsed_time); + } + omni_results->peak_cpu_util = (float)lib_local_peak_cpu_util; + omni_results->peak_cpu_id = lib_local_peak_cpu_id; + local_interface_name = + find_egress_interface(local_res->ai_addr,(struct sockaddr *)&peeraddr_in); + strncpy(omni_results->ifname,local_interface_name,16); + omni_results->ifname[15] = 0; + local_interface_slot = find_interface_slot(local_interface_name); + strncpy(omni_results->ifslot,local_interface_slot,16); + omni_results->ifslot[15] = 0; + find_interface_ids(local_interface_name, + &omni_results->vendor, + &omni_results->device, + &omni_results->subvendor, + &omni_results->subdevice); + find_driver_info(local_interface_name, + omni_results->driver, + omni_results->version, + omni_results->firmware, + omni_results->bus, + 32); + if (debug) { + fprintf(where, + "recv_omni: test complete, sending results.\n"); + fflush(where); + } + + send_response_n(OMNI_RESULTS_CONF_CUTOFF); + + /* when we implement this, it will look a little strange, but we do + it to avoid certain overheads when running aggregates and using + confidence intervals. we will post a recv_request() call to get + the next message or EOF on the control connection. either the + netperf will close the control connection, which will tell us we + are done, or the netperf will send us another "DO_OMNI" message, + which by definition should be identical to the first DO_OMNI + message we received. + + in this way we can avoid overheads like allocating the buffer + rings and the listen socket and the like */ + +} + +void +scan_omni_args(int argc, char *argv[]) + +{ + +#define OMNI_ARGS "b:cCd:DnNhH:kL:m:M:oOp:P:r:s:S:t:T:u:Vw:W:46" + + extern char *optarg; /* pointer to option string */ + + int c; + int have_uuid = 0; + + char + arg1[BUFSIZ], /* argument holders */ + arg2[BUFSIZ]; + + if (debug) { + int i; + printf("%s called with the following argument vector\n", + __func__); + for (i = 0; i< argc; i++) { + printf("%s ",argv[i]); + } + printf("\n"); + } + + strncpy(local_data_port,"0",sizeof(local_data_port)); + strncpy(remote_data_port,"0",sizeof(remote_data_port)); + + /* default to a STREAM socket type. i wonder if this should be part + of send_omni or here... */ + socket_type = nst_to_hst(NST_STREAM); + socket_type_str = hst_to_str(socket_type); + + /* default to TCP. i wonder if this should be here or in + send_omni? */ +#ifdef IPPROTO_TCP + protocol = IPPROTO_TCP; +#endif + + /* we will check to see if this needs to remain 0 or set to + something else when we get finished scanning all the argument + values */ + direction = 0; + + /* default is to be a stream test, so req_size and rsp_size should + be < 0) */ + + req_size = rsp_size = -1; + + /* Go through all the command line arguments and break them */ + /* out. For those options that take two parms, specifying only */ + /* the first will set both to that value. Specifying only the */ + /* second will leave the first untouched. To change only the */ + /* first, use the form "first," (see the routine break_args.. */ + + while ((c= getopt(argc, argv, OMNI_ARGS)) != EOF) { + switch (c) { + case '?': + case '4': + remote_data_family = AF_INET; + local_data_family = AF_INET; + break; + case '6': +#if defined(AF_INET6) + remote_data_family = AF_INET6; + local_data_family = AF_INET6; +#else + fprintf(stderr, + "This netperf was not compiled on an IPv6 capable host!\n"); + fflush(stderr); + exit(-1); +#endif + break; + case 'h': + print_sockets_usage(); + exit(1); + case 'b': +#ifdef WANT_FIRST_BURST + first_burst_size = atoi(optarg); +#else /* WANT_FIRST_BURST */ + printf("Initial request burst functionality not compiled-in!\n"); +#endif /* WANT_FIRST_BURST */ + break; + case 'c': + /* this is a connection test */ + connection_test = 1; + break; + case 'C': +#ifdef TCP_CORK + /* set TCP_CORK */ + loc_tcpcork = 1; + rem_tcpcork = 1; /* however, at first, we ony have cork affect loc */ +#else + printf("WARNING: TCP_CORK not available on this platform!\n"); +#endif /* TCP_CORK */ + break; + case 'd': + /* arbitrarily set the direction variable */ + direction = strtol(optarg,NULL,0); + break; + case 'D': + /* set the TCP nodelay flag */ + loc_nodelay = 1; + rem_nodelay = 1; + break; + case 'H': + break_args_explicit(optarg,arg1,arg2); + if (arg1[0]) { + /* make sure we leave room for the NULL termination boys and + girls. raj 2005-02-82 */ + remote_data_address = malloc(strlen(arg1)+1); + strcpy(remote_data_address,arg1); + } + if (arg2[0]) + remote_data_family = parse_address_family(arg2); + break; + case 'k': + csv = 0; + keyword = 1; + /* obliterate any previous file name */ + if (human_selection_file) { + free(human_selection_file); + human_selection_file = NULL; + } + if (csv_selection_file) { + free(csv_selection_file); + csv_selection_file = NULL; + } + if (argv[optind] && ((unsigned char)argv[optind][0] != '-')) { + /* we assume that what follows is the name of a file with the + list of desired output values. */ + csv_selection_file = strdup(argv[optind]); + optind++; + /* special case - if the file name is "?" then we will emit a + list of the available outputs */ + if (strcmp(csv_selection_file,"?") == 0) { + dump_netperf_output_list(stdout,1); + exit(1); + } + } + break; + case 'L': + break_args_explicit(optarg,arg1,arg2); + if (arg1[0]) { + /* make sure we leave room for the NULL termination boys and + girls. raj 2005-02-82 */ + local_data_address = malloc(strlen(arg1)+1); + strcpy(local_data_address,arg1); + } + if (arg2[0]) + local_data_family = parse_address_family(arg2); + break; + case 'm': + /* set the send size. if we set the local send size it will add + XMIT to direction. if we set the remote send size it will + add RECV to the direction. likely as not this will need some + additional throught */ + break_args_explicit(optarg,arg1,arg2); + if (arg1[0]) { + send_size = convert(arg1); + direction |= NETPERF_XMIT; + } + if (arg2[0]) { + remote_send_size_req = convert(arg2); + direction |= NETPERF_RECV; + } + break; + case 'M': + /* set the recv sizes. if we set the local recv size it will + add RECV to direction. if we set the remote recv size it + will add XMIT to direction */ + break_args_explicit(optarg,arg1,arg2); + if (arg1[0]) { + remote_recv_size_req = convert(arg1); + direction |= NETPERF_XMIT; + } + if (arg2[0]) { + recv_size = convert(arg2); + direction |= NETPERF_RECV; + } + break; + case 'n': + /* set the local socket type */ + local_connected = 1; + break; + case 'N': + /* set the remote socket type */ + remote_connected = 1; + break; + case 'o': + csv = 1; + keyword = 0; + /* obliterate any previous file name */ + if (human_selection_file) { + free(human_selection_file); + human_selection_file = NULL; + } + if (csv_selection_file) { + free(csv_selection_file); + csv_selection_file = NULL; + } + if (argv[optind] && ((unsigned char)argv[optind][0] != '-')) { + /* we assume that what follows is the name of a file with the + list of desired output values. */ + csv_selection_file = strdup(argv[optind]); + optind++; + /* special case - if the file name is "?" then we will emit a + list of the available outputs */ + if (strcmp(csv_selection_file,"?") == 0) { + dump_netperf_output_list(stdout,1); + exit(1); + } + } + break; + case 'O': + csv = 0; + keyword = 0; + /* obliterate any previous file name */ + if (human_selection_file) { + free(human_selection_file); + human_selection_file = NULL; + } + if (csv_selection_file) { + free(csv_selection_file); + csv_selection_file = NULL; + } + if (argv[optind] && ((unsigned char)argv[optind][0] != '-')) { + /* we assume that what follows is the name of a file with the + list of desired output values */ + human_selection_file = strdup(argv[optind]); + optind++; + if (strcmp(human_selection_file,"?") == 0) { + dump_netperf_output_list(stdout,0); + exit(1); + } + } + break; + case 'p': + /* set the min and max port numbers for the TCP_CRR and TCP_TRR */ + /* tests. */ + break_args(optarg,arg1,arg2); + if (arg1[0]) + client_port_min = atoi(arg1); + if (arg2[0]) + client_port_max = atoi(arg2); + break; + case 'P': + /* set the local and remote data port numbers for the tests to + allow them to run through those blankety blank end-to-end + breaking firewalls. raj 2004-06-15 */ + break_args(optarg,arg1,arg2); + if (arg1[0]) + strncpy(local_data_port,arg1,sizeof(local_data_port)); + if (arg2[0]) + strncpy(remote_data_port,arg2,sizeof(remote_data_port)); + break; + case 'r': + /* set the request/response sizes. setting request/response + sizes implicitly sets direction to XMIT and RECV */ + direction |= NETPERF_XMIT; + direction |= NETPERF_RECV; + break_args(optarg,arg1,arg2); + if (arg1[0]) + req_size = convert(arg1); + if (arg2[0]) + rsp_size = convert(arg2); + break; + case 's': + /* set local socket sizes */ + break_args(optarg,arg1,arg2); + if (arg1[0]) + lss_size_req = convert(arg1); + if (arg2[0]) + lsr_size_req = convert(arg2); + break; + case 'S': + /* set remote socket sizes */ + break_args(optarg,arg1,arg2); + if (arg1[0]) + rss_size_req = convert(arg1); + if (arg2[0]) + rsr_size_req = convert(arg2); + break; + case 't': + /* set the socket type */ + socket_type = parse_socket_type(optarg); + break; + case 'T': + /* set the protocol - aka "Transport" */ + protocol = parse_protocol(optarg); + break; + case 'u': + /* use the supplied string as the UUID for this test. at some + point we may want to sanity check the string we are given but + for now we won't worry about it */ + strncpy(test_uuid,optarg,sizeof(test_uuid)); + /* strncpy may leave us with a string without a null at the end */ + test_uuid[sizeof(test_uuid) - 1] = 0; + have_uuid = 1; + break; + case 'W': + /* set the "width" of the user space data */ + /* buffer. This will be the number of */ + /* send_size buffers malloc'd in the */ + /* *_STREAM test. It may be enhanced to set */ + /* both send and receive "widths" but for now */ + /* it is just the sending *_STREAM. */ + send_width = convert(optarg); + break; + case 'V' : + /* we want to do copy avoidance and will set */ + /* it for everything, everywhere, if we really */ + /* can. of course, we don't know anything */ + /* about the remote... */ +#ifdef SO_SND_COPYAVOID + loc_sndavoid = 1; +#else + loc_sndavoid = 0; + printf("Local send copy avoidance not available.\n"); +#endif +#ifdef SO_RCV_COPYAVOID + loc_rcvavoid = 1; +#else + loc_rcvavoid = 0; + printf("Local recv copy avoidance not available.\n"); +#endif + rem_sndavoid = 1; + rem_rcvavoid = 1; + break; + }; + } + + /* generate the UUID for this test if the user has not supplied it */ + if (!have_uuid) + get_uuid_string(test_uuid,sizeof(test_uuid)); + + + protocol_str = protocol_to_str(protocol); + /* ok, if we have gone through all that, and direction is still + zero, let us see if it needs to be set to something else. */ + if ((0 == direction) && (!connection_test)) direction = NETPERF_XMIT; + direction_str = direction_to_str(direction); + /* some other sanity checks we need to make would include stuff when + the user has set -m and -M such that both XMIT and RECV are set + and has not set -r. initially we will not allow that. at some + point we might allow that if the user has also set -r, but until + then the code will simply ignore the values from -m and -M when + -r is set. */ + +#if defined(WANT_FIRST_BURST) +#if defined(WANT_HISTOGRAM) + /* if WANT_FIRST_BURST and WANT_HISTOGRAM are defined and the user + indeed wants a non-zero first burst size, and we would emit a + histogram, then we should emit a warning that the two are not + compatible. raj 2006-01-31 */ + if ((first_burst_size > 0) && (verbosity >= 2)) { + fprintf(stderr, + "WARNING! Histograms and first bursts are incompatible!\n"); + fflush(stderr); + } +#endif +#endif + + /* ok, time to sanity check the output units */ + if ('?' == libfmt) { + /* if this is a RR test then set it to 'x' for transactions */ + if (NETPERF_IS_RR(direction)) { + libfmt = 'x'; + } + else { + libfmt = 'm'; + } + } + else if ('x' == libfmt) { + /* now, a format of 'x' makes no sense for anything other than + an RR test. if someone has been silly enough to try to set + that, we will reset it silently to default - namely 'm' */ + if (!NETPERF_IS_RR(direction)) { + libfmt = 'm'; + } + } + + /* this needs to be strdup :) */ + thruput_format_str = strdup(format_units()); + + /* so, if there is to be no control connection, we want to have some + different settings for a few things */ + + if (no_control) { + + fprintf(where,"I don't know about no control connection tests yet\n"); + exit(1); + + if (strcmp(remote_data_port,"0") == 0) { + /* we need to select either the discard port, echo port or + chargen port dedepending on the test name. raj 2007-02-08 */ + if (strstr(test_name,"STREAM") || + strstr(test_name,"SENDFILE")) { + strncpy(remote_data_port,"discard",sizeof(remote_data_port)); + } + else if (strstr(test_name,"RR")) { + strncpy(remote_data_port,"echo",sizeof(remote_data_port)); + } + else if (strstr(test_name,"MAERTS")) { + strncpy(remote_data_port,"chargen",sizeof(remote_data_port)); + } + else { + printf("No default port known for the %s test, please set one yourself\n",test_name); + exit(-1); + } + } + remote_data_port[sizeof(remote_data_port) - 1] = '\0'; + + /* I go back and forth on whether these should become -1 or if + they should become 0 for a no_control test. what do you think? + raj 2006-02-08 */ + + rem_rcvavoid = -1; + rem_sndavoid = -1; + rss_size_req = -1; + rsr_size_req = -1; + rem_nodelay = -1; + + if (strstr(test_name,"STREAM") || + strstr(test_name,"SENDFILE")) { + recv_size = -1; + } + else if (strstr(test_name,"RR")) { + /* I am however _certain_ that for a no control RR test the + response size must equal the request size since 99 times out + of ten we will be speaking to the echo service somewhere */ + rsp_size = req_size; + } + else if (strstr(test_name,"MAERTS")) { + send_size = -1; + } + else { + printf("No default port known for the %s test, please set one yourself\n",test_name); + exit(-1); + } + } +} + +#endif /* WANT_OMNI */ diff --git a/src/nettest_sctp.c b/src/nettest_sctp.c new file mode 100644 index 0000000..7cfcd9f --- /dev/null +++ b/src/nettest_sctp.c @@ -0,0 +1,4869 @@ +#ifndef lint +char nettest_sctp[]="\ +@(#)nettest_sctp.c (c) Copyright 2005-2007 Hewlett-Packard Co. Version 2.4.3"; +#else +#define DIRTY +#define WANT_HISTOGRAM +#define WANT_INTERVALS +#endif /* lint */ + +/****************************************************************/ +/* */ +/* nettest_sctp.c */ +/* */ +/* */ +/* scan_sctp_args() get the sctp command line args */ +/* */ +/* the actual test routines... */ +/* */ +/* send_sctp_stream() perform a sctp stream test */ +/* recv_sctp_stream() */ +/* send_sctp_rr() perform a sctp request/response */ +/* recv_sctp_rr() */ +/* send_sctp_stream_udp() perform a sctp request/response */ +/* recv_sctp_stream_upd() using UDP style API */ +/* send_sctp_rr_udp() perform a sctp request/response */ +/* recv_sctp_rr_upd() using UDP style API */ +/* */ +/* relies on create_data_socket in nettest_bsd.c */ +/****************************************************************/ + +#if HAVE_CONFIG_H +# include +#endif + +#if defined(WANT_SCTP) + +#include +#include +#include +#include +#include +#include +#include +#ifdef NOSTDLIBH +#include +#else /* NOSTDLIBH */ +#include +#endif /* NOSTDLIBH */ + +#if !defined(__VMS) +#include +#endif /* !defined(__VMS) */ +#include +#include +#include +#include +#include +#include +#include +#include + +/* would seem that not all sctp.h files define a MSG_EOF, but that + MSG_EOF can be the same as MSG_FIN so lets work with that + assumption. initial find by Jon Pedersen. raj 2006-02-01 */ +#ifndef MSG_EOF +#ifdef MSG_FIN +#define MSG_EOF MSG_FIN +#else +#error Must have either MSG_EOF or MSG_FIN defined +#endif +#endif + +#include "netlib.h" +#include "netsh.h" +/* get some of the functions from nettest_bsd.c */ +#include "nettest_bsd.h" +#include "nettest_sctp.h" + +#ifdef WANT_HISTOGRAM +#ifdef __sgi +#include +#endif /* __sgi */ +#include "hist.h" +#endif /* WANT_HISTOGRAM */ + +#ifdef WANT_FIRST_BURST +extern int first_burst_size; +#endif /* WANT_FIRST_BURST */ + + + +/* these variables are specific to SCTP tests. declare */ +/* them static to make them global only to this file. */ + +static int + msg_count = 0, /* number of messages to transmit on association */ + non_block = 0, /* default to blocking sockets */ + num_associations = 1; /* number of associations on the endpoint */ + +static int confidence_iteration; +static char local_cpu_method; +static char remote_cpu_method; + +#ifdef WANT_HISTOGRAM +static struct timeval time_one; +static struct timeval time_two; +static HIST time_hist; +#endif /* WANT_HISTOGRAM */ + + +char sctp_usage[] = "\n\ +Usage: netperf [global options] -- [test options] \n\ +\n\ +SCTP Sockets Test Options:\n\ + -b number Send number requests at the start of _RR tests\n\ + -D [L][,R] Set SCTP_NODELAY locally and/or remotely\n\ + -h Display this text\n\ + -H name,fam Use name (or IP) and family as target of data connection\n\ + -L name,fam Use name (or IP) and family as source of data connextion\n\ + -m bytes Set the size of each sent message\n\ + -M bytes Set the size of each received messages\n\ + -P local[,remote] Set the local/remote port for the data socket\n\ + -r req,[rsp] Set request/response sizes (_RR tests)\n\ + -s send[,recv] Set local socket send/recv buffer sizes\n\ + -S send[,recv] Set remote socket send/recv buffer sizes\n\ + -V Enable copy avoidance if supported\n\ + -N number Specifies the number of messages to send (_STREAM tests)\n\ + -B run the test in non-blocking mode\n\ + -T number Number of associations to create (_MANY tests)\n\ + -4 Use AF_INET (eg IPv4) on both ends of the data conn\n\ + -6 Use AF_INET6 (eg IPv6) on both ends of the data conn\n\ +\n\ +For those options taking two parms, at least one must be specified;\n\ +specifying one value without a comma will set both parms to that\n\ +value, specifying a value with a leading comma will set just the second\n\ +parm, a value with a trailing comma will set just the first. To set\n\ +each parm to unique values, specify both and separate them with a\n\ +comma.\n"; + + + /* This routine is intended to retrieve interesting aspects of tcp */ + /* for the data connection. at first, it attempts to retrieve the */ + /* maximum segment size. later, it might be modified to retrieve */ + /* other information, but it must be information that can be */ + /* retrieved quickly as it is called during the timing of the test. */ + /* for that reason, a second routine may be created that can be */ + /* called outside of the timing loop */ +static +void +get_sctp_info(socket, mss) + int socket; + int *mss; +{ + + int sock_opt_len; + + if (sctp_opt_info(socket, + 0, + SCTP_MAXSEG, + mss, + &sock_opt_len) < 0) { + lss_size = -1; + } +} + + +static +void +sctp_enable_events(socket, ev_mask) + int socket; + int ev_mask; +{ + struct sctp_event_subscribe ev; + + bzero(&ev, sizeof(ev)); + + if (ev_mask & SCTP_SNDRCV_INFO_EV) + ev.sctp_data_io_event = 1; + + if (ev_mask & SCTP_ASSOC_CHANGE_EV) + ev.sctp_association_event = 1; + + if (ev_mask & SCTP_PEERADDR_CHANGE_EV) + ev.sctp_address_event = 1; + + if (ev_mask & SCTP_SND_FAILED_EV) + ev.sctp_send_failure_event = 1; + + if (ev_mask & SCTP_REMOTE_ERROR_EV) + ev.sctp_peer_error_event = 1; + + if (ev_mask & SCTP_SHUTDOWN_EV) + ev.sctp_shutdown_event = 1; + + if (ev_mask & SCTP_PD_EV) + ev.sctp_partial_delivery_event = 1; + + if (ev_mask & SCTP_ADAPT_EV) +#ifdef HAVE_SCTP_ADAPTATION_LAYER_EVENT + ev.sctp_adaptation_layer_event = 1; +#else + ev.sctp_adaption_layer_event = 1; +#endif + + if (setsockopt(socket, + IPPROTO_SCTP, +#ifdef SCTP_EVENTS + SCTP_EVENTS, +#else + SCTP_SET_EVENTS, +#endif + (const char*)&ev, + sizeof(ev)) != 0 ) { + fprintf(where, + "sctp_enable_event: could not set sctp events errno %d\n", + errno); + fflush(where); + exit(1); + } +} + + +static +sctp_disposition_t +sctp_process_event(socket, buf) + int socket; + void *buf; +{ + + struct sctp_assoc_change *sac; + struct sctp_send_failed *ssf; + struct sctp_paddr_change *spc; + struct sctp_remote_error *sre; + union sctp_notification *snp; + + snp = buf; + + switch (snp->sn_header.sn_type) { + case SCTP_ASSOC_CHANGE: + if (debug) { + fprintf(where, "\tSCTP_ASSOC_CHANGE event, type:"); + fflush(where); + } + sac = &snp->sn_assoc_change; + switch (sac->sac_type) { + case SCTP_COMM_UP: + if (debug) { + fprintf(where, " SCTP_COMM_UP\n"); + fflush(where); + } + break; + case SCTP_RESTART: + if (debug) { + fprintf(where, " SCTP_RESTART\n"); + fflush(where); + } + break; + case SCTP_CANT_STR_ASSOC: + if (debug) { + fprintf(where, " SCTP_CANT_STR_ASSOC\n"); + fflush(where); + } + break; /* FIXME ignore above status changes */ + case SCTP_COMM_LOST: + if (debug) { + fprintf(where, " SCTP_COMM_LOST\n"); + fflush(where); + } + return SCTP_CLOSE; + case SCTP_SHUTDOWN_COMP: + if (debug) { + fprintf(where, " SCTP_SHUTDOWN_COMPLETE\n"); + fflush(where); + } + return SCTP_CLOSE; + break; + } + + case SCTP_SEND_FAILED: + if (debug) { + fprintf(where, "\tSCTP_SEND_FAILED event\n"); + fflush(where); + } + ssf = &snp->sn_send_failed; + break; /* FIXME ??? ignore this for now */ + + case SCTP_PEER_ADDR_CHANGE: + if (debug) { + fprintf(where, "\tSCTP_PEER_ADDR_CHANGE event\n"); + fflush(where); + } + spc = &snp->sn_paddr_change; + break; /* FIXME ??? ignore this for now */ + + case SCTP_REMOTE_ERROR: + if (debug) { + fprintf(where, "\tSCTP_REMOTE_ERROR event\n"); + fflush(where); + } + sre = &snp->sn_remote_error; + break; /* FIXME ??? ignore this for now */ + case SCTP_SHUTDOWN_EVENT: + if (debug) { + fprintf(where, "\tSCTP_SHUTDOWN event\n"); + fflush(where); + } + return SCTP_CLOSE; + default: + fprintf(where, "unknown type: %hu\n", snp->sn_header.sn_type); + fflush(where); + break; + } + return SCTP_OK; +} + + + +/* This routine implements the SCTP unidirectional data transfer test */ +/* (a.k.a. stream) for the sockets interface. It receives its */ +/* parameters via global variables from the shell and writes its */ +/* output to the standard output. */ + + +void +send_sctp_stream(remote_host) +char remote_host[]; +{ + + char *tput_title = "\ +Recv Send Send \n\ +Socket Socket Message Elapsed \n\ +Size Size Size Time Throughput \n\ +bytes bytes bytes secs. %s/sec \n\n"; + + char *tput_fmt_0 = + "%7.2f\n"; + + char *tput_fmt_1 = + "%6d %6d %6d %-6.2f %7.2f \n"; + + char *cpu_title = "\ +Recv Send Send Utilization Service Demand\n\ +Socket Socket Message Elapsed Send Recv Send Recv\n\ +Size Size Size Time Throughput local remote local remote\n\ +bytes bytes bytes secs. %-8.8s/s %% %c %% %c us/KB us/KB\n\n"; + + char *cpu_fmt_0 = + "%6.3f %c\n"; + + char *cpu_fmt_1 = + "%6d %6d %6d %-6.2f %7.2f %-6.2f %-6.2f %-6.3f %-6.3f\n"; + + char *ksink_fmt = "\n\ +Alignment Offset %-8.8s %-8.8s Sends %-8.8s Recvs\n\ +Local Remote Local Remote Xfered Per Per\n\ +Send Recv Send Recv Send (avg) Recv (avg)\n\ +%5d %5d %5d %5d %6.4g %6.2f %6d %6.2f %6d\n"; + + char *ksink_fmt2 = "\n\ +Maximum\n\ +Segment\n\ +Size (bytes)\n\ +%6d\n"; + + + float elapsed_time; + +#ifdef WANT_INTERVALS + int interval_count; + sigset_t signal_set; +#endif + + /* what we want is to have a buffer space that is at least one */ + /* send-size greater than our send window. this will insure that we */ + /* are never trying to re-use a buffer that may still be in the hands */ + /* of the transport. This buffer will be malloc'd after we have found */ + /* the size of the local senc socket buffer. We will want to deal */ + /* with alignment and offset concerns as well. */ + +#ifdef DIRTY + int *message_int_ptr; +#endif + + struct ring_elt *send_ring; + + int len; + unsigned int nummessages = 0; + int send_socket; + int bytes_remaining; + int sctp_mss; + int timed_out; + + /* with links like fddi, one can send > 32 bits worth of bytes */ + /* during a test... ;-) at some point, this should probably become a */ + /* 64bit integral type, but those are not entirely common yet */ + double bytes_sent = 0.0; + +#ifdef DIRTY + int i; +#endif /* DIRTY */ + + float local_cpu_utilization; + float local_service_demand; + float remote_cpu_utilization; + float remote_service_demand; + + double thruput; + + struct addrinfo *remote_res; + struct addrinfo *local_res; + struct addrinfo *local_remote_res; + struct addrinfo *local_local_res; + + struct sctp_stream_request_struct *sctp_stream_request; + struct sctp_stream_response_struct *sctp_stream_response; + struct sctp_stream_results_struct *sctp_stream_result; + + sctp_stream_request = + (struct sctp_stream_request_struct *)netperf_request.content.test_specific_data; + sctp_stream_response = + (struct sctp_stream_response_struct *)netperf_response.content.test_specific_data; + sctp_stream_result = + (struct sctp_stream_results_struct *)netperf_response.content.test_specific_data; + +#ifdef WANT_HISTOGRAM + time_hist = HIST_new(); +#endif /* WANT_HISTOGRAM */ + /* since we are now disconnected from the code that established the */ + /* control socket, and since we want to be able to use different */ + /* protocols and such, we are passed the name of the remote host and */ + /* must turn that into the test specific addressing information. */ + + /* complete_addrinfos will either succede or exit the process */ + complete_addrinfos(&remote_res, + &local_res, + remote_host, + SOCK_STREAM, + IPPROTO_SCTP, + 0); + + if ( print_headers ) { + print_top_test_header("SCTP STREAM TEST", local_res, remote_res); + } + + send_ring = NULL; + confidence_iteration = 1; + init_stat(); + + /* we have a great-big while loop which controls the number of times */ + /* we run a particular test. this is for the calculation of a */ + /* confidence interval (I really should have stayed awake during */ + /* probstats :). If the user did not request confidence measurement */ + /* (no confidence is the default) then we will only go though the */ + /* loop once. the confidence stuff originates from the folks at IBM */ + + while (((confidence < 0) && (confidence_iteration < iteration_max)) || + (confidence_iteration <= iteration_min)) { + + /* initialize a few counters. we have to remember that we might be */ + /* going through the loop more than once. */ + + nummessages = 0; + bytes_sent = 0.0; + times_up = 0; + timed_out = 0; + + /*set up the data socket */ + send_socket = create_data_socket(local_res); + + if (send_socket == INVALID_SOCKET){ + perror("netperf: send_sctp_stream: sctp stream data socket"); + exit(1); + } + + if (debug) { + fprintf(where,"send_sctp_stream: send_socket obtained...\n"); + } + + /* at this point, we have either retrieved the socket buffer sizes, */ + /* or have tried to set them, so now, we may want to set the send */ + /* size based on that (because the user either did not use a -m */ + /* option, or used one with an argument of 0). If the socket buffer */ + /* size is not available, we will set the send size to 4KB - no */ + /* particular reason, just arbitrary... */ + if (send_size == 0) { + if (lss_size > 0) { + send_size = lss_size; + } + else { + send_size = 4096; + } + } + + /* set-up the data buffer ring with the requested alignment and offset. */ + /* note also that we have allocated a quantity */ + /* of memory that is at least one send-size greater than our socket */ + /* buffer size. We want to be sure that there are at least two */ + /* buffers allocated - this can be a bit of a problem when the */ + /* send_size is bigger than the socket size, so we must check... the */ + /* user may have wanted to explicitly set the "width" of our send */ + /* buffers, we should respect that wish... */ + if (send_width == 0) { + send_width = (lss_size/send_size) + 1; + if (send_width == 1) send_width++; + } + + if (send_ring == NULL) { + /* only allocate the send ring once. this is a networking test, */ + /* not a memory allocation test. this way, we do not need a */ + /* deallocate_buffer_ring() routine, and I don't feel like */ + /* writing one anyway :) raj 11/94 */ + send_ring = allocate_buffer_ring(send_width, + send_size, + local_send_align, + local_send_offset); + } + + /* If the user has requested cpu utilization measurements, we must */ + /* calibrate the cpu(s). We will perform this task within the tests */ + /* themselves. If the user has specified the cpu rate, then */ + /* calibrate_local_cpu will return rather quickly as it will have */ + /* nothing to do. If local_cpu_rate is zero, then we will go through */ + /* all the "normal" calibration stuff and return the rate back. */ + + if (local_cpu_usage) { + local_cpu_rate = calibrate_local_cpu(local_cpu_rate); + } + + /* Tell the remote end to do a listen. The server alters the socket */ + /* paramters on the other side at this point, hence the reason for */ + /* all the values being passed in the setup message. If the user did */ + /* not specify any of the parameters, they will be passed as 0, which */ + /* will indicate to the remote that no changes beyond the system's */ + /* default should be used. Alignment is the exception, it will */ + /* default to 1, which will be no alignment alterations. */ + + netperf_request.content.request_type = DO_SCTP_STREAM; + sctp_stream_request->send_buf_size = rss_size_req; + sctp_stream_request->recv_buf_size = rsr_size_req; + sctp_stream_request->receive_size = recv_size; + sctp_stream_request->no_delay = rem_nodelay; + sctp_stream_request->recv_alignment = remote_recv_align; + sctp_stream_request->recv_offset = remote_recv_offset; + sctp_stream_request->measure_cpu = remote_cpu_usage; + sctp_stream_request->cpu_rate = remote_cpu_rate; + if (test_time) { + sctp_stream_request->test_length = test_time; + } + else { + if (msg_count) + test_bytes = send_size * msg_count; + + sctp_stream_request->test_length = test_bytes; + } + sctp_stream_request->so_rcvavoid = rem_rcvavoid; + sctp_stream_request->so_sndavoid = rem_sndavoid; +#ifdef DIRTY + sctp_stream_request->dirty_count = rem_dirty_count; + sctp_stream_request->clean_count = rem_clean_count; +#endif /* DIRTY */ + sctp_stream_request->port = htonl(atoi(remote_data_port)); + sctp_stream_request->ipfamily = af_to_nf(remote_res->ai_family); + sctp_stream_request->non_blocking = non_block; + + + if (debug > 1) { + fprintf(where, + "netperf: send_sctp_stream: requesting sctp stream test\n"); + } + + send_request(); + + /* The response from the remote will contain all of the relevant */ + /* socket parameters for this test type. We will put them back into */ + /* the variables here so they can be displayed if desired. The */ + /* remote will have calibrated CPU if necessary, and will have done */ + /* all the needed set-up we will have calibrated the cpu locally */ + /* before sending the request, and will grab the counter value right*/ + /* after the connect returns. The remote will grab the counter right*/ + /* after the accept call. This saves the hassle of extra messages */ + /* being sent for the sctp tests. */ + + recv_response(); + + if (!netperf_response.content.serv_errno) { + if (debug) + fprintf(where,"remote listen done.\n"); + rsr_size = sctp_stream_response->recv_buf_size; + rss_size = sctp_stream_response->send_buf_size; + rem_nodelay = sctp_stream_response->no_delay; + remote_cpu_usage= sctp_stream_response->measure_cpu; + remote_cpu_rate = sctp_stream_response->cpu_rate; + + /* we have to make sure that the server port number is in */ + /* network order */ + set_port_number(remote_res, (short)sctp_stream_response->data_port_number); + + rem_rcvavoid = sctp_stream_response->so_rcvavoid; + rem_sndavoid = sctp_stream_response->so_sndavoid; + } + else { + Set_errno(netperf_response.content.serv_errno); + fprintf(where, + "netperf: remote error %d", + netperf_response.content.serv_errno); + perror(""); + fflush(where); + + exit(1); + } + + /*Connect up to the remote port on the data socket */ + if (connect(send_socket, + remote_res->ai_addr, + remote_res->ai_addrlen) == INVALID_SOCKET) { + perror("netperf: send_sctp_stream: data socket connect failed"); + exit(1); + } + + sctp_enable_events(send_socket, SCTP_ASSOC_CHANGE_EV); + + if (non_block) { + /* now that we are connected, mark the socket as non-blocking */ + if (!set_nonblock(send_socket)) { + perror("netperf: fcntl"); + exit(1); + } + } + + /* Data Socket set-up is finished. If there were problems, either */ + /* the connect would have failed, or the previous response would */ + /* have indicated a problem. I failed to see the value of the */ + /* extra message after the accept on the remote. If it failed, */ + /* we'll see it here. If it didn't, we might as well start pumping */ + /* data. */ + + /* Set-up the test end conditions. For a stream test, they can be */ + /* either time or byte-count based. */ + + if (test_time) { + /* The user wanted to end the test after a period of time. */ + times_up = 0; + bytes_remaining = 0; + /* in previous revisions, we had the same code repeated throught */ + /* all the test suites. this was unnecessary, and meant more */ + /* work for me when I wanted to switch to POSIX signals, so I */ + /* have abstracted this out into a routine in netlib.c. if you */ + /* are experiencing signal problems, you might want to look */ + /* there. raj 11/94 */ + start_timer(test_time); + } + else { + /* The tester wanted to send a number of bytes. */ + bytes_remaining = test_bytes; + times_up = 1; + } + + /* The cpu_start routine will grab the current time and possibly */ + /* value of the idle counter for later use in measuring cpu */ + /* utilization and/or service demand and thruput. */ + + cpu_start(local_cpu_usage); + +#ifdef WANT_INTERVALS + if ((interval_burst) || (demo_mode)) { + /* zero means that we never pause, so we never should need the */ + /* interval timer, unless we are in demo_mode */ + start_itimer(interval_wate); + } + interval_count = interval_burst; + /* get the signal set for the call to sigsuspend */ + if (sigprocmask(SIG_BLOCK, (sigset_t *)NULL, &signal_set) != 0) { + fprintf(where, + "send_sctp_stream: unable to get sigmask errno %d\n", + errno); + fflush(where); + exit(1); + } +#endif /* WANT_INTERVALS */ + +#ifdef DIRTY + /* initialize the random number generator for putting dirty stuff */ + /* into the send buffer. raj */ + srand((int) getpid()); +#endif + + /* before we start, initialize a few variables */ + + /* We use an "OR" to control test execution. When the test is */ + /* controlled by time, the byte count check will always return false. */ + /* When the test is controlled by byte count, the time test will */ + /* always return false. When the test is finished, the whole */ + /* expression will go false and we will stop sending data. */ + + while ((!times_up) || (bytes_remaining > 0)) { + +#ifdef DIRTY + /* we want to dirty some number of consecutive integers in the buffer */ + /* we are about to send. we may also want to bring some number of */ + /* them cleanly into the cache. The clean ones will follow any dirty */ + /* ones into the cache. at some point, we might want to replace */ + /* the rand() call with something from a table to reduce our call */ + /* overhead during the test, but it is not a high priority item. */ + message_int_ptr = (int *)(send_ring->buffer_ptr); + for (i = 0; i < loc_dirty_count; i++) { + *message_int_ptr = rand(); + message_int_ptr++; + } + for (i = 0; i < loc_clean_count; i++) { + loc_dirty_count = *message_int_ptr; + message_int_ptr++; + } +#endif /* DIRTY */ + +#ifdef WANT_HISTOGRAM + /* timestamp just before we go into send and then again just after */ + /* we come out raj 8/94 */ + HIST_timestamp(&time_one); +#endif /* WANT_HISTOGRAM */ + + while ((len=sctp_sendmsg(send_socket, + send_ring->buffer_ptr, send_size, + NULL, 0, + 0, 0, 0, 0, 0)) != send_size) { + if (non_block && errno == EAGAIN) + continue; + else if ((len >=0) || SOCKET_EINTR(len)) { + /* the test was interrupted, must be the end of test */ + timed_out = 1; + break; + } + perror("netperf: data send error"); + printf("len was %d\n",len); + exit(1); + } + + if (timed_out) + break; /* we timed out durint sendmsg, done with test */ + +#ifdef WANT_HISTOGRAM + /* timestamp the exit from the send call and update the histogram */ + HIST_timestamp(&time_two); + HIST_add(time_hist,delta_micro(&time_one,&time_two)); +#endif /* WANT_HISTOGRAM */ + +#ifdef WANT_INTERVALS + if (demo_mode) { + units_this_tick += send_size; + } + /* in this case, the interval count is the count-down couter */ + /* to decide to sleep for a little bit */ + if ((interval_burst) && (--interval_count == 0)) { + /* call sigsuspend and wait for the interval timer to get us */ + /* out */ + if (debug > 1) { + fprintf(where,"about to suspend\n"); + fflush(where); + } + if (sigsuspend(&signal_set) == EFAULT) { + fprintf(where, + "send_sctp_stream: fault with sigsuspend.\n"); + fflush(where); + exit(1); + } + interval_count = interval_burst; + } +#endif /* WANT_INTERVALS */ + + /* now we want to move our pointer to the next position in the */ + /* data buffer...we may also want to wrap back to the "beginning" */ + /* of the bufferspace, so we will mod the number of messages sent */ + /* by the send width, and use that to calculate the offset to add */ + /* to the base pointer. */ + nummessages++; + send_ring = send_ring->next; + if (bytes_remaining) { + bytes_remaining -= send_size; + } + } + + /* The test is over. Flush the buffers to the remote end. We do a */ + /* graceful release to insure that all data has been taken by the */ + /* remote. */ + + /* but first, if the verbosity is greater than 1, find-out what */ + /* the sctp maximum segment_size was (if possible) */ + if (verbosity > 1) { + sctp_mss = -1; + get_sctp_info(send_socket, &sctp_mss); + } + + shutdown(send_socket, SHUT_WR); + + /* The test server will signal to us when it wants to shutdown. + * In blocking mode, we can call recvmsg. In non-blocking + * mode, we need to select on the socket for reading. + * We'll assume that all returns are succefull + */ + if (non_block) { + fd_set readfds; + + FD_ZERO(&readfds); + FD_SET(send_socket, &readfds); + select(send_socket+1, &readfds, NULL, NULL, NULL); + } else { + sctp_recvmsg(send_socket, send_ring->buffer_ptr, send_size, NULL, + 0, NULL, 0); + } + + /* this call will always give us the elapsed time for the test, and */ + /* will also store-away the necessaries for cpu utilization */ + + cpu_stop(local_cpu_usage,&elapsed_time); /* was cpu being */ + /* measured and how */ + /* long did we really */ + /* run? */ + + /* we are finished with the socket, so close it to prevent hitting */ + /* the limit on maximum open files. */ + close(send_socket); + + /* Get the statistics from the remote end. The remote will have */ + /* calculated service demand and all those interesting things. If it */ + /* wasn't supposed to care, it will return obvious values. */ + + recv_response(); + if (!netperf_response.content.serv_errno) { + if (debug) + fprintf(where,"remote results obtained\n"); + } + else { + Set_errno(netperf_response.content.serv_errno); + fprintf(where, + "netperf: remote error %d", + netperf_response.content.serv_errno); + perror(""); + fflush(where); + + exit(1); + } + + /* We now calculate what our thruput was for the test. In the future, */ + /* we may want to include a calculation of the thruput measured by */ + /* the remote, but it should be the case that for a sctp stream test, */ + /* that the two numbers should be *very* close... We calculate */ + /* bytes_sent regardless of the way the test length was controlled. */ + /* If it was time, we needed to, and if it was by bytes, the user may */ + /* have specified a number of bytes that wasn't a multiple of the */ + /* send_size, so we really didn't send what he asked for ;-) */ + + bytes_sent = ntohd(sctp_stream_result->bytes_received); + + thruput = (double) calc_thruput(bytes_sent); + + if (local_cpu_usage || remote_cpu_usage) { + /* We must now do a little math for service demand and cpu */ + /* utilization for the system(s) */ + /* Of course, some of the information might be bogus because */ + /* there was no idle counter in the kernel(s). We need to make */ + /* a note of this for the user's benefit...*/ + if (local_cpu_usage) { + + local_cpu_utilization = calc_cpu_util(0.0); + local_service_demand = calc_service_demand(bytes_sent, + 0.0, + 0.0, + 0); + } + else { + local_cpu_utilization = (float) -1.0; + local_service_demand = (float) -1.0; + } + + if (remote_cpu_usage) { + + remote_cpu_utilization = sctp_stream_result->cpu_util; + remote_service_demand = calc_service_demand(bytes_sent, + 0.0, + remote_cpu_utilization, + sctp_stream_result->num_cpus); + } + else { + remote_cpu_utilization = (float) -1.0; + remote_service_demand = (float) -1.0; + } + } + else { + /* we were not measuring cpu, for the confidence stuff, we */ + /* should make it -1.0 */ + local_cpu_utilization = (float) -1.0; + local_service_demand = (float) -1.0; + remote_cpu_utilization = (float) -1.0; + remote_service_demand = (float) -1.0; + } + + /* at this point, we want to calculate the confidence information. */ + /* if debugging is on, calculate_confidence will print-out the */ + /* parameters we pass it */ + + calculate_confidence(confidence_iteration, + elapsed_time, + thruput, + local_cpu_utilization, + remote_cpu_utilization, + local_service_demand, + remote_service_demand); + + + confidence_iteration++; + } + + /* at this point, we have finished making all the runs that we */ + /* will be making. so, we should extract what the calcuated values */ + /* are for all the confidence stuff. we could make the values */ + /* global, but that seemed a little messy, and it did not seem worth */ + /* all the mucking with header files. so, we create a routine much */ + /* like calcualte_confidence, which just returns the mean values. */ + /* raj 11/94 */ + + retrieve_confident_values(&elapsed_time, + &thruput, + &local_cpu_utilization, + &remote_cpu_utilization, + &local_service_demand, + &remote_service_demand); + + /* We are now ready to print all the information. If the user */ + /* has specified zero-level verbosity, we will just print the */ + /* local service demand, or the remote service demand. If the */ + /* user has requested verbosity level 1, he will get the basic */ + /* "streamperf" numbers. If the user has specified a verbosity */ + /* of greater than 1, we will display a veritable plethora of */ + /* background information from outside of this block as it it */ + /* not cpu_measurement specific... */ + + if (confidence < 0) { + /* we did not hit confidence, but were we asked to look for it? */ + if (iteration_max > 1) { + display_confidence(); + } + } + + if (local_cpu_usage || remote_cpu_usage) { + local_cpu_method = format_cpu_method(cpu_method); + remote_cpu_method = format_cpu_method(sctp_stream_result->cpu_method); + + switch (verbosity) { + case 0: + if (local_cpu_usage) { + fprintf(where, + cpu_fmt_0, + local_service_demand, + local_cpu_method); + } + else { + fprintf(where, + cpu_fmt_0, + remote_service_demand, + remote_cpu_method); + } + break; + case 1: + case 2: + if (print_headers) { + fprintf(where, + cpu_title, + format_units(), + local_cpu_method, + remote_cpu_method); + } + + fprintf(where, + cpu_fmt_1, /* the format string */ + rsr_size, /* remote recvbuf size */ + lss_size, /* local sendbuf size */ + send_size, /* how large were the sends */ + elapsed_time, /* how long was the test */ + thruput, /* what was the xfer rate */ + local_cpu_utilization, /* local cpu */ + remote_cpu_utilization, /* remote cpu */ + local_service_demand, /* local service demand */ + remote_service_demand); /* remote service demand */ + break; + } + } + else { + /* The tester did not wish to measure service demand. */ + + switch (verbosity) { + case 0: + fprintf(where, + tput_fmt_0, + thruput); + break; + case 1: + case 2: + if (print_headers) { + fprintf(where,tput_title,format_units()); + } + fprintf(where, + tput_fmt_1, /* the format string */ + rsr_size, /* remote recvbuf size */ + lss_size, /* local sendbuf size */ + send_size, /* how large were the sends */ + elapsed_time, /* how long did it take */ + thruput);/* how fast did it go */ + break; + } + } + + /* it would be a good thing to include information about some of the */ + /* other parameters that may have been set for this test, but at the */ + /* moment, I do not wish to figure-out all the formatting, so I will */ + /* just put this comment here to help remind me that it is something */ + /* that should be done at a later time. */ + + if (verbosity > 1) { + /* The user wanted to know it all, so we will give it to him. */ + /* This information will include as much as we can find about */ + /* sctp statistics, the alignments of the sends and receives */ + /* and all that sort of rot... */ + + /* this stuff needs to be worked-out in the presence of confidence */ + /* intervals and multiple iterations of the test... raj 11/94 */ + + fprintf(where, + ksink_fmt, + "Bytes", + "Bytes", + "Bytes", + local_send_align, + remote_recv_align, + local_send_offset, + remote_recv_offset, + bytes_sent, + bytes_sent / (double)nummessages, + nummessages, + bytes_sent / (double)sctp_stream_result->recv_calls, + sctp_stream_result->recv_calls); + fprintf(where, + ksink_fmt2, + sctp_mss); + fflush(where); +#ifdef WANT_HISTOGRAM + fprintf(where,"\n\nHistogram of time spent in send() call.\n"); + fflush(where); + HIST_report(time_hist); +#endif /* WANT_HISTOGRAM */ + } + +} + + + + +/* This is the server-side routine for the sctp stream test. It is */ +/* implemented as one routine. I could break things-out somewhat, but */ +/* didn't feel it was necessary. */ + +void +recv_sctp_stream() +{ + + struct sockaddr_in myaddr_in; /* needed to get port number */ + struct sockaddr_storage peeraddr; /* used in accept */ + int s_listen,s_data; + int addrlen; + int len; + unsigned int receive_calls; + float elapsed_time; + double bytes_received; + + struct ring_elt *recv_ring; + + struct addrinfo *local_res; + char local_name[BUFSIZ]; + char port_buffer[PORTBUFSIZE]; + int msg_flags = 0; + +#ifdef DIRTY + int *message_int_ptr; + int dirty_count; + int clean_count; + int i; +#endif + +#ifdef DO_SELECT + fd_set readfds; + struct timeval timeout; +#endif /* DO_SELECT */ + + struct sctp_stream_request_struct *sctp_stream_request; + struct sctp_stream_response_struct *sctp_stream_response; + struct sctp_stream_results_struct *sctp_stream_results; + +#ifdef DO_SELECT + FD_ZERO(&readfds); + timeout.tv_sec = 1; + timeout.tv_usec = 0; +#endif /* DO_SELECT */ + + sctp_stream_request = + (struct sctp_stream_request_struct *)netperf_request.content.test_specific_data; + sctp_stream_response = + (struct sctp_stream_response_struct *)netperf_response.content.test_specific_data; + sctp_stream_results = + (struct sctp_stream_results_struct *)netperf_response.content.test_specific_data; + + if (debug) { + fprintf(where,"netserver: recv_sctp_stream: entered...\n"); + fflush(where); + } + + /* We want to set-up the listen socket with all the desired */ + /* parameters and then let the initiator know that all is ready. If */ + /* socket size defaults are to be used, then the initiator will have */ + /* sent us 0's. If the socket sizes cannot be changed, then we will */ + /* send-back what they are. If that information cannot be determined, */ + /* then we send-back -1's for the sizes. If things go wrong for any */ + /* reason, we will drop back ten yards and punt. */ + + /* If anything goes wrong, we want the remote to know about it. It */ + /* would be best if the error that the remote reports to the user is */ + /* the actual error we encountered, rather than some bogus unexpected */ + /* response type message. */ + + if (debug) { + fprintf(where,"recv_sctp_stream: setting the response type...\n"); + fflush(where); + } + + netperf_response.content.response_type = SCTP_STREAM_RESPONSE; + + if (debug) { + fprintf(where,"recv_sctp_stream: the response type is set...\n"); + fflush(where); + } + + /* We now alter the message_ptr variable to be at the desired */ + /* alignment with the desired offset. */ + + if (debug) { + fprintf(where,"recv_sctp_stream: requested alignment of %d\n", + sctp_stream_request->recv_alignment); + fflush(where); + } + + /* create_data_socket expects to find some things in the global */ + /* variables, so set the globals based on the values in the request. */ + /* once the socket has been created, we will set the response values */ + /* based on the updated value of those globals. raj 7/94 */ + lss_size_req = sctp_stream_request->send_buf_size; + lsr_size_req = sctp_stream_request->recv_buf_size; + loc_nodelay = sctp_stream_request->no_delay; + loc_rcvavoid = sctp_stream_request->so_rcvavoid; + loc_sndavoid = sctp_stream_request->so_sndavoid; + non_block = sctp_stream_request->non_blocking; + + set_hostname_and_port(local_name, + port_buffer, + nf_to_af(sctp_stream_request->ipfamily), + sctp_stream_request->port); + + local_res = complete_addrinfo(local_name, + local_name, + port_buffer, + nf_to_af(sctp_stream_request->ipfamily), + SOCK_STREAM, + IPPROTO_SCTP, + 0); + + s_listen = create_data_socket(local_res); + + if (s_listen < 0) { + netperf_response.content.serv_errno = errno; + send_response(); + exit(1); + } + + /* what sort of sizes did we end-up with? */ + if (sctp_stream_request->receive_size == 0) { + if (lsr_size > 0) { + recv_size = lsr_size; + } + else { + recv_size = 4096; + } + } + else { + recv_size = sctp_stream_request->receive_size; + } + + /* we want to set-up our recv_ring in a manner analagous to what we */ + /* do on the sending side. this is more for the sake of symmetry */ + /* than for the needs of say copy avoidance, but it might also be */ + /* more realistic - this way one could conceivably go with a */ + /* double-buffering scheme when taking the data an putting it into */ + /* the filesystem or something like that. raj 7/94 */ + + if (recv_width == 0) { + recv_width = (lsr_size/recv_size) + 1; + if (recv_width == 1) recv_width++; + } + + recv_ring = allocate_buffer_ring(recv_width, + recv_size, + sctp_stream_request->recv_alignment, + sctp_stream_request->recv_offset); + + if (debug) { + fprintf(where,"recv_sctp_stream: set recv_size = %d, align = %d, offset = %d.\n", + recv_size, sctp_stream_request->recv_alignment, + sctp_stream_request->recv_offset); + fflush(where); + } + + /* now get the port number assigned by the system */ + addrlen = sizeof(myaddr_in); + if (getsockname(s_listen, + (struct sockaddr *)&myaddr_in, + &addrlen) == -1){ + netperf_response.content.serv_errno = errno; + close(s_listen); + send_response(); + + exit(1); + } + + /* Now myaddr_in contains the port and the internet address this is */ + /* returned to the sender also implicitly telling the sender that the */ + /* socket buffer sizing has been done. */ + + sctp_stream_response->data_port_number = (int) ntohs(myaddr_in.sin_port); + netperf_response.content.serv_errno = 0; + + /* But wait, there's more. If the initiator wanted cpu measurements, */ + /* then we must call the calibrate routine, which will return the max */ + /* rate back to the initiator. If the CPU was not to be measured, or */ + /* something went wrong with the calibration, we will return a -1 to */ + /* the initiator. */ + + sctp_stream_response->cpu_rate = (float)0.0; /* assume no cpu */ + if (sctp_stream_request->measure_cpu) { + sctp_stream_response->measure_cpu = 1; + sctp_stream_response->cpu_rate = + calibrate_local_cpu(sctp_stream_request->cpu_rate); + } + else { + sctp_stream_response->measure_cpu = 0; + } + + /* before we send the response back to the initiator, pull some of */ + /* the socket parms from the globals */ + sctp_stream_response->send_buf_size = lss_size; + sctp_stream_response->recv_buf_size = lsr_size; + sctp_stream_response->no_delay = loc_nodelay; + sctp_stream_response->so_rcvavoid = loc_rcvavoid; + sctp_stream_response->so_sndavoid = loc_sndavoid; + sctp_stream_response->receive_size = recv_size; + + /* Now, let's set-up the socket to listen for connections */ + if (listen(s_listen, 5) == -1) { + netperf_response.content.serv_errno = errno; + close(s_listen); + send_response(); + + exit(1); + } + + send_response(); + + addrlen = sizeof(peeraddr); + + if ((s_data = accept(s_listen, + (struct sockaddr *)&peeraddr, + &addrlen)) == INVALID_SOCKET) { + /* Let's just punt. The remote will be given some information */ + close(s_listen); + exit(1); + } + + sctp_enable_events(s_data, SCTP_ASSOC_CHANGE_EV | SCTP_SHUTDOWN_EV); + + /* now that we are connected, mark the socket as non-blocking */ + if (non_block) { + fprintf(where, "setting socket as nonblocking\n"); + fflush(where); + if (!set_nonblock(s_data)) { + close(s_data); + exit(1); + } + } + +#ifdef KLUDGE_SOCKET_OPTIONS + /* this is for those systems which *INCORRECTLY* fail to pass */ + /* attributes across an accept() call. Including this goes against */ + /* my better judgement :( raj 11/95 */ + + kludge_socket_options(s_data); + +#endif /* KLUDGE_SOCKET_OPTIONS */ + + /* Now it's time to start receiving data on the connection. We will */ + /* first grab the apropriate counters and then start grabbing. */ + + cpu_start(sctp_stream_request->measure_cpu); + + /* The loop will exit when the sender does a shutdown, which will */ + /* return a length of zero */ + +#ifdef DIRTY + /* we want to dirty some number of consecutive integers in the buffer */ + /* we are about to recv. we may also want to bring some number of */ + /* them cleanly into the cache. The clean ones will follow any dirty */ + /* ones into the cache. */ + + dirty_count = sctp_stream_request->dirty_count; + clean_count = sctp_stream_request->clean_count; + message_int_ptr = (int *)recv_ring->buffer_ptr; + for (i = 0; i < dirty_count; i++) { + *message_int_ptr = rand(); + message_int_ptr++; + } + for (i = 0; i < clean_count; i++) { + dirty_count = *message_int_ptr; + message_int_ptr++; + } +#endif /* DIRTY */ + + bytes_received = 0; + receive_calls = 0; + + while ((len = sctp_recvmsg(s_data, + recv_ring->buffer_ptr, recv_size, + NULL, 0, NULL, &msg_flags)) != 0) { + if (len == SOCKET_ERROR) { + if (non_block && errno == EAGAIN) { + if (debug){ + fprintf(where, + "recv_sctp_stream: sctp_recvmsg timed out, trying again\n"); + fflush(where); + } + Set_errno(0); + continue; + } + if (debug) { + fprintf(where, + "recv_sctp_stream: sctp_recvmsg error %d, exiting", + errno); + fflush(where); + } + netperf_response.content.serv_errno = errno; + send_response(); + close(s_data); + exit(1); + } + + if (msg_flags & MSG_NOTIFICATION) { + msg_flags = 0; + if (debug) { + fprintf(where, + "recv_sctp_stream: Got notification... processing\n"); + fflush(where); + } + if (sctp_process_event(s_data, recv_ring->buffer_ptr) == SCTP_CLOSE) + break; /* break out of the recvmsg loop */ + + continue; + } + + bytes_received += len; + receive_calls++; + + /* more to the next buffer in the recv_ring */ + recv_ring = recv_ring->next; + +#ifdef PAUSE + sleep(1); +#endif /* PAUSE */ + +#ifdef DIRTY + message_int_ptr = (int *)(recv_ring->buffer_ptr); + for (i = 0; i < dirty_count; i++) { + *message_int_ptr = rand(); + message_int_ptr++; + } + for (i = 0; i < clean_count; i++) { + dirty_count = *message_int_ptr; + message_int_ptr++; + } +#endif /* DIRTY */ + +#ifdef DO_SELECT + FD_SET(s_data,&readfds); + select(s_data+1,&readfds,NULL,NULL,&timeout); +#endif /* DO_SELECT */ + + } + + /* perform a shutdown to signal the sender that */ + /* we have received all the data sent. raj 4/93 */ + + if (close(s_data) == -1) { + netperf_response.content.serv_errno = errno; + send_response(); + exit(1); + } + + cpu_stop(sctp_stream_request->measure_cpu,&elapsed_time); + + /* send the results to the sender */ + + if (debug) { + fprintf(where, + "recv_sctp_stream: got %g bytes\n", + bytes_received); + fprintf(where, + "recv_sctp_stream: got %d recvs\n", + receive_calls); + fflush(where); + } + + sctp_stream_results->bytes_received = htond(bytes_received); + sctp_stream_results->elapsed_time = elapsed_time; + sctp_stream_results->recv_calls = receive_calls; + + if (sctp_stream_request->measure_cpu) { + sctp_stream_results->cpu_util = calc_cpu_util(0.0); + }; + + if (debug) { + fprintf(where, + "recv_sctp_stream: test complete, sending results.\n"); + fprintf(where, + " bytes_received %g receive_calls %d\n", + bytes_received, + receive_calls); + fprintf(where, + " len %d\n", + len); + fflush(where); + } + + sctp_stream_results->cpu_method = cpu_method; + sctp_stream_results->num_cpus = lib_num_loc_cpus; + send_response(); + + /* we are now done with the sockets */ + close(s_listen); + +} + + +/* This routine implements the SCTP unidirectional data transfer test */ +/* (a.k.a. stream) for the sockets interface. It receives its */ +/* parameters via global variables from the shell and writes its */ +/* output to the standard output. */ + + +void +send_sctp_stream_1toMany(remote_host) +char remote_host[]; +{ + + char *tput_title = "\ +Recv Send Send \n\ +Socket Socket Message Elapsed \n\ +Size Size Size Time Throughput \n\ +bytes bytes bytes secs. %s/sec \n\n"; + + char *tput_fmt_0 = + "%7.2f\n"; + + char *tput_fmt_1 = + "%6d %6d %6d %-6.2f %7.2f \n"; + + char *cpu_title = "\ +Recv Send Send Utilization Service Demand\n\ +Socket Socket Message Elapsed Send Recv Send Recv\n\ +Size Size Size Time Throughput local remote local remote\n\ +bytes bytes bytes secs. %-8.8s/s %% %c %% %c us/KB us/KB\n\n"; + + char *cpu_fmt_0 = + "%6.3f %c\n"; + + char *cpu_fmt_1 = + "%6d %6d %6d %-6.2f %7.2f %-6.2f %-6.2f %-6.3f %-6.3f\n"; + + char *ksink_fmt = "\n\ +Alignment Offset %-8.8s %-8.8s Sends %-8.8s Recvs\n\ +Local Remote Local Remote Xfered Per Per\n\ +Send Recv Send Recv Send (avg) Recv (avg)\n\ +%5d %5d %5d %5d %6.4g %6.2f %6d %6.2f %6d\n"; + + char *ksink_fmt2 = "\n\ +Maximum\n\ +Segment\n\ +Size (bytes)\n\ +%6d\n"; + + + float elapsed_time; + +#ifdef WANT_INTERVALS + int interval_count; + sigset_t signal_set; +#endif + + /* what we want is to have a buffer space that is at least one */ + /* send-size greater than our send window. this will insure that we */ + /* are never trying to re-use a buffer that may still be in the hands */ + /* of the transport. This buffer will be malloc'd after we have found */ + /* the size of the local senc socket buffer. We will want to deal */ + /* with alignment and offset concerns as well. */ + +#ifdef DIRTY + int *message_int_ptr; +#endif + + struct ring_elt *send_ring; + + int len; + unsigned int nummessages = 0; + int *send_socket; + int bytes_remaining; + int sctp_mss; + + /* with links like fddi, one can send > 32 bits worth of bytes */ + /* during a test... ;-) at some point, this should probably become a */ + /* 64bit integral type, but those are not entirely common yet */ + double bytes_sent = 0.0; + +#ifdef DIRTY + int i; +#endif /* DIRTY */ + int j; + + float local_cpu_utilization; + float local_service_demand; + float remote_cpu_utilization; + float remote_service_demand; + + double thruput; + + struct addrinfo *remote_res; + struct addrinfo *local_res; + struct addrinfo *last_remote_res; + struct addrinfo *last_local_res; + + struct sctp_stream_request_struct *sctp_stream_request; + struct sctp_stream_response_struct *sctp_stream_response; + struct sctp_stream_results_struct *sctp_stream_result; + + sctp_stream_request = + (struct sctp_stream_request_struct *)netperf_request.content.test_specific_data; + sctp_stream_response = + (struct sctp_stream_response_struct *)netperf_response.content.test_specific_data; + sctp_stream_result = + (struct sctp_stream_results_struct *)netperf_response.content.test_specific_data; + +#ifdef WANT_HISTOGRAM + time_hist = HIST_new(); +#endif /* WANT_HISTOGRAM */ + + complete_addrinfos(&remote_res, + &local_res, + remote_host, + SOCK_SEQPACKET, + IPPROTO_SCTP, + 0); + + if ( print_headers ) { + print_top_test_header("SCTP 1-TO-MANY STREAM TEST",local_res,remote_res); + } + + send_ring = NULL; + confidence_iteration = 1; + init_stat(); + + send_socket = malloc(sizeof (int) * num_associations); + if (send_socket == NULL) { + fprintf(where, "send_sctp_stream_1toMany: failed to allocation sockets!\n"); + exit(1); + } + + /* we have a great-big while loop which controls the number of times */ + /* we run a particular test. this is for the calculation of a */ + /* confidence interval (I really should have stayed awake during */ + /* probstats :). If the user did not request confidence measurement */ + /* (no confidence is the default) then we will only go though the */ + /* loop once. the confidence stuff originates from the folks at IBM */ + + while (((confidence < 0) && (confidence_iteration < iteration_max)) || + (confidence_iteration <= iteration_min)) { + + int j=0; + int timed_out = 0; + + + /* initialize a few counters. we have to remember that we might be */ + /* going through the loop more than once. */ + + nummessages = 0; + bytes_sent = 0.0; + times_up = 0; + + /* at this point, we have either retrieved the socket buffer sizes, */ + /* or have tried to set them, so now, we may want to set the send */ + /* size based on that (because the user either did not use a -m */ + /* option, or used one with an argument of 0). If the socket buffer */ + /* size is not available, we will set the send size to 4KB - no */ + /* particular reason, just arbitrary... */ + if (send_size == 0) { + if (lss_size > 0) { + send_size = lss_size; + } + else { + send_size = 4096; + } + } + + /* set-up the data buffer ring with the requested alignment and offset. */ + /* note also that we have allocated a quantity */ + /* of memory that is at least one send-size greater than our socket */ + /* buffer size. We want to be sure that there are at least two */ + /* buffers allocated - this can be a bit of a problem when the */ + /* send_size is bigger than the socket size, so we must check... the */ + /* user may have wanted to explicitly set the "width" of our send */ + /* buffers, we should respect that wish... */ + if (send_width == 0) { + send_width = (lss_size/send_size) + 1; + if (send_width == 1) send_width++; + } + + if (send_ring == NULL) { + /* only allocate the send ring once. this is a networking test, */ + /* not a memory allocation test. this way, we do not need a */ + /* deallocate_buffer_ring() routine, and I don't feel like */ + /* writing one anyway :) raj 11/94 */ + send_ring = allocate_buffer_ring(send_width, + send_size, + local_send_align, + local_send_offset); + } + + /* If the user has requested cpu utilization measurements, we must */ + /* calibrate the cpu(s). We will perform this task within the tests */ + /* themselves. If the user has specified the cpu rate, then */ + /* calibrate_local_cpu will return rather quickly as it will have */ + /* nothing to do. If local_cpu_rate is zero, then we will go through */ + /* all the "normal" calibration stuff and return the rate back. */ + + if (local_cpu_usage) { + local_cpu_rate = calibrate_local_cpu(local_cpu_rate); + } + + /* Tell the remote end to do a listen. The server alters the socket */ + /* paramters on the other side at this point, hence the reason for */ + /* all the values being passed in the setup message. If the user did */ + /* not specify any of the parameters, they will be passed as 0, which */ + /* will indicate to the remote that no changes beyond the system's */ + /* default should be used. Alignment is the exception, it will */ + /* default to 1, which will be no alignment alterations. */ + + netperf_request.content.request_type = DO_SCTP_STREAM_MANY; + sctp_stream_request->send_buf_size = rss_size_req; + sctp_stream_request->recv_buf_size = rsr_size_req; + sctp_stream_request->receive_size = recv_size; + sctp_stream_request->no_delay = rem_nodelay; + sctp_stream_request->recv_alignment = remote_recv_align; + sctp_stream_request->recv_offset = remote_recv_offset; + sctp_stream_request->measure_cpu = remote_cpu_usage; + sctp_stream_request->cpu_rate = remote_cpu_rate; + if (test_time) { + sctp_stream_request->test_length = test_time; + } + else { + if (msg_count) + test_bytes = send_size * msg_count; + + sctp_stream_request->test_length = test_bytes*num_associations; + } + sctp_stream_request->so_rcvavoid = rem_rcvavoid; + sctp_stream_request->so_sndavoid = rem_sndavoid; +#ifdef DIRTY + sctp_stream_request->dirty_count = rem_dirty_count; + sctp_stream_request->clean_count = rem_clean_count; +#endif /* DIRTY */ + sctp_stream_request->port = (atoi(remote_data_port)); + sctp_stream_request->ipfamily = af_to_nf(remote_res->ai_family); + sctp_stream_request->non_blocking = non_block; + + + if (debug > 1) { + fprintf(where, + "netperf: send_sctp_stream_1toMany: requesting sctp stream test\n"); + } + + send_request(); + + /* The response from the remote will contain all of the relevant */ + /* socket parameters for this test type. We will put them back into */ + /* the variables here so they can be displayed if desired. The */ + /* remote will have calibrated CPU if necessary, and will have done */ + /* all the needed set-up we will have calibrated the cpu locally */ + /* before sending the request, and will grab the counter value right*/ + /* after the connect returns. The remote will grab the counter right*/ + /* after the accept call. This saves the hassle of extra messages */ + /* being sent for the sctp tests. */ + + recv_response(); + + if (!netperf_response.content.serv_errno) { + if (debug) + fprintf(where,"remote listen done.\n"); + rsr_size = sctp_stream_response->recv_buf_size; + rss_size = sctp_stream_response->send_buf_size; + rem_nodelay = sctp_stream_response->no_delay; + remote_cpu_usage= sctp_stream_response->measure_cpu; + remote_cpu_rate = sctp_stream_response->cpu_rate; + + /* we have to make sure that the server port number is in */ + /* network order */ + set_port_number(remote_res, (unsigned short)sctp_stream_response->data_port_number); + rem_rcvavoid = sctp_stream_response->so_rcvavoid; + rem_sndavoid = sctp_stream_response->so_sndavoid; + } + else { + Set_errno(netperf_response.content.serv_errno); + fprintf(where, + "netperf: remote error %d", + netperf_response.content.serv_errno); + perror(""); + fflush(where); + + exit(1); + } + + /*set up the the array of data sockets and connect them to the server */ + + for (j = 0; j < num_associations; j++) { + send_socket[j] = create_data_socket(local_res); + + if (send_socket[j] < 0){ + perror("netperf: send_sctp_stream_1toMany: sctp stream data socket"); + exit(1); + } + + if (debug) { + fprintf(where,"send_sctp_stream_1toMany: send_socket obtained...\n"); + } + + /*Connect up to the remote port on the data socket */ + if (connect(send_socket[j], + remote_res->ai_addr, + remote_res->ai_addrlen) == INVALID_SOCKET){ + perror("netperf: send_sctp_stream_1toMany: data socket connect failed"); + exit(1); + } + + /* Do it after connect is successfull, so that we don't see COMM_UP */ + sctp_enable_events(send_socket[j], SCTP_ASSOC_CHANGE_EV); + + if (non_block) { + /* now that we are connected, mark the socket as non-blocking */ + if (!set_nonblock(send_socket[j])) { + perror("netperf: fcntl"); + exit(1); + } + } + } + + /* Data Socket set-up is finished. If there were problems, either */ + /* the connect would have failed, or the previous response would */ + /* have indicated a problem. I failed to see the value of the */ + /* extra message after the accept on the remote. If it failed, */ + /* we'll see it here. If it didn't, we might as well start pumping */ + /* data. */ + + /* Set-up the test end conditions. For a stream test, they can be */ + /* either time or byte-count based. */ + + if (test_time) { + /* The user wanted to end the test after a period of time. */ + times_up = 0; + bytes_remaining = 0; + /* in previous revisions, we had the same code repeated throught */ + /* all the test suites. this was unnecessary, and meant more */ + /* work for me when I wanted to switch to POSIX signals, so I */ + /* have abstracted this out into a routine in netlib.c. if you */ + /* are experiencing signal problems, you might want to look */ + /* there. raj 11/94 */ + start_timer(test_time); + } + else { + /* The tester wanted to send a number of bytes. */ + bytes_remaining = test_bytes * num_associations; + times_up = 1; + } + + /* The cpu_start routine will grab the current time and possibly */ + /* value of the idle counter for later use in measuring cpu */ + /* utilization and/or service demand and thruput. */ + + cpu_start(local_cpu_usage); + +#ifdef WANT_INTERVALS + if ((interval_burst) || (demo_mode)) { + /* zero means that we never pause, so we never should need the */ + /* interval timer, unless we are in demo_mode */ + start_itimer(interval_wate); + } + interval_count = interval_burst; + /* get the signal set for the call to sigsuspend */ + if (sigprocmask(SIG_BLOCK, (sigset_t *)NULL, &signal_set) != 0) { + fprintf(where, + "send_sctp_stream_1toMany: unable to get sigmask errno %d\n", + errno); + fflush(where); + exit(1); + } +#endif /* WANT_INTERVALS */ + +#ifdef DIRTY + /* initialize the random number generator for putting dirty stuff */ + /* into the send buffer. raj */ + srand((int) getpid()); +#endif + + /* before we start, initialize a few variables */ + + /* We use an "OR" to control test execution. When the test is */ + /* controlled by time, the byte count check will always return false. */ + /* When the test is controlled by byte count, the time test will */ + /* always return false. When the test is finished, the whole */ + /* expression will go false and we will stop sending data. */ + + while ((!times_up) || (bytes_remaining > 0)) { + +#ifdef DIRTY + /* we want to dirty some number of consecutive integers in the buffer */ + /* we are about to send. we may also want to bring some number of */ + /* them cleanly into the cache. The clean ones will follow any dirty */ + /* ones into the cache. at some point, we might want to replace */ + /* the rand() call with something from a table to reduce our call */ + /* overhead during the test, but it is not a high priority item. */ + message_int_ptr = (int *)(send_ring->buffer_ptr); + for (i = 0; i < loc_dirty_count; i++) { + *message_int_ptr = rand(); + message_int_ptr++; + } + for (i = 0; i < loc_clean_count; i++) { + loc_dirty_count = *message_int_ptr; + message_int_ptr++; + } +#endif /* DIRTY */ + +#ifdef WANT_HISTOGRAM + /* timestamp just before we go into send and then again just after */ + /* we come out raj 8/94 */ + gettimeofday(&time_one,NULL); +#endif /* WANT_HISTOGRAM */ + + for (j = 0; j < num_associations; j++) { + + if((len=sctp_sendmsg(send_socket[j], + send_ring->buffer_ptr, + send_size, + (struct sockaddr *)remote_res->ai_addr, + remote_res->ai_addrlen, + 0, 0, 0, 0, 0)) != send_size) { + if ((len >=0) || SOCKET_EINTR(len)) { + /* the test was interrupted, must be the end of test */ + timed_out = 1; + break; + } else if (non_block && errno == EAGAIN) { + j--; /* send again on the same socket */ + Set_errno(0); + continue; + } + perror("netperf: data send error"); + printf("len was %d\n",len); + exit(1); + } + } + + if (timed_out) + break; /* test is over, try next iteration */ + +#ifdef WANT_HISTOGRAM + /* timestamp the exit from the send call and update the histogram */ + gettimeofday(&time_two,NULL); + HIST_add(time_hist,delta_micro(&time_one,&time_two)); +#endif /* WANT_HISTOGRAM */ + +#ifdef WANT_INTERVALS + if (demo_mode) { + units_this_tick += send_size; + } + /* in this case, the interval count is the count-down couter */ + /* to decide to sleep for a little bit */ + if ((interval_burst) && (--interval_count == 0)) { + /* call sigsuspend and wait for the interval timer to get us */ + /* out */ + if (debug > 1) { + fprintf(where,"about to suspend\n"); + fflush(where); + } + if (sigsuspend(&signal_set) == EFAULT) { + fprintf(where, + "send_sctp_stream_1toMany: fault with sigsuspend.\n"); + fflush(where); + exit(1); + } + interval_count = interval_burst; + } +#endif /* WANT_INTERVALS */ + + /* now we want to move our pointer to the next position in the */ + /* data buffer...we may also want to wrap back to the "beginning" */ + /* of the bufferspace, so we will mod the number of messages sent */ + /* by the send width, and use that to calculate the offset to add */ + /* to the base pointer. */ + nummessages++; + send_ring = send_ring->next; + if (bytes_remaining) { + bytes_remaining -= send_size; + } + } + + /* The test is over. Flush the buffers to the remote end. We do a */ + /* graceful release to insure that all data has been taken by the */ + /* remote. */ + + /* but first, if the verbosity is greater than 1, find-out what */ + /* the sctp maximum segment_size was (if possible) */ + if (verbosity > 1) { + sctp_mss = -1; + get_sctp_info(send_socket[0], &sctp_mss); + } + + /* signal the server that we are all done writing, this will + * initiate a shutdonw of one of the associations on the + * server and trigger an event telling the server it's all done + */ + sctp_sendmsg(send_socket[0], NULL, 0, remote_res->ai_addr, + remote_res->ai_addrlen, 0, MSG_EOF, 0, 0, 0); + + + /* The test server will initiate closure of all associations + * when it's done reading. We want a basic mechanism to catch this + * and are using SCTP events for this. + * In blocking mode, we can call recvmsg with the last socket we created. + * In non-blocking mode, we need to select on the socket for reading. + * We'll assume that all returns are succefull and signify + * closure. + * It is sufficient to do this on a single socket in the client. + * We choose to do it on a socket other then the one that send MSG_EOF. + * This means that anything comming in on that socket will be a shutdown. + */ + if (non_block) { + fd_set readfds; + + FD_ZERO(&readfds); + FD_SET(send_socket[num_associations-1], &readfds); + select(send_socket[num_associations-1]+1, &readfds, NULL, NULL, NULL); + } else { + sctp_recvmsg(send_socket[num_associations], send_ring->buffer_ptr, + send_size, NULL, 0, NULL, 0); + } + + /* this call will always give us the elapsed time for the test, and */ + /* will also store-away the necessaries for cpu utilization */ + + cpu_stop(local_cpu_usage,&elapsed_time); /* was cpu being */ + /* measured and how */ + /* long did we really */ + /* run? */ + + /* we are finished with our sockets, so close them to prevent hitting */ + /* the limit on maximum open files. */ + for (j = 0; j < num_associations; j++) + close(send_socket[j]); + + /* Get the statistics from the remote end. The remote will have */ + /* calculated service demand and all those interesting things. If it */ + /* wasn't supposed to care, it will return obvious values. */ + + recv_response(); + if (!netperf_response.content.serv_errno) { + if (debug) + fprintf(where,"remote results obtained\n"); + } + else { + Set_errno(netperf_response.content.serv_errno); + fprintf(where, + "netperf: remote error %d", + netperf_response.content.serv_errno); + perror(""); + fflush(where); + + exit(1); + } + + /* We now calculate what our thruput was for the test. In the future, */ + /* we may want to include a calculation of the thruput measured by */ + /* the remote, but it should be the case that for a sctp stream test, */ + /* that the two numbers should be *very* close... We calculate */ + /* bytes_sent regardless of the way the test length was controlled. */ + /* If it was time, we needed to, and if it was by bytes, the user may */ + /* have specified a number of bytes that wasn't a multiple of the */ + /* send_size, so we really didn't send what he asked for ;-) */ + + bytes_sent = ntohd(sctp_stream_result->bytes_received); + + thruput = (double) calc_thruput(bytes_sent); + + if (local_cpu_usage || remote_cpu_usage) { + /* We must now do a little math for service demand and cpu */ + /* utilization for the system(s) */ + /* Of course, some of the information might be bogus because */ + /* there was no idle counter in the kernel(s). We need to make */ + /* a note of this for the user's benefit...*/ + if (local_cpu_usage) { + + local_cpu_utilization = calc_cpu_util(0.0); + local_service_demand = calc_service_demand(bytes_sent, + 0.0, + 0.0, + 0); + } + else { + local_cpu_utilization = (float) -1.0; + local_service_demand = (float) -1.0; + } + + if (remote_cpu_usage) { + + remote_cpu_utilization = sctp_stream_result->cpu_util; + remote_service_demand = calc_service_demand(bytes_sent, + 0.0, + remote_cpu_utilization, + sctp_stream_result->num_cpus); + } + else { + remote_cpu_utilization = (float) -1.0; + remote_service_demand = (float) -1.0; + } + } + else { + /* we were not measuring cpu, for the confidence stuff, we */ + /* should make it -1.0 */ + local_cpu_utilization = (float) -1.0; + local_service_demand = (float) -1.0; + remote_cpu_utilization = (float) -1.0; + remote_service_demand = (float) -1.0; + } + + /* at this point, we want to calculate the confidence information. */ + /* if debugging is on, calculate_confidence will print-out the */ + /* parameters we pass it */ + + calculate_confidence(confidence_iteration, + elapsed_time, + thruput, + local_cpu_utilization, + remote_cpu_utilization, + local_service_demand, + remote_service_demand); + + + confidence_iteration++; + } + + /* at this point, we have finished making all the runs that we */ + /* will be making. so, we should extract what the calcuated values */ + /* are for all the confidence stuff. we could make the values */ + /* global, but that seemed a little messy, and it did not seem worth */ + /* all the mucking with header files. so, we create a routine much */ + /* like calcualte_confidence, which just returns the mean values. */ + /* raj 11/94 */ + + retrieve_confident_values(&elapsed_time, + &thruput, + &local_cpu_utilization, + &remote_cpu_utilization, + &local_service_demand, + &remote_service_demand); + + /* We are now ready to print all the information. If the user */ + /* has specified zero-level verbosity, we will just print the */ + /* local service demand, or the remote service demand. If the */ + /* user has requested verbosity level 1, he will get the basic */ + /* "streamperf" numbers. If the user has specified a verbosity */ + /* of greater than 1, we will display a veritable plethora of */ + /* background information from outside of this block as it it */ + /* not cpu_measurement specific... */ + + if (confidence < 0) { + /* we did not hit confidence, but were we asked to look for it? */ + if (iteration_max > 1) { + display_confidence(); + } + } + + if (local_cpu_usage || remote_cpu_usage) { + local_cpu_method = format_cpu_method(cpu_method); + remote_cpu_method = format_cpu_method(sctp_stream_result->cpu_method); + + switch (verbosity) { + case 0: + if (local_cpu_usage) { + fprintf(where, + cpu_fmt_0, + local_service_demand, + local_cpu_method); + } + else { + fprintf(where, + cpu_fmt_0, + remote_service_demand, + remote_cpu_method); + } + break; + case 1: + case 2: + if (print_headers) { + fprintf(where, + cpu_title, + format_units(), + local_cpu_method, + remote_cpu_method); + } + + fprintf(where, + cpu_fmt_1, /* the format string */ + rsr_size, /* remote recvbuf size */ + lss_size, /* local sendbuf size */ + send_size, /* how large were the sends */ + elapsed_time, /* how long was the test */ + thruput, /* what was the xfer rate */ + local_cpu_utilization, /* local cpu */ + remote_cpu_utilization, /* remote cpu */ + local_service_demand, /* local service demand */ + remote_service_demand); /* remote service demand */ + break; + } + } + else { + /* The tester did not wish to measure service demand. */ + + switch (verbosity) { + case 0: + fprintf(where, + tput_fmt_0, + thruput); + break; + case 1: + case 2: + if (print_headers) { + fprintf(where,tput_title,format_units()); + } + fprintf(where, + tput_fmt_1, /* the format string */ + rsr_size, /* remote recvbuf size */ + lss_size, /* local sendbuf size */ + send_size, /* how large were the sends */ + elapsed_time, /* how long did it take */ + thruput);/* how fast did it go */ + break; + } + } + + /* it would be a good thing to include information about some of the */ + /* other parameters that may have been set for this test, but at the */ + /* moment, I do not wish to figure-out all the formatting, so I will */ + /* just put this comment here to help remind me that it is something */ + /* that should be done at a later time. */ + + if (verbosity > 1) { + /* The user wanted to know it all, so we will give it to him. */ + /* This information will include as much as we can find about */ + /* sctp statistics, the alignments of the sends and receives */ + /* and all that sort of rot... */ + + /* this stuff needs to be worked-out in the presence of confidence */ + /* intervals and multiple iterations of the test... raj 11/94 */ + + fprintf(where, + ksink_fmt, + "Bytes", + "Bytes", + "Bytes", + local_send_align, + remote_recv_align, + local_send_offset, + remote_recv_offset, + bytes_sent, + bytes_sent / (double)nummessages, + nummessages, + bytes_sent / (double)sctp_stream_result->recv_calls, + sctp_stream_result->recv_calls); + fprintf(where, + ksink_fmt2, + sctp_mss); + fflush(where); +#ifdef WANT_HISTOGRAM + fprintf(where,"\n\nHistogram of time spent in send() call.\n"); + fflush(where); + HIST_report(time_hist); +#endif /* WANT_HISTOGRAM */ + } + +} + + + +/* This is the server-side routine for the sctp stream test. It is */ +/* implemented as one routine. I could break things-out somewhat, but */ +/* didn't feel it was necessary. */ + +void +recv_sctp_stream_1toMany() +{ + + struct sockaddr_in myaddr_in; + int s_recv; + int addrlen; + int len; + unsigned int receive_calls; + float elapsed_time; + double bytes_received; + int msg_flags = 0; + + struct ring_elt *recv_ring; + + struct addrinfo *local_res; + char local_name[BUFSIZ]; + char port_buffer[PORTBUFSIZE]; + +#ifdef DIRTY + int *message_int_ptr; + int dirty_count; + int clean_count; + int i; +#endif + +#ifdef DO_SELECT + fd_set readfds; + struct timeval timeout; +#endif + + struct sctp_stream_request_struct *sctp_stream_request; + struct sctp_stream_response_struct *sctp_stream_response; + struct sctp_stream_results_struct *sctp_stream_results; + +#ifdef DO_SELECT + FD_ZERO(&readfds); + timeout.tv_sec = 1; + timeout.tv_usec = 0; +#endif + + sctp_stream_request = + (struct sctp_stream_request_struct *)netperf_request.content.test_specific_data; + sctp_stream_response = + (struct sctp_stream_response_struct *)netperf_response.content.test_specific_data; + sctp_stream_results = + (struct sctp_stream_results_struct *)netperf_response.content.test_specific_data; + + if (debug) { + fprintf(where,"netserver: recv_sctp_stream: entered...\n"); + fflush(where); + } + + /* We want to set-up the listen socket with all the desired */ + /* parameters and then let the initiator know that all is ready. If */ + /* socket size defaults are to be used, then the initiator will have */ + /* sent us 0's. If the socket sizes cannot be changed, then we will */ + /* send-back what they are. If that information cannot be determined, */ + /* then we send-back -1's for the sizes. If things go wrong for any */ + /* reason, we will drop back ten yards and punt. */ + + /* If anything goes wrong, we want the remote to know about it. It */ + /* would be best if the error that the remote reports to the user is */ + /* the actual error we encountered, rather than some bogus unexpected */ + /* response type message. */ + + if (debug) { + fprintf(where,"recv_sctp_stream_1toMany: setting the response type...\n"); + fflush(where); + } + + netperf_response.content.response_type = SCTP_STREAM_MANY_RESPONSE; + + if (debug) { + fprintf(where,"recv_sctp_stream_1toMany: the response type is set...\n"); + fflush(where); + } + + /* We now alter the message_ptr variable to be at the desired */ + /* alignment with the desired offset. */ + + if (debug) { + fprintf(where,"recv_sctp_stream_1toMany: requested alignment of %d\n", + sctp_stream_request->recv_alignment); + fflush(where); + } + + /* create_data_socket expects to find some things in the global */ + /* variables, so set the globals based on the values in the request. */ + /* once the socket has been created, we will set the response values */ + /* based on the updated value of those globals. raj 7/94 */ + lss_size_req = sctp_stream_request->send_buf_size; + lsr_size_req = sctp_stream_request->recv_buf_size; + loc_nodelay = sctp_stream_request->no_delay; + loc_rcvavoid = sctp_stream_request->so_rcvavoid; + loc_sndavoid = sctp_stream_request->so_sndavoid; + non_block = sctp_stream_request->non_blocking; + + set_hostname_and_port(local_name, + port_buffer, + nf_to_af(sctp_stream_request->ipfamily), + sctp_stream_request->port); + + local_res = complete_addrinfo(local_name, + local_name, + port_buffer, + nf_to_af(sctp_stream_request->ipfamily), + SOCK_SEQPACKET, + IPPROTO_SCTP, + 0); + + s_recv = create_data_socket(local_res); + + if (s_recv < 0) { + netperf_response.content.serv_errno = errno; + send_response(); + exit(1); + } + + /* what sort of sizes did we end-up with? */ + if (sctp_stream_request->receive_size == 0) { + if (lsr_size > 0) { + recv_size = lsr_size; + } + else { + recv_size = 4096; + } + } + else { + recv_size = sctp_stream_request->receive_size; + } + + /* we want to set-up our recv_ring in a manner analagous to what we */ + /* do on the sending side. this is more for the sake of symmetry */ + /* than for the needs of say copy avoidance, but it might also be */ + /* more realistic - this way one could conceivably go with a */ + /* double-buffering scheme when taking the data an putting it into */ + /* the filesystem or something like that. raj 7/94 */ + + if (recv_width == 0) { + recv_width = (lsr_size/recv_size) + 1; + if (recv_width == 1) recv_width++; + } + + recv_ring = allocate_buffer_ring(recv_width, + recv_size, + sctp_stream_request->recv_alignment, + sctp_stream_request->recv_offset); + + if (debug) { + fprintf(where,"recv_sctp_stream: receive alignment and offset set...\n"); + fflush(where); + } + + /* Now, let's set-up the socket to listen for connections */ + if (listen(s_recv, 5) == -1) { + netperf_response.content.serv_errno = errno; + close(s_recv); + send_response(); + + exit(1); + } + + /* now get the port number assigned by the system */ + addrlen = sizeof(myaddr_in); + if (getsockname(s_recv, + (struct sockaddr *)&myaddr_in, + &addrlen) == -1){ + netperf_response.content.serv_errno = errno; + close(s_recv); + send_response(); + + exit(1); + } + + /* Now myaddr_in contains the port and the internet address this is */ + /* returned to the sender also implicitly telling the sender that the */ + /* socket buffer sizing has been done. */ + + sctp_stream_response->data_port_number = (int) ntohs(myaddr_in.sin_port); + netperf_response.content.serv_errno = 0; + + /* But wait, there's more. If the initiator wanted cpu measurements, */ + /* then we must call the calibrate routine, which will return the max */ + /* rate back to the initiator. If the CPU was not to be measured, or */ + /* something went wrong with the calibration, we will return a -1 to */ + /* the initiator. */ + + sctp_stream_response->cpu_rate = (float)0.0; /* assume no cpu */ + if (sctp_stream_request->measure_cpu) { + sctp_stream_response->measure_cpu = 1; + sctp_stream_response->cpu_rate = + calibrate_local_cpu(sctp_stream_request->cpu_rate); + } + else { + sctp_stream_response->measure_cpu = 0; + } + + /* before we send the response back to the initiator, pull some of */ + /* the socket parms from the globals */ + sctp_stream_response->send_buf_size = lss_size; + sctp_stream_response->recv_buf_size = lsr_size; + sctp_stream_response->no_delay = loc_nodelay; + sctp_stream_response->so_rcvavoid = loc_rcvavoid; + sctp_stream_response->so_sndavoid = loc_sndavoid; + sctp_stream_response->receive_size = recv_size; + + send_response(); + + + sctp_enable_events(s_recv, SCTP_ASSOC_CHANGE_EV | SCTP_SHUTDOWN_EV); + + /* now that we are connected, mark the socket as non-blocking */ + if (non_block) { + if (!set_nonblock(s_recv)) { + close(s_recv); + exit(1); + } + } + + + /* Now it's time to start receiving data on the connection. We will */ + /* first grab the apropriate counters and then start grabbing. */ + + cpu_start(sctp_stream_request->measure_cpu); + + /* The loop will exit when the sender does a shutdown, which will */ + /* return a length of zero */ + +#ifdef DIRTY + /* we want to dirty some number of consecutive integers in the buffer */ + /* we are about to recv. we may also want to bring some number of */ + /* them cleanly into the cache. The clean ones will follow any dirty */ + /* ones into the cache. */ + + dirty_count = sctp_stream_request->dirty_count; + clean_count = sctp_stream_request->clean_count; + message_int_ptr = (int *)recv_ring->buffer_ptr; + for (i = 0; i < dirty_count; i++) { + *message_int_ptr = rand(); + message_int_ptr++; + } + for (i = 0; i < clean_count; i++) { + dirty_count = *message_int_ptr; + message_int_ptr++; + } +#endif /* DIRTY */ + + bytes_received = 0; + receive_calls = 0; + + while ((len = sctp_recvmsg(s_recv, recv_ring->buffer_ptr, recv_size, + NULL, 0, /* we don't care who it's from */ + NULL, &msg_flags)) != 0) { + if (len < 0) { + if (non_block && errno == EAGAIN) { + Set_errno(0); + continue; + } + netperf_response.content.serv_errno = errno; + send_response(); + close(s_recv); + exit(1); + } + + if (msg_flags & MSG_NOTIFICATION) { + if (sctp_process_event(s_recv, recv_ring->buffer_ptr) == SCTP_CLOSE) + break; + + continue; + } + + bytes_received += len; + receive_calls++; + + /* more to the next buffer in the recv_ring */ + recv_ring = recv_ring->next; + +#ifdef PAUSE + sleep(1); +#endif /* PAUSE */ + +#ifdef DIRTY + message_int_ptr = (int *)(recv_ring->buffer_ptr); + for (i = 0; i < dirty_count; i++) { + *message_int_ptr = rand(); + message_int_ptr++; + } + for (i = 0; i < clean_count; i++) { + dirty_count = *message_int_ptr; + message_int_ptr++; + } +#endif /* DIRTY */ + +#ifdef DO_SELECT + FD_SET(s_recv,&readfds); + select(s_recv+1,&readfds,NULL,NULL,&timeout); +#endif /* DO_SELECT */ + + } + + /* perform a shutdown to signal the sender. in this case, sctp + * will close all associations on this socket + */ + if (close(s_recv) == -1) { + netperf_response.content.serv_errno = errno; + send_response(); + exit(1); + } + + cpu_stop(sctp_stream_request->measure_cpu,&elapsed_time); + + /* send the results to the sender */ + + if (debug) { + fprintf(where, + "recv_sctp_stream: got %g bytes\n", + bytes_received); + fprintf(where, + "recv_sctp_stream: got %d recvs\n", + receive_calls); + fflush(where); + } + + sctp_stream_results->bytes_received = htond(bytes_received); + sctp_stream_results->elapsed_time = elapsed_time; + sctp_stream_results->recv_calls = receive_calls; + + if (sctp_stream_request->measure_cpu) { + sctp_stream_results->cpu_util = calc_cpu_util(0.0); + }; + + if (debug) { + fprintf(where, + "recv_sctp_stream: test complete, sending results.\n"); + fprintf(where, + " bytes_received %g receive_calls %d\n", + bytes_received, + receive_calls); + fprintf(where, + " len %d\n", + len); + fflush(where); + } + + sctp_stream_results->cpu_method = cpu_method; + sctp_stream_results->num_cpus = lib_num_loc_cpus; + send_response(); +} + + + /* this routine implements the sending (netperf) side of the SCTP_RR */ + /* test. */ + +void +send_sctp_rr(remote_host) + char remote_host[]; +{ + + char *tput_title = "\ +Local /Remote\n\ +Socket Size Request Resp. Elapsed Trans.\n\ +Send Recv Size Size Time Rate \n\ +bytes Bytes bytes bytes secs. per sec \n\n"; + + char *tput_fmt_0 = + "%7.2f\n"; + + char *tput_fmt_1_line_1 = "\ +%-6d %-6d %-6d %-6d %-6.2f %7.2f \n"; + char *tput_fmt_1_line_2 = "\ +%-6d %-6d\n"; + + char *cpu_title = "\ +Local /Remote\n\ +Socket Size Request Resp. Elapsed Trans. CPU CPU S.dem S.dem\n\ +Send Recv Size Size Time Rate local remote local remote\n\ +bytes bytes bytes bytes secs. per sec %% %c %% %c us/Tr us/Tr\n\n"; + + char *cpu_fmt_0 = + "%6.3f %c\n"; + + char *cpu_fmt_1_line_1 = "\ +%-6d %-6d %-6d %-6d %-6.2f %-6.2f %-6.2f %-6.2f %-6.3f %-6.3f\n"; + + char *cpu_fmt_1_line_2 = "\ +%-6d %-6d\n"; + + char *ksink_fmt = "\ +Alignment Offset\n\ +Local Remote Local Remote\n\ +Send Recv Send Recv\n\ +%5d %5d %5d %5d\n"; + + + int timed_out = 0; + float elapsed_time; + + int len; + char *temp_message_ptr; + int nummessages; + int send_socket; + int trans_remaining; + int msg_flags = 0; + double bytes_xferd; + + struct ring_elt *send_ring; + struct ring_elt *recv_ring; + + int rsp_bytes_left; + int rsp_bytes_recvd; + + float local_cpu_utilization; + float local_service_demand; + float remote_cpu_utilization; + float remote_service_demand; + double thruput; + + struct sockaddr_storage peer; + struct addrinfo *remote_res; + struct addrinfo *local_res; + + struct sctp_rr_request_struct *sctp_rr_request; + struct sctp_rr_response_struct *sctp_rr_response; + struct sctp_rr_results_struct *sctp_rr_result; + +#ifdef WANT_INTERVALS + int interval_count; + sigset_t signal_set; +#endif /* WANT_INTERVALS */ + + sctp_rr_request = + (struct sctp_rr_request_struct *)netperf_request.content.test_specific_data; + sctp_rr_response = + (struct sctp_rr_response_struct *)netperf_response.content.test_specific_data; + sctp_rr_result = + (struct sctp_rr_results_struct *)netperf_response.content.test_specific_data; + +#ifdef WANT_HISTOGRAM + time_hist = HIST_new(); +#endif /* WANT_HISTOGRAM */ + + /* since we are now disconnected from the code that established the */ + /* control socket, and since we want to be able to use different */ + /* protocols and such, we are passed the name of the remote host and */ + /* must turn that into the test specific addressing information. */ + + /* complete_addrinfos will either succede or exit the process */ + complete_addrinfos(&remote_res, + &local_res, + remote_host, + SOCK_STREAM, + IPPROTO_SCTP, + 0); + + if ( print_headers ) { + print_top_test_header("SCTP REQUEST/RESPONSE TEST", local_res, remote_res); + } + + /* initialize a few counters */ + + send_ring = NULL; + recv_ring = NULL; + confidence_iteration = 1; + init_stat(); + + /* we have a great-big while loop which controls the number of times */ + /* we run a particular test. this is for the calculation of a */ + /* confidence interval (I really should have stayed awake during */ + /* probstats :). If the user did not request confidence measurement */ + /* (no confidence is the default) then we will only go though the */ + /* loop once. the confidence stuff originates from the folks at IBM */ + + while (((confidence < 0) && (confidence_iteration < iteration_max)) || + (confidence_iteration <= iteration_min)) { + + /* initialize a few counters. we have to remember that we might be */ + /* going through the loop more than once. */ + + nummessages = 0; + bytes_xferd = 0.0; + times_up = 0; + timed_out = 0; + trans_remaining = 0; + + /* set-up the data buffers with the requested alignment and offset. */ + /* since this is a request/response test, default the send_width and */ + /* recv_width to 1 and not two raj 7/94 */ + + if (send_width == 0) send_width = 1; + if (recv_width == 0) recv_width = 1; + + if (send_ring == NULL) { + send_ring = allocate_buffer_ring(send_width, + req_size, + local_send_align, + local_send_offset); + } + + if (recv_ring == NULL) { + recv_ring = allocate_buffer_ring(recv_width, + rsp_size, + local_recv_align, + local_recv_offset); + } + + /*set up the data socket */ + send_socket = create_data_socket(local_res); + + if (send_socket < 0){ + perror("netperf: send_sctp_rr: sctp stream data socket"); + exit(1); + } + + if (debug) { + fprintf(where,"send_sctp_rr: send_socket obtained...\n"); + } + + /* If the user has requested cpu utilization measurements, we must */ + /* calibrate the cpu(s). We will perform this task within the tests */ + /* themselves. If the user has specified the cpu rate, then */ + /* calibrate_local_cpu will return rather quickly as it will have */ + /* nothing to do. If local_cpu_rate is zero, then we will go through */ + /* all the "normal" calibration stuff and return the rate back.*/ + + if (local_cpu_usage) { + local_cpu_rate = calibrate_local_cpu(local_cpu_rate); + } + + /* Tell the remote end to do a listen. The server alters the socket */ + /* paramters on the other side at this point, hence the reason for */ + /* all the values being passed in the setup message. If the user did */ + /* not specify any of the parameters, they will be passed as 0, which */ + /* will indicate to the remote that no changes beyond the system's */ + /* default should be used. Alignment is the exception, it will */ + /* default to 8, which will be no alignment alterations. */ + + netperf_request.content.request_type = DO_SCTP_RR; + sctp_rr_request->recv_buf_size = rsr_size_req; + sctp_rr_request->send_buf_size = rss_size_req; + sctp_rr_request->recv_alignment = remote_recv_align; + sctp_rr_request->recv_offset = remote_recv_offset; + sctp_rr_request->send_alignment = remote_send_align; + sctp_rr_request->send_offset = remote_send_offset; + sctp_rr_request->request_size = req_size; + sctp_rr_request->response_size = rsp_size; + sctp_rr_request->no_delay = rem_nodelay; + sctp_rr_request->measure_cpu = remote_cpu_usage; + sctp_rr_request->cpu_rate = remote_cpu_rate; + sctp_rr_request->so_rcvavoid = rem_rcvavoid; + sctp_rr_request->so_sndavoid = rem_sndavoid; + if (test_time) { + sctp_rr_request->test_length = test_time; + } + else { + sctp_rr_request->test_length = test_trans * -1; + } + sctp_rr_request->non_blocking = non_block; + sctp_rr_request->ipfamily = af_to_nf(remote_res->ai_family); + + if (debug > 1) { + fprintf(where,"netperf: send_sctp_rr: requesting SCTP rr test\n"); + } + + send_request(); + + /* The response from the remote will contain all of the relevant */ + /* socket parameters for this test type. We will put them back into */ + /* the variables here so they can be displayed if desired. The */ + /* remote will have calibrated CPU if necessary, and will have done */ + /* all the needed set-up we will have calibrated the cpu locally */ + /* before sending the request, and will grab the counter value right*/ + /* after the connect returns. The remote will grab the counter right*/ + /* after the accept call. This saves the hassle of extra messages */ + /* being sent for the sctp tests. */ + + recv_response(); + + if (!netperf_response.content.serv_errno) { + if (debug) + fprintf(where,"remote listen done.\n"); + rsr_size = sctp_rr_response->recv_buf_size; + rss_size = sctp_rr_response->send_buf_size; + rem_nodelay = sctp_rr_response->no_delay; + remote_cpu_usage = sctp_rr_response->measure_cpu; + remote_cpu_rate = sctp_rr_response->cpu_rate; + /* make sure that port numbers are in network order */ + set_port_number(remote_res, + (unsigned short)sctp_rr_response->data_port_number); + } + else { + Set_errno(netperf_response.content.serv_errno); + fprintf(where, + "netperf: remote error %d", + netperf_response.content.serv_errno); + perror(""); + fflush(where); + + exit(1); + } + + /*Connect up to the remote port on the data socket */ + if (connect(send_socket, + remote_res->ai_addr, + remote_res->ai_addrlen) <0){ + perror("netperf: send_sctp_rr data socket connect failed"); + exit(1); + } + + /* don't need events for 1-to-1 API with request-response tests */ + sctp_enable_events(send_socket, 0); + + /* set non-blocking if needed */ + if (non_block) { + if (!set_nonblock(send_socket)) { + close(send_socket); + exit(1); + } + } + + /* Data Socket set-up is finished. If there were problems, either the */ + /* connect would have failed, or the previous response would have */ + /* indicated a problem. I failed to see the value of the extra */ + /* message after the accept on the remote. If it failed, we'll see it */ + /* here. If it didn't, we might as well start pumping data. */ + + /* Set-up the test end conditions. For a request/response test, they */ + /* can be either time or transaction based. */ + + if (test_time) { + /* The user wanted to end the test after a period of time. */ + times_up = 0; + trans_remaining = 0; + start_timer(test_time); + } + else { + /* The tester wanted to send a number of bytes. */ + trans_remaining = test_bytes; + times_up = 1; + } + + /* The cpu_start routine will grab the current time and possibly */ + /* value of the idle counter for later use in measuring cpu */ + /* utilization and/or service demand and thruput. */ + + cpu_start(local_cpu_usage); + +#ifdef WANT_INTERVALS + if ((interval_burst) || (demo_mode)) { + /* zero means that we never pause, so we never should need the */ + /* interval timer, unless we are in demo_mode */ + start_itimer(interval_wate); + } + interval_count = interval_burst; + /* get the signal set for the call to sigsuspend */ + if (sigprocmask(SIG_BLOCK, (sigset_t *)NULL, &signal_set) != 0) { + fprintf(where, + "send_sctp_rr: unable to get sigmask errno %d\n", + errno); + fflush(where); + exit(1); + } +#endif /* WANT_INTERVALS */ + + /* We use an "OR" to control test execution. When the test is */ + /* controlled by time, the byte count check will always return false. */ + /* When the test is controlled by byte count, the time test will */ + /* always return false. When the test is finished, the whole */ + /* expression will go false and we will stop sending data. I think I */ + /* just arbitrarily decrement trans_remaining for the timed test, but */ + /* will not do that just yet... One other question is whether or not */ + /* the send buffer and the receive buffer should be the same buffer. */ + +#ifdef WANT_FIRST_BURST + { + int i; + for (i = 0; i < first_burst_size; i++) { + if((len=sctp_sendmsg(send_socket, + send_ring->buffer_ptr, req_size, + NULL, 0, /* don't need addrs with 1-to-1 */ + 0, 0, 0, 0, 0)) != req_size) { + /* we should never hit the end of the test in the first burst */ + perror("send_sctp_rr: initial burst data send error"); + exit(1); + } + } + } +#endif /* WANT_FIRST_BURST */ + + while ((!times_up) || (trans_remaining > 0)) { + /* send the request. we assume that if we use a blocking socket, */ + /* the request will be sent at one shot. */ + +#ifdef WANT_HISTOGRAM + /* timestamp just before our call to send, and then again just */ + /* after the receive raj 8/94 */ + HIST_timestamp(&time_one); +#endif /* WANT_HISTOGRAM */ + + while ((len=sctp_sendmsg(send_socket, + send_ring->buffer_ptr, req_size, + NULL, 0, /* don't need addrs with 1-to-1 */ + 0, 0, 0, 0, 0)) != req_size) { + if (non_block && errno == EAGAIN) { + /* try sending again */ + continue; + } else if (SOCKET_EINTR(len) || (errno == 0)) { + /* we hit the end of a */ + /* timed test. */ + timed_out = 1; + break; + } + perror("send_sctp_rr: data send error"); + exit(1); + } + + if (timed_out) { + /* we timed out while sending. break out another level */ + break; + } + send_ring = send_ring->next; + + /* receive the response */ + rsp_bytes_left = rsp_size; + temp_message_ptr = recv_ring->buffer_ptr; + do { + msg_flags = 0; + if ((rsp_bytes_recvd=sctp_recvmsg(send_socket, + temp_message_ptr, rsp_bytes_left, + NULL, 0, + NULL, &msg_flags)) < 0) { + if (errno == EINTR) { + /* We hit the end of a timed test. */ + timed_out = 1; + break; + } else if (non_block && errno == EAGAIN) { + continue; + } + perror("send_sctp_rr: data recv error"); + exit(1); + } + rsp_bytes_left -= rsp_bytes_recvd; + temp_message_ptr += rsp_bytes_recvd; + } while (!(msg_flags & MSG_EOR)); + + recv_ring = recv_ring->next; + + if (timed_out) { + /* we may have been in a nested while loop - we need */ + /* another call to break. */ + break; + } + +#ifdef WANT_HISTOGRAM + HIST_timestamp(&time_two); + HIST_add(time_hist,delta_micro(&time_one,&time_two)); +#endif /* WANT_HISTOGRAM */ +#ifdef WANT_INTERVALS + if (demo_mode) { + units_this_tick += 1; + } + /* in this case, the interval count is the count-down couter */ + /* to decide to sleep for a little bit */ + if ((interval_burst) && (--interval_count == 0)) { + /* call sigsuspend and wait for the interval timer to get us */ + /* out */ + if (debug > 1) { + fprintf(where,"about to suspend\n"); + fflush(where); + } + if (sigsuspend(&signal_set) == EFAULT) { + fprintf(where, + "send_sctp_rr: fault with signal set!\n"); + fflush(where); + exit(1); + } + interval_count = interval_burst; + } +#endif /* WANT_INTERVALS */ + + nummessages++; + if (trans_remaining) { + trans_remaining--; + } + + if (debug > 3) { + if ((nummessages % 100) == 0) { + fprintf(where, + "Transaction %d completed\n", + nummessages); + fflush(where); + } + } + } + + /* At this point we used to call shutdown on the data socket to be */ + /* sure all the data was delivered, but this was not germane in a */ + /* request/response test, and it was causing the tests to "hang" when */ + /* they were being controlled by time. So, I have replaced this */ + /* shutdown call with a call to close that can be found later in the */ + /* procedure. */ + + /* this call will always give us the elapsed time for the test, and */ + /* will also store-away the necessaries for cpu utilization */ + + cpu_stop(local_cpu_usage,&elapsed_time); /* was cpu being */ + /* measured? how long */ + /* did we really run? */ + + /* Get the statistics from the remote end. The remote will have */ + /* calculated CPU utilization. If it wasn't supposed to care, it */ + /* will return obvious values. */ + + recv_response(); + if (!netperf_response.content.serv_errno) { + if (debug) + fprintf(where,"remote results obtained\n"); + } + else { + Set_errno(netperf_response.content.serv_errno); + fprintf(where,"netperf: remote error %d", + netperf_response.content.serv_errno); + perror(""); + fflush(where); + exit(1); + } + + /* We now calculate what our throughput was for the test. */ + + bytes_xferd = (req_size * nummessages) + (rsp_size * nummessages); + thruput = nummessages/elapsed_time; + + if (local_cpu_usage || remote_cpu_usage) { + /* We must now do a little math for service demand and cpu */ + /* utilization for the system(s) */ + /* Of course, some of the information might be bogus because */ + /* there was no idle counter in the kernel(s). We need to make */ + /* a note of this for the user's benefit...*/ + if (local_cpu_usage) { + local_cpu_utilization = calc_cpu_util(0.0); + /* since calc_service demand is doing ms/Kunit we will */ + /* multiply the number of transaction by 1024 to get */ + /* "good" numbers */ + local_service_demand = calc_service_demand((double) nummessages*1024, + 0.0, + 0.0, + 0); + } + else { + local_cpu_utilization = (float) -1.0; + local_service_demand = (float) -1.0; + } + + if (remote_cpu_usage) { + remote_cpu_utilization = sctp_rr_result->cpu_util; + /* since calc_service demand is doing ms/Kunit we will */ + /* multiply the number of transaction by 1024 to get */ + /* "good" numbers */ + remote_service_demand = calc_service_demand((double) nummessages*1024, + 0.0, + remote_cpu_utilization, + sctp_rr_result->num_cpus); + } + else { + remote_cpu_utilization = (float) -1.0; + remote_service_demand = (float) -1.0; + } + + } + else { + /* we were not measuring cpu, for the confidence stuff, we */ + /* should make it -1.0 */ + local_cpu_utilization = (float) -1.0; + local_service_demand = (float) -1.0; + remote_cpu_utilization = (float) -1.0; + remote_service_demand = (float) -1.0; + } + + /* at this point, we want to calculate the confidence information. */ + /* if debugging is on, calculate_confidence will print-out the */ + /* parameters we pass it */ + + calculate_confidence(confidence_iteration, + elapsed_time, + thruput, + local_cpu_utilization, + remote_cpu_utilization, + local_service_demand, + remote_service_demand); + + + confidence_iteration++; + + /* we are now done with the socket, so close it */ + close(send_socket); + + } + + retrieve_confident_values(&elapsed_time, + &thruput, + &local_cpu_utilization, + &remote_cpu_utilization, + &local_service_demand, + &remote_service_demand); + + /* We are now ready to print all the information. If the user */ + /* has specified zero-level verbosity, we will just print the */ + /* local service demand, or the remote service demand. If the */ + /* user has requested verbosity level 1, he will get the basic */ + /* "streamperf" numbers. If the user has specified a verbosity */ + /* of greater than 1, we will display a veritable plethora of */ + /* background information from outside of this block as it it */ + /* not cpu_measurement specific... */ + + if (confidence < 0) { + /* we did not hit confidence, but were we asked to look for it? */ + if (iteration_max > 1) { + display_confidence(); + } + } + + if (local_cpu_usage || remote_cpu_usage) { + local_cpu_method = format_cpu_method(cpu_method); + remote_cpu_method = format_cpu_method(sctp_rr_result->cpu_method); + + switch (verbosity) { + case 0: + if (local_cpu_usage) { + fprintf(where, + cpu_fmt_0, + local_service_demand, + local_cpu_method); + } + else { + fprintf(where, + cpu_fmt_0, + remote_service_demand, + remote_cpu_method); + } + break; + case 1: + case 2: + if (print_headers) { + fprintf(where, + cpu_title, + local_cpu_method, + remote_cpu_method); + } + + fprintf(where, + cpu_fmt_1_line_1, /* the format string */ + lss_size, /* local sendbuf size */ + lsr_size, + req_size, /* how large were the requests */ + rsp_size, /* guess */ + elapsed_time, /* how long was the test */ + thruput, + local_cpu_utilization, /* local cpu */ + remote_cpu_utilization, /* remote cpu */ + local_service_demand, /* local service demand */ + remote_service_demand); /* remote service demand */ + fprintf(where, + cpu_fmt_1_line_2, + rss_size, + rsr_size); + break; + } + } + else { + /* The tester did not wish to measure service demand. */ + + switch (verbosity) { + case 0: + fprintf(where, + tput_fmt_0, + thruput); + break; + case 1: + case 2: + if (print_headers) { + fprintf(where,tput_title,format_units()); + } + + fprintf(where, + tput_fmt_1_line_1, /* the format string */ + lss_size, + lsr_size, + req_size, /* how large were the requests */ + rsp_size, /* how large were the responses */ + elapsed_time, /* how long did it take */ + thruput); + fprintf(where, + tput_fmt_1_line_2, + rss_size, /* remote recvbuf size */ + rsr_size); + + break; + } + } + + /* it would be a good thing to include information about some of the */ + /* other parameters that may have been set for this test, but at the */ + /* moment, I do not wish to figure-out all the formatting, so I will */ + /* just put this comment here to help remind me that it is something */ + /* that should be done at a later time. */ + + /* how to handle the verbose information in the presence of */ + /* confidence intervals is yet to be determined... raj 11/94 */ + if (verbosity > 1) { + /* The user wanted to know it all, so we will give it to him. */ + /* This information will include as much as we can find about */ + /* TCP statistics, the alignments of the sends and receives */ + /* and all that sort of rot... */ + + fprintf(where, + ksink_fmt, + local_send_align, + remote_recv_offset, + local_send_offset, + remote_recv_offset); + +#ifdef WANT_HISTOGRAM + fprintf(where,"\nHistogram of request/response times\n"); + fflush(where); + HIST_report(time_hist); +#endif /* WANT_HISTOGRAM */ + + } + +} + + + /* this routine implements the receive (netserver) side of a TCP_RR */ + /* test */ +void +recv_sctp_rr() +{ + + struct ring_elt *send_ring; + struct ring_elt *recv_ring; + + struct addrinfo *local_res; + char local_name[BUFSIZ]; + char port_buffer[PORTBUFSIZE]; + + struct sockaddr_in myaddr_in, peeraddr_in; + int s_listen, s_data; + int addrlen; + char *temp_message_ptr; + int trans_received; + int trans_remaining; + int bytes_sent; + int request_bytes_recvd; + int request_bytes_remaining; + int timed_out = 0; + float elapsed_time; + + struct sctp_rr_request_struct *sctp_rr_request; + struct sctp_rr_response_struct *sctp_rr_response; + struct sctp_rr_results_struct *sctp_rr_results; + + sctp_rr_request = + (struct sctp_rr_request_struct *)netperf_request.content.test_specific_data; + sctp_rr_response = + (struct sctp_rr_response_struct *)netperf_response.content.test_specific_data; + sctp_rr_results = + (struct sctp_rr_results_struct *)netperf_response.content.test_specific_data; + + if (debug) { + fprintf(where,"netserver: recv_sctp_rr: entered...\n"); + fflush(where); + } + + /* We want to set-up the listen socket with all the desired */ + /* parameters and then let the initiator know that all is ready. If */ + /* socket size defaults are to be used, then the initiator will have */ + /* sent us 0's. If the socket sizes cannot be changed, then we will */ + /* send-back what they are. If that information cannot be determined, */ + /* then we send-back -1's for the sizes. If things go wrong for any */ + /* reason, we will drop back ten yards and punt. */ + + /* If anything goes wrong, we want the remote to know about it. It */ + /* would be best if the error that the remote reports to the user is */ + /* the actual error we encountered, rather than some bogus unexpected */ + /* response type message. */ + + if (debug) { + fprintf(where,"recv_sctp_rr: setting the response type...\n"); + fflush(where); + } + + netperf_response.content.response_type = SCTP_RR_RESPONSE; + + if (debug) { + fprintf(where,"recv_sctp_rr: the response type is set...\n"); + fflush(where); + } + + /* allocate the recv and send rings with the requested alignments */ + /* and offsets. raj 7/94 */ + if (debug) { + fprintf(where,"recv_sctp_rr: requested recv alignment of %d offset %d\n", + sctp_rr_request->recv_alignment, + sctp_rr_request->recv_offset); + fprintf(where,"recv_sctp_rr: requested send alignment of %d offset %d\n", + sctp_rr_request->send_alignment, + sctp_rr_request->send_offset); + fflush(where); + } + + /* at some point, these need to come to us from the remote system */ + if (send_width == 0) send_width = 1; + if (recv_width == 0) recv_width = 1; + + send_ring = allocate_buffer_ring(send_width, + sctp_rr_request->response_size, + sctp_rr_request->send_alignment, + sctp_rr_request->send_offset); + + recv_ring = allocate_buffer_ring(recv_width, + sctp_rr_request->request_size, + sctp_rr_request->recv_alignment, + sctp_rr_request->recv_offset); + + + /* Grab a socket to listen on, and then listen on it. */ + + if (debug) { + fprintf(where,"recv_sctp_rr: grabbing a socket...\n"); + fflush(where); + } + + /* create_data_socket expects to find some things in the global */ + /* variables, so set the globals based on the values in the request. */ + /* once the socket has been created, we will set the response values */ + /* based on the updated value of those globals. raj 7/94 */ + lss_size_req = sctp_rr_request->send_buf_size; + lsr_size_req = sctp_rr_request->recv_buf_size; + loc_nodelay = sctp_rr_request->no_delay; + loc_rcvavoid = sctp_rr_request->so_rcvavoid; + loc_sndavoid = sctp_rr_request->so_sndavoid; + non_block = sctp_rr_request->non_blocking; + + set_hostname_and_port(local_name, + port_buffer, + nf_to_af(sctp_rr_request->ipfamily), + sctp_rr_request->port); + + local_res = complete_addrinfo(local_name, + local_name, + port_buffer, + nf_to_af(sctp_rr_request->ipfamily), + SOCK_STREAM, + IPPROTO_SCTP, + 0); + + s_listen = create_data_socket(local_res); + + if (s_listen < 0) { + netperf_response.content.serv_errno = errno; + send_response(); + + exit(1); + } + + /* Now, let's set-up the socket to listen for connections */ + if (listen(s_listen, 5) == -1) { + netperf_response.content.serv_errno = errno; + close(s_listen); + send_response(); + + exit(1); + } + + + /* now get the port number assigned by the system */ + addrlen = sizeof(myaddr_in); + if (getsockname(s_listen, + (struct sockaddr *)&myaddr_in, &addrlen) == -1){ + netperf_response.content.serv_errno = errno; + close(s_listen); + send_response(); + + exit(1); + } + + /* Now myaddr_in contains the port and the internet address this is */ + /* returned to the sender also implicitly telling the sender that the */ + /* socket buffer sizing has been done. */ + + sctp_rr_response->data_port_number = (int) ntohs(myaddr_in.sin_port); + netperf_response.content.serv_errno = 0; + + /* But wait, there's more. If the initiator wanted cpu measurements, */ + /* then we must call the calibrate routine, which will return the max */ + /* rate back to the initiator. If the CPU was not to be measured, or */ + /* something went wrong with the calibration, we will return a 0.0 to */ + /* the initiator. */ + + sctp_rr_response->cpu_rate = (float)0.0; /* assume no cpu */ + sctp_rr_response->measure_cpu = 0; + + if (sctp_rr_request->measure_cpu) { + sctp_rr_response->measure_cpu = 1; + sctp_rr_response->cpu_rate = calibrate_local_cpu(sctp_rr_request->cpu_rate); + } + + + /* before we send the response back to the initiator, pull some of */ + /* the socket parms from the globals */ + sctp_rr_response->send_buf_size = lss_size; + sctp_rr_response->recv_buf_size = lsr_size; + sctp_rr_response->no_delay = loc_nodelay; + sctp_rr_response->so_rcvavoid = loc_rcvavoid; + sctp_rr_response->so_sndavoid = loc_sndavoid; + sctp_rr_response->test_length = sctp_rr_request->test_length; + send_response(); + + addrlen = sizeof(peeraddr_in); + + if ((s_data = accept(s_listen, + (struct sockaddr *)&peeraddr_in, + &addrlen)) == -1) { + /* Let's just punt. The remote will be given some information */ + close(s_listen); + + exit(1); + } + + /* we do not need events on a 1-to-1 RR test. The test will finish + * once all transactions are done. + */ + + /* now that we are connected, mark the socket as non-blocking */ + if (non_block) { + if (!set_nonblock(s_data)) { + perror("netperf: set_nonblock"); + exit(1); + } + } + +#ifdef KLUDGE_SOCKET_OPTIONS + /* this is for those systems which *INCORRECTLY* fail to pass */ + /* attributes across an accept() call. Including this goes against */ + /* my better judgement :( raj 11/95 */ + + kludge_socket_options(s_data); + +#endif /* KLUDGE_SOCKET_OPTIONS */ + + if (debug) { + fprintf(where,"recv_sctp_rr: accept completes on the data connection.\n"); + fflush(where); + } + + /* Now it's time to start receiving data on the connection. We will */ + /* first grab the apropriate counters and then start grabbing. */ + + cpu_start(sctp_rr_request->measure_cpu); + + /* The loop will exit when we hit the end of the test time, or when */ + /* we have exchanged the requested number of transactions. */ + + if (sctp_rr_request->test_length > 0) { + times_up = 0; + trans_remaining = 0; + start_timer(sctp_rr_request->test_length + PAD_TIME); + } + else { + times_up = 1; + trans_remaining = sctp_rr_request->test_length * -1; + } + + trans_received = 0; + + while ((!times_up) || (trans_remaining > 0)) { + int msg_flags = 0; + + temp_message_ptr = recv_ring->buffer_ptr; + request_bytes_remaining = sctp_rr_request->request_size; + while(!(msg_flags & MSG_EOR)) { + if((request_bytes_recvd=sctp_recvmsg(s_data, + temp_message_ptr, + request_bytes_remaining, + NULL, 0, + NULL, &msg_flags)) < 0) { + if (errno == EINTR) { + /* the timer popped */ + timed_out = 1; + break; + } else if (non_block && errno == EAGAIN) { + continue; /* while request_bytes_remaining */ + } + netperf_response.content.serv_errno = errno; + send_response(); + exit(1); + } + request_bytes_remaining -= request_bytes_recvd; + temp_message_ptr += request_bytes_recvd; + } + + recv_ring = recv_ring->next; + + if (timed_out) { + /* we hit the end of the test based on time - lets */ + /* bail out of here now... */ + if (debug) { + fprintf(where,"yo55\n"); + fflush(where); + } + break; + } + + + /* Now, send the response to the remote + * In 1-to-1 API destination addr is not needed. + */ + while ((bytes_sent=sctp_sendmsg(s_data, + send_ring->buffer_ptr, + sctp_rr_request->response_size, + NULL, 0, + 0, 0, 0, 0, 0)) == -1) { + if (errno == EINTR) { + /* the test timer has popped */ + timed_out = 1; + break; + } else if (non_block && errno == EAGAIN) { + continue; + } + + netperf_response.content.serv_errno = 982; + send_response(); + exit(1); + } + + if (timed_out) { + /* we hit the end of the test based on time - lets */ + /* bail out of here now... */ + if (debug) { + fprintf(where,"yo6\n"); + fflush(where); + } + break; + } + + send_ring = send_ring->next; + + trans_received++; + if (trans_remaining) { + trans_remaining--; + } + } + + + /* The loop now exits due to timeout or transaction count being */ + /* reached */ + + cpu_stop(sctp_rr_request->measure_cpu,&elapsed_time); + + stop_timer(); + + if (timed_out) { + /* we ended the test by time, which was at least 2 seconds */ + /* longer than we wanted to run. so, we want to subtract */ + /* PAD_TIME from the elapsed_time. */ + elapsed_time -= PAD_TIME; + } + + /* send the results to the sender */ + + if (debug) { + fprintf(where, + "recv_sctp_rr: got %d transactions\n", + trans_received); + fflush(where); + } + + sctp_rr_results->bytes_received = (trans_received * + (sctp_rr_request->request_size + + sctp_rr_request->response_size)); + sctp_rr_results->trans_received = trans_received; + sctp_rr_results->elapsed_time = elapsed_time; + sctp_rr_results->cpu_method = cpu_method; + sctp_rr_results->num_cpus = lib_num_loc_cpus; + if (sctp_rr_request->measure_cpu) { + sctp_rr_results->cpu_util = calc_cpu_util(elapsed_time); + } + + if (debug) { + fprintf(where, + "recv_sctp_rr: test complete, sending results.\n"); + fflush(where); + } + + /* we are now done with the sockets */ + send_response(); + + close(s_data); + close(s_listen); + +} + + + +/* this routine implements the sending (netperf) side of the + SCTP_RR_1TOMANY test */ + +void +send_sctp_rr_1toMany(remote_host) + char remote_host[]; +{ + + char *tput_title = "\ +Local /Remote\n\ +Socket Size Request Resp. Elapsed Trans.\n\ +Send Recv Size Size Time Rate \n\ +bytes Bytes bytes bytes secs. per sec \n\n"; + + char *tput_fmt_0 = + "%7.2f\n"; + + char *tput_fmt_1_line_1 = "\ +%-6d %-6d %-6d %-6d %-6.2f %7.2f \n"; + char *tput_fmt_1_line_2 = "\ +%-6d %-6d\n"; + + char *cpu_title = "\ +Local /Remote\n\ +Socket Size Request Resp. Elapsed Trans. CPU CPU S.dem S.dem\n\ +Send Recv Size Size Time Rate local remote local remote\n\ +bytes bytes bytes bytes secs. per sec %% %c %% %c us/Tr us/Tr\n\n"; + + char *cpu_fmt_0 = + "%6.3f %c\n"; + + char *cpu_fmt_1_line_1 = "\ +%-6d %-6d %-6d %-6d %-6.2f %-6.2f %-6.2f %-6.2f %-6.3f %-6.3f\n"; + + char *cpu_fmt_1_line_2 = "\ +%-6d %-6d\n"; + + char *ksink_fmt = "\ +Alignment Offset\n\ +Local Remote Local Remote\n\ +Send Recv Send Recv\n\ +%5d %5d %5d %5d\n"; + + + int timed_out = 0; + float elapsed_time; + + int len, j = 0; + char *temp_message_ptr; + int nummessages; + int *send_socket; + int trans_remaining; + double bytes_xferd; + int msg_flags = 0; + + struct ring_elt *send_ring; + struct ring_elt *recv_ring; + + int rsp_bytes_left; + int rsp_bytes_recvd; + + float local_cpu_utilization; + float local_service_demand; + float remote_cpu_utilization; + float remote_service_demand; + double thruput; + + struct sockaddr_storage peer; + struct addrinfo *local_res; + struct addrinfo *remote_res; + + struct sctp_rr_request_struct *sctp_rr_request; + struct sctp_rr_response_struct *sctp_rr_response; + struct sctp_rr_results_struct *sctp_rr_result; + +#ifdef WANT_INTERVALS + int interval_count; + sigset_t signal_set; +#endif /* WANT_INTERVALS */ + + sctp_rr_request = + (struct sctp_rr_request_struct *)netperf_request.content.test_specific_data; + sctp_rr_response = + (struct sctp_rr_response_struct *)netperf_response.content.test_specific_data; + sctp_rr_result = + (struct sctp_rr_results_struct *)netperf_response.content.test_specific_data; + +#ifdef WANT_HISTOGRAM + time_hist = HIST_new(); +#endif /* WANT_HISTOGRAM */ + + /* since we are now disconnected from the code that established the */ + /* control socket, and since we want to be able to use different */ + /* protocols and such, we are passed the name of the remote host and */ + /* must turn that into the test specific addressing information. */ + + complete_addrinfos(&remote_res, + &local_res, + remote_host, + SOCK_SEQPACKET, + IPPROTO_SCTP, + 0); + + if ( print_headers ) { + print_top_test_header("SCTP 1-TO-MANY REQUEST/RESPONSE TEST",local_res,remote_res); + } + + /* initialize a few counters */ + + send_ring = NULL; + recv_ring = NULL; + confidence_iteration = 1; + init_stat(); + + send_socket = malloc(sizeof(int) * num_associations); + if (send_socket == NULL) { + fprintf(where, + "Could not create the socket array for %d associations", + num_associations); + fflush(where); + exit(1); + } + + /* we have a great-big while loop which controls the number of times */ + /* we run a particular test. this is for the calculation of a */ + /* confidence interval (I really should have stayed awake during */ + /* probstats :). If the user did not request confidence measurement */ + /* (no confidence is the default) then we will only go though the */ + /* loop once. the confidence stuff originates from the folks at IBM */ + + while (((confidence < 0) && (confidence_iteration < iteration_max)) || + (confidence_iteration <= iteration_min)) { + + /* initialize a few counters. we have to remember that we might be */ + /* going through the loop more than once. */ + + nummessages = 0; + bytes_xferd = 0.0; + times_up = 0; + timed_out = 0; + trans_remaining = 0; + + /* set-up the data buffers with the requested alignment and offset. */ + /* since this is a request/response test, default the send_width and */ + /* recv_width to 1 and not two raj 7/94 */ + + if (send_width == 0) send_width = 1; + if (recv_width == 0) recv_width = 1; + + if (send_ring == NULL) { + send_ring = allocate_buffer_ring(send_width, + req_size, + local_send_align, + local_send_offset); + } + + if (recv_ring == NULL) { + recv_ring = allocate_buffer_ring(recv_width, + rsp_size, + local_recv_align, + local_recv_offset); + } + + /* If the user has requested cpu utilization measurements, we must */ + /* calibrate the cpu(s). We will perform this task within the tests */ + /* themselves. If the user has specified the cpu rate, then */ + /* calibrate_local_cpu will return rather quickly as it will have */ + /* nothing to do. If local_cpu_rate is zero, then we will go through */ + /* all the "normal" calibration stuff and return the rate back.*/ + + if (local_cpu_usage) { + local_cpu_rate = calibrate_local_cpu(local_cpu_rate); + } + + /* Tell the remote end to do a listen. The server alters the socket */ + /* paramters on the other side at this point, hence the reason for */ + /* all the values being passed in the setup message. If the user did */ + /* not specify any of the parameters, they will be passed as 0, which */ + /* will indicate to the remote that no changes beyond the system's */ + /* default should be used. Alignment is the exception, it will */ + /* default to 8, which will be no alignment alterations. */ + + netperf_request.content.request_type = DO_SCTP_RR_MANY; + sctp_rr_request->recv_buf_size = rsr_size_req; + sctp_rr_request->send_buf_size = rss_size_req; + sctp_rr_request->recv_alignment = remote_recv_align; + sctp_rr_request->recv_offset = remote_recv_offset; + sctp_rr_request->send_alignment = remote_send_align; + sctp_rr_request->send_offset = remote_send_offset; + sctp_rr_request->request_size = req_size; + sctp_rr_request->response_size = rsp_size; + sctp_rr_request->no_delay = rem_nodelay; + sctp_rr_request->measure_cpu = remote_cpu_usage; + sctp_rr_request->cpu_rate = remote_cpu_rate; + sctp_rr_request->so_rcvavoid = rem_rcvavoid; + sctp_rr_request->so_sndavoid = rem_sndavoid; + if (test_time) { + sctp_rr_request->test_length = test_time; + } + else { + sctp_rr_request->test_length = test_trans * num_associations + * -1; + } + sctp_rr_request->non_blocking = non_block; + sctp_rr_request->port = atoi(remote_data_port); + sctp_rr_request->ipfamily = af_to_nf(remote_res->ai_family); + if (debug > 1) { + fprintf(where,"netperf: send_sctp_rr_1toMany: requesting SCTP rr test\n"); + } + + send_request(); + + /* The response from the remote will contain all of the relevant */ + /* socket parameters for this test type. We will put them back into */ + /* the variables here so they can be displayed if desired. The */ + /* remote will have calibrated CPU if necessary, and will have done */ + /* all the needed set-up we will have calibrated the cpu locally */ + /* before sending the request, and will grab the counter value right*/ + /* after the connect returns. The remote will grab the counter right*/ + /* after the accept call. This saves the hassle of extra messages */ + /* being sent for the sctp tests. */ + + recv_response(); + + if (!netperf_response.content.serv_errno) { + rsr_size = sctp_rr_response->recv_buf_size; + rss_size = sctp_rr_response->send_buf_size; + rem_nodelay = sctp_rr_response->no_delay; + remote_cpu_usage = sctp_rr_response->measure_cpu; + remote_cpu_rate = sctp_rr_response->cpu_rate; + /* make sure that port numbers are in network order */ + set_port_number(remote_res, + (unsigned short)sctp_rr_response->data_port_number); + } + else { + Set_errno(netperf_response.content.serv_errno); + fprintf(where, + "netperf: remote error %d", + netperf_response.content.serv_errno); + perror(""); + fflush(where); + + exit(1); + } + + /*set up the data socket list */ + for (j = 0; j < num_associations; j++) { + send_socket[j] = create_data_socket(local_res); + + if (send_socket < 0){ + perror("netperf: send_sctp_rr_1toMany: sctp stream data socket"); + exit(1); + } + + /*Connect up to the remote port on the data socket */ + if (connect(send_socket[j], + remote_res->ai_addr, + remote_res->ai_addrlen) < 0){ + perror("netperf: data socket connect failed"); + + exit(1); + } + + /* The client end of the 1-to-Many test uses 1-to-1 sockets. + * it doesn't need events. + */ + sctp_enable_events(send_socket[j], 0); + + if (non_block) { + if (!set_nonblock(send_socket[j])) { + close(send_socket[j]); + exit(1); + } + } + } + + /* Data Socket set-up is finished. If there were problems, either the */ + /* connect would have failed, or the previous response would have */ + /* indicated a problem. I failed to see the value of the extra */ + /* message after the accept on the remote. If it failed, we'll see it */ + /* here. If it didn't, we might as well start pumping data. */ + + /* Set-up the test end conditions. For a request/response test, they */ + /* can be either time or transaction based. */ + + if (test_time) { + /* The user wanted to end the test after a period of time. */ + times_up = 0; + trans_remaining = 0; + start_timer(test_time); + } + else { + /* The tester wanted to send a number of bytes. */ + trans_remaining = test_bytes * num_associations; + times_up = 1; + } + + /* The cpu_start routine will grab the current time and possibly */ + /* value of the idle counter for later use in measuring cpu */ + /* utilization and/or service demand and thruput. */ + + cpu_start(local_cpu_usage); + +#ifdef WANT_INTERVALS + if ((interval_burst) || (demo_mode)) { + /* zero means that we never pause, so we never should need the */ + /* interval timer, unless we are in demo_mode */ + start_itimer(interval_wate); + } + interval_count = interval_burst; + /* get the signal set for the call to sigsuspend */ + if (sigprocmask(SIG_BLOCK, (sigset_t *)NULL, &signal_set) != 0) { + fprintf(where, + "send_sctp_rr_1toMany: unable to get sigmask errno %d\n", + errno); + fflush(where); + exit(1); + } +#endif /* WANT_INTERVALS */ + + /* We use an "OR" to control test execution. When the test is */ + /* controlled by time, the byte count check will always return false. */ + /* When the test is controlled by byte count, the time test will */ + /* always return false. When the test is finished, the whole */ + /* expression will go false and we will stop sending data. I think I */ + /* just arbitrarily decrement trans_remaining for the timed test, but */ + /* will not do that just yet... One other question is whether or not */ + /* the send buffer and the receive buffer should be the same buffer. */ + +#ifdef WANT_FIRST_BURST + { + int i; + for (j = 0; j < num_associations; j++) { + for (i = 0; i < first_burst_size; i++) { + if((len=sctp_sendmsg(send_socket[j], + send_ring->buffer_ptr, send_size, + remote_res->ai_addr, + remote_res->ai_addrlen, + 0, 0, 0, 0, 0)) != req_size) { + /* we should never hit the end of the test in the first burst */ + perror("send_sctp_rr_1toMany: initial burst data send error"); + exit(1); + } + } + } + } +#endif /* WANT_FIRST_BURST */ + + while ((!times_up) || (trans_remaining > 0)) { + /* send the request. we assume that if we use a blocking socket, */ + /* the request will be sent at one shot. */ + + /* this is a fairly poor way of testing 1toMany connections. + * For each association we measure round trip time to account for + * any delay in lookups and delivery. To stress the server a bit + * more we would need a distributed client test, or at least multiple + * processes. I want to force as much paralellism as possible, but + * this will do for the fist take. vlad + */ + for (j = 0; j < num_associations; j++) { +#ifdef WANT_HISTOGRAM + /* timestamp just before our call to send, and then again just */ + /* after the receive raj 8/94 */ + gettimeofday(&time_one,NULL); +#endif /* WANT_HISTOGRAM */ + + while ((len=sctp_sendmsg(send_socket[j], + send_ring->buffer_ptr, send_size, + remote_res->ai_addr, + remote_res->ai_addrlen, + 0, 0, 0, 0, 0)) != req_size) { + if (non_block && errno == EAGAIN) { + /* try sending again */ + continue; + } else if ((errno == EINTR) || (errno == 0)) { + /* we hit the end of a */ + /* timed test. */ + timed_out = 1; + break; + } + perror("send_sctp_rr_1toMany: data send error"); + exit(1); + } + + if (timed_out) { + /* we may have been in a nested while loop - we need */ + /* another call to break. */ + break; + } + + /* setup for the next time */ + send_ring = send_ring->next; + + rsp_bytes_left = rsp_size; + temp_message_ptr = recv_ring->buffer_ptr; + while (!(msg_flags & MSG_EOR)) { + if((rsp_bytes_recvd = sctp_recvmsg(send_socket[j], + temp_message_ptr, + rsp_bytes_left, + NULL, 0, + NULL, &msg_flags)) < 0) { + if (errno == EINTR) { + /* We hit the end of a timed test. */ + timed_out = 1; + break; + } else if (non_block && errno == EAGAIN) { + continue; + } + perror("send_sctp_rr_1toMany: data recv error"); + exit(1); + } + rsp_bytes_left -= rsp_bytes_recvd; + temp_message_ptr += rsp_bytes_recvd; + } + recv_ring = recv_ring->next; + + if (timed_out) { + /* we may have been in a nested while loop - we need */ + /* another call to break. */ + break; + } + +#ifdef WANT_HISTOGRAM + gettimeofday(&time_two,NULL); + HIST_add(time_hist,delta_micro(&time_one,&time_two)); +#endif /* WANT_HISTOGRAM */ + + nummessages++; + if (trans_remaining) { + trans_remaining--; + } + + if (debug > 3) { + if ((nummessages % 100) == 0) { + fprintf(where, + "Transaction %d completed\n", + nummessages); + fflush(where); + } + } + } + } + + /* At this point we used to call shutdown on the data socket to be */ + /* sure all the data was delivered, but this was not germane in a */ + /* request/response test, and it was causing the tests to "hang" when */ + /* they were being controlled by time. So, I have replaced this */ + /* shutdown call with a call to close that can be found later in the */ + /* procedure. */ + + /* this call will always give us the elapsed time for the test, and */ + /* will also store-away the necessaries for cpu utilization */ + + cpu_stop(local_cpu_usage,&elapsed_time); /* was cpu being */ + /* measured? how long */ + /* did we really run? */ + + /* Get the statistics from the remote end. The remote will have */ + /* calculated CPU utilization. If it wasn't supposed to care, it */ + /* will return obvious values. */ + + recv_response(); + if (!netperf_response.content.serv_errno) { + if (debug) + fprintf(where,"remote results obtained\n"); + } + else { + Set_errno(netperf_response.content.serv_errno); + fprintf(where,"netperf: remote error %d", + netperf_response.content.serv_errno); + perror(""); + fflush(where); + exit(1); + } + + /* We now calculate what our throughput was for the test. */ + + bytes_xferd = (req_size * nummessages) + (rsp_size * nummessages); + thruput = nummessages/elapsed_time; + + if (local_cpu_usage || remote_cpu_usage) { + /* We must now do a little math for service demand and cpu */ + /* utilization for the system(s) */ + /* Of course, some of the information might be bogus because */ + /* there was no idle counter in the kernel(s). We need to make */ + /* a note of this for the user's benefit...*/ + if (local_cpu_usage) { + local_cpu_utilization = calc_cpu_util(0.0); + /* since calc_service demand is doing ms/Kunit we will */ + /* multiply the number of transaction by 1024 to get */ + /* "good" numbers */ + local_service_demand = calc_service_demand((double) nummessages*1024, + 0.0, + 0.0, + 0); + } + else { + local_cpu_utilization = (float) -1.0; + local_service_demand = (float) -1.0; + } + + if (remote_cpu_usage) { + remote_cpu_utilization = sctp_rr_result->cpu_util; + /* since calc_service demand is doing ms/Kunit we will */ + /* multiply the number of transaction by 1024 to get */ + /* "good" numbers */ + remote_service_demand = calc_service_demand((double) nummessages*1024, + 0.0, + remote_cpu_utilization, + sctp_rr_result->num_cpus); + } + else { + remote_cpu_utilization = (float) -1.0; + remote_service_demand = (float) -1.0; + } + + } + else { + /* we were not measuring cpu, for the confidence stuff, we */ + /* should make it -1.0 */ + local_cpu_utilization = (float) -1.0; + local_service_demand = (float) -1.0; + remote_cpu_utilization = (float) -1.0; + remote_service_demand = (float) -1.0; + } + + /* at this point, we want to calculate the confidence information. */ + /* if debugging is on, calculate_confidence will print-out the */ + /* parameters we pass it */ + + calculate_confidence(confidence_iteration, + elapsed_time, + thruput, + local_cpu_utilization, + remote_cpu_utilization, + local_service_demand, + remote_service_demand); + + + confidence_iteration++; + + /* we are now done with the socket, so close it */ + for (j = 0; j < num_associations; j++) + close(send_socket[j]); + } + + retrieve_confident_values(&elapsed_time, + &thruput, + &local_cpu_utilization, + &remote_cpu_utilization, + &local_service_demand, + &remote_service_demand); + + /* We are now ready to print all the information. If the user */ + /* has specified zero-level verbosity, we will just print the */ + /* local service demand, or the remote service demand. If the */ + /* user has requested verbosity level 1, he will get the basic */ + /* "streamperf" numbers. If the user has specified a verbosity */ + /* of greater than 1, we will display a veritable plethora of */ + /* background information from outside of this block as it it */ + /* not cpu_measurement specific... */ + + if (confidence < 0) { + /* we did not hit confidence, but were we asked to look for it? */ + if (iteration_max > 1) { + display_confidence(); + } + } + + if (local_cpu_usage || remote_cpu_usage) { + local_cpu_method = format_cpu_method(cpu_method); + remote_cpu_method = format_cpu_method(sctp_rr_result->cpu_method); + + switch (verbosity) { + case 0: + if (local_cpu_usage) { + fprintf(where, + cpu_fmt_0, + local_service_demand, + local_cpu_method); + } + else { + fprintf(where, + cpu_fmt_0, + remote_service_demand, + remote_cpu_method); + } + break; + case 1: + case 2: + if (print_headers) { + fprintf(where, + cpu_title, + local_cpu_method, + remote_cpu_method); + } + + fprintf(where, + cpu_fmt_1_line_1, /* the format string */ + lss_size, /* local sendbuf size */ + lsr_size, + req_size, /* how large were the requests */ + rsp_size, /* guess */ + elapsed_time, /* how long was the test */ + thruput, + local_cpu_utilization, /* local cpu */ + remote_cpu_utilization, /* remote cpu */ + local_service_demand, /* local service demand */ + remote_service_demand); /* remote service demand */ + fprintf(where, + cpu_fmt_1_line_2, + rss_size, + rsr_size); + break; + } + } + else { + /* The tester did not wish to measure service demand. */ + + switch (verbosity) { + case 0: + fprintf(where, + tput_fmt_0, + thruput); + break; + case 1: + case 2: + if (print_headers) { + fprintf(where,tput_title,format_units()); + } + + fprintf(where, + tput_fmt_1_line_1, /* the format string */ + lss_size, + lsr_size, + req_size, /* how large were the requests */ + rsp_size, /* how large were the responses */ + elapsed_time, /* how long did it take */ + thruput); + fprintf(where, + tput_fmt_1_line_2, + rss_size, /* remote recvbuf size */ + rsr_size); + + break; + } + } + + /* it would be a good thing to include information about some of the */ + /* other parameters that may have been set for this test, but at the */ + /* moment, I do not wish to figure-out all the formatting, so I will */ + /* just put this comment here to help remind me that it is something */ + /* that should be done at a later time. */ + + /* how to handle the verbose information in the presence of */ + /* confidence intervals is yet to be determined... raj 11/94 */ + if (verbosity > 1) { + /* The user wanted to know it all, so we will give it to him. */ + /* This information will include as much as we can find about */ + /* TCP statistics, the alignments of the sends and receives */ + /* and all that sort of rot... */ + + fprintf(where, + ksink_fmt, + local_send_align, + remote_recv_offset, + local_send_offset, + remote_recv_offset); + +#ifdef WANT_HISTOGRAM + fprintf(where,"\nHistogram of request/response times\n"); + fflush(where); + HIST_report(time_hist); +#endif /* WANT_HISTOGRAM */ + + } + +} + + + /* this routine implements the receive (netserver) side of a TCP_RR */ + /* test */ +void +recv_sctp_rr_1toMany() +{ + + struct ring_elt *send_ring; + struct ring_elt *recv_ring; + + + struct sockaddr_in myaddr_in; /* needed to get the port number */ + struct sockaddr_storage peeraddr; /* to communicate with peer */ + struct addrinfo *local_res; + char local_name[BUFSIZ]; + char port_buffer[PORTBUFSIZE]; + int msg_flags; + + int s_rcv; + int addrlen; + char *temp_message_ptr; + int trans_received; + int trans_remaining; + int bytes_sent; + int bytes_recvd; + int recv_buf_size; + int timed_out = 0; + float elapsed_time; + + struct sctp_rr_request_struct *sctp_rr_request; + struct sctp_rr_response_struct *sctp_rr_response; + struct sctp_rr_results_struct *sctp_rr_results; + + sctp_rr_request = + (struct sctp_rr_request_struct *)netperf_request.content.test_specific_data; + sctp_rr_response = + (struct sctp_rr_response_struct *)netperf_response.content.test_specific_data; + sctp_rr_results = + (struct sctp_rr_results_struct *)netperf_response.content.test_specific_data; + + if (debug) { + fprintf(where,"netserver: recv_sctp_rr_1toMany: entered...\n"); + fflush(where); + } + + /* We want to set-up the listen socket with all the desired */ + /* parameters and then let the initiator know that all is ready. If */ + /* socket size defaults are to be used, then the initiator will have */ + /* sent us 0's. If the socket sizes cannot be changed, then we will */ + /* send-back what they are. If that information cannot be determined, */ + /* then we send-back -1's for the sizes. If things go wrong for any */ + /* reason, we will drop back ten yards and punt. */ + + /* If anything goes wrong, we want the remote to know about it. It */ + /* would be best if the error that the remote reports to the user is */ + /* the actual error we encountered, rather than some bogus unexpected */ + /* response type message. */ + + if (debug) { + fprintf(where,"recv_sctp_rr_1toMany: setting the response type...\n"); + fflush(where); + } + + netperf_response.content.response_type = SCTP_RR_MANY_RESPONSE; + + if (debug) { + fprintf(where,"recv_sctp_rr_1toMany: the response type is set...\n"); + fflush(where); + } + + /* allocate the recv and send rings with the requested alignments */ + /* and offsets. raj 7/94 */ + if (debug) { + fprintf(where,"recv_sctp_rr_1toMany: requested recv alignment of %d offset %d\n", + sctp_rr_request->recv_alignment, + sctp_rr_request->recv_offset); + fprintf(where,"recv_sctp_rr_1toMany: requested send alignment of %d offset %d\n", + sctp_rr_request->send_alignment, + sctp_rr_request->send_offset); + fflush(where); + } + + /* at some point, these need to come to us from the remote system */ + if (send_width == 0) send_width = 1; + if (recv_width == 0) recv_width = 1; + + send_ring = allocate_buffer_ring(send_width, + sctp_rr_request->response_size, + sctp_rr_request->send_alignment, + sctp_rr_request->send_offset); + + recv_ring = allocate_buffer_ring(recv_width, + sctp_rr_request->request_size, + sctp_rr_request->recv_alignment, + sctp_rr_request->recv_offset); + + + /* create_data_socket expects to find some things in the global */ + /* variables, so set the globals based on the values in the request. */ + /* once the socket has been created, we will set the response values */ + /* based on the updated value of those globals. raj 7/94 */ + lss_size_req = sctp_rr_request->send_buf_size; + lsr_size_req = sctp_rr_request->recv_buf_size; + loc_nodelay = sctp_rr_request->no_delay; + loc_rcvavoid = sctp_rr_request->so_rcvavoid; + loc_sndavoid = sctp_rr_request->so_sndavoid; + non_block = sctp_rr_request->non_blocking; + + set_hostname_and_port(local_name, + port_buffer, + nf_to_af(sctp_rr_request->ipfamily), + sctp_rr_request->port); + + local_res = complete_addrinfo(local_name, + local_name, + port_buffer, + nf_to_af(sctp_rr_request->ipfamily), + SOCK_SEQPACKET, + IPPROTO_SCTP, + 0); + + /* Grab a socket to listen on, and then listen on it. */ + if (debug) { + fprintf(where,"recv_sctp_rr_1toMany: grabbing a socket...\n"); + fflush(where); + } + + s_rcv = create_data_socket(local_res); + + if (s_rcv < 0) { + netperf_response.content.serv_errno = errno; + send_response(); + + exit(1); + } + + /* Now, let's set-up the socket to listen for connections */ + if (listen(s_rcv, 5) == -1) { + netperf_response.content.serv_errno = errno; + close(s_rcv); + send_response(); + + exit(1); + } + + + /* now get the port number assigned by the system */ + addrlen = sizeof(myaddr_in); + if (getsockname(s_rcv, + (struct sockaddr *)&myaddr_in, &addrlen) == -1){ + netperf_response.content.serv_errno = errno; + close(s_rcv); + send_response(); + + exit(1); + } + + /* Now myaddr_in contains the port and the internet address this is */ + /* returned to the sender also implicitly telling the sender that the */ + /* socket buffer sizing has been done. */ + + sctp_rr_response->data_port_number = (int) ntohs(myaddr_in.sin_port); + netperf_response.content.serv_errno = 0; + + /* But wait, there's more. If the initiator wanted cpu measurements, */ + /* then we must call the calibrate routine, which will return the max */ + /* rate back to the initiator. If the CPU was not to be measured, or */ + /* something went wrong with the calibration, we will return a 0.0 to */ + /* the initiator. */ + + sctp_rr_response->cpu_rate = (float)0.0; /* assume no cpu */ + sctp_rr_response->measure_cpu = 0; + + if (sctp_rr_request->measure_cpu) { + sctp_rr_response->measure_cpu = 1; + sctp_rr_response->cpu_rate = calibrate_local_cpu(sctp_rr_request->cpu_rate); + } + + + /* before we send the response back to the initiator, pull some of */ + /* the socket parms from the globals */ + sctp_rr_response->send_buf_size = lss_size; + sctp_rr_response->recv_buf_size = lsr_size; + sctp_rr_response->no_delay = loc_nodelay; + sctp_rr_response->so_rcvavoid = loc_rcvavoid; + sctp_rr_response->so_sndavoid = loc_sndavoid; + sctp_rr_response->test_length = sctp_rr_request->test_length; + send_response(); + + /* Don't need events */ + sctp_enable_events(s_rcv, 0); + + /* now that we are connected, mark the socket as non-blocking */ + if (non_block) { + if (!set_nonblock(s_rcv)) { + perror("netperf: set_nonblock"); + exit(1); + } + } + + /* FIXME: The way 1-to-Many test operates right now, we are including + * association setup time into our measurements. The reason for this + * is that the client creates multiple endpoints and connects each + * endpoint to us using the connect call. On this end we simply call + * recvmsg() to get data becuase there is no equivalen of accept() for + * 1-to-Many API. + * I think this is OK, but if it were to be fixed, the server side + * would need to know how many associations are being setup and + * have a recvmsg() loop with SCTP_ASSOC_CHANGE events waiting for + * all the associations to be be established. + * I am punting on this for now. + */ + + + addrlen = sizeof(peeraddr); + + /* Now it's time to start receiving data on the connection. We will */ + /* first grab the apropriate counters and then start grabbing. */ + + cpu_start(sctp_rr_request->measure_cpu); + + /* The loop will exit when we hit the end of the test time, or when */ + /* we have exchanged the requested number of transactions. */ + + if (sctp_rr_request->test_length > 0) { + times_up = 0; + trans_remaining = 0; + start_timer(sctp_rr_request->test_length + PAD_TIME); + } + else { + times_up = 1; + trans_remaining = sctp_rr_request->test_length * -1; + } + + trans_received = 0; + + while ((!times_up) || (trans_remaining > 0)) { + + recv_buf_size = sctp_rr_request->request_size; + + /* Receive the data. We don't particularly care which association + * the data came in on. We'll simply be doing a receive untill + * we get and MSG_EOR flag (meaning that a single transmission was + * received) and a send to the same address, so the RR would be for + * the same associations. + * We can get away with this because the client will establish all + * the associations before transmitting any data. Any partial data + * will not have EOR thus will we will not send a response untill + * we get everything. + */ + + do { + msg_flags = 0; + if((bytes_recvd = sctp_recvmsg(s_rcv, + recv_ring->buffer_ptr, + recv_buf_size, + (struct sockaddr *)&peeraddr, &addrlen, + 0, &msg_flags)) == SOCKET_ERROR) { + if (SOCKET_EINTR(bytes_recvd)) { + /* the timer popped */ + timed_out = 1; + break; + } else if (non_block & errno == EAGAIN) { + /* do recvmsg again */ + continue; + } + netperf_response.content.serv_errno = errno; + send_response(); + exit(1); + } + } while(!(msg_flags & MSG_EOR)); + + recv_ring = recv_ring->next; + + if (timed_out) { + /* we hit the end of the test based on time - lets */ + /* bail out of here now... */ + if (debug) { + fprintf(where,"yo5\n"); + fflush(where); + } + break; + } + + /* Now, send the response to the remote */ + while ((bytes_sent=sctp_sendmsg(s_rcv, + send_ring->buffer_ptr, + sctp_rr_request->response_size, + (struct sockaddr *)&peeraddr, addrlen, + 0, 0, 0, 0, 0)) == SOCKET_ERROR) { + if (SOCKET_EINTR(bytes_sent)) { + /* the test timer has popped */ + timed_out = 1; + break; + } else if (non_block && errno == EAGAIN) { + continue; + } + + netperf_response.content.serv_errno = 992; + send_response(); + exit(1); + } + + if (timed_out) { + if (debug) { + fprintf(where,"yo6\n"); + fflush(where); + } + /* we hit the end of the test based on time - lets */ + /* bail out of here now... */ + break; + } + + send_ring = send_ring->next; + + trans_received++; + if (trans_remaining) { + trans_remaining--; + } + } + + + /* The loop now exits due to timeout or transaction count being */ + /* reached */ + + cpu_stop(sctp_rr_request->measure_cpu,&elapsed_time); + + stop_timer(); + + if (timed_out) { + /* we ended the test by time, which was at least 2 seconds */ + /* longer than we wanted to run. so, we want to subtract */ + /* PAD_TIME from the elapsed_time. */ + elapsed_time -= PAD_TIME; + } + + /* send the results to the sender */ + + if (debug) { + fprintf(where, + "recv_sctp_rr: got %d transactions\n", + trans_received); + fflush(where); + } + + sctp_rr_results->bytes_received = (trans_received * + (sctp_rr_request->request_size + + sctp_rr_request->response_size)); + sctp_rr_results->trans_received = trans_received; + sctp_rr_results->elapsed_time = elapsed_time; + sctp_rr_results->cpu_method = cpu_method; + sctp_rr_results->num_cpus = lib_num_loc_cpus; + if (sctp_rr_request->measure_cpu) { + sctp_rr_results->cpu_util = calc_cpu_util(elapsed_time); + } + + if (debug) { + fprintf(where, + "recv_sctp_rr: test complete, sending results.\n"); + fflush(where); + } + + /* we are now done with the sockets */ + close(s_rcv); + + send_response(); + +} + + +void +print_sctp_usage() +{ + + printf("%s",sctp_usage); + exit(1); + +} +void +scan_sctp_args(argc, argv) + int argc; + char *argv[]; + +{ + +#define SOCKETS_ARGS "BDhH:I:L:m:M:P:r:s:S:VN:T:46" + + extern char *optarg; /* pointer to option string */ + + int c; + + char + arg1[BUFSIZ], /* argument holders */ + arg2[BUFSIZ]; + + if (no_control) { + fprintf(where, + "The SCTP tests do not know how to deal with no control tests\n"); + exit(-1); + } + + strncpy(local_data_port,"0",sizeof(local_data_port)); + strncpy(remote_data_port,"0",sizeof(remote_data_port)); + + /* Go through all the command line arguments and break them */ + /* out. For those options that take two parms, specifying only */ + /* the first will set both to that value. Specifying only the */ + /* second will leave the first untouched. To change only the */ + /* first, use the form "first," (see the routine break_args.. */ + + while ((c= getopt(argc, argv, SOCKETS_ARGS)) != EOF) { + switch (c) { + case '?': + case '4': + remote_data_family = AF_INET; + local_data_family = AF_INET; + break; + case '6': +#if defined(AF_INET6) + remote_data_family = AF_INET6; + local_data_family = AF_INET6; +#else + fprintf(stderr, + "This netperf was not compiled on an IPv6 capable host!\n"); + fflush(stderr); + exit(-1); +#endif + break; + case 'h': + print_sctp_usage(); + exit(1); + case 'b': +#ifdef WANT_FIRST_BURST + first_burst_size = atoi(optarg); +#else /* WANT_FIRST_BURST */ + printf("Initial request burst functionality not compiled-in!\n"); +#endif /* WANT_FIRST_BURST */ + break; + case 'D': + /* set the nodelay flag */ + loc_nodelay = 1; + rem_nodelay = 1; + break; + case 'H': + break_args_explicit(optarg,arg1,arg2); + if (arg1[0]) { + /* make sure we leave room for the NULL termination boys and + girls. raj 2005-02-82 */ + remote_data_address = malloc(strlen(arg1)+1); + strncpy(remote_data_address,arg1,strlen(arg1)); + } + if (arg2[0]) + remote_data_family = parse_address_family(arg2); + break; + case 'L': + break_args_explicit(optarg,arg1,arg2); + if (arg1[0]) { + /* make sure we leave room for the NULL termination boys and + girls. raj 2005-02-82 */ + local_data_address = malloc(strlen(arg1)+1); + strncpy(local_data_address,arg1,strlen(arg1)); + } + if (arg2[0]) + local_data_family = parse_address_family(arg2); + break; + case 'P': + /* set the local and remote data port numbers for the tests to + allow them to run through those blankety blank end-to-end + breaking firewalls. raj 2004-06-15 */ + break_args(optarg,arg1,arg2); + if (arg1[0]) + strncpy(local_data_port,arg1,sizeof(local_data_port)); + if (arg2[0]) + strncpy(remote_data_port,arg2,sizeof(remote_data_port)); + break; + case 's': + /* set local socket sizes */ + break_args(optarg,arg1,arg2); + if (arg1[0]) + lss_size_req = convert(arg1); + if (arg2[0]) + lsr_size_req = convert(arg2); + break; + case 'S': + /* set remote socket sizes */ + break_args(optarg,arg1,arg2); + if (arg1[0]) + rss_size_req = convert(arg1); + if (arg2[0]) + rsr_size_req = convert(arg2); + break; + case 'r': + /* set the request/response sizes */ + break_args(optarg,arg1,arg2); + if (arg1[0]) + req_size = convert(arg1); + if (arg2[0]) + rsp_size = convert(arg2); + break; + case 'm': + /* set size of the buffer for each sent message */ + send_size = convert(optarg); + break; + case 'M': + /* set the size of the buffer for each received message */ + recv_size = convert(optarg); + break; + case 't': + /* set the test name */ + strcpy(test_name,optarg); + break; + case 'W': + /* set the "width" of the user space data */ + /* buffer. This will be the number of */ + /* send_size buffers malloc'd in the */ + /* *_STREAM test. It may be enhanced to set */ + /* both send and receive "widths" but for now */ + /* it is just the sending *_STREAM. */ + send_width = convert(optarg); + break; + case 'V': + /* we want to do copy avoidance and will set */ + /* it for everything, everywhere, if we really */ + /* can. of course, we don't know anything */ + /* about the remote... */ +#ifdef SO_SND_COPYAVOID + loc_sndavoid = 1; +#else + loc_sndavoid = 0; + printf("Local send copy avoidance not available.\n"); +#endif +#ifdef SO_RCV_COPYAVOID + loc_rcvavoid = 1; +#else + loc_rcvavoid = 0; + printf("Local recv copy avoidance not available.\n"); +#endif + rem_sndavoid = 1; + rem_rcvavoid = 1; + break; + case 'N': + /* this opton allows the user to set the number of + * messages to send. This in effect modifies the test + * time. If we know the message size, then the we can + * express the test time as message_size * number_messages + */ + msg_count = convert (optarg); + if (msg_count > 0) + test_time = 0; + break; + case 'B': + non_block = 1; + break; + case 'T': + num_associations = atoi(optarg); + if (num_associations <= 1) { + printf("Number of SCTP associations must be >= 1\n"); + exit(1); + } + break; + }; + } +} + +#endif /* WANT_SCTP */ diff --git a/src/nettest_sctp.h b/src/nettest_sctp.h new file mode 100644 index 0000000..5297853 --- /dev/null +++ b/src/nettest_sctp.h @@ -0,0 +1,128 @@ +/* + Copyright (C) 1993-2003 Hewlett-Packard Company +*/ + + /* This file contains the test-specific definitions for netperf's BSD */ + /* sockets tests */ + + +struct sctp_stream_request_struct { + int send_buf_size; + int recv_buf_size; /* how big does the client want it - the */ + /* receive socket buffer that is */ + int receive_size; /* how many bytes do we want to receive at one */ + /* time? */ + int recv_alignment; /* what is the alignment of the receive */ + /* buffer? */ + int recv_offset; /* and at what offset from that alignment? */ + int no_delay; /* do we disable the nagle algorithm for send */ + /* coalescing? */ + int measure_cpu; /* does the client want server cpu utilization */ + /* measured? */ + float cpu_rate; /* do we know how fast the cpu is already? */ + int test_length; /* how long is the test? */ + int so_rcvavoid; /* do we want the remote to avoid copies on */ + /* receives? */ + int so_sndavoid; /* do we want the remote to avoid send copies? */ + int dirty_count; /* how many integers in the receive buffer */ + /* should be made dirty before calling recv? */ + int clean_count; /* how many integers should be read from the */ + /* recv buffer before calling recv? */ + int port; /* the to port to which recv side should bind + to allow netperf to run through firewalls */ + int ipfamily; /* address family of ipaddress */ + int non_blocking; /* run the test in non-blocking mode */ +}; + +struct sctp_stream_response_struct { + int recv_buf_size; /* how big does the client want it */ + int receive_size; + int no_delay; + int measure_cpu; /* does the client want server cpu */ + int test_length; /* how long is the test? */ + int send_buf_size; + int data_port_number; /* connect to me here */ + float cpu_rate; /* could we measure */ + int so_rcvavoid; /* could the remote avoid receive copies? */ + int so_sndavoid; /* could the remote avoid send copies? */ + int non_blocking; /* run the test in non-blocking mode */ +}; + +struct sctp_stream_results_struct { + double bytes_received; + unsigned int recv_calls; + float elapsed_time; /* how long the test ran */ + float cpu_util; /* -1 if not measured */ + float serv_dem; /* -1 if not measured */ + int cpu_method; /* how was cpu util measured? */ + int num_cpus; /* how many CPUs had the remote? */ +}; + +struct sctp_rr_request_struct { + int recv_buf_size; /* how big does the client want it */ + int send_buf_size; + int recv_alignment; + int recv_offset; + int send_alignment; + int send_offset; + int request_size; + int response_size; + int no_delay; + int measure_cpu; /* does the client want server cpu */ + float cpu_rate; /* do we know how fast the cpu is? */ + int test_length; /* how long is the test? */ + int so_rcvavoid; /* do we want the remote to avoid receive */ + /* copies? */ + int so_sndavoid; /* do we want the remote to avoid send copies? */ + int port; /* the to port to which recv side should bind + to allow netperf to run through firewalls */ + int ipfamily; /* address family of ipaddress */ + int non_blocking; /* run the test in non-blocking mode */ +}; + +struct sctp_rr_response_struct { + int recv_buf_size; /* how big does the client want it */ + int no_delay; + int measure_cpu; /* does the client want server cpu */ + int test_length; /* how long is the test? */ + int send_buf_size; + int data_port_number; /* connect to me here */ + float cpu_rate; /* could we measure */ + int so_rcvavoid; /* could the remote avoid receive copies? */ + int so_sndavoid; /* could the remote avoid send copies? */ + int non_blocking; /* run the test in non-blocking mode */ +}; + +struct sctp_rr_results_struct { + unsigned int bytes_received; /* ignored initially */ + unsigned int recv_calls; /* ignored initially */ + unsigned int trans_received; /* not ignored */ + float elapsed_time; /* how long the test ran */ + float cpu_util; /* -1 if not measured */ + float serv_dem; /* -1 if not measured */ + int cpu_method; /* how was cpu util measured? */ + int num_cpus; /* how many CPUs had the remote? */ +}; + +#define SCTP_SNDRCV_INFO_EV 0x01 +#define SCTP_ASSOC_CHANGE_EV 0x02 +#define SCTP_PEERADDR_CHANGE_EV 0x04 +#define SCTP_SND_FAILED_EV 0x08 +#define SCTP_REMOTE_ERROR_EV 0x10 +#define SCTP_SHUTDOWN_EV 0x20 +#define SCTP_PD_EV 0x40 +#define SCTP_ADAPT_EV 0x80 + +typedef enum sctp_disposition { + SCTP_OK = 1, + SCTP_CLOSE, +} sctp_disposition_t; + +extern void send_sctp_stream(); +extern void send_sctp_rr(); + +extern void recv_sctp_stream(); +extern void recv_sctp_rr(); + +extern void loc_cpu_rate(); +extern void rem_cpu_rate(); diff --git a/src/nettest_sdp.c b/src/nettest_sdp.c new file mode 100644 index 0000000..696fd3e --- /dev/null +++ b/src/nettest_sdp.c @@ -0,0 +1,3553 @@ +#ifndef lint +char nettest_sdp[]="\ +@(#)nettest_sdp.c (c) Copyright 2007 Hewlett-Packard Co. Version 2.4.4"; +#else +#define DIRTY +#define WANT_HISTOGRAM +#define WANT_INTERVALS +#endif /* lint */ + +/****************************************************************/ +/* */ +/* nettest_sdp.c */ +/* */ +/* */ +/* scan_sdp_args() get the sdp command line args */ +/* */ +/* the actual test routines... */ +/* */ +/* send_sdp_stream() perform a sdp stream test */ +/* recv_sdp_stream() */ +/* send_sdp_rr() perform a sdp request/response */ +/* recv_sdp_rr() */ +/* */ +/* relies on create_data_socket in nettest_bsd.c */ +/****************************************************************/ + +#if HAVE_CONFIG_H +# include +#endif + +#if defined(WANT_SDP) + +#include +#include +#include +#include +#include +#include +#include +#ifdef NOSTDLIBH +#include +#else /* NOSTDLIBH */ +#include +#endif /* NOSTDLIBH */ + +#if !defined(__VMS) +#include +#endif /* !defined(__VMS) */ +#include +#include +#include +#include +#include +#include +#include + +/* would seem that not all sdp.h files define a MSG_EOF, but that + MSG_EOF can be the same as MSG_FIN so lets work with that + assumption. initial find by Jon Pedersen. raj 2006-02-01 */ +#ifndef MSG_EOF +#ifdef MSG_FIN +#define MSG_EOF MSG_FIN +#else +#error Must have either MSG_EOF or MSG_FIN defined +#endif +#endif + +#include "netlib.h" +#include "netsh.h" +/* get some of the functions from nettest_bsd.c */ +#include "nettest_bsd.h" +#include "nettest_sdp.h" + +#ifdef WANT_HISTOGRAM +#ifdef __sgi +#include +#endif /* __sgi */ +#include "hist.h" +#endif /* WANT_HISTOGRAM */ + +#ifdef WANT_FIRST_BURST +extern int first_burst_size; +#endif /* WANT_FIRST_BURST */ + + + +/* these variables are specific to SDP tests. declare */ +/* them static to make them global only to this file. */ + +static int + msg_count = 0, /* number of messages to transmit on association */ + non_block = 0, /* default to blocking sockets */ + num_associations = 1; /* number of associations on the endpoint */ + +static int confidence_iteration; +static char local_cpu_method; +static char remote_cpu_method; + +#ifdef WANT_HISTOGRAM +static struct timeval time_one; +static struct timeval time_two; +static HIST time_hist; +#endif /* WANT_HISTOGRAM */ + + +char sdp_usage[] = "\n\ +Usage: netperf [global options] -- [test options] \n\ +\n\ +SDP Sockets Test Options:\n\ + -b number Send number requests at the start of _RR tests\n\ + -D [L][,R] Set SDP_NODELAY locally and/or remotely\n\ + -h Display this text\n\ + -H name,fam Use name (or IP) and family as target of data connection\n\ + -L name,fam Use name (or IP) and family as source of data connextion\n\ + -m bytes Set the size of each sent message\n\ + -M bytes Set the size of each received messages\n\ + -P local[,remote] Set the local/remote port for the data socket\n\ + -r req,[rsp] Set request/response sizes (_RR tests)\n\ + -s send[,recv] Set local socket send/recv buffer sizes\n\ + -S send[,recv] Set remote socket send/recv buffer sizes\n\ + -V Enable copy avoidance if supported\n\ + -4 Use AF_INET (eg IPv4) on both ends of the data conn\n\ + -6 Use AF_INET6 (eg IPv6) on both ends of the data conn\n\ +\n\ +For those options taking two parms, at least one must be specified;\n\ +specifying one value without a comma will set both parms to that\n\ +value, specifying a value with a leading comma will set just the second\n\ +parm, a value with a trailing comma will set just the first. To set\n\ +each parm to unique values, specify both and separate them with a\n\ +comma.\n"; + + + /* This routine is intended to retrieve interesting aspects of sdp */ + /* for the data connection. at first, it attempts to retrieve the */ + /* maximum segment size. later, it might be modified to retrieve */ + /* other information, but it must be information that can be */ + /* retrieved quickly as it is called during the timing of the test. */ + /* for that reason, a second routine may be created that can be */ + /* called outside of the timing loop */ +static +void +get_sdp_info(int socket, int * mss) +{ + +#ifdef TCP_MAXSEG + netperf_socklen_t sock_opt_len; + + sock_opt_len = sizeof(netperf_socklen_t); + if (getsockopt(socket, + getprotobyname("tcp")->p_proto, + TCP_MAXSEG, + (char *)mss, + &sock_opt_len) == SOCKET_ERROR) { + fprintf(where, + "netperf: get_sdp_info: getsockopt TCP_MAXSEG: errno %d\n", + errno); + fflush(where); + *mss = -1; + } +#else + *mss = -1; +#endif /* TCP_MAXSEG */ + +} + +void +send_sdp_stream(char remote_host[]) +{ + + char *tput_title = "\ +Recv Send Send \n\ +Socket Socket Message Elapsed \n\ +Size Size Size Time Throughput \n\ +bytes bytes bytes secs. %s/sec \n\n"; + + char *tput_fmt_0 = + "%7.2f %s\n"; + + char *tput_fmt_1 = + "%6d %6d %6d %-6.2f %7.2f %s\n"; + + char *cpu_title = "\ +Recv Send Send Utilization Service Demand\n\ +Socket Socket Message Elapsed Send Recv Send Recv\n\ +Size Size Size Time Throughput local remote local remote\n\ +bytes bytes bytes secs. %-8.8s/s %% %c %% %c us/KB us/KB\n\n"; + + char *cpu_fmt_0 = + "%6.3f %c %s\n"; + + char *cpu_fmt_1 = + "%6d %6d %6d %-6.2f %7.2f %-6.2f %-6.2f %-6.3f %-6.3f %s\n"; + + char *ksink_fmt = "\n\ +Alignment Offset %-8.8s %-8.8s Sends %-8.8s Recvs\n\ +Local Remote Local Remote Xfered Per Per\n\ +Send Recv Send Recv Send (avg) Recv (avg)\n\ +%5d %5d %5d %5d %6.4g %6.2f %6d %6.2f %6d\n"; + + char *ksink_fmt2 = "\n\ +Maximum\n\ +Segment\n\ +Size (bytes)\n\ +%6d\n"; + + + float elapsed_time; + + /* what we want is to have a buffer space that is at least one */ + /* send-size greater than our send window. this will insure that we */ + /* are never trying to re-use a buffer that may still be in the hands */ + /* of the transport. This buffer will be malloc'd after we have found */ + /* the size of the local senc socket buffer. We will want to deal */ + /* with alignment and offset concerns as well. */ + + struct ring_elt *send_ring; + + int len; + unsigned int nummessages = 0; + SOCKET send_socket; + int bytes_remaining; + int sdp_mss = -1; /* possibly uninitialized on printf far below */ + + /* with links like fddi, one can send > 32 bits worth of bytes */ + /* during a test... ;-) at some point, this should probably become a */ + /* 64bit integral type, but those are not entirely common yet */ + + unsigned long long local_bytes_sent = 0; + double bytes_sent = 0.0; + + float local_cpu_utilization; + float local_service_demand; + float remote_cpu_utilization; + float remote_service_demand; + + double thruput; + + struct addrinfo *remote_res; + struct addrinfo *local_res; + + struct sdp_stream_request_struct *sdp_stream_request; + struct sdp_stream_response_struct *sdp_stream_response; + struct sdp_stream_results_struct *sdp_stream_result; + + sdp_stream_request = + (struct sdp_stream_request_struct *)netperf_request.content.test_specific_data; + sdp_stream_response = + (struct sdp_stream_response_struct *)netperf_response.content.test_specific_data; + sdp_stream_result = + (struct sdp_stream_results_struct *)netperf_response.content.test_specific_data; + +#ifdef WANT_HISTOGRAM + if (verbosity > 1) { + time_hist = HIST_new(); + } +#endif /* WANT_HISTOGRAM */ + /* since we are now disconnected from the code that established the */ + /* control socket, and since we want to be able to use different */ + /* protocols and such, we are passed the name of the remote host and */ + /* must turn that into the test specific addressing information. */ + + /* complete_addrinfos will either succede or exit the process */ + complete_addrinfos(&remote_res, + &local_res, + remote_host, + SOCK_STREAM, + IPPROTO_TCP, + 0); + + if ( print_headers ) { + print_top_test_header("SDP STREAM TEST",local_res,remote_res); + } + + send_ring = NULL; + confidence_iteration = 1; + init_stat(); + + /* we have a great-big while loop which controls the number of times */ + /* we run a particular test. this is for the calculation of a */ + /* confidence interval (I really should have stayed awake during */ + /* probstats :). If the user did not request confidence measurement */ + /* (no confidence is the default) then we will only go though the */ + /* loop once. the confidence stuff originates from the folks at IBM */ + + while (((confidence < 0) && (confidence_iteration < iteration_max)) || + (confidence_iteration <= iteration_min)) { + + /* initialize a few counters. we have to remember that we might be */ + /* going through the loop more than once. */ + + nummessages = 0; + bytes_sent = 0.0; + times_up = 0; + + /*set up the data socket */ + /* fake things out by changing local_res->ai_family to AF_INET_SDP */ + local_res->ai_family = AF_INET_SDP; + local_res->ai_protocol = 0; + send_socket = create_data_socket(local_res); + + if (send_socket == INVALID_SOCKET){ + perror("netperf: send_sdp_stream: sdp stream data socket"); + exit(1); + } + + if (debug) { + fprintf(where,"send_sdp_stream: send_socket obtained...\n"); + } + + /* at this point, we have either retrieved the socket buffer sizes, */ + /* or have tried to set them, so now, we may want to set the send */ + /* size based on that (because the user either did not use a -m */ + /* option, or used one with an argument of 0). If the socket buffer */ + /* size is not available, we will set the send size to 4KB - no */ + /* particular reason, just arbitrary... */ + if (send_size == 0) { + if (lss_size > 0) { + send_size = lss_size; + } + else { + send_size = 4096; + } + } + + /* set-up the data buffer ring with the requested alignment and offset. */ + /* note also that we have allocated a quantity */ + /* of memory that is at least one send-size greater than our socket */ + /* buffer size. We want to be sure that there are at least two */ + /* buffers allocated - this can be a bit of a problem when the */ + /* send_size is bigger than the socket size, so we must check... the */ + /* user may have wanted to explicitly set the "width" of our send */ + /* buffers, we should respect that wish... */ + if (send_width == 0) { + send_width = (lss_size/send_size) + 1; + if (send_width == 1) send_width++; + } + + if (send_ring == NULL) { + /* only allocate the send ring once. this is a networking test, */ + /* not a memory allocation test. this way, we do not need a */ + /* deallocate_buffer_ring() routine, and I don't feel like */ + /* writing one anyway :) raj 11/94 */ + send_ring = allocate_buffer_ring(send_width, + send_size, + local_send_align, + local_send_offset); + } + + /* If the user has requested cpu utilization measurements, we must */ + /* calibrate the cpu(s). We will perform this task within the tests */ + /* themselves. If the user has specified the cpu rate, then */ + /* calibrate_local_cpu will return rather quickly as it will have */ + /* nothing to do. If local_cpu_rate is zero, then we will go through */ + /* all the "normal" calibration stuff and return the rate back. */ + + if (local_cpu_usage) { + local_cpu_rate = calibrate_local_cpu(local_cpu_rate); + } + + if (!no_control) { + /* Tell the remote end to do a listen. The server alters the + socket paramters on the other side at this point, hence the + reason for all the values being passed in the setup + message. If the user did not specify any of the parameters, + they will be passed as 0, which will indicate to the remote + that no changes beyond the system's default should be + used. Alignment is the exception, it will default to 1, which + will be no alignment alterations. */ + + netperf_request.content.request_type = DO_SDP_STREAM; + sdp_stream_request->send_buf_size = rss_size_req; + sdp_stream_request->recv_buf_size = rsr_size_req; + sdp_stream_request->receive_size = recv_size; + sdp_stream_request->no_delay = rem_nodelay; + sdp_stream_request->recv_alignment = remote_recv_align; + sdp_stream_request->recv_offset = remote_recv_offset; + sdp_stream_request->measure_cpu = remote_cpu_usage; + sdp_stream_request->cpu_rate = remote_cpu_rate; + if (test_time) { + sdp_stream_request->test_length = test_time; + } + else { + sdp_stream_request->test_length = test_bytes; + } + sdp_stream_request->so_rcvavoid = rem_rcvavoid; + sdp_stream_request->so_sndavoid = rem_sndavoid; +#ifdef DIRTY + sdp_stream_request->dirty_count = rem_dirty_count; + sdp_stream_request->clean_count = rem_clean_count; +#endif /* DIRTY */ + sdp_stream_request->port = atoi(remote_data_port); + sdp_stream_request->ipfamily = af_to_nf(remote_res->ai_family); + if (debug > 1) { + fprintf(where, + "netperf: send_sdp_stream: requesting SDP stream test\n"); + } + + send_request(); + + /* The response from the remote will contain all of the relevant + socket parameters for this test type. We will put them back + into the variables here so they can be displayed if desired. + The remote will have calibrated CPU if necessary, and will + have done all the needed set-up we will have calibrated the + cpu locally before sending the request, and will grab the + counter value right after the connect returns. The remote + will grab the counter right after the accept call. This saves + the hassle of extra messages being sent for the SDP + tests. */ + + recv_response(); + + if (!netperf_response.content.serv_errno) { + if (debug) + fprintf(where,"remote listen done.\n"); + rsr_size = sdp_stream_response->recv_buf_size; + rss_size = sdp_stream_response->send_buf_size; + rem_nodelay = sdp_stream_response->no_delay; + remote_cpu_usage= sdp_stream_response->measure_cpu; + remote_cpu_rate = sdp_stream_response->cpu_rate; + + /* we have to make sure that the server port number is in + network order */ + set_port_number(remote_res, + (short)sdp_stream_response->data_port_number); + + rem_rcvavoid = sdp_stream_response->so_rcvavoid; + rem_sndavoid = sdp_stream_response->so_sndavoid; + } + else { + Set_errno(netperf_response.content.serv_errno); + fprintf(where, + "netperf: remote error %d", + netperf_response.content.serv_errno); + perror(""); + fflush(where); + + exit(1); + } + } + +#ifdef WANT_DEMO + DEMO_STREAM_SETUP(lss_size,rsr_size) +#endif + + /*Connect up to the remote port on the data socket */ + if (connect(send_socket, + remote_res->ai_addr, + remote_res->ai_addrlen) == INVALID_SOCKET){ + perror("netperf: send_sdp_stream: data socket connect failed"); + exit(1); + } + + /* Data Socket set-up is finished. If there were problems, either */ + /* the connect would have failed, or the previous response would */ + /* have indicated a problem. I failed to see the value of the */ + /* extra message after the accept on the remote. If it failed, */ + /* we'll see it here. If it didn't, we might as well start pumping */ + /* data. */ + + /* Set-up the test end conditions. For a stream test, they can be */ + /* either time or byte-count based. */ + + if (test_time) { + /* The user wanted to end the test after a period of time. */ + times_up = 0; + bytes_remaining = 0; + /* in previous revisions, we had the same code repeated throught */ + /* all the test suites. this was unnecessary, and meant more */ + /* work for me when I wanted to switch to POSIX signals, so I */ + /* have abstracted this out into a routine in netlib.c. if you */ + /* are experiencing signal problems, you might want to look */ + /* there. raj 11/94 */ + start_timer(test_time); + } + else { + /* The tester wanted to send a number of bytes. */ + bytes_remaining = test_bytes; + times_up = 1; + } + + /* The cpu_start routine will grab the current time and possibly */ + /* value of the idle counter for later use in measuring cpu */ + /* utilization and/or service demand and thruput. */ + + cpu_start(local_cpu_usage); + + /* we only start the interval timer if we are using the + timer-timed intervals rather than the sit and spin ones. raj + 2006-02-06 */ +#if defined(WANT_INTERVALS) + INTERVALS_INIT(); +#endif /* WANT_INTERVALS */ + + /* before we start, initialize a few variables */ + +#ifdef WANT_DEMO + if (demo_mode) { + HIST_timestamp(demo_one_ptr); + } +#endif + + + /* We use an "OR" to control test execution. When the test is */ + /* controlled by time, the byte count check will always return false. */ + /* When the test is controlled by byte count, the time test will */ + /* always return false. When the test is finished, the whole */ + /* expression will go false and we will stop sending data. */ + + while ((!times_up) || (bytes_remaining > 0)) { + +#ifdef DIRTY + access_buffer(send_ring->buffer_ptr, + send_size, + loc_dirty_count, + loc_clean_count); +#endif /* DIRTY */ + +#ifdef WANT_HISTOGRAM + if (verbosity > 1) { + /* timestamp just before we go into send and then again just + after we come out raj 8/94 */ + /* but lets only do this if there is going to be a histogram + displayed */ + HIST_timestamp(&time_one); + } +#endif /* WANT_HISTOGRAM */ + + if((len=send(send_socket, + send_ring->buffer_ptr, + send_size, + 0)) != send_size) { + if ((len >=0) || SOCKET_EINTR(len)) { + /* the test was interrupted, must be the end of test */ + break; + } + perror("netperf: data send error"); + printf("len was %d\n",len); + exit(1); + } + + local_bytes_sent += send_size; + +#ifdef WANT_HISTOGRAM + if (verbosity > 1) { + /* timestamp the exit from the send call and update the histogram */ + HIST_timestamp(&time_two); + HIST_add(time_hist,delta_micro(&time_one,&time_two)); + } +#endif /* WANT_HISTOGRAM */ + +#ifdef WANT_DEMO + DEMO_STREAM_INTERVAL(send_size) +#endif + +#if defined(WANT_INTERVALS) + INTERVALS_WAIT(); +#endif /* WANT_INTERVALS */ + + /* now we want to move our pointer to the next position in the */ + /* data buffer...we may also want to wrap back to the "beginning" */ + /* of the bufferspace, so we will mod the number of messages sent */ + /* by the send width, and use that to calculate the offset to add */ + /* to the base pointer. */ + nummessages++; + send_ring = send_ring->next; + if (bytes_remaining) { + bytes_remaining -= send_size; + } + } + + /* The test is over. Flush the buffers to the remote end. We do a */ + /* graceful release to insure that all data has been taken by the */ + /* remote. */ + + /* but first, if the verbosity is greater than 1, find-out what */ + /* the SDP maximum segment_size was (if possible) */ + if (verbosity > 1) { + sdp_mss = -1; + get_sdp_info(send_socket,&sdp_mss); + } + + if (shutdown(send_socket,SHUT_WR) == SOCKET_ERROR) { + perror("netperf: cannot shutdown sdp stream socket"); + exit(1); + } + + /* hang a recv() off the socket to block until the remote has */ + /* brought all the data up into the application. it will do a */ + /* shutdown to cause a FIN to be sent our way. We will assume that */ + /* any exit from the recv() call is good... raj 4/93 */ + + recv(send_socket, send_ring->buffer_ptr, send_size, 0); + + /* this call will always give us the elapsed time for the test, and */ + /* will also store-away the necessaries for cpu utilization */ + + cpu_stop(local_cpu_usage,&elapsed_time); /* was cpu being */ + /* measured and how */ + /* long did we really */ + /* run? */ + + /* we are finished with the socket, so close it to prevent hitting */ + /* the limit on maximum open files. */ + + close(send_socket); + + if (!no_control) { + /* Get the statistics from the remote end. The remote will have + calculated service demand and all those interesting + things. If it wasn't supposed to care, it will return obvious + values. */ + + recv_response(); + if (!netperf_response.content.serv_errno) { + if (debug) + fprintf(where,"remote results obtained\n"); + } + else { + Set_errno(netperf_response.content.serv_errno); + fprintf(where, + "netperf: remote error %d", + netperf_response.content.serv_errno); + perror(""); + fflush(where); + + exit(1); + } + + /* We now calculate what our thruput was for the test. In the + future, we may want to include a calculation of the thruput + measured by the remote, but it should be the case that for a + SDP stream test, that the two numbers should be *very* + close... We calculate bytes_sent regardless of the way the + test length was controlled. If it was time, we needed to, + and if it was by bytes, the user may have specified a number + of bytes that wasn't a multiple of the send_size, so we + really didn't send what he asked for ;-) */ + + bytes_sent = ntohd(sdp_stream_result->bytes_received); + } + else { + bytes_sent = (double)local_bytes_sent; + } + + thruput = calc_thruput(bytes_sent); + + if (local_cpu_usage || remote_cpu_usage) { + /* We must now do a little math for service demand and cpu */ + /* utilization for the system(s) */ + /* Of course, some of the information might be bogus because */ + /* there was no idle counter in the kernel(s). We need to make */ + /* a note of this for the user's benefit...*/ + if (local_cpu_usage) { + + local_cpu_utilization = calc_cpu_util(0.0); + local_service_demand = calc_service_demand(bytes_sent, + 0.0, + 0.0, + 0); + } + else { + local_cpu_utilization = (float) -1.0; + local_service_demand = (float) -1.0; + } + + if (remote_cpu_usage) { + + remote_cpu_utilization = sdp_stream_result->cpu_util; + remote_service_demand = calc_service_demand(bytes_sent, + 0.0, + remote_cpu_utilization, + sdp_stream_result->num_cpus); + } + else { + remote_cpu_utilization = (float) -1.0; + remote_service_demand = (float) -1.0; + } + } + else { + /* we were not measuring cpu, for the confidence stuff, we */ + /* should make it -1.0 */ + local_cpu_utilization = (float) -1.0; + local_service_demand = (float) -1.0; + remote_cpu_utilization = (float) -1.0; + remote_service_demand = (float) -1.0; + } + + /* at this point, we want to calculate the confidence information. */ + /* if debugging is on, calculate_confidence will print-out the */ + /* parameters we pass it */ + + calculate_confidence(confidence_iteration, + elapsed_time, + thruput, + local_cpu_utilization, + remote_cpu_utilization, + local_service_demand, + remote_service_demand); + + + confidence_iteration++; + } + + /* at this point, we have finished making all the runs that we */ + /* will be making. so, we should extract what the calcuated values */ + /* are for all the confidence stuff. we could make the values */ + /* global, but that seemed a little messy, and it did not seem worth */ + /* all the mucking with header files. so, we create a routine much */ + /* like calcualte_confidence, which just returns the mean values. */ + /* raj 11/94 */ + + retrieve_confident_values(&elapsed_time, + &thruput, + &local_cpu_utilization, + &remote_cpu_utilization, + &local_service_demand, + &remote_service_demand); + + /* We are now ready to print all the information. If the user */ + /* has specified zero-level verbosity, we will just print the */ + /* local service demand, or the remote service demand. If the */ + /* user has requested verbosity level 1, he will get the basic */ + /* "streamperf" numbers. If the user has specified a verbosity */ + /* of greater than 1, we will display a veritable plethora of */ + /* background information from outside of this block as it it */ + /* not cpu_measurement specific... */ + + if (confidence < 0) { + /* we did not hit confidence, but were we asked to look for it? */ + if (iteration_max > 1) { + display_confidence(); + } + } + + if (local_cpu_usage || remote_cpu_usage) { + local_cpu_method = format_cpu_method(cpu_method); + remote_cpu_method = format_cpu_method(sdp_stream_result->cpu_method); + + switch (verbosity) { + case 0: + if (local_cpu_usage) { + fprintf(where, + cpu_fmt_0, + local_service_demand, + local_cpu_method, + ((print_headers) || + (result_brand == NULL)) ? "" : result_brand); + } + else { + fprintf(where, + cpu_fmt_0, + remote_service_demand, + remote_cpu_method, + ((print_headers) || + (result_brand == NULL)) ? "" : result_brand); + } + break; + case 1: + case 2: + if (print_headers) { + fprintf(where, + cpu_title, + format_units(), + local_cpu_method, + remote_cpu_method); + } + + fprintf(where, + cpu_fmt_1, /* the format string */ + rsr_size, /* remote recvbuf size */ + lss_size, /* local sendbuf size */ + send_size, /* how large were the sends */ + elapsed_time, /* how long was the test */ + thruput, /* what was the xfer rate */ + local_cpu_utilization, /* local cpu */ + remote_cpu_utilization, /* remote cpu */ + local_service_demand, /* local service demand */ + remote_service_demand, /* remote service demand */ + ((print_headers) || + (result_brand == NULL)) ? "" : result_brand); + break; + } + } + else { + /* The tester did not wish to measure service demand. */ + + switch (verbosity) { + case 0: + fprintf(where, + tput_fmt_0, + thruput, + ((print_headers) || + (result_brand == NULL)) ? "" : result_brand); + break; + case 1: + case 2: + if (print_headers) { + fprintf(where,tput_title,format_units()); + } + fprintf(where, + tput_fmt_1, /* the format string */ + rsr_size, /* remote recvbuf size */ + lss_size, /* local sendbuf size */ + send_size, /* how large were the sends */ + elapsed_time, /* how long did it take */ + thruput, /* how fast did it go */ + ((print_headers) || + (result_brand == NULL)) ? "" : result_brand); + break; + } + } + + /* it would be a good thing to include information about some of the */ + /* other parameters that may have been set for this test, but at the */ + /* moment, I do not wish to figure-out all the formatting, so I will */ + /* just put this comment here to help remind me that it is something */ + /* that should be done at a later time. */ + + if (verbosity > 1) { + /* The user wanted to know it all, so we will give it to him. */ + /* This information will include as much as we can find about */ + /* SDP statistics, the alignments of the sends and receives */ + /* and all that sort of rot... */ + + /* this stuff needs to be worked-out in the presence of confidence */ + /* intervals and multiple iterations of the test... raj 11/94 */ + + fprintf(where, + ksink_fmt, + "Bytes", + "Bytes", + "Bytes", + local_send_align, + remote_recv_align, + local_send_offset, + remote_recv_offset, + bytes_sent, + bytes_sent / (double)nummessages, + nummessages, + bytes_sent / (double)sdp_stream_result->recv_calls, + sdp_stream_result->recv_calls); + fprintf(where, + ksink_fmt2, + sdp_mss); + fflush(where); +#ifdef WANT_HISTOGRAM + fprintf(where,"\n\nHistogram of time spent in send() call.\n"); + fflush(where); + HIST_report(time_hist); +#endif /* WANT_HISTOGRAM */ + } + +} + + + +/* This routine implements the netperf-side SDP unidirectional data + transfer test (a.k.a. stream) for the sockets interface where the + data flow is from the netserver to the netperf. It receives its + parameters via global variables from the shell and writes its + output to the standard output. */ + + +void +send_sdp_maerts(char remote_host[]) +{ + + char *tput_title = "\ +Recv Send Send \n\ +Socket Socket Message Elapsed \n\ +Size Size Size Time Throughput \n\ +bytes bytes bytes secs. %s/sec \n\n"; + + char *tput_fmt_0 = + "%7.2f %s\n"; + + char *tput_fmt_1 = + "%6d %6d %6d %-6.2f %7.2f \n %s"; + + char *cpu_title = "\ +Recv Send Send Utilization Service Demand\n\ +Socket Socket Message Elapsed Send Recv Send Recv\n\ +Size Size Size Time Throughput local remote local remote\n\ +bytes bytes bytes secs. %-8.8s/s %% %c %% %c us/KB us/KB\n\n"; + + char *cpu_fmt_0 = + "%6.3f %c %s\n"; + + char *cpu_fmt_1 = + "%6d %6d %6d %-6.2f %7.2f %-6.2f %-6.2f %-6.3f %-6.3f %s\n"; + + char *ksink_fmt = "\n\ +Alignment Offset %-8.8s %-8.8s Recvs %-8.8s Sends\n\ +Local Remote Local Remote Xfered Per Per\n\ +Recv Send Recv Send Recv (avg) Send (avg)\n\ +%5d %5d %5d %5d %6.4g %6.2f %6d %6.2f %6d\n"; + + char *ksink_fmt2 = "\n\ +Maximum\n\ +Segment\n\ +Size (bytes)\n\ +%6d\n"; + + + float elapsed_time; + + /* what we want is to have a buffer space that is at least one */ + /* recv-size greater than our recv window. this will insure that we */ + /* are never trying to re-use a buffer that may still be in the hands */ + /* of the transport. This buffer will be malloc'd after we have found */ + /* the size of the local senc socket buffer. We will want to deal */ + /* with alignment and offset concerns as well. */ + + struct ring_elt *recv_ring; + + int len; + unsigned int nummessages = 0; + SOCKET recv_socket; + int bytes_remaining; + int sdp_mss = -1; /* possibly uninitialized on printf far below */ + + /* with links like fddi, one can recv > 32 bits worth of bytes */ + /* during a test... ;-) at some point, this should probably become a */ + /* 64bit integral type, but those are not entirely common yet */ + double bytes_sent = 0.0; + unsigned long long local_bytes_recvd = 0; + + float local_cpu_utilization; + float local_service_demand; + float remote_cpu_utilization; + float remote_service_demand; + + double thruput; + + struct addrinfo *remote_res; + struct addrinfo *local_res; + + struct sdp_maerts_request_struct *sdp_maerts_request; + struct sdp_maerts_response_struct *sdp_maerts_response; + struct sdp_maerts_results_struct *sdp_maerts_result; + + sdp_maerts_request = + (struct sdp_maerts_request_struct *)netperf_request.content.test_specific_data; + sdp_maerts_response = + (struct sdp_maerts_response_struct *)netperf_response.content.test_specific_data; + sdp_maerts_result = + (struct sdp_maerts_results_struct *)netperf_response.content.test_specific_data; + +#ifdef WANT_HISTOGRAM + if (verbosity > 1) { + time_hist = HIST_new(); + } +#endif /* WANT_HISTOGRAM */ + /* since we are now disconnected from the code that established the */ + /* control socket, and since we want to be able to use different */ + /* protocols and such, we are passed the name of the remote host and */ + /* must turn that into the test specific addressing information. */ + + complete_addrinfos(&remote_res, + &local_res, + remote_host, + SOCK_STREAM, + IPPROTO_TCP, + 0); + + if ( print_headers ) { + print_top_test_header("SDP MAERTS TEST",local_res,remote_res); + } + + recv_ring = NULL; + confidence_iteration = 1; + init_stat(); + + /* we have a great-big while loop which controls the number of times */ + /* we run a particular test. this is for the calculation of a */ + /* confidence interval (I really should have stayed awake during */ + /* probstats :). If the user did not request confidence measurement */ + /* (no confidence is the default) then we will only go though the */ + /* loop once. the confidence stuff originates from the folks at IBM */ + + while (((confidence < 0) && (confidence_iteration < iteration_max)) || + (confidence_iteration <= iteration_min)) { + + /* initialize a few counters. we have to remember that we might be */ + /* going through the loop more than once. */ + + nummessages = 0; + bytes_sent = 0.0; + times_up = 0; + + /*set up the data socket */ + /* fake things out by changing local_res->ai_family to AF_INET_SDP */ + local_res->ai_family = AF_INET_SDP; + local_res->ai_protocol = 0; + recv_socket = create_data_socket(local_res); + + if (recv_socket == INVALID_SOCKET){ + perror("netperf: send_sdp_maerts: sdp stream data socket"); + exit(1); + } + + if (debug) { + fprintf(where,"send_sdp_maerts: recv_socket obtained...\n"); + } + + /* at this point, we have either retrieved the socket buffer sizes, */ + /* or have tried to set them, so now, we may want to set the recv */ + /* size based on that (because the user either did not use a -m */ + /* option, or used one with an argument of 0). If the socket buffer */ + /* size is not available, we will set the recv size to 4KB - no */ + /* particular reason, just arbitrary... */ + if (recv_size == 0) { + if (lsr_size > 0) { + recv_size = lsr_size; + } + else { + recv_size = 4096; + } + } + + /* set-up the data buffer ring with the requested alignment and offset. */ + /* note also that we have allocated a quantity */ + /* of memory that is at least one recv-size greater than our socket */ + /* buffer size. We want to be sure that there are at least two */ + /* buffers allocated - this can be a bit of a problem when the */ + /* recv_size is bigger than the socket size, so we must check... the */ + /* user may have wanted to explicitly set the "width" of our recv */ + /* buffers, we should respect that wish... */ + if (recv_width == 0) { + recv_width = (lsr_size/recv_size) + 1; + if (recv_width == 1) recv_width++; + } + + if (recv_ring == NULL) { + /* only allocate the recv ring once. this is a networking test, */ + /* not a memory allocation test. this way, we do not need a */ + /* deallocate_buffer_ring() routine, and I don't feel like */ + /* writing one anyway :) raj 11/94 */ + recv_ring = allocate_buffer_ring(recv_width, + recv_size, + local_recv_align, + local_recv_offset); + } + + /* If the user has requested cpu utilization measurements, we must */ + /* calibrate the cpu(s). We will perform this task within the tests */ + /* themselves. If the user has specified the cpu rate, then */ + /* calibrate_local_cpu will return rather quickly as it will have */ + /* nothing to do. If local_cpu_rate is zero, then we will go through */ + /* all the "normal" calibration stuff and return the rate back. */ + + if (local_cpu_usage) { + local_cpu_rate = calibrate_local_cpu(local_cpu_rate); + } + + if (!no_control) { + /* Tell the remote end to do a listen. The server alters the + socket paramters on the other side at this point, hence the + reason for all the values being passed in the setup + message. If the user did not specify any of the parameters, + they will be passed as 0, which will indicate to the remote + that no changes beyond the system's default should be + used. Alignment is the exception, it will default to 1, which + will be no alignment alterations. */ + + netperf_request.content.request_type = DO_SDP_MAERTS; + sdp_maerts_request->send_buf_size = rss_size_req; + sdp_maerts_request->recv_buf_size = rsr_size_req; + sdp_maerts_request->send_size = send_size; + sdp_maerts_request->no_delay = rem_nodelay; + sdp_maerts_request->send_alignment = remote_send_align; + sdp_maerts_request->send_offset = remote_send_offset; + sdp_maerts_request->measure_cpu = remote_cpu_usage; + sdp_maerts_request->cpu_rate = remote_cpu_rate; + if (test_time) { + sdp_maerts_request->test_length = test_time; + } + else { + sdp_maerts_request->test_length = test_bytes; + } + sdp_maerts_request->so_rcvavoid = rem_rcvavoid; + sdp_maerts_request->so_sndavoid = rem_sndavoid; +#ifdef DIRTY + sdp_maerts_request->dirty_count = rem_dirty_count; + sdp_maerts_request->clean_count = rem_clean_count; +#endif /* DIRTY */ + sdp_maerts_request->port = atoi(remote_data_port); + sdp_maerts_request->ipfamily = af_to_nf(remote_res->ai_family); + if (debug > 1) { + fprintf(where, + "netperf: send_sdp_maerts: requesting SDP maerts test\n"); + } + + send_request(); + + /* The response from the remote will contain all of the relevant + socket parameters for this test type. We will put them back + into the variables here so they can be displayed if desired. + The remote will have calibrated CPU if necessary, and will + have done all the needed set-up we will have calibrated the + cpu locally before sending the request, and will grab the + counter value right after the connect returns. The remote + will grab the counter right after the accept call. This saves + the hassle of extra messages being sent for the SDP + tests. */ + + recv_response(); + + if (!netperf_response.content.serv_errno) { + if (debug) + fprintf(where,"remote listen done.\n"); + rsr_size = sdp_maerts_response->recv_buf_size; + rss_size = sdp_maerts_response->send_buf_size; + rem_nodelay = sdp_maerts_response->no_delay; + remote_cpu_usage= sdp_maerts_response->measure_cpu; + remote_cpu_rate = sdp_maerts_response->cpu_rate; + send_size = sdp_maerts_response->send_size; + + /* we have to make sure that the server port number is in + network order */ + set_port_number(remote_res, + (short)sdp_maerts_response->data_port_number); + rem_rcvavoid = sdp_maerts_response->so_rcvavoid; + rem_sndavoid = sdp_maerts_response->so_sndavoid; + } + else { + Set_errno(netperf_response.content.serv_errno); + fprintf(where, + "netperf: remote error %d", + netperf_response.content.serv_errno); + perror(""); + fflush(where); + + exit(1); + } + } + +#ifdef WANT_DEMO + DEMO_STREAM_SETUP(lsr_size,rss_size) +#endif + + /*Connect up to the remote port on the data socket */ + if (connect(recv_socket, + remote_res->ai_addr, + remote_res->ai_addrlen) == INVALID_SOCKET){ + perror("netperf: send_sdp_maerts: data socket connect failed"); + exit(1); + } + + /* Data Socket set-up is finished. If there were problems, either */ + /* the connect would have failed, or the previous response would */ + /* have indicated a problem. I failed to see the value of the */ + /* extra message after the accept on the remote. If it failed, */ + /* we'll see it here. If it didn't, we might as well start pumping */ + /* data. */ + + /* Set-up the test end conditions. For a maerts test, they can be */ + /* either time or byte-count based. */ + + if (test_time) { + /* The user wanted to end the test after a period of time. */ + times_up = 0; + bytes_remaining = 0; + /* in previous revisions, we had the same code repeated throught */ + /* all the test suites. this was unnecessary, and meant more */ + /* work for me when I wanted to switch to POSIX signals, so I */ + /* have abstracted this out into a routine in netlib.c. if you */ + /* are experiencing signal problems, you might want to look */ + /* there. raj 11/94 */ + if (!no_control) { + /* this is a netperf to netserver test, netserver will close + to tell us the test is over, so use PAD_TIME to avoid + causing the netserver fits. */ + start_timer(test_time + PAD_TIME); + } + else { + /* this is a netperf to data source test, no PAD_TIME */ + start_timer(test_time); + } + } + else { + /* The tester wanted to recv a number of bytes. we don't do that + in a SDP_MAERTS test. sorry. raj 2002-06-21 */ + printf("netperf: send_sdp_maerts: test must be timed\n"); + exit(1); + } + + /* The cpu_start routine will grab the current time and possibly */ + /* value of the idle counter for later use in measuring cpu */ + /* utilization and/or service demand and thruput. */ + + cpu_start(local_cpu_usage); + +#ifdef WANT_INTERVALS + INTERVALS_INIT(); +#endif /* WANT_INTERVALS */ + + /* before we start, initialize a few variables */ + +#ifdef WANT_DEMO + if (demo_mode) { + HIST_timestamp(demo_one_ptr); + } +#endif + + /* the test will continue until we either get a zero-byte recv() + on the socket or our failsafe timer expires. most of the time + we trust that we get a zero-byte recieve from the socket. raj + 2002-06-21 */ + +#ifdef WANT_HISTOGRAM + if (verbosity > 1) { + /* timestamp just before we go into recv and then again just + after we come out raj 8/94 */ + /* but only if we are actually going to display a histogram. raj + 2006-02-07 */ + HIST_timestamp(&time_one); + } +#endif /* WANT_HISTOGRAM */ + + while ((!times_up) && (len=recv(recv_socket, + recv_ring->buffer_ptr, + recv_size, + 0)) > 0 ) { + +#ifdef WANT_HISTOGRAM + if (verbosity > 1) { + /* timestamp the exit from the recv call and update the histogram */ + HIST_timestamp(&time_two); + HIST_add(time_hist,delta_micro(&time_one,&time_two)); + } +#endif /* WANT_HISTOGRAM */ + +#ifdef DIRTY + access_buffer(recv_ring->buffer_ptr, + recv_size, + loc_dirty_count, + loc_clean_count); +#endif /* DIRTY */ + +#ifdef WANT_DEMO + DEMO_STREAM_INTERVAL(len); +#endif + +#ifdef WANT_INTERVALS + INTERVALS_WAIT(); +#endif /* WANT_INTERVALS */ + + /* now we want to move our pointer to the next position in the */ + /* data buffer...we may also want to wrap back to the "beginning" */ + /* of the bufferspace, so we will mod the number of messages sent */ + /* by the recv width, and use that to calculate the offset to add */ + /* to the base pointer. */ + nummessages++; + recv_ring = recv_ring->next; + if (bytes_remaining) { + bytes_remaining -= len; + } + + local_bytes_recvd += len; + +#ifdef WANT_HISTOGRAM + if (verbosity > 1) { + /* make sure we timestamp just before we go into recv */ + /* raj 2004-06-15 */ + HIST_timestamp(&time_one); + } +#endif /* WANT_HISTOGRAM */ + + } + + /* an EINTR is to be expected when this is a no_control test */ + if (((len < 0) || SOCKET_EINTR(len)) && (!no_control)) { + perror("send_sdp_maerts: data recv error"); + printf("len was %d\n",len); + exit(1); + } + + /* if we get here, it must mean we had a recv return of 0 before + the watchdog timer expired, or the watchdog timer expired and + this was a no_control test */ + + /* The test is over. Flush the buffers to the remote end. We do a + graceful release to tell the remote we have all the data. */ + + /* but first, if the verbosity is greater than 1, find-out what */ + /* the SDP maximum segment_size was (if possible) */ + if (verbosity > 1) { + sdp_mss = -1; + get_sdp_info(recv_socket,&sdp_mss); + } + + if (shutdown(recv_socket,SHUT_WR) == SOCKET_ERROR) { + perror("netperf: cannot shutdown sdp maerts socket"); + exit(1); + } + + stop_timer(); + + /* this call will always give us the local elapsed time for the + test, and will also store-away the necessaries for cpu + utilization */ + + cpu_stop(local_cpu_usage,&elapsed_time); /* was cpu being */ + /* measured and how */ + /* long did we really */ + /* run? */ + + /* we are finished with the socket, so close it to prevent hitting */ + /* the limit on maximum open files. */ + + close(recv_socket); + + if (!no_control) { + /* Get the statistics from the remote end. The remote will have + calculated service demand and all those interesting + things. If it wasn't supposed to care, it will return obvious + values. */ + + recv_response(); + if (!netperf_response.content.serv_errno) { + if (debug) + fprintf(where,"remote results obtained\n"); + } + else { + Set_errno(netperf_response.content.serv_errno); + fprintf(where, + "netperf: remote error %d", + netperf_response.content.serv_errno); + perror(""); + fflush(where); + + exit(1); + } + + /* We now calculate what our thruput was for the test. In the + future, we may want to include a calculation of the thruput + measured by the remote, but it should be the case that for a + SDP maerts test, that the two numbers should be *very* + close... We calculate bytes_sent regardless of the way the + test length was controlled. If it was time, we needed to, + and if it was by bytes, the user may have specified a number + of bytes that wasn't a multiple of the recv_size, so we + really didn't recv what he asked for ;-) */ + + bytes_sent = ntohd(sdp_maerts_result->bytes_sent); + } + else { + bytes_sent = (double)local_bytes_recvd; + } + + + thruput = calc_thruput(bytes_sent); + + if (local_cpu_usage || remote_cpu_usage) { + /* We must now do a little math for service demand and cpu */ + /* utilization for the system(s) */ + /* Of course, some of the information might be bogus because */ + /* there was no idle counter in the kernel(s). We need to make */ + /* a note of this for the user's benefit...*/ + if (local_cpu_usage) { + + local_cpu_utilization = calc_cpu_util(0.0); + local_service_demand = calc_service_demand(bytes_sent, + 0.0, + 0.0, + 0); + } + else { + local_cpu_utilization = (float) -1.0; + local_service_demand = (float) -1.0; + } + + if (remote_cpu_usage) { + + remote_cpu_utilization = sdp_maerts_result->cpu_util; + remote_service_demand = calc_service_demand(bytes_sent, + 0.0, + remote_cpu_utilization, + sdp_maerts_result->num_cpus); + } + else { + remote_cpu_utilization = (float) -1.0; + remote_service_demand = (float) -1.0; + } + } + else { + /* we were not measuring cpu, for the confidence stuff, we */ + /* should make it -1.0 */ + local_cpu_utilization = (float) -1.0; + local_service_demand = (float) -1.0; + remote_cpu_utilization = (float) -1.0; + remote_service_demand = (float) -1.0; + } + + /* at this point, we want to calculate the confidence information. */ + /* if debugging is on, calculate_confidence will print-out the */ + /* parameters we pass it */ + + calculate_confidence(confidence_iteration, + elapsed_time, + thruput, + local_cpu_utilization, + remote_cpu_utilization, + local_service_demand, + remote_service_demand); + + + confidence_iteration++; + } + + /* at this point, we have finished making all the runs that we */ + /* will be making. so, we should extract what the calcuated values */ + /* are for all the confidence stuff. we could make the values */ + /* global, but that seemed a little messy, and it did not seem worth */ + /* all the mucking with header files. so, we create a routine much */ + /* like calcualte_confidence, which just returns the mean values. */ + /* raj 11/94 */ + + retrieve_confident_values(&elapsed_time, + &thruput, + &local_cpu_utilization, + &remote_cpu_utilization, + &local_service_demand, + &remote_service_demand); + + /* We are now ready to print all the information. If the user */ + /* has specified zero-level verbosity, we will just print the */ + /* local service demand, or the remote service demand. If the */ + /* user has requested verbosity level 1, he will get the basic */ + /* "streamperf" numbers. If the user has specified a verbosity */ + /* of greater than 1, we will display a veritable plethora of */ + /* background information from outside of this block as it it */ + /* not cpu_measurement specific... */ + + if (confidence < 0) { + /* we did not hit confidence, but were we asked to look for it? */ + if (iteration_max > 1) { + display_confidence(); + } + } + + if (local_cpu_usage || remote_cpu_usage) { + local_cpu_method = format_cpu_method(cpu_method); + remote_cpu_method = format_cpu_method(sdp_maerts_result->cpu_method); + + switch (verbosity) { + case 0: + if (local_cpu_usage) { + fprintf(where, + cpu_fmt_0, + local_service_demand, + local_cpu_method, + ((print_headers) || + (result_brand == NULL)) ? "" : result_brand); + } + else { + fprintf(where, + cpu_fmt_0, + remote_service_demand, + remote_cpu_method, + ((print_headers) || + (result_brand == NULL)) ? "" : result_brand); + } + break; + case 1: + case 2: + if (print_headers) { + fprintf(where, + cpu_title, + format_units(), + local_cpu_method, + remote_cpu_method); + } + + fprintf(where, + cpu_fmt_1, /* the format string */ + rsr_size, /* remote recvbuf size */ + lss_size, /* local sendbuf size */ + send_size, /* how large were the recvs */ + elapsed_time, /* how long was the test */ + thruput, /* what was the xfer rate */ + local_cpu_utilization, /* local cpu */ + remote_cpu_utilization, /* remote cpu */ + local_service_demand, /* local service demand */ + remote_service_demand, /* remote service demand */ + ((print_headers) || + (result_brand == NULL)) ? "" : result_brand); + break; + } + } + else { + /* The tester did not wish to measure service demand. */ + + switch (verbosity) { + case 0: + fprintf(where, + tput_fmt_0, + thruput, + ((print_headers) || + (result_brand == NULL)) ? "" : result_brand); + break; + case 1: + case 2: + if (print_headers) { + fprintf(where,tput_title,format_units()); + } + fprintf(where, + tput_fmt_1, /* the format string */ + lsr_size, /* local recvbuf size */ + rss_size, /* remot sendbuf size */ + send_size, /* how large were the recvs */ + elapsed_time, /* how long did it take */ + thruput, /* how fast did it go */ + ((print_headers) || + (result_brand == NULL)) ? "" : result_brand); + break; + } + } + + /* it would be a good thing to include information about some of the */ + /* other parameters that may have been set for this test, but at the */ + /* moment, I do not wish to figure-out all the formatting, so I will */ + /* just put this comment here to help remind me that it is something */ + /* that should be done at a later time. */ + + if (verbosity > 1) { + /* The user wanted to know it all, so we will give it to him. */ + /* This information will include as much as we can find about */ + /* SDP statistics, the alignments of the sends and receives */ + /* and all that sort of rot... */ + + /* this stuff needs to be worked-out in the presence of confidence */ + /* intervals and multiple iterations of the test... raj 11/94 */ + + fprintf(where, + ksink_fmt, + "Bytes", + "Bytes", + "Bytes", + local_recv_align, + remote_recv_align, + local_recv_offset, + remote_recv_offset, + bytes_sent, + bytes_sent / (double)nummessages, + nummessages, + bytes_sent / (double)sdp_maerts_result->send_calls, + sdp_maerts_result->send_calls); + fprintf(where, + ksink_fmt2, + sdp_mss); + fflush(where); +#ifdef WANT_HISTOGRAM + fprintf(where,"\n\nHistogram of time spent in recv() call.\n"); + fflush(where); + HIST_report(time_hist); +#endif /* WANT_HISTOGRAM */ + } + +} +/* This is the server-side routine for the sdp stream test. It is */ +/* implemented as one routine. I could break things-out somewhat, but */ +/* didn't feel it was necessary. */ + +void +recv_sdp_stream() +{ + + struct sockaddr_in myaddr_in, peeraddr_in; + SOCKET s_listen,s_data; + netperf_socklen_t addrlen; + int len; + unsigned int receive_calls; + float elapsed_time; + double bytes_received; + + struct ring_elt *recv_ring; + + struct addrinfo *local_res; + char local_name[BUFSIZ]; + char port_buffer[PORTBUFSIZE]; + +#ifdef DO_SELECT + fd_set readfds; + struct timeval timeout; +#endif /* DO_SELECT */ + + struct sdp_stream_request_struct *sdp_stream_request; + struct sdp_stream_response_struct *sdp_stream_response; + struct sdp_stream_results_struct *sdp_stream_results; + +#ifdef DO_SELECT + FD_ZERO(&readfds); + timeout.tv_sec = 1; + timeout.tv_usec = 0; +#endif /* DO_SELECT */ + + sdp_stream_request = + (struct sdp_stream_request_struct *)netperf_request.content.test_specific_data; + sdp_stream_response = + (struct sdp_stream_response_struct *)netperf_response.content.test_specific_data; + sdp_stream_results = + (struct sdp_stream_results_struct *)netperf_response.content.test_specific_data; + + if (debug) { + fprintf(where,"netserver: recv_sdp_stream: entered...\n"); + fflush(where); + } + + /* We want to set-up the listen socket with all the desired */ + /* parameters and then let the initiator know that all is ready. If */ + /* socket size defaults are to be used, then the initiator will have */ + /* sent us 0's. If the socket sizes cannot be changed, then we will */ + /* send-back what they are. If that information cannot be determined, */ + /* then we send-back -1's for the sizes. If things go wrong for any */ + /* reason, we will drop back ten yards and punt. */ + + /* If anything goes wrong, we want the remote to know about it. It */ + /* would be best if the error that the remote reports to the user is */ + /* the actual error we encountered, rather than some bogus unexpected */ + /* response type message. */ + + if (debug) { + fprintf(where,"recv_sdp_stream: setting the response type...\n"); + fflush(where); + } + + netperf_response.content.response_type = SDP_STREAM_RESPONSE; + + if (debug) { + fprintf(where,"recv_sdp_stream: the response type is set...\n"); + fflush(where); + } + + /* We now alter the message_ptr variable to be at the desired */ + /* alignment with the desired offset. */ + + if (debug) { + fprintf(where,"recv_sdp_stream: requested alignment of %d\n", + sdp_stream_request->recv_alignment); + fflush(where); + } + + /* create_data_socket expects to find some things in the global */ + /* variables, so set the globals based on the values in the request. */ + /* once the socket has been created, we will set the response values */ + /* based on the updated value of those globals. raj 7/94 */ + lss_size_req = sdp_stream_request->send_buf_size; + lsr_size_req = sdp_stream_request->recv_buf_size; + loc_nodelay = sdp_stream_request->no_delay; + loc_rcvavoid = sdp_stream_request->so_rcvavoid; + loc_sndavoid = sdp_stream_request->so_sndavoid; + + set_hostname_and_port(local_name, + port_buffer, + nf_to_af(sdp_stream_request->ipfamily), + sdp_stream_request->port); + + local_res = complete_addrinfo(local_name, + local_name, + port_buffer, + nf_to_af(sdp_stream_request->ipfamily), + SOCK_STREAM, + IPPROTO_TCP, + 0); + + /* fake things out by changing local_res->ai_family to AF_INET_SDP */ + local_res->ai_family = AF_INET_SDP; + local_res->ai_protocol = 0; + s_listen = create_data_socket(local_res); + + if (s_listen == INVALID_SOCKET) { + netperf_response.content.serv_errno = errno; + send_response(); + exit(1); + } + +#ifdef WIN32 + /* The test timer can fire during operations on the listening socket, + so to make the start_timer below work we have to move + it to close s_listen while we are blocked on accept. */ + win_kludge_socket2 = s_listen; +#endif + + /* what sort of sizes did we end-up with? */ + if (sdp_stream_request->receive_size == 0) { + if (lsr_size > 0) { + recv_size = lsr_size; + } + else { + recv_size = 4096; + } + } + else { + recv_size = sdp_stream_request->receive_size; + } + + /* we want to set-up our recv_ring in a manner analagous to what we */ + /* do on the sending side. this is more for the sake of symmetry */ + /* than for the needs of say copy avoidance, but it might also be */ + /* more realistic - this way one could conceivably go with a */ + /* double-buffering scheme when taking the data an putting it into */ + /* the filesystem or something like that. raj 7/94 */ + + if (recv_width == 0) { + recv_width = (lsr_size/recv_size) + 1; + if (recv_width == 1) recv_width++; + } + + recv_ring = allocate_buffer_ring(recv_width, + recv_size, + sdp_stream_request->recv_alignment, + sdp_stream_request->recv_offset); + + if (debug) { + fprintf(where,"recv_sdp_stream: receive alignment and offset set...\n"); + fflush(where); + } + + /* Now, let's set-up the socket to listen for connections */ + if (listen(s_listen, 5) == SOCKET_ERROR) { + netperf_response.content.serv_errno = errno; + close(s_listen); + send_response(); + + exit(1); + } + + + /* now get the port number assigned by the system */ + addrlen = sizeof(myaddr_in); + if (getsockname(s_listen, + (struct sockaddr *)&myaddr_in, + &addrlen) == SOCKET_ERROR){ + netperf_response.content.serv_errno = errno; + close(s_listen); + send_response(); + + exit(1); + } + + /* Now myaddr_in contains the port and the internet address this is */ + /* returned to the sender also implicitly telling the sender that the */ + /* socket buffer sizing has been done. */ + + sdp_stream_response->data_port_number = (int) ntohs(myaddr_in.sin_port); + netperf_response.content.serv_errno = 0; + + /* But wait, there's more. If the initiator wanted cpu measurements, */ + /* then we must call the calibrate routine, which will return the max */ + /* rate back to the initiator. If the CPU was not to be measured, or */ + /* something went wrong with the calibration, we will return a -1 to */ + /* the initiator. */ + + sdp_stream_response->cpu_rate = (float)0.0; /* assume no cpu */ + if (sdp_stream_request->measure_cpu) { + sdp_stream_response->measure_cpu = 1; + sdp_stream_response->cpu_rate = + calibrate_local_cpu(sdp_stream_request->cpu_rate); + } + else { + sdp_stream_response->measure_cpu = 0; + } + + /* before we send the response back to the initiator, pull some of */ + /* the socket parms from the globals */ + sdp_stream_response->send_buf_size = lss_size; + sdp_stream_response->recv_buf_size = lsr_size; + sdp_stream_response->no_delay = loc_nodelay; + sdp_stream_response->so_rcvavoid = loc_rcvavoid; + sdp_stream_response->so_sndavoid = loc_sndavoid; + sdp_stream_response->receive_size = recv_size; + + send_response(); + + addrlen = sizeof(peeraddr_in); + + if ((s_data=accept(s_listen, + (struct sockaddr *)&peeraddr_in, + &addrlen)) == INVALID_SOCKET) { + /* Let's just punt. The remote will be given some information */ + close(s_listen); + exit(1); + } + +#ifdef KLUDGE_SOCKET_OPTIONS + /* this is for those systems which *INCORRECTLY* fail to pass */ + /* attributes across an accept() call. Including this goes against */ + /* my better judgement :( raj 11/95 */ + + kludge_socket_options(s_data); + +#endif /* KLUDGE_SOCKET_OPTIONS */ + + /* Now it's time to start receiving data on the connection. We will */ + /* first grab the apropriate counters and then start grabbing. */ + + cpu_start(sdp_stream_request->measure_cpu); + + /* The loop will exit when the sender does a shutdown, which will */ + /* return a length of zero */ + + /* there used to be an #ifdef DIRTY call to access_buffer() here, + but we have switched from accessing the buffer before the recv() + call to accessing the buffer after the recv() call. The + accessing before was, IIRC, related to having dirty data when + doing page-flipping copy avoidance. */ + + bytes_received = 0; + receive_calls = 0; + + while ((len = recv(s_data, recv_ring->buffer_ptr, recv_size, 0)) != 0) { + if (len == SOCKET_ERROR ) + { + netperf_response.content.serv_errno = errno; + send_response(); + exit(1); + } + bytes_received += len; + receive_calls++; + +#ifdef DIRTY + /* we access the buffer after the recv() call now, rather than before */ + access_buffer(recv_ring->buffer_ptr, + recv_size, + sdp_stream_request->dirty_count, + sdp_stream_request->clean_count); +#endif /* DIRTY */ + + + /* move to the next buffer in the recv_ring */ + recv_ring = recv_ring->next; + +#ifdef PAUSE + sleep(1); +#endif /* PAUSE */ + +#ifdef DO_SELECT + FD_SET(s_data,&readfds); + select(s_data+1,&readfds,NULL,NULL,&timeout); +#endif /* DO_SELECT */ + + } + + /* perform a shutdown to signal the sender that */ + /* we have received all the data sent. raj 4/93 */ + + if (shutdown(s_data,SHUT_WR) == SOCKET_ERROR) { + netperf_response.content.serv_errno = errno; + send_response(); + exit(1); + } + + cpu_stop(sdp_stream_request->measure_cpu,&elapsed_time); + + /* send the results to the sender */ + + if (debug) { + fprintf(where, + "recv_sdp_stream: got %g bytes\n", + bytes_received); + fprintf(where, + "recv_sdp_stream: got %d recvs\n", + receive_calls); + fflush(where); + } + + sdp_stream_results->bytes_received = htond(bytes_received); + sdp_stream_results->elapsed_time = elapsed_time; + sdp_stream_results->recv_calls = receive_calls; + + sdp_stream_results->cpu_method = cpu_method; + sdp_stream_results->num_cpus = lib_num_loc_cpus; + + if (sdp_stream_request->measure_cpu) { + sdp_stream_results->cpu_util = calc_cpu_util(0.0); + }; + + if (debug) { + fprintf(where, + "recv_sdp_stream: test complete, sending results.\n"); + fprintf(where, + " bytes_received %g receive_calls %d\n", + bytes_received, + receive_calls); + fprintf(where, + " len %d\n", + len); + fflush(where); + } + + send_response(); + + /* we are now done with the sockets */ + close(s_data); + close(s_listen); + + } + +/* This is the server-side routine for the sdp maerts test. It is + implemented as one routine. I could break things-out somewhat, but + didn't feel it was necessary. */ + +void +recv_sdp_maerts() +{ + + struct sockaddr_in myaddr_in, peeraddr_in; + struct addrinfo *local_res; + char local_name[BUFSIZ]; + char port_buffer[PORTBUFSIZE]; + + SOCKET s_listen,s_data; + netperf_socklen_t addrlen; + int len; + unsigned int send_calls; + float elapsed_time; + double bytes_sent = 0.0 ; + + struct ring_elt *send_ring; + + struct sdp_maerts_request_struct *sdp_maerts_request; + struct sdp_maerts_response_struct *sdp_maerts_response; + struct sdp_maerts_results_struct *sdp_maerts_results; + + sdp_maerts_request = + (struct sdp_maerts_request_struct *)netperf_request.content.test_specific_data; + sdp_maerts_response = + (struct sdp_maerts_response_struct *)netperf_response.content.test_specific_data; + sdp_maerts_results = + (struct sdp_maerts_results_struct *)netperf_response.content.test_specific_data; + + if (debug) { + fprintf(where,"netserver: recv_sdp_maerts: entered...\n"); + fflush(where); + } + + /* We want to set-up the listen socket with all the desired + parameters and then let the initiator know that all is ready. If + socket size defaults are to be used, then the initiator will have + sent us 0's. If the socket sizes cannot be changed, then we will + send-back what they are. If that information cannot be + determined, then we send-back -1's for the sizes. If things go + wrong for any reason, we will drop back ten yards and punt. */ + + /* If anything goes wrong, we want the remote to know about it. It + would be best if the error that the remote reports to the user is + the actual error we encountered, rather than some bogus + unexpected response type message. */ + + if (debug) { + fprintf(where,"recv_sdp_maerts: setting the response type...\n"); + fflush(where); + } + + netperf_response.content.response_type = SDP_MAERTS_RESPONSE; + + if (debug) { + fprintf(where,"recv_sdp_maerts: the response type is set...\n"); + fflush(where); + } + + /* We now alter the message_ptr variable to be at the desired */ + /* alignment with the desired offset. */ + + if (debug) { + fprintf(where,"recv_sdp_maerts: requested alignment of %d\n", + sdp_maerts_request->send_alignment); + fflush(where); + } + + /* Grab a socket to listen on, and then listen on it. */ + + if (debug) { + fprintf(where,"recv_sdp_maerts: grabbing a socket...\n"); + fflush(where); + } + + /* create_data_socket expects to find some things in the global */ + /* variables, so set the globals based on the values in the request. */ + /* once the socket has been created, we will set the response values */ + /* based on the updated value of those globals. raj 7/94 */ + lss_size_req = sdp_maerts_request->send_buf_size; + lsr_size_req = sdp_maerts_request->recv_buf_size; + loc_nodelay = sdp_maerts_request->no_delay; + loc_rcvavoid = sdp_maerts_request->so_rcvavoid; + loc_sndavoid = sdp_maerts_request->so_sndavoid; + + set_hostname_and_port(local_name, + port_buffer, + nf_to_af(sdp_maerts_request->ipfamily), + sdp_maerts_request->port); + + local_res = complete_addrinfo(local_name, + local_name, + port_buffer, + nf_to_af(sdp_maerts_request->ipfamily), + SOCK_STREAM, + IPPROTO_TCP, + 0); + + /* fake things out by changing local_res->ai_family to AF_INET_SDP */ + local_res->ai_family = AF_INET_SDP; + local_res->ai_protocol = 0; + s_listen = create_data_socket(local_res); + + if (s_listen == INVALID_SOCKET) { + netperf_response.content.serv_errno = errno; + send_response(); + exit(1); + } + +#ifdef WIN32 + /* The test timer can fire during operations on the listening socket, + so to make the start_timer below work we have to move + it to close s_listen while we are blocked on accept. */ + win_kludge_socket2 = s_listen; +#endif + + + /* what sort of sizes did we end-up with? */ + if (sdp_maerts_request->send_size == 0) { + if (lss_size > 0) { + send_size = lss_size; + } + else { + send_size = 4096; + } + } + else { + send_size = sdp_maerts_request->send_size; + } + + /* we want to set-up our recv_ring in a manner analagous to what we */ + /* do on the recving side. this is more for the sake of symmetry */ + /* than for the needs of say copy avoidance, but it might also be */ + /* more realistic - this way one could conceivably go with a */ + /* double-buffering scheme when taking the data an putting it into */ + /* the filesystem or something like that. raj 7/94 */ + + if (send_width == 0) { + send_width = (lsr_size/send_size) + 1; + if (send_width == 1) send_width++; + } + + send_ring = allocate_buffer_ring(send_width, + send_size, + sdp_maerts_request->send_alignment, + sdp_maerts_request->send_offset); + + if (debug) { + fprintf(where,"recv_sdp_maerts: receive alignment and offset set...\n"); + fflush(where); + } + + /* Now, let's set-up the socket to listen for connections */ + if (listen(s_listen, 5) == SOCKET_ERROR) { + netperf_response.content.serv_errno = errno; + close(s_listen); + send_response(); + + exit(1); + } + + + /* now get the port number assigned by the system */ + addrlen = sizeof(myaddr_in); + if (getsockname(s_listen, + (struct sockaddr *)&myaddr_in, + &addrlen) == SOCKET_ERROR){ + netperf_response.content.serv_errno = errno; + close(s_listen); + send_response(); + + exit(1); + } + + /* Now myaddr_in contains the port and the internet address this is */ + /* returned to the sender also implicitly telling the sender that the */ + /* socket buffer sizing has been done. */ + + sdp_maerts_response->data_port_number = (int) ntohs(myaddr_in.sin_port); + netperf_response.content.serv_errno = 0; + + /* But wait, there's more. If the initiator wanted cpu measurements, */ + /* then we must call the calibrate routine, which will return the max */ + /* rate back to the initiator. If the CPU was not to be measured, or */ + /* something went wrong with the calibration, we will return a -1 to */ + /* the initiator. */ + + sdp_maerts_response->cpu_rate = (float)0.0; /* assume no cpu */ + if (sdp_maerts_request->measure_cpu) { + sdp_maerts_response->measure_cpu = 1; + sdp_maerts_response->cpu_rate = + calibrate_local_cpu(sdp_maerts_request->cpu_rate); + } + else { + sdp_maerts_response->measure_cpu = 0; + } + + /* before we send the response back to the initiator, pull some of */ + /* the socket parms from the globals */ + sdp_maerts_response->send_buf_size = lss_size; + sdp_maerts_response->recv_buf_size = lsr_size; + sdp_maerts_response->no_delay = loc_nodelay; + sdp_maerts_response->so_rcvavoid = loc_rcvavoid; + sdp_maerts_response->so_sndavoid = loc_sndavoid; + sdp_maerts_response->send_size = send_size; + + send_response(); + + addrlen = sizeof(peeraddr_in); + + /* we will start the timer before the accept() to be somewhat + analagous to the starting of the timer before the connect() call + in the SDP_STREAM test. raj 2002-06-21 */ + + start_timer(sdp_maerts_request->test_length); + + /* Now it's time to start receiving data on the connection. We will + first grab the apropriate counters and then start grabbing. */ + + cpu_start(sdp_maerts_request->measure_cpu); + + + if ((s_data=accept(s_listen, + (struct sockaddr *)&peeraddr_in, + &addrlen)) == INVALID_SOCKET) { + /* Let's just punt. The remote will be given some information */ + close(s_listen); + exit(1); + } + +#ifdef KLUDGE_SOCKET_OPTIONS + + /* this is for those systems which *INCORRECTLY* fail to pass + attributes across an accept() call. Including this goes against + my better judgement :( raj 11/95 */ + + kludge_socket_options(s_data); + +#endif /* KLUDGE_SOCKET_OPTIONS */ + + /* The loop will exit when the sender does a shutdown, which will */ + /* return a length of zero */ + + bytes_sent = 0.0; + send_calls = 0; + + len = 0; /* nt-lint; len is not initialized (printf far below) if + times_up initially true.*/ + times_up = 0; /* must remember to initialize this little beauty */ + while (!times_up) { + +#ifdef DIRTY + /* we want to dirty some number of consecutive integers in the buffer */ + /* we are about to send. we may also want to bring some number of */ + /* them cleanly into the cache. The clean ones will follow any dirty */ + /* ones into the cache. */ + + access_buffer(send_ring->buffer_ptr, + send_size, + sdp_maerts_request->dirty_count, + sdp_maerts_request->clean_count); + +#endif /* DIRTY */ + + if((len=send(s_data, + send_ring->buffer_ptr, + send_size, + 0)) != send_size) { + if ((len >=0) || SOCKET_EINTR(len)) { + /* the test was interrupted, must be the end of test */ + break; + } + netperf_response.content.serv_errno = errno; + send_response(); + exit(1); + } + + bytes_sent += len; + send_calls++; + + /* more to the next buffer in the send_ring */ + send_ring = send_ring->next; + + } + + /* perform a shutdown to signal the sender that */ + /* we have received all the data sent. raj 4/93 */ + + if (shutdown(s_data,SHUT_WR) == SOCKET_ERROR) { + netperf_response.content.serv_errno = errno; + send_response(); + exit(1); + } + + /* hang a recv() off the socket to block until the remote has + brought all the data up into the application. it will do a + shutdown to cause a FIN to be sent our way. We will assume that + any exit from the recv() call is good... raj 4/93 */ + + recv(s_data, send_ring->buffer_ptr, send_size, 0); + + + cpu_stop(sdp_maerts_request->measure_cpu,&elapsed_time); + + /* send the results to the sender */ + + if (debug) { + fprintf(where, + "recv_sdp_maerts: got %g bytes\n", + bytes_sent); + fprintf(where, + "recv_sdp_maerts: got %d sends\n", + send_calls); + fflush(where); + } + + sdp_maerts_results->bytes_sent = htond(bytes_sent); + sdp_maerts_results->elapsed_time = elapsed_time; + sdp_maerts_results->send_calls = send_calls; + + if (sdp_maerts_request->measure_cpu) { + sdp_maerts_results->cpu_util = calc_cpu_util(0.0); + }; + + if (debug) { + fprintf(where, + "recv_sdp_maerts: test complete, sending results.\n"); + fprintf(where, + " bytes_sent %g send_calls %d\n", + bytes_sent, + send_calls); + fprintf(where, + " len %d\n", + len); + fflush(where); + } + + sdp_maerts_results->cpu_method = cpu_method; + sdp_maerts_results->num_cpus = lib_num_loc_cpus; + send_response(); + + /* we are now done with the sockets */ + close(s_data); + close(s_listen); + + } + + + /* this routine implements the sending (netperf) side of the SDP_RR */ + /* test. */ + +void +send_sdp_rr(char remote_host[]) +{ + + char *tput_title = "\ +Local /Remote\n\ +Socket Size Request Resp. Elapsed Trans.\n\ +Send Recv Size Size Time Rate \n\ +bytes Bytes bytes bytes secs. per sec \n\n"; + + char *tput_fmt_0 = + "%7.2f %s\n"; + + char *tput_fmt_1_line_1 = "\ +%-6d %-6d %-6d %-6d %-6.2f %7.2f %s\n"; + char *tput_fmt_1_line_2 = "\ +%-6d %-6d\n"; + + char *cpu_title = "\ +Local /Remote\n\ +Socket Size Request Resp. Elapsed Trans. CPU CPU S.dem S.dem\n\ +Send Recv Size Size Time Rate local remote local remote\n\ +bytes bytes bytes bytes secs. per sec %% %c %% %c us/Tr us/Tr\n\n"; + + char *cpu_fmt_0 = + "%6.3f %c %s\n"; + + char *cpu_fmt_1_line_1 = "\ +%-6d %-6d %-6d %-6d %-6.2f %-6.2f %-6.2f %-6.2f %-6.3f %-6.3f %s\n"; + + char *cpu_fmt_1_line_2 = "\ +%-6d %-6d\n"; + + char *ksink_fmt = "\ +Alignment Offset\n\ +Local Remote Local Remote\n\ +Send Recv Send Recv\n\ +%5d %5d %5d %5d\n"; + + + int timed_out = 0; + float elapsed_time; + + int len; + char *temp_message_ptr; + int nummessages; + SOCKET send_socket; + int trans_remaining; + double bytes_xferd; + + struct ring_elt *send_ring; + struct ring_elt *recv_ring; + + int rsp_bytes_left; + int rsp_bytes_recvd; + + float local_cpu_utilization; + float local_service_demand; + float remote_cpu_utilization; + float remote_service_demand; + double thruput; + + struct addrinfo *local_res; + struct addrinfo *remote_res; + + struct sdp_rr_request_struct *sdp_rr_request; + struct sdp_rr_response_struct *sdp_rr_response; + struct sdp_rr_results_struct *sdp_rr_result; + +#ifdef WANT_FIRST_BURST +#define REQUEST_CWND_INITIAL 2 + /* "in the beginning..." the WANT_FIRST_BURST stuff was like both + Unix and the state of New Jersey - both were simple an unspoiled. + then it was realized that some stacks are quite picky about + initial congestion windows and a non-trivial initial burst of + requests would not be individual segments even with TCP_NODELAY + set. so, we have to start tracking a poor-man's congestion window + up here in window space because we want to try to make something + happen that frankly, we cannot guarantee with the specification + of SDP. ain't that grand?-) raj 2006-01-30 */ + int requests_outstanding = 0; + int request_cwnd = REQUEST_CWND_INITIAL; /* we ass-u-me that having + three requests + outstanding at the + beginning of the test + is ok with SDP stacks + of interest. the first + two will come from our + first_burst loop, and + the third from our + regularly scheduled + send */ +#endif + + sdp_rr_request = + (struct sdp_rr_request_struct *)netperf_request.content.test_specific_data; + sdp_rr_response= + (struct sdp_rr_response_struct *)netperf_response.content.test_specific_data; + sdp_rr_result = + (struct sdp_rr_results_struct *)netperf_response.content.test_specific_data; + +#ifdef WANT_HISTOGRAM + if (verbosity > 1) { + time_hist = HIST_new(); + } +#endif /* WANT_HISTOGRAM */ + + /* since we are now disconnected from the code that established the */ + /* control socket, and since we want to be able to use different */ + /* protocols and such, we are passed the name of the remote host and */ + /* must turn that into the test specific addressing information. */ + + complete_addrinfos(&remote_res, + &local_res, + remote_host, + SOCK_STREAM, + IPPROTO_TCP, + 0); + + if ( print_headers ) { + print_top_test_header("SDP REQUEST/RESPONSE TEST",local_res,remote_res); + } + + /* initialize a few counters */ + + send_ring = NULL; + recv_ring = NULL; + confidence_iteration = 1; + init_stat(); + + /* we have a great-big while loop which controls the number of times */ + /* we run a particular test. this is for the calculation of a */ + /* confidence interval (I really should have stayed awake during */ + /* probstats :). If the user did not request confidence measurement */ + /* (no confidence is the default) then we will only go though the */ + /* loop once. the confidence stuff originates from the folks at IBM */ + + while (((confidence < 0) && (confidence_iteration < iteration_max)) || + (confidence_iteration <= iteration_min)) { + + /* initialize a few counters. we have to remember that we might be */ + /* going through the loop more than once. */ + + nummessages = 0; + bytes_xferd = 0.0; + times_up = 0; + timed_out = 0; + trans_remaining = 0; + +#ifdef WANT_FIRST_BURST + /* we have to remember to reset the number of transactions + outstanding and the "congestion window for each new + iteration. raj 2006-01-31 */ + requests_outstanding = 0; + request_cwnd = REQUEST_CWND_INITIAL; +#endif + + + /* set-up the data buffers with the requested alignment and offset. */ + /* since this is a request/response test, default the send_width and */ + /* recv_width to 1 and not two raj 7/94 */ + + if (send_width == 0) send_width = 1; + if (recv_width == 0) recv_width = 1; + + if (send_ring == NULL) { + send_ring = allocate_buffer_ring(send_width, + req_size, + local_send_align, + local_send_offset); + } + + if (recv_ring == NULL) { + recv_ring = allocate_buffer_ring(recv_width, + rsp_size, + local_recv_align, + local_recv_offset); + } + + /*set up the data socket */ + /* fake things out by changing local_res->ai_family to AF_INET_SDP */ + local_res->ai_family = AF_INET_SDP; + local_res->ai_protocol = 0; + send_socket = create_data_socket(local_res); + + if (send_socket == INVALID_SOCKET){ + perror("netperf: send_sdp_rr: sdp stream data socket"); + exit(1); + } + + if (debug) { + fprintf(where,"send_sdp_rr: send_socket obtained...\n"); + } + + /* If the user has requested cpu utilization measurements, we must */ + /* calibrate the cpu(s). We will perform this task within the tests */ + /* themselves. If the user has specified the cpu rate, then */ + /* calibrate_local_cpu will return rather quickly as it will have */ + /* nothing to do. If local_cpu_rate is zero, then we will go through */ + /* all the "normal" calibration stuff and return the rate back.*/ + + if (local_cpu_usage) { + local_cpu_rate = calibrate_local_cpu(local_cpu_rate); + } + + if (!no_control) { + /* Tell the remote end to do a listen. The server alters the + socket paramters on the other side at this point, hence the + reason for all the values being passed in the setup + message. If the user did not specify any of the parameters, + they will be passed as 0, which will indicate to the remote + that no changes beyond the system's default should be + used. Alignment is the exception, it will default to 8, which + will be no alignment alterations. */ + + netperf_request.content.request_type = DO_SDP_RR; + sdp_rr_request->recv_buf_size = rsr_size_req; + sdp_rr_request->send_buf_size = rss_size_req; + sdp_rr_request->recv_alignment = remote_recv_align; + sdp_rr_request->recv_offset = remote_recv_offset; + sdp_rr_request->send_alignment = remote_send_align; + sdp_rr_request->send_offset = remote_send_offset; + sdp_rr_request->request_size = req_size; + sdp_rr_request->response_size = rsp_size; + sdp_rr_request->no_delay = rem_nodelay; + sdp_rr_request->measure_cpu = remote_cpu_usage; + sdp_rr_request->cpu_rate = remote_cpu_rate; + sdp_rr_request->so_rcvavoid = rem_rcvavoid; + sdp_rr_request->so_sndavoid = rem_sndavoid; + if (test_time) { + sdp_rr_request->test_length = test_time; + } + else { + sdp_rr_request->test_length = test_trans * -1; + } + sdp_rr_request->port = atoi(remote_data_port); + sdp_rr_request->ipfamily = af_to_nf(remote_res->ai_family); + + if (debug > 1) { + fprintf(where,"netperf: send_sdp_rr: requesting SDP rr test\n"); + } + + send_request(); + + /* The response from the remote will contain all of the relevant + socket parameters for this test type. We will put them back + into the variables here so they can be displayed if desired. + The remote will have calibrated CPU if necessary, and will + have done all the needed set-up we will have calibrated the + cpu locally before sending the request, and will grab the + counter value right after the connect returns. The remote + will grab the counter right after the accept call. This saves + the hassle of extra messages being sent for the SDP + tests. */ + + recv_response(); + + if (!netperf_response.content.serv_errno) { + if (debug) + fprintf(where,"remote listen done.\n"); + rsr_size = sdp_rr_response->recv_buf_size; + rss_size = sdp_rr_response->send_buf_size; + rem_nodelay = sdp_rr_response->no_delay; + remote_cpu_usage = sdp_rr_response->measure_cpu; + remote_cpu_rate = sdp_rr_response->cpu_rate; + /* make sure that port numbers are in network order */ + set_port_number(remote_res,(short)sdp_rr_response->data_port_number); + } + else { + Set_errno(netperf_response.content.serv_errno); + fprintf(where, + "netperf: remote error %d", + netperf_response.content.serv_errno); + perror(""); + fflush(where); + + exit(1); + } + } + +#ifdef WANT_DEMO + DEMO_RR_SETUP(1000) +#endif + + /*Connect up to the remote port on the data socket */ + if (connect(send_socket, + remote_res->ai_addr, + remote_res->ai_addrlen) == INVALID_SOCKET){ + perror("netperf: data socket connect failed"); + + exit(1); + } + + /* Data Socket set-up is finished. If there were problems, either the */ + /* connect would have failed, or the previous response would have */ + /* indicated a problem. I failed to see the value of the extra */ + /* message after the accept on the remote. If it failed, we'll see it */ + /* here. If it didn't, we might as well start pumping data. */ + + /* Set-up the test end conditions. For a request/response test, they */ + /* can be either time or transaction based. */ + + if (test_time) { + /* The user wanted to end the test after a period of time. */ + times_up = 0; + trans_remaining = 0; + start_timer(test_time); + } + else { + /* The tester wanted to send a number of bytes. */ + trans_remaining = test_bytes; + times_up = 1; + } + + /* The cpu_start routine will grab the current time and possibly */ + /* value of the idle counter for later use in measuring cpu */ + /* utilization and/or service demand and thruput. */ + + cpu_start(local_cpu_usage); + +#ifdef WANT_INTERVALS + INTERVALS_INIT(); +#endif /* WANT_INTERVALS */ + + /* We use an "OR" to control test execution. When the test is */ + /* controlled by time, the byte count check will always return false. */ + /* When the test is controlled by byte count, the time test will */ + /* always return false. When the test is finished, the whole */ + /* expression will go false and we will stop sending data. I think I */ + /* just arbitrarily decrement trans_remaining for the timed test, but */ + /* will not do that just yet... One other question is whether or not */ + /* the send buffer and the receive buffer should be the same buffer. */ + +#ifdef WANT_DEMO + if (demo_mode) { + HIST_timestamp(demo_one_ptr); + } +#endif + + while ((!times_up) || (trans_remaining > 0)) { + /* send the request. we assume that if we use a blocking socket, */ + /* the request will be sent at one shot. */ + +#ifdef WANT_FIRST_BURST + /* we can inject no more than request_cwnd, which will grow with + time, and no more than first_burst_size. we don't use <= to + account for the "regularly scheduled" send call. of course + that makes it more a "max_outstanding_ than a + "first_burst_size" but for now we won't fix the names. also, + I suspect the extra check against < first_burst_size is + redundant since later I expect to make sure that request_cwnd + can never get larger than first_burst_size, but just at the + moment I'm feeling like a belt and suspenders kind of + programmer. raj 2006-01-30 */ + while ((first_burst_size > 0) && + (requests_outstanding < request_cwnd) && + (requests_outstanding < first_burst_size)) { + if (debug) { + fprintf(where, + "injecting, req_outstndng %d req_cwnd %d burst %d\n", + requests_outstanding, + request_cwnd, + first_burst_size); + } + if ((len = send(send_socket, + send_ring->buffer_ptr, + req_size, + 0)) != req_size) { + /* we should never hit the end of the test in the first burst */ + perror("send_sdp_rr: initial burst data send error"); + exit(-1); + } + requests_outstanding += 1; + } + +#endif /* WANT_FIRST_BURST */ + +#ifdef WANT_HISTOGRAM + if (verbosity > 1) { + /* timestamp just before our call to send, and then again just + after the receive raj 8/94 */ + /* but only if we are actually going to display one. raj + 2007-02-07 */ + + HIST_timestamp(&time_one); + } +#endif /* WANT_HISTOGRAM */ + + if ((len = send(send_socket, + send_ring->buffer_ptr, + req_size, + 0)) != req_size) { + if (SOCKET_EINTR(len) || (errno == 0)) { + /* we hit the end of a */ + /* timed test. */ + timed_out = 1; + break; + } + perror("send_sdp_rr: data send error"); + exit(1); + } + send_ring = send_ring->next; + +#ifdef WANT_FIRST_BURST + requests_outstanding += 1; +#endif + + /* receive the response */ + rsp_bytes_left = rsp_size; + temp_message_ptr = recv_ring->buffer_ptr; + while(rsp_bytes_left > 0) { + if((rsp_bytes_recvd=recv(send_socket, + temp_message_ptr, + rsp_bytes_left, + 0)) == SOCKET_ERROR) { + if ( SOCKET_EINTR(rsp_bytes_recvd) ) { + /* We hit the end of a timed test. */ + timed_out = 1; + break; + } + perror("send_sdp_rr: data recv error"); + exit(1); + } + rsp_bytes_left -= rsp_bytes_recvd; + temp_message_ptr += rsp_bytes_recvd; + } + recv_ring = recv_ring->next; + +#ifdef WANT_FIRST_BURST + /* so, since we've gotten a response back, update the + bookkeeping accordingly. there is one less request + outstanding and we can put one more out there than before. */ + requests_outstanding -= 1; + if (request_cwnd < first_burst_size) { + request_cwnd += 1; + if (debug) { + fprintf(where, + "incr req_cwnd to %d first_burst %d reqs_outstndng %d\n", + request_cwnd, + first_burst_size, + requests_outstanding); + } + } +#endif + if (timed_out) { + /* we may have been in a nested while loop - we need */ + /* another call to break. */ + break; + } + +#ifdef WANT_HISTOGRAM + if (verbosity > 1) { + HIST_timestamp(&time_two); + HIST_add(time_hist,delta_micro(&time_one,&time_two)); + } +#endif /* WANT_HISTOGRAM */ + +#ifdef WANT_DEMO + DEMO_RR_INTERVAL(1); +#endif + +#ifdef WANT_INTERVALS + INTERVALS_WAIT(); +#endif /* WANT_INTERVALS */ + + nummessages++; + if (trans_remaining) { + trans_remaining--; + } + + if (debug > 3) { + if ((nummessages % 100) == 0) { + fprintf(where, + "Transaction %d completed\n", + nummessages); + fflush(where); + } + } + } + + /* At this point we used to call shutdown on the data socket to be + sure all the data was delivered, but this was not germane in a + request/response test, and it was causing the tests to "hang" + when they were being controlled by time. So, I have replaced + this shutdown call with a call to close that can be found later + in the procedure. */ + + /* this call will always give us the elapsed time for the test, + and will also store-away the necessaries for cpu utilization */ + + cpu_stop(local_cpu_usage,&elapsed_time); /* was cpu being */ + /* measured? how long */ + /* did we really run? */ + + if (!no_control) { + /* Get the statistics from the remote end. The remote will have + calculated CPU utilization. If it wasn't supposed to care, it + will return obvious values. */ + + recv_response(); + if (!netperf_response.content.serv_errno) { + if (debug) + fprintf(where,"remote results obtained\n"); + } + else { + Set_errno(netperf_response.content.serv_errno); + fprintf(where,"netperf: remote error %d", + netperf_response.content.serv_errno); + perror(""); + fflush(where); + exit(1); + } + } + + /* We now calculate what our throughput was for the test. */ + + bytes_xferd = (req_size * nummessages) + (rsp_size * nummessages); + thruput = nummessages/elapsed_time; + + if (local_cpu_usage || remote_cpu_usage) { + /* We must now do a little math for service demand and cpu + utilization for the system(s) Of course, some of the + information might be bogus because there was no idle counter in + the kernel(s). We need to make a note of this for the user's + benefit... */ + if (local_cpu_usage) { + local_cpu_utilization = calc_cpu_util(0.0); + /* since calc_service demand is doing ms/Kunit we will + multiply the number of transaction by 1024 to get "good" + numbers */ + local_service_demand = calc_service_demand((double) nummessages*1024, + 0.0, + 0.0, + 0); + } + else { + local_cpu_utilization = (float) -1.0; + local_service_demand = (float) -1.0; + } + + if (remote_cpu_usage) { + remote_cpu_utilization = sdp_rr_result->cpu_util; + /* since calc_service demand is doing ms/Kunit we will + multiply the number of transaction by 1024 to get "good" + numbers */ + remote_service_demand = calc_service_demand((double) nummessages*1024, + 0.0, + remote_cpu_utilization, + sdp_rr_result->num_cpus); + } + else { + remote_cpu_utilization = (float) -1.0; + remote_service_demand = (float) -1.0; + } + + } + else { + /* we were not measuring cpu, for the confidence stuff, we */ + /* should make it -1.0 */ + local_cpu_utilization = (float) -1.0; + local_service_demand = (float) -1.0; + remote_cpu_utilization = (float) -1.0; + remote_service_demand = (float) -1.0; + } + + /* at this point, we want to calculate the confidence information. + if debugging is on, calculate_confidence will print-out the + parameters we pass it */ + + calculate_confidence(confidence_iteration, + elapsed_time, + thruput, + local_cpu_utilization, + remote_cpu_utilization, + local_service_demand, + remote_service_demand); + + + confidence_iteration++; + + /* we are now done with the socket, so close it */ + close(send_socket); + + } + + retrieve_confident_values(&elapsed_time, + &thruput, + &local_cpu_utilization, + &remote_cpu_utilization, + &local_service_demand, + &remote_service_demand); + + /* We are now ready to print all the information. If the user has + specified zero-level verbosity, we will just print the local + service demand, or the remote service demand. If the user has + requested verbosity level 1, he will get the basic "streamperf" + numbers. If the user has specified a verbosity of greater than 1, + we will display a veritable plethora of background information + from outside of this block as it it not cpu_measurement + specific... */ + + if (confidence < 0) { + /* we did not hit confidence, but were we asked to look for it? */ + if (iteration_max > 1) { + display_confidence(); + } + } + + if (local_cpu_usage || remote_cpu_usage) { + local_cpu_method = format_cpu_method(cpu_method); + remote_cpu_method = format_cpu_method(sdp_rr_result->cpu_method); + + switch (verbosity) { + case 0: + if (local_cpu_usage) { + fprintf(where, + cpu_fmt_0, + local_service_demand, + local_cpu_method, + ((print_headers) || + (result_brand == NULL)) ? "" : result_brand); + } + else { + fprintf(where, + cpu_fmt_0, + remote_service_demand, + remote_cpu_method, + ((print_headers) || + (result_brand == NULL)) ? "" : result_brand); + } + break; + case 1: + case 2: + if (print_headers) { + fprintf(where, + cpu_title, + local_cpu_method, + remote_cpu_method); + } + + fprintf(where, + cpu_fmt_1_line_1, /* the format string */ + lss_size, /* local sendbuf size */ + lsr_size, + req_size, /* how large were the requests */ + rsp_size, /* guess */ + elapsed_time, /* how long was the test */ + thruput, + local_cpu_utilization, /* local cpu */ + remote_cpu_utilization, /* remote cpu */ + local_service_demand, /* local service demand */ + remote_service_demand, /* remote service demand */ + ((print_headers) || + (result_brand == NULL)) ? "" : result_brand); + fprintf(where, + cpu_fmt_1_line_2, + rss_size, + rsr_size); + break; + } + } + else { + /* The tester did not wish to measure service demand. */ + + switch (verbosity) { + case 0: + fprintf(where, + tput_fmt_0, + thruput, + ((print_headers) || + (result_brand == NULL)) ? "" : result_brand); + break; + case 1: + case 2: + if (print_headers) { + fprintf(where,tput_title,format_units()); + } + + fprintf(where, + tput_fmt_1_line_1, /* the format string */ + lss_size, + lsr_size, + req_size, /* how large were the requests */ + rsp_size, /* how large were the responses */ + elapsed_time, /* how long did it take */ + thruput, + ((print_headers) || + (result_brand == NULL)) ? "" : result_brand); + fprintf(where, + tput_fmt_1_line_2, + rss_size, /* remote recvbuf size */ + rsr_size); + + break; + } + } + + /* it would be a good thing to include information about some of the */ + /* other parameters that may have been set for this test, but at the */ + /* moment, I do not wish to figure-out all the formatting, so I will */ + /* just put this comment here to help remind me that it is something */ + /* that should be done at a later time. */ + + /* how to handle the verbose information in the presence of */ + /* confidence intervals is yet to be determined... raj 11/94 */ + if (verbosity > 1) { + /* The user wanted to know it all, so we will give it to him. */ + /* This information will include as much as we can find about */ + /* SDP statistics, the alignments of the sends and receives */ + /* and all that sort of rot... */ + + fprintf(where, + ksink_fmt, + local_send_align, + remote_recv_offset, + local_send_offset, + remote_recv_offset); + +#ifdef WANT_HISTOGRAM + fprintf(where,"\nHistogram of request/response times\n"); + fflush(where); + HIST_report(time_hist); +#endif /* WANT_HISTOGRAM */ + + } + +} + /* this routine implements the receive (netserver) side of a SDP_RR */ + /* test */ +void +recv_sdp_rr() +{ + + struct ring_elt *send_ring; + struct ring_elt *recv_ring; + + struct addrinfo *local_res; + char local_name[BUFSIZ]; + char port_buffer[PORTBUFSIZE]; + + struct sockaddr_in myaddr_in, + peeraddr_in; + SOCKET s_listen,s_data; + netperf_socklen_t addrlen; + char *temp_message_ptr; + int trans_received; + int trans_remaining; + int bytes_sent; + int request_bytes_recvd; + int request_bytes_remaining; + int timed_out = 0; + int sock_closed = 0; + float elapsed_time; + + struct sdp_rr_request_struct *sdp_rr_request; + struct sdp_rr_response_struct *sdp_rr_response; + struct sdp_rr_results_struct *sdp_rr_results; + + sdp_rr_request = + (struct sdp_rr_request_struct *)netperf_request.content.test_specific_data; + sdp_rr_response = + (struct sdp_rr_response_struct *)netperf_response.content.test_specific_data; + sdp_rr_results = + (struct sdp_rr_results_struct *)netperf_response.content.test_specific_data; + + if (debug) { + fprintf(where,"netserver: recv_sdp_rr: entered...\n"); + fflush(where); + } + + /* We want to set-up the listen socket with all the desired */ + /* parameters and then let the initiator know that all is ready. If */ + /* socket size defaults are to be used, then the initiator will have */ + /* sent us 0's. If the socket sizes cannot be changed, then we will */ + /* send-back what they are. If that information cannot be determined, */ + /* then we send-back -1's for the sizes. If things go wrong for any */ + /* reason, we will drop back ten yards and punt. */ + + /* If anything goes wrong, we want the remote to know about it. It */ + /* would be best if the error that the remote reports to the user is */ + /* the actual error we encountered, rather than some bogus unexpected */ + /* response type message. */ + + if (debug) { + fprintf(where,"recv_sdp_rr: setting the response type...\n"); + fflush(where); + } + + netperf_response.content.response_type = SDP_RR_RESPONSE; + + if (debug) { + fprintf(where,"recv_sdp_rr: the response type is set...\n"); + fflush(where); + } + + /* allocate the recv and send rings with the requested alignments */ + /* and offsets. raj 7/94 */ + if (debug) { + fprintf(where,"recv_sdp_rr: requested recv alignment of %d offset %d\n", + sdp_rr_request->recv_alignment, + sdp_rr_request->recv_offset); + fprintf(where,"recv_sdp_rr: requested send alignment of %d offset %d\n", + sdp_rr_request->send_alignment, + sdp_rr_request->send_offset); + fflush(where); + } + + /* at some point, these need to come to us from the remote system */ + if (send_width == 0) send_width = 1; + if (recv_width == 0) recv_width = 1; + + send_ring = allocate_buffer_ring(send_width, + sdp_rr_request->response_size, + sdp_rr_request->send_alignment, + sdp_rr_request->send_offset); + + recv_ring = allocate_buffer_ring(recv_width, + sdp_rr_request->request_size, + sdp_rr_request->recv_alignment, + sdp_rr_request->recv_offset); + + + /* Grab a socket to listen on, and then listen on it. */ + + if (debug) { + fprintf(where,"recv_sdp_rr: grabbing a socket...\n"); + fflush(where); + } + + /* create_data_socket expects to find some things in the global */ + /* variables, so set the globals based on the values in the request. */ + /* once the socket has been created, we will set the response values */ + /* based on the updated value of those globals. raj 7/94 */ + lss_size_req = sdp_rr_request->send_buf_size; + lsr_size_req = sdp_rr_request->recv_buf_size; + loc_nodelay = sdp_rr_request->no_delay; + loc_rcvavoid = sdp_rr_request->so_rcvavoid; + loc_sndavoid = sdp_rr_request->so_sndavoid; + + set_hostname_and_port(local_name, + port_buffer, + nf_to_af(sdp_rr_request->ipfamily), + sdp_rr_request->port); + + local_res = complete_addrinfo(local_name, + local_name, + port_buffer, + nf_to_af(sdp_rr_request->ipfamily), + SOCK_STREAM, + IPPROTO_TCP, + 0); + + /* fake things out by changing local_res->ai_family to AF_INET_SDP */ + local_res->ai_family = AF_INET_SDP; + local_res->ai_protocol = 0; + s_listen = create_data_socket(local_res); + + if (s_listen == INVALID_SOCKET) { + netperf_response.content.serv_errno = errno; + send_response(); + + exit(1); + } + + +#ifdef WIN32 + /* The test timer can fire during operations on the listening socket, + so to make the start_timer below work we have to move + it to close s_listen while we are blocked on accept. */ + win_kludge_socket2 = s_listen; +#endif + + + /* Now, let's set-up the socket to listen for connections */ + if (listen(s_listen, 5) == SOCKET_ERROR) { + netperf_response.content.serv_errno = errno; + close(s_listen); + send_response(); + + exit(1); + } + + + /* now get the port number assigned by the system */ + addrlen = sizeof(myaddr_in); + if (getsockname(s_listen, + (struct sockaddr *)&myaddr_in, + &addrlen) == SOCKET_ERROR) { + netperf_response.content.serv_errno = errno; + close(s_listen); + send_response(); + + exit(1); + } + + /* Now myaddr_in contains the port and the internet address this is */ + /* returned to the sender also implicitly telling the sender that the */ + /* socket buffer sizing has been done. */ + + sdp_rr_response->data_port_number = (int) ntohs(myaddr_in.sin_port); + netperf_response.content.serv_errno = 0; + + /* But wait, there's more. If the initiator wanted cpu measurements, */ + /* then we must call the calibrate routine, which will return the max */ + /* rate back to the initiator. If the CPU was not to be measured, or */ + /* something went wrong with the calibration, we will return a 0.0 to */ + /* the initiator. */ + + sdp_rr_response->cpu_rate = (float)0.0; /* assume no cpu */ + sdp_rr_response->measure_cpu = 0; + + if (sdp_rr_request->measure_cpu) { + sdp_rr_response->measure_cpu = 1; + sdp_rr_response->cpu_rate = calibrate_local_cpu(sdp_rr_request->cpu_rate); + } + + + /* before we send the response back to the initiator, pull some of */ + /* the socket parms from the globals */ + sdp_rr_response->send_buf_size = lss_size; + sdp_rr_response->recv_buf_size = lsr_size; + sdp_rr_response->no_delay = loc_nodelay; + sdp_rr_response->so_rcvavoid = loc_rcvavoid; + sdp_rr_response->so_sndavoid = loc_sndavoid; + sdp_rr_response->test_length = sdp_rr_request->test_length; + send_response(); + + addrlen = sizeof(peeraddr_in); + + if ((s_data = accept(s_listen, + (struct sockaddr *)&peeraddr_in, + &addrlen)) == INVALID_SOCKET) { + /* Let's just punt. The remote will be given some information */ + close(s_listen); + + exit(1); + } + +#ifdef KLUDGE_SOCKET_OPTIONS + /* this is for those systems which *INCORRECTLY* fail to pass */ + /* attributes across an accept() call. Including this goes against */ + /* my better judgement :( raj 11/95 */ + + kludge_socket_options(s_data); + +#endif /* KLUDGE_SOCKET_OPTIONS */ + +#ifdef WIN32 + /* this is used so the timer thread can close the socket out from */ + /* under us, which to date is the easiest/cleanest/least */ + /* Windows-specific way I can find to force the winsock calls to */ + /* return WSAEINTR with the test is over. anything that will run on */ + /* 95 and NT and is closer to what netperf expects from Unix signals */ + /* and such would be appreciated raj 1/96 */ + win_kludge_socket = s_data; +#endif /* WIN32 */ + + if (debug) { + fprintf(where,"recv_sdp_rr: accept completes on the data connection.\n"); + fflush(where); + } + + /* Now it's time to start receiving data on the connection. We will */ + /* first grab the apropriate counters and then start grabbing. */ + + cpu_start(sdp_rr_request->measure_cpu); + + /* The loop will exit when we hit the end of the test time, or when */ + /* we have exchanged the requested number of transactions. */ + + if (sdp_rr_request->test_length > 0) { + times_up = 0; + trans_remaining = 0; + start_timer(sdp_rr_request->test_length + PAD_TIME); + } + else { + times_up = 1; + trans_remaining = sdp_rr_request->test_length * -1; + } + + trans_received = 0; + + while ((!times_up) || (trans_remaining > 0)) { + temp_message_ptr = recv_ring->buffer_ptr; + request_bytes_remaining = sdp_rr_request->request_size; + while(request_bytes_remaining > 0) { + if((request_bytes_recvd=recv(s_data, + temp_message_ptr, + request_bytes_remaining, + 0)) == SOCKET_ERROR) { + if (SOCKET_EINTR(request_bytes_recvd)) + { + timed_out = 1; + break; + } + + netperf_response.content.serv_errno = errno; + send_response(); + exit(1); + } + else if( request_bytes_recvd == 0 ) { + if (debug) { + fprintf(where,"zero is my hero\n"); + fflush(where); + } + sock_closed = 1; + break; + } + else { + request_bytes_remaining -= request_bytes_recvd; + temp_message_ptr += request_bytes_recvd; + } + } + + recv_ring = recv_ring->next; + + if ((timed_out) || (sock_closed)) { + /* we hit the end of the test based on time - or the socket + closed on us along the way. bail out of here now... */ + if (debug) { + fprintf(where,"yo5\n"); + fflush(where); + } + break; + } + + /* Now, send the response to the remote */ + if((bytes_sent=send(s_data, + send_ring->buffer_ptr, + sdp_rr_request->response_size, + 0)) == SOCKET_ERROR) { + if (SOCKET_EINTR(bytes_sent)) { + /* the test timer has popped */ + timed_out = 1; + fprintf(where,"yo6\n"); + fflush(where); + break; + } + netperf_response.content.serv_errno = 992; + send_response(); + exit(1); + } + + send_ring = send_ring->next; + + trans_received++; + if (trans_remaining) { + trans_remaining--; + } + } + + + /* The loop now exits due to timeout or transaction count being */ + /* reached */ + + cpu_stop(sdp_rr_request->measure_cpu,&elapsed_time); + + stop_timer(); + + if (timed_out) { + /* we ended the test by time, which was at least 2 seconds */ + /* longer than we wanted to run. so, we want to subtract */ + /* PAD_TIME from the elapsed_time. */ + elapsed_time -= PAD_TIME; + } + + /* send the results to the sender */ + + if (debug) { + fprintf(where, + "recv_sdp_rr: got %d transactions\n", + trans_received); + fflush(where); + } + + sdp_rr_results->bytes_received = (trans_received * + (sdp_rr_request->request_size + + sdp_rr_request->response_size)); + sdp_rr_results->trans_received = trans_received; + sdp_rr_results->elapsed_time = elapsed_time; + sdp_rr_results->cpu_method = cpu_method; + sdp_rr_results->num_cpus = lib_num_loc_cpus; + if (sdp_rr_request->measure_cpu) { + sdp_rr_results->cpu_util = calc_cpu_util(elapsed_time); + } + + if (debug) { + fprintf(where, + "recv_sdp_rr: test complete, sending results.\n"); + fflush(where); + } + + /* we are now done with the sockets */ + close(s_data); + close(s_listen); + + send_response(); + +} + + + +void +print_sdp_usage() +{ + + printf("%s",sdp_usage); + exit(1); + +} +void +scan_sdp_args(argc, argv) + int argc; + char *argv[]; + +{ + +#define SOCKETS_ARGS "b:DhH:I:L:m:M:P:r:s:S:V46" + + extern char *optarg; /* pointer to option string */ + + int c; + + char + arg1[BUFSIZ], /* argument holders */ + arg2[BUFSIZ]; + + if (no_control) { + fprintf(where, + "The SDP tests do not know how to deal with no control tests\n"); + exit(-1); + } + + strncpy(local_data_port,"0",sizeof(local_data_port)); + strncpy(remote_data_port,"0",sizeof(remote_data_port)); + + /* Go through all the command line arguments and break them */ + /* out. For those options that take two parms, specifying only */ + /* the first will set both to that value. Specifying only the */ + /* second will leave the first untouched. To change only the */ + /* first, use the form "first," (see the routine break_args.. */ + + while ((c= getopt(argc, argv, SOCKETS_ARGS)) != EOF) { + switch (c) { + case '?': + case '4': + remote_data_family = AF_INET; + local_data_family = AF_INET; + break; + case '6': +#if defined(AF_INET6) + remote_data_family = AF_INET6; + local_data_family = AF_INET6; +#else + fprintf(stderr, + "This netperf was not compiled on an IPv6 capable host!\n"); + fflush(stderr); + exit(-1); +#endif + break; + case 'h': + print_sdp_usage(); + exit(1); + case 'b': +#ifdef WANT_FIRST_BURST + first_burst_size = atoi(optarg); +#else /* WANT_FIRST_BURST */ + printf("Initial request burst functionality not compiled-in!\n"); +#endif /* WANT_FIRST_BURST */ + break; + case 'D': + /* set the nodelay flag */ + loc_nodelay = 1; + rem_nodelay = 1; + break; + case 'H': + break_args_explicit(optarg,arg1,arg2); + if (arg1[0]) { + /* make sure we leave room for the NULL termination boys and + girls. raj 2005-02-82 */ + remote_data_address = malloc(strlen(arg1)+1); + strncpy(remote_data_address,arg1,strlen(arg1)); + } + if (arg2[0]) + remote_data_family = parse_address_family(arg2); + break; + case 'L': + break_args_explicit(optarg,arg1,arg2); + if (arg1[0]) { + /* make sure we leave room for the NULL termination boys and + girls. raj 2005-02-82 */ + local_data_address = malloc(strlen(arg1)+1); + strncpy(local_data_address,arg1,strlen(arg1)); + } + if (arg2[0]) + local_data_family = parse_address_family(arg2); + break; + case 'P': + /* set the local and remote data port numbers for the tests to + allow them to run through those blankety blank end-to-end + breaking firewalls. raj 2004-06-15 */ + break_args(optarg,arg1,arg2); + if (arg1[0]) + strncpy(local_data_port,arg1,sizeof(local_data_port)); + if (arg2[0]) + strncpy(remote_data_port,arg2,sizeof(remote_data_port)); + break; + case 's': + /* set local socket sizes */ + break_args(optarg,arg1,arg2); + if (arg1[0]) + lss_size_req = convert(arg1); + if (arg2[0]) + lsr_size_req = convert(arg2); + break; + case 'S': + /* set remote socket sizes */ + break_args(optarg,arg1,arg2); + if (arg1[0]) + rss_size_req = convert(arg1); + if (arg2[0]) + rsr_size_req = convert(arg2); + break; + case 'r': + /* set the request/response sizes */ + break_args(optarg,arg1,arg2); + if (arg1[0]) + req_size = convert(arg1); + if (arg2[0]) + rsp_size = convert(arg2); + break; + case 'm': + /* set size of the buffer for each sent message */ + send_size = convert(optarg); + break; + case 'M': + /* set the size of the buffer for each received message */ + recv_size = convert(optarg); + break; + case 't': + /* set the test name */ + strcpy(test_name,optarg); + break; + case 'W': + /* set the "width" of the user space data */ + /* buffer. This will be the number of */ + /* send_size buffers malloc'd in the */ + /* *_STREAM test. It may be enhanced to set */ + /* both send and receive "widths" but for now */ + /* it is just the sending *_STREAM. */ + send_width = convert(optarg); + break; + case 'V': + /* we want to do copy avoidance and will set */ + /* it for everything, everywhere, if we really */ + /* can. of course, we don't know anything */ + /* about the remote... */ +#ifdef SO_SND_COPYAVOID + loc_sndavoid = 1; +#else + loc_sndavoid = 0; + printf("Local send copy avoidance not available.\n"); +#endif +#ifdef SO_RCV_COPYAVOID + loc_rcvavoid = 1; +#else + loc_rcvavoid = 0; + printf("Local recv copy avoidance not available.\n"); +#endif + rem_sndavoid = 1; + rem_rcvavoid = 1; + break; + case 'N': + /* this opton allows the user to set the number of + * messages to send. This in effect modifies the test + * time. If we know the message size, then the we can + * express the test time as message_size * number_messages + */ + msg_count = convert (optarg); + if (msg_count > 0) + test_time = 0; + break; + case 'B': + non_block = 1; + break; + case 'T': + num_associations = atoi(optarg); + if (num_associations <= 1) { + printf("Number of SDP associations must be >= 1\n"); + exit(1); + } + break; + }; + } +} + +#endif /* WANT_SDP */ diff --git a/src/nettest_sdp.h b/src/nettest_sdp.h new file mode 100644 index 0000000..31d76bc --- /dev/null +++ b/src/nettest_sdp.h @@ -0,0 +1,170 @@ +/* + Copyright (C) 2007 Hewlett-Packard Company +*/ + + /* This file contains the test-specific definitions for netperf's SDP */ + /* sockets tests */ + +/* one of these days, this should not be required */ +#ifndef AF_INET_SDP +#define AF_INET_SDP 27 +#define PF_INET_SDP AF_INET_SDP +#endif + +struct sdp_stream_request_struct { + int send_buf_size; + int recv_buf_size; /* how big does the client want it - the */ + /* receive socket buffer that is */ + int receive_size; /* how many bytes do we want to receive at one */ + /* time? */ + int recv_alignment; /* what is the alignment of the receive */ + /* buffer? */ + int recv_offset; /* and at what offset from that alignment? */ + int no_delay; /* do we disable the nagle algorithm for send */ + /* coalescing? */ + int measure_cpu; /* does the client want server cpu utilization */ + /* measured? */ + float cpu_rate; /* do we know how fast the cpu is already? */ + int test_length; /* how long is the test? */ + int so_rcvavoid; /* do we want the remote to avoid copies on */ + /* receives? */ + int so_sndavoid; /* do we want the remote to avoid send copies? */ + int dirty_count; /* how many integers in the receive buffer */ + /* should be made dirty before calling recv? */ + int clean_count; /* how many integers should be read from the */ + /* recv buffer before calling recv? */ + int port; /* the to port to which recv side should bind + to allow netperf to run through firewalls */ + int ipfamily; /* address family of ipaddress */ + int non_blocking; /* run the test in non-blocking mode */ +}; + +struct sdp_stream_response_struct { + int recv_buf_size; /* how big does the client want it */ + int receive_size; + int no_delay; + int measure_cpu; /* does the client want server cpu */ + int test_length; /* how long is the test? */ + int send_buf_size; + int data_port_number; /* connect to me here */ + float cpu_rate; /* could we measure */ + int so_rcvavoid; /* could the remote avoid receive copies? */ + int so_sndavoid; /* could the remote avoid send copies? */ + int non_blocking; /* run the test in non-blocking mode */ +}; + +struct sdp_stream_results_struct { + double bytes_received; + unsigned int recv_calls; + float elapsed_time; /* how long the test ran */ + float cpu_util; /* -1 if not measured */ + float serv_dem; /* -1 if not measured */ + int cpu_method; /* how was cpu util measured? */ + int num_cpus; /* how many CPUs had the remote? */ +}; + +struct sdp_rr_request_struct { + int recv_buf_size; /* how big does the client want it */ + int send_buf_size; + int recv_alignment; + int recv_offset; + int send_alignment; + int send_offset; + int request_size; + int response_size; + int no_delay; + int measure_cpu; /* does the client want server cpu */ + float cpu_rate; /* do we know how fast the cpu is? */ + int test_length; /* how long is the test? */ + int so_rcvavoid; /* do we want the remote to avoid receive */ + /* copies? */ + int so_sndavoid; /* do we want the remote to avoid send copies? */ + int port; /* the to port to which recv side should bind + to allow netperf to run through firewalls */ + int ipfamily; /* address family of ipaddress */ + int non_blocking; /* run the test in non-blocking mode */ +}; + +struct sdp_rr_response_struct { + int recv_buf_size; /* how big does the client want it */ + int no_delay; + int measure_cpu; /* does the client want server cpu */ + int test_length; /* how long is the test? */ + int send_buf_size; + int data_port_number; /* connect to me here */ + float cpu_rate; /* could we measure */ + int so_rcvavoid; /* could the remote avoid receive copies? */ + int so_sndavoid; /* could the remote avoid send copies? */ + int non_blocking; /* run the test in non-blocking mode */ +}; + +struct sdp_rr_results_struct { + unsigned int bytes_received; /* ignored initially */ + unsigned int recv_calls; /* ignored initially */ + unsigned int trans_received; /* not ignored */ + float elapsed_time; /* how long the test ran */ + float cpu_util; /* -1 if not measured */ + float serv_dem; /* -1 if not measured */ + int cpu_method; /* how was cpu util measured? */ + int num_cpus; /* how many CPUs had the remote? */ +}; + +struct sdp_maerts_request_struct { + int send_buf_size; + int recv_buf_size; /* how big does the client want it - the */ + /* receive socket buffer that is */ + int send_size; /* how many bytes do we want netserver to send + at one time? */ + int send_alignment; /* what is the alignment of the send */ + /* buffer? */ + int send_offset; /* and at what offset from that alignment? */ + int no_delay; /* do we disable the nagle algorithm for send */ + /* coalescing? */ + int measure_cpu; /* does the client want server cpu utilization */ + /* measured? */ + float cpu_rate; /* do we know how fast the cpu is already? */ + int test_length; /* how long is the test? */ + int so_rcvavoid; /* do we want the remote to avoid copies on */ + /* receives? */ + int so_sndavoid; /* do we want the remote to avoid send copies? */ + int dirty_count; /* how many integers in the send buffer */ + /* should be made dirty before calling recv? */ + int clean_count; /* how many integers should be read from the */ + /* recv buffer before calling recv? */ + int port; /* the port to which the recv side should bind + to allow netperf to run through those evil + firewall things */ + int ipfamily; +}; + +struct sdp_maerts_response_struct { + int recv_buf_size; /* how big does the client want it */ + int send_size; + int no_delay; + int measure_cpu; /* does the client want server cpu */ + int test_length; /* how long is the test? */ + int send_buf_size; + int data_port_number; /* connect to me here */ + float cpu_rate; /* could we measure */ + int so_rcvavoid; /* could the remote avoid receive copies? */ + int so_sndavoid; /* could the remote avoid send copies? */ +}; + +struct sdp_maerts_results_struct { + double bytes_sent; + unsigned int send_calls; + float elapsed_time; /* how long the test ran */ + float cpu_util; /* -1 if not measured */ + float serv_dem; /* -1 if not measured */ + int cpu_method; /* how was cpu util measured? */ + int num_cpus; /* how many CPUs had the remote? */ +}; + +extern void send_sdp_stream(); +extern void send_sdp_rr(); + +extern void recv_sdp_stream(); +extern void recv_sdp_rr(); + +extern void loc_cpu_rate(); +extern void rem_cpu_rate(); diff --git a/src/nettest_unix.c b/src/nettest_unix.c new file mode 100644 index 0000000..885f030 --- /dev/null +++ b/src/nettest_unix.c @@ -0,0 +1,3435 @@ +#ifdef lint +#define WANT_UNIX +#define DIRTY +#define WANT_INTERVALS +#endif /* lint */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#ifdef WIN32 +#error Unix Domain Sockets are not available under Windows +#endif + +#ifdef WANT_UNIX +char nettest_unix_id[]="\ +@(#)nettest_unix.c (c) Copyright 1994-2008 Hewlett-Packard Co. Version 2.4.5"; + +/****************************************************************/ +/* */ +/* nettest_bsd.c */ +/* */ +/* the BSD sockets parsing routine... */ +/* */ +/* scan_unix_args() */ +/* */ +/* the actual test routines... */ +/* */ +/* send_stream_stream() perform a stream stream test */ +/* recv_stream_stream() */ +/* send_stream_rr() perform a stream request/response */ +/* recv_stream_rr() */ +/* send_dg_stream() perform a dg stream test */ +/* recv_dg_stream() */ +/* send_dg_rr() perform a dg request/response */ +/* recv_dg_rr() */ +/* loc_cpu_rate() determine the local cpu maxrate */ +/* rem_cpu_rate() find the remote cpu maxrate */ +/* */ +/****************************************************************/ + + /* at some point, I might want to go-in and see if I really need all */ + /* these includes, but for the moment, we'll let them all just sit */ + /* there. raj 8/94 */ +#include +#include +#include +#include +#ifndef WIN32 +#include +#include +#include +#include +#include +#include +#else /* WIN32 */ +#include +#include +#include +#endif /* WIN32 */ +#include +#include +#include + +#ifdef NOSTDLIBH +#include +#else /* NOSTDLIBH */ +#include +#endif /* NOSTDLIBH */ + +#include + + +#include "netlib.h" +#include "netsh.h" +#include "nettest_unix.h" + + + + /* these variables are specific to the UNIX sockets tests. declare */ + /* them static to make them global only to this file. */ + +#define UNIX_PRFX "netperf." +#define UNIX_LENGTH_MAX 0xFFFF - 28 + +static char + path_prefix[32]; + +static int + rss_size, /* remote socket send buffer size */ + rsr_size, /* remote socket recv buffer size */ + lss_size_req, /* requested local socket send buffer size */ + lsr_size_req, /* requested local socket recv buffer size */ + lss_size, /* local socket send buffer size */ + lsr_size, /* local socket recv buffer size */ + req_size = 1, /* request size */ + rsp_size = 1, /* response size */ + send_size, /* how big are individual sends */ + recv_size; /* how big are individual receives */ + + /* different options for the sockets */ + + +char unix_usage[] = "\n\ +Usage: netperf [global options] -- [test options] \n\ +\n\ +STREAM/DG UNIX Sockets Test Options:\n\ + -h Display this text\n\ + -m bytes Set the send size (STREAM_STREAM, DG_STREAM)\n\ + -M bytes Set the recv size (STREAM_STREAM, DG_STREAM)\n\ + -p dir Set the directory where pipes are created\n\ + -r req,res Set request,response size (STREAM_RR, DG_RR)\n\ + -s send[,recv] Set local socket send/recv buffer sizes\n\ + -S send[,recv] Set remote socket send/recv buffer sizes\n\ +\n\ +For those options taking two parms, at least one must be specified;\n\ +specifying one value without a comma will set both parms to that\n\ +value, specifying a value with a leading comma will set just the second\n\ +parm, a value with a trailing comma will set just the first. To set\n\ +each parm to unique values, specify both and separate them with a\n\ +comma.\n"; + + /* this routing initializes all the test specific variables */ + +static void +init_test_vars() +{ + rss_size = 0; + rsr_size = 0; + lss_size_req = 0; + lsr_size_req = 0; + lss_size = 0; + lsr_size = 0; + req_size = 1; + rsp_size = 1; + send_size = 0; + recv_size = 0; + + strcpy(path_prefix,"/tmp"); + +} + + /* This routine will create a data (listen) socket with the apropriate */ + /* options set and return it to the caller. this replaces all the */ + /* duplicate code in each of the test routines and should help make */ + /* things a little easier to understand. since this routine can be */ + /* called by either the netperf or netserver programs, all output */ + /* should be directed towards "where." family is generally AF_UNIX, */ + /* and type will be either SOCK_STREAM or SOCK_DGRAM */ +SOCKET +create_unix_socket(int family, int type) +{ + + SOCKET temp_socket; + int sock_opt_len; + + /*set up the data socket */ + temp_socket = socket(family, + type, + 0); + + if (temp_socket == INVALID_SOCKET){ + fprintf(where, + "netperf: create_unix_socket: socket: %d\n", + errno); + fflush(where); + exit(1); + } + + if (debug) { + fprintf(where,"create_unix_socket: socket %d obtained...\n",temp_socket); + fflush(where); + } + + /* Modify the local socket size. The reason we alter the send buffer */ + /* size here rather than when the connection is made is to take care */ + /* of decreases in buffer size. Decreasing the window size after */ + /* connection establishment is a STREAM no-no. Also, by setting the */ + /* buffer (window) size before the connection is established, we can */ + /* control the STREAM MSS (segment size). The MSS is never more that 1/2 */ + /* the minimum receive buffer size at each half of the connection. */ + /* This is why we are altering the receive buffer size on the sending */ + /* size of a unidirectional transfer. If the user has not requested */ + /* that the socket buffers be altered, we will try to find-out what */ + /* their values are. If we cannot touch the socket buffer in any way, */ + /* we will set the values to -1 to indicate that. */ + + set_sock_buffer(temp_socket, SEND_BUFFER, lss_size_req, &lss_size); + set_sock_buffer(temp_socket, RECV_BUFFER, lsr_size_req, &lsr_size); + + return(temp_socket); + +} + + +/* This routine implements the STREAM unidirectional data transfer test */ +/* (a.k.a. stream) for the sockets interface. It receives its */ +/* parameters via global variables from the shell and writes its */ +/* output to the standard output. */ + + +void +send_stream_stream(char remote_host[]) +{ + + char *tput_title = "\ +Recv Send Send \n\ +Socket Socket Message Elapsed \n\ +Size Size Size Time Throughput \n\ +bytes bytes bytes secs. %s/sec \n\n"; + + char *tput_fmt_0 = + "%7.2f\n"; + + char *tput_fmt_1 = + "%5d %5d %6d %-6.2f %7.2f \n"; + + char *cpu_title = "\ +Recv Send Send Utilization Service Demand\n\ +Socket Socket Message Elapsed Send Recv Send Recv\n\ +Size Size Size Time Throughput local remote local remote\n\ +bytes bytes bytes secs. %-8.8s/s %% %% us/KB us/KB\n\n"; + + char *cpu_fmt_0 = + "%6.3f\n"; + + char *cpu_fmt_1 = + "%5d %5d %6d %-6.2f %7.2f %-6.2f %-6.2f %-6.3f %-6.3f\n"; + + char *ksink_fmt = "\n\ +Alignment Offset %-8.8s %-8.8s Sends %-8.8s Recvs\n\ +Local Remote Local Remote Xfered Per Per\n\ +Send Recv Send Recv Send (avg) Recv (avg)\n\ +%5d %5d %5d %5d %6.4g %6.2f %6d %6.2f %6d\n"; + + + float elapsed_time; + +#ifdef WANT_INTERVALS + int interval_count; +#endif + + /* what we want is to have a buffer space that is at least one */ + /* send-size greater than our send window. this will insure that we */ + /* are never trying to re-use a buffer that may still be in the hands */ + /* of the transport. This buffer will be malloc'd after we have found */ + /* the size of the local senc socket buffer. We will want to deal */ + /* with alignment and offset concerns as well. */ + +#ifdef DIRTY + int *message_int_ptr; +#endif +#include + + struct ring_elt *send_ring; + + int len = 0; + int nummessages; + SOCKET send_socket; + int bytes_remaining; + /* with links like fddi, one can send > 32 bits worth of bytes */ + /* during a test... ;-) */ + double bytes_sent; + +#ifdef DIRTY + int i; +#endif /* DIRTY */ + + float local_cpu_utilization; + float local_service_demand; + float remote_cpu_utilization; + float remote_service_demand; + double thruput; + + struct sockaddr_un server; + + struct stream_stream_request_struct *stream_stream_request; + struct stream_stream_response_struct *stream_stream_response; + struct stream_stream_results_struct *stream_stream_result; + + stream_stream_request = + (struct stream_stream_request_struct *)netperf_request.content.test_specific_data; + stream_stream_response = + (struct stream_stream_response_struct *)netperf_response.content.test_specific_data; + stream_stream_result = + (struct stream_stream_results_struct *)netperf_response.content.test_specific_data; + + /* since we are now disconnected from the code that established the */ + /* control socket, and since we want to be able to use different */ + /* protocols and such, we are passed the name of the remote host and */ + /* must turn that into the test specific addressing information. */ + + bzero((char *)&server, + sizeof(server)); + server.sun_family = AF_UNIX; + + + if ( print_headers ) { + fprintf(where,"STREAM STREAM TEST\n"); + if (local_cpu_usage || remote_cpu_usage) + fprintf(where,cpu_title,format_units()); + else + fprintf(where,tput_title,format_units()); + } + + /* initialize a few counters */ + + nummessages = 0; + bytes_sent = 0.0; + times_up = 0; + + /*set up the data socket */ + send_socket = create_unix_socket(AF_UNIX, + SOCK_STREAM); + + if (send_socket == INVALID_SOCKET){ + perror("netperf: send_stream_stream: stream stream data socket"); + exit(1); + } + + if (debug) { + fprintf(where,"send_stream_stream: send_socket obtained...\n"); + } + + /* at this point, we have either retrieved the socket buffer sizes, */ + /* or have tried to set them, so now, we may want to set the send */ + /* size based on that (because the user either did not use a -m */ + /* option, or used one with an argument of 0). If the socket buffer */ + /* size is not available, we will set the send size to 4KB - no */ + /* particular reason, just arbitrary... */ + if (send_size == 0) { + if (lss_size > 0) { + send_size = lss_size; + } + else { + send_size = 4096; + } + } + + /* set-up the data buffer ring with the requested alignment and offset. */ + /* note also that we have allocated a quantity */ + /* of memory that is at least one send-size greater than our socket */ + /* buffer size. We want to be sure that there are at least two */ + /* buffers allocated - this can be a bit of a problem when the */ + /* send_size is bigger than the socket size, so we must check... the */ + /* user may have wanted to explicitly set the "width" of our send */ + /* buffers, we should respect that wish... */ + if (send_width == 0) { + send_width = (lss_size/send_size) + 1; + if (send_width == 1) send_width++; + } + + send_ring = allocate_buffer_ring(send_width, + send_size, + local_send_align, + local_send_offset); + + /* If the user has requested cpu utilization measurements, we must */ + /* calibrate the cpu(s). We will perform this task within the tests */ + /* themselves. If the user has specified the cpu rate, then */ + /* calibrate_local_cpu will return rather quickly as it will have */ + /* nothing to do. If local_cpu_rate is zero, then we will go through */ + /* all the "normal" calibration stuff and return the rate back.*/ + + if (local_cpu_usage) { + local_cpu_rate = calibrate_local_cpu(local_cpu_rate); + } + + /* Tell the remote end to do a listen. The server alters the socket */ + /* paramters on the other side at this point, hence the reason for */ + /* all the values being passed in the setup message. If the user did */ + /* not specify any of the parameters, they will be passed as 0, which */ + /* will indicate to the remote that no changes beyond the system's */ + /* default should be used. Alignment is the exception, it will */ + /* default to 1, which will be no alignment alterations. */ + + netperf_request.content.request_type = DO_STREAM_STREAM; + stream_stream_request->send_buf_size = rss_size; + stream_stream_request->recv_buf_size = rsr_size; + stream_stream_request->receive_size = recv_size; + stream_stream_request->recv_alignment = remote_recv_align; + stream_stream_request->recv_offset = remote_recv_offset; + stream_stream_request->measure_cpu = remote_cpu_usage; + stream_stream_request->cpu_rate = remote_cpu_rate; + if (test_time) { + stream_stream_request->test_length = test_time; + } + else { + stream_stream_request->test_length = test_bytes; + } +#ifdef DIRTY + stream_stream_request->dirty_count = rem_dirty_count; + stream_stream_request->clean_count = rem_clean_count; +#endif /* DIRTY */ + + + if (debug > 1) { + fprintf(where, + "netperf: send_stream_stream: requesting STREAM stream test\n"); + } + + send_request(); + + /* The response from the remote will contain all of the relevant */ + /* socket parameters for this test type. We will put them back into */ + /* the variables here so they can be displayed if desired. The */ + /* remote will have calibrated CPU if necessary, and will have done */ + /* all the needed set-up we will have calibrated the cpu locally */ + /* before sending the request, and will grab the counter value right */ + /* after the connect returns. The remote will grab the counter right */ + /* after the accept call. This saves the hassle of extra messages */ + /* being sent for the STREAM tests. */ + + recv_response(); + + if (!netperf_response.content.serv_errno) { + if (debug) + fprintf(where,"remote listen done.\n"); + rsr_size = stream_stream_response->recv_buf_size; + rss_size = stream_stream_response->send_buf_size; + remote_cpu_usage = stream_stream_response->measure_cpu; + remote_cpu_rate = stream_stream_response->cpu_rate; + strcpy(server.sun_path,stream_stream_response->unix_path); + } + else { + Set_errno(netperf_response.content.serv_errno); + perror("netperf: send_stream_stream: remote error"); + exit(1); + } + + /*Connect up to the remote port on the data socket */ + if (connect(send_socket, + (struct sockaddr *)&server, + sizeof(server)) == INVALID_SOCKET){ + perror("netperf: send_stream_stream: data socket connect failed"); + printf(" path: %s\n",server.sun_path); + exit(1); + } + + /* Data Socket set-up is finished. If there were problems, either the */ + /* connect would have failed, or the previous response would have */ + /* indicated a problem. I failed to see the value of the extra */ + /* message after the accept on the remote. If it failed, we'll see it */ + /* here. If it didn't, we might as well start pumping data. */ + + /* Set-up the test end conditions. For a stream test, they can be */ + /* either time or byte-count based. */ + + if (test_time) { + /* The user wanted to end the test after a period of time. */ + times_up = 0; + bytes_remaining = 0; + start_timer(test_time); + } + else { + /* The tester wanted to send a number of bytes. */ + bytes_remaining = test_bytes; + times_up = 1; + } + + /* The cpu_start routine will grab the current time and possibly */ + /* value of the idle counter for later use in measuring cpu */ + /* utilization and/or service demand and thruput. */ + + cpu_start(local_cpu_usage); + + /* We use an "OR" to control test execution. When the test is */ + /* controlled by time, the byte count check will always return false. */ + /* When the test is controlled by byte count, the time test will */ + /* always return false. When the test is finished, the whole */ + /* expression will go false and we will stop sending data. */ + +#ifdef DIRTY + /* initialize the random number generator for putting dirty stuff */ + /* into the send buffer. raj */ + srand((int) getpid()); +#endif + + while ((!times_up) || (bytes_remaining > 0)) { + +#ifdef DIRTY + /* we want to dirty some number of consecutive integers in the buffer */ + /* we are about to send. we may also want to bring some number of */ + /* them cleanly into the cache. The clean ones will follow any dirty */ + /* ones into the cache. at some point, we might want to replace */ + /* the rand() call with something from a table to reduce our call */ + /* overhead during the test, but it is not a high priority item. */ + message_int_ptr = (int *)(send_ring->buffer_ptr); + for (i = 0; i < loc_dirty_count; i++) { + *message_int_ptr = rand(); + message_int_ptr++; + } + for (i = 0; i < loc_clean_count; i++) { + loc_dirty_count = *message_int_ptr; + message_int_ptr++; + } +#endif /* DIRTY */ + + if((len=send(send_socket, + send_ring->buffer_ptr, + send_size, + 0)) != send_size) { + if ((len >=0) || (errno == EINTR)) { + /* the test was interrupted, must be the end of test */ + break; + } + perror("netperf: data send error"); + printf("len was %d\n",len); + exit(1); + } +#ifdef WANT_INTERVALS + for (interval_count = 0; + interval_count < interval_wate; + interval_count++); +#endif + + /* now we want to move our pointer to the next position in the */ + /* data buffer...we may also want to wrap back to the "beginning" */ + /* of the bufferspace, so we will mod the number of messages sent */ + /* by the send width, and use that to calculate the offset to add */ + /* to the base pointer. */ + nummessages++; + send_ring = send_ring->next; + if (bytes_remaining) { + bytes_remaining -= send_size; + } + } + + /* The test is over. Flush the buffers to the remote end. We do a */ + /* graceful release to insure that all data has been taken by the */ + /* remote. */ + + if (close(send_socket) == -1) { + perror("netperf: send_stream_stream: cannot close socket"); + exit(1); + } + + /* this call will always give us the elapsed time for the test, and */ + /* will also store-away the necessaries for cpu utilization */ + + cpu_stop(local_cpu_usage,&elapsed_time); /* was cpu being */ + /* measured and how */ + /* long did we really */ + /* run? */ + + /* Get the statistics from the remote end. The remote will have */ + /* calculated service demand and all those interesting things. If it */ + /* wasn't supposed to care, it will return obvious values. */ + + recv_response(); + if (!netperf_response.content.serv_errno) { + if (debug) + fprintf(where,"remote results obtained\n"); + } + else { + Set_errno(netperf_response.content.serv_errno); + perror("netperf: remote error"); + + exit(1); + } + + /* We now calculate what our thruput was for the test. In the future, */ + /* we may want to include a calculation of the thruput measured by */ + /* the remote, but it should be the case that for a STREAM stream test, */ + /* that the two numbers should be *very* close... We calculate */ + /* bytes_sent regardless of the way the test length was controlled. */ + /* If it was time, we needed to, and if it was by bytes, the user may */ + /* have specified a number of bytes that wasn't a multiple of the */ + /* send_size, so we really didn't send what he asked for ;-) */ + + bytes_sent = ((double) send_size * (double) nummessages) + len; + thruput = calc_thruput(bytes_sent); + + if (local_cpu_usage || remote_cpu_usage) { + /* We must now do a little math for service demand and cpu */ + /* utilization for the system(s) */ + /* Of course, some of the information might be bogus because */ + /* there was no idle counter in the kernel(s). We need to make */ + /* a note of this for the user's benefit...*/ + if (local_cpu_usage) { + if (local_cpu_rate == 0.0) { + fprintf(where,"WARNING WARNING WARNING WARNING WARNING WARNING WARNING!\n"); + fprintf(where,"Local CPU usage numbers based on process information only!\n"); + fflush(where); + } + local_cpu_utilization = calc_cpu_util(0.0); + local_service_demand = calc_service_demand(bytes_sent, + 0.0, + 0.0, + 0); + } + else { + local_cpu_utilization = -1.0; + local_service_demand = -1.0; + } + + if (remote_cpu_usage) { + if (remote_cpu_rate == 0.0) { + fprintf(where,"DANGER DANGER DANGER DANGER DANGER DANGER DANGER!\n"); + fprintf(where,"Remote CPU usage numbers based on process information only!\n"); + fflush(where); + } + remote_cpu_utilization = stream_stream_result->cpu_util; + remote_service_demand = calc_service_demand(bytes_sent, + 0.0, + remote_cpu_utilization, + stream_stream_result->num_cpus); + } + else { + remote_cpu_utilization = -1.0; + remote_service_demand = -1.0; + } + + /* We are now ready to print all the information. If the user */ + /* has specified zero-level verbosity, we will just print the */ + /* local service demand, or the remote service demand. If the */ + /* user has requested verbosity level 1, he will get the basic */ + /* "streamperf" numbers. If the user has specified a verbosity */ + /* of greater than 1, we will display a veritable plethora of */ + /* background information from outside of this block as it it */ + /* not cpu_measurement specific... */ + + switch (verbosity) { + case 0: + if (local_cpu_usage) { + fprintf(where, + cpu_fmt_0, + local_service_demand); + } + else { + fprintf(where, + cpu_fmt_0, + remote_service_demand); + } + break; + case 1: + case 2: + fprintf(where, + cpu_fmt_1, /* the format string */ + rsr_size, /* remote recvbuf size */ + lss_size, /* local sendbuf size */ + send_size, /* how large were the sends */ + elapsed_time, /* how long was the test */ + thruput, /* what was the xfer rate */ + local_cpu_utilization, /* local cpu */ + remote_cpu_utilization, /* remote cpu */ + local_service_demand, /* local service demand */ + remote_service_demand); /* remote service demand */ + break; + } + } + else { + /* The tester did not wish to measure service demand. */ + switch (verbosity) { + case 0: + fprintf(where, + tput_fmt_0, + thruput); + break; + case 1: + case 2: + fprintf(where, + tput_fmt_1, /* the format string */ + rsr_size, /* remote recvbuf size */ + lss_size, /* local sendbuf size */ + send_size, /* how large were the sends */ + elapsed_time, /* how long did it take */ + thruput);/* how fast did it go */ + break; + } + } + + /* it would be a good thing to include information about some of the */ + /* other parameters that may have been set for this test, but at the */ + /* moment, I do not wish to figure-out all the formatting, so I will */ + /* just put this comment here to help remind me that it is something */ + /* that should be done at a later time. */ + + if (verbosity > 1) { + /* The user wanted to know it all, so we will give it to him. */ + /* This information will include as much as we can find about */ + /* STREAM statistics, the alignments of the sends and receives */ + /* and all that sort of rot... */ + + fprintf(where, + ksink_fmt, + "Bytes", + "Bytes", + "Bytes", + local_send_align, + remote_recv_align, + local_send_offset, + remote_recv_offset, + bytes_sent, + bytes_sent / (double)nummessages, + nummessages, + bytes_sent / (double)stream_stream_result->recv_calls, + stream_stream_result->recv_calls); + } + +} + + +/* This is the server-side routine for the stream stream test. It is */ +/* implemented as one routine. I could break things-out somewhat, but */ +/* didn't feel it was necessary. */ + +void +recv_stream_stream() +{ + + struct sockaddr_un myaddr_un, peeraddr_un; + SOCKET s_listen,s_data; + int addrlen; + int len; + int receive_calls = 0; + float elapsed_time; + int bytes_received; + + struct ring_elt *recv_ring; + +#ifdef DIRTY + char *message_ptr; + int *message_int_ptr; + int dirty_count; + int clean_count; + int i; +#endif + + struct stream_stream_request_struct *stream_stream_request; + struct stream_stream_response_struct *stream_stream_response; + struct stream_stream_results_struct *stream_stream_results; + + stream_stream_request = + (struct stream_stream_request_struct *)netperf_request.content.test_specific_data; + stream_stream_response = + (struct stream_stream_response_struct *)netperf_response.content.test_specific_data; + stream_stream_results = + (struct stream_stream_results_struct *)netperf_response.content.test_specific_data; + + if (debug) { + fprintf(where,"netserver: recv_stream_stream: entered...\n"); + fflush(where); + } + + /* We want to set-up the listen socket with all the desired */ + /* parameters and then let the initiator know that all is ready. If */ + /* socket size defaults are to be used, then the initiator will have */ + /* sent us 0's. If the socket sizes cannot be changed, then we will */ + /* send-back what they are. If that information cannot be determined, */ + /* then we send-back -1's for the sizes. If things go wrong for any */ + /* reason, we will drop back ten yards and punt. */ + + /* If anything goes wrong, we want the remote to know about it. It */ + /* would be best if the error that the remote reports to the user is */ + /* the actual error we encountered, rather than some bogus unexpected */ + /* response type message. */ + + if (debug) { + fprintf(where,"recv_stream_stream: setting the response type...\n"); + fflush(where); + } + + netperf_response.content.response_type = STREAM_STREAM_RESPONSE; + + if (debug) { + fprintf(where,"recv_stream_stream: the response type is set...\n"); + fflush(where); + } + + /* We now alter the message_ptr variable to be at the desired */ + /* alignment with the desired offset. */ + + if (debug) { + fprintf(where,"recv_stream_stream: requested alignment of %d\n", + stream_stream_request->recv_alignment); + fflush(where); + } + + /* Let's clear-out our sockaddr for the sake of cleanlines. Then we */ + /* can put in OUR values !-) At some point, we may want to nail this */ + /* socket to a particular network-level address, but for now, */ + /* INADDR_ANY should be just fine. */ + + bzero((char *)&myaddr_un, + sizeof(myaddr_un)); + myaddr_un.sun_family = AF_UNIX; + + /* Grab a socket to listen on, and then listen on it. */ + + if (debug) { + fprintf(where,"recv_stream_stream: grabbing a socket...\n"); + fflush(where); + } + + /* create_unix_socket expects to find some things in the global */ + /* variables, so set the globals based on the values in the request. */ + /* once the socket has been created, we will set the response values */ + /* based on the updated value of those globals. raj 7/94 */ + lss_size_req = stream_stream_request->send_buf_size; + lsr_size_req = stream_stream_request->recv_buf_size; + + s_listen = create_unix_socket(AF_UNIX, + SOCK_STREAM); + + if (s_listen == INVALID_SOCKET) { + netperf_response.content.serv_errno = errno; + send_response(); + exit(1); + } + + /* Let's get an address assigned to this socket so we can tell the */ + /* initiator how to reach the data socket. There may be a desire to */ + /* nail this socket to a specific IP address in a multi-homed, */ + /* multi-connection situation, but for now, we'll ignore the issue */ + /* and concentrate on single connection testing. */ + + strcpy(myaddr_un.sun_path,tempnam(path_prefix,"netperf.")); + if (debug) { + fprintf(where,"selected a path of %s\n",myaddr_un.sun_path); + fflush(where); + } + if (bind(s_listen, + (struct sockaddr *)&myaddr_un, + sizeof(myaddr_un)) == SOCKET_ERROR) { + netperf_response.content.serv_errno = errno; + fprintf(where,"could not bind to path\n"); + close(s_listen); + send_response(); + + exit(1); + } + + chmod(myaddr_un.sun_path, 0666); + + /* what sort of sizes did we end-up with? */ + if (stream_stream_request->receive_size == 0) { + if (lsr_size > 0) { + recv_size = lsr_size; + } + else { + recv_size = 4096; + } + } + else { + recv_size = stream_stream_request->receive_size; + } + + /* we want to set-up our recv_ring in a manner analagous to what we */ + /* do on the sending side. this is more for the sake of symmetry */ + /* than for the needs of say copy avoidance, but it might also be */ + /* more realistic - this way one could conceivably go with a */ + /* double-buffering scheme when taking the data an putting it into */ + /* the filesystem or something like that. raj 7/94 */ + + if (recv_width == 0) { + recv_width = (lsr_size/recv_size) + 1; + if (recv_width == 1) recv_width++; + } + + recv_ring = allocate_buffer_ring(recv_width, + recv_size, + stream_stream_request->recv_alignment, + stream_stream_request->recv_offset); + + if (debug) { + fprintf(where,"recv_stream_stream: receive alignment and offset set...\n"); + fflush(where); + } + + /* Now, let's set-up the socket to listen for connections */ + if (listen(s_listen, 5) == SOCKET_ERROR) { + netperf_response.content.serv_errno = errno; + close(s_listen); + send_response(); + + exit(1); + } + + /* now get the port number assigned by the system */ + addrlen = sizeof(myaddr_un); + if (getsockname(s_listen, + (struct sockaddr *)&myaddr_un, + &addrlen) == SOCKET_ERROR){ + netperf_response.content.serv_errno = errno; + close(s_listen); + send_response(); + + exit(1); + } + + /* Now myaddr_un contains the path */ + /* returned to the sender also implicitly telling the sender that the */ + /* socket buffer sizing has been done. */ + strcpy(stream_stream_response->unix_path,myaddr_un.sun_path); + netperf_response.content.serv_errno = 0; + + /* But wait, there's more. If the initiator wanted cpu measurements, */ + /* then we must call the calibrate routine, which will return the max */ + /* rate back to the initiator. If the CPU was not to be measured, or */ + /* something went wrong with the calibration, we will return a -1 to */ + /* the initiator. */ + + stream_stream_response->cpu_rate = 0.0; /* assume no cpu */ + if (stream_stream_request->measure_cpu) { + stream_stream_response->measure_cpu = 1; + stream_stream_response->cpu_rate = + calibrate_local_cpu(stream_stream_request->cpu_rate); + } + + /* before we send the response back to the initiator, pull some of */ + /* the socket parms from the globals */ + stream_stream_response->send_buf_size = lss_size; + stream_stream_response->recv_buf_size = lsr_size; + stream_stream_response->receive_size = recv_size; + + send_response(); + + addrlen = sizeof(peeraddr_un); + + if ((s_data=accept(s_listen, + (struct sockaddr *)&peeraddr_un, + &addrlen)) == INVALID_SOCKET) { + /* Let's just punt. The remote will be given some information */ + close(s_listen); + exit(1); + } + + /* Now it's time to start receiving data on the connection. We will */ + /* first grab the apropriate counters and then start grabbing. */ + + cpu_start(stream_stream_request->measure_cpu); + + /* The loop will exit when the sender does a shutdown, which will */ + /* return a length of zero */ + +#ifdef DIRTY + /* we want to dirty some number of consecutive integers in the buffer */ + /* we are about to recv. we may also want to bring some number of */ + /* them cleanly into the cache. The clean ones will follow any dirty */ + /* ones into the cache. */ + + dirty_count = stream_stream_request->dirty_count; + clean_count = stream_stream_request->clean_count; + message_int_ptr = (int *)recv_ring->buffer_ptr; + for (i = 0; i < dirty_count; i++) { + *message_int_ptr = rand(); + message_int_ptr++; + } + for (i = 0; i < clean_count; i++) { + dirty_count = *message_int_ptr; + message_int_ptr++; + } +#endif /* DIRTY */ + bytes_received = 0; + + while ((len = recv(s_data, recv_ring->buffer_ptr, recv_size, 0)) != 0) { + if (len == SOCKET_ERROR) { + netperf_response.content.serv_errno = errno; + send_response(); + exit(1); + } + bytes_received += len; + receive_calls++; + + /* more to the next buffer in the recv_ring */ + recv_ring = recv_ring->next; + +#ifdef DIRTY + message_int_ptr = (int *)(recv_ring->buffer_ptr); + for (i = 0; i < dirty_count; i++) { + *message_int_ptr = rand(); + message_int_ptr++; + } + for (i = 0; i < clean_count; i++) { + dirty_count = *message_int_ptr; + message_int_ptr++; + } +#endif /* DIRTY */ + } + + /* The loop now exits due to zero bytes received. we will have */ + /* counted one too many messages received, so decrement the */ + /* receive_calls counter by one. raj 7/94 */ + receive_calls--; + + /* perform a shutdown to signal the sender that */ + /* we have received all the data sent. raj 4/93 */ + + if (shutdown(s_data,1) == SOCKET_ERROR) { + netperf_response.content.serv_errno = errno; + send_response(); + exit(1); + } + + cpu_stop(stream_stream_request->measure_cpu,&elapsed_time); + + /* send the results to the sender */ + + if (debug) { + fprintf(where, + "recv_stream_stream: got %d bytes\n", + bytes_received); + fprintf(where, + "recv_stream_stream: got %d recvs\n", + receive_calls); + fflush(where); + } + + stream_stream_results->bytes_received = bytes_received; + stream_stream_results->elapsed_time = elapsed_time; + stream_stream_results->recv_calls = receive_calls; + + if (stream_stream_request->measure_cpu) { + stream_stream_results->cpu_util = calc_cpu_util(0.0); + }; + + if (debug > 1) { + fprintf(where, + "recv_stream_stream: test complete, sending results.\n"); + fflush(where); + } + + send_response(); + unlink(myaddr_un.sun_path); +} + + + /* this routine implements the sending (netperf) side of the STREAM_RR */ + /* test. */ + +void +send_stream_rr(char remote_host[]) +{ + + char *tput_title = "\ +Local /Remote\n\ +Socket Size Request Resp. Elapsed Trans.\n\ +Send Recv Size Size Time Rate \n\ +bytes Bytes bytes bytes secs. per sec \n\n"; + + char *tput_fmt_0 = + "%7.2f\n"; + + char *tput_fmt_1_line_1 = "\ +%-6d %-6d %-6d %-6d %-6.2f %7.2f \n"; + char *tput_fmt_1_line_2 = "\ +%-6d %-6d\n"; + + char *cpu_title = "\ +Local /Remote\n\ +Socket Size Request Resp. Elapsed Trans. CPU CPU S.dem S.dem\n\ +Send Recv Size Size Time Rate local remote local remote\n\ +bytes bytes bytes bytes secs. per sec %% %% us/Tr us/Tr\n\n"; + + char *cpu_fmt_0 = + "%6.3f\n"; + + char *cpu_fmt_1_line_1 = "\ +%-6d %-6d %-6d %-6d %-6.2f %-6.2f %-6.2f %-6.2f %-6.3f %-6.3f\n"; + + char *cpu_fmt_1_line_2 = "\ +%-6d %-6d\n"; + + char *ksink_fmt = "\ +Alignment Offset\n\ +Local Remote Local Remote\n\ +Send Recv Send Recv\n\ +%5d %5d %5d %5d\n"; + + + int timed_out = 0; + float elapsed_time; + + int len; + char *temp_message_ptr; + int nummessages; + SOCKET send_socket; + int trans_remaining; + double bytes_xferd; + + struct ring_elt *send_ring; + struct ring_elt *recv_ring; + + int rsp_bytes_left; + int rsp_bytes_recvd; + + float local_cpu_utilization; + float local_service_demand; + float remote_cpu_utilization; + float remote_service_demand; + double thruput; + + struct sockaddr_un server; + + struct stream_rr_request_struct *stream_rr_request; + struct stream_rr_response_struct *stream_rr_response; + struct stream_rr_results_struct *stream_rr_result; + + stream_rr_request = + (struct stream_rr_request_struct *)netperf_request.content.test_specific_data; + stream_rr_response= + (struct stream_rr_response_struct *)netperf_response.content.test_specific_data; + stream_rr_result = + (struct stream_rr_results_struct *)netperf_response.content.test_specific_data; + + /* since we are now disconnected from the code that established the */ + /* control socket, and since we want to be able to use different */ + /* protocols and such, we are passed the name of the remote host and */ + /* must turn that into the test specific addressing information. */ + + bzero((char *)&server, + sizeof(server)); + + server.sun_family = AF_UNIX; + + + if ( print_headers ) { + fprintf(where,"STREAM REQUEST/RESPONSE TEST\n"); + if (local_cpu_usage || remote_cpu_usage) + fprintf(where,cpu_title,format_units()); + else + fprintf(where,tput_title,format_units()); + } + + /* initialize a few counters */ + + nummessages = 0; + bytes_xferd = 0.0; + times_up = 0; + + /* set-up the data buffers with the requested alignment and offset. */ + /* since this is a request/response test, default the send_width and */ + /* recv_width to 1 and not two raj 7/94 */ + + if (send_width == 0) send_width = 1; + if (recv_width == 0) recv_width = 1; + + send_ring = allocate_buffer_ring(send_width, + req_size, + local_send_align, + local_send_offset); + + recv_ring = allocate_buffer_ring(recv_width, + rsp_size, + local_recv_align, + local_recv_offset); + + /*set up the data socket */ + send_socket = create_unix_socket(AF_UNIX, + SOCK_STREAM); + + if (send_socket == INVALID_SOCKET){ + perror("netperf: send_stream_rr: stream stream data socket"); + exit(1); + } + + if (debug) { + fprintf(where,"send_stream_rr: send_socket obtained...\n"); + } + + /* If the user has requested cpu utilization measurements, we must */ + /* calibrate the cpu(s). We will perform this task within the tests */ + /* themselves. If the user has specified the cpu rate, then */ + /* calibrate_local_cpu will return rather quickly as it will have */ + /* nothing to do. If local_cpu_rate is zero, then we will go through */ + /* all the "normal" calibration stuff and return the rate back.*/ + + if (local_cpu_usage) { + local_cpu_rate = calibrate_local_cpu(local_cpu_rate); + } + + /* Tell the remote end to do a listen. The server alters the socket */ + /* paramters on the other side at this point, hence the reason for */ + /* all the values being passed in the setup message. If the user did */ + /* not specify any of the parameters, they will be passed as 0, which */ + /* will indicate to the remote that no changes beyond the system's */ + /* default should be used. Alignment is the exception, it will */ + /* default to 8, which will be no alignment alterations. */ + + netperf_request.content.request_type = DO_STREAM_RR; + stream_rr_request->recv_buf_size = rsr_size; + stream_rr_request->send_buf_size = rss_size; + stream_rr_request->recv_alignment= remote_recv_align; + stream_rr_request->recv_offset = remote_recv_offset; + stream_rr_request->send_alignment= remote_send_align; + stream_rr_request->send_offset = remote_send_offset; + stream_rr_request->request_size = req_size; + stream_rr_request->response_size = rsp_size; + stream_rr_request->measure_cpu = remote_cpu_usage; + stream_rr_request->cpu_rate = remote_cpu_rate; + if (test_time) { + stream_rr_request->test_length = test_time; + } + else { + stream_rr_request->test_length = test_trans * -1; + } + + if (debug > 1) { + fprintf(where,"netperf: send_stream_rr: requesting STREAM rr test\n"); + } + + send_request(); + + /* The response from the remote will contain all of the relevant */ + /* socket parameters for this test type. We will put them back into */ + /* the variables here so they can be displayed if desired. The */ + /* remote will have calibrated CPU if necessary, and will have done */ + /* all the needed set-up we will have calibrated the cpu locally */ + /* before sending the request, and will grab the counter value right */ + /* after the connect returns. The remote will grab the counter right */ + /* after the accept call. This saves the hassle of extra messages */ + /* being sent for the STREAM tests. */ + + recv_response(); + + if (!netperf_response.content.serv_errno) { + if (debug) + fprintf(where,"remote listen done.\n"); + rsr_size = stream_rr_response->recv_buf_size; + rss_size = stream_rr_response->send_buf_size; + remote_cpu_usage= stream_rr_response->measure_cpu; + remote_cpu_rate = stream_rr_response->cpu_rate; + /* make sure that port numbers are in network order */ + strcpy(server.sun_path,stream_rr_response->unix_path); + } + else { + Set_errno(netperf_response.content.serv_errno); + perror("netperf: remote error"); + + exit(1); + } + + /*Connect up to the remote port on the data socket */ + if (connect(send_socket, + (struct sockaddr *)&server, + sizeof(server)) == INVALID_SOCKET){ + perror("netperf: data socket connect failed"); + + exit(1); + } + + /* Data Socket set-up is finished. If there were problems, either the */ + /* connect would have failed, or the previous response would have */ + /* indicated a problem. I failed to see the value of the extra */ + /* message after the accept on the remote. If it failed, we'll see it */ + /* here. If it didn't, we might as well start pumping data. */ + + /* Set-up the test end conditions. For a request/response test, they */ + /* can be either time or transaction based. */ + + if (test_time) { + /* The user wanted to end the test after a period of time. */ + times_up = 0; + trans_remaining = 0; + start_timer(test_time); + } + else { + /* The tester wanted to send a number of bytes. */ + trans_remaining = test_bytes; + times_up = 1; + } + + /* The cpu_start routine will grab the current time and possibly */ + /* value of the idle counter for later use in measuring cpu */ + /* utilization and/or service demand and thruput. */ + + cpu_start(local_cpu_usage); + + /* We use an "OR" to control test execution. When the test is */ + /* controlled by time, the byte count check will always return false. */ + /* When the test is controlled by byte count, the time test will */ + /* always return false. When the test is finished, the whole */ + /* expression will go false and we will stop sending data. I think I */ + /* just arbitrarily decrement trans_remaining for the timed test, but */ + /* will not do that just yet... One other question is whether or not */ + /* the send buffer and the receive buffer should be the same buffer. */ + + while ((!times_up) || (trans_remaining > 0)) { + /* send the request. we assume that if we use a blocking socket, */ + /* the request will be sent at one shot. */ + if((len=send(send_socket, + send_ring->buffer_ptr, + req_size, + 0)) != req_size) { + if (errno == EINTR) { + /* we hit the end of a */ + /* timed test. */ + timed_out = 1; + break; + } + perror("send_stream_rr: data send error"); + exit(1); + } + send_ring = send_ring->next; + + /* receive the response */ + rsp_bytes_left = rsp_size; + temp_message_ptr = recv_ring->buffer_ptr; + while(rsp_bytes_left > 0) { + if((rsp_bytes_recvd=recv(send_socket, + temp_message_ptr, + rsp_bytes_left, + 0)) == SOCKET_ERROR) { + if (errno == EINTR) { + /* We hit the end of a timed test. */ + timed_out = 1; + break; + } + perror("send_stream_rr: data recv error"); + exit(1); + } + rsp_bytes_left -= rsp_bytes_recvd; + temp_message_ptr += rsp_bytes_recvd; + } + recv_ring = recv_ring->next; + + if (timed_out) { + /* we may have been in a nested while loop - we need */ + /* another call to break. */ + break; + } + + nummessages++; + if (trans_remaining) { + trans_remaining--; + } + + if (debug > 3) { + fprintf(where, + "Transaction %d completed\n", + nummessages); + fflush(where); + } + } + + /* At this point we used to call shutdown on the data socket to be */ + /* sure all the data was delivered, but this was not germane in a */ + /* request/response test, and it was causing the tests to "hang" when */ + /* they were being controlled by time. So, I have replaced this */ + /* shutdown call with a call to close that can be found later in the */ + /* procedure. */ + + /* this call will always give us the elapsed time for the test, and */ + /* will also store-away the necessaries for cpu utilization */ + + cpu_stop(local_cpu_usage,&elapsed_time); /* was cpu being measured? */ + /* how long did we really run? */ + + /* Get the statistics from the remote end. The remote will have */ + /* calculated service demand and all those interesting things. If it */ + /* wasn't supposed to care, it will return obvious values. */ + + recv_response(); + if (!netperf_response.content.serv_errno) { + if (debug) + fprintf(where,"remote results obtained\n"); + } + else { + Set_errno(netperf_response.content.serv_errno); + perror("netperf: remote error"); + + exit(1); + } + + /* We now calculate what our thruput was for the test. In the future, */ + /* we may want to include a calculation of the thruput measured by */ + /* the remote, but it should be the case that for a STREAM stream test, */ + /* that the two numbers should be *very* close... We calculate */ + /* bytes_sent regardless of the way the test length was controlled. */ + /* If it was time, we needed to, and if it was by bytes, the user may */ + /* have specified a number of bytes that wasn't a multiple of the */ + /* send_size, so we really didn't send what he asked for ;-) We use */ + /* Kbytes/s as the units of thruput for a STREAM stream test, where K = */ + /* 1024. A future enhancement *might* be to choose from a couple of */ + /* unit selections. */ + + bytes_xferd = (req_size * nummessages) + (rsp_size * nummessages); + thruput = calc_thruput(bytes_xferd); + + if (local_cpu_usage || remote_cpu_usage) { + /* We must now do a little math for service demand and cpu */ + /* utilization for the system(s) */ + /* Of course, some of the information might be bogus because */ + /* there was no idle counter in the kernel(s). We need to make */ + /* a note of this for the user's benefit...*/ + if (local_cpu_usage) { + if (local_cpu_rate == 0.0) { + fprintf(where,"WARNING WARNING WARNING WARNING WARNING WARNING WARNING!\n"); + fprintf(where,"Local CPU usage numbers based on process information only!\n"); + fflush(where); + } + local_cpu_utilization = calc_cpu_util(0.0); + /* since calc_service demand is doing ms/Kunit we will */ + /* multiply the number of transaction by 1024 to get */ + /* "good" numbers */ + local_service_demand = calc_service_demand((double) nummessages*1024, + 0.0, + 0.0, + 0); + } + else { + local_cpu_utilization = -1.0; + local_service_demand = -1.0; + } + + if (remote_cpu_usage) { + if (remote_cpu_rate == 0.0) { + fprintf(where,"DANGER DANGER DANGER DANGER DANGER DANGER DANGER!\n"); + fprintf(where,"Remote CPU usage numbers based on process information only!\n"); + fflush(where); + } + remote_cpu_utilization = stream_rr_result->cpu_util; + /* since calc_service demand is doing ms/Kunit we will */ + /* multiply the number of transaction by 1024 to get */ + /* "good" numbers */ + remote_service_demand = calc_service_demand((double) nummessages*1024, + 0.0, + remote_cpu_utilization, + stream_rr_result->num_cpus); + } + else { + remote_cpu_utilization = -1.0; + remote_service_demand = -1.0; + } + + /* We are now ready to print all the information. If the user */ + /* has specified zero-level verbosity, we will just print the */ + /* local service demand, or the remote service demand. If the */ + /* user has requested verbosity level 1, he will get the basic */ + /* "streamperf" numbers. If the user has specified a verbosity */ + /* of greater than 1, we will display a veritable plethora of */ + /* background information from outside of this block as it it */ + /* not cpu_measurement specific... */ + + switch (verbosity) { + case 0: + if (local_cpu_usage) { + fprintf(where, + cpu_fmt_0, + local_service_demand); + } + else { + fprintf(where, + cpu_fmt_0, + remote_service_demand); + } + break; + case 1: + fprintf(where, + cpu_fmt_1_line_1, /* the format string */ + lss_size, /* local sendbuf size */ + lsr_size, + req_size, /* how large were the requests */ + rsp_size, /* guess */ + elapsed_time, /* how long was the test */ + nummessages/elapsed_time, + local_cpu_utilization, /* local cpu */ + remote_cpu_utilization, /* remote cpu */ + local_service_demand, /* local service demand */ + remote_service_demand); /* remote service demand */ + fprintf(where, + cpu_fmt_1_line_2, + rss_size, + rsr_size); + break; + } + } + else { + /* The tester did not wish to measure service demand. */ + switch (verbosity) { + case 0: + fprintf(where, + tput_fmt_0, + nummessages/elapsed_time); + break; + case 1: + fprintf(where, + tput_fmt_1_line_1, /* the format string */ + lss_size, + lsr_size, + req_size, /* how large were the requests */ + rsp_size, /* how large were the responses */ + elapsed_time, /* how long did it take */ + nummessages/elapsed_time); + fprintf(where, + tput_fmt_1_line_2, + rss_size, /* remote recvbuf size */ + rsr_size); + + break; + } + } + + /* it would be a good thing to include information about some of the */ + /* other parameters that may have been set for this test, but at the */ + /* moment, I do not wish to figure-out all the formatting, so I will */ + /* just put this comment here to help remind me that it is something */ + /* that should be done at a later time. */ + + if (verbosity > 1) { + /* The user wanted to know it all, so we will give it to him. */ + /* This information will include as much as we can find about */ + /* STREAM statistics, the alignments of the sends and receives */ + /* and all that sort of rot... */ + + fprintf(where, + ksink_fmt); + } + /* The test is over. Kill the data socket */ + + if (close(send_socket) == -1) { + perror("send_stream_rr: cannot shutdown stream stream socket"); + } + +} + +void +send_dg_stream(char remote_host[]) +{ + /************************************************************************/ + /* */ + /* DG Unidirectional Send Test */ + /* */ + /************************************************************************/ + char *tput_title = + "Socket Message Elapsed Messages \n\ +Size Size Time Okay Errors Throughput\n\ +bytes bytes secs # # %s/sec\n\n"; + + char *tput_fmt_0 = + "%7.2f\n"; + + char *tput_fmt_1 = + "%5d %5d %-7.2f %7d %6d %7.2f\n\ +%5d %-7.2f %7d %7.2f\n\n"; + + + char *cpu_title = + "Socket Message Elapsed Messages CPU Service\n\ +Size Size Time Okay Errors Throughput Util Demand\n\ +bytes bytes secs # # %s/sec %% us/KB\n\n"; + + char *cpu_fmt_0 = + "%6.2f\n"; + + char *cpu_fmt_1 = + "%5d %5d %-7.2f %7d %6d %7.1f %-6.2f %-6.3f\n\ +%5d %-7.2f %7d %7.1f %-6.2f %-6.3f\n\n"; + + int messages_recvd; + float elapsed_time, + local_cpu_utilization, + remote_cpu_utilization; + + float local_service_demand, remote_service_demand; + double local_thruput, remote_thruput; + double bytes_sent; + double bytes_recvd; + + + int len; + struct ring_elt *send_ring; + int failed_sends; + int failed_cows; + int messages_sent; + SOCKET data_socket; + + +#ifdef WANT_INTERVALS + int interval_count; +#endif /* WANT_INTERVALS */ +#ifdef DIRTY + int *message_int_ptr; + int i; +#endif /* DIRTY */ + + struct sockaddr_un server; + + struct dg_stream_request_struct *dg_stream_request; + struct dg_stream_response_struct *dg_stream_response; + struct dg_stream_results_struct *dg_stream_results; + + dg_stream_request = (struct dg_stream_request_struct *)netperf_request.content.test_specific_data; + dg_stream_response = (struct dg_stream_response_struct *)netperf_response.content.test_specific_data; + dg_stream_results = (struct dg_stream_results_struct *)netperf_response.content.test_specific_data; + + /* since we are now disconnected from the code that established the */ + /* control socket, and since we want to be able to use different */ + /* protocols and such, we are passed the name of the remote host and */ + /* must turn that into the test specific addressing information. */ + + bzero((char *)&server, + sizeof(server)); + + server.sun_family = AF_UNIX; + + if ( print_headers ) { + printf("DG UNIDIRECTIONAL SEND TEST\n"); + if (local_cpu_usage || remote_cpu_usage) + printf(cpu_title,format_units()); + else + printf(tput_title,format_units()); + } + + failed_sends = 0; + failed_cows = 0; + messages_sent = 0; + times_up = 0; + + /*set up the data socket */ + data_socket = create_unix_socket(AF_UNIX, + SOCK_DGRAM); + + if (data_socket == INVALID_SOCKET){ + perror("dg_send: data socket"); + exit(1); + } + + /* now, we want to see if we need to set the send_size */ + if (send_size == 0) { + if (lss_size > 0) { + send_size = (lss_size < UNIX_LENGTH_MAX ? lss_size : UNIX_LENGTH_MAX); + } + else { + send_size = 4096; + } + } + + + /* set-up the data buffer with the requested alignment and offset, */ + /* most of the numbers here are just a hack to pick something nice */ + /* and big in an attempt to never try to send a buffer a second time */ + /* before it leaves the node...unless the user set the width */ + /* explicitly. */ + if (send_width == 0) send_width = 32; + + send_ring = allocate_buffer_ring(send_width, + send_size, + local_send_align, + local_send_offset); + + /* At this point, we want to do things like disable DG checksumming */ + /* and measure the cpu rate and all that so we are ready to go */ + /* immediately after the test response message is delivered. */ + + /* if the user supplied a cpu rate, this call will complete rather */ + /* quickly, otherwise, the cpu rate will be retured to us for */ + /* possible display. The Library will keep it's own copy of this data */ + /* for use elsewhere. We will only display it. (Does that make it */ + /* "opaque" to us?) */ + + if (local_cpu_usage) + local_cpu_rate = calibrate_local_cpu(local_cpu_rate); + + /* Tell the remote end to set up the data connection. The server */ + /* sends back the port number and alters the socket parameters there. */ + /* Of course this is a datagram service so no connection is actually */ + /* set up, the server just sets up the socket and binds it. */ + + netperf_request.content.request_type = DO_DG_STREAM; + dg_stream_request->recv_buf_size = rsr_size; + dg_stream_request->message_size = send_size; + dg_stream_request->recv_alignment = remote_recv_align; + dg_stream_request->recv_offset = remote_recv_offset; + dg_stream_request->measure_cpu = remote_cpu_usage; + dg_stream_request->cpu_rate = remote_cpu_rate; + dg_stream_request->test_length = test_time; + + send_request(); + + recv_response(); + + if (!netperf_response.content.serv_errno) { + if (debug) + fprintf(where,"send_dg_stream: remote data connection done.\n"); + } + else { + Set_errno(netperf_response.content.serv_errno); + perror("send_dg_stream: error on remote"); + exit(1); + } + + /* Place the port number returned by the remote into the sockaddr */ + /* structure so our sends can be sent to the correct place. Also get */ + /* some of the returned socket buffer information for user display. */ + + /* make sure that port numbers are in the proper order */ + strcpy(server.sun_path,dg_stream_response->unix_path); + rsr_size = dg_stream_response->recv_buf_size; + rss_size = dg_stream_response->send_buf_size; + remote_cpu_rate = dg_stream_response->cpu_rate; + + /* We "connect" up to the remote post to allow is to use the send */ + /* call instead of the sendto call. Presumeably, this is a little */ + /* simpler, and a little more efficient. I think that it also means */ + /* that we can be informed of certain things, but am not sure yet... */ + + if (connect(data_socket, + (struct sockaddr *)&server, + sizeof(server)) == INVALID_SOCKET){ + perror("send_dg_stream: data socket connect failed"); + exit(1); + } + + /* set up the timer to call us after test_time */ + start_timer(test_time); + + /* Get the start count for the idle counter and the start time */ + + cpu_start(local_cpu_usage); + +#ifdef WANT_INTERVALS + interval_count = interval_burst; +#endif + + /* Send datagrams like there was no tomorrow. at somepoint it might */ + /* be nice to set this up so that a quantity of bytes could be sent, */ + /* but we still need some sort of end of test trigger on the receive */ + /* side. that could be a select with a one second timeout, but then */ + /* if there is a test where none of the data arrives for awile and */ + /* then starts again, we would end the test too soon. something to */ + /* think about... */ + while (!times_up) { + +#ifdef DIRTY + /* we want to dirty some number of consecutive integers in the buffer */ + /* we are about to send. we may also want to bring some number of */ + /* them cleanly into the cache. The clean ones will follow any dirty */ + /* ones into the cache. */ + message_int_ptr = (int *)(send_ring->buffer_ptr); + for (i = 0; i < loc_dirty_count; i++) { + *message_int_ptr = 4; + message_int_ptr++; + } + for (i = 0; i < loc_clean_count; i++) { + loc_dirty_count = *message_int_ptr; + message_int_ptr++; + } +#endif /* DIRTY */ + + if ((len=send(data_socket, + send_ring->buffer_ptr, + send_size, + 0)) != send_size) { + if ((len >= 0) || (errno == EINTR)) + break; + if (errno == ENOBUFS) { + failed_sends++; + continue; + } + perror("dg_send: data send error"); + exit(1); + } + messages_sent++; + + /* now we want to move our pointer to the next position in the */ + /* data buffer... */ + + send_ring = send_ring->next; + + +#ifdef WANT_INTERVALS + /* in this case, the interval count is the count-down couter */ + /* to decide to sleep for a little bit */ + if ((interval_burst) && (--interval_count == 0)) { + /* call the sleep routine for some milliseconds, if our */ + /* timer popped while we were in there, we want to */ + /* break out of the loop. */ + if (msec_sleep(interval_wate)) { + break; + } + interval_count = interval_burst; + } + +#endif + + } + + /* This is a timed test, so the remote will be returning to us after */ + /* a time. We should not need to send any "strange" messages to tell */ + /* the remote that the test is completed, unless we decide to add a */ + /* number of messages to the test. */ + + /* the test is over, so get stats and stuff */ + cpu_stop(local_cpu_usage, + &elapsed_time); + + /* Get the statistics from the remote end */ + recv_response(); + if (!netperf_response.content.serv_errno) { + if (debug) + fprintf(where,"send_dg_stream: remote results obtained\n"); + } + else { + Set_errno(netperf_response.content.serv_errno); + perror("send_dg_stream: error on remote"); + exit(1); + } + + bytes_sent = send_size * messages_sent; + local_thruput = calc_thruput(bytes_sent); + + messages_recvd = dg_stream_results->messages_recvd; + bytes_recvd = send_size * messages_recvd; + + /* we asume that the remote ran for as long as we did */ + + remote_thruput = calc_thruput(bytes_recvd); + + /* print the results for this socket and message size */ + + if (local_cpu_usage || remote_cpu_usage) { + /* We must now do a little math for service demand and cpu */ + /* utilization for the system(s) We pass zeros for the local */ + /* cpu utilization and elapsed time to tell the routine to use */ + /* the libraries own values for those. */ + if (local_cpu_usage) { + if (local_cpu_rate == 0.0) { + fprintf(where,"WARNING WARNING WARNING WARNING WARNING WARNING WARNING!\n"); + fprintf(where,"Local CPU usage numbers based on process information only!\n"); + fflush(where); + } + + local_cpu_utilization = calc_cpu_util(0.0); + local_service_demand = calc_service_demand(bytes_sent, + 0.0, + 0.0, + 0); + } + else { + local_cpu_utilization = -1.0; + local_service_demand = -1.0; + } + + /* The local calculations could use variables being kept by */ + /* the local netlib routines. The remote calcuations need to */ + /* have a few things passed to them. */ + if (remote_cpu_usage) { + if (remote_cpu_rate == 0.0) { + fprintf(where,"DANGER DANGER DANGER DANGER DANGER DANGER DANGER!\n"); + fprintf(where,"REMOTE CPU usage numbers based on process information only!\n"); + fflush(where); + } + + remote_cpu_utilization = dg_stream_results->cpu_util; + remote_service_demand = calc_service_demand(bytes_recvd, + 0.0, + remote_cpu_utilization, + dg_stream_results->num_cpus); + } + else { + remote_cpu_utilization = -1.0; + remote_service_demand = -1.0; + } + + /* We are now ready to print all the information. If the user */ + /* has specified zero-level verbosity, we will just print the */ + /* local service demand, or the remote service demand. If the */ + /* user has requested verbosity level 1, he will get the basic */ + /* "streamperf" numbers. If the user has specified a verbosity */ + /* of greater than 1, we will display a veritable plethora of */ + /* background information from outside of this block as it it */ + /* not cpu_measurement specific... */ + + switch (verbosity) { + case 0: + if (local_cpu_usage) { + fprintf(where, + cpu_fmt_0, + local_service_demand); + } + else { + fprintf(where, + cpu_fmt_0, + remote_service_demand); + } + break; + case 1: + fprintf(where, + cpu_fmt_1, /* the format string */ + lss_size, /* local sendbuf size */ + send_size, /* how large were the sends */ + elapsed_time, /* how long was the test */ + messages_sent, + failed_sends, + local_thruput, /* what was the xfer rate */ + local_cpu_utilization, /* local cpu */ + local_service_demand, /* local service demand */ + rsr_size, + elapsed_time, + messages_recvd, + remote_thruput, + remote_cpu_utilization, /* remote cpu */ + remote_service_demand); /* remote service demand */ + break; + } + } + else { + /* The tester did not wish to measure service demand. */ + switch (verbosity) { + case 0: + fprintf(where, + tput_fmt_0, + local_thruput); + break; + case 1: + fprintf(where, + tput_fmt_1, /* the format string */ + lss_size, /* local sendbuf size */ + send_size, /* how large were the sends */ + elapsed_time, /* how long did it take */ + messages_sent, + failed_sends, + local_thruput, + rsr_size, /* remote recvbuf size */ + elapsed_time, + messages_recvd, + remote_thruput + ); + break; + } + } +} + + + /* this routine implements the receive side (netserver) of the */ + /* DG_STREAM performance test. */ + +void +recv_dg_stream() +{ + struct ring_elt *recv_ring; + + struct sockaddr_un myaddr_un; + SOCKET s_data; + int len = 0; + int bytes_received = 0; + float elapsed_time; + + int message_size; + int messages_recvd = 0; + + struct dg_stream_request_struct *dg_stream_request; + struct dg_stream_response_struct *dg_stream_response; + struct dg_stream_results_struct *dg_stream_results; + + dg_stream_request = + (struct dg_stream_request_struct *)netperf_request.content.test_specific_data; + dg_stream_response = + (struct dg_stream_response_struct *)netperf_response.content.test_specific_data; + dg_stream_results = + (struct dg_stream_results_struct *)netperf_response.content.test_specific_data; + + if (debug) { + fprintf(where,"netserver: recv_dg_stream: entered...\n"); + fflush(where); + } + + /* We want to set-up the listen socket with all the desired */ + /* parameters and then let the initiator know that all is ready. If */ + /* socket size defaults are to be used, then the initiator will have */ + /* sent us 0's. If the socket sizes cannot be changed, then we will */ + /* send-back what they are. If that information cannot be determined, */ + /* then we send-back -1's for the sizes. If things go wrong for any */ + /* reason, we will drop back ten yards and punt. */ + + /* If anything goes wrong, we want the remote to know about it. It */ + /* would be best if the error that the remote reports to the user is */ + /* the actual error we encountered, rather than some bogus unexpected */ + /* response type message. */ + + if (debug > 1) { + fprintf(where,"recv_dg_stream: setting the response type...\n"); + fflush(where); + } + + netperf_response.content.response_type = DG_STREAM_RESPONSE; + + if (debug > 2) { + fprintf(where,"recv_dg_stream: the response type is set...\n"); + fflush(where); + } + + /* We now alter the message_ptr variable to be at the desired */ + /* alignment with the desired offset. */ + + if (debug > 1) { + fprintf(where,"recv_dg_stream: requested alignment of %d\n", + dg_stream_request->recv_alignment); + fflush(where); + } + + if (recv_width == 0) recv_width = 1; + + recv_ring = allocate_buffer_ring(recv_width, + dg_stream_request->message_size, + dg_stream_request->recv_alignment, + dg_stream_request->recv_offset); + + if (debug > 1) { + fprintf(where,"recv_dg_stream: receive alignment and offset set...\n"); + fflush(where); + } + + /* Let's clear-out our sockaddr for the sake of cleanlines. Then we */ + /* can put in OUR values !-) At some point, we may want to nail this */ + /* socket to a particular network-level address, but for now, */ + /* INADDR_ANY should be just fine. */ + + bzero((char *)&myaddr_un, + sizeof(myaddr_un)); + myaddr_un.sun_family = AF_UNIX; + + /* Grab a socket to listen on, and then listen on it. */ + + if (debug > 1) { + fprintf(where,"recv_dg_stream: grabbing a socket...\n"); + fflush(where); + } + + /* create_unix_socket expects to find some things in the global */ + /* variables, so set the globals based on the values in the request. */ + /* once the socket has been created, we will set the response values */ + /* based on the updated value of those globals. raj 7/94 */ + lsr_size = dg_stream_request->recv_buf_size; + + s_data = create_unix_socket(AF_UNIX, + SOCK_DGRAM); + + if (s_data == INVALID_SOCKET) { + netperf_response.content.serv_errno = errno; + send_response(); + exit(1); + } + + /* Let's get an address assigned to this socket so we can tell the */ + /* initiator how to reach the data socket. There may be a desire to */ + /* nail this socket to a specific IP address in a multi-homed, */ + /* multi-connection situation, but for now, we'll ignore the issue */ + /* and concentrate on single connection testing. */ + + strcpy(myaddr_un.sun_path,tempnam(path_prefix,"netperf.")); + if (bind(s_data, + (struct sockaddr *)&myaddr_un, + sizeof(myaddr_un)) == SOCKET_ERROR) { + netperf_response.content.serv_errno = errno; + send_response(); + exit(1); + } + + chmod(myaddr_un.sun_path, 0666); + + dg_stream_response->test_length = dg_stream_request->test_length; + + /* Now myaddr_un contains the port and the internet address this is */ + /* returned to the sender also implicitly telling the sender that the */ + /* socket buffer sizing has been done. */ + + strcpy(dg_stream_response->unix_path,myaddr_un.sun_path); + netperf_response.content.serv_errno = 0; + + /* But wait, there's more. If the initiator wanted cpu measurements, */ + /* then we must call the calibrate routine, which will return the max */ + /* rate back to the initiator. If the CPU was not to be measured, or */ + /* something went wrong with the calibration, we will return a -1 to */ + /* the initiator. */ + + dg_stream_response->cpu_rate = 0.0; /* assume no cpu */ + if (dg_stream_request->measure_cpu) { + /* We will pass the rate into the calibration routine. If the */ + /* user did not specify one, it will be 0.0, and we will do a */ + /* "real" calibration. Otherwise, all it will really do is */ + /* store it away... */ + dg_stream_response->measure_cpu = 1; + dg_stream_response->cpu_rate = + calibrate_local_cpu(dg_stream_request->cpu_rate); + } + + message_size = dg_stream_request->message_size; + test_time = dg_stream_request->test_length; + + /* before we send the response back to the initiator, pull some of */ + /* the socket parms from the globals */ + dg_stream_response->send_buf_size = lss_size; + dg_stream_response->recv_buf_size = lsr_size; + + send_response(); + + /* Now it's time to start receiving data on the connection. We will */ + /* first grab the apropriate counters and then start grabbing. */ + + cpu_start(dg_stream_request->measure_cpu); + + /* The loop will exit when the timer pops, or if we happen to recv a */ + /* message of less than send_size bytes... */ + + times_up = 0; + start_timer(test_time + PAD_TIME); + + if (debug) { + fprintf(where,"recv_dg_stream: about to enter inner sanctum.\n"); + fflush(where); + } + + while (!times_up) { + if ((len = recv(s_data, + recv_ring->buffer_ptr, + message_size, + 0)) != message_size) { + if ((len == SOCKET_ERROR) && (errno != EINTR)) { + netperf_response.content.serv_errno = errno; + send_response(); + exit(1); + } + break; + } + messages_recvd++; + recv_ring = recv_ring->next; + } + + if (debug) { + fprintf(where,"recv_dg_stream: got %d messages.\n",messages_recvd); + fflush(where); + } + + + /* The loop now exits due timer or < send_size bytes received. */ + + cpu_stop(dg_stream_request->measure_cpu,&elapsed_time); + + if (times_up) { + /* we ended on a timer, subtract the PAD_TIME */ + elapsed_time -= (float)PAD_TIME; + } + else { + stop_timer(); + } + + if (debug) { + fprintf(where,"recv_dg_stream: test ended in %f seconds.\n",elapsed_time); + fflush(where); + } + + + /* We will count the "off" message that got us out of the loop */ + bytes_received = (messages_recvd * message_size) + len; + + /* send the results to the sender */ + + if (debug) { + fprintf(where, + "recv_dg_stream: got %d bytes\n", + bytes_received); + fflush(where); + } + + netperf_response.content.response_type = DG_STREAM_RESULTS; + dg_stream_results->bytes_received = bytes_received; + dg_stream_results->messages_recvd = messages_recvd; + dg_stream_results->elapsed_time = elapsed_time; + if (dg_stream_request->measure_cpu) { + dg_stream_results->cpu_util = calc_cpu_util(elapsed_time); + } + else { + dg_stream_results->cpu_util = -1.0; + } + + if (debug > 1) { + fprintf(where, + "recv_dg_stream: test complete, sending results.\n"); + fflush(where); + } + + send_response(); + +} + +void +send_dg_rr(char remote_host[]) +{ + + char *tput_title = "\ +Local /Remote\n\ +Socket Size Request Resp. Elapsed Trans.\n\ +Send Recv Size Size Time Rate \n\ +bytes Bytes bytes bytes secs. per sec \n\n"; + + char *tput_fmt_0 = + "%7.2f\n"; + + char *tput_fmt_1_line_1 = "\ +%-6d %-6d %-6d %-6d %-6.2f %7.2f \n"; + char *tput_fmt_1_line_2 = "\ +%-6d %-6d\n"; + + char *cpu_title = "\ +Local /Remote\n\ +Socket Size Request Resp. Elapsed Trans. CPU CPU S.dem S.dem\n\ +Send Recv Size Size Time Rate local remote local remote\n\ +bytes bytes bytes bytes secs. per sec %% %% us/Tr us/Tr\n\n"; + + char *cpu_fmt_0 = + "%6.3f\n"; + + char *cpu_fmt_1_line_1 = "\ +%-6d %-6d %-6d %-6d %-6.2f %-6.2f %-6.2f %-6.2f %-6.3f %-6.3f\n"; + + char *cpu_fmt_1_line_2 = "\ +%-6d %-6d\n"; + + float elapsed_time; + + /* we add MAXALIGNMENT and MAXOFFSET to insure that there is enough */ + /* space for a maximally aligned, maximally sized message. At some */ + /* point, we may want to actually make this even larger and cycle */ + /* through the thing one piece at a time.*/ + + int len; + char *send_message_ptr; + char *recv_message_ptr; + char *temp_message_ptr; + int nummessages; + SOCKET send_socket; + int trans_remaining; + int bytes_xferd; + + int rsp_bytes_recvd; + + float local_cpu_utilization; + float local_service_demand; + float remote_cpu_utilization; + float remote_service_demand; + double thruput; + +#ifdef WANT_INTERVALS + /* timing stuff */ +#define MAX_KEPT_TIMES 1024 + int time_index = 0; + int unused_buckets; + int kept_times[MAX_KEPT_TIMES]; + int sleep_usecs; + unsigned int total_times=0; + struct timezone dummy_zone; + struct timeval send_time; + struct timeval recv_time; + struct timeval sleep_timeval; +#endif + + struct sockaddr_un server, myaddr_un; + + struct dg_rr_request_struct *dg_rr_request; + struct dg_rr_response_struct *dg_rr_response; + struct dg_rr_results_struct *dg_rr_result; + + dg_rr_request = + (struct dg_rr_request_struct *)netperf_request.content.test_specific_data; + dg_rr_response= + (struct dg_rr_response_struct *)netperf_response.content.test_specific_data; + dg_rr_result = + (struct dg_rr_results_struct *)netperf_response.content.test_specific_data; + + /* we want to zero out the times, so we can detect unused entries. */ +#ifdef WANT_INTERVALS + time_index = 0; + while (time_index < MAX_KEPT_TIMES) { + kept_times[time_index] = 0; + time_index += 1; + } + time_index = 0; +#endif + + /* since we are now disconnected from the code that established the */ + /* control socket, and since we want to be able to use different */ + /* protocols and such, we are passed the name of the remote host and */ + /* must turn that into the test specific addressing information. */ + + bzero((char *)&server, + sizeof(server)); + server.sun_family = AF_UNIX; + + bzero((char *)&myaddr_un, + sizeof(myaddr_un)); + myaddr_un.sun_family = AF_UNIX; + + strcpy(myaddr_un.sun_path,tempnam(path_prefix,"netperf.")); + + if ( print_headers ) { + fprintf(where,"DG REQUEST/RESPONSE TEST\n"); + if (local_cpu_usage || remote_cpu_usage) + fprintf(where,cpu_title,format_units()); + else + fprintf(where,tput_title,format_units()); + } + + /* initialize a few counters */ + + nummessages = 0; + bytes_xferd = 0; + times_up = 0; + + /* set-up the data buffer with the requested alignment and offset */ + temp_message_ptr = (char *)malloc(DATABUFFERLEN); + if (temp_message_ptr == NULL) { + printf("malloc(%d) failed!\n", DATABUFFERLEN); + exit(1); + } + send_message_ptr = (char *)(( (long)temp_message_ptr + + (long) local_send_align - 1) & + ~((long) local_send_align - 1)); + send_message_ptr = send_message_ptr + local_send_offset; + temp_message_ptr = (char *)malloc(DATABUFFERLEN); + if (temp_message_ptr == NULL) { + printf("malloc(%d) failed!\n", DATABUFFERLEN); + exit(1); + } + recv_message_ptr = (char *)(( (long)temp_message_ptr + + (long) local_recv_align - 1) & + ~((long) local_recv_align - 1)); + recv_message_ptr = recv_message_ptr + local_recv_offset; + + /*set up the data socket */ + send_socket = create_unix_socket(AF_UNIX, + SOCK_DGRAM); + + if (send_socket == INVALID_SOCKET){ + perror("netperf: send_dg_rr: dg rr data socket"); + exit(1); + } + + if (debug) { + fprintf(where,"send_dg_rr: send_socket obtained...\n"); + } + + + /* If the user has requested cpu utilization measurements, we must */ + /* calibrate the cpu(s). We will perform this task within the tests */ + /* themselves. If the user has specified the cpu rate, then */ + /* calibrate_local_cpu will return rather quickly as it will have */ + /* nothing to do. If local_cpu_rate is zero, then we will go through */ + /* all the "normal" calibration stuff and return the rate back. If */ + /* there is no idle counter in the kernel idle loop, the */ + /* local_cpu_rate will be set to -1. */ + + if (local_cpu_usage) { + local_cpu_rate = calibrate_local_cpu(local_cpu_rate); + } + + /* Tell the remote end to do a listen. The server alters the socket */ + /* paramters on the other side at this point, hence the reason for */ + /* all the values being passed in the setup message. If the user did */ + /* not specify any of the parameters, they will be passed as 0, which */ + /* will indicate to the remote that no changes beyond the system's */ + /* default should be used. Alignment is the exception, it will */ + /* default to 8, which will be no alignment alterations. */ + + netperf_request.content.request_type = DO_DG_RR; + dg_rr_request->recv_buf_size = rsr_size; + dg_rr_request->send_buf_size = rss_size; + dg_rr_request->recv_alignment = remote_recv_align; + dg_rr_request->recv_offset = remote_recv_offset; + dg_rr_request->send_alignment = remote_send_align; + dg_rr_request->send_offset = remote_send_offset; + dg_rr_request->request_size = req_size; + dg_rr_request->response_size = rsp_size; + dg_rr_request->measure_cpu = remote_cpu_usage; + dg_rr_request->cpu_rate = remote_cpu_rate; + if (test_time) { + dg_rr_request->test_length = test_time; + } + else { + dg_rr_request->test_length = test_trans * -1; + } + + if (debug > 1) { + fprintf(where,"netperf: send_dg_rr: requesting DG request/response test\n"); + } + + send_request(); + + /* The response from the remote will contain all of the relevant */ + /* socket parameters for this test type. We will put them back into */ + /* the variables here so they can be displayed if desired. The */ + /* remote will have calibrated CPU if necessary, and will have done */ + /* all the needed set-up we will have calibrated the cpu locally */ + /* before sending the request, and will grab the counter value right */ + /* after the connect returns. The remote will grab the counter right */ + /* after the accept call. This saves the hassle of extra messages */ + /* being sent for the DG tests. */ + + recv_response(); + + if (!netperf_response.content.serv_errno) { + if (debug) + fprintf(where,"remote listen done.\n"); + rsr_size = dg_rr_response->recv_buf_size; + rss_size = dg_rr_response->send_buf_size; + remote_cpu_usage= dg_rr_response->measure_cpu; + remote_cpu_rate = dg_rr_response->cpu_rate; + /* port numbers in proper order */ + strcpy(server.sun_path,dg_rr_response->unix_path); + } + else { + Set_errno(netperf_response.content.serv_errno); + perror("netperf: remote error"); + + exit(1); + } + + /* Connect up to the remote port on the data socket. This will set */ + /* the default destination address on this socket. we need to bind */ + /* out socket so that the remote gets something from a recvfrom */ + if (bind(send_socket, + (struct sockaddr *)&myaddr_un, + sizeof(myaddr_un)) == SOCKET_ERROR) { + perror("netperf: send_dg_rr"); + unlink(myaddr_un.sun_path); + close(send_socket); + exit(1); + } + + if (connect(send_socket, + (struct sockaddr *)&server, + sizeof(server)) == INVALID_SOCKET ) { + perror("netperf: data socket connect failed"); + exit(1); + } + + /* Data Socket set-up is finished. If there were problems, either the */ + /* connect would have failed, or the previous response would have */ + /* indicated a problem. I failed to see the value of the extra */ + /* message after the accept on the remote. If it failed, we'll see it */ + /* here. If it didn't, we might as well start pumping data. */ + + /* Set-up the test end conditions. For a request/response test, they */ + /* can be either time or transaction based. */ + + if (test_time) { + /* The user wanted to end the test after a period of time. */ + times_up = 0; + trans_remaining = 0; + start_timer(test_time); + } + else { + /* The tester wanted to send a number of bytes. */ + trans_remaining = test_bytes; + times_up = 1; + } + + /* The cpu_start routine will grab the current time and possibly */ + /* value of the idle counter for later use in measuring cpu */ + /* utilization and/or service demand and thruput. */ + + cpu_start(local_cpu_usage); + + /* We use an "OR" to control test execution. When the test is */ + /* controlled by time, the byte count check will always return false. */ + /* When the test is controlled by byte count, the time test will */ + /* always return false. When the test is finished, the whole */ + /* expression will go false and we will stop sending data. I think I */ + /* just arbitrarily decrement trans_remaining for the timed test, but */ + /* will not do that just yet... One other question is whether or not */ + /* the send buffer and the receive buffer should be the same buffer. */ + while ((!times_up) || (trans_remaining > 0)) { + /* send the request */ +#ifdef WANT_INTERVALS + gettimeofday(&send_time,&dummy_zone); +#endif + if((len=send(send_socket, + send_message_ptr, + req_size, + 0)) != req_size) { + if (errno == EINTR) { + /* We likely hit */ + /* test-end time. */ + break; + } + perror("send_dg_rr: data send error"); + exit(1); + } + + /* receive the response. with DG we will get it all, or nothing */ + + if((rsp_bytes_recvd=recv(send_socket, + recv_message_ptr, + rsp_size, + 0)) != rsp_size) { + if (errno == EINTR) { + /* Again, we have likely hit test-end time */ + break; + } + perror("send_dg_rr: data recv error"); + exit(1); + } +#ifdef WANT_INTERVALS + gettimeofday(&recv_time,&dummy_zone); + + /* now we do some arithmatic on the two timevals */ + if (recv_time.tv_usec < send_time.tv_usec) { + /* we wrapped around a second */ + recv_time.tv_usec += 1000000; + recv_time.tv_sec -= 1; + } + + /* and store it away */ + kept_times[time_index] = (recv_time.tv_sec - send_time.tv_sec) * 1000000; + kept_times[time_index] += (recv_time.tv_usec - send_time.tv_usec); + + /* at this point, we may wish to sleep for some period of */ + /* time, so we see how long that last transaction just took, */ + /* and sleep for the difference of that and the interval. We */ + /* will not sleep if the time would be less than a */ + /* millisecond. */ + if (interval_usecs > 0) { + sleep_usecs = interval_usecs - kept_times[time_index]; + if (sleep_usecs > 1000) { + /* we sleep */ + sleep_timeval.tv_sec = sleep_usecs / 1000000; + sleep_timeval.tv_usec = sleep_usecs % 1000000; + select(0, + 0, + 0, + 0, + &sleep_timeval); + } + } + + /* now up the time index */ + time_index = (time_index +1)%MAX_KEPT_TIMES; +#endif + nummessages++; + if (trans_remaining) { + trans_remaining--; + } + + if (debug > 3) { + fprintf(where,"Transaction %d completed\n",nummessages); + fflush(where); + } + + } + + /* The test is over. Flush the buffers to the remote end. We do a */ + /* graceful release to insure that all data has been taken by the */ + /* remote. Of course, since this was a request/response test, there */ + /* should be no data outstanding on the socket ;-) */ + + if (shutdown(send_socket,1) == SOCKET_ERROR) { + perror("netperf: cannot shutdown dg stream socket"); + + exit(1); + } + + /* this call will always give us the elapsed time for the test, and */ + /* will also store-away the necessaries for cpu utilization */ + + cpu_stop(local_cpu_usage,&elapsed_time); /* was cpu being measured? */ + /* how long did we really run? */ + + /* Get the statistics from the remote end. The remote will have */ + /* calculated service demand and all those interesting things. If it */ + /* wasn't supposed to care, it will return obvious values. */ + + recv_response(); + if (!netperf_response.content.serv_errno) { + if (debug) + fprintf(where,"remote results obtained\n"); + } + else { + Set_errno(netperf_response.content.serv_errno); + perror("netperf: remote error"); + + exit(1); + } + + /* We now calculate what our thruput was for the test. In the future, */ + /* we may want to include a calculation of the thruput measured by */ + /* the remote, but it should be the case that for a DG stream test, */ + /* that the two numbers should be *very* close... We calculate */ + /* bytes_sent regardless of the way the test length was controlled. */ + /* If it was time, we needed to, and if it was by bytes, the user may */ + /* have specified a number of bytes that wasn't a multiple of the */ + /* send_size, so we really didn't send what he asked for ;-) We use */ + + bytes_xferd = (req_size * nummessages) + (rsp_size * nummessages); + thruput = calc_thruput(bytes_xferd); + + if (local_cpu_usage || remote_cpu_usage) { + /* We must now do a little math for service demand and cpu */ + /* utilization for the system(s) */ + /* Of course, some of the information might be bogus because */ + /* there was no idle counter in the kernel(s). We need to make */ + /* a note of this for the user's benefit...*/ + if (local_cpu_usage) { + if (local_cpu_rate == 0.0) { + fprintf(where,"WARNING WARNING WARNING WARNING WARNING WARNING WARNING!\n"); + fprintf(where,"Local CPU usage numbers based on process information only!\n"); + fflush(where); + } + local_cpu_utilization = calc_cpu_util(0.0); + /* since calc_service demand is doing ms/Kunit we will */ + /* multiply the number of transaction by 1024 to get */ + /* "good" numbers */ + local_service_demand = calc_service_demand((double) nummessages*1024, + 0.0, + 0.0, + 0); + } + else { + local_cpu_utilization = -1.0; + local_service_demand = -1.0; + } + + if (remote_cpu_usage) { + if (remote_cpu_rate == 0.0) { + fprintf(where,"DANGER DANGER DANGER DANGER DANGER DANGER DANGER!\n"); + fprintf(where,"Remote CPU usage numbers based on process information only!\n"); + fflush(where); + } + remote_cpu_utilization = dg_rr_result->cpu_util; + /* since calc_service demand is doing ms/Kunit we will */ + /* multiply the number of transaction by 1024 to get */ + /* "good" numbers */ + remote_service_demand = calc_service_demand((double) nummessages*1024, + 0.0, + remote_cpu_utilization, + dg_rr_result->num_cpus); + } + else { + remote_cpu_utilization = -1.0; + remote_service_demand = -1.0; + } + + /* We are now ready to print all the information. If the user */ + /* has specified zero-level verbosity, we will just print the */ + /* local service demand, or the remote service demand. If the */ + /* user has requested verbosity level 1, he will get the basic */ + /* "streamperf" numbers. If the user has specified a verbosity */ + /* of greater than 1, we will display a veritable plethora of */ + /* background information from outside of this block as it it */ + /* not cpu_measurement specific... */ + + switch (verbosity) { + case 0: + if (local_cpu_usage) { + fprintf(where, + cpu_fmt_0, + local_service_demand); + } + else { + fprintf(where, + cpu_fmt_0, + remote_service_demand); + } + break; + case 1: + case 2: + fprintf(where, + cpu_fmt_1_line_1, /* the format string */ + lss_size, /* local sendbuf size */ + lsr_size, + req_size, /* how large were the requests */ + rsp_size, /* guess */ + elapsed_time, /* how long was the test */ + nummessages/elapsed_time, + local_cpu_utilization, /* local cpu */ + remote_cpu_utilization, /* remote cpu */ + local_service_demand, /* local service demand */ + remote_service_demand); /* remote service demand */ + fprintf(where, + cpu_fmt_1_line_2, + rss_size, + rsr_size); + break; + } + } + else { + /* The tester did not wish to measure service demand. */ + switch (verbosity) { + case 0: + fprintf(where, + tput_fmt_0, + nummessages/elapsed_time); + break; + case 1: + case 2: + fprintf(where, + tput_fmt_1_line_1, /* the format string */ + lss_size, + lsr_size, + req_size, /* how large were the requests */ + rsp_size, /* how large were the responses */ + elapsed_time, /* how long did it take */ + nummessages/elapsed_time); + fprintf(where, + tput_fmt_1_line_2, + rss_size, /* remote recvbuf size */ + rsr_size); + + break; + } + } + + /* it would be a good thing to include information about some of the */ + /* other parameters that may have been set for this test, but at the */ + /* moment, I do not wish to figure-out all the formatting, so I will */ + /* just put this comment here to help remind me that it is something */ + /* that should be done at a later time. */ + + if (verbosity > 1) { + /* The user wanted to know it all, so we will give it to him. */ + /* This information will include as much as we can find about */ + /* DG statistics, the alignments of the sends and receives */ + /* and all that sort of rot... */ + +#ifdef WANT_INTERVALS + kept_times[MAX_KEPT_TIMES] = 0; + time_index = 0; + while (time_index < MAX_KEPT_TIMES) { + if (kept_times[time_index] > 0) { + total_times += kept_times[time_index]; + } + else + unused_buckets++; + time_index += 1; + } + total_times /= (MAX_KEPT_TIMES-unused_buckets); + fprintf(where, + "Average response time %d usecs\n", + total_times); +#endif + } + unlink(myaddr_un.sun_path); +} + + /* this routine implements the receive side (netserver) of a DG_RR */ + /* test. */ +void +recv_dg_rr() +{ + + struct ring_elt *recv_ring; + struct ring_elt *send_ring; + + struct sockaddr_un myaddr_un, + peeraddr_un; + SOCKET s_data; + int addrlen; + int trans_received = 0; + int trans_remaining; + float elapsed_time; + + struct dg_rr_request_struct *dg_rr_request; + struct dg_rr_response_struct *dg_rr_response; + struct dg_rr_results_struct *dg_rr_results; + + dg_rr_request = + (struct dg_rr_request_struct *)netperf_request.content.test_specific_data; + dg_rr_response = + (struct dg_rr_response_struct *)netperf_response.content.test_specific_data; + dg_rr_results = + (struct dg_rr_results_struct *)netperf_response.content.test_specific_data; + + if (debug) { + fprintf(where,"netserver: recv_dg_rr: entered...\n"); + fflush(where); + } + + /* We want to set-up the listen socket with all the desired */ + /* parameters and then let the initiator know that all is ready. If */ + /* socket size defaults are to be used, then the initiator will have */ + /* sent us 0's. If the socket sizes cannot be changed, then we will */ + /* send-back what they are. If that information cannot be determined, */ + /* then we send-back -1's for the sizes. If things go wrong for any */ + /* reason, we will drop back ten yards and punt. */ + + /* If anything goes wrong, we want the remote to know about it. It */ + /* would be best if the error that the remote reports to the user is */ + /* the actual error we encountered, rather than some bogus unexpected */ + /* response type message. */ + + if (debug) { + fprintf(where,"recv_dg_rr: setting the response type...\n"); + fflush(where); + } + + netperf_response.content.response_type = DG_RR_RESPONSE; + + if (debug) { + fprintf(where,"recv_dg_rr: the response type is set...\n"); + fflush(where); + } + + /* We now alter the message_ptr variables to be at the desired */ + /* alignments with the desired offsets. */ + + if (debug) { + fprintf(where,"recv_dg_rr: requested recv alignment of %d offset %d\n", + dg_rr_request->recv_alignment, + dg_rr_request->recv_offset); + fprintf(where,"recv_dg_rr: requested send alignment of %d offset %d\n", + dg_rr_request->send_alignment, + dg_rr_request->send_offset); + fflush(where); + } + + if (send_width == 0) send_width = 1; + if (recv_width == 0) recv_width = 1; + + recv_ring = allocate_buffer_ring(recv_width, + dg_rr_request->request_size, + dg_rr_request->recv_alignment, + dg_rr_request->recv_offset); + + send_ring = allocate_buffer_ring(send_width, + dg_rr_request->response_size, + dg_rr_request->send_alignment, + dg_rr_request->send_offset); + + if (debug) { + fprintf(where,"recv_dg_rr: receive alignment and offset set...\n"); + fflush(where); + } + + /* Let's clear-out our sockaddr for the sake of cleanlines. Then we */ + /* can put in OUR values !-) At some point, we may want to nail this */ + /* socket to a particular network-level address, but for now, */ + /* INADDR_ANY should be just fine. */ + + bzero((char *)&myaddr_un, + sizeof(myaddr_un)); + myaddr_un.sun_family = AF_UNIX; + + /* Grab a socket to listen on, and then listen on it. */ + + if (debug) { + fprintf(where,"recv_dg_rr: grabbing a socket...\n"); + fflush(where); + } + + + /* create_unix_socket expects to find some things in the global */ + /* variables, so set the globals based on the values in the request. */ + /* once the socket has been created, we will set the response values */ + /* based on the updated value of those globals. raj 7/94 */ + lss_size_req = dg_rr_request->send_buf_size; + lsr_size_req = dg_rr_request->recv_buf_size; + + s_data = create_unix_socket(AF_UNIX, + SOCK_DGRAM); + + if (s_data == INVALID_SOCKET) { + netperf_response.content.serv_errno = errno; + send_response(); + + exit(1); + } + + /* Let's get an address assigned to this socket so we can tell the */ + /* initiator how to reach the data socket. There may be a desire to */ + /* nail this socket to a specific IP address in a multi-homed, */ + /* multi-connection situation, but for now, we'll ignore the issue */ + /* and concentrate on single connection testing. */ + + strcpy(myaddr_un.sun_path,tempnam(path_prefix,"netperf.")); + if (bind(s_data, + (struct sockaddr *)&myaddr_un, + sizeof(myaddr_un)) == SOCKET_ERROR) { + netperf_response.content.serv_errno = errno; + unlink(myaddr_un.sun_path); + close(s_data); + send_response(); + + exit(1); + } + + /* Now myaddr_un contains the port and the internet address this is */ + /* returned to the sender also implicitly telling the sender that the */ + /* socket buffer sizing has been done. */ + + strcpy(dg_rr_response->unix_path,myaddr_un.sun_path); + netperf_response.content.serv_errno = 0; + + /* But wait, there's more. If the initiator wanted cpu measurements, */ + /* then we must call the calibrate routine, which will return the max */ + /* rate back to the initiator. If the CPU was not to be measured, or */ + /* something went wrong with the calibration, we will return a 0.0 to */ + /* the initiator. */ + + dg_rr_response->cpu_rate = 0.0; /* assume no cpu */ + if (dg_rr_request->measure_cpu) { + dg_rr_response->measure_cpu = 1; + dg_rr_response->cpu_rate = calibrate_local_cpu(dg_rr_request->cpu_rate); + } + + /* before we send the response back to the initiator, pull some of */ + /* the socket parms from the globals */ + dg_rr_response->send_buf_size = lss_size; + dg_rr_response->recv_buf_size = lsr_size; + + send_response(); + + + /* Now it's time to start receiving data on the connection. We will */ + /* first grab the apropriate counters and then start grabbing. */ + + cpu_start(dg_rr_request->measure_cpu); + + if (dg_rr_request->test_length > 0) { + times_up = 0; + trans_remaining = 0; + start_timer(dg_rr_request->test_length + PAD_TIME); + } + else { + times_up = 1; + trans_remaining = dg_rr_request->test_length * -1; + } + + addrlen = sizeof(peeraddr_un); + bzero((char *)&peeraddr_un, addrlen); + + while ((!times_up) || (trans_remaining > 0)) { + + /* receive the request from the other side */ + fprintf(where,"socket %d ptr %p size %d\n", + s_data, + recv_ring->buffer_ptr, + dg_rr_request->request_size); + fflush(where); + if (recvfrom(s_data, + recv_ring->buffer_ptr, + dg_rr_request->request_size, + 0, + (struct sockaddr *)&peeraddr_un, + &addrlen) != dg_rr_request->request_size) { + if (errno == EINTR) { + /* we must have hit the end of test time. */ + break; + } + netperf_response.content.serv_errno = errno; + fprintf(where,"error on recvfrom errno %d\n",errno); + fflush(where); + send_response(); + unlink(myaddr_un.sun_path); + exit(1); + } + recv_ring = recv_ring->next; + + /* Now, send the response to the remote */ + if (sendto(s_data, + send_ring->buffer_ptr, + dg_rr_request->response_size, + 0, + (struct sockaddr *)&peeraddr_un, + addrlen) != dg_rr_request->response_size) { + if (errno == EINTR) { + /* we have hit end of test time. */ + break; + } + netperf_response.content.serv_errno = errno; + fprintf(where,"error on recvfrom errno %d\n",errno); + fflush(where); + unlink(myaddr_un.sun_path); + send_response(); + exit(1); + } + send_ring = send_ring->next; + + trans_received++; + if (trans_remaining) { + trans_remaining--; + } + + if (debug) { + fprintf(where, + "recv_dg_rr: Transaction %d complete.\n", + trans_received); + fflush(where); + } + + } + + + /* The loop now exits due to timeout or transaction count being */ + /* reached */ + + cpu_stop(dg_rr_request->measure_cpu,&elapsed_time); + + if (times_up) { + /* we ended the test by time, which was at least 2 seconds */ + /* longer than we wanted to run. so, we want to subtract */ + /* PAD_TIME from the elapsed_time. */ + elapsed_time -= PAD_TIME; + } + /* send the results to the sender */ + + if (debug) { + fprintf(where, + "recv_dg_rr: got %d transactions\n", + trans_received); + fflush(where); + } + + dg_rr_results->bytes_received = (trans_received * + (dg_rr_request->request_size + + dg_rr_request->response_size)); + dg_rr_results->trans_received = trans_received; + dg_rr_results->elapsed_time = elapsed_time; + if (dg_rr_request->measure_cpu) { + dg_rr_results->cpu_util = calc_cpu_util(elapsed_time); + } + + if (debug) { + fprintf(where, + "recv_dg_rr: test complete, sending results.\n"); + fflush(where); + } + + send_response(); + unlink(myaddr_un.sun_path); + +} + /* this routine implements the receive (netserver) side of a STREAM_RR */ + /* test */ + +void +recv_stream_rr() +{ + + struct ring_elt *send_ring; + struct ring_elt *recv_ring; + + struct sockaddr_un myaddr_un, + peeraddr_un; + SOCKET s_listen,s_data; + int addrlen; + char *temp_message_ptr; + int trans_received = 0; + int trans_remaining; + int bytes_sent; + int request_bytes_recvd; + int request_bytes_remaining; + int timed_out = 0; + float elapsed_time; + + struct stream_rr_request_struct *stream_rr_request; + struct stream_rr_response_struct *stream_rr_response; + struct stream_rr_results_struct *stream_rr_results; + + stream_rr_request = + (struct stream_rr_request_struct *)netperf_request.content.test_specific_data; + stream_rr_response = + (struct stream_rr_response_struct *)netperf_response.content.test_specific_data; + stream_rr_results = + (struct stream_rr_results_struct *)netperf_response.content.test_specific_data; + + if (debug) { + fprintf(where,"netserver: recv_stream_rr: entered...\n"); + fflush(where); + } + + /* We want to set-up the listen socket with all the desired */ + /* parameters and then let the initiator know that all is ready. If */ + /* socket size defaults are to be used, then the initiator will have */ + /* sent us 0's. If the socket sizes cannot be changed, then we will */ + /* send-back what they are. If that information cannot be determined, */ + /* then we send-back -1's for the sizes. If things go wrong for any */ + /* reason, we will drop back ten yards and punt. */ + + /* If anything goes wrong, we want the remote to know about it. It */ + /* would be best if the error that the remote reports to the user is */ + /* the actual error we encountered, rather than some bogus unexpected */ + /* response type message. */ + + if (debug) { + fprintf(where,"recv_stream_rr: setting the response type...\n"); + fflush(where); + } + + netperf_response.content.response_type = STREAM_RR_RESPONSE; + + if (debug) { + fprintf(where,"recv_stream_rr: the response type is set...\n"); + fflush(where); + } + + /* allocate the recv and send rings with the requested alignments */ + /* and offsets. raj 7/94 */ + if (debug) { + fprintf(where,"recv_stream_rr: requested recv alignment of %d offset %d\n", + stream_rr_request->recv_alignment, + stream_rr_request->recv_offset); + fprintf(where,"recv_stream_rr: requested send alignment of %d offset %d\n", + stream_rr_request->send_alignment, + stream_rr_request->send_offset); + fflush(where); + } + + /* at some point, these need to come to us from the remote system */ + if (send_width == 0) send_width = 1; + if (recv_width == 0) recv_width = 1; + + send_ring = allocate_buffer_ring(send_width, + stream_rr_request->response_size, + stream_rr_request->send_alignment, + stream_rr_request->send_offset); + + recv_ring = allocate_buffer_ring(recv_width, + stream_rr_request->request_size, + stream_rr_request->recv_alignment, + stream_rr_request->recv_offset); + + + /* Let's clear-out our sockaddr for the sake of cleanlines. Then we */ + /* can put in OUR values !-) At some point, we may want to nail this */ + /* socket to a particular network-level address, but for now, */ + /* INADDR_ANY should be just fine. */ + + bzero((char *)&myaddr_un, + sizeof(myaddr_un)); + myaddr_un.sun_family = AF_UNIX; + + /* Grab a socket to listen on, and then listen on it. */ + + if (debug) { + fprintf(where,"recv_stream_rr: grabbing a socket...\n"); + fflush(where); + } + + /* create_unix_socket expects to find some things in the global */ + /* variables, so set the globals based on the values in the request. */ + /* once the socket has been created, we will set the response values */ + /* based on the updated value of those globals. raj 7/94 */ + lss_size_req = stream_rr_request->send_buf_size; + lsr_size_req = stream_rr_request->recv_buf_size; + + s_listen = create_unix_socket(AF_UNIX, + SOCK_STREAM); + + if (s_listen == INVALID_SOCKET) { + netperf_response.content.serv_errno = errno; + send_response(); + + exit(1); + } + + /* Let's get an address assigned to this socket so we can tell the */ + /* initiator how to reach the data socket. There may be a desire to */ + /* nail this socket to a specific IP address in a multi-homed, */ + /* multi-connection situation, but for now, we'll ignore the issue */ + /* and concentrate on single connection testing. */ + + strcpy(myaddr_un.sun_path,tempnam(path_prefix,"netperf.")); + if (bind(s_listen, + (struct sockaddr *)&myaddr_un, + sizeof(myaddr_un)) == SOCKET_ERROR) { + netperf_response.content.serv_errno = errno; + unlink(myaddr_un.sun_path); + close(s_listen); + send_response(); + + exit(1); + } + + /* Now, let's set-up the socket to listen for connections */ + if (listen(s_listen, 5) == SOCKET_ERROR) { + netperf_response.content.serv_errno = errno; + close(s_listen); + send_response(); + + exit(1); + } + + /* Now myaddr_un contains the port and the internet address this is */ + /* returned to the sender also implicitly telling the sender that the */ + /* socket buffer sizing has been done. */ + + strcpy(stream_rr_response->unix_path,myaddr_un.sun_path); + netperf_response.content.serv_errno = 0; + + /* But wait, there's more. If the initiator wanted cpu measurements, */ + /* then we must call the calibrate routine, which will return the max */ + /* rate back to the initiator. If the CPU was not to be measured, or */ + /* something went wrong with the calibration, we will return a 0.0 to */ + /* the initiator. */ + + stream_rr_response->cpu_rate = 0.0; /* assume no cpu */ + if (stream_rr_request->measure_cpu) { + stream_rr_response->measure_cpu = 1; + stream_rr_response->cpu_rate = calibrate_local_cpu(stream_rr_request->cpu_rate); + } + + + /* before we send the response back to the initiator, pull some of */ + /* the socket parms from the globals */ + stream_rr_response->send_buf_size = lss_size; + stream_rr_response->recv_buf_size = lsr_size; + + send_response(); + + addrlen = sizeof(peeraddr_un); + + if ((s_data = accept(s_listen, + (struct sockaddr *)&peeraddr_un, + &addrlen)) == INVALID_SOCKET) { + /* Let's just punt. The remote will be given some information */ + close(s_listen); + + exit(1); + } + + if (debug) { + fprintf(where,"recv_stream_rr: accept completes on the data connection.\n"); + fflush(where); + } + + /* Now it's time to start receiving data on the connection. We will */ + /* first grab the apropriate counters and then start grabbing. */ + + cpu_start(stream_rr_request->measure_cpu); + + /* The loop will exit when the sender does a shutdown, which will */ + /* return a length of zero */ + + if (stream_rr_request->test_length > 0) { + times_up = 0; + trans_remaining = 0; + start_timer(stream_rr_request->test_length + PAD_TIME); + } + else { + times_up = 1; + trans_remaining = stream_rr_request->test_length * -1; + } + + while ((!times_up) || (trans_remaining > 0)) { + temp_message_ptr = recv_ring->buffer_ptr; + request_bytes_remaining = stream_rr_request->request_size; + + /* receive the request from the other side */ + if (debug) { + fprintf(where,"about to receive for trans %d\n",trans_received); + fprintf(where,"temp_message_ptr is %p\n",temp_message_ptr); + fflush(where); + } + while(request_bytes_remaining > 0) { + if((request_bytes_recvd=recv(s_data, + temp_message_ptr, + request_bytes_remaining, + 0)) == SOCKET_ERROR) { + if (errno == EINTR) { + /* the timer popped */ + timed_out = 1; + break; + } + netperf_response.content.serv_errno = errno; + send_response(); + exit(1); + } + else { + request_bytes_remaining -= request_bytes_recvd; + temp_message_ptr += request_bytes_recvd; + } + if (debug) { + fprintf(where,"just received for trans %d\n",trans_received); + fflush(where); + } + } + + recv_ring = recv_ring->next; + + if (timed_out) { + /* we hit the end of the test based on time - lets */ + /* bail out of here now... */ + fprintf(where,"yo5\n"); + fflush(where); + break; + } + + /* Now, send the response to the remote */ + if (debug) { + fprintf(where,"about to send for trans %d\n",trans_received); + fflush(where); + } + if((bytes_sent=send(s_data, + send_ring->buffer_ptr, + stream_rr_request->response_size, + 0)) == SOCKET_ERROR) { + if (errno == EINTR) { + /* the test timer has popped */ + timed_out = 1; + fprintf(where,"yo6\n"); + fflush(where); + break; + } + netperf_response.content.serv_errno = 997; + send_response(); + exit(1); + } + + send_ring = send_ring->next; + + trans_received++; + if (trans_remaining) { + trans_remaining--; + } + + if (debug) { + fprintf(where, + "recv_stream_rr: Transaction %d complete\n", + trans_received); + fflush(where); + } + } + + + /* The loop now exits due to timeout or transaction count being */ + /* reached */ + + cpu_stop(stream_rr_request->measure_cpu,&elapsed_time); + + if (timed_out) { + /* we ended the test by time, which was at least 2 seconds */ + /* longer than we wanted to run. so, we want to subtract */ + /* PAD_TIME from the elapsed_time. */ + elapsed_time -= PAD_TIME; + } + /* send the results to the sender */ + + if (debug) { + fprintf(where, + "recv_stream_rr: got %d transactions\n", + trans_received); + fflush(where); + } + + stream_rr_results->bytes_received = (trans_received * + (stream_rr_request->request_size + + stream_rr_request->response_size)); + stream_rr_results->trans_received = trans_received; + stream_rr_results->elapsed_time = elapsed_time; + if (stream_rr_request->measure_cpu) { + stream_rr_results->cpu_util = calc_cpu_util(elapsed_time); + } + + if (debug) { + fprintf(where, + "recv_stream_rr: test complete, sending results.\n"); + fflush(where); + } + + send_response(); + unlink(myaddr_un.sun_path); +} + +void +print_unix_usage() +{ + + fwrite(unix_usage, sizeof(char), strlen(unix_usage), stdout); + exit(1); + +} +void +scan_unix_args(int argc, char *argv[]) +{ +#define UNIX_ARGS "hm:M:p:r:s:S:" + extern char *optarg; /* pointer to option string */ + + int c; + + char + arg1[BUFSIZ], /* argument holders */ + arg2[BUFSIZ]; + + init_test_vars(); + + if (no_control) { + fprintf(where, + "The UNIX tests do not know how to run with no control connection\n"); + exit(-1); + } + + /* Go through all the command line arguments and break them */ + /* out. For those options that take two parms, specifying only */ + /* the first will set both to that value. Specifying only the */ + /* second will leave the first untouched. To change only the */ + /* first, use the form "first," (see the routine break_args.. */ + + while ((c= getopt(argc, argv, UNIX_ARGS)) != EOF) { + switch (c) { + case '?': + case 'h': + print_unix_usage(); + exit(1); + case 'p': + /* set the path prefix (directory) that should be used for the */ + /* pipes. at some point, there should be some error checking. */ + strcpy(path_prefix,optarg); + break; + case 's': + /* set local socket sizes */ + break_args(optarg,arg1,arg2); + if (arg1[0]) + lss_size_req = atoi(arg1); + if (arg2[0]) + lsr_size_req = atoi(arg2); + break; + case 'S': + /* set remote socket sizes */ + break_args(optarg,arg1,arg2); + if (arg1[0]) + rss_size = atoi(arg1); + if (arg2[0]) + rsr_size = atoi(arg2); + break; + case 'r': + /* set the request/response sizes */ + break_args(optarg,arg1,arg2); + if (arg1[0]) + req_size = atoi(arg1); + if (arg2[0]) + rsp_size = atoi(arg2); + break; + case 'm': + /* set the send size */ + send_size = atoi(optarg); + break; + case 'M': + /* set the recv size */ + recv_size = atoi(optarg); + break; + }; + } +} +#endif /* WANT_UNIX */ diff --git a/src/nettest_unix.h b/src/nettest_unix.h new file mode 100644 index 0000000..8eb393b --- /dev/null +++ b/src/nettest_unix.h @@ -0,0 +1,198 @@ +/* + Copyright (C) 1993-2004 Hewlett-Packard Company +*/ + + /* This file contains the test-specific definitions for netperf's */ + /* DLPI tests */ + +struct stream_stream_request_struct { + int recv_buf_size; + int send_buf_size; + int receive_size; /* how many bytes do we want to */ + /* receive at one time? */ + int recv_alignment; /* what is the alignment of the */ + /* receive buffer? */ + int recv_offset; /* and at what offset from that */ + /* alignment? */ + int so_rcvavoid; /* do we want the remote to avoid receive copies? */ + int so_sndavoid; /* do we want the remote to avoid send copies? */ + int measure_cpu; /* does the client want server cpu */ + /* utilization measured? */ + float cpu_rate; /* do we know how fast the cpu is */ + /* already? */ + int test_length; /* how long is the test? */ + int dirty_count; /* how many integers in the receive buffer */ + /* should be made dirty before calling recv? */ + int clean_count; /* how many integers should be read from the */ + /* recv buffer before calling recv? */ + int path_name_len; /* the length of the device name string. this */ + /* is used to put it into the proper order on */ + /* @#$% byte-swapped boxes... */ + char unix_path[32]; /* the path */ +}; + +struct stream_stream_response_struct { + int recv_buf_size; /* how big does the client want it */ + int send_buf_size; + int receive_size; + int so_rcvavoid; /* do we want the remote to avoid receive copies? */ + int so_sndavoid; /* do we want the remote to avoid send copies? */ + int measure_cpu; /* does the client want server cpu */ + int test_length; /* how long is the test? */ + int data_port_number; /* connect to me here */ + float cpu_rate; /* could we measure */ + int path_name_len; /* the length of the device name string. this */ + /* is used to put it into the proper order on */ + /* @#$% byte-swapped boxes... */ + char unix_path[32]; /* the path */ +}; + +struct stream_stream_results_struct { + int bytes_received; /* ignored initially */ + int recv_calls; /* ignored initially */ + float elapsed_time; /* how long the test ran */ + float cpu_util; /* -1 if not measured */ + float serv_dem; /* -1 if not measured */ + int num_cpus; +}; + +struct stream_rr_request_struct { + int recv_buf_size; /* how big does the client want it */ + int send_buf_size; + int recv_alignment; + int recv_offset; + int send_alignment; + int send_offset; + int request_size; + int response_size; + int so_rcvavoid; /* do we want the remote to avoid receive copies? */ + int so_sndavoid; /* do we want the remote to avoid send copies? */ + int measure_cpu; /* does the client want server cpu */ + float cpu_rate; /* do we know how fast the cpu is? */ + int test_length; /* how long is the test? */ + int path_name_len; /* the length of the device name string. this */ + /* is used to put it into the proper order on */ + /* @#$% byte-swapped boxes... */ + char unix_path[32]; /* the path */ +}; + +struct stream_rr_response_struct { + int recv_buf_size; /* how big does the client want it */ + int send_buf_size; + int so_rcvavoid; /* do we want the remote to avoid receive copies? */ + int so_sndavoid; /* do we want the remote to avoid send copies? */ + int measure_cpu; /* does the client want server cpu */ + int test_length; /* how long is the test? */ + float cpu_rate; /* could we measure */ + int path_name_len; /* the length of the device name string. this */ + /* is used to put it into the proper order on */ + /* @#$% byte-swapped boxes... */ + char unix_path[32]; /* the path to the dlpi device */ +}; + +struct stream_rr_results_struct { + int bytes_received; /* ignored initially */ + int recv_calls; /* ignored initially */ + int trans_received; /* not ignored */ + float elapsed_time; /* how long the test ran */ + float cpu_util; /* -1 if not measured */ + float serv_dem; /* -1 if not measured */ + int num_cpus; +}; + +struct dg_stream_request_struct { + int recv_buf_size; + int message_size; + int recv_alignment; + int recv_offset; + int measure_cpu; + float cpu_rate; + int test_length; + int so_rcvavoid; /* do we want the remote to avoid receive copies? */ + int so_sndavoid; /* do we want the remote to avoid send copies? */ + int path_name_len; /* the length of the device name string. this */ + /* is used to put it into the proper order on */ + /* @#$% byte-swapped boxes... */ + char unix_path[32]; /* the path */ +}; + +struct dg_stream_response_struct { + int recv_buf_size; + int send_buf_size; + int measure_cpu; + int test_length; + float cpu_rate; + int so_rcvavoid; /* could the remote avoid receive copies? */ + int so_sndavoid; /* could the remote avoid send copies? */ + int path_name_len; /* the length of the device name string. this */ + /* is used to put it into the proper order on */ + /* @#$% byte-swapped boxes... */ + char unix_path[32]; /* the path */ +}; + +struct dg_stream_results_struct { + int messages_recvd; + int bytes_received; + float elapsed_time; + float cpu_util; + int num_cpus; +}; + + +struct dg_rr_request_struct { + int recv_buf_size; /* how big does the client want it */ + int send_buf_size; + int recv_alignment; + int recv_offset; + int send_alignment; + int send_offset; + int request_size; + int response_size; + int measure_cpu; /* does the client want server cpu */ + float cpu_rate; /* do we know how fast the cpu is? */ + int test_length; /* how long is the test? */ + int so_rcvavoid; /* do we want the remote to avoid receive */ + /* copies? */ + int so_sndavoid; /* do we want the remote to avoid send copies? */ + int path_name_len; /* the length of the device name string. this */ + /* is used to put it into the proper order on */ + /* @#$% byte-swapped boxes... */ + char unix_path[32]; /* the path */ +}; + +struct dg_rr_response_struct { + int recv_buf_size; /* how big does the client want it */ + int send_buf_size; + int no_delay; + int measure_cpu; /* does the client want server cpu */ + int test_length; /* how long is the test? */ + float cpu_rate; /* could we measure */ + int so_rcvavoid; /* could the remote avoid receive copies? */ + int so_sndavoid; /* could the remote avoid send copies? */ + int path_name_len; /* the length of the device name string. this */ + /* is used to put it into the proper order on */ + /* @#$% byte-swapped boxes... */ + char unix_path[32]; /* the path */ +}; + +struct dg_rr_results_struct { + int bytes_received; /* ignored initially */ + int recv_calls; /* ignored initially */ + int trans_received; /* not ignored */ + float elapsed_time; /* how long the test ran */ + float cpu_util; /* -1 if not measured */ + float serv_dem; /* -1 if not measured */ + int num_cpus; +}; + +extern void scan_unix_args(int argc, char *argv[]); + +extern void send_stream_stream(char remote_host[]); +extern void send_stream_rr(char remote_host[]); +extern void send_dg_stream(char remote_host[]); +extern void send_dg_rr(char remote_host[]); + +extern void recv_stream_stream(); +extern void recv_stream_rr(); +extern void recv_dg_stream(); +extern void recv_dg_rr(); diff --git a/src/nettest_xti.c b/src/nettest_xti.c new file mode 100644 index 0000000..95291eb --- /dev/null +++ b/src/nettest_xti.c @@ -0,0 +1,6025 @@ +#ifdef HAVE_CONFIG_H +#include +#endif + +#ifdef WANT_XTI +#ifndef lint +char nettest_xti_id[]="\ +@(#)nettest_xti.c (c) Copyright 1995-2008 Hewlett-Packard Co. Version 2.4.5"; +#else +#define DIRTY +#define WANT_HISTOGRAM +#define WANT_INTERVALS +#endif /* lint */ + +#ifdef WIN32 +#error XTI Interface tests are not available under Windows +#endif + +/****************************************************************/ +/* */ +/* nettest_xti.c */ +/* */ +/* the XTI args parsing routine... */ +/* */ +/* scan_xti_args() */ +/* */ +/* the actual test routines... */ +/* */ +/* send_xti_tcp_stream() perform a tcp stream test */ +/* recv_xti_tcp_stream() */ +/* send_xti_tcp_rr() perform a tcp request/response */ +/* recv_xti_tcp_rr() */ +/* send_xti_tcp_conn_rr() an RR test including connect */ +/* recv_xti_tcp_conn_rr() */ +/* send_xti_udp_stream() perform a udp stream test */ +/* recv_xti_udp_stream() */ +/* send_xti_udp_rr() perform a udp request/response */ +/* recv_xti_udp_rr() */ +/* */ +/****************************************************************/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + /* xti.h should be included *after* in.h because there are name */ + /* conflicts!( Silly standards people... raj 2/95 fortuenately, the */ + /* confilcts are on IP_TOP and IP_TTL, whcih netperf does not yet use */ +#include + +#include "netlib.h" +#include "netsh.h" +#include "nettest_xti.h" + +#ifdef WANT_HISTOGRAM +#ifdef __sgi +#include +#endif /* __sgi */ +#include "hist.h" +#endif /* WANT_HISTOGRAM */ + + + + /* these variables are specific to the XTI sockets tests. declare */ + /* them static to make them global only to this file. */ + +static int + rss_size, /* remote socket send buffer size */ + rsr_size, /* remote socket recv buffer size */ + lss_size, /* local socket send buffer size */ + lsr_size, /* local socket recv buffer size */ + req_size = 1, /* request size */ + rsp_size = 1, /* response size */ + send_size, /* how big are individual sends */ + recv_size; /* how big are individual receives */ + +static int confidence_iteration; +static char local_cpu_method; +static char remote_cpu_method; + + /* different options for the xti */ + +static int + loc_nodelay, /* don't/do use NODELAY locally */ + rem_nodelay, /* don't/do use NODELAY remotely */ + loc_sndavoid, /* avoid send copies locally */ + loc_rcvavoid, /* avoid recv copies locally */ + rem_sndavoid, /* avoid send copies remotely */ + rem_rcvavoid; /* avoid recv_copies remotely */ + +static struct t_info info_struct; + +#ifdef WANT_HISTOGRAM +#ifdef HAVE_GETHRTIME +hrtime_t time_one; +hrtime_t time_two; +#else +static struct timeval time_one; +static struct timeval time_two; +#endif /* HAVE_GETHRTIME */ +static HIST time_hist; +#endif /* WANT_HISTOGRAM */ + +static char loc_xti_device[32] = "/dev/tcp"; +static char rem_xti_device[32] = "/dev/tcp"; + +static int xti_flags = 0; + +char xti_usage[] = "\n\ +Usage: netperf [global options] -- [test options] \n\ +\n\ +TCP/UDP XTI API Test Options:\n\ + -D [L][,R] Set XTI_TCP_NODELAY locally and/or remotely (XTI_TCP_*)\n\ + -h Display this text\n\ + -m bytes Set the send size (XTI_TCP_STREAM, XTI_UDP_STREAM)\n\ + -M bytes Set the recv size (XTI_TCP_STREAM, XTI_UDP_STREAM)\n\ + -r bytes Set request size (XTI_TCP_RR, XTI_UDP_RR)\n\ + -R bytes Set response size (XTI_TCP_RR, XTI_UDP_RR)\n\ + -s send[,recv] Set local socket send/recv buffer sizes\n\ + -S send[,recv] Set remote socket send/recv buffer sizes\n\ + -X dev[,dev] Set the local/remote XTI device file name\n\ +\n\ +For those options taking two parms, at least one must be specified;\n\ +specifying one value without a comma will set both parms to that\n\ +value, specifying a value with a leading comma will set just the second\n\ +parm, a value with a trailing comma will set just the first. To set\n\ +each parm to unique values, specify both and separate them with a\n\ +comma.\n"; + + + /* This routine is intended to retrieve interesting aspects of tcp */ + /* for the data connection. at first, it attempts to retrieve the */ + /* maximum segment size. later, it might be modified to retrieve */ + /* other information, but it must be information that can be */ + /* retrieved quickly as it is called during the timing of the test. */ + /* for that reason, a second routine may be created that can be */ + /* called outside of the timing loop */ +void +get_xti_info(socket, info_struct) + int socket; + struct t_info *info_struct; +{ + +} + + + /* This routine will create a data (listen) socket with the apropriate */ + /* options set and return it to the caller. this replaces all the */ + /* duplicate code in each of the test routines and should help make */ + /* things a little easier to understand. since this routine can be */ + /* called by either the netperf or netserver programs, all output */ + /* should be directed towards "where." family is generally AF_INET, */ + /* and type will be either SOCK_STREAM or SOCK_DGRAM */ +SOCKET +create_xti_endpoint(char *name) +{ + + SOCKET temp_socket; + + struct t_optmgmt *opt_req; /* we request an option */ + struct t_optmgmt *opt_ret; /* it tells us what we got */ + + /* we use this to pass-in BSD-like socket options through t_optmgmt. */ + /* it ends up being about as clear as mud. raj 2/95 */ + struct sock_option { + struct t_opthdr myopthdr; + long value; + } *sock_option; + + if (debug) { + fprintf(where,"create_xti_endpoint: attempting to open %s\n", + name); + fflush(where); + } + + /*set up the data socket */ + temp_socket = t_open(name,O_RDWR,NULL); + + if (temp_socket == INVALID_SOCKET){ + fprintf(where, + "netperf: create_xti_endpoint: t_open %s: errno %d t_errno %d\n", + name, + errno, + t_errno); + fflush(where); + exit(1); + } + + if (debug) { + fprintf(where,"create_xti_endpoint: socket %d obtained...\n",temp_socket); + fflush(where); + } + + /* allocate what we need for option mgmt */ + if ((opt_req = (struct t_optmgmt *)t_alloc(temp_socket,T_OPTMGMT,T_ALL)) == + NULL) { + fprintf(where, + "netperf: create_xti_endpoint: t_alloc: opt_req errno %d\n", + errno); + fflush(where); + exit(1); + } + + if (debug) { + fprintf(where, + "create_xti_endpoint: opt_req->opt.buf %x maxlen %d len %d\n", + opt_req->opt.buf, + opt_req->opt.maxlen, + opt_req->opt.len); + + fflush(where); + } + + if ((opt_ret = (struct t_optmgmt *) t_alloc(temp_socket,T_OPTMGMT,T_ALL)) == + NULL) { + fprintf(where, + "netperf: create_xti_endpoint: t_alloc: opt_ret errno %d\n", + errno); + fflush(where); + exit(1); + } + + if (debug) { + fprintf(where, + "create_xti_endpoint: opt_ret->opt.buf %x maxlen %d len %d\n", + opt_ret->opt.buf, + opt_ret->opt.maxlen, + opt_ret->opt.len); + fflush(where); + } + + /* Modify the local socket size. The reason we alter the send buffer */ + /* size here rather than when the connection is made is to take care */ + /* of decreases in buffer size. Decreasing the window size after */ + /* connection establishment is a TCP no-no. Also, by setting the */ + /* buffer (window) size before the connection is established, we can */ + /* control the TCP MSS (segment size). The MSS is never more that 1/2 */ + /* the minimum receive buffer size at each half of the connection. */ + /* This is why we are altering the receive buffer size on the sending */ + /* size of a unidirectional transfer. If the user has not requested */ + /* that the socket buffers be altered, we will try to find-out what */ + /* their values are. If we cannot touch the socket buffer in any way, */ + /* we will set the values to -1 to indicate that. */ + +#ifdef XTI_SNDBUF + if (lss_size > 0) { + /* we want to "negotiate" the option */ + opt_req->flags = T_NEGOTIATE; + } + else { + /* we want to accept the default, and know what it is. I assume */ + /* that when nothing has been changed, that T_CURRENT will return */ + /* the same as T_DEFAULT raj 3/95 */ + opt_req->flags = T_CURRENT; + } + + /* the first part is for the netbuf that holds the option we want */ + /* to negotiate or check */ + /* the buffer of the netbuf points at the socket options structure */ + + /* we assume that the t_alloc call allocated a buffer that started */ + /* on a proper alignment */ + sock_option = (struct sock_option *)opt_req->opt.buf; + + /* and next, set the fields in the sock_option structure */ + sock_option->myopthdr.level = XTI_GENERIC; + sock_option->myopthdr.name = XTI_SNDBUF; + sock_option->myopthdr.len = sizeof(struct t_opthdr) + sizeof(long); + sock_option->value = lss_size; + + opt_req->opt.len = sizeof(struct t_opthdr) + sizeof(long); + + /* now, set-up the stuff to return the value in the end */ + /* we assume that the t_alloc call allocated a buffer that started */ + /* on a proper alignment */ + sock_option = (struct sock_option *)opt_ret->opt.buf; + + /* finally, call t_optmgmt. clear as mud. */ + if (t_optmgmt(temp_socket,opt_req,opt_ret) == -1) { + fprintf(where, + "netperf: create_xti_endpoint: XTI_SNDBUF option: t_errno %d\n", + t_errno); + fflush(where); + exit(1); + } + + if (sock_option->myopthdr.status == T_SUCCESS) { + lss_size = sock_option->value; + } + else { + fprintf(where,"create_xti_endpoint: XTI_SNDBUF option status 0x%.4x", + sock_option->myopthdr.status); + fprintf(where," value %d\n", + sock_option->value); + fflush(where); + lss_size = -1; + } + + if (lsr_size > 0) { + /* we want to "negotiate" the option */ + opt_req->flags = T_NEGOTIATE; + } + else { + /* we want to accept the default, and know what it is. I assume */ + /* that when nothing has been changed, that T_CURRENT will return */ + /* the same as T_DEFAULT raj 3/95 */ + opt_req->flags = T_CURRENT; + } + + /* the first part is for the netbuf that holds the option we want */ + /* to negotiate or check */ + /* the buffer of the netbuf points at the socket options structure */ + + /* we assume that the t_alloc call allocated a buffer that started */ + /* on a proper alignment */ + sock_option = (struct sock_option *)opt_req->opt.buf; + + /* and next, set the fields in the sock_option structure */ + sock_option->myopthdr.level = XTI_GENERIC; + sock_option->myopthdr.name = XTI_RCVBUF; + sock_option->myopthdr.len = sizeof(struct t_opthdr) + sizeof(long); + sock_option->value = lsr_size; + + opt_req->opt.len = sizeof(struct t_opthdr) + sizeof(long); + + /* now, set-up the stuff to return the value in the end */ + /* we assume that the t_alloc call allocated a buffer that started */ + /* on a proper alignment */ + sock_option = (struct sock_option *)opt_ret->opt.buf; + + /* finally, call t_optmgmt. clear as mud. */ + if (t_optmgmt(temp_socket,opt_req,opt_ret) == -1) { + fprintf(where, + "netperf: create_xti_endpoint: XTI_RCVBUF option: t_errno %d\n", + t_errno); + fflush(where); + exit(1); + } + lsr_size = sock_option->value; + + /* this needs code */ + + if (debug) { + fprintf(where,"netperf: create_xti_endpoint: socket sizes determined...\n"); + fprintf(where," send: %d recv: %d\n", + lss_size,lsr_size); + fflush(where); + } + +#else /* XTI_SNDBUF */ + + lss_size = -1; + lsr_size = -1; + +#endif /* XTI_SNDBUF */ + + /* now, we may wish to enable the copy avoidance features on the */ + /* local system. of course, this may not be possible... */ + + if (loc_rcvavoid) { + fprintf(where, + "netperf: create_xti_endpoint: Could not enable receive copy avoidance"); + fflush(where); + loc_rcvavoid = 0; + } + + if (loc_sndavoid) { + fprintf(where, + "netperf: create_xti_endpoint: Could not enable send copy avoidance"); + fflush(where); + loc_sndavoid = 0; + } + + /* Now, we will see about setting the TCP_NODELAY flag on the local */ + /* socket. We will only do this for those systems that actually */ + /* support the option. If it fails, note the fact, but keep going. */ + /* If the user tries to enable TCP_NODELAY on a UDP socket, this */ + /* will cause an error to be displayed */ + +#ifdef TCP_NODELAY + if ((strcmp(test_name,"XTI_TCP_STREAM") == 0) || + (strcmp(test_name,"XTI_TCP_RR") == 0) || + (strcmp(test_name,"XTI_TCP_CRR") == 0)) { + if (loc_nodelay) { + /* we want to "negotiate" the option */ + opt_req->flags = T_NEGOTIATE; + } + else { + /* we want to accept the default, and know what it is. I assume */ + /* that when nothing has been changed, that T_CURRENT will return */ + /* the same as T_DEFAULT raj 3/95 */ + opt_req->flags = T_CURRENT; + } + + /* the first part is for the netbuf that holds the option we want */ + /* to negotiate or check the buffer of the netbuf points at the */ + /* socket options structure */ + + /* we assume that the t_alloc call allocated a buffer that started */ + /* on a proper alignment */ + sock_option = (struct sock_option *)opt_req->opt.buf; + + /* and next, set the fields in the sock_option structure */ + sock_option->myopthdr.level = INET_TCP; + sock_option->myopthdr.name = TCP_NODELAY; + sock_option->myopthdr.len = sizeof(struct t_opthdr) + sizeof(long); + sock_option->value = T_YES; + + opt_req->opt.len = sizeof(struct t_opthdr) + sizeof(long); + + /* now, set-up the stuff to return the value in the end */ + /* we assume that the t_alloc call allocated a buffer that started */ + /* on a proper alignment */ + sock_option = (struct sock_option *)opt_ret->opt.buf; + + /* finally, call t_optmgmt. clear as mud. */ + if (t_optmgmt(temp_socket,opt_req,opt_ret) == -1) { + fprintf(where, + "create_xti_endpoint: TCP_NODELAY option: errno %d t_errno %d\n", + errno, + t_errno); + fflush(where); + exit(1); + } + loc_nodelay = sock_option->value; + } +#else /* TCP_NODELAY */ + + loc_nodelay = 0; + +#endif /* TCP_NODELAY */ + + return(temp_socket); + +} + + +/* This routine implements the TCP unidirectional data transfer test */ +/* (a.k.a. stream) for the xti interface. It receives its */ +/* parameters via global variables from the shell and writes its */ +/* output to the standard output. */ + + +void +send_xti_tcp_stream(char remote_host[]) +{ + + char *tput_title = "\ +Recv Send Send \n\ +Socket Socket Message Elapsed \n\ +Size Size Size Time Throughput \n\ +bytes bytes bytes secs. %s/sec \n\n"; + + char *tput_fmt_0 = + "%7.2f\n"; + + char *tput_fmt_1 = + "%6d %6d %6d %-6.2f %7.2f \n"; + + char *cpu_title = "\ +Recv Send Send Utilization Service Demand\n\ +Socket Socket Message Elapsed Send Recv Send Recv\n\ +Size Size Size Time Throughput local remote local remote\n\ +bytes bytes bytes secs. %-8.8s/s %% %c %% %c us/KB us/KB\n\n"; + + char *cpu_fmt_0 = + "%6.3f %c\n"; + + char *cpu_fmt_1 = + "%6d %6d %6d %-6.2f %7.2f %-6.2f %-6.2f %-6.3f %-6.3f\n"; + + char *ksink_fmt = "\n\ +Alignment Offset %-8.8s %-8.8s Sends %-8.8s Recvs\n\ +Local Remote Local Remote Xfered Per Per\n\ +Send Recv Send Recv Send (avg) Recv (avg)\n\ +%5d %5d %5d %5d %6.4g %6.2f %6d %6.2f %6d\n"; + + char *ksink_fmt2 = "\n\ +Maximum\n\ +Segment\n\ +Size (bytes)\n\ +%6d\n"; + + + float elapsed_time; + +#ifdef WANT_INTERVALS + int interval_count; + sigset_t signal_set; +#endif + + /* what we want is to have a buffer space that is at least one */ + /* send-size greater than our send window. this will insure that we */ + /* are never trying to re-use a buffer that may still be in the hands */ + /* of the transport. This buffer will be malloc'd after we have found */ + /* the size of the local senc socket buffer. We will want to deal */ + /* with alignment and offset concerns as well. */ + + int *message_int_ptr; + + struct ring_elt *send_ring; + + int len; + unsigned int nummessages; + SOCKET send_socket; + int bytes_remaining; + int tcp_mss = -1; /* possibly uninitialized on printf far below */ + + /* with links like fddi, one can send > 32 bits worth of bytes */ + /* during a test... ;-) at some point, this should probably become a */ + /* 64bit integral type, but those are not entirely common yet */ + + double bytes_sent; + + float local_cpu_utilization; + float local_service_demand; + float remote_cpu_utilization; + float remote_service_demand; + + double thruput; + + /* some addressing information */ + struct hostent *hp; + struct sockaddr_in server; + unsigned int addr; + + struct t_call server_call; + + struct xti_tcp_stream_request_struct *xti_tcp_stream_request; + struct xti_tcp_stream_response_struct *xti_tcp_stream_response; + struct xti_tcp_stream_results_struct *xti_tcp_stream_result; + + xti_tcp_stream_request = + (struct xti_tcp_stream_request_struct *)netperf_request.content.test_specific_data; + xti_tcp_stream_response = + (struct xti_tcp_stream_response_struct *)netperf_response.content.test_specific_data; + xti_tcp_stream_result = + (struct xti_tcp_stream_results_struct *)netperf_response.content.test_specific_data; + +#ifdef WANT_HISTOGRAM + time_hist = HIST_new(); +#endif /* WANT_HISTOGRAM */ + /* since we are now disconnected from the code that established the */ + /* control socket, and since we want to be able to use different */ + /* protocols and such, we are passed the name of the remote host and */ + /* must turn that into the test specific addressing information. */ + + bzero((char *)&server, + sizeof(server)); + + /* it would seem that while HP-UX will allow an IP address (as a */ + /* string) in a call to gethostbyname, other, less enlightened */ + /* systems do not. fix from awjacks@ca.sandia.gov raj 10/95 */ + /* order changed to check for IP address first. raj 7/96 */ + + if ((addr = inet_addr(remote_host)) == SOCKET_ERROR) { + /* it was not an IP address, try it as a name */ + if ((hp = gethostbyname(remote_host)) == NULL) { + /* we have no idea what it is */ + fprintf(where, + "establish_control: could not resolve the destination %s\n", + remote_host); + fflush(where); + exit(1); + } + else { + /* it was a valid remote_host */ + bcopy(hp->h_addr, + (char *)&server.sin_addr, + hp->h_length); + server.sin_family = hp->h_addrtype; + } + } + else { + /* it was a valid IP address */ + server.sin_addr.s_addr = addr; + server.sin_family = AF_INET; + } + + if ( print_headers ) { + /* we want to have some additional, interesting information in */ + /* the headers. we know some of it here, but not all, so we will */ + /* only print the test title here and will print the results */ + /* titles after the test is finished */ + fprintf(where,"XTI TCP STREAM TEST"); + fprintf(where," to %s", remote_host); + if (iteration_max > 1) { + fprintf(where, + " : +/-%3.1f%% @ %2d%% conf.", + interval/0.02, + confidence_level); + } + if (loc_nodelay || rem_nodelay) { + fprintf(where," : nodelay"); + } + if (loc_sndavoid || + loc_rcvavoid || + rem_sndavoid || + rem_rcvavoid) { + fprintf(where," : copy avoidance"); + } +#ifdef WANT_HISTOGRAM + fprintf(where," : histogram"); +#endif /* WANT_HISTOGRAM */ +#ifdef WANT_INTERVALS + fprintf(where," : interval"); +#endif /* WANT_INTERVALS */ +#ifdef DIRTY + fprintf(where," : dirty data"); +#endif /* DIRTY */ + fprintf(where,"\n"); + } + + send_ring = NULL; + confidence_iteration = 1; + init_stat(); + + /* we have a great-big while loop which controls the number of times */ + /* we run a particular test. this is for the calculation of a */ + /* confidence interval (I really should have stayed awake during */ + /* probstats :). If the user did not request confidence measurement */ + /* (no confidence is the default) then we will only go though the */ + /* loop once. the confidence stuff originates from the folks at IBM */ + + while (((confidence < 0) && (confidence_iteration < iteration_max)) || + (confidence_iteration <= iteration_min)) { + + /* initialize a few counters. we have to remember that we might be */ + /* going through the loop more than once. */ + + nummessages = 0; + bytes_sent = 0.0; + times_up = 0; + + /*set up the data socket */ + send_socket = create_xti_endpoint(loc_xti_device); + + if (send_socket == INVALID_SOCKET) { + perror("netperf: send_xti_tcp_stream: tcp stream data socket"); + exit(1); + } + + if (debug) { + fprintf(where,"send_xti_tcp_stream: send_socket obtained...\n"); + } + + /* it would seem that with XTI, there is no implicit bind on a */ + /* connect, so we have to make a call to t_bind. this is not */ + /* terribly convenient, but I suppose that "standard is better */ + /* than better" :) raj 2/95 */ + + if (t_bind(send_socket, NULL, NULL) == SOCKET_ERROR) { + t_error("send_xti_tcp_stream: t_bind"); + exit(1); + } + + /* at this point, we have either retrieved the socket buffer sizes, */ + /* or have tried to set them, so now, we may want to set the send */ + /* size based on that (because the user either did not use a -m */ + /* option, or used one with an argument of 0). If the socket buffer */ + /* size is not available, we will set the send size to 4KB - no */ + /* particular reason, just arbitrary... */ + if (send_size == 0) { + if (lss_size > 0) { + send_size = lss_size; + } + else { + send_size = 4096; + } + } + + /* set-up the data buffer ring with the requested alignment and offset. */ + /* note also that we have allocated a quantity */ + /* of memory that is at least one send-size greater than our socket */ + /* buffer size. We want to be sure that there are at least two */ + /* buffers allocated - this can be a bit of a problem when the */ + /* send_size is bigger than the socket size, so we must check... the */ + /* user may have wanted to explicitly set the "width" of our send */ + /* buffers, we should respect that wish... */ + + if (send_width == 0) { + send_width = (lss_size/send_size) + 1; + if (send_width == 1) send_width++; + } + + if (send_ring == NULL) { + /* only allocate the send ring once. this is a networking test, */ + /* not a memory allocation test. this way, we do not need a */ + /* deallocate_buffer_ring() routine, and I don't feel like */ + /* writing one anyway :) raj 11/94 */ + send_ring = allocate_buffer_ring(send_width, + send_size, + local_send_align, + local_send_offset); + } + + /* If the user has requested cpu utilization measurements, we must */ + /* calibrate the cpu(s). We will perform this task within the tests */ + /* themselves. If the user has specified the cpu rate, then */ + /* calibrate_local_cpu will return rather quickly as it will have */ + /* nothing to do. If local_cpu_rate is zero, then we will go through */ + /* all the "normal" calibration stuff and return the rate back. */ + + if (local_cpu_usage) { + local_cpu_rate = calibrate_local_cpu(local_cpu_rate); + } + + /* Tell the remote end to do a listen. The server alters the socket */ + /* paramters on the other side at this point, hence the reason for */ + /* all the values being passed in the setup message. If the user did */ + /* not specify any of the parameters, they will be passed as 0, which */ + /* will indicate to the remote that no changes beyond the system's */ + /* default should be used. Alignment is the exception, it will */ + /* default to 1, which will be no alignment alterations. */ + + netperf_request.content.request_type = DO_XTI_TCP_STREAM; + xti_tcp_stream_request->send_buf_size = rss_size; + xti_tcp_stream_request->recv_buf_size = rsr_size; + xti_tcp_stream_request->receive_size = recv_size; + xti_tcp_stream_request->no_delay = rem_nodelay; + xti_tcp_stream_request->recv_alignment = remote_recv_align; + xti_tcp_stream_request->recv_offset = remote_recv_offset; + xti_tcp_stream_request->measure_cpu = remote_cpu_usage; + xti_tcp_stream_request->cpu_rate = remote_cpu_rate; + if (test_time) { + xti_tcp_stream_request->test_length = test_time; + } + else { + xti_tcp_stream_request->test_length = test_bytes; + } + xti_tcp_stream_request->so_rcvavoid = rem_rcvavoid; + xti_tcp_stream_request->so_sndavoid = rem_sndavoid; + + strcpy(xti_tcp_stream_request->xti_device, rem_xti_device); + +#ifdef __alpha + + /* ok - even on a DEC box, strings are strings. I didn't really want */ + /* to ntohl the words of a string. since I don't want to teach the */ + /* send_ and recv_ _request and _response routines about the types, */ + /* I will put "anti-ntohl" calls here. I imagine that the "pure" */ + /* solution would be to use XDR, but I am still leary of being able */ + /* to find XDR libs on all platforms I want running netperf. raj */ + { + int *charword; + int *initword; + int *lastword; + + initword = (int *) xti_tcp_stream_request->xti_device; + lastword = initword + ((strlen(rem_xti_device) + 3) / 4); + + for (charword = initword; + charword < lastword; + charword++) { + + *charword = ntohl(*charword); + } + } +#endif /* __alpha */ + +#ifdef DIRTY + xti_tcp_stream_request->dirty_count = rem_dirty_count; + xti_tcp_stream_request->clean_count = rem_clean_count; +#endif /* DIRTY */ + + + if (debug > 1) { + fprintf(where, + "netperf: send_xti_tcp_stream: requesting TCP stream test\n"); + } + + send_request(); + + /* The response from the remote will contain all of the relevant */ + /* socket parameters for this test type. We will put them back into */ + /* the variables here so they can be displayed if desired. The */ + /* remote will have calibrated CPU if necessary, and will have done */ + /* all the needed set-up we will have calibrated the cpu locally */ + /* before sending the request, and will grab the counter value right*/ + /* after the connect returns. The remote will grab the counter right*/ + /* after the accept call. This saves the hassle of extra messages */ + /* being sent for the TCP tests. */ + + recv_response(); + + if (!netperf_response.content.serv_errno) { + if (debug) + fprintf(where,"remote listen done.\n"); + rsr_size = xti_tcp_stream_response->recv_buf_size; + rss_size = xti_tcp_stream_response->send_buf_size; + rem_nodelay = xti_tcp_stream_response->no_delay; + remote_cpu_usage = xti_tcp_stream_response->measure_cpu; + remote_cpu_rate = xti_tcp_stream_response->cpu_rate; + + /* we have to make sure that the server port number is in */ + /* network order */ + server.sin_port = (short)xti_tcp_stream_response->data_port_number; + server.sin_port = htons(server.sin_port); + rem_rcvavoid = xti_tcp_stream_response->so_rcvavoid; + rem_sndavoid = xti_tcp_stream_response->so_sndavoid; + } + else { + Set_errno(netperf_response.content.serv_errno); + perror("netperf: remote error"); + + exit(1); + } + + /*Connect up to the remote port on the data socket */ + memset (&server_call, 0, sizeof(server_call)); + server_call.addr.maxlen = sizeof(struct sockaddr_in); + server_call.addr.len = sizeof(struct sockaddr_in); + server_call.addr.buf = (char *)&server; + + if (t_connect(send_socket, + &server_call, + NULL) == INVALID_SOCKET){ + t_error("netperf: send_xti_tcp_stream: data socket connect failed"); + printf(" port: %d\n",ntohs(server.sin_port)); + exit(1); + } + + /* Data Socket set-up is finished. If there were problems, either */ + /* the connect would have failed, or the previous response would */ + /* have indicated a problem. I failed to see the value of the */ + /* extra message after the accept on the remote. If it failed, */ + /* we'll see it here. If it didn't, we might as well start pumping */ + /* data. */ + + /* Set-up the test end conditions. For a stream test, they can be */ + /* either time or byte-count based. */ + + if (test_time) { + /* The user wanted to end the test after a period of time. */ + times_up = 0; + bytes_remaining = 0; + /* in previous revisions, we had the same code repeated throught */ + /* all the test suites. this was unnecessary, and meant more */ + /* work for me when I wanted to switch to POSIX signals, so I */ + /* have abstracted this out into a routine in netlib.c. if you */ + /* are experiencing signal problems, you might want to look */ + /* there. raj 11/94 */ + start_timer(test_time); + } + else { + /* The tester wanted to send a number of bytes. */ + bytes_remaining = test_bytes; + times_up = 1; + } + + /* The cpu_start routine will grab the current time and possibly */ + /* value of the idle counter for later use in measuring cpu */ + /* utilization and/or service demand and thruput. */ + + cpu_start(local_cpu_usage); + +#ifdef WANT_INTERVALS + if ((interval_burst) || (demo_mode)) { + /* zero means that we never pause, so we never should need the */ + /* interval timer, unless we are in demo_mode */ + start_itimer(interval_wate); + } + interval_count = interval_burst; + /* get the signal set for the call to sigsuspend */ + if (sigprocmask(SIG_BLOCK, (sigset_t *)NULL, &signal_set) != 0) { + fprintf(where, + "send_xti_tcp_stream: unable to get sigmask errno %d\n", + errno); + fflush(where); + exit(1); + } +#endif /* WANT_INTERVALS */ + + /* before we start, initialize a few variables */ + + /* We use an "OR" to control test execution. When the test is */ + /* controlled by time, the byte count check will always return false. */ + /* When the test is controlled by byte count, the time test will */ + /* always return false. When the test is finished, the whole */ + /* expression will go false and we will stop sending data. */ + + while ((!times_up) || (bytes_remaining > 0)) { + +#ifdef DIRTY + /* we want to dirty some number of consecutive integers in the buffer */ + /* we are about to send. we may also want to bring some number of */ + /* them cleanly into the cache. The clean ones will follow any dirty */ + /* ones into the cache. at some point, we might want to replace */ + /* the rand() call with something from a table to reduce our call */ + /* overhead during the test, but it is not a high priority item. */ + access_buffer(send_ring->buffer_ptr, + send_size, + loc_dirty_count, + loc_clean_count); +#endif /* DIRTY */ + +#ifdef WANT_HISTOGRAM + /* timestamp just before we go into send and then again just after */ + /* we come out raj 8/94 */ + HIST_timestamp(&time_one); +#endif /* WANT_HISTOGRAM */ + + if((len=t_snd(send_socket, + send_ring->buffer_ptr, + send_size, + 0)) != send_size) { + if ((len >=0) || (errno == EINTR)) { + /* the test was interrupted, must be the end of test */ + break; + } + fprintf(where, + "send_xti_tcp_stream: t_snd: errno %d t_errno %d t_look 0x%.4x\n", + errno, + t_errno, + t_look(send_socket)); + fflush(where); + exit(1); + } + +#ifdef WANT_HISTOGRAM + /* timestamp the exit from the send call and update the histogram */ + HIST_timestamp(&time_two); + HIST_add(time_hist,delta_micro(&time_one,&time_two)); +#endif /* WANT_HISTOGRAM */ + +#ifdef WANT_INTERVALS + if (demo_mode) { + units_this_tick += send_size; + } + /* in this case, the interval count is the count-down couter */ + /* to decide to sleep for a little bit */ + if ((interval_burst) && (--interval_count == 0)) { + /* call sigsuspend and wait for the interval timer to get us */ + /* out */ + if (debug) { + fprintf(where,"about to suspend\n"); + fflush(where); + } + if (sigsuspend(&signal_set) == EFAULT) { + fprintf(where, + "send_xti_tcp_stream: fault with signal set!\n"); + fflush(where); + exit(1); + } + interval_count = interval_burst; + } +#endif /* WANT_INTERVALS */ + + /* now we want to move our pointer to the next position in the */ + /* data buffer...we may also want to wrap back to the "beginning" */ + /* of the bufferspace, so we will mod the number of messages sent */ + /* by the send width, and use that to calculate the offset to add */ + /* to the base pointer. */ + nummessages++; + send_ring = send_ring->next; + if (bytes_remaining) { + bytes_remaining -= send_size; + } + } + + /* The test is over. Flush the buffers to the remote end. We do a */ + /* graceful release to insure that all data has been taken by the */ + /* remote. */ + + /* but first, if the verbosity is greater than 1, find-out what */ + /* the TCP maximum segment_size was (if possible) */ + if (verbosity > 1) { + tcp_mss = -1; + get_xti_info(send_socket,info_struct); + } + + if (t_sndrel(send_socket) == -1) { + t_error("netperf: cannot shutdown tcp stream socket"); + exit(1); + } + + /* hang a t_rcvrel() off the socket to block until the remote has */ + /* brought all the data up into the application. it will do a */ + /* t_sedrel to cause a FIN to be sent our way. We will assume that */ + /* any exit from the t_rcvrel() call is good... raj 2/95 */ + + if (debug > 1) { + fprintf(where,"about to hang a receive for graceful release.\n"); + fflush(where); + } + + t_rcvrel(send_socket); + + /* this call will always give us the elapsed time for the test, and */ + /* will also store-away the necessaries for cpu utilization */ + + cpu_stop(local_cpu_usage,&elapsed_time); /* was cpu being */ + /* measured and how */ + /* long did we really */ + /* run? */ + + /* Get the statistics from the remote end. The remote will have */ + /* calculated service demand and all those interesting things. If it */ + /* wasn't supposed to care, it will return obvious values. */ + + recv_response(); + if (!netperf_response.content.serv_errno) { + if (debug) + fprintf(where,"remote results obtained\n"); + } + else { + Set_errno(netperf_response.content.serv_errno); + perror("netperf: remote error"); + + exit(1); + } + + /* We now calculate what our thruput was for the test. In the future, */ + /* we may want to include a calculation of the thruput measured by */ + /* the remote, but it should be the case that for a TCP stream test, */ + /* that the two numbers should be *very* close... We calculate */ + /* bytes_sent regardless of the way the test length was controlled. */ + /* If it was time, we needed to, and if it was by bytes, the user may */ + /* have specified a number of bytes that wasn't a multiple of the */ + /* send_size, so we really didn't send what he asked for ;-) */ + + bytes_sent = xti_tcp_stream_result->bytes_received; + + thruput = calc_thruput(bytes_sent); + + if (local_cpu_usage || remote_cpu_usage) { + /* We must now do a little math for service demand and cpu */ + /* utilization for the system(s) */ + /* Of course, some of the information might be bogus because */ + /* there was no idle counter in the kernel(s). We need to make */ + /* a note of this for the user's benefit...*/ + if (local_cpu_usage) { + + local_cpu_utilization = calc_cpu_util(0.0); + local_service_demand = calc_service_demand(bytes_sent, + 0.0, + 0.0, + 0); + } + else { + local_cpu_utilization = -1.0; + local_service_demand = -1.0; + } + + if (remote_cpu_usage) { + + remote_cpu_utilization = xti_tcp_stream_result->cpu_util; + remote_service_demand = calc_service_demand(bytes_sent, + 0.0, + remote_cpu_utilization, + xti_tcp_stream_result->num_cpus); + } + else { + remote_cpu_utilization = -1.0; + remote_service_demand = -1.0; + } + } + else { + /* we were not measuring cpu, for the confidence stuff, we */ + /* should make it -1.0 */ + local_cpu_utilization = -1.0; + local_service_demand = -1.0; + remote_cpu_utilization = -1.0; + remote_service_demand = -1.0; + } + + /* at this point, we want to calculate the confidence information. */ + /* if debugging is on, calculate_confidence will print-out the */ + /* parameters we pass it */ + + calculate_confidence(confidence_iteration, + elapsed_time, + thruput, + local_cpu_utilization, + remote_cpu_utilization, + local_service_demand, + remote_service_demand); + + + confidence_iteration++; + } + + /* at this point, we have finished making all the runs that we */ + /* will be making. so, we should extract what the calcuated values */ + /* are for all the confidence stuff. we could make the values */ + /* global, but that seemed a little messy, and it did not seem worth */ + /* all the mucking with header files. so, we create a routine much */ + /* like calcualte_confidence, which just returns the mean values. */ + /* raj 11/94 */ + + retrieve_confident_values(&elapsed_time, + &thruput, + &local_cpu_utilization, + &remote_cpu_utilization, + &local_service_demand, + &remote_service_demand); + + /* We are now ready to print all the information. If the user */ + /* has specified zero-level verbosity, we will just print the */ + /* local service demand, or the remote service demand. If the */ + /* user has requested verbosity level 1, he will get the basic */ + /* "streamperf" numbers. If the user has specified a verbosity */ + /* of greater than 1, we will display a veritable plethora of */ + /* background information from outside of this block as it it */ + /* not cpu_measurement specific... */ + + if (confidence < 0) { + /* we did not hit confidence, but were we asked to look for it? */ + if (iteration_max > 1) { + display_confidence(); + } + } + + if (local_cpu_usage || remote_cpu_usage) { + local_cpu_method = format_cpu_method(cpu_method); + remote_cpu_method = format_cpu_method(xti_tcp_stream_result->cpu_method); + + switch (verbosity) { + case 0: + if (local_cpu_usage) { + fprintf(where, + cpu_fmt_0, + local_service_demand, + local_cpu_method); + } + else { + fprintf(where, + cpu_fmt_0, + remote_service_demand, + remote_cpu_method); + } + break; + case 1: + case 2: + if (print_headers) { + fprintf(where, + cpu_title, + format_units(), + local_cpu_method, + remote_cpu_method); + } + + fprintf(where, + cpu_fmt_1, /* the format string */ + rsr_size, /* remote recvbuf size */ + lss_size, /* local sendbuf size */ + send_size, /* how large were the sends */ + elapsed_time, /* how long was the test */ + thruput, /* what was the xfer rate */ + local_cpu_utilization, /* local cpu */ + remote_cpu_utilization, /* remote cpu */ + local_service_demand, /* local service demand */ + remote_service_demand); /* remote service demand */ + break; + } + } + else { + /* The tester did not wish to measure service demand. */ + + switch (verbosity) { + case 0: + fprintf(where, + tput_fmt_0, + thruput); + break; + case 1: + case 2: + if (print_headers) { + fprintf(where,tput_title,format_units()); + } + fprintf(where, + tput_fmt_1, /* the format string */ + rsr_size, /* remote recvbuf size */ + lss_size, /* local sendbuf size */ + send_size, /* how large were the sends */ + elapsed_time, /* how long did it take */ + thruput);/* how fast did it go */ + break; + } + } + + /* it would be a good thing to include information about some of the */ + /* other parameters that may have been set for this test, but at the */ + /* moment, I do not wish to figure-out all the formatting, so I will */ + /* just put this comment here to help remind me that it is something */ + /* that should be done at a later time. */ + + if (verbosity > 1) { + /* The user wanted to know it all, so we will give it to him. */ + /* This information will include as much as we can find about */ + /* TCP statistics, the alignments of the sends and receives */ + /* and all that sort of rot... */ + + /* this stuff needs to be worked-out in the presence of confidence */ + /* intervals and multiple iterations of the test... raj 11/94 */ + + fprintf(where, + ksink_fmt, + "Bytes", + "Bytes", + "Bytes", + local_send_align, + remote_recv_align, + local_send_offset, + remote_recv_offset, + bytes_sent, + bytes_sent / (double)nummessages, + nummessages, + bytes_sent / (double)xti_tcp_stream_result->recv_calls, + xti_tcp_stream_result->recv_calls); + fprintf(where, + ksink_fmt2, + tcp_mss); + fflush(where); +#ifdef WANT_HISTOGRAM + fprintf(where,"\n\nHistogram of time spent in send() call.\n"); + fflush(where); + HIST_report(time_hist); +#endif /* WANT_HISTOGRAM */ + } + +} + + +/* This is the server-side routine for the tcp stream test. It is */ +/* implemented as one routine. I could break things-out somewhat, but */ +/* didn't feel it was necessary. */ + +void +recv_xti_tcp_stream() +{ + + struct sockaddr_in myaddr_in, peeraddr_in; + struct t_bind bind_req, bind_resp; + struct t_call call_req; + + SOCKET s_listen,s_data; + int addrlen; + int len; + unsigned int receive_calls; + float elapsed_time; + double bytes_received; + + struct ring_elt *recv_ring; + + int *message_int_ptr; + int i; + + struct xti_tcp_stream_request_struct *xti_tcp_stream_request; + struct xti_tcp_stream_response_struct *xti_tcp_stream_response; + struct xti_tcp_stream_results_struct *xti_tcp_stream_results; + + xti_tcp_stream_request = + (struct xti_tcp_stream_request_struct *)netperf_request.content.test_specific_data; + xti_tcp_stream_response = + (struct xti_tcp_stream_response_struct *)netperf_response.content.test_specific_data; + xti_tcp_stream_results = + (struct xti_tcp_stream_results_struct *)netperf_response.content.test_specific_data; + + if (debug) { + fprintf(where,"netserver: recv_xti_tcp_stream: entered...\n"); + fflush(where); + } + + /* We want to set-up the listen socket with all the desired */ + /* parameters and then let the initiator know that all is ready. If */ + /* socket size defaults are to be used, then the initiator will have */ + /* sent us 0's. If the socket sizes cannot be changed, then we will */ + /* send-back what they are. If that information cannot be determined, */ + /* then we send-back -1's for the sizes. If things go wrong for any */ + /* reason, we will drop back ten yards and punt. */ + + /* If anything goes wrong, we want the remote to know about it. It */ + /* would be best if the error that the remote reports to the user is */ + /* the actual error we encountered, rather than some bogus unexpected */ + /* response type message. */ + + if (debug) { + fprintf(where,"recv_xti_tcp_stream: setting the response type...\n"); + fflush(where); + } + + netperf_response.content.response_type = XTI_TCP_STREAM_RESPONSE; + + if (debug) { + fprintf(where,"recv_xti_tcp_stream: the response type is set...\n"); + fflush(where); + } + + /* We now alter the message_ptr variable to be at the desired */ + /* alignment with the desired offset. */ + + if (debug) { + fprintf(where,"recv_xti_tcp_stream: requested alignment of %d\n", + xti_tcp_stream_request->recv_alignment); + fflush(where); + } + + /* Let's clear-out our sockaddr for the sake of cleanlines. Then we */ + /* can put in OUR values !-) At some point, we may want to nail this */ + /* socket to a particular network-level address, but for now, */ + /* INADDR_ANY should be just fine. */ + + bzero((char *)&myaddr_in, + sizeof(myaddr_in)); + myaddr_in.sin_family = AF_INET; + myaddr_in.sin_addr.s_addr = INADDR_ANY; + myaddr_in.sin_port = 0; + + /* Grab a socket to listen on, and then listen on it. */ + + if (debug) { + fprintf(where,"recv_xti_tcp_stream: grabbing a socket...\n"); + fflush(where); + } + + /* create_xti_endpoint expects to find some things in the global */ + /* variables, so set the globals based on the values in the request. */ + /* once the socket has been created, we will set the response values */ + /* based on the updated value of those globals. raj 7/94 */ + lss_size = xti_tcp_stream_request->send_buf_size; + lsr_size = xti_tcp_stream_request->recv_buf_size; + loc_nodelay = xti_tcp_stream_request->no_delay; + loc_rcvavoid = xti_tcp_stream_request->so_rcvavoid; + loc_sndavoid = xti_tcp_stream_request->so_sndavoid; + +#ifdef __alpha + + /* ok - even on a DEC box, strings are strings. I din't really want */ + /* to ntohl the words of a string. since I don't want to teach the */ + /* send_ and recv_ _request and _response routines about the types, */ + /* I will put "anti-ntohl" calls here. I imagine that the "pure" */ + /* solution would be to use XDR, but I am still leary of being able */ + /* to find XDR libs on all platforms I want running netperf. raj */ + { + int *charword; + int *initword; + int *lastword; + + initword = (int *) xti_tcp_stream_request->xti_device; + lastword = initword + ((xti_tcp_stream_request->dev_name_len + 3) / 4); + + for (charword = initword; + charword < lastword; + charword++) { + + *charword = htonl(*charword); + } + } + +#endif /* __alpha */ + + s_listen = create_xti_endpoint(xti_tcp_stream_request->xti_device); + + if (s_listen == INVALID_SOCKET) { + netperf_response.content.serv_errno = errno; + send_response(); + exit(1); + } + + /* Let's get an address assigned to this socket so we can tell the */ + /* initiator how to reach the data socket. There may be a desire to */ + /* nail this socket to a specific IP address in a multi-homed, */ + /* multi-connection situation, but for now, we'll ignore the issue */ + /* and concentrate on single connection testing. */ + + bind_req.addr.maxlen = sizeof(struct sockaddr_in); + bind_req.addr.len = sizeof(struct sockaddr_in); + bind_req.addr.buf = (char *)&myaddr_in; + bind_req.qlen = 1; + + bind_resp.addr.maxlen = sizeof(struct sockaddr_in); + bind_resp.addr.len = sizeof(struct sockaddr_in); + bind_resp.addr.buf = (char *)&myaddr_in; + bind_resp.qlen = 1; + + if (t_bind(s_listen, + &bind_req, + &bind_resp) == SOCKET_ERROR) { + netperf_response.content.serv_errno = t_errno; + close(s_listen); + send_response(); + + exit(1); + } + + if (debug) { + fprintf(where, + "recv_xti_tcp_stream: t_bind complete port %d\n", + ntohs(myaddr_in.sin_port)); + fflush(where); + } + + /* what sort of sizes did we end-up with? */ + if (xti_tcp_stream_request->receive_size == 0) { + if (lsr_size > 0) { + recv_size = lsr_size; + } + else { + recv_size = 4096; + } + } + else { + recv_size = xti_tcp_stream_request->receive_size; + } + + /* we want to set-up our recv_ring in a manner analagous to what we */ + /* do on the sending side. this is more for the sake of symmetry */ + /* than for the needs of say copy avoidance, but it might also be */ + /* more realistic - this way one could conceivably go with a */ + /* double-buffering scheme when taking the data an putting it into */ + /* the filesystem or something like that. raj 7/94 */ + + if (recv_width == 0) { + recv_width = (lsr_size/recv_size) + 1; + if (recv_width == 1) recv_width++; + } + + recv_ring = allocate_buffer_ring(recv_width, + recv_size, + xti_tcp_stream_request->recv_alignment, + xti_tcp_stream_request->recv_offset); + + if (debug) { + fprintf(where,"recv_xti_tcp_stream: recv alignment and offset set...\n"); + fflush(where); + } + + /* Now myaddr_in contains the port and the internet address this is */ + /* returned to the sender also implicitly telling the sender that the */ + /* socket buffer sizing has been done. */ + + xti_tcp_stream_response->data_port_number = + (int) ntohs(myaddr_in.sin_port); + netperf_response.content.serv_errno = 0; + + /* But wait, there's more. If the initiator wanted cpu measurements, */ + /* then we must call the calibrate routine, which will return the max */ + /* rate back to the initiator. If the CPU was not to be measured, or */ + /* something went wrong with the calibration, we will return a -1 to */ + /* the initiator. */ + + xti_tcp_stream_response->cpu_rate = 0.0; /* assume no cpu */ + if (xti_tcp_stream_request->measure_cpu) { + xti_tcp_stream_response->measure_cpu = 1; + xti_tcp_stream_response->cpu_rate = + calibrate_local_cpu(xti_tcp_stream_request->cpu_rate); + } + else { + xti_tcp_stream_response->measure_cpu = 0; + } + + /* before we send the response back to the initiator, pull some of */ + /* the socket parms from the globals */ + xti_tcp_stream_response->send_buf_size = lss_size; + xti_tcp_stream_response->recv_buf_size = lsr_size; + xti_tcp_stream_response->no_delay = loc_nodelay; + xti_tcp_stream_response->so_rcvavoid = loc_rcvavoid; + xti_tcp_stream_response->so_sndavoid = loc_sndavoid; + xti_tcp_stream_response->receive_size = recv_size; + + send_response(); + + /* Now, let's set-up the socket to listen for connections. for xti, */ + /* the t_listen call is blocking by default - this is different */ + /* semantics from BSD - probably has to do with being able to reject */ + /* a call before an accept */ + call_req.addr.maxlen = sizeof(struct sockaddr_in); + call_req.addr.len = sizeof(struct sockaddr_in); + call_req.addr.buf = (char *)&peeraddr_in; + call_req.opt.maxlen = 0; + call_req.opt.len = 0; + call_req.opt.buf = NULL; + call_req.udata.maxlen= 0; + call_req.udata.len = 0; + call_req.udata.buf = 0; + + if (t_listen(s_listen, &call_req) == -1) { + fprintf(where, + "recv_xti_tcp_stream: t_listen: errno %d t_errno %d\n", + errno, + t_errno); + fflush(where); + netperf_response.content.serv_errno = t_errno; + close(s_listen); + send_response(); + exit(1); + } + + if (debug) { + fprintf(where, + "recv_xti_tcp_stream: t_listen complete t_look 0x%.4x\n", + t_look(s_listen)); + fflush(where); + } + + /* now just rubber stamp the thing. we want to use the same fd? so */ + /* we will just equate s_data with s_listen. this seems a little */ + /* hokey to me, but then I'm a BSD biggot still. raj 2/95 */ + s_data = s_listen; + if (t_accept(s_listen, + s_data, + &call_req) == -1) { + fprintf(where, + "recv_xti_tcp_stream: t_accept: errno %d t_errno %d\n", + errno, + t_errno); + fflush(where); + close(s_listen); + exit(1); + } + + if (debug) { + fprintf(where, + "recv_xti_tcp_stream: t_accept complete t_look 0x%.4x\n", + t_look(s_data)); + fprintf(where, + " remote is %s port %d\n", + inet_ntoa(*(struct in_addr *)&peeraddr_in.sin_addr), + ntohs(peeraddr_in.sin_port)); + fflush(where); + } + + /* Now it's time to start receiving data on the connection. We will */ + /* first grab the apropriate counters and then start grabbing. */ + + cpu_start(xti_tcp_stream_request->measure_cpu); + + /* The loop will exit when the sender does a t_sndrel, which will */ + /* return T_LOOK error from the t_recv */ + +#ifdef DIRTY + /* we want to dirty some number of consecutive integers in the buffer */ + /* we are about to recv. we may also want to bring some number of */ + /* them cleanly into the cache. The clean ones will follow any dirty */ + /* ones into the cache. */ + + access_buffer(recv_ring->buffer_ptr, + recv_size, + xti_tcp_stream_request->dirty_count, + xti_tcp_stream_request->clean_count); + +#endif /* DIRTY */ + + bytes_received = 0; + receive_calls = 0; + + while ((len = t_rcv(s_data, + recv_ring->buffer_ptr, + recv_size, + &xti_flags)) != -1) { + bytes_received += len; + receive_calls++; + + /* more to the next buffer in the recv_ring */ + recv_ring = recv_ring->next; + +#ifdef DIRTY + + access_buffer(recv_ring->buffer_ptr, + recv_size, + xti_tcp_stream_request->dirty_count, + xti_tcp_stream_request->clean_count); + +#endif /* DIRTY */ + } + + if (t_look(s_data) == T_ORDREL) { + /* this is a normal exit path */ + if (debug) { + fprintf(where, + "recv_xti_tcp_stream: t_rcv T_ORDREL indicated\n"); + fflush(where); + } + } + else { + /* something went wrong */ + fprintf(where, + "recv_xti_tcp_stream: t_rcv: errno %d t_errno %d len %d", + errno, + t_errno, + len); + fprintf(where, + " t_look 0x%.4x", + t_look(s_data)); + fflush(where); + netperf_response.content.serv_errno = t_errno; + send_response(); + exit(1); + } + + /* receive the release and let the initiator know that we have */ + /* received all the data. raj 3/95 */ + + if (t_rcvrel(s_data) == -1) { + netperf_response.content.serv_errno = errno; + send_response(); + exit(1); + } + + if (debug) { + fprintf(where, + "recv_xti_tcp_stream: t_rcvrel complete\n"); + fflush(where); + } + + if (t_sndrel(s_data) == -1) { + netperf_response.content.serv_errno = errno; + send_response(); + exit(1); + } + + if (debug) { + fprintf(where, + "recv_xti_tcp_stream: t_sndrel complete\n"); + fflush(where); + } + + cpu_stop(xti_tcp_stream_request->measure_cpu,&elapsed_time); + + /* send the results to the sender */ + + if (debug) { + fprintf(where, + "recv_xti_tcp_stream: got %g bytes\n", + bytes_received); + fprintf(where, + "recv_xti_tcp_stream: got %d recvs\n", + receive_calls); + fflush(where); + } + + xti_tcp_stream_results->bytes_received = bytes_received; + xti_tcp_stream_results->elapsed_time = elapsed_time; + xti_tcp_stream_results->recv_calls = receive_calls; + + if (xti_tcp_stream_request->measure_cpu) { + xti_tcp_stream_results->cpu_util = calc_cpu_util(0.0); + }; + + if (debug) { + fprintf(where, + "recv_xti_tcp_stream: test complete, sending results.\n"); + fprintf(where, + " bytes_received %g receive_calls %d\n", + bytes_received, + receive_calls); + fprintf(where, + " len %d\n", + len); + fflush(where); + } + + xti_tcp_stream_results->cpu_method = cpu_method; + send_response(); + + /* we are now done with the socket */ + t_close(s_data); + +} + + + /* this routine implements the sending (netperf) side of the XTI_TCP_RR */ + /* test. */ + +void +send_xti_tcp_rr(char remote_host[]) +{ + + char *tput_title = "\ +Local /Remote\n\ +Socket Size Request Resp. Elapsed Trans.\n\ +Send Recv Size Size Time Rate \n\ +bytes Bytes bytes bytes secs. per sec \n\n"; + + char *tput_fmt_0 = + "%7.2f\n"; + + char *tput_fmt_1_line_1 = "\ +%-6d %-6d %-6d %-6d %-6.2f %7.2f \n"; + char *tput_fmt_1_line_2 = "\ +%-6d %-6d\n"; + + char *cpu_title = "\ +Local /Remote\n\ +Socket Size Request Resp. Elapsed Trans. CPU CPU S.dem S.dem\n\ +Send Recv Size Size Time Rate local remote local remote\n\ +bytes bytes bytes bytes secs. per sec %% %c %% %c us/Tr us/Tr\n\n"; + + char *cpu_fmt_0 = + "%6.3f %c\n"; + + char *cpu_fmt_1_line_1 = "\ +%-6d %-6d %-6d %-6d %-6.2f %-6.2f %-6.2f %-6.2f %-6.3f %-6.3f\n"; + + char *cpu_fmt_1_line_2 = "\ +%-6d %-6d\n"; + + char *ksink_fmt = "\ +Alignment Offset\n\ +Local Remote Local Remote\n\ +Send Recv Send Recv\n\ +%5d %5d %5d %5d\n"; + + + int timed_out = 0; + float elapsed_time; + + int len; + char *temp_message_ptr; + int nummessages; + SOCKET send_socket; + int trans_remaining; + double bytes_xferd; + + struct ring_elt *send_ring; + struct ring_elt *recv_ring; + + int rsp_bytes_left; + int rsp_bytes_recvd; + + float local_cpu_utilization; + float local_service_demand; + float remote_cpu_utilization; + float remote_service_demand; + double thruput; + + struct hostent *hp; + struct sockaddr_in server; + unsigned int addr; + + struct t_call server_call; + + struct xti_tcp_rr_request_struct *xti_tcp_rr_request; + struct xti_tcp_rr_response_struct *xti_tcp_rr_response; + struct xti_tcp_rr_results_struct *xti_tcp_rr_result; + +#ifdef WANT_INTERVALS + int interval_count; + sigset_t signal_set; +#endif /* WANT_INTERVALS */ + + xti_tcp_rr_request = + (struct xti_tcp_rr_request_struct *)netperf_request.content.test_specific_data; + xti_tcp_rr_response= + (struct xti_tcp_rr_response_struct *)netperf_response.content.test_specific_data; + xti_tcp_rr_result = + (struct xti_tcp_rr_results_struct *)netperf_response.content.test_specific_data; + +#ifdef WANT_HISTOGRAM + time_hist = HIST_new(); +#endif /* WANT_HISTOGRAM */ + + /* since we are now disconnected from the code that established the */ + /* control socket, and since we want to be able to use different */ + /* protocols and such, we are passed the name of the remote host and */ + /* must turn that into the test specific addressing information. */ + + bzero((char *)&server, + sizeof(server)); + + /* it would seem that while HP-UX will allow an IP address (as a */ + /* string) in a call to gethostbyname, other, less enlightened */ + /* systems do not. fix from awjacks@ca.sandia.gov raj 10/95 */ + /* order changed to check for IP address first. raj 7/96 */ + + if ((addr = inet_addr(remote_host)) == SOCKET_ERROR) { + /* it was not an IP address, try it as a name */ + if ((hp = gethostbyname(remote_host)) == NULL) { + /* we have no idea what it is */ + fprintf(where, + "establish_control: could not resolve the destination %s\n", + remote_host); + fflush(where); + exit(1); + } + else { + /* it was a valid remote_host */ + bcopy(hp->h_addr, + (char *)&server.sin_addr, + hp->h_length); + server.sin_family = hp->h_addrtype; + } + } + else { + /* it was a valid IP address */ + server.sin_addr.s_addr = addr; + server.sin_family = AF_INET; + } + + if ( print_headers ) { + fprintf(where,"XTI TCP REQUEST/RESPONSE TEST"); + fprintf(where," to %s", remote_host); + if (iteration_max > 1) { + fprintf(where, + " : +/-%3.1f%% @ %2d%% conf.", + interval/0.02, + confidence_level); + } + if (loc_nodelay || rem_nodelay) { + fprintf(where," : nodelay"); + } + if (loc_sndavoid || + loc_rcvavoid || + rem_sndavoid || + rem_rcvavoid) { + fprintf(where," : copy avoidance"); + } +#ifdef WANT_HISTOGRAM + fprintf(where," : histogram"); +#endif /* WANT_HISTOGRAM */ +#ifdef WANT_INTERVALS + fprintf(where," : interval"); +#endif /* WANT_INTERVALS */ +#ifdef DIRTY + fprintf(where," : dirty data"); +#endif /* DIRTY */ + fprintf(where,"\n"); + } + + /* initialize a few counters */ + + send_ring = NULL; + recv_ring = NULL; + confidence_iteration = 1; + init_stat(); + + /* we have a great-big while loop which controls the number of times */ + /* we run a particular test. this is for the calculation of a */ + /* confidence interval (I really should have stayed awake during */ + /* probstats :). If the user did not request confidence measurement */ + /* (no confidence is the default) then we will only go though the */ + /* loop once. the confidence stuff originates from the folks at IBM */ + + while (((confidence < 0) && (confidence_iteration < iteration_max)) || + (confidence_iteration <= iteration_min)) { + + /* initialize a few counters. we have to remember that we might be */ + /* going through the loop more than once. */ + + nummessages = 0; + bytes_xferd = 0.0; + times_up = 0; + timed_out = 0; + trans_remaining = 0; + + /* set-up the data buffers with the requested alignment and offset. */ + /* since this is a request/response test, default the send_width and */ + /* recv_width to 1 and not two raj 7/94 */ + + if (send_width == 0) send_width = 1; + if (recv_width == 0) recv_width = 1; + + if (send_ring == NULL) { + send_ring = allocate_buffer_ring(send_width, + req_size, + local_send_align, + local_send_offset); + } + + if (recv_ring == NULL) { + recv_ring = allocate_buffer_ring(recv_width, + rsp_size, + local_recv_align, + local_recv_offset); + } + + /*set up the data socket */ + send_socket = create_xti_endpoint(loc_xti_device); + + if (send_socket == INVALID_SOCKET){ + perror("netperf: send_xti_tcp_rr: tcp stream data socket"); + exit(1); + } + + if (debug) { + fprintf(where,"send_xti_tcp_rr: send_socket obtained...\n"); + } + + /* it would seem that with XTI, there is no implicit bind on a */ + /* connect, so we have to make a call to t_bind. this is not */ + /* terribly convenient, but I suppose that "standard is better */ + /* than better" :) raj 2/95 */ + + if (t_bind(send_socket, NULL, NULL) == SOCKET_ERROR) { + t_error("send_xti_tcp_stream: t_bind"); + exit(1); + } + + /* If the user has requested cpu utilization measurements, we must */ + /* calibrate the cpu(s). We will perform this task within the tests */ + /* themselves. If the user has specified the cpu rate, then */ + /* calibrate_local_cpu will return rather quickly as it will have */ + /* nothing to do. If local_cpu_rate is zero, then we will go through */ + /* all the "normal" calibration stuff and return the rate back.*/ + + if (local_cpu_usage) { + local_cpu_rate = calibrate_local_cpu(local_cpu_rate); + } + + /* Tell the remote end to do a listen. The server alters the socket */ + /* paramters on the other side at this point, hence the reason for */ + /* all the values being passed in the setup message. If the user did */ + /* not specify any of the parameters, they will be passed as 0, which */ + /* will indicate to the remote that no changes beyond the system's */ + /* default should be used. Alignment is the exception, it will */ + /* default to 8, which will be no alignment alterations. */ + + netperf_request.content.request_type = DO_XTI_TCP_RR; + xti_tcp_rr_request->recv_buf_size = rsr_size; + xti_tcp_rr_request->send_buf_size = rss_size; + xti_tcp_rr_request->recv_alignment = remote_recv_align; + xti_tcp_rr_request->recv_offset = remote_recv_offset; + xti_tcp_rr_request->send_alignment = remote_send_align; + xti_tcp_rr_request->send_offset = remote_send_offset; + xti_tcp_rr_request->request_size = req_size; + xti_tcp_rr_request->response_size = rsp_size; + xti_tcp_rr_request->no_delay = rem_nodelay; + xti_tcp_rr_request->measure_cpu = remote_cpu_usage; + xti_tcp_rr_request->cpu_rate = remote_cpu_rate; + xti_tcp_rr_request->so_rcvavoid = rem_rcvavoid; + xti_tcp_rr_request->so_sndavoid = rem_sndavoid; + if (test_time) { + xti_tcp_rr_request->test_length = test_time; + } + else { + xti_tcp_rr_request->test_length = test_trans * -1; + } + + strcpy(xti_tcp_rr_request->xti_device, rem_xti_device); + +#ifdef __alpha + + /* ok - even on a DEC box, strings are strings. I didn't really want */ + /* to ntohl the words of a string. since I don't want to teach the */ + /* send_ and recv_ _request and _response routines about the types, */ + /* I will put "anti-ntohl" calls here. I imagine that the "pure" */ + /* solution would be to use XDR, but I am still leary of being able */ + /* to find XDR libs on all platforms I want running netperf. raj */ + { + int *charword; + int *initword; + int *lastword; + + initword = (int *) xti_tcp_rr_request->xti_device; + lastword = initword + ((strlen(rem_xti_device) + 3) / 4); + + for (charword = initword; + charword < lastword; + charword++) { + + *charword = ntohl(*charword); + } + } +#endif /* __alpha */ + + if (debug > 1) { + fprintf(where,"netperf: send_xti_tcp_rr: requesting TCP rr test\n"); + } + + send_request(); + + /* The response from the remote will contain all of the relevant */ + /* socket parameters for this test type. We will put them back into */ + /* the variables here so they can be displayed if desired. The */ + /* remote will have calibrated CPU if necessary, and will have done */ + /* all the needed set-up we will have calibrated the cpu locally */ + /* before sending the request, and will grab the counter value right*/ + /* after the connect returns. The remote will grab the counter right*/ + /* after the accept call. This saves the hassle of extra messages */ + /* being sent for the TCP tests. */ + + recv_response(); + + if (!netperf_response.content.serv_errno) { + if (debug) + fprintf(where,"remote listen done.\n"); + rsr_size = xti_tcp_rr_response->recv_buf_size; + rss_size = xti_tcp_rr_response->send_buf_size; + rem_nodelay = xti_tcp_rr_response->no_delay; + remote_cpu_usage = xti_tcp_rr_response->measure_cpu; + remote_cpu_rate = xti_tcp_rr_response->cpu_rate; + /* make sure that port numbers are in network order */ + server.sin_port = (short)xti_tcp_rr_response->data_port_number; + server.sin_port = htons(server.sin_port); + } + else { + Set_errno(netperf_response.content.serv_errno); + perror("netperf: remote error"); + + exit(1); + } + + /*Connect up to the remote port on the data socket */ + memset (&server_call, 0, sizeof(server_call)); + server_call.addr.maxlen = sizeof(struct sockaddr_in); + server_call.addr.len = sizeof(struct sockaddr_in); + server_call.addr.buf = (char *)&server; + + if (t_connect(send_socket, + &server_call, + NULL) == INVALID_SOCKET){ + t_error("netperf: send_xti_tcp_rr: data socket connect failed"); + printf(" port: %d\n",ntohs(server.sin_port)); + exit(1); + } + + /* Data Socket set-up is finished. If there were problems, either the */ + /* connect would have failed, or the previous response would have */ + /* indicated a problem. I failed to see the value of the extra */ + /* message after the accept on the remote. If it failed, we'll see it */ + /* here. If it didn't, we might as well start pumping data. */ + + /* Set-up the test end conditions. For a request/response test, they */ + /* can be either time or transaction based. */ + + if (test_time) { + /* The user wanted to end the test after a period of time. */ + times_up = 0; + trans_remaining = 0; + start_timer(test_time); + } + else { + /* The tester wanted to send a number of bytes. */ + trans_remaining = test_bytes; + times_up = 1; + } + + /* The cpu_start routine will grab the current time and possibly */ + /* value of the idle counter for later use in measuring cpu */ + /* utilization and/or service demand and thruput. */ + + cpu_start(local_cpu_usage); + +#ifdef WANT_INTERVALS + if ((interval_burst) || (demo_mode)) { + /* zero means that we never pause, so we never should need the */ + /* interval timer, unless we are in demo_mode */ + start_itimer(interval_wate); + } + interval_count = interval_burst; + /* get the signal set for the call to sigsuspend */ + if (sigprocmask(SIG_BLOCK, (sigset_t *)NULL, &signal_set) != 0) { + fprintf(where, + "send_xti_tcp_rr: unable to get sigmask errno %d\n", + errno); + fflush(where); + exit(1); + } +#endif /* WANT_INTERVALS */ + + /* We use an "OR" to control test execution. When the test is */ + /* controlled by time, the byte count check will always return false. */ + /* When the test is controlled by byte count, the time test will */ + /* always return false. When the test is finished, the whole */ + /* expression will go false and we will stop sending data. I think I */ + /* just arbitrarily decrement trans_remaining for the timed test, but */ + /* will not do that just yet... One other question is whether or not */ + /* the send buffer and the receive buffer should be the same buffer. */ + + while ((!times_up) || (trans_remaining > 0)) { + /* send the request. we assume that if we use a blocking socket, */ + /* the request will be sent at one shot. */ + +#ifdef WANT_HISTOGRAM + /* timestamp just before our call to send, and then again just */ + /* after the receive raj 8/94 */ + HIST_timestamp(&time_one); +#endif /* WANT_HISTOGRAM */ + + if((len=t_snd(send_socket, + send_ring->buffer_ptr, + req_size, + 0)) != req_size) { + if ((errno == EINTR) || (errno == 0)) { + /* we hit the end of a */ + /* timed test. */ + timed_out = 1; + break; + } + fprintf(where, + "send_xti_tcp_rr: t_snd: errno %d t_errno %d t_look 0x%.4x\n", + errno, + t_errno, + t_look(send_socket)); + fflush(where); + exit(1); + } + send_ring = send_ring->next; + + /* receive the response */ + rsp_bytes_left = rsp_size; + temp_message_ptr = recv_ring->buffer_ptr; + while(rsp_bytes_left > 0) { + if((rsp_bytes_recvd=t_rcv(send_socket, + temp_message_ptr, + rsp_bytes_left, + &xti_flags)) == SOCKET_ERROR) { + if (errno == EINTR) { + /* We hit the end of a timed test. */ + timed_out = 1; + break; + } + fprintf(where, + "send_xti_tcp_rr: t_rcv: errno %d t_errno %d t_look 0x%x\n", + errno, + t_errno, + t_look(send_socket)); + fflush(where); + exit(1); + } + rsp_bytes_left -= rsp_bytes_recvd; + temp_message_ptr += rsp_bytes_recvd; + } + recv_ring = recv_ring->next; + + if (timed_out) { + /* we may have been in a nested while loop - we need */ + /* another call to break. */ + break; + } + +#ifdef WANT_HISTOGRAM + HIST_timestamp(&time_two); + HIST_add(time_hist,delta_micro(&time_one,&time_two)); +#endif /* WANT_HISTOGRAM */ +#ifdef WANT_INTERVALS + if (demo_mode) { + units_this_tick += 1; + } + /* in this case, the interval count is the count-down couter */ + /* to decide to sleep for a little bit */ + if ((interval_burst) && (--interval_count == 0)) { + /* call sigsuspend and wait for the interval timer to get us */ + /* out */ + if (debug) { + fprintf(where,"about to suspend\n"); + fflush(where); + } + if (sigsuspend(&signal_set) == EFAULT) { + fprintf(where, + "send_xti_udp_rr: fault with signal set!\n"); + fflush(where); + exit(1); + } + interval_count = interval_burst; + } +#endif /* WANT_INTERVALS */ + + nummessages++; + if (trans_remaining) { + trans_remaining--; + } + + if (debug > 3) { + if ((nummessages % 100) == 0) { + fprintf(where, + "Transaction %d completed\n", + nummessages); + fflush(where); + } + } + } + + + /* this call will always give us the elapsed time for the test, and */ + /* will also store-away the necessaries for cpu utilization */ + + cpu_stop(local_cpu_usage,&elapsed_time); /* was cpu being */ + /* measured? how long */ + /* did we really run? */ + + /* Get the statistics from the remote end. The remote will have */ + /* calculated service demand and all those interesting things. If it */ + /* wasn't supposed to care, it will return obvious values. */ + + recv_response(); + if (!netperf_response.content.serv_errno) { + if (debug) + fprintf(where,"remote results obtained\n"); + } + else { + Set_errno(netperf_response.content.serv_errno); + perror("netperf: remote error"); + + exit(1); + } + + /* We now calculate what our thruput was for the test. */ + + bytes_xferd = (req_size * nummessages) + (rsp_size * nummessages); + thruput = nummessages/elapsed_time; + + if (local_cpu_usage || remote_cpu_usage) { + /* We must now do a little math for service demand and cpu */ + /* utilization for the system(s) */ + /* Of course, some of the information might be bogus because */ + /* there was no idle counter in the kernel(s). We need to make */ + /* a note of this for the user's benefit...*/ + if (local_cpu_usage) { + local_cpu_utilization = calc_cpu_util(0.0); + /* since calc_service demand is doing ms/Kunit we will */ + /* multiply the number of transaction by 1024 to get */ + /* "good" numbers */ + local_service_demand = calc_service_demand((double) nummessages*1024, + 0.0, + 0.0, + 0); + } + else { + local_cpu_utilization = -1.0; + local_service_demand = -1.0; + } + + if (remote_cpu_usage) { + remote_cpu_utilization = xti_tcp_rr_result->cpu_util; + /* since calc_service demand is doing ms/Kunit we will */ + /* multiply the number of transaction by 1024 to get */ + /* "good" numbers */ + remote_service_demand = calc_service_demand((double) nummessages*1024, + 0.0, + remote_cpu_utilization, + xti_tcp_rr_result->num_cpus); + } + else { + remote_cpu_utilization = -1.0; + remote_service_demand = -1.0; + } + + } + else { + /* we were not measuring cpu, for the confidence stuff, we */ + /* should make it -1.0 */ + local_cpu_utilization = -1.0; + local_service_demand = -1.0; + remote_cpu_utilization = -1.0; + remote_service_demand = -1.0; + } + + /* at this point, we want to calculate the confidence information. */ + /* if debugging is on, calculate_confidence will print-out the */ + /* parameters we pass it */ + + calculate_confidence(confidence_iteration, + elapsed_time, + thruput, + local_cpu_utilization, + remote_cpu_utilization, + local_service_demand, + remote_service_demand); + + + confidence_iteration++; + + /* we are now done with the socket, so close it */ + t_close(send_socket); + + } + + retrieve_confident_values(&elapsed_time, + &thruput, + &local_cpu_utilization, + &remote_cpu_utilization, + &local_service_demand, + &remote_service_demand); + + /* We are now ready to print all the information. If the user */ + /* has specified zero-level verbosity, we will just print the */ + /* local service demand, or the remote service demand. If the */ + /* user has requested verbosity level 1, he will get the basic */ + /* "streamperf" numbers. If the user has specified a verbosity */ + /* of greater than 1, we will display a veritable plethora of */ + /* background information from outside of this block as it it */ + /* not cpu_measurement specific... */ + + if (confidence < 0) { + /* we did not hit confidence, but were we asked to look for it? */ + if (iteration_max > 1) { + display_confidence(); + } + } + + if (local_cpu_usage || remote_cpu_usage) { + local_cpu_method = format_cpu_method(cpu_method); + remote_cpu_method = format_cpu_method(xti_tcp_rr_result->cpu_method); + + switch (verbosity) { + case 0: + if (local_cpu_usage) { + fprintf(where, + cpu_fmt_0, + local_service_demand, + local_cpu_method); + } + else { + fprintf(where, + cpu_fmt_0, + remote_service_demand, + remote_cpu_method); + } + break; + case 1: + case 2: + if (print_headers) { + fprintf(where, + cpu_title, + local_cpu_method, + remote_cpu_method); + } + + fprintf(where, + cpu_fmt_1_line_1, /* the format string */ + lss_size, /* local sendbuf size */ + lsr_size, + req_size, /* how large were the requests */ + rsp_size, /* guess */ + elapsed_time, /* how long was the test */ + thruput, + local_cpu_utilization, /* local cpu */ + remote_cpu_utilization, /* remote cpu */ + local_service_demand, /* local service demand */ + remote_service_demand); /* remote service demand */ + fprintf(where, + cpu_fmt_1_line_2, + rss_size, + rsr_size); + break; + } + } + else { + /* The tester did not wish to measure service demand. */ + + switch (verbosity) { + case 0: + fprintf(where, + tput_fmt_0, + thruput); + break; + case 1: + case 2: + if (print_headers) { + fprintf(where,tput_title,format_units()); + } + + fprintf(where, + tput_fmt_1_line_1, /* the format string */ + lss_size, + lsr_size, + req_size, /* how large were the requests */ + rsp_size, /* how large were the responses */ + elapsed_time, /* how long did it take */ + thruput); + fprintf(where, + tput_fmt_1_line_2, + rss_size, /* remote recvbuf size */ + rsr_size); + + break; + } + } + + /* it would be a good thing to include information about some of the */ + /* other parameters that may have been set for this test, but at the */ + /* moment, I do not wish to figure-out all the formatting, so I will */ + /* just put this comment here to help remind me that it is something */ + /* that should be done at a later time. */ + + /* how to handle the verbose information in the presence of */ + /* confidence intervals is yet to be determined... raj 11/94 */ + if (verbosity > 1) { + /* The user wanted to know it all, so we will give it to him. */ + /* This information will include as much as we can find about */ + /* TCP statistics, the alignments of the sends and receives */ + /* and all that sort of rot... */ + + fprintf(where, + ksink_fmt, + local_send_align, + remote_recv_offset, + local_send_offset, + remote_recv_offset); + +#ifdef WANT_HISTOGRAM + fprintf(where,"\nHistogram of request/response times\n"); + fflush(where); + HIST_report(time_hist); +#endif /* WANT_HISTOGRAM */ + + } + +} + +void +send_xti_udp_stream(char remote_host[]) +{ + /**********************************************************************/ + /* */ + /* UDP Unidirectional Send Test */ + /* */ + /**********************************************************************/ + char *tput_title = "\ +Socket Message Elapsed Messages \n\ +Size Size Time Okay Errors Throughput\n\ +bytes bytes secs # # %s/sec\n\n"; + + char *tput_fmt_0 = + "%7.2f\n"; + + char *tput_fmt_1 = "\ +%6d %6d %-7.2f %7d %6d %7.2f\n\ +%6d %-7.2f %7d %7.2f\n\n"; + + + char *cpu_title = "\ +Socket Message Elapsed Messages CPU Service\n\ +Size Size Time Okay Errors Throughput Util Demand\n\ +bytes bytes secs # # %s/sec %% %c%c us/KB\n\n"; + + char *cpu_fmt_0 = + "%6.2f %c\n"; + + char *cpu_fmt_1 = "\ +%6d %6d %-7.2f %7d %6d %7.1f %-6.2f %-6.3f\n\ +%6d %-7.2f %7d %7.1f %-6.2f %-6.3f\n\n"; + + unsigned int messages_recvd; + unsigned int messages_sent; + unsigned int failed_sends; + + float elapsed_time, + recv_elapsed, + local_cpu_utilization, + remote_cpu_utilization; + + float local_service_demand, remote_service_demand; + double local_thruput, remote_thruput; + double bytes_sent; + double bytes_recvd; + + + int len; + int *message_int_ptr; + struct ring_elt *send_ring; + SOCKET data_socket; + + unsigned int sum_messages_sent; + unsigned int sum_messages_recvd; + unsigned int sum_failed_sends; + double sum_local_thruput; + +#ifdef WANT_INTERVALS + int interval_count; + sigset_t signal_set; +#endif /* WANT_INTERVALS */ + + struct hostent *hp; + struct sockaddr_in server; + unsigned int addr; + + struct t_unitdata unitdata; + + struct xti_udp_stream_request_struct *xti_udp_stream_request; + struct xti_udp_stream_response_struct *xti_udp_stream_response; + struct xti_udp_stream_results_struct *xti_udp_stream_results; + + xti_udp_stream_request = + (struct xti_udp_stream_request_struct *)netperf_request.content.test_specific_data; + xti_udp_stream_response = + (struct xti_udp_stream_response_struct *)netperf_response.content.test_specific_data; + xti_udp_stream_results = + (struct xti_udp_stream_results_struct *)netperf_response.content.test_specific_data; + +#ifdef WANT_HISTOGRAM + time_hist = HIST_new(); +#endif /* WANT_HISTOGRAM */ + + /* since we are now disconnected from the code that established the */ + /* control socket, and since we want to be able to use different */ + /* protocols and such, we are passed the name of the remote host and */ + /* must turn that into the test specific addressing information. */ + + bzero((char *)&server, + sizeof(server)); + + /* it would seem that while HP-UX will allow an IP address (as a */ + /* string) in a call to gethostbyname, other, less enlightened */ + /* systems do not. fix from awjacks@ca.sandia.gov raj 10/95 */ + /* order changed to check for IP address first. raj 7/96 */ + + if ((addr = inet_addr(remote_host)) == SOCKET_ERROR) { + /* it was not an IP address, try it as a name */ + if ((hp = gethostbyname(remote_host)) == NULL) { + /* we have no idea what it is */ + fprintf(where, + "establish_control: could not resolve the destination %s\n", + remote_host); + fflush(where); + exit(1); + } + else { + /* it was a valid remote_host */ + bcopy(hp->h_addr, + (char *)&server.sin_addr, + hp->h_length); + server.sin_family = hp->h_addrtype; + } + } + else { + /* it was a valid IP address */ + server.sin_addr.s_addr = addr; + server.sin_family = AF_INET; + } + + if ( print_headers ) { + fprintf(where,"UDP UNIDIRECTIONAL SEND TEST"); + fprintf(where," to %s", remote_host); + if (iteration_max > 1) { + fprintf(where, + " : +/-%3.1f%% @ %2d%% conf.", + interval/0.02, + confidence_level); + } + if (loc_sndavoid || + loc_rcvavoid || + rem_sndavoid || + rem_rcvavoid) { + fprintf(where," : copy avoidance"); + } +#ifdef WANT_HISTOGRAM + fprintf(where," : histogram"); +#endif /* WANT_HISTOGRAM */ +#ifdef WANT_INTERVALS + fprintf(where," : interval"); +#endif /* WANT_INTERVALS */ +#ifdef DIRTY + fprintf(where," : dirty data"); +#endif /* DIRTY */ + fprintf(where,"\n"); + } + + send_ring = NULL; + confidence_iteration = 1; + init_stat(); + sum_messages_sent = 0; + sum_messages_recvd = 0; + sum_failed_sends = 0; + sum_local_thruput = 0.0; + + /* we have a great-big while loop which controls the number of times */ + /* we run a particular test. this is for the calculation of a */ + /* confidence interval (I really should have stayed awake during */ + /* probstats :). If the user did not request confidence measurement */ + /* (no confidence is the default) then we will only go though the */ + /* loop once. the confidence stuff originates from the folks at IBM */ + + while (((confidence < 0) && (confidence_iteration < iteration_max)) || + (confidence_iteration <= iteration_min)) { + + /* initialize a few counters. we have to remember that we might be */ + /* going through the loop more than once. */ + messages_sent = 0; + messages_recvd = 0; + failed_sends = 0; + times_up = 0; + + /*set up the data socket */ + data_socket = create_xti_endpoint(loc_xti_device); + + if (data_socket == INVALID_SOCKET) { + perror("send_xti_udp_stream: create_xti_endpoint"); + exit(1); + } + + if (t_bind(data_socket, NULL, NULL) == SOCKET_ERROR) { + t_error("send_xti_udp_stream: t_bind"); + exit(1); + } + + /* now, we want to see if we need to set the send_size */ + if (send_size == 0) { + if (lss_size > 0) { + send_size = lss_size; + } + else { + send_size = 4096; + } + } + + /* set-up the data buffer with the requested alignment and offset, */ + /* most of the numbers here are just a hack to pick something nice */ + /* and big in an attempt to never try to send a buffer a second time */ + /* before it leaves the node...unless the user set the width */ + /* explicitly. */ + if (send_width == 0) send_width = 32; + + if (send_ring == NULL ) { + send_ring = allocate_buffer_ring(send_width, + send_size, + local_send_align, + local_send_offset); + } + + + /* if the user supplied a cpu rate, this call will complete rather */ + /* quickly, otherwise, the cpu rate will be retured to us for */ + /* possible display. The Library will keep it's own copy of this data */ + /* for use elsewhere. We will only display it. (Does that make it */ + /* "opaque" to us?) */ + + if (local_cpu_usage) + local_cpu_rate = calibrate_local_cpu(local_cpu_rate); + + /* Tell the remote end to set up the data connection. The server */ + /* sends back the port number and alters the socket parameters there. */ + /* Of course this is a datagram service so no connection is actually */ + /* set up, the server just sets up the socket and binds it. */ + + netperf_request.content.request_type = DO_XTI_UDP_STREAM; + xti_udp_stream_request->recv_buf_size = rsr_size; + xti_udp_stream_request->message_size = send_size; + xti_udp_stream_request->recv_alignment = remote_recv_align; + xti_udp_stream_request->recv_offset = remote_recv_offset; + xti_udp_stream_request->measure_cpu = remote_cpu_usage; + xti_udp_stream_request->cpu_rate = remote_cpu_rate; + xti_udp_stream_request->test_length = test_time; + xti_udp_stream_request->so_rcvavoid = rem_rcvavoid; + xti_udp_stream_request->so_sndavoid = rem_sndavoid; + + strcpy(xti_udp_stream_request->xti_device, rem_xti_device); + +#ifdef __alpha + + /* ok - even on a DEC box, strings are strings. I didn't really want */ + /* to ntohl the words of a string. since I don't want to teach the */ + /* send_ and recv_ _request and _response routines about the types, */ + /* I will put "anti-ntohl" calls here. I imagine that the "pure" */ + /* solution would be to use XDR, but I am still leary of being able */ + /* to find XDR libs on all platforms I want running netperf. raj */ + { + int *charword; + int *initword; + int *lastword; + + initword = (int *) xti_udp_stream_request->xti_device; + lastword = initword + ((strlen(rem_xti_device) + 3) / 4); + + for (charword = initword; + charword < lastword; + charword++) { + + *charword = ntohl(*charword); + } + } +#endif /* __alpha */ + + send_request(); + + recv_response(); + + if (!netperf_response.content.serv_errno) { + if (debug) + fprintf(where,"send_xti_udp_stream: remote data connection done.\n"); + } + else { + Set_errno(netperf_response.content.serv_errno); + perror("send_xti_udp_stream: error on remote"); + exit(1); + } + + /* Place the port number returned by the remote into the sockaddr */ + /* structure so our sends can be sent to the correct place. Also get */ + /* some of the returned socket buffer information for user display. */ + + /* make sure that port numbers are in the proper order */ + server.sin_port = (short)xti_udp_stream_response->data_port_number; + server.sin_port = htons(server.sin_port); + rsr_size = xti_udp_stream_response->recv_buf_size; + rss_size = xti_udp_stream_response->send_buf_size; + remote_cpu_rate = xti_udp_stream_response->cpu_rate; + + /* it would seem that XTI does not allow the expedient of */ + /* "connecting" a UDP end-point the way BSD does. so, we will do */ + /* everything with t_sndudata and t_rcvudata. Our "virtual" */ + /* connect here will be to assign the destination portion of the */ + /* t_unitdata struct here, where we would have otherwise called */ + /* t_connect() raj 3/95 */ + + memset (&unitdata, 0, sizeof(unitdata)); + unitdata.addr.maxlen = sizeof(struct sockaddr_in); + unitdata.addr.len = sizeof(struct sockaddr_in); + unitdata.addr.buf = (char *)&server; + + /* we don't use any options, so might as well set that part here */ + /* too */ + + unitdata.opt.maxlen = 0; + unitdata.opt.len = 0; + unitdata.opt.buf = NULL; + + /* we need to initialize the send buffer for the first time as */ + /* well since we move to the next pointer after the send call. */ + + unitdata.udata.maxlen = send_size; + unitdata.udata.len = send_size; + unitdata.udata.buf = send_ring->buffer_ptr; + + /* set up the timer to call us after test_time. one of these days, */ + /* it might be nice to figure-out a nice reliable way to have the */ + /* test controlled by a byte count as well, but since UDP is not */ + /* reliable, that could prove difficult. so, in the meantime, we */ + /* only allow a XTI_UDP_STREAM test to be a timed test. */ + + if (test_time) { + times_up = 0; + start_timer(test_time); + } + else { + fprintf(where,"Sorry, XTI_UDP_STREAM tests must be timed.\n"); + fflush(where); + exit(1); + } + + /* Get the start count for the idle counter and the start time */ + + cpu_start(local_cpu_usage); + +#ifdef WANT_INTERVALS + if ((interval_burst) || (demo_mode)) { + /* zero means that we never pause, so we never should need the */ + /* interval timer, unless we are in demo_mode */ + start_itimer(interval_wate); + } + interval_count = interval_burst; + /* get the signal set for the call to sigsuspend */ + if (sigprocmask(SIG_BLOCK, (sigset_t *)NULL, &signal_set) != 0) { + fprintf(where, + "send_xti_udp_stream: unable to get sigmask errno %d\n", + errno); + fflush(where); + exit(1); + } +#endif /* WANT_INTERVALS */ + + /* Send datagrams like there was no tomorrow. at somepoint it might */ + /* be nice to set this up so that a quantity of bytes could be sent, */ + /* but we still need some sort of end of test trigger on the receive */ + /* side. that could be a select with a one second timeout, but then */ + /* if there is a test where none of the data arrives for awile and */ + /* then starts again, we would end the test too soon. something to */ + /* think about... */ + while (!times_up) { + +#ifdef DIRTY + /* we want to dirty some number of consecutive integers in the buffer */ + /* we are about to send. we may also want to bring some number of */ + /* them cleanly into the cache. The clean ones will follow any dirty */ + /* ones into the cache. */ + + access_buffer(send_ring->buffer_ptr, + send_size, + loc_dirty_count, + loc_clean_count); + +#endif /* DIRTY */ + +#ifdef WANT_HISTOGRAM + HIST_timestamp(&time_one); +#endif /* WANT_HISTOGRAM */ + + if ((t_sndudata(data_socket, + &unitdata)) != 0) { + if (errno == EINTR) + break; + if (errno == ENOBUFS) { + failed_sends++; + continue; + } + perror("xti_udp_send: data send error"); + t_error("xti_udp_send: data send error"); + exit(1); + } + messages_sent++; + + /* now we want to move our pointer to the next position in the */ + /* data buffer...and update the unitdata structure */ + + send_ring = send_ring->next; + unitdata.udata.buf = send_ring->buffer_ptr; + +#ifdef WANT_HISTOGRAM + /* get the second timestamp */ + HIST_timestamp(&time_two); + HIST_add(time_hist,delta_micro(&time_one,&time_two)); +#endif /* WANT_HISTOGRAM */ +#ifdef WANT_INTERVALS + if (demo_mode) { + units_this_tick += send_size; + } + /* in this case, the interval count is the count-down couter */ + /* to decide to sleep for a little bit */ + if ((interval_burst) && (--interval_count == 0)) { + /* call sigsuspend and wait for the interval timer to get us */ + /* out */ + if (debug) { + fprintf(where,"about to suspend\n"); + fflush(where); + } + if (sigsuspend(&signal_set) == EFAULT) { + fprintf(where, + "send_xti_udp_stream: fault with signal set!\n"); + fflush(where); + exit(1); + } + interval_count = interval_burst; + } +#endif /* WANT_INTERVALS */ + + } + + /* This is a timed test, so the remote will be returning to us after */ + /* a time. We should not need to send any "strange" messages to tell */ + /* the remote that the test is completed, unless we decide to add a */ + /* number of messages to the test. */ + + /* the test is over, so get stats and stuff */ + cpu_stop(local_cpu_usage, + &elapsed_time); + + /* Get the statistics from the remote end */ + recv_response(); + if (!netperf_response.content.serv_errno) { + if (debug) + fprintf(where,"send_xti_udp_stream: remote results obtained\n"); + } + else { + Set_errno(netperf_response.content.serv_errno); + perror("send_xti_udp_stream: error on remote"); + exit(1); + } + + bytes_sent = (double) send_size * (double) messages_sent; + local_thruput = calc_thruput(bytes_sent); + + messages_recvd = xti_udp_stream_results->messages_recvd; + bytes_recvd = (double) send_size * (double) messages_recvd; + + /* we asume that the remote ran for as long as we did */ + + remote_thruput = calc_thruput(bytes_recvd); + + /* print the results for this socket and message size */ + + if (local_cpu_usage || remote_cpu_usage) { + /* We must now do a little math for service demand and cpu */ + /* utilization for the system(s) We pass zeros for the local */ + /* cpu utilization and elapsed time to tell the routine to use */ + /* the libraries own values for those. */ + if (local_cpu_usage) { + local_cpu_utilization = calc_cpu_util(0.0); + /* shouldn't this really be based on bytes_recvd, since that is */ + /* the effective throughput of the test? I think that it should, */ + /* so will make the change raj 11/94 */ + local_service_demand = calc_service_demand(bytes_recvd, + 0.0, + 0.0, + 0); + } + else { + local_cpu_utilization = -1.0; + local_service_demand = -1.0; + } + + /* The local calculations could use variables being kept by */ + /* the local netlib routines. The remote calcuations need to */ + /* have a few things passed to them. */ + if (remote_cpu_usage) { + remote_cpu_utilization = xti_udp_stream_results->cpu_util; + remote_service_demand = calc_service_demand(bytes_recvd, + 0.0, + remote_cpu_utilization, + xti_udp_stream_results->num_cpus); + } + else { + remote_cpu_utilization = -1.0; + remote_service_demand = -1.0; + } + } + else { + /* we were not measuring cpu, for the confidence stuff, we */ + /* should make it -1.0 */ + local_cpu_utilization = -1.0; + local_service_demand = -1.0; + remote_cpu_utilization = -1.0; + remote_service_demand = -1.0; + } + + /* at this point, we want to calculate the confidence information. */ + /* if debugging is on, calculate_confidence will print-out the */ + /* parameters we pass it */ + + calculate_confidence(confidence_iteration, + elapsed_time, + remote_thruput, + local_cpu_utilization, + remote_cpu_utilization, + local_service_demand, + remote_service_demand); + + /* since the routine calculate_confidence is rather generic, and */ + /* we have a few other parms of interest, we will do a little work */ + /* here to caclulate their average. */ + sum_messages_sent += messages_sent; + sum_messages_recvd += messages_recvd; + sum_failed_sends += failed_sends; + sum_local_thruput += local_thruput; + + confidence_iteration++; + + /* this datapoint is done, so we don't need the socket any longer */ + close(data_socket); + + } + + /* we should reach this point once the test is finished */ + + retrieve_confident_values(&elapsed_time, + &remote_thruput, + &local_cpu_utilization, + &remote_cpu_utilization, + &local_service_demand, + &remote_service_demand); + + /* some of the interesting values aren't covered by the generic */ + /* confidence routine */ + messages_sent = sum_messages_sent / (confidence_iteration -1); + messages_recvd = sum_messages_recvd / (confidence_iteration -1); + failed_sends = sum_failed_sends / (confidence_iteration -1); + local_thruput = sum_local_thruput / (confidence_iteration -1); + + /* We are now ready to print all the information. If the user */ + /* has specified zero-level verbosity, we will just print the */ + /* local service demand, or the remote service demand. If the */ + /* user has requested verbosity level 1, he will get the basic */ + /* "streamperf" numbers. If the user has specified a verbosity */ + /* of greater than 1, we will display a veritable plethora of */ + /* background information from outside of this block as it it */ + /* not cpu_measurement specific... */ + + + if (confidence < 0) { + /* we did not hit confidence, but were we asked to look for it? */ + if (iteration_max > 1) { + display_confidence(); + } + } + + if (local_cpu_usage || remote_cpu_usage) { + local_cpu_method = format_cpu_method(cpu_method); + remote_cpu_method = format_cpu_method(xti_udp_stream_results->cpu_method); + + switch (verbosity) { + case 0: + if (local_cpu_usage) { + fprintf(where, + cpu_fmt_0, + local_service_demand, + local_cpu_method); + } + else { + fprintf(where, + cpu_fmt_0, + remote_service_demand, + local_cpu_method); + } + break; + case 1: + case 2: + if (print_headers) { + fprintf(where, + cpu_title, + format_units(), + local_cpu_method, + remote_cpu_method); + } + + fprintf(where, + cpu_fmt_1, /* the format string */ + lss_size, /* local sendbuf size */ + send_size, /* how large were the sends */ + elapsed_time, /* how long was the test */ + messages_sent, + failed_sends, + local_thruput, /* what was the xfer rate */ + local_cpu_utilization, /* local cpu */ + local_service_demand, /* local service demand */ + rsr_size, + elapsed_time, + messages_recvd, + remote_thruput, + remote_cpu_utilization, /* remote cpu */ + remote_service_demand); /* remote service demand */ + break; + } + } + else { + /* The tester did not wish to measure service demand. */ + switch (verbosity) { + case 0: + fprintf(where, + tput_fmt_0, + local_thruput); + break; + case 1: + case 2: + if (print_headers) { + fprintf(where,tput_title,format_units()); + } + fprintf(where, + tput_fmt_1, /* the format string */ + lss_size, /* local sendbuf size */ + send_size, /* how large were the sends */ + elapsed_time, /* how long did it take */ + messages_sent, + failed_sends, + local_thruput, + rsr_size, /* remote recvbuf size */ + elapsed_time, + messages_recvd, + remote_thruput); + break; + } + } + + fflush(where); +#ifdef WANT_HISTOGRAM + if (verbosity > 1) { + fprintf(where,"\nHistogram of time spent in send() call\n"); + fflush(where); + HIST_report(time_hist); + } +#endif /* WANT_HISTOGRAM */ + +} + + + /* this routine implements the receive side (netserver) of the */ + /* XTI_UDP_STREAM performance test. */ + +void +recv_xti_udp_stream() +{ + struct ring_elt *recv_ring; + + struct t_bind bind_req, bind_resp; + struct t_unitdata unitdata; + int flags = 0; + + struct sockaddr_in myaddr_in; + struct sockaddr_in fromaddr_in; + + SOCKET s_data; + int addrlen; + unsigned int bytes_received = 0; + float elapsed_time; + + unsigned int message_size; + unsigned int messages_recvd = 0; + + struct xti_udp_stream_request_struct *xti_udp_stream_request; + struct xti_udp_stream_response_struct *xti_udp_stream_response; + struct xti_udp_stream_results_struct *xti_udp_stream_results; + + xti_udp_stream_request = + (struct xti_udp_stream_request_struct *)netperf_request.content.test_specific_data; + xti_udp_stream_response = + (struct xti_udp_stream_response_struct *)netperf_response.content.test_specific_data; + xti_udp_stream_results = + (struct xti_udp_stream_results_struct *)netperf_response.content.test_specific_data; + + if (debug) { + fprintf(where,"netserver: recv_xti_udp_stream: entered...\n"); + fflush(where); + } + + /* We want to set-up the listen socket with all the desired */ + /* parameters and then let the initiator know that all is ready. If */ + /* socket size defaults are to be used, then the initiator will have */ + /* sent us 0's. If the socket sizes cannot be changed, then we will */ + /* send-back what they are. If that information cannot be determined, */ + /* then we send-back -1's for the sizes. If things go wrong for any */ + /* reason, we will drop back ten yards and punt. */ + + /* If anything goes wrong, we want the remote to know about it. It */ + /* would be best if the error that the remote reports to the user is */ + /* the actual error we encountered, rather than some bogus unexpected */ + /* response type message. */ + + if (debug > 1) { + fprintf(where,"recv_xti_udp_stream: setting the response type...\n"); + fflush(where); + } + + netperf_response.content.response_type = XTI_UDP_STREAM_RESPONSE; + + if (debug > 2) { + fprintf(where,"recv_xti_udp_stream: the response type is set...\n"); + fflush(where); + } + + /* We now alter the message_ptr variable to be at the desired */ + /* alignment with the desired offset. */ + + if (debug > 1) { + fprintf(where,"recv_xti_udp_stream: requested alignment of %d\n", + xti_udp_stream_request->recv_alignment); + fflush(where); + } + + if (recv_width == 0) recv_width = 1; + + recv_ring = allocate_buffer_ring(recv_width, + xti_udp_stream_request->message_size, + xti_udp_stream_request->recv_alignment, + xti_udp_stream_request->recv_offset); + + if (debug > 1) { + fprintf(where,"recv_xti_udp_stream: receive alignment and offset set...\n"); + fflush(where); + } + + /* Let's clear-out our sockaddr for the sake of cleanlines. Then we */ + /* can put in OUR values !-) At some point, we may want to nail this */ + /* socket to a particular network-level address, but for now, */ + /* INADDR_ANY should be just fine. */ + + bzero((char *)&myaddr_in, + sizeof(myaddr_in)); + myaddr_in.sin_family = AF_INET; + myaddr_in.sin_addr.s_addr = INADDR_ANY; + myaddr_in.sin_port = 0; + + /* Grab a socket to listen on, and then listen on it. */ + + if (debug > 1) { + fprintf(where,"recv_xti_udp_stream: grabbing a socket...\n"); + fflush(where); + } + + /* create_xti_endpoint expects to find some things in the global */ + /* variables, so set the globals based on the values in the request. */ + /* once the socket has been created, we will set the response values */ + /* based on the updated value of those globals. raj 7/94 */ + lsr_size = xti_udp_stream_request->recv_buf_size; + loc_rcvavoid = xti_udp_stream_request->so_rcvavoid; + loc_sndavoid = xti_udp_stream_request->so_sndavoid; + +#ifdef __alpha + + /* ok - even on a DEC box, strings are strings. I din't really want */ + /* to ntohl the words of a string. since I don't want to teach the */ + /* send_ and recv_ _request and _response routines about the types, */ + /* I will put "anti-ntohl" calls here. I imagine that the "pure" */ + /* solution would be to use XDR, but I am still leary of being able */ + /* to find XDR libs on all platforms I want running netperf. raj */ + { + int *charword; + int *initword; + int *lastword; + + initword = (int *) xti_udp_stream_request->xti_device; + lastword = initword + ((xti_udp_stream_request->dev_name_len + 3) / 4); + + for (charword = initword; + charword < lastword; + charword++) { + + *charword = htonl(*charword); + } + } + +#endif /* __alpha */ + + s_data = create_xti_endpoint(xti_udp_stream_request->xti_device); + + if (s_data == INVALID_SOCKET) { + netperf_response.content.serv_errno = errno; + send_response(); + exit(1); + } + + /* Let's get an address assigned to this socket so we can tell the */ + /* initiator how to reach the data socket. There may be a desire to */ + /* nail this socket to a specific IP address in a multi-homed, */ + /* multi-connection situation, but for now, we'll ignore the issue */ + /* and concentrate on single connection testing. */ + + bind_req.addr.maxlen = sizeof(struct sockaddr_in); + bind_req.addr.len = sizeof(struct sockaddr_in); + bind_req.addr.buf = (char *)&myaddr_in; + bind_req.qlen = 1; + + bind_resp.addr.maxlen = sizeof(struct sockaddr_in); + bind_resp.addr.len = sizeof(struct sockaddr_in); + bind_resp.addr.buf = (char *)&myaddr_in; + bind_resp.qlen = 1; + + if (t_bind(s_data, + &bind_req, + &bind_resp) == SOCKET_ERROR) { + netperf_response.content.serv_errno = t_errno; + send_response(); + + exit(1); + } + + xti_udp_stream_response->test_length = + xti_udp_stream_request->test_length; + + /* Now myaddr_in contains the port and the internet address this is */ + /* returned to the sender also implicitly telling the sender that the */ + /* socket buffer sizing has been done. */ + + xti_udp_stream_response->data_port_number = + (int) ntohs(myaddr_in.sin_port); + netperf_response.content.serv_errno = 0; + + /* But wait, there's more. If the initiator wanted cpu measurements, */ + /* then we must call the calibrate routine, which will return the max */ + /* rate back to the initiator. If the CPU was not to be measured, or */ + /* something went wrong with the calibration, we will return a -1 to */ + /* the initiator. */ + + xti_udp_stream_response->cpu_rate = 0.0; /* assume no cpu */ + xti_udp_stream_response->measure_cpu = 0; + if (xti_udp_stream_request->measure_cpu) { + /* We will pass the rate into the calibration routine. If the */ + /* user did not specify one, it will be 0.0, and we will do a */ + /* "real" calibration. Otherwise, all it will really do is */ + /* store it away... */ + xti_udp_stream_response->measure_cpu = 1; + xti_udp_stream_response->cpu_rate = + calibrate_local_cpu(xti_udp_stream_request->cpu_rate); + } + + message_size = xti_udp_stream_request->message_size; + test_time = xti_udp_stream_request->test_length; + + /* before we send the response back to the initiator, pull some of */ + /* the socket parms from the globals */ + xti_udp_stream_response->send_buf_size = lss_size; + xti_udp_stream_response->recv_buf_size = lsr_size; + xti_udp_stream_response->so_rcvavoid = loc_rcvavoid; + xti_udp_stream_response->so_sndavoid = loc_sndavoid; + + /* since we are going to call t_rcvudata() instead of t_rcv() we */ + /* need to init the unitdata structure raj 3/95 */ + + unitdata.addr.maxlen = sizeof(fromaddr_in); + unitdata.addr.len = sizeof(fromaddr_in); + unitdata.addr.buf = (char *)&fromaddr_in; + + unitdata.opt.maxlen = 0; + unitdata.opt.len = 0; + unitdata.opt.buf = NULL; + + unitdata.udata.maxlen = xti_udp_stream_request->message_size; + unitdata.udata.len = xti_udp_stream_request->message_size; + unitdata.udata.buf = recv_ring->buffer_ptr; + + send_response(); + + /* Now it's time to start receiving data on the connection. We will */ + /* first grab the apropriate counters and then start grabbing. */ + + cpu_start(xti_udp_stream_request->measure_cpu); + + /* The loop will exit when the timer pops, or if we happen to recv a */ + /* message of less than send_size bytes... */ + + times_up = 0; + start_timer(test_time + PAD_TIME); + + if (debug) { + fprintf(where,"recv_xti_udp_stream: about to enter inner sanctum.\n"); + fflush(where); + } + + while (!times_up) { +#ifdef RAJ_DEBUG + if (debug) { + fprintf(where,"t_rcvudata, errno %d, t_errno %d", + errno, + t_errno); + fprintf(where," after %d messages\n",messages_recvd); + fprintf(where,"addrmax %d addrlen %d addrbuf %x\n", + unitdata.addr.maxlen, + unitdata.addr.len, + unitdata.addr.buf); + fprintf(where,"optmax %d optlen %d optbuf %x\n", + unitdata.opt.maxlen, + unitdata.opt.len, + unitdata.opt.buf); + fprintf(where,"udatamax %d udatalen %d udatabuf %x\n", + unitdata.udata.maxlen, + unitdata.udata.len, + unitdata.udata.buf); + fflush(where); + } +#endif /* RAJ_DEBUG */ + if (t_rcvudata(s_data, + &unitdata, + &flags) != 0) { + if (errno == TNODATA) { + continue; + } + if (errno != EINTR) { + netperf_response.content.serv_errno = t_errno; + send_response(); + exit(1); + } + break; + } + messages_recvd++; + recv_ring = recv_ring->next; + unitdata.udata.buf = recv_ring->buffer_ptr; + } + + if (debug) { + fprintf(where,"recv_xti_udp_stream: got %d messages.\n",messages_recvd); + fflush(where); + } + + + /* The loop now exits due timer or < send_size bytes received. */ + + cpu_stop(xti_udp_stream_request->measure_cpu,&elapsed_time); + + if (times_up) { + /* we ended on a timer, subtract the PAD_TIME */ + elapsed_time -= (float)PAD_TIME; + } + else { + stop_timer(); + } + + if (debug) { + fprintf(where,"recv_xti_udp_stream: test ended in %f seconds.\n",elapsed_time); + fflush(where); + } + + bytes_received = (messages_recvd * message_size); + + /* send the results to the sender */ + + if (debug) { + fprintf(where, + "recv_xti_udp_stream: got %d bytes\n", + bytes_received); + fflush(where); + } + + netperf_response.content.response_type = XTI_UDP_STREAM_RESULTS; + xti_udp_stream_results->bytes_received = bytes_received; + xti_udp_stream_results->messages_recvd = messages_recvd; + xti_udp_stream_results->elapsed_time = elapsed_time; + xti_udp_stream_results->cpu_method = cpu_method; + if (xti_udp_stream_request->measure_cpu) { + xti_udp_stream_results->cpu_util = calc_cpu_util(elapsed_time); + } + else { + xti_udp_stream_results->cpu_util = -1.0; + } + + if (debug > 1) { + fprintf(where, + "recv_xti_udp_stream: test complete, sending results.\n"); + fflush(where); + } + + send_response(); + +} + +void send_xti_udp_rr(char remote_host[]) +{ + + char *tput_title = "\ +Local /Remote\n\ +Socket Size Request Resp. Elapsed Trans.\n\ +Send Recv Size Size Time Rate \n\ +bytes Bytes bytes bytes secs. per sec \n\n"; + + char *tput_fmt_0 = + "%7.2f\n"; + + char *tput_fmt_1_line_1 = "\ +%-6d %-6d %-6d %-6d %-6.2f %7.2f \n"; + char *tput_fmt_1_line_2 = "\ +%-6d %-6d\n"; + + char *cpu_title = "\ +Local /Remote\n\ +Socket Size Request Resp. Elapsed Trans. CPU CPU S.dem S.dem\n\ +Send Recv Size Size Time Rate local remote local remote\n\ +bytes bytes bytes bytes secs. per sec %% %c %% %c us/Tr us/Tr\n\n"; + + char *cpu_fmt_0 = + "%6.3f %c\n"; + + char *cpu_fmt_1_line_1 = "\ +%-6d %-6d %-6d %-6d %-6.2f %-6.2f %-6.2f %-6.2f %-6.3f %-6.3f\n"; + + char *cpu_fmt_1_line_2 = "\ +%-6d %-6d\n"; + + char *ksink_fmt = "\ +Alignment Offset\n\ +Local Remote Local Remote\n\ +Send Recv Send Recv\n\ +%5d %5d %5d %5d\n"; + + + float elapsed_time; + + struct ring_elt *send_ring; + struct ring_elt *recv_ring; + + struct t_bind bind_req, bind_resp; + struct t_unitdata unitdata; + struct t_unitdata send_unitdata; + struct t_unitdata recv_unitdata; + int flags = 0; + + int len; + int nummessages; + SOCKET send_socket; + int trans_remaining; + int bytes_xferd; + + int rsp_bytes_recvd; + + float local_cpu_utilization; + float local_service_demand; + float remote_cpu_utilization; + float remote_service_demand; + double thruput; + + struct hostent *hp; + struct sockaddr_in server, myaddr_in; + unsigned int addr; + int addrlen; + + struct xti_udp_rr_request_struct *xti_udp_rr_request; + struct xti_udp_rr_response_struct *xti_udp_rr_response; + struct xti_udp_rr_results_struct *xti_udp_rr_result; + +#ifdef WANT_INTERVALS + int interval_count; + sigset_t signal_set; +#endif /* WANT_INTERVALS */ + + xti_udp_rr_request = + (struct xti_udp_rr_request_struct *)netperf_request.content.test_specific_data; + xti_udp_rr_response = + (struct xti_udp_rr_response_struct *)netperf_response.content.test_specific_data; + xti_udp_rr_result = + (struct xti_udp_rr_results_struct *)netperf_response.content.test_specific_data; + +#ifdef WANT_HISTOGRAM + time_hist = HIST_new(); +#endif + + /* since we are now disconnected from the code that established the */ + /* control socket, and since we want to be able to use different */ + /* protocols and such, we are passed the name of the remote host and */ + /* must turn that into the test specific addressing information. */ + + bzero((char *)&server, + sizeof(server)); + + /* it would seem that while HP-UX will allow an IP address (as a */ + /* string) in a call to gethostbyname, other, less enlightened */ + /* systems do not. fix from awjacks@ca.sandia.gov raj 10/95 */ + /* order changed to check for IP address first. raj 7/96 */ + + if ((addr = inet_addr(remote_host)) == SOCKET_ERROR) { + /* it was not an IP address, try it as a name */ + if ((hp = gethostbyname(remote_host)) == NULL) { + /* we have no idea what it is */ + fprintf(where, + "establish_control: could not resolve the destination %s\n", + remote_host); + fflush(where); + exit(1); + } + else { + /* it was a valid remote_host */ + bcopy(hp->h_addr, + (char *)&server.sin_addr, + hp->h_length); + server.sin_family = hp->h_addrtype; + } + } + else { + /* it was a valid IP address */ + server.sin_addr.s_addr = addr; + server.sin_family = AF_INET; + } + + if ( print_headers ) { + fprintf(where,"XTI UDP REQUEST/RESPONSE TEST"); + fprintf(where," to %s", remote_host); + if (iteration_max > 1) { + fprintf(where, + " : +/-%3.1f%% @ %2d%% conf.", + interval/0.02, + confidence_level); + } + if (loc_sndavoid || + loc_rcvavoid || + rem_sndavoid || + rem_rcvavoid) { + fprintf(where," : copy avoidance"); + } +#ifdef WANT_HISTOGRAM + fprintf(where," : histogram"); +#endif /* WANT_HISTOGRAM */ +#ifdef WANT_INTERVALS + fprintf(where," : interval"); +#endif /* WANT_INTERVALS */ +#ifdef DIRTY + fprintf(where," : dirty data"); +#endif /* DIRTY */ + fprintf(where,"\n"); + } + + /* initialize a few counters */ + + send_ring = NULL; + recv_ring = NULL; + nummessages = 0; + bytes_xferd = 0; + times_up = 0; + confidence_iteration = 1; + init_stat(); + + + /* we have a great-big while loop which controls the number of times */ + /* we run a particular test. this is for the calculation of a */ + /* confidence interval (I really should have stayed awake during */ + /* probstats :). If the user did not request confidence measurement */ + /* (no confidence is the default) then we will only go though the */ + /* loop once. the confidence stuff originates from the folks at IBM */ + + while (((confidence < 0) && (confidence_iteration < iteration_max)) || + (confidence_iteration <= iteration_min)) { + + nummessages = 0; + bytes_xferd = 0.0; + times_up = 0; + trans_remaining = 0; + + /* set-up the data buffers with the requested alignment and offset */ + + if (send_width == 0) send_width = 1; + if (recv_width == 0) recv_width = 1; + + if (send_ring == NULL) { + send_ring = allocate_buffer_ring(send_width, + req_size, + local_send_align, + local_send_offset); + } + + if (recv_ring == NULL) { + recv_ring = allocate_buffer_ring(recv_width, + rsp_size, + local_recv_align, + local_recv_offset); + } + + /* since we are going to call t_rcvudata() instead of t_rcv() we */ + /* need to init the unitdata structure raj 8/95 */ + + memset (&recv_unitdata, 0, sizeof(recv_unitdata)); + recv_unitdata.addr.maxlen = sizeof(struct sockaddr_in); + recv_unitdata.addr.len = sizeof(struct sockaddr_in); + recv_unitdata.addr.buf = (char *)&server; + + recv_unitdata.opt.maxlen = 0; + recv_unitdata.opt.len = 0; + recv_unitdata.opt.buf = NULL; + + recv_unitdata.udata.maxlen = rsp_size; + recv_unitdata.udata.len = rsp_size; + recv_unitdata.udata.buf = recv_ring->buffer_ptr; + + /* since we are going to call t_sndudata() instead of t_snd() we */ + /* need to init the unitdata structure raj 8/95 */ + + memset (&send_unitdata, 0, sizeof(send_unitdata)); + send_unitdata.addr.maxlen = sizeof(struct sockaddr_in); + send_unitdata.addr.len = sizeof(struct sockaddr_in); + send_unitdata.addr.buf = (char *)&server; + + send_unitdata.opt.maxlen = 0; + send_unitdata.opt.len = 0; + send_unitdata.opt.buf = NULL; + + send_unitdata.udata.maxlen = req_size; + send_unitdata.udata.len = req_size; + send_unitdata.udata.buf = send_ring->buffer_ptr; + + /*set up the data socket */ + send_socket = create_xti_endpoint(loc_xti_device); + + if (send_socket == INVALID_SOCKET){ + perror("netperf: send_xti_udp_rr: udp rr data socket"); + exit(1); + } + + if (debug) { + fprintf(where,"send_xti_udp_rr: send_socket obtained...\n"); + } + + /* it would seem that with XTI, there is no implicit bind */ + /* so we have to make a call to t_bind. this is not */ + /* terribly convenient, but I suppose that "standard is better */ + /* than better" :) raj 2/95 */ + + if (t_bind(send_socket, NULL, NULL) == SOCKET_ERROR) { + t_error("send_xti_tcp_stream: t_bind"); + exit(1); + } + + /* If the user has requested cpu utilization measurements, we must */ + /* calibrate the cpu(s). We will perform this task within the tests */ + /* themselves. If the user has specified the cpu rate, then */ + /* calibrate_local_cpu will return rather quickly as it will have */ + /* nothing to do. If local_cpu_rate is zero, then we will go through */ + /* all the "normal" calibration stuff and return the rate back. If */ + /* there is no idle counter in the kernel idle loop, the */ + /* local_cpu_rate will be set to -1. */ + + if (local_cpu_usage) { + local_cpu_rate = calibrate_local_cpu(local_cpu_rate); + } + + /* Tell the remote end to do a listen. The server alters the socket */ + /* paramters on the other side at this point, hence the reason for */ + /* all the values being passed in the setup message. If the user did */ + /* not specify any of the parameters, they will be passed as 0, which */ + /* will indicate to the remote that no changes beyond the system's */ + /* default should be used. Alignment is the exception, it will */ + /* default to 8, which will be no alignment alterations. */ + + netperf_request.content.request_type = DO_XTI_UDP_RR; + xti_udp_rr_request->recv_buf_size = rsr_size; + xti_udp_rr_request->send_buf_size = rss_size; + xti_udp_rr_request->recv_alignment = remote_recv_align; + xti_udp_rr_request->recv_offset = remote_recv_offset; + xti_udp_rr_request->send_alignment = remote_send_align; + xti_udp_rr_request->send_offset = remote_send_offset; + xti_udp_rr_request->request_size = req_size; + xti_udp_rr_request->response_size = rsp_size; + xti_udp_rr_request->measure_cpu = remote_cpu_usage; + xti_udp_rr_request->cpu_rate = remote_cpu_rate; + xti_udp_rr_request->so_rcvavoid = rem_rcvavoid; + xti_udp_rr_request->so_sndavoid = rem_sndavoid; + if (test_time) { + xti_udp_rr_request->test_length = test_time; + } + else { + xti_udp_rr_request->test_length = test_trans * -1; + } + + strcpy(xti_udp_rr_request->xti_device, rem_xti_device); + +#ifdef __alpha + + /* ok - even on a DEC box, strings are strings. I didn't really want */ + /* to ntohl the words of a string. since I don't want to teach the */ + /* send_ and recv_ _request and _response routines about the types, */ + /* I will put "anti-ntohl" calls here. I imagine that the "pure" */ + /* solution would be to use XDR, but I am still leary of being able */ + /* to find XDR libs on all platforms I want running netperf. raj */ + { + int *charword; + int *initword; + int *lastword; + + initword = (int *) xti_udp_rr_request->xti_device; + lastword = initword + ((strlen(rem_xti_device) + 3) / 4); + + for (charword = initword; + charword < lastword; + charword++) { + + *charword = ntohl(*charword); + } + } +#endif /* __alpha */ + + if (debug > 1) { + fprintf(where,"netperf: send_xti_udp_rr: requesting UDP r/r test\n"); + } + + send_request(); + + /* The response from the remote will contain all of the relevant */ + /* socket parameters for this test type. We will put them back into */ + /* the variables here so they can be displayed if desired. The */ + /* remote will have calibrated CPU if necessary, and will have done */ + /* all the needed set-up we will have calibrated the cpu locally */ + /* before sending the request, and will grab the counter value right*/ + /* after the connect returns. The remote will grab the counter right*/ + /* after the accept call. This saves the hassle of extra messages */ + /* being sent for the UDP tests. */ + + recv_response(); + + if (!netperf_response.content.serv_errno) { + if (debug) + fprintf(where,"remote listen done.\n"); + rsr_size = xti_udp_rr_response->recv_buf_size; + rss_size = xti_udp_rr_response->send_buf_size; + remote_cpu_usage = xti_udp_rr_response->measure_cpu; + remote_cpu_rate = xti_udp_rr_response->cpu_rate; + /* port numbers in proper order */ + server.sin_port = (short)xti_udp_rr_response->data_port_number; + server.sin_port = htons(server.sin_port); + } + else { + Set_errno(netperf_response.content.serv_errno); + perror("netperf: remote error"); + + exit(1); + } + + /* Data Socket set-up is finished. If there were problems, either the */ + /* connect would have failed, or the previous response would have */ + /* indicated a problem. I failed to see the value of the extra */ + /* message after the accept on the remote. If it failed, we'll see it */ + /* here. If it didn't, we might as well start pumping data. */ + + /* Set-up the test end conditions. For a request/response test, they */ + /* can be either time or transaction based. */ + + if (test_time) { + /* The user wanted to end the test after a period of time. */ + times_up = 0; + trans_remaining = 0; + start_timer(test_time); + } + else { + /* The tester wanted to send a number of bytes. */ + trans_remaining = test_bytes; + times_up = 1; + } + + /* The cpu_start routine will grab the current time and possibly */ + /* value of the idle counter for later use in measuring cpu */ + /* utilization and/or service demand and thruput. */ + + cpu_start(local_cpu_usage); + +#ifdef WANT_INTERVALS + if ((interval_burst) || (demo_mode)) { + /* zero means that we never pause, so we never should need the */ + /* interval timer, unless we are in demo_mode */ + start_itimer(interval_wate); + } + interval_count = interval_burst; + /* get the signal set for the call to sigsuspend */ + if (sigprocmask(SIG_BLOCK, (sigset_t *)NULL, &signal_set) != 0) { + fprintf(where, + "send_xti_udp_rr: unable to get sigmask errno %d\n", + errno); + fflush(where); + exit(1); + } +#endif /* WANT_INTERVALS */ + + /* We use an "OR" to control test execution. When the test is */ + /* controlled by time, the byte count check will always return */ + /* false. When the test is controlled by byte count, the time test */ + /* will always return false. When the test is finished, the whole */ + /* expression will go false and we will stop sending data. I think */ + /* I just arbitrarily decrement trans_remaining for the timed */ + /* test, but will not do that just yet... One other question is */ + /* whether or not the send buffer and the receive buffer should be */ + /* the same buffer. */ + + while ((!times_up) || (trans_remaining > 0)) { + /* send the request */ +#ifdef WANT_HISTOGRAM + HIST_timestamp(&time_one); +#endif + if((t_sndudata(send_socket, + &send_unitdata)) != 0) { + if (errno == EINTR) { + /* We likely hit */ + /* test-end time. */ + break; + } + fprintf(where, + "send_xti_udp_rr: t_sndudata: errno %d t_errno %d t_look 0x%.4x\n", + errno, + t_errno, + t_look(send_socket)); + fflush(where); + exit(1); + } + send_ring = send_ring->next; + + /* receive the response. with UDP we will get it all, or nothing */ + + if((t_rcvudata(send_socket, + &recv_unitdata, + &flags)) != 0) { + if (errno == TNODATA) { + continue; + } + if (errno == EINTR) { + /* Again, we have likely hit test-end time */ + break; + } + fprintf(where, + "send_xti_udp_rr: t_rcvudata: errno %d t_errno %d t_look 0x%x\n", + errno, + t_errno, + t_look(send_socket)); + fprintf(where, + "recv_unitdata.udata.buf %x\n",recv_unitdata.udata.buf); + fprintf(where, + "recv_unitdata.udata.maxlen %x\n",recv_unitdata.udata.maxlen); + fprintf(where, + "recv_unitdata.udata.len %x\n",recv_unitdata.udata.len); + fprintf(where, + "recv_unitdata.addr.buf %x\n",recv_unitdata.addr.buf); + fprintf(where, + "recv_unitdata.addr.maxlen %x\n",recv_unitdata.addr.maxlen); + fprintf(where, + "recv_unitdata.addr.len %x\n",recv_unitdata.addr.len); + fflush(where); + exit(1); + } + recv_ring = recv_ring->next; + +#ifdef WANT_HISTOGRAM + HIST_timestamp(&time_two); + HIST_add(time_hist,delta_micro(&time_one,&time_two)); + + /* at this point, we may wish to sleep for some period of */ + /* time, so we see how long that last transaction just took, */ + /* and sleep for the difference of that and the interval. We */ + /* will not sleep if the time would be less than a */ + /* millisecond. */ +#endif +#ifdef WANT_INTERVALS + if (demo_mode) { + units_this_tick += 1; + } + /* in this case, the interval count is the count-down couter */ + /* to decide to sleep for a little bit */ + if ((interval_burst) && (--interval_count == 0)) { + /* call sigsuspend and wait for the interval timer to get us */ + /* out */ + if (debug) { + fprintf(where,"about to suspend\n"); + fflush(where); + } + if (sigsuspend(&signal_set) == EFAULT) { + fprintf(where, + "send_xti_udp_rr: fault with signal set!\n"); + fflush(where); + exit(1); + } + interval_count = interval_burst; + } +#endif /* WANT_INTERVALS */ + + nummessages++; + if (trans_remaining) { + trans_remaining--; + } + + if (debug > 3) { + if ((nummessages % 100) == 0) { + fprintf(where,"Transaction %d completed\n",nummessages); + fflush(where); + } + } + + } + + /* this call will always give us the elapsed time for the test, and */ + /* will also store-away the necessaries for cpu utilization */ + + cpu_stop(local_cpu_usage,&elapsed_time); /* was cpu being */ + /* measured? how long */ + /* did we really run? */ + + /* Get the statistics from the remote end. The remote will have */ + /* calculated service demand and all those interesting things. If */ + /* it wasn't supposed to care, it will return obvious values. */ + + recv_response(); + if (!netperf_response.content.serv_errno) { + if (debug) + fprintf(where,"remote results obtained\n"); + } + else { + Set_errno(netperf_response.content.serv_errno); + perror("netperf: remote error"); + + exit(1); + } + + /* We now calculate what our thruput was for the test. In the */ + /* future, we may want to include a calculation of the thruput */ + /* measured by the remote, but it should be the case that for a */ + /* UDP rr test, that the two numbers should be *very* close... */ + /* We calculate bytes_sent regardless of the way the test length */ + /* was controlled. */ + + bytes_xferd = (req_size * nummessages) + (rsp_size * nummessages); + thruput = nummessages / elapsed_time; + + if (local_cpu_usage || remote_cpu_usage) { + + /* We must now do a little math for service demand and cpu */ + /* utilization for the system(s) Of course, some of the */ + /* information might be bogus because there was no idle counter */ + /* in the kernel(s). We need to make a note of this for the */ + /* user's benefit by placing a code for the metod used in the */ + /* test banner */ + + if (local_cpu_usage) { + local_cpu_utilization = calc_cpu_util(0.0); + + /* since calc_service demand is doing ms/Kunit we will */ + /* multiply the number of transaction by 1024 to get */ + /* "good" numbers */ + + local_service_demand = calc_service_demand((double) nummessages*1024, + 0.0, + 0.0, + 0); + } + else { + local_cpu_utilization = -1.0; + local_service_demand = -1.0; + } + + if (remote_cpu_usage) { + remote_cpu_utilization = xti_udp_rr_result->cpu_util; + + /* since calc_service demand is doing ms/Kunit we will */ + /* multiply the number of transaction by 1024 to get */ + /* "good" numbers */ + + remote_service_demand = calc_service_demand((double) nummessages*1024, + 0.0, + remote_cpu_utilization, + xti_udp_rr_result->num_cpus); + } + else { + remote_cpu_utilization = -1.0; + remote_service_demand = -1.0; + } + } + else { + /* we were not measuring cpu, for the confidence stuff, we */ + /* should make it -1.0 */ + local_cpu_utilization = -1.0; + local_service_demand = -1.0; + remote_cpu_utilization = -1.0; + remote_service_demand = -1.0; + } + + /* at this point, we want to calculate the confidence information. */ + /* if debugging is on, calculate_confidence will print-out the */ + /* parameters we pass it */ + + calculate_confidence(confidence_iteration, + elapsed_time, + thruput, + local_cpu_utilization, + remote_cpu_utilization, + local_service_demand, + remote_service_demand); + + + confidence_iteration++; + + /* we are done with the socket */ + t_close(send_socket); + } + + /* at this point, we have made all the iterations we are going to */ + /* make. */ + retrieve_confident_values(&elapsed_time, + &thruput, + &local_cpu_utilization, + &remote_cpu_utilization, + &local_service_demand, + &remote_service_demand); + + /* We are now ready to print all the information. If the user */ + /* has specified zero-level verbosity, we will just print the */ + /* local service demand, or the remote service demand. If the */ + /* user has requested verbosity level 1, he will get the basic */ + /* "streamperf" numbers. If the user has specified a verbosity */ + /* of greater than 1, we will display a veritable plethora of */ + /* background information from outside of this block as it it */ + /* not cpu_measurement specific... */ + + if (confidence < 0) { + /* we did not hit confidence, but were we asked to look for it? */ + if (iteration_max > 1) { + display_confidence(); + } + } + + if (local_cpu_usage || remote_cpu_usage) { + local_cpu_method = format_cpu_method(cpu_method); + remote_cpu_method = format_cpu_method(xti_udp_rr_result->cpu_method); + + switch (verbosity) { + case 0: + if (local_cpu_usage) { + fprintf(where, + cpu_fmt_0, + local_service_demand, + local_cpu_method); + } + else { + fprintf(where, + cpu_fmt_0, + remote_service_demand, + remote_cpu_method); + } + break; + case 1: + case 2: + if (print_headers) { + fprintf(where, + cpu_title, + local_cpu_method, + remote_cpu_method); + } + + fprintf(where, + cpu_fmt_1_line_1, /* the format string */ + lss_size, /* local sendbuf size */ + lsr_size, + req_size, /* how large were the requests */ + rsp_size, /* guess */ + elapsed_time, /* how long was the test */ + nummessages/elapsed_time, + local_cpu_utilization, /* local cpu */ + remote_cpu_utilization, /* remote cpu */ + local_service_demand, /* local service demand */ + remote_service_demand); /* remote service demand */ + fprintf(where, + cpu_fmt_1_line_2, + rss_size, + rsr_size); + break; + } + } + else { + /* The tester did not wish to measure service demand. */ + switch (verbosity) { + case 0: + fprintf(where, + tput_fmt_0, + nummessages/elapsed_time); + break; + case 1: + case 2: + if (print_headers) { + fprintf(where,tput_title,format_units()); + } + + fprintf(where, + tput_fmt_1_line_1, /* the format string */ + lss_size, + lsr_size, + req_size, /* how large were the requests */ + rsp_size, /* how large were the responses */ + elapsed_time, /* how long did it take */ + nummessages/elapsed_time); + fprintf(where, + tput_fmt_1_line_2, + rss_size, /* remote recvbuf size */ + rsr_size); + + break; + } + } + fflush(where); + + /* it would be a good thing to include information about some of the */ + /* other parameters that may have been set for this test, but at the */ + /* moment, I do not wish to figure-out all the formatting, so I will */ + /* just put this comment here to help remind me that it is something */ + /* that should be done at a later time. */ + + /* how to handle the verbose information in the presence of */ + /* confidence intervals is yet to be determined... raj 11/94 */ + + if (verbosity > 1) { + /* The user wanted to know it all, so we will give it to him. */ + /* This information will include as much as we can find about */ + /* UDP statistics, the alignments of the sends and receives */ + /* and all that sort of rot... */ + +#ifdef WANT_HISTOGRAM + fprintf(where,"\nHistogram of request/reponse times.\n"); + fflush(where); + HIST_report(time_hist); +#endif /* WANT_HISTOGRAM */ + } +} + + /* this routine implements the receive side (netserver) of a XTI_UDP_RR */ + /* test. */ +void + recv_xti_udp_rr() +{ + + struct ring_elt *recv_ring; + struct ring_elt *send_ring; + + struct t_bind bind_req, bind_resp; + struct t_unitdata send_unitdata; + struct t_unitdata recv_unitdata; + int flags = 0; + + struct sockaddr_in myaddr_in, peeraddr_in; + SOCKET s_data; + int addrlen; + int trans_received; + int trans_remaining; + float elapsed_time; + + struct xti_udp_rr_request_struct *xti_udp_rr_request; + struct xti_udp_rr_response_struct *xti_udp_rr_response; + struct xti_udp_rr_results_struct *xti_udp_rr_results; + + + /* a little variable initialization */ + memset (&myaddr_in, 0, sizeof(struct sockaddr_in)); + myaddr_in.sin_family = AF_INET; + myaddr_in.sin_addr.s_addr = INADDR_ANY; + myaddr_in.sin_port = 0; + memset (&peeraddr_in, 0, sizeof(struct sockaddr_in)); + + /* and some not so paranoid :) */ + xti_udp_rr_request = + (struct xti_udp_rr_request_struct *)netperf_request.content.test_specific_data; + xti_udp_rr_response = + (struct xti_udp_rr_response_struct *)netperf_response.content.test_specific_data; + xti_udp_rr_results = + (struct xti_udp_rr_results_struct *)netperf_response.content.test_specific_data; + + if (debug) { + fprintf(where,"netserver: recv_xti_udp_rr: entered...\n"); + fflush(where); + } + + /* We want to set-up the listen socket with all the desired */ + /* parameters and then let the initiator know that all is ready. If */ + /* socket size defaults are to be used, then the initiator will have */ + /* sent us 0's. If the socket sizes cannot be changed, then we will */ + /* send-back what they are. If that information cannot be determined, */ + /* then we send-back -1's for the sizes. If things go wrong for any */ + /* reason, we will drop back ten yards and punt. */ + + /* If anything goes wrong, we want the remote to know about it. It */ + /* would be best if the error that the remote reports to the user is */ + /* the actual error we encountered, rather than some bogus unexpected */ + /* response type message. */ + + if (debug) { + fprintf(where,"recv_xti_udp_rr: setting the response type...\n"); + fflush(where); + } + + netperf_response.content.response_type = XTI_UDP_RR_RESPONSE; + + if (debug) { + fprintf(where,"recv_xti_udp_rr: the response type is set...\n"); + fflush(where); + } + + /* We now alter the message_ptr variables to be at the desired */ + /* alignments with the desired offsets. */ + + if (debug) { + fprintf(where,"recv_xti_udp_rr: requested recv alignment of %d offset %d\n", + xti_udp_rr_request->recv_alignment, + xti_udp_rr_request->recv_offset); + fprintf(where,"recv_xti_udp_rr: requested send alignment of %d offset %d\n", + xti_udp_rr_request->send_alignment, + xti_udp_rr_request->send_offset); + fflush(where); + } + + if (send_width == 0) send_width = 1; + if (recv_width == 0) recv_width = 1; + + recv_ring = allocate_buffer_ring(recv_width, + xti_udp_rr_request->request_size, + xti_udp_rr_request->recv_alignment, + xti_udp_rr_request->recv_offset); + + send_ring = allocate_buffer_ring(send_width, + xti_udp_rr_request->response_size, + xti_udp_rr_request->send_alignment, + xti_udp_rr_request->send_offset); + + if (debug) { + fprintf(where,"recv_xti_udp_rr: receive alignment and offset set...\n"); + fflush(where); + } + + /* create_xti_endpoint expects to find some things in the global */ + /* variables, so set the globals based on the values in the request. */ + /* once the socket has been created, we will set the response values */ + /* based on the updated value of those globals. raj 7/94 */ + lss_size = xti_udp_rr_request->send_buf_size; + lsr_size = xti_udp_rr_request->recv_buf_size; + loc_rcvavoid = xti_udp_rr_request->so_rcvavoid; + loc_sndavoid = xti_udp_rr_request->so_sndavoid; + +#ifdef __alpha + + /* ok - even on a DEC box, strings are strings. I din't really want */ + /* to ntohl the words of a string. since I don't want to teach the */ + /* send_ and recv_ _request and _response routines about the types, */ + /* I will put "anti-ntohl" calls here. I imagine that the "pure" */ + /* solution would be to use XDR, but I am still leary of being able */ + /* to find XDR libs on all platforms I want running netperf. raj */ + { + int *charword; + int *initword; + int *lastword; + + initword = (int *) xti_udp_rr_request->xti_device; + lastword = initword + ((xti_udp_rr_request->dev_name_len + 3) / 4); + + for (charword = initword; + charword < lastword; + charword++) { + + *charword = htonl(*charword); + } + } + +#endif /* __alpha */ + + s_data = create_xti_endpoint(xti_udp_rr_request->xti_device); + + if (s_data == INVALID_SOCKET) { + netperf_response.content.serv_errno = errno; + send_response(); + exit(1); + } + + if (debug) { + fprintf(where,"recv_xti_udp_rr: endpoint created...\n"); + fflush(where); + } + + /* Let's get an address assigned to this socket so we can tell the */ + /* initiator how to reach the data socket. There may be a desire to */ + /* nail this socket to a specific IP address in a multi-homed, */ + /* multi-connection situation, but for now, we'll ignore the issue */ + /* and concentrate on single connection testing. */ + + bind_req.addr.maxlen = sizeof(struct sockaddr_in); + bind_req.addr.len = sizeof(struct sockaddr_in); + bind_req.addr.buf = (char *)&myaddr_in; + bind_req.qlen = 1; + + bind_resp.addr.maxlen = sizeof(struct sockaddr_in); + bind_resp.addr.len = sizeof(struct sockaddr_in); + bind_resp.addr.buf = (char *)&myaddr_in; + bind_resp.qlen = 1; + + if (t_bind(s_data, + &bind_req, + &bind_resp) == SOCKET_ERROR) { + if (debug) { + fprintf(where, + "recv_xti_udp_rr: t_bind failed, t_errno %d errno %d\n", + t_errno, + errno); + fflush(where); + } + + netperf_response.content.serv_errno = t_errno; + send_response(); + + exit(1); + } + + if (debug) { + fprintf(where, + "recv_xti_udp_rr: endpoint bound to port %d...\n", + ntohs(myaddr_in.sin_port)); + fflush(where); + } + + xti_udp_rr_response->test_length = + xti_udp_rr_request->test_length; + + + /* Now myaddr_in contains the port and the internet address this is */ + /* returned to the sender also implicitly telling the sender that the */ + /* socket buffer sizing has been done. */ + + xti_udp_rr_response->data_port_number = (int) ntohs(myaddr_in.sin_port); + netperf_response.content.serv_errno = 0; + + fprintf(where,"recv port number %d\n",myaddr_in.sin_port); + fflush(where); + + /* But wait, there's more. If the initiator wanted cpu measurements, */ + /* then we must call the calibrate routine, which will return the max */ + /* rate back to the initiator. If the CPU was not to be measured, or */ + /* something went wrong with the calibration, we will return a 0.0 to */ + /* the initiator. */ + + xti_udp_rr_response->cpu_rate = 0.0; /* assume no cpu */ + xti_udp_rr_response->measure_cpu = 0; + if (xti_udp_rr_request->measure_cpu) { + xti_udp_rr_response->measure_cpu = 1; + xti_udp_rr_response->cpu_rate = + calibrate_local_cpu(xti_udp_rr_request->cpu_rate); + } + + /* before we send the response back to the initiator, pull some of */ + /* the socket parms from the globals */ + xti_udp_rr_response->send_buf_size = lss_size; + xti_udp_rr_response->recv_buf_size = lsr_size; + xti_udp_rr_response->so_rcvavoid = loc_rcvavoid; + xti_udp_rr_response->so_sndavoid = loc_sndavoid; + + /* since we are going to call t_rcvudata() instead of t_rcv() we */ + /* need to init the unitdata structure raj 3/95 */ + + memset (&recv_unitdata, 0, sizeof(recv_unitdata)); + recv_unitdata.addr.maxlen = sizeof(struct sockaddr_in); + recv_unitdata.addr.len = sizeof(struct sockaddr_in); + recv_unitdata.addr.buf = (char *)&peeraddr_in; + + recv_unitdata.opt.maxlen = 0; + recv_unitdata.opt.len = 0; + recv_unitdata.opt.buf = NULL; + + recv_unitdata.udata.maxlen = xti_udp_rr_request->request_size; + recv_unitdata.udata.len = xti_udp_rr_request->request_size; + recv_unitdata.udata.buf = recv_ring->buffer_ptr; + + /* since we are going to call t_sndudata() instead of t_snd() we */ + /* need to init the unitdata structure raj 8/95 */ + + memset (&send_unitdata, 0, sizeof(send_unitdata)); + send_unitdata.addr.maxlen = sizeof(struct sockaddr_in); + send_unitdata.addr.len = sizeof(struct sockaddr_in); + send_unitdata.addr.buf = (char *)&peeraddr_in; + + send_unitdata.opt.maxlen = 0; + send_unitdata.opt.len = 0; + send_unitdata.opt.buf = NULL; + + send_unitdata.udata.maxlen = xti_udp_rr_request->response_size; + send_unitdata.udata.len = xti_udp_rr_request->response_size; + send_unitdata.udata.buf = send_ring->buffer_ptr; + + send_response(); + + + /* Now it's time to start receiving data on the connection. We will */ + /* first grab the apropriate counters and then start grabbing. */ + + cpu_start(xti_udp_rr_request->measure_cpu); + + if (xti_udp_rr_request->test_length > 0) { + times_up = 0; + trans_remaining = 0; + start_timer(xti_udp_rr_request->test_length + PAD_TIME); + } + else { + times_up = 1; + trans_remaining = xti_udp_rr_request->test_length * -1; + } + + addrlen = sizeof(peeraddr_in); + bzero((char *)&peeraddr_in, addrlen); + + trans_received = 0; + + while ((!times_up) || (trans_remaining > 0)) { + + /* receive the request from the other side */ + if (t_rcvudata(s_data, + &recv_unitdata, + &flags) != 0) { + if (errno == TNODATA) { + continue; + } + if (errno == EINTR) { + /* we must have hit the end of test time. */ + break; + } + if (debug) { + fprintf(where, + "recv_xti_udp_rr: t_rcvudata failed, t_errno %d errno %d\n", + t_errno, + errno); + fflush(where); + } + netperf_response.content.serv_errno = t_errno; + send_response(); + exit(1); + } + recv_ring = recv_ring->next; + recv_unitdata.udata.buf = recv_ring->buffer_ptr; + + /* Now, send the response to the remote */ + if (t_sndudata(s_data, + &send_unitdata) != 0) { + if (errno == EINTR) { + /* we have hit end of test time. */ + break; + } + if (debug) { + fprintf(where, + "recv_xti_udp_rr: t_sndudata failed, t_errno %d errno %d\n", + t_errno, + errno); + fflush(where); + } + netperf_response.content.serv_errno = errno; + send_response(); + exit(1); + } + send_ring = send_ring->next; + send_unitdata.udata.buf = send_ring->buffer_ptr; + + trans_received++; + if (trans_remaining) { + trans_remaining--; + } + + if (debug) { + fprintf(where, + "recv_xti_udp_rr: Transaction %d complete.\n", + trans_received); + fflush(where); + } + + } + + + /* The loop now exits due to timeout or transaction count being */ + /* reached */ + + cpu_stop(xti_udp_rr_request->measure_cpu,&elapsed_time); + + if (times_up) { + /* we ended the test by time, which was at least 2 seconds */ + /* longer than we wanted to run. so, we want to subtract */ + /* PAD_TIME from the elapsed_time. */ + elapsed_time -= PAD_TIME; + } + /* send the results to the sender */ + + if (debug) { + fprintf(where, + "recv_xti_udp_rr: got %d transactions\n", + trans_received); + fflush(where); + } + + xti_udp_rr_results->bytes_received = (trans_received * + (xti_udp_rr_request->request_size + + xti_udp_rr_request->response_size)); + xti_udp_rr_results->trans_received = trans_received; + xti_udp_rr_results->elapsed_time = elapsed_time; + xti_udp_rr_results->cpu_method = cpu_method; + if (xti_udp_rr_request->measure_cpu) { + xti_udp_rr_results->cpu_util = calc_cpu_util(elapsed_time); + } + + if (debug) { + fprintf(where, + "recv_xti_udp_rr: test complete, sending results.\n"); + fflush(where); + } + + send_response(); + + /* we are done with the socket now */ + close(s_data); + +} + + /* this routine implements the receive (netserver) side of a XTI_TCP_RR */ + /* test */ +void +recv_xti_tcp_rr() +{ + + struct ring_elt *send_ring; + struct ring_elt *recv_ring; + + struct sockaddr_in myaddr_in, peeraddr_in; + struct t_bind bind_req, bind_resp; + struct t_call call_req; + + SOCKET s_listen,s_data; + int addrlen; + char *temp_message_ptr; + int trans_received; + int trans_remaining; + int bytes_sent; + int request_bytes_recvd; + int request_bytes_remaining; + int timed_out = 0; + float elapsed_time; + + struct xti_tcp_rr_request_struct *xti_tcp_rr_request; + struct xti_tcp_rr_response_struct *xti_tcp_rr_response; + struct xti_tcp_rr_results_struct *xti_tcp_rr_results; + + xti_tcp_rr_request = + (struct xti_tcp_rr_request_struct *)netperf_request.content.test_specific_data; + xti_tcp_rr_response = + (struct xti_tcp_rr_response_struct *)netperf_response.content.test_specific_data; + xti_tcp_rr_results = + (struct xti_tcp_rr_results_struct *)netperf_response.content.test_specific_data; + + if (debug) { + fprintf(where,"netserver: recv_xti_tcp_rr: entered...\n"); + fflush(where); + } + + /* We want to set-up the listen socket with all the desired */ + /* parameters and then let the initiator know that all is ready. If */ + /* socket size defaults are to be used, then the initiator will have */ + /* sent us 0's. If the socket sizes cannot be changed, then we will */ + /* send-back what they are. If that information cannot be determined, */ + /* then we send-back -1's for the sizes. If things go wrong for any */ + /* reason, we will drop back ten yards and punt. */ + + /* If anything goes wrong, we want the remote to know about it. It */ + /* would be best if the error that the remote reports to the user is */ + /* the actual error we encountered, rather than some bogus unexpected */ + /* response type message. */ + + if (debug) { + fprintf(where,"recv_xti_tcp_rr: setting the response type...\n"); + fflush(where); + } + + netperf_response.content.response_type = XTI_TCP_RR_RESPONSE; + + if (debug) { + fprintf(where,"recv_xti_tcp_rr: the response type is set...\n"); + fflush(where); + } + + /* allocate the recv and send rings with the requested alignments */ + /* and offsets. raj 7/94 */ + if (debug) { + fprintf(where,"recv_xti_tcp_rr: requested recv alignment of %d offset %d\n", + xti_tcp_rr_request->recv_alignment, + xti_tcp_rr_request->recv_offset); + fprintf(where,"recv_xti_tcp_rr: requested send alignment of %d offset %d\n", + xti_tcp_rr_request->send_alignment, + xti_tcp_rr_request->send_offset); + fflush(where); + } + + /* at some point, these need to come to us from the remote system */ + if (send_width == 0) send_width = 1; + if (recv_width == 0) recv_width = 1; + + send_ring = allocate_buffer_ring(send_width, + xti_tcp_rr_request->response_size, + xti_tcp_rr_request->send_alignment, + xti_tcp_rr_request->send_offset); + + recv_ring = allocate_buffer_ring(recv_width, + xti_tcp_rr_request->request_size, + xti_tcp_rr_request->recv_alignment, + xti_tcp_rr_request->recv_offset); + + + /* Let's clear-out our sockaddr for the sake of cleanlines. Then we */ + /* can put in OUR values !-) At some point, we may want to nail this */ + /* socket to a particular network-level address, but for now, */ + /* INADDR_ANY should be just fine. */ + + bzero((char *)&myaddr_in, + sizeof(myaddr_in)); + myaddr_in.sin_family = AF_INET; + myaddr_in.sin_addr.s_addr = INADDR_ANY; + myaddr_in.sin_port = 0; + + /* Grab a socket to listen on, and then listen on it. */ + + if (debug) { + fprintf(where,"recv_xti_tcp_rr: grabbing a socket...\n"); + fflush(where); + } + + /* create_xti_endpoint expects to find some things in the global */ + /* variables, so set the globals based on the values in the request. */ + /* once the socket has been created, we will set the response values */ + /* based on the updated value of those globals. raj 7/94 */ + lss_size = xti_tcp_rr_request->send_buf_size; + lsr_size = xti_tcp_rr_request->recv_buf_size; + loc_nodelay = xti_tcp_rr_request->no_delay; + loc_rcvavoid = xti_tcp_rr_request->so_rcvavoid; + loc_sndavoid = xti_tcp_rr_request->so_sndavoid; + +#ifdef __alpha + + /* ok - even on a DEC box, strings are strings. I din't really want */ + /* to ntohl the words of a string. since I don't want to teach the */ + /* send_ and recv_ _request and _response routines about the types, */ + /* I will put "anti-ntohl" calls here. I imagine that the "pure" */ + /* solution would be to use XDR, but I am still leary of being able */ + /* to find XDR libs on all platforms I want running netperf. raj */ + { + int *charword; + int *initword; + int *lastword; + + initword = (int *) xti_tcp_rr_request->xti_device; + lastword = initword + ((xti_tcp_rr_request->dev_name_len + 3) / 4); + + for (charword = initword; + charword < lastword; + charword++) { + + *charword = htonl(*charword); + } + } + +#endif /* __alpha */ + + s_listen = create_xti_endpoint(xti_tcp_rr_request->xti_device); + + if (s_listen == INVALID_SOCKET) { + netperf_response.content.serv_errno = errno; + send_response(); + + exit(1); + } + + /* Let's get an address assigned to this socket so we can tell the */ + /* initiator how to reach the data socket. There may be a desire to */ + /* nail this socket to a specific IP address in a multi-homed, */ + /* multi-connection situation, but for now, we'll ignore the issue */ + /* and concentrate on single connection testing. */ + + bind_req.addr.maxlen = sizeof(struct sockaddr_in); + bind_req.addr.len = sizeof(struct sockaddr_in); + bind_req.addr.buf = (char *)&myaddr_in; + bind_req.qlen = 1; + + bind_resp.addr.maxlen = sizeof(struct sockaddr_in); + bind_resp.addr.len = sizeof(struct sockaddr_in); + bind_resp.addr.buf = (char *)&myaddr_in; + bind_resp.qlen = 1; + + if (t_bind(s_listen, + &bind_req, + &bind_resp) == SOCKET_ERROR) { + netperf_response.content.serv_errno = t_errno; + close(s_listen); + send_response(); + + exit(1); + } + + if (debug) { + fprintf(where, + "recv_xti_tcp_rr: t_bind complete port %d\n", + ntohs(myaddr_in.sin_port)); + fflush(where); + } + + /* Now myaddr_in contains the port and the internet address this is */ + /* returned to the sender also implicitly telling the sender that the */ + /* socket buffer sizing has been done. */ + + xti_tcp_rr_response->data_port_number = (int) ntohs(myaddr_in.sin_port); + netperf_response.content.serv_errno = 0; + + /* But wait, there's more. If the initiator wanted cpu measurements, */ + /* then we must call the calibrate routine, which will return the max */ + /* rate back to the initiator. If the CPU was not to be measured, or */ + /* something went wrong with the calibration, we will return a 0.0 to */ + /* the initiator. */ + + xti_tcp_rr_response->cpu_rate = 0.0; /* assume no cpu */ + xti_tcp_rr_response->measure_cpu = 0; + + if (xti_tcp_rr_request->measure_cpu) { + xti_tcp_rr_response->measure_cpu = 1; + xti_tcp_rr_response->cpu_rate = calibrate_local_cpu(xti_tcp_rr_request->cpu_rate); + } + + + /* before we send the response back to the initiator, pull some of */ + /* the socket parms from the globals */ + xti_tcp_rr_response->send_buf_size = lss_size; + xti_tcp_rr_response->recv_buf_size = lsr_size; + xti_tcp_rr_response->no_delay = loc_nodelay; + xti_tcp_rr_response->so_rcvavoid = loc_rcvavoid; + xti_tcp_rr_response->so_sndavoid = loc_sndavoid; + xti_tcp_rr_response->test_length = xti_tcp_rr_request->test_length; + send_response(); + + /* Now, let's set-up the socket to listen for connections. for xti, */ + /* the t_listen call is blocking by default - this is different */ + /* semantics from BSD - probably has to do with being able to reject */ + /* a call before an accept */ + call_req.addr.maxlen = sizeof(struct sockaddr_in); + call_req.addr.len = sizeof(struct sockaddr_in); + call_req.addr.buf = (char *)&peeraddr_in; + call_req.opt.maxlen = 0; + call_req.opt.len = 0; + call_req.opt.buf = NULL; + call_req.udata.maxlen= 0; + call_req.udata.len = 0; + call_req.udata.buf = 0; + + if (t_listen(s_listen, &call_req) == -1) { + fprintf(where, + "recv_xti_tcp_rr: t_listen: errno %d t_errno %d\n", + errno, + t_errno); + fflush(where); + netperf_response.content.serv_errno = t_errno; + close(s_listen); + send_response(); + exit(1); + } + + if (debug) { + fprintf(where, + "recv_xti_tcp_rr: t_listen complete t_look 0x%.4x\n", + t_look(s_listen)); + fflush(where); + } + + /* now just rubber stamp the thing. we want to use the same fd? so */ + /* we will just equate s_data with s_listen. this seems a little */ + /* hokey to me, but then I'm a BSD biggot still. raj 2/95 */ + s_data = s_listen; + if (t_accept(s_listen, + s_data, + &call_req) == -1) { + fprintf(where, + "recv_xti_tcp_rr: t_accept: errno %d t_errno %d\n", + errno, + t_errno); + fflush(where); + close(s_listen); + exit(1); + } + + if (debug) { + fprintf(where, + "recv_xti_tcp_rr: t_accept complete t_look 0x%.4x", + t_look(s_data)); + fprintf(where, + " remote is %s port %d\n", + inet_ntoa(*(struct in_addr *)&peeraddr_in.sin_addr), + ntohs(peeraddr_in.sin_port)); + fflush(where); + } + + /* Now it's time to start receiving data on the connection. We will */ + /* first grab the apropriate counters and then start grabbing. */ + + cpu_start(xti_tcp_rr_request->measure_cpu); + + if (xti_tcp_rr_request->test_length > 0) { + times_up = 0; + trans_remaining = 0; + start_timer(xti_tcp_rr_request->test_length + PAD_TIME); + } + else { + times_up = 1; + trans_remaining = xti_tcp_rr_request->test_length * -1; + } + + trans_received = 0; + + while ((!times_up) || (trans_remaining > 0)) { + temp_message_ptr = recv_ring->buffer_ptr; + request_bytes_remaining = xti_tcp_rr_request->request_size; + while(request_bytes_remaining > 0) { + if((request_bytes_recvd=t_rcv(s_data, + temp_message_ptr, + request_bytes_remaining, + &xti_flags)) == SOCKET_ERROR) { + if (errno == EINTR) { + /* the timer popped */ + timed_out = 1; + break; + } + fprintf(where, + "recv_xti_tcp_rr: t_rcv: errno %d t_errno %d len %d", + errno, + t_errno, + request_bytes_recvd); + fprintf(where, + " t_look 0x%x", + t_look(s_data)); + fflush(where); + netperf_response.content.serv_errno = t_errno; + send_response(); + exit(1); + } + else { + request_bytes_remaining -= request_bytes_recvd; + temp_message_ptr += request_bytes_recvd; + } + } + + recv_ring = recv_ring->next; + + if (timed_out) { + /* we hit the end of the test based on time - lets */ + /* bail out of here now... */ + if (debug) { + fprintf(where,"yo5\n"); + fflush(where); + } + break; + } + + /* Now, send the response to the remote */ + if((bytes_sent=t_snd(s_data, + send_ring->buffer_ptr, + xti_tcp_rr_request->response_size, + 0)) == -1) { + if (errno == EINTR) { + /* the test timer has popped */ + timed_out = 1; + if (debug) { + fprintf(where,"yo6\n"); + fflush(where); + } + break; + } + fprintf(where, + "recv_xti_tcp_rr: t_rcv: errno %d t_errno %d len %d", + errno, + t_errno, + bytes_sent); + fprintf(where, + " t_look 0x%x", + t_look(s_data)); + fflush(where); + netperf_response.content.serv_errno = t_errno; + send_response(); + exit(1); + } + + send_ring = send_ring->next; + + trans_received++; + if (trans_remaining) { + trans_remaining--; + } + } + + + /* The loop now exits due to timeout or transaction count being */ + /* reached */ + + cpu_stop(xti_tcp_rr_request->measure_cpu,&elapsed_time); + + stop_timer(); /* this is probably unnecessary, but it shouldn't hurt */ + + if (timed_out) { + /* we ended the test by time, which was at least 2 seconds */ + /* longer than we wanted to run. so, we want to subtract */ + /* PAD_TIME from the elapsed_time. */ + elapsed_time -= PAD_TIME; + } + + /* send the results to the sender */ + + if (debug) { + fprintf(where, + "recv_xti_tcp_rr: got %d transactions\n", + trans_received); + fflush(where); + } + + xti_tcp_rr_results->bytes_received = (trans_received * + (xti_tcp_rr_request->request_size + + xti_tcp_rr_request->response_size)); + xti_tcp_rr_results->trans_received = trans_received; + xti_tcp_rr_results->elapsed_time = elapsed_time; + xti_tcp_rr_results->cpu_method = cpu_method; + if (xti_tcp_rr_request->measure_cpu) { + xti_tcp_rr_results->cpu_util = calc_cpu_util(elapsed_time); + } + + if (debug) { + fprintf(where, + "recv_xti_tcp_rr: test complete, sending results.\n"); + fflush(where); + } + + /* we are done with the socket, free it */ + t_close(s_data); + + send_response(); + +} + + + + /* this test is intended to test the performance of establishing a */ + /* connection, exchanging a request/response pair, and repeating. it */ + /* is expected that this would be a good starting-point for */ + /* comparision of T/TCP with classic TCP for transactional workloads. */ + /* it will also look (can look) much like the communication pattern */ + /* of http for www access. */ + +void +send_xti_tcp_conn_rr(char remote_host[]) +{ + + char *tput_title = "\ +Local /Remote\n\ +Socket Size Request Resp. Elapsed Trans.\n\ +Send Recv Size Size Time Rate \n\ +bytes Bytes bytes bytes secs. per sec \n\n"; + + char *tput_fmt_0 = + "%7.2f\n"; + + char *tput_fmt_1_line_1 = "\ +%-6d %-6d %-6d %-6d %-6.2f %7.2f \n"; + char *tput_fmt_1_line_2 = "\ +%-6d %-6d\n"; + + char *cpu_title = "\ +Local /Remote\n\ +Socket Size Request Resp. Elapsed Trans. CPU CPU S.dem S.dem\n\ +Send Recv Size Size Time Rate local remote local remote\n\ +bytes bytes bytes bytes secs. per sec %% %% us/Tr us/Tr\n\n"; + + char *cpu_fmt_0 = + "%6.3f\n"; + + char *cpu_fmt_1_line_1 = "\ +%-6d %-6d %-6d %-6d %-6.2f %-6.2f %-6.2f %-6.2f %-6.3f %-6.3f\n"; + + char *cpu_fmt_1_line_2 = "\ +%-6d %-6d\n"; + + char *ksink_fmt = "\ +Alignment Offset\n\ +Local Remote Local Remote\n\ +Send Recv Send Recv\n\ +%5d %5d %5d %5d\n"; + + + int one = 1; + int timed_out = 0; + float elapsed_time; + + int len; + struct ring_elt *send_ring; + struct ring_elt *recv_ring; + char *temp_message_ptr; + int nummessages; + SOCKET send_socket; + int trans_remaining; + double bytes_xferd; + int sock_opt_len = sizeof(int); + int rsp_bytes_left; + int rsp_bytes_recvd; + + float local_cpu_utilization; + float local_service_demand; + float remote_cpu_utilization; + float remote_service_demand; + double thruput; + + struct hostent *hp; + struct sockaddr_in server; + struct sockaddr_in *myaddr; + unsigned int addr; + int myport; + + struct xti_tcp_conn_rr_request_struct *xti_tcp_conn_rr_request; + struct xti_tcp_conn_rr_response_struct *xti_tcp_conn_rr_response; + struct xti_tcp_conn_rr_results_struct *xti_tcp_conn_rr_result; + + xti_tcp_conn_rr_request = + (struct xti_tcp_conn_rr_request_struct *)netperf_request.content.test_specific_data; + xti_tcp_conn_rr_response = + (struct xti_tcp_conn_rr_response_struct *)netperf_response.content.test_specific_data; + xti_tcp_conn_rr_result = + (struct xti_tcp_conn_rr_results_struct *)netperf_response.content.test_specific_data; + + /* since we are now disconnected from the code that established the */ + /* control socket, and since we want to be able to use different */ + /* protocols and such, we are passed the name of the remote host and */ + /* must turn that into the test specific addressing information. */ + + myaddr = (struct sockaddr_in *)malloc(sizeof(struct sockaddr_in)); + if (myaddr == NULL) { + printf("malloc(%d) failed!\n", sizeof(struct sockaddr_in)); + exit(1); + } + + bzero((char *)&server, + sizeof(server)); + bzero((char *)myaddr, + sizeof(struct sockaddr_in)); + myaddr->sin_family = AF_INET; + + /* it would seem that while HP-UX will allow an IP address (as a */ + /* string) in a call to gethostbyname, other, less enlightened */ + /* systems do not. fix from awjacks@ca.sandia.gov raj 10/95 */ + /* order changed to check for IP address first. raj 7/96 */ + + if ((addr = inet_addr(remote_host)) == SOCKET_ERROR) { + /* it was not an IP address, try it as a name */ + if ((hp = gethostbyname(remote_host)) == NULL) { + /* we have no idea what it is */ + fprintf(where, + "establish_control: could not resolve the destination %s\n", + remote_host); + fflush(where); + exit(1); + } + else { + /* it was a valid remote_host */ + bcopy(hp->h_addr, + (char *)&server.sin_addr, + hp->h_length); + server.sin_family = hp->h_addrtype; + } + } + else { + /* it was a valid IP address */ + server.sin_addr.s_addr = addr; + server.sin_family = AF_INET; + } + + if ( print_headers ) { + fprintf(where,"TCP Connect/Request/Response Test\n"); + if (local_cpu_usage || remote_cpu_usage) + fprintf(where,cpu_title,format_units()); + else + fprintf(where,tput_title,format_units()); + } + + /* initialize a few counters */ + + nummessages = 0; + bytes_xferd = 0.0; + times_up = 0; + + /* set-up the data buffers with the requested alignment and offset */ + if (send_width == 0) send_width = 1; + if (recv_width == 0) recv_width = 1; + + send_ring = allocate_buffer_ring(send_width, + req_size, + local_send_align, + local_send_offset); + + recv_ring = allocate_buffer_ring(recv_width, + rsp_size, + local_recv_align, + local_recv_offset); + + + if (debug) { + fprintf(where,"send_xti_tcp_conn_rr: send_socket obtained...\n"); + } + + /* If the user has requested cpu utilization measurements, we must */ + /* calibrate the cpu(s). We will perform this task within the tests */ + /* themselves. If the user has specified the cpu rate, then */ + /* calibrate_local_cpu will return rather quickly as it will have */ + /* nothing to do. If local_cpu_rate is zero, then we will go through */ + /* all the "normal" calibration stuff and return the rate back.*/ + + if (local_cpu_usage) { + local_cpu_rate = calibrate_local_cpu(local_cpu_rate); + } + + /* Tell the remote end to do a listen. The server alters the socket */ + /* paramters on the other side at this point, hence the reason for */ + /* all the values being passed in the setup message. If the user did */ + /* not specify any of the parameters, they will be passed as 0, which */ + /* will indicate to the remote that no changes beyond the system's */ + /* default should be used. Alignment is the exception, it will */ + /* default to 8, which will be no alignment alterations. */ + + netperf_request.content.request_type = DO_XTI_TCP_CRR; + xti_tcp_conn_rr_request->recv_buf_size = rsr_size; + xti_tcp_conn_rr_request->send_buf_size = rss_size; + xti_tcp_conn_rr_request->recv_alignment = remote_recv_align; + xti_tcp_conn_rr_request->recv_offset = remote_recv_offset; + xti_tcp_conn_rr_request->send_alignment = remote_send_align; + xti_tcp_conn_rr_request->send_offset = remote_send_offset; + xti_tcp_conn_rr_request->request_size = req_size; + xti_tcp_conn_rr_request->response_size = rsp_size; + xti_tcp_conn_rr_request->no_delay = rem_nodelay; + xti_tcp_conn_rr_request->measure_cpu = remote_cpu_usage; + xti_tcp_conn_rr_request->cpu_rate = remote_cpu_rate; + xti_tcp_conn_rr_request->so_rcvavoid = rem_rcvavoid; + xti_tcp_conn_rr_request->so_sndavoid = rem_sndavoid; + if (test_time) { + xti_tcp_conn_rr_request->test_length = test_time; + } + else { + xti_tcp_conn_rr_request->test_length = test_trans * -1; + } + + if (debug > 1) { + fprintf(where,"netperf: send_xti_tcp_conn_rr: requesting TCP crr test\n"); + } + + send_request(); + + /* The response from the remote will contain all of the relevant */ + /* socket parameters for this test type. We will put them back into */ + /* the variables here so they can be displayed if desired. The */ + /* remote will have calibrated CPU if necessary, and will have done */ + /* all the needed set-up we will have calibrated the cpu locally */ + /* before sending the request, and will grab the counter value right */ + /* after the connect returns. The remote will grab the counter right */ + /* after the accept call. This saves the hassle of extra messages */ + /* being sent for the TCP tests. */ + + recv_response(); + + if (!netperf_response.content.serv_errno) { + rsr_size = xti_tcp_conn_rr_response->recv_buf_size; + rss_size = xti_tcp_conn_rr_response->send_buf_size; + rem_nodelay = xti_tcp_conn_rr_response->no_delay; + remote_cpu_usage= xti_tcp_conn_rr_response->measure_cpu; + remote_cpu_rate = xti_tcp_conn_rr_response->cpu_rate; + /* make sure that port numbers are in network order */ + server.sin_port = (short)xti_tcp_conn_rr_response->data_port_number; + server.sin_port = htons(server.sin_port); + if (debug) { + fprintf(where,"remote listen done.\n"); + fprintf(where,"remote port is %d\n",ntohs(server.sin_port)); + fflush(where); + } + } + else { + Set_errno(netperf_response.content.serv_errno); + perror("netperf: remote error"); + + exit(1); + } + + /* Set-up the test end conditions. For a request/response test, they */ + /* can be either time or transaction based. */ + + if (test_time) { + /* The user wanted to end the test after a period of time. */ + times_up = 0; + trans_remaining = 0; + start_timer(test_time); + } + else { + /* The tester wanted to send a number of bytes. */ + trans_remaining = test_bytes; + times_up = 1; + } + + /* The cpu_start routine will grab the current time and possibly */ + /* value of the idle counter for later use in measuring cpu */ + /* utilization and/or service demand and thruput. */ + + cpu_start(local_cpu_usage); + + /* We use an "OR" to control test execution. When the test is */ + /* controlled by time, the byte count check will always return false. */ + /* When the test is controlled by byte count, the time test will */ + /* always return false. When the test is finished, the whole */ + /* expression will go false and we will stop sending data. I think I */ + /* just arbitrarily decrement trans_remaining for the timed test, but */ + /* will not do that just yet... One other question is whether or not */ + /* the send buffer and the receive buffer should be the same buffer. */ + + /* just for grins, start the port numbers at 65530. this should */ + /* quickly flush-out those broken implementations of TCP which treat */ + /* the port number as a signed 16 bit quantity. */ + myport = 65530; + myaddr->sin_port = htons(myport); + + while ((!times_up) || (trans_remaining > 0)) { + + /* set up the data socket */ + send_socket = create_xti_endpoint(loc_xti_device); + + if (send_socket == INVALID_SOCKET) { + perror("netperf: send_xti_tcp_conn_rr: tcp stream data socket"); + exit(1); + } + + /* we set SO_REUSEADDR on the premis that no unreserved port */ + /* number on the local system is going to be already connected to */ + /* the remote netserver's port number. we might still have a */ + /* problem if there is a port in the unconnected state. In that */ + /* case, we might want to throw-in a goto to the point where we */ + /* increment the port number by one and try again. of course, this */ + /* could lead to a big load of spinning. one thing that I might */ + /* try later is to have the remote actually allocate a couple of */ + /* port numbers and cycle through those as well. depends on if we */ + /* can get through all the unreserved port numbers in less than */ + /* the length of the TIME_WAIT state raj 8/94 */ + one = 1; + if(setsockopt(send_socket, SOL_SOCKET, SO_REUSEADDR, + (char *)&one, sock_opt_len) == SOCKET_ERROR) { + perror("netperf: send_xti_tcp_conn_rr: so_reuseaddr"); + exit(1); + } + + /* we want to bind our socket to a particular port number. */ + if (bind(send_socket, + (struct sockaddr *)myaddr, + sizeof(struct sockaddr_in)) == SOCKET_ERROR) { + printf("netperf: send_xti_tcp_conn_rr: tried to bind to port %d\n", + ntohs(myaddr->sin_port)); + perror("netperf: send_xti_tcp_conn_rr: bind"); + exit(1); + } + + /* Connect up to the remote port on the data socket */ + if (connect(send_socket, + (struct sockaddr *)&server, + sizeof(server)) == INVALID_SOCKET){ + if (errno == EINTR) { + /* we hit the end of a */ + /* timed test. */ + timed_out = 1; + break; + } + perror("netperf: data socket connect failed"); + printf("\tattempted to connect on socket %d to port %d", + send_socket, + ntohs(server.sin_port)); + printf(" from port %d \n",ntohs(myaddr->sin_port)); + exit(1); + } + + /* send the request */ + if((len=send(send_socket, + send_ring->buffer_ptr, + req_size, + 0)) != req_size) { + if (errno == EINTR) { + /* we hit the end of a */ + /* timed test. */ + timed_out = 1; + break; + } + perror("send_xti_tcp_conn_rr: data send error"); + exit(1); + } + send_ring = send_ring->next; + + /* receive the response */ + rsp_bytes_left = rsp_size; + temp_message_ptr = recv_ring->buffer_ptr; + while(rsp_bytes_left > 0) { + if((rsp_bytes_recvd=recv(send_socket, + temp_message_ptr, + rsp_bytes_left, + 0)) == SOCKET_ERROR) { + if (errno == EINTR) { + /* We hit the end of a timed test. */ + timed_out = 1; + break; + } + perror("send_xti_tcp_conn_rr: data recv error"); + exit(1); + } + rsp_bytes_left -= rsp_bytes_recvd; + temp_message_ptr += rsp_bytes_recvd; + } + recv_ring = recv_ring->next; + + if (timed_out) { + /* we may have been in a nested while loop - we need */ + /* another call to break. */ + break; + } + + close(send_socket); + + nummessages++; + if (trans_remaining) { + trans_remaining--; + } + + if (debug > 3) { + fprintf(where, + "Transaction %d completed on local port %d\n", + nummessages, + ntohs(myaddr->sin_port)); + fflush(where); + } + +newport: + /* pick a new port number */ + myport = ntohs(myaddr->sin_port); + myport++; + /* we do not want to use the port number that the server is */ + /* sitting at - this would cause us to fail in a loopback test */ + + if (myport == ntohs(server.sin_port)) myport++; + + /* wrap the port number when we get to 65535. NOTE, some broken */ + /* TCP's might treat the port number as a signed 16 bit quantity. */ + /* we aren't interested in testing such broekn implementations :) */ + /* raj 8/94 */ + if (myport == 65535) { + myport = 5000; + } + myaddr->sin_port = htons(myport); + + if (debug) { + if ((myport % 1000) == 0) { + printf("port %d\n",myport); + } + } + + } + + /* this call will always give us the elapsed time for the test, and */ + /* will also store-away the necessaries for cpu utilization */ + + cpu_stop(local_cpu_usage,&elapsed_time); /* was cpu being measured? */ + /* how long did we really run? */ + + /* Get the statistics from the remote end. The remote will have */ + /* calculated service demand and all those interesting things. If it */ + /* wasn't supposed to care, it will return obvious values. */ + + recv_response(); + if (!netperf_response.content.serv_errno) { + if (debug) + fprintf(where,"remote results obtained\n"); + } + else { + Set_errno(netperf_response.content.serv_errno); + perror("netperf: remote error"); + + exit(1); + } + + /* We now calculate what our thruput was for the test. In the future, */ + /* we may want to include a calculation of the thruput measured by */ + /* the remote, but it should be the case that for a TCP stream test, */ + /* that the two numbers should be *very* close... We calculate */ + /* bytes_sent regardless of the way the test length was controlled. */ + /* If it was time, we needed to, and if it was by bytes, the user may */ + /* have specified a number of bytes that wasn't a multiple of the */ + /* send_size, so we really didn't send what he asked for ;-) We use */ + /* Kbytes/s as the units of thruput for a TCP stream test, where K = */ + /* 1024. A future enhancement *might* be to choose from a couple of */ + /* unit selections. */ + + bytes_xferd = (req_size * nummessages) + (rsp_size * nummessages); + thruput = calc_thruput(bytes_xferd); + + if (local_cpu_usage || remote_cpu_usage) { + /* We must now do a little math for service demand and cpu */ + /* utilization for the system(s) */ + /* Of course, some of the information might be bogus because */ + /* there was no idle counter in the kernel(s). We need to make */ + /* a note of this for the user's benefit...*/ + if (local_cpu_usage) { + if (local_cpu_rate == 0.0) { + fprintf(where,"WARNING WARNING WARNING WARNING WARNING WARNING WARNING!\n"); + fprintf(where,"Local CPU usage numbers based on process information only!\n"); + fflush(where); + } + local_cpu_utilization = calc_cpu_util(0.0); + /* since calc_service demand is doing ms/Kunit we will */ + /* multiply the number of transaction by 1024 to get */ + /* "good" numbers */ + local_service_demand = calc_service_demand((double) nummessages*1024, + 0.0, + 0.0, + 0); + } + else { + local_cpu_utilization = -1.0; + local_service_demand = -1.0; + } + + if (remote_cpu_usage) { + if (remote_cpu_rate == 0.0) { + fprintf(where,"DANGER DANGER DANGER DANGER DANGER DANGER DANGER!\n"); + fprintf(where,"Remote CPU usage numbers based on process information only!\n"); + fflush(where); + } + remote_cpu_utilization = xti_tcp_conn_rr_result->cpu_util; + /* since calc_service demand is doing ms/Kunit we will */ + /* multiply the number of transaction by 1024 to get */ + /* "good" numbers */ + remote_service_demand = calc_service_demand((double) nummessages*1024, + 0.0, + remote_cpu_utilization, + xti_tcp_conn_rr_result->num_cpus); + } + else { + remote_cpu_utilization = -1.0; + remote_service_demand = -1.0; + } + + /* We are now ready to print all the information. If the user */ + /* has specified zero-level verbosity, we will just print the */ + /* local service demand, or the remote service demand. If the */ + /* user has requested verbosity level 1, he will get the basic */ + /* "streamperf" numbers. If the user has specified a verbosity */ + /* of greater than 1, we will display a veritable plethora of */ + /* background information from outside of this block as it it */ + /* not cpu_measurement specific... */ + + switch (verbosity) { + case 0: + if (local_cpu_usage) { + fprintf(where, + cpu_fmt_0, + local_service_demand); + } + else { + fprintf(where, + cpu_fmt_0, + remote_service_demand); + } + break; + case 1: + fprintf(where, + cpu_fmt_1_line_1, /* the format string */ + lss_size, /* local sendbuf size */ + lsr_size, + req_size, /* how large were the requests */ + rsp_size, /* guess */ + elapsed_time, /* how long was the test */ + nummessages/elapsed_time, + local_cpu_utilization, /* local cpu */ + remote_cpu_utilization, /* remote cpu */ + local_service_demand, /* local service demand */ + remote_service_demand); /* remote service demand */ + fprintf(where, + cpu_fmt_1_line_2, + rss_size, + rsr_size); + break; + } + } + else { + /* The tester did not wish to measure service demand. */ + switch (verbosity) { + case 0: + fprintf(where, + tput_fmt_0, + nummessages/elapsed_time); + break; + case 1: + fprintf(where, + tput_fmt_1_line_1, /* the format string */ + lss_size, + lsr_size, + req_size, /* how large were the requests */ + rsp_size, /* how large were the responses */ + elapsed_time, /* how long did it take */ + nummessages/elapsed_time); + fprintf(where, + tput_fmt_1_line_2, + rss_size, /* remote recvbuf size */ + rsr_size); + + break; + } + } + + /* it would be a good thing to include information about some of the */ + /* other parameters that may have been set for this test, but at the */ + /* moment, I do not wish to figure-out all the formatting, so I will */ + /* just put this comment here to help remind me that it is something */ + /* that should be done at a later time. */ + + if (verbosity > 1) { + /* The user wanted to know it all, so we will give it to him. */ + /* This information will include as much as we can find about */ + /* TCP statistics, the alignments of the sends and receives */ + /* and all that sort of rot... */ + + fprintf(where, + ksink_fmt); + } + +} + + +void +recv_xti_tcp_conn_rr() +{ + + char *message; + struct sockaddr_in myaddr_in, + peeraddr_in; + SOCKET s_listen,s_data; + int addrlen; + char *recv_message_ptr; + char *send_message_ptr; + char *temp_message_ptr; + int trans_received; + int trans_remaining; + int bytes_sent; + int request_bytes_recvd; + int request_bytes_remaining; + int timed_out = 0; + float elapsed_time; + + struct xti_tcp_conn_rr_request_struct *xti_tcp_conn_rr_request; + struct xti_tcp_conn_rr_response_struct *xti_tcp_conn_rr_response; + struct xti_tcp_conn_rr_results_struct *xti_tcp_conn_rr_results; + + xti_tcp_conn_rr_request = + (struct xti_tcp_conn_rr_request_struct *)netperf_request.content.test_specific_data; + xti_tcp_conn_rr_response = + (struct xti_tcp_conn_rr_response_struct *)netperf_response.content.test_specific_data; + xti_tcp_conn_rr_results = + (struct xti_tcp_conn_rr_results_struct *)netperf_response.content.test_specific_data; + + if (debug) { + fprintf(where,"netserver: recv_xti_tcp_conn_rr: entered...\n"); + fflush(where); + } + + /* We want to set-up the listen socket with all the desired */ + /* parameters and then let the initiator know that all is ready. If */ + /* socket size defaults are to be used, then the initiator will have */ + /* sent us 0's. If the socket sizes cannot be changed, then we will */ + /* send-back what they are. If that information cannot be determined, */ + /* then we send-back -1's for the sizes. If things go wrong for any */ + /* reason, we will drop back ten yards and punt. */ + + /* If anything goes wrong, we want the remote to know about it. It */ + /* would be best if the error that the remote reports to the user is */ + /* the actual error we encountered, rather than some bogus unexpected */ + /* response type message. */ + + if (debug) { + fprintf(where,"recv_xti_tcp_conn_rr: setting the response type...\n"); + fflush(where); + } + + netperf_response.content.response_type = XTI_TCP_CRR_RESPONSE; + + if (debug) { + fprintf(where,"recv_xti_tcp_conn_rr: the response type is set...\n"); + fflush(where); + } + + /* set-up the data buffer with the requested alignment and offset */ + message = (char *)malloc(DATABUFFERLEN); + if (message == NULL) { + printf("malloc(%d) failed!\n", DATABUFFERLEN); + exit(1); + } + + /* We now alter the message_ptr variables to be at the desired */ + /* alignments with the desired offsets. */ + + if (debug) { + fprintf(where, + "recv_xti_tcp_conn_rr: requested recv alignment of %d offset %d\n", + xti_tcp_conn_rr_request->recv_alignment, + xti_tcp_conn_rr_request->recv_offset); + fprintf(where, + "recv_xti_tcp_conn_rr: requested send alignment of %d offset %d\n", + xti_tcp_conn_rr_request->send_alignment, + xti_tcp_conn_rr_request->send_offset); + fflush(where); + } + + recv_message_ptr = ALIGN_BUFFER(message, xti_tcp_conn_rr_request->recv_alignment, xti_tcp_conn_rr_request->recv_offset); + + send_message_ptr = ALIGN_BUFFER(message, xti_tcp_conn_rr_request->send_alignment, xti_tcp_conn_rr_request->send_offset); + + if (debug) { + fprintf(where,"recv_xti_tcp_conn_rr: receive alignment and offset set...\n"); + fflush(where); + } + + /* Let's clear-out our sockaddr for the sake of cleanlines. Then we */ + /* can put in OUR values !-) At some point, we may want to nail this */ + /* socket to a particular network-level address, but for now, */ + /* INADDR_ANY should be just fine. */ + + bzero((char *)&myaddr_in, + sizeof(myaddr_in)); + myaddr_in.sin_family = AF_INET; + myaddr_in.sin_addr.s_addr = INADDR_ANY; + myaddr_in.sin_port = 0; + + /* Grab a socket to listen on, and then listen on it. */ + + if (debug) { + fprintf(where,"recv_xti_tcp_conn_rr: grabbing a socket...\n"); + fflush(where); + } + + /* create_xti_endpoint expects to find some things in the global */ + /* variables, so set the globals based on the values in the request. */ + /* once the socket has been created, we will set the response values */ + /* based on the updated value of those globals. raj 7/94 */ + lss_size = xti_tcp_conn_rr_request->send_buf_size; + lsr_size = xti_tcp_conn_rr_request->recv_buf_size; + loc_nodelay = xti_tcp_conn_rr_request->no_delay; + loc_rcvavoid = xti_tcp_conn_rr_request->so_rcvavoid; + loc_sndavoid = xti_tcp_conn_rr_request->so_sndavoid; + + s_listen = create_xti_endpoint(loc_xti_device); + + if (s_listen == INVALID_SOCKET) { + netperf_response.content.serv_errno = errno; + send_response(); + if (debug) { + fprintf(where,"could not create data socket\n"); + fflush(where); + } + exit(1); + } + + /* Let's get an address assigned to this socket so we can tell the */ + /* initiator how to reach the data socket. There may be a desire to */ + /* nail this socket to a specific IP address in a multi-homed, */ + /* multi-connection situation, but for now, we'll ignore the issue */ + /* and concentrate on single connection testing. */ + + if (bind(s_listen, + (struct sockaddr *)&myaddr_in, + sizeof(myaddr_in)) == SOCKET_ERROR) { + netperf_response.content.serv_errno = errno; + close(s_listen); + send_response(); + if (debug) { + fprintf(where,"could not bind\n"); + fflush(where); + } + exit(1); + } + + /* Now, let's set-up the socket to listen for connections */ + if (listen(s_listen, 5) == SOCKET_ERROR) { + netperf_response.content.serv_errno = errno; + close(s_listen); + send_response(); + if (debug) { + fprintf(where,"could not listen\n"); + fflush(where); + } + exit(1); + } + + /* now get the port number assigned by the system */ + addrlen = sizeof(myaddr_in); + if (getsockname(s_listen, + (struct sockaddr *)&myaddr_in, + &addrlen) == SOCKET_ERROR){ + netperf_response.content.serv_errno = errno; + close(s_listen); + send_response(); + if (debug) { + fprintf(where,"could not geetsockname\n"); + fflush(where); + } + exit(1); + } + + /* Now myaddr_in contains the port and the internet address this is */ + /* returned to the sender also implicitly telling the sender that the */ + /* socket buffer sizing has been done. */ + + xti_tcp_conn_rr_response->data_port_number = (int) ntohs(myaddr_in.sin_port); + if (debug) { + fprintf(where,"telling the remote to call me at %d\n", + xti_tcp_conn_rr_response->data_port_number); + fflush(where); + } + netperf_response.content.serv_errno = 0; + + /* But wait, there's more. If the initiator wanted cpu measurements, */ + /* then we must call the calibrate routine, which will return the max */ + /* rate back to the initiator. If the CPU was not to be measured, or */ + /* something went wrong with the calibration, we will return a 0.0 to */ + /* the initiator. */ + + xti_tcp_conn_rr_response->cpu_rate = 0.0; /* assume no cpu */ + if (xti_tcp_conn_rr_request->measure_cpu) { + xti_tcp_conn_rr_response->measure_cpu = 1; + xti_tcp_conn_rr_response->cpu_rate = + calibrate_local_cpu(xti_tcp_conn_rr_request->cpu_rate); + } + + + + /* before we send the response back to the initiator, pull some of */ + /* the socket parms from the globals */ + xti_tcp_conn_rr_response->send_buf_size = lss_size; + xti_tcp_conn_rr_response->recv_buf_size = lsr_size; + xti_tcp_conn_rr_response->no_delay = loc_nodelay; + xti_tcp_conn_rr_response->so_rcvavoid = loc_rcvavoid; + xti_tcp_conn_rr_response->so_sndavoid = loc_sndavoid; + + send_response(); + + addrlen = sizeof(peeraddr_in); + + /* Now it's time to start receiving data on the connection. We will */ + /* first grab the apropriate counters and then start grabbing. */ + + cpu_start(xti_tcp_conn_rr_request->measure_cpu); + + /* The loop will exit when the sender does a shutdown, which will */ + /* return a length of zero */ + + if (xti_tcp_conn_rr_request->test_length > 0) { + times_up = 0; + trans_remaining = 0; + start_timer(xti_tcp_conn_rr_request->test_length + PAD_TIME); + } + else { + times_up = 1; + trans_remaining = xti_tcp_conn_rr_request->test_length * -1; + } + + trans_received = 0; + + while ((!times_up) || (trans_remaining > 0)) { + + /* accept a connection from the remote */ + if ((s_data=accept(s_listen, + (struct sockaddr *)&peeraddr_in, + &addrlen)) == INVALID_SOCKET) { + if (errno == EINTR) { + /* the timer popped */ + timed_out = 1; + break; + } + fprintf(where,"recv_xti_tcp_conn_rr: accept: errno = %d\n",errno); + fflush(where); + close(s_listen); + + exit(1); + } + + if (debug) { + fprintf(where,"recv_xti_tcp_conn_rr: accepted data connection.\n"); + fflush(where); + } + + temp_message_ptr = recv_message_ptr; + request_bytes_remaining = xti_tcp_conn_rr_request->request_size; + + /* receive the request from the other side */ + while(request_bytes_remaining > 0) { + if((request_bytes_recvd=recv(s_data, + temp_message_ptr, + request_bytes_remaining, + 0)) == SOCKET_ERROR) { + if (errno == EINTR) { + /* the timer popped */ + timed_out = 1; + break; + } + netperf_response.content.serv_errno = errno; + send_response(); + exit(1); + } + else { + request_bytes_remaining -= request_bytes_recvd; + temp_message_ptr += request_bytes_recvd; + } + } + + if (timed_out) { + /* we hit the end of the test based on time - lets */ + /* bail out of here now... */ + fprintf(where,"yo5\n"); + fflush(where); + break; + } + + /* Now, send the response to the remote */ + if((bytes_sent=send(s_data, + send_message_ptr, + xti_tcp_conn_rr_request->response_size, + 0)) == SOCKET_ERROR) { + if (errno == EINTR) { + /* the test timer has popped */ + timed_out = 1; + fprintf(where,"yo6\n"); + fflush(where); + break; + } + netperf_response.content.serv_errno = 99; + send_response(); + exit(1); + } + + trans_received++; + if (trans_remaining) { + trans_remaining--; + } + + if (debug) { + fprintf(where, + "recv_xti_tcp_conn_rr: Transaction %d complete\n", + trans_received); + fflush(where); + } + + /* close the connection */ + close(s_data); + + } + + + /* The loop now exits due to timeout or transaction count being */ + /* reached */ + + cpu_stop(xti_tcp_conn_rr_request->measure_cpu,&elapsed_time); + + if (timed_out) { + /* we ended the test by time, which was at least 2 seconds */ + /* longer than we wanted to run. so, we want to subtract */ + /* PAD_TIME from the elapsed_time. */ + elapsed_time -= PAD_TIME; + } + /* send the results to the sender */ + + if (debug) { + fprintf(where, + "recv_xti_tcp_conn_rr: got %d transactions\n", + trans_received); + fflush(where); + } + + xti_tcp_conn_rr_results->bytes_received = (trans_received * + (xti_tcp_conn_rr_request->request_size + + xti_tcp_conn_rr_request->response_size)); + xti_tcp_conn_rr_results->trans_received = trans_received; + xti_tcp_conn_rr_results->elapsed_time = elapsed_time; + if (xti_tcp_conn_rr_request->measure_cpu) { + xti_tcp_conn_rr_results->cpu_util = calc_cpu_util(elapsed_time); + } + + if (debug) { + fprintf(where, + "recv_xti_tcp_conn_rr: test complete, sending results.\n"); + fflush(where); + } + + send_response(); + +} + +void +print_xti_usage() +{ + + fwrite(xti_usage, sizeof(char), strlen(xti_usage), stdout); + exit(1); + +} + +void +scan_xti_args(int argc, char *argv[]) +{ +#define XTI_ARGS "Dhm:M:r:s:S:Vw:W:X:" + extern int optind, opterrs; /* index of first unused arg */ + extern char *optarg; /* pointer to option string */ + + int c; + + char + arg1[BUFSIZ], /* argument holders */ + arg2[BUFSIZ]; + + if (no_control) { + fprintf(where, + "The XTI tests do not know how to run with no control connection\n"); + exit(-1); + } + + /* Go through all the command line arguments and break them */ + /* out. For those options that take two parms, specifying only */ + /* the first will set both to that value. Specifying only the */ + /* second will leave the first untouched. To change only the */ + /* first, use the form "first," (see the routine break_args.. */ + + while ((c= getopt(argc, argv, XTI_ARGS)) != EOF) { + switch (c) { + case '?': + case 'h': + print_xti_usage(); + exit(1); + case 'D': + /* set the TCP nodelay flag */ + loc_nodelay = 1; + rem_nodelay = 1; + break; + case 's': + /* set local socket sizes */ + break_args(optarg,arg1,arg2); + if (arg1[0]) + lss_size = convert(arg1); + if (arg2[0]) + lsr_size = convert(arg2); + break; + case 'S': + /* set remote socket sizes */ + break_args(optarg,arg1,arg2); + if (arg1[0]) + rss_size = convert(arg1); + if (arg2[0]) + rsr_size = convert(arg2); + break; + case 'r': + /* set the request/response sizes */ + break_args(optarg,arg1,arg2); + if (arg1[0]) + req_size = convert(arg1); + if (arg2[0]) + rsp_size = convert(arg2); + break; + case 'm': + /* set the send size */ + send_size = convert(optarg); + break; + case 'M': + /* set the recv size */ + recv_size = convert(optarg); + break; + case 'W': + /* set the "width" of the user space data */ + /* buffer. This will be the number of */ + /* send_size buffers malloc'd in the */ + /* *_STREAM test. It may be enhanced to set */ + /* both send and receive "widths" but for now */ + /* it is just the sending *_STREAM. */ + send_width = convert(optarg); + break; + case 'V' : + /* we want to do copy avoidance and will set */ + /* it for everything, everywhere, if we really */ + /* can. of course, we don't know anything */ + /* about the remote... */ +#ifdef SO_SND_COPYAVOID + loc_sndavoid = 1; +#else + loc_sndavoid = 0; + printf("Local send copy avoidance not available.\n"); +#endif +#ifdef SO_RCV_COPYAVOID + loc_rcvavoid = 1; +#else + loc_rcvavoid = 0; + printf("Local recv copy avoidance not available.\n"); +#endif + rem_sndavoid = 1; + rem_rcvavoid = 1; + break; + case 'X': + /* set the xti device file name(s) */ + break_args(optarg,arg1,arg2); + if (arg1[0]) + strcpy(loc_xti_device,arg1); + if (arg2[0]) + strcpy(rem_xti_device,arg2); + break; + }; + } +} +#endif /* WANT_XTI */ diff --git a/src/nettest_xti.h b/src/nettest_xti.h new file mode 100644 index 0000000..3bf9968 --- /dev/null +++ b/src/nettest_xti.h @@ -0,0 +1,264 @@ +/* + * Copyright (C) 1995,2004 Hewlett-Packard Company + */ + + /* This file contains the test-specific definitions for netperf's BSD */ + /* sockets tests */ + +struct xti_tcp_stream_request_struct { + int send_buf_size; + int recv_buf_size; /* how big does the client want it - the */ + /* receive socket buffer that is */ + int receive_size; /* how many bytes do we want to receive at one */ + /* time? */ + int recv_alignment; /* what is the alignment of the receive */ + /* buffer? */ + int recv_offset; /* and at what offset from that alignment? */ + int no_delay; /* do we disable the nagle algorithm for send */ + /* coalescing? */ + int measure_cpu; /* does the client want server cpu utilization */ + /* measured? */ + float cpu_rate; /* do we know how fast the cpu is already? */ + int test_length; /* how long is the test? */ + int so_rcvavoid; /* do we want the remote to avoid copies on */ + /* receives? */ + int so_sndavoid; /* do we want the remote to avoid send copies? */ + int dirty_count; /* how many integers in the receive buffer */ + /* should be made dirty before calling recv? */ + int clean_count; /* how many integers should be read from the */ + /* recv buffer before calling recv? */ + int dev_name_len; /* the length of the device name string. this */ + /* is used to put it into the proper order on */ + /* @#$% byte-swapped boxes... */ + char xti_device[32]; /* the path to the dlpi device */ +}; + +struct xti_tcp_stream_response_struct { + int recv_buf_size; /* how big does the client want it */ + int receive_size; + int no_delay; + int measure_cpu; /* does the client want server cpu */ + int test_length; /* how long is the test? */ + int send_buf_size; + int data_port_number; /* connect to me here */ + float cpu_rate; /* could we measure */ + int so_rcvavoid; /* could the remote avoid receive copies? */ + int so_sndavoid; /* could the remote avoid send copies? */ +}; + +struct xti_tcp_stream_results_struct { + double bytes_received; + unsigned int recv_calls; + float elapsed_time; /* how long the test ran */ + float cpu_util; /* -1 if not measured */ + float serv_dem; /* -1 if not measured */ + int cpu_method; /* how was cpu util measured? */ + int num_cpus; /* how many CPUs were there */ +}; + +struct xti_tcp_rr_request_struct { + int recv_buf_size; /* how big does the client want it */ + int send_buf_size; + int recv_alignment; + int recv_offset; + int send_alignment; + int send_offset; + int request_size; + int response_size; + int no_delay; + int measure_cpu; /* does the client want server cpu */ + float cpu_rate; /* do we know how fast the cpu is? */ + int test_length; /* how long is the test? */ + int so_rcvavoid; /* do we want the remote to avoid receive */ + /* copies? */ + int so_sndavoid; /* do we want the remote to avoid send copies? */ + int dev_name_len; /* the length of the device name string. this */ + /* is used to put it into the proper order on */ + /* @#$% byte-swapped boxes... */ + char xti_device[32]; /* the path to the dlpi device */ +}; + +struct xti_tcp_rr_response_struct { + int recv_buf_size; /* how big does the client want it */ + int no_delay; + int measure_cpu; /* does the client want server cpu */ + int test_length; /* how long is the test? */ + int send_buf_size; + int data_port_number; /* connect to me here */ + float cpu_rate; /* could we measure */ + int so_rcvavoid; /* could the remote avoid receive copies? */ + int so_sndavoid; /* could the remote avoid send copies? */ +}; + +struct xti_tcp_rr_results_struct { + unsigned int bytes_received; /* ignored initially */ + unsigned int recv_calls; /* ignored initially */ + unsigned int trans_received; /* not ignored */ + float elapsed_time; /* how long the test ran */ + float cpu_util; /* -1 if not measured */ + float serv_dem; /* -1 if not measured */ + int cpu_method; /* how was cpu util measured? */ + int num_cpus; /* how many CPUs were there */ +}; + +struct xti_tcp_conn_rr_request_struct { + int recv_buf_size; /* how big does the client want it */ + int send_buf_size; + int recv_alignment; + int recv_offset; + int send_alignment; + int send_offset; + int request_size; + int response_size; + int no_delay; + int measure_cpu; /* does the client want server cpu */ + float cpu_rate; /* do we know how fast the cpu is? */ + int test_length; /* how long is the test? */ + int so_rcvavoid; /* do we want the remote to avoid receive */ + /* copies? */ + int so_sndavoid; /* do we want the remote to avoid send copies? */ + int dev_name_len; /* the length of the device name string. this */ + /* is used to put it into the proper order on */ + /* @#$% byte-swapped boxes... */ + char xti_device[32]; /* the path to the dlpi device */ +}; + + +struct xti_tcp_conn_rr_response_struct { + int recv_buf_size; /* how big does the client want it */ + int no_delay; + int measure_cpu; /* does the client want server cpu */ + int test_length; /* how long is the test? */ + int send_buf_size; + int data_port_number; /* connect to me here */ + float cpu_rate; /* could we measure */ + int so_rcvavoid; /* could the remote avoid receive copies? */ + int so_sndavoid; /* could the remote avoid send copies? */ +}; + +struct xti_tcp_conn_rr_results_struct { + unsigned int bytes_received; /* ignored initially */ + unsigned int recv_calls; /* ignored initially */ + unsigned int trans_received; /* not ignored */ + float elapsed_time; /* how long the test ran */ + float cpu_util; /* -1 if not measured */ + float serv_dem; /* -1 if not measured */ + int cpu_method; /* how was cpu util measured? */ + int num_cpus; /* how many CPUs were there */ +}; + +struct xti_udp_stream_request_struct { + int recv_buf_size; + int message_size; + int recv_alignment; + int recv_offset; + int checksum_off; /* not used. left in for compatibility */ + int measure_cpu; + float cpu_rate; + int test_length; + int so_rcvavoid; /* do we want the remote to avoid receive */ + /* copies? */ + int so_sndavoid; /* do we want the remote to avoid send copies? */ + int dev_name_len; /* the length of the device name string. this */ + /* is used to put it into the proper order on */ + /* @#$% byte-swapped boxes... */ + char xti_device[32]; /* the path to the dlpi device */ +}; + +struct xti_udp_stream_response_struct { + int recv_buf_size; + int send_buf_size; + int measure_cpu; + int test_length; + int data_port_number; + float cpu_rate; + int so_rcvavoid; /* could the remote avoid receive copies? */ + int so_sndavoid; /* could the remote avoid send copies? */ +}; + +struct xti_udp_stream_results_struct { + unsigned int messages_recvd; + unsigned int bytes_received; + float elapsed_time; + float cpu_util; + int cpu_method; /* how was cpu util measured? */ + int num_cpus; /* how many CPUs were there */ +}; + + +struct xti_udp_rr_request_struct { + int recv_buf_size; /* how big does the client want it */ + int send_buf_size; + int recv_alignment; + int recv_offset; + int send_alignment; + int send_offset; + int request_size; + int response_size; + int no_delay; + int measure_cpu; /* does the client want server cpu */ + float cpu_rate; /* do we know how fast the cpu is? */ + int test_length; /* how long is the test? */ + int so_rcvavoid; /* do we want the remote to avoid receive */ + /* copies? */ + int so_sndavoid; /* do we want the remote to avoid send copies? */ + int dev_name_len; /* the length of the device name string. this */ + /* is used to put it into the proper order on */ + /* @#$% byte-swapped boxes... */ + char xti_device[32]; /* the path to the dlpi device */ +}; + +struct xti_udp_rr_response_struct { + int recv_buf_size; /* how big does the client want it */ + int no_delay; + int measure_cpu; /* does the client want server cpu */ + int test_length; /* how long is the test? */ + int send_buf_size; + int data_port_number; /* connect to me here */ + float cpu_rate; /* could we measure */ + int so_rcvavoid; /* could the remote avoid receive copies? */ + int so_sndavoid; /* could the remote avoid send copies? */ +}; + +struct xti_udp_rr_results_struct { + unsigned int bytes_received; /* ignored initially */ + unsigned int recv_calls; /* ignored initially */ + unsigned int trans_received; /* not ignored */ + float elapsed_time; /* how long the test ran */ + float cpu_util; /* -1 if not measured */ + float serv_dem; /* -1 if not measured */ + int cpu_method; /* how was cpu util measured? */ + int num_cpus; /* how many CPUs were there */ +}; + +extern void send_xti_tcp_stream(char remote_host[]); + +extern void recv_xti_tcp_stream(); + +extern void send_xti_tcp_rr(char remote_host[]); + +extern void send_xti_udp_stream(char remote_host[]); + +extern void recv_xti_udp_stream(); + +extern void send_xti_udp_rr(char remote_host[]); + +extern void recv_xti_udp_rr(); + +extern void recv_xti_tcp_rr(); + +extern void send_xti_tcp_conn_rr(char remote_host[]); + +extern void recv_xti_tcp_conn_rr(); + +extern void scan_xti_args(int argc, char *argv[]); + + + + + + + + + + -- 2.39.5