aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjjako <jjako>2003-10-13 20:33:30 +0000
committerjjako <jjako>2003-10-13 20:33:30 +0000
commit08d331db63cf42d16d0b2b00533a37fde79eb2c2 (patch)
treef21b884722d5e3a1f7bc5c9ea261a6a04fdaf822
parent48c205f3f02161cc86d97cac92577f19eda2ba34 (diff)
First attempt at a GTP1 implementation
-rw-r--r--aclocal.m4241
-rw-r--r--config.h.in6
-rwxr-xr-xconfigure2269
-rw-r--r--ggsn/ggsn.c40
-rw-r--r--gtp/gtp.c2071
-rw-r--r--gtp/gtp.h254
-rw-r--r--gtp/gtpie.c47
-rw-r--r--gtp/gtpie.h74
-rw-r--r--gtp/pdp.c7
-rw-r--r--gtp/pdp.h18
-rw-r--r--gtp/queue.c8
-rw-r--r--gtp/queue.h7
-rw-r--r--sgsnemu/sgsnemu.c49
13 files changed, 3282 insertions, 1809 deletions
diff --git a/aclocal.m4 b/aclocal.m4
index eef9beb..d9b5fbb 100644
--- a/aclocal.m4
+++ b/aclocal.m4
@@ -118,6 +118,8 @@ AC_REQUIRE([AC_PROG_CC])dnl
AC_REQUIRE([AC_PROG_LD])dnl
AC_REQUIRE([AC_PROG_LD_RELOAD_FLAG])dnl
AC_REQUIRE([AC_PROG_NM])dnl
+AC_REQUIRE([LT_AC_PROG_SED])dnl
+
AC_REQUIRE([AC_PROG_LN_S])dnl
AC_REQUIRE([AC_DEPLIBS_CHECK_METHOD])dnl
AC_REQUIRE([AC_OBJEXT])dnl
@@ -285,9 +287,12 @@ hpux*) # Its linker distinguishes data from code symbols
lt_cv_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern char \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'"
lt_cv_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'"
;;
-irix*)
+irix* | nonstopux*)
symcode='[[BCDEGRST]]'
;;
+osf*)
+ symcode='[[BCDEGQRST]]'
+ ;;
solaris* | sysv5*)
symcode='[[BDT]]'
;;
@@ -384,7 +389,7 @@ EOF
save_CFLAGS="$CFLAGS"
LIBS="conftstm.$ac_objext"
CFLAGS="$CFLAGS$no_builtin_flag"
- if AC_TRY_EVAL(ac_link) && test -s conftest; then
+ if AC_TRY_EVAL(ac_link) && test -s conftest$ac_exeext; then
pipe_works=yes
fi
LIBS="$save_LIBS"
@@ -928,7 +933,7 @@ AC_CACHE_VAL(lt_cv_prog_cc_pic,
# like `-m68040'.
lt_cv_prog_cc_pic='-m68020 -resident32 -malways-restore-a4'
;;
- beos* | irix5* | irix6* | osf3* | osf4* | osf5*)
+ beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
# PIC is the default for these OSes.
;;
darwin* | rhapsody*)
@@ -971,7 +976,7 @@ AC_CACHE_VAL(lt_cv_prog_cc_pic,
lt_cv_prog_cc_pic='+Z'
;;
- irix5* | irix6*)
+ irix5* | irix6* | nonstopux*)
lt_cv_prog_cc_wl='-Wl,'
lt_cv_prog_cc_static='-non_shared'
# PIC (with -KPIC) is the default.
@@ -1015,11 +1020,7 @@ AC_CACHE_VAL(lt_cv_prog_cc_pic,
sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
lt_cv_prog_cc_pic='-KPIC'
lt_cv_prog_cc_static='-Bstatic'
- if test "x$host_vendor" = xsni; then
- lt_cv_prog_cc_wl='-LD'
- else
- lt_cv_prog_cc_wl='-Wl,'
- fi
+ lt_cv_prog_cc_wl='-Wl,'
;;
uts4*)
@@ -1384,7 +1385,7 @@ EOF
# If the export-symbols file already is a .def file (1st line
# is EXPORTS), use it as is.
# If DATA tags from a recent dlltool are present, honour them!
- archive_expsym_cmds='if test "x`head -1 $export_symbols`" = xEXPORTS; then
+ archive_expsym_cmds='if test "x`sed 1q $export_symbols`" = xEXPORTS; then
cp $export_symbols $output_objdir/$soname-def;
else
echo EXPORTS > $output_objdir/$soname-def;
@@ -1393,6 +1394,7 @@ EOF
set dummy \$symbol;
case \[$]# in
2) echo " \[$]2 @ \$_lt_hint ; " >> $output_objdir/$soname-def;;
+ 4) echo " \[$]2 \[$]3 \[$]4 ; " >> $output_objdir/$soname-def; _lt_hint=`expr \$_lt_hint - 1`;;
*) echo " \[$]2 @ \$_lt_hint \[$]3 ; " >> $output_objdir/$soname-def;;
esac;
_lt_hint=`expr 1 + \$_lt_hint`;
@@ -1505,10 +1507,12 @@ else
# need to do runtime linking.
case $host_os in aix4.[[23]]|aix4.[[23]].*|aix5*)
for ld_flag in $LDFLAGS; do
- if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then
+ case $ld_flag in
+ *-brtl*)
aix_use_runtimelinking=yes
break
- fi
+ ;;
+ esac
done
esac
@@ -1622,8 +1626,9 @@ else
esac
# FIXME: Relying on posixy $() will cause problems for
# cross-compilation, but unfortunately the echo tests do not
- # yet detect zsh echo's removal of \ escapes.
- archive_cmds='$nonopt $(test "x$module" = xyes && echo -bundle || echo -dynamiclib) $allow_undefined_flag -o $lib $libobjs $deplibs$linker_flags -install_name $rpath/$soname $verstring'
+ # yet detect zsh echo's removal of \ escapes. Also zsh mangles
+ # `"' quotes if we put them in here... so don't!
+ archive_cmds='$CC -r -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs && $CC $(test .$module = .yes && echo -bundle || echo -dynamiclib) $allow_undefined_flag -o $lib ${lib}-master.o $deplibs$linker_flags $(test .$module != .yes && echo -install_name $rpath/$soname $verstring)'
# We need to add '_' to the symbols in $export_symbols first
#archive_expsym_cmds="$archive_cmds"' && strip -s $export_symbols'
hardcode_direct=yes
@@ -1675,13 +1680,14 @@ else
export_dynamic_flag_spec='${wl}-E'
;;
- irix5* | irix6*)
+ irix5* | irix6* | nonstopux*)
if test "$GCC" = yes; then
archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
else
archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
+ hardcode_libdir_flag_spec='-rpath $libdir'
fi
- hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
hardcode_libdir_separator=:
link_all_deplibs=yes
;;
@@ -1709,7 +1715,7 @@ else
hardcode_direct=yes
hardcode_shlibpath_var=no
if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
- archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $linker_flags'
+ archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
export_dynamic_flag_spec='${wl}-E'
else
@@ -1719,7 +1725,7 @@ else
hardcode_libdir_flag_spec='-R$libdir'
;;
*)
- archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $linker_flags'
+ archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
;;
esac
@@ -1831,13 +1837,23 @@ EOF
;;
sysv4)
- if test "x$host_vendor" = xsno; then
- archive_cmds='$LD -G -Bsymbolic -h $soname -o $lib $libobjs $deplibs $linker_flags'
- hardcode_direct=yes # is this really true???
- else
- archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
- hardcode_direct=no #Motorola manual says yes, but my tests say they lie
- fi
+ case $host_vendor in
+ sni)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_direct=yes # is this really true???
+ ;;
+ siemens)
+ ## LD is ld it makes a PLAMLIB
+ ## CC just makes a GrossModule.
+ archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags'
+ reload_cmds='$CC -r -o $output$reload_objs'
+ hardcode_direct=no
+ ;;
+ motorola)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_direct=no #Motorola manual says yes, but my tests say they lie
+ ;;
+ esac
runpath_var='LD_RUN_PATH'
hardcode_shlibpath_var=no
;;
@@ -1978,6 +1994,9 @@ aix3*)
aix4* | aix5*)
version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ hardcode_into_libs=yes
if test "$host_cpu" = ia64; then
# AIX 5 supports IA64
library_names_spec='${libname}${release}.so$major ${libname}${release}.so$versuffix $libname.so'
@@ -2016,6 +2035,7 @@ aix4* | aix5*)
fi
shlibpath_var=LIBPATH
fi
+ hardcode_into_libs=yes
;;
amigaos*)
@@ -2063,7 +2083,7 @@ cygwin* | mingw* | pw32*)
;;
yes,mingw*)
library_names_spec='${libname}`echo ${release} | sed -e 's/[[.]]/-/g'`${versuffix}.dll'
- sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | sed -e "s/^libraries://" -e "s/;/ /g"`
+ sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | sed -e "s/^libraries://" -e "s/;/ /g" -e "s,=/,/,g"`
;;
yes,pw32*)
library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | sed -e 's/[.]/-/g'`${versuffix}.dll'
@@ -2146,14 +2166,17 @@ hpux9* | hpux10* | hpux11*)
postinstall_cmds='chmod 555 $lib'
;;
-irix5* | irix6*)
- version_type=irix
+irix5* | irix6* | nonstopux*)
+ case $host_os in
+ nonstopux*) version_type=nonstopux ;;
+ *) version_type=irix ;;
+ esac
need_lib_prefix=no
need_version=no
soname_spec='${libname}${release}.so$major'
library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major ${libname}${release}.so $libname.so'
case $host_os in
- irix5*)
+ irix5* | nonstopux*)
libsuff= shlibsuff=
;;
*)
@@ -2198,6 +2221,26 @@ linux-gnu*)
# people can always --disable-shared, the test was removed, and we
# assume the GNU/Linux dynamic linker is in use.
dynamic_linker='GNU/Linux ld.so'
+
+ # Find out which ABI we are using (multilib Linux x86_64 hack).
+ libsuff=
+ case "$host_cpu" in
+ x86_64*|s390x*)
+ echo '[#]line __oline__ "configure"' > conftest.$ac_ext
+ if AC_TRY_EVAL(ac_compile); then
+ case `/usr/bin/file conftest.$ac_objext` in
+ *64-bit*)
+ libsuff=64
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+ *)
+ ;;
+ esac
+ sys_lib_dlsearch_path_spec="/lib${libsuff} /usr/lib${libsuff}"
+ sys_lib_search_path_spec="/lib${libsuff} /usr/lib${libsuff} /usr/local/lib${libsuff}"
;;
netbsd*)
@@ -2257,11 +2300,12 @@ os2*)
osf3* | osf4* | osf5*)
version_type=osf
need_version=no
- soname_spec='${libname}${release}.so'
- library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so $libname.so'
+ soname_spec='${libname}${release}.so$major'
+ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
shlibpath_var=LD_LIBRARY_PATH
sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec"
+ hardcode_into_libs=yes
;;
sco3.2v5*)
@@ -2304,6 +2348,12 @@ sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
case $host_vendor in
sni)
shlibpath_overrides_runpath=no
+ need_lib_prefix=no
+ export_dynamic_flag_spec='${wl}-Blargedynsym'
+ runpath_var=LD_RUN_PATH
+ ;;
+ siemens)
+ need_lib_prefix=no
;;
motorola)
need_lib_prefix=no
@@ -2458,7 +2508,7 @@ if test -f "$ltmain"; then
# Now quote all the things that may contain metacharacters while being
# careful not to overquote the AC_SUBSTed values. We take copies of the
# variables and quote the copies for generation of the libtool script.
- for var in echo old_CC old_CFLAGS \
+ for var in echo old_CC old_CFLAGS SED \
AR AR_FLAGS CC LD LN_S NM SHELL \
reload_flag reload_cmds wl \
pic_flag link_static_flag no_builtin_flag export_dynamic_flag_spec \
@@ -2520,8 +2570,11 @@ if test -f "$ltmain"; then
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
+# A sed that does not truncate output.
+SED=$lt_SED
+
# Sed that helps us avoid accidentally triggering echo(1) options like -n.
-Xsed="sed -e s/^X//"
+Xsed="${SED} -e s/^X//"
# The HP-UX ksh and POSIX shell print the target directory to stdout
# if CDPATH is set.
@@ -3282,7 +3335,7 @@ test -n "$reload_flag" && reload_flag=" $reload_flag"
# AC_DEPLIBS_CHECK_METHOD - how to check for library dependencies
# -- PORTME fill in with the dynamic library characteristics
AC_DEFUN([AC_DEPLIBS_CHECK_METHOD],
-[AC_CACHE_CHECK([how to recognise dependant libraries],
+[AC_CACHE_CHECK([how to recognise dependent libraries],
lt_cv_deplibs_check_method,
[lt_cv_file_magic_cmd='$MAGIC_CMD'
lt_cv_file_magic_test_file=
@@ -3357,9 +3410,9 @@ hpux10.20*|hpux11*)
lt_cv_file_magic_test_file=/usr/lib/libc.sl
;;
-irix5* | irix6*)
+irix5* | irix6* | nonstopux*)
case $host_os in
- irix5*)
+ irix5* | nonstopux*)
# this will be overridden with pass_all, but let us keep it just in case
lt_cv_deplibs_check_method="file_magic ELF 32-bit MSB dynamic lib MIPS - version 1"
;;
@@ -3381,7 +3434,7 @@ irix5* | irix6*)
# This must be Linux ELF.
linux-gnu*)
case $host_cpu in
- alpha* | hppa* | i*86 | powerpc* | sparc* | ia64* | s390* )
+ alpha* | hppa* | i*86 | mips | mipsel | powerpc* | sparc* | ia64* | s390* | x86_64*)
lt_cv_deplibs_check_method=pass_all ;;
*)
# glibc up to 2.1.1 does not perform some relocations on ARM
@@ -3452,6 +3505,9 @@ sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib"
lt_cv_file_magic_test_file=/lib/libc.so
;;
+ siemens)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
esac
;;
esac
@@ -3517,12 +3573,12 @@ esac
])
# AC_LIBLTDL_CONVENIENCE[(dir)] - sets LIBLTDL to the link flags for
-# the libltdl convenience library and INCLTDL to the include flags for
+# the libltdl convenience library and LTDLINCL to the include flags for
# the libltdl header and adds --enable-ltdl-convenience to the
-# configure arguments. Note that LIBLTDL and INCLTDL are not
+# configure arguments. Note that LIBLTDL and LTDLINCL are not
# AC_SUBSTed, nor is AC_CONFIG_SUBDIRS called. If DIR is not
# provided, it is assumed to be `libltdl'. LIBLTDL will be prefixed
-# with '${top_builddir}/' and INCLTDL will be prefixed with
+# with '${top_builddir}/' and LTDLINCL will be prefixed with
# '${top_srcdir}/' (note the single quotes!). If your package is not
# flat and you're not using automake, define top_builddir and
# top_srcdir appropriately in the Makefiles.
@@ -3534,16 +3590,18 @@ AC_DEFUN([AC_LIBLTDL_CONVENIENCE],
ac_configure_args="$ac_configure_args --enable-ltdl-convenience" ;;
esac
LIBLTDL='${top_builddir}/'ifelse($#,1,[$1],['libltdl'])/libltdlc.la
- INCLTDL='-I${top_srcdir}/'ifelse($#,1,[$1],['libltdl'])
+ LTDLINCL='-I${top_srcdir}/'ifelse($#,1,[$1],['libltdl'])
+ # For backwards non-gettext consistent compatibility...
+ INCLTDL="$LTDLINCL"
])
# AC_LIBLTDL_INSTALLABLE[(dir)] - sets LIBLTDL to the link flags for
-# the libltdl installable library and INCLTDL to the include flags for
+# the libltdl installable library and LTDLINCL to the include flags for
# the libltdl header and adds --enable-ltdl-install to the configure
-# arguments. Note that LIBLTDL and INCLTDL are not AC_SUBSTed, nor is
+# arguments. Note that LIBLTDL and LTDLINCL are not AC_SUBSTed, nor is
# AC_CONFIG_SUBDIRS called. If DIR is not provided and an installed
# libltdl is not found, it is assumed to be `libltdl'. LIBLTDL will
-# be prefixed with '${top_builddir}/' and INCLTDL will be prefixed
+# be prefixed with '${top_builddir}/' and LTDLINCL will be prefixed
# with '${top_srcdir}/' (note the single quotes!). If your package is
# not flat and you're not using automake, define top_builddir and
# top_srcdir appropriately in the Makefiles.
@@ -3561,12 +3619,14 @@ AC_DEFUN([AC_LIBLTDL_INSTALLABLE],
if test x"$enable_ltdl_install" = x"yes"; then
ac_configure_args="$ac_configure_args --enable-ltdl-install"
LIBLTDL='${top_builddir}/'ifelse($#,1,[$1],['libltdl'])/libltdl.la
- INCLTDL='-I${top_srcdir}/'ifelse($#,1,[$1],['libltdl'])
+ LTDLINCL='-I${top_srcdir}/'ifelse($#,1,[$1],['libltdl'])
else
ac_configure_args="$ac_configure_args --enable-ltdl-install=no"
LIBLTDL="-lltdl"
- INCLTDL=
+ LTDLINCL=
fi
+ # For backwards non-gettext consistent compatibility...
+ INCLTDL="$LTDLINCL"
])
# old names
@@ -3581,6 +3641,95 @@ AC_DEFUN([AM_PROG_NM], [AC_PROG_NM])
# This is just to silence aclocal about the macro not being used
ifelse([AC_DISABLE_FAST_INSTALL])
+# NOTE: This macro has been submitted for inclusion into #
+# GNU Autoconf as AC_PROG_SED. When it is available in #
+# a released version of Autoconf we should remove this #
+# macro and use it instead. #
+# LT_AC_PROG_SED
+# --------------
+# Check for a fully-functional sed program, that truncates
+# as few characters as possible. Prefer GNU sed if found.
+AC_DEFUN([LT_AC_PROG_SED],
+[AC_MSG_CHECKING([for a sed that does not truncate output])
+AC_CACHE_VAL(lt_cv_path_SED,
+[# Loop through the user's path and test for sed and gsed.
+# Then use that list of sed's as ones to test for truncation.
+as_executable_p="test -f"
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in sed gsed; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then
+ _sed_list="$_sed_list $as_dir/$ac_prog$ac_exec_ext"
+ fi
+ done
+ done
+done
+
+ # Create a temporary directory, and hook for its removal unless debugging.
+$debug ||
+{
+ trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0
+ trap '{ (exit 1); exit 1; }' 1 2 13 15
+}
+
+# Create a (secure) tmp directory for tmp files.
+: ${TMPDIR=/tmp}
+{
+ tmp=`(umask 077 && mktemp -d -q "$TMPDIR/sedXXXXXX") 2>/dev/null` &&
+ test -n "$tmp" && test -d "$tmp"
+} ||
+{
+ tmp=$TMPDIR/sed$$-$RANDOM
+ (umask 077 && mkdir $tmp)
+} ||
+{
+ echo "$me: cannot create a temporary directory in $TMPDIR" >&2
+ { (exit 1); exit 1; }
+}
+ _max=0
+ _count=0
+ # Add /usr/xpg4/bin/sed as it is typically found on Solaris
+ # along with /bin/sed that truncates output.
+ for _sed in $_sed_list /usr/xpg4/bin/sed; do
+ test ! -f ${_sed} && break
+ cat /dev/null > "$tmp/sed.in"
+ _count=0
+ echo ${ECHO_N-$ac_n} "0123456789${ECHO_C-$ac_c}" >"$tmp/sed.in"
+ # Check for GNU sed and select it if it is found.
+ if "${_sed}" --version 2>&1 < /dev/null | egrep '(GNU)' > /dev/null; then
+ lt_cv_path_SED=${_sed}
+ break
+ fi
+ while true; do
+ cat "$tmp/sed.in" "$tmp/sed.in" >"$tmp/sed.tmp"
+ mv "$tmp/sed.tmp" "$tmp/sed.in"
+ cp "$tmp/sed.in" "$tmp/sed.nl"
+ echo >>"$tmp/sed.nl"
+ ${_sed} -e 's/a$//' < "$tmp/sed.nl" >"$tmp/sed.out" || break
+ cmp -s "$tmp/sed.out" "$tmp/sed.nl" || break
+ # 40000 chars as input seems more than enough
+ test $_count -gt 10 && break
+ _count=`expr $_count + 1`
+ if test $_count -gt $_max; then
+ _max=$_count
+ lt_cv_path_SED=$_sed
+ fi
+ done
+ done
+ rm -rf "$tmp"
+])
+if test "X$SED" != "X"; then
+ lt_cv_path_SED=$SED
+else
+ SED=$lt_cv_path_SED
+fi
+AC_MSG_RESULT([$SED])
+])
+
# Do all the work for Automake. -*- Autoconf -*-
# This macro actually does too much some checks are only needed if
diff --git a/config.h.in b/config.h.in
index e27fa33..39b59f8 100644
--- a/config.h.in
+++ b/config.h.in
@@ -18,7 +18,8 @@
/* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H
-/* Define to 1 if your system has a working `malloc' function. */
+/* 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. */
@@ -114,6 +115,9 @@
/* Define to empty if `const' does not conform to ANSI C. */
#undef const
+/* Define to rpl_malloc if the replacement function should be used. */
+#undef malloc
+
/* Define to `int' if <sys/types.h> does not define. */
#undef mode_t
diff --git a/configure b/configure
index f9d86bf..847ffa1 100755
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.53 for openggsn 0.61b.
+# Generated by GNU Autoconf 2.57 for openggsn 0.61b.
#
# Report bugs to <jj@openggsn.org>.
#
@@ -8,173 +8,6 @@
# Free Software Foundation, Inc.
# This configure script is free software; the Free Software Foundation
# gives unlimited permission to copy, distribute and modify it.
-
-# Find the correct PATH separator. Usually this is `:', but
-# DJGPP uses `;' like DOS.
-if test "X${PATH_SEPARATOR+set}" != Xset; then
- UNAME=${UNAME-`uname 2>/dev/null`}
- case X$UNAME in
- *-DOS) lt_cv_sys_path_separator=';' ;;
- *) lt_cv_sys_path_separator=':' ;;
- esac
- PATH_SEPARATOR=$lt_cv_sys_path_separator
-fi
-
-
-# Check that we are running under the correct shell.
-SHELL=${CONFIG_SHELL-/bin/sh}
-
-case X$ECHO in
-X*--fallback-echo)
- # Remove one level of quotation (which was required for Make).
- ECHO=`echo "$ECHO" | sed 's,\\\\\$\\$0,'$0','`
- ;;
-esac
-
-echo=${ECHO-echo}
-if test "X$1" = X--no-reexec; then
- # Discard the --no-reexec flag, and continue.
- shift
-elif test "X$1" = X--fallback-echo; then
- # Avoid inline document here, it may be left over
- :
-elif test "X`($echo '\t') 2>/dev/null`" = 'X\t'; then
- # Yippee, $echo works!
- :
-else
- # Restart under the correct shell.
- exec $SHELL "$0" --no-reexec ${1+"$@"}
-fi
-
-if test "X$1" = X--fallback-echo; then
- # used as fallback echo
- shift
- cat <<EOF
-
-EOF
- exit 0
-fi
-
-# The HP-UX ksh and POSIX shell print the target directory to stdout
-# if CDPATH is set.
-if test "X${CDPATH+set}" = Xset; then CDPATH=:; export CDPATH; fi
-
-if test -z "$ECHO"; then
-if test "X${echo_test_string+set}" != Xset; then
-# find a string as large as possible, as long as the shell can cope with it
- for cmd in 'sed 50q "$0"' 'sed 20q "$0"' 'sed 10q "$0"' 'sed 2q "$0"' 'echo test'; do
- # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ...
- if (echo_test_string="`eval $cmd`") 2>/dev/null &&
- echo_test_string="`eval $cmd`" &&
- (test "X$echo_test_string" = "X$echo_test_string") 2>/dev/null
- then
- break
- fi
- done
-fi
-
-if test "X`($echo '\t') 2>/dev/null`" = 'X\t' &&
- echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` &&
- test "X$echo_testing_string" = "X$echo_test_string"; then
- :
-else
- # The Solaris, AIX, and Digital Unix default echo programs unquote
- # backslashes. This makes it impossible to quote backslashes using
- # echo "$something" | sed 's/\\/\\\\/g'
- #
- # So, first we look for a working echo in the user's PATH.
-
- IFS="${IFS= }"; save_ifs="$IFS"; IFS=$PATH_SEPARATOR
- for dir in $PATH /usr/ucb; do
- if (test -f $dir/echo || test -f $dir/echo$ac_exeext) &&
- test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' &&
- echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` &&
- test "X$echo_testing_string" = "X$echo_test_string"; then
- echo="$dir/echo"
- break
- fi
- done
- IFS="$save_ifs"
-
- if test "X$echo" = Xecho; then
- # We didn't find a better echo, so look for alternatives.
- if test "X`(print -r '\t') 2>/dev/null`" = 'X\t' &&
- echo_testing_string=`(print -r "$echo_test_string") 2>/dev/null` &&
- test "X$echo_testing_string" = "X$echo_test_string"; then
- # This shell has a builtin print -r that does the trick.
- echo='print -r'
- elif (test -f /bin/ksh || test -f /bin/ksh$ac_exeext) &&
- test "X$CONFIG_SHELL" != X/bin/ksh; then
- # If we have ksh, try running configure again with it.
- ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh}
- export ORIGINAL_CONFIG_SHELL
- CONFIG_SHELL=/bin/ksh
- export CONFIG_SHELL
- exec $CONFIG_SHELL "$0" --no-reexec ${1+"$@"}
- else
- # Try using printf.
- echo='printf %s\n'
- if test "X`($echo '\t') 2>/dev/null`" = 'X\t' &&
- echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` &&
- test "X$echo_testing_string" = "X$echo_test_string"; then
- # Cool, printf works
- :
- elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` &&
- test "X$echo_testing_string" = 'X\t' &&
- echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` &&
- test "X$echo_testing_string" = "X$echo_test_string"; then
- CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL
- export CONFIG_SHELL
- SHELL="$CONFIG_SHELL"
- export SHELL
- echo="$CONFIG_SHELL $0 --fallback-echo"
- elif echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` &&
- test "X$echo_testing_string" = 'X\t' &&
- echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` &&
- test "X$echo_testing_string" = "X$echo_test_string"; then
- echo="$CONFIG_SHELL $0 --fallback-echo"
- else
- # maybe with a smaller string...
- prev=:
-
- for cmd in 'echo test' 'sed 2q "$0"' 'sed 10q "$0"' 'sed 20q "$0"' 'sed 50q "$0"'; do
- if (test "X$echo_test_string" = "X`eval $cmd`") 2>/dev/null
- then
- break
- fi
- prev="$cmd"
- done
-
- if test "$prev" != 'sed 50q "$0"'; then
- echo_test_string=`eval $prev`
- export echo_test_string
- exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "$0" ${1+"$@"}
- else
- # Oops. We lost completely, so just stick with echo.
- echo=echo
- fi
- fi
- fi
- fi
-fi
-fi
-
-# Copy echo and quote the copy suitably for passing to libtool from
-# the Makefile, instead of quoting the original, which is used later.
-ECHO=$echo
-if test "X$ECHO" = "X$CONFIG_SHELL $0 --fallback-echo"; then
- ECHO="$CONFIG_SHELL \\\$\$0 --fallback-echo"
-fi
-
-
-
-if expr a : '\(a\)' >/dev/null 2>&1; then
- as_expr=expr
-else
- as_expr=false
-fi
-
-
## --------------------- ##
## M4sh Initialization. ##
## --------------------- ##
@@ -183,11 +16,13 @@ fi
if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
emulate sh
NULLCMD=:
+ # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
set -o posix
fi
-# NLS nuisances.
# Support unset when possible.
if (FOO=FOO; unset FOO) >/dev/null 2>&1; then
as_unset=unset
@@ -195,34 +30,42 @@ else
as_unset=false
fi
-(set +x; test -n "`(LANG=C; export LANG) 2>&1`") &&
- { $as_unset LANG || test "${LANG+set}" != set; } ||
- { LANG=C; export LANG; }
-(set +x; test -n "`(LC_ALL=C; export LC_ALL) 2>&1`") &&
- { $as_unset LC_ALL || test "${LC_ALL+set}" != set; } ||
- { LC_ALL=C; export LC_ALL; }
-(set +x; test -n "`(LC_TIME=C; export LC_TIME) 2>&1`") &&
- { $as_unset LC_TIME || test "${LC_TIME+set}" != set; } ||
- { LC_TIME=C; export LC_TIME; }
-(set +x; test -n "`(LC_CTYPE=C; export LC_CTYPE) 2>&1`") &&
- { $as_unset LC_CTYPE || test "${LC_CTYPE+set}" != set; } ||
- { LC_CTYPE=C; export LC_CTYPE; }
-(set +x; test -n "`(LANGUAGE=C; export LANGUAGE) 2>&1`") &&
- { $as_unset LANGUAGE || test "${LANGUAGE+set}" != set; } ||
- { LANGUAGE=C; export LANGUAGE; }
-(set +x; test -n "`(LC_COLLATE=C; export LC_COLLATE) 2>&1`") &&
- { $as_unset LC_COLLATE || test "${LC_COLLATE+set}" != set; } ||
- { LC_COLLATE=C; export LC_COLLATE; }
-(set +x; test -n "`(LC_NUMERIC=C; export LC_NUMERIC) 2>&1`") &&
- { $as_unset LC_NUMERIC || test "${LC_NUMERIC+set}" != set; } ||
- { LC_NUMERIC=C; export LC_NUMERIC; }
-(set +x; test -n "`(LC_MESSAGES=C; export LC_MESSAGES) 2>&1`") &&
- { $as_unset LC_MESSAGES || test "${LC_MESSAGES+set}" != set; } ||
- { LC_MESSAGES=C; export LC_MESSAGES; }
+
+# Work around bugs in pre-3.0 UWIN ksh.
+$as_unset ENV MAIL MAILPATH
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+for as_var in \
+ LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
+ LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
+ LC_TELEPHONE LC_TIME
+do
+ if (set +x; test -n "`(eval $as_var=C; export $as_var) 2>&1`"); then
+ eval $as_var=C; export $as_var
+ else
+ $as_unset $as_var
+ fi
+done
+
+# Required to use basename.
+if expr a : '\(a\)' >/dev/null 2>&1; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then
+ as_basename=basename
+else
+ as_basename=false
+fi
# Name of the executable.
-as_me=`(basename "$0") 2>/dev/null ||
+as_me=`$as_basename "$0" ||
$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
X"$0" : 'X\(//\)$' \| \
X"$0" : 'X\(/\)$' \| \
@@ -233,6 +76,7 @@ echo X/"$0" |
/^X\/\(\/\).*/{ s//\1/; q; }
s/.*/./; q'`
+
# PATH needs CR, and LINENO needs CR and PATH.
# Avoid depending upon Character Ranges.
as_cr_letters='abcdefghijklmnopqrstuvwxyz'
@@ -243,15 +87,15 @@ as_cr_alnum=$as_cr_Letters$as_cr_digits
# The user is always right.
if test "${PATH_SEPARATOR+set}" != set; then
- echo "#! /bin/sh" >conftest.sh
- echo "exit 0" >>conftest.sh
- chmod +x conftest.sh
- if (PATH=".;."; conftest.sh) >/dev/null 2>&1; then
+ echo "#! /bin/sh" >conf$$.sh
+ echo "exit 0" >>conf$$.sh
+ chmod +x conf$$.sh
+ if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
PATH_SEPARATOR=';'
else
PATH_SEPARATOR=:
fi
- rm -f conftest.sh
+ rm -f conf$$.sh
fi
@@ -299,6 +143,8 @@ do
as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
test "x$as_lineno_1" != "x$as_lineno_2" &&
test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then
+ $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; }
+ $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; }
CONFIG_SHELL=$as_dir/$as_base
export CONFIG_SHELL
exec "$CONFIG_SHELL" "$0" ${1+"$@"}
@@ -371,6 +217,12 @@ else
fi
rm -f conf$$ conf$$.exe conf$$.file
+if mkdir -p . 2>/dev/null; then
+ as_mkdir_p=:
+else
+ as_mkdir_p=false
+fi
+
as_executable_p="test -f"
# Sed expression to map a string onto a valid CPP name.
@@ -387,7 +239,166 @@ as_nl='
IFS=" $as_nl"
# CDPATH.
-$as_unset CDPATH || test "${CDPATH+set}" != set || { CDPATH=$PATH_SEPARATOR; export CDPATH; }
+$as_unset CDPATH
+
+
+# Find the correct PATH separator. Usually this is `:', but
+# DJGPP uses `;' like DOS.
+if test "X${PATH_SEPARATOR+set}" != Xset; then
+ UNAME=${UNAME-`uname 2>/dev/null`}
+ case X$UNAME in
+ *-DOS) lt_cv_sys_path_separator=';' ;;
+ *) lt_cv_sys_path_separator=':' ;;
+ esac
+ PATH_SEPARATOR=$lt_cv_sys_path_separator
+fi
+
+
+# Check that we are running under the correct shell.
+SHELL=${CONFIG_SHELL-/bin/sh}
+
+case X$ECHO in
+X*--fallback-echo)
+ # Remove one level of quotation (which was required for Make).
+ ECHO=`echo "$ECHO" | sed 's,\\\\\$\\$0,'$0','`
+ ;;
+esac
+
+echo=${ECHO-echo}
+if test "X$1" = X--no-reexec; then
+ # Discard the --no-reexec flag, and continue.
+ shift
+elif test "X$1" = X--fallback-echo; then
+ # Avoid inline document here, it may be left over
+ :
+elif test "X`($echo '\t') 2>/dev/null`" = 'X\t'; then
+ # Yippee, $echo works!
+ :
+else
+ # Restart under the correct shell.
+ exec $SHELL "$0" --no-reexec ${1+"$@"}
+fi
+
+if test "X$1" = X--fallback-echo; then
+ # used as fallback echo
+ shift
+ cat <<EOF
+
+EOF
+ exit 0
+fi
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+if test "X${CDPATH+set}" = Xset; then CDPATH=:; export CDPATH; fi
+
+if test -z "$ECHO"; then
+if test "X${echo_test_string+set}" != Xset; then
+# find a string as large as possible, as long as the shell can cope with it
+ for cmd in 'sed 50q "$0"' 'sed 20q "$0"' 'sed 10q "$0"' 'sed 2q "$0"' 'echo test'; do
+ # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ...
+ if (echo_test_string="`eval $cmd`") 2>/dev/null &&
+ echo_test_string="`eval $cmd`" &&
+ (test "X$echo_test_string" = "X$echo_test_string") 2>/dev/null
+ then
+ break
+ fi
+ done
+fi
+
+if test "X`($echo '\t') 2>/dev/null`" = 'X\t' &&
+ echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` &&
+ test "X$echo_testing_string" = "X$echo_test_string"; then
+ :
+else
+ # The Solaris, AIX, and Digital Unix default echo programs unquote
+ # backslashes. This makes it impossible to quote backslashes using
+ # echo "$something" | sed 's/\\/\\\\/g'
+ #
+ # So, first we look for a working echo in the user's PATH.
+
+ IFS="${IFS= }"; save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+ for dir in $PATH /usr/ucb; do
+ if (test -f $dir/echo || test -f $dir/echo$ac_exeext) &&
+ test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' &&
+ echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` &&
+ test "X$echo_testing_string" = "X$echo_test_string"; then
+ echo="$dir/echo"
+ break
+ fi
+ done
+ IFS="$save_ifs"
+
+ if test "X$echo" = Xecho; then
+ # We didn't find a better echo, so look for alternatives.
+ if test "X`(print -r '\t') 2>/dev/null`" = 'X\t' &&
+ echo_testing_string=`(print -r "$echo_test_string") 2>/dev/null` &&
+ test "X$echo_testing_string" = "X$echo_test_string"; then
+ # This shell has a builtin print -r that does the trick.
+ echo='print -r'
+ elif (test -f /bin/ksh || test -f /bin/ksh$ac_exeext) &&
+ test "X$CONFIG_SHELL" != X/bin/ksh; then
+ # If we have ksh, try running configure again with it.
+ ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh}
+ export ORIGINAL_CONFIG_SHELL
+ CONFIG_SHELL=/bin/ksh
+ export CONFIG_SHELL
+ exec $CONFIG_SHELL "$0" --no-reexec ${1+"$@"}
+ else
+ # Try using printf.
+ echo='printf %s\n'
+ if test "X`($echo '\t') 2>/dev/null`" = 'X\t' &&
+ echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` &&
+ test "X$echo_testing_string" = "X$echo_test_string"; then
+ # Cool, printf works
+ :
+ elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` &&
+ test "X$echo_testing_string" = 'X\t' &&
+ echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` &&
+ test "X$echo_testing_string" = "X$echo_test_string"; then
+ CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL
+ export CONFIG_SHELL
+ SHELL="$CONFIG_SHELL"
+ export SHELL
+ echo="$CONFIG_SHELL $0 --fallback-echo"
+ elif echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` &&
+ test "X$echo_testing_string" = 'X\t' &&
+ echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` &&
+ test "X$echo_testing_string" = "X$echo_test_string"; then
+ echo="$CONFIG_SHELL $0 --fallback-echo"
+ else
+ # maybe with a smaller string...
+ prev=:
+
+ for cmd in 'echo test' 'sed 2q "$0"' 'sed 10q "$0"' 'sed 20q "$0"' 'sed 50q "$0"'; do
+ if (test "X$echo_test_string" = "X`eval $cmd`") 2>/dev/null
+ then
+ break
+ fi
+ prev="$cmd"
+ done
+
+ if test "$prev" != 'sed 50q "$0"'; then
+ echo_test_string=`eval $prev`
+ export echo_test_string
+ exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "$0" ${1+"$@"}
+ else
+ # Oops. We lost completely, so just stick with echo.
+ echo=echo
+ fi
+ fi
+ fi
+ fi
+fi
+fi
+
+# Copy echo and quote the copy suitably for passing to libtool from
+# the Makefile, instead of quoting the original, which is used later.
+ECHO=$echo
+if test "X$ECHO" = "X$CONFIG_SHELL $0 --fallback-echo"; then
+ ECHO="$CONFIG_SHELL \\\$\$0 --fallback-echo"
+fi
+
# Name of the host.
@@ -401,6 +412,7 @@ exec 6>&1
# Initializations.
#
ac_default_prefix=/usr/local
+ac_config_libobj_dir=.
cross_compiling=no
subdirs=
MFLAGS=
@@ -457,6 +469,8 @@ ac_includes_default="\
# include <unistd.h>
#endif"
+ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA AWK CPP CXX CXXFLAGS ac_ct_CXX RANLIB ac_ct_RANLIB build build_cpu build_vendor build_os host host_cpu host_vendor host_os LN_S ECHO STRIP ac_ct_STRIP EGREP LIBTOOL EXEC_LDFLAGS LIBOBJS PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO AMTAR install_sh INSTALL_STRIP_PROGRAM SET_MAKE DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE CXXDEPMODE LTLIBOBJS'
+ac_subst_files=''
# Initialize some variables set by options.
ac_init_help=
@@ -880,6 +894,9 @@ if test ! -r $srcdir/$ac_unique_file; then
{ (exit 1); exit 1; }; }
fi
fi
+(cd $srcdir && test -r ./$ac_unique_file) 2>/dev/null ||
+ { echo "$as_me: error: sources are in $srcdir, but \`cd $srcdir' does not work" >&2
+ { (exit 1); exit 1; }; }
srcdir=`echo "$srcdir" | sed 's%\([^\\/]\)[\\/]*$%\1%'`
ac_env_build_alias_set=${build_alias+set}
ac_env_build_alias_value=$build_alias
@@ -1067,7 +1084,7 @@ esac
# Don't blindly perform a `cd "$ac_dir"/$ac_foo && pwd` since $ac_foo can be
# absolute.
ac_abs_builddir=`cd "$ac_dir" && cd $ac_builddir && pwd`
-ac_abs_top_builddir=`cd "$ac_dir" && cd $ac_top_builddir && pwd`
+ac_abs_top_builddir=`cd "$ac_dir" && cd ${ac_top_builddir}. && pwd`
ac_abs_srcdir=`cd "$ac_dir" && cd $ac_srcdir && pwd`
ac_abs_top_srcdir=`cd "$ac_dir" && cd $ac_top_srcdir && pwd`
@@ -1094,7 +1111,7 @@ test -n "$ac_init_help" && exit 0
if $ac_init_version; then
cat <<\_ACEOF
openggsn configure 0.61b
-generated by GNU Autoconf 2.53
+generated by GNU Autoconf 2.57
Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002
Free Software Foundation, Inc.
@@ -1109,7 +1126,7 @@ This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
It was created by openggsn $as_me 0.61b, which was
-generated by GNU Autoconf 2.53. Invocation command line was
+generated by GNU Autoconf 2.57. Invocation command line was
$ $0 $@
@@ -1161,27 +1178,54 @@ _ACEOF
# Keep a trace of the command line.
# Strip out --no-create and --no-recursion so they do not pile up.
+# Strip out --silent because we don't want to record it for future runs.
# Also quote any args containing shell meta-characters.
+# Make two passes to allow for proper duplicate-argument suppression.
ac_configure_args=
+ac_configure_args0=
+ac_configure_args1=
ac_sep=
-for ac_arg
+ac_must_keep_next=false
+for ac_pass in 1 2
do
- case $ac_arg in
- -no-create | --no-create | --no-creat | --no-crea | --no-cre \
- | --no-cr | --no-c | -n ) continue ;;
- -no-recursion | --no-recursion | --no-recursio | --no-recursi \
- | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
- continue ;;
- *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*)
- ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
- esac
- case " $ac_configure_args " in
- *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy.
- *) ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'"
- ac_sep=" " ;;
- esac
- # Get rid of the leading space.
+ for ac_arg
+ do
+ case $ac_arg in
+ -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ continue ;;
+ *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*)
+ ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+ esac
+ case $ac_pass in
+ 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;;
+ 2)
+ ac_configure_args1="$ac_configure_args1 '$ac_arg'"
+ if test $ac_must_keep_next = true; then
+ ac_must_keep_next=false # Got value, back to normal.
+ else
+ case $ac_arg in
+ *=* | --config-cache | -C | -disable-* | --disable-* \
+ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
+ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
+ | -with-* | --with-* | -without-* | --without-* | --x)
+ case "$ac_configure_args0 " in
+ "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
+ esac
+ ;;
+ -* ) ac_must_keep_next=true ;;
+ esac
+ fi
+ ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'"
+ # Get rid of the leading space.
+ ac_sep=" "
+ ;;
+ esac
+ done
done
+$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; }
+$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; }
# When interrupted or exit'd, cleanup temporary files, and complete
# config.log. We remove comments because anyway the quotes in there
@@ -1192,6 +1236,7 @@ trap 'exit_status=$?
# Save into config.log some information that might help in debugging.
{
echo
+
cat <<\_ASBOX
## ---------------- ##
## Cache variables. ##
@@ -1214,6 +1259,35 @@ _ASBOX
esac;
}
echo
+
+ cat <<\_ASBOX
+## ----------------- ##
+## Output variables. ##
+## ----------------- ##
+_ASBOX
+ echo
+ for ac_var in $ac_subst_vars
+ do
+ eval ac_val=$`echo $ac_var`
+ echo "$ac_var='"'"'$ac_val'"'"'"
+ done | sort
+ echo
+
+ if test -n "$ac_subst_files"; then
+ cat <<\_ASBOX
+## ------------- ##
+## Output files. ##
+## ------------- ##
+_ASBOX
+ echo
+ for ac_var in $ac_subst_files
+ do
+ eval ac_val=$`echo $ac_var`
+ echo "$ac_var='"'"'$ac_val'"'"'"
+ done | sort
+ echo
+ fi
+
if test -s confdefs.h; then
cat <<\_ASBOX
## ----------- ##
@@ -1221,7 +1295,7 @@ _ASBOX
## ----------- ##
_ASBOX
echo
- sed "/^$/d" confdefs.h
+ sed "/^$/d" confdefs.h | sort
echo
fi
test "$ac_signal" != 0 &&
@@ -1387,9 +1461,10 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
# Add the stamp file to the list of files AC keeps track of,
# along with our hook.
-ac_config_headers="$ac_config_headers config.h"
+ ac_config_headers="$ac_config_headers config.h"
@@ -1600,9 +1675,7 @@ if test $ac_prog_rejected = yes; then
# However, it has the same basename, so the bogon will be chosen
# first if we set CC to just the basename; use the full file name.
shift
- set dummy "$as_dir/$ac_word" ${1+"$@"}
- shift
- ac_cv_prog_CC="$@"
+ ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
fi
fi
fi
@@ -1707,8 +1780,10 @@ fi
fi
-test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH" >&5
-echo "$as_me: error: no acceptable C compiler found in \$PATH" >&2;}
+test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH
+See \`config.log' for more details." >&5
+echo "$as_me: error: no acceptable C compiler found in \$PATH
+See \`config.log' for more details." >&2;}
{ (exit 1); exit 1; }; }
# Provide some information about the compiler.
@@ -1733,14 +1808,12 @@ ac_compiler=`set X $ac_compile; echo $2`
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
-#include "confdefs.h"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
-#ifdef F77_DUMMY_MAIN
-# ifdef __cplusplus
- extern "C"
-# endif
- int F77_DUMMY_MAIN() { return 1; }
-#endif
int
main ()
{
@@ -1750,7 +1823,7 @@ main ()
}
_ACEOF
ac_clean_files_save=$ac_clean_files
-ac_clean_files="$ac_clean_files a.out a.exe"
+ac_clean_files="$ac_clean_files a.out a.exe b.out"
# Try to create an executable without -o first, disregard a.out.
# It will help us diagnose broken compilers, and finding out an intuition
# of exeext.
@@ -1769,26 +1842,39 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link_default\"") >&5
# Be careful to initialize this variable, since it used to be cached.
# Otherwise an old cache value of `no' led to `EXEEXT = no' in a Makefile.
ac_cv_exeext=
-for ac_file in `ls a_out.exe a.exe conftest.exe 2>/dev/null;
- ls a.out conftest 2>/dev/null;
- ls a.* conftest.* 2>/dev/null`; do
+# b.out is created by i960 compilers.
+for ac_file in a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out
+do
+ test -f "$ac_file" || continue
case $ac_file in
- *.$ac_ext | *.o | *.obj | *.xcoff | *.tds | *.d | *.pdb | *.xSYM ) ;;
- a.out ) # We found the default executable, but exeext='' is most
- # certainly right.
- break;;
- *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
- # FIXME: I believe we export ac_cv_exeext for Libtool --akim.
- export ac_cv_exeext
- break;;
- * ) break;;
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj )
+ ;;
+ conftest.$ac_ext )
+ # This is the source file.
+ ;;
+ [ab].out )
+ # We found the default executable, but exeext='' is most
+ # certainly right.
+ break;;
+ *.* )
+ ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+ # FIXME: I believe we export ac_cv_exeext for Libtool,
+ # but it would be cool to find out if it's true. Does anybody
+ # maintain Libtool? --akim.
+ export ac_cv_exeext
+ break;;
+ * )
+ break;;
esac
done
else
echo "$as_me: failed program was:" >&5
-cat conftest.$ac_ext >&5
-{ { echo "$as_me:$LINENO: error: C compiler cannot create executables" >&5
-echo "$as_me: error: C compiler cannot create executables" >&2;}
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { echo "$as_me:$LINENO: error: C compiler cannot create executables
+See \`config.log' for more details." >&5
+echo "$as_me: error: C compiler cannot create executables
+See \`config.log' for more details." >&2;}
{ (exit 77); exit 77; }; }
fi
@@ -1815,9 +1901,11 @@ if test "$cross_compiling" != yes; then
cross_compiling=yes
else
{ { echo "$as_me:$LINENO: error: cannot run C compiled programs.
-If you meant to cross compile, use \`--host'." >&5
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details." >&5
echo "$as_me: error: cannot run C compiled programs.
-If you meant to cross compile, use \`--host'." >&2;}
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details." >&2;}
{ (exit 1); exit 1; }; }
fi
fi
@@ -1825,7 +1913,7 @@ fi
echo "$as_me:$LINENO: result: yes" >&5
echo "${ECHO_T}yes" >&6
-rm -f a.out a.exe conftest$ac_cv_exeext
+rm -f a.out a.exe conftest$ac_cv_exeext b.out
ac_clean_files=$ac_clean_files_save
# Check the compiler produces executables we can run. If not, either
# the compiler is broken, or we cross compile.
@@ -1845,9 +1933,10 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will
# work properly (i.e., refer to `conftest.exe'), while it won't with
# `rm'.
-for ac_file in `(ls conftest.exe; ls conftest; ls conftest.*) 2>/dev/null`; do
+for ac_file in conftest.exe conftest conftest.*; do
+ test -f "$ac_file" || continue
case $ac_file in
- *.$ac_ext | *.o | *.obj | *.xcoff | *.tds | *.d | *.pdb ) ;;
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;;
*.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
export ac_cv_exeext
break;;
@@ -1855,8 +1944,10 @@ for ac_file in `(ls conftest.exe; ls conftest; ls conftest.*) 2>/dev/null`; do
esac
done
else
- { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link" >&5
-echo "$as_me: error: cannot compute suffix of executables: cannot compile and link" >&2;}
+ { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details." >&2;}
{ (exit 1); exit 1; }; }
fi
@@ -1874,14 +1965,12 @@ if test "${ac_cv_objext+set}" = set; then
else
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
-#include "confdefs.h"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
-#ifdef F77_DUMMY_MAIN
-# ifdef __cplusplus
- extern "C"
-# endif
- int F77_DUMMY_MAIN() { return 1; }
-#endif
int
main ()
{
@@ -1898,16 +1987,19 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
(exit $ac_status); }; then
for ac_file in `(ls conftest.o conftest.obj; ls conftest.*) 2>/dev/null`; do
case $ac_file in
- *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb ) ;;
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg ) ;;
*) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
break;;
esac
done
else
echo "$as_me: failed program was:" >&5
-cat conftest.$ac_ext >&5
-{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile" >&5
-echo "$as_me: error: cannot compute suffix of object files: cannot compile" >&2;}
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute suffix of object files: cannot compile
+See \`config.log' for more details." >&2;}
{ (exit 1); exit 1; }; }
fi
@@ -1924,14 +2016,12 @@ if test "${ac_cv_c_compiler_gnu+set}" = set; then
else
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
-#include "confdefs.h"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
-#ifdef F77_DUMMY_MAIN
-# ifdef __cplusplus
- extern "C"
-# endif
- int F77_DUMMY_MAIN() { return 1; }
-#endif
int
main ()
{
@@ -1958,7 +2048,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
ac_compiler_gnu=yes
else
echo "$as_me: failed program was:" >&5
-cat conftest.$ac_ext >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
ac_compiler_gnu=no
fi
rm -f conftest.$ac_objext conftest.$ac_ext
@@ -1978,14 +2069,12 @@ if test "${ac_cv_prog_cc_g+set}" = set; then
else
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
-#include "confdefs.h"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
-#ifdef F77_DUMMY_MAIN
-# ifdef __cplusplus
- extern "C"
-# endif
- int F77_DUMMY_MAIN() { return 1; }
-#endif
int
main ()
{
@@ -2009,7 +2098,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
ac_cv_prog_cc_g=yes
else
echo "$as_me: failed program was:" >&5
-cat conftest.$ac_ext >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
ac_cv_prog_cc_g=no
fi
rm -f conftest.$ac_objext conftest.$ac_ext
@@ -2031,6 +2121,102 @@ else
CFLAGS=
fi
fi
+echo "$as_me:$LINENO: checking for $CC option to accept ANSI C" >&5
+echo $ECHO_N "checking for $CC option to accept ANSI C... $ECHO_C" >&6
+if test "${ac_cv_prog_cc_stdc+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_cv_prog_cc_stdc=no
+ac_save_CC=$CC
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <stdarg.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */
+struct buf { int x; };
+FILE * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+ char **p;
+ int i;
+{
+ return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+ char *s;
+ va_list v;
+ va_start (v,p);
+ s = g (p, va_arg (v,int));
+ va_end (v);
+ return s;
+}
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
+int argc;
+char **argv;
+int
+main ()
+{
+return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1];
+ ;
+ return 0;
+}
+_ACEOF
+# Don't try gcc -ansi; that turns off useful extensions and
+# breaks some systems' header files.
+# AIX -qlanglvl=ansi
+# Ultrix and OSF/1 -std1
+# HP-UX 10.20 and later -Ae
+# HP-UX older versions -Aa -D_HPUX_SOURCE
+# SVR4 -Xc -D__EXTENSIONS__
+for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+ CC="$ac_save_CC $ac_arg"
+ rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_prog_cc_stdc=$ac_arg
+break
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.$ac_objext
+done
+rm -f conftest.$ac_ext conftest.$ac_objext
+CC=$ac_save_CC
+
+fi
+
+case "x$ac_cv_prog_cc_stdc" in
+ x|xno)
+ echo "$as_me:$LINENO: result: none needed" >&5
+echo "${ECHO_T}none needed" >&6 ;;
+ *)
+ echo "$as_me:$LINENO: result: $ac_cv_prog_cc_stdc" >&5
+echo "${ECHO_T}$ac_cv_prog_cc_stdc" >&6
+ CC="$CC $ac_cv_prog_cc_stdc" ;;
+esac
+
# Some people use a C++ compiler to compile C. Since we use `exit',
# in C++ we need to declare it. In case someone uses the same compiler
# for both compiling C and C++ we need to have the C++ compiler decide
@@ -2063,15 +2249,13 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
do
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
-#include "confdefs.h"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
#include <stdlib.h>
$ac_declaration
-#ifdef F77_DUMMY_MAIN
-# ifdef __cplusplus
- extern "C"
-# endif
- int F77_DUMMY_MAIN() { return 1; }
-#endif
int
main ()
{
@@ -2095,20 +2279,19 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
:
else
echo "$as_me: failed program was:" >&5
-cat conftest.$ac_ext >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
continue
fi
rm -f conftest.$ac_objext conftest.$ac_ext
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
-#include "confdefs.h"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
$ac_declaration
-#ifdef F77_DUMMY_MAIN
-# ifdef __cplusplus
- extern "C"
-# endif
- int F77_DUMMY_MAIN() { return 1; }
-#endif
int
main ()
{
@@ -2132,7 +2315,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
break
else
echo "$as_me: failed program was:" >&5
-cat conftest.$ac_ext >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
fi
rm -f conftest.$ac_objext conftest.$ac_ext
done
@@ -2145,7 +2329,8 @@ fi
else
echo "$as_me: failed program was:" >&5
-cat conftest.$ac_ext >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
fi
rm -f conftest.$ac_objext conftest.$ac_ext
ac_ext=c
@@ -2319,18 +2504,28 @@ for ac_c_preproc_warn_flag in '' yes
do
# Use a header file that comes with gcc, so configuring glibc
# with a fresh cross-compiler works.
+ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ # <limits.h> exists even on freestanding compilers.
# On the NeXT, cc -E runs the code through the compiler's parser,
# not just through cpp. "Syntax error" is here to catch this case.
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
-#include "confdefs.h"
-#include <assert.h>
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
Syntax error
_ACEOF
if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
(eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
ac_status=$?
- egrep -v '^ *\+' conftest.er1 >conftest.err
+ grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
@@ -2347,7 +2542,8 @@ if test -z "$ac_cpp_err"; then
:
else
echo "$as_me: failed program was:" >&5
- cat conftest.$ac_ext >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
# Broken: fails on valid input.
continue
fi
@@ -2357,13 +2553,17 @@ rm -f conftest.err conftest.$ac_ext
# can be detected and how.
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
-#include "confdefs.h"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
#include <ac_nonexistent.h>
_ACEOF
if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
(eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
ac_status=$?
- egrep -v '^ *\+' conftest.er1 >conftest.err
+ grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
@@ -2381,7 +2581,8 @@ if test -z "$ac_cpp_err"; then
continue
else
echo "$as_me: failed program was:" >&5
- cat conftest.$ac_ext >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
# Passes both tests.
ac_preproc_ok=:
break
@@ -2410,18 +2611,28 @@ for ac_c_preproc_warn_flag in '' yes
do
# Use a header file that comes with gcc, so configuring glibc
# with a fresh cross-compiler works.
+ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ # <limits.h> exists even on freestanding compilers.
# On the NeXT, cc -E runs the code through the compiler's parser,
# not just through cpp. "Syntax error" is here to catch this case.
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
-#include "confdefs.h"
-#include <assert.h>
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
Syntax error
_ACEOF
if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
(eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
ac_status=$?
- egrep -v '^ *\+' conftest.er1 >conftest.err
+ grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
@@ -2438,7 +2649,8 @@ if test -z "$ac_cpp_err"; then
:
else
echo "$as_me: failed program was:" >&5
- cat conftest.$ac_ext >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
# Broken: fails on valid input.
continue
fi
@@ -2448,13 +2660,17 @@ rm -f conftest.err conftest.$ac_ext
# can be detected and how.
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
-#include "confdefs.h"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
#include <ac_nonexistent.h>
_ACEOF
if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
(eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
ac_status=$?
- egrep -v '^ *\+' conftest.er1 >conftest.err
+ grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
@@ -2472,7 +2688,8 @@ if test -z "$ac_cpp_err"; then
continue
else
echo "$as_me: failed program was:" >&5
- cat conftest.$ac_ext >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
# Passes both tests.
ac_preproc_ok=:
break
@@ -2485,8 +2702,10 @@ rm -f conftest.err conftest.$ac_ext
if $ac_preproc_ok; then
:
else
- { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check" >&5
-echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check" >&2;}
+ { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details." >&5
+echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details." >&2;}
{ (exit 1); exit 1; }; }
fi
@@ -2616,14 +2835,12 @@ if test "${ac_cv_cxx_compiler_gnu+set}" = set; then
else
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
-#include "confdefs.h"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
-#ifdef F77_DUMMY_MAIN
-# ifdef __cplusplus
- extern "C"
-# endif
- int F77_DUMMY_MAIN() { return 1; }
-#endif
int
main ()
{
@@ -2650,7 +2867,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
ac_compiler_gnu=yes
else
echo "$as_me: failed program was:" >&5
-cat conftest.$ac_ext >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
ac_compiler_gnu=no
fi
rm -f conftest.$ac_objext conftest.$ac_ext
@@ -2670,14 +2888,12 @@ if test "${ac_cv_prog_cxx_g+set}" = set; then
else
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
-#include "confdefs.h"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
-#ifdef F77_DUMMY_MAIN
-# ifdef __cplusplus
- extern "C"
-# endif
- int F77_DUMMY_MAIN() { return 1; }
-#endif
int
main ()
{
@@ -2701,7 +2917,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
ac_cv_prog_cxx_g=yes
else
echo "$as_me: failed program was:" >&5
-cat conftest.$ac_ext >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
ac_cv_prog_cxx_g=no
fi
rm -f conftest.$ac_objext conftest.$ac_ext
@@ -2734,15 +2951,13 @@ for ac_declaration in \
do
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
-#include "confdefs.h"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
#include <stdlib.h>
$ac_declaration
-#ifdef F77_DUMMY_MAIN
-# ifdef __cplusplus
- extern "C"
-# endif
- int F77_DUMMY_MAIN() { return 1; }
-#endif
int
main ()
{
@@ -2766,20 +2981,19 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
:
else
echo "$as_me: failed program was:" >&5
-cat conftest.$ac_ext >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
continue
fi
rm -f conftest.$ac_objext conftest.$ac_ext
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
-#include "confdefs.h"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
$ac_declaration
-#ifdef F77_DUMMY_MAIN
-# ifdef __cplusplus
- extern "C"
-# endif
- int F77_DUMMY_MAIN() { return 1; }
-#endif
int
main ()
{
@@ -2803,7 +3017,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
break
else
echo "$as_me: failed program was:" >&5
-cat conftest.$ac_ext >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
fi
rm -f conftest.$ac_objext conftest.$ac_ext
done
@@ -3185,6 +3400,91 @@ NM="$lt_cv_path_NM"
echo "$as_me:$LINENO: result: $NM" >&5
echo "${ECHO_T}$NM" >&6
+echo "$as_me:$LINENO: checking for a sed that does not truncate output" >&5
+echo $ECHO_N "checking for a sed that does not truncate output... $ECHO_C" >&6
+if test "${lt_cv_path_SED+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ # Loop through the user's path and test for sed and gsed.
+# Then use that list of sed's as ones to test for truncation.
+as_executable_p="test -f"
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in sed gsed; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then
+ _sed_list="$_sed_list $as_dir/$ac_prog$ac_exec_ext"
+ fi
+ done
+ done
+done
+
+ # Create a temporary directory, and hook for its removal unless debugging.
+$debug ||
+{
+ trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0
+ trap '{ (exit 1); exit 1; }' 1 2 13 15
+}
+
+# Create a (secure) tmp directory for tmp files.
+: ${TMPDIR=/tmp}
+{
+ tmp=`(umask 077 && mktemp -d -q "$TMPDIR/sedXXXXXX") 2>/dev/null` &&
+ test -n "$tmp" && test -d "$tmp"
+} ||
+{
+ tmp=$TMPDIR/sed$$-$RANDOM
+ (umask 077 && mkdir $tmp)
+} ||
+{
+ echo "$me: cannot create a temporary directory in $TMPDIR" >&2
+ { (exit 1); exit 1; }
+}
+ _max=0
+ _count=0
+ # Add /usr/xpg4/bin/sed as it is typically found on Solaris
+ # along with /bin/sed that truncates output.
+ for _sed in $_sed_list /usr/xpg4/bin/sed; do
+ test ! -f ${_sed} && break
+ cat /dev/null > "$tmp/sed.in"
+ _count=0
+ echo ${ECHO_N-$ac_n} "0123456789${ECHO_C-$ac_c}" >"$tmp/sed.in"
+ # Check for GNU sed and select it if it is found.
+ if "${_sed}" --version 2>&1 < /dev/null | egrep '(GNU)' > /dev/null; then
+ lt_cv_path_SED=${_sed}
+ break
+ fi
+ while true; do
+ cat "$tmp/sed.in" "$tmp/sed.in" >"$tmp/sed.tmp"
+ mv "$tmp/sed.tmp" "$tmp/sed.in"
+ cp "$tmp/sed.in" "$tmp/sed.nl"
+ echo >>"$tmp/sed.nl"
+ ${_sed} -e 's/a$//' < "$tmp/sed.nl" >"$tmp/sed.out" || break
+ cmp -s "$tmp/sed.out" "$tmp/sed.nl" || break
+ # 40000 chars as input seems more than enough
+ test $_count -gt 10 && break
+ _count=`expr $_count + 1`
+ if test $_count -gt $_max; then
+ _max=$_count
+ lt_cv_path_SED=$_sed
+ fi
+ done
+ done
+ rm -rf "$tmp"
+
+fi
+
+if test "X$SED" != "X"; then
+ lt_cv_path_SED=$SED
+else
+ SED=$lt_cv_path_SED
+fi
+echo "$as_me:$LINENO: result: $SED" >&5
+echo "${ECHO_T}$SED" >&6
+
echo "$as_me:$LINENO: checking whether ln -s works" >&5
echo $ECHO_N "checking whether ln -s works... $ECHO_C" >&6
LN_S=$as_ln_s
@@ -3196,8 +3496,8 @@ else
echo "${ECHO_T}no, using $LN_S" >&6
fi
-echo "$as_me:$LINENO: checking how to recognise dependant libraries" >&5
-echo $ECHO_N "checking how to recognise dependant libraries... $ECHO_C" >&6
+echo "$as_me:$LINENO: checking how to recognise dependent libraries" >&5
+echo $ECHO_N "checking how to recognise dependent libraries... $ECHO_C" >&6
if test "${lt_cv_deplibs_check_method+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
@@ -3274,9 +3574,9 @@ hpux10.20*|hpux11*)
lt_cv_file_magic_test_file=/usr/lib/libc.sl
;;
-irix5* | irix6*)
+irix5* | irix6* | nonstopux*)
case $host_os in
- irix5*)
+ irix5* | nonstopux*)
# this will be overridden with pass_all, but let us keep it just in case
lt_cv_deplibs_check_method="file_magic ELF 32-bit MSB dynamic lib MIPS - version 1"
;;
@@ -3298,7 +3598,7 @@ irix5* | irix6*)
# This must be Linux ELF.
linux-gnu*)
case $host_cpu in
- alpha* | hppa* | i*86 | powerpc* | sparc* | ia64* | s390* )
+ alpha* | hppa* | i*86 | mips | mipsel | powerpc* | sparc* | ia64* | s390* | x86_64*)
lt_cv_deplibs_check_method=pass_all ;;
*)
# glibc up to 2.1.1 does not perform some relocations on ARM
@@ -3369,6 +3669,9 @@ sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib"
lt_cv_file_magic_test_file=/lib/libc.so
;;
+ siemens)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
esac
;;
esac
@@ -3423,9 +3726,12 @@ hpux*) # Its linker distinguishes data from code symbols
lt_cv_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern char \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'"
lt_cv_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'"
;;
-irix*)
+irix* | nonstopux*)
symcode='[BCDEGRST]'
;;
+osf*)
+ symcode='[BCDEGQRST]'
+ ;;
solaris* | sysv5*)
symcode='[BDT]'
;;
@@ -3534,7 +3840,7 @@ EOF
(eval $ac_link) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && test -s conftest; then
+ (exit $ac_status); } && test -s conftest$ac_exeext; then
pipe_works=yes
fi
LIBS="$save_LIBS"
@@ -3582,6 +3888,21 @@ echo "${ECHO_T}ok" >&6
fi
+echo "$as_me:$LINENO: checking for egrep" >&5
+echo $ECHO_N "checking for egrep... $ECHO_C" >&6
+if test "${ac_cv_prog_egrep+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if echo a | (grep -E '(a|b)') >/dev/null 2>&1
+ then ac_cv_prog_egrep='grep -E'
+ else ac_cv_prog_egrep='egrep'
+ fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_prog_egrep" >&5
+echo "${ECHO_T}$ac_cv_prog_egrep" >&6
+ EGREP=$ac_cv_prog_egrep
+
+
echo "$as_me:$LINENO: checking for ANSI C header files" >&5
echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6
if test "${ac_cv_header_stdc+set}" = set; then
@@ -3589,48 +3910,59 @@ if test "${ac_cv_header_stdc+set}" = set; then
else
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
-#include "confdefs.h"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <float.h>
+int
+main ()
+{
+
+ ;
+ return 0;
+}
_ACEOF
-if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
- (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>&5
ac_status=$?
- egrep -v '^ *\+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null; then
- if test -s conftest.err; then
- ac_cpp_err=$ac_c_preproc_warn_flag
- else
- ac_cpp_err=
- fi
-else
- ac_cpp_err=yes
-fi
-if test -z "$ac_cpp_err"; then
+ (exit $ac_status); } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
ac_cv_header_stdc=yes
else
echo "$as_me: failed program was:" >&5
- cat conftest.$ac_ext >&5
- ac_cv_header_stdc=no
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_header_stdc=no
fi
-rm -f conftest.err conftest.$ac_ext
+rm -f conftest.$ac_objext conftest.$ac_ext
if test $ac_cv_header_stdc = yes; then
# SunOS 4.x string.h does not declare mem*, contrary to ANSI.
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
-#include "confdefs.h"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
#include <string.h>
_ACEOF
if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- egrep "memchr" >/dev/null 2>&1; then
+ $EGREP "memchr" >/dev/null 2>&1; then
:
else
ac_cv_header_stdc=no
@@ -3643,12 +3975,16 @@ if test $ac_cv_header_stdc = yes; then
# ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
-#include "confdefs.h"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
#include <stdlib.h>
_ACEOF
if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- egrep "free" >/dev/null 2>&1; then
+ $EGREP "free" >/dev/null 2>&1; then
:
else
ac_cv_header_stdc=no
@@ -3664,13 +4000,18 @@ if test $ac_cv_header_stdc = yes; then
else
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
-#include "confdefs.h"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
#include <ctype.h>
#if ((' ' & 0x0FF) == 0x020)
# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
#else
-# define ISLOWER(c) (('a' <= (c) && (c) <= 'i') \
+# define ISLOWER(c) \
+ (('a' <= (c) && (c) <= 'i') \
|| ('j' <= (c) && (c) <= 'r') \
|| ('s' <= (c) && (c) <= 'z'))
# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
@@ -3703,11 +4044,12 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
else
echo "$as_me: program exited with status $ac_status" >&5
echo "$as_me: failed program was:" >&5
-cat conftest.$ac_ext >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
( exit $ac_status )
ac_cv_header_stdc=no
fi
-rm -f core core.* *.core conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
fi
fi
fi
@@ -3742,7 +4084,11 @@ if eval "test \"\${$as_ac_Header+set}\" = set"; then
else
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
-#include "confdefs.h"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
$ac_includes_default
#include <$ac_header>
@@ -3762,7 +4108,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
eval "$as_ac_Header=yes"
else
echo "$as_me: failed program was:" >&5
-cat conftest.$ac_ext >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
eval "$as_ac_Header=no"
fi
rm -f conftest.$ac_objext conftest.$ac_ext
@@ -3797,7 +4144,11 @@ echo "$as_me:$LINENO: checking $ac_header usability" >&5
echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
-#include "confdefs.h"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
$ac_includes_default
#include <$ac_header>
_ACEOF
@@ -3816,7 +4167,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
ac_header_compiler=yes
else
echo "$as_me: failed program was:" >&5
-cat conftest.$ac_ext >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
ac_header_compiler=no
fi
rm -f conftest.$ac_objext conftest.$ac_ext
@@ -3828,13 +4180,17 @@ echo "$as_me:$LINENO: checking $ac_header presence" >&5
echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
-#include "confdefs.h"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
#include <$ac_header>
_ACEOF
if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
(eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
ac_status=$?
- egrep -v '^ *\+' conftest.er1 >conftest.err
+ grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
@@ -3851,7 +4207,8 @@ if test -z "$ac_cpp_err"; then
ac_header_preproc=yes
else
echo "$as_me: failed program was:" >&5
- cat conftest.$ac_ext >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
ac_header_preproc=no
fi
rm -f conftest.err conftest.$ac_ext
@@ -3864,14 +4221,32 @@ case $ac_header_compiler:$ac_header_preproc in
{ echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
{ echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;};;
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+ (
+ cat <<\_ASBOX
+## ------------------------------------ ##
+## Report this to bug-autoconf@gnu.org. ##
+## ------------------------------------ ##
+_ASBOX
+ ) |
+ sed "s/^/$as_me: WARNING: /" >&2
+ ;;
no:yes )
{ echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
{ echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
{ echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;};;
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+ (
+ cat <<\_ASBOX
+## ------------------------------------ ##
+## Report this to bug-autoconf@gnu.org. ##
+## ------------------------------------ ##
+_ASBOX
+ ) |
+ sed "s/^/$as_me: WARNING: /" >&2
+ ;;
esac
echo "$as_me:$LINENO: checking for $ac_header" >&5
echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
@@ -3897,6 +4272,7 @@ done
+
# Only perform the check for file, if the check method requires it
case $deplibs_check_method in
file_magic*)
@@ -4212,7 +4588,7 @@ test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes
case $host in
*-*-irix6*)
# Find out which ABI we are using.
- echo '#line 4215 "configure"' > conftest.$ac_ext
+ echo '#line 4591 "configure"' > conftest.$ac_ext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
(eval $ac_compile) 2>&5
ac_status=$?
@@ -4252,14 +4628,12 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
-#include "confdefs.h"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
-#ifdef F77_DUMMY_MAIN
-# ifdef __cplusplus
- extern "C"
-# endif
- int F77_DUMMY_MAIN() { return 1; }
-#endif
int
main ()
{
@@ -4283,7 +4657,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
lt_cv_cc_needs_belf=yes
else
echo "$as_me: failed program was:" >&5
-cat conftest.$ac_ext >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
lt_cv_cc_needs_belf=no
fi
rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
@@ -4455,7 +4830,7 @@ else
# like `-m68040'.
lt_cv_prog_cc_pic='-m68020 -resident32 -malways-restore-a4'
;;
- beos* | irix5* | irix6* | osf3* | osf4* | osf5*)
+ beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
# PIC is the default for these OSes.
;;
darwin* | rhapsody*)
@@ -4498,7 +4873,7 @@ else
lt_cv_prog_cc_pic='+Z'
;;
- irix5* | irix6*)
+ irix5* | irix6* | nonstopux*)
lt_cv_prog_cc_wl='-Wl,'
lt_cv_prog_cc_static='-non_shared'
# PIC (with -KPIC) is the default.
@@ -4542,11 +4917,7 @@ else
sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
lt_cv_prog_cc_pic='-KPIC'
lt_cv_prog_cc_static='-Bstatic'
- if test "x$host_vendor" = xsni; then
- lt_cv_prog_cc_wl='-LD'
- else
- lt_cv_prog_cc_wl='-Wl,'
- fi
+ lt_cv_prog_cc_wl='-Wl,'
;;
uts4*)
@@ -4586,14 +4957,12 @@ else
CFLAGS="$CFLAGS $lt_cv_prog_cc_pic -DPIC"
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
-#include "confdefs.h"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
-#ifdef F77_DUMMY_MAIN
-# ifdef __cplusplus
- extern "C"
-# endif
- int F77_DUMMY_MAIN() { return 1; }
-#endif
int
main ()
{
@@ -4632,7 +5001,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
else
echo "$as_me: failed program was:" >&5
-cat conftest.$ac_ext >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
lt_cv_prog_cc_pic_works=no
fi
@@ -4675,14 +5045,12 @@ else
LDFLAGS="$LDFLAGS $lt_cv_prog_cc_static"
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
-#include "confdefs.h"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
-#ifdef F77_DUMMY_MAIN
-# ifdef __cplusplus
- extern "C"
-# endif
- int F77_DUMMY_MAIN() { return 1; }
-#endif
int
main ()
{
@@ -4706,7 +5074,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
lt_cv_prog_cc_static_works=yes
else
echo "$as_me: failed program was:" >&5
-cat conftest.$ac_ext >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
fi
rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
LDFLAGS="$save_LDFLAGS"
@@ -4748,7 +5117,7 @@ chmod -w .
save_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS -o out/conftest2.$ac_objext"
compiler_c_o=no
-if { (eval echo configure:4751: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>out/conftest.err; } && test -s out/conftest2.$ac_objext; then
+if { (eval echo configure:5120: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>out/conftest.err; } && test -s out/conftest2.$ac_objext; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings
if test -s out/conftest.err; then
@@ -4790,14 +5159,12 @@ else
ac_objext=lo
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
-#include "confdefs.h"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
-#ifdef F77_DUMMY_MAIN
-# ifdef __cplusplus
- extern "C"
-# endif
- int F77_DUMMY_MAIN() { return 1; }
-#endif
int
main ()
{
@@ -4828,7 +5195,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
else
echo "$as_me: failed program was:" >&5
-cat conftest.$ac_ext >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
fi
rm -f conftest.$ac_objext conftest.$ac_ext
ac_objext="$save_objext"
@@ -4876,14 +5244,12 @@ echo $ECHO_N "checking if $compiler supports -fno-rtti -fno-exceptions... $ECHO_
compiler_rtti_exceptions=no
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
-#include "confdefs.h"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
-#ifdef F77_DUMMY_MAIN
-# ifdef __cplusplus
- extern "C"
-# endif
- int F77_DUMMY_MAIN() { return 1; }
-#endif
int
main ()
{
@@ -4914,7 +5280,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
else
echo "$as_me: failed program was:" >&5
-cat conftest.$ac_ext >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
fi
rm -f conftest.$ac_objext conftest.$ac_ext
CFLAGS="$save_CFLAGS"
@@ -5086,7 +5453,7 @@ EOF
# If the export-symbols file already is a .def file (1st line
# is EXPORTS), use it as is.
# If DATA tags from a recent dlltool are present, honour them!
- archive_expsym_cmds='if test "x`head -1 $export_symbols`" = xEXPORTS; then
+ archive_expsym_cmds='if test "x`sed 1q $export_symbols`" = xEXPORTS; then
cp $export_symbols $output_objdir/$soname-def;
else
echo EXPORTS > $output_objdir/$soname-def;
@@ -5095,6 +5462,7 @@ EOF
set dummy \$symbol;
case \$# in
2) echo " \$2 @ \$_lt_hint ; " >> $output_objdir/$soname-def;;
+ 4) echo " \$2 \$3 \$4 ; " >> $output_objdir/$soname-def; _lt_hint=`expr \$_lt_hint - 1`;;
*) echo " \$2 @ \$_lt_hint \$3 ; " >> $output_objdir/$soname-def;;
esac;
_lt_hint=`expr 1 + \$_lt_hint`;
@@ -5207,10 +5575,12 @@ else
# need to do runtime linking.
case $host_os in aix4.[23]|aix4.[23].*|aix5*)
for ld_flag in $LDFLAGS; do
- if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then
+ case $ld_flag in
+ *-brtl*)
aix_use_runtimelinking=yes
break
- fi
+ ;;
+ esac
done
esac
@@ -5324,8 +5694,9 @@ else
esac
# FIXME: Relying on posixy $() will cause problems for
# cross-compilation, but unfortunately the echo tests do not
- # yet detect zsh echo's removal of \ escapes.
- archive_cmds='$nonopt $(test "x$module" = xyes && echo -bundle || echo -dynamiclib) $allow_undefined_flag -o $lib $libobjs $deplibs$linker_flags -install_name $rpath/$soname $verstring'
+ # yet detect zsh echo's removal of \ escapes. Also zsh mangles
+ # `"' quotes if we put them in here... so don't!
+ archive_cmds='$CC -r -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs && $CC $(test .$module = .yes && echo -bundle || echo -dynamiclib) $allow_undefined_flag -o $lib ${lib}-master.o $deplibs$linker_flags $(test .$module != .yes && echo -install_name $rpath/$soname $verstring)'
# We need to add '_' to the symbols in $export_symbols first
#archive_expsym_cmds="$archive_cmds"' && strip -s $export_symbols'
hardcode_direct=yes
@@ -5377,13 +5748,14 @@ else
export_dynamic_flag_spec='${wl}-E'
;;
- irix5* | irix6*)
+ irix5* | irix6* | nonstopux*)
if test "$GCC" = yes; then
archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
else
archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
+ hardcode_libdir_flag_spec='-rpath $libdir'
fi
- hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
hardcode_libdir_separator=:
link_all_deplibs=yes
;;
@@ -5411,7 +5783,7 @@ else
hardcode_direct=yes
hardcode_shlibpath_var=no
if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
- archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $linker_flags'
+ archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
export_dynamic_flag_spec='${wl}-E'
else
@@ -5421,7 +5793,7 @@ else
hardcode_libdir_flag_spec='-R$libdir'
;;
*)
- archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $linker_flags'
+ archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
;;
esac
@@ -5533,13 +5905,23 @@ EOF
;;
sysv4)
- if test "x$host_vendor" = xsno; then
- archive_cmds='$LD -G -Bsymbolic -h $soname -o $lib $libobjs $deplibs $linker_flags'
- hardcode_direct=yes # is this really true???
- else
- archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
- hardcode_direct=no #Motorola manual says yes, but my tests say they lie
- fi
+ case $host_vendor in
+ sni)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_direct=yes # is this really true???
+ ;;
+ siemens)
+ ## LD is ld it makes a PLAMLIB
+ ## CC just makes a GrossModule.
+ archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags'
+ reload_cmds='$CC -r -o $output$reload_objs'
+ hardcode_direct=no
+ ;;
+ motorola)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_direct=no #Motorola manual says yes, but my tests say they lie
+ ;;
+ esac
runpath_var='LD_RUN_PATH'
hardcode_shlibpath_var=no
;;
@@ -5687,6 +6069,9 @@ aix3*)
aix4* | aix5*)
version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ hardcode_into_libs=yes
if test "$host_cpu" = ia64; then
# AIX 5 supports IA64
library_names_spec='${libname}${release}.so$major ${libname}${release}.so$versuffix $libname.so'
@@ -5725,6 +6110,7 @@ aix4* | aix5*)
fi
shlibpath_var=LIBPATH
fi
+ hardcode_into_libs=yes
;;
amigaos*)
@@ -5772,7 +6158,7 @@ cygwin* | mingw* | pw32*)
;;
yes,mingw*)
library_names_spec='${libname}`echo ${release} | sed -e 's/[.]/-/g'`${versuffix}.dll'
- sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | sed -e "s/^libraries://" -e "s/;/ /g"`
+ sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | sed -e "s/^libraries://" -e "s/;/ /g" -e "s,=/,/,g"`
;;
yes,pw32*)
library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | sed -e 's/./-/g'`${versuffix}.dll'
@@ -5855,14 +6241,17 @@ hpux9* | hpux10* | hpux11*)
postinstall_cmds='chmod 555 $lib'
;;
-irix5* | irix6*)
- version_type=irix
+irix5* | irix6* | nonstopux*)
+ case $host_os in
+ nonstopux*) version_type=nonstopux ;;
+ *) version_type=irix ;;
+ esac
need_lib_prefix=no
need_version=no
soname_spec='${libname}${release}.so$major'
library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major ${libname}${release}.so $libname.so'
case $host_os in
- irix5*)
+ irix5* | nonstopux*)
libsuff= shlibsuff=
;;
*)
@@ -5907,6 +6296,30 @@ linux-gnu*)
# people can always --disable-shared, the test was removed, and we
# assume the GNU/Linux dynamic linker is in use.
dynamic_linker='GNU/Linux ld.so'
+
+ # Find out which ABI we are using (multilib Linux x86_64 hack).
+ libsuff=
+ case "$host_cpu" in
+ x86_64*|s390x*)
+ echo '#line 6304 "configure"' > conftest.$ac_ext
+ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; then
+ case `/usr/bin/file conftest.$ac_objext` in
+ *64-bit*)
+ libsuff=64
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+ *)
+ ;;
+ esac
+ sys_lib_dlsearch_path_spec="/lib${libsuff} /usr/lib${libsuff}"
+ sys_lib_search_path_spec="/lib${libsuff} /usr/lib${libsuff} /usr/local/lib${libsuff}"
;;
netbsd*)
@@ -5966,11 +6379,12 @@ os2*)
osf3* | osf4* | osf5*)
version_type=osf
need_version=no
- soname_spec='${libname}${release}.so'
- library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so $libname.so'
+ soname_spec='${libname}${release}.so$major'
+ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
shlibpath_var=LD_LIBRARY_PATH
sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec"
+ hardcode_into_libs=yes
;;
sco3.2v5*)
@@ -6013,6 +6427,12 @@ sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
case $host_vendor in
sni)
shlibpath_overrides_runpath=no
+ need_lib_prefix=no
+ export_dynamic_flag_spec='${wl}-Blargedynsym'
+ runpath_var=LD_RUN_PATH
+ ;;
+ siemens)
+ need_lib_prefix=no
;;
motorola)
need_lib_prefix=no
@@ -6135,37 +6555,44 @@ if test "${ac_cv_func_shl_load+set}" = set; then
else
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
-#include "confdefs.h"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
/* System header to define __stub macros and hopefully few prototypes,
- which can conflict with char shl_load (); below. */
-#include <assert.h>
+ which can conflict with char shl_load (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
/* Override any gcc2 internal prototype to avoid an error. */
#ifdef __cplusplus
extern "C"
+{
#endif
/* We use char because int might match the return type of a gcc2
builtin and then its argument prototype would still apply. */
char shl_load ();
-char (*f) ();
-
-#ifdef F77_DUMMY_MAIN
-# ifdef __cplusplus
- extern "C"
-# endif
- int F77_DUMMY_MAIN() { return 1; }
-#endif
-int
-main ()
-{
/* The GNU C library defines this for functions which it implements
to always fail with ENOSYS. Some functions are actually named
something starting with __ and the normal name is an alias. */
#if defined (__stub_shl_load) || defined (__stub___shl_load)
choke me
#else
-f = shl_load;
+char (*f) () = shl_load;
+#endif
+#ifdef __cplusplus
+}
#endif
+int
+main ()
+{
+return f != shl_load;
;
return 0;
}
@@ -6185,7 +6612,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
ac_cv_func_shl_load=yes
else
echo "$as_me: failed program was:" >&5
-cat conftest.$ac_ext >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
ac_cv_func_shl_load=no
fi
rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
@@ -6204,7 +6632,11 @@ else
LIBS="-ldld $LIBS"
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
-#include "confdefs.h"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
/* Override any gcc2 internal prototype to avoid an error. */
#ifdef __cplusplus
@@ -6213,12 +6645,6 @@ extern "C"
/* We use char because int might match the return type of a gcc2
builtin and then its argument prototype would still apply. */
char shl_load ();
-#ifdef F77_DUMMY_MAIN
-# ifdef __cplusplus
- extern "C"
-# endif
- int F77_DUMMY_MAIN() { return 1; }
-#endif
int
main ()
{
@@ -6242,7 +6668,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
ac_cv_lib_dld_shl_load=yes
else
echo "$as_me: failed program was:" >&5
-cat conftest.$ac_ext >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
ac_cv_lib_dld_shl_load=no
fi
rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
@@ -6260,37 +6687,44 @@ if test "${ac_cv_func_dlopen+set}" = set; then
else
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
-#include "confdefs.h"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
/* System header to define __stub macros and hopefully few prototypes,
- which can conflict with char dlopen (); below. */
-#include <assert.h>
+ which can conflict with char dlopen (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
/* Override any gcc2 internal prototype to avoid an error. */
#ifdef __cplusplus
extern "C"
+{
#endif
/* We use char because int might match the return type of a gcc2
builtin and then its argument prototype would still apply. */
char dlopen ();
-char (*f) ();
-
-#ifdef F77_DUMMY_MAIN
-# ifdef __cplusplus
- extern "C"
-# endif
- int F77_DUMMY_MAIN() { return 1; }
-#endif
-int
-main ()
-{
/* The GNU C library defines this for functions which it implements
to always fail with ENOSYS. Some functions are actually named
something starting with __ and the normal name is an alias. */
#if defined (__stub_dlopen) || defined (__stub___dlopen)
choke me
#else
-f = dlopen;
+char (*f) () = dlopen;
+#endif
+#ifdef __cplusplus
+}
#endif
+int
+main ()
+{
+return f != dlopen;
;
return 0;
}
@@ -6310,7 +6744,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
ac_cv_func_dlopen=yes
else
echo "$as_me: failed program was:" >&5
-cat conftest.$ac_ext >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
ac_cv_func_dlopen=no
fi
rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
@@ -6329,7 +6764,11 @@ else
LIBS="-ldl $LIBS"
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
-#include "confdefs.h"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
/* Override any gcc2 internal prototype to avoid an error. */
#ifdef __cplusplus
@@ -6338,12 +6777,6 @@ extern "C"
/* We use char because int might match the return type of a gcc2
builtin and then its argument prototype would still apply. */
char dlopen ();
-#ifdef F77_DUMMY_MAIN
-# ifdef __cplusplus
- extern "C"
-# endif
- int F77_DUMMY_MAIN() { return 1; }
-#endif
int
main ()
{
@@ -6367,7 +6800,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
ac_cv_lib_dl_dlopen=yes
else
echo "$as_me: failed program was:" >&5
-cat conftest.$ac_ext >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
ac_cv_lib_dl_dlopen=no
fi
rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
@@ -6387,7 +6821,11 @@ else
LIBS="-lsvld $LIBS"
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
-#include "confdefs.h"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
/* Override any gcc2 internal prototype to avoid an error. */
#ifdef __cplusplus
@@ -6396,12 +6834,6 @@ extern "C"
/* We use char because int might match the return type of a gcc2
builtin and then its argument prototype would still apply. */
char dlopen ();
-#ifdef F77_DUMMY_MAIN
-# ifdef __cplusplus
- extern "C"
-# endif
- int F77_DUMMY_MAIN() { return 1; }
-#endif
int
main ()
{
@@ -6425,7 +6857,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
ac_cv_lib_svld_dlopen=yes
else
echo "$as_me: failed program was:" >&5
-cat conftest.$ac_ext >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
ac_cv_lib_svld_dlopen=no
fi
rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
@@ -6445,7 +6878,11 @@ else
LIBS="-ldld $LIBS"
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
-#include "confdefs.h"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
/* Override any gcc2 internal prototype to avoid an error. */
#ifdef __cplusplus
@@ -6454,12 +6891,6 @@ extern "C"
/* We use char because int might match the return type of a gcc2
builtin and then its argument prototype would still apply. */
char dld_link ();
-#ifdef F77_DUMMY_MAIN
-# ifdef __cplusplus
- extern "C"
-# endif
- int F77_DUMMY_MAIN() { return 1; }
-#endif
int
main ()
{
@@ -6483,7 +6914,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
ac_cv_lib_dld_dld_link=yes
else
echo "$as_me: failed program was:" >&5
-cat conftest.$ac_ext >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
ac_cv_lib_dld_dld_link=no
fi
rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
@@ -6541,7 +6973,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<EOF
-#line 6544 "configure"
+#line 6976 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -6639,7 +7071,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<EOF
-#line 6642 "configure"
+#line 7074 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -6822,7 +7254,7 @@ if test -f "$ltmain"; then
# Now quote all the things that may contain metacharacters while being
# careful not to overquote the AC_SUBSTed values. We take copies of the
# variables and quote the copies for generation of the libtool script.
- for var in echo old_CC old_CFLAGS \
+ for var in echo old_CC old_CFLAGS SED \
AR AR_FLAGS CC LD LN_S NM SHELL \
reload_flag reload_cmds wl \
pic_flag link_static_flag no_builtin_flag export_dynamic_flag_spec \
@@ -6884,8 +7316,11 @@ if test -f "$ltmain"; then
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
+# A sed that does not truncate output.
+SED=$lt_SED
+
# Sed that helps us avoid accidentally triggering echo(1) options like -n.
-Xsed="sed -e s/^X//"
+Xsed="${SED} -e s/^X//"
# The HP-UX ksh and POSIX shell print the target directory to stdout
# if CDPATH is set.
@@ -7389,48 +7824,59 @@ if test "${ac_cv_header_stdc+set}" = set; then
else
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
-#include "confdefs.h"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <float.h>
+int
+main ()
+{
+
+ ;
+ return 0;
+}
_ACEOF
-if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
- (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>&5
ac_status=$?
- egrep -v '^ *\+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null; then
- if test -s conftest.err; then
- ac_cpp_err=$ac_c_preproc_warn_flag
- else
- ac_cpp_err=
- fi
-else
- ac_cpp_err=yes
-fi
-if test -z "$ac_cpp_err"; then
+ (exit $ac_status); } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
ac_cv_header_stdc=yes
else
echo "$as_me: failed program was:" >&5
- cat conftest.$ac_ext >&5
- ac_cv_header_stdc=no
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_header_stdc=no
fi
-rm -f conftest.err conftest.$ac_ext
+rm -f conftest.$ac_objext conftest.$ac_ext
if test $ac_cv_header_stdc = yes; then
# SunOS 4.x string.h does not declare mem*, contrary to ANSI.
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
-#include "confdefs.h"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
#include <string.h>
_ACEOF
if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- egrep "memchr" >/dev/null 2>&1; then
+ $EGREP "memchr" >/dev/null 2>&1; then
:
else
ac_cv_header_stdc=no
@@ -7443,12 +7889,16 @@ if test $ac_cv_header_stdc = yes; then
# ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
-#include "confdefs.h"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
#include <stdlib.h>
_ACEOF
if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- egrep "free" >/dev/null 2>&1; then
+ $EGREP "free" >/dev/null 2>&1; then
:
else
ac_cv_header_stdc=no
@@ -7464,13 +7914,18 @@ if test $ac_cv_header_stdc = yes; then
else
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
-#include "confdefs.h"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
#include <ctype.h>
#if ((' ' & 0x0FF) == 0x020)
# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
#else
-# define ISLOWER(c) (('a' <= (c) && (c) <= 'i') \
+# define ISLOWER(c) \
+ (('a' <= (c) && (c) <= 'i') \
|| ('j' <= (c) && (c) <= 'r') \
|| ('s' <= (c) && (c) <= 'z'))
# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
@@ -7503,11 +7958,12 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
else
echo "$as_me: program exited with status $ac_status" >&5
echo "$as_me: failed program was:" >&5
-cat conftest.$ac_ext >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
( exit $ac_status )
ac_cv_header_stdc=no
fi
-rm -f core core.* *.core conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
fi
fi
fi
@@ -7528,7 +7984,11 @@ if test "${ac_cv_header_sys_wait_h+set}" = set; then
else
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
-#include "confdefs.h"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
#include <sys/types.h>
#include <sys/wait.h>
#ifndef WEXITSTATUS
@@ -7538,12 +7998,6 @@ else
# define WIFEXITED(stat_val) (((stat_val) & 255) == 0)
#endif
-#ifdef F77_DUMMY_MAIN
-# ifdef __cplusplus
- extern "C"
-# endif
- int F77_DUMMY_MAIN() { return 1; }
-#endif
int
main ()
{
@@ -7569,7 +8023,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
ac_cv_header_sys_wait_h=yes
else
echo "$as_me: failed program was:" >&5
-cat conftest.$ac_ext >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
ac_cv_header_sys_wait_h=no
fi
rm -f conftest.$ac_objext conftest.$ac_ext
@@ -7613,7 +8068,11 @@ echo "$as_me:$LINENO: checking $ac_header usability" >&5
echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
-#include "confdefs.h"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
$ac_includes_default
#include <$ac_header>
_ACEOF
@@ -7632,7 +8091,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
ac_header_compiler=yes
else
echo "$as_me: failed program was:" >&5
-cat conftest.$ac_ext >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
ac_header_compiler=no
fi
rm -f conftest.$ac_objext conftest.$ac_ext
@@ -7644,13 +8104,17 @@ echo "$as_me:$LINENO: checking $ac_header presence" >&5
echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
-#include "confdefs.h"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
#include <$ac_header>
_ACEOF
if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
(eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
ac_status=$?
- egrep -v '^ *\+' conftest.er1 >conftest.err
+ grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
@@ -7667,7 +8131,8 @@ if test -z "$ac_cpp_err"; then
ac_header_preproc=yes
else
echo "$as_me: failed program was:" >&5
- cat conftest.$ac_ext >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
ac_header_preproc=no
fi
rm -f conftest.err conftest.$ac_ext
@@ -7680,14 +8145,32 @@ case $ac_header_compiler:$ac_header_preproc in
{ echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
{ echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;};;
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+ (
+ cat <<\_ASBOX
+## ------------------------------------ ##
+## Report this to bug-autoconf@gnu.org. ##
+## ------------------------------------ ##
+_ASBOX
+ ) |
+ sed "s/^/$as_me: WARNING: /" >&2
+ ;;
no:yes )
{ echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
{ echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
{ echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;};;
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+ (
+ cat <<\_ASBOX
+## ------------------------------------ ##
+## Report this to bug-autoconf@gnu.org. ##
+## ------------------------------------ ##
+_ASBOX
+ ) |
+ sed "s/^/$as_me: WARNING: /" >&2
+ ;;
esac
echo "$as_me:$LINENO: checking for $ac_header" >&5
echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
@@ -7711,103 +8194,6 @@ done
# Checks for typedefs, structures, and compiler characteristics.
-echo "$as_me:$LINENO: checking for $CC option to accept ANSI C" >&5
-echo $ECHO_N "checking for $CC option to accept ANSI C... $ECHO_C" >&6
-if test "${ac_cv_prog_cc_stdc+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_cv_prog_cc_stdc=no
-ac_save_CC=$CC
-cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
-#include "confdefs.h"
-#include <stdarg.h>
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */
-struct buf { int x; };
-FILE * (*rcsopen) (struct buf *, struct stat *, int);
-static char *e (p, i)
- char **p;
- int i;
-{
- return p[i];
-}
-static char *f (char * (*g) (char **, int), char **p, ...)
-{
- char *s;
- va_list v;
- va_start (v,p);
- s = g (p, va_arg (v,int));
- va_end (v);
- return s;
-}
-int test (int i, double x);
-struct s1 {int (*f) (int a);};
-struct s2 {int (*f) (double a);};
-int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
-int argc;
-char **argv;
-#ifdef F77_DUMMY_MAIN
-# ifdef __cplusplus
- extern "C"
-# endif
- int F77_DUMMY_MAIN() { return 1; }
-#endif
-int
-main ()
-{
-return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1];
- ;
- return 0;
-}
-_ACEOF
-# Don't try gcc -ansi; that turns off useful extensions and
-# breaks some systems' header files.
-# AIX -qlanglvl=ansi
-# Ultrix and OSF/1 -std1
-# HP-UX 10.20 and later -Ae
-# HP-UX older versions -Aa -D_HPUX_SOURCE
-# SVR4 -Xc -D__EXTENSIONS__
-for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
-do
- CC="$ac_save_CC $ac_arg"
- rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_prog_cc_stdc=$ac_arg
-break
-else
- echo "$as_me: failed program was:" >&5
-cat conftest.$ac_ext >&5
-fi
-rm -f conftest.$ac_objext
-done
-rm -f conftest.$ac_ext conftest.$ac_objext
-CC=$ac_save_CC
-
-fi
-
-case "x$ac_cv_prog_cc_stdc" in
- x|xno)
- echo "$as_me:$LINENO: result: none needed" >&5
-echo "${ECHO_T}none needed" >&6 ;;
- *)
- echo "$as_me:$LINENO: result: $ac_cv_prog_cc_stdc" >&5
-echo "${ECHO_T}$ac_cv_prog_cc_stdc" >&6
- CC="$CC $ac_cv_prog_cc_stdc" ;;
-esac
-
echo "$as_me:$LINENO: checking for an ANSI C-conforming const" >&5
echo $ECHO_N "checking for an ANSI C-conforming const... $ECHO_C" >&6
if test "${ac_cv_c_const+set}" = set; then
@@ -7815,14 +8201,12 @@ if test "${ac_cv_c_const+set}" = set; then
else
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
-#include "confdefs.h"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
-#ifdef F77_DUMMY_MAIN
-# ifdef __cplusplus
- extern "C"
-# endif
- int F77_DUMMY_MAIN() { return 1; }
-#endif
int
main ()
{
@@ -7892,7 +8276,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
ac_cv_c_const=yes
else
echo "$as_me: failed program was:" >&5
-cat conftest.$ac_ext >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
ac_cv_c_const=no
fi
rm -f conftest.$ac_objext conftest.$ac_ext
@@ -7914,14 +8299,12 @@ if test "${ac_cv_type_mode_t+set}" = set; then
else
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
-#include "confdefs.h"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
$ac_includes_default
-#ifdef F77_DUMMY_MAIN
-# ifdef __cplusplus
- extern "C"
-# endif
- int F77_DUMMY_MAIN() { return 1; }
-#endif
int
main ()
{
@@ -7948,7 +8331,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
ac_cv_type_mode_t=yes
else
echo "$as_me: failed program was:" >&5
-cat conftest.$ac_ext >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
ac_cv_type_mode_t=no
fi
rm -f conftest.$ac_objext conftest.$ac_ext
@@ -7972,14 +8356,12 @@ if test "${ac_cv_type_size_t+set}" = set; then
else
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
-#include "confdefs.h"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
$ac_includes_default
-#ifdef F77_DUMMY_MAIN
-# ifdef __cplusplus
- extern "C"
-# endif
- int F77_DUMMY_MAIN() { return 1; }
-#endif
int
main ()
{
@@ -8006,7 +8388,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
ac_cv_type_size_t=yes
else
echo "$as_me: failed program was:" >&5
-cat conftest.$ac_ext >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
ac_cv_type_size_t=no
fi
rm -f conftest.$ac_objext conftest.$ac_ext
@@ -8030,17 +8413,15 @@ if test "${ac_cv_header_time+set}" = set; then
else
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
-#include "confdefs.h"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
#include <sys/types.h>
#include <sys/time.h>
#include <time.h>
-#ifdef F77_DUMMY_MAIN
-# ifdef __cplusplus
- extern "C"
-# endif
- int F77_DUMMY_MAIN() { return 1; }
-#endif
int
main ()
{
@@ -8065,7 +8446,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
ac_cv_header_time=yes
else
echo "$as_me: failed program was:" >&5
-cat conftest.$ac_ext >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
ac_cv_header_time=no
fi
rm -f conftest.$ac_objext conftest.$ac_ext
@@ -8091,12 +8473,16 @@ else
ac_pattern="Autoconf.*'x'"
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
-#include "confdefs.h"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
#include <sgtty.h>
Autoconf TIOCGETP
_ACEOF
if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- egrep "$ac_pattern" >/dev/null 2>&1; then
+ $EGREP "$ac_pattern" >/dev/null 2>&1; then
ac_cv_prog_gcc_traditional=yes
else
ac_cv_prog_gcc_traditional=no
@@ -8107,12 +8493,16 @@ rm -f conftest*
if test $ac_cv_prog_gcc_traditional = no; then
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
-#include "confdefs.h"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
#include <termio.h>
Autoconf TCGETA
_ACEOF
if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- egrep "$ac_pattern" >/dev/null 2>&1; then
+ $EGREP "$ac_pattern" >/dev/null 2>&1; then
ac_cv_prog_gcc_traditional=yes
fi
rm -f conftest*
@@ -8144,7 +8534,11 @@ echo "$as_me:$LINENO: checking $ac_header usability" >&5
echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
-#include "confdefs.h"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
$ac_includes_default
#include <$ac_header>
_ACEOF
@@ -8163,7 +8557,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
ac_header_compiler=yes
else
echo "$as_me: failed program was:" >&5
-cat conftest.$ac_ext >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
ac_header_compiler=no
fi
rm -f conftest.$ac_objext conftest.$ac_ext
@@ -8175,13 +8570,17 @@ echo "$as_me:$LINENO: checking $ac_header presence" >&5
echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
-#include "confdefs.h"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
#include <$ac_header>
_ACEOF
if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
(eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
ac_status=$?
- egrep -v '^ *\+' conftest.er1 >conftest.err
+ grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
@@ -8198,7 +8597,8 @@ if test -z "$ac_cpp_err"; then
ac_header_preproc=yes
else
echo "$as_me: failed program was:" >&5
- cat conftest.$ac_ext >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
ac_header_preproc=no
fi
rm -f conftest.err conftest.$ac_ext
@@ -8211,14 +8611,32 @@ case $ac_header_compiler:$ac_header_preproc in
{ echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
{ echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;};;
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+ (
+ cat <<\_ASBOX
+## ------------------------------------ ##
+## Report this to bug-autoconf@gnu.org. ##
+## ------------------------------------ ##
+_ASBOX
+ ) |
+ sed "s/^/$as_me: WARNING: /" >&2
+ ;;
no:yes )
{ echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
{ echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
{ echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;};;
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+ (
+ cat <<\_ASBOX
+## ------------------------------------ ##
+## Report this to bug-autoconf@gnu.org. ##
+## ------------------------------------ ##
+_ASBOX
+ ) |
+ sed "s/^/$as_me: WARNING: /" >&2
+ ;;
esac
echo "$as_me:$LINENO: checking for $ac_header" >&5
echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
@@ -8240,29 +8658,27 @@ fi
done
-echo "$as_me:$LINENO: checking for working malloc" >&5
-echo $ECHO_N "checking for working malloc... $ECHO_C" >&6
-if test "${ac_cv_func_malloc_works+set}" = set; then
+echo "$as_me:$LINENO: checking for GNU libc compatible malloc" >&5
+echo $ECHO_N "checking for GNU libc compatible malloc... $ECHO_C" >&6
+if test "${ac_cv_func_malloc_0_nonnull+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
if test "$cross_compiling" = yes; then
- ac_cv_func_malloc_works=no
+ ac_cv_func_malloc_0_nonnull=no
else
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
-#include "confdefs.h"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
#if STDC_HEADERS || HAVE_STDLIB_H
# include <stdlib.h>
#else
char *malloc ();
#endif
-#ifdef F77_DUMMY_MAIN
-# ifdef __cplusplus
- extern "C"
-# endif
- int F77_DUMMY_MAIN() { return 1; }
-#endif
int
main ()
{
@@ -8282,27 +8698,41 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
- ac_cv_func_malloc_works=yes
+ ac_cv_func_malloc_0_nonnull=yes
else
echo "$as_me: program exited with status $ac_status" >&5
echo "$as_me: failed program was:" >&5
-cat conftest.$ac_ext >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
( exit $ac_status )
-ac_cv_func_malloc_works=no
+ac_cv_func_malloc_0_nonnull=no
fi
-rm -f core core.* *.core conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
fi
fi
-echo "$as_me:$LINENO: result: $ac_cv_func_malloc_works" >&5
-echo "${ECHO_T}$ac_cv_func_malloc_works" >&6
-if test $ac_cv_func_malloc_works = yes; then
+echo "$as_me:$LINENO: result: $ac_cv_func_malloc_0_nonnull" >&5
+echo "${ECHO_T}$ac_cv_func_malloc_0_nonnull" >&6
+if test $ac_cv_func_malloc_0_nonnull = yes; then
cat >>confdefs.h <<\_ACEOF
#define HAVE_MALLOC 1
_ACEOF
+else
+ cat >>confdefs.h <<\_ACEOF
+#define HAVE_MALLOC 0
+_ACEOF
+
+ LIBOBJS="$LIBOBJS malloc.$ac_objext"
+
+cat >>confdefs.h <<\_ACEOF
+#define malloc rpl_malloc
+_ACEOF
+
fi
+
+
echo "$as_me:$LINENO: checking for working memcmp" >&5
echo $ECHO_N "checking for working memcmp... $ECHO_C" >&6
if test "${ac_cv_func_memcmp_working+set}" = set; then
@@ -8313,14 +8743,12 @@ else
else
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
-#include "confdefs.h"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
-#ifdef F77_DUMMY_MAIN
-# ifdef __cplusplus
- extern "C"
-# endif
- int F77_DUMMY_MAIN() { return 1; }
-#endif
int
main ()
{
@@ -8368,11 +8796,12 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
else
echo "$as_me: program exited with status $ac_status" >&5
echo "$as_me: failed program was:" >&5
-cat conftest.$ac_ext >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
( exit $ac_status )
ac_cv_func_memcmp_working=no
fi
-rm -f core core.* *.core conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
fi
fi
echo "$as_me:$LINENO: result: $ac_cv_func_memcmp_working" >&5
@@ -8397,37 +8826,44 @@ if eval "test \"\${$as_ac_var+set}\" = set"; then
else
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
-#include "confdefs.h"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
/* System header to define __stub macros and hopefully few prototypes,
- which can conflict with char $ac_func (); below. */
-#include <assert.h>
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
/* Override any gcc2 internal prototype to avoid an error. */
#ifdef __cplusplus
extern "C"
+{
#endif
/* We use char because int might match the return type of a gcc2
builtin and then its argument prototype would still apply. */
char $ac_func ();
-char (*f) ();
-
-#ifdef F77_DUMMY_MAIN
-# ifdef __cplusplus
- extern "C"
-# endif
- int F77_DUMMY_MAIN() { return 1; }
-#endif
-int
-main ()
-{
/* The GNU C library defines this for functions which it implements
to always fail with ENOSYS. Some functions are actually named
something starting with __ and the normal name is an alias. */
#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
choke me
#else
-f = $ac_func;
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
#endif
+int
+main ()
+{
+return f != $ac_func;
;
return 0;
}
@@ -8447,7 +8883,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
eval "$as_ac_var=yes"
else
echo "$as_me: failed program was:" >&5
-cat conftest.$ac_ext >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
eval "$as_ac_var=no"
fi
rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
@@ -8536,15 +8973,15 @@ else
echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;}
fi
-echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \${MAKE}" >&5
-echo $ECHO_N "checking whether ${MAKE-make} sets \${MAKE}... $ECHO_C" >&6
+echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \$(MAKE)" >&5
+echo $ECHO_N "checking whether ${MAKE-make} sets \$(MAKE)... $ECHO_C" >&6
set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y,./+-,__p_,'`
if eval "test \"\${ac_cv_prog_make_${ac_make}_set+set}\" = set"; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
cat >conftest.make <<\_ACEOF
all:
- @echo 'ac_maketemp="${MAKE}"'
+ @echo 'ac_maketemp="$(MAKE)"'
_ACEOF
# GNU make sometimes prints "make[1]: Entering...", which would confuse us.
eval `${MAKE-make} -f conftest.make 2>/dev/null | grep temp=`
@@ -8576,7 +9013,7 @@ fi
rmdir .deps 2>/dev/null
-ac_config_commands="$ac_config_commands depfiles"
+ ac_config_commands="$ac_config_commands depfiles"
am_make=${MAKE-make}
@@ -8913,7 +9350,7 @@ CXXDEPMODE=depmode=$am_cv_CXX_dependencies_compiler_type
-ac_config_files="$ac_config_files Makefile doc/Makefile ggsn/Makefile gtp/Makefile intl/Makefile po/Makefile sgsnemu/Makefile src/Makefile tests/Makefile openggsn.spec"
+ ac_config_files="$ac_config_files Makefile doc/Makefile ggsn/Makefile gtp/Makefile intl/Makefile po/Makefile sgsnemu/Makefile src/Makefile tests/Makefile openggsn.spec"
cat >confcache <<\_ACEOF
# This file is a shell script that caches the results of configure
@@ -8925,7 +9362,7 @@ cat >confcache <<\_ACEOF
# config.status only pays attention to the cache file if you give it
# the --recheck option to rerun configure.
#
-# `ac_cv_env_foo' variables (set or unset) will be overriden when
+# `ac_cv_env_foo' variables (set or unset) will be overridden when
# loading this file, other *unset* `ac_cv_foo' will be assigned the
# following values.
@@ -8960,7 +9397,7 @@ _ACEOF
t end
/^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
: end' >>confcache
-if cmp -s $cache_file confcache; then :; else
+if diff $cache_file confcache >/dev/null 2>&1; then :; else
if test -w $cache_file; then
test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file"
cat confcache >$cache_file
@@ -8991,6 +9428,21 @@ fi
DEFS=-DHAVE_CONFIG_H
+ac_libobjs=
+ac_ltlibobjs=
+for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
+ # 1. Remove the extension, and $U if already installed.
+ ac_i=`echo "$ac_i" |
+ sed 's/\$U\././;s/\.o$//;s/\.obj$//'`
+ # 2. Add them.
+ ac_libobjs="$ac_libobjs $ac_i\$U.$ac_objext"
+ ac_ltlibobjs="$ac_ltlibobjs $ac_i"'$U.lo'
+done
+LIBOBJS=$ac_libobjs
+
+LTLIBOBJS=$ac_ltlibobjs
+
+
if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then
{ { echo "$as_me:$LINENO: error: conditional \"AMDEP\" was never defined.
Usually this means the macro was only invoked conditionally." >&5
@@ -9012,11 +9464,12 @@ cat >$CONFIG_STATUS <<_ACEOF
# configure, is in config.log if it exists.
debug=false
+ac_cs_recheck=false
+ac_cs_silent=false
SHELL=\${CONFIG_SHELL-$SHELL}
_ACEOF
cat >>$CONFIG_STATUS <<\_ACEOF
-
## --------------------- ##
## M4sh Initialization. ##
## --------------------- ##
@@ -9025,11 +9478,13 @@ cat >>$CONFIG_STATUS <<\_ACEOF
if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
emulate sh
NULLCMD=:
+ # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
set -o posix
fi
-# NLS nuisances.
# Support unset when possible.
if (FOO=FOO; unset FOO) >/dev/null 2>&1; then
as_unset=unset
@@ -9037,34 +9492,42 @@ else
as_unset=false
fi
-(set +x; test -n "`(LANG=C; export LANG) 2>&1`") &&
- { $as_unset LANG || test "${LANG+set}" != set; } ||
- { LANG=C; export LANG; }
-(set +x; test -n "`(LC_ALL=C; export LC_ALL) 2>&1`") &&
- { $as_unset LC_ALL || test "${LC_ALL+set}" != set; } ||
- { LC_ALL=C; export LC_ALL; }
-(set +x; test -n "`(LC_TIME=C; export LC_TIME) 2>&1`") &&
- { $as_unset LC_TIME || test "${LC_TIME+set}" != set; } ||
- { LC_TIME=C; export LC_TIME; }
-(set +x; test -n "`(LC_CTYPE=C; export LC_CTYPE) 2>&1`") &&
- { $as_unset LC_CTYPE || test "${LC_CTYPE+set}" != set; } ||
- { LC_CTYPE=C; export LC_CTYPE; }
-(set +x; test -n "`(LANGUAGE=C; export LANGUAGE) 2>&1`") &&
- { $as_unset LANGUAGE || test "${LANGUAGE+set}" != set; } ||
- { LANGUAGE=C; export LANGUAGE; }
-(set +x; test -n "`(LC_COLLATE=C; export LC_COLLATE) 2>&1`") &&
- { $as_unset LC_COLLATE || test "${LC_COLLATE+set}" != set; } ||
- { LC_COLLATE=C; export LC_COLLATE; }
-(set +x; test -n "`(LC_NUMERIC=C; export LC_NUMERIC) 2>&1`") &&
- { $as_unset LC_NUMERIC || test "${LC_NUMERIC+set}" != set; } ||
- { LC_NUMERIC=C; export LC_NUMERIC; }
-(set +x; test -n "`(LC_MESSAGES=C; export LC_MESSAGES) 2>&1`") &&
- { $as_unset LC_MESSAGES || test "${LC_MESSAGES+set}" != set; } ||
- { LC_MESSAGES=C; export LC_MESSAGES; }
+
+# Work around bugs in pre-3.0 UWIN ksh.
+$as_unset ENV MAIL MAILPATH
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+for as_var in \
+ LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
+ LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
+ LC_TELEPHONE LC_TIME
+do
+ if (set +x; test -n "`(eval $as_var=C; export $as_var) 2>&1`"); then
+ eval $as_var=C; export $as_var
+ else
+ $as_unset $as_var
+ fi
+done
+
+# Required to use basename.
+if expr a : '\(a\)' >/dev/null 2>&1; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then
+ as_basename=basename
+else
+ as_basename=false
+fi
# Name of the executable.
-as_me=`(basename "$0") 2>/dev/null ||
+as_me=`$as_basename "$0" ||
$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
X"$0" : 'X\(//\)$' \| \
X"$0" : 'X\(/\)$' \| \
@@ -9075,6 +9538,7 @@ echo X/"$0" |
/^X\/\(\/\).*/{ s//\1/; q; }
s/.*/./; q'`
+
# PATH needs CR, and LINENO needs CR and PATH.
# Avoid depending upon Character Ranges.
as_cr_letters='abcdefghijklmnopqrstuvwxyz'
@@ -9085,15 +9549,15 @@ as_cr_alnum=$as_cr_Letters$as_cr_digits
# The user is always right.
if test "${PATH_SEPARATOR+set}" != set; then
- echo "#! /bin/sh" >conftest.sh
- echo "exit 0" >>conftest.sh
- chmod +x conftest.sh
- if (PATH=".;."; conftest.sh) >/dev/null 2>&1; then
+ echo "#! /bin/sh" >conf$$.sh
+ echo "exit 0" >>conf$$.sh
+ chmod +x conf$$.sh
+ if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
PATH_SEPARATOR=';'
else
PATH_SEPARATOR=:
fi
- rm -f conftest.sh
+ rm -f conf$$.sh
fi
@@ -9142,6 +9606,8 @@ do
as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
test "x$as_lineno_1" != "x$as_lineno_2" &&
test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then
+ $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; }
+ $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; }
CONFIG_SHELL=$as_dir/$as_base
export CONFIG_SHELL
exec "$CONFIG_SHELL" "$0" ${1+"$@"}
@@ -9215,6 +9681,12 @@ else
fi
rm -f conf$$ conf$$.exe conf$$.file
+if mkdir -p . 2>/dev/null; then
+ as_mkdir_p=:
+else
+ as_mkdir_p=false
+fi
+
as_executable_p="test -f"
# Sed expression to map a string onto a valid CPP name.
@@ -9231,7 +9703,7 @@ as_nl='
IFS=" $as_nl"
# CDPATH.
-$as_unset CDPATH || test "${CDPATH+set}" != set || { CDPATH=$PATH_SEPARATOR; export CDPATH; }
+$as_unset CDPATH
exec 6>&1
@@ -9248,7 +9720,7 @@ _ASBOX
cat >&5 <<_CSEOF
This file was extended by openggsn $as_me 0.61b, which was
-generated by GNU Autoconf 2.53. Invocation command line was
+generated by GNU Autoconf 2.57. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
CONFIG_HEADERS = $CONFIG_HEADERS
@@ -9288,6 +9760,7 @@ Usage: $0 [OPTIONS] [FILE]...
-h, --help print this help, then exit
-V, --version print version number, then exit
+ -q, --quiet do not print progress messages
-d, --debug don't remove temporary files
--recheck update $as_me by reconfiguring in the same conditions
--file=FILE[:TEMPLATE]
@@ -9310,7 +9783,7 @@ _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF
ac_cs_version="\\
openggsn config.status 0.61b
-configured by $0, generated by GNU Autoconf 2.53,
+configured by $0, generated by GNU Autoconf 2.57,
with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\"
Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001
@@ -9331,25 +9804,25 @@ do
--*=*)
ac_option=`expr "x$1" : 'x\([^=]*\)='`
ac_optarg=`expr "x$1" : 'x[^=]*=\(.*\)'`
- shift
- set dummy "$ac_option" "$ac_optarg" ${1+"$@"}
- shift
+ ac_shift=:
+ ;;
+ -*)
+ ac_option=$1
+ ac_optarg=$2
+ ac_shift=shift
;;
- -*);;
*) # This is not an option, so the user has probably given explicit
# arguments.
+ ac_option=$1
ac_need_defaults=false;;
esac
- case $1 in
+ case $ac_option in
# Handling of the options.
_ACEOF
-cat >>$CONFIG_STATUS <<_ACEOF
- -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
- echo "running $SHELL $0 " $ac_configure_args " --no-create --no-recursion"
- exec $SHELL $0 $ac_configure_args --no-create --no-recursion ;;
-_ACEOF
cat >>$CONFIG_STATUS <<\_ACEOF
+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+ ac_cs_recheck=: ;;
--version | --vers* | -V )
echo "$ac_cs_version"; exit 0 ;;
--he | --h)
@@ -9364,13 +9837,16 @@ Try \`$0 --help' for more information." >&2;}
--debug | --d* | -d )
debug=: ;;
--file | --fil | --fi | --f )
- shift
- CONFIG_FILES="$CONFIG_FILES $1"
+ $ac_shift
+ CONFIG_FILES="$CONFIG_FILES $ac_optarg"
ac_need_defaults=false;;
--header | --heade | --head | --hea )
- shift
- CONFIG_HEADERS="$CONFIG_HEADERS $1"
+ $ac_shift
+ CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg"
ac_need_defaults=false;;
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil | --si | --s)
+ ac_cs_silent=: ;;
# This is an error.
-*) { { echo "$as_me:$LINENO: error: unrecognized option: $1
@@ -9385,6 +9861,20 @@ Try \`$0 --help' for more information." >&2;}
shift
done
+ac_configure_extra_args=
+
+if $ac_cs_silent; then
+ exec 6>/dev/null
+ ac_configure_extra_args="$ac_configure_extra_args --silent"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF
+if \$ac_cs_recheck; then
+ echo "running $SHELL $0 " $ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6
+ exec $SHELL $0 $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+fi
+
_ACEOF
cat >>$CONFIG_STATUS <<_ACEOF
@@ -9431,6 +9921,9 @@ if $ac_need_defaults; then
test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands
fi
+# Have a temporary directory for convenience. Make it in the build tree
+# simply because there is no reason to put it here, and in addition,
+# creating and moving files from /tmp can sometimes cause problems.
# Create a temporary directory, and hook for its removal unless debugging.
$debug ||
{
@@ -9439,17 +9932,17 @@ $debug ||
}
# Create a (secure) tmp directory for tmp files.
-: ${TMPDIR=/tmp}
+
{
- tmp=`(umask 077 && mktemp -d -q "$TMPDIR/csXXXXXX") 2>/dev/null` &&
+ tmp=`(umask 077 && mktemp -d -q "./confstatXXXXXX") 2>/dev/null` &&
test -n "$tmp" && test -d "$tmp"
} ||
{
- tmp=$TMPDIR/cs$$-$RANDOM
+ tmp=./confstat$$-$RANDOM
(umask 077 && mkdir $tmp)
} ||
{
- echo "$me: cannot create a temporary directory in $TMPDIR" >&2
+ echo "$me: cannot create a temporary directory in ." >&2
{ (exit 1); exit 1; }
}
@@ -9526,6 +10019,7 @@ s,@LN_S@,$LN_S,;t t
s,@ECHO@,$ECHO,;t t
s,@STRIP@,$STRIP,;t t
s,@ac_ct_STRIP@,$ac_ct_STRIP,;t t
+s,@EGREP@,$EGREP,;t t
s,@LIBTOOL@,$LIBTOOL,;t t
s,@EXEC_LDFLAGS@,$EXEC_LDFLAGS,;t t
s,@LIBOBJS@,$LIBOBJS,;t t
@@ -9548,6 +10042,7 @@ s,@AMDEP_FALSE@,$AMDEP_FALSE,;t t
s,@AMDEPBACKSLASH@,$AMDEPBACKSLASH,;t t
s,@CCDEPMODE@,$CCDEPMODE,;t t
s,@CXXDEPMODE@,$CXXDEPMODE,;t t
+s,@LTLIBOBJS@,$LTLIBOBJS,;t t
CEOF
_ACEOF
@@ -9618,25 +10113,30 @@ echo X"$ac_file" |
/^X\(\/\/\)$/{ s//\1/; q; }
/^X\(\/\).*/{ s//\1/; q; }
s/.*/./; q'`
- { case "$ac_dir" in
- [\\/]* | ?:[\\/]* ) as_incr_dir=;;
- *) as_incr_dir=.;;
-esac
-as_dummy="$ac_dir"
-for as_mkdir_dir in `IFS='/\\'; set X $as_dummy; shift; echo "$@"`; do
- case $as_mkdir_dir in
- # Skip DOS drivespec
- ?:) as_incr_dir=$as_mkdir_dir ;;
- *)
- as_incr_dir=$as_incr_dir/$as_mkdir_dir
- test -d "$as_incr_dir" ||
- mkdir "$as_incr_dir" ||
- { { echo "$as_me:$LINENO: error: cannot create \"$ac_dir\"" >&5
-echo "$as_me: error: cannot create \"$ac_dir\"" >&2;}
- { (exit 1); exit 1; }; }
- ;;
- esac
-done; }
+ { if $as_mkdir_p; then
+ mkdir -p "$ac_dir"
+ else
+ as_dir="$ac_dir"
+ as_dirs=
+ while test ! -d "$as_dir"; do
+ as_dirs="$as_dir $as_dirs"
+ as_dir=`(dirname "$as_dir") 2>/dev/null ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_dir" : 'X\(//\)[^/]' \| \
+ X"$as_dir" : 'X\(//\)$' \| \
+ X"$as_dir" : 'X\(/\)' \| \
+ . : '\(.\)' 2>/dev/null ||
+echo X"$as_dir" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+ /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+ /^X\(\/\/\)$/{ s//\1/; q; }
+ /^X\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`
+ done
+ test ! -n "$as_dirs" || mkdir $as_dirs
+ fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5
+echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;}
+ { (exit 1); exit 1; }; }; }
ac_builddir=.
@@ -9666,7 +10166,7 @@ esac
# Don't blindly perform a `cd "$ac_dir"/$ac_foo && pwd` since $ac_foo can be
# absolute.
ac_abs_builddir=`cd "$ac_dir" && cd $ac_builddir && pwd`
-ac_abs_top_builddir=`cd "$ac_dir" && cd $ac_top_builddir && pwd`
+ac_abs_top_builddir=`cd "$ac_dir" && cd ${ac_top_builddir}. && pwd`
ac_abs_srcdir=`cd "$ac_dir" && cd $ac_srcdir && pwd`
ac_abs_top_srcdir=`cd "$ac_dir" && cd $ac_top_srcdir && pwd`
@@ -9856,7 +10356,7 @@ _ACEOF
# Break up conftest.defines because some shells have a limit on the size
# of here documents, and old seds have small limits too (100 cmds).
echo ' # Handle all the #define templates only if necessary.' >>$CONFIG_STATUS
-echo ' if egrep "^[ ]*#[ ]*define" $tmp/in >/dev/null; then' >>$CONFIG_STATUS
+echo ' if grep "^[ ]*#[ ]*define" $tmp/in >/dev/null; then' >>$CONFIG_STATUS
echo ' # If there are no defines, we may have an empty if/fi' >>$CONFIG_STATUS
echo ' :' >>$CONFIG_STATUS
rm -f conftest.tail
@@ -9880,7 +10380,7 @@ do
mv conftest.tail conftest.defines
done
rm -f conftest.defines
-echo ' fi # egrep' >>$CONFIG_STATUS
+echo ' fi # grep' >>$CONFIG_STATUS
echo >>$CONFIG_STATUS
# Break up conftest.undefs because some shells have a limit on the size
@@ -9920,7 +10420,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF
cat $tmp/in >>$tmp/config.h
rm -f $tmp/in
if test x"$ac_file" != x-; then
- if cmp -s $ac_file $tmp/config.h 2>/dev/null; then
+ if diff $ac_file $tmp/config.h >/dev/null 2>&1; then
{ echo "$as_me:$LINENO: $ac_file is unchanged" >&5
echo "$as_me: $ac_file is unchanged" >&6;}
else
@@ -9936,25 +10436,30 @@ echo X"$ac_file" |
/^X\(\/\/\)$/{ s//\1/; q; }
/^X\(\/\).*/{ s//\1/; q; }
s/.*/./; q'`
- { case "$ac_dir" in
- [\\/]* | ?:[\\/]* ) as_incr_dir=;;
- *) as_incr_dir=.;;
-esac
-as_dummy="$ac_dir"
-for as_mkdir_dir in `IFS='/\\'; set X $as_dummy; shift; echo "$@"`; do
- case $as_mkdir_dir in
- # Skip DOS drivespec
- ?:) as_incr_dir=$as_mkdir_dir ;;
- *)
- as_incr_dir=$as_incr_dir/$as_mkdir_dir
- test -d "$as_incr_dir" ||
- mkdir "$as_incr_dir" ||
- { { echo "$as_me:$LINENO: error: cannot create \"$ac_dir\"" >&5
-echo "$as_me: error: cannot create \"$ac_dir\"" >&2;}
- { (exit 1); exit 1; }; }
- ;;
- esac
-done; }
+ { if $as_mkdir_p; then
+ mkdir -p "$ac_dir"
+ else
+ as_dir="$ac_dir"
+ as_dirs=
+ while test ! -d "$as_dir"; do
+ as_dirs="$as_dir $as_dirs"
+ as_dir=`(dirname "$as_dir") 2>/dev/null ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_dir" : 'X\(//\)[^/]' \| \
+ X"$as_dir" : 'X\(//\)$' \| \
+ X"$as_dir" : 'X\(/\)' \| \
+ . : '\(.\)' 2>/dev/null ||
+echo X"$as_dir" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+ /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+ /^X\(\/\/\)$/{ s//\1/; q; }
+ /^X\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`
+ done
+ test ! -n "$as_dirs" || mkdir $as_dirs
+ fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5
+echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;}
+ { (exit 1); exit 1; }; }; }
rm -f $ac_file
mv $tmp/config.h $ac_file
@@ -10019,7 +10524,7 @@ esac
# Don't blindly perform a `cd "$ac_dir"/$ac_foo && pwd` since $ac_foo can be
# absolute.
ac_abs_builddir=`cd "$ac_dir" && cd $ac_builddir && pwd`
-ac_abs_top_builddir=`cd "$ac_dir" && cd $ac_top_builddir && pwd`
+ac_abs_top_builddir=`cd "$ac_dir" && cd ${ac_top_builddir}. && pwd`
ac_abs_srcdir=`cd "$ac_dir" && cd $ac_srcdir && pwd`
ac_abs_top_srcdir=`cd "$ac_dir" && cd $ac_top_srcdir && pwd`
@@ -10088,25 +10593,30 @@ echo X"$file" |
/^X\(\/\/\)$/{ s//\1/; q; }
/^X\(\/\).*/{ s//\1/; q; }
s/.*/./; q'`
- { case $dirpart/$fdir in
- [\\/]* | ?:[\\/]* ) as_incr_dir=;;
- *) as_incr_dir=.;;
-esac
-as_dummy=$dirpart/$fdir
-for as_mkdir_dir in `IFS='/\\'; set X $as_dummy; shift; echo "$@"`; do
- case $as_mkdir_dir in
- # Skip DOS drivespec
- ?:) as_incr_dir=$as_mkdir_dir ;;
- *)
- as_incr_dir=$as_incr_dir/$as_mkdir_dir
- test -d "$as_incr_dir" ||
- mkdir "$as_incr_dir" ||
- { { echo "$as_me:$LINENO: error: cannot create $dirpart/$fdir" >&5
-echo "$as_me: error: cannot create $dirpart/$fdir" >&2;}
- { (exit 1); exit 1; }; }
- ;;
- esac
-done; }
+ { if $as_mkdir_p; then
+ mkdir -p $dirpart/$fdir
+ else
+ as_dir=$dirpart/$fdir
+ as_dirs=
+ while test ! -d "$as_dir"; do
+ as_dirs="$as_dir $as_dirs"
+ as_dir=`(dirname "$as_dir") 2>/dev/null ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_dir" : 'X\(//\)[^/]' \| \
+ X"$as_dir" : 'X\(//\)$' \| \
+ X"$as_dir" : 'X\(/\)' \| \
+ . : '\(.\)' 2>/dev/null ||
+echo X"$as_dir" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+ /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+ /^X\(\/\/\)$/{ s//\1/; q; }
+ /^X\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`
+ done
+ test ! -n "$as_dirs" || mkdir $as_dirs
+ fi || { { echo "$as_me:$LINENO: error: cannot create directory $dirpart/$fdir" >&5
+echo "$as_me: error: cannot create directory $dirpart/$fdir" >&2;}
+ { (exit 1); exit 1; }; }; }
# echo "creating $dirpart/$file"
echo '# dummy' > "$dirpart/$file"
@@ -10135,8 +10645,11 @@ ac_clean_files=$ac_clean_files_save
# need to make the FD available again.
if test "$no_create" != yes; then
ac_cs_success=:
+ ac_config_status_args=
+ test "$silent" = yes &&
+ ac_config_status_args="$ac_config_status_args --quiet"
exec 5>/dev/null
- $SHELL $CONFIG_STATUS || ac_cs_success=false
+ $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
exec 5>>config.log
# Use ||, not &&, to avoid exiting from the if with $? = 1, which
# would make configure fail if this is the last instruction.
diff --git a/ggsn/ggsn.c b/ggsn/ggsn.c
index 163e602..25da64c 100644
--- a/ggsn/ggsn.c
+++ b/ggsn/ggsn.c
@@ -109,12 +109,15 @@ int encaps_printf(void *p, void *packet, unsigned len)
int delete_context(struct pdp_t *pdp) {
if (debug) printf("Deleting PDP context\n");
- ippool_freeip(ippool, (struct ippoolm_t *) pdp->peer);
+ if (pdp->peer)
+ ippool_freeip(ippool, (struct ippoolm_t *) pdp->peer);
+ else
+ sys_err(LOG_ERR, __FILE__, __LINE__, 0, "Peer not defined!");
return 0;
}
-int create_context(struct pdp_t *pdp) {
+int create_context_ind(struct pdp_t *pdp) {
struct in_addr addr;
struct ippoolm_t *member;
@@ -126,12 +129,16 @@ int create_context(struct pdp_t *pdp) {
memcpy(pdp->qos_neg0, pdp->qos_req0, sizeof(pdp->qos_neg));
memcpy(&pdp->pco_neg, &pco, sizeof(pdp->pco_neg));
+ memcpy(pdp->qos_neg.v, pdp->qos_req.v, pdp->qos_req.l); /* TODO */
+ pdp->qos_neg.l = pdp->qos_req.l;
+
if (pdp_euaton(&pdp->eua, &addr)) {
addr.s_addr = 0; /* Request dynamic */
}
if (ippool_newip(ippool, &member, &addr)) {
- return EOF; /* Allready in use, or no more available */
+ gtp_create_context_resp(gsn, pdp, GTPCAUSE_NO_RESOURCES);
+ return 0; /* Allready in use, or no more available */
}
pdp_ntoeua(&member->addr, &pdp->eua);
@@ -139,6 +146,7 @@ int create_context(struct pdp_t *pdp) {
pdp->ipif = tun; /* TODO */
member->peer = pdp;
+ gtp_create_context_resp(gsn, pdp, GTPCAUSE_ACC_REQ);
return 0; /* Success */
}
@@ -157,7 +165,7 @@ int cb_tun_ind(struct tun_t *tun, void *pack, unsigned len) {
}
if (ipm->peer) /* Check if a peer protocol is defined */
- gtp_gpdu(gsn, (struct pdp_t*) ipm->peer, pack, len);
+ gtp_data_req(gsn, (struct pdp_t*) ipm->peer, pack, len);
return 0;
}
@@ -368,11 +376,13 @@ int main(int argc, char **argv)
"Failed to create gtp");
exit(1);
}
- if (gsn->fd > maxfd) maxfd = gsn->fd;
+ if (gsn->fd0 > maxfd) maxfd = gsn->fd0;
+ if (gsn->fd1c > maxfd) maxfd = gsn->fd1c;
+ if (gsn->fd1u > maxfd) maxfd = gsn->fd1u;
- gtp_set_cb_gpdu(gsn, encaps_tun);
+ gtp_set_cb_data_ind(gsn, encaps_tun);
gtp_set_cb_delete_context(gsn, delete_context);
- gtp_set_cb_create_context(gsn, create_context);
+ gtp_set_cb_create_context_ind(gsn, create_context_ind);
/* Create a tunnel interface */
@@ -396,7 +406,9 @@ int main(int argc, char **argv)
FD_ZERO(&fds);
if (tun) FD_SET(tun->fd, &fds);
- FD_SET(gsn->fd, &fds);
+ FD_SET(gsn->fd0, &fds);
+ FD_SET(gsn->fd1c, &fds);
+ FD_SET(gsn->fd1u, &fds);
gtp_retranstimeout(gsn, &idleTime);
switch (select(maxfd + 1, &fds, NULL, NULL, &idleTime)) {
@@ -417,9 +429,15 @@ int main(int argc, char **argv)
sys_err(LOG_ERR, __FILE__, __LINE__, 0,
"TUN read failed (fd)=(%d)", tun->fd);
}
-
- if (FD_ISSET(gsn->fd, &fds))
- gtp_decaps(gsn);
+
+ if (FD_ISSET(gsn->fd0, &fds))
+ gtp_decaps0(gsn);
+
+ if (FD_ISSET(gsn->fd1c, &fds))
+ gtp_decaps1c(gsn);
+
+ if (FD_ISSET(gsn->fd1u, &fds))
+ gtp_decaps1u(gsn);
}
diff --git a/gtp/gtp.c b/gtp/gtp.c
index 7d36dbb..27d8a03 100644
--- a/gtp/gtp.c
+++ b/gtp/gtp.c
@@ -122,171 +122,162 @@ int gtp_freepdp(struct gsn_t* gsn, struct pdp_t *pdp) {
return pdp_freepdp(pdp);
}
-int gtp_create_context(struct gsn_t *gsn, struct pdp_t *pdp, void *aid,
- struct in_addr* inetaddr) {
- int version = 0;
-
- return gtp_create_pdp_req(gsn, version, aid, inetaddr, pdp);
-}
-
-int gtp_create_context2(struct gsn_t *gsn, void *aid,
- struct in_addr* inetaddr,
- int selmode, uint64_t imsi, int nsapi,
- uint8_t *qos, int qoslen,
- char *apn, int apnlen,
- char *msisdn, int msisdnlen,
- uint8_t *pco, int pcolen) {
- int version = 0;
-
- struct pdp_t *pdp;
-
- if (qoslen > sizeof(pdp->qos_req0)) {
- gtp_err(LOG_ERR, __FILE__, __LINE__, 0, "QoS length too big");
- return -1;
- }
-
- if (apnlen > sizeof(pdp->apn_use.v)) {
- gtp_err(LOG_ERR, __FILE__, __LINE__, 0, "APN length too big");
- return -1;
- }
-
- if (msisdnlen > sizeof(pdp->msisdn.v)) {
- gtp_err(LOG_ERR, __FILE__, __LINE__, 0, "MSISDN length too big");
- return -1;
- }
-
- if (pcolen > sizeof(pdp->pco_req.v)) {
- gtp_err(LOG_ERR, __FILE__, __LINE__, 0, "PCO length too big");
- return -1;
- }
-
- /* New pdp allocated here:*/
- pdp_newpdp(&pdp, imsi, nsapi, NULL);
-
- pdp->peer = aid;
- pdp->ipif = NULL;
-
- pdp->selmode = selmode;
-
- memcpy(pdp->qos_req0, qos, qoslen); /* Length checked above */
- pdp->apn_use.l = apnlen;
- memcpy(pdp->apn_use.v, apn, apnlen); /* Length checked above */
-
- pdp->gsnlc.l = sizeof(gsn->gsnc);
- memcpy(pdp->gsnlc.v, &gsn->gsnc, sizeof(gsn->gsnc));
- pdp->gsnlu.l = sizeof(gsn->gsnc);
- memcpy(pdp->gsnlu.v, &gsn->gsnc, sizeof(gsn->gsnc));
-
- pdp->msisdn.l = msisdnlen;
- memcpy(pdp->msisdn.v, msisdn, msisdnlen);
-
- ipv42eua(&pdp->eua, NULL); /* Request dynamic IP address */
-
- pdp->pco_req.l = pcolen;
- memcpy(pdp->pco_req.v, pco, pcolen);
-
- return gtp_create_pdp_req(gsn, version, aid, inetaddr, pdp);
-}
-
-int gtp_update_context(struct gsn_t *gsn, struct pdp_t *pdp, void *aid,
- struct in_addr* inetaddr) {
- int version = 0;
-
- return gtp_update_pdp_req(gsn, version, aid, inetaddr, pdp);
-}
-
-int gtp_delete_context(struct gsn_t *gsn, struct pdp_t *pdp, void *aid) {
- int version = 0;
- return gtp_delete_pdp_req(gsn, version, aid, pdp);
-}
-
/* gtp_gpdu */
extern int gtp_fd(struct gsn_t *gsn) {
- return gsn->fd;
+ return gsn->fd0;
}
/* gtp_decaps */
/* gtp_retrans */
/* gtp_retranstimeout */
-int gtp_set_cb_delete_context(struct gsn_t *gsn,
- int (*cb_delete_context) (struct pdp_t* pdp))
-{
- gsn->cb_delete_context = cb_delete_context;
- return 0;
-}
-int gtp_set_cb_create_context(struct gsn_t *gsn,
- int (*cb_create_context) (struct pdp_t* pdp))
-{
- gsn->cb_create_context = cb_create_context;
+int gtp_set_cb_unsup_ind(struct gsn_t *gsn,
+ int (*cb) (struct sockaddr_in *peer)) {
+ gsn->cb_unsup_ind = cb;
return 0;
}
-/*
- int gtp_set_cb_create_pdp_conf(struct gsn_t *gsn,
- int (*cb) (struct pdp_t*, int))
- {
- gsn->cb_create_pdp_conf = cb;
+/* API: Initialise delete context callback */
+/* Called whenever a pdp context is deleted for any reason */
+int gtp_set_cb_delete_context(struct gsn_t *gsn,
+ int (*cb) (struct pdp_t* pdp))
+{
+ gsn->cb_delete_context = cb;
return 0;
- }
-
- int gtp_set_cb_update_pdp_conf(struct gsn_t *gsn,
- int (*cb) (struct pdp_t*, int, int))
- {
- gsn->cb_update_pdp_conf = cb;
- return 0;
-}
-
-in t gtp_set_cb_delete_pdp_conf(struct gsn_t *gsn,
-int (*cb) (struct pdp_t*, int))
- {
-gsn->cb_delete_pdp_conf = cb;
-return 0;
}
-*/
-
int gtp_set_cb_conf(struct gsn_t *gsn,
int (*cb) (int type, int cause,
- struct pdp_t* pdp, void *aid)) {
+ struct pdp_t* pdp, void *cbp)) {
gsn->cb_conf = cb;
return 0;
}
-extern int gtp_set_cb_gpdu(struct gsn_t *gsn,
- int (*cb_gpdu) (struct pdp_t* pdp,
+extern int gtp_set_cb_data_ind(struct gsn_t *gsn,
+ int (*cb_data_ind) (struct pdp_t* pdp,
void* pack,
unsigned len))
{
- gsn->cb_gpdu = cb_gpdu;
+ gsn->cb_data_ind = cb_data_ind;
return 0;
}
-
-void get_default_gtp(int version, void *packet) {
+/**
+ * get_default_gtp()
+ * Generate a GPRS Tunneling Protocol signalling packet header, depending
+ * on GTP version and message type. pdp is used for teid/flow label.
+ * *packet must be allocated by the calling function, and be large enough
+ * to hold the packet header.
+ * returns the length of the header. 0 on error.
+ **/
+static int get_default_gtp(int version, u_int8_t type, void *packet) {
struct gtp0_header *gtp0_default = (struct gtp0_header*) packet;
struct gtp1_header_long *gtp1_default = (struct gtp1_header_long*) packet;
switch (version) {
case 0:
/* Initialise "standard" GTP0 header */
- memset(gtp0_default, 0, sizeof(gtp0_default));
+ memset(gtp0_default, 0, sizeof(struct gtp0_header));
gtp0_default->flags=0x1e;
+ gtp0_default->type=hton8(type);
gtp0_default->spare1=0xff;
gtp0_default->spare2=0xff;
gtp0_default->spare3=0xff;
gtp0_default->number=0xff;
- break;
+ return GTP0_HEADER_SIZE;
case 1:
/* Initialise "standard" GTP1 header */
- memset(gtp1_default, 0, sizeof(gtp1_default));
- gtp0_default->flags=0x1e;
- break;
+ /* 29.060: 8.2: S=1 and PN=0 */
+ /* 29.060 9.3.1: For GTP-U messages Echo Request, Echo Response */
+ /* and Supported Extension Headers Notification, the S field shall be */
+ /* set to 1 */
+ /* Currently extension headers are not supported */
+ memset(gtp1_default, 0, sizeof(struct gtp1_header_long));
+ gtp1_default->flags=0x32; /* No extension, enable sequence, no N-PDU */
+ gtp1_default->type=hton8(type);
+ return GTP1_HEADER_SIZE_LONG;
+ default:
+ gtp_err(LOG_ERR, __FILE__, __LINE__, "Unknown GTP packet version");
+ return 0;
+ }
+}
+
+/**
+ * get_seq()
+ * Get sequence number of a packet.
+ * Returns 0 on error
+ **/
+static uint16_t get_seq(void *pack) {
+ union gtp_packet *packet = (union gtp_packet *) pack;
+
+ if ((packet->flags & 0xe0) == 0x00) { /* Version 0 */
+ return ntoh16(packet->gtp0.h.seq);
+ }
+ else if ((packet->flags & 0xe2) == 0x22) { /* Version 1 with seq */
+ return ntoh16(packet->gtp1l.h.seq);
+ } else {
+ gtp_err(LOG_ERR, __FILE__, __LINE__, "Unknown packet flag");
+ return 0;
+ }
+}
+
+/**
+ * get_tid()
+ * Get tunnel identifier of a packet.
+ * Returns 0 on error
+ **/
+static uint64_t get_tid(void *pack) {
+ union gtp_packet *packet = (union gtp_packet *) pack;
+
+ if ((packet->flags & 0xe0) == 0x00) { /* Version 0 */
+ return packet->gtp0.h.tid;
+ }
+ return 0;
+}
+
+/**
+ * get_hlen()
+ * Get the header length of a packet.
+ * Returns 0 on error
+ **/
+static uint16_t get_hlen(void *pack) {
+ union gtp_packet *packet = (union gtp_packet *) pack;
+
+ if ((packet->flags & 0xe0) == 0x00) { /* Version 0 */
+ return GTP0_HEADER_SIZE;
+ }
+ else if ((packet->flags & 0xe2) == 0x22) { /* Version 1 with seq */
+ return GTP1_HEADER_SIZE_LONG;
+ }
+ else if ((packet->flags & 0xe7) == 0x20) { /* Short version 1 */
+ return GTP1_HEADER_SIZE_SHORT;
+ } else {
+ gtp_err(LOG_ERR, __FILE__, __LINE__, "Unknown packet flag");
+ return 0;
}
}
+/**
+ * get_tei()
+ * Get the tunnel endpoint identifier (flow label) of a packet.
+ * Returns 0xffffffff on error.
+ **/
+static uint32_t get_tei(void *pack) {
+ union gtp_packet *packet = (union gtp_packet *) pack;
+
+ if ((packet->flags & 0xe0) == 0x00) { /* Version 0 */
+ return ntoh16(packet->gtp0.h.flow);
+ }
+ else if ((packet->flags & 0xe0) == 0x20) { /* Version 1 */
+ return ntoh32(packet->gtp1l.h.tei);
+ }
+ else {
+ gtp_err(LOG_ERR, __FILE__, __LINE__, "Unknown packet flag");
+ return 0xffffffff;
+ }
+}
int print_packet(void *packet, unsigned len)
@@ -362,8 +353,8 @@ char* snprint_packet(struct gsn_t *gsn, struct sockaddr_in *peer,
* Create pdp context: The SGSN may send create context request even if
* a context allready exist (imsi+nsapi?). This means that the reply will
automatically dublicate the original response. It might however have
- * sideeffects in the application which is asked twice to allocate
- * validate the login.
+ * side effects in the application which is asked twice to validate
+ * the login.
* Update pdp context: Automatically dublicates the original response???
* Delete pdp context. Automatically in gtp0, but in gtp1 will generate
* a nonexist reply message.
@@ -390,28 +381,57 @@ char* snprint_packet(struct gsn_t *gsn, struct sockaddr_in *peer,
* gtp_conf:
* Remove an incoming confirmation from the queue
* gtp_resp:
- * Send off a responce to a request. Use the same sequence
+ * Send off a response to a request. Use the same sequence
* number in the response as in the request.
* gtp_retrans:
* Retransmit any outstanding packets which have exceeded
* a predefined timeout.
*************************************************************/
-int gtp_req(struct gsn_t *gsn, int version, union gtp_packet *packet,
- int len, struct in_addr *inetaddr, void *aid) {
+int gtp_req(struct gsn_t *gsn, int version, struct pdp_t *pdp,
+ union gtp_packet *packet, int len,
+ struct in_addr *inetaddr, void *cbp) {
struct sockaddr_in addr;
struct qmsg_t *qmsg;
+ int fd;
+
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_addr = *inetaddr;
- addr.sin_port = htons(GTP0_PORT);
- packet->gtp0.h.seq = hton16(gsn->seq_next);
+ if ((packet->flags & 0xe0) == 0x00) { /* Version 0 */
+ addr.sin_port = htons(GTP0_PORT);
+ packet->gtp0.h.length = hton16(len - GTP0_HEADER_SIZE);
+ packet->gtp0.h.seq = hton16(gsn->seq_next);
+ if (pdp)
+ packet->gtp0.h.tid = (pdp->imsi & 0x0fffffffffffffff) +
+ ((uint64_t)pdp->nsapi << 60);
+ if (pdp && ((packet->gtp0.h.type == GTP_GPDU) ||
+ (packet->gtp0.h.type == GTP_ERROR)))
+ packet->gtp0.h.flow=hton16(pdp->flru);
+ else if (pdp)
+ packet->gtp0.h.flow=hton16(pdp->flrc);
+ fd = gsn->fd0;
+ }
+ else if ((packet->flags & 0xe2) == 0x22) { /* Version 1 with seq */
+ addr.sin_port = htons(GTP1C_PORT);
+ packet->gtp1l.h.length = hton16(len - GTP1_HEADER_SIZE_SHORT);
+ packet->gtp1l.h.seq = hton16(gsn->seq_next);
+ if (pdp && ((packet->gtp1l.h.type == GTP_GPDU) ||
+ (packet->gtp1l.h.type == GTP_ERROR)))
+ packet->gtp1l.h.tei=hton32(pdp->teid_gn);
+ else if (pdp)
+ packet->gtp1l.h.tei=hton32(pdp->teic_gn);
+ fd = gsn->fd1c;
+ } else {
+ gtp_err(LOG_ERR, __FILE__, __LINE__, "Unknown packet flag");
+ return -1;
+ }
- if (sendto(gsn->fd, packet, len, 0,
+ if (sendto(fd, packet, len, 0,
(struct sockaddr *) &addr, sizeof(addr)) < 0) {
gsn->err_sendto++;
- gtp_err(LOG_ERR, __FILE__, __LINE__, "Sendto(fd=%d, msg=%lx, len=%d) failed: Error = %s", gsn->fd, (unsigned long) &packet, len, strerror(errno));
+ gtp_err(LOG_ERR, __FILE__, __LINE__, "Sendto(fd=%d, msg=%lx, len=%d) failed: Error = %s", fd, (unsigned long) &packet, len, strerror(errno));
return -1;
}
@@ -425,8 +445,9 @@ int gtp_req(struct gsn_t *gsn, int version, union gtp_packet *packet,
qmsg->l = len;
qmsg->timeout = time(NULL) + 3; /* When to timeout */
qmsg->retrans = 0; /* No retransmissions so far */
- qmsg->aid = aid;
+ qmsg->cbp = cbp;
qmsg->type = ntoh8(packet->gtp0.h.type);
+ qmsg->fd = fd;
}
gsn->seq_next++; /* Count up this time */
return 0;
@@ -437,10 +458,21 @@ int gtp_req(struct gsn_t *gsn, int version, union gtp_packet *packet,
* return 0 on success, EOF if packet was not found */
int gtp_conf(struct gsn_t *gsn, int version, struct sockaddr_in *peer,
- union gtp_packet *packet, int len, uint8_t *type, void **aid) {
- int seq = ntoh16(packet->gtp0.h.seq);
+ union gtp_packet *packet, int len, uint8_t *type, void **cbp) {
+
+ uint16_t seq;
+
+ if ((packet->gtp0.h.flags & 0xe0) == 0x00)
+ seq = ntoh16(packet->gtp0.h.seq);
+ else if ((packet->gtp1l.h.flags & 0xe2) == 0x22)
+ seq = ntoh16(packet->gtp1l.h.seq);
+ else {
+ gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, packet, len,
+ "Unknown GTP packet version");
+ return EOF;
+ }
- if (queue_freemsg_seq(gsn->queue_req, peer, seq, type, aid)) {
+ if (queue_freemsg_seq(gsn->queue_req, peer, seq, type, cbp)) {
gsn->err_seq++;
gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, packet, len,
"Confirmation packet not found in queue");
@@ -462,14 +494,14 @@ int gtp_retrans(struct gsn_t *gsn) {
(qmsg->timeout <= now)) {
/*printf("Retrans timeout found: %d\n", (int) time(NULL));*/
if (qmsg->retrans > 3) { /* To many retrans */
- if (gsn->cb_conf) gsn->cb_conf(qmsg->type, EOF, NULL, qmsg->aid);
+ if (gsn->cb_conf) gsn->cb_conf(qmsg->type, EOF, NULL, qmsg->cbp);
queue_freemsg(gsn->queue_req, qmsg);
}
else {
- if (sendto(gsn->fd, &qmsg->p, qmsg->l, 0,
+ if (sendto(qmsg->fd, &qmsg->p, qmsg->l, 0,
(struct sockaddr *) &qmsg->peer, sizeof(struct sockaddr_in)) < 0) {
gsn->err_sendto++;
- gtp_err(LOG_ERR, __FILE__, __LINE__, "Sendto(fd=%d, msg=%lx, len=%d) failed: Error = %s", gsn->fd, (unsigned long) &qmsg->p, qmsg->l, strerror(errno));
+ gtp_err(LOG_ERR, __FILE__, __LINE__, "Sendto(fd0=%d, msg=%lx, len=%d) failed: Error = %s", gsn->fd0, (unsigned long) &qmsg->p, qmsg->l, strerror(errno));
}
queue_back(gsn->queue_req, qmsg);
qmsg->timeout = now + 3;
@@ -506,30 +538,44 @@ int gtp_retranstimeout(struct gsn_t *gsn, struct timeval *timeout) {
return 0;
}
-int gtp_resp(int version, struct gsn_t *gsn, union gtp_packet *packet,
- int len, struct sockaddr_in *peer) {
+int gtp_resp(int version, struct gsn_t *gsn, struct pdp_t *pdp,
+ union gtp_packet *packet, int len,
+ struct sockaddr_in *peer, int fd,
+ uint16_t seq, uint64_t tid) {
struct qmsg_t *qmsg;
- uint16_t seq;
- seq = ntoh16(packet->gtp0.h.seq);
+ if ((packet->flags & 0xe0) == 0x00) { /* Version 0 */
+ packet->gtp0.h.length = hton16(len - GTP0_HEADER_SIZE);
+ packet->gtp0.h.seq = hton16(seq);
+ packet->gtp0.h.tid = tid;
+ if (pdp && ((packet->gtp0.h.type == GTP_GPDU) ||
+ (packet->gtp0.h.type == GTP_ERROR)))
+ packet->gtp0.h.flow=hton16(pdp->flru);
+ else if (pdp)
+ packet->gtp0.h.flow=hton16(pdp->flrc);
+ }
+ else if ((packet->flags & 0xe2) == 0x22) { /* Version 1 with seq */
+ packet->gtp1l.h.length = hton16(len - GTP1_HEADER_SIZE_SHORT);
+ packet->gtp1l.h.seq = hton16(seq);
+ if (pdp && (fd == gsn->fd1u))
+ packet->gtp1l.h.tei=hton32(pdp->teid_gn);
+ else if (pdp)
+ packet->gtp1l.h.tei=hton32(pdp->teic_gn);
+ }
+ else {
+ gtp_err(LOG_ERR, __FILE__, __LINE__, "Unknown packet flag");
+ return -1;
+ }
- /* print message */
- /*
- printf("gtp_resp: to %s:UDP%u\n",
- inet_ntoa(peer->sin_addr),
- ntohs(peer->sin_port));
- print_packet(packet, len);
- */
-
- if (fcntl(gsn->fd, F_SETFL, 0)) {
+ if (fcntl(fd, F_SETFL, 0)) {
gtp_err(LOG_ERR, __FILE__, __LINE__, "fnctl()");
return -1;
}
-
- if (sendto(gsn->fd, packet, len, 0,
+
+ if (sendto(fd, packet, len, 0,
(struct sockaddr *) peer, sizeof(struct sockaddr_in)) < 0) {
gsn->err_sendto++;
- gtp_err(LOG_ERR, __FILE__, __LINE__, "Sendto(fd=%d, msg=%lx, len=%d) failed: Error = %s", gsn->fd, (unsigned long) &packet, len, strerror(errno));
+ gtp_err(LOG_ERR, __FILE__, __LINE__, "Sendto(fd=%d, msg=%lx, len=%d) failed: Error = %s", fd, (unsigned long) &packet, len, strerror(errno));
return -1;
}
@@ -543,8 +589,9 @@ int gtp_resp(int version, struct gsn_t *gsn, union gtp_packet *packet,
qmsg->l = len;
qmsg->timeout = time(NULL) + 60; /* When to timeout */
qmsg->retrans = 0; /* No retransmissions so far */
- qmsg->aid = NULL;
+ qmsg->cbp = NULL;
qmsg->type = 0;
+ qmsg->fd = fd;
}
return 0;
}
@@ -556,27 +603,18 @@ int gtp_dublicate(struct gsn_t *gsn, int version,
if(queue_seqget(gsn->queue_resp, &qmsg, peer, seq)) {
return EOF; /* Notfound */
}
- else {
- /* print message */
-
- /*printf("gtp_dublicate: to %s:UDP%u\n",
- inet_ntoa(peer->sin_addr),
- ntohs(peer->sin_port));
- print_packet(&qmsg->p, qmsg->l);
- */
-
- if (fcntl(gsn->fd, F_SETFL, 0)) {
- gtp_err(LOG_ERR, __FILE__, __LINE__, "fnctl()");
- return -1;
- }
- if (sendto(gsn->fd, &qmsg->p, qmsg->l, 0,
- (struct sockaddr *) peer, sizeof(struct sockaddr_in)) < 0) {
- gsn->err_sendto++;
- gtp_err(LOG_ERR, __FILE__, __LINE__, "Sendto(fd=%d, msg=%lx, len=%d) failed: Error = %s", gsn->fd, (unsigned long) &qmsg->p, qmsg->l, strerror(errno));
- }
- return 0;
+ if (fcntl(qmsg->fd, F_SETFL, 0)) {
+ gtp_err(LOG_ERR, __FILE__, __LINE__, "fnctl()");
+ return -1;
+ }
+
+ if (sendto(qmsg->fd, &qmsg->p, qmsg->l, 0,
+ (struct sockaddr *) peer, sizeof(struct sockaddr_in)) < 0) {
+ gsn->err_sendto++;
+ gtp_err(LOG_ERR, __FILE__, __LINE__, "Sendto(fd=%d, msg=%lx, len=%d) failed: Error = %s", qmsg->fd, (unsigned long) &qmsg->p, qmsg->l, strerror(errno));
}
+ return 0;
}
@@ -629,7 +667,6 @@ int gtp_new(struct gsn_t **gsn, char *statedir, struct in_addr *listen,
int mode)
{
struct sockaddr_in addr;
- int gtp_fd;
syslog(LOG_ERR, "GTP: gtp_newgsn() started");
@@ -649,33 +686,69 @@ int gtp_new(struct gsn_t **gsn, char *statedir, struct in_addr *listen,
pdp_init();
/* Initialise call back functions */
- (*gsn)->cb_create_context = 0;
+ (*gsn)->cb_create_context_ind = 0;
(*gsn)->cb_delete_context = 0;
+ (*gsn)->cb_unsup_ind = 0;
(*gsn)->cb_conf = 0;
- (*gsn)->cb_gpdu = 0;
+ (*gsn)->cb_data_ind = 0;
+
+ /* Store function parameters */
+ (*gsn)->gsnc = *listen;
+ (*gsn)->gsnu = *listen;
+ (*gsn)->mode = mode;
- if ((gtp_fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0 ) {
+
+ /* Create GTP version 0 socket */
+ if (((*gsn)->fd0 = socket(AF_INET, SOCK_DGRAM, 0)) < 0 ) {
(*gsn)->err_socket++;
gtp_err(LOG_ERR, __FILE__, __LINE__, "socket(domain=%d, type=%d, protocol=%d) failed: Error = %s", AF_INET, SOCK_DGRAM, 0, strerror(errno));
return -1;
}
- (*gsn)->fd = gtp_fd;
+
+ memset(&addr, 0, sizeof(addr));
+ addr.sin_family = AF_INET;
+ addr.sin_addr = *listen; /* Same IP for user traffic and signalling*/
+ addr.sin_port = htons(GTP0_PORT);
+
+ if (bind((*gsn)->fd0, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
+ (*gsn)->err_socket++;
+ gtp_err(LOG_ERR, __FILE__, __LINE__, "bind(fd0=%d, addr=%lx, len=%d) failed: Error = %s", (*gsn)->fd0, (unsigned long) &addr, sizeof(addr), strerror(errno));
+ return -1;
+ }
- (*gsn)->gsnc = *listen;
- (*gsn)->gsnu = *listen;
+ /* Create GTP version 1 control plane socket */
+ if (((*gsn)->fd1c = socket(AF_INET, SOCK_DGRAM, 0)) < 0 ) {
+ (*gsn)->err_socket++;
+ gtp_err(LOG_ERR, __FILE__, __LINE__, "socket(domain=%d, type=%d, protocol=%d) failed: Error = %s", AF_INET, SOCK_DGRAM, 0, strerror(errno));
+ return -1;
+ }
- (*gsn)->mode = mode;
-
memset(&addr, 0, sizeof(addr));
+ addr.sin_family = AF_INET;
+ addr.sin_addr = *listen; /* Same IP for user traffic and signalling*/
+ addr.sin_port = htons(GTP1C_PORT);
+ if (bind((*gsn)->fd1c, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
+ (*gsn)->err_socket++;
+ gtp_err(LOG_ERR, __FILE__, __LINE__, "bind(fd1c=%d, addr=%lx, len=%d) failed: Error = %s", (*gsn)->fd1c, (unsigned long) &addr, sizeof(addr), strerror(errno));
+ return -1;
+ }
+
+ /* Create GTP version 1 user plane socket */
+ if (((*gsn)->fd1u = socket(AF_INET, SOCK_DGRAM, 0)) < 0 ) {
+ (*gsn)->err_socket++;
+ gtp_err(LOG_ERR, __FILE__, __LINE__, "socket(domain=%d, type=%d, protocol=%d) failed: Error = %s", AF_INET, SOCK_DGRAM, 0, strerror(errno));
+ return -1;
+ }
+
+ memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
- /* addr.sin_addr = *inetaddr; */
addr.sin_addr = *listen; /* Same IP for user traffic and signalling*/
- addr.sin_port = htons(GTP0_PORT);
+ addr.sin_port = htons(GTP1U_PORT);
- if (bind(gtp_fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
+ if (bind((*gsn)->fd1u, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
(*gsn)->err_socket++;
- gtp_err(LOG_ERR, __FILE__, __LINE__, "bind(fd=%d, addr=%lx, len=%d) failed: Error = %s", gtp_fd, (unsigned long) &addr, sizeof(addr), strerror(errno));
+ gtp_err(LOG_ERR, __FILE__, __LINE__, "bind(fd1c=%d, addr=%lx, len=%d) failed: Error = %s", (*gsn)->fd1c, (unsigned long) &addr, sizeof(addr), strerror(errno));
return -1;
}
@@ -687,6 +760,10 @@ int gtp_free(struct gsn_t *gsn) {
/* Clean up retransmit queues */
queue_free(gsn->queue_req);
queue_free(gsn->queue_resp);
+
+ close(gsn->fd0);
+ close(gsn->fd1c);
+ close(gsn->fd1u);
free(gsn);
return 0;
@@ -722,67 +799,56 @@ int gtp_free(struct gsn_t *gsn) {
*************************************************************/
/* Send off an echo request */
-int gtp_echo_req(struct gsn_t *gsn, struct in_addr *inetaddr)
+int gtp_echo_req(struct gsn_t *gsn, int version, void *cbp,
+ struct in_addr *inetaddr)
{
union gtp_packet packet;
-
- get_default_gtp(0, &packet);
- packet.gtp0.h.type = hton8(GTP_ECHO_REQ);
- packet.gtp0.h.length = hton16(0);
-
- return gtp_req(gsn, 0, &packet, GTP0_HEADER_SIZE, inetaddr, NULL);
+ int length = get_default_gtp(version, GTP_ECHO_REQ, &packet);
+ return gtp_req(gsn, version, NULL, &packet, length, inetaddr, cbp);
}
-/* Send of an echo reply */
-int gtp_echo_resp(struct gsn_t *gsn, struct sockaddr_in *peer,
+/* Send off an echo reply */
+int gtp_echo_resp(struct gsn_t *gsn, int version,
+ struct sockaddr_in *peer, int fd,
void *pack, unsigned len)
{
union gtp_packet packet;
- int length = 0;
-
- get_default_gtp(0, &packet);
-
- gtpie_tv1(packet.gtp0.p, &length, GTP_MAX, GTPIE_RECOVERY,
- gsn->restart_counter);
-
- packet.gtp0.h.type = hton8(GTP_ECHO_RSP);
- packet.gtp0.h.length = hton16(length);
- packet.gtp0.h.seq = ((union gtp_packet*)pack)->gtp0.h.seq;
-
- return gtp_resp(0, gsn, &packet, GTP0_HEADER_SIZE+length, peer);
+ int length = get_default_gtp(version, GTP_ECHO_RSP, &packet);
+ gtpie_tv1(&packet, &length, GTP_MAX, GTPIE_RECOVERY, gsn->restart_counter);
+ return gtp_resp(version, gsn, NULL, &packet, length, peer, fd,
+ get_seq(pack), get_tid(pack));
}
/* Handle a received echo request */
-int gtp_echo_ind(struct gsn_t *gsn, struct sockaddr_in *peer,
- void *pack, unsigned len) {
+int gtp_echo_ind(struct gsn_t *gsn, int version, struct sockaddr_in *peer,
+ int fd, void *pack, unsigned len) {
- uint16_t seq = ntoh16(((union gtp_packet*)pack)->gtp0.h.seq);
+ /* Check if it was a dublicate request */
+ if(!gtp_dublicate(gsn, 0, peer, get_seq(pack))) return 0;
- if(!gtp_dublicate(gsn, 0, peer, seq)) {
- return 0; /* We allready send of response once */
- }
-
-
- /* Now send off a reply to the peer */
- return gtp_echo_resp(gsn, peer, pack, len);
+ /* Send off reply to request */
+ return gtp_echo_resp(gsn, version, peer, fd, pack, len);
}
/* Handle a received echo reply */
-int gtp_echo_conf(struct gsn_t *gsn, struct sockaddr_in *peer,
+int gtp_echo_conf(struct gsn_t *gsn, int version, struct sockaddr_in *peer,
void *pack, unsigned len) {
union gtpie_member *ie[GTPIE_SIZE];
unsigned char recovery;
- void *aid = NULL;
+ void *cbp = NULL;
uint8_t type = 0;
+ int hlen = get_hlen(pack);
/* Remove packet from queue */
- if (gtp_conf(gsn, 0, peer, pack, len, &type, &aid)) return EOF;
+ if (gtp_conf(gsn, version, peer, pack, len, &type, &cbp)) return EOF;
- if (gtpie_decaps(ie, pack+sizeof(struct gtp0_header), len-sizeof(struct gtp0_header))) {
+ /* Extract information elements into a pointer array */
+ if (gtpie_decaps(ie, version, pack+hlen, len-hlen)) {
gsn->invalid++;
gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
"Invalid message format");
+ if (gsn->cb_conf) gsn->cb_conf(type, EOF, NULL, cbp);
return EOF;
}
@@ -790,10 +856,13 @@ int gtp_echo_conf(struct gsn_t *gsn, struct sockaddr_in *peer,
gsn->missing++;
gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
"Missing mandatory field");
+ if (gsn->cb_conf) gsn->cb_conf(type, EOF, NULL, cbp);
return EOF;
}
- if (gsn->cb_conf) gsn->cb_conf(type, 0, NULL, aid); /* TODO: Should return recovery in callback */
+ /* Echo reply packages does not have a cause information element */
+ /* Instead we return the recovery number in the callback function */
+ if (gsn->cb_conf) gsn->cb_conf(type, recovery, NULL, cbp);
return 0;
}
@@ -809,34 +878,22 @@ int gtp_echo_conf(struct gsn_t *gsn, struct sockaddr_in *peer,
* only listen to the GTP0 port, and therefore will never receive
* anything else than GTP0 */
-int gtp_unsup_resp(struct gsn_t *gsn, struct sockaddr_in *peer,
- void *pack, unsigned len)
+int gtp_unsup_req(struct gsn_t *gsn, int version, struct sockaddr_in *peer,
+ int fd, void *pack, unsigned len)
{
union gtp_packet packet;
- int length = 0;
- get_default_gtp(0, &packet);
- packet.gtp0.h.type = hton8(GTP_NOT_SUPPORTED);
- packet.gtp0.h.length = hton16(0);
-
- return gtp_resp(0, gsn, &packet, GTP0_HEADER_SIZE+length, peer);
+ /* GTP 1 is the highest supported protocol */
+ int hlen = get_default_gtp(1, GTP_NOT_SUPPORTED, &packet);
+ return gtp_resp(version, gsn, NULL, &packet, hlen, peer, fd, 0, 0);
}
/* Handle a Version Not Supported message */
-int gtp_unsup_conf(struct gsn_t *gsn, struct sockaddr_in *peer, void *pack, unsigned len) {
+int gtp_unsup_ind(struct gsn_t *gsn, struct sockaddr_in *peer,
+ void *pack, unsigned len) {
- /* TODO: Need to check the validity of header and information elements */
- /* TODO: Implement callback to application */
- /* As long as we only support GTP0 we should never receive this message */
- /* Should be implemented as part of GTP1 support */
+ if (gsn->cb_unsup_ind) gsn->cb_unsup_ind(peer);
- /* print received message */
- /*
- printf("gtp_unsup_ind: from %s:UDP%u\n",
- inet_ntoa(peer->sin_addr),
- ntohs(peer->sin_port));
- print_packet(pack, len);
- */
return 0;
}
@@ -852,284 +909,404 @@ int gtp_unsup_conf(struct gsn_t *gsn, struct sockaddr_in *peer, void *pack, unsi
* information.
*************************************************************/
-/* Send Create PDP Context Request */
-extern int gtp_create_pdp_req(struct gsn_t *gsn, int version, void *aid,
- struct in_addr* inetaddr, struct pdp_t *pdp) {
+/* API: Send Create PDP Context Request */
+extern int gtp_create_context_req(struct gsn_t *gsn, struct pdp_t *pdp,
+ void *cbp, struct in_addr* inetaddr) {
union gtp_packet packet;
- int length = 0;
+ int length = get_default_gtp(pdp->version, GTP_CREATE_PDP_REQ, &packet);
- get_default_gtp(0, &packet);
-
- if (0==0) { /* Always GTP0 */
-
- gtpie_tv0(packet.gtp0.p, &length, GTP_MAX, GTPIE_QOS_PROFILE0,
+ if (pdp->version == 0)
+ gtpie_tv0(&packet, &length, GTP_MAX, GTPIE_QOS_PROFILE0,
sizeof(pdp->qos_req0), pdp->qos_req0);
- gtpie_tv1(packet.gtp0.p, &length, GTP_MAX, GTPIE_RECOVERY,
- gsn->restart_counter);
- gtpie_tv1(packet.gtp0.p, &length, GTP_MAX, GTPIE_SELECTION_MODE,
- pdp->selmode);
- gtpie_tv2(packet.gtp0.p, &length, GTP_MAX, GTPIE_FL_DI,
- pdp->fllu);
- gtpie_tv2(packet.gtp0.p, &length, GTP_MAX, GTPIE_FL_C,
- pdp->fllc);
- gtpie_tlv(packet.gtp0.p, &length, GTP_MAX, GTPIE_EUA,
- pdp->eua.l, pdp->eua.v);
- gtpie_tlv(packet.gtp0.p, &length, GTP_MAX, GTPIE_APN,
- pdp->apn_use.l, pdp->apn_use.v);
- if (pdp->pco_req.l) { /* Optional PCO */
- gtpie_tlv(packet.gtp0.p, &length, GTP_MAX, GTPIE_PCO,
- pdp->pco_req.l, pdp->pco_req.v);
- }
+ if (pdp->version == 1)
+ gtpie_tv0(&packet, &length, GTP_MAX, GTPIE_IMSI,
+ sizeof(pdp->imsi), (uint8_t*) &pdp->imsi);
- gtpie_tlv(packet.gtp0.p, &length, GTP_MAX, GTPIE_GSN_ADDR,
- pdp->gsnlc.l, pdp->gsnlc.v);
- gtpie_tlv(packet.gtp0.p, &length, GTP_MAX, GTPIE_GSN_ADDR,
- pdp->gsnlu.l, pdp->gsnlu.v);
- gtpie_tlv(packet.gtp0.p, &length, GTP_MAX, GTPIE_MSISDN,
- pdp->msisdn.l, pdp->msisdn.v);
-
+ gtpie_tv1(&packet, &length, GTP_MAX, GTPIE_RECOVERY,
+ gsn->restart_counter);
+ gtpie_tv1(&packet, &length, GTP_MAX, GTPIE_SELECTION_MODE,
+ pdp->selmode);
+ if (pdp->version == 0) {
+ gtpie_tv2(&packet, &length, GTP_MAX, GTPIE_FL_DI,
+ pdp->fllu);
+ gtpie_tv2(&packet, &length, GTP_MAX, GTPIE_FL_C,
+ pdp->fllc);
+ }
- } else { /* GTP1 */
- gtpie_tv0(packet.gtp1s.p, &length, GTP_MAX, GTPIE_IMSI,
- sizeof(pdp->imsi), (uint8_t*) &pdp->imsi);
- gtpie_tv1(packet.gtp1s.p, &length, GTP_MAX, GTPIE_RECOVERY,
- gsn->restart_counter);
- gtpie_tv1(packet.gtp1s.p, &length, GTP_MAX, GTPIE_SELECTION_MODE,
- pdp->selmode);
- gtpie_tv4(packet.gtp1s.p, &length, GTP_MAX, GTPIE_TEI_DI,
+ if (pdp->version == 1) {
+ gtpie_tv4(&packet, &length, GTP_MAX, GTPIE_TEI_DI,
pdp->teid_own);
- gtpie_tv4(packet.gtp1s.p, &length, GTP_MAX, GTPIE_TEI_C,
+ gtpie_tv4(&packet, &length, GTP_MAX, GTPIE_TEI_C,
pdp->teic_own);
- gtpie_tv1(packet.gtp1s.p, &length, GTP_MAX, GTPIE_NSAPI,
- pdp->nsapi);
- /*gtpie_tv1(packet.gtp1s.p, &length, GTP_MAX, GTPIE_NSAPI,
- pdp->nsapil); For use by several QoS profiles for the same address */
- gtpie_tv2(packet.gtp1s.p, &length, GTP_MAX, GTPIE_CHARGING_C,
+ }
+
+ gtpie_tv1(&packet, &length, GTP_MAX, GTPIE_NSAPI,
+ pdp->nsapi);
+
+ /*gtpie_tv1(packet.gtp1l.p, &length, GTP_MAX, GTPIE_NSAPI,
+ pdp->nsapil); For use by several QoS profiles for the same address */
+
+ if (pdp->version == 1) {
+ gtpie_tv2(&packet, &length, GTP_MAX, GTPIE_CHARGING_C,
pdp->cch_pdp);
- gtpie_tv2(packet.gtp1s.p, &length, GTP_MAX, GTPIE_TRACE_REF,
- pdp->traceref);
- gtpie_tv2(packet.gtp1s.p, &length, GTP_MAX, GTPIE_TRACE_TYPE,
- pdp->tracetype);
- gtpie_tlv(packet.gtp1s.p, &length, GTP_MAX, GTPIE_EUA,
- pdp->eua.l, pdp->eua.v);
- gtpie_tlv(packet.gtp1s.p, &length, GTP_MAX, GTPIE_APN,
- pdp->apn_use.l, pdp->apn_use.v);
- gtpie_tlv(packet.gtp1s.p, &length, GTP_MAX, GTPIE_PCO,
+ }
+
+ /* TODO
+ gtpie_tv2(&packet, &length, GTP_MAX, GTPIE_TRACE_REF,
+ pdp->traceref);
+ gtpie_tv2(&packet, &length, GTP_MAX, GTPIE_TRACE_TYPE,
+ pdp->tracetype); */
+
+ gtpie_tlv(&packet, &length, GTP_MAX, GTPIE_EUA,
+ pdp->eua.l, pdp->eua.v);
+ gtpie_tlv(&packet, &length, GTP_MAX, GTPIE_APN,
+ pdp->apn_use.l, pdp->apn_use.v);
+
+ if (pdp->pco_req.l)
+ gtpie_tlv(&packet, &length, GTP_MAX, GTPIE_PCO,
pdp->pco_req.l, pdp->pco_req.v);
- gtpie_tlv(packet.gtp1s.p, &length, GTP_MAX, GTPIE_GSN_ADDR,
- pdp->gsnlc.l, pdp->gsnlc.v);
- gtpie_tlv(packet.gtp1s.p, &length, GTP_MAX, GTPIE_GSN_ADDR,
- pdp->gsnlu.l, pdp->gsnlu.v);
- gtpie_tlv(packet.gtp1s.p, &length, GTP_MAX, GTPIE_MSISDN,
- pdp->msisdn.l, pdp->msisdn.v);
- gtpie_tlv(packet.gtp1s.p, &length, GTP_MAX, GTPIE_QOS_PROFILE,
+
+ gtpie_tlv(&packet, &length, GTP_MAX, GTPIE_GSN_ADDR,
+ pdp->gsnlc.l, pdp->gsnlc.v);
+ gtpie_tlv(&packet, &length, GTP_MAX, GTPIE_GSN_ADDR,
+ pdp->gsnlu.l, pdp->gsnlu.v);
+ gtpie_tlv(&packet, &length, GTP_MAX, GTPIE_MSISDN,
+ pdp->msisdn.l, pdp->msisdn.v);
+
+ if (pdp->version == 1)
+ gtpie_tlv(&packet, &length, GTP_MAX, GTPIE_QOS_PROFILE,
pdp->qos_req.l, pdp->qos_req.v);
- gtpie_tlv(packet.gtp1s.p, &length, GTP_MAX, GTPIE_TFT,
+
+
+ if ((pdp->version == 1) && pdp->tft.l)
+ gtpie_tlv(&packet, &length, GTP_MAX, GTPIE_TFT,
pdp->tft.l, pdp->tft.v);
- gtpie_tlv(packet.gtp1s.p, &length, GTP_MAX, GTPIE_TRIGGER_ID,
+
+ if ((pdp->version == 1) && pdp->triggerid.l)
+ gtpie_tlv(&packet, &length, GTP_MAX, GTPIE_TRIGGER_ID,
pdp->triggerid.l, pdp->triggerid.v);
- gtpie_tlv(packet.gtp1s.p, &length, GTP_MAX, GTPIE_OMC_ID,
+
+ if ((pdp->version == 1) && pdp->omcid.l)
+ gtpie_tlv(&packet, &length, GTP_MAX, GTPIE_OMC_ID,
pdp->omcid.l, pdp->omcid.v);
- }
- packet.gtp0.h.type = hton8(GTP_CREATE_PDP_REQ);
- packet.gtp0.h.length = hton16(length);
- packet.gtp0.h.flow = 0;
- packet.gtp0.h.tid = pdp->tid;
+
+ gtp_req(gsn, pdp->version, pdp, &packet, length, inetaddr, cbp);
+
+ return 0;
+}
+
- gtp_req(gsn, 0, &packet, GTP0_HEADER_SIZE+length, inetaddr, aid);
+/* API: Application response to context indication */
+int gtp_create_context_resp(struct gsn_t *gsn, struct pdp_t *pdp, int cause) {
+ /* Now send off a reply to the peer */
+ gtp_create_pdp_resp(gsn, pdp->version, pdp, cause);
+
+ if (cause != GTPCAUSE_ACC_REQ) {
+ pdp_freepdp(pdp);
+ }
+
return 0;
}
-/* Send Create PDP Context Response */
-int gtp_create_pdp_resp(struct gsn_t *gsn, int version,
- struct sockaddr_in *peer,
- void *pack, unsigned len,
- struct pdp_t *pdp, uint8_t cause)
+/* API: Register create context indication callback */
+int gtp_set_cb_create_context_ind(struct gsn_t *gsn,
+ int (*cb_create_context_ind) (struct pdp_t* pdp))
{
- union gtp_packet packet;
- int length = 0;
+ gsn->cb_create_context_ind = cb_create_context_ind;
+ return 0;
+}
- get_default_gtp(0, &packet);
- gtpie_tv1(packet.gtp0.p, &length, GTP_MAX, GTPIE_CAUSE, cause);
+/* Send Create PDP Context Response */
+int gtp_create_pdp_resp(struct gsn_t *gsn, int version, struct pdp_t *pdp,
+ uint8_t cause) {
+ union gtp_packet packet;
+ int length = get_default_gtp(version, GTP_CREATE_PDP_RSP, &packet);
+
+ gtpie_tv1(&packet, &length, GTP_MAX, GTPIE_CAUSE, cause);
if (cause == GTPCAUSE_ACC_REQ) {
- gtpie_tv0(packet.gtp0.p, &length, GTP_MAX, GTPIE_QOS_PROFILE0,
- sizeof(pdp->qos_neg0), pdp->qos_neg0);
- gtpie_tv1(packet.gtp0.p, &length, GTP_MAX, GTPIE_REORDER,
+
+ if (version == 0)
+ gtpie_tv0(&packet, &length, GTP_MAX, GTPIE_QOS_PROFILE0,
+ sizeof(pdp->qos_neg0), pdp->qos_neg0);
+
+ gtpie_tv1(&packet, &length, GTP_MAX, GTPIE_REORDER,
pdp->reorder);
- gtpie_tv1(packet.gtp0.p, &length, GTP_MAX, GTPIE_RECOVERY,
+ gtpie_tv1(&packet, &length, GTP_MAX, GTPIE_RECOVERY,
gsn->restart_counter);
- gtpie_tv2(packet.gtp0.p, &length, GTP_MAX, GTPIE_FL_DI,
- pdp->fllu);
- gtpie_tv2(packet.gtp0.p, &length, GTP_MAX, GTPIE_FL_C,
- pdp->fllc);
- gtpie_tv4(packet.gtp0.p, &length, GTP_MAX, GTPIE_CHARGING_ID,
+
+ if (version == 0) {
+ gtpie_tv2(&packet, &length, GTP_MAX, GTPIE_FL_DI,
+ pdp->fllu);
+ gtpie_tv2(&packet, &length, GTP_MAX, GTPIE_FL_C,
+ pdp->fllc);
+ }
+
+ if (version == 1) {
+ gtpie_tv4(&packet, &length, GTP_MAX, GTPIE_TEI_DI,
+ pdp->teid_own);
+ gtpie_tv4(&packet, &length, GTP_MAX, GTPIE_TEI_C,
+ pdp->teic_own);
+ }
+
+ gtpie_tv4(&packet, &length, GTP_MAX, GTPIE_CHARGING_ID,
0x12345678);
- gtpie_tlv(packet.gtp0.p, &length, GTP_MAX, GTPIE_EUA,
+ gtpie_tlv(&packet, &length, GTP_MAX, GTPIE_EUA,
pdp->eua.l, pdp->eua.v);
if (pdp->pco_neg.l) { /* Optional PCO */
- gtpie_tlv(packet.gtp0.p, &length, GTP_MAX, GTPIE_PCO,
+ gtpie_tlv(&packet, &length, GTP_MAX, GTPIE_PCO,
pdp->pco_neg.l, pdp->pco_neg.v);
}
- gtpie_tlv(packet.gtp0.p, &length, GTP_MAX, GTPIE_GSN_ADDR,
+ gtpie_tlv(&packet, &length, GTP_MAX, GTPIE_GSN_ADDR,
pdp->gsnlc.l, pdp->gsnlc.v);
- gtpie_tlv(packet.gtp0.p, &length, GTP_MAX, GTPIE_GSN_ADDR,
+ gtpie_tlv(&packet, &length, GTP_MAX, GTPIE_GSN_ADDR,
pdp->gsnlu.l, pdp->gsnlu.v);
- }
- packet.gtp0.h.type = hton8(GTP_CREATE_PDP_RSP);
- packet.gtp0.h.length = hton16(length);
- packet.gtp0.h.flow = hton16(pdp->flrc);
- packet.gtp0.h.seq = ((union gtp_packet*)pack)->gtp0.h.seq;
- packet.gtp0.h.tid = ((union gtp_packet*)pack)->gtp0.h.tid;
+ if (version == 1)
+ gtpie_tlv(&packet, &length, GTP_MAX, GTPIE_QOS_PROFILE,
+ pdp->qos_neg.l, pdp->qos_neg.v);
+
+ /* TODO: Charging gateway address */
+ }
- return gtp_resp(0, gsn, &packet, GTP0_HEADER_SIZE+length, peer);
+ return gtp_resp(version, gsn, pdp, &packet, length, &pdp->sa_peer,
+ pdp->fd, pdp->seq, pdp->tid);
}
/* Handle Create PDP Context Request */
int gtp_create_pdp_ind(struct gsn_t *gsn, int version,
- struct sockaddr_in *peer, void *pack, unsigned len) {
+ struct sockaddr_in *peer, int fd,
+ void *pack, unsigned len) {
struct pdp_t *pdp, *pdp_old;
struct pdp_t pdp_buf;
union gtpie_member* ie[GTPIE_SIZE];
uint8_t recovery;
- uint64_t imsi;
- uint8_t nsapi;
- int auth = 0; /* Allow access if no callback is defined */
- uint16_t seq = ntoh16(((union gtp_packet*)pack)->gtp0.h.seq);
+ uint16_t seq = get_seq(pack);
+ int hlen = get_hlen(pack);
- if(!gtp_dublicate(gsn, 0, peer, seq)) {
- return 0; /* We allready send of response once */
+ if(!gtp_dublicate(gsn, 0, peer, seq)) return 0;
+
+ pdp = &pdp_buf;
+ memset(pdp, 0, sizeof(struct pdp_t));
+
+ if (version == 0) {
+ pdp->imsi = ((union gtp_packet*)pack)->gtp0.h.tid & 0x0fffffffffffffff;
+ pdp->nsapi = (((union gtp_packet*)pack)->gtp0.h.tid & 0xf000000000000000) >> 60;
}
+ pdp->seq = seq;
+ pdp->sa_peer = *peer;
+ pdp->fd = fd;
+ pdp->version = version;
+
/* Decode information elements */
- if (gtpie_decaps(ie, pack+GTP0_HEADER_SIZE, len-GTP0_HEADER_SIZE)) {
+ if (gtpie_decaps(ie, version, pack+hlen, len-hlen)) {
gsn->invalid++;
gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
"Invalid message format");
if (0 == version)
return EOF;
else
- return gtp_create_pdp_resp(gsn, version, peer, pack, len, pdp,
- GTPCAUSE_INVALID_MESSAGE);
+ return gtp_create_pdp_resp(gsn, version, pdp, GTPCAUSE_INVALID_MESSAGE);
}
- pdp = &pdp_buf;
- memset(pdp, 0, sizeof(struct pdp_t));
-
- /* Extract IMSI and NSAPI from header */
- imsi = ((union gtp_packet*)pack)->gtp0.h.tid & 0x0fffffffffffffff;
- nsapi = (((union gtp_packet*)pack)->gtp0.h.tid & 0xf000000000000000) >> 60;
+ if (version == 0) {
+ if (gtpie_gettv0(ie, GTPIE_QOS_PROFILE0, 0,
+ pdp->qos_req0, sizeof(pdp->qos_req0))) {
+ gsn->missing++;
+ gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
+ "Missing mandatory information field");
+ return gtp_create_pdp_resp(gsn, version, pdp, GTPCAUSE_MAN_IE_MISSING);
+ }
+ }
- /* pdp_newpdp(&pdp, imsi, nsapi); TODO: Need to remove again */
- if (gtpie_gettv0(ie, GTPIE_QOS_PROFILE0, 0,
- pdp->qos_req0, sizeof(pdp->qos_req0))) {
- gsn->missing++;
- gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
- "Missing mandatory information field");
- return gtp_create_pdp_resp(gsn, version, peer, pack, len, pdp,
- GTPCAUSE_MAN_IE_MISSING);
+ if (version == 1) {
+ /* IMSI (conditional) */
+ if (gtpie_gettv0(ie, GTPIE_IMSI, 0, &pdp->imsi, sizeof(pdp->imsi))) {
+ gsn->missing++;
+ gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
+ "Missing mandatory information field");
+ return gtp_create_pdp_resp(gsn, version, pdp,
+ GTPCAUSE_MAN_IE_MISSING);
+ }
}
- /* Extract recovery (optional) */
+ /* Recovery (optional) */
if (!gtpie_gettv1(ie, GTPIE_RECOVERY, 0, &recovery)) {
/* TODO: Handle received recovery IE */
}
+ /* Selection mode (conditional) */
if (gtpie_gettv0(ie, GTPIE_SELECTION_MODE, 0,
&pdp->selmode, sizeof(pdp->selmode))) {
gsn->missing++;
gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
"Missing mandatory information field");
- return gtp_create_pdp_resp(gsn, version, peer, pack, len, pdp,
+ return gtp_create_pdp_resp(gsn, version, pdp,
GTPCAUSE_MAN_IE_MISSING);
}
- if (gtpie_gettv2(ie, GTPIE_FL_DI, 0, &pdp->flru)) {
- gsn->missing++;
- gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
- "Missing mandatory information field");
- return gtp_create_pdp_resp(gsn, version, peer, pack, len, pdp,
- GTPCAUSE_MAN_IE_MISSING);
+ if (version == 0) {
+ if (gtpie_gettv2(ie, GTPIE_FL_DI, 0, &pdp->flru)) {
+ gsn->missing++;
+ gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
+ "Missing mandatory information field");
+ return gtp_create_pdp_resp(gsn, version, pdp,
+ GTPCAUSE_MAN_IE_MISSING);
+ }
+
+ if (gtpie_gettv2(ie, GTPIE_FL_C, 0, &pdp->flrc)) {
+ gsn->missing++;
+ gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
+ "Missing mandatory information field");
+ return gtp_create_pdp_resp(gsn, version, pdp,
+ GTPCAUSE_MAN_IE_MISSING);
+ }
}
- if (gtpie_gettv2(ie, GTPIE_FL_C, 0, &pdp->flrc)) {
- gsn->missing++;
- gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
- "Missing mandatory information field");
- return gtp_create_pdp_resp(gsn, version, peer, pack, len, pdp,
- GTPCAUSE_MAN_IE_MISSING);
+
+ if (version == 1) {
+ /* TEID (mandatory) */
+ if (gtpie_gettv4(ie, GTPIE_TEI_DI, 0, &pdp->teid_gn)) {
+ gsn->missing++;
+ gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
+ "Missing mandatory information field");
+ return gtp_create_pdp_resp(gsn, version, pdp,
+ GTPCAUSE_MAN_IE_MISSING);
+ }
+
+ /* TEIC (conditional) */
+ if (gtpie_gettv4(ie, GTPIE_TEI_C, 0, &pdp->teic_gn)) {
+ gsn->missing++;
+ gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
+ "Missing mandatory information field");
+ return gtp_create_pdp_resp(gsn, version, pdp,
+ GTPCAUSE_MAN_IE_MISSING);
+ }
+
+ /* NSAPI (mandatory) */
+ if (gtpie_gettv1(ie, GTPIE_NSAPI, 0, &pdp->nsapi)) {
+ gsn->missing++;
+ gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
+ "Missing mandatory information field");
+ return gtp_create_pdp_resp(gsn, version, pdp,
+ GTPCAUSE_MAN_IE_MISSING);
+ }
+
+ /* Linked NSAPI (conditional) */
+ if (gtpie_gettv1(ie, GTPIE_NSAPI, 1, &pdp->linked_nsapi)) {
+ /* TODO: Handle linked NSAPI */
+ /* Currently the Secondary PDP Context Activation Procedure is not */
+ /* supported */
+ } else {
+ gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
+ "Found Linked NSAPI");
+ return gtp_create_pdp_resp(gsn, version, pdp,
+ GTPCAUSE_NOT_SUPPORTED);
+ }
}
+ /* Charging Characteriatics (optional) */
+ /* Trace reference (optional) */
+ /* Trace type (optional) */
+ /* Charging Characteriatics (optional) */
+
+ /* End User Address (conditional) */
if (gtpie_gettlv(ie, GTPIE_EUA, 0, &pdp->eua.l,
&pdp->eua.v, sizeof(pdp->eua.v))) {
gsn->missing++;
gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
"Missing mandatory information field");
- return gtp_create_pdp_resp(gsn, version, peer, pack, len, pdp,
+ return gtp_create_pdp_resp(gsn, version, pdp,
GTPCAUSE_MAN_IE_MISSING);
}
+ /* APN */
if (gtpie_gettlv(ie, GTPIE_APN, 0, &pdp->apn_req.l,
&pdp->apn_req.v, sizeof(pdp->apn_req.v))) {
gsn->missing++;
gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
"Missing mandatory information field");
- return gtp_create_pdp_resp(gsn, version, peer, pack, len, pdp,
+ return gtp_create_pdp_resp(gsn, version, pdp,
GTPCAUSE_MAN_IE_MISSING);
}
/* Extract protocol configuration options (optional) */
if (!gtpie_gettlv(ie, GTPIE_PCO, 0, &pdp->pco_req.l,
&pdp->pco_req.v, sizeof(pdp->pco_req.v))) {
- /* TODO: Handle PCO IE */
}
+ /* SGSN address for signalling (mandatory) */
if (gtpie_gettlv(ie, GTPIE_GSN_ADDR, 0, &pdp->gsnrc.l,
&pdp->gsnrc.v, sizeof(pdp->gsnrc.v))) {
gsn->missing++;
gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
"Missing mandatory information field");
- return gtp_create_pdp_resp(gsn, version, peer, pack, len, pdp,
+ return gtp_create_pdp_resp(gsn, version, pdp,
GTPCAUSE_MAN_IE_MISSING);
}
+ /* SGSN address for user traffic (mandatory) */
if (gtpie_gettlv(ie, GTPIE_GSN_ADDR, 1, &pdp->gsnru.l,
&pdp->gsnru.v, sizeof(pdp->gsnru.v))) {
gsn->missing++;
gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
"Missing mandatory information field");
- return gtp_create_pdp_resp(gsn, version, peer, pack, len, pdp,
+ return gtp_create_pdp_resp(gsn, version, pdp,
GTPCAUSE_MAN_IE_MISSING);
}
+ /* MSISDN (conditional) */
if (gtpie_gettlv(ie, GTPIE_MSISDN, 0, &pdp->msisdn.l,
&pdp->msisdn.v, sizeof(pdp->msisdn.v))) {
gsn->missing++;
gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
"Missing mandatory information field");
- return gtp_create_pdp_resp(gsn, version, peer, pack, len, pdp,
+ return gtp_create_pdp_resp(gsn, version, pdp,
GTPCAUSE_MAN_IE_MISSING);
}
+ if (version == 1) {
+ /* QoS (mandatory) */
+ if (gtpie_gettlv(ie, GTPIE_QOS_PROFILE, 0, &pdp->qos_req.l,
+ &pdp->qos_req.v, sizeof(pdp->qos_req.v))) {
+ gsn->missing++;
+ gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
+ "Missing mandatory information field");
+ return gtp_create_pdp_resp(gsn, version, pdp,
+ GTPCAUSE_MAN_IE_MISSING);
+ }
+
+ /* TFT (conditional) */
+ if (gtpie_gettlv(ie, GTPIE_TFT, 0, &pdp->tft.l,
+ &pdp->tft.v, sizeof(pdp->tft.v))) {
+ }
+
+ /* Trigger ID */
+ /* OMC identity */
+ }
+
+ /* Initialize our own IP addresses */
in_addr2gsna(&pdp->gsnlc, &gsn->gsnc);
in_addr2gsna(&pdp->gsnlu, &gsn->gsnu);
if (GTP_DEBUG) printf("gtp_create_pdp_ind: Before pdp_tidget\n");
- if (!pdp_tidget(&pdp_old, ((union gtp_packet*)pack)->gtp0.h.tid)) {
+ if (!pdp_getimsi(&pdp_old, pdp->imsi, pdp->nsapi)) {
/* Found old pdp with same tid. Now the voodoo begins! */
+ /* 09.60 / 29.060 allows create on existing context to "steal" */
+ /* the context which was allready established */
/* We check that the APN, selection mode and MSISDN is the same */
if (GTP_DEBUG) printf("gtp_create_pdp_ind: Old context found\n");
- if ( (pdp->apn_req.l == pdp_old->apn_req.l)
+ if ((pdp->apn_req.l == pdp_old->apn_req.l)
&& (!memcmp(pdp->apn_req.v, pdp_old->apn_req.v, pdp->apn_req.l))
&& (pdp->selmode == pdp_old->selmode)
&& (pdp->msisdn.l == pdp_old->msisdn.l)
@@ -1147,18 +1324,20 @@ int gtp_create_pdp_ind(struct gsn_t *gsn, int version,
pdp_old->flru = pdp->flru;
pdp_old->flrc = pdp->flrc;
+ /* Copy remote tei */
+ pdp_old->teid_gn = pdp->teid_gn;
+ pdp_old->teic_gn = pdp->teic_gn;
+
/* Copy peer GSN address */
pdp_old->gsnrc.l = pdp->gsnrc.l;
memcpy(&pdp_old->gsnrc.v, &pdp->gsnrc.v, pdp->gsnrc.l);
pdp_old->gsnru.l = pdp->gsnru.l;
memcpy(&pdp_old->gsnru.v, &pdp->gsnru.v, pdp->gsnru.l);
- /* pdp_freepdp(pdp); not nessasary anymore since never allocated */
pdp = pdp_old;
/* Confirm to peer that things were "successful" */
- return gtp_create_pdp_resp(gsn, version, peer, pack, len, pdp,
- GTPCAUSE_ACC_REQ);
+ return gtp_create_pdp_resp(gsn, version, pdp, GTPCAUSE_ACC_REQ);
}
else { /* This is not the same PDP context. Delete the old one. */
@@ -1166,59 +1345,53 @@ int gtp_create_pdp_ind(struct gsn_t *gsn, int version,
if (gsn->cb_delete_context) gsn->cb_delete_context(pdp_old);
pdp_freepdp(pdp_old);
-
+
if (GTP_DEBUG) printf("gtp_create_pdp_ind: Deleted...\n");
}
}
- pdp_newpdp(&pdp, imsi, nsapi, pdp);
+ pdp_newpdp(&pdp, pdp->imsi, pdp->nsapi, pdp);
/* Callback function to validata login */
- if (gsn->cb_create_context !=0)
- auth = gsn->cb_create_context(pdp);
-
- /* Now send off a reply to the peer */
- if (!auth) {
- return gtp_create_pdp_resp(gsn, version, peer, pack, len, pdp,
- GTPCAUSE_ACC_REQ);
- }
+ if (gsn->cb_create_context_ind !=0)
+ return gsn->cb_create_context_ind(pdp);
else {
- gtp_create_pdp_resp(gsn, version, peer, pack, len, pdp,
- GTPCAUSE_USER_AUTH_FAIL);
- pdp_freepdp(pdp);
- return 0;
+ gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
+ "No create_context_ind callback defined");
+ return gtp_create_pdp_resp(gsn, version, pdp, GTPCAUSE_NOT_SUPPORTED);
}
}
/* Handle Create PDP Context Response */
int gtp_create_pdp_conf(struct gsn_t *gsn, int version,
- struct sockaddr_in *peer,
- void *pack, unsigned len) {
+ struct sockaddr_in *peer,
+ void *pack, unsigned len) {
struct pdp_t *pdp;
union gtpie_member *ie[GTPIE_SIZE];
uint8_t cause, recovery;
- void *aid = NULL;
+ void *cbp = NULL;
uint8_t type = 0;
+ int hlen = get_hlen(pack);
/* Remove packet from queue */
- if (gtp_conf(gsn, 0, peer, pack, len, &type, &aid)) return EOF;
+ if (gtp_conf(gsn, version, peer, pack, len, &type, &cbp)) return EOF;
/* Find the context in question */
- if (pdp_getgtp0(&pdp, ntoh16(((union gtp_packet*)pack)->gtp0.h.flow))) {
+ if (pdp_getgtp1(&pdp, get_tei(pack))) {
gsn->err_unknownpdp++;
gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
"Unknown PDP context");
- if (gsn->cb_conf) gsn->cb_conf(type, EOF, NULL, aid);
+ if (gsn->cb_conf) gsn->cb_conf(type, EOF, NULL, cbp);
return EOF;
}
/* Decode information elements */
- if (gtpie_decaps(ie, pack+GTP0_HEADER_SIZE, len-GTP0_HEADER_SIZE)) {
+ if (gtpie_decaps(ie, version, pack+hlen, len-hlen)) {
gsn->invalid++;
gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
"Invalid message format");
- if (gsn->cb_conf) gsn->cb_conf(type, EOF, pdp, aid);
+ if (gsn->cb_conf) gsn->cb_conf(type, EOF, pdp, cbp);
return EOF;
}
@@ -1227,7 +1400,7 @@ int gtp_create_pdp_conf(struct gsn_t *gsn, int version,
gsn->missing++;
gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
"Missing mandatory information field");
- if (gsn->cb_conf) gsn->cb_conf(type, EOF, pdp, aid);
+ if (gsn->cb_conf) gsn->cb_conf(type, EOF, pdp, cbp);
return EOF;
}
@@ -1239,53 +1412,71 @@ int gtp_create_pdp_conf(struct gsn_t *gsn, int version,
/* Extract protocol configuration options (optional) */
if (!gtpie_gettlv(ie, GTPIE_PCO, 0, &pdp->pco_req.l,
&pdp->pco_req.v, sizeof(pdp->pco_req.v))) {
- /* TODO: Handle PCO IE */
}
/* Check all conditional information elements */
if (GTPCAUSE_ACC_REQ == cause) {
- if (gtpie_gettv0(ie, GTPIE_QOS_PROFILE0, 0, /* TODO: HACK only gtp0 */
- &pdp->qos_neg0, sizeof(pdp->qos_neg0))) {
- gsn->missing++;
- gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
- "Missing conditional information field");
- if (gsn->cb_conf) gsn->cb_conf(type, EOF, pdp, aid);
- return EOF;
+ if (version == 0) {
+ if (gtpie_gettv0(ie, GTPIE_QOS_PROFILE0, 0,
+ &pdp->qos_neg0, sizeof(pdp->qos_neg0))) {
+ gsn->missing++;
+ gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
+ "Missing conditional information field");
+ if (gsn->cb_conf) gsn->cb_conf(type, EOF, pdp, cbp);
+ return EOF;
+ }
}
- /* pdp->qos_neg.l = 3; * TODO: HACK only gtp0 */
if (gtpie_gettv1(ie, GTPIE_REORDER, 0, &pdp->reorder)) {
gsn->missing++;
gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
"Missing conditional information field");
- if (gsn->cb_conf) gsn->cb_conf(type, EOF, pdp, aid);
+ if (gsn->cb_conf) gsn->cb_conf(type, EOF, pdp, cbp);
return EOF;
}
- if (gtpie_gettv2(ie, GTPIE_FL_DI, 0, &pdp->flru)) {
- gsn->missing++;
- gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
- "Missing conditional information field");
- if (gsn->cb_conf) gsn->cb_conf(type, EOF, pdp, aid);
- return EOF;
+ if (version == 0) {
+ if (gtpie_gettv2(ie, GTPIE_FL_DI, 0, &pdp->flru)) {
+ gsn->missing++;
+ gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
+ "Missing conditional information field");
+ if (gsn->cb_conf) gsn->cb_conf(type, EOF, pdp, cbp);
+ return EOF;
+ }
+
+ if (gtpie_gettv2(ie, GTPIE_FL_C, 0, &pdp->flrc)) {
+ gsn->missing++;
+ gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
+ "Missing conditional information field");
+ if (gsn->cb_conf) gsn->cb_conf(type, EOF, pdp, cbp);
+ return EOF;
+ }
}
+
+ if (version == 1) {
+ if (gtpie_gettv4(ie, GTPIE_TEI_DI, 0, &pdp->teid_gn)) {
+ gsn->missing++;
+ gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
+ "Missing conditional information field");
+ if (gsn->cb_conf) gsn->cb_conf(type, EOF, pdp, cbp);
+ return EOF;
+ }
- if (gtpie_gettv2(ie, GTPIE_FL_C, 0, &pdp->flrc)) {
- gsn->missing++;
- gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
- "Missing conditional information field");
- if (gsn->cb_conf) gsn->cb_conf(type, EOF, pdp, aid);
- return EOF;
+ if (gtpie_gettv4(ie, GTPIE_TEI_C, 0, &pdp->teic_gn)) {
+ gsn->missing++;
+ gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
+ "Missing conditional information field");
+ if (gsn->cb_conf) gsn->cb_conf(type, EOF, pdp, cbp);
+ return EOF;
+ }
}
if (gtpie_gettv4(ie, GTPIE_CHARGING_ID, 0, &pdp->cid)) {
gsn->missing++;
gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
"Missing conditional information field");
- if (gsn->cb_conf) gsn->cb_conf(type, EOF, pdp, aid);
- return gtp_create_pdp_resp(gsn, version, peer, pack, len, pdp,
- GTPCAUSE_MAN_IE_MISSING);
+ if (gsn->cb_conf) gsn->cb_conf(type, EOF, pdp, cbp);
}
if (gtpie_gettlv(ie, GTPIE_EUA, 0, &pdp->eua.l,
@@ -1293,7 +1484,7 @@ int gtp_create_pdp_conf(struct gsn_t *gsn, int version,
gsn->missing++;
gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
"Missing conditional information field");
- if (gsn->cb_conf) gsn->cb_conf(type, EOF, pdp, aid);
+ if (gsn->cb_conf) gsn->cb_conf(type, EOF, pdp, cbp);
return EOF;
}
@@ -1302,7 +1493,7 @@ int gtp_create_pdp_conf(struct gsn_t *gsn, int version,
gsn->missing++;
gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
"Missing conditional information field");
- if (gsn->cb_conf) gsn->cb_conf(type, EOF, pdp, aid);
+ if (gsn->cb_conf) gsn->cb_conf(type, EOF, pdp, cbp);
return EOF;
}
@@ -1311,178 +1502,375 @@ int gtp_create_pdp_conf(struct gsn_t *gsn, int version,
gsn->missing++;
gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
"Missing conditional information field");
- if (gsn->cb_conf) gsn->cb_conf(type, EOF, pdp, aid);
+ if (gsn->cb_conf) gsn->cb_conf(type, EOF, pdp, cbp);
return EOF;
}
- }
- if (gsn->cb_conf) gsn->cb_conf(type, cause, pdp, aid);
+ if (version == 1) {
+ if (gtpie_gettlv(ie, GTPIE_QOS_PROFILE, 0, &pdp->qos_neg.l,
+ &pdp->qos_neg.v, sizeof(pdp->qos_neg.v))) {
+ gsn->missing++;
+ gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
+ "Missing conditional information field");
+ if (gsn->cb_conf) gsn->cb_conf(type, EOF, pdp, cbp);
+ return EOF;
+ }
+ }
+
+ }
+
+ if (gsn->cb_conf) gsn->cb_conf(type, cause, pdp, cbp);
return 0;
}
-/* Send Update PDP Context Request */
-extern int gtp_update_pdp_req(struct gsn_t *gsn, int version, void *aid,
- struct in_addr* inetaddr, struct pdp_t *pdp) {
- union gtp_packet packet;
- int length = 0;
- get_default_gtp(0, &packet);
+/* API: Send Update PDP Context Request */
+int gtp_update_context(struct gsn_t *gsn, struct pdp_t *pdp, void *cbp,
+ struct in_addr* inetaddr) {
+ union gtp_packet packet;
+ int length = get_default_gtp(pdp->version, GTP_UPDATE_PDP_REQ, &packet);
- gtpie_tv0(packet.gtp0.p, &length, GTP_MAX, GTPIE_QOS_PROFILE0,
- sizeof(pdp->qos_req0), pdp->qos_req0);
- gtpie_tv1(packet.gtp0.p, &length, GTP_MAX, GTPIE_RECOVERY,
+ if (pdp->version == 0)
+ gtpie_tv0(&packet, &length, GTP_MAX, GTPIE_QOS_PROFILE0,
+ sizeof(pdp->qos_req0), pdp->qos_req0);
+
+ if (pdp->version == 1)
+ gtpie_tv0(&packet, &length, GTP_MAX, GTPIE_IMSI,
+ sizeof(pdp->imsi), (uint8_t*) &pdp->imsi);
+
+ gtpie_tv1(&packet, &length, GTP_MAX, GTPIE_RECOVERY,
gsn->restart_counter);
- gtpie_tv2(packet.gtp0.p, &length, GTP_MAX, GTPIE_FL_DI,
- pdp->fllu);
- gtpie_tv2(packet.gtp0.p, &length, GTP_MAX, GTPIE_FL_C,
- pdp->fllc);
- gtpie_tlv(packet.gtp0.p, &length, GTP_MAX, GTPIE_GSN_ADDR,
+
+ if (pdp->version == 0) {
+ gtpie_tv2(&packet, &length, GTP_MAX, GTPIE_FL_DI,
+ pdp->fllu);
+ gtpie_tv2(&packet, &length, GTP_MAX, GTPIE_FL_C,
+ pdp->fllc);
+ }
+
+ if (pdp->version == 1) {
+ gtpie_tv4(&packet, &length, GTP_MAX, GTPIE_TEI_DI,
+ pdp->teid_own);
+ gtpie_tv4(&packet, &length, GTP_MAX, GTPIE_TEI_C,
+ pdp->teic_own);
+ }
+
+ gtpie_tv1(&packet, &length, GTP_MAX, GTPIE_NSAPI,
+ pdp->nsapi);
+
+ /* TODO
+ gtpie_tv2(&packet, &length, GTP_MAX, GTPIE_TRACE_REF,
+ pdp->traceref);
+ gtpie_tv2(&packet, &length, GTP_MAX, GTPIE_TRACE_TYPE,
+ pdp->tracetype); */
+
+ /* TODO if ggsn update message
+ gtpie_tlv(&packet, &length, GTP_MAX, GTPIE_EUA,
+ pdp->eua.l, pdp->eua.v);
+ */
+
+ gtpie_tlv(&packet, &length, GTP_MAX, GTPIE_GSN_ADDR,
pdp->gsnlc.l, pdp->gsnlc.v);
- gtpie_tlv(packet.gtp0.p, &length, GTP_MAX, GTPIE_GSN_ADDR,
+ gtpie_tlv(&packet, &length, GTP_MAX, GTPIE_GSN_ADDR,
pdp->gsnlu.l, pdp->gsnlu.v);
+
+ if (pdp->version == 1)
+ gtpie_tlv(&packet, &length, GTP_MAX, GTPIE_QOS_PROFILE,
+ pdp->qos_req.l, pdp->qos_req.v);
+
+
+ if ((pdp->version == 1) && pdp->tft.l)
+ gtpie_tlv(&packet, &length, GTP_MAX, GTPIE_TFT,
+ pdp->tft.l, pdp->tft.v);
- packet.gtp0.h.type = hton8(GTP_UPDATE_PDP_REQ);
- packet.gtp0.h.length = hton16(length);
- packet.gtp0.h.flow = 0;
- packet.gtp0.h.tid = (pdp->imsi & 0x0fffffffffffffff) + ((uint64_t)pdp->nsapi << 60);
+ if ((pdp->version == 1) && pdp->triggerid.l)
+ gtpie_tlv(&packet, &length, GTP_MAX, GTPIE_TRIGGER_ID,
+ pdp->triggerid.l, pdp->triggerid.v);
+
+ if ((pdp->version == 1) && pdp->omcid.l)
+ gtpie_tlv(&packet, &length, GTP_MAX, GTPIE_OMC_ID,
+ pdp->omcid.l, pdp->omcid.v);
+
+ gtp_req(gsn, pdp->version, NULL, &packet, length, inetaddr, cbp);
- return gtp_req(gsn, 0, &packet, GTP0_HEADER_SIZE+length, inetaddr, aid);
+ return 0;
}
+
/* Send Update PDP Context Response */
-int gtp_update_pdp_resp(struct gsn_t *gsn, int version,
- struct sockaddr_in *peer,
- void *pack, unsigned len,
- struct pdp_t *pdp, uint8_t cause)
-{
+int gtp_update_pdp_resp(struct gsn_t *gsn, int version,
+ struct sockaddr_in *peer, int fd,
+ void *pack, unsigned len,
+ struct pdp_t *pdp, uint8_t cause) {
+
union gtp_packet packet;
- int length = 0;
+ int length = get_default_gtp(version, GTP_CREATE_PDP_RSP, &packet);
+
+ gtpie_tv1(&packet, &length, GTP_MAX, GTPIE_CAUSE, cause);
+
+ if (cause == GTPCAUSE_ACC_REQ) {
+
+ if (version == 0)
+ gtpie_tv0(&packet, &length, GTP_MAX, GTPIE_QOS_PROFILE0,
+ sizeof(pdp->qos_neg0), pdp->qos_neg0);
- get_default_gtp(0, &packet);
+ gtpie_tv1(&packet, &length, GTP_MAX, GTPIE_RECOVERY,
+ gsn->restart_counter);
- gtpie_tv1(packet.gtp0.p, &length, GTP_MAX, GTPIE_CAUSE, cause);
+ if (version == 0) {
+ gtpie_tv2(&packet, &length, GTP_MAX, GTPIE_FL_DI,
+ pdp->fllu);
+ gtpie_tv2(&packet, &length, GTP_MAX, GTPIE_FL_C,
+ pdp->fllc);
+ }
- if (cause == GTPCAUSE_ACC_REQ) {
- gtpie_tv0(packet.gtp0.p, &length, GTP_MAX, GTPIE_QOS_PROFILE0,
- sizeof(pdp->qos_sub0), pdp->qos_sub0);
- gtpie_tv1(packet.gtp0.p, &length, GTP_MAX, GTPIE_RECOVERY,
- gsn->restart_counter);
- gtpie_tv2(packet.gtp0.p, &length, GTP_MAX, GTPIE_FL_DI,
- pdp->fllu);
- gtpie_tv2(packet.gtp0.p, &length, GTP_MAX, GTPIE_FL_C,
- pdp->fllc);
- gtpie_tv4(packet.gtp0.p, &length, GTP_MAX, GTPIE_CHARGING_ID,
- 0x12345678);
- gtpie_tlv(packet.gtp0.p, &length, GTP_MAX, GTPIE_GSN_ADDR,
+ if (version == 1) {
+ gtpie_tv4(&packet, &length, GTP_MAX, GTPIE_TEI_DI,
+ pdp->teid_own);
+ gtpie_tv4(&packet, &length, GTP_MAX, GTPIE_TEI_C,
+ pdp->teic_own);
+ }
+
+ gtpie_tv4(&packet, &length, GTP_MAX, GTPIE_CHARGING_ID,
+ 0x12345678); /* TODO */
+
+ /* If ggsn
+ gtpie_tlv(&packet, &length, GTP_MAX, GTPIE_EUA,
+ pdp->eua.l, pdp->eua.v); */
+
+ gtpie_tlv(&packet, &length, GTP_MAX, GTPIE_GSN_ADDR,
pdp->gsnlc.l, pdp->gsnlc.v);
- gtpie_tlv(packet.gtp0.p, &length, GTP_MAX, GTPIE_GSN_ADDR,
+ gtpie_tlv(&packet, &length, GTP_MAX, GTPIE_GSN_ADDR,
pdp->gsnlu.l, pdp->gsnlu.v);
- }
- packet.gtp0.h.type = hton8(GTP_UPDATE_PDP_RSP);
- packet.gtp0.h.length = hton16(length);
- packet.gtp0.h.flow = hton16(pdp->flrc);
- packet.gtp0.h.seq = ((union gtp_packet*)pack)->gtp0.h.seq;
- packet.gtp0.h.tid = (pdp->imsi & 0x0fffffffffffffff) + ((uint64_t)pdp->nsapi << 60);
+ if (version == 1)
+ gtpie_tlv(&packet, &length, GTP_MAX, GTPIE_QOS_PROFILE,
+ pdp->qos_neg.l, pdp->qos_neg.v);
+
+ /* TODO: Charging gateway address */
+ }
- return gtp_resp(0, gsn, &packet, GTP0_HEADER_SIZE+length, peer);
+ return gtp_resp(version, gsn, pdp, &packet, length, &pdp->sa_peer,
+ pdp->fd, pdp->seq, pdp->tid);
}
+
/* Handle Update PDP Context Request */
int gtp_update_pdp_ind(struct gsn_t *gsn, int version,
- struct sockaddr_in *peer, void *pack, unsigned len) {
- struct pdp_t *pdp, *pdp2;
- struct pdp_t pdp_buf;
+ struct sockaddr_in *peer, int fd,
+ void *pack, unsigned len) {
+ struct pdp_t *pdp;
+ struct pdp_t pdp_backup;
union gtpie_member* ie[GTPIE_SIZE];
uint8_t recovery;
- uint16_t seq = ntoh16(((union gtp_packet*)pack)->gtp0.h.seq);
+ uint16_t seq = get_seq(pack);
+ int hlen = get_hlen(pack);
+ uint64_t imsi;
+ uint8_t nsapi;
+
/* Is this a dublicate ? */
- if(!gtp_dublicate(gsn, 0, peer, seq)) {
+ if(!gtp_dublicate(gsn, version, peer, seq)) {
return 0; /* We allready send of response once */
}
- /* Find the pdp context in question */
- if (pdp_getgtp0(&pdp, ntoh16(((union gtp_packet*)pack)->gtp0.h.flow))) {
- gsn->err_unknownpdp++;
- gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
- "Unknown PDP context");
- return gtp_update_pdp_resp(gsn, version, peer, pack, len, NULL,
- GTPCAUSE_NON_EXIST);
- }
/* Decode information elements */
- if (gtpie_decaps(ie, pack+GTP0_HEADER_SIZE, len-GTP0_HEADER_SIZE)) {
+ if (gtpie_decaps(ie, version, pack+hlen, len-hlen)) {
gsn->invalid++;
gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
"Invalid message format");
if (0 == version)
return EOF;
else
- return gtp_update_pdp_resp(gsn, version, peer, pack, len, pdp,
- GTPCAUSE_INVALID_MESSAGE);
+ return gtp_update_pdp_resp(gsn, version, peer, fd, pack, len,
+ NULL, GTPCAUSE_INVALID_MESSAGE);
}
- pdp2 = &pdp_buf;
- memcpy(pdp2, pdp, sizeof (struct pdp_t)); /* Generate local copy */
+ /* Finding PDP: */
+ /* For GTP0 we use the tunnel identifier to provide imsi and nsapi. */
+ /* For GTP1 we must use imsi and nsapi if imsi is present. Otherwise */
+ /* we have to use the tunnel endpoint identifier */
+ if (version == 0) {
+ imsi = ((union gtp_packet*)pack)->gtp0.h.tid & 0x0fffffffffffffff;
+ nsapi = (((union gtp_packet*)pack)->gtp0.h.tid & 0xf000000000000000) >> 60;
- if (gtpie_gettv0(ie, GTPIE_QOS_PROFILE0, 0, /* TODO: HACK only gtp0 */
- &pdp2->qos_req0, sizeof(pdp2->qos_req0))) {
- gsn->missing++;
- gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
- "Missing mandatory information field");
- return gtp_update_pdp_resp(gsn, version, peer, pack, len, pdp2,
- GTPCAUSE_MAN_IE_MISSING);
+ /* Find the context in question */
+ if (pdp_getimsi(&pdp, imsi, nsapi)) {
+ gsn->err_unknownpdp++;
+ gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
+ "Unknown PDP context");
+ return gtp_update_pdp_resp(gsn, version, peer, fd, pack, len,
+ NULL, GTPCAUSE_NON_EXIST);
+ }
}
- /* pdp2->qos_req.l = 3; * TODO: HACK only gtp0 */
+ else if (version == 1) {
+ /* NSAPI (mandatory) */
+ if (gtpie_gettv1(ie, GTPIE_NSAPI, 0, &nsapi)) {
+ gsn->missing++;
+ gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
+ "Missing mandatory information field");
+ return gtp_update_pdp_resp(gsn, version, peer, fd, pack, len,
+ NULL, GTPCAUSE_MAN_IE_MISSING);
+ }
- /* Extract recovery (optional) */
+ /* IMSI (conditional) */
+ if (gtpie_gettv0(ie, GTPIE_IMSI, 0, &imsi, sizeof(imsi))) {
+ /* Find the context in question */
+ if (pdp_getgtp1(&pdp, get_tei(pack))) {
+ gsn->err_unknownpdp++;
+ gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
+ "Unknown PDP context");
+ return gtp_update_pdp_resp(gsn, version, peer, fd, pack, len,
+ NULL, GTPCAUSE_NON_EXIST);
+ }
+ }
+ else {
+ /* Find the context in question */
+ if (pdp_getimsi(&pdp, imsi, nsapi)) {
+ gsn->err_unknownpdp++;
+ gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
+ "Unknown PDP context");
+ return gtp_update_pdp_resp(gsn, version, peer, fd, pack, len,
+ NULL, GTPCAUSE_NON_EXIST);
+ }
+ }
+ }
+ else {
+ gtp_err(LOG_ERR, __FILE__, __LINE__, "Unknown version");
+ return EOF;
+ }
+
+ /* Make a backup copy in case anything is wrong */
+ memcpy(&pdp_backup, pdp, sizeof(pdp_backup));
+
+ if (version == 0) {
+ if (gtpie_gettv0(ie, GTPIE_QOS_PROFILE0, 0,
+ pdp->qos_req0, sizeof(pdp->qos_req0))) {
+ gsn->missing++;
+ gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
+ "Missing mandatory information field");
+ memcpy(pdp, &pdp_backup, sizeof(pdp_backup));
+ return gtp_update_pdp_resp(gsn, version, peer, fd, pack, len,
+ pdp, GTPCAUSE_MAN_IE_MISSING);
+ }
+ }
+
+ /* Recovery (optional) */
if (!gtpie_gettv1(ie, GTPIE_RECOVERY, 0, &recovery)) {
/* TODO: Handle received recovery IE */
}
- if (gtpie_gettv2(ie, GTPIE_FL_DI, 0, &pdp2->flru)) {
- gsn->missing++;
- gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
- "Missing mandatory information field");
- return gtp_update_pdp_resp(gsn, version, peer, pack, len, pdp2,
- GTPCAUSE_MAN_IE_MISSING);
+ if (version == 0) {
+ if (gtpie_gettv2(ie, GTPIE_FL_DI, 0, &pdp->flru)) {
+ gsn->missing++;
+ gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
+ "Missing mandatory information field");
+ memcpy(pdp, &pdp_backup, sizeof(pdp_backup));
+ return gtp_update_pdp_resp(gsn, version, peer, fd, pack, len, pdp,
+ GTPCAUSE_MAN_IE_MISSING);
+ }
+
+ if (gtpie_gettv2(ie, GTPIE_FL_C, 0, &pdp->flrc)) {
+ gsn->missing++;
+ gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
+ "Missing mandatory information field");
+ memcpy(pdp, &pdp_backup, sizeof(pdp_backup));
+ return gtp_update_pdp_resp(gsn, version, peer, fd, pack, len, pdp,
+ GTPCAUSE_MAN_IE_MISSING);
+ }
}
- if (gtpie_gettv2(ie, GTPIE_FL_C, 0, &pdp2->flrc)) {
+
+ if (version == 1) {
+ /* TEID (mandatory) */
+ if (gtpie_gettv4(ie, GTPIE_TEI_DI, 0, &pdp->teid_gn)) {
+ gsn->missing++;
+ gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
+ "Missing mandatory information field");
+ memcpy(pdp, &pdp_backup, sizeof(pdp_backup));
+ return gtp_update_pdp_resp(gsn, version, peer, fd, pack, len, pdp,
+ GTPCAUSE_MAN_IE_MISSING);
+ }
+
+ /* TEIC (conditional) */
+ /* If TEIC is not included it means that we have allready received it */
+ if (gtpie_gettv4(ie, GTPIE_TEI_C, 0, &pdp->teic_gn)) {
+ }
+
+ /* NSAPI (mandatory) */
+ if (gtpie_gettv1(ie, GTPIE_NSAPI, 0, &pdp->nsapi)) {
+ gsn->missing++;
+ gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
+ "Missing mandatory information field");
+ memcpy(pdp, &pdp_backup, sizeof(pdp_backup));
+ return gtp_update_pdp_resp(gsn, version, peer, fd, pack, len, pdp,
+ GTPCAUSE_MAN_IE_MISSING);
+ }
+ }
+
+ /* Trace reference (optional) */
+ /* Trace type (optional) */
+
+ /* End User Address (conditional) TODO: GGSN Initiated
+ if (gtpie_gettlv(ie, GTPIE_EUA, 0, &pdp->eua.l,
+ &pdp->eua.v, sizeof(pdp->eua.v))) {
gsn->missing++;
gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
"Missing mandatory information field");
- return gtp_update_pdp_resp(gsn, version, peer, pack, len, pdp2,
+ memcpy(pdp, &pdp_backup, sizeof(pdp_backup));
+ return gtp_update_pdp_resp(gsn, version, pdp,
GTPCAUSE_MAN_IE_MISSING);
- }
+ } */
- if (gtpie_gettlv(ie, GTPIE_GSN_ADDR, 0, &pdp2->gsnrc.l,
- &pdp2->gsnrc.v, sizeof(pdp2->gsnrc.v))) {
+
+ /* SGSN address for signalling (mandatory) */
+ /* It is weird that this is mandatory when TEIC is conditional */
+ if (gtpie_gettlv(ie, GTPIE_GSN_ADDR, 0, &pdp->gsnrc.l,
+ &pdp->gsnrc.v, sizeof(pdp->gsnrc.v))) {
gsn->missing++;
gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
"Missing mandatory information field");
- return gtp_update_pdp_resp(gsn, version, peer, pack, len, pdp2,
+ memcpy(pdp, &pdp_backup, sizeof(pdp_backup));
+ return gtp_update_pdp_resp(gsn, version, peer, fd, pack, len, pdp,
GTPCAUSE_MAN_IE_MISSING);
}
- if (gtpie_gettlv(ie, GTPIE_GSN_ADDR, 1, &pdp2->gsnru.l,
- &pdp2->gsnru.v, sizeof(pdp2->gsnru.v))) {
+ /* SGSN address for user traffic (mandatory) */
+ if (gtpie_gettlv(ie, GTPIE_GSN_ADDR, 1, &pdp->gsnru.l,
+ &pdp->gsnru.v, sizeof(pdp->gsnru.v))) {
gsn->missing++;
gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
"Missing mandatory information field");
- return gtp_update_pdp_resp(gsn, version, peer, pack, len, pdp2,
+ memcpy(pdp, &pdp_backup, sizeof(pdp_backup));
+ return gtp_update_pdp_resp(gsn, version, peer, fd, pack, len, pdp,
GTPCAUSE_MAN_IE_MISSING);
}
+
+ if (version == 1) {
+ /* QoS (mandatory) */
+ if (gtpie_gettlv(ie, GTPIE_QOS_PROFILE, 0, &pdp->qos_req.l,
+ &pdp->qos_req.v, sizeof(pdp->qos_req.v))) {
+ gsn->missing++;
+ gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
+ "Missing mandatory information field");
+ memcpy(pdp, &pdp_backup, sizeof(pdp_backup));
+ return gtp_update_pdp_resp(gsn, version, peer, fd, pack, len, pdp,
+ GTPCAUSE_MAN_IE_MISSING);
+ }
- /* OK! It seames as if we received a valid message */
-
- memcpy(pdp, pdp2, sizeof (struct pdp_t)); /* Update original pdp */
+ /* TFT (conditional) */
+ if (gtpie_gettlv(ie, GTPIE_TFT, 0, &pdp->tft.l,
+ &pdp->tft.v, sizeof(pdp->tft.v))) {
+ }
+
+ /* OMC identity */
+ }
/* Confirm to peer that things were "successful" */
- return gtp_update_pdp_resp(gsn, version, peer, pack, len, pdp,
+ return gtp_update_pdp_resp(gsn, version, peer, fd, pack, len, pdp,
GTPCAUSE_ACC_REQ);
}
@@ -1494,27 +1882,27 @@ int gtp_update_pdp_conf(struct gsn_t *gsn, int version,
struct pdp_t *pdp;
union gtpie_member *ie[GTPIE_SIZE];
uint8_t cause, recovery;
- void *aid = NULL;
+ void *cbp = NULL;
uint8_t type = 0;
/* Remove packet from queue */
- if (gtp_conf(gsn, 0, peer, pack, len, &type, &aid)) return EOF;
+ if (gtp_conf(gsn, 0, peer, pack, len, &type, &cbp)) return EOF;
/* Find the context in question */
if (pdp_getgtp0(&pdp, ntoh16(((union gtp_packet*)pack)->gtp0.h.flow))) {
gsn->err_unknownpdp++;
gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
"Unknown PDP context");
- if (gsn->cb_conf) gsn->cb_conf(type, cause, NULL, aid);
+ if (gsn->cb_conf) gsn->cb_conf(type, cause, NULL, cbp);
return EOF;
}
/* Decode information elements */
- if (gtpie_decaps(ie, pack+GTP0_HEADER_SIZE, len-GTP0_HEADER_SIZE)) {
+ if (gtpie_decaps(ie, 0, pack+GTP0_HEADER_SIZE, len-GTP0_HEADER_SIZE)) {
gsn->invalid++;
gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
"Invalid message format");
- if (gsn->cb_conf) gsn->cb_conf(type, EOF, pdp, aid);
+ if (gsn->cb_conf) gsn->cb_conf(type, EOF, pdp, cbp);
if (gsn->cb_delete_context) gsn->cb_delete_context(pdp);
pdp_freepdp(pdp);
return EOF;
@@ -1525,7 +1913,7 @@ int gtp_update_pdp_conf(struct gsn_t *gsn, int version,
gsn->missing++;
gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
"Missing mandatory information field");
- if (gsn->cb_conf) gsn->cb_conf(type, EOF, pdp, aid);
+ if (gsn->cb_conf) gsn->cb_conf(type, EOF, pdp, cbp);
if (gsn->cb_delete_context) gsn->cb_delete_context(pdp);
pdp_freepdp(pdp);
return EOF;
@@ -1538,7 +1926,7 @@ int gtp_update_pdp_conf(struct gsn_t *gsn, int version,
/* Check all conditional information elements */
if (GTPCAUSE_ACC_REQ != cause) {
- if (gsn->cb_conf) gsn->cb_conf(type, cause, pdp, aid);
+ if (gsn->cb_conf) gsn->cb_conf(type, cause, pdp, cbp);
if (gsn->cb_delete_context) gsn->cb_delete_context(pdp);
pdp_freepdp(pdp);
return 0;
@@ -1556,7 +1944,7 @@ int gtp_update_pdp_conf(struct gsn_t *gsn, int version,
gsn->missing++;
gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
"Missing conditional information field");
- if (gsn->cb_conf) gsn->cb_conf(type, EOF, pdp, aid);
+ if (gsn->cb_conf) gsn->cb_conf(type, EOF, pdp, cbp);
if (gsn->cb_delete_context) gsn->cb_delete_context(pdp);
pdp_freepdp(pdp);
return EOF;
@@ -1576,55 +1964,51 @@ int gtp_update_pdp_conf(struct gsn_t *gsn, int version,
gtpie_gettlv(ie, GTPIE_GSN_ADDR, 1, &pdp->gsnru.l,
&pdp->gsnru.v, sizeof(pdp->gsnru.v));
- if (gsn->cb_conf) gsn->cb_conf(type, cause, pdp, aid);
+ if (gsn->cb_conf) gsn->cb_conf(type, cause, pdp, cbp);
return 0; /* Succes */
}
}
-/* Send Delete PDP Context Request */
-extern int gtp_delete_pdp_req(struct gsn_t *gsn, int version, void *aid,
- struct pdp_t *pdp) {
+
+/* API: Send Delete PDP Context Request */
+int gtp_delete_context_req(struct gsn_t *gsn, struct pdp_t *pdp, void *cbp) {
union gtp_packet packet;
- int length = 0;
+ int length = get_default_gtp(pdp->version, GTP_CREATE_PDP_REQ, &packet);
struct in_addr addr;
-
+
if (gsna2in_addr(&addr, &pdp->gsnrc)) {
gsn->err_address++;
gtp_err(LOG_ERR, __FILE__, __LINE__, "GSN address conversion failed");
return EOF;
}
+
+ if (pdp->version == 1) {
+ gtpie_tv1(&packet, &length, GTP_MAX, GTPIE_NSAPI,
+ pdp->nsapi);
- get_default_gtp(0, &packet);
-
- packet.gtp0.h.type = hton8(GTP_DELETE_PDP_REQ);
- packet.gtp0.h.length = hton16(length);
- packet.gtp0.h.flow = hton16(pdp->flrc);
- packet.gtp0.h.tid = (pdp->imsi & 0x0fffffffffffffff) + ((uint64_t)pdp->nsapi << 60);
+ gtpie_tv1(&packet, &length, GTP_MAX, GTPIE_TEARDOWN,
+ 0xff);
+ }
- return gtp_req(gsn, 0, &packet, GTP0_HEADER_SIZE+length, &addr, aid);
+ get_default_gtp(pdp->version, GTP_DELETE_PDP_REQ, &packet);
+
+ return gtp_req(gsn, pdp->version, pdp, &packet, length, &addr, cbp);
}
+
/* Send Delete PDP Context Response */
int gtp_delete_pdp_resp(struct gsn_t *gsn, int version,
- struct sockaddr_in *peer,
+ struct sockaddr_in *peer, int fd,
void *pack, unsigned len,
struct pdp_t *pdp, uint8_t cause)
{
union gtp_packet packet;
- int length = 0;
- uint16_t flow = 0;
-
- if (pdp) flow = hton16(pdp->flrc);
-
- get_default_gtp(0, &packet);
+ int length = get_default_gtp(version, GTP_DELETE_PDP_RSP, &packet);
- gtpie_tv1(packet.gtp0.p, &length, GTP_MAX, GTPIE_CAUSE, cause);
+ gtpie_tv1(&packet, &length, GTP_MAX, GTPIE_CAUSE, cause);
- packet.gtp0.h.type = hton8(GTP_DELETE_PDP_RSP);
- packet.gtp0.h.length = hton16(length);
- packet.gtp0.h.flow = flow;
- packet.gtp0.h.seq = ((union gtp_packet*)pack)->gtp0.h.seq;
- packet.gtp0.h.tid = ((union gtp_packet*)pack)->gtp0.h.tid;
+ gtp_resp(version, gsn, pdp, &packet, length, peer, fd,
+ get_seq(pack),get_tid(pack));
if (pdp) {
/* Callback function to allow application to clean up */
@@ -1632,47 +2016,74 @@ int gtp_delete_pdp_resp(struct gsn_t *gsn, int version,
pdp_freepdp(pdp); /* Clean up PDP context */
}
- return gtp_resp(0, gsn, &packet, GTP0_HEADER_SIZE+length, peer);
+ return 0;
}
/* Handle Delete PDP Context Request */
int gtp_delete_pdp_ind(struct gsn_t *gsn, int version,
- struct sockaddr_in *peer, void *pack, unsigned len) {
- struct pdp_t *pdp;
+ struct sockaddr_in *peer, int fd,
+ void *pack, unsigned len) {
+ struct pdp_t *pdp;
union gtpie_member* ie[GTPIE_SIZE];
- uint16_t seq = ntoh16(((union gtp_packet*)pack)->gtp0.h.seq);
+
+ uint16_t seq = get_seq(pack);
+ int hlen = get_hlen(pack);
+ uint8_t nsapi;
+ uint8_t teardown;
+
/* Is this a dublicate ? */
- if(!gtp_dublicate(gsn, 0, peer, seq)) {
- return 0;
+ if(!gtp_dublicate(gsn, version, peer, seq)) {
+ return 0; /* We allready send off response once */
}
- /* Find the pdp context in question */
- if (pdp_getgtp0(&pdp, ntoh16(((union gtp_packet*)pack)->gtp0.h.flow))) {
+ /* Find the context in question */
+ if (pdp_getgtp1(&pdp, get_tei(pack))) {
gsn->err_unknownpdp++;
gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
"Unknown PDP context");
- if (0 == version)
- return gtp_delete_pdp_resp(gsn, version, peer, pack, len, NULL,
- GTPCAUSE_ACC_REQ);
- else
- return gtp_delete_pdp_resp(gsn, version, peer, pack, len, NULL,
- GTPCAUSE_NON_EXIST);
+ return gtp_delete_pdp_resp(gsn, version, peer, fd, pack, len,
+ NULL, GTPCAUSE_NON_EXIST);
}
/* Decode information elements */
- if (gtpie_decaps(ie, pack+GTP0_HEADER_SIZE, len-GTP0_HEADER_SIZE)) {
+ if (gtpie_decaps(ie, version, pack+hlen, len-hlen)) {
gsn->invalid++;
gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
"Invalid message format");
if (0 == version)
return EOF;
else
- return gtp_delete_pdp_resp(gsn, version, peer, pack, len, pdp,
- GTPCAUSE_INVALID_MESSAGE);
+ return gtp_delete_pdp_resp(gsn, version, peer, fd, pack, len,
+ NULL, GTPCAUSE_INVALID_MESSAGE);
}
- return gtp_delete_pdp_resp(gsn, version, peer, pack, len, pdp,
+ if (version == 1) {
+ /* NSAPI (mandatory) */
+ if (gtpie_gettv1(ie, GTPIE_NSAPI, 0, &nsapi)) {
+ gsn->missing++;
+ gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
+ "Missing mandatory information field");
+ return gtp_delete_pdp_resp(gsn, version, peer, fd, pack, len,
+ NULL, GTPCAUSE_MAN_IE_MISSING);
+ }
+
+ /* TODO: When multiple contexts with the same IP address exists
+ we need to tear down each one individually or as a group depending
+ on the value of teardown */
+
+ /* Teardown (conditional) */
+ if (gtpie_gettv1(ie, GTPIE_TEARDOWN, 0, &teardown)) {
+ return 0; /* 29.060 7.3.5 Ignore message */
+ /* gsn->missing++;
+ gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
+ "Missing mandatory information field");
+ return gtp_delete_pdp_resp(gsn, version, peer, fd, pack, len,
+ NULL, GTPCAUSE_MAN_IE_MISSING); */
+ }
+ }
+
+ return gtp_delete_pdp_resp(gsn, version, peer, fd, pack, len, pdp,
GTPCAUSE_ACC_REQ);
}
@@ -1684,33 +2095,37 @@ int gtp_delete_pdp_conf(struct gsn_t *gsn, int version,
struct pdp_t *pdp;
union gtpie_member *ie[GTPIE_SIZE];
uint8_t cause;
- void *aid = NULL;
+ void *cbp = NULL;
uint8_t type = 0;
-
+ int hlen = get_hlen(pack);
+
/* Remove packet from queue */
- if (gtp_conf(gsn, 0, peer, pack, len, &type, &aid)) return EOF;
+ if (gtp_conf(gsn, version, peer, pack, len, &type, &cbp)) return EOF;
/* Find the context in question */
- if (pdp_getgtp0(&pdp, ntoh16(((union gtp_packet*)pack)->gtp0.h.flow))) {
+ if (pdp_getgtp1(&pdp, get_tei(pack))) {
gsn->err_unknownpdp++;
gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
"Unknown PDP context");
+ if (gsn->cb_conf) gsn->cb_conf(type, EOF, NULL, cbp);
return EOF;
}
/* Decode information elements */
- if (gtpie_decaps(ie, pack+GTP0_HEADER_SIZE, len-GTP0_HEADER_SIZE)) {
+ if (gtpie_decaps(ie, version, pack+hlen, len-hlen)) {
gsn->invalid++;
gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
"Invalid message format");
+ if (gsn->cb_conf) gsn->cb_conf(type, EOF, pdp, cbp);
return EOF;
}
- /* Extract cause value */
+ /* Extract cause value (mandatory) */
if (gtpie_gettv1(ie, GTPIE_CAUSE, 0, &cause)) {
gsn->missing++;
gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
"Missing mandatory information field");
+ if (gsn->cb_conf) gsn->cb_conf(type, EOF, pdp, cbp);
return EOF;
}
@@ -1719,12 +2134,12 @@ int gtp_delete_pdp_conf(struct gsn_t *gsn, int version,
gsn->err_cause++;
gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
"Unexpected cause value received: %d", cause);
- return EOF;
}
- /* Callback function to allow application to clean up */
- if (gsn->cb_conf) gsn->cb_conf(type, cause, pdp, aid);
+ /* Callback function to notify application */
+ if (gsn->cb_conf) gsn->cb_conf(type, cause, pdp, cbp);
+ /* Callback function to allow application to clean up */
if (gsn->cb_delete_context) gsn->cb_delete_context(pdp);
pdp_freepdp(pdp);
@@ -1733,21 +2148,14 @@ int gtp_delete_pdp_conf(struct gsn_t *gsn, int version,
/* Send Error Indication (response to a GPDU message */
int gtp_error_ind_resp(struct gsn_t *gsn, int version,
- struct sockaddr_in *peer,
+ struct sockaddr_in *peer, int fd,
void *pack, unsigned len)
{
union gtp_packet packet;
- int length = 0;
-
- get_default_gtp(0, &packet);
+ int length = get_default_gtp(version, GTP_ERROR, &packet);
- packet.gtp0.h.type = hton8(GTP_ERROR);
- packet.gtp0.h.length = hton16(length);
- packet.gtp0.h.flow = 0;
- packet.gtp0.h.seq = ((union gtp_packet*)pack)->gtp0.h.seq;
- packet.gtp0.h.tid = ((union gtp_packet*)pack)->gtp0.h.tid;
-
- return gtp_resp(0, gsn, &packet, GTP0_HEADER_SIZE+length, peer);
+ return gtp_resp(version, gsn, NULL, &packet, length, peer, fd,
+ get_seq(pack), get_tid(pack));
}
/* Handle Error Indication */
@@ -1774,78 +2182,93 @@ int gtp_error_ind_conf(struct gsn_t *gsn, int version,
}
int gtp_gpdu_ind(struct gsn_t *gsn, int version,
- struct sockaddr_in *peer,
- void *pack,
- unsigned len) {
+ struct sockaddr_in *peer, int fd,
+ void *pack, unsigned len) {
+
+ int hlen = GTP1_HEADER_SIZE_SHORT;
/* Need to include code to verify packet src and dest addresses */
struct pdp_t *pdp;
-
- if (pdp_getgtp0(&pdp, ntoh16(((union gtp_packet*)pack)->gtp0.h.flow))) {
- gsn->err_unknownpdp++;
- gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
- "Unknown PDP context");
- return gtp_error_ind_resp(gsn, version, peer, pack, len);
-
+
+ if (version == 0) {
+ if (pdp_getgtp0(&pdp, ntoh16(((union gtp_packet*)pack)->gtp0.h.flow))) {
+ gsn->err_unknownpdp++;
+ gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
+ "Unknown PDP context");
+ return gtp_error_ind_resp(gsn, version, peer, fd, pack, len);
+ }
+ hlen = GTP0_HEADER_SIZE;
}
+ else if (version == 1) {
+ if (pdp_getgtp1(&pdp, ntoh32(((union gtp_packet*)pack)->gtp1l.h.tei))) {
+ gsn->err_unknownpdp++;
+ gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
+ "Unknown PDP context");
+ return gtp_error_ind_resp(gsn, version, peer, fd, pack, len);
+ }
+ /* Is this a long or a short header ? */
+ if (((union gtp_packet*)pack)->gtp1l.h.flags & 0x07)
+ hlen = GTP1_HEADER_SIZE_LONG;
+ else
+ hlen = GTP1_HEADER_SIZE_SHORT;
+ }
+ else {
+ gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
+ "Unknown version");
+ }
+
/* If the GPDU was not from the peer GSN tell him to delete context */
if (memcmp(&peer->sin_addr, pdp->gsnru.v, pdp->gsnru.l)) { /* TODO Range? */
gsn->err_unknownpdp++;
gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
"Unknown PDP context");
- return gtp_error_ind_resp(gsn, version, peer, pack, len);
+ return gtp_error_ind_resp(gsn, version, peer, fd, pack, len);
}
-
+
/* Callback function */
- if (gsn->cb_gpdu !=0)
- return gsn->cb_gpdu(pdp, pack+20, len-20); /* TODO ???? */
+ if (gsn->cb_data_ind !=0)
+ return gsn->cb_data_ind(pdp, pack+hlen, len-hlen);
return 0;
}
+
/* Receives GTP packet and sends off for further processing
* Function will check the validity of the header. If the header
* is not valid the packet is either dropped or a version not
* supported is returned to the peer.
* TODO: Need to decide on return values! */
-int gtp_decaps(struct gsn_t *gsn)
+int gtp_decaps0(struct gsn_t *gsn)
{
unsigned char buffer[PACKET_MAX + 64 /*TODO: ip header */ ];
- int status, ip_len = 0;
struct sockaddr_in peer;
int peerlen;
+ int status;
struct gtp0_header *pheader;
int version = 0; /* GTP version should be determined from header!*/
+ int fd = gsn->fd0;
/* TODO: Need strategy of userspace buffering and blocking */
/* Currently read is non-blocking and send is blocking. */
/* This means that the program have to wait for busy send calls...*/
while (1) { /* Loop until no more to read */
- if (fcntl(gsn->fd, F_SETFL, O_NONBLOCK)) {
+ if (fcntl(gsn->fd0, F_SETFL, O_NONBLOCK)) {
gtp_err(LOG_ERR, __FILE__, __LINE__, "fnctl()");
return -1;
}
peerlen = sizeof(peer);
if ((status =
- recvfrom(gsn->fd, buffer, sizeof(buffer), 0,
+ recvfrom(gsn->fd0, buffer, sizeof(buffer), 0,
(struct sockaddr *) &peer, &peerlen)) < 0 ) {
- if (errno == EAGAIN) return -1;
+ if (errno == EAGAIN) return 0;
gsn->err_readfrom++;
- gtp_err(LOG_ERR, __FILE__, __LINE__, "recvfrom(fd=%d, buffer=%lx, len=%d) failed: status = %d error = %s", gsn->fd, (unsigned long) buffer, sizeof(buffer), status, status ? strerror(errno) : "No error");
+ gtp_err(LOG_ERR, __FILE__, __LINE__, "recvfrom(fd0=%d, buffer=%lx, len=%d) failed: status = %d error = %s", gsn->fd0, (unsigned long) buffer, sizeof(buffer), status, status ? strerror(errno) : "No error");
return -1;
}
- /* Strip off IP header, if present: TODO Is this nessesary? */
- if ((buffer[0] & 0xF0) == 0x40) {
- ip_len = (buffer[0] & 0xF) * 4;
- gtp_errpack(LOG_ERR, __FILE__, __LINE__, &peer, buffer, status,
- "IP header found in return from read");
- continue;
- }
-
/* Need at least 1 byte in order to check version */
if (status < (1)) {
gsn->empty++;
@@ -1854,30 +2277,37 @@ int gtp_decaps(struct gsn_t *gsn)
continue;
}
- /* TODO: Remove these ERROR MESSAGES
- gtp_err(LOG_ERR, __FILE__, __LINE__, "Discarding packet - too small");
- gtp_errpack(LOG_ERR, __FILE__, __LINE__, &peer, buffer, status,
- "Discarding packet - too small"); */
-
- pheader = (struct gtp0_header *) (buffer + ip_len);
+ pheader = (struct gtp0_header *) (buffer);
- /* Version should be gtp0 (or earlier in theory) */
+ /* Version should be gtp0 (or earlier) */
+ /* 09.60 is somewhat unclear on this issue. On gsn->fd0 we expect only */
+ /* GTP 0 messages. If other version message is received we reply that we */
+ /* only support version 0, implying that this is the only version */
+ /* supported on this port */
if (((pheader->flags & 0xe0) > 0x00)) {
gsn->unsup++;
gtp_errpack(LOG_ERR, __FILE__, __LINE__, &peer, buffer, status,
"Unsupported GTP version");
- gtp_unsup_resp(gsn, &peer, buffer, status); /* 29.60: 11.1.1 */
+ gtp_unsup_req(gsn, 0, &peer, gsn->fd0, buffer, status); /* 29.60: 11.1.1 */
continue;
}
/* Check length of gtp0 packet */
- if (((pheader->flags & 0xe0) == 0x00) && (status < GTP0_HEADER_SIZE)) {
+ if (status < GTP0_HEADER_SIZE) {
gsn->tooshort++;
gtp_errpack(LOG_ERR, __FILE__, __LINE__, &peer, buffer, status,
"GTP0 packet too short");
continue; /* Silently discard 29.60: 11.1.2 */
}
+ /* Check packet length field versus length of packet */
+ if (status != (ntoh16(pheader->length) + GTP0_HEADER_SIZE)) {
+ gsn->tooshort++;
+ gtp_errpack(LOG_ERR, __FILE__, __LINE__, &peer, buffer, status,
+ "GTP packet length field does not match actual length");
+ continue; /* Silently discard */
+ }
+
if ((gsn->mode == GTP_MODE_GGSN) &&
((pheader->type == GTP_CREATE_PDP_RSP) ||
(pheader->type == GTP_UPDATE_PDP_RSP) ||
@@ -1898,48 +2328,289 @@ int gtp_decaps(struct gsn_t *gsn)
continue; /* Silently discard 29.60: 11.1.4 */
}
+ switch (pheader->type) {
+ case GTP_ECHO_REQ:
+ gtp_echo_ind(gsn, version, &peer, fd, buffer, status);
+ break;
+ case GTP_ECHO_RSP:
+ gtp_echo_conf(gsn, version, &peer, buffer, status);
+ break;
+ case GTP_NOT_SUPPORTED:
+ gtp_unsup_ind(gsn, &peer, buffer, status);
+ break;
+ case GTP_CREATE_PDP_REQ:
+ gtp_create_pdp_ind(gsn, version, &peer, fd, buffer, status);
+ break;
+ case GTP_CREATE_PDP_RSP:
+ gtp_create_pdp_conf(gsn, version, &peer, buffer, status);
+ break;
+ case GTP_UPDATE_PDP_REQ:
+ gtp_update_pdp_ind(gsn, version, &peer, fd, buffer, status);
+ break;
+ case GTP_UPDATE_PDP_RSP:
+ gtp_update_pdp_conf(gsn, version, &peer, buffer, status);
+ break;
+ case GTP_DELETE_PDP_REQ:
+ gtp_delete_pdp_ind(gsn, version, &peer, fd, buffer, status);
+ break;
+ case GTP_DELETE_PDP_RSP:
+ gtp_delete_pdp_conf(gsn, version, &peer, buffer, status);
+ break;
+ case GTP_ERROR:
+ gtp_error_ind_conf(gsn, version, &peer, buffer, status);
+ break;
+ case GTP_GPDU:
+ gtp_gpdu_ind(gsn, version, &peer, fd, buffer, status);
+ break;
+ default:
+ gsn->unknown++;
+ gtp_errpack(LOG_ERR, __FILE__, __LINE__, &peer, buffer, status,
+ "Unknown GTP message type received");
+ break;
+ }
+ }
+}
+
+int gtp_decaps1c(struct gsn_t *gsn)
+{
+ unsigned char buffer[PACKET_MAX + 64 /*TODO: ip header */ ];
+ struct sockaddr_in peer;
+ int peerlen;
+ int status;
+ struct gtp1_header_short *pheader;
+ int version = 1; /* GTP version should be determined from header!*/
+ int fd = gsn->fd1c;
+
+ /* TODO: Need strategy of userspace buffering and blocking */
+ /* Currently read is non-blocking and send is blocking. */
+ /* This means that the program have to wait for busy send calls...*/
+
+ while (1) { /* Loop until no more to read */
+ if (fcntl(gsn->fd1c, F_SETFL, O_NONBLOCK)) {
+ gtp_err(LOG_ERR, __FILE__, __LINE__, "fnctl()");
+ return -1;
+ }
+ peerlen = sizeof(peer);
+ if ((status =
+ recvfrom(gsn->fd1c, buffer, sizeof(buffer), 0,
+ (struct sockaddr *) &peer, &peerlen)) < 0 ) {
+ if (errno == EAGAIN) return 0;
+ gsn->err_readfrom++;
+ gtp_err(LOG_ERR, __FILE__, __LINE__, "recvfrom(fd1c=%d, buffer=%lx, len=%d) failed: status = %d error = %s", gsn->fd1c, (unsigned long) buffer, sizeof(buffer), status, status ? strerror(errno) : "No error");
+ return -1;
+ }
+
+ /* Need at least 1 byte in order to check version */
+ if (status < (1)) {
+ gsn->empty++;
+ gtp_errpack(LOG_ERR, __FILE__, __LINE__, &peer, buffer, status,
+ "Discarding packet - too small");
+ continue;
+ }
+
+ pheader = (struct gtp1_header_short *) (buffer);
+ /* Version must be no larger than GTP 1 */
+ if (((pheader->flags & 0xe0) > 0x20)) {
+ gsn->unsup++;
+ gtp_errpack(LOG_ERR, __FILE__, __LINE__, &peer, buffer, status,
+ "Unsupported GTP version");
+ gtp_unsup_req(gsn, 1, &peer, gsn->fd1c, buffer, status);/*29.60: 11.1.1*/
+ continue;
+ }
+
+ /* Version must be at least GTP 1 */
+ /* 29.060 is somewhat unclear on this issue. On gsn->fd1c we expect only */
+ /* GTP 1 messages. If GTP 0 message is received we silently discard */
+ /* the message */
+ if (((pheader->flags & 0xe0) < 0x20)) {
+ gsn->unsup++;
+ gtp_errpack(LOG_ERR, __FILE__, __LINE__, &peer, buffer, status,
+ "Unsupported GTP version");
+ continue;
+ }
+
+ /* Check packet flag field */
+ if (((pheader->flags & 0xf7) != 0x32)) {
+ gsn->unsup++;
+ gtp_errpack(LOG_ERR, __FILE__, __LINE__, &peer, buffer, status,
+ "Unsupported packet flag");
+ continue;
+ }
+
+ /* Check length of packet */
+ if (status < GTP1_HEADER_SIZE_LONG) {
+ gsn->tooshort++;
+ gtp_errpack(LOG_ERR, __FILE__, __LINE__, &peer, buffer, status,
+ "GTP packet too short");
+ continue; /* Silently discard 29.60: 11.1.2 */
+ }
+
+ /* Check packet length field versus length of packet */
+ if (status != (ntoh16(pheader->length) + GTP1_HEADER_SIZE_SHORT)) {
+ gsn->tooshort++;
+ gtp_errpack(LOG_ERR, __FILE__, __LINE__, &peer, buffer, status,
+ "GTP packet length field does not match actual length");
+ continue; /* Silently discard */
+ }
+
+ if ((gsn->mode == GTP_MODE_GGSN) &&
+ ((pheader->type == GTP_CREATE_PDP_RSP) ||
+ (pheader->type == GTP_UPDATE_PDP_RSP) ||
+ (pheader->type == GTP_DELETE_PDP_RSP))) {
+ gsn->unexpect++;
+ gtp_errpack(LOG_ERR, __FILE__, __LINE__, &peer, buffer, status,
+ "Unexpected GTP Signalling Message");
+ continue; /* Silently discard 29.60: 11.1.4 */
+ }
+
+ if ((gsn->mode == GTP_MODE_SGSN) &&
+ ((pheader->type == GTP_CREATE_PDP_REQ) ||
+ (pheader->type == GTP_UPDATE_PDP_REQ) ||
+ (pheader->type == GTP_DELETE_PDP_REQ))) {
+ gsn->unexpect++;
+ gtp_errpack(LOG_ERR, __FILE__, __LINE__, &peer, buffer, status,
+ "Unexpected GTP Signalling Message");
+ continue; /* Silently discard 29.60: 11.1.4 */
+ }
+
switch (pheader->type) {
case GTP_ECHO_REQ:
- gtp_echo_ind(gsn, &peer, buffer+ip_len, status - ip_len);
+ gtp_echo_ind(gsn, version, &peer, fd, buffer, status);
break;
case GTP_ECHO_RSP:
- gtp_echo_conf(gsn, &peer, buffer+ip_len, status - ip_len);
+ gtp_echo_conf(gsn, version, &peer, buffer, status);
break;
case GTP_NOT_SUPPORTED:
- gtp_unsup_conf(gsn, &peer, buffer+ip_len, status - ip_len);
+ gtp_unsup_ind(gsn, &peer, buffer, status);
break;
case GTP_CREATE_PDP_REQ:
- gtp_create_pdp_ind(gsn, version, &peer, buffer+ip_len,
- status - ip_len);
+ gtp_create_pdp_ind(gsn, version, &peer, fd, buffer, status);
break;
case GTP_CREATE_PDP_RSP:
- gtp_create_pdp_conf(gsn, version, &peer, buffer+ip_len,
- status - ip_len);
+ gtp_create_pdp_conf(gsn, version, &peer, buffer, status);
break;
case GTP_UPDATE_PDP_REQ:
- gtp_update_pdp_ind(gsn, version, &peer, buffer+ip_len,
- status - ip_len);
+ gtp_update_pdp_ind(gsn, version, &peer, fd, buffer, status);
break;
case GTP_UPDATE_PDP_RSP:
- gtp_update_pdp_conf(gsn, version, &peer, buffer+ip_len,
- status - ip_len);
+ gtp_update_pdp_conf(gsn, version, &peer, buffer, status);
break;
case GTP_DELETE_PDP_REQ:
- gtp_delete_pdp_ind(gsn, version, &peer, buffer+ip_len,
- status - ip_len);
+ gtp_delete_pdp_ind(gsn, version, &peer, fd, buffer, status);
break;
case GTP_DELETE_PDP_RSP:
- gtp_delete_pdp_conf(gsn, version, &peer, buffer+ip_len,
- status - ip_len);
+ gtp_delete_pdp_conf(gsn, version, &peer, buffer, status);
break;
case GTP_ERROR:
- gtp_error_ind_conf(gsn, version, &peer, buffer+ip_len,
- status - ip_len);
+ gtp_error_ind_conf(gsn, version, &peer, buffer, status);
+ break;
+ default:
+ gsn->unknown++;
+ gtp_errpack(LOG_ERR, __FILE__, __LINE__, &peer, buffer, status,
+ "Unknown GTP message type received");
break;
+ }
+ }
+}
+
+int gtp_decaps1u(struct gsn_t *gsn)
+{
+ unsigned char buffer[PACKET_MAX + 64 /*TODO: ip header */ ];
+ struct sockaddr_in peer;
+ int peerlen;
+ int status;
+ struct gtp1_header_short *pheader;
+ int version = 1; /* GTP version should be determined from header!*/
+ int fd = gsn->fd1u;
+
+ /* TODO: Need strategy of userspace buffering and blocking */
+ /* Currently read is non-blocking and send is blocking. */
+ /* This means that the program have to wait for busy send calls...*/
+
+ while (1) { /* Loop until no more to read */
+ if (fcntl(gsn->fd1u, F_SETFL, O_NONBLOCK)) {
+ gtp_err(LOG_ERR, __FILE__, __LINE__, "fnctl()");
+ return -1;
+ }
+ peerlen = sizeof(peer);
+ if ((status =
+ recvfrom(gsn->fd1u, buffer, sizeof(buffer), 0,
+ (struct sockaddr *) &peer, &peerlen)) < 0 ) {
+ if (errno == EAGAIN) return 0;
+ gsn->err_readfrom++;
+ gtp_err(LOG_ERR, __FILE__, __LINE__, "recvfrom(fd1u=%d, buffer=%lx, len=%d) failed: status = %d error = %s", gsn->fd1u, (unsigned long) buffer, sizeof(buffer), status, status ? strerror(errno) : "No error");
+ return -1;
+ }
+
+ /* Need at least 1 byte in order to check version */
+ if (status < (1)) {
+ gsn->empty++;
+ gtp_errpack(LOG_ERR, __FILE__, __LINE__, &peer, buffer, status,
+ "Discarding packet - too small");
+ continue;
+ }
+
+ pheader = (struct gtp1_header_short *) (buffer);
+
+ /* Version must be no larger than GTP 1 */
+ if (((pheader->flags & 0xe0) > 0x20)) {
+ gsn->unsup++;
+ gtp_errpack(LOG_ERR, __FILE__, __LINE__, &peer, buffer, status,
+ "Unsupported GTP version");
+ gtp_unsup_req(gsn, 1, &peer, gsn->fd1c, buffer, status);/*29.60: 11.1.1*/
+ continue;
+ }
+
+ /* Version must be at least GTP 1 */
+ /* 29.060 is somewhat unclear on this issue. On gsn->fd1c we expect only */
+ /* GTP 1 messages. If GTP 0 message is received we silently discard */
+ /* the message */
+ if (((pheader->flags & 0xe0) < 0x20)) {
+ gsn->unsup++;
+ gtp_errpack(LOG_ERR, __FILE__, __LINE__, &peer, buffer, status,
+ "Unsupported GTP version");
+ continue;
+ }
+
+ /* Check packet flag field (allow both with and without sequence number)*/
+ if (((pheader->flags & 0xf5) != 0x30)) {
+ gsn->unsup++;
+ gtp_errpack(LOG_ERR, __FILE__, __LINE__, &peer, buffer, status,
+ "Unsupported packet flag");
+ continue;
+ }
+
+ /* Check length of packet */
+ if (status < GTP1_HEADER_SIZE_SHORT) {
+ gsn->tooshort++;
+ gtp_errpack(LOG_ERR, __FILE__, __LINE__, &peer, buffer, status,
+ "GTP packet too short");
+ continue; /* Silently discard 29.60: 11.1.2 */
+ }
+
+ /* Check packet length field versus length of packet */
+ if (status != (ntoh16(pheader->length) + GTP1_HEADER_SIZE_SHORT)) {
+ gsn->tooshort++;
+ gtp_errpack(LOG_ERR, __FILE__, __LINE__, &peer, buffer, status,
+ "GTP packet length field does not match actual length");
+ continue; /* Silently discard */
+ }
+
+ switch (pheader->type) {
+ case GTP_ECHO_REQ:
+ gtp_echo_ind(gsn, version, &peer, fd, buffer, status);
+ break;
+ case GTP_ECHO_RSP:
+ gtp_echo_conf(gsn, version, &peer, buffer, status);
+ break;
+ case GTP_ERROR:
+ gtp_error_ind_conf(gsn, version, &peer, buffer, status);
+ break;
+ /* Supported header extensions */
case GTP_GPDU:
- gtp_gpdu_ind(gsn, version, &peer, buffer+ip_len, status - ip_len);
+ gtp_gpdu_ind(gsn, version, &peer, fd, buffer, status);
break;
default:
gsn->unknown++;
@@ -1950,46 +2621,72 @@ int gtp_decaps(struct gsn_t *gsn)
}
}
-int gtp_gpdu(struct gsn_t *gsn, struct pdp_t* pdp,
+int gtp_data_req(struct gsn_t *gsn, struct pdp_t* pdp,
void *pack, unsigned len)
{
union gtp_packet packet;
struct sockaddr_in addr;
-
- /*printf("gtp_encaps start\n");
- print_packet(pack, len);*/
+ int fd;
+ int length;
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
-
memcpy(&addr.sin_addr, pdp->gsnru.v,pdp->gsnru.l); /* TODO range check */
- addr.sin_port = htons(GTP0_PORT);
- get_default_gtp(0, &packet);
- packet.gtp0.h.type = hton8(GTP_GPDU);
- packet.gtp0.h.length = hton16(len);
- packet.gtp0.h.seq = hton16(pdp->gtpsntx++);
- packet.gtp0.h.flow = hton16(pdp->flru);
- packet.gtp0.h.tid = (pdp->imsi & 0x0fffffffffffffff) + ((uint64_t)pdp->nsapi << 60);
-
- if (len > sizeof (union gtp_packet) - sizeof(struct gtp0_header)) {
- gsn->err_memcpy++;
+ if (pdp->version == 0) {
+
+ length = GTP0_HEADER_SIZE+len;
+ addr.sin_port = htons(GTP0_PORT);
+ fd = gsn->fd0;
+
+ get_default_gtp(0, GTP_GPDU, &packet);
+ packet.gtp0.h.length = hton16(len);
+ packet.gtp0.h.seq = hton16(pdp->gtpsntx++);
+ packet.gtp0.h.flow = hton16(pdp->flru);
+ packet.gtp0.h.tid = (pdp->imsi & 0x0fffffffffffffff) + ((uint64_t)pdp->nsapi << 60);
+
+ if (len > sizeof (union gtp_packet) - sizeof(struct gtp0_header)) {
+ gsn->err_memcpy++;
+ gtp_err(LOG_ERR, __FILE__, __LINE__,
+ "Memcpy failed");
+ return EOF;
+ }
+ memcpy(packet.gtp0.p, pack, len); /* TODO Should be avoided! */
+ }
+ else if (pdp->version == 1) {
+
+ length = GTP1_HEADER_SIZE_LONG+len;
+ addr.sin_port = htons(GTP1U_PORT);
+ fd = gsn->fd1u;
+
+ get_default_gtp(1, GTP_GPDU, &packet);
+ packet.gtp1l.h.length = hton16(len-GTP1_HEADER_SIZE_SHORT+
+ GTP1_HEADER_SIZE_LONG);
+ packet.gtp1l.h.seq = hton16(pdp->gtpsntx++);
+
+ if (len > sizeof (union gtp_packet) - sizeof(struct gtp1_header_long)) {
+ gsn->err_memcpy++;
+ gtp_err(LOG_ERR, __FILE__, __LINE__,
+ "Memcpy failed");
+ return EOF;
+ }
+ memcpy(packet.gtp1l.p, pack, len); /* TODO Should be avoided! */
+ }
+ else {
gtp_err(LOG_ERR, __FILE__, __LINE__,
- "Memcpy failed");
+ "Unknown version");
return EOF;
- }
+ }
- if (fcntl(gsn->fd, F_SETFL, 0)) {
+ if (fcntl(fd, F_SETFL, 0)) {
gtp_err(LOG_ERR, __FILE__, __LINE__, "fnctl()");
return -1;
}
- memcpy(packet.gtp0.p, pack, len); /* TODO Should be avoided! */
-
- if (sendto(gsn->fd, &packet, GTP0_HEADER_SIZE+len, 0,
+ if (sendto(fd, &packet, length, 0,
(struct sockaddr *) &addr, sizeof(addr)) < 0) {
gsn->err_sendto++;
- gtp_err(LOG_ERR, __FILE__, __LINE__, "Sendto(fd=%d, msg=%lx, len=%d) failed: Error = %s", gsn->fd, (unsigned long) &packet, GTP0_HEADER_SIZE+len, strerror(errno));
+ gtp_err(LOG_ERR, __FILE__, __LINE__, "Sendto(fd=%d, msg=%lx, len=%d) failed: Error = %s", fd, (unsigned long) &packet, GTP0_HEADER_SIZE+len, strerror(errno));
return EOF;
}
return 0;
diff --git a/gtp/gtp.h b/gtp/gtp.h
index d21cbb4..123339b 100644
--- a/gtp/gtp.h
+++ b/gtp/gtp.h
@@ -89,6 +89,55 @@
/* 242-254 For future use. */
#define GTP_GPDU 255 /* G-PDU */
+
+/* GTP information element cause codes from 29.060 v3.9.0 7.7 */
+/* */
+#define GTPCAUSE_REQ_IMSI 0 /* Request IMSI */
+#define GTPCAUSE_REQ_IMEI 1 /* Request IMEI */
+#define GTPCAUSE_REQ_IMSI_IMEI 2 /* Request IMSI and IMEI */
+#define GTPCAUSE_NO_ID_NEEDED 3 /* No identity needed */
+#define GTPCAUSE_MS_REFUSES_X 4 /* MS refuses */
+#define GTPCAUSE_MS_NOT_RESP_X 5 /* MS is not GPRS responding */
+#define GTPCAUSE_006 6 /* For future use 6-48 */
+#define GTPCAUSE_049 49 /* Cause values reserved for GPRS charging protocol use (See GTP' in GSM 12.15) 49-63 */
+#define GTPCAUSE_064 64 /* For future use 64-127 */
+#define GTPCAUSE_ACC_REQ 128 /* Request accepted */
+#define GTPCAUSE_129 129 /* For future use 129-176 */
+#define GTPCAUSE_177 177 /* Cause values reserved for GPRS charging protocol use (See GTP' In GSM 12.15) 177-191 */
+#define GTPCAUSE_NON_EXIST 192 /* Non-existent */
+#define GTPCAUSE_INVALID_MESSAGE 193 /* Invalid message format */
+#define GTPCAUSE_IMSI_NOT_KNOWN 194 /* IMSI not known */
+#define GTPCAUSE_MS_DETACHED 195 /* MS is GPRS detached */
+#define GTPCAUSE_MS_NOT_RESP 196 /* MS is not GPRS responding */
+#define GTPCAUSE_MS_REFUSES 197 /* MS refuses */
+#define GTPCAUSE_198 198 /* For future use */
+#define GTPCAUSE_NO_RESOURCES 199 /* No resources available */
+#define GTPCAUSE_NOT_SUPPORTED 200 /* Service not supported */
+#define GTPCAUSE_MAN_IE_INCORRECT 201 /* Mandatory IE incorrect */
+#define GTPCAUSE_MAN_IE_MISSING 202 /* Mandatory IE missing */
+#define GTPCAUSE_OPT_IE_INCORRECT 203 /* Optional IE incorrect */
+#define GTPCAUSE_SYS_FAIL 204 /* System failure */
+#define GTPCAUSE_ROAMING_REST 205 /* Roaming Restriction */
+#define GTPCAUSE_PTIMSI_MISMATCH 206 /* P-TMSI signature mismatch */
+#define GTPCAUSE_CONN_SUSP 207 /* GPRS connection suspended */
+#define GTPCAUSE_AUTH_FAIL 208 /* Authentication failure */
+#define GTPCAUSE_USER_AUTH_FAIL 209 /* User authentication failed */
+#define GTPCAUSE_CONTEXT_NOT_FOUND 210 /* Context not found */
+#define GTPCAUSE_ADDR_OCCUPIED 211 /* All dynamic PDP addresses are occupied */
+#define GTPCAUSE_NO_MEMORY 212 /* No memory is available */
+#define GTPCAUSE_RELOC_FAIL 213 /* Relocation failure */
+#define GTPCAUSE_UNKNOWN_MAN_EXTHEADER 214 /* Unknown mandatory extension header */
+#define GTPCAUSE_SEM_ERR_TFT 215 /* Semantic error in the TFT operation */
+#define GTPCAUSE_SYN_ERR_TFT 216 /* Syntactic error in the TFT operation */
+#define GTPCAUSE_SEM_ERR_FILTER 217 /* Semantic errors in packet filter(s) */
+#define GTPCAUSE_SYN_ERR_FILTER 218 /* Syntactic errors in packet filter(s) */
+#define GTPCAUSE_MISSING_APN 219 /* Missing or unknown APN*/
+#define GTPCAUSE_UNKNOWN_PDP 220 /* Unknown PDP address or PDP type */
+#define GTPCAUSE_221 221 /* For Future Use 221-240 */
+#define GTPCAUSE_241 241 /* Cause Values Reserved For Gprs Charging Protocol Use (See Gtp' In Gsm 12.15) 241-255 */
+
+
+
/* GTP 0 header.
* Explanation to some of the fields:
* SNDCP NPDU Number flag = 0 except for inter SGSN handover situations
@@ -100,49 +149,49 @@
* Tunnel ID is IMSI+NSAPI. Unique identifier of PDP context. Is somewhat
* redundant because the header also includes flow. */
-struct gtp0_header { /* Descriptions from 3GPP 09.60 */
- u_int8_t flags; /* 01 bitfield, with typical values */
- /* 000..... Version: 1 (0) */
- /* ...1111. Spare (7) */
- /* .......0 SNDCP N-PDU Number flag (0) */
- u_int8_t type; /* 02 Message type. T-PDU = 0xff */
- u_int16_t length; /* 03 Length (of G-PDU excluding header) */
- u_int16_t seq; /* 05 Sequence Number */
- u_int16_t flow; /* 07 Flow Label ( = 0 for signalling) */
- u_int8_t number; /* 09 SNDCP N-PDU LCC Number ( 0 = 0xff) */
- u_int8_t spare1; /* 10 Spare */
- u_int8_t spare2; /* 11 Spare */
- u_int8_t spare3; /* 12 Spare */
- u_int64_t tid; /* 13 Tunnel ID */
-}; /* 20 */
-
-struct gtp1_header_short { /* Descriptions from 3GPP 29060 */
- u_int8_t flags; /* 01 bitfield, with typical values */
- /* 000..... Version: 1 */
- /* ...1.... Protocol Type: GTP=1, GTP'=0 */
- /* ....1... Spare = 1 */
- /* .....1.. Extension header flag: 1 */
- /* ......1. Sequence number flag: 1 */
- /* .......0 PN: N-PDU Number flag */
- u_int8_t type; /* 02 Message type. T-PDU = 0xff */
- u_int16_t length; /* 03 Length (of IP packet or signalling) */
- u_int64_t tid; /* 05 - 08 Tunnel ID */
+struct gtp0_header { /* Descriptions from 3GPP 09.60 */
+ u_int8_t flags; /* 01 bitfield, with typical values */
+ /* 000..... Version: 1 (0) */
+ /* ...1111. Spare (7) */
+ /* .......0 SNDCP N-PDU Number flag (0) */
+ u_int8_t type; /* 02 Message type. T-PDU = 0xff */
+ u_int16_t length; /* 03 Length (of G-PDU excluding header) */
+ u_int16_t seq; /* 05 Sequence Number */
+ u_int16_t flow; /* 07 Flow Label ( = 0 for signalling) */
+ u_int8_t number; /* 09 SNDCP N-PDU LCC Number ( 0 = 0xff) */
+ u_int8_t spare1; /* 10 Spare */
+ u_int8_t spare2; /* 11 Spare */
+ u_int8_t spare3; /* 12 Spare */
+ u_int64_t tid; /* 13 Tunnel ID */
+}; /* 20 */
+
+struct gtp1_header_short { /* Descriptions from 3GPP 29060 */
+ u_int8_t flags; /* 01 bitfield, with typical values */
+ /* 001..... Version: 1 */
+ /* ...1.... Protocol Type: GTP=1, GTP'=0 */
+ /* ....0... Spare = 0 */
+ /* .....0.. Extension header flag: 0 */
+ /* ......0. Sequence number flag: 0 */
+ /* .......0 PN: N-PDU Number flag */
+ u_int8_t type; /* 02 Message type. T-PDU = 0xff */
+ u_int16_t length; /* 03 Length (of IP packet or signalling) */
+ u_int32_t tei; /* 05 - 08 Tunnel Endpoint ID */
};
-struct gtp1_header_long { /* Descriptions from 3GPP 29060 */
- u_int8_t flags; /* 01 bitfield, with typical values */
- /* 000..... Version: 1 */
- /* ...1.... Protocol Type: GTP=1, GTP'=0 */
- /* ....1... Spare = 1 */
- /* .....1.. Extension header flag: 1 */
- /* ......1. Sequence number flag: 1 */
- /* .......0 PN: N-PDU Number flag */
- u_int8_t type; /* 02 Message type. T-PDU = 0xff */
- u_int16_t length; /* 03 Length (of IP packet or signalling) */
- u_int64_t tid; /* 05 Tunnel ID */
- u_int16_t seq; /* 10 Sequence Number */
- u_int8_t npdu; /* 11 N-PDU Number */
- u_int8_t next; /* 12 Next extension header type. Empty = 0 */
+struct gtp1_header_long { /* Descriptions from 3GPP 29060 */
+ u_int8_t flags; /* 01 bitfield, with typical values */
+ /* 001..... Version: 1 */
+ /* ...1.... Protocol Type: GTP=1, GTP'=0 */
+ /* ....0... Spare = 0 */
+ /* .....0.. Extension header flag: 0 */
+ /* ......1. Sequence number flag: 1 */
+ /* .......0 PN: N-PDU Number flag */
+ u_int8_t type; /* 02 Message type. T-PDU = 0xff */
+ u_int16_t length; /* 03 Length (of IP packet or signalling) */
+ u_int32_t tei; /* 05 Tunnel Endpoint ID */
+ u_int16_t seq; /* 10 Sequence Number */
+ u_int8_t npdu; /* 11 N-PDU Number */
+ u_int8_t next; /* 12 Next extension header type. Empty = 0 */
};
struct gtp0_packet {
@@ -162,9 +211,9 @@ struct gtp1_packet_long {
union gtp_packet {
u_int8_t flags;
- struct gtp0_packet gtp0;
- struct gtp1_packet_short gtp1s;
- struct gtp1_packet_long gtp1l;
+ struct gtp0_packet gtp0;
+ struct gtp1_packet_short gtp1s;
+ struct gtp1_packet_long gtp1l;
} __attribute__((packed)) h;
@@ -188,7 +237,9 @@ union gtp_packet {
struct gsn_t {
/* Parameters related to the network interface */
- int fd; /* File descriptor to network interface */
+ int fd0; /* GTP0 file descriptor */
+ int fd1c; /* GTP1 control plane file descriptor */
+ int fd1u; /* GTP0 user plane file descriptor */
int mode; /* Mode of operation: GGSN or SGSN */
struct in_addr gsnc; /* IP address of this gsn for signalling */
struct in_addr gsnu; /* IP address of this gsn for user traffic */
@@ -206,9 +257,10 @@ struct gsn_t {
/* Call back functions */
int (*cb_delete_context) (struct pdp_t*);
- int (*cb_create_context) (struct pdp_t*);
- int (*cb_conf) (int type, int cause, struct pdp_t *pdp, void* aid);
- int (*cb_gpdu) (struct pdp_t* pdp, void* pack, unsigned len);
+ int (*cb_create_context_ind) (struct pdp_t*);
+ int (*cb_unsup_ind) (struct sockaddr_in *peer);
+ int (*cb_conf) (int type, int cause, struct pdp_t *pdp, void* cbp);
+ int (*cb_data_ind) (struct pdp_t* pdp, void* pack, unsigned len);
/* Counters */
@@ -247,100 +299,92 @@ extern int gtp_newpdp(struct gsn_t *gsn, struct pdp_t **pdp,
uint64_t imsi, uint8_t nsapi);
extern int gtp_freepdp(struct gsn_t *gsn, struct pdp_t *pdp);
-extern int gtp_create_context(struct gsn_t *gsn, struct pdp_t *pdp, void *aid,
- struct in_addr* inetaddr);
-extern int gtp_update_context(struct gsn_t *gsn, struct pdp_t *pdp, void *aid,
- struct in_addr* inetaddr);
-extern int gtp_delete_context(struct gsn_t *gsn, struct pdp_t *pdp, void *aid);
+extern int gtp_create_context_req(struct gsn_t *gsn, struct pdp_t *pdp,
+ void *cbp, struct in_addr* inetaddr);
+
+extern int gtp_set_cb_create_context_ind(struct gsn_t *gsn,
+ int (*cb_create_context_ind) (struct pdp_t* pdp));
+
+extern int gtp_create_context_resp(struct gsn_t *gsn, struct pdp_t *pdp,
+ int cause);
+
+extern int gtp_update_context(struct gsn_t *gsn, struct pdp_t *pdp,
+ void *cbp, struct in_addr* inetaddr);
+
+extern int gtp_delete_context_req(struct gsn_t *gsn, struct pdp_t *pdp,
+ void *cbp);
+
+extern int gtp_data_req(struct gsn_t *gsn, struct pdp_t *pdp,
+ void *pack, unsigned len);
-extern int
-gtp_create_context2(struct gsn_t *gsn, void *aid,
- struct in_addr* inetaddr,
- int selmode, uint64_t imsi, int nsapi,
- uint8_t *qos, int qoslen,
- char *apn, int apnlen,
- char *msisdn, int msisdnlen,
- uint8_t *pco, int pcolen);
+extern int gtp_set_cb_data_ind(struct gsn_t *gsn,
+ int (*cb_data_ind) (struct pdp_t* pdp, void* pack, unsigned len));
-extern int gtp_gpdu(struct gsn_t *gsn, struct pdp_t *pdp,
- void *pack, unsigned len);
extern int gtp_fd(struct gsn_t *gsn);
-extern int gtp_decaps(struct gsn_t *gsn);
+extern int gtp_decaps0(struct gsn_t *gsn);
+extern int gtp_decaps1c(struct gsn_t *gsn);
+extern int gtp_decaps1u(struct gsn_t *gsn);
extern int gtp_retrans(struct gsn_t *gsn);
extern int gtp_retranstimeout(struct gsn_t *gsn, struct timeval *timeout);
-/*
-extern int gtp_set_cb_newpdp(struct gsn_t *gsn,
- int (*cb) (struct pdp_t*));
-extern int gtp_set_cb_freepdp(struct gsn_t *gsn,
- int (*cb) (struct pdp_t*));
-extern int gtp_set_cb_create_pdp_ind(struct gsn_t *gsn,
- int (*cb) (struct pdp_t*));
-extern int gtp_set_cb_create_pdp_conf(struct gsn_t *gsn,
- int (*cb) (struct pdp_t*, int));
-extern int gtp_set_cb_update_pdp_conf(struct gsn_t *gsn,
- int (*cb) (struct pdp_t*, int, int));
-extern int gtp_set_cb_delete_pdp_ind(struct gsn_t *gsn,
- int (*cb) (struct pdp_t*));
-extern int gtp_set_cb_delete_pdp_conf(struct gsn_t *gsn,
- int (*cb) (struct pdp_t*, int));
-*/
-
extern int gtp_set_cb_delete_context(struct gsn_t *gsn,
int (*cb_delete_context) (struct pdp_t* pdp));
-extern int gtp_set_cb_create_context(struct gsn_t *gsn,
- int (*cb_create_context) (struct pdp_t* pdp));
+/*extern int gtp_set_cb_create_context(struct gsn_t *gsn,
+ int (*cb_create_context) (struct pdp_t* pdp)); */
+
+extern int gtp_set_cb_unsup_ind(struct gsn_t *gsn,
+ int (*cb) (struct sockaddr_in *peer));
+
+
extern int gtp_set_cb_conf(struct gsn_t *gsn,
- int (*cb) (int type, int cause, struct pdp_t* pdp, void *aid));
-extern int gtp_set_cb_gpdu(struct gsn_t *gsn,
- int (*cb_gpdu) (struct pdp_t* pdp, void* pack, unsigned len));
+ int (*cb) (int type, int cause, struct pdp_t* pdp, void *cbp));
/* Internal functions (not part of the API */
-extern int gtp_echo_req(struct gsn_t *gsn, struct in_addr *inetaddrs);
-extern int gtp_echo_resp(struct gsn_t *gsn, struct sockaddr_in *peer,
+extern int gtp_echo_req(struct gsn_t *gsn, int version, void *cbp,
+ struct in_addr *inetaddrs);
+extern int gtp_echo_resp(struct gsn_t *gsn, int version,
+ struct sockaddr_in *peer, int fd,
void *pack, unsigned len);
-extern int gtp_echo_ind(struct gsn_t *gsn, struct sockaddr_in *peer,
+extern int gtp_echo_ind(struct gsn_t *gsn, int version,
+ struct sockaddr_in *peer, int fd,
void *pack, unsigned len);
-extern int gtp_echo_conf(struct gsn_t *gsn, struct sockaddr_in *peer,
+extern int gtp_echo_conf(struct gsn_t *gsn, int version,
+ struct sockaddr_in *peer,
void *pack, unsigned len);
-extern int gtp_unsup_resp(struct gsn_t *gsn, struct sockaddr_in *peer,
- void *pack, unsigned len);
-extern int gtp_unsup_conf(struct gsn_t *gsn, struct sockaddr_in *peer,
- void *pack, unsigned len);
-
-extern int gtp_create_pdp_req(struct gsn_t *gsn, int version, void *aid,
- struct in_addr* inetaddr, struct pdp_t *pdp);
+extern int gtp_unsup_req(struct gsn_t *gsn, int version,
+ struct sockaddr_in *peer,
+ int fd, void *pack, unsigned len);
+extern int gtp_unsup_ind(struct gsn_t *gsn, struct sockaddr_in *peer,
+ void *pack, unsigned len);
-extern int gtp_create_pdp_resp(struct gsn_t *gsn, int version,
- struct sockaddr_in *peer,
- void *pack, unsigned len,
+extern int gtp_create_pdp_resp(struct gsn_t *gsn, int version,
struct pdp_t *pdp, uint8_t cause);
extern int gtp_create_pdp_ind(struct gsn_t *gsn, int version,
- struct sockaddr_in *peer,
+ struct sockaddr_in *peer, int fd,
void *pack, unsigned len);
extern int gtp_create_pdp_conf(struct gsn_t *gsn, int version,
struct sockaddr_in *peer,
void *pack, unsigned len);
-extern int gtp_update_pdp_req(struct gsn_t *gsn, int version, void *aid,
+extern int gtp_update_pdp_req(struct gsn_t *gsn, int version, void *cbp,
struct in_addr* inetaddr, struct pdp_t *pdp);
-extern int gtp_delete_pdp_req(struct gsn_t *gsn, int version, void *aid,
+extern int gtp_delete_pdp_req(struct gsn_t *gsn, int version, void *cbp,
struct pdp_t *pdp);
extern int gtp_delete_pdp_resp(struct gsn_t *gsn, int version,
- struct sockaddr_in *peer,
+ struct sockaddr_in *peer, int fd,
void *pack, unsigned len,
struct pdp_t *pdp, uint8_t cause);
extern int gtp_delete_pdp_ind(struct gsn_t *gsn, int version,
- struct sockaddr_in *peer,
+ struct sockaddr_in *peer, int fd,
void *pack, unsigned len);
extern int gtp_delete_pdp_conf(struct gsn_t *gsn, int version,
diff --git a/gtp/gtpie.c b/gtp/gtpie.c
index 8fd4a20..68f912f 100644
--- a/gtp/gtpie.c
+++ b/gtp/gtpie.c
@@ -79,6 +79,14 @@ int gtpie_tv4(void *p, int *length, int size, u_int8_t t, u_int32_t v) {
return 0;
}
+int gtpie_tv8(void *p, int *length, int size, u_int8_t t, u_int64_t v) {
+ if ((*length + 9) >= size) return 1;
+ ((union gtpie_member*) (p + *length))->tv8.t = hton8(t);
+ ((union gtpie_member*) (p + *length))->tv8.v = hton64(v);
+ *length += 9;
+ return 0;
+}
+
int gtpie_getie(union gtpie_member* ie[], int type, int instance) {
int j;
for (j=0; j< GTPIE_SIZE; j++) {
@@ -157,7 +165,18 @@ int gtpie_gettv4(union gtpie_member* ie[], int type, int instance,
return 0;
}
-int gtpie_decaps(union gtpie_member* ie[], void *pack, unsigned len) {
+int gtpie_gettv8(union gtpie_member* ie[], int type, int instance,
+ uint64_t *dst){
+ int ien;
+ ien = gtpie_getie(ie, type, instance);
+ if (ien>=0)
+ *dst = ntoh64(ie[ien]->tv8.v);
+ else
+ return EOF;
+ return 0;
+}
+
+int gtpie_decaps(union gtpie_member* ie[], int version, void *pack, unsigned len) {
int i;
int j = 0;
unsigned char *p;
@@ -175,9 +194,9 @@ int gtpie_decaps(union gtpie_member* ie[], void *pack, unsigned len) {
printf("%02x ", (unsigned char)*(char *)(p+i));
if (!((i+1)%16)) printf("\n");
};
- printf("\n");
+ printf("\n");
}
-
+
switch (*p) {
case GTPIE_CAUSE: /* TV GTPIE types with value length 1 */
case GTPIE_REORDER:
@@ -194,14 +213,26 @@ int gtpie_decaps(union gtpie_member* ie[], void *pack, unsigned len) {
if (j<GTPIE_SIZE) {
ie[j] = (union gtpie_member*) p;
if (GTPIE_DEBUG) printf("GTPIE TV1 found. Type %d, value %d\n",
- ie[j]->tv1.t, ie[j]->tv1.v);
+ ie[j]->tv1.t, ie[j]->tv1.v);
p+= 1 + 1;
j++;
}
break;
- case GTPIE_FL_DI: /* TV GTPIE types with value length 2 */
+ case GTPIE_FL_DI: /* TV GTPIE types with value length 2 or 4 */
case GTPIE_FL_C:
- case GTPIE_PFI:
+ if (version != 0) {
+ if (j<GTPIE_SIZE) { /* GTPIE_TEI_DI & GTPIE_TEI_C with length 4 */
+ /* case GTPIE_TEI_DI: gtp1 */
+ /* case GTPIE_TEI_C: gtp1 */
+ ie[j] = (union gtpie_member*) p;
+ if (GTPIE_DEBUG) printf("GTPIE TV 4 found. Type %d, value %d\n",
+ ie[j]->tv4.t, ie[j]->tv4.v);
+ p+= 1 + 4;
+ j++;
+ }
+ break;
+ }
+ case GTPIE_PFI: /* TV GTPIE types with value length 2 */
case GTPIE_CHARGING_C:
case GTPIE_TRACE_REF:
case GTPIE_TRACE_TYPE:
@@ -227,9 +258,9 @@ int gtpie_decaps(union gtpie_member* ie[], void *pack, unsigned len) {
case GTPIE_TLLI: /* TV GTPIE types with value length 4 */
case GTPIE_P_TMSI:
case GTPIE_CHARGING_ID:
+ /* case GTPIE_TEI_DI: Handled by GTPIE_FL_DI */
+ /* case GTPIE_TEI_C: Handled by GTPIE_FL_DI */
if (j<GTPIE_SIZE) {
- /* case GTPIE_TEI_DI: gtp1 */
- /* case GTPIE_TEI_C: gtp1 */
ie[j] = (union gtpie_member*) p;
if (GTPIE_DEBUG) printf("GTPIE TV 4 found. Type %d, value %d\n",
ie[j]->tv4.t, ie[j]->tv4.v);
diff --git a/gtp/gtpie.h b/gtp/gtpie.h
index 58a36e9..f8990dc 100644
--- a/gtp/gtpie.h
+++ b/gtp/gtpie.h
@@ -25,6 +25,29 @@
#define hton32(x) htonl(x)
#define ntoh32(x) ntohl(x)
+#if BYTE_ORDER == LITTLE_ENDIAN
+static __inline u_int64_t
+hton64(u_int64_t q)
+{
+ register u_int32_t u, l;
+ u = q >> 32;
+ l = (u_int32_t) q;
+
+ return htonl(u) | ((u_int64_t)htonl(l) << 32);
+}
+
+#define ntoh64(_x) hton64(_x)
+
+#elif BYTE_ORDER == BIG_ENDIAN
+
+#define hton64(_x) (_x)
+#define ntoh64(_x) hton64(_x)
+
+#else
+#error "Please fix <machine/endian.h>"
+#endif
+
+
#define GTPIE_SIZE 256 /* Max number of information elements */
#define GTPIE_MAX 0xffff /* Max length of information elements */
#define GTPIE_MAX_TV 28 /* Max length of type value pair */
@@ -91,52 +114,6 @@
/* 252-254 Reserved for the GPRS charging protocol (see GTP' in GSM 12.15) */
#define GTPIE_PRIVATE 255 /* Private Extension */
-/* GTP information element cause codes from 29.060 v3.9.0 7.7 */
-/* */
-#define GTPCAUSE_REQ_IMSI 0 /* Request IMSI */
-#define GTPCAUSE_REQ_IMEI 1 /* Request IMEI */
-#define GTPCAUSE_REQ_IMSI_IMEI 2 /* Request IMSI and IMEI */
-#define GTPCAUSE_NO_ID_NEEDED 3 /* No identity needed */
-#define GTPCAUSE_MS_REFUSES_X 4 /* MS refuses */
-#define GTPCAUSE_MS_NOT_RESP_X 5 /* MS is not GPRS responding */
-#define GTPCAUSE_006 6 /* For future use 6-48 */
-#define GTPCAUSE_049 49 /* Cause values reserved for GPRS charging protocol use (See GTP' in GSM 12.15) 49-63 */
-#define GTPCAUSE_064 64 /* For future use 64-127 */
-#define GTPCAUSE_ACC_REQ 128 /* Request accepted */
-#define GTPCAUSE_129 129 /* For future use 129-176 */
-#define GTPCAUSE_177 177 /* Cause values reserved for GPRS charging protocol use (See GTP' In GSM 12.15) 177-191 */
-#define GTPCAUSE_NON_EXIST 192 /* Non-existent */
-#define GTPCAUSE_INVALID_MESSAGE 193 /* Invalid message format */
-#define GTPCAUSE_IMSI_NOT_KNOWN 194 /* IMSI not known */
-#define GTPCAUSE_MS_DETACHED 195 /* MS is GPRS detached */
-#define GTPCAUSE_MS_NOT_RESP 196 /* MS is not GPRS responding */
-#define GTPCAUSE_MS_REFUSES 197 /* MS refuses */
-#define GTPCAUSE_198 198 /* For future use */
-#define GTPCAUSE_NO_RESOURCES 199 /* No resources available */
-#define GTPCAUSE_NOT_SUPPORTED 200 /* Service not supported */
-#define GTPCAUSE_MAN_IE_INCORRECT 201 /* Mandatory IE incorrect */
-#define GTPCAUSE_MAN_IE_MISSING 202 /* Mandatory IE missing */
-#define GTPCAUSE_OPT_IE_INCORRECT 203 /* Optional IE incorrect */
-#define GTPCAUSE_SYS_FAIL 204 /* System failure */
-#define GTPCAUSE_ROAMING_REST 205 /* Roaming Restriction */
-#define GTPCAUSE_PTIMSI_MISMATCH 206 /* P-TMSI signature mismatch */
-#define GTPCAUSE_CONN_SUSP 207 /* GPRS connection suspended */
-#define GTPCAUSE_AUTH_FAIL 208 /* Authentication failure */
-#define GTPCAUSE_USER_AUTH_FAIL 209 /* User authentication failed */
-#define GTPCAUSE_CONTEXT_NOT_FOUND 210 /* Context not found */
-#define GTPCAUSE_ADDR_OCCUPIED 211 /* All dynamic PDP addresses are occupied */
-#define GTPCAUSE_NO_MEMORY 212 /* No memory is available */
-#define GTPCAUSE_RELOC_FAIL 213 /* Relocation failure */
-#define GTPCAUSE_UNKNOWN_MAN_EXTHEADER 214 /* Unknown mandatory extension header */
-#define GTPCAUSE_SEM_ERR_TFT 215 /* Semantic error in the TFT operation */
-#define GTPCAUSE_SYN_ERR_TFT 216 /* Syntactic error in the TFT operation */
-#define GTPCAUSE_SEM_ERR_FILTER 217 /* Semantic errors in packet filter(s) */
-#define GTPCAUSE_SYN_ERR_FILTER 218 /* Syntactic errors in packet filter(s) */
-#define GTPCAUSE_MISSING_APN 219 /* Missing or unknown APN*/
-#define GTPCAUSE_UNKNOWN_PDP 220 /* Unknown PDP address or PDP type */
-#define GTPCAUSE_221 221 /* For Future Use 221-240 */
-#define GTPCAUSE_241 241 /* Cause Values Reserved For Gprs Charging Protocol Use (See Gtp' In Gsm 12.15) 241-255 */
-
/* GTP information element structs in network order */
struct gtpie_ext { /* Extension header */
@@ -267,8 +244,11 @@ extern int gtpie_gettv2(union gtpie_member* ie[], int type, int instance,
uint16_t *dst);
extern int gtpie_gettv4(union gtpie_member* ie[], int type, int instance,
uint32_t *dst);
+extern int gtpie_gettv8(union gtpie_member* ie[], int type, int instance,
+ uint64_t *dst);
-extern int gtpie_decaps(union gtpie_member* ie[], void *pack, unsigned len);
+extern int gtpie_decaps(union gtpie_member* ie[], int version,
+ void *pack, unsigned len);
extern int gtpie_encaps(union gtpie_member* ie[], void *pack, unsigned *len);
extern int gtpie_encaps2(union gtpie_member ie[], int size,
void *pack, unsigned *len);
diff --git a/gtp/pdp.c b/gtp/pdp.c
index 2c05bdb..493b9b4 100644
--- a/gtp/pdp.c
+++ b/gtp/pdp.c
@@ -128,7 +128,7 @@ int pdp_newpdp(struct pdp_t **pdp, uint64_t imsi, uint8_t nsapi,
(*pdp)->fllc = (uint16_t) n;
(*pdp)->fllu = (uint16_t) n;
(*pdp)->teic_own = (uint32_t) n;
- (*pdp)->teic_own = (uint32_t) n;
+ (*pdp)->teid_own = (uint32_t) n;
pdp_tidset(*pdp, pdp_gettid(imsi, nsapi));
return 0;
}
@@ -227,6 +227,11 @@ int pdp_tidget(struct pdp_t **pdp, uint64_t tid) {
return EOF; /* End of linked list and not found */
}
+int pdp_getimsi(struct pdp_t **pdp, uint64_t imsi, uint8_t nsapi) {
+ return pdp_tidget(pdp,
+ (imsi & 0x0fffffffffffffff) + ((uint64_t)nsapi << 60));
+}
+
/*
int pdp_iphash(void* ipif, struct ul66_t *eua) {
/#printf("IPhash %ld\n", lookup(eua->v, eua->l, ipif) % PDP_MAX);#/
diff --git a/gtp/pdp.h b/gtp/pdp.h
index b4f9986..90a1871 100644
--- a/gtp/pdp.h
+++ b/gtp/pdp.h
@@ -123,6 +123,7 @@ struct pdp_t {
struct ul255_t apn_sub;/* The APN received from the HLR. */
struct ul255_t apn_use;/* The APN Network Identifier currently used. */
uint8_t nsapi; /* Network layer Service Access Point Identifier. (4 bit) */
+ uint8_t linked_nsapi; /* (Linked NSAPI) (4 bit) */
uint16_t ti; /* Transaction Identifier. (4 or 12 bit) */
uint32_t teic_own; /* (Own Tunnel Endpoint Identifier Control) */
@@ -136,7 +137,7 @@ struct pdp_t {
uint16_t flrc; /* (Remote gn/gp Flow Label Control, gtp0) */
uint16_t flru; /* (Remote gn/gp Flow Label Data I, gtp0) */
- struct ul_t tft; /* Traffic flow template. */
+ struct ul255_t tft; /* Traffic flow template. */
/*struct ul16_t sgsnc; * The IP address of the SGSN currently serving this MS. (Control plane) */
/*struct ul16_t sgsnu; * The IP address of the SGSN currently serving this MS. (User plane) */
/*struct ul16_t ggsnc; * The IP address of the GGSN currently used. (Control plane) */
@@ -173,7 +174,15 @@ struct pdp_t {
struct ul255_t pco_req; /* Requested packet control options. */
struct ul255_t pco_neg; /* Negotiated packet control options. */
uint32_t selmode; /* Selection mode. */
- uint64_t tid; /* (Combination of imsi and nsapi) */
+
+ /* Additional parameters used by library */
+
+ int version; /* Protocol version currently in use. 0 or 1 */
+
+ uint64_t tid; /* Combination of imsi and nsapi */
+ u_int16_t seq; /* Sequence number of last request */
+ struct sockaddr_in sa_peer; /* Address of last request */
+ int fd; /* File descriptor request was received on */
};
@@ -185,13 +194,16 @@ int pdp_freepdp(struct pdp_t *pdp);
int pdp_getpdp(struct pdp_t **pdp);
int pdp_getgtp0(struct pdp_t **pdp, uint16_t fl);
-int pdp_getgtp1(struct pdp_t **pdp, uint32_t teid);
+int pdp_getgtp1(struct pdp_t **pdp, uint32_t tei);
+
+int pdp_getimsi(struct pdp_t **pdp, uint64_t imsi, uint8_t nsapi);
int pdp_tidhash(uint64_t tid);
int pdp_tidset(struct pdp_t *pdp, uint64_t tid);
int pdp_tiddel(struct pdp_t *pdp);
int pdp_tidget(struct pdp_t **pdp, uint64_t tid);
+
/*
int pdp_iphash(void* ipif, struct ul66_t *eua);
int pdp_ipset(struct pdp_t *pdp, void* ipif, struct ul66_t *eua);
diff --git a/gtp/queue.c b/gtp/queue.c
index 900f240..845b4ba 100644
--- a/gtp/queue.c
+++ b/gtp/queue.c
@@ -77,6 +77,8 @@ int queue_seqset(struct queue_t *queue, struct qmsg_t *qmsg,
if (QUEUE_DEBUG) printf("End queue_seqset\n");
return 0;
}
+
+
int queue_seqdel(struct queue_t *queue, struct qmsg_t *qmsg) {
int hash = queue_seqhash(&qmsg->peer, qmsg->seq);
struct qmsg_t *qmsg2;
@@ -234,14 +236,14 @@ int queue_seqget(struct queue_t *queue, struct qmsg_t **qmsg,
}
int queue_freemsg_seq(struct queue_t *queue, struct sockaddr_in *peer,
- uint16_t seq, uint8_t *type, void **aid) {
+ uint16_t seq, uint8_t *type, void **cbp) {
struct qmsg_t *qmsg;
if (queue_seqget(queue, &qmsg, peer, seq)) {
- *aid = NULL;
+ *cbp = NULL;
*type = 0;
return EOF;
}
- *aid = qmsg->aid;
+ *cbp = qmsg->cbp;
*type = qmsg->type;
if (queue_freemsg(queue, qmsg)) {
return EOF;
diff --git a/gtp/queue.h b/gtp/queue.h
index 076a3ef..1e226c9 100644
--- a/gtp/queue.h
+++ b/gtp/queue.h
@@ -30,10 +30,11 @@
struct qmsg_t { /* Holder for queued packets */
int state; /* 0=empty, 1=full */
uint16_t seq; /* The sequence number */
- u_int8_t type; /* The type of packet */
- void *aid; /* Application specific pointer */
+ u_int8_t type; /* The type of packet */
+ void *cbp; /* Application specific pointer */
union gtp_packet p; /* The packet stored */
int l; /* Length of the packet */
+ int fd; /* Socket packet was sent to / received from */
struct sockaddr_in peer;/* Address packet was sent to / received from */
struct qmsg_t *seqnext; /* Pointer to next in sequence hash list */
int next; /* Pointer to the next in queue. -1: Last */
@@ -70,7 +71,7 @@ int queue_seqget(struct queue_t *queue, struct qmsg_t **qmsg,
struct sockaddr_in *peer, uint16_t seq);
/* Free message based on sequence number */
int queue_freemsg_seq(struct queue_t *queue, struct sockaddr_in *peer,
- uint16_t seq, uint8_t *type, void **aid);
+ uint16_t seq, uint8_t *type, void **cbp);
#endif /* !_QUEUE_H */
diff --git a/sgsnemu/sgsnemu.c b/sgsnemu/sgsnemu.c
index 1148755..577428f 100644
--- a/sgsnemu/sgsnemu.c
+++ b/sgsnemu/sgsnemu.c
@@ -739,7 +739,7 @@ int create_ping(void *gsn, struct pdp_t *pdp,
pack.checksum = ~sum;
ntransmitted++;
- return gtp_gpdu(gsn, pdp, &pack, 28 + datasize);
+ return gtp_data_req(gsn, pdp, &pack, 28 + datasize);
}
@@ -771,7 +771,7 @@ int cb_tun_ind(struct tun_t *tun, void *pack, unsigned len) {
}
if (ipm->pdp) /* Check if a peer protocol is defined */
- gtp_gpdu(gsn, ipm->pdp, pack, len);
+ gtp_data_req(gsn, ipm->pdp, pack, len);
return 0;
}
@@ -818,13 +818,13 @@ int delete_pdp_conf(struct pdp_t *pdp, int cause) {
return 0;
}
-int echo_conf(struct pdp_t *pdp, int cause) {
- if (cause <0) {
+int echo_conf(int recovery) {
+ if (recovery <0) {
printf("Echo request timed out\n");
state = 0;
}
else
- printf("Received echo response.\n");
+ printf("Received echo response\n");
return 0;
}
@@ -832,7 +832,7 @@ int conf(int type, int cause, struct pdp_t* pdp, void *aid) {
/* if (cause < 0) return 0; Some error occurred. We don't care */
switch (type) {
case GTP_ECHO_REQ:
- return echo_conf(pdp, cause);
+ return echo_conf(cause);
case GTP_CREATE_PDP_REQ:
if (cause !=128) return 0; /* Request not accepted. We don't care */
return create_pdp_conf(pdp, cause);
@@ -878,14 +878,16 @@ int main(int argc, char **argv)
"Failed to create gtp");
exit(1);
}
- if (gsn->fd > maxfd) maxfd = gsn->fd;
+ if (gsn->fd0 > maxfd) maxfd = gsn->fd0;
+ if (gsn->fd1c > maxfd) maxfd = gsn->fd1c;
+ if (gsn->fd1u > maxfd) maxfd = gsn->fd1u;
gtp_set_cb_delete_context(gsn, delete_context);
gtp_set_cb_conf(gsn, conf);
if (options.createif)
- gtp_set_cb_gpdu(gsn, encaps_tun);
+ gtp_set_cb_data_ind(gsn, encaps_tun);
else
- gtp_set_cb_gpdu(gsn, encaps_ping);
+ gtp_set_cb_data_ind(gsn, encaps_ping);
if (options.createif) {
printf("Setting up interface\n");
@@ -907,7 +909,8 @@ int main(int argc, char **argv)
/* See if anybody is there */
printf("Sending off echo request\n");
- gtp_echo_req(gsn, &options.remote); /* See if remote is alive ? */
+ gtp_echo_req(gsn, 1, NULL, &options.remote); /* See if remote is alive ? */
+ gtp_echo_req(gsn, 0, NULL, &options.remote); /* See if remote is alive ? */
for(n=0; n<options.contexts; n++) {
printf("Setting up PDP context #%d\n", n);
@@ -927,6 +930,11 @@ int main(int argc, char **argv)
else {
memcpy(pdp->qos_req0, options.qos.v, options.qos.l);
}
+
+ /* TODO */
+ pdp->qos_req.l = 4;
+ pdp->qos_req.v[0] = 0x00;
+ memcpy(pdp->qos_req.v+1, options.qos.v, options.qos.l);
pdp->selmode = 0x01; /* MS provided APN, subscription not verified */
@@ -964,9 +972,11 @@ int main(int argc, char **argv)
memcpy(pdp->pco_req.v, options.pco.v, options.pco.l);
}
+ pdp->version = 1; /* First try with version 1 */
+
/* Create context */
/* We send this of once. Retransmissions are handled by gtplib */
- gtp_create_context(gsn, pdp, NULL, &options.remote);
+ gtp_create_context_req(gsn, pdp, NULL, &options.remote);
}
state = 1; /* Enter wait_connection state */
@@ -1015,7 +1025,7 @@ int main(int argc, char **argv)
for(n=0; n<options.contexts; n++) {
/* Delete context */
printf("Disconnecting PDP context #%d\n", n);
- gtp_delete_context(gsn, iparr[n].pdp, NULL);
+ gtp_delete_context_req(gsn, iparr[n].pdp, NULL);
if ((options.pinghost.s_addr !=0) && ntransmitted) ping_finish();
}
}
@@ -1041,7 +1051,9 @@ int main(int argc, char **argv)
FD_ZERO(&fds);
if (tun) FD_SET(tun->fd, &fds);
- FD_SET(gsn->fd, &fds);
+ FD_SET(gsn->fd0, &fds);
+ FD_SET(gsn->fd1c, &fds);
+ FD_SET(gsn->fd1u, &fds);
gtp_retranstimeout(gsn, &idleTime);
ping_timeout(&idleTime);
@@ -1066,9 +1078,14 @@ int main(int argc, char **argv)
"TUN decaps failed");
}
- if (FD_ISSET(gsn->fd, &fds))
- gtp_decaps(gsn);
-
+ if (FD_ISSET(gsn->fd0, &fds))
+ gtp_decaps0(gsn);
+
+ if (FD_ISSET(gsn->fd1c, &fds))
+ gtp_decaps1c(gsn);
+
+ if (FD_ISSET(gsn->fd1u, &fds))
+ gtp_decaps1u(gsn);
}
gtp_free(gsn); /* Clean up the gsn instance */