From: Konrad Rzeszutek Wilk Date: Wed, 24 Feb 2010 21:05:16 +0000 (-0500) Subject: Pull from ftp://ftp.netperf.org/netperf/netperf-2.4.5.tar.bz2 X-Git-Url: http://xenbits.xensource.com/gitweb?a=commitdiff_plain;h=refs%2Fheads%2Fmaster;p=xentesttools%2Fnetperf.git Pull from ftp://ftp.netperf.org/netperf/netperf-2.4.5.tar.bz2 --- 6695f068295cd2c078f5fa6d474c6d674c269c38 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[]); + + + + + + + + + +