import of iperf-2.0 release

This commit is contained in:
Jon Dugan 2007-08-29 21:57:27 +00:00
parent fc458a9768
commit aa594bbb79
81 changed files with 35454 additions and 0 deletions

13
INSTALL Normal file
View File

@ -0,0 +1,13 @@
$Id: INSTALL,v 1.1.1.1 2004/05/18 01:50:44 kgibbs Exp $
Platform Specific Notes
FreeBSD
If you use a cc or c++ other than the system one, threads may not be
detected properly. To work around this set the following environment
variables:
setenv CC /usr/bin/cc
setenv CXX /usr/bin/c++

3
Makefile.am Normal file
View File

@ -0,0 +1,3 @@
SUBDIRS = compat doc include src
EXTRA_DIST = autogen.sh

576
Makefile.in Normal file
View File

@ -0,0 +1,576 @@
# Makefile.in generated by automake 1.8.3 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
# 2003, 2004 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
top_builddir = .
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
INSTALL = @INSTALL@
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
host_triplet = @host@
DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \
$(srcdir)/Makefile.in $(srcdir)/config.h.in \
$(top_srcdir)/configure INSTALL config.guess config.sub \
depcomp install-sh missing
subdir = .
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/dast.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 configure.status.lineno
mkinstalldirs = $(mkdir_p)
CONFIG_HEADER = config.h
CONFIG_CLEAN_FILES =
SOURCES =
DIST_SOURCES =
RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
html-recursive info-recursive install-data-recursive \
install-exec-recursive install-info-recursive \
install-recursive installcheck-recursive installdirs-recursive \
pdf-recursive ps-recursive uninstall-info-recursive \
uninstall-recursive
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); }; }
DIST_ARCHIVES = $(distdir).tar.gz
GZIP_ENV = --best
distuninstallcheck_listfiles = find . -type f -print
distcleancheck_listfiles = find . -type f -print
ACLOCAL = @ACLOCAL@
AMDEP_FALSE = @AMDEP_FALSE@
AMDEP_TRUE = @AMDEP_TRUE@
AMTAR = @AMTAR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CXX = @CXX@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
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@
OBJEXT = @OBJEXT@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
RANLIB = @RANLIB@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
STRIP_BEGIN = @STRIP_BEGIN@
STRIP_DUMMY = @STRIP_DUMMY@
STRIP_END = @STRIP_END@
VERSION = @VERSION@
WEB100_CFLAGS = @WEB100_CFLAGS@
WEB100_CONFIG = @WEB100_CONFIG@
WEB100_LIBS = @WEB100_LIBS@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
ac_ct_RANLIB = @ac_ct_RANLIB@
ac_ct_STRIP = @ac_ct_STRIP@
am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
datadir = @datadir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localstatedir = @localstatedir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
prefix = @prefix@
program_transform_name = @program_transform_name@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
SUBDIRS = compat doc include src
EXTRA_DIST = autogen.sh
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) --foreign '; \
cd $(srcdir) && $(AUTOMAKE) --foreign \
&& exit 0; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \
cd $(top_srcdir) && \
$(AUTOMAKE) --foreign 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)
cd $(srcdir) && $(AUTOCONF)
$(ACLOCAL_M4): $(am__aclocal_m4_deps)
cd $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS)
config.h: stamp-h1
@if test ! -f $@; then \
rm -f stamp-h1; \
$(MAKE) stamp-h1; \
else :; fi
stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status
@rm -f stamp-h1
cd $(top_builddir) && $(SHELL) ./config.status config.h
$(srcdir)/config.h.in: $(am__configure_deps)
cd $(top_srcdir) && $(AUTOHEADER)
rm -f stamp-h1
touch $@
distclean-hdr:
-rm -f config.h stamp-h1
uninstall-info-am:
# This directory's subdirectories are mostly independent; you can cd
# into them and run `make' without going through this Makefile.
# To change the values of `make' variables: instead of editing Makefiles,
# (1) if the variable is set in `config.status', edit `config.status'
# (which will cause the Makefiles to be regenerated when you run `make');
# (2) otherwise, pass the desired values on the `make' command line.
$(RECURSIVE_TARGETS):
@set fnord $$MAKEFLAGS; amf=$$2; \
dot_seen=no; \
target=`echo $@ | sed s/-recursive//`; \
list='$(SUBDIRS)'; for subdir in $$list; do \
echo "Making $$target in $$subdir"; \
if test "$$subdir" = "."; then \
dot_seen=yes; \
local_target="$$target-am"; \
else \
local_target="$$target"; \
fi; \
(cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|| case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
done; \
if test "$$dot_seen" = "no"; then \
$(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
fi; test -z "$$fail"
mostlyclean-recursive clean-recursive distclean-recursive \
maintainer-clean-recursive:
@set fnord $$MAKEFLAGS; amf=$$2; \
dot_seen=no; \
case "$@" in \
distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
*) list='$(SUBDIRS)' ;; \
esac; \
rev=''; for subdir in $$list; do \
if test "$$subdir" = "."; then :; else \
rev="$$subdir $$rev"; \
fi; \
done; \
rev="$$rev ."; \
target=`echo $@ | sed s/-recursive//`; \
for subdir in $$rev; do \
echo "Making $$target in $$subdir"; \
if test "$$subdir" = "."; then \
local_target="$$target-am"; \
else \
local_target="$$target"; \
fi; \
(cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|| case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
done && test -z "$$fail"
tags-recursive:
list='$(SUBDIRS)'; for subdir in $$list; do \
test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
done
ctags-recursive:
list='$(SUBDIRS)'; for subdir in $$list; do \
test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \
done
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
mkid -fID $$unique
tags: TAGS
TAGS: tags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
here=`pwd`; \
if (etags --etags-include --version) >/dev/null 2>&1; then \
include_option=--etags-include; \
else \
include_option=--include; \
fi; \
list='$(SUBDIRS)'; for subdir in $$list; do \
if test "$$subdir" = .; then :; else \
test -f $$subdir/TAGS && \
tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \
fi; \
done; \
list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
test -z "$(ETAGS_ARGS)$$tags$$unique" \
|| $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$tags $$unique
ctags: CTAGS
CTAGS: ctags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
test -z "$(CTAGS_ARGS)$$tags$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$tags $$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& cd $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) $$here
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
distdir: $(DISTFILES)
$(am__remove_distdir)
mkdir $(distdir)
$(mkdir_p) $(distdir)/m4
@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
list='$(DISTFILES)'; for file in $$list; do \
case $$file in \
$(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
$(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
esac; \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
if test "$$dir" != "$$file" && test "$$dir" != "."; then \
dir="/$$dir"; \
$(mkdir_p) "$(distdir)$$dir"; \
else \
dir=''; \
fi; \
if test -d $$d/$$file; then \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
fi; \
cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
else \
test -f $(distdir)/$$file \
|| cp -p $$d/$$file $(distdir)/$$file \
|| exit 1; \
fi; \
done
list='$(SUBDIRS)'; for subdir in $$list; do \
if test "$$subdir" = .; then :; else \
test -d "$(distdir)/$$subdir" \
|| mkdir "$(distdir)/$$subdir" \
|| exit 1; \
(cd $$subdir && \
$(MAKE) $(AM_MAKEFLAGS) \
top_distdir="../$(top_distdir)" \
distdir="../$(distdir)/$$subdir" \
distdir) \
|| exit 1; \
fi; \
done
-find $(distdir) -type d ! -perm -777 -exec chmod a+rwx {} \; -o \
! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \
! -type d ! -perm -400 -exec chmod a+r {} \; -o \
! -type d ! -perm -444 -exec $(SHELL) $(install_sh) -c -m a+r {} {} \; \
|| chmod -R a+r $(distdir)
dist-gzip: distdir
$(AMTAR) chof - $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
$(am__remove_distdir)
dist-bzip2: distdir
$(AMTAR) chof - $(distdir) | bzip2 -9 -c >$(distdir).tar.bz2
$(am__remove_distdir)
dist-tarZ: distdir
$(AMTAR) chof - $(distdir) | 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
$(AMTAR) chof - $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
$(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) gunzip -c $(distdir).tar.gz | $(AMTAR) xf - ;;\
*.tar.bz2*) \
bunzip2 -c $(distdir).tar.bz2 | $(AMTAR) xf - ;;\
*.tar.Z*) \
uncompress -c $(distdir).tar.Z | $(AMTAR) xf - ;;\
*.shar.gz*) \
GZIP=$(GZIP_ENV) gunzip -c $(distdir).tar.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)
dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \
&& dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \
&& cd $(distdir)/_build \
&& ../configure --srcdir=.. --prefix="$$dc_install_base" \
$(DISTCHECK_CONFIGURE_FLAGS) \
&& $(MAKE) $(AM_MAKEFLAGS) \
&& $(MAKE) $(AM_MAKEFLAGS) dvi \
&& $(MAKE) $(AM_MAKEFLAGS) check \
&& $(MAKE) $(AM_MAKEFLAGS) install \
&& $(MAKE) $(AM_MAKEFLAGS) installcheck \
&& $(MAKE) $(AM_MAKEFLAGS) uninstall \
&& $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \
distuninstallcheck \
&& chmod -R a-w "$$dc_install_base" \
&& ({ \
(cd ../.. && 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
$(am__remove_distdir)
@(echo "$(distdir) archives ready for distribution: "; \
list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \
sed -e '1{h;s/./=/g;p;x;}' -e '$${p;x;}'
distuninstallcheck:
@cd $(distuninstallcheck_dir) \
&& test `$(distuninstallcheck_listfiles) | wc -l` -le 1 \
|| { echo "ERROR: files left after uninstall:" ; \
if test -n "$(DESTDIR)"; then \
echo " (check DESTDIR support)"; \
fi ; \
$(distuninstallcheck_listfiles) ; \
exit 1; } >&2
distcleancheck: distclean
@if test '$(srcdir)' = . ; then \
echo "ERROR: distcleancheck can only run from a VPATH build" ; \
exit 1 ; \
fi
@test `$(distcleancheck_listfiles) | wc -l` -eq 0 \
|| { echo "ERROR: files left in build directory after distclean:" ; \
$(distcleancheck_listfiles) ; \
exit 1; } >&2
check-am: all-am
check: check-recursive
all-am: Makefile config.h
installdirs: installdirs-recursive
installdirs-am:
install: install-recursive
install-exec: install-exec-recursive
install-data: install-data-recursive
uninstall: uninstall-recursive
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-recursive
install-strip:
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
`test -z '$(STRIP)' || \
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:
clean-generic:
distclean-generic:
-rm -f $(CONFIG_CLEAN_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-recursive
clean-am: clean-generic mostlyclean-am
distclean: distclean-recursive
-rm -f $(am__CONFIG_DISTCLEAN_FILES)
-rm -f Makefile
distclean-am: clean-am distclean-generic distclean-hdr distclean-tags
dvi: dvi-recursive
dvi-am:
html: html-recursive
info: info-recursive
info-am:
install-data-am:
install-exec-am:
install-info: install-info-recursive
install-man:
installcheck-am:
maintainer-clean: maintainer-clean-recursive
-rm -f $(am__CONFIG_DISTCLEAN_FILES)
-rm -rf $(top_srcdir)/autom4te.cache
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-recursive
mostlyclean-am: mostlyclean-generic
pdf: pdf-recursive
pdf-am:
ps: ps-recursive
ps-am:
uninstall-am: uninstall-info-am
uninstall-info: uninstall-info-recursive
.PHONY: $(RECURSIVE_TARGETS) CTAGS GTAGS all all-am am--refresh check \
check-am clean clean-generic clean-recursive ctags \
ctags-recursive dist dist-all dist-bzip2 dist-gzip dist-shar \
dist-tarZ dist-zip distcheck distclean distclean-generic \
distclean-hdr distclean-recursive distclean-tags \
distcleancheck distdir distuninstallcheck dvi dvi-am html \
html-am info info-am install install-am install-data \
install-data-am install-exec install-exec-am install-info \
install-info-am install-man install-strip installcheck \
installcheck-am installdirs installdirs-am maintainer-clean \
maintainer-clean-generic maintainer-clean-recursive \
mostlyclean mostlyclean-generic mostlyclean-recursive pdf \
pdf-am ps ps-am tags tags-recursive uninstall uninstall-am \
uninstall-info-am
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

19
README Normal file
View File

@ -0,0 +1,19 @@
This is Iperf v2.0.0, a tool for measuring Internet bandwidth performance.
See the doc directory for more documentation.
Briefly:
./configure -- configure for your machine
make -- compile Iperf
make install -- install Iperf, if desired
iperf -s (on machine "foo.bar.edu")
iperf -c foo.bar.edu (on some other machine)
iperf -h (for help screen)
iperf -v (for version information)
Copyright 1999, 2000, 2001, 2002, 2003, 2004
The Board of Trustees of the University of Illinois
All rights reserved
See UI License (doc/ui_license.html) for complete details.
$Id: README,v 1.1.1.1 2004/05/18 01:50:44 kgibbs Exp $

904
aclocal.m4 vendored Normal file
View File

@ -0,0 +1,904 @@
# generated automatically by aclocal 1.8.3 -*- Autoconf -*-
# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
# 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.
# -*- Autoconf -*-
# Copyright (C) 2002, 2003 Free Software Foundation, Inc.
# Generated from amversion.in; do not edit by hand.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
# AM_AUTOMAKE_VERSION(VERSION)
# ----------------------------
# Automake X.Y traces this macro to ensure aclocal.m4 has been
# generated from the m4 files accompanying Automake X.Y.
AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version="1.8"])
# AM_SET_CURRENT_AUTOMAKE_VERSION
# -------------------------------
# Call AM_AUTOMAKE_VERSION so it can be traced.
# This function is AC_REQUIREd by AC_INIT_AUTOMAKE.
AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
[AM_AUTOMAKE_VERSION([1.8.3])])
# AM_AUX_DIR_EXPAND
# Copyright (C) 2001, 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.
# 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 Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
# 02111-1307, USA.
# serial 6
# 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])
AC_SUBST([$1_FALSE])
if $2; then
$1_TRUE=
$1_FALSE='#'
else
$1_TRUE='#'
$1_FALSE=
fi
AC_CONFIG_COMMANDS_PRE(
[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then
AC_MSG_ERROR([conditional "$1" was never defined.
Usually this means the macro was only invoked conditionally.])
fi])])
# serial 7 -*- Autoconf -*-
# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004
# Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
# 02111-1307, USA.
# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be
# written in clear, in which case automake, when reading aclocal.m4,
# will think it sees a *use*, and therefore will trigger all it's
# C support machinery. Also note that it means that autoscan, seeing
# CC etc. in the Makefile, will ask for an AC_PROG_CC use...
# _AM_DEPENDENCIES(NAME)
# ----------------------
# See how the compiler implements dependency checking.
# NAME is "CC", "CXX", "GCJ", or "OBJC".
# We try a few techniques and use that to set a single cache variable.
#
# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was
# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular
# dependency, and given that the user is not expected to run this macro,
# just rely on AC_PROG_CC.
AC_DEFUN([_AM_DEPENDENCIES],
[AC_REQUIRE([AM_SET_DEPDIR])dnl
AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl
AC_REQUIRE([AM_MAKE_INCLUDE])dnl
AC_REQUIRE([AM_DEP_TRACK])dnl
ifelse([$1], CC, [depcc="$CC" am_compiler_list=],
[$1], CXX, [depcc="$CXX" am_compiler_list=],
[$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'],
[$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'],
[depcc="$$1" am_compiler_list=])
AC_CACHE_CHECK([dependency style of $depcc],
[am_cv_$1_dependencies_compiler_type],
[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
# We make a subdir and do the tests there. Otherwise we can end up
# making bogus files that we don't know about and never remove. For
# instance it was reported that on HP-UX the gcc test will end up
# making a dummy file named `D' -- because `-MD' means `put the output
# in D'.
mkdir conftest.dir
# Copy depcomp to subdir because otherwise we won't find it if we're
# using a relative directory.
cp "$am_depcomp" conftest.dir
cd conftest.dir
# We will build objects and dependencies in a subdirectory because
# it helps to detect inapplicable dependency modes. For instance
# both Tru64's cc and ICC support -MD to output dependencies as a
# side effect of compilation, but ICC will put the dependencies in
# the current directory while Tru64 will put them in the object
# directory.
mkdir sub
am_cv_$1_dependencies_compiler_type=none
if test "$am_compiler_list" = ""; then
am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp`
fi
for depmode in $am_compiler_list; do
# Setup a source with many dependencies, because some compilers
# like to wrap large dependency lists on column 80 (with \), and
# we should not choose a depcomp mode which is confused by this.
#
# We need to recreate these files for each test, as the compiler may
# overwrite some of them when testing with obscure command lines.
# This happens at least with the AIX C compiler.
: > sub/conftest.c
for i in 1 2 3 4 5 6; do
echo '#include "conftst'$i'.h"' >> sub/conftest.c
# 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
case $depmode in
nosideeffect)
# after this tag, mechanisms are not by side-effect, so they'll
# only be used when explicitly requested
if test "x$enable_dependency_tracking" = xyes; then
continue
else
break
fi
;;
none) break ;;
esac
# We check with `-c' and `-o' for the sake of the "dashmstdout"
# mode. It turns out that the SunPro C++ compiler does not properly
# handle `-M -o', and we need to detect this.
if depmode=$depmode \
source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \
depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
$SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \
>/dev/null 2>conftest.err &&
grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 &&
${MAKE-make} -s -f confmf > /dev/null 2>&1; then
# icc doesn't choke on unknown options, it will just issue warnings
# (even with -Werror). So we grep stderr for any message
# that says an option was ignored.
if grep 'ignoring option' conftest.err >/dev/null 2>&1; then :; else
am_cv_$1_dependencies_compiler_type=$depmode
break
fi
fi
done
cd ..
rm -rf conftest.dir
else
am_cv_$1_dependencies_compiler_type=none
fi
])
AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type])
AM_CONDITIONAL([am__fastdep$1], [
test "x$enable_dependency_tracking" != xno \
&& test "$am_cv_$1_dependencies_compiler_type" = gcc3])
])
# AM_SET_DEPDIR
# -------------
# Choose a directory name for dependency files.
# This macro is AC_REQUIREd in _AM_DEPENDENCIES
AC_DEFUN([AM_SET_DEPDIR],
[AC_REQUIRE([AM_SET_LEADING_DOT])dnl
AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl
])
# AM_DEP_TRACK
# ------------
AC_DEFUN([AM_DEP_TRACK],
[AC_ARG_ENABLE(dependency-tracking,
[ --disable-dependency-tracking speeds up one-time 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])
])
# Generate code to set up dependency tracking. -*- Autoconf -*-
# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
# 02111-1307, USA.
#serial 2
# _AM_OUTPUT_DEPENDENCY_COMMANDS
# ------------------------------
AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
[for mf in $CONFIG_FILES; do
# Strip MF so we end up with the name of the file.
mf=`echo "$mf" | sed -e 's/:.*$//'`
# Check whether this is an Automake generated Makefile or not.
# We used to match only the files named `Makefile.in', but
# some people rename them; so instead we look at the file content.
# Grep'ing the first line is not enough: some people post-process
# each Makefile.in and add a new line on top of each file to say so.
# So let's grep whole file.
if grep '^#.*generated by automake' $mf > /dev/null 2>&1; then
dirpart=`AS_DIRNAME("$mf")`
else
continue
fi
grep '^DEP_FILES *= *[[^ @%:@]]' < "$mf" > /dev/null || continue
# Extract the definition of DEP_FILES from the Makefile without
# running `make'.
DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
test -z "$DEPDIR" && continue
# When using ansi2knr, U may be empty or an underscore; expand it
U=`sed -n 's/^U = //p' < "$mf"`
test -d "$dirpart/$DEPDIR" || mkdir "$dirpart/$DEPDIR"
# We invoke sed twice because it is the simplest approach to
# changing $(DEPDIR) to its actual value in the expansion.
for file in `sed -n '
/^DEP_FILES = .*\\\\$/ {
s/^DEP_FILES = //
:loop
s/\\\\$//
p
n
/\\\\$/ b loop
p
}
/^DEP_FILES = / s/^DEP_FILES = //p' < "$mf" | \
sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do
# Make sure the directory exists.
test -f "$dirpart/$file" && continue
fdir=`AS_DIRNAME(["$file"])`
AS_MKDIR_P([$dirpart/$fdir])
# echo "creating $dirpart/$file"
echo '# dummy' > "$dirpart/$file"
done
done
])# _AM_OUTPUT_DEPENDENCY_COMMANDS
# AM_OUTPUT_DEPENDENCY_COMMANDS
# -----------------------------
# This macro should only be invoked once -- use via AC_REQUIRE.
#
# This code is only required when automatic dependency tracking
# is enabled. FIXME. This creates each `.P' file that we will
# need in order to bootstrap the dependency handling code.
AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
[AC_CONFIG_COMMANDS([depfiles],
[test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS],
[AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"])
])
# Do all the work for Automake. -*- Autoconf -*-
# This macro actually does too much some checks are only needed if
# your package does certain things. But this isn't really a big deal.
# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
# Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
# 02111-1307, USA.
# serial 11
# 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.58])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
# test to see if srcdir already configured
if test "`cd $srcdir && pwd`" != "`pwd`" &&
test -f $srcdir/config.status; then
AC_MSG_ERROR([source directory already configured; run "make distclean" there first])
fi
# test whether we have cygpath
if test -z "$CYGPATH_W"; then
if (cygpath --version) >/dev/null 2>/dev/null; then
CYGPATH_W='cygpath -w'
else
CYGPATH_W=echo
fi
fi
AC_SUBST([CYGPATH_W])
# Define the identity of the package.
dnl Distinguish between old-style and new-style calls.
m4_ifval([$2],
[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl
AC_SUBST([PACKAGE], [$1])dnl
AC_SUBST([VERSION], [$2])],
[_AM_SET_OPTIONS([$1])dnl
AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl
AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl
_AM_IF_OPTION([no-define],,
[AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package])
AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl
# Some tools Automake needs.
AC_REQUIRE([AM_SANITY_CHECK])dnl
AC_REQUIRE([AC_ARG_PROGRAM])dnl
AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version})
AM_MISSING_PROG(AUTOCONF, autoconf)
AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version})
AM_MISSING_PROG(AUTOHEADER, autoheader)
AM_MISSING_PROG(MAKEINFO, makeinfo)
AM_MISSING_PROG(AMTAR, tar)
AM_PROG_INSTALL_SH
AM_PROG_INSTALL_STRIP
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([no-dependencies],,
[AC_PROVIDE_IFELSE([AC_PROG_CC],
[_AM_DEPENDENCIES(CC)],
[define([AC_PROG_CC],
defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl
AC_PROVIDE_IFELSE([AC_PROG_CXX],
[_AM_DEPENDENCIES(CXX)],
[define([AC_PROG_CXX],
defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl
])
])
# When config.status generates a header, we must update the stamp-h file.
# This file resides in the same directory as the config header
# that is generated. The stamp files are numbered to have different names.
# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the
# loop where config.status creates the headers, so we can generate
# our stamp files there.
AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK],
[# Compute $1's index in $config_headers.
_am_stamp_count=1
for _am_header in $config_headers :; do
case $_am_header in
$1 | $1:* )
break ;;
* )
_am_stamp_count=`expr $_am_stamp_count + 1` ;;
esac
done
echo "timestamp for $1" >`AS_DIRNAME([$1])`/stamp-h[]$_am_stamp_count])
# AM_PROG_INSTALL_SH
# ------------------
# Define $install_sh.
# Copyright (C) 2001, 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.
AC_DEFUN([AM_PROG_INSTALL_SH],
[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
install_sh=${install_sh-"$am_aux_dir/install-sh"}
AC_SUBST(install_sh)])
# -*- Autoconf -*-
# Copyright (C) 2003 Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
# 02111-1307, USA.
# serial 1
# Check whether the underlying file-system supports filenames
# with a leading dot. For instance MS-DOS doesn't.
AC_DEFUN([AM_SET_LEADING_DOT],
[rm -rf .tst 2>/dev/null
mkdir .tst 2>/dev/null
if test -d .tst; then
am__leading_dot=.
else
am__leading_dot=_
fi
rmdir .tst 2>/dev/null
AC_SUBST([am__leading_dot])])
# Check to see how 'make' treats includes. -*- Autoconf -*-
# Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
# 02111-1307, USA.
# serial 2
# AM_MAKE_INCLUDE()
# -----------------
# Check to see how make treats includes.
AC_DEFUN([AM_MAKE_INCLUDE],
[am_make=${MAKE-make}
cat > confinc << 'END'
am__doit:
@echo done
.PHONY: am__doit
END
# If we don't find an include directive, just comment out the code.
AC_MSG_CHECKING([for style of include used by $am_make])
am__include="#"
am__quote=
_am_result=none
# First try GNU make style include.
echo "include confinc" > confmf
# We grep out `Entering directory' and `Leaving directory'
# messages which can occur if `w' ends up in MAKEFLAGS.
# In particular we don't look at `^make:' because GNU make might
# be invoked under some other name (usually "gmake"), in which
# case it prints its new name instead of `make'.
if test "`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`" = "done"; then
am__include=include
am__quote=
_am_result=GNU
fi
# Now try BSD make style include.
if test "$am__include" = "#"; then
echo '.include "confinc"' > confmf
if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then
am__include=.include
am__quote="\""
_am_result=BSD
fi
fi
AC_SUBST([am__include])
AC_SUBST([am__quote])
AC_MSG_RESULT([$_am_result])
rm -f confinc confmf
])
# -*- Autoconf -*-
# Copyright (C) 1997, 1999, 2000, 2001, 2003 Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
# 02111-1307, USA.
# serial 3
# AM_MISSING_PROG(NAME, PROGRAM)
# ------------------------------
AC_DEFUN([AM_MISSING_PROG],
[AC_REQUIRE([AM_MISSING_HAS_RUN])
$1=${$1-"${am_missing_run}$2"}
AC_SUBST($1)])
# AM_MISSING_HAS_RUN
# ------------------
# Define MISSING if not defined so far and test if it supports --run.
# If it does, set am_missing_run to use it, otherwise, to nothing.
AC_DEFUN([AM_MISSING_HAS_RUN],
[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing"
# Use eval to expand $SHELL
if eval "$MISSING --run true"; then
am_missing_run="$MISSING --run "
else
am_missing_run=
AC_MSG_WARN([`missing' script is too old or missing])
fi
])
# AM_PROG_MKDIR_P
# ---------------
# Check whether `mkdir -p' is supported, fallback to mkinstalldirs otherwise.
# Copyright (C) 2003, 2004 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.
# Automake 1.8 used `mkdir -m 0755 -p --' to ensure that directories
# created by `make install' are always world readable, even if the
# installer happens to have an overly restrictive umask (e.g. 077).
# This was a mistake. There are at least two reasons why we must not
# use `-m 0755':
# - it causes special bits like SGID to be ignored,
# - it may be too restrictive (some setups expect 775 directories).
#
# Do not use -m 0755 and let people choose whatever they expect by
# setting umask.
#
# We cannot accept any implementation of `mkdir' that recognizes `-p'.
# Some implementations (such as Solaris 8's) are not thread-safe: if a
# parallel make tries to run `mkdir -p a/b' and `mkdir -p a/c'
# concurrently, both version can detect that a/ is missing, but only
# one can create it and the other will error out. Consequently we
# restrict ourselves to GNU make (using the --version option ensures
# this.)
AC_DEFUN([AM_PROG_MKDIR_P],
[if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then
# Keeping the `.' argument allows $(mkdir_p) to be used without
# argument. Indeed, we sometimes output rules like
# $(mkdir_p) $(somedir)
# where $(somedir) is conditionally defined.
# (`test -n '$(somedir)' && $(mkdir_p) $(somedir)' is a more
# expensive solution, as it forces Make to start a sub-shell.)
mkdir_p='mkdir -p -- .'
else
# On NextStep and OpenStep, the `mkdir' command does not
# recognize any option. It will interpret all options as
# directories to create, and then abort because `.' already
# exists.
for d in ./-p ./--version;
do
test -d $d && rmdir $d
done
# $(mkinstalldirs) is defined by Automake if mkinstalldirs exists.
if test -f "$ac_aux_dir/mkinstalldirs"; then
mkdir_p='$(mkinstalldirs)'
else
mkdir_p='$(install_sh) -d'
fi
fi
AC_SUBST([mkdir_p])])
# Helper functions for option handling. -*- Autoconf -*-
# Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
# 02111-1307, USA.
# serial 2
# _AM_MANGLE_OPTION(NAME)
# -----------------------
AC_DEFUN([_AM_MANGLE_OPTION],
[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])])
# _AM_SET_OPTION(NAME)
# ------------------------------
# Set option NAME. Presently that only means defining a flag for this option.
AC_DEFUN([_AM_SET_OPTION],
[m4_define(_AM_MANGLE_OPTION([$1]), 1)])
# _AM_SET_OPTIONS(OPTIONS)
# ----------------------------------
# OPTIONS is a space-separated list of Automake options.
AC_DEFUN([_AM_SET_OPTIONS],
[AC_FOREACH([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])])
# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET])
# -------------------------------------------
# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.
AC_DEFUN([_AM_IF_OPTION],
[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
#
# Check to make sure that the build environment is sane.
#
# Copyright (C) 1996, 1997, 2000, 2001, 2003 Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
# 02111-1307, USA.
# serial 3
# AM_SANITY_CHECK
# ---------------
AC_DEFUN([AM_SANITY_CHECK],
[AC_MSG_CHECKING([whether build environment is sane])
# Just in case
sleep 1
echo timestamp > conftest.file
# Do `set' in a subshell so we don't clobber the current shell's
# arguments. Must try -L first in case configure is actually a
# symlink; some systems play weird games with the mod time of symlinks
# (eg FreeBSD returns the mod time of the symlink's containing
# directory).
if (
set X `ls -Lt $srcdir/configure conftest.file 2> /dev/null`
if test "$[*]" = "X"; then
# -L didn't work.
set X `ls -t $srcdir/configure conftest.file`
fi
rm -f conftest.file
if test "$[*]" != "X $srcdir/configure conftest.file" \
&& test "$[*]" != "X conftest.file $srcdir/configure"; then
# If neither matched, then we have a broken ls. This can happen
# if, for instance, CONFIG_SHELL is bash and it inherits a
# broken ls alias from the environment. This has actually
# happened. Such a system could not be considered "sane".
AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken
alias in your environment])
fi
test "$[2]" = conftest.file
)
then
# Ok.
:
else
AC_MSG_ERROR([newly created file is older than distributed files!
Check your system clock])
fi
AC_MSG_RESULT(yes)])
# AM_PROG_INSTALL_STRIP
# Copyright (C) 2001, 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.
# One issue with vendor `install' (even GNU) is that you can't
# specify the program used to strip binaries. This is especially
# annoying in cross-compiling environments, where the build's strip
# is unlikely to handle the host's binaries.
# Fortunately install-sh will honor a STRIPPROG variable, so we
# always use install-sh in `make install-strip', and initialize
# STRIPPROG with the value of the STRIP variable (set by the user).
AC_DEFUN([AM_PROG_INSTALL_STRIP],
[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
# Installed binaries are usually stripped using `strip' when the user
# run `make install-strip'. However `strip' might not be the right
# tool to use in cross-compilation environments, therefore Automake
# will honor the `STRIP' environment variable to overrule this program.
dnl Don't test for $cross_compiling = yes, because it might be `maybe'.
if test "$cross_compiling" != no; then
AC_CHECK_TOOL([STRIP], [strip], :)
fi
INSTALL_STRIP_PROGRAM="\${SHELL} \$(install_sh) -c -s"
AC_SUBST([INSTALL_STRIP_PROGRAM])])
m4_include([m4/dast.m4])

17
autogen.sh Executable file
View File

@ -0,0 +1,17 @@
#!/bin/sh
# autogen.sh: Automatically generate all build files from configure.ac
# aclocal doesn't like it if you -I the system aclocal directory
SYS_ACLOCAL_DIR=`aclocal --print-ac-dir`
for i in m4 /usr/local/share/aclocal; do
if [ ! $i = $SYS_ACLOCAL_DIR -a -d $i ]; then
ACLOCAL_OPTS="$ACLOCAL_OPTS -I $i"
fi
done
aclocal $ACLOCAL_OPTS || exit 1
autoheader || exit 1
autoconf || exit 1
automake --add-missing --include-deps --foreign || exit 1

16
compat/Makefile.am Normal file
View File

@ -0,0 +1,16 @@
noinst_LIBRARIES = libcompat.a
AM_CPPFLAGS = @STRIP_BEGIN@ \
-I$(top_srcdir)/include \
@STRIP_END@
libcompat_a_SOURCES = \
Thread.c \
error.c \
delay.cpp \
gettimeofday.c \
inet_ntop.c \
inet_pton.c \
signal.c \
snprintf.c \
string.c

442
compat/Makefile.in Normal file
View File

@ -0,0 +1,442 @@
# Makefile.in generated by automake 1.8.3 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
# 2003, 2004 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@
SOURCES = $(libcompat_a_SOURCES)
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
top_builddir = ..
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
INSTALL = @INSTALL@
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
host_triplet = @host@
subdir = compat
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/dast.m4 \
$(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(mkdir_p)
CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
AR = ar
ARFLAGS = cru
LIBRARIES = $(noinst_LIBRARIES)
libcompat_a_AR = $(AR) $(ARFLAGS)
libcompat_a_LIBADD =
am_libcompat_a_OBJECTS = Thread.$(OBJEXT) error.$(OBJEXT) \
delay.$(OBJEXT) gettimeofday.$(OBJEXT) inet_ntop.$(OBJEXT) \
inet_pton.$(OBJEXT) signal.$(OBJEXT) snprintf.$(OBJEXT) \
string.$(OBJEXT)
libcompat_a_OBJECTS = $(am_libcompat_a_OBJECTS)
DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__depfiles_maybe = depfiles
@AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/Thread.Po ./$(DEPDIR)/delay.Po \
@AMDEP_TRUE@ ./$(DEPDIR)/error.Po ./$(DEPDIR)/gettimeofday.Po \
@AMDEP_TRUE@ ./$(DEPDIR)/inet_ntop.Po ./$(DEPDIR)/inet_pton.Po \
@AMDEP_TRUE@ ./$(DEPDIR)/signal.Po ./$(DEPDIR)/snprintf.Po \
@AMDEP_TRUE@ ./$(DEPDIR)/string.Po
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
CCLD = $(CC)
LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
CXXLD = $(CXX)
CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \
-o $@
SOURCES = $(libcompat_a_SOURCES)
DIST_SOURCES = $(libcompat_a_SOURCES)
ETAGS = etags
CTAGS = ctags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMDEP_FALSE = @AMDEP_FALSE@
AMDEP_TRUE = @AMDEP_TRUE@
AMTAR = @AMTAR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CXX = @CXX@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
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@
OBJEXT = @OBJEXT@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
RANLIB = @RANLIB@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
STRIP_BEGIN = @STRIP_BEGIN@
STRIP_DUMMY = @STRIP_DUMMY@
STRIP_END = @STRIP_END@
VERSION = @VERSION@
WEB100_CFLAGS = @WEB100_CFLAGS@
WEB100_CONFIG = @WEB100_CONFIG@
WEB100_LIBS = @WEB100_LIBS@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
ac_ct_RANLIB = @ac_ct_RANLIB@
ac_ct_STRIP = @ac_ct_STRIP@
am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
datadir = @datadir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localstatedir = @localstatedir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
prefix = @prefix@
program_transform_name = @program_transform_name@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
noinst_LIBRARIES = libcompat.a
AM_CPPFLAGS = @STRIP_BEGIN@ \
-I$(top_srcdir)/include \
@STRIP_END@
libcompat_a_SOURCES = \
Thread.c \
error.c \
delay.cpp \
gettimeofday.c \
inet_ntop.c \
inet_pton.c \
signal.c \
snprintf.c \
string.c
all: all-am
.SUFFIXES:
.SUFFIXES: .c .cpp .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 \
&& exit 0; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign compat/Makefile'; \
cd $(top_srcdir) && \
$(AUTOMAKE) --foreign compat/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
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)/Thread.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/delay.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/error.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gettimeofday.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/inet_ntop.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/inet_pton.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/signal.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/snprintf.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/string.Po@am__quote@
.c.o:
@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(COMPILE) -c $<
.c.obj:
@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \
@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
.cpp.o:
@am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $<
.cpp.obj:
@am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \
@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
uninstall-info-am:
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
mkid -fID $$unique
tags: TAGS
TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
test -z "$(ETAGS_ARGS)$$tags$$unique" \
|| $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$tags $$unique
ctags: CTAGS
CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
test -z "$(CTAGS_ARGS)$$tags$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$tags $$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& cd $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) $$here
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
distdir: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
list='$(DISTFILES)'; for file in $$list; do \
case $$file in \
$(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
$(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
esac; \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
if test "$$dir" != "$$file" && test "$$dir" != "."; then \
dir="/$$dir"; \
$(mkdir_p) "$(distdir)$$dir"; \
else \
dir=''; \
fi; \
if test -d $$d/$$file; then \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
fi; \
cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
else \
test -f $(distdir)/$$file \
|| cp -p $$d/$$file $(distdir)/$$file \
|| exit 1; \
fi; \
done
check-am: all-am
check: check-am
all-am: Makefile $(LIBRARIES)
installdirs:
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-am
install-strip:
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
`test -z '$(STRIP)' || \
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:
clean-generic:
distclean-generic:
-rm -f $(CONFIG_CLEAN_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-am
clean-am: clean-generic clean-noinstLIBRARIES mostlyclean-am
distclean: distclean-am
-rm -rf ./$(DEPDIR)
-rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
distclean-tags
dvi: dvi-am
dvi-am:
html: html-am
info: info-am
info-am:
install-data-am:
install-exec-am:
install-info: install-info-am
install-man:
installcheck-am:
maintainer-clean: maintainer-clean-am
-rm -rf ./$(DEPDIR)
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-compile mostlyclean-generic
pdf: pdf-am
pdf-am:
ps: ps-am
ps-am:
uninstall-am: uninstall-info-am
.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
clean-noinstLIBRARIES ctags 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-exec install-exec-am install-info \
install-info-am install-man install-strip installcheck \
installcheck-am installdirs maintainer-clean \
maintainer-clean-generic mostlyclean mostlyclean-compile \
mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \
uninstall-am uninstall-info-am
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

420
compat/Thread.c Normal file
View File

@ -0,0 +1,420 @@
/*---------------------------------------------------------------
* Copyright (c) 1999,2000,2001,2002,2003
* The Board of Trustees of the University of Illinois
* All Rights Reserved.
*---------------------------------------------------------------
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software (Iperf) 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:
*
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and
* the following disclaimers.
*
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimers in the documentation and/or other materials
* provided with the distribution.
*
*
* Neither the names of the University of Illinois, NCSA,
* nor the names of its contributors may be used to endorse
* or promote products derived from this Software without
* specific prior written permission.
*
* 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 CONTIBUTORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* ________________________________________________________________
* National Laboratory for Applied Network Research
* National Center for Supercomputing Applications
* University of Illinois at Urbana-Champaign
* http://www.ncsa.uiuc.edu
* ________________________________________________________________
*
* Thread.c
* by Kevin Gibbs <kgibbs@nlanr.net>
*
* Based on:
* Thread.cpp
* by Mark Gates <mgates@nlanr.net>
* -------------------------------------------------------------------
* The thread subsystem is responsible for all thread functions. It
* provides a thread implementation agnostic interface to Iperf. If
* threads are not available (HAVE_THREAD is undefined), thread_start
* does not start a new thread but just launches the specified object
* in the current thread. Everything that defines a thread of
* execution in Iperf is contained in an thread_Settings structure. To
* start a thread simply pass one such structure into thread_start.
* -------------------------------------------------------------------
* headers
* uses
* <stdlib.h>
* <stdio.h>
* <assert.h>
* <errno.h>
* Thread.h may include <pthread.h>
* ------------------------------------------------------------------- */
#include "headers.h"
#include "Thread.h"
#include "Locale.h"
#include "util.h"
#ifdef __cplusplus
extern "C" {
#endif
/* -------------------------------------------------------------------
* define static variables.
* ------------------------------------------------------------------- */
// number of currently running threads
int thread_sNum = 0;
// number of non-terminating running threads (ie listener thread)
int nonterminating_num = 0;
// condition to protect updating the above and alerting on
// changes to above
Condition thread_sNum_cond;
/* -------------------------------------------------------------------
* Initialize the thread subsystems variables and set the concurrency
* level in solaris.
* ------------------------------------------------------------------- */
void thread_init( ) {
Condition_Initialize( &thread_sNum_cond );
#if defined( sun )
/* Solaris apparently doesn't default to timeslicing threads,
* as such we force it to play nice. This may not work perfectly
* when _sending_ multiple _UDP_ streams.
*/
pthread_setconcurrency (3);
#endif
}
/* -------------------------------------------------------------------
* Destroy the thread subsystems variables.
* ------------------------------------------------------------------- */
void thread_destroy( ) {
Condition_Destroy( &thread_sNum_cond );
}
/* -------------------------------------------------------------------
* Start the specified object's thread execution. Increments thread
* count, spawns new thread, and stores thread ID.
* ------------------------------------------------------------------- */
void thread_start( struct thread_Settings* thread ) {
// Make sure this object has not been started already
if ( thread_equalid( thread->mTID, thread_zeroid() ) ) {
// Check if we need to start another thread before this one
if ( thread->runNow != NULL ) {
thread_start( thread->runNow );
}
// increment thread count
Condition_Lock( thread_sNum_cond );
thread_sNum++;
Condition_Unlock( thread_sNum_cond );
#if defined( HAVE_POSIX_THREAD )
// pthreads -- spawn new thread
if ( pthread_create( &thread->mTID, NULL, thread_run_wrapper, thread ) != 0 ) {
WARN( 1, "pthread_create" );
// decrement thread count
Condition_Lock( thread_sNum_cond );
thread_sNum--;
Condition_Unlock( thread_sNum_cond );
}
#elif defined( HAVE_WIN32_THREAD )
// Win32 threads -- spawn new thread
// Win32 has a thread handle in addition to the thread ID
thread->mHandle = CreateThread( NULL, 0, thread_run_wrapper, thread, 0, &thread->mTID );
if ( thread->mHandle == NULL ) {
WARN( 1, "CreateThread" );
// decrement thread count
Condition_Lock( thread_sNum_cond );
thread_sNum--;
Condition_Unlock( thread_sNum_cond );
}
#else
// single-threaded -- call Run_Wrapper in this thread
thread_run_wrapper( thread );
#endif
}
} // end thread_start
/* -------------------------------------------------------------------
* Stop the specified object's thread execution (if any) immediately.
* Decrements thread count and resets the thread ID.
* ------------------------------------------------------------------- */
void thread_stop( struct thread_Settings* thread ) {
#ifdef HAVE_THREAD
// Make sure we have been started
if ( ! thread_equalid( thread->mTID, thread_zeroid() ) ) {
// decrement thread count
Condition_Lock( thread_sNum_cond );
thread_sNum--;
Condition_Signal( &thread_sNum_cond );
Condition_Unlock( thread_sNum_cond );
// use exit() if called from within this thread
// use cancel() if called from a different thread
if ( thread_equalid( thread_getid(), thread->mTID ) ) {
// Destroy the object
Settings_Destroy( thread );
// Exit
#if defined( HAVE_POSIX_THREAD )
pthread_exit( NULL );
#else // Win32
CloseHandle( thread->mHandle );
ExitThread( 0 );
#endif
} else {
// Cancel
#if defined( HAVE_POSIX_THREAD )
// Cray J90 doesn't have pthread_cancel; Iperf works okay without
#ifdef HAVE_PTHREAD_CANCEL
pthread_cancel( oldTID );
#endif
#else // Win32
// this is a somewhat dangerous function; it's not
// suggested to Stop() threads a lot.
TerminateThread( thread->mHandle, 0 );
#endif
// Destroy the object only after killing the thread
Settings_Destroy( thread );
}
}
#endif
} // end Stop
/* -------------------------------------------------------------------
* This function is the entry point for new threads created in
* thread_start.
* ------------------------------------------------------------------- */
#if defined( HAVE_WIN32_THREAD )
DWORD WINAPI
#else
void*
#endif
thread_run_wrapper( void* paramPtr ) {
struct thread_Settings* thread = (struct thread_Settings*) paramPtr;
// which type of object are we
switch ( thread->mThreadMode ) {
case kMode_Server:
{
/* Spawn a Server thread with these settings */
server_spawn( thread );
} break;
case kMode_Client:
{
/* Spawn a Client thread with these settings */
client_spawn( thread );
} break;
case kMode_Reporter:
{
/* Spawn a Reporter thread with these settings */
reporter_spawn( thread );
} break;
case kMode_Listener:
{
// Increment the non-terminating thread count
thread_register_nonterm();
/* Spawn a Listener thread with these settings */
listener_spawn( thread );
// Decrement the non-terminating thread count
thread_unregister_nonterm();
} break;
default:
{
FAIL(1, "Unknown Thread Type!\n", thread);
} break;
}
#ifdef HAVE_POSIX_THREAD
// detach Thread. If someone already joined it will not do anything
// If noone has then it will free resources upon return from this
// function (Run_Wrapper)
pthread_detach(thread->mTID);
#endif
// decrement thread count and send condition signal
Condition_Lock( thread_sNum_cond );
thread_sNum--;
Condition_Signal( &thread_sNum_cond );
Condition_Unlock( thread_sNum_cond );
// Check if we need to start up a thread after executing this one
if ( thread->runNext != NULL ) {
thread_start( thread->runNext );
}
// Destroy this thread object
Settings_Destroy( thread );
return 0;
} // end run_wrapper
/* -------------------------------------------------------------------
* Wait for all thread object's execution to complete. Depends on the
* thread count being accurate and the threads sending a condition
* signal when they terminate.
* ------------------------------------------------------------------- */
void thread_joinall( void ) {
Condition_Lock( thread_sNum_cond );
while ( thread_sNum > 0 ) {
Condition_Wait( &thread_sNum_cond );
}
Condition_Unlock( thread_sNum_cond );
} // end Joinall
/* -------------------------------------------------------------------
* Compare the thread ID's (inLeft == inRight); return true if they
* are equal. On some OS's nthread_t is a struct so == will not work.
* TODO use pthread_equal. Any Win32 equivalent??
* ------------------------------------------------------------------- */
int thread_equalid( nthread_t inLeft, nthread_t inRight ) {
return(memcmp( &inLeft, &inRight, sizeof(inLeft)) == 0);
}
/* -------------------------------------------------------------------
* Return a zero'd out thread ID. On some OS's nthread_t is a struct
* so == 0 will not work.
* [static]
* ------------------------------------------------------------------- */
nthread_t thread_zeroid( void ) {
nthread_t a;
memset( &a, 0, sizeof(a));
return a;
}
/* -------------------------------------------------------------------
* set a thread to be ignorable, so joinall won't wait on it
* this simply decrements the thread count that joinall uses.
* This is utilized by the reporter thread which knows when it
* is ok to quit (aka no pending reports).
* ------------------------------------------------------------------- */
void thread_setignore( ) {
Condition_Lock( thread_sNum_cond );
thread_sNum--;
Condition_Signal( &thread_sNum_cond );
Condition_Unlock( thread_sNum_cond );
}
/* -------------------------------------------------------------------
* unset a thread from being ignorable, so joinall will wait on it
* this simply increments the thread count that joinall uses.
* This is utilized by the reporter thread which knows when it
* is ok to quit (aka no pending reports).
* ------------------------------------------------------------------- */
void thread_unsetignore( void ) {
Condition_Lock( thread_sNum_cond );
thread_sNum++;
Condition_Signal( &thread_sNum_cond );
Condition_Unlock( thread_sNum_cond );
}
/* -------------------------------------------------------------------
* set a thread to be non-terminating, so if you cancel through
* Ctrl-C they can be ignored by the joinall.
* ------------------------------------------------------------------- */
void thread_register_nonterm( void ) {
Condition_Lock( thread_sNum_cond );
nonterminating_num++;
Condition_Unlock( thread_sNum_cond );
}
/* -------------------------------------------------------------------
* unset a thread from being non-terminating, so if you cancel through
* Ctrl-C they can be ignored by the joinall.
* ------------------------------------------------------------------- */
void thread_unregister_nonterm( void ) {
Condition_Lock( thread_sNum_cond );
if ( nonterminating_num == 0 ) {
// nonterminating has been released with release_nonterm
// Add back to the threads to wait on
thread_sNum++;
} else {
nonterminating_num--;
}
Condition_Unlock( thread_sNum_cond );
}
/* -------------------------------------------------------------------
* this function releases all non-terminating threads from the list
* of active threads, so that when all terminating threads quit
* the joinall will complete. This is called on a Ctrl-C input. It is
* also used by the -P usage on the server side
* ------------------------------------------------------------------- */
int thread_release_nonterm( int interrupt ) {
Condition_Lock( thread_sNum_cond );
thread_sNum -= nonterminating_num;
if ( thread_sNum > 1 && nonterminating_num > 0 && interrupt != 0 ) {
fprintf( stderr, wait_server_threads );
}
nonterminating_num = 0;
Condition_Signal( &thread_sNum_cond );
Condition_Unlock( thread_sNum_cond );
return thread_sNum;
}
/* -------------------------------------------------------------------
* Return the number of threads currently running (doesn't include
* active threads that have called setdaemon (aka reporter thread))
* ------------------------------------------------------------------- */
int thread_numuserthreads( void ) {
return thread_sNum;
}
/*
* -------------------------------------------------------------------
* Allow another thread to execute. If no other threads are runable this
* is not guarenteed to actually rest.
* ------------------------------------------------------------------- */
void thread_rest ( void ) {
#if defined( HAVE_THREAD )
#if defined( HAVE_POSIX_THREAD )
// TODO add checks for sched_yield or pthread_yield and call that
// if available
usleep( 0 );
#else // Win32
SwitchToThread( );
#endif
#endif
}
#ifdef __cplusplus
} /* end extern "C" */
#endif

74
compat/delay.cpp Normal file
View File

@ -0,0 +1,74 @@
/*---------------------------------------------------------------
* Copyright (c) 1999,2000,2001,2002,2003
* The Board of Trustees of the University of Illinois
* All Rights Reserved.
*---------------------------------------------------------------
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software (Iperf) 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:
*
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and
* the following disclaimers.
*
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimers in the documentation and/or other materials
* provided with the distribution.
*
*
* Neither the names of the University of Illinois, NCSA,
* nor the names of its contributors may be used to endorse
* or promote products derived from this Software without
* specific prior written permission.
*
* 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 CONTIBUTORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* ________________________________________________________________
* National Laboratory for Applied Network Research
* National Center for Supercomputing Applications
* University of Illinois at Urbana-Champaign
* http://www.ncsa.uiuc.edu
* ________________________________________________________________
*
* delay.c
* by Mark Gates <mgates@nlanr.net>
* -------------------------------------------------------------------
* accurate microsecond delay
* ------------------------------------------------------------------- */
#include "Timestamp.hpp"
#include "delay.hpp"
/* -------------------------------------------------------------------
* A micro-second delay function. This uses gettimeofday (underneith
* the Timestamp) which has a resolution of upto microseconds. I've
* found it's good to within about 10 usecs.
* I used to do calibration, but iperf automatically adjusts itself
* so that isn't necesary, and it causes some problems if the
* calibration adjustment is larger than your sleep time.
* ------------------------------------------------------------------- */
void delay_loop( unsigned long usec ) {
Timestamp end;
end.add( usec * 1e-6 );
Timestamp now;
while ( now.before( end ) ) {
now.setnow();
}
}

210
compat/error.c Normal file
View File

@ -0,0 +1,210 @@
/*---------------------------------------------------------------
* Copyright (c) 1999,2000,2001,2002,2003
* The Board of Trustees of the University of Illinois
* All Rights Reserved.
*---------------------------------------------------------------
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software (Iperf) 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:
*
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and
* the following disclaimers.
*
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimers in the documentation and/or other materials
* provided with the distribution.
*
*
* Neither the names of the University of Illinois, NCSA,
* nor the names of its contributors may be used to endorse
* or promote products derived from this Software without
* specific prior written permission.
*
* 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 CONTIBUTORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* ________________________________________________________________
* National Laboratory for Applied Network Research
* National Center for Supercomputing Applications
* University of Illinois at Urbana-Champaign
* http://www.ncsa.uiuc.edu
* ________________________________________________________________
*
* error.c
* by Mark Gates <mgates@nlanr.net>
* -------------------------------------------------------------------
* error handlers
* ------------------------------------------------------------------- */
#include "headers.h"
#include "util.h"
#ifdef __cplusplus
extern "C" {
#endif
#ifdef WIN32
/* -------------------------------------------------------------------
* Implement a simple Win32 strerror function for our purposes.
* These error values weren't handled by FormatMessage;
* any particular reason why not??
* ------------------------------------------------------------------- */
struct mesg {
DWORD err;
const char* str;
};
const struct mesg error_mesgs[] =
{
{ WSAEACCES, "Permission denied"},
{ WSAEADDRINUSE, "Address already in use"},
{ WSAEADDRNOTAVAIL, "Cannot assign requested address"},
{ WSAEAFNOSUPPORT, "Address family not supported by protocol family"},
{ WSAEALREADY, "Operation already in progress"},
{ WSAECONNABORTED, "Software caused connection abort"},
{ WSAECONNREFUSED, "Connection refused"},
{ WSAECONNRESET, "Connection reset by peer"},
{ WSAEDESTADDRREQ, "Destination address required"},
{ WSAEFAULT, "Bad address"},
{ WSAEHOSTDOWN, "Host is down"},
{ WSAEHOSTUNREACH, "No route to host"},
{ WSAEINPROGRESS, "Operation now in progress"},
{ WSAEINTR, "Interrupted function call."},
{ WSAEINVAL, "Invalid argument."},
{ WSAEISCONN, "Socket is already connected."},
{ WSAEMFILE, "Too many open files."},
{ WSAEMSGSIZE, "Message too long"},
{ WSAENETDOWN, "Network is down"},
{ WSAENETRESET, "Network dropped connection on reset"},
{ WSAENETUNREACH, "Network is unreachable"},
{ WSAENOBUFS, "No buffer space available."},
{ WSAENOPROTOOPT, "Bad protocol option."},
{ WSAENOTCONN, "Socket is not connected"},
{ WSAENOTSOCK, "Socket operation on non-socket."},
{ WSAEOPNOTSUPP, "Operation not supported"},
{ WSAEPFNOSUPPORT, "Protocol family not supported"},
{ WSAEPROCLIM, "Too many processes."},
{ WSAEPROTONOSUPPORT, "Protocol not supported"},
{ WSAEPROTOTYPE, "Protocol wrong type for socket"},
{ WSAESHUTDOWN, "Cannot send after socket shutdown"},
{ WSAESOCKTNOSUPPORT, "Socket type not supported."},
{ WSAETIMEDOUT, "Connection timed out."},
{ WSATYPE_NOT_FOUND, "Class type not found."},
{ WSAEWOULDBLOCK, "Resource temporarily unavailable"},
{ WSAHOST_NOT_FOUND, "Host not found."},
{ WSA_INVALID_HANDLE, "Specified event object handle is invalid."},
{ WSA_INVALID_PARAMETER, "One or more parameters are invalid."},
{ WSA_IO_INCOMPLETE, "Overlapped I/O event object not in signaled state."},
{ WSA_IO_PENDING, "Overlapped operations will complete later."},
{ WSA_NOT_ENOUGH_MEMORY, "Insufficient memory available."},
{ WSANOTINITIALISED, "Successful WSAStartup not yet performed."},
{ WSANO_DATA, "Valid name, no data record of requested type."},
{ WSANO_RECOVERY, "This is a non-recoverable error."},
{ WSASYSCALLFAILURE, "System call failure."},
{ WSASYSNOTREADY, "Network subsystem is unavailable."},
{ WSATRY_AGAIN, "Non-authoritative host not found."},
{ WSAVERNOTSUPPORTED, "WINSOCK.DLL version out of range."},
{ WSAEDISCON, "Graceful shutdown in progress."},
{ WSA_OPERATION_ABORTED, "Overlapped operation aborted."},
{ 0, "No error."}
/* These appeared in the documentation, but didn't compile.
* { WSAINVALIDPROCTABLE, "Invalid procedure table from service provider." },
* { WSAINVALIDPROVIDER, "Invalid service provider version number." },
* { WSAPROVIDERFAILEDINIT, "Unable to initialize a service provider." },
*/
}; /* end error_mesgs[] */
const char* winsock_strerror( DWORD inErrno );
/* -------------------------------------------------------------------
* winsock_strerror
*
* returns a string representing the error code. The error messages
* were taken from Microsoft's online developer library.
* ------------------------------------------------------------------- */
const char* winsock_strerror( DWORD inErrno ) {
const char* str = "Unknown error";
int i;
for ( i = 0; i < sizeof(error_mesgs); i++ ) {
if ( error_mesgs[i].err == inErrno ) {
str = error_mesgs[i].str;
break;
}
}
return str;
} /* end winsock_strerror */
#endif /* WIN32 */
/* -------------------------------------------------------------------
* warn
*
* Prints message and return
* ------------------------------------------------------------------- */
void warn( const char *inMessage, const char *inFile, int inLine ) {
fflush( 0 );
#ifdef NDEBUG
fprintf( stderr, "%s failed\n", inMessage );
#else
/* while debugging output file/line number also */
fprintf( stderr, "%s failed (%s:%d)\n", inMessage, inFile, inLine );
#endif
} /* end warn */
/* -------------------------------------------------------------------
* warn_errno
*
* Prints message and errno message, and return.
* ------------------------------------------------------------------- */
void warn_errno( const char *inMessage, const char *inFile, int inLine ) {
int my_err;
const char* my_str;
/* get platform's errno and error message */
#ifdef WIN32
my_err = WSAGetLastError();
my_str = winsock_strerror( my_err );
#else
my_err = errno;
my_str = strerror( my_err );
#endif
fflush( 0 );
#ifdef NDEBUG
fprintf( stderr, "%s failed: %s\n", inMessage, my_str );
#else
/* while debugging output file/line number and errno value also */
fprintf( stderr, "%s failed (%s:%d): %s (%d)\n",
inMessage, inFile, inLine, my_str, my_err );
#endif
} /* end warn_errno */
#ifdef __cplusplus
} /* end extern "C" */
#endif

92
compat/gettimeofday.c Normal file
View File

@ -0,0 +1,92 @@
/*---------------------------------------------------------------
* Copyright (c) 1999,2000,2001,2002,2003
* The Board of Trustees of the University of Illinois
* All Rights Reserved.
*---------------------------------------------------------------
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software (Iperf) 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:
*
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and
* the following disclaimers.
*
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimers in the documentation and/or other materials
* provided with the distribution.
*
*
* Neither the names of the University of Illinois, NCSA,
* nor the names of its contributors may be used to endorse
* or promote products derived from this Software without
* specific prior written permission.
*
* 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 CONTIBUTORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* ________________________________________________________________
* National Laboratory for Applied Network Research
* National Center for Supercomputing Applications
* University of Illinois at Urbana-Champaign
* http://www.ncsa.uiuc.edu
* ________________________________________________________________
*
* gettimeofday.c
* by Mark Gates <mgates@nlanr.net>
* -------------------------------------------------------------------
* A (hack) implementation of gettimeofday for Windows.
* Since I send sec/usec in UDP packets, this made the most sense.
* ------------------------------------------------------------------- */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#ifndef HAVE_GETTIMEOFDAY
#include "headers.h"
#include "gettimeofday.h"
#ifdef __cplusplus
extern "C" {
#endif
int gettimeofday( struct timeval* tv, void* timezone ) {
FILETIME time;
double timed;
GetSystemTimeAsFileTime( &time );
// Apparently Win32 has units of 1e-7 sec (tenths of microsecs)
// 4294967296 is 2^32, to shift high word over
// 11644473600 is the number of seconds between
// the Win32 epoch 1601-Jan-01 and the Unix epoch 1970-Jan-01
// Tests found floating point to be 10x faster than 64bit int math.
timed = ((time.dwHighDateTime * 4294967296e-7) - 11644473600.0) +
(time.dwLowDateTime * 1e-7);
tv->tv_sec = (long) timed;
tv->tv_usec = (long) ((timed - tv->tv_sec) * 1e6);
return 0;
}
#ifdef __cplusplus
} /* end extern "C" */
#endif
#endif /* HAVE_GETTIMEOFDAY */

183
compat/inet_ntop.c Normal file
View File

@ -0,0 +1,183 @@
#include "inet_aton.h"
#ifdef __cplusplus
extern "C" {
#endif
/*
* Copyright (C) 1996-2001 Internet Software Consortium.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
* DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
* INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
* FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef HAVE_INET_NTOP
#define NS_INT16SZ 2
#define NS_INADDRSZ 4
#define NS_IN6ADDRSZ 16
/*
* WARNING: Don't even consider trying to compile this on a system where
* sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX.
*/
/* char *
* isc_net_ntop(af, src, dst, size)
* convert a network format address to presentation format.
* return:
* pointer to presentation format address (`dst'), or NULL (see errno).
* author:
* Paul Vixie, 1996.
*/
int
inet_ntop(int af, const void *src, char *dst, size_t size) {
switch ( af ) {
case AF_INET:
return(inet_ntop4(src, dst, size));
#ifdef HAVE_IPV6
case AF_INET6:
return(inet_ntop6(src, dst, size));
#endif
default:
return 0;
}
/* NOTREACHED */
}
/* const char *
* inet_ntop4(src, dst, size)
* format an IPv4 address
* return:
* `dst' (as a const)
* notes:
* (1) uses no statics
* (2) takes a unsigned char* not an in_addr as input
* author:
* Paul Vixie, 1996.
*/
int
inet_ntop4(const unsigned char *src, char *dst, size_t size) {
static const char *fmt = "%u.%u.%u.%u";
char tmp[sizeof "255.255.255.255"];
if ( (size_t)sprintf(tmp, fmt, src[0], src[1], src[2], src[3]) >= size ) {
return 0;
}
strcpy(dst, tmp);
return 1;
}
/* const char *
* isc_inet_ntop6(src, dst, size)
* convert IPv6 binary address into presentation (printable) format
* author:
* Paul Vixie, 1996.
*/
#ifdef HAVE_IPV6
int
inet_ntop6(const unsigned char *src, char *dst, size_t size) {
/*
* Note that int32_t and int16_t need only be "at least" large enough
* to contain a value of the specified size. On some systems, like
* Crays, there is no such thing as an integer variable with 16 bits.
* Keep this in mind if you think this function should have been coded
* to use pointer overlays. All the world's not a VAX.
*/
char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"], *tp;
struct {
int base, len;
} best, cur;
unsigned int words[NS_IN6ADDRSZ / NS_INT16SZ];
int i;
/*
* Preprocess:
* Copy the input (bytewise) array into a wordwise array.
* Find the longest run of 0x00's in src[] for :: shorthanding.
*/
memset(words, '\0', sizeof words);
for ( i = 0; i < NS_IN6ADDRSZ; i++ )
words[i / 2] |= (src[i] << ((1 - (i % 2)) << 3));
best.base = -1;
cur.base = -1;
for ( i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++ ) {
if ( words[i] == 0 ) {
if ( cur.base == -1 )
cur.base = i, cur.len = 1;
else
cur.len++;
} else {
if ( cur.base != -1 ) {
if ( best.base == -1 || cur.len > best.len )
best = cur;
cur.base = -1;
}
}
}
if ( cur.base != -1 ) {
if ( best.base == -1 || cur.len > best.len )
best = cur;
}
if ( best.base != -1 && best.len < 2 )
best.base = -1;
/*
* Format the result.
*/
tp = tmp;
for ( i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++ ) {
/* Are we inside the best run of 0x00's? */
if ( best.base != -1 && i >= best.base &&
i < (best.base + best.len) ) {
if ( i == best.base )
*tp++ = ':';
continue;
}
/* Are we following an initial run of 0x00s or any real hex? */
if ( i != 0 )
*tp++ = ':';
/* Is this address an encapsulated IPv4? */
if ( i == 6 && best.base == 0 &&
(best.len == 6 || (best.len == 5 && words[5] == 0xffff)) ) {
if ( !inet_ntop4(src+12, tp,
sizeof tmp - (tp - tmp)) )
return 0;
tp += strlen(tp);
break;
}
tp += sprintf(tp, "%x", words[i]);
}
/* Was it a trailing run of 0x00's? */
if ( best.base != -1 && (best.base + best.len) ==
(NS_IN6ADDRSZ / NS_INT16SZ) )
*tp++ = ':';
*tp++ = '\0';
/*
* Check for overflow, copy, and we're done.
*/
if ( (size_t)(tp - tmp) > size ) {
errno = ENOSPC;
return 0;
}
strcpy(dst, tmp);
return 1;
}
#endif /* HAVE_IPV6 */
#endif /* HAVE_INET_NTOP */
#ifdef __cplusplus
} /* end extern "C" */
#endif

209
compat/inet_pton.c Normal file
View File

@ -0,0 +1,209 @@
#include "inet_aton.h"
#ifdef __cplusplus
extern "C" {
#endif
/*
* Copyright (C) 1996-2001 Internet Software Consortium.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
* DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
* INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
* FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef HAVE_INET_PTON
#define NS_INT16SZ 2
#define NS_INADDRSZ 4
#define NS_IN6ADDRSZ 16
/* int
* isc_net_pton(af, src, dst)
* convert from presentation format (which usually means ASCII printable)
* to network format (which is usually some kind of binary format).
* return:
* 1 if the address was valid for the specified address family
* 0 if the address wasn't valid (`dst' is untouched in this case)
* author:
* Paul Vixie, 1996.
*/
int
inet_pton(int af,
const char *src,
void *dst) {
switch ( af ) {
case AF_INET:
return(inet_pton4(src, dst));
#ifdef HAVE_IPV6
case AF_INET6:
return(inet_pton6(src, dst));
#endif
default:
return 0;
}
/* NOTREACHED */
}
/* int
* inet_pton4(src, dst)
* like inet_aton() but without all the hexadecimal and shorthand.
* return:
* 1 if `src' is a valid dotted quad, else 0.
* notice:
* does not touch `dst' unless it's returning 1.
* author:
* Paul Vixie, 1996.
*/
int
inet_pton4(src, dst)
const char *src;
unsigned char *dst;
{
static const char digits[] = "0123456789";
int saw_digit, octets, ch;
unsigned char tmp[NS_INADDRSZ], *tp;
saw_digit = 0;
octets = 0;
*(tp = tmp) = 0;
while ( (ch = *src++) != '\0' ) {
const char *pch;
if ( (pch = strchr(digits, ch)) != NULL ) {
unsigned int new = *tp * 10 + (pch - digits);
if ( new > 255 )
return(0);
*tp = new;
if ( ! saw_digit ) {
if ( ++octets > 4 )
return(0);
saw_digit = 1;
}
} else if ( ch == '.' && saw_digit ) {
if ( octets == 4 )
return(0);
*++tp = 0;
saw_digit = 0;
} else
return(0);
}
if ( octets < 4 )
return(0);
memcpy(dst, tmp, NS_INADDRSZ);
return(1);
}
/* int
* inet_pton6(src, dst)
* convert presentation level address to network order binary form.
* return:
* 1 if `src' is a valid [RFC1884 2.2] address, else 0.
* notice:
* (1) does not touch `dst' unless it's returning 1.
* (2) :: in a full address is silently ignored.
* credit:
* inspired by Mark Andrews.
* author:
* Paul Vixie, 1996.
*/
#ifdef HAVE_IPV6
int
inet_pton6(src, dst)
const char *src;
unsigned char *dst;
{
static const char xdigits_l[] = "0123456789abcdef",
xdigits_u[] = "0123456789ABCDEF";
unsigned char tmp[NS_IN6ADDRSZ], *tp, *endp, *colonp;
const char *xdigits, *curtok;
int ch, saw_xdigit;
unsigned int val;
memset((tp = tmp), '\0', NS_IN6ADDRSZ);
endp = tp + NS_IN6ADDRSZ;
colonp = NULL;
/* Leading :: requires some special handling. */
if ( *src == ':' )
if ( *++src != ':' )
return(0);
curtok = src;
saw_xdigit = 0;
val = 0;
while ( (ch = *src++) != '\0' ) {
const char *pch;
if ( (pch = strchr((xdigits = xdigits_l), ch)) == NULL )
pch = strchr((xdigits = xdigits_u), ch);
if ( pch != NULL ) {
val <<= 4;
val |= (pch - xdigits);
if ( val > 0xffff )
return(0);
saw_xdigit = 1;
continue;
}
if ( ch == ':' ) {
curtok = src;
if ( !saw_xdigit ) {
if ( colonp )
return(0);
colonp = tp;
continue;
}
if ( tp + NS_INT16SZ > endp )
return(0);
*tp++ = (unsigned char) (val >> 8) & 0xff;
*tp++ = (unsigned char) val & 0xff;
saw_xdigit = 0;
val = 0;
continue;
}
if ( ch == '.' && ((tp + NS_INADDRSZ) <= endp) &&
inet_pton4(curtok, tp) > 0 ) {
tp += NS_INADDRSZ;
saw_xdigit = 0;
break; /* '\0' was seen by inet_pton4(). */
}
return(0);
}
if ( saw_xdigit ) {
if ( tp + NS_INT16SZ > endp )
return(0);
*tp++ = (unsigned char) (val >> 8) & 0xff;
*tp++ = (unsigned char) val & 0xff;
}
if ( colonp != NULL ) {
/*
* Since some memmove()'s erroneously fail to handle
* overlapping regions, we'll do the shift by hand.
*/
const int n = tp - colonp;
int i;
for ( i = 1; i <= n; i++ ) {
endp[- i] = colonp[n - i];
colonp[n - i] = 0;
}
tp = endp;
}
if ( tp != endp )
return(0);
memcpy(dst, tmp, NS_IN6ADDRSZ);
return(1);
}
#endif
#endif /* HAVE_INET_PTON */
#ifdef __cplusplus
} /* end extern "C" */
#endif

180
compat/signal.c Normal file
View File

@ -0,0 +1,180 @@
/*---------------------------------------------------------------
* Copyright (c) 1999,2000,2001,2002,2003
* The Board of Trustees of the University of Illinois
* All Rights Reserved.
*---------------------------------------------------------------
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software (Iperf) 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:
*
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and
* the following disclaimers.
*
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimers in the documentation and/or other materials
* provided with the distribution.
*
*
* Neither the names of the University of Illinois, NCSA,
* nor the names of its contributors may be used to endorse
* or promote products derived from this Software without
* specific prior written permission.
*
* 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 CONTIBUTORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* ________________________________________________________________
* National Laboratory for Applied Network Research
* National Center for Supercomputing Applications
* University of Illinois at Urbana-Champaign
* http://www.ncsa.uiuc.edu
* ________________________________________________________________
*
* signal.c
* by Mark Gates <mgates@nlanr.net>
* -------------------------------------------------------------------
* standard signal installer
* ------------------------------------------------------------------- */
#include "headers.h"
#include "util.h"
#ifdef __cplusplus
extern "C" {
#endif
#ifdef WIN32
/* list of signal handlers. _NSIG is number of signals defined. */
static SigfuncPtr handlers[ _NSIG ] = { 0};
/* -------------------------------------------------------------------
* sig_dispatcher
*
* dispatches the signal to appropriate signal handler. This emulates
* the signal handling of Unix.
*
* ------------------------------------------------------------------- */
BOOL WINAPI sig_dispatcher( DWORD type ) {
SigfuncPtr h = NULL;
int signo;
switch ( type ) {
case CTRL_C_EVENT:
signo = SIGINT;
h = handlers[ SIGINT ];
break;
case CTRL_CLOSE_EVENT:
case CTRL_LOGOFF_EVENT:
case CTRL_SHUTDOWN_EVENT:
signo = SIGTERM;
h = handlers[ SIGTERM ];
break;
default:
break;
}
if ( h != NULL ) {
// call the signal handler
h( signo );
return true;
} else {
return false;
}
}
/* -------------------------------------------------------------------
* my_signal
*
* installs a signal handler. I emulate Unix signals by storing the
* function pointers and dispatching events myself, using the
* sig_dispatcher above.
* ------------------------------------------------------------------- */
SigfuncPtr my_signal( int inSigno, SigfuncPtr inFunc ) {
SigfuncPtr old = NULL;
if ( inSigno >= 0 && inSigno < _NSIG ) {
old = handlers[ inSigno ];
handlers[ inSigno ] = inFunc;
}
return old;
} /* end my_signal */
#else /* not WIN32 */
/* -------------------------------------------------------------------
* my_signal
*
* installs a signal handler, and returns the old handler.
* This emulates the semi-standard signal() function in a
* standard way using the Posix sigaction function.
*
* from Stevens, 1998, section 5.8
* ------------------------------------------------------------------- */
SigfuncPtr my_signal( int inSigno, SigfuncPtr inFunc ) {
struct sigaction theNewAction, theOldAction;
assert( inFunc != NULL );
theNewAction.sa_handler = inFunc;
sigemptyset( &theNewAction.sa_mask );
theNewAction.sa_flags = 0;
if ( inSigno == SIGALRM ) {
#ifdef SA_INTERRUPT
theNewAction.sa_flags |= SA_INTERRUPT; /* SunOS 4.x */
#endif
} else {
#ifdef SA_RESTART
theNewAction.sa_flags |= SA_RESTART; /* SVR4, 4.4BSD */
#endif
}
if ( sigaction( inSigno, &theNewAction, &theOldAction ) < 0 ) {
return SIG_ERR;
} else {
return theOldAction.sa_handler;
}
} /* end my_signal */
#endif /* not WIN32 */
/* -------------------------------------------------------------------
* sig_exit
*
* Quietly exits. This protects some against being called multiple
* times. (TODO: should use a mutex to ensure (num++ == 0) is atomic.)
* ------------------------------------------------------------------- */
void sig_exit( int inSigno ) {
static int num = 0;
if ( num++ == 0 ) {
fflush( 0 );
exit( 0 );
}
} /* end sig_exit */
#ifdef __cplusplus
} /* end extern "C" */
#endif

101
compat/snprintf.c Normal file
View File

@ -0,0 +1,101 @@
/*---------------------------------------------------------------
* Copyright (c) 1999,2000,2001,2002,2003
* The Board of Trustees of the University of Illinois
* All Rights Reserved.
*---------------------------------------------------------------
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software (Iperf) 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:
*
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and
* the following disclaimers.
*
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimers in the documentation and/or other materials
* provided with the distribution.
*
*
* Neither the names of the University of Illinois, NCSA,
* nor the names of its contributors may be used to endorse
* or promote products derived from this Software without
* specific prior written permission.
*
* 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 CONTIBUTORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* ________________________________________________________________
* National Laboratory for Applied Network Research
* National Center for Supercomputing Applications
* University of Illinois at Urbana-Champaign
* http://www.ncsa.uiuc.edu
* ________________________________________________________________
* Author: Mark Gates
*
* snprintf.c
*
* This is from
* W. Richard Stevens, 'UNIX Network Programming', Vol 1, 2nd Edition,
* Prentice Hall, 1998.
*
*
* Throughout the book I use snprintf() because it's safer than sprintf().
* But as of the time of this writing, not all systems provide this
* function. The function below should only be built on those systems
* that do not provide a real snprintf().
* The function below just acts like sprintf(); it is not safe, but it
* tries to detect overflow.
* ________________________________________________________________ */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#ifndef HAVE_SNPRINTF
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <stdarg.h>
#include "snprintf.h"
#ifdef __cplusplus
extern "C" {
#endif
int snprintf(char *buf, size_t size, const char *fmt, ...) {
int n;
va_list ap;
va_start(ap, fmt);
vsprintf(buf, fmt, ap); /* Sigh, some vsprintf's return ptr, not length */
n = strlen(buf);
va_end(ap);
if ( n >= size ) {
fprintf( stderr, "snprintf: overflowed array\n" );
exit(1);
}
return(n);
}
#ifdef __cplusplus
} /* end extern "C" */
#endif
#endif /* HAVE_SNPRINTF */

76
compat/string.c Normal file
View File

@ -0,0 +1,76 @@
/*---------------------------------------------------------------
* Copyright (c) 1999,2000,2001,2002,2003
* The Board of Trustees of the University of Illinois
* All Rights Reserved.
*---------------------------------------------------------------
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software (Iperf) 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:
*
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and
* the following disclaimers.
*
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimers in the documentation and/or other materials
* provided with the distribution.
*
*
* Neither the names of the University of Illinois, NCSA,
* nor the names of its contributors may be used to endorse
* or promote products derived from this Software without
* specific prior written permission.
*
* 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 CONTIBUTORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* ________________________________________________________________
* National Laboratory for Applied Network Research
* National Center for Supercomputing Applications
* University of Illinois at Urbana-Champaign
* http://www.ncsa.uiuc.edu
* ________________________________________________________________
*
* string.c
* by Mark Gates <mgates@nlanr.net>
* -------------------------------------------------------------------
* various string utilities
* ------------------------------------------------------------------- */
#include "headers.h"
#include "util.h"
#ifdef __cplusplus
extern "C" {
#endif
/* -------------------------------------------------------------------
* pattern
*
* Initialize the buffer with a pattern of (index mod 10).
* ------------------------------------------------------------------- */
void pattern( char *outBuf, int inBytes ) {
assert( outBuf != NULL );
while ( inBytes-- > 0 ) {
outBuf[ inBytes ] = (inBytes % 10) + '0';
}
} /* end pattern */
#ifdef __cplusplus
} /* end extern "C" */
#endif

1456
config.guess vendored Executable file

File diff suppressed because it is too large Load Diff

301
config.h.in Normal file
View File

@ -0,0 +1,301 @@
/* config.h.in. Generated from configure.ac by autoheader. */
/* Define if debugging info is desired */
#undef DBG_MJZ
/* Define to 1 if you have the <arpa/inet.h> header file. */
#undef HAVE_ARPA_INET_H
/* Define to 1 if you have the `atexit' function. */
#undef HAVE_ATEXIT
/* Define to 1 if you have the declaration of `AF_INET6', and to 0 if you
don't. */
#undef HAVE_DECL_AF_INET6
/* Define to 1 if you have the declaration of `IPV6_ADD_MEMBERSHIP', and to 0
if you don't. */
#undef HAVE_DECL_IPV6_ADD_MEMBERSHIP
/* Define to 1 if you have the declaration of `IPV6_MULTICAST_HOPS', and to 0
if you don't. */
#undef HAVE_DECL_IPV6_MULTICAST_HOPS
/* Define to 1 if you have the declaration of `IP_ADD_MEMBERSHIP', and to 0 if
you don't. */
#undef HAVE_DECL_IP_ADD_MEMBERSHIP
/* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */
#undef HAVE_DOPRNT
/* Define to 1 if you have the `fork' function. */
#undef HAVE_FORK
/* Define to 1 if you have the `gettimeofday' function. */
#undef HAVE_GETTIMEOFDAY
/* Define to 1 if you have the `inet_ntop' function. */
#undef HAVE_INET_NTOP
/* Define to 1 if you have the `inet_pton' function. */
#undef HAVE_INET_PTON
/* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H
/* Define to enable IPv6 support */
#undef HAVE_IPV6
/* Define to enable IPv6 multicast support */
#undef HAVE_IPV6_MULTICAST
/* Define to 1 if you have the <libintl.h> header file. */
#undef HAVE_LIBINTL_H
/* Define to 1 if you have the `nsl' library (-lnsl). */
#undef HAVE_LIBNSL
/* Define to 1 if you have the `socket' library (-lsocket). */
#undef HAVE_LIBSOCKET
/* Define to 1 if your system has a GNU libc compatible `malloc' function, and
to 0 otherwise. */
#undef HAVE_MALLOC
/* Define to 1 if you have the <memory.h> header file. */
#undef HAVE_MEMORY_H
/* Define to 1 if you have the `memset' function. */
#undef HAVE_MEMSET
/* Define to enable multicast support */
#undef HAVE_MULTICAST
/* Define to 1 if you have the <netdb.h> header file. */
#undef HAVE_NETDB_H
/* Define to 1 if you have the <netinet/in.h> header file. */
#undef HAVE_NETINET_IN_H
/* */
#undef HAVE_POSIX_THREAD
/* */
#undef HAVE_PRINTF_QD
/* Define to 1 if you have the `pthread_cancel' function. */
#undef HAVE_PTHREAD_CANCEL
/* */
#undef HAVE_QUAD_SUPPORT
/* Define to 1 if you have the `select' function. */
#undef HAVE_SELECT
/* Define to 1 if you have the `snprintf' function. */
#undef HAVE_SNPRINTF
/* Define to 1 if the system has the type `ssize_t'. */
#undef HAVE_SSIZE_T
/* Define to 1 if you have the <stdint.h> header file. */
#undef HAVE_STDINT_H
/* Define to 1 if you have the <stdlib.h> header file. */
#undef HAVE_STDLIB_H
/* Define to 1 if you have the `strchr' function. */
#undef HAVE_STRCHR
/* Define to 1 if you have the `strerror' function. */
#undef HAVE_STRERROR
/* Define to 1 if you have the `strftime' function. */
#undef HAVE_STRFTIME
/* Define to 1 if you have the <strings.h> header file. */
#undef HAVE_STRINGS_H
/* Define to 1 if you have the <string.h> header file. */
#undef HAVE_STRING_H
/* Define to 1 if you have the `strtol' function. */
#undef HAVE_STRTOL
/* Define to 1 if the system has the type `struct ipv6_mreq'. */
#undef HAVE_STRUCT_IPV6_MREQ
/* Define to 1 if the system has the type `struct ip_mreq'. */
#undef HAVE_STRUCT_IP_MREQ
/* Define to 1 if the system has the type `struct sockaddr_in6'. */
#undef HAVE_STRUCT_SOCKADDR_IN6
/* Define to 1 if the system has the type `struct sockaddr_storage'. */
#undef HAVE_STRUCT_SOCKADDR_STORAGE
/* Define to 1 if you have the <syslog.h> header file. */
#undef HAVE_SYSLOG_H
/* Define to 1 if you have the <sys/select.h> header file. */
#undef HAVE_SYS_SELECT_H
/* Define to 1 if you have the <sys/socket.h> header file. */
#undef HAVE_SYS_SOCKET_H
/* Define to 1 if you have the <sys/stat.h> header file. */
#undef HAVE_SYS_STAT_H
/* Define to 1 if you have the <sys/time.h> header file. */
#undef HAVE_SYS_TIME_H
/* Define to 1 if you have the <sys/types.h> header file. */
#undef HAVE_SYS_TYPES_H
/* Define to 1 if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H
/* Define to 1 if you have the `usleep' function. */
#undef HAVE_USLEEP
/* Define to 1 if you have the `vfork' function. */
#undef HAVE_VFORK
/* Define to 1 if you have the <vfork.h> header file. */
#undef HAVE_VFORK_H
/* Define to 1 if you have the `vprintf' function. */
#undef HAVE_VPRINTF
/* Define if Web100 is desired and available */
#undef HAVE_WEB100
/* Define to 1 if `fork' works. */
#undef HAVE_WORKING_FORK
/* Define to 1 if `vfork' works. */
#undef HAVE_WORKING_VFORK
/* Name of package */
#undef PACKAGE
/* Define to the address where bug reports for this package should be sent. */
#undef PACKAGE_BUGREPORT
/* Define to the full name of this package. */
#undef PACKAGE_NAME
/* Define to the full name and version of this package. */
#undef PACKAGE_STRING
/* Define to the one symbol short name of this package. */
#undef PACKAGE_TARNAME
/* Define to the version of this package. */
#undef PACKAGE_VERSION
/* Define as the return type of signal handlers (`int' or `void'). */
#undef RETSIGTYPE
/* Define to the type of arg 1 for `select'. */
#undef SELECT_TYPE_ARG1
/* Define to the type of args 2, 3 and 4 for `select'. */
#undef SELECT_TYPE_ARG234
/* Define to the type of arg 5 for `select'. */
#undef SELECT_TYPE_ARG5
/* The size of a `bool', as computed by sizeof. */
#undef SIZEOF_BOOL
/* The size of a `int', as computed by sizeof. */
#undef SIZEOF_INT
/* The size of a `long', as computed by sizeof. */
#undef SIZEOF_LONG
/* The size of a `long long', as computed by sizeof. */
#undef SIZEOF_LONG_LONG
/* The size of a `short', as computed by sizeof. */
#undef SIZEOF_SHORT
/* The size of a `unsigned int', as computed by sizeof. */
#undef SIZEOF_UNSIGNED_INT
/* The size of a `unsigned long', as computed by sizeof. */
#undef SIZEOF_UNSIGNED_LONG
/* The size of a `unsigned long long', as computed by sizeof. */
#undef SIZEOF_UNSIGNED_LONG_LONG
/* The size of a `unsigned short', as computed by sizeof. */
#undef SIZEOF_UNSIGNED_SHORT
/* Define to 1 if you have the ANSI C header files. */
#undef STDC_HEADERS
/* Define 3rd arg of accept */
#undef Socklen_t
/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
#undef TIME_WITH_SYS_TIME
/* Define to 1 if your <sys/time.h> declares `struct tm'. */
#undef TM_IN_SYS_TIME
/* Version number of package */
#undef VERSION
/* Define to 1 if your processor stores words with the most significant byte
first (like Motorola and SPARC, unlike Intel and VAX). */
#undef WORDS_BIGENDIAN
/* */
#undef _REENTRANT
/* */
#undef bool
/* Define to empty if `const' does not conform to ANSI C. */
#undef const
/* */
#undef false
/* */
#undef int16_t
/* */
#undef int32_t
/* */
#undef int64_t
/* Define to rpl_malloc if the replacement function should be used. */
#undef malloc
/* Define to `int' if <sys/types.h> does not define. */
#undef pid_t
/* Define to `unsigned' if <sys/types.h> does not define. */
#undef size_t
/* Define to "int" if <sys/types.h> does not define. */
#undef ssize_t
/* */
#undef true
/* */
#undef u_int16_t
/* */
#undef u_int32_t
/* */
#undef u_int64_t
/* Define as `fork' if `vfork' does not work. */
#undef vfork

1549
config.sub vendored Executable file

File diff suppressed because it is too large Load Diff

14111
configure vendored Executable file

File diff suppressed because it is too large Load Diff

289
configure.ac Normal file
View File

@ -0,0 +1,289 @@
dnl ===================================================================
dnl configure.ac
dnl Process this file with autogen.sh to produce configure files
dnl ===================================================================
AC_INIT(Iperf,2.0)
AC_CONFIG_HEADERS([config.h])
AM_INIT_AUTOMAKE
AC_ARG_ENABLE(ipv6, AC_HELP_STRING([--disable-ipv6],
[disable ipv6 support (default is autodetect)]),
ac_cv_have_ipv6=$enable_ipv6,)
AC_ARG_ENABLE(multicast, AC_HELP_STRING([--disable-multicast],
[disable multicast support (default is autodetect)]),
ac_cv_multicast=$enable_multicast,)
AC_ARG_ENABLE(threads, AC_HELP_STRING([--disable-threads],
[disable thread support (default is autodetect)]))
AC_ARG_ENABLE(debuginfo, AC_HELP_STRING([--enable-debuginfo],
[enable debugging info for sockets (default is no)]),
enable_debuginfo=$enableval,
enable_debuginfo=no)
AC_ARG_ENABLE(web100, AC_HELP_STRING([--disable-web100],
[disable web100 support (default is autodetect)]))
dnl ===================================================================
dnl Checks for programs
dnl ===================================================================
AC_PROG_CXX
CXXFLAGS=`echo " $CXXFLAGS " | sed -e "s/ -g / /"` # do not want it implicitly
AC_PROG_CC
CFLAGS=`echo " $CFLAGS " | sed -e "s/ -g / /"` # do not want it implicitly
AC_ISC_POSIX
AC_PROG_INSTALL
AC_PROG_MAKE_SET
AC_PROG_RANLIB
AC_CANONICAL_HOST
dnl ===================================================================
dnl Checks for libraries.
dnl ===================================================================
dnl check for -lpthread
if test "$enable_threads" != no; then
ACX_PTHREAD()
if test "$acx_pthread_ok" = yes; then
AC_DEFINE([HAVE_POSIX_THREAD], 1,)
AC_DEFINE([_REENTRANT], 1,)
fi
fi
dnl check for -lnsl, -lsocket
AC_CHECK_FUNC(gethostbyname,,AC_CHECK_LIB(nsl, gethostbyname))
AC_CHECK_FUNC(socket,,AC_CHECK_LIB(socket, socket))
dnl Checks for header files.
AC_HEADER_STDC
AC_CHECK_HEADERS([arpa/inet.h libintl.h netdb.h netinet/in.h stdlib.h string.h strings.h sys/socket.h sys/time.h syslog.h unistd.h])
dnl ===================================================================
dnl Checks for typedefs, structures
dnl ===================================================================
AC_C_CONST
AC_TYPE_SIZE_T
AC_CHECK_TYPES(ssize_t,,AC_DEFINE_UNQUOTED(ssize_t, int))
AC_HEADER_TIME
AC_STRUCT_TM
dnl these intXX_t and u_intXX_t need to be defined to be the right size.
AC_CHECK_SIZEOF(short)
AC_CHECK_SIZEOF(int)
AC_CHECK_SIZEOF(long)
AC_CHECK_SIZEOF(long long)
AC_CHECK_SIZEOF(unsigned short)
AC_CHECK_SIZEOF(unsigned int)
AC_CHECK_SIZEOF(unsigned long)
AC_CHECK_SIZEOF(unsigned long long)
AH_TEMPLATE(int16_t)
AH_TEMPLATE(int32_t)
AH_TEMPLATE(int64_t)
AH_TEMPLATE(u_int16_t)
AH_TEMPLATE(u_int32_t)
AH_TEMPLATE(u_int64_t)
DAST_REPLACE_TYPE(int16_t, 2)
DAST_REPLACE_TYPE(int32_t, 4)
DAST_REPLACE_TYPE(int64_t, 8)
DAST_REPLACE_TYPE_UNSIGNED(u_int16_t, 2)
DAST_REPLACE_TYPE_UNSIGNED(u_int32_t, 4)
DAST_REPLACE_TYPE_UNSIGNED(u_int64_t, 8)
AC_CACHE_CHECK(3rd argument of accept, ac_cv_accept_arg, [
dnl Try socklen_t (POSIX)
DAST_ACCEPT_ARG(socklen_t)
dnl Try int (original BSD)
DAST_ACCEPT_ARG(int)
dnl Try size_t (older standard; AIX)
DAST_ACCEPT_ARG(size_t)
dnl Try short (shouldn't be)
DAST_ACCEPT_ARG(short)
dnl Try long (shouldn't be)
DAST_ACCEPT_ARG(long)
])
if test -z "$ac_cv_accept_arg" ; then
ac_cv_accept_arg=int
fi
AC_DEFINE_UNQUOTED([Socklen_t], $ac_cv_accept_arg, [Define 3rd arg of accept])
dnl Checks for library functions.
AC_FUNC_FORK
AC_FUNC_MALLOC
AC_FUNC_MEMCMP
AC_FUNC_SELECT_ARGTYPES
AC_TYPE_SIGNAL
AC_FUNC_STRFTIME
AC_FUNC_VPRINTF
AC_CHECK_FUNCS([atexit gettimeofday memset pthread_cancel select strchr strerror strtol usleep])
AC_REPLACE_FUNCS(snprintf inet_pton inet_ntop gettimeofday)
dnl Gotten from some NetBSD configure.in
dnl We assume that if sprintf() supports %lld or %qd,
dnl then all of *printf() does. If not, disable long long
dnl support because we don't know how to display it.
AH_TEMPLATE(HAVE_QUAD_SUPPORT)
AH_TEMPLATE(HAVE_PRINTF_QD)
AC_MSG_CHECKING(*printf() support for %lld)
can_printf_longlong=no
AC_TRY_RUN([
#include <stdio.h>
int main() {
char buf[100];
sprintf(buf, "%lld", 21726587590LL);
return (strcmp(buf, "21726587590"));
}
], [
AC_MSG_RESULT(yes)
can_printf_longlong=yes
], [
AC_MSG_RESULT(no)
], [ : ])
if test $can_printf_longlong != yes; then
AC_MSG_CHECKING(*printf() support for %qd)
AC_TRY_RUN([
#include <stdio.h>
int main() {
char buf[100];
sprintf(buf, "%qd", 21726587590LL);
return (strcmp(buf, "21726587590"));
}
], [
AC_MSG_RESULT(yes)
can_printf_longlong=yes
AC_DEFINE(HAVE_PRINTF_QD, 1)
], [
AC_MSG_RESULT(no)
], [ : ])
fi
if test $can_printf_longlong = yes; then
AC_DEFINE(HAVE_QUAD_SUPPORT, 1)
fi
dnl ===================================================================
dnl Check for compiler characteristics
DAST_CHECK_BOOL
AC_C_BIGENDIAN
dnl ===================================================================
dnl Check for system services
dnl check for multicast
if test "$ac_cv_multicast" != no; then
AC_CHECK_TYPES(struct ip_mreq,,,[#include "include/headers_slim.h"])
AC_CHECK_DECLS(IP_ADD_MEMBERSHIP,,,[#include "include/headers_slim.h"])
AC_MSG_CHECKING(for multicast support)
ac_cv_multicast=no
if test "$ac_cv_have_decl_IP_ADD_MEMBERSHIP" = yes; then
if test "$ac_cv_type_struct_ip_mreq" = yes; then
ac_cv_multicast=yes
fi
fi
AC_MSG_RESULT($ac_cv_multicast)
if test "$ac_cv_multicast" = yes; then
AC_DEFINE([HAVE_MULTICAST], 1, [Define to enable multicast support])
fi
fi
dnl check for IPv6
if test "$ac_cv_have_ipv6" != no; then
AC_CHECK_TYPES(struct sockaddr_storage,,,[#include "include/headers_slim.h"])
AC_CHECK_TYPES(struct sockaddr_in6,,,[#include "include/headers_slim.h"])
AC_CHECK_DECLS(AF_INET6,,,[#include "include/headers_slim.h"])
AC_MSG_CHECKING(for IPv6 headers and structures)
ac_cv_have_ipv6=no
if test "$ac_cv_type_struct_sockaddr_storage" = yes; then
if test "$ac_cv_type_struct_sockaddr_in6" = yes; then
if test "$ac_cv_have_decl_AF_INET6" = yes; then
AC_DEFINE([HAVE_IPV6], 1, [Define to enable IPv6 support])
ac_cv_have_ipv6=yes
fi
fi
fi
AC_MSG_RESULT($ac_cv_have_ipv6)
fi
if test "$ac_cv_have_ipv6" = yes; then
if test "$ac_cv_multicast" = yes; then
AC_CHECK_TYPES(struct ipv6_mreq,,,[#include "include/headers_slim.h"])
AC_CHECK_DECLS(IPV6_ADD_MEMBERSHIP,,,[#include "include/headers_slim.h"])
AC_CHECK_DECLS(IPV6_MULTICAST_HOPS,,,[#include "include/headers_slim.h"])
AC_MSG_CHECKING(for IPv6 multicast support)
ac_cv_have_ipv6_multicast=no
if test "$ac_cv_type_struct_ipv6_mreq" = yes; then
if test "$ac_cv_have_decl_IPV6_ADD_MEMBERSHIP" = yes; then
if test "$ac_cv_have_decl_IPV6_MULTICAST_HOPS" = yes; then
AC_DEFINE([HAVE_IPV6_MULTICAST], 1, [Define to enable IPv6 multicast support])
ac_cv_have_ipv6_multicast=yes
fi
fi
fi
AC_MSG_RESULT($ac_cv_have_ipv6_multicast)
fi
fi
if test "$enable_debuginfo" = yes; then
AC_DEFINE([DBG_MJZ], 1, [Define if debugging info is desired])
fi
if test "$enable_web100" != no; then
if test -e "/proc/web100"; then
if test -d "/proc/web100"; then
if test -e "/proc/web100/header"; then
if test -f "/proc/web100/header"; then
if test -r "/proc/web100/header"; then
AM_PATH_WEB100()
if test "$web100_success" = yes; then
AC_DEFINE([HAVE_WEB100], 1, [Define if Web100 is desired and available])
fi fi fi fi fi fi
fi
dnl GNU make allows us to use the $(strip ...) builtin which eliminates a
dnl large amount of extra whitespace in compile lines.
AC_MSG_CHECKING(whether make is GNU make)
STRIP_BEGIN=
STRIP_END=
if $ac_make --version 2> /dev/null | grep '^GNU Make ' > /dev/null ; then
STRIP_BEGIN='$(strip $(STRIP_DUMMY)'
STRIP_END=')'
AC_MSG_RESULT(yes)
else
AC_MSG_RESULT(no)
fi
dnl some Make 3.79 $(strip ) versions are broken and require an empty arg
STRIP_DUMMY=
AC_SUBST(STRIP_DUMMY)
AC_SUBST(STRIP_BEGIN)
AC_SUBST(STRIP_END)
AC_CONFIG_FILES([Makefile
compat/Makefile
doc/Makefile
include/Makefile
src/Makefile])
AC_OUTPUT

520
depcomp Executable file
View File

@ -0,0 +1,520 @@
#! /bin/sh
# depcomp - compile a program generating dependencies as side-effects
scriptversion=2003-11-08.23
# Copyright (C) 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 <oliva@dcc.unicamp.br>.
case $1 in
'')
echo "$0: No command. Try \`$0 --help' for more information." 1>&2
exit 1;
;;
-h | --h*)
cat <<\EOF
Usage: depcomp [--help] [--version] PROGRAM [ARGS]
Run PROGRAMS ARGS to compile a file, generating dependencies
as side-effects.
Environment variables:
depmode Dependency tracking mode.
source Source file read by `PROGRAMS ARGS'.
object Object file output by `PROGRAMS ARGS'.
depfile Dependency file to output.
tmpdepfile Temporary file to use when outputing dependencies.
libtool Whether libtool is used (yes/no).
Report bugs to <bug-automake@gnu.org>.
EOF
exit 0
;;
-v | --v*)
echo "depcomp $scriptversion"
exit 0
;;
esac
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
# Local Variables:
# mode: shell-script
# sh-indentation: 2
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-end: "$"
# End:

1
doc/Makefile.am Normal file
View File

@ -0,0 +1 @@
EXTRA_DIST = index.html ui_license.html dast.gif

294
doc/Makefile.in Normal file
View File

@ -0,0 +1,294 @@
# Makefile.in generated by automake 1.8.3 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
# 2003, 2004 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
top_builddir = ..
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
INSTALL = @INSTALL@
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
host_triplet = @host@
subdir = doc
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/dast.m4 \
$(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(mkdir_p)
CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
SOURCES =
DIST_SOURCES =
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMDEP_FALSE = @AMDEP_FALSE@
AMDEP_TRUE = @AMDEP_TRUE@
AMTAR = @AMTAR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CXX = @CXX@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
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@
OBJEXT = @OBJEXT@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
RANLIB = @RANLIB@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
STRIP_BEGIN = @STRIP_BEGIN@
STRIP_DUMMY = @STRIP_DUMMY@
STRIP_END = @STRIP_END@
VERSION = @VERSION@
WEB100_CFLAGS = @WEB100_CFLAGS@
WEB100_CONFIG = @WEB100_CONFIG@
WEB100_LIBS = @WEB100_LIBS@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
ac_ct_RANLIB = @ac_ct_RANLIB@
ac_ct_STRIP = @ac_ct_STRIP@
am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
datadir = @datadir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localstatedir = @localstatedir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
prefix = @prefix@
program_transform_name = @program_transform_name@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
EXTRA_DIST = index.html ui_license.html dast.gif
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 \
&& exit 0; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign doc/Makefile'; \
cd $(top_srcdir) && \
$(AUTOMAKE) --foreign 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
uninstall-info-am:
tags: TAGS
TAGS:
ctags: CTAGS
CTAGS:
distdir: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
list='$(DISTFILES)'; for file in $$list; do \
case $$file in \
$(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
$(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
esac; \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
if test "$$dir" != "$$file" && test "$$dir" != "."; then \
dir="/$$dir"; \
$(mkdir_p) "$(distdir)$$dir"; \
else \
dir=''; \
fi; \
if test -d $$d/$$file; then \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
fi; \
cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
else \
test -f $(distdir)/$$file \
|| cp -p $$d/$$file $(distdir)/$$file \
|| exit 1; \
fi; \
done
check-am: all-am
check: check-am
all-am: Makefile
installdirs:
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-am
install-strip:
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
`test -z '$(STRIP)' || \
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:
clean-generic:
distclean-generic:
-rm -f $(CONFIG_CLEAN_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-am
clean-am: clean-generic mostlyclean-am
distclean: distclean-am
-rm -f Makefile
distclean-am: clean-am distclean-generic
dvi: dvi-am
dvi-am:
html: html-am
info: info-am
info-am:
install-data-am:
install-exec-am:
install-info: install-info-am
install-man:
installcheck-am:
maintainer-clean: maintainer-clean-am
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-generic
pdf: pdf-am
pdf-am:
ps: ps-am
ps-am:
uninstall-am: uninstall-info-am
.PHONY: all all-am check check-am clean clean-generic distclean \
distclean-generic distdir dvi dvi-am html html-am info info-am \
install install-am install-data install-data-am install-exec \
install-exec-am install-info install-info-am install-man \
install-strip installcheck installcheck-am installdirs \
maintainer-clean maintainer-clean-generic mostlyclean \
mostlyclean-generic pdf pdf-am ps ps-am uninstall uninstall-am \
uninstall-info-am
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

BIN
doc/dast.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

758
doc/index.html Normal file
View File

@ -0,0 +1,758 @@
<HTML>
<HEAD>
<TITLE>Iperf version 2.0.0</TITLE>
<!-- $Id: index.html,v 1.1.1.1 2004/05/18 01:50:44 kgibbs Exp $ -->
</HEAD>
<BODY BGCOLOR="#FFFFFF" LINK="#006633" VLINK="#669900" ALINK="#669966">
<CENTER>
<P><IMG SRC="dast.gif"
ALT="Distributed Applications Support Team"></P>
</CENTER>
<H1>Iperf version 2.0.0</H1>
<H3>May 2004</H3>
<HR><!-- ----- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- -->
<H3>NLANR applications support
<BR><A HREF="http://dast.nlanr.net/">http://dast.nlanr.net/</A>
<BR><A HREF="mailto:dast@nlanr.net">&lt;dast@nlanr.net&gt;</A>
</H3>
<P><FONT face="arial,helvetica">
<H1>Iperf User Docs</H1>
<H4>Mark Gates<br>
Ajay Tirumala<BR>
Jon Dugan<BR>
Kevin Gibbs<BR> </H4>
May 2004
<P></CENTER>
[<a href="#compiling">Compiling</A> |
<A href="#features">Features</A>&nbsp; |
<A href="#tuningtcp">Tuning a TCP connection</A> |
<A href="#tuningudp">Tuning a UDP connection</A> |
<A href="#multicast">Running multicast servers and clients</A> |
<A href="#ipv6">IPv6 Mode</A> |
<A href="#repmode">Representative Streams</A> |
<A href="#daemon"> Running Iperf as a daemon</A> |
<!--<A href="#adaptive">Adaptive Window Sizes</A> | -->
<A href="#service">Running Iperf as a Windows Service</A> ]
<HR>
<!-- ----- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- -->
<H2><A name=compiling></A>Compiling</H2>
Once you have the distribution, on UNIX,
unpack it using gzip and tar. That will create a new directory
'iperf-&lt;version#&gt;' with the source files and documentation.
<P>
Iperf compiles cleanly on many systems including Linux, SGI IRIX, HP-UX,
Solaris, AIX, and Cray UNICOS. Use '<TT>make</TT>' to configure for your OS and
compile the source code.
<BLOCKQUOTE><PRE>
gunzip -c iperf-&lt;version&gt;.tar.gz | tar -xvf -
cd iperf-&lt;version&gt;
./configure
make
</PRE></BLOCKQUOTE>
To install iperf, use '<TT>make install</TT>',
which will ask you where to install it. To recompile, the easiest way is to
start over. Do '<TT>make distclean</TT>' then '<TT>./configure; make</TT>'. See the Makefile
for more options.
<P>
If you have problems, please report them to <A href="mailto:dast@nlanr.net">dast@nlanr.net</A> and
we will try to fix them quickly. <BR>
<HR>
<!-- ----- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- -->
<H2><A name=features></A>Features</H2>
<UL>
<LI>TCP
<UL>
<LI>Measure bandwidth
<LI>Report MSS/MTU size and observed read sizes.
<LI>Support for TCP window size via socket buffers.
<LI>Multi-threaded if pthreads or Win32 threads are available. Client and
server can have multiple simultaneous connections.
<!-- <LI>Suggest the optimal window size for a connection where the OS allows
setting window sizes in the granularity of bytes. </LI>--></UL>
<LI>UDP
<UL>
<LI>Client can create UDP streams of specified bandwidth.
<LI>Measure packet loss
<LI>Measure delay jitter
<LI>Multicast capable
<LI>Multi-threaded if pthreads are available. Client and server can have
multiple simultaneous connections. (This doesn't work in Windows.) </LI></UL>
<LI>Where appropriate, options can be specified with K (kilo-) and M (mega-)
suffices. So 128K instead of 131072 bytes.
<LI>Can run for specified time, rather than a set amount of data to transfer.
<LI>Picks the best units for the size of data being reported.
<LI>Server handles multiple connections, rather than quitting after a single
test.
<LI>Print periodic, intermediate bandwidth, jitter, and loss reports at
specified intervals.
<LI>Run the server as a daemon (Check out <A
href="http://www-itg.lbl.gov/nettest">Nettest</A> for running it as a secure
daemon).
<LI>Run the server as a Windows NT Service
<LI>Use representative streams to test out how link layer compression affects
your achievable bandwidth.
<!-- <LI>A library of <A
href="lib.html">useful functions and C++
classes.</A> </LI>
-->
</UL>
<HR>
<!-- ----- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- --><BR>&nbsp;
<TABLE cellPadding=3 border=1>
<TBODY>
<TR vAlign=top>
<TH align=left>Command line option</TH>
<TH align=left>Environment variable option</TH>
<TH align=left>Description</TH></TR>
<TR>
<TH bgColor=#cccccc colSpan=3>Client and Server options</TH></TR>
<TR vAlign=top>
<TD><A name=format></A><TT>-f, --format <I>[bkmaBKMA]</I></TT></TD>
<TD><TT>$IPERF_FORMAT</TT></TD>
<TD>A letter specifying the format to print bandwidth numbers in.
Supported formats are&nbsp;
<PRE>
&nbsp;&nbsp;&nbsp; 'b' = bits/sec&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 'B' = Bytes/sec
&nbsp;&nbsp;&nbsp; 'k' = Kbits/sec&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 'K' = KBytes/sec
&nbsp;&nbsp;&nbsp; 'm' = Mbits/sec&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 'M' = MBytes/sec
&nbsp;&nbsp;&nbsp; 'g' = Gbits/sec&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 'G' = GBytes/sec
&nbsp;&nbsp;&nbsp; 'a' = adaptive bits/sec&nbsp;&nbsp; 'A' = adaptive Bytes/sec
</PRE>
The adaptive formats choose between kilo- and mega- as appropriate. Fields
other than bandwidth always print bytes, but otherwise follow the
requested format. Default is 'a'.&nbsp; <BR><I>NOTE:</I> here Kilo = 1024,
Mega = 1024^2 and Giga = 1024^3 when dealing with bytes. Commonly in networking,
Kilo = 1000, Mega = 1000^2, and Giga = 1000^3 so we use this when dealing with
bits. If this really bothers you, use -f b and do the math.</TD></TR>
<TR vAlign=top>
<TD><A name=interval></A><TT>-i, --interval <I>#</I></TT></TD>
<TD><TT>$IPERF_INTERVAL</TT></TD>
<TD>Sets the interval time in seconds between periodic bandwidth, jitter,
and loss reports. If non-zero, a report is made every <I>interval</I>
seconds of the bandwidth since the last report. If zero, no periodic
reports are printed. Default is zero.</TD></TR>
<TR vAlign=top>
<TD><A name=len></A><TT>-l, --len <I>#[KM]</I></TT></TD>
<TD><TT>$IPERF_LEN</TT></TD>
<TD>The length of buffers to read or write. Iperf works by writing an
array of <I>len</I> bytes a number of times. Default is 8 KB for TCP, 1470
bytes for UDP. Note for UDP, this is the datagram size and needs to be lowered when using
IPv6 addressing to 1450 or less to avoid fragmentation. See also the <A
href="#num">-n</A>
and <A
href="#time">-t</A>
options.</TD></TR>
<TR vAlign=top>
<TD><A name=print_mss></A><TT>-m, --print_mss</TT></TD>
<TD><TT>$IPERF_PRINT_MSS</TT></TD>
<TD>Print the reported TCP MSS size (via the TCP_MAXSEG option) and the
observed read sizes which often correlate with the MSS. The MSS is usually
the MTU - 40 bytes for the TCP/IP header. Often a slightly smaller MSS is
reported because of extra header space from IP options. The interface type
corresponding to the MTU is also printed (ethernet, FDDI, etc.). This
option is not implemented on many OSes, but the read sizes may still
indicate the MSS.</TD></TR>
<TR vAlign=top>
<TD><A name=port></A><TT>-p, --port <I>#</I></TT></TD>
<TD><TT>$IPERF_PORT</TT></TD>
<TD>The server port for the server to listen on and the client to connect
to. This should be the same in both client and server. Default is 5001,
the same as ttcp.</TD></TR>
<TR vAlign=top>
<TD><A name=udp></A><TT>-u, --udp</TT></TD>
<TD><TT>$IPERF_UDP</TT></TD>
<TD>Use UDP rather than TCP. See also the <A
href="#bandwidth">-b</A>
option.</TD></TR>
<TR vAlign=top>
<TD><A name=window></A><TT>-w, --window <I>#[KM]</I></TT></TD>
<TD><TT>$TCP_WINDOW_SIZE</TT></TD>
<TD>Sets the socket buffer sizes to the specified value. For TCP, this
sets the TCP window size. For UDP it is just the buffer which datagrams
are received in, and so limits the largest receivable datagram size.</TD></TR>
<TR vAlign=top>
<TD><A name=bind></A><TT>-B, --bind <I>host</I></TT></TD>
<TD><TT>$IPERF_BIND</TT></TD>
<TD>Bind to <I>host</I>, one of this machine's addresses. For the client
this sets the outbound interface. For a server this sets the incoming
interface. This is only useful on multihomed hosts, which have multiple
network interfaces.&nbsp;
<P>For Iperf in UDP server mode, this is also used to bind and join to a
multicast group. Use addresses in the range 224.0.0.0 to 239.255.255.255
for multicast. See also the <A
href="#ttl">-T</A>
option.</P></TD></TR>
<TR vAlign=top>
<TD><A name=compatibility></A><TT>-C, --compatibility </TT></TD>
<TD><TT>$IPERF_COMPAT</TT></TD>
<TD>Compatibility mode allows for use with older version of iperf. This mode
is not required for interoperability but it is highly recommended. In
some cases when using representative streaming you could cause a 1.7 server
to crash or cause undesired connection attempts.</P></TD></TR>
<TR vAlign=top>
<TD><A name=mss></A><TT>-M, --mss <I>#[KM}</I></TT></TD>
<TD><TT>$IPERF_MSS</TT></TD>
<TD>Attempt to set the TCP maximum segment size (MSS) via the TCP_MAXSEG
option. The MSS is usually the MTU - 40 bytes for the TCP/IP header. For
ethernet, the MSS is 1460 bytes (1500 byte MTU). This option is not
implemented on many OSes.</TD></TR>
<TR vAlign=top>
<TD><A name=nodelay></A><TT>-N, --nodelay</TT></TD>
<TD><TT>$IPERF_NODELAY</TT></TD>
<TD>Set the TCP no delay option, disabling Nagle's algorithm. Normally
this is only disabled for interactive applications like telnet.</TD></TR>
<TR>
<TD><TT>-V </TT>(from v1.6 or higher)</TD>
<TD>.</TD>
<TD>Bind to an IPv6 address <BR>Server side: <BR>$ iperf -s -V&nbsp;
<P>Client side: <BR>$ iperf -c &lt;Server IPv6 Address&gt; -V
<BR>&nbsp;</P>Note: On version 1.6.3 and later a specific IPv6 Address does
not need to be bound with the <A href="#bind">-B</A> option, previous 1.6
versions do. Also on most OSes using this option will also respond to IPv4
clients using IPv4 mapped addresses.</TD></TR>
<TR>
<TH bgColor=#cccccc colSpan=3>Server specific options</TH></TR>
<TR vAlign=top>
<TD><A name=server></A><TT>-s, --server</TT></TD>
<TD><TT>$IPERF_SERVER</TT></TD>
<TD>Run Iperf in server mode.</TD></TR>
<TR>
<TD><TT>-D </TT> (from v1.2 or higher)</TD>
<TD>.</TD>
<TD>Run the server as a daemon (Unix platforms) <BR>On Win32 platforms
where services are available, Iperf will start running as a service.</TD></TR>
<TR>
<TD><TT>-R </TT>(only for Windows, from v1.2 or higher)</TD>
<TD>.</TD>
<TD>Remove the Iperf service (if it's running).&nbsp;</TD></TR><TR>
<TD><TT>-o </TT>(only for Windows, from v1.2 or higher)</TD>
<TD>.</TD>
<TD>Redirect output to given file.&nbsp;</TD></TR>
<TR vAlign=top>
<TD><A name=sclient></A><TT>-c, --client <I>host</I></TT></TD>
<TD><TT>$IPERF_CLIENT</TT></TD>
<TD> If Iperf is in server mode, then specifying a host with -c
will limit the connections that Iperf will accept to the
<I>host</I> specified. Does not work well for UDP.</TD></TR>
<TR vAlign=top>
<TD><A name=sparallel></A><TT>-P, --parallel <I>#</I></TT></TD>
<TD><TT>$IPERF_PARALLEL</TT></TD>
<TD>The number of connections to handle by the server before
closing. Default is 0 (which means to accept connections forever).</TD></TR>
<TR>
<TH bgColor=#cccccc colSpan=3>Client specific options</TH></TR>
<TR vAlign=top>
<TD><A name=bandwidth></A><TT>-b, --bandwidth <I>#[KM]</I></TT></TD>
<TD><TT>$IPERF_BANDWIDTH</TT></TD>
<TD>The UDP bandwidth to send at, in bits/sec. This implies the -u option.
Default is 1 Mbit/sec.</TD></TR>
<TR vAlign=top>
<TD><A name=client></A><TT>-c, --client <I>host</I></TT></TD>
<TD><TT>$IPERF_CLIENT</TT></TD>
<TD>Run Iperf in client mode, connecting to an Iperf server running on
<I>host</I>.</TD></TR>
<TR vAlign=top>
<TD><A name=dualtest></A><TT>-d, --dualtest </TT></TD>
<TD><TT>$IPERF_DUALTEST</TT></TD>
<TD>Run Iperf in dual testing mode. This will cause the server to connect
back to the client on the port specified in the
<A href="#listenport">-L</A> option (or defaults
to the port the client connected to the server on). This is done immediately
therefore running the tests simultaneously. If you want an alternating
test try <A href="#tradeoff">-r.</A></TD></TR>
<TR vAlign=top>
<TD><A name=num></A><TT>-n, --num <I>#[KM]</I></TT></TD>
<TD><TT>$IPERF_NUM</TT></TD>
<TD>The number of buffers to transmit. Normally, Iperf sends for 10
seconds. The -n option overrides this and sends an array of <I>len</I>
bytes <I>num</I> times, no matter how long that takes. See also the <A
href="#len">-l</A>
and <A
href="#time">-t</A>
options.</TD></TR>
<TR vAlign=top>
<TD><A name=tradeoff></A><TT>-r, --tradeoff </TT></TD>
<TD><TT>$IPERF_TRADEOFF</TT></TD>
<TD>Run Iperf in tradeoff testing mode. This will cause the server to connect
back to the client on the port specified in the
<A href="#listenport">-L</A> option (or defaults
to the port the client connected to the server on). This is done following
the client connection termination, therefore running the tests
alternating. If you want an simultaneous test try
<A href="#dualtest">-d.</A></TD></TR>
<TR vAlign=top>
<TD><A name=time></A><TT>-t, --time <I>#</I></TT></TD>
<TD><TT>$IPERF_TIME</TT></TD>
<TD>The time in seconds to transmit for. Iperf normally works by
repeatedly sending an array of <I>len</I> bytes for <I>time</I> seconds.
Default is 10 seconds. See also the <A
href="#len">-l</A>
and <A
href="#num">-n</A>
options.</TD></TR>
<TR vAlign=top>
<TD><A name=listenport></A><TT>-L, --listenport <I>#</I></TT></TD>
<TD><TT>$IPERF_LISTENPORT</TT></TD>
<TD>This specifies the port that the server will connect back to the
client on. It defaults to the port used to connect to the server
from the client.</TD></TR>
<TR vAlign=top>
<TD><A name=parallel></A><TT>-P, --parallel <I>#</I></TT></TD>
<TD><TT>$IPERF_PARALLEL</TT></TD>
<TD>The number of simultaneous connections to make to the server. Default
is 1. Requires thread support on both the client and server.</TD></TR>
<TR vAlign=top>
<TD><A name=tos></A><TT>-S, --tos <I>#</I></TT></TD>
<TD><TT>$IPERF_TOS</TT></TD>
<TD>The type-of-service for outgoing packets. (Many routers ignore the TOS
field.) You may specify the value in hex with a '0x' prefix, in octal with
a '0' prefix, or in decimal. For example, '0x10' hex = '020' octal = '16'
decimal. The TOS numbers specified in RFC 1349 are:&nbsp;
<PRE>
&nbsp;&nbsp;&nbsp; IPTOS_LOWDELAY&nbsp;&nbsp;&nbsp;&nbsp; minimize delay&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0x10
&nbsp;&nbsp;&nbsp; IPTOS_THROUGHPUT&nbsp;&nbsp; maximize throughput&nbsp;&nbsp; 0x08
&nbsp;&nbsp;&nbsp; IPTOS_RELIABILITY&nbsp; maximize reliability&nbsp; 0x04
&nbsp;&nbsp;&nbsp; IPTOS_LOWCOST&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; minimize cost&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0x02
&nbsp;&nbsp;&nbsp;&nbsp;
</PRE>
</TD></TR>
<TR vAlign=top>
<TD><A name=ttl></A><TT>-T, --ttl <I>#</I></TT></TD>
<TD><TT>$IPERF_TTL</TT></TD>
<TD>The time-to-live for outgoing multicast packets. This is essentially
the number of router hops to go through, and is also used for scoping.
Default is 1, link-local.</TD></TR>
<TR>
<TD><TT>-F</TT> (from v1.2 or higher)</TD>
<TD>.</TD>
<TD>Use a representative stream to measure bandwidth, e.g. :-&nbsp; <BR>$
iperf -c &lt;server address&gt; -F &lt;file-name&gt;</TD></TR>
<TR>
<TD><TT>-I </TT>(from v1.2 or higher)</TD>
<TD>.</TD>
<TD>Same as -F, input from stdin.</TD></TR>
<!-- <TR>
<TD><TT>-W </TT>(from v1.2 or higher)</TD>
<TD>.</TD>
<TD>Adaptive Window Sizes.
<BR>Use Iperf to suggest the best Window size for a connection. Iperf will start from a default window size and try to perform a search for the optimal window size</TD></TR>
--> <TR>
<TH bgColor=#cccccc colSpan=3>Miscellaneous options</TH></TR>
<TR vAlign=top>
<TD><A name=help></A><TT>-h, --help</TT></TD>
<TD>&nbsp;</TD>
<TD>Print out a summary of commands and quit.</TD></TR>
<TR vAlign=top>
<TD><A name=version></A><TT>-v, --version</TT></TD>
<TD>&nbsp;</TD>
<TD>Print version information and quit. Prints 'pthreads' if compiled with
POSIX threads, 'win32 threads' if compiled with Microsoft Win32 threads,
or 'single threaded' if compiled without threads.</TD></TR></TBODY></TABLE>
<P>
<HR>
<!-- ----- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- -->
<H2><A name=tuningtcp></A>Tuning a TCP connection</H2>
The primary goal of Iperf
is to help in tuning TCP connections over a particular path. The most
fundamental tuning issue for TCP is the TCP window size, which controls how much
data can be in the network at any one point. If it is too small, the sender will
be idle at times and get poor performance. The theoretical value to use for the
TCP window size is the <I>bandwidth delay product</I>,
<BLOCKQUOTE>bottleneck bandwidth * round trip time</BLOCKQUOTE>In the below
modi4/cyclops example, the bottleneck link is a 45 Mbit/sec DS3 link and the
round trip time measured with ping is 42 ms. The bandwidth delay product is
<BLOCKQUOTE>45 Mbit/sec * 42 ms <BR>= (45e6) * (42e-3) <BR>= 1890000 bits
<BR>= 230 KByte</BLOCKQUOTE>That is a starting point for figuring the best
window size; setting it higher or lower may produce better results. In our
example, buffer sizes over 130K did not improve the performance, despite the
bandwidth delay product of 230K.
<P>Note that many OSes and hosts have upper limits on the TCP window size. These
may be as low as 64 KB, or as high as several MB. Iperf tries to detect when
these occur and give a warning that the actual and requested window sizes are
not equal (as below, though that is due to rounding in IRIX). PSC has a <A
href="http://www.psc.edu/networking/perf_tune.html">list detailing</A> how to
change the default and maximum window sizes for various OSes. For more
information on TCP window sizes, see the <A
href="http://dast.nlanr.net/Guides/GettingStarted/TCP_window_size.html">User's
Guide to TCP Windows.</A>
<P>Here is an example session, between node1 in Illinois and node2 in North
Carolina. These are connected via the vBNS backbone and a 45 Mbit/sec DS3 link.
Notice we improve bandwidth performance by a factor of 3 using proper TCP window
sizes. Use the adaptive window sizes feature on platforms which allow setting
window sizes in the granularity of bytes.
<BLOCKQUOTE>
<PRE>
<B>node2&gt;</B> iperf -s
------------------------------------------------------------
Server listening on TCP port 5001
TCP window size: 60.0 KByte (default)
------------------------------------------------------------
[&nbsp; 4] local &lt;IP Addr node2&gt; port 5001 connected with &lt;IP Addr node1&gt; port 2357
[ ID] Interval&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Transfer&nbsp;&nbsp;&nbsp;&nbsp; Bandwidth
[&nbsp; 4]&nbsp; 0.0-10.1 sec&nbsp;&nbsp; 6.5 MBytes&nbsp;&nbsp; <B><FONT color=#ff0000>5.2 Mbits/sec
</FONT>node1&gt;</B> iperf -c node2
------------------------------------------------------------
Client connecting to node1, TCP port 5001
TCP window size: 59.9 KByte (default)
------------------------------------------------------------
[&nbsp; 3] local &lt;IP Addr node1&gt; port 2357 connected with &lt;IP Addr node2&gt; port 5001
[ ID] Interval&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Transfer&nbsp;&nbsp;&nbsp;&nbsp; Bandwidth
[&nbsp; 3]&nbsp; 0.0-10.0 sec&nbsp;&nbsp; 6.5 MBytes&nbsp;&nbsp; 5.2 Mbits/sec</PRE>
<HR>
<PRE><B>node2&gt;</B> iperf -s -w 130k
------------------------------------------------------------
Server listening on TCP port 5001
TCP window size:&nbsp; 130 KByte
------------------------------------------------------------
[&nbsp; 4] local &lt;IP Addr node 2&gt; port 5001 connected with &lt;IP Addr node 1&gt; port 2530
[ ID] Interval&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Transfer&nbsp;&nbsp;&nbsp;&nbsp; Bandwidth
[&nbsp; 4]&nbsp; 0.0-10.1 sec&nbsp; 19.7 MBytes&nbsp; <B><FONT color=#ff0000>15.7 Mbits/sec
</FONT>node1&gt;</B> iperf -c node2 -w 130k
------------------------------------------------------------
Client connecting to node2, TCP port 5001
TCP window size:&nbsp; 129 KByte (WARNING: requested&nbsp; 130 KByte)
------------------------------------------------------------
[&nbsp; 3] local &lt;IP Addr node1&gt; port 2530 connected with &lt;IP Addr node2&gt; port 5001
[ ID] Interval&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Transfer&nbsp;&nbsp;&nbsp;&nbsp; Bandwidth
[&nbsp; 3]&nbsp; 0.0-10.0 sec&nbsp; 19.7 MBytes&nbsp; 15.8 Mbits/sec</PRE></BLOCKQUOTE>Another
test to do is run parallel TCP streams. If the total aggregate bandwidth is more
than what an individual stream gets, something is wrong. Either the TCP window
size is too small, or the OS's TCP implementation has bugs, or the network
itself has deficiencies. See above for TCP window sizes; otherwise diagnosing
which is somewhat difficult. If Iperf is compiled with pthreads, a single client
and server can test this, otherwise setup multiple clients and servers on
different ports. Here's an example where a single stream gets 16.5 Mbit/sec, but
two parallel streams together get 16.7 + 9.4 = 26.1 Mbit/sec, even when using
large TCP window sizes:
<BLOCKQUOTE><PRE><B>node2&gt;</B> iperf -s -w 300k
------------------------------------------------------------
Server listening on TCP port 5001
TCP window size:&nbsp; 300 KByte
------------------------------------------------------------
[&nbsp; 4] local &lt;IP Addr node2&gt; port 5001 connected with &lt;IP Addr node1&gt; port 6902
[ ID] Interval&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Transfer&nbsp;&nbsp;&nbsp;&nbsp; Bandwidth
[&nbsp; 4]&nbsp; 0.0-10.2 sec&nbsp; 20.9 MBytes&nbsp; <B><FONT color=#ff0000>16.5 Mbits/sec
</FONT></B>[&nbsp; 4] local &lt;IP Addr node2&gt; port 5001 connected with &lt;IP Addr node1&gt; port 6911
[&nbsp; 5] local &lt;IP Addr node2&gt; port 5001 connected with &lt;IP Addr node2&gt; port 6912
[ ID] Interval&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Transfer&nbsp;&nbsp;&nbsp;&nbsp; Bandwidth
[&nbsp; 5]&nbsp; 0.0-10.1 sec&nbsp; 21.0 MBytes&nbsp; <B><FONT color=#ff0000>16.7 Mbits/sec
</FONT></B>[&nbsp; 4]&nbsp; 0.0-10.3 sec&nbsp; 12.0 MBytes&nbsp;&nbsp;<B><FONT color=#ff0000> 9.4 Mbits/sec
</FONT>node1&gt;</B> ./iperf -c node2 -w 300k
------------------------------------------------------------
Client connecting to node2, TCP port 5001
TCP window size:&nbsp; 299 KByte (WARNING: requested&nbsp; 300 KByte)
------------------------------------------------------------
[&nbsp; 3] local &lt;IP Addr node2&gt; port 6902 connected with &lt;IP Addr node1&gt; port 5001
[ ID] Interval&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Transfer&nbsp;&nbsp;&nbsp;&nbsp; Bandwidth
[&nbsp; 3]&nbsp; 0.0-10.2 sec&nbsp; 20.9 MBytes&nbsp; 16.4 Mbits/sec
<B>node1&gt;</B> iperf -c node2 -w 300k -P 2
------------------------------------------------------------
Client connecting to node2, TCP port 5001
TCP window size:&nbsp; 299 KByte (WARNING: requested&nbsp; 300 KByte)
------------------------------------------------------------
[&nbsp; 4] local &lt;IP Addr node2&gt; port 6912 connected with &lt;IP Addr node1&gt; port 5001
[&nbsp; 3] local &lt;IP Addr node2&gt; port 6911 connected with &lt;IP Addr node1&gt; port 5001
[ ID] Interval&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Transfer&nbsp;&nbsp;&nbsp;&nbsp; Bandwidth
[&nbsp; 4]&nbsp; 0.0-10.1 sec&nbsp; 21.0 MBytes&nbsp; 16.6 Mbits/sec
[&nbsp; 3]&nbsp; 0.0-10.2 sec&nbsp; 12.0 MBytes&nbsp;&nbsp; 9.4 Mbits/sec</PRE></BLOCKQUOTE>A
secondary tuning issue for TCP is the maximum transmission unit (MTU). To be
most effective, both hosts should support Path MTU Discovery. PSC has a <A
href="http://www.psc.edu/networking/perf_tune.html">list detailing</A> what OSes
support Path MTU Discovery. Hosts without Path MTU Discovery often use 536 as
the MSS, which wastes bandwidth and processing time. Use the -m option to
display what MSS is being used, and see if this matches what you expect. Often
it is around 1460 bytes for ethernet.
<BLOCKQUOTE><PRE><B>node3&gt;</B> iperf -s -m
------------------------------------------------------------
Server listening on TCP port 5001
TCP window size: 60.0 KByte (default)
------------------------------------------------------------
[&nbsp; 4] local &lt;IP Addr node3&gt; port 5001 connected with &lt;IP Addr node4&gt; port 1096
[ ID] Interval&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Transfer&nbsp;&nbsp;&nbsp;&nbsp; Bandwidth
[&nbsp; 4]&nbsp; 0.0- 2.0 sec&nbsp;&nbsp; 1.8 MBytes&nbsp;&nbsp; 6.9 Mbits/sec
[&nbsp; 4] <B><FONT color=#ff0000>MSS size 1448 bytes (MTU 1500 bytes, ethernet)
</FONT></B>[&nbsp; 4] Read lengths occurring in more than 5% of reads:
[&nbsp; 4]&nbsp;&nbsp; 952 bytes read&nbsp;&nbsp; 219 times (16.2%)
[&nbsp; 4]&nbsp; 1448 bytes read&nbsp; 1128 times (83.6%)</PRE></BLOCKQUOTE>Here
is a host that doesn't support Path MTU Discovery. It will only send and receive
small 576 byte packets.
<BLOCKQUOTE><PRE><B>node4&gt;</B> iperf -s -m
------------------------------------------------------------
Server listening on TCP port 5001
TCP window size: 32.0 KByte (default)
------------------------------------------------------------
[&nbsp; 4] local &lt;IP Addr node4&gt; port 5001 connected with &lt;IP Addr node3&gt; port 13914
[ ID] Interval&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Transfer&nbsp;&nbsp;&nbsp;&nbsp; Bandwidth
[&nbsp; 4]&nbsp; 0.0- 2.3 sec&nbsp;&nbsp; 632 KBytes&nbsp;&nbsp; 2.1 Mbits/sec
<B><FONT color=#ff0000>WARNING: Path MTU Discovery may not be enabled.
</FONT></B>[&nbsp; 4] <B><FONT color=#ff0000>MSS size 536 bytes (MTU 576 bytes, minimum)
</FONT></B>[&nbsp; 4] Read lengths occurring in more than 5% of reads:
[&nbsp; 4]&nbsp;&nbsp; 536 bytes read&nbsp;&nbsp; 308 times (58.4%)
[&nbsp; 4]&nbsp; 1072 bytes read&nbsp;&nbsp;&nbsp; 91 times (17.3%)
[&nbsp; 4]&nbsp; 1608 bytes read&nbsp;&nbsp;&nbsp; 29 times (5.5%)</PRE></BLOCKQUOTE>Iperf
supports other tuning options, which were added for exceptional network
situations like HIPPI-to-HIPPI over ATM. <BR>
<HR>
<!-- ----- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- -->
<H2><A name=tuningudp></A>Tuning a UDP connection</H2>
Iperf creates a constant bit rate UDP stream. This is a very artificial
stream, similar to voice communication but not much else.
<P>
You will want to adjust the datagram size (-l) to the size your application
uses.
<P>
The server detects UDP datagram loss by ID numbers in the datagrams. Usually
a UDP datagram becomes several IP packets. Losing a single IP packet will lose
the entire datagram. To measure packet loss instead of datagram loss, make the
datagrams small enough to fit into a single packet, using the -l option. The
default size of 1470 bytes works for ethernet. Out-of-order packets are also
detected. (Out-of-order packets cause some ambiguity in the lost packet count;
Iperf assumes they are not duplicate packets, so they are excluded from the lost
packet count.) Since TCP does not report loss to the user, I find UDP tests
helpful to see packet loss along a path.
<P>
Jitter calculations are continuously computed by the server, as specified by
RTP in RFC 1889. The client records a 64 bit second/microsecond timestamp in the
packet. The server computes the relative transit time as (server's receive time
- client's send time). The client's and server's clocks do not need to be
synchronized; any difference is subtracted out in the jitter calculation. Jitter
is the smoothed mean of differences between consecutive transit times.
<BLOCKQUOTE><PRE><B>node2&gt;</B> iperf -s -u -i 1
------------------------------------------------------------
Server listening on UDP port 5001
Receiving 1470 byte datagrams
UDP buffer size: 60.0 KByte (default)
------------------------------------------------------------
[&nbsp; 4] local &lt;IP Addr node2&gt; port 5001 connected with &lt;IP Addr node1&gt; port 9726
[ ID] Interval&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Transfer&nbsp;&nbsp;&nbsp;&nbsp; Bandwidth&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Jitter&nbsp;&nbsp; Lost/Total Datagrams
[&nbsp; 4]&nbsp; 0.0- 1.0 sec&nbsp;&nbsp; 1.3 MBytes&nbsp; 10.0 Mbits/sec&nbsp; 0.209 ms&nbsp;&nbsp;&nbsp; 1/&nbsp; 894 (0.11%)
[&nbsp; 4]&nbsp; 1.0- 2.0 sec&nbsp;&nbsp; 1.3 MBytes&nbsp; 10.0 Mbits/sec&nbsp; 0.221 ms&nbsp;&nbsp;&nbsp; 0/&nbsp; 892 (0%)
[&nbsp; 4]&nbsp; 2.0- 3.0 sec&nbsp;&nbsp; 1.3 MBytes&nbsp; 10.0 Mbits/sec&nbsp; 0.277 ms&nbsp;&nbsp;&nbsp; 0/&nbsp; 892 (0%)
[&nbsp; 4]&nbsp; 3.0- 4.0 sec&nbsp;&nbsp; 1.3 MBytes&nbsp; 10.0 Mbits/sec&nbsp; 0.359 ms&nbsp;&nbsp;&nbsp; 0/&nbsp; 893 (0%)
[&nbsp; 4]&nbsp; 4.0- 5.0 sec&nbsp;&nbsp; 1.3 MBytes&nbsp; 10.0 Mbits/sec&nbsp; 0.251 ms&nbsp;&nbsp;&nbsp; 0/&nbsp; 892 (0%)
[&nbsp; 4]&nbsp; 5.0- 6.0 sec&nbsp;&nbsp; 1.3 MBytes&nbsp; 10.0 Mbits/sec&nbsp; 0.215 ms&nbsp;&nbsp;&nbsp; 0/&nbsp; 892 (0%)
[&nbsp; 4]&nbsp; 6.0- 7.0 sec&nbsp;&nbsp; 1.3 MBytes&nbsp; 10.0 Mbits/sec&nbsp; 0.325 ms&nbsp;&nbsp;&nbsp; 0/&nbsp; 892 (0%)
[&nbsp; 4]&nbsp; 7.0- 8.0 sec&nbsp;&nbsp; 1.3 MBytes&nbsp; 10.0 Mbits/sec&nbsp; 0.254 ms&nbsp;&nbsp;&nbsp; 0/&nbsp; 892 (0%)
[&nbsp; 4]&nbsp; 8.0- 9.0 sec&nbsp;&nbsp; 1.3 MBytes&nbsp; 10.0 Mbits/sec&nbsp; 0.282 ms&nbsp;&nbsp;&nbsp; 0/&nbsp; 892 (0%)
[&nbsp; 4]&nbsp; 0.0-10.0 sec&nbsp; 12.5 MBytes&nbsp; 10.0 Mbits/sec&nbsp; 0.243 ms&nbsp;&nbsp;&nbsp; 1/ 8922 (0.011%)
<B>node1&gt;</B> iperf -c node2 -u -b 10m
------------------------------------------------------------
Client connecting to node2, UDP port 5001
Sending 1470 byte datagrams
UDP buffer size: 60.0 KByte (default)
------------------------------------------------------------
[&nbsp; 3] local &lt;IP Addr node1&gt; port 9726 connected with &lt;IP Addr node2&gt; port 5001
[ ID] Interval&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Transfer&nbsp;&nbsp;&nbsp;&nbsp; Bandwidth
[&nbsp; 3]&nbsp; 0.0-10.0 sec&nbsp; 12.5 MBytes&nbsp; 10.0 Mbits/sec
[&nbsp; 3] Sent 8922 datagrams</PRE></BLOCKQUOTE>Notice the higher jitter due to
datagram reassembly when using larger 32 KB datagrams, each split into 23
packets of 1500 bytes. The higher datagram loss seen here may be due to the
burstiness of the traffic, which is 23 back-to-back packets and then a long
pause, rather than evenly spaced individual packets.
<BLOCKQUOTE><PRE><B>node2&gt;</B> iperf -s -u -l 32k -w 128k -i 1
------------------------------------------------------------
Server listening on UDP port 5001
Receiving 32768 byte datagrams
UDP buffer size:&nbsp; 128 KByte
------------------------------------------------------------
[&nbsp; 3] local &lt;IP Addr node2&gt; port 5001 connected with &lt;IP Addr node1&gt; port 11303
[ ID] Interval&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Transfer&nbsp;&nbsp;&nbsp;&nbsp; Bandwidth&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Jitter&nbsp;&nbsp; Lost/Total Datagrams
[&nbsp; 3]&nbsp; 0.0- 1.0 sec&nbsp;&nbsp; 1.3 MBytes&nbsp; 10.0 Mbits/sec&nbsp; 0.430 ms&nbsp;&nbsp;&nbsp; 0/&nbsp;&nbsp; 41 (0%)
[&nbsp; 3]&nbsp; 1.0- 2.0 sec&nbsp;&nbsp; 1.1 MBytes&nbsp;&nbsp; 8.5 Mbits/sec&nbsp; 5.996 ms&nbsp;&nbsp;&nbsp; 6/&nbsp;&nbsp; 40 (15%)
[&nbsp; 3]&nbsp; 2.0- 3.0 sec&nbsp;&nbsp; 1.2 MBytes&nbsp;&nbsp; 9.7 Mbits/sec&nbsp; 0.796 ms&nbsp;&nbsp;&nbsp; 1/&nbsp;&nbsp; 40 (2.5%)
[&nbsp; 3]&nbsp; 3.0- 4.0 sec&nbsp;&nbsp; 1.2 MBytes&nbsp; 10.0 Mbits/sec&nbsp; 0.403 ms&nbsp;&nbsp;&nbsp; 0/&nbsp;&nbsp; 40 (0%)
[&nbsp; 3]&nbsp; 4.0- 5.0 sec&nbsp;&nbsp; 1.2 MBytes&nbsp; 10.0 Mbits/sec&nbsp; 0.448 ms&nbsp;&nbsp;&nbsp; 0/&nbsp;&nbsp; 40 (0%)
[&nbsp; 3]&nbsp; 5.0- 6.0 sec&nbsp;&nbsp; 1.2 MBytes&nbsp; 10.0 Mbits/sec&nbsp; 0.464 ms&nbsp;&nbsp;&nbsp; 0/&nbsp;&nbsp; 40 (0%)
[&nbsp; 3]&nbsp; 6.0- 7.0 sec&nbsp;&nbsp; 1.2 MBytes&nbsp; 10.0 Mbits/sec&nbsp; 0.442 ms&nbsp;&nbsp;&nbsp; 0/&nbsp;&nbsp; 40 (0%)
[&nbsp; 3]&nbsp; 7.0- 8.0 sec&nbsp;&nbsp; 1.2 MBytes&nbsp; 10.0 Mbits/sec&nbsp; 0.342 ms&nbsp;&nbsp;&nbsp; 0/&nbsp;&nbsp; 40 (0%)
[&nbsp; 3]&nbsp; 8.0- 9.0 sec&nbsp;&nbsp; 1.2 MBytes&nbsp; 10.0 Mbits/sec&nbsp; 0.431 ms&nbsp;&nbsp;&nbsp; 0/&nbsp;&nbsp; 40 (0%)
[&nbsp; 3]&nbsp; 9.0-10.0 sec&nbsp;&nbsp; 1.2 MBytes&nbsp; 10.0 Mbits/sec&nbsp; 0.407 ms&nbsp;&nbsp;&nbsp; 0/&nbsp;&nbsp; 40 (0%)
[&nbsp; 3]&nbsp; 0.0-10.0 sec&nbsp; 12.3 MBytes&nbsp;&nbsp; 9.8 Mbits/sec&nbsp; 0.407 ms&nbsp;&nbsp;&nbsp; 7/&nbsp; 401 (1.7%)
<B>node1&gt;</B> iperf -c node2 -b 10m -l 32k -w 128k
------------------------------------------------------------
Client connecting to node2, UDP port 5001
Sending 32768 byte datagrams
UDP buffer size:&nbsp; 128 KByte
------------------------------------------------------------
[&nbsp; 3] local &lt;IP Addr node2&gt; port 11303 connected with &lt;IP Addr node1&gt; port 5001
[ ID] Interval&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Transfer&nbsp;&nbsp;&nbsp;&nbsp; Bandwidth
[&nbsp; 3]&nbsp; 0.0-10.0 sec&nbsp; 12.5 MBytes&nbsp; 10.0 Mbits/sec
[&nbsp; 3] Sent 401 datagrams</PRE><PRE></PRE></BLOCKQUOTE>
<P><A name=multicast></A>
<B><FONT size=+1>Multicast</FONT></B>
<P>To test multicast, run several servers with the bind option (-B, --bind) set
to the multicast group address. Run the client, connecting to the multicast
group address and setting the TTL (-T, --ttl) as needed. Unlike normal TCP and
UDP tests, multicast servers may be started after the client. In that case,
datagrams sent before the server started show up as losses in the first periodic
report (61 datagrams on arno below).
<BLOCKQUOTE><PRE><B>node5&gt;</B> iperf -c 224.0.67.67 -u --ttl 5 -t 5
------------------------------------------------------------
Client connecting to 224.0.67.67, UDP port 5001
Sending 1470 byte datagrams
Setting multicast TTL to 5
UDP buffer size: 32.0 KByte (default)
------------------------------------------------------------
[&nbsp; 3] local &lt;IP Addr node5&gt; port 1025 connected with 224.0.67.67 port 5001
[ ID] Interval&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Transfer&nbsp;&nbsp;&nbsp;&nbsp; Bandwidth
[&nbsp; 3]&nbsp; 0.0- 5.0 sec&nbsp;&nbsp; 642 KBytes&nbsp;&nbsp; 1.0 Mbits/sec
[&nbsp; 3] Sent 447 datagrams
<B>node5&gt;</B> iperf -s -u -B 224.0.67.67 -i 1
------------------------------------------------------------
Server listening on UDP port 5001
Binding to local address 224.0.67.67
Joining multicast group&nbsp; 224.0.67.67
Receiving 1470 byte datagrams
UDP buffer size: 32.0 KByte (default)
------------------------------------------------------------
[&nbsp; 3] local 224.0.67.67 port 5001 connected with &lt;IP Addr node5&gt; port 1025
[ ID] Interval&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Transfer&nbsp;&nbsp;&nbsp;&nbsp; Bandwidth&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Jitter&nbsp;&nbsp; Lost/Total Datagrams
[&nbsp; 3]&nbsp; 0.0- 1.0 sec&nbsp;&nbsp; 131 KBytes&nbsp;&nbsp; 1.0 Mbits/sec&nbsp; 0.007 ms&nbsp;&nbsp;&nbsp; 0/&nbsp;&nbsp; 91 (0%)
[&nbsp; 3]&nbsp; 1.0- 2.0 sec&nbsp;&nbsp; 128 KBytes&nbsp;&nbsp; 1.0 Mbits/sec&nbsp; 0.008 ms&nbsp;&nbsp;&nbsp; 0/&nbsp;&nbsp; 89 (0%)
[&nbsp; 3]&nbsp; 2.0- 3.0 sec&nbsp;&nbsp; 128 KBytes&nbsp;&nbsp; 1.0 Mbits/sec&nbsp; 0.010 ms&nbsp;&nbsp;&nbsp; 0/&nbsp;&nbsp; 89 (0%)
[&nbsp; 3]&nbsp; 3.0- 4.0 sec&nbsp;&nbsp; 128 KBytes&nbsp;&nbsp; 1.0 Mbits/sec&nbsp; 0.013 ms&nbsp;&nbsp;&nbsp; 0/&nbsp;&nbsp; 89 (0%)
[&nbsp; 3]&nbsp; 4.0- 5.0 sec&nbsp;&nbsp; 128 KBytes&nbsp;&nbsp; 1.0 Mbits/sec&nbsp; 0.008 ms&nbsp;&nbsp;&nbsp; 0/&nbsp;&nbsp; 89 (0%)
[&nbsp; 3]&nbsp; 0.0- 5.0 sec&nbsp;&nbsp; 642 KBytes&nbsp;&nbsp; 1.0 Mbits/sec&nbsp; 0.008 ms&nbsp;&nbsp;&nbsp; 0/&nbsp; 447 (0%)
<B>node6&gt;</B> iperf -s -u -B 224.0.67.67 -i 1
------------------------------------------------------------
Server listening on UDP port 5001
Binding to local address 224.0.67.67
Joining multicast group&nbsp; 224.0.67.67
Receiving 1470 byte datagrams
UDP buffer size: 60.0 KByte (default)
------------------------------------------------------------
[&nbsp; 3] local 224.0.67.67 port 5001 connected with &lt;IP Addr node5&gt; port 1025
[ ID] Interval&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Transfer&nbsp;&nbsp;&nbsp;&nbsp; Bandwidth&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Jitter&nbsp;&nbsp; Lost/Total Datagrams
[&nbsp; 3]&nbsp; 0.0- 1.0 sec&nbsp;&nbsp; 129 KBytes&nbsp;&nbsp; 1.0 Mbits/sec&nbsp; 0.778 ms&nbsp;&nbsp; 61/&nbsp; 151 (40%)
[&nbsp; 3]&nbsp; 1.0- 2.0 sec&nbsp;&nbsp; 128 KBytes&nbsp;&nbsp; 1.0 Mbits/sec&nbsp; 0.236 ms&nbsp;&nbsp;&nbsp; 0/&nbsp;&nbsp; 89 (0%)
[&nbsp; 3]&nbsp; 2.0- 3.0 sec&nbsp;&nbsp; 128 KBytes&nbsp;&nbsp; 1.0 Mbits/sec&nbsp; 0.264 ms&nbsp;&nbsp;&nbsp; 0/&nbsp;&nbsp; 89 (0%)
[&nbsp; 3]&nbsp; 3.0- 4.0 sec&nbsp;&nbsp; 128 KBytes&nbsp;&nbsp; 1.0 Mbits/sec&nbsp; 0.248 ms&nbsp;&nbsp;&nbsp; 0/&nbsp;&nbsp; 89 (0%)
[&nbsp; 3]&nbsp; 0.0- 4.3 sec&nbsp;&nbsp; 554 KBytes&nbsp;&nbsp; 1.0 Mbits/sec&nbsp; 0.298 ms&nbsp;&nbsp; 61/&nbsp; 447 (14%)</PRE><PRE><HR width="100%"></PRE></BLOCKQUOTE>
<P><A name=ipv6></A>
<DL>
<DT><B><FONT size=+2>IPv6 Mode</FONT></B>
<DD>Download the IPv6 version of this release.<BR>Get the IPv6 address of the node using the 'ifconfig' command.<BR>Use the <FONT color=#000099>-V</FONT> option to indicate that you are using an IPv6 address Please note that we need to explicitly bind the server address also.
<P>Server side:<BR><FONT color=#000099> $ iperf -s -V</FONT>
<P>Client side:<BR><FONT color=#000099>$ iperf -c &lt;Server IPv6 Address&gt; -V </FONT>
<P>Note: Iperf version 1.6.2 and eariler require a IPv6 address to be explicitly bound
with the <A HREF="#bind">-B</A> option for the server.</P></DD></DL>
<HR>
<P><A name=repmode></A>
<DL>
<DT><B><FONT size=+2>Using Representative Streams to measure
bandwidth</FONT></B>
<DD>Use the -F or -I option. If you want to test how your network performs
with compressed / uncompressed streams, just create representative streams and
use the -F option to test it. This is usually due to the link layer
compressing data.
<P>The -F option is for file input.<BR>The -I option is for input from stdin.
<P>E.g. <BR>Client: $ <FONT color=#000099> iperf -c &lt;server address&gt; -F &lt;file-name&gt;<BR></FONT>
<BR>Client: $ <FONT color=#000099> iperf -c &lt;server address&gt; -I </FONT></P></DD></DL>
<P><A name=daemon></A>
<HR>
<DL>
<DT><B><FONT size=+2>Running the server as a daemon</FONT></B>
<DD>Use the -D command line option to run the server as a daemon. Redirect the
output to a file.<BR>E.g. <FONT color=#000099>iperf -s -D &gt;
iperfLog</FONT>. <FONT color=#000000>This will have the Iperf Server running
as a daemon and the server messages will be logged in the file iperfLog.
</DD></DL>
<HR>
<P><A name=service></A>
<DL>
<DT><B><FONT size=+2>Using Iperf as a Service under Win32</FONT></B>
<DD>There are three options for Win32:
<P>
<DL>
<DT>-o outputfilename
<DD>output the messages into the specified file
<DT>-s -D
<DD>install Iperf as a service and run it
<DT>-s -R
<DD>uninstall the Iperf service </DD></DL>
<P>Examples:
<DL>
<DT><FONT color=#3366ff>iperf -s -D -o iperflog.txt</FONT>
<DD>will install the Iperf service and run it. Messages will be reported
into "%windir%\system32\iperflog.txt"
<P></P>
<DT><FONT color=#3366ff>iperf -s -R</FONT>
<DD>will uninstall the Iperf service if it is installed.
<P>Note: If you stop want to restart the Iperf service after having killed
it with the Microsoft Management Console or the Windows Task Manager, make
sure to use the proper OPTION in the service properties dialog.
</P></DD></DL></DD></DL>
<HR>
<!--<P><A name=multicast></A>
<DL>
<DT><B><FONT size=+2>Running the multicast server and client</FONT></B>
<DD>Use the -B option while starting the server to bind it to a multicast
address.<BR>E.g. :-<FONT color=#3366ff>iperf -s -u -B 224.0.55.55</FONT>.
<P>This will have the Iperf server listening for datagrams (-u) for the
address 224.0.55.55(-B 224.0.55.55).
<P>Now, start a client sending packets to this multicast address.
<P>E.g. : <FONT color=#3366ff>iperf -c 224.0.55.55 -u</FONT>.
This will have a UDP client (-u) sending to the multicast address
224.0.55.55(-c 224.0.55.55).
<P><FONT color=#000000>Start multiple clients or servers as explained above,
sending data to the same multicast server. (If you have multiple servers
listening on the multicast address, each of the servers will be getting the data)
</P></DD></DL>
<HR>-->
<!--<A name=adaptive></A>
<DL>
<DT><B><FONT size=+2>Adaptive window sizes</FONT></B>
<DD>Use the -W option on the client to run the client with the adaptive window
size. Ensure that the server window size is fairly big for this
option.<BR>E.g.. If the server TCP window size is 8KB, it does not help having
a client TCP window size of 256KB.<BR>256KB Server TCP Window Size should
suffice for most high bandwidth networks.
<P>Client changes the TCP window size using a binary exponential
algorithm. This means that you may notice that TCP window size suggested may
vary according to the traffic in the network, Iperf will suggest the best
window size for the current network scenario.
</DL>
<HR width="100%">
--><P><!-- ----- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- -->
<CENTER>
<P>Copyright 1999,2000,2001,2002,2003,2004 <BR>The Board of Trustees of the University of
Illinois <BR>All rights reserved <BR>See <A
href="ui_license.html">UI License</A> for
complete details.</CENTER>
</BODY>
</HTML>

89
doc/ui_license.html Normal file
View File

@ -0,0 +1,89 @@
<HTML>
<HEAD>
<TITLE>Iperf Copyright</TITLE>
<!-- $Id: ui_license.html,v 1.1.1.1 2004/05/18 01:50:44 kgibbs Exp $ -->
</HEAD>
<BODY BGCOLOR="#FFFFFF" LINK="#006633" VLINK="#669900" ALINK="#669966">
<CENTER>
<P><IMG SRC="dast.gif"
ALT="Distributed Applications Support Team"></P>
</CENTER>
<H1 ALIGN=CENTER>Iperf Copyright</H1>
<HR><!-- ----- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- -->
<CENTER>
Copyright (c) 1999,2000,2001,2002,2003,2004 The Board of Trustees of the University of Illinois<br>
All Rights Reserved.
<P>
<a href="http://dast.nlanr.net/Projects/Iperf">Iperf performance test</a><BR>
Mark Gates<BR>
Ajay Tirumala<br>
Jim Ferguson<br>
Jon Dugan<br>
Feng Qin<br>
Kevin Gibbs<BR>
National Laboratory for Applied Network Research <BR>
National Center for Supercomputing Applications <BR>
University of Illinois at Urbana-Champaign <BR>
<a href="http://www.ncsa.uiuc.edu">http://www.ncsa.uiuc.edu</a>
</center>
<P>
Permission is hereby granted, free of charge, to any person obtaining a copy of this software (Iperf)
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:
<p>
<ul>
<li>Redistributions of source code must retain the above copyright notice, this list of
conditions and the following disclaimers.
<p>
<li>Redistributions in binary form must reproduce the above copyright notice, this list
of conditions and the following disclaimers in the documentation and/or other
materials provided with the distribution.
<p>
<li>Neither the names of the University of Illinois, NCSA, nor the names of its
contributors may be used to endorse or promote products derived from this
Software without specific prior written permission.
</ul>
<p>
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 CONTIBUTORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
USE OR OTHER DEALINGS IN THE SOFTWARE.
</pre>
<HR><!-- ----- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- -->
<CENTER>
<P><FONT FACE="helvetica,arial" SIZE="2">
<A HREF="mailto:dast@nlanr.net">dast@nlanr.net</A>
Last modified: Jan 5, 2004<br>
<A HREF="http://www.nlanr.net">NLANR</a> ||
<A HREF="http://dast.nlanr.net">applications support</a> ||
<A HREF="http://ncne.nlanr.net">engineering support</a> ||
<A HREF="http://moat.nlanr.net">measurement and operations</a>
</FONT></P>
</CENTER>
</BODY>
</HTML>

90
include/Client.hpp Normal file
View File

@ -0,0 +1,90 @@
/*---------------------------------------------------------------
* Copyright (c) 1999,2000,2001,2002,2003
* The Board of Trustees of the University of Illinois
* All Rights Reserved.
*---------------------------------------------------------------
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software (Iperf) 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:
*
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and
* the following disclaimers.
*
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimers in the documentation and/or other materials
* provided with the distribution.
*
*
* Neither the names of the University of Illinois, NCSA,
* nor the names of its contributors may be used to endorse
* or promote products derived from this Software without
* specific prior written permission.
*
* 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 CONTIBUTORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* ________________________________________________________________
* National Laboratory for Applied Network Research
* National Center for Supercomputing Applications
* University of Illinois at Urbana-Champaign
* http://www.ncsa.uiuc.edu
* ________________________________________________________________
* Client.hpp
* by Mark Gates <mgates@nlanr.net>
* -------------------------------------------------------------------
* A client thread initiates a connect to the server and handles
* sending and receiving data, then closes the socket.
* -------------------------------------------------------------------
*/
#ifndef CLIENT_H
#define CLIENT_H
#include "Settings.hpp"
#include "Timestamp.hpp"
/* ------------------------------------------------------------------- */
class Client {
public:
// stores server hostname, port, UDP/TCP mode, and UDP rate
Client( thread_Settings *inSettings );
// destroy the client object
~Client();
// connects and sends data
void Run( void );
void InitiateServer();
// UDP / TCP
void Send( void );
void write_UDP_FIN( );
// client connect
void Connect( );
protected:
thread_Settings *mSettings;
char* mBuf;
Timestamp mEndTime;
Timestamp lastPacketTime;
}; // end class Client
#endif // CLIENT_H

169
include/Condition.h Normal file
View File

@ -0,0 +1,169 @@
/*---------------------------------------------------------------
* Copyright (c) 1999,2000,2001,2002,2003
* The Board of Trustees of the University of Illinois
* All Rights Reserved.
*---------------------------------------------------------------
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software (Iperf) 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:
*
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and
* the following disclaimers.
*
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimers in the documentation and/or other materials
* provided with the distribution.
*
*
* Neither the names of the University of Illinois, NCSA,
* nor the names of its contributors may be used to endorse
* or promote products derived from this Software without
* specific prior written permission.
*
* 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 CONTIBUTORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* ________________________________________________________________
* National Laboratory for Applied Network Research
* National Center for Supercomputing Applications
* University of Illinois at Urbana-Champaign
* http://www.ncsa.uiuc.edu
* ________________________________________________________________
*
* Condition.h
* by Mark Gates <mgates@nlanr.net>
* -------------------------------------------------------------------
* An abstract class for waiting on a condition variable. If
* threads are not available, this does nothing.
* ------------------------------------------------------------------- */
#ifndef CONDITION_H
#define CONDITION_H
#include "headers.h"
#include "Mutex.h"
#include "util.h"
#if defined( HAVE_POSIX_THREAD )
typedef struct Condition {
pthread_cond_t mCondition;
pthread_mutex_t mMutex;
} Condition;
#elif defined( HAVE_WIN32_THREAD )
typedef struct Condition {
HANDLE mCondition;
HANDLE mMutex;
} Condition;
#else
typedef struct Condition {
int mCondition;
int mMutex;
} Condition;
#endif
#define Condition_Lock( Cond ) Mutex_Lock( &Cond.mMutex )
#define Condition_Unlock( Cond ) Mutex_Unlock( &Cond.mMutex )
// initialize condition
#if defined( HAVE_POSIX_THREAD )
#define Condition_Initialize( Cond ) do { \
Mutex_Initialize( &(Cond)->mMutex ); \
pthread_cond_init( &(Cond)->mCondition, NULL ); \
} while ( 0 )
#elif defined( HAVE_WIN32_THREAD )
// set all conditions to be broadcast
// unfortunately in Win32 you have to know at creation
// whether the signal is broadcast or not.
#define Condition_Initialize( Cond ) do { \
Mutex_Initialize( &(Cond)->mMutex ); \
(Cond)->mCondition = CreateEvent( NULL, true, false, NULL ); \
} while ( 0 )
#else
#define Condition_Initialize( Cond )
#endif
// destroy condition
#if defined( HAVE_POSIX_THREAD )
#define Condition_Destroy( Cond ) do { \
pthread_cond_destroy( &(Cond)->mCondition ); \
Mutex_Destroy( &(Cond)->mMutex ); \
} while ( 0 )
#elif defined( HAVE_WIN32_THREAD )
#define Condition_Destroy( Cond ) do { \
CloseHandle( (Cond)->mCondition ); \
Mutex_Destroy( &(Cond)->mMutex ); \
} while ( 0 )
#else
#define Condition_Destroy( Cond )
#endif
// sleep this thread, waiting for condition signal
#if defined( HAVE_POSIX_THREAD )
#define Condition_Wait( Cond ) pthread_cond_wait( &(Cond)->mCondition, &(Cond)->mMutex )
#elif defined( HAVE_WIN32_THREAD )
// atomically release mutex and wait on condition,
// then re-acquire the mutex
#define Condition_Wait( Cond ) do { \
SignalObjectAndWait( (Cond)->mMutex, (Cond)->mCondition, INFINITE, false ); \
Mutex_Lock( &(Cond)->mMutex ); \
} while ( 0 )
#else
#define Condition_Wait( Cond )
#endif
// sleep this thread, waiting for condition signal,
// but bound sleep time by the relative time inSeconds.
#if defined( HAVE_POSIX_THREAD )
#define Condition_TimedWait( Cond, inSeconds ) do { \
struct timespec absTimeout; \
absTimeout.tv_sec = time( NULL ) + inSeconds; \
absTimeout.tv_nsec = 0; \
pthread_cond_timedwait( &(Cond)->mCondition, &(Cond)->mMutex, &absTimeout ); \
} while ( 0 )
#elif defined( HAVE_WIN32_THREAD )
// atomically release mutex and wait on condition,
// then re-acquire the mutex
#define Condition_TimedWait( Cond, inSeconds ) do { \
SignalObjectAndWait( (Cond)->mMutex, (Cond)->mCondition, inSeconds*1000, false ); \
Mutex_Lock( &(Cond)->mMutex ); \
} while ( 0 )
#else
#define Condition_TimedWait( Cond, inSeconds )
#endif
// send a condition signal to wake one thread waiting on condition
// in Win32, this actually wakes up all threads, same as Broadcast
// use PulseEvent to auto-reset the signal after waking all threads
#if defined( HAVE_POSIX_THREAD )
#define Condition_Signal( Cond ) pthread_cond_signal( &(Cond)->mCondition )
#elif defined( HAVE_WIN32_THREAD )
#define Condition_Signal( Cond ) PulseEvent( (Cond)->mCondition )
#else
#define Condition_Signal( Cond )
#endif
// send a condition signal to wake all threads waiting on condition
#if defined( HAVE_POSIX_THREAD )
#define Condition_Broadcast( Cond ) pthread_cond_broadcast( &(Cond)->mCondition )
#elif defined( HAVE_WIN32_THREAD )
#define Condition_Broadcast( Cond ) PulseEvent( (Cond)->mCondition )
#else
#define Condition_Broadcast( Cond )
#endif
#endif // CONDITION_H

123
include/Extractor.h Normal file
View File

@ -0,0 +1,123 @@
/*---------------------------------------------------------------
* Copyright (c) 1999,2000,2001,2002,2003
* The Board of Trustees of the University of Illinois
* All Rights Reserved.
*---------------------------------------------------------------
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software (Iperf) 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:
*
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and
* the following disclaimers.
*
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimers in the documentation and/or other materials
* provided with the distribution.
*
*
* Neither the names of the University of Illinois, NCSA,
* nor the names of its contributors may be used to endorse
* or promote products derived from this Software without
* specific prior written permission.
*
* 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 CONTIBUTORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* ________________________________________________________________
* National Laboratory for Applied Network Research
* National Center for Supercomputing Applications
* University of Illinois at Urbana-Champaign
* http://www.ncsa.uiuc.edu
* ________________________________________________________________
*
* Extractor.h
* by Ajay Tirumala (tirumala@ncsa.uiuc.edu)
* -------------------------------------------------------------------
* Extract data from a file, used to measure the transfer rates
* for various stream formats.
*
* E.g. Use a gzipped file to measure the transfer rates for
* compressed data
* Use an MPEG file to measure the transfer rates of
* Multimedia data formats
* Use a plain BMP file to measure the transfer rates of
* Uncompressed data
*
* This is beneficial especially in measuring bandwidth across WAN
* links where data compression takes place before data transmission
* ------------------------------------------------------------------- */
#ifndef _EXTRACTOR_H
#define _EXTRACTOR_H
#include <stdlib.h>
#include <stdio.h>
#include "Settings.hpp"
#ifdef __cplusplus
extern "C" {
#endif
/**
* Constructor
* @arg fileName Name of the file
* @arg size Block size for reading
*/
void Extractor_Initialize( char *fileName, int size, thread_Settings *mSettings );
/**
* Constructor
* @arg fp File Pointer
* @arg size Block size for reading
*/
void Extractor_InitializeFile( FILE *fp, int size, thread_Settings *mSettings );
/*
* Fetches the next data block from
* the file
* @arg block Pointer to the data read
* @return Number of bytes read
*/
int Extractor_getNextDataBlock( char *block, thread_Settings *mSettings );
/**
* Function which determines whether
* the file stream is still readable
* @return true, if readable; false, if not
*/
int Extractor_canRead( thread_Settings *mSettings );
/**
* This is used to reduce the read size
* Used in UDP transfer to accomodate the
* the header (timestamp)
* @arg delta Size to reduce
*/
void Extractor_reduceReadSize( int delta, thread_Settings *mSettings );
/**
* Destructor
*/
void Extractor_Destroy( thread_Settings *mSettings );
#ifdef __cplusplus
} /* end extern "C" */
#endif
#endif

96
include/List.h Normal file
View File

@ -0,0 +1,96 @@
/*---------------------------------------------------------------
* Copyright (c) 1999,2000,2001,2002,2003
* The Board of Trustees of the University of Illinois
* All Rights Reserved.
*---------------------------------------------------------------
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software (Iperf) 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:
*
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and
* the following disclaimers.
*
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimers in the documentation and/or other materials
* provided with the distribution.
*
*
* Neither the names of the University of Illinois, NCSA,
* nor the names of its contributors may be used to endorse
* or promote products derived from this Software without
* specific prior written permission.
*
* 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 CONTIBUTORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* ________________________________________________________________
* National Laboratory for Applied Network Research
* National Center for Supercomputing Applications
* University of Illinois at Urbana-Champaign
* http://www.ncsa.uiuc.edu
* ________________________________________________________________
*
* List.h
* by Kevin Gibbs <kgibbs@ncsa.uiuc.edu>
* -------------------------------------------------------------------
*/
#ifndef Iperf_LIST_H
#define Iperf_LIST_H
#include "headers.h"
#include "Settings.hpp"
#include "Reporter.h"
#include "Mutex.h"
/*
* List handling utilities to replace STD vector
*/
struct Iperf_ListEntry;
/*
* A List entry that consists of a sockaddr
* a pointer to the Audience that sockaddr is
* associated with and a pointer to the next
* entry
*/
struct Iperf_ListEntry {
iperf_sockaddr data;
MultiHeader *holder;
thread_Settings *server;
Iperf_ListEntry *next;
};
extern Mutex clients_mutex;
extern Iperf_ListEntry *clients;
/*
* Functions to modify or search the List
*/
void Iperf_pushback ( Iperf_ListEntry *add, Iperf_ListEntry **root );
void Iperf_delete ( iperf_sockaddr *del, Iperf_ListEntry **root );
void Iperf_destroy ( Iperf_ListEntry **root );
Iperf_ListEntry* Iperf_present ( iperf_sockaddr *find, Iperf_ListEntry *root );
Iperf_ListEntry* Iperf_hostpresent ( iperf_sockaddr *find, Iperf_ListEntry *root );
#endif

95
include/Listener.hpp Normal file
View File

@ -0,0 +1,95 @@
/*---------------------------------------------------------------
* Copyright (c) 1999,2000,2001,2002,2003
* The Board of Trustees of the University of Illinois
* All Rights Reserved.
*---------------------------------------------------------------
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software (Iperf) 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:
*
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and
* the following disclaimers.
*
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimers in the documentation and/or other materials
* provided with the distribution.
*
*
* Neither the names of the University of Illinois, NCSA,
* nor the names of its contributors may be used to endorse
* or promote products derived from this Software without
* specific prior written permission.
*
* 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 CONTIBUTORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* ________________________________________________________________
* National Laboratory for Applied Network Research
* National Center for Supercomputing Applications
* University of Illinois at Urbana-Champaign
* http://www.ncsa.uiuc.edu
* ________________________________________________________________
*
* Listener.hpp
* by Mark Gates <mgates@nlanr.net>
* -------------------------------------------------------------------
* Listener sets up a socket listening on the server host. For each
* connected socket that accept() returns, this creates a Server
* socket and spawns a thread for it.
* ------------------------------------------------------------------- */
#ifndef LISTENER_H
#define LISTENER_H
#include "Thread.h"
#include "Settings.hpp"
class Listener;
class Listener {
public:
// stores server port and TCP/UDP mode
Listener( thread_Settings *inSettings );
// destroy the server object
~Listener();
// accepts connections and starts Servers
void Run( void );
// Starts the Servers as a daemon
void runAsDaemon( const char *, int );
void Listen( );
void McastJoin( );
void McastSetTTL( int val );
void Accept( thread_Settings *server );
void UDPSingleServer ();
protected:
int mClients;
char* mBuf;
thread_Settings *mSettings;
thread_Settings *server;
}; // end class Listener
#endif // LISTENER_H

200
include/Locale.h Normal file
View File

@ -0,0 +1,200 @@
/*---------------------------------------------------------------
* Copyright (c) 1999,2000,2001,2002,2003
* The Board of Trustees of the University of Illinois
* All Rights Reserved.
*---------------------------------------------------------------
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software (Iperf) 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:
*
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and
* the following disclaimers.
*
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimers in the documentation and/or other materials
* provided with the distribution.
*
*
* Neither the names of the University of Illinois, NCSA,
* nor the names of its contributors may be used to endorse
* or promote products derived from this Software without
* specific prior written permission.
*
* 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 CONTIBUTORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* ________________________________________________________________
* National Laboratory for Applied Network Research
* National Center for Supercomputing Applications
* University of Illinois at Urbana-Champaign
* http://www.ncsa.uiuc.edu
* ________________________________________________________________
*
* Locale.h
* by Ajay Tirumala <tirumala@ncsa.uiuc.edu>
* & Mark Gates <mgates@nlanr.net>
* -------------------------------------------------------------------
* Strings and other stuff that is locale specific.
* ------------------------------------------------------------------- */
#ifndef LOCALE_H
#define LOCALE_H
#ifdef __cplusplus
extern "C" {
#endif
/* -------------------------------------------------------------------
* usage
* ------------------------------------------------------------------- */
extern const char usage_short[];
#ifdef WIN32
extern const char usage_long1[];
extern const char usage_long2[];
#else
extern const char usage_long[];
#endif
extern const char version[];
/* -------------------------------------------------------------------
* settings
* ------------------------------------------------------------------- */
extern const char seperator_line[];
extern const char server_port[];
extern const char client_port[];
extern const char bind_address[];
extern const char multicast_ttl[];
extern const char join_multicast[];
extern const char client_datagram_size[];
extern const char server_datagram_size[];
extern const char tcp_window_size[];
extern const char udp_buffer_size[];
extern const char window_default[];
extern const char wait_server_threads[];
/* -------------------------------------------------------------------
* reports
* ------------------------------------------------------------------- */
extern const char report_read_lengths[];
extern const char report_read_length_times[];
extern const char report_bw_header[];
extern const char report_bw_format[];
extern const char report_sum_bw_format[];
extern const char report_bw_jitter_loss_header[];
extern const char report_bw_jitter_loss_format[];
extern const char report_sum_bw_jitter_loss_format[];
extern const char report_outoforder[];
extern const char report_sum_outoforder[];
extern const char report_peer[];
extern const char report_mss_unsupported[];
extern const char report_mss[];
extern const char report_datagrams[];
extern const char report_sum_datagrams[];
extern const char server_reporting[];
extern const char reportCSV_peer[];
extern const char reportCSV_bw_format[];
extern const char reportCSV_bw_jitter_loss_format[];
/* -------------------------------------------------------------------
* warnings
* ------------------------------------------------------------------- */
extern const char warn_window_requested[];
extern const char warn_window_small[];
extern const char warn_delay_large[];
extern const char warn_no_pathmtu[];
extern const char warn_no_ack[];
extern const char warn_ack_failed[];
extern const char warn_fileopen_failed[];
extern const char unable_to_change_win[];
extern const char opt_estimate[];
extern const char report_interval_small[];
extern const char warn_invalid_server_option[];
extern const char warn_invalid_client_option[];
extern const char warn_invalid_compatibility_option[];
extern const char warn_implied_udp[];
extern const char warn_implied_compatibility[];
extern const char warn_buffer_too_small[];
extern const char warn_invalid_single_threaded[];
extern const char warn_invalid_report_style[];
extern const char warn_invalid_report[];
#ifdef __cplusplus
} /* end extern "C" */
#endif
#endif // LOCALE_H

1
include/Makefile.am Normal file
View File

@ -0,0 +1 @@
EXTRA_DIST = Client.hpp Condition.h Extractor.h List.h Listener.hpp Locale.h Makefile.am Mutex.h PerfSocket.hpp Reporter.h Server.hpp Settings.hpp SocketAddr.h Thread.h Timestamp.hpp config.win32.h delay.hpp gettimeofday.h gnu_getopt.h headers.h inet_aton.h report_CSV.h report_default.h service.h snprintf.h util.h version.h

294
include/Makefile.in Normal file
View File

@ -0,0 +1,294 @@
# Makefile.in generated by automake 1.8.3 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
# 2003, 2004 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
top_builddir = ..
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
INSTALL = @INSTALL@
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
host_triplet = @host@
subdir = include
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/dast.m4 \
$(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(mkdir_p)
CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
SOURCES =
DIST_SOURCES =
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMDEP_FALSE = @AMDEP_FALSE@
AMDEP_TRUE = @AMDEP_TRUE@
AMTAR = @AMTAR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CXX = @CXX@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
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@
OBJEXT = @OBJEXT@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
RANLIB = @RANLIB@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
STRIP_BEGIN = @STRIP_BEGIN@
STRIP_DUMMY = @STRIP_DUMMY@
STRIP_END = @STRIP_END@
VERSION = @VERSION@
WEB100_CFLAGS = @WEB100_CFLAGS@
WEB100_CONFIG = @WEB100_CONFIG@
WEB100_LIBS = @WEB100_LIBS@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
ac_ct_RANLIB = @ac_ct_RANLIB@
ac_ct_STRIP = @ac_ct_STRIP@
am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
datadir = @datadir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localstatedir = @localstatedir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
prefix = @prefix@
program_transform_name = @program_transform_name@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
EXTRA_DIST = Client.hpp Condition.h Extractor.h List.h Listener.hpp Locale.h Makefile.am Mutex.h PerfSocket.hpp Reporter.h Server.hpp Settings.hpp SocketAddr.h Thread.h Timestamp.hpp config.win32.h delay.hpp gettimeofday.h gnu_getopt.h headers.h inet_aton.h report_CSV.h report_default.h service.h snprintf.h util.h version.h
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 \
&& exit 0; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign include/Makefile'; \
cd $(top_srcdir) && \
$(AUTOMAKE) --foreign include/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
uninstall-info-am:
tags: TAGS
TAGS:
ctags: CTAGS
CTAGS:
distdir: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
list='$(DISTFILES)'; for file in $$list; do \
case $$file in \
$(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
$(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
esac; \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
if test "$$dir" != "$$file" && test "$$dir" != "."; then \
dir="/$$dir"; \
$(mkdir_p) "$(distdir)$$dir"; \
else \
dir=''; \
fi; \
if test -d $$d/$$file; then \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
fi; \
cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
else \
test -f $(distdir)/$$file \
|| cp -p $$d/$$file $(distdir)/$$file \
|| exit 1; \
fi; \
done
check-am: all-am
check: check-am
all-am: Makefile
installdirs:
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-am
install-strip:
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
`test -z '$(STRIP)' || \
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:
clean-generic:
distclean-generic:
-rm -f $(CONFIG_CLEAN_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-am
clean-am: clean-generic mostlyclean-am
distclean: distclean-am
-rm -f Makefile
distclean-am: clean-am distclean-generic
dvi: dvi-am
dvi-am:
html: html-am
info: info-am
info-am:
install-data-am:
install-exec-am:
install-info: install-info-am
install-man:
installcheck-am:
maintainer-clean: maintainer-clean-am
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-generic
pdf: pdf-am
pdf-am:
ps: ps-am
ps-am:
uninstall-am: uninstall-info-am
.PHONY: all all-am check check-am clean clean-generic distclean \
distclean-generic distdir dvi dvi-am html html-am info info-am \
install install-am install-data install-data-am install-exec \
install-exec-am install-info install-info-am install-man \
install-strip installcheck installcheck-am installdirs \
maintainer-clean maintainer-clean-generic mostlyclean \
mostlyclean-generic pdf pdf-am ps ps-am uninstall uninstall-am \
uninstall-info-am
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

112
include/Mutex.h Normal file
View File

@ -0,0 +1,112 @@
/*---------------------------------------------------------------
* Copyright (c) 1999,2000,2001,2002,2003
* The Board of Trustees of the University of Illinois
* All Rights Reserved.
*---------------------------------------------------------------
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software (Iperf) 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:
*
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and
* the following disclaimers.
*
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimers in the documentation and/or other materials
* provided with the distribution.
*
*
* Neither the names of the University of Illinois, NCSA,
* nor the names of its contributors may be used to endorse
* or promote products derived from this Software without
* specific prior written permission.
*
* 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 CONTIBUTORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* ________________________________________________________________
* National Laboratory for Applied Network Research
* National Center for Supercomputing Applications
* University of Illinois at Urbana-Champaign
* http://www.ncsa.uiuc.edu
* ________________________________________________________________
*
* Mutex.h
* by Mark Gates <mgates@nlanr.net>
* -------------------------------------------------------------------
* An abstract class for locking a mutex (mutual exclusion). If
* threads are not available, this does nothing.
* ------------------------------------------------------------------- */
#ifndef MUTEX_H
#define MUTEX_H
#include "headers.h"
#if defined( HAVE_POSIX_THREAD )
typedef pthread_mutex_t Mutex;
#elif defined( HAVE_WIN32_THREAD )
typedef HANDLE Mutex;
#else
typedef int Mutex;
#endif
/* ------------------------------------------------------------------- *
class Mutex {
public:*/
// initialize mutex
#if defined( HAVE_POSIX_THREAD )
#define Mutex_Initialize( MutexPtr ) pthread_mutex_init( MutexPtr, NULL )
#elif defined( HAVE_WIN32_THREAD )
#define Mutex_Initialize( MutexPtr ) *MutexPtr = CreateMutex( NULL, false, NULL )
#else
#define Mutex_Initialize( MutexPtr )
#endif
// lock the mutex variable
#if defined( HAVE_POSIX_THREAD )
#define Mutex_Lock( MutexPtr ) pthread_mutex_lock( MutexPtr )
#elif defined( HAVE_WIN32_THREAD )
#define Mutex_Lock( MutexPtr ) WaitForSingleObject( *MutexPtr, INFINITE )
#else
#define Mutex_Lock( MutexPtr )
#endif
// unlock the mutex variable
#if defined( HAVE_POSIX_THREAD )
#define Mutex_Unlock( MutexPtr ) pthread_mutex_unlock( MutexPtr )
#elif defined( HAVE_WIN32_THREAD )
#define Mutex_Unlock( MutexPtr ) ReleaseMutex( *MutexPtr )
#else
#define Mutex_Unlock( MutexPtr )
#endif
// destroy, making sure mutex is unlocked
#if defined( HAVE_POSIX_THREAD )
#define Mutex_Destroy( MutexPtr ) do { \
int rc = pthread_mutex_destroy( MutexPtr ); \
if ( rc == EBUSY ) { \
Mutex_Unlock( MutexPtr ); \
pthread_mutex_destroy( MutexPtr ); \
} \
} while ( 0 )
#elif defined( HAVE_WIN32_THREAD )
#define Mutex_Destroy( MutexPtr ) CloseHandle( *MutexPtr )
#else
#define Mutex_Destroy( MutexPtr )
#endif
#endif // MUTEX_H

78
include/PerfSocket.hpp Normal file
View File

@ -0,0 +1,78 @@
/*---------------------------------------------------------------
* Copyright (c) 1999,2000,2001,2002,2003
* The Board of Trustees of the University of Illinois
* All Rights Reserved.
*---------------------------------------------------------------
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software (Iperf) 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:
*
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and
* the following disclaimers.
*
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimers in the documentation and/or other materials
* provided with the distribution.
*
*
* Neither the names of the University of Illinois, NCSA,
* nor the names of its contributors may be used to endorse
* or promote products derived from this Software without
* specific prior written permission.
*
* 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 CONTIBUTORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* ________________________________________________________________
* National Laboratory for Applied Network Research
* National Center for Supercomputing Applications
* University of Illinois at Urbana-Champaign
* http://www.ncsa.uiuc.edu
* ________________________________________________________________
*
* PerfSocket.hpp
* by Mark Gates <mgates@nlanr.net>
* & Ajay Tirumala <tirumala@ncsa.uiuc.edu>
* -------------------------------------------------------------------
* Changes in version 1.6
* Incorporates class declarations for fetching data from files
* ------------------------------------------------------------------- */
#ifndef PERFSOCKET_H
#define PERFSOCKET_H
#include "Mutex.h"
#include "Settings.hpp"
void SetSocketOptions( thread_Settings *inSettings );
// handle interupts
void Sig_Interupt( int inSigno );
#ifdef __cplusplus
extern "C" {
#endif
extern int sInterupted;
extern int groupID;
extern Mutex groupCond;
#ifdef __cplusplus
} /* end extern "C" */
#endif
#endif // PERFSOCKET_H

230
include/Reporter.h Normal file
View File

@ -0,0 +1,230 @@
/*---------------------------------------------------------------
* Copyright (c) 1999,2000,2001,2002,2003
* The Board of Trustees of the University of Illinois
* All Rights Reserved.
*---------------------------------------------------------------
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software (Iperf) 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:
*
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and
* the following disclaimers.
*
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimers in the documentation and/or other materials
* provided with the distribution.
*
*
* Neither the names of the University of Illinois, NCSA,
* nor the names of its contributors may be used to endorse
* or promote products derived from this Software without
* specific prior written permission.
*
* 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 CONTIBUTORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* ________________________________________________________________
* National Laboratory for Applied Network Research
* National Center for Supercomputing Applications
* University of Illinois at Urbana-Champaign
* http://www.ncsa.uiuc.edu
* ________________________________________________________________
*
* Reporter.h
* by Kevin Gibbs <kgibbs@nlanr.net>
*
* Since version 2.0 this handles all reporting.
* ________________________________________________________________ */
#ifndef REPORTER_H
#define REPORTER_H
#include "headers.h"
#include "Mutex.h"
struct thread_Settings;
struct server_hdr;
#include "Settings.hpp"
#define NUM_REPORT_STRUCTS 700
#define NUM_MULTI_SLOTS 5
#ifdef __cplusplus
extern "C" {
#endif
/*
* This struct contains all important information from the sending or
* recieving thread.
*/
typedef struct ReportStruct {
int packetID;
int packetLen;
struct timeval packetTime;
struct timeval sentTime;
} ReportStruct;
/*
* The type field of ReporterData is a bitmask
* with one or more of the following
*/
#define TRANSFER_REPORT 0x00000001
#define SERVER_RELAY_REPORT 0x00000002
#define SETTINGS_REPORT 0x00000004
#define CONNECTION_REPORT 0x00000008
#define MULTIPLE_REPORT 0x00000010
typedef struct Transfer_Info {
void *reserved_delay;
int transferID;
int groupID;
int cntError;
int cntOutofOrder;
int cntDatagrams;
// Hopefully int64_t's
max_size_t TotalLen;
double jitter;
double startTime;
double endTime;
// chars
char mFormat; // -f
u_char mTTL; // -T
char mUDP;
char free;
} Transfer_Info;
typedef struct Connection_Info {
iperf_sockaddr peer;
Socklen_t size_peer;
iperf_sockaddr local;
Socklen_t size_local;
} Connection_Info;
typedef struct ReporterData {
char* mHost; // -c
char* mLocalhost; // -B
// int's
int type;
int cntError;
int lastError;
int cntOutofOrder;
int lastOutofOrder;
int cntDatagrams;
int lastDatagrams;
int PacketID;
int mBufLen; // -l
int mMSS; // -M
int mTCPWin; // -w
/* flags is a BitMask of old bools
bool mBufLenSet; // -l
bool mCompat; // -C
bool mDaemon; // -D
bool mDomain; // -V
bool mFileInput; // -F or -I
bool mNodelay; // -N
bool mPrintMSS; // -m
bool mRemoveService; // -R
bool mStdin; // -I
bool mStdout; // -o
bool mSuggestWin; // -W
bool mUDP;
bool mMode_time;*/
int flags;
// enums (which should be special int's)
ThreadMode mThreadMode; // -s or -c
ReportMode mode;
max_size_t TotalLen;
max_size_t lastTotal;
// doubles
double lastTransit;
// shorts
unsigned short mPort; // -p
// structs or miscellaneous
Transfer_Info info;
Connection_Info connection;
struct timeval startTime;
struct timeval packetTime;
struct timeval nextTime;
struct timeval intervalTime;
} ReporterData;
typedef struct MultiHeader {
int reporterindex;
int agentindex;
int groupID;
int threads;
ReporterData *report;
Transfer_Info *data;
Condition barrier;
struct timeval startTime;
} MultiHeader;
typedef struct ReportHeader {
int reporterindex;
int agentindex;
ReporterData report;
ReportStruct *data;
MultiHeader *multireport;
struct ReportHeader *next;
} ReportHeader;
typedef void* (* report_connection)( Connection_Info*, int );
typedef void (* report_settings)( ReporterData* );
typedef void (* report_statistics)( Transfer_Info* );
typedef void (* report_serverstatistics)( Connection_Info*, Transfer_Info* );
MultiHeader* InitMulti( struct thread_Settings *agent, int inID );
ReportHeader* InitReport( struct thread_Settings *agent );
void ReportPacket( ReportHeader *agent, ReportStruct *packet );
void CloseReport( ReportHeader *agent, ReportStruct *packet );
void EndReport( ReportHeader *agent );
Transfer_Info* GetReport( ReportHeader *agent );
void ReportServerUDP( struct thread_Settings *agent, struct server_hdr *server );
void ReportSettings( struct thread_Settings *agent );
void ReportConnections( struct thread_Settings *agent );
extern report_connection connection_reports[];
extern report_settings settings_reports[];
extern report_statistics statistics_reports[];
extern report_serverstatistics serverstatistics_reports[];
extern report_statistics multiple_reports[];
extern char buffer[64]; // Buffer for printing
#define rMillion 1000000
#define TimeDifference( left, right ) (left.tv_sec - right.tv_sec) + \
(left.tv_usec - right.tv_usec) / ((double) rMillion)
#define TimeAdd( left, right ) do { \
left.tv_usec += right.tv_usec; \
if ( left.tv_usec > rMillion ) { \
left.tv_usec -= rMillion; \
left.tv_sec++; \
} \
left.tv_sec += right.tv_sec; \
} while ( 0 )
#ifdef __cplusplus
} /* end extern "C" */
#endif
#endif // REPORTER_H

85
include/Server.hpp Normal file
View File

@ -0,0 +1,85 @@
/*---------------------------------------------------------------
* Copyright (c) 1999,2000,2001,2002,2003
* The Board of Trustees of the University of Illinois
* All Rights Reserved.
*---------------------------------------------------------------
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software (Iperf) 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:
*
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and
* the following disclaimers.
*
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimers in the documentation and/or other materials
* provided with the distribution.
*
*
* Neither the names of the University of Illinois, NCSA,
* nor the names of its contributors may be used to endorse
* or promote products derived from this Software without
* specific prior written permission.
*
* 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 CONTIBUTORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* ________________________________________________________________
* National Laboratory for Applied Network Research
* National Center for Supercomputing Applications
* University of Illinois at Urbana-Champaign
* http://www.ncsa.uiuc.edu
* ________________________________________________________________
*
* Server.hpp
* by Mark Gates <mgates@nlanr.net>
* -------------------------------------------------------------------
* A server thread is initiated for each connection accept() returns.
* Handles sending and receiving data, and then closes socket.
* ------------------------------------------------------------------- */
#ifndef SERVER_H
#define SERVER_H
#include "Settings.hpp"
#include "util.h"
#include "Timestamp.hpp"
/* ------------------------------------------------------------------- */
class Server {
public:
// stores server socket, port and TCP/UDP mode
Server( thread_Settings *inSettings );
// destroy the server object
~Server();
// accepts connection and receives data
void Run( void );
void write_UDP_AckFIN( );
static void Sig_Int( int inSigno );
private:
thread_Settings *mSettings;
char* mBuf;
Timestamp mEndTime;
}; // end class Server
#endif // SERVER_H

420
include/Settings.hpp Normal file
View File

@ -0,0 +1,420 @@
/*---------------------------------------------------------------
* Copyright (c) 1999,2000,2001,2002,2003
* The Board of Trustees of the University of Illinois
* All Rights Reserved.
*---------------------------------------------------------------
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software (Iperf) 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:
*
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and
* the following disclaimers.
*
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimers in the documentation and/or other materials
* provided with the distribution.
*
*
* Neither the names of the University of Illinois, NCSA,
* nor the names of its contributors may be used to endorse
* or promote products derived from this Software without
* specific prior written permission.
*
* 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 CONTIBUTORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* ________________________________________________________________
* National Laboratory for Applied Network Research
* National Center for Supercomputing Applications
* University of Illinois at Urbana-Champaign
* http://www.ncsa.uiuc.edu
* ________________________________________________________________
*
* Settings.hpp
* by Mark Gates <mgates@nlanr.net>
* & Ajay Tirumala <tirumala@ncsa.uiuc.edu>
* -------------------------------------------------------------------
* Stores and parses the initial values for all the global variables.
* -------------------------------------------------------------------
* headers
* uses
* <stdlib.h>
* <assert.h>
* ------------------------------------------------------------------- */
#ifndef SETTINGS_H
#define SETTINGS_H
#include "headers.h"
#include "Thread.h"
/* -------------------------------------------------------------------
* constants
* ------------------------------------------------------------------- */
#ifdef __cplusplus
extern "C" {
#endif
// server/client mode
typedef enum ThreadMode {
kMode_Unknown = 0,
kMode_Server,
kMode_Client,
kMode_Reporter,
kMode_Listener
} ThreadMode;
// report mode
typedef enum ReportMode {
kReport_Default = 0,
kReport_CSV,
//kReport_XML,
kReport_MAXIMUM
} ReportMode;
// test mode
typedef enum TestMode {
kTest_Normal = 0,
kTest_DualTest,
kTest_TradeOff,
kTest_Unknown
} TestMode;
#include "Reporter.h"
/*
* The thread_Settings is a structure that holds all
* options for a given execution of either a client
* or server. By using this structure rather than
* a global structure or class we can have multiple
* clients or servers running with different settings.
* In version 2.0 and above this structure contains
* all the information needed for a thread to execute
* and contains only C elements so it can be manipulated
* by either C or C++.
*/
typedef struct thread_Settings {
// Pointers
char* mFileName; // -F
char* mHost; // -c
char* mLocalhost; // -B
char* mOutputFileName; // -o
FILE* Extractor_file;
ReportHeader* reporthdr;
MultiHeader* multihdr;
struct thread_Settings *runNow;
struct thread_Settings *runNext;
// int's
int mThreads; // -P
int mTOS; // -S
int mSock;
int Extractor_size;
int mBufLen; // -l
int mMSS; // -M
int mTCPWin; // -w
/* flags is a BitMask of old bools
bool mBufLenSet; // -l
bool mCompat; // -C
bool mDaemon; // -D
bool mDomain; // -V
bool mFileInput; // -F or -I
bool mNodelay; // -N
bool mPrintMSS; // -m
bool mRemoveService; // -R
bool mStdin; // -I
bool mStdout; // -o
bool mSuggestWin; // -W
bool mUDP; // -u
bool mMode_time;
bool mReportSettings;
bool mMulticast;
bool mNoSettingsReport; // -x s
bool mNoConnectionReport; // -x c
bool mNoDataReport; // -x d
bool mNoServerReport; // -x
bool mNoMultReport; // -x m
bool mSinlgeClient; // -1 */
int flags;
// enums (which should be special int's)
ThreadMode mThreadMode; // -s or -c
ReportMode mReportMode;
TestMode mMode; // -r or -d
// Hopefully int64_t's
max_size_t mUDPRate; // -b or -u
max_size_t mAmount; // -n or -t
// doubles
double mInterval; // -i
// shorts
unsigned short mListenPort; // -L
unsigned short mPort; // -p
// chars
char mFormat; // -f
u_char mTTL; // -T
char pad1[2];
// structs or miscellaneous
iperf_sockaddr peer;
Socklen_t size_peer;
iperf_sockaddr local;
Socklen_t size_local;
nthread_t mTID;
#if defined( HAVE_WIN32_THREAD )
HANDLE mHandle;
#endif
} thread_Settings;
/*
* Due to the use of thread_Settings in C and C++
* we are unable to use bool values. To provide
* the functionality of bools we use the following
* bitmask over an assumed 32 bit int. This will
* work fine on 64bit machines we will just be ignoring
* the upper 32bits.
*
* To add a flag simply define it as the next bit then
* add the 3 support functions below.
*/
#define FLAG_BUFLENSET 0x00000001
#define FLAG_COMPAT 0x00000002
#define FLAG_DAEMON 0x00000004
#define FLAG_DOMAIN 0x00000008
#define FLAG_FILEINPUT 0x00000010
#define FLAG_NODELAY 0x00000020
#define FLAG_PRINTMSS 0x00000040
#define FLAG_REMOVESERVICE 0x00000080
#define FLAG_STDIN 0x00000100
#define FLAG_STDOUT 0x00000200
#define FLAG_SUGGESTWIN 0x00000400
#define FLAG_UDP 0x00000800
#define FLAG_MODETIME 0x00001000
#define FLAG_REPORTSETTINGS 0x00002000
#define FLAG_MULTICAST 0x00004000
#define FLAG_NOSETTREPORT 0x00008000
#define FLAG_NOCONNREPORT 0x00010000
#define FLAG_NODATAREPORT 0x00020000
#define FLAG_NOSERVREPORT 0x00040000
#define FLAG_NOMULTREPORT 0x00080000
#define FLAG_SINGLECLIENT 0x00100000
#define FLAG_SINGLEUDP 0x00200000
#define isBuflenSet(settings) ((settings->flags & FLAG_BUFLENSET) != 0)
#define isCompat(settings) ((settings->flags & FLAG_COMPAT) != 0)
#define isDaemon(settings) ((settings->flags & FLAG_DAEMON) != 0)
#define isIPV6(settings) ((settings->flags & FLAG_DOMAIN) != 0)
#define isFileInput(settings) ((settings->flags & FLAG_FILEINPUT) != 0)
#define isNoDelay(settings) ((settings->flags & FLAG_NODELAY) != 0)
#define isPrintMSS(settings) ((settings->flags & FLAG_PRINTMSS) != 0)
#define isRemoveService(settings) ((settings->flags & FLAG_REMOVESERVICE) != 0)
#define isSTDIN(settings) ((settings->flags & FLAG_STDIN) != 0)
#define isSTDOUT(settings) ((settings->flags & FLAG_STDOUT) != 0)
#define isSuggestWin(settings) ((settings->flags & FLAG_SUGGESTWIN) != 0)
#define isUDP(settings) ((settings->flags & FLAG_UDP) != 0)
#define isModeTime(settings) ((settings->flags & FLAG_MODETIME) != 0)
#define isReport(settings) ((settings->flags & FLAG_REPORTSETTINGS) != 0)
#define isMulticast(settings) ((settings->flags & FLAG_MULTICAST) != 0)
// Active Low for Reports
#define isSettingsReport(settings) ((settings->flags & FLAG_NOSETTREPORT) == 0)
#define isConnectionReport(settings) ((settings->flags & FLAG_NOCONNREPORT) == 0)
#define isDataReport(settings) ((settings->flags & FLAG_NODATAREPORT) == 0)
#define isServerReport(settings) ((settings->flags & FLAG_NOSERVREPORT) == 0)
#define isMultipleReport(settings) ((settings->flags & FLAG_NOMULTREPORT) == 0)
// end Active Low
#define isSingleClient(settings) ((settings->flags & FLAG_SINGLECLIENT) != 0)
#define isSingleUDP(settings) ((settings->flags & FLAG_SINGLEUDP) != 0)
#define setBuflenSet(settings) settings->flags |= FLAG_BUFLENSET
#define setCompat(settings) settings->flags |= FLAG_COMPAT
#define setDaemon(settings) settings->flags |= FLAG_DAEMON
#define setIPV6(settings) settings->flags |= FLAG_DOMAIN
#define setFileInput(settings) settings->flags |= FLAG_FILEINPUT
#define setNoDelay(settings) settings->flags |= FLAG_NODELAY
#define setPrintMSS(settings) settings->flags |= FLAG_PRINTMSS
#define setRemoveService(settings) settings->flags |= FLAG_REMOVESERVICE
#define setSTDIN(settings) settings->flags |= FLAG_STDIN
#define setSTDOUT(settings) settings->flags |= FLAG_STDOUT
#define setSuggestWin(settings) settings->flags |= FLAG_SUGGESTWIN
#define setUDP(settings) settings->flags |= FLAG_UDP
#define setModeTime(settings) settings->flags |= FLAG_MODETIME
#define setReport(settings) settings->flags |= FLAG_REPORTSETTINGS
#define setMulticast(settings) settings->flags |= FLAG_MULTICAST
#define setNoSettReport(settings) settings->flags |= FLAG_NOSETTREPORT
#define setNoConnReport(settings) settings->flags |= FLAG_NOCONNREPORT
#define setNoDataReport(settings) settings->flags |= FLAG_NODATAREPORT
#define setNoServReport(settings) settings->flags |= FLAG_NOSERVREPORT
#define setNoMultReport(settings) settings->flags |= FLAG_NOMULTREPORT
#define setSingleClient(settings) settings->flags |= FLAG_SINGLECLIENT
#define setSingleUDP(settings) settings->flags |= FLAG_SINGLEUDP
#define unsetBuflenSet(settings) settings->flags &= ~FLAG_BUFLENSET
#define unsetCompat(settings) settings->flags &= ~FLAG_COMPAT
#define unsetDaemon(settings) settings->flags &= ~FLAG_DAEMON
#define unsetIPV6(settings) settings->flags &= ~FLAG_DOMAIN
#define unsetFileInput(settings) settings->flags &= ~FLAG_FILEINPUT
#define unsetNoDelay(settings) settings->flags &= ~FLAG_NODELAY
#define unsetPrintMSS(settings) settings->flags &= ~FLAG_PRINTMSS
#define unsetRemoveService(settings) settings->flags &= ~FLAG_REMOVESERVICE
#define unsetSTDIN(settings) settings->flags &= ~FLAG_STDIN
#define unsetSTDOUT(settings) settings->flags &= ~FLAG_STDOUT
#define unsetSuggestWin(settings) settings->flags &= ~FLAG_SUGGESTWIN
#define unsetUDP(settings) settings->flags &= ~FLAG_UDP
#define unsetModeTime(settings) settings->flags &= ~FLAG_MODETIME
#define unsetReport(settings) settings->flags &= ~FLAG_REPORTSETTINGS
#define unsetMulticast(settings) settings->flags &= ~FLAG_MULTICAST
#define unsetNoSettReport(settings) settings->flags &= ~FLAG_NOSETTREPORT
#define unsetNoConnReport(settings) settings->flags &= ~FLAG_NOCONNREPORT
#define unsetNoDataReport(settings) settings->flags &= ~FLAG_NODATAREPORT
#define unsetNoServReport(settings) settings->flags &= ~FLAG_NOSERVREPORT
#define unsetNoMultReport(settings) settings->flags &= ~FLAG_NOMULTREPORT
#define unsetSingleClient(settings) settings->flags &= ~FLAG_SINGLECLIENT
#define unsetSingleUDP(settings) settings->flags &= ~FLAG_SINGLEUDP
#define HEADER_VERSION1 0x80000000
#define RUN_NOW 0x00000001
// used to reference the 4 byte ID number we place in UDP datagrams
// use int32_t if possible, otherwise a 32 bit bitfield (e.g. on J90)
typedef struct UDP_datagram {
#ifdef HAVE_INT32_T
int32_t id;
u_int32_t tv_sec;
u_int32_t tv_usec;
#else
signed int id : 32;
unsigned int tv_sec : 32;
unsigned int tv_usec : 32;
#endif
} UDP_datagram;
/*
* The client_hdr structure is sent from clients
* to servers to alert them of things that need
* to happen. Order must be perserved in all
* future releases for backward compatibility.
* 1.7 has flags, numThreads, mPort, and bufferlen
*/
typedef struct client_hdr {
#ifdef HAVE_INT32_T
/*
* flags is a bitmap for different options
* the most significant bits are for determining
* which information is available. So 1.7 uses
* 0x80000000 and the next time information is added
* the 1.7 bit will be set and 0x40000000 will be
* set signifying additional information. If no
* information bits are set then the header is ignored.
* The lowest order diferentiates between dualtest and
* tradeoff modes, wheither the speaker needs to start
* immediately or after the audience finishes.
*/
int32_t flags;
int32_t numThreads;
int32_t mPort;
int32_t bufferlen;
int32_t mWinBand;
int32_t mAmount;
#else
signed int flags : 32;
signed int numThreads : 32;
signed int mPort : 32;
signed int bufferlen : 32;
signed int mWinBand : 32;
signed int mAmount : 32;
#endif
} client_hdr;
/*
* The server_hdr structure facilitates the server
* report of jitter and loss on the client side.
* It piggy_backs on the existing clear to close
* packet.
*/
typedef struct server_hdr {
#ifdef HAVE_INT32_T
/*
* flags is a bitmap for different options
* the most significant bits are for determining
* which information is available. So 1.7 uses
* 0x80000000 and the next time information is added
* the 1.7 bit will be set and 0x40000000 will be
* set signifying additional information. If no
* information bits are set then the header is ignored.
*/
int32_t flags;
int32_t total_len1;
int32_t total_len2;
int32_t stop_sec;
int32_t stop_usec;
int32_t error_cnt;
int32_t outorder_cnt;
int32_t datagrams;
int32_t jitter1;
int32_t jitter2;
#else
signed int flags : 32;
signed int total_len1 : 32;
signed int total_len2 : 32;
signed int stop_sec : 32;
signed int stop_usec : 32;
signed int error_cnt : 32;
signed int outorder_cnt : 32;
signed int datagrams : 32;
signed int jitter1 : 32;
signed int jitter2 : 32;
#endif
} server_hdr;
// set to defaults
void Settings_Initialize( thread_Settings* main );
// copy structure
void Settings_Copy( thread_Settings* from, thread_Settings** into );
// free associated memory
void Settings_Destroy( thread_Settings *mSettings );
// parse settings from user's environment variables
void Settings_ParseEnvironment( thread_Settings *mSettings );
// parse settings from app's command line
void Settings_ParseCommandLine( int argc, char **argv, thread_Settings *mSettings );
// convert to lower case for [KMG]bits/sec
void Settings_GetLowerCaseArg(const char *,char *);
// convert to upper case for [KMG]bytes/sec
void Settings_GetUpperCaseArg(const char *,char *);
// generate settings for listener instance
void Settings_GenerateListenerSettings( thread_Settings *client, thread_Settings **listener);
// generate settings for speaker instance
void Settings_GenerateClientSettings( thread_Settings *server,
thread_Settings **client,
client_hdr *hdr );
// generate client header for server
void Settings_GenerateClientHdr( thread_Settings *client, client_hdr *hdr );
#ifdef __cplusplus
} /* end extern "C" */
#endif
#endif // SETTINGS_H

104
include/SocketAddr.h Normal file
View File

@ -0,0 +1,104 @@
/*---------------------------------------------------------------
* Copyright (c) 1999,2000,2001,2002,2003
* The Board of Trustees of the University of Illinois
* All Rights Reserved.
*---------------------------------------------------------------
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software (Iperf) 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:
*
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and
* the following disclaimers.
*
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimers in the documentation and/or other materials
* provided with the distribution.
*
*
* Neither the names of the University of Illinois, NCSA,
* nor the names of its contributors may be used to endorse
* or promote products derived from this Software without
* specific prior written permission.
*
* 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 CONTIBUTORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* ________________________________________________________________
* National Laboratory for Applied Network Research
* National Center for Supercomputing Applications
* University of Illinois at Urbana-Champaign
* http://www.ncsa.uiuc.edu
* ________________________________________________________________
*
* Socket.cpp
* by Ajay Tirumala <tirumala@ncsa.uiuc.edu>
* and Mark Gates <mgates@nlanr.net>
* ------------------------------------------------------------------- */
#ifndef SOCKET_ADDR_H
#define SOCKET_ADDR_H
#include "headers.h"
#include "Settings.hpp"
#ifdef __cplusplus
extern "C" {
#endif
/* ------------------------------------------------------------------- */
void SockAddr_localAddr( thread_Settings *inSettings );
void SockAddr_remoteAddr( thread_Settings *inSettings );
void SockAddr_setHostname( const char* inHostname,
iperf_sockaddr *inSockAddr,
int isIPv6 ); // DNS lookup
void SockAddr_getHostname( iperf_sockaddr *inSockAddr,
char* outHostname,
size_t len ); // reverse DNS lookup
void SockAddr_getHostAddress( iperf_sockaddr *inSockAddr,
char* outAddress,
size_t len ); // dotted decimal
void SockAddr_setPort( iperf_sockaddr *inSockAddr, unsigned short inPort );
void SockAddr_setPortAny( iperf_sockaddr *inSockAddr );
unsigned short SockAddr_getPort( iperf_sockaddr *inSockAddr );
void SockAddr_setAddressAny( iperf_sockaddr *inSockAddr );
// return pointer to the struct in_addr
struct in_addr* SockAddr_get_in_addr( iperf_sockaddr *inSockAddr );
#ifdef HAVE_IPV6
// return pointer to the struct in_addr
struct in6_addr* SockAddr_get_in6_addr( iperf_sockaddr *inSockAddr );
#endif
// return the sizeof the addess structure (struct sockaddr_in)
Socklen_t SockAddr_get_sizeof_sockaddr( iperf_sockaddr *inSockAddr );
int SockAddr_isMulticast( iperf_sockaddr *inSockAddr );
int SockAddr_isIPv6( iperf_sockaddr *inSockAddr );
int SockAddr_are_Equal( struct sockaddr *first, struct sockaddr *second );
int SockAddr_Hostare_Equal( struct sockaddr *first, struct sockaddr *second );
void SockAddr_zeroAddress( iperf_sockaddr *inSockAddr );
#ifdef __cplusplus
} /* end extern "C" */
#endif
#endif /* SOCKET_ADDR_H */

159
include/Thread.h Normal file
View File

@ -0,0 +1,159 @@
/*---------------------------------------------------------------
* Copyright (c) 1999,2000,2001,2002,2003
* The Board of Trustees of the University of Illinois
* All Rights Reserved.
*---------------------------------------------------------------
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software (Iperf) 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:
*
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and
* the following disclaimers.
*
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimers in the documentation and/or other materials
* provided with the distribution.
*
*
* Neither the names of the University of Illinois, NCSA,
* nor the names of its contributors may be used to endorse
* or promote products derived from this Software without
* specific prior written permission.
*
* 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 CONTIBUTORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* ________________________________________________________________
* National Laboratory for Applied Network Research
* National Center for Supercomputing Applications
* University of Illinois at Urbana-Champaign
* http://www.ncsa.uiuc.edu
* ________________________________________________________________
*
* Thread.h
* by Kevin Gibbs <kgibbs@nlanr.net>
*
* Based on:
* Thread.hpp
* by Mark Gates <mgates@nlanr.net>
* -------------------------------------------------------------------
* The thread subsystem is responsible for all thread functions. It
* provides a thread implementation agnostic interface to Iperf. If
* threads are not available (HAVE_THREAD is undefined), thread_start
* does not start a new thread but just launches the specified object
* in the current thread. Everything that defines a thread of
* execution in Iperf is contained in an thread_Settings structure. To
* start a thread simply pass one such structure into thread_start.
* ------------------------------------------------------------------- */
#ifndef THREAD_H
#define THREAD_H
#ifdef __cplusplus
extern "C" {
#endif
#if defined( HAVE_POSIX_THREAD )
/* Definitions for Posix Threads (pthreads) */
#include <pthread.h>
typedef pthread_t nthread_t;
#define HAVE_THREAD 1
#elif defined( HAVE_WIN32_THREAD )
/* Definitions for Win32 NT Threads */
typedef DWORD nthread_t;
#define HAVE_THREAD 1
#else
/* Definitions for no threads */
typedef int nthread_t;
#undef HAVE_THREAD
#endif
// Forward declaration
struct thread_Settings;
#include "Condition.h"
#include "Settings.hpp"
// initialize or destroy the thread subsystem
void thread_init( );
void thread_destroy( );
// start or stop a thread executing
void thread_start( struct thread_Settings* thread );
void thread_stop( struct thread_Settings* thread );
/* wait for this or all threads to complete */
void thread_joinall( void );
int thread_numuserthreads( void );
// set a thread to be ignorable, so joinall won't wait on it
void thread_setignore( void );
void thread_unsetignore( void );
// Used for threads that may never terminate (ie Listener Thread)
void thread_register_nonterm( void );
void thread_unregister_nonterm( void );
int thread_release_nonterm( int force );
/* -------------------------------------------------------------------
* Return the current thread's ID.
* ------------------------------------------------------------------- */
#if defined( HAVE_POSIX_THREAD )
#define thread_getid() pthread_self()
#elif defined( HAVE_WIN32_THREAD )
#define thread_getid() GetCurrentThreadId()
#else
#define thread_getid() 0
#endif
int thread_equalid( nthread_t inLeft, nthread_t inRight );
nthread_t thread_zeroid( void );
#if defined( HAVE_WIN32_THREAD )
DWORD WINAPI thread_run_wrapper( void* paramPtr );
#else
void* thread_run_wrapper( void* paramPtr );
#endif
void thread_rest ( void );
// defined in launch.cpp
void server_spawn( struct thread_Settings* thread );
void client_spawn( struct thread_Settings* thread );
void client_init( struct thread_Settings* clients );
void listener_spawn( struct thread_Settings* thread );
// defined in reporter.c
void reporter_spawn( struct thread_Settings* thread );
#ifdef __cplusplus
} /* end extern "C" */
#endif
#endif // THREAD_H

252
include/Timestamp.hpp Normal file
View File

@ -0,0 +1,252 @@
/*---------------------------------------------------------------
* Copyright (c) 1999,2000,2001,2002,2003
* The Board of Trustees of the University of Illinois
* All Rights Reserved.
*---------------------------------------------------------------
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software (Iperf) 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:
*
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and
* the following disclaimers.
*
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimers in the documentation and/or other materials
* provided with the distribution.
*
*
* Neither the names of the University of Illinois, NCSA,
* nor the names of its contributors may be used to endorse
* or promote products derived from this Software without
* specific prior written permission.
*
* 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 CONTIBUTORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* ________________________________________________________________
* National Laboratory for Applied Network Research
* National Center for Supercomputing Applications
* University of Illinois at Urbana-Champaign
* http://www.ncsa.uiuc.edu
* ________________________________________________________________
*
* Timestamp.hpp
* by Mark Gates <mgates@nlanr.net>
* -------------------------------------------------------------------
* A generic interface to a timestamp.
* This implementation uses the unix gettimeofday().
* -------------------------------------------------------------------
* headers
* uses
* <sys/types.h>
* <sys/time.h>
* <unistd.h>
* ------------------------------------------------------------------- */
#ifndef TIMESTAMP_H
#define TIMESTAMP_H
#include "headers.h"
/* ------------------------------------------------------------------- */
class Timestamp {
public:
/* -------------------------------------------------------------------
* Create a timestamp, with the current time in it.
* ------------------------------------------------------------------- */
Timestamp( void ) {
setnow();
}
/* -------------------------------------------------------------------
* Create a timestamp, with the given seconds/microseconds
* ------------------------------------------------------------------- */
Timestamp( long sec, long usec ) {
set( sec, usec );
}
/* -------------------------------------------------------------------
* Create a timestamp, with the given seconds
* ------------------------------------------------------------------- */
Timestamp( double sec ) {
set( sec );
}
/* -------------------------------------------------------------------
* Set timestamp to current time.
* ------------------------------------------------------------------- */
void setnow( void ) {
gettimeofday( &mTime, NULL );
}
/* -------------------------------------------------------------------
* Set timestamp to the given seconds/microseconds
* ------------------------------------------------------------------- */
void set( long sec, long usec ) {
assert( sec >= 0 );
assert( usec >= 0 && usec < kMillion );
mTime.tv_sec = sec;
mTime.tv_usec = usec;
}
/* -------------------------------------------------------------------
* Set timestamp to the given seconds
* ------------------------------------------------------------------- */
void set( double sec ) {
mTime.tv_sec = (long) sec;
mTime.tv_usec = (long) ((sec - mTime.tv_sec) * kMillion);
}
/* -------------------------------------------------------------------
* return seconds portion of timestamp
* ------------------------------------------------------------------- */
long getSecs( void ) {
return mTime.tv_sec;
}
/* -------------------------------------------------------------------
* return microseconds portion of timestamp
* ------------------------------------------------------------------- */
long getUsecs( void ) {
return mTime.tv_usec;
}
/* -------------------------------------------------------------------
* return timestamp as a floating point seconds
* ------------------------------------------------------------------- */
double get( void ) {
return mTime.tv_sec + mTime.tv_usec / ((double) kMillion);
}
/* -------------------------------------------------------------------
* subtract the right timestamp from my timestamp.
* return the difference in microseconds.
* ------------------------------------------------------------------- */
long subUsec( Timestamp right ) {
return(mTime.tv_sec - right.mTime.tv_sec) * kMillion +
(mTime.tv_usec - right.mTime.tv_usec);
}
/* -------------------------------------------------------------------
* subtract the right timestamp from my timestamp.
* return the difference in microseconds.
* ------------------------------------------------------------------- */
long subUsec( timeval right ) {
return(mTime.tv_sec - right.tv_sec) * kMillion +
(mTime.tv_usec - right.tv_usec);
}
/* -------------------------------------------------------------------
* subtract the right timestamp from my timestamp.
* return the difference in seconds as a floating point.
* ------------------------------------------------------------------- */
double subSec( Timestamp right ) {
return(mTime.tv_sec - right.mTime.tv_sec) +
(mTime.tv_usec - right.mTime.tv_usec) / ((double) kMillion);
}
/* -------------------------------------------------------------------
* add the right timestamp to my timestamp.
* ------------------------------------------------------------------- */
void add( Timestamp right ) {
mTime.tv_sec += right.mTime.tv_sec;
mTime.tv_usec += right.mTime.tv_usec;
// watch for under- and overflow
if ( mTime.tv_usec < 0 ) {
mTime.tv_usec += kMillion;
mTime.tv_sec--;
}
if ( mTime.tv_usec >= kMillion ) {
mTime.tv_usec -= kMillion;
mTime.tv_sec++;
}
assert( mTime.tv_usec >= 0 &&
mTime.tv_usec < kMillion );
}
/* -------------------------------------------------------------------
* add the seconds to my timestamp.
* TODO optimize?
* ------------------------------------------------------------------- */
void add( double sec ) {
mTime.tv_sec += (long) sec;
mTime.tv_usec += (long) ((sec - ((long) sec )) * kMillion);
// watch for overflow
if ( mTime.tv_usec >= kMillion ) {
mTime.tv_usec -= kMillion;
mTime.tv_sec++;
}
assert( mTime.tv_usec >= 0 &&
mTime.tv_usec < kMillion );
}
/* -------------------------------------------------------------------
* return true if my timestamp is before the right timestamp.
* ------------------------------------------------------------------- */
bool before( Timestamp right ) {
return mTime.tv_sec < right.mTime.tv_sec ||
(mTime.tv_sec == right.mTime.tv_sec &&
mTime.tv_usec < right.mTime.tv_usec);
}
/* -------------------------------------------------------------------
* return true if my timestamp is before the right timestamp.
* ------------------------------------------------------------------- */
bool before( timeval right ) {
return mTime.tv_sec < right.tv_sec ||
(mTime.tv_sec == right.tv_sec &&
mTime.tv_usec < right.tv_usec);
}
/* -------------------------------------------------------------------
* return true if my timestamp is after the right timestamp.
* ------------------------------------------------------------------- */
bool after( Timestamp right ) {
return mTime.tv_sec > right.mTime.tv_sec ||
(mTime.tv_sec == right.mTime.tv_sec &&
mTime.tv_usec > right.mTime.tv_usec);
}
/**
* This function returns the fraction of time elapsed after the beginning
* till the end
*/
double fraction(Timestamp currentTime, Timestamp endTime) {
if ( (currentTime.after(*this)) && (endTime.after(currentTime)) ) {
return(((double)currentTime.subUsec(*this)) /
((double)endTime.subUsec(*this)));
} else {
return -1.0;
}
}
protected:
enum {
kMillion = 1000000
};
struct timeval mTime;
}; // end class Timestamp
#endif // TIMESTAMP_H

82
include/config.win32.h Normal file
View File

@ -0,0 +1,82 @@
/* config.h. Generated by hand for Windows. */
#ifndef CONFIG_H
#define CONFIG_H
/* ===================================================================
* config.h
*
* config.h is derived from config.h.in -- do not edit config.h
*
* This contains variables that the configure script checks and
* then defines or undefines. The source code checks for these
* variables to know if certain features are present.
*
* by Mark Gates <mgates@nlanr.net>
*
* Copyright 1999 The Board of Trustees of the University of Illinois
* All rights reserved. See doc/license.txt for complete text.
*
* $Id: config.win32.h,v 1.1.1.1 2004/05/18 01:50:44 kgibbs Exp $
* =================================================================== */
/* Define if threads exist (using pthreads or Win32 threads) */
/* #undef HAVE_POSIX_THREAD */
#define HAVE_WIN32_THREAD 1
/* #undef _REENTRANT */
/* Define if on OSF1 and need special extern "C" around some header files */
/* #undef SPECIAL_OSF1_EXTERN */
/* Define if the strings.h header file exists */
/* #undef HAVE_STRINGS_H */
/* Define the intXX_t, u_intXX_t, size_t, ssize_t, and socklen_t types */
/* On the Cray J90 there is no 4 byte integer, so we define int32_t
* but it is 8 bytes, and we leave HAVE_INT32_T undefined. */
#define SIZEOF_INT 4
#define HAVE_U_INT16_T 1
#define HAVE_INT32_T 1
#define HAVE_INT64_T 1
#define HAVE_U_INT32_T 1
#define int32_t LONG32
#define u_int16_t UINT16
#define u_int32_t ULONG32
/* #undef size_t */
#define ssize_t int
/* socklen_t usually defined in <sys/socket.h>. Unfortunately it doesn't
* work on some systems (like DEC OSF/1), so we'll use our own Socklen_t */
#define Socklen_t int
/* Define if you have these functions. */
#define HAVE_SNPRINTF 1
/* #undef HAVE_INET_PTON */
/* #undef HAVE_INET_NTOP */
/* #undef HAVE_GETTIMEOFDAY */
/* #undef HAVE_PTHREAD_CANCEL */
#define HAVE_USLEEP 1
/* #undef HAVE_QUAD_SUPPORT */
/* #undef HAVE_PRINTF_QD */
/* standard C++, which isn't always... */
/* #undef bool */
#define true 1
#define false 0
/* Define if the host is Big Endian (network byte order) */
/* #undef WORDS_BIGENDIAN */
/* Define if multicast support exists */
#define HAVE_MULTICAST 1
/* Define if all IPv6 headers/structures are present */
#define HAVE_IPV6 1
/* Define if IPv6 multicast support exists */
#define HAVE_IPV6_MULTICAST 1
/* Define if Debugging of sockets is desired */
/* #undef DBG_MJZ */
#endif /* CONFIG_H */

58
include/delay.hpp Normal file
View File

@ -0,0 +1,58 @@
/*---------------------------------------------------------------
* Copyright (c) 1999,2000,2001,2002,2003
* The Board of Trustees of the University of Illinois
* All Rights Reserved.
*---------------------------------------------------------------
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software (Iperf) 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:
*
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and
* the following disclaimers.
*
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimers in the documentation and/or other materials
* provided with the distribution.
*
*
* Neither the names of the University of Illinois, NCSA,
* nor the names of its contributors may be used to endorse
* or promote products derived from this Software without
* specific prior written permission.
*
* 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 CONTIBUTORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* ________________________________________________________________
* National Laboratory for Applied Network Research
* National Center for Supercomputing Applications
* University of Illinois at Urbana-Champaign
* http://www.ncsa.uiuc.edu
* ________________________________________________________________
*
* delay.hpp
* by Mark Gates <mgates@nlanr.net>
* -------------------------------------------------------------------
* accurate microsecond delay
* ------------------------------------------------------------------- */
#ifndef DELAY_H
#define DELAY_H
void delay_loop( unsigned long usecs );
#endif /* DELAY_H */

81
include/gettimeofday.h Normal file
View File

@ -0,0 +1,81 @@
/*---------------------------------------------------------------
* Copyright (c) 1999,2000,2001,2002,2003
* The Board of Trustees of the University of Illinois
* All Rights Reserved.
*---------------------------------------------------------------
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software (Iperf) 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:
*
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and
* the following disclaimers.
*
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimers in the documentation and/or other materials
* provided with the distribution.
*
*
* Neither the names of the University of Illinois, NCSA,
* nor the names of its contributors may be used to endorse
* or promote products derived from this Software without
* specific prior written permission.
*
* 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 CONTIBUTORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* ________________________________________________________________
* National Laboratory for Applied Network Research
* National Center for Supercomputing Applications
* University of Illinois at Urbana-Champaign
* http://www.ncsa.uiuc.edu
* ________________________________________________________________
*
* gettimeofday.h
*
* Mark Gates <mgates@nlanr.net>
* -------------------------------------------------------------------
* An implementation of gettimeofday for Windows.
* ------------------------------------------------------------------- */
#ifndef GETTIMEOFDAY_H
#define GETTIMEOFDAY_H
#ifndef HAVE_GETTIMEOFDAY
#ifdef __cplusplus
extern "C" {
#endif
int gettimeofday( struct timeval* tv, void* timezone );
#ifdef __cplusplus
} /* end extern "C" */
#endif
#endif /* HAVE_GETTIMEOFDAY */
#endif /* GETTIMEOFDAY_H */

136
include/gnu_getopt.h Normal file
View File

@ -0,0 +1,136 @@
/* Declarations for gnu_getopt.
Copyright (C) 1989,90,91,92,93,94,96,97 Free Software Foundation, Inc.
This file is part of the GNU C Library. Its master source is NOT part of
the C library, however. The master source lives in /gd/gnu/lib.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C Library 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with the GNU C Library; see the file COPYING.LIB. If not,
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
/*
* modified July 9, 1999 by mark gates <mgates@nlanr.net>
* Dec 17, 1999
*
* renamed all functions and variables by prepending "gnu_"
* removed/redid a bunch of stuff under the assumption we're
* using a modern standard C compiler.
*
* $Id: gnu_getopt.h,v 1.1.1.1 2004/05/18 01:50:44 kgibbs Exp $
*/
#ifndef _GETOPT_H
#define _GETOPT_H 1
#ifdef __cplusplus
extern "C" {
#endif
/* For communication from `gnu_getopt' to the caller.
When `gnu_getopt' finds an option that takes an argument,
the argument value is returned here.
Also, when `ordering' is RETURN_IN_ORDER,
each non-option ARGV-element is returned here. */
extern char *gnu_optarg;
/* Index in ARGV of the next element to be scanned.
This is used for communication to and from the caller
and for communication between successive calls to `gnu_getopt'.
On entry to `gnu_getopt', zero means this is the first call; initialize.
When `gnu_getopt' returns -1, this is the index of the first of the
non-option elements that the caller should itself scan.
Otherwise, `gnu_optind' communicates from one call to the next
how much of ARGV has been scanned so far. */
extern int gnu_optind;
/* Callers store zero here to inhibit the error message `gnu_getopt' prints
for unrecognized options. */
extern int gnu_opterr;
/* Set to an option character which was unrecognized. */
extern int gnu_optopt;
/* Describe the long-named options requested by the application.
The LONG_OPTIONS argument to gnu_getopt_long or getopt_long_only is a vector
of `struct option' terminated by an element containing a name which is
zero.
The field `has_arg' is:
no_argument (or 0) if the option does not take an argument,
required_argument (or 1) if the option requires an argument,
optional_argument (or 2) if the option takes an optional argument.
If the field `flag' is not NULL, it points to a variable that is set
to the value given in the field `val' when the option is found, but
left unchanged if the option is not found.
To have a long-named option do something other than set an `int' to
a compiled-in constant, such as set a value from `gnu_optarg', set the
option's `flag' field to zero and its `val' field to a nonzero
value (the equivalent single-letter option character, if there is
one). For long options that have a zero `flag' field, `gnu_getopt'
returns the contents of the `val' field. */
/* has_arg can't be an enum because some compilers complain about
type mismatches in all the code that assumes it is an int. */
struct option {
const char *name;
int has_arg;
int *flag;
int val;
};
/* Names for the values of the `has_arg' field of `struct option'. */
#define no_argument 0
#define required_argument 1
#define optional_argument 2
int gnu_getopt( int argc,
char *const *argv,
const char *shortopts );
int gnu_getopt_long( int argc,
char *const *argv,
const char *shortopts,
const struct option *longopts,
int *longind );
int gnu_getopt_long_only( int argc,
char *const *argv,
const char *shortopts,
const struct option *longopts,
int *longind );
/* Internal only. Users should not call this directly. */
int _gnu_getopt_internal( int argc,
char *const *argv,
const char *shortopts,
const struct option *longopts,
int *longind,
int long_only );
#ifdef __cplusplus
} /* end extern "C" */
#endif
#endif /* _GETOPT_H */

202
include/headers.h Normal file
View File

@ -0,0 +1,202 @@
/*---------------------------------------------------------------
* Copyright (c) 1999,2000,2001,2002,2003
* The Board of Trustees of the University of Illinois
* All Rights Reserved.
*---------------------------------------------------------------
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software (Iperf) 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:
*
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and
* the following disclaimers.
*
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimers in the documentation and/or other materials
* provided with the distribution.
*
*
* Neither the names of the University of Illinois, NCSA,
* nor the names of its contributors may be used to endorse
* or promote products derived from this Software without
* specific prior written permission.
*
* 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 CONTIBUTORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* ________________________________________________________________
* National Laboratory for Applied Network Research
* National Center for Supercomputing Applications
* University of Illinois at Urbana-Champaign
* http://www.ncsa.uiuc.edu
* ________________________________________________________________
*
* headers.h
* by Mark Gates <mgates@nlanr.net>
* -------------------------------------------------------------------
* All system headers required by iperf.
* This could be processed to form a single precompiled header,
* to avoid overhead of compiling it multiple times.
* This also verifies a few things are defined, for portability.
* ------------------------------------------------------------------- */
#ifndef HEADERS_H
#define HEADERS_H
#ifdef HAVE_CONFIG_H
#include "config.h"
/* OSF1 (at least the system I use) needs extern C
* around the <netdb.h> and <arpa/inet.h> files. */
#if defined( SPECIAL_OSF1_EXTERN ) && defined( __cplusplus )
#define SPECIAL_OSF1_EXTERN_C_START extern "C" {
#define SPECIAL_OSF1_EXTERN_C_STOP }
#else
#define SPECIAL_OSF1_EXTERN_C_START
#define SPECIAL_OSF1_EXTERN_C_STOP
#endif
#endif /* HAVE_CONFIG_H */
/* turn off assert debugging */
#define NDEBUG
/* standard C headers */
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include <ctype.h>
#include <errno.h>
#include <string.h>
#include <time.h>
#include <math.h>
#ifdef WIN32
/* Windows config file */
#include "config.win32.h"
/* Windows headers */
#define _WIN32_WINNT 0x0400 /* use (at least) WinNT 4.0 API */
#define WIN32_LEAN_AND_MEAN /* exclude unnecesary headers */
#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
/* define EINTR, just to help compile; it isn't useful */
#ifndef EINTR
#define EINTR WSAEINTR
#endif // EINTR
/* Visual C++ has INT64, but not 'long long'.
* Metrowerks has 'long long', but INT64 doesn't work. */
#ifdef __MWERKS__
#define int64_t long long
#else
#define int64_t INT64
#endif // __MWERKS__
/* Visual C++ has _snprintf instead of snprintf */
#ifndef __MWERKS__
#define snprintf _snprintf
#endif // __MWERKS__
/* close, read, and write only work on files in Windows.
* I get away with #defining them because I don't read files. */
#define close( s ) closesocket( s )
#define read( s, b, l ) recv( s, (char*) b, l, 0 )
#define write( s, b, l ) send( s, (char*) b, l, 0 )
#else /* not defined WIN32 */
/* required on AIX for FD_SET (requires bzero).
* often this is the same as <string.h> */
#ifdef HAVE_STRINGS_H
#include <strings.h>
#endif // HAVE_STRINGS_H
/* unix headers */
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <signal.h>
#include <unistd.h>
/** Added for daemonizing the process */
#include <syslog.h>
SPECIAL_OSF1_EXTERN_C_START
#include <netdb.h>
SPECIAL_OSF1_EXTERN_C_STOP
#include <netinet/in.h>
#include <netinet/tcp.h>
SPECIAL_OSF1_EXTERN_C_START
#include <arpa/inet.h> /* netinet/in.h must be before this on SunOS */
SPECIAL_OSF1_EXTERN_C_STOP
#ifdef HAVE_POSIX_THREAD
#include <pthread.h>
#endif // HAVE_POSIX_THREAD
/* used in Win32 for error checking,
* rather than checking rc < 0 as unix usually does */
#define SOCKET_ERROR -1
#define INVALID_SOCKET -1
#endif /* not defined WIN32 */
#ifndef INET6_ADDRSTRLEN
#define INET6_ADDRSTRLEN 40
#endif
#ifndef INET_ADDRSTRLEN
#define INET_ADDRSTRLEN 15
#endif
//#ifdef __cplusplus
#ifdef HAVE_IPV6
#define REPORT_ADDRLEN (INET6_ADDRSTRLEN + 1)
typedef struct sockaddr_storage iperf_sockaddr;
#else
#define REPORT_ADDRLEN (INET_ADDRSTRLEN + 1)
typedef struct sockaddr_in iperf_sockaddr;
#endif
//#endif
/* in case the OS doesn't have these, we provide our own implementations */
#include "gettimeofday.h"
#include "inet_aton.h"
#include "snprintf.h"
#ifndef SHUT_RD
#define SHUT_RD 0
#define SHUT_WR 1
#define SHUT_RDWR 2
#endif // SHUT_RD
#ifdef HAVE_INT64_T
typedef int64_t max_size_t;
#else
typedef unsigned long max_size_t;
#endif // HAVE_INT64_T
#endif /* HEADERS_H */

105
include/inet_aton.h Normal file
View File

@ -0,0 +1,105 @@
/*---------------------------------------------------------------
* Copyright (c) 1999,2000,2001,2002,2003
* The Board of Trustees of the University of Illinois
* All Rights Reserved.
*---------------------------------------------------------------
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software (Iperf) 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:
*
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and
* the following disclaimers.
*
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimers in the documentation and/or other materials
* provided with the distribution.
*
*
* Neither the names of the University of Illinois, NCSA,
* nor the names of its contributors may be used to endorse
* or promote products derived from this Software without
* specific prior written permission.
*
* 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 CONTIBUTORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* ________________________________________________________________
* National Laboratory for Applied Network Research
* National Center for Supercomputing Applications
* University of Illinois at Urbana-Champaign
* http://www.ncsa.uiuc.edu
* ________________________________________________________________
*
* inet_aton.h
*
* Mark Gates <mgates@nlanr.net>
* Kevin Gibbs <kgibbs@ncsa.uiuc.edu> Sept. 2002
* to use this prototype, make sure HAVE_INET_PTON is not defined
* to use this prototype, make sure HAVE_INET_NTOP is not defined
*
* =================================================================== */
#ifndef INET_ATON_H
#define INET_ATON_H
#include "headers.h"
/*
* inet_pton is the new, better version of inet_aton.
* inet_aton is not IP version agnostic.
* inet_aton is the new, better version of inet_addr.
* inet_addr is incorrect in that it returns -1 as an error value,
* while -1 (0xFFFFFFFF) is a valid IP address (255.255.255.255).
*/
#ifndef HAVE_INET_NTOP
#ifdef __cplusplus
extern "C" {
#endif
int inet_ntop(int af, const void *src, char *dst, size_t size);
int inet_ntop4(const unsigned char *src, char *dst,
size_t size);
#ifdef HAVE_IPV6
int inet_ntop6(const unsigned char *src, char *dst,
size_t size);
#endif
#ifdef __cplusplus
} /* end extern "C" */
#endif
#endif /* HAVE_INET_NTOP */
#ifndef HAVE_INET_PTON
#ifdef __cplusplus
extern "C" {
#endif
int inet_pton(int af, const char *src, void *dst);
int inet_pton4(const char *src, unsigned char *dst);
#ifdef HAVE_IPV6
int inet_pton6(const char *src, unsigned char *dst);
#endif
#ifdef __cplusplus
} /* end extern "C" */
#endif
#endif /* HAVE_INET_PTON */
#endif /* INET_ATON_H */

62
include/report_CSV.h Normal file
View File

@ -0,0 +1,62 @@
/*---------------------------------------------------------------
* Copyright (c) 1999,2000,2001,2002,2003
* The Board of Trustees of the University of Illinois
* All Rights Reserved.
*---------------------------------------------------------------
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software (Iperf) 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:
*
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and
* the following disclaimers.
*
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimers in the documentation and/or other materials
* provided with the distribution.
*
*
* Neither the names of the University of Illinois, NCSA,
* nor the names of its contributors may be used to endorse
* or promote products derived from this Software without
* specific prior written permission.
*
* 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 CONTIBUTORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* ________________________________________________________________
* National Laboratory for Applied Network Research
* National Center for Supercomputing Applications
* University of Illinois at Urbana-Champaign
* http://www.ncsa.uiuc.edu
* ________________________________________________________________
*
* report_CSV.h
* by Kevin Gibbs <kgibbs@nlanr.net>
*
* ________________________________________________________________ */
#ifndef REPORT_CSV_H
#define REPORT_CSV_H
void CSV_stats( Transfer_Info *stats );
void *CSV_peer( Connection_Info *stats, int ID);
void CSV_serverstats( Connection_Info *conn, Transfer_Info *stats );
#endif // REPORT_CSV_H

64
include/report_default.h Normal file
View File

@ -0,0 +1,64 @@
/*---------------------------------------------------------------
* Copyright (c) 1999,2000,2001,2002,2003
* The Board of Trustees of the University of Illinois
* All Rights Reserved.
*---------------------------------------------------------------
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software (Iperf) 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:
*
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and
* the following disclaimers.
*
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimers in the documentation and/or other materials
* provided with the distribution.
*
*
* Neither the names of the University of Illinois, NCSA,
* nor the names of its contributors may be used to endorse
* or promote products derived from this Software without
* specific prior written permission.
*
* 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 CONTIBUTORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* ________________________________________________________________
* National Laboratory for Applied Network Research
* National Center for Supercomputing Applications
* University of Illinois at Urbana-Champaign
* http://www.ncsa.uiuc.edu
* ________________________________________________________________
*
* report_default.h
* by Kevin Gibbs <kgibbs@nlanr.net>
*
* ________________________________________________________________ */
#ifndef REPORT_DEFAULT_H
#define REPORT_DEFAULT_H
void reporter_printstats( Transfer_Info *stats );
void reporter_multistats( Transfer_Info *stats );
void reporter_serverstats( Connection_Info *conn, Transfer_Info *stats );
void reporter_reportsettings( ReporterData *stats );
void *reporter_reportpeer( Connection_Info *stats, int ID);
#endif // REPORT_DEFAULT_H

159
include/service.h Normal file
View File

@ -0,0 +1,159 @@
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (C) 1993-1997 Microsoft Corporation. All Rights Reserved.
//
// MODULE: service.h
//
// AUTHOR: Craig Link
//
//
// Comments: The use of this header file and the accompanying service.c
// file simplifies the process of writting a service. You as a developer
// simply need to follow the TODO's outlined in this header file, and
// implement the ServiceStart() and ServiceStop() functions.
//
// There is no need to modify the code in service.c. Just add service.c
// to your project and link with the following libraries...
//
// libcmt.lib kernel32.lib advapi.lib shell32.lib
//
// This code also supports unicode. Be sure to compile both service.c and
// and code #include "service.h" with the same Unicode setting.
//
// Upon completion, your code will have the following command line interface
//
// <service exe> -? to display this list
// <service exe> -install to install the service
// <service exe> -remove to remove the service
// <service exe> -debug <params> to run as a console app for debugging
//
// Note: This code also implements Ctrl+C and Ctrl+Break handlers
// when using the debug option. These console events cause
// your ServiceStop routine to be called
//
// Also, this code only handles the OWN_SERVICE service type
// running in the LOCAL_SYSTEM security context.
//
// To control your service ( start, stop, etc ) you may use the
// Services control panel applet or the NET.EXE program.
//
// To aid in writing/debugging service, the
// SDK contains a utility (MSTOOLS\BIN\SC.EXE) that
// can be used to control, configure, or obtain service status.
// SC displays complete status for any service/driver
// in the service database, and allows any of the configuration
// parameters to be easily changed at the command line.
// For more information on SC.EXE, type SC at the command line.
//
/*
* modified Mar.07, 2002 by Feng Qin <fqin@ncsa.uiuc.edu>
* Mar.15, 2002
*
* removed some functions we don't use at all
* add code to start the service immediately after service is installed
*
* $Id: service.h,v 1.1.1.1 2004/05/18 01:50:44 kgibbs Exp $
*/
#ifndef _SERVICE_H
#define _SERVICE_H
#ifdef __cplusplus
extern "C" {
#endif
//////////////////////////////////////////////////////////////////////////////
//// todo: change to desired strings
////
// name of the executable
#define SZAPPNAME "IPerf"
// internal name of the service
#define SZSERVICENAME "IPerfService"
// displayed name of the service
#define SZSERVICEDISPLAYNAME "IPerf Service"
// list of service dependencies - "dep1\0dep2\0\0"
#define SZDEPENDENCIES ""
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
//// todo: ServiceStart()must be defined by in your code.
//// The service should use ReportStatusToSCMgr to indicate
//// progress. This routine must also be used by StartService()
//// to report to the SCM when the service is running.
////
//// If a ServiceStop procedure is going to take longer than
//// 3 seconds to execute, it should spawn a thread to
//// execute the stop code, and return. Otherwise, the
//// ServiceControlManager will believe that the service has
//// stopped responding
////
VOID ServiceStart(DWORD dwArgc, LPTSTR *lpszArgv);
VOID ServiceStop();
//////////////////////////////////////////////////////////////////////////////
VOID WINAPI service_ctrl(DWORD dwCtrlCode);
VOID WINAPI service_main(DWORD dwArgc, LPTSTR *lpszArgv);
VOID CmdInstallService(int argc, char **argv);
BOOL CmdRemoveService();
BOOL CmdStartService(int argc, char **argv);
LPTSTR GetLastErrorText( LPTSTR lpszBuf, DWORD dwSize );
VOID ServiceStart (DWORD dwArgc, LPTSTR *lpszArgv);
VOID ServiceStop();
//////////////////////////////////////////////////////////////////////////////
//// The following are procedures which
//// may be useful to call within the above procedures,
//// but require no implementation by the user.
//// They are implemented in service.c
//
// FUNCTION: ReportStatusToSCMgr()
//
// PURPOSE: Sets the current status of the service and
// reports it to the Service Control Manager
//
// PARAMETERS:
// dwCurrentState - the state of the service
// dwWin32ExitCode - error code to report
// dwWaitHint - worst case estimate to next checkpoint
//
// RETURN VALUE:
// TRUE - success
// FALSE - failure
//
BOOL ReportStatusToSCMgr(DWORD dwCurrentState, DWORD dwWin32ExitCode, DWORD dwWaitHint);
//
// FUNCTION: AddToMessageLog(LPTSTR lpszMsg)
//
// PURPOSE: Allows any thread to log an error message
//
// PARAMETERS:
// lpszMsg - text for message
//
// RETURN VALUE:
// none
//
void AddToMessageLog(LPTSTR lpszMsg);
//////////////////////////////////////////////////////////////////////////////
#ifdef __cplusplus
}
#endif
#endif

40
include/snprintf.h Normal file
View File

@ -0,0 +1,40 @@
#ifndef SNPRINTF_H
#define SNPRINTF_H
/* ===================================================================
* snprintf.h
*
* This is from
* W. Richard Stevens, 'UNIX Network Programming', Vol 1, 2nd Edition,
* Prentice Hall, 1998.
*
* Mark Gates <mgates@nlanr.net>
* July 1998
*
* to use this prototype, make sure HAVE_SNPRINTF is not defined
*
* =================================================================== */
/*
* Throughout the book I use snprintf() because it's safer than sprintf().
* But as of the time of this writing, not all systems provide this
* function. The function below should only be built on those systems
* that do not provide a real snprintf().
* The function below just acts like sprintf(); it is not safe, but it
* tries to detect overflow.
*/
#ifndef HAVE_SNPRINTF
#ifdef __cplusplus
extern "C" {
#endif
int snprintf(char *buf, size_t size, const char *fmt, ...);
#ifdef __cplusplus
} /* end extern "C" */
#endif
#endif /* HAVE_SNPRINTF */
#endif /* SNPRINTF_H */

199
include/util.h Normal file
View File

@ -0,0 +1,199 @@
/*---------------------------------------------------------------
* Copyright (c) 1999,2000,2001,2002,2003
* The Board of Trustees of the University of Illinois
* All Rights Reserved.
*---------------------------------------------------------------
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software (Iperf) 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:
*
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and
* the following disclaimers.
*
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimers in the documentation and/or other materials
* provided with the distribution.
*
*
* Neither the names of the University of Illinois, NCSA,
* nor the names of its contributors may be used to endorse
* or promote products derived from this Software without
* specific prior written permission.
*
* 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 CONTIBUTORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* ________________________________________________________________
* National Laboratory for Applied Network Research
* National Center for Supercomputing Applications
* University of Illinois at Urbana-Champaign
* http://www.ncsa.uiuc.edu
* ________________________________________________________________
*
* util.h
* by Mark Gates <mgates@nlanr.net>
* -------------------------------------------------------------------
* various C utility functions.
* ------------------------------------------------------------------- */
#ifndef UTIL_H
#define UTIL_H
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#ifdef __cplusplus
extern "C" {
#endif
/* -------------------------------------------------------------------
* set/getsockopt wrappers for SO_RCVBUF and SO_SNDBUF; TCP_MAXSEG
* socket.c
* ------------------------------------------------------------------- */
int setsock_tcp_windowsize( int inSock, int inTCPWin, int inSend );
int getsock_tcp_windowsize( int inSock, int inSend );
void setsock_tcp_mss( int inSock, int inTCPWin );
int getsock_tcp_mss( int inSock );
/* -------------------------------------------------------------------
* signal handlers
* signal.c
* ------------------------------------------------------------------- */
typedef void Sigfunc(int);
void sig_exit( int inSigno );
typedef Sigfunc *SigfuncPtr;
SigfuncPtr my_signal( int inSigno, SigfuncPtr inFunc );
#ifdef WIN32
/* under windows, emulate unix signals */
enum {
SIGINT,
SIGTERM,
SIGPIPE,
_NSIG
};
BOOL WINAPI sig_dispatcher( DWORD type );
#endif
/* -------------------------------------------------------------------
* error handlers
* error.c
* ------------------------------------------------------------------- */
void warn ( const char *inMessage, const char *inFile, int inLine );
void warn_errno( const char *inMessage, const char *inFile, int inLine );
#if defined( HAVE_POSIX_THREAD ) || defined( HAVE_WIN32_THREAD)
#define FAIL( cond, msg, settings ) \
do { \
if ( cond ) { \
warn( msg, __FILE__, __LINE__ ); \
thread_stop(settings); \
} \
} while( 0 )
#else
#define FAIL( cond, msg, settings ) \
do { \
if ( cond ) { \
warn( msg, __FILE__, __LINE__ ); \
exit( 1 ); \
} \
} while( 0 )
#endif
#define WARN( cond, msg ) \
do { \
if ( cond ) { \
warn( msg, __FILE__, __LINE__ ); \
} \
} while( 0 )
#if defined( HAVE_POSIX_THREAD ) || defined( HAVE_WIN32_THREAD)
#define FAIL_errno( cond, msg, settings ) \
do { \
if ( cond ) { \
warn_errno( msg, __FILE__, __LINE__ ); \
thread_stop(settings); \
} \
} while( 0 )
#else
#define FAIL_errno( cond, msg, settings ) \
do { \
if ( cond ) { \
warn_errno( msg, __FILE__, __LINE__ ); \
exit( 1 ); \
} \
} while( 0 )
#endif
#define WARN_errno( cond, msg ) \
do { \
if ( cond ) { \
warn_errno( msg, __FILE__, __LINE__ ); \
} \
} while( 0 )
/* -------------------------------------------------------------------
* initialize buffer to a pattern
* ------------------------------------------------------------------- */
void pattern( char *outBuf, int inBytes );
/* -------------------------------------------------------------------
* input and output numbers, converting with kilo, mega, giga
* stdio.c
* ------------------------------------------------------------------- */
double byte_atof( const char *inString );
max_size_t byte_atoi( const char *inString );
void byte_snprintf( char* outString, int inLen, double inNum, char inFormat );
/* -------------------------------------------------------------------
* redirect the stdout to a specified file
* stdio.c
* ------------------------------------------------------------------- */
void redirect(const char *inOutputFileName);
/* -------------------------------------------------------------------
* delete macro
* ------------------------------------------------------------------- */
#define DELETE_PTR( ptr ) \
do { \
if ( ptr != NULL ) { \
delete ptr; \
ptr = NULL; \
} \
} while( false )
#define DELETE_ARRAY( ptr ) \
do { \
if ( ptr != NULL ) { \
delete [] ptr; \
ptr = NULL; \
} \
} while( false )
#ifdef __cplusplus
} /* end extern "C" */
#endif
#endif /* UTIL_H */

2
include/version.h Normal file
View File

@ -0,0 +1,2 @@
#define IPERF_VERSION "2.0.0"
#define IPERF_VERSION_DATE "23 May 2004"

316
install-sh Executable file
View File

@ -0,0 +1,316 @@
#!/bin/sh
# install - install a program, script, or datafile
scriptversion=2004-02-15.20
# This originates from X11R5 (mit/util/scripts/install.sh), which was
# later released in X11R6 (xc/config/util/install.sh) with the
# following copyright and license.
#
# Copyright (C) 1994 X Consortium
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to
# deal in the Software without restriction, including without limitation the
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
# sell copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
# Except as contained in this notice, the name of the X Consortium shall not
# be used in advertising or otherwise to promote the sale, use or other deal-
# ings in this Software without prior written authorization from the X Consor-
# tium.
#
#
# FSF changes to this file are in the public domain.
#
# Calling this script install-sh is preferred over install.sh, to prevent
# `make' implicit rules from creating a file called install from it
# when there is no Makefile.
#
# This script is compatible with the BSD install script, but was written
# from scratch. It can only install one file at a time, a restriction
# shared with many OS's install programs.
# set DOITPROG to echo to test this script
# Don't use :- since 4.3BSD and earlier shells don't like it.
doit="${DOITPROG-}"
# put in absolute paths if you don't have them in your path; or use env. vars.
mvprog="${MVPROG-mv}"
cpprog="${CPPROG-cp}"
chmodprog="${CHMODPROG-chmod}"
chownprog="${CHOWNPROG-chown}"
chgrpprog="${CHGRPPROG-chgrp}"
stripprog="${STRIPPROG-strip}"
rmprog="${RMPROG-rm}"
mkdirprog="${MKDIRPROG-mkdir}"
transformbasename=
transform_arg=
instcmd="$mvprog"
chmodcmd="$chmodprog 0755"
chowncmd=
chgrpcmd=
stripcmd=
rmcmd="$rmprog -f"
mvcmd="$mvprog"
src=
dst=
dir_arg=
usage="Usage: $0 [OPTION]... SRCFILE DSTFILE
or: $0 [OPTION]... SRCFILES... DIRECTORY
or: $0 -d DIRECTORIES...
In the first form, install SRCFILE to DSTFILE, removing SRCFILE by default.
In the second, create the directory path DIR.
Options:
-b=TRANSFORMBASENAME
-c copy source (using $cpprog) instead of moving (using $mvprog).
-d create directories instead of installing files.
-g GROUP $chgrp installed files to GROUP.
-m MODE $chmod installed files to MODE.
-o USER $chown installed files to USER.
-s strip installed files (using $stripprog).
-t=TRANSFORM
--help display this help and exit.
--version display version info and exit.
Environment variables override the default commands:
CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG
"
while test -n "$1"; do
case $1 in
-b=*) transformbasename=`echo $1 | sed 's/-b=//'`
shift
continue;;
-c) instcmd=$cpprog
shift
continue;;
-d) dir_arg=true
shift
continue;;
-g) chgrpcmd="$chgrpprog $2"
shift
shift
continue;;
--help) echo "$usage"; exit 0;;
-m) chmodcmd="$chmodprog $2"
shift
shift
continue;;
-o) chowncmd="$chownprog $2"
shift
shift
continue;;
-s) stripcmd=$stripprog
shift
continue;;
-t=*) transformarg=`echo $1 | sed 's/-t=//'`
shift
continue;;
--version) echo "$0 $scriptversion"; exit 0;;
*) # When -d is used, all remaining arguments are directories to create.
test -n "$dir_arg" && break
# Otherwise, the last argument is the destination. Remove it from $@.
for arg
do
if test -n "$dstarg"; then
# $@ is not empty: it contains at least $arg.
set fnord "$@" "$dstarg"
shift # fnord
fi
shift # arg
dstarg=$arg
done
break;;
esac
done
if test -z "$1"; 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
for src
do
# Protect names starting with `-'.
case $src in
-*) src=./$src ;;
esac
if test -n "$dir_arg"; then
dst=$src
src=
if test -d "$dst"; then
instcmd=:
chmodcmd=
else
instcmd=$mkdirprog
fi
else
# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
# might cause directories to be created, which would be especially bad
# if $src (and thus $dsttmp) contains '*'.
if test ! -f "$src" && test ! -d "$src"; then
echo "$0: $src does not exist." >&2
exit 1
fi
if test -z "$dstarg"; then
echo "$0: no destination specified." >&2
exit 1
fi
dst=$dstarg
# 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
dst=$dst/`basename "$src"`
fi
fi
# This sed command emulates the dirname command.
dstdir=`echo "$dst" | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
# Make sure that the destination directory exists.
# Skip lots of stat calls in the usual case.
if test ! -d "$dstdir"; then
defaultIFS='
'
IFS="${IFS-$defaultIFS}"
oIFS=$IFS
# Some sh's can't handle IFS=/ for some reason.
IFS='%'
set - `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'`
IFS=$oIFS
pathcomp=
while test $# -ne 0 ; do
pathcomp=$pathcomp$1
shift
if test ! -d "$pathcomp"; then
$mkdirprog "$pathcomp" || lasterr=$?
# mkdir can fail with a `File exist' error in case several
# install-sh are creating the directory concurrently. This
# is OK.
test ! -d "$pathcomp" && { (exit ${lasterr-1}); exit; }
fi
pathcomp=$pathcomp/
done
fi
if test -n "$dir_arg"; then
$doit $instcmd "$dst" \
&& { test -z "$chowncmd" || $doit $chowncmd "$dst"; } \
&& { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } \
&& { test -z "$stripcmd" || $doit $stripcmd "$dst"; } \
&& { test -z "$chmodcmd" || $doit $chmodcmd "$dst"; }
else
# If we're going to rename the final executable, determine the name now.
if test -z "$transformarg"; then
dstfile=`basename "$dst"`
else
dstfile=`basename "$dst" $transformbasename \
| sed $transformarg`$transformbasename
fi
# don't allow the sed command to completely eliminate the filename.
test -z "$dstfile" && dstfile=`basename "$dst"`
# 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 'status=$?; rm -f "$dsttmp" "$rmtmp" && exit $status' 0
trap '(exit $?); exit' 1 2 13 15
# Move or copy the file name to the temp name
$doit $instcmd "$src" "$dsttmp" &&
# and set any options; do chmod last to preserve setuid bits.
#
# If any of these fail, we abort the whole thing. If we want to
# ignore errors from any of these, just make sure not to ignore
# errors from the above "$doit $instcmd $src $dsttmp" command.
#
{ test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } \
&& { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } \
&& { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } \
&& { test -z "$chmodcmd" || $doit $chmodcmd "$dsttmp"; } &&
# Now remove or move aside any old file at destination location. We
# try this two ways since rm can't unlink itself on some systems and
# the destination file might be busy for other reasons. In this case,
# the final cleanup might fail but the new file should still install
# successfully.
{
if test -f "$dstdir/$dstfile"; then
$doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null \
|| $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null \
|| {
echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2
(exit 1); exit
}
else
:
fi
} &&
# Now rename the file to the real destination.
$doit $mvcmd "$dsttmp" "$dstdir/$dstfile"
fi || { (exit 1); exit; }
done
# The final little trick to "correctly" pass the exit status to the exit trap.
{
(exit 0); exit
}
# Local variables:
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-end: "$"
# End:

178
m4/dast.m4 Normal file
View File

@ -0,0 +1,178 @@
dnl DAST_CHECK_BOOL
dnl Check for bool support. Defines bool, true, and false.
AH_TEMPLATE([HAVE_POSIX_THREAD], [])
AH_TEMPLATE([_REENTRANT], [])
AH_TEMPLATE([ssize_t], [Define to "int" if <sys/types.h> does not define.])
AH_TEMPLATE([bool])
AH_TEMPLATE([true])
AH_TEMPLATE([false])
AC_DEFUN(DAST_CHECK_BOOL, [
AC_CHECK_SIZEOF(bool)
if test "$ac_cv_sizeof_bool" = 0 ; then
AC_DEFINE(bool, int)
fi
AC_CACHE_CHECK(if true is defined, ac_cv_have_true,
[AC_LANG_SAVE
AC_LANG_CPLUSPLUS
AC_TRY_COMPILE([],
[unsigned int i = true],
ac_cv_have_true=yes,
ac_cv_have_true=no)
AC_LANG_RESTORE
])
if test "$ac_cv_have_true" != yes ; then
AC_DEFINE(true, 1)
AC_DEFINE(false, 0)
fi
])
dnl ===================================================================
dnl DAST_REPLACE_TYPE( type, sizeof )
dnl Check for the type as AC_CHECK_TYPE does. Define HAVE_<type>
dnl if type exists; don't define <type> to anything if it doesn't exist.
dnl Useful if there is no well-defined default type, such as int32_t
AC_DEFUN(DAST_REPLACE_TYPE, [
AC_CACHE_CHECK(for $1, ac_cv_type_$1,
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[$ac_includes_default]],
[[$1 foo]])],
ac_cv_type_$1=yes,
ac_cv_type_$1=no)
if test $ac_cv_type_$1 != yes ; then
if test "$ac_cv_sizeof_char" = $2; then
ac_cv_type_$1="char"
elif test "$ac_cv_sizeof_short" = $2; then
ac_cv_type_$1="short"
elif test "$ac_cv_sizeof_int" = $2; then
ac_cv_type_$1="int"
elif test "$ac_cv_sizeof_long" = $2; then
ac_cv_type_$1="long"
elif test "$ac_cv_sizeof_long_long" = $2; then
ac_cv_type_$1="long long"
fi
fi)
if test "$ac_cv_type_$1" != no; then
if test "$ac_cv_type_$1" != yes; then
AC_DEFINE_UNQUOTED($1, $ac_cv_type_$1)
fi
AC_DEFINE_UNQUOTED(HAVE_`echo $1 | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`)
fi
])
AC_DEFUN(DAST_REPLACE_TYPE_UNSIGNED, [
AC_CACHE_CHECK(for $1, ac_cv_type_$1,
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[$ac_includes_default]],
[[$1 foo]])],
ac_cv_type_$1=yes,
ac_cv_type_$1=no)
if test $ac_cv_type_$1 != yes ; then
if test "$ac_cv_sizeof_unsigned_char" = $2; then
ac_cv_type_$1="unsigned char"
elif test "$ac_cv_sizeof_unsigned_short" = $2; then
ac_cv_type_$1="unsigned short"
elif test "$ac_cv_sizeof_unsigned_int" = $2; then
ac_cv_type_$1="unsigned int"
elif test "$ac_cv_sizeof_unsigned_long" = $2; then
ac_cv_type_$1="unsigned long"
elif test "$ac_cv_sizeof_unsigned_long_long" = $2; then
ac_cv_type_$1="unsigned long long"
fi
fi)
if test "$ac_cv_type_$1" != no; then
if test "$ac_cv_type_$1" != yes; then
AC_DEFINE_UNQUOTED($1, $ac_cv_type_$1)
fi
AC_DEFINE_UNQUOTED(HAVE_`echo $1 | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`)
fi
])
dnl DAST_CHECK_ARG
dnl Check for the 3rd arguement to accept
AC_DEFUN(DAST_ACCEPT_ARG, [
if test -z "$ac_cv_accept_arg" ; then
AC_LANG_SAVE
AC_LANG_CPLUSPLUS
AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
[[$ac_includes_default
#include <sys/socket.h>]],
[[$1 length;
accept( 0, 0, &length );]])],
ac_cv_accept_arg=$1)
AC_LANG_RESTORE
fi
])
dnl Configure paths for Web100. Based off of Owen Taylor's gtk.m4 from gtk+-1.2.10
dnl AM_PATH_WEB100([EXACT-VERSION [, ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]])
dnl Test for Web100, and define WEB100_CFLAGS and WEB100_LIBS
dnl
AC_DEFUN(AM_PATH_WEB100,
[
web100_success=""
AC_PATH_PROG([WEB100_CONFIG], [web100-config], [no])
AC_MSG_CHECKING(for Web100)
if test "$WEB100_CONFIG" != "no"; then
WEB100_CFLAGS=`$WEB100_CONFIG --cflags`
WEB100_LIBS=`$WEB100_CONFIG --libs`
AC_MSG_RESULT(yes)
else
AC_MSG_RESULT(no)
echo "*** The web100-config script installed by Web100 could not be found"
echo "*** If Web100 was installed in PREFIX, make sure PREFIX/bin is in"
echo "*** your path, or set the WEB100_CONFIG environment variable to the"
echo "*** full path to web100-config"
web100_success="no"
fi
if test x$web100_success = x; then
if test "x$1" != "x"; then
AC_MSG_CHECKING(for Web100 - version $1)
WEB100_VERSION=`$WEB100_CONFIG --version`
if test "$WEB100_VERSION" = "$1"; then
AC_MSG_RESULT(yes)
else
AC_MSG_RESULT(no)
echo "*** The requested ($1) and installed ($WEB100_VERSION) versions"
echo "*** of Web100 do not match."
web100_success="no"
fi
fi
fi
if test x$web100_success = x; then
web100_success="yes"
fi
if test x$web100_success = xyes; then
m4_if([$2], [], [:], [$2])
else
WEB100_CFLAGS=""
WEB100_LIBS=""
m4_if([$3], [], [:], [$3])
fi
AC_SUBST(WEB100_CFLAGS)
AC_SUBST(WEB100_LIBS)
])

360
missing Executable file
View File

@ -0,0 +1,360 @@
#! /bin/sh
# Common stub for a few missing GNU programs while installing.
scriptversion=2003-09-02.23
# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003
# Free Software Foundation, Inc.
# Originally by Fran,cois Pinard <pinard@iro.umontreal.ca>, 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
msg="missing on your system"
case "$1" in
--run)
# Try to run requested program, and just exit if it succeeds.
run=
shift
"$@" && exit 0
# Exit code 63 means version mismatch. This often happens
# when the user try to use an ancient version of a tool on
# a file that requires a minimum version. In this case we
# we should proceed has if the program had been absent, or
# if --run hadn't been passed.
if test $? = 63; then
run=:
msg="probably too old"
fi
;;
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]
Send bug reports to <bug-automake@gnu.org>."
;;
-v|--v|--ve|--ver|--vers|--versi|--versio|--version)
echo "missing $scriptversion (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 $msg. 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 $msg. 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 $msg. 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 $msg. 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, but is $msg.
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' $msg. 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 $msg. 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 $msg. 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 $msg. 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 is $msg.
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
# Local variables:
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-end: "$"
# End:

378
src/Client.cpp Normal file
View File

@ -0,0 +1,378 @@
/*---------------------------------------------------------------
* Copyright (c) 1999,2000,2001,2002,2003
* The Board of Trustees of the University of Illinois
* All Rights Reserved.
*---------------------------------------------------------------
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software (Iperf) 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:
*
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and
* the following disclaimers.
*
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimers in the documentation and/or other materials
* provided with the distribution.
*
*
* Neither the names of the University of Illinois, NCSA,
* nor the names of its contributors may be used to endorse
* or promote products derived from this Software without
* specific prior written permission.
*
* 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 CONTIBUTORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* ________________________________________________________________
* National Laboratory for Applied Network Research
* National Center for Supercomputing Applications
* University of Illinois at Urbana-Champaign
* http://www.ncsa.uiuc.edu
* ________________________________________________________________
*
* Client.cpp
* by Mark Gates <mgates@nlanr.net>
* -------------------------------------------------------------------
* A client thread initiates a connect to the server and handles
* sending and receiving data, then closes the socket.
* ------------------------------------------------------------------- */
#include "headers.h"
#include "Client.hpp"
#include "Thread.h"
#include "SocketAddr.h"
#include "PerfSocket.hpp"
#include "Extractor.h"
#include "delay.hpp"
#include "util.h"
#include "Locale.h"
/* -------------------------------------------------------------------
* Store server hostname, optionally local hostname, and socket info.
* ------------------------------------------------------------------- */
Client::Client( thread_Settings *inSettings ) {
mSettings = inSettings;
mBuf = NULL;
// initialize buffer
mBuf = new char[ mSettings->mBufLen ];
pattern( mBuf, mSettings->mBufLen );
if ( isFileInput( mSettings ) ) {
if ( !isSTDIN( mSettings ) )
Extractor_Initialize( mSettings->mFileName, mSettings->mBufLen, mSettings );
else
Extractor_InitializeFile( stdin, mSettings->mBufLen, mSettings );
if ( !Extractor_canRead( mSettings ) ) {
unsetFileInput( mSettings );
}
}
// connect
Connect( );
if ( isReport( inSettings ) ) {
ReportSettings( inSettings );
if ( mSettings->multihdr && isMultipleReport( inSettings ) ) {
mSettings->multihdr->report->connection.peer = mSettings->peer;
mSettings->multihdr->report->connection.size_peer = mSettings->size_peer;
mSettings->multihdr->report->connection.local = mSettings->local;
SockAddr_setPortAny( &mSettings->multihdr->report->connection.local );
mSettings->multihdr->report->connection.size_local = mSettings->size_local;
}
}
} // end Client
/* -------------------------------------------------------------------
* Delete memory (hostname strings).
* ------------------------------------------------------------------- */
Client::~Client() {
if ( mSettings->mSock != INVALID_SOCKET ) {
int rc = close( mSettings->mSock );
WARN_errno( rc == SOCKET_ERROR, "close" );
mSettings->mSock = INVALID_SOCKET;
}
DELETE_ARRAY( mBuf );
} // end ~Client
const double kSecs_to_usecs = 1e6;
const int kBytes_to_Bits = 8;
/* -------------------------------------------------------------------
* Send data using the connected UDP/TCP socket,
* until a termination flag is reached.
* Does not close the socket.
* ------------------------------------------------------------------- */
void Client::Run( void ) {
struct UDP_datagram* mBuf_UDP = (struct UDP_datagram*) mBuf;
long currLen = 0;
int delay_target = 0;
int delay = 0;
int adjust = 0;
char* readAt = mBuf;
// Indicates if the stream is readable
bool canRead = true, mMode_Time = isModeTime( mSettings );
// setup termination variables
if ( mMode_Time ) {
mEndTime.setnow();
mEndTime.add( mSettings->mAmount / 100.0 );
}
if ( isUDP( mSettings ) ) {
// Due to the UDP timestamps etc, included
// reduce the read size by an amount
// equal to the header size
// compute delay for bandwidth restriction, constrained to [0,1] seconds
delay_target = (int) ( mSettings->mBufLen * ((kSecs_to_usecs * kBytes_to_Bits)
/ mSettings->mUDPRate) );
if ( delay_target < 0 ||
delay_target > (int) 1 * kSecs_to_usecs ) {
fprintf( stderr, warn_delay_large, delay_target / kSecs_to_usecs );
delay_target = (int) kSecs_to_usecs * 1;
}
if ( isFileInput( mSettings ) ) {
if ( isCompat( mSettings ) ) {
Extractor_reduceReadSize( sizeof(struct UDP_datagram), mSettings );
readAt += sizeof(struct UDP_datagram);
} else {
Extractor_reduceReadSize( sizeof(struct UDP_datagram) +
sizeof(struct client_hdr), mSettings );
readAt += sizeof(struct UDP_datagram) +
sizeof(struct client_hdr);
}
}
}
ReportStruct *reportstruct = NULL;
// InitReport handles Barrier for multiple Streams
mSettings->reporthdr = InitReport( mSettings );
reportstruct = new ReportStruct;
reportstruct->packetID = 0;
lastPacketTime.setnow();
do {
// Test case: drop 17 packets and send 2 out-of-order:
// sequence 51, 52, 70, 53, 54, 71, 72
//switch( datagramID ) {
// case 53: datagramID = 70; break;
// case 71: datagramID = 53; break;
// case 55: datagramID = 71; break;
// default: break;
//}
gettimeofday( &(reportstruct->packetTime), NULL );
if ( isUDP( mSettings ) ) {
// store datagram ID into buffer
mBuf_UDP->id = htonl( (reportstruct->packetID)++ );
mBuf_UDP->tv_sec = htonl( reportstruct->packetTime.tv_sec );
mBuf_UDP->tv_usec = htonl( reportstruct->packetTime.tv_usec );
// delay between writes
// make an adjustment for how long the last loop iteration took
// TODO this doesn't work well in certain cases, like 2 parallel streams
adjust = delay_target + lastPacketTime.subUsec( reportstruct->packetTime );
lastPacketTime.set( reportstruct->packetTime.tv_sec,
reportstruct->packetTime.tv_usec );
if ( adjust > 0 || delay > 0 ) {
delay += adjust;
}
}
// Read the next data block from
// the file if it's file input
if ( isFileInput( mSettings ) ) {
Extractor_getNextDataBlock( readAt, mSettings );
canRead = Extractor_canRead( mSettings ) != 0;
} else
canRead = true;
// perform write
currLen = write( mSettings->mSock, mBuf, mSettings->mBufLen );
if ( currLen < 0 ) {
WARN_errno( currLen < 0, "write2" );
break;
}
// report packets
reportstruct->packetLen = currLen;
ReportPacket( mSettings->reporthdr, reportstruct );
if ( delay > 0 ) {
delay_loop( delay );
}
if ( !mMode_Time ) {
mSettings->mAmount -= currLen;
}
} while ( ! (sInterupted ||
(mMode_Time && mEndTime.before( reportstruct->packetTime )) ||
(!mMode_Time && 0 >= mSettings->mAmount)) && canRead );
// stop timing
gettimeofday( &(reportstruct->packetTime), NULL );
CloseReport( mSettings->reporthdr, reportstruct );
if ( isUDP( mSettings ) ) {
// send a final terminating datagram
// Don't count in the mTotalLen. The server counts this one,
// but didn't count our first datagram, so we're even now.
// The negative datagram ID signifies termination to the server.
// store datagram ID into buffer
mBuf_UDP->id = htonl( -(reportstruct->packetID) );
mBuf_UDP->tv_sec = htonl( reportstruct->packetTime.tv_sec );
mBuf_UDP->tv_usec = htonl( reportstruct->packetTime.tv_usec );
if ( isMulticast( mSettings ) ) {
write( mSettings->mSock, mBuf, mSettings->mBufLen );
} else {
write_UDP_FIN( );
}
}
DELETE_PTR( reportstruct );
EndReport( mSettings->reporthdr );
}
// end Run
void Client::InitiateServer() {
if ( !isCompat( mSettings ) ) {
int currLen;
client_hdr* temp_hdr;
if ( isUDP( mSettings ) ) {
UDP_datagram *UDPhdr = (UDP_datagram *)mBuf;
temp_hdr = (client_hdr*)(UDPhdr + 1);
} else {
temp_hdr = (client_hdr*)mBuf;
}
Settings_GenerateClientHdr( mSettings, temp_hdr );
if ( !isUDP( mSettings ) ) {
currLen = send( mSettings->mSock, mBuf, sizeof(client_hdr), 0 );
if ( currLen < 0 ) {
WARN_errno( currLen < 0, "write1" );
}
}
}
}
/* -------------------------------------------------------------------
* Setup a socket connected to a server.
* If inLocalhost is not null, bind to that address, specifying
* which outgoing interface to use.
* ------------------------------------------------------------------- */
void Client::Connect( ) {
int rc;
SockAddr_remoteAddr( mSettings );
assert( mSettings->inHostname != NULL );
// create an internet socket
int type = ( isUDP( mSettings ) ? SOCK_DGRAM : SOCK_STREAM);
int domain = (SockAddr_isIPv6( &mSettings->peer ) ?
#ifdef HAVE_IPV6
AF_INET6
#else
AF_INET
#endif
: AF_INET);
mSettings->mSock = socket( domain, type, 0 );
WARN_errno( mSettings->mSock == INVALID_SOCKET, "socket" );
SetSocketOptions( mSettings );
SockAddr_localAddr( mSettings );
if ( mSettings->mLocalhost != NULL ) {
// bind socket to local address
rc = bind( mSettings->mSock, (sockaddr*) &mSettings->local,
SockAddr_get_sizeof_sockaddr( &mSettings->local ) );
WARN_errno( rc == SOCKET_ERROR, "bind" );
}
// connect socket
rc = connect( mSettings->mSock, (sockaddr*) &mSettings->peer,
SockAddr_get_sizeof_sockaddr( &mSettings->peer ));
WARN_errno( rc == SOCKET_ERROR, "connect" );
getsockname( mSettings->mSock, (sockaddr*) &mSettings->local,
&mSettings->size_local );
getpeername( mSettings->mSock, (sockaddr*) &mSettings->peer,
&mSettings->size_peer );
} // end Connect
/* -------------------------------------------------------------------
* Send a datagram on the socket. The datagram's contents should signify
* a FIN to the application. Keep re-transmitting until an
* acknowledgement datagram is received.
* ------------------------------------------------------------------- */
void Client::write_UDP_FIN( ) {
int rc;
fd_set readSet;
struct timeval timeout;
int count = 0;
while ( count < 10 ) {
count++;
// write data
write( mSettings->mSock, mBuf, mSettings->mBufLen );
// wait until the socket is readable, or our timeout expires
FD_ZERO( &readSet );
FD_SET( mSettings->mSock, &readSet );
timeout.tv_sec = 0;
timeout.tv_usec = 250000; // quarter second, 250 ms
rc = select( mSettings->mSock+1, &readSet, NULL, NULL, &timeout );
FAIL_errno( rc == SOCKET_ERROR, "select", mSettings );
if ( rc == 0 ) {
// select timed out
continue;
} else {
// socket ready to read
rc = read( mSettings->mSock, mBuf, mSettings->mBufLen );
WARN_errno( rc < 0, "read" );
if ( rc < 0 ) {
break;
} else if ( rc >= (int) (sizeof(UDP_datagram) + sizeof(server_hdr)) ) {
ReportServerUDP( mSettings, (server_hdr*) ((UDP_datagram*)mBuf + 1) );
}
return;
}
}
fprintf( stderr, warn_no_ack, mSettings->mSock, count );
}
// end write_UDP_FIN

188
src/Extractor.c Normal file
View File

@ -0,0 +1,188 @@
/*---------------------------------------------------------------
* Copyright (c) 1999,2000,2001,2002,2003
* The Board of Trustees of the University of Illinois
* All Rights Reserved.
*---------------------------------------------------------------
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software (Iperf) 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:
*
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and
* the following disclaimers.
*
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimers in the documentation and/or other materials
* provided with the distribution.
*
*
* Neither the names of the University of Illinois, NCSA,
* nor the names of its contributors may be used to endorse
* or promote products derived from this Software without
* specific prior written permission.
*
* 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 CONTIBUTORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* ________________________________________________________________
* National Laboratory for Applied Network Research
* National Center for Supercomputing Applications
* University of Illinois at Urbana-Champaign
* http://www.ncsa.uiuc.edu
* ________________________________________________________________
* Extractor.cpp
* by Ajay Tirumala (tirumala@ncsa.uiuc.edu)
* -------------------------------------------------------------------
* Extract data from a file, used to measure the transfer rates
* for various stream formats.
*
* E.g. Use a gzipped file to measure the transfer rates for
* compressed data
* Use an MPEG file to measure the transfer rates of
* Multimedia data formats
* Use a plain BMP file to measure the transfer rates of
* Uncompressed data
*
* This is beneficial especially in measuring bandwidth across WAN
* links where data compression takes place before data transmission
* -------------------------------------------------------------------
*/
#include "Extractor.h"
/**
* Constructor
* @arg fileName Name of the file
* @arg size Block size for reading
* Open the file and set the block size
*/
void Extractor_Initialize ( char *fileName, int inSize, thread_Settings *mSettings ) {
if ( (mSettings->Extractor_file = fopen (fileName, "rb")) == NULL ) {
fprintf( stderr, "Unable to open the file stream\n");
fprintf( stderr, "Will use the default data stream\n");
return;
}
mSettings->Extractor_size = inSize;
}
/**
* Constructor
* @arg fp File Pointer
* @arg size Block size for reading
* Set the block size,file pointer
*/
void Extractor_InitializeFile ( FILE *fp, int inSize, thread_Settings *mSettings ) {
mSettings->Extractor_file = fp;
mSettings->Extractor_size = inSize;
}
/**
* Destructor - Close the file
*/
void Extractor_Destroy ( thread_Settings *mSettings ) {
if ( mSettings->Extractor_file != NULL )
fclose( mSettings->Extractor_file );
}
/*
* Fetches the next data block from
* the file
* @arg block Pointer to the data read
* @return Number of bytes read
*/
int Extractor_getNextDataBlock ( char *data, thread_Settings *mSettings ) {
if ( Extractor_canRead( mSettings ) ) {
return(fread( data, 1, mSettings->Extractor_size,
mSettings->Extractor_file ));
}
return 0;
}
/**
* Function which determines whether
* the file stream is still readable
* @return boolean true, if readable; false, if not
*/
int Extractor_canRead ( thread_Settings *mSettings ) {
return(( mSettings->Extractor_file != NULL )
&& !(feof( mSettings->Extractor_file )));
}
/**
* This is used to reduce the read size
* Used in UDP transfer to accomodate the
* the header (timestamp)
* @arg delta Size to reduce
*/
void Extractor_reduceReadSize ( int delta, thread_Settings *mSettings ) {
mSettings->Extractor_size -= delta;
}

171
src/Launch.cpp Normal file
View File

@ -0,0 +1,171 @@
/*---------------------------------------------------------------
* Copyright (c) 1999,2000,2001,2002,2003
* The Board of Trustees of the University of Illinois
* All Rights Reserved.
*---------------------------------------------------------------
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software (Iperf) 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:
*
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and
* the following disclaimers.
*
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimers in the documentation and/or other materials
* provided with the distribution.
*
*
* Neither the names of the University of Illinois, NCSA,
* nor the names of its contributors may be used to endorse
* or promote products derived from this Software without
* specific prior written permission.
*
* 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 CONTIBUTORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* ________________________________________________________________
* National Laboratory for Applied Network Research
* National Center for Supercomputing Applications
* University of Illinois at Urbana-Champaign
* http://www.ncsa.uiuc.edu
* ________________________________________________________________
*
* Launch.cpp
* by Kevin Gibbs <kgibbs@nlanr.net>
* -------------------------------------------------------------------
* Functions to launch new server and client threads from C while
* the server and client are in C++.
* The launch function for reporters is in Reporter.c since it is
* in C and does not need a special launching function.
* ------------------------------------------------------------------- */
#include "headers.h"
#include "Thread.h"
#include "Settings.hpp"
#include "Client.hpp"
#include "Listener.hpp"
#include "Server.hpp"
#include "PerfSocket.hpp"
/*
* listener_spawn is responsible for creating a Listener class
* and launching the listener. It is provided as a means for
* the C thread subsystem to launch the listener C++ object.
*/
void listener_spawn( thread_Settings *thread ) {
Listener *theListener = NULL;
// start up a listener
theListener = new Listener( thread );
#ifndef WIN32
// handling of daemon mode in non-win32 builds
if ( isDaemon( thread ) ) {
theListener->runAsDaemon("iperf",LOG_DAEMON);
}
#endif
// Start listening
theListener->Run();
DELETE_PTR( theListener );
}
/*
* server_spawn is responsible for creating a Server class
* and launching the server. It is provided as a means for
* the C thread subsystem to launch the server C++ object.
*/
void server_spawn( thread_Settings *thread) {
Server *theServer = NULL;
// Start up the server
theServer = new Server( thread );
// Run the test
theServer->Run();
DELETE_PTR( theServer);
}
/*
* client_spawn is responsible for creating a Client class
* and launching the client. It is provided as a means for
* the C thread subsystem to launch the client C++ object.
*/
void client_spawn( thread_Settings *thread ) {
Client *theClient = NULL;
//start up the client
theClient = new Client( thread );
// Let the server know about our settings
theClient->InitiateServer();
// Run the test
theClient->Run();
DELETE_PTR( theClient );
}
/*
* client_init handles multiple threaded connects. It creates
* a listener object if either the dual test or tradeoff were
* specified. It also creates settings structures for all the
* threads and arranges them so they can be managed and started
* via the one settings structure that was passed in.
*/
void client_init( thread_Settings *clients ) {
thread_Settings *itr = NULL;
thread_Settings *next = NULL;
// Set the first thread to report Settings
setReport( clients );
itr = clients;
// See if we need to start a listener as well
Settings_GenerateListenerSettings( clients, &next );
// Create a multiple report header to handle reporting the
// sum of multiple client threads
Mutex_Lock( &groupCond );
groupID--;
clients->multihdr = InitMulti( clients, groupID );
Mutex_Unlock( &groupCond );
#ifdef HAVE_THREAD
if ( next != NULL ) {
// We have threads and we need to start a listener so
// have it ran before the client is launched
itr->runNow = next;
itr = next;
}
#endif
// For each of the needed threads create a copy of the
// provided settings, unsetting the report flag and add
// to the list of threads to start
for (int i = 1; i < clients->mThreads; i++) {
Settings_Copy( clients, &next );
unsetReport( next );
itr->runNow = next;
itr = next;
}
#ifndef HAVE_THREAD
if ( next != NULL ) {
// We don't have threads and we need to start a listener so
// have it ran after the client is finished
itr->runNext = next;
}
#endif
}

134
src/List.cpp Normal file
View File

@ -0,0 +1,134 @@
/*---------------------------------------------------------------
* Copyright (c) 1999,2000,2001,2002,2003
* The Board of Trustees of the University of Illinois
* All Rights Reserved.
*---------------------------------------------------------------
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software (Iperf) 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:
*
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and
* the following disclaimers.
*
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimers in the documentation and/or other materials
* provided with the distribution.
*
*
* Neither the names of the University of Illinois, NCSA,
* nor the names of its contributors may be used to endorse
* or promote products derived from this Software without
* specific prior written permission.
*
* 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 CONTIBUTORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* ________________________________________________________________
* National Laboratory for Applied Network Research
* National Center for Supercomputing Applications
* University of Illinois at Urbana-Champaign
* http://www.ncsa.uiuc.edu
* ________________________________________________________________
*
* List.cpp
* by Kevin Gibbs <kgibbs@ncsa.uiuc.edu>
* -------------------------------------------------------------------
*/
#include "List.h"
#include "Mutex.h"
#include "SocketAddr.h"
/*
* Global List and Mutex variables
*/
Iperf_ListEntry *clients = NULL;
Mutex clients_mutex;
/*
* Add Entry add to the List
*/
void Iperf_pushback ( Iperf_ListEntry *add, Iperf_ListEntry **root ) {
add->next = *root;
*root = add;
}
/*
* Delete Entry del from the List
*/
void Iperf_delete ( iperf_sockaddr *del, Iperf_ListEntry **root ) {
Iperf_ListEntry *temp = Iperf_present( del, *root );
if ( temp != NULL ) {
if ( temp == *root ) {
*root = (*root)->next;
} else {
Iperf_ListEntry *itr = *root;
while ( itr->next != NULL ) {
if ( itr->next == temp ) {
itr->next = itr->next->next;
break;
}
itr = itr->next;
}
}
delete temp;
}
}
/*
* Destroy the List (cleanup function)
*/
void Iperf_destroy ( Iperf_ListEntry **root ) {
Iperf_ListEntry *itr1 = *root, *itr2;
while ( itr1 != NULL ) {
itr2 = itr1->next;
delete itr1;
itr1 = itr2;
}
*root = NULL;
}
/*
* Check if the exact Entry find is present
*/
Iperf_ListEntry* Iperf_present ( iperf_sockaddr *find, Iperf_ListEntry *root ) {
Iperf_ListEntry *itr = root;
while ( itr != NULL ) {
if ( SockAddr_are_Equal( (sockaddr*)itr, (sockaddr*)find ) ) {
return itr;
}
itr = itr->next;
}
return NULL;
}
/*
* Check if a Entry find is in the List or if any
* Entry exists that has the same host as the
* Entry find
*/
Iperf_ListEntry* Iperf_hostpresent ( iperf_sockaddr *find, Iperf_ListEntry *root ) {
Iperf_ListEntry *itr = root;
while ( itr != NULL ) {
if ( SockAddr_Hostare_Equal( (sockaddr*)itr, (sockaddr*)find ) ) {
return itr;
}
itr = itr->next;
}
return NULL;
}

716
src/Listener.cpp Normal file
View File

@ -0,0 +1,716 @@
/*---------------------------------------------------------------
* Copyright (c) 1999,2000,2001,2002,2003
* The Board of Trustees of the University of Illinois
* All Rights Reserved.
*---------------------------------------------------------------
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software (Iperf) 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:
*
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and
* the following disclaimers.
*
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimers in the documentation and/or other materials
* provided with the distribution.
*
*
* Neither the names of the University of Illinois, NCSA,
* nor the names of its contributors may be used to endorse
* or promote products derived from this Software without
* specific prior written permission.
*
* 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 CONTIBUTORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* ________________________________________________________________
* National Laboratory for Applied Network Research
* National Center for Supercomputing Applications
* University of Illinois at Urbana-Champaign
* http://www.ncsa.uiuc.edu
* ________________________________________________________________
*
* Listener.cpp
* by Mark Gates <mgates@nlanr.net>
* & Ajay Tirumala <tirumala@ncsa.uiuc.edu>
* -------------------------------------------------------------------
* Listener sets up a socket listening on the server host. For each
* connected socket that accept() returns, this creates a Server
* socket and spawns a thread for it.
*
* Changes to the latest version. Listener will run as a daemon
* Multicast Server is now Multi-threaded
* -------------------------------------------------------------------
* headers
* uses
* <stdlib.h>
* <stdio.h>
* <string.h>
* <errno.h>
*
* <sys/types.h>
* <unistd.h>
*
* <netdb.h>
* <netinet/in.h>
* <sys/socket.h>
* ------------------------------------------------------------------- */
#define HEADERS()
#include "headers.h"
#include "Listener.hpp"
#include "SocketAddr.h"
#include "PerfSocket.hpp"
#include "List.h"
#include "util.h"
/* -------------------------------------------------------------------
* Stores local hostname and socket info.
* ------------------------------------------------------------------- */
Listener::Listener( thread_Settings *inSettings ) {
mClients = inSettings->mThreads;
mBuf = NULL;
mSettings = inSettings;
// initialize buffer
mBuf = new char[ mSettings->mBufLen ];
// open listening socket
Listen( );
ReportSettings( inSettings );
} // end Listener
/* -------------------------------------------------------------------
* Delete memory (buffer).
* ------------------------------------------------------------------- */
Listener::~Listener() {
if ( mSettings->mSock != INVALID_SOCKET ) {
int rc = close( mSettings->mSock );
WARN_errno( rc == SOCKET_ERROR, "close" );
mSettings->mSock = INVALID_SOCKET;
}
DELETE_ARRAY( mBuf );
} // end ~Listener
/* -------------------------------------------------------------------
* Listens for connections and starts Servers to handle data.
* For TCP, each accepted connection spawns a Server thread.
* For UDP, handle all data in this thread for Win32 Only, otherwise
* spawn a new Server thread.
* ------------------------------------------------------------------- */
void Listener::Run( void ) {
#ifdef WIN32
if ( isUDP( mSettings ) && !isSingleUDP( mSettings ) ) {
UDPSingleServer();
} else
#else
#ifdef sun
if ( ( isUDP( mSettings ) &&
isMulticast( mSettings ) &&
!isSingleUDP( mSettings ) ) ||
isSingleUDP( mSettings ) ) {
UDPSingleServer();
} else
#else
if ( isSingleUDP( mSettings ) ) {
UDPSingleServer();
} else
#endif
#endif
{
bool client = false, UDP = isUDP( mSettings ), mCount = (mSettings->mThreads != 0);
thread_Settings *tempSettings = NULL;
Iperf_ListEntry *exist, *listtemp;
client_hdr* hdr = ( UDP ? (client_hdr*) (((UDP_datagram*)mBuf) + 1) :
(client_hdr*) mBuf);
if ( mSettings->mHost != NULL ) {
client = true;
SockAddr_remoteAddr( mSettings );
}
Settings_Copy( mSettings, &server );
server->mThreadMode = kMode_Server;
// Accept each packet,
// If there is no existing client, then start
// a new thread to service the new client
// The listener runs in a single thread
// Thread per client model is followed
do {
// Get a new socket
Accept( server );
if ( server->mSock == INVALID_SOCKET ) {
break;
}
if ( sInterupted != 0 ) {
close( server->mSock );
break;
}
// Reset Single Client Stuff
if ( isSingleClient( mSettings ) && clients == NULL ) {
mSettings->peer = server->peer;
mClients--;
client = true;
// Once all the server threads exit then quit
// Must keep going in case this client sends
// more streams
if ( mClients == 0 ) {
thread_release_nonterm( 0 );
mClients = 1;
}
}
// Verify that it is allowed
if ( client ) {
if ( !SockAddr_Hostare_Equal( (sockaddr*) &mSettings->peer,
(sockaddr*) &server->peer ) ) {
// Not allowed try again
close( server->mSock );
if ( isUDP( mSettings ) ) {
mSettings->mSock = -1;
Listen();
}
continue;
}
}
// Create an entry for the connection list
listtemp = new Iperf_ListEntry;
memcpy(listtemp, &server->peer, sizeof(iperf_sockaddr));
listtemp->next = NULL;
// See if we need to do summing
Mutex_Lock( &clients_mutex );
exist = Iperf_hostpresent( &server->peer, clients);
if ( exist != NULL ) {
// Copy group ID
listtemp->holder = exist->holder;
server->multihdr = exist->holder;
} else {
server->mThreads = 0;
Mutex_Lock( &groupCond );
groupID--;
listtemp->holder = InitMulti( server, groupID );
server->multihdr = listtemp->holder;
Mutex_Unlock( &groupCond );
}
// Store entry in connection list
Iperf_pushback( listtemp, &clients );
Mutex_Unlock( &clients_mutex );
tempSettings = NULL;
if ( !isCompat( mSettings ) && !isMulticast( mSettings ) ) {
if ( !UDP ) {
// TCP does not have the info yet
if ( recv( server->mSock, (char*)hdr, sizeof(client_hdr), 0) > 0 ) {
Settings_GenerateClientSettings( server, &tempSettings,
hdr );
}
} else {
Settings_GenerateClientSettings( server, &tempSettings,
hdr );
}
}
if ( tempSettings != NULL ) {
client_init( tempSettings );
if ( tempSettings->mMode == kTest_DualTest ) {
#ifdef HAVE_THREAD
server->runNow = tempSettings;
#else
server->runNext = tempSettings;
#endif
} else {
server->runNext = tempSettings;
}
}
// Start the server
#if defined(WIN32) && defined(HAVE_THREAD)
if ( UDP ) {
// WIN32 does bad UDP handling so run single threaded
if ( server->runNow != NULL ) {
thread_start( server->runNow );
}
server_spawn( server );
if ( server->runNext != NULL ) {
thread_start( server->runNext );
}
} else
#endif
thread_start( server );
// create a new socket
if ( UDP ) {
mSettings->mSock = -1;
Listen( );
}
// Prep for next connection
if ( !isSingleClient( mSettings ) ) {
mClients--;
}
Settings_Copy( mSettings, &server );
server->mThreadMode = kMode_Server;
} while ( !sInterupted && (!mCount || ( mCount && mClients > 0 )) );
Settings_Destroy( server );
}
} // end Run
/* -------------------------------------------------------------------
* Setup a socket listening on a port.
* For TCP, this calls bind() and listen().
* For UDP, this just calls bind().
* If inLocalhost is not null, bind to that address rather than the
* wildcard server address, specifying what incoming interface to
* accept connections on.
* ------------------------------------------------------------------- */
void Listener::Listen( ) {
int rc;
SockAddr_localAddr( mSettings );
// create an internet TCP socket
int type = (isUDP( mSettings ) ? SOCK_DGRAM : SOCK_STREAM);
int domain = (SockAddr_isIPv6( &mSettings->local ) ?
#ifdef HAVE_IPV6
AF_INET6
#else
AF_INET
#endif
: AF_INET);
#ifdef WIN32
if ( SockAddr_isMulticast( &mSettings->local ) ) {
// Multicast on Win32 requires special handling
mSettings->mSock = WSASocket( domain, type, 0, 0, 0, WSA_FLAG_MULTIPOINT_C_LEAF | WSA_FLAG_MULTIPOINT_D_LEAF );
WARN_errno( mSettings->mSock == INVALID_SOCKET, "socket" );
} else
#endif
{
mSettings->mSock = socket( domain, type, 0 );
WARN_errno( mSettings->mSock == INVALID_SOCKET, "socket" );
}
SetSocketOptions( mSettings );
// reuse the address, so we can run if a former server was killed off
int boolean = 1;
Socklen_t len = sizeof(boolean);
setsockopt( mSettings->mSock, SOL_SOCKET, SO_REUSEADDR, (char*) &boolean, len );
// bind socket to server address
#ifdef WIN32
if ( SockAddr_isMulticast( &mSettings->local ) ) {
// Multicast on Win32 requires special handling
rc = WSAJoinLeaf( mSettings->mSock, (sockaddr*) &mSettings->local, mSettings->size_local,0,0,0,0,JL_BOTH);
WARN_errno( rc == SOCKET_ERROR, "WSAJoinLeaf (aka bind)" );
} else
#endif
{
rc = bind( mSettings->mSock, (sockaddr*) &mSettings->local, mSettings->size_local );
WARN_errno( rc == SOCKET_ERROR, "bind" );
}
// listen for connections (TCP only).
// default backlog traditionally 5
if ( !isUDP( mSettings ) ) {
rc = listen( mSettings->mSock, 5 );
WARN_errno( rc == SOCKET_ERROR, "listen" );
}
#ifndef WIN32
// if multicast, join the group
if ( SockAddr_isMulticast( &mSettings->local ) ) {
McastJoin( );
}
#endif
} // end Listen
/* -------------------------------------------------------------------
* Joins the multicast group, with the default interface.
* ------------------------------------------------------------------- */
void Listener::McastJoin( ) {
#ifdef HAVE_MULTICAST
if ( !SockAddr_isIPv6( &mSettings->local ) ) {
struct ip_mreq mreq;
memcpy( &mreq.imr_multiaddr, SockAddr_get_in_addr( &mSettings->local ),
sizeof(mreq.imr_multiaddr));
mreq.imr_interface.s_addr = htonl( INADDR_ANY );
int rc = setsockopt( mSettings->mSock, IPPROTO_IP, IP_ADD_MEMBERSHIP,
(char*) &mreq, sizeof(mreq));
WARN_errno( rc == SOCKET_ERROR, "multicast join" );
}
#ifdef HAVE_IPV6_MULTICAST
else {
struct ipv6_mreq mreq;
memcpy( &mreq.ipv6mr_multiaddr, SockAddr_get_in6_addr( &mSettings->local ),
sizeof(mreq.ipv6mr_multiaddr));
mreq.ipv6mr_interface = 0;
int rc = setsockopt( mSettings->mSock, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP,
(char*) &mreq, sizeof(mreq));
WARN_errno( rc == SOCKET_ERROR, "multicast join" );
}
#endif
#endif
}
// end McastJoin
/* -------------------------------------------------------------------
* Sets the Multicast TTL for outgoing packets.
* ------------------------------------------------------------------- */
void Listener::McastSetTTL( int val ) {
#ifdef HAVE_MULTICAST
if ( !SockAddr_isIPv6( &mSettings->local ) ) {
int rc = setsockopt( mSettings->mSock, IPPROTO_IP, IP_MULTICAST_TTL,
(char*) &val, sizeof(val));
WARN_errno( rc == SOCKET_ERROR, "multicast ttl" );
}
#ifdef HAVE_IPV6_MULTICAST
else {
int rc = setsockopt( mSettings->mSock, IPPROTO_IPV6, IPV6_MULTICAST_HOPS,
(char*) &val, sizeof(val));
WARN_errno( rc == SOCKET_ERROR, "multicast ttl" );
}
#endif
#endif
}
// end McastSetTTL
/* -------------------------------------------------------------------
* After Listen() has setup mSock, this will block
* until a new connection arrives.
* ------------------------------------------------------------------- */
void Listener::Accept( thread_Settings *server ) {
server->size_peer = sizeof(iperf_sockaddr);
if ( isUDP( server ) ) {
/* -------------------------------------------------------------------
* Do the equivalent of an accept() call for UDP sockets. This waits
* on a listening UDP socket until we get a datagram.
* ------------------------------------------------------------------- */
int rc;
Iperf_ListEntry *exist;
int32_t datagramID;
server->mSock = INVALID_SOCKET;
while ( server->mSock == INVALID_SOCKET ) {
rc = recvfrom( mSettings->mSock, mBuf, mSettings->mBufLen, 0,
(struct sockaddr*) &server->peer, &server->size_peer );
FAIL_errno( rc == SOCKET_ERROR, "recvfrom", mSettings );
Mutex_Lock( &clients_mutex );
// Handle connection for UDP sockets.
exist = Iperf_present( &server->peer, clients);
datagramID = ntohl( ((UDP_datagram*) mBuf)->id );
if ( exist == NULL && datagramID >= 0 ) {
server->mSock = mSettings->mSock;
int rc = connect( server->mSock, (struct sockaddr*) &server->peer,
server->size_peer );
FAIL_errno( rc == SOCKET_ERROR, "connect UDP", mSettings );
} else {
server->mSock = INVALID_SOCKET;
}
Mutex_Unlock( &clients_mutex );
}
} else {
// Handles interupted accepts. Returns the newly connected socket.
server->mSock = INVALID_SOCKET;
while ( server->mSock == INVALID_SOCKET ) {
// accept a connection
server->mSock = accept( mSettings->mSock,
(sockaddr*) &server->peer, &server->size_peer );
if ( server->mSock == INVALID_SOCKET && errno == EINTR ) {
continue;
}
}
}
server->size_local = sizeof(iperf_sockaddr);
getsockname( server->mSock, (sockaddr*) &server->local,
&server->size_local );
} // end Accept
void Listener::UDPSingleServer( ) {
bool client = false, UDP = isUDP( mSettings ), mCount = (mSettings->mThreads != 0);
thread_Settings *tempSettings = NULL;
Iperf_ListEntry *exist, *listtemp;
int rc;
int32_t datagramID;
client_hdr* hdr = ( UDP ? (client_hdr*) (((UDP_datagram*)mBuf) + 1) :
(client_hdr*) mBuf);
ReportStruct *reportstruct = new ReportStruct;
if ( mSettings->mHost != NULL ) {
client = true;
SockAddr_remoteAddr( mSettings );
}
Settings_Copy( mSettings, &server );
server->mThreadMode = kMode_Server;
// Accept each packet,
// If there is no existing client, then start
// a new report to service the new client
// The listener runs in a single thread
Mutex_Lock( &clients_mutex );
do {
// Get next packet
while ( sInterupted == 0) {
server->size_peer = sizeof( iperf_sockaddr );
rc = recvfrom( mSettings->mSock, mBuf, mSettings->mBufLen, 0,
(struct sockaddr*) &server->peer, &server->size_peer );
WARN_errno( rc == SOCKET_ERROR, "recvfrom" );
if ( rc == SOCKET_ERROR ) {
return;
}
// Handle connection for UDP sockets.
exist = Iperf_present( &server->peer, clients);
datagramID = ntohl( ((UDP_datagram*) mBuf)->id );
if ( datagramID >= 0 ) {
if ( exist != NULL ) {
// read the datagram ID and sentTime out of the buffer
reportstruct->packetID = datagramID;
reportstruct->sentTime.tv_sec = ntohl( ((UDP_datagram*) mBuf)->tv_sec );
reportstruct->sentTime.tv_usec = ntohl( ((UDP_datagram*) mBuf)->tv_usec );
reportstruct->packetLen = rc;
gettimeofday( &(reportstruct->packetTime), NULL );
ReportPacket( exist->server->reporthdr, reportstruct );
} else {
Mutex_Lock( &groupCond );
groupID--;
server->mSock = -groupID;
Mutex_Unlock( &groupCond );
server->size_local = sizeof(iperf_sockaddr);
getsockname( mSettings->mSock, (sockaddr*) &server->local,
&server->size_local );
break;
}
} else {
if ( exist != NULL ) {
// read the datagram ID and sentTime out of the buffer
reportstruct->packetID = -datagramID;
reportstruct->sentTime.tv_sec = ntohl( ((UDP_datagram*) mBuf)->tv_sec );
reportstruct->sentTime.tv_usec = ntohl( ((UDP_datagram*) mBuf)->tv_usec );
reportstruct->packetLen = rc;
gettimeofday( &(reportstruct->packetTime), NULL );
ReportPacket( exist->server->reporthdr, reportstruct );
// stop timing
gettimeofday( &(reportstruct->packetTime), NULL );
CloseReport( exist->server->reporthdr, reportstruct );
if ( rc > (int) ( sizeof( UDP_datagram )
+ sizeof( server_hdr ) ) ) {
UDP_datagram *UDP_Hdr;
server_hdr *hdr;
UDP_Hdr = (UDP_datagram*) mBuf;
Transfer_Info *stats = GetReport( exist->server->reporthdr );
hdr = (server_hdr*) (UDP_Hdr+1);
hdr->flags = htonl( HEADER_VERSION1 );
hdr->total_len1 = htonl( (long) (stats->TotalLen >> 32) );
hdr->total_len2 = htonl( (long) (stats->TotalLen & 0xFFFFFFFF) );
hdr->stop_sec = htonl( (long) stats->endTime );
hdr->stop_usec = htonl( (long)((stats->endTime - (long)stats->endTime)
* rMillion));
hdr->error_cnt = htonl( stats->cntError );
hdr->outorder_cnt = htonl( stats->cntOutofOrder );
hdr->datagrams = htonl( stats->cntDatagrams );
hdr->jitter1 = htonl( (long) stats->jitter );
hdr->jitter2 = htonl( (long) ((stats->jitter - (long)stats->jitter)
* rMillion) );
}
EndReport( exist->server->reporthdr );
exist->server->reporthdr = NULL;
Iperf_delete( &(exist->server->peer), &clients );
} else if ( rc > (int) ( sizeof( UDP_datagram )
+ sizeof( server_hdr ) ) ) {
UDP_datagram *UDP_Hdr;
server_hdr *hdr;
UDP_Hdr = (UDP_datagram*) mBuf;
hdr = (server_hdr*) (UDP_Hdr+1);
hdr->flags = htonl( 0 );
}
sendto( mSettings->mSock, mBuf, mSettings->mBufLen, 0,
(struct sockaddr*) &server->peer, server->size_peer);
}
}
if ( server->mSock == INVALID_SOCKET ) {
break;
}
if ( sInterupted != 0 ) {
close( server->mSock );
break;
}
// Reset Single Client Stuff
if ( isSingleClient( mSettings ) && clients == NULL ) {
mSettings->peer = server->peer;
mClients--;
client = true;
// Once all the server threads exit then quit
// Must keep going in case this client sends
// more streams
if ( mClients == 0 ) {
thread_release_nonterm( 0 );
mClients = 1;
}
}
// Verify that it is allowed
if ( client ) {
if ( !SockAddr_Hostare_Equal( (sockaddr*) &mSettings->peer,
(sockaddr*) &server->peer ) ) {
// Not allowed try again
connect( mSettings->mSock,
(sockaddr*) &server->peer,
server->size_peer );
close( mSettings->mSock );
mSettings->mSock = -1;
Listen( );
continue;
}
}
// Create an entry for the connection list
listtemp = new Iperf_ListEntry;
memcpy(listtemp, &server->peer, sizeof(iperf_sockaddr));
listtemp->server = server;
listtemp->next = NULL;
// See if we need to do summing
exist = Iperf_hostpresent( &server->peer, clients);
if ( exist != NULL ) {
// Copy group ID
listtemp->holder = exist->holder;
server->multihdr = exist->holder;
} else {
server->mThreads = 0;
Mutex_Lock( &groupCond );
groupID--;
listtemp->holder = InitMulti( server, groupID );
server->multihdr = listtemp->holder;
Mutex_Unlock( &groupCond );
}
// Store entry in connection list
Iperf_pushback( listtemp, &clients );
tempSettings = NULL;
if ( !isCompat( mSettings ) && !isMulticast( mSettings ) ) {
Settings_GenerateClientSettings( server, &tempSettings,
hdr );
}
if ( tempSettings != NULL ) {
client_init( tempSettings );
if ( tempSettings->mMode == kTest_DualTest ) {
#ifdef HAVE_THREAD
thread_start( tempSettings );
#else
server->runNext = tempSettings;
#endif
} else {
server->runNext = tempSettings;
}
}
server->reporthdr = InitReport( server );
// Prep for next connection
if ( !isSingleClient( mSettings ) ) {
mClients--;
}
Settings_Copy( mSettings, &server );
server->mThreadMode = kMode_Server;
} while ( !sInterupted && (!mCount || ( mCount && mClients > 0 )) );
Mutex_Unlock( &clients_mutex );
Settings_Destroy( server );
}
/* --------------------------------------------------------------------
* Run the server as a daemon
* --------------------------------------------------------------------*/
void Listener::runAsDaemon(const char *pname, int facility) {
#ifndef WIN32
pid_t pid;
/* Create a child process & if successful, exit from the parent process */
if ( (pid = fork()) == -1 ) {
fprintf( stderr, "error in first child create\n");
exit(0);
} else if ( pid != 0 ) {
exit(0);
}
/* Try becoming the session leader, once the parent exits */
if ( setsid() == -1 ) { /* Become the session leader */
fprintf( stderr, "Cannot change the session group leader\n");
} else {
}
signal(SIGHUP,SIG_IGN);
/* Now fork() and get released from the terminal */
if ( (pid = fork()) == -1 ) {
fprintf( stderr, "error\n");
exit(0);
} else if ( pid != 0 ) {
exit(0);
}
chdir(".");
fprintf( stderr, "Running Iperf Server as a daemon\n");
fprintf( stderr, "The Iperf daemon process ID : %d\n",((int)getpid()));
fflush(stderr);
fclose(stdin);
#else
fprintf( stderr, "Use the precompiled windows version for service (daemon) option\n");
#endif
}

381
src/Locale.c Normal file
View File

@ -0,0 +1,381 @@
/*---------------------------------------------------------------
* Copyright (c) 1999,2000,2001,2002,2003
* The Board of Trustees of the University of Illinois
* All Rights Reserved.
*---------------------------------------------------------------
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software (Iperf) 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:
*
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and
* the following disclaimers.
*
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimers in the documentation and/or other materials
* provided with the distribution.
*
*
* Neither the names of the University of Illinois, NCSA,
* nor the names of its contributors may be used to endorse
* or promote products derived from this Software without
* specific prior written permission.
*
* 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 CONTIBUTORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* ________________________________________________________________
* National Laboratory for Applied Network Research
* National Center for Supercomputing Applications
* University of Illinois at Urbana-Champaign
* http://www.ncsa.uiuc.edu
* ________________________________________________________________
*
* Locale.c
* by Ajay Tirumala <tirumala@ncsa.uiuc.edu>
* & Mark Gates <mgates@nlanr.net>
* -------------------------------------------------------------------
* Strings and other stuff that is locale specific.
* ------------------------------------------------------------------- */
#include "version.h"
#ifdef HAVE_CONFIG_H
#include "config.h"
#else
#ifdef WIN32
#include "config.win32.h"
#endif
#endif
#ifdef __cplusplus
extern "C" {
#endif
/* -------------------------------------------------------------------
* usage
* ------------------------------------------------------------------- */
const char usage_short[] = "\
Usage: %s [-s|-c host] [options]\n\
Try `%s --help' for more information.\n";
#ifdef WIN32
const char usage_long1[] = "\
Usage: iperf [-s|-c host] [options]\n\
iperf [-h|--help] [-v|--version]\n\
\n\
Client/Server:\n\
-f, --format [kmKM] format to report: Kbits, Mbits, KBytes, MBytes\n\
-i, --interval # seconds between periodic bandwidth reports\n\
-l, --len #[KM] length of buffer to read or write (default 8 KB)\n\
-m, --print_mss print TCP maximum segment size (MTU - TCP/IP header)\n\
-o, --output <filename> output the report or error message to this specified file\n\
-p, --port # server port to listen on/connect to\n\
-u, --udp use UDP rather than TCP\n\
-w, --window #[KM] TCP window size (socket buffer size)\n\
-B, --bind <host> bind to <host>, an interface or multicast address\n\
-C, --compatibility for use with older versions does not sent extra msgs\n\
-M, --mss # set TCP maximum segment size (MTU - 40 bytes)\n\
-N, --nodelay set TCP no delay, disabling Nagle's Algorithm\n\
-V, --IPv6Version Set the domain to IPv6\n\
\n\
Server specific:\n\
-s, --server run in server mode\n\
-U, --single_udp run in single threaded UDP mode\n\
-D, --daemon run the server as a daemon\n\
-R, --remove remove service in win32\n";
const char usage_long2[] = "\
\n\
Client specific:\n\
-b, --bandwidth #[KM] for UDP, bandwidth to send at in bits/sec\n\
(default 1 Mbit/sec, implies -u)\n\
-c, --client <host> run in client mode, connecting to <host>\n\
-d, --dualtest Do a bidirectional test simultaneously\n\
-n, --num #[KM] number of bytes to transmit (instead of -t)\n\
-r, --tradeoff Do a bidirectional test individually\n\
-t, --time # time in seconds to transmit for (default 10 secs)\n\
-F, --fileinput <name> input the data to be transmitted from a file\n\
-I, --stdin input the data to be transmitted from stdin\n\
-L, --listenport # port to recieve bidirectional tests back on\n\
-P, --parallel # number of parallel client threads to run\n\
-T, --ttl # time-to-live, for multicast (default 1)\n\
\n\
Miscellaneous:\n\
-h, --help print this message and quit\n\
-v, --version print version information and quit\n\
\n\
[KM] Indicates options that support a K or M suffix for kilo- or mega-\n\
\n\
The TCP window size option can be set by the environment variable\n\
TCP_WINDOW_SIZE. Most other options can be set by an environment variable\n\
IPERF_<long option name>, such as IPERF_BANDWIDTH.\n\
\n\
Report bugs to <dast@nlanr.net>\n";
#else
const char usage_long[] = "\
Usage: iperf [-s|-c host] [options]\n\
iperf [-h|--help] [-v|--version]\n\
\n\
Client/Server:\n\
-f, --format [kmKM] format to report: Kbits, Mbits, KBytes, MBytes\n\
-i, --interval # seconds between periodic bandwidth reports\n\
-l, --len #[KM] length of buffer to read or write (default 8 KB)\n\
-m, --print_mss print TCP maximum segment size (MTU - TCP/IP header)\n\
-p, --port # server port to listen on/connect to\n\
-u, --udp use UDP rather than TCP\n\
-w, --window #[KM] TCP window size (socket buffer size)\n\
-B, --bind <host> bind to <host>, an interface or multicast address\n\
-C, --compatibility for use with older versions does not sent extra msgs\n\
-M, --mss # set TCP maximum segment size (MTU - 40 bytes)\n\
-N, --nodelay set TCP no delay, disabling Nagle's Algorithm\n\
-V, --IPv6Version Set the domain to IPv6\n\
\n\
Server specific:\n\
-s, --server run in server mode\n\
-U, --single_udp run in single threaded UDP mode\n\
-D, --daemon run the server as a daemon\n\
\n\
Client specific:\n\
-b, --bandwidth #[KM] for UDP, bandwidth to send at in bits/sec\n\
(default 1 Mbit/sec, implies -u)\n\
-c, --client <host> run in client mode, connecting to <host>\n\
-d, --dualtest Do a bidirectional test simultaneously\n\
-n, --num #[KM] number of bytes to transmit (instead of -t)\n\
-r, --tradeoff Do a bidirectional test individually\n\
-t, --time # time in seconds to transmit for (default 10 secs)\n\
-F, --fileinput <name> input the data to be transmitted from a file\n\
-I, --stdin input the data to be transmitted from stdin\n\
-L, --listenport # port to recieve bidirectional tests back on\n\
-P, --parallel # number of parallel client threads to run\n\
-T, --ttl # time-to-live, for multicast (default 1)\n\
\n\
Miscellaneous:\n\
-h, --help print this message and quit\n\
-v, --version print version information and quit\n\
\n\
[KM] Indicates options that support a K or M suffix for kilo- or mega-\n\
\n\
The TCP window size option can be set by the environment variable\n\
TCP_WINDOW_SIZE. Most other options can be set by an environment variable\n\
IPERF_<long option name>, such as IPERF_BANDWIDTH.\n\
\n\
Report bugs to <dast@nlanr.net>\n";
#endif
// include a description of the threading in the version
#if defined( HAVE_POSIX_THREAD )
#define IPERF_THREADS "pthreads"
#elif defined( HAVE_WIN32_THREAD )
#define IPERF_THREADS "win32 threads"
#else
#define IPERF_THREADS "single threaded"
#endif
const char version[] =
"iperf version " IPERF_VERSION " (" IPERF_VERSION_DATE ") " IPERF_THREADS "\n";
/* -------------------------------------------------------------------
* settings
* ------------------------------------------------------------------- */
const char seperator_line[] =
"------------------------------------------------------------\n";
const char server_port[] =
"Server listening on %s port %d\n";
const char client_port[] =
"Client connecting to %s, %s port %d\n";
const char bind_address[] =
"Binding to local address %s\n";
const char multicast_ttl[] =
"Setting multicast TTL to %d\n";
const char join_multicast[] =
"Joining multicast group %s\n";
const char client_datagram_size[] =
"Sending %d byte datagrams\n";
const char server_datagram_size[] =
"Receiving %d byte datagrams\n";
const char tcp_window_size[] =
"TCP window size";
const char udp_buffer_size[] =
"UDP buffer size";
const char window_default[] =
"(default)";
const char wait_server_threads[] =
"Waiting for server threads to complete. Interrupt again to force quit.\n";
/* -------------------------------------------------------------------
* reports
* ------------------------------------------------------------------- */
const char report_read_lengths[] =
"[%3d] Read lengths occurring in more than 5%% of reads:\n";
const char report_read_length_times[] =
"[%3d] %5d bytes read %5d times (%.3g%%)\n";
const char report_bw_header[] =
"[ ID] Interval Transfer Bandwidth\n";
const char report_bw_format[] =
"[%3d] %4.1f-%4.1f sec %ss %ss/sec\n";
const char report_sum_bw_format[] =
"[SUM] %4.1f-%4.1f sec %ss %ss/sec\n";
const char report_bw_jitter_loss_header[] =
"[ ID] Interval Transfer Bandwidth Jitter Lost/Total \
Datagrams\n";
const char report_bw_jitter_loss_format[] =
"[%3d] %4.1f-%4.1f sec %ss %ss/sec %5.3f ms %4d/%5d (%.2g%%)\n";
const char report_sum_bw_jitter_loss_format[] =
"[SUM] %4.1f-%4.1f sec %ss %ss/sec %5.3f ms %4d/%5d (%.2g%%)\n";
const char report_outoforder[] =
"[%3d] %4.1f-%4.1f sec %d datagrams received out-of-order\n";
const char report_sum_outoforder[] =
"[SUM] %4.1f-%4.1f sec %d datagrams received out-of-order\n";
const char report_peer[] =
"[%3d] local %s port %u connected with %s port %u\n";
const char report_mss_unsupported[] =
"[%3d] MSS and MTU size unknown (TCP_MAXSEG not supported by OS?)\n";
const char report_mss[] =
"[%3d] MSS size %d bytes (MTU %d bytes, %s)\n";
const char report_datagrams[] =
"[%3d] Sent %d datagrams\n";
const char report_sum_datagrams[] =
"[SUM] Sent %d datagrams\n";
const char server_reporting[] =
"[%3d] Server Report:\n";
const char reportCSV_peer[] =
"%s,%u,%s,%u";
#ifdef HAVE_QUAD_SUPPORT
#ifdef HAVE_PRINTF_QD
const char reportCSV_bw_format[] =
"%s,%s,%d,%.1f-%.1f,%qd,%qd\n";
const char reportCSV_bw_jitter_loss_format[] =
"%s,%s,%d,%.1f-%.1f,%qd,%qd,%.3f,%d,%d,%.3f,%d\n";
#else // HAVE_PRINTF_QD
const char reportCSV_bw_format[] =
"%s,%s,%d,%.1f-%.1f,%lld,%lld\n";
const char reportCSV_bw_jitter_loss_format[] =
"%s,%s,%d,%.1f-%.1f,%lld,%lld,%.3f,%d,%d,%.3f,%d\n";
#endif // HAVE_PRINTF_QD
#else // HAVE_QUAD_SUPPORT
#ifdef WIN32
const char reportCSV_bw_format[] =
"%s,%s,%d,%.1f-%.1f,%I64d,%I64d\n";
const char reportCSV_bw_jitter_loss_format[] =
"%s,%s,%d,%.1f-%.1f,%I64d,%I64d,%.3f,%d,%d,%.3f,%d\n";
#else
const char reportCSV_bw_format[] =
"%s,%s,%d,%.1f-%.1f,%d,%d\n";
const char reportCSV_bw_jitter_loss_format[] =
"%s,%s,%d,%.1f-%.1f,%d,%d,%.3f,%d,%d,%.3f,%d\n";
#endif //WIN32
#endif //HAVE_QUAD_SUPPORT
/* -------------------------------------------------------------------
* warnings
* ------------------------------------------------------------------- */
const char warn_window_requested[] =
" (WARNING: requested %s)";
const char warn_window_small[] = "\
WARNING: TCP window size set to %d bytes. A small window size\n\
will give poor performance. See the Iperf documentation.\n";
const char warn_delay_large[] =
"WARNING: delay too large, reducing from %.1f to 1.0 seconds.\n";
const char warn_no_pathmtu[] =
"WARNING: Path MTU Discovery may not be enabled.\n";
const char warn_no_ack[]=
"[%3d] WARNING: did not receive ack of last datagram after %d tries.\n";
const char warn_ack_failed[]=
"[%3d] WARNING: ack of last datagram failed after %d tries.\n";
const char warn_fileopen_failed[]=
"WARNING: Unable to open file stream for transfer\n\
Using default data stream. \n";
const char unable_to_change_win[]=
"WARNING: Unable to change the window size\n";
const char opt_estimate[]=
"Optimal Estimate\n";
const char report_interval_small[] =
"WARNING: interval too small, increasing from %3.2f to 0.5 seconds.\n";
const char warn_invalid_server_option[] =
"WARNING: option -%c is not valid for server mode\n";
const char warn_invalid_client_option[] =
"WARNING: option -%c is not valid for client mode\n";
const char warn_invalid_compatibility_option[] =
"WARNING: option -%c is not valid in compatibility mode\n";
const char warn_implied_udp[] =
"WARNING: option -%c implies udp testing\n";
const char warn_implied_compatibility[] =
"WARNING: option -%c has implied compatibility mode\n";
const char warn_buffer_too_small[] =
"WARNING: the UDP buffer was increased to %d for proper operation\n";
const char warn_invalid_single_threaded[] =
"WARNING: option -%c is not valid in single threaded versions\n";
const char warn_invalid_report_style[] =
"WARNING: unknown reporting style \"%s\", switching to default\n";
const char warn_invalid_report[] =
"WARNING: unknown reporting type \"%c\"\n";
#ifdef __cplusplus
} /* end extern "C" */
#endif

33
src/Makefile.am Normal file
View File

@ -0,0 +1,33 @@
bin_PROGRAMS = iperf
LIBCOMPAT_LDADDS = @STRIP_BEGIN@ \
$(top_builddir)/compat/libcompat.a \
@STRIP_END@
AM_CPPFLAGS = @STRIP_BEGIN@ \
-I$(top_srcdir)/include \
@STRIP_END@
iperf_SOURCES = \
Client.cpp \
Extractor.c \
Launch.cpp \
List.cpp \
Listener.cpp \
Locale.c \
PerfSocket.cpp \
ReportCSV.c \
ReportDefault.c \
Reporter.c \
Server.cpp \
Settings.cpp \
SocketAddr.c \
gnu_getopt.c \
gnu_getopt_long.c \
main.cpp \
service.c \
sockets.c \
stdio.c \
tcp_window_size.c
iperf_LDADD = $(LIBCOMPAT_LDADDS)

501
src/Makefile.in Normal file
View File

@ -0,0 +1,501 @@
# Makefile.in generated by automake 1.8.3 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
# 2003, 2004 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@
SOURCES = $(iperf_SOURCES)
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
top_builddir = ..
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
INSTALL = @INSTALL@
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
host_triplet = @host@
bin_PROGRAMS = iperf$(EXEEXT)
subdir = src
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/dast.m4 \
$(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(mkdir_p)
CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
am__installdirs = "$(DESTDIR)$(bindir)"
binPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
PROGRAMS = $(bin_PROGRAMS)
am_iperf_OBJECTS = Client.$(OBJEXT) Extractor.$(OBJEXT) \
Launch.$(OBJEXT) List.$(OBJEXT) Listener.$(OBJEXT) \
Locale.$(OBJEXT) PerfSocket.$(OBJEXT) ReportCSV.$(OBJEXT) \
ReportDefault.$(OBJEXT) Reporter.$(OBJEXT) Server.$(OBJEXT) \
Settings.$(OBJEXT) SocketAddr.$(OBJEXT) gnu_getopt.$(OBJEXT) \
gnu_getopt_long.$(OBJEXT) main.$(OBJEXT) service.$(OBJEXT) \
sockets.$(OBJEXT) stdio.$(OBJEXT) tcp_window_size.$(OBJEXT)
iperf_OBJECTS = $(am_iperf_OBJECTS)
am__DEPENDENCIES_1 = $(top_builddir)/compat/libcompat.a
iperf_DEPENDENCIES = $(am__DEPENDENCIES_1)
DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__depfiles_maybe = depfiles
@AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/Client.Po ./$(DEPDIR)/Extractor.Po \
@AMDEP_TRUE@ ./$(DEPDIR)/Launch.Po ./$(DEPDIR)/List.Po \
@AMDEP_TRUE@ ./$(DEPDIR)/Listener.Po ./$(DEPDIR)/Locale.Po \
@AMDEP_TRUE@ ./$(DEPDIR)/PerfSocket.Po ./$(DEPDIR)/ReportCSV.Po \
@AMDEP_TRUE@ ./$(DEPDIR)/ReportDefault.Po \
@AMDEP_TRUE@ ./$(DEPDIR)/Reporter.Po ./$(DEPDIR)/Server.Po \
@AMDEP_TRUE@ ./$(DEPDIR)/Settings.Po ./$(DEPDIR)/SocketAddr.Po \
@AMDEP_TRUE@ ./$(DEPDIR)/gnu_getopt.Po \
@AMDEP_TRUE@ ./$(DEPDIR)/gnu_getopt_long.Po ./$(DEPDIR)/main.Po \
@AMDEP_TRUE@ ./$(DEPDIR)/service.Po ./$(DEPDIR)/sockets.Po \
@AMDEP_TRUE@ ./$(DEPDIR)/stdio.Po \
@AMDEP_TRUE@ ./$(DEPDIR)/tcp_window_size.Po
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
CCLD = $(CC)
LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
CXXLD = $(CXX)
CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \
-o $@
SOURCES = $(iperf_SOURCES)
DIST_SOURCES = $(iperf_SOURCES)
ETAGS = etags
CTAGS = ctags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMDEP_FALSE = @AMDEP_FALSE@
AMDEP_TRUE = @AMDEP_TRUE@
AMTAR = @AMTAR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CXX = @CXX@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
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@
OBJEXT = @OBJEXT@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
RANLIB = @RANLIB@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
STRIP_BEGIN = @STRIP_BEGIN@
STRIP_DUMMY = @STRIP_DUMMY@
STRIP_END = @STRIP_END@
VERSION = @VERSION@
WEB100_CFLAGS = @WEB100_CFLAGS@
WEB100_CONFIG = @WEB100_CONFIG@
WEB100_LIBS = @WEB100_LIBS@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
ac_ct_RANLIB = @ac_ct_RANLIB@
ac_ct_STRIP = @ac_ct_STRIP@
am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
datadir = @datadir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localstatedir = @localstatedir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
prefix = @prefix@
program_transform_name = @program_transform_name@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
LIBCOMPAT_LDADDS = @STRIP_BEGIN@ \
$(top_builddir)/compat/libcompat.a \
@STRIP_END@
AM_CPPFLAGS = @STRIP_BEGIN@ \
-I$(top_srcdir)/include \
@STRIP_END@
iperf_SOURCES = \
Client.cpp \
Extractor.c \
Launch.cpp \
List.cpp \
Listener.cpp \
Locale.c \
PerfSocket.cpp \
ReportCSV.c \
ReportDefault.c \
Reporter.c \
Server.cpp \
Settings.cpp \
SocketAddr.c \
gnu_getopt.c \
gnu_getopt_long.c \
main.cpp \
service.c \
sockets.c \
stdio.c \
tcp_window_size.c
iperf_LDADD = $(LIBCOMPAT_LDADDS)
all: all-am
.SUFFIXES:
.SUFFIXES: .c .cpp .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 \
&& exit 0; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/Makefile'; \
cd $(top_srcdir) && \
$(AUTOMAKE) --foreign 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
install-binPROGRAMS: $(bin_PROGRAMS)
@$(NORMAL_INSTALL)
test -z "$(bindir)" || $(mkdir_p) "$(DESTDIR)$(bindir)"
@list='$(bin_PROGRAMS)'; for p in $$list; do \
p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
if test -f $$p \
; then \
f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \
echo " $(INSTALL_PROGRAM_ENV) $(binPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(bindir)/$$f'"; \
$(INSTALL_PROGRAM_ENV) $(binPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(bindir)/$$f" || exit 1; \
else :; fi; \
done
uninstall-binPROGRAMS:
@$(NORMAL_UNINSTALL)
@list='$(bin_PROGRAMS)'; for p in $$list; do \
f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \
echo " rm -f '$(DESTDIR)$(bindir)/$$f'"; \
rm -f "$(DESTDIR)$(bindir)/$$f"; \
done
clean-binPROGRAMS:
-test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS)
iperf$(EXEEXT): $(iperf_OBJECTS) $(iperf_DEPENDENCIES)
@rm -f iperf$(EXEEXT)
$(CXXLINK) $(iperf_LDFLAGS) $(iperf_OBJECTS) $(iperf_LDADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT)
distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Client.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Extractor.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Launch.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/List.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Listener.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Locale.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/PerfSocket.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ReportCSV.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ReportDefault.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Reporter.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Server.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Settings.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SocketAddr.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gnu_getopt.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gnu_getopt_long.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/service.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sockets.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stdio.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tcp_window_size.Po@am__quote@
.c.o:
@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(COMPILE) -c $<
.c.obj:
@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \
@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
.cpp.o:
@am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $<
.cpp.obj:
@am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \
@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
uninstall-info-am:
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
mkid -fID $$unique
tags: TAGS
TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
test -z "$(ETAGS_ARGS)$$tags$$unique" \
|| $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$tags $$unique
ctags: CTAGS
CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
test -z "$(CTAGS_ARGS)$$tags$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$tags $$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& cd $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) $$here
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
distdir: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
list='$(DISTFILES)'; for file in $$list; do \
case $$file in \
$(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
$(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
esac; \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
if test "$$dir" != "$$file" && test "$$dir" != "."; then \
dir="/$$dir"; \
$(mkdir_p) "$(distdir)$$dir"; \
else \
dir=''; \
fi; \
if test -d $$d/$$file; then \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
fi; \
cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
else \
test -f $(distdir)/$$file \
|| cp -p $$d/$$file $(distdir)/$$file \
|| exit 1; \
fi; \
done
check-am: all-am
check: check-am
all-am: Makefile $(PROGRAMS)
installdirs:
for dir in "$(DESTDIR)$(bindir)"; do \
test -z "$$dir" || $(mkdir_p) "$$dir"; \
done
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-am
install-strip:
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
`test -z '$(STRIP)' || \
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:
clean-generic:
distclean-generic:
-rm -f $(CONFIG_CLEAN_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-am
clean-am: clean-binPROGRAMS clean-generic mostlyclean-am
distclean: distclean-am
-rm -rf ./$(DEPDIR)
-rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
distclean-tags
dvi: dvi-am
dvi-am:
html: html-am
info: info-am
info-am:
install-data-am:
install-exec-am: install-binPROGRAMS
install-info: install-info-am
install-man:
installcheck-am:
maintainer-clean: maintainer-clean-am
-rm -rf ./$(DEPDIR)
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-compile mostlyclean-generic
pdf: pdf-am
pdf-am:
ps: ps-am
ps-am:
uninstall-am: uninstall-binPROGRAMS uninstall-info-am
.PHONY: CTAGS GTAGS all all-am check check-am clean clean-binPROGRAMS \
clean-generic ctags 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-exec install-exec-am \
install-info install-info-am install-man install-strip \
installcheck installcheck-am installdirs maintainer-clean \
maintainer-clean-generic mostlyclean mostlyclean-compile \
mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \
uninstall-am uninstall-binPROGRAMS uninstall-info-am
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

121
src/PerfSocket.cpp Normal file
View File

@ -0,0 +1,121 @@
/*---------------------------------------------------------------
* Copyright (c) 1999,2000,2001,2002,2003
* The Board of Trustees of the University of Illinois
* All Rights Reserved.
*---------------------------------------------------------------
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software (Iperf) 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:
*
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and
* the following disclaimers.
*
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimers in the documentation and/or other materials
* provided with the distribution.
*
*
* Neither the names of the University of Illinois, NCSA,
* nor the names of its contributors may be used to endorse
* or promote products derived from this Software without
* specific prior written permission.
*
* 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 CONTIBUTORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* ________________________________________________________________
* National Laboratory for Applied Network Research
* National Center for Supercomputing Applications
* University of Illinois at Urbana-Champaign
* http://www.ncsa.uiuc.edu
* ________________________________________________________________
*
* PerfSocket.cpp
* by Mark Gates <mgates@nlanr.net>
* Ajay Tirumala <tirumala@ncsa.uiuc.edu>
* -------------------------------------------------------------------
* Has routines the Client and Server classes use in common for
* performance testing the network.
* Changes in version 1.2.0
* for extracting data from files
* -------------------------------------------------------------------
* headers
* uses
* <stdlib.h>
* <stdio.h>
* <string.h>
*
* <sys/types.h>
* <sys/socket.h>
* <unistd.h>
*
* <arpa/inet.h>
* <netdb.h>
* <netinet/in.h>
* <sys/socket.h>
* ------------------------------------------------------------------- */
#define HEADERS()
#include "headers.h"
#include "PerfSocket.hpp"
#include "util.h"
/* -------------------------------------------------------------------
* Set socket options before the listen() or connect() calls.
* These are optional performance tuning factors.
* ------------------------------------------------------------------- */
void SetSocketOptions( thread_Settings *inSettings ) {
// set the TCP window size (socket buffer sizes)
// also the UDP buffer size
// must occur before call to accept() for large window sizes
setsock_tcp_windowsize( inSettings->mSock, inSettings->mTCPWin,
(inSettings->mThreadMode == kMode_Client ? 1 : 0) );
#ifdef IP_TOS
// set IP TOS (type-of-service) field
if ( inSettings->mTOS > 0 ) {
int tos = inSettings->mTOS;
Socklen_t len = sizeof(tos);
int rc = setsockopt( inSettings->mSock, IPPROTO_IP, IP_TOS,
(char*) &tos, len );
WARN_errno( rc == SOCKET_ERROR, "setsockopt IP_TOS" );
}
#endif
if ( !isUDP( inSettings ) ) {
// set the TCP maximum segment size
setsock_tcp_mss( inSettings->mSock, inSettings->mMSS );
#ifdef TCP_NODELAY
// set TCP nodelay option
if ( isNoDelay( inSettings ) ) {
int nodelay = 1;
Socklen_t len = sizeof(nodelay);
int rc = setsockopt( inSettings->mSock, IPPROTO_TCP, TCP_NODELAY,
(char*) &nodelay, len );
WARN_errno( rc == SOCKET_ERROR, "setsockopt TCP_NODELAY" );
}
#endif
}
}
// end SetSocketOptions

157
src/ReportCSV.c Normal file
View File

@ -0,0 +1,157 @@
/*---------------------------------------------------------------
* Copyright (c) 1999,2000,2001,2002,2003
* The Board of Trustees of the University of Illinois
* All Rights Reserved.
*---------------------------------------------------------------
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software (Iperf) 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:
*
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and
* the following disclaimers.
*
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimers in the documentation and/or other materials
* provided with the distribution.
*
*
* Neither the names of the University of Illinois, NCSA,
* nor the names of its contributors may be used to endorse
* or promote products derived from this Software without
* specific prior written permission.
*
* 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 CONTIBUTORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* ________________________________________________________________
* National Laboratory for Applied Network Research
* National Center for Supercomputing Applications
* University of Illinois at Urbana-Champaign
* http://www.ncsa.uiuc.edu
* ________________________________________________________________
*
* ReportCSV.c
* by Kevin Gibbs <kgibbs@nlanr.net>
*
* ________________________________________________________________ */
#include "headers.h"
#include "Settings.hpp"
#include "util.h"
#include "Reporter.h"
#include "report_CSV.h"
#include "Locale.h"
void CSV_timestamp( char *timestamp, int length );
void CSV_stats( Transfer_Info *stats ) {
// $TIMESTAMP,$ID,$INTERVAL,$BYTE,$SPEED,$JITTER,$LOSS,$PACKET,$%LOSS
max_size_t speed = (max_size_t)(((double)stats->TotalLen * 8.0) / (stats->endTime - stats->startTime));
char timestamp[16];
CSV_timestamp( timestamp, sizeof(timestamp) );
if ( stats->mUDP != (char)kMode_Server ) {
// TCP Reporting
printf( reportCSV_bw_format,
timestamp,
(stats->reserved_delay == NULL ? ",,," : stats->reserved_delay),
stats->transferID,
stats->startTime,
stats->endTime,
stats->TotalLen,
speed);
} else {
// UDP Reporting
printf( reportCSV_bw_jitter_loss_format,
timestamp,
(stats->reserved_delay == NULL ? ",,," : stats->reserved_delay),
stats->transferID,
stats->startTime,
stats->endTime,
stats->TotalLen,
speed,
stats->jitter*1000.0,
stats->cntError,
stats->cntDatagrams,
(100.0 * stats->cntError) / stats->cntDatagrams, stats->cntOutofOrder );
}
if ( stats->free == 1 && stats->reserved_delay != NULL ) {
free( stats->reserved_delay );
}
}
void *CSV_peer( Connection_Info *stats, int ID ) {
// copy the inet_ntop into temp buffers, to avoid overwriting
char local_addr[ REPORT_ADDRLEN ];
char remote_addr[ REPORT_ADDRLEN ];
char *buf = malloc( REPORT_ADDRLEN*2 + 10 );
struct sockaddr *local = ((struct sockaddr*)&stats->local);
struct sockaddr *peer = ((struct sockaddr*)&stats->peer);
if ( local->sa_family == AF_INET ) {
inet_ntop( AF_INET, &((struct sockaddr_in*)local)->sin_addr,
local_addr, REPORT_ADDRLEN);
}
#ifdef HAVE_IPV6
else {
inet_ntop( AF_INET6, &((struct sockaddr_in6*)local)->sin6_addr,
local_addr, REPORT_ADDRLEN);
}
#endif
if ( peer->sa_family == AF_INET ) {
inet_ntop( AF_INET, &((struct sockaddr_in*)peer)->sin_addr,
remote_addr, REPORT_ADDRLEN);
}
#ifdef HAVE_IPV6
else {
inet_ntop( AF_INET6, &((struct sockaddr_in6*)peer)->sin6_addr,
remote_addr, REPORT_ADDRLEN);
}
#endif
snprintf(buf, REPORT_ADDRLEN*2+10, reportCSV_peer,
local_addr, ( local->sa_family == AF_INET ?
ntohs(((struct sockaddr_in*)local)->sin_port) :
#ifdef HAVE_IPV6
ntohs(((struct sockaddr_in6*)local)->sin6_port)),
#else
0),
#endif
remote_addr, ( peer->sa_family == AF_INET ?
ntohs(((struct sockaddr_in*)peer)->sin_port) :
#ifdef HAVE_IPV6
ntohs(((struct sockaddr_in6*)peer)->sin6_port)));
#else
0));
#endif
return buf;
}
void CSV_serverstats( Connection_Info *conn, Transfer_Info *stats ) {
stats->reserved_delay = CSV_peer( conn, stats->transferID );
stats->free = 1;
CSV_stats( stats );
}
void CSV_timestamp( char *timestamp, int length ) {
time_t times;
struct tm *timest;
times = time( NULL );
timest = localtime( &times );
strftime( timestamp, length,"%Y%m%d%H%M%S", timest );
}

294
src/ReportDefault.c Normal file
View File

@ -0,0 +1,294 @@
/*---------------------------------------------------------------
* Copyright (c) 1999,2000,2001,2002,2003
* The Board of Trustees of the University of Illinois
* All Rights Reserved.
*---------------------------------------------------------------
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software (Iperf) 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:
*
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and
* the following disclaimers.
*
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimers in the documentation and/or other materials
* provided with the distribution.
*
*
* Neither the names of the University of Illinois, NCSA,
* nor the names of its contributors may be used to endorse
* or promote products derived from this Software without
* specific prior written permission.
*
* 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 CONTIBUTORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* ________________________________________________________________
* National Laboratory for Applied Network Research
* National Center for Supercomputing Applications
* University of Illinois at Urbana-Champaign
* http://www.ncsa.uiuc.edu
* ________________________________________________________________
*
* ReportDefault.c
* by Kevin Gibbs <kgibbs@nlanr.net>
*
* ________________________________________________________________ */
#include "headers.h"
#include "Settings.hpp"
#include "util.h"
#include "Reporter.h"
#include "report_default.h"
#include "Thread.h"
#include "Locale.h"
#include "PerfSocket.hpp"
#include "SocketAddr.h"
#ifdef __cplusplus
extern "C" {
#endif
/*
* Prints transfer reports in default style
*/
void reporter_printstats( Transfer_Info *stats ) {
byte_snprintf( buffer, sizeof(buffer)/2, (double) stats->TotalLen,
toupper( stats->mFormat));
byte_snprintf( &buffer[sizeof(buffer)/2], sizeof(buffer)/2,
stats->TotalLen / (stats->endTime - stats->startTime),
stats->mFormat);
if ( stats->mUDP != (char)kMode_Server ) {
// TCP Reporting
printf( report_bw_format, stats->transferID,
stats->startTime, stats->endTime,
buffer, &buffer[sizeof(buffer)/2] );
} else {
// UDP Reporting
printf( report_bw_jitter_loss_format, stats->transferID,
stats->startTime, stats->endTime,
buffer, &buffer[sizeof(buffer)/2],
stats->jitter*1000.0, stats->cntError, stats->cntDatagrams,
(100.0 * stats->cntError) / stats->cntDatagrams );
if ( stats->cntOutofOrder > 0 ) {
printf( report_outoforder,
stats->transferID, stats->startTime,
stats->endTime, stats->cntOutofOrder );
}
}
if ( stats->free == 1 && stats->mUDP == (char)kMode_Client ) {
printf( report_datagrams, stats->transferID, stats->cntDatagrams );
}
}
/*
* Prints multiple transfer reports in default style
*/
void reporter_multistats( Transfer_Info *stats ) {
byte_snprintf( buffer, sizeof(buffer)/2, (double) stats->TotalLen,
toupper( stats->mFormat));
byte_snprintf( &buffer[sizeof(buffer)/2], sizeof(buffer)/2,
stats->TotalLen / (stats->endTime - stats->startTime),
stats->mFormat);
if ( stats->mUDP != (char)kMode_Server ) {
// TCP Reporting
printf( report_sum_bw_format,
stats->startTime, stats->endTime,
buffer, &buffer[sizeof(buffer)/2] );
} else {
// UDP Reporting
printf( report_sum_bw_jitter_loss_format,
stats->startTime, stats->endTime,
buffer, &buffer[sizeof(buffer)/2],
stats->jitter*1000.0, stats->cntError, stats->cntDatagrams,
(100.0 * stats->cntError) / stats->cntDatagrams );
if ( stats->cntOutofOrder > 0 ) {
printf( report_sum_outoforder,
stats->startTime,
stats->endTime, stats->cntOutofOrder );
}
}
if ( stats->free == 1 && stats->mUDP == (char)kMode_Client ) {
printf( report_sum_datagrams, stats->cntDatagrams );
}
}
/*
* Prints server transfer reports in default style
*/
void reporter_serverstats( Connection_Info *nused, Transfer_Info *stats ) {
printf( server_reporting, stats->transferID );
reporter_printstats( stats );
}
/*
* Report the client or listener Settings in default style
*/
void reporter_reportsettings( ReporterData *data ) {
int win, win_requested;
win = getsock_tcp_windowsize( data->info.transferID,
(data->mThreadMode == kMode_Listener ? 0 : 1) );
win_requested = data->mTCPWin;
printf( seperator_line );
if ( data->mThreadMode == kMode_Listener ) {
printf( server_port,
(isUDP( data ) ? "UDP" : "TCP"),
data->mPort );
} else {
printf( client_port,
data->mHost,
(isUDP( data ) ? "UDP" : "TCP"),
data->mPort );
}
if ( data->mLocalhost != NULL ) {
printf( bind_address, data->mLocalhost );
if ( SockAddr_isMulticast( &data->connection.local ) ) {
printf( join_multicast, data->mLocalhost );
}
}
if ( isUDP( data ) ) {
printf( (data->mThreadMode == kMode_Listener ?
server_datagram_size : client_datagram_size),
data->mBufLen );
if ( SockAddr_isMulticast( &data->connection.peer ) ) {
printf( multicast_ttl, data->info.mTTL);
}
}
byte_snprintf( buffer, sizeof(buffer), win,
toupper( data->info.mFormat));
printf( "%s: %s", (isUDP( data ) ?
udp_buffer_size : tcp_window_size), buffer );
if ( win_requested == 0 ) {
printf( " %s", window_default );
} else if ( win != win_requested ) {
byte_snprintf( buffer, sizeof(buffer), win_requested,
toupper( data->info.mFormat));
printf( warn_window_requested, buffer );
}
printf( "\n" );
printf( seperator_line );
}
/*
* Report a socket's peer IP address in default style
*/
void *reporter_reportpeer( Connection_Info *stats, int ID ) {
if ( ID > 0 ) {
// copy the inet_ntop into temp buffers, to avoid overwriting
char local_addr[ REPORT_ADDRLEN ];
char remote_addr[ REPORT_ADDRLEN ];
struct sockaddr *local = ((struct sockaddr*)&stats->local);
struct sockaddr *peer = ((struct sockaddr*)&stats->peer);
if ( local->sa_family == AF_INET ) {
inet_ntop( AF_INET, &((struct sockaddr_in*)local)->sin_addr,
local_addr, REPORT_ADDRLEN);
}
#ifdef HAVE_IPV6
else {
inet_ntop( AF_INET6, &((struct sockaddr_in6*)local)->sin6_addr,
local_addr, REPORT_ADDRLEN);
}
#endif
if ( peer->sa_family == AF_INET ) {
inet_ntop( AF_INET, &((struct sockaddr_in*)peer)->sin_addr,
remote_addr, REPORT_ADDRLEN);
}
#ifdef HAVE_IPV6
else {
inet_ntop( AF_INET6, &((struct sockaddr_in6*)peer)->sin6_addr,
remote_addr, REPORT_ADDRLEN);
}
#endif
printf( report_peer,
ID,
local_addr, ( local->sa_family == AF_INET ?
ntohs(((struct sockaddr_in*)local)->sin_port) :
#ifdef HAVE_IPV6
ntohs(((struct sockaddr_in6*)local)->sin6_port)),
#else
0),
#endif
remote_addr, ( peer->sa_family == AF_INET ?
ntohs(((struct sockaddr_in*)peer)->sin_port) :
#ifdef HAVE_IPV6
ntohs(((struct sockaddr_in6*)peer)->sin6_port)));
#else
0));
#endif
}
return NULL;
}
// end ReportPeer
/* -------------------------------------------------------------------
* Report the MSS and MTU, given the MSS (or a guess thereof)
* ------------------------------------------------------------------- */
// compare the MSS against the (MTU - 40) to (MTU - 80) bytes.
// 40 byte IP header and somewhat arbitrarily, 40 more bytes of IP options.
#define checkMSS_MTU( inMSS, inMTU ) (inMTU-40) >= inMSS && inMSS >= (inMTU-80)
void reporter_reportMSS( int inMSS, thread_Settings *inSettings ) {
if ( inMSS <= 0 ) {
printf( report_mss_unsupported, inSettings->mSock );
} else {
char* net;
int mtu = 0;
if ( checkMSS_MTU( inMSS, 1500 ) ) {
net = "ethernet";
mtu = 1500;
} else if ( checkMSS_MTU( inMSS, 4352 ) ) {
net = "FDDI";
mtu = 4352;
} else if ( checkMSS_MTU( inMSS, 9180 ) ) {
net = "ATM";
mtu = 9180;
} else if ( checkMSS_MTU( inMSS, 65280 ) ) {
net = "HIPPI";
mtu = 65280;
} else if ( checkMSS_MTU( inMSS, 576 ) ) {
net = "minimum";
mtu = 576;
printf( warn_no_pathmtu );
} else {
mtu = inMSS + 40;
net = "unknown interface";
}
printf( report_mss,
inSettings->mSock, inMSS, mtu, net );
}
}
// end ReportMSS
#ifdef __cplusplus
} /* end extern "C" */
#endif

908
src/Reporter.c Normal file
View File

@ -0,0 +1,908 @@
/*---------------------------------------------------------------
* Copyright (c) 1999,2000,2001,2002,2003
* The Board of Trustees of the University of Illinois
* All Rights Reserved.
*---------------------------------------------------------------
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software (Iperf) 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:
*
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and
* the following disclaimers.
*
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimers in the documentation and/or other materials
* provided with the distribution.
*
*
* Neither the names of the University of Illinois, NCSA,
* nor the names of its contributors may be used to endorse
* or promote products derived from this Software without
* specific prior written permission.
*
* 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 CONTIBUTORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* ________________________________________________________________
* National Laboratory for Applied Network Research
* National Center for Supercomputing Applications
* University of Illinois at Urbana-Champaign
* http://www.ncsa.uiuc.edu
* ________________________________________________________________
*
* Reporter.c
* by Kevin Gibbs <kgibbs@nlanr.net>
*
* ________________________________________________________________ */
#include "headers.h"
#include "Settings.hpp"
#include "util.h"
#include "Reporter.h"
#include "Thread.h"
#include "Locale.h"
#include "PerfSocket.hpp"
#include "SocketAddr.h"
#ifdef __cplusplus
extern "C" {
#endif
/*
The following 4 functions are provided for Reporting
styles that do not have all the reporting formats. For
instance the provided CSV format does not have a settings
report so it uses settings_notimpl.
*/
void* connection_notimpl( Connection_Info * nused, int nuse ) {
return NULL;
}
void settings_notimpl( ReporterData * nused ) { }
void statistics_notimpl( Transfer_Info * nused ) { }
void serverstatistics_notimpl( Connection_Info *nused1, Transfer_Info *nused2 ) { }
// To add a reporting style include its header here.
#include "report_default.h"
#include "report_CSV.h"
// The following array of report structs contains the
// pointers required for reporting in different reporting
// styles. To add a reporting style add a report struct
// below.
report_connection connection_reports[kReport_MAXIMUM] = {
reporter_reportpeer,
CSV_peer
};
report_settings settings_reports[kReport_MAXIMUM] = {
reporter_reportsettings,
settings_notimpl
};
report_statistics statistics_reports[kReport_MAXIMUM] = {
reporter_printstats,
CSV_stats
};
report_serverstatistics serverstatistics_reports[kReport_MAXIMUM] = {
reporter_serverstats,
CSV_serverstats
};
report_statistics multiple_reports[kReport_MAXIMUM] = {
reporter_multistats,
CSV_stats
};
char buffer[64]; // Buffer for printing
ReportHeader *ReportRoot = NULL;
extern Condition ReportCond;
int reporter_process_report ( ReportHeader *report );
void process_report ( ReportHeader *report );
int reporter_handle_packet( ReportHeader *report );
int reporter_condprintstats( ReporterData *stats, MultiHeader *multireport, int force );
int reporter_print( ReporterData *stats, int type, int end );
void PrintMSS( ReporterData *stats );
MultiHeader* InitMulti( thread_Settings *agent, int inID ) {
MultiHeader *multihdr = NULL;
if ( agent->mThreads > 1 || agent->mThreadMode == kMode_Server ) {
if ( isMultipleReport( agent ) ) {
multihdr = malloc(sizeof(MultiHeader) + sizeof(ReporterData) +
NUM_MULTI_SLOTS * sizeof(Transfer_Info));
} else {
multihdr = malloc(sizeof(MultiHeader));
}
if ( multihdr != NULL ) {
memset( multihdr, 0, sizeof(MultiHeader) );
Condition_Initialize( &multihdr->barrier );
multihdr->groupID = inID;
multihdr->threads = agent->mThreads;
if ( isMultipleReport( agent ) ) {
int i;
ReporterData *data = NULL;
multihdr->report = (ReporterData*)(multihdr + 1);
memset(multihdr->report, 0, sizeof(ReporterData));
multihdr->data = (Transfer_Info*)(multihdr->report + 1);
data = multihdr->report;
for ( i = 0; i < NUM_MULTI_SLOTS; i++ ) {
multihdr->data[i].startTime = -1;
multihdr->data[i].transferID = inID;
multihdr->data[i].groupID = -2;
}
data->type = TRANSFER_REPORT;
if ( agent->mInterval != 0.0 ) {
struct timeval *interval = &data->intervalTime;
interval->tv_sec = (long) agent->mInterval;
interval->tv_usec = (long) ((agent->mInterval - interval->tv_sec)
* rMillion);
}
data->mHost = agent->mHost;
data->mLocalhost = agent->mLocalhost;
data->mBufLen = agent->mBufLen;
data->mMSS = agent->mMSS;
data->mTCPWin = agent->mTCPWin;
data->flags = agent->flags;
data->mThreadMode = agent->mThreadMode;
data->mode = agent->mReportMode;
data->info.mFormat = agent->mFormat;
data->info.mTTL = agent->mTTL;
if ( isUDP( agent ) ) {
multihdr->report->info.mUDP = (char)agent->mThreadMode;
}
if ( isConnectionReport( agent ) ) {
data->type |= CONNECTION_REPORT;
data->connection.peer = agent->peer;
data->connection.size_peer = agent->size_peer;
SockAddr_setPortAny( &data->connection.peer );
data->connection.local = agent->local;
data->connection.size_local = agent->size_local;
SockAddr_setPortAny( &data->connection.local );
}
}
} else {
FAIL(1, "Out of Memory!!\n", agent);
}
}
return multihdr;
}
/*
* BarrierClient allows for multiple stream clients to be syncronized
*/
void BarrierClient( ReportHeader *agent ) {
Condition_Lock(agent->multireport->barrier);
agent->multireport->threads--;
if ( agent->multireport->threads == 0 ) {
// last one set time and wake up everyone
gettimeofday( &(agent->multireport->startTime), NULL );
Condition_Broadcast( &agent->multireport->barrier );
} else {
Condition_Wait( &agent->multireport->barrier );
}
agent->multireport->threads++;
Condition_Unlock( agent->multireport->barrier );
agent->report.startTime = agent->multireport->startTime;
agent->report.nextTime = agent->report.startTime;
TimeAdd( agent->report.nextTime, agent->report.intervalTime );
}
/*
* InitReport is called by a transfer agent (client or
* server) to setup the needed structures to communicate
* traffic.
*/
ReportHeader* InitReport( thread_Settings *agent ) {
ReportHeader *reporthdr = NULL;
ReporterData *data = NULL;
if ( isDataReport( agent ) ) {
/*
* Create in one big chunk
*/
reporthdr = malloc( sizeof(ReportHeader) +
NUM_REPORT_STRUCTS * sizeof(ReportStruct) );
if ( reporthdr != NULL ) {
// Only need to make sure the headers are clean
memset( reporthdr, 0, sizeof(ReportHeader));
reporthdr->data = (ReportStruct*)(reporthdr+1);
reporthdr->multireport = agent->multihdr;
data = &reporthdr->report;
reporthdr->reporterindex = NUM_REPORT_STRUCTS - 1;
data->info.transferID = agent->mSock;
data->info.groupID = (agent->multihdr != NULL ? agent->multihdr->groupID
: -1);
data->type = TRANSFER_REPORT;
if ( agent->mInterval != 0.0 ) {
struct timeval *interval = &data->intervalTime;
interval->tv_sec = (long) agent->mInterval;
interval->tv_usec = (long) ((agent->mInterval - interval->tv_sec)
* rMillion);
}
data->mHost = agent->mHost;
data->mLocalhost = agent->mLocalhost;
data->mBufLen = agent->mBufLen;
data->mMSS = agent->mMSS;
data->mTCPWin = agent->mTCPWin;
data->flags = agent->flags;
data->mThreadMode = agent->mThreadMode;
data->mode = agent->mReportMode;
data->info.mFormat = agent->mFormat;
data->info.mTTL = agent->mTTL;
if ( isUDP( agent ) ) {
reporthdr->report.info.mUDP = (char)agent->mThreadMode;
}
} else {
FAIL(1, "Out of Memory!!\n", agent);
}
}
if ( isConnectionReport( agent ) ) {
if ( reporthdr == NULL ) {
/*
* Create in one big chunk
*/
reporthdr = malloc( sizeof(ReportHeader) );
if ( reporthdr != NULL ) {
// Only need to make sure the headers are clean
memset( reporthdr, 0, sizeof(ReportHeader));
data = &reporthdr->report;
data->info.transferID = agent->mSock;
data->info.groupID = -1;
} else {
FAIL(1, "Out of Memory!!\n", agent);
}
}
if ( reporthdr != NULL ) {
data->type |= CONNECTION_REPORT;
data->connection.peer = agent->peer;
data->connection.size_peer = agent->size_peer;
data->connection.local = agent->local;
data->connection.size_local = agent->size_local;
} else {
FAIL(1, "Out of Memory!!\n", agent);
}
}
if ( isConnectionReport( agent ) || isDataReport( agent ) ) {
#ifdef HAVE_THREAD
/*
* Update the ReportRoot to include this report.
*/
if ( reporthdr->report.mThreadMode == kMode_Client &&
reporthdr->multireport != NULL ) {
// syncronize watches on my mark......
BarrierClient( reporthdr );
} else {
if ( reporthdr->multireport != NULL && isMultipleReport( agent )) {
reporthdr->multireport->threads++;
if ( reporthdr->multireport->report->startTime.tv_sec == 0 ) {
gettimeofday( &(reporthdr->multireport->report->startTime), NULL );
}
reporthdr->report.startTime = reporthdr->multireport->report->startTime;
} else {
// set start time
gettimeofday( &(reporthdr->report.startTime), NULL );
}
reporthdr->report.nextTime = reporthdr->report.startTime;
TimeAdd( reporthdr->report.nextTime, reporthdr->report.intervalTime );
}
Condition_Lock( ReportCond );
reporthdr->next = ReportRoot;
ReportRoot = reporthdr;
Condition_Signal( &ReportCond );
Condition_Unlock( ReportCond );
#else
// set start time
gettimeofday( &(reporthdr->report.startTime), NULL );
/*
* Process the report in this thread
*/
reporthdr->next = NULL;
process_report ( reporthdr );
#endif
}
if ( !isDataReport( agent ) ) {
reporthdr = NULL;
}
return reporthdr;
}
/*
* ReportPacket is called by a transfer agent to record
* the arrival or departure of a "packet" (for TCP it
* will actually represent many packets). This needs to
* be as simple and fast as possible as it gets called for
* every "packet".
*/
void ReportPacket( ReportHeader* agent, ReportStruct *packet ) {
if ( agent != NULL ) {
int index = agent->reporterindex;
/*
* First find the appropriate place to put the information
*/
if ( agent->agentindex == NUM_REPORT_STRUCTS ) {
// Just need to make sure that reporter is not on the first
// item
while ( index == 0 ) {
Condition_Signal( &ReportCond );
thread_rest();
index = agent->reporterindex;
}
agent->agentindex = 0;
}
// Need to make sure that reporter is not about to be "lapped"
while ( index - 1 == agent->agentindex ) {
Condition_Signal( &ReportCond );
thread_rest();
index = agent->reporterindex;
}
// Put the information there
memcpy( agent->data + agent->agentindex, packet, sizeof(ReportStruct) );
// Updating agentindex MUST be the last thing done
agent->agentindex++;
#ifndef HAVE_THREAD
/*
* Process the report in this thread
*/
process_report ( agent );
#endif
}
}
/*
* CloseReport is called by a transfer agent to finalize
* the report and signal transfer is over.
*/
void CloseReport( ReportHeader *agent, ReportStruct *packet ) {
if ( agent != NULL) {
/*
* Using PacketID of -1 ends reporting
*/
packet->packetID = -1;
packet->packetLen = 0;
ReportPacket( agent, packet );
packet->packetID = agent->report.cntDatagrams;
}
}
/*
* EndReport signifies the agent no longer is interested
* in the report. Calls to GetReport will no longer be
* filled
*/
void EndReport( ReportHeader *agent ) {
if ( agent != NULL ) {
int index = agent->reporterindex;
while ( index != -1 ) {
thread_rest();
index = agent->reporterindex;
}
agent->agentindex = -1;
#ifndef HAVE_THREAD
/*
* Process the report in this thread
*/
process_report ( agent );
#endif
}
}
/*
* GetReport is called by the agent after a CloseReport
* but before an EndReport to get the stats generated
* by the reporter thread.
*/
Transfer_Info *GetReport( ReportHeader *agent ) {
int index = agent->reporterindex;
while ( index != -1 ) {
thread_rest();
index = agent->reporterindex;
}
return &agent->report.info;
}
/*
* ReportSettings will generate a summary report for
* settings being used with Listeners or Clients
*/
void ReportSettings( thread_Settings *agent ) {
if ( isSettingsReport( agent ) ) {
/*
* Create in one big chunk
*/
ReportHeader *reporthdr = malloc( sizeof(ReportHeader) );
if ( reporthdr != NULL ) {
ReporterData *data = &reporthdr->report;
data->info.transferID = agent->mSock;
data->info.groupID = -1;
reporthdr->agentindex = -1;
reporthdr->reporterindex = -1;
data->mHost = agent->mHost;
data->mLocalhost = agent->mLocalhost;
data->mode = agent->mReportMode;
data->type = SETTINGS_REPORT;
data->mBufLen = agent->mBufLen;
data->mMSS = agent->mMSS;
data->mTCPWin = agent->mTCPWin;
data->flags = agent->flags;
data->mThreadMode = agent->mThreadMode;
data->mPort = agent->mPort;
data->info.mFormat = agent->mFormat;
data->info.mTTL = agent->mTTL;
data->connection.peer = agent->peer;
data->connection.size_peer = agent->size_peer;
data->connection.local = agent->local;
data->connection.size_local = agent->size_local;
#ifdef HAVE_THREAD
/*
* Update the ReportRoot to include this report.
*/
Condition_Lock( ReportCond );
reporthdr->next = ReportRoot;
ReportRoot = reporthdr;
Condition_Signal( &ReportCond );
Condition_Unlock( ReportCond );
#else
/*
* Process the report in this thread
*/
reporthdr->next = NULL;
process_report ( reporthdr );
#endif
} else {
FAIL(1, "Out of Memory!!\n", agent);
}
}
}
/*
* ReportServerUDP will generate a report of the UDP
* statistics as reported by the server on the client
* side.
*/
void ReportServerUDP( thread_Settings *agent, server_hdr *server ) {
if ( (ntohl(server->flags) & HEADER_VERSION1) != 0 &&
isServerReport( agent ) ) {
/*
* Create in one big chunk
*/
ReportHeader *reporthdr = malloc( sizeof(ReportHeader) );
Transfer_Info *stats = &reporthdr->report.info;
if ( reporthdr != NULL ) {
stats->transferID = agent->mSock;
stats->groupID = (agent->multihdr != NULL ? agent->multihdr->groupID
: -1);
reporthdr->agentindex = -1;
reporthdr->reporterindex = -1;
reporthdr->report.type = SERVER_RELAY_REPORT;
reporthdr->report.mode = agent->mReportMode;
stats->mFormat = agent->mFormat;
stats->jitter = ntohl( server->jitter1 );
stats->jitter += ntohl( server->jitter2 ) / (double)rMillion;
stats->TotalLen = (((max_size_t) ntohl( server->total_len1 )) << 32) +
ntohl( server->total_len2 );
stats->startTime = 0;
stats->endTime = ntohl( server->stop_sec );
stats->endTime += ntohl( server->stop_usec ) / (double)rMillion;
stats->cntError = ntohl( server->error_cnt );
stats->cntOutofOrder = ntohl( server->outorder_cnt );
stats->cntDatagrams = ntohl( server->datagrams );
stats->mUDP = (char)kMode_Server;
reporthdr->report.connection.peer = agent->local;
reporthdr->report.connection.size_peer = agent->size_local;
reporthdr->report.connection.local = agent->peer;
reporthdr->report.connection.size_local = agent->size_peer;
#ifdef HAVE_THREAD
/*
* Update the ReportRoot to include this report.
*/
Condition_Lock( ReportCond );
reporthdr->next = ReportRoot;
ReportRoot = reporthdr;
Condition_Signal( &ReportCond );
Condition_Unlock( ReportCond );
#else
/*
* Process the report in this thread
*/
reporthdr->next = NULL;
process_report ( reporthdr );
#endif
} else {
FAIL(1, "Out of Memory!!\n", agent);
}
}
}
/*
* This function is called only when the reporter thread
* This function is the loop that the reporter thread processes
*/
void reporter_spawn( thread_Settings *thread ) {
do {
// This section allows for safe exiting with Ctrl-C
Condition_Lock ( ReportCond );
if ( ReportRoot == NULL ) {
// Allow main thread to exit if Ctrl-C is received
thread_setignore();
Condition_Wait ( &ReportCond );
// Stop main thread from exiting until done with all reports
thread_unsetignore();
}
Condition_Unlock ( ReportCond );
if ( ReportRoot != NULL ) {
ReportHeader *temp = ReportRoot;
//Condition_Unlock ( ReportCond );
if ( reporter_process_report ( temp ) ) {
// This section allows for more reports to be added while
// the reporter is processing reports without needing to
// stop the reporter or immediately notify it
Condition_Lock ( ReportCond );
if ( temp == ReportRoot ) {
// no new reports
ReportRoot = temp->next;
} else {
// new reports added
ReportHeader *itr = ReportRoot;
while ( itr->next != temp ) {
itr = itr->next;
}
itr->next = temp->next;
}
// finished with report so free it
free( temp );
Condition_Unlock ( ReportCond );
}
// yield control of CPU is another thread is waiting
thread_rest();
} else {
//Condition_Unlock ( ReportCond );
}
} while ( 1 );
}
/*
* Used for single threaded reporting
*/
void process_report ( ReportHeader *report ) {
if ( report != NULL ) {
if ( reporter_process_report( report ) ) {
free( report );
}
}
}
/*
* Process reports starting with "reporthdr"
*/
int reporter_process_report ( ReportHeader *reporthdr ) {
int need_free = 0;
// Recursively process reports
if ( reporthdr->next != NULL ) {
if ( reporter_process_report( reporthdr->next ) ) {
// If we are done with this report then free it
ReportHeader *temp = reporthdr->next;
reporthdr->next = reporthdr->next->next;
free( temp );
}
}
if ( (reporthdr->report.type & SETTINGS_REPORT) != 0 ) {
reporthdr->report.type &= ~SETTINGS_REPORT;
return reporter_print( &reporthdr->report, SETTINGS_REPORT, 1 );
} else if ( (reporthdr->report.type & CONNECTION_REPORT) != 0 ) {
reporthdr->report.type &= ~CONNECTION_REPORT;
reporter_print( &reporthdr->report, CONNECTION_REPORT,
(reporthdr->report.type == 0 ? 1 : 0) );
if ( reporthdr->multireport != NULL && isMultipleReport( (&reporthdr->report) )) {
if ( (reporthdr->multireport->report->type & CONNECTION_REPORT) != 0 ) {
reporthdr->multireport->report->type &= ~CONNECTION_REPORT;
reporter_print( reporthdr->multireport->report, CONNECTION_REPORT,
(reporthdr->report.type == 0 ? 1 : 0) );
}
}
} else if ( (reporthdr->report.type & SERVER_RELAY_REPORT) != 0 ) {
reporthdr->report.type &= ~SERVER_RELAY_REPORT;
return reporter_print( &reporthdr->report, SERVER_RELAY_REPORT, 1 );
}
if ( (reporthdr->report.type & TRANSFER_REPORT) != 0 ) {
// If there are more packets to process then handle them
if ( reporthdr->reporterindex >= 0 ) {
// Need to make sure we do not pass the "agent"
while ( reporthdr->reporterindex != reporthdr->agentindex - 1 ) {
if ( reporthdr->reporterindex == NUM_REPORT_STRUCTS - 1 ) {
if ( reporthdr->agentindex == 0 ) {
break;
} else {
reporthdr->reporterindex = 0;
}
} else {
reporthdr->reporterindex++;
}
if ( reporter_handle_packet( reporthdr ) ) {
// No more packets to process
reporthdr->reporterindex = -1;
break;
}
}
}
// If the agent is done with the report then free it
if ( reporthdr->agentindex == -1 ) {
need_free = 1;
}
}
return need_free;
}
/*
* Updates connection stats
*/
int reporter_handle_packet( ReportHeader *reporthdr ) {
ReportStruct *packet = &reporthdr->data[reporthdr->reporterindex];
ReporterData *data = &reporthdr->report;
Transfer_Info *stats = &reporthdr->report.info;
int finished = 0;
data->cntDatagrams++;
// If this is the last packet set the endTime
if ( packet->packetID < 0 ) {
data->packetTime = packet->packetTime;
finished = 1;
if ( reporthdr->report.mThreadMode != kMode_Client ) {
data->TotalLen += packet->packetLen;
}
} else {
// update recieved amount and time
data->packetTime = packet->packetTime;
reporter_condprintstats( &reporthdr->report, reporthdr->multireport, finished );
data->TotalLen += packet->packetLen;
if ( packet->packetID != 0 ) {
// UDP packet
double transit;
double deltaTransit;
// from RFC 1889, Real Time Protocol (RTP)
// J = J + ( | D(i-1,i) | - J ) / 16
transit = TimeDifference( packet->packetTime, packet->sentTime );
if ( data->lastTransit != 0.0 ) {
deltaTransit = transit - data->lastTransit;
if ( deltaTransit < 0.0 ) {
deltaTransit = -deltaTransit;
}
stats->jitter += (deltaTransit - stats->jitter) / (16.0);
}
data->lastTransit = transit;
// packet loss occured if the datagram numbers aren't sequential
if ( packet->packetID != data->PacketID + 1 ) {
if ( packet->packetID < data->PacketID + 1 ) {
data->cntOutofOrder++;
} else {
data->cntError += packet->packetID - data->PacketID - 1;
}
}
// never decrease datagramID (e.g. if we get an out-of-order packet)
if ( packet->packetID > data->PacketID ) {
data->PacketID = packet->packetID;
}
}
}
// Print a report if appropriate
return reporter_condprintstats( &reporthdr->report, reporthdr->multireport, finished );
}
/*
* Handles summing of threads
*/
void reporter_handle_multiple_reports( MultiHeader *reporthdr, Transfer_Info *stats, int force ) {
if ( reporthdr != NULL ) {
if ( reporthdr->threads > 1 ) {
int i;
Transfer_Info *current = NULL;
// Search for start Time
for ( i = 0; i < NUM_MULTI_SLOTS; i++ ) {
current = &reporthdr->data[i];
if ( current->startTime == stats->startTime ) {
break;
}
}
if ( current->startTime != stats->startTime ) {
// Find first available
for ( i = 0; i < NUM_MULTI_SLOTS; i++ ) {
current = &reporthdr->data[i];
if ( current->startTime < 0 ) {
break;
}
}
current->cntDatagrams = stats->cntDatagrams;
current->cntError = stats->cntError;
current->cntOutofOrder = stats->cntOutofOrder;
current->TotalLen = stats->TotalLen;
current->mFormat = stats->mFormat;
current->endTime = stats->endTime;
current->jitter = stats->jitter;
current->startTime = stats->startTime;
current->free = 1;
} else {
current->cntDatagrams += stats->cntDatagrams;
current->cntError += stats->cntError;
current->cntOutofOrder += stats->cntOutofOrder;
current->TotalLen += stats->TotalLen;
current->mFormat = stats->mFormat;
if ( current->endTime < stats->endTime ) {
current->endTime = stats->endTime;
}
if ( current->jitter < stats->jitter ) {
current->jitter = stats->jitter;
}
current->free++;
if ( current->free == reporthdr->threads ) {
void *reserved = reporthdr->report->info.reserved_delay;
current->free = force;
memcpy( &reporthdr->report->info, current, sizeof(Transfer_Info) );
current->startTime = -1;
reporthdr->report->info.reserved_delay = reserved;
reporter_print( reporthdr->report, MULTIPLE_REPORT, force );
}
}
}
}
}
/*
* Prints reports conditionally
*/
int reporter_condprintstats( ReporterData *stats, MultiHeader *multireport, int force ) {
if ( force != 0 ) {
stats->info.cntOutofOrder = stats->cntOutofOrder;
// assume most of the time out-of-order packets are not
// duplicate packets, so conditionally subtract them from the lost packets.
stats->info.cntError = stats->cntError;
if ( stats->info.cntError > stats->info.cntOutofOrder ) {
stats->info.cntError -= stats->info.cntOutofOrder;
}
stats->info.cntDatagrams = (isUDP(stats) ? stats->PacketID : stats->cntDatagrams);
stats->info.TotalLen = stats->TotalLen;
stats->info.startTime = 0;
stats->info.endTime = TimeDifference( stats->packetTime, stats->startTime );
stats->info.free = 1;
reporter_print( stats, TRANSFER_REPORT, force );
if ( isMultipleReport(stats) ) {
reporter_handle_multiple_reports( multireport, &stats->info, force );
}
} else while ((stats->intervalTime.tv_sec != 0 ||
stats->intervalTime.tv_usec != 0) &&
TimeDifference( stats->nextTime,
stats->packetTime ) < 0 ) {
stats->info.cntOutofOrder = stats->cntOutofOrder - stats->lastOutofOrder;
stats->lastOutofOrder = stats->cntOutofOrder;
// assume most of the time out-of-order packets are not
// duplicate packets, so conditionally subtract them from the lost packets.
stats->info.cntError = stats->cntError - stats->lastError;
if ( stats->info.cntError > stats->info.cntOutofOrder ) {
stats->info.cntError -= stats->info.cntOutofOrder;
}
stats->lastError = stats->cntError;
stats->info.cntDatagrams = (isUDP( stats ) ? stats->PacketID - stats->lastDatagrams :
stats->cntDatagrams - stats->lastDatagrams);
stats->lastDatagrams = (isUDP( stats ) ? stats->PacketID : stats->cntDatagrams);
stats->info.TotalLen = stats->TotalLen - stats->lastTotal;
stats->lastTotal = stats->TotalLen;
stats->info.startTime = stats->info.endTime;
stats->info.endTime = TimeDifference( stats->nextTime, stats->startTime );
TimeAdd( stats->nextTime, stats->intervalTime );
stats->info.free = 0;
reporter_print( stats, TRANSFER_REPORT, force );
if ( isMultipleReport(stats) ) {
reporter_handle_multiple_reports( multireport, &stats->info, force );
}
}
return force;
}
/*
* This function handles multiple format printing by sending to the
* appropriate dispatch function
*/
int reporter_print( ReporterData *stats, int type, int end ) {
switch ( type ) {
case TRANSFER_REPORT:
statistics_reports[stats->mode]( &stats->info );
if ( end != 0 && isPrintMSS( stats ) && !isUDP( stats ) ) {
PrintMSS( stats );
}
break;
case SERVER_RELAY_REPORT:
serverstatistics_reports[stats->mode]( &stats->connection, &stats->info );
break;
case SETTINGS_REPORT:
settings_reports[stats->mode]( stats );
break;
case CONNECTION_REPORT:
stats->info.reserved_delay = connection_reports[stats->mode](
&stats->connection,
stats->info.transferID );
break;
case MULTIPLE_REPORT:
multiple_reports[stats->mode]( &stats->info );
break;
default:
fprintf( stderr, "Printing type not implemented! No Output\n" );
}
fflush( stdout );
return end;
}
/* -------------------------------------------------------------------
* Report the MSS and MTU, given the MSS (or a guess thereof)
* ------------------------------------------------------------------- */
// compare the MSS against the (MTU - 40) to (MTU - 80) bytes.
// 40 byte IP header and somewhat arbitrarily, 40 more bytes of IP options.
#define checkMSS_MTU( inMSS, inMTU ) (inMTU-40) >= inMSS && inMSS >= (inMTU-80)
void PrintMSS( ReporterData *stats ) {
int inMSS = getsock_tcp_mss( stats->info.transferID );
if ( inMSS <= 0 ) {
printf( report_mss_unsupported, stats->info.transferID );
} else {
char* net;
int mtu = 0;
if ( checkMSS_MTU( inMSS, 1500 ) ) {
net = "ethernet";
mtu = 1500;
} else if ( checkMSS_MTU( inMSS, 4352 ) ) {
net = "FDDI";
mtu = 4352;
} else if ( checkMSS_MTU( inMSS, 9180 ) ) {
net = "ATM";
mtu = 9180;
} else if ( checkMSS_MTU( inMSS, 65280 ) ) {
net = "HIPPI";
mtu = 65280;
} else if ( checkMSS_MTU( inMSS, 576 ) ) {
net = "minimum";
mtu = 576;
printf( warn_no_pathmtu );
} else {
mtu = inMSS + 40;
net = "unknown interface";
}
printf( report_mss,
stats->info.transferID, inMSS, mtu, net );
}
}
// end ReportMSS
#ifdef __cplusplus
} /* end extern "C" */
#endif

228
src/Server.cpp Normal file
View File

@ -0,0 +1,228 @@
/*---------------------------------------------------------------
* Copyright (c) 1999,2000,2001,2002,2003
* The Board of Trustees of the University of Illinois
* All Rights Reserved.
*---------------------------------------------------------------
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software (Iperf) 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:
*
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and
* the following disclaimers.
*
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimers in the documentation and/or other materials
* provided with the distribution.
*
*
* Neither the names of the University of Illinois, NCSA,
* nor the names of its contributors may be used to endorse
* or promote products derived from this Software without
* specific prior written permission.
*
* 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 CONTIBUTORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* ________________________________________________________________
* National Laboratory for Applied Network Research
* National Center for Supercomputing Applications
* University of Illinois at Urbana-Champaign
* http://www.ncsa.uiuc.edu
* ________________________________________________________________
*
* Server.cpp
* by Mark Gates <mgates@nlanr.net>
* Ajay Tirumala (tirumala@ncsa.uiuc.edu>.
* -------------------------------------------------------------------
* A server thread is initiated for each connection accept() returns.
* Handles sending and receiving data, and then closes socket.
* Changes to this version : The server can be run as a daemon
* ------------------------------------------------------------------- */
#define HEADERS()
#include "headers.h"
#include "Server.hpp"
#include "List.h"
#include "Extractor.h"
#include "Reporter.h"
#include "Locale.h"
/* -------------------------------------------------------------------
* Stores connected socket and socket info.
* ------------------------------------------------------------------- */
Server::Server( thread_Settings *inSettings ) {
mSettings = inSettings;
mBuf = NULL;
// initialize buffer
mBuf = new char[ mSettings->mBufLen ];
FAIL_errno( mBuf == NULL, "No memory for buffer\n", mSettings );
}
/* -------------------------------------------------------------------
* Destructor close socket.
* ------------------------------------------------------------------- */
Server::~Server() {
if ( mSettings->mSock != INVALID_SOCKET ) {
int rc = close( mSettings->mSock );
WARN_errno( rc == SOCKET_ERROR, "close" );
mSettings->mSock = INVALID_SOCKET;
}
DELETE_ARRAY( mBuf );
}
void Server::Sig_Int( int inSigno ) {
}
/* -------------------------------------------------------------------
* Receieve data from the (connected) TCP/UDP socket.
* Sends termination flag several times at the end.
* Does not close the socket.
* ------------------------------------------------------------------- */
void Server::Run( void ) {
long currLen;
struct UDP_datagram* mBuf_UDP = (struct UDP_datagram*) mBuf;
ReportStruct *reportstruct = NULL;
reportstruct = new ReportStruct;
if ( reportstruct != NULL ) {
reportstruct->packetID = 0;
mSettings->reporthdr = InitReport( mSettings );
do {
// perform read
currLen = recv( mSettings->mSock, mBuf, mSettings->mBufLen, 0 );
if ( isUDP( mSettings ) ) {
// read the datagram ID and sentTime out of the buffer
reportstruct->packetID = ntohl( mBuf_UDP->id );
reportstruct->sentTime.tv_sec = ntohl( mBuf_UDP->tv_sec );
reportstruct->sentTime.tv_usec = ntohl( mBuf_UDP->tv_usec );
}
reportstruct->packetLen = currLen;
gettimeofday( &(reportstruct->packetTime), NULL );
// terminate when datagram begins with negative index
// the datagram ID should be correct, just negated
if ( reportstruct->packetID < 0 ) {
reportstruct->packetID = -reportstruct->packetID;
currLen = -1;
}
ReportPacket( mSettings->reporthdr, reportstruct );
} while ( currLen > 0 );
// stop timing
gettimeofday( &(reportstruct->packetTime), NULL );
CloseReport( mSettings->reporthdr, reportstruct );
// send a acknowledgement back only if we're NOT receiving multicast
if ( isUDP( mSettings ) && !isMulticast( mSettings ) ) {
// send back an acknowledgement of the terminating datagram
write_UDP_AckFIN( );
}
} else {
FAIL(1, "Out of memory! Closing server thread\n", mSettings);
}
Mutex_Lock( &clients_mutex );
Iperf_delete( &(mSettings->peer), &clients );
Mutex_Unlock( &clients_mutex );
DELETE_PTR( reportstruct );
EndReport( mSettings->reporthdr );
}
// end Recv
/* -------------------------------------------------------------------
* Send an AckFIN (a datagram acknowledging a FIN) on the socket,
* then select on the socket for some time. If additional datagrams
* come in, probably our AckFIN was lost and they are re-transmitted
* termination datagrams, so re-transmit our AckFIN.
* ------------------------------------------------------------------- */
void Server::write_UDP_AckFIN( ) {
int rc;
fd_set readSet;
FD_ZERO( &readSet );
struct timeval timeout;
int count = 0;
while ( count < 10 ) {
count++;
UDP_datagram *UDP_Hdr;
server_hdr *hdr;
UDP_Hdr = (UDP_datagram*) mBuf;
if ( mSettings->mBufLen > (int) ( sizeof( UDP_datagram )
+ sizeof( server_hdr ) ) ) {
Transfer_Info *stats = GetReport( mSettings->reporthdr );
hdr = (server_hdr*) (UDP_Hdr+1);
hdr->flags = htonl( HEADER_VERSION1 );
hdr->total_len1 = htonl( (long) (stats->TotalLen >> 32) );
hdr->total_len2 = htonl( (long) (stats->TotalLen & 0xFFFFFFFF) );
hdr->stop_sec = htonl( (long) stats->endTime );
hdr->stop_usec = htonl( (long)((stats->endTime - (long)stats->endTime)
* rMillion));
hdr->error_cnt = htonl( stats->cntError );
hdr->outorder_cnt = htonl( stats->cntOutofOrder );
hdr->datagrams = htonl( stats->cntDatagrams );
hdr->jitter1 = htonl( (long) stats->jitter );
hdr->jitter2 = htonl( (long) ((stats->jitter - (long)stats->jitter)
* rMillion) );
}
// write data
write( mSettings->mSock, mBuf, mSettings->mBufLen );
// wait until the socket is readable, or our timeout expires
FD_SET( mSettings->mSock, &readSet );
timeout.tv_sec = 1;
timeout.tv_usec = 0;
rc = select( mSettings->mSock+1, &readSet, NULL, NULL, &timeout );
FAIL_errno( rc == SOCKET_ERROR, "select", mSettings );
if ( rc == 0 ) {
// select timed out
return;
} else {
// socket ready to read
rc = read( mSettings->mSock, mBuf, mSettings->mBufLen );
WARN_errno( rc < 0, "read" );
if ( rc <= 0 ) {
// Connection closed or errored
// Stop using it.
return;
}
}
}
fprintf( stderr, warn_ack_failed, mSettings->mSock, count );
}
// end write_UDP_AckFIN

835
src/Settings.cpp Normal file
View File

@ -0,0 +1,835 @@
/*---------------------------------------------------------------
* Copyright (c) 1999,2000,2001,2002,2003
* The Board of Trustees of the University of Illinois
* All Rights Reserved.
*---------------------------------------------------------------
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software (Iperf) 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:
*
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and
* the following disclaimers.
*
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimers in the documentation and/or other materials
* provided with the distribution.
*
*
* Neither the names of the University of Illinois, NCSA,
* nor the names of its contributors may be used to endorse
* or promote products derived from this Software without
* specific prior written permission.
*
* 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 CONTIBUTORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* ________________________________________________________________
* National Laboratory for Applied Network Research
* National Center for Supercomputing Applications
* University of Illinois at Urbana-Champaign
* http://www.ncsa.uiuc.edu
* ________________________________________________________________
*
* Settings.cpp
* by Mark Gates <mgates@nlanr.net>
* & Ajay Tirumala <tirumala@ncsa.uiuc.edu>
* -------------------------------------------------------------------
* Stores and parses the initial values for all the global variables.
* -------------------------------------------------------------------
* headers
* uses
* <stdlib.h>
* <stdio.h>
* <string.h>
*
* <unistd.h>
* ------------------------------------------------------------------- */
#define HEADERS()
#include "headers.h"
#include "Settings.hpp"
#include "Locale.h"
#include "SocketAddr.h"
#include "util.h"
#include "gnu_getopt.h"
void Settings_Interpret( char option, const char *optarg, thread_Settings *mExtSettings );
/* -------------------------------------------------------------------
* command line options
*
* The option struct essentially maps a long option name (--foobar)
* or environment variable ($FOOBAR) to its short option char (f).
* ------------------------------------------------------------------- */
#define LONG_OPTIONS()
const struct option long_options[] =
{
{"singleclient", no_argument, NULL, '1'},
{"bandwidth", required_argument, NULL, 'b'},
{"client", required_argument, NULL, 'c'},
{"dualtest", no_argument, NULL, 'd'},
{"format", required_argument, NULL, 'f'},
{"help", no_argument, NULL, 'h'},
{"interval", required_argument, NULL, 'i'},
{"len", required_argument, NULL, 'l'},
{"print_mss", no_argument, NULL, 'm'},
{"num", required_argument, NULL, 'n'},
{"output", required_argument, NULL, 'o'},
{"port", required_argument, NULL, 'p'},
{"tradeoff", no_argument, NULL, 'r'},
{"server", no_argument, NULL, 's'},
{"time", required_argument, NULL, 't'},
{"udp", no_argument, NULL, 'u'},
{"version", no_argument, NULL, 'v'},
{"window", required_argument, NULL, 'w'},
{"reportexclude", required_argument, NULL, 'x'},
{"reportstyle",required_argument, NULL, 'y'},
// more esoteric options
{"bind", required_argument, NULL, 'B'},
{"compatibility", no_argument, NULL, 'C'},
{"daemon", no_argument, NULL, 'D'},
{"file_input", required_argument, NULL, 'F'},
{"stdin_input", no_argument, NULL, 'I'},
{"mss", required_argument, NULL, 'M'},
{"nodelay", no_argument, NULL, 'N'},
{"listenport", required_argument, NULL, 'L'},
{"parallel", required_argument, NULL, 'P'},
{"remove", no_argument, NULL, 'R'},
{"tos", required_argument, NULL, 'S'},
{"ttl", required_argument, NULL, 'T'},
{"single_udp", no_argument, NULL, 'U'},
{"ipv6_domian", no_argument, NULL, 'V'},
{"suggest_win_size", no_argument, NULL, 'W'},
{0, 0, 0, 0}
};
#define ENV_OPTIONS()
const struct option env_options[] =
{
{"IPERF_SINGLECLIENT", no_argument, NULL, '1'},
{"IPERF_BANDWIDTH", required_argument, NULL, 'b'},
{"IPERF_CLIENT", required_argument, NULL, 'c'},
{"IPERF_DUALTEST", no_argument, NULL, 'd'},
{"IPERF_FORMAT", required_argument, NULL, 'f'},
// skip help
{"IPERF_INTERVAL", required_argument, NULL, 'i'},
{"IPERF_LEN", required_argument, NULL, 'l'},
{"IPERF_PRINT_MSS", no_argument, NULL, 'm'},
{"IPERF_NUM", required_argument, NULL, 'n'},
{"IPERF_PORT", required_argument, NULL, 'p'},
{"IPERF_TRADEOFF", no_argument, NULL, 'r'},
{"IPERF_SERVER", no_argument, NULL, 's'},
{"IPERF_TIME", required_argument, NULL, 't'},
{"IPERF_UDP", no_argument, NULL, 'u'},
// skip version
{"TCP_WINDOW_SIZE", required_argument, NULL, 'w'},
{"IPERF_REPORTEXCLUDE", required_argument, NULL, 'x'},
{"IPERF_REPORTSTYLE",required_argument, NULL, 'y'},
// more esoteric options
{"IPERF_BIND", required_argument, NULL, 'B'},
{"IPERF_COMPAT", no_argument, NULL, 'C'},
{"IPERF_DAEMON", no_argument, NULL, 'D'},
{"IPERF_FILE_INPUT", required_argument, NULL, 'F'},
{"IPERF_STDIN_INPUT", no_argument, NULL, 'I'},
{"IPERF_MSS", required_argument, NULL, 'M'},
{"IPERF_NODELAY", no_argument, NULL, 'N'},
{"IPERF_LISTENPORT", required_argument, NULL, 'L'},
{"IPERF_PARALLEL", required_argument, NULL, 'P'},
{"IPERF_TOS", required_argument, NULL, 'S'},
{"IPERF_TTL", required_argument, NULL, 'T'},
{"IPERF_SINGLE_UDP", no_argument, NULL, 'U'},
{"IPERF_IPV6_DOMAIN", no_argument, NULL, 'V'},
{"IPERF_SUGGEST_WIN_SIZE", required_argument, NULL, 'W'},
{0, 0, 0, 0}
};
#define SHORT_OPTIONS()
const char short_options[] = "1b:c:df:hi:l:mn:o:p:rst:uvw:x:y:B:CDF:IL:M:NP:RS:T:UVW";
/* -------------------------------------------------------------------
* defaults
* ------------------------------------------------------------------- */
#define DEFAULTS()
const long kDefault_UDPRate = 1024 * 1024; // -u if set, 1 Mbit/sec
const int kDefault_UDPBufLen = 1470; // -u if set, read/write 1470 bytes
// 1470 bytes is small enough to be sending one packet per datagram on ethernet
// 1450 bytes is small enough to be sending one packet per datagram on ethernet
// **** with IPv6 ****
/* -------------------------------------------------------------------
* Initialize all settings to defaults.
* ------------------------------------------------------------------- */
void Settings_Initialize( thread_Settings *main ) {
// Everything defaults to zero or NULL with
// this memset. Only need to set non-zero values
// below.
memset( main, 0, sizeof(thread_Settings) );
main->mSock = INVALID_SOCKET;
main->mReportMode = kReport_Default;
// option, defaults
main->flags = FLAG_MODETIME | FLAG_STDOUT; // Default time and stdout
//main->mUDPRate = 0; // -b, ie. TCP mode
//main->mHost = NULL; // -c, none, required for client
main->mMode = kTest_Normal; // -d, mMode == kTest_DualTest
main->mFormat = 'a'; // -f, adaptive bits
// skip help // -h,
//main->mBufLenSet = false; // -l,
main->mBufLen = 8 * 1024; // -l, 8 Kbyte
//main->mInterval = 0; // -i, ie. no periodic bw reports
//main->mPrintMSS = false; // -m, don't print MSS
// mAmount is time also // -n, N/A
//main->mOutputFileName = NULL; // -o, filename
main->mPort = 5001; // -p, ttcp port
// mMode = kTest_Normal; // -r, mMode == kTest_TradeOff
main->mThreadMode = kMode_Unknown; // -s, or -c, none
main->mAmount = 1000; // -t, 10 seconds
// mUDPRate > 0 means UDP // -u, N/A, see kDefault_UDPRate
// skip version // -v,
//main->mTCPWin = 0; // -w, ie. don't set window
// more esoteric options
//main->mLocalhost = NULL; // -B, none
//main->mCompat = false; // -C, run in Compatibility mode
//main->mDaemon = false; // -D, run as a daemon
//main->mFileInput = false; // -F,
//main->mFileName = NULL; // -F, filename
//main->mStdin = false; // -I, default not stdin
//main->mListenPort = 0; // -L, listen port
//main->mMSS = 0; // -M, ie. don't set MSS
//main->mNodelay = false; // -N, don't set nodelay
//main->mThreads = 0; // -P,
//main->mRemoveService = false; // -R,
//main->mTOS = 0; // -S, ie. don't set type of service
main->mTTL = 1; // -T, link-local TTL
//main->mDomain = kMode_IPv4; // -V,
//mian->mSuggestWin = false; // -W, Suggest the window size.
} // end Settings
void Settings_Copy( thread_Settings *from, thread_Settings **into ) {
*into = new thread_Settings;
memcpy( *into, from, sizeof(thread_Settings) );
if ( from->mHost != NULL ) {
(*into)->mHost = new char[ strlen(from->mHost) + 1];
strcpy( (*into)->mHost, from->mHost );
}
if ( from->mOutputFileName != NULL ) {
(*into)->mOutputFileName = new char[ strlen(from->mOutputFileName) + 1];
strcpy( (*into)->mOutputFileName, from->mOutputFileName );
}
if ( from->mLocalhost != NULL ) {
(*into)->mLocalhost = new char[ strlen(from->mLocalhost) + 1];
strcpy( (*into)->mLocalhost, from->mLocalhost );
}
if ( from->mFileName != NULL ) {
(*into)->mFileName = new char[ strlen(from->mFileName) + 1];
strcpy( (*into)->mFileName, from->mFileName );
}
// Zero out certain entries
(*into)->mTID = thread_zeroid();
(*into)->runNext = NULL;
(*into)->runNow = NULL;
}
/* -------------------------------------------------------------------
* Delete memory: Does not clean up open file pointers or ptr_parents
* ------------------------------------------------------------------- */
void Settings_Destroy( thread_Settings *mSettings) {
DELETE_ARRAY( mSettings->mHost );
DELETE_ARRAY( mSettings->mLocalhost );
DELETE_ARRAY( mSettings->mFileName );
DELETE_ARRAY( mSettings->mOutputFileName );
DELETE_PTR( mSettings );
} // end ~Settings
/* -------------------------------------------------------------------
* Parses settings from user's environment variables.
* ------------------------------------------------------------------- */
void Settings_ParseEnvironment( thread_Settings *mSettings ) {
char *theVariable;
int i = 0;
while ( env_options[i].name != NULL ) {
theVariable = getenv( env_options[i].name );
if ( theVariable != NULL ) {
Settings_Interpret( env_options[i].val, theVariable, mSettings );
}
i++;
}
} // end ParseEnvironment
/* -------------------------------------------------------------------
* Parse settings from app's command line.
* ------------------------------------------------------------------- */
void Settings_ParseCommandLine( int argc, char **argv, thread_Settings *mSettings ) {
int option;
while ( (option =
gnu_getopt_long( argc, argv, short_options,
long_options, NULL )) != EOF ) {
Settings_Interpret( option, gnu_optarg, mSettings );
}
for ( int i = gnu_optind; i < argc; i++ ) {
fprintf( stderr, "%s: ignoring extra argument -- %s\n", argv[0], argv[i] );
}
} // end ParseCommandLine
/* -------------------------------------------------------------------
* Interpret individual options, either from the command line
* or from environment variables.
* ------------------------------------------------------------------- */
void Settings_Interpret( char option, const char *optarg, thread_Settings *mExtSettings ) {
char outarg[100];
switch ( option ) {
case '1': // Single Client
setSingleClient( mExtSettings );
break;
case 'b': // UDP bandwidth
if ( !isUDP( mExtSettings ) ) {
fprintf( stderr, warn_implied_udp, option );
}
if ( mExtSettings->mThreadMode != kMode_Client ) {
fprintf( stderr, warn_invalid_server_option, option );
break;
}
Settings_GetLowerCaseArg(optarg,outarg);
mExtSettings->mUDPRate = byte_atoi(outarg);
setUDP( mExtSettings );
// if -l has already been processed, mBufLenSet is true
// so don't overwrite that value.
if ( !isBuflenSet( mExtSettings ) ) {
mExtSettings->mBufLen = kDefault_UDPBufLen;
}
break;
case 'c': // client mode w/ server host to connect to
mExtSettings->mHost = new char[ strlen( optarg ) + 1 ];
strcpy( mExtSettings->mHost, optarg );
if ( mExtSettings->mThreadMode == kMode_Unknown ) {
// Test for Multicast
iperf_sockaddr temp;
SockAddr_setHostname( mExtSettings->mHost, &temp,
(isIPV6( mExtSettings ) ? 1 : 0 ));
if ( SockAddr_isMulticast( &temp ) ) {
setMulticast( mExtSettings );
}
mExtSettings->mThreadMode = kMode_Client;
mExtSettings->mThreads = 1;
}
break;
case 'd': // Dual-test Mode
if ( mExtSettings->mThreadMode != kMode_Client ) {
fprintf( stderr, warn_invalid_server_option, option );
break;
}
if ( isCompat( mExtSettings ) ) {
fprintf( stderr, warn_invalid_compatibility_option, option );
}
#ifdef HAVE_THREAD
mExtSettings->mMode = kTest_DualTest;
#else
fprintf( stderr, warn_invalid_single_threaded, option );
mExtSettings->mMode = kTest_TradeOff;
#endif
break;
case 'f': // format to print in
mExtSettings->mFormat = (*optarg);
break;
case 'h': // print help and exit
#ifndef WIN32
fprintf( stderr, usage_long );
#else
fprintf(stderr, usage_long1);
fprintf(stderr, usage_long2);
#endif
exit(1);
break;
case 'i': // specify interval between periodic bw reports
mExtSettings->mInterval = atof( optarg );
if ( mExtSettings->mInterval < 0.5 ) {
fprintf (stderr, report_interval_small, mExtSettings->mInterval);
mExtSettings->mInterval = 0.5;
}
break;
case 'l': // length of each buffer
Settings_GetUpperCaseArg(optarg,outarg);
mExtSettings->mBufLen = byte_atoi( outarg );
setBuflenSet( mExtSettings );
if ( !isUDP( mExtSettings ) ) {
if ( mExtSettings->mBufLen < (int) sizeof( client_hdr ) &&
!isCompat( mExtSettings ) ) {
setCompat( mExtSettings );
fprintf( stderr, warn_implied_compatibility, option );
}
} else {
if ( mExtSettings->mBufLen < (int) sizeof( UDP_datagram ) ) {
mExtSettings->mBufLen = sizeof( UDP_datagram );
fprintf( stderr, warn_buffer_too_small, mExtSettings->mBufLen );
}
if ( !isCompat( mExtSettings ) &&
mExtSettings->mBufLen < (int) ( sizeof( UDP_datagram )
+ sizeof( client_hdr ) ) ) {
setCompat( mExtSettings );
fprintf( stderr, warn_implied_compatibility, option );
}
}
break;
case 'm': // print TCP MSS
setPrintMSS( mExtSettings );
break;
case 'n': // bytes of data
// amount mode (instead of time mode)
unsetModeTime( mExtSettings );
Settings_GetUpperCaseArg(optarg,outarg);
mExtSettings->mAmount = byte_atoi( outarg );
break;
case 'o' : // output the report and other messages into the file
unsetSTDOUT( mExtSettings );
mExtSettings->mOutputFileName = new char[strlen(optarg)+1];
strcpy( mExtSettings->mOutputFileName, optarg);
break;
case 'p': // server port
mExtSettings->mPort = atoi( optarg );
break;
case 'r': // test mode tradeoff
if ( mExtSettings->mThreadMode != kMode_Client ) {
fprintf( stderr, warn_invalid_server_option, option );
break;
}
if ( isCompat( mExtSettings ) ) {
fprintf( stderr, warn_invalid_compatibility_option, option );
}
mExtSettings->mMode = kTest_TradeOff;
break;
case 's': // server mode
if ( mExtSettings->mThreadMode != kMode_Unknown ) {
fprintf( stderr, warn_invalid_client_option, option );
break;
}
mExtSettings->mThreadMode = kMode_Listener;
break;
case 't': // seconds to write for
// time mode (instead of amount mode)
setModeTime( mExtSettings );
mExtSettings->mAmount = (int) (atof( optarg ) * 100.0);
break;
case 'u': // UDP instead of TCP
// if -b has already been processed, UDP rate will
// already be non-zero, so don't overwrite that value
if ( !isUDP( mExtSettings ) ) {
setUDP( mExtSettings );
mExtSettings->mUDPRate = kDefault_UDPRate;
}
// if -l has already been processed, mBufLenSet is true
// so don't overwrite that value.
if ( !isBuflenSet( mExtSettings ) ) {
mExtSettings->mBufLen = kDefault_UDPBufLen;
} else if ( mExtSettings->mBufLen < (int) ( sizeof( UDP_datagram )
+ sizeof( client_hdr ) ) &&
!isCompat( mExtSettings ) ) {
setCompat( mExtSettings );
fprintf( stderr, warn_implied_compatibility, option );
}
break;
case 'v': // print version and exit
fprintf( stderr, version );
exit(1);
break;
case 'w': // TCP window size (socket buffer size)
Settings_GetUpperCaseArg(optarg,outarg);
mExtSettings->mTCPWin = byte_atoi(outarg);
if ( mExtSettings->mTCPWin < 2048 ) {
fprintf( stderr, warn_window_small, mExtSettings->mTCPWin );
}
break;
case 'x': // Limit Reports
while ( *optarg != '\0' ) {
switch ( *optarg ) {
case 's':
case 'S':
setNoSettReport( mExtSettings );
break;
case 'c':
case 'C':
setNoConnReport( mExtSettings );
break;
case 'd':
case 'D':
setNoDataReport( mExtSettings );
break;
case 'v':
case 'V':
setNoServReport( mExtSettings );
break;
case 'm':
case 'M':
setNoMultReport( mExtSettings );
break;
default:
fprintf(stderr, warn_invalid_report, *optarg);
}
optarg++;
}
break;
case 'y': // Reporting Style
switch ( *optarg ) {
case 'c':
case 'C':
mExtSettings->mReportMode = kReport_CSV;
break;
default:
fprintf( stderr, warn_invalid_report_style, optarg );
}
break;
// more esoteric options
case 'B': // specify bind address
mExtSettings->mLocalhost = new char[ strlen( optarg ) + 1 ];
strcpy( mExtSettings->mLocalhost, optarg );
// Test for Multicast
iperf_sockaddr temp;
SockAddr_setHostname( mExtSettings->mLocalhost, &temp,
(isIPV6( mExtSettings ) ? 1 : 0 ));
if ( SockAddr_isMulticast( &temp ) ) {
setMulticast( mExtSettings );
}
break;
case 'C': // Run in Compatibility Mode
setCompat( mExtSettings );
if ( mExtSettings->mMode != kTest_Normal ) {
fprintf( stderr, warn_invalid_compatibility_option,
( mExtSettings->mMode == kTest_DualTest ?
'd' : 'r' ) );
mExtSettings->mMode = kTest_Normal;
}
break;
case 'D': // Run as a daemon
setDaemon( mExtSettings );
break;
case 'F' : // Get the input for the data stream from a file
if ( mExtSettings->mThreadMode != kMode_Client ) {
fprintf( stderr, warn_invalid_server_option, option );
break;
}
setFileInput( mExtSettings );
mExtSettings->mFileName = new char[strlen(optarg)+1];
strcpy( mExtSettings->mFileName, optarg);
break;
case 'I' : // Set the stdin as the input source
if ( mExtSettings->mThreadMode != kMode_Client ) {
fprintf( stderr, warn_invalid_server_option, option );
break;
}
setFileInput( mExtSettings );
setSTDIN( mExtSettings );
mExtSettings->mFileName = new char[strlen("<stdin>")+1];
strcpy( mExtSettings->mFileName,"<stdin>");
break;
case 'L': // Listen Port (bidirectional testing client-side)
if ( mExtSettings->mThreadMode != kMode_Client ) {
fprintf( stderr, warn_invalid_server_option, option );
break;
}
mExtSettings->mListenPort = atoi( optarg );
break;
case 'M': // specify TCP MSS (maximum segment size)
Settings_GetUpperCaseArg(optarg,outarg);
mExtSettings->mMSS = byte_atoi( outarg );
break;
case 'N': // specify TCP nodelay option (disable Jacobson's Algorithm)
setNoDelay( mExtSettings );
break;
case 'P': // number of client threads
#ifdef HAVE_THREAD
mExtSettings->mThreads = atoi( optarg );
#else
if ( mExtSettings->mThreadMode != kMode_Server ) {
fprintf( stderr, warn_invalid_single_threaded, option );
} else {
mExtSettings->mThreads = atoi( optarg );
}
#endif
break;
case 'R':
setRemoveService( mExtSettings );
break;
case 'S': // IP type-of-service
// TODO use a function that understands base-2
// the zero base here allows the user to specify
// "0x#" hex, "0#" octal, and "#" decimal numbers
mExtSettings->mTOS = strtol( optarg, NULL, 0 );
break;
case 'T': // time-to-live for multicast
mExtSettings->mTTL = atoi( optarg );
break;
case 'U': // single threaded UDP server
setSingleUDP( mExtSettings );
break;
case 'V': // IPv6 Domain
setIPV6( mExtSettings );
if ( mExtSettings->mThreadMode == kMode_Server
&& mExtSettings->mLocalhost != NULL ) {
// Test for Multicast
iperf_sockaddr temp;
SockAddr_setHostname( mExtSettings->mLocalhost, &temp, 1);
if ( SockAddr_isMulticast( &temp ) ) {
setMulticast( mExtSettings );
}
} else if ( mExtSettings->mThreadMode == kMode_Client ) {
// Test for Multicast
iperf_sockaddr temp;
SockAddr_setHostname( mExtSettings->mHost, &temp, 1 );
if ( SockAddr_isMulticast( &temp ) ) {
setMulticast( mExtSettings );
}
}
break;
case 'W' :
setSuggestWin( mExtSettings );
fprintf( stderr, "The -W option is not available in this release\n");
break;
default: // ignore unknown
break;
}
} // end Interpret
void Settings_GetUpperCaseArg(const char *inarg, char *outarg) {
int len = strlen(inarg);
strcpy(outarg,inarg);
if ( (len > 0) && (inarg[len-1] >='a')
&& (inarg[len-1] <= 'z') )
outarg[len-1]= outarg[len-1]+'A'-'a';
}
void Settings_GetLowerCaseArg(const char *inarg, char *outarg) {
int len = strlen(inarg);
strcpy(outarg,inarg);
if ( (len > 0) && (inarg[len-1] >='A')
&& (inarg[len-1] <= 'Z') )
outarg[len-1]= outarg[len-1]-'A'+'a';
}
/*
* Settings_GenerateListenerSettings
* Called to generate the settings to be passed to the Listener
* instance that will handle dual testings from the client side
* this should only return an instance if it was called on
* the thread_Settings instance generated from the command line
* for client side execution
*/
void Settings_GenerateListenerSettings( thread_Settings *client, thread_Settings **listener ) {
if ( !isCompat( client ) &&
(client->mMode == kTest_DualTest || client->mMode == kTest_TradeOff) ) {
*listener = new thread_Settings;
memcpy(*listener, client, sizeof( thread_Settings ));
setCompat( (*listener) );
unsetDaemon( (*listener) );
if ( client->mListenPort != 0 ) {
(*listener)->mPort = client->mListenPort;
} else {
(*listener)->mPort = client->mPort;
}
(*listener)->mFileName = NULL;
(*listener)->mHost = NULL;
(*listener)->mLocalhost = NULL;
(*listener)->mOutputFileName = NULL;
(*listener)->mMode = kTest_Normal;
(*listener)->mThreadMode = kMode_Listener;
if ( client->mHost != NULL ) {
(*listener)->mHost = new char[strlen( client->mHost ) + 1];
strcpy( (*listener)->mHost, client->mHost );
}
if ( client->mLocalhost != NULL ) {
(*listener)->mLocalhost = new char[strlen( client->mLocalhost ) + 1];
strcpy( (*listener)->mLocalhost, client->mLocalhost );
}
} else {
*listener = NULL;
}
}
/*
* Settings_GenerateSpeakerSettings
* Called to generate the settings to be passed to the Speaker
* instance that will handle dual testings from the server side
* this should only return an instance if it was called on
* the thread_Settings instance generated from the command line
* for server side execution. This should be an inverse operation
* of GenerateClientHdr.
*/
void Settings_GenerateClientSettings( thread_Settings *server,
thread_Settings **client,
client_hdr *hdr ) {
int flags = ntohl(hdr->flags);
if ( (flags & HEADER_VERSION1) != 0 ) {
*client = new thread_Settings;
memcpy(*client, server, sizeof( thread_Settings ));
setCompat( (*client) );
(*client)->mTID = thread_zeroid();
(*client)->mPort = (unsigned short) ntohl(hdr->mPort);
(*client)->mThreads = ntohl(hdr->numThreads);
if ( hdr->bufferlen != 0 ) {
(*client)->mBufLen = ntohl(hdr->bufferlen);
}
if ( hdr->mWinBand != 0 ) {
if ( isUDP( server ) ) {
(*client)->mUDPRate = ntohl(hdr->mWinBand);
} else {
(*client)->mTCPWin = ntohl(hdr->mWinBand);
}
}
(*client)->mAmount = ntohl(hdr->mAmount);
if ( ((*client)->mAmount & 0x80000000) > 0 ) {
setModeTime( (*client) );
#ifndef WIN32
(*client)->mAmount |= 0xFFFFFFFF00000000LL;
#else
(*client)->mAmount |= 0xFFFFFFFF00000000;
#endif
(*client)->mAmount = -(*client)->mAmount;
}
(*client)->mFileName = NULL;
(*client)->mHost = NULL;
(*client)->mLocalhost = NULL;
(*client)->mOutputFileName = NULL;
(*client)->mMode = ((flags & RUN_NOW) == 0 ?
kTest_TradeOff : kTest_DualTest);
(*client)->mThreadMode = kMode_Client;
if ( server->mLocalhost != NULL ) {
(*client)->mLocalhost = new char[strlen( server->mLocalhost ) + 1];
strcpy( (*client)->mLocalhost, server->mLocalhost );
}
(*client)->mHost = new char[REPORT_ADDRLEN];
if ( ((sockaddr*)&server->peer)->sa_family == AF_INET ) {
inet_ntop( AF_INET, &((sockaddr_in*)&server->peer)->sin_addr,
(*client)->mHost, REPORT_ADDRLEN);
}
#ifdef HAVE_IPV6
else {
inet_ntop( AF_INET6, &((sockaddr_in6*)&server->peer)->sin6_addr,
(*client)->mHost, REPORT_ADDRLEN);
}
#endif
} else {
*client = NULL;
}
}
/*
* Settings_GenerateClientHdr
* Called to generate the client header to be passed to the
* server that will handle dual testings from the server side
* This should be an inverse operation of GenerateSpeakerSettings
*/
void Settings_GenerateClientHdr( thread_Settings *client, client_hdr *hdr ) {
if ( client->mMode != kTest_Normal ) {
hdr->flags = htonl(HEADER_VERSION1);
} else {
hdr->flags = 0;
}
if ( isBuflenSet( client ) ) {
hdr->bufferlen = htonl(client->mBufLen);
} else {
hdr->bufferlen = 0;
}
if ( isUDP( client ) ) {
hdr->mWinBand = htonl(client->mUDPRate);
} else {
hdr->mWinBand = htonl(client->mTCPWin);
}
if ( client->mListenPort != 0 ) {
hdr->mPort = htonl(client->mListenPort);
} else {
hdr->mPort = htonl(client->mPort);
}
hdr->numThreads = htonl(client->mThreads);
if ( isModeTime( client ) ) {
hdr->mAmount = htonl(-(long)client->mAmount);
} else {
hdr->mAmount = htonl((long)client->mAmount);
hdr->mAmount &= htonl( 0x7FFFFFFF );
}
if ( client->mMode == kTest_DualTest ) {
hdr->flags |= htonl(RUN_NOW);
}
}

422
src/SocketAddr.c Normal file
View File

@ -0,0 +1,422 @@
/*---------------------------------------------------------------
* Copyright (c) 1999,2000,2001,2002,2003
* The Board of Trustees of the University of Illinois
* All Rights Reserved.
*---------------------------------------------------------------
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software (Iperf) 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:
*
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and
* the following disclaimers.
*
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimers in the documentation and/or other materials
* provided with the distribution.
*
*
* Neither the names of the University of Illinois, NCSA,
* nor the names of its contributors may be used to endorse
* or promote products derived from this Software without
* specific prior written permission.
*
* 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 CONTIBUTORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* ________________________________________________________________
* National Laboratory for Applied Network Research
* National Center for Supercomputing Applications
* University of Illinois at Urbana-Champaign
* http://www.ncsa.uiuc.edu
* ________________________________________________________________
*
* Socket.cpp
* by Ajay Tirumala <tirumala@ncsa.uiuc.edu>
* and Mark Gates <mgates@nlanr.net>
* ------------------------------------------------------------------- */
#define HEADERS()
#include "headers.h"
#include "SocketAddr.h"
#ifdef __cplusplus
extern "C" {
#endif
/* -------------------------------------------------------------------
* Create a socket address. If inHostname is not null, resolve that
* address and fill it in. Fill in the port number. Use IPv6 ADDR_ANY
* if that is what is desired.
* ------------------------------------------------------------------- */
void SockAddr_remoteAddr( thread_Settings *inSettings ) {
SockAddr_zeroAddress( &inSettings->peer );
if ( inSettings->mHost != NULL ) {
SockAddr_setHostname( inSettings->mHost, &inSettings->peer,
isIPV6( inSettings ) );
} else {
#ifdef HAVE_IPV6
if ( isIPV6( inSettings ) ) {
((struct sockaddr*)&inSettings->peer)->sa_family = AF_INET6;
} else {
((struct sockaddr*)&inSettings->peer)->sa_family = AF_INET;
}
}
if ( SockAddr_isIPv6( &inSettings->peer ) ) {
inSettings->size_peer = sizeof( struct sockaddr_in6 );
} else {
inSettings->size_peer = sizeof( struct sockaddr_in );
}
#else
((struct sockaddr*)&inSettings->peer)->sa_family = AF_INET;
}
inSettings->size_peer = sizeof( struct sockaddr_in );
#endif
SockAddr_setPort( &inSettings->peer, inSettings->mPort );
}
// end SocketAddr
void SockAddr_localAddr( thread_Settings *inSettings ) {
SockAddr_zeroAddress( &inSettings->local );
if ( inSettings->mLocalhost != NULL ) {
SockAddr_setHostname( inSettings->mLocalhost, &inSettings->local,
isIPV6( inSettings ) );
} else {
#ifdef HAVE_IPV6
if ( isIPV6( inSettings ) ) {
((struct sockaddr*)&inSettings->local)->sa_family = AF_INET6;
} else {
((struct sockaddr*)&inSettings->local)->sa_family = AF_INET;
}
}
if ( SockAddr_isIPv6( &inSettings->local ) ) {
inSettings->size_local = sizeof( struct sockaddr_in6 );
} else {
inSettings->size_local = sizeof( struct sockaddr_in );
}
#else
((struct sockaddr*)&inSettings->local)->sa_family = AF_INET;
}
inSettings->size_local = sizeof( struct sockaddr_in );
#endif
SockAddr_setPort( &inSettings->local, inSettings->mPort );
}
// end SocketAddr
/* -------------------------------------------------------------------
* Resolve the hostname address and fill it in.
* ------------------------------------------------------------------- */
void SockAddr_setHostname( const char* inHostname,
iperf_sockaddr *inSockAddr,
int isIPv6 ) {
// ..I think this works for both ipv6 & ipv4... we'll see
#if defined(HAVE_IPV6)
{
struct addrinfo *res, *itr;
int ret_ga;
ret_ga = getaddrinfo(inHostname, NULL, NULL, &res);
if ( ret_ga ) {
fprintf(stderr, "error: %s\n", gai_strerror(ret_ga));
exit(1);
}
if ( !res->ai_addr ) {
fprintf(stderr, "getaddrinfo failed to get an address... target was '%s'\n", inHostname);
exit(1);
}
// Check address type before filling in the address
// ai_family = PF_xxx; ai_protocol = IPPROTO_xxx, see netdb.h
// ...but AF_INET6 == PF_INET6
itr = res;
if ( isIPv6 ) {
// First check all results for a IPv6 Address
while ( itr != NULL ) {
if ( itr->ai_family == AF_INET6 ) {
memcpy(inSockAddr, (itr->ai_addr),
(itr->ai_addrlen));
freeaddrinfo(res);
return;
} else {
itr = itr->ai_next;
}
}
}
itr = res;
// Now find a IPv4 Address
while ( itr != NULL ) {
if ( itr->ai_family == AF_INET ) {
memcpy(inSockAddr, (itr->ai_addr),
(itr->ai_addrlen));
freeaddrinfo(res);
return;
} else {
itr = itr->ai_next;
}
}
}
#else
// first try just converting dotted decimal
// on Windows gethostbyname doesn't understand dotted decimal
int rc = inet_pton( AF_INET, inHostname,
(unsigned char*)&(((struct sockaddr_in*)inSockAddr)->sin_addr) );
inSockAddr->sin_family = AF_INET;
if ( rc == 0 ) {
struct hostent *hostP = gethostbyname( inHostname );
if ( hostP == NULL ) {
/* this is the same as herror() but works on more systems */
const char* format;
switch ( h_errno ) {
case HOST_NOT_FOUND:
format = "%s: Unknown host\n";
break;
case NO_ADDRESS:
format = "%s: No address associated with name\n";
break;
case NO_RECOVERY:
format = "%s: Unknown server error\n";
break;
case TRY_AGAIN:
format = "%s: Host name lookup failure\n";
break;
default:
format = "%s: Unknown resolver error\n";
break;
}
fprintf( stderr, format, inHostname );
exit(1);
return; // TODO throw
}
memcpy(&(((struct sockaddr_in*)inSockAddr)->sin_addr), *(hostP->h_addr_list),
(hostP->h_length));
}
#endif
}
// end setHostname
/* -------------------------------------------------------------------
* Copy the IP address into the string.
* ------------------------------------------------------------------- */
void SockAddr_getHostAddress( iperf_sockaddr *inSockAddr, char* outAddress,
size_t len ) {
if ( ((struct sockaddr*)inSockAddr)->sa_family == AF_INET ) {
inet_ntop( AF_INET, &(((struct sockaddr_in*) inSockAddr)->sin_addr),
outAddress, len);
}
#ifdef HAVE_IPV6
else {
inet_ntop( AF_INET6, &(((struct sockaddr_in6*) inSockAddr)->sin6_addr),
outAddress, len);
}
#endif
}
// end getHostAddress
/* -------------------------------------------------------------------
* Set the address to any (generally all zeros).
* ------------------------------------------------------------------- */
void SockAddr_setAddressAny( iperf_sockaddr *inSockAddr ) {
if ( ((struct sockaddr*)inSockAddr)->sa_family == AF_INET )
memset( &(((struct sockaddr_in*) inSockAddr)->sin_addr), 0,
sizeof( struct in_addr ));
#if defined(HAVE_IPV6)
else
memset( &(((struct sockaddr_in6*) inSockAddr)->sin6_addr), 0,
sizeof( struct in6_addr ));
#endif
}
// end setAddressAny
/* -------------------------------------------------------------------
* Set the port to the given port. Handles the byte swapping.
* ------------------------------------------------------------------- */
void SockAddr_setPort( iperf_sockaddr *inSockAddr, unsigned short inPort ) {
if ( ((struct sockaddr*)inSockAddr)->sa_family == AF_INET )
((struct sockaddr_in*) inSockAddr)->sin_port = htons( inPort );
#if defined(HAVE_IPV6)
else
((struct sockaddr_in6*) inSockAddr)->sin6_port = htons( inPort );
#endif
}
// end setPort
/* -------------------------------------------------------------------
* Set the port to zero, which lets the OS pick the port.
* ------------------------------------------------------------------- */
void SockAddr_setPortAny( iperf_sockaddr *inSockAddr ) {
SockAddr_setPort( inSockAddr, 0 );
}
// end setPortAny
/* -------------------------------------------------------------------
* Return the port. Handles the byte swapping.
* ------------------------------------------------------------------- */
unsigned short SockAddr_getPort( iperf_sockaddr *inSockAddr ) {
if ( ((struct sockaddr*)inSockAddr)->sa_family == AF_INET )
return ntohs( ((struct sockaddr_in*) inSockAddr)->sin_port );
#if defined(HAVE_IPV6)
else
return ntohs( ((struct sockaddr_in6*) inSockAddr)->sin6_port);
#endif
return 0;
}
// end getPort
/* -------------------------------------------------------------------
* Return the IPv4 Internet Address from the sockaddr_in structure
* ------------------------------------------------------------------- */
struct in_addr* SockAddr_get_in_addr( iperf_sockaddr *inSockAddr ) {
if ( ((struct sockaddr*)inSockAddr)->sa_family == AF_INET )
return &(((struct sockaddr_in*) inSockAddr)->sin_addr);
fprintf(stderr, "FATAL: get_in_addr called on IPv6 address\n");
return NULL;
}
/* -------------------------------------------------------------------
* Return the IPv6 Internet Address from the sockaddr_in6 structure
* ------------------------------------------------------------------- */
#ifdef HAVE_IPV6
struct in6_addr* SockAddr_get_in6_addr( iperf_sockaddr *inSockAddr ) {
if ( ((struct sockaddr*)inSockAddr)->sa_family == AF_INET6 )
return &(((struct sockaddr_in6*) inSockAddr)->sin6_addr);
fprintf(stderr, "FATAL: get_in6_addr called on IPv4 address\n");
return NULL;
}
#endif
/* -------------------------------------------------------------------
* Return the size of the appropriate address structure.
* ------------------------------------------------------------------- */
Socklen_t SockAddr_get_sizeof_sockaddr( iperf_sockaddr *inSockAddr ) {
#if defined(HAVE_IPV6)
if ( ((struct sockaddr*)inSockAddr)->sa_family == AF_INET6 ) {
return(sizeof(struct sockaddr_in6));
}
#endif
return(sizeof(struct sockaddr_in));
}
// end get_sizeof_sockaddr
/* -------------------------------------------------------------------
* Return if IPv6 socket
* ------------------------------------------------------------------- */
int SockAddr_isIPv6( iperf_sockaddr *inSockAddr ) {
#if defined(HAVE_IPV6)
if ( ((struct sockaddr*)inSockAddr)->sa_family == AF_INET6 ) {
return 1;
}
#endif
return 0;
}
// end get_sizeof_sockaddr
/* -------------------------------------------------------------------
* Return true if the address is a IPv4 multicast address.
* ------------------------------------------------------------------- */
int SockAddr_isMulticast( iperf_sockaddr *inSockAddr ) {
#if defined(HAVE_IPV6)
if ( ((struct sockaddr*)inSockAddr)->sa_family == AF_INET6 ) {
return( IN6_IS_ADDR_MULTICAST(&(((struct sockaddr_in6*) inSockAddr)->sin6_addr) ));
} else
#endif
{
// 224.0.0.0 to 239.255.255.255 (e0.00.00.00 to ef.ff.ff.ff)
const unsigned long kMulticast_Mask = 0xe0000000L;
return(kMulticast_Mask ==
(ntohl( ((struct sockaddr_in*) inSockAddr)->sin_addr.s_addr) & kMulticast_Mask));
}
}
// end isMulticast
/* -------------------------------------------------------------------
* Zero out the address structure.
* ------------------------------------------------------------------- */
void SockAddr_zeroAddress( iperf_sockaddr *inSockAddr ) {
memset( inSockAddr, 0, sizeof( iperf_sockaddr ));
}
// zeroAddress
/* -------------------------------------------------------------------
* Compare two sockaddrs and return true if they are equal
* ------------------------------------------------------------------- */
int SockAddr_are_Equal( struct sockaddr* first, struct sockaddr* second ) {
if ( first->sa_family == AF_INET && second->sa_family == AF_INET ) {
// compare IPv4 adresses
return( ((long) ((struct sockaddr_in*)first)->sin_addr.s_addr == (long) ((struct sockaddr_in*)second)->sin_addr.s_addr)
&& ( ((struct sockaddr_in*)first)->sin_port == ((struct sockaddr_in*)second)->sin_port) );
}
#if defined(HAVE_IPV6)
if ( first->sa_family == AF_INET6 && second->sa_family == AF_INET6 ) {
// compare IPv6 addresses
return( !memcmp(((struct sockaddr_in6*)first)->sin6_addr.s6_addr, ((struct sockaddr_in6*)second)->sin6_addr.s6_addr, sizeof(struct in6_addr))
&& (((struct sockaddr_in6*)first)->sin6_port == ((struct sockaddr_in6*)second)->sin6_port) );
}
#endif
return 0;
}
/* -------------------------------------------------------------------
* Compare two sockaddrs and return true if the hosts are equal
* ------------------------------------------------------------------- */
int SockAddr_Hostare_Equal( struct sockaddr* first, struct sockaddr* second ) {
if ( first->sa_family == AF_INET && second->sa_family == AF_INET ) {
// compare IPv4 adresses
return( (long) ((struct sockaddr_in*)first)->sin_addr.s_addr ==
(long) ((struct sockaddr_in*)second)->sin_addr.s_addr);
}
#if defined(HAVE_IPV6)
if ( first->sa_family == AF_INET6 && second->sa_family == AF_INET6 ) {
// compare IPv6 addresses
return( !memcmp(((struct sockaddr_in6*)first)->sin6_addr.s6_addr,
((struct sockaddr_in6*)second)->sin6_addr.s6_addr, sizeof(struct in6_addr)));
}
#endif
return 0;
}
#ifdef __cplusplus
} /* end extern "C" */
#endif

818
src/gnu_getopt.c Normal file
View File

@ -0,0 +1,818 @@
/* Getopt for GNU.
NOTE: gnu_getopt is now part of the C library, so if you don't know what
"Keep this file name-space clean" means, talk to roland@gnu.ai.mit.edu
before changing it!
Copyright (C) 1987, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97
Free Software Foundation, Inc.
This file is part of the GNU C Library. Its master source is NOT part of
the C library, however. The master source lives in /gd/gnu/lib.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C Library 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with the GNU C Library; see the file COPYING.LIB. If not,
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
/*
* modified July 9, 1999 by mark gates <mgates@nlanr.net>
* Dec 17, 1999
*
* renamed all functions and variables by prepending "gnu_"
* removed/redid a bunch of stuff under the assumption we're
* using a modern standard C compiler.
* add #include <string.h> here for strncmp(). Originally
* it was included only under special conditions.
*
* $Id: gnu_getopt.c,v 1.1.1.1 2004/05/18 01:50:44 kgibbs Exp $
*/
#include <stdio.h>
#include <stdlib.h>
#ifndef _MSC_VER /* Visual C++ doesn't have unistd.h */
#include <unistd.h>
#endif
#include <string.h>
#ifndef _
/* This is for other GNU distributions with internationalized messages.
When compiling libc, the _ macro is predefined. */
#ifdef HAVE_LIBINTL_H
#include <libintl.h>
#define _(msgid) gettext (msgid)
#else
#define _(msgid) (msgid)
#endif
#endif
/* This version of `gnu_getopt' appears to the caller like standard
Unix `getopt' but it behaves differently for the user, since it
allows the user to intersperse the options with the other
arguments.
As `gnu_getopt' works, it permutes the elements of ARGV so that,
when it is done, all the options precede everything else. Thus
all application programs are extended to handle flexible argument order.
Setting the environment variable POSIXLY_CORRECT disables permutation.
Then the behavior is completely standard.
GNU application programs can use a third alternative mode in which
they can distinguish the relative order of options and other arguments. */
#include "gnu_getopt.h"
#ifdef __cplusplus
extern "C" {
#endif
/* For communication from `gnu_getopt' to the caller.
When `gnu_getopt' finds an option that takes an argument,
the argument value is returned here.
Also, when `ordering' is RETURN_IN_ORDER,
each non-option ARGV-element is returned here. */
char *gnu_optarg = NULL;
/* Index in ARGV of the next element to be scanned.
This is used for communication to and from the caller
and for communication between successive calls to `gnu_getopt'.
On entry to `gnu_getopt', zero means this is the first call; initialize.
When `gnu_getopt' returns -1, this is the index of the first of the
non-option elements that the caller should itself scan.
Otherwise, `gnu_optind' communicates from one call to the next
how much of ARGV has been scanned so far. */
/* 1003.2 says this must be 1 before any call. */
int gnu_optind = 1;
/* Formerly, initialization of gnu_getopt depended on gnu_optind==0, which
causes problems with re-calling gnu_getopt as programs generally don't
know that. */
int __gnu_getopt_initialized = 0;
/* The next char to be scanned in the option-element
in which the last option character we returned was found.
This allows us to pick up the scan where we left off.
If this is zero, or a null string, it means resume the scan
by advancing to the next ARGV-element. */
static char *nextchar;
/* Callers store zero here to inhibit the error message
for unrecognized options. */
int gnu_opterr = 1;
/* Set to an option character which was unrecognized.
This must be initialized on some systems to avoid linking in the
system's own gnu_getopt implementation. */
int gnu_optopt = '?';
/* Describe how to deal with options that follow non-option ARGV-elements.
If the caller did not specify anything,
the default is REQUIRE_ORDER if the environment variable
POSIXLY_CORRECT is defined, PERMUTE otherwise.
REQUIRE_ORDER means don't recognize them as options;
stop option processing when the first non-option is seen.
This is what Unix does.
This mode of operation is selected by either setting the environment
variable POSIXLY_CORRECT, or using `+' as the first character
of the list of option characters.
PERMUTE is the default. We permute the contents of ARGV as we scan,
so that eventually all the non-options are at the end. This allows options
to be given in any order, even with programs that were not written to
expect this.
RETURN_IN_ORDER is an option available to programs that were written
to expect options and other ARGV-elements in any order and that care about
the ordering of the two. We describe each non-option ARGV-element
as if it were the argument of an option with character code 1.
Using `-' as the first character of the list of option characters
selects this mode of operation.
The special argument `--' forces an end of option-scanning regardless
of the value of `ordering'. In the case of RETURN_IN_ORDER, only
`--' can cause `gnu_getopt' to return -1 with `gnu_optind' != ARGC. */
static enum {
REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
} ordering;
/* Value of POSIXLY_CORRECT environment variable. */
static char *posixly_correct;
/* Avoid depending on library functions or files
whose names are inconsistent. */
static char *
my_index( const char* str, int chr ) {
while ( *str ) {
if ( *str == chr )
return(char *) str;
str++;
}
return 0;
}
/* Handle permutation of arguments. */
/* Describe the part of ARGV that contains non-options that have
been skipped. `first_nonopt' is the index in ARGV of the first of them;
`last_nonopt' is the index after the last of them. */
static int first_nonopt;
static int last_nonopt;
/* Exchange two adjacent subsequences of ARGV.
One subsequence is elements [first_nonopt,last_nonopt)
which contains all the non-options that have been skipped so far.
The other is elements [last_nonopt,gnu_optind), which contains all
the options processed since those non-options were skipped.
`first_nonopt' and `last_nonopt' are relocated so that they describe
the new indices of the non-options in ARGV after they are moved. */
static void exchange( char **argv );
static void
exchange( char **argv ) {
int bottom = first_nonopt;
int middle = last_nonopt;
int top = gnu_optind;
char *tem;
/* Exchange the shorter segment with the far end of the longer segment.
That puts the shorter segment into the right place.
It leaves the longer segment in the right place overall,
but it consists of two parts that need to be swapped next. */
while ( top > middle && middle > bottom ) {
if ( top - middle > middle - bottom ) {
/* Bottom segment is the short one. */
int len = middle - bottom;
register int i;
/* Swap it with the top part of the top segment. */
for ( i = 0; i < len; i++ ) {
tem = argv[bottom + i];
argv[bottom + i] = argv[top - (middle - bottom) + i];
argv[top - (middle - bottom) + i] = tem;
}
/* Exclude the moved bottom segment from further swapping. */
top -= len;
} else {
/* Top segment is the short one. */
int len = top - middle;
register int i;
/* Swap it with the bottom part of the bottom segment. */
for ( i = 0; i < len; i++ ) {
tem = argv[bottom + i];
argv[bottom + i] = argv[middle + i];
argv[middle + i] = tem;
}
/* Exclude the moved top segment from further swapping. */
bottom += len;
}
}
/* Update records for the slots the non-options now occupy. */
first_nonopt += (gnu_optind - last_nonopt);
last_nonopt = gnu_optind;
}
/* Initialize the internal data when the first call is made. */
static const char *
_gnu_getopt_initialize( int argc,
char *const * argv,
const char *optstring );
static const char *
_gnu_getopt_initialize( int argc,
char *const * argv,
const char *optstring ) {
/* Start processing options with ARGV-element 1 (since ARGV-element 0
is the program name); the sequence of previously skipped
non-option ARGV-elements is empty. */
first_nonopt = last_nonopt = gnu_optind = 1;
nextchar = NULL;
posixly_correct = getenv ("POSIXLY_CORRECT");
/* Determine how to handle the ordering of options and nonoptions. */
if ( optstring[0] == '-' ) {
ordering = RETURN_IN_ORDER;
++optstring;
} else if ( optstring[0] == '+' ) {
ordering = REQUIRE_ORDER;
++optstring;
} else if ( posixly_correct != NULL )
ordering = REQUIRE_ORDER;
else
ordering = PERMUTE;
return optstring;
}
/* Scan elements of ARGV (whose length is ARGC) for option characters
given in OPTSTRING.
If an element of ARGV starts with '-', and is not exactly "-" or "--",
then it is an option element. The characters of this element
(aside from the initial '-') are option characters. If `gnu_getopt'
is called repeatedly, it returns successively each of the option characters
from each of the option elements.
If `gnu_getopt' finds another option character, it returns that character,
updating `gnu_optind' and `nextchar' so that the next call to `gnu_getopt' can
resume the scan with the following option character or ARGV-element.
If there are no more option characters, `gnu_getopt' returns -1.
Then `gnu_optind' is the index in ARGV of the first ARGV-element
that is not an option. (The ARGV-elements have been permuted
so that those that are not options now come last.)
OPTSTRING is a string containing the legitimate option characters.
If an option character is seen that is not listed in OPTSTRING,
return '?' after printing an error message. If you set `gnu_opterr' to
zero, the error message is suppressed but we still return '?'.
If a char in OPTSTRING is followed by a colon, that means it wants an arg,
so the following text in the same ARGV-element, or the text of the following
ARGV-element, is returned in `gnu_optarg'. Two colons mean an option that
wants an optional arg; if there is text in the current ARGV-element,
it is returned in `gnu_optarg', otherwise `gnu_optarg' is set to zero.
If OPTSTRING starts with `-' or `+', it requests different methods of
handling the non-option ARGV-elements.
See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above.
Long-named options begin with `--' instead of `-'.
Their names may be abbreviated as long as the abbreviation is unique
or is an exact match for some defined option. If they have an
argument, it follows the option name in the same ARGV-element, separated
from the option name by a `=', or else the in next ARGV-element.
When `gnu_getopt' finds a long-named option, it returns 0 if that option's
`flag' field is nonzero, the value of the option's `val' field
if the `flag' field is zero.
The elements of ARGV aren't really const, because we permute them.
But we pretend they're const in the prototype to be compatible
with other systems.
LONGOPTS is a vector of `struct option' terminated by an
element containing a name which is zero.
LONGIND returns the index in LONGOPT of the long-named option found.
It is only valid when a long-named option has been found by the most
recent call.
If LONG_ONLY is nonzero, '-' as well as '--' can introduce
long-named options. */
int
_gnu_getopt_internal( int argc,
char *const *argv,
const char *optstring,
const struct option *longopts,
int *longind,
int long_only ) {
gnu_optarg = NULL;
if ( !__gnu_getopt_initialized || gnu_optind == 0 ) {
optstring = _gnu_getopt_initialize (argc, argv, optstring);
gnu_optind = 1; /* Don't scan ARGV[0], the program name. */
__gnu_getopt_initialized = 1;
}
/* Test whether ARGV[gnu_optind] points to a non-option argument.
Either it does not have option syntax, or there is an environment flag
from the shell indicating it is not an option. The later information
is only used when the used in the GNU libc. */
#define NONOPTION_P (argv[gnu_optind][0] != '-' || argv[gnu_optind][1] == '\0')
if ( nextchar == NULL || *nextchar == '\0' ) {
/* Advance to the next ARGV-element. */
/* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been
moved back by the user (who may also have changed the arguments). */
if ( last_nonopt > gnu_optind )
last_nonopt = gnu_optind;
if ( first_nonopt > gnu_optind )
first_nonopt = gnu_optind;
if ( ordering == PERMUTE ) {
/* If we have just processed some options following some non-options,
exchange them so that the options come first. */
if ( first_nonopt != last_nonopt && last_nonopt != gnu_optind )
exchange ((char **) argv);
else if ( last_nonopt != gnu_optind )
first_nonopt = gnu_optind;
/* Skip any additional non-options
and extend the range of non-options previously skipped. */
while ( gnu_optind < argc && NONOPTION_P )
gnu_optind++;
last_nonopt = gnu_optind;
}
/* The special ARGV-element `--' means premature end of options.
Skip it like a null option,
then exchange with previous non-options as if it were an option,
then skip everything else like a non-option. */
if ( gnu_optind != argc && !strcmp (argv[gnu_optind], "--") ) {
gnu_optind++;
if ( first_nonopt != last_nonopt && last_nonopt != gnu_optind )
exchange ((char **) argv);
else if ( first_nonopt == last_nonopt )
first_nonopt = gnu_optind;
last_nonopt = argc;
gnu_optind = argc;
}
/* If we have done all the ARGV-elements, stop the scan
and back over any non-options that we skipped and permuted. */
if ( gnu_optind == argc ) {
/* Set the next-arg-index to point at the non-options
that we previously skipped, so the caller will digest them. */
if ( first_nonopt != last_nonopt )
gnu_optind = first_nonopt;
return -1;
}
/* If we have come to a non-option and did not permute it,
either stop the scan or describe it to the caller and pass it by. */
if ( NONOPTION_P ) {
if ( ordering == REQUIRE_ORDER )
return -1;
gnu_optarg = argv[gnu_optind++];
return 1;
}
/* We have found another option-ARGV-element.
Skip the initial punctuation. */
nextchar = (argv[gnu_optind] + 1
+ (longopts != NULL && argv[gnu_optind][1] == '-'));
}
/* Decode the current option-ARGV-element. */
/* Check whether the ARGV-element is a long option.
If long_only and the ARGV-element has the form "-f", where f is
a valid short option, don't consider it an abbreviated form of
a long option that starts with f. Otherwise there would be no
way to give the -f short option.
On the other hand, if there's a long option "fubar" and
the ARGV-element is "-fu", do consider that an abbreviation of
the long option, just like "--fu", and not "-f" with arg "u".
This distinction seems to be the most useful approach. */
if ( longopts != NULL
&& (argv[gnu_optind][1] == '-'
|| (long_only && (argv[gnu_optind][2] || !my_index (optstring, argv[gnu_optind][1])))) ) {
char *nameend;
const struct option *p;
const struct option *pfound = NULL;
int exact = 0;
int ambig = 0;
int indfound = -1;
int option_index;
for ( nameend = nextchar; *nameend && *nameend != '='; nameend++ )
/* Do nothing. */ ;
/* Test all long options for either exact match
or abbreviated matches. */
for ( p = longopts, option_index = 0; p->name; p++, option_index++ )
if ( !strncmp (p->name, nextchar, nameend - nextchar) ) {
if ( (unsigned int) (nameend - nextchar)
== (unsigned int) strlen (p->name) ) {
/* Exact match found. */
pfound = p;
indfound = option_index;
exact = 1;
break;
} else if ( pfound == NULL ) {
/* First nonexact match found. */
pfound = p;
indfound = option_index;
} else
/* Second or later nonexact match found. */
ambig = 1;
}
if ( ambig && !exact ) {
if ( gnu_opterr )
fprintf (stderr, _("%s: option `%s' is ambiguous\n"),
argv[0], argv[gnu_optind]);
nextchar += strlen (nextchar);
gnu_optind++;
gnu_optopt = 0;
return '?';
}
if ( pfound != NULL ) {
option_index = indfound;
gnu_optind++;
if ( *nameend ) {
/* Don't test has_arg with >, because some C compilers don't
allow it to be used on enums. */
if ( pfound->has_arg )
gnu_optarg = nameend + 1;
else {
if ( gnu_opterr ) {
if ( argv[gnu_optind - 1][1] == '-' ) {
/* --option */
fprintf (stderr,
_("%s: option `--%s' doesn't allow an argument\n"),
argv[0], pfound->name);
} else {
/* +option or -option */
fprintf (stderr,
_("%s: option `%c%s' doesn't allow an argument\n"),
argv[0], argv[gnu_optind - 1][0], pfound->name);
}
}
nextchar += strlen (nextchar);
gnu_optopt = pfound->val;
return '?';
}
} else if ( pfound->has_arg == 1 ) {
if ( gnu_optind < argc )
gnu_optarg = argv[gnu_optind++];
else {
if ( gnu_opterr )
fprintf (stderr,
_("%s: option `%s' requires an argument\n"),
argv[0], argv[gnu_optind - 1]);
nextchar += strlen (nextchar);
gnu_optopt = pfound->val;
return optstring[0] == ':' ? ':' : '?';
}
}
nextchar += strlen (nextchar);
if ( longind != NULL )
*longind = option_index;
if ( pfound->flag ) {
*(pfound->flag) = pfound->val;
return 0;
}
return pfound->val;
}
/* Can't find it as a long option. If this is not gnu_getopt_long_only,
or the option starts with '--' or is not a valid short
option, then it's an error.
Otherwise interpret it as a short option. */
if ( !long_only || argv[gnu_optind][1] == '-'
|| my_index (optstring, *nextchar) == NULL ) {
if ( gnu_opterr ) {
if ( argv[gnu_optind][1] == '-' )
/* --option */
fprintf (stderr, _("%s: unrecognized option `--%s'\n"),
argv[0], nextchar);
else
/* +option or -option */
fprintf (stderr, _("%s: unrecognized option `%c%s'\n"),
argv[0], argv[gnu_optind][0], nextchar);
}
nextchar = (char *) "";
gnu_optind++;
gnu_optopt = 0;
return '?';
}
}
/* Look at and handle the next short option-character. */
{
char c = *nextchar++;
char *temp = my_index (optstring, c);
/* Increment `gnu_optind' when we start to process its last character. */
if ( *nextchar == '\0' )
++gnu_optind;
if ( temp == NULL || c == ':' ) {
if ( gnu_opterr ) {
if ( posixly_correct )
/* 1003.2 specifies the format of this message. */
fprintf (stderr, _("%s: illegal option -- %c\n"),
argv[0], c);
else
fprintf (stderr, _("%s: invalid option -- %c\n"),
argv[0], c);
}
gnu_optopt = c;
return '?';
}
/* Convenience. Treat POSIX -W foo same as long option --foo */
if ( temp[0] == 'W' && temp[1] == ';' ) {
char *nameend;
const struct option *p;
const struct option *pfound = NULL;
int exact = 0;
int ambig = 0;
int indfound = 0;
int option_index;
/* This is an option that requires an argument. */
if ( *nextchar != '\0' ) {
gnu_optarg = nextchar;
/* If we end this ARGV-element by taking the rest as an arg,
we must advance to the next element now. */
gnu_optind++;
} else if ( gnu_optind == argc ) {
if ( gnu_opterr ) {
/* 1003.2 specifies the format of this message. */
fprintf (stderr, _("%s: option requires an argument -- %c\n"),
argv[0], c);
}
gnu_optopt = c;
if ( optstring[0] == ':' )
c = ':';
else
c = '?';
return c;
} else
/* We already incremented `gnu_optind' once;
increment it again when taking next ARGV-elt as argument. */
gnu_optarg = argv[gnu_optind++];
/* gnu_optarg is now the argument, see if it's in the
table of longopts. */
for ( nextchar = nameend = gnu_optarg; *nameend && *nameend != '='; nameend++ )
/* Do nothing. */ ;
/* Test all long options for either exact match
or abbreviated matches. */
for ( p = longopts, option_index = 0; p->name; p++, option_index++ )
if ( !strncmp (p->name, nextchar, nameend - nextchar) ) {
if ( (unsigned int) (nameend - nextchar) == strlen (p->name) ) {
/* Exact match found. */
pfound = p;
indfound = option_index;
exact = 1;
break;
} else if ( pfound == NULL ) {
/* First nonexact match found. */
pfound = p;
indfound = option_index;
} else
/* Second or later nonexact match found. */
ambig = 1;
}
if ( ambig && !exact ) {
if ( gnu_opterr )
fprintf (stderr, _("%s: option `-W %s' is ambiguous\n"),
argv[0], argv[gnu_optind]);
nextchar += strlen (nextchar);
gnu_optind++;
return '?';
}
if ( pfound != NULL ) {
option_index = indfound;
if ( *nameend ) {
/* Don't test has_arg with >, because some C compilers don't
allow it to be used on enums. */
if ( pfound->has_arg )
gnu_optarg = nameend + 1;
else {
if ( gnu_opterr )
fprintf (stderr, _("\
%s: option `-W %s' doesn't allow an argument\n"),
argv[0], pfound->name);
nextchar += strlen (nextchar);
return '?';
}
} else if ( pfound->has_arg == 1 ) {
if ( gnu_optind < argc )
gnu_optarg = argv[gnu_optind++];
else {
if ( gnu_opterr )
fprintf (stderr,
_("%s: option `%s' requires an argument\n"),
argv[0], argv[gnu_optind - 1]);
nextchar += strlen (nextchar);
return optstring[0] == ':' ? ':' : '?';
}
}
nextchar += strlen (nextchar);
if ( longind != NULL )
*longind = option_index;
if ( pfound->flag ) {
*(pfound->flag) = pfound->val;
return 0;
}
return pfound->val;
}
nextchar = NULL;
return 'W'; /* Let the application handle it. */
}
if ( temp[1] == ':' ) {
if ( temp[2] == ':' ) {
/* This is an option that accepts an argument optionally. */
if ( *nextchar != '\0' ) {
gnu_optarg = nextchar;
gnu_optind++;
} else
gnu_optarg = NULL;
nextchar = NULL;
} else {
/* This is an option that requires an argument. */
if ( *nextchar != '\0' ) {
gnu_optarg = nextchar;
/* If we end this ARGV-element by taking the rest as an arg,
we must advance to the next element now. */
gnu_optind++;
} else if ( gnu_optind == argc ) {
if ( gnu_opterr ) {
/* 1003.2 specifies the format of this message. */
fprintf (stderr,
_("%s: option requires an argument -- %c\n"),
argv[0], c);
}
gnu_optopt = c;
if ( optstring[0] == ':' )
c = ':';
else
c = '?';
} else
/* We already incremented `gnu_optind' once;
increment it again when taking next ARGV-elt as argument. */
gnu_optarg = argv[gnu_optind++];
nextchar = NULL;
}
}
return c;
}
}
int
gnu_getopt ( int argc,
char *const *argv,
const char *optstring ) {
return _gnu_getopt_internal (argc, argv, optstring,
(const struct option *) 0,
(int *) 0,
0);
}
#ifdef __cplusplus
} /* end extern "C" */
#endif
#ifdef TEST
/* Compile with -DTEST to make an executable for use in testing
the above definition of `gnu_getopt'. */
int
main (argc, argv)
int argc;
char **argv;
{
int c;
int digit_optind = 0;
while ( 1 ) {
int this_option_optind = gnu_optind ? gnu_optind : 1;
c = gnu_getopt (argc, argv, "abc:d:0123456789");
if ( c == -1 )
break;
switch ( c ) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
if ( digit_optind != 0 && digit_optind != this_option_optind )
fprintf ( stderr, "digits occur in two different argv-elements.\n");
digit_optind = this_option_optind;
fprintf ( stderr, "option %c\n", c);
break;
case 'a':
fprintf ( stderr, "option a\n");
break;
case 'b':
fprintf ( stderr, "option b\n");
break;
case 'c':
fprintf ( stderr, "option c with value `%s'\n", gnu_optarg);
break;
case '?':
break;
default:
fprintf ( stderr, "?? gnu_getopt returned character code 0%o ??\n", c);
}
}
if ( gnu_optind < argc ) {
fprintf (stderr, "non-option ARGV-elements: ");
while ( gnu_optind < argc )
fprintf ( stderr, "%s ", argv[gnu_optind++]);
fprintf ( stderr, "\n");
}
exit (0);
}
#endif /* TEST */

162
src/gnu_getopt_long.c Normal file
View File

@ -0,0 +1,162 @@
/* gnu_getopt_long and getopt_long_only entry points for GNU getopt.
Copyright (C) 1987,88,89,90,91,92,93,94,96,97 Free Software Foundation, Inc.
This file is part of the GNU C Library. Its master source is NOT part of
the C library, however. The master source lives in /gd/gnu/lib.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C Library 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with the GNU C Library; see the file COPYING.LIB. If not,
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
/*
* modified July 9, 1999 by mark gates <mgates@nlanr.net>
* Dec 17, 1999
*
* renamed all functions and variables by prepending "gnu_"
* removed/redid a bunch of stuff under the assumption we're
* using a modern standard C compiler.
* renamed file to gnu_getopt_long.c (from gnu_getopt1.c)
*
* $Id: gnu_getopt_long.c,v 1.1.1.1 2004/05/18 01:50:44 kgibbs Exp $
*/
#include "gnu_getopt.h"
#include <stdio.h>
#include <stdlib.h>
#ifdef __cplusplus
extern "C" {
#endif
int
gnu_getopt_long( int argc,
char *const *argv,
const char *options,
const struct option *long_options,
int *opt_index ) {
return _gnu_getopt_internal (argc, argv, options, long_options, opt_index, 0);
}
/* Like gnu_getopt_long, but '-' as well as '--' can indicate a long option.
If an option that starts with '-' (not '--') doesn't match a long option,
but does match a short option, it is parsed as a short option
instead. */
int
gnu_getopt_long_only( int argc,
char *const *argv,
const char *options,
const struct option *long_options,
int *opt_index ) {
return _gnu_getopt_internal (argc, argv, options, long_options, opt_index, 1);
}
#ifdef __cplusplus
} /* end extern "C" */
#endif
#ifdef TEST
#include <stdio.h>
int
main (argc, argv)
int argc;
char **argv;
{
int c;
int digit_optind = 0;
while ( 1 ) {
int this_option_optind = gnu_optind ? gnu_optind : 1;
int option_index = 0;
static struct option long_options[] =
{
{"add", 1, 0, 0},
{"append", 0, 0, 0},
{"delete", 1, 0, 0},
{"verbose", 0, 0, 0},
{"create", 0, 0, 0},
{"file", 1, 0, 0},
{0, 0, 0, 0}
};
c = gnu_getopt_long (argc, argv, "abc:d:0123456789",
long_options, &option_index);
if ( c == -1 )
break;
switch ( c ) {
case 0:
fprintf ( stderr, "option %s", long_options[option_index].name);
if ( gnu_optarg )
fprintf ( stderr, " with arg %s", gnu_optarg);
fprintf ( stderr, "\n");
break;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
if ( digit_optind != 0 && digit_optind != this_option_optind )
fprintf ( stderr, "digits occur in two different argv-elements.\n");
digit_optind = this_option_optind;
fprintf ( stderr, "option %c\n", c);
break;
case 'a':
fprintf ( stderr, "option a\n");
break;
case 'b':
fprintf ( stderr, "option b\n");
break;
case 'c':
fprintf ( stderr, "option c with value `%s'\n", gnu_optarg);
break;
case 'd':
fprintf ( stderr, "option d with value `%s'\n", gnu_optarg);
break;
case '?':
break;
default:
fprintf ( stderr, "?? gnu_getopt returned character code 0%o ??\n", c);
}
}
if ( gnu_optind < argc ) {
fprintf ( stderr, "non-option ARGV-elements: ");
while ( gnu_optind < argc )
fprintf ( stderr, "%s ", argv[gnu_optind++]);
fprintf ( stderr, "\n");
}
exit (0);
}
#endif /* TEST */

402
src/main.cpp Normal file
View File

@ -0,0 +1,402 @@
/*---------------------------------------------------------------
* Copyright (c) 1999,2000,2001,2002,2003
* The Board of Trustees of the University of Illinois
* All Rights Reserved.
*---------------------------------------------------------------
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software (Iperf) 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:
*
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and
* the following disclaimers.
*
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimers in the documentation and/or other materials
* provided with the distribution.
*
*
* Neither the names of the University of Illinois, NCSA,
* nor the names of its contributors may be used to endorse
* or promote products derived from this Software without
* specific prior written permission.
*
* 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 CONTIBUTORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* ________________________________________________________________
* National Laboratory for Applied Network Research
* National Center for Supercomputing Applications
* University of Illinois at Urbana-Champaign
* http://www.ncsa.uiuc.edu
* ________________________________________________________________
* main.cpp
* by Mark Gates <mgates@nlanr.net>
* & Ajay Tirumala <tirumala@ncsa.uiuc.edu>
* -------------------------------------------------------------------
* main does initialization and creates the various objects that will
* actually run the iperf program, then waits in the Joinall().
* -------------------------------------------------------------------
* headers
* uses
* <stdlib.h>
* <string.h>
*
* <signal.h>
* ------------------------------------------------------------------- */
#define HEADERS()
#include "headers.h"
#include "Settings.hpp"
#include "PerfSocket.hpp"
#include "Locale.h"
#include "Condition.h"
#include "Timestamp.hpp"
#include "Listener.hpp"
#include "List.h"
#include "util.h"
#ifdef WIN32
#include "service.h"
#endif
/* -------------------------------------------------------------------
* prototypes
* ------------------------------------------------------------------- */
// Function called at exit to clean up as much as possible
void cleanup( void );
/* -------------------------------------------------------------------
* global variables
* ------------------------------------------------------------------- */
extern "C" {
// Global flag to signal a user interrupt
int sInterupted = 0;
// Global ID that we increment to be used
// as identifier for SUM reports
int groupID = 0;
// Mutex to protect access to the above ID
Mutex groupCond;
// Condition used to signify advances of the current
// records being accessed in a report and also to
// serialize modification of the report list
Condition ReportCond;
}
// global variables only accessed within this file
// Thread that received the SIGTERM or SIGINT signal
// Used to ensure that if multiple threads receive the
// signal we do not prematurely exit
nthread_t sThread;
// The main thread uses this function to wait
// for all other threads to complete
void waitUntilQuit( void );
/* -------------------------------------------------------------------
* main()
* Entry point into Iperf
*
* sets up signal handlers
* initialize global locks and conditions
* parses settings from environment and command line
* starts up server or client thread
* waits for all threads to complete
* ------------------------------------------------------------------- */
int main( int argc, char **argv ) {
// Set SIGTERM and SIGINT to call our user interrupt function
my_signal( SIGTERM, Sig_Interupt );
my_signal( SIGINT, Sig_Interupt );
#ifndef WIN32
// Ignore broken pipes
signal(SIGPIPE,SIG_IGN);
#else
// Start winsock
WSADATA wsaData;
int rc = WSAStartup( 0x202, &wsaData );
WARN_errno( rc == SOCKET_ERROR, "WSAStartup" );
if (rc == SOCKET_ERROR)
return 0;
// Tell windows we want to handle our own signals
SetConsoleCtrlHandler( sig_dispatcher, true );
#endif
// Initialize global mutexes and conditions
Condition_Initialize ( &ReportCond );
Mutex_Initialize( &groupCond );
Mutex_Initialize( &clients_mutex );
// Initialize the thread subsystem
thread_init( );
// Initialize the interrupt handling thread to 0
sThread = thread_zeroid();
// perform any cleanup when quitting Iperf
atexit( cleanup );
// Allocate the "global" settings
thread_Settings* ext_gSettings = new thread_Settings;
// Initialize settings to defaults
Settings_Initialize( ext_gSettings );
// read settings from environment variables
Settings_ParseEnvironment( ext_gSettings );
// read settings from command-line parameters
Settings_ParseCommandLine( argc, argv, ext_gSettings );
// Check for either having specified client or server
if ( ext_gSettings->mThreadMode == kMode_Client
|| ext_gSettings->mThreadMode == kMode_Listener ) {
#ifdef WIN32
// Start the server as a daemon
// Daemon mode for non-windows in handled
// in the listener_spawn function
if ( isDaemon( ext_gSettings ) ) {
CmdInstallService(argc, argv);
return 0;
}
// Remove the Windows service if requested
if ( isRemoveService( ext_gSettings ) ) {
// remove the service
if ( CmdRemoveService() ) {
fprintf(stderr, "IPerf Service is removed.\n");
return 0;
}
}
#endif
// initialize client(s)
if ( ext_gSettings->mThreadMode == kMode_Client ) {
client_init( ext_gSettings );
}
#ifdef HAVE_THREAD
// start up the reporter and client(s) or listener
{
thread_Settings *into = NULL;
// Create the settings structure for the reporter thread
Settings_Copy( ext_gSettings, &into );
into->mThreadMode = kMode_Reporter;
// Have the reporter launch the client or listener
into->runNow = ext_gSettings;
// Start all the threads that are ready to go
thread_start( into );
}
#else
// No need to make a reporter thread because we don't have threads
thread_start( ext_gSettings );
#endif
} else {
// neither server nor client mode was specified
// print usage and exit
#ifdef WIN32
// In Win32 we also attempt to start a previously defined service
// Starting in 2.0 to restart a previously defined service
// you must call iperf with "iperf -D" or using the environment variable
SERVICE_TABLE_ENTRY dispatchTable[] =
{
{ TEXT(SZSERVICENAME), (LPSERVICE_MAIN_FUNCTION)service_main},
{ NULL, NULL}
};
// Only attempt to start the service if "-D" was specified
if ( !isDaemon(ext_gSettings) ||
// starting the service by SCM, there is no arguments will be passed in.
// the arguments will pass into Service_Main entry.
!StartServiceCtrlDispatcher(dispatchTable) )
// If the service failed to start then print usage
#endif
fprintf( stderr, usage_short, argv[0], argv[0] );
return 0;
}
// wait for other (client, server) threads to complete
thread_joinall();
// all done!
return 0;
} // end main
/* -------------------------------------------------------------------
* Signal handler sets the sInterupted flag, so the object can
* respond appropriately.. [static]
* ------------------------------------------------------------------- */
void Sig_Interupt( int inSigno ) {
#ifdef HAVE_THREAD
// We try to not allow a single interrupt handled by multiple threads
// to completely kill the app so we save off the first thread ID
// then that is the only thread that can supply the next interrupt
if ( thread_equalid( sThread, thread_zeroid() ) ) {
sThread = thread_getid();
} else if ( thread_equalid( sThread, thread_getid() ) ) {
sig_exit( inSigno );
}
// global variable used by threads to see if they were interrupted
sInterupted = 1;
// with threads, stop waiting for non-terminating threads
// (ie Listener Thread)
thread_release_nonterm( 1 );
#else
// without threads, just exit quietly, same as sig_exit()
sig_exit( inSigno );
#endif
}
/* -------------------------------------------------------------------
* Any necesary cleanup before Iperf quits. Called at program exit,
* either by exit() or terminating main().
* ------------------------------------------------------------------- */
void cleanup( void ) {
#ifdef WIN32
// Shutdown Winsock
WSACleanup();
#endif
// clean up the list of clients
Iperf_destroy ( &clients );
// shutdown the thread subsystem
thread_destroy( );
} // end cleanup
#ifdef WIN32
/*--------------------------------------------------------------------
* ServiceStart
*
* each time starting the service, this is the entry point of the service.
* Start the service, certainly it is on server-mode
*
*-------------------------------------------------------------------- */
VOID ServiceStart (DWORD dwArgc, LPTSTR *lpszArgv) {
// report the status to the service control manager.
//
if ( !ReportStatusToSCMgr(
SERVICE_START_PENDING, // service state
NO_ERROR, // exit code
3000) ) // wait hint
goto clean;
thread_Settings* ext_gSettings = new thread_Settings;
// Initialize settings to defaults
Settings_Initialize( ext_gSettings );
// read settings from environment variables
Settings_ParseEnvironment( ext_gSettings );
// read settings from command-line parameters
Settings_ParseCommandLine( dwArgc, lpszArgv, ext_gSettings );
// report the status to the service control manager.
//
if ( !ReportStatusToSCMgr(
SERVICE_START_PENDING, // service state
NO_ERROR, // exit code
3000) ) // wait hint
goto clean;
// if needed, redirect the output into a specified file
if ( !isSTDOUT( ext_gSettings ) ) {
redirect( ext_gSettings->mOutputFileName );
}
// report the status to the service control manager.
//
if ( !ReportStatusToSCMgr(
SERVICE_START_PENDING, // service state
NO_ERROR, // exit code
3000) ) // wait hint
goto clean;
// initialize client(s)
if ( ext_gSettings->mThreadMode == kMode_Client ) {
client_init( ext_gSettings );
}
// start up the reporter and client(s) or listener
{
thread_Settings *into = NULL;
#ifdef HAVE_THREAD
Settings_Copy( ext_gSettings, &into );
into->mThreadMode = kMode_Reporter;
into->runNow = ext_gSettings;
#else
into = ext_gSettings;
#endif
thread_start( into );
}
// report the status to the service control manager.
//
if ( !ReportStatusToSCMgr(
SERVICE_RUNNING, // service state
NO_ERROR, // exit code
0) ) // wait hint
goto clean;
clean:
// wait for other (client, server) threads to complete
thread_joinall();
}
//
// FUNCTION: ServiceStop
//
// PURPOSE: Stops the service
//
// PARAMETERS:
// none
//
// RETURN VALUE:
// none
//
// COMMENTS:
// If a ServiceStop procedure is going to
// take longer than 3 seconds to execute,
// it should spawn a thread to execute the
// stop code, and return. Otherwise, the
// ServiceControlManager will believe that
// the service has stopped responding.
//
VOID ServiceStop() {
#ifdef HAVE_THREAD
Sig_Interupt( 1 );
#else
sig_exit(1);
#endif
}
#endif

495
src/service.c Normal file
View File

@ -0,0 +1,495 @@
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (C) 1993-1997 Microsoft Corporation. All Rights Reserved.
//
// MODULE: service.c
//
// PURPOSE: Implements functions required by all services
// windows.
//
// FUNCTIONS:
// main(int argc, char **argv);
// service_ctrl(DWORD dwCtrlCode);
// service_main(DWORD dwArgc, LPTSTR *lpszArgv);
// CmdInstallService();
// CmdRemoveService();
// ControlHandler ( DWORD dwCtrlType );
// GetLastErrorText( LPTSTR lpszBuf, DWORD dwSize );
//
// COMMENTS:
//
// AUTHOR: Craig Link - Microsoft Developer Support
//
/*
* modified Mar.07, 2002 by Feng Qin <fqin@ncsa.uiuc.edu>
* Mar.15, 2002
*
* removed some functions we don't use at all
* add code to start the service immediately after service is installed
*
* $Id: service.c,v 1.1.1.1 2004/05/18 01:50:44 kgibbs Exp $
*/
#ifdef WIN32
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <process.h>
#include <tchar.h>
#include "service.h"
// internal variables
SERVICE_STATUS ssStatus; // current status of the service
SERVICE_STATUS_HANDLE sshStatusHandle;
DWORD dwErr = 0;
TCHAR szErr[256];
//
// FUNCTION: service_main
//
// PURPOSE: To perform actual initialization of the service
//
// PARAMETERS:
// dwArgc - number of command line arguments
// lpszArgv - array of command line arguments
//
// RETURN VALUE:
// none
//
// COMMENTS:
// This routine performs the service initialization and then calls
// the user defined ServiceStart() routine to perform majority
// of the work.
//
void WINAPI service_main(DWORD dwArgc, LPTSTR *lpszArgv) {
// register our service control handler:
//
sshStatusHandle = RegisterServiceCtrlHandler( TEXT(SZSERVICENAME), service_ctrl);
if ( !sshStatusHandle )
goto clean;
// SERVICE_STATUS members that don't change in example
//
ssStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
ssStatus.dwServiceSpecificExitCode = 0;
// report the status to the service control manager.
//
if ( !ReportStatusToSCMgr(
SERVICE_START_PENDING, // service state
NO_ERROR, // exit code
3000) ) // wait hint
goto clean;
ServiceStart( dwArgc, lpszArgv );
clean:
// try to report the stopped status to the service control manager.
//
if ( sshStatusHandle )
(VOID)ReportStatusToSCMgr(
SERVICE_STOPPED,
dwErr,
0);
return;
}
//
// FUNCTION: service_ctrl
//
// PURPOSE: This function is called by the SCM whenever
// ControlService() is called on this service.
//
// PARAMETERS:
// dwCtrlCode - type of control requested
//
// RETURN VALUE:
// none
//
// COMMENTS:
//
VOID WINAPI service_ctrl(DWORD dwCtrlCode) {
// Handle the requested control code.
//
switch ( dwCtrlCode ) {
// Stop the service.
//
// SERVICE_STOP_PENDING should be reported before
// setting the Stop Event - hServerStopEvent - in
// ServiceStop(). This avoids a race condition
// which may result in a 1053 - The Service did not respond...
// error.
case SERVICE_CONTROL_STOP:
ReportStatusToSCMgr(SERVICE_STOP_PENDING, NO_ERROR, 0);
ServiceStop();
return;
// Update the service status.
//
case SERVICE_CONTROL_INTERROGATE:
break;
// invalid control code
//
default:
break;
}
ReportStatusToSCMgr(SERVICE_STOPPED, NO_ERROR, 0);
// ReportStatusToSCMgr(ssStatus.dwCurrentState, NO_ERROR, 0);
}
//
// FUNCTION: ReportStatusToSCMgr()
//
// PURPOSE: Sets the current status of the service and
// reports it to the Service Control Manager
//
// PARAMETERS:
// dwCurrentState - the state of the service
// dwWin32ExitCode - error code to report
// dwWaitHint - worst case estimate to next checkpoint
//
// RETURN VALUE:
// TRUE - success
// FALSE - failure
//
// COMMENTS:
//
BOOL ReportStatusToSCMgr(DWORD dwCurrentState,
DWORD dwWin32ExitCode,
DWORD dwWaitHint) {
static DWORD dwCheckPoint = 1;
BOOL fResult = TRUE;
if ( dwCurrentState == SERVICE_START_PENDING )
ssStatus.dwControlsAccepted = 0;
else
ssStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;
ssStatus.dwCurrentState = dwCurrentState;
ssStatus.dwWin32ExitCode = dwWin32ExitCode;
ssStatus.dwWaitHint = dwWaitHint;
if ( ( dwCurrentState == SERVICE_RUNNING ) ||
( dwCurrentState == SERVICE_STOPPED ) )
ssStatus.dwCheckPoint = 0;
else
ssStatus.dwCheckPoint = dwCheckPoint++;
// Report the status of the service to the service control manager.
//
if ( !(fResult = SetServiceStatus( sshStatusHandle, &ssStatus)) ) {
AddToMessageLog(TEXT("SetServiceStatus"));
}
return fResult;
}
//
// FUNCTION: AddToMessageLog(LPTSTR lpszMsg)
//
// PURPOSE: Allows any thread to log an error message
//
// PARAMETERS:
// lpszMsg - text for message
//
// RETURN VALUE:
// none
//
// COMMENTS:
//
VOID AddToMessageLog(LPTSTR lpszMsg) {
TCHAR szMsg[256];
HANDLE hEventSource;
LPTSTR lpszStrings[2];
dwErr = GetLastError();
// Use event logging to log the error.
//
hEventSource = RegisterEventSource(NULL, TEXT(SZSERVICENAME));
printf(lpszMsg);
_stprintf(szMsg, TEXT("%s error: %d"), TEXT(SZSERVICENAME), dwErr);
lpszStrings[0] = szMsg;
lpszStrings[1] = lpszMsg;
if ( hEventSource != NULL ) {
ReportEvent(hEventSource, // handle of event source
EVENTLOG_ERROR_TYPE, // event type
0, // event category
0, // event ID
NULL, // current user's SID
2, // strings in lpszStrings
0, // no bytes of raw data
lpszStrings, // array of error strings
NULL); // no raw data
(VOID) DeregisterEventSource(hEventSource);
}
}
///////////////////////////////////////////////////////////////////
//
// The following code handles service installation and removal
//
//
// FUNCTION: CmdInstallService()
//
// PURPOSE: Installs the service and Starts it
//
// PARAMETERS:
// argc: number of arguments
// argv: all of the arguments including the program's name
//
// RETURN VALUE:
// none
//
// COMMENTS:
//
void CmdInstallService(int argc, char **argv) {
SC_HANDLE schService;
SC_HANDLE schSCManager;
TCHAR szPath[512];
if ( GetModuleFileName( NULL, szPath, 512 ) == 0 ) {
_tprintf(TEXT("Unable to install %s - %s\n"), TEXT(SZSERVICEDISPLAYNAME), GetLastErrorText(szErr, 256));
return;
}
schSCManager = OpenSCManager(
NULL, // machine (NULL == local)
NULL, // database (NULL == default)
SC_MANAGER_ALL_ACCESS // access required
);
if ( schSCManager ) {
schService = OpenService(schSCManager, TEXT(SZSERVICENAME), SERVICE_ALL_ACCESS);
if ( !schService ) {
schService = CreateService(
schSCManager, // SCManager database
TEXT(SZSERVICENAME), // name of service
TEXT(SZSERVICEDISPLAYNAME), // name to display
SERVICE_ALL_ACCESS, // desired access
SERVICE_WIN32_OWN_PROCESS, // service type
SERVICE_DEMAND_START, // start type
SERVICE_ERROR_NORMAL, // error control type
szPath, // service's binary
NULL, // no load ordering group
NULL, // no tag identifier
TEXT(SZDEPENDENCIES), // dependencies
NULL, // LocalSystem account
NULL); // no password
} else {
_tprintf(TEXT("%s already installed.\n"), TEXT(SZSERVICEDISPLAYNAME) );
}
if ( schService ) {
if ( QueryServiceStatus( schService, &ssStatus ) ) {
int rc;
if ( ssStatus.dwCurrentState == SERVICE_STOPPED ) {
rc = StartService(schService, argc-1, argv+1);
}
if ( rc != 0 )
_tprintf(TEXT("%s started.\n"), TEXT(SZSERVICEDISPLAYNAME) );
}
CloseServiceHandle(schService);
} else {
_tprintf(TEXT("CreateService failed - %s\n"), GetLastErrorText(szErr, 256));
}
CloseServiceHandle(schSCManager);
} else
_tprintf(TEXT("OpenSCManager failed - %s\n"), GetLastErrorText(szErr,256));
}
//
// FUNCTION: CmdRemoveService()
//
// PURPOSE: Stops and removes the service
//
// PARAMETERS:
// none
//
// RETURN VALUE:
// TRUE: service exists and is removed
// FALSE: service doesn't exist
//
// COMMENTS:
//
BOOL CmdRemoveService() {
BOOL isExist = FALSE;
SC_HANDLE schService;
SC_HANDLE schSCManager;
schSCManager = OpenSCManager(
NULL, // machine (NULL == local)
NULL, // database (NULL == default)
SC_MANAGER_ALL_ACCESS // access required
);
if ( schSCManager ) {
schService = OpenService(schSCManager, TEXT(SZSERVICENAME), SERVICE_ALL_ACCESS);
if ( schService ) {
isExist = TRUE;
// try to stop the service
if ( ControlService( schService, SERVICE_CONTROL_STOP, &ssStatus ) ) {
_tprintf(TEXT("Stopping %s."), TEXT(SZSERVICEDISPLAYNAME));
Sleep( 1000 );
while ( QueryServiceStatus( schService, &ssStatus ) ) {
if ( ssStatus.dwCurrentState == SERVICE_STOP_PENDING ) {
_tprintf(TEXT("."));
Sleep( 1000 );
} else
break;
}
if ( ssStatus.dwCurrentState == SERVICE_STOPPED )
_tprintf(TEXT("\n%s stopped.\n"), TEXT(SZSERVICEDISPLAYNAME) );
else
_tprintf(TEXT("\n%s failed to stop.\n"), TEXT(SZSERVICEDISPLAYNAME) );
}
// now remove the service
if ( DeleteService(schService) )
_tprintf(TEXT("%s removed.\n"), TEXT(SZSERVICEDISPLAYNAME) );
else
_tprintf(TEXT("DeleteService failed - %s\n"), GetLastErrorText(szErr,256));
CloseServiceHandle(schService);
}
CloseServiceHandle(schSCManager);
} else
_tprintf(TEXT("OpenSCManager failed - %s\n"), GetLastErrorText(szErr,256));
return isExist;
}
//
// FUNCTION: CmdStartService()
//
// PURPOSE: Start service if it exists
//
// PARAMETERS:
// argc: number of arguments
// argv: arguments including program's name
//
// RETURN VALUE:
// TRUE: service exists and is started
// FALSE: service doesn't exist
//
// COMMENTS:
//
BOOL CmdStartService(int argc, char **argv) {
BOOL isExist = FALSE;
SC_HANDLE schService;
SC_HANDLE schSCManager;
schSCManager = OpenSCManager(
NULL, // machine (NULL == local)
NULL, // database (NULL == default)
SC_MANAGER_ALL_ACCESS // access required
);
if ( schSCManager ) {
schService = OpenService(schSCManager, TEXT(SZSERVICENAME), SERVICE_ALL_ACCESS);
if ( schService ) {
isExist = TRUE;
if ( QueryServiceStatus( schService, &ssStatus ) ) {
int rc;
if ( ssStatus.dwCurrentState == SERVICE_STOPPED ) {
rc = StartService(schService, argc-1, argv+1);
}
if ( rc != 0 )
_tprintf(TEXT("%s started.\n"), TEXT(SZSERVICEDISPLAYNAME) );
}
CloseServiceHandle(schService);
}
CloseServiceHandle(schSCManager);
} else
_tprintf(TEXT("OpenSCManager failed - %s\n"), GetLastErrorText(szErr,256));
return isExist;
}
//
// FUNCTION: GetLastErrorText
//
// PURPOSE: copies error message text to string
//
// PARAMETERS:
// lpszBuf - destination buffer
// dwSize - size of buffer
//
// RETURN VALUE:
// destination buffer
//
// COMMENTS:
//
LPTSTR GetLastErrorText( LPTSTR lpszBuf, DWORD dwSize ) {
DWORD dwRet;
LPTSTR lpszTemp = NULL;
dwRet = FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |FORMAT_MESSAGE_ARGUMENT_ARRAY,
NULL,
GetLastError(),
LANG_NEUTRAL,
(LPTSTR)&lpszTemp,
0,
NULL );
// supplied buffer is not long enough
if ( !dwRet || ( (long)dwSize < (long)dwRet+14 ) )
lpszBuf[0] = TEXT('\0');
else {
lpszTemp[lstrlen(lpszTemp)-2] = TEXT('\0'); //remove cr and newline character
_stprintf( lpszBuf, TEXT("%s (0x%x)"), lpszTemp, GetLastError() );
}
if ( lpszTemp )
LocalFree((HLOCAL) lpszTemp );
return lpszBuf;
}
#endif

196
src/sockets.c Normal file
View File

@ -0,0 +1,196 @@
/*---------------------------------------------------------------
* Copyright (c) 1999,2000,2001,2002,2003
* The Board of Trustees of the University of Illinois
* All Rights Reserved.
*---------------------------------------------------------------
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software (Iperf) 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:
*
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and
* the following disclaimers.
*
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimers in the documentation and/or other materials
* provided with the distribution.
*
*
* Neither the names of the University of Illinois, NCSA,
* nor the names of its contributors may be used to endorse
* or promote products derived from this Software without
* specific prior written permission.
*
* 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 CONTIBUTORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* ________________________________________________________________
* National Laboratory for Applied Network Research
* National Center for Supercomputing Applications
* University of Illinois at Urbana-Champaign
* http://www.ncsa.uiuc.edu
* ________________________________________________________________
*
* socket.c
* by Mark Gates <mgates@nlanr.net>
* -------------------------------------------------------------------
* set/getsockopt and read/write wrappers
* ------------------------------------------------------------------- */
#include "headers.h"
#include "util.h"
#ifdef __cplusplus
extern "C" {
#endif
/* -------------------------------------------------------------------
* If inMSS > 0, set the TCP maximum segment size for inSock.
* Otherwise leave it as the system default.
* ------------------------------------------------------------------- */
const char warn_mss_fail[] = "\
WARNING: attempt to set TCP maxmimum segment size to %d failed.\n\
Setting the MSS may not be implemented on this OS.\n";
const char warn_mss_notset[] =
"WARNING: attempt to set TCP maximum segment size to %d, but got %d\n";
void setsock_tcp_mss( int inSock, int inMSS ) {
#ifdef TCP_MAXSEG
int rc;
int newMSS;
Socklen_t len;
assert( inSock != INVALID_SOCKET );
if ( inMSS > 0 ) {
/* set */
newMSS = inMSS;
len = sizeof( newMSS );
rc = setsockopt( inSock, IPPROTO_TCP, TCP_MAXSEG, (char*) &newMSS, len );
if ( rc == SOCKET_ERROR ) {
fprintf( stderr, warn_mss_fail, newMSS );
return;
}
/* verify results */
rc = getsockopt( inSock, IPPROTO_TCP, TCP_MAXSEG, (char*) &newMSS, &len );
WARN_errno( rc == SOCKET_ERROR, "getsockopt TCP_MAXSEG" );
if ( newMSS != inMSS ) {
fprintf( stderr, warn_mss_notset, inMSS, newMSS );
}
}
#endif
} /* end setsock_tcp_mss */
/* -------------------------------------------------------------------
* returns the TCP maximum segment size
* ------------------------------------------------------------------- */
int getsock_tcp_mss( int inSock ) {
int theMSS = 0;
#ifdef TCP_MAXSEG
int rc;
Socklen_t len;
assert( inSock >= 0 );
/* query for MSS */
len = sizeof( theMSS );
rc = getsockopt( inSock, IPPROTO_TCP, TCP_MAXSEG, (char*) &theMSS, &len );
WARN_errno( rc == SOCKET_ERROR, "getsockopt TCP_MAXSEG" );
#endif
return theMSS;
} /* end getsock_tcp_mss */
/* -------------------------------------------------------------------
* Attempts to reads n bytes from a socket.
* Returns number actually read, or -1 on error.
* If number read < inLen then we reached EOF.
*
* from Stevens, 1998, section 3.9
* ------------------------------------------------------------------- */
ssize_t readn( int inSock, void *outBuf, size_t inLen ) {
size_t nleft;
ssize_t nread;
char *ptr;
assert( inSock >= 0 );
assert( outBuf != NULL );
assert( inLen > 0 );
ptr = (char*) outBuf;
nleft = inLen;
while ( nleft > 0 ) {
nread = read( inSock, ptr, nleft );
if ( nread < 0 ) {
if ( errno == EINTR )
nread = 0; /* interupted, call read again */
else
return -1; /* error */
} else if ( nread == 0 )
break; /* EOF */
nleft -= nread;
ptr += nread;
}
return(inLen - nleft);
} /* end readn */
/* -------------------------------------------------------------------
* Attempts to write n bytes to a socket.
* returns number actually written, or -1 on error.
* number written is always inLen if there is not an error.
*
* from Stevens, 1998, section 3.9
* ------------------------------------------------------------------- */
ssize_t writen( int inSock, const void *inBuf, size_t inLen ) {
size_t nleft;
ssize_t nwritten;
const char *ptr;
assert( inSock >= 0 );
assert( inBuf != NULL );
assert( inLen > 0 );
ptr = (char*) inBuf;
nleft = inLen;
while ( nleft > 0 ) {
nwritten = write( inSock, ptr, nleft );
if ( nwritten <= 0 ) {
if ( errno == EINTR )
nwritten = 0; /* interupted, call write again */
else
return -1; /* error */
}
nleft -= nwritten;
ptr += nwritten;
}
return inLen;
} /* end writen */
#ifdef __cplusplus
} /* end extern "C" */
#endif

282
src/stdio.c Normal file
View File

@ -0,0 +1,282 @@
/*---------------------------------------------------------------
* Copyright (c) 1999,2000,2001,2002,2003
* The Board of Trustees of the University of Illinois
* All Rights Reserved.
*---------------------------------------------------------------
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software (Iperf) 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:
*
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and
* the following disclaimers.
*
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimers in the documentation and/or other materials
* provided with the distribution.
*
*
* Neither the names of the University of Illinois, NCSA,
* nor the names of its contributors may be used to endorse
* or promote products derived from this Software without
* specific prior written permission.
*
* 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 CONTIBUTORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* ________________________________________________________________
* National Laboratory for Applied Network Research
* National Center for Supercomputing Applications
* University of Illinois at Urbana-Champaign
* http://www.ncsa.uiuc.edu
* ________________________________________________________________
*
* stdio.c
* by Mark Gates <mgates@nlanr.net>
* and Ajay Tirumalla <tirumala@ncsa.uiuc.edu>
* -------------------------------------------------------------------
* input and output numbers, converting with kilo, mega, giga
* ------------------------------------------------------------------- */
#include "headers.h"
#include "util.h"
#ifdef __cplusplus
extern "C" {
#endif
const long kKilo_to_Unit = 1024;
const long kMega_to_Unit = 1024 * 1024;
const long kGiga_to_Unit = 1024 * 1024 * 1024;
const long kkilo_to_Unit = 1000;
const long kmega_to_Unit = 1000 * 1000;
const long kgiga_to_Unit = 1000 * 1000 * 1000;
/* -------------------------------------------------------------------
* byte_atof
*
* Given a string of form #x where # is a number and x is a format
* character listed below, this returns the interpreted integer.
* Gg, Mm, Kk are giga, mega, kilo respectively
* ------------------------------------------------------------------- */
double byte_atof( const char *inString ) {
double theNum;
char suffix = '\0';
assert( inString != NULL );
/* scan the number and any suffices */
sscanf( inString, "%lf%c", &theNum, &suffix );
/* convert according to [Gg Mm Kk] */
switch ( suffix ) {
case 'G': theNum *= kGiga_to_Unit; break;
case 'M': theNum *= kMega_to_Unit; break;
case 'K': theNum *= kKilo_to_Unit; break;
case 'g': theNum *= kgiga_to_Unit; break;
case 'm': theNum *= kmega_to_Unit; break;
case 'k': theNum *= kkilo_to_Unit; break;
default: break;
}
return theNum;
} /* end byte_atof */
/* -------------------------------------------------------------------
* byte_atoi
*
* Given a string of form #x where # is a number and x is a format
* character listed below, this returns the interpreted integer.
* Gg, Mm, Kk are giga, mega, kilo respectively
* ------------------------------------------------------------------- */
max_size_t byte_atoi( const char *inString ) {
double theNum;
char suffix = '\0';
assert( inString != NULL );
/* scan the number and any suffices */
sscanf( inString, "%lf%c", &theNum, &suffix );
/* convert according to [Gg Mm Kk] */
switch ( suffix ) {
case 'G': theNum *= kGiga_to_Unit; break;
case 'M': theNum *= kMega_to_Unit; break;
case 'K': theNum *= kKilo_to_Unit; break;
case 'g': theNum *= kgiga_to_Unit; break;
case 'm': theNum *= kmega_to_Unit; break;
case 'k': theNum *= kkilo_to_Unit; break;
default: break;
}
return (max_size_t) theNum;
} /* end byte_atof */
/* -------------------------------------------------------------------
* constants for byte_printf
* ------------------------------------------------------------------- */
/* used as indices into kConversion[], kLabel_Byte[], and kLabel_bit[] */
enum {
kConv_Unit,
kConv_Kilo,
kConv_Mega,
kConv_Giga
};
/* factor to multiply the number by */
const double kConversion[] =
{
1.0, /* unit */
1.0 / 1024, /* kilo */
1.0 / 1024 / 1024, /* mega */
1.0 / 1024 / 1024 / 1024 /* giga */
};
/* factor to multiply the number by for bits*/
const double kConversionForBits[] =
{
1.0, /* unit */
1.0 / 1000, /* kilo */
1.0 / 1000 / 1000, /* mega */
1.0 / 1000 / 1000 / 1000 /* giga */
};
/* labels for Byte formats [KMG] */
const char* kLabel_Byte[] =
{
"Byte",
"KByte",
"MByte",
"GByte"
};
/* labels for bit formats [kmg] */
const char* kLabel_bit[] =
{
"bit",
"Kbit",
"Mbit",
"Gbit"
};
/* -------------------------------------------------------------------
* byte_snprintf
*
* Given a number in bytes and a format, converts the number and
* prints it out with a bits or bytes label.
* B, K, M, G, A for Byte, Kbyte, Mbyte, Gbyte, adaptive byte
* b, k, m, g, a for bit, Kbit, Mbit, Gbit, adaptive bit
* adaptive picks the "best" one based on the number.
* outString should be at least 11 chars long
* (4 digits + space + 5 chars max + null)
* ------------------------------------------------------------------- */
void byte_snprintf( char* outString, int inLen,
double inNum, char inFormat ) {
int conv;
const char* suffix;
const char* format;
/* convert to bits for [bkmga] */
if ( ! isupper( (int)inFormat ) ) {
inNum *= 8;
}
switch ( toupper(inFormat) ) {
case 'B': conv = kConv_Unit; break;
case 'K': conv = kConv_Kilo; break;
case 'M': conv = kConv_Mega; break;
case 'G': conv = kConv_Giga; break;
default:
case 'A': {
double tmpNum = inNum;
conv = kConv_Unit;
if ( isupper((int)inFormat) ) {
while ( tmpNum >= 1024.0 && conv <= kConv_Giga ) {
tmpNum /= 1024.0;
conv++;
}
} else {
while ( tmpNum >= 1000.0 && conv <= kConv_Giga ) {
tmpNum /= 1000.0;
conv++;
}
}
break;
}
}
if ( ! isupper ((int)inFormat) ) {
inNum *= kConversionForBits[ conv ];
suffix = kLabel_bit[conv];
} else {
inNum *= kConversion [conv];
suffix = kLabel_Byte[ conv ];
}
/* print such that we always fit in 4 places */
if ( inNum < 9.995 ) { /* 9.995 would be rounded to 10.0 */
format = "%4.2f %s"; /* #.## */
} else if ( inNum < 99.95 ) { /* 99.95 would be rounded to 100 */
format = "%4.1f %s"; /* ##.# */
} else if ( inNum < 999.5 ) { /* 999.5 would be rounded to 1000 */
format = " %4.0f %s"; /* ### */
} else { /* 1000-1024 fits in 4 places
* If not using Adaptive sizes then
* this code will not control spaces*/
format = "%4.0f %s"; /* #### */
}
snprintf( outString, inLen, format, inNum, suffix );
} /* end byte_snprintf */
/* -------------------------------------------------------------------
* redirect
*
* redirect the stdout into a specified file
* return: none
* ------------------------------------------------------------------- */
void redirect(const char *inOutputFileName) {
#ifdef WIN32
FILE *fp;
if ( inOutputFileName == NULL ) {
fprintf(stderr, "should specify the output file name.\n");
return;
}
fp = freopen(inOutputFileName, "a+", stdout);
if ( fp == NULL ) {
fprintf(stderr, "redirect stdout failed!\n");
return;
}
#endif
return;
}
#ifdef __cplusplus
} /* end extern "C" */
#endif

177
src/tcp_window_size.c Normal file
View File

@ -0,0 +1,177 @@
/*---------------------------------------------------------------
* Copyright (c) 1999,2000,2001,2002,2003
* The Board of Trustees of the University of Illinois
* All Rights Reserved.
*---------------------------------------------------------------
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software (Iperf) 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:
*
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and
* the following disclaimers.
*
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimers in the documentation and/or other materials
* provided with the distribution.
*
*
* Neither the names of the University of Illinois, NCSA,
* nor the names of its contributors may be used to endorse
* or promote products derived from this Software without
* specific prior written permission.
*
* 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 CONTIBUTORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* ________________________________________________________________
* National Laboratory for Applied Network Research
* National Center for Supercomputing Applications
* University of Illinois at Urbana-Champaign
* http://www.ncsa.uiuc.edu
* ________________________________________________________________
*
* tcp_window_size.c
* by Mark Gates <mgates@nlanr.net>
* -------------------------------------------------------------------
* set/getsockopt
* ------------------------------------------------------------------- */
#include "headers.h"
#include "util.h"
#ifdef __cplusplus
extern "C" {
#endif
/* -------------------------------------------------------------------
* If inTCPWin > 0, set the TCP window size (via the socket buffer
* sizes) for inSock. Otherwise leave it as the system default.
*
* This must be called prior to calling listen() or connect() on
* the socket, for TCP window sizes > 64 KB to be effective.
*
* This now works on UNICOS also, by setting TCP_WINSHIFT.
* This now works on AIX, by enabling RFC1323.
* returns -1 on error, 0 on no error.
* ------------------------------------------------------------------- */
int setsock_tcp_windowsize( int inSock, int inTCPWin, int inSend ) {
#ifdef SO_SNDBUF
int rc;
int newTCPWin;
assert( inSock >= 0 );
if ( inTCPWin > 0 ) {
#ifdef TCP_WINSHIFT
/* UNICOS requires setting the winshift explicitly */
if ( inTCPWin > 65535 ) {
int winShift = 0;
int scaledWin = inTCPWin >> 16;
while ( scaledWin > 0 ) {
scaledWin >>= 1;
winShift++;
}
/* set TCP window shift */
rc = setsockopt( inSock, IPPROTO_TCP, TCP_WINSHIFT,
(char*) &winShift, sizeof( winShift ));
if ( rc < 0 ) {
return rc;
}
/* Note: you cannot verify TCP window shift, since it returns
* a structure and not the same integer we use to set it. (ugh) */
}
#endif /* TCP_WINSHIFT */
#ifdef TCP_RFC1323
/* On AIX, RFC 1323 extensions can be set system-wide,
* using the 'no' network options command. But we can also set them
* per-socket, so let's try just in case. */
if ( inTCPWin > 65535 ) {
/* enable RFC 1323 */
int on = 1;
rc = setsockopt( inSock, IPPROTO_TCP, TCP_RFC1323,
(char*) &on, sizeof( on ));
if ( rc < 0 ) {
return rc;
}
}
#endif /* TCP_RFC1323 */
if ( !inSend ) {
/* receive buffer -- set
* note: results are verified after connect() or listen(),
* since some OS's don't show the corrected value until then. */
newTCPWin = inTCPWin;
rc = setsockopt( inSock, SOL_SOCKET, SO_RCVBUF,
(char*) &newTCPWin, sizeof( newTCPWin ));
} else {
/* send buffer -- set
* note: results are verified after connect() or listen(),
* since some OS's don't show the corrected value until then. */
newTCPWin = inTCPWin;
rc = setsockopt( inSock, SOL_SOCKET, SO_SNDBUF,
(char*) &newTCPWin, sizeof( newTCPWin ));
}
if ( rc < 0 ) {
return rc;
}
}
#endif /* SO_SNDBUF */
return 0;
} /* end setsock_tcp_windowsize */
/* -------------------------------------------------------------------
* returns the TCP window size (on the sending buffer, SO_SNDBUF),
* or -1 on error.
* ------------------------------------------------------------------- */
int getsock_tcp_windowsize( int inSock, int inSend ) {
int theTCPWin = 0;
#ifdef SO_SNDBUF
int rc;
Socklen_t len;
/* send buffer -- query for buffer size */
len = sizeof( theTCPWin );
if ( inSend ) {
rc = getsockopt( inSock, SOL_SOCKET, SO_SNDBUF,
(char*) &theTCPWin, &len );
} else {
rc = getsockopt( inSock, SOL_SOCKET, SO_RCVBUF,
(char*) &theTCPWin, &len );
}
if ( rc < 0 ) {
return rc;
}
#endif
return theTCPWin;
} /* end getsock_tcp_windowsize */
#ifdef __cplusplus
} /* end extern "C" */
#endif