netperf-2.6.0/0000755000175000017500000000000011770164743010175 500000000000000netperf-2.6.0/README.windows0000644000175000017500000001037411770160156012465 00000000000000It 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. If you do not want the corresponding features, edit the sources files and remove the -Ds for WANT_DEMO, WANT_HISTOGRAM and/or WANT_INTERVALS 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 netperf-2.6.0/config.guess0000755000175000017500000012475311525015225012435 00000000000000#! /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: netperf-2.6.0/netperf.spec.in0000644000175000017500000000341711525015225013032 00000000000000Summary: Network Performance Testing Tool Name: netperf Version: @VERSION@ Release: 1 Group: System Environment/Base License: Unknown URL: http://www.netperf.org/ Packager: Martin A. Brown Source: ftp://ftp.netperf.org/netperf/%{name}-%{version}.tar.bz2 BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root BuildRequires: texinfo, texinfo-tex # we are not quite ready to make this a requirement but leave # the line here as a heads up for the attentive :) # BuildRequires: libsmbios-devel # if you want to enable the SCTP tests, append --enable-sctp to the # configure line, and uncomment the next line # BuildRequires: lksctp-tools-devel %description Many different network benchmarking tools are collected in this package, maintained by Rick Jones of HP. %prep %setup -q %build # gcc 4.4 users may want to disable the strict aliasing warnings # CFLAGS="$RPM_OPT_FLAGS -Wno-strict-aliasing" %configure make %{_smp_mflags} %install rm -rf $RPM_BUILD_ROOT make install DESTDIR=${RPM_BUILD_ROOT} # Convert the main netperf document to other formats cd doc make %{name}.txt %{name}.html %{name}.xml pdf cd .. # We don't want to package the Makefile files in the examples directory rm -f doc/examples/Makefile* # Info rm -f $RPM_BUILD_ROOT/%{_infodir}/dir %clean rm -rf $RPM_BUILD_ROOT # %post %files %defattr(-,root,root,-) %doc README AUTHORS COPYING Release_Notes %doc doc/netperf.{html,pdf,txt,xml} %doc doc/examples %{_mandir}/man1/* %{_infodir}/* %{_bindir}/netperf %{_bindir}/netserver %changelog * Mon Sep 7 2009 Jose Pedro Oliveira - 2.4.5-1 - Specfile cleanup. * Sat Jun 17 2006 Martin A. Brown - 2.4.2-1 - initial contributed specfile for netperf package (v2.4.2) netperf-2.6.0/Makefile.in0000644000175000017500000005406311770160504012161 00000000000000# Makefile.in generated by automake 1.11.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008, 2009 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@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd 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 = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ subdir = . DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \ $(srcdir)/Makefile.in $(srcdir)/config.h.in \ $(srcdir)/netperf.spec.in $(top_srcdir)/configure AUTHORS \ COPYING ChangeLog INSTALL NEWS config.guess config.sub depcomp \ install-sh missing mkinstalldirs ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/src/missing/m4/salen.m4 \ $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ configure.lineno config.status.lineno mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_HEADER = config.h CONFIG_CLEAN_FILES = netperf.spec CONFIG_CLEAN_VPATH_FILES = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ html-recursive info-recursive install-data-recursive \ install-dvi-recursive install-exec-recursive \ install-html-recursive install-info-recursive \ install-pdf-recursive install-ps-recursive install-recursive \ installcheck-recursive installdirs-recursive pdf-recursive \ ps-recursive uninstall-recursive RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \ $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \ distdir dist dist-all distcheck ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) distdir = $(PACKAGE)-$(VERSION) top_distdir = $(distdir) am__remove_distdir = \ { test ! -d "$(distdir)" \ || { find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \ && rm -fr "$(distdir)"; }; } am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" DIST_ARCHIVES = $(distdir).tar.gz $(distdir).tar.bz2 $(distdir).zip GZIP_ENV = --best distuninstallcheck_listfiles = find . -type f -print distcleancheck_listfiles = find . -type f -print ACLOCAL = @ACLOCAL@ 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 = @INSTALL@ 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@ MKDIR_P = @MKDIR_P@ 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_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ RANLIB = @RANLIB@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ 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@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ AUTOMAKE_OPTIONS = dist-bzip2 dist-zip SUBDIRS = src doc EXTRA_DIST = README.* Release_Notes inet_ntop.c autogen.sh m4 all: config.h $(MAKE) $(AM_MAKEFLAGS) all-recursive .SUFFIXES: am--refresh: @: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ echo ' cd $(srcdir) && $(AUTOMAKE) --gnu'; \ $(am__cd) $(srcdir) && $(AUTOMAKE) --gnu \ && exit 0; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ echo ' $(SHELL) ./config.status'; \ $(SHELL) ./config.status;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) $(SHELL) ./config.status --recheck $(top_srcdir)/configure: $(am__configure_deps) $(am__cd) $(srcdir) && $(AUTOCONF) $(ACLOCAL_M4): $(am__aclocal_m4_deps) $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) $(am__aclocal_m4_deps): config.h: stamp-h1 @if test ! -f $@; then \ rm -f stamp-h1; \ $(MAKE) $(AM_MAKEFLAGS) 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: $(am__configure_deps) ($(am__cd) $(top_srcdir) && $(AUTOHEADER)) rm -f stamp-h1 touch $@ distclean-hdr: -rm -f config.h stamp-h1 netperf.spec: $(top_builddir)/config.status $(srcdir)/netperf.spec.in cd $(top_builddir) && $(SHELL) ./config.status $@ # 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): @fail= failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ 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; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" $(RECURSIVE_CLEAN_TARGETS): @fail= failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ 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; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done && test -z "$$fail" tags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ done ctags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ done 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; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: tags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$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; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: ctags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) 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; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) $(am__remove_distdir) test -d "$(distdir)" || mkdir "$(distdir)" @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done -test -n "$(am__skip_mode_fix)" \ || find "$(distdir)" -type d ! -perm -755 \ -exec chmod u+rwx,go+rx {} \; -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 $(install_sh) -c -m a+r {} {} \; \ || chmod -R a+r "$(distdir)" dist-gzip: distdir tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz $(am__remove_distdir) dist-bzip2: distdir tardir=$(distdir) && $(am__tar) | bzip2 -9 -c >$(distdir).tar.bz2 $(am__remove_distdir) dist-lzma: distdir tardir=$(distdir) && $(am__tar) | lzma -9 -c >$(distdir).tar.lzma $(am__remove_distdir) dist-xz: distdir tardir=$(distdir) && $(am__tar) | xz -c >$(distdir).tar.xz $(am__remove_distdir) dist-tarZ: distdir tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z $(am__remove_distdir) dist-shar: distdir shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz $(am__remove_distdir) dist-zip: distdir -rm -f $(distdir).zip zip -rq $(distdir).zip $(distdir) $(am__remove_distdir) dist dist-all: distdir tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz tardir=$(distdir) && $(am__tar) | 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 case '$(DIST_ARCHIVES)' in \ *.tar.gz*) \ GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\ *.tar.bz2*) \ bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ *.tar.lzma*) \ lzma -dc $(distdir).tar.lzma | $(am__untar) ;;\ *.tar.xz*) \ xz -dc $(distdir).tar.xz | $(am__untar) ;;\ *.tar.Z*) \ uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ *.shar.gz*) \ GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\ *.zip*) \ unzip $(distdir).zip ;;\ esac chmod -R a-w $(distdir); chmod a+w $(distdir) mkdir $(distdir)/_build mkdir $(distdir)/_inst chmod a-w $(distdir) test -d $(distdir)/_build || exit 0; \ dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ && am__cwd=`pwd` \ && $(am__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 ../.. && umask 077 && mkdir "$$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 \ && rm -rf $(DIST_ARCHIVES) \ && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \ && cd "$$am__cwd" \ || exit 1 $(am__remove_distdir) @(echo "$(distdir) archives ready for distribution: "; \ list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' distuninstallcheck: @$(am__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: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_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: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: 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: .MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) all \ ctags-recursive install-am install-strip tags-recursive .PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ all all-am am--refresh check check-am clean clean-generic \ ctags ctags-recursive dist dist-all dist-bzip2 dist-gzip \ dist-lzma dist-shar dist-tarZ dist-xz dist-zip distcheck \ distclean distclean-generic distclean-hdr distclean-tags \ distcleancheck distdir distuninstallcheck dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs installdirs-am maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic pdf \ pdf-am ps ps-am tags tags-recursive uninstall uninstall-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: netperf-2.6.0/COPYING0000644000175000017500000000403711525015225011140 00000000000000 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. netperf-2.6.0/Makefile.am0000644000175000017500000000017011525015225012133 00000000000000 AUTOMAKE_OPTIONS = dist-bzip2 dist-zip SUBDIRS = src doc EXTRA_DIST = README.* Release_Notes inet_ntop.c autogen.sh m4 netperf-2.6.0/configure.ac0000644000175000017500000005173011770160475012407 00000000000000# -*- Autoconf -*- # Process this file with autoconf to produce a configure script. FULL-PACKAGE-NAME=netperf VERSION=2.6.0 BUG-REPORT-ADDRESS=netperf-feedback@netperf.org AC_PREREQ(2.59) AC_INIT(netperf, 2.6.0) # Inherit compiler flags from the environment... CFLAGS="${CFLAGS:=}" CXXFLAGS="${CXXFLAGS:=}" # 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 ${ac_top_srcdir}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 # lets keep this in some semblence of alphabetical order AC_CHECK_HEADERS([arpa/inet.h endian.h errno.h fcntl.h ifaddrs.h limits.h linux/tcp.h malloc.h netdb.h netinet/in.h netinet/sctp.h signal.h stdlib.h string.h strings.h syscall.h sys/ioctl.h sys/mman.h sys/param.h sys/socket.h sys/stat.h sys/time.h sys/wait.h sys/ipc.h sys/sockio.h sys/sysinfo.h sys/wait.h stdlib.h unistd.h netinet/in_systm.h netinet/ip.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 daemon gethostbyname gethrtime gettimeofday inet_ntoa memset memcpy munmap select setsid socket sqrt strcasecmp strchr strstr strtoul uname toupper]) #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=true ;; *) 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.]) AC_DEFINE([WANT_MIGRATION],,[Define to one to migrate classic to 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 *-*-freebsd[78].*) # FreeBSD 7.x and later 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=true ;; *) 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.* | *-*-aix6.*) 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-8]].* | *-*-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-8]].* | *-*-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 ;; hpux) 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) ;; *-*-hpux11.31*) use_slotlookup=true enable_slotlookup="hpux 11.31 - auto" NETSLOTLKUP_SOURCE="ux1131" AC_HAVE_LIBRARY(IO) AC_HAVE_LIBRARY(olrad) ;; *) 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 netperf-2.6.0/autogen.sh0000755000175000017500000000013711525015225012103 00000000000000#! /bin/sh aclocal -I src/missing/m4 \ && automake --add-missing \ && autoconf && autoheader netperf-2.6.0/doc/0000755000175000017500000000000011770164744010743 500000000000000netperf-2.6.0/doc/netserver.man0000644000175000017500000000312111576721154013370 00000000000000.TH netserver 1 "" .SH NAME netserver \- a network performance benchmark server .SH SYNOPSIS .B netserver [-4] [-6] [-d] [-h] [-L name,family] [-p portnum] [-v verbosity] [-V] .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 \-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 \-d Increase the quantity of debugging output displayed during a test (possibly at the expense of performance). .TP .B \-h Display a usage string, and exit. .TP .B \-L name,family Set the local name and/or address family for the socket used for the control connection. .TP .B \-p portnum Listen on the specified port. This is used when running as a standalone daemon. .TP .B \-v verbosity Set the verbosity level for the test. .TP .B \-V Display the netperf version and exit. .SH BUGS No known bugs at this time. If you think you have found a bug, please report it to either netperf-talk@netperf.org or netperf-feedback@netperf.org. .SH SEE ALSO .BR netperf (1) .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 AUTHORS file netperf-2.6.0/doc/netperf.texi0000644000175000017500000054052211770164537013231 00000000000000\input texinfo @c -*-texinfo-*- @c %**start of header @setfilename netperf.info @settitle Care and Feeding of Netperf 2.6.X @c %**end of header @copying This is Rick Jones' feeble attempt at a Texinfo-based manual for the netperf benchmark. Copyright @copyright{} 2005-2012 Hewlett-Packard Company @quotation Permission is granted to copy, distribute and/or modify this document per the terms of the netperf source license, 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.6.0 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 what it 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:: * The Omni Tests:: * Other Netperf Tests:: * Address Resolution:: * Enhancing Netperf:: * Netperf4:: * Concept Index:: * Option Index:: @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 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. It is the Contributing Editor's belief that the netperf license walks like open source and talks like open source. However, the license was never submitted for ``certification'' as an open source license. If you would prefer to make contributions to a networking benchmark using a certified open source license, please consider netperf4, which is distributed under the terms of the GPLv2. 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 (to deal with spam) 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.6.0,netperf 2.6.0}. 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}. When fixing bugs or making enhancements, patches against the top-of-trunk are preferred. 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. @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 netperf-.tar.gz | tar xf - cd netperf- ./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. You may find the @code{--prefix} option helpful in deciding where the binaries and such will be put during the @code{make install}. @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-unixdomain, 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|unixdomain|dlpi|sctp]=yes} options to the configure command. As of this writing, the configure script will not include those tests automagically. @vindex --enable-omni, Configure Starting with version 2.5.0, netperf began migrating most of the ``classic'' netperf tests found in @file{src/nettest_bsd.c} to the so-called ``omni'' tests (aka ``two routines to run them all'') found in @file{src/nettest_omni.c}. This migration enables a number of new features such as greater control over what output is included, and new things to output. The ``omni'' test is enabled by default in 2.5.0 and a number of the classic tests are migrated - you can tell if a test has been migrated from the presence of @code{MIGRATED} in the test banner. If you encounter problems with either the omni or migrated tests, please first attempt to obtain resolution via @email{netperf-talk@@netperf.org} or @email{netperf-feedback@@netperf.org}. If that is unsuccessful, you can add a @code{--enable-omni=no} to the configure command and the omni tests will not be compiled-in and the classic tests will not be migrated. Starting with version 2.5.0, netperf includes the ``burst mode'' functionality in a default compilation of the bits. If you encounter problems with this, please first attempt to obtain help via @email{netperf-talk@@netperf.org} or @email{netperf-feedback@@netperf.org}. If that is unsuccessful, you can add a @code{--enable-burst=no} to the configure command and the burst mode functionality will not be compiled-in. 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 automagic 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 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 @option{-D} output: @example $ src/netperf -D 1.35 -H tardy.hpl.hp.com -f M MIGRATED TCP STREAM TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to tardy.hpl.hp.com (15.9.116.144) port 0 AF_INET : demo Interim result: 5.41 MBytes/s over 1.35 seconds ending at 1308789765.848 Interim result: 11.07 MBytes/s over 1.36 seconds ending at 1308789767.206 Interim result: 16.00 MBytes/s over 1.36 seconds ending at 1308789768.566 Interim result: 20.66 MBytes/s over 1.36 seconds ending at 1308789769.922 Interim result: 22.74 MBytes/s over 1.36 seconds ending at 1308789771.285 Interim result: 23.07 MBytes/s over 1.36 seconds ending at 1308789772.647 Interim result: 23.77 MBytes/s over 1.37 seconds ending at 1308789774.016 Recv Send Send Socket Socket Message Elapsed Size Size Size Time Throughput bytes bytes bytes secs. MBytes/sec 87380 16384 16384 10.06 17.81 @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 not by relying on interval timers or frequent calls to get the current time, but by calculating how many units of work must be performed to take at least the desired interval. Those familiar with this option in earlier versions of netperf will note the addition of the ``ending at'' text. This is the time as reported by a @code{gettimeofday()} call (or its emulation) with a @code{NULL} timezone pointer. This addition is intended to make it easier to insert interim results into an @uref{http://oss.oetiker.ch/rrdtool/doc/rrdtool.en.html,rrdtool} Round-Robin Database (RRD). A likely bug-riddled example of doing so can be found in @file{doc/examples/netperf_interim_to_rrd.sh}. The time is reported out to milliseconds rather than microseconds because that is the most rrdtool understands as of the time of this writing. 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 having been previously started as its own standalone daemon. When you execute netperf it will establish 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 @node CPU Utilization, , The Design of Netperf, The Design of Netperf @section CPU Utilization @cindex 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 and portably. Netperf will do its level best to report accurate CPU utilization figures, but some combinations of processor, OS and configuration may make that difficult. 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 and thus ``better.'' 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.31 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 whereby 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 consumption, it has been suggested that this mechanism may become slightly confused, in which case using BIOS/uEFI 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 11iv2 and later are known/presumed 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. @menu * CPU Utilization in a Virtual Guest:: @end menu @node CPU Utilization in a Virtual Guest, , CPU Utilization, CPU Utilization @subsection CPU Utilization in a Virtual Guest The CPU utilization mechanisms used by netperf are ``inline'' in that they are run by the same netperf or netserver process as is running the test itself. This works just fine for ``bare iron'' tests but runs into a problem when using virtual machines. The relationship between virtual guest and hypervisor can be thought of as being similar to that between a process and kernel in a bare iron system. As such, (m)any CPU utilization mechanisms used in the virtual guest are similar to ``process-local'' mechanisms in a bare iron situation. However, just as with bare iron and process-local mechanisms, much networking processing happens outside the context of the virtual guest. It takes place in the hypervisor, and is not visible to mechanisms running in the guest(s). For this reason, one should not really trust CPU utilization figures reported by netperf or netserver when running in a virtual guest. If one is looking to measure the added overhead of a virtualization mechanism, rather than rely on CPU utilization, one can rely instead on netperf _RR tests - path-lengths and overheads can be a significant fraction of the latency, so increases in overhead should appear as decreases in transaction rate. Whatever you do, @b{DO NOT} rely on the throughput of a _STREAM test. Achieving link-rate can be done via a multitude of options that mask overhead rather than eliminate it. @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 if you wish :). 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|x 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. An argument of ``x'' requests the units be transactions per second and is only meaningful for a request-response test. [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 transferred 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 previously required for a TCP_SENDFILE test, later versions of netperf removed that restriction, creating a temporary file as needed. While the author cannot recall exactly when that took place, it is known to be unnecessary in version 2.5.0 and later. @vindex -h, Global @item -h This option causes netperf to display its ``global'' 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 ``linger'' 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 half 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 classic netperf test 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 In the example above we see that netperf did not meet the desired confidence 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. In an explicit ``omni'' test, failure to meet the confidence intervals will not result in netperf emitting a warning. To verify the hitting, or not, of the confidence intervals one will need to include them as part of an @ref{Omni Output Selection,output selection} in the test-specific @option{-o}, @option{-O} or @option{k} output selection options. The warning about not hitting the confidence intervals will remain in a ``migrated'' classic netperf test. @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. A classic or migrated netperf test will not display the actual number of iterations run. An @ref{The Omni Tests,omni test} will emit the number of iterations run if the @code{CONFIDENCE_ITERATION} output selector is included in the @ref{Omni Output Selection,output selection}. 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. Output of a warning upon not hitting the desired confidence intervals follows the description provided for the @option{-I} option. 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 -j, Global @item -j This option instructs netperf to keep additional timing statistics when explicitly running an @ref{The Omni Tests,omni test}. These can be output when the test-specific @option{-o}, @option{-O} or @option{-k} @ref{Omni Output Selectors,output selectors} include one or more of: @itemize @item MIN_LATENCY @item MAX_LATENCY @item P50_LATENCY @item P90_LATENCY @item P99_LATENCY @item MEAN_LATENCY @item STDDEV_LATENCY @end itemize These statistics will be based on an expanded (100 buckets per row rather than 10) histogram of times rather than a terribly long list of individual times. As such, there will be some slight error thanks to the bucketing. However, the reduction in storage and processing overheads is well worth it. When running a request/response test, one might get some idea of the error by comparing the @ref{Omni Output Selectors,@code{MEAN_LATENCY}} calculated from the histogram with the @code{RT_LATENCY} calculated from the number of request/response transactions and the test run time. In the case of a request/response test the latencies will be transaction latencies. In the case of a receive-only test they will be time spent in the receive call. In the case of a send-only test they will be time spent in the send call. The units will be microseconds. Added in netperf 2.5.0. @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. This limitation may be relaxed in an @ref{The Omni Tests,omni} test. 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. As it is almost universally possible for netperf/netserver to determine the number of CPUs on the system automagically, 99 times out of 10 this option should not be necessary and may be removed in a future release of netperf. @vindex -N, Global @item -N This option tells netperf to forgo 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 displayed as values which 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 (netperf) 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 (netserver) 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 -s, Global @item -s This option will cause netperf to sleep @samp{} before actually transferring data over the data connection. This may be useful in situations where one wishes to start a great many netperf instances and do not want the earlier ones affecting the ability of the later ones to get established. Added somewhere between versions 2.4.3 and 2.5.0. @vindex -S, Global @item -S This option will cause an attempt to be made to set SO_KEEPALIVE on the data socket of a test using the BSD sockets interface. The attempt will be made on the netperf side of all tests, and will be made on the netserver side of an @ref{The Omni Tests,omni} or @ref{Migrated Tests,migrated} test. No indication of failure is given unless debug output is enabled with the global @option{-d} option. Added in version 2.5.0. @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} @item @ref{The Omni Tests,OMNI} @end itemize Not all tests are always compiled into netperf. In particular, the ``XTI,'' ``SCTP,'' ``UNIXDOMAIN,'' and ``DL*'' tests are only included in netperf when configured with @option{--enable-[xti|sctp|unixdomain|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 -T, Global @item -T This option controls the CPU, and probably by extension memory, affinity of netperf and/or netserver. @example netperf -T 1 @end example will bind both netperf and netserver to ``CPU 1'' on their respective systems. @example netperf -T 1, @end example will bind just netperf to ``CPU 1'' and will leave netserver unbound. @example netperf -T ,2 @end example will leave netperf unbound and will bind netserver to ``CPU 2.'' @example netperf -T 1,2 @end example will bind netperf to ``CPU 1'' and netserver to ``CPU 2.'' This can be particularly useful when investigating performance issues involving where processes run relative to where NIC interrupts are processed or where NICs allocate their DMA buffers. @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] In an @ref{The Omni Tests,omni} test the verbosity setting is largely ignored, save for when asking for the time histogram to be displayed. In version 2.5.0 and later there is no @ref{Omni Output Selectors,output selector} for the histogram and so it remains displayed only when the verbosity level is set to 2. @vindex -V, Global @item -V This option displays the netperf version and then exits. Added in netperf 2.4.4. @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 classic 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). In that case, one might see as much as two CPUs' worth of processing being used to service the flow of data. 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 platform(s) of interest. If running a version 2.5.0 or later ``omni'' test under Linux one can include either or both of: @itemize @item LOCAL_TRANSPORT_RETRANS @item REMOTE_TRANSPORT_RETRANS @end itemize in the values provided via a test-specific @option{-o}, @option{-O}, or @option{-k} output selction option and netperf will report the retransmissions experienced on the data connection, as reported via a @code{getsockopt(TCP_INFO)} call. If confidence intervals have been requested via the global @option{-I} or @option{-i} options, the reported value(s) will be for the last iteration. If the test is over a protocol other than TCP, or on a platform other than Linux, the results are undefined. 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 (netperf) 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 @code{setsockopt()} call will be the value returned via a @code{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 (netserver) 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 remote 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 @code{setsockopt()} call will be the value returned via a @code{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, however Linux does ``auto tuning'' of socket buffer and TCP window sizes, which means the send socket buffer size may be different at the end of the test than it was at the beginning. This is addressed in the @ref{The Omni Tests,omni tests} added in version 2.5.0 and @ref{Omni Output Selection,output selection}. Throughput 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 @code{getsockopt()} as was requested in the prior @code{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. As of some time before version 2.5.0, the @ref{Global Options,global @option{-F} option} is no longer required for this test. If it is not specified, netperf will create a temporary file, which it will delete at the end of the test. If the @option{-F} option is specified it must reference 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 remain 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 $ 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 DLPI 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-unixdomain=yes}. The remote netserver must have also been configured with @code{--enable-unixdomain=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-unixdomain=yes}. The remote netserver must have also been configured with @code{--enable-unixdomain=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, and stateless offloads like TSO and LRO can cover a multitude of latency and even path-length sins, those sins 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 a time test such as those found by default in netperf, is particularly sensitive to the path-length of the networking stack. An _RR test can also uncover those platforms where the NICs 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 transferred per second, by default 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. As of version 2.5.0 (actually slightly before) netperf still does not do the latter, but will do the former if one sets the verbosity to 2 for a classic netperf test, or includes the appropriate @ref{Omni Output Selectors,output selector} in an @ref{The Omni Tests,omni test}. It will also allow the user to switch the throughput units from transactions per second to bits or bytes per second with the global @option{-f} option. @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 Request/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. Virtualization may considerably increase the effective path length of a networking stack. While this may not preclude achieving link-rate on a comparatively slow link (eg 1 Gigabit Ethernet) on a _STREAM test, it can show-up as measurably fewer transactions per second on an _RR test. However, this may still be masked by interrupt coalescing in the NIC/driver. 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 distinguished 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 driver 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 (netperf) 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 (netperf) 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 (netserver) 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 remote (netserver) 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 @subsection TCP_RR @cindex Measuring Latency @cindex Latency, Request-Response 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 thought-of as a user-space to user-space @code{ping} with no think time - it is by default 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 @ref{TCP_CC,TPC_CC} or @ref{TCP_CRR,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 for the time :) @node TCP_CC, TCP_CRR, TCP_RR, Options Common to TCP UDP and SCTP _RR tests @subsection TCP_CC @cindex Connection Latency @cindex Latency, Connection Establishment 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, such as Window Scaling or Timestamps. 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 @subsection TCP_CRR @cindex Latency, Connection Establishment @cindex Latency, Request-Response 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_CRR test is like a merger of a @ref{TCP_RR} and @ref{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 @subsection UDP_RR @cindex Latency, Request-Response @cindex Packet Loss 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. If @option{--enable-burst} was included in the @code{configure} command and a test-specific @option{-b} option used, the UDP_RR test will ``survive'' the loss of requests and responses until the sum is one more than the value passed via the @option{-b} option. It will though almost certainly run more slowly. 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 @subsection XTI_TCP_RR @cindex Latency, Request-Response 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 @subsection XTI_TCP_CC @cindex Latency, Connection Establishment An XTI_TCP_CC test is essentially the same as a @ref{TCP_CC,TCP_CC} test, only using the XTI rather than BSD Sockets interface. The test-specific options for an XTI_TCP_CC test are the same as those for a TCP_CC 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_CRR, XTI_UDP_RR, XTI_TCP_CC, Options Common to TCP UDP and SCTP _RR tests @comment node-name, next, previous, up @subsection XTI_TCP_CRR @cindex Latency, Connection Establishment @cindex Latency, Request-Response The XTI_TCP_CRR test is essentially the same as a @ref{TCP_CRR,TCP_CRR} test, only using the XTI rather than BSD Sockets interface. The test-specific options for an XTI_TCP_CRR 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_UDP_RR, DLCL_RR, XTI_TCP_CRR, Options Common to TCP UDP and SCTP _RR tests @subsection XTI_UDP_RR @cindex Latency, Request-Response 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 @subsection DLCL_RR @cindex Latency, Request-Response @node DLCO_RR, SCTP_RR, DLCL_RR, Options Common to TCP UDP and SCTP _RR tests @comment node-name, next, previous, up @subsection DLCO_RR @cindex Latency, Request-Response @node SCTP_RR, , DLCO_RR, Options Common to TCP UDP and SCTP _RR tests @comment node-name, next, previous, up @subsection SCTP_RR @cindex Latency, Request-Response @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 @chapter Using Netperf to Measure Aggregate Performance @cindex Aggregate Performance @vindex --enable-burst, Configure Ultimately, @ref{Netperf4,Netperf4} will be the preferred benchmark to use when one wants to measure aggregate performance because netperf has no support for explicit synchronization of concurrent tests. Until netperf4 is ready for prime time, one can make use of the heuristics and procedures mentioned here for the 85% solution. There are a few 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. The third is a variation on the first. @menu * Running Concurrent Netperf Tests:: * Using --enable-burst:: * Using --enable-demo:: @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. This method does not need to be limited to one system speaking to one other system. It can be extended to one system talking to N other systems. It could be as simple as: @example for host in 'foo bar baz bing' do netperf -t TCP_STREAM -H $hosts -i 10 -P 0 & done @end example A more complicated/sophisticated example can be found in @file{doc/examples/runemomniagg2.sh} where. 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. Presumably 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. As the number of CPUs in the system increases, and so too the odds of saturating a single CPU, the accuracy of similar CPU utilization implying little skew error is diminished. This is also the case for those increasingly rare single CPU systems if the utilization is reported as 100% or very close to it. @quotation @b{NOTE: It is very important to remember 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 will eventually be the preferred tool for aggregate tests. Even if you see the Netperf Contributing Editor acting to the contrary!-) @menu * Issues in Running Concurrent Tests:: @end menu @node Issues in Running Concurrent Tests, , Running Concurrent Netperf Tests, Running Concurrent Netperf Tests @subsection Issues in Running Concurrent Tests In addition to the aforementioned issue of skew error, there can be other issues to consider when running concurrent netperf tests. For example, when running concurrent tests over multiple interfaces, one is not always assured that the traffic one thinks went over a given interface actually did so. In particular, the Linux networking stack takes a particularly strong stance on its following the so called @samp{weak end system model}. As such, it is willing to answer ARP requests for any of its local IP addresses on any of its interfaces. If multiple interfaces are connected to the same broadcast domain, then even if they are configured into separate IP subnets there is no a priori way of knowing which interface was actually used for which connection(s). This can be addressed by setting the @samp{arp_ignore} sysctl before configuring interfaces. As it is quite important, we will repeat that it is very important to remember that each concurrent netperf instance is calculating system-wide CPU utilization. When calculating the service demand each netperf assumes it is the only thing running on the system. This means that for concurrent tests the service demands reported by netperf @b{will be wrong}. One has to compute service demands for concurrent tests by hand Running concurrent tests can also become difficult when there is no one ``central'' node. Running tests between pairs of systems may be more difficult, calling for remote shell commands in the for loop rather than netperf commands. This introduces more skew error, which the confidence intervals may not be able to sufficiently mitigate. One possibility is to actually run three consecutive netperf tests on each node - the first being a warm-up, the last being a cool-down. The idea then is to ensure that the time it takes to get all the netperfs started is less than the length of the first netperf command in the sequence of three. Similarly, it assumes that all ``middle'' netperfs will complete before the first of the ``last'' netperfs complete. @node Using --enable-burst, Using --enable-demo, Running Concurrent Netperf Tests, Using Netperf to Measure Aggregate Performance @comment node-name, next, previous, up @section Using - -enable-burst Starting in version 2.5.0 @code{--enable-burst=yes} is the default, which means one no longer must: @example configure --enable-burst @end example To have burst-mode functionality present in netperf. This enables a test-specific @option{-b num} option in @ref{TCP_RR,TCP_RR}, @ref{UDP_RR,UDP_RR} and @ref{The Omni Tests,omni} tests. Normally, netperf will attempt to ramp-up the number of outstanding requests to @option{num} plus one transactions in flight at one time. The ramp-up is to avoid transactions being smashed together into a smaller number of segments when the transport's congestion window (if any) is smaller at the time than what netperf wants to have outstanding at one time. If, however, the user specifies a negative value for @option{num} this ramp-up is bypassed and the burst of sends is made without consideration of transport congestion window. This burst-mode is used as an alternative to or even in conjunction with multiple-concurrent _RR tests and as a way to implement a single-connection, bidirectional bulk-transfer test. When run with just a single instance of netperf, increasing the burst size can determine the maximum number of transactions per second which 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} increase 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 even in the absence of transport congestion window issues. 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 exercise 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 exercise 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 --enable-demo, , Using --enable-burst, Using Netperf to Measure Aggregate Performance @section Using - -enable-demo One can @example configure --enable-demo @end example and compile netperf to enable netperf to emit ``interim results'' at semi-regular intervals. This enables a global @code{-D} option which takes a reporting interval as an argument. With that specified, the output of netperf will then look something like @example $ src/netperf -D 1.25 MIGRATED TCP STREAM TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to localhost.localdomain () port 0 AF_INET : demo Interim result: 25425.52 10^6bits/s over 1.25 seconds ending at 1327962078.405 Interim result: 25486.82 10^6bits/s over 1.25 seconds ending at 1327962079.655 Interim result: 25474.96 10^6bits/s over 1.25 seconds ending at 1327962080.905 Interim result: 25523.49 10^6bits/s over 1.25 seconds ending at 1327962082.155 Interim result: 25053.57 10^6bits/s over 1.27 seconds ending at 1327962083.429 Interim result: 25349.64 10^6bits/s over 1.25 seconds ending at 1327962084.679 Interim result: 25292.84 10^6bits/s over 1.25 seconds ending at 1327962085.932 Recv Send Send Socket Socket Message Elapsed Size Size Size Time Throughput bytes bytes bytes secs. 10^6bits/sec 87380 16384 16384 10.00 25375.66 @end example The units of the ``Interim result'' lines will follow the units selected via the global @code{-f} option. If the test-specific @code{-o} option is specified on the command line, the format will be CSV: @example ... 2978.81,MBytes/s,1.25,1327962298.035 ... @end example If the test-specific @code{-k} option is used the format will be keyval with each keyval being given an index: @example ... NETPERF_INTERIM_RESULT[2]=25.00 NETPERF_UNITS[2]=10^9bits/s NETPERF_INTERVAL[2]=1.25 NETPERF_ENDING[2]=1327962357.249 ... @end example The expectation is it may be easier to utilize the keyvals if they have indices. But how does this help with aggregate tests? Well, what one can do is start the netperfs via a script, giving each a Very Long (tm) run time. Direct the output to a file per instance. Then, once all the netperfs have been started, take a timestamp and wait for some desired test interval. Once that interval expires take another timestamp and then start terminating the netperfs by sending them a SIGALRM signal via the likes of the @code{kill} or @code{pkill} command. The netperfs will terminate and emit the rest of the ``usual'' output, and you can then bring the files to a central location for post processing to find the aggregate performance over the ``test interval.'' This method has the advantage that it does not require advance knowledge of how long it takes to get netperf tests started and/or stopped. It does though require sufficiently synchronized clocks on all the test systems. While calls to get the current time can be inexpensive, that neither has been nor is universally true. For that reason netperf tries to minimize the number of such ``timestamping'' calls (eg @code{gettimeofday}) calls it makes when in demo mode. Rather than take a timestamp after each @code{send} or @code{recv} call completes netperf tries to guess how many units of work will be performed over the desired interval. Only once that many units of work have been completed will netperf check the time. If the reporting interval has passed, netperf will emit an ``interim result.'' If the interval has not passed, netperf will update its estimate for units and continue. After a bit of thought one can see that if things ``speed-up'' netperf will still honor the interval. However, if things ``slow-down'' netperf may be late with an ``interim result.'' Here is an example of both of those happening during a test - with the interval being honored while throughput increases, and then about half-way through when another netperf (not shown) is started we see things slowing down and netperf not hitting the interval as desired. @example $ src/netperf -D 2 -H tardy.hpl.hp.com -l 20 MIGRATED TCP STREAM TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to tardy.hpl.hp.com () port 0 AF_INET : demo Interim result: 36.46 10^6bits/s over 2.01 seconds ending at 1327963880.565 Interim result: 59.19 10^6bits/s over 2.00 seconds ending at 1327963882.569 Interim result: 73.39 10^6bits/s over 2.01 seconds ending at 1327963884.576 Interim result: 84.01 10^6bits/s over 2.03 seconds ending at 1327963886.603 Interim result: 75.63 10^6bits/s over 2.21 seconds ending at 1327963888.814 Interim result: 55.52 10^6bits/s over 2.72 seconds ending at 1327963891.538 Interim result: 70.94 10^6bits/s over 2.11 seconds ending at 1327963893.650 Interim result: 80.66 10^6bits/s over 2.13 seconds ending at 1327963895.777 Interim result: 86.42 10^6bits/s over 2.12 seconds ending at 1327963897.901 Recv Send Send Socket Socket Message Elapsed Size Size Size Time Throughput bytes bytes bytes secs. 10^6bits/sec 87380 16384 16384 20.34 68.87 @end example So long as your post-processing mechanism can account for that, there should be no problem. As time passes there may be changes to try to improve the netperf's honoring the interval but one should not ass-u-me it will always do so. One should not assume the precision will remain fixed - future versions may change it - perhaps going beyond tenths of seconds in reporting the interval length etc. @node Using Netperf to Measure Bidirectional Transfer, The Omni 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 performance 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:: * Implications of Concurrent Tests vs Burst Request/Response:: @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}. Beginning with version 2.5.0 we can accomplish a similar result with the @ref{The Omni Tests,the omni tests} and @ref{Omni Output Selectors,output selectors}: @example for i in 1 do netperf -H 192.168.1.3 -t omni -l 10 -P 0 -- \ -d stream -s 256K -S 256K -o throughput,direction & netperf -H 192.168.1.3 -t omni -l 10 -P 0 -- \ -d maerts -s 256K -S 256K -o throughput,direction & done 805.26,Receive 828.54,Send @end example @node Bidirectional Transfer with TCP_RR, Implications of Concurrent Tests vs Burst Request/Response, Bidirectional Transfer with Concurrent Tests, Using Netperf to Measure Bidirectional Transfer @comment node-name, next, previous, up @section Bidirectional Transfer with TCP_RR Starting with version 2.5.0 the @code{--enable-burst} configure option defaults to @code{yes}, and starting some time before version 2.5.0 but after 2.4.0 the global @option{-f} option would affect the ``throughput'' reported by request/response tests. If one uses the test-specific @option{-b} option to have several ``transactions'' in flight at one time and the test-specific @option{-r} option to increase their size, the test looks more and more like a single-connection bidirectional transfer than a simple request/response test. So, putting it all together one can do something like: @example netperf -f m -t TCP_RR -H 192.168.1.3 -v 2 -- -b 6 -r 32K -S 256K -S 256K MIGRATED TCP REQUEST/RESPONSE TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to 192.168.1.3 (192.168.1.3) port 0 AF_INET : interval : first burst 6 Local /Remote Socket Size Request Resp. Elapsed Send Recv Size Size Time Throughput bytes Bytes bytes bytes secs. 10^6bits/sec 16384 87380 32768 32768 10.00 1821.30 524288 524288 Alignment Offset RoundTrip Trans Throughput Local Remote Local Remote Latency Rate 10^6bits/s Send Recv Send Recv usec/Tran per sec Outbound Inbound 8 0 0 0 2015.402 3473.252 910.492 910.492 @end example to get a bidirectional bulk-throughput result. As one can see, the -v 2 output will include a number of interesting, related values. @quotation @b{NOTE: The logic behind @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()}.} @end quotation 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. @node Implications of Concurrent Tests vs Burst Request/Response, , Bidirectional Transfer with TCP_RR, Using Netperf to Measure Bidirectional Transfer @section Implications of Concurrent Tests vs Burst Request/Response There are perhaps subtle but important differences between using concurrent unidirectional tests vs a burst-mode request to measure bidirectional performance. Broadly speaking, a single ``connection'' or ``flow'' of traffic cannot make use of the services of more than one or two CPUs at either end. Whether one or two CPUs will be used processing a flow will depend on the specifics of the stack(s) involved and whether or not the global @option{-T} option has been used to bind netperf/netserver to specific CPUs. When using concurrent tests there will be two concurrent connections or flows, which means that upwards of four CPUs will be employed processing the packets (global @option{-T} used, no more than two if not), however, with just a single, bidirectional request/response test no more than two CPUs will be employed (only one if the global @option{-T} is not used). If there is a CPU bottleneck on either system this may result in rather different results between the two methods. Also, with a bidirectional request/response test there is something of a natural balance or synchronization between inbound and outbound - a response will not be sent until a request is received, and (once the burst level is reached) a subsequent request will not be sent until a response is received. This may mask favoritism in the NIC between inbound and outbound processing. With two concurrent unidirectional tests there is no such synchronization or balance and any favoritism in the NIC may be exposed. @node The Omni Tests, Other Netperf Tests, Using Netperf to Measure Bidirectional Transfer, Top @chapter The Omni Tests Beginning with version 2.5.0, netperf begins a migration to the @samp{omni} tests or ``Two routines to measure them all.'' The code for the omni tests can be found in @file{src/nettest_omni.c} and the goal is to make it easier for netperf to support multiple protocols and report a great many additional things about the systems under test. Additionally, a flexible output selection mechanism is present which allows the user to chose specifically what values she wishes to have reported and in what format. The omni tests are included by default in version 2.5.0. To disable them, one must: @example ./configure --enable-omni=no ... @end example and remake netperf. Remaking netserver is optional because even in 2.5.0 it has ``unmigrated'' netserver side routines for the classic (eg @file{src/nettest_bsd.c}) tests. @menu * Native Omni Tests:: * Migrated Tests:: * Omni Output Selection:: @end menu @node Native Omni Tests, Migrated Tests, The Omni Tests, The Omni Tests @section Native Omni Tests One access the omni tests ``natively'' by using a value of ``OMNI'' with the global @option{-t} test-selection option. This will then cause netperf to use the code in @file{src/nettest_omni.c} and in particular the test-specific options parser for the omni tests. The test-specific options for the omni tests are a superset of those for ``classic'' tests. The options added by the omni tests are: @table @code @vindex -c, Test-specific @item -c This explicitly declares that the test is to include connection establishment and tear-down as in either a TCP_CRR or TCP_CC test. @vindex -d, Test-specific @item -d This option sets the direction of the test relative to the netperf process. As of version 2.5.0 one can use the following in a case-insensitive manner: @table @code @item send, stream, transmit, xmit or 2 Any of which will cause netperf to send to the netserver. @item recv, receive, maerts or 4 Any of which will cause netserver to send to netperf. @item rr or 6 Either of which will cause a request/response test. @end table Additionally, one can specify two directions separated by a '|' character and they will be OR'ed together. In this way one can use the ''Send|Recv'' that will be emitted by the @ref{Omni Output Selectors,DIRECTION} @ref{Omni Output Selection,output selector} when used with a request/response test. @vindex -k, Test-specific @item -k [@ref{Omni Output Selection,output selector}] This option sets the style of output to ``keyval'' where each line of output has the form: @example key=value @end example For example: @example $ netperf -t omni -- -d rr -k "THROUGHPUT,THROUGHPUT_UNITS" OMNI 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 : demo THROUGHPUT=59092.65 THROUGHPUT_UNITS=Trans/s @end example Using the @option{-k} option will override any previous, test-specific @option{-o} or @option{-O} option. @vindex -o, Test-specific @item -o [@ref{Omni Output Selection,output selector}] This option sets the style of output to ``CSV'' where there will be one line of comma-separated values, preceded by one line of column names unless the global @option{-P} option is used with a value of 0: @example $ netperf -t omni -- -d rr -o "THROUGHPUT,THROUGHPUT_UNITS" OMNI 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 : demo Throughput,Throughput Units 60999.07,Trans/s @end example Using the @option{-o} option will override any previous, test-specific @option{-k} or @option{-O} option. @vindex -O, Test-specific @item -O [@ref{Omni Output Selection,output selector}] This option sets the style of output to ``human readable'' which will look quite similar to classic netperf output: @example $ netperf -t omni -- -d rr -O "THROUGHPUT,THROUGHPUT_UNITS" OMNI 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 : demo Throughput Throughput Units 60492.57 Trans/s @end example Using the @option{-O} option will override any previous, test-specific @option{-k} or @option{-o} option. @vindex -t, Test-specific @item -t This option explicitly sets the socket type for the test's data connection. As of version 2.5.0 the known socket types include ``stream'' and ``dgram'' for SOCK_STREAM and SOCK_DGRAM respectively. @vindex -T, Test-specific @item -T This option is used to explicitly set the protocol used for the test. It is case-insensitive. As of version 2.5.0 the protocols known to netperf include: @table @code @item TCP Select the Transmission Control Protocol @item UDP Select the User Datagram Protocol @item SDP Select the Sockets Direct Protocol @item DCCP Select the Datagram Congestion Control Protocol @item SCTP Select the Stream Control Transport Protocol @item udplite Select UDP Lite @end table The default is implicit based on other settings. @end table The omni tests also extend the interpretation of some of the classic, test-specific options for the BSD Sockets tests: @table @code @item -m This can set the send size for either or both of the netperf and netserver sides of the test: @example -m 32K @end example sets only the netperf-side send size to 32768 bytes, and or's-in transmit for the direction. This is effectively the same behaviour as for the classic tests. @example -m ,32K @end example sets only the netserver side send size to 32768 bytes and or's-in receive for the direction. @example -m 16K,32K sets the netperf side send size to 16284 bytes, the netserver side send size to 32768 bytes and the direction will be "Send|Recv." @end example @item -M This can set the receive size for either or both of the netperf and netserver sides of the test: @example -M 32K @end example sets only the netserver side receive size to 32768 bytes and or's-in send for the test direction. @example -M ,32K @end example sets only the netperf side receive size to 32768 bytes and or's-in receive for the test direction. @example -M 16K,32K @end example sets the netserver side receive size to 16384 bytes and the netperf side receive size to 32768 bytes and the direction will be "Send|Recv." @end table @node Migrated Tests, Omni Output Selection, Native Omni Tests, The Omni Tests @section Migrated Tests As of version 2.5.0 several tests have been migrated to use the omni code in @file{src/nettest_omni.c} for the core of their testing. A migrated test retains all its previous output code and so should still ``look and feel'' just like a pre-2.5.0 test with one exception - the first line of the test banners will include the word ``MIGRATED'' at the beginning as in: @example $ netperf MIGRATED 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 : demo Recv Send Send Socket Socket Message Elapsed Size Size Size Time Throughput bytes bytes bytes secs. 10^6bits/sec 87380 16384 16384 10.00 27175.27 @end example The tests migrated in version 2.5.0 are: @itemize @item TCP_STREAM @item TCP_MAERTS @item TCP_RR @item TCP_CRR @item UDP_STREAM @item UDP_RR @end itemize It is expected that future releases will have additional tests migrated to use the ``omni'' functionality. If one uses ``omni-specific'' test-specific options in conjunction with a migrated test, instead of using the classic output code, the new omni output code will be used. For example if one uses the @option{-k} test-specific option with a value of ``MIN_LATENCY,MAX_LATENCY'' with a migrated TCP_RR test one will see: @example $ netperf -t tcp_rr -- -k THROUGHPUT,THROUGHPUT_UNITS MIGRATED TCP REQUEST/RESPONSE 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 : demo THROUGHPUT=60074.74 THROUGHPUT_UNITS=Trans/s @end example rather than: @example $ netperf -t tcp_rr MIGRATED TCP REQUEST/RESPONSE 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 : demo 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 59421.52 16384 87380 @end example @node Omni Output Selection, , Migrated Tests, The Omni Tests @section Omni Output Selection The omni test-specific @option{-k}, @option{-o} and @option{-O} options take an optional @code{output selector} by which the user can configure what values are reported. The output selector can take several forms: @table @code @item @file{filename} The output selections will be read from the named file. Within the file there can be up to four lines of comma-separated output selectors. This controls how many multi-line blocks of output are emitted when the @option{-O} option is used. This output, while not identical to ``classic'' netperf output, is inspired by it. Multiple lines have no effect for @option{-k} and @option{-o} options. Putting output selections in a file can be useful when the list of selections is long. @item comma and/or semi-colon-separated list The output selections will be parsed from a comma and/or semi-colon-separated list of output selectors. When the list is given to a @option{-O} option a semi-colon specifies a new output block should be started. Semi-colons have the same meaning as commas when used with the @option{-k} or @option{-o} options. Depending on the command interpreter being used, the semi-colon may have to be escaped somehow to keep it from being interpreted by the command interpreter. This can often be done by enclosing the entire list in quotes. @item all If the keyword @b{all} is specified it means that all known output values should be displayed at the end of the test. This can be a great deal of output. As of version 2.5.0 there are 157 different output selectors. @item ? If a ``?'' is given as the output selection, the list of all known output selectors will be displayed and no test actually run. When passed to the @option{-O} option they will be listed one per line. Otherwise they will be listed as a comma-separated list. It may be necessary to protect the ``?'' from the command interpreter by escaping it or enclosing it in quotes. @item no selector If nothing is given to the @option{-k}, @option{-o} or @option{-O} option then the code selects a default set of output selectors inspired by classic netperf output. The format will be the @samp{human readable} format emitted by the test-specific @option{-O} option. @end table The order of evaluation will first check for an output selection. If none is specified with the @option{-k}, @option{-o} or @option{-O} option netperf will select a default based on the characteristics of the test. If there is an output selection, the code will first check for @samp{?}, then check to see if it is the magic @samp{all} keyword. After that it will check for either @samp{,} or @samp{;} in the selection and take that to mean it is a comma and/or semi-colon-separated list. If none of those checks match, netperf will then assume the output specification is a filename and attempt to open and parse the file. @menu * Omni Output Selectors:: @end menu @node Omni Output Selectors, , Omni Output Selection, Omni Output Selection @subsection Omni Output Selectors As of version 2.5.0 the output selectors are: @table @code @item OUTPUT_NONE This is essentially a null output. For @option{-k} output it will simply add a line that reads ``OUTPUT_NONE='' to the output. For @option{-o} it will cause an empty ``column'' to be included. For @option{-O} output it will cause extra spaces to separate ``real'' output. @item SOCKET_TYPE This will cause the socket type (eg SOCK_STREAM, SOCK_DGRAM) for the data connection to be output. @item PROTOCOL This will cause the protocol used for the data connection to be displayed. @item DIRECTION This will display the data flow direction relative to the netperf process. Units: Send or Recv for a unidirectional bulk-transfer test, or Send|Recv for a request/response test. @item ELAPSED_TIME This will display the elapsed time in seconds for the test. @item THROUGHPUT This will display the throughput for the test. Units: As requested via the global @option{-f} option and displayed by the THROUGHPUT_UNITS output selector. @item THROUGHPUT_UNITS This will display the units for what is displayed by the @code{THROUGHPUT} output selector. @item LSS_SIZE_REQ This will display the local (netperf) send socket buffer size (aka SO_SNDBUF) requested via the command line. Units: Bytes. @item LSS_SIZE This will display the local (netperf) send socket buffer size (SO_SNDBUF) immediately after the data connection socket was created. Peculiarities of different networking stacks may lead to this differing from the size requested via the command line. Units: Bytes. @item LSS_SIZE_END This will display the local (netperf) send socket buffer size (SO_SNDBUF) immediately before the data connection socket is closed. Peculiarities of different networking stacks may lead this to differ from the size requested via the command line and/or the size immediately after the data connection socket was created. Units: Bytes. @item LSR_SIZE_REQ This will display the local (netperf) receive socket buffer size (aka SO_RCVBUF) requested via the command line. Units: Bytes. @item LSR_SIZE This will display the local (netperf) receive socket buffer size (SO_RCVBUF) immediately after the data connection socket was created. Peculiarities of different networking stacks may lead to this differing from the size requested via the command line. Units: Bytes. @item LSR_SIZE_END This will display the local (netperf) receive socket buffer size (SO_RCVBUF) immediately before the data connection socket is closed. Peculiarities of different networking stacks may lead this to differ from the size requested via the command line and/or the size immediately after the data connection socket was created. Units: Bytes. @item RSS_SIZE_REQ This will display the remote (netserver) send socket buffer size (aka SO_SNDBUF) requested via the command line. Units: Bytes. @item RSS_SIZE This will display the remote (netserver) send socket buffer size (SO_SNDBUF) immediately after the data connection socket was created. Peculiarities of different networking stacks may lead to this differing from the size requested via the command line. Units: Bytes. @item RSS_SIZE_END This will display the remote (netserver) send socket buffer size (SO_SNDBUF) immediately before the data connection socket is closed. Peculiarities of different networking stacks may lead this to differ from the size requested via the command line and/or the size immediately after the data connection socket was created. Units: Bytes. @item RSR_SIZE_REQ This will display the remote (netserver) receive socket buffer size (aka SO_RCVBUF) requested via the command line. Units: Bytes. @item RSR_SIZE This will display the remote (netserver) receive socket buffer size (SO_RCVBUF) immediately after the data connection socket was created. Peculiarities of different networking stacks may lead to this differing from the size requested via the command line. Units: Bytes. @item RSR_SIZE_END This will display the remote (netserver) receive socket buffer size (SO_RCVBUF) immediately before the data connection socket is closed. Peculiarities of different networking stacks may lead this to differ from the size requested via the command line and/or the size immediately after the data connection socket was created. Units: Bytes. @item LOCAL_SEND_SIZE This will display the size of the buffers netperf passed in any ``send'' calls it made on the data connection for a non-request/response test. Units: Bytes. @item LOCAL_RECV_SIZE This will display the size of the buffers netperf passed in any ``receive'' calls it made on the data connection for a non-request/response test. Units: Bytes. @item REMOTE_SEND_SIZE This will display the size of the buffers netserver passed in any ``send'' calls it made on the data connection for a non-request/response test. Units: Bytes. @item REMOTE_RECV_SIZE This will display the size of the buffers netserver passed in any ``receive'' calls it made on the data connection for a non-request/response test. Units: Bytes. @item REQUEST_SIZE This will display the size of the requests netperf sent in a request-response test. Units: Bytes. @item RESPONSE_SIZE This will display the size of the responses netserver sent in a request-response test. Units: Bytes. @item LOCAL_CPU_UTIL This will display the overall CPU utilization during the test as measured by netperf. Units: 0 to 100 percent. @item LOCAL_CPU_METHOD This will display the method used by netperf to measure CPU utilization. Units: single character denoting method. @item LOCAL_SD This will display the service demand, or units of CPU consumed per unit of work, as measured by netperf. Units: microseconds of CPU consumed per either KB (K==1024) of data transferred or request/response transaction. @item REMOTE_CPU_UTIL This will display the overall CPU utilization during the test as measured by netserver. Units 0 to 100 percent. @item REMOTE_CPU_METHOD This will display the method used by netserver to measure CPU utilization. Units: single character denoting method. @item REMOTE_SD This will display the service demand, or units of CPU consumed per unit of work, as measured by netserver. Units: microseconds of CPU consumed per either KB (K==1024) of data transferred or request/response transaction. @item SD_UNITS This will display the units for LOCAL_SD and REMOTE_SD @item CONFIDENCE_LEVEL This will display the confidence level requested by the user either explicitly via the global @option{-I} option, or implicitly via the global @option{-i} option. The value will be either 95 or 99 if confidence intervals have been requested or 0 if they were not. Units: Percent @item CONFIDENCE_INTERVAL This will display the width of the confidence interval requested either explicitly via the global @option{-I} option or implicitly via the global @option{-i} option. Units: Width in percent of mean value computed. A value of -1.0 means that confidence intervals were not requested. @item CONFIDENCE_ITERATION This will display the number of test iterations netperf undertook, perhaps while attempting to achieve the requested confidence interval and level. If confidence intervals were requested via the command line then the value will be between 3 and 30. If confidence intervals were not requested the value will be 1. Units: Iterations @item THROUGHPUT_CONFID This will display the width of the confidence interval actually achieved for @code{THROUGHPUT} during the test. Units: Width of interval as percentage of reported throughput value. @item LOCAL_CPU_CONFID This will display the width of the confidence interval actually achieved for overall CPU utilization on the system running netperf (@code{LOCAL_CPU_UTIL}) during the test, if CPU utilization measurement was enabled. Units: Width of interval as percentage of reported CPU utilization. @item REMOTE_CPU_CONFID This will display the width of the confidence interval actually achieved for overall CPU utilization on the system running netserver (@code{REMOTE_CPU_UTIL}) during the test, if CPU utilization measurement was enabled. Units: Width of interval as percentage of reported CPU utilization. @item TRANSACTION_RATE This will display the transaction rate in transactions per second for a request/response test even if the user has requested a throughput in units of bits or bytes per second via the global @option{-f} option. It is undefined for a non-request/response test. Units: Transactions per second. @item RT_LATENCY This will display the average round-trip latency for a request/response test, accounting for number of transactions in flight at one time. It is undefined for a non-request/response test. Units: Microseconds per transaction @item BURST_SIZE This will display the ``burst size'' or added transactions in flight in a request/response test as requested via a test-specific @option{-b} option. The number of transactions in flight at one time will be one greater than this value. It is undefined for a non-request/response test. Units: added Transactions in flight. @item LOCAL_TRANSPORT_RETRANS This will display the number of retransmissions experienced on the data connection during the test as determined by netperf. A value of -1 means the attempt to determine the number of retransmissions failed or the concept was not valid for the given protocol or the mechanism is not known for the platform. A value of -2 means it was not attempted. As of version 2.5.0 the meaning of values are in flux and subject to change. Units: number of retransmissions. @item REMOTE_TRANSPORT_RETRANS This will display the number of retransmissions experienced on the data connection during the test as determined by netserver. A value of -1 means the attempt to determine the number of retransmissions failed or the concept was not valid for the given protocol or the mechanism is not known for the platform. A value of -2 means it was not attempted. As of version 2.5.0 the meaning of values are in flux and subject to change. Units: number of retransmissions. @item TRANSPORT_MSS This will display the Maximum Segment Size (aka MSS) or its equivalent for the protocol being used during the test. A value of -1 means either the concept of an MSS did not apply to the protocol being used, or there was an error in retrieving it. Units: Bytes. @item LOCAL_SEND_THROUGHPUT The throughput as measured by netperf for the successful ``send'' calls it made on the data connection. Units: as requested via the global @option{-f} option and displayed via the @code{THROUGHPUT_UNITS} output selector. @item LOCAL_RECV_THROUGHPUT The throughput as measured by netperf for the successful ``receive'' calls it made on the data connection. Units: as requested via the global @option{-f} option and displayed via the @code{THROUGHPUT_UNITS} output selector. @item REMOTE_SEND_THROUGHPUT The throughput as measured by netserver for the successful ``send'' calls it made on the data connection. Units: as requested via the global @option{-f} option and displayed via the @code{THROUGHPUT_UNITS} output selector. @item REMOTE_RECV_THROUGHPUT The throughput as measured by netserver for the successful ``receive'' calls it made on the data connection. Units: as requested via the global @option{-f} option and displayed via the @code{THROUGHPUT_UNITS} output selector. @item LOCAL_CPU_BIND The CPU to which netperf was bound, if at all, during the test. A value of -1 means that netperf was not explicitly bound to a CPU during the test. Units: CPU ID @item LOCAL_CPU_COUNT The number of CPUs (cores, threads) detected by netperf. Units: CPU count. @item LOCAL_CPU_PEAK_UTIL The utilization of the CPU most heavily utilized during the test, as measured by netperf. This can be used to see if any one CPU of a multi-CPU system was saturated even though the overall CPU utilization as reported by @code{LOCAL_CPU_UTIL} was low. Units: 0 to 100% @item LOCAL_CPU_PEAK_ID The id of the CPU most heavily utilized during the test as determined by netperf. Units: CPU ID. @item LOCAL_CPU_MODEL Model information for the processor(s) present on the system running netperf. Assumes all processors in the system (as perceived by netperf) on which netperf is running are the same model. Units: Text @item LOCAL_CPU_FREQUENCY The frequency of the processor(s) on the system running netperf, at the time netperf made the call. Assumes that all processors present in the system running netperf are running at the same frequency. Units: MHz @item REMOTE_CPU_BIND The CPU to which netserver was bound, if at all, during the test. A value of -1 means that netperf was not explicitly bound to a CPU during the test. Units: CPU ID @item REMOTE_CPU_COUNT The number of CPUs (cores, threads) detected by netserver. Units: CPU count. @item REMOTE_CPU_PEAK_UTIL The utilization of the CPU most heavily utilized during the test, as measured by netserver. This can be used to see if any one CPU of a multi-CPU system was saturated even though the overall CPU utilization as reported by @code{REMOTE_CPU_UTIL} was low. Units: 0 to 100% @item REMOTE_CPU_PEAK_ID The id of the CPU most heavily utilized during the test as determined by netserver. Units: CPU ID. @item REMOTE_CPU_MODEL Model information for the processor(s) present on the system running netserver. Assumes all processors in the system (as perceived by netserver) on which netserver is running are the same model. Units: Text @item REMOTE_CPU_FREQUENCY The frequency of the processor(s) on the system running netserver, at the time netserver made the call. Assumes that all processors present in the system running netserver are running at the same frequency. Units: MHz @item SOURCE_PORT The port ID/service name to which the data socket created by netperf was bound. A value of 0 means the data socket was not explicitly bound to a port number. Units: ASCII text. @item SOURCE_ADDR The name/address to which the data socket created by netperf was bound. A value of 0.0.0.0 means the data socket was not explicitly bound to an address. Units: ASCII text. @item SOURCE_FAMILY The address family to which the data socket created by netperf was bound. A value of 0 means the data socket was not explicitly bound to a given address family. Units: ASCII text. @item DEST_PORT The port ID to which the data socket created by netserver was bound. A value of 0 means the data socket was not explicitly bound to a port number. Units: ASCII text. @item DEST_ADDR The name/address of the data socket created by netserver. Units: ASCII text. @item DEST_FAMILY The address family to which the data socket created by netserver was bound. A value of 0 means the data socket was not explicitly bound to a given address family. Units: ASCII text. @item LOCAL_SEND_CALLS The number of successful ``send'' calls made by netperf against its data socket. Units: Calls. @item LOCAL_RECV_CALLS The number of successful ``receive'' calls made by netperf against its data socket. Units: Calls. @item LOCAL_BYTES_PER_RECV The average number of bytes per ``receive'' call made by netperf against its data socket. Units: Bytes. @item LOCAL_BYTES_PER_SEND The average number of bytes per ``send'' call made by netperf against its data socket. Units: Bytes. @item LOCAL_BYTES_SENT The number of bytes successfully sent by netperf through its data socket. Units: Bytes. @item LOCAL_BYTES_RECVD The number of bytes successfully received by netperf through its data socket. Units: Bytes. @item LOCAL_BYTES_XFERD The sum of bytes sent and received by netperf through its data socket. Units: Bytes. @item LOCAL_SEND_OFFSET The offset from the alignment of the buffers passed by netperf in its ``send'' calls. Specified via the global @option{-o} option and defaults to 0. Units: Bytes. @item LOCAL_RECV_OFFSET The offset from the alignment of the buffers passed by netperf in its ``receive'' calls. Specified via the global @option{-o} option and defaults to 0. Units: Bytes. @item LOCAL_SEND_ALIGN The alignment of the buffers passed by netperf in its ``send'' calls as specified via the global @option{-a} option. Defaults to 8. Units: Bytes. @item LOCAL_RECV_ALIGN The alignment of the buffers passed by netperf in its ``receive'' calls as specified via the global @option{-a} option. Defaults to 8. Units: Bytes. @item LOCAL_SEND_WIDTH The ``width'' of the ring of buffers through which netperf cycles as it makes its ``send'' calls. Defaults to one more than the local send socket buffer size divided by the send size as determined at the time the data socket is created. Can be used to make netperf more processor data cache unfriendly. Units: number of buffers. @item LOCAL_RECV_WIDTH The ``width'' of the ring of buffers through which netperf cycles as it makes its ``receive'' calls. Defaults to one more than the local receive socket buffer size divided by the receive size as determined at the time the data socket is created. Can be used to make netperf more processor data cache unfriendly. Units: number of buffers. @item LOCAL_SEND_DIRTY_COUNT The number of bytes to ``dirty'' (write to) before netperf makes a ``send'' call. Specified via the global @option{-k} option, which requires that --enable-dirty=yes was specified with the configure command prior to building netperf. Units: Bytes. @item LOCAL_RECV_DIRTY_COUNT The number of bytes to ``dirty'' (write to) before netperf makes a ``recv'' call. Specified via the global @option{-k} option which requires that --enable-dirty was specified with the configure command prior to building netperf. Units: Bytes. @item LOCAL_RECV_CLEAN_COUNT The number of bytes netperf should read ``cleanly'' before making a ``receive'' call. Specified via the global @option{-k} option which requires that --enable-dirty was specified with configure command prior to building netperf. Clean reads start were dirty writes ended. Units: Bytes. @item LOCAL_NODELAY Indicates whether or not setting the test protocol-specific ``no delay'' (eg TCP_NODELAY) option on the data socket used by netperf was requested by the test-specific @option{-D} option and successful. Units: 0 means no, 1 means yes. @item LOCAL_CORK Indicates whether or not TCP_CORK was set on the data socket used by netperf as requested via the test-specific @option{-C} option. 1 means yes, 0 means no/not applicable. @item REMOTE_SEND_CALLS @item REMOTE_RECV_CALLS @item REMOTE_BYTES_PER_RECV @item REMOTE_BYTES_PER_SEND @item REMOTE_BYTES_SENT @item REMOTE_BYTES_RECVD @item REMOTE_BYTES_XFERD @item REMOTE_SEND_OFFSET @item REMOTE_RECV_OFFSET @item REMOTE_SEND_ALIGN @item REMOTE_RECV_ALIGN @item REMOTE_SEND_WIDTH @item REMOTE_RECV_WIDTH @item REMOTE_SEND_DIRTY_COUNT @item REMOTE_RECV_DIRTY_COUNT @item REMOTE_RECV_CLEAN_COUNT @item REMOTE_NODELAY @item REMOTE_CORK These are all like their ``LOCAL_'' counterparts only for the netserver rather than netperf. @item LOCAL_SYSNAME The name of the OS (eg ``Linux'') running on the system on which netperf was running. Units: ASCII Text @item LOCAL_SYSTEM_MODEL The model name of the system on which netperf was running. Units: ASCII Text. @item LOCAL_RELEASE The release name/number of the OS running on the system on which netperf was running. Units: ASCII Text @item LOCAL_VERSION The version number of the OS running on the system on which netperf was running. Units: ASCII Text @item LOCAL_MACHINE The machine architecture of the machine on which netperf was running. Units: ASCII Text. @item REMOTE_SYSNAME @item REMOTE_SYSTEM_MODEL @item REMOTE_RELEASE @item REMOTE_VERSION @item REMOTE_MACHINE These are all like their ``LOCAL_'' counterparts only for the netserver rather than netperf. @item LOCAL_INTERFACE_NAME The name of the probable egress interface through which the data connection went on the system running netperf. Example: eth0. Units: ASCII Text. @item LOCAL_INTERFACE_VENDOR The vendor ID of the probable egress interface through which traffic on the data connection went on the system running netperf. Units: Hexadecimal IDs as might be found in a @file{pci.ids} file or at @uref{http://pciids.sourceforge.net/,the PCI ID Repository}. @item LOCAL_INTERFACE_DEVICE The device ID of the probable egress interface through which traffic on the data connection went on the system running netperf. Units: Hexadecimal IDs as might be found in a @file{pci.ids} file or at @uref{http://pciids.sourceforge.net/,the PCI ID Repository}. @item LOCAL_INTERFACE_SUBVENDOR The sub-vendor ID of the probable egress interface through which traffic on the data connection went on the system running netperf. Units: Hexadecimal IDs as might be found in a @file{pci.ids} file or at @uref{http://pciids.sourceforge.net/,the PCI ID Repository}. @item LOCAL_INTERFACE_SUBDEVICE The sub-device ID of the probable egress interface through which traffic on the data connection went on the system running netperf. Units: Hexadecimal IDs as might be found in a @file{pci.ids} file or at @uref{http://pciids.sourceforge.net/,the PCI ID Repository}. @item LOCAL_DRIVER_NAME The name of the driver used for the probable egress interface through which traffic on the data connection went on the system running netperf. Units: ASCII Text. @item LOCAL_DRIVER_VERSION The version string for the driver used for the probable egress interface through which traffic on the data connection went on the system running netperf. Units: ASCII Text. @item LOCAL_DRIVER_FIRMWARE The firmware version for the driver used for the probable egress interface through which traffic on the data connection went on the system running netperf. Units: ASCII Text. @item LOCAL_DRIVER_BUS The bus address of the probable egress interface through which traffic on the data connection went on the system running netperf. Units: ASCII Text. @item LOCAL_INTERFACE_SLOT The slot ID of the probable egress interface through which traffic on the data connection went on the system running netperf. Units: ASCII Text. @item REMOTE_INTERFACE_NAME @item REMOTE_INTERFACE_VENDOR @item REMOTE_INTERFACE_DEVICE @item REMOTE_INTERFACE_SUBVENDOR @item REMOTE_INTERFACE_SUBDEVICE @item REMOTE_DRIVER_NAME @item REMOTE_DRIVER_VERSION @item REMOTE_DRIVER_FIRMWARE @item REMOTE_DRIVER_BUS @item REMOTE_INTERFACE_SLOT These are all like their ``LOCAL_'' counterparts only for the netserver rather than netperf. @item LOCAL_INTERVAL_USECS The interval at which bursts of operations (sends, receives, transactions) were attempted by netperf. Specified by the global @option{-w} option which requires --enable-intervals to have been specified with the configure command prior to building netperf. Units: Microseconds (though specified by default in milliseconds on the command line) @item LOCAL_INTERVAL_BURST The number of operations (sends, receives, transactions depending on the test) which were attempted by netperf each LOCAL_INTERVAL_USECS units of time. Specified by the global @option{-b} option which requires --enable-intervals to have been specified with the configure command prior to building netperf. Units: number of operations per burst. @item REMOTE_INTERVAL_USECS The interval at which bursts of operations (sends, receives, transactions) were attempted by netserver. Specified by the global @option{-w} option which requires --enable-intervals to have been specified with the configure command prior to building netperf. Units: Microseconds (though specified by default in milliseconds on the command line) @item REMOTE_INTERVAL_BURST The number of operations (sends, receives, transactions depending on the test) which were attempted by netperf each LOCAL_INTERVAL_USECS units of time. Specified by the global @option{-b} option which requires --enable-intervals to have been specified with the configure command prior to building netperf. Units: number of operations per burst. @item LOCAL_SECURITY_TYPE_ID @item LOCAL_SECURITY_TYPE @item LOCAL_SECURITY_ENABLED_NUM @item LOCAL_SECURITY_ENABLED @item LOCAL_SECURITY_SPECIFIC @item REMOTE_SECURITY_TYPE_ID @item REMOTE_SECURITY_TYPE @item REMOTE_SECURITY_ENABLED_NUM @item REMOTE_SECURITY_ENABLED @item REMOTE_SECURITY_SPECIFIC A bunch of stuff related to what sort of security mechanisms (eg SELINUX) were enabled on the systems during the test. @item RESULT_BRAND The string specified by the user with the global @option{-B} option. Units: ASCII Text. @item UUID The universally unique identifier associated with this test, either generated automagically by netperf, or passed to netperf via an omni test-specific @option{-u} option. Note: Future versions may make this a global command-line option. Units: ASCII Text. @item MIN_LATENCY The minimum ``latency'' or operation time (send, receive or request/response exchange depending on the test) as measured on the netperf side when the global @option{-j} option was specified. Units: Microseconds. @item MAX_LATENCY The maximum ``latency'' or operation time (send, receive or request/response exchange depending on the test) as measured on the netperf side when the global @option{-j} option was specified. Units: Microseconds. @item P50_LATENCY The 50th percentile value of ``latency'' or operation time (send, receive or request/response exchange depending on the test) as measured on the netperf side when the global @option{-j} option was specified. Units: Microseconds. @item P90_LATENCY The 90th percentile value of ``latency'' or operation time (send, receive or request/response exchange depending on the test) as measured on the netperf side when the global @option{-j} option was specified. Units: Microseconds. @item P99_LATENCY The 99th percentile value of ``latency'' or operation time (send, receive or request/response exchange depending on the test) as measured on the netperf side when the global @option{-j} option was specified. Units: Microseconds. @item MEAN_LATENCY The average ``latency'' or operation time (send, receive or request/response exchange depending on the test) as measured on the netperf side when the global @option{-j} option was specified. Units: Microseconds. @item STDDEV_LATENCY The standard deviation of ``latency'' or operation time (send, receive or request/response exchange depending on the test) as measured on the netperf side when the global @option{-j} option was specified. Units: Microseconds. @item COMMAND_LINE The full command line used when invoking netperf. Units: ASCII Text. @item OUTPUT_END While emitted with the list of output selectors, it is ignored when specified as an output selector. @end table @node Other Netperf Tests, Address Resolution, The Omni Tests, 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:: * UUID Generation:: @end menu @node CPU rate calibration, UUID Generation, 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 systems, 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 UUID Generation, , CPU rate calibration, Other Netperf Tests @section UUID Generation Beginning with version 2.5.0 netperf can generate Universally Unique IDentifiers (UUIDs). This can be done explicitly via the ``UUID'' test: @example $ netperf -t UUID 2c8561ae-9ebd-11e0-a297-0f5bfa0349d0 @end example In and of itself, this is not terribly useful, but used in conjunction with the test-specific @option{-u} option of an ``omni'' test to set the UUID emitted by the @ref{Omni Output Selectors,UUID} output selector, it can be used to tie-together the separate instances of an aggregate netperf test. Say, for instance if they were inserted into a database of some sort. @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 appropriate @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 However, with the addition of the ``omni'' tests in version 2.5.0 it is preferred that one attempt to make the necessary changes to @file{src/nettest_omni.c} rather than adding new source files, unless this would make the omni tests entirely too complicated. 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 consensus 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 descendant 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 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 netperf-2.6.0/doc/Makefile.in0000644000175000017500000007274411770160504012734 00000000000000# Makefile.in generated by automake 1.11.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008, 2009 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 VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd 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 = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ subdir = doc DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in texinfo.tex ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/src/missing/m4/salen.m4 \ $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = SOURCES = DIST_SOURCES = INFO_DEPS = $(srcdir)/netperf.info am__TEXINFO_TEX_DIR = $(srcdir) DVIS = netperf.dvi PDFS = netperf.pdf PSS = netperf.ps HTMLS = netperf.html TEXINFOS = netperf.texi TEXI2DVI = texi2dvi TEXI2PDF = $(TEXI2DVI) --pdf --batch MAKEINFOHTML = $(MAKEINFO) --html AM_MAKEINFOHTMLFLAGS = $(AM_MAKEINFOFLAGS) DVIPS = dvips RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ html-recursive info-recursive install-data-recursive \ install-dvi-recursive install-exec-recursive \ install-html-recursive install-info-recursive \ install-pdf-recursive install-ps-recursive install-recursive \ installcheck-recursive installdirs-recursive pdf-recursive \ ps-recursive uninstall-recursive am__installdirs = "$(DESTDIR)$(infodir)" "$(DESTDIR)$(man1dir)" am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' man1dir = $(mandir)/man1 NROFF = nroff MANS = $(man1_MANS) RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \ $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \ distdir ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ 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 = @INSTALL@ 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@ MKDIR_P = @MKDIR_P@ 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_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ RANLIB = @RANLIB@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ 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@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ 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 all: all-recursive .SUFFIXES: .SUFFIXES: .dvi .html .info .pdf .ps .texi $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu doc/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu doc/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): .texi.info: restore=: && backupdir="$(am__leading_dot)am$$$$" && \ am__cwd=`pwd` && $(am__cd) $(srcdir) && \ rm -rf $$backupdir && mkdir $$backupdir && \ if ($(MAKEINFO) --version) >/dev/null 2>&1; then \ for f in $@ $@-[0-9] $@-[0-9][0-9] $(@:.info=).i[0-9] $(@:.info=).i[0-9][0-9]; do \ if test -f $$f; then mv $$f $$backupdir; restore=mv; else :; fi; \ done; \ else :; fi && \ cd "$$am__cwd"; \ if $(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir) \ -o $@ $<; \ then \ rc=0; \ $(am__cd) $(srcdir); \ else \ rc=$$?; \ $(am__cd) $(srcdir) && \ $$restore $$backupdir/* `echo "./$@" | sed 's|[^/]*$$||'`; \ fi; \ rm -rf $$backupdir; exit $$rc .texi.dvi: TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \ MAKEINFO='$(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir)' \ $(TEXI2DVI) $< .texi.pdf: TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \ MAKEINFO='$(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir)' \ $(TEXI2PDF) $< .texi.html: rm -rf $(@:.html=.htp) if $(MAKEINFOHTML) $(AM_MAKEINFOHTMLFLAGS) $(MAKEINFOFLAGS) -I $(srcdir) \ -o $(@:.html=.htp) $<; \ then \ rm -rf $@; \ if test ! -d $(@:.html=.htp) && test -d $(@:.html=); then \ mv $(@:.html=) $@; else mv $(@:.html=.htp) $@; fi; \ else \ if test ! -d $(@:.html=.htp) && test -d $(@:.html=); then \ rm -rf $(@:.html=); else rm -Rf $(@:.html=.htp) $@; fi; \ exit 1; \ fi $(srcdir)/netperf.info: netperf.texi netperf.dvi: netperf.texi netperf.pdf: netperf.texi .dvi.ps: TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \ $(DVIPS) -o $@ $< uninstall-dvi-am: @$(NORMAL_UNINSTALL) @list='$(DVIS)'; test -n "$(dvidir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " rm -f '$(DESTDIR)$(dvidir)/$$f'"; \ rm -f "$(DESTDIR)$(dvidir)/$$f"; \ done uninstall-html-am: @$(NORMAL_UNINSTALL) @list='$(HTMLS)'; test -n "$(htmldir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " rm -rf '$(DESTDIR)$(htmldir)/$$f'"; \ rm -rf "$(DESTDIR)$(htmldir)/$$f"; \ done uninstall-info-am: @$(PRE_UNINSTALL) @if test -d '$(DESTDIR)$(infodir)' && \ (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'"; \ if install-info --info-dir="$(DESTDIR)$(infodir)" --remove "$(DESTDIR)$(infodir)/$$relfile"; \ then :; else test ! -f "$(DESTDIR)$(infodir)/$$relfile" || exit 1; fi; \ 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 test -d "$(DESTDIR)$(infodir)" && cd "$(DESTDIR)$(infodir)"; then \ echo " cd '$(DESTDIR)$(infodir)' && 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 uninstall-pdf-am: @$(NORMAL_UNINSTALL) @list='$(PDFS)'; test -n "$(pdfdir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " rm -f '$(DESTDIR)$(pdfdir)/$$f'"; \ rm -f "$(DESTDIR)$(pdfdir)/$$f"; \ done uninstall-ps-am: @$(NORMAL_UNINSTALL) @list='$(PSS)'; test -n "$(psdir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " rm -f '$(DESTDIR)$(psdir)/$$f'"; \ rm -f "$(DESTDIR)$(psdir)/$$f"; \ done dist-info: $(INFO_DEPS) @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ list='$(INFO_DEPS)'; \ for base in $$list; do \ case $$base in \ $(srcdir)/*) base=`echo "$$base" | sed "s|^$$srcdirstrip/||"`;; \ esac; \ if test -f $$base; then d=.; else d=$(srcdir); fi; \ base_i=`echo "$$base" | sed 's|\.info$$||;s|$$|.i|'`; \ for file in $$d/$$base $$d/$$base-[0-9] $$d/$$base-[0-9][0-9] $$d/$$base_i[0-9] $$d/$$base_i[0-9][0-9]; do \ if test -f $$file; then \ relfile=`expr "$$file" : "$$d/\(.*\)"`; \ test -f "$(distdir)/$$relfile" || \ cp -p $$file "$(distdir)/$$relfile"; \ else :; fi; \ done; \ done mostlyclean-aminfo: -rm -rf 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 clean-aminfo: -test -z "netperf.dvi netperf.pdf netperf.ps netperf.html" \ || rm -rf netperf.dvi netperf.pdf netperf.ps netperf.html 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 install-man1: $(man1_MANS) @$(NORMAL_INSTALL) test -z "$(man1dir)" || $(MKDIR_P) "$(DESTDIR)$(man1dir)" @list='$(man1_MANS)'; test -n "$(man1dir)" || exit 0; \ { for i in $$list; do echo "$$i"; done; \ } | while read p; do \ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; echo "$$p"; \ done | \ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ sed 'N;N;s,\n, ,g' | { \ list=; while read file base inst; do \ if test "$$base" = "$$inst"; then list="$$list $$file"; else \ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst" || exit $$?; \ fi; \ done; \ for i in $$list; do echo "$$i"; done | $(am__base_list) | \ while read files; do \ test -z "$$files" || { \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man1dir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(man1dir)" || exit $$?; }; \ done; } uninstall-man1: @$(NORMAL_UNINSTALL) @list='$(man1_MANS)'; test -n "$(man1dir)" || exit 0; \ files=`{ for i in $$list; do echo "$$i"; done; \ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ test -z "$$files" || { \ echo " ( cd '$(DESTDIR)$(man1dir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(man1dir)" && rm -f $$files; } # 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): @fail= failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ 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; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" $(RECURSIVE_CLEAN_TARGETS): @fail= failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ 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; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done && test -z "$$fail" tags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ done ctags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ done 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; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$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; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) 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; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @list='$(MANS)'; if test -n "$$list"; then \ list=`for p in $$list; do \ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ if test -f "$$d$$p"; then echo "$$d$$p"; else :; fi; done`; \ if test -n "$$list" && \ grep 'ab help2man is required to generate this page' $$list >/dev/null; then \ echo "error: found man pages containing the \`missing help2man' replacement text:" >&2; \ grep -l 'ab help2man is required to generate this page' $$list | sed 's/^/ /' >&2; \ echo " to fix them, install help2man, remove and regenerate the man pages;" >&2; \ echo " typically \`make maintainer-clean' will remove them" >&2; \ exit 1; \ else :; fi; \ else :; fi @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ 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: for dir in "$(DESTDIR)$(infodir)" "$(DESTDIR)$(man1dir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done 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: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_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-aminfo clean-generic mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: $(DVIS) html: html-recursive html-am: $(HTMLS) info: info-recursive info-am: $(INFO_DEPS) install-data-am: install-info-am install-man install-dvi: install-dvi-recursive install-dvi-am: $(DVIS) @$(NORMAL_INSTALL) test -z "$(dvidir)" || $(MKDIR_P) "$(DESTDIR)$(dvidir)" @list='$(DVIS)'; test -n "$(dvidir)" || list=; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(dvidir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(dvidir)" || exit $$?; \ done install-exec-am: install-html: install-html-recursive install-html-am: $(HTMLS) @$(NORMAL_INSTALL) test -z "$(htmldir)" || $(MKDIR_P) "$(DESTDIR)$(htmldir)" @list='$(HTMLS)'; list2=; test -n "$(htmldir)" || list=; \ for p in $$list; do \ if test -f "$$p" || test -d "$$p"; then d=; else d="$(srcdir)/"; fi; \ $(am__strip_dir) \ if test -d "$$d$$p"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(htmldir)/$$f'"; \ $(MKDIR_P) "$(DESTDIR)$(htmldir)/$$f" || exit 1; \ echo " $(INSTALL_DATA) '$$d$$p'/* '$(DESTDIR)$(htmldir)/$$f'"; \ $(INSTALL_DATA) "$$d$$p"/* "$(DESTDIR)$(htmldir)/$$f" || exit $$?; \ else \ list2="$$list2 $$d$$p"; \ fi; \ done; \ test -z "$$list2" || { echo "$$list2" | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(htmldir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(htmldir)" || exit $$?; \ done; } install-info: install-info-recursive install-info-am: $(INFO_DEPS) @$(NORMAL_INSTALL) test -z "$(infodir)" || $(MKDIR_P) "$(DESTDIR)$(infodir)" @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ list='$(INFO_DEPS)'; test -n "$(infodir)" || list=; \ for file in $$list; do \ case $$file in \ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ esac; \ 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 \ echo "$$ifile"; \ else : ; fi; \ done; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(infodir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(infodir)" || exit $$?; 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)'; test -n "$(infodir)" || list=; \ 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 install-pdf: install-pdf-recursive install-pdf-am: $(PDFS) @$(NORMAL_INSTALL) test -z "$(pdfdir)" || $(MKDIR_P) "$(DESTDIR)$(pdfdir)" @list='$(PDFS)'; test -n "$(pdfdir)" || list=; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pdfdir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(pdfdir)" || exit $$?; done install-ps: install-ps-recursive install-ps-am: $(PSS) @$(NORMAL_INSTALL) test -z "$(psdir)" || $(MKDIR_P) "$(DESTDIR)$(psdir)" @list='$(PSS)'; test -n "$(psdir)" || list=; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(psdir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(psdir)" || exit $$?; done 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-dvi-am uninstall-html-am uninstall-info-am \ uninstall-man uninstall-pdf-am uninstall-ps-am uninstall-man: uninstall-man1 .MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) ctags-recursive \ install-am install-strip tags-recursive .PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ all all-am check check-am clean clean-aminfo clean-generic \ ctags ctags-recursive dist-info distclean distclean-generic \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-man1 install-pdf install-pdf-am install-ps \ install-ps-am install-strip installcheck installcheck-am \ installdirs installdirs-am maintainer-clean \ maintainer-clean-aminfo maintainer-clean-generic mostlyclean \ mostlyclean-aminfo mostlyclean-generic pdf pdf-am ps ps-am \ tags tags-recursive uninstall uninstall-am uninstall-dvi-am \ uninstall-html-am uninstall-info-am uninstall-man \ uninstall-man1 uninstall-pdf-am uninstall-ps-am 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: netperf-2.6.0/doc/Makefile.am0000644000175000017500000000167111576721154012722 00000000000000# 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)/'`$< netperf-2.6.0/doc/examples/0000755000175000017500000000000011770164744012561 500000000000000netperf-2.6.0/doc/examples/Makefile.in0000644000175000017500000002277411770160504014550 00000000000000# Makefile.in generated by automake 1.11.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008, 2009 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@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd 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 = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ subdir = doc/examples DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/src/missing/m4/salen.m4 \ $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = SOURCES = DIST_SOURCES = DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ 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 = @INSTALL@ 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@ MKDIR_P = @MKDIR_P@ 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_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ RANLIB = @RANLIB@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ 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@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ 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 all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu doc/examples/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu doc/examples/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): tags: TAGS TAGS: ctags: CTAGS CTAGS: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$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: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_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: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: 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: .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic distclean \ distclean-generic distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-generic pdf pdf-am ps ps-am uninstall uninstall-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: netperf-2.6.0/doc/examples/Makefile.am0000644000175000017500000000072311525015224014521 00000000000000EXTRA_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 netperf-2.6.0/doc/examples/tcp_rr_script0000755000175000017500000000567511525015224015303 00000000000000#!/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 netperf-2.6.0/doc/examples/packet_byte_script0000755000175000017500000001410511525015224016270 00000000000000#!/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 netperf-2.6.0/doc/examples/tcp_stream_script0000755000175000017500000000535711525015224016150 00000000000000#!/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 netperf-2.6.0/doc/examples/tcp_range_script0000755000175000017500000000504611525015224015744 00000000000000#!/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 netperf-2.6.0/doc/examples/udp_rr_script0000755000175000017500000000523011525015224015270 00000000000000#!/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 netperf-2.6.0/doc/examples/arr_script0000755000175000017500000002214611525015224014566 00000000000000# 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 netperf-2.6.0/doc/examples/sctp_stream_script0000644000175000017500000000535611525015224016327 00000000000000#!/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 netperf-2.6.0/doc/examples/snapshot_script0000755000175000017500000001654411525015224015646 00000000000000#!/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 netperf-2.6.0/doc/examples/udp_stream_script0000644000175000017500000000527111525015224016142 00000000000000#!/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 netperf-2.6.0/doc/netperf.man0000644000175000017500000001604411602736471013024 00000000000000.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 \-j Instruct netperf to calculate additional statistics on timing when running an omni test. Display of said statistics will depend on the presence of the corresponding output selectors in the output selection. These are MIN_LATENCY, MAX_LATENCY, P50_LATENCY, P90_LATENCY, P99_LATENCY, MEAN_LATENCY and STDDEV_LATENCY. .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 \-S This option will cause an attempt to set SO_KEEPALIVE on the ends of the data connection for tests using BSD Sockets. It will be made on the netperf side of classic tests, and both netperf and netserver side of an omni or migrated test. .TP .B \-s seconds This will cause netperf to sleep "seconds" seconds before transferring data over the data connection. .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 SCTP_STREAM .I SCTP_STREAM_MANY .I SCTP_RR .I SCTP_RR_MANY .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). .TP .B \-V Display the netperf version and exit. .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 Care and Feeding of Netperf 2.5.X (doc/netperf.[pdf|html|txt]) for more information. Or you can join and send email 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 parm 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 netperf-feedback@netperf.org. .SH SEE ALSO .BR netserver (1) .br .I Care and Feeding of Netperf 2.5.X .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 AUTHORS file netperf-2.6.0/doc/texinfo.tex0000644000175000017500000066100111576721154013063 00000000000000% 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: netperf-2.6.0/doc/netperf.info0000644000175000017500000056765511770164574013234 00000000000000This is netperf.info, produced by makeinfo version 4.13 from netperf.texi. This is Rick Jones' feeble attempt at a Texinfo-based manual for the netperf benchmark. Copyright (C) 2005-2012 Hewlett-Packard Company Permission is granted to copy, distribute and/or modify this document per the terms of the netperf source license, 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-2012 Hewlett-Packard Company Permission is granted to copy, distribute and/or modify this document per the terms of the netperf source license, 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 what it 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:: * The Omni Tests:: * Other Netperf Tests:: * Address Resolution:: * Enhancing Netperf:: * Netperf4:: * Concept Index:: * Option Index::  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 * 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. It is the Contributing Editor's belief that the netperf license walks like open source and talks like open source. However, the license was never submitted for "certification" as an open source license. If you would prefer to make contributions to a networking benchmark using a certified open source license, please consider netperf4, which is distributed under the terms of the GPLv2. 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 (to deal with spam) 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.6.0 (http://www.netperf.org/svn/netperf2/tags/netperf-2.6.0). 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). When fixing bugs or making enhancements, patches against the top-of-trunk are preferred. 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.  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 netperf-.tar.gz | tar xf - cd netperf- ./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. You may find the `--prefix' option helpful in deciding where the binaries and such will be put during the `make install'. 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|unixdomain|dlpi|sctp]=yes' options to the configure command. As of this writing, the configure script will not include those tests automagically. Starting with version 2.5.0, netperf began migrating most of the "classic" netperf tests found in `src/nettest_bsd.c' to the so-called "omni" tests (aka "two routines to run them all") found in `src/nettest_omni.c'. This migration enables a number of new features such as greater control over what output is included, and new things to output. The "omni" test is enabled by default in 2.5.0 and a number of the classic tests are migrated - you can tell if a test has been migrated from the presence of `MIGRATED' in the test banner. If you encounter problems with either the omni or migrated tests, please first attempt to obtain resolution via or . If that is unsuccessful, you can add a `--enable-omni=no' to the configure command and the omni tests will not be compiled-in and the classic tests will not be migrated. Starting with version 2.5.0, netperf includes the "burst mode" functionality in a default compilation of the bits. If you encounter problems with this, please first attempt to obtain help via or . If that is unsuccessful, you can add a `--enable-burst=no' to the configure command and the burst mode functionality will not be compiled-in. 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 automagic 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 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 `-D' output: $ src/netperf -D 1.35 -H tardy.hpl.hp.com -f M MIGRATED TCP STREAM TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to tardy.hpl.hp.com (15.9.116.144) port 0 AF_INET : demo Interim result: 5.41 MBytes/s over 1.35 seconds ending at 1308789765.848 Interim result: 11.07 MBytes/s over 1.36 seconds ending at 1308789767.206 Interim result: 16.00 MBytes/s over 1.36 seconds ending at 1308789768.566 Interim result: 20.66 MBytes/s over 1.36 seconds ending at 1308789769.922 Interim result: 22.74 MBytes/s over 1.36 seconds ending at 1308789771.285 Interim result: 23.07 MBytes/s over 1.36 seconds ending at 1308789772.647 Interim result: 23.77 MBytes/s over 1.37 seconds ending at 1308789774.016 Recv Send Send Socket Socket Message Elapsed Size Size Size Time Throughput bytes bytes bytes secs. MBytes/sec 87380 16384 16384 10.06 17.81 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 not by relying on interval timers or frequent calls to get the current time, but by calculating how many units of work must be performed to take at least the desired interval. Those familiar with this option in earlier versions of netperf will note the addition of the "ending at" text. This is the time as reported by a `gettimeofday()' call (or its emulation) with a `NULL' timezone pointer. This addition is intended to make it easier to insert interim results into an rrdtool (http://oss.oetiker.ch/rrdtool/doc/rrdtool.en.html) Round-Robin Database (RRD). A likely bug-riddled example of doing so can be found in `doc/examples/netperf_interim_to_rrd.sh'. The time is reported out to milliseconds rather than microseconds because that is the most rrdtool understands as of the time of this writing. 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 having been previously started as its own standalone daemon. When you execute netperf it will establish 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 and portably. Netperf will do its level best to report accurate CPU utilization figures, but some combinations of processor, OS and configuration may make that difficult. 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 and thus "better." 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.31 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 whereby 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 consumption, it has been suggested that this mechanism may become slightly confused, in which case using BIOS/uEFI 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 11iv2 and later are known/presumed 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. * Menu: * CPU Utilization in a Virtual Guest::  File: netperf.info, Node: CPU Utilization in a Virtual Guest, Prev: CPU Utilization, Up: CPU Utilization 3.1.1 CPU Utilization in a Virtual Guest ---------------------------------------- The CPU utilization mechanisms used by netperf are "inline" in that they are run by the same netperf or netserver process as is running the test itself. This works just fine for "bare iron" tests but runs into a problem when using virtual machines. The relationship between virtual guest and hypervisor can be thought of as being similar to that between a process and kernel in a bare iron system. As such, (m)any CPU utilization mechanisms used in the virtual guest are similar to "process-local" mechanisms in a bare iron situation. However, just as with bare iron and process-local mechanisms, much networking processing happens outside the context of the virtual guest. It takes place in the hypervisor, and is not visible to mechanisms running in the guest(s). For this reason, one should not really trust CPU utilization figures reported by netperf or netserver when running in a virtual guest. If one is looking to measure the added overhead of a virtualization mechanism, rather than rely on CPU utilization, one can rely instead on netperf _RR tests - path-lengths and overheads can be a significant fraction of the latency, so increases in overhead should appear as decreases in transaction rate. Whatever you do, DO NOT rely on the throughput of a _STREAM test. Achieving link-rate can be done via a multitude of options that mask overhead rather than eliminate it.  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 if you wish :). 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|x' 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. An argument of "x" requests the units be transactions per second and is only meaningful for a request-response test. [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 transferred 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 previously required for a TCP_SENDFILE test, later versions of netperf removed that restriction, creating a temporary file as needed. While the author cannot recall exactly when that took place, it is known to be unnecessary in version 2.5.0 and later. `-h' This option causes netperf to display its "global" 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 "linger" 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 half 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 classic netperf test 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 In the example above we see that netperf did not meet the desired confidence 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. In an explicit "omni" test, failure to meet the confidence intervals will not result in netperf emitting a warning. To verify the hitting, or not, of the confidence intervals one will need to include them as part of an *note output selection: Omni Output Selection. in the test-specific `-o', `-O' or `k' output selection options. The warning about not hitting the confidence intervals will remain in a "migrated" classic netperf test. `-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. A classic or migrated netperf test will not display the actual number of iterations run. An *note omni test: The Omni Tests. will emit the number of iterations run if the `CONFIDENCE_ITERATION' output selector is included in the *note output selection: Omni Output Selection. 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. Output of a warning upon not hitting the desired confidence intervals follows the description provided for the `-I' option. 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. `-j' This option instructs netperf to keep additional timing statistics when explicitly running an *note omni test: The Omni Tests. These can be output when the test-specific `-o', `-O' or `-k' *note output selectors: Omni Output Selectors. include one or more of: * MIN_LATENCY * MAX_LATENCY * P50_LATENCY * P90_LATENCY * P99_LATENCY * MEAN_LATENCY * STDDEV_LATENCY These statistics will be based on an expanded (100 buckets per row rather than 10) histogram of times rather than a terribly long list of individual times. As such, there will be some slight error thanks to the bucketing. However, the reduction in storage and processing overheads is well worth it. When running a request/response test, one might get some idea of the error by comparing the *note `MEAN_LATENCY': Omni Output Selectors. calculated from the histogram with the `RT_LATENCY' calculated from the number of request/response transactions and the test run time. In the case of a request/response test the latencies will be transaction latencies. In the case of a receive-only test they will be time spent in the receive call. In the case of a send-only test they will be time spent in the send call. The units will be microseconds. Added in netperf 2.5.0. `-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. This limitation may be relaxed in an *note omni: The Omni Tests. test. 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. As it is almost universally possible for netperf/netserver to determine the number of CPUs on the system automagically, 99 times out of 10 this option should not be necessary and may be removed in a future release of netperf. `-N' This option tells netperf to forgo 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 displayed as values which 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 (netperf) 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 (netserver) 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] `-s ' This option will cause netperf to sleep `' before actually transferring data over the data connection. This may be useful in situations where one wishes to start a great many netperf instances and do not want the earlier ones affecting the ability of the later ones to get established. Added somewhere between versions 2.4.3 and 2.5.0. `-S' This option will cause an attempt to be made to set SO_KEEPALIVE on the data socket of a test using the BSD sockets interface. The attempt will be made on the netperf side of all tests, and will be made on the netserver side of an *note omni: The Omni Tests. or *note migrated: Migrated Tests. test. No indication of failure is given unless debug output is enabled with the global `-d' option. Added in version 2.5.0. `-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. * *note OMNI: The Omni Tests. Not all tests are always compiled into netperf. In particular, the "XTI," "SCTP," "UNIXDOMAIN," and "DL*" tests are only included in netperf when configured with `--enable-[xti|sctp|unixdomain|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] `-T ' This option controls the CPU, and probably by extension memory, affinity of netperf and/or netserver. netperf -T 1 will bind both netperf and netserver to "CPU 1" on their respective systems. netperf -T 1, will bind just netperf to "CPU 1" and will leave netserver unbound. netperf -T ,2 will leave netperf unbound and will bind netserver to "CPU 2." netperf -T 1,2 will bind netperf to "CPU 1" and netserver to "CPU 2." This can be particularly useful when investigating performance issues involving where processes run relative to where NIC interrupts are processed or where NICs allocate their DMA buffers. `-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] In an *note omni: The Omni Tests. test the verbosity setting is largely ignored, save for when asking for the time histogram to be displayed. In version 2.5.0 and later there is no *note output selector: Omni Output Selectors. for the histogram and so it remains displayed only when the verbosity level is set to 2. `-V' This option displays the netperf version and then exits. Added in netperf 2.4.4. `-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 classic 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). In that case, one might see as much as two CPUs' worth of processing being used to service the flow of data. 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 platform(s) of interest. If running a version 2.5.0 or later "omni" test under Linux one can include either or both of: * LOCAL_TRANSPORT_RETRANS * REMOTE_TRANSPORT_RETRANS in the values provided via a test-specific `-o', `-O', or `-k' output selction option and netperf will report the retransmissions experienced on the data connection, as reported via a `getsockopt(TCP_INFO)' call. If confidence intervals have been requested via the global `-I' or `-i' options, the reported value(s) will be for the last iteration. If the test is over a protocol other than TCP, or on a platform other than Linux, the results are undefined. 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 (netperf) 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 (netserver) 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 remote 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, however Linux does "auto tuning" of socket buffer and TCP window sizes, which means the send socket buffer size may be different at the end of the test than it was at the beginning. This is addressed in the *note omni tests: The Omni Tests. added in version 2.5.0 and *note output selection: Omni Output Selection. Throughput 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. As of some time before version 2.5.0, the *note global `-F' option: Global Options. is no longer required for this test. If it is not specified, netperf will create a temporary file, which it will delete at the end of the test. If the `-F' option is specified it must reference 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 remain 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: $ 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 DLPI 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-unixdomain=yes'. The remote netserver must have also been configured with `--enable-unixdomain=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-unixdomain=yes'. The remote netserver must have also been configured with `--enable-unixdomain=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, and stateless offloads like TSO and LRO can cover a multitude of latency and even path-length sins, those sins 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 a time test such as those found by default in netperf, is particularly sensitive to the path-length of the networking stack. An _RR test can also uncover those platforms where the NICs 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 transferred per second, by default 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. As of version 2.5.0 (actually slightly before) netperf still does not do the latter, but will do the former if one sets the verbosity to 2 for a classic netperf test, or includes the appropriate *note output selector: Omni Output Selectors. in an *note omni test: The Omni Tests. It will also allow the user to switch the throughput units from transactions per second to bits or bytes per second with the global `-f' option. * 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 Request/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. Virtualization may considerably increase the effective path length of a networking stack. While this may not preclude achieving link-rate on a comparatively slow link (eg 1 Gigabit Ethernet) on a _STREAM test, it can show-up as measurably fewer transactions per second on an _RR test. However, this may still be masked by interrupt coalescing in the NIC/driver. 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 distinguished 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 driver 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 (netperf) 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 (netperf) 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 (netserver) 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 remote (netserver) 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 thought-of as a user-space to user-space `ping' with no think time - it is by default 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 *note TPC_CC: TCP_CC. or *note TCP_CRR: 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 for the time :)  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, such as Window Scaling or Timestamps. 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_CRR test is like a merger of a *note TCP_RR:: and *note 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. If `--enable-burst' was included in the `configure' command and a test-specific `-b' option used, the UDP_RR test will "survive" the loss of requests and responses until the sum is one more than the value passed via the `-b' option. It will though almost certainly run more slowly. 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 ---------------- An XTI_TCP_CC test is essentially the same as a *note TCP_CC: TCP_CC. test, only using the XTI rather than BSD Sockets interface. The test-specific options for an XTI_TCP_CC test are the same as those for a TCP_CC 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_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 ----------------- The XTI_TCP_CRR test is essentially the same as a *note TCP_CRR: TCP_CRR. test, only using the XTI rather than BSD Sockets interface. The test-specific options for an XTI_TCP_CRR 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_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 ************************************************ Ultimately, *note Netperf4: Netperf4. will be the preferred benchmark to use when one wants to measure aggregate performance because netperf has no support for explicit synchronization of concurrent tests. Until netperf4 is ready for prime time, one can make use of the heuristics and procedures mentioned here for the 85% solution. There are a few 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. The third is a variation on the first. * Menu: * Running Concurrent Netperf Tests:: * Using --enable-burst:: * Using --enable-demo::  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. This method does not need to be limited to one system speaking to one other system. It can be extended to one system talking to N other systems. It could be as simple as: for host in 'foo bar baz bing' do netperf -t TCP_STREAM -H $hosts -i 10 -P 0 & done A more complicated/sophisticated example can be found in `doc/examples/runemomniagg2.sh' where. 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. Presumably 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. As the number of CPUs in the system increases, and so too the odds of saturating a single CPU, the accuracy of similar CPU utilization implying little skew error is diminished. This is also the case for those increasingly rare single CPU systems if the utilization is reported as 100% or very close to it. NOTE: It is very important to remember 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 will eventually be the preferred tool for aggregate tests. Even if you see the Netperf Contributing Editor acting to the contrary!-) * Menu: * Issues in Running Concurrent Tests::  File: netperf.info, Node: Issues in Running Concurrent Tests, Prev: Running Concurrent Netperf Tests, Up: Running Concurrent Netperf Tests 7.1.1 Issues in Running Concurrent Tests ---------------------------------------- In addition to the aforementioned issue of skew error, there can be other issues to consider when running concurrent netperf tests. For example, when running concurrent tests over multiple interfaces, one is not always assured that the traffic one thinks went over a given interface actually did so. In particular, the Linux networking stack takes a particularly strong stance on its following the so called `weak end system model'. As such, it is willing to answer ARP requests for any of its local IP addresses on any of its interfaces. If multiple interfaces are connected to the same broadcast domain, then even if they are configured into separate IP subnets there is no a priori way of knowing which interface was actually used for which connection(s). This can be addressed by setting the `arp_ignore' sysctl before configuring interfaces. As it is quite important, we will repeat that it is very important to remember that each concurrent netperf instance is calculating system-wide CPU utilization. When calculating the service demand 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 Running concurrent tests can also become difficult when there is no one "central" node. Running tests between pairs of systems may be more difficult, calling for remote shell commands in the for loop rather than netperf commands. This introduces more skew error, which the confidence intervals may not be able to sufficiently mitigate. One possibility is to actually run three consecutive netperf tests on each node - the first being a warm-up, the last being a cool-down. The idea then is to ensure that the time it takes to get all the netperfs started is less than the length of the first netperf command in the sequence of three. Similarly, it assumes that all "middle" netperfs will complete before the first of the "last" netperfs complete.  File: netperf.info, Node: Using --enable-burst, Next: Using --enable-demo, Prev: Running Concurrent Netperf Tests, Up: Using Netperf to Measure Aggregate Performance 7.2 Using - -enable-burst ========================= Starting in version 2.5.0 `--enable-burst=yes' is the default, which means one no longer must: configure --enable-burst To have burst-mode functionality present in netperf. This enables a test-specific `-b num' option in *note TCP_RR: TCP_RR, *note UDP_RR: UDP_RR. and *note omni: The Omni Tests. tests. Normally, netperf will attempt to ramp-up the number of outstanding requests to `num' plus one transactions in flight at one time. The ramp-up is to avoid transactions being smashed together into a smaller number of segments when the transport's congestion window (if any) is smaller at the time than what netperf wants to have outstanding at one time. If, however, the user specifies a negative value for `num' this ramp-up is bypassed and the burst of sends is made without consideration of transport congestion window. This burst-mode is used as an alternative to or even in conjunction with multiple-concurrent _RR tests and as a way to implement a single-connection, bidirectional bulk-transfer test. When run with just a single instance of netperf, increasing the burst size can determine the maximum number of transactions per second which 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' increase 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 even in the absence of transport congestion window issues. 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 exercise 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 exercise 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 --enable-demo, Prev: Using --enable-burst, Up: Using Netperf to Measure Aggregate Performance 7.3 Using - -enable-demo ======================== One can configure --enable-demo and compile netperf to enable netperf to emit "interim results" at semi-regular intervals. This enables a global `-D' option which takes a reporting interval as an argument. With that specified, the output of netperf will then look something like $ src/netperf -D 1.25 MIGRATED TCP STREAM TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to localhost.localdomain () port 0 AF_INET : demo Interim result: 25425.52 10^6bits/s over 1.25 seconds ending at 1327962078.405 Interim result: 25486.82 10^6bits/s over 1.25 seconds ending at 1327962079.655 Interim result: 25474.96 10^6bits/s over 1.25 seconds ending at 1327962080.905 Interim result: 25523.49 10^6bits/s over 1.25 seconds ending at 1327962082.155 Interim result: 25053.57 10^6bits/s over 1.27 seconds ending at 1327962083.429 Interim result: 25349.64 10^6bits/s over 1.25 seconds ending at 1327962084.679 Interim result: 25292.84 10^6bits/s over 1.25 seconds ending at 1327962085.932 Recv Send Send Socket Socket Message Elapsed Size Size Size Time Throughput bytes bytes bytes secs. 10^6bits/sec 87380 16384 16384 10.00 25375.66 The units of the "Interim result" lines will follow the units selected via the global `-f' option. If the test-specific `-o' option is specified on the command line, the format will be CSV: ... 2978.81,MBytes/s,1.25,1327962298.035 ... If the test-specific `-k' option is used the format will be keyval with each keyval being given an index: ... NETPERF_INTERIM_RESULT[2]=25.00 NETPERF_UNITS[2]=10^9bits/s NETPERF_INTERVAL[2]=1.25 NETPERF_ENDING[2]=1327962357.249 ... The expectation is it may be easier to utilize the keyvals if they have indices. But how does this help with aggregate tests? Well, what one can do is start the netperfs via a script, giving each a Very Long (tm) run time. Direct the output to a file per instance. Then, once all the netperfs have been started, take a timestamp and wait for some desired test interval. Once that interval expires take another timestamp and then start terminating the netperfs by sending them a SIGALRM signal via the likes of the `kill' or `pkill' command. The netperfs will terminate and emit the rest of the "usual" output, and you can then bring the files to a central location for post processing to find the aggregate performance over the "test interval." This method has the advantage that it does not require advance knowledge of how long it takes to get netperf tests started and/or stopped. It does though require sufficiently synchronized clocks on all the test systems. While calls to get the current time can be inexpensive, that neither has been nor is universally true. For that reason netperf tries to minimize the number of such "timestamping" calls (eg `gettimeofday') calls it makes when in demo mode. Rather than take a timestamp after each `send' or `recv' call completes netperf tries to guess how many units of work will be performed over the desired interval. Only once that many units of work have been completed will netperf check the time. If the reporting interval has passed, netperf will emit an "interim result." If the interval has not passed, netperf will update its estimate for units and continue. After a bit of thought one can see that if things "speed-up" netperf will still honor the interval. However, if things "slow-down" netperf may be late with an "interim result." Here is an example of both of those happening during a test - with the interval being honored while throughput increases, and then about half-way through when another netperf (not shown) is started we see things slowing down and netperf not hitting the interval as desired. $ src/netperf -D 2 -H tardy.hpl.hp.com -l 20 MIGRATED TCP STREAM TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to tardy.hpl.hp.com () port 0 AF_INET : demo Interim result: 36.46 10^6bits/s over 2.01 seconds ending at 1327963880.565 Interim result: 59.19 10^6bits/s over 2.00 seconds ending at 1327963882.569 Interim result: 73.39 10^6bits/s over 2.01 seconds ending at 1327963884.576 Interim result: 84.01 10^6bits/s over 2.03 seconds ending at 1327963886.603 Interim result: 75.63 10^6bits/s over 2.21 seconds ending at 1327963888.814 Interim result: 55.52 10^6bits/s over 2.72 seconds ending at 1327963891.538 Interim result: 70.94 10^6bits/s over 2.11 seconds ending at 1327963893.650 Interim result: 80.66 10^6bits/s over 2.13 seconds ending at 1327963895.777 Interim result: 86.42 10^6bits/s over 2.12 seconds ending at 1327963897.901 Recv Send Send Socket Socket Message Elapsed Size Size Size Time Throughput bytes bytes bytes secs. 10^6bits/sec 87380 16384 16384 20.34 68.87 So long as your post-processing mechanism can account for that, there should be no problem. As time passes there may be changes to try to improve the netperf's honoring the interval but one should not ass-u-me it will always do so. One should not assume the precision will remain fixed - future versions may change it - perhaps going beyond tenths of seconds in reporting the interval length etc.  File: netperf.info, Node: Using Netperf to Measure Bidirectional Transfer, Next: The Omni 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 performance 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:: * Implications of Concurrent Tests vs Burst Request/Response::  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. Beginning with version 2.5.0 we can accomplish a similar result with the *note the omni tests: The Omni Tests. and *note output selectors: Omni Output Selectors.: for i in 1 do netperf -H 192.168.1.3 -t omni -l 10 -P 0 -- \ -d stream -s 256K -S 256K -o throughput,direction & netperf -H 192.168.1.3 -t omni -l 10 -P 0 -- \ -d maerts -s 256K -S 256K -o throughput,direction & done 805.26,Receive 828.54,Send  File: netperf.info, Node: Bidirectional Transfer with TCP_RR, Next: Implications of Concurrent Tests vs Burst Request/Response, Prev: Bidirectional Transfer with Concurrent Tests, Up: Using Netperf to Measure Bidirectional Transfer 8.2 Bidirectional Transfer with TCP_RR ====================================== Starting with version 2.5.0 the `--enable-burst' configure option defaults to `yes', and starting some time before version 2.5.0 but after 2.4.0 the global `-f' option would affect the "throughput" reported by request/response tests. If one uses the test-specific `-b' option to have several "transactions" in flight at one time and the test-specific `-r' option to increase their size, the test looks more and more like a single-connection bidirectional transfer than a simple request/response test. So, putting it all together one can do something like: netperf -f m -t TCP_RR -H 192.168.1.3 -v 2 -- -b 6 -r 32K -S 256K -S 256K MIGRATED TCP REQUEST/RESPONSE TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to 192.168.1.3 (192.168.1.3) port 0 AF_INET : interval : first burst 6 Local /Remote Socket Size Request Resp. Elapsed Send Recv Size Size Time Throughput bytes Bytes bytes bytes secs. 10^6bits/sec 16384 87380 32768 32768 10.00 1821.30 524288 524288 Alignment Offset RoundTrip Trans Throughput Local Remote Local Remote Latency Rate 10^6bits/s Send Recv Send Recv usec/Tran per sec Outbound Inbound 8 0 0 0 2015.402 3473.252 910.492 910.492 to get a bidirectional bulk-throughput result. As one can see, the -v 2 output will include a number of interesting, related values. NOTE: The logic behind `--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.  File: netperf.info, Node: Implications of Concurrent Tests vs Burst Request/Response, Prev: Bidirectional Transfer with TCP_RR, Up: Using Netperf to Measure Bidirectional Transfer 8.3 Implications of Concurrent Tests vs Burst Request/Response ============================================================== There are perhaps subtle but important differences between using concurrent unidirectional tests vs a burst-mode request to measure bidirectional performance. Broadly speaking, a single "connection" or "flow" of traffic cannot make use of the services of more than one or two CPUs at either end. Whether one or two CPUs will be used processing a flow will depend on the specifics of the stack(s) involved and whether or not the global `-T' option has been used to bind netperf/netserver to specific CPUs. When using concurrent tests there will be two concurrent connections or flows, which means that upwards of four CPUs will be employed processing the packets (global `-T' used, no more than two if not), however, with just a single, bidirectional request/response test no more than two CPUs will be employed (only one if the global `-T' is not used). If there is a CPU bottleneck on either system this may result in rather different results between the two methods. Also, with a bidirectional request/response test there is something of a natural balance or synchronization between inbound and outbound - a response will not be sent until a request is received, and (once the burst level is reached) a subsequent request will not be sent until a response is received. This may mask favoritism in the NIC between inbound and outbound processing. With two concurrent unidirectional tests there is no such synchronization or balance and any favoritism in the NIC may be exposed.  File: netperf.info, Node: The Omni Tests, Next: Other Netperf Tests, Prev: Using Netperf to Measure Bidirectional Transfer, Up: Top 9 The Omni Tests **************** Beginning with version 2.5.0, netperf begins a migration to the `omni' tests or "Two routines to measure them all." The code for the omni tests can be found in `src/nettest_omni.c' and the goal is to make it easier for netperf to support multiple protocols and report a great many additional things about the systems under test. Additionally, a flexible output selection mechanism is present which allows the user to chose specifically what values she wishes to have reported and in what format. The omni tests are included by default in version 2.5.0. To disable them, one must: ./configure --enable-omni=no ... and remake netperf. Remaking netserver is optional because even in 2.5.0 it has "unmigrated" netserver side routines for the classic (eg `src/nettest_bsd.c') tests. * Menu: * Native Omni Tests:: * Migrated Tests:: * Omni Output Selection::  File: netperf.info, Node: Native Omni Tests, Next: Migrated Tests, Prev: The Omni Tests, Up: The Omni Tests 9.1 Native Omni Tests ===================== One access the omni tests "natively" by using a value of "OMNI" with the global `-t' test-selection option. This will then cause netperf to use the code in `src/nettest_omni.c' and in particular the test-specific options parser for the omni tests. The test-specific options for the omni tests are a superset of those for "classic" tests. The options added by the omni tests are: `-c' This explicitly declares that the test is to include connection establishment and tear-down as in either a TCP_CRR or TCP_CC test. `-d ' This option sets the direction of the test relative to the netperf process. As of version 2.5.0 one can use the following in a case-insensitive manner: `send, stream, transmit, xmit or 2' Any of which will cause netperf to send to the netserver. `recv, receive, maerts or 4' Any of which will cause netserver to send to netperf. `rr or 6' Either of which will cause a request/response test. Additionally, one can specify two directions separated by a '|' character and they will be OR'ed together. In this way one can use the "Send|Recv" that will be emitted by the *note DIRECTION: Omni Output Selectors. *note output selector: Omni Output Selection. when used with a request/response test. `-k [*note output selector: Omni Output Selection.]' This option sets the style of output to "keyval" where each line of output has the form: key=value For example: $ netperf -t omni -- -d rr -k "THROUGHPUT,THROUGHPUT_UNITS" OMNI 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 : demo THROUGHPUT=59092.65 THROUGHPUT_UNITS=Trans/s Using the `-k' option will override any previous, test-specific `-o' or `-O' option. `-o [*note output selector: Omni Output Selection.]' This option sets the style of output to "CSV" where there will be one line of comma-separated values, preceded by one line of column names unless the global `-P' option is used with a value of 0: $ netperf -t omni -- -d rr -o "THROUGHPUT,THROUGHPUT_UNITS" OMNI 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 : demo Throughput,Throughput Units 60999.07,Trans/s Using the `-o' option will override any previous, test-specific `-k' or `-O' option. `-O [*note output selector: Omni Output Selection.]' This option sets the style of output to "human readable" which will look quite similar to classic netperf output: $ netperf -t omni -- -d rr -O "THROUGHPUT,THROUGHPUT_UNITS" OMNI 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 : demo Throughput Throughput Units 60492.57 Trans/s Using the `-O' option will override any previous, test-specific `-k' or `-o' option. `-t' This option explicitly sets the socket type for the test's data connection. As of version 2.5.0 the known socket types include "stream" and "dgram" for SOCK_STREAM and SOCK_DGRAM respectively. `-T ' This option is used to explicitly set the protocol used for the test. It is case-insensitive. As of version 2.5.0 the protocols known to netperf include: `TCP' Select the Transmission Control Protocol `UDP' Select the User Datagram Protocol `SDP' Select the Sockets Direct Protocol `DCCP' Select the Datagram Congestion Control Protocol `SCTP' Select the Stream Control Transport Protocol `udplite' Select UDP Lite The default is implicit based on other settings. The omni tests also extend the interpretation of some of the classic, test-specific options for the BSD Sockets tests: `-m ' This can set the send size for either or both of the netperf and netserver sides of the test: -m 32K sets only the netperf-side send size to 32768 bytes, and or's-in transmit for the direction. This is effectively the same behaviour as for the classic tests. -m ,32K sets only the netserver side send size to 32768 bytes and or's-in receive for the direction. -m 16K,32K sets the netperf side send size to 16284 bytes, the netserver side send size to 32768 bytes and the direction will be "Send|Recv." `-M ' This can set the receive size for either or both of the netperf and netserver sides of the test: -M 32K sets only the netserver side receive size to 32768 bytes and or's-in send for the test direction. -M ,32K sets only the netperf side receive size to 32768 bytes and or's-in receive for the test direction. -M 16K,32K sets the netserver side receive size to 16384 bytes and the netperf side receive size to 32768 bytes and the direction will be "Send|Recv."  File: netperf.info, Node: Migrated Tests, Next: Omni Output Selection, Prev: Native Omni Tests, Up: The Omni Tests 9.2 Migrated Tests ================== As of version 2.5.0 several tests have been migrated to use the omni code in `src/nettest_omni.c' for the core of their testing. A migrated test retains all its previous output code and so should still "look and feel" just like a pre-2.5.0 test with one exception - the first line of the test banners will include the word "MIGRATED" at the beginning as in: $ netperf MIGRATED 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 : demo Recv Send Send Socket Socket Message Elapsed Size Size Size Time Throughput bytes bytes bytes secs. 10^6bits/sec 87380 16384 16384 10.00 27175.27 The tests migrated in version 2.5.0 are: * TCP_STREAM * TCP_MAERTS * TCP_RR * TCP_CRR * UDP_STREAM * UDP_RR It is expected that future releases will have additional tests migrated to use the "omni" functionality. If one uses "omni-specific" test-specific options in conjunction with a migrated test, instead of using the classic output code, the new omni output code will be used. For example if one uses the `-k' test-specific option with a value of "MIN_LATENCY,MAX_LATENCY" with a migrated TCP_RR test one will see: $ netperf -t tcp_rr -- -k THROUGHPUT,THROUGHPUT_UNITS MIGRATED TCP REQUEST/RESPONSE 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 : demo THROUGHPUT=60074.74 THROUGHPUT_UNITS=Trans/s rather than: $ netperf -t tcp_rr MIGRATED TCP REQUEST/RESPONSE 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 : demo 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 59421.52 16384 87380  File: netperf.info, Node: Omni Output Selection, Prev: Migrated Tests, Up: The Omni Tests 9.3 Omni Output Selection ========================= The omni test-specific `-k', `-o' and `-O' options take an optional `output selector' by which the user can configure what values are reported. The output selector can take several forms: ``filename'' The output selections will be read from the named file. Within the file there can be up to four lines of comma-separated output selectors. This controls how many multi-line blocks of output are emitted when the `-O' option is used. This output, while not identical to "classic" netperf output, is inspired by it. Multiple lines have no effect for `-k' and `-o' options. Putting output selections in a file can be useful when the list of selections is long. `comma and/or semi-colon-separated list' The output selections will be parsed from a comma and/or semi-colon-separated list of output selectors. When the list is given to a `-O' option a semi-colon specifies a new output block should be started. Semi-colons have the same meaning as commas when used with the `-k' or `-o' options. Depending on the command interpreter being used, the semi-colon may have to be escaped somehow to keep it from being interpreted by the command interpreter. This can often be done by enclosing the entire list in quotes. `all' If the keyword all is specified it means that all known output values should be displayed at the end of the test. This can be a great deal of output. As of version 2.5.0 there are 157 different output selectors. `?' If a "?" is given as the output selection, the list of all known output selectors will be displayed and no test actually run. When passed to the `-O' option they will be listed one per line. Otherwise they will be listed as a comma-separated list. It may be necessary to protect the "?" from the command interpreter by escaping it or enclosing it in quotes. `no selector' If nothing is given to the `-k', `-o' or `-O' option then the code selects a default set of output selectors inspired by classic netperf output. The format will be the `human readable' format emitted by the test-specific `-O' option. The order of evaluation will first check for an output selection. If none is specified with the `-k', `-o' or `-O' option netperf will select a default based on the characteristics of the test. If there is an output selection, the code will first check for `?', then check to see if it is the magic `all' keyword. After that it will check for either `,' or `;' in the selection and take that to mean it is a comma and/or semi-colon-separated list. If none of those checks match, netperf will then assume the output specification is a filename and attempt to open and parse the file. * Menu: * Omni Output Selectors::  File: netperf.info, Node: Omni Output Selectors, Prev: Omni Output Selection, Up: Omni Output Selection 9.3.1 Omni Output Selectors --------------------------- As of version 2.5.0 the output selectors are: `OUTPUT_NONE' This is essentially a null output. For `-k' output it will simply add a line that reads "OUTPUT_NONE=" to the output. For `-o' it will cause an empty "column" to be included. For `-O' output it will cause extra spaces to separate "real" output. `SOCKET_TYPE' This will cause the socket type (eg SOCK_STREAM, SOCK_DGRAM) for the data connection to be output. `PROTOCOL' This will cause the protocol used for the data connection to be displayed. `DIRECTION' This will display the data flow direction relative to the netperf process. Units: Send or Recv for a unidirectional bulk-transfer test, or Send|Recv for a request/response test. `ELAPSED_TIME' This will display the elapsed time in seconds for the test. `THROUGHPUT' This will display the throughput for the test. Units: As requested via the global `-f' option and displayed by the THROUGHPUT_UNITS output selector. `THROUGHPUT_UNITS' This will display the units for what is displayed by the `THROUGHPUT' output selector. `LSS_SIZE_REQ' This will display the local (netperf) send socket buffer size (aka SO_SNDBUF) requested via the command line. Units: Bytes. `LSS_SIZE' This will display the local (netperf) send socket buffer size (SO_SNDBUF) immediately after the data connection socket was created. Peculiarities of different networking stacks may lead to this differing from the size requested via the command line. Units: Bytes. `LSS_SIZE_END' This will display the local (netperf) send socket buffer size (SO_SNDBUF) immediately before the data connection socket is closed. Peculiarities of different networking stacks may lead this to differ from the size requested via the command line and/or the size immediately after the data connection socket was created. Units: Bytes. `LSR_SIZE_REQ' This will display the local (netperf) receive socket buffer size (aka SO_RCVBUF) requested via the command line. Units: Bytes. `LSR_SIZE' This will display the local (netperf) receive socket buffer size (SO_RCVBUF) immediately after the data connection socket was created. Peculiarities of different networking stacks may lead to this differing from the size requested via the command line. Units: Bytes. `LSR_SIZE_END' This will display the local (netperf) receive socket buffer size (SO_RCVBUF) immediately before the data connection socket is closed. Peculiarities of different networking stacks may lead this to differ from the size requested via the command line and/or the size immediately after the data connection socket was created. Units: Bytes. `RSS_SIZE_REQ' This will display the remote (netserver) send socket buffer size (aka SO_SNDBUF) requested via the command line. Units: Bytes. `RSS_SIZE' This will display the remote (netserver) send socket buffer size (SO_SNDBUF) immediately after the data connection socket was created. Peculiarities of different networking stacks may lead to this differing from the size requested via the command line. Units: Bytes. `RSS_SIZE_END' This will display the remote (netserver) send socket buffer size (SO_SNDBUF) immediately before the data connection socket is closed. Peculiarities of different networking stacks may lead this to differ from the size requested via the command line and/or the size immediately after the data connection socket was created. Units: Bytes. `RSR_SIZE_REQ' This will display the remote (netserver) receive socket buffer size (aka SO_RCVBUF) requested via the command line. Units: Bytes. `RSR_SIZE' This will display the remote (netserver) receive socket buffer size (SO_RCVBUF) immediately after the data connection socket was created. Peculiarities of different networking stacks may lead to this differing from the size requested via the command line. Units: Bytes. `RSR_SIZE_END' This will display the remote (netserver) receive socket buffer size (SO_RCVBUF) immediately before the data connection socket is closed. Peculiarities of different networking stacks may lead this to differ from the size requested via the command line and/or the size immediately after the data connection socket was created. Units: Bytes. `LOCAL_SEND_SIZE' This will display the size of the buffers netperf passed in any "send" calls it made on the data connection for a non-request/response test. Units: Bytes. `LOCAL_RECV_SIZE' This will display the size of the buffers netperf passed in any "receive" calls it made on the data connection for a non-request/response test. Units: Bytes. `REMOTE_SEND_SIZE' This will display the size of the buffers netserver passed in any "send" calls it made on the data connection for a non-request/response test. Units: Bytes. `REMOTE_RECV_SIZE' This will display the size of the buffers netserver passed in any "receive" calls it made on the data connection for a non-request/response test. Units: Bytes. `REQUEST_SIZE' This will display the size of the requests netperf sent in a request-response test. Units: Bytes. `RESPONSE_SIZE' This will display the size of the responses netserver sent in a request-response test. Units: Bytes. `LOCAL_CPU_UTIL' This will display the overall CPU utilization during the test as measured by netperf. Units: 0 to 100 percent. `LOCAL_CPU_METHOD' This will display the method used by netperf to measure CPU utilization. Units: single character denoting method. `LOCAL_SD' This will display the service demand, or units of CPU consumed per unit of work, as measured by netperf. Units: microseconds of CPU consumed per either KB (K==1024) of data transferred or request/response transaction. `REMOTE_CPU_UTIL' This will display the overall CPU utilization during the test as measured by netserver. Units 0 to 100 percent. `REMOTE_CPU_METHOD' This will display the method used by netserver to measure CPU utilization. Units: single character denoting method. `REMOTE_SD' This will display the service demand, or units of CPU consumed per unit of work, as measured by netserver. Units: microseconds of CPU consumed per either KB (K==1024) of data transferred or request/response transaction. `SD_UNITS' This will display the units for LOCAL_SD and REMOTE_SD `CONFIDENCE_LEVEL' This will display the confidence level requested by the user either explicitly via the global `-I' option, or implicitly via the global `-i' option. The value will be either 95 or 99 if confidence intervals have been requested or 0 if they were not. Units: Percent `CONFIDENCE_INTERVAL' This will display the width of the confidence interval requested either explicitly via the global `-I' option or implicitly via the global `-i' option. Units: Width in percent of mean value computed. A value of -1.0 means that confidence intervals were not requested. `CONFIDENCE_ITERATION' This will display the number of test iterations netperf undertook, perhaps while attempting to achieve the requested confidence interval and level. If confidence intervals were requested via the command line then the value will be between 3 and 30. If confidence intervals were not requested the value will be 1. Units: Iterations `THROUGHPUT_CONFID' This will display the width of the confidence interval actually achieved for `THROUGHPUT' during the test. Units: Width of interval as percentage of reported throughput value. `LOCAL_CPU_CONFID' This will display the width of the confidence interval actually achieved for overall CPU utilization on the system running netperf (`LOCAL_CPU_UTIL') during the test, if CPU utilization measurement was enabled. Units: Width of interval as percentage of reported CPU utilization. `REMOTE_CPU_CONFID' This will display the width of the confidence interval actually achieved for overall CPU utilization on the system running netserver (`REMOTE_CPU_UTIL') during the test, if CPU utilization measurement was enabled. Units: Width of interval as percentage of reported CPU utilization. `TRANSACTION_RATE' This will display the transaction rate in transactions per second for a request/response test even if the user has requested a throughput in units of bits or bytes per second via the global `-f' option. It is undefined for a non-request/response test. Units: Transactions per second. `RT_LATENCY' This will display the average round-trip latency for a request/response test, accounting for number of transactions in flight at one time. It is undefined for a non-request/response test. Units: Microseconds per transaction `BURST_SIZE' This will display the "burst size" or added transactions in flight in a request/response test as requested via a test-specific `-b' option. The number of transactions in flight at one time will be one greater than this value. It is undefined for a non-request/response test. Units: added Transactions in flight. `LOCAL_TRANSPORT_RETRANS' This will display the number of retransmissions experienced on the data connection during the test as determined by netperf. A value of -1 means the attempt to determine the number of retransmissions failed or the concept was not valid for the given protocol or the mechanism is not known for the platform. A value of -2 means it was not attempted. As of version 2.5.0 the meaning of values are in flux and subject to change. Units: number of retransmissions. `REMOTE_TRANSPORT_RETRANS' This will display the number of retransmissions experienced on the data connection during the test as determined by netserver. A value of -1 means the attempt to determine the number of retransmissions failed or the concept was not valid for the given protocol or the mechanism is not known for the platform. A value of -2 means it was not attempted. As of version 2.5.0 the meaning of values are in flux and subject to change. Units: number of retransmissions. `TRANSPORT_MSS' This will display the Maximum Segment Size (aka MSS) or its equivalent for the protocol being used during the test. A value of -1 means either the concept of an MSS did not apply to the protocol being used, or there was an error in retrieving it. Units: Bytes. `LOCAL_SEND_THROUGHPUT' The throughput as measured by netperf for the successful "send" calls it made on the data connection. Units: as requested via the global `-f' option and displayed via the `THROUGHPUT_UNITS' output selector. `LOCAL_RECV_THROUGHPUT' The throughput as measured by netperf for the successful "receive" calls it made on the data connection. Units: as requested via the global `-f' option and displayed via the `THROUGHPUT_UNITS' output selector. `REMOTE_SEND_THROUGHPUT' The throughput as measured by netserver for the successful "send" calls it made on the data connection. Units: as requested via the global `-f' option and displayed via the `THROUGHPUT_UNITS' output selector. `REMOTE_RECV_THROUGHPUT' The throughput as measured by netserver for the successful "receive" calls it made on the data connection. Units: as requested via the global `-f' option and displayed via the `THROUGHPUT_UNITS' output selector. `LOCAL_CPU_BIND' The CPU to which netperf was bound, if at all, during the test. A value of -1 means that netperf was not explicitly bound to a CPU during the test. Units: CPU ID `LOCAL_CPU_COUNT' The number of CPUs (cores, threads) detected by netperf. Units: CPU count. `LOCAL_CPU_PEAK_UTIL' The utilization of the CPU most heavily utilized during the test, as measured by netperf. This can be used to see if any one CPU of a multi-CPU system was saturated even though the overall CPU utilization as reported by `LOCAL_CPU_UTIL' was low. Units: 0 to 100% `LOCAL_CPU_PEAK_ID' The id of the CPU most heavily utilized during the test as determined by netperf. Units: CPU ID. `LOCAL_CPU_MODEL' Model information for the processor(s) present on the system running netperf. Assumes all processors in the system (as perceived by netperf) on which netperf is running are the same model. Units: Text `LOCAL_CPU_FREQUENCY' The frequency of the processor(s) on the system running netperf, at the time netperf made the call. Assumes that all processors present in the system running netperf are running at the same frequency. Units: MHz `REMOTE_CPU_BIND' The CPU to which netserver was bound, if at all, during the test. A value of -1 means that netperf was not explicitly bound to a CPU during the test. Units: CPU ID `REMOTE_CPU_COUNT' The number of CPUs (cores, threads) detected by netserver. Units: CPU count. `REMOTE_CPU_PEAK_UTIL' The utilization of the CPU most heavily utilized during the test, as measured by netserver. This can be used to see if any one CPU of a multi-CPU system was saturated even though the overall CPU utilization as reported by `REMOTE_CPU_UTIL' was low. Units: 0 to 100% `REMOTE_CPU_PEAK_ID' The id of the CPU most heavily utilized during the test as determined by netserver. Units: CPU ID. `REMOTE_CPU_MODEL' Model information for the processor(s) present on the system running netserver. Assumes all processors in the system (as perceived by netserver) on which netserver is running are the same model. Units: Text `REMOTE_CPU_FREQUENCY' The frequency of the processor(s) on the system running netserver, at the time netserver made the call. Assumes that all processors present in the system running netserver are running at the same frequency. Units: MHz `SOURCE_PORT' The port ID/service name to which the data socket created by netperf was bound. A value of 0 means the data socket was not explicitly bound to a port number. Units: ASCII text. `SOURCE_ADDR' The name/address to which the data socket created by netperf was bound. A value of 0.0.0.0 means the data socket was not explicitly bound to an address. Units: ASCII text. `SOURCE_FAMILY' The address family to which the data socket created by netperf was bound. A value of 0 means the data socket was not explicitly bound to a given address family. Units: ASCII text. `DEST_PORT' The port ID to which the data socket created by netserver was bound. A value of 0 means the data socket was not explicitly bound to a port number. Units: ASCII text. `DEST_ADDR' The name/address of the data socket created by netserver. Units: ASCII text. `DEST_FAMILY' The address family to which the data socket created by netserver was bound. A value of 0 means the data socket was not explicitly bound to a given address family. Units: ASCII text. `LOCAL_SEND_CALLS' The number of successful "send" calls made by netperf against its data socket. Units: Calls. `LOCAL_RECV_CALLS' The number of successful "receive" calls made by netperf against its data socket. Units: Calls. `LOCAL_BYTES_PER_RECV' The average number of bytes per "receive" call made by netperf against its data socket. Units: Bytes. `LOCAL_BYTES_PER_SEND' The average number of bytes per "send" call made by netperf against its data socket. Units: Bytes. `LOCAL_BYTES_SENT' The number of bytes successfully sent by netperf through its data socket. Units: Bytes. `LOCAL_BYTES_RECVD' The number of bytes successfully received by netperf through its data socket. Units: Bytes. `LOCAL_BYTES_XFERD' The sum of bytes sent and received by netperf through its data socket. Units: Bytes. `LOCAL_SEND_OFFSET' The offset from the alignment of the buffers passed by netperf in its "send" calls. Specified via the global `-o' option and defaults to 0. Units: Bytes. `LOCAL_RECV_OFFSET' The offset from the alignment of the buffers passed by netperf in its "receive" calls. Specified via the global `-o' option and defaults to 0. Units: Bytes. `LOCAL_SEND_ALIGN' The alignment of the buffers passed by netperf in its "send" calls as specified via the global `-a' option. Defaults to 8. Units: Bytes. `LOCAL_RECV_ALIGN' The alignment of the buffers passed by netperf in its "receive" calls as specified via the global `-a' option. Defaults to 8. Units: Bytes. `LOCAL_SEND_WIDTH' The "width" of the ring of buffers through which netperf cycles as it makes its "send" calls. Defaults to one more than the local send socket buffer size divided by the send size as determined at the time the data socket is created. Can be used to make netperf more processor data cache unfriendly. Units: number of buffers. `LOCAL_RECV_WIDTH' The "width" of the ring of buffers through which netperf cycles as it makes its "receive" calls. Defaults to one more than the local receive socket buffer size divided by the receive size as determined at the time the data socket is created. Can be used to make netperf more processor data cache unfriendly. Units: number of buffers. `LOCAL_SEND_DIRTY_COUNT' The number of bytes to "dirty" (write to) before netperf makes a "send" call. Specified via the global `-k' option, which requires that -enable-dirty=yes was specified with the configure command prior to building netperf. Units: Bytes. `LOCAL_RECV_DIRTY_COUNT' The number of bytes to "dirty" (write to) before netperf makes a "recv" call. Specified via the global `-k' option which requires that -enable-dirty was specified with the configure command prior to building netperf. Units: Bytes. `LOCAL_RECV_CLEAN_COUNT' The number of bytes netperf should read "cleanly" before making a "receive" call. Specified via the global `-k' option which requires that -enable-dirty was specified with configure command prior to building netperf. Clean reads start were dirty writes ended. Units: Bytes. `LOCAL_NODELAY' Indicates whether or not setting the test protocol-specific "no delay" (eg TCP_NODELAY) option on the data socket used by netperf was requested by the test-specific `-D' option and successful. Units: 0 means no, 1 means yes. `LOCAL_CORK' Indicates whether or not TCP_CORK was set on the data socket used by netperf as requested via the test-specific `-C' option. 1 means yes, 0 means no/not applicable. `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' These are all like their "LOCAL_" counterparts only for the netserver rather than netperf. `LOCAL_SYSNAME' The name of the OS (eg "Linux") running on the system on which netperf was running. Units: ASCII Text `LOCAL_SYSTEM_MODEL' The model name of the system on which netperf was running. Units: ASCII Text. `LOCAL_RELEASE' The release name/number of the OS running on the system on which netperf was running. Units: ASCII Text `LOCAL_VERSION' The version number of the OS running on the system on which netperf was running. Units: ASCII Text `LOCAL_MACHINE' The machine architecture of the machine on which netperf was running. Units: ASCII Text. `REMOTE_SYSNAME' `REMOTE_SYSTEM_MODEL' `REMOTE_RELEASE' `REMOTE_VERSION' `REMOTE_MACHINE' These are all like their "LOCAL_" counterparts only for the netserver rather than netperf. `LOCAL_INTERFACE_NAME' The name of the probable egress interface through which the data connection went on the system running netperf. Example: eth0. Units: ASCII Text. `LOCAL_INTERFACE_VENDOR' The vendor ID of the probable egress interface through which traffic on the data connection went on the system running netperf. Units: Hexadecimal IDs as might be found in a `pci.ids' file or at the PCI ID Repository (http://pciids.sourceforge.net/). `LOCAL_INTERFACE_DEVICE' The device ID of the probable egress interface through which traffic on the data connection went on the system running netperf. Units: Hexadecimal IDs as might be found in a `pci.ids' file or at the PCI ID Repository (http://pciids.sourceforge.net/). `LOCAL_INTERFACE_SUBVENDOR' The sub-vendor ID of the probable egress interface through which traffic on the data connection went on the system running netperf. Units: Hexadecimal IDs as might be found in a `pci.ids' file or at the PCI ID Repository (http://pciids.sourceforge.net/). `LOCAL_INTERFACE_SUBDEVICE' The sub-device ID of the probable egress interface through which traffic on the data connection went on the system running netperf. Units: Hexadecimal IDs as might be found in a `pci.ids' file or at the PCI ID Repository (http://pciids.sourceforge.net/). `LOCAL_DRIVER_NAME' The name of the driver used for the probable egress interface through which traffic on the data connection went on the system running netperf. Units: ASCII Text. `LOCAL_DRIVER_VERSION' The version string for the driver used for the probable egress interface through which traffic on the data connection went on the system running netperf. Units: ASCII Text. `LOCAL_DRIVER_FIRMWARE' The firmware version for the driver used for the probable egress interface through which traffic on the data connection went on the system running netperf. Units: ASCII Text. `LOCAL_DRIVER_BUS' The bus address of the probable egress interface through which traffic on the data connection went on the system running netperf. Units: ASCII Text. `LOCAL_INTERFACE_SLOT' The slot ID of the probable egress interface through which traffic on the data connection went on the system running netperf. Units: ASCII Text. `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' These are all like their "LOCAL_" counterparts only for the netserver rather than netperf. `LOCAL_INTERVAL_USECS' The interval at which bursts of operations (sends, receives, transactions) were attempted by netperf. Specified by the global `-w' option which requires -enable-intervals to have been specified with the configure command prior to building netperf. Units: Microseconds (though specified by default in milliseconds on the command line) `LOCAL_INTERVAL_BURST' The number of operations (sends, receives, transactions depending on the test) which were attempted by netperf each LOCAL_INTERVAL_USECS units of time. Specified by the global `-b' option which requires -enable-intervals to have been specified with the configure command prior to building netperf. Units: number of operations per burst. `REMOTE_INTERVAL_USECS' The interval at which bursts of operations (sends, receives, transactions) were attempted by netserver. Specified by the global `-w' option which requires -enable-intervals to have been specified with the configure command prior to building netperf. Units: Microseconds (though specified by default in milliseconds on the command line) `REMOTE_INTERVAL_BURST' The number of operations (sends, receives, transactions depending on the test) which were attempted by netperf each LOCAL_INTERVAL_USECS units of time. Specified by the global `-b' option which requires -enable-intervals to have been specified with the configure command prior to building netperf. Units: number of operations per 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' A bunch of stuff related to what sort of security mechanisms (eg SELINUX) were enabled on the systems during the test. `RESULT_BRAND' The string specified by the user with the global `-B' option. Units: ASCII Text. `UUID' The universally unique identifier associated with this test, either generated automagically by netperf, or passed to netperf via an omni test-specific `-u' option. Note: Future versions may make this a global command-line option. Units: ASCII Text. `MIN_LATENCY' The minimum "latency" or operation time (send, receive or request/response exchange depending on the test) as measured on the netperf side when the global `-j' option was specified. Units: Microseconds. `MAX_LATENCY' The maximum "latency" or operation time (send, receive or request/response exchange depending on the test) as measured on the netperf side when the global `-j' option was specified. Units: Microseconds. `P50_LATENCY' The 50th percentile value of "latency" or operation time (send, receive or request/response exchange depending on the test) as measured on the netperf side when the global `-j' option was specified. Units: Microseconds. `P90_LATENCY' The 90th percentile value of "latency" or operation time (send, receive or request/response exchange depending on the test) as measured on the netperf side when the global `-j' option was specified. Units: Microseconds. `P99_LATENCY' The 99th percentile value of "latency" or operation time (send, receive or request/response exchange depending on the test) as measured on the netperf side when the global `-j' option was specified. Units: Microseconds. `MEAN_LATENCY' The average "latency" or operation time (send, receive or request/response exchange depending on the test) as measured on the netperf side when the global `-j' option was specified. Units: Microseconds. `STDDEV_LATENCY' The standard deviation of "latency" or operation time (send, receive or request/response exchange depending on the test) as measured on the netperf side when the global `-j' option was specified. Units: Microseconds. `COMMAND_LINE' The full command line used when invoking netperf. Units: ASCII Text. `OUTPUT_END' While emitted with the list of output selectors, it is ignored when specified as an output selector.  File: netperf.info, Node: Other Netperf Tests, Next: Address Resolution, Prev: The Omni Tests, Up: Top 10 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:: * UUID Generation::  File: netperf.info, Node: CPU rate calibration, Next: UUID Generation, Prev: Other Netperf Tests, Up: Other Netperf Tests 10.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 systems, 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: UUID Generation, Prev: CPU rate calibration, Up: Other Netperf Tests 10.2 UUID Generation ==================== Beginning with version 2.5.0 netperf can generate Universally Unique IDentifiers (UUIDs). This can be done explicitly via the "UUID" test: $ netperf -t UUID 2c8561ae-9ebd-11e0-a297-0f5bfa0349d0 In and of itself, this is not terribly useful, but used in conjunction with the test-specific `-u' option of an "omni" test to set the UUID emitted by the *note UUID: Omni Output Selectors. output selector, it can be used to tie-together the separate instances of an aggregate netperf test. Say, for instance if they were inserted into a database of some sort.  File: netperf.info, Node: Address Resolution, Next: Enhancing Netperf, Prev: Other Netperf Tests, Up: Top 11 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 12 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 appropriate `--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 However, with the addition of the "omni" tests in version 2.5.0 it is preferred that one attempt to make the necessary changes to `src/nettest_omni.c' rather than adding new source files, unless this would make the omni tests entirely too complicated. 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 consensus 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 13 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 descendant 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 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 6) * Bandwidth Limitation: Installing Netperf Bits. (line 64) * Connection Latency: TCP_CC. (line 6) * CPU Utilization: CPU Utilization. (line 6) * 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 6) * Latency, Connection Establishment <2>: XTI_TCP_CC. (line 6) * Latency, Connection Establishment <3>: TCP_CRR. (line 6) * Latency, Connection Establishment: TCP_CC. (line 6) * Latency, Request-Response <1>: SCTP_RR. (line 6) * Latency, Request-Response <2>: DLCO_RR. (line 6) * Latency, Request-Response <3>: DLCL_RR. (line 6) * Latency, Request-Response <4>: XTI_UDP_RR. (line 6) * Latency, Request-Response <5>: XTI_TCP_CRR. (line 6) * Latency, Request-Response <6>: XTI_TCP_RR. (line 6) * Latency, Request-Response <7>: UDP_RR. (line 6) * Latency, Request-Response <8>: TCP_CRR. (line 6) * Latency, Request-Response: TCP_RR. (line 6) * Limiting Bandwidth <1>: UDP_STREAM. (line 9) * Limiting Bandwidth: Installing Netperf Bits. (line 64) * Measuring Latency: TCP_RR. (line 6) * Packet Loss: UDP_RR. (line 6) * 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 6) * --enable-cpuutil, Configure: Installing Netperf Bits. (line 24) * --enable-dlpi, Configure: Installing Netperf Bits. (line 30) * --enable-histogram, Configure: Installing Netperf Bits. (line 64) * --enable-intervals, Configure: Installing Netperf Bits. (line 64) * --enable-omni, Configure: Installing Netperf Bits. (line 36) * --enable-sctp, Configure: Installing Netperf Bits. (line 30) * --enable-unixdomain, Configure: Installing Netperf Bits. (line 30) * --enable-xti, Configure: Installing Netperf Bits. (line 30) * -4, Global: Global Options. (line 489) * -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 498) * -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) * -c, Test-specific: Native Omni Tests. (line 13) * -D, Global: Global Options. (line 56) * -d, Global: Global Options. (line 47) * -d, Test-specific: Native Omni Tests. (line 17) * -F, Global: Global Options. (line 76) * -f, Global: Global Options. (line 67) * -H, Global: Global Options. (line 95) * -h, Global: Global Options. (line 91) * -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 179) * -I, Global: Global Options. (line 130) * -j, Global: Global Options. (line 205) * -k, Test-specific: Native Omni Tests. (line 37) * -L, Global: Global Options. (line 263) * -l, Global: Global Options. (line 242) * -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 293) * -n, Global: Global Options. (line 275) * -O, Global: Global Options. (line 338) * -o, Global: Global Options. (line 329) * -O, Test-specific: Native Omni Tests. (line 62) * -o, Test-specific: Native Omni Tests. (line 50) * -P, Global: Global Options. (line 363) * -p, Global: Global Options. (line 343) * -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, Global: Global Options. (line 381) * -s, Global: Global Options. (line 372) * -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 423) * -t, Global: Global Options. (line 391) * -T, Test-specific: Native Omni Tests. (line 81) * -t, Test-specific: Native Omni Tests. (line 76) * -V, Global: Global Options. (line 468) * -v, Global: Global Options. (line 440) * -W, Global: Global Options. (line 480) * -w, Global: Global Options. (line 473)  Tag Table: Node: Top439 Node: Introduction1476 Node: Conventions4150 Node: Installing Netperf5913 Node: Getting Netperf Bits7467 Node: Installing Netperf Bits9326 Node: Verifying Installation17820 Node: The Design of Netperf18524 Node: CPU Utilization20120 Node: CPU Utilization in a Virtual Guest28844 Node: Global Command-line Options30431 Node: Command-line Options Syntax30970 Node: Global Options32366 Node: Using Netperf to Measure Bulk Data Transfer56529 Node: Issues in Bulk Transfer57202 Node: Options common to TCP UDP and SCTP tests61463 Node: TCP_STREAM67788 Node: TCP_MAERTS71873 Node: TCP_SENDFILE73110 Node: UDP_STREAM75610 Node: XTI_TCP_STREAM79046 Node: XTI_UDP_STREAM79691 Node: SCTP_STREAM80336 Node: DLCO_STREAM81036 Node: DLCL_STREAM83009 Node: STREAM_STREAM83883 Node: DG_STREAM84741 Node: Using Netperf to Measure Request/Response85422 Node: Issues in Request/Response87740 Node: Options Common to TCP UDP and SCTP _RR tests90114 Node: TCP_RR95138 Node: TCP_CC97538 Node: TCP_CRR99772 Node: UDP_RR100834 Node: XTI_TCP_RR103138 Node: XTI_TCP_CC103721 Node: XTI_TCP_CRR104226 Node: XTI_UDP_RR104738 Node: DLCL_RR105315 Node: DLCO_RR105468 Node: SCTP_RR105620 Node: Using Netperf to Measure Aggregate Performance105756 Node: Running Concurrent Netperf Tests106788 Node: Issues in Running Concurrent Tests111429 Node: Using --enable-burst113693 Node: Using --enable-demo120592 Node: Using Netperf to Measure Bidirectional Transfer126148 Node: Bidirectional Transfer with Concurrent Tests127280 Node: Bidirectional Transfer with TCP_RR129636 Node: Implications of Concurrent Tests vs Burst Request/Response132020 Node: The Omni Tests133834 Node: Native Omni Tests134881 Node: Migrated Tests140159 Node: Omni Output Selection142264 Node: Omni Output Selectors145247 Node: Other Netperf Tests172955 Node: CPU rate calibration173390 Node: UUID Generation175758 Node: Address Resolution176474 Node: Enhancing Netperf178450 Node: Netperf4179945 Node: Concept Index180850 Node: Option Index183176  End Tag Table netperf-2.6.0/doc/netperf_old.ps0000644000175000017500000454151311576721154013543 00000000000000%!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 netperf-2.6.0/README.solaris0000644000175000017500000000235411525015225012440 00000000000000Until 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. netperf-2.6.0/Release_Notes0000644000175000017500000013467311770164154012602 00000000000000These are the Release Notes for Revision 2.6.0 of netperf: *) Initial pass at support for --enable-intervals (WANT_INTERVALS) for Windows, courtesy of Jonathan Cook. *) When in demo mode (./configure --enable-demo and a global -D option netperf will make sure it emits "one last interval result" when the test is terminated. This should assist when post-processing results through the likes of rrdtool when there is a slow-down in the performance just at the end that would have stretched the interval to beyond the test termination. *) A fix to have the AF_UNIX tests realize that the value for "take the system default" socket buffer size became -1 years ago. Bug found by Eric Dumazet. *) Include a patch from Dave Taht to enable symbolic manipulation of IP_TOS values. *) Include a patch from Sachar Raindel to enable the omni tests to get ENOBUFS under Linux when the socket buffer is larger than the tx queue of the egress interface. This will help preclude netperf's reporting a larger than link-rate send-side figure. *) Fix a problem with late checking of the return from select() in src/netserver.c. Reported by Waqar Sheikh. *) A new global -Z option has been added to netperf and netserver. This takes as an argument a passphrase. In the case of netserver it will expect a control message with the passphrase as the first thing it receives on the control connection. If netserver does not receive a control message with the passphrase it will close the control connection and move-on. If the netserver receives a control message with a passprhase when it is not lookign for one, it will be ignored. There is at present a 20 second timeout on the attempted receipt of the request message. In the case of netperf, the passphrase will be the first thing sent on the control connection. There is no response to a passphrase control message. *) Demo mode output format will now track the omni output format. So, if the omni ouput format is CSV then the interim results will be emitted in csv. Likewise for keyval. If the mode is human (default and test-specific -O) then the output remains unchanged. Keyval output includes the count of interval, with a mind towards being able to source it in shells and whatnot. Subject to change without notice. *) A patch to correctly handle IPv6 addresses in the control messages, courtesy of Bjoern Zeeb. *) The global -F option can now be used specify a local and/or remote fill file. *) It is now possible to set/get the TCP congestion control algorithm being used by either end of the test connection when using the omni code. The output selectors are LOCAL_CONG_CONTROL and REMOTE_CONG_CONTROL and setting is via the test-specific -K option. *) Stop leaking file descriptors when looking-up probable egress interface names and I/O slot numbers. *) The global -Y option can be used to set IP_TOS on those platforms which support it. Since this is specific to IP (v4 or v6) it may move to a test-specific otion in the future. It is presently global for foolish consistency with the -y option to set SO_PRIORITY. *) The global -y option can be used to set SO_PRIORITY on those platforms which support it. Based on patches from Amir Vidai. *) The control message size has been increased from 256 bytes to 512 bytes. THIS WILL BREAK COMPATABILITY WITH PREVIOUS VERSIONS OF NETPERF. However, we need more room on the pinhead on which the angels dance. *) Make the "sum" field of the histogram structure a 64 bit int to avoid having it wrap-around on tests where the sum of all the measured latencies was larger than 31 bits. This was causing statistics like stddev to go negative in some cases. *) If the time delta between two events is negative, do not bother doing any math with it in the histogram/statistics code, just increment the ridiculous count and move-on. *) Fixed a bug which caused local transport retransmissions to be reported as -1 even though the getsockopt() call was successful. (Linux). Later included remote transport retransmissions. *) The src/nettest_omni.c and re-written src/netserver.c code are now known to have compiled under Windows 7 x64 with the Microsoft WDK. There remains a timing issue with confidence intervals which is yet to be addressed, and may have been there for ages. Netserver has been run as a non-spawning (-f) server, netperf has been run, both have run "classic" and "omni" tests. These are the Release Notes for Revision 2.5.0 of netperf: *) Add a new -N option to netserver which will suppress all creation of debug files and so debugging output. While this would put a serious crimp in debugging a problem in netserver, it will enable folks using small embedded systems to avoid soaking-up their /tmp filesystem with clutter. *) A refactoring and partial re-write of the src/netserver.c code to untangle years of accumulated spaghetti code. Included is the ability to not daemonize netserver when launched from the command-line (-D) and also to not fork/spawn child processes upon the acceptance of a control connection (-f). Combined, the two options will cause netserver to remain in the forground and not spawn children - in effect netserver will handle only one test at a time. *) As it has been two years since the defect in Solaris getaddrinfo() was submitted, it should be the case that a fix is available, so it should no longer be necessary to "hide" the "Hey your platform's getaddrinfo() call is buggy" warning. Consequently, it is no longer being suppressed. *) A new global command line option - -S - has been added to enable setting of SO_KEEPALIVE on the data socket. This will affect the netperf side of the "classic" netperf tests, and will also affect the netserver side of an "omni" or migrated classic test as only the control message for the omni tests has the requisite flags field to communicate the desire to set SO_KEEPALIVE. Ostensibly, this may help when netperf is (ab)used in functional testing situations and netservers end-up orphaned and out in the cold because their corresponding netperfs went away and the notification was lost amid the roar of traffic over-saturating the interconnect(s). The default is to behave as before - SO_KEEPALIVE not set. *) Base on the frequency at which the author has used the functionality, the default for --enable-burst is now "yes." To disable support for burst mode one must now include a --enable-burst=no when performing the ./configure prior to compiling the bits. *) The output of the -D global command line option (./configure --enable-demo) has been enhanced to include seconds and milliseconds since the epoch as returned by a gettimeofday() call with a null pointer for the timezone. This is in support of being able to easily shove interim results into an rrdtool Round-Robin Database (RRD). *) The "omni" tests will be compiled-in by default, and WANT_MIGRATION is the default. One must ./configure with --enable-omni=no to disable this. *) When ./configured with --enable-intervals and intervals are actually used, the round-trip latency reported by an omni (or migrated classic) request/response test should better reflect reality rather than the length of the pacing interval. It and the MEAN_LATENCY from the histogram and -j output will still differ slightly and probably always will. *) The histogram code has been enhanced to track more than one latency at a time and so --enable-histogram and --enable-burst are now compatible - for the omni tests or migrated "classic" tests only however. This change was inspired/instigated by Jim Gettys and his work on overly-large queues of buffers *) WANT_MIGRATION is enabled when one specifies --enable-omni on the configure command line. *) Massage and encorporate a patch from Google that enables randomization of the IP addresses used in a test. An optional mask length in the standard '/' notation can be added to the end of the IP/name in the test-specific -H or -L options of an Omni test. *) Massage and include a DEBUG_LOG_FILE patch for Android from Josselin Costanzi *) Add intial attempt to report Slot ID on HP-UX 11.31. *) Add global -s option to cause omni tests to pause between setting-up the test and actually starting it. pause is in seconds. Poor man's way to (attempt to) avoid issues when starting many, Many, MANY concurrent netperf tests. Based on patches from Google. *) Additional timing statistics will be kept by the omni tests when the global "-j" option is specified. The additional statistics are min, max, mean, stddev and the 50th, 90th and 99th percentiles on the timings measured by histograms. Based on patches from Google. *) Add a workaround to get Linux to report TX queue drops in a UDP_STREAM test when the socket buffer size is larger than the TX queue. Provided by Andrew Gallatin. *) Fix the configure script to know it does not have to look for an SCTP library on FreeBSD 8.X *) The BSD and "omni" tests now have a test-specific -R option which is a boolean controlling whether or not SO_DONTROUTE will be set on the data socket. By default, any unidirectional UDP test will have SO_DONTROUTE set unless a -R 1 option is given. All other tests (including UDP request/response tests) will not have SO_DONTROUTE set unless a -R 0 option is given. This is put into place to make it take longer for blithering idiots to shoot themselves in the foot by running tests on setups they shouldn't. *) At least the beginnings of support for RDS, based on a circa 2007 patch against 2.4.2 by Vladimir Sokolovsky. Rather than create the "RDS_STREAM" test of his patch, the intention this time around is to enable RDS for the "omni" tests by using an omni test-specific -T rds specifyer for the "transport" to use. *) Missing fprintf format statements provided by Bruno Cornec *) Numerous cleanups from Jose Pedro Oliveira *) Fixes to allow netperf -H ::1 to work without having to add -6 or an AF_INET6 -L option These are the Release Notes for 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. netperf-2.6.0/README.osx0000644000175000017500000000040211525015225011565 00000000000000If 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. netperf-2.6.0/mkinstalldirs0000755000175000017500000000370411525015225012713 00000000000000#! /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 netperf-2.6.0/configure0000755000175000017500000076355611770160504012041 00000000000000#! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.67 for netperf 2.6.0. # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, # 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 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=: # Pre-4.2 versions of Zsh do 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_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } 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.) 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 $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH if test "x$CONFIG_SHELL" = x; then as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do 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_required="as_fn_return () { (exit \$1); } as_fn_success () { as_fn_return 0; } as_fn_failure () { as_fn_return 1; } as_fn_ret_success () { return 0; } as_fn_ret_failure () { return 1; } exitcode=0 as_fn_success || { exitcode=1; echo as_fn_success failed.; } as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : else exitcode=1; echo positional parameters were not saved. fi test x\$exitcode = x0 || exit 1" as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 test \$(( 1 + 1 )) = 2 || exit 1" if (eval "$as_required") 2>/dev/null; then : as_have_required=yes else as_have_required=no fi if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR as_found=false for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. as_found=: case $as_dir in #( /*) for as_base in sh bash ksh sh5; do # Try only shells that exist, to save several forks. as_shell=$as_dir/$as_base if { test -f "$as_shell" || test -f "$as_shell.exe"; } && { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : CONFIG_SHELL=$as_shell as_have_required=yes if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : break 2 fi fi done;; esac as_found=false done $as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : CONFIG_SHELL=$SHELL as_have_required=yes fi; } IFS=$as_save_IFS if test "x$CONFIG_SHELL" != x; then : # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV export CONFIG_SHELL exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"} fi if test x$as_have_required = xno; then : $as_echo "$0: This script requires a shell more modern than all" $as_echo "$0: the shells that I found on your system." if test x${ZSH_VERSION+set} = xset ; then $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" $as_echo "$0: be upgraded to zsh 4.3.4 or later." else $as_echo "$0: Please tell bug-autoconf@gnu.org about your system, $0: including any error possibly output before this $0: message. Then install a modern shell, or manually run $0: the script under such a shell if you do have one." fi exit 1 fi fi fi SHELL=${CONFIG_SHELL-/bin/sh} export SHELL # Unset more variables known to interfere with behavior of common tools. CLICOLOR_FORCE= GREP_OPTIONS= unset CLICOLOR_FORCE GREP_OPTIONS ## --------------------- ## ## M4sh Shell Functions. ## ## --------------------- ## # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_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 || $as_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" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error 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 if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # 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 as_lineno_1=$LINENO as_lineno_1a=$LINENO as_lineno_2=$LINENO as_lineno_2a=$LINENO eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { # 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" || { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_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 } ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac 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 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then 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 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='mkdir -p "$as_dir"' 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'" test -n "$DJDIR" || exec 7<&0 &1 # Name of the host. # hostname on some systems (SVR3.2, old GNU/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= # Identity of this package. PACKAGE_NAME='netperf' PACKAGE_TARNAME='netperf' PACKAGE_VERSION='2.6.0' PACKAGE_STRING='netperf 2.6.0' PACKAGE_BUGREPORT='' PACKAGE_URL='' 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_header_list= ac_subst_vars='am__EXEEXT_FALSE am__EXEEXT_TRUE LTLIBOBJS NETSYSLKUP_SOURCE NETDRVLKUP_SOURCE NETSECLKUP_SOURCE NETSLOTLKUP_SOURCE NETRTLKUP_SOURCE NETCPU_SOURCE NEED_LIBCOMPAT_FALSE NEED_LIBCOMPAT_TRUE LIBOBJS EGREP GREP CPP RANLIB am__fastdepCC_FALSE am__fastdepCC_TRUE CCDEPMODE AMDEPBACKSLASH AMDEP_FALSE AMDEP_TRUE am__quote am__include DEPDIR OBJEXT EXEEXT ac_ct_CC CPPFLAGS LDFLAGS CFLAGS CC am__untar am__tar AMTAR am__leading_dot SET_MAKE AWK mkdir_p MKDIR_P INSTALL_STRIP_PROGRAM STRIP install_sh MAKEINFO AUTOHEADER AUTOMAKE AUTOCONF ACLOCAL VERSION PACKAGE CYGPATH_W am__isrc INSTALL_DATA INSTALL_SCRIPT INSTALL_PROGRAM target_os target_vendor target_cpu target host_os host_vendor host_cpu host build_os build_vendor build_cpu build target_alias host_alias build_alias LIBS ECHO_T ECHO_N ECHO_C DEFS mandir localedir libdir psdir pdfdir dvidir htmldir infodir docdir oldincludedir includedir localstatedir sharedstatedir sysconfdir datadir datarootdir libexecdir sbindir bindir program_transform_name prefix exec_prefix PACKAGE_URL PACKAGE_BUGREPORT PACKAGE_STRING PACKAGE_VERSION PACKAGE_TARNAME PACKAGE_NAME PATH_SEPARATOR SHELL' ac_subst_files='' ac_user_opts=' enable_option_checking enable_dependency_tracking enable_largefile enable_histogram enable_dirty enable_demo enable_unixdomain enable_dlpi enable_dccp enable_omni enable_xti enable_sdp enable_exs enable_sctp enable_intervals enable_spin enable_burst enable_cpuutil enable_rtlookup enable_slotlookup enable_seclookup enable_drvlookup enable_syslookup ' 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 ac_unrecognized_opts= ac_unrecognized_sep= # 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= ;; *) 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_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=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_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=\$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_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=\$ac_optarg ;; -without-* | --without-*) ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=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 ;; -*) as_fn_error $? "unrecognized option: \`$ac_option' Try \`$0 --help' for more information" ;; *=*) ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` # Reject names that are not valid shell variable names. case $ac_envvar in #( '' | [0-9]* | *[!_$as_cr_alnum]* ) as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; esac eval $ac_envvar=\$ac_optarg export $ac_envvar ;; *) # FIXME: should be removed in autoconf 3.0. $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && $as_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'` as_fn_error $? "missing argument to $ac_option" fi if test -n "$ac_unrecognized_opts"; then case $enable_option_checking in no) ;; fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; esac fi # Check all directory arguments for consistency. 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 # Remove trailing slashes. case $ac_val in */ ) ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` eval $ac_var=\$ac_val;; esac # Be sure to have absolute directory names. case $ac_val in [\\/$]* | ?:[\\/]* ) continue;; NONE | '' ) case $ac_var in *prefix ) continue;; esac;; esac as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" 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 $as_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 .` || as_fn_error $? "working directory cannot be determined" test "X$ac_ls_di" = "X$ac_pwd_ls_di" || as_fn_error $? "pwd does not report name of working directory" # 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 -- "$as_myself" || $as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_myself" : 'X\(//\)[^/]' \| \ X"$as_myself" : 'X\(//\)$' \| \ X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_myself" | 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 .." as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" fi ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" ac_abs_confdir=`( cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" 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.6.0 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.6.0:";; esac cat <<\_ACEOF Optional Features: --disable-option-checking ignore unrecognized --enable/--with options --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 build --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 (Objective) C/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. Report bugs to the package provider. _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" || { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && 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=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_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 $as_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.6.0 generated by GNU Autoconf 2.67 Copyright (C) 2010 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 ## ------------------------ ## ## Autoconf initialization. ## ## ------------------------ ## # ac_fn_c_try_compile LINENO # -------------------------- # Try to compile conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack 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 ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} as_fn_set_status $ac_retval } # ac_fn_c_try_compile # ac_fn_c_try_link LINENO # ----------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_link () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack 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 ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would # interfere with the next link command; also delete a directory that is # left behind by Apple's compiler. We do this before executing the actions. rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} as_fn_set_status $ac_retval } # ac_fn_c_try_link # ac_fn_c_try_cpp LINENO # ---------------------- # Try to preprocess conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_cpp () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } > conftest.i && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} as_fn_set_status $ac_retval } # ac_fn_c_try_cpp # ac_fn_c_try_run LINENO # ---------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. Assumes # that executables *can* be run. ac_fn_c_try_run () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then : ac_retval=0 else $as_echo "$as_me: program exited with status $ac_status" >&5 $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=$ac_status fi rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} as_fn_set_status $ac_retval } # ac_fn_c_try_run # ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES # ------------------------------------------------------- # Tests whether HEADER exists, giving a warning if it cannot be compiled using # the include files in INCLUDES and setting the cache variable VAR # accordingly. ac_fn_c_check_header_mongrel () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if eval "test \"\${$3+set}\"" = set; then : { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval "test \"\${$3+set}\"" = set; then : $as_echo_n "(cached) " >&6 fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } else # Is the header compilable? { $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 $as_echo_n "checking $2 usability... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_header_compiler=yes else ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 $as_echo "$ac_header_compiler" >&6; } # Is the header present? { $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 $as_echo_n "checking $2 presence... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include <$2> _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : ac_header_preproc=yes else ac_header_preproc=no fi rm -f conftest.err conftest.i conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 $as_echo "$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #(( yes:no: ) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 $as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} ;; no:yes:* ) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 $as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 $as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 $as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 $as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval "test \"\${$3+set}\"" = set; then : $as_echo_n "(cached) " >&6 else eval "$3=\$ac_header_compiler" fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } fi eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} } # ac_fn_c_check_header_mongrel # ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES # ------------------------------------------------------- # Tests whether HEADER exists and can be compiled using the include files in # INCLUDES, setting the cache variable VAR accordingly. ac_fn_c_check_header_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval "test \"\${$3+set}\"" = set; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_c_try_compile "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} } # ac_fn_c_check_header_compile # ac_fn_c_check_type LINENO TYPE VAR INCLUDES # ------------------------------------------- # Tests whether TYPE exists after having included INCLUDES, setting cache # variable VAR accordingly. ac_fn_c_check_type () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval "test \"\${$3+set}\"" = set; then : $as_echo_n "(cached) " >&6 else eval "$3=no" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { if (sizeof ($2)) return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { if (sizeof (($2))) return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : else eval "$3=yes" 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 eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} } # ac_fn_c_check_type # ac_fn_c_check_func LINENO FUNC VAR # ---------------------------------- # Tests whether FUNC exists, setting the cache variable VAR accordingly ac_fn_c_check_func () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval "test \"\${$3+set}\"" = set; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Define $2 to an innocuous variant, in case declares $2. For example, HP-UX 11i declares gettimeofday. */ #define $2 innocuous_$2 /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $2 (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $2 /* 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 $2 (); /* 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_$2 || defined __stub___$2 choke me #endif int main () { return $2 (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} } # ac_fn_c_check_func # ac_fn_c_check_member LINENO AGGR MEMBER VAR INCLUDES # ---------------------------------------------------- # Tries to find if the field MEMBER exists in type AGGR, after including # INCLUDES, setting cache variable VAR accordingly. ac_fn_c_check_member () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2.$3" >&5 $as_echo_n "checking for $2.$3... " >&6; } if eval "test \"\${$4+set}\"" = set; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $5 int main () { static $2 ac_aggr; if (ac_aggr.$3) return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : eval "$4=yes" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $5 int main () { static $2 ac_aggr; if (sizeof ac_aggr.$3) return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : eval "$4=yes" else eval "$4=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 eval ac_res=\$$4 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} } # ac_fn_c_check_member 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.6.0, which was generated by GNU Autoconf 2.67. 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=. $as_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=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac case $ac_pass in 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; 2) as_fn_append 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 as_fn_append ac_configure_args " '$ac_arg'" ;; esac done done { ac_configure_args0=; unset ac_configure_args0;} { ac_configure_args1=; unset 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 $as_echo "## ---------------- ## ## Cache variables. ## ## ---------------- ##" 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_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; 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 $as_echo "## ----------------- ## ## Output variables. ## ## ----------------- ##" echo for ac_var in $ac_subst_vars do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo if test -n "$ac_subst_files"; then $as_echo "## ------------------- ## ## File substitutions. ## ## ------------------- ##" echo for ac_var in $ac_subst_files do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo fi if test -s confdefs.h; then $as_echo "## ----------- ## ## confdefs.h. ## ## ----------- ##" echo cat confdefs.h echo fi test "$ac_signal" != 0 && $as_echo "$as_me: caught signal $ac_signal" $as_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'; as_fn_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 $as_echo "/* confdefs.h */" > 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 cat >>confdefs.h <<_ACEOF #define PACKAGE_URL "$PACKAGE_URL" _ACEOF # Let the site file select an alternate cache file if it wants to. # Prefer an explicitly selected file to automatically selected ones. ac_site_file1=NONE ac_site_file2=NONE if test -n "$CONFIG_SITE"; then # We do not want a PATH search for config.site. case $CONFIG_SITE in #(( -*) ac_site_file1=./$CONFIG_SITE;; */*) ac_site_file1=$CONFIG_SITE;; *) ac_site_file1=./$CONFIG_SITE;; esac elif test "x$prefix" != xNONE; then ac_site_file1=$prefix/share/config.site ac_site_file2=$prefix/etc/config.site else ac_site_file1=$ac_default_prefix/share/config.site ac_site_file2=$ac_default_prefix/etc/config.site fi for ac_site_file in "$ac_site_file1" "$ac_site_file2" do test "x$ac_site_file" = xNONE && continue if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 $as_echo "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 . "$ac_site_file" \ || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "failed to load site script $ac_site_file See \`config.log' for more details" "$LINENO" 5 ; } 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. DJGPP emulates it as a regular file. if test /dev/null != "$cache_file" && test -f "$cache_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 $as_echo "$as_me: loading cache $cache_file" >&6;} case $cache_file in [\\/]* | ?:[\\/]* ) . "$cache_file";; *) . "./$cache_file";; esac fi else { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 $as_echo "$as_me: creating cache $cache_file" >&6;} >$cache_file fi as_fn_append ac_header_list " stdlib.h" as_fn_append ac_header_list " unistd.h" as_fn_append ac_header_list " sys/param.h" # 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,) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} ac_cache_corrupted=: ;; ,set) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 $as_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 # differences in whitespace do not lead to failure. ac_old_val_w=`echo x $ac_old_val` ac_new_val_w=`echo x $ac_new_val` if test "$ac_old_val_w" != "$ac_new_val_w"; then { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 $as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} ac_cache_corrupted=: else { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 $as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} eval $ac_var=\$ac_old_val fi { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 $as_echo "$as_me: former value: \`$ac_old_val'" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 $as_echo "$as_me: current value: \`$ac_new_val'" >&2;} fi;; esac # Pass precious variables to config.status. if test "$ac_new_set" = set; then case $ac_new_val in *\'*) ac_arg=$ac_var=`$as_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. *) as_fn_append ac_configure_args " '$ac_arg'" ;; esac fi done if $ac_cache_corrupted; then { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 $as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 fi ## -------------------- ## ## Main body of script. ## ## -------------------- ## 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 # Inherit compiler flags from the environment... CFLAGS="${CFLAGS:=}" CXXFLAGS="${CXXFLAGS:=}" # 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 as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5 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 || as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5 { $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 $as_echo_n "checking build system type... " >&6; } if test "${ac_cv_build+set}" = set; then : $as_echo_n "(cached) " >&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 && as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5 ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 $as_echo "$ac_cv_build" >&6; } case $ac_cv_build in *-*-*) ;; *) as_fn_error $? "invalid value of canonical build" "$LINENO" 5 ;; 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 { $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 $as_echo_n "checking host system type... " >&6; } if test "${ac_cv_host+set}" = set; then : $as_echo_n "(cached) " >&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` || as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5 fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 $as_echo "$ac_cv_host" >&6; } case $ac_cv_host in *-*-*) ;; *) as_fn_error $? "invalid value of canonical host" "$LINENO" 5 ;; 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 { $as_echo "$as_me:${as_lineno-$LINENO}: checking target system type" >&5 $as_echo_n "checking target system type... " >&6; } if test "${ac_cv_target+set}" = set; then : $as_echo_n "(cached) " >&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` || as_fn_error $? "$SHELL $ac_aux_dir/config.sub $target_alias failed" "$LINENO" 5 fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_target" >&5 $as_echo "$ac_cv_target" >&6; } case $ac_cv_target in *-*-*) ;; *) as_fn_error $? "invalid value of canonical target" "$LINENO" 5 ;; 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.11' # 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. # Reject install programs that cannot install multiple files. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 $as_echo_n "checking for a BSD-compatible install... " >&6; } if test -z "$INSTALL"; then if test "${ac_cv_path_install+set}" = set; then : $as_echo_n "(cached) " >&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 rm -rf conftest.one conftest.two conftest.dir echo one > conftest.one echo two > conftest.two mkdir conftest.dir if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && test -s conftest.one && test -s conftest.two && test -s conftest.dir/conftest.one && test -s conftest.dir/conftest.two then ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" break 3 fi fi fi done done ;; esac done IFS=$as_save_IFS rm -rf conftest.one conftest.two conftest.dir 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 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 $as_echo "$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' { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 $as_echo_n "checking whether build environment is sane... " >&6; } # Just in case sleep 1 echo timestamp > conftest.file # Reject unsafe characters in $srcdir or the absolute working directory # name. Accept space and tab only in the latter. am_lf=' ' case `pwd` in *[\\\"\#\$\&\'\`$am_lf]*) as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5 ;; esac case $srcdir in *[\\\"\#\$\&\'\`$am_lf\ \ ]*) as_fn_error $? "unsafe srcdir value: \`$srcdir'" "$LINENO" 5 ;; esac # 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". as_fn_error $? "ls -t appears to fail. Make sure there is not a broken alias in your environment" "$LINENO" 5 fi test "$2" = conftest.file ) then # Ok. : else as_fn_error $? "newly created file is older than distributed files! Check your system clock" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "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 $. # By default was `s,x,x', remove it if useless. ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"` # expand $ac_aux_dir to an absolute path am_aux_dir=`cd $ac_aux_dir && pwd` if test x"${MISSING+set}" != xset; then case $am_aux_dir in *\ * | *\ *) MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; *) MISSING="\${SHELL} $am_aux_dir/missing" ;; esac fi # Use eval to expand $SHELL if eval "$MISSING --run true"; then am_missing_run="$MISSING --run " else am_missing_run= { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`missing' script is too old or missing" >&5 $as_echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;} fi if test x"${install_sh}" != xset; then case $am_aux_dir in *\ * | *\ *) install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; *) install_sh="\${SHELL} $am_aux_dir/install-sh" esac fi # 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 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_STRIP+set}" = set; then : $as_echo_n "(cached) " >&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" $as_echo "$as_me:${as_lineno-$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 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 $as_echo "$STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "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 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then : $as_echo_n "(cached) " >&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" $as_echo "$as_me:${as_lineno-$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 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 $as_echo "$ac_ct_STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_STRIP" = x; then STRIP=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac STRIP=$ac_ct_STRIP fi else STRIP="$ac_cv_prog_STRIP" fi fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5 $as_echo_n "checking for a thread-safe mkdir -p... " >&6; } if test -z "$MKDIR_P"; then if test "${ac_cv_path_mkdir+set}" = set; then : $as_echo_n "(cached) " >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in mkdir gmkdir; do for ac_exec_ext in '' $ac_executable_extensions; do { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; } || continue case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #( 'mkdir (GNU coreutils) '* | \ 'mkdir (coreutils) '* | \ 'mkdir (fileutils) '4.1*) ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext break 3;; esac done done done IFS=$as_save_IFS fi test -d ./--version && rmdir ./--version if test "${ac_cv_path_mkdir+set}" = set; then MKDIR_P="$ac_cv_path_mkdir -p" else # As a last resort, use the slow shell script. Don't cache a # value for MKDIR_P 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. MKDIR_P="$ac_install_sh -d" fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 $as_echo "$MKDIR_P" >&6; } mkdir_p="$MKDIR_P" case $mkdir_p in [\\/$]* | ?:[\\/]*) ;; */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;; esac 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 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_AWK+set}" = set; then : $as_echo_n "(cached) " >&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" $as_echo "$as_me:${as_lineno-$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 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 $as_echo "$AWK" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$AWK" && break done { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 $as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } set x ${MAKE-make} ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` if eval "test \"\${ac_cv_prog_make_${ac_make}_set+set}\"" = set; then : $as_echo_n "(cached) " >&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 { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } SET_MAKE= else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "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 if test "`cd $srcdir && pwd`" != "`pwd`"; then # Use -I$(srcdir) only when $(srcdir) != ., so that make's output # is not polluted with repeated "-I." am__isrc=' -I$(srcdir)' # test to see if srcdir already configured if test -f $srcdir/config.status; then as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5 fi 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.6.0' 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"} # We need awk for the "check" target. The system "awk" is bad on # some platforms. # Always define AMTAR for backward compatibility. AMTAR=${AMTAR-"${am_missing_run}tar"} am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -' ac_config_headers="$ac_config_headers config.h" # AC_CONFIG_HEADER(config.h) # make sure we build netperf_version.h touch ${ac_top_srcdir}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 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_CC+set}" = set; then : $as_echo_n "(cached) " >&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" $as_echo "$as_me:${as_lineno-$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 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "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 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_ac_ct_CC+set}" = set; then : $as_echo_n "(cached) " >&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" $as_echo "$as_me:${as_lineno-$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 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&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 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_CC+set}" = set; then : $as_echo_n "(cached) " >&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" $as_echo "$as_me:${as_lineno-$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 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "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 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_CC+set}" = set; then : $as_echo_n "(cached) " >&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" $as_echo "$as_me:${as_lineno-$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 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "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 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_CC+set}" = set; then : $as_echo_n "(cached) " >&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" $as_echo "$as_me:${as_lineno-$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 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "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 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_ac_ct_CC+set}" = set; then : $as_echo_n "(cached) " >&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" $as_echo "$as_me:${as_lineno-$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 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "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:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi fi fi test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "no acceptable C compiler found in \$PATH See \`config.log' for more details" "$LINENO" 5 ; } # Provide some information about the compiler. $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 set X $ac_compile ac_compiler=$2 for ac_option in --version -v -V -qversion; do { { ac_try="$ac_compiler $ac_option >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compiler $ac_option >&5") 2>conftest.err ac_status=$? if test -s conftest.err; then sed '10a\ ... rest of stderr output deleted ... 10q' conftest.err >conftest.er1 cat conftest.er1 >&5 fi rm -f conftest.er1 conftest.err $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files a.out a.out.dSYM 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. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 $as_echo_n "checking whether the C compiler works... " >&6; } ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` # The possible output files: ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" ac_rmfiles= for ac_file in $ac_files do case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.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 ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link_default") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; 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 | *.dSYM | *.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 if test -z "$ac_file"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "C compiler cannot create executables See \`config.log' for more details" "$LINENO" 5 ; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 $as_echo_n "checking for C compiler default output file name... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 $as_echo "$ac_file" >&6; } ac_exeext=$ac_cv_exeext rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 $as_echo_n "checking for suffix of executables... " >&6; } if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; 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 | *.dSYM | *.o | *.obj ) ;; *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` break;; * ) break;; esac done else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of executables: cannot compile and link See \`config.log' for more details" "$LINENO" 5 ; } fi rm -f conftest conftest$ac_cv_exeext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 $as_echo "$ac_cv_exeext" >&6; } rm -f conftest.$ac_ext EXEEXT=$ac_cv_exeext ac_exeext=$EXEEXT cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { FILE *f = fopen ("conftest.out", "w"); return ferror (f) || fclose (f) != 0; ; return 0; } _ACEOF ac_clean_files="$ac_clean_files conftest.out" # Check that the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 $as_echo_n "checking whether we are cross compiling... " >&6; } if test "$cross_compiling" != yes; then { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if { ac_try='./conftest$ac_cv_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then cross_compiling=no else if test "$cross_compiling" = maybe; then cross_compiling=yes else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run C compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details" "$LINENO" 5 ; } fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 $as_echo "$cross_compiling" >&6; } rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 $as_echo_n "checking for suffix of object files... " >&6; } if test "${ac_cv_objext+set}" = set; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; 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 | *.dSYM ) ;; *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` break;; esac done else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of object files: cannot compile See \`config.log' for more details" "$LINENO" 5 ; } fi rm -f conftest.$ac_cv_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 $as_echo "$ac_cv_objext" >&6; } OBJEXT=$ac_cv_objext ac_objext=$OBJEXT { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 $as_echo_n "checking whether we are using the GNU C compiler... " >&6; } if test "${ac_cv_c_compiler_gnu+set}" = set; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_compiler_gnu=yes else 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 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 $as_echo "$ac_cv_c_compiler_gnu" >&6; } if test $ac_compiler_gnu = yes; then GCC=yes else GCC= fi ac_test_CFLAGS=${CFLAGS+set} ac_save_CFLAGS=$CFLAGS { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 $as_echo_n "checking whether $CC accepts -g... " >&6; } if test "${ac_cv_prog_cc_g+set}" = set; then : $as_echo_n "(cached) " >&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 confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes else CFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : else ac_c_werror_flag=$ac_save_c_werror_flag CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes 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 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 $as_echo "$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 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 $as_echo_n "checking for $CC option to accept ISO C89... " >&6; } if test "${ac_cv_prog_cc_c89+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_cv_prog_cc_c89=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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" if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_c89=$ac_arg 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) { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 $as_echo "none needed" >&6; } ;; xno) { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 $as_echo "unsupported" >&6; } ;; *) CC="$CC $ac_cv_prog_cc_c89" { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 $as_echo "$ac_cv_prog_cc_c89" >&6; } ;; esac if test "x$ac_cv_prog_cc_c89" != xno; then : 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 DEPDIR="${am__leading_dot}deps" ac_config_commands="$ac_config_commands depfiles" am_make=${MAKE-make} cat > confinc << 'END' am__doit: @echo this is the am__doit target .PHONY: am__doit END # If we don't find an include directive, just comment out the code. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5 $as_echo_n "checking for style of include used by $am_make... " >&6; } am__include="#" am__quote= _am_result=none # First try GNU make style include. echo "include confinc" > confmf # Ignore all kinds of additional output from `make'. case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=include am__quote= _am_result=GNU ;; esac # Now try BSD make style include. if test "$am__include" = "#"; then echo '.include "confinc"' > confmf case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=.include am__quote="\"" _am_result=BSD ;; esac fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5 $as_echo "$_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= { $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 $as_echo_n "checking dependency style of $depcc... " >&6; } if test "${am_cv_CC_dependencies_compiler_type+set}" = set; then : $as_echo_n "(cached) " >&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 am__universal=false case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac 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 # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with # Solaris 8's {/usr,}/bin/sh. touch sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf # 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. Also, some Intel # versions had trouble with output in subdirs am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in gcc) # This depmode causes a compiler race in universal mode. test "$am__universal" = false || continue ;; 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 ;; msvisualcpp | msvcmsys) # This compiler won't grok `-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} am__minus_obj= ;; none) break ;; esac if depmode=$depmode \ source=sub/conftest.c object=$am__obj \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep $am__obj 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 # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' 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 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 $as_echo "$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 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_RANLIB+set}" = set; then : $as_echo_n "(cached) " >&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" $as_echo "$as_me:${as_lineno-$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 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 $as_echo "$RANLIB" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "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 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then : $as_echo_n "(cached) " >&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" $as_echo "$as_me:${as_lineno-$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 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 $as_echo "$ac_ct_RANLIB" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_RANLIB" = x; then RANLIB=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac RANLIB=$ac_ct_RANLIB fi else RANLIB="$ac_cv_prog_RANLIB" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for an ANSI C-conforming const" >&5 $as_echo_n "checking for an ANSI C-conforming const... " >&6; } if test "${ac_cv_c_const+set}" = set; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 if ac_fn_c_try_compile "$LINENO"; then : ac_cv_c_const=yes else ac_cv_c_const=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_const" >&5 $as_echo "$ac_cv_c_const" >&6; } if test $ac_cv_c_const = no; then $as_echo "#define const /**/" >>confdefs.h fi # Checks for libraries. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lm" >&5 $as_echo_n "checking for main in -lm... " >&6; } if test "${ac_cv_lib_m_main+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lm $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { return main (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_m_main=yes else ac_cv_lib_m_main=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_main" >&5 $as_echo "$ac_cv_lib_m_main" >&6; } if test "x$ac_cv_lib_m_main" = x""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 { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 $as_echo_n "checking how to run the C preprocessor... " >&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 : $as_echo_n "(cached) " >&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 confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i 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 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 $as_echo "$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 confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details" "$LINENO" 5 ; } 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 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 $as_echo_n "checking for grep that handles long lines and -e... " >&6; } if test "${ac_cv_path_GREP+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -z "$GREP"; then 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 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_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 as_fn_arith $ac_count + 1 && ac_count=$as_val 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 if test -z "$ac_cv_path_GREP"; then as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_GREP=$GREP fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 $as_echo "$ac_cv_path_GREP" >&6; } GREP="$ac_cv_path_GREP" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 $as_echo_n "checking for egrep... " >&6; } if test "${ac_cv_path_EGREP+set}" = set; then : $as_echo_n "(cached) " >&6 else if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 then ac_cv_path_EGREP="$GREP -E" else if test -z "$EGREP"; then 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 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_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 as_fn_arith $ac_count + 1 && ac_count=$as_val 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 if test -z "$ac_cv_path_EGREP"; then as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_EGREP=$EGREP fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 $as_echo "$ac_cv_path_EGREP" >&6; } EGREP="$ac_cv_path_EGREP" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 $as_echo_n "checking for ANSI C header files... " >&6; } if test "${ac_cv_header_stdc+set}" = set; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include #include int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_header_stdc=yes else 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 confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 if ac_fn_c_try_run "$LINENO"; then : else ac_cv_header_stdc=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 $as_echo "$ac_cv_header_stdc" >&6; } if test $ac_cv_header_stdc = yes; then $as_echo "#define STDC_HEADERS 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sys/wait.h that is POSIX.1 compatible" >&5 $as_echo_n "checking for sys/wait.h that is POSIX.1 compatible... " >&6; } if test "${ac_cv_header_sys_wait_h+set}" = set; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 if ac_fn_c_try_compile "$LINENO"; then : ac_cv_header_sys_wait_h=yes else ac_cv_header_sys_wait_h=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_sys_wait_h" >&5 $as_echo "$ac_cv_header_sys_wait_h" >&6; } if test $ac_cv_header_sys_wait_h = yes; then $as_echo "#define HAVE_SYS_WAIT_H 1" >>confdefs.h fi # lets keep this in some semblence of alphabetical order # 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=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default " if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_header in arpa/inet.h endian.h errno.h fcntl.h ifaddrs.h limits.h linux/tcp.h malloc.h netdb.h netinet/in.h netinet/sctp.h signal.h stdlib.h string.h strings.h syscall.h sys/ioctl.h sys/mman.h sys/param.h sys/socket.h sys/stat.h sys/time.h sys/wait.h sys/ipc.h sys/sockio.h sys/sysinfo.h sys/wait.h stdlib.h unistd.h netinet/in_systm.h netinet/ip.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done # Some platforms require these. There may be a better way. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lsocket" >&5 $as_echo_n "checking for main in -lsocket... " >&6; } if test "${ac_cv_lib_socket_main+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lsocket $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { return main (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_socket_main=yes else ac_cv_lib_socket_main=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_socket_main" >&5 $as_echo "$ac_cv_lib_socket_main" >&6; } if test "x$ac_cv_lib_socket_main" = x""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 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lnsl" >&5 $as_echo_n "checking for main in -lnsl... " >&6; } if test "${ac_cv_lib_nsl_main+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lnsl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { return main (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_nsl_main=yes else ac_cv_lib_nsl_main=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_nsl_main" >&5 $as_echo "$ac_cv_lib_nsl_main" >&6; } if test "x$ac_cv_lib_nsl_main" = x""yes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBNSL 1 _ACEOF LIBS="-lnsl $LIBS" fi ac_cv_lib_nsl=ac_cv_lib_nsl_main { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lsendfile" >&5 $as_echo_n "checking for main in -lsendfile... " >&6; } if test "${ac_cv_lib_sendfile_main+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lsendfile $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { return main (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_sendfile_main=yes else ac_cv_lib_sendfile_main=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_sendfile_main" >&5 $as_echo "$ac_cv_lib_sendfile_main" >&6; } if test "x$ac_cv_lib_sendfile_main" = x""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 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for special C compiler options needed for large files" >&5 $as_echo_n "checking for special C compiler options needed for large files... " >&6; } if test "${ac_cv_sys_largefile_CC+set}" = set; then : $as_echo_n "(cached) " >&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 confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 if ac_fn_c_try_compile "$LINENO"; then : break fi rm -f core conftest.err conftest.$ac_objext CC="$CC -n32" if ac_fn_c_try_compile "$LINENO"; then : ac_cv_sys_largefile_CC=' -n32'; break fi rm -f core conftest.err conftest.$ac_objext break done CC=$ac_save_CC rm -f conftest.$ac_ext fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_largefile_CC" >&5 $as_echo "$ac_cv_sys_largefile_CC" >&6; } if test "$ac_cv_sys_largefile_CC" != no; then CC=$CC$ac_cv_sys_largefile_CC fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _FILE_OFFSET_BITS value needed for large files" >&5 $as_echo_n "checking for _FILE_OFFSET_BITS value needed for large files... " >&6; } if test "${ac_cv_sys_file_offset_bits+set}" = set; then : $as_echo_n "(cached) " >&6 else while :; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 if ac_fn_c_try_compile "$LINENO"; then : ac_cv_sys_file_offset_bits=no; break fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 if ac_fn_c_try_compile "$LINENO"; then : ac_cv_sys_file_offset_bits=64; break fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_sys_file_offset_bits=unknown break done fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_file_offset_bits" >&5 $as_echo "$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 -rf conftest* if test $ac_cv_sys_file_offset_bits = unknown; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _LARGE_FILES value needed for large files" >&5 $as_echo_n "checking for _LARGE_FILES value needed for large files... " >&6; } if test "${ac_cv_sys_large_files+set}" = set; then : $as_echo_n "(cached) " >&6 else while :; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 if ac_fn_c_try_compile "$LINENO"; then : ac_cv_sys_large_files=no; break fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 if ac_fn_c_try_compile "$LINENO"; then : ac_cv_sys_large_files=1; break fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_sys_large_files=unknown break done fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_large_files" >&5 $as_echo "$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 -rf conftest* fi fi fi # this one is for Tru64 and bind_to_cpu_id { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lmach" >&5 $as_echo_n "checking for main in -lmach... " >&6; } if test "${ac_cv_lib_mach_main+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lmach $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { return main (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_mach_main=yes else ac_cv_lib_mach_main=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_mach_main" >&5 $as_echo "$ac_cv_lib_mach_main" >&6; } if test "x$ac_cv_lib_mach_main" = x""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. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for an ANSI C-conforming const" >&5 $as_echo_n "checking for an ANSI C-conforming const... " >&6; } if test "${ac_cv_c_const+set}" = set; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 if ac_fn_c_try_compile "$LINENO"; then : ac_cv_c_const=yes else ac_cv_c_const=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_const" >&5 $as_echo "$ac_cv_c_const" >&6; } if test $ac_cv_c_const = no; then $as_echo "#define const /**/" >>confdefs.h fi ac_fn_c_check_type "$LINENO" "off_t" "ac_cv_type_off_t" "$ac_includes_default" if test "x$ac_cv_type_off_t" = x""yes; then : else cat >>confdefs.h <<_ACEOF #define off_t long int _ACEOF fi ac_fn_c_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default" if test "x$ac_cv_type_size_t" = x""yes; then : else cat >>confdefs.h <<_ACEOF #define size_t unsigned int _ACEOF fi # AC_TYPE_SOCKLEN_T { $as_echo "$as_me:${as_lineno-$LINENO}: checking for socklen_t equivalent" >&5 $as_echo_n "checking for socklen_t equivalent... " >&6; } if test "${curl_cv_socklen_t_equiv+set}" = set; then : $as_echo_n "(cached) " >&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 confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 if ac_fn_c_try_compile "$LINENO"; then : curl_cv_socklen_t_equiv="$t" break 2 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" { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Cannot find a type to use in place of socklen_t, guessing socklen_t" >&5 $as_echo "$as_me: WARNING: Cannot find a type to use in place of socklen_t, guessing socklen_t" >&2;} fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $curl_cv_socklen_t_equiv" >&5 $as_echo "$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 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for h_errno declaration in netdb.h" >&5 $as_echo_n "checking for h_errno declaration in netdb.h... " >&6; } if test "${ac_cv_decl_h_errno+set}" = set; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { h_errno = 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_decl_h_errno=yes else ac_cv_decl_h_errno=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_decl_h_errno" >&5 $as_echo "$ac_cv_decl_h_errno" >&6; } if test "$ac_cv_decl_h_errno" = yes; then $as_echo "#define H_ERRNO_DECLARED 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for struct sockaddr_storage" >&5 $as_echo_n "checking for struct sockaddr_storage... " >&6; } if test "${ac_cv_struct_sockaddr_storage+set}" = set; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include int main () { struct sockaddr_storage address; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_struct_sockaddr_storage=yes else ac_cv_struct_sockaddr_storage=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_struct_sockaddr_storage" >&5 $as_echo "$ac_cv_struct_sockaddr_storage" >&6; } if test "$ac_cv_struct_sockaddr_storage" = yes; then $as_echo "#define HAVE_STRUCT_SOCKADDR_STORAGE 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether time.h and sys/time.h may both be included" >&5 $as_echo_n "checking whether time.h and sys/time.h may both be included... " >&6; } if test "${ac_cv_header_time+set}" = set; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include int main () { if ((struct tm *) 0) return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_header_time=yes else ac_cv_header_time=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_time" >&5 $as_echo "$ac_cv_header_time" >&6; } if test $ac_cv_header_time = yes; then $as_echo "#define TIME_WITH_SYS_TIME 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdbool.h that conforms to C99" >&5 $as_echo_n "checking for stdbool.h that conforms to C99... " >&6; } if test "${ac_cv_header_stdbool_h+set}" = set; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 }; /* The following fails for HP aC++/ANSI C B3910B A.05.55 [Dec 04 2003]. */ _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 if ac_fn_c_try_compile "$LINENO"; then : ac_cv_header_stdbool_h=yes else ac_cv_header_stdbool_h=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdbool_h" >&5 $as_echo "$ac_cv_header_stdbool_h" >&6; } ac_fn_c_check_type "$LINENO" "_Bool" "ac_cv_type__Bool" "$ac_includes_default" if test "x$ac_cv_type__Bool" = x""yes; then : cat >>confdefs.h <<_ACEOF #define HAVE__BOOL 1 _ACEOF fi if test $ac_cv_header_stdbool_h = yes; then $as_echo "#define HAVE_STDBOOL_H 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking if sockaddr struct has sa_len member" >&5 $as_echo_n "checking if sockaddr struct has sa_len member... " >&6; } if test "${ac_cv_sockaddr_has_sa_len+set}" = set; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ # include # include int main () { u_int i = sizeof(((struct sockaddr *)0)->sa_len) ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_sockaddr_has_sa_len=yes else ac_cv_sockaddr_has_sa_len=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sockaddr_has_sa_len" >&5 $as_echo "$ac_cv_sockaddr_has_sa_len" >&6; } if test $ac_cv_sockaddr_has_sa_len = yes ; then $as_echo "#define HAVE_SOCKADDR_SA_LEN 1" >>confdefs.h fi # Checks for library functions. # AC_FUNC_ERROR_AT_LINE ac_fn_c_check_type "$LINENO" "pid_t" "ac_cv_type_pid_t" "$ac_includes_default" if test "x$ac_cv_type_pid_t" = x""yes; then : else cat >>confdefs.h <<_ACEOF #define pid_t int _ACEOF fi for ac_header in vfork.h do : ac_fn_c_check_header_mongrel "$LINENO" "vfork.h" "ac_cv_header_vfork_h" "$ac_includes_default" if test "x$ac_cv_header_vfork_h" = x""yes; then : cat >>confdefs.h <<_ACEOF #define HAVE_VFORK_H 1 _ACEOF fi done for ac_func in fork vfork do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done if test "x$ac_cv_func_fork" = xyes; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for working fork" >&5 $as_echo_n "checking for working fork... " >&6; } if test "${ac_cv_func_fork_works+set}" = set; then : $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then : ac_cv_func_fork_works=cross else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_includes_default int main () { /* By Ruediger Kuhlmann. */ return fork () < 0; ; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : ac_cv_func_fork_works=yes else ac_cv_func_fork_works=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_fork_works" >&5 $as_echo "$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 { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: result $ac_cv_func_fork_works guessed because of cross compilation" >&5 $as_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 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for working vfork" >&5 $as_echo_n "checking for working vfork... " >&6; } if test "${ac_cv_func_vfork_works+set}" = set; then : $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then : ac_cv_func_vfork_works=cross else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 if ac_fn_c_try_run "$LINENO"; then : ac_cv_func_vfork_works=yes else ac_cv_func_vfork_works=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_vfork_works" >&5 $as_echo "$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 { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: result $ac_cv_func_vfork_works guessed because of cross compilation" >&5 $as_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 $as_echo "#define HAVE_WORKING_VFORK 1" >>confdefs.h else $as_echo "#define vfork fork" >>confdefs.h fi if test "x$ac_cv_func_fork_works" = xyes; then $as_echo "#define HAVE_WORKING_FORK 1" >>confdefs.h fi # AC_FUNC_MALLOC for ac_header in $ac_header_list do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default " if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_func in getpagesize do : ac_fn_c_check_func "$LINENO" "getpagesize" "ac_cv_func_getpagesize" if test "x$ac_cv_func_getpagesize" = x""yes; then : cat >>confdefs.h <<_ACEOF #define HAVE_GETPAGESIZE 1 _ACEOF fi done { $as_echo "$as_me:${as_lineno-$LINENO}: checking for working mmap" >&5 $as_echo_n "checking for working mmap... " >&6; } if test "${ac_cv_func_mmap_fixed_mapped+set}" = set; then : $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then : ac_cv_func_mmap_fixed_mapped=no else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 # 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; const char *cdata2; int i, pagesize; int fd, fd2; 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 2; if (write (fd, data, pagesize) != pagesize) return 3; close (fd); /* Next, check that the tail of a page is zero-filled. File must have non-zero length, otherwise we risk SIGBUS for entire page. */ fd2 = open ("conftest.txt", O_RDWR | O_CREAT | O_TRUNC, 0600); if (fd2 < 0) return 4; cdata2 = ""; if (write (fd2, cdata2, 1) != 1) return 5; data2 = (char *) mmap (0, pagesize, PROT_READ | PROT_WRITE, MAP_SHARED, fd2, 0L); if (data2 == MAP_FAILED) return 6; for (i = 0; i < pagesize; ++i) if (*(data2 + i)) return 7; close (fd2); if (munmap (data2, pagesize)) return 8; /* 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 9; if (data2 != mmap (data2, pagesize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_FIXED, fd, 0L)) return 10; for (i = 0; i < pagesize; ++i) if (*(data + i) != *(data2 + i)) return 11; /* 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 12; if (read (fd, data3, pagesize) != pagesize) return 13; for (i = 0; i < pagesize; ++i) if (*(data + i) != *(data3 + i)) return 14; close (fd); return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : ac_cv_func_mmap_fixed_mapped=yes else 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.beam conftest.$ac_ext fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_mmap_fixed_mapped" >&5 $as_echo "$ac_cv_func_mmap_fixed_mapped" >&6; } if test $ac_cv_func_mmap_fixed_mapped = yes; then $as_echo "#define HAVE_MMAP 1" >>confdefs.h fi rm -f conftest.mmap conftest.txt for ac_header in sys/select.h sys/socket.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done { $as_echo "$as_me:${as_lineno-$LINENO}: checking types of arguments for select" >&5 $as_echo_n "checking types of arguments for select... " >&6; } if test "${ac_cv_func_select_args+set}" = set; then : $as_echo_n "(cached) " >&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 confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 if ac_fn_c_try_compile "$LINENO"; then : ac_cv_func_select_args="$ac_arg1,$ac_arg234,$ac_arg5"; break 3 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 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_select_args" >&5 $as_echo "$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* { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether setpgrp takes no argument" >&5 $as_echo_n "checking whether setpgrp takes no argument... " >&6; } if test "${ac_cv_func_setpgrp_void+set}" = set; then : $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then : as_fn_error $? "cannot check setpgrp when cross compiling" "$LINENO" 5 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 if ac_fn_c_try_run "$LINENO"; then : ac_cv_func_setpgrp_void=no else ac_cv_func_setpgrp_void=yes fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_setpgrp_void" >&5 $as_echo "$ac_cv_func_setpgrp_void" >&6; } if test $ac_cv_func_setpgrp_void = yes; then $as_echo "#define SETPGRP_VOID 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking return type of signal handlers" >&5 $as_echo_n "checking return type of signal handlers... " >&6; } if test "${ac_cv_type_signal+set}" = set; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { return *(signal (0, 0)) (0) == 1; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_type_signal=int else ac_cv_type_signal=void fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_signal" >&5 $as_echo "$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 daemon gethostbyname gethrtime gettimeofday inet_ntoa memset memcpy munmap select setsid socket sqrt strcasecmp strchr strstr strtoul uname toupper do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_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=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_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 { $as_echo "$as_me:${as_lineno-$LINENO}: Requesting replacement getaddrinfo/getnameinfo" >&5 $as_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 { $as_echo "$as_me:${as_lineno-$LINENO}: Requesting replacement inet_ntop" >&5 $as_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 : ac_fn_c_check_func "$LINENO" "sendfile" "ac_cv_func_sendfile" if test "x$ac_cv_func_sendfile" = x""yes; then : cat >>confdefs.h <<_ACEOF #define HAVE_SENDFILE 1 _ACEOF fi done for ac_func in uname do : ac_fn_c_check_func "$LINENO" "uname" "ac_cv_func_uname" if test "x$ac_cv_func_uname" = x""yes; then : cat >>confdefs.h <<_ACEOF #define HAVE_UNAME 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=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done # see if we should be enabling histogram support { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to include histogram support" >&5 $as_echo_n "checking whether to include histogram support... " >&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 ;; *) as_fn_error $? "--enable-histogram takes yes or no" "$LINENO" 5 ;; esac if $use_histogram then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if $use_histogram then $as_echo "#define WANT_HISTOGRAM /**/" >>confdefs.h fi # see if we should be enabling histogram support { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to include dirty support" >&5 $as_echo_n "checking whether to include dirty support... " >&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 ;; *) as_fn_error $? "--enable-dirty takes yes or no" "$LINENO" 5 ;; esac if $use_dirty then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if $use_dirty then $as_echo "#define DIRTY /**/" >>confdefs.h fi # see if we should be enabling demo support { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to include demo support" >&5 $as_echo_n "checking whether to include demo support... " >&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 ;; *) as_fn_error $? "--enable-demo takes yes or no" "$LINENO" 5 ;; esac if $use_demo then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if $use_demo then $as_echo "#define WANT_DEMO /**/" >>confdefs.h fi # see if we should be including the AF_UNIX tests { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to include Unix-domain socket tests" >&5 $as_echo_n "checking whether to include Unix-domain socket tests... " >&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 ;; *) as_fn_error $? "--enable-unixdomain takes yes or no" "$LINENO" 5 ;; esac if $use_unixdomain then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if $use_unixdomain then $as_echo "#define WANT_UNIX /**/" >>confdefs.h fi # see if we should be including the DLPI tests { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to include DLPI tests" >&5 $as_echo_n "checking whether to include DLPI tests... " >&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 ;; *) as_fn_error $? "--enable-dlpi takes yes or no" "$LINENO" 5 ;; esac if $use_dlpi then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if $use_dlpi then $as_echo "#define WANT_DLPI /**/" >>confdefs.h fi # see if we should be including the DCCP tests { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to include DCCP tests" >&5 $as_echo_n "checking whether to include DCCP tests... " >&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 ;; *) as_fn_error $? "--enable-dccp takes yes or no" "$LINENO" 5 ;; esac if $use_dccp then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if $use_dccp then $as_echo "#define WANT_DCCP /**/" >>confdefs.h fi # see if we should be including the OMNI tests { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to include OMNI tests" >&5 $as_echo_n "checking whether to include OMNI tests... " >&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=true ;; *) as_fn_error $? "--enable-omni takes yes or no" "$LINENO" 5 ;; esac if $use_omni then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if $use_omni then $as_echo "#define WANT_OMNI /**/" >>confdefs.h $as_echo "#define WANT_MIGRATION /**/" >>confdefs.h fi # see if we should be including the XTI tests { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to include XTI tests" >&5 $as_echo_n "checking whether to include XTI tests... " >&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 ;; *) as_fn_error $? "--enable-xti takes yes or no" "$LINENO" 5 ;; esac if $use_xti then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if $use_xti then $as_echo "#define WANT_XTI /**/" >>confdefs.h fi # see if we should be including the SDP tests { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to include SDP tests" >&5 $as_echo_n "checking whether to include SDP tests... " >&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 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for t_open in -lsdp" >&5 $as_echo_n "checking for t_open in -lsdp... " >&6; } if test "${ac_cv_lib_sdp_t_open+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lsdp $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_sdp_t_open=yes else ac_cv_lib_sdp_t_open=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_sdp_t_open" >&5 $as_echo "$ac_cv_lib_sdp_t_open" >&6; } if test "x$ac_cv_lib_sdp_t_open" = x""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 ;; *) as_fn_error $? "--enable-sdp takes yes or no" "$LINENO" 5 ;; esac if $use_sdp then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if $use_sdp then $as_echo "#define WANT_SDP /**/" >>confdefs.h fi # see if we should be including the ICSC-EXS tests { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to include ICSC-EXS tests" >&5 $as_echo_n "checking whether to include ICSC-EXS tests... " >&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 ac_fn_c_check_header_mongrel "$LINENO" "sys/exs.h" "ac_cv_header_sys_exs_h" "$ac_includes_default" if test "x$ac_cv_header_sys_exs_h" = x""yes; then : else use_exs=false fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for exs_init in -lexs" >&5 $as_echo_n "checking for exs_init in -lexs... " >&6; } if test "${ac_cv_lib_exs_exs_init+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lexs $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_exs_exs_init=yes else ac_cv_lib_exs_exs_init=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_exs_exs_init" >&5 $as_echo "$ac_cv_lib_exs_exs_init" >&6; } if test "x$ac_cv_lib_exs_exs_init" = x""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 ;; *) as_fn_error $? "--enable-exs takes yes or no" "$LINENO" 5 ;; esac if $use_exs then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if $use_exs then $as_echo "#define HAVE_ICSC_EXS /**/" >>confdefs.h 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 : ac_fn_c_check_header_compile "$LINENO" "netinet/sctp.h" "ac_cv_header_netinet_sctp_h" " #include " if test "x$ac_cv_header_netinet_sctp_h" = x""yes; then : cat >>confdefs.h <<_ACEOF #define HAVE_NETINET_SCTP_H 1 _ACEOF else use_sctp=false fi done case "$host" in *-*-freebsd78.*) # FreeBSD 7.x and later SCTP support doesn't need -lsctp. ;; *) { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lsctp" >&5 $as_echo_n "checking for main in -lsctp... " >&6; } if test "${ac_cv_lib_sctp_main+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lsctp $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { return main (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_sctp_main=yes else ac_cv_lib_sctp_main=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_sctp_main" >&5 $as_echo "$ac_cv_lib_sctp_main" >&6; } if test "x$ac_cv_lib_sctp_main" = x""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 ac_fn_c_check_member "$LINENO" "struct sctp_event_subscribe" "sctp_adaptation_layer_event" "ac_cv_member_struct_sctp_event_subscribe_sctp_adaptation_layer_event" "#include " if test "x$ac_cv_member_struct_sctp_event_subscribe_sctp_adaptation_layer_event" = x""yes; then : fi if test "$ac_cv_member_struct_sctp_event_subscribe_sctp_adaptation_layer_event" = "yes"; then $as_echo "#define HAVE_SCTP_ADAPTATION_LAYER_EVENT 1" >>confdefs.h fi ;; no) use_sctp=false ;; '') # whatever use_sctp=false ;; *) as_fn_error $? "--enable-sctp takes yes or no" "$LINENO" 5 ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to include SCTP tests" >&5 $as_echo_n "checking whether to include SCTP tests... " >&6; } if $use_sctp then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if $use_sctp then $as_echo "#define WANT_SCTP /**/" >>confdefs.h fi # see if we should be enabling paced sends { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to include paced send (intervals) support" >&5 $as_echo_n "checking whether to include paced send (intervals) support... " >&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 ;; *) as_fn_error $? "--enable-intervals takes yes or no" "$LINENO" 5 ;; esac if $use_intervals then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if $use_intervals then $as_echo "#define WANT_INTERVALS /**/" >>confdefs.h fi # see if paced sends should wait and spin { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether paced sends should spin" >&5 $as_echo_n "checking whether paced sends should spin... " >&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 ;; *) as_fn_error $? "--enable-spin takes yes or no" "$LINENO" 5 ;; esac if $use_spin then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if $use_spin then $as_echo "#define WANT_INTERVALS /**/" >>confdefs.h $as_echo "#define WANT_SPIN /**/" >>confdefs.h fi # see if we should be enabling initial request bursts { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to include initial burst support in _RR tests" >&5 $as_echo_n "checking whether to include initial burst support in _RR tests... " >&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=true ;; *) as_fn_error $? "--enable-burst takes yes or no" "$LINENO" 5 ;; esac if $use_burst then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if $use_burst then $as_echo "#define WANT_FIRST_BURST /**/" >>confdefs.h fi # time to see about CPU utilization measurements { $as_echo "$as_me:${as_lineno-$LINENO}: checking which CPU utilization measurement type to use" >&5 $as_echo_n "checking which CPU utilization measurement type to use... " >&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 $as_echo "#define USE_PSTAT /**/" >>confdefs.h ;; pstatnew) use_cpuutil=true $as_echo "#define USE_PSTAT /**/" >>confdefs.h ;; perfstat) use_cpuutil=true $as_echo "#define USE_PERFSTAT /**/" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lperfstat" >&5 $as_echo_n "checking for main in -lperfstat... " >&6; } if test "${ac_cv_lib_perfstat_main+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lperfstat $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { return main (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_perfstat_main=yes else ac_cv_lib_perfstat_main=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_perfstat_main" >&5 $as_echo "$ac_cv_lib_perfstat_main" >&6; } if test "x$ac_cv_lib_perfstat_main" = x""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 $as_echo "#define USE_LOOPER /**/" >>confdefs.h ;; procstat) use_cpuutil=true $as_echo "#define USE_PROC_STAT /**/" >>confdefs.h ;; kstat) use_cpuutil=true $as_echo "#define USE_KSTAT /**/" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lkstat" >&5 $as_echo_n "checking for main in -lkstat... " >&6; } if test "${ac_cv_lib_kstat_main+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lkstat $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { return main (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_kstat_main=yes else ac_cv_lib_kstat_main=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_kstat_main" >&5 $as_echo "$ac_cv_lib_kstat_main" >&6; } if test "x$ac_cv_lib_kstat_main" = x""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 $as_echo "#define USE_KSTAT /**/" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lkstat" >&5 $as_echo_n "checking for main in -lkstat... " >&6; } if test "${ac_cv_lib_kstat_main+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lkstat $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { return main (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_kstat_main=yes else ac_cv_lib_kstat_main=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_kstat_main" >&5 $as_echo "$ac_cv_lib_kstat_main" >&6; } if test "x$ac_cv_lib_kstat_main" = x""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 $as_echo "#define USE_OSX /**/" >>confdefs.h ;; '') # ia64-hp-hpux11.23 # i386-pc-solaris2.10 # guess it automagically in a nice big case statement case $target in *-*-linux*) use_cpuutil=true $as_echo "#define USE_PROC_STAT /**/" >>confdefs.h enable_cpuutil="procstat - auto" NETCPU_SOURCE="procstat" ;; *-*-hpux11.23 | *-*-hpux11.31) use_cpuutil=true $as_echo "#define USE_PSTAT /**/" >>confdefs.h enable_cpuutil="pstatnew - auto" NETCPU_SOURCE="pstatnew" ;; *-*-hpux11* | *-*-hpux10*) use_cpuutil=true $as_echo "#define USE_PSTAT /**/" >>confdefs.h enable_cpuutil="pstat - auto" NETCPU_SOURCE="pstat" ;; *-*-aix5.* | *-*-aix6.*) use_puutil=true $as_echo "#define USE_PERFSTAT /**/" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lperfstat" >&5 $as_echo_n "checking for main in -lperfstat... " >&6; } if test "${ac_cv_lib_perfstat_main+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lperfstat $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { return main (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_perfstat_main=yes else ac_cv_lib_perfstat_main=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_perfstat_main" >&5 $as_echo "$ac_cv_lib_perfstat_main" >&6; } if test "x$ac_cv_lib_perfstat_main" = x""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 $as_echo "#define USE_KSTAT /**/" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lkstat" >&5 $as_echo_n "checking for main in -lkstat... " >&6; } if test "${ac_cv_lib_kstat_main+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lkstat $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { return main (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_kstat_main=yes else ac_cv_lib_kstat_main=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_kstat_main" >&5 $as_echo "$ac_cv_lib_kstat_main" >&6; } if test "x$ac_cv_lib_kstat_main" = x""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 $as_echo "#define USE_KSTAT /**/" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lkstat" >&5 $as_echo_n "checking for main in -lkstat... " >&6; } if test "${ac_cv_lib_kstat_main+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lkstat $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { return main (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_kstat_main=yes else ac_cv_lib_kstat_main=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_kstat_main" >&5 $as_echo "$ac_cv_lib_kstat_main" >&6; } if test "x$ac_cv_lib_kstat_main" = x""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-8].* | *-*-netbsd[1-9].* ) use_cpuutil=true $as_echo "#define USE_SYSCTL /**/" >>confdefs.h enable_cpuutil="sysctl - auto" NETCPU_SOURCE="sysctl" ;; *-*-darwin*) use_cpuutil=true $as_echo "#define USE_OSX /**/" >>confdefs.h 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 ;; *) as_fn_error $? "--enable-cpuutil takes kstat, kstat10, looper, osx, perfstat, procstat, pstat, pstatnew, sysctl or none" "$LINENO" 5 ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: \"$enable_cpuutil\"" >&5 $as_echo "\"$enable_cpuutil\"" >&6; } # time to see about route lookup mechanisms { $as_echo "$as_me:${as_lineno-$LINENO}: checking which route lookup type to use" >&5 $as_echo_n "checking which route lookup type to use... " >&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-8].* | *-*-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 ;; *) as_fn_error $? "--enable-rtlookup takes rtmget, rtnetlink or none" "$LINENO" 5 ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: \"$enable_rtlookup\"" >&5 $as_echo "\"$enable_rtlookup\"" >&6; } # time to see about slot lookup mechanisms { $as_echo "$as_me:${as_lineno-$LINENO}: checking which slot lookup type to use" >&5 $as_echo_n "checking which slot lookup type to use... " >&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 ;; hpux) 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" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -ldevinfo" >&5 $as_echo_n "checking for main in -ldevinfo... " >&6; } if test "${ac_cv_lib_devinfo_main+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldevinfo $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { return main (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_devinfo_main=yes else ac_cv_lib_devinfo_main=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_devinfo_main" >&5 $as_echo "$ac_cv_lib_devinfo_main" >&6; } if test "x$ac_cv_lib_devinfo_main" = x""yes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBDEVINFO 1 _ACEOF LIBS="-ldevinfo $LIBS" fi ac_cv_lib_devinfo=ac_cv_lib_devinfo_main ;; *-*-hpux11.31*) use_slotlookup=true enable_slotlookup="hpux 11.31 - auto" NETSLOTLKUP_SOURCE="ux1131" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lIO" >&5 $as_echo_n "checking for main in -lIO... " >&6; } if test "${ac_cv_lib_IO_main+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lIO $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { return main (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_IO_main=yes else ac_cv_lib_IO_main=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_IO_main" >&5 $as_echo "$ac_cv_lib_IO_main" >&6; } if test "x$ac_cv_lib_IO_main" = x""yes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBIO 1 _ACEOF LIBS="-lIO $LIBS" fi ac_cv_lib_IO=ac_cv_lib_IO_main { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lolrad" >&5 $as_echo_n "checking for main in -lolrad... " >&6; } if test "${ac_cv_lib_olrad_main+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lolrad $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { return main (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_olrad_main=yes else ac_cv_lib_olrad_main=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_olrad_main" >&5 $as_echo "$ac_cv_lib_olrad_main" >&6; } if test "x$ac_cv_lib_olrad_main" = x""yes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBOLRAD 1 _ACEOF LIBS="-lolrad $LIBS" fi ac_cv_lib_olrad=ac_cv_lib_olrad_main ;; *) use_slotlookup=false NETSLOTLKUP_SOURCE="none" enable_slotlookup="none. Consider teaching configure about your platform." ;; esac ;; none) use_slotlookup=false ;; *) as_fn_error $? "--enable-slotlookup takes linux or none" "$LINENO" 5 ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: \"$enable_slotlookup\"" >&5 $as_echo "\"$enable_slotlookup\"" >&6; } # time to see about sec lookup mechanisms { $as_echo "$as_me:${as_lineno-$LINENO}: checking which sec lookup type to use" >&5 $as_echo_n "checking which sec lookup type to use... " >&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*) { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -ldl" >&5 $as_echo_n "checking for main in -ldl... " >&6; } if test "${ac_cv_lib_dl_main+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { return main (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dl_main=yes else ac_cv_lib_dl_main=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_main" >&5 $as_echo "$ac_cv_lib_dl_main" >&6; } if test "x$ac_cv_lib_dl_main" = x""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 ;; *) as_fn_error $? "--enable-seclookup takes linux or none" "$LINENO" 5 ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: \"$enable_seclookup\"" >&5 $as_echo "\"$enable_seclookup\"" >&6; } # time to see about driver lookup mechanisms { $as_echo "$as_me:${as_lineno-$LINENO}: checking which driver info lookup type to use" >&5 $as_echo_n "checking which driver info lookup type to use... " >&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 ;; *) as_fn_error $? "--enable-drvlookup takes ethtool or none" "$LINENO" 5 ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: \"$enable_drvlookup\"" >&5 $as_echo "\"$enable_drvlookup\"" >&6; } # time to see about system lookup mechanisms { $as_echo "$as_me:${as_lineno-$LINENO}: checking which system info lookup type to use" >&5 $as_echo_n "checking which system info lookup type to use... " >&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 : ac_fn_c_check_header_mongrel "$LINENO" "smbios/SystemInfo.h" "ac_cv_header_smbios_SystemInfo_h" "$ac_includes_default" if test "x$ac_cv_header_smbios_SystemInfo_h" = x""yes; then : cat >>confdefs.h <<_ACEOF #define HAVE_SMBIOS_SYSTEMINFO_H 1 _ACEOF fi done { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lsmbios" >&5 $as_echo_n "checking for main in -lsmbios... " >&6; } if test "${ac_cv_lib_smbios_main+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lsmbios $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { return main (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_smbios_main=yes else ac_cv_lib_smbios_main=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_smbios_main" >&5 $as_echo "$ac_cv_lib_smbios_main" >&6; } if test "x$ac_cv_lib_smbios_main" = x""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 : ac_fn_c_check_header_mongrel "$LINENO" "sys/sbmios.h" "ac_cv_header_sys_sbmios_h" "$ac_includes_default" if test "x$ac_cv_header_sys_sbmios_h" = x""yes; then : cat >>confdefs.h <<_ACEOF #define HAVE_SYS_SBMIOS_H 1 _ACEOF fi done { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lsmbios" >&5 $as_echo_n "checking for main in -lsmbios... " >&6; } if test "${ac_cv_lib_smbios_main+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lsmbios $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { return main (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_smbios_main=yes else ac_cv_lib_smbios_main=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_smbios_main" >&5 $as_echo "$ac_cv_lib_smbios_main" >&6; } if test "x$ac_cv_lib_smbios_main" = x""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 : ac_fn_c_check_header_mongrel "$LINENO" "smbios/SystemInfo.h" "ac_cv_header_smbios_SystemInfo_h" "$ac_includes_default" if test "x$ac_cv_header_smbios_SystemInfo_h" = x""yes; then : cat >>confdefs.h <<_ACEOF #define HAVE_SMBIOS_SYSTEMINFO_H 1 _ACEOF fi done { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lsmbios" >&5 $as_echo_n "checking for main in -lsmbios... " >&6; } if test "${ac_cv_lib_smbios_main+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lsmbios $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { return main (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_smbios_main=yes else ac_cv_lib_smbios_main=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_smbios_main" >&5 $as_echo "$ac_cv_lib_smbios_main" >&6; } if test "x$ac_cv_lib_smbios_main" = x""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 : ac_fn_c_check_header_mongrel "$LINENO" "sys/smbios.h" "ac_cv_header_sys_smbios_h" "$ac_includes_default" if test "x$ac_cv_header_sys_smbios_h" = x""yes; then : cat >>confdefs.h <<_ACEOF #define HAVE_SYS_SMBIOS_H 1 _ACEOF fi done { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lsmbios" >&5 $as_echo_n "checking for main in -lsmbios... " >&6; } if test "${ac_cv_lib_smbios_main+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lsmbios $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { return main (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_smbios_main=yes else ac_cv_lib_smbios_main=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_smbios_main" >&5 $as_echo "$ac_cv_lib_smbios_main" >&6; } if test "x$ac_cv_lib_smbios_main" = x""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 ;; *) as_fn_error $? "--enable-syslookup takes hpux11i, linux or none" "$LINENO" 5 ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: \"$enable_syslookup\"" >&5 $as_echo "\"$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_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; 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" && { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 $as_echo "$as_me: updating cache $cache_file" >&6;} cat confcache >$cache_file else { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 $as_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= U= 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=`$as_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. as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' done LIBOBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs if test -n "$EXEEXT"; then am__EXEEXT_TRUE= am__EXEEXT_FALSE='#' else am__EXEEXT_TRUE='#' am__EXEEXT_FALSE= fi if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then as_fn_error $? "conditional \"AMDEP\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then as_fn_error $? "conditional \"am__fastdepCC\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${NEED_LIBCOMPAT_TRUE}" && test -z "${NEED_LIBCOMPAT_FALSE}"; then as_fn_error $? "conditional \"NEED_LIBCOMPAT\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi : ${CONFIG_STATUS=./config.status} ac_write_fail=0 ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files $CONFIG_STATUS" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 $as_echo "$as_me: creating $CONFIG_STATUS" >&6;} as_write_fail=0 cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 #! $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} export SHELL _ASEOF cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 ## -------------------- ## ## 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=: # Pre-4.2 versions of Zsh do 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_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } 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.) 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 $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith 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 if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # 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 ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac 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 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then 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 else as_ln_s='cp -p' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_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 || $as_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" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' 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 ## ----------------------------------- ## ## Main body of $CONFIG_STATUS script. ## ## ----------------------------------- ## _ASEOF test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=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.6.0, which was generated by GNU Autoconf 2.67. 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 case $ac_config_files in *" "*) set x $ac_config_files; shift; ac_config_files=$*;; esac case $ac_config_headers in *" "*) set x $ac_config_headers; shift; ac_config_headers=$*;; esac cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # 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_write_fail=1 ac_cs_usage="\ \`$as_me' instantiates files and other configuration actions from templates according to the current configuration. Unless the files and actions are specified as TAGs, all are instantiated by default. Usage: $0 [OPTION]... [TAG]... -h, --help print this help, then exit -V, --version print version number and configuration settings, then exit --config print configuration, then exit -q, --quiet, --silent 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 the package provider." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ netperf config.status 2.6.0 configured by $0, generated by GNU Autoconf 2.67, with options \\"\$ac_cs_config\\" Copyright (C) 2010 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' MKDIR_P='$MKDIR_P' AWK='$AWK' test -n "\$AWK" || AWK=awk _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # The default lists apply if the user does not specify any file. 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=`expr "X$1" : 'X\([^=]*\)='` ac_optarg= 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 ) $as_echo "$ac_cs_version"; exit ;; --config | --confi | --conf | --con | --co | --c ) $as_echo "$ac_cs_config"; exit ;; --debug | --debu | --deb | --de | --d | -d ) debug=: ;; --file | --fil | --fi | --f ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; '') as_fn_error $? "missing file argument" ;; esac as_fn_append CONFIG_FILES " '$ac_optarg'" ac_need_defaults=false;; --header | --heade | --head | --hea ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; esac as_fn_append CONFIG_HEADERS " '$ac_optarg'" ac_need_defaults=false;; --he | --h) # Conflict between --help and --header as_fn_error $? "ambiguous option: \`$1' Try \`$0 --help' for more information.";; --help | --hel | -h ) $as_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. -*) as_fn_error $? "unrecognized option: \`$1' Try \`$0 --help' for more information." ;; *) as_fn_append 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 || ac_write_fail=1 if \$ac_cs_recheck; then set X '$SHELL' '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion shift \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 CONFIG_SHELL='$SHELL' export CONFIG_SHELL exec "\$@" fi _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 exec 5>>config.log { echo sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX ## Running $as_me. ## _ASBOX $as_echo "$ac_log" } >&5 _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # # INIT-COMMANDS # AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # 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" ;; *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5 ;; 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 'as_fn_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") } || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 # Set up the scripts for CONFIG_FILES section. # No need to generate them if there are no CONFIG_FILES. # This happens for instance with `./config.status config.h'. if test -n "$CONFIG_FILES"; then ac_cr=`echo X | tr X '\015'` # On cygwin, bash can eat \r inside `` if the user requested igncr. # But we know of no other shell where ac_cr would be empty at this # point, so we can use a bashism as a fallback. if test "x$ac_cr" = x; then eval ac_cr=\$\'\\r\' fi ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then ac_cs_awk_cr='\\r' else ac_cs_awk_cr=$ac_cr fi echo 'BEGIN {' >"$tmp/subs1.awk" && _ACEOF { echo "cat >conf$$subs.awk <<_ACEOF" && echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && echo "_ACEOF" } >conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` ac_delim='%!_!# ' for ac_last_try in false false false false false :; do . ./conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` if test $ac_delim_n = $ac_delim_num; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done rm -f conf$$subs.sh cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 cat >>"\$tmp/subs1.awk" <<\\_ACAWK && _ACEOF sed -n ' h s/^/S["/; s/!.*/"]=/ p g s/^[^!]*!// :repl t repl s/'"$ac_delim"'$// t delim :nl h s/\(.\{148\}\)..*/\1/ t more1 s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ p n b repl :more1 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t nl :delim h s/\(.\{148\}\)..*/\1/ t more2 s/["\\]/\\&/g; s/^/"/; s/$/"/ p b :more2 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t delim ' >$CONFIG_STATUS || ac_write_fail=1 rm -f conf$$subs.awk cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 _ACAWK cat >>"\$tmp/subs1.awk" <<_ACAWK && for (key in S) S_is_set[key] = 1 FS = "" } { line = $ 0 nfields = split(line, field, "@") substed = 0 len = length(field[1]) for (i = 2; i < nfields; i++) { key = field[i] keylen = length(key) if (S_is_set[key]) { value = S[key] line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) len += length(value) + length(field[++i]) substed = 1 } else len += 1 + keylen } print line } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" else cat fi < "$tmp/subs1.awk" > "$tmp/subs.awk" \ || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 _ACEOF # VPATH may cause trouble with some makes, so we remove sole $(srcdir), # ${srcdir} and @srcdir@ entries 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[ ]*=[ ]*/{ h s/// s/^/:/ s/[ ]*$/:/ s/:\$(srcdir):/:/g s/:\${srcdir}:/:/g s/:@srcdir@:/:/g s/^:*// s/:*$// x s/\(=[ ]*\).*/\1/ G s/\n// s/^[^=]*=[ ]*$// }' fi cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 fi # test -n "$CONFIG_FILES" # Set up the scripts for CONFIG_HEADERS section. # No need to generate them if there are no CONFIG_HEADERS. # This happens for instance with `./config.status Makefile'. if test -n "$CONFIG_HEADERS"; then cat >"$tmp/defines.awk" <<\_ACAWK || BEGIN { _ACEOF # Transform confdefs.h into an awk script `defines.awk', embedded as # here-document in config.status, that substitutes the proper values into # config.h.in to produce config.h. # Create a delimiter string that does not exist in confdefs.h, to ease # handling of long lines. ac_delim='%!_!# ' for ac_last_try in false false :; do ac_t=`sed -n "/$ac_delim/p" confdefs.h` if test -z "$ac_t"; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done # For the awk script, D is an array of macro values keyed by name, # likewise P contains macro parameters if any. Preserve backslash # newline sequences. ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* sed -n ' s/.\{148\}/&'"$ac_delim"'/g t rset :rset s/^[ ]*#[ ]*define[ ][ ]*/ / t def d :def s/\\$// t bsnl s/["\\]/\\&/g s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ D["\1"]=" \3"/p s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p d :bsnl s/["\\]/\\&/g s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ D["\1"]=" \3\\\\\\n"\\/p t cont s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p t cont d :cont n s/.\{148\}/&'"$ac_delim"'/g t clear :clear s/\\$// t bsnlc s/["\\]/\\&/g; s/^/"/; s/$/"/p d :bsnlc s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p b cont ' >$CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 for (key in D) D_is_set[key] = 1 FS = "" } /^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { line = \$ 0 split(line, arg, " ") if (arg[1] == "#") { defundef = arg[2] mac1 = arg[3] } else { defundef = substr(arg[1], 2) mac1 = arg[2] } split(mac1, mac2, "(") #) macro = mac2[1] prefix = substr(line, 1, index(line, defundef) - 1) if (D_is_set[macro]) { # Preserve the white space surrounding the "#". print prefix "define", macro P[macro] D[macro] next } else { # 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. if (defundef == "undef") { print "/*", prefix defundef, macro, "*/" next } } } { print } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 fi # test -n "$CONFIG_HEADERS" eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS" shift for ac_tag do case $ac_tag in :[FHLC]) ac_mode=$ac_tag; continue;; esac case $ac_mode$ac_tag in :[FHL]*:*);; :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5 ;; :[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 || as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5 ;; esac case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac as_fn_append 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 '` $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' `' by configure.' if test x"$ac_file" != x-; then configure_input="$ac_file. $configure_input" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 $as_echo "$as_me: creating $ac_file" >&6;} fi # Neutralize special characters interpreted by sed in replacement strings. case $configure_input in #( *\&* | *\|* | *\\* ) ac_sed_conf_input=`$as_echo "$configure_input" | sed 's/[\\\\&|]/\\\\&/g'`;; #( *) ac_sed_conf_input=$configure_input;; esac case $ac_tag in *:-:* | *:-) cat >"$tmp/stdin" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; 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 || $as_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"; as_fn_mkdir_p ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_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 ac_MKDIR_P=$MKDIR_P case $MKDIR_P in [\\/$]* | ?:[\\/]* ) ;; */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; esac _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # 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= ac_sed_dataroot=' /datarootdir/ { p q } /@datadir@/p /@docdir@/p /@infodir@/p /@localedir@/p /@mandir@/p' case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in *datarootdir*) ac_datarootdir_seen=yes;; *@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 $as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 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 || ac_write_fail=1 ac_sed_extra="$ac_vpsub $extrasub _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 :t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b s|@configure_input@|$ac_sed_conf_input|;t t s&@top_builddir@&$ac_top_builddir_sub&;t t s&@top_build_prefix@&$ac_top_build_prefix&;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 s&@MKDIR_P@&$ac_MKDIR_P&;t t $ac_datarootdir_hack " eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$tmp/subs.awk" >$tmp/out \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 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"; } && { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&5 $as_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 \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; :H) # # CONFIG_HEADER # if test x"$ac_file" != x-; then { $as_echo "/* $configure_input */" \ && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs" } >"$tmp/config.h" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 if diff "$ac_file" "$tmp/config.h" >/dev/null 2>&1; then { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 $as_echo "$as_me: $ac_file is unchanged" >&6;} else rm -f "$ac_file" mv "$tmp/config.h" "$ac_file" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 fi else $as_echo "/* $configure_input */" \ && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs" \ || as_fn_error $? "could not create -" "$LINENO" 5 fi # Compute "$ac_file"'s index in $config_headers. _am_arg="$ac_file" _am_stamp_count=1 for _am_header in $config_headers :; do case $_am_header in $_am_arg | $_am_arg:* ) break ;; * ) _am_stamp_count=`expr $_am_stamp_count + 1` ;; esac done echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" || $as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$_am_arg" : 'X\(//\)[^/]' \| \ X"$_am_arg" : 'X\(//\)$' \| \ X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$_am_arg" | 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) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 $as_echo "$as_me: executing $ac_file commands" >&6;} ;; esac case $ac_file$ac_mode in "depfiles":C) test x"$AMDEP_TRUE" != x"" || { # Autoconf 2.62 quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. case $CONFIG_FILES in *\'*) eval set x "$CONFIG_FILES" ;; *) set x $CONFIG_FILES ;; esac shift for mf 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. # Grep'ing the whole file is not good either: AIX grep has a line # limit of 2048, but all sed's we know have understand at least 4000. if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/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 || $as_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 # Extract the definition of DEPDIR, am__include, and am__quote # from the Makefile without running `make'. DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` test -z "$DEPDIR" && continue am__include=`sed -n 's/^am__include = //p' < "$mf"` test -z "am__include" && continue am__quote=`sed -n 's/^am__quote = //p' < "$mf"` # When using ansi2knr, U may be empty or an underscore; expand it U=`sed -n 's/^U = //p' < "$mf"` # Find all dependency output files, they are included files with # $(DEPDIR) in their names. 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 " s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/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 || $as_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; as_fn_mkdir_p # echo "creating $dirpart/$file" echo '# dummy' > "$dirpart/$file" done done } ;; esac done # for ac_tag as_fn_exit 0 _ACEOF ac_clean_files=$ac_clean_files_save test $ac_write_fail = 0 || as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 # 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 || as_fn_exit 1 fi if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} fi netperf-2.6.0/missing0000755000175000017500000002403211525015225011501 00000000000000#! /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 netperf-2.6.0/src/0000755000175000017500000000000011770164743010764 500000000000000netperf-2.6.0/src/netsys_solaris.c0000644000175000017500000001042311712332606014120 00000000000000#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 netperf-2.6.0/src/netrt_rtnetlink.c0000644000175000017500000001531711712332146014273 00000000000000#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 { close(s); return strdup("UnknownAddressFamily"); } } else { /* there must always be a destination */ printf("No destination specified.\n"); close(s); 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 { close(s); 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) { close(s); return strdup("SendmsgFailure"); } memset(reply,0,sizeof(reply)); ret = recv(s, reply, sizeof(reply), 0); if (ret < 0) { close(s); 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 { close(s); return strdup("MultipleInterfacesFound"); } } } } if (interface_index == -1) { /* we didn't find it */ return strdup("InterfaceNotFound"); } else { if (NULL == if_indextoname(interface_index,interface_name)) { close(s); return strdup("IfIndexToNameFailure"); } else { close(s); 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 netperf-2.6.0/src/netserver.c0000644000175000017500000010463311770161205013062 00000000000000/* Copyright (C) 1993-2012 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-2012 Hewlett-Packard Co. Version 2.6.0"; #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 #if HAVE_SYS_IPC_H #include #endif #if HAVE_SYS_IOCTL_H #include #endif #if HAVE_SYS_SOCKET_H #include #endif #if HAVE_SYS_STAT_H #include #endif #if HAVE_NETINET_IN_H #include #endif #if HAVE_NETDB_H #include #endif #if HAVE_UNISTD_H #include #endif #if HAVE_STDLIB_H #include #endif #if HAVE_ERRNO_H #include #endif #if HAVE_SIGNAL_H #include /* some OS's have SIGCLD defined as SIGCHLD */ #ifndef SIGCLD #define SIGCLD SIGCHLD #endif /* SIGCLD */ #endif #if !defined(HAVE_SETSID) #if HAVE_SYS_WAIT_H #include #endif #endif #ifdef WIN32 #include #include #if HAVE_WS2TCPIP_H #include #endif #include #include "missing\stdint.h" #define strdup _strdup #define sleep(x) Sleep((x)*1000) #define netperf_socklen_t socklen_t #endif /* WIN32 */ /* unconditional system includes */ #include #include #include /* netperf includes */ #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_DIR #if defined(WIN32) #define DEBUG_LOG_FILE_DIR "" #elif defined(ANDROID) #define DEBUG_LOG_FILE_DIR "/data/local/tmp/" #else #define DEBUG_LOG_FILE_DIR "/tmp/" #endif #endif /* DEBUG_LOG_FILE_DIR */ #ifndef DEBUG_LOG_FILE #define DEBUG_LOG_FILE DEBUG_LOG_FILE_DIR"netserver.debug" #endif #if !defined(PATH_MAX) #define PATH_MAX MAX_PATH #endif char FileName[PATH_MAX]; char listen_port[10]; struct listen_elt { SOCKET fd; struct listen_elt *next; }; struct listen_elt *listen_list = NULL; SOCKET server_control; int child; /* are we the child of inetd or a parent netserver? */ int netperf_daemon; int daemon_parent = 0; int not_inetd; int want_daemonize; int spawn_on_accept; int suppress_debug = 0; extern char *optarg; extern int optind, opterr; /* char *passphrase = NULL; */ static void init_netserver_globals() { #if defined(__VMS) || defined(VMWARE_UW) spawn_on_accept = 0; want_daemonize = 0; #else spawn_on_accept = 1; #if defined(WIN32) /* we only know how to spawn in WIN32, not daemonize */ want_daemonize = 0; #else want_daemonize = 1; #endif /* WIN32 */ #endif /* __VMS || VMWARE_UW */ child = 0; not_inetd = 0; netperf_daemon = 0; } void unlink_empty_debug_file() { #if !defined(WIN32) struct stat buf; if (stat(FileName,&buf)== 0) { if (buf.st_size == 0) unlink(FileName); } #endif } /* it is important that set_server_sock() be called before this routine as we depend on the control socket being dup()ed out of the way when we go messing about with the streams. */ void open_debug_file() { #if !defined WIN32 #define NETPERF_NULL "/dev/null" #else #define NETPERF_NULL "nul" #endif FILE *rd_null_fp; if (where != NULL) fflush(where); snprintf(FileName, sizeof(FileName), #if defined(WIN32) "%s\\%s_%d", getenv("TEMP"), #else "%s_%d", #endif DEBUG_LOG_FILE, getpid()); if ((where = fopen((suppress_debug) ? NETPERF_NULL : FileName, "w")) == NULL) { perror("netserver: debug file"); exit(1); } #if !defined(WIN32) chmod(FileName,0644); /* redirect stdin to "/dev/null" */ rd_null_fp = fopen(NETPERF_NULL,"r"); if (NULL == rd_null_fp) { fprintf(where, "%s: opening of %s failed: %s (errno %d)\n", __FUNCTION__, NETPERF_NULL, strerror(errno), errno); fflush(where); exit(1); } if (close(STDIN_FILENO) == -1) { fprintf(where, "%s: close of STDIN_FILENO failed: %s (errno %d)\n", __FUNCTION__, strerror(errno), errno); fflush(where); exit(1); } if (dup(fileno(rd_null_fp)) == -1) { fprintf(where, "%s: dup of rd_null_fp to stdin failed: %s (errno %d)\n", __FUNCTION__, strerror(errno), errno); fflush(where); exit(1); } /* redirect stdout to "where" */ if (close(STDOUT_FILENO) == -1) { fprintf(where, "%s: close of STDOUT_FILENO failed: %s (errno %d)\n", __FUNCTION__, strerror(errno), errno); fflush(where); exit(1); } if (dup(fileno(where)) == -1) { fprintf(where, "%s: dup of where to stdout failed: %s (errno %d)\n", __FUNCTION__, strerror(errno), errno); fflush(where); exit(1); } /* redirect stderr to "where" */ if (close(STDERR_FILENO) == -1) { fprintf(where, "%s: close of STDERR_FILENO failed: %s (errno %d)\n", __FUNCTION__, strerror(errno), errno); fflush(where); exit(1); } if (dup(fileno(where)) == -1) { fprintf(where, "%s: dup of where to stderr failed: %s (errno %d)\n", __FUNCTION__, strerror(errno), errno); fflush(where); exit(1); } #else /* 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 } /* so, either we are a child of inetd in which case server_sock should be stdin, or we are a child of a netserver parent. there will be logic here for all of it, including Windows. it is important that this be called before open_debug_file() */ void set_server_sock() { if (debug) { fprintf(where, "%s: enter\n", __FUNCTION__); fflush(where); } #ifdef WIN32 server_sock = (SOCKET)GetStdHandle(STD_INPUT_HANDLE); #elif !defined(__VMS) if (server_sock != INVALID_SOCKET) { fprintf(where,"Yo, Iz ain't invalid!\n"); fflush(where); exit(1); } /* we dup this to up the reference count so when we do redirection of the io streams we don't accidentally toast the control connection in the case of our being a child of inetd. */ server_sock = dup(0); #else if ((server_sock = socket(TCPIP$C_AUXS, SOCK_STREAM, 0)) == INVALID_SOCKET) { fprintf(stderr, "%s: failed to grab aux server socket: %s (errno %s)\n", __FUNCTION__, strerror(errno), errno); fflush(stderr); exit(1); } #endif } void create_listens(char hostname[], char port[], int af) { struct addrinfo hints; struct addrinfo *local_res; struct addrinfo *local_res_temp; int count, error; int on = 1; SOCKET temp_socket; struct listen_elt *temp_elt; if (debug) { fprintf(stderr, "%s: called with host '%s' port '%s' family %s(%d)\n", __FUNCTION__, hostname, port, inet_ftos(af), 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, "%s: Sleeping on getaddrinfo EAI_AGAIN\n", __FUNCTION__); fflush(stderr); } sleep(1); } } while ((error == EAI_AGAIN) && (count <= 5)); if (error) { if (debug) { fprintf(stderr, "%s: could not resolve remote '%s' port '%s' af %d\n" "\tgetaddrinfo returned %s (%d)\n", __FUNCTION__, hostname, port, af, gai_strerror(error), error); } return; } if (debug) { dump_addrinfo(stderr, local_res, hostname, port, af); } local_res_temp = local_res; while (local_res_temp != NULL) { temp_socket = socket(local_res_temp->ai_family,SOCK_STREAM,0); if (temp_socket == INVALID_SOCKET) { if (debug) { fprintf(stderr, "%s could not allocate a socket: %s (errno %d)\n", __FUNCTION__, strerror(errno), errno); fflush(stderr); } local_res_temp = local_res_temp->ai_next; continue; } /* happiness and joy, keep going */ if (setsockopt(temp_socket, SOL_SOCKET, SO_REUSEADDR, (char *)&on , sizeof(on)) == SOCKET_ERROR) { if (debug) { fprintf(stderr, "%s: warning: could not set SO_REUSEADDR: %s (errno %d)\n", __FUNCTION__, strerror(errno), errno); fflush(stderr); } } /* still happy and joyful */ if ((bind(temp_socket, local_res_temp->ai_addr, local_res_temp->ai_addrlen) != SOCKET_ERROR) && (listen(temp_socket,128) != SOCKET_ERROR)) { /* OK, now add to the list */ temp_elt = (struct listen_elt *)malloc(sizeof(struct listen_elt)); if (temp_elt) { temp_elt->fd = temp_socket; if (listen_list) { temp_elt->next = listen_list; } else { temp_elt->next = NULL; } listen_list = temp_elt; } else { fprintf(stderr, "%s: could not malloc a listen_elt\n", __FUNCTION__); fflush(stderr); exit(1); } } else { /* we consider a bind() or listen() failure a transient and try the next address */ if (debug) { fprintf(stderr, "%s: warning: bind or listen call failure: %s (errno %d)\n", __FUNCTION__, strerror(errno), errno); fflush(stderr); } close(temp_socket); } local_res_temp = local_res_temp->ai_next; } } void setup_listens(char name[], char port[], int af) { int do_inet; int no_name = 0; #ifdef AF_INET6 int do_inet6; #endif if (debug) { fprintf(where, "%s: enter\n", __FUNCTION__); fflush(where); } if (strcmp(name,"") == 0) { no_name = 1; switch (af) { case AF_UNSPEC: do_inet = 1; #ifdef AF_INET6 do_inet6 = 1; #endif break; case AF_INET: do_inet = 1; #ifdef AF_INET6 do_inet6 = 0; #endif break; #ifdef AF_INET6 case AF_INET6: do_inet = 0; do_inet6 = 1; break; #endif default: do_inet = 1; } /* if we have IPv6, try that one first because it may be a superset */ #ifdef AF_INET6 if (do_inet6) create_listens("::0",port,AF_INET6); #endif if (do_inet) create_listens("0.0.0.0",port,AF_INET); } else { create_listens(name,port,af); } if (listen_list) { fprintf(stdout, "Starting netserver with host '%s' port '%s' and family %s\n", (no_name) ? "IN(6)ADDR_ANY" : name, port, inet_ftos(af)); fflush(stdout); } else { fprintf(stderr, "Unable to start netserver with '%s' port '%s' and family %s\n", (no_name) ? "IN(6)ADDR_ANY" : name, port, inet_ftos(af)); fflush(stderr); exit(1); } } SOCKET set_fdset(struct listen_elt *list, fd_set *fdset) { struct listen_elt *temp; SOCKET max = INVALID_SOCKET; FD_ZERO(fdset); temp = list; if (debug) { fprintf(where, "%s: enter list %p fd_set %p\n", __FUNCTION__, list, fdset); fflush(where); } while (temp) { if (temp->fd > max) max = temp->fd; if (debug) { fprintf(where, "setting %d in fdset\n", temp->fd); fflush(where); } FD_SET(temp->fd,fdset); temp = temp->next; } return max; } void close_listens(struct listen_elt *list) { struct listen_elt *temp; if (debug) { fprintf(where, "%s: enter\n", __FUNCTION__); fflush(where); } temp = list; while (temp) { close(temp->fd); temp = temp->next; } } static int recv_passphrase() { /* may need to revisit the timeout. we only respond if there is an error with receiving the passphrase */ if ((recv_request_timed_n(0,20) > 0) && (netperf_request.content.request_type == PASSPHRASE) && (!strcmp(passphrase, (char *)netperf_request.content.test_specific_data))) { /* it was okey dokey */ return 0; } #if defined(SEND_PASSPHRASE_RESPONSE) netperf_response.content.response_type = PASSPHRASE; netperf_response.content.serv_errno = 403; snprintf((char *)netperf_response.content.test_specific_data, sizeof(netperf_response.content.test_specific_data), "Sorry, unable to match with required passphrase\n"); send_response_n(0); #endif fprintf(where, "Unable to match required passphrase. Closing control connection\n"); fflush(where); close(server_sock); return -1; } /* 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) { fprintf(where, "%s: enter\n", __FUNCTION__); fflush(where); } /* if the netserver was started with a passphrase, look for it in the first request to arrive. if there is no passphrase in the first request we will end-up dumping the control connection. raj 2012-01-23 */ if ((passphrase != NULL) && (recv_passphrase())) return; while (1) { if (recv_request() <= 0) { close(server_sock); return; } switch (netperf_request.content.request_type) { case DEBUG_ON: netperf_response.content.response_type = DEBUG_OK; if (!suppress_debug) { debug++; if (debug == 1) { /* we just flipped-on debugging, dump the request because recv_request/recv_request_n will not have dumped it as its dump_request() call is conditional on debug being set. raj 2011-07-08 */ dump_request(); } } send_response(); break; case DEBUG_OFF: if (debug) debug--; netperf_response.content.response_type = DEBUG_OK; send_response(); /* we used to take the trouble to close the debug file, but SAF asked a good question when he asked "Why?" and since I cannot think of a good reason, I have removed the code. raj 2011-07-08 */ 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.content.test_specific_data), "%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 of course, the last one is not i but i-1 */ i -= 1; snprintf((char *)netperf_response.content.test_specific_data, sizeof(netperf_response.content.test_specific_data), "%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: 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 case PASSPHRASE: if (debug) { fprintf(where,"Ignoring an unexpected passphrase control message\n"); fflush(where); } break; default: fprintf(where,"unknown test number %d\n", netperf_request.content.request_type); fflush(where); netperf_response.content.serv_errno=998; send_response(); break; } } } /* the routine we call when we are going to spawn/fork/whatnot a child process from the parent netserver daemon. raj 2011-07-08 */ void spawn_child() { #if defined(HAVE_FORK) if (debug) { fprintf(where, "%s: enter\n", __FUNCTION__); fflush(where); } /* flush the usual suspects */ fflush(stdin); fflush(stdout); fflush(stderr); fflush(where); signal(SIGCLD,SIG_IGN); switch (fork()) { case -1: fprintf(where, "%s: fork() error %s (errno %d)\n", __FUNCTION__, strerror(errno), errno); fflush(where); exit(1); case 0: /* we are the child, but not of inetd. we don't know if we are the child of a daemonized parent or not, so we still need to worry about the standard file descriptors. raj 2011-07-11 */ close_listens(listen_list); open_debug_file(); child = 1; netperf_daemon = 0; process_requests(); exit(0); break; default: /* we are the parent, not a great deal to do here, but we may want to reap some children */ #if !defined(HAVE_SETSID) /* Only call "waitpid()" if "setsid()" is not used. */ while(waitpid(-1, NULL, WNOHANG) > 0) { if (debug) { fprintf(where, "%s: reaped a child process\n", __FUNCTION__); } } #endif break; } #elif defined(WIN32) BOOL b; char *cmdline; int cmdline_length; int cmd_index; PROCESS_INFORMATION pi; STARTUPINFO si; int i; if (debug) { fprintf(where, "%s: enter\n", __FUNCTION__); fflush(where); } /* create the cmdline array based on strlen(program) + 80 chars */ cmdline_length = strlen(program) + 80; cmdline = malloc(cmdline_length + 1); // +1 for trailing null 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); cmd_index = strlen(cmdline); if (verbosity > 1) { cmd_index += snprintf(&cmdline[cmd_index], cmdline_length - cmd_index, " -v %d", verbosity); } for (i=0; i < debug; i++) { cmd_index += snprintf(&cmdline[cmd_index], cmdline_length - cmd_index, " -d"); } cmd_index += snprintf(&cmdline[cmd_index], cmdline_length - cmd_index, " -I %x", (int)(UINT_PTR)server_sock); /* are these -i settings even necessary? the command line scanning does not seem to do anything with them */ cmd_index += snprintf(&cmdline[cmd_index], cmdline_length - cmd_index, " -i %x", (int)(UINT_PTR)server_control); cmd_index += snprintf(&cmdline[cmd_index], cmdline_length - cmd_index, " -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); /* the caller/parent will close server_sock */ free(cmdline); #else fprintf(where, "%s called on platform which cannot spawn children\n", __FUNCTION__); fflush(where); exit(1); #endif /* HAVE_FORK */ } void accept_connection(SOCKET listen_fd) { struct sockaddr_storage peeraddr; netperf_socklen_t peeraddrlen; #if defined(SO_KEEPALIVE) int on = 1; #endif if (debug) { fprintf(where, "%s: enter\n", __FUNCTION__); fflush(where); } peeraddrlen = sizeof(peeraddr); /* while server_control is only used by the WIN32 path, but why bother ifdef'ing it? and besides, do we *really* need knowledge of server_control in the WIN32 case? do we have to tell the child about *all* the listen endpoints? raj 2011-07-08 */ server_control = listen_fd; if ((server_sock = accept(listen_fd, (struct sockaddr *)&peeraddr, &peeraddrlen)) == INVALID_SOCKET) { fprintf(where, "%s: accept failure: %s (errno %d)\n", __FUNCTION__, strerror(errno), errno); fflush(where); exit(1); } #if defined(SO_KEEPALIVE) /* we are not terribly concerned if this does not work, it is merely duct tape added to belts and suspenders. raj 2011-07-08 */ setsockopt(server_sock, SOL_SOCKET, SO_KEEPALIVE, (const char *)&on, sizeof(on)); #endif if (spawn_on_accept) { spawn_child(); /* spawn_child() only returns when we are the parent */ close(server_sock); } else { process_requests(); } } void accept_connections() { fd_set read_fds, write_fds, except_fds; SOCKET high_fd, candidate; int num_ready; if (debug) { fprintf(where, "%s: enter\n", __FUNCTION__); fflush(where); } while (1) { FD_ZERO(&write_fds); FD_ZERO(&except_fds); high_fd = set_fdset(listen_list,&read_fds); #if !defined(WIN32) num_ready = select(high_fd + 1, #else num_ready = select(1, #endif &read_fds, &write_fds, &except_fds, NULL); if (num_ready < 0) { fprintf(where, "%s: select failure: %s (errno %d)\n", __FUNCTION__, strerror(errno), errno); fflush(where); exit(1); } /* try to keep things simple */ candidate = 0; while ((num_ready) && (candidate <= high_fd)) { if (FD_ISSET(candidate,&read_fds)) { accept_connection(candidate); FD_CLR(candidate,&read_fds); num_ready--; } else { candidate++; } } } } #ifndef WIN32 #define SERVER_ARGS "DdfhL:n:Np:v:VZ:46" #else #define SERVER_ARGS "DdfhL:n:Np:v:VZ:46I:i:" #endif void scan_netserver_args(int argc, char *argv[]) { int c; char arg1[BUFSIZ], arg2[BUFSIZ]; if (debug) { fprintf(where, "%s: enter\n", __FUNCTION__); fflush(where); } while ((c = getopt(argc, argv, SERVER_ARGS)) != EOF){ switch (c) { case '?': case 'h': print_netserver_usage(); exit(1); case 'd': debug++; suppress_debug = 0; break; case 'D': /* perhaps one of these days we'll take an argument */ want_daemonize = 0; not_inetd = 1; break; case 'f': spawn_on_accept = 0; not_inetd = 1; break; #ifdef WIN32 case 'I': child = TRUE; break; case 'i': break; #endif 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); } break; case 'n': shell_num_cpus = atoi(optarg); if (shell_num_cpus > MAXCPUS) { fprintf(stderr, "netserver: This version can only support %d CPUs. Please" "increase MAXCPUS in netlib.h and recompile.\n", MAXCPUS); fflush(stderr); exit(1); } break; case 'N': suppress_debug = 1; debug = 0; 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 'Z': /* only copy as much of the passphrase as could fit in the test-specific portion of a control message. Windows does not seem to have a strndup() so just malloc and strncpy it. we weren't checking the strndup() return so won't bother with checking malloc(). we will though make certain we only allocated it once in the event that someone puts -Z on the command line more than once */ if (passphrase == NULL) passphrase = malloc(sizeof(netperf_request.content.test_specific_data)); strncpy(passphrase, optarg, sizeof(netperf_request.content.test_specific_data)); passphrase[sizeof(netperf_request.content.test_specific_data) - 1] = '\0'; break; case '4': local_address_family = AF_INET; break; case '6': #if defined(AF_INET6) local_address_family = AF_INET6; #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; } } } void daemonize() { #if defined(HAVE_FORK) if (debug) { fprintf(where, "%s: enter\n", __FUNCTION__); fflush(where); } /* flush the usual suspects */ fflush(stdin); fflush(stdout); fflush(stderr); switch (fork()) { case -1: fprintf(stderr, "%s: fork() error %s (errno %d)\n", __FUNCTION__, strerror(errno), errno); fflush(stderr); exit(1); case 0: /* perhaps belt and suspenders, but if we dump core, perhaps better to do so here. we won't worry about the call being successful though. raj 2011-07-08 */ chdir(DEBUG_LOG_FILE_DIR); /* we are the child. we should get a new "where" to match our new pid */ open_debug_file(); #ifdef HAVE_SETSID setsid(); #else setpgrp(); #endif /* HAVE_SETSID */ signal(SIGCLD, SIG_IGN); /* ok, we can start accepting control connections now */ accept_connections(); default: /* we are the parent, nothing to do but exit? */ exit(0); } #else fprintf(where, "%s called on platform which cannot daemonize\n", __FUNCTION__); fflush(where); exit(1); #endif /* HAVE_FORK */ } static void check_if_inetd() { if (debug) { fprintf(where, "%s: enter\n", __FUNCTION__); fflush(where); } if (not_inetd) { return; } else { #if !defined(WIN32) && !defined(__VMS) struct sockaddr_storage name; netperf_socklen_t namelen; namelen = sizeof(name); if (getsockname(0, (struct sockaddr *)&name, &namelen) == SOCKET_ERROR) { not_inetd = 1; } else { not_inetd = 0; child = 1; } #endif } } /* OK, so how does all this work you ask? Well, we are in a maze of twisty options, all different. Netserver can be invoked as a child of inetd or the VMS auxiliary server process, or a parent netserver process. In those cases, we could/should follow the "child" path. However, there are really two "child" paths through the netserver code. When this netserver is a child of a parent netserver in the case of *nix, the child process will be created by a spawn_child_process() in accept_connections() and will not hit the "child" path here in main(). When this netserver is a child of a parent netserver in the case of windows, the child process will have been spawned via a Create_Process() call in spawn_child_process() in accept_connections, but will flow through here again. We rely on the scan_netserver_args() call to have noticed the magic option that tells us we are a child process. When this netserver is launched from the command line we will first set-up the listen endpoint(s) for the controll connection. At that point we decide if we want to and can become our own daemon, or stay attached to the "terminal." When this happens under *nix, we will again take a fork() path via daemonize() and will not come back through main(). If we ever learn how to become our own daemon under Windows, we will undoubtedly take a Create_Process() path again and will come through main() once again - that is what the "daemon" case here is all about. It is hoped that this is all much clearer than the old spaghetti code that netserver had become. raj 2011-07-11 */ int _cdecl main(int argc, char *argv[]) { #ifdef WIN32 WSADATA wsa_data ; /* Initialize the winsock lib do we still want 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 for program name failed!\n"); return -1 ; } strcpy(program, argv[0]); init_netserver_globals(); netlib_init(); strncpy(local_host_name,"",sizeof(local_host_name)); local_address_family = AF_UNSPEC; strncpy(listen_port,TEST_PORT,sizeof(listen_port)); scan_netserver_args(argc, argv); check_if_inetd(); if (child) { /* we are the child of either an inetd or parent netserver via spawning (Windows) rather than fork()ing. if we were fork()ed we would not be coming through this way. set_server_sock() must be called before open_debug_file() or there is a chance that we'll toast the descriptor when we do not wish it. */ set_server_sock(); open_debug_file(); process_requests(); } else if (daemon_parent) { /* we are the parent daemonized netserver process. accept_connections() will decide if we want to spawn a child process */ accept_connections(); } else { /* we are the top netserver process, so we have to create the listen endpoint(s) and decide if we want to daemonize */ setup_listens(local_host_name,listen_port,local_address_family); if (want_daemonize) { daemonize(); } accept_connections(); } unlink_empty_debug_file(); #ifdef WIN32 WSACleanup(); #endif return 0; } netperf-2.6.0/src/netdrv_none.c0000644000175000017500000000060311525015213013351 00000000000000#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; } netperf-2.6.0/src/NetServerDir/0000755000175000017500000000000011770164743013340 500000000000000netperf-2.6.0/src/NetServerDir/sources0000644000175000017500000000152111770163512014656 00000000000000TARGETNAME=netserver TARGETPATH=OBJ TARGETTYPE=PROGRAM LINKLIBS= \ $(SDK_LIB_PATH)\kernel32.lib \ $(SDK_LIB_PATH)\ws2_32.lib \ $(SDK_LIB_PATH)\wsock32.lib \ $(SDK_LIB_PATH)\Winmm.lib USE_MSVCRT=1 UMTYPE=console INCLUDES=$(SDK_INC_PATH);.;.. MSC_WARNING_LEVEL=/W3 /WX C_DEFINES=$(C_DEFINES) -D_CONSOLE_ -DHAVE_STRING_H -DHAVE_STRUCT_SOCKADDR_STORAGE -DHAVE_GETADDRINFO -DHAVE_GETNAMEINFO -DSTDC_HEADERS -DHAVE_STDLIB_H -DHAVE_WS2TCPIP_H -DWANT_OMNI -DWANT_DEMO -DWANT_HISTOGRAM -DWANT_INTERVALS #USER_C_FLAGS=$(USER_C_FLAGS) /E SOURCES= \ ..\netcpu_ntperf.c \ ..\netlib.c \ ..\netsh.c \ ..\nettest_bsd.c \ ..\nettest_omni.c \ ..\netsec_win.c \ ..\netdrv_none.c \ ..\netslot_none.c \ ..\netsys_none.c \ ..\netrt_none.c \ ..\net_uuid.c \ ..\netserver.c \ ..\dscp.c \ ..\inet_ntop.c netperf-2.6.0/src/NetServerDir/makefile0000644000175000017500000000041111525015213014735 00000000000000# # 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.defnetperf-2.6.0/src/NetServerDir/inet_ntop.c0000644000175000017500000000016711525015213015410 00000000000000#if !defined(InetNtop) /* +*+ Why isn't this in the winsock headers yet? */ #include "..\missing\inet_ntop.c" #endif netperf-2.6.0/src/Makefile.in0000644000175000017500000005775411770160504012762 00000000000000# Makefile.in generated by automake 1.11.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008, 2009 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@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd 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 = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ bin_PROGRAMS = netperf$(EXEEXT) netserver$(EXEEXT) subdir = src DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ $(srcdir)/netperf_version.h.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/src/missing/m4/salen.m4 \ $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = netperf_version.h CONFIG_CLEAN_VPATH_FILES = am__installdirs = "$(DESTDIR)$(bindir)" 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) dscp.$(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 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.ap DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ SOURCES = $(netperf_SOURCES) $(netserver_SOURCES) DIST_SOURCES = $(netperf_SOURCES) $(netserver_SOURCES) RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ html-recursive info-recursive install-data-recursive \ install-dvi-recursive install-exec-recursive \ install-html-recursive install-info-recursive \ install-pdf-recursive install-ps-recursive install-recursive \ installcheck-recursive installdirs-recursive pdf-recursive \ ps-recursive uninstall-recursive RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \ $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \ distdir ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ 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 = @INSTALL@ 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@ MKDIR_P = @MKDIR_P@ 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_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ RANLIB = @RANLIB@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ 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@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = missing CLEANFILES = netperf_version.h 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 netslot_ux1131.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 dscp.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.ap all: all-recursive .SUFFIXES: .SUFFIXES: .c .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu src/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): netperf_version.h: $(top_builddir)/config.status $(srcdir)/netperf_version.h.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ install-binPROGRAMS: $(bin_PROGRAMS) @$(NORMAL_INSTALL) test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)" @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ for p in $$list; do echo "$$p $$p"; done | \ sed 's/$(EXEEXT)$$//' | \ while read p p1; do if test -f $$p; \ then echo "$$p"; echo "$$p"; else :; fi; \ done | \ sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ if ($$2 == $$4) files[d] = files[d] " " $$1; \ else { print "f", $$3 "/" $$4, $$1; } } \ END { for (d in files) print "f", d, files[d] }' | \ while read type dir files; do \ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ test -z "$$files" || { \ echo " $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ } \ ; done uninstall-binPROGRAMS: @$(NORMAL_UNINSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ -e 's/$$/$(EXEEXT)/' `; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(bindir)" && rm -f $$files clean-binPROGRAMS: -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS) netperf$(EXEEXT): $(netperf_OBJECTS) $(netperf_DEPENDENCIES) @rm -f netperf$(EXEEXT) $(LINK) $(netperf_OBJECTS) $(netperf_LDADD) $(LIBS) netserver$(EXEEXT): $(netserver_OBJECTS) $(netserver_DEPENDENCIES) @rm -f netserver$(EXEEXT) $(LINK) $(netserver_OBJECTS) $(netserver_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dscp.Po@am__quote@ @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@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` # 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): @fail= failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ 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; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" $(RECURSIVE_CLEAN_TARGETS): @fail= failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ 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; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done && test -z "$$fail" tags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ done ctags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ done 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; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$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; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) 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; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile $(PROGRAMS) installdirs: installdirs-recursive installdirs-am: for dir in "$(DESTDIR)$(bindir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done 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: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_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: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-binPROGRAMS install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: 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 .MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) ctags-recursive \ install-am install-strip tags-recursive .PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ all all-am check check-am clean clean-binPROGRAMS \ clean-generic ctags ctags-recursive distclean \ distclean-compile distclean-generic distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-binPROGRAMS install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ installdirs-am maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-compile mostlyclean-generic pdf pdf-am \ ps ps-am tags tags-recursive uninstall uninstall-am \ uninstall-binPROGRAMS # 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: netperf-2.6.0/src/netdrv_ethtool.c0000644000175000017500000000554611731710354014112 00000000000000#if defined(HAVE_CONFIG_H) #include #endif #include #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; close(s); 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; close(s); 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; } p 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 netperf-2.6.0/src/netcpu_perfstat.c0000644000175000017500000002021511770161113014242 00000000000000char netcpu_perfstat_id[]="\ @(#)netcpu_perfstat.c Version 2.6.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" "\tsec = %ld usec = %ld\n" "\telapsed time = %g\n", i, sec,usec, 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); } netperf-2.6.0/src/Makefile.am0000644000175000017500000000315511736405703012740 00000000000000SUBDIRS = 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 netslot_ux1131.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 dscp.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.ap endif netperf-2.6.0/src/netslot_none.c0000644000175000017500000000176211614107257013557 00000000000000#if defined(HAVE_CONFIG_H) #include #endif #if defined(HAVE_STRING_H) #include #endif #if defined(NETPERF_STANDALONE_DEBUG) #include #endif #ifdef WIN32 #define strdup _strdup #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 netperf-2.6.0/src/nettest_sdp.c0000644000175000017500000033170011770161501013375 00000000000000#ifndef lint char nettest_sdp[]="\ @(#)nettest_sdp.c (c) Copyright 2007-2012 Hewlett-Packard Co. Version 2.6.0"; #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 */ netperf-2.6.0/src/nettest_unix.c0000644000175000017500000032330511770161231013574 00000000000000#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-2012 Hewlett-Packard Co. Version 2.6.0"; /****************************************************************/ /* */ /* 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 #include #include #include #include #include #include #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 = -1; lsr_size_req = -1; 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; /*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; netperf_socklen_t 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, "%s", 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; netperf_socklen_t 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; netperf_socklen_t 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 = 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 = 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; }; } } #endif /* WANT_UNIX */ netperf-2.6.0/src/netslot_linux.c0000644000175000017500000001000611712332414013740 00000000000000#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 = NULL; /* 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; } fclose(address_file); } 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 = NULL; 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)) { fclose(valfile); return -1; } ret = (int)strtol(buffer,NULL,0); fclose(valfile); 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,128,"/sys/class/net/%s/device/vendor",interface_name); *vendor = get_val_from_file(sysfile); /* next the device */ ret = snprintf(sysfile,128,"/sys/class/net/%s/device/device",interface_name); *device = get_val_from_file(sysfile); /* next the subsystem vendor */ ret = snprintf(sysfile,128,"/sys/class/net/%s/device/subsystem_vendor",interface_name); *sub_vend = get_val_from_file(sysfile); /* next the subsystem device */ ret = snprintf(sysfile,128,"/sys/class/net/%s/device/subsystem_device",interface_name); *sub_dev = get_val_from_file(sysfile); } netperf-2.6.0/src/netsys_linux.c0000644000175000017500000000546211712332543013612 00000000000000#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; 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); fclose(proccpu); return; } } } while (!feof(proccpu)); *cpu_model = strdup("model_name"); fclose(proccpu); } static int find_cpu_freq() { char linebuf[256]; char *cret; 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,":"); fclose(proccpu); return rint(strtod(target+1,NULL)); } } } while (!feof(proccpu)); fclose(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) { 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 netperf-2.6.0/src/Makefile.uw0000644000175000017500000000613611525015213012765 00000000000000# 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 netperf-2.6.0/src/nettest_dlpi.c0000644000175000017500000037565311770161400013554 00000000000000 /****************************************************************/ /* */ /* 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-2012 Hewlett-Packard Co. Version 2.6.0"; #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" /* 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}; /* 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"; /* routines that used to be in src/netlib.c but this code is the only code that uses them. raj 20110111 */ 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; { } /* 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); fflush(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 */ netperf-2.6.0/src/netrt_none.c0000644000175000017500000000050211614107316013206 00000000000000#ifdef HAVE_CONFIG_H #include #endif #ifdef HAVE_SYS_SOCKET_H #include #endif #ifdef HAVE_STRING_H #include #endif #ifdef WIN32 #define strdup _strdup #endif char * find_egress_interface(struct sockaddr *source, struct sockaddr *dest) { return strdup("InterfaceUnavailable"); } netperf-2.6.0/src/netcpu_procstat.c0000644000175000017500000002171011770161131014252 00000000000000char netcpu_procstat_id[]="\ @(#)netcpu_procstat.c (c) Copyright 2005-2012 Version 2.6.0"; /* 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 (int)((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 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) { 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; 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++) { /* 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) { if (debug) { fprintf(where, "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); } netperf-2.6.0/src/netcpu_looper.c0000644000175000017500000004512011770161651013723 00000000000000char netcpu_looper_id[]="\ @(#)netcpu_looper.c (c) Copyright 2005-2012. Version 2.6.0"; /* 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); } netperf-2.6.0/src/netcpu_kstat.c0000644000175000017500000002244011770162252013547 00000000000000char netcpu_kstat_id[]="\ @(#)netcpu_kstat.c Version 2.6.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); } netperf-2.6.0/src/netcpu_sysctl.c0000644000175000017500000000462111770162120013735 00000000000000char netcpu_sysctl_id[]="\ @(#)netcpu_sysctl.c Version 2.6.0"; #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); } netperf-2.6.0/src/netslot_solaris.c0000644000175000017500000001552011712332441014263 00000000000000#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 netperf-2.6.0/src/netrt_rtmget.c0000644000175000017500000002413411712332127013557 00000000000000#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; 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 netperf-2.6.0/src/netsys_none.c0000644000175000017500000000041311614107365013404 00000000000000#include #ifdef WIN32 #define strdup _strdup #endif 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; } netperf-2.6.0/src/nettest_sctp.c0000644000175000017500000045140111770161572013571 00000000000000#ifndef lint char nettest_sctp[]="\ @(#)nettest_sctp.c (c) Copyright 2005-2012 Hewlett-Packard Co. Version 2.6.0"; #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 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( int socket, int *mss ) { socklen_t sock_opt_len; if (sctp_opt_info(socket, 0, SCTP_MAXSEG, mss, &sock_opt_len) < 0) { lss_size = -1; } } static void sctp_enable_events( 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( 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( 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 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_n(1); #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_start(time_hist); #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_stop_add(time_hist); #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( void ) { struct sockaddr_in myaddr_in; /* needed to get port number */ struct sockaddr_storage peeraddr; /* used in accept */ int s_listen,s_data; 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]; 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( 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 */ 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 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_n(1); #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 */ HIST_timestamp_start(time_hist); #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 */ HIST_timestamp_stop_add(time_hist); #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( void ) { struct sockaddr_in myaddr_in; int s_recv; socklen_t 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( 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 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_n(1); #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_start(time_hist); #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_stop_add(time_hist); #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( void ) { 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; 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 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( 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 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_n(1); #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 */ HIST_timestamp_start(time_hist); #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 HIST_timestamp_stop_add(time_hist); #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( void ) { 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; socklen_t addrlen; 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( void ) { printf("%s",sctp_usage); exit(1); } void scan_sctp_args( 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 */ netperf-2.6.0/src/netlib.h0000644000175000017500000005557011770162467012347 00000000000000/* Copyright (C) 1993-2012 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 162 /* 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 PASSPHRASE 6 #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 #else # ifdef WIN32 # include "missing\inttypes.h" # endif # endif #endif enum sock_buffer{ SEND_BUFFER, RECV_BUFFER }; enum netperf_output_modes { HUMAN = 0, CSV, KEYVAL, }; /* 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 */ void *completion_ptr; /* a pointer to information for async completion */ }; /* +*+ 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 int control_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 enum netperf_output_modes netperf_output_mode; #if defined(WANT_INTERVALS) || defined(WANT_DEMO) extern int demo_mode; extern double demo_interval; extern double demo_units; extern double units_this_tick; #if defined(WANT_DEMO) extern void demo_rr_interval(uint32_t units); extern void demo_rr_setup(uint32_t units); extern void demo_stream_interval(uint32_t units); extern void demo_interval_tick(uint32_t units); extern void demo_interval_final(); #endif #endif extern void netlib_init(); extern int netlib_get_page_size(); extern void install_signal_catchers(); extern struct addrinfo *resolve_host(char hostname[], char port[], int af); 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 int recv_request(); extern int recv_request_timed_n(int n, int seconds); 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 int recv_request_n(int n); extern void fixup_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 random_ip_address(struct addrinfo *res, int mask_len); 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); extern int HIST_get_percentile(); extern void HIST_get_stats(); extern void find_security_info(int *enabled, int *type, char **specific); extern void demo_first_timestamp(); extern void demo_stream_setup(uint32_t a, uint32_t b); #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); extern void stop_itimer(void); #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 extern HANDLE WinTimer; #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 #define strdup _strdup #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 netperf-2.6.0/src/netdrv_solaris.c0000644000175000017500000000302611712332704014075 00000000000000#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 netperf-2.6.0/src/nettest_sdp.h0000644000175000017500000001500211525015213013370 00000000000000/* 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(); netperf-2.6.0/src/netcpu_pstat.c0000644000175000017500000001675711770162001013562 00000000000000char netcpu_pstat_id[]="\ @(#)netcpu_pstat.c (c) Copyright 2005-2012, Hewlett-Packard Company, Version 2.6.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); } netperf-2.6.0/src/nettest_xti.h0000644000175000017500000002207211525015213013413 00000000000000/* * 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[]); netperf-2.6.0/src/netcpu_kstat10.c0000644000175000017500000004051011770161073013706 00000000000000char netcpu_kstat10_id[]="\ @(#)netcpu_kstat10.c (c) Copyright 2005-2012, Hewlett-Packard Company Version 2.6.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 #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" "\t idle %llu\n" "\t user %llu\n" "\t kernel %llu\n" "\t interrupt %llu\n", name,instance, counters[instance].idle, counters[instance].user, counters[instance].kernel, 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" "Please alter MAXCPUS in netlib.h and recompile.\n", i, MAXCPUS); 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" "%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" "calc_cpu_util_internal: more interrupt time than others combined!\n" "\tso CPU util cannot be estimated\n" "\t delta[%d].interrupt %llu\n" "\t delta[%d].idle %llu\n" "\t delta[%d].user %llu\n" "\t delta[%d].kernel %llu\n", i,delta_cpu_counters[i].interrupt, i,delta_cpu_counters[i].idle, i,delta_cpu_counters[i].user, 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" "\tfraction_user %llu interrupt_user %llu\n" "\tfraction_kernel %llu interrupt_kernel %llu\n", fraction_idle, interrupt_idle, fraction_user, interrupt_user, 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 check for 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); } netperf-2.6.0/src/netsh.c0000644000175000017500000011313711770160677012201 00000000000000#include "netperf_version.h" char netsh_id[]="\ @(#)netsh.c (c) Copyright 1993-2012 Hewlett-Packard Company. Version 2.6.0"; /****************************************************************/ /* */ /* Global include files */ /* */ /****************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #ifndef WIN32 #include #include #include #include #include #include #include #include #else #include #include #include "missing\stdint.h" /* 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 #define netperf_socklen_t socklen_t extern int getopt(int , char **, char *) ; #endif #ifndef STRINGS #include #else /* STRINGS */ #include #endif /* STRINGS */ /**********************************************************************/ /* */ /* Local Include Files */ /* */ /**********************************************************************/ #define NETSH #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_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:CcdD:f:F:H:hi:I:jk:K:l:L:n:NO:o:P:p:rSs:t:T:v:VW:w:y:Y:Z:46" /************************************************************************/ /* */ /* Global variables */ /* */ /************************************************************************/ /* some names and such */ char *program; /* program invocation name */ char *command_line; /* a copy of the entire command line */ /* stuff to say where this test is going */ char host_name[HOSTNAMESIZE] = "", /* remote host name or ip addr */ local_host_name[HOSTNAMESIZE] = "", /* local hostname or ip */ test_name[BUFSIZ] = "TCP_STREAM", /* which test to run */ test_port[PORTBUFSIZE] = "12865", /* where is the test waiting */ local_test_port[PORTBUFSIZE] = "0"; /* from whence we should start */ int address_family = AF_UNSPEC, /* which address family remote */ local_address_family = AF_UNSPEC; /* which address family local */ /* the source of data for filling the buffers */ char local_fill_file[BUFSIZ] = ""; char remote_fill_file[32] = ""; /* size limited for control message */ /* output controlling variables */ int debug = 0, /* debugging level */ print_headers = 1, /* do/don't display headers */ verbosity = 1, /* verbosity level */ keep_histogram = 0, keep_statistics = 0; /* 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 = 0, /* you guessed it */ remote_cpu_usage = 0; /* still right ! */ float local_cpu_rate = 0.0F, remote_cpu_rate = 0.0F; 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 = 10, /* test ends by time */ test_len_ticks, /* how many times will the timer go off before the test is over? */ test_bytes = 0, /* test ends on byte count */ test_trans = 0; /* test ends on tran count */ /* the alignment conditions for the tests */ int local_recv_align = 8, /* alignment for local receives */ local_send_align = 8, /* alignment for local sends */ local_send_offset = 0, local_recv_offset = 0, remote_recv_align = 8, /* alignment for remote receives */ remote_send_align = 8, /* 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 = 0, interval_wate = 0, interval_burst = 0, remote_interval_usecs = 0, remote_interval_burst = 0; /* wait time between control/data connection establishment and start of data traffic */ int wait_time_secs = 0; #ifdef DIRTY int loc_dirty_count = 0, loc_clean_count = 0, rem_dirty_count = 0, rem_clean_count = 0; #else int 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... */ int confidence_level = 0; int iteration_min = 1; int iteration_max = 1; int result_confidence_only = 0; double interval = 0.0; /* 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; /* socket priority via SO_PRIORITY */ int local_socket_prio = -1; int remote_socket_prio = -1; /* and IP_TOS */ int local_socket_tos = -1; int remote_socket_tos = -1; /* did someone request processor affinity? */ int cpu_binding_requested = 0; /* are we not establishing a control connection? */ int no_control = 0; /* what is the passphrase? */ char *passphrase = NULL; char netserver_usage[] = "\n\ Usage: netserver [options] \n\ \n\ Options:\n\ -h Display this text\n\ -D Do not daemonize\n\ -d Increase debugging output\n\ -f Do not spawn chilren for each test, run serially\n\ -L name,family Use name to pick listen address and family for family\n\ -N No debugging output, even if netperf asks\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\ -Z passphrase Expect passphrase as the first thing received\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 time,[units] * Display interim results at least every time interval\n\ using units as the initial guess for units per second\n\ A negative value for time will make heavy use of the\n\ system's timestamping functionality\n\ -f G|M|K|g|m|k Set the output units\n\ -F lfill[,rfill]* Pre-fill buffers with data from specified 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\ -j Keep additional timing statistics\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\ -s seconds Wait seconds between test setup and test start\n\ -S Set SO_KEEPALIVE on the data connection\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\ -y local,remote Set the socket priority\n\ -Y local,remote Set the IP_TOS. Use hexadecimal.\n\ -Z passphrase Set and pass to netserver a passphrase\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_sep this routine is somewhat like break_args in that it will separate a pair of values using the given separator. however, if there is no separator this version will not ass-u-me that arg2 should be the same as arg1. raj 20101129 */ void break_args_explicit_sep(char *s, int sep, char *arg1, char *arg2) { char *ns; ns = strchr(s,sep); if (ns) { /* there was a separator arg2 should be the second arg*/ *ns++ = '\0'; while ((*arg2++ = *ns++) != '\0'); } else { /* there was no separator, so we should make sure that arg2 is \0 lest something become confused. raj 2005-02-04 */ *arg2 = '\0'; }; while ((*arg1++ = *s++) != '\0'); } /* break_args_explicit - now just a wrapper around a call to break_args_explicit_sep passing-in a ',' as the separator. raj 20101129 */ void break_args_explicit(char *s, char *arg1, char *arg2) { break_args_explicit_sep(s, ',', arg1, arg2); } /* 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 defined(AF_RDS) if (strstr(temp,"af_rds") || strstr(temp,"32")) { return(AF_RDS); } #endif if (strstr(temp,"unspec") || strstr(temp,"0")) { return(AF_UNSPEC); } fprintf(where, "WARNING! %s not recognized as an address family, using AF_UNPSEC\n" "Are you sure netperf was configured for that address family?\n", family_string); 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_direction(char direction_string[]) { char arg1[BUFSIZ],arg2[BUFSIZ]; int left, right; if (NULL == direction_string) { return 0; } if (direction_string[0] == '\0') { return 0; } /* allow someone to "or" break_args_explicit will split at the first '|' in the string so we know that arg1 has no '|' in it and arg2 might */ break_args_explicit_sep(direction_string,'|',arg1,arg2); /* at this point only arg2 could contain a '|' so recurse on that */ right = parse_direction(arg2); /* now we parse the "left side" or arg1 */ if (arg1[0] == '\0') { left = 0; } else if ((strcasecmp(arg1,"xmit") == 0) || (strcasecmp(arg1,"send") == 0) || (strcasecmp(arg1,"stream") == 0) || (strcasecmp(arg1,"transmit") == 0)) { left = NETPERF_XMIT; } else if ((strcasecmp(arg1,"recv") == 0) || (strcasecmp(arg1,"receive") == 0) || (strcasecmp(arg1,"maerts") == 0)) { /* yes, another magic number... */ left = NETPERF_RECV; } else if (strcasecmp(arg1,"rr") == 0) { left = NETPERF_XMIT|NETPERF_RECV; } else { /* we now "ass-u-me" it is a number that can be parsed by strtol() */ left = strtol(arg1,NULL,0); } return (left | right); } 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); } /* we ass-u-me that everyone has IPPROTO_TCP elsewhere so might as well here, and avoid issues with windows using an enum. Kudos to Jonathan Cook. */ if (!strcasecmp(temp,"tcp")){ socket_type = SOCK_STREAM; return IPPROTO_TCP; } if (!strcasecmp(temp,"udp")) { socket_type = SOCK_DGRAM; return IPPROTO_UDP; } /* we keep the rest of the #idefs though because these may not be as universal as TCP and UDP... */ #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 #if defined(IPPROTO_DCCP) && defined(SOCK_DCCP) if (!strcasecmp(temp,"dccp")) { socket_type = SOCK_DCCP; return IPPROTO_DCCP; } #endif #ifdef IPPROTO_UDPLITE if (!strcasecmp(temp,"udplite")) { socket_type = SOCK_DGRAM; return IPPROTO_UDPLITE; } #endif return IPPROTO_IP; } void print_netserver_usage() { fprintf(stderr, "%s", netserver_usage); } void print_netperf_usage() { fprintf(stderr, "%s%s", netperf_usage1, netperf_usage2); } /* convert the specified string to upper case if we know how */ static void convert_to_upper(char *source) { #if defined(HAVE_TOUPPER) int i,length; length = strlen(source); for (i=0; i < length; i++) { source[i] = toupper(source[i]); } #endif return; } 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() to store program name failed!\n"); 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++; break; case 'D': #if (defined WANT_DEMO) demo_mode = 1; /* 1 == use units; 2 == always timestamp */ break_args_explicit(optarg,arg1,arg2); if (arg1[0]) { demo_interval = atof(arg1) * 1000000.0; if (demo_interval < 0.0) { demo_interval = demo_interval * -1.0; demo_mode = 2; } } if (arg2[0]) { demo_units = convert(arg2); } #else printf("Sorry, Demo Mode not configured into this netperf.\n" "Please consider reconfiguring netperf with\n" "--enable-demo=yes and recompiling\n"); #endif break; case 'f': /* set the thruput formatting */ libfmt = *optarg; break; case 'F': /* set the fill_file variables for pre-filling buffers. check the remote fill file name length against our limit as we will not hear from the remote on errors opening the fill file. Props to Jonathan Cook for the remote name check */ break_args_explicit(optarg,arg1,arg2); if (arg1[0]) { strncpy(local_fill_file,arg1,sizeof(local_fill_file)); local_fill_file[sizeof(local_fill_file) - 1] = '\0'; } if (arg2[0]) { if (strlen(arg2)>(sizeof(remote_fill_file) - 1)){ fprintf(stderr, "Remote fill file name must be less than %d characters\n", (int) sizeof(remote_fill_file)); fflush(stderr); exit(-1); } strncpy(remote_fill_file,arg2,sizeof(remote_fill_file)); remote_fill_file[sizeof(remote_fill_file) - 1] = '\0'; } 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 'j': keep_histogram = 1; keep_statistics = 1; 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 'S': /* the user wishes us to set SO_KEEPALIVE */ want_keepalive = 1; break; case 's': /* the user wishes us to sleep/pause some length of time before actually starting the test */ wait_time_secs = convert(optarg); break; case 't': /* set the test name and shift it to upper case so we don't have to worry about compares on things like substrings */ strncpy(test_name,optarg,sizeof(test_name)-1); convert_to_upper(test_name); 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 'y': break_args(optarg, arg1, arg2); #if defined(SO_PRIORITY) if (arg1[0]) local_socket_prio = convert(arg1); #else if (debug) { fprintf(where, "Setting SO_PRIORITY is not supported on this platform, request to set SO_PRIORITY locally ignored.\n"); fflush(where); } local_socket_prio = -3; #endif if (arg2[0]) remote_socket_prio = convert(arg2); break; case 'Y': break_args(optarg, arg1, arg2); #if defined(IP_TOS) || defined(IPV6_TCLASS) if (arg1[0]) local_socket_tos = parse_ipqos(arg1); #else if (debug) { fprintf(where, "Setting IP type-of-service is not supported on this platform, request to set it locally ignored.\n"); fflush(where); } local_socket_tos = -1; #endif if (arg2[0]) { remote_socket_tos = parse_ipqos(arg2); if (debug) { fprintf(where, "Setting remote_socket_tos to 0x%x\n", remote_socket_tos); fflush(where); } } break; case 'Z': /* only copy as much of the passphrase as could fit in the test-specific portion of a control message. Windows does not seem to have a strndup() so just malloc and strncpy it. we weren't checking the strndup() return so won't bother with checking malloc(). we will though make certain we only allocated it once in the event that someone puts -Z on the command line more than once */ if (passphrase == NULL) passphrase = malloc(sizeof(netperf_request.content.test_specific_data)); strncpy(passphrase, optarg, sizeof(netperf_request.content.test_specific_data)); passphrase[sizeof(netperf_request.content.test_specific_data) - 1] = '\0'; 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: #if defined(AF_RDS) case AF_RDS: #endif 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: #if defined(AF_RDS) case AF_RDS: #endif 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); } } else { /* resolve the hostname and pull the address family from the addrinfo */ struct addrinfo *ai; ai = resolve_host(host_name, NULL, address_family); if (!ai) { printf("Netperf could not resolve %s as a host name\n", host_name); exit(-1); } address_family = ai->ai_family; freeaddrinfo(ai); } /* 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: #if defined(AF_RDS) case AF_RDS: #endif strcpy(local_host_name,"0.0.0.0"); break; case AF_UNSPEC: switch (address_family) { case AF_INET: case AF_UNSPEC: #if defined(AF_RDS) case AF_RDS: #endif 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_socket_prio = -1; remote_socket_tos = -1; 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 */ /* while the parsing of the command line will upshift the test name, since we don't know that there will always be a way to do so? we will retain for now the strcasecmp calls rather than switch to strcmp. raj 20101220 */ if ( #ifndef WANT_MIGRATION (strcasecmp(test_name,"TCP_STREAM") == 0) || (strcasecmp(test_name,"TCP_MAERTS") == 0) || (strcasecmp(test_name,"TCP_RR") == 0) || (strcasecmp(test_name,"TCP_CRR") == 0) || (strcasecmp(test_name,"UDP_STREAM") == 0) || (strcasecmp(test_name,"UDP_RR") == 0) || #endif #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_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 */ (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) || #ifdef WANT_MIGRATION (strcasecmp(test_name,"TCP_STREAM") == 0) || (strcasecmp(test_name,"TCP_MAERTS") == 0) || (strcasecmp(test_name,"TCP_RR") == 0) || (strcasecmp(test_name,"TCP_CRR") == 0) || (strcasecmp(test_name,"UDP_STREAM") == 0) || (strcasecmp(test_name,"UDP_RR") == 0) || #endif (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("Local socket priority: %d\n", local_socket_prio); printf("Remote socket priority: %d\n", remote_socket_prio); printf("Local socket TOS: %s\n", iptos2str(local_socket_tos)); printf("Remote socket TOS: %s\n", iptos2str(remote_socket_tos)); 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"); } netperf-2.6.0/src/net_uuid.c0000644000175000017500000002055511731712044012661 00000000000000/* 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 #if defined(HAVE_INTTYPES_H) #include #endif /* 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 #include "missing\stdint.h" #define snprintf _snprintf #else #if HAVE_SYS_TYPES_H #include #else # if HAVE_STDINT_H # include # endif #endif #if HAVE_SYS_TIME_H #include #endif #if HAVE_SYS_SYSINFO_H #include #endif #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(char),16,fp); fclose(fp); return; } /* ok, now what? */ i = 0; do { myrand = true_random(); seed[i++] = myrand & 0xff; seed[i++] = myrand >> 8; } while (i < 14); fclose(fp); } #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 (uint16_t)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 netperf-2.6.0/src/netperf_version.h.in0000644000175000017500000000004411770160516014662 00000000000000#define NETPERF_VERSION "@VERSION@" netperf-2.6.0/src/missing/0000755000175000017500000000000011770164744012436 500000000000000netperf-2.6.0/src/missing/Makefile.in0000644000175000017500000004465411770160504014426 00000000000000# Makefile.in generated by automake 1.11.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008, 2009 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@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd 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 = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ subdir = src/missing DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ getaddrinfo.c inet_ntop.c ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/src/missing/m4/salen.m4 \ $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LIBRARIES = $(noinst_LIBRARIES) AR = ar ARFLAGS = cru libcompat_a_AR = $(AR) $(ARFLAGS) @NEED_LIBCOMPAT_TRUE@libcompat_a_DEPENDENCIES = $(LIBOBJS) am__libcompat_a_SOURCES_DIST = getaddrinfo.h am_libcompat_a_OBJECTS = libcompat_a_OBJECTS = $(am_libcompat_a_OBJECTS) DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ SOURCES = $(libcompat_a_SOURCES) DIST_SOURCES = $(am__libcompat_a_SOURCES_DIST) RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ html-recursive info-recursive install-data-recursive \ install-dvi-recursive install-exec-recursive \ install-html-recursive install-info-recursive \ install-pdf-recursive install-ps-recursive install-recursive \ installcheck-recursive installdirs-recursive pdf-recursive \ ps-recursive uninstall-recursive RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \ $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \ distdir ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ 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 = @INSTALL@ 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@ MKDIR_P = @MKDIR_P@ 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_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ RANLIB = @RANLIB@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ 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@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ 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) all: all-recursive .SUFFIXES: .SUFFIXES: .c .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/missing/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu src/missing/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): 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) 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@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` # 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): @fail= failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ 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; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" $(RECURSIVE_CLEAN_TARGETS): @fail= failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ 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; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done && test -z "$$fail" tags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ done ctags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ done 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; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$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; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) 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; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ 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: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_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: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: 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: .MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) ctags-recursive \ install-am install-strip tags-recursive .PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ all all-am check check-am clean clean-generic \ clean-noinstLIBRARIES ctags ctags-recursive distclean \ distclean-compile distclean-generic distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs installdirs-am \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-compile mostlyclean-generic pdf pdf-am ps ps-am \ tags tags-recursive uninstall uninstall-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: netperf-2.6.0/src/missing/Makefile.am0000644000175000017500000000022411525015213014370 00000000000000SUBDIRS = m4 if NEED_LIBCOMPAT noinst_LIBRARIES = libcompat.a libcompat_a_SOURCES = getaddrinfo.h libcompat_a_LIBADD = $(LIBOBJS) $(ALLOCA) endif netperf-2.6.0/src/missing/m4/0000755000175000017500000000000011770164744012756 500000000000000netperf-2.6.0/src/missing/m4/Makefile.in0000644000175000017500000002214311770160504014733 00000000000000# Makefile.in generated by automake 1.11.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008, 2009 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@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd 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 = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ subdir = src/missing/m4 DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/src/missing/m4/salen.m4 \ $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = SOURCES = DIST_SOURCES = DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ 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 = @INSTALL@ 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@ MKDIR_P = @MKDIR_P@ 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_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ RANLIB = @RANLIB@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ 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@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ EXTRA_DIST = *.m4 all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/missing/m4/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu src/missing/m4/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): tags: TAGS TAGS: ctags: CTAGS CTAGS: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$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: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_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: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: 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: .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic distclean \ distclean-generic distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-generic pdf pdf-am ps ps-am uninstall uninstall-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: netperf-2.6.0/src/missing/m4/Makefile.am0000644000175000017500000000002211525015213014704 00000000000000EXTRA_DIST = *.m4 netperf-2.6.0/src/missing/m4/herrno.m40000644000175000017500000000374611525015213014427 00000000000000dnl * 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]) netperf-2.6.0/src/missing/m4/socklent.m40000644000175000017500000000673111525015213014751 00000000000000dnl 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]) ]) netperf-2.6.0/src/missing/m4/sockaddrin6.m40000644000175000017500000000523211525015213015331 00000000000000dnl * 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]) netperf-2.6.0/src/missing/m4/type_socklen_t.m40000644000175000017500000000125411525015213016144 00000000000000dnl @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 ]) netperf-2.6.0/src/missing/m4/in6addr.m40000644000175000017500000000671211525015213014455 00000000000000dnl * 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]) netperf-2.6.0/src/missing/m4/sockinttypes.m40000644000175000017500000001313711525015213015664 00000000000000dnl * 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]) netperf-2.6.0/src/missing/m4/salen.m40000644000175000017500000000257411525015213014232 00000000000000dnl 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 ]) netperf-2.6.0/src/missing/getaddrinfo.h0000644000175000017500000001227111525015213015000 00000000000000/* * 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 */ netperf-2.6.0/src/missing/inet_ntop.c0000644000175000017500000000766011525015213014512 00000000000000/* * 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; } } netperf-2.6.0/src/missing/getaddrinfo.c0000644000175000017500000003340411525015213014774 00000000000000/* * 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; } netperf-2.6.0/src/nettest_bsd.h0000644000175000017500000006012111770162515013366 00000000000000/* Copyright (C) 1993-2012 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 /* since it isn't clear that AF_RDS will be the same value everywhere we will have an NF_RDS as well and will make it "lucky 7" raj 20091014 */ #define NF_RDS 7 /* 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 #define NST_SEQPACKET 4 #ifdef WANT_OMNI #define OMNI_NO_DELAY 0x00000001 #define OMNI_USE_SENDFILE 0x00000002 #define OMNI_CONNECT_TEST 0x00000004 #define OMNI_MEASURE_CPU 0x00000008 #define OMNI_CHECKSUM_OFF 0x00000010 #define OMNI_ROUTING_ALLOWED 0x00000020 #define OMNI_WANT_IFNAME 0x00000040 #define OMNI_WANT_IFSLOT 0x00000080 #define OMNI_WANT_IFIDS 0x00000100 #define OMNI_WANT_DRVINFO 0x00000200 /* room in the middle */ #define OMNI_WANT_KEEPALIVE 0x80000000 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 flags; /* to convey things that didn't really need to burn an entire int */ 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 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 netperf_ip[4]; /* when netserver needs netperf's data IP */ uint32_t netserver_ip[4]; /* when netperf tells netserver his IP */ int32_t socket_prio; /* what netserver should use for socket prio */ int32_t socket_tos; /* what netserver should use for socket tos */ /* there are 38 "ints" above here, add another and you will need to adjust the define below */ #define OMNI_REQUEST_CONV_CUTOFF 38 char cong_control[16]; /* the requested congestion control alg */ char fill_file[32]; /* file from which netserver fills bufs */ }; 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 flags; 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 */ /* 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; int32_t socket_prio; int32_t socket_tos; /* there are 18 ints above here, add another and you need to adjust the define below */ #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]; }; 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; int32_t transport_retrans; #define OMNI_RESULTS_CONV_CUTOFF 22 /* 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 */ char cong_control[16]; /* what the congestion control alg was */ }; #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 */ routing_allowed, /* do we set/clear SO_DONTROUTE on data sock */ multicast_ttl, /* what should the TTL be on mcast dgrams */ want_keepalive, /* do we bother setting SO_KEEPALIVE? */ transport_mss_req; #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 extern SOCKET create_data_socket(struct addrinfo *res); netperf-2.6.0/src/netcpu_none.c0000644000175000017500000000134511770162050013355 00000000000000char netcpu_none_id[]="\ @(#)netcpu_none.c (c) Copyright 2005-2012 Hewlett-Packard Company, Version 2.6.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; } netperf-2.6.0/src/netsh.h0000644000175000017500000001355111770162501012171 00000000000000/* Copyright (C) 1993-2012 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 */ /* which way are we going and what are we doing in this handbasket?-) */ #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)) /* misc defines for the hell of it */ #ifndef MAXLONG #define MAXLONG 4294967295UL #endif /* MAXLONG */ #ifdef WANT_DCCP /* include netinet/in.h to see if SOCK_DCCP and IPPROTO_DCCP are there */ #include #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 */ extern char *passphrase; /* 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 int parse_direction(char direction_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 break_args_explicit_sep(char *s, int sep, 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 */ keep_histogram, /* do we keep a histogram of interesting times? */ keep_statistics; /* do we keep/calculate expensive statistics? */ /* 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 */ /* wait time between control/data connection establishment and start of data traffic */ extern int wait_time_secs; /* 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; #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 control the bufferspace "width" */ extern int send_width; extern int recv_width; /* control the socket priority */ extern int local_socket_prio; extern int remote_socket_prio; extern int local_socket_tos; extern int remote_socket_tos; /* 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 local_fill_file[BUFSIZ], remote_fill_file[32]; 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 extern int parse_ipqos(const char *cp); extern const char * iptos2str(int iptos); netperf-2.6.0/src/netperf.c0000644000175000017500000002035711770160720012511 00000000000000/* Copyright (C) 1993-2011 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-2012 Hewlett-Packard Company. Version 2.6.0"; #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #if HAVE_STRING_H # if !STDC_HEADERS && HAVE_MEMORY_H # include # endif # include #endif #ifdef HAVE_STRINGS_H #include #endif /* FreeBSD doesn't like socket.h before types are set. */ #if __FreeBSD__ # include #endif #ifdef WIN32 #include #include #include "missing\stdint.h" #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(); /* the call to set_defaults() is gone because we can initialize in declarations (or is that definitions) unlike the old days */ 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 (passphrase != NULL) { netperf_request.content.request_type = PASSPHRASE; strncpy((char *)netperf_request.content.test_specific_data, passphrase, sizeof(netperf_request.content.test_specific_data)); send_request_n(0); } } 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_rr_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 (%s) is unknown to this netperf.\n" "Please verify that you have the correct test name, \n" "and that test family has been compiled into this netperf.\n", test_name); exit(1); } if (!no_control) { shutdown_control(); } #ifdef WIN32 /* Cleanup the winsock lib */ WSACleanup(); #endif return(0); } netperf-2.6.0/src/netcpu_osx.c0000644000175000017500000000672511770161266013246 00000000000000char netcpu_sysctl_id[]="\ @(#)netcpu_osx.c Version 2.6.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 #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 /* some of this is to make Tiger (10.4), Leopard (10.5) and SnowLeopard (10.6) happy, we hope it does not anger previous versions */ #include /* #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); } netperf-2.6.0/src/NetPerfDir/0000755000175000017500000000000011770164743012766 500000000000000netperf-2.6.0/src/NetPerfDir/sources0000644000175000017500000000151411770160332014303 00000000000000TARGETNAME=netperf TARGETPATH=OBJ TARGETTYPE=PROGRAM LINKLIBS= \ $(SDK_LIB_PATH)\kernel32.lib \ $(SDK_LIB_PATH)\ws2_32.lib \ $(SDK_LIB_PATH)\wsock32.lib \ $(SDK_LIB_PATH)\Winmm.lib USE_MSVCRT=1 UMTYPE=console INCLUDES=$(SDK_INC_PATH);. MSC_WARNING_LEVEL=/W3 /WX C_DEFINES=$(C_DEFINES) -D_CONSOLE_ -DHAVE_STRING_H -DHAVE_STRUCT_SOCKADDR_STORAGE -DHAVE_GETADDRINFO -DHAVE_GETNAMEINFO -DSTDC_HEADERS -DHAVE_STDLIB_H -DHAVE_WS2TCPIP_H -DWANT_OMNI -DWANT_DEMO -DWANT_HISTOGRAM -DWANT_INTERVALS #USER_C_FLAGS=$(USER_C_FLAGS) /E SOURCES= \ ..\netcpu_ntperf.c \ ..\netlib.c \ ..\netsh.c \ ..\nettest_bsd.c \ ..\nettest_omni.c \ ..\netsec_win.c \ ..\netdrv_none.c \ ..\netslot_none.c \ ..\netsys_none.c \ ..\netrt_none.c \ ..\net_uuid.c \ ..\netperf.c \ ..\dscp.c \ ..\inet_ntop.c netperf-2.6.0/src/NetPerfDir/makefile0000644000175000017500000000041111525015210014360 00000000000000# # 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.defnetperf-2.6.0/src/NetPerfDir/inet_ntop.c0000644000175000017500000000016711525015210015033 00000000000000#if !defined(InetNtop) /* +*+ Why isn't this in the winsock headers yet? */ #include "..\missing\inet_ntop.c" #endif netperf-2.6.0/src/netcpu_ntperf.c0000644000175000017500000003313511770162200013713 00000000000000char netcpu_ntperf_id[]="\ @(#)netcpu_ntperf.c (c) Copyright 2005-2012, Hewlett-Packard Company, Version 2.6.0"; #if HAVE_CONFIG_H # include #endif #include #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; } netperf-2.6.0/src/netcpu.h0000644000175000017500000000114311525015213012333 00000000000000/* 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); netperf-2.6.0/src/dscp.c0000644000175000017500000001067411736706401012004 00000000000000/* dscp lookup routines lifted wholesale from openssh */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * Copyright (c) 2005,2006 Damien Miller. 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. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. */ #if HAVE_CONFIG_H #include #endif #include #if HAVE_STRING_H #include #endif #if HAVE_STDLIB_H #include #endif #ifdef WIN32 #define strcasecmp(a,b) _stricmp(a,b) #define snprintf _snprintf #endif int parse_ipqos(const char *cp); const char * iptos2str(int iptos); /* * Definitions for IP type of service (ip_tos) */ #if HAVE_NETINET_IN_SYSTM_H #include #endif #if HAVE_NETINET_IP_H #include #endif #ifndef IPTOS_LOWDELAY # define IPTOS_LOWDELAY 0x10 # define IPTOS_THROUGHPUT 0x08 # define IPTOS_RELIABILITY 0x04 # define IPTOS_LOWCOST 0x02 # define IPTOS_MINCOST IPTOS_LOWCOST #endif /* IPTOS_LOWDELAY */ /* * Definitions for DiffServ Codepoints as per RFC2474 */ #ifndef IPTOS_DSCP_AF11 # define IPTOS_DSCP_AF11 0x28 # define IPTOS_DSCP_AF12 0x30 # define IPTOS_DSCP_AF13 0x38 # define IPTOS_DSCP_AF21 0x48 # define IPTOS_DSCP_AF22 0x50 # define IPTOS_DSCP_AF23 0x58 # define IPTOS_DSCP_AF31 0x68 # define IPTOS_DSCP_AF32 0x70 # define IPTOS_DSCP_AF33 0x78 # define IPTOS_DSCP_AF41 0x88 # define IPTOS_DSCP_AF42 0x90 # define IPTOS_DSCP_AF43 0x98 # define IPTOS_DSCP_EF 0xb8 #endif /* IPTOS_DSCP_AF11 */ #ifndef IPTOS_DSCP_CS0 # define IPTOS_DSCP_CS0 0x00 # define IPTOS_DSCP_CS1 0x20 # define IPTOS_DSCP_CS2 0x40 # define IPTOS_DSCP_CS3 0x60 # define IPTOS_DSCP_CS4 0x80 # define IPTOS_DSCP_CS5 0xa0 # define IPTOS_DSCP_CS6 0xc0 # define IPTOS_DSCP_CS7 0xe0 #endif /* IPTOS_DSCP_CS0 */ #ifndef IPTOS_DSCP_EF # define IPTOS_DSCP_EF 0xb8 #endif /* IPTOS_DSCP_EF */ static const struct { const char *name; int value; } ipqos[] = { { "af11", IPTOS_DSCP_AF11 }, { "af12", IPTOS_DSCP_AF12 }, { "af13", IPTOS_DSCP_AF13 }, { "af21", IPTOS_DSCP_AF21 }, { "af22", IPTOS_DSCP_AF22 }, { "af23", IPTOS_DSCP_AF23 }, { "af31", IPTOS_DSCP_AF31 }, { "af32", IPTOS_DSCP_AF32 }, { "af33", IPTOS_DSCP_AF33 }, { "af41", IPTOS_DSCP_AF41 }, { "af42", IPTOS_DSCP_AF42 }, { "af43", IPTOS_DSCP_AF43 }, { "cs0", IPTOS_DSCP_CS0 }, { "cs1", IPTOS_DSCP_CS1 }, { "cs2", IPTOS_DSCP_CS2 }, { "cs3", IPTOS_DSCP_CS3 }, { "cs4", IPTOS_DSCP_CS4 }, { "cs5", IPTOS_DSCP_CS5 }, { "cs6", IPTOS_DSCP_CS6 }, { "cs7", IPTOS_DSCP_CS7 }, { "ef", IPTOS_DSCP_EF }, { "lowdelay", IPTOS_LOWDELAY }, { "throughput", IPTOS_THROUGHPUT }, { "reliability", IPTOS_RELIABILITY }, { NULL, -1 } }; int parse_ipqos(const char *cp) { unsigned int i; char *ep = NULL; long val; if (cp == NULL) return -1; for (i = 0; ipqos[i].name != NULL; i++) { if (strcasecmp(cp, ipqos[i].name) == 0) return ipqos[i].value; } /* Try parsing as an integer */ val = strtol(cp, &ep, 0); if (*cp == '\0' || *ep != '\0' || val < 0 || val > 255) return -1; return val; } const char * iptos2str(int iptos) { int i; static char iptos_str[sizeof "0xff"]; if (iptos < 0 || iptos > 64) iptos = 0; for (i = 0; ipqos[i].name != NULL; i++) { if (ipqos[i].value == iptos) return ipqos[i].name; } snprintf(iptos_str, sizeof iptos_str, "0x%02x", iptos); return iptos_str; } netperf-2.6.0/src/nettest_xti.c0000644000175000017500000057054011770161443013427 00000000000000#ifdef HAVE_CONFIG_H #include #endif #ifdef WANT_XTI #ifndef lint char nettest_xti_id[]="\ @(#)nettest_xti.c (c) Copyright 1995-2012 Hewlett-Packard Co. Version 2.6.0"; #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 */ netperf-2.6.0/src/netcpu_pstatnew.c0000644000175000017500000003326311770161151014270 00000000000000char netcpu_pstatnew_id[]="\ @(#)netcpu_pstatnew.c (c) Copyright 2005-2012 Hewlett-Packard Company, Version 2.6.0"; /* 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]; /* there can be more "processors" in the system than are actually online. so, we can either walk all the processors one at a time, which would be slow, or we can track not just lib_num_loc_cpu, which is the number of active "processors" but also the total number, and retrieve all of them at one shot and walk the list once, ignoring those that are offline. we will ass-u-me there is no change to the number of processors online while we are running or there will be strange things happening to CPU utilization. raj 2010-04-27 */ static long max_proc_count; void cpu_util_init(void) { struct pst_dynamic psd; if (pstat_getdynamic((struct pst_dynamic *)&psd, (size_t)sizeof(psd), (size_t)1, 0) != -1) { max_proc_count = psd.psd_max_proc_cnt; } else { /* we hope this never happens */ max_proc_count = lib_num_loc_cpus; } 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; /* to handle the cases of "processors" present but disabled, we will have to allocate a buffer big enough for everyone and then walk the entire list, pulling data for those which are online, assuming the processors online have not changed in the middle of the run. raj 2010-04-27 */ psp = (struct pst_processor *)malloc(max_proc_count * sizeof(*psp)); if (psp == NULL) { printf("malloc(%d) failed!\n", max_proc_count * sizeof(*psp)); exit(1); } if (pstat_getprocessor(psp, sizeof(*psp), max_proc_count, 0) != -1) { int i,j; /* 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; i = j = 0; while ((i < lib_num_loc_cpus) && (j < max_proc_count)) { if (psp[j].psp_processor_state == PSP_SPU_DISABLED) { j++; continue; } /* we know that psp[j] is online */ res[i].idle = (((uint64_t)psp[j].psp_idlecycles.psc_hi << 32) + psp[j].psp_idlecycles.psc_lo); if(debug) { fprintf(where, "\tidle[%d] = 0x%"PRIx64" ", i, res[i].idle); fflush(where); } res[i].user = (((uint64_t)psp[j].psp_usercycles.psc_hi << 32) + psp[j].psp_usercycles.psc_lo); if(debug) { fprintf(where, "user[%d] = 0x%"PRIx64" ", i, res[i].user); fflush(where); } res[i].kernel = (((uint64_t)psp[j].psp_systemcycles.psc_hi << 32) + psp[j].psp_systemcycles.psc_lo); if(debug) { fprintf(where, "kern[%d] = 0x%"PRIx64" ", i, res[i].kernel); fflush(where); } res[i].interrupt = (((uint64_t)psp[j].psp_interruptcycles.psc_hi << 32) + psp[j].psp_interruptcycles.psc_lo); if(debug) { fprintf(where, "intr[%d] = 0x%"PRIx64"\n", i, res[i].interrupt); fflush(where); } i++; j++; } 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" "\t idle %llu\n" "\t user %llu\n" "\t kernel %llu\n" "\t interrupt %llu\n", name,instance, counters[instance].idle, counters[instance].user, counters[instance].kernel, 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" "\tfraction_user %g\n" "\tfraction_kernel %g\n" "\tfraction_interrupt %g WARNING, possibly under-counted!\n" "\testimated_fraction_interrupt %g\n", fraction_idle, fraction_user, fraction_kernel, fraction_interrupt, 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" "\tfraction_user %"PRIu64"\n" "\tfraction_kernel %"PRIu64"\n" "\tfraction_interrupt %"PRIu64"WARNING, possibly under-counted!\n" "\testimated_fraction_interrupt %"PRIu64"\n", fraction_idle, fraction_user, fraction_kernel, fraction_interrupt, 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); } netperf-2.6.0/src/nettest_bsd.c0000644000175000017500000146173511770160757013410 00000000000000#ifndef lint char nettest_id[]="\ @(#)nettest_bsd.c (c) Copyright 1993-2012 Hewlett-Packard Co. Version 2.6.0"; #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 */ #ifndef WIN32 #if !defined(__VMS) #include #endif /* !__VMS */ #include #include #include #ifdef HAVE_NETINET_SCTP_H #include #endif #include #include #else /* WIN32 */ #include #define netperf_socklen_t socklen_t #include #include "missing\stdint.h" /* 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 */ transport_mss_req = -1; /* what maximum segment size is wanted */ 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 */ routing_allowed = 1; /* set/clear SO_DONTROUTE on data socket */ int multicast_ttl = -1; /* should we set the multicast TTL to a value? */ int want_keepalive = 0; #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 #ifdef WIN32 #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; #else 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); \ } #endif /* WIN32 */ #ifdef WIN32 #define INTERVALS_WAIT() \ /* in this case, the interval count is the count-down counter \ to decide to sleep for a little bit */ \ if ((interval_burst) && (--interval_count == 0)) { \ /* call WaitForSingleObject and wait for the interval timer to get us \ out */ \ if (debug > 1) { \ fprintf(where,"about to suspend\n"); \ fflush(where); \ } \ if (WaitForSingleObject(WinTimer, INFINITE) != WAIT_OBJECT_0) { \ fprintf(where, "WaitForSingleObject failed (%d)\n", GetLastError()); \ fflush(where); \ exit(1); \ } \ interval_count = interval_burst; \ } #else #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; \ } #endif /* WIN32 */ #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 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; case NF_UNSPEC: return AF_UNSPEC; case NF_INET6: #if defined(AF_INET6) return AF_INET6; #else return AF_UNSPEC; #endif case NF_RDS: #if defined(AF_RDS) return AF_RDS; #else return AF_UNSPEC; #endif default: return AF_UNSPEC; } } int af_to_nf(int af) { switch(af) { case AF_INET: return NF_INET; case AF_UNSPEC: return NF_UNSPEC; #if defined(AF_INET6) case AF_INET6: return NF_INET6; #endif #if defined(AF_RDS) case AF_RDS: return NF_RDS; #endif default: return NF_UNSPEC; } } /* 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 #ifdef SOCK_SEQPACKET case NST_SEQPACKET: return NST_SEQPACKET; #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 #ifdef SOCK_SEQPACKET case SOCK_SEQPACKET: return NST_SEQPACKET; #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 #ifdef SOCK_SEQPACKET case SOCK_SEQPACKET: return "Seqpacket"; #endif default: return "Unknown"; } } char * protocol_to_str(int protocol) { switch(protocol) { /* ass-u-me that everyone has IPPROTO_TCP and IPPROTO_UDP */ case IPPROTO_TCP: return "TCP"; case IPPROTO_UDP: return "UDP"; /* but do not assume that everyone has the others */ #ifdef IPPROTO_UDPLITE case IPPROTO_UDPLITE: return "UDPLite"; #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 #ifdef IPPROTO_IP case IPPROTO_IP: return "IP Default"; #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(int); 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 */ } static void set_tcp_mss(SOCKET socket, int mss) { #ifdef TCP_MAXSEG netperf_socklen_t sock_opt_len; sock_opt_len = sizeof(int); if ((setsockopt(socket, getprotobyname("tcp")->p_proto, TCP_MAXSEG, (const char *)&mss, sock_opt_len) == SOCKET_ERROR) && (debug)) { fprintf(where, "netperf: %s: setsockopt TCP_MAXSEG: %s (errno %d)\n", __FUNCTION__, strerror(errno), errno); fflush(where); } #else if (debug) { fprintf(where, "netperf: %s platform does not know how to set TCP segment size\n", __FUNCTION); fflush(where); } #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|AI_ADDRCONFIG; 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) && defined(SOCK_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" "\n\tgetaddrinfo returned %d %s\n", hostname, port, family, 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" "match the requested type. Please contact your vendor for\n" "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 */ /* since it has now been two years since that bug was filed, it should be resolved by now, so the "out" given to Sun should no longer be necessary. either folks are running with the fix or they need to get the fix. raj 2011-07-06 */ if ((change_info & CHANGED_PROTOCOL) && !(change_warning_displayed & CHANGED_PROTOCOL) && (hints.ai_protocol != 0)) { change_warning_displayed |= CHANGED_PROTOCOL; fprintf(where, "WARNING! getaddrinfo returned a protocol other than the\n" "requested protocol. Please contact your vendor for\n" "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" "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" "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) { if (remote_data_family == AF_UNSPEC) { remote_data_family = control_family; } *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: #if defined(AF_RDS) case AF_RDS: #endif { 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) { #if defined(AF_RDS) case AF_RDS: #endif 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; foo->sin6_port = htons((unsigned short) port); foo->sin6_family = (unsigned short) family; memcpy(&(foo->sin6_addr),addr,sizeof(foo->sin6_addr)); 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) { #if defined(AF_RDS) case AF_RDS: #endif 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 i; struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sockaddr; *port = ntohs(sin6->sin6_port); ret = 1; for (i=0; i < sizeof(struct in6_addr); i++) if (sin6->sin6_addr.s6_addr[i] != 0) ret=0; memcpy(addr,&(sin6->sin6_addr), sizeof(sin6->sin6_addr)); break; } #endif default: fprintf(where, "get_sockaddr_family_addr_port: Unexpected Address Family of %u\n",family); fflush(where); exit(-1); } return ret; } int set_socket_tos(SOCKET sock, int family, int socket_tos) { int my_tos = -3; netperf_socklen_t sock_opt_len; switch (family) { #if defined(IP_TOS) case AF_INET: /* should I mask-away anything above the byte? */ my_tos = socket_tos; if (setsockopt(sock, IPPROTO_IP, IP_TOS, (const char *)&my_tos,sizeof(my_tos)) == SOCKET_ERROR) { fprintf(where, "%s ip_tos failed with %s (errno %d)\n", __FUNCTION__, strerror(errno), errno); fflush(where); my_tos = -2; } else { sock_opt_len = sizeof(my_tos); getsockopt(sock, IPPROTO_IP, IP_TOS, (char *)&my_tos, &sock_opt_len); } break; #endif #if defined(IPV6_TCLASS) case AF_INET6: /* should I mask-away anything above the byte? */ my_tos = socket_tos; if (setsockopt(sock, IPPROTO_IPV6, IPV6_TCLASS, (const char *)&my_tos,sizeof(my_tos)) == SOCKET_ERROR) { fprintf(where, "%s ip_tos failed with %s (errno %d)\n", __FUNCTION__, strerror(errno), errno); fflush(where); my_tos = -2; } else { sock_opt_len = sizeof(my_tos); getsockopt(sock, IPPROTO_IPV6, IPV6_TCLASS, (char *)&my_tos, &sock_opt_len); } break; #endif } return my_tos; } /* 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 = 1; int on = 1; netperf_socklen_t sock_opt_len; /*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 /* this is ancient vestigial HP-UX code that should probably go away one day */ 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; } } #endif #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; } } #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 operandi 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 ((transport_mss_req != -1) && (IPPROTO_TCP == res->ai_protocol)) { set_tcp_mss(temp_socket,transport_mss_req); } #if defined(TCP_CORK) if (loc_tcpcork > 0) { /* the user wishes for us to set TCP_CORK on the socket */ 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 */ /* well, after Knuth only knows how many years, I have finally decided to enable setting SO_KEEPALIVE on the data socket. 99 times out of 10 this should not be necessary, but that 100th time, perhaps when netperf is being (ab)used by functional testers, may benefit from it. And it may help clean-up some lingering netservers from time to time. raj 2011-06-29 */ #if defined(SO_KEEPALIVE) if (want_keepalive) { if (setsockopt(temp_socket, SOL_SOCKET, SO_KEEPALIVE, (const char *)&on, sizeof(on)) < 0) { if (debug) { fprintf(where, "%s: unable to set SO_KEEPALIVE on data socket: %s (errno %d)\n", __FUNCTION__, strerror(errno), errno); fflush(where); } } } #endif /* SO_KEEPALIVE */ /* 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: %s (errno %d)\n", strerror(errno), errno); fprintf(where," port: %d\n",get_port_number(res)); fflush(where); } } /* this one is a slightly grudgingly added backside covering for those folks who (ab)use netperf as a functional testing tool, and further compound that error by running tests on systems also connected to their site networks, and then compound it even further compound it by running UDP_STREAM tests over links that generate link-down events and so cause the traffic to be sent out the default route into their corporate network... frankly such people should not be allowed to run netperf in the first place but there we are... raj 20091026 */ #if defined (SO_DONTROUTE) if (!routing_allowed) { if (setsockopt(temp_socket, SOL_SOCKET, SO_DONTROUTE, (char *)&one, sizeof(one)) == SOCKET_ERROR) { fprintf(where, "netperf: create_data_socket: so_dontroute: errno %d\n", errno); fflush(where); } } #endif #if defined(SO_PRIORITY) if (local_socket_prio >= 0) { if (setsockopt(temp_socket, SOL_SOCKET, SO_PRIORITY, &local_socket_prio, sizeof(int)) == SOCKET_ERROR) { fprintf(where, "netperf: create_data_socket: so_priority: errno %d\n", errno); fflush(where); local_socket_prio = -2; } else { sock_opt_len = 4; getsockopt(temp_socket, SOL_SOCKET, SO_PRIORITY, &local_socket_prio, &sock_opt_len); } } #else local_socket_prio = -3; #endif #if defined (IP_TOS) || defined(IPV6_TCLASS) if (local_socket_tos > 0) local_socket_tos = set_socket_tos(temp_socket,res->ai_family, local_socket_tos); #endif 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) { char *address_buf; #ifdef AF_INET6 address_buf = malloc(INET6_ADDRSTRLEN); #else address_buf = malloc(16); /* magic constant */ #endif if (address_buf == NULL) { fprintf(where,"Unable to allocate address_buf\n"); fflush(where); exit(1); } /* 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,"%s",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"); free(address_buf); } /* if WANT_MIGRATION is defined, we will use the send_tcp_stream() call in src/nettest_omni.c */ #ifndef WANT_MIGRATION /* 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... time passes, and 64 bit types do indeed become common. */ #if defined(WIN32) && _MSC_VER <= 1200 __int64 local_bytes_sent = 0 #else unsigned long long local_bytes_sent = 0; #endif 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) { demo_first_timestamp(); } #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 && !times_up) { 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 defined(WANT_INTERVALS) #ifdef WIN32 stop_itimer(); #endif #endif /* WANT_INTERVALS */ 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. of course, time passes and they do become common. */ double bytes_sent = 0.0; #if defined(WIN32) && (_MSC_VER < 1200) __int64 local_bytes_recvd = 0; #else unsigned long long local_bytes_recvd = 0; #endif 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) { demo_first_timestamp(); } #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(); #if defined(WANT_INTERVALS) #ifdef WIN32 stop_itimer(); #endif #endif /* WANT_INTERVALS */ /* 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 */ } } #endif /* WANT_MIGRATION */ /* 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,"%s",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) { demo_first_timestamp(); } #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) { demo_first_timestamp(); } #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); #if defined(WANT_INTERVALS) #ifdef WIN32 stop_itimer(); #endif #endif /* WANT_INTERVALS */ /* 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 ) { if (times_up) { break; } 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 && !times_up) { 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. */ #ifndef WANT_MIGRATION 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) { demo_first_timestamp(); } #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 defined(WANT_INTERVALS) #ifdef WIN32 stop_itimer(); #endif #endif /* WANT_INTERVALS */ 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 */ } } #endif /* WANT_MIGRATION */ #if defined(__linux) /* * Linux has this odd behavior where if the socket buffers are larger than * a device's txqueuelen, the kernel will silently drop transmits which would * not fit into the tx queue, and not pass an ENOBUFS error back to the * application. As a result, a UDP stream test can report absurd transmit * bandwidths (like 20Gb/s on a 1GbE NIC). This behavior can be avoided if * you request extended error reporting on the socket. This is done by * setting the IP_RECVERR socket option at the IP level. */ static void enable_enobufs(int s) { struct protoent *pr; int on = 1; if ((pr = getprotobyname("ip")) == NULL) { fprintf(where, "enable_enobufs failed: getprotobyname\n"); fflush(where); return; } if (setsockopt(s, pr->p_proto, IP_RECVERR, (char *)&on, sizeof(on)) < 0) { fprintf(where, "enable_enobufs failed: setsockopt\n"); fflush(where); return; } } #endif #ifndef WANT_MIGRATION 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); } } #if defined (__linux) enable_enobufs(data_socket); #endif #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) { demo_first_timestamp(); } #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 defined(WANT_INTERVALS) #ifdef WIN32 stop_itimer(); #endif #endif /* WANT_INTERVALS */ 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 */ } #endif /* WANT_MIGRATION */ /* 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 = 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); } #ifndef WANT_MIGRATION 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) { demo_first_timestamp(); } #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 defined(WANT_INTERVALS) #ifdef WIN32 stop_itimer(); #endif #endif /* WANT_INTERVALS */ 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 */ } } #endif /* WANT_MIGRATION */ /* 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"); } #ifndef WANT_MIGRATION /* 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) { demo_first_timestamp(); } #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 */ } } #endif /* WANT_MIGRATION */ 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, 128) == 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 if (request_bytes_recvd > 0) { request_bytes_remaining -= request_bytes_recvd; temp_message_ptr += request_bytes_recvd; } else { /* for some reason the remote closed the connection on * us and that is unexpected so we should just close the * socket and move-on. for that we will use an evil goto * neener neener raj 20090622 */ goto bail; } } 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); bail: close(s_data); #else bail: 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. */ #if defined(WANT_INTERVALS) #ifdef WIN32 stop_itimer(); #endif #endif /* WANT_INTERVALS */ 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) { demo_first_timestamp(); } #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; tcp_cc_results->num_cpus = lib_num_loc_cpus; 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: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", #if _MSC_VER <= 1200 "scan_sockets_args"); #else __func__); #endif 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)); /* by default, only a UDP_STREAM test disallows routing, to cover the backsides of incompetent testers who have bogus setups */ if (strcasecmp(test_name,"UDP_STREAM") == 0) { routing_allowed = 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, 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 'R': /* enable/disable routing on the data connection*/ routing_allowed = atoi(optarg); 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,"MAERTS")) { send_size = -1; } } } netperf-2.6.0/src/nettest_omni.c0000644000175000017500000066327711770161054013575 00000000000000#ifdef HAVE_CONFIG_H #include #endif #ifdef WANT_OMNI char nettest_omni_id[]="\ @(#)nettest_omni.c (c) Copyright 2008-2012 Hewlett-Packard Co. Version 2.6.0"; #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 */ #ifndef WIN32 #include #include /* it would seem that including both and is not a path to happiness and joy when one wishes to grab tcp_info stats and not get something like the compiler complaining about either redefinitions, or missing tcpi_total_retrans. */ #ifdef HAVE_LINUX_TCP_H #include #else #include #endif #ifdef HAVE_NETINET_SCTP_H #include #endif #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) #include "missing\stdint.h" #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" /* we only really use this once, but the initial patch to src/nettest_bsd.c used it in several places. keep it as a macro just for kicks and just in case we do end-up needing to use it multiple times. */ #define WAIT_BEFORE_DATA_TRAFFIC() \ { \ if (wait_time_secs) \ sleep(wait_time_secs); \ } \ /* since someone can ask for latency stats, we will always include this and do the other other things */ #include "hist.h" static HIST time_hist; #ifdef WANT_INTERVALS int interval_count; unsigned int interval_wait_microseconds; /* hoist the timestamps up here so we can use them to factor-out the time spent "waiting" */ /* first out timestamp */ #ifdef HAVE_GETHRTIME static hrtime_t intvl_one; static hrtime_t intvl_two; static hrtime_t intvl_wait_start; 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_wait_start; 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_wait_start; 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 #ifndef WANT_SPIN #ifdef WIN32 #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; \ interval_wait_microseconds = 0; #else 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; \ interval_wait_microseconds = 0; \ /* 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", \ __FUNCTION__, \ errno); \ fflush(where); \ exit(1); \ } #endif /* WIN32 */ #ifdef WIN32 #define INTERVALS_WAIT() \ /* in this case, the interval count is the count-down counter \ to decide to sleep for a little bit */ \ if ((interval_burst) && (--interval_count == 0)) { \ /* call WaitForSingleObject and wait for the interval timer to get us \ out */ \ if (debug > 1) { \ fprintf(where,"about to suspend\n"); \ fflush(where); \ } \ HIST_timestamp(&intvl_wait_start); \ if (WaitForSingleObject(WinTimer, INFINITE) != WAIT_OBJECT_0) { \ fprintf(where, "WaitForSingleObject failed (%d)\n", GetLastError()); \ fflush(where); \ exit(1); \ } \ HIST_timestamp(&intvl_two); \ interval_wait_microseconds += \ delta_micro(&intvl_wait_start,&intvl_two); \ interval_count = interval_burst; \ } #else #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); \ } \ HIST_timestamp(&intvl_wait_start); \ if (sigsuspend(&signal_set) == EFAULT) { \ fprintf(where, \ "%s: fault with sigsuspend.\n", \ __FUNCTION__); \ fflush(where); \ exit(1); \ } \ HIST_timestamp(&intvl_two); \ interval_wait_microseconds += \ delta_micro(&intvl_wait_start,&intvl_two); \ interval_count = interval_burst; \ } #endif /* WIN32 */ #else #define INTERVALS_INIT() \ if (interval_burst) { \ HIST_timestamp(intvl_one_ptr); \ } \ interval_wait_microseconds = 0; \ 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)) { \ /* spin 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_wait_start); \ do { \ HIST_timestamp(intvl_two_ptr); } \ while(delta_micro(intvl_one_ptr,intvl_two_ptr) < interval_usecs); \ interval_wait_microseconds += \ delta_micro(&intvl_wait_start,&intvl_two); \ 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 extern void get_uuid_string(char *string, size_t size); /* a boatload of globals while I settle things out */ char *output_selection_spec = 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 was_legacy = 0; int legacy = 0; int implicit_direction = 0; int explicit_data_address = 0; uint64_t trans_completed = 0; int64_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; int32_t local_transport_retrans = -2; int32_t remote_transport_retrans = -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 = NULL; char *local_cpu_model = NULL; int local_cpu_frequency; char *remote_system_model = NULL; char *remote_cpu_model = NULL; int remote_cpu_frequency; int local_security_type_id; int local_security_enabled_num; char *local_security_type = NULL; char *local_security_enabled = NULL; char *local_security_specific = NULL; int remote_security_type_id; int remote_security_enabled_num; char *remote_security_enabled = NULL; char *remote_security_type = NULL; char *remote_security_specific = NULL; char local_cong_control[16] = ""; char remote_cong_control[16] = ""; char local_cong_control_req[16] = ""; char remote_cong_control_req[16] = ""; /* new statistics based on code diffs from Google, with raj's own personal twist added to make them compatible with the omni tests... 20100913 */ /* min and max "latency" */ int min_latency = -1, max_latency = -1; /* the percentiles */ int p50_latency = -1, p90_latency = -1, p99_latency = -1; /* mean and stddev - while the mean is reduntant with the *_RR test we keep it because it won't be for other tests */ double mean_latency = -1.0, stddev_latency = -1.0; /* default to zero to avoid randomizing */ int local_mask_len = 0; int remote_mask_len = 0; 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; enum netperf_output_type { NETPERF_TYPE_UNKNOWN, NETPERF_TYPE_UINT32, NETPERF_TYPE_INT32, NETPERF_TYPE_UINT64, NETPERF_TYPE_INT64, NETPERF_TYPE_CHAR, NETPERF_TYPE_FLOAT, NETPERF_TYPE_DOUBLE, }; /* you should add to this in the order in which they should appear in the default csv (everything) output */ enum netperf_output_name { NETPERF_OUTPUT_UNKNOWN, 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, LOCAL_TRANSPORT_RETRANS, REMOTE_TRANSPORT_RETRANS, 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, MIN_LATENCY, MAX_LATENCY, P50_LATENCY, P90_LATENCY, P99_LATENCY, MEAN_LATENCY, STDDEV_LATENCY, LOCAL_SOCKET_PRIO, REMOTE_SOCKET_PRIO, LOCAL_SOCKET_TOS, REMOTE_SOCKET_TOS, LOCAL_CONG_CONTROL, REMOTE_CONG_CONTROL, LOCAL_FILL_FILE, REMOTE_FILL_FILE, COMMAND_LINE, /* COMMAND_LINE should always be "last" */ OUTPUT_END, NETPERF_OUTPUT_MAX }; /* flags for the output groups, lower 16 bits for remote, upper 16 bits for local */ #define OMNI_WANT_REM_IFNAME 0X00000001 #define OMNI_WANT_LOC_IFNAME 0X00010000 #define OMNI_WANT_REM_IFSLOT 0X00000002 #define OMNI_WANT_LOC_IFSLOT 0X00020000 #define OMNI_WANT_REM_IFIDS 0X00000004 #define OMNI_WANT_LOC_IFIDS 0X00040000 #define OMNI_WANT_REM_DRVINFO 0X00000008 #define OMNI_WANT_LOC_DRVINFO 0X00080000 #define OMNI_WANT_STATS 0X00100010 #define OMNI_WANT_REM_CONG 0X00000020 #define OMNI_WANT_LOC_CONG 0X00200000 unsigned int desired_output_groups = 0; 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 */ enum netperf_output_type output_type; /* what type is the value? */ int output_default; /* is it included in the default output */ unsigned int output_group; /* used to avoid some lookups */ } netperf_output_elt_t; netperf_output_elt_t netperf_output_source[NETPERF_OUTPUT_MAX]; #define NETPERF_MAX_BLOCKS 4 /* let us simply use one, two-dimensional list, and either use or some of the additional dimension depending on the type of output we are doing. this should help simplify matters. raj 20110120 */ enum netperf_output_name output_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 if (connection_test) { return "Connect|Send|Recv"; } 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); } } /* does this need to become conditional on the presence of the macros or might we ass-u-me that we will not be compiled on something so old as to not have what we use? raj 20090803 */ static int is_multicast_addr(struct addrinfo *res) { switch(res->ai_family) { case AF_INET: { /* IPv4 multicast runs from 224.0.0.0 to 239.255.255.255 or 0xE0000000 to 0xEFFFFFFF. Thankfully though there are macros available to make the checks for one */ struct in_addr bar = ((struct sockaddr_in *)res->ai_addr)->sin_addr; /* and here I thought IN_MULTICAST would operate on things in network byte order??? raj 20100315 */ return IN_MULTICAST(ntohl(bar.s_addr)); } #if defined(AF_INET6) case AF_INET6: { struct in6_addr *bar = &(((struct sockaddr_in6 *)res->ai_addr)->sin6_addr); return IN6_IS_ADDR_MULTICAST(bar); } #endif default: fprintf(where, "Unexpected Address Family for Multicast Check %u\n", res->ai_family); fflush(where); return 0; /* or should we exit? */ } } static void set_multicast_ttl(SOCKET sock) { int optlen = sizeof(int); /* now set/get the TTL */ if (multicast_ttl >= 0) { if (setsockopt(sock, IPPROTO_IP, IP_TTL, (const char *)&multicast_ttl, sizeof(multicast_ttl)) == SOCKET_ERROR) { fprintf(where, "setsockopt(IP_TTL) failed errno %d\n", errno); } } if (getsockopt(sock, IPPROTO_IP, IP_TTL, (char *)&multicast_ttl, (netperf_socklen_t *)&optlen) < 0) { fprintf(where, "getsockopt(IP_TTL) failed errno %d\n", errno); multicast_ttl = -2; } } /* we presume we are only called with something which is actually a multicast address. raj 20100315 */ static void join_multicast_addr(SOCKET sock, struct addrinfo *res) { switch(res->ai_family) { case AF_INET: { struct ip_mreq mreq; struct in_addr bar = ((struct sockaddr_in *)res->ai_addr)->sin_addr; int optlen = sizeof(int); int one = 1; mreq.imr_multiaddr.s_addr=bar.s_addr; mreq.imr_interface.s_addr=htonl(INADDR_ANY); if (setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, (const char *)&mreq, sizeof(mreq)) == 0) { /* let others do the same */ if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (const char *)&one, sizeof(one)) == SOCKET_ERROR) { if (debug) { fprintf(where, "join_multicast_addr SO_REUSADDR failed errno %d\n", errno); fflush(where); } } /* now set/get the TTL */ if (multicast_ttl >= 0) { if (setsockopt(sock, IPPROTO_IP, IP_TTL, (const char *)&multicast_ttl, sizeof(multicast_ttl)) == SOCKET_ERROR) { fprintf(where, "setsockopt(IP_TTL) failed errno %d\n", errno); } } if (getsockopt(sock, IPPROTO_IP, IP_TTL, (char *)&multicast_ttl, (netperf_socklen_t *)&optlen) == SOCKET_ERROR) { fprintf(where, "getsockopt(IP_TTL) failed errno %d\n", errno); multicast_ttl = -2; } } else { if (debug) { fprintf(where, "setsockopt(IP_ADD_MEMBERSHIP) failed errno %d\n", errno); fflush(where); } } break; } case AF_INET6: { fprintf(where,"I do not know how to join an IPv6 multicast group\n"); break; } } return; } 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 = (unsigned short)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 = (unsigned short)client_port_min; } /* set up the data socket */ set_port_number(local_res, (unsigned short)myport); } /* at some point this should become a table lookup... raj 20090813 */ 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 LOCAL_TRANSPORT_RETRANS: return "LOCAL_TRANSPORT_RETRANS"; case REMOTE_TRANSPORT_RETRANS: return "REMOTE_TRANSPORT_RETRANS"; 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 MIN_LATENCY: return "MIN_LATENCY"; case MAX_LATENCY: return "MAX_LATENCY"; case P50_LATENCY: return "P50_LATENCY"; case P90_LATENCY: return "P90_LATENCY"; case P99_LATENCY: return "P99_LATENCY"; case MEAN_LATENCY: return "MEAN_LATENCY"; case STDDEV_LATENCY: return "STDDEV_LATENCY"; case LOCAL_SOCKET_PRIO: return "LOCAL_SOCKET_PRIO"; case REMOTE_SOCKET_PRIO: return "REMOTE_SOCKET_PRIO"; case LOCAL_SOCKET_TOS: return "LOCAL_SOCKET_TOS"; case REMOTE_SOCKET_TOS: return "REMOTE_SOCKET_TOS"; case LOCAL_CONG_CONTROL: return "LOCAL_CONG_CONTROL"; case REMOTE_CONG_CONTROL: return "REMOTE_CONG_CONTROL"; case LOCAL_FILL_FILE: return "LOCAL_FILL_FILE"; case REMOTE_FILL_FILE: return "REMOTE_FILL_FILE"; 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 i,j; for (i = 0; i < NETPERF_MAX_BLOCKS; i++) { fprintf(where,"Output Block %d\n",i + 1); for (j = 0; j < NETPERF_OUTPUT_MAX; j++) { fprintf(where,"%s ",netperf_output_enum_to_str(output_list[i][j])); } fprintf(where,"\n"); } fflush(where); } void dump_netperf_output_choices(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" "\tmax_line_len %d tot_line_len %d display_value %p\n" "\tline[0]: |%s|\n" "\tline[1]: |%s|\n" "\tline[2]: |%s|\n" "\tline[3]: |%s|\n" "\tbrief: |%s|\n" "\tformat: |%s|\n", netperf_output_enum_to_str(netperf_output_source[i].output_name), netperf_output_source[i].max_line_len, netperf_output_source[i].tot_line_len, netperf_output_source[i].display_value, (netperf_output_source[i].line[0] == NULL) ? "" : netperf_output_source[i].line[0], (netperf_output_source[i].line[1] == NULL) ? "" : netperf_output_source[i].line[1], (netperf_output_source[i].line[2] == NULL) ? "" : netperf_output_source[i].line[2], (netperf_output_source[i].line[3] == NULL) ? "" : netperf_output_source[i].line[3], (netperf_output_source[i].brief == NULL) ? "" : netperf_output_source[i].brief, (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_mnenomic(char *candidate) { enum netperf_output_name name; for (name = OUTPUT_NONE; name < NETPERF_OUTPUT_MAX; name++) { if(!strcasecmp(candidate,netperf_output_enum_to_str(name))) return name; } return NETPERF_OUTPUT_UNKNOWN; } 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 set_output_list_all() { 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_list[i][j++] = k; desired_output_groups |= netperf_output_source[k].output_group; } /* Line Two LOCAL_CPU_UTIL to TRANSPORT_MSS */ i = 1; j = 0; for (k = LOCAL_CPU_UTIL; k <= TRANSPORT_MSS; k++) { output_list[i][j++] = k; desired_output_groups |= netperf_output_source[k].output_group; } /* Line Three LOCAL_SEND_THROUGHPUT throught REMOTE_CORK */ i = 2; j = 0; for (k = LOCAL_SEND_THROUGHPUT; k <= REMOTE_CORK; k++) { output_list[i][j++] = k; desired_output_groups |= netperf_output_source[k].output_group; } /* Line Four LOCAL_SYSNAME through COMMAND_LINE */ i = 3; j = 0; for (k = LOCAL_SYSNAME; k <= COMMAND_LINE; k++) { output_list[i][j++] = k; desired_output_groups |= netperf_output_source[k].output_group; } } void parse_output_selection_file(char *selection_file) { FILE *selections; char name[81]; /* best be more than enough */ int namepos; int c; int j; int line,column; selections = fopen(selection_file,"r"); if (!selections) { fprintf(where, "Could not open output selection file '%s' errno %d\n", selection_file, errno); fflush(where); 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_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_list[line++][j++] = match_string_to_output(name); namepos = 0; j = 0; } else if (isprint(c)) { name[namepos++] = (char)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_list[line][j] = match_string_to_output(name); } } void parse_output_selection_line(int line, char *list) { char *token; int j; enum netperf_output_name name; /* belt and suspenders */ if (line < 0) { fprintf(where, "parse_output_selection_line called with negative line number %d\n",line); fflush(where); exit(-1); } /* silently ignore extra lines and only warn if debug is set */ if (line >= NETPERF_MAX_BLOCKS) { if (debug) { fprintf(where, "There can be no more than %d output selection lines." " Ignoring output selection line %d |%s|\n", NETPERF_MAX_BLOCKS, line + 1, list); fflush(where); } return; } j=0; token = strtok(list," ,"); while ((token) && (j < NETPERF_OUTPUT_MAX)) { name = match_string_to_output_mnenomic(token); if ((name == NETPERF_OUTPUT_UNKNOWN) && (debug)) { fprintf(where,"Ignoring unknown output selector %d |%s| on line %d\n", j + 1, token, line +1); fflush(where); } else { output_list[line][j] = name; desired_output_groups |= netperf_output_source[name].output_group; j++; } token = strtok(NULL," ,"); } if ((token) && (debug)) { fprintf(where, "There can be no more than %d output selectors per line. " "Ignoring remaining selectors on line %d\n", NETPERF_OUTPUT_MAX,line +1); fflush(where); } } void parse_output_selection_direct(char *output_selection) { char *source,*line,*remainder,*temp; char *f1, *f2, *f3; int i,len,done; len = strlen(output_selection); source = strdup(output_selection); line = (char *) malloc(len+1); remainder = (char *) malloc(len+1); if ((NULL == source) || (NULL == line) || (NULL == remainder)) { fprintf(where,"Unable to malloc memory for output selection parsing\n"); fflush(where); exit(-1); } f1 = source; f2 = line; f3 = remainder; i = 0; done = 0; do { break_args_explicit_sep(source,';',line,remainder); if (line[0]) { parse_output_selection_line(i,line); } if (remainder[0]) { temp = source; source = remainder; remainder = temp; i++; /* if (i == NETPERF_MAX_BLOCKS) { fprintf(where, "Too many output blocks requested, maximum is %d\n", NETPERF_MAX_BLOCKS); fflush(where); exit(-1); } */ continue; } else { done = 1; } } while (!done); free(f1); free(f2); free(f3); } /* building blocks for output selection */ #define NETPERF_TPUT "ELAPSED_TIME,THROUGHPUT,THROUGHPUT_UNITS" #define NETPERF_OUTPUT_STREAM "LSS_SIZE_END,RSR_SIZE_END,LOCAL_SEND_SIZE" #define NETPERF_OUTPUT_MAERTS "RSS_SIZE_END,LSR_SIZE_END,REMOTE_SEND_SIZE" #define NETPERF_CPU "LOCAL_CPU_UTIL,LOCAL_CPU_METHOD,REMOTE_CPU_UTIL,REMOTE_CPU_METHOD,LOCAL_SD,REMOTE_SD,SD_UNITS" #define NETPERF_RR "LSS_SIZE_END,LSR_SIZE_END,RSR_SIZE_END,RSS_SIZE_END,REQUEST_SIZE,RESPONSE_SIZE" void set_output_list_by_test() { char *stream_no_cpu = NETPERF_OUTPUT_STREAM "," NETPERF_TPUT; char *stream_cpu = NETPERF_OUTPUT_STREAM "," NETPERF_TPUT "," NETPERF_CPU; char *maerts_no_cpu = NETPERF_OUTPUT_MAERTS "," NETPERF_TPUT; char *maerts_cpu = NETPERF_OUTPUT_MAERTS "," NETPERF_TPUT "," NETPERF_CPU; char *rr_no_cpu = NETPERF_RR "," NETPERF_TPUT; char *rr_cpu = NETPERF_RR "," NETPERF_TPUT "," NETPERF_CPU; if (debug) { fprintf(where,"%s setting the output list by test\n", __FUNCTION__); fflush(where); } if (NETPERF_XMIT_ONLY(direction)) { if (!(local_cpu_usage || remote_cpu_usage)) parse_output_selection_direct(stream_no_cpu); else parse_output_selection_direct(stream_cpu); } else if (NETPERF_RECV_ONLY(direction)) { if (!(local_cpu_usage || remote_cpu_usage)) parse_output_selection_direct(maerts_no_cpu); else parse_output_selection_direct(maerts_cpu); } else if (NETPERF_CC(direction)) { if (!(local_cpu_usage || remote_cpu_usage)) parse_output_selection_direct(rr_no_cpu); else parse_output_selection_direct(rr_cpu); } else if (NETPERF_IS_RR(direction)) { if (!(local_cpu_usage || remote_cpu_usage)) parse_output_selection_direct(rr_no_cpu); else parse_output_selection_direct(rr_cpu); } else { /* no idea */ if (debug) { fprintf(where,"Cannot determine default test output, using mins\n"); fflush(where); } parse_output_selection_direct(NETPERF_TPUT "," NETPERF_CPU); } } void parse_output_selection(char *output_selection) { if (debug) { fprintf(where,"%s is parsing the output selection '%s'\n", __FUNCTION__, output_selection); fflush(where); } /* is it the magic keyword? */ if (strcasecmp(output_selection,"all") == 0) { set_output_list_all(); } /* do not forget the case when the output_selection is a single mnemonic without any separators... */ else if (strchr(output_selection,',') || strchr(output_selection,';') || (match_string_to_output_mnenomic(output_selection) != NETPERF_OUTPUT_UNKNOWN)) { parse_output_selection_direct(output_selection); } else { parse_output_selection_file(output_selection); } if (debug > 2) { dump_netperf_output_list(stderr); } return; } static void set_output_elt(enum netperf_output_name name, char *line0, char *line1, char *line2, char *line3, char *format, void *value, unsigned int out_default, unsigned int group, enum netperf_output_type type) { netperf_output_source[name].output_name = name; netperf_output_source[name].line[0] = line0; netperf_output_source[name].line[1] = line1; netperf_output_source[name].line[2] = line2; netperf_output_source[name].line[3] = line3; netperf_output_source[name].format = format; netperf_output_source[name].display_value = value; netperf_output_source[name].output_default = out_default; netperf_output_source[name].output_group = group; netperf_output_source[name].max_line_len = NETPERF_LINE_MAX(name); netperf_output_source[name].tot_line_len = NETPERF_LINE_TOT(name); netperf_output_source[name].output_type = type; } void print_omni_init_list() { int i; if (debug) { fprintf(where,"%s called\n", __FUNCTION__); } /* belts and suspenders everyone... */ for (i = NETPERF_OUTPUT_UNKNOWN; 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[i].output_default = 1; netperf_output_source[i].output_group = 0; netperf_output_source[i].output_type = NETPERF_TYPE_UNKNOWN; } set_output_elt(OUTPUT_NONE, " ", "", "", "", "%s", &" ",1, 0, NETPERF_TYPE_CHAR); set_output_elt(COMMAND_LINE, "Command","Line","","","\"%s\"", command_line,1, 0, NETPERF_TYPE_CHAR); set_output_elt(UUID, "Test", "UUID", "", "", "%s", test_uuid, 1, 0, NETPERF_TYPE_CHAR); set_output_elt(RESULT_BRAND, "Result", "Tag", "", "", "\"%s\"", result_brand, 1, 0, NETPERF_TYPE_CHAR); set_output_elt(SOCKET_TYPE, "Socket", "Type", "", "", "%s", socket_type_str, 1, 0, NETPERF_TYPE_CHAR); set_output_elt(DIRECTION, "Direction", "", "", "", "%s", direction_str, 1, 0, NETPERF_TYPE_CHAR); set_output_elt(PROTOCOL, "Protocol", "", "", "", "%s", protocol_str, 1, 0, NETPERF_TYPE_CHAR); set_output_elt(ELAPSED_TIME, "Elapsed", "Time", "(sec)", "", "%.2f", &elapsed_time_double, 1, 0, NETPERF_TYPE_DOUBLE); set_output_elt(SOURCE_PORT, "Source", "Port", "", "", "%s", local_data_port, 1, 0, NETPERF_TYPE_CHAR); set_output_elt(SOURCE_ADDR, "Source", "Address", "", "", "%s", local_data_address, 1, 0, NETPERF_TYPE_CHAR); set_output_elt(SOURCE_FAMILY, "Source", "Family", "", "", "%d", &local_data_family, 1, 0, NETPERF_TYPE_INT32); set_output_elt(DEST_PORT, "Destination", "Port", "", "", "%s", remote_data_port, 1, 0, NETPERF_TYPE_CHAR); set_output_elt(DEST_ADDR, "Destination", "Address", "", "", "%s", remote_data_address, 1, 0, NETPERF_TYPE_CHAR); set_output_elt(DEST_FAMILY, "Destination", "Family", "", "", "%d", &remote_data_family, 1, 0, NETPERF_TYPE_INT32); set_output_elt(THROUGHPUT, "Throughput", "", "", "", "%.2f", &thruput, 1, 0, NETPERF_TYPE_DOUBLE); set_output_elt(LOCAL_SEND_THROUGHPUT, "Local", "Send", "Throughput", "", "%.2f", &local_send_thruput, 1, 0, NETPERF_TYPE_DOUBLE); set_output_elt(LOCAL_RECV_THROUGHPUT, "Local", "Recv", "Throughput", "", "%.2f", &local_recv_thruput, 1, 0, NETPERF_TYPE_DOUBLE); set_output_elt(REMOTE_SEND_THROUGHPUT, "Remote", "Send", "Throughput", "", "%.2f", &remote_send_thruput, 1, 0, NETPERF_TYPE_DOUBLE); set_output_elt(REMOTE_RECV_THROUGHPUT, "Remote", "Recv", "Throughput", "", "%.2f", &remote_recv_thruput, 1, 0, NETPERF_TYPE_DOUBLE); set_output_elt(THROUGHPUT_UNITS, "Throughput", "Units", "", "", "%s/s", thruput_format_str, 1, 0, NETPERF_TYPE_CHAR); set_output_elt(CONFIDENCE_LEVEL, "Confidence", "Level", "Percent", "", "%d", &confidence_level, 1, 0, NETPERF_TYPE_INT32); set_output_elt(CONFIDENCE_INTERVAL, "Confidence", "Width", "Target", "", "%f", &interval_pct, 1, 0, NETPERF_TYPE_DOUBLE); set_output_elt(CONFIDENCE_ITERATION, "Confidence", "Iterations", "Run", "", "%d", &confidence_iteration, 1, 0, NETPERF_TYPE_INT32); set_output_elt(THROUGHPUT_CONFID, "Throughput", "Confidence", "Width (%)", "", "%.3f", &result_confid_pct, 1, 0, NETPERF_TYPE_DOUBLE); set_output_elt(LOCAL_CPU_CONFID, "Local", "CPU", "Confidence", "Width (%)", "%.3f", &loc_cpu_confid_pct, 1, 0, NETPERF_TYPE_DOUBLE); set_output_elt(REMOTE_CPU_CONFID, "Remote", "CPU", "Confidence", "Width (%)", "%.3f", &rem_cpu_confid_pct, 1, 0, NETPERF_TYPE_DOUBLE); set_output_elt(RT_LATENCY, "Round", "Trip", "Latency", "usec/tran", "%.3f", &rtt_latency, 1, 0, NETPERF_TYPE_DOUBLE); set_output_elt(TRANSACTION_RATE, "Transaction", "Rate", "Tran/s", "", "%.3f", &transaction_rate, 1, 0, NETPERF_TYPE_DOUBLE); set_output_elt(TRANSPORT_MSS, "Transport", "MSS", "bytes", "", "%d", &transport_mss, 1, 0, NETPERF_TYPE_INT32); set_output_elt(LOCAL_TRANSPORT_RETRANS, "Local", "Transport", "Retransmissions", "", "%d", &local_transport_retrans, 1, 0, NETPERF_TYPE_INT32); set_output_elt(REMOTE_TRANSPORT_RETRANS, "Remote", "Transport", "Retransmissions", "", "%d", &remote_transport_retrans, 1, 0, NETPERF_TYPE_INT32); set_output_elt(REQUEST_SIZE, "Request", "Size", "Bytes", "", "%d", &req_size, 1, 0, NETPERF_TYPE_INT32); set_output_elt(RESPONSE_SIZE, "Response", "Size", "Bytes", "", "%d", &rsp_size, 1, 0, NETPERF_TYPE_INT32); set_output_elt(BURST_SIZE, "Initial", "Burst", "Requests", "", "%d", &first_burst_size, 1, 0, NETPERF_TYPE_INT32); set_output_elt(LSS_SIZE_REQ, "Local", "Send Socket", "Size", "Requested", "%d", &lss_size_req, 1, 0, NETPERF_TYPE_INT32); set_output_elt(LSS_SIZE, "Local", "Send Socket", "Size", "Initial", "%d", &lss_size, 1, 0, NETPERF_TYPE_INT32); set_output_elt(LSS_SIZE_END, "Local", "Send Socket", "Size", "Final", "%d", &lss_size_end, 1, 0, NETPERF_TYPE_INT32); set_output_elt(LSR_SIZE_REQ, "Local", "Recv Socket", "Size", "Requested", "%d", &lsr_size_req, 1, 0, NETPERF_TYPE_INT32); set_output_elt(LSR_SIZE, "Local", "Recv Socket", "Size", "Initial", "%d", &lsr_size, 1, 0, NETPERF_TYPE_INT32); set_output_elt(LSR_SIZE_END, "Local", "Recv Socket", "Size", "Final", "%d", &lsr_size_end, 1, 0, NETPERF_TYPE_INT32); set_output_elt(LOCAL_SEND_SIZE, "Local", "Send", "Size", "", "%d", &send_size, 1, 0, NETPERF_TYPE_INT32); set_output_elt(LOCAL_RECV_SIZE, "Local", "Recv", "Size", "", "%d", &recv_size, 1, 0, NETPERF_TYPE_INT32); set_output_elt(LOCAL_SEND_CALLS, "Local", "Send", "Calls", "", "%"PRIu64, &local_send_calls, 1, 0, NETPERF_TYPE_UINT64); set_output_elt(LOCAL_RECV_CALLS, "Local", "Recv", "Calls", "", "%"PRIu64, &local_receive_calls, 1, 0, NETPERF_TYPE_UINT64); set_output_elt(LOCAL_BYTES_PER_RECV, "Local", "Bytes", "Per", "Recv", "%.2f", &bytes_per_recv, 1, 0, NETPERF_TYPE_DOUBLE); set_output_elt(LOCAL_BYTES_PER_SEND, "Local", "Bytes", "Per", "Send", "%.2f", &bytes_per_send, 1, 0, NETPERF_TYPE_DOUBLE); set_output_elt(LOCAL_BYTES_RECVD, "Local", "Bytes", "Received", "", "%"PRIu64, &bytes_received, 1, 0, NETPERF_TYPE_UINT64); set_output_elt(LOCAL_BYTES_SENT, "Local", "Bytes", "Sent", "", "%"PRIu64, &bytes_sent, 1, 0, NETPERF_TYPE_UINT64); set_output_elt(LOCAL_BYTES_XFERD, "Local", "Bytes", "Xferred", "", "%.0f", &bytes_xferd, 1, 0, NETPERF_TYPE_DOUBLE); set_output_elt(LOCAL_SEND_WIDTH, "Local", "Send", "Width", "", "%d", &send_width, 1, 0, NETPERF_TYPE_INT32); set_output_elt(LOCAL_RECV_WIDTH, "Local", "Recv", "Width", "", "%d", &recv_width, 1, 0, NETPERF_TYPE_INT32); set_output_elt(LOCAL_SEND_OFFSET, "Local", "Send", "Offset", "", "%d", &local_send_offset, 1, 0, NETPERF_TYPE_INT32); set_output_elt(LOCAL_RECV_OFFSET, "Local", "Recv", "Offset", "", "%d", &local_recv_offset, 1, 0, NETPERF_TYPE_INT32); set_output_elt(LOCAL_RECV_ALIGN, "Local", "Recv", "Alignment", "", "%d", &local_recv_align, 1, 0, NETPERF_TYPE_INT32); set_output_elt(LOCAL_SEND_ALIGN, "Local", "Send", "Alignment", "", "%d", &local_send_align, 1, 0, NETPERF_TYPE_INT32); set_output_elt(LOCAL_SEND_DIRTY_COUNT, "Local", "Send", "Dirty", "Count", "%d", &loc_dirty_count, 1, 0, NETPERF_TYPE_INT32); set_output_elt(LOCAL_RECV_DIRTY_COUNT, "Local", "Recv", "Dirty", "Count", "%d", &loc_dirty_count, 1, 0, NETPERF_TYPE_INT32); set_output_elt(LOCAL_RECV_CLEAN_COUNT, "Local", "Recv", "Clean", "Count", "%d", &loc_clean_count, 1, 0, NETPERF_TYPE_INT32); set_output_elt(LOCAL_CPU_UTIL, "Local", "CPU", "Util", "%", "%.2f", &local_cpu_utilization_double, 1, 0, NETPERF_TYPE_DOUBLE); set_output_elt(LOCAL_CPU_PEAK_UTIL, "Local", "Peak", "Per CPU", "Util %", "%.2f", &lib_local_peak_cpu_util, 1, 0, NETPERF_TYPE_DOUBLE); set_output_elt(LOCAL_CPU_PEAK_ID, "Local", "Peak", "Per CPU", "ID", "%d", &lib_local_peak_cpu_id, 1, 0, NETPERF_TYPE_INT32); set_output_elt(LOCAL_CPU_BIND, "Local", "CPU", "Bind", "", "%d", &local_proc_affinity, 1, 0, NETPERF_TYPE_INT32); set_output_elt(LOCAL_SD, "Local", "Service", "Demand", "", "%.3f", &local_service_demand_double, 1, 0, NETPERF_TYPE_DOUBLE); set_output_elt(SD_UNITS, "Service", "Demand", "Units", "", "%s", sd_str, 1, 0, NETPERF_TYPE_CHAR); set_output_elt(LOCAL_CPU_METHOD, "Local", "CPU", "Util", "Method", "%c", &local_cpu_method, 1, 0, NETPERF_TYPE_INT32); set_output_elt(LOCAL_CPU_COUNT, "Local", "CPU", "Count", "", "%d", &lib_num_loc_cpus, 1, 0, NETPERF_TYPE_INT32); set_output_elt(LOCAL_NODELAY, "Local", "NODELAY", "", "", "%d", &loc_nodelay, 1, 0, NETPERF_TYPE_INT32); set_output_elt(LOCAL_CORK, "Local", "Cork", "", "", "%d", &loc_tcpcork, 1, 0, NETPERF_TYPE_INT32); set_output_elt(RSS_SIZE_REQ, "Remote", "Send Socket", "Size", "Requested", "%d", &rss_size_req, 1, 0, NETPERF_TYPE_INT32); set_output_elt(RSS_SIZE, "Remote", "Send Socket", "Size", "Initial", "%d", &rss_size, 1, 0, NETPERF_TYPE_INT32); set_output_elt(RSS_SIZE_END, "Remote", "Send Socket", "Size", "Final", "%d", &rss_size_end, 1, 0, NETPERF_TYPE_INT32); set_output_elt(RSR_SIZE_REQ, "Remote", "Recv Socket", "Size", "Requested", "%d", &rsr_size_req, 1, 0, NETPERF_TYPE_INT32); set_output_elt(RSR_SIZE, "Remote", "Recv Socket", "Size", "Initial", "%d", &rsr_size, 1, 0, NETPERF_TYPE_INT32); set_output_elt(RSR_SIZE_END, "Remote", "Recv Socket", "Size", "Final", "%d", &rsr_size_end, 1, 0, NETPERF_TYPE_INT32); set_output_elt(REMOTE_SEND_SIZE, "Remote", "Send", "Size", "", "%d", &remote_send_size, 1, 0, NETPERF_TYPE_INT32); set_output_elt(REMOTE_RECV_SIZE, "Remote", "Recv", "Size", "", "%d", &remote_recv_size, 1, 0, NETPERF_TYPE_INT32); set_output_elt(REMOTE_SEND_CALLS, "Remote", "Send", "Calls", "", "%"PRIu64, &remote_send_calls, 1, 0, NETPERF_TYPE_UINT64); set_output_elt(REMOTE_RECV_CALLS, "Remote", "Recv", "Calls", "", "%"PRIu64, &remote_receive_calls, 1, 0, NETPERF_TYPE_UINT64); set_output_elt(REMOTE_BYTES_PER_RECV, "Remote", "Bytes", "Per", "Recv", "%.2f", &remote_bytes_per_recv, 1, 0, NETPERF_TYPE_DOUBLE); set_output_elt(REMOTE_BYTES_PER_SEND, "Remote", "Bytes", "Per", "Send", "%.2f", &remote_bytes_per_send, 1, 0, NETPERF_TYPE_DOUBLE); set_output_elt(REMOTE_BYTES_RECVD, "Remote", "Bytes", "Received", "", "%"PRIu64, &remote_bytes_received, 1, 0, NETPERF_TYPE_UINT64); set_output_elt(REMOTE_BYTES_SENT, "Remote", "Bytes", "Sent", "", "%"PRIu64, &remote_bytes_sent, 1, 0, NETPERF_TYPE_UINT64); set_output_elt(REMOTE_BYTES_XFERD, "Remote", "Bytes", "Xferred", "", "%.0f", &remote_bytes_xferd, 1, 0, NETPERF_TYPE_DOUBLE); set_output_elt(REMOTE_SEND_WIDTH, "Remote", "Send", "Width", "", "%d", &remote_send_width, 1, 0, NETPERF_TYPE_INT32); set_output_elt(REMOTE_RECV_WIDTH, "Remote", "Recv", "Width", "", "%d", &remote_recv_width, 1, 0, NETPERF_TYPE_INT32); set_output_elt(REMOTE_SEND_OFFSET, "Remote", "Send", "Offset", "", "%d", &remote_send_offset, 1, 0, NETPERF_TYPE_INT32); set_output_elt(REMOTE_RECV_OFFSET, "Remote", "Recv", "Offset", "", "%d", &remote_recv_offset, 1, 0, NETPERF_TYPE_INT32); set_output_elt(REMOTE_RECV_ALIGN, "Remote", "Recv", "Alignment", "", "%d", &remote_recv_align, 1, 0, NETPERF_TYPE_INT32); set_output_elt(REMOTE_SEND_ALIGN, "Remote", "Send", "Alignment", "", "%d", &remote_send_align, 1, 0, NETPERF_TYPE_INT32); set_output_elt(REMOTE_SEND_DIRTY_COUNT, "Remote", "Send", "Dirty", "Count", "%d", &rem_dirty_count, 1, 0, NETPERF_TYPE_INT32); set_output_elt(REMOTE_RECV_DIRTY_COUNT, "Remote", "Recv", "Dirty", "Count", "%d", &rem_dirty_count, 1, 0, NETPERF_TYPE_INT32); set_output_elt(REMOTE_RECV_CLEAN_COUNT, "Remote", "Recv", "Clean", "Count", "%d", &rem_clean_count, 1, 0, NETPERF_TYPE_INT32); set_output_elt(REMOTE_CPU_UTIL, "Remote", "CPU", "Util", "%", "%.2f", &remote_cpu_utilization_double, 1, 0, NETPERF_TYPE_DOUBLE); set_output_elt(REMOTE_CPU_PEAK_UTIL, "Remote", "Peak", "Per CPU", "Util %", "%.2f", &lib_remote_peak_cpu_util, 1, 0, NETPERF_TYPE_DOUBLE); set_output_elt(REMOTE_CPU_PEAK_ID, "Remote", "Peak", "Per CPU", "ID", "%d", &lib_remote_peak_cpu_id, 1, 0, NETPERF_TYPE_INT32); set_output_elt(REMOTE_CPU_BIND, "Remote", "CPU", "Bind", "", "%d", &remote_proc_affinity, 1, 0, NETPERF_TYPE_INT32); set_output_elt(REMOTE_SD, "Remote", "Service", "Demand", "", "%.3f", &remote_service_demand_double, 1, 0, NETPERF_TYPE_DOUBLE); set_output_elt(REMOTE_CPU_METHOD, "Remote", "CPU", "Util", "Method", "%c", &remote_cpu_method, 1, 0, NETPERF_TYPE_INT32); set_output_elt(REMOTE_CPU_COUNT, "Remote", "CPU", "Count", "", "%d", &lib_num_rem_cpus, 1, 0, NETPERF_TYPE_INT32); set_output_elt(REMOTE_NODELAY, "Remote", "NODELAY", "", "", "%d", &rem_nodelay, 1, 0, NETPERF_TYPE_INT32); set_output_elt(REMOTE_CORK, "Remote", "Cork", "", "", "%d", &rem_tcpcork, 1, 0, NETPERF_TYPE_INT32); set_output_elt(LOCAL_DRIVER_NAME, "Local", "Driver", "Name", "", "%s", local_driver_name, 1, OMNI_WANT_LOC_DRVINFO, NETPERF_TYPE_CHAR); set_output_elt(LOCAL_DRIVER_VERSION, "Local", "Driver", "Version", "", "%s", local_driver_version, 1, OMNI_WANT_LOC_DRVINFO, NETPERF_TYPE_CHAR); set_output_elt(LOCAL_DRIVER_FIRMWARE, "Local", "Driver", "Firmware", "", "%s", local_driver_firmware, 1, OMNI_WANT_LOC_DRVINFO, NETPERF_TYPE_CHAR); set_output_elt(LOCAL_DRIVER_BUS, "Local", "Driver", "Bus", "", "%s", local_driver_bus, 1, OMNI_WANT_LOC_DRVINFO, NETPERF_TYPE_CHAR); set_output_elt(REMOTE_DRIVER_NAME, "Remote", "Driver", "Name", "", "%s", remote_driver_name, 1, OMNI_WANT_REM_DRVINFO, NETPERF_TYPE_CHAR); set_output_elt(REMOTE_DRIVER_VERSION, "Remote", "Driver", "Version", "", "%s", remote_driver_version, 1, OMNI_WANT_REM_DRVINFO, NETPERF_TYPE_CHAR); set_output_elt(REMOTE_DRIVER_FIRMWARE, "Remote", "Driver", "Firmware", "", "%s", remote_driver_firmware, 1, OMNI_WANT_REM_DRVINFO, NETPERF_TYPE_CHAR); set_output_elt(REMOTE_DRIVER_BUS, "Remote", "Driver", "Bus", "", "%s", remote_driver_bus, 1, OMNI_WANT_REM_DRVINFO, NETPERF_TYPE_CHAR); set_output_elt(LOCAL_INTERFACE_SUBDEVICE, "Local", "Interface", "Subdevice", "", "0x%.4x", &local_interface_subdevice, 1, OMNI_WANT_LOC_IFIDS, NETPERF_TYPE_INT32); set_output_elt(LOCAL_INTERFACE_DEVICE, "Local", "Interface", "Device", "", "0x%.4x", &local_interface_device, 1, OMNI_WANT_LOC_IFIDS, NETPERF_TYPE_INT32); set_output_elt(LOCAL_INTERFACE_SUBVENDOR, "Local", "Interface", "Subvendor", "", "0x%.4x", &local_interface_subvendor, 1, OMNI_WANT_LOC_IFIDS, NETPERF_TYPE_UINT32); set_output_elt(LOCAL_INTERFACE_VENDOR, "Local", "Interface", "Vendor", "", "0x%.4x", &local_interface_vendor, 1, OMNI_WANT_LOC_IFIDS, NETPERF_TYPE_UINT32); set_output_elt(REMOTE_INTERFACE_SUBDEVICE, "Remote", "Interface", "Subdevice", "", "0x%.4x", &remote_interface_subdevice, 1, OMNI_WANT_REM_IFIDS, NETPERF_TYPE_UINT32); set_output_elt(REMOTE_INTERFACE_DEVICE, "Remote", "Interface", "Device", "", "0x%.4x", &remote_interface_device, 1, OMNI_WANT_REM_IFIDS, NETPERF_TYPE_UINT32); set_output_elt(REMOTE_INTERFACE_SUBVENDOR, "Remote", "Interface", "Subvendor", "", "0x%.4x", &remote_interface_subvendor, 1, OMNI_WANT_REM_IFIDS, NETPERF_TYPE_UINT32); set_output_elt(REMOTE_INTERFACE_VENDOR, "Remote", "Interface", "Vendor", "", "0x%.4x", &remote_interface_vendor, 1, OMNI_WANT_REM_IFIDS, NETPERF_TYPE_UINT32); set_output_elt(LOCAL_INTERFACE_NAME, "Local", "Interface", "Name", "", "%s", local_interface_name, 1, OMNI_WANT_LOC_IFNAME, NETPERF_TYPE_CHAR); set_output_elt(REMOTE_INTERFACE_NAME, "Remote", "Interface", "Name", "", "%s", remote_interface_name, 1, OMNI_WANT_REM_IFNAME, NETPERF_TYPE_CHAR); set_output_elt(LOCAL_INTERFACE_SLOT, "Local", "Interface", "Slot", "", "%s", local_interface_slot, 1, OMNI_WANT_LOC_IFSLOT, NETPERF_TYPE_CHAR); set_output_elt(REMOTE_INTERFACE_SLOT, "Remote", "Interface", "Slot", "", "%s", remote_interface_slot, 1, OMNI_WANT_REM_IFSLOT, NETPERF_TYPE_CHAR); set_output_elt(REMOTE_MACHINE, "Remote", "Machine", "", "", "%s", remote_machine, 1, 0, NETPERF_TYPE_CHAR); set_output_elt(REMOTE_VERSION, "Remote", "Version", "", "", "%s", remote_version, 1, 0, NETPERF_TYPE_CHAR); set_output_elt(REMOTE_RELEASE, "Remote", "Release", "", "", "%s", remote_release, 1, 0, NETPERF_TYPE_CHAR); set_output_elt(REMOTE_SYSNAME, "Remote", "Sysname", "", "", "%s", remote_sysname, 1, 0, NETPERF_TYPE_CHAR); set_output_elt(LOCAL_MACHINE, "Local", "Machine", "", "", "%s", local_machine, 1, 0, NETPERF_TYPE_CHAR); set_output_elt(LOCAL_VERSION, "Local", "Version", "", "", "%s", local_version, 1, 0, NETPERF_TYPE_CHAR); set_output_elt(LOCAL_RELEASE, "Local", "Release", "", "", "%s", local_release, 1, 0, NETPERF_TYPE_CHAR); set_output_elt(LOCAL_SYSNAME, "Local", "Sysname", "", "", "%s", local_sysname, 1, 0, NETPERF_TYPE_CHAR); set_output_elt(REMOTE_INTERVAL_USECS, "Remote", "Interval", "Usecs", "", "%d", &remote_interval_usecs, 1, 0, NETPERF_TYPE_INT32); set_output_elt(REMOTE_INTERVAL_BURST, "Remote", "Interval", "Burst", "", "%d", &remote_interval_burst, 1, 0, NETPERF_TYPE_INT32); set_output_elt(LOCAL_SECURITY_ENABLED, "Local", "OS", "Security", "Enabled", "%s", local_security_enabled, 1, 0, NETPERF_TYPE_CHAR); set_output_elt(LOCAL_SECURITY_TYPE, "Local", "OS", "Security", "Type", "%s", local_security_type, 1, 0, NETPERF_TYPE_CHAR); set_output_elt(LOCAL_SECURITY_SPECIFIC, "Local", "OS", "Security", "Specific", "%s", local_security_specific, 1, 0, NETPERF_TYPE_CHAR); set_output_elt(LOCAL_SECURITY_ENABLED_NUM, "Local", "OS", "Security", "Enabled Num", "%d", &local_security_enabled_num, 1, 0, NETPERF_TYPE_INT32); set_output_elt(LOCAL_SECURITY_TYPE_ID, "Local", "OS", "Security", "Type ID", "%d", &local_security_type_id, 1, 0, NETPERF_TYPE_INT32); set_output_elt(REMOTE_SECURITY_ENABLED, "Remote", "OS", "Security", "Enabled", "%s", remote_security_enabled, 1, 0, NETPERF_TYPE_CHAR); set_output_elt(REMOTE_SECURITY_TYPE, "Remote", "OS", "Security", "Type", "%s", remote_security_type, 1, 0, NETPERF_TYPE_CHAR); set_output_elt(REMOTE_SECURITY_SPECIFIC, "Remote", "OS", "Security", "Specific", "%s", remote_security_specific, 1, 0, NETPERF_TYPE_CHAR); set_output_elt(REMOTE_SECURITY_ENABLED_NUM, "Remote", "OS", "Security", "Enabled", "%d", &remote_security_enabled_num, 1, 0, NETPERF_TYPE_INT32); set_output_elt(REMOTE_SECURITY_TYPE_ID, "Remote", "OS", "Security", "Type", "%d", &remote_security_type_id, 1, 0, NETPERF_TYPE_INT32); set_output_elt(LOCAL_INTERVAL_USECS, "Local", "Interval", "Usecs", "", "%d", &interval_usecs, 1, 0, NETPERF_TYPE_INT32); set_output_elt(LOCAL_INTERVAL_BURST, "Local", "Interval", "Burst", "", "%d", &interval_burst, 1, 0, NETPERF_TYPE_INT32); set_output_elt(REMOTE_SYSTEM_MODEL, "Remote", "System", "Model", "", "%s", remote_system_model, 1, 0, NETPERF_TYPE_CHAR); set_output_elt(REMOTE_CPU_MODEL, "Remote", "CPU", "Model", "", "%s", remote_cpu_model, 1, 0, NETPERF_TYPE_CHAR); set_output_elt(REMOTE_CPU_FREQUENCY, "Remote", "CPU", "Frequency", "MHz", "%d", &remote_cpu_frequency, 1, 0, NETPERF_TYPE_INT32); set_output_elt(LOCAL_SYSTEM_MODEL, "Local", "System", "Model", "", "%s", local_system_model, 1, 0, NETPERF_TYPE_CHAR); set_output_elt(LOCAL_CPU_MODEL, "Local", "CPU", "Model", "", "%s", local_cpu_model, 1, 0, NETPERF_TYPE_CHAR); set_output_elt(LOCAL_CPU_FREQUENCY, "Local", "CPU", "Frequency", "MHz", "%d", &local_cpu_frequency, 1, 0, NETPERF_TYPE_INT32); set_output_elt(MIN_LATENCY, "Minimum", "Latency", "Microseconds", "", "%d", &min_latency, 0, OMNI_WANT_STATS, NETPERF_TYPE_INT32); set_output_elt(MAX_LATENCY, "Maximum", "Latency", "Microseconds", "", "%d", &max_latency, 0, OMNI_WANT_STATS, NETPERF_TYPE_INT32); set_output_elt(P50_LATENCY, "50th", "Percentile", "Latency", "Microseconds", "%d", &p50_latency, 0, OMNI_WANT_STATS, NETPERF_TYPE_INT32); set_output_elt(P90_LATENCY, "90th", "Percentile", "Latency", "Microseconds", "%d", &p90_latency, 0, OMNI_WANT_STATS, NETPERF_TYPE_INT32); set_output_elt(P99_LATENCY, "99th", "Percentile", "Latency", "Microseconds", "%d", &p99_latency, 0, OMNI_WANT_STATS, NETPERF_TYPE_INT32); set_output_elt(MEAN_LATENCY, "Mean", "Latency", "Microseconds", "", "%.2f", &mean_latency, 0, OMNI_WANT_STATS, NETPERF_TYPE_DOUBLE); set_output_elt(STDDEV_LATENCY, "Stddev", "Latency", "Microseconds", "", "%.2f", &stddev_latency, 0, OMNI_WANT_STATS, NETPERF_TYPE_DOUBLE); set_output_elt(LOCAL_SOCKET_PRIO, "Local", "Socket", "Priority", "", "%d", &local_socket_prio, 1, 0, NETPERF_TYPE_INT32); set_output_elt(REMOTE_SOCKET_PRIO, "Remote", "Socket", "Priority", "", "%d" , &remote_socket_prio, 1, 0, NETPERF_TYPE_INT32); set_output_elt(LOCAL_SOCKET_TOS, "Local", "Socket", "TOS", "", "0x%.2x", &local_socket_tos, 1, 0, NETPERF_TYPE_INT32); set_output_elt(REMOTE_SOCKET_TOS, "Remote", "Socket", "TOS", "", "0x%.2x", &remote_socket_tos, 1, 0, NETPERF_TYPE_INT32); set_output_elt(LOCAL_CONG_CONTROL, "Local", "Congestion", "Control", "Algorithm", "%s", local_cong_control, 0, OMNI_WANT_LOC_CONG, NETPERF_TYPE_CHAR); set_output_elt(REMOTE_CONG_CONTROL, "Remote", "Congestion", "Control", "Algorithm", "%s", remote_cong_control, 0, OMNI_WANT_REM_CONG, NETPERF_TYPE_CHAR); set_output_elt(LOCAL_FILL_FILE, "Local", "Fill", "File", "", "%s", local_fill_file, 0, 0, NETPERF_TYPE_CHAR); set_output_elt(REMOTE_FILL_FILE, "Remote", "Fill", "File", "", "%s", remote_fill_file, 0, 0, NETPERF_TYPE_CHAR); set_output_elt(OUTPUT_END, "This", "Is", "The", "End", "%s", NULL, 0, 0, NETPERF_TYPE_CHAR); } void print_omni_init() { int i,j; if (debug) { fprintf(where,"%s entered\n", __FUNCTION__); fflush(where); } /* why is this before the if you ask? because some of the output specifiers are char * rather than char[] and when I wanted to start setting output_group flags I was needing to call print_omni_init() before the char * 's were malloced, which meant the netperf_output_source got NULL pointers. there is undoubtedly a cleaner way to do all this. raj 20110629 */ print_omni_init_list(); if (printing_initialized) return; printing_initialized = 1; /* belts and suspenders */ for (j = 0; j < NETPERF_MAX_BLOCKS; j++) for (i = 0; i < NETPERF_OUTPUT_MAX; i++) output_list[j][i] = OUTPUT_END; if (output_selection_spec) { parse_output_selection(output_selection_spec); } else { set_output_list_by_test(); } } #ifdef notdef /* 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 old_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; } #endif /* notdef */ /* why? because one cannot simply pass a pointer to snprintf - well except when it is expecting one... */ int my_snprintf(char *buffer, size_t size, netperf_output_elt_t *output_elt) { switch (output_elt->output_type) { case NETPERF_TYPE_CHAR: return snprintf(buffer, size, output_elt->format, (char *)output_elt->display_value); break; case NETPERF_TYPE_INT32: return snprintf(buffer, size, output_elt->format, *(int *)(output_elt->display_value)); break; case NETPERF_TYPE_UINT32: return snprintf(buffer, size, output_elt->format, *(unsigned int *)(output_elt->display_value)); break; case NETPERF_TYPE_INT64: return snprintf(buffer, size, output_elt->format, *(long long *)(output_elt->display_value)); break; case NETPERF_TYPE_UINT64: return snprintf(buffer, size, output_elt->format, *(unsigned long long *)(output_elt->display_value)); break; case NETPERF_TYPE_DOUBLE: return snprintf(buffer, size, output_elt->format, *(double *)(output_elt->display_value)); break; default: fprintf(stderr, "Unknown/unsupported output_elt output_type of %d\n", output_elt->output_type); fflush(stderr); exit(-1); } } void print_omni_csv() { int i,j,k,buflen,vallen; char *hdr1 = NULL; char *val1 = NULL; char *h1 = NULL; char *v1 = NULL; char tmpval[1024]; buflen = 0; for (i = 0; i < NETPERF_MAX_BLOCKS; i++) { for (j = 0; ((j < NETPERF_OUTPUT_MAX) && (output_list[i][j] != OUTPUT_END)); j++) { if ((netperf_output_source[output_list[i][j]].format != NULL) && (netperf_output_source[output_list[i][j]].display_value != NULL)) { vallen = my_snprintf(tmpval, 1024, &(netperf_output_source[output_list[i][j]])); if (vallen == -1) { fprintf(where,"my_snprintf failed on %s with format %s\n", netperf_output_enum_to_str(j), netperf_output_source[output_list[i][j]].format); fflush(where); } vallen += 1; /* forget not the terminator */ } else vallen = 0; if (vallen > netperf_output_source[output_list[i][j]].tot_line_len) netperf_output_source[output_list[i][j]].tot_line_len = vallen; buflen += netperf_output_source[output_list[i][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 */ h1 = hdr1; v1 = val1; for (i = 0; i < NETPERF_MAX_BLOCKS; i++) { for (j = 0; ((j < NETPERF_OUTPUT_MAX) && (output_list[i][j] != OUTPUT_END)); j++) { int len; len = 0; if (print_headers) { for (k = 0; ((k < 4) && (NULL != netperf_output_source[output_list[i][j]].line[k]) && (strcmp("",netperf_output_source[output_list[i][j]].line[k]))); k++) { len = sprintf(h1, "%s", netperf_output_source[output_list[i][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_list[i][j]].format != NULL) && (netperf_output_source[output_list[i][j]].display_value != NULL)) { /* tot_line_len is bogus here, but should be "OK" ? */ len = my_snprintf(v1, netperf_output_source[output_list[i][j]].tot_line_len, &(netperf_output_source[output_list[i][j]])); /* 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_list[0][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 i,j; char tmpval[1024]; int vallen; for (i = 0; i < NETPERF_MAX_BLOCKS; i++) { for (j = 0; ((j < NETPERF_OUTPUT_MAX) && (output_list[i][j] != OUTPUT_END)); j++) { if ((netperf_output_source[output_list[i][j]].format != NULL) && (netperf_output_source[output_list[i][j]].display_value != NULL)) { vallen = my_snprintf(tmpval, 1024, &(netperf_output_source[output_list[i][j]])); if (vallen == -1) { snprintf(tmpval, 1024, "my_snprintf failed with format %s\n", netperf_output_source[output_list[i][j]].format); } fprintf(where, "%s=%s\n",netperf_output_enum_to_str(output_list[i][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_list[i][j] != OUTPUT_END)); j++) { if ((netperf_output_source[output_list[i][j]].format != NULL) && (netperf_output_source[output_list[i][j]].display_value != NULL)) /* need to count the \n */ vallen = my_snprintf(tmpval, 1024, &(netperf_output_source[output_list[i][j]])) + 1; else vallen = 0; if (vallen > netperf_output_source[output_list[i][j]].max_line_len) netperf_output_source[output_list[i][j]].max_line_len = vallen; buflen += netperf_output_source[output_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_list[i][j] != OUTPUT_END)); j++) { if (print_headers) { for (k = 0; k < 4; k++) { memcpy(h[k], netperf_output_source[output_list[i][j]].line[k], strlen(netperf_output_source[output_list[i][j]].line[k])); } } if ((netperf_output_source[output_list[i][j]].format != NULL) && (netperf_output_source[output_list[i][j]].display_value != NULL)) { int len; len = my_snprintf(v1, netperf_output_source[output_list[i][j]].max_line_len, &(netperf_output_source[output_list[i][j]])); /* 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_list[i][j]].max_line_len + 1; } v1 += netperf_output_source[output_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_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); switch (netperf_output_mode) { case CSV: print_omni_csv(); break; case KEYVAL: print_omni_keyword(); break; case HUMAN: print_omni_human(); break; default: fprintf(where,"Yo Rick! There is a bug in netperf_output_mode!\n"); fflush(where); exit(-1); } } /* 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 > 2) { fprintf(where, "%s sock %d, ring elt %p, bytes %d, dest %p, len %d\n", __FUNCTION__, 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,"%s: data send error: errno %d\n",__FUNCTION__,errno); return -3; } } return len; } #if defined(__linux) static int recv_data_no_copy(SOCKET data_socket, struct ring_elt *recv_ring, uint32_t bytes_to_recv, struct sockaddr *source, netperf_socklen_t *sourcelen, uint32_t flags, uint32_t *num_receives) { static int pfd[2] = {-1, -1}; static int fdnull = -1; char *temp_message_ptr; int bytes_left; int bytes_recvd; int my_recvs; int my_flags = 0; /* will we one day want to set MSG_WAITALL? */ int ret; if (pfd[0] == -1) { if (pipe(pfd)) { fprintf(where, "%s pipe call failed with errno %d '%s'\n", __FUNCTION__, errno, strerror(errno)); return -4; /* this will cause recv_data to do things the old-fashioned way for the test */ } if ((fdnull = open("/dev/null",O_WRONLY)) == -1) { fprintf(where, "%s open call failed with errno %d '%s'\n", __FUNCTION__, errno, strerror(errno)); return -4; } } /* 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; if (debug > 1) { fprintf(where, "%s sock %d, ring elt %p, bytes %d, source %p, srclen %d, flags %x, num_recv %p\n", __FUNCTION__, data_socket, recv_ring, bytes_to_recv, source, (source != NULL) ? *sourcelen : -1, flags, num_receives); fflush(where); } do { bytes_recvd = splice(data_socket, NULL, pfd[1], NULL, bytes_left, my_flags); if (bytes_recvd > 0) { if (splice(pfd[0], NULL, fdnull, NULL, bytes_recvd, my_flags) != bytes_recvd) { return -3; } bytes_left -= bytes_recvd; } else { break; } my_recvs++; /* should the pair of splices count as one? */ } 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; } #endif int recv_data(SOCKET data_socket, struct ring_elt *recv_ring, uint32_t bytes_to_recv, struct sockaddr *source, netperf_socklen_t *sourcelen, uint32_t flags, uint32_t *num_receives) { char *temp_message_ptr; int bytes_left; int bytes_recvd; int my_recvs; int my_flags = 0; /* will we one day want to set MSG_WAITALL? */ #if defined(__linux) int ret; if (loc_rcvavoid == 1) { ret = recv_data_no_copy(data_socket, recv_ring, bytes_to_recv, source, sourcelen, flags, num_receives); if (ret != -4) return ret; else loc_rcvavoid = 0; } #endif /* 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, "%s sock %d, ring elt %p, bytes %d, source %p, srclen %d, flags %x, num_recv %p\n", __FUNCTION__, 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, my_flags, source, sourcelen); } else { /* just call recv */ bytes_recvd = recv(data_socket, temp_message_ptr, bytes_left, my_flags); } 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 protocol) { int ret; char buffer[4]; if (debug) { fprintf(where, "%s sock %d peer %p peerlen %d protocol %d\n", __FUNCTION__, data_socket, peer, peerlen, protocol); fflush(where); } if (protocol == IPPROTO_UDP) { /* try to give the remote a signal. what this means if we ever wanted to actually send zero-length messages remains to be seen :) */ 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, "%s sock %d init %d do_close %d protocol %d\n", __FUNCTION__, 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 */ /* this needs to be revisited for the netperf receiving case when the test is terminated by a Ctrl-C. raj 2012-01-24 */ 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. of course, we *may* never receive anything from the remote which means we probably really aught to have a select here but until we are once bitten we will remain twice bold. */ 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; } #ifdef HAVE_LINUX_TCP_H static void dump_tcp_info(struct tcp_info *tcp_info) { printf("tcpi_rto %d tcpi_ato %d tcpi_pmtu %d tcpi_rcv_ssthresh %d\n" "tcpi_rtt %d tcpi_rttvar %d tcpi_snd_ssthresh %d tpci_snd_cwnd %d\n" "tcpi_reordering %d tcpi_total_retrans %d\n", tcp_info->tcpi_rto, tcp_info->tcpi_ato, tcp_info->tcpi_pmtu, tcp_info->tcpi_rcv_ssthresh, tcp_info->tcpi_rtt, tcp_info->tcpi_rttvar, tcp_info->tcpi_snd_ssthresh, tcp_info->tcpi_snd_cwnd, tcp_info->tcpi_reordering, tcp_info->tcpi_total_retrans); return; } #endif static int get_transport_retrans(SOCKET socket, int protocol) { #ifdef HAVE_LINUX_TCP_H struct tcp_info tcp_info; int ret; netperf_socklen_t infosize; if (protocol != IPPROTO_TCP) return -1; infosize = sizeof(struct tcp_info); if ((ret = getsockopt(socket,protocol,TCP_INFO,&tcp_info,&infosize)) < 0) { if (debug) { fprintf(where, "%s: getsockopt errno %d %s\n", __FUNCTION__, errno, strerror(errno)); fflush(where); } return -1; } else { if (debug > 1) { dump_tcp_info(&tcp_info); } return tcp_info.tcpi_total_retrans; } #else return -1; #endif } 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, "%s: getsockopt: errno %d\n", __FUNCTION__, errno); fflush(where); *mss = -1; } } /* if ( setsockopt(sd, SOL_TCP, TCP_CONGESTION, "ledbat", 6) == -1 ) { perror("setsockopt"); exit(EXIT_FAILURE); } */ static void get_transport_cong_control(SOCKET socket, int protocol, char cong_control[], int len) { #ifdef TCP_CONGESTION int my_len = len; if (protocol != IPPROTO_TCP) { strncpy(cong_control,"TCP Only",len); } else if (getsockopt(socket, protocol, TCP_CONGESTION, cong_control, &my_len) == SOCKET_ERROR) { snprintf(cong_control,len,"%d errno",errno); } #else strncpy(cong_control,"Unavailable",len); #endif cong_control[len-1] = '\0'; } static void set_transport_cong_control(SOCKET socket, int protocol, char cong_control[], int len) { #ifdef TCP_CONGESTION if (protocol == IPPROTO_TCP) { /* if it fails, we'll pick that up via the subsequent "get" */ setsockopt(socket, protocol, TCP_CONGESTION, cong_control, len); } #endif } static SOCKET omni_create_data_socket(struct addrinfo *res) { SOCKET temp_socket; temp_socket = create_data_socket(res); if (temp_socket != SOCKET_ERROR) { if (local_cong_control_req[0] != '\0') { set_transport_cong_control(temp_socket, res->ai_protocol, local_cong_control_req, sizeof(local_cong_control_req)); } } return temp_socket; } /* choosing the default send size is a trifle more complicated than it used to be as we have to account for different protocol limits */ #define UDP_LENGTH_MAX (0xFFFF - 28) static int choose_send_size(int lss, int protocol) { int send_size; if (lss > 0) { send_size = lss_size; /* we will assume that everyone has IPPROTO_UDP and thus avoid an issue with Windows using an enum */ if ((protocol == IPPROTO_UDP) && (send_size > UDP_LENGTH_MAX)) send_size = UDP_LENGTH_MAX; } else { send_size = 4096; } return send_size; } /* 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); } #if defined(__linux) /* * Linux has this odd behavior where if the socket buffers are larger * than a device's txqueuelen, the kernel will silently drop transmits * which would not fit into the tx queue, and not pass an ENOBUFS * error back to the application. As a result, a UDP stream test can * report absurd transmit bandwidths (like 20Gb/s on a 1GbE NIC). * This behavior can be avoided if you request extended error * reporting on the socket. This is done by setting the IP_RECVERR * socket option at the IP level. */ static void enable_enobufs(int s) { struct protoent *pr; int on = 1; if ((pr = getprotobyname("ip")) == NULL) { fprintf(where, "%s failed: getprotobyname\n",__FUNCTION__); fflush(where); return; } if (setsockopt(s, pr->p_proto, IP_RECVERR, (char *)&on, sizeof(on)) < 0) { fprintf(where, "%s failed: setsockopt\n",__FUNCTION__); fflush(where); return; } } #endif /* 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. raj 2008-01-07 */ void send_omni_inner(char remote_host[], unsigned int legacy_caller, char header_str[]) { 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); netperf_socklen_t my_addr_len = sizeof(my_addr); SOCKET data_socket; int need_socket; uint32_t temp_recvs; char tmpfmt; 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 user 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 requests_this_cwnd = 0; int request_cwnd_initial = REQUEST_CWND_INITIAL; 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 */ /* if the user has specified a negative value for first_burst_size via the test-specific -b option, we forgo the nicities of ramping up the request_cwnd and go straight to burst size. raj 20110715 */ if (first_burst_size < 0) { first_burst_size = first_burst_size * -1; request_cwnd_initial = first_burst_size; } else { request_cwnd_initial = REQUEST_CWND_INITIAL; } #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... however, we do not want to do this if this is a no_control test. raj 20101220 */ /* should we also not call this if this is a legacy test? */ if (!no_control) { get_remote_system_info(); } if (keep_histogram) { if (first_burst_size > 0) time_hist = HIST_new_n(first_burst_size + 1); else time_hist = HIST_new_n(1); } /* 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(header_str,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; /* since we are tracking the number of outstanding requests for timestamping purposes, and since the previous iteration if using confidence intervals may not have completed all of them, we now need to forget about them or we will mistakenly fill our tracking array. raj 2011-03-14 */ if (keep_histogram) { HIST_purge(time_hist); } #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; requests_this_cwnd = 0; request_cwnd = request_cwnd_initial; #endif /* if the command-line included requests to randomize the IP addresses, then honor it. of course, this may not work all that well for some tests... raj 20101129 */ if (local_mask_len) random_ip_address(local_res, local_mask_len); if (remote_mask_len) random_ip_address(remote_res, remote_mask_len); data_socket = omni_create_data_socket(local_res); if (data_socket == INVALID_SOCKET) { perror("netperf: send_omni: unable to create data socket"); exit(1); } #if defined(__linux) enable_enobufs(data_socket); #endif 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) { if (is_multicast_addr(remote_res)) { set_multicast_ttl(data_socket); } if (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) { send_size = choose_send_size(lss_size,protocol); } 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, "%s: %d entry send_ring obtained...\n", __FUNCTION__, send_width); } } } if (direction & NETPERF_RECV) { /* do we need to join a multicast group? */ if (is_multicast_addr(local_res)) { join_multicast_addr(data_socket, local_res); } /* do we need to allocate a recv_ring? */ if (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, "%s: %d entry recv_ring obtained...\n", __FUNCTION__, recv_width); } } } if (!no_control) { /* 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->flags = 0; 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 = send_width; 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 = recv_width; omni_request->response_size = rsp_size; omni_request->socket_prio = remote_socket_prio; omni_request->socket_tos = remote_socket_tos; /* we have no else clauses here because we previously set flags to zero above raj 20090803 */ if (rem_nodelay) omni_request->flags |= OMNI_NO_DELAY; if (remote_use_sendfile) omni_request->flags |= OMNI_USE_SENDFILE; if (connection_test) omni_request->flags |= OMNI_CONNECT_TEST; if (remote_checksum_off) omni_request->flags |= OMNI_CHECKSUM_OFF; if (remote_cpu_usage) omni_request->flags |= OMNI_MEASURE_CPU; if (routing_allowed) omni_request->flags |= OMNI_ROUTING_ALLOWED; if (desired_output_groups & OMNI_WANT_REM_IFNAME) omni_request->flags |= OMNI_WANT_IFNAME; if (desired_output_groups & OMNI_WANT_REM_IFSLOT) omni_request->flags |= OMNI_WANT_IFSLOT; if (desired_output_groups & OMNI_WANT_REM_IFIDS) omni_request->flags |= OMNI_WANT_IFIDS; if (desired_output_groups & OMNI_WANT_REM_DRVINFO) omni_request->flags |= OMNI_WANT_DRVINFO; if (desired_output_groups & OMNI_WANT_REM_CONG) omni_request->flags |= OMNI_WANT_REM_CONG; /* perhaps this should be made conditional on remote_cong_control_req[0] not being NULL? */ strncpy(omni_request->cong_control, remote_cong_control_req, sizeof(omni_request->cong_control)); omni_request->cong_control[sizeof(omni_request->cong_control) - 1] = '\0'; if (want_keepalive) omni_request->flags |= OMNI_WANT_KEEPALIVE; 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->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->netperf_ip, &(omni_request->netperf_port)); ret = get_sockaddr_family_addr_port((struct sockaddr_storage *)remote_res->ai_addr, nf_to_af(omni_request->ipfamily), omni_request->netserver_ip, &(omni_request->data_port)); /* if the user didn't explicitly set the remote data address we don't want to pass along the one we picked implicitly, or a netserver sitting behind a (BLETCH) NAT will be asked to try to bind to the "public" IP. */ if (!explicit_data_address) { omni_request->netserver_ip[0] = 0; omni_request->netserver_ip[1] = 0; omni_request->netserver_ip[2] = 0; omni_request->netserver_ip[3] = 0; } if (debug > 1) { fprintf(where,"netperf: %s: requesting OMNI test\n",__FUNCTION__); } strncpy(omni_request->fill_file, remote_fill_file, sizeof(omni_request->fill_file)); send_request_n(OMNI_REQUEST_CONV_CUTOFF); /* 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->flags & OMNI_NO_DELAY; remote_use_sendfile = omni_response->flags & OMNI_USE_SENDFILE; remote_cpu_usage = omni_response->flags & OMNI_MEASURE_CPU; remote_cpu_rate = omni_response->cpu_rate; remote_send_width = omni_response->send_width; remote_recv_width = omni_response->recv_width; remote_socket_prio = omni_response->socket_prio; remote_socket_tos = omni_response->socket_tos; /* 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 { /* we are a no_control test so some things about the remote need to be set accordingly */ 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); /* possibly wait just a moment before actually starting - used mainly when one is doing many many many concurrent netperf tests */ WAIT_BEFORE_DATA_TRAFFIC(); /* 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 */ /* enable a test_time of 0 to mean just keep running until something other than alarm() generates a signal. raj 2012-02-01 */ if ((test_time) || ((test_trans == 0) && (test_bytes == 0))) { /* 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)) && ((test_trans == 0) && (test_bytes == 0))) pad_time = 0; 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) { demo_first_timestamp(); } #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)) { /* we need to be careful about when we snap a timestamp depending on the test parameters. this one *should* cover everything but the burst request/response test - famous last words of course. raj 20110111 */ if (keep_histogram) { HIST_timestamp_start(time_hist); } again: if (need_socket) { if (connection_test) pick_next_port_number(local_res,remote_res); data_socket = omni_create_data_socket(local_res); if (data_socket == INVALID_SOCKET) { perror("netperf: send_omni: unable to create data socket"); exit(1); } need_socket = 0; #if defined(__linux) enable_enobufs(data_socket); #endif } /* 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 */ if (debug) { 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); /* yes Virginia, a goto. perhaps one day we will rewrite the code to avoid it but for now, a goto... raj */ 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 > 1) { 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; /* yes, it seems a trifle odd having this *after* the send() just above, but really this is for the next send() or recv() call below or in the iteration of this loop, and the first HIST_timestamp_start() call at the top of the outermost loop will be for the first send() call here in the burst code. clear ain't it?-) raj 20110111 */ if (keep_histogram) { HIST_timestamp_start(time_hist); } } #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 #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 */ 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)) && (++requests_this_cwnd == request_cwnd)) { request_cwnd += 1; requests_this_cwnd = 0; if (debug > 1) { fprintf(where, "incr req_cwnd to %d first_burst %d reqs_outstanding %d trans %"PRIu64"\n", request_cwnd, first_burst_size, requests_outstanding, trans_completed + 1); } } #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 */ /* however annoying having to do this might be, it really shouldn't be done over and over again. instead we will assume it does not change, which is fine since we would have only reported one of them anyway. raj 20100917 */ if ((lsr_size_req < 0) && (-1 == lsr_size_end)) get_sock_buffer(data_socket, RECV_BUFFER, &lsr_size_end); else lsr_size_end = lsr_size; if ((lss_size_req < 0) && (-1 == lss_size_end)) 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); } } if (keep_histogram) { HIST_timestamp_stop_add(time_hist); } #ifdef WANT_DEMO if (NETPERF_IS_RR(direction)) { if (libfmt == 'x') { demo_interval_tick(1); } else { demo_interval_tick(req_size + rsp_size); } } else if (NETPERF_XMIT_ONLY(direction)) { demo_interval_tick(bytes_to_send); } else { demo_interval_tick(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 defined(WANT_DEMO) /* if we were in demo mode this will ensure one final interim result, which, naturally might be a bit early :) */ demo_interval_final(); #endif if (transport_mss == -2) get_transport_info(data_socket, &transport_mss, local_res->ai_protocol); local_transport_retrans = get_transport_retrans(data_socket, 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 if ((desired_output_groups & OMNI_WANT_LOC_CONG) && (local_cong_control[0] == '\0')) { get_transport_cong_control(data_socket, local_res->ai_protocol, local_cong_control, sizeof(local_cong_control)); } /* 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); /* if this is a legacy test, there is not much point to finding all these things since they will not be emitted. */ if (!legacy) { /* and even if this is not a legacy test, there is still not much point to finding these things if they will not be emitted */ find_system_info(&local_system_model, &local_cpu_model, &local_cpu_frequency); if ((desired_output_groups & OMNI_WANT_LOC_IFNAME) || (desired_output_groups & OMNI_WANT_LOC_DRVINFO) || (desired_output_groups & OMNI_WANT_LOC_IFSLOT) || (desired_output_groups & OMNI_WANT_LOC_IFIDS)) { local_interface_name = find_egress_interface(local_res->ai_addr,remote_res->ai_addr); } else { local_interface_name = strdup("Bug If Seen IFNAME"); } if (desired_output_groups & OMNI_WANT_LOC_DRVINFO) { find_driver_info(local_interface_name,local_driver_name, local_driver_version,local_driver_firmware, local_driver_bus,32); } else { strncpy(local_driver_name,"Bug If Seen DRVINFO",32); strncpy(local_driver_version, "Bug If Seen DRVINFO",32); strncpy(local_driver_firmware,"Bug If Seen DRVINFO",32); strncpy(local_driver_bus,"Bug If Seen DRVINFO",32); } if (desired_output_groups & OMNI_WANT_LOC_IFSLOT) { local_interface_slot = find_interface_slot(local_interface_name); } else { local_interface_slot = strdup("Bug If Seen IFSLOT"); } if (desired_output_groups & OMNI_WANT_LOC_IFIDS) { find_interface_ids(local_interface_name, &local_interface_vendor, &local_interface_device, &local_interface_subvendor, &local_interface_subdevice); } else { local_interface_vendor = -2; local_interface_device = -2; local_interface_subvendor = -2; local_interface_subdevice = -2; } } /* 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_CONV_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); 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; /* 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... */ 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 = (double) 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; remote_transport_retrans = omni_result->transport_retrans; /* what was the congestion control? */ if (desired_output_groups & OMNI_WANT_REM_CONG) { strncpy(remote_cong_control, omni_result->cong_control, sizeof(remote_cong_control)); remote_cong_control[sizeof(remote_cong_control) - 1] = '\0'; } } 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 { /* when we are sending, in a no_control test, we have to ass-u-me that everything we sent was received, otherwise, we will report a transfer rate of zero. */ remote_bytes_xferd = (double) bytes_sent; } /* 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 = (double) 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((double)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)) { float rtt_elapsed_time = elapsed_time; #ifdef WANT_INTERVALS /* if the test was paced, we need to subtract the time we were sitting paced from the time we use to calculate the average rtt_latency. Of course, won't really know how long we were sitting unless we bracket the sit with timing calls, which will be additional overhead affecting CPU utilization. but, there is no such thing as a free lunch is there :) raj 20110121 */ if (interval_burst) { rtt_elapsed_time -= (float)(interval_wait_microseconds / 1000000.0); } #endif /* WANT_INTERVALS */ 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/rtt_elapsed_time)) * (double)1000000.0) * (double) (1 + ((first_burst_size > 0) ? first_burst_size : 0)); } else { rtt_latency = ((double)1.0/(trans_completed/rtt_elapsed_time)) * (double)1000000.0; } tmpfmt = libfmt; libfmt = 'x'; transaction_rate = calc_thruput((double)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; 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--; #if defined(WANT_INTERVALS) #ifdef WIN32 stop_itimer(); #endif #endif /* WANT_INTERVALS */ /* 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 */ tmpfmt = libfmt; if ('x' == libfmt) { libfmt = 'm'; } local_send_thruput = calc_thruput((double)bytes_sent); local_recv_thruput = calc_thruput((double)bytes_received); remote_send_thruput = calc_thruput((double)remote_bytes_sent); remote_recv_thruput = calc_thruput((double)remote_bytes_received); libfmt = tmpfmt; /* were we tracking possibly expensive statistics? */ if (keep_statistics) { HIST_get_stats(time_hist, &min_latency, &max_latency, &mean_latency, &stddev_latency); p50_latency = HIST_get_percentile(time_hist, 0.50); p90_latency = HIST_get_percentile(time_hist, 0.90); p99_latency = HIST_get_percentile(time_hist, 0.99); } /* if we are running a legacy test we do not do the nifty new omni output stuff */ if (!legacy) { 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_list[0][1] = OUTPUT_END; for (i = OUTPUT_NONE; i < NETPERF_OUTPUT_MAX; i++) { output_list[0][0] = i; print_omni_csv(); } } #endif /* likely as not we are going to do something slightly different here */ if ((verbosity > 1) && (!legacy)) { #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"); HIST_report(time_hist); fflush(where); #endif /* WANT_HISTOGRAM */ } } void send_omni(char remote_host[]) { char name_buf[32]; snprintf(name_buf,sizeof(name_buf),"OMNI %s TEST",direction_str); name_buf[31] = '\0'; send_omni_inner(remote_host, 0, name_buf); } #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 static void set_hostname_and_port_2(void *addr, char *hostname, char *portstr, int family, int port) { inet_ntop(family, addr, hostname, BUFSIZ); sprintf(portstr, "%u", port); } /* the name is something of a misnomer since this test could send, or receive, or both, but it matches the historical netperf routine naming convention for what runs in the netserver context. */ void recv_omni() { struct addrinfo *local_res; char local_name[BUFSIZ]; char port_buffer[PORTBUFSIZE]; struct sockaddr_storage myaddr_in, peeraddr_in; int peeraddr_set = 0; 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 = 0; int need_to_accept; int connected; int ret; uint32_t 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: %s: entered...\n",__FUNCTION__); fflush(where); } /* netserver has no good way of knowing where the conversion cutoff point is, so we have to fix it after the fact */ fixup_request_n(OMNI_REQUEST_CONV_CUTOFF); /* thus fixed-up, we can extract the requested congestion control algorithm */ strncpy(local_cong_control_req, omni_request->cong_control, sizeof(local_cong_control_req)); /* 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,"%s: setting the response type...\n",__FUNCTION__); fflush(where); } netperf_response.content.response_type = OMNI_RESPONSE; if (debug) { fprintf(where,"%s: the response type is set...\n",__FUNCTION__); fflush(where); } /* Grab a socket to listen on, and then listen on it. */ if (debug) { fprintf(where,"%s: grabbing a socket...\n",__FUNCTION__); 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->flags) & OMNI_NO_DELAY; loc_rcvavoid = omni_request->so_rcvavoid; loc_sndavoid = omni_request->so_sndavoid; routing_allowed = (omni_request->flags) & OMNI_ROUTING_ALLOWED; want_keepalive = (omni_request->flags) & OMNI_WANT_KEEPALIVE; local_socket_prio = omni_request->socket_prio; local_socket_tos = omni_request->socket_tos; #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->flags & OMNI_CONNECT_TEST; direction = omni_request->direction; /* let's be quite certain the fill file string is null terminated */ omni_request->fill_file[sizeof(omni_request->fill_file) - 1] = '\0'; strncpy(local_fill_file, omni_request->fill_file, sizeof(local_fill_file)); /* kludgy, because I have no way at present to say how many bytes needed to be swapped around for the request from which this is pulled, and it is probably all wrong for IPv6 :( */ switch (nf_to_af(omni_request->ipfamily)) { case AF_INET6: /* yes indeed it is, do nothing, bz */ break; case AF_INET: default: for (ret=0; ret < 4; ret++) { omni_request->netserver_ip[ret] = htonl(omni_request->netserver_ip[ret]); omni_request->netperf_ip[ret] = htonl(omni_request->netperf_ip[ret]); } break; } set_hostname_and_port_2(omni_request->netserver_ip, 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 = omni_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" "recv_omni: requested send alignment of %d offset %d\n", omni_request->recv_alignment, omni_request->recv_offset, 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; omni_response->socket_prio = local_socket_prio; omni_response->socket_tos = local_socket_tos; if (omni_request->direction & NETPERF_XMIT) { #ifdef fo /* do we need to set multicast ttl? */ if (is_multicast_addr(remote_res)) { /* yes, s_listen - for a UDP test we will be copying it to data_socket but that hasn't happened yet. raj 20100315 */ set_multicast_ttl(s_listen); } #endif 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) { bytes_to_send = choose_send_size(lss_size,omni_request->protocol); } 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_request->recv_width; if (omni_request->direction & NETPERF_RECV) { /* do we need to join a multicast group? */ if (is_multicast_addr(local_res)) { /* yes, s_listen - for a UDP test we will be copying it to data_socket but that hasn't happened yet. raj 20100315 */ join_multicast_addr(s_listen, local_res); } 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. the age-old constant of 5 is probably OK for our purposes but does not necessarily represent best practice */ 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->flags &= ~OMNI_MEASURE_CPU; if (omni_request->flags & OMNI_MEASURE_CPU) { omni_response->flags |= OMNI_MEASURE_CPU; 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; if (loc_nodelay) omni_response->flags |= OMNI_NO_DELAY; else omni_response->flags &= ~OMNI_NO_DELAY; 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->flags & OMNI_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; test_time=omni_request->test_length; /* 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)) && (omni_request->test_length > 0)) 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; } netperf_response.content.serv_errno = errno; send_response(); fprintf(where,"%s: accept: errno = %d\n",__FUNCTION__,errno); fflush(where); close(s_listen); exit(-1); } if (debug) { fprintf(where,"%s: accepted data connection.\n",__FUNCTION__); 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, but we only need to do it once. */ if ((omni_request->protocol == IPPROTO_UDP) && (!peeraddr_set)) { peeraddr_set = 1; data_socket = s_listen; set_sockaddr_family_addr_port(&peeraddr_in, nf_to_af(omni_request->ipfamily), omni_request->netperf_ip, 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) || (units_remaining > 0))) { 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 */ 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! */ netperf_response.content.serv_errno = errno; send_response(); 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) || (units_remaining > 0))) { 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; */ netperf_response.content.serv_errno = errno; send_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 */ /* but as annoying as it is to have to make these calls, don't penalize linux by calling them over and over again. instead we will simply ass-u-me that it will become the same value over and over again. raj 20100917 */ if ((lsr_size_req < 0) && (-1 == lsr_size_end)) get_sock_buffer(data_socket, RECV_BUFFER, &lsr_size_end); else lsr_size_end = lsr_size; if ((lss_size_req < 0) && (-1 == lss_size_end)) 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,omni_request->protocol); if (ret == -1) { times_up = 1; timed_out = 1; break; } else if (ret < 0) { netperf_response.content.serv_errno = errno; send_response(); 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 */ stop_timer(); cpu_stop(omni_request->flags & OMNI_MEASURE_CPU,&elapsed_time); close(s_listen); #if defined(WANT_INTERVALS) #ifdef WIN32 stop_itimer(); #endif #endif /* WANT_INTERVALS */ 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; } remote_transport_retrans = get_transport_retrans(data_socket, omni_request->protocol); 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 if (omni_request->flags & OMNI_WANT_REM_CONG) { get_transport_cong_control(data_socket, local_res->ai_protocol, omni_results->cong_control, sizeof(omni_results->cong_control)); } else { strncpy(omni_results->cong_control,"",sizeof(omni_results->cong_control)); } close_data_socket(data_socket,NULL,0,omni_request->protocol); } else { close_data_socket(data_socket,(struct sockaddr *)&peeraddr_in,addrlen,omni_request->protocol); lsr_size_end = lsr_size; lss_size_end = lss_size; } /* send the results to the sender */ omni_results->send_calls = (uint32_t) 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 = (uint32_t) 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 = (uint32_t) trans_completed; omni_results->elapsed_time = elapsed_time; omni_results->transport_retrans = remote_transport_retrans; omni_results->cpu_method = cpu_method; omni_results->num_cpus = lib_num_loc_cpus; if (omni_request->flags & OMNI_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; if ((omni_request->flags & OMNI_WANT_IFNAME) || (omni_request->flags & OMNI_WANT_IFSLOT) || (omni_request->flags & OMNI_WANT_IFIDS) || (omni_request->flags & OMNI_WANT_DRVINFO)) { 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; } else { strncpy(omni_results->ifname,"Bug If Seen IFNAME",16); } if (omni_request->flags & OMNI_WANT_IFSLOT) { local_interface_slot = find_interface_slot(local_interface_name); strncpy(omni_results->ifslot,local_interface_slot,16); omni_results->ifslot[15] = 0; } else { strncpy(omni_results->ifslot,"Bug If Seen IFSLOT",16); } if (omni_request->flags & OMNI_WANT_IFIDS) { find_interface_ids(local_interface_name, &omni_results->vendor, &omni_results->device, &omni_results->subvendor, &omni_results->subdevice); } else { omni_results->vendor = -2; omni_results->device = -2; omni_results->subvendor = -2; omni_results->subdevice = -2; } if (omni_request->flags & OMNI_WANT_DRVINFO) { find_driver_info(local_interface_name, omni_results->driver, omni_results->version, omni_results->firmware, omni_results->bus, 32); } else { strncpy(omni_results->driver,"Bug If Seen DRVINFO",32); strncpy(omni_results->version,"Bug If Seen DRVINFO",32); strncpy(omni_results->firmware,"Bug If Seen DRVINFO",32); strncpy(omni_results->bus,"Bug If Seen DRVINFO",32); } #if defined(WANT_INTERVALS) #ifdef WIN32 stop_itimer(); #endif #endif /* WANT_INTERVALS */ if (debug) { fprintf(where, "%s: test complete, sending results.\n", __FUNCTION__); fflush(where); } send_response_n(OMNI_RESULTS_CONV_CUTOFF); } #ifdef WANT_MIGRATION 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"PRId64" %6.2f %6"PRId64" %6.2f %6"PRId64"\n"; char *ksink_fmt2 = "\n\ Maximum\n\ Segment\n\ Size (bytes)\n\ %6d\n"; send_omni_inner(remote_host, legacy, "MIGRATED TCP STREAM TEST"); if (legacy) { /* We are now ready to print all the information, but only if we are truly acting as a legacy test. 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) { 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)local_send_calls, local_send_calls, bytes_sent / (double)remote_receive_calls, remote_receive_calls); fprintf(where, ksink_fmt2, transport_mss); #ifdef WANT_HISTOGRAM fprintf(where,"\n\nHistogram of time spent in send() call.\n"); HIST_report(time_hist); #endif /* WANT_HISTOGRAM */ fflush(where); } } } 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"PRId64" %6.2f %6d %6.2f %6d\n"; char *ksink_fmt2 = "\n\ Maximum\n\ Segment\n\ Size (bytes)\n\ %6d\n"; send_omni_inner(remote_host, legacy, "MIGRATED TCP MAERTS TEST"); /* We are now ready to print all the information, but only if we are truly acting as a leacy test. 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 (legacy) { 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) { 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 */ remote_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_received, bytes_received / (double)local_receive_calls, local_receive_calls, remote_bytes_sent / (double)remote_send_calls, remote_send_calls); fprintf(where, ksink_fmt2, transport_mss); #ifdef WANT_HISTOGRAM fprintf(where,"\n\nHistogram of time spent in recv() call.\n"); HIST_report(time_hist); #endif /* WANT_HISTOGRAM */ fflush(where); } } } 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/KB us/KB\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"; send_omni_inner(remote_host, legacy, "MIGRATED TCP REQUEST/RESPONSE TEST"); if (legacy) { /* 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) { 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 */ 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, ('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 */ 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 */ /* 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/transaction_rate)*(double)1000000.0) * (double) (1 + ((first_burst_size > 0) ? first_burst_size : 0)), transaction_rate, calc_thruput_interval_omni(transaction_rate * (double)req_size, 1.0), calc_thruput_interval_omni(transaction_rate * (double)rsp_size, 1.0)); #ifdef WANT_HISTOGRAM fprintf(where,"\nHistogram of request/response times\n"); HIST_report(time_hist); #endif /* WANT_HISTOGRAM */ fflush(where); } } } 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"; send_omni_inner(remote_host, legacy, "MIGRATED TCP Connect/Request/Response TEST"); /* 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 (legacy) { 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) { 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_align, local_send_offset, remote_recv_offset); #ifdef WANT_HISTOGRAM fprintf(where,"\nHistogram of request/response times\n"); HIST_report(time_hist); #endif /* WANT_HISTOGRAM */ fflush(where); } } } void send_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 %7"PRIu64" %6d %7.2f\n\ %6d %-7.2f %7"PRIu64" %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 %7"PRIu64" %6d %7.1f %-6.2f %-6.3f\n\ %6d %-7.2f %7"PRIu64" %7.1f %-6.2f %-6.3f\n\n"; send_omni_inner(remote_host, legacy, "MIGRATED UDP STREAM TEST"); if (legacy) { /* 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) { 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 */ local_send_calls, failed_sends, local_send_thruput, /* what was the xfer rate */ local_cpu_utilization, /* local cpu */ local_service_demand, /* local service demand */ rsr_size, elapsed_time, remote_receive_calls, remote_recv_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_send_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 */ local_send_calls, failed_sends, local_send_thruput, rsr_size, /* remote recvbuf size */ elapsed_time, remote_receive_calls, remote_recv_thruput); break; } } #ifdef WANT_HISTOGRAM if (verbosity > 1) { fprintf(where,"\nHistogram of time spent in send() call\n"); HIST_report(time_hist); } #endif /* WANT_HISTOGRAM */ fflush(where); } } 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/KB us/KB\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"; send_omni_inner(remote_host, legacy, "MIGRATED UDP REQUEST/RESPONSE TEST"); if (legacy) { /* 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) { 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 */ 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, ('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 */ 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 */ /* 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"); HIST_report(time_hist); #endif /* WANT_HISTOGRAM */ } fflush(where); } } #endif /* WANT_MIGRATION */ /* using legacy test names will cause certain default settings to be made before we scan the test-specific arguments. raj 2010-07-20 */ static void set_omni_defaults_by_legacy_testname() { /* the uber defaults are for a unidirectional test using TCP */ protocol = IPPROTO_TCP; socket_type = SOCK_STREAM; connection_test = 0; req_size = rsp_size = -1; was_legacy = 1; legacy = 1; implicit_direction = 0; /* do we allow certain options to implicitly affect the test direction? */ if (strcasecmp(test_name,"TCP_STREAM") == 0) { direction = NETPERF_XMIT; } else if (strcasecmp(test_name,"TCP_MAERTS") == 0) { direction = NETPERF_RECV; } else if (strcasecmp(test_name,"TCP_RR") == 0) { req_size = rsp_size = 1; direction = 0; direction |= NETPERF_XMIT; direction |= NETPERF_RECV; } else if (strcasecmp(test_name,"UDP_STREAM") == 0) { protocol = IPPROTO_UDP; socket_type = SOCK_DGRAM; } else if (strcasecmp(test_name,"UDP_RR") == 0) { protocol = IPPROTO_UDP; socket_type = SOCK_DGRAM; direction = 0; direction |= NETPERF_XMIT; direction |= NETPERF_RECV; req_size = rsp_size = 1; } else if (strcasecmp(test_name,"TCP_CC") == 0) { direction = 0; connection_test = 1; } else if (strcasecmp(test_name,"TCP_CRR") == 0) { direction = 0; direction |= NETPERF_XMIT; direction |= NETPERF_RECV; req_size = rsp_size = 1; connection_test = 1; } else if (strcasecmp(test_name,"omni") == 0) { /* there is not much to do here but clear the legacy flag */ was_legacy = 0; legacy = 0; implicit_direction = 1; } socket_type_str = hst_to_str(socket_type); } char omni_usage[] = "\n\ Usage: netperf [global options] -- [test options] \n\ \n\ OMNI and Migrated BSD Sockets Test Options:\n\ -b number Send number requests at start of _RR tests\n\ -c Explicitly declare this a connection test such as\n\ TCP_CRR or TCP_CC\n\ -C Set TCP_CORK when available\n\ -d direction Explicitly set test direction based on bitwise OR\n\ of 0x2 for transmit and 0x4 for receive. Default:\n\ based on test type\n\ -D [L][,R] Set TCP_NODELAY locally and/or remotely (TCP_*)\n\ -h Display this text\n\ -H name[/mask],fam Use name (or IP) and family as target of data connection\n\ A mask value will cause randomization of the IP used\n\ -k [file] Generate keyval output optionally based on file\n\ Use filename of '?' to get the list of choices\n\ -K loc[,rem] Set the local and/or remote congestion control\n\ algorithm to use on those platforms where it can\n\ be set.\n\ -L name[/mask],fam Use name (or IP) and family as source of data connection\n\ A mask value will cause randomization of the IP used\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\ -o [file] Generate CSV output optionally based on file\n\ Use filename of '?' to get the list of choices\n\ -O [file] Generate classic-style output based on file\n\ Use filename of '?' to get the list of choices\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\ -R 0/1 Allow routing of traffic on data connection.\n\ Default: 0 (off) for UDP_STREAM, 1 (on) otherwise\n\ -s send[,recv] Set local socket send/recv buffer sizes\n\ -S send[,recv] Set remote socket send/recv buffer sizes\n\ -t type Explicitly set socket type. Default is implicit\n\ based on other settings\n\ -T protocol Explicitly set data connection protocol. Default is\n\ implicit based on other settings\n\ -u uuid Use the supplied string as the UUID for this test.\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"; void print_omni_usage() { fwrite(omni_usage, sizeof(char), strlen(omni_usage), stdout); exit(1); } void scan_omni_args(int argc, char *argv[]) { #define OMNI_ARGS "b:cCd:DG:hH:kK:l:L:m:M:nNoOp:P:r:R:s:S:t:T:u:Vw:W:46" extern char *optarg; /* pointer to option string */ int c; int have_uuid = 0; int have_R_option = 0; char arg1[BUFSIZ], /* argument holders */ arg2[BUFSIZ], arg3[BUFSIZ]; if (debug) { int i; printf("%s called with the following argument vector\n", __FUNCTION__); 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)); /* this will handle setting default settings based on test name */ set_omni_defaults_by_legacy_testname(); /* 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_omni_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, but only for an actual omni test and then disable implicit setting of direction */ if (!was_legacy) { direction = parse_direction(optarg); implicit_direction = 0; } break; case 'D': /* set the TCP nodelay flag */ loc_nodelay = 1; rem_nodelay = 1; break; case 'G': /* set the value for a tcp_maxseG call*/ transport_mss_req = atoi(optarg); break; case 'H': break_args_explicit_sep(optarg,',',arg1,arg2); if (arg1[0]) { /* check to see if there was a width, which we would want to be arg3. for simplicities sake, we will assume the width must follow the address and not the address family - ie 1.2.3.4/24,inet. This means we can just pass optarg again as the source rather than have to shuffle arg values. */ break_args_explicit_sep(optarg,'/',arg1,arg3); if (arg1[0]) { remote_data_address = malloc(strlen(arg1)+1); strcpy(remote_data_address,arg1); explicit_data_address = 1; } if (arg3[0]) { remote_mask_len = convert(arg3); } } if (arg2[0]) { remote_data_family = parse_address_family(arg2); } break; case 'k': netperf_output_mode = KEYVAL; legacy = 0; /* obliterate any previous file name */ if (output_selection_spec) { free(output_selection_spec); output_selection_spec = 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. */ output_selection_spec = strdup(argv[optind]); optind++; /* special case - if the file name is "?" then we will emit a list of the available outputs */ if (strcmp(output_selection_spec,"?") == 0) { dump_netperf_output_choices(stdout,1); exit(1); } } break; case 'K': /* "Kongestion Kontrol */ break_args(optarg,arg1,arg2); if (arg1[0]) strncpy(local_cong_control_req,arg1,sizeof(local_cong_control_req)); if (arg2[2]) strncpy(remote_cong_control_req,arg2,sizeof(remote_cong_control_req)); break; case 'l': multicast_ttl = atoi(optarg); break; case 'L': break_args_explicit_sep(optarg,',',arg1,arg2); if (arg1[0]) { /* check to see if there was a width, which we would want to be arg3. for simplicities sake, we will assume the width must follow the address and not the address family - ie 1.2.3.4/24,inet. This means we can just pass optarg again as the source rather than have to shuffle arg values. */ break_args_explicit_sep(optarg,'/',arg1,arg3); if (arg1[0]) { local_data_address = malloc(strlen(arg1)+1); strcpy(local_data_address,arg1); } if (arg3[0]) { local_mask_len = convert(arg3); } } 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); if (implicit_direction) direction |= NETPERF_XMIT; } if (arg2[0]) { remote_send_size_req = convert(arg2); if (implicit_direction) 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); if (implicit_direction) direction |= NETPERF_XMIT; } if (arg2[0]) { recv_size = convert(arg2); if (implicit_direction) 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': netperf_output_mode = CSV; legacy = 0; /* obliterate any previous file name */ if (output_selection_spec) { free(output_selection_spec); output_selection_spec = NULL; } if (output_selection_spec) { free(output_selection_spec); output_selection_spec = 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. */ output_selection_spec = strdup(argv[optind]); optind++; /* special case - if the file name is "?" then we will emit a list of the available outputs */ if (strcmp(output_selection_spec,"?") == 0) { dump_netperf_output_choices(stdout,1); exit(1); } } break; case 'O': netperf_output_mode = HUMAN; legacy = 0; /* obliterate any previous file name */ if (output_selection_spec) { free(output_selection_spec); output_selection_spec = 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 */ output_selection_spec = strdup(argv[optind]); optind++; if (strcmp(output_selection_spec,"?") == 0) { dump_netperf_output_choices(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 */ if (implicit_direction) { 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 'R': routing_allowed = atoi(optarg); have_R_option = 1; 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... */ loc_sndavoid = 1; loc_rcvavoid = 1; 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); /* to cover the backside of blithering idiots who run unidirectional UDP tests on test setups where they might trash their corporate WAN, we grudgingly provide a safety latch. unless explicitly enabled, UDP_STREAM/UDP_MAERTS sockets will not allow themselves to be routed via a gateway. raj 20091026 */ if ((!have_R_option) && (protocol == IPPROTO_UDP) && (!NETPERF_IS_RR(direction))) { routing_allowed = 0; } /* 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_HISTOGRAM) if (verbosity > 1) keep_histogram = 1; #endif /* did the user use -d 6 but not set -r? */ if (NETPERF_IS_RR(direction) && !NETPERF_CC(direction)) { if (req_size == -1) req_size = 1; if (rsp_size == -1) rsp_size = 1; } /* 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) { if (strcmp(remote_data_port,"0") == 0) { /* we need to select either the discard port, echo port or chargen port dedepending on the test direction. raj 20101220 */ if (NETPERF_XMIT_ONLY(direction)) { strncpy(remote_data_port,"discard",sizeof(remote_data_port)); recv_size = -1; } else if (NETPERF_RECV_ONLY(direction)) { strncpy(remote_data_port,"chargen",sizeof(remote_data_port)); send_size = -1; } else if (NETPERF_IS_RR(direction) || NETPERF_CC(direction)) { strncpy(remote_data_port,"echo",sizeof(remote_data_port)); rsp_size = req_size; } 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; } /* so, did the user request a few things implicitly via output selection? */ if (!legacy) print_omni_init(); if (desired_output_groups & OMNI_WANT_STATS) { keep_statistics = 1; keep_histogram = 1; } } #endif /* WANT_OMNI */ netperf-2.6.0/src/netsec_linux.c0000644000175000017500000000560711712332266013551 00000000000000#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 netperf-2.6.0/src/netsys_hpux11i.c0000644000175000017500000000313011712332526013741 00000000000000#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"); } netperf-2.6.0/src/nettest_sctp.h0000644000175000017500000001171711525015213013564 00000000000000/* 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 scan_sctp_args( int argc, char *argv[] ); extern void send_sctp_stream( char remote_host[] ); extern void send_sctp_stream_1toMany( char remote_host[] ); extern void send_sctp_rr( char remote_host[] ); extern void send_sctp_rr_1toMany( char remote_host[] ); extern void recv_sctp_stream( void ); extern void recv_sctp_stream_1toMany( void ); extern void recv_sctp_rr( void ); extern void recv_sctp_rr_1toMany( void ); extern void loc_cpu_rate(); extern void rem_cpu_rate(); netperf-2.6.0/src/nettest_dlpi.h0000644000175000017500000001725711525015213013550 00000000000000/* 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[]); netperf-2.6.0/src/netslot_ux1131.c0000644000175000017500000000635311712332460013556 00000000000000/* Copyright 2010, Hewlett-Packard Company */ #include #include #include #include #include #include #include /* * No OLAR headerfile on target system! ;-( Yes, this means that these * interfaces are NOT DOCUMENTED FOR PUBLIC USE, which means you don't * really see what you are reading here, and if you attempt to use it * elsewhere, no one will profess any knowledge of what you are doing. * You will be utterly and completely on your own. */ typedef uint64_t olar_io_slot_t; typedef struct olar_error_info { int oe_err; char oe_hwpath[MAX_HW_PATH_STR]; } olar_err_t; #define MAX_SLOT_ID_LEN 30 char * get_hw_path_from_if(char *if_name); char * find_interface_slot(char *interface_name) { char *hw_str; olar_io_slot_t slot_id; olar_err_t oe; char slot_str[MAX_SLOT_ID_LEN]; /* Open dev_config for libIO communication */ if ( io_init(O_RDONLY) == IO_ERROR ) { return strdup("io_init"); } hw_str = get_hw_path_from_if(interface_name); /* close dev_config */ io_end(); slot_id = 0; if ( olar_path_to_id(hw_str,&slot_id,&oe) == -1 ) { /* since the call failed, lets give them the HW path as a consolation prize. we will ass-u-me that the caller will be freeing the string we give him anyway. */ if (debug) { fprintf(where, "%s olar_path_to_id hw_str %s oe_err %d path %s\n", __func__, hw_str, oe.oe_err, oe.oe_hwpath); fflush(where); } return hw_str; } if ( olar_slot_id_to_string(slot_id,slot_str,30) == -1 ) { /* do the same thing here, give them the hw path if this call fails */ if (debug) { fprintf(where, "%s olar_slot_id_to_string slot_id %" PRId64 "\n", slot_id); fflush(where); } return hw_str; } /* we can give them the honest to goodness slot id as a string now, so let us free that which we should free */ free(hw_str); return strdup(slot_str); } /* * Returns the H/W path string corresponding to the lan if name * * Assumption: if_name is of type lan%ppid * Not known to work with Logical,Vlan etc.. * */ char * get_hw_path_from_if(char *if_name) { int instance; io_token_t tok; hw_path_t hw; char *hwstr; sscanf(if_name,"lan%d",&instance); if ( (tok = io_search(NULL,S_IOTREE_EXT,0,"class", "lan", "instance", &instance, NULL)) == NULL ) { /* we don't want extraneous output on netserver side - at some point we can teach it about "where" */ /* io_error("Could not find H/w path"); */ return(NULL); } if ( io_node_to_hw_path(tok, &hw) != IO_SUCCESS ) { /* io_error("io_node_to_hw_path failed"); */ return NULL; } hwstr = (char *) malloc (MAX_HW_PATH_STR * sizeof(char)); if (hwstr == NULL ) { /* perror("malloc failed in get_hw_path_from_if"); */ return NULL; } if (io_hw_path_to_str(hwstr,&hw) == IO_ERROR ) { /* io_error("io_hw_path_to_str failed"); */ free(hwstr); return NULL; } return hwstr; } 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; } netperf-2.6.0/src/netsec_none.c0000644000175000017500000000113611614103731013334 00000000000000#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 netperf-2.6.0/src/nettest_unix.h0000644000175000017500000001606311525015213013575 00000000000000/* 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(); netperf-2.6.0/src/netlib.c0000644000175000017500000041031511770160735012326 00000000000000char netlib_id[]="\ @(#)netlib.c (c) Copyright 1993-2012 Hewlett-Packard Company. Version 2.6.0"; /****************************************************************/ /* */ /* 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 */ /* random_ip_address() select a random IP address from */ /* specified range */ /* */ /* the routines you get when WANT_DLPI is defined... */ /* ...all moved to src/nettest_dlpi.c */ /* */ /* 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 HAVE_SYSCALL_H #include #endif #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 #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 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 HAVE_MPCTL #include #endif #if !defined(HAVE_GETADDRINFO) || !defined(HAVE_GETNAMEINFO) # include "missing/getaddrinfo.h" #endif #include "hist.h" /****************************************************************/ /* */ /* Local Include Files */ /* */ /****************************************************************/ #define NETLIB #include "netlib.h" #include "netsh.h" #include "netcpu.h" #include "netperf_version.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; int control_family = AF_UNSPEC; /* 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; char *netperf_version; enum netperf_output_modes netperf_output_mode = HUMAN; /* 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 WIN32 HANDLE hAlarm = INVALID_HANDLE_VALUE; int timed_out=0; #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 #ifdef WIN32 HANDLE WinTimer; UINT timerRes; void stop_itimer() { CancelWaitableTimer(WinTimer); CloseHandle(WinTimer); timeEndPeriod(timerRes); } #else 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 /* WIN32 */ #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 #ifdef SOCK_SEQPACKET case SOCK_SEQPACKET: return("SOCK_SEQPACKET"); #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 #if defined(IPPROTO_UDPLITE) case IPPROTO_UDPLITE: return "IPPROTO_UDPLITE"; 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"); #if defined(AF_INET6) case AF_INET6: return("AF_INET6"); #endif #if defined(AF_INET_SDP) case AF_INET_SDP: return("AF_INET_SDP"); #endif #if defined(AF_RDS) case AF_RDS: return("AF_RDS"); #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 #if defined(AF_RDS) case AF_RDS: if (cnt >= 4) { memcpy(dst,src,4); return 4; } #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); } /* The original patch from Google used lrand48, but I have been informed that is not easily available under Windows. So, rather than have some #ifdefs here I'll just simplistically replace lrand48 with rand(), which should be "good enough" at some point it may be sufficient to just call rand() directly rather than call this raj 20101130 */ unsigned int rand32(){ return (unsigned int)rand() * 2 + rand() % 2; } /* this routine will set the ip address of the sockaddr in the addrinfo to a random number in range, based on the address family. for grins, we will sanity check the value of mask_len against the address family. initial version from google, enhancements by raj 20101129 */ void random_ip_address(struct addrinfo *res, int mask_len) { switch(res->ai_family) { case AF_INET: { struct sockaddr_in *foo = (struct sockaddr_in *)res->ai_addr; unsigned int addr = ntohl(foo->sin_addr.s_addr); unsigned int mask = ((unsigned int)1 << (32 - mask_len)) - 1; if ((mask_len < 0) || (mask_len > 32)) { fprintf(where, "Mask length must be between 0 and 32 inclusive for AF_INET\n"); fflush(where); exit(-1); } addr = ntohl(foo->sin_addr.s_addr); do { addr = (addr & ~mask) | (rand32() & mask); } while ((addr & 0xff) == 0xff); foo->sin_addr.s_addr = htonl(addr); break; } #if defined(AF_INET6) case AF_INET6: { struct sockaddr_in6 *foo = (struct sockaddr_in6 *)res->ai_addr; unsigned int i, len; unsigned int *addr = (unsigned int *)&(foo->sin6_addr.s6_addr); unsigned int mask; if ((mask_len < 0) || (mask_len > 128)) { fprintf(where, "Mask length must be between 0 and 128 inclusive for AF_INET\n"); fflush(where); exit(-1); } for (i = 0; i < 4; i ++){ addr[i] = ntohl(addr[i]); len = mask_len - i * 32; len = ((len < 32) ? len : 32); len = ((len > 0) ? len : 0); mask = ((unsigned int)1 << (32 - len)) - 1; addr[i] = (addr[i] & ~mask) | (rand32() & mask); addr[i] = htonl(addr[i]); } break; } #endif default: fprintf(where, "Unexpected Address Family of %u\n",res->ai_family); fflush(where); exit(-1); } } /* 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" "Please alter MAXCPUS in netlib.h and recompile.\n", temp_cpus, MAXCPUS); 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 */ /* 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 */ } /************************************************************************/ /* */ /* signal catcher */ /* */ /************************************************************************/ #ifndef WIN32 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: times_up = 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(); /* we should also stop the normal test timer lest it fire at an inopportune moment - we do not know if we got here off the interval timer or the test timer... */ stop_timer(); #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; } #endif /* WIN32 */ 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. */ timed_out=0; if (WaitForSingleObject(hAlarm, PAD_TIME/2*1000) == WAIT_TIMEOUT) { timed_out=1; /* 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; #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 */ sigemptyset(&(action.sa_mask)); sigaddset(&(action.sa_mask),SIGALRM); if (sigaction(SIGALRM, &action, NULL) < 0) { fprintf(where, "start_timer: error installing alarm handler errno %d\n", errno); fflush(where); exit(-1); } sigemptyset(&(action.sa_mask)); sigaddset(&(action.sa_mask),SIGINT); if (sigaction(SIGINT, &action, NULL) < 0) { fprintf(where, "start_timer: error installing SIGINT handler 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); exit(-1); } #endif /* WIN32 */ test_len_ticks = 1; } #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 ) { #ifdef WIN32 LARGE_INTEGER liDueTime; TIMECAPS ptc; MMRESULT mmr; /* make sure timer resolution is at least as small as interval length */ timerRes=interval_len_msec; mmr=timeGetDevCaps(&ptc, sizeof (ptc)); if (mmr==TIMERR_NOERROR){ if (interval_len_msec 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 test len %d ticks\n", usec_per_itvl / 1000000, usec_per_itvl % 1000000, 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 /* WIN32*/ } #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; netperf_version = strdup(NETPERF_VERSION); /* 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" "netlib_init: response_array at %p\n", request_array, response_array); fflush(where); } /* some functionality might want to use random numbers, so we should initialize the random number generator */ srand(getpid()); } /* 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 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 be filled from "default_fill" which will be "netperf" so anyone sniffing the traffic will have a better idea what this traffic happens to be. */ 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(local_fill_file,"") == 0) { do_fill = 0; fill_source = NULL; } else { do_fill = 1; fill_source = (FILE *)fopen(local_fill_file,"r"); if (fill_source == (FILE *)NULL) { fprintf(where,"Could not open requested fill file: %s\n", strerror(errno)); fflush(where); } } 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) { fprintf(where, "malloc(%u) failed!\n", (unsigned int)sizeof(struct ring_elt)); exit(-1); } temp_link->completion_ptr = NULL; /* 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) { fprintf(where, "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 local_fill_file. if local_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 (local_fill_file, "") == 0) { do_fill = 0; fill_source = NULL; } else { do_fill = 1; fill_source = (FILE *) fopen (local_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 is 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(local_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; /* we initialize the random number generator in netlib_init() now. raj 20110111 */ /* 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(local_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(local_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" "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) { fprintf(where, "malloc(%u) failed!\n", (unsigned int) 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", (unsigned int) 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", (unsigned int) 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", (unsigned int) 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); } /* go back and "undo" the ntohl that recv_request() did, starting with the specified point and going to the end of the request array */ void fixup_request_n(int n) { int i; int limit; limit = sizeof(netperf_request) / 4; /* we must remember that the request_array also contains two ints of "other" stuff, so we start the fixup two in - at least I think we should. raj 2012-04-02 */ for (i = n + 2; i < limit; i++) { request_array[i] = htonl(request_array[i]); } if (debug > 1) { fprintf(where, "%s: request contents after fixup at the %d th int\n", __FUNCTION__, n); dump_request(); fflush(where); } } /* 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 */ int recv_request_timed_n(int n, int seconds) { int tot_bytes_recvd, bytes_recvd, bytes_left; char *buf = (char *)&netperf_request; int buflen = sizeof(netperf_request); int counter,count; fd_set readfds; struct timeval timeout; 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; } /* for the time being, we rather rely on select decrementing timeout each time to preclude someone with nefarious intent from just dribbling data to us piecemeal. of course, who knows what someone with nefarious intent might come-up with. raj 2012-01-23 */ tot_bytes_recvd = 0; bytes_recvd = 0; /* nt_lint; bytes_recvd uninitialized if buflen == 0 */ bytes_left = buflen; timeout.tv_sec = seconds; timeout.tv_usec = 0; do { FD_ZERO(&readfds); FD_SET(server_sock,&readfds); if (select(FD_SETSIZE, &readfds, 0, 0, (seconds > 0) ? &timeout : NULL) != 1) { fprintf(where, "Issue receiving request on control connection. Errno %d (%s)\n", errno, strerror(errno)); fflush(where); close(server_sock); return -1; } if ((bytes_recvd = recv(server_sock, buf, bytes_left, 0)) > 0) { tot_bytes_recvd += bytes_recvd; buf += bytes_recvd; bytes_left -= bytes_recvd; } } while ((tot_bytes_recvd != buflen) && (bytes_recvd > 0 )); /* 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); close(server_sock); return -1; } if (bytes_recvd == 0) { /* the remote has shutdown the control connection, we should shut it down as well and return */ if (debug) { fprintf(where, "recv_request: remote requested shutdown of control\n"); fflush(where); } close(server_sock); return 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); close(server_sock); return -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); } return buflen; } /* 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 */ int recv_request_n(int n) { return recv_request_timed_n(n,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. */ /* */ /***********************************************************************/ int recv_request() { return 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, "%s: no response received. errno %d counter %d\n", __FUNCTION__, 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, const char *host, char *port, int family) { struct sockaddr *ai_addr; struct addrinfo *temp; temp=info; fprintf(dumploc, "getaddrinfo returned the following for host '%s' port '%s' " " family %s\n", host, port, 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 */ fprintf(dumploc, "\tcannonical name: '%s'\n" "\tflags: %x family: %s: socktype: %s protocol %s addrlen %d\n", (temp->ai_canonname) ? temp->ai_canonname : "(nil)", 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) { int i; fprintf(dumploc, "\tsa_family: %s sadata:", inet_ftos(ai_addr->sa_family)); for (i = 0; i < (int) temp->ai_addrlen; i++) { fprintf(dumploc, (temp->ai_family == AF_INET) ? " %d" : " %.2x", (u_char)ai_addr->sa_data[i]); } fprintf(dumploc,"\n"); } temp = temp->ai_next; } fflush(dumploc); } struct addrinfo * resolve_host(char *hostname, char *port, int family) { struct addrinfo hints; struct addrinfo *ai; int count; int error; if (debug) { fprintf(where, "resolve_host called with host '%s' port '%s' family %s\n", hostname, port, inet_ftos(family)); fflush(where); } memset(&hints, 0, sizeof(hints)); hints.ai_family = family; hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = IPPROTO_TCP; hints.ai_flags = AI_CANONNAME|AI_ADDRCONFIG; count = 0; do { error = getaddrinfo((char *)hostname, (char *)port, &hints, &ai); 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("%s: could not resolve host '%s' port '%s' af %s" "\n\tgetaddrinfo returned %d %s\n", __FUNCTION__, hostname, port, inet_ftos(family), error, gai_strerror(error)); return(NULL); } if (debug) { dump_addrinfo(where, ai, hostname, port, family); } return (ai); } /* 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 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; struct addrinfo *local_res; struct addrinfo *remote_res; struct addrinfo *local_res_temp; struct addrinfo *remote_res_temp; remote_res = resolve_host(hostname, port, remfam); if (!remote_res) return(INVALID_SOCKET); local_res = resolve_host(localhost, localport, locfam); if (!local_res) return(INVALID_SOCKET); if (debug) { fprintf(where, "establish_control called with host '%s' port '%s' remfam %s\n" "\t\tlocal '%s' port '%s' locfam %s\n", hostname, port, inet_ftos(remfam), localhost, localport, inet_ftos(locfam)); fflush(where); } 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" " trying next address combination\n", errno, strerror(errno)); fflush(where); } } } else { /* the bind failed */ if (debug) { fprintf(where, "establish_control: bind failed, errno %d %s\n" " trying next address combination\n", errno, strerror(errno)); 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); } control_family = local_res_temp->ai_family; /* 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); control_family = AF_UNSPEC; 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); #ifdef WIN32 if (timed_out) lib_elapsed-=PAD_TIME/2; #endif *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" " elapsed_time = %f\n" " cpu_util = %f\n" " num cpu = %d\n", units_sent, elapsed_time, cpu_utilization, 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" " elapsed_time = %f\n" " cpu_util = %f\n" " num cpu = %d\n" "calc_service_demand got: thruput = %f\n" " servdem = %f\n", units_sent, elapsed_time, cpu_utilization, num_cpus, thruput, 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 */ #if defined(WANT_INTERVALS) || defined(WANT_DEMO) int demo_mode; /* are we actually in demo mode? = 0 == not in demo mode; 1 == classic unit based demo mode; 2 == always timestamp 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 #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 void demo_first_timestamp() { HIST_timestamp(demo_one_ptr); } /* 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 */ void demo_stream_setup(uint32_t a, uint32_t 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; } } } #ifdef WIN32 __forceinline void demo_interval_display(double actual_interval) #else inline void demo_interval_display(double actual_interval) #endif { static int count = 0; struct timeval now; gettimeofday(&now,NULL); switch (netperf_output_mode) { case HUMAN: fprintf(where, "Interim result: %7.2f %s/s over %.3f seconds ending at %ld.%.3ld\n", calc_thruput_interval(units_this_tick, actual_interval/1000000.0), format_units(), actual_interval/1000000.0, now.tv_sec, (long) now.tv_usec/1000); break; case CSV: fprintf(where, "%7.2f,%s/s,%.3f,%ld.%.3ld\n", calc_thruput_interval(units_this_tick, actual_interval/1000000.0), format_units(), actual_interval/1000000.0, now.tv_sec, (long) now.tv_usec/1000); break; case KEYVAL: fprintf(where, "NETPERF_INTERIM_RESULT[%d]=%.2f\n" "NETPERF_UNITS[%d]=%s/s\n" "NETPERF_INTERVAL[%d]=%.3f\n" "NETPERF_ENDING[%d]=%ld.%.3ld\n", count, calc_thruput_interval(units_this_tick, actual_interval/1000000.0), count, format_units(), count, actual_interval/1000000.0, count, now.tv_sec, (long) now.tv_usec/1000); count += 1; break; default: fprintf(where, "Hey Ricky you not fine, theres a bug at demo time. Hey Ricky!"); fflush(where); exit(-1); } fflush(where); } /* this has gotten long enough to warrant being an inline function rather than a macro, and it has been enough years since all the important compilers have supported such a construct so it should not be a big deal. raj 2012-01-23 */ #ifdef WIN32 /* It would seem that the Microsoft compiler will not inline across source files. So there is little point in having an inline directive in that situation. Of course that makes me wonder if an inline directive has to appear in netlib.h... */ void demo_interval_tick(uint32_t units) #else inline void demo_interval_tick(uint32_t units) #endif { double actual_interval = 0.0; switch (demo_mode) { case 0: return; case 1: /* use the unit accumulation first */ 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); } else return; break; case 2: /* Always timestamp */ units_this_tick += units; HIST_timestamp(demo_two_ptr); actual_interval = delta_micro(demo_one_ptr,demo_two_ptr); break; default: fprintf(where, "Unexpected value of demo_mode of %d. Please report this as a bug.\n", demo_mode); fflush(where); exit(-1); } /* units == 0 will be when we have completed a test. we want to emit a final interim results if there is anything to report */ if (actual_interval >= demo_interval) { /* time to emit an interim result, giving the current time to the millisecond for compatability with RRD */ demo_interval_display(actual_interval); 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; } } void demo_interval_final() { double actual_interval; switch (demo_mode) { case 0: return; case 1: case 2: if (units_this_tick > 0.0) { HIST_timestamp(demo_two_ptr); actual_interval = delta_micro(demo_one_ptr,demo_two_ptr); demo_interval_display(actual_interval); units_this_tick = 0.0; } } } void demo_stream_interval(uint32_t units) { demo_interval_tick(units); } void demo_rr_setup(uint32_t a) { if ((demo_mode) && (demo_units == 0)) { /* take whatever we are given */ demo_units = a; } } void demo_rr_interval(uint32_t units) { demo_interval_tick(units); } #endif /* 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_n(int max_outstanding) { HIST h; if((h = (HIST) malloc(sizeof(struct histogram_struct))) == NULL) { perror("HIST_new_n - histogram_struct malloc failed"); exit(1); } HIST_clear(h); /* we never want to have a full queue, so will trade a little space for that. one day we may still have to check for a full queue */ h->limit = max_outstanding + 1; /* now allocate the time_ones based on h->limit */ #ifdef HAVE_GETHRTIME h->time_ones = (hrtime_t *) malloc(h->limit * sizeof(hrtime_t)); #elif HAVE_GET_HRT h->time_ones = (hrt_t *) malloc(h->limit * sizeof(hrt_t)); #elif defined(WIN32) h->time_ones = (LARGE_INTEGER *) malloc(h->limit * sizeof(LARGE_INTEGER)); #else h->time_ones = (struct timeval *) malloc(h->limit * sizeof(struct timeval)); #endif /* HAVE_GETHRTIME */ if (h->time_ones == NULL) { perror("HIST_new_n - time_ones malloc failed"); exit(1); } return h; } HIST HIST_new(void){ return HIST_new_n(0); } void HIST_clear(HIST h){ int i; for(i = 0; i < HIST_NUM_OF_BUCKET; 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; h->sum = 0; h->sumsquare = 0; h->hmin = 0; h->hmax = 0; h->limit = 0; h->count = 0; h->producer = 0; h->consumer = 0; h->time_ones = NULL; } void HIST_purge(HIST h) { h->count = 0; h->producer = 0; h->consumer = 0; } void HIST_add(register HIST h, int time_delta){ register float val; register int base = HIST_NUM_OF_BUCKET / 10; /* check for < 0 added via VMware ESX patches. */ /* hoisted up to the top because we do not want to count any ridiculous values in the actual statistics. right? raj 2011-07-28 */ if (time_delta < 0) { h->ridiculous++; return; } if (!h->total) h->hmin = h->hmax = time_delta; h->total++; h->sum += time_delta; /* am I just being paranoid about the overhead of pow() when we aren't all that interested in the statistics derived from it? raj 20100914 */ if (keep_statistics) { h->sumsquare += pow(time_delta, 2); } h->hmin = ((h->hmin < time_delta) ? h->hmin : time_delta); h->hmax = ((h->hmax > time_delta) ? h->hmax : time_delta); val = (float) time_delta; if(val < 10) h->unit_usec[(int)(val * base)]++; else { val /= 10; if(val < 10) h->ten_usec[(int)(val * base)]++; else { val /= 10; if(val < 10) h->hundred_usec[(int)(val * base)]++; else { val /= 10; if(val < 10) h->unit_msec[(int)(val * base)]++; else { val /= 10; if(val < 10) h->ten_msec[(int)(val * base)]++; else { val /= 10; if(val < 10) h->hundred_msec[(int)(val * base)]++; else { val /= 10; if(val < 10) h->unit_sec[(int)(val * base)]++; else { val /= 10; if(val < 10) h->ten_sec[(int)(val * base)]++; else h->ridiculous++; } } } } } } } } void output_row(FILE *fd, char *title, int *row){ register int i; register int j; register int base = HIST_NUM_OF_BUCKET / 10; register int sum; fprintf(where,"%s", title); for(i = 0; i < 10; i++){ sum = 0; for (j = i * base; j < (i + 1) * base; j++) { sum += row[j]; } fprintf(where,": %4d", sum); } fprintf(where,"\n"); } int sum_row(int *row) { int sum = 0; int i; for (i = 0; i < HIST_NUM_OF_BUCKET; 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); fprintf(where,">100_SECS: %d\n", h->ridiculous); fprintf(where,"HIST_TOTAL: %d\n", h->total); if (debug) { fprintf(where, "sum %"PRIi64", sumsquare %f, limit %d count %d\n", h->sum, h->sumsquare, h->limit, h->count); } } /* search buckets for each unit */ int HIST_search_bucket(int *unit, int num, int *last, int *current, double scale){ int base = HIST_NUM_OF_BUCKET / 10; int i; for (i = 0; i < HIST_NUM_OF_BUCKET; i++){ *last = *current; *current += unit[i]; if (*current >= num) return (int)((i + (double)(num - *last)/(*current - *last)) * scale/base); } return 0; } /* get percentile from histogram */ int HIST_get_percentile(HIST h, const double percentile){ double win_kludge = percentile * (double) h->total; int num = (int) win_kludge; int last = 0; int current = 0; int result; if (!num) return 0; /* search in unit usec range */ result = HIST_search_bucket(h->unit_usec, num, &last, ¤t, 1e0); if (result) return result; /* search in ten usec range */ result = HIST_search_bucket(h->ten_usec, num, &last, ¤t, 1e1); if (result) return result; /* search in ten hundred usec range */ result = HIST_search_bucket(h->hundred_usec, num, &last, ¤t, 1e2); if (result) return result; /* search in unic msec range */ result = HIST_search_bucket(h->unit_msec, num, &last, ¤t, 1e3); if (result) return result; /* search in ten msec range */ result = HIST_search_bucket(h->ten_msec, num, &last, ¤t, 1e4); if (result) return result; /* search in hundred msec range */ result = HIST_search_bucket(h->hundred_msec, num, &last, ¤t, 1e5); if (result) return result; /* search in unit sec range */ result = HIST_search_bucket(h->unit_sec, num, &last, ¤t, 1e6); if (result) return result; /* search in ten sec range */ result = HIST_search_bucket(h->ten_sec, num, &last, ¤t, 1e7); if (result) return result; return (int)(1e8); } /* get basic stats */ void HIST_get_stats(HIST h, int *min, int *max, double *mean, double *stddev){ *min = h->hmin; *max = h->hmax; if (h->total){ *mean = (double)h->sum / (double)h->total; *stddev = (h->sumsquare * h->total - pow((double)h->sum, 2)) / pow(h->total, 2); *stddev = sqrt(*stddev); } else{ *mean = 0; *stddev = 0; } } /* 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 */ void HIST_timestamp_start(HIST h) { if (NULL == h) { fprintf(where,"HIST_timestamp_start called with NULL histogram\n"); fflush(where); exit(-1); } if (h->count == h->limit) { fprintf(where,"HIST_timestamp_start called with full time_ones\n"); } HIST_timestamp(&(h->time_ones[h->producer])); h->producer += 1; h->producer %= h->limit; h->count += 1; } /* snap an ending timestamp and add the delta to the histogram */ void HIST_timestamp_stop_add(HIST h) { if (NULL == h) { fprintf(where,"HIST_timestamp_stop called with NULL histogram\n"); fflush(where); exit(-1); } if (h->consumer == h->producer) { fprintf(where, "HIST_timestamp_stop called with empty time_ones consumer %d producer %d\n", h->consumer, h->producer); fflush(where); exit(-1); } /* take our stopping timestamp */ HIST_timestamp(&(h->time_two)); /* now add it */ HIST_add(h,delta_micro(&(h->time_ones[h->consumer]),&(h->time_two))); h->consumer += 1; h->consumer %= h->limit; h->count -= 1; } /* 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" " lcpu %f; rcpu %f\n" " lsdm %f; rsdm %f\n", confidence_iterations, time, result, loc_cpu, rem_cpu, 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 desired confidence in the results. it will print the achieved confidence to "where" raj 11/94 */ void display_confidence() { fprintf(where, "!!! WARNING\n" "!!! Desired confidence was not achieved within " "the specified iterations.\n" "!!! This implies that there was variability in " "the test environment that\n" "!!! must be investigated before going further.\n" "!!! Confidence intervals: Throughput : %4.3f%%\n" "!!! Local CPU util : %4.3f%%\n" "!!! Remote CPU util : %4.3f%%\n\n", 100.0 * (interval - result_confid), 100.0 * (interval - loc_cpu_confid), 100.0 * (interval - rem_cpu_confid)); } netperf-2.6.0/src/netperf_version.h0000644000175000017500000000004011770160523014247 00000000000000#define NETPERF_VERSION "2.6.0" netperf-2.6.0/src/dirs0000644000175000017500000000004511525015213011550 00000000000000DIRS= \ NetPerfDir \ NetServerDirnetperf-2.6.0/src/hist.h0000644000175000017500000000700611732412555012022 00000000000000#if TIME_WITH_SYS_TIME # include # include #else # if HAVE_SYS_TIME_H # include # else # include # endif #endif #ifdef WIN32 # include "missing\stdint.h" #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 #if defined(HAVE_GET_HRT) #include "hrt.h" #endif #ifndef HIST_NUM_OF_BUCKET #define HIST_NUM_OF_BUCKET 100 #endif struct histogram_struct { int unit_usec[HIST_NUM_OF_BUCKET]; int ten_usec[HIST_NUM_OF_BUCKET]; int hundred_usec[HIST_NUM_OF_BUCKET]; int unit_msec[HIST_NUM_OF_BUCKET]; int ten_msec[HIST_NUM_OF_BUCKET]; int hundred_msec[HIST_NUM_OF_BUCKET]; int unit_sec[HIST_NUM_OF_BUCKET]; int ten_sec[HIST_NUM_OF_BUCKET]; int ridiculous; int total; int64_t sum; double sumsquare; int hmin; int hmax; int limit; int count; int producer; int consumer; #ifdef HAVE_GETHRTIME hrtime_t *time_ones; hrtime_t time_two; #elif HAVE_GET_HRT hrt_t *time_ones; hrt_t time_two; #elif defined(WIN32) LARGE_INTEGER *time_ones; LARGE_INTEGER time_two; #else struct timeval *time_ones; struct timeval time_two; #endif /* HAVE_GETHRTIME */ }; typedef struct histogram_struct *HIST; /* HIST_new - return a new, cleared histogram data type */ HIST HIST_new(void); /* HIST_new_n - return a new, cleard histogram data type able to track at least max_outstanding timestamps */ HIST HIST_new_n(int max_outstanding); /* HIST_clear - reset a histogram by clearing all totals to zero */ void HIST_clear(HIST h); /* HIST_purge - forget about any remaining outstanding timestamps being tracked */ void HIST_purge(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 /* HIST_timestamp_start - start a new timestamp */ void HIST_timestamp_start(HIST h); /* HIST_timestamp_stop_add - complete the oldest outstanding timestamp and add it to the histogram */ void HIST_timestamp_stop_add(HIST h); /* 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 netperf-2.6.0/NEWS0000644000175000017500000000000011525015225010566 00000000000000netperf-2.6.0/depcomp0000755000175000017500000003305211525015225011461 00000000000000#! /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 netperf-2.6.0/install-sh0000755000175000017500000003253711611413243012115 00000000000000#!/bin/sh # install - install a program, script, or datafile scriptversion=2009-04-28.21; # UTC # 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. nl=' ' IFS=" "" $nl" # set DOITPROG to echo to test this script # Don't use :- since 4.3BSD and earlier shells don't like it. doit=${DOITPROG-} if test -z "$doit"; then doit_exec=exec else doit_exec=$doit fi # Put in absolute file names if you don't have them in your path; # or use environment vars. chgrpprog=${CHGRPPROG-chgrp} chmodprog=${CHMODPROG-chmod} chownprog=${CHOWNPROG-chown} cmpprog=${CMPPROG-cmp} cpprog=${CPPROG-cp} mkdirprog=${MKDIRPROG-mkdir} mvprog=${MVPROG-mv} rmprog=${RMPROG-rm} stripprog=${STRIPPROG-strip} posix_glob='?' initialize_posix_glob=' test "$posix_glob" != "?" || { if (set -f) 2>/dev/null; then posix_glob= else posix_glob=: fi } ' posix_mkdir= # Desired mode of installed file. mode=0755 chgrpcmd= chmodcmd=$chmodprog chowncmd= mvcmd=$mvprog rmcmd="$rmprog -f" stripcmd= src= dst= dir_arg= dst_arg= copy_on_change=false no_target_directory= usage="\ Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE or: $0 [OPTION]... SRCFILES... DIRECTORY or: $0 [OPTION]... -t DIRECTORY SRCFILES... or: $0 [OPTION]... -d DIRECTORIES... In the 1st form, copy SRCFILE to DSTFILE. In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. In the 4th, create DIRECTORIES. Options: --help display this help and exit. --version display version info and exit. -c (ignored) -C install only if different (preserve the last data modification time) -d create directories instead of installing files. -g GROUP $chgrpprog installed files to GROUP. -m MODE $chmodprog installed files to MODE. -o USER $chownprog installed files to USER. -s $stripprog installed files. -t DIRECTORY install into DIRECTORY. -T report an error if DSTFILE is a directory. Environment variables override the default commands: CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG " while test $# -ne 0; do case $1 in -c) ;; -C) copy_on_change=true;; -d) dir_arg=true;; -g) chgrpcmd="$chgrpprog $2" shift;; --help) echo "$usage"; exit $?;; -m) mode=$2 case $mode in *' '* | *' '* | *' '* | *'*'* | *'?'* | *'['*) echo "$0: invalid mode: $mode" >&2 exit 1;; esac shift;; -o) chowncmd="$chownprog $2" shift;; -s) stripcmd=$stripprog;; -t) dst_arg=$2 shift;; -T) no_target_directory=true;; --version) echo "$0 $scriptversion"; exit $?;; --) shift break;; -*) echo "$0: invalid option: $1" >&2 exit 1;; *) break;; esac shift done if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then # When -d is used, all remaining arguments are directories to create. # When -t is used, the destination is already specified. # Otherwise, the last argument is the destination. Remove it from $@. for arg do if test -n "$dst_arg"; then # $@ is not empty: it contains at least $arg. set fnord "$@" "$dst_arg" shift # fnord fi shift # arg dst_arg=$arg done fi if test $# -eq 0; then if test -z "$dir_arg"; then echo "$0: no input file specified." >&2 exit 1 fi # It's OK to call `install-sh -d' without argument. # This can happen when creating conditional directories. exit 0 fi if test -z "$dir_arg"; then trap '(exit $?); exit' 1 2 13 15 # Set umask so as not to create temps with too-generous modes. # However, 'strip' requires both read and write access to temps. case $mode in # Optimize common cases. *644) cp_umask=133;; *755) cp_umask=22;; *[0-7]) if test -z "$stripcmd"; then u_plus_rw= else u_plus_rw='% 200' fi cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; *) if test -z "$stripcmd"; then u_plus_rw= else u_plus_rw=,u+rw fi cp_umask=$mode$u_plus_rw;; esac fi for src do # Protect names starting with `-'. case $src in -*) src=./$src;; esac if test -n "$dir_arg"; then dst=$src dstdir=$dst test -d "$dstdir" dstdir_status=$? else # Waiting for this to be detected by the "$cpprog $src $dsttmp" command # might cause directories to be created, which would be especially bad # if $src (and thus $dsttmp) contains '*'. if test ! -f "$src" && test ! -d "$src"; then echo "$0: $src does not exist." >&2 exit 1 fi if test -z "$dst_arg"; then echo "$0: no destination specified." >&2 exit 1 fi dst=$dst_arg # Protect names starting with `-'. case $dst in -*) dst=./$dst;; esac # If destination is a directory, append the input filename; won't work # if double slashes aren't ignored. if test -d "$dst"; then if test -n "$no_target_directory"; then echo "$0: $dst_arg: Is a directory" >&2 exit 1 fi dstdir=$dst dst=$dstdir/`basename "$src"` dstdir_status=0 else # Prefer dirname, but fall back on a substitute if dirname fails. dstdir=` (dirname "$dst") 2>/dev/null || expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$dst" : 'X\(//\)[^/]' \| \ X"$dst" : 'X\(//\)$' \| \ X"$dst" : 'X\(/\)' \| . 2>/dev/null || echo X"$dst" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q' ` test -d "$dstdir" dstdir_status=$? fi fi obsolete_mkdir_used=false if test $dstdir_status != 0; then case $posix_mkdir in '') # Create intermediate dirs using mode 755 as modified by the umask. # This is like FreeBSD 'install' as of 1997-10-28. umask=`umask` case $stripcmd.$umask in # Optimize common cases. *[2367][2367]) mkdir_umask=$umask;; .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; *[0-7]) mkdir_umask=`expr $umask + 22 \ - $umask % 100 % 40 + $umask % 20 \ - $umask % 10 % 4 + $umask % 2 `;; *) mkdir_umask=$umask,go-w;; esac # With -d, create the new directory with the user-specified mode. # Otherwise, rely on $mkdir_umask. if test -n "$dir_arg"; then mkdir_mode=-m$mode else mkdir_mode= fi posix_mkdir=false case $umask in *[123567][0-7][0-7]) # POSIX mkdir -p sets u+wx bits regardless of umask, which # is incompatible with FreeBSD 'install' when (umask & 300) != 0. ;; *) tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 if (umask $mkdir_umask && exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 then if test -z "$dir_arg" || { # Check for POSIX incompatibilities with -m. # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or # other-writeable bit of parent directory when it shouldn't. # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. ls_ld_tmpdir=`ls -ld "$tmpdir"` case $ls_ld_tmpdir in d????-?r-*) different_mode=700;; d????-?--*) different_mode=755;; *) false;; esac && $mkdirprog -m$different_mode -p -- "$tmpdir" && { ls_ld_tmpdir_1=`ls -ld "$tmpdir"` test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" } } then posix_mkdir=: fi rmdir "$tmpdir/d" "$tmpdir" else # Remove any dirs left behind by ancient mkdir implementations. rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null fi trap '' 0;; esac;; esac if $posix_mkdir && ( umask $mkdir_umask && $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" ) then : else # The umask is ridiculous, or mkdir does not conform to POSIX, # or it failed possibly due to a race condition. Create the # directory the slow way, step by step, checking for races as we go. case $dstdir in /*) prefix='/';; -*) prefix='./';; *) prefix='';; esac eval "$initialize_posix_glob" oIFS=$IFS IFS=/ $posix_glob set -f set fnord $dstdir shift $posix_glob set +f IFS=$oIFS prefixes= for d do test -z "$d" && continue prefix=$prefix$d if test -d "$prefix"; then prefixes= else if $posix_mkdir; then (umask=$mkdir_umask && $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break # Don't fail if two instances are running concurrently. test -d "$prefix" || exit 1 else case $prefix in *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; *) qprefix=$prefix;; esac prefixes="$prefixes '$qprefix'" fi fi prefix=$prefix/ done if test -n "$prefixes"; then # Don't fail if two instances are running concurrently. (umask $mkdir_umask && eval "\$doit_exec \$mkdirprog $prefixes") || test -d "$dstdir" || exit 1 obsolete_mkdir_used=true fi fi fi if test -n "$dir_arg"; then { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 else # Make a couple of temp file names in the proper directory. dsttmp=$dstdir/_inst.$$_ rmtmp=$dstdir/_rm.$$_ # Trap to clean up those temp files at exit. trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 # Copy the file name to the temp name. (umask $cp_umask && $doit_exec $cpprog "$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 $cpprog $src $dsttmp" command. # { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && # If -C, don't bother to copy if it wouldn't change the file. if $copy_on_change && old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && eval "$initialize_posix_glob" && $posix_glob set -f && set X $old && old=:$2:$4:$5:$6 && set X $new && new=:$2:$4:$5:$6 && $posix_glob set +f && test "$old" = "$new" && $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 then rm -f "$dsttmp" else # Rename the file to the real destination. $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || # The rename failed, perhaps because mv can't rename something else # to itself, or perhaps because mv is so ancient that it does not # support -f. { # 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. { test ! -f "$dst" || $doit $rmcmd -f "$dst" 2>/dev/null || { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } } || { echo "$0: cannot unlink or rename $dst" >&2 (exit 1); exit 1 } } && # Now rename the file to the real destination. $doit $mvcmd "$dsttmp" "$dst" } fi || exit 1 trap '' 0 fi done # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC" # time-stamp-end: "; # UTC" # End: netperf-2.6.0/m4/0000755000175000017500000000000011525015206010500 500000000000000netperf-2.6.0/m4/.svn/0000755000175000017500000000000011770164645011402 500000000000000netperf-2.6.0/m4/.svn/tmp/0000755000175000017500000000000011753257340012176 500000000000000netperf-2.6.0/m4/.svn/tmp/text-base/0000755000175000017500000000000011525015206014060 500000000000000netperf-2.6.0/m4/.svn/tmp/prop-base/0000755000175000017500000000000011525015206014054 500000000000000netperf-2.6.0/m4/.svn/tmp/props/0000755000175000017500000000000011525015206013327 500000000000000netperf-2.6.0/m4/.svn/text-base/0000755000175000017500000000000011525015206013260 500000000000000netperf-2.6.0/m4/.svn/prop-base/0000755000175000017500000000000011525015206013254 500000000000000netperf-2.6.0/m4/.svn/entries0000444000175000017500000000030211753257340012703 0000000000000010 dir 575 http://www.netperf.org/svn/netperf2/trunk/m4 http://www.netperf.org/svn/netperf2 2008-03-18T21:08:56.012824Z 266 raj 5bbd99f3-5903-0410-b283-f1d88047b228 m4 dir netperf-2.6.0/m4/.svn/all-wcprops0000444000175000017500000000011411525015206013464 00000000000000K 25 svn:wc:ra_dav:version-url V 35 /svn/netperf2/!svn/ver/266/trunk/m4 END netperf-2.6.0/m4/.svn/props/0000755000175000017500000000000011525015206012527 500000000000000netperf-2.6.0/m4/m4/0000755000175000017500000000000011525015206011020 500000000000000netperf-2.6.0/m4/m4/.svn/0000755000175000017500000000000011770164645011722 500000000000000netperf-2.6.0/m4/m4/.svn/tmp/0000755000175000017500000000000011753257340012516 500000000000000netperf-2.6.0/m4/m4/.svn/tmp/text-base/0000755000175000017500000000000011525015206014400 500000000000000netperf-2.6.0/m4/m4/.svn/tmp/prop-base/0000755000175000017500000000000011525015206014374 500000000000000netperf-2.6.0/m4/m4/.svn/tmp/props/0000755000175000017500000000000011525015206013647 500000000000000netperf-2.6.0/m4/m4/.svn/text-base/0000755000175000017500000000000011525015206013600 500000000000000netperf-2.6.0/m4/m4/.svn/text-base/salen.m4.svn-base0000444000175000017500000000257211525015206016605 00000000000000dnl 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 ]) netperf-2.6.0/m4/m4/.svn/text-base/sockaddrin6.m4.svn-base0000444000175000017500000000523211525015206017706 00000000000000dnl * 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]) netperf-2.6.0/m4/m4/.svn/text-base/sockinttypes.m4.svn-base0000444000175000017500000001313711525015206020241 00000000000000dnl * 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]) netperf-2.6.0/m4/m4/.svn/prop-base/0000755000175000017500000000000011525015206013574 500000000000000netperf-2.6.0/m4/m4/.svn/entries0000444000175000017500000000116411753257340013232 0000000000000010 dir 575 http://www.netperf.org/svn/netperf2/trunk/m4/m4 http://www.netperf.org/svn/netperf2 2008-03-18T21:08:56.012824Z 266 raj 5bbd99f3-5903-0410-b283-f1d88047b228 salen.m4 file 2011-02-10T17:04:06.952170Z 0a5ed6a330cac1af2398fb47a8b2e3f8 2008-03-18T21:08:56.012824Z 266 raj 1402 sockaddrin6.m4 file 2011-02-10T17:04:06.952170Z 19d9c4f1138e5876254228d1b554c13d 2005-10-17T22:25:24.828295Z 33 raj 2714 sockinttypes.m4 file 2011-02-10T17:04:06.952170Z d5b12afdcfa72f3b6846639f0f91dd5f 2005-10-17T22:25:24.828295Z 33 raj 5727 netperf-2.6.0/m4/m4/.svn/all-wcprops0000444000175000017500000000061211525015206014007 00000000000000K 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 netperf-2.6.0/m4/m4/.svn/props/0000755000175000017500000000000011525015206013047 500000000000000netperf-2.6.0/m4/m4/sockaddrin6.m40000644000175000017500000000523211525015206013413 00000000000000dnl * 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]) netperf-2.6.0/m4/m4/sockinttypes.m40000644000175000017500000001313711525015206013746 00000000000000dnl * 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]) netperf-2.6.0/m4/m4/salen.m40000644000175000017500000000257211525015206012312 00000000000000dnl 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 ]) netperf-2.6.0/README.ovms0000644000175000017500000000451611525015225011752 00000000000000February 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. netperf-2.6.0/README.hpux0000644000175000017500000000335411525015225011751 00000000000000A 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. netperf-2.6.0/INSTALL0000644000175000017500000002203011525015225011127 00000000000000Copyright (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. netperf-2.6.0/aclocal.m40000644000175000017500000010442611770160503011752 00000000000000# generated automatically by aclocal 1.11.1 -*- Autoconf -*- # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, # 2005, 2006, 2007, 2008, 2009 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. m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.67],, [m4_warning([this file was generated for autoconf 2.67. You have another version of autoconf. It may work, but is not guaranteed to. If you have problems, you may need to regenerate the build system entirely. To do so, use the procedure documented by the package, typically `autoreconf'.])]) # Copyright (C) 2002, 2003, 2005, 2006, 2007, 2008 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. # 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. # (This private macro should not be called outside this file.) AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version='1.11' dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to dnl require some minimum version. Point them to the right macro. m4_if([$1], [1.11.1], [], [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl ]) # _AM_AUTOCONF_VERSION(VERSION) # ----------------------------- # aclocal traces this macro to find the Autoconf version. # This is a private macro too. Using m4_define simplifies # the logic in aclocal, which can simply ignore this definition. m4_define([_AM_AUTOCONF_VERSION], []) # AM_SET_CURRENT_AUTOMAKE_VERSION # ------------------------------- # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. # This function is AC_REQUIREd by AM_INIT_AUTOMAKE. AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], [AM_AUTOMAKE_VERSION([1.11.1])dnl m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) # AM_AUX_DIR_EXPAND -*- Autoconf -*- # Copyright (C) 2001, 2003, 2005 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. # 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. AC_DEFUN([AM_AUX_DIR_EXPAND], [dnl Rely on autoconf to set up CDPATH properly. AC_PREREQ([2.50])dnl # expand $ac_aux_dir to an absolute path am_aux_dir=`cd $ac_aux_dir && pwd` ]) # AM_CONDITIONAL -*- Autoconf -*- # Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005, 2006, 2008 # 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. # serial 9 # AM_CONDITIONAL(NAME, SHELL-CONDITION) # ------------------------------------- # Define a conditional. AC_DEFUN([AM_CONDITIONAL], [AC_PREREQ(2.52)dnl ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl AC_SUBST([$1_TRUE])dnl AC_SUBST([$1_FALSE])dnl _AM_SUBST_NOTMAKE([$1_TRUE])dnl _AM_SUBST_NOTMAKE([$1_FALSE])dnl m4_define([_AM_COND_VALUE_$1], [$2])dnl 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])]) # Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2009 # 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. # serial 10 # 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], UPC, [depcc="$UPC" am_compiler_list=], [$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 am__universal=false m4_case([$1], [CC], [case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac], [CXX], [case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac]) 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 # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with # Solaris 8's {/usr,}/bin/sh. touch sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf # 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. Also, some Intel # versions had trouble with output in subdirs am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in gcc) # This depmode causes a compiler race in universal mode. test "$am__universal" = false || continue ;; 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 ;; msvisualcpp | msvcmsys) # This compiler won't grok `-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} am__minus_obj= ;; none) break ;; esac if depmode=$depmode \ source=sub/conftest.c object=$am__obj \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep $am__obj 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 # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' 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 build --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])dnl _AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl ]) # Generate code to set up dependency tracking. -*- Autoconf -*- # Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2008 # 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. #serial 5 # _AM_OUTPUT_DEPENDENCY_COMMANDS # ------------------------------ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], [{ # Autoconf 2.62 quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. case $CONFIG_FILES in *\'*) eval set x "$CONFIG_FILES" ;; *) set x $CONFIG_FILES ;; esac shift for mf 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. # Grep'ing the whole file is not good either: AIX grep has a line # limit of 2048, but all sed's we know have understand at least 4000. if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then dirpart=`AS_DIRNAME("$mf")` else continue fi # Extract the definition of DEPDIR, am__include, and am__quote # from the Makefile without running `make'. DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` test -z "$DEPDIR" && continue am__include=`sed -n 's/^am__include = //p' < "$mf"` test -z "am__include" && continue am__quote=`sed -n 's/^am__quote = //p' < "$mf"` # When using ansi2knr, U may be empty or an underscore; expand it U=`sed -n 's/^U = //p' < "$mf"` # Find all dependency output files, they are included files with # $(DEPDIR) in their names. 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 " s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/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"]) ]) # Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005 # 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. # serial 8 # AM_CONFIG_HEADER is obsolete. It has been replaced by AC_CONFIG_HEADERS. AU_DEFUN([AM_CONFIG_HEADER], [AC_CONFIG_HEADERS($@)]) # Do all the work for Automake. -*- Autoconf -*- # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, # 2005, 2006, 2008, 2009 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. # serial 16 # 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. # 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_PREREQ([2.62])dnl dnl Autoconf wants to disallow AM_ names. We explicitly allow dnl the ones we care about. m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl AC_REQUIRE([AC_PROG_INSTALL])dnl if test "`cd $srcdir && pwd`" != "`pwd`"; then # Use -I$(srcdir) only when $(srcdir) != ., so that make's output # is not polluted with repeated "-I." AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl # test to see if srcdir already configured if test -f $srcdir/config.status; then AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) fi 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 dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. m4_if(m4_ifdef([AC_PACKAGE_NAME], 1)m4_ifdef([AC_PACKAGE_VERSION], 1), 11,, [m4_fatal([AC_INIT should be called with package and version arguments])])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) AC_REQUIRE([AM_PROG_INSTALL_SH])dnl AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl AC_REQUIRE([AM_PROG_MKDIR_P])dnl # 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([tar-ustar], [_AM_PROG_TAR([ustar])], [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], [_AM_PROG_TAR([v7])])]) _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 AC_PROVIDE_IFELSE([AC_PROG_OBJC], [_AM_DEPENDENCIES(OBJC)], [define([AC_PROG_OBJC], defn([AC_PROG_OBJC])[_AM_DEPENDENCIES(OBJC)])])dnl ]) _AM_IF_OPTION([silent-rules], [AC_REQUIRE([AM_SILENT_RULES])])dnl dnl The `parallel-tests' driver may need to know about EXEEXT, so add the dnl `am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This macro dnl is hooked onto _AC_COMPILER_EXEEXT early, see below. AC_CONFIG_COMMANDS_PRE(dnl [m4_provide_if([_AM_COMPILER_EXEEXT], [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl ]) dnl Hook into `_AC_COMPILER_EXEEXT' early to learn its expansion. Do not dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further dnl mangled by Autoconf and run in a shell conditional statement. m4_define([_AC_COMPILER_EXEEXT], m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])]) # 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_arg=$1 _am_stamp_count=1 for _am_header in $config_headers :; do case $_am_header in $_am_arg | $_am_arg:* ) break ;; * ) _am_stamp_count=`expr $_am_stamp_count + 1` ;; esac done echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) # Copyright (C) 2001, 2003, 2005, 2008 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. # AM_PROG_INSTALL_SH # ------------------ # Define $install_sh. AC_DEFUN([AM_PROG_INSTALL_SH], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl if test x"${install_sh}" != xset; then case $am_aux_dir in *\ * | *\ *) install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; *) install_sh="\${SHELL} $am_aux_dir/install-sh" esac fi AC_SUBST(install_sh)]) # Copyright (C) 2003, 2005 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. # serial 2 # 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])]) # Check to see how 'make' treats includes. -*- Autoconf -*- # Copyright (C) 2001, 2002, 2003, 2005, 2009 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. # serial 4 # 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 this is the am__doit target .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 # Ignore all kinds of additional output from `make'. case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=include am__quote= _am_result=GNU ;; esac # Now try BSD make style include. if test "$am__include" = "#"; then echo '.include "confinc"' > confmf case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=.include am__quote="\"" _am_result=BSD ;; esac fi AC_SUBST([am__include]) AC_SUBST([am__quote]) AC_MSG_RESULT([$_am_result]) rm -f confinc confmf ]) # Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- # Copyright (C) 1997, 1999, 2000, 2001, 2003, 2004, 2005, 2008 # 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. # serial 6 # 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 AC_REQUIRE_AUX_FILE([missing])dnl if test x"${MISSING+set}" != xset; then case $am_aux_dir in *\ * | *\ *) MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; *) MISSING="\${SHELL} $am_aux_dir/missing" ;; esac fi # 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 ]) # Copyright (C) 2003, 2004, 2005, 2006 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. # AM_PROG_MKDIR_P # --------------- # Check for `mkdir -p'. AC_DEFUN([AM_PROG_MKDIR_P], [AC_PREREQ([2.60])dnl AC_REQUIRE([AC_PROG_MKDIR_P])dnl dnl Automake 1.8 to 1.9.6 used to define mkdir_p. We now use MKDIR_P, dnl while keeping a definition of mkdir_p for backward compatibility. dnl @MKDIR_P@ is magic: AC_OUTPUT adjusts its value for each Makefile. dnl However we cannot define mkdir_p as $(MKDIR_P) for the sake of dnl Makefile.ins that do not define MKDIR_P, so we do our own dnl adjustment using top_builddir (which is defined more often than dnl MKDIR_P). AC_SUBST([mkdir_p], ["$MKDIR_P"])dnl case $mkdir_p in [[\\/$]]* | ?:[[\\/]]*) ;; */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;; esac ]) # Helper functions for option handling. -*- Autoconf -*- # Copyright (C) 2001, 2002, 2003, 2005, 2008 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. # serial 4 # _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], [m4_foreach_w([_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. -*- Autoconf -*- # Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005, 2008 # 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. # serial 5 # 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 # Reject unsafe characters in $srcdir or the absolute working directory # name. Accept space and tab only in the latter. am_lf=' ' case `pwd` in *[[\\\"\#\$\&\'\`$am_lf]]*) AC_MSG_ERROR([unsafe absolute working directory name]);; esac case $srcdir in *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*) AC_MSG_ERROR([unsafe srcdir value: `$srcdir']);; esac # 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)]) # Copyright (C) 2001, 2003, 2005 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. # AM_PROG_INSTALL_STRIP # --------------------- # 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="\$(install_sh) -c -s" AC_SUBST([INSTALL_STRIP_PROGRAM])]) # Copyright (C) 2006, 2008 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. # serial 2 # _AM_SUBST_NOTMAKE(VARIABLE) # --------------------------- # Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. # This macro is traced by Automake. AC_DEFUN([_AM_SUBST_NOTMAKE]) # AM_SUBST_NOTMAKE(VARIABLE) # --------------------------- # Public sister of _AM_SUBST_NOTMAKE. AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) # Check how to create a tarball. -*- Autoconf -*- # Copyright (C) 2004, 2005 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. # serial 2 # _AM_PROG_TAR(FORMAT) # -------------------- # Check how to create a tarball in format FORMAT. # FORMAT should be one of `v7', `ustar', or `pax'. # # Substitute a variable $(am__tar) that is a command # writing to stdout a FORMAT-tarball containing the directory # $tardir. # tardir=directory && $(am__tar) > result.tar # # Substitute a variable $(am__untar) that extract such # a tarball read from stdin. # $(am__untar) < result.tar AC_DEFUN([_AM_PROG_TAR], [# Always define AMTAR for backward compatibility. AM_MISSING_PROG([AMTAR], [tar]) m4_if([$1], [v7], [am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'], [m4_case([$1], [ustar],, [pax],, [m4_fatal([Unknown tar format])]) AC_MSG_CHECKING([how to create a $1 tar archive]) # Loop over all known methods to create a tar archive until one works. _am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' _am_tools=${am_cv_prog_tar_$1-$_am_tools} # Do not fold the above two line into one, because Tru64 sh and # Solaris sh will not grok spaces in the rhs of `-'. for _am_tool in $_am_tools do case $_am_tool in gnutar) for _am_tar in tar gnutar gtar; do AM_RUN_LOG([$_am_tar --version]) && break done am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' am__untar="$_am_tar -xf -" ;; plaintar) # Must skip GNU tar: if it does not support --format= it doesn't create # ustar tarball either. (tar --version) >/dev/null 2>&1 && continue am__tar='tar chf - "$$tardir"' am__tar_='tar chf - "$tardir"' am__untar='tar xf -' ;; pax) am__tar='pax -L -x $1 -w "$$tardir"' am__tar_='pax -L -x $1 -w "$tardir"' am__untar='pax -r' ;; cpio) am__tar='find "$$tardir" -print | cpio -o -H $1 -L' am__tar_='find "$tardir" -print | cpio -o -H $1 -L' am__untar='cpio -i -H $1 -d' ;; none) am__tar=false am__tar_=false am__untar=false ;; esac # If the value was cached, stop now. We just wanted to have am__tar # and am__untar set. test -n "${am_cv_prog_tar_$1}" && break # tar/untar a dummy directory, and stop if the command works rm -rf conftest.dir mkdir conftest.dir echo GrepMe > conftest.dir/file AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) rm -rf conftest.dir if test -s conftest.tar; then AM_RUN_LOG([$am__untar /dev/null 2>&1 && break fi done rm -rf conftest.dir AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) AC_MSG_RESULT([$am_cv_prog_tar_$1])]) AC_SUBST([am__tar]) AC_SUBST([am__untar]) ]) # _AM_PROG_TAR m4_include([src/missing/m4/salen.m4]) m4_include([acinclude.m4]) netperf-2.6.0/config.sub0000755000175000017500000007577711525015225012113 00000000000000#! /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: netperf-2.6.0/AUTHORS0000644000175000017500000001720111736436706011171 00000000000000This 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 workarounds to get Linux to report ENOBUFS on TX queue overflows 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) cleanups. Marcel Shuldman Changes to make netperf more profiling friendly Bruno Cornec Fixes to supply some missing fprintf format statements. Jose Pedro Oliveira Linux compilation fixes when SCTP and DCCP are enabled. Changes to configure.ac to allow it to inherit compiler flags from environment variables. Pal Baranyai Typo in nettest_dlpi.c Brian Haley Changes to allow something like netperf -H ::1 to work Frank Schuster Discovering that FreeBSD 8.X also does not need an SCTP library Josselin Costanzi DEBUG_LOG_FILE patch for Android Dongsheng Song Assorted Windows fixes Hushan Jia Fix to actually run SCTP_RR_MANY when requested David MacMahon davidm@astro.berkeley.edu Fix to allow configure in a build directory. Remove duplicate htonl in recv_udp_stream(). Masanari Iida Cleanups for the manual. Amir Vidai Patch from which changes to set SO_PRIORITY were based. Alexander Duyck Uncovering an out of bounds access of the netperf_output_source array. Bjoern A. Zeeb - a patch to enable netperf to correctly manipulate IPv6 addresses in the control message. Shachar Raindel - a patch to bring the "get linux to emit ENOBUFS" functionality from classic netperf tests to the omni tests. Chema Gonzalez - fixes for some assorted warnings. Dave Taht - changes for symbolic handling of TOS valuesnetperf-2.6.0/README0000644000175000017500000000407011525015225010762 00000000000000 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. netperf-2.6.0/README.vmware0000644000175000017500000000132011525015225012255 00000000000000Compiling 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. netperf-2.6.0/ChangeLog0000644000175000017500000000003311525015225011647 00000000000000See the file Release_Notes.netperf-2.6.0/inet_ntop.c0000644000175000017500000000003611525015225012243 00000000000000#include "missing\inet_ntop.c"netperf-2.6.0/config.h.in0000644000175000017500000002576011770160524012143 00000000000000/* 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 `daemon' function. */ #undef HAVE_DAEMON /* 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 `IO' library (-lIO). */ #undef HAVE_LIBIO /* 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 `olrad' library (-lolrad). */ #undef HAVE_LIBOLRAD /* 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_LINUX_TCP_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_IN_SYSTM_H /* Define to 1 if you have the header file. */ #undef HAVE_NETINET_IP_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 `setsid' function. */ #undef HAVE_SETSID /* 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_SYSCALL_H /* 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_IPC_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_SYSINFO_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 the header file. */ #undef HAVE_SYS_WAIT_H /* Define to 1 if you have the `toupper' function. */ #undef HAVE_TOUPPER /* 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 home page for this package. */ #undef PACKAGE_URL /* 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 migrate classic to OMNI tests. */ #undef WANT_MIGRATION /* 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 netperf-2.6.0/README.aix0000644000175000017500000000321111654272633011551 00000000000000Pseudo-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. Coutesy of Jan Krueger of TUI Infotec, Germany we have a pointer to a workaround for problems with compilation on AIX 6.1: https://www-304.ibm.com/support/docview.wss?uid=isg1IV01736 when you get errors like: config.status: creating src/netperf_version.h gcc -DHAVE_CONFIG_H -I. -I.. -MT netlib.o -MD -MP -MF .deps/netlib.Tpo -c -o netlib.o netlib.c In file included from /usr/include/sys/corral.h:25, from /usr/include/libperfstat.h:28, from netlib.h:679, from netlib.c:166: /usr/include/netinet/in6_var.h:65: error: array type has incomplete element type netperf-2.6.0/acinclude.m40000644000175000017500000003330611525015225012277 00000000000000 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])