ppp-2.5.0/0000755000175000017500000000000014412736275007331 500000000000000ppp-2.5.0/etc.ppp/0000755000175000017500000000000014412736274010701 500000000000000ppp-2.5.0/etc.ppp/options0000644000175000017500000000000506665661000012225 00000000000000lock ppp-2.5.0/etc.ppp/chap-secrets0000644000175000017500000000011605772416650013125 00000000000000# Secrets for authentication using CHAP # client server secret IP addresses ppp-2.5.0/etc.ppp/pap-secrets0000644000175000017500000000011505772416653012774 00000000000000# Secrets for authentication using PAP # client server secret IP addresses ppp-2.5.0/etc.ppp/eaptls-server0000664000175000017500000000062513750470070013336 00000000000000# Parameters for authentication using EAP-TLS (server) # client name (can be *) # server name (can be *) # client certificate file (optional, if unused put '-') # server certificate file (required) # CA certificate file (required) # server private key file (required) # allowed addresses (required, can be *) #client server - /root/cert/server.crt /root/cert/ca.crt /root/cert/server.key 192.168.1.0/24 ppp-2.5.0/etc.ppp/eaptls-client0000664000175000017500000000053513750470070013306 00000000000000# Parameters for authentication using EAP-TLS (client) # client name (can be *) # server name (can be *) # client certificate file (required) # server certificate file (optional, if unused put '-') # CA certificate file (required) # client private key file (required) #client server /root/cert/client.crt - /root/cert/ca.crt /root/cert/client.key ppp-2.5.0/etc.ppp/openssl.cnf0000664000175000017500000000040513750470070012766 00000000000000openssl_conf = openssl_def [ openssl_def ] engines = engine_section [ engine_section ] pkcs11 = pkcs11_section [ pkcs11_section ] engine_id = pkcs11 dynamic_path = /usr/lib64/openssl/engines/engine_pkcs11.so MODULE_PATH = /usr/lib64/libeTPkcs11.so init = 0 ppp-2.5.0/m4/0000755000175000017500000000000014412736274007650 500000000000000ppp-2.5.0/m4/ax_check_atm.m40000664000175000017500000000511214273050614012431 00000000000000# SYNOPSIS # # AX_CHECK_ATM([action-if-found[, action-if-not-found]]) # # DESCRIPTION # # Look for libatm in a number of default locations, or in a provided location # (via --with-atm=). Sets # ATM_CFLAGS # ATM_LDFLAGS # ATM_LIBS # # and calls ACTION-IF-FOUND or ACTION-IF-NOT-FOUND appropriately # # LICENSE # # Copyright (c) 2021 Eivind Naess # # Copying and distribution of this file, with or without modification, are # permitted in any medium without royalty provided the copyright notice # and this notice are preserved. This file is offered as-is, without any # warranty. #serial 1 AC_DEFUN([AX_CHECK_ATM], [ AC_ARG_WITH([atm], [AS_HELP_STRING([--with-atm=DIR], [With libatm support, see http://linux-atm.sourceforge.net])], [ case "$withval" in "" | y | ye | yes) atmdirs="/usr/local /usr/lib /usr" ;; n | no) with_atm="no" ;; *) atmdirs="$withval" ;; esac ]) if [ test "x${with_atm}" != "xno" ] ; then ATM_LIBS="-latm" for atmdir in $atmdirs; do AC_MSG_CHECKING([for atm.h in $atmdir]) if test -f "$atmdir/include/atm.h"; then ATM_CFLAGS="-I$atmdir/include" ATM_LDFLAGS="-L$atmdir/lib" AC_MSG_RESULT([yes]) break else AC_MSG_RESULT([no]) fi done # try the preprocessor and linker with our new flags, # being careful not to pollute the global LIBS, LDFLAGS, and CPPFLAGS AC_MSG_CHECKING([if compiling and linking against libatm works]) save_LIBS="$LIBS" save_LDFLAGS="$LDFLAGS" save_CPPFLAGS="$CPPFLAGS" LDFLAGS="$LDFLAGS $ATM_LDFLAGS" LIBS="$ATM_LIBS $LIBS" CPPFLAGS="$ATM_CFLAGS $CPPFLAGS" AC_LINK_IFELSE( [AC_LANG_PROGRAM( [#include #include ], [text2atm(NULL,NULL,0,0);])], [ AC_MSG_RESULT([yes]) with_atm=yes $1 ], [ AC_MSG_RESULT([no]) with_atm="no" $2 ]) CPPFLAGS="$save_CPPFLAGS" LDFLAGS="$save_LDFLAGS" LIBS="$save_LIBS" AC_SUBST([ATM_CFLAGS]) AC_SUBST([ATM_LIBS]) AC_SUBST([ATM_LDFLAGS]) fi AM_CONDITIONAL(WITH_LIBATM, test "x${with_atm}" != "xno") ]) ppp-2.5.0/m4/ax_check_openssl.m40000664000175000017500000001010514076444143013336 00000000000000# =========================================================================== # http://www.gnu.org/software/autoconf-archive/ax_check_openssl.html # =========================================================================== # # SYNOPSIS # # AX_CHECK_OPENSSL([action-if-found[, action-if-not-found]]) # # DESCRIPTION # # Look for OpenSSL in a number of default spots, or in a user-selected # spot (via --with-openssl). Sets # # OPENSSL_INCLUDES to the include directives required # OPENSSL_LIBS to the -l directives required # OPENSSL_LDFLAGS to the -L or -R flags required # # and calls ACTION-IF-FOUND or ACTION-IF-NOT-FOUND appropriately # # This macro sets OPENSSL_INCLUDES such that source files should use the # openssl/ directory in include directives: # # #include # # LICENSE # # Copyright (c) 2009,2010 Zmanda Inc. # Copyright (c) 2009,2010 Dustin J. Mitchell # # Copying and distribution of this file, with or without modification, are # permitted in any medium without royalty provided the copyright notice # and this notice are preserved. This file is offered as-is, without any # warranty. #serial 9 AU_ALIAS([CHECK_SSL], [AX_CHECK_OPENSSL]) AC_DEFUN([AX_CHECK_OPENSSL], [ found=false AC_ARG_WITH([openssl], [AS_HELP_STRING([--with-openssl=DIR], [With openssl support, see http://www.openssl.org])], [ case "$withval" in "" | y | ye | yes ) ssldirs="/usr/local/ssl /usr/lib/ssl /usr/ssl /usr/pkg /usr/local /usr" ;; n | no ) ;; *) ssldirs="$withval" ;; esac ], [ ssldirs="/usr/local/ssl /usr/lib/ssl /usr/ssl /usr/pkg /usr/local /usr" ]) AS_IF([test "${with_openssl}" != "no"], [ OPENSSL_INCLUDES= for ssldir in $ssldirs; do AC_MSG_CHECKING([for openssl/ssl.h in $ssldir]) AS_IF([ test -f "$ssldir/include/openssl/ssl.h" ], [ OPENSSL_INCLUDES="-I$ssldir/include" OPENSSL_LDFLAGS="-L$ssldir/lib" OPENSSL_LIBS="-lssl -lcrypto" found=true AC_MSG_RESULT([yes]) break ], [ AC_MSG_RESULT([no]) ]) done]) AS_IF([test "${with_openssl}" != "no" && test ! ${found}], [ # if pkg-config is installed and openssl has installed a .pc file, # then use that information and don't search ssldirs AC_PATH_PROG([PKG_CONFIG], [pkg-config]) if test x"$PKG_CONFIG" != x""; then OPENSSL_LDFLAGS=`$PKG_CONFIG openssl --libs-only-L 2>/dev/null` if test $? = 0; then OPENSSL_LIBS=`$PKG_CONFIG openssl --libs-only-l 2>/dev/null` OPENSSL_INCLUDES=`$PKG_CONFIG openssl --cflags-only-I 2>/dev/null` found=true fi fi ]) AS_IF([test "${with_openssl}" != "no" && test ${found}], [ # try the preprocessor and linker with our new flags, # being careful not to pollute the global LIBS, LDFLAGS, and CPPFLAGS AC_MSG_CHECKING([whether compiling and linking against OpenSSL works]) echo "Trying link with OPENSSL_LDFLAGS=$OPENSSL_LDFLAGS;" \ "OPENSSL_LIBS=$OPENSSL_LIBS; OPENSSL_INCLUDES=$OPENSSL_INCLUDES" >&AS_MESSAGE_LOG_FD save_LIBS="$LIBS" save_LDFLAGS="$LDFLAGS" save_CPPFLAGS="$CPPFLAGS" LDFLAGS="$LDFLAGS $OPENSSL_LDFLAGS" LIBS="$OPENSSL_LIBS $LIBS" CPPFLAGS="$OPENSSL_INCLUDES $CPPFLAGS" AC_LINK_IFELSE( [AC_LANG_PROGRAM([#include ], [SSL_new(NULL)])], [ AC_MSG_RESULT([yes]) $1 ], [ AC_MSG_RESULT([no]) $2 ]) CPPFLAGS="$save_CPPFLAGS" LDFLAGS="$save_LDFLAGS" LIBS="$save_LIBS" AC_SUBST([OPENSSL_INCLUDES]) AC_SUBST([OPENSSL_LIBS]) AC_SUBST([OPENSSL_LDFLAGS]) ], [ $2 ]) ]) ppp-2.5.0/m4/ax_check_openssl_func.m40000664000175000017500000000237114076444143014357 00000000000000# SYNOPSIS # # AX_CHECK_OPENSSL_DEFINE([DEFINE], [VAR][, action-if-found[, action-if-not-found]]) # # DESCRIPTION # # Check if OpenSSL has a define set in it's features provided, i.e. OPENSSL_NO_MD4. # If so, the var argument ac_cv_openssl_[VAR] is set to yes, and action-is-found is # run, else action-if-not-found is executed. # # This module require AX_CHECK_OPENSSL # # LICENSE # # Copyright (c) 2021 Eivind Naess # # Copying and distribution of this file, with or without modification, are # permitted in any medium without royalty provided the copyright notice # and this notice are preserved. This file is offered as-is, without any # warranty. #serial 1 AC_DEFUN([AX_CHECK_OPENSSL_DEFINE], [ AC_REQUIRE([AX_CHECK_OPENSSL]) AC_MSG_CHECKING([for $2 support in openssl]) save_CPPFLAGS="$CPPFLAGS" CPPFLAGS="$OPENSSL_INCLUDES $CPPFLAGS" AC_PREPROC_IFELSE([ AC_LANG_PROGRAM( [[@%:@include ]], [[#ifdef $1 #error "No support for $1" #endif]])], AC_MSG_RESULT([yes]) [ac_cv_openssl_$2=yes] $3, AC_MSG_RESULT([no]) [ac_cv_openssl_$2=no] $4 ) CPPFLAGS="$save_CPPFLAGS" ]) ppp-2.5.0/m4/ax_check_pam.m40000664000175000017500000000514414273050614012432 00000000000000# SYNOPSIS # # AX_CHECK_PAM([action-if-found[, action-if-not-found]]) # # DESCRIPTION # # Look for libpam in a number of default locations, or in a provided location # (via --with-pam=). Sets # PAM_CFLAGS # PAM_LDFLAGS # PAM_LIBS # # and calls ACTION-IF-FOUND or ACTION-IF-NOT-FOUND appropriately # # LICENSE # # Copyright (c) 2021 Eivind Naess # # Copying and distribution of this file, with or without modification, are # permitted in any medium without royalty provided the copyright notice # and this notice are preserved. This file is offered as-is, without any # warranty. #serial 1 AC_DEFUN([AX_CHECK_PAM], [ AC_ARG_WITH([pam], [AS_HELP_STRING([--with-pam=DIR], [With libpam support, see ftp.redhat.com:/pub/pam])], [ case "$withval" in "" | y | ye | yes) pamdirs="/usr/local /usr/lib /usr" ;; n | no) with_pam="no" ;; *) pamdirs="$withval" ;; esac ]) if [ test "x${with_pam}" != "xno" ] ; then PAM_LIBS="-lpam" for pamdir in $pamdirs; do AC_MSG_CHECKING([for pam_appl.h in $pamdir]) if test -f "$pamdir/include/security/pam_appl.h"; then PAM_CFLAGS="-I$pamdir/include" PAM_LDFLAGS="-L$pamdir/lib" AC_MSG_RESULT([yes]) break else AC_MSG_RESULT([no]) fi done # try the preprocessor and linker with our new flags, # being careful not to pollute the global LIBS, LDFLAGS, and CPPFLAGS AC_MSG_CHECKING([if compiling and linking against libpam works]) save_LIBS="$LIBS" save_LDFLAGS="$LDFLAGS" save_CPPFLAGS="$CPPFLAGS" LDFLAGS="$LDFLAGS $PAM_LDFLAGS" LIBS="$PAM_LIBS $LIBS" CPPFLAGS="$PAM_CFLAGS $CPPFLAGS" AC_LINK_IFELSE( [AC_LANG_PROGRAM( [#include #include ], [pam_authenticate(NULL, 0);])], [ AC_MSG_RESULT([yes]) with_pam=yes $1 ], [ AC_MSG_RESULT([no]) with_pam="no" $2 ]) CPPFLAGS="$save_CPPFLAGS" LDFLAGS="$save_LDFLAGS" LIBS="$save_LIBS" AC_SUBST([PAM_CFLAGS]) AC_SUBST([PAM_LIBS]) AC_SUBST([PAM_LDFLAGS]) fi AM_CONDITIONAL(WITH_LIBPAM, test "x${with_pam}" != "xno") ]) ppp-2.5.0/m4/ax_check_pcap.m40000664000175000017500000000507214273050614012600 00000000000000# SYNOPSIS # # AX_CHECK_PCAP([action-if-found[, action-if-not-found]] # # DESCRIPTION # # Look for libpcap in a number of default locations, or in a provided location # (via --with-pcap=). Sets # PCAP_CFLAGS # PCAP_LDFLAGS # PCAP_LIBS # # and calls ACTION-IF-FOUND or ACTION-IF-NOT-FOUND appropriately # # LICENSE # # Copyright (c) 2021 Eivind Naess # # Copying and distribution of this file, with or without modification, are # permitted in any medium without royalty provided the copyright notice # and this notice are preserved. This file is offered as-is, without any # warranty. #serial 1 AC_DEFUN([AX_CHECK_PCAP], [ AC_ARG_WITH([pcap], [AS_HELP_STRING([--with-pcap=DIR], [With libpcap support, see https://www.tcpdump.org])], [ case "$withval" in "" | y | ye | yes) pcapdirs="/usr/local /usr/lib /usr" ;; n | no) with_pcap="no" ;; *) pcapdirs="$withval" ;; esac ]) if [ test "x${with_pcap}" != "xno" ] ; then PCAP_LIBS="-lpcap" for pcapdir in $pcapdirs; do AC_MSG_CHECKING([for pcap.h in $pcapdir]) if test -f "$pcapdir/include/pcap.h"; then PCAP_CFLAGS="-I$pcapdir/include" PCAP_LDFLAGS="-L$pcapdir/lib" AC_MSG_RESULT([yes]) break else AC_MSG_RESULT([no]) fi done # try the preprocessor and linker with our new flags, # being careful not to pollute the global LIBS, LDFLAGS, and CPPFLAGS AC_MSG_CHECKING([if compiling and linking against libpcap works]) save_LIBS="$LIBS" save_LDFLAGS="$LDFLAGS" save_CPPFLAGS="$CPPFLAGS" LDFLAGS="$PCAP_LDFLAGS $LDFLAGS" LIBS="$PCAP_LIBS $LIBS" CPPFLAGS="$PCAP_CFLAGS $CPPFLAGS" AC_LINK_IFELSE( [AC_LANG_PROGRAM( [@%:@include ], [pcap_create(0,0);])], [ AC_MSG_RESULT([yes]) with_pcap=yes $1 ], [ AC_MSG_RESULT([no]) with_pcap="no" $2 ]) CPPFLAGS="$save_CPPFLAGS" LDFLAGS="$save_LDFLAGS" LIBS="$save_LIBS" AC_SUBST([PCAP_CFLAGS]) AC_SUBST([PCAP_LIBS]) AC_SUBST([PCAP_LDFLAGS]) fi AM_CONDITIONAL(WITH_PCAP, test "x${with_pcap}" != "xno") ]) ppp-2.5.0/m4/ax_check_srp.m40000664000175000017500000000515514273050614012463 00000000000000# SYNOPSIS # # AX_CHECK_SRP([action-if-found[, action-if-not-found]]) # # DESCRIPTION # # Look for libsrp in a number of default locations, or in a provided location # (via --with-srp=). Sets # SRP_CFLAGS # SRP_LDFLAGS # SRP_LIBS # # and calls ACTION-IF-FOUND or ACTION-IF-NOT-FOUND appropriately # # LICENSE # # Copyright (c) 2021 Eivind Naess # # Copying and distribution of this file, with or without modification, are # permitted in any medium without royalty provided the copyright notice # and this notice are preserved. This file is offered as-is, without any # warranty. #serial 1 AC_DEFUN([AX_CHECK_SRP], [ AC_ARG_WITH([srp], [AS_HELP_STRING([--with-srp=DIR], [With libsrp support, see http://srp.stanford.edu])], [ case "$withval" in "" | y | ye | yes) srpdirs="/usr/local /usr/lib /usr" ;; n | no) with_srp="no" ;; *) srpdirs="$withval" ;; esac ]) if [ test "x${with_srp}" != "xno" ] ; then SRP_LIBS="-lsrp" for srpdir in $srpdirs; do AC_MSG_CHECKING([for srp.h in $srpdir]) if test -f "$srpdir/include/srp.h"; then SRP_CFLAGS="-I$srpdir/include" SRP_LDFLAGS="-L$srpdir/lib" AC_MSG_RESULT([yes]) break else AC_MSG_RESULT([no]) fi done # try the preprocessor and linker with our new flags, # being careful not to pollute the global LIBS, LDFLAGS, and CPPFLAGS AC_MSG_CHECKING([if compiling and linking against libsrp works]) save_LIBS="$LIBS" save_LDFLAGS="$LDFLAGS" save_CPPFLAGS="$CPPFLAGS" LDFLAGS="$SRP_LDFLAGS $OPENSSL_LDFLAGS $LDFLAGS" LIBS="$SRP_LIBS $OPENSSL_LIBS $LIBS" CPPFLAGS="$SRP_CFLAGS $OPENSSL_INCLUDES $CPPFLAGS" AC_LINK_IFELSE( [AC_LANG_PROGRAM( [#include #include ], [SRP_use_engine(NULL);])], [ AC_MSG_RESULT([yes]) with_srp=yes $1 ], [ AC_MSG_RESULT([no]) with_srp="no" $2 ]) CPPFLAGS="$save_CPPFLAGS" LDFLAGS="$save_LDFLAGS" LIBS="$save_LIBS" AC_SUBST([SRP_CFLAGS]) AC_SUBST([SRP_LIBS]) AC_SUBST([SRP_LDFLAGS]) fi AM_CONDITIONAL(WITH_SRP, test "x${with_srp}" != "xno") ]) ppp-2.5.0/m4/libtool.m40000644000175000017500000112776414246131576011517 00000000000000# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*- # # Copyright (C) 1996-2001, 2003-2019, 2021-2022 Free Software # Foundation, Inc. # Written by Gordon Matzigkeit, 1996 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. m4_define([_LT_COPYING], [dnl # Copyright (C) 2014 Free Software Foundation, Inc. # This is free software; see the source for copying conditions. There is NO # warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # GNU Libtool is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of of the License, or # (at your option) any later version. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program or library that is built # using GNU Libtool, you may include this file under the same # distribution terms that you use for the rest of that program. # # GNU Libtool is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . ]) # serial 59 LT_INIT # LT_PREREQ(VERSION) # ------------------ # Complain and exit if this libtool version is less that VERSION. m4_defun([LT_PREREQ], [m4_if(m4_version_compare(m4_defn([LT_PACKAGE_VERSION]), [$1]), -1, [m4_default([$3], [m4_fatal([Libtool version $1 or higher is required], 63)])], [$2])]) # _LT_CHECK_BUILDDIR # ------------------ # Complain if the absolute build directory name contains unusual characters m4_defun([_LT_CHECK_BUILDDIR], [case `pwd` in *\ * | *\ *) AC_MSG_WARN([Libtool does not cope well with whitespace in `pwd`]) ;; esac ]) # LT_INIT([OPTIONS]) # ------------------ AC_DEFUN([LT_INIT], [AC_PREREQ([2.62])dnl We use AC_PATH_PROGS_FEATURE_CHECK AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl AC_BEFORE([$0], [LT_LANG])dnl AC_BEFORE([$0], [LT_OUTPUT])dnl AC_BEFORE([$0], [LTDL_INIT])dnl m4_require([_LT_CHECK_BUILDDIR])dnl dnl Autoconf doesn't catch unexpanded LT_ macros by default: m4_pattern_forbid([^_?LT_[A-Z_]+$])dnl m4_pattern_allow([^(_LT_EOF|LT_DLGLOBAL|LT_DLLAZY_OR_NOW|LT_MULTI_MODULE)$])dnl dnl aclocal doesn't pull ltoptions.m4, ltsugar.m4, or ltversion.m4 dnl unless we require an AC_DEFUNed macro: AC_REQUIRE([LTOPTIONS_VERSION])dnl AC_REQUIRE([LTSUGAR_VERSION])dnl AC_REQUIRE([LTVERSION_VERSION])dnl AC_REQUIRE([LTOBSOLETE_VERSION])dnl m4_require([_LT_PROG_LTMAIN])dnl _LT_SHELL_INIT([SHELL=${CONFIG_SHELL-/bin/sh}]) dnl Parse OPTIONS _LT_SET_OPTIONS([$0], [$1]) # This can be used to rebuild libtool when needed LIBTOOL_DEPS=$ltmain # Always use our own libtool. LIBTOOL='$(SHELL) $(top_builddir)/libtool' AC_SUBST(LIBTOOL)dnl _LT_SETUP # Only expand once: m4_define([LT_INIT]) ])# LT_INIT # Old names: AU_ALIAS([AC_PROG_LIBTOOL], [LT_INIT]) AU_ALIAS([AM_PROG_LIBTOOL], [LT_INIT]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_PROG_LIBTOOL], []) dnl AC_DEFUN([AM_PROG_LIBTOOL], []) # _LT_PREPARE_CC_BASENAME # ----------------------- m4_defun([_LT_PREPARE_CC_BASENAME], [ # Calculate cc_basename. Skip known compiler wrappers and cross-prefix. func_cc_basename () { for cc_temp in @S|@*""; do case $cc_temp in compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;; distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;; \-*) ;; *) break;; esac done func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` } ])# _LT_PREPARE_CC_BASENAME # _LT_CC_BASENAME(CC) # ------------------- # It would be clearer to call AC_REQUIREs from _LT_PREPARE_CC_BASENAME, # but that macro is also expanded into generated libtool script, which # arranges for $SED and $ECHO to be set by different means. m4_defun([_LT_CC_BASENAME], [m4_require([_LT_PREPARE_CC_BASENAME])dnl AC_REQUIRE([_LT_DECL_SED])dnl AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl func_cc_basename $1 cc_basename=$func_cc_basename_result ]) # _LT_FILEUTILS_DEFAULTS # ---------------------- # It is okay to use these file commands and assume they have been set # sensibly after 'm4_require([_LT_FILEUTILS_DEFAULTS])'. m4_defun([_LT_FILEUTILS_DEFAULTS], [: ${CP="cp -f"} : ${MV="mv -f"} : ${RM="rm -f"} ])# _LT_FILEUTILS_DEFAULTS # _LT_SETUP # --------- m4_defun([_LT_SETUP], [AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_CANONICAL_BUILD])dnl AC_REQUIRE([_LT_PREPARE_SED_QUOTE_VARS])dnl AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl _LT_DECL([], [PATH_SEPARATOR], [1], [The PATH separator for the build system])dnl dnl _LT_DECL([], [host_alias], [0], [The host system])dnl _LT_DECL([], [host], [0])dnl _LT_DECL([], [host_os], [0])dnl dnl _LT_DECL([], [build_alias], [0], [The build system])dnl _LT_DECL([], [build], [0])dnl _LT_DECL([], [build_os], [0])dnl dnl AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([LT_PATH_LD])dnl AC_REQUIRE([LT_PATH_NM])dnl dnl AC_REQUIRE([AC_PROG_LN_S])dnl test -z "$LN_S" && LN_S="ln -s" _LT_DECL([], [LN_S], [1], [Whether we need soft or hard links])dnl dnl AC_REQUIRE([LT_CMD_MAX_LEN])dnl _LT_DECL([objext], [ac_objext], [0], [Object file suffix (normally "o")])dnl _LT_DECL([], [exeext], [0], [Executable file suffix (normally "")])dnl dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_CHECK_SHELL_FEATURES])dnl m4_require([_LT_PATH_CONVERSION_FUNCTIONS])dnl m4_require([_LT_CMD_RELOAD])dnl m4_require([_LT_DECL_FILECMD])dnl m4_require([_LT_CHECK_MAGIC_METHOD])dnl m4_require([_LT_CHECK_SHAREDLIB_FROM_LINKLIB])dnl m4_require([_LT_CMD_OLD_ARCHIVE])dnl m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl m4_require([_LT_WITH_SYSROOT])dnl m4_require([_LT_CMD_TRUNCATE])dnl _LT_CONFIG_LIBTOOL_INIT([ # See if we are running on zsh, and set the options that allow our # commands through without removal of \ escapes INIT. if test -n "\${ZSH_VERSION+set}"; then setopt NO_GLOB_SUBST fi ]) if test -n "${ZSH_VERSION+set}"; then setopt NO_GLOB_SUBST fi _LT_CHECK_OBJDIR m4_require([_LT_TAG_COMPILER])dnl case $host_os in aix3*) # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test set != "${COLLECT_NAMES+set}"; then COLLECT_NAMES= export COLLECT_NAMES fi ;; esac # Global variables: ofile=libtool can_build_shared=yes # All known linkers require a '.a' archive for static linking (except MSVC and # ICC, which need '.lib'). libext=a with_gnu_ld=$lt_cv_prog_gnu_ld old_CC=$CC old_CFLAGS=$CFLAGS # Set sane defaults for various variables test -z "$CC" && CC=cc test -z "$LTCC" && LTCC=$CC test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS test -z "$LD" && LD=ld test -z "$ac_objext" && ac_objext=o _LT_CC_BASENAME([$compiler]) # Only perform the check for file, if the check method requires it test -z "$MAGIC_CMD" && MAGIC_CMD=file case $deplibs_check_method in file_magic*) if test "$file_magic_cmd" = '$MAGIC_CMD'; then _LT_PATH_MAGIC fi ;; esac # Use C for the default configuration in the libtool script LT_SUPPORTED_TAG([CC]) _LT_LANG_C_CONFIG _LT_LANG_DEFAULT_CONFIG _LT_CONFIG_COMMANDS ])# _LT_SETUP # _LT_PREPARE_SED_QUOTE_VARS # -------------------------- # Define a few sed substitution that help us do robust quoting. m4_defun([_LT_PREPARE_SED_QUOTE_VARS], [# Backslashify metacharacters that are still active within # double-quoted strings. sed_quote_subst='s/\([["`$\\]]\)/\\\1/g' # Same as above, but do not quote variable references. double_quote_subst='s/\([["`\\]]\)/\\\1/g' # Sed substitution to delay expansion of an escaped shell variable in a # double_quote_subst'ed string. delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' # Sed substitution to delay expansion of an escaped single quote. delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' # Sed substitution to avoid accidental globbing in evaled expressions no_glob_subst='s/\*/\\\*/g' ]) # _LT_PROG_LTMAIN # --------------- # Note that this code is called both from 'configure', and 'config.status' # now that we use AC_CONFIG_COMMANDS to generate libtool. Notably, # 'config.status' has no value for ac_aux_dir unless we are using Automake, # so we pass a copy along to make sure it has a sensible value anyway. m4_defun([_LT_PROG_LTMAIN], [m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([ltmain.sh])])dnl _LT_CONFIG_LIBTOOL_INIT([ac_aux_dir='$ac_aux_dir']) ltmain=$ac_aux_dir/ltmain.sh ])# _LT_PROG_LTMAIN ## ------------------------------------- ## ## Accumulate code for creating libtool. ## ## ------------------------------------- ## # So that we can recreate a full libtool script including additional # tags, we accumulate the chunks of code to send to AC_CONFIG_COMMANDS # in macros and then make a single call at the end using the 'libtool' # label. # _LT_CONFIG_LIBTOOL_INIT([INIT-COMMANDS]) # ---------------------------------------- # Register INIT-COMMANDS to be passed to AC_CONFIG_COMMANDS later. m4_define([_LT_CONFIG_LIBTOOL_INIT], [m4_ifval([$1], [m4_append([_LT_OUTPUT_LIBTOOL_INIT], [$1 ])])]) # Initialize. m4_define([_LT_OUTPUT_LIBTOOL_INIT]) # _LT_CONFIG_LIBTOOL([COMMANDS]) # ------------------------------ # Register COMMANDS to be passed to AC_CONFIG_COMMANDS later. m4_define([_LT_CONFIG_LIBTOOL], [m4_ifval([$1], [m4_append([_LT_OUTPUT_LIBTOOL_COMMANDS], [$1 ])])]) # Initialize. m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS]) # _LT_CONFIG_SAVE_COMMANDS([COMMANDS], [INIT_COMMANDS]) # ----------------------------------------------------- m4_defun([_LT_CONFIG_SAVE_COMMANDS], [_LT_CONFIG_LIBTOOL([$1]) _LT_CONFIG_LIBTOOL_INIT([$2]) ]) # _LT_FORMAT_COMMENT([COMMENT]) # ----------------------------- # Add leading comment marks to the start of each line, and a trailing # full-stop to the whole comment if one is not present already. m4_define([_LT_FORMAT_COMMENT], [m4_ifval([$1], [ m4_bpatsubst([m4_bpatsubst([$1], [^ *], [# ])], [['`$\]], [\\\&])]m4_bmatch([$1], [[!?.]$], [], [.]) )]) ## ------------------------ ## ## FIXME: Eliminate VARNAME ## ## ------------------------ ## # _LT_DECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION], [IS-TAGGED?]) # ------------------------------------------------------------------- # CONFIGNAME is the name given to the value in the libtool script. # VARNAME is the (base) name used in the configure script. # VALUE may be 0, 1 or 2 for a computed quote escaped value based on # VARNAME. Any other value will be used directly. m4_define([_LT_DECL], [lt_if_append_uniq([lt_decl_varnames], [$2], [, ], [lt_dict_add_subkey([lt_decl_dict], [$2], [libtool_name], [m4_ifval([$1], [$1], [$2])]) lt_dict_add_subkey([lt_decl_dict], [$2], [value], [$3]) m4_ifval([$4], [lt_dict_add_subkey([lt_decl_dict], [$2], [description], [$4])]) lt_dict_add_subkey([lt_decl_dict], [$2], [tagged?], [m4_ifval([$5], [yes], [no])])]) ]) # _LT_TAGDECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION]) # -------------------------------------------------------- m4_define([_LT_TAGDECL], [_LT_DECL([$1], [$2], [$3], [$4], [yes])]) # lt_decl_tag_varnames([SEPARATOR], [VARNAME1...]) # ------------------------------------------------ m4_define([lt_decl_tag_varnames], [_lt_decl_filter([tagged?], [yes], $@)]) # _lt_decl_filter(SUBKEY, VALUE, [SEPARATOR], [VARNAME1..]) # --------------------------------------------------------- m4_define([_lt_decl_filter], [m4_case([$#], [0], [m4_fatal([$0: too few arguments: $#])], [1], [m4_fatal([$0: too few arguments: $#: $1])], [2], [lt_dict_filter([lt_decl_dict], [$1], [$2], [], lt_decl_varnames)], [3], [lt_dict_filter([lt_decl_dict], [$1], [$2], [$3], lt_decl_varnames)], [lt_dict_filter([lt_decl_dict], $@)])[]dnl ]) # lt_decl_quote_varnames([SEPARATOR], [VARNAME1...]) # -------------------------------------------------- m4_define([lt_decl_quote_varnames], [_lt_decl_filter([value], [1], $@)]) # lt_decl_dquote_varnames([SEPARATOR], [VARNAME1...]) # --------------------------------------------------- m4_define([lt_decl_dquote_varnames], [_lt_decl_filter([value], [2], $@)]) # lt_decl_varnames_tagged([SEPARATOR], [VARNAME1...]) # --------------------------------------------------- m4_define([lt_decl_varnames_tagged], [m4_assert([$# <= 2])dnl _$0(m4_quote(m4_default([$1], [[, ]])), m4_ifval([$2], [[$2]], [m4_dquote(lt_decl_tag_varnames)]), m4_split(m4_normalize(m4_quote(_LT_TAGS)), [ ]))]) m4_define([_lt_decl_varnames_tagged], [m4_ifval([$3], [lt_combine([$1], [$2], [_], $3)])]) # lt_decl_all_varnames([SEPARATOR], [VARNAME1...]) # ------------------------------------------------ m4_define([lt_decl_all_varnames], [_$0(m4_quote(m4_default([$1], [[, ]])), m4_if([$2], [], m4_quote(lt_decl_varnames), m4_quote(m4_shift($@))))[]dnl ]) m4_define([_lt_decl_all_varnames], [lt_join($@, lt_decl_varnames_tagged([$1], lt_decl_tag_varnames([[, ]], m4_shift($@))))dnl ]) # _LT_CONFIG_STATUS_DECLARE([VARNAME]) # ------------------------------------ # Quote a variable value, and forward it to 'config.status' so that its # declaration there will have the same value as in 'configure'. VARNAME # must have a single quote delimited value for this to work. m4_define([_LT_CONFIG_STATUS_DECLARE], [$1='`$ECHO "$][$1" | $SED "$delay_single_quote_subst"`']) # _LT_CONFIG_STATUS_DECLARATIONS # ------------------------------ # We delimit libtool config variables with single quotes, so when # we write them to config.status, we have to be sure to quote all # embedded single quotes properly. In configure, this macro expands # each variable declared with _LT_DECL (and _LT_TAGDECL) into: # # ='`$ECHO "$" | $SED "$delay_single_quote_subst"`' m4_defun([_LT_CONFIG_STATUS_DECLARATIONS], [m4_foreach([_lt_var], m4_quote(lt_decl_all_varnames), [m4_n([_LT_CONFIG_STATUS_DECLARE(_lt_var)])])]) # _LT_LIBTOOL_TAGS # ---------------- # Output comment and list of tags supported by the script m4_defun([_LT_LIBTOOL_TAGS], [_LT_FORMAT_COMMENT([The names of the tagged configurations supported by this script])dnl available_tags='_LT_TAGS'dnl ]) # _LT_LIBTOOL_DECLARE(VARNAME, [TAG]) # ----------------------------------- # Extract the dictionary values for VARNAME (optionally with TAG) and # expand to a commented shell variable setting: # # # Some comment about what VAR is for. # visible_name=$lt_internal_name m4_define([_LT_LIBTOOL_DECLARE], [_LT_FORMAT_COMMENT(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [description])))[]dnl m4_pushdef([_libtool_name], m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [libtool_name])))[]dnl m4_case(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [value])), [0], [_libtool_name=[$]$1], [1], [_libtool_name=$lt_[]$1], [2], [_libtool_name=$lt_[]$1], [_libtool_name=lt_dict_fetch([lt_decl_dict], [$1], [value])])[]dnl m4_ifval([$2], [_$2])[]m4_popdef([_libtool_name])[]dnl ]) # _LT_LIBTOOL_CONFIG_VARS # ----------------------- # Produce commented declarations of non-tagged libtool config variables # suitable for insertion in the LIBTOOL CONFIG section of the 'libtool' # script. Tagged libtool config variables (even for the LIBTOOL CONFIG # section) are produced by _LT_LIBTOOL_TAG_VARS. m4_defun([_LT_LIBTOOL_CONFIG_VARS], [m4_foreach([_lt_var], m4_quote(_lt_decl_filter([tagged?], [no], [], lt_decl_varnames)), [m4_n([_LT_LIBTOOL_DECLARE(_lt_var)])])]) # _LT_LIBTOOL_TAG_VARS(TAG) # ------------------------- m4_define([_LT_LIBTOOL_TAG_VARS], [m4_foreach([_lt_var], m4_quote(lt_decl_tag_varnames), [m4_n([_LT_LIBTOOL_DECLARE(_lt_var, [$1])])])]) # _LT_TAGVAR(VARNAME, [TAGNAME]) # ------------------------------ m4_define([_LT_TAGVAR], [m4_ifval([$2], [$1_$2], [$1])]) # _LT_CONFIG_COMMANDS # ------------------- # Send accumulated output to $CONFIG_STATUS. Thanks to the lists of # variables for single and double quote escaping we saved from calls # to _LT_DECL, we can put quote escaped variables declarations # into 'config.status', and then the shell code to quote escape them in # for loops in 'config.status'. Finally, any additional code accumulated # from calls to _LT_CONFIG_LIBTOOL_INIT is expanded. m4_defun([_LT_CONFIG_COMMANDS], [AC_PROVIDE_IFELSE([LT_OUTPUT], dnl If the libtool generation code has been placed in $CONFIG_LT, dnl instead of duplicating it all over again into config.status, dnl then we will have config.status run $CONFIG_LT later, so it dnl needs to know what name is stored there: [AC_CONFIG_COMMANDS([libtool], [$SHELL $CONFIG_LT || AS_EXIT(1)], [CONFIG_LT='$CONFIG_LT'])], dnl If the libtool generation code is destined for config.status, dnl expand the accumulated commands and init code now: [AC_CONFIG_COMMANDS([libtool], [_LT_OUTPUT_LIBTOOL_COMMANDS], [_LT_OUTPUT_LIBTOOL_COMMANDS_INIT])]) ])#_LT_CONFIG_COMMANDS # Initialize. m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS_INIT], [ # The HP-UX ksh and POSIX shell print the target directory to stdout # if CDPATH is set. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH sed_quote_subst='$sed_quote_subst' double_quote_subst='$double_quote_subst' delay_variable_subst='$delay_variable_subst' _LT_CONFIG_STATUS_DECLARATIONS LTCC='$LTCC' LTCFLAGS='$LTCFLAGS' compiler='$compiler_DEFAULT' # A function that is used when there is no print builtin or printf. func_fallback_echo () { eval 'cat <<_LTECHO_EOF \$[]1 _LTECHO_EOF' } # Quote evaled strings. for var in lt_decl_all_varnames([[ \ ]], lt_decl_quote_varnames); do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[[\\\\\\\`\\"\\\$]]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done # Double-quote double-evaled strings. for var in lt_decl_all_varnames([[ \ ]], lt_decl_dquote_varnames); do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[[\\\\\\\`\\"\\\$]]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done _LT_OUTPUT_LIBTOOL_INIT ]) # _LT_GENERATED_FILE_INIT(FILE, [COMMENT]) # ------------------------------------ # Generate a child script FILE with all initialization necessary to # reuse the environment learned by the parent script, and make the # file executable. If COMMENT is supplied, it is inserted after the # '#!' sequence but before initialization text begins. After this # macro, additional text can be appended to FILE to form the body of # the child script. The macro ends with non-zero status if the # file could not be fully written (such as if the disk is full). m4_ifdef([AS_INIT_GENERATED], [m4_defun([_LT_GENERATED_FILE_INIT],[AS_INIT_GENERATED($@)])], [m4_defun([_LT_GENERATED_FILE_INIT], [m4_require([AS_PREPARE])]dnl [m4_pushdef([AS_MESSAGE_LOG_FD])]dnl [lt_write_fail=0 cat >$1 <<_ASEOF || lt_write_fail=1 #! $SHELL # Generated by $as_me. $2 SHELL=\${CONFIG_SHELL-$SHELL} export SHELL _ASEOF cat >>$1 <<\_ASEOF || lt_write_fail=1 AS_SHELL_SANITIZE _AS_PREPARE exec AS_MESSAGE_FD>&1 _ASEOF test 0 = "$lt_write_fail" && chmod +x $1[]dnl m4_popdef([AS_MESSAGE_LOG_FD])])])# _LT_GENERATED_FILE_INIT # LT_OUTPUT # --------- # This macro allows early generation of the libtool script (before # AC_OUTPUT is called), incase it is used in configure for compilation # tests. AC_DEFUN([LT_OUTPUT], [: ${CONFIG_LT=./config.lt} AC_MSG_NOTICE([creating $CONFIG_LT]) _LT_GENERATED_FILE_INIT(["$CONFIG_LT"], [# Run this file to recreate a libtool stub with the current configuration.]) cat >>"$CONFIG_LT" <<\_LTEOF lt_cl_silent=false exec AS_MESSAGE_LOG_FD>>config.log { echo AS_BOX([Running $as_me.]) } >&AS_MESSAGE_LOG_FD lt_cl_help="\ '$as_me' creates a local libtool stub from the current configuration, for use in further configure time tests before the real libtool is generated. Usage: $[0] [[OPTIONS]] -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 Report bugs to ." lt_cl_version="\ m4_ifset([AC_PACKAGE_NAME], [AC_PACKAGE_NAME ])config.lt[]dnl m4_ifset([AC_PACKAGE_VERSION], [ AC_PACKAGE_VERSION]) configured by $[0], generated by m4_PACKAGE_STRING. Copyright (C) 2011 Free Software Foundation, Inc. This config.lt script is free software; the Free Software Foundation gives unlimited permision to copy, distribute and modify it." while test 0 != $[#] do case $[1] in --version | --v* | -V ) echo "$lt_cl_version"; exit 0 ;; --help | --h* | -h ) echo "$lt_cl_help"; exit 0 ;; --debug | --d* | -d ) debug=: ;; --quiet | --q* | --silent | --s* | -q ) lt_cl_silent=: ;; -*) AC_MSG_ERROR([unrecognized option: $[1] Try '$[0] --help' for more information.]) ;; *) AC_MSG_ERROR([unrecognized argument: $[1] Try '$[0] --help' for more information.]) ;; esac shift done if $lt_cl_silent; then exec AS_MESSAGE_FD>/dev/null fi _LTEOF cat >>"$CONFIG_LT" <<_LTEOF _LT_OUTPUT_LIBTOOL_COMMANDS_INIT _LTEOF cat >>"$CONFIG_LT" <<\_LTEOF AC_MSG_NOTICE([creating $ofile]) _LT_OUTPUT_LIBTOOL_COMMANDS AS_EXIT(0) _LTEOF chmod +x "$CONFIG_LT" # configure is writing to config.log, but config.lt does its own redirection, # appending to config.log, which fails on DOS, as config.log is still kept # open by configure. Here we exec the FD to /dev/null, effectively closing # config.log, so it can be properly (re)opened and appended to by config.lt. lt_cl_success=: test yes = "$silent" && lt_config_lt_args="$lt_config_lt_args --quiet" exec AS_MESSAGE_LOG_FD>/dev/null $SHELL "$CONFIG_LT" $lt_config_lt_args || lt_cl_success=false exec AS_MESSAGE_LOG_FD>>config.log $lt_cl_success || AS_EXIT(1) ])# LT_OUTPUT # _LT_CONFIG(TAG) # --------------- # If TAG is the built-in tag, create an initial libtool script with a # default configuration from the untagged config vars. Otherwise add code # to config.status for appending the configuration named by TAG from the # matching tagged config vars. m4_defun([_LT_CONFIG], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl _LT_CONFIG_SAVE_COMMANDS([ m4_define([_LT_TAG], m4_if([$1], [], [C], [$1]))dnl m4_if(_LT_TAG, [C], [ # See if we are running on zsh, and set the options that allow our # commands through without removal of \ escapes. if test -n "${ZSH_VERSION+set}"; then setopt NO_GLOB_SUBST fi cfgfile=${ofile}T trap "$RM \"$cfgfile\"; exit 1" 1 2 15 $RM "$cfgfile" cat <<_LT_EOF >> "$cfgfile" #! $SHELL # Generated automatically by $as_me ($PACKAGE) $VERSION # Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: # NOTE: Changes made to this file will be lost: look at ltmain.sh. # Provide generalized library-building support services. # Written by Gordon Matzigkeit, 1996 _LT_COPYING _LT_LIBTOOL_TAGS # Configured defaults for sys_lib_dlsearch_path munging. : \${LT_SYS_LIBRARY_PATH="$configure_time_lt_sys_library_path"} # ### BEGIN LIBTOOL CONFIG _LT_LIBTOOL_CONFIG_VARS _LT_LIBTOOL_TAG_VARS # ### END LIBTOOL CONFIG _LT_EOF cat <<'_LT_EOF' >> "$cfgfile" # ### BEGIN FUNCTIONS SHARED WITH CONFIGURE _LT_PREPARE_MUNGE_PATH_LIST _LT_PREPARE_CC_BASENAME # ### END FUNCTIONS SHARED WITH CONFIGURE _LT_EOF case $host_os in aix3*) cat <<\_LT_EOF >> "$cfgfile" # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test set != "${COLLECT_NAMES+set}"; then COLLECT_NAMES= export COLLECT_NAMES fi _LT_EOF ;; esac _LT_PROG_LTMAIN # We use sed instead of cat because bash on DJGPP gets confused if # if finds mixed CR/LF and LF-only lines. Since sed operates in # text mode, it properly converts lines to CR/LF. This bash problem # is reportedly fixed, but why not run on old versions too? $SED '$q' "$ltmain" >> "$cfgfile" \ || (rm -f "$cfgfile"; exit 1) mv -f "$cfgfile" "$ofile" || (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") chmod +x "$ofile" ], [cat <<_LT_EOF >> "$ofile" dnl Unfortunately we have to use $1 here, since _LT_TAG is not expanded dnl in a comment (ie after a #). # ### BEGIN LIBTOOL TAG CONFIG: $1 _LT_LIBTOOL_TAG_VARS(_LT_TAG) # ### END LIBTOOL TAG CONFIG: $1 _LT_EOF ])dnl /m4_if ], [m4_if([$1], [], [ PACKAGE='$PACKAGE' VERSION='$VERSION' RM='$RM' ofile='$ofile'], []) ])dnl /_LT_CONFIG_SAVE_COMMANDS ])# _LT_CONFIG # LT_SUPPORTED_TAG(TAG) # --------------------- # Trace this macro to discover what tags are supported by the libtool # --tag option, using: # autoconf --trace 'LT_SUPPORTED_TAG:$1' AC_DEFUN([LT_SUPPORTED_TAG], []) # C support is built-in for now m4_define([_LT_LANG_C_enabled], []) m4_define([_LT_TAGS], []) # LT_LANG(LANG) # ------------- # Enable libtool support for the given language if not already enabled. AC_DEFUN([LT_LANG], [AC_BEFORE([$0], [LT_OUTPUT])dnl m4_case([$1], [C], [_LT_LANG(C)], [C++], [_LT_LANG(CXX)], [Go], [_LT_LANG(GO)], [Java], [_LT_LANG(GCJ)], [Fortran 77], [_LT_LANG(F77)], [Fortran], [_LT_LANG(FC)], [Windows Resource], [_LT_LANG(RC)], [m4_ifdef([_LT_LANG_]$1[_CONFIG], [_LT_LANG($1)], [m4_fatal([$0: unsupported language: "$1"])])])dnl ])# LT_LANG # _LT_LANG(LANGNAME) # ------------------ m4_defun([_LT_LANG], [m4_ifdef([_LT_LANG_]$1[_enabled], [], [LT_SUPPORTED_TAG([$1])dnl m4_append([_LT_TAGS], [$1 ])dnl m4_define([_LT_LANG_]$1[_enabled], [])dnl _LT_LANG_$1_CONFIG($1)])dnl ])# _LT_LANG m4_ifndef([AC_PROG_GO], [ ############################################################ # NOTE: This macro has been submitted for inclusion into # # GNU Autoconf as AC_PROG_GO. When it is available in # # a released version of Autoconf we should remove this # # macro and use it instead. # ############################################################ m4_defun([AC_PROG_GO], [AC_LANG_PUSH(Go)dnl AC_ARG_VAR([GOC], [Go compiler command])dnl AC_ARG_VAR([GOFLAGS], [Go compiler flags])dnl _AC_ARG_VAR_LDFLAGS()dnl AC_CHECK_TOOL(GOC, gccgo) if test -z "$GOC"; then if test -n "$ac_tool_prefix"; then AC_CHECK_PROG(GOC, [${ac_tool_prefix}gccgo], [${ac_tool_prefix}gccgo]) fi fi if test -z "$GOC"; then AC_CHECK_PROG(GOC, gccgo, gccgo, false) fi ])#m4_defun ])#m4_ifndef # _LT_LANG_DEFAULT_CONFIG # ----------------------- m4_defun([_LT_LANG_DEFAULT_CONFIG], [AC_PROVIDE_IFELSE([AC_PROG_CXX], [LT_LANG(CXX)], [m4_define([AC_PROG_CXX], defn([AC_PROG_CXX])[LT_LANG(CXX)])]) AC_PROVIDE_IFELSE([AC_PROG_F77], [LT_LANG(F77)], [m4_define([AC_PROG_F77], defn([AC_PROG_F77])[LT_LANG(F77)])]) AC_PROVIDE_IFELSE([AC_PROG_FC], [LT_LANG(FC)], [m4_define([AC_PROG_FC], defn([AC_PROG_FC])[LT_LANG(FC)])]) dnl The call to [A][M_PROG_GCJ] is quoted like that to stop aclocal dnl pulling things in needlessly. AC_PROVIDE_IFELSE([AC_PROG_GCJ], [LT_LANG(GCJ)], [AC_PROVIDE_IFELSE([A][M_PROG_GCJ], [LT_LANG(GCJ)], [AC_PROVIDE_IFELSE([LT_PROG_GCJ], [LT_LANG(GCJ)], [m4_ifdef([AC_PROG_GCJ], [m4_define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[LT_LANG(GCJ)])]) m4_ifdef([A][M_PROG_GCJ], [m4_define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[LT_LANG(GCJ)])]) m4_ifdef([LT_PROG_GCJ], [m4_define([LT_PROG_GCJ], defn([LT_PROG_GCJ])[LT_LANG(GCJ)])])])])]) AC_PROVIDE_IFELSE([AC_PROG_GO], [LT_LANG(GO)], [m4_define([AC_PROG_GO], defn([AC_PROG_GO])[LT_LANG(GO)])]) AC_PROVIDE_IFELSE([LT_PROG_RC], [LT_LANG(RC)], [m4_define([LT_PROG_RC], defn([LT_PROG_RC])[LT_LANG(RC)])]) ])# _LT_LANG_DEFAULT_CONFIG # Obsolete macros: AU_DEFUN([AC_LIBTOOL_CXX], [LT_LANG(C++)]) AU_DEFUN([AC_LIBTOOL_F77], [LT_LANG(Fortran 77)]) AU_DEFUN([AC_LIBTOOL_FC], [LT_LANG(Fortran)]) AU_DEFUN([AC_LIBTOOL_GCJ], [LT_LANG(Java)]) AU_DEFUN([AC_LIBTOOL_RC], [LT_LANG(Windows Resource)]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_CXX], []) dnl AC_DEFUN([AC_LIBTOOL_F77], []) dnl AC_DEFUN([AC_LIBTOOL_FC], []) dnl AC_DEFUN([AC_LIBTOOL_GCJ], []) dnl AC_DEFUN([AC_LIBTOOL_RC], []) # _LT_TAG_COMPILER # ---------------- m4_defun([_LT_TAG_COMPILER], [AC_REQUIRE([AC_PROG_CC])dnl _LT_DECL([LTCC], [CC], [1], [A C compiler])dnl _LT_DECL([LTCFLAGS], [CFLAGS], [1], [LTCC compiler flags])dnl _LT_TAGDECL([CC], [compiler], [1], [A language specific compiler])dnl _LT_TAGDECL([with_gcc], [GCC], [0], [Is the compiler the GNU compiler?])dnl # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} # If no C compiler flags were specified, use CFLAGS. LTCFLAGS=${LTCFLAGS-"$CFLAGS"} # Allow CC to be a program name with arguments. compiler=$CC ])# _LT_TAG_COMPILER # _LT_COMPILER_BOILERPLATE # ------------------------ # Check for compiler boilerplate output or warnings with # the simple compiler test code. m4_defun([_LT_COMPILER_BOILERPLATE], [m4_require([_LT_DECL_SED])dnl ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" >conftest.$ac_ext eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_compiler_boilerplate=`cat conftest.err` $RM conftest* ])# _LT_COMPILER_BOILERPLATE # _LT_LINKER_BOILERPLATE # ---------------------- # Check for linker boilerplate output or warnings with # the simple link test code. m4_defun([_LT_LINKER_BOILERPLATE], [m4_require([_LT_DECL_SED])dnl ac_outfile=conftest.$ac_objext echo "$lt_simple_link_test_code" >conftest.$ac_ext eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_linker_boilerplate=`cat conftest.err` $RM -r conftest* ])# _LT_LINKER_BOILERPLATE # _LT_REQUIRED_DARWIN_CHECKS # ------------------------- m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[ case $host_os in rhapsody* | darwin*) AC_CHECK_TOOL([DSYMUTIL], [dsymutil], [:]) AC_CHECK_TOOL([NMEDIT], [nmedit], [:]) AC_CHECK_TOOL([LIPO], [lipo], [:]) AC_CHECK_TOOL([OTOOL], [otool], [:]) AC_CHECK_TOOL([OTOOL64], [otool64], [:]) _LT_DECL([], [DSYMUTIL], [1], [Tool to manipulate archived DWARF debug symbol files on Mac OS X]) _LT_DECL([], [NMEDIT], [1], [Tool to change global to local symbols on Mac OS X]) _LT_DECL([], [LIPO], [1], [Tool to manipulate fat objects and archives on Mac OS X]) _LT_DECL([], [OTOOL], [1], [ldd/readelf like tool for Mach-O binaries on Mac OS X]) _LT_DECL([], [OTOOL64], [1], [ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4]) AC_CACHE_CHECK([for -single_module linker flag],[lt_cv_apple_cc_single_mod], [lt_cv_apple_cc_single_mod=no if test -z "$LT_MULTI_MODULE"; then # By default we will add the -single_module flag. You can override # by either setting the environment variable LT_MULTI_MODULE # non-empty at configure time, or by adding -multi_module to the # link flags. rm -rf libconftest.dylib* echo "int foo(void){return 1;}" > conftest.c echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c" >&AS_MESSAGE_LOG_FD $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c 2>conftest.err _lt_result=$? # If there is a non-empty error log, and "single_module" # appears in it, assume the flag caused a linker warning if test -s conftest.err && $GREP single_module conftest.err; then cat conftest.err >&AS_MESSAGE_LOG_FD # Otherwise, if the output was created with a 0 exit code from # the compiler, it worked. elif test -f libconftest.dylib && test 0 = "$_lt_result"; then lt_cv_apple_cc_single_mod=yes else cat conftest.err >&AS_MESSAGE_LOG_FD fi rm -rf libconftest.dylib* rm -f conftest.* fi]) AC_CACHE_CHECK([for -exported_symbols_list linker flag], [lt_cv_ld_exported_symbols_list], [lt_cv_ld_exported_symbols_list=no save_LDFLAGS=$LDFLAGS echo "_main" > conftest.sym LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], [lt_cv_ld_exported_symbols_list=yes], [lt_cv_ld_exported_symbols_list=no]) LDFLAGS=$save_LDFLAGS ]) AC_CACHE_CHECK([for -force_load linker flag],[lt_cv_ld_force_load], [lt_cv_ld_force_load=no cat > conftest.c << _LT_EOF int forced_loaded() { return 2;} _LT_EOF echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&AS_MESSAGE_LOG_FD $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&AS_MESSAGE_LOG_FD echo "$AR $AR_FLAGS libconftest.a conftest.o" >&AS_MESSAGE_LOG_FD $AR $AR_FLAGS libconftest.a conftest.o 2>&AS_MESSAGE_LOG_FD echo "$RANLIB libconftest.a" >&AS_MESSAGE_LOG_FD $RANLIB libconftest.a 2>&AS_MESSAGE_LOG_FD cat > conftest.c << _LT_EOF int main() { return 0;} _LT_EOF echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&AS_MESSAGE_LOG_FD $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err _lt_result=$? if test -s conftest.err && $GREP force_load conftest.err; then cat conftest.err >&AS_MESSAGE_LOG_FD elif test -f conftest && test 0 = "$_lt_result" && $GREP forced_load conftest >/dev/null 2>&1; then lt_cv_ld_force_load=yes else cat conftest.err >&AS_MESSAGE_LOG_FD fi rm -f conftest.err libconftest.a conftest conftest.c rm -rf conftest.dSYM ]) case $host_os in rhapsody* | darwin1.[[012]]) _lt_dar_allow_undefined='$wl-undefined ${wl}suppress' ;; darwin1.*) _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; darwin*) case $MACOSX_DEPLOYMENT_TARGET,$host in 10.[[012]],*|,*powerpc*-darwin[[5-8]]*) _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; *) _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; esac ;; esac if test yes = "$lt_cv_apple_cc_single_mod"; then _lt_dar_single_mod='$single_module' fi if test yes = "$lt_cv_ld_exported_symbols_list"; then _lt_dar_export_syms=' $wl-exported_symbols_list,$output_objdir/$libname-symbols.expsym' else _lt_dar_export_syms='~$NMEDIT -s $output_objdir/$libname-symbols.expsym $lib' fi if test : != "$DSYMUTIL" && test no = "$lt_cv_ld_force_load"; then _lt_dsymutil='~$DSYMUTIL $lib || :' else _lt_dsymutil= fi ;; esac ]) # _LT_DARWIN_LINKER_FEATURES([TAG]) # --------------------------------- # Checks for linker and compiler features on darwin m4_defun([_LT_DARWIN_LINKER_FEATURES], [ m4_require([_LT_REQUIRED_DARWIN_CHECKS]) _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_automatic, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported if test yes = "$lt_cv_ld_force_load"; then _LT_TAGVAR(whole_archive_flag_spec, $1)='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience $wl-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' m4_case([$1], [F77], [_LT_TAGVAR(compiler_needs_object, $1)=yes], [FC], [_LT_TAGVAR(compiler_needs_object, $1)=yes]) else _LT_TAGVAR(whole_archive_flag_spec, $1)='' fi _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(allow_undefined_flag, $1)=$_lt_dar_allow_undefined case $cc_basename in ifort*|nagfor*) _lt_dar_can_shared=yes ;; *) _lt_dar_can_shared=$GCC ;; esac if test yes = "$_lt_dar_can_shared"; then output_verbose_link_cmd=func_echo_all _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil" _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil" _LT_TAGVAR(archive_expsym_cmds, $1)="$SED 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil" _LT_TAGVAR(module_expsym_cmds, $1)="$SED -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil" m4_if([$1], [CXX], [ if test yes != "$lt_cv_apple_cc_single_mod"; then _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dsymutil" _LT_TAGVAR(archive_expsym_cmds, $1)="$SED 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dar_export_syms$_lt_dsymutil" fi ],[]) else _LT_TAGVAR(ld_shlibs, $1)=no fi ]) # _LT_SYS_MODULE_PATH_AIX([TAGNAME]) # ---------------------------------- # Links a minimal program and checks the executable # for the system default hardcoded library path. In most cases, # this is /usr/lib:/lib, but when the MPI compilers are used # the location of the communication and MPI libs are included too. # If we don't find anything, use the default library path according # to the aix ld manual. # Store the results from the different compilers for each TAGNAME. # Allow to override them for all tags through lt_cv_aix_libpath. m4_defun([_LT_SYS_MODULE_PATH_AIX], [m4_require([_LT_DECL_SED])dnl if test set = "${lt_cv_aix_libpath+set}"; then aix_libpath=$lt_cv_aix_libpath else AC_CACHE_VAL([_LT_TAGVAR([lt_cv_aix_libpath_], [$1])], [AC_LINK_IFELSE([AC_LANG_PROGRAM],[ lt_aix_libpath_sed='[ /Import File Strings/,/^$/ { /^0/ { s/^0 *\([^ ]*\) *$/\1/ p } }]' _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi],[]) if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=/usr/lib:/lib fi ]) aix_libpath=$_LT_TAGVAR([lt_cv_aix_libpath_], [$1]) fi ])# _LT_SYS_MODULE_PATH_AIX # _LT_SHELL_INIT(ARG) # ------------------- m4_define([_LT_SHELL_INIT], [m4_divert_text([M4SH-INIT], [$1 ])])# _LT_SHELL_INIT # _LT_PROG_ECHO_BACKSLASH # ----------------------- # Find how we can fake an echo command that does not interpret backslash. # In particular, with Autoconf 2.60 or later we add some code to the start # of the generated configure script that will find a shell with a builtin # printf (that we can use as an echo command). m4_defun([_LT_PROG_ECHO_BACKSLASH], [ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO AC_MSG_CHECKING([how to print strings]) # Test print first, because it will be a builtin if present. if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then ECHO='print -r --' elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then ECHO='printf %s\n' else # Use this function as a fallback that always works. func_fallback_echo () { eval 'cat <<_LTECHO_EOF $[]1 _LTECHO_EOF' } ECHO='func_fallback_echo' fi # func_echo_all arg... # Invoke $ECHO with all args, space-separated. func_echo_all () { $ECHO "$*" } case $ECHO in printf*) AC_MSG_RESULT([printf]) ;; print*) AC_MSG_RESULT([print -r]) ;; *) AC_MSG_RESULT([cat]) ;; esac m4_ifdef([_AS_DETECT_SUGGESTED], [_AS_DETECT_SUGGESTED([ test -n "${ZSH_VERSION+set}${BASH_VERSION+set}" || ( ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO PATH=/empty FPATH=/empty; export PATH FPATH test "X`printf %s $ECHO`" = "X$ECHO" \ || test "X`print -r -- $ECHO`" = "X$ECHO" )])]) _LT_DECL([], [SHELL], [1], [Shell to use when invoking shell scripts]) _LT_DECL([], [ECHO], [1], [An echo program that protects backslashes]) ])# _LT_PROG_ECHO_BACKSLASH # _LT_WITH_SYSROOT # ---------------- AC_DEFUN([_LT_WITH_SYSROOT], [m4_require([_LT_DECL_SED])dnl AC_MSG_CHECKING([for sysroot]) AC_ARG_WITH([sysroot], [AS_HELP_STRING([--with-sysroot@<:@=DIR@:>@], [Search for dependent libraries within DIR (or the compiler's sysroot if not specified).])], [], [with_sysroot=no]) dnl lt_sysroot will always be passed unquoted. We quote it here dnl in case the user passed a directory name. lt_sysroot= case $with_sysroot in #( yes) if test yes = "$GCC"; then lt_sysroot=`$CC --print-sysroot 2>/dev/null` fi ;; #( /*) lt_sysroot=`echo "$with_sysroot" | $SED -e "$sed_quote_subst"` ;; #( no|'') ;; #( *) AC_MSG_RESULT([$with_sysroot]) AC_MSG_ERROR([The sysroot must be an absolute path.]) ;; esac AC_MSG_RESULT([${lt_sysroot:-no}]) _LT_DECL([], [lt_sysroot], [0], [The root where to search for ]dnl [dependent libraries, and where our libraries should be installed.])]) # _LT_ENABLE_LOCK # --------------- m4_defun([_LT_ENABLE_LOCK], [AC_ARG_ENABLE([libtool-lock], [AS_HELP_STRING([--disable-libtool-lock], [avoid locking (might break parallel builds)])]) test no = "$enable_libtool_lock" || enable_libtool_lock=yes # Some flags need to be propagated to the compiler or linker for good # libtool support. case $host in ia64-*-hpux*) # Find out what ABI is being produced by ac_compile, and set mode # options accordingly. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then case `$FILECMD conftest.$ac_objext` in *ELF-32*) HPUX_IA64_MODE=32 ;; *ELF-64*) HPUX_IA64_MODE=64 ;; esac fi rm -rf conftest* ;; *-*-irix6*) # Find out what ABI is being produced by ac_compile, and set linker # options accordingly. echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then if test yes = "$lt_cv_prog_gnu_ld"; then case `$FILECMD conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -melf32bsmip" ;; *N32*) LD="${LD-ld} -melf32bmipn32" ;; *64-bit*) LD="${LD-ld} -melf64bmip" ;; esac else case `$FILECMD conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -32" ;; *N32*) LD="${LD-ld} -n32" ;; *64-bit*) LD="${LD-ld} -64" ;; esac fi fi rm -rf conftest* ;; mips64*-*linux*) # Find out what ABI is being produced by ac_compile, and set linker # options accordingly. echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then emul=elf case `$FILECMD conftest.$ac_objext` in *32-bit*) emul="${emul}32" ;; *64-bit*) emul="${emul}64" ;; esac case `$FILECMD conftest.$ac_objext` in *MSB*) emul="${emul}btsmip" ;; *LSB*) emul="${emul}ltsmip" ;; esac case `$FILECMD conftest.$ac_objext` in *N32*) emul="${emul}n32" ;; esac LD="${LD-ld} -m $emul" fi rm -rf conftest* ;; x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) # Find out what ABI is being produced by ac_compile, and set linker # options accordingly. Note that the listed cases only cover the # situations where additional linker options are needed (such as when # doing 32-bit compilation for a host where ld defaults to 64-bit, or # vice versa); the common cases where no linker options are needed do # not appear in the list. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then case `$FILECMD conftest.o` in *32-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_i386_fbsd" ;; x86_64-*linux*) case `$FILECMD conftest.o` in *x86-64*) LD="${LD-ld} -m elf32_x86_64" ;; *) LD="${LD-ld} -m elf_i386" ;; esac ;; powerpc64le-*linux*) LD="${LD-ld} -m elf32lppclinux" ;; powerpc64-*linux*) LD="${LD-ld} -m elf32ppclinux" ;; s390x-*linux*) LD="${LD-ld} -m elf_s390" ;; sparc64-*linux*) LD="${LD-ld} -m elf32_sparc" ;; esac ;; *64-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_x86_64_fbsd" ;; x86_64-*linux*) LD="${LD-ld} -m elf_x86_64" ;; powerpcle-*linux*) LD="${LD-ld} -m elf64lppc" ;; powerpc-*linux*) LD="${LD-ld} -m elf64ppc" ;; s390*-*linux*|s390*-*tpf*) LD="${LD-ld} -m elf64_s390" ;; sparc*-*linux*) LD="${LD-ld} -m elf64_sparc" ;; esac ;; esac fi rm -rf conftest* ;; *-*-sco3.2v5*) # On SCO OpenServer 5, we need -belf to get full-featured binaries. SAVE_CFLAGS=$CFLAGS CFLAGS="$CFLAGS -belf" AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf, [AC_LANG_PUSH(C) AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],[[]])],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no]) AC_LANG_POP]) if test yes != "$lt_cv_cc_needs_belf"; then # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf CFLAGS=$SAVE_CFLAGS fi ;; *-*solaris*) # Find out what ABI is being produced by ac_compile, and set linker # options accordingly. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then case `$FILECMD conftest.o` in *64-bit*) case $lt_cv_prog_gnu_ld in yes*) case $host in i?86-*-solaris*|x86_64-*-solaris*) LD="${LD-ld} -m elf_x86_64" ;; sparc*-*-solaris*) LD="${LD-ld} -m elf64_sparc" ;; esac # GNU ld 2.21 introduced _sol2 emulations. Use them if available. if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then LD=${LD-ld}_sol2 fi ;; *) if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then LD="${LD-ld} -64" fi ;; esac ;; esac fi rm -rf conftest* ;; esac need_locks=$enable_libtool_lock ])# _LT_ENABLE_LOCK # _LT_PROG_AR # ----------- m4_defun([_LT_PROG_AR], [AC_CHECK_TOOLS(AR, [ar], false) : ${AR=ar} _LT_DECL([], [AR], [1], [The archiver]) # Use ARFLAGS variable as AR's operation code to sync the variable naming with # Automake. If both AR_FLAGS and ARFLAGS are specified, AR_FLAGS should have # higher priority because thats what people were doing historically (setting # ARFLAGS for automake and AR_FLAGS for libtool). FIXME: Make the AR_FLAGS # variable obsoleted/removed. test ${AR_FLAGS+y} || AR_FLAGS=${ARFLAGS-cr} lt_ar_flags=$AR_FLAGS _LT_DECL([], [lt_ar_flags], [0], [Flags to create an archive (by configure)]) # Make AR_FLAGS overridable by 'make ARFLAGS='. Don't try to run-time override # by AR_FLAGS because that was never working and AR_FLAGS is about to die. _LT_DECL([], [AR_FLAGS], [\@S|@{ARFLAGS-"\@S|@lt_ar_flags"}], [Flags to create an archive]) AC_CACHE_CHECK([for archiver @FILE support], [lt_cv_ar_at_file], [lt_cv_ar_at_file=no AC_COMPILE_IFELSE([AC_LANG_PROGRAM], [echo conftest.$ac_objext > conftest.lst lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&AS_MESSAGE_LOG_FD' AC_TRY_EVAL([lt_ar_try]) if test 0 -eq "$ac_status"; then # Ensure the archiver fails upon bogus file names. rm -f conftest.$ac_objext libconftest.a AC_TRY_EVAL([lt_ar_try]) if test 0 -ne "$ac_status"; then lt_cv_ar_at_file=@ fi fi rm -f conftest.* libconftest.a ]) ]) if test no = "$lt_cv_ar_at_file"; then archiver_list_spec= else archiver_list_spec=$lt_cv_ar_at_file fi _LT_DECL([], [archiver_list_spec], [1], [How to feed a file listing to the archiver]) ])# _LT_PROG_AR # _LT_CMD_OLD_ARCHIVE # ------------------- m4_defun([_LT_CMD_OLD_ARCHIVE], [_LT_PROG_AR AC_CHECK_TOOL(STRIP, strip, :) test -z "$STRIP" && STRIP=: _LT_DECL([], [STRIP], [1], [A symbol stripping program]) AC_CHECK_TOOL(RANLIB, ranlib, :) test -z "$RANLIB" && RANLIB=: _LT_DECL([], [RANLIB], [1], [Commands used to install an old-style archive]) # Determine commands to create old-style static archives. old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' old_postinstall_cmds='chmod 644 $oldlib' old_postuninstall_cmds= if test -n "$RANLIB"; then case $host_os in bitrig* | openbsd*) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib" ;; *) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" ;; esac old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib" fi case $host_os in darwin*) lock_old_archive_extraction=yes ;; *) lock_old_archive_extraction=no ;; esac _LT_DECL([], [old_postinstall_cmds], [2]) _LT_DECL([], [old_postuninstall_cmds], [2]) _LT_TAGDECL([], [old_archive_cmds], [2], [Commands used to build an old-style archive]) _LT_DECL([], [lock_old_archive_extraction], [0], [Whether to use a lock for old archive extraction]) ])# _LT_CMD_OLD_ARCHIVE # _LT_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, # [OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE]) # ---------------------------------------------------------------- # Check whether the given compiler option works AC_DEFUN([_LT_COMPILER_OPTION], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_SED])dnl AC_CACHE_CHECK([$1], [$2], [$2=no m4_if([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4]) echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="$3" ## exclude from sc_useless_quotes_in_assignment # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&AS_MESSAGE_LOG_FD echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then $2=yes fi fi $RM conftest* ]) if test yes = "[$]$2"; then m4_if([$5], , :, [$5]) else m4_if([$6], , :, [$6]) fi ])# _LT_COMPILER_OPTION # Old name: AU_ALIAS([AC_LIBTOOL_COMPILER_OPTION], [_LT_COMPILER_OPTION]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], []) # _LT_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, # [ACTION-SUCCESS], [ACTION-FAILURE]) # ---------------------------------------------------- # Check whether the given linker option works AC_DEFUN([_LT_LINKER_OPTION], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_SED])dnl AC_CACHE_CHECK([$1], [$2], [$2=no save_LDFLAGS=$LDFLAGS LDFLAGS="$LDFLAGS $3" echo "$lt_simple_link_test_code" > conftest.$ac_ext if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then # The linker can only warn and ignore the option if not recognized # So say no if there are warnings if test -s conftest.err; then # Append any errors to the config.log. cat conftest.err 1>&AS_MESSAGE_LOG_FD $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if diff conftest.exp conftest.er2 >/dev/null; then $2=yes fi else $2=yes fi fi $RM -r conftest* LDFLAGS=$save_LDFLAGS ]) if test yes = "[$]$2"; then m4_if([$4], , :, [$4]) else m4_if([$5], , :, [$5]) fi ])# _LT_LINKER_OPTION # Old name: AU_ALIAS([AC_LIBTOOL_LINKER_OPTION], [_LT_LINKER_OPTION]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], []) # LT_CMD_MAX_LEN #--------------- AC_DEFUN([LT_CMD_MAX_LEN], [AC_REQUIRE([AC_CANONICAL_HOST])dnl # find the maximum length of command line arguments AC_MSG_CHECKING([the maximum length of command line arguments]) AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl i=0 teststring=ABCD case $build_os in msdosdjgpp*) # On DJGPP, this test can blow up pretty badly due to problems in libc # (any single argument exceeding 2000 bytes causes a buffer overrun # during glob expansion). Even if it were fixed, the result of this # check would be larger than it should be. lt_cv_sys_max_cmd_len=12288; # 12K is about right ;; gnu*) # Under GNU Hurd, this test is not required because there is # no limit to the length of command line arguments. # Libtool will interpret -1 as no limit whatsoever lt_cv_sys_max_cmd_len=-1; ;; cygwin* | mingw* | cegcc*) # On Win9x/ME, this test blows up -- it succeeds, but takes # about 5 minutes as the teststring grows exponentially. # Worse, since 9x/ME are not pre-emptively multitasking, # you end up with a "frozen" computer, even though with patience # the test eventually succeeds (with a max line length of 256k). # Instead, let's just punt: use the minimum linelength reported by # all of the supported platforms: 8192 (on NT/2K/XP). lt_cv_sys_max_cmd_len=8192; ;; mint*) # On MiNT this can take a long time and run out of memory. lt_cv_sys_max_cmd_len=8192; ;; amigaos*) # On AmigaOS with pdksh, this test takes hours, literally. # So we just punt and use a minimum line length of 8192. lt_cv_sys_max_cmd_len=8192; ;; bitrig* | darwin* | dragonfly* | freebsd* | midnightbsd* | netbsd* | openbsd*) # This has been around since 386BSD, at least. Likely further. if test -x /sbin/sysctl; then lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` elif test -x /usr/sbin/sysctl; then lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` else lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs fi # And add a safety zone lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` ;; interix*) # We know the value 262144 and hardcode it with a safety zone (like BSD) lt_cv_sys_max_cmd_len=196608 ;; os2*) # The test takes a long time on OS/2. lt_cv_sys_max_cmd_len=8192 ;; osf*) # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not # nice to cause kernel panics so lets avoid the loop below. # First set a reasonable default. lt_cv_sys_max_cmd_len=16384 # if test -x /sbin/sysconfig; then case `/sbin/sysconfig -q proc exec_disable_arg_limit` in *1*) lt_cv_sys_max_cmd_len=-1 ;; esac fi ;; sco3.2v5*) lt_cv_sys_max_cmd_len=102400 ;; sysv5* | sco5v6* | sysv4.2uw2*) kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` if test -n "$kargmax"; then lt_cv_sys_max_cmd_len=`echo $kargmax | $SED 's/.*[[ ]]//'` else lt_cv_sys_max_cmd_len=32768 fi ;; *) lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` if test -n "$lt_cv_sys_max_cmd_len" && \ test undefined != "$lt_cv_sys_max_cmd_len"; then lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` else # Make teststring a little bigger before we do anything with it. # a 1K string should be a reasonable start. for i in 1 2 3 4 5 6 7 8; do teststring=$teststring$teststring done SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} # If test is not a shell built-in, we'll probably end up computing a # maximum length that is only half of the actual maximum length, but # we can't tell. while { test X`env echo "$teststring$teststring" 2>/dev/null` \ = "X$teststring$teststring"; } >/dev/null 2>&1 && test 17 != "$i" # 1/2 MB should be enough do i=`expr $i + 1` teststring=$teststring$teststring done # Only check the string length outside the loop. lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` teststring= # Add a significant safety factor because C++ compilers can tack on # massive amounts of additional arguments before passing them to the # linker. It appears as though 1/2 is a usable value. lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` fi ;; esac ]) if test -n "$lt_cv_sys_max_cmd_len"; then AC_MSG_RESULT($lt_cv_sys_max_cmd_len) else AC_MSG_RESULT(none) fi max_cmd_len=$lt_cv_sys_max_cmd_len _LT_DECL([], [max_cmd_len], [0], [What is the maximum length of a command?]) ])# LT_CMD_MAX_LEN # Old name: AU_ALIAS([AC_LIBTOOL_SYS_MAX_CMD_LEN], [LT_CMD_MAX_LEN]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], []) # _LT_HEADER_DLFCN # ---------------- m4_defun([_LT_HEADER_DLFCN], [AC_CHECK_HEADERS([dlfcn.h], [], [], [AC_INCLUDES_DEFAULT])dnl ])# _LT_HEADER_DLFCN # _LT_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE, # ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING) # ---------------------------------------------------------------- m4_defun([_LT_TRY_DLOPEN_SELF], [m4_require([_LT_HEADER_DLFCN])dnl if test yes = "$cross_compiling"; then : [$4] else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF [#line $LINENO "configure" #include "confdefs.h" #if HAVE_DLFCN_H #include #endif #include #ifdef RTLD_GLOBAL # define LT_DLGLOBAL RTLD_GLOBAL #else # ifdef DL_GLOBAL # define LT_DLGLOBAL DL_GLOBAL # else # define LT_DLGLOBAL 0 # endif #endif /* We may have to define LT_DLLAZY_OR_NOW in the command line if we find out it does not work in some platform. */ #ifndef LT_DLLAZY_OR_NOW # ifdef RTLD_LAZY # define LT_DLLAZY_OR_NOW RTLD_LAZY # else # ifdef DL_LAZY # define LT_DLLAZY_OR_NOW DL_LAZY # else # ifdef RTLD_NOW # define LT_DLLAZY_OR_NOW RTLD_NOW # else # ifdef DL_NOW # define LT_DLLAZY_OR_NOW DL_NOW # else # define LT_DLLAZY_OR_NOW 0 # endif # endif # endif # endif #endif /* When -fvisibility=hidden is used, assume the code has been annotated correspondingly for the symbols needed. */ #if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) int fnord () __attribute__((visibility("default"))); #endif int fnord () { return 42; } int main () { void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); int status = $lt_dlunknown; if (self) { if (dlsym (self,"fnord")) status = $lt_dlno_uscore; else { if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; else puts (dlerror ()); } /* dlclose (self); */ } else puts (dlerror ()); return status; }] _LT_EOF if AC_TRY_EVAL(ac_link) && test -s "conftest$ac_exeext" 2>/dev/null; then (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null lt_status=$? case x$lt_status in x$lt_dlno_uscore) $1 ;; x$lt_dlneed_uscore) $2 ;; x$lt_dlunknown|x*) $3 ;; esac else : # compilation failed $3 fi fi rm -fr conftest* ])# _LT_TRY_DLOPEN_SELF # LT_SYS_DLOPEN_SELF # ------------------ AC_DEFUN([LT_SYS_DLOPEN_SELF], [m4_require([_LT_HEADER_DLFCN])dnl if test yes != "$enable_dlopen"; then enable_dlopen=unknown enable_dlopen_self=unknown enable_dlopen_self_static=unknown else lt_cv_dlopen=no lt_cv_dlopen_libs= case $host_os in beos*) lt_cv_dlopen=load_add_on lt_cv_dlopen_libs= lt_cv_dlopen_self=yes ;; mingw* | pw32* | cegcc*) lt_cv_dlopen=LoadLibrary lt_cv_dlopen_libs= ;; cygwin*) lt_cv_dlopen=dlopen lt_cv_dlopen_libs= ;; darwin*) # if libdl is installed we need to link against it AC_CHECK_LIB([dl], [dlopen], [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl],[ lt_cv_dlopen=dyld lt_cv_dlopen_libs= lt_cv_dlopen_self=yes ]) ;; tpf*) # Don't try to run any link tests for TPF. We know it's impossible # because TPF is a cross-compiler, and we know how we open DSOs. lt_cv_dlopen=dlopen lt_cv_dlopen_libs= lt_cv_dlopen_self=no ;; *) AC_CHECK_FUNC([shl_load], [lt_cv_dlopen=shl_load], [AC_CHECK_LIB([dld], [shl_load], [lt_cv_dlopen=shl_load lt_cv_dlopen_libs=-ldld], [AC_CHECK_FUNC([dlopen], [lt_cv_dlopen=dlopen], [AC_CHECK_LIB([dl], [dlopen], [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl], [AC_CHECK_LIB([svld], [dlopen], [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-lsvld], [AC_CHECK_LIB([dld], [dld_link], [lt_cv_dlopen=dld_link lt_cv_dlopen_libs=-ldld]) ]) ]) ]) ]) ]) ;; esac if test no = "$lt_cv_dlopen"; then enable_dlopen=no else enable_dlopen=yes fi case $lt_cv_dlopen in dlopen) save_CPPFLAGS=$CPPFLAGS test yes = "$ac_cv_header_dlfcn_h" && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" save_LDFLAGS=$LDFLAGS wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" save_LIBS=$LIBS LIBS="$lt_cv_dlopen_libs $LIBS" AC_CACHE_CHECK([whether a program can dlopen itself], lt_cv_dlopen_self, [dnl _LT_TRY_DLOPEN_SELF( lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes, lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross) ]) if test yes = "$lt_cv_dlopen_self"; then wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" AC_CACHE_CHECK([whether a statically linked program can dlopen itself], lt_cv_dlopen_self_static, [dnl _LT_TRY_DLOPEN_SELF( lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=no, lt_cv_dlopen_self_static=cross) ]) fi CPPFLAGS=$save_CPPFLAGS LDFLAGS=$save_LDFLAGS LIBS=$save_LIBS ;; esac case $lt_cv_dlopen_self in yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; *) enable_dlopen_self=unknown ;; esac case $lt_cv_dlopen_self_static in yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; *) enable_dlopen_self_static=unknown ;; esac fi _LT_DECL([dlopen_support], [enable_dlopen], [0], [Whether dlopen is supported]) _LT_DECL([dlopen_self], [enable_dlopen_self], [0], [Whether dlopen of programs is supported]) _LT_DECL([dlopen_self_static], [enable_dlopen_self_static], [0], [Whether dlopen of statically linked programs is supported]) ])# LT_SYS_DLOPEN_SELF # Old name: AU_ALIAS([AC_LIBTOOL_DLOPEN_SELF], [LT_SYS_DLOPEN_SELF]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], []) # _LT_COMPILER_C_O([TAGNAME]) # --------------------------- # Check to see if options -c and -o are simultaneously supported by compiler. # This macro does not hard code the compiler like AC_PROG_CC_C_O. m4_defun([_LT_COMPILER_C_O], [m4_require([_LT_DECL_SED])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_TAG_COMPILER])dnl AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext], [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)], [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no $RM -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&AS_MESSAGE_LOG_FD echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD if (exit $ac_status) && 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 $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes fi fi chmod u+w . 2>&AS_MESSAGE_LOG_FD $RM conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files $RM out/* && rmdir out cd .. $RM -r conftest $RM conftest* ]) _LT_TAGDECL([compiler_c_o], [lt_cv_prog_compiler_c_o], [1], [Does compiler simultaneously support -c and -o options?]) ])# _LT_COMPILER_C_O # _LT_COMPILER_FILE_LOCKS([TAGNAME]) # ---------------------------------- # Check to see if we can do hard links to lock some files if needed m4_defun([_LT_COMPILER_FILE_LOCKS], [m4_require([_LT_ENABLE_LOCK])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl _LT_COMPILER_C_O([$1]) hard_links=nottested if test no = "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" && test no != "$need_locks"; then # do not overwrite the value of need_locks provided by the user AC_MSG_CHECKING([if we can lock with hard links]) hard_links=yes $RM conftest* ln conftest.a conftest.b 2>/dev/null && hard_links=no touch conftest.a ln conftest.a conftest.b 2>&5 || hard_links=no ln conftest.a conftest.b 2>/dev/null && hard_links=no AC_MSG_RESULT([$hard_links]) if test no = "$hard_links"; then AC_MSG_WARN(['$CC' does not support '-c -o', so 'make -j' may be unsafe]) need_locks=warn fi else need_locks=no fi _LT_DECL([], [need_locks], [1], [Must we lock files when doing compilation?]) ])# _LT_COMPILER_FILE_LOCKS # _LT_CHECK_OBJDIR # ---------------- m4_defun([_LT_CHECK_OBJDIR], [AC_CACHE_CHECK([for objdir], [lt_cv_objdir], [rm -f .libs 2>/dev/null mkdir .libs 2>/dev/null if test -d .libs; then lt_cv_objdir=.libs else # MS-DOS does not allow filenames that begin with a dot. lt_cv_objdir=_libs fi rmdir .libs 2>/dev/null]) objdir=$lt_cv_objdir _LT_DECL([], [objdir], [0], [The name of the directory that contains temporary libtool files])dnl m4_pattern_allow([LT_OBJDIR])dnl AC_DEFINE_UNQUOTED([LT_OBJDIR], "$lt_cv_objdir/", [Define to the sub-directory where libtool stores uninstalled libraries.]) ])# _LT_CHECK_OBJDIR # _LT_LINKER_HARDCODE_LIBPATH([TAGNAME]) # -------------------------------------- # Check hardcoding attributes. m4_defun([_LT_LINKER_HARDCODE_LIBPATH], [AC_MSG_CHECKING([how to hardcode library paths into programs]) _LT_TAGVAR(hardcode_action, $1)= if test -n "$_LT_TAGVAR(hardcode_libdir_flag_spec, $1)" || test -n "$_LT_TAGVAR(runpath_var, $1)" || test yes = "$_LT_TAGVAR(hardcode_automatic, $1)"; then # We can hardcode non-existent directories. if test no != "$_LT_TAGVAR(hardcode_direct, $1)" && # If the only mechanism to avoid hardcoding is shlibpath_var, we # have to relink, otherwise we might link with an installed library # when we should be linking with a yet-to-be-installed one ## test no != "$_LT_TAGVAR(hardcode_shlibpath_var, $1)" && test no != "$_LT_TAGVAR(hardcode_minus_L, $1)"; then # Linking always hardcodes the temporary library directory. _LT_TAGVAR(hardcode_action, $1)=relink else # We can link without hardcoding, and we can hardcode nonexisting dirs. _LT_TAGVAR(hardcode_action, $1)=immediate fi else # We cannot hardcode anything, or else we can only hardcode existing # directories. _LT_TAGVAR(hardcode_action, $1)=unsupported fi AC_MSG_RESULT([$_LT_TAGVAR(hardcode_action, $1)]) if test relink = "$_LT_TAGVAR(hardcode_action, $1)" || test yes = "$_LT_TAGVAR(inherit_rpath, $1)"; then # Fast installation is not supported enable_fast_install=no elif test yes = "$shlibpath_overrides_runpath" || test no = "$enable_shared"; then # Fast installation is not necessary enable_fast_install=needless fi _LT_TAGDECL([], [hardcode_action], [0], [How to hardcode a shared library path into an executable]) ])# _LT_LINKER_HARDCODE_LIBPATH # _LT_CMD_STRIPLIB # ---------------- m4_defun([_LT_CMD_STRIPLIB], [m4_require([_LT_DECL_EGREP]) striplib= old_striplib= AC_MSG_CHECKING([whether stripping libraries is possible]) if test -z "$STRIP"; then AC_MSG_RESULT([no]) else if $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then old_striplib="$STRIP --strip-debug" striplib="$STRIP --strip-unneeded" AC_MSG_RESULT([yes]) else case $host_os in darwin*) # FIXME - insert some real tests, host_os isn't really good enough striplib="$STRIP -x" old_striplib="$STRIP -S" AC_MSG_RESULT([yes]) ;; freebsd*) if $STRIP -V 2>&1 | $GREP "elftoolchain" >/dev/null; then old_striplib="$STRIP --strip-debug" striplib="$STRIP --strip-unneeded" AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) fi ;; *) AC_MSG_RESULT([no]) ;; esac fi fi _LT_DECL([], [old_striplib], [1], [Commands to strip libraries]) _LT_DECL([], [striplib], [1]) ])# _LT_CMD_STRIPLIB # _LT_PREPARE_MUNGE_PATH_LIST # --------------------------- # Make sure func_munge_path_list() is defined correctly. m4_defun([_LT_PREPARE_MUNGE_PATH_LIST], [[# func_munge_path_list VARIABLE PATH # ----------------------------------- # VARIABLE is name of variable containing _space_ separated list of # directories to be munged by the contents of PATH, which is string # having a format: # "DIR[:DIR]:" # string "DIR[ DIR]" will be prepended to VARIABLE # ":DIR[:DIR]" # string "DIR[ DIR]" will be appended to VARIABLE # "DIRP[:DIRP]::[DIRA:]DIRA" # string "DIRP[ DIRP]" will be prepended to VARIABLE and string # "DIRA[ DIRA]" will be appended to VARIABLE # "DIR[:DIR]" # VARIABLE will be replaced by "DIR[ DIR]" func_munge_path_list () { case x@S|@2 in x) ;; *:) eval @S|@1=\"`$ECHO @S|@2 | $SED 's/:/ /g'` \@S|@@S|@1\" ;; x:*) eval @S|@1=\"\@S|@@S|@1 `$ECHO @S|@2 | $SED 's/:/ /g'`\" ;; *::*) eval @S|@1=\"\@S|@@S|@1\ `$ECHO @S|@2 | $SED -e 's/.*:://' -e 's/:/ /g'`\" eval @S|@1=\"`$ECHO @S|@2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \@S|@@S|@1\" ;; *) eval @S|@1=\"`$ECHO @S|@2 | $SED 's/:/ /g'`\" ;; esac } ]])# _LT_PREPARE_PATH_LIST # _LT_SYS_DYNAMIC_LINKER([TAG]) # ----------------------------- # PORTME Fill in your ld.so characteristics m4_defun([_LT_SYS_DYNAMIC_LINKER], [AC_REQUIRE([AC_CANONICAL_HOST])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_OBJDUMP])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_CHECK_SHELL_FEATURES])dnl m4_require([_LT_PREPARE_MUNGE_PATH_LIST])dnl AC_MSG_CHECKING([dynamic linker characteristics]) m4_if([$1], [], [ if test yes = "$GCC"; then case $host_os in darwin*) lt_awk_arg='/^libraries:/,/LR/' ;; *) lt_awk_arg='/^libraries:/' ;; esac case $host_os in mingw* | cegcc*) lt_sed_strip_eq='s|=\([[A-Za-z]]:\)|\1|g' ;; *) lt_sed_strip_eq='s|=/|/|g' ;; esac lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` case $lt_search_path_spec in *\;*) # if the path contains ";" then we assume it to be the separator # otherwise default to the standard path separator (i.e. ":") - it is # assumed that no part of a normal pathname contains ";" but that should # okay in the real world where ";" in dirpaths is itself problematic. lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` ;; *) lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` ;; esac # Ok, now we have the path, separated by spaces, we can step through it # and add multilib dir if necessary... lt_tmp_lt_search_path_spec= lt_multi_os_dir=/`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` # ...but if some path component already ends with the multilib dir we assume # that all is fine and trust -print-search-dirs as is (GCC 4.2? or newer). case "$lt_multi_os_dir; $lt_search_path_spec " in "/; "* | "/.; "* | "/./; "* | *"$lt_multi_os_dir "* | *"$lt_multi_os_dir/ "*) lt_multi_os_dir= ;; esac for lt_sys_path in $lt_search_path_spec; do if test -d "$lt_sys_path$lt_multi_os_dir"; then lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path$lt_multi_os_dir" elif test -n "$lt_multi_os_dir"; then test -d "$lt_sys_path" && \ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" fi done lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' BEGIN {RS = " "; FS = "/|\n";} { lt_foo = ""; lt_count = 0; for (lt_i = NF; lt_i > 0; lt_i--) { if ($lt_i != "" && $lt_i != ".") { if ($lt_i == "..") { lt_count++; } else { if (lt_count == 0) { lt_foo = "/" $lt_i lt_foo; } else { lt_count--; } } } } if (lt_foo != "") { lt_freq[[lt_foo]]++; } if (lt_freq[[lt_foo]] == 1) { print lt_foo; } }'` # AWK program above erroneously prepends '/' to C:/dos/paths # for these hosts. case $host_os in mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ $SED 's|/\([[A-Za-z]]:\)|\1|g'` ;; esac sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` else sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" fi]) library_names_spec= libname_spec='lib$name' soname_spec= shrext_cmds=.so postinstall_cmds= postuninstall_cmds= finish_cmds= finish_eval= shlibpath_var= shlibpath_overrides_runpath=unknown version_type=none dynamic_linker="$host_os ld.so" sys_lib_dlsearch_path_spec="/lib /usr/lib" need_lib_prefix=unknown hardcode_into_libs=no # when you set need_version to no, make sure it does not cause -set_version # flags to be left without arguments need_version=unknown AC_ARG_VAR([LT_SYS_LIBRARY_PATH], [User-defined run-time library search path.]) case $host_os in aix3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname.a' shlibpath_var=LIBPATH # AIX 3 has no versioning support, so we append a major version to the name. soname_spec='$libname$release$shared_ext$major' ;; aix[[4-9]]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no hardcode_into_libs=yes if test ia64 = "$host_cpu"; then # AIX 5 supports IA64 library_names_spec='$libname$release$shared_ext$major $libname$release$shared_ext$versuffix $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH else # With GCC up to 2.95.x, collect2 would create an import file # for dependence libraries. The import file would start with # the line '#! .'. This would cause the generated library to # depend on '.', always an invalid library. This was fixed in # development snapshots of GCC prior to 3.0. case $host_os in aix4 | aix4.[[01]] | aix4.[[01]].*) if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' echo ' yes ' echo '#endif'; } | $CC -E - | $GREP yes > /dev/null; then : else can_build_shared=no fi ;; esac # Using Import Files as archive members, it is possible to support # filename-based versioning of shared library archives on AIX. While # this would work for both with and without runtime linking, it will # prevent static linking of such archives. So we do filename-based # shared library versioning with .so extension only, which is used # when both runtime linking and shared linking is enabled. # Unfortunately, runtime linking may impact performance, so we do # not want this to be the default eventually. Also, we use the # versioned .so libs for executables only if there is the -brtl # linker flag in LDFLAGS as well, or --with-aix-soname=svr4 only. # To allow for filename-based versioning support, we need to create # libNAME.so.V as an archive file, containing: # *) an Import File, referring to the versioned filename of the # archive as well as the shared archive member, telling the # bitwidth (32 or 64) of that shared object, and providing the # list of exported symbols of that shared object, eventually # decorated with the 'weak' keyword # *) the shared object with the F_LOADONLY flag set, to really avoid # it being seen by the linker. # At run time we better use the real file rather than another symlink, # but for link time we create the symlink libNAME.so -> libNAME.so.V case $with_aix_soname,$aix_use_runtimelinking in # AIX (on Power*) has no versioning support, so currently we cannot hardcode correct # soname into executable. Probably we can add versioning support to # collect2, so additional links can be useful in future. aix,yes) # traditional libtool dynamic_linker='AIX unversionable lib.so' # If using run time linking (on AIX 4.2 or later) use lib.so # instead of lib.a to let people know that these are not # typical AIX shared libraries. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' ;; aix,no) # traditional AIX only dynamic_linker='AIX lib.a[(]lib.so.V[)]' # We preserve .a as extension for shared libraries through AIX4.2 # and later when we are not doing run time linking. library_names_spec='$libname$release.a $libname.a' soname_spec='$libname$release$shared_ext$major' ;; svr4,*) # full svr4 only dynamic_linker="AIX lib.so.V[(]$shared_archive_member_spec.o[)]" library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' # We do not specify a path in Import Files, so LIBPATH fires. shlibpath_overrides_runpath=yes ;; *,yes) # both, prefer svr4 dynamic_linker="AIX lib.so.V[(]$shared_archive_member_spec.o[)], lib.a[(]lib.so.V[)]" library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' # unpreferred sharedlib libNAME.a needs extra handling postinstall_cmds='test -n "$linkname" || linkname="$realname"~func_stripname "" ".so" "$linkname"~$install_shared_prog "$dir/$func_stripname_result.$libext" "$destdir/$func_stripname_result.$libext"~test -z "$tstripme" || test -z "$striplib" || $striplib "$destdir/$func_stripname_result.$libext"' postuninstall_cmds='for n in $library_names $old_library; do :; done~func_stripname "" ".so" "$n"~test "$func_stripname_result" = "$n" || func_append rmfiles " $odir/$func_stripname_result.$libext"' # We do not specify a path in Import Files, so LIBPATH fires. shlibpath_overrides_runpath=yes ;; *,no) # both, prefer aix dynamic_linker="AIX lib.a[(]lib.so.V[)], lib.so.V[(]$shared_archive_member_spec.o[)]" library_names_spec='$libname$release.a $libname.a' soname_spec='$libname$release$shared_ext$major' # unpreferred sharedlib libNAME.so.V and symlink libNAME.so need extra handling postinstall_cmds='test -z "$dlname" || $install_shared_prog $dir/$dlname $destdir/$dlname~test -z "$tstripme" || test -z "$striplib" || $striplib $destdir/$dlname~test -n "$linkname" || linkname=$realname~func_stripname "" ".a" "$linkname"~(cd "$destdir" && $LN_S -f $dlname $func_stripname_result.so)' postuninstall_cmds='test -z "$dlname" || func_append rmfiles " $odir/$dlname"~for n in $old_library $library_names; do :; done~func_stripname "" ".a" "$n"~func_append rmfiles " $odir/$func_stripname_result.so"' ;; esac shlibpath_var=LIBPATH fi ;; amigaos*) case $host_cpu in powerpc) # Since July 2007 AmigaOS4 officially supports .so libraries. # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' ;; m68k) library_names_spec='$libname.ixlibrary $libname.a' # Create ${libname}_ixlibrary.a entries in /sys/libs. finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' ;; esac ;; beos*) library_names_spec='$libname$shared_ext' dynamic_linker="$host_os ld.so" shlibpath_var=LIBRARY_PATH ;; bsdi[[45]]*) version_type=linux # correct to gnu/linux during the next big refactor need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" # the default ld.so.conf also contains /usr/contrib/lib and # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow # libtool to hard-code these into programs ;; cygwin* | mingw* | pw32* | cegcc*) version_type=windows shrext_cmds=.dll need_version=no need_lib_prefix=no case $GCC,$cc_basename in yes,*) # gcc library_names_spec='$libname.dll.a' # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \$file`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ chmod a+x \$dldir/$dlname~ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; fi' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes case $host_os in cygwin*) # Cygwin DLLs use 'cyg' prefix rather than 'lib' soname_spec='`echo $libname | $SED -e 's/^lib/cyg/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' m4_if([$1], [],[ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"]) ;; mingw* | cegcc*) # MinGW DLLs use traditional 'lib' prefix soname_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' ;; pw32*) # pw32 DLLs use 'pw' prefix rather than 'lib' library_names_spec='`echo $libname | $SED -e 's/^lib/pw/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' ;; esac dynamic_linker='Win32 ld.exe' ;; *,cl* | *,icl*) # Native MSVC or ICC libname_spec='$name' soname_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' library_names_spec='$libname.dll.lib' case $build_os in mingw*) sys_lib_search_path_spec= lt_save_ifs=$IFS IFS=';' for lt_path in $LIB do IFS=$lt_save_ifs # Let DOS variable expansion print the short 8.3 style file name. lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" done IFS=$lt_save_ifs # Convert to MSYS style. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's|\\\\|/|g' -e 's| \\([[a-zA-Z]]\\):| /\\1|g' -e 's|^ ||'` ;; cygwin*) # Convert to unix form, then to dos form, then back to unix form # but this time dos style (no spaces!) so that the unix form looks # like /cygdrive/c/PROGRA~1:/cygdr... sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` ;; *) sys_lib_search_path_spec=$LIB if $ECHO "$sys_lib_search_path_spec" | [$GREP ';[c-zC-Z]:/' >/dev/null]; then # It is most probably a Windows format PATH. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` else sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` fi # FIXME: find the short name or the path components, as spaces are # common. (e.g. "Program Files" -> "PROGRA~1") ;; esac # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \$file`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes dynamic_linker='Win32 link.exe' ;; *) # Assume MSVC and ICC wrapper library_names_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext $libname.lib' dynamic_linker='Win32 ld.exe' ;; esac # FIXME: first we should search . and the directory the executable is in shlibpath_var=PATH ;; darwin* | rhapsody*) dynamic_linker="$host_os dyld" version_type=darwin need_lib_prefix=no need_version=no library_names_spec='$libname$release$major$shared_ext $libname$shared_ext' soname_spec='$libname$release$major$shared_ext' shlibpath_overrides_runpath=yes shlibpath_var=DYLD_LIBRARY_PATH shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' m4_if([$1], [],[ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"]) sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' ;; dgux*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH ;; freebsd* | dragonfly* | midnightbsd*) # DragonFly does not have aout. When/if they implement a new # versioning mechanism, adjust this. if test -x /usr/bin/objformat; then objformat=`/usr/bin/objformat` else case $host_os in freebsd[[23]].*) objformat=aout ;; *) objformat=elf ;; esac fi version_type=freebsd-$objformat case $version_type in freebsd-elf*) library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' need_version=no need_lib_prefix=no ;; freebsd-*) library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' need_version=yes ;; esac shlibpath_var=LD_LIBRARY_PATH case $host_os in freebsd2.*) shlibpath_overrides_runpath=yes ;; freebsd3.[[01]]* | freebsdelf3.[[01]]*) shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; freebsd3.[[2-9]]* | freebsdelf3.[[2-9]]* | \ freebsd4.[[0-5]] | freebsdelf4.[[0-5]] | freebsd4.1.1 | freebsdelf4.1.1) shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; *) # from 4.6 on, and DragonFly shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; esac ;; haiku*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no dynamic_linker="$host_os runtime_loader" library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LIBRARY_PATH shlibpath_overrides_runpath=no sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' hardcode_into_libs=yes ;; hpux9* | hpux10* | hpux11*) # Give a soname corresponding to the major version so that dld.sl refuses to # link against other versions. version_type=sunos need_lib_prefix=no need_version=no case $host_cpu in ia64*) shrext_cmds='.so' hardcode_into_libs=yes dynamic_linker="$host_os dld.so" shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' if test 32 = "$HPUX_IA64_MODE"; then sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" sys_lib_dlsearch_path_spec=/usr/lib/hpux32 else sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" sys_lib_dlsearch_path_spec=/usr/lib/hpux64 fi ;; hppa*64*) shrext_cmds='.sl' hardcode_into_libs=yes dynamic_linker="$host_os dld.sl" shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; *) shrext_cmds='.sl' dynamic_linker="$host_os dld.sl" shlibpath_var=SHLIB_PATH shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' ;; esac # HP-UX runs *really* slowly unless shared libraries are mode 555, ... postinstall_cmds='chmod 555 $lib' # or fails outright, so override atomically: install_override_mode=555 ;; interix[[3-9]]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; irix5* | irix6* | nonstopux*) case $host_os in nonstopux*) version_type=nonstopux ;; *) if test yes = "$lt_cv_prog_gnu_ld"; then version_type=linux # correct to gnu/linux during the next big refactor else version_type=irix fi ;; esac need_lib_prefix=no need_version=no soname_spec='$libname$release$shared_ext$major' library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$release$shared_ext $libname$shared_ext' case $host_os in irix5* | nonstopux*) libsuff= shlibsuff= ;; *) case $LD in # libtool.m4 will add one of these switches to LD *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= libmagic=32-bit;; *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 libmagic=N32;; *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 libmagic=64-bit;; *) libsuff= shlibsuff= libmagic=never-match;; esac ;; esac shlibpath_var=LD_LIBRARY${shlibsuff}_PATH shlibpath_overrides_runpath=no sys_lib_search_path_spec="/usr/lib$libsuff /lib$libsuff /usr/local/lib$libsuff" sys_lib_dlsearch_path_spec="/usr/lib$libsuff /lib$libsuff" hardcode_into_libs=yes ;; # No shared lib support for Linux oldld, aout, or coff. linux*oldld* | linux*aout* | linux*coff*) dynamic_linker=no ;; linux*android*) version_type=none # Android doesn't support versioned libraries. need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext' soname_spec='$libname$release$shared_ext' finish_cmds= shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # This implies no fast_install, which is unacceptable. # Some rework will be needed to allow for fast_install # before this can be enabled. hardcode_into_libs=yes dynamic_linker='Android linker' # Don't embed -rpath directories since the linker doesn't support them. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' ;; # This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no # Some binutils ld are patched to set DT_RUNPATH AC_CACHE_VAL([lt_cv_shlibpath_overrides_runpath], [lt_cv_shlibpath_overrides_runpath=no save_LDFLAGS=$LDFLAGS save_libdir=$libdir eval "libdir=/foo; wl=\"$_LT_TAGVAR(lt_prog_compiler_wl, $1)\"; \ LDFLAGS=\"\$LDFLAGS $_LT_TAGVAR(hardcode_libdir_flag_spec, $1)\"" AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], [AS_IF([ ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null], [lt_cv_shlibpath_overrides_runpath=yes])]) LDFLAGS=$save_LDFLAGS libdir=$save_libdir ]) shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath # This implies no fast_install, which is unacceptable. # Some rework will be needed to allow for fast_install # before this can be enabled. hardcode_into_libs=yes # Add ABI-specific directories to the system library path. sys_lib_dlsearch_path_spec="/lib64 /usr/lib64 /lib /usr/lib" # Ideally, we could use ldconfig to report *all* directores which are # searched for libraries, however this is still not possible. Aside from not # being certain /sbin/ldconfig is available, command # 'ldconfig -N -X -v | grep ^/' on 64bit Fedora does not report /usr/lib64, # even though it is searched at run-time. Try to do the best guess by # appending ld.so.conf contents (and includes) to the search path. if test -f /etc/ld.so.conf; then lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` sys_lib_dlsearch_path_spec="$sys_lib_dlsearch_path_spec $lt_ld_extra" fi # We used to test for /lib/ld.so.1 and disable shared libraries on # powerpc, because MkLinux only supported shared libraries with the # GNU dynamic linker. Since this was broken with cross compilers, # most powerpc-linux boxes support dynamic linking these days and # 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' ;; netbsd*) version_type=sunos need_lib_prefix=no need_version=no if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' dynamic_linker='NetBSD (a.out) ld.so' else library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' dynamic_linker='NetBSD ld.elf_so' fi shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; newsos6) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; *nto* | *qnx*) version_type=qnx need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='ldqnx.so' ;; openbsd* | bitrig*) version_type=sunos sys_lib_dlsearch_path_spec=/usr/lib need_lib_prefix=no if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then need_version=no else need_version=yes fi library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; os2*) libname_spec='$name' version_type=windows shrext_cmds=.dll need_version=no need_lib_prefix=no # OS/2 can only load a DLL with a base name of 8 characters or less. soname_spec='`test -n "$os2dllname" && libname="$os2dllname"; v=$($ECHO $release$versuffix | tr -d .-); n=$($ECHO $libname | cut -b -$((8 - ${#v})) | tr . _); $ECHO $n$v`$shared_ext' library_names_spec='${libname}_dll.$libext' dynamic_linker='OS/2 ld.exe' shlibpath_var=BEGINLIBPATH sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec postinstall_cmds='base_file=`basename \$file`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; $ECHO \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ chmod a+x \$dldir/$dlname~ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; fi' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; $ECHO \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' ;; osf3* | osf4* | osf5*) version_type=osf need_lib_prefix=no need_version=no soname_spec='$libname$release$shared_ext$major' library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' 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 ;; rdos*) dynamic_linker=no ;; solaris*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes # ldd complains unless libraries are executable postinstall_cmds='chmod +x $lib' ;; sunos4*) version_type=sunos library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes if test yes = "$with_gnu_ld"; then need_lib_prefix=no fi need_version=yes ;; sysv4 | sysv4.3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH case $host_vendor in sni) shlibpath_overrides_runpath=no need_lib_prefix=no runpath_var=LD_RUN_PATH ;; siemens) need_lib_prefix=no ;; motorola) need_lib_prefix=no need_version=no shlibpath_overrides_runpath=no sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' ;; esac ;; sysv4*MP*) if test -d /usr/nec; then version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$shared_ext.$versuffix $libname$shared_ext.$major $libname$shared_ext' soname_spec='$libname$shared_ext.$major' shlibpath_var=LD_LIBRARY_PATH fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) version_type=sco need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes if test yes = "$with_gnu_ld"; then sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' else sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' case $host_os in sco3.2v5*) sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" ;; esac fi sys_lib_dlsearch_path_spec='/usr/lib' ;; tpf*) # TPF is a cross-target only. Preferred cross-host = GNU/Linux. version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; uts4*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH ;; *) dynamic_linker=no ;; esac AC_MSG_RESULT([$dynamic_linker]) test no = "$dynamic_linker" && can_build_shared=no variables_saved_for_relink="PATH $shlibpath_var $runpath_var" if test yes = "$GCC"; then variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" fi if test set = "${lt_cv_sys_lib_search_path_spec+set}"; then sys_lib_search_path_spec=$lt_cv_sys_lib_search_path_spec fi if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec fi # remember unaugmented sys_lib_dlsearch_path content for libtool script decls... configure_time_dlsearch_path=$sys_lib_dlsearch_path_spec # ... but it needs LT_SYS_LIBRARY_PATH munging for other configure-time code func_munge_path_list sys_lib_dlsearch_path_spec "$LT_SYS_LIBRARY_PATH" # to be used as default LT_SYS_LIBRARY_PATH value in generated libtool configure_time_lt_sys_library_path=$LT_SYS_LIBRARY_PATH _LT_DECL([], [variables_saved_for_relink], [1], [Variables whose values should be saved in libtool wrapper scripts and restored at link time]) _LT_DECL([], [need_lib_prefix], [0], [Do we need the "lib" prefix for modules?]) _LT_DECL([], [need_version], [0], [Do we need a version for libraries?]) _LT_DECL([], [version_type], [0], [Library versioning type]) _LT_DECL([], [runpath_var], [0], [Shared library runtime path variable]) _LT_DECL([], [shlibpath_var], [0],[Shared library path variable]) _LT_DECL([], [shlibpath_overrides_runpath], [0], [Is shlibpath searched before the hard-coded library search path?]) _LT_DECL([], [libname_spec], [1], [Format of library name prefix]) _LT_DECL([], [library_names_spec], [1], [[List of archive names. First name is the real one, the rest are links. The last name is the one that the linker finds with -lNAME]]) _LT_DECL([], [soname_spec], [1], [[The coded name of the library, if different from the real name]]) _LT_DECL([], [install_override_mode], [1], [Permission mode override for installation of shared libraries]) _LT_DECL([], [postinstall_cmds], [2], [Command to use after installation of a shared archive]) _LT_DECL([], [postuninstall_cmds], [2], [Command to use after uninstallation of a shared archive]) _LT_DECL([], [finish_cmds], [2], [Commands used to finish a libtool library installation in a directory]) _LT_DECL([], [finish_eval], [1], [[As "finish_cmds", except a single script fragment to be evaled but not shown]]) _LT_DECL([], [hardcode_into_libs], [0], [Whether we should hardcode library paths into libraries]) _LT_DECL([], [sys_lib_search_path_spec], [2], [Compile-time system search path for libraries]) _LT_DECL([sys_lib_dlsearch_path_spec], [configure_time_dlsearch_path], [2], [Detected run-time system search path for libraries]) _LT_DECL([], [configure_time_lt_sys_library_path], [2], [Explicit LT_SYS_LIBRARY_PATH set during ./configure time]) ])# _LT_SYS_DYNAMIC_LINKER # _LT_PATH_TOOL_PREFIX(TOOL) # -------------------------- # find a file program that can recognize shared library AC_DEFUN([_LT_PATH_TOOL_PREFIX], [m4_require([_LT_DECL_EGREP])dnl AC_MSG_CHECKING([for $1]) AC_CACHE_VAL(lt_cv_path_MAGIC_CMD, [case $MAGIC_CMD in [[\\/*] | ?:[\\/]*]) lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path. ;; *) lt_save_MAGIC_CMD=$MAGIC_CMD lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR dnl $ac_dummy forces splitting on constant user-supplied paths. dnl POSIX.2 word splitting is done only on the output of word expansions, dnl not every word. This closes a longstanding sh security hole. ac_dummy="m4_if([$2], , $PATH, [$2])" for ac_dir in $ac_dummy; do IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/$1"; then lt_cv_path_MAGIC_CMD=$ac_dir/"$1" if test -n "$file_magic_test_file"; then case $deplibs_check_method in "file_magic "*) file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` MAGIC_CMD=$lt_cv_path_MAGIC_CMD if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | $EGREP "$file_magic_regex" > /dev/null; then : else cat <<_LT_EOF 1>&2 *** Warning: the command libtool uses to detect shared libraries, *** $file_magic_cmd, produces output that libtool cannot recognize. *** The result is that libtool may fail to recognize shared libraries *** as such. This will affect the creation of libtool libraries that *** depend on shared libraries, but programs linked with such libtool *** libraries will work regardless of this problem. Nevertheless, you *** may want to report the problem to your system manager and/or to *** bug-libtool@gnu.org _LT_EOF fi ;; esac fi break fi done IFS=$lt_save_ifs MAGIC_CMD=$lt_save_MAGIC_CMD ;; esac]) MAGIC_CMD=$lt_cv_path_MAGIC_CMD if test -n "$MAGIC_CMD"; then AC_MSG_RESULT($MAGIC_CMD) else AC_MSG_RESULT(no) fi _LT_DECL([], [MAGIC_CMD], [0], [Used to examine libraries when file_magic_cmd begins with "file"])dnl ])# _LT_PATH_TOOL_PREFIX # Old name: AU_ALIAS([AC_PATH_TOOL_PREFIX], [_LT_PATH_TOOL_PREFIX]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_PATH_TOOL_PREFIX], []) # _LT_PATH_MAGIC # -------------- # find a file program that can recognize a shared library m4_defun([_LT_PATH_MAGIC], [_LT_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH) if test -z "$lt_cv_path_MAGIC_CMD"; then if test -n "$ac_tool_prefix"; then _LT_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH) else MAGIC_CMD=: fi fi ])# _LT_PATH_MAGIC # LT_PATH_LD # ---------- # find the pathname to the GNU or non-GNU linker AC_DEFUN([LT_PATH_LD], [AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_CANONICAL_BUILD])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_PROG_ECHO_BACKSLASH])dnl AC_ARG_WITH([gnu-ld], [AS_HELP_STRING([--with-gnu-ld], [assume the C compiler uses GNU ld @<:@default=no@:>@])], [test no = "$withval" || with_gnu_ld=yes], [with_gnu_ld=no])dnl ac_prog=ld if test yes = "$GCC"; then # Check if gcc -print-prog-name=ld gives a path. AC_MSG_CHECKING([for ld used by $CC]) case $host in *-*-mingw*) # gcc leaves a trailing carriage return, which upsets mingw ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; *) ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; esac case $ac_prog in # Accept absolute paths. [[\\/]]* | ?:[[\\/]]*) re_direlt='/[[^/]][[^/]]*/\.\./' # Canonicalize the pathname of ld ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` done test -z "$LD" && LD=$ac_prog ;; "") # If it fails, then pretend we aren't using GCC. ac_prog=ld ;; *) # If it is relative, then search for the first ld in PATH. with_gnu_ld=unknown ;; esac elif test yes = "$with_gnu_ld"; then AC_MSG_CHECKING([for GNU ld]) else AC_MSG_CHECKING([for non-GNU ld]) fi AC_CACHE_VAL(lt_cv_path_LD, [if test -z "$LD"; then lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR for ac_dir in $PATH; do IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then lt_cv_path_LD=$ac_dir/$ac_prog # Check to see if the program is GNU ld. I'd rather use --version, # but apparently some variants of GNU ld only accept -v. # Break only if it was the GNU/non-GNU ld that we prefer. case `"$lt_cv_path_LD" -v 2>&1 &1 conftest.i cat conftest.i conftest.i >conftest2.i : ${lt_DD:=$DD} AC_PATH_PROGS_FEATURE_CHECK([lt_DD], [dd], [if "$ac_path_lt_DD" bs=32 count=1 conftest.out 2>/dev/null; then cmp -s conftest.i conftest.out \ && ac_cv_path_lt_DD="$ac_path_lt_DD" ac_path_lt_DD_found=: fi]) rm -f conftest.i conftest2.i conftest.out]) ])# _LT_PATH_DD # _LT_CMD_TRUNCATE # ---------------- # find command to truncate a binary pipe m4_defun([_LT_CMD_TRUNCATE], [m4_require([_LT_PATH_DD]) AC_CACHE_CHECK([how to truncate binary pipes], [lt_cv_truncate_bin], [printf 0123456789abcdef0123456789abcdef >conftest.i cat conftest.i conftest.i >conftest2.i lt_cv_truncate_bin= if "$ac_cv_path_lt_DD" bs=32 count=1 conftest.out 2>/dev/null; then cmp -s conftest.i conftest.out \ && lt_cv_truncate_bin="$ac_cv_path_lt_DD bs=4096 count=1" fi rm -f conftest.i conftest2.i conftest.out test -z "$lt_cv_truncate_bin" && lt_cv_truncate_bin="$SED -e 4q"]) _LT_DECL([lt_truncate_bin], [lt_cv_truncate_bin], [1], [Command to truncate a binary pipe]) ])# _LT_CMD_TRUNCATE # _LT_CHECK_MAGIC_METHOD # ---------------------- # how to check for library dependencies # -- PORTME fill in with the dynamic library characteristics m4_defun([_LT_CHECK_MAGIC_METHOD], [m4_require([_LT_DECL_EGREP]) m4_require([_LT_DECL_OBJDUMP]) AC_CACHE_CHECK([how to recognize dependent libraries], lt_cv_deplibs_check_method, [lt_cv_file_magic_cmd='$MAGIC_CMD' lt_cv_file_magic_test_file= lt_cv_deplibs_check_method='unknown' # Need to set the preceding variable on all platforms that support # interlibrary dependencies. # 'none' -- dependencies not supported. # 'unknown' -- same as none, but documents that we really don't know. # 'pass_all' -- all dependencies passed with no checks. # 'test_compile' -- check by making test program. # 'file_magic [[regex]]' -- check by looking for files in library path # that responds to the $file_magic_cmd with a given extended regex. # If you have 'file' or equivalent on your system and you're not sure # whether 'pass_all' will *always* work, you probably want this one. case $host_os in aix[[4-9]]*) lt_cv_deplibs_check_method=pass_all ;; beos*) lt_cv_deplibs_check_method=pass_all ;; bsdi[[45]]*) lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib)' lt_cv_file_magic_cmd='$FILECMD -L' lt_cv_file_magic_test_file=/shlib/libc.so ;; cygwin*) # func_win32_libid is a shell function defined in ltmain.sh lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' lt_cv_file_magic_cmd='func_win32_libid' ;; mingw* | pw32*) # Base MSYS/MinGW do not provide the 'file' command needed by # func_win32_libid shell function, so use a weaker test based on 'objdump', # unless we find 'file', for example because we are cross-compiling. if ( file / ) >/dev/null 2>&1; then lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' lt_cv_file_magic_cmd='func_win32_libid' else # Keep this pattern in sync with the one in func_win32_libid. lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' lt_cv_file_magic_cmd='$OBJDUMP -f' fi ;; cegcc*) # use the weaker test based on 'objdump'. See mingw*. lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' lt_cv_file_magic_cmd='$OBJDUMP -f' ;; darwin* | rhapsody*) lt_cv_deplibs_check_method=pass_all ;; freebsd* | dragonfly* | midnightbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then case $host_cpu in i*86 ) # Not sure whether the presence of OpenBSD here was a mistake. # Let's accept both of them until this is cleared up. lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library' lt_cv_file_magic_cmd=$FILECMD lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` ;; esac else lt_cv_deplibs_check_method=pass_all fi ;; haiku*) lt_cv_deplibs_check_method=pass_all ;; hpux10.20* | hpux11*) lt_cv_file_magic_cmd=$FILECMD case $host_cpu in ia64*) lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64' lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so ;; hppa*64*) [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]'] lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl ;; *) lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]]\.[[0-9]]) shared library' lt_cv_file_magic_test_file=/usr/lib/libc.sl ;; esac ;; interix[[3-9]]*) # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|\.a)$' ;; irix5* | irix6* | nonstopux*) case $LD in *-32|*"-32 ") libmagic=32-bit;; *-n32|*"-n32 ") libmagic=N32;; *-64|*"-64 ") libmagic=64-bit;; *) libmagic=never-match;; esac lt_cv_deplibs_check_method=pass_all ;; # This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) lt_cv_deplibs_check_method=pass_all ;; netbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|_pic\.a)$' fi ;; newos6*) lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)' lt_cv_file_magic_cmd=$FILECMD lt_cv_file_magic_test_file=/usr/lib/libnls.so ;; *nto* | *qnx*) lt_cv_deplibs_check_method=pass_all ;; openbsd* | bitrig*) if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' fi ;; osf3* | osf4* | osf5*) lt_cv_deplibs_check_method=pass_all ;; rdos*) lt_cv_deplibs_check_method=pass_all ;; solaris*) lt_cv_deplibs_check_method=pass_all ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) lt_cv_deplibs_check_method=pass_all ;; sysv4 | sysv4.3*) case $host_vendor in motorola) lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]' lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` ;; ncr) lt_cv_deplibs_check_method=pass_all ;; sequent) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )' ;; sni) lt_cv_file_magic_cmd='/bin/file' 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 ;; pc) lt_cv_deplibs_check_method=pass_all ;; esac ;; tpf*) lt_cv_deplibs_check_method=pass_all ;; os2*) lt_cv_deplibs_check_method=pass_all ;; esac ]) file_magic_glob= want_nocaseglob=no if test "$build" = "$host"; then case $host_os in mingw* | pw32*) if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then want_nocaseglob=yes else file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[[\1]]\/[[\1]]\/g;/g"` fi ;; esac fi file_magic_cmd=$lt_cv_file_magic_cmd deplibs_check_method=$lt_cv_deplibs_check_method test -z "$deplibs_check_method" && deplibs_check_method=unknown _LT_DECL([], [deplibs_check_method], [1], [Method to check whether dependent libraries are shared objects]) _LT_DECL([], [file_magic_cmd], [1], [Command to use when deplibs_check_method = "file_magic"]) _LT_DECL([], [file_magic_glob], [1], [How to find potential files when deplibs_check_method = "file_magic"]) _LT_DECL([], [want_nocaseglob], [1], [Find potential files using nocaseglob when deplibs_check_method = "file_magic"]) ])# _LT_CHECK_MAGIC_METHOD # LT_PATH_NM # ---------- # find the pathname to a BSD- or MS-compatible name lister AC_DEFUN([LT_PATH_NM], [AC_REQUIRE([AC_PROG_CC])dnl AC_CACHE_CHECK([for BSD- or MS-compatible name lister (nm)], lt_cv_path_NM, [if test -n "$NM"; then # Let the user override the test. lt_cv_path_NM=$NM else lt_nm_to_check=${ac_tool_prefix}nm if test -n "$ac_tool_prefix" && test "$build" = "$host"; then lt_nm_to_check="$lt_nm_to_check nm" fi for lt_tmp_nm in $lt_nm_to_check; do lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. tmp_nm=$ac_dir/$lt_tmp_nm if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext"; then # Check to see if the nm accepts a BSD-compat flag. # Adding the 'sed 1q' prevents false positives on HP-UX, which says: # nm: unknown option "B" ignored # Tru64's nm complains that /dev/null is an invalid object file # MSYS converts /dev/null to NUL, MinGW nm treats NUL as empty case $build_os in mingw*) lt_bad_file=conftest.nm/nofile ;; *) lt_bad_file=/dev/null ;; esac case `"$tmp_nm" -B $lt_bad_file 2>&1 | $SED '1q'` in *$lt_bad_file* | *'Invalid file or object type'*) lt_cv_path_NM="$tmp_nm -B" break 2 ;; *) case `"$tmp_nm" -p /dev/null 2>&1 | $SED '1q'` in */dev/null*) lt_cv_path_NM="$tmp_nm -p" break 2 ;; *) lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but continue # so that we can try to find one that supports BSD flags ;; esac ;; esac fi done IFS=$lt_save_ifs done : ${lt_cv_path_NM=no} fi]) if test no != "$lt_cv_path_NM"; then NM=$lt_cv_path_NM else # Didn't find any BSD compatible name lister, look for dumpbin. if test -n "$DUMPBIN"; then : # Let the user override the test. else AC_CHECK_TOOLS(DUMPBIN, [dumpbin "link -dump"], :) case `$DUMPBIN -symbols -headers /dev/null 2>&1 | $SED '1q'` in *COFF*) DUMPBIN="$DUMPBIN -symbols -headers" ;; *) DUMPBIN=: ;; esac fi AC_SUBST([DUMPBIN]) if test : != "$DUMPBIN"; then NM=$DUMPBIN fi fi test -z "$NM" && NM=nm AC_SUBST([NM]) _LT_DECL([], [NM], [1], [A BSD- or MS-compatible name lister])dnl AC_CACHE_CHECK([the name lister ($NM) interface], [lt_cv_nm_interface], [lt_cv_nm_interface="BSD nm" echo "int some_variable = 0;" > conftest.$ac_ext (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&AS_MESSAGE_LOG_FD) (eval "$ac_compile" 2>conftest.err) cat conftest.err >&AS_MESSAGE_LOG_FD (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&AS_MESSAGE_LOG_FD) (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) cat conftest.err >&AS_MESSAGE_LOG_FD (eval echo "\"\$as_me:$LINENO: output\"" >&AS_MESSAGE_LOG_FD) cat conftest.out >&AS_MESSAGE_LOG_FD if $GREP 'External.*some_variable' conftest.out > /dev/null; then lt_cv_nm_interface="MS dumpbin" fi rm -f conftest*]) ])# LT_PATH_NM # Old names: AU_ALIAS([AM_PROG_NM], [LT_PATH_NM]) AU_ALIAS([AC_PROG_NM], [LT_PATH_NM]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AM_PROG_NM], []) dnl AC_DEFUN([AC_PROG_NM], []) # _LT_CHECK_SHAREDLIB_FROM_LINKLIB # -------------------------------- # how to determine the name of the shared library # associated with a specific link library. # -- PORTME fill in with the dynamic library characteristics m4_defun([_LT_CHECK_SHAREDLIB_FROM_LINKLIB], [m4_require([_LT_DECL_EGREP]) m4_require([_LT_DECL_OBJDUMP]) m4_require([_LT_DECL_DLLTOOL]) AC_CACHE_CHECK([how to associate runtime and link libraries], lt_cv_sharedlib_from_linklib_cmd, [lt_cv_sharedlib_from_linklib_cmd='unknown' case $host_os in cygwin* | mingw* | pw32* | cegcc*) # two different shell functions defined in ltmain.sh; # decide which one to use based on capabilities of $DLLTOOL case `$DLLTOOL --help 2>&1` in *--identify-strict*) lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib ;; *) lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback ;; esac ;; *) # fallback: assume linklib IS sharedlib lt_cv_sharedlib_from_linklib_cmd=$ECHO ;; esac ]) sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO _LT_DECL([], [sharedlib_from_linklib_cmd], [1], [Command to associate shared and link libraries]) ])# _LT_CHECK_SHAREDLIB_FROM_LINKLIB # _LT_PATH_MANIFEST_TOOL # ---------------------- # locate the manifest tool m4_defun([_LT_PATH_MANIFEST_TOOL], [AC_CHECK_TOOL(MANIFEST_TOOL, mt, :) test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt AC_CACHE_CHECK([if $MANIFEST_TOOL is a manifest tool], [lt_cv_path_mainfest_tool], [lt_cv_path_mainfest_tool=no echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&AS_MESSAGE_LOG_FD $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out cat conftest.err >&AS_MESSAGE_LOG_FD if $GREP 'Manifest Tool' conftest.out > /dev/null; then lt_cv_path_mainfest_tool=yes fi rm -f conftest*]) if test yes != "$lt_cv_path_mainfest_tool"; then MANIFEST_TOOL=: fi _LT_DECL([], [MANIFEST_TOOL], [1], [Manifest tool])dnl ])# _LT_PATH_MANIFEST_TOOL # _LT_DLL_DEF_P([FILE]) # --------------------- # True iff FILE is a Windows DLL '.def' file. # Keep in sync with func_dll_def_p in the libtool script AC_DEFUN([_LT_DLL_DEF_P], [dnl test DEF = "`$SED -n dnl -e '\''s/^[[ ]]*//'\'' dnl Strip leading whitespace -e '\''/^\(;.*\)*$/d'\'' dnl Delete empty lines and comments -e '\''s/^\(EXPORTS\|LIBRARY\)\([[ ]].*\)*$/DEF/p'\'' dnl -e q dnl Only consider the first "real" line $1`" dnl ])# _LT_DLL_DEF_P # LT_LIB_M # -------- # check for math library AC_DEFUN([LT_LIB_M], [AC_REQUIRE([AC_CANONICAL_HOST])dnl LIBM= case $host in *-*-beos* | *-*-cegcc* | *-*-cygwin* | *-*-haiku* | *-*-pw32* | *-*-darwin*) # These system don't have libm, or don't need it ;; *-ncr-sysv4.3*) AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM=-lmw) AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm") ;; *) AC_CHECK_LIB(m, cos, LIBM=-lm) ;; esac AC_SUBST([LIBM]) ])# LT_LIB_M # Old name: AU_ALIAS([AC_CHECK_LIBM], [LT_LIB_M]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_CHECK_LIBM], []) # _LT_COMPILER_NO_RTTI([TAGNAME]) # ------------------------------- m4_defun([_LT_COMPILER_NO_RTTI], [m4_require([_LT_TAG_COMPILER])dnl _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= if test yes = "$GCC"; then case $cc_basename in nvcc*) _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -Xcompiler -fno-builtin' ;; *) _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' ;; esac _LT_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions], lt_cv_prog_compiler_rtti_exceptions, [-fno-rtti -fno-exceptions], [], [_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"]) fi _LT_TAGDECL([no_builtin_flag], [lt_prog_compiler_no_builtin_flag], [1], [Compiler flag to turn off builtin functions]) ])# _LT_COMPILER_NO_RTTI # _LT_CMD_GLOBAL_SYMBOLS # ---------------------- m4_defun([_LT_CMD_GLOBAL_SYMBOLS], [AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([AC_PROG_AWK])dnl AC_REQUIRE([LT_PATH_NM])dnl AC_REQUIRE([LT_PATH_LD])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_TAG_COMPILER])dnl # Check for command to grab the raw symbol name followed by C symbol from nm. AC_MSG_CHECKING([command to parse $NM output from $compiler object]) AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe], [ # These are sane defaults that work on at least a few old systems. # [They come from Ultrix. What could be older than Ultrix?!! ;)] # Character class describing NM global symbol codes. symcode='[[BCDEGRST]]' # Regexp to match symbols that can be accessed directly from C. sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)' # Define system-specific variables. case $host_os in aix*) symcode='[[BCDT]]' ;; cygwin* | mingw* | pw32* | cegcc*) symcode='[[ABCDGISTW]]' ;; hpux*) if test ia64 = "$host_cpu"; then symcode='[[ABCDEGRST]]' fi ;; irix* | nonstopux*) symcode='[[BCDEGRST]]' ;; osf*) symcode='[[BCDEGQRST]]' ;; solaris*) symcode='[[BDRT]]' ;; sco3.2v5*) symcode='[[DT]]' ;; sysv4.2uw2*) symcode='[[DT]]' ;; sysv5* | sco5v6* | unixware* | OpenUNIX*) symcode='[[ABDT]]' ;; sysv4) symcode='[[DFNSTU]]' ;; esac # If we're using GNU nm, then use its standard symbol codes. case `$NM -V 2>&1` in *GNU* | *'with BFD'*) symcode='[[ABCDGIRSTW]]' ;; esac if test "$lt_cv_nm_interface" = "MS dumpbin"; then # Gets list of data symbols to import. lt_cv_sys_global_symbol_to_import="$SED -n -e 's/^I .* \(.*\)$/\1/p'" # Adjust the below global symbol transforms to fixup imported variables. lt_cdecl_hook=" -e 's/^I .* \(.*\)$/extern __declspec(dllimport) char \1;/p'" lt_c_name_hook=" -e 's/^I .* \(.*\)$/ {\"\1\", (void *) 0},/p'" lt_c_name_lib_hook="\ -e 's/^I .* \(lib.*\)$/ {\"\1\", (void *) 0},/p'\ -e 's/^I .* \(.*\)$/ {\"lib\1\", (void *) 0},/p'" else # Disable hooks by default. lt_cv_sys_global_symbol_to_import= lt_cdecl_hook= lt_c_name_hook= lt_c_name_lib_hook= fi # Transform an extracted symbol line into a proper C declaration. # Some systems (esp. on ia64) link data and code symbols differently, # so use this general approach. lt_cv_sys_global_symbol_to_cdecl="$SED -n"\ $lt_cdecl_hook\ " -e 's/^T .* \(.*\)$/extern int \1();/p'"\ " -e 's/^$symcode$symcode* .* \(.*\)$/extern char \1;/p'" # Transform an extracted symbol line into symbol name and symbol address lt_cv_sys_global_symbol_to_c_name_address="$SED -n"\ $lt_c_name_hook\ " -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ " -e 's/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/p'" # Transform an extracted symbol line into symbol name with lib prefix and # symbol address. lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="$SED -n"\ $lt_c_name_lib_hook\ " -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ " -e 's/^$symcode$symcode* .* \(lib.*\)$/ {\"\1\", (void *) \&\1},/p'"\ " -e 's/^$symcode$symcode* .* \(.*\)$/ {\"lib\1\", (void *) \&\1},/p'" # Handle CRLF in mingw tool chain opt_cr= case $build_os in mingw*) opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp ;; esac # Try without a prefix underscore, then with it. for ac_symprfx in "" "_"; do # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. symxfrm="\\1 $ac_symprfx\\2 \\2" # Write the raw and C identifiers. if test "$lt_cv_nm_interface" = "MS dumpbin"; then # Fake it for dumpbin and say T for any non-static function, # D for any global variable and I for any imported variable. # Also find C++ and __fastcall symbols from MSVC++ or ICC, # which start with @ or ?. lt_cv_sys_global_symbol_pipe="$AWK ['"\ " {last_section=section; section=\$ 3};"\ " /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\ " /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ " /^ *Symbol name *: /{split(\$ 0,sn,\":\"); si=substr(sn[2],2)};"\ " /^ *Type *: code/{print \"T\",si,substr(si,length(prfx))};"\ " /^ *Type *: data/{print \"I\",si,substr(si,length(prfx))};"\ " \$ 0!~/External *\|/{next};"\ " / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ " {if(hide[section]) next};"\ " {f=\"D\"}; \$ 0~/\(\).*\|/{f=\"T\"};"\ " {split(\$ 0,a,/\||\r/); split(a[2],s)};"\ " s[1]~/^[@?]/{print f,s[1],s[1]; next};"\ " s[1]~prfx {split(s[1],t,\"@\"); print f,t[1],substr(t[1],length(prfx))}"\ " ' prfx=^$ac_symprfx]" else lt_cv_sys_global_symbol_pipe="$SED -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" fi lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | $SED '/ __gnu_lto/d'" # Check to see that the pipe works correctly. pipe_works=no rm -f conftest* cat > conftest.$ac_ext <<_LT_EOF #ifdef __cplusplus extern "C" { #endif char nm_test_var; void nm_test_func(void); void nm_test_func(void){} #ifdef __cplusplus } #endif int main(){nm_test_var='a';nm_test_func();return(0);} _LT_EOF if AC_TRY_EVAL(ac_compile); then # Now try to grab the symbols. nlist=conftest.nm if AC_TRY_EVAL(NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) && test -s "$nlist"; then # Try sorting and uniquifying the output. if sort "$nlist" | uniq > "$nlist"T; then mv -f "$nlist"T "$nlist" else rm -f "$nlist"T fi # Make sure that we snagged all the symbols we need. if $GREP ' nm_test_var$' "$nlist" >/dev/null; then if $GREP ' nm_test_func$' "$nlist" >/dev/null; then cat <<_LT_EOF > conftest.$ac_ext /* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ #if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE /* DATA imports from DLLs on WIN32 can't be const, because runtime relocations are performed -- see ld's documentation on pseudo-relocs. */ # define LT@&t@_DLSYM_CONST #elif defined __osf__ /* This system does not cope well with relocations in const data. */ # define LT@&t@_DLSYM_CONST #else # define LT@&t@_DLSYM_CONST const #endif #ifdef __cplusplus extern "C" { #endif _LT_EOF # Now generate the symbol file. eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' cat <<_LT_EOF >> conftest.$ac_ext /* The mapping between symbol names and symbols. */ LT@&t@_DLSYM_CONST struct { const char *name; void *address; } lt__PROGRAM__LTX_preloaded_symbols[[]] = { { "@PROGRAM@", (void *) 0 }, _LT_EOF $SED "s/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext cat <<\_LT_EOF >> conftest.$ac_ext {0, (void *) 0} }; /* This works around a problem in FreeBSD linker */ #ifdef FREEBSD_WORKAROUND static const void *lt_preloaded_setup() { return lt__PROGRAM__LTX_preloaded_symbols; } #endif #ifdef __cplusplus } #endif _LT_EOF # Now try linking the two files. mv conftest.$ac_objext conftstm.$ac_objext lt_globsym_save_LIBS=$LIBS lt_globsym_save_CFLAGS=$CFLAGS LIBS=conftstm.$ac_objext CFLAGS="$CFLAGS$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)" if AC_TRY_EVAL(ac_link) && test -s conftest$ac_exeext; then pipe_works=yes fi LIBS=$lt_globsym_save_LIBS CFLAGS=$lt_globsym_save_CFLAGS else echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD fi else echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD fi else echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD fi else echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD cat conftest.$ac_ext >&5 fi rm -rf conftest* conftst* # Do not use the global_symbol_pipe unless it works. if test yes = "$pipe_works"; then break else lt_cv_sys_global_symbol_pipe= fi done ]) if test -z "$lt_cv_sys_global_symbol_pipe"; then lt_cv_sys_global_symbol_to_cdecl= fi if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then AC_MSG_RESULT(failed) else AC_MSG_RESULT(ok) fi # Response file support. if test "$lt_cv_nm_interface" = "MS dumpbin"; then nm_file_list_spec='@' elif $NM --help 2>/dev/null | grep '[[@]]FILE' >/dev/null; then nm_file_list_spec='@' fi _LT_DECL([global_symbol_pipe], [lt_cv_sys_global_symbol_pipe], [1], [Take the output of nm and produce a listing of raw symbols and C names]) _LT_DECL([global_symbol_to_cdecl], [lt_cv_sys_global_symbol_to_cdecl], [1], [Transform the output of nm in a proper C declaration]) _LT_DECL([global_symbol_to_import], [lt_cv_sys_global_symbol_to_import], [1], [Transform the output of nm into a list of symbols to manually relocate]) _LT_DECL([global_symbol_to_c_name_address], [lt_cv_sys_global_symbol_to_c_name_address], [1], [Transform the output of nm in a C name address pair]) _LT_DECL([global_symbol_to_c_name_address_lib_prefix], [lt_cv_sys_global_symbol_to_c_name_address_lib_prefix], [1], [Transform the output of nm in a C name address pair when lib prefix is needed]) _LT_DECL([nm_interface], [lt_cv_nm_interface], [1], [The name lister interface]) _LT_DECL([], [nm_file_list_spec], [1], [Specify filename containing input files for $NM]) ]) # _LT_CMD_GLOBAL_SYMBOLS # _LT_COMPILER_PIC([TAGNAME]) # --------------------------- m4_defun([_LT_COMPILER_PIC], [m4_require([_LT_TAG_COMPILER])dnl _LT_TAGVAR(lt_prog_compiler_wl, $1)= _LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_static, $1)= m4_if([$1], [CXX], [ # C++ specific cases for pic, static, wl, etc. if test yes = "$GXX"; then _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' case $host_os in aix*) # All AIX code is PIC. if test ia64 = "$host_cpu"; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' fi _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; m68k) # FIXME: we need at least 68020 code to build shared libraries, but # adding the '-m68020' flag to GCC prevents building anything better, # like '-m68040'. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' ;; esac ;; beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; mingw* | cygwin* | os2* | pw32* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). # Although the cygwin gcc ignores -fPIC, still need this for old-style # (--disable-auto-import) libraries m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) case $host_os in os2*) _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static' ;; esac ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' ;; *djgpp*) # DJGPP does not support shared libraries at all _LT_TAGVAR(lt_prog_compiler_pic, $1)= ;; haiku*) # PIC is the default for Haiku. # The "-static" flag exists, but is broken. _LT_TAGVAR(lt_prog_compiler_static, $1)= ;; interix[[3-9]]*) # Interix 3.x gcc -fpic/-fPIC options generate broken code. # Instead, we relocate shared libraries at runtime. ;; sysv4*MP*) if test -d /usr/nec; then _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic fi ;; hpux*) # PIC is the default for 64-bit PA HP-UX, but not for 32-bit # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag # sets the default TLS model and affects inlining. case $host_cpu in hppa*64*) ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac ;; *qnx* | *nto*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac else case $host_os in aix[[4-9]]*) # All AIX code is PIC. if test ia64 = "$host_cpu"; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' else _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' fi ;; chorus*) case $cc_basename in cxch68*) # Green Hills C++ Compiler # _LT_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" ;; esac ;; mingw* | cygwin* | os2* | pw32* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) ;; dgux*) case $cc_basename in ec++*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' ;; ghcx*) # Green Hills C++ Compiler _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ;; *) ;; esac ;; freebsd* | dragonfly* | midnightbsd*) # FreeBSD uses GNU C++ ;; hpux9* | hpux10* | hpux11*) case $cc_basename in CC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive' if test ia64 != "$host_cpu"; then _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' fi ;; aCC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive' case $host_cpu in hppa*64*|ia64*) # +Z the default ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' ;; esac ;; *) ;; esac ;; interix*) # This is c89, which is MS Visual C++ (no shared libs) # Anyone wants to do a port? ;; irix5* | irix6* | nonstopux*) case $cc_basename in CC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' # CC pic flag -KPIC is the default. ;; *) ;; esac ;; linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) case $cc_basename in KCC*) # KAI C++ Compiler _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; ecpc* ) # old Intel C++ for x86_64, which still supported -KPIC. _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; icpc* ) # Intel C++, used to be incompatible with GCC. # ICC 10 doesn't accept -KPIC any more. _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; pgCC* | pgcpp*) # Portland Group C++ compiler _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; cxx*) # Compaq C++ # Make sure the PIC flag is empty. It appears that all Alpha # Linux and Compaq Tru64 Unix objects are PIC. _LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; xlc* | xlC* | bgxl[[cC]]* | mpixl[[cC]]*) # IBM XL 8.0, 9.0 on PPC and BlueGene _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' ;; *) case `$CC -V 2>&1 | $SED 5q` in *Sun\ C*) # Sun C++ 5.9 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' ;; esac ;; esac ;; lynxos*) ;; m88k*) ;; mvs*) case $cc_basename in cxx*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall' ;; *) ;; esac ;; netbsd*) ;; *qnx* | *nto*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; osf3* | osf4* | osf5*) case $cc_basename in KCC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' ;; RCC*) # Rational C++ 2.4.1 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ;; cxx*) # Digital/Compaq C++ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # Make sure the PIC flag is empty. It appears that all Alpha # Linux and Compaq Tru64 Unix objects are PIC. _LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; *) ;; esac ;; psos*) ;; solaris*) case $cc_basename in CC* | sunCC*) # Sun C++ 4.2, 5.x and Centerline C++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' ;; gcx*) # Green Hills C++ Compiler _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' ;; *) ;; esac ;; sunos4*) case $cc_basename in CC*) # Sun C++ 4.x _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; lcc*) # Lucid _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ;; *) ;; esac ;; sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) case $cc_basename in CC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; esac ;; tandem*) case $cc_basename in NCC*) # NonStop-UX NCC 3.20 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' ;; *) ;; esac ;; vxworks*) ;; *) _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no ;; esac fi ], [ if test yes = "$GCC"; then _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' case $host_os in aix*) # All AIX code is PIC. if test ia64 = "$host_cpu"; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' fi _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; m68k) # FIXME: we need at least 68020 code to build shared libraries, but # adding the '-m68020' flag to GCC prevents building anything better, # like '-m68040'. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' ;; esac ;; beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). # Although the cygwin gcc ignores -fPIC, still need this for old-style # (--disable-auto-import) libraries m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) case $host_os in os2*) _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static' ;; esac ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' ;; haiku*) # PIC is the default for Haiku. # The "-static" flag exists, but is broken. _LT_TAGVAR(lt_prog_compiler_static, $1)= ;; hpux*) # PIC is the default for 64-bit PA HP-UX, but not for 32-bit # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag # sets the default TLS model and affects inlining. case $host_cpu in hppa*64*) # +Z the default ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac ;; interix[[3-9]]*) # Interix 3.x gcc -fpic/-fPIC options generate broken code. # Instead, we relocate shared libraries at runtime. ;; msdosdjgpp*) # Just because we use GCC doesn't mean we suddenly get shared libraries # on systems that don't support them. _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no enable_shared=no ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; sysv4*MP*) if test -d /usr/nec; then _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic fi ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac case $cc_basename in nvcc*) # Cuda Compiler Driver 2.2 _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Xlinker ' if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then _LT_TAGVAR(lt_prog_compiler_pic, $1)="-Xcompiler $_LT_TAGVAR(lt_prog_compiler_pic, $1)" fi ;; esac else # PORTME Check for flag to pass linker flags through the system compiler. case $host_os in aix*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' if test ia64 = "$host_cpu"; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' else _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' fi ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' case $cc_basename in nagfor*) # NAG Fortran compiler _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; esac ;; mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) case $host_os in os2*) _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static' ;; esac ;; hpux9* | hpux10* | hpux11*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but # not for PA HP-UX. case $host_cpu in hppa*64*|ia64*) # +Z the default ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' ;; esac # Is there a better lt_prog_compiler_static that works with the bundled CC? _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive' ;; irix5* | irix6* | nonstopux*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # PIC (with -KPIC) is the default. _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) case $cc_basename in # old Intel for x86_64, which still supported -KPIC. ecc*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; # icc used to be incompatible with GCC. # ICC 10 doesn't accept -KPIC any more. icc* | ifort*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; # Lahey Fortran 8.1. lf95*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='--shared' _LT_TAGVAR(lt_prog_compiler_static, $1)='--static' ;; nagfor*) # NAG Fortran compiler _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; tcc*) # Fabrice Bellard et al's Tiny C Compiler _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group compilers (*not* the Pentium gcc compiler, # which looks to be a dead project) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; ccc*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # All Alpha code is PIC. _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; xl* | bgxl* | bgf* | mpixl*) # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' ;; *) case `$CC -V 2>&1 | $SED 5q` in *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [[1-7]].* | *Sun*Fortran*\ 8.[[0-3]]*) # Sun Fortran 8.3 passes all unrecognized flags to the linker _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='' ;; *Sun\ F* | *Sun*Fortran*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' ;; *Sun\ C*) # Sun C 5.9 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ;; *Intel*\ [[CF]]*Compiler*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; *Portland\ Group*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; esac ;; esac ;; newsos6) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; osf3* | osf4* | osf5*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # All OSF/1 code is PIC. _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; rdos*) _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; solaris*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' case $cc_basename in f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';; *) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';; esac ;; sunos4*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; sysv4 | sysv4.2uw2* | sysv4.3*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; sysv4*MP*) if test -d /usr/nec; then _LT_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' fi ;; sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; unicos*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no ;; uts4*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; *) _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no ;; esac fi ]) case $host_os in # For platforms that do not support PIC, -DPIC is meaningless: *djgpp*) _LT_TAGVAR(lt_prog_compiler_pic, $1)= ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])" ;; esac AC_CACHE_CHECK([for $compiler option to produce PIC], [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)], [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_prog_compiler_pic, $1)]) _LT_TAGVAR(lt_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_cv_prog_compiler_pic, $1) # # Check to make sure the PIC flag actually works. # if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then _LT_COMPILER_OPTION([if $compiler PIC flag $_LT_TAGVAR(lt_prog_compiler_pic, $1) works], [_LT_TAGVAR(lt_cv_prog_compiler_pic_works, $1)], [$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])], [], [case $_LT_TAGVAR(lt_prog_compiler_pic, $1) in "" | " "*) ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_TAGVAR(lt_prog_compiler_pic, $1)" ;; esac], [_LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no]) fi _LT_TAGDECL([pic_flag], [lt_prog_compiler_pic], [1], [Additional compiler flags for building library objects]) _LT_TAGDECL([wl], [lt_prog_compiler_wl], [1], [How to pass a linker flag through the compiler]) # # Check to make sure the static flag actually works. # wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) eval lt_tmp_static_flag=\"$_LT_TAGVAR(lt_prog_compiler_static, $1)\" _LT_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works], _LT_TAGVAR(lt_cv_prog_compiler_static_works, $1), $lt_tmp_static_flag, [], [_LT_TAGVAR(lt_prog_compiler_static, $1)=]) _LT_TAGDECL([link_static_flag], [lt_prog_compiler_static], [1], [Compiler flag to prevent dynamic linking]) ])# _LT_COMPILER_PIC # _LT_LINKER_SHLIBS([TAGNAME]) # ---------------------------- # See if the linker supports building shared libraries. m4_defun([_LT_LINKER_SHLIBS], [AC_REQUIRE([LT_PATH_LD])dnl AC_REQUIRE([LT_PATH_NM])dnl m4_require([_LT_PATH_MANIFEST_TOOL])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl m4_require([_LT_TAG_COMPILER])dnl AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) m4_if([$1], [CXX], [ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] case $host_os in aix[[4-9]]*) # If we're using GNU nm, then we don't want the "-C" option. # -C means demangle to GNU nm, but means don't demangle to AIX nm. # Without the "-l" option, or with the "-B" option, AIX nm treats # weak defined symbols like other global defined symbols, whereas # GNU nm marks them as "W". # While the 'weak' keyword is ignored in the Export File, we need # it in the Import File for the 'aix-soname' feature, so we have # to replace the "-B" option with "-P" for AIX nm. if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols' else _LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "L") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' fi ;; pw32*) _LT_TAGVAR(export_symbols_cmds, $1)=$ltdll_cmds ;; cygwin* | mingw* | cegcc*) case $cc_basename in cl* | icl*) _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' ;; *) _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] ;; esac ;; *) _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' ;; esac ], [ runpath_var= _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_cmds, $1)= _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(compiler_needs_object, $1)=no _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(old_archive_from_new_cmds, $1)= _LT_TAGVAR(old_archive_from_expsyms_cmds, $1)= _LT_TAGVAR(thread_safe_flag_spec, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= # include_expsyms should be a list of space-separated symbols to be *always* # included in the symbol list _LT_TAGVAR(include_expsyms, $1)= # exclude_expsyms can be an extended regexp of symbols to exclude # it will be wrapped by ' (' and ')$', so one must not match beginning or # end of line. Example: 'a|bc|.*d.*' will exclude the symbols 'a' and 'bc', # as well as any symbol that contains 'd'. _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out # platforms (ab)use it in PIC code, but their linkers get confused if # the symbol is explicitly referenced. Since portable code cannot # rely on this symbol name, it's probably fine to never include it in # preloaded symbol tables. # Exclude shared library initialization/finalization symbols. dnl Note also adjust exclude_expsyms for C++ above. extract_expsyms_cmds= case $host_os in cygwin* | mingw* | pw32* | cegcc*) # FIXME: the MSVC++ and ICC port hasn't been tested in a loooong time # When not using gcc, we currently assume that we are using # Microsoft Visual C++ or Intel C++ Compiler. if test yes != "$GCC"; then with_gnu_ld=no fi ;; interix*) # we just hope/assume this is gcc and not c89 (= MSVC++ or ICC) with_gnu_ld=yes ;; openbsd* | bitrig*) with_gnu_ld=no ;; esac _LT_TAGVAR(ld_shlibs, $1)=yes # On some targets, GNU ld is compatible enough with the native linker # that we're better off using the native interface for both. lt_use_gnu_ld_interface=no if test yes = "$with_gnu_ld"; then case $host_os in aix*) # The AIX port of GNU ld has always aspired to compatibility # with the native linker. However, as the warning in the GNU ld # block says, versions before 2.19.5* couldn't really create working # shared libraries, regardless of the interface used. case `$LD -v 2>&1` in *\ \(GNU\ Binutils\)\ 2.19.5*) ;; *\ \(GNU\ Binutils\)\ 2.[[2-9]]*) ;; *\ \(GNU\ Binutils\)\ [[3-9]]*) ;; *) lt_use_gnu_ld_interface=yes ;; esac ;; *) lt_use_gnu_ld_interface=yes ;; esac fi if test yes = "$lt_use_gnu_ld_interface"; then # If archive_cmds runs LD, not CC, wlarc should be empty wlarc='$wl' # Set some defaults for GNU ld with shared library support. These # are reset later if shared libraries are not supported. Putting them # here allows them to be overridden if necessary. runpath_var=LD_RUN_PATH _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' # ancient GNU ld didn't support --whole-archive et. al. if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' else _LT_TAGVAR(whole_archive_flag_spec, $1)= fi supports_anon_versioning=no case `$LD -v | $SED -e 's/([[^)]]\+)\s\+//' 2>&1` in *GNU\ gold*) supports_anon_versioning=yes ;; *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11 *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... *\ 2.11.*) ;; # other 2.11 versions *) supports_anon_versioning=yes ;; esac # See if GNU ld supports shared libraries. case $host_os in aix[[3-9]]*) # On AIX/PPC, the GNU linker is very broken if test ia64 != "$host_cpu"; then _LT_TAGVAR(ld_shlibs, $1)=no cat <<_LT_EOF 1>&2 *** Warning: the GNU linker, at least up to release 2.19, is reported *** to be unable to reliably create shared libraries on AIX. *** Therefore, libtool is disabling shared libraries support. If you *** really care for shared libraries, you may want to install binutils *** 2.20 or above, or modify your PATH so that a non-GNU linker is found. *** You will then need to restart the configuration process. _LT_EOF fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='' ;; m68k) _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes ;; esac ;; beos*) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(allow_undefined_flag, $1)=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; cygwin* | mingw* | pw32* | cegcc*) # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, # as there is no search path for DLLs. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-all-symbols' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file, use it as # is; otherwise, prepend EXPORTS... _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then cp $export_symbols $output_objdir/$soname.def; else echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; haiku*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(link_all_deplibs, $1)=yes ;; os2*) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(allow_undefined_flag, $1)=unsupported shrext_cmds=.dll _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' _LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ prefix_cmds="$SED"~ if test EXPORTS = "`$SED 1q $export_symbols`"; then prefix_cmds="$prefix_cmds -e 1d"; fi~ prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes _LT_TAGVAR(file_list_spec, $1)='@' ;; interix[[3-9]]*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$SED "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) tmp_diet=no if test linux-dietlibc = "$host_os"; then case $cc_basename in diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) esac fi if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ && test no = "$tmp_diet" then tmp_addflag=' $pic_flag' tmp_sharedflag='-shared' case $cc_basename,$host_cpu in pgcc*) # Portland Group C compiler _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' tmp_addflag=' $pic_flag' ;; pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group f77 and f90 compilers _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' tmp_addflag=' $pic_flag -Mnomain' ;; ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 tmp_addflag=' -i_dynamic' ;; efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 tmp_addflag=' -i_dynamic -nofor_main' ;; ifc* | ifort*) # Intel Fortran compiler tmp_addflag=' -nofor_main' ;; lf95*) # Lahey Fortran 8.1 _LT_TAGVAR(whole_archive_flag_spec, $1)= tmp_sharedflag='--shared' ;; nagfor*) # NAGFOR 5.3 tmp_sharedflag='-Wl,-shared' ;; xl[[cC]]* | bgxl[[cC]]* | mpixl[[cC]]*) # IBM XL C 8.0 on PPC (deal with xlf below) tmp_sharedflag='-qmkshrobj' tmp_addflag= ;; nvcc*) # Cuda Compiler Driver 2.2 _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' _LT_TAGVAR(compiler_needs_object, $1)=yes ;; esac case `$CC -V 2>&1 | $SED 5q` in *Sun\ C*) # Sun C 5.9 _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' _LT_TAGVAR(compiler_needs_object, $1)=yes tmp_sharedflag='-G' ;; *Sun\ F*) # Sun Fortran 8.3 tmp_sharedflag='-G' ;; esac _LT_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' if test yes = "$supports_anon_versioning"; then _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' fi case $cc_basename in tcc*) _LT_TAGVAR(export_dynamic_flag_spec, $1)='-rdynamic' ;; xlf* | bgf* | bgxlf* | mpixlf*) # IBM XL Fortran 10.1 on PPC cannot create shared libs itself _LT_TAGVAR(whole_archive_flag_spec, $1)='--whole-archive$convenience --no-whole-archive' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' if test yes = "$supports_anon_versioning"; then _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' fi ;; esac else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; netbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' wlarc= else _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' fi ;; solaris*) if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then _LT_TAGVAR(ld_shlibs, $1)=no cat <<_LT_EOF 1>&2 *** Warning: The releases 2.8.* of the GNU linker cannot reliably *** create shared libraries on Solaris systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.9.1 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) case `$LD -v 2>&1` in *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.1[[0-5]].*) _LT_TAGVAR(ld_shlibs, $1)=no cat <<_LT_EOF 1>&2 *** Warning: Releases of the GNU linker prior to 2.16.91.0.3 cannot *** reliably create shared libraries on SCO systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.16.91.0.3 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF ;; *) # For security reasons, it is highly recommended that you always # use absolute paths for naming shared libraries, and exclude the # DT_RUNPATH tag from executables and libraries. But doing so # requires that you compile everything twice, which is a pain. if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; sunos4*) _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' wlarc= _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac if test no = "$_LT_TAGVAR(ld_shlibs, $1)"; then runpath_var= _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= fi else # PORTME fill in a description of your system's linker (not GNU ld) case $host_os in aix3*) _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=yes _LT_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' # Note: this linker hardcodes the directories in LIBPATH if there # are no directories specified by -L. _LT_TAGVAR(hardcode_minus_L, $1)=yes if test yes = "$GCC" && test -z "$lt_prog_compiler_static"; then # Neither direct hardcoding nor static linking is supported with a # broken collect2. _LT_TAGVAR(hardcode_direct, $1)=unsupported fi ;; aix[[4-9]]*) if test ia64 = "$host_cpu"; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' no_entry_flag= else # If we're using GNU nm, then we don't want the "-C" option. # -C means demangle to GNU nm, but means don't demangle to AIX nm. # Without the "-l" option, or with the "-B" option, AIX nm treats # weak defined symbols like other global defined symbols, whereas # GNU nm marks them as "W". # While the 'weak' keyword is ignored in the Export File, we need # it in the Import File for the 'aix-soname' feature, so we have # to replace the "-B" option with "-P" for AIX nm. if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols' else _LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "L") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' fi aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # have runtime linking enabled, and use it for executables. # For shared libraries, we enable/disable runtime linking # depending on the kind of the shared library created - # when "with_aix_soname,aix_use_runtimelinking" is: # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables # "aix,yes" lib.so shared, rtl:yes, for executables # lib.a static archive # "both,no" lib.so.V(shr.o) shared, rtl:yes # lib.a(lib.so.V) shared, rtl:no, for executables # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables # lib.a(lib.so.V) shared, rtl:no # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables # lib.a static archive case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) for ld_flag in $LDFLAGS; do if (test x-brtl = "x$ld_flag" || test x-Wl,-brtl = "x$ld_flag"); then aix_use_runtimelinking=yes break fi done if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then # With aix-soname=svr4, we create the lib.so.V shared archives only, # so we don't have lib.a shared libs to link our executables. # We have to force runtime linking in this case. aix_use_runtimelinking=yes LDFLAGS="$LDFLAGS -Wl,-brtl" fi ;; esac exp_sym_flag='-bexport' no_entry_flag='-bnoentry' fi # When large executables or shared objects are built, AIX ld can # have problems creating the table of contents. If linking a library # or program results in "error TOC overflow" add -mminimal-toc to # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. _LT_TAGVAR(archive_cmds, $1)='' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(file_list_spec, $1)='$wl-f,' case $with_aix_soname,$aix_use_runtimelinking in aix,*) ;; # traditional, no import file svr4,* | *,yes) # use import file # The Import File defines what to hardcode. _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no ;; esac if test yes = "$GCC"; then case $host_os in aix4.[[012]]|aix4.[[012]].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ collect2name=`$CC -print-prog-name=collect2` if test -f "$collect2name" && strings "$collect2name" | $GREP resolve_lib_name >/dev/null then # We have reworked collect2 : else # We have old collect2 _LT_TAGVAR(hardcode_direct, $1)=unsupported # It fails to find uninstalled libraries when the uninstalled # path is not listed in the libpath. Setting hardcode_minus_L # to unsupported forces relinking _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)= fi ;; esac shared_flag='-shared' if test yes = "$aix_use_runtimelinking"; then shared_flag="$shared_flag "'$wl-G' fi # Need to ensure runtime linking is disabled for the traditional # shared library, or the linker may eventually find shared libraries # /with/ Import File - we do not want to mix them. shared_flag_aix='-shared' shared_flag_svr4='-shared $wl-G' else # not using gcc if test ia64 = "$host_cpu"; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else if test yes = "$aix_use_runtimelinking"; then shared_flag='$wl-G' else shared_flag='$wl-bM:SRE' fi shared_flag_aix='$wl-bM:SRE' shared_flag_svr4='$wl-G' fi fi _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-bexpall' # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to export. _LT_TAGVAR(always_export_symbols, $1)=yes if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. _LT_TAGVAR(allow_undefined_flag, $1)='-berok' # Determine the default libpath from the value encoded in an # empty executable. _LT_SYS_MODULE_PATH_AIX([$1]) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag else if test ia64 = "$host_cpu"; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $libdir:/usr/lib:/lib' _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an # empty executable. _LT_SYS_MODULE_PATH_AIX([$1]) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. _LT_TAGVAR(no_undefined_flag, $1)=' $wl-bernotok' _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-berok' if test yes = "$with_gnu_ld"; then # We only use this code for GNU lds that support --whole-archive. _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive' else # Exported symbols can be pulled into shared objects from archives _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' fi _LT_TAGVAR(archive_cmds_need_lc, $1)=yes _LT_TAGVAR(archive_expsym_cmds, $1)='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d' # -brtl affects multiple linker settings, -berok does not and is overridden later compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([[, ]]\\)%-berok\\1%g"`' if test svr4 != "$with_aix_soname"; then # This is similar to how AIX traditionally builds its shared libraries. _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname' fi if test aix != "$with_aix_soname"; then _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp' else # used by -dlpreopen to get the symbols _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$MV $output_objdir/$realname.d/$soname $output_objdir' fi _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$RM -r $output_objdir/$realname.d' fi fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='' ;; m68k) _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes ;; esac ;; bsdi[[45]]*) _LT_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic ;; cygwin* | mingw* | pw32* | cegcc*) # When not using gcc, we currently assume that we are using # Microsoft Visual C++ or Intel C++ Compiler. # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. case $cc_basename in cl* | icl*) # Native MSVC or ICC _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=yes _LT_TAGVAR(file_list_spec, $1)='@' # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=.dll # FIXME: Setting linknames here is a bad hack. _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then cp "$export_symbols" "$output_objdir/$soname.def"; echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; else $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp; fi~ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ linknames=' # The linker will not automatically build a static lib if we build a DLL. # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1,DATA/'\'' | $SED -e '\''/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols' # Don't use ranlib _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ lt_tool_outputfile="@TOOL_OUTPUT@"~ case $lt_outputfile in *.exe|*.EXE) ;; *) lt_outputfile=$lt_outputfile.exe lt_tool_outputfile=$lt_tool_outputfile.exe ;; esac~ if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; $RM "$lt_outputfile.manifest"; fi' ;; *) # Assume MSVC and ICC wrapper _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=.dll # FIXME: Setting linknames here is a bad hack. _LT_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' # The linker will automatically build a .lib file if we build a DLL. _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' # FIXME: Should let the user specify the lib program. _LT_TAGVAR(old_archive_cmds, $1)='lib -OUT:$oldlib$oldobjs$old_deplibs' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes ;; esac ;; darwin* | rhapsody*) _LT_DARWIN_LINKER_FEATURES($1) ;; dgux*) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor # support. Future versions do this automatically, but an explicit c++rt0.o # does not break anything, and helps significantly (at the cost of a little # extra space). freebsd2.2*) _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; # Unfortunately, older versions of FreeBSD 2 do not have this feature. freebsd2.*) _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; # FreeBSD 3 and greater uses gcc -shared to do shared libraries. freebsd* | dragonfly* | midnightbsd*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; hpux9*) if test yes = "$GCC"; then _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' else _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(hardcode_direct, $1)=yes # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' ;; hpux10*) if test yes,no = "$GCC,$with_gnu_ld"; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' fi if test no = "$with_gnu_ld"; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. _LT_TAGVAR(hardcode_minus_L, $1)=yes fi ;; hpux11*) if test yes,no = "$GCC,$with_gnu_ld"; then case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ;; esac else case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) m4_if($1, [], [ # Older versions of the 11.00 compiler do not understand -b yet # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) _LT_LINKER_OPTION([if $CC understands -b], _LT_TAGVAR(lt_cv_prog_compiler__b, $1), [-b], [_LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'], [_LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'])], [_LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags']) ;; esac fi if test no = "$with_gnu_ld"; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: case $host_cpu in hppa*64*|ia64*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. _LT_TAGVAR(hardcode_minus_L, $1)=yes ;; esac fi ;; irix5* | irix6* | nonstopux*) if test yes = "$GCC"; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' # Try to use the -exported_symbol ld option, if it does not # work, assume that -exports_file does not work either and # implicitly export all symbols. # This should be the same for all languages, so no per-tag cache variable. AC_CACHE_CHECK([whether the $host_os linker accepts -exported_symbol], [lt_cv_irix_exported_symbol], [save_LDFLAGS=$LDFLAGS LDFLAGS="$LDFLAGS -shared $wl-exported_symbol ${wl}foo $wl-update_registry $wl/dev/null" AC_LINK_IFELSE( [AC_LANG_SOURCE( [AC_LANG_CASE([C], [[int foo (void) { return 0; }]], [C++], [[int foo (void) { return 0; }]], [Fortran 77], [[ subroutine foo end]], [Fortran], [[ subroutine foo end]])])], [lt_cv_irix_exported_symbol=yes], [lt_cv_irix_exported_symbol=no]) LDFLAGS=$save_LDFLAGS]) if test yes = "$lt_cv_irix_exported_symbol"; then _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations $wl-exports_file $wl$export_symbols -o $lib' fi else _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -exports_file $export_symbols -o $lib' fi _LT_TAGVAR(archive_cmds_need_lc, $1)='no' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(inherit_rpath, $1)=yes _LT_TAGVAR(link_all_deplibs, $1)=yes ;; linux*) case $cc_basename in tcc*) # Fabrice Bellard et al's Tiny C Compiler _LT_TAGVAR(ld_shlibs, $1)=yes _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' ;; esac ;; netbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out else _LT_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; newsos6) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *nto* | *qnx*) ;; openbsd* | bitrig*) if test -f /usr/libexec/ld.so; then _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=yes if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags $wl-retain-symbols-file,$export_symbols' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' else _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' fi else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; os2*) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(allow_undefined_flag, $1)=unsupported shrext_cmds=.dll _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' _LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ prefix_cmds="$SED"~ if test EXPORTS = "`$SED 1q $export_symbols`"; then prefix_cmds="$prefix_cmds -e 1d"; fi~ prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes _LT_TAGVAR(file_list_spec, $1)='@' ;; osf3*) if test yes = "$GCC"; then _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' else _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' fi _LT_TAGVAR(archive_cmds_need_lc, $1)='no' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: ;; osf4* | osf5*) # as osf3* with the addition of -msym flag if test yes = "$GCC"; then _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $pic_flag $libobjs $deplibs $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' else _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ $CC -shared$allow_undefined_flag $wl-input $wl$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~$RM $lib.exp' # Both c and cxx compiler support -rpath directly _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' fi _LT_TAGVAR(archive_cmds_need_lc, $1)='no' _LT_TAGVAR(hardcode_libdir_separator, $1)=: ;; solaris*) _LT_TAGVAR(no_undefined_flag, $1)=' -z defs' if test yes = "$GCC"; then wlarc='$wl' _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl-z ${wl}text $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -shared $pic_flag $wl-z ${wl}text $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' else case `$CC -V 2>&1` in *"Compilers 5.0"*) wlarc='' _LT_TAGVAR(archive_cmds, $1)='$LD -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $LD -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' ;; *) wlarc='$wl' _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' ;; esac fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no case $host_os in solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; *) # The compiler driver will combine and reorder linker options, # but understands '-z linker_flag'. GCC discards it without '$wl', # but is careful enough not to reorder. # Supported since Solaris 2.6 (maybe 2.5.1?) if test yes = "$GCC"; then _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract' else _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' fi ;; esac _LT_TAGVAR(link_all_deplibs, $1)=yes ;; sunos4*) if test sequent = "$host_vendor"; then # Use $CC to link under sequent, because it throws in some extra .o # files that make .init and .fini sections work. _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h $soname -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; sysv4) case $host_vendor in sni) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=yes # is this really true??? ;; siemens) ## LD is ld it makes a PLAMLIB ## CC just makes a GrossModule. _LT_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs' _LT_TAGVAR(hardcode_direct, $1)=no ;; motorola) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie ;; esac runpath_var='LD_RUN_PATH' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; sysv4.3*) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport' ;; sysv4*MP*) if test -d /usr/nec; then _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no runpath_var=LD_RUN_PATH hardcode_runpath_var=yes _LT_TAGVAR(ld_shlibs, $1)=yes fi ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no runpath_var='LD_RUN_PATH' if test yes = "$GCC"; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; sysv5* | sco3.2v5* | sco5v6*) # Note: We CANNOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' _LT_TAGVAR(allow_undefined_flag, $1)='$wl-z,nodefs' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R,$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Bexport' runpath_var='LD_RUN_PATH' if test yes = "$GCC"; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; uts4*) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) _LT_TAGVAR(ld_shlibs, $1)=no ;; esac if test sni = "$host_vendor"; then case $host in sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Blargedynsym' ;; esac fi fi ]) AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) test no = "$_LT_TAGVAR(ld_shlibs, $1)" && can_build_shared=no _LT_TAGVAR(with_gnu_ld, $1)=$with_gnu_ld _LT_DECL([], [libext], [0], [Old archive suffix (normally "a")])dnl _LT_DECL([], [shrext_cmds], [1], [Shared library suffix (normally ".so")])dnl _LT_DECL([], [extract_expsyms_cmds], [2], [The commands to extract the exported symbol list from a shared archive]) # # Do we need to explicitly link libc? # case "x$_LT_TAGVAR(archive_cmds_need_lc, $1)" in x|xyes) # Assume -lc should be added _LT_TAGVAR(archive_cmds_need_lc, $1)=yes if test yes,yes = "$GCC,$enable_shared"; then case $_LT_TAGVAR(archive_cmds, $1) in *'~'*) # FIXME: we may have to deal with multi-command sequences. ;; '$CC '*) # Test whether the compiler implicitly links with -lc since on some # systems, -lgcc has to come before -lc. If gcc already passes -lc # to ld, don't add -lc before -lgcc. AC_CACHE_CHECK([whether -lc should be explicitly linked in], [lt_cv_]_LT_TAGVAR(archive_cmds_need_lc, $1), [$RM conftest* echo "$lt_simple_compile_test_code" > conftest.$ac_ext if AC_TRY_EVAL(ac_compile) 2>conftest.err; then soname=conftest lib=conftest libobjs=conftest.$ac_objext deplibs= wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) pic_flag=$_LT_TAGVAR(lt_prog_compiler_pic, $1) compiler_flags=-v linker_flags=-v verstring= output_objdir=. libname=conftest lt_save_allow_undefined_flag=$_LT_TAGVAR(allow_undefined_flag, $1) _LT_TAGVAR(allow_undefined_flag, $1)= if AC_TRY_EVAL(_LT_TAGVAR(archive_cmds, $1) 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) then lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=no else lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=yes fi _LT_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag else cat conftest.err 1>&5 fi $RM conftest* ]) _LT_TAGVAR(archive_cmds_need_lc, $1)=$lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1) ;; esac fi ;; esac _LT_TAGDECL([build_libtool_need_lc], [archive_cmds_need_lc], [0], [Whether or not to add -lc for building shared libraries]) _LT_TAGDECL([allow_libtool_libs_with_static_runtimes], [enable_shared_with_static_runtimes], [0], [Whether or not to disallow shared libs when runtime libs are static]) _LT_TAGDECL([], [export_dynamic_flag_spec], [1], [Compiler flag to allow reflexive dlopens]) _LT_TAGDECL([], [whole_archive_flag_spec], [1], [Compiler flag to generate shared objects directly from archives]) _LT_TAGDECL([], [compiler_needs_object], [1], [Whether the compiler copes with passing no objects directly]) _LT_TAGDECL([], [old_archive_from_new_cmds], [2], [Create an old-style archive from a shared archive]) _LT_TAGDECL([], [old_archive_from_expsyms_cmds], [2], [Create a temporary old-style archive to link instead of a shared archive]) _LT_TAGDECL([], [archive_cmds], [2], [Commands used to build a shared archive]) _LT_TAGDECL([], [archive_expsym_cmds], [2]) _LT_TAGDECL([], [module_cmds], [2], [Commands used to build a loadable module if different from building a shared archive.]) _LT_TAGDECL([], [module_expsym_cmds], [2]) _LT_TAGDECL([], [with_gnu_ld], [1], [Whether we are building with GNU ld or not]) _LT_TAGDECL([], [allow_undefined_flag], [1], [Flag that allows shared libraries with undefined symbols to be built]) _LT_TAGDECL([], [no_undefined_flag], [1], [Flag that enforces no undefined symbols]) _LT_TAGDECL([], [hardcode_libdir_flag_spec], [1], [Flag to hardcode $libdir into a binary during linking. This must work even if $libdir does not exist]) _LT_TAGDECL([], [hardcode_libdir_separator], [1], [Whether we need a single "-rpath" flag with a separated argument]) _LT_TAGDECL([], [hardcode_direct], [0], [Set to "yes" if using DIR/libNAME$shared_ext during linking hardcodes DIR into the resulting binary]) _LT_TAGDECL([], [hardcode_direct_absolute], [0], [Set to "yes" if using DIR/libNAME$shared_ext during linking hardcodes DIR into the resulting binary and the resulting library dependency is "absolute", i.e impossible to change by setting $shlibpath_var if the library is relocated]) _LT_TAGDECL([], [hardcode_minus_L], [0], [Set to "yes" if using the -LDIR flag during linking hardcodes DIR into the resulting binary]) _LT_TAGDECL([], [hardcode_shlibpath_var], [0], [Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into the resulting binary]) _LT_TAGDECL([], [hardcode_automatic], [0], [Set to "yes" if building a shared library automatically hardcodes DIR into the library and all subsequent libraries and executables linked against it]) _LT_TAGDECL([], [inherit_rpath], [0], [Set to yes if linker adds runtime paths of dependent libraries to runtime path list]) _LT_TAGDECL([], [link_all_deplibs], [0], [Whether libtool must link a program against all its dependency libraries]) _LT_TAGDECL([], [always_export_symbols], [0], [Set to "yes" if exported symbols are required]) _LT_TAGDECL([], [export_symbols_cmds], [2], [The commands to list exported symbols]) _LT_TAGDECL([], [exclude_expsyms], [1], [Symbols that should not be listed in the preloaded symbols]) _LT_TAGDECL([], [include_expsyms], [1], [Symbols that must always be exported]) _LT_TAGDECL([], [prelink_cmds], [2], [Commands necessary for linking programs (against libraries) with templates]) _LT_TAGDECL([], [postlink_cmds], [2], [Commands necessary for finishing linking programs]) _LT_TAGDECL([], [file_list_spec], [1], [Specify filename containing input files]) dnl FIXME: Not yet implemented dnl _LT_TAGDECL([], [thread_safe_flag_spec], [1], dnl [Compiler flag to generate thread safe objects]) ])# _LT_LINKER_SHLIBS # _LT_LANG_C_CONFIG([TAG]) # ------------------------ # Ensure that the configuration variables for a C compiler are suitably # defined. These variables are subsequently used by _LT_CONFIG to write # the compiler configuration to 'libtool'. m4_defun([_LT_LANG_C_CONFIG], [m4_require([_LT_DECL_EGREP])dnl lt_save_CC=$CC AC_LANG_PUSH(C) # Source file extension for C test sources. ac_ext=c # Object file extension for compiled C test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="int some_variable = 0;" # Code to be used in simple link tests lt_simple_link_test_code='int main(){return(0);}' _LT_TAG_COMPILER # Save the default compiler, since it gets overwritten when the other # tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. compiler_DEFAULT=$CC # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... if test -n "$compiler"; then _LT_COMPILER_NO_RTTI($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) LT_SYS_DLOPEN_SELF _LT_CMD_STRIPLIB # Report what library types will actually be built AC_MSG_CHECKING([if libtool supports shared libraries]) AC_MSG_RESULT([$can_build_shared]) AC_MSG_CHECKING([whether to build shared libraries]) test no = "$can_build_shared" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test yes = "$enable_shared" && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[[4-9]]*) if test ia64 != "$host_cpu"; then case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in yes,aix,yes) ;; # shared object as lib.so file only yes,svr4,*) ;; # shared object as lib.so archive member only yes,*) enable_static=no ;; # shared object in lib.a archive as well esac fi ;; esac AC_MSG_RESULT([$enable_shared]) AC_MSG_CHECKING([whether to build static libraries]) # Make sure either enable_shared or enable_static is yes. test yes = "$enable_shared" || enable_static=yes AC_MSG_RESULT([$enable_static]) _LT_CONFIG($1) fi AC_LANG_POP CC=$lt_save_CC ])# _LT_LANG_C_CONFIG # _LT_LANG_CXX_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for a C++ compiler are suitably # defined. These variables are subsequently used by _LT_CONFIG to write # the compiler configuration to 'libtool'. m4_defun([_LT_LANG_CXX_CONFIG], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_PATH_MANIFEST_TOOL])dnl if test -n "$CXX" && ( test no != "$CXX" && ( (test g++ = "$CXX" && `g++ -v >/dev/null 2>&1` ) || (test g++ != "$CXX"))); then AC_PROG_CXXCPP else _lt_caught_CXX_error=yes fi AC_LANG_PUSH(C++) _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(compiler_needs_object, $1)=no _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds _LT_TAGVAR(no_undefined_flag, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no # Source file extension for C++ test sources. ac_ext=cpp # Object file extension for compiled C++ test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # No sense in running all these tests if we already determined that # the CXX compiler isn't working. Some variables (like enable_shared) # are currently assumed to apply to all compilers on this platform, # and will be corrupted by setting them based on a non-working compiler. if test yes != "$_lt_caught_CXX_error"; then # Code to be used in simple compile tests lt_simple_compile_test_code="int some_variable = 0;" # Code to be used in simple link tests lt_simple_link_test_code='int main(int, char *[[]]) { return(0); }' # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_CFLAGS=$CFLAGS lt_save_LD=$LD lt_save_GCC=$GCC GCC=$GXX lt_save_with_gnu_ld=$with_gnu_ld lt_save_path_LD=$lt_cv_path_LD if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx else $as_unset lt_cv_prog_gnu_ld fi if test -n "${lt_cv_path_LDCXX+set}"; then lt_cv_path_LD=$lt_cv_path_LDCXX else $as_unset lt_cv_path_LD fi test -z "${LDCXX+set}" || LD=$LDCXX CC=${CXX-"c++"} CFLAGS=$CXXFLAGS compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) if test -n "$compiler"; then # We don't want -fno-exception when compiling C++ code, so set the # no_builtin_flag separately if test yes = "$GXX"; then _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' else _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= fi if test yes = "$GXX"; then # Set up default GNU C++ configuration LT_PATH_LD # Check if GNU C++ uses GNU ld as the underlying linker, since the # archiving commands below assume that GNU ld is being used. if test yes = "$with_gnu_ld"; then _LT_TAGVAR(archive_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' # If archive_cmds runs LD, not CC, wlarc should be empty # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to # investigate it a little bit more. (MM) wlarc='$wl' # ancient GNU ld didn't support --whole-archive et. al. if eval "`$CC -print-prog-name=ld` --help 2>&1" | $GREP 'no-whole-archive' > /dev/null; then _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' else _LT_TAGVAR(whole_archive_flag_spec, $1)= fi else with_gnu_ld=no wlarc= # A generic and very simple default shared library creation # command for GNU C++ for the case where it uses the native # linker, instead of GNU ld. If possible, this setting should # overridden to take advantage of the native linker features on # the platform it is being used on. _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' fi # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' else GXX=no with_gnu_ld=no wlarc= fi # PORTME: fill in a description of your system's C++ link characteristics AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) _LT_TAGVAR(ld_shlibs, $1)=yes case $host_os in aix3*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; aix[[4-9]]*) if test ia64 = "$host_cpu"; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' no_entry_flag= else aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # have runtime linking enabled, and use it for executables. # For shared libraries, we enable/disable runtime linking # depending on the kind of the shared library created - # when "with_aix_soname,aix_use_runtimelinking" is: # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables # "aix,yes" lib.so shared, rtl:yes, for executables # lib.a static archive # "both,no" lib.so.V(shr.o) shared, rtl:yes # lib.a(lib.so.V) shared, rtl:no, for executables # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables # lib.a(lib.so.V) shared, rtl:no # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables # lib.a static archive case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) for ld_flag in $LDFLAGS; do case $ld_flag in *-brtl*) aix_use_runtimelinking=yes break ;; esac done if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then # With aix-soname=svr4, we create the lib.so.V shared archives only, # so we don't have lib.a shared libs to link our executables. # We have to force runtime linking in this case. aix_use_runtimelinking=yes LDFLAGS="$LDFLAGS -Wl,-brtl" fi ;; esac exp_sym_flag='-bexport' no_entry_flag='-bnoentry' fi # When large executables or shared objects are built, AIX ld can # have problems creating the table of contents. If linking a library # or program results in "error TOC overflow" add -mminimal-toc to # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. _LT_TAGVAR(archive_cmds, $1)='' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(file_list_spec, $1)='$wl-f,' case $with_aix_soname,$aix_use_runtimelinking in aix,*) ;; # no import file svr4,* | *,yes) # use import file # The Import File defines what to hardcode. _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no ;; esac if test yes = "$GXX"; then case $host_os in aix4.[[012]]|aix4.[[012]].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ collect2name=`$CC -print-prog-name=collect2` if test -f "$collect2name" && strings "$collect2name" | $GREP resolve_lib_name >/dev/null then # We have reworked collect2 : else # We have old collect2 _LT_TAGVAR(hardcode_direct, $1)=unsupported # It fails to find uninstalled libraries when the uninstalled # path is not listed in the libpath. Setting hardcode_minus_L # to unsupported forces relinking _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)= fi esac shared_flag='-shared' if test yes = "$aix_use_runtimelinking"; then shared_flag=$shared_flag' $wl-G' fi # Need to ensure runtime linking is disabled for the traditional # shared library, or the linker may eventually find shared libraries # /with/ Import File - we do not want to mix them. shared_flag_aix='-shared' shared_flag_svr4='-shared $wl-G' else # not using gcc if test ia64 = "$host_cpu"; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else if test yes = "$aix_use_runtimelinking"; then shared_flag='$wl-G' else shared_flag='$wl-bM:SRE' fi shared_flag_aix='$wl-bM:SRE' shared_flag_svr4='$wl-G' fi fi _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-bexpall' # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to # export. _LT_TAGVAR(always_export_symbols, $1)=yes if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. # The "-G" linker flag allows undefined symbols. _LT_TAGVAR(no_undefined_flag, $1)='-bernotok' # Determine the default libpath from the value encoded in an empty # executable. _LT_SYS_MODULE_PATH_AIX([$1]) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag else if test ia64 = "$host_cpu"; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $libdir:/usr/lib:/lib' _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an # empty executable. _LT_SYS_MODULE_PATH_AIX([$1]) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. _LT_TAGVAR(no_undefined_flag, $1)=' $wl-bernotok' _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-berok' if test yes = "$with_gnu_ld"; then # We only use this code for GNU lds that support --whole-archive. _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive' else # Exported symbols can be pulled into shared objects from archives _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' fi _LT_TAGVAR(archive_cmds_need_lc, $1)=yes _LT_TAGVAR(archive_expsym_cmds, $1)='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d' # -brtl affects multiple linker settings, -berok does not and is overridden later compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([[, ]]\\)%-berok\\1%g"`' if test svr4 != "$with_aix_soname"; then # This is similar to how AIX traditionally builds its shared # libraries. Need -bnortl late, we may have -brtl in LDFLAGS. _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname' fi if test aix != "$with_aix_soname"; then _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp' else # used by -dlpreopen to get the symbols _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$MV $output_objdir/$realname.d/$soname $output_objdir' fi _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$RM -r $output_objdir/$realname.d' fi fi ;; beos*) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(allow_undefined_flag, $1)=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; chorus*) case $cc_basename in *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; cygwin* | mingw* | pw32* | cegcc*) case $GXX,$cc_basename in ,cl* | no,cl* | ,icl* | no,icl*) # Native MSVC or ICC # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=yes _LT_TAGVAR(file_list_spec, $1)='@' # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=.dll # FIXME: Setting linknames here is a bad hack. _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then cp "$export_symbols" "$output_objdir/$soname.def"; echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; else $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp; fi~ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ linknames=' # The linker will not automatically build a static lib if we build a DLL. # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes # Don't use ranlib _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ lt_tool_outputfile="@TOOL_OUTPUT@"~ case $lt_outputfile in *.exe|*.EXE) ;; *) lt_outputfile=$lt_outputfile.exe lt_tool_outputfile=$lt_tool_outputfile.exe ;; esac~ func_to_tool_file "$lt_outputfile"~ if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; $RM "$lt_outputfile.manifest"; fi' ;; *) # g++ # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, # as there is no search path for DLLs. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-all-symbols' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file, use it as # is; otherwise, prepend EXPORTS... _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then cp $export_symbols $output_objdir/$soname.def; else echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; darwin* | rhapsody*) _LT_DARWIN_LINKER_FEATURES($1) ;; os2*) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(allow_undefined_flag, $1)=unsupported shrext_cmds=.dll _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' _LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ prefix_cmds="$SED"~ if test EXPORTS = "`$SED 1q $export_symbols`"; then prefix_cmds="$prefix_cmds -e 1d"; fi~ prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes _LT_TAGVAR(file_list_spec, $1)='@' ;; dgux*) case $cc_basename in ec++*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; ghcx*) # Green Hills C++ Compiler # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; freebsd2.*) # C++ shared libraries reported to be fairly broken before # switch to ELF _LT_TAGVAR(ld_shlibs, $1)=no ;; freebsd-elf*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;; freebsd* | dragonfly* | midnightbsd*) # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF # conventions _LT_TAGVAR(ld_shlibs, $1)=yes ;; haiku*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(link_all_deplibs, $1)=yes ;; hpux9*) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, # but as the default # location of the library. case $cc_basename in CC*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; aCC*) _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -b $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test yes = "$GXX"; then _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' else # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; hpux10*|hpux11*) if test no = "$with_gnu_ld"; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: case $host_cpu in hppa*64*|ia64*) ;; *) _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' ;; esac fi case $host_cpu in hppa*64*|ia64*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, # but as the default # location of the library. ;; esac case $cc_basename in CC*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; aCC*) case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; esac # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test yes = "$GXX"; then if test no = "$with_gnu_ld"; then case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; esac fi else # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; interix[[3-9]]*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$SED "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; irix5* | irix6*) case $cc_basename in CC*) # SGI C++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' # Archives containing C++ object files must be created using # "CC -ar", where "CC" is the IRIX C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs' ;; *) if test yes = "$GXX"; then if test no = "$with_gnu_ld"; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' else _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` -o $lib' fi fi _LT_TAGVAR(link_all_deplibs, $1)=yes ;; esac _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(inherit_rpath, $1)=yes ;; linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) case $cc_basename in KCC*) # Kuck and Associates, Inc. (KAI) C++ Compiler # KCC will only create a shared library if the output file # ends with ".so" (or ".sl" for HP-UX), so rename the library # to its proper name (with version) after linking. _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib $wl-retain-symbols-file,$export_symbols; mv \$templib $lib' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' # Archives containing C++ object files must be created using # "CC -Bstatic", where "CC" is the KAI C++ compiler. _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;; icpc* | ecpc* ) # Intel C++ with_gnu_ld=yes # version 8.0 and above of icpc choke on multiply defined symbols # if we add $predep_objects and $postdep_objects, however 7.1 and # earlier do not add the objects themselves. case `$CC -V 2>&1` in *"Version 7."*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' ;; *) # Version 8.0 or newer tmp_idyn= case $host_cpu in ia64*) tmp_idyn=' -i_dynamic';; esac _LT_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' ;; esac _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive' ;; pgCC* | pgcpp*) # Portland Group C++ compiler case `$CC -V` in *pgCC\ [[1-5]].* | *pgcpp\ [[1-5]].*) _LT_TAGVAR(prelink_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~ compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"' _LT_TAGVAR(old_archive_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~ $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~ $RANLIB $oldlib' _LT_TAGVAR(archive_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' ;; *) # Version 6 and above use weak symbols _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' ;; esac _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl--rpath $wl$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' ;; cxx*) # Compaq C++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib $wl-retain-symbols-file $wl$export_symbols' runpath_var=LD_RUN_PATH _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed' ;; xl* | mpixl* | bgxl*) # IBM XL 8.0 on PPC, with GNU ld _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' if test yes = "$supports_anon_versioning"; then _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' fi ;; *) case `$CC -V 2>&1 | $SED 5q` in *Sun\ C*) # Sun C++ 5.9 _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file $wl$export_symbols' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' _LT_TAGVAR(compiler_needs_object, $1)=yes # Not sure whether something based on # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 # would be better. output_verbose_link_cmd='func_echo_all' # Archives containing C++ object files must be created using # "CC -xar", where "CC" is the Sun C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' ;; esac ;; esac ;; lynxos*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; m88k*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; mvs*) case $cc_basename in cxx*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; netbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' wlarc= _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no fi # Workaround some broken pre-1.5 toolchains output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' ;; *nto* | *qnx*) _LT_TAGVAR(ld_shlibs, $1)=yes ;; openbsd* | bitrig*) if test -f /usr/libexec/ld.so; then _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`"; then _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file,$export_symbols -o $lib' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' fi output_verbose_link_cmd=func_echo_all else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; osf3* | osf4* | osf5*) case $cc_basename in KCC*) # Kuck and Associates, Inc. (KAI) C++ Compiler # KCC will only create a shared library if the output file # ends with ".so" (or ".sl" for HP-UX), so rename the library # to its proper name (with version) after linking. _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Archives containing C++ object files must be created using # the KAI C++ compiler. case $host in osf3*) _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;; *) _LT_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs' ;; esac ;; RCC*) # Rational C++ 2.4.1 # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; cxx*) case $host in osf3*) _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $soname `test -n "$verstring" && func_echo_all "$wl-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' ;; *) _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ echo "-hidden">> $lib.exp~ $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname $wl-input $wl$lib.exp `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~ $RM $lib.exp' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' ;; esac _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test yes,no = "$GXX,$with_gnu_ld"; then _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' case $host in osf3*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' ;; esac _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' else # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; psos*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; sunos4*) case $cc_basename in CC*) # Sun C++ 4.x # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; lcc*) # Lucid # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; solaris*) case $cc_basename in CC* | sunCC*) # Sun C++ 4.2, 5.x and Centerline C++ _LT_TAGVAR(archive_cmds_need_lc,$1)=yes _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G$allow_undefined_flag $wl-M $wl$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no case $host_os in solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; *) # The compiler driver will combine and reorder linker options, # but understands '-z linker_flag'. # Supported since Solaris 2.6 (maybe 2.5.1?) _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' ;; esac _LT_TAGVAR(link_all_deplibs, $1)=yes output_verbose_link_cmd='func_echo_all' # Archives containing C++ object files must be created using # "CC -xar", where "CC" is the Sun C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' ;; gcx*) # Green Hills C++ Compiler _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' # The C++ compiler must be used to create the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs' ;; *) # GNU C++ compiler with Solaris linker if test yes,no = "$GXX,$with_gnu_ld"; then _LT_TAGVAR(no_undefined_flag, $1)=' $wl-z ${wl}defs' if $CC --version | $GREP -v '^2\.7' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -shared $pic_flag -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' else # g++ 2.7 appears to require '-G' NOT '-shared' on this # platform. _LT_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $wl$libdir' case $host_os in solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; *) _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract' ;; esac fi ;; esac ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no runpath_var='LD_RUN_PATH' case $cc_basename in CC*) _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; esac ;; sysv5* | sco3.2v5* | sco5v6*) # Note: We CANNOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' _LT_TAGVAR(allow_undefined_flag, $1)='$wl-z,nodefs' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R,$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Bexport' runpath_var='LD_RUN_PATH' case $cc_basename in CC*) _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(old_archive_cmds, $1)='$CC -Tprelink_objects $oldobjs~ '"$_LT_TAGVAR(old_archive_cmds, $1)" _LT_TAGVAR(reload_cmds, $1)='$CC -Tprelink_objects $reload_objs~ '"$_LT_TAGVAR(reload_cmds, $1)" ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; esac ;; tandem*) case $cc_basename in NCC*) # NonStop-UX NCC 3.20 # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; vxworks*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) test no = "$_LT_TAGVAR(ld_shlibs, $1)" && can_build_shared=no _LT_TAGVAR(GCC, $1)=$GXX _LT_TAGVAR(LD, $1)=$LD ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... _LT_SYS_HIDDEN_LIBDEPS($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi # test -n "$compiler" CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS LDCXX=$LD LD=$lt_save_LD GCC=$lt_save_GCC with_gnu_ld=$lt_save_with_gnu_ld lt_cv_path_LDCXX=$lt_cv_path_LD lt_cv_path_LD=$lt_save_path_LD lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld fi # test yes != "$_lt_caught_CXX_error" AC_LANG_POP ])# _LT_LANG_CXX_CONFIG # _LT_FUNC_STRIPNAME_CNF # ---------------------- # func_stripname_cnf prefix suffix name # strip PREFIX and SUFFIX off of NAME. # PREFIX and SUFFIX must not contain globbing or regex special # characters, hashes, percent signs, but SUFFIX may contain a leading # dot (in which case that matches only a dot). # # This function is identical to the (non-XSI) version of func_stripname, # except this one can be used by m4 code that may be executed by configure, # rather than the libtool script. m4_defun([_LT_FUNC_STRIPNAME_CNF],[dnl AC_REQUIRE([_LT_DECL_SED]) AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH]) func_stripname_cnf () { case @S|@2 in .*) func_stripname_result=`$ECHO "@S|@3" | $SED "s%^@S|@1%%; s%\\\\@S|@2\$%%"`;; *) func_stripname_result=`$ECHO "@S|@3" | $SED "s%^@S|@1%%; s%@S|@2\$%%"`;; esac } # func_stripname_cnf ])# _LT_FUNC_STRIPNAME_CNF # _LT_SYS_HIDDEN_LIBDEPS([TAGNAME]) # --------------------------------- # Figure out "hidden" library dependencies from verbose # compiler output when linking a shared library. # Parse the compiler output and extract the necessary # objects, libraries and library flags. m4_defun([_LT_SYS_HIDDEN_LIBDEPS], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl AC_REQUIRE([_LT_FUNC_STRIPNAME_CNF])dnl # Dependencies to place before and after the object being linked: _LT_TAGVAR(predep_objects, $1)= _LT_TAGVAR(postdep_objects, $1)= _LT_TAGVAR(predeps, $1)= _LT_TAGVAR(postdeps, $1)= _LT_TAGVAR(compiler_lib_search_path, $1)= dnl we can't use the lt_simple_compile_test_code here, dnl because it contains code intended for an executable, dnl not a library. It's possible we should let each dnl tag define a new lt_????_link_test_code variable, dnl but it's only used here... m4_if([$1], [], [cat > conftest.$ac_ext <<_LT_EOF int a; void foo (void) { a = 0; } _LT_EOF ], [$1], [CXX], [cat > conftest.$ac_ext <<_LT_EOF class Foo { public: Foo (void) { a = 0; } private: int a; }; _LT_EOF ], [$1], [F77], [cat > conftest.$ac_ext <<_LT_EOF subroutine foo implicit none integer*4 a a=0 return end _LT_EOF ], [$1], [FC], [cat > conftest.$ac_ext <<_LT_EOF subroutine foo implicit none integer a a=0 return end _LT_EOF ], [$1], [GCJ], [cat > conftest.$ac_ext <<_LT_EOF public class foo { private int a; public void bar (void) { a = 0; } }; _LT_EOF ], [$1], [GO], [cat > conftest.$ac_ext <<_LT_EOF package foo func foo() { } _LT_EOF ]) _lt_libdeps_save_CFLAGS=$CFLAGS case "$CC $CFLAGS " in #( *\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;; *\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;; *\ -fuse-linker-plugin*\ *) CFLAGS="$CFLAGS -fno-use-linker-plugin" ;; esac dnl Parse the compiler output and extract the necessary dnl objects, libraries and library flags. if AC_TRY_EVAL(ac_compile); then # Parse the compiler output and extract the necessary # objects, libraries and library flags. # Sentinel used to keep track of whether or not we are before # the conftest object file. pre_test_object_deps_done=no for p in `eval "$output_verbose_link_cmd"`; do case $prev$p in -L* | -R* | -l*) # Some compilers place space between "-{L,R}" and the path. # Remove the space. if test x-L = "$p" || test x-R = "$p"; then prev=$p continue fi # Expand the sysroot to ease extracting the directories later. if test -z "$prev"; then case $p in -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;; -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;; -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;; esac fi case $p in =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;; esac if test no = "$pre_test_object_deps_done"; then case $prev in -L | -R) # Internal compiler library paths should come after those # provided the user. The postdeps already come after the # user supplied libs so there is no need to process them. if test -z "$_LT_TAGVAR(compiler_lib_search_path, $1)"; then _LT_TAGVAR(compiler_lib_search_path, $1)=$prev$p else _LT_TAGVAR(compiler_lib_search_path, $1)="${_LT_TAGVAR(compiler_lib_search_path, $1)} $prev$p" fi ;; # The "-l" case would never come before the object being # linked, so don't bother handling this case. esac else if test -z "$_LT_TAGVAR(postdeps, $1)"; then _LT_TAGVAR(postdeps, $1)=$prev$p else _LT_TAGVAR(postdeps, $1)="${_LT_TAGVAR(postdeps, $1)} $prev$p" fi fi prev= ;; *.lto.$objext) ;; # Ignore GCC LTO objects *.$objext) # This assumes that the test object file only shows up # once in the compiler output. if test "$p" = "conftest.$objext"; then pre_test_object_deps_done=yes continue fi if test no = "$pre_test_object_deps_done"; then if test -z "$_LT_TAGVAR(predep_objects, $1)"; then _LT_TAGVAR(predep_objects, $1)=$p else _LT_TAGVAR(predep_objects, $1)="$_LT_TAGVAR(predep_objects, $1) $p" fi else if test -z "$_LT_TAGVAR(postdep_objects, $1)"; then _LT_TAGVAR(postdep_objects, $1)=$p else _LT_TAGVAR(postdep_objects, $1)="$_LT_TAGVAR(postdep_objects, $1) $p" fi fi ;; *) ;; # Ignore the rest. esac done # Clean up. rm -f a.out a.exe else echo "libtool.m4: error: problem compiling $1 test program" fi $RM -f confest.$objext CFLAGS=$_lt_libdeps_save_CFLAGS # PORTME: override above test on systems where it is broken m4_if([$1], [CXX], [case $host_os in interix[[3-9]]*) # Interix 3.5 installs completely hosed .la files for C++, so rather than # hack all around it, let's just trust "g++" to DTRT. _LT_TAGVAR(predep_objects,$1)= _LT_TAGVAR(postdep_objects,$1)= _LT_TAGVAR(postdeps,$1)= ;; esac ]) case " $_LT_TAGVAR(postdeps, $1) " in *" -lc "*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;; esac _LT_TAGVAR(compiler_lib_search_dirs, $1)= if test -n "${_LT_TAGVAR(compiler_lib_search_path, $1)}"; then _LT_TAGVAR(compiler_lib_search_dirs, $1)=`echo " ${_LT_TAGVAR(compiler_lib_search_path, $1)}" | $SED -e 's! -L! !g' -e 's!^ !!'` fi _LT_TAGDECL([], [compiler_lib_search_dirs], [1], [The directories searched by this compiler when creating a shared library]) _LT_TAGDECL([], [predep_objects], [1], [Dependencies to place before and after the objects being linked to create a shared library]) _LT_TAGDECL([], [postdep_objects], [1]) _LT_TAGDECL([], [predeps], [1]) _LT_TAGDECL([], [postdeps], [1]) _LT_TAGDECL([], [compiler_lib_search_path], [1], [The library search path used internally by the compiler when linking a shared library]) ])# _LT_SYS_HIDDEN_LIBDEPS # _LT_LANG_F77_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for a Fortran 77 compiler are # suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to 'libtool'. m4_defun([_LT_LANG_F77_CONFIG], [AC_LANG_PUSH(Fortran 77) if test -z "$F77" || test no = "$F77"; then _lt_disable_F77=yes fi _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds _LT_TAGVAR(no_undefined_flag, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no # Source file extension for f77 test sources. ac_ext=f # Object file extension for compiled f77 test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # No sense in running all these tests if we already determined that # the F77 compiler isn't working. Some variables (like enable_shared) # are currently assumed to apply to all compilers on this platform, # and will be corrupted by setting them based on a non-working compiler. if test yes != "$_lt_disable_F77"; then # Code to be used in simple compile tests lt_simple_compile_test_code="\ subroutine t return end " # Code to be used in simple link tests lt_simple_link_test_code="\ program t end " # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_GCC=$GCC lt_save_CFLAGS=$CFLAGS CC=${F77-"f77"} CFLAGS=$FFLAGS compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) GCC=$G77 if test -n "$compiler"; then AC_MSG_CHECKING([if libtool supports shared libraries]) AC_MSG_RESULT([$can_build_shared]) AC_MSG_CHECKING([whether to build shared libraries]) test no = "$can_build_shared" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test yes = "$enable_shared" && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[[4-9]]*) if test ia64 != "$host_cpu"; then case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in yes,aix,yes) ;; # shared object as lib.so file only yes,svr4,*) ;; # shared object as lib.so archive member only yes,*) enable_static=no ;; # shared object in lib.a archive as well esac fi ;; esac AC_MSG_RESULT([$enable_shared]) AC_MSG_CHECKING([whether to build static libraries]) # Make sure either enable_shared or enable_static is yes. test yes = "$enable_shared" || enable_static=yes AC_MSG_RESULT([$enable_static]) _LT_TAGVAR(GCC, $1)=$G77 _LT_TAGVAR(LD, $1)=$LD ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi # test -n "$compiler" GCC=$lt_save_GCC CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS fi # test yes != "$_lt_disable_F77" AC_LANG_POP ])# _LT_LANG_F77_CONFIG # _LT_LANG_FC_CONFIG([TAG]) # ------------------------- # Ensure that the configuration variables for a Fortran compiler are # suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to 'libtool'. m4_defun([_LT_LANG_FC_CONFIG], [AC_LANG_PUSH(Fortran) if test -z "$FC" || test no = "$FC"; then _lt_disable_FC=yes fi _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds _LT_TAGVAR(no_undefined_flag, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no # Source file extension for fc test sources. ac_ext=${ac_fc_srcext-f} # Object file extension for compiled fc test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # No sense in running all these tests if we already determined that # the FC compiler isn't working. Some variables (like enable_shared) # are currently assumed to apply to all compilers on this platform, # and will be corrupted by setting them based on a non-working compiler. if test yes != "$_lt_disable_FC"; then # Code to be used in simple compile tests lt_simple_compile_test_code="\ subroutine t return end " # Code to be used in simple link tests lt_simple_link_test_code="\ program t end " # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_GCC=$GCC lt_save_CFLAGS=$CFLAGS CC=${FC-"f95"} CFLAGS=$FCFLAGS compiler=$CC GCC=$ac_cv_fc_compiler_gnu _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) if test -n "$compiler"; then AC_MSG_CHECKING([if libtool supports shared libraries]) AC_MSG_RESULT([$can_build_shared]) AC_MSG_CHECKING([whether to build shared libraries]) test no = "$can_build_shared" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test yes = "$enable_shared" && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[[4-9]]*) if test ia64 != "$host_cpu"; then case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in yes,aix,yes) ;; # shared object as lib.so file only yes,svr4,*) ;; # shared object as lib.so archive member only yes,*) enable_static=no ;; # shared object in lib.a archive as well esac fi ;; esac AC_MSG_RESULT([$enable_shared]) AC_MSG_CHECKING([whether to build static libraries]) # Make sure either enable_shared or enable_static is yes. test yes = "$enable_shared" || enable_static=yes AC_MSG_RESULT([$enable_static]) _LT_TAGVAR(GCC, $1)=$ac_cv_fc_compiler_gnu _LT_TAGVAR(LD, $1)=$LD ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... _LT_SYS_HIDDEN_LIBDEPS($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi # test -n "$compiler" GCC=$lt_save_GCC CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS fi # test yes != "$_lt_disable_FC" AC_LANG_POP ])# _LT_LANG_FC_CONFIG # _LT_LANG_GCJ_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for the GNU Java Compiler compiler # are suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to 'libtool'. m4_defun([_LT_LANG_GCJ_CONFIG], [AC_REQUIRE([LT_PROG_GCJ])dnl AC_LANG_SAVE # Source file extension for Java test sources. ac_ext=java # Object file extension for compiled Java test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="class foo {}" # Code to be used in simple link tests lt_simple_link_test_code='public class conftest { public static void main(String[[]] argv) {}; }' # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_CFLAGS=$CFLAGS lt_save_GCC=$GCC GCC=yes CC=${GCJ-"gcj"} CFLAGS=$GCJFLAGS compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_TAGVAR(LD, $1)=$LD _LT_CC_BASENAME([$compiler]) # GCJ did not exist at the time GCC didn't implicitly link libc in. _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... if test -n "$compiler"; then _LT_COMPILER_NO_RTTI($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi AC_LANG_RESTORE GCC=$lt_save_GCC CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS ])# _LT_LANG_GCJ_CONFIG # _LT_LANG_GO_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for the GNU Go compiler # are suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to 'libtool'. m4_defun([_LT_LANG_GO_CONFIG], [AC_REQUIRE([LT_PROG_GO])dnl AC_LANG_SAVE # Source file extension for Go test sources. ac_ext=go # Object file extension for compiled Go test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="package main; func main() { }" # Code to be used in simple link tests lt_simple_link_test_code='package main; func main() { }' # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_CFLAGS=$CFLAGS lt_save_GCC=$GCC GCC=yes CC=${GOC-"gccgo"} CFLAGS=$GOFLAGS compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_TAGVAR(LD, $1)=$LD _LT_CC_BASENAME([$compiler]) # Go did not exist at the time GCC didn't implicitly link libc in. _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... if test -n "$compiler"; then _LT_COMPILER_NO_RTTI($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi AC_LANG_RESTORE GCC=$lt_save_GCC CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS ])# _LT_LANG_GO_CONFIG # _LT_LANG_RC_CONFIG([TAG]) # ------------------------- # Ensure that the configuration variables for the Windows resource compiler # are suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to 'libtool'. m4_defun([_LT_LANG_RC_CONFIG], [AC_REQUIRE([LT_PROG_RC])dnl AC_LANG_SAVE # Source file extension for RC test sources. ac_ext=rc # Object file extension for compiled RC test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }' # Code to be used in simple link tests lt_simple_link_test_code=$lt_simple_compile_test_code # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_CFLAGS=$CFLAGS lt_save_GCC=$GCC GCC= CC=${RC-"windres"} CFLAGS= compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes if test -n "$compiler"; then : _LT_CONFIG($1) fi GCC=$lt_save_GCC AC_LANG_RESTORE CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS ])# _LT_LANG_RC_CONFIG # LT_PROG_GCJ # ----------- AC_DEFUN([LT_PROG_GCJ], [m4_ifdef([AC_PROG_GCJ], [AC_PROG_GCJ], [m4_ifdef([A][M_PROG_GCJ], [A][M_PROG_GCJ], [AC_CHECK_TOOL(GCJ, gcj,) test set = "${GCJFLAGS+set}" || GCJFLAGS="-g -O2" AC_SUBST(GCJFLAGS)])])[]dnl ]) # Old name: AU_ALIAS([LT_AC_PROG_GCJ], [LT_PROG_GCJ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([LT_AC_PROG_GCJ], []) # LT_PROG_GO # ---------- AC_DEFUN([LT_PROG_GO], [AC_CHECK_TOOL(GOC, gccgo,) ]) # LT_PROG_RC # ---------- AC_DEFUN([LT_PROG_RC], [AC_CHECK_TOOL(RC, windres,) ]) # Old name: AU_ALIAS([LT_AC_PROG_RC], [LT_PROG_RC]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([LT_AC_PROG_RC], []) # _LT_DECL_EGREP # -------------- # If we don't have a new enough Autoconf to choose the best grep # available, choose the one first in the user's PATH. m4_defun([_LT_DECL_EGREP], [AC_REQUIRE([AC_PROG_EGREP])dnl AC_REQUIRE([AC_PROG_FGREP])dnl test -z "$GREP" && GREP=grep _LT_DECL([], [GREP], [1], [A grep program that handles long lines]) _LT_DECL([], [EGREP], [1], [An ERE matcher]) _LT_DECL([], [FGREP], [1], [A literal string matcher]) dnl Non-bleeding-edge autoconf doesn't subst GREP, so do it here too AC_SUBST([GREP]) ]) # _LT_DECL_OBJDUMP # -------------- # If we don't have a new enough Autoconf to choose the best objdump # available, choose the one first in the user's PATH. m4_defun([_LT_DECL_OBJDUMP], [AC_CHECK_TOOL(OBJDUMP, objdump, false) test -z "$OBJDUMP" && OBJDUMP=objdump _LT_DECL([], [OBJDUMP], [1], [An object symbol dumper]) AC_SUBST([OBJDUMP]) ]) # _LT_DECL_DLLTOOL # ---------------- # Ensure DLLTOOL variable is set. m4_defun([_LT_DECL_DLLTOOL], [AC_CHECK_TOOL(DLLTOOL, dlltool, false) test -z "$DLLTOOL" && DLLTOOL=dlltool _LT_DECL([], [DLLTOOL], [1], [DLL creation program]) AC_SUBST([DLLTOOL]) ]) # _LT_DECL_FILECMD # ---------------- # Check for a file(cmd) program that can be used to detect file type and magic m4_defun([_LT_DECL_FILECMD], [AC_CHECK_TOOL([FILECMD], [file], [:]) _LT_DECL([], [FILECMD], [1], [A file(cmd) program that detects file types]) ])# _LD_DECL_FILECMD # _LT_DECL_SED # ------------ # Check for a fully-functional sed program, that truncates # as few characters as possible. Prefer GNU sed if found. m4_defun([_LT_DECL_SED], [AC_PROG_SED test -z "$SED" && SED=sed Xsed="$SED -e 1s/^X//" _LT_DECL([], [SED], [1], [A sed program that does not truncate output]) _LT_DECL([], [Xsed], ["\$SED -e 1s/^X//"], [Sed that helps us avoid accidentally triggering echo(1) options like -n]) ])# _LT_DECL_SED m4_ifndef([AC_PROG_SED], [ ############################################################ # 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. # ############################################################ m4_defun([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_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for lt_ac_prog in sed gsed; do for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext" fi done done done IFS=$as_save_IFS lt_ac_max=0 lt_ac_count=0 # Add /usr/xpg4/bin/sed as it is typically found on Solaris # along with /bin/sed that truncates output. for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do test ! -f "$lt_ac_sed" && continue cat /dev/null > conftest.in lt_ac_count=0 echo $ECHO_N "0123456789$ECHO_C" >conftest.in # Check for GNU sed and select it if it is found. if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then lt_cv_path_SED=$lt_ac_sed break fi while true; do cat conftest.in conftest.in >conftest.tmp mv conftest.tmp conftest.in cp conftest.in conftest.nl echo >>conftest.nl $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break cmp -s conftest.out conftest.nl || break # 10000 chars as input seems more than enough test 10 -lt "$lt_ac_count" && break lt_ac_count=`expr $lt_ac_count + 1` if test "$lt_ac_count" -gt "$lt_ac_max"; then lt_ac_max=$lt_ac_count lt_cv_path_SED=$lt_ac_sed fi done done ]) SED=$lt_cv_path_SED AC_SUBST([SED]) AC_MSG_RESULT([$SED]) ])#AC_PROG_SED ])#m4_ifndef # Old name: AU_ALIAS([LT_AC_PROG_SED], [AC_PROG_SED]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([LT_AC_PROG_SED], []) # _LT_CHECK_SHELL_FEATURES # ------------------------ # Find out whether the shell is Bourne or XSI compatible, # or has some other useful features. m4_defun([_LT_CHECK_SHELL_FEATURES], [if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then lt_unset=unset else lt_unset=false fi _LT_DECL([], [lt_unset], [0], [whether the shell understands "unset"])dnl # test EBCDIC or ASCII case `echo X|tr X '\101'` in A) # ASCII based system # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr lt_SP2NL='tr \040 \012' lt_NL2SP='tr \015\012 \040\040' ;; *) # EBCDIC based system lt_SP2NL='tr \100 \n' lt_NL2SP='tr \r\n \100\100' ;; esac _LT_DECL([SP2NL], [lt_SP2NL], [1], [turn spaces into newlines])dnl _LT_DECL([NL2SP], [lt_NL2SP], [1], [turn newlines into spaces])dnl ])# _LT_CHECK_SHELL_FEATURES # _LT_PATH_CONVERSION_FUNCTIONS # ----------------------------- # Determine what file name conversion functions should be used by # func_to_host_file (and, implicitly, by func_to_host_path). These are needed # for certain cross-compile configurations and native mingw. m4_defun([_LT_PATH_CONVERSION_FUNCTIONS], [AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_CANONICAL_BUILD])dnl AC_MSG_CHECKING([how to convert $build file names to $host format]) AC_CACHE_VAL(lt_cv_to_host_file_cmd, [case $host in *-*-mingw* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 ;; *-*-cygwin* ) lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32 ;; * ) # otherwise, assume *nix lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32 ;; esac ;; *-*-cygwin* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin ;; *-*-cygwin* ) lt_cv_to_host_file_cmd=func_convert_file_noop ;; * ) # otherwise, assume *nix lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin ;; esac ;; * ) # unhandled hosts (and "normal" native builds) lt_cv_to_host_file_cmd=func_convert_file_noop ;; esac ]) to_host_file_cmd=$lt_cv_to_host_file_cmd AC_MSG_RESULT([$lt_cv_to_host_file_cmd]) _LT_DECL([to_host_file_cmd], [lt_cv_to_host_file_cmd], [0], [convert $build file names to $host format])dnl AC_MSG_CHECKING([how to convert $build file names to toolchain format]) AC_CACHE_VAL(lt_cv_to_tool_file_cmd, [#assume ordinary cross tools, or native build. lt_cv_to_tool_file_cmd=func_convert_file_noop case $host in *-*-mingw* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 ;; esac ;; esac ]) to_tool_file_cmd=$lt_cv_to_tool_file_cmd AC_MSG_RESULT([$lt_cv_to_tool_file_cmd]) _LT_DECL([to_tool_file_cmd], [lt_cv_to_tool_file_cmd], [0], [convert $build files to toolchain format])dnl ])# _LT_PATH_CONVERSION_FUNCTIONS ppp-2.5.0/m4/ltoptions.m40000644000175000017500000003427514214520133012061 00000000000000# Helper functions for option handling. -*- Autoconf -*- # # Copyright (C) 2004-2005, 2007-2009, 2011-2019, 2021-2022 Free # Software Foundation, Inc. # Written by Gary V. Vaughan, 2004 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # serial 8 ltoptions.m4 # This is to help aclocal find these macros, as it can't see m4_define. AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])]) # _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME) # ------------------------------------------ m4_define([_LT_MANGLE_OPTION], [[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])]) # _LT_SET_OPTION(MACRO-NAME, OPTION-NAME) # --------------------------------------- # Set option OPTION-NAME for macro MACRO-NAME, and if there is a # matching handler defined, dispatch to it. Other OPTION-NAMEs are # saved as a flag. m4_define([_LT_SET_OPTION], [m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]), _LT_MANGLE_DEFUN([$1], [$2]), [m4_warning([Unknown $1 option '$2'])])[]dnl ]) # _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET]) # ------------------------------------------------------------ # Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. m4_define([_LT_IF_OPTION], [m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])]) # _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET) # ------------------------------------------------------- # Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME # are set. m4_define([_LT_UNLESS_OPTIONS], [m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), [m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option), [m4_define([$0_found])])])[]dnl m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3 ])[]dnl ]) # _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST) # ---------------------------------------- # OPTION-LIST is a space-separated list of Libtool options associated # with MACRO-NAME. If any OPTION has a matching handler declared with # LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about # the unknown option and exit. m4_defun([_LT_SET_OPTIONS], [# Set options m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), [_LT_SET_OPTION([$1], _LT_Option)]) m4_if([$1],[LT_INIT],[ dnl dnl Simply set some default values (i.e off) if boolean options were not dnl specified: _LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no ]) _LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no ]) dnl dnl If no reference was made to various pairs of opposing options, then dnl we run the default mode handler for the pair. For example, if neither dnl 'shared' nor 'disable-shared' was passed, we enable building of shared dnl archives by default: _LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED]) _LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC]) _LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC]) _LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install], [_LT_ENABLE_FAST_INSTALL]) _LT_UNLESS_OPTIONS([LT_INIT], [aix-soname=aix aix-soname=both aix-soname=svr4], [_LT_WITH_AIX_SONAME([aix])]) ]) ])# _LT_SET_OPTIONS ## --------------------------------- ## ## Macros to handle LT_INIT options. ## ## --------------------------------- ## # _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME) # ----------------------------------------- m4_define([_LT_MANGLE_DEFUN], [[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])]) # LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE) # ----------------------------------------------- m4_define([LT_OPTION_DEFINE], [m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl ])# LT_OPTION_DEFINE # dlopen # ------ LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes ]) AU_DEFUN([AC_LIBTOOL_DLOPEN], [_LT_SET_OPTION([LT_INIT], [dlopen]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the 'dlopen' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], []) # win32-dll # --------- # Declare package support for building win32 dll's. LT_OPTION_DEFINE([LT_INIT], [win32-dll], [enable_win32_dll=yes case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*) AC_CHECK_TOOL(AS, as, false) AC_CHECK_TOOL(DLLTOOL, dlltool, false) AC_CHECK_TOOL(OBJDUMP, objdump, false) ;; esac test -z "$AS" && AS=as _LT_DECL([], [AS], [1], [Assembler program])dnl test -z "$DLLTOOL" && DLLTOOL=dlltool _LT_DECL([], [DLLTOOL], [1], [DLL creation program])dnl test -z "$OBJDUMP" && OBJDUMP=objdump _LT_DECL([], [OBJDUMP], [1], [Object dumper program])dnl ])# win32-dll AU_DEFUN([AC_LIBTOOL_WIN32_DLL], [AC_REQUIRE([AC_CANONICAL_HOST])dnl _LT_SET_OPTION([LT_INIT], [win32-dll]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the 'win32-dll' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], []) # _LT_ENABLE_SHARED([DEFAULT]) # ---------------------------- # implement the --enable-shared flag, and supports the 'shared' and # 'disable-shared' LT_INIT options. # DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'. m4_define([_LT_ENABLE_SHARED], [m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl AC_ARG_ENABLE([shared], [AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@], [build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])], [p=${PACKAGE-default} case $enableval in yes) enable_shared=yes ;; no) enable_shared=no ;; *) enable_shared=no # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for pkg in $enableval; do IFS=$lt_save_ifs if test "X$pkg" = "X$p"; then enable_shared=yes fi done IFS=$lt_save_ifs ;; esac], [enable_shared=]_LT_ENABLE_SHARED_DEFAULT) _LT_DECL([build_libtool_libs], [enable_shared], [0], [Whether or not to build shared libraries]) ])# _LT_ENABLE_SHARED LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])]) LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])]) # Old names: AC_DEFUN([AC_ENABLE_SHARED], [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared]) ]) AC_DEFUN([AC_DISABLE_SHARED], [_LT_SET_OPTION([LT_INIT], [disable-shared]) ]) AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)]) AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AM_ENABLE_SHARED], []) dnl AC_DEFUN([AM_DISABLE_SHARED], []) # _LT_ENABLE_STATIC([DEFAULT]) # ---------------------------- # implement the --enable-static flag, and support the 'static' and # 'disable-static' LT_INIT options. # DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'. m4_define([_LT_ENABLE_STATIC], [m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl AC_ARG_ENABLE([static], [AS_HELP_STRING([--enable-static@<:@=PKGS@:>@], [build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])], [p=${PACKAGE-default} case $enableval in yes) enable_static=yes ;; no) enable_static=no ;; *) enable_static=no # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for pkg in $enableval; do IFS=$lt_save_ifs if test "X$pkg" = "X$p"; then enable_static=yes fi done IFS=$lt_save_ifs ;; esac], [enable_static=]_LT_ENABLE_STATIC_DEFAULT) _LT_DECL([build_old_libs], [enable_static], [0], [Whether or not to build static libraries]) ])# _LT_ENABLE_STATIC LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])]) LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])]) # Old names: AC_DEFUN([AC_ENABLE_STATIC], [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static]) ]) AC_DEFUN([AC_DISABLE_STATIC], [_LT_SET_OPTION([LT_INIT], [disable-static]) ]) AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)]) AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AM_ENABLE_STATIC], []) dnl AC_DEFUN([AM_DISABLE_STATIC], []) # _LT_ENABLE_FAST_INSTALL([DEFAULT]) # ---------------------------------- # implement the --enable-fast-install flag, and support the 'fast-install' # and 'disable-fast-install' LT_INIT options. # DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'. m4_define([_LT_ENABLE_FAST_INSTALL], [m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl AC_ARG_ENABLE([fast-install], [AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@], [optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])], [p=${PACKAGE-default} case $enableval in yes) enable_fast_install=yes ;; no) enable_fast_install=no ;; *) enable_fast_install=no # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for pkg in $enableval; do IFS=$lt_save_ifs if test "X$pkg" = "X$p"; then enable_fast_install=yes fi done IFS=$lt_save_ifs ;; esac], [enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT) _LT_DECL([fast_install], [enable_fast_install], [0], [Whether or not to optimize for fast installation])dnl ])# _LT_ENABLE_FAST_INSTALL LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])]) LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])]) # Old names: AU_DEFUN([AC_ENABLE_FAST_INSTALL], [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the 'fast-install' option into LT_INIT's first parameter.]) ]) AU_DEFUN([AC_DISABLE_FAST_INSTALL], [_LT_SET_OPTION([LT_INIT], [disable-fast-install]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the 'disable-fast-install' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], []) dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], []) # _LT_WITH_AIX_SONAME([DEFAULT]) # ---------------------------------- # implement the --with-aix-soname flag, and support the `aix-soname=aix' # and `aix-soname=both' and `aix-soname=svr4' LT_INIT options. DEFAULT # is either `aix', `both' or `svr4'. If omitted, it defaults to `aix'. m4_define([_LT_WITH_AIX_SONAME], [m4_define([_LT_WITH_AIX_SONAME_DEFAULT], [m4_if($1, svr4, svr4, m4_if($1, both, both, aix))])dnl shared_archive_member_spec= case $host,$enable_shared in power*-*-aix[[5-9]]*,yes) AC_MSG_CHECKING([which variant of shared library versioning to provide]) AC_ARG_WITH([aix-soname], [AS_HELP_STRING([--with-aix-soname=aix|svr4|both], [shared library versioning (aka "SONAME") variant to provide on AIX, @<:@default=]_LT_WITH_AIX_SONAME_DEFAULT[@:>@.])], [case $withval in aix|svr4|both) ;; *) AC_MSG_ERROR([Unknown argument to --with-aix-soname]) ;; esac lt_cv_with_aix_soname=$with_aix_soname], [AC_CACHE_VAL([lt_cv_with_aix_soname], [lt_cv_with_aix_soname=]_LT_WITH_AIX_SONAME_DEFAULT) with_aix_soname=$lt_cv_with_aix_soname]) AC_MSG_RESULT([$with_aix_soname]) if test aix != "$with_aix_soname"; then # For the AIX way of multilib, we name the shared archive member # based on the bitwidth used, traditionally 'shr.o' or 'shr_64.o', # and 'shr.imp' or 'shr_64.imp', respectively, for the Import File. # Even when GNU compilers ignore OBJECT_MODE but need '-maix64' flag, # the AIX toolchain works better with OBJECT_MODE set (default 32). if test 64 = "${OBJECT_MODE-32}"; then shared_archive_member_spec=shr_64 else shared_archive_member_spec=shr fi fi ;; *) with_aix_soname=aix ;; esac _LT_DECL([], [shared_archive_member_spec], [0], [Shared archive member basename, for filename based shared library versioning on AIX])dnl ])# _LT_WITH_AIX_SONAME LT_OPTION_DEFINE([LT_INIT], [aix-soname=aix], [_LT_WITH_AIX_SONAME([aix])]) LT_OPTION_DEFINE([LT_INIT], [aix-soname=both], [_LT_WITH_AIX_SONAME([both])]) LT_OPTION_DEFINE([LT_INIT], [aix-soname=svr4], [_LT_WITH_AIX_SONAME([svr4])]) # _LT_WITH_PIC([MODE]) # -------------------- # implement the --with-pic flag, and support the 'pic-only' and 'no-pic' # LT_INIT options. # MODE is either 'yes' or 'no'. If omitted, it defaults to 'both'. m4_define([_LT_WITH_PIC], [AC_ARG_WITH([pic], [AS_HELP_STRING([--with-pic@<:@=PKGS@:>@], [try to use only PIC/non-PIC objects @<:@default=use both@:>@])], [lt_p=${PACKAGE-default} case $withval in yes|no) pic_mode=$withval ;; *) pic_mode=default # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for lt_pkg in $withval; do IFS=$lt_save_ifs if test "X$lt_pkg" = "X$lt_p"; then pic_mode=yes fi done IFS=$lt_save_ifs ;; esac], [pic_mode=m4_default([$1], [default])]) _LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl ])# _LT_WITH_PIC LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])]) LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])]) # Old name: AU_DEFUN([AC_LIBTOOL_PICMODE], [_LT_SET_OPTION([LT_INIT], [pic-only]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the 'pic-only' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_PICMODE], []) ## ----------------- ## ## LTDL_INIT Options ## ## ----------------- ## m4_define([_LTDL_MODE], []) LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive], [m4_define([_LTDL_MODE], [nonrecursive])]) LT_OPTION_DEFINE([LTDL_INIT], [recursive], [m4_define([_LTDL_MODE], [recursive])]) LT_OPTION_DEFINE([LTDL_INIT], [subproject], [m4_define([_LTDL_MODE], [subproject])]) m4_define([_LTDL_TYPE], []) LT_OPTION_DEFINE([LTDL_INIT], [installable], [m4_define([_LTDL_TYPE], [installable])]) LT_OPTION_DEFINE([LTDL_INIT], [convenience], [m4_define([_LTDL_TYPE], [convenience])]) ppp-2.5.0/m4/ltsugar.m40000644000175000017500000001045314214520133011477 00000000000000# ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*- # # Copyright (C) 2004-2005, 2007-2008, 2011-2019, 2021-2022 Free Software # Foundation, Inc. # Written by Gary V. Vaughan, 2004 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # serial 6 ltsugar.m4 # This is to help aclocal find these macros, as it can't see m4_define. AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])]) # lt_join(SEP, ARG1, [ARG2...]) # ----------------------------- # Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their # associated separator. # Needed until we can rely on m4_join from Autoconf 2.62, since all earlier # versions in m4sugar had bugs. m4_define([lt_join], [m4_if([$#], [1], [], [$#], [2], [[$2]], [m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])]) m4_define([_lt_join], [m4_if([$#$2], [2], [], [m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])]) # lt_car(LIST) # lt_cdr(LIST) # ------------ # Manipulate m4 lists. # These macros are necessary as long as will still need to support # Autoconf-2.59, which quotes differently. m4_define([lt_car], [[$1]]) m4_define([lt_cdr], [m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])], [$#], 1, [], [m4_dquote(m4_shift($@))])]) m4_define([lt_unquote], $1) # lt_append(MACRO-NAME, STRING, [SEPARATOR]) # ------------------------------------------ # Redefine MACRO-NAME to hold its former content plus 'SEPARATOR''STRING'. # Note that neither SEPARATOR nor STRING are expanded; they are appended # to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked). # No SEPARATOR is output if MACRO-NAME was previously undefined (different # than defined and empty). # # This macro is needed until we can rely on Autoconf 2.62, since earlier # versions of m4sugar mistakenly expanded SEPARATOR but not STRING. m4_define([lt_append], [m4_define([$1], m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])]) # lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...]) # ---------------------------------------------------------- # Produce a SEP delimited list of all paired combinations of elements of # PREFIX-LIST with SUFFIX1 through SUFFIXn. Each element of the list # has the form PREFIXmINFIXSUFFIXn. # Needed until we can rely on m4_combine added in Autoconf 2.62. m4_define([lt_combine], [m4_if(m4_eval([$# > 3]), [1], [m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl [[m4_foreach([_Lt_prefix], [$2], [m4_foreach([_Lt_suffix], ]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[, [_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])]) # lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ]) # ----------------------------------------------------------------------- # Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited # by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ. m4_define([lt_if_append_uniq], [m4_ifdef([$1], [m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1], [lt_append([$1], [$2], [$3])$4], [$5])], [lt_append([$1], [$2], [$3])$4])]) # lt_dict_add(DICT, KEY, VALUE) # ----------------------------- m4_define([lt_dict_add], [m4_define([$1($2)], [$3])]) # lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE) # -------------------------------------------- m4_define([lt_dict_add_subkey], [m4_define([$1($2:$3)], [$4])]) # lt_dict_fetch(DICT, KEY, [SUBKEY]) # ---------------------------------- m4_define([lt_dict_fetch], [m4_ifval([$3], m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]), m4_ifdef([$1($2)], [m4_defn([$1($2)])]))]) # lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE]) # ----------------------------------------------------------------- m4_define([lt_if_dict_fetch], [m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4], [$5], [$6])]) # lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...]) # -------------------------------------------------------------- m4_define([lt_dict_filter], [m4_if([$5], [], [], [lt_join(m4_quote(m4_default([$4], [[, ]])), lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]), [lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl ]) ppp-2.5.0/m4/ltversion.m40000644000175000017500000000131214214520272012041 00000000000000# ltversion.m4 -- version numbers -*- Autoconf -*- # # Copyright (C) 2004, 2011-2019, 2021-2022 Free Software Foundation, # Inc. # Written by Scott James Remnant, 2004 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # @configure_input@ # serial 4245 ltversion.m4 # This file is part of GNU Libtool m4_define([LT_PACKAGE_VERSION], [2.4.7]) m4_define([LT_PACKAGE_REVISION], [2.4.7]) AC_DEFUN([LTVERSION_VERSION], [macro_version='2.4.7' macro_revision='2.4.7' _LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?]) _LT_DECL(, macro_revision, 0) ]) ppp-2.5.0/m4/lt~obsolete.m40000644000175000017500000001400714214520133012367 00000000000000# lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*- # # Copyright (C) 2004-2005, 2007, 2009, 2011-2019, 2021-2022 Free # Software Foundation, Inc. # Written by Scott James Remnant, 2004. # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # serial 5 lt~obsolete.m4 # These exist entirely to fool aclocal when bootstrapping libtool. # # In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN), # which have later been changed to m4_define as they aren't part of the # exported API, or moved to Autoconf or Automake where they belong. # # The trouble is, aclocal is a bit thick. It'll see the old AC_DEFUN # in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us # using a macro with the same name in our local m4/libtool.m4 it'll # pull the old libtool.m4 in (it doesn't see our shiny new m4_define # and doesn't know about Autoconf macros at all.) # # So we provide this file, which has a silly filename so it's always # included after everything else. This provides aclocal with the # AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything # because those macros already exist, or will be overwritten later. # We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6. # # Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here. # Yes, that means every name once taken will need to remain here until # we give up compatibility with versions before 1.7, at which point # we need to keep only those names which we still refer to. # This is to help aclocal find these macros, as it can't see m4_define. AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])]) m4_ifndef([AC_LIBTOOL_LINKER_OPTION], [AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])]) m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP])]) m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])]) m4_ifndef([_LT_AC_SHELL_INIT], [AC_DEFUN([_LT_AC_SHELL_INIT])]) m4_ifndef([_LT_AC_SYS_LIBPATH_AIX], [AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])]) m4_ifndef([_LT_PROG_LTMAIN], [AC_DEFUN([_LT_PROG_LTMAIN])]) m4_ifndef([_LT_AC_TAGVAR], [AC_DEFUN([_LT_AC_TAGVAR])]) m4_ifndef([AC_LTDL_ENABLE_INSTALL], [AC_DEFUN([AC_LTDL_ENABLE_INSTALL])]) m4_ifndef([AC_LTDL_PREOPEN], [AC_DEFUN([AC_LTDL_PREOPEN])]) m4_ifndef([_LT_AC_SYS_COMPILER], [AC_DEFUN([_LT_AC_SYS_COMPILER])]) m4_ifndef([_LT_AC_LOCK], [AC_DEFUN([_LT_AC_LOCK])]) m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE], [AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])]) m4_ifndef([_LT_AC_TRY_DLOPEN_SELF], [AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])]) m4_ifndef([AC_LIBTOOL_PROG_CC_C_O], [AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])]) m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])]) m4_ifndef([AC_LIBTOOL_OBJDIR], [AC_DEFUN([AC_LIBTOOL_OBJDIR])]) m4_ifndef([AC_LTDL_OBJDIR], [AC_DEFUN([AC_LTDL_OBJDIR])]) m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])]) m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP], [AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])]) m4_ifndef([AC_PATH_MAGIC], [AC_DEFUN([AC_PATH_MAGIC])]) m4_ifndef([AC_PROG_LD_GNU], [AC_DEFUN([AC_PROG_LD_GNU])]) m4_ifndef([AC_PROG_LD_RELOAD_FLAG], [AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])]) m4_ifndef([AC_DEPLIBS_CHECK_METHOD], [AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])]) m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])]) m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])]) m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])]) m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS], [AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])]) m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP], [AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])]) m4_ifndef([LT_AC_PROG_EGREP], [AC_DEFUN([LT_AC_PROG_EGREP])]) m4_ifndef([LT_AC_PROG_SED], [AC_DEFUN([LT_AC_PROG_SED])]) m4_ifndef([_LT_CC_BASENAME], [AC_DEFUN([_LT_CC_BASENAME])]) m4_ifndef([_LT_COMPILER_BOILERPLATE], [AC_DEFUN([_LT_COMPILER_BOILERPLATE])]) m4_ifndef([_LT_LINKER_BOILERPLATE], [AC_DEFUN([_LT_LINKER_BOILERPLATE])]) m4_ifndef([_AC_PROG_LIBTOOL], [AC_DEFUN([_AC_PROG_LIBTOOL])]) m4_ifndef([AC_LIBTOOL_SETUP], [AC_DEFUN([AC_LIBTOOL_SETUP])]) m4_ifndef([_LT_AC_CHECK_DLFCN], [AC_DEFUN([_LT_AC_CHECK_DLFCN])]) m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER], [AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])]) m4_ifndef([_LT_AC_TAGCONFIG], [AC_DEFUN([_LT_AC_TAGCONFIG])]) m4_ifndef([AC_DISABLE_FAST_INSTALL], [AC_DEFUN([AC_DISABLE_FAST_INSTALL])]) m4_ifndef([_LT_AC_LANG_CXX], [AC_DEFUN([_LT_AC_LANG_CXX])]) m4_ifndef([_LT_AC_LANG_F77], [AC_DEFUN([_LT_AC_LANG_F77])]) m4_ifndef([_LT_AC_LANG_GCJ], [AC_DEFUN([_LT_AC_LANG_GCJ])]) m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])]) m4_ifndef([_LT_AC_LANG_C_CONFIG], [AC_DEFUN([_LT_AC_LANG_C_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])]) m4_ifndef([_LT_AC_LANG_CXX_CONFIG], [AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])]) m4_ifndef([_LT_AC_LANG_F77_CONFIG], [AC_DEFUN([_LT_AC_LANG_F77_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])]) m4_ifndef([_LT_AC_LANG_GCJ_CONFIG], [AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])]) m4_ifndef([_LT_AC_LANG_RC_CONFIG], [AC_DEFUN([_LT_AC_LANG_RC_CONFIG])]) m4_ifndef([AC_LIBTOOL_CONFIG], [AC_DEFUN([AC_LIBTOOL_CONFIG])]) m4_ifndef([_LT_AC_FILE_LTDLL_C], [AC_DEFUN([_LT_AC_FILE_LTDLL_C])]) m4_ifndef([_LT_REQUIRED_DARWIN_CHECKS], [AC_DEFUN([_LT_REQUIRED_DARWIN_CHECKS])]) m4_ifndef([_LT_AC_PROG_CXXCPP], [AC_DEFUN([_LT_AC_PROG_CXXCPP])]) m4_ifndef([_LT_PREPARE_SED_QUOTE_VARS], [AC_DEFUN([_LT_PREPARE_SED_QUOTE_VARS])]) m4_ifndef([_LT_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_PROG_ECHO_BACKSLASH])]) m4_ifndef([_LT_PROG_F77], [AC_DEFUN([_LT_PROG_F77])]) m4_ifndef([_LT_PROG_FC], [AC_DEFUN([_LT_PROG_FC])]) m4_ifndef([_LT_PROG_CXX], [AC_DEFUN([_LT_PROG_CXX])]) ppp-2.5.0/m4/pkg.m40000664000175000017500000002400714076444143010615 00000000000000# pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*- # serial 12 (pkg-config-0.29.2) dnl Copyright © 2004 Scott James Remnant . dnl Copyright © 2012-2015 Dan Nicholson dnl dnl This program is free software; you can redistribute it and/or modify dnl it under the terms of the GNU General Public License as published by dnl the Free Software Foundation; either version 2 of the License, or dnl (at your option) any later version. dnl dnl This program is distributed in the hope that it will be useful, but dnl WITHOUT ANY WARRANTY; without even the implied warranty of dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU dnl General Public License for more details. dnl dnl You should have received a copy of the GNU General Public License dnl along with this program; if not, write to the Free Software dnl Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA dnl 02111-1307, USA. dnl dnl As a special exception to the GNU General Public License, if you dnl distribute this file as part of a program that contains a dnl configuration script generated by Autoconf, you may include it under dnl the same distribution terms that you use for the rest of that dnl program. dnl PKG_PREREQ(MIN-VERSION) dnl ----------------------- dnl Since: 0.29 dnl dnl Verify that the version of the pkg-config macros are at least dnl MIN-VERSION. Unlike PKG_PROG_PKG_CONFIG, which checks the user's dnl installed version of pkg-config, this checks the developer's version dnl of pkg.m4 when generating configure. dnl dnl To ensure that this macro is defined, also add: dnl m4_ifndef([PKG_PREREQ], dnl [m4_fatal([must install pkg-config 0.29 or later before running autoconf/autogen])]) dnl dnl See the "Since" comment for each macro you use to see what version dnl of the macros you require. m4_defun([PKG_PREREQ], [m4_define([PKG_MACROS_VERSION], [0.29.2]) m4_if(m4_version_compare(PKG_MACROS_VERSION, [$1]), -1, [m4_fatal([pkg.m4 version $1 or higher is required but ]PKG_MACROS_VERSION[ found])]) ])dnl PKG_PREREQ dnl PKG_PROG_PKG_CONFIG([MIN-VERSION]) dnl ---------------------------------- dnl Since: 0.16 dnl dnl Search for the pkg-config tool and set the PKG_CONFIG variable to dnl first found in the path. Checks that the version of pkg-config found dnl is at least MIN-VERSION. If MIN-VERSION is not specified, 0.9.0 is dnl used since that's the first version where most current features of dnl pkg-config existed. AC_DEFUN([PKG_PROG_PKG_CONFIG], [m4_pattern_forbid([^_?PKG_[A-Z_]+$]) m4_pattern_allow([^PKG_CONFIG(_(PATH|LIBDIR|SYSROOT_DIR|ALLOW_SYSTEM_(CFLAGS|LIBS)))?$]) m4_pattern_allow([^PKG_CONFIG_(DISABLE_UNINSTALLED|TOP_BUILD_DIR|DEBUG_SPEW)$]) AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility]) AC_ARG_VAR([PKG_CONFIG_PATH], [directories to add to pkg-config's search path]) AC_ARG_VAR([PKG_CONFIG_LIBDIR], [path overriding pkg-config's built-in search path]) if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then AC_PATH_TOOL([PKG_CONFIG], [pkg-config]) fi if test -n "$PKG_CONFIG"; then _pkg_min_version=m4_default([$1], [0.9.0]) AC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version]) if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) PKG_CONFIG="" fi fi[]dnl ])dnl PKG_PROG_PKG_CONFIG dnl PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) dnl ------------------------------------------------------------------- dnl Since: 0.18 dnl dnl Check to see whether a particular set of modules exists. Similar to dnl PKG_CHECK_MODULES(), but does not set variables or print errors. dnl dnl Please remember that m4 expands AC_REQUIRE([PKG_PROG_PKG_CONFIG]) dnl only at the first occurence in configure.ac, so if the first place dnl it's called might be skipped (such as if it is within an "if", you dnl have to call PKG_CHECK_EXISTS manually AC_DEFUN([PKG_CHECK_EXISTS], [AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl if test -n "$PKG_CONFIG" && \ AC_RUN_LOG([$PKG_CONFIG --exists --print-errors "$1"]); then m4_default([$2], [:]) m4_ifvaln([$3], [else $3])dnl fi]) dnl _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES]) dnl --------------------------------------------- dnl Internal wrapper calling pkg-config via PKG_CONFIG and setting dnl pkg_failed based on the result. m4_define([_PKG_CONFIG], [if test -n "$$1"; then pkg_cv_[]$1="$$1" elif test -n "$PKG_CONFIG"; then PKG_CHECK_EXISTS([$3], [pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes ], [pkg_failed=yes]) else pkg_failed=untried fi[]dnl ])dnl _PKG_CONFIG dnl _PKG_SHORT_ERRORS_SUPPORTED dnl --------------------------- dnl Internal check to see if pkg-config supports short errors. AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED], [AC_REQUIRE([PKG_PROG_PKG_CONFIG]) if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi[]dnl ])dnl _PKG_SHORT_ERRORS_SUPPORTED dnl PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND], dnl [ACTION-IF-NOT-FOUND]) dnl -------------------------------------------------------------- dnl Since: 0.4.0 dnl dnl Note that if there is a possibility the first call to dnl PKG_CHECK_MODULES might not happen, you should be sure to include an dnl explicit call to PKG_PROG_PKG_CONFIG in your configure.ac AC_DEFUN([PKG_CHECK_MODULES], [AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl pkg_failed=no AC_MSG_CHECKING([for $2]) _PKG_CONFIG([$1][_CFLAGS], [cflags], [$2]) _PKG_CONFIG([$1][_LIBS], [libs], [$2]) m4_define([_PKG_TEXT], [Alternatively, you may set the environment variables $1[]_CFLAGS and $1[]_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details.]) if test $pkg_failed = yes; then AC_MSG_RESULT([no]) _PKG_SHORT_ERRORS_SUPPORTED if test $_pkg_short_errors_supported = yes; then $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$2" 2>&1` else $1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$2" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD m4_default([$4], [AC_MSG_ERROR( [Package requirements ($2) were not met: $$1_PKG_ERRORS Consider adjusting the PKG_CONFIG_PATH environment variable if you installed software in a non-standard prefix. _PKG_TEXT])[]dnl ]) elif test $pkg_failed = untried; then AC_MSG_RESULT([no]) m4_default([$4], [AC_MSG_FAILURE( [The pkg-config script could not be found or is too old. Make sure it is in your PATH or set the PKG_CONFIG environment variable to the full path to pkg-config. _PKG_TEXT To get pkg-config, see .])[]dnl ]) else $1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS $1[]_LIBS=$pkg_cv_[]$1[]_LIBS AC_MSG_RESULT([yes]) $3 fi[]dnl ])dnl PKG_CHECK_MODULES dnl PKG_CHECK_MODULES_STATIC(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND], dnl [ACTION-IF-NOT-FOUND]) dnl --------------------------------------------------------------------- dnl Since: 0.29 dnl dnl Checks for existence of MODULES and gathers its build flags with dnl static libraries enabled. Sets VARIABLE-PREFIX_CFLAGS from --cflags dnl and VARIABLE-PREFIX_LIBS from --libs. dnl dnl Note that if there is a possibility the first call to dnl PKG_CHECK_MODULES_STATIC might not happen, you should be sure to dnl include an explicit call to PKG_PROG_PKG_CONFIG in your dnl configure.ac. AC_DEFUN([PKG_CHECK_MODULES_STATIC], [AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl _save_PKG_CONFIG=$PKG_CONFIG PKG_CONFIG="$PKG_CONFIG --static" PKG_CHECK_MODULES($@) PKG_CONFIG=$_save_PKG_CONFIG[]dnl ])dnl PKG_CHECK_MODULES_STATIC dnl PKG_INSTALLDIR([DIRECTORY]) dnl ------------------------- dnl Since: 0.27 dnl dnl Substitutes the variable pkgconfigdir as the location where a module dnl should install pkg-config .pc files. By default the directory is dnl $libdir/pkgconfig, but the default can be changed by passing dnl DIRECTORY. The user can override through the --with-pkgconfigdir dnl parameter. AC_DEFUN([PKG_INSTALLDIR], [m4_pushdef([pkg_default], [m4_default([$1], ['${libdir}/pkgconfig'])]) m4_pushdef([pkg_description], [pkg-config installation directory @<:@]pkg_default[@:>@]) AC_ARG_WITH([pkgconfigdir], [AS_HELP_STRING([--with-pkgconfigdir], pkg_description)],, [with_pkgconfigdir=]pkg_default) AC_SUBST([pkgconfigdir], [$with_pkgconfigdir]) m4_popdef([pkg_default]) m4_popdef([pkg_description]) ])dnl PKG_INSTALLDIR dnl PKG_NOARCH_INSTALLDIR([DIRECTORY]) dnl -------------------------------- dnl Since: 0.27 dnl dnl Substitutes the variable noarch_pkgconfigdir as the location where a dnl module should install arch-independent pkg-config .pc files. By dnl default the directory is $datadir/pkgconfig, but the default can be dnl changed by passing DIRECTORY. The user can override through the dnl --with-noarch-pkgconfigdir parameter. AC_DEFUN([PKG_NOARCH_INSTALLDIR], [m4_pushdef([pkg_default], [m4_default([$1], ['${datadir}/pkgconfig'])]) m4_pushdef([pkg_description], [pkg-config arch-independent installation directory @<:@]pkg_default[@:>@]) AC_ARG_WITH([noarch-pkgconfigdir], [AS_HELP_STRING([--with-noarch-pkgconfigdir], pkg_description)],, [with_noarch_pkgconfigdir=]pkg_default) AC_SUBST([noarch_pkgconfigdir], [$with_noarch_pkgconfigdir]) m4_popdef([pkg_default]) m4_popdef([pkg_description]) ])dnl PKG_NOARCH_INSTALLDIR dnl PKG_CHECK_VAR(VARIABLE, MODULE, CONFIG-VARIABLE, dnl [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) dnl ------------------------------------------- dnl Since: 0.28 dnl dnl Retrieves the value of the pkg-config variable for the given module. AC_DEFUN([PKG_CHECK_VAR], [AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl AC_ARG_VAR([$1], [value of $3 for $2, overriding pkg-config])dnl _PKG_CONFIG([$1], [variable="][$3]["], [$2]) AS_VAR_COPY([$1], [pkg_cv_][$1]) AS_VAR_IF([$1], [""], [$5], [$4])dnl ])dnl PKG_CHECK_VAR ppp-2.5.0/solaris/0000755000175000017500000000000014412736275011005 500000000000000ppp-2.5.0/solaris/Makedefs0000644000175000017500000000031410140607006012344 00000000000000# # defines common to several Makefiles # INSTALL= /usr/sbin/install BINDIR = @DESTDIR@/bin MANDIR = @DESTDIR@/man ETCDIR = @SYSCONF@/ppp CC = /opt/SUNWspro/bin/cc COPTS = -O -Xa LD = /usr/ccs/bin/ld ppp-2.5.0/solaris/Makedefs.gcc0000644000175000017500000000027010140612351013077 00000000000000# # defines common to several Makefiles # INSTALL= /usr/sbin/install BINDIR = @DESTDIR@/bin MANDIR = @DESTDIR@/man ETCDIR = @SYSCONF@/ppp CC = gcc COPTS = -O2 LD = /usr/ccs/bin/ld ppp-2.5.0/solaris/Makedefs.sol20000644000175000017500000000402307536353402013240 00000000000000# # Generic make definitions for Solaris 2 # # $Id: Makedefs.sol2,v 1.2 2002/09/07 05:15:25 carlsonj Exp $ # include ../Makedefs.com CPPFLAGS = -D_KERNEL -DSVR4 -DSOL2 -DPRIOQ -DDEBUG -I../include CFLAGS = $(CPPFLAGS) $(COPTS) # lint-specific variables LINT = lint LINT_OPT_32 = LINT_OPT_64 = -Xarch=v9 -errchk=longptr64 LINT_32 = LINT_32 += -erroff=E_BAD_PTR_CAST_ALIGN LINT_32 += -erroff=E_SUPPRESSION_DIRECTIVE_UNUSED LINT_32 += -erroff=E_SUSPICIOUS_COMPARISON LINT_32 += -erroff=E_CAST_UINT_TO_SIGNED_INT LINT_32 += -erroff=E_PASS_UINT_TO_SIGNED_INT LINT_32 += -erroff=E_INVALID_ANNOTATION_NAME LINT_32 += -erroff=E_FUNC_ARG_UNUSED # This might be needed, but zlib.c and vjcompress.c will squawk # when not ignored LINT_32 += -erroff=E_CASE_FALLTHRU LINT_32 += -erroff=E_RET_INT_IMPLICITLY LINT_32 += -erroff=E_FUNC_NO_RET_VAL # Some STREAMS macros will be noisy too when this isn't ignored LINT_32 += -erroff=E_CONSTANT_CONDITION LINT_32 += -erroff=E_CONST_EXPR # Extra noise suppressant for 64-bit EXTRA_OFF = EXTRA_OFF += -erroff=E_CAST_INT_TO_SMALL_INT EXTRA_OFF += -erroff=E_CAST_INT_CONST_TO_SMALL_INT EXTRA_OFF += -erroff=E_CAST_TO_PTR_FROM_INT EXTRA_OFF += -erroff=E_ASSIGN_INT_TO_SMALL_INT EXTRA_OFF += -erroff=E_ASSIGN_INT_FROM_BIG_CONST EXTRA_OFF += -erroff=E_CONST_PROMOTED_UNSIGNED_LL EXTRA_OFF += -erroff=E_CONST_PROMOTED_LONG_LONG EXTRA_OFF += -erroff=E_CONST_TRUNCATED_BY_ASSIGN EXTRA_OFF += -erroff=E_PASS_INT_FROM_BIG_CONST EXTRA_OFF += -erroff=E_COMP_INT_WITH_LARGE_INT EXTRA_OFF += -erroff=E_ASSIGN_UINT_TO_SIGNED_INT EXTRA_OFF += -erroff=E_ASSIGN_NARROW_CONV EXTRA_OFF += -erroff=E_PASS_INT_TO_SMALL_INT EXTRA_OFF += -erroff=E_PTR_CONV_LOSES_BITS LINT_64 = $(LINT_32) LINT_64 += $(EXTRA_OFF) LINTFLAGS64 = -Xa -nsxmuF -errtags=yes $(LINT_OPT_64) $(LINT_64) LINT64 = $(LINT) -c $(LINTFLAGS64) $(CPPFLAGS) LINTFLAGS32 = -Xa -nsxmuF -errtags=yes $(LINT_OPT_32) $(LINT_32) LINT32 = $(LINT) -c $(LINTFLAGS32) $(CPPFLAGS) ppp-2.5.0/solaris/Makefile.sol20000644000175000017500000000304010146065312013223 00000000000000# # Makefile for STREAMS modules for Solaris 2. # # $Id: Makefile.sol2,v 1.3 2004/11/15 00:57:54 carlsonj Exp $ # include Makedefs.sol2 COPTS += -xO2 -xspace -W0,-Lt COMP_OBJS = ppp_comp.o bsd-comp.o deflate.o zlib.o vjcompress.o \ ppp_comp_mod.o all: ppp ppp_ahdl ppp_comp ppp: ppp.o ppp_mod.o $(LD) -r -o $@ ppp.o ppp_mod.o chmod +x $@ ppp_ahdl: ppp_ahdlc.o ppp_ahdlc_mod.o $(LD) -r -o $@ ppp_ahdlc.o ppp_ahdlc_mod.o chmod +x $@ ppp_comp: $(COMP_OBJS) $(LD) -r -o $@ $(COMP_OBJS) chmod +x $@ bsd-comp.o: ../modules/bsd-comp.c $(CC) $(CFLAGS) -c $? deflate.o: ../modules/deflate.c $(CC) $(CFLAGS) -c $? ppp.o: ppp.c $(CC) $(CFLAGS) -c $? ppp_mod.o: ppp_mod.c $(CC) $(CFLAGS) -c $? ppp_ahdlc_mod.o: ppp_ahdlc_mod.c $(CC) $(CFLAGS) -c $? ppp_ahdlc.o: ppp_ahdlc.c $(CC) $(CFLAGS) -c $? ppp_comp.o: ppp_comp.c $(CC) $(CFLAGS) -c $? ppp_comp_mod.o: ppp_comp_mod.c $(CC) $(CFLAGS) -c $? vjcompress.o: ../modules/vjcompress.c $(CC) $(CFLAGS) -c $? zlib.o: ../common/zlib.c $(CC) $(CFLAGS) -c $? install: /usr/sbin/modunload -i 0 cp ppp ppp.conf /kernel/drv cp ppp_comp ppp_ahdl /kernel/strmod if grep clone:ppp /etc/minor_perm; then :; else \ echo clone:ppp 0644 root sys >>/etc/minor_perm; fi /usr/sbin/rem_drv ppp 2>/dev/null || true /usr/sbin/modunload -i 0 /usr/sbin/add_drv ppp SRCS = ppp.c ppp_mod.c ppp_ahdlc.c ppp_ahdlc_mod.c \ ppp_comp.c ../modules/bsd-comp.c ../modules/deflate.c \ ../common/zlib.c ../modules/vjcompress.c ppp_comp_mod.c lint: $(LINT32) $(SRCS) clean: rm -f ppp ppp_comp ppp_ahdl *.o *~ core rm -f *.ln ppp-2.5.0/solaris/Makefile.sol2-640000644000175000017500000000500210146065312013452 00000000000000# # Makefile for 64-bit STREAMS modules for Solaris 2. # # $Id: Makefile.sol2-64,v 1.3 2004/11/15 00:57:54 carlsonj Exp $ # include Makedefs.sol2 # Sun's cc flag for LP64 compilation / linkage COPTS += -xchip=ultra -xarch=v9 -Wc,-xcode=abs32 -Wc,-Qiselect-regsym=0 -xO3 -xspace -W0,-Lt # subdirectory where 64-bit objects / binaries will be placed LP64DIR = sparcv9 # Name of legacy Makefile (for 32-bit binaries) STD_MAKE = Makefile.sol2 COMP_OBJS = $(LP64DIR)/ppp_comp.o $(LP64DIR)/bsd-comp.o \ $(LP64DIR)/deflate.o $(LP64DIR)/zlib.o $(LP64DIR)/vjcompress.o \ $(LP64DIR)/ppp_comp_mod.o all: std_objs $(LP64DIR) ppp ppp_ahdl ppp_comp std_objs: $(MAKE) -f $(STD_MAKE) all ppp: $(LP64DIR)/ppp.o $(LP64DIR)/ppp_mod.o $(LD) -r -o $(LP64DIR)/$@ $(LP64DIR)/ppp.o $(LP64DIR)/ppp_mod.o chmod +x $(LP64DIR)/$@ ppp_ahdl: $(LP64DIR)/ppp_ahdlc.o $(LP64DIR)/ppp_ahdlc_mod.o $(LD) -r -o $(LP64DIR)/$@ $(LP64DIR)/ppp_ahdlc.o \ $(LP64DIR)/ppp_ahdlc_mod.o chmod +x $(LP64DIR)/$@ ppp_comp: $(COMP_OBJS) $(LD) -r -o $(LP64DIR)/$@ $(COMP_OBJS) chmod +x $(LP64DIR)/$@ $(LP64DIR)/bsd-comp.o: ../modules/bsd-comp.c $(CC) $(CFLAGS) -c $? -o $@ $(LP64DIR)/deflate.o: ../modules/deflate.c $(CC) $(CFLAGS) -c $? -o $@ $(LP64DIR)/ppp.o: ppp.c $(CC) $(CFLAGS) -c $? -o $@ $(LP64DIR)/ppp_mod.o: ppp_mod.c $(CC) $(CFLAGS) -c $? -o $@ $(LP64DIR)/ppp_ahdlc_mod.o: ppp_ahdlc_mod.c $(CC) $(CFLAGS) -c $? -o $@ $(LP64DIR)/ppp_ahdlc.o: ppp_ahdlc.c $(CC) $(CFLAGS) -c $? -o $@ $(LP64DIR)/ppp_comp.o: ppp_comp.c $(CC) $(CFLAGS) -c $? -o $@ $(LP64DIR)/ppp_comp_mod.o: ppp_comp_mod.c $(CC) $(CFLAGS) -c $? -o $@ $(LP64DIR)/vjcompress.o: ../modules/vjcompress.c $(CC) $(CFLAGS) -c $? -o $@ $(LP64DIR)/zlib.o: ../common/zlib.c $(CC) $(CFLAGS) -c $? -o $@ $(LP64DIR): mkdir -m 755 -p $@ install: /usr/sbin/modunload -i 0 cp ppp ppp.conf /kernel/drv cp ppp_comp ppp_ahdl /kernel/strmod cp $(LP64DIR)/ppp /kernel/drv/$(LP64DIR) cp $(LP64DIR)/ppp_comp $(LP64DIR)/ppp_ahdl /kernel/strmod/$(LP64DIR) if grep clone:ppp /etc/minor_perm; then :; else \ echo clone:ppp 0644 root sys >>/etc/minor_perm; fi /usr/sbin/rem_drv ppp 2>/dev/null || true /usr/sbin/modunload -i 0 /usr/sbin/add_drv ppp SRCS = ppp.c ppp_mod.c ppp_ahdlc.c ppp_ahdlc_mod.c \ ppp_comp.c ../modules/bsd-comp.c ../modules/deflate.c \ ../common/zlib.c ../modules/vjcompress.c ppp_comp_mod.c lint: $(LINT64) $(SRCS) lint-32: $(LINT32) $(SRCS) clean: $(MAKE) -f $(STD_MAKE) clean rm -f $(LP64DIR)/ppp $(LP64DIR)/ppp_comp $(LP64DIR)/ppp_ahdl $(LP64DIR)/*.o $(LP64DIR)/*~ $(LP64DIR)/core ppp-2.5.0/solaris/Makefile.sol2-64x0000644000175000017500000000500712261164655013661 00000000000000# # Makefile for 64-bit STREAMS modules for Solaris 2 on x64 # # $Id: Makefile.sol2-64x,v 1.1 2005/06/26 23:53:17 carlsonj Exp $ # include Makedefs.sol2 # Sun's cc flag for LP64 compilation / linkage COPTS += -errwarn -xtarget=opteron -m64 -xmodel=kernel \ -Ui386 -U__i386 -D__amd64 -xO2 # subdirectory where 64-bit objects / binaries will be placed LP64DIR = amd64 # Name of legacy Makefile (for 32-bit binaries) STD_MAKE = Makefile.sol2 COMP_OBJS = $(LP64DIR)/ppp_comp.o $(LP64DIR)/bsd-comp.o \ $(LP64DIR)/deflate.o $(LP64DIR)/zlib.o $(LP64DIR)/vjcompress.o \ $(LP64DIR)/ppp_comp_mod.o all: std_objs $(LP64DIR) ppp ppp_ahdl ppp_comp std_objs: $(MAKE) -f $(STD_MAKE) all ppp: $(LP64DIR)/ppp.o $(LP64DIR)/ppp_mod.o $(LD) -r -o $(LP64DIR)/$@ $(LP64DIR)/ppp.o $(LP64DIR)/ppp_mod.o chmod +x $(LP64DIR)/$@ ppp_ahdl: $(LP64DIR)/ppp_ahdlc.o $(LP64DIR)/ppp_ahdlc_mod.o $(LD) -r -o $(LP64DIR)/$@ $(LP64DIR)/ppp_ahdlc.o \ $(LP64DIR)/ppp_ahdlc_mod.o chmod +x $(LP64DIR)/$@ ppp_comp: $(COMP_OBJS) $(LD) -r -o $(LP64DIR)/$@ $(COMP_OBJS) chmod +x $(LP64DIR)/$@ $(LP64DIR)/bsd-comp.o: ../modules/bsd-comp.c $(CC) $(CFLAGS) -c $? -o $@ $(LP64DIR)/deflate.o: ../modules/deflate.c $(CC) $(CFLAGS) -c $? -o $@ $(LP64DIR)/ppp.o: ppp.c $(CC) $(CFLAGS) -c $? -o $@ $(LP64DIR)/ppp_mod.o: ppp_mod.c $(CC) $(CFLAGS) -c $? -o $@ $(LP64DIR)/ppp_ahdlc_mod.o: ppp_ahdlc_mod.c $(CC) $(CFLAGS) -c $? -o $@ $(LP64DIR)/ppp_ahdlc.o: ppp_ahdlc.c $(CC) $(CFLAGS) -c $? -o $@ $(LP64DIR)/ppp_comp.o: ppp_comp.c $(CC) $(CFLAGS) -c $? -o $@ $(LP64DIR)/ppp_comp_mod.o: ppp_comp_mod.c $(CC) $(CFLAGS) -c $? -o $@ $(LP64DIR)/vjcompress.o: ../modules/vjcompress.c $(CC) $(CFLAGS) -c $? -o $@ $(LP64DIR)/zlib.o: ../common/zlib.c $(CC) $(CFLAGS) -c $? -o $@ $(LP64DIR): mkdir -m 755 -p $@ install: /usr/sbin/modunload -i 0 cp ppp ppp.conf /kernel/drv cp ppp_comp ppp_ahdl /kernel/strmod cp $(LP64DIR)/ppp /kernel/drv/$(LP64DIR) cp $(LP64DIR)/ppp_comp $(LP64DIR)/ppp_ahdl /kernel/strmod/$(LP64DIR) if grep clone:ppp /etc/minor_perm; then :; else \ echo clone:ppp 0644 root sys >>/etc/minor_perm; fi /usr/sbin/rem_drv ppp 2>/dev/null || true /usr/sbin/modunload -i 0 /usr/sbin/add_drv ppp SRCS = ppp.c ppp_mod.c ppp_ahdlc.c ppp_ahdlc_mod.c \ ppp_comp.c ../modules/bsd-comp.c ../modules/deflate.c \ ../common/zlib.c ../modules/vjcompress.c ppp_comp_mod.c lint: $(LINT64) $(SRCS) lint-32: $(LINT32) $(SRCS) clean: $(MAKE) -f $(STD_MAKE) clean rm -f $(LP64DIR)/ppp $(LP64DIR)/ppp_comp $(LP64DIR)/ppp_ahdl $(LP64DIR)/*.o $(LP64DIR)/*~ $(LP64DIR)/core ppp-2.5.0/solaris/Makefile.sol2gcc0000644000175000017500000000303310146065312013702 00000000000000# # Makefile for STREAMS modules for Solaris 2. # # $Id: Makefile.sol2gcc,v 1.4 2004/11/15 00:57:54 carlsonj Exp $ # include Makedefs.sol2 COPTS += -fno-builtin COMP_OBJS = ppp_comp.o bsd-comp.o deflate.o zlib.o vjcompress.o \ ppp_comp_mod.o all: ppp ppp_ahdl ppp_comp ppp: ppp.o ppp_mod.o $(LD) -r -o $@ ppp.o ppp_mod.o chmod +x $@ ppp_ahdl: ppp_ahdlc.o ppp_ahdlc_mod.o $(LD) -r -o $@ ppp_ahdlc.o ppp_ahdlc_mod.o chmod +x $@ ppp_comp: $(COMP_OBJS) $(LD) -r -o $@ $(COMP_OBJS) chmod +x $@ bsd-comp.o: ../modules/bsd-comp.c $(CC) $(CFLAGS) -c $? deflate.o: ../modules/deflate.c $(CC) $(CFLAGS) -c $? ppp.o: ppp.c $(CC) $(CFLAGS) -c $? ppp_mod.o: ppp_mod.c $(CC) $(CFLAGS) -c $? ppp_ahdlc_mod.o: ppp_ahdlc_mod.c $(CC) $(CFLAGS) -c $? ppp_ahdlc.o: ppp_ahdlc.c $(CC) $(CFLAGS) -c $? ppp_comp.o: ppp_comp.c $(CC) $(CFLAGS) -c $? ppp_comp_mod.o: ppp_comp_mod.c $(CC) $(CFLAGS) -c $? vjcompress.o: ../modules/vjcompress.c $(CC) $(CFLAGS) -c $? zlib.o: ../common/zlib.c $(CC) $(CFLAGS) -c $? install: /usr/sbin/modunload -i 0 cp ppp ppp.conf /kernel/drv cp ppp_comp ppp_ahdl /kernel/strmod if grep clone:ppp /etc/minor_perm; then :; else \ echo clone:ppp 0644 root sys >>/etc/minor_perm; fi /usr/sbin/rem_drv ppp 2>/dev/null || true /usr/sbin/modunload -i 0 /usr/sbin/add_drv ppp SRCS = ppp.c ppp_mod.c ppp_ahdlc.c ppp_ahdlc_mod.c \ ppp_comp.c ../modules/bsd-comp.c ../modules/deflate.c \ ../common/zlib.c ../modules/vjcompress.c ppp_comp_mod.c lint: $(LINT32) $(SRCS) clean: rm -f ppp ppp_comp ppp_ahdl *.o *~ core rm -f *.ln ppp-2.5.0/solaris/Makefile.sol2gcc-640000644000175000017500000000476010146065312014141 00000000000000# # Makefile for 64-bit STREAMS modules for Solaris 2. # # $Id: Makefile.sol2gcc-64,v 1.3 2004/11/15 00:57:54 carlsonj Exp $ # include Makedefs.sol2 # gcc flags for LP64 compilation / linkage COPTS += -mcpu=v9 -m64 -mcmodel=medlow -mstack-bias -fno-builtin # subdirectory where 64-bit objects / binaries will be placed LP64DIR = sparcv9 # Name of legacy Makefile (for 32-bit binaries) STD_MAKE = Makefile.sol2gcc COMP_OBJS = $(LP64DIR)/ppp_comp.o $(LP64DIR)/bsd-comp.o \ $(LP64DIR)/deflate.o $(LP64DIR)/zlib.o $(LP64DIR)/vjcompress.o \ $(LP64DIR)/ppp_comp_mod.o all: std_objs $(LP64DIR) ppp ppp_ahdl ppp_comp std_objs: $(MAKE) -f $(STD_MAKE) all ppp: $(LP64DIR)/ppp.o $(LP64DIR)/ppp_mod.o $(LD) -r -o $(LP64DIR)/$@ $(LP64DIR)/ppp.o $(LP64DIR)/ppp_mod.o chmod +x $(LP64DIR)/$@ ppp_ahdl: $(LP64DIR)/ppp_ahdlc.o $(LP64DIR)/ppp_ahdlc_mod.o $(LD) -r -o $(LP64DIR)/$@ $(LP64DIR)/ppp_ahdlc.o \ $(LP64DIR)/ppp_ahdlc_mod.o chmod +x $(LP64DIR)/$@ ppp_comp: $(COMP_OBJS) $(LD) -r -o $(LP64DIR)/$@ $(COMP_OBJS) chmod +x $(LP64DIR)/$@ $(LP64DIR)/bsd-comp.o: ../modules/bsd-comp.c $(CC) $(CFLAGS) -c $? -o $@ $(LP64DIR)/deflate.o: ../modules/deflate.c $(CC) $(CFLAGS) -c $? -o $@ $(LP64DIR)/ppp.o: ppp.c $(CC) $(CFLAGS) -c $? -o $@ $(LP64DIR)/ppp_mod.o: ppp_mod.c $(CC) $(CFLAGS) -c $? -o $@ $(LP64DIR)/ppp_ahdlc_mod.o: ppp_ahdlc_mod.c $(CC) $(CFLAGS) -c $? -o $@ $(LP64DIR)/ppp_ahdlc.o: ppp_ahdlc.c $(CC) $(CFLAGS) -c $? -o $@ $(LP64DIR)/ppp_comp.o: ppp_comp.c $(CC) $(CFLAGS) -c $? -o $@ $(LP64DIR)/ppp_comp_mod.o: ppp_comp_mod.c $(CC) $(CFLAGS) -c $? -o $@ $(LP64DIR)/vjcompress.o: ../modules/vjcompress.c $(CC) $(CFLAGS) -c $? -o $@ $(LP64DIR)/zlib.o: ../common/zlib.c $(CC) $(CFLAGS) -c $? -o $@ $(LP64DIR): mkdir -m 755 -p $@ install: /usr/sbin/modunload -i 0 cp ppp ppp.conf /kernel/drv cp ppp_comp ppp_ahdl /kernel/strmod cp $(LP64DIR)/ppp /kernel/drv/$(LP64DIR) cp $(LP64DIR)/ppp_comp $(LP64DIR)/ppp_ahdl /kernel/strmod/$(LP64DIR) if grep clone:ppp /etc/minor_perm; then :; else \ echo clone:ppp 0644 root sys >>/etc/minor_perm; fi /usr/sbin/rem_drv ppp 2>/dev/null || true /usr/sbin/modunload -i 0 /usr/sbin/add_drv ppp SRCS = ppp.c ppp_mod.c ppp_ahdlc.c ppp_ahdlc_mod.c \ ppp_comp.c ../modules/bsd-comp.c ../modules/deflate.c \ ../common/zlib.c ../modules/vjcompress.c ppp_comp_mod.c lint: $(LINT64) $(SRCS) lint-32: $(LINT32) $(SRCS) clean: $(MAKE) -f $(STD_MAKE) clean rm -f $(LP64DIR)/ppp $(LP64DIR)/ppp_comp $(LP64DIR)/ppp_ahdl $(LP64DIR)/*.o $(LP64DIR)/*~ $(LP64DIR)/core ppp-2.5.0/solaris/Makefile.sol2gcc-64x0000644000175000017500000000550410257637755014351 00000000000000# # Makefile for 64-bit STREAMS modules for Solaris 2 on x64 with gcc. # # $Id: Makefile.sol2gcc-64x,v 1.1 2005/06/26 23:53:17 carlsonj Exp $ # include Makedefs.sol2 # gcc flags for LP64 compilation / linkage COPTS += -finline -fno-inline-functions -fno-builtin -fno-asm \ -nodefaultlibs -D__sun -m64 -mtune=opteron -Ui386 \ -U__i386 -fno-strict-aliasing -fno-unit-at-a-time \ -fno-optimize-sibling-calls -O2 -D_ASM_INLINES \ -ffreestanding -mcmodel=kernel -mno-red-zone -gdwarf-2 \ -std=gnu89 -D_KERNEL -D_SYSCALL32 -D_SYSCALL32_IMPL \ -D_ELF64 -Dsun -D__sun -D__SVR4 # subdirectory where 64-bit objects / binaries will be placed LP64DIR = amd64 # Name of legacy Makefile (for 32-bit binaries) STD_MAKE = Makefile.sol2gcc COMP_OBJS = $(LP64DIR)/ppp_comp.o $(LP64DIR)/bsd-comp.o \ $(LP64DIR)/deflate.o $(LP64DIR)/zlib.o $(LP64DIR)/vjcompress.o \ $(LP64DIR)/ppp_comp_mod.o all: std_objs $(LP64DIR) ppp ppp_ahdl ppp_comp std_objs: $(MAKE) -f $(STD_MAKE) all ppp: $(LP64DIR)/ppp.o $(LP64DIR)/ppp_mod.o $(LD) -r -o $(LP64DIR)/$@ $(LP64DIR)/ppp.o $(LP64DIR)/ppp_mod.o chmod +x $(LP64DIR)/$@ ppp_ahdl: $(LP64DIR)/ppp_ahdlc.o $(LP64DIR)/ppp_ahdlc_mod.o $(LD) -r -o $(LP64DIR)/$@ $(LP64DIR)/ppp_ahdlc.o \ $(LP64DIR)/ppp_ahdlc_mod.o chmod +x $(LP64DIR)/$@ ppp_comp: $(COMP_OBJS) $(LD) -r -o $(LP64DIR)/$@ $(COMP_OBJS) chmod +x $(LP64DIR)/$@ $(LP64DIR)/bsd-comp.o: ../modules/bsd-comp.c $(CC) $(CFLAGS) -c $? -o $@ $(LP64DIR)/deflate.o: ../modules/deflate.c $(CC) $(CFLAGS) -c $? -o $@ $(LP64DIR)/ppp.o: ppp.c $(CC) $(CFLAGS) -c $? -o $@ $(LP64DIR)/ppp_mod.o: ppp_mod.c $(CC) $(CFLAGS) -c $? -o $@ $(LP64DIR)/ppp_ahdlc_mod.o: ppp_ahdlc_mod.c $(CC) $(CFLAGS) -c $? -o $@ $(LP64DIR)/ppp_ahdlc.o: ppp_ahdlc.c $(CC) $(CFLAGS) -c $? -o $@ $(LP64DIR)/ppp_comp.o: ppp_comp.c $(CC) $(CFLAGS) -c $? -o $@ $(LP64DIR)/ppp_comp_mod.o: ppp_comp_mod.c $(CC) $(CFLAGS) -c $? -o $@ $(LP64DIR)/vjcompress.o: ../modules/vjcompress.c $(CC) $(CFLAGS) -c $? -o $@ $(LP64DIR)/zlib.o: ../common/zlib.c $(CC) $(CFLAGS) -c $? -o $@ $(LP64DIR): mkdir -m 755 -p $@ install: /usr/sbin/modunload -i 0 cp ppp ppp.conf /kernel/drv cp ppp_comp ppp_ahdl /kernel/strmod cp $(LP64DIR)/ppp /kernel/drv/$(LP64DIR) cp $(LP64DIR)/ppp_comp $(LP64DIR)/ppp_ahdl /kernel/strmod/$(LP64DIR) if grep clone:ppp /etc/minor_perm; then :; else \ echo clone:ppp 0644 root sys >>/etc/minor_perm; fi /usr/sbin/rem_drv ppp 2>/dev/null || true /usr/sbin/modunload -i 0 /usr/sbin/add_drv ppp SRCS = ppp.c ppp_mod.c ppp_ahdlc.c ppp_ahdlc_mod.c \ ppp_comp.c ../modules/bsd-comp.c ../modules/deflate.c \ ../common/zlib.c ../modules/vjcompress.c ppp_comp_mod.c lint: $(LINT64) $(SRCS) lint-32: $(LINT32) $(SRCS) clean: $(MAKE) -f $(STD_MAKE) clean rm -f $(LP64DIR)/ppp $(LP64DIR)/ppp_comp $(LP64DIR)/ppp_ahdl $(LP64DIR)/*.o $(LP64DIR)/*~ $(LP64DIR)/core ppp-2.5.0/solaris/Makefile.top0000644000175000017500000000207210141401133013140 00000000000000# # ppp top level makefile for SVR4 and Solaris 2 # # $Id: Makefile.top,v 1.3 2004/11/01 09:31:07 paulus Exp $ # include Makedefs.com all: cd chat; $(MAKE) all cd pppd; $(MAKE) all cd pppstats; $(MAKE) all cd pppdump; $(MAKE) all cd solaris; $(MAKE) all install: $(BINDIR) $(MANDIR)/man8 install-progs install-progs: cd chat; $(MAKE) install cd pppd; $(MAKE) install cd pppstats; $(MAKE) install cd pppdump; $(MAKE) install install-etcppp: $(ETCDIR) $(ETCDIR)/options $(ETCDIR)/pap-secrets \ $(ETCDIR)/chap-secrets install-modules: cd solaris; $(MAKE) install $(ETCDIR)/options: cp etc.ppp/options $@ chmod go-w $@ $(ETCDIR)/pap-secrets: $(INSTALL) -f $(ETCDIR) -m 600 etc.ppp/pap-secrets $(ETCDIR)/chap-secrets: $(INSTALL) -f $(ETCDIR) -m 600 etc.ppp/chap-secrets $(BINDIR): mkdir -m 755 -p $@ $(MANDIR)/man8: mkdir -m 755 -p $@ $(ETCDIR): mkdir -m 755 -p $@ clean: rm -f *~ cd chat; $(MAKE) clean cd pppd; $(MAKE) clean cd pppstats; $(MAKE) clean cd pppdump; $(MAKE) clean cd solaris; $(MAKE) clean # no tests yet, one day... installcheck: true ppp-2.5.0/solaris/ppp_ahdlc.c0000664000175000017500000005233413772533376013041 00000000000000/* * ppp_ahdlc.c - STREAMS module for doing PPP asynchronous HDLC. * * Re-written by Adi Masputra , based on * the original ppp_ahdlc.c * * Copyright (c) 2000 by Sun Microsystems, Inc. * All rights reserved. * * Permission to use, copy, modify, and distribute this software and its * documentation is hereby granted, provided that the above copyright * notice appears in all copies. * * SUN MAKES NO REPRESENTATION OR WARRANTIES ABOUT THE SUITABILITY OF * THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * PARTICULAR PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES * * Copyright (c) 1994 Paul Mackerras. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The name(s) of the authors of this software must not be used to * endorse or promote products derived from this software without * prior written permission. * * 4. Redistributions of any form whatsoever must retain the following * acknowledgment: * "This product includes software developed by Paul Mackerras * ". * * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * $Id: ppp_ahdlc.c,v 1.5 2005/06/27 00:59:57 carlsonj Exp $ */ /* * This file is used under Solaris 2, SVR4, SunOS 4, and Digital UNIX. */ #include #include #include #include #include #ifdef SVR4 #include #include #include #include #else #include #ifdef __osf__ #include #endif #endif /* SVR4 */ #include #include #include "ppp_mod.h" /* * Right now, mutex is only enabled for Solaris 2.x */ #if defined(SOL2) #define USE_MUTEX #endif /* SOL2 */ #ifdef USE_MUTEX #define MUTEX_ENTER(x) mutex_enter(x) #define MUTEX_EXIT(x) mutex_exit(x) #else #define MUTEX_ENTER(x) #define MUTEX_EXIT(x) #endif /* * intpointer_t and uintpointer_t are signed and unsigned integer types * large enough to hold any data pointer; that is, data pointers can be * assigned into or from these integer types without losing precision. * On recent Solaris releases, these types are defined in sys/int_types.h, * but not on SunOS 4.x or the earlier Solaris versions. */ #if defined(_LP64) || defined(_I32LPx) typedef long intpointer_t; typedef unsigned long uintpointer_t; #else typedef int intpointer_t; typedef unsigned int uintpointer_t; #endif MOD_OPEN_DECL(ahdlc_open); MOD_CLOSE_DECL(ahdlc_close); static int ahdlc_wput(queue_t *, mblk_t *); static int ahdlc_rput(queue_t *, mblk_t *); static void ahdlc_encode(queue_t *, mblk_t *); static void ahdlc_decode(queue_t *, mblk_t *); static int msg_byte(mblk_t *, unsigned int); #if defined(SOL2) /* * Don't send HDLC start flag is last transmit is within 1.5 seconds - * FLAG_TIME is defined is microseconds */ #define FLAG_TIME 1500 #define ABS(x) (x >= 0 ? x : (-x)) #endif /* SOL2 */ /* * Extract byte i of message mp */ #define MSG_BYTE(mp, i) ((i) < (mp)->b_wptr - (mp)->b_rptr? (mp)->b_rptr[i]: \ msg_byte((mp), (i))) /* * Is this LCP packet one we have to transmit using LCP defaults? */ #define LCP_USE_DFLT(mp) (1 <= (code = MSG_BYTE((mp), 4)) && code <= 7) /* * Standard STREAMS declarations */ static struct module_info minfo = { 0x7d23, "ppp_ahdl", 0, INFPSZ, 32768, 512 }; static struct qinit rinit = { ahdlc_rput, NULL, ahdlc_open, ahdlc_close, NULL, &minfo, NULL }; static struct qinit winit = { ahdlc_wput, NULL, NULL, NULL, NULL, &minfo, NULL }; #if defined(SVR4) && !defined(SOL2) int phdldevflag = 0; #define ppp_ahdlcinfo phdlinfo #endif /* defined(SVR4) && !defined(SOL2) */ struct streamtab ppp_ahdlcinfo = { &rinit, /* ptr to st_rdinit */ &winit, /* ptr to st_wrinit */ NULL, /* ptr to st_muxrinit */ NULL, /* ptr to st_muxwinit */ #if defined(SUNOS4) NULL /* ptr to ptr to st_modlist */ #endif /* SUNOS4 */ }; #if defined(SUNOS4) int ppp_ahdlc_count = 0; /* open counter */ #endif /* SUNOS4 */ /* * Per-stream state structure */ typedef struct ahdlc_state { #if defined(USE_MUTEX) kmutex_t lock; /* lock for this structure */ #endif /* USE_MUTEX */ int flags; /* link flags */ mblk_t *rx_buf; /* ptr to receive buffer */ int rx_buf_size; /* receive buffer size */ ushort_t infcs; /* calculated rx HDLC FCS */ u_int32_t xaccm[8]; /* 256-bit xmit ACCM */ u_int32_t raccm; /* 32-bit rcv ACCM */ int mtu; /* interface MTU */ int mru; /* link MRU */ int unit; /* current PPP unit number */ struct pppstat stats; /* statistic structure */ #if defined(SOL2) clock_t flag_time; /* time in usec between flags */ clock_t lbolt; /* last updated lbolt */ #endif /* SOL2 */ } ahdlc_state_t; /* * Values for flags */ #define ESCAPED 0x100 /* last saw escape char on input */ #define IFLUSH 0x200 /* flushing input due to error */ /* * RCV_B7_1, etc., defined in net/pppio.h, are stored in flags also. */ #define RCV_FLAGS (RCV_B7_1|RCV_B7_0|RCV_ODDP|RCV_EVNP) /* * FCS lookup table as calculated by genfcstab. */ static u_short fcstab[256] = { 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf, 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7, 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e, 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876, 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd, 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5, 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c, 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974, 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb, 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3, 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a, 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72, 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9, 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1, 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738, 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70, 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7, 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff, 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036, 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e, 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5, 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd, 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134, 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c, 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3, 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb, 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232, 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a, 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1, 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9, 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330, 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78 }; static u_int32_t paritytab[8] = { 0x96696996, 0x69969669, 0x69969669, 0x96696996, 0x69969669, 0x96696996, 0x96696996, 0x69969669 }; /* * STREAMS module open (entry) point */ MOD_OPEN(ahdlc_open) { ahdlc_state_t *state; mblk_t *mp; /* * Return if it's already opened */ if (q->q_ptr) { return 0; } /* * This can only be opened as a module */ if (sflag != MODOPEN) { OPEN_ERROR(EINVAL); } state = (ahdlc_state_t *) ALLOC_NOSLEEP(sizeof(ahdlc_state_t)); if (state == 0) OPEN_ERROR(ENOSR); bzero((caddr_t) state, sizeof(ahdlc_state_t)); q->q_ptr = (caddr_t) state; WR(q)->q_ptr = (caddr_t) state; #if defined(USE_MUTEX) mutex_init(&state->lock, NULL, MUTEX_DEFAULT, NULL); #endif /* USE_MUTEX */ state->xaccm[0] = ~0; /* escape 0x00 through 0x1f */ state->xaccm[3] = 0x60000000; /* escape 0x7d and 0x7e */ state->mru = PPP_MRU; /* default of 1500 bytes */ #if defined(SOL2) state->flag_time = drv_usectohz(FLAG_TIME); #endif /* SOL2 */ #if defined(SUNOS4) ppp_ahdlc_count++; #endif /* SUNOS4 */ qprocson(q); if ((mp = allocb(1, BPRI_HI)) != NULL) { mp->b_datap->db_type = M_FLUSH; *mp->b_wptr++ = FLUSHR; putnext(q, mp); } return 0; } /* * STREAMS module close (exit) point */ MOD_CLOSE(ahdlc_close) { ahdlc_state_t *state; qprocsoff(q); state = (ahdlc_state_t *) q->q_ptr; if (state == 0) { DPRINT("state == 0 in ahdlc_close\n"); return 0; } if (state->rx_buf != 0) { freemsg(state->rx_buf); state->rx_buf = 0; } #if defined(USE_MUTEX) mutex_destroy(&state->lock); #endif /* USE_MUTEX */ FREE(q->q_ptr, sizeof(ahdlc_state_t)); q->q_ptr = NULL; OTHERQ(q)->q_ptr = NULL; #if defined(SUNOS4) if (ppp_ahdlc_count) ppp_ahdlc_count--; #endif /* SUNOS4 */ return 0; } /* * Write side put routine */ static int ahdlc_wput(q, mp) queue_t *q; mblk_t *mp; { ahdlc_state_t *state; struct iocblk *iop; int error; mblk_t *np; struct ppp_stats *psp; state = (ahdlc_state_t *) q->q_ptr; if (state == 0) { DPRINT("state == 0 in ahdlc_wput\n"); freemsg(mp); return 0; } switch (mp->b_datap->db_type) { case M_DATA: /* * A data packet - do character-stuffing and FCS, and * send it onwards. */ ahdlc_encode(q, mp); freemsg(mp); break; case M_IOCTL: iop = (struct iocblk *) mp->b_rptr; error = EINVAL; switch (iop->ioc_cmd) { case PPPIO_XACCM: if ((iop->ioc_count < sizeof(u_int32_t)) || (iop->ioc_count > sizeof(ext_accm))) { break; } if (mp->b_cont == 0) { DPRINT1("ahdlc_wput/%d: PPPIO_XACCM b_cont = 0!\n", state->unit); break; } MUTEX_ENTER(&state->lock); bcopy((caddr_t)mp->b_cont->b_rptr, (caddr_t)state->xaccm, iop->ioc_count); state->xaccm[2] &= ~0x40000000; /* don't escape 0x5e */ state->xaccm[3] |= 0x60000000; /* do escape 0x7d, 0x7e */ MUTEX_EXIT(&state->lock); iop->ioc_count = 0; error = 0; break; case PPPIO_RACCM: if (iop->ioc_count != sizeof(u_int32_t)) break; if (mp->b_cont == 0) { DPRINT1("ahdlc_wput/%d: PPPIO_RACCM b_cont = 0!\n", state->unit); break; } MUTEX_ENTER(&state->lock); bcopy((caddr_t)mp->b_cont->b_rptr, (caddr_t)&state->raccm, sizeof(u_int32_t)); MUTEX_EXIT(&state->lock); iop->ioc_count = 0; error = 0; break; case PPPIO_GCLEAN: np = allocb(sizeof(int), BPRI_HI); if (np == 0) { error = ENOSR; break; } if (mp->b_cont != 0) freemsg(mp->b_cont); mp->b_cont = np; MUTEX_ENTER(&state->lock); *(int *)np->b_wptr = state->flags & RCV_FLAGS; MUTEX_EXIT(&state->lock); np->b_wptr += sizeof(int); iop->ioc_count = sizeof(int); error = 0; break; case PPPIO_GETSTAT: np = allocb(sizeof(struct ppp_stats), BPRI_HI); if (np == 0) { error = ENOSR; break; } if (mp->b_cont != 0) freemsg(mp->b_cont); mp->b_cont = np; psp = (struct ppp_stats *) np->b_wptr; np->b_wptr += sizeof(struct ppp_stats); bzero((caddr_t)psp, sizeof(struct ppp_stats)); psp->p = state->stats; iop->ioc_count = sizeof(struct ppp_stats); error = 0; break; case PPPIO_LASTMOD: /* we knew this anyway */ error = 0; break; default: error = -1; break; } if (error < 0) putnext(q, mp); else if (error == 0) { mp->b_datap->db_type = M_IOCACK; qreply(q, mp); } else { mp->b_datap->db_type = M_IOCNAK; iop->ioc_count = 0; iop->ioc_error = error; qreply(q, mp); } break; case M_CTL: switch (*mp->b_rptr) { case PPPCTL_MTU: MUTEX_ENTER(&state->lock); state->mtu = ((unsigned short *)mp->b_rptr)[1]; MUTEX_EXIT(&state->lock); break; case PPPCTL_MRU: MUTEX_ENTER(&state->lock); state->mru = ((unsigned short *)mp->b_rptr)[1]; MUTEX_EXIT(&state->lock); break; case PPPCTL_UNIT: MUTEX_ENTER(&state->lock); state->unit = mp->b_rptr[1]; MUTEX_EXIT(&state->lock); break; default: putnext(q, mp); return 0; } freemsg(mp); break; default: putnext(q, mp); } return 0; } /* * Read side put routine */ static int ahdlc_rput(q, mp) queue_t *q; mblk_t *mp; { ahdlc_state_t *state; state = (ahdlc_state_t *) q->q_ptr; if (state == 0) { DPRINT("state == 0 in ahdlc_rput\n"); freemsg(mp); return 0; } switch (mp->b_datap->db_type) { case M_DATA: ahdlc_decode(q, mp); break; case M_HANGUP: MUTEX_ENTER(&state->lock); if (state->rx_buf != 0) { /* XXX would like to send this up for debugging */ freemsg(state->rx_buf); state->rx_buf = 0; } state->flags = IFLUSH; MUTEX_EXIT(&state->lock); putnext(q, mp); break; default: putnext(q, mp); } return 0; } /* * Extract bit c from map m, to determine if c needs to be escaped */ #define IN_TX_MAP(c, m) ((m)[(c) >> 5] & (1 << ((c) & 0x1f))) static void ahdlc_encode(q, mp) queue_t *q; mblk_t *mp; { ahdlc_state_t *state; u_int32_t *xaccm, loc_xaccm[8]; ushort_t fcs; size_t outmp_len; mblk_t *outmp, *tmp; uchar_t *dp, fcs_val; int is_lcp, code; #if defined(SOL2) clock_t lbolt; #endif /* SOL2 */ if (msgdsize(mp) < 4) { return; } state = (ahdlc_state_t *)q->q_ptr; MUTEX_ENTER(&state->lock); /* * Allocate an output buffer large enough to handle a case where all * characters need to be escaped */ outmp_len = (msgdsize(mp) << 1) + /* input block x 2 */ (sizeof(fcs) << 2) + /* HDLC FCS x 4 */ (sizeof(uchar_t) << 1); /* HDLC flags x 2 */ outmp = allocb(outmp_len, BPRI_MED); if (outmp == NULL) { state->stats.ppp_oerrors++; MUTEX_EXIT(&state->lock); putctl1(RD(q)->q_next, M_CTL, PPPCTL_OERROR); return; } #if defined(SOL2) /* * Check if our last transmit happenned within flag_time, using * the system's LBOLT value in clock ticks */ if (drv_getparm(LBOLT, &lbolt) != -1) { if (ABS((clock_t)lbolt - state->lbolt) > state->flag_time) { *outmp->b_wptr++ = PPP_FLAG; } state->lbolt = lbolt; } else { *outmp->b_wptr++ = PPP_FLAG; } #else /* * If the driver below still has a message to process, skip the * HDLC flag, otherwise, put one in the beginning */ if (qsize(q->q_next) == 0) { *outmp->b_wptr++ = PPP_FLAG; } #endif /* * All control characters must be escaped for LCP packets with code * values between 1 (Conf-Req) and 7 (Code-Rej). */ is_lcp = ((MSG_BYTE(mp, 0) == PPP_ALLSTATIONS) && (MSG_BYTE(mp, 1) == PPP_UI) && (MSG_BYTE(mp, 2) == (PPP_LCP >> 8)) && (MSG_BYTE(mp, 3) == (PPP_LCP & 0xff)) && LCP_USE_DFLT(mp)); xaccm = state->xaccm; if (is_lcp) { bcopy((caddr_t)state->xaccm, (caddr_t)loc_xaccm, sizeof(loc_xaccm)); loc_xaccm[0] = ~0; /* force escape on 0x00 through 0x1f */ xaccm = loc_xaccm; } fcs = PPP_INITFCS; /* Initial FCS is 0xffff */ /* * Process this block and the rest (if any) attached to the this one */ for (tmp = mp; tmp; tmp = tmp->b_cont) { if (tmp->b_datap->db_type == M_DATA) { for (dp = tmp->b_rptr; dp < tmp->b_wptr; dp++) { fcs = PPP_FCS(fcs, *dp); if (IN_TX_MAP(*dp, xaccm)) { *outmp->b_wptr++ = PPP_ESCAPE; *outmp->b_wptr++ = *dp ^ PPP_TRANS; } else { *outmp->b_wptr++ = *dp; } } } else { continue; /* skip if db_type is something other than M_DATA */ } } /* * Append the HDLC FCS, making sure that escaping is done on any * necessary bytes */ fcs_val = (fcs ^ 0xffff) & 0xff; if (IN_TX_MAP(fcs_val, xaccm)) { *outmp->b_wptr++ = PPP_ESCAPE; *outmp->b_wptr++ = fcs_val ^ PPP_TRANS; } else { *outmp->b_wptr++ = fcs_val; } fcs_val = ((fcs ^ 0xffff) >> 8) & 0xff; if (IN_TX_MAP(fcs_val, xaccm)) { *outmp->b_wptr++ = PPP_ESCAPE; *outmp->b_wptr++ = fcs_val ^ PPP_TRANS; } else { *outmp->b_wptr++ = fcs_val; } /* * And finally, append the HDLC flag, and send it away */ *outmp->b_wptr++ = PPP_FLAG; state->stats.ppp_obytes += msgdsize(outmp); state->stats.ppp_opackets++; MUTEX_EXIT(&state->lock); putnext(q, outmp); } /* * Checks the 32-bit receive ACCM to see if the byte needs un-escaping */ #define IN_RX_MAP(c, m) ((((unsigned int) (uchar_t) (c)) < 0x20) && \ (m) & (1 << (c))) /* * Process received characters. */ static void ahdlc_decode(q, mp) queue_t *q; mblk_t *mp; { ahdlc_state_t *state; mblk_t *om; uchar_t *dp; state = (ahdlc_state_t *) q->q_ptr; MUTEX_ENTER(&state->lock); state->stats.ppp_ibytes += msgdsize(mp); for (; mp != 0; om = mp->b_cont, freeb(mp), mp = om) for (dp = mp->b_rptr; dp < mp->b_wptr; dp++) { /* * This should detect the lack of 8-bit communication channel * which is necessary for PPP to work. In addition, it also * checks on the parity. */ if (*dp & 0x80) state->flags |= RCV_B7_1; else state->flags |= RCV_B7_0; if (paritytab[*dp >> 5] & (1 << (*dp & 0x1f))) state->flags |= RCV_ODDP; else state->flags |= RCV_EVNP; /* * So we have a HDLC flag ... */ if (*dp == PPP_FLAG) { /* * If we think that it marks the beginning of the frame, * then continue to process the next octects */ if ((state->flags & IFLUSH) || (state->rx_buf == 0) || (msgdsize(state->rx_buf) == 0)) { state->flags &= ~IFLUSH; continue; } /* * We get here because the above condition isn't true, * in which case the HDLC flag was there to mark the end * of the frame (or so we think) */ om = state->rx_buf; if (state->infcs == PPP_GOODFCS) { state->stats.ppp_ipackets++; adjmsg(om, -PPP_FCSLEN); putnext(q, om); } else { DPRINT2("ppp%d: bad fcs (len=%d)\n", state->unit, msgdsize(state->rx_buf)); freemsg(state->rx_buf); state->flags &= ~(IFLUSH | ESCAPED); state->stats.ppp_ierrors++; putctl1(q->q_next, M_CTL, PPPCTL_IERROR); } state->rx_buf = 0; continue; } if (state->flags & IFLUSH) { continue; } /* * Allocate a receive buffer, large enough to store a frame (after * un-escaping) of at least 1500 octets. If MRU is negotiated to * be more than the default, then allocate that much. In addition, * we add an extra 32-bytes for a fudge factor */ if (state->rx_buf == 0) { state->rx_buf_size = (state->mru < PPP_MRU ? PPP_MRU : state->mru); state->rx_buf_size += (sizeof(u_int32_t) << 3); state->rx_buf = allocb(state->rx_buf_size, BPRI_MED); /* * If allocation fails, try again on the next frame */ if (state->rx_buf == 0) { state->flags |= IFLUSH; continue; } state->flags &= ~(IFLUSH | ESCAPED); state->infcs = PPP_INITFCS; } if (*dp == PPP_ESCAPE) { state->flags |= ESCAPED; continue; } /* * Make sure we un-escape the necessary characters, as well as the * ones in our receive async control character map */ if (state->flags & ESCAPED) { *dp ^= PPP_TRANS; state->flags &= ~ESCAPED; } else if (IN_RX_MAP(*dp, state->raccm)) continue; /* * Unless the peer lied to us about the negotiated MRU, we should * never get a frame which is too long. If it happens, toss it away * and grab the next incoming one */ if (msgdsize(state->rx_buf) < state->rx_buf_size) { state->infcs = PPP_FCS(state->infcs, *dp); *state->rx_buf->b_wptr++ = *dp; } else { DPRINT2("ppp%d: frame too long (%d)\n", state->unit, msgdsize(state->rx_buf)); freemsg(state->rx_buf); state->rx_buf = 0; state->flags |= IFLUSH; } } MUTEX_EXIT(&state->lock); } static int msg_byte(mp, i) mblk_t *mp; unsigned int i; { while (mp != 0 && i >= mp->b_wptr - mp->b_rptr) mp = mp->b_cont; if (mp == 0) return -1; return mp->b_rptr[i]; } ppp-2.5.0/solaris/ppp_ahdlc_mod.c0000644000175000017500000000132507077172400013654 00000000000000#include #include #include #include #include extern struct streamtab ppp_ahdlcinfo; static struct fmodsw fsw = { "ppp_ahdl", &ppp_ahdlcinfo, D_NEW | D_MP | D_MTQPAIR }; extern struct mod_ops mod_strmodops; static struct modlstrmod modlstrmod = { &mod_strmodops, "PPP async HDLC module", &fsw }; static struct modlinkage modlinkage = { MODREV_1, (void *) &modlstrmod, NULL }; /* * Entry points for modloading. */ int _init(void) { return mod_install(&modlinkage); } int _fini(void) { return mod_remove(&modlinkage); } int _info(mip) struct modinfo *mip; { return mod_info(&modlinkage, mip); } ppp-2.5.0/solaris/ppp.c0000664000175000017500000017212513772533350011677 00000000000000/* * ppp.c - STREAMS multiplexing pseudo-device driver for PPP. * * Copyright (c) 1994 Paul Mackerras. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The name(s) of the authors of this software must not be used to * endorse or promote products derived from this software without * prior written permission. * * 4. Redistributions of any form whatsoever must retain the following * acknowledgment: * "This product includes software developed by Paul Mackerras * ". * * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /* * This file is used under Solaris 2, SVR4, SunOS 4, and Digital UNIX. */ #include #include #include #include #include #include #ifdef __osf__ #include #include #define queclass(mp) ((mp)->b_band & QPCTL) #else #include #endif #include #ifdef SVR4 #include #include #include #include #ifdef SOL2 #include #include #include #include #else #include #include #include #include #endif /* SOL2 */ #else /* not SVR4 */ #include #endif /* SVR4 */ #include #include #include "ppp_mod.h" /* * Modifications marked with #ifdef PRIOQ are for priority queueing of * interactive traffic, and are due to Marko Zec . */ #ifdef PRIOQ #endif /* PRIOQ */ #include /* leave this outside of PRIOQ for htons */ /* * The IP module may use this SAP value for IP packets. */ #ifndef ETHERTYPE_IP #define ETHERTYPE_IP 0x800 #endif #if !defined(ETHERTYPE_IPV6) #define ETHERTYPE_IPV6 0x86dd #endif /* !defined(ETHERTYPE_IPV6) */ #if !defined(ETHERTYPE_ALLSAP) && defined(SOL2) #define ETHERTYPE_ALLSAP 0 #endif /* !defined(ETHERTYPE_ALLSAP) && defined(SOL2) */ #if !defined(PPP_ALLSAP) && defined(SOL2) #define PPP_ALLSAP PPP_ALLSTATIONS #endif /* !defined(PPP_ALLSAP) && defined(SOL2) */ extern time_t time; #ifdef SOL2 /* * We use this reader-writer lock to ensure that the lower streams * stay connected to the upper streams while the lower-side put and * service procedures are running. Essentially it is an existence * lock for the upper stream associated with each lower stream. */ krwlock_t ppp_lower_lock; #define LOCK_LOWER_W rw_enter(&ppp_lower_lock, RW_WRITER) #define LOCK_LOWER_R rw_enter(&ppp_lower_lock, RW_READER) #define TRYLOCK_LOWER_R rw_tryenter(&ppp_lower_lock, RW_READER) #define UNLOCK_LOWER rw_exit(&ppp_lower_lock) #define MT_ENTER(x) mutex_enter(x) #define MT_EXIT(x) mutex_exit(x) /* * Notes on multithreaded implementation for Solaris 2: * * We use an inner perimeter around each queue pair and an outer * perimeter around the whole driver. The inner perimeter is * entered exclusively for all entry points (open, close, put, * service). The outer perimeter is entered exclusively for open * and close and shared for put and service. This is all done for * us by the streams framework. * * I used to think that the perimeters were entered for the lower * streams' put and service routines as well as for the upper streams'. * Because of problems experienced by people, and after reading the * documentation more closely, I now don't think that is true. So we * now use ppp_lower_lock to give us an existence guarantee on the * upper stream controlling each lower stream. * * Shared entry to the outer perimeter protects the existence of all * the upper streams and their upperstr_t structures, and guarantees * that the following fields of any upperstr_t won't change: * nextmn, next, nextppa. It guarantees that the lowerq field of an * upperstr_t won't go from non-zero to zero, that the global `ppas' * won't change and that the no lower stream will get unlinked. * * Shared (reader) access to ppa_lower_lock guarantees that no lower * stream will be unlinked and that the lowerq field of all upperstr_t * structures won't change. */ #else /* SOL2 */ #define LOCK_LOWER_W 0 #define LOCK_LOWER_R 0 #define TRYLOCK_LOWER_R 1 #define UNLOCK_LOWER 0 #define MT_ENTER(x) 0 #define MT_EXIT(x) 0 #endif /* SOL2 */ /* * Private information; one per upper stream. */ typedef struct upperstr { minor_t mn; /* minor device number */ struct upperstr *nextmn; /* next minor device */ queue_t *q; /* read q associated with this upper stream */ int flags; /* flag bits, see below */ int state; /* current DLPI state */ int sap; /* service access point */ int req_sap; /* which SAP the DLPI client requested */ struct upperstr *ppa; /* control stream for our ppa */ struct upperstr *next; /* next stream for this ppa */ uint ioc_id; /* last ioctl ID for this stream */ enum NPmode npmode; /* what to do with packets on this SAP */ unsigned char rblocked; /* flow control has blocked upper read strm */ /* N.B. rblocked is only changed by control stream's put/srv procs */ /* * There is exactly one control stream for each PPA. * The following fields are only used for control streams. */ int ppa_id; queue_t *lowerq; /* write queue attached below this PPA */ struct upperstr *nextppa; /* next control stream */ int mru; int mtu; struct pppstat stats; /* statistics */ time_t last_sent; /* time last NP packet sent */ time_t last_recv; /* time last NP packet rcvd */ #ifdef SOL2 kmutex_t stats_lock; /* lock for stats updates */ kstat_t *kstats; /* stats for netstat */ #endif /* SOL2 */ #ifdef LACHTCP int ifflags; char ifname[IFNAMSIZ]; struct ifstats ifstats; #endif /* LACHTCP */ } upperstr_t; /* Values for flags */ #define US_PRIV 1 /* stream was opened by superuser */ #define US_CONTROL 2 /* stream is a control stream */ #define US_BLOCKED 4 /* flow ctrl has blocked lower write stream */ #define US_LASTMOD 8 /* no PPP modules below us */ #define US_DBGLOG 0x10 /* log various occurrences */ #define US_RBLOCKED 0x20 /* flow ctrl has blocked upper read stream */ #if defined(SOL2) #if DL_CURRENT_VERSION >= 2 #define US_PROMISC 0x40 /* stream is promiscuous */ #endif /* DL_CURRENT_VERSION >= 2 */ #define US_RAWDATA 0x80 /* raw M_DATA, no DLPI header */ #endif /* defined(SOL2) */ #ifdef PRIOQ static u_char max_band=0; static u_char def_band=0; #define IPPORT_DEFAULT 65535 /* * Port priority table * Highest priority ports are listed first, lowest are listed last. * ICMP & packets using unlisted ports will be treated as "default". * If IPPORT_DEFAULT is not listed here, "default" packets will be * assigned lowest priority. * Each line should be terminated with "0". * Line containing only "0" marks the end of the list. */ static u_short prioq_table[]= { 113, 53, 0, 22, 23, 513, 517, 518, 0, 514, 21, 79, 111, 0, 25, 109, 110, 0, IPPORT_DEFAULT, 0, 20, 70, 80, 8001, 8008, 8080, 0, /* 8001,8008,8080 - common proxy ports */ 0 }; #endif /* PRIOQ */ static upperstr_t *minor_devs = NULL; static upperstr_t *ppas = NULL; #ifdef SVR4 static int pppopen(queue_t *, dev_t *, int, int, cred_t *); static int pppclose(queue_t *, int, cred_t *); #else static int pppopen(queue_t *, int, int, int); static int pppclose(queue_t *, int); #endif /* SVR4 */ static int pppurput(queue_t *, mblk_t *); static int pppuwput(queue_t *, mblk_t *); static int pppursrv(queue_t *); static int pppuwsrv(queue_t *); static int ppplrput(queue_t *, mblk_t *); static int ppplwput(queue_t *, mblk_t *); static int ppplrsrv(queue_t *); static int ppplwsrv(queue_t *); #ifndef NO_DLPI static void dlpi_request(queue_t *, mblk_t *, upperstr_t *); static void dlpi_error(queue_t *, upperstr_t *, int, int, int); static void dlpi_ok(queue_t *, int); #endif static int send_data(mblk_t *, upperstr_t *); static void new_ppa(queue_t *, mblk_t *); static void attach_ppa(queue_t *, mblk_t *); #ifndef NO_DLPI static void detach_ppa(queue_t *, mblk_t *); #endif static void detach_lower(queue_t *, mblk_t *); static void debug_dump(queue_t *, mblk_t *); static upperstr_t *find_dest(upperstr_t *, int); #if defined(SOL2) static upperstr_t *find_promisc(upperstr_t *, int); static mblk_t *prepend_ether(upperstr_t *, mblk_t *, int); static mblk_t *prepend_udind(upperstr_t *, mblk_t *, int); static void promisc_sendup(upperstr_t *, mblk_t *, int, int); #endif /* defined(SOL2) */ static int putctl2(queue_t *, int, int, int); static int putctl4(queue_t *, int, int, int); static int pass_packet(upperstr_t *ppa, mblk_t *mp, int outbound); #ifdef FILTER_PACKETS static int ip_hard_filter(upperstr_t *ppa, mblk_t *mp, int outbound); #endif /* FILTER_PACKETS */ #define PPP_ID 0xb1a6 static struct module_info ppp_info = { #ifdef PRIOQ PPP_ID, "ppp", 0, 512, 512, 384 #else PPP_ID, "ppp", 0, 512, 512, 128 #endif /* PRIOQ */ }; static struct qinit pppurint = { pppurput, pppursrv, pppopen, pppclose, NULL, &ppp_info, NULL }; static struct qinit pppuwint = { pppuwput, pppuwsrv, NULL, NULL, NULL, &ppp_info, NULL }; static struct qinit ppplrint = { ppplrput, ppplrsrv, NULL, NULL, NULL, &ppp_info, NULL }; static struct qinit ppplwint = { ppplwput, ppplwsrv, NULL, NULL, NULL, &ppp_info, NULL }; #ifdef LACHTCP extern struct ifstats *ifstats; int pppdevflag = 0; #endif struct streamtab pppinfo = { &pppurint, &pppuwint, &ppplrint, &ppplwint }; int ppp_count; /* * How we maintain statistics. */ #ifdef SOL2 #define INCR_IPACKETS(ppa) \ if (ppa->kstats != 0) { \ KSTAT_NAMED_PTR(ppa->kstats)[0].value.ul++; \ } #define INCR_IERRORS(ppa) \ if (ppa->kstats != 0) { \ KSTAT_NAMED_PTR(ppa->kstats)[1].value.ul++; \ } #define INCR_OPACKETS(ppa) \ if (ppa->kstats != 0) { \ KSTAT_NAMED_PTR(ppa->kstats)[2].value.ul++; \ } #define INCR_OERRORS(ppa) \ if (ppa->kstats != 0) { \ KSTAT_NAMED_PTR(ppa->kstats)[3].value.ul++; \ } #endif #ifdef LACHTCP #define INCR_IPACKETS(ppa) ppa->ifstats.ifs_ipackets++; #define INCR_IERRORS(ppa) ppa->ifstats.ifs_ierrors++; #define INCR_OPACKETS(ppa) ppa->ifstats.ifs_opackets++; #define INCR_OERRORS(ppa) ppa->ifstats.ifs_oerrors++; #endif /* * STREAMS driver entry points. */ static int #ifdef SVR4 pppopen(q, devp, oflag, sflag, credp) queue_t *q; dev_t *devp; int oflag, sflag; cred_t *credp; #else pppopen(q, dev, oflag, sflag) queue_t *q; int dev; /* really dev_t */ int oflag, sflag; #endif { upperstr_t *up; upperstr_t **prevp; minor_t mn; #ifdef PRIOQ u_short *ptr; u_char new_band; #endif /* PRIOQ */ if (q->q_ptr) DRV_OPEN_OK(dev); /* device is already open */ #ifdef PRIOQ /* Calculate max_bband & def_band from definitions in prioq.h This colud be done at some more approtiate time (less often) but this way it works well so I'll just leave it here */ max_band = 1; def_band = 0; ptr = prioq_table; while (*ptr) { new_band = 1; while (*ptr) if (*ptr++ == IPPORT_DEFAULT) { new_band = 0; def_band = max_band; } max_band += new_band; ptr++; } if (def_band) def_band = max_band - def_band; --max_band; #endif /* PRIOQ */ if (sflag == CLONEOPEN) { mn = 0; for (prevp = &minor_devs; (up = *prevp) != 0; prevp = &up->nextmn) { if (up->mn != mn) break; ++mn; } } else { #ifdef SVR4 mn = getminor(*devp); #else mn = minor(dev); #endif for (prevp = &minor_devs; (up = *prevp) != 0; prevp = &up->nextmn) { if (up->mn >= mn) break; } if (up->mn == mn) { /* this can't happen */ q->q_ptr = WR(q)->q_ptr = (caddr_t) up; DRV_OPEN_OK(dev); } } /* * Construct a new minor node. */ up = (upperstr_t *) ALLOC_SLEEP(sizeof(upperstr_t)); bzero((caddr_t) up, sizeof(upperstr_t)); if (up == 0) { DPRINT("pppopen: out of kernel memory\n"); OPEN_ERROR(ENXIO); } up->nextmn = *prevp; *prevp = up; up->mn = mn; #ifdef SVR4 *devp = makedevice(getmajor(*devp), mn); #endif up->q = q; if (NOTSUSER() == 0) up->flags |= US_PRIV; #ifndef NO_DLPI up->state = DL_UNATTACHED; #endif #ifdef LACHTCP up->ifflags = IFF_UP | IFF_POINTOPOINT; #endif up->sap = -1; up->last_sent = up->last_recv = time; up->npmode = NPMODE_DROP; q->q_ptr = (caddr_t) up; WR(q)->q_ptr = (caddr_t) up; noenable(WR(q)); #ifdef SOL2 mutex_init(&up->stats_lock, NULL, MUTEX_DRIVER, NULL); #endif ++ppp_count; qprocson(q); DRV_OPEN_OK(makedev(major(dev), mn)); } static int #ifdef SVR4 pppclose(q, flag, credp) queue_t *q; int flag; cred_t *credp; #else pppclose(q, flag) queue_t *q; int flag; #endif { upperstr_t *up, **upp; upperstr_t *as, *asnext; upperstr_t **prevp; qprocsoff(q); up = (upperstr_t *) q->q_ptr; if (up == 0) { DPRINT("pppclose: q_ptr = 0\n"); return 0; } if (up->flags & US_DBGLOG) DPRINT2("ppp/%d: close, flags=%x\n", up->mn, up->flags); if (up->flags & US_CONTROL) { #ifdef LACHTCP struct ifstats *ifp, *pifp; #endif if (up->lowerq != 0) { /* Gack! the lower stream should have be unlinked earlier! */ DPRINT1("ppp%d: lower stream still connected on close?\n", up->mn); LOCK_LOWER_W; up->lowerq->q_ptr = 0; RD(up->lowerq)->q_ptr = 0; up->lowerq = 0; UNLOCK_LOWER; } /* * This stream represents a PPA: * For all streams attached to the PPA, clear their * references to this PPA. * Then remove this PPA from the list of PPAs. */ for (as = up->next; as != 0; as = asnext) { asnext = as->next; as->next = 0; as->ppa = 0; if (as->flags & US_BLOCKED) { as->flags &= ~US_BLOCKED; flushq(WR(as->q), FLUSHDATA); } } for (upp = &ppas; *upp != 0; upp = &(*upp)->nextppa) if (*upp == up) { *upp = up->nextppa; break; } #ifdef LACHTCP /* Remove the statistics from the active list. */ for (ifp = ifstats, pifp = 0; ifp; ifp = ifp->ifs_next) { if (ifp == &up->ifstats) { if (pifp) pifp->ifs_next = ifp->ifs_next; else ifstats = ifp->ifs_next; break; } pifp = ifp; } #endif } else { /* * If this stream is attached to a PPA, * remove it from the PPA's list. */ if ((as = up->ppa) != 0) { for (; as->next != 0; as = as->next) if (as->next == up) { as->next = up->next; break; } } } #ifdef SOL2 if (up->kstats) kstat_delete(up->kstats); mutex_destroy(&up->stats_lock); #endif q->q_ptr = NULL; WR(q)->q_ptr = NULL; for (prevp = &minor_devs; *prevp != 0; prevp = &(*prevp)->nextmn) { if (*prevp == up) { *prevp = up->nextmn; break; } } FREE(up, sizeof(upperstr_t)); --ppp_count; return 0; } /* * A message from on high. We do one of three things: * - qreply() * - put the message on the lower write stream * - queue it for our service routine */ static int pppuwput(q, mp) queue_t *q; mblk_t *mp; { upperstr_t *us, *ppa, *nps; struct iocblk *iop; struct linkblk *lb; #ifdef LACHTCP struct ifreq *ifr; int i; #endif queue_t *lq; int error, n, sap; mblk_t *mq; struct ppp_idle *pip; #ifdef PRIOQ queue_t *tlq; #endif /* PRIOQ */ #ifdef NO_DLPI upperstr_t *os; #endif us = (upperstr_t *) q->q_ptr; if (us == 0) { DPRINT("pppuwput: q_ptr = 0!\n"); return 0; } if (mp == 0) { DPRINT1("pppuwput/%d: mp = 0!\n", us->mn); return 0; } if (mp->b_datap == 0) { DPRINT1("pppuwput/%d: mp->b_datap = 0!\n", us->mn); return 0; } switch (mp->b_datap->db_type) { #ifndef NO_DLPI case M_PCPROTO: case M_PROTO: dlpi_request(q, mp, us); break; #endif /* NO_DLPI */ case M_DATA: if (us->flags & US_DBGLOG) DPRINT3("ppp/%d: uwput M_DATA len=%d flags=%x\n", us->mn, msgdsize(mp), us->flags); if (us->ppa == 0 || msgdsize(mp) > us->ppa->mtu + PPP_HDRLEN #ifndef NO_DLPI || (us->flags & US_CONTROL) == 0 #endif /* NO_DLPI */ ) { DPRINT1("pppuwput: junk data len=%d\n", msgdsize(mp)); freemsg(mp); break; } #ifdef NO_DLPI /* pass_packet frees the packet on returning 0 */ if ((us->flags & US_CONTROL) == 0 && !pass_packet(us, mp, 1)) break; #endif if (!send_data(mp, us) && !putq(q, mp)) freemsg(mp); break; case M_IOCTL: iop = (struct iocblk *) mp->b_rptr; error = EINVAL; if (us->flags & US_DBGLOG) DPRINT3("ppp/%d: ioctl %x count=%d\n", us->mn, iop->ioc_cmd, iop->ioc_count); switch (iop->ioc_cmd) { #if defined(SOL2) case DLIOCRAW: /* raw M_DATA mode */ us->flags |= US_RAWDATA; error = 0; break; #endif /* defined(SOL2) */ case I_LINK: if ((us->flags & US_CONTROL) == 0 || us->lowerq != 0) break; if (mp->b_cont == 0) { DPRINT1("pppuwput/%d: ioctl I_LINK b_cont = 0!\n", us->mn); break; } lb = (struct linkblk *) mp->b_cont->b_rptr; lq = lb->l_qbot; if (lq == 0) { DPRINT1("pppuwput/%d: ioctl I_LINK l_qbot = 0!\n", us->mn); break; } LOCK_LOWER_W; us->lowerq = lq; lq->q_ptr = (caddr_t) q; RD(lq)->q_ptr = (caddr_t) us->q; UNLOCK_LOWER; iop->ioc_count = 0; error = 0; us->flags &= ~US_LASTMOD; /* Unblock upper streams which now feed this lower stream. */ qenable(q); /* Send useful information down to the modules which are now linked below us. */ putctl2(lq, M_CTL, PPPCTL_UNIT, us->ppa_id); putctl4(lq, M_CTL, PPPCTL_MRU, us->mru); putctl4(lq, M_CTL, PPPCTL_MTU, us->mtu); #ifdef PRIOQ /* Lower tty driver's queue hiwat/lowat from default 4096/128 to 256/128 since we don't want queueing of data on output to physical device */ freezestr(lq); for (tlq = lq; tlq->q_next != NULL; tlq = tlq->q_next) ; strqset(tlq, QHIWAT, 0, 256); strqset(tlq, QLOWAT, 0, 128); unfreezestr(lq); #endif /* PRIOQ */ break; case I_UNLINK: if (mp->b_cont == 0) { DPRINT1("pppuwput/%d: ioctl I_UNLINK b_cont = 0!\n", us->mn); break; } lb = (struct linkblk *) mp->b_cont->b_rptr; #if DEBUG if (us->lowerq != lb->l_qbot) { DPRINT2("ppp unlink: lowerq=%x qbot=%x\n", us->lowerq, lb->l_qbot); break; } #endif iop->ioc_count = 0; qwriter(q, mp, detach_lower, PERIM_OUTER); /* mp is now gone */ error = -1; break; case PPPIO_NEWPPA: if (us->flags & US_CONTROL) break; if ((us->flags & US_PRIV) == 0) { error = EPERM; break; } /* Arrange to return an int */ if ((mq = mp->b_cont) == 0 || mq->b_datap->db_lim - mq->b_rptr < sizeof(int)) { mq = allocb(sizeof(int), BPRI_HI); if (mq == 0) { error = ENOSR; break; } if (mp->b_cont != 0) freemsg(mp->b_cont); mp->b_cont = mq; mq->b_cont = 0; } iop->ioc_count = sizeof(int); mq->b_wptr = mq->b_rptr + sizeof(int); qwriter(q, mp, new_ppa, PERIM_OUTER); /* mp is now gone */ error = -1; break; case PPPIO_ATTACH: /* like dlpi_attach, for programs which can't write to the stream (like pppstats) */ if (iop->ioc_count != sizeof(int) || us->ppa != 0) break; if (mp->b_cont == 0) { DPRINT1("pppuwput/%d: ioctl PPPIO_ATTACH b_cont = 0!\n", us->mn); break; } n = *(int *)mp->b_cont->b_rptr; for (ppa = ppas; ppa != 0; ppa = ppa->nextppa) if (ppa->ppa_id == n) break; if (ppa == 0) break; us->ppa = ppa; iop->ioc_count = 0; qwriter(q, mp, attach_ppa, PERIM_OUTER); /* mp is now gone */ error = -1; break; #ifdef NO_DLPI case PPPIO_BIND: /* Attach to a given SAP. */ if (iop->ioc_count != sizeof(int) || us->ppa == 0) break; if (mp->b_cont == 0) { DPRINT1("pppuwput/%d: ioctl PPPIO_BIND b_cont = 0!\n", us->mn); break; } n = *(int *)mp->b_cont->b_rptr; /* n must be a valid PPP network protocol number. */ if (n < 0x21 || n > 0x3fff || (n & 0x101) != 1) break; /* check that no other stream is bound to this sap already. */ for (os = us->ppa; os != 0; os = os->next) if (os->sap == n) break; if (os != 0) break; us->sap = n; iop->ioc_count = 0; error = 0; break; #endif /* NO_DLPI */ case PPPIO_MRU: if (iop->ioc_count != sizeof(int) || (us->flags & US_CONTROL) == 0) break; if (mp->b_cont == 0) { DPRINT1("pppuwput/%d: ioctl PPPIO_MRU b_cont = 0!\n", us->mn); break; } n = *(int *)mp->b_cont->b_rptr; if (n <= 0 || n > PPP_MAXMRU) break; if (n < PPP_MRU) n = PPP_MRU; us->mru = n; if (us->lowerq) putctl4(us->lowerq, M_CTL, PPPCTL_MRU, n); error = 0; iop->ioc_count = 0; break; case PPPIO_MTU: if (iop->ioc_count != sizeof(int) || (us->flags & US_CONTROL) == 0) break; if (mp->b_cont == 0) { DPRINT1("pppuwput/%d: ioctl PPPIO_MTU b_cont = 0!\n", us->mn); break; } n = *(int *)mp->b_cont->b_rptr; if (n <= 0 || n > PPP_MAXMTU) break; us->mtu = n; #ifdef LACHTCP /* The MTU reported in netstat, not used as IP max packet size! */ us->ifstats.ifs_mtu = n; #endif if (us->lowerq) putctl4(us->lowerq, M_CTL, PPPCTL_MTU, n); error = 0; iop->ioc_count = 0; break; case PPPIO_LASTMOD: us->flags |= US_LASTMOD; error = 0; break; case PPPIO_DEBUG: if (iop->ioc_count != sizeof(int)) break; if (mp->b_cont == 0) { DPRINT1("pppuwput/%d: ioctl PPPIO_DEBUG b_cont = 0!\n", us->mn); break; } n = *(int *)mp->b_cont->b_rptr; if (n == PPPDBG_DUMP + PPPDBG_DRIVER) { qwriter(q, mp, debug_dump, PERIM_OUTER); /* mp is now gone */ error = -1; } else if (n == PPPDBG_LOG + PPPDBG_DRIVER) { DPRINT1("ppp/%d: debug log enabled\n", us->mn); us->flags |= US_DBGLOG; iop->ioc_count = 0; error = 0; } else { if (us->ppa == 0 || us->ppa->lowerq == 0) break; putnext(us->ppa->lowerq, mp); /* mp is now gone */ error = -1; } break; case PPPIO_NPMODE: if (iop->ioc_count != 2 * sizeof(int)) break; if ((us->flags & US_CONTROL) == 0) break; if (mp->b_cont == 0) { DPRINT1("pppuwput/%d: ioctl PPPIO_NPMODE b_cont = 0!\n", us->mn); break; } sap = ((int *)mp->b_cont->b_rptr)[0]; for (nps = us->next; nps != 0; nps = nps->next) { if (us->flags & US_DBGLOG) DPRINT2("us = 0x%x, us->next->sap = 0x%x\n", nps, nps->sap); if (nps->sap == sap) break; } if (nps == 0) { if (us->flags & US_DBGLOG) DPRINT2("ppp/%d: no stream for sap %x\n", us->mn, sap); break; } /* XXX possibly should use qwriter here */ nps->npmode = (enum NPmode) ((int *)mp->b_cont->b_rptr)[1]; if (nps->npmode != NPMODE_QUEUE && (nps->flags & US_BLOCKED) != 0) qenable(WR(nps->q)); iop->ioc_count = 0; error = 0; break; case PPPIO_GIDLE: if ((ppa = us->ppa) == 0) break; mq = allocb(sizeof(struct ppp_idle), BPRI_HI); if (mq == 0) { error = ENOSR; break; } if (mp->b_cont != 0) freemsg(mp->b_cont); mp->b_cont = mq; mq->b_cont = 0; pip = (struct ppp_idle *) mq->b_wptr; pip->xmit_idle = time - ppa->last_sent; pip->recv_idle = time - ppa->last_recv; mq->b_wptr += sizeof(struct ppp_idle); iop->ioc_count = sizeof(struct ppp_idle); error = 0; break; #ifdef LACHTCP case SIOCSIFNAME: /* Sent from IP down to us. Attach the ifstats structure. */ if (iop->ioc_count != sizeof(struct ifreq) || us->ppa == 0) break; ifr = (struct ifreq *)mp->b_cont->b_rptr; /* Find the unit number in the interface name. */ for (i = 0; i < IFNAMSIZ; i++) { if (ifr->ifr_name[i] == 0 || (ifr->ifr_name[i] >= '0' && ifr->ifr_name[i] <= '9')) break; else us->ifname[i] = ifr->ifr_name[i]; } us->ifname[i] = 0; /* Convert the unit number to binary. */ for (n = 0; i < IFNAMSIZ; i++) { if (ifr->ifr_name[i] == 0) { break; } else { n = n * 10 + ifr->ifr_name[i] - '0'; } } /* Verify the ppa. */ if (us->ppa->ppa_id != n) break; ppa = us->ppa; /* Set up the netstat block. */ strncpy (ppa->ifname, us->ifname, IFNAMSIZ); ppa->ifstats.ifs_name = ppa->ifname; ppa->ifstats.ifs_unit = n; ppa->ifstats.ifs_active = us->state != DL_UNBOUND; ppa->ifstats.ifs_mtu = ppa->mtu; /* Link in statistics used by netstat. */ ppa->ifstats.ifs_next = ifstats; ifstats = &ppa->ifstats; iop->ioc_count = 0; error = 0; break; case SIOCGIFFLAGS: if (!(us->flags & US_CONTROL)) { if (us->ppa) us = us->ppa; else break; } ((struct iocblk_in *)iop)->ioc_ifflags = us->ifflags; error = 0; break; case SIOCSIFFLAGS: if (!(us->flags & US_CONTROL)) { if (us->ppa) us = us->ppa; else break; } us->ifflags = ((struct iocblk_in *)iop)->ioc_ifflags; error = 0; break; case SIOCSIFADDR: if (!(us->flags & US_CONTROL)) { if (us->ppa) us = us->ppa; else break; } us->ifflags |= IFF_RUNNING; ((struct iocblk_in *)iop)->ioc_ifflags |= IFF_RUNNING; error = 0; break; case SIOCSIFMTU: /* * Vanilla SVR4 systems don't handle SIOCSIFMTU, rather * they take the MTU from the DL_INFO_ACK we sent in response * to their DL_INFO_REQ. Fortunately, they will update the * MTU if we send an unsolicited DL_INFO_ACK up. */ if ((mq = allocb(sizeof(dl_info_req_t), BPRI_HI)) == 0) break; /* should do bufcall */ ((union DL_primitives *)mq->b_rptr)->dl_primitive = DL_INFO_REQ; mq->b_wptr = mq->b_rptr + sizeof(dl_info_req_t); dlpi_request(q, mq, us); /* mp is now gone */ error = -1; break; case SIOCGIFNETMASK: case SIOCSIFNETMASK: case SIOCGIFADDR: case SIOCGIFDSTADDR: case SIOCSIFDSTADDR: case SIOCGIFMETRIC: error = 0; break; #endif /* LACHTCP */ default: if (us->ppa == 0 || us->ppa->lowerq == 0) break; us->ioc_id = iop->ioc_id; error = -1; switch (iop->ioc_cmd) { case PPPIO_GETSTAT: case PPPIO_GETCSTAT: if (us->flags & US_LASTMOD) { error = EINVAL; break; } putnext(us->ppa->lowerq, mp); break; default: if (us->flags & US_PRIV) putnext(us->ppa->lowerq, mp); else { DPRINT1("ppp ioctl %x rejected\n", iop->ioc_cmd); error = EPERM; } break; } break; } if (error > 0) { iop->ioc_error = error; mp->b_datap->db_type = M_IOCNAK; qreply(q, mp); } else if (error == 0) { mp->b_datap->db_type = M_IOCACK; qreply(q, mp); } break; case M_FLUSH: if (us->flags & US_DBGLOG) DPRINT2("ppp/%d: flush %x\n", us->mn, *mp->b_rptr); if (*mp->b_rptr & FLUSHW) flushq(q, FLUSHDATA); if (*mp->b_rptr & FLUSHR) { *mp->b_rptr &= ~FLUSHW; qreply(q, mp); } else freemsg(mp); break; default: freemsg(mp); break; } return 0; } #ifndef NO_DLPI static void dlpi_request(q, mp, us) queue_t *q; mblk_t *mp; upperstr_t *us; { union DL_primitives *d = (union DL_primitives *) mp->b_rptr; int size = mp->b_wptr - mp->b_rptr; mblk_t *reply, *np; upperstr_t *ppa, *os; int sap, len; dl_info_ack_t *info; dl_bind_ack_t *ackp; #if DL_CURRENT_VERSION >= 2 dl_phys_addr_ack_t *paddrack; static struct ether_addr eaddr = {0}; #endif if (us->flags & US_DBGLOG) DPRINT3("ppp/%d: dlpi prim %x len=%d\n", us->mn, d->dl_primitive, size); switch (d->dl_primitive) { case DL_INFO_REQ: if (size < sizeof(dl_info_req_t)) goto badprim; if ((reply = allocb(sizeof(dl_info_ack_t), BPRI_HI)) == 0) break; /* should do bufcall */ reply->b_datap->db_type = M_PCPROTO; info = (dl_info_ack_t *) reply->b_wptr; reply->b_wptr += sizeof(dl_info_ack_t); bzero((caddr_t) info, sizeof(dl_info_ack_t)); info->dl_primitive = DL_INFO_ACK; info->dl_max_sdu = us->ppa? us->ppa->mtu: PPP_MAXMTU; info->dl_min_sdu = 1; info->dl_addr_length = sizeof(uint); info->dl_mac_type = DL_ETHER; /* a bigger lie */ info->dl_current_state = us->state; info->dl_service_mode = DL_CLDLS; info->dl_provider_style = DL_STYLE2; #if DL_CURRENT_VERSION >= 2 info->dl_sap_length = sizeof(uint); info->dl_version = DL_CURRENT_VERSION; #endif qreply(q, reply); break; case DL_ATTACH_REQ: if (size < sizeof(dl_attach_req_t)) goto badprim; if (us->state != DL_UNATTACHED || us->ppa != 0) { dlpi_error(q, us, DL_ATTACH_REQ, DL_OUTSTATE, 0); break; } for (ppa = ppas; ppa != 0; ppa = ppa->nextppa) if (ppa->ppa_id == d->attach_req.dl_ppa) break; if (ppa == 0) { dlpi_error(q, us, DL_ATTACH_REQ, DL_BADPPA, 0); break; } us->ppa = ppa; qwriter(q, mp, attach_ppa, PERIM_OUTER); return; case DL_DETACH_REQ: if (size < sizeof(dl_detach_req_t)) goto badprim; if (us->state != DL_UNBOUND || us->ppa == 0) { dlpi_error(q, us, DL_DETACH_REQ, DL_OUTSTATE, 0); break; } qwriter(q, mp, detach_ppa, PERIM_OUTER); return; case DL_BIND_REQ: if (size < sizeof(dl_bind_req_t)) goto badprim; if (us->state != DL_UNBOUND || us->ppa == 0) { dlpi_error(q, us, DL_BIND_REQ, DL_OUTSTATE, 0); break; } #if 0 /* apparently this test fails (unnecessarily?) on some systems */ if (d->bind_req.dl_service_mode != DL_CLDLS) { dlpi_error(q, us, DL_BIND_REQ, DL_UNSUPPORTED, 0); break; } #endif /* saps must be valid PPP network protocol numbers, except that we accept ETHERTYPE_IP in place of PPP_IP. */ sap = d->bind_req.dl_sap; us->req_sap = sap; #if defined(SOL2) if (us->flags & US_DBGLOG) DPRINT2("DL_BIND_REQ: ip gives sap = 0x%x, us = 0x%x", sap, us); if (sap == ETHERTYPE_IP) /* normal IFF_IPV4 */ sap = PPP_IP; else if (sap == ETHERTYPE_IPV6) /* when IFF_IPV6 is set */ sap = PPP_IPV6; else if (sap == ETHERTYPE_ALLSAP) /* snoop gives sap of 0 */ sap = PPP_ALLSAP; else { DPRINT2("DL_BIND_REQ: unrecognized sap = 0x%x, us = 0x%x", sap, us); dlpi_error(q, us, DL_BIND_REQ, DL_BADADDR, 0); break; } #else if (sap == ETHERTYPE_IP) sap = PPP_IP; if (sap < 0x21 || sap > 0x3fff || (sap & 0x101) != 1) { dlpi_error(q, us, DL_BIND_REQ, DL_BADADDR, 0); break; } #endif /* defined(SOL2) */ /* check that no other stream is bound to this sap already. */ for (os = us->ppa; os != 0; os = os->next) if (os->sap == sap) break; if (os != 0) { dlpi_error(q, us, DL_BIND_REQ, DL_NOADDR, 0); break; } us->sap = sap; us->state = DL_IDLE; if ((reply = allocb(sizeof(dl_bind_ack_t) + sizeof(uint), BPRI_HI)) == 0) break; /* should do bufcall */ ackp = (dl_bind_ack_t *) reply->b_wptr; reply->b_wptr += sizeof(dl_bind_ack_t) + sizeof(uint); reply->b_datap->db_type = M_PCPROTO; bzero((caddr_t) ackp, sizeof(dl_bind_ack_t)); ackp->dl_primitive = DL_BIND_ACK; ackp->dl_sap = sap; ackp->dl_addr_length = sizeof(uint); ackp->dl_addr_offset = sizeof(dl_bind_ack_t); *(uint *)(ackp+1) = sap; qreply(q, reply); break; case DL_UNBIND_REQ: if (size < sizeof(dl_unbind_req_t)) goto badprim; if (us->state != DL_IDLE) { dlpi_error(q, us, DL_UNBIND_REQ, DL_OUTSTATE, 0); break; } us->sap = -1; us->state = DL_UNBOUND; #ifdef LACHTCP us->ppa->ifstats.ifs_active = 0; #endif dlpi_ok(q, DL_UNBIND_REQ); break; case DL_UNITDATA_REQ: if (size < sizeof(dl_unitdata_req_t)) goto badprim; if (us->state != DL_IDLE) { dlpi_error(q, us, DL_UNITDATA_REQ, DL_OUTSTATE, 0); break; } if ((ppa = us->ppa) == 0) { cmn_err(CE_CONT, "ppp: in state dl_idle but ppa == 0?\n"); break; } len = mp->b_cont == 0? 0: msgdsize(mp->b_cont); if (len > ppa->mtu) { DPRINT2("dlpi data too large (%d > %d)\n", len, ppa->mtu); break; } #if defined(SOL2) /* * Should there be any promiscuous stream(s), send the data * up for each promiscuous stream that we recognize. */ if (mp->b_cont) promisc_sendup(ppa, mp->b_cont, us->sap, 0); #endif /* defined(SOL2) */ mp->b_band = 0; #ifdef PRIOQ /* Extract s_port & d_port from IP-packet, the code is a bit dirty here, but so am I, too... */ if (mp->b_datap->db_type == M_PROTO && us->sap == PPP_IP && mp->b_cont != 0) { u_char *bb, *tlh; int iphlen, len; u_short *ptr; u_char band_unset, cur_band, syn; u_short s_port, d_port; bb = mp->b_cont->b_rptr; /* bb points to IP-header*/ len = mp->b_cont->b_wptr - mp->b_cont->b_rptr; syn = 0; s_port = IPPORT_DEFAULT; d_port = IPPORT_DEFAULT; if (len >= 20) { /* 20 = minimum length of IP header */ iphlen = (bb[0] & 0x0f) * 4; tlh = bb + iphlen; len -= iphlen; switch (bb[9]) { case IPPROTO_TCP: if (len >= 20) { /* min length of TCP header */ s_port = (tlh[0] << 8) + tlh[1]; d_port = (tlh[2] << 8) + tlh[3]; syn = tlh[13] & 0x02; } break; case IPPROTO_UDP: if (len >= 8) { /* min length of UDP header */ s_port = (tlh[0] << 8) + tlh[1]; d_port = (tlh[2] << 8) + tlh[3]; } break; } } /* * Now calculate b_band for this packet from the * port-priority table. */ ptr = prioq_table; cur_band = max_band; band_unset = 1; while (*ptr) { while (*ptr && band_unset) if (s_port == *ptr || d_port == *ptr++) { mp->b_band = cur_band; band_unset = 0; break; } ptr++; cur_band--; } if (band_unset) mp->b_band = def_band; /* It may be usable to urge SYN packets a bit */ if (syn) mp->b_band++; } #endif /* PRIOQ */ /* this assumes PPP_HDRLEN <= sizeof(dl_unitdata_req_t) */ if (mp->b_datap->db_ref > 1) { np = allocb(PPP_HDRLEN, BPRI_HI); if (np == 0) break; /* gak! */ np->b_cont = mp->b_cont; mp->b_cont = 0; freeb(mp); mp = np; } else mp->b_datap->db_type = M_DATA; /* XXX should use dl_dest_addr_offset/length here, but we would have to translate ETHERTYPE_IP -> PPP_IP */ mp->b_wptr = mp->b_rptr + PPP_HDRLEN; mp->b_rptr[0] = PPP_ALLSTATIONS; mp->b_rptr[1] = PPP_UI; mp->b_rptr[2] = us->sap >> 8; mp->b_rptr[3] = us->sap; /* pass_packet frees the packet on returning 0 */ if (pass_packet(us, mp, 1)) { if (!send_data(mp, us) && !putq(q, mp)) freemsg(mp); } return; #if DL_CURRENT_VERSION >= 2 case DL_PHYS_ADDR_REQ: if (size < sizeof(dl_phys_addr_req_t)) goto badprim; /* * Don't check state because ifconfig sends this one down too */ if ((reply = allocb(sizeof(dl_phys_addr_ack_t)+ETHERADDRL, BPRI_HI)) == 0) break; /* should do bufcall */ reply->b_datap->db_type = M_PCPROTO; paddrack = (dl_phys_addr_ack_t *) reply->b_wptr; reply->b_wptr += sizeof(dl_phys_addr_ack_t); bzero((caddr_t) paddrack, sizeof(dl_phys_addr_ack_t)+ETHERADDRL); paddrack->dl_primitive = DL_PHYS_ADDR_ACK; paddrack->dl_addr_length = ETHERADDRL; paddrack->dl_addr_offset = sizeof(dl_phys_addr_ack_t); bcopy(&eaddr, reply->b_wptr, ETHERADDRL); reply->b_wptr += ETHERADDRL; qreply(q, reply); break; #if defined(SOL2) case DL_PROMISCON_REQ: if (size < sizeof(dl_promiscon_req_t)) goto badprim; us->flags |= US_PROMISC; dlpi_ok(q, DL_PROMISCON_REQ); break; case DL_PROMISCOFF_REQ: if (size < sizeof(dl_promiscoff_req_t)) goto badprim; us->flags &= ~US_PROMISC; dlpi_ok(q, DL_PROMISCOFF_REQ); break; #else case DL_PROMISCON_REQ: /* fall thru */ case DL_PROMISCOFF_REQ: /* fall thru */ #endif /* defined(SOL2) */ #endif /* DL_CURRENT_VERSION >= 2 */ #if DL_CURRENT_VERSION >= 2 case DL_SET_PHYS_ADDR_REQ: case DL_SUBS_BIND_REQ: case DL_SUBS_UNBIND_REQ: case DL_ENABMULTI_REQ: case DL_DISABMULTI_REQ: case DL_XID_REQ: case DL_TEST_REQ: case DL_REPLY_UPDATE_REQ: case DL_REPLY_REQ: case DL_DATA_ACK_REQ: #endif case DL_CONNECT_REQ: case DL_TOKEN_REQ: dlpi_error(q, us, d->dl_primitive, DL_NOTSUPPORTED, 0); break; case DL_CONNECT_RES: case DL_DISCONNECT_REQ: case DL_RESET_REQ: case DL_RESET_RES: dlpi_error(q, us, d->dl_primitive, DL_OUTSTATE, 0); break; case DL_UDQOS_REQ: dlpi_error(q, us, d->dl_primitive, DL_BADQOSTYPE, 0); break; #if DL_CURRENT_VERSION >= 2 case DL_TEST_RES: case DL_XID_RES: break; #endif default: if (us->flags & US_DBGLOG) DPRINT1("ppp: unknown dlpi prim 0x%x\n", d->dl_primitive); /* fall through */ badprim: dlpi_error(q, us, d->dl_primitive, DL_BADPRIM, 0); break; } freemsg(mp); } static void dlpi_error(q, us, prim, err, uerr) queue_t *q; upperstr_t *us; int prim, err, uerr; { mblk_t *reply; dl_error_ack_t *errp; if (us->flags & US_DBGLOG) DPRINT3("ppp/%d: dlpi error, prim=%x, err=%x\n", us->mn, prim, err); reply = allocb(sizeof(dl_error_ack_t), BPRI_HI); if (reply == 0) return; /* XXX should do bufcall */ reply->b_datap->db_type = M_PCPROTO; errp = (dl_error_ack_t *) reply->b_wptr; reply->b_wptr += sizeof(dl_error_ack_t); errp->dl_primitive = DL_ERROR_ACK; errp->dl_error_primitive = prim; errp->dl_errno = err; errp->dl_unix_errno = uerr; qreply(q, reply); } static void dlpi_ok(q, prim) queue_t *q; int prim; { mblk_t *reply; dl_ok_ack_t *okp; reply = allocb(sizeof(dl_ok_ack_t), BPRI_HI); if (reply == 0) return; /* XXX should do bufcall */ reply->b_datap->db_type = M_PCPROTO; okp = (dl_ok_ack_t *) reply->b_wptr; reply->b_wptr += sizeof(dl_ok_ack_t); okp->dl_primitive = DL_OK_ACK; okp->dl_correct_primitive = prim; qreply(q, reply); } #endif /* NO_DLPI */ /* * If return value is 0, then the packet has already been freed. */ static int pass_packet(us, mp, outbound) upperstr_t *us; mblk_t *mp; int outbound; { int pass; upperstr_t *ppa; if ((ppa = us->ppa) == 0) { freemsg(mp); return 0; } #ifdef FILTER_PACKETS pass = ip_hard_filter(us, mp, outbound); #else /* * Here is where we might, in future, decide whether to pass * or drop the packet, and whether it counts as link activity. */ pass = 1; #endif /* FILTER_PACKETS */ if (pass < 0) { /* pass only if link already up, and don't update time */ if (ppa->lowerq == 0) { freemsg(mp); return 0; } pass = 1; } else if (pass) { if (outbound) ppa->last_sent = time; else ppa->last_recv = time; } return pass; } /* * We have some data to send down to the lower stream (or up the * control stream, if we don't have a lower stream attached). * Returns 1 if the message was dealt with, 0 if it wasn't able * to be sent on and should therefore be queued up. */ static int send_data(mp, us) mblk_t *mp; upperstr_t *us; { upperstr_t *ppa; if ((us->flags & US_BLOCKED) || us->npmode == NPMODE_QUEUE) return 0; ppa = us->ppa; if (ppa == 0 || us->npmode == NPMODE_DROP || us->npmode == NPMODE_ERROR) { if (us->flags & US_DBGLOG) DPRINT2("ppp/%d: dropping pkt (npmode=%d)\n", us->mn, us->npmode); freemsg(mp); return 1; } if (ppa->lowerq == 0) { /* try to send it up the control stream */ if (bcanputnext(ppa->q, mp->b_band)) { /* * The message seems to get corrupted for some reason if * we just send the message up as it is, so we send a copy. */ mblk_t *np = copymsg(mp); freemsg(mp); if (np != 0) putnext(ppa->q, np); return 1; } } else { if (bcanputnext(ppa->lowerq, mp->b_band)) { MT_ENTER(&ppa->stats_lock); ppa->stats.ppp_opackets++; ppa->stats.ppp_obytes += msgdsize(mp); #ifdef INCR_OPACKETS INCR_OPACKETS(ppa); #endif MT_EXIT(&ppa->stats_lock); /* * The lower queue is only ever detached while holding an * exclusive lock on the whole driver. So we can be confident * that the lower queue is still there. */ putnext(ppa->lowerq, mp); return 1; } } us->flags |= US_BLOCKED; return 0; } /* * Allocate a new PPA id and link this stream into the list of PPAs. * This procedure is called with an exclusive lock on all queues in * this driver. */ static void new_ppa(q, mp) queue_t *q; mblk_t *mp; { upperstr_t *us, *up, **usp; int ppa_id; us = (upperstr_t *) q->q_ptr; if (us == 0) { DPRINT("new_ppa: q_ptr = 0!\n"); return; } usp = &ppas; ppa_id = 0; while ((up = *usp) != 0 && ppa_id == up->ppa_id) { ++ppa_id; usp = &up->nextppa; } us->ppa_id = ppa_id; us->ppa = us; us->next = 0; us->nextppa = *usp; *usp = us; us->flags |= US_CONTROL; us->npmode = NPMODE_PASS; us->mtu = PPP_MTU; us->mru = PPP_MRU; #ifdef SOL2 /* * Create a kstats record for our statistics, so netstat -i works. */ if (us->kstats == 0) { char unit[32]; sprintf(unit, "ppp%d", us->ppa->ppa_id); us->kstats = kstat_create("ppp", us->ppa->ppa_id, unit, "net", KSTAT_TYPE_NAMED, 4, 0); if (us->kstats != 0) { kstat_named_t *kn = KSTAT_NAMED_PTR(us->kstats); strcpy(kn[0].name, "ipackets"); kn[0].data_type = KSTAT_DATA_ULONG; strcpy(kn[1].name, "ierrors"); kn[1].data_type = KSTAT_DATA_ULONG; strcpy(kn[2].name, "opackets"); kn[2].data_type = KSTAT_DATA_ULONG; strcpy(kn[3].name, "oerrors"); kn[3].data_type = KSTAT_DATA_ULONG; kstat_install(us->kstats); } } #endif /* SOL2 */ *(int *)mp->b_cont->b_rptr = ppa_id; mp->b_datap->db_type = M_IOCACK; qreply(q, mp); } static void attach_ppa(q, mp) queue_t *q; mblk_t *mp; { upperstr_t *us, *t; us = (upperstr_t *) q->q_ptr; if (us == 0) { DPRINT("attach_ppa: q_ptr = 0!\n"); return; } #ifndef NO_DLPI us->state = DL_UNBOUND; #endif for (t = us->ppa; t->next != 0; t = t->next) ; t->next = us; us->next = 0; if (mp->b_datap->db_type == M_IOCTL) { mp->b_datap->db_type = M_IOCACK; qreply(q, mp); } else { #ifndef NO_DLPI dlpi_ok(q, DL_ATTACH_REQ); #endif freemsg(mp); } } #ifndef NO_DLPI static void detach_ppa(q, mp) queue_t *q; mblk_t *mp; { upperstr_t *us, *t; us = (upperstr_t *) q->q_ptr; if (us == 0) { DPRINT("detach_ppa: q_ptr = 0!\n"); return; } for (t = us->ppa; t->next != 0; t = t->next) if (t->next == us) { t->next = us->next; break; } us->next = 0; us->ppa = 0; us->state = DL_UNATTACHED; dlpi_ok(q, DL_DETACH_REQ); freemsg(mp); } #endif /* * We call this with qwriter in order to give the upper queue procedures * the guarantee that the lower queue is not going to go away while * they are executing. */ static void detach_lower(q, mp) queue_t *q; mblk_t *mp; { upperstr_t *us; us = (upperstr_t *) q->q_ptr; if (us == 0) { DPRINT("detach_lower: q_ptr = 0!\n"); return; } LOCK_LOWER_W; us->lowerq->q_ptr = 0; RD(us->lowerq)->q_ptr = 0; us->lowerq = 0; UNLOCK_LOWER; /* Unblock streams which now feed back up the control stream. */ qenable(us->q); mp->b_datap->db_type = M_IOCACK; qreply(q, mp); } static int pppuwsrv(q) queue_t *q; { upperstr_t *us, *as; mblk_t *mp; us = (upperstr_t *) q->q_ptr; if (us == 0) { DPRINT("pppuwsrv: q_ptr = 0!\n"); return 0; } /* * If this is a control stream, then this service procedure * probably got enabled because of flow control in the lower * stream being enabled (or because of the lower stream going * away). Therefore we enable the service procedure of all * attached upper streams. */ if (us->flags & US_CONTROL) { for (as = us->next; as != 0; as = as->next) qenable(WR(as->q)); } /* Try to send on any data queued here. */ us->flags &= ~US_BLOCKED; while ((mp = getq(q)) != 0) { if (!send_data(mp, us)) { putbq(q, mp); break; } } return 0; } /* should never get called... */ static int ppplwput(q, mp) queue_t *q; mblk_t *mp; { putnext(q, mp); return 0; } static int ppplwsrv(q) queue_t *q; { queue_t *uq; /* * Flow control has back-enabled this stream: * enable the upper write service procedure for * the upper control stream for this lower stream. */ LOCK_LOWER_R; uq = (queue_t *) q->q_ptr; if (uq != 0) qenable(uq); UNLOCK_LOWER; return 0; } /* * This should only get called for control streams. */ static int pppurput(q, mp) queue_t *q; mblk_t *mp; { upperstr_t *ppa, *us; int proto, len; struct iocblk *iop; ppa = (upperstr_t *) q->q_ptr; if (ppa == 0) { DPRINT("pppurput: q_ptr = 0!\n"); return 0; } switch (mp->b_datap->db_type) { case M_CTL: MT_ENTER(&ppa->stats_lock); switch (*mp->b_rptr) { case PPPCTL_IERROR: #ifdef INCR_IERRORS INCR_IERRORS(ppa); #endif ppa->stats.ppp_ierrors++; break; case PPPCTL_OERROR: #ifdef INCR_OERRORS INCR_OERRORS(ppa); #endif ppa->stats.ppp_oerrors++; break; } MT_EXIT(&ppa->stats_lock); freemsg(mp); break; case M_IOCACK: case M_IOCNAK: /* * Attempt to match up the response with the stream * that the request came from. */ iop = (struct iocblk *) mp->b_rptr; for (us = ppa; us != 0; us = us->next) if (us->ioc_id == iop->ioc_id) break; if (us == 0) freemsg(mp); else putnext(us->q, mp); break; case M_HANGUP: /* * The serial device has hung up. We don't want to send * the M_HANGUP message up to pppd because that will stop * us from using the control stream any more. Instead we * send a zero-length message as an end-of-file indication. */ freemsg(mp); mp = allocb(1, BPRI_HI); if (mp == 0) { DPRINT1("ppp/%d: couldn't allocate eof message!\n", ppa->mn); break; } putnext(ppa->q, mp); break; case M_DATA: len = msgdsize(mp); if (mp->b_wptr - mp->b_rptr < PPP_HDRLEN) { PULLUP(mp, PPP_HDRLEN); if (mp == 0) { DPRINT1("ppp_urput: msgpullup failed (len=%d)\n", len); break; } } MT_ENTER(&ppa->stats_lock); ppa->stats.ppp_ipackets++; ppa->stats.ppp_ibytes += len; #ifdef INCR_IPACKETS INCR_IPACKETS(ppa); #endif MT_EXIT(&ppa->stats_lock); proto = PPP_PROTOCOL(mp->b_rptr); #if defined(SOL2) /* * Should there be any promiscuous stream(s), send the data * up for each promiscuous stream that we recognize. */ promisc_sendup(ppa, mp, proto, 1); #endif /* defined(SOL2) */ if (proto < 0x8000 && (us = find_dest(ppa, proto)) != 0) { /* * A data packet for some network protocol. * Queue it on the upper stream for that protocol. * XXX could we just putnext it? (would require thought) * The rblocked flag is there to ensure that we keep * messages in order for each network protocol. */ /* pass_packet frees the packet on returning 0 */ if (!pass_packet(us, mp, 0)) break; if (!us->rblocked && !canput(us->q)) us->rblocked = 1; if (!putq(us->rblocked ? q : us->q, mp)) freemsg(mp); break; } /* FALLTHROUGH */ default: /* * A control frame, a frame for an unknown protocol, * or some other message type. * Send it up to pppd via the control stream. */ if (queclass(mp) == QPCTL || canputnext(ppa->q)) putnext(ppa->q, mp); else if (!putq(q, mp)) freemsg(mp); break; } return 0; } static int pppursrv(q) queue_t *q; { upperstr_t *us, *as; mblk_t *mp, *hdr; #ifndef NO_DLPI dl_unitdata_ind_t *ud; #endif int proto; us = (upperstr_t *) q->q_ptr; if (us == 0) { DPRINT("pppursrv: q_ptr = 0!\n"); return 0; } if (us->flags & US_CONTROL) { /* * A control stream. * If there is no lower queue attached, run the write service * routines of other upper streams attached to this PPA. */ if (us->lowerq == 0) { as = us; do { if (as->flags & US_BLOCKED) qenable(WR(as->q)); as = as->next; } while (as != 0); } /* * Messages get queued on this stream's read queue if they * can't be queued on the read queue of the attached stream * that they are destined for. This is for flow control - * when this queue fills up, the lower read put procedure will * queue messages there and the flow control will propagate * down from there. */ while ((mp = getq(q)) != 0) { proto = PPP_PROTOCOL(mp->b_rptr); if (proto < 0x8000 && (as = find_dest(us, proto)) != 0) { if (!canput(as->q)) break; if (!putq(as->q, mp)) freemsg(mp); } else { if (!canputnext(q)) break; putnext(q, mp); } } if (mp) { putbq(q, mp); } else { /* can now put stuff directly on network protocol streams again */ for (as = us->next; as != 0; as = as->next) as->rblocked = 0; } /* * If this stream has a lower stream attached, * enable the read queue's service routine. * XXX we should really only do this if the queue length * has dropped below the low-water mark. */ if (us->lowerq != 0) qenable(RD(us->lowerq)); } else { /* * A network protocol stream. Put a DLPI header on each * packet and send it on. * (Actually, it seems that the IP module will happily * accept M_DATA messages without the DL_UNITDATA_IND header.) */ while ((mp = getq(q)) != 0) { if (!canputnext(q)) { putbq(q, mp); break; } #ifndef NO_DLPI proto = PPP_PROTOCOL(mp->b_rptr); mp->b_rptr += PPP_HDRLEN; hdr = allocb(sizeof(dl_unitdata_ind_t) + 2 * sizeof(uint), BPRI_MED); if (hdr == 0) { /* XXX should put it back and use bufcall */ freemsg(mp); continue; } hdr->b_datap->db_type = M_PROTO; ud = (dl_unitdata_ind_t *) hdr->b_wptr; hdr->b_wptr += sizeof(dl_unitdata_ind_t) + 2 * sizeof(uint); hdr->b_cont = mp; ud->dl_primitive = DL_UNITDATA_IND; ud->dl_dest_addr_length = sizeof(uint); ud->dl_dest_addr_offset = sizeof(dl_unitdata_ind_t); ud->dl_src_addr_length = sizeof(uint); ud->dl_src_addr_offset = ud->dl_dest_addr_offset + sizeof(uint); #if DL_CURRENT_VERSION >= 2 ud->dl_group_address = 0; #endif /* Send the DLPI client the data with the SAP they requested, (e.g. ETHERTYPE_IP) rather than the PPP protocol number (e.g. PPP_IP) */ ((uint *)(ud + 1))[0] = us->req_sap; /* dest SAP */ ((uint *)(ud + 1))[1] = us->req_sap; /* src SAP */ putnext(q, hdr); #else /* NO_DLPI */ putnext(q, mp); #endif /* NO_DLPI */ } /* * Now that we have consumed some packets from this queue, * enable the control stream's read service routine so that we * can process any packets for us that might have got queued * there for flow control reasons. */ if (us->ppa) qenable(us->ppa->q); } return 0; } static upperstr_t * find_dest(ppa, proto) upperstr_t *ppa; int proto; { upperstr_t *us; for (us = ppa->next; us != 0; us = us->next) if (proto == us->sap) break; return us; } #if defined (SOL2) /* * Test upstream promiscuous conditions. As of now, only pass IPv4 and * Ipv6 packets upstream (let PPP packets be decoded elsewhere). */ static upperstr_t * find_promisc(us, proto) upperstr_t *us; int proto; { if ((proto != PPP_IP) && (proto != PPP_IPV6)) return (upperstr_t *)0; for ( ; us; us = us->next) { if ((us->flags & US_PROMISC) && (us->state == DL_IDLE)) return us; } return (upperstr_t *)0; } /* * Prepend an empty Ethernet header to msg for snoop, et al. */ static mblk_t * prepend_ether(us, mp, proto) upperstr_t *us; mblk_t *mp; int proto; { mblk_t *eh; int type; if ((eh = allocb(sizeof(struct ether_header), BPRI_HI)) == 0) { freemsg(mp); return (mblk_t *)0; } if (proto == PPP_IP) type = ETHERTYPE_IP; else if (proto == PPP_IPV6) type = ETHERTYPE_IPV6; else type = proto; /* What else? Let decoder decide */ eh->b_wptr += sizeof(struct ether_header); bzero((caddr_t)eh->b_rptr, sizeof(struct ether_header)); ((struct ether_header *)eh->b_rptr)->ether_type = htons((short)type); eh->b_cont = mp; return (eh); } /* * Prepend DL_UNITDATA_IND mblk to msg */ static mblk_t * prepend_udind(us, mp, proto) upperstr_t *us; mblk_t *mp; int proto; { dl_unitdata_ind_t *dlu; mblk_t *dh; size_t size; size = sizeof(dl_unitdata_ind_t); if ((dh = allocb(size, BPRI_MED)) == 0) { freemsg(mp); return (mblk_t *)0; } dh->b_datap->db_type = M_PROTO; dh->b_wptr = dh->b_datap->db_lim; dh->b_rptr = dh->b_wptr - size; dlu = (dl_unitdata_ind_t *)dh->b_rptr; dlu->dl_primitive = DL_UNITDATA_IND; dlu->dl_dest_addr_length = 0; dlu->dl_dest_addr_offset = sizeof(dl_unitdata_ind_t); dlu->dl_src_addr_length = 0; dlu->dl_src_addr_offset = sizeof(dl_unitdata_ind_t); dlu->dl_group_address = 0; dh->b_cont = mp; return (dh); } /* * For any recognized promiscuous streams, send data upstream */ static void promisc_sendup(ppa, mp, proto, skip) upperstr_t *ppa; mblk_t *mp; int proto, skip; { mblk_t *dup_mp, *dup_dup_mp; upperstr_t *prus, *nprus; if ((prus = find_promisc(ppa, proto)) != 0) { if (dup_mp = dupmsg(mp)) { if (skip) dup_mp->b_rptr += PPP_HDRLEN; for ( ; nprus = find_promisc(prus->next, proto); prus = nprus) { if (dup_dup_mp = dupmsg(dup_mp)) { if (canputnext(prus->q)) { if (prus->flags & US_RAWDATA) { dup_dup_mp = prepend_ether(prus, dup_dup_mp, proto); } else { dup_dup_mp = prepend_udind(prus, dup_dup_mp, proto); } if (dup_dup_mp == 0) continue; putnext(prus->q, dup_dup_mp); } else { DPRINT("ppp_urput: data to promisc q dropped\n"); freemsg(dup_dup_mp); } } } if (canputnext(prus->q)) { if (prus->flags & US_RAWDATA) { dup_mp = prepend_ether(prus, dup_mp, proto); } else { dup_mp = prepend_udind(prus, dup_mp, proto); } if (dup_mp != 0) putnext(prus->q, dup_mp); } else { DPRINT("ppp_urput: data to promisc q dropped\n"); freemsg(dup_mp); } } } } #endif /* defined(SOL2) */ /* * We simply put the message on to the associated upper control stream * (either here or in ppplrsrv). That way we enter the perimeters * before looking through the list of attached streams to decide which * stream it should go up. */ static int ppplrput(q, mp) queue_t *q; mblk_t *mp; { queue_t *uq; struct iocblk *iop; switch (mp->b_datap->db_type) { case M_IOCTL: iop = (struct iocblk *) mp->b_rptr; iop->ioc_error = EINVAL; mp->b_datap->db_type = M_IOCNAK; qreply(q, mp); return 0; case M_FLUSH: if (*mp->b_rptr & FLUSHR) flushq(q, FLUSHDATA); if (*mp->b_rptr & FLUSHW) { *mp->b_rptr &= ~FLUSHR; qreply(q, mp); } else freemsg(mp); return 0; } /* * If we can't get the lower lock straight away, queue this one * rather than blocking, to avoid the possibility of deadlock. */ if (!TRYLOCK_LOWER_R) { if (!putq(q, mp)) freemsg(mp); return 0; } /* * Check that we're still connected to the driver. */ uq = (queue_t *) q->q_ptr; if (uq == 0) { UNLOCK_LOWER; DPRINT1("ppplrput: q = %x, uq = 0??\n", q); freemsg(mp); return 0; } /* * Try to forward the message to the put routine for the upper * control stream for this lower stream. * If there are already messages queued here, queue this one so * they don't get out of order. */ if (queclass(mp) == QPCTL || (qsize(q) == 0 && canput(uq))) put(uq, mp); else if (!putq(q, mp)) freemsg(mp); UNLOCK_LOWER; return 0; } static int ppplrsrv(q) queue_t *q; { mblk_t *mp; queue_t *uq; /* * Packets get queued here for flow control reasons * or if the lrput routine couldn't get the lower lock * without blocking. */ LOCK_LOWER_R; uq = (queue_t *) q->q_ptr; if (uq == 0) { UNLOCK_LOWER; flushq(q, FLUSHALL); DPRINT1("ppplrsrv: q = %x, uq = 0??\n", q); return 0; } while ((mp = getq(q)) != 0) { if (queclass(mp) == QPCTL || canput(uq)) put(uq, mp); else { putbq(q, mp); break; } } UNLOCK_LOWER; return 0; } static int putctl2(q, type, code, val) queue_t *q; int type, code, val; { mblk_t *mp; mp = allocb(2, BPRI_HI); if (mp == 0) return 0; mp->b_datap->db_type = type; mp->b_wptr[0] = code; mp->b_wptr[1] = val; mp->b_wptr += 2; putnext(q, mp); return 1; } static int putctl4(q, type, code, val) queue_t *q; int type, code, val; { mblk_t *mp; mp = allocb(4, BPRI_HI); if (mp == 0) return 0; mp->b_datap->db_type = type; mp->b_wptr[0] = code; ((short *)mp->b_wptr)[1] = val; mp->b_wptr += 4; putnext(q, mp); return 1; } static void debug_dump(q, mp) queue_t *q; mblk_t *mp; { upperstr_t *us; queue_t *uq, *lq; DPRINT("ppp upper streams:\n"); for (us = minor_devs; us != 0; us = us->nextmn) { uq = us->q; DPRINT3(" %d: q=%x rlev=%d", us->mn, uq, (uq? qsize(uq): 0)); DPRINT3(" wlev=%d flags=0x%b", (uq? qsize(WR(uq)): 0), us->flags, "\020\1priv\2control\3blocked\4last"); DPRINT3(" state=%x sap=%x req_sap=%x", us->state, us->sap, us->req_sap); if (us->ppa == 0) DPRINT(" ppa=?\n"); else DPRINT1(" ppa=%d\n", us->ppa->ppa_id); if (us->flags & US_CONTROL) { lq = us->lowerq; DPRINT3(" control for %d lq=%x rlev=%d", us->ppa_id, lq, (lq? qsize(RD(lq)): 0)); DPRINT3(" wlev=%d mru=%d mtu=%d\n", (lq? qsize(lq): 0), us->mru, us->mtu); } } mp->b_datap->db_type = M_IOCACK; qreply(q, mp); } #ifdef FILTER_PACKETS #include #include #include #include #define MAX_IPHDR 128 /* max TCP/IP header size */ /* The following table contains a hard-coded list of protocol/port pairs. * Any matching packets are either discarded unconditionally, or, * if ok_if_link_up is non-zero when a connection does not currently exist * (i.e., they go through if the connection is present, but never initiate * a dial-out). * This idea came from a post by dm@garage.uun.org (David Mazieres) */ static struct pktfilt_tab { int proto; u_short port; u_short ok_if_link_up; } pktfilt_tab[] = { { IPPROTO_UDP, 520, 1 }, /* RIP, ok to pass if link is up */ { IPPROTO_UDP, 123, 1 }, /* NTP, don't keep up the link for it */ { -1, 0, 0 } /* terminator entry has port == -1 */ }; /* * Packet has already been freed if return value is 0. */ static int ip_hard_filter(us, mp, outbound) upperstr_t *us; mblk_t *mp; int outbound; { struct ip *ip; struct pktfilt_tab *pft; mblk_t *temp_mp; int proto; int len, hlen; /* Note, the PPP header has already been pulled up in all cases */ proto = PPP_PROTOCOL(mp->b_rptr); if (us->flags & US_DBGLOG) DPRINT3("ppp/%d: filter, proto=0x%x, out=%d\n", us->mn, proto, outbound); switch (proto) { case PPP_IP: if ((mp->b_wptr - mp->b_rptr) == PPP_HDRLEN && mp->b_cont != 0) { temp_mp = mp->b_cont; len = msgdsize(temp_mp); hlen = (len < MAX_IPHDR) ? len : MAX_IPHDR; PULLUP(temp_mp, hlen); if (temp_mp == 0) { DPRINT2("ppp/%d: filter, pullup next failed, len=%d\n", us->mn, hlen); mp->b_cont = 0; /* PULLUP() freed the rest */ freemsg(mp); return 0; } ip = (struct ip *)mp->b_cont->b_rptr; } else { len = msgdsize(mp); hlen = (len < (PPP_HDRLEN+MAX_IPHDR)) ? len : (PPP_HDRLEN+MAX_IPHDR); PULLUP(mp, hlen); if (mp == 0) { DPRINT2("ppp/%d: filter, pullup failed, len=%d\n", us->mn, hlen); return 0; } ip = (struct ip *)(mp->b_rptr + PPP_HDRLEN); } /* For IP traffic, certain packets (e.g., RIP) may be either * 1. ignored - dropped completely * 2. will not initiate a connection, but * will be passed if a connection is currently up. */ for (pft=pktfilt_tab; pft->proto != -1; pft++) { if (ip->ip_p == pft->proto) { switch(pft->proto) { case IPPROTO_UDP: if (((struct udphdr *) &((int *)ip)[ip->ip_hl])->uh_dport == htons(pft->port)) goto endfor; break; case IPPROTO_TCP: if (((struct tcphdr *) &((int *)ip)[ip->ip_hl])->th_dport == htons(pft->port)) goto endfor; break; } } } endfor: if (pft->proto != -1) { if (us->flags & US_DBGLOG) DPRINT3("ppp/%d: found IP pkt, proto=0x%x (%d)\n", us->mn, pft->proto, pft->port); /* Discard if not connected, or if not pass_with_link_up */ /* else, if link is up let go by, but don't update time */ if (pft->ok_if_link_up) return -1; freemsg(mp); return 0; } break; } /* end switch (proto) */ return 1; } #endif /* FILTER_PACKETS */ ppp-2.5.0/solaris/ppp_comp.c0000664000175000017500000006704413772533415012722 00000000000000/* * ppp_comp.c - STREAMS module for kernel-level compression and CCP support. * * Copyright (c) 1994 Paul Mackerras. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The name(s) of the authors of this software must not be used to * endorse or promote products derived from this software without * prior written permission. * * 4. Redistributions of any form whatsoever must retain the following * acknowledgment: * "This product includes software developed by Paul Mackerras * ". * * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * $Id: ppp_comp.c,v 1.3 2004/01/17 05:47:55 carlsonj Exp $ */ /* * This file is used under SVR4, Solaris 2, SunOS 4, and Digital UNIX. */ #include #include #include #include #ifdef SVR4 #include #include #include #else #include #ifdef __osf__ #include #endif #endif /* SVR4 */ #include #include #include "ppp_mod.h" #ifdef __osf__ #include #include #endif #include #include #include #include #define PACKETPTR mblk_t * #include MOD_OPEN_DECL(ppp_comp_open); MOD_CLOSE_DECL(ppp_comp_close); static int ppp_comp_rput(queue_t *, mblk_t *); static int ppp_comp_rsrv(queue_t *); static int ppp_comp_wput(queue_t *, mblk_t *); static int ppp_comp_wsrv(queue_t *); static void ppp_comp_ccp(queue_t *, mblk_t *, int); static int msg_byte(mblk_t *, unsigned int); /* Extract byte i of message mp. */ #define MSG_BYTE(mp, i) ((i) < (mp)->b_wptr - (mp)->b_rptr? (mp)->b_rptr[i]: \ msg_byte((mp), (i))) /* Is this LCP packet one we have to transmit using LCP defaults? */ #define LCP_USE_DFLT(mp) (1 <= (code = MSG_BYTE((mp), 4)) && code <= 7) #define PPP_COMP_ID 0xbadf static struct module_info minfo = { #ifdef PRIOQ PPP_COMP_ID, "ppp_comp", 0, INFPSZ, 16512, 16384, #else PPP_COMP_ID, "ppp_comp", 0, INFPSZ, 16384, 4096, #endif }; static struct qinit r_init = { ppp_comp_rput, ppp_comp_rsrv, ppp_comp_open, ppp_comp_close, NULL, &minfo, NULL }; static struct qinit w_init = { ppp_comp_wput, ppp_comp_wsrv, NULL, NULL, NULL, &minfo, NULL }; #if defined(SVR4) && !defined(SOL2) int pcmpdevflag = 0; #define ppp_compinfo pcmpinfo #endif struct streamtab ppp_compinfo = { &r_init, &w_init, NULL, NULL }; int ppp_comp_count; /* number of module instances in use */ #ifdef __osf__ static void ppp_comp_alloc(comp_state_t *); typedef struct memreq { unsigned char comp_opts[20]; int cmd; int thread_status; char *returned_mem; } memreq_t; #endif typedef struct comp_state { int flags; int mru; int mtu; int unit; struct compressor *xcomp; void *xstate; struct compressor *rcomp; void *rstate; struct vjcompress vj_comp; int vj_last_ierrors; struct pppstat stats; #ifdef __osf__ memreq_t memreq; thread_t thread; #endif } comp_state_t; #ifdef __osf__ extern task_t first_task; #endif /* Bits in flags are as defined in pppio.h. */ #define CCP_ERR (CCP_ERROR | CCP_FATALERROR) #define LAST_MOD 0x1000000 /* no ppp modules below us */ #define DBGLOG 0x2000000 /* log debugging stuff */ #define MAX_IPHDR 128 /* max TCP/IP header size */ #define MAX_VJHDR 20 /* max VJ compressed header size (?) */ #undef MIN /* just in case */ #define MIN(a, b) ((a) < (b)? (a): (b)) /* * List of compressors we know about. */ #if DO_BSD_COMPRESS extern struct compressor ppp_bsd_compress; #endif #if DO_DEFLATE extern struct compressor ppp_deflate, ppp_deflate_draft; #endif struct compressor *ppp_compressors[] = { #if DO_BSD_COMPRESS &ppp_bsd_compress, #endif #if DO_DEFLATE &ppp_deflate, &ppp_deflate_draft, #endif NULL }; /* * STREAMS module entry points. */ MOD_OPEN(ppp_comp_open) { comp_state_t *cp; #ifdef __osf__ thread_t thread; #endif if (q->q_ptr == NULL) { cp = (comp_state_t *) ALLOC_SLEEP(sizeof(comp_state_t)); if (cp == NULL) OPEN_ERROR(ENOSR); bzero((caddr_t)cp, sizeof(comp_state_t)); WR(q)->q_ptr = q->q_ptr = (caddr_t) cp; cp->mru = PPP_MRU; cp->mtu = PPP_MTU; cp->xstate = NULL; cp->rstate = NULL; vj_compress_init(&cp->vj_comp, -1); #ifdef __osf__ if (!(thread = kernel_thread_w_arg(first_task, ppp_comp_alloc, (void *)cp))) OPEN_ERROR(ENOSR); cp->thread = thread; #endif ++ppp_comp_count; qprocson(q); } return 0; } MOD_CLOSE(ppp_comp_close) { comp_state_t *cp; qprocsoff(q); cp = (comp_state_t *) q->q_ptr; if (cp != NULL) { if (cp->xstate != NULL) (*cp->xcomp->comp_free)(cp->xstate); if (cp->rstate != NULL) (*cp->rcomp->decomp_free)(cp->rstate); #ifdef __osf__ if (!cp->thread) printf("ppp_comp_close: NULL thread!\n"); else thread_terminate(cp->thread); #endif FREE(cp, sizeof(comp_state_t)); q->q_ptr = NULL; OTHERQ(q)->q_ptr = NULL; --ppp_comp_count; } return 0; } #ifdef __osf__ /* thread for calling back to a compressor's memory allocator * Needed for Digital UNIX since it's VM can't handle requests * for large amounts of memory without blocking. The thread * provides a context in which we can call a memory allocator * that may block. */ static void ppp_comp_alloc(comp_state_t *cp) { int len, cmd; unsigned char *compressor_options; thread_t thread; void *(*comp_allocator)(); #if defined(MAJOR_VERSION) && (MAJOR_VERSION <= 2) /* In 2.x and earlier the argument gets passed * in the thread structure itself. Yuck. */ thread = current_thread(); cp = thread->reply_port; thread->reply_port = PORT_NULL; #endif for (;;) { assert_wait((vm_offset_t)&cp->memreq.thread_status, TRUE); thread_block(); if (thread_should_halt(current_thread())) thread_halt_self(); cmd = cp->memreq.cmd; compressor_options = &cp->memreq.comp_opts[0]; len = compressor_options[1]; if (cmd == PPPIO_XCOMP) { cp->memreq.returned_mem = cp->xcomp->comp_alloc(compressor_options, len); if (!cp->memreq.returned_mem) { cp->memreq.thread_status = ENOSR; } else { cp->memreq.thread_status = 0; } } else { cp->memreq.returned_mem = cp->rcomp->decomp_alloc(compressor_options, len); if (!cp->memreq.returned_mem) { cp->memreq.thread_status = ENOSR; } else { cp->memreq.thread_status = 0; } } } } #endif /* __osf__ */ /* here's the deal with memory allocation under Digital UNIX. * Some other may also benefit from this... * We can't ask for huge chunks of memory in a context where * the caller can't be put to sleep (like, here.) The alloc * is likely to fail. Instead we do this: the first time we * get called, kick off a thread to do the allocation. Return * immediately to the caller with EAGAIN, as an indication that * they should send down the ioctl again. By the time the * second call comes in it's likely that the memory allocation * thread will have returned with the requested memory. We will * continue to return EAGAIN however until the thread has completed. * When it has, we return zero (and the memory) if the allocator * was successful and ENOSR otherwise. * * Callers of the RCOMP and XCOMP ioctls are encouraged (but not * required) to loop for some number of iterations with a small * delay in the loop body (for instance a 1/10-th second "sleep" * via select.) */ static int ppp_comp_wput(q, mp) queue_t *q; mblk_t *mp; { struct iocblk *iop; comp_state_t *cp; int error, len, n; int flags, mask; mblk_t *np; struct compressor **comp; struct ppp_stats *psp; struct ppp_comp_stats *csp; unsigned char *opt_data; int nxslots, nrslots; cp = (comp_state_t *) q->q_ptr; if (cp == 0) { DPRINT("cp == 0 in ppp_comp_wput\n"); freemsg(mp); return 0; } switch (mp->b_datap->db_type) { case M_DATA: putq(q, mp); break; case M_IOCTL: iop = (struct iocblk *) mp->b_rptr; error = EINVAL; switch (iop->ioc_cmd) { case PPPIO_CFLAGS: /* set/get CCP state */ if (iop->ioc_count != 2 * sizeof(int)) break; if (mp->b_cont == 0) { DPRINT1("ppp_comp_wput/%d: PPPIO_CFLAGS b_cont = 0!\n", cp->unit); break; } flags = ((int *) mp->b_cont->b_rptr)[0]; mask = ((int *) mp->b_cont->b_rptr)[1]; cp->flags = (cp->flags & ~mask) | (flags & mask); if ((mask & CCP_ISOPEN) && (flags & CCP_ISOPEN) == 0) { if (cp->xstate != NULL) { (*cp->xcomp->comp_free)(cp->xstate); cp->xstate = NULL; } if (cp->rstate != NULL) { (*cp->rcomp->decomp_free)(cp->rstate); cp->rstate = NULL; } cp->flags &= ~CCP_ISUP; } error = 0; iop->ioc_count = sizeof(int); ((int *) mp->b_cont->b_rptr)[0] = cp->flags; mp->b_cont->b_wptr = mp->b_cont->b_rptr + sizeof(int); break; case PPPIO_VJINIT: /* * Initialize VJ compressor/decompressor */ if (iop->ioc_count != 2) break; if (mp->b_cont == 0) { DPRINT1("ppp_comp_wput/%d: PPPIO_VJINIT b_cont = 0!\n", cp->unit); break; } nxslots = mp->b_cont->b_rptr[0] + 1; nrslots = mp->b_cont->b_rptr[1] + 1; if (nxslots > MAX_STATES || nrslots > MAX_STATES) break; vj_compress_init(&cp->vj_comp, nxslots); cp->vj_last_ierrors = cp->stats.ppp_ierrors; error = 0; iop->ioc_count = 0; break; case PPPIO_XCOMP: case PPPIO_RCOMP: if (iop->ioc_count <= 0) break; if (mp->b_cont == 0) { DPRINT1("ppp_comp_wput/%d: PPPIO_[XR]COMP b_cont = 0!\n", cp->unit); break; } opt_data = mp->b_cont->b_rptr; len = mp->b_cont->b_wptr - opt_data; if (len > iop->ioc_count) len = iop->ioc_count; if (opt_data[1] < 2 || opt_data[1] > len) break; for (comp = ppp_compressors; *comp != NULL; ++comp) if ((*comp)->compress_proto == opt_data[0]) { /* here's the handler! */ error = 0; #ifndef __osf__ if (iop->ioc_cmd == PPPIO_XCOMP) { /* A previous call may have fetched memory for a compressor * that's now being retired or reset. Free it using it's * mechanism for freeing stuff. */ if (cp->xstate != NULL) { (*cp->xcomp->comp_free)(cp->xstate); cp->xstate = NULL; } cp->xcomp = *comp; cp->xstate = (*comp)->comp_alloc(opt_data, len); if (cp->xstate == NULL) error = ENOSR; } else { if (cp->rstate != NULL) { (*cp->rcomp->decomp_free)(cp->rstate); cp->rstate = NULL; } cp->rcomp = *comp; cp->rstate = (*comp)->decomp_alloc(opt_data, len); if (cp->rstate == NULL) error = ENOSR; } #else if ((error = cp->memreq.thread_status) != EAGAIN) if (iop->ioc_cmd == PPPIO_XCOMP) { if (cp->xstate) { (*cp->xcomp->comp_free)(cp->xstate); cp->xstate = 0; } /* sanity check for compressor options */ if (sizeof (cp->memreq.comp_opts) < len) { printf("can't handle options for compressor %d (%d)\n", opt_data[0], opt_data[1]); cp->memreq.thread_status = ENOSR; cp->memreq.returned_mem = 0; } /* fill in request for the thread and kick it off */ if (cp->memreq.thread_status == 0 && !cp->memreq.returned_mem) { bcopy(opt_data, cp->memreq.comp_opts, len); cp->memreq.cmd = PPPIO_XCOMP; cp->xcomp = *comp; error = cp->memreq.thread_status = EAGAIN; thread_wakeup((vm_offset_t)&cp->memreq.thread_status); } else { cp->xstate = cp->memreq.returned_mem; cp->memreq.returned_mem = 0; cp->memreq.thread_status = 0; } } else { if (cp->rstate) { (*cp->rcomp->decomp_free)(cp->rstate); cp->rstate = NULL; } if (sizeof (cp->memreq.comp_opts) < len) { printf("can't handle options for compressor %d (%d)\n", opt_data[0], opt_data[1]); cp->memreq.thread_status = ENOSR; cp->memreq.returned_mem = 0; } if (cp->memreq.thread_status == 0 && !cp->memreq.returned_mem) { bcopy(opt_data, cp->memreq.comp_opts, len); cp->memreq.cmd = PPPIO_RCOMP; cp->rcomp = *comp; error = cp->memreq.thread_status = EAGAIN; thread_wakeup((vm_offset_t)&cp->memreq.thread_status); } else { cp->rstate = cp->memreq.returned_mem; cp->memreq.returned_mem = 0; cp->memreq.thread_status = 0; } } #endif break; } iop->ioc_count = 0; break; case PPPIO_GETSTAT: if ((cp->flags & LAST_MOD) == 0) { error = -1; /* let the ppp_ahdl module handle it */ break; } np = allocb(sizeof(struct ppp_stats), BPRI_HI); if (np == 0) { error = ENOSR; break; } if (mp->b_cont != 0) freemsg(mp->b_cont); mp->b_cont = np; psp = (struct ppp_stats *) np->b_wptr; np->b_wptr += sizeof(struct ppp_stats); iop->ioc_count = sizeof(struct ppp_stats); psp->p = cp->stats; psp->vj = cp->vj_comp.stats; error = 0; break; case PPPIO_GETCSTAT: np = allocb(sizeof(struct ppp_comp_stats), BPRI_HI); if (np == 0) { error = ENOSR; break; } if (mp->b_cont != 0) freemsg(mp->b_cont); mp->b_cont = np; csp = (struct ppp_comp_stats *) np->b_wptr; np->b_wptr += sizeof(struct ppp_comp_stats); iop->ioc_count = sizeof(struct ppp_comp_stats); bzero((caddr_t)csp, sizeof(struct ppp_comp_stats)); if (cp->xstate != 0) (*cp->xcomp->comp_stat)(cp->xstate, &csp->c); if (cp->rstate != 0) (*cp->rcomp->decomp_stat)(cp->rstate, &csp->d); error = 0; break; case PPPIO_DEBUG: if (iop->ioc_count != sizeof(int)) break; if (mp->b_cont == 0) { DPRINT1("ppp_comp_wput/%d: PPPIO_DEBUG b_cont = 0!\n", cp->unit); break; } n = *(int *)mp->b_cont->b_rptr; if (n == PPPDBG_LOG + PPPDBG_COMP) { DPRINT1("ppp_comp%d: debug log enabled\n", cp->unit); cp->flags |= DBGLOG; error = 0; iop->ioc_count = 0; } else { error = -1; } break; case PPPIO_LASTMOD: cp->flags |= LAST_MOD; error = 0; break; default: error = -1; break; } if (error < 0) putnext(q, mp); else if (error == 0) { mp->b_datap->db_type = M_IOCACK; qreply(q, mp); } else { mp->b_datap->db_type = M_IOCNAK; iop->ioc_error = error; iop->ioc_count = 0; qreply(q, mp); } break; case M_CTL: switch (*mp->b_rptr) { case PPPCTL_MTU: cp->mtu = ((unsigned short *)mp->b_rptr)[1]; break; case PPPCTL_MRU: cp->mru = ((unsigned short *)mp->b_rptr)[1]; break; case PPPCTL_UNIT: cp->unit = mp->b_rptr[1]; break; } putnext(q, mp); break; default: putnext(q, mp); } return 0; } static int ppp_comp_wsrv(q) queue_t *q; { mblk_t *mp, *cmp = NULL; comp_state_t *cp; int len, proto, type, hlen, code; struct ip *ip; unsigned char *vjhdr, *dp; cp = (comp_state_t *) q->q_ptr; if (cp == 0) { DPRINT("cp == 0 in ppp_comp_wsrv\n"); return 0; } while ((mp = getq(q)) != 0) { /* assert(mp->b_datap->db_type == M_DATA) */ #ifdef PRIOQ if (!bcanputnext(q,mp->b_band)) #else if (!canputnext(q)) #endif /* PRIOQ */ { putbq(q, mp); break; } /* * First check the packet length and work out what the protocol is. */ len = msgdsize(mp); if (len < PPP_HDRLEN) { DPRINT1("ppp_comp_wsrv: bogus short packet (%d)\n", len); freemsg(mp); cp->stats.ppp_oerrors++; putctl1(RD(q)->q_next, M_CTL, PPPCTL_OERROR); continue; } proto = (MSG_BYTE(mp, 2) << 8) + MSG_BYTE(mp, 3); /* * Make sure we've got enough data in the first mblk * and that we are its only user. */ if (proto == PPP_CCP) hlen = len; else if (proto == PPP_IP) hlen = PPP_HDRLEN + MAX_IPHDR; else hlen = PPP_HDRLEN; if (hlen > len) hlen = len; if (mp->b_wptr < mp->b_rptr + hlen || mp->b_datap->db_ref > 1) { PULLUP(mp, hlen); if (mp == 0) { DPRINT1("ppp_comp_wsrv: pullup failed (%d)\n", hlen); cp->stats.ppp_oerrors++; putctl1(RD(q)->q_next, M_CTL, PPPCTL_OERROR); continue; } } /* * Do VJ compression if requested. */ if (proto == PPP_IP && (cp->flags & COMP_VJC)) { ip = (struct ip *) (mp->b_rptr + PPP_HDRLEN); if (ip->ip_p == IPPROTO_TCP) { type = vj_compress_tcp(ip, len - PPP_HDRLEN, &cp->vj_comp, (cp->flags & COMP_VJCCID), &vjhdr); switch (type) { case TYPE_UNCOMPRESSED_TCP: mp->b_rptr[3] = proto = PPP_VJC_UNCOMP; break; case TYPE_COMPRESSED_TCP: dp = vjhdr - PPP_HDRLEN; dp[1] = mp->b_rptr[1]; /* copy control field */ dp[0] = mp->b_rptr[0]; /* copy address field */ dp[2] = 0; /* set protocol field */ dp[3] = proto = PPP_VJC_COMP; mp->b_rptr = dp; break; } } } /* * Do packet compression if enabled. */ if (proto == PPP_CCP) ppp_comp_ccp(q, mp, 0); else if (proto != PPP_LCP && (cp->flags & CCP_COMP_RUN) && cp->xstate != NULL) { len = msgdsize(mp); (*cp->xcomp->compress)(cp->xstate, &cmp, mp, len, (cp->flags & CCP_ISUP? cp->mtu + PPP_HDRLEN: 0)); if (cmp != NULL) { #ifdef PRIOQ cmp->b_band=mp->b_band; #endif /* PRIOQ */ freemsg(mp); mp = cmp; } } /* * Do address/control and protocol compression if enabled. */ if ((cp->flags & COMP_AC) && !(proto == PPP_LCP && LCP_USE_DFLT(mp))) { mp->b_rptr += 2; /* drop the address & ctrl fields */ if (proto < 0x100 && (cp->flags & COMP_PROT)) ++mp->b_rptr; /* drop the high protocol byte */ } else if (proto < 0x100 && (cp->flags & COMP_PROT)) { /* shuffle up the address & ctrl fields */ mp->b_rptr[2] = mp->b_rptr[1]; mp->b_rptr[1] = mp->b_rptr[0]; ++mp->b_rptr; } cp->stats.ppp_opackets++; cp->stats.ppp_obytes += msgdsize(mp); putnext(q, mp); } return 0; } static int ppp_comp_rput(q, mp) queue_t *q; mblk_t *mp; { comp_state_t *cp; struct iocblk *iop; struct ppp_stats *psp; cp = (comp_state_t *) q->q_ptr; if (cp == 0) { DPRINT("cp == 0 in ppp_comp_rput\n"); freemsg(mp); return 0; } switch (mp->b_datap->db_type) { case M_DATA: putq(q, mp); break; case M_IOCACK: iop = (struct iocblk *) mp->b_rptr; switch (iop->ioc_cmd) { case PPPIO_GETSTAT: /* * Catch this on the way back from the ppp_ahdl module * so we can fill in the VJ stats. */ if (mp->b_cont == 0 || iop->ioc_count != sizeof(struct ppp_stats)) break; psp = (struct ppp_stats *) mp->b_cont->b_rptr; psp->vj = cp->vj_comp.stats; break; } putnext(q, mp); break; case M_CTL: switch (mp->b_rptr[0]) { case PPPCTL_IERROR: ++cp->stats.ppp_ierrors; break; case PPPCTL_OERROR: ++cp->stats.ppp_oerrors; break; } putnext(q, mp); break; default: putnext(q, mp); } return 0; } static int ppp_comp_rsrv(q) queue_t *q; { int proto, rv, i; mblk_t *mp, *dmp = NULL, *np; uchar_t *dp, *iphdr; comp_state_t *cp; int len, hlen, vjlen; u_int iphlen; cp = (comp_state_t *) q->q_ptr; if (cp == 0) { DPRINT("cp == 0 in ppp_comp_rsrv\n"); return 0; } while ((mp = getq(q)) != 0) { /* assert(mp->b_datap->db_type == M_DATA) */ if (!canputnext(q)) { putbq(q, mp); break; } len = msgdsize(mp); cp->stats.ppp_ibytes += len; cp->stats.ppp_ipackets++; /* * First work out the protocol and where the PPP header ends. */ i = 0; proto = MSG_BYTE(mp, 0); if (proto == PPP_ALLSTATIONS) { i = 2; proto = MSG_BYTE(mp, 2); } if ((proto & 1) == 0) { ++i; proto = (proto << 8) + MSG_BYTE(mp, i); } hlen = i + 1; /* * Now reconstruct a complete, contiguous PPP header at the * start of the packet. */ if (hlen < ((cp->flags & DECOMP_AC)? 0: 2) + ((cp->flags & DECOMP_PROT)? 1: 2)) { /* count these? */ goto bad; } if (mp->b_rptr + hlen > mp->b_wptr) { adjmsg(mp, hlen); /* XXX check this call */ hlen = 0; } if (hlen != PPP_HDRLEN) { /* * We need to put some bytes on the front of the packet * to make a full-length PPP header. * If we can put them in *mp, we do, otherwise we * tack another mblk on the front. * XXX we really shouldn't need to carry around * the address and control at this stage. */ dp = mp->b_rptr + hlen - PPP_HDRLEN; if (dp < mp->b_datap->db_base || mp->b_datap->db_ref > 1) { np = allocb(PPP_HDRLEN, BPRI_MED); if (np == 0) goto bad; np->b_cont = mp; mp->b_rptr += hlen; mp = np; dp = mp->b_wptr; mp->b_wptr += PPP_HDRLEN; } else mp->b_rptr = dp; dp[0] = PPP_ALLSTATIONS; dp[1] = PPP_UI; dp[2] = proto >> 8; dp[3] = proto; } /* * Now see if we have a compressed packet to decompress, * or a CCP packet to take notice of. */ proto = PPP_PROTOCOL(mp->b_rptr); if (proto == PPP_CCP) { len = msgdsize(mp); if (mp->b_wptr < mp->b_rptr + len) { PULLUP(mp, len); if (mp == 0) goto bad; } ppp_comp_ccp(q, mp, 1); } else if (proto == PPP_COMP) { if ((cp->flags & CCP_ISUP) && (cp->flags & CCP_DECOMP_RUN) && cp->rstate && (cp->flags & CCP_ERR) == 0) { rv = (*cp->rcomp->decompress)(cp->rstate, mp, &dmp); switch (rv) { case DECOMP_OK: freemsg(mp); mp = dmp; if (mp == NULL) { /* no error, but no packet returned either. */ continue; } break; case DECOMP_ERROR: cp->flags |= CCP_ERROR; ++cp->stats.ppp_ierrors; putctl1(q->q_next, M_CTL, PPPCTL_IERROR); break; case DECOMP_FATALERROR: cp->flags |= CCP_FATALERROR; ++cp->stats.ppp_ierrors; putctl1(q->q_next, M_CTL, PPPCTL_IERROR); break; } } } else if (cp->rstate && (cp->flags & CCP_DECOMP_RUN)) { (*cp->rcomp->incomp)(cp->rstate, mp); } /* * Now do VJ decompression. */ proto = PPP_PROTOCOL(mp->b_rptr); if (proto == PPP_VJC_COMP || proto == PPP_VJC_UNCOMP) { len = msgdsize(mp) - PPP_HDRLEN; if ((cp->flags & DECOMP_VJC) == 0 || len <= 0) goto bad; /* * Advance past the ppp header. * Here we assume that the whole PPP header is in the first mblk. */ np = mp; dp = np->b_rptr + PPP_HDRLEN; if (dp >= mp->b_wptr) { np = np->b_cont; dp = np->b_rptr; } /* * Make sure we have sufficient contiguous data at this point. */ hlen = (proto == PPP_VJC_COMP)? MAX_VJHDR: MAX_IPHDR; if (hlen > len) hlen = len; if (np->b_wptr < dp + hlen || np->b_datap->db_ref > 1) { PULLUP(mp, hlen + PPP_HDRLEN); if (mp == 0) goto bad; np = mp; dp = np->b_rptr + PPP_HDRLEN; } if (proto == PPP_VJC_COMP) { /* * Decompress VJ-compressed packet. * First reset compressor if an input error has occurred. */ if (cp->stats.ppp_ierrors != cp->vj_last_ierrors) { if (cp->flags & DBGLOG) DPRINT1("ppp%d: resetting VJ\n", cp->unit); vj_uncompress_err(&cp->vj_comp); cp->vj_last_ierrors = cp->stats.ppp_ierrors; } vjlen = vj_uncompress_tcp(dp, np->b_wptr - dp, len, &cp->vj_comp, &iphdr, &iphlen); if (vjlen < 0) { if (cp->flags & DBGLOG) DPRINT2("ppp%d: vj_uncomp_tcp failed, pkt len %d\n", cp->unit, len); ++cp->vj_last_ierrors; /* so we don't reset next time */ goto bad; } /* drop ppp and vj headers off */ if (mp != np) { freeb(mp); mp = np; } mp->b_rptr = dp + vjlen; /* allocate a new mblk for the ppp and ip headers */ if ((np = allocb(iphlen + PPP_HDRLEN + 4, BPRI_MED)) == 0) goto bad; dp = np->b_rptr; /* prepend mblk with TCP/IP hdr */ dp[0] = PPP_ALLSTATIONS; /* reconstruct PPP header */ dp[1] = PPP_UI; dp[2] = PPP_IP >> 8; dp[3] = PPP_IP; bcopy((caddr_t)iphdr, (caddr_t)dp + PPP_HDRLEN, iphlen); np->b_wptr = dp + iphlen + PPP_HDRLEN; np->b_cont = mp; /* XXX there seems to be a bug which causes panics in strread if we make an mbuf with only the IP header in it :-( */ if (mp->b_wptr - mp->b_rptr > 4) { bcopy((caddr_t)mp->b_rptr, (caddr_t)np->b_wptr, 4); mp->b_rptr += 4; np->b_wptr += 4; } else { bcopy((caddr_t)mp->b_rptr, (caddr_t)np->b_wptr, mp->b_wptr - mp->b_rptr); np->b_wptr += mp->b_wptr - mp->b_rptr; np->b_cont = mp->b_cont; freeb(mp); } mp = np; } else { /* * "Decompress" a VJ-uncompressed packet. */ cp->vj_last_ierrors = cp->stats.ppp_ierrors; if (!vj_uncompress_uncomp(dp, hlen, &cp->vj_comp)) { if (cp->flags & DBGLOG) DPRINT2("ppp%d: vj_uncomp_uncomp failed, pkt len %d\n", cp->unit, len); ++cp->vj_last_ierrors; /* don't need to reset next time */ goto bad; } mp->b_rptr[3] = PPP_IP; /* fix up the PPP protocol field */ } } putnext(q, mp); continue; bad: if (mp != 0) freemsg(mp); cp->stats.ppp_ierrors++; putctl1(q->q_next, M_CTL, PPPCTL_IERROR); } return 0; } /* * Handle a CCP packet being sent or received. * Here all the data in the packet is in a single mbuf. */ static void ppp_comp_ccp(q, mp, rcvd) queue_t *q; mblk_t *mp; int rcvd; { int len, clen; comp_state_t *cp; unsigned char *dp; len = msgdsize(mp); if (len < PPP_HDRLEN + CCP_HDRLEN) return; cp = (comp_state_t *) q->q_ptr; dp = mp->b_rptr + PPP_HDRLEN; len -= PPP_HDRLEN; clen = CCP_LENGTH(dp); if (clen > len) return; switch (CCP_CODE(dp)) { case CCP_CONFREQ: case CCP_TERMREQ: case CCP_TERMACK: cp->flags &= ~CCP_ISUP; break; case CCP_CONFACK: if ((cp->flags & (CCP_ISOPEN | CCP_ISUP)) == CCP_ISOPEN && clen >= CCP_HDRLEN + CCP_OPT_MINLEN && clen >= CCP_HDRLEN + CCP_OPT_LENGTH(dp + CCP_HDRLEN)) { if (!rcvd) { if (cp->xstate != NULL && (*cp->xcomp->comp_init) (cp->xstate, dp + CCP_HDRLEN, clen - CCP_HDRLEN, cp->unit, 0, ((cp->flags & DBGLOG) != 0))) cp->flags |= CCP_COMP_RUN; } else { if (cp->rstate != NULL && (*cp->rcomp->decomp_init) (cp->rstate, dp + CCP_HDRLEN, clen - CCP_HDRLEN, cp->unit, 0, cp->mru, ((cp->flags & DBGLOG) != 0))) cp->flags = (cp->flags & ~CCP_ERR) | CCP_DECOMP_RUN; } } break; case CCP_RESETACK: if (cp->flags & CCP_ISUP) { if (!rcvd) { if (cp->xstate && (cp->flags & CCP_COMP_RUN)) (*cp->xcomp->comp_reset)(cp->xstate); } else { if (cp->rstate && (cp->flags & CCP_DECOMP_RUN)) { (*cp->rcomp->decomp_reset)(cp->rstate); cp->flags &= ~CCP_ERROR; } } } break; } } #if 0 dump_msg(mp) mblk_t *mp; { dblk_t *db; while (mp != 0) { db = mp->b_datap; DPRINT2("mp=%x cont=%x ", mp, mp->b_cont); DPRINT3("rptr=%x wptr=%x datap=%x\n", mp->b_rptr, mp->b_wptr, db); DPRINT2(" base=%x lim=%x", db->db_base, db->db_lim); DPRINT2(" ref=%d type=%d\n", db->db_ref, db->db_type); mp = mp->b_cont; } } #endif static int msg_byte(mp, i) mblk_t *mp; unsigned int i; { while (mp != 0 && i >= mp->b_wptr - mp->b_rptr) mp = mp->b_cont; if (mp == 0) return -1; return mp->b_rptr[i]; } ppp-2.5.0/solaris/ppp_comp_mod.c0000644000175000017500000000445407574071234013552 00000000000000/* * ppp_comp_mod.c - modload support for PPP compression STREAMS module. * * Copyright (c) 1994 Paul Mackerras. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The name(s) of the authors of this software must not be used to * endorse or promote products derived from this software without * prior written permission. * * 4. Redistributions of any form whatsoever must retain the following * acknowledgment: * "This product includes software developed by Paul Mackerras * ". * * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * $Id: ppp_comp_mod.c,v 1.2 2002/12/06 09:49:16 paulus Exp $ */ /* * This file is used under Solaris 2. */ #include #include #include #include #include extern struct streamtab ppp_compinfo; static struct fmodsw fsw = { "ppp_comp", &ppp_compinfo, D_NEW | D_MP | D_MTQPAIR }; extern struct mod_ops mod_strmodops; static struct modlstrmod modlstrmod = { &mod_strmodops, "PPP compression module", &fsw }; static struct modlinkage modlinkage = { MODREV_1, (void *) &modlstrmod, NULL }; /* * Entry points for modloading. */ int _init(void) { return mod_install(&modlinkage); } int _fini(void) { return mod_remove(&modlinkage); } int _info(mip) struct modinfo *mip; { return mod_info(&modlinkage, mip); } ppp-2.5.0/solaris/ppp.conf0000644000175000017500000000004707077172400012365 00000000000000name="ppp" parent="pseudo" instance=0; ppp-2.5.0/solaris/ppp_mod.c0000664000175000017500000001066013772533431012531 00000000000000/* * ppp_mod.c - modload support for PPP pseudo-device driver. * * Copyright (c) 1994 Paul Mackerras. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The name(s) of the authors of this software must not be used to * endorse or promote products derived from this software without * prior written permission. * * 4. Redistributions of any form whatsoever must retain the following * acknowledgment: * "This product includes software developed by Paul Mackerras * ". * * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * $Id: ppp_mod.c,v 1.3 2004/01/17 05:47:55 carlsonj Exp $ */ /* * This file is used under Solaris 2. */ #include #include #include #include #include #include #include static int ppp_identify(dev_info_t *); static int ppp_attach(dev_info_t *, ddi_attach_cmd_t); static int ppp_detach(dev_info_t *, ddi_detach_cmd_t); static int ppp_devinfo(dev_info_t *, ddi_info_cmd_t, void *, void **); extern struct streamtab pppinfo; extern krwlock_t ppp_lower_lock; static dev_info_t *ppp_dip; static struct cb_ops cb_ppp_ops = { nulldev, nulldev, nodev, nodev, /* cb_open, ... */ nodev, nodev, nodev, nodev, /* cb_dump, ... */ nodev, nodev, nodev, nochpoll, /* cb_devmap, ... */ ddi_prop_op, /* cb_prop_op */ &pppinfo, /* cb_stream */ D_NEW|D_MP|D_MTQPAIR|D_MTOUTPERIM|D_MTOCEXCL /* cb_flag */ }; static struct dev_ops ppp_ops = { DEVO_REV, /* devo_rev */ 0, /* devo_refcnt */ ppp_devinfo, /* devo_getinfo */ ppp_identify, /* devo_identify */ nulldev, /* devo_probe */ ppp_attach, /* devo_attach */ ppp_detach, /* devo_detach */ nodev, /* devo_reset */ &cb_ppp_ops, /* devo_cb_ops */ NULL /* devo_bus_ops */ }; /* * Module linkage information */ static struct modldrv modldrv = { &mod_driverops, /* says this is a pseudo driver */ "PPP-2.4.7 multiplexing driver", &ppp_ops /* driver ops */ }; static struct modlinkage modlinkage = { MODREV_1, (void *) &modldrv, NULL }; int _init(void) { return mod_install(&modlinkage); } int _fini(void) { return mod_remove(&modlinkage); } int _info(mip) struct modinfo *mip; { return mod_info(&modlinkage, mip); } static int ppp_identify(dip) dev_info_t *dip; { /* This entry point is not used as of Solaris 10 */ #ifdef DDI_IDENTIFIED return strcmp(ddi_get_name(dip), "ppp") == 0? DDI_IDENTIFIED: DDI_NOT_IDENTIFIED; #else return 0; #endif } static int ppp_attach(dip, cmd) dev_info_t *dip; ddi_attach_cmd_t cmd; { if (cmd != DDI_ATTACH) return DDI_FAILURE; if (ddi_create_minor_node(dip, "ppp", S_IFCHR, 0, DDI_PSEUDO, CLONE_DEV) == DDI_FAILURE) { ddi_remove_minor_node(dip, NULL); return DDI_FAILURE; } rw_init(&ppp_lower_lock, NULL, RW_DRIVER, NULL); return DDI_SUCCESS; } static int ppp_detach(dip, cmd) dev_info_t *dip; ddi_detach_cmd_t cmd; { rw_destroy(&ppp_lower_lock); ddi_remove_minor_node(dip, NULL); return DDI_SUCCESS; } static int ppp_devinfo(dip, cmd, arg, result) dev_info_t *dip; ddi_info_cmd_t cmd; void *arg; void **result; { int error; error = DDI_SUCCESS; switch (cmd) { case DDI_INFO_DEVT2DEVINFO: if (ppp_dip == NULL) error = DDI_FAILURE; else *result = (void *) ppp_dip; break; case DDI_INFO_DEVT2INSTANCE: *result = NULL; break; default: error = DDI_FAILURE; } return error; } ppp-2.5.0/solaris/ppp_mod.h0000664000175000017500000001160313772533475012544 00000000000000/* * Miscellaneous definitions for PPP STREAMS modules. */ /* * Macros for allocating and freeing kernel memory. */ #ifdef SVR4 /* SVR4, including Solaris 2 */ #include #define ALLOC_SLEEP(n) kmem_alloc((n), KM_SLEEP) #define ALLOC_NOSLEEP(n) kmem_alloc((n), KM_NOSLEEP) #define FREE(p, n) kmem_free((p), (n)) #endif #ifdef SUNOS4 #include /* SunOS 4.x */ #define ALLOC_SLEEP(n) kmem_alloc((n), KMEM_SLEEP) #define ALLOC_NOSLEEP(n) kmem_alloc((n), KMEM_NOSLEEP) #define FREE(p, n) kmem_free((p), (n)) #define NOTSUSER() (suser()? 0: EPERM) #define bcanputnext(q, band) canputnext((q)) #endif /* SunOS 4 */ #ifdef __osf__ #include /* caution: this mirrors macros in sys/malloc.h, and uses interfaces * which are subject to change. * The problems are that: * - the official MALLOC macro wants the lhs of the assignment as an argument, * and it takes care of the assignment itself (yuck.) * - PPP insists on using "FREE" which conflicts with a macro of the same name. * */ #ifdef BUCKETINDX /* V2.0 */ #define ALLOC_SLEEP(n) (void *)malloc((u_long)(n), BUCKETP(n), M_DEVBUF, M_WAITOK) #define ALLOC_NOSLEEP(n) (void *)malloc((u_long)(n), BUCKETP(n), M_DEVBUF, M_NOWAIT) #else #define ALLOC_SLEEP(n) (void *)malloc((u_long)(n), BUCKETINDEX(n), M_DEVBUF, M_WAITOK) #define ALLOC_NOSLEEP(n) (void *)malloc((u_long)(n), BUCKETINDEX(n), M_DEVBUF, M_NOWAIT) #endif #define bcanputnext(q, band) canputnext((q)) #ifdef FREE #undef FREE #endif #define FREE(p, n) free((void *)(p), M_DEVBUF) #define NO_DLPI 1 #ifndef IFT_PPP #define IFT_PPP 0x17 #endif #include #define NOTSUSER() (suser(u.u_procp->p_rcred, &u.u_acflag) ? EPERM : 0) /* #include "ppp_osf.h" */ #endif /* __osf__ */ #ifdef AIX4 #define ALLOC_SLEEP(n) xmalloc((n), 0, pinned_heap) /* AIX V4.x */ #define ALLOC_NOSLEEP(n) xmalloc((n), 0, pinned_heap) /* AIX V4.x */ #define FREE(p, n) xmfree((p), pinned_heap) #define NOTSUSER() (suser()? 0: EPERM) #endif /* AIX */ /* * Macros for printing debugging stuff. */ #ifdef DEBUG #if defined(SVR4) || defined(__osf__) #if defined(SNI) #include #define STRLOG_ID 4712 #define DPRINT(f) strlog(STRLOG_ID, 0, 0, SL_TRACE, f) #define DPRINT1(f, a1) strlog(STRLOG_ID, 0, 0, SL_TRACE, f, a1) #define DPRINT2(f, a1, a2) strlog(STRLOG_ID, 0, 0, SL_TRACE, f, a1, a2) #define DPRINT3(f, a1, a2, a3) strlog(STRLOG_ID, 0, 0, SL_TRACE, f, a1, a2, a3) #else #define DPRINT(f) cmn_err(CE_CONT, f) #define DPRINT1(f, a1) cmn_err(CE_CONT, f, a1) #define DPRINT2(f, a1, a2) cmn_err(CE_CONT, f, a1, a2) #define DPRINT3(f, a1, a2, a3) cmn_err(CE_CONT, f, a1, a2, a3) #endif /* SNI */ #else #define DPRINT(f) printf(f) #define DPRINT1(f, a1) printf(f, a1) #define DPRINT2(f, a1, a2) printf(f, a1, a2) #define DPRINT3(f, a1, a2, a3) printf(f, a1, a2, a3) #endif /* SVR4 or OSF */ #else #define DPRINT(f) 0 #define DPRINT1(f, a1) 0 #define DPRINT2(f, a1, a2) 0 #define DPRINT3(f, a1, a2, a3) 0 #endif /* DEBUG */ #ifndef SVR4 typedef unsigned char uchar_t; typedef unsigned short ushort_t; #ifndef __osf__ typedef int minor_t; #endif #endif /* * If we don't have multithreading support, define substitutes. */ #ifndef D_MP # define qprocson(q) # define qprocsoff(q) # define put(q, mp) ((*(q)->q_qinfo->qi_putp)((q), (mp))) # define canputnext(q) canput((q)->q_next) # define qwriter(q, mp, func, scope) (func)((q), (mp)) #endif #ifdef D_MP /* Use msgpullup if we have other multithreading support. */ #define PULLUP(mp, len) \ do { \ mblk_t *np = msgpullup((mp), (len)); \ freemsg((mp)); \ mp = np; \ } while (0) #else /* Use pullupmsg if we don't have any multithreading support. */ #define PULLUP(mp, len) \ do { \ if (!pullupmsg((mp), (len))) { \ freemsg((mp)); \ mp = 0; \ } \ } while (0) #endif /* * How to declare the open and close procedures for a module. */ #ifdef SVR4 #define MOD_OPEN_DECL(name) \ static int name(queue_t *, dev_t *, int, int, cred_t *) #define MOD_CLOSE_DECL(name) \ static int name(queue_t *, int, cred_t *) #define MOD_OPEN(name) \ static int name(q, devp, flag, sflag, credp) \ queue_t *q; \ dev_t *devp; \ int flag, sflag; \ cred_t *credp; #define MOD_CLOSE(name) \ static int name(q, flag, credp) \ queue_t *q; \ int flag; \ cred_t *credp; #define OPEN_ERROR(x) return (x) #define DRV_OPEN_OK(dev) return 0 #define NOTSUSER() (drv_priv(credp)) #else /* not SVR4 */ #define MOD_OPEN_DECL(name) \ static int name(queue_t *, int, int, int) #define MOD_CLOSE_DECL(name) \ static int name(queue_t *, int) #define MOD_OPEN(name) \ static int name(q, dev, flag, sflag) \ queue_t *q; \ int dev; \ int flag, sflag; #define MOD_CLOSE(name) \ static int name(q, flag) \ queue_t *q; \ int flag; #define OPEN_ERROR(x) { u.u_error = (x); return OPENFAIL; } #define DRV_OPEN_OK(dev) return (dev) #endif /* SVR4 */ ppp-2.5.0/Makefile.am0000664000175000017500000000323614273050614011302 00000000000000ACLOCAL_AMFLAGS="-Im4" SUBDIRS = chat contrib pppd pppstats pppdump if PPP_WITH_PLUGINS SUBDIRS += pppd/plugins endif DIST_SUBDIRS = $(SUBDIRS) common include modules scripts # # *HACK* # This is to work around the kernel module for PPP on Sun Solaris if SUNOS all-am: (cd solaris ; $(MAKE) -f Makefile) clean-generic: (cd solaris ; $(MAKE) -f Makefile clean) install-am: (cd solaris ; $(MAKE) -f Makefile install) endif install-data-hook: (cd $(DESTDIR)/$(sysconfdir)/$(PACKAGE) ; \ chmod 600 chap-secrets pap-secrets eaptls-server eaptls-client) sampledir = $(sysconfdir)/$(PACKAGE) sample_DATA = \ etc.ppp/options \ etc.ppp/chap-secrets \ etc.ppp/pap-secrets \ etc.ppp/eaptls-server \ etc.ppp/eaptls-client \ etc.ppp/openssl.cnf EXTRA_README = \ Changes-2.3 \ FAQ \ README \ README.cbcp \ README.eap-srp \ README.eap-tls \ README.linux \ README.MPPE \ README.MSCHAP80 \ README.MSCHAP81 \ README.pppoe \ README.pppol2tp \ README.pwfd \ README.sol2 \ PLUGINS \ SETUP \ Submitting-patches.md EXTRA_SOLARIS = \ solaris/Makedefs \ solaris/Makedefs.gcc \ solaris/Makedefs.sol2 \ solaris/Makefile.sol2 \ solaris/Makefile.sol2-64 \ solaris/Makefile.sol2-64x \ solaris/Makefile.sol2gcc \ solaris/Makefile.sol2gcc-64 \ solaris/Makefile.sol2gcc-64x \ solaris/Makefile.top \ solaris/ppp_ahdlc.c \ solaris/ppp_ahdlc_mod.c \ solaris/ppp.c \ solaris/ppp_comp.c \ solaris/ppp_comp_mod.c \ solaris/ppp.conf \ solaris/ppp_mod.c \ solaris/ppp_mod.h EXTRA_DIST= \ $(sample_DATA) \ $(EXTRA_README) \ $(EXTRA_SOLARIS) ppp-2.5.0/configure0000755000175000017500000200215214407475314011160 00000000000000#! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.71 for ppp 2.5.0. # # Report bugs to . # # # Copyright (C) 1992-1996, 1998-2017, 2020-2021 Free Software Foundation, # Inc. # # # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh as_nop=: if test ${ZSH_VERSION+y} && (emulate sh) >/dev/null 2>&1 then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else $as_nop case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi # Reset variables that may have inherited troublesome values from # the environment. # IFS needs to be set, to space, tab, and newline, in precisely that order. # (If _AS_PATH_WALK were called with IFS unset, it would have the # side effect of setting IFS to empty, thus disabling word splitting.) # Quoting is to prevent editors from complaining about space-tab. as_nl=' ' export as_nl IFS=" "" $as_nl" PS1='$ ' PS2='> ' PS4='+ ' # Ensure predictable behavior from utilities with locale-dependent output. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # We cannot yet rely on "unset" to work, but we need these variables # to be unset--not just set to an empty or harmless value--now, to # avoid bugs in old shells (e.g. pre-3.0 UWIN ksh). This construct # also avoids known problems related to "unset" and subshell syntax # in other old shells (e.g. bash 2.01 and pdksh 5.2.14). for as_var in BASH_ENV ENV MAIL MAILPATH CDPATH do eval test \${$as_var+y} \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done # Ensure that fds 0, 1, and 2 are open. if (exec 3>&0) 2>/dev/null; then :; else exec 0&1) 2>/dev/null; then :; else exec 1>/dev/null; fi if (exec 3>&2) ; then :; else exec 2>/dev/null; fi # The user is always right. if ${PATH_SEPARATOR+false} :; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac test -r "$as_dir$0" && as_myself=$as_dir$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then printf "%s\n" "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Use a proper internal environment variable to ensure we don't fall # into an infinite loop, continuously re-executing ourselves. if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then _as_can_reexec=no; export _as_can_reexec; # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV case $- in # (((( *v*x* | *x*v* ) as_opts=-vx ;; *v* ) as_opts=-v ;; *x* ) as_opts=-x ;; * ) as_opts= ;; esac exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} # Admittedly, this is quite paranoid, since all the known shells bail # out after a failed `exec'. printf "%s\n" "$0: could not re-execute with $CONFIG_SHELL" >&2 exit 255 fi # We don't want this to propagate to other subprocesses. { _as_can_reexec=; unset _as_can_reexec;} if test "x$CONFIG_SHELL" = x; then as_bourne_compatible="as_nop=: if test \${ZSH_VERSION+y} && (emulate sh) >/dev/null 2>&1 then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which # is contrary to our usage. Disable this feature. alias -g '\${1+\"\$@\"}'='\"\$@\"' setopt NO_GLOB_SUBST else \$as_nop case \`(set -o) 2>/dev/null\` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi " as_required="as_fn_return () { (exit \$1); } as_fn_success () { as_fn_return 0; } as_fn_failure () { as_fn_return 1; } as_fn_ret_success () { return 0; } as_fn_ret_failure () { return 1; } exitcode=0 as_fn_success || { exitcode=1; echo as_fn_success failed.; } as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } if ( set x; as_fn_ret_success y && test x = \"\$1\" ) then : else \$as_nop exitcode=1; echo positional parameters were not saved. fi test x\$exitcode = x0 || exit 1 blah=\$(echo \$(echo blah)) test x\"\$blah\" = xblah || exit 1 test -x / || exit 1" as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 test -n \"\${ZSH_VERSION+set}\${BASH_VERSION+set}\" || ( ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO PATH=/empty FPATH=/empty; export PATH FPATH test \"X\`printf %s \$ECHO\`\" = \"X\$ECHO\" \\ || test \"X\`print -r -- \$ECHO\`\" = \"X\$ECHO\" ) || exit 1 test \$(( 1 + 1 )) = 2 || exit 1" if (eval "$as_required") 2>/dev/null then : as_have_required=yes else $as_nop as_have_required=no fi if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null then : else $as_nop as_save_IFS=$IFS; IFS=$PATH_SEPARATOR as_found=false for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac as_found=: case $as_dir in #( /*) for as_base in sh bash ksh sh5; do # Try only shells that exist, to save several forks. as_shell=$as_dir$as_base if { test -f "$as_shell" || test -f "$as_shell.exe"; } && as_run=a "$as_shell" -c "$as_bourne_compatible""$as_required" 2>/dev/null then : CONFIG_SHELL=$as_shell as_have_required=yes if as_run=a "$as_shell" -c "$as_bourne_compatible""$as_suggested" 2>/dev/null then : break 2 fi fi done;; esac as_found=false done IFS=$as_save_IFS if $as_found then : else $as_nop if { test -f "$SHELL" || test -f "$SHELL.exe"; } && as_run=a "$SHELL" -c "$as_bourne_compatible""$as_required" 2>/dev/null then : CONFIG_SHELL=$SHELL as_have_required=yes fi fi if test "x$CONFIG_SHELL" != x then : export CONFIG_SHELL # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV case $- in # (((( *v*x* | *x*v* ) as_opts=-vx ;; *v* ) as_opts=-v ;; *x* ) as_opts=-x ;; * ) as_opts= ;; esac exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} # Admittedly, this is quite paranoid, since all the known shells bail # out after a failed `exec'. printf "%s\n" "$0: could not re-execute with $CONFIG_SHELL" >&2 exit 255 fi if test x$as_have_required = xno then : printf "%s\n" "$0: This script requires a shell more modern than all" printf "%s\n" "$0: the shells that I found on your system." if test ${ZSH_VERSION+y} ; then printf "%s\n" "$0: In particular, zsh $ZSH_VERSION has bugs and should" printf "%s\n" "$0: be upgraded to zsh 4.3.4 or later." else printf "%s\n" "$0: Please tell bug-autoconf@gnu.org and $0: https://github.com/ppp-project/ppp about your system, $0: including any error possibly output before this $0: message. Then install a modern shell, or manually run $0: the script under such a shell if you do have one." fi exit 1 fi fi fi SHELL=${CONFIG_SHELL-/bin/sh} export SHELL # Unset more variables known to interfere with behavior of common tools. CLICOLOR_FORCE= GREP_OPTIONS= unset CLICOLOR_FORCE GREP_OPTIONS ## --------------------- ## ## M4sh Shell Functions. ## ## --------------------- ## # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_nop # --------- # Do nothing but, unlike ":", preserve the value of $?. as_fn_nop () { return $? } as_nop=as_fn_nop # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`printf "%s\n" "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || printf "%s\n" X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p # as_fn_executable_p FILE # ----------------------- # Test if FILE is an executable regular file. as_fn_executable_p () { test -f "$1" && test -x "$1" } # as_fn_executable_p # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null then : eval 'as_fn_append () { eval $1+=\$2 }' else $as_nop as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null then : eval 'as_fn_arith () { as_val=$(( $* )) }' else $as_nop as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith # as_fn_nop # --------- # Do nothing but, unlike ":", preserve the value of $?. as_fn_nop () { return $? } as_nop=as_fn_nop # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi printf "%s\n" "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || printf "%s\n" X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits as_lineno_1=$LINENO as_lineno_1a=$LINENO as_lineno_2=$LINENO as_lineno_2a=$LINENO eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) sed -n ' p /[$]LINENO/= ' <$as_myself | sed ' s/[$]LINENO.*/&-/ t lineno b :lineno N :loop s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ t loop s/-\n.*// ' >$as_me.lineno && chmod +x "$as_me.lineno" || { printf "%s\n" "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } # If we had to re-execute with $CONFIG_SHELL, we're ensured to have # already done that, so ensure we don't try to do so again and fall # in an infinite loop. This has already happened in practice. _as_can_reexec=no; export _as_can_reexec # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensitive to this). . "./$as_me.lineno" # Exit status is that of the last command. exit } # Determine whether it's possible to make 'echo' print without a newline. # These variables are no longer used directly by Autoconf, but are AC_SUBSTed # for compatibility with existing Makefiles. ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac # For backward compatibility with old third-party macros, we provide # the shell variables $as_echo and $as_echo_n. New code should use # AS_ECHO(["message"]) and AS_ECHO_N(["message"]), respectively. as_echo='printf %s\n' as_echo_n='printf %s' rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -pR' fi else as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi as_test_x='test -x' as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" SHELL=${CONFIG_SHELL-/bin/sh} test -n "$DJDIR" || exec 7<&0 &1 # Name of the host. # hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, # so uname gets run too. ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` # # Initializations. # ac_default_prefix=/usr/local ac_clean_files= ac_config_libobj_dir=. LIBOBJS= cross_compiling=no subdirs= MFLAGS= MAKEFLAGS= # Identity of this package. PACKAGE_NAME='ppp' PACKAGE_TARNAME='ppp' PACKAGE_VERSION='2.5.0' PACKAGE_STRING='ppp 2.5.0' PACKAGE_BUGREPORT='https://github.com/ppp-project/ppp' PACKAGE_URL='' ac_unique_file="pppd/main.c" # Factoring default headers for most tests. ac_includes_default="\ #include #ifdef HAVE_STDIO_H # include #endif #ifdef HAVE_STDLIB_H # include #endif #ifdef HAVE_STRING_H # include #endif #ifdef HAVE_INTTYPES_H # include #endif #ifdef HAVE_STDINT_H # include #endif #ifdef HAVE_STRINGS_H # include #endif #ifdef HAVE_SYS_TYPES_H # include #endif #ifdef HAVE_SYS_STAT_H # include #endif #ifdef HAVE_UNISTD_H # include #endif" ac_header_c_list= ac_subst_vars='am__EXEEXT_FALSE am__EXEEXT_TRUE LTLIBOBJS LIBOBJS WITH_GTK_FALSE WITH_GTK_TRUE GLIB_LIBS GLIB_CFLAGS GTK_LIBS GTK_CFLAGS PPP_WITH_FILTER_FALSE PPP_WITH_FILTER_TRUE WITH_PCAP_FALSE WITH_PCAP_TRUE PCAP_LDFLAGS PCAP_LIBS PCAP_CFLAGS PPP_WITH_PAM_FALSE PPP_WITH_PAM_TRUE WITH_LIBPAM_FALSE WITH_LIBPAM_TRUE PAM_LDFLAGS PAM_LIBS PAM_CFLAGS WITH_LIBATM_FALSE WITH_LIBATM_TRUE ATM_LDFLAGS ATM_LIBS ATM_CFLAGS WITH_SRP_FALSE WITH_SRP_TRUE SRP_LDFLAGS SRP_LIBS SRP_CFLAGS OPENSSL_HAVE_DES_FALSE OPENSSL_HAVE_DES_TRUE OPENSSL_HAVE_SHA_FALSE OPENSSL_HAVE_SHA_TRUE OPENSSL_HAVE_MD5_FALSE OPENSSL_HAVE_MD5_TRUE OPENSSL_HAVE_MD4_FALSE OPENSSL_HAVE_MD4_TRUE CPP PPP_WITH_OPENSSL_FALSE PPP_WITH_OPENSSL_TRUE OPENSSL_LDFLAGS OPENSSL_LIBS OPENSSL_INCLUDES SYSTEM_CA_PATH PPP_WITH_SYSTEM_CA_PATH_FALSE PPP_WITH_SYSTEM_CA_PATH_TRUE PPPD_LOGFILE_DIR PPPD_RUNTIME_DIR PPPD_PLUGIN_DIR PPP_WITH_PEAP_FALSE PPP_WITH_PEAP_TRUE PPP_WITH_EAPTLS_FALSE PPP_WITH_EAPTLS_TRUE PPP_WITH_PLUGINS_FALSE PPP_WITH_PLUGINS_TRUE PPP_WITH_TDB_FALSE PPP_WITH_TDB_TRUE PPP_WITH_MULTILINK_FALSE PPP_WITH_MULTILINK_TRUE PPP_WITH_IPV6CP_FALSE PPP_WITH_IPV6CP_TRUE PPP_WITH_MPPE_FALSE PPP_WITH_MPPE_TRUE PPP_WITH_CHAPMS_FALSE PPP_WITH_CHAPMS_TRUE PPP_WITH_CBCP_FALSE PPP_WITH_CBCP_TRUE SYSTEMD_LIBS SYSTEMD_CFLAGS WITH_SYSTEMD_FALSE WITH_SYSTEMD_TRUE CRYPT_LIBS UTIL_LIBS SUNOS_FALSE SUNOS_TRUE LINUX_FALSE LINUX_TRUE PKG_CONFIG_LIBDIR PKG_CONFIG_PATH PKG_CONFIG LT_SYS_LIBRARY_PATH OTOOL64 OTOOL LIPO NMEDIT DSYMUTIL MANIFEST_TOOL RANLIB ac_ct_AR AR DLLTOOL OBJDUMP FILECMD NM ac_ct_DUMPBIN DUMPBIN LD FGREP EGREP GREP SED host_os host_vendor host_cpu host build_os build_vendor build_cpu build LIBTOOL LN_S am__fastdepCC_FALSE am__fastdepCC_TRUE CCDEPMODE am__nodep AMDEPBACKSLASH AMDEP_FALSE AMDEP_TRUE am__include DEPDIR OBJEXT EXEEXT ac_ct_CC CPPFLAGS LDFLAGS CFLAGS CC MAINT MAINTAINER_MODE_FALSE MAINTAINER_MODE_TRUE CSCOPE ETAGS CTAGS am__untar am__tar AMTAR am__leading_dot SET_MAKE AWK mkdir_p MKDIR_P INSTALL_STRIP_PROGRAM STRIP install_sh MAKEINFO AUTOHEADER AUTOMAKE AUTOCONF ACLOCAL VERSION PACKAGE CYGPATH_W am__isrc INSTALL_DATA INSTALL_SCRIPT INSTALL_PROGRAM AM_BACKSLASH AM_DEFAULT_VERBOSITY AM_DEFAULT_V AM_V target_alias host_alias build_alias LIBS ECHO_T ECHO_N ECHO_C DEFS mandir localedir libdir psdir pdfdir dvidir htmldir infodir docdir oldincludedir includedir runstatedir localstatedir sharedstatedir sysconfdir datadir datarootdir libexecdir sbindir bindir program_transform_name prefix exec_prefix PACKAGE_URL PACKAGE_BUGREPORT PACKAGE_STRING PACKAGE_VERSION PACKAGE_TARNAME PACKAGE_NAME PATH_SEPARATOR SHELL am__quote' ac_subst_files='' ac_user_opts=' enable_option_checking enable_silent_rules enable_maintainer_mode enable_static enable_dependency_tracking enable_shared with_pic enable_fast_install with_aix_soname with_gnu_ld with_sysroot enable_libtool_lock enable_systemd enable_cbcp enable_microsoft_extensions enable_mslanman enable_ipv6cp enable_multilink enable_plugins enable_eaptls enable_peap enable_openssl_engine with_plugin_dir with_runtime_dir with_logfile_dir with_system_ca_path with_openssl with_srp with_atm with_pam with_pcap with_gtk ' ac_precious_vars='build_alias host_alias target_alias CC CFLAGS LDFLAGS LIBS CPPFLAGS LT_SYS_LIBRARY_PATH PKG_CONFIG PKG_CONFIG_PATH PKG_CONFIG_LIBDIR SYSTEMD_CFLAGS SYSTEMD_LIBS CPP GTK_CFLAGS GTK_LIBS GLIB_CFLAGS GLIB_LIBS' # Initialize some variables set by options. ac_init_help= ac_init_version=false ac_unrecognized_opts= ac_unrecognized_sep= # The variables have the same names as the options, with # dashes changed to underlines. cache_file=/dev/null exec_prefix=NONE no_create= no_recursion= prefix=NONE program_prefix=NONE program_suffix=NONE program_transform_name=s,x,x, silent= site= srcdir= verbose= x_includes=NONE x_libraries=NONE # Installation directory options. # These are left unexpanded so users can "make install exec_prefix=/foo" # and all the variables that are supposed to be based on exec_prefix # by default will actually change. # Use braces instead of parens because sh, perl, etc. also accept them. # (The list follows the same order as the GNU Coding Standards.) bindir='${exec_prefix}/bin' sbindir='${exec_prefix}/sbin' libexecdir='${exec_prefix}/libexec' datarootdir='${prefix}/share' datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' runstatedir='${localstatedir}/run' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' infodir='${datarootdir}/info' htmldir='${docdir}' dvidir='${docdir}' pdfdir='${docdir}' psdir='${docdir}' libdir='${exec_prefix}/lib' localedir='${datarootdir}/locale' mandir='${datarootdir}/man' ac_prev= ac_dashdash= for ac_option do # If the previous option needs an argument, assign it. if test -n "$ac_prev"; then eval $ac_prev=\$ac_option ac_prev= continue fi case $ac_option in *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; *=) ac_optarg= ;; *) ac_optarg=yes ;; esac case $ac_dashdash$ac_option in --) ac_dashdash=yes ;; -bindir | --bindir | --bindi | --bind | --bin | --bi) ac_prev=bindir ;; -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) bindir=$ac_optarg ;; -build | --build | --buil | --bui | --bu) ac_prev=build_alias ;; -build=* | --build=* | --buil=* | --bui=* | --bu=*) build_alias=$ac_optarg ;; -cache-file | --cache-file | --cache-fil | --cache-fi \ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ac_prev=cache_file ;; -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) cache_file=$ac_optarg ;; --config-cache | -C) cache_file=config.cache ;; -datadir | --datadir | --datadi | --datad) ac_prev=datadir ;; -datadir=* | --datadir=* | --datadi=* | --datad=*) datadir=$ac_optarg ;; -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ | --dataroo | --dataro | --datar) ac_prev=datarootdir ;; -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) datarootdir=$ac_optarg ;; -disable-* | --disable-*) ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: \`$ac_useropt'" ac_useropt_orig=$ac_useropt ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=no ;; -docdir | --docdir | --docdi | --doc | --do) ac_prev=docdir ;; -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) docdir=$ac_optarg ;; -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) ac_prev=dvidir ;; -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) dvidir=$ac_optarg ;; -enable-* | --enable-*) ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: \`$ac_useropt'" ac_useropt_orig=$ac_useropt ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=\$ac_optarg ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ | --exec | --exe | --ex) ac_prev=exec_prefix ;; -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ | --exec=* | --exe=* | --ex=*) exec_prefix=$ac_optarg ;; -gas | --gas | --ga | --g) # Obsolete; use --with-gas. with_gas=yes ;; -help | --help | --hel | --he | -h) ac_init_help=long ;; -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) ac_init_help=recursive ;; -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) ac_init_help=short ;; -host | --host | --hos | --ho) ac_prev=host_alias ;; -host=* | --host=* | --hos=* | --ho=*) host_alias=$ac_optarg ;; -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) ac_prev=htmldir ;; -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ | --ht=*) htmldir=$ac_optarg ;; -includedir | --includedir | --includedi | --included | --include \ | --includ | --inclu | --incl | --inc) ac_prev=includedir ;; -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ | --includ=* | --inclu=* | --incl=* | --inc=*) includedir=$ac_optarg ;; -infodir | --infodir | --infodi | --infod | --info | --inf) ac_prev=infodir ;; -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) infodir=$ac_optarg ;; -libdir | --libdir | --libdi | --libd) ac_prev=libdir ;; -libdir=* | --libdir=* | --libdi=* | --libd=*) libdir=$ac_optarg ;; -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ | --libexe | --libex | --libe) ac_prev=libexecdir ;; -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ | --libexe=* | --libex=* | --libe=*) libexecdir=$ac_optarg ;; -localedir | --localedir | --localedi | --localed | --locale) ac_prev=localedir ;; -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) localedir=$ac_optarg ;; -localstatedir | --localstatedir | --localstatedi | --localstated \ | --localstate | --localstat | --localsta | --localst | --locals) ac_prev=localstatedir ;; -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) localstatedir=$ac_optarg ;; -mandir | --mandir | --mandi | --mand | --man | --ma | --m) ac_prev=mandir ;; -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) mandir=$ac_optarg ;; -nfp | --nfp | --nf) # Obsolete; use --without-fp. with_fp=no ;; -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c | -n) no_create=yes ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) no_recursion=yes ;; -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ | --oldin | --oldi | --old | --ol | --o) ac_prev=oldincludedir ;; -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) oldincludedir=$ac_optarg ;; -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ac_prev=prefix ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) prefix=$ac_optarg ;; -program-prefix | --program-prefix | --program-prefi | --program-pref \ | --program-pre | --program-pr | --program-p) ac_prev=program_prefix ;; -program-prefix=* | --program-prefix=* | --program-prefi=* \ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) program_prefix=$ac_optarg ;; -program-suffix | --program-suffix | --program-suffi | --program-suff \ | --program-suf | --program-su | --program-s) ac_prev=program_suffix ;; -program-suffix=* | --program-suffix=* | --program-suffi=* \ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) program_suffix=$ac_optarg ;; -program-transform-name | --program-transform-name \ | --program-transform-nam | --program-transform-na \ | --program-transform-n | --program-transform- \ | --program-transform | --program-transfor \ | --program-transfo | --program-transf \ | --program-trans | --program-tran \ | --progr-tra | --program-tr | --program-t) ac_prev=program_transform_name ;; -program-transform-name=* | --program-transform-name=* \ | --program-transform-nam=* | --program-transform-na=* \ | --program-transform-n=* | --program-transform-=* \ | --program-transform=* | --program-transfor=* \ | --program-transfo=* | --program-transf=* \ | --program-trans=* | --program-tran=* \ | --progr-tra=* | --program-tr=* | --program-t=*) program_transform_name=$ac_optarg ;; -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) ac_prev=pdfdir ;; -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) pdfdir=$ac_optarg ;; -psdir | --psdir | --psdi | --psd | --ps) ac_prev=psdir ;; -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) psdir=$ac_optarg ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; -runstatedir | --runstatedir | --runstatedi | --runstated \ | --runstate | --runstat | --runsta | --runst | --runs \ | --run | --ru | --r) ac_prev=runstatedir ;; -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \ | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \ | --run=* | --ru=* | --r=*) runstatedir=$ac_optarg ;; -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ | --sbi=* | --sb=*) sbindir=$ac_optarg ;; -sharedstatedir | --sharedstatedir | --sharedstatedi \ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ | --sharedst | --shareds | --shared | --share | --shar \ | --sha | --sh) ac_prev=sharedstatedir ;; -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ | --sha=* | --sh=*) sharedstatedir=$ac_optarg ;; -site | --site | --sit) ac_prev=site ;; -site=* | --site=* | --sit=*) site=$ac_optarg ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) srcdir=$ac_optarg ;; -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ | --syscon | --sysco | --sysc | --sys | --sy) ac_prev=sysconfdir ;; -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) sysconfdir=$ac_optarg ;; -target | --target | --targe | --targ | --tar | --ta | --t) ac_prev=target_alias ;; -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target_alias=$ac_optarg ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers | -V) ac_init_version=: ;; -with-* | --with-*) ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: \`$ac_useropt'" ac_useropt_orig=$ac_useropt ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=\$ac_optarg ;; -without-* | --without-*) ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: \`$ac_useropt'" ac_useropt_orig=$ac_useropt ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=no ;; --x) # Obsolete; use --with-x. with_x=yes ;; -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ | --x-incl | --x-inc | --x-in | --x-i) ac_prev=x_includes ;; -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) x_includes=$ac_optarg ;; -x-libraries | --x-libraries | --x-librarie | --x-librari \ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) ac_prev=x_libraries ;; -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries=$ac_optarg ;; -*) as_fn_error $? "unrecognized option: \`$ac_option' Try \`$0 --help' for more information" ;; *=*) ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` # Reject names that are not valid shell variable names. case $ac_envvar in #( '' | [0-9]* | *[!_$as_cr_alnum]* ) as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; esac eval $ac_envvar=\$ac_optarg export $ac_envvar ;; *) # FIXME: should be removed in autoconf 3.0. printf "%s\n" "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && printf "%s\n" "$as_me: WARNING: invalid host type: $ac_option" >&2 : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" ;; esac done if test -n "$ac_prev"; then ac_option=--`echo $ac_prev | sed 's/_/-/g'` as_fn_error $? "missing argument to $ac_option" fi if test -n "$ac_unrecognized_opts"; then case $enable_option_checking in no) ;; fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; *) printf "%s\n" "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; esac fi # Check all directory arguments for consistency. for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ libdir localedir mandir runstatedir do eval ac_val=\$$ac_var # Remove trailing slashes. case $ac_val in */ ) ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` eval $ac_var=\$ac_val;; esac # Be sure to have absolute directory names. case $ac_val in [\\/$]* | ?:[\\/]* ) continue;; NONE | '' ) case $ac_var in *prefix ) continue;; esac;; esac as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" done # There might be people who depend on the old broken behavior: `$host' # used to hold the argument of --host etc. # FIXME: To remove some day. build=$build_alias host=$host_alias target=$target_alias # FIXME: To remove some day. if test "x$host_alias" != x; then if test "x$build_alias" = x; then cross_compiling=maybe elif test "x$build_alias" != "x$host_alias"; then cross_compiling=yes fi fi ac_tool_prefix= test -n "$host_alias" && ac_tool_prefix=$host_alias- test "$silent" = yes && exec 6>/dev/null ac_pwd=`pwd` && test -n "$ac_pwd" && ac_ls_di=`ls -di .` && ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || as_fn_error $? "working directory cannot be determined" test "X$ac_ls_di" = "X$ac_pwd_ls_di" || as_fn_error $? "pwd does not report name of working directory" # Find the source files, if location was not specified. if test -z "$srcdir"; then ac_srcdir_defaulted=yes # Try the directory containing this script, then the parent directory. ac_confdir=`$as_dirname -- "$as_myself" || $as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_myself" : 'X\(//\)[^/]' \| \ X"$as_myself" : 'X\(//\)$' \| \ X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || printf "%s\n" X"$as_myself" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` srcdir=$ac_confdir if test ! -r "$srcdir/$ac_unique_file"; then srcdir=.. fi else ac_srcdir_defaulted=no fi if test ! -r "$srcdir/$ac_unique_file"; then test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" fi ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" ac_abs_confdir=`( cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" pwd)` # When building in place, set srcdir=. if test "$ac_abs_confdir" = "$ac_pwd"; then srcdir=. fi # Remove unnecessary trailing slashes from srcdir. # Double slashes in file names in object file debugging info # mess up M-x gdb in Emacs. case $srcdir in */) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; esac for ac_var in $ac_precious_vars; do eval ac_env_${ac_var}_set=\${${ac_var}+set} eval ac_env_${ac_var}_value=\$${ac_var} eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} eval ac_cv_env_${ac_var}_value=\$${ac_var} done # # Report the --help message. # if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF \`configure' configures ppp 2.5.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... To assign environment variables (e.g., CC, CFLAGS...), specify them as VAR=VALUE. See below for descriptions of some of the useful variables. Defaults for the options are specified in brackets. Configuration: -h, --help display this help and exit --help=short display options specific to this package --help=recursive display the short help of all the included packages -V, --version display version information and exit -q, --quiet, --silent do not print \`checking ...' messages --cache-file=FILE cache test results in FILE [disabled] -C, --config-cache alias for \`--cache-file=config.cache' -n, --no-create do not create output files --srcdir=DIR find the sources in DIR [configure dir or \`..'] Installation directories: --prefix=PREFIX install architecture-independent files in PREFIX [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [PREFIX] By default, \`make install' will install all the files in \`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify an installation prefix other than \`$ac_default_prefix' using \`--prefix', for instance \`--prefix=\$HOME'. For better control, use the options below. Fine tuning of the installation directories: --bindir=DIR user executables [EPREFIX/bin] --sbindir=DIR system admin executables [EPREFIX/sbin] --libexecdir=DIR program executables [EPREFIX/libexec] --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] --datadir=DIR read-only architecture-independent data [DATAROOTDIR] --infodir=DIR info documentation [DATAROOTDIR/info] --localedir=DIR locale-dependent data [DATAROOTDIR/locale] --mandir=DIR man documentation [DATAROOTDIR/man] --docdir=DIR documentation root [DATAROOTDIR/doc/ppp] --htmldir=DIR html documentation [DOCDIR] --dvidir=DIR dvi documentation [DOCDIR] --pdfdir=DIR pdf documentation [DOCDIR] --psdir=DIR ps documentation [DOCDIR] _ACEOF cat <<\_ACEOF Program names: --program-prefix=PREFIX prepend PREFIX to installed program names --program-suffix=SUFFIX append SUFFIX to installed program names --program-transform-name=PROGRAM run sed PROGRAM on installed program names System types: --build=BUILD configure for building on BUILD [guessed] --host=HOST cross-compile to build programs to run on HOST [BUILD] _ACEOF fi if test -n "$ac_init_help"; then case $ac_init_help in short | recursive ) echo "Configuration of ppp 2.5.0:";; esac cat <<\_ACEOF Optional Features: --disable-option-checking ignore unrecognized --enable/--with options --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --enable-silent-rules less verbose build output (undo: "make V=1") --disable-silent-rules verbose build output (undo: "make V=0") --disable-maintainer-mode disable make rules and dependencies not useful (and sometimes confusing) to the casual installer --enable-static[=PKGS] build static libraries [default=no] --enable-dependency-tracking do not reject slow dependency extractors --disable-dependency-tracking speeds up one-time build --enable-shared[=PKGS] build shared libraries [default=yes] --enable-fast-install[=PKGS] optimize for fast installation [default=yes] --disable-libtool-lock avoid locking (might break parallel builds) --enable-systemd Enable support for systemd notification --enable-cbcp Enable Callback Protocol --disable-microsoft-extensions Disable Microsoft CHAP / MPPE extensions --enable-mslanman Enable Microsoft LAN Manager support --disable-ipv6cp Disable IPv6 Control Protocol --enable-multilink Enable multilink support --disable-plugins Disable support for loadable plugins --disable-eaptls Disable EAP-TLS authentication support --disable-peap Disable PEAP authentication support --disable-openssl-engine Disable OpenSSL engine support Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --with-pic[=PKGS] try to use only PIC/non-PIC objects [default=use both] --with-aix-soname=aix|svr4|both shared library versioning (aka "SONAME") variant to provide on AIX, [default=aix]. --with-gnu-ld assume the C compiler uses GNU ld [default=no] --with-sysroot[=DIR] Search for dependent libraries within DIR (or the compiler's sysroot if not specified). --with-plugin-dir=DIR Specify the plugin directory for pppd --with-runtime-dir=DIR Specify the runtime directory for pppd --with-logfile-dir=DIR Specify the log directory for pppd --with-system-ca-path=/path/to/ssl/certs path to system CA certificates --with-openssl=DIR With openssl support, see http://www.openssl.org --with-srp=DIR With libsrp support, see http://srp.stanford.edu --with-atm=DIR With libatm support, see http://linux-atm.sourceforge.net --with-pam=DIR With libpam support, see ftp.redhat.com:/pub/pam --with-pcap=DIR With libpcap support, see https://www.tcpdump.org --with-gtk Build contributions with the GTK+ interface Some influential environment variables: CC C compiler command CFLAGS C compiler flags LDFLAGS linker flags, e.g. -L if you have libraries in a nonstandard directory LIBS libraries to pass to the linker, e.g. -l CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if you have headers in a nonstandard directory LT_SYS_LIBRARY_PATH User-defined run-time library search path. PKG_CONFIG path to pkg-config utility PKG_CONFIG_PATH directories to add to pkg-config's search path PKG_CONFIG_LIBDIR path overriding pkg-config's built-in search path SYSTEMD_CFLAGS C compiler flags for SYSTEMD, overriding pkg-config SYSTEMD_LIBS linker flags for SYSTEMD, overriding pkg-config CPP C preprocessor GTK_CFLAGS C compiler flags for GTK, overriding pkg-config GTK_LIBS linker flags for GTK, overriding pkg-config GLIB_CFLAGS C compiler flags for GLIB, overriding pkg-config GLIB_LIBS linker flags for GLIB, overriding pkg-config Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. Report bugs to . _ACEOF ac_status=$? fi if test "$ac_init_help" = "recursive"; then # If there are subdirs, report their specific --help. for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue test -d "$ac_dir" || { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || continue ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`printf "%s\n" "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`printf "%s\n" "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix cd "$ac_dir" || { ac_status=$?; continue; } # Check for configure.gnu first; this name is used for a wrapper for # Metaconfig's "Configure" on case-insensitive file systems. if test -f "$ac_srcdir/configure.gnu"; then echo && $SHELL "$ac_srcdir/configure.gnu" --help=recursive elif test -f "$ac_srcdir/configure"; then echo && $SHELL "$ac_srcdir/configure" --help=recursive else printf "%s\n" "$as_me: WARNING: no configuration information is in $ac_dir" >&2 fi || ac_status=$? cd "$ac_pwd" || { ac_status=$?; break; } done fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF ppp configure 2.5.0 generated by GNU Autoconf 2.71 Copyright (C) 2021 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF exit fi ## ------------------------ ## ## Autoconf initialization. ## ## ------------------------ ## # ac_fn_c_try_compile LINENO # -------------------------- # Try to compile conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext conftest.beam if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext then : ac_retval=0 else $as_nop printf "%s\n" "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_compile # ac_fn_c_try_link LINENO # ----------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_link () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext conftest.beam conftest$ac_exeext if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_link") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || test -x conftest$ac_exeext } then : ac_retval=0 else $as_nop printf "%s\n" "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would # interfere with the next link command; also delete a directory that is # left behind by Apple's compiler. We do this before executing the actions. rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_link # ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES # ------------------------------------------------------- # Tests whether HEADER exists and can be compiled using the include files in # INCLUDES, setting the cache variable VAR accordingly. ac_fn_c_check_header_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 printf %s "checking for $2... " >&6; } if eval test \${$3+y} then : printf %s "(cached) " >&6 else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_c_try_compile "$LINENO" then : eval "$3=yes" else $as_nop eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi eval ac_res=\$$3 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 printf "%s\n" "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_header_compile # ac_fn_c_check_func LINENO FUNC VAR # ---------------------------------- # Tests whether FUNC exists, setting the cache variable VAR accordingly ac_fn_c_check_func () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 printf %s "checking for $2... " >&6; } if eval test \${$3+y} then : printf %s "(cached) " >&6 else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Define $2 to an innocuous variant, in case declares $2. For example, HP-UX 11i declares gettimeofday. */ #define $2 innocuous_$2 /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $2 (); below. */ #include #undef $2 /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $2 (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$2 || defined __stub___$2 choke me #endif int main (void) { return $2 (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : eval "$3=yes" else $as_nop eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext fi eval ac_res=\$$3 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 printf "%s\n" "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_func # ac_fn_c_check_type LINENO TYPE VAR INCLUDES # ------------------------------------------- # Tests whether TYPE exists after having included INCLUDES, setting cache # variable VAR accordingly. ac_fn_c_check_type () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 printf %s "checking for $2... " >&6; } if eval test \${$3+y} then : printf %s "(cached) " >&6 else $as_nop eval "$3=no" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main (void) { if (sizeof ($2)) return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main (void) { if (sizeof (($2))) return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : else $as_nop eval "$3=yes" fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi eval ac_res=\$$3 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 printf "%s\n" "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_type # ac_fn_c_try_run LINENO # ---------------------- # Try to run conftest.$ac_ext, and return whether this succeeded. Assumes that # executables *can* be run. ac_fn_c_try_run () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; } then : ac_retval=0 else $as_nop printf "%s\n" "$as_me: program exited with status $ac_status" >&5 printf "%s\n" "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=$ac_status fi rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_run # ac_fn_c_compute_int LINENO EXPR VAR INCLUDES # -------------------------------------------- # Tries to find the compile-time value of EXPR in a program that includes # INCLUDES, setting VAR accordingly. Returns whether the value could be # computed ac_fn_c_compute_int () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if test "$cross_compiling" = yes; then # Depending upon the size, compute the lo and hi bounds. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main (void) { static int test_array [1 - 2 * !(($2) >= 0)]; test_array [0] = 0; return test_array [0]; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : ac_lo=0 ac_mid=0 while :; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main (void) { static int test_array [1 - 2 * !(($2) <= $ac_mid)]; test_array [0] = 0; return test_array [0]; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : ac_hi=$ac_mid; break else $as_nop as_fn_arith $ac_mid + 1 && ac_lo=$as_val if test $ac_lo -le $ac_mid; then ac_lo= ac_hi= break fi as_fn_arith 2 '*' $ac_mid + 1 && ac_mid=$as_val fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext done else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main (void) { static int test_array [1 - 2 * !(($2) < 0)]; test_array [0] = 0; return test_array [0]; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : ac_hi=-1 ac_mid=-1 while :; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main (void) { static int test_array [1 - 2 * !(($2) >= $ac_mid)]; test_array [0] = 0; return test_array [0]; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : ac_lo=$ac_mid; break else $as_nop as_fn_arith '(' $ac_mid ')' - 1 && ac_hi=$as_val if test $ac_mid -le $ac_hi; then ac_lo= ac_hi= break fi as_fn_arith 2 '*' $ac_mid && ac_mid=$as_val fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext done else $as_nop ac_lo= ac_hi= fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext # Binary search between lo and hi bounds. while test "x$ac_lo" != "x$ac_hi"; do as_fn_arith '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo && ac_mid=$as_val cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main (void) { static int test_array [1 - 2 * !(($2) <= $ac_mid)]; test_array [0] = 0; return test_array [0]; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : ac_hi=$ac_mid else $as_nop as_fn_arith '(' $ac_mid ')' + 1 && ac_lo=$as_val fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext done case $ac_lo in #(( ?*) eval "$3=\$ac_lo"; ac_retval=0 ;; '') ac_retval=1 ;; esac else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 static long int longval (void) { return $2; } static unsigned long int ulongval (void) { return $2; } #include #include int main (void) { FILE *f = fopen ("conftest.val", "w"); if (! f) return 1; if (($2) < 0) { long int i = longval (); if (i != ($2)) return 1; fprintf (f, "%ld", i); } else { unsigned long int i = ulongval (); if (i != ($2)) return 1; fprintf (f, "%lu", i); } /* Do not output a trailing newline, as this causes \r\n confusion on some platforms. */ return ferror (f) || fclose (f) != 0; ; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO" then : echo >>conftest.val; read $3 &5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } > conftest.i && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err } then : ac_retval=0 else $as_nop printf "%s\n" "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_cpp ac_configure_args_raw= for ac_arg do case $ac_arg in *\'*) ac_arg=`printf "%s\n" "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac as_fn_append ac_configure_args_raw " '$ac_arg'" done case $ac_configure_args_raw in *$as_nl*) ac_safe_unquote= ;; *) ac_unsafe_z='|&;<>()$`\\"*?[ '' ' # This string ends in space, tab. ac_unsafe_a="$ac_unsafe_z#~" ac_safe_unquote="s/ '\\([^$ac_unsafe_a][^$ac_unsafe_z]*\\)'/ \\1/g" ac_configure_args_raw=` printf "%s\n" "$ac_configure_args_raw" | sed "$ac_safe_unquote"`;; esac cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. It was created by ppp $as_me 2.5.0, which was generated by GNU Autoconf 2.71. Invocation command line was $ $0$ac_configure_args_raw _ACEOF exec 5>>config.log { cat <<_ASUNAME ## --------- ## ## Platform. ## ## --------- ## hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` /bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` /bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` /usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` /bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` /bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` _ASUNAME as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac printf "%s\n" "PATH: $as_dir" done IFS=$as_save_IFS } >&5 cat >&5 <<_ACEOF ## ----------- ## ## Core tests. ## ## ----------- ## _ACEOF # Keep a trace of the command line. # Strip out --no-create and --no-recursion so they do not pile up. # Strip out --silent because we don't want to record it for future runs. # Also quote any args containing shell meta-characters. # Make two passes to allow for proper duplicate-argument suppression. ac_configure_args= ac_configure_args0= ac_configure_args1= ac_must_keep_next=false for ac_pass in 1 2 do for ac_arg do case $ac_arg in -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) continue ;; *\'*) ac_arg=`printf "%s\n" "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac case $ac_pass in 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; 2) as_fn_append ac_configure_args1 " '$ac_arg'" if test $ac_must_keep_next = true; then ac_must_keep_next=false # Got value, back to normal. else case $ac_arg in *=* | --config-cache | -C | -disable-* | --disable-* \ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ | -with-* | --with-* | -without-* | --without-* | --x) case "$ac_configure_args0 " in "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; esac ;; -* ) ac_must_keep_next=true ;; esac fi as_fn_append ac_configure_args " '$ac_arg'" ;; esac done done { ac_configure_args0=; unset ac_configure_args0;} { ac_configure_args1=; unset ac_configure_args1;} # When interrupted or exit'd, cleanup temporary files, and complete # config.log. We remove comments because anyway the quotes in there # would cause problems or look ugly. # WARNING: Use '\'' to represent an apostrophe within the trap. # WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. trap 'exit_status=$? # Sanitize IFS. IFS=" "" $as_nl" # Save into config.log some information that might help in debugging. { echo printf "%s\n" "## ---------------- ## ## Cache variables. ## ## ---------------- ##" echo # The following way of writing the cache mishandles newlines in values, ( for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 printf "%s\n" "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( *${as_nl}ac_space=\ *) sed -n \ "s/'\''/'\''\\\\'\'''\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" ;; #( *) sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) echo printf "%s\n" "## ----------------- ## ## Output variables. ## ## ----------------- ##" echo for ac_var in $ac_subst_vars do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`printf "%s\n" "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac printf "%s\n" "$ac_var='\''$ac_val'\''" done | sort echo if test -n "$ac_subst_files"; then printf "%s\n" "## ------------------- ## ## File substitutions. ## ## ------------------- ##" echo for ac_var in $ac_subst_files do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`printf "%s\n" "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac printf "%s\n" "$ac_var='\''$ac_val'\''" done | sort echo fi if test -s confdefs.h; then printf "%s\n" "## ----------- ## ## confdefs.h. ## ## ----------- ##" echo cat confdefs.h echo fi test "$ac_signal" != 0 && printf "%s\n" "$as_me: caught signal $ac_signal" printf "%s\n" "$as_me: exit $exit_status" } >&5 rm -f core *.core core.conftest.* && rm -f -r conftest* confdefs* conf$$* $ac_clean_files && exit $exit_status ' 0 for ac_signal in 1 2 13 15; do trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal done ac_signal=0 # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -f -r conftest* confdefs.h printf "%s\n" "/* confdefs.h */" > confdefs.h # Predefined preprocessor variables. printf "%s\n" "#define PACKAGE_NAME \"$PACKAGE_NAME\"" >>confdefs.h printf "%s\n" "#define PACKAGE_TARNAME \"$PACKAGE_TARNAME\"" >>confdefs.h printf "%s\n" "#define PACKAGE_VERSION \"$PACKAGE_VERSION\"" >>confdefs.h printf "%s\n" "#define PACKAGE_STRING \"$PACKAGE_STRING\"" >>confdefs.h printf "%s\n" "#define PACKAGE_BUGREPORT \"$PACKAGE_BUGREPORT\"" >>confdefs.h printf "%s\n" "#define PACKAGE_URL \"$PACKAGE_URL\"" >>confdefs.h # Let the site file select an alternate cache file if it wants to. # Prefer an explicitly selected file to automatically selected ones. if test -n "$CONFIG_SITE"; then ac_site_files="$CONFIG_SITE" elif test "x$prefix" != xNONE; then ac_site_files="$prefix/share/config.site $prefix/etc/config.site" else ac_site_files="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" fi for ac_site_file in $ac_site_files do case $ac_site_file in #( */*) : ;; #( *) : ac_site_file=./$ac_site_file ;; esac if test -f "$ac_site_file" && test -r "$ac_site_file"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 printf "%s\n" "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 . "$ac_site_file" \ || { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "failed to load site script $ac_site_file See \`config.log' for more details" "$LINENO" 5; } fi done if test -r "$cache_file"; then # Some versions of bash will fail to source /dev/null (special files # actually), so we avoid doing that. DJGPP emulates it as a regular file. if test /dev/null != "$cache_file" && test -f "$cache_file"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 printf "%s\n" "$as_me: loading cache $cache_file" >&6;} case $cache_file in [\\/]* | ?:[\\/]* ) . "$cache_file";; *) . "./$cache_file";; esac fi else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 printf "%s\n" "$as_me: creating cache $cache_file" >&6;} >$cache_file fi # Test code for whether the C compiler supports C89 (global declarations) ac_c_conftest_c89_globals=' /* Does the compiler advertise C89 conformance? Do not test the value of __STDC__, because some compilers set it to 0 while being otherwise adequately conformant. */ #if !defined __STDC__ # error "Compiler does not advertise C89 conformance" #endif #include #include struct stat; /* Most of the following tests are stolen from RCS 5.7 src/conf.sh. */ struct buf { int x; }; struct buf * (*rcsopen) (struct buf *, struct stat *, int); static char *e (p, i) char **p; int i; { return p[i]; } static char *f (char * (*g) (char **, int), char **p, ...) { char *s; va_list v; va_start (v,p); s = g (p, va_arg (v,int)); va_end (v); return s; } /* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has function prototypes and stuff, but not \xHH hex character constants. These do not provoke an error unfortunately, instead are silently treated as an "x". The following induces an error, until -std is added to get proper ANSI mode. Curiously \x00 != x always comes out true, for an array size at least. It is necessary to write \x00 == 0 to get something that is true only with -std. */ int osf4_cc_array ['\''\x00'\'' == 0 ? 1 : -1]; /* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters inside strings and character constants. */ #define FOO(x) '\''x'\'' int xlc6_cc_array[FOO(a) == '\''x'\'' ? 1 : -1]; int test (int i, double x); struct s1 {int (*f) (int a);}; struct s2 {int (*f) (double a);}; int pairnames (int, char **, int *(*)(struct buf *, struct stat *, int), int, int);' # Test code for whether the C compiler supports C89 (body of main). ac_c_conftest_c89_main=' ok |= (argc == 0 || f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]); ' # Test code for whether the C compiler supports C99 (global declarations) ac_c_conftest_c99_globals=' // Does the compiler advertise C99 conformance? #if !defined __STDC_VERSION__ || __STDC_VERSION__ < 199901L # error "Compiler does not advertise C99 conformance" #endif #include extern int puts (const char *); extern int printf (const char *, ...); extern int dprintf (int, const char *, ...); extern void *malloc (size_t); // Check varargs macros. These examples are taken from C99 6.10.3.5. // dprintf is used instead of fprintf to avoid needing to declare // FILE and stderr. #define debug(...) dprintf (2, __VA_ARGS__) #define showlist(...) puts (#__VA_ARGS__) #define report(test,...) ((test) ? puts (#test) : printf (__VA_ARGS__)) static void test_varargs_macros (void) { int x = 1234; int y = 5678; debug ("Flag"); debug ("X = %d\n", x); showlist (The first, second, and third items.); report (x>y, "x is %d but y is %d", x, y); } // Check long long types. #define BIG64 18446744073709551615ull #define BIG32 4294967295ul #define BIG_OK (BIG64 / BIG32 == 4294967297ull && BIG64 % BIG32 == 0) #if !BIG_OK #error "your preprocessor is broken" #endif #if BIG_OK #else #error "your preprocessor is broken" #endif static long long int bignum = -9223372036854775807LL; static unsigned long long int ubignum = BIG64; struct incomplete_array { int datasize; double data[]; }; struct named_init { int number; const wchar_t *name; double average; }; typedef const char *ccp; static inline int test_restrict (ccp restrict text) { // See if C++-style comments work. // Iterate through items via the restricted pointer. // Also check for declarations in for loops. for (unsigned int i = 0; *(text+i) != '\''\0'\''; ++i) continue; return 0; } // Check varargs and va_copy. static bool test_varargs (const char *format, ...) { va_list args; va_start (args, format); va_list args_copy; va_copy (args_copy, args); const char *str = ""; int number = 0; float fnumber = 0; while (*format) { switch (*format++) { case '\''s'\'': // string str = va_arg (args_copy, const char *); break; case '\''d'\'': // int number = va_arg (args_copy, int); break; case '\''f'\'': // float fnumber = va_arg (args_copy, double); break; default: break; } } va_end (args_copy); va_end (args); return *str && number && fnumber; } ' # Test code for whether the C compiler supports C99 (body of main). ac_c_conftest_c99_main=' // Check bool. _Bool success = false; success |= (argc != 0); // Check restrict. if (test_restrict ("String literal") == 0) success = true; char *restrict newvar = "Another string"; // Check varargs. success &= test_varargs ("s, d'\'' f .", "string", 65, 34.234); test_varargs_macros (); // Check flexible array members. struct incomplete_array *ia = malloc (sizeof (struct incomplete_array) + (sizeof (double) * 10)); ia->datasize = 10; for (int i = 0; i < ia->datasize; ++i) ia->data[i] = i * 1.234; // Check named initializers. struct named_init ni = { .number = 34, .name = L"Test wide string", .average = 543.34343, }; ni.number = 58; int dynamic_array[ni.number]; dynamic_array[0] = argv[0][0]; dynamic_array[ni.number - 1] = 543; // work around unused variable warnings ok |= (!success || bignum == 0LL || ubignum == 0uLL || newvar[0] == '\''x'\'' || dynamic_array[ni.number - 1] != 543); ' # Test code for whether the C compiler supports C11 (global declarations) ac_c_conftest_c11_globals=' // Does the compiler advertise C11 conformance? #if !defined __STDC_VERSION__ || __STDC_VERSION__ < 201112L # error "Compiler does not advertise C11 conformance" #endif // Check _Alignas. char _Alignas (double) aligned_as_double; char _Alignas (0) no_special_alignment; extern char aligned_as_int; char _Alignas (0) _Alignas (int) aligned_as_int; // Check _Alignof. enum { int_alignment = _Alignof (int), int_array_alignment = _Alignof (int[100]), char_alignment = _Alignof (char) }; _Static_assert (0 < -_Alignof (int), "_Alignof is signed"); // Check _Noreturn. int _Noreturn does_not_return (void) { for (;;) continue; } // Check _Static_assert. struct test_static_assert { int x; _Static_assert (sizeof (int) <= sizeof (long int), "_Static_assert does not work in struct"); long int y; }; // Check UTF-8 literals. #define u8 syntax error! char const utf8_literal[] = u8"happens to be ASCII" "another string"; // Check duplicate typedefs. typedef long *long_ptr; typedef long int *long_ptr; typedef long_ptr long_ptr; // Anonymous structures and unions -- taken from C11 6.7.2.1 Example 1. struct anonymous { union { struct { int i; int j; }; struct { int k; long int l; } w; }; int m; } v1; ' # Test code for whether the C compiler supports C11 (body of main). ac_c_conftest_c11_main=' _Static_assert ((offsetof (struct anonymous, i) == offsetof (struct anonymous, w.k)), "Anonymous union alignment botch"); v1.i = 2; v1.w.k = 5; ok |= v1.i != 5; ' # Test code for whether the C compiler supports C11 (complete). ac_c_conftest_c11_program="${ac_c_conftest_c89_globals} ${ac_c_conftest_c99_globals} ${ac_c_conftest_c11_globals} int main (int argc, char **argv) { int ok = 0; ${ac_c_conftest_c89_main} ${ac_c_conftest_c99_main} ${ac_c_conftest_c11_main} return ok; } " # Test code for whether the C compiler supports C99 (complete). ac_c_conftest_c99_program="${ac_c_conftest_c89_globals} ${ac_c_conftest_c99_globals} int main (int argc, char **argv) { int ok = 0; ${ac_c_conftest_c89_main} ${ac_c_conftest_c99_main} return ok; } " # Test code for whether the C compiler supports C89 (complete). ac_c_conftest_c89_program="${ac_c_conftest_c89_globals} int main (int argc, char **argv) { int ok = 0; ${ac_c_conftest_c89_main} return ok; } " as_fn_append ac_header_c_list " stdio.h stdio_h HAVE_STDIO_H" as_fn_append ac_header_c_list " stdlib.h stdlib_h HAVE_STDLIB_H" as_fn_append ac_header_c_list " string.h string_h HAVE_STRING_H" as_fn_append ac_header_c_list " inttypes.h inttypes_h HAVE_INTTYPES_H" as_fn_append ac_header_c_list " stdint.h stdint_h HAVE_STDINT_H" as_fn_append ac_header_c_list " strings.h strings_h HAVE_STRINGS_H" as_fn_append ac_header_c_list " sys/stat.h sys_stat_h HAVE_SYS_STAT_H" as_fn_append ac_header_c_list " sys/types.h sys_types_h HAVE_SYS_TYPES_H" as_fn_append ac_header_c_list " unistd.h unistd_h HAVE_UNISTD_H" # Auxiliary files required by this configure script. ac_aux_files="config.guess config.sub ltmain.sh compile missing install-sh" # Locations in which to look for auxiliary files. ac_aux_dir_candidates="${srcdir}${PATH_SEPARATOR}${srcdir}/..${PATH_SEPARATOR}${srcdir}/../.." # Search for a directory containing all of the required auxiliary files, # $ac_aux_files, from the $PATH-style list $ac_aux_dir_candidates. # If we don't find one directory that contains all the files we need, # we report the set of missing files from the *first* directory in # $ac_aux_dir_candidates and give up. ac_missing_aux_files="" ac_first_candidate=: printf "%s\n" "$as_me:${as_lineno-$LINENO}: looking for aux files: $ac_aux_files" >&5 as_save_IFS=$IFS; IFS=$PATH_SEPARATOR as_found=false for as_dir in $ac_aux_dir_candidates do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac as_found=: printf "%s\n" "$as_me:${as_lineno-$LINENO}: trying $as_dir" >&5 ac_aux_dir_found=yes ac_install_sh= for ac_aux in $ac_aux_files do # As a special case, if "install-sh" is required, that requirement # can be satisfied by any of "install-sh", "install.sh", or "shtool", # and $ac_install_sh is set appropriately for whichever one is found. if test x"$ac_aux" = x"install-sh" then if test -f "${as_dir}install-sh"; then printf "%s\n" "$as_me:${as_lineno-$LINENO}: ${as_dir}install-sh found" >&5 ac_install_sh="${as_dir}install-sh -c" elif test -f "${as_dir}install.sh"; then printf "%s\n" "$as_me:${as_lineno-$LINENO}: ${as_dir}install.sh found" >&5 ac_install_sh="${as_dir}install.sh -c" elif test -f "${as_dir}shtool"; then printf "%s\n" "$as_me:${as_lineno-$LINENO}: ${as_dir}shtool found" >&5 ac_install_sh="${as_dir}shtool install -c" else ac_aux_dir_found=no if $ac_first_candidate; then ac_missing_aux_files="${ac_missing_aux_files} install-sh" else break fi fi else if test -f "${as_dir}${ac_aux}"; then printf "%s\n" "$as_me:${as_lineno-$LINENO}: ${as_dir}${ac_aux} found" >&5 else ac_aux_dir_found=no if $ac_first_candidate; then ac_missing_aux_files="${ac_missing_aux_files} ${ac_aux}" else break fi fi fi done if test "$ac_aux_dir_found" = yes; then ac_aux_dir="$as_dir" break fi ac_first_candidate=false as_found=false done IFS=$as_save_IFS if $as_found then : else $as_nop as_fn_error $? "cannot find required auxiliary files:$ac_missing_aux_files" "$LINENO" 5 fi # These three variables are undocumented and unsupported, # and are intended to be withdrawn in a future Autoconf release. # They can cause serious problems if a builder's source tree is in a directory # whose full name contains unusual characters. if test -f "${ac_aux_dir}config.guess"; then ac_config_guess="$SHELL ${ac_aux_dir}config.guess" fi if test -f "${ac_aux_dir}config.sub"; then ac_config_sub="$SHELL ${ac_aux_dir}config.sub" fi if test -f "$ac_aux_dir/configure"; then ac_configure="$SHELL ${ac_aux_dir}configure" fi # Check that the precious variables saved in the cache have kept the same # value. ac_cache_corrupted=false for ac_var in $ac_precious_vars; do eval ac_old_set=\$ac_cv_env_${ac_var}_set eval ac_new_set=\$ac_env_${ac_var}_set eval ac_old_val=\$ac_cv_env_${ac_var}_value eval ac_new_val=\$ac_env_${ac_var}_value case $ac_old_set,$ac_new_set in set,) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 printf "%s\n" "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} ac_cache_corrupted=: ;; ,set) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 printf "%s\n" "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} ac_cache_corrupted=: ;; ,);; *) if test "x$ac_old_val" != "x$ac_new_val"; then # differences in whitespace do not lead to failure. ac_old_val_w=`echo x $ac_old_val` ac_new_val_w=`echo x $ac_new_val` if test "$ac_old_val_w" != "$ac_new_val_w"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 printf "%s\n" "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} ac_cache_corrupted=: else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 printf "%s\n" "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} eval $ac_var=\$ac_old_val fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 printf "%s\n" "$as_me: former value: \`$ac_old_val'" >&2;} { printf "%s\n" "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 printf "%s\n" "$as_me: current value: \`$ac_new_val'" >&2;} fi;; esac # Pass precious variables to config.status. if test "$ac_new_set" = set; then case $ac_new_val in *\'*) ac_arg=$ac_var=`printf "%s\n" "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; *) ac_arg=$ac_var=$ac_new_val ;; esac case " $ac_configure_args " in *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. *) as_fn_append ac_configure_args " '$ac_arg'" ;; esac fi done if $ac_cache_corrupted; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 printf "%s\n" "$as_me: error: changes in the environment can compromise the build" >&2;} as_fn_error $? "run \`${MAKE-make} distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 fi ## -------------------- ## ## Main body of script. ## ## -------------------- ## ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu # Check whether --enable-silent-rules was given. if test ${enable_silent_rules+y} then : enableval=$enable_silent_rules; fi case $enable_silent_rules in # ((( yes) AM_DEFAULT_VERBOSITY=0;; no) AM_DEFAULT_VERBOSITY=1;; *) AM_DEFAULT_VERBOSITY=0;; esac am_make=${MAKE-make} { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 printf %s "checking whether $am_make supports nested variables... " >&6; } if test ${am_cv_make_support_nested_variables+y} then : printf %s "(cached) " >&6 else $as_nop if printf "%s\n" 'TRUE=$(BAR$(V)) BAR0=false BAR1=true V=1 am__doit: @$(TRUE) .PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then am_cv_make_support_nested_variables=yes else am_cv_make_support_nested_variables=no fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5 printf "%s\n" "$am_cv_make_support_nested_variables" >&6; } if test $am_cv_make_support_nested_variables = yes; then AM_V='$(V)' AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' else AM_V=$AM_DEFAULT_VERBOSITY AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY fi AM_BACKSLASH='\' am__api_version='1.16' # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or # incompatible versions: # SysV /etc/install, /usr/sbin/install # SunOS /usr/etc/install # IRIX /sbin/install # AIX /bin/install # AmigaOS /C/install, which installs bootblocks on floppy discs # AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag # AFS /usr/afsws/bin/install, which mishandles nonexistent args # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # OS/2's system install, which has a completely different semantic # ./install, which can be erroneously created by make from ./install.sh. # Reject install programs that cannot install multiple files. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 printf %s "checking for a BSD-compatible install... " >&6; } if test -z "$INSTALL"; then if test ${ac_cv_path_install+y} then : printf %s "(cached) " >&6 else $as_nop as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac # Account for fact that we put trailing slashes in our PATH walk. case $as_dir in #(( ./ | /[cC]/* | \ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ /usr/ucb/* ) ;; *) # OSF1 and SCO ODT 3.0 have their own names for install. # Don't use installbsd from OSF since it installs stuff as root # by default. for ac_prog in ginstall scoinst install; do for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_prog$ac_exec_ext"; then if test $ac_prog = install && grep dspmsg "$as_dir$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # AIX install. It has an incompatible calling convention. : elif test $ac_prog = install && grep pwplus "$as_dir$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # program-specific install script used by HP pwplus--don't use. : else rm -rf conftest.one conftest.two conftest.dir echo one > conftest.one echo two > conftest.two mkdir conftest.dir if "$as_dir$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir/" && test -s conftest.one && test -s conftest.two && test -s conftest.dir/conftest.one && test -s conftest.dir/conftest.two then ac_cv_path_install="$as_dir$ac_prog$ac_exec_ext -c" break 3 fi fi fi done done ;; esac done IFS=$as_save_IFS rm -rf conftest.one conftest.two conftest.dir fi if test ${ac_cv_path_install+y}; then INSTALL=$ac_cv_path_install else # As a last resort, use the slow shell script. Don't cache a # value for INSTALL within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the value is a relative name. INSTALL=$ac_install_sh fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 printf "%s\n" "$INSTALL" >&6; } # Use test -z because SunOS4 sh mishandles braces in ${var-val}. # It thinks the first close brace ends the variable substitution. test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 printf %s "checking whether build environment is sane... " >&6; } # Reject unsafe characters in $srcdir or the absolute working directory # name. Accept space and tab only in the latter. am_lf=' ' case `pwd` in *[\\\"\#\$\&\'\`$am_lf]*) as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;; esac case $srcdir in *[\\\"\#\$\&\'\`$am_lf\ \ ]*) as_fn_error $? "unsafe srcdir value: '$srcdir'" "$LINENO" 5;; esac # Do 'set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( am_has_slept=no for am_try in 1 2; do echo "timestamp, slept: $am_has_slept" > conftest.file set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` if test "$*" = "X"; then # -L didn't work. set X `ls -t "$srcdir/configure" conftest.file` fi if test "$*" != "X $srcdir/configure conftest.file" \ && test "$*" != "X conftest.file $srcdir/configure"; then # If neither matched, then we have a broken ls. This can happen # if, for instance, CONFIG_SHELL is bash and it inherits a # broken ls alias from the environment. This has actually # happened. Such a system could not be considered "sane". as_fn_error $? "ls -t appears to fail. Make sure there is not a broken alias in your environment" "$LINENO" 5 fi if test "$2" = conftest.file || test $am_try -eq 2; then break fi # Just in case. sleep 1 am_has_slept=yes done test "$2" = conftest.file ) then # Ok. : else as_fn_error $? "newly created file is older than distributed files! Check your system clock" "$LINENO" 5 fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } # If we didn't sleep, we still need to ensure time stamps of config.status and # generated files are strictly newer. am_sleep_pid= if grep 'slept: no' conftest.file >/dev/null 2>&1; then ( sleep 1 ) & am_sleep_pid=$! fi rm -f conftest.file test "$program_prefix" != NONE && program_transform_name="s&^&$program_prefix&;$program_transform_name" # Use a double $ so make ignores it. test "$program_suffix" != NONE && program_transform_name="s&\$&$program_suffix&;$program_transform_name" # Double any \ or $. # By default was `s,x,x', remove it if useless. ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' program_transform_name=`printf "%s\n" "$program_transform_name" | sed "$ac_script"` # Expand $ac_aux_dir to an absolute path. am_aux_dir=`cd "$ac_aux_dir" && pwd` if test x"${MISSING+set}" != xset; then MISSING="\${SHELL} '$am_aux_dir/missing'" fi # Use eval to expand $SHELL if eval "$MISSING --is-lightweight"; then am_missing_run="$MISSING " else am_missing_run= { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: 'missing' script is too old or missing" >&5 printf "%s\n" "$as_me: WARNING: 'missing' script is too old or missing" >&2;} fi if test x"${install_sh+set}" != xset; then case $am_aux_dir in *\ * | *\ *) install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; *) install_sh="\${SHELL} $am_aux_dir/install-sh" esac fi # Installed binaries are usually stripped using 'strip' when the user # run "make install-strip". However 'strip' might not be the right # tool to use in cross-compilation environments, therefore Automake # will honor the 'STRIP' environment variable to overrule this program. if test "$cross_compiling" != no; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. set dummy ${ac_tool_prefix}strip; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_STRIP+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$STRIP"; then ac_cv_prog_STRIP="$STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_STRIP="${ac_tool_prefix}strip" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi STRIP=$ac_cv_prog_STRIP if test -n "$STRIP"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 printf "%s\n" "$STRIP" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_prog_STRIP"; then ac_ct_STRIP=$STRIP # Extract the first word of "strip", so it can be a program name with args. set dummy strip; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_STRIP+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_STRIP"; then ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_STRIP="strip" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP if test -n "$ac_ct_STRIP"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 printf "%s\n" "$ac_ct_STRIP" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_STRIP" = x; then STRIP=":" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac STRIP=$ac_ct_STRIP fi else STRIP="$ac_cv_prog_STRIP" fi fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for a race-free mkdir -p" >&5 printf %s "checking for a race-free mkdir -p... " >&6; } if test -z "$MKDIR_P"; then if test ${ac_cv_path_mkdir+y} then : printf %s "(cached) " >&6 else $as_nop as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_prog in mkdir gmkdir; do for ac_exec_ext in '' $ac_executable_extensions; do as_fn_executable_p "$as_dir$ac_prog$ac_exec_ext" || continue case `"$as_dir$ac_prog$ac_exec_ext" --version 2>&1` in #( 'mkdir ('*'coreutils) '* | \ 'BusyBox '* | \ 'mkdir (fileutils) '4.1*) ac_cv_path_mkdir=$as_dir$ac_prog$ac_exec_ext break 3;; esac done done done IFS=$as_save_IFS fi test -d ./--version && rmdir ./--version if test ${ac_cv_path_mkdir+y}; then MKDIR_P="$ac_cv_path_mkdir -p" else # As a last resort, use the slow shell script. Don't cache a # value for MKDIR_P within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the value is a relative name. MKDIR_P="$ac_install_sh -d" fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 printf "%s\n" "$MKDIR_P" >&6; } for ac_prog in gawk mawk nawk awk do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_AWK+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$AWK"; then ac_cv_prog_AWK="$AWK" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_AWK="$ac_prog" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi AWK=$ac_cv_prog_AWK if test -n "$AWK"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 printf "%s\n" "$AWK" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi test -n "$AWK" && break done { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 printf %s "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } set x ${MAKE-make} ac_make=`printf "%s\n" "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` if eval test \${ac_cv_prog_make_${ac_make}_set+y} then : printf %s "(cached) " >&6 else $as_nop cat >conftest.make <<\_ACEOF SHELL = /bin/sh all: @echo '@@@%%%=$(MAKE)=@@@%%%' _ACEOF # GNU make sometimes prints "make[1]: Entering ...", which would confuse us. case `${MAKE-make} -f conftest.make 2>/dev/null` in *@@@%%%=?*=@@@%%%*) eval ac_cv_prog_make_${ac_make}_set=yes;; *) eval ac_cv_prog_make_${ac_make}_set=no;; esac rm -f conftest.make fi if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } SET_MAKE= else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } SET_MAKE="MAKE=${MAKE-make}" fi rm -rf .tst 2>/dev/null mkdir .tst 2>/dev/null if test -d .tst; then am__leading_dot=. else am__leading_dot=_ fi rmdir .tst 2>/dev/null if test "`cd $srcdir && pwd`" != "`pwd`"; then # Use -I$(srcdir) only when $(srcdir) != ., so that make's output # is not polluted with repeated "-I." am__isrc=' -I$(srcdir)' # test to see if srcdir already configured if test -f $srcdir/config.status; then as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5 fi fi # test whether we have cygpath if test -z "$CYGPATH_W"; then if (cygpath --version) >/dev/null 2>/dev/null; then CYGPATH_W='cygpath -w' else CYGPATH_W=echo fi fi # Define the identity of the package. PACKAGE='ppp' VERSION='2.5.0' printf "%s\n" "#define PACKAGE \"$PACKAGE\"" >>confdefs.h printf "%s\n" "#define VERSION \"$VERSION\"" >>confdefs.h # Some tools Automake needs. ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} # For better backward compatibility. To be removed once Automake 1.9.x # dies out for good. For more background, see: # # mkdir_p='$(MKDIR_P)' # We need awk for the "check" target (and possibly the TAP driver). The # system "awk" is bad on some platforms. # Always define AMTAR for backward compatibility. Yes, it's still used # in the wild :-( We should find a proper way to deprecate it ... AMTAR='$${TAR-tar}' # We'll loop over all known methods to create a tar archive until one works. _am_tools='gnutar pax cpio none' am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -' # Variables for tags utilities; see am/tags.am if test -z "$CTAGS"; then CTAGS=ctags fi if test -z "$ETAGS"; then ETAGS=etags fi if test -z "$CSCOPE"; then CSCOPE=cscope fi # POSIX will say in a future version that running "rm -f" with no argument # is OK; and we want to be able to make that assumption in our Makefile # recipes. So use an aggressive probe to check that the usage we want is # actually supported "in the wild" to an acceptable degree. # See automake bug#10828. # To make any issue more visible, cause the running configure to be aborted # by default if the 'rm' program in use doesn't match our expectations; the # user can still override this though. if rm -f && rm -fr && rm -rf; then : OK; else cat >&2 <<'END' Oops! Your 'rm' program seems unable to run without file operands specified on the command line, even when the '-f' option is present. This is contrary to the behaviour of most rm programs out there, and not conforming with the upcoming POSIX standard: Please tell bug-automake@gnu.org about your system, including the value of your $PATH and any error possibly output before this message. This can help us improve future automake versions. END if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then echo 'Configuration will proceed anyway, since you have set the' >&2 echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 echo >&2 else cat >&2 <<'END' Aborting the configuration process, to ensure you take notice of the issue. You can download and install GNU coreutils to get an 'rm' implementation that behaves properly: . If you want to complete the configuration process using your problematic 'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM to "yes", and re-run configure. END as_fn_error $? "Your 'rm' program is bad, sorry." "$LINENO" 5 fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable maintainer-specific portions of Makefiles" >&5 printf %s "checking whether to enable maintainer-specific portions of Makefiles... " >&6; } # Check whether --enable-maintainer-mode was given. if test ${enable_maintainer_mode+y} then : enableval=$enable_maintainer_mode; USE_MAINTAINER_MODE=$enableval else $as_nop USE_MAINTAINER_MODE=yes fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $USE_MAINTAINER_MODE" >&5 printf "%s\n" "$USE_MAINTAINER_MODE" >&6; } if test $USE_MAINTAINER_MODE = yes; then MAINTAINER_MODE_TRUE= MAINTAINER_MODE_FALSE='#' else MAINTAINER_MODE_TRUE='#' MAINTAINER_MODE_FALSE= fi MAINT=$MAINTAINER_MODE_TRUE ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_config_headers="$ac_config_headers pppd/config.h pppd/pppdconf.h pppd/plugins/pppoe/config.h" # Check whether --enable-static was given. if test ${enable_static+y} then : enableval=$enable_static; p=${PACKAGE-default} case $enableval in yes) enable_static=yes ;; no) enable_static=no ;; *) enable_static=no # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for pkg in $enableval; do IFS=$lt_save_ifs if test "X$pkg" = "X$p"; then enable_static=yes fi done IFS=$lt_save_ifs ;; esac else $as_nop enable_static=no fi # Checks for programs. ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. set dummy ${ac_tool_prefix}gcc; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_CC+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}gcc" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 printf "%s\n" "$CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_CC+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="gcc" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 printf "%s\n" "$ac_ct_CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi else CC="$ac_cv_prog_CC" fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. set dummy ${ac_tool_prefix}cc; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_CC+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}cc" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 printf "%s\n" "$CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_CC+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else ac_prog_rejected=no as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then if test "$as_dir$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS if test $ac_prog_rejected = yes; then # We found a bogon in the path, so make sure we never use it. set dummy $ac_cv_prog_CC shift if test $# != 0; then # We chose a different compiler from the bogus one. # However, it has the same basename, so the bogon will be chosen # first if we set CC to just the basename; use the full file name. shift ac_cv_prog_CC="$as_dir$ac_word${1+' '}$@" fi fi fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 printf "%s\n" "$CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then for ac_prog in cl.exe do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_CC+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 printf "%s\n" "$CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi test -n "$CC" && break done fi if test -z "$CC"; then ac_ct_CC=$CC for ac_prog in cl.exe do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_CC+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="$ac_prog" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 printf "%s\n" "$ac_ct_CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi test -n "$ac_ct_CC" && break done if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi fi fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}clang", so it can be a program name with args. set dummy ${ac_tool_prefix}clang; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_CC+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}clang" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 printf "%s\n" "$CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "clang", so it can be a program name with args. set dummy clang; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_CC+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="clang" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 printf "%s\n" "$ac_ct_CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi else CC="$ac_cv_prog_CC" fi fi test -z "$CC" && { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "no acceptable C compiler found in \$PATH See \`config.log' for more details" "$LINENO" 5; } # Provide some information about the compiler. printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 set X $ac_compile ac_compiler=$2 for ac_option in --version -v -V -qversion -version; do { { ac_try="$ac_compiler $ac_option >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_compiler $ac_option >&5") 2>conftest.err ac_status=$? if test -s conftest.err; then sed '10a\ ... rest of stderr output deleted ... 10q' conftest.err >conftest.er1 cat conftest.er1 >&5 fi rm -f conftest.er1 conftest.err printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" # Try to create an executable without -o first, disregard a.out. # It will help us diagnose broken compilers, and finding out an intuition # of exeext. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 printf %s "checking whether the C compiler works... " >&6; } ac_link_default=`printf "%s\n" "$ac_link" | sed 's/ -o *conftest[^ ]*//'` # The possible output files: ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" ac_rmfiles= for ac_file in $ac_files do case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; * ) ac_rmfiles="$ac_rmfiles $ac_file";; esac done rm -f $ac_rmfiles if { { ac_try="$ac_link_default" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_link_default") 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } then : # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. # So ignore a value of `no', otherwise this would lead to `EXEEXT = no' # in a Makefile. We should not override ac_cv_exeext if it was cached, # so that the user can short-circuit this test for compilers unknown to # Autoconf. for ac_file in $ac_files '' do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; [ab].out ) # We found the default executable, but exeext='' is most # certainly right. break;; *.* ) if test ${ac_cv_exeext+y} && test "$ac_cv_exeext" != no; then :; else ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` fi # We set ac_cv_exeext here because the later test for it is not # safe: cross compilers may not add the suffix if given an `-o' # argument, so we may need to know it at that point already. # Even if this section looks crufty: it has the advantage of # actually working. break;; * ) break;; esac done test "$ac_cv_exeext" = no && ac_cv_exeext= else $as_nop ac_file='' fi if test -z "$ac_file" then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } printf "%s\n" "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "C compiler cannot create executables See \`config.log' for more details" "$LINENO" 5; } else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 printf %s "checking for C compiler default output file name... " >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 printf "%s\n" "$ac_file" >&6; } ac_exeext=$ac_cv_exeext rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out ac_clean_files=$ac_clean_files_save { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 printf %s "checking for suffix of executables... " >&6; } if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } then : # If both `conftest.exe' and `conftest' are `present' (well, observable) # catch `conftest.exe'. For instance with Cygwin, `ls conftest' will # work properly (i.e., refer to `conftest.exe'), while it won't with # `rm'. for ac_file in conftest.exe conftest conftest.*; do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` break;; * ) break;; esac done else $as_nop { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of executables: cannot compile and link See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest conftest$ac_cv_exeext { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 printf "%s\n" "$ac_cv_exeext" >&6; } rm -f conftest.$ac_ext EXEEXT=$ac_cv_exeext ac_exeext=$EXEEXT cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main (void) { FILE *f = fopen ("conftest.out", "w"); return ferror (f) || fclose (f) != 0; ; return 0; } _ACEOF ac_clean_files="$ac_clean_files conftest.out" # Check that the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 printf %s "checking whether we are cross compiling... " >&6; } if test "$cross_compiling" != yes; then { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if { ac_try='./conftest$ac_cv_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then cross_compiling=no else if test "$cross_compiling" = maybe; then cross_compiling=yes else { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "cannot run C compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details" "$LINENO" 5; } fi fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 printf "%s\n" "$cross_compiling" >&6; } rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out ac_clean_files=$ac_clean_files_save { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 printf %s "checking for suffix of object files... " >&6; } if test ${ac_cv_objext+y} then : printf %s "(cached) " >&6 else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF rm -f conftest.o conftest.obj if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } then : for ac_file in conftest.o conftest.obj conftest.*; do test -f "$ac_file" || continue; case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` break;; esac done else $as_nop printf "%s\n" "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of object files: cannot compile See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest.$ac_cv_objext conftest.$ac_ext fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 printf "%s\n" "$ac_cv_objext" >&6; } OBJEXT=$ac_cv_objext ac_objext=$OBJEXT { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports GNU C" >&5 printf %s "checking whether the compiler supports GNU C... " >&6; } if test ${ac_cv_c_compiler_gnu+y} then : printf %s "(cached) " >&6 else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : ac_compiler_gnu=yes else $as_nop ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ac_cv_c_compiler_gnu=$ac_compiler_gnu fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 printf "%s\n" "$ac_cv_c_compiler_gnu" >&6; } ac_compiler_gnu=$ac_cv_c_compiler_gnu if test $ac_compiler_gnu = yes; then GCC=yes else GCC= fi ac_test_CFLAGS=${CFLAGS+y} ac_save_CFLAGS=$CFLAGS { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 printf %s "checking whether $CC accepts -g... " >&6; } if test ${ac_cv_prog_cc_g+y} then : printf %s "(cached) " >&6 else $as_nop ac_save_c_werror_flag=$ac_c_werror_flag ac_c_werror_flag=yes ac_cv_prog_cc_g=no CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : ac_cv_prog_cc_g=yes else $as_nop CFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : else $as_nop ac_c_werror_flag=$ac_save_c_werror_flag CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : ac_cv_prog_cc_g=yes fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ac_c_werror_flag=$ac_save_c_werror_flag fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 printf "%s\n" "$ac_cv_prog_cc_g" >&6; } if test $ac_test_CFLAGS; then CFLAGS=$ac_save_CFLAGS elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then CFLAGS="-g -O2" else CFLAGS="-g" fi else if test "$GCC" = yes; then CFLAGS="-O2" else CFLAGS= fi fi ac_prog_cc_stdc=no if test x$ac_prog_cc_stdc = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable C11 features" >&5 printf %s "checking for $CC option to enable C11 features... " >&6; } if test ${ac_cv_prog_cc_c11+y} then : printf %s "(cached) " >&6 else $as_nop ac_cv_prog_cc_c11=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_c_conftest_c11_program _ACEOF for ac_arg in '' -std=gnu11 do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO" then : ac_cv_prog_cc_c11=$ac_arg fi rm -f core conftest.err conftest.$ac_objext conftest.beam test "x$ac_cv_prog_cc_c11" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi if test "x$ac_cv_prog_cc_c11" = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 printf "%s\n" "unsupported" >&6; } else $as_nop if test "x$ac_cv_prog_cc_c11" = x then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 printf "%s\n" "none needed" >&6; } else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c11" >&5 printf "%s\n" "$ac_cv_prog_cc_c11" >&6; } CC="$CC $ac_cv_prog_cc_c11" fi ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c11 ac_prog_cc_stdc=c11 fi fi if test x$ac_prog_cc_stdc = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable C99 features" >&5 printf %s "checking for $CC option to enable C99 features... " >&6; } if test ${ac_cv_prog_cc_c99+y} then : printf %s "(cached) " >&6 else $as_nop ac_cv_prog_cc_c99=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_c_conftest_c99_program _ACEOF for ac_arg in '' -std=gnu99 -std=c99 -c99 -qlanglvl=extc1x -qlanglvl=extc99 -AC99 -D_STDC_C99= do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO" then : ac_cv_prog_cc_c99=$ac_arg fi rm -f core conftest.err conftest.$ac_objext conftest.beam test "x$ac_cv_prog_cc_c99" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi if test "x$ac_cv_prog_cc_c99" = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 printf "%s\n" "unsupported" >&6; } else $as_nop if test "x$ac_cv_prog_cc_c99" = x then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 printf "%s\n" "none needed" >&6; } else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c99" >&5 printf "%s\n" "$ac_cv_prog_cc_c99" >&6; } CC="$CC $ac_cv_prog_cc_c99" fi ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c99 ac_prog_cc_stdc=c99 fi fi if test x$ac_prog_cc_stdc = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable C89 features" >&5 printf %s "checking for $CC option to enable C89 features... " >&6; } if test ${ac_cv_prog_cc_c89+y} then : printf %s "(cached) " >&6 else $as_nop ac_cv_prog_cc_c89=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_c_conftest_c89_program _ACEOF for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO" then : ac_cv_prog_cc_c89=$ac_arg fi rm -f core conftest.err conftest.$ac_objext conftest.beam test "x$ac_cv_prog_cc_c89" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi if test "x$ac_cv_prog_cc_c89" = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 printf "%s\n" "unsupported" >&6; } else $as_nop if test "x$ac_cv_prog_cc_c89" = x then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 printf "%s\n" "none needed" >&6; } else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 printf "%s\n" "$ac_cv_prog_cc_c89" >&6; } CC="$CC $ac_cv_prog_cc_c89" fi ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c89 ac_prog_cc_stdc=c89 fi fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5 printf %s "checking whether $CC understands -c and -o together... " >&6; } if test ${am_cv_prog_cc_c_o+y} then : printf %s "(cached) " >&6 else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF # Make sure it works both with $CC and with simple cc. # Following AC_PROG_CC_C_O, we do the test twice because some # compilers refuse to overwrite an existing .o file with -o, # though they will create one. am_cv_prog_cc_c_o=yes for am_i in 1 2; do if { echo "$as_me:$LINENO: $CC -c conftest.$ac_ext -o conftest2.$ac_objext" >&5 ($CC -c conftest.$ac_ext -o conftest2.$ac_objext) >&5 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } \ && test -f conftest2.$ac_objext; then : OK else am_cv_prog_cc_c_o=no break fi done rm -f core conftest* unset am_i fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5 printf "%s\n" "$am_cv_prog_cc_c_o" >&6; } if test "$am_cv_prog_cc_c_o" != yes; then # Losing compiler, so override with the script. # FIXME: It is wrong to rewrite CC. # But if we don't then we get into trouble of one sort or another. # A longer-term fix would be to have automake use am__CC in this case, # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" CC="$am_aux_dir/compile $CC" fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu DEPDIR="${am__leading_dot}deps" ac_config_commands="$ac_config_commands depfiles" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} supports the include directive" >&5 printf %s "checking whether ${MAKE-make} supports the include directive... " >&6; } cat > confinc.mk << 'END' am__doit: @echo this is the am__doit target >confinc.out .PHONY: am__doit END am__include="#" am__quote= # BSD make does it like this. echo '.include "confinc.mk" # ignored' > confmf.BSD # Other make implementations (GNU, Solaris 10, AIX) do it like this. echo 'include confinc.mk # ignored' > confmf.GNU _am_result=no for s in GNU BSD; do { echo "$as_me:$LINENO: ${MAKE-make} -f confmf.$s && cat confinc.out" >&5 (${MAKE-make} -f confmf.$s && cat confinc.out) >&5 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } case $?:`cat confinc.out 2>/dev/null` in #( '0:this is the am__doit target') : case $s in #( BSD) : am__include='.include' am__quote='"' ;; #( *) : am__include='include' am__quote='' ;; esac ;; #( *) : ;; esac if test "$am__include" != "#"; then _am_result="yes ($s style)" break fi done rm -f confinc.* confmf.* { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: ${_am_result}" >&5 printf "%s\n" "${_am_result}" >&6; } # Check whether --enable-dependency-tracking was given. if test ${enable_dependency_tracking+y} then : enableval=$enable_dependency_tracking; fi if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' am__nodep='_no' fi if test "x$enable_dependency_tracking" != xno; then AMDEP_TRUE= AMDEP_FALSE='#' else AMDEP_TRUE='#' AMDEP_FALSE= fi depcc="$CC" am_compiler_list= { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 printf %s "checking dependency style of $depcc... " >&6; } if test ${am_cv_CC_dependencies_compiler_type+y} then : printf %s "(cached) " >&6 else $as_nop if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named 'D' -- because '-MD' means "put the output # in D". rm -rf conftest.dir mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_CC_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` fi am__universal=false case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with # Solaris 10 /bin/sh. echo '/* dummy */' > sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf # We check with '-c' and '-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle '-M -o', and we need to detect this. Also, some Intel # versions had trouble with output in subdirs. am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in gcc) # This depmode causes a compiler race in universal mode. test "$am__universal" = false || continue ;; nosideeffect) # After this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested. if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; msvc7 | msvc7msys | msvisualcpp | msvcmsys) # This compiler won't grok '-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} am__minus_obj= ;; none) break ;; esac if depmode=$depmode \ source=sub/conftest.c object=$am__obj \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_CC_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_CC_dependencies_compiler_type=none fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 printf "%s\n" "$am_cv_CC_dependencies_compiler_type" >&6; } CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type if test "x$enable_dependency_tracking" != xno \ && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then am__fastdepCC_TRUE= am__fastdepCC_FALSE='#' else am__fastdepCC_TRUE='#' am__fastdepCC_FALSE= fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5 printf %s "checking whether ln -s works... " >&6; } LN_S=$as_ln_s if test "$LN_S" = "ln -s"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5 printf "%s\n" "no, using $LN_S" >&6; } fi case `pwd` in *\ * | *\ *) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5 printf "%s\n" "$as_me: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&2;} ;; esac macro_version='2.4.7' macro_revision='2.4.7' ltmain=$ac_aux_dir/ltmain.sh # Make sure we can run config.sub. $SHELL "${ac_aux_dir}config.sub" sun4 >/dev/null 2>&1 || as_fn_error $? "cannot run $SHELL ${ac_aux_dir}config.sub" "$LINENO" 5 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 printf %s "checking build system type... " >&6; } if test ${ac_cv_build+y} then : printf %s "(cached) " >&6 else $as_nop ac_build_alias=$build_alias test "x$ac_build_alias" = x && ac_build_alias=`$SHELL "${ac_aux_dir}config.guess"` test "x$ac_build_alias" = x && as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5 ac_cv_build=`$SHELL "${ac_aux_dir}config.sub" $ac_build_alias` || as_fn_error $? "$SHELL ${ac_aux_dir}config.sub $ac_build_alias failed" "$LINENO" 5 fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 printf "%s\n" "$ac_cv_build" >&6; } case $ac_cv_build in *-*-*) ;; *) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;; esac build=$ac_cv_build ac_save_IFS=$IFS; IFS='-' set x $ac_cv_build shift build_cpu=$1 build_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: build_os=$* IFS=$ac_save_IFS case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 printf %s "checking host system type... " >&6; } if test ${ac_cv_host+y} then : printf %s "(cached) " >&6 else $as_nop if test "x$host_alias" = x; then ac_cv_host=$ac_cv_build else ac_cv_host=`$SHELL "${ac_aux_dir}config.sub" $host_alias` || as_fn_error $? "$SHELL ${ac_aux_dir}config.sub $host_alias failed" "$LINENO" 5 fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 printf "%s\n" "$ac_cv_host" >&6; } case $ac_cv_host in *-*-*) ;; *) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;; esac host=$ac_cv_host ac_save_IFS=$IFS; IFS='-' set x $ac_cv_host shift host_cpu=$1 host_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: host_os=$* IFS=$ac_save_IFS case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac # Backslashify metacharacters that are still active within # double-quoted strings. sed_quote_subst='s/\(["`$\\]\)/\\\1/g' # Same as above, but do not quote variable references. double_quote_subst='s/\(["`\\]\)/\\\1/g' # Sed substitution to delay expansion of an escaped shell variable in a # double_quote_subst'ed string. delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' # Sed substitution to delay expansion of an escaped single quote. delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' # Sed substitution to avoid accidental globbing in evaled expressions no_glob_subst='s/\*/\\\*/g' ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to print strings" >&5 printf %s "checking how to print strings... " >&6; } # Test print first, because it will be a builtin if present. if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then ECHO='print -r --' elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then ECHO='printf %s\n' else # Use this function as a fallback that always works. func_fallback_echo () { eval 'cat <<_LTECHO_EOF $1 _LTECHO_EOF' } ECHO='func_fallback_echo' fi # func_echo_all arg... # Invoke $ECHO with all args, space-separated. func_echo_all () { $ECHO "" } case $ECHO in printf*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: printf" >&5 printf "%s\n" "printf" >&6; } ;; print*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: print -r" >&5 printf "%s\n" "print -r" >&6; } ;; *) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: cat" >&5 printf "%s\n" "cat" >&6; } ;; esac { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5 printf %s "checking for a sed that does not truncate output... " >&6; } if test ${ac_cv_path_SED+y} then : printf %s "(cached) " >&6 else $as_nop ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ for ac_i in 1 2 3 4 5 6 7; do ac_script="$ac_script$as_nl$ac_script" done echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed { ac_script=; unset ac_script;} if test -z "$SED"; then ac_path_SED_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_prog in sed gsed do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_SED="$as_dir$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_SED" || continue # Check for GNU ac_path_SED and select it if it is found. # Check for GNU $ac_path_SED case `"$ac_path_SED" --version 2>&1` in *GNU*) ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;; *) ac_count=0 printf %s 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" printf "%s\n" '' >> "conftest.nl" "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_SED_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_SED="$ac_path_SED" ac_path_SED_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_SED_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_SED"; then as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5 fi else ac_cv_path_SED=$SED fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5 printf "%s\n" "$ac_cv_path_SED" >&6; } SED="$ac_cv_path_SED" rm -f conftest.sed test -z "$SED" && SED=sed Xsed="$SED -e 1s/^X//" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 printf %s "checking for grep that handles long lines and -e... " >&6; } if test ${ac_cv_path_GREP+y} then : printf %s "(cached) " >&6 else $as_nop if test -z "$GREP"; then ac_path_GREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_prog in grep ggrep do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_GREP="$as_dir$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_GREP" || continue # Check for GNU ac_path_GREP and select it if it is found. # Check for GNU $ac_path_GREP case `"$ac_path_GREP" --version 2>&1` in *GNU*) ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; *) ac_count=0 printf %s 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" printf "%s\n" 'GREP' >> "conftest.nl" "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_GREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_GREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_GREP"; then as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_GREP=$GREP fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 printf "%s\n" "$ac_cv_path_GREP" >&6; } GREP="$ac_cv_path_GREP" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 printf %s "checking for egrep... " >&6; } if test ${ac_cv_path_EGREP+y} then : printf %s "(cached) " >&6 else $as_nop if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 then ac_cv_path_EGREP="$GREP -E" else if test -z "$EGREP"; then ac_path_EGREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_prog in egrep do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_EGREP="$as_dir$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_EGREP" || continue # Check for GNU ac_path_EGREP and select it if it is found. # Check for GNU $ac_path_EGREP case `"$ac_path_EGREP" --version 2>&1` in *GNU*) ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; *) ac_count=0 printf %s 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" printf "%s\n" 'EGREP' >> "conftest.nl" "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_EGREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_EGREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_EGREP"; then as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_EGREP=$EGREP fi fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 printf "%s\n" "$ac_cv_path_EGREP" >&6; } EGREP="$ac_cv_path_EGREP" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5 printf %s "checking for fgrep... " >&6; } if test ${ac_cv_path_FGREP+y} then : printf %s "(cached) " >&6 else $as_nop if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1 then ac_cv_path_FGREP="$GREP -F" else if test -z "$FGREP"; then ac_path_FGREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_prog in fgrep do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_FGREP="$as_dir$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_FGREP" || continue # Check for GNU ac_path_FGREP and select it if it is found. # Check for GNU $ac_path_FGREP case `"$ac_path_FGREP" --version 2>&1` in *GNU*) ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_found=:;; *) ac_count=0 printf %s 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" printf "%s\n" 'FGREP' >> "conftest.nl" "$ac_path_FGREP" FGREP < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_FGREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_FGREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_FGREP"; then as_fn_error $? "no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_FGREP=$FGREP fi fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_FGREP" >&5 printf "%s\n" "$ac_cv_path_FGREP" >&6; } FGREP="$ac_cv_path_FGREP" test -z "$GREP" && GREP=grep # Check whether --with-gnu-ld was given. if test ${with_gnu_ld+y} then : withval=$with_gnu_ld; test no = "$withval" || with_gnu_ld=yes else $as_nop with_gnu_ld=no fi ac_prog=ld if test yes = "$GCC"; then # Check if gcc -print-prog-name=ld gives a path. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 printf %s "checking for ld used by $CC... " >&6; } case $host in *-*-mingw*) # gcc leaves a trailing carriage return, which upsets mingw ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; *) ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; esac case $ac_prog in # Accept absolute paths. [\\/]* | ?:[\\/]*) re_direlt='/[^/][^/]*/\.\./' # Canonicalize the pathname of ld ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` done test -z "$LD" && LD=$ac_prog ;; "") # If it fails, then pretend we aren't using GCC. ac_prog=ld ;; *) # If it is relative, then search for the first ld in PATH. with_gnu_ld=unknown ;; esac elif test yes = "$with_gnu_ld"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 printf %s "checking for GNU ld... " >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 printf %s "checking for non-GNU ld... " >&6; } fi if test ${lt_cv_path_LD+y} then : printf %s "(cached) " >&6 else $as_nop if test -z "$LD"; then lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR for ac_dir in $PATH; do IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then lt_cv_path_LD=$ac_dir/$ac_prog # Check to see if the program is GNU ld. I'd rather use --version, # but apparently some variants of GNU ld only accept -v. # Break only if it was the GNU/non-GNU ld that we prefer. case `"$lt_cv_path_LD" -v 2>&1 &5 printf "%s\n" "$LD" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 printf %s "checking if the linker ($LD) is GNU ld... " >&6; } if test ${lt_cv_prog_gnu_ld+y} then : printf %s "(cached) " >&6 else $as_nop # I'd rather use --version here, but apparently some GNU lds only accept -v. case `$LD -v 2>&1 &5 printf "%s\n" "$lt_cv_prog_gnu_ld" >&6; } with_gnu_ld=$lt_cv_prog_gnu_ld { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for BSD- or MS-compatible name lister (nm)" >&5 printf %s "checking for BSD- or MS-compatible name lister (nm)... " >&6; } if test ${lt_cv_path_NM+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$NM"; then # Let the user override the test. lt_cv_path_NM=$NM else lt_nm_to_check=${ac_tool_prefix}nm if test -n "$ac_tool_prefix" && test "$build" = "$host"; then lt_nm_to_check="$lt_nm_to_check nm" fi for lt_tmp_nm in $lt_nm_to_check; do lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. tmp_nm=$ac_dir/$lt_tmp_nm if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext"; then # Check to see if the nm accepts a BSD-compat flag. # Adding the 'sed 1q' prevents false positives on HP-UX, which says: # nm: unknown option "B" ignored # Tru64's nm complains that /dev/null is an invalid object file # MSYS converts /dev/null to NUL, MinGW nm treats NUL as empty case $build_os in mingw*) lt_bad_file=conftest.nm/nofile ;; *) lt_bad_file=/dev/null ;; esac case `"$tmp_nm" -B $lt_bad_file 2>&1 | $SED '1q'` in *$lt_bad_file* | *'Invalid file or object type'*) lt_cv_path_NM="$tmp_nm -B" break 2 ;; *) case `"$tmp_nm" -p /dev/null 2>&1 | $SED '1q'` in */dev/null*) lt_cv_path_NM="$tmp_nm -p" break 2 ;; *) lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but continue # so that we can try to find one that supports BSD flags ;; esac ;; esac fi done IFS=$lt_save_ifs done : ${lt_cv_path_NM=no} fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_NM" >&5 printf "%s\n" "$lt_cv_path_NM" >&6; } if test no != "$lt_cv_path_NM"; then NM=$lt_cv_path_NM else # Didn't find any BSD compatible name lister, look for dumpbin. if test -n "$DUMPBIN"; then : # Let the user override the test. else if test -n "$ac_tool_prefix"; then for ac_prog in dumpbin "link -dump" do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_DUMPBIN+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$DUMPBIN"; then ac_cv_prog_DUMPBIN="$DUMPBIN" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_DUMPBIN="$ac_tool_prefix$ac_prog" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi DUMPBIN=$ac_cv_prog_DUMPBIN if test -n "$DUMPBIN"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $DUMPBIN" >&5 printf "%s\n" "$DUMPBIN" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi test -n "$DUMPBIN" && break done fi if test -z "$DUMPBIN"; then ac_ct_DUMPBIN=$DUMPBIN for ac_prog in dumpbin "link -dump" do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_DUMPBIN+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_DUMPBIN"; then ac_cv_prog_ac_ct_DUMPBIN="$ac_ct_DUMPBIN" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_DUMPBIN="$ac_prog" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_DUMPBIN=$ac_cv_prog_ac_ct_DUMPBIN if test -n "$ac_ct_DUMPBIN"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DUMPBIN" >&5 printf "%s\n" "$ac_ct_DUMPBIN" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi test -n "$ac_ct_DUMPBIN" && break done if test "x$ac_ct_DUMPBIN" = x; then DUMPBIN=":" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac DUMPBIN=$ac_ct_DUMPBIN fi fi case `$DUMPBIN -symbols -headers /dev/null 2>&1 | $SED '1q'` in *COFF*) DUMPBIN="$DUMPBIN -symbols -headers" ;; *) DUMPBIN=: ;; esac fi if test : != "$DUMPBIN"; then NM=$DUMPBIN fi fi test -z "$NM" && NM=nm { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking the name lister ($NM) interface" >&5 printf %s "checking the name lister ($NM) interface... " >&6; } if test ${lt_cv_nm_interface+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_nm_interface="BSD nm" echo "int some_variable = 0;" > conftest.$ac_ext (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&5) (eval "$ac_compile" 2>conftest.err) cat conftest.err >&5 (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&5) (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) cat conftest.err >&5 (eval echo "\"\$as_me:$LINENO: output\"" >&5) cat conftest.out >&5 if $GREP 'External.*some_variable' conftest.out > /dev/null; then lt_cv_nm_interface="MS dumpbin" fi rm -f conftest* fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_nm_interface" >&5 printf "%s\n" "$lt_cv_nm_interface" >&6; } # find the maximum length of command line arguments { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking the maximum length of command line arguments" >&5 printf %s "checking the maximum length of command line arguments... " >&6; } if test ${lt_cv_sys_max_cmd_len+y} then : printf %s "(cached) " >&6 else $as_nop i=0 teststring=ABCD case $build_os in msdosdjgpp*) # On DJGPP, this test can blow up pretty badly due to problems in libc # (any single argument exceeding 2000 bytes causes a buffer overrun # during glob expansion). Even if it were fixed, the result of this # check would be larger than it should be. lt_cv_sys_max_cmd_len=12288; # 12K is about right ;; gnu*) # Under GNU Hurd, this test is not required because there is # no limit to the length of command line arguments. # Libtool will interpret -1 as no limit whatsoever lt_cv_sys_max_cmd_len=-1; ;; cygwin* | mingw* | cegcc*) # On Win9x/ME, this test blows up -- it succeeds, but takes # about 5 minutes as the teststring grows exponentially. # Worse, since 9x/ME are not pre-emptively multitasking, # you end up with a "frozen" computer, even though with patience # the test eventually succeeds (with a max line length of 256k). # Instead, let's just punt: use the minimum linelength reported by # all of the supported platforms: 8192 (on NT/2K/XP). lt_cv_sys_max_cmd_len=8192; ;; mint*) # On MiNT this can take a long time and run out of memory. lt_cv_sys_max_cmd_len=8192; ;; amigaos*) # On AmigaOS with pdksh, this test takes hours, literally. # So we just punt and use a minimum line length of 8192. lt_cv_sys_max_cmd_len=8192; ;; bitrig* | darwin* | dragonfly* | freebsd* | midnightbsd* | netbsd* | openbsd*) # This has been around since 386BSD, at least. Likely further. if test -x /sbin/sysctl; then lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` elif test -x /usr/sbin/sysctl; then lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` else lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs fi # And add a safety zone lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` ;; interix*) # We know the value 262144 and hardcode it with a safety zone (like BSD) lt_cv_sys_max_cmd_len=196608 ;; os2*) # The test takes a long time on OS/2. lt_cv_sys_max_cmd_len=8192 ;; osf*) # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not # nice to cause kernel panics so lets avoid the loop below. # First set a reasonable default. lt_cv_sys_max_cmd_len=16384 # if test -x /sbin/sysconfig; then case `/sbin/sysconfig -q proc exec_disable_arg_limit` in *1*) lt_cv_sys_max_cmd_len=-1 ;; esac fi ;; sco3.2v5*) lt_cv_sys_max_cmd_len=102400 ;; sysv5* | sco5v6* | sysv4.2uw2*) kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` if test -n "$kargmax"; then lt_cv_sys_max_cmd_len=`echo $kargmax | $SED 's/.*[ ]//'` else lt_cv_sys_max_cmd_len=32768 fi ;; *) lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` if test -n "$lt_cv_sys_max_cmd_len" && \ test undefined != "$lt_cv_sys_max_cmd_len"; then lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` else # Make teststring a little bigger before we do anything with it. # a 1K string should be a reasonable start. for i in 1 2 3 4 5 6 7 8; do teststring=$teststring$teststring done SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} # If test is not a shell built-in, we'll probably end up computing a # maximum length that is only half of the actual maximum length, but # we can't tell. while { test X`env echo "$teststring$teststring" 2>/dev/null` \ = "X$teststring$teststring"; } >/dev/null 2>&1 && test 17 != "$i" # 1/2 MB should be enough do i=`expr $i + 1` teststring=$teststring$teststring done # Only check the string length outside the loop. lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` teststring= # Add a significant safety factor because C++ compilers can tack on # massive amounts of additional arguments before passing them to the # linker. It appears as though 1/2 is a usable value. lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` fi ;; esac fi if test -n "$lt_cv_sys_max_cmd_len"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sys_max_cmd_len" >&5 printf "%s\n" "$lt_cv_sys_max_cmd_len" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none" >&5 printf "%s\n" "none" >&6; } fi max_cmd_len=$lt_cv_sys_max_cmd_len : ${CP="cp -f"} : ${MV="mv -f"} : ${RM="rm -f"} if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then lt_unset=unset else lt_unset=false fi # test EBCDIC or ASCII case `echo X|tr X '\101'` in A) # ASCII based system # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr lt_SP2NL='tr \040 \012' lt_NL2SP='tr \015\012 \040\040' ;; *) # EBCDIC based system lt_SP2NL='tr \100 \n' lt_NL2SP='tr \r\n \100\100' ;; esac { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to $host format" >&5 printf %s "checking how to convert $build file names to $host format... " >&6; } if test ${lt_cv_to_host_file_cmd+y} then : printf %s "(cached) " >&6 else $as_nop case $host in *-*-mingw* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 ;; *-*-cygwin* ) lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32 ;; * ) # otherwise, assume *nix lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32 ;; esac ;; *-*-cygwin* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin ;; *-*-cygwin* ) lt_cv_to_host_file_cmd=func_convert_file_noop ;; * ) # otherwise, assume *nix lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin ;; esac ;; * ) # unhandled hosts (and "normal" native builds) lt_cv_to_host_file_cmd=func_convert_file_noop ;; esac fi to_host_file_cmd=$lt_cv_to_host_file_cmd { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_host_file_cmd" >&5 printf "%s\n" "$lt_cv_to_host_file_cmd" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to toolchain format" >&5 printf %s "checking how to convert $build file names to toolchain format... " >&6; } if test ${lt_cv_to_tool_file_cmd+y} then : printf %s "(cached) " >&6 else $as_nop #assume ordinary cross tools, or native build. lt_cv_to_tool_file_cmd=func_convert_file_noop case $host in *-*-mingw* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 ;; esac ;; esac fi to_tool_file_cmd=$lt_cv_to_tool_file_cmd { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_tool_file_cmd" >&5 printf "%s\n" "$lt_cv_to_tool_file_cmd" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $LD option to reload object files" >&5 printf %s "checking for $LD option to reload object files... " >&6; } if test ${lt_cv_ld_reload_flag+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_ld_reload_flag='-r' fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_reload_flag" >&5 printf "%s\n" "$lt_cv_ld_reload_flag" >&6; } reload_flag=$lt_cv_ld_reload_flag case $reload_flag in "" | " "*) ;; *) reload_flag=" $reload_flag" ;; esac reload_cmds='$LD$reload_flag -o $output$reload_objs' case $host_os in cygwin* | mingw* | pw32* | cegcc*) if test yes != "$GCC"; then reload_cmds=false fi ;; darwin*) if test yes = "$GCC"; then reload_cmds='$LTCC $LTCFLAGS -nostdlib $wl-r -o $output$reload_objs' else reload_cmds='$LD$reload_flag -o $output$reload_objs' fi ;; esac if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}file", so it can be a program name with args. set dummy ${ac_tool_prefix}file; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_FILECMD+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$FILECMD"; then ac_cv_prog_FILECMD="$FILECMD" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_FILECMD="${ac_tool_prefix}file" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi FILECMD=$ac_cv_prog_FILECMD if test -n "$FILECMD"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $FILECMD" >&5 printf "%s\n" "$FILECMD" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_prog_FILECMD"; then ac_ct_FILECMD=$FILECMD # Extract the first word of "file", so it can be a program name with args. set dummy file; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_FILECMD+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_FILECMD"; then ac_cv_prog_ac_ct_FILECMD="$ac_ct_FILECMD" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_FILECMD="file" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_FILECMD=$ac_cv_prog_ac_ct_FILECMD if test -n "$ac_ct_FILECMD"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_FILECMD" >&5 printf "%s\n" "$ac_ct_FILECMD" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_FILECMD" = x; then FILECMD=":" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac FILECMD=$ac_ct_FILECMD fi else FILECMD="$ac_cv_prog_FILECMD" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args. set dummy ${ac_tool_prefix}objdump; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_OBJDUMP+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$OBJDUMP"; then ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi OBJDUMP=$ac_cv_prog_OBJDUMP if test -n "$OBJDUMP"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5 printf "%s\n" "$OBJDUMP" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_prog_OBJDUMP"; then ac_ct_OBJDUMP=$OBJDUMP # Extract the first word of "objdump", so it can be a program name with args. set dummy objdump; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_OBJDUMP+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_OBJDUMP"; then ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_OBJDUMP="objdump" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP if test -n "$ac_ct_OBJDUMP"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5 printf "%s\n" "$ac_ct_OBJDUMP" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_OBJDUMP" = x; then OBJDUMP="false" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac OBJDUMP=$ac_ct_OBJDUMP fi else OBJDUMP="$ac_cv_prog_OBJDUMP" fi test -z "$OBJDUMP" && OBJDUMP=objdump { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to recognize dependent libraries" >&5 printf %s "checking how to recognize dependent libraries... " >&6; } if test ${lt_cv_deplibs_check_method+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_file_magic_cmd='$MAGIC_CMD' lt_cv_file_magic_test_file= lt_cv_deplibs_check_method='unknown' # Need to set the preceding variable on all platforms that support # interlibrary dependencies. # 'none' -- dependencies not supported. # 'unknown' -- same as none, but documents that we really don't know. # 'pass_all' -- all dependencies passed with no checks. # 'test_compile' -- check by making test program. # 'file_magic [[regex]]' -- check by looking for files in library path # that responds to the $file_magic_cmd with a given extended regex. # If you have 'file' or equivalent on your system and you're not sure # whether 'pass_all' will *always* work, you probably want this one. case $host_os in aix[4-9]*) lt_cv_deplibs_check_method=pass_all ;; beos*) lt_cv_deplibs_check_method=pass_all ;; bsdi[45]*) lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)' lt_cv_file_magic_cmd='$FILECMD -L' lt_cv_file_magic_test_file=/shlib/libc.so ;; cygwin*) # func_win32_libid is a shell function defined in ltmain.sh lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' lt_cv_file_magic_cmd='func_win32_libid' ;; mingw* | pw32*) # Base MSYS/MinGW do not provide the 'file' command needed by # func_win32_libid shell function, so use a weaker test based on 'objdump', # unless we find 'file', for example because we are cross-compiling. if ( file / ) >/dev/null 2>&1; then lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' lt_cv_file_magic_cmd='func_win32_libid' else # Keep this pattern in sync with the one in func_win32_libid. lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' lt_cv_file_magic_cmd='$OBJDUMP -f' fi ;; cegcc*) # use the weaker test based on 'objdump'. See mingw*. lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' lt_cv_file_magic_cmd='$OBJDUMP -f' ;; darwin* | rhapsody*) lt_cv_deplibs_check_method=pass_all ;; freebsd* | dragonfly* | midnightbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then case $host_cpu in i*86 ) # Not sure whether the presence of OpenBSD here was a mistake. # Let's accept both of them until this is cleared up. lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library' lt_cv_file_magic_cmd=$FILECMD lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` ;; esac else lt_cv_deplibs_check_method=pass_all fi ;; haiku*) lt_cv_deplibs_check_method=pass_all ;; hpux10.20* | hpux11*) lt_cv_file_magic_cmd=$FILECMD case $host_cpu in ia64*) lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64' lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so ;; hppa*64*) lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]' lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl ;; *) lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9]\.[0-9]) shared library' lt_cv_file_magic_test_file=/usr/lib/libc.sl ;; esac ;; interix[3-9]*) # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|\.a)$' ;; irix5* | irix6* | nonstopux*) case $LD in *-32|*"-32 ") libmagic=32-bit;; *-n32|*"-n32 ") libmagic=N32;; *-64|*"-64 ") libmagic=64-bit;; *) libmagic=never-match;; esac lt_cv_deplibs_check_method=pass_all ;; # This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) lt_cv_deplibs_check_method=pass_all ;; netbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|_pic\.a)$' fi ;; newos6*) lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)' lt_cv_file_magic_cmd=$FILECMD lt_cv_file_magic_test_file=/usr/lib/libnls.so ;; *nto* | *qnx*) lt_cv_deplibs_check_method=pass_all ;; openbsd* | bitrig*) if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' fi ;; osf3* | osf4* | osf5*) lt_cv_deplibs_check_method=pass_all ;; rdos*) lt_cv_deplibs_check_method=pass_all ;; solaris*) lt_cv_deplibs_check_method=pass_all ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) lt_cv_deplibs_check_method=pass_all ;; sysv4 | sysv4.3*) case $host_vendor in motorola) lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]' lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` ;; ncr) lt_cv_deplibs_check_method=pass_all ;; sequent) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )' ;; sni) lt_cv_file_magic_cmd='/bin/file' 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 ;; pc) lt_cv_deplibs_check_method=pass_all ;; esac ;; tpf*) lt_cv_deplibs_check_method=pass_all ;; os2*) lt_cv_deplibs_check_method=pass_all ;; esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_deplibs_check_method" >&5 printf "%s\n" "$lt_cv_deplibs_check_method" >&6; } file_magic_glob= want_nocaseglob=no if test "$build" = "$host"; then case $host_os in mingw* | pw32*) if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then want_nocaseglob=yes else file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[\1]\/[\1]\/g;/g"` fi ;; esac fi file_magic_cmd=$lt_cv_file_magic_cmd deplibs_check_method=$lt_cv_deplibs_check_method test -z "$deplibs_check_method" && deplibs_check_method=unknown if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args. set dummy ${ac_tool_prefix}dlltool; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_DLLTOOL+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$DLLTOOL"; then ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi DLLTOOL=$ac_cv_prog_DLLTOOL if test -n "$DLLTOOL"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5 printf "%s\n" "$DLLTOOL" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_prog_DLLTOOL"; then ac_ct_DLLTOOL=$DLLTOOL # Extract the first word of "dlltool", so it can be a program name with args. set dummy dlltool; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_DLLTOOL+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_DLLTOOL"; then ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_DLLTOOL="dlltool" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL if test -n "$ac_ct_DLLTOOL"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5 printf "%s\n" "$ac_ct_DLLTOOL" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_DLLTOOL" = x; then DLLTOOL="false" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac DLLTOOL=$ac_ct_DLLTOOL fi else DLLTOOL="$ac_cv_prog_DLLTOOL" fi test -z "$DLLTOOL" && DLLTOOL=dlltool { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to associate runtime and link libraries" >&5 printf %s "checking how to associate runtime and link libraries... " >&6; } if test ${lt_cv_sharedlib_from_linklib_cmd+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_sharedlib_from_linklib_cmd='unknown' case $host_os in cygwin* | mingw* | pw32* | cegcc*) # two different shell functions defined in ltmain.sh; # decide which one to use based on capabilities of $DLLTOOL case `$DLLTOOL --help 2>&1` in *--identify-strict*) lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib ;; *) lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback ;; esac ;; *) # fallback: assume linklib IS sharedlib lt_cv_sharedlib_from_linklib_cmd=$ECHO ;; esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sharedlib_from_linklib_cmd" >&5 printf "%s\n" "$lt_cv_sharedlib_from_linklib_cmd" >&6; } sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO if test -n "$ac_tool_prefix"; then for ac_prog in ar do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_AR+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$AR"; then ac_cv_prog_AR="$AR" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_AR="$ac_tool_prefix$ac_prog" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi AR=$ac_cv_prog_AR if test -n "$AR"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 printf "%s\n" "$AR" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi test -n "$AR" && break done fi if test -z "$AR"; then ac_ct_AR=$AR for ac_prog in ar do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_AR+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_AR"; then ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_AR="$ac_prog" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_AR=$ac_cv_prog_ac_ct_AR if test -n "$ac_ct_AR"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5 printf "%s\n" "$ac_ct_AR" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi test -n "$ac_ct_AR" && break done if test "x$ac_ct_AR" = x; then AR="false" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac AR=$ac_ct_AR fi fi : ${AR=ar} # Use ARFLAGS variable as AR's operation code to sync the variable naming with # Automake. If both AR_FLAGS and ARFLAGS are specified, AR_FLAGS should have # higher priority because thats what people were doing historically (setting # ARFLAGS for automake and AR_FLAGS for libtool). FIXME: Make the AR_FLAGS # variable obsoleted/removed. test ${AR_FLAGS+y} || AR_FLAGS=${ARFLAGS-cr} lt_ar_flags=$AR_FLAGS # Make AR_FLAGS overridable by 'make ARFLAGS='. Don't try to run-time override # by AR_FLAGS because that was never working and AR_FLAGS is about to die. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for archiver @FILE support" >&5 printf %s "checking for archiver @FILE support... " >&6; } if test ${lt_cv_ar_at_file+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_ar_at_file=no cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : echo conftest.$ac_objext > conftest.lst lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&5' { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 (eval $lt_ar_try) 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if test 0 -eq "$ac_status"; then # Ensure the archiver fails upon bogus file names. rm -f conftest.$ac_objext libconftest.a { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 (eval $lt_ar_try) 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if test 0 -ne "$ac_status"; then lt_cv_ar_at_file=@ fi fi rm -f conftest.* libconftest.a fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ar_at_file" >&5 printf "%s\n" "$lt_cv_ar_at_file" >&6; } if test no = "$lt_cv_ar_at_file"; then archiver_list_spec= else archiver_list_spec=$lt_cv_ar_at_file fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. set dummy ${ac_tool_prefix}strip; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_STRIP+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$STRIP"; then ac_cv_prog_STRIP="$STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_STRIP="${ac_tool_prefix}strip" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi STRIP=$ac_cv_prog_STRIP if test -n "$STRIP"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 printf "%s\n" "$STRIP" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_prog_STRIP"; then ac_ct_STRIP=$STRIP # Extract the first word of "strip", so it can be a program name with args. set dummy strip; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_STRIP+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_STRIP"; then ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_STRIP="strip" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP if test -n "$ac_ct_STRIP"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 printf "%s\n" "$ac_ct_STRIP" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_STRIP" = x; then STRIP=":" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac STRIP=$ac_ct_STRIP fi else STRIP="$ac_cv_prog_STRIP" fi test -z "$STRIP" && STRIP=: if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. set dummy ${ac_tool_prefix}ranlib; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_RANLIB+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$RANLIB"; then ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi RANLIB=$ac_cv_prog_RANLIB if test -n "$RANLIB"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 printf "%s\n" "$RANLIB" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_prog_RANLIB"; then ac_ct_RANLIB=$RANLIB # Extract the first word of "ranlib", so it can be a program name with args. set dummy ranlib; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_RANLIB+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_RANLIB"; then ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_RANLIB="ranlib" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB if test -n "$ac_ct_RANLIB"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 printf "%s\n" "$ac_ct_RANLIB" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_RANLIB" = x; then RANLIB=":" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac RANLIB=$ac_ct_RANLIB fi else RANLIB="$ac_cv_prog_RANLIB" fi test -z "$RANLIB" && RANLIB=: # Determine commands to create old-style static archives. old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' old_postinstall_cmds='chmod 644 $oldlib' old_postuninstall_cmds= if test -n "$RANLIB"; then case $host_os in bitrig* | openbsd*) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib" ;; *) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" ;; esac old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib" fi case $host_os in darwin*) lock_old_archive_extraction=yes ;; *) lock_old_archive_extraction=no ;; esac # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} # If no C compiler flags were specified, use CFLAGS. LTCFLAGS=${LTCFLAGS-"$CFLAGS"} # Allow CC to be a program name with arguments. compiler=$CC # Check for command to grab the raw symbol name followed by C symbol from nm. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking command to parse $NM output from $compiler object" >&5 printf %s "checking command to parse $NM output from $compiler object... " >&6; } if test ${lt_cv_sys_global_symbol_pipe+y} then : printf %s "(cached) " >&6 else $as_nop # These are sane defaults that work on at least a few old systems. # [They come from Ultrix. What could be older than Ultrix?!! ;)] # Character class describing NM global symbol codes. symcode='[BCDEGRST]' # Regexp to match symbols that can be accessed directly from C. sympat='\([_A-Za-z][_A-Za-z0-9]*\)' # Define system-specific variables. case $host_os in aix*) symcode='[BCDT]' ;; cygwin* | mingw* | pw32* | cegcc*) symcode='[ABCDGISTW]' ;; hpux*) if test ia64 = "$host_cpu"; then symcode='[ABCDEGRST]' fi ;; irix* | nonstopux*) symcode='[BCDEGRST]' ;; osf*) symcode='[BCDEGQRST]' ;; solaris*) symcode='[BDRT]' ;; sco3.2v5*) symcode='[DT]' ;; sysv4.2uw2*) symcode='[DT]' ;; sysv5* | sco5v6* | unixware* | OpenUNIX*) symcode='[ABDT]' ;; sysv4) symcode='[DFNSTU]' ;; esac # If we're using GNU nm, then use its standard symbol codes. case `$NM -V 2>&1` in *GNU* | *'with BFD'*) symcode='[ABCDGIRSTW]' ;; esac if test "$lt_cv_nm_interface" = "MS dumpbin"; then # Gets list of data symbols to import. lt_cv_sys_global_symbol_to_import="$SED -n -e 's/^I .* \(.*\)$/\1/p'" # Adjust the below global symbol transforms to fixup imported variables. lt_cdecl_hook=" -e 's/^I .* \(.*\)$/extern __declspec(dllimport) char \1;/p'" lt_c_name_hook=" -e 's/^I .* \(.*\)$/ {\"\1\", (void *) 0},/p'" lt_c_name_lib_hook="\ -e 's/^I .* \(lib.*\)$/ {\"\1\", (void *) 0},/p'\ -e 's/^I .* \(.*\)$/ {\"lib\1\", (void *) 0},/p'" else # Disable hooks by default. lt_cv_sys_global_symbol_to_import= lt_cdecl_hook= lt_c_name_hook= lt_c_name_lib_hook= fi # Transform an extracted symbol line into a proper C declaration. # Some systems (esp. on ia64) link data and code symbols differently, # so use this general approach. lt_cv_sys_global_symbol_to_cdecl="$SED -n"\ $lt_cdecl_hook\ " -e 's/^T .* \(.*\)$/extern int \1();/p'"\ " -e 's/^$symcode$symcode* .* \(.*\)$/extern char \1;/p'" # Transform an extracted symbol line into symbol name and symbol address lt_cv_sys_global_symbol_to_c_name_address="$SED -n"\ $lt_c_name_hook\ " -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ " -e 's/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/p'" # Transform an extracted symbol line into symbol name with lib prefix and # symbol address. lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="$SED -n"\ $lt_c_name_lib_hook\ " -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ " -e 's/^$symcode$symcode* .* \(lib.*\)$/ {\"\1\", (void *) \&\1},/p'"\ " -e 's/^$symcode$symcode* .* \(.*\)$/ {\"lib\1\", (void *) \&\1},/p'" # Handle CRLF in mingw tool chain opt_cr= case $build_os in mingw*) opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp ;; esac # Try without a prefix underscore, then with it. for ac_symprfx in "" "_"; do # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. symxfrm="\\1 $ac_symprfx\\2 \\2" # Write the raw and C identifiers. if test "$lt_cv_nm_interface" = "MS dumpbin"; then # Fake it for dumpbin and say T for any non-static function, # D for any global variable and I for any imported variable. # Also find C++ and __fastcall symbols from MSVC++ or ICC, # which start with @ or ?. lt_cv_sys_global_symbol_pipe="$AWK '"\ " {last_section=section; section=\$ 3};"\ " /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\ " /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ " /^ *Symbol name *: /{split(\$ 0,sn,\":\"); si=substr(sn[2],2)};"\ " /^ *Type *: code/{print \"T\",si,substr(si,length(prfx))};"\ " /^ *Type *: data/{print \"I\",si,substr(si,length(prfx))};"\ " \$ 0!~/External *\|/{next};"\ " / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ " {if(hide[section]) next};"\ " {f=\"D\"}; \$ 0~/\(\).*\|/{f=\"T\"};"\ " {split(\$ 0,a,/\||\r/); split(a[2],s)};"\ " s[1]~/^[@?]/{print f,s[1],s[1]; next};"\ " s[1]~prfx {split(s[1],t,\"@\"); print f,t[1],substr(t[1],length(prfx))}"\ " ' prfx=^$ac_symprfx" else lt_cv_sys_global_symbol_pipe="$SED -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" fi lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | $SED '/ __gnu_lto/d'" # Check to see that the pipe works correctly. pipe_works=no rm -f conftest* cat > conftest.$ac_ext <<_LT_EOF #ifdef __cplusplus extern "C" { #endif char nm_test_var; void nm_test_func(void); void nm_test_func(void){} #ifdef __cplusplus } #endif int main(){nm_test_var='a';nm_test_func();return(0);} _LT_EOF if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then # Now try to grab the symbols. nlist=conftest.nm if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist\""; } >&5 (eval $NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -s "$nlist"; then # Try sorting and uniquifying the output. if sort "$nlist" | uniq > "$nlist"T; then mv -f "$nlist"T "$nlist" else rm -f "$nlist"T fi # Make sure that we snagged all the symbols we need. if $GREP ' nm_test_var$' "$nlist" >/dev/null; then if $GREP ' nm_test_func$' "$nlist" >/dev/null; then cat <<_LT_EOF > conftest.$ac_ext /* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ #if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE /* DATA imports from DLLs on WIN32 can't be const, because runtime relocations are performed -- see ld's documentation on pseudo-relocs. */ # define LT_DLSYM_CONST #elif defined __osf__ /* This system does not cope well with relocations in const data. */ # define LT_DLSYM_CONST #else # define LT_DLSYM_CONST const #endif #ifdef __cplusplus extern "C" { #endif _LT_EOF # Now generate the symbol file. eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' cat <<_LT_EOF >> conftest.$ac_ext /* The mapping between symbol names and symbols. */ LT_DLSYM_CONST struct { const char *name; void *address; } lt__PROGRAM__LTX_preloaded_symbols[] = { { "@PROGRAM@", (void *) 0 }, _LT_EOF $SED "s/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext cat <<\_LT_EOF >> conftest.$ac_ext {0, (void *) 0} }; /* This works around a problem in FreeBSD linker */ #ifdef FREEBSD_WORKAROUND static const void *lt_preloaded_setup() { return lt__PROGRAM__LTX_preloaded_symbols; } #endif #ifdef __cplusplus } #endif _LT_EOF # Now try linking the two files. mv conftest.$ac_objext conftstm.$ac_objext lt_globsym_save_LIBS=$LIBS lt_globsym_save_CFLAGS=$CFLAGS LIBS=conftstm.$ac_objext CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag" if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 (eval $ac_link) 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -s conftest$ac_exeext; then pipe_works=yes fi LIBS=$lt_globsym_save_LIBS CFLAGS=$lt_globsym_save_CFLAGS else echo "cannot find nm_test_func in $nlist" >&5 fi else echo "cannot find nm_test_var in $nlist" >&5 fi else echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5 fi else echo "$progname: failed program was:" >&5 cat conftest.$ac_ext >&5 fi rm -rf conftest* conftst* # Do not use the global_symbol_pipe unless it works. if test yes = "$pipe_works"; then break else lt_cv_sys_global_symbol_pipe= fi done fi if test -z "$lt_cv_sys_global_symbol_pipe"; then lt_cv_sys_global_symbol_to_cdecl= fi if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: failed" >&5 printf "%s\n" "failed" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: ok" >&5 printf "%s\n" "ok" >&6; } fi # Response file support. if test "$lt_cv_nm_interface" = "MS dumpbin"; then nm_file_list_spec='@' elif $NM --help 2>/dev/null | grep '[@]FILE' >/dev/null; then nm_file_list_spec='@' fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for sysroot" >&5 printf %s "checking for sysroot... " >&6; } # Check whether --with-sysroot was given. if test ${with_sysroot+y} then : withval=$with_sysroot; else $as_nop with_sysroot=no fi lt_sysroot= case $with_sysroot in #( yes) if test yes = "$GCC"; then lt_sysroot=`$CC --print-sysroot 2>/dev/null` fi ;; #( /*) lt_sysroot=`echo "$with_sysroot" | $SED -e "$sed_quote_subst"` ;; #( no|'') ;; #( *) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $with_sysroot" >&5 printf "%s\n" "$with_sysroot" >&6; } as_fn_error $? "The sysroot must be an absolute path." "$LINENO" 5 ;; esac { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: ${lt_sysroot:-no}" >&5 printf "%s\n" "${lt_sysroot:-no}" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for a working dd" >&5 printf %s "checking for a working dd... " >&6; } if test ${ac_cv_path_lt_DD+y} then : printf %s "(cached) " >&6 else $as_nop printf 0123456789abcdef0123456789abcdef >conftest.i cat conftest.i conftest.i >conftest2.i : ${lt_DD:=$DD} if test -z "$lt_DD"; then ac_path_lt_DD_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_prog in dd do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_lt_DD="$as_dir$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_lt_DD" || continue if "$ac_path_lt_DD" bs=32 count=1 conftest.out 2>/dev/null; then cmp -s conftest.i conftest.out \ && ac_cv_path_lt_DD="$ac_path_lt_DD" ac_path_lt_DD_found=: fi $ac_path_lt_DD_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_lt_DD"; then : fi else ac_cv_path_lt_DD=$lt_DD fi rm -f conftest.i conftest2.i conftest.out fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_lt_DD" >&5 printf "%s\n" "$ac_cv_path_lt_DD" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to truncate binary pipes" >&5 printf %s "checking how to truncate binary pipes... " >&6; } if test ${lt_cv_truncate_bin+y} then : printf %s "(cached) " >&6 else $as_nop printf 0123456789abcdef0123456789abcdef >conftest.i cat conftest.i conftest.i >conftest2.i lt_cv_truncate_bin= if "$ac_cv_path_lt_DD" bs=32 count=1 conftest.out 2>/dev/null; then cmp -s conftest.i conftest.out \ && lt_cv_truncate_bin="$ac_cv_path_lt_DD bs=4096 count=1" fi rm -f conftest.i conftest2.i conftest.out test -z "$lt_cv_truncate_bin" && lt_cv_truncate_bin="$SED -e 4q" fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_truncate_bin" >&5 printf "%s\n" "$lt_cv_truncate_bin" >&6; } # Calculate cc_basename. Skip known compiler wrappers and cross-prefix. func_cc_basename () { for cc_temp in $*""; do case $cc_temp in compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; \-*) ;; *) break;; esac done func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` } # Check whether --enable-libtool-lock was given. if test ${enable_libtool_lock+y} then : enableval=$enable_libtool_lock; fi test no = "$enable_libtool_lock" || enable_libtool_lock=yes # Some flags need to be propagated to the compiler or linker for good # libtool support. case $host in ia64-*-hpux*) # Find out what ABI is being produced by ac_compile, and set mode # options accordingly. echo 'int i;' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then case `$FILECMD conftest.$ac_objext` in *ELF-32*) HPUX_IA64_MODE=32 ;; *ELF-64*) HPUX_IA64_MODE=64 ;; esac fi rm -rf conftest* ;; *-*-irix6*) # Find out what ABI is being produced by ac_compile, and set linker # options accordingly. echo '#line '$LINENO' "configure"' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then if test yes = "$lt_cv_prog_gnu_ld"; then case `$FILECMD conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -melf32bsmip" ;; *N32*) LD="${LD-ld} -melf32bmipn32" ;; *64-bit*) LD="${LD-ld} -melf64bmip" ;; esac else case `$FILECMD conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -32" ;; *N32*) LD="${LD-ld} -n32" ;; *64-bit*) LD="${LD-ld} -64" ;; esac fi fi rm -rf conftest* ;; mips64*-*linux*) # Find out what ABI is being produced by ac_compile, and set linker # options accordingly. echo '#line '$LINENO' "configure"' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then emul=elf case `$FILECMD conftest.$ac_objext` in *32-bit*) emul="${emul}32" ;; *64-bit*) emul="${emul}64" ;; esac case `$FILECMD conftest.$ac_objext` in *MSB*) emul="${emul}btsmip" ;; *LSB*) emul="${emul}ltsmip" ;; esac case `$FILECMD conftest.$ac_objext` in *N32*) emul="${emul}n32" ;; esac LD="${LD-ld} -m $emul" fi rm -rf conftest* ;; x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) # Find out what ABI is being produced by ac_compile, and set linker # options accordingly. Note that the listed cases only cover the # situations where additional linker options are needed (such as when # doing 32-bit compilation for a host where ld defaults to 64-bit, or # vice versa); the common cases where no linker options are needed do # not appear in the list. echo 'int i;' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then case `$FILECMD conftest.o` in *32-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_i386_fbsd" ;; x86_64-*linux*) case `$FILECMD conftest.o` in *x86-64*) LD="${LD-ld} -m elf32_x86_64" ;; *) LD="${LD-ld} -m elf_i386" ;; esac ;; powerpc64le-*linux*) LD="${LD-ld} -m elf32lppclinux" ;; powerpc64-*linux*) LD="${LD-ld} -m elf32ppclinux" ;; s390x-*linux*) LD="${LD-ld} -m elf_s390" ;; sparc64-*linux*) LD="${LD-ld} -m elf32_sparc" ;; esac ;; *64-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_x86_64_fbsd" ;; x86_64-*linux*) LD="${LD-ld} -m elf_x86_64" ;; powerpcle-*linux*) LD="${LD-ld} -m elf64lppc" ;; powerpc-*linux*) LD="${LD-ld} -m elf64ppc" ;; s390*-*linux*|s390*-*tpf*) LD="${LD-ld} -m elf64_s390" ;; sparc*-*linux*) LD="${LD-ld} -m elf64_sparc" ;; esac ;; esac fi rm -rf conftest* ;; *-*-sco3.2v5*) # On SCO OpenServer 5, we need -belf to get full-featured binaries. SAVE_CFLAGS=$CFLAGS CFLAGS="$CFLAGS -belf" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the C compiler needs -belf" >&5 printf %s "checking whether the C compiler needs -belf... " >&6; } if test ${lt_cv_cc_needs_belf+y} then : printf %s "(cached) " >&6 else $as_nop ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : lt_cv_cc_needs_belf=yes else $as_nop lt_cv_cc_needs_belf=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_cc_needs_belf" >&5 printf "%s\n" "$lt_cv_cc_needs_belf" >&6; } if test yes != "$lt_cv_cc_needs_belf"; then # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf CFLAGS=$SAVE_CFLAGS fi ;; *-*solaris*) # Find out what ABI is being produced by ac_compile, and set linker # options accordingly. echo 'int i;' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then case `$FILECMD conftest.o` in *64-bit*) case $lt_cv_prog_gnu_ld in yes*) case $host in i?86-*-solaris*|x86_64-*-solaris*) LD="${LD-ld} -m elf_x86_64" ;; sparc*-*-solaris*) LD="${LD-ld} -m elf64_sparc" ;; esac # GNU ld 2.21 introduced _sol2 emulations. Use them if available. if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then LD=${LD-ld}_sol2 fi ;; *) if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then LD="${LD-ld} -64" fi ;; esac ;; esac fi rm -rf conftest* ;; esac need_locks=$enable_libtool_lock if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}mt", so it can be a program name with args. set dummy ${ac_tool_prefix}mt; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_MANIFEST_TOOL+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$MANIFEST_TOOL"; then ac_cv_prog_MANIFEST_TOOL="$MANIFEST_TOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_MANIFEST_TOOL="${ac_tool_prefix}mt" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi MANIFEST_TOOL=$ac_cv_prog_MANIFEST_TOOL if test -n "$MANIFEST_TOOL"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $MANIFEST_TOOL" >&5 printf "%s\n" "$MANIFEST_TOOL" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_prog_MANIFEST_TOOL"; then ac_ct_MANIFEST_TOOL=$MANIFEST_TOOL # Extract the first word of "mt", so it can be a program name with args. set dummy mt; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_MANIFEST_TOOL+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_MANIFEST_TOOL"; then ac_cv_prog_ac_ct_MANIFEST_TOOL="$ac_ct_MANIFEST_TOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_MANIFEST_TOOL="mt" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_MANIFEST_TOOL=$ac_cv_prog_ac_ct_MANIFEST_TOOL if test -n "$ac_ct_MANIFEST_TOOL"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_MANIFEST_TOOL" >&5 printf "%s\n" "$ac_ct_MANIFEST_TOOL" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_MANIFEST_TOOL" = x; then MANIFEST_TOOL=":" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac MANIFEST_TOOL=$ac_ct_MANIFEST_TOOL fi else MANIFEST_TOOL="$ac_cv_prog_MANIFEST_TOOL" fi test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $MANIFEST_TOOL is a manifest tool" >&5 printf %s "checking if $MANIFEST_TOOL is a manifest tool... " >&6; } if test ${lt_cv_path_mainfest_tool+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_path_mainfest_tool=no echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&5 $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out cat conftest.err >&5 if $GREP 'Manifest Tool' conftest.out > /dev/null; then lt_cv_path_mainfest_tool=yes fi rm -f conftest* fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_mainfest_tool" >&5 printf "%s\n" "$lt_cv_path_mainfest_tool" >&6; } if test yes != "$lt_cv_path_mainfest_tool"; then MANIFEST_TOOL=: fi case $host_os in rhapsody* | darwin*) if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}dsymutil", so it can be a program name with args. set dummy ${ac_tool_prefix}dsymutil; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_DSYMUTIL+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$DSYMUTIL"; then ac_cv_prog_DSYMUTIL="$DSYMUTIL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_DSYMUTIL="${ac_tool_prefix}dsymutil" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi DSYMUTIL=$ac_cv_prog_DSYMUTIL if test -n "$DSYMUTIL"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $DSYMUTIL" >&5 printf "%s\n" "$DSYMUTIL" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_prog_DSYMUTIL"; then ac_ct_DSYMUTIL=$DSYMUTIL # Extract the first word of "dsymutil", so it can be a program name with args. set dummy dsymutil; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_DSYMUTIL+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_DSYMUTIL"; then ac_cv_prog_ac_ct_DSYMUTIL="$ac_ct_DSYMUTIL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_DSYMUTIL="dsymutil" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_DSYMUTIL=$ac_cv_prog_ac_ct_DSYMUTIL if test -n "$ac_ct_DSYMUTIL"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DSYMUTIL" >&5 printf "%s\n" "$ac_ct_DSYMUTIL" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_DSYMUTIL" = x; then DSYMUTIL=":" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac DSYMUTIL=$ac_ct_DSYMUTIL fi else DSYMUTIL="$ac_cv_prog_DSYMUTIL" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}nmedit", so it can be a program name with args. set dummy ${ac_tool_prefix}nmedit; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_NMEDIT+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$NMEDIT"; then ac_cv_prog_NMEDIT="$NMEDIT" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_NMEDIT="${ac_tool_prefix}nmedit" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi NMEDIT=$ac_cv_prog_NMEDIT if test -n "$NMEDIT"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $NMEDIT" >&5 printf "%s\n" "$NMEDIT" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_prog_NMEDIT"; then ac_ct_NMEDIT=$NMEDIT # Extract the first word of "nmedit", so it can be a program name with args. set dummy nmedit; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_NMEDIT+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_NMEDIT"; then ac_cv_prog_ac_ct_NMEDIT="$ac_ct_NMEDIT" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_NMEDIT="nmedit" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_NMEDIT=$ac_cv_prog_ac_ct_NMEDIT if test -n "$ac_ct_NMEDIT"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_NMEDIT" >&5 printf "%s\n" "$ac_ct_NMEDIT" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_NMEDIT" = x; then NMEDIT=":" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac NMEDIT=$ac_ct_NMEDIT fi else NMEDIT="$ac_cv_prog_NMEDIT" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}lipo", so it can be a program name with args. set dummy ${ac_tool_prefix}lipo; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_LIPO+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$LIPO"; then ac_cv_prog_LIPO="$LIPO" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_LIPO="${ac_tool_prefix}lipo" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi LIPO=$ac_cv_prog_LIPO if test -n "$LIPO"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $LIPO" >&5 printf "%s\n" "$LIPO" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_prog_LIPO"; then ac_ct_LIPO=$LIPO # Extract the first word of "lipo", so it can be a program name with args. set dummy lipo; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_LIPO+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_LIPO"; then ac_cv_prog_ac_ct_LIPO="$ac_ct_LIPO" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_LIPO="lipo" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_LIPO=$ac_cv_prog_ac_ct_LIPO if test -n "$ac_ct_LIPO"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_LIPO" >&5 printf "%s\n" "$ac_ct_LIPO" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_LIPO" = x; then LIPO=":" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac LIPO=$ac_ct_LIPO fi else LIPO="$ac_cv_prog_LIPO" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}otool", so it can be a program name with args. set dummy ${ac_tool_prefix}otool; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_OTOOL+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$OTOOL"; then ac_cv_prog_OTOOL="$OTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_OTOOL="${ac_tool_prefix}otool" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi OTOOL=$ac_cv_prog_OTOOL if test -n "$OTOOL"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $OTOOL" >&5 printf "%s\n" "$OTOOL" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_prog_OTOOL"; then ac_ct_OTOOL=$OTOOL # Extract the first word of "otool", so it can be a program name with args. set dummy otool; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_OTOOL+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_OTOOL"; then ac_cv_prog_ac_ct_OTOOL="$ac_ct_OTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_OTOOL="otool" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_OTOOL=$ac_cv_prog_ac_ct_OTOOL if test -n "$ac_ct_OTOOL"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL" >&5 printf "%s\n" "$ac_ct_OTOOL" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_OTOOL" = x; then OTOOL=":" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac OTOOL=$ac_ct_OTOOL fi else OTOOL="$ac_cv_prog_OTOOL" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}otool64", so it can be a program name with args. set dummy ${ac_tool_prefix}otool64; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_OTOOL64+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$OTOOL64"; then ac_cv_prog_OTOOL64="$OTOOL64" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_OTOOL64="${ac_tool_prefix}otool64" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi OTOOL64=$ac_cv_prog_OTOOL64 if test -n "$OTOOL64"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $OTOOL64" >&5 printf "%s\n" "$OTOOL64" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_prog_OTOOL64"; then ac_ct_OTOOL64=$OTOOL64 # Extract the first word of "otool64", so it can be a program name with args. set dummy otool64; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_OTOOL64+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_OTOOL64"; then ac_cv_prog_ac_ct_OTOOL64="$ac_ct_OTOOL64" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_OTOOL64="otool64" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_OTOOL64=$ac_cv_prog_ac_ct_OTOOL64 if test -n "$ac_ct_OTOOL64"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL64" >&5 printf "%s\n" "$ac_ct_OTOOL64" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_OTOOL64" = x; then OTOOL64=":" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac OTOOL64=$ac_ct_OTOOL64 fi else OTOOL64="$ac_cv_prog_OTOOL64" fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for -single_module linker flag" >&5 printf %s "checking for -single_module linker flag... " >&6; } if test ${lt_cv_apple_cc_single_mod+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_apple_cc_single_mod=no if test -z "$LT_MULTI_MODULE"; then # By default we will add the -single_module flag. You can override # by either setting the environment variable LT_MULTI_MODULE # non-empty at configure time, or by adding -multi_module to the # link flags. rm -rf libconftest.dylib* echo "int foo(void){return 1;}" > conftest.c echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c" >&5 $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c 2>conftest.err _lt_result=$? # If there is a non-empty error log, and "single_module" # appears in it, assume the flag caused a linker warning if test -s conftest.err && $GREP single_module conftest.err; then cat conftest.err >&5 # Otherwise, if the output was created with a 0 exit code from # the compiler, it worked. elif test -f libconftest.dylib && test 0 = "$_lt_result"; then lt_cv_apple_cc_single_mod=yes else cat conftest.err >&5 fi rm -rf libconftest.dylib* rm -f conftest.* fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_apple_cc_single_mod" >&5 printf "%s\n" "$lt_cv_apple_cc_single_mod" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for -exported_symbols_list linker flag" >&5 printf %s "checking for -exported_symbols_list linker flag... " >&6; } if test ${lt_cv_ld_exported_symbols_list+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_ld_exported_symbols_list=no save_LDFLAGS=$LDFLAGS echo "_main" > conftest.sym LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : lt_cv_ld_exported_symbols_list=yes else $as_nop lt_cv_ld_exported_symbols_list=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LDFLAGS=$save_LDFLAGS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5 printf "%s\n" "$lt_cv_ld_exported_symbols_list" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for -force_load linker flag" >&5 printf %s "checking for -force_load linker flag... " >&6; } if test ${lt_cv_ld_force_load+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_ld_force_load=no cat > conftest.c << _LT_EOF int forced_loaded() { return 2;} _LT_EOF echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&5 $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5 echo "$AR $AR_FLAGS libconftest.a conftest.o" >&5 $AR $AR_FLAGS libconftest.a conftest.o 2>&5 echo "$RANLIB libconftest.a" >&5 $RANLIB libconftest.a 2>&5 cat > conftest.c << _LT_EOF int main() { return 0;} _LT_EOF echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&5 $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err _lt_result=$? if test -s conftest.err && $GREP force_load conftest.err; then cat conftest.err >&5 elif test -f conftest && test 0 = "$_lt_result" && $GREP forced_load conftest >/dev/null 2>&1; then lt_cv_ld_force_load=yes else cat conftest.err >&5 fi rm -f conftest.err libconftest.a conftest conftest.c rm -rf conftest.dSYM fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_force_load" >&5 printf "%s\n" "$lt_cv_ld_force_load" >&6; } case $host_os in rhapsody* | darwin1.[012]) _lt_dar_allow_undefined='$wl-undefined ${wl}suppress' ;; darwin1.*) _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; darwin*) case $MACOSX_DEPLOYMENT_TARGET,$host in 10.[012],*|,*powerpc*-darwin[5-8]*) _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; *) _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; esac ;; esac if test yes = "$lt_cv_apple_cc_single_mod"; then _lt_dar_single_mod='$single_module' fi if test yes = "$lt_cv_ld_exported_symbols_list"; then _lt_dar_export_syms=' $wl-exported_symbols_list,$output_objdir/$libname-symbols.expsym' else _lt_dar_export_syms='~$NMEDIT -s $output_objdir/$libname-symbols.expsym $lib' fi if test : != "$DSYMUTIL" && test no = "$lt_cv_ld_force_load"; then _lt_dsymutil='~$DSYMUTIL $lib || :' else _lt_dsymutil= fi ;; esac # func_munge_path_list VARIABLE PATH # ----------------------------------- # VARIABLE is name of variable containing _space_ separated list of # directories to be munged by the contents of PATH, which is string # having a format: # "DIR[:DIR]:" # string "DIR[ DIR]" will be prepended to VARIABLE # ":DIR[:DIR]" # string "DIR[ DIR]" will be appended to VARIABLE # "DIRP[:DIRP]::[DIRA:]DIRA" # string "DIRP[ DIRP]" will be prepended to VARIABLE and string # "DIRA[ DIRA]" will be appended to VARIABLE # "DIR[:DIR]" # VARIABLE will be replaced by "DIR[ DIR]" func_munge_path_list () { case x$2 in x) ;; *:) eval $1=\"`$ECHO $2 | $SED 's/:/ /g'` \$$1\" ;; x:*) eval $1=\"\$$1 `$ECHO $2 | $SED 's/:/ /g'`\" ;; *::*) eval $1=\"\$$1\ `$ECHO $2 | $SED -e 's/.*:://' -e 's/:/ /g'`\" eval $1=\"`$ECHO $2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \$$1\" ;; *) eval $1=\"`$ECHO $2 | $SED 's/:/ /g'`\" ;; esac } ac_header= ac_cache= for ac_item in $ac_header_c_list do if test $ac_cache; then ac_fn_c_check_header_compile "$LINENO" $ac_header ac_cv_header_$ac_cache "$ac_includes_default" if eval test \"x\$ac_cv_header_$ac_cache\" = xyes; then printf "%s\n" "#define $ac_item 1" >> confdefs.h fi ac_header= ac_cache= elif test $ac_header; then ac_cache=$ac_item else ac_header=$ac_item fi done if test $ac_cv_header_stdlib_h = yes && test $ac_cv_header_string_h = yes then : printf "%s\n" "#define STDC_HEADERS 1" >>confdefs.h fi ac_fn_c_check_header_compile "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default " if test "x$ac_cv_header_dlfcn_h" = xyes then : printf "%s\n" "#define HAVE_DLFCN_H 1" >>confdefs.h fi # Set options enable_dlopen=no enable_win32_dll=no # Check whether --enable-shared was given. if test ${enable_shared+y} then : enableval=$enable_shared; p=${PACKAGE-default} case $enableval in yes) enable_shared=yes ;; no) enable_shared=no ;; *) enable_shared=no # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for pkg in $enableval; do IFS=$lt_save_ifs if test "X$pkg" = "X$p"; then enable_shared=yes fi done IFS=$lt_save_ifs ;; esac else $as_nop enable_shared=yes fi # Check whether --with-pic was given. if test ${with_pic+y} then : withval=$with_pic; lt_p=${PACKAGE-default} case $withval in yes|no) pic_mode=$withval ;; *) pic_mode=default # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for lt_pkg in $withval; do IFS=$lt_save_ifs if test "X$lt_pkg" = "X$lt_p"; then pic_mode=yes fi done IFS=$lt_save_ifs ;; esac else $as_nop pic_mode=default fi # Check whether --enable-fast-install was given. if test ${enable_fast_install+y} then : enableval=$enable_fast_install; p=${PACKAGE-default} case $enableval in yes) enable_fast_install=yes ;; no) enable_fast_install=no ;; *) enable_fast_install=no # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for pkg in $enableval; do IFS=$lt_save_ifs if test "X$pkg" = "X$p"; then enable_fast_install=yes fi done IFS=$lt_save_ifs ;; esac else $as_nop enable_fast_install=yes fi shared_archive_member_spec= case $host,$enable_shared in power*-*-aix[5-9]*,yes) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking which variant of shared library versioning to provide" >&5 printf %s "checking which variant of shared library versioning to provide... " >&6; } # Check whether --with-aix-soname was given. if test ${with_aix_soname+y} then : withval=$with_aix_soname; case $withval in aix|svr4|both) ;; *) as_fn_error $? "Unknown argument to --with-aix-soname" "$LINENO" 5 ;; esac lt_cv_with_aix_soname=$with_aix_soname else $as_nop if test ${lt_cv_with_aix_soname+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_with_aix_soname=aix fi with_aix_soname=$lt_cv_with_aix_soname fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $with_aix_soname" >&5 printf "%s\n" "$with_aix_soname" >&6; } if test aix != "$with_aix_soname"; then # For the AIX way of multilib, we name the shared archive member # based on the bitwidth used, traditionally 'shr.o' or 'shr_64.o', # and 'shr.imp' or 'shr_64.imp', respectively, for the Import File. # Even when GNU compilers ignore OBJECT_MODE but need '-maix64' flag, # the AIX toolchain works better with OBJECT_MODE set (default 32). if test 64 = "${OBJECT_MODE-32}"; then shared_archive_member_spec=shr_64 else shared_archive_member_spec=shr fi fi ;; *) with_aix_soname=aix ;; esac # This can be used to rebuild libtool when needed LIBTOOL_DEPS=$ltmain # Always use our own libtool. LIBTOOL='$(SHELL) $(top_builddir)/libtool' test -z "$LN_S" && LN_S="ln -s" if test -n "${ZSH_VERSION+set}"; then setopt NO_GLOB_SUBST fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for objdir" >&5 printf %s "checking for objdir... " >&6; } if test ${lt_cv_objdir+y} then : printf %s "(cached) " >&6 else $as_nop rm -f .libs 2>/dev/null mkdir .libs 2>/dev/null if test -d .libs; then lt_cv_objdir=.libs else # MS-DOS does not allow filenames that begin with a dot. lt_cv_objdir=_libs fi rmdir .libs 2>/dev/null fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_objdir" >&5 printf "%s\n" "$lt_cv_objdir" >&6; } objdir=$lt_cv_objdir printf "%s\n" "#define LT_OBJDIR \"$lt_cv_objdir/\"" >>confdefs.h case $host_os in aix3*) # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test set != "${COLLECT_NAMES+set}"; then COLLECT_NAMES= export COLLECT_NAMES fi ;; esac # Global variables: ofile=libtool can_build_shared=yes # All known linkers require a '.a' archive for static linking (except MSVC and # ICC, which need '.lib'). libext=a with_gnu_ld=$lt_cv_prog_gnu_ld old_CC=$CC old_CFLAGS=$CFLAGS # Set sane defaults for various variables test -z "$CC" && CC=cc test -z "$LTCC" && LTCC=$CC test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS test -z "$LD" && LD=ld test -z "$ac_objext" && ac_objext=o func_cc_basename $compiler cc_basename=$func_cc_basename_result # Only perform the check for file, if the check method requires it test -z "$MAGIC_CMD" && MAGIC_CMD=file case $deplibs_check_method in file_magic*) if test "$file_magic_cmd" = '$MAGIC_CMD'; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ${ac_tool_prefix}file" >&5 printf %s "checking for ${ac_tool_prefix}file... " >&6; } if test ${lt_cv_path_MAGIC_CMD+y} then : printf %s "(cached) " >&6 else $as_nop case $MAGIC_CMD in [\\/*] | ?:[\\/]*) lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path. ;; *) lt_save_MAGIC_CMD=$MAGIC_CMD lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" for ac_dir in $ac_dummy; do IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/${ac_tool_prefix}file"; then lt_cv_path_MAGIC_CMD=$ac_dir/"${ac_tool_prefix}file" if test -n "$file_magic_test_file"; then case $deplibs_check_method in "file_magic "*) file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` MAGIC_CMD=$lt_cv_path_MAGIC_CMD if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | $EGREP "$file_magic_regex" > /dev/null; then : else cat <<_LT_EOF 1>&2 *** Warning: the command libtool uses to detect shared libraries, *** $file_magic_cmd, produces output that libtool cannot recognize. *** The result is that libtool may fail to recognize shared libraries *** as such. This will affect the creation of libtool libraries that *** depend on shared libraries, but programs linked with such libtool *** libraries will work regardless of this problem. Nevertheless, you *** may want to report the problem to your system manager and/or to *** bug-libtool@gnu.org _LT_EOF fi ;; esac fi break fi done IFS=$lt_save_ifs MAGIC_CMD=$lt_save_MAGIC_CMD ;; esac fi MAGIC_CMD=$lt_cv_path_MAGIC_CMD if test -n "$MAGIC_CMD"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 printf "%s\n" "$MAGIC_CMD" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test -z "$lt_cv_path_MAGIC_CMD"; then if test -n "$ac_tool_prefix"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for file" >&5 printf %s "checking for file... " >&6; } if test ${lt_cv_path_MAGIC_CMD+y} then : printf %s "(cached) " >&6 else $as_nop case $MAGIC_CMD in [\\/*] | ?:[\\/]*) lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path. ;; *) lt_save_MAGIC_CMD=$MAGIC_CMD lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" for ac_dir in $ac_dummy; do IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/file"; then lt_cv_path_MAGIC_CMD=$ac_dir/"file" if test -n "$file_magic_test_file"; then case $deplibs_check_method in "file_magic "*) file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` MAGIC_CMD=$lt_cv_path_MAGIC_CMD if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | $EGREP "$file_magic_regex" > /dev/null; then : else cat <<_LT_EOF 1>&2 *** Warning: the command libtool uses to detect shared libraries, *** $file_magic_cmd, produces output that libtool cannot recognize. *** The result is that libtool may fail to recognize shared libraries *** as such. This will affect the creation of libtool libraries that *** depend on shared libraries, but programs linked with such libtool *** libraries will work regardless of this problem. Nevertheless, you *** may want to report the problem to your system manager and/or to *** bug-libtool@gnu.org _LT_EOF fi ;; esac fi break fi done IFS=$lt_save_ifs MAGIC_CMD=$lt_save_MAGIC_CMD ;; esac fi MAGIC_CMD=$lt_cv_path_MAGIC_CMD if test -n "$MAGIC_CMD"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 printf "%s\n" "$MAGIC_CMD" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi else MAGIC_CMD=: fi fi fi ;; esac # Use C for the default configuration in the libtool script lt_save_CC=$CC ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu # Source file extension for C test sources. ac_ext=c # Object file extension for compiled C test sources. objext=o objext=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="int some_variable = 0;" # Code to be used in simple link tests lt_simple_link_test_code='int main(){return(0);}' # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} # If no C compiler flags were specified, use CFLAGS. LTCFLAGS=${LTCFLAGS-"$CFLAGS"} # Allow CC to be a program name with arguments. compiler=$CC # Save the default compiler, since it gets overwritten when the other # tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. compiler_DEFAULT=$CC # save warnings/boilerplate of simple test code ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" >conftest.$ac_ext eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_compiler_boilerplate=`cat conftest.err` $RM conftest* ac_outfile=conftest.$ac_objext echo "$lt_simple_link_test_code" >conftest.$ac_ext eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_linker_boilerplate=`cat conftest.err` $RM -r conftest* ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... if test -n "$compiler"; then lt_prog_compiler_no_builtin_flag= if test yes = "$GCC"; then case $cc_basename in nvcc*) lt_prog_compiler_no_builtin_flag=' -Xcompiler -fno-builtin' ;; *) lt_prog_compiler_no_builtin_flag=' -fno-builtin' ;; esac { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 printf %s "checking if $compiler supports -fno-rtti -fno-exceptions... " >&6; } if test ${lt_cv_prog_compiler_rtti_exceptions+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_prog_compiler_rtti_exceptions=no ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-fno-rtti -fno-exceptions" ## exclude from sc_useless_quotes_in_assignment # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_rtti_exceptions=yes fi fi $RM conftest* fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_rtti_exceptions" >&5 printf "%s\n" "$lt_cv_prog_compiler_rtti_exceptions" >&6; } if test yes = "$lt_cv_prog_compiler_rtti_exceptions"; then lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions" else : fi fi lt_prog_compiler_wl= lt_prog_compiler_pic= lt_prog_compiler_static= if test yes = "$GCC"; then lt_prog_compiler_wl='-Wl,' lt_prog_compiler_static='-static' case $host_os in aix*) # All AIX code is PIC. if test ia64 = "$host_cpu"; then # AIX 5 now supports IA64 processor lt_prog_compiler_static='-Bstatic' fi lt_prog_compiler_pic='-fPIC' ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support lt_prog_compiler_pic='-fPIC' ;; m68k) # FIXME: we need at least 68020 code to build shared libraries, but # adding the '-m68020' flag to GCC prevents building anything better, # like '-m68040'. lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4' ;; esac ;; beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). # Although the cygwin gcc ignores -fPIC, still need this for old-style # (--disable-auto-import) libraries lt_prog_compiler_pic='-DDLL_EXPORT' case $host_os in os2*) lt_prog_compiler_static='$wl-static' ;; esac ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files lt_prog_compiler_pic='-fno-common' ;; haiku*) # PIC is the default for Haiku. # The "-static" flag exists, but is broken. lt_prog_compiler_static= ;; hpux*) # PIC is the default for 64-bit PA HP-UX, but not for 32-bit # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag # sets the default TLS model and affects inlining. case $host_cpu in hppa*64*) # +Z the default ;; *) lt_prog_compiler_pic='-fPIC' ;; esac ;; interix[3-9]*) # Interix 3.x gcc -fpic/-fPIC options generate broken code. # Instead, we relocate shared libraries at runtime. ;; msdosdjgpp*) # Just because we use GCC doesn't mean we suddenly get shared libraries # on systems that don't support them. lt_prog_compiler_can_build_shared=no enable_shared=no ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. lt_prog_compiler_pic='-fPIC -shared' ;; sysv4*MP*) if test -d /usr/nec; then lt_prog_compiler_pic=-Kconform_pic fi ;; *) lt_prog_compiler_pic='-fPIC' ;; esac case $cc_basename in nvcc*) # Cuda Compiler Driver 2.2 lt_prog_compiler_wl='-Xlinker ' if test -n "$lt_prog_compiler_pic"; then lt_prog_compiler_pic="-Xcompiler $lt_prog_compiler_pic" fi ;; esac else # PORTME Check for flag to pass linker flags through the system compiler. case $host_os in aix*) lt_prog_compiler_wl='-Wl,' if test ia64 = "$host_cpu"; then # AIX 5 now supports IA64 processor lt_prog_compiler_static='-Bstatic' else lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp' fi ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files lt_prog_compiler_pic='-fno-common' case $cc_basename in nagfor*) # NAG Fortran compiler lt_prog_compiler_wl='-Wl,-Wl,,' lt_prog_compiler_pic='-PIC' lt_prog_compiler_static='-Bstatic' ;; esac ;; mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). lt_prog_compiler_pic='-DDLL_EXPORT' case $host_os in os2*) lt_prog_compiler_static='$wl-static' ;; esac ;; hpux9* | hpux10* | hpux11*) lt_prog_compiler_wl='-Wl,' # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but # not for PA HP-UX. case $host_cpu in hppa*64*|ia64*) # +Z the default ;; *) lt_prog_compiler_pic='+Z' ;; esac # Is there a better lt_prog_compiler_static that works with the bundled CC? lt_prog_compiler_static='$wl-a ${wl}archive' ;; irix5* | irix6* | nonstopux*) lt_prog_compiler_wl='-Wl,' # PIC (with -KPIC) is the default. lt_prog_compiler_static='-non_shared' ;; linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) case $cc_basename in # old Intel for x86_64, which still supported -KPIC. ecc*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-static' ;; # icc used to be incompatible with GCC. # ICC 10 doesn't accept -KPIC any more. icc* | ifort*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fPIC' lt_prog_compiler_static='-static' ;; # Lahey Fortran 8.1. lf95*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='--shared' lt_prog_compiler_static='--static' ;; nagfor*) # NAG Fortran compiler lt_prog_compiler_wl='-Wl,-Wl,,' lt_prog_compiler_pic='-PIC' lt_prog_compiler_static='-Bstatic' ;; tcc*) # Fabrice Bellard et al's Tiny C Compiler lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fPIC' lt_prog_compiler_static='-static' ;; pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group compilers (*not* the Pentium gcc compiler, # which looks to be a dead project) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fpic' lt_prog_compiler_static='-Bstatic' ;; ccc*) lt_prog_compiler_wl='-Wl,' # All Alpha code is PIC. lt_prog_compiler_static='-non_shared' ;; xl* | bgxl* | bgf* | mpixl*) # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-qpic' lt_prog_compiler_static='-qstaticlink' ;; *) case `$CC -V 2>&1 | $SED 5q` in *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [1-7].* | *Sun*Fortran*\ 8.[0-3]*) # Sun Fortran 8.3 passes all unrecognized flags to the linker lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' lt_prog_compiler_wl='' ;; *Sun\ F* | *Sun*Fortran*) lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' lt_prog_compiler_wl='-Qoption ld ' ;; *Sun\ C*) # Sun C 5.9 lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' lt_prog_compiler_wl='-Wl,' ;; *Intel*\ [CF]*Compiler*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fPIC' lt_prog_compiler_static='-static' ;; *Portland\ Group*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fpic' lt_prog_compiler_static='-Bstatic' ;; esac ;; esac ;; newsos6) lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. lt_prog_compiler_pic='-fPIC -shared' ;; osf3* | osf4* | osf5*) lt_prog_compiler_wl='-Wl,' # All OSF/1 code is PIC. lt_prog_compiler_static='-non_shared' ;; rdos*) lt_prog_compiler_static='-non_shared' ;; solaris*) lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' case $cc_basename in f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) lt_prog_compiler_wl='-Qoption ld ';; *) lt_prog_compiler_wl='-Wl,';; esac ;; sunos4*) lt_prog_compiler_wl='-Qoption ld ' lt_prog_compiler_pic='-PIC' lt_prog_compiler_static='-Bstatic' ;; sysv4 | sysv4.2uw2* | sysv4.3*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' ;; sysv4*MP*) if test -d /usr/nec; then lt_prog_compiler_pic='-Kconform_pic' lt_prog_compiler_static='-Bstatic' fi ;; sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' ;; unicos*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_can_build_shared=no ;; uts4*) lt_prog_compiler_pic='-pic' lt_prog_compiler_static='-Bstatic' ;; *) lt_prog_compiler_can_build_shared=no ;; esac fi case $host_os in # For platforms that do not support PIC, -DPIC is meaningless: *djgpp*) lt_prog_compiler_pic= ;; *) lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC" ;; esac { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 printf %s "checking for $compiler option to produce PIC... " >&6; } if test ${lt_cv_prog_compiler_pic+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_prog_compiler_pic=$lt_prog_compiler_pic fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic" >&5 printf "%s\n" "$lt_cv_prog_compiler_pic" >&6; } lt_prog_compiler_pic=$lt_cv_prog_compiler_pic # # Check to make sure the PIC flag actually works. # if test -n "$lt_prog_compiler_pic"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5 printf %s "checking if $compiler PIC flag $lt_prog_compiler_pic works... " >&6; } if test ${lt_cv_prog_compiler_pic_works+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_prog_compiler_pic_works=no ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="$lt_prog_compiler_pic -DPIC" ## exclude from sc_useless_quotes_in_assignment # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_pic_works=yes fi fi $RM conftest* fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works" >&5 printf "%s\n" "$lt_cv_prog_compiler_pic_works" >&6; } if test yes = "$lt_cv_prog_compiler_pic_works"; then case $lt_prog_compiler_pic in "" | " "*) ;; *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;; esac else lt_prog_compiler_pic= lt_prog_compiler_can_build_shared=no fi fi # # Check to make sure the static flag actually works. # wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 printf %s "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } if test ${lt_cv_prog_compiler_static_works+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_prog_compiler_static_works=no save_LDFLAGS=$LDFLAGS LDFLAGS="$LDFLAGS $lt_tmp_static_flag" echo "$lt_simple_link_test_code" > conftest.$ac_ext if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then # The linker can only warn and ignore the option if not recognized # So say no if there are warnings if test -s conftest.err; then # Append any errors to the config.log. cat conftest.err 1>&5 $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_static_works=yes fi else lt_cv_prog_compiler_static_works=yes fi fi $RM -r conftest* LDFLAGS=$save_LDFLAGS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works" >&5 printf "%s\n" "$lt_cv_prog_compiler_static_works" >&6; } if test yes = "$lt_cv_prog_compiler_static_works"; then : else lt_prog_compiler_static= fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 printf %s "checking if $compiler supports -c -o file.$ac_objext... " >&6; } if test ${lt_cv_prog_compiler_c_o+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_prog_compiler_c_o=no $RM -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && 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 $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then lt_cv_prog_compiler_c_o=yes fi fi chmod u+w . 2>&5 $RM conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files $RM out/* && rmdir out cd .. $RM -r conftest $RM conftest* fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 printf "%s\n" "$lt_cv_prog_compiler_c_o" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 printf %s "checking if $compiler supports -c -o file.$ac_objext... " >&6; } if test ${lt_cv_prog_compiler_c_o+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_prog_compiler_c_o=no $RM -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && 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 $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then lt_cv_prog_compiler_c_o=yes fi fi chmod u+w . 2>&5 $RM conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files $RM out/* && rmdir out cd .. $RM -r conftest $RM conftest* fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 printf "%s\n" "$lt_cv_prog_compiler_c_o" >&6; } hard_links=nottested if test no = "$lt_cv_prog_compiler_c_o" && test no != "$need_locks"; then # do not overwrite the value of need_locks provided by the user { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5 printf %s "checking if we can lock with hard links... " >&6; } hard_links=yes $RM conftest* ln conftest.a conftest.b 2>/dev/null && hard_links=no touch conftest.a ln conftest.a conftest.b 2>&5 || hard_links=no ln conftest.a conftest.b 2>/dev/null && hard_links=no { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5 printf "%s\n" "$hard_links" >&6; } if test no = "$hard_links"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&5 printf "%s\n" "$as_me: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&2;} need_locks=warn fi else need_locks=no fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 printf %s "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } runpath_var= allow_undefined_flag= always_export_symbols=no archive_cmds= archive_expsym_cmds= compiler_needs_object=no enable_shared_with_static_runtimes=no export_dynamic_flag_spec= export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' hardcode_automatic=no hardcode_direct=no hardcode_direct_absolute=no hardcode_libdir_flag_spec= hardcode_libdir_separator= hardcode_minus_L=no hardcode_shlibpath_var=unsupported inherit_rpath=no link_all_deplibs=unknown module_cmds= module_expsym_cmds= old_archive_from_new_cmds= old_archive_from_expsyms_cmds= thread_safe_flag_spec= whole_archive_flag_spec= # include_expsyms should be a list of space-separated symbols to be *always* # included in the symbol list include_expsyms= # exclude_expsyms can be an extended regexp of symbols to exclude # it will be wrapped by ' (' and ')$', so one must not match beginning or # end of line. Example: 'a|bc|.*d.*' will exclude the symbols 'a' and 'bc', # as well as any symbol that contains 'd'. exclude_expsyms='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out # platforms (ab)use it in PIC code, but their linkers get confused if # the symbol is explicitly referenced. Since portable code cannot # rely on this symbol name, it's probably fine to never include it in # preloaded symbol tables. # Exclude shared library initialization/finalization symbols. extract_expsyms_cmds= case $host_os in cygwin* | mingw* | pw32* | cegcc*) # FIXME: the MSVC++ and ICC port hasn't been tested in a loooong time # When not using gcc, we currently assume that we are using # Microsoft Visual C++ or Intel C++ Compiler. if test yes != "$GCC"; then with_gnu_ld=no fi ;; interix*) # we just hope/assume this is gcc and not c89 (= MSVC++ or ICC) with_gnu_ld=yes ;; openbsd* | bitrig*) with_gnu_ld=no ;; esac ld_shlibs=yes # On some targets, GNU ld is compatible enough with the native linker # that we're better off using the native interface for both. lt_use_gnu_ld_interface=no if test yes = "$with_gnu_ld"; then case $host_os in aix*) # The AIX port of GNU ld has always aspired to compatibility # with the native linker. However, as the warning in the GNU ld # block says, versions before 2.19.5* couldn't really create working # shared libraries, regardless of the interface used. case `$LD -v 2>&1` in *\ \(GNU\ Binutils\)\ 2.19.5*) ;; *\ \(GNU\ Binutils\)\ 2.[2-9]*) ;; *\ \(GNU\ Binutils\)\ [3-9]*) ;; *) lt_use_gnu_ld_interface=yes ;; esac ;; *) lt_use_gnu_ld_interface=yes ;; esac fi if test yes = "$lt_use_gnu_ld_interface"; then # If archive_cmds runs LD, not CC, wlarc should be empty wlarc='$wl' # Set some defaults for GNU ld with shared library support. These # are reset later if shared libraries are not supported. Putting them # here allows them to be overridden if necessary. runpath_var=LD_RUN_PATH hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' export_dynamic_flag_spec='$wl--export-dynamic' # ancient GNU ld didn't support --whole-archive et. al. if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then whole_archive_flag_spec=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' else whole_archive_flag_spec= fi supports_anon_versioning=no case `$LD -v | $SED -e 's/([^)]\+)\s\+//' 2>&1` in *GNU\ gold*) supports_anon_versioning=yes ;; *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... *\ 2.11.*) ;; # other 2.11 versions *) supports_anon_versioning=yes ;; esac # See if GNU ld supports shared libraries. case $host_os in aix[3-9]*) # On AIX/PPC, the GNU linker is very broken if test ia64 != "$host_cpu"; then ld_shlibs=no cat <<_LT_EOF 1>&2 *** Warning: the GNU linker, at least up to release 2.19, is reported *** to be unable to reliably create shared libraries on AIX. *** Therefore, libtool is disabling shared libraries support. If you *** really care for shared libraries, you may want to install binutils *** 2.20 or above, or modify your PATH so that a non-GNU linker is found. *** You will then need to restart the configuration process. _LT_EOF fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds='' ;; m68k) archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes ;; esac ;; beos*) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then allow_undefined_flag=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' else ld_shlibs=no fi ;; cygwin* | mingw* | pw32* | cegcc*) # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless, # as there is no search path for DLLs. hardcode_libdir_flag_spec='-L$libdir' export_dynamic_flag_spec='$wl--export-all-symbols' allow_undefined_flag=unsupported always_export_symbols=no enable_shared_with_static_runtimes=yes export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols' exclude_expsyms='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname' if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file, use it as # is; otherwise, prepend EXPORTS... archive_expsym_cmds='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then cp $export_symbols $output_objdir/$soname.def; else echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else ld_shlibs=no fi ;; haiku*) archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' link_all_deplibs=yes ;; os2*) hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes allow_undefined_flag=unsupported shrext_cmds=.dll archive_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' archive_expsym_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ prefix_cmds="$SED"~ if test EXPORTS = "`$SED 1q $export_symbols`"; then prefix_cmds="$prefix_cmds -e 1d"; fi~ prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' old_archive_From_new_cmds='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' enable_shared_with_static_runtimes=yes file_list_spec='@' ;; interix[3-9]*) hardcode_direct=no hardcode_shlibpath_var=no hardcode_libdir_flag_spec='$wl-rpath,$libdir' export_dynamic_flag_spec='$wl-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' archive_expsym_cmds='$SED "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) tmp_diet=no if test linux-dietlibc = "$host_os"; then case $cc_basename in diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) esac fi if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ && test no = "$tmp_diet" then tmp_addflag=' $pic_flag' tmp_sharedflag='-shared' case $cc_basename,$host_cpu in pgcc*) # Portland Group C compiler whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' tmp_addflag=' $pic_flag' ;; pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group f77 and f90 compilers whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' tmp_addflag=' $pic_flag -Mnomain' ;; ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 tmp_addflag=' -i_dynamic' ;; efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 tmp_addflag=' -i_dynamic -nofor_main' ;; ifc* | ifort*) # Intel Fortran compiler tmp_addflag=' -nofor_main' ;; lf95*) # Lahey Fortran 8.1 whole_archive_flag_spec= tmp_sharedflag='--shared' ;; nagfor*) # NAGFOR 5.3 tmp_sharedflag='-Wl,-shared' ;; xl[cC]* | bgxl[cC]* | mpixl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below) tmp_sharedflag='-qmkshrobj' tmp_addflag= ;; nvcc*) # Cuda Compiler Driver 2.2 whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' compiler_needs_object=yes ;; esac case `$CC -V 2>&1 | $SED 5q` in *Sun\ C*) # Sun C 5.9 whole_archive_flag_spec='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' compiler_needs_object=yes tmp_sharedflag='-G' ;; *Sun\ F*) # Sun Fortran 8.3 tmp_sharedflag='-G' ;; esac archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' if test yes = "$supports_anon_versioning"; then archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' fi case $cc_basename in tcc*) export_dynamic_flag_spec='-rdynamic' ;; xlf* | bgf* | bgxlf* | mpixlf*) # IBM XL Fortran 10.1 on PPC cannot create shared libs itself whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive' hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' if test yes = "$supports_anon_versioning"; then archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' fi ;; esac else ld_shlibs=no fi ;; netbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' wlarc= else archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' fi ;; solaris*) if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then ld_shlibs=no cat <<_LT_EOF 1>&2 *** Warning: The releases 2.8.* of the GNU linker cannot reliably *** create shared libraries on Solaris systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.9.1 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' else ld_shlibs=no fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) case `$LD -v 2>&1` in *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) ld_shlibs=no cat <<_LT_EOF 1>&2 *** Warning: Releases of the GNU linker prior to 2.16.91.0.3 cannot *** reliably create shared libraries on SCO systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.16.91.0.3 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF ;; *) # For security reasons, it is highly recommended that you always # use absolute paths for naming shared libraries, and exclude the # DT_RUNPATH tag from executables and libraries. But doing so # requires that you compile everything twice, which is a pain. if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' else ld_shlibs=no fi ;; esac ;; sunos4*) archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' wlarc= hardcode_direct=yes hardcode_shlibpath_var=no ;; *) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' else ld_shlibs=no fi ;; esac if test no = "$ld_shlibs"; then runpath_var= hardcode_libdir_flag_spec= export_dynamic_flag_spec= whole_archive_flag_spec= fi else # PORTME fill in a description of your system's linker (not GNU ld) case $host_os in aix3*) allow_undefined_flag=unsupported always_export_symbols=yes archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' # Note: this linker hardcodes the directories in LIBPATH if there # are no directories specified by -L. hardcode_minus_L=yes if test yes = "$GCC" && test -z "$lt_prog_compiler_static"; then # Neither direct hardcoding nor static linking is supported with a # broken collect2. hardcode_direct=unsupported fi ;; aix[4-9]*) if test ia64 = "$host_cpu"; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' no_entry_flag= else # If we're using GNU nm, then we don't want the "-C" option. # -C means demangle to GNU nm, but means don't demangle to AIX nm. # Without the "-l" option, or with the "-B" option, AIX nm treats # weak defined symbols like other global defined symbols, whereas # GNU nm marks them as "W". # While the 'weak' keyword is ignored in the Export File, we need # it in the Import File for the 'aix-soname' feature, so we have # to replace the "-B" option with "-P" for AIX nm. if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols' else export_symbols_cmds='`func_echo_all $NM | $SED -e '\''s/B\([^B]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "L") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && (substr(\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' fi aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # have runtime linking enabled, and use it for executables. # For shared libraries, we enable/disable runtime linking # depending on the kind of the shared library created - # when "with_aix_soname,aix_use_runtimelinking" is: # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables # "aix,yes" lib.so shared, rtl:yes, for executables # lib.a static archive # "both,no" lib.so.V(shr.o) shared, rtl:yes # lib.a(lib.so.V) shared, rtl:no, for executables # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables # lib.a(lib.so.V) shared, rtl:no # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables # lib.a static archive case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) for ld_flag in $LDFLAGS; do if (test x-brtl = "x$ld_flag" || test x-Wl,-brtl = "x$ld_flag"); then aix_use_runtimelinking=yes break fi done if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then # With aix-soname=svr4, we create the lib.so.V shared archives only, # so we don't have lib.a shared libs to link our executables. # We have to force runtime linking in this case. aix_use_runtimelinking=yes LDFLAGS="$LDFLAGS -Wl,-brtl" fi ;; esac exp_sym_flag='-bexport' no_entry_flag='-bnoentry' fi # When large executables or shared objects are built, AIX ld can # have problems creating the table of contents. If linking a library # or program results in "error TOC overflow" add -mminimal-toc to # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. archive_cmds='' hardcode_direct=yes hardcode_direct_absolute=yes hardcode_libdir_separator=':' link_all_deplibs=yes file_list_spec='$wl-f,' case $with_aix_soname,$aix_use_runtimelinking in aix,*) ;; # traditional, no import file svr4,* | *,yes) # use import file # The Import File defines what to hardcode. hardcode_direct=no hardcode_direct_absolute=no ;; esac if test yes = "$GCC"; then case $host_os in aix4.[012]|aix4.[012].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ collect2name=`$CC -print-prog-name=collect2` if test -f "$collect2name" && strings "$collect2name" | $GREP resolve_lib_name >/dev/null then # We have reworked collect2 : else # We have old collect2 hardcode_direct=unsupported # It fails to find uninstalled libraries when the uninstalled # path is not listed in the libpath. Setting hardcode_minus_L # to unsupported forces relinking hardcode_minus_L=yes hardcode_libdir_flag_spec='-L$libdir' hardcode_libdir_separator= fi ;; esac shared_flag='-shared' if test yes = "$aix_use_runtimelinking"; then shared_flag="$shared_flag "'$wl-G' fi # Need to ensure runtime linking is disabled for the traditional # shared library, or the linker may eventually find shared libraries # /with/ Import File - we do not want to mix them. shared_flag_aix='-shared' shared_flag_svr4='-shared $wl-G' else # not using gcc if test ia64 = "$host_cpu"; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else if test yes = "$aix_use_runtimelinking"; then shared_flag='$wl-G' else shared_flag='$wl-bM:SRE' fi shared_flag_aix='$wl-bM:SRE' shared_flag_svr4='$wl-G' fi fi export_dynamic_flag_spec='$wl-bexpall' # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to export. always_export_symbols=yes if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. allow_undefined_flag='-berok' # Determine the default libpath from the value encoded in an # empty executable. if test set = "${lt_cv_aix_libpath+set}"; then aix_libpath=$lt_cv_aix_libpath else if test ${lt_cv_aix_libpath_+y} then : printf %s "(cached) " >&6 else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : lt_aix_libpath_sed=' /Import File Strings/,/^$/ { /^0/ { s/^0 *\([^ ]*\) *$/\1/ p } }' lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. if test -z "$lt_cv_aix_libpath_"; then lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext if test -z "$lt_cv_aix_libpath_"; then lt_cv_aix_libpath_=/usr/lib:/lib fi fi aix_libpath=$lt_cv_aix_libpath_ fi hardcode_libdir_flag_spec='$wl-blibpath:$libdir:'"$aix_libpath" archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag else if test ia64 = "$host_cpu"; then hardcode_libdir_flag_spec='$wl-R $libdir:/usr/lib:/lib' allow_undefined_flag="-z nodefs" archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an # empty executable. if test set = "${lt_cv_aix_libpath+set}"; then aix_libpath=$lt_cv_aix_libpath else if test ${lt_cv_aix_libpath_+y} then : printf %s "(cached) " >&6 else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : lt_aix_libpath_sed=' /Import File Strings/,/^$/ { /^0/ { s/^0 *\([^ ]*\) *$/\1/ p } }' lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. if test -z "$lt_cv_aix_libpath_"; then lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext if test -z "$lt_cv_aix_libpath_"; then lt_cv_aix_libpath_=/usr/lib:/lib fi fi aix_libpath=$lt_cv_aix_libpath_ fi hardcode_libdir_flag_spec='$wl-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. no_undefined_flag=' $wl-bernotok' allow_undefined_flag=' $wl-berok' if test yes = "$with_gnu_ld"; then # We only use this code for GNU lds that support --whole-archive. whole_archive_flag_spec='$wl--whole-archive$convenience $wl--no-whole-archive' else # Exported symbols can be pulled into shared objects from archives whole_archive_flag_spec='$convenience' fi archive_cmds_need_lc=yes archive_expsym_cmds='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d' # -brtl affects multiple linker settings, -berok does not and is overridden later compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([, ]\\)%-berok\\1%g"`' if test svr4 != "$with_aix_soname"; then # This is similar to how AIX traditionally builds its shared libraries. archive_expsym_cmds="$archive_expsym_cmds"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname' fi if test aix != "$with_aix_soname"; then archive_expsym_cmds="$archive_expsym_cmds"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp' else # used by -dlpreopen to get the symbols archive_expsym_cmds="$archive_expsym_cmds"'~$MV $output_objdir/$realname.d/$soname $output_objdir' fi archive_expsym_cmds="$archive_expsym_cmds"'~$RM -r $output_objdir/$realname.d' fi fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds='' ;; m68k) archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes ;; esac ;; bsdi[45]*) export_dynamic_flag_spec=-rdynamic ;; cygwin* | mingw* | pw32* | cegcc*) # When not using gcc, we currently assume that we are using # Microsoft Visual C++ or Intel C++ Compiler. # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. case $cc_basename in cl* | icl*) # Native MSVC or ICC hardcode_libdir_flag_spec=' ' allow_undefined_flag=unsupported always_export_symbols=yes file_list_spec='@' # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=.dll # FIXME: Setting linknames here is a bad hack. archive_cmds='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' archive_expsym_cmds='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then cp "$export_symbols" "$output_objdir/$soname.def"; echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; else $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp; fi~ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ linknames=' # The linker will not automatically build a static lib if we build a DLL. # _LT_TAGVAR(old_archive_from_new_cmds, )='true' enable_shared_with_static_runtimes=yes exclude_expsyms='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1,DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols' # Don't use ranlib old_postinstall_cmds='chmod 644 $oldlib' postlink_cmds='lt_outputfile="@OUTPUT@"~ lt_tool_outputfile="@TOOL_OUTPUT@"~ case $lt_outputfile in *.exe|*.EXE) ;; *) lt_outputfile=$lt_outputfile.exe lt_tool_outputfile=$lt_tool_outputfile.exe ;; esac~ if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; $RM "$lt_outputfile.manifest"; fi' ;; *) # Assume MSVC and ICC wrapper hardcode_libdir_flag_spec=' ' allow_undefined_flag=unsupported # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=.dll # FIXME: Setting linknames here is a bad hack. archive_cmds='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' # The linker will automatically build a .lib file if we build a DLL. old_archive_from_new_cmds='true' # FIXME: Should let the user specify the lib program. old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs' enable_shared_with_static_runtimes=yes ;; esac ;; darwin* | rhapsody*) archive_cmds_need_lc=no hardcode_direct=no hardcode_automatic=yes hardcode_shlibpath_var=unsupported if test yes = "$lt_cv_ld_force_load"; then whole_archive_flag_spec='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience $wl-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' else whole_archive_flag_spec='' fi link_all_deplibs=yes allow_undefined_flag=$_lt_dar_allow_undefined case $cc_basename in ifort*|nagfor*) _lt_dar_can_shared=yes ;; *) _lt_dar_can_shared=$GCC ;; esac if test yes = "$_lt_dar_can_shared"; then output_verbose_link_cmd=func_echo_all archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil" module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil" archive_expsym_cmds="$SED 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil" module_expsym_cmds="$SED -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil" else ld_shlibs=no fi ;; dgux*) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_libdir_flag_spec='-L$libdir' hardcode_shlibpath_var=no ;; # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor # support. Future versions do this automatically, but an explicit c++rt0.o # does not break anything, and helps significantly (at the cost of a little # extra space). freebsd2.2*) archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes hardcode_shlibpath_var=no ;; # Unfortunately, older versions of FreeBSD 2 do not have this feature. freebsd2.*) archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=yes hardcode_minus_L=yes hardcode_shlibpath_var=no ;; # FreeBSD 3 and greater uses gcc -shared to do shared libraries. freebsd* | dragonfly* | midnightbsd*) archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes hardcode_shlibpath_var=no ;; hpux9*) if test yes = "$GCC"; then archive_cmds='$RM $output_objdir/$soname~$CC -shared $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' else archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' fi hardcode_libdir_flag_spec='$wl+b $wl$libdir' hardcode_libdir_separator=: hardcode_direct=yes # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L=yes export_dynamic_flag_spec='$wl-E' ;; hpux10*) if test yes,no = "$GCC,$with_gnu_ld"; then archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' fi if test no = "$with_gnu_ld"; then hardcode_libdir_flag_spec='$wl+b $wl$libdir' hardcode_libdir_separator=: hardcode_direct=yes hardcode_direct_absolute=yes export_dynamic_flag_spec='$wl-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L=yes fi ;; hpux11*) if test yes,no = "$GCC,$with_gnu_ld"; then case $host_cpu in hppa*64*) archive_cmds='$CC -shared $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ;; esac else case $host_cpu in hppa*64*) archive_cmds='$CC -b $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) archive_cmds='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) # Older versions of the 11.00 compiler do not understand -b yet # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $CC understands -b" >&5 printf %s "checking if $CC understands -b... " >&6; } if test ${lt_cv_prog_compiler__b+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_prog_compiler__b=no save_LDFLAGS=$LDFLAGS LDFLAGS="$LDFLAGS -b" echo "$lt_simple_link_test_code" > conftest.$ac_ext if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then # The linker can only warn and ignore the option if not recognized # So say no if there are warnings if test -s conftest.err; then # Append any errors to the config.log. cat conftest.err 1>&5 $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler__b=yes fi else lt_cv_prog_compiler__b=yes fi fi $RM -r conftest* LDFLAGS=$save_LDFLAGS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler__b" >&5 printf "%s\n" "$lt_cv_prog_compiler__b" >&6; } if test yes = "$lt_cv_prog_compiler__b"; then archive_cmds='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' fi ;; esac fi if test no = "$with_gnu_ld"; then hardcode_libdir_flag_spec='$wl+b $wl$libdir' hardcode_libdir_separator=: case $host_cpu in hppa*64*|ia64*) hardcode_direct=no hardcode_shlibpath_var=no ;; *) hardcode_direct=yes hardcode_direct_absolute=yes export_dynamic_flag_spec='$wl-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L=yes ;; esac fi ;; irix5* | irix6* | nonstopux*) if test yes = "$GCC"; then archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' # Try to use the -exported_symbol ld option, if it does not # work, assume that -exports_file does not work either and # implicitly export all symbols. # This should be the same for all languages, so no per-tag cache variable. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the $host_os linker accepts -exported_symbol" >&5 printf %s "checking whether the $host_os linker accepts -exported_symbol... " >&6; } if test ${lt_cv_irix_exported_symbol+y} then : printf %s "(cached) " >&6 else $as_nop save_LDFLAGS=$LDFLAGS LDFLAGS="$LDFLAGS -shared $wl-exported_symbol ${wl}foo $wl-update_registry $wl/dev/null" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int foo (void) { return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : lt_cv_irix_exported_symbol=yes else $as_nop lt_cv_irix_exported_symbol=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LDFLAGS=$save_LDFLAGS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_irix_exported_symbol" >&5 printf "%s\n" "$lt_cv_irix_exported_symbol" >&6; } if test yes = "$lt_cv_irix_exported_symbol"; then archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations $wl-exports_file $wl$export_symbols -o $lib' fi else archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -exports_file $export_symbols -o $lib' fi archive_cmds_need_lc='no' hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' hardcode_libdir_separator=: inherit_rpath=yes link_all_deplibs=yes ;; linux*) case $cc_basename in tcc*) # Fabrice Bellard et al's Tiny C Compiler ld_shlibs=yes archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' ;; esac ;; netbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out else archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF fi hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes hardcode_shlibpath_var=no ;; newsos6) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=yes hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' hardcode_libdir_separator=: hardcode_shlibpath_var=no ;; *nto* | *qnx*) ;; openbsd* | bitrig*) if test -f /usr/libexec/ld.so; then hardcode_direct=yes hardcode_shlibpath_var=no hardcode_direct_absolute=yes if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags $wl-retain-symbols-file,$export_symbols' hardcode_libdir_flag_spec='$wl-rpath,$libdir' export_dynamic_flag_spec='$wl-E' else archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' hardcode_libdir_flag_spec='$wl-rpath,$libdir' fi else ld_shlibs=no fi ;; os2*) hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes allow_undefined_flag=unsupported shrext_cmds=.dll archive_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' archive_expsym_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ prefix_cmds="$SED"~ if test EXPORTS = "`$SED 1q $export_symbols`"; then prefix_cmds="$prefix_cmds -e 1d"; fi~ prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' old_archive_From_new_cmds='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' enable_shared_with_static_runtimes=yes file_list_spec='@' ;; osf3*) if test yes = "$GCC"; then allow_undefined_flag=' $wl-expect_unresolved $wl\*' archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' else allow_undefined_flag=' -expect_unresolved \*' archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' fi archive_cmds_need_lc='no' hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' hardcode_libdir_separator=: ;; osf4* | osf5*) # as osf3* with the addition of -msym flag if test yes = "$GCC"; then allow_undefined_flag=' $wl-expect_unresolved $wl\*' archive_cmds='$CC -shared$allow_undefined_flag $pic_flag $libobjs $deplibs $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' else allow_undefined_flag=' -expect_unresolved \*' archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ $CC -shared$allow_undefined_flag $wl-input $wl$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~$RM $lib.exp' # Both c and cxx compiler support -rpath directly hardcode_libdir_flag_spec='-rpath $libdir' fi archive_cmds_need_lc='no' hardcode_libdir_separator=: ;; solaris*) no_undefined_flag=' -z defs' if test yes = "$GCC"; then wlarc='$wl' archive_cmds='$CC -shared $pic_flag $wl-z ${wl}text $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -shared $pic_flag $wl-z ${wl}text $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' else case `$CC -V 2>&1` in *"Compilers 5.0"*) wlarc='' archive_cmds='$LD -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $linker_flags' archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $LD -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' ;; *) wlarc='$wl' archive_cmds='$CC -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' ;; esac fi hardcode_libdir_flag_spec='-R$libdir' hardcode_shlibpath_var=no case $host_os in solaris2.[0-5] | solaris2.[0-5].*) ;; *) # The compiler driver will combine and reorder linker options, # but understands '-z linker_flag'. GCC discards it without '$wl', # but is careful enough not to reorder. # Supported since Solaris 2.6 (maybe 2.5.1?) if test yes = "$GCC"; then whole_archive_flag_spec='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract' else whole_archive_flag_spec='-z allextract$convenience -z defaultextract' fi ;; esac link_all_deplibs=yes ;; sunos4*) if test sequent = "$host_vendor"; then # Use $CC to link under sequent, because it throws in some extra .o # files that make .init and .fini sections work. archive_cmds='$CC -G $wl-h $soname -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' fi hardcode_libdir_flag_spec='-L$libdir' hardcode_direct=yes hardcode_minus_L=yes hardcode_shlibpath_var=no ;; sysv4) 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 ;; sysv4.3*) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_shlibpath_var=no export_dynamic_flag_spec='-Bexport' ;; sysv4*MP*) if test -d /usr/nec; then archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_shlibpath_var=no runpath_var=LD_RUN_PATH hardcode_runpath_var=yes ld_shlibs=yes fi ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) no_undefined_flag='$wl-z,text' archive_cmds_need_lc=no hardcode_shlibpath_var=no runpath_var='LD_RUN_PATH' if test yes = "$GCC"; then archive_cmds='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; sysv5* | sco3.2v5* | sco5v6*) # Note: We CANNOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. no_undefined_flag='$wl-z,text' allow_undefined_flag='$wl-z,nodefs' archive_cmds_need_lc=no hardcode_shlibpath_var=no hardcode_libdir_flag_spec='$wl-R,$libdir' hardcode_libdir_separator=':' link_all_deplibs=yes export_dynamic_flag_spec='$wl-Bexport' runpath_var='LD_RUN_PATH' if test yes = "$GCC"; then archive_cmds='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; uts4*) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_libdir_flag_spec='-L$libdir' hardcode_shlibpath_var=no ;; *) ld_shlibs=no ;; esac if test sni = "$host_vendor"; then case $host in sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) export_dynamic_flag_spec='$wl-Blargedynsym' ;; esac fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs" >&5 printf "%s\n" "$ld_shlibs" >&6; } test no = "$ld_shlibs" && can_build_shared=no with_gnu_ld=$with_gnu_ld # # Do we need to explicitly link libc? # case "x$archive_cmds_need_lc" in x|xyes) # Assume -lc should be added archive_cmds_need_lc=yes if test yes,yes = "$GCC,$enable_shared"; then case $archive_cmds in *'~'*) # FIXME: we may have to deal with multi-command sequences. ;; '$CC '*) # Test whether the compiler implicitly links with -lc since on some # systems, -lgcc has to come before -lc. If gcc already passes -lc # to ld, don't add -lc before -lgcc. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 printf %s "checking whether -lc should be explicitly linked in... " >&6; } if test ${lt_cv_archive_cmds_need_lc+y} then : printf %s "(cached) " >&6 else $as_nop $RM conftest* echo "$lt_simple_compile_test_code" > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } 2>conftest.err; then soname=conftest lib=conftest libobjs=conftest.$ac_objext deplibs= wl=$lt_prog_compiler_wl pic_flag=$lt_prog_compiler_pic compiler_flags=-v linker_flags=-v verstring= output_objdir=. libname=conftest lt_save_allow_undefined_flag=$allow_undefined_flag allow_undefined_flag= if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 (eval $archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } then lt_cv_archive_cmds_need_lc=no else lt_cv_archive_cmds_need_lc=yes fi allow_undefined_flag=$lt_save_allow_undefined_flag else cat conftest.err 1>&5 fi $RM conftest* fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc" >&5 printf "%s\n" "$lt_cv_archive_cmds_need_lc" >&6; } archive_cmds_need_lc=$lt_cv_archive_cmds_need_lc ;; esac fi ;; esac { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5 printf %s "checking dynamic linker characteristics... " >&6; } if test yes = "$GCC"; then case $host_os in darwin*) lt_awk_arg='/^libraries:/,/LR/' ;; *) lt_awk_arg='/^libraries:/' ;; esac case $host_os in mingw* | cegcc*) lt_sed_strip_eq='s|=\([A-Za-z]:\)|\1|g' ;; *) lt_sed_strip_eq='s|=/|/|g' ;; esac lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` case $lt_search_path_spec in *\;*) # if the path contains ";" then we assume it to be the separator # otherwise default to the standard path separator (i.e. ":") - it is # assumed that no part of a normal pathname contains ";" but that should # okay in the real world where ";" in dirpaths is itself problematic. lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` ;; *) lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` ;; esac # Ok, now we have the path, separated by spaces, we can step through it # and add multilib dir if necessary... lt_tmp_lt_search_path_spec= lt_multi_os_dir=/`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` # ...but if some path component already ends with the multilib dir we assume # that all is fine and trust -print-search-dirs as is (GCC 4.2? or newer). case "$lt_multi_os_dir; $lt_search_path_spec " in "/; "* | "/.; "* | "/./; "* | *"$lt_multi_os_dir "* | *"$lt_multi_os_dir/ "*) lt_multi_os_dir= ;; esac for lt_sys_path in $lt_search_path_spec; do if test -d "$lt_sys_path$lt_multi_os_dir"; then lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path$lt_multi_os_dir" elif test -n "$lt_multi_os_dir"; then test -d "$lt_sys_path" && \ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" fi done lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' BEGIN {RS = " "; FS = "/|\n";} { lt_foo = ""; lt_count = 0; for (lt_i = NF; lt_i > 0; lt_i--) { if ($lt_i != "" && $lt_i != ".") { if ($lt_i == "..") { lt_count++; } else { if (lt_count == 0) { lt_foo = "/" $lt_i lt_foo; } else { lt_count--; } } } } if (lt_foo != "") { lt_freq[lt_foo]++; } if (lt_freq[lt_foo] == 1) { print lt_foo; } }'` # AWK program above erroneously prepends '/' to C:/dos/paths # for these hosts. case $host_os in mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ $SED 's|/\([A-Za-z]:\)|\1|g'` ;; esac sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` else sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" fi library_names_spec= libname_spec='lib$name' soname_spec= shrext_cmds=.so postinstall_cmds= postuninstall_cmds= finish_cmds= finish_eval= shlibpath_var= shlibpath_overrides_runpath=unknown version_type=none dynamic_linker="$host_os ld.so" sys_lib_dlsearch_path_spec="/lib /usr/lib" need_lib_prefix=unknown hardcode_into_libs=no # when you set need_version to no, make sure it does not cause -set_version # flags to be left without arguments need_version=unknown case $host_os in aix3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname.a' shlibpath_var=LIBPATH # AIX 3 has no versioning support, so we append a major version to the name. soname_spec='$libname$release$shared_ext$major' ;; aix[4-9]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no hardcode_into_libs=yes if test ia64 = "$host_cpu"; then # AIX 5 supports IA64 library_names_spec='$libname$release$shared_ext$major $libname$release$shared_ext$versuffix $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH else # With GCC up to 2.95.x, collect2 would create an import file # for dependence libraries. The import file would start with # the line '#! .'. This would cause the generated library to # depend on '.', always an invalid library. This was fixed in # development snapshots of GCC prior to 3.0. case $host_os in aix4 | aix4.[01] | aix4.[01].*) if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' echo ' yes ' echo '#endif'; } | $CC -E - | $GREP yes > /dev/null; then : else can_build_shared=no fi ;; esac # Using Import Files as archive members, it is possible to support # filename-based versioning of shared library archives on AIX. While # this would work for both with and without runtime linking, it will # prevent static linking of such archives. So we do filename-based # shared library versioning with .so extension only, which is used # when both runtime linking and shared linking is enabled. # Unfortunately, runtime linking may impact performance, so we do # not want this to be the default eventually. Also, we use the # versioned .so libs for executables only if there is the -brtl # linker flag in LDFLAGS as well, or --with-aix-soname=svr4 only. # To allow for filename-based versioning support, we need to create # libNAME.so.V as an archive file, containing: # *) an Import File, referring to the versioned filename of the # archive as well as the shared archive member, telling the # bitwidth (32 or 64) of that shared object, and providing the # list of exported symbols of that shared object, eventually # decorated with the 'weak' keyword # *) the shared object with the F_LOADONLY flag set, to really avoid # it being seen by the linker. # At run time we better use the real file rather than another symlink, # but for link time we create the symlink libNAME.so -> libNAME.so.V case $with_aix_soname,$aix_use_runtimelinking in # AIX (on Power*) has no versioning support, so currently we cannot hardcode correct # soname into executable. Probably we can add versioning support to # collect2, so additional links can be useful in future. aix,yes) # traditional libtool dynamic_linker='AIX unversionable lib.so' # If using run time linking (on AIX 4.2 or later) use lib.so # instead of lib.a to let people know that these are not # typical AIX shared libraries. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' ;; aix,no) # traditional AIX only dynamic_linker='AIX lib.a(lib.so.V)' # We preserve .a as extension for shared libraries through AIX4.2 # and later when we are not doing run time linking. library_names_spec='$libname$release.a $libname.a' soname_spec='$libname$release$shared_ext$major' ;; svr4,*) # full svr4 only dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o)" library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' # We do not specify a path in Import Files, so LIBPATH fires. shlibpath_overrides_runpath=yes ;; *,yes) # both, prefer svr4 dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o), lib.a(lib.so.V)" library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' # unpreferred sharedlib libNAME.a needs extra handling postinstall_cmds='test -n "$linkname" || linkname="$realname"~func_stripname "" ".so" "$linkname"~$install_shared_prog "$dir/$func_stripname_result.$libext" "$destdir/$func_stripname_result.$libext"~test -z "$tstripme" || test -z "$striplib" || $striplib "$destdir/$func_stripname_result.$libext"' postuninstall_cmds='for n in $library_names $old_library; do :; done~func_stripname "" ".so" "$n"~test "$func_stripname_result" = "$n" || func_append rmfiles " $odir/$func_stripname_result.$libext"' # We do not specify a path in Import Files, so LIBPATH fires. shlibpath_overrides_runpath=yes ;; *,no) # both, prefer aix dynamic_linker="AIX lib.a(lib.so.V), lib.so.V($shared_archive_member_spec.o)" library_names_spec='$libname$release.a $libname.a' soname_spec='$libname$release$shared_ext$major' # unpreferred sharedlib libNAME.so.V and symlink libNAME.so need extra handling postinstall_cmds='test -z "$dlname" || $install_shared_prog $dir/$dlname $destdir/$dlname~test -z "$tstripme" || test -z "$striplib" || $striplib $destdir/$dlname~test -n "$linkname" || linkname=$realname~func_stripname "" ".a" "$linkname"~(cd "$destdir" && $LN_S -f $dlname $func_stripname_result.so)' postuninstall_cmds='test -z "$dlname" || func_append rmfiles " $odir/$dlname"~for n in $old_library $library_names; do :; done~func_stripname "" ".a" "$n"~func_append rmfiles " $odir/$func_stripname_result.so"' ;; esac shlibpath_var=LIBPATH fi ;; amigaos*) case $host_cpu in powerpc) # Since July 2007 AmigaOS4 officially supports .so libraries. # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' ;; m68k) library_names_spec='$libname.ixlibrary $libname.a' # Create ${libname}_ixlibrary.a entries in /sys/libs. finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' ;; esac ;; beos*) library_names_spec='$libname$shared_ext' dynamic_linker="$host_os ld.so" shlibpath_var=LIBRARY_PATH ;; bsdi[45]*) version_type=linux # correct to gnu/linux during the next big refactor need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" # the default ld.so.conf also contains /usr/contrib/lib and # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow # libtool to hard-code these into programs ;; cygwin* | mingw* | pw32* | cegcc*) version_type=windows shrext_cmds=.dll need_version=no need_lib_prefix=no case $GCC,$cc_basename in yes,*) # gcc library_names_spec='$libname.dll.a' # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \$file`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ chmod a+x \$dldir/$dlname~ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; fi' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes case $host_os in cygwin*) # Cygwin DLLs use 'cyg' prefix rather than 'lib' soname_spec='`echo $libname | $SED -e 's/^lib/cyg/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api" ;; mingw* | cegcc*) # MinGW DLLs use traditional 'lib' prefix soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' ;; pw32*) # pw32 DLLs use 'pw' prefix rather than 'lib' library_names_spec='`echo $libname | $SED -e 's/^lib/pw/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' ;; esac dynamic_linker='Win32 ld.exe' ;; *,cl* | *,icl*) # Native MSVC or ICC libname_spec='$name' soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' library_names_spec='$libname.dll.lib' case $build_os in mingw*) sys_lib_search_path_spec= lt_save_ifs=$IFS IFS=';' for lt_path in $LIB do IFS=$lt_save_ifs # Let DOS variable expansion print the short 8.3 style file name. lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" done IFS=$lt_save_ifs # Convert to MSYS style. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'` ;; cygwin*) # Convert to unix form, then to dos form, then back to unix form # but this time dos style (no spaces!) so that the unix form looks # like /cygdrive/c/PROGRA~1:/cygdr... sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` ;; *) sys_lib_search_path_spec=$LIB if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then # It is most probably a Windows format PATH. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` else sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` fi # FIXME: find the short name or the path components, as spaces are # common. (e.g. "Program Files" -> "PROGRA~1") ;; esac # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \$file`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes dynamic_linker='Win32 link.exe' ;; *) # Assume MSVC and ICC wrapper library_names_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext $libname.lib' dynamic_linker='Win32 ld.exe' ;; esac # FIXME: first we should search . and the directory the executable is in shlibpath_var=PATH ;; darwin* | rhapsody*) dynamic_linker="$host_os dyld" version_type=darwin need_lib_prefix=no need_version=no library_names_spec='$libname$release$major$shared_ext $libname$shared_ext' soname_spec='$libname$release$major$shared_ext' shlibpath_overrides_runpath=yes shlibpath_var=DYLD_LIBRARY_PATH shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib" sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' ;; dgux*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH ;; freebsd* | dragonfly* | midnightbsd*) # DragonFly does not have aout. When/if they implement a new # versioning mechanism, adjust this. if test -x /usr/bin/objformat; then objformat=`/usr/bin/objformat` else case $host_os in freebsd[23].*) objformat=aout ;; *) objformat=elf ;; esac fi version_type=freebsd-$objformat case $version_type in freebsd-elf*) library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' need_version=no need_lib_prefix=no ;; freebsd-*) library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' need_version=yes ;; esac shlibpath_var=LD_LIBRARY_PATH case $host_os in freebsd2.*) shlibpath_overrides_runpath=yes ;; freebsd3.[01]* | freebsdelf3.[01]*) shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; *) # from 4.6 on, and DragonFly shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; esac ;; haiku*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no dynamic_linker="$host_os runtime_loader" library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LIBRARY_PATH shlibpath_overrides_runpath=no sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' hardcode_into_libs=yes ;; hpux9* | hpux10* | hpux11*) # Give a soname corresponding to the major version so that dld.sl refuses to # link against other versions. version_type=sunos need_lib_prefix=no need_version=no case $host_cpu in ia64*) shrext_cmds='.so' hardcode_into_libs=yes dynamic_linker="$host_os dld.so" shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' if test 32 = "$HPUX_IA64_MODE"; then sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" sys_lib_dlsearch_path_spec=/usr/lib/hpux32 else sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" sys_lib_dlsearch_path_spec=/usr/lib/hpux64 fi ;; hppa*64*) shrext_cmds='.sl' hardcode_into_libs=yes dynamic_linker="$host_os dld.sl" shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; *) shrext_cmds='.sl' dynamic_linker="$host_os dld.sl" shlibpath_var=SHLIB_PATH shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' ;; esac # HP-UX runs *really* slowly unless shared libraries are mode 555, ... postinstall_cmds='chmod 555 $lib' # or fails outright, so override atomically: install_override_mode=555 ;; interix[3-9]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; irix5* | irix6* | nonstopux*) case $host_os in nonstopux*) version_type=nonstopux ;; *) if test yes = "$lt_cv_prog_gnu_ld"; then version_type=linux # correct to gnu/linux during the next big refactor else version_type=irix fi ;; esac need_lib_prefix=no need_version=no soname_spec='$libname$release$shared_ext$major' library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$release$shared_ext $libname$shared_ext' case $host_os in irix5* | nonstopux*) libsuff= shlibsuff= ;; *) case $LD in # libtool.m4 will add one of these switches to LD *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= libmagic=32-bit;; *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 libmagic=N32;; *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 libmagic=64-bit;; *) libsuff= shlibsuff= libmagic=never-match;; esac ;; esac shlibpath_var=LD_LIBRARY${shlibsuff}_PATH shlibpath_overrides_runpath=no sys_lib_search_path_spec="/usr/lib$libsuff /lib$libsuff /usr/local/lib$libsuff" sys_lib_dlsearch_path_spec="/usr/lib$libsuff /lib$libsuff" hardcode_into_libs=yes ;; # No shared lib support for Linux oldld, aout, or coff. linux*oldld* | linux*aout* | linux*coff*) dynamic_linker=no ;; linux*android*) version_type=none # Android doesn't support versioned libraries. need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext' soname_spec='$libname$release$shared_ext' finish_cmds= shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # This implies no fast_install, which is unacceptable. # Some rework will be needed to allow for fast_install # before this can be enabled. hardcode_into_libs=yes dynamic_linker='Android linker' # Don't embed -rpath directories since the linker doesn't support them. hardcode_libdir_flag_spec='-L$libdir' ;; # This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no # Some binutils ld are patched to set DT_RUNPATH if test ${lt_cv_shlibpath_overrides_runpath+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_shlibpath_overrides_runpath=no save_LDFLAGS=$LDFLAGS save_libdir=$libdir eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \ LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\"" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null then : lt_cv_shlibpath_overrides_runpath=yes fi fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LDFLAGS=$save_LDFLAGS libdir=$save_libdir fi shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath # This implies no fast_install, which is unacceptable. # Some rework will be needed to allow for fast_install # before this can be enabled. hardcode_into_libs=yes # Add ABI-specific directories to the system library path. sys_lib_dlsearch_path_spec="/lib64 /usr/lib64 /lib /usr/lib" # Ideally, we could use ldconfig to report *all* directores which are # searched for libraries, however this is still not possible. Aside from not # being certain /sbin/ldconfig is available, command # 'ldconfig -N -X -v | grep ^/' on 64bit Fedora does not report /usr/lib64, # even though it is searched at run-time. Try to do the best guess by # appending ld.so.conf contents (and includes) to the search path. if test -f /etc/ld.so.conf; then lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` sys_lib_dlsearch_path_spec="$sys_lib_dlsearch_path_spec $lt_ld_extra" fi # We used to test for /lib/ld.so.1 and disable shared libraries on # powerpc, because MkLinux only supported shared libraries with the # GNU dynamic linker. Since this was broken with cross compilers, # most powerpc-linux boxes support dynamic linking these days and # 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' ;; netbsd*) version_type=sunos need_lib_prefix=no need_version=no if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' dynamic_linker='NetBSD (a.out) ld.so' else library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' dynamic_linker='NetBSD ld.elf_so' fi shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; newsos6) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; *nto* | *qnx*) version_type=qnx need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='ldqnx.so' ;; openbsd* | bitrig*) version_type=sunos sys_lib_dlsearch_path_spec=/usr/lib need_lib_prefix=no if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then need_version=no else need_version=yes fi library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; os2*) libname_spec='$name' version_type=windows shrext_cmds=.dll need_version=no need_lib_prefix=no # OS/2 can only load a DLL with a base name of 8 characters or less. soname_spec='`test -n "$os2dllname" && libname="$os2dllname"; v=$($ECHO $release$versuffix | tr -d .-); n=$($ECHO $libname | cut -b -$((8 - ${#v})) | tr . _); $ECHO $n$v`$shared_ext' library_names_spec='${libname}_dll.$libext' dynamic_linker='OS/2 ld.exe' shlibpath_var=BEGINLIBPATH sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec postinstall_cmds='base_file=`basename \$file`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; $ECHO \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ chmod a+x \$dldir/$dlname~ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; fi' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; $ECHO \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' ;; osf3* | osf4* | osf5*) version_type=osf need_lib_prefix=no need_version=no soname_spec='$libname$release$shared_ext$major' library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' 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 ;; rdos*) dynamic_linker=no ;; solaris*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes # ldd complains unless libraries are executable postinstall_cmds='chmod +x $lib' ;; sunos4*) version_type=sunos library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes if test yes = "$with_gnu_ld"; then need_lib_prefix=no fi need_version=yes ;; sysv4 | sysv4.3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH case $host_vendor in sni) shlibpath_overrides_runpath=no need_lib_prefix=no runpath_var=LD_RUN_PATH ;; siemens) need_lib_prefix=no ;; motorola) need_lib_prefix=no need_version=no shlibpath_overrides_runpath=no sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' ;; esac ;; sysv4*MP*) if test -d /usr/nec; then version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$shared_ext.$versuffix $libname$shared_ext.$major $libname$shared_ext' soname_spec='$libname$shared_ext.$major' shlibpath_var=LD_LIBRARY_PATH fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) version_type=sco need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes if test yes = "$with_gnu_ld"; then sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' else sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' case $host_os in sco3.2v5*) sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" ;; esac fi sys_lib_dlsearch_path_spec='/usr/lib' ;; tpf*) # TPF is a cross-target only. Preferred cross-host = GNU/Linux. version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; uts4*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH ;; *) dynamic_linker=no ;; esac { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 printf "%s\n" "$dynamic_linker" >&6; } test no = "$dynamic_linker" && can_build_shared=no variables_saved_for_relink="PATH $shlibpath_var $runpath_var" if test yes = "$GCC"; then variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" fi if test set = "${lt_cv_sys_lib_search_path_spec+set}"; then sys_lib_search_path_spec=$lt_cv_sys_lib_search_path_spec fi if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec fi # remember unaugmented sys_lib_dlsearch_path content for libtool script decls... configure_time_dlsearch_path=$sys_lib_dlsearch_path_spec # ... but it needs LT_SYS_LIBRARY_PATH munging for other configure-time code func_munge_path_list sys_lib_dlsearch_path_spec "$LT_SYS_LIBRARY_PATH" # to be used as default LT_SYS_LIBRARY_PATH value in generated libtool configure_time_lt_sys_library_path=$LT_SYS_LIBRARY_PATH { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 printf %s "checking how to hardcode library paths into programs... " >&6; } hardcode_action= if test -n "$hardcode_libdir_flag_spec" || test -n "$runpath_var" || test yes = "$hardcode_automatic"; then # We can hardcode non-existent directories. if test no != "$hardcode_direct" && # If the only mechanism to avoid hardcoding is shlibpath_var, we # have to relink, otherwise we might link with an installed library # when we should be linking with a yet-to-be-installed one ## test no != "$_LT_TAGVAR(hardcode_shlibpath_var, )" && test no != "$hardcode_minus_L"; then # Linking always hardcodes the temporary library directory. hardcode_action=relink else # We can link without hardcoding, and we can hardcode nonexisting dirs. hardcode_action=immediate fi else # We cannot hardcode anything, or else we can only hardcode existing # directories. hardcode_action=unsupported fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $hardcode_action" >&5 printf "%s\n" "$hardcode_action" >&6; } if test relink = "$hardcode_action" || test yes = "$inherit_rpath"; then # Fast installation is not supported enable_fast_install=no elif test yes = "$shlibpath_overrides_runpath" || test no = "$enable_shared"; then # Fast installation is not necessary enable_fast_install=needless fi if test yes != "$enable_dlopen"; then enable_dlopen=unknown enable_dlopen_self=unknown enable_dlopen_self_static=unknown else lt_cv_dlopen=no lt_cv_dlopen_libs= case $host_os in beos*) lt_cv_dlopen=load_add_on lt_cv_dlopen_libs= lt_cv_dlopen_self=yes ;; mingw* | pw32* | cegcc*) lt_cv_dlopen=LoadLibrary lt_cv_dlopen_libs= ;; cygwin*) lt_cv_dlopen=dlopen lt_cv_dlopen_libs= ;; darwin*) # if libdl is installed we need to link against it { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 printf %s "checking for dlopen in -ldl... " >&6; } if test ${ac_cv_lib_dl_dlopen+y} then : printf %s "(cached) " >&6 else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-ldl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ char dlopen (); int main (void) { return dlopen (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : ac_cv_lib_dl_dlopen=yes else $as_nop ac_cv_lib_dl_dlopen=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 printf "%s\n" "$ac_cv_lib_dl_dlopen" >&6; } if test "x$ac_cv_lib_dl_dlopen" = xyes then : lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl else $as_nop lt_cv_dlopen=dyld lt_cv_dlopen_libs= lt_cv_dlopen_self=yes fi ;; tpf*) # Don't try to run any link tests for TPF. We know it's impossible # because TPF is a cross-compiler, and we know how we open DSOs. lt_cv_dlopen=dlopen lt_cv_dlopen_libs= lt_cv_dlopen_self=no ;; *) ac_fn_c_check_func "$LINENO" "shl_load" "ac_cv_func_shl_load" if test "x$ac_cv_func_shl_load" = xyes then : lt_cv_dlopen=shl_load else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5 printf %s "checking for shl_load in -ldld... " >&6; } if test ${ac_cv_lib_dld_shl_load+y} then : printf %s "(cached) " >&6 else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-ldld $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ char shl_load (); int main (void) { return shl_load (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : ac_cv_lib_dld_shl_load=yes else $as_nop ac_cv_lib_dld_shl_load=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5 printf "%s\n" "$ac_cv_lib_dld_shl_load" >&6; } if test "x$ac_cv_lib_dld_shl_load" = xyes then : lt_cv_dlopen=shl_load lt_cv_dlopen_libs=-ldld else $as_nop ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen" if test "x$ac_cv_func_dlopen" = xyes then : lt_cv_dlopen=dlopen else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 printf %s "checking for dlopen in -ldl... " >&6; } if test ${ac_cv_lib_dl_dlopen+y} then : printf %s "(cached) " >&6 else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-ldl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ char dlopen (); int main (void) { return dlopen (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : ac_cv_lib_dl_dlopen=yes else $as_nop ac_cv_lib_dl_dlopen=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 printf "%s\n" "$ac_cv_lib_dl_dlopen" >&6; } if test "x$ac_cv_lib_dl_dlopen" = xyes then : lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld" >&5 printf %s "checking for dlopen in -lsvld... " >&6; } if test ${ac_cv_lib_svld_dlopen+y} then : printf %s "(cached) " >&6 else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-lsvld $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ char dlopen (); int main (void) { return dlopen (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : ac_cv_lib_svld_dlopen=yes else $as_nop ac_cv_lib_svld_dlopen=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svld_dlopen" >&5 printf "%s\n" "$ac_cv_lib_svld_dlopen" >&6; } if test "x$ac_cv_lib_svld_dlopen" = xyes then : lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-lsvld else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld" >&5 printf %s "checking for dld_link in -ldld... " >&6; } if test ${ac_cv_lib_dld_dld_link+y} then : printf %s "(cached) " >&6 else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-ldld $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ char dld_link (); int main (void) { return dld_link (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : ac_cv_lib_dld_dld_link=yes else $as_nop ac_cv_lib_dld_dld_link=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_dld_link" >&5 printf "%s\n" "$ac_cv_lib_dld_dld_link" >&6; } if test "x$ac_cv_lib_dld_dld_link" = xyes then : lt_cv_dlopen=dld_link lt_cv_dlopen_libs=-ldld fi fi fi fi fi fi ;; esac if test no = "$lt_cv_dlopen"; then enable_dlopen=no else enable_dlopen=yes fi case $lt_cv_dlopen in dlopen) save_CPPFLAGS=$CPPFLAGS test yes = "$ac_cv_header_dlfcn_h" && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" save_LDFLAGS=$LDFLAGS wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" save_LIBS=$LIBS LIBS="$lt_cv_dlopen_libs $LIBS" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether a program can dlopen itself" >&5 printf %s "checking whether a program can dlopen itself... " >&6; } if test ${lt_cv_dlopen_self+y} then : printf %s "(cached) " >&6 else $as_nop if test yes = "$cross_compiling"; then : lt_cv_dlopen_self=cross else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF #line $LINENO "configure" #include "confdefs.h" #if HAVE_DLFCN_H #include #endif #include #ifdef RTLD_GLOBAL # define LT_DLGLOBAL RTLD_GLOBAL #else # ifdef DL_GLOBAL # define LT_DLGLOBAL DL_GLOBAL # else # define LT_DLGLOBAL 0 # endif #endif /* We may have to define LT_DLLAZY_OR_NOW in the command line if we find out it does not work in some platform. */ #ifndef LT_DLLAZY_OR_NOW # ifdef RTLD_LAZY # define LT_DLLAZY_OR_NOW RTLD_LAZY # else # ifdef DL_LAZY # define LT_DLLAZY_OR_NOW DL_LAZY # else # ifdef RTLD_NOW # define LT_DLLAZY_OR_NOW RTLD_NOW # else # ifdef DL_NOW # define LT_DLLAZY_OR_NOW DL_NOW # else # define LT_DLLAZY_OR_NOW 0 # endif # endif # endif # endif #endif /* When -fvisibility=hidden is used, assume the code has been annotated correspondingly for the symbols needed. */ #if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) int fnord () __attribute__((visibility("default"))); #endif int fnord () { return 42; } int main () { void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); int status = $lt_dlunknown; if (self) { if (dlsym (self,"fnord")) status = $lt_dlno_uscore; else { if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; else puts (dlerror ()); } /* dlclose (self); */ } else puts (dlerror ()); return status; } _LT_EOF if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 (eval $ac_link) 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -s "conftest$ac_exeext" 2>/dev/null; then (./conftest; exit; ) >&5 2>/dev/null lt_status=$? case x$lt_status in x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;; x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;; x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;; esac else : # compilation failed lt_cv_dlopen_self=no fi fi rm -fr conftest* fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self" >&5 printf "%s\n" "$lt_cv_dlopen_self" >&6; } if test yes = "$lt_cv_dlopen_self"; then wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether a statically linked program can dlopen itself" >&5 printf %s "checking whether a statically linked program can dlopen itself... " >&6; } if test ${lt_cv_dlopen_self_static+y} then : printf %s "(cached) " >&6 else $as_nop if test yes = "$cross_compiling"; then : lt_cv_dlopen_self_static=cross else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF #line $LINENO "configure" #include "confdefs.h" #if HAVE_DLFCN_H #include #endif #include #ifdef RTLD_GLOBAL # define LT_DLGLOBAL RTLD_GLOBAL #else # ifdef DL_GLOBAL # define LT_DLGLOBAL DL_GLOBAL # else # define LT_DLGLOBAL 0 # endif #endif /* We may have to define LT_DLLAZY_OR_NOW in the command line if we find out it does not work in some platform. */ #ifndef LT_DLLAZY_OR_NOW # ifdef RTLD_LAZY # define LT_DLLAZY_OR_NOW RTLD_LAZY # else # ifdef DL_LAZY # define LT_DLLAZY_OR_NOW DL_LAZY # else # ifdef RTLD_NOW # define LT_DLLAZY_OR_NOW RTLD_NOW # else # ifdef DL_NOW # define LT_DLLAZY_OR_NOW DL_NOW # else # define LT_DLLAZY_OR_NOW 0 # endif # endif # endif # endif #endif /* When -fvisibility=hidden is used, assume the code has been annotated correspondingly for the symbols needed. */ #if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) int fnord () __attribute__((visibility("default"))); #endif int fnord () { return 42; } int main () { void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); int status = $lt_dlunknown; if (self) { if (dlsym (self,"fnord")) status = $lt_dlno_uscore; else { if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; else puts (dlerror ()); } /* dlclose (self); */ } else puts (dlerror ()); return status; } _LT_EOF if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 (eval $ac_link) 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -s "conftest$ac_exeext" 2>/dev/null; then (./conftest; exit; ) >&5 2>/dev/null lt_status=$? case x$lt_status in x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;; x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;; x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;; esac else : # compilation failed lt_cv_dlopen_self_static=no fi fi rm -fr conftest* fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self_static" >&5 printf "%s\n" "$lt_cv_dlopen_self_static" >&6; } fi CPPFLAGS=$save_CPPFLAGS LDFLAGS=$save_LDFLAGS LIBS=$save_LIBS ;; esac case $lt_cv_dlopen_self in yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; *) enable_dlopen_self=unknown ;; esac case $lt_cv_dlopen_self_static in yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; *) enable_dlopen_self_static=unknown ;; esac fi striplib= old_striplib= { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether stripping libraries is possible" >&5 printf %s "checking whether stripping libraries is possible... " >&6; } if test -z "$STRIP"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } else if $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then old_striplib="$STRIP --strip-debug" striplib="$STRIP --strip-unneeded" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } else case $host_os in darwin*) # FIXME - insert some real tests, host_os isn't really good enough striplib="$STRIP -x" old_striplib="$STRIP -S" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } ;; freebsd*) if $STRIP -V 2>&1 | $GREP "elftoolchain" >/dev/null; then old_striplib="$STRIP --strip-debug" striplib="$STRIP --strip-unneeded" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi ;; *) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } ;; esac fi fi # Report what library types will actually be built { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if libtool supports shared libraries" >&5 printf %s "checking if libtool supports shared libraries... " >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $can_build_shared" >&5 printf "%s\n" "$can_build_shared" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to build shared libraries" >&5 printf %s "checking whether to build shared libraries... " >&6; } test no = "$can_build_shared" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test yes = "$enable_shared" && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[4-9]*) if test ia64 != "$host_cpu"; then case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in yes,aix,yes) ;; # shared object as lib.so file only yes,svr4,*) ;; # shared object as lib.so archive member only yes,*) enable_static=no ;; # shared object in lib.a archive as well esac fi ;; esac { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_shared" >&5 printf "%s\n" "$enable_shared" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to build static libraries" >&5 printf %s "checking whether to build static libraries... " >&6; } # Make sure either enable_shared or enable_static is yes. test yes = "$enable_shared" || enable_static=yes { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_static" >&5 printf "%s\n" "$enable_static" >&6; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu CC=$lt_save_CC ac_config_commands="$ac_config_commands libtool" # Only expand once: if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args. set dummy ${ac_tool_prefix}pkg-config; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_path_PKG_CONFIG+y} then : printf %s "(cached) " >&6 else $as_nop case $PKG_CONFIG in [\\/]* | ?:[\\/]*) ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_path_PKG_CONFIG="$as_dir$ac_word$ac_exec_ext" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi PKG_CONFIG=$ac_cv_path_PKG_CONFIG if test -n "$PKG_CONFIG"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5 printf "%s\n" "$PKG_CONFIG" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_path_PKG_CONFIG"; then ac_pt_PKG_CONFIG=$PKG_CONFIG # Extract the first word of "pkg-config", so it can be a program name with args. set dummy pkg-config; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_path_ac_pt_PKG_CONFIG+y} then : printf %s "(cached) " >&6 else $as_nop case $ac_pt_PKG_CONFIG in [\\/]* | ?:[\\/]*) ac_cv_path_ac_pt_PKG_CONFIG="$ac_pt_PKG_CONFIG" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_path_ac_pt_PKG_CONFIG="$as_dir$ac_word$ac_exec_ext" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi ac_pt_PKG_CONFIG=$ac_cv_path_ac_pt_PKG_CONFIG if test -n "$ac_pt_PKG_CONFIG"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_pt_PKG_CONFIG" >&5 printf "%s\n" "$ac_pt_PKG_CONFIG" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_pt_PKG_CONFIG" = x; then PKG_CONFIG="" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac PKG_CONFIG=$ac_pt_PKG_CONFIG fi else PKG_CONFIG="$ac_cv_path_PKG_CONFIG" fi fi if test -n "$PKG_CONFIG"; then _pkg_min_version=0.9.0 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking pkg-config is at least version $_pkg_min_version" >&5 printf %s "checking pkg-config is at least version $_pkg_min_version... " >&6; } if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } PKG_CONFIG="" fi fi build_linux=no build_sunos=no case "${host_os}" in linux*) build_linux=yes ;; solaris2*) build_sunos=yes ;; *) as_fn_error $? "\"OS ${host_os} not supported\"" "$LINENO" 5 ;; esac if test "x${build_linux}" = "xyes" ; then LINUX_TRUE= LINUX_FALSE='#' else LINUX_TRUE='#' LINUX_FALSE= fi if test "x${build_sunos}" = "xyes" ; then SUNOS_TRUE= SUNOS_FALSE='#' else SUNOS_TRUE='#' SUNOS_FALSE= fi if test -z "$SUNOS_TRUE"; then : CFLAGS="$CFLAGS -DSOL2 -DSRV4" fi # # Checks for header files, these will set the HAVE_[FILE]_H macros in config.h ac_fn_c_check_type "$LINENO" "_Bool" "ac_cv_type__Bool" "$ac_includes_default" if test "x$ac_cv_type__Bool" = xyes then : printf "%s\n" "#define HAVE__BOOL 1" >>confdefs.h fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for stdbool.h that conforms to C99" >&5 printf %s "checking for stdbool.h that conforms to C99... " >&6; } if test ${ac_cv_header_stdbool_h+y} then : printf %s "(cached) " >&6 else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #ifndef __bool_true_false_are_defined #error "__bool_true_false_are_defined is not defined" #endif char a[__bool_true_false_are_defined == 1 ? 1 : -1]; /* Regardless of whether this is C++ or "_Bool" is a valid type name, "true" and "false" should be usable in #if expressions and integer constant expressions, and "bool" should be a valid type name. */ #if !true #error "'true' is not true" #endif #if true != 1 #error "'true' is not equal to 1" #endif char b[true == 1 ? 1 : -1]; char c[true]; #if false #error "'false' is not false" #endif #if false != 0 #error "'false' is not equal to 0" #endif char d[false == 0 ? 1 : -1]; enum { e = false, f = true, g = false * true, h = true * 256 }; char i[(bool) 0.5 == true ? 1 : -1]; char j[(bool) 0.0 == false ? 1 : -1]; char k[sizeof (bool) > 0 ? 1 : -1]; struct sb { bool s: 1; bool t; } s; char l[sizeof s.t > 0 ? 1 : -1]; /* The following fails for HP aC++/ANSI C B3910B A.05.55 [Dec 04 2003]. */ bool m[h]; char n[sizeof m == h * sizeof m[0] ? 1 : -1]; char o[-1 - (bool) 0 < 0 ? 1 : -1]; /* Catch a bug in an HP-UX C compiler. See https://gcc.gnu.org/ml/gcc-patches/2003-12/msg02303.html https://lists.gnu.org/archive/html/bug-coreutils/2005-11/msg00161.html */ bool p = true; bool *pp = &p; /* C 1999 specifies that bool, true, and false are to be macros, but C++ 2011 and later overrule this. */ #if __cplusplus < 201103 #ifndef bool #error "bool is not defined" #endif #ifndef false #error "false is not defined" #endif #ifndef true #error "true is not defined" #endif #endif /* If _Bool is available, repeat with it all the tests above that used bool. */ #ifdef HAVE__BOOL struct sB { _Bool s: 1; _Bool t; } t; char q[(_Bool) 0.5 == true ? 1 : -1]; char r[(_Bool) 0.0 == false ? 1 : -1]; char u[sizeof (_Bool) > 0 ? 1 : -1]; char v[sizeof t.t > 0 ? 1 : -1]; _Bool w[h]; char x[sizeof m == h * sizeof m[0] ? 1 : -1]; char y[-1 - (_Bool) 0 < 0 ? 1 : -1]; _Bool z = true; _Bool *pz = &p; #endif int main (void) { bool ps = &s; *pp |= p; *pp |= ! p; #ifdef HAVE__BOOL _Bool pt = &t; *pz |= z; *pz |= ! z; #endif /* Refer to every declared value, so they cannot be discarded as unused. */ return (!a + !b + !c + !d + !e + !f + !g + !h + !i + !j + !k + !l + !m + !n + !o + !p + !pp + !ps #ifdef HAVE__BOOL + !q + !r + !u + !v + !w + !x + !y + !z + !pt #endif ); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : ac_cv_header_stdbool_h=yes else $as_nop ac_cv_header_stdbool_h=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdbool_h" >&5 printf "%s\n" "$ac_cv_header_stdbool_h" >&6; } if test $ac_cv_header_stdbool_h = yes; then printf "%s\n" "#define HAVE_STDBOOL_H 1" >>confdefs.h fi ac_fn_c_check_header_compile "$LINENO" "asm/types.h" "ac_cv_header_asm_types_h" "$ac_includes_default" if test "x$ac_cv_header_asm_types_h" = xyes then : printf "%s\n" "#define HAVE_ASM_TYPES_H 1" >>confdefs.h fi ac_fn_c_check_header_compile "$LINENO" "crypt.h" "ac_cv_header_crypt_h" "$ac_includes_default" if test "x$ac_cv_header_crypt_h" = xyes then : printf "%s\n" "#define HAVE_CRYPT_H 1" >>confdefs.h fi ac_fn_c_check_header_compile "$LINENO" "paths.h" "ac_cv_header_paths_h" "$ac_includes_default" if test "x$ac_cv_header_paths_h" = xyes then : printf "%s\n" "#define HAVE_PATHS_H 1" >>confdefs.h fi ac_fn_c_check_header_compile "$LINENO" "shadow.h" "ac_cv_header_shadow_h" "$ac_includes_default" if test "x$ac_cv_header_shadow_h" = xyes then : printf "%s\n" "#define HAVE_SHADOW_H 1" >>confdefs.h fi ac_fn_c_check_header_compile "$LINENO" "stddef.h" "ac_cv_header_stddef_h" "$ac_includes_default" if test "x$ac_cv_header_stddef_h" = xyes then : printf "%s\n" "#define HAVE_STDDEF_H 1" >>confdefs.h fi ac_fn_c_check_header_compile "$LINENO" "stdarg.h" "ac_cv_header_stdarg_h" "$ac_includes_default" if test "x$ac_cv_header_stdarg_h" = xyes then : printf "%s\n" "#define HAVE_STDARG_H 1" >>confdefs.h fi ac_fn_c_check_header_compile "$LINENO" "sys/dlpi.h" "ac_cv_header_sys_dlpi_h" "$ac_includes_default" if test "x$ac_cv_header_sys_dlpi_h" = xyes then : printf "%s\n" "#define HAVE_SYS_DLPI_H 1" >>confdefs.h fi ac_fn_c_check_header_compile "$LINENO" "sys/ioctl.h" "ac_cv_header_sys_ioctl_h" "$ac_includes_default" if test "x$ac_cv_header_sys_ioctl_h" = xyes then : printf "%s\n" "#define HAVE_SYS_IOCTL_H 1" >>confdefs.h fi ac_fn_c_check_header_compile "$LINENO" "sys/socket.h" "ac_cv_header_sys_socket_h" "$ac_includes_default" if test "x$ac_cv_header_sys_socket_h" = xyes then : printf "%s\n" "#define HAVE_SYS_SOCKET_H 1" >>confdefs.h fi ac_fn_c_check_header_compile "$LINENO" "sys/time.h" "ac_cv_header_sys_time_h" "$ac_includes_default" if test "x$ac_cv_header_sys_time_h" = xyes then : printf "%s\n" "#define HAVE_SYS_TIME_H 1" >>confdefs.h fi ac_fn_c_check_header_compile "$LINENO" "sys/uio.h" "ac_cv_header_sys_uio_h" "$ac_includes_default" if test "x$ac_cv_header_sys_uio_h" = xyes then : printf "%s\n" "#define HAVE_SYS_UIO_H 1" >>confdefs.h fi ac_fn_c_check_header_compile "$LINENO" "time.h" "ac_cv_header_time_h" "$ac_includes_default" if test "x$ac_cv_header_time_h" = xyes then : printf "%s\n" "#define HAVE_TIME_H 1" >>confdefs.h fi ac_fn_c_check_header_compile "$LINENO" "unistd.h" "ac_cv_header_unistd_h" "$ac_includes_default" if test "x$ac_cv_header_unistd_h" = xyes then : printf "%s\n" "#define HAVE_UNISTD_H 1" >>confdefs.h fi ac_fn_c_check_header_compile "$LINENO" "utmp.h" "ac_cv_header_utmp_h" "$ac_includes_default" if test "x$ac_cv_header_utmp_h" = xyes then : printf "%s\n" "#define HAVE_UTMP_H 1" >>confdefs.h fi # # Check for linux specific headers, required by pppoe, or pppol2tp if test -z "$LINUX_TRUE"; then : ac_fn_c_check_header_compile "$LINENO" "net/bpf.h" "ac_cv_header_net_bpf_h" "$ac_includes_default" if test "x$ac_cv_header_net_bpf_h" = xyes then : printf "%s\n" "#define HAVE_NET_BPF_H 1" >>confdefs.h fi ac_fn_c_check_header_compile "$LINENO" "net/if.h" "ac_cv_header_net_if_h" "$ac_includes_default" if test "x$ac_cv_header_net_if_h" = xyes then : printf "%s\n" "#define HAVE_NET_IF_H 1" >>confdefs.h fi ac_fn_c_check_header_compile "$LINENO" "net/if_types.h" "ac_cv_header_net_if_types_h" "$ac_includes_default" if test "x$ac_cv_header_net_if_types_h" = xyes then : printf "%s\n" "#define HAVE_NET_IF_TYPES_H 1" >>confdefs.h fi ac_fn_c_check_header_compile "$LINENO" "net/if_arp.h" "ac_cv_header_net_if_arp_h" "$ac_includes_default" if test "x$ac_cv_header_net_if_arp_h" = xyes then : printf "%s\n" "#define HAVE_NET_IF_ARP_H 1" >>confdefs.h fi ac_fn_c_check_header_compile "$LINENO" "linux/if.h" "ac_cv_header_linux_if_h" "$ac_includes_default" if test "x$ac_cv_header_linux_if_h" = xyes then : printf "%s\n" "#define HAVE_LINUX_IF_H 1" >>confdefs.h fi ac_fn_c_check_header_compile "$LINENO" "linux/if_ether.h" "ac_cv_header_linux_if_ether_h" "$ac_includes_default" if test "x$ac_cv_header_linux_if_ether_h" = xyes then : printf "%s\n" "#define HAVE_LINUX_IF_ETHER_H 1" >>confdefs.h fi ac_fn_c_check_header_compile "$LINENO" "linux/if_packet.h" "ac_cv_header_linux_if_packet_h" "$ac_includes_default" if test "x$ac_cv_header_linux_if_packet_h" = xyes then : printf "%s\n" "#define HAVE_LINUX_IF_PACKET_H 1" >>confdefs.h fi ac_fn_c_check_header_compile "$LINENO" "netinet/if_ether.h" "ac_cv_header_netinet_if_ether_h" "$ac_includes_default" if test "x$ac_cv_header_netinet_if_ether_h" = xyes then : printf "%s\n" "#define HAVE_NETINET_IF_ETHER_H 1" >>confdefs.h fi ac_fn_c_check_header_compile "$LINENO" "netpacket/packet.h" "ac_cv_header_netpacket_packet_h" "$ac_includes_default" if test "x$ac_cv_header_netpacket_packet_h" = xyes then : printf "%s\n" "#define HAVE_NETPACKET_PACKET_H 1" >>confdefs.h fi fi # The cast to long int works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. # This bug is HP SR number 8606223364. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking size of unsigned int" >&5 printf %s "checking size of unsigned int... " >&6; } if test ${ac_cv_sizeof_unsigned_int+y} then : printf %s "(cached) " >&6 else $as_nop if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (unsigned int))" "ac_cv_sizeof_unsigned_int" "$ac_includes_default" then : else $as_nop if test "$ac_cv_type_unsigned_int" = yes; then { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "cannot compute sizeof (unsigned int) See \`config.log' for more details" "$LINENO" 5; } else ac_cv_sizeof_unsigned_int=0 fi fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_unsigned_int" >&5 printf "%s\n" "$ac_cv_sizeof_unsigned_int" >&6; } printf "%s\n" "#define SIZEOF_UNSIGNED_INT $ac_cv_sizeof_unsigned_int" >>confdefs.h # The cast to long int works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. # This bug is HP SR number 8606223364. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking size of unsigned long" >&5 printf %s "checking size of unsigned long... " >&6; } if test ${ac_cv_sizeof_unsigned_long+y} then : printf %s "(cached) " >&6 else $as_nop if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (unsigned long))" "ac_cv_sizeof_unsigned_long" "$ac_includes_default" then : else $as_nop if test "$ac_cv_type_unsigned_long" = yes; then { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "cannot compute sizeof (unsigned long) See \`config.log' for more details" "$LINENO" 5; } else ac_cv_sizeof_unsigned_long=0 fi fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_unsigned_long" >&5 printf "%s\n" "$ac_cv_sizeof_unsigned_long" >&6; } printf "%s\n" "#define SIZEOF_UNSIGNED_LONG $ac_cv_sizeof_unsigned_long" >>confdefs.h # The cast to long int works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. # This bug is HP SR number 8606223364. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking size of unsigned short" >&5 printf %s "checking size of unsigned short... " >&6; } if test ${ac_cv_sizeof_unsigned_short+y} then : printf %s "(cached) " >&6 else $as_nop if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (unsigned short))" "ac_cv_sizeof_unsigned_short" "$ac_includes_default" then : else $as_nop if test "$ac_cv_type_unsigned_short" = yes; then { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "cannot compute sizeof (unsigned short) See \`config.log' for more details" "$LINENO" 5; } else ac_cv_sizeof_unsigned_short=0 fi fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_unsigned_short" >&5 printf "%s\n" "$ac_cv_sizeof_unsigned_short" >&6; } printf "%s\n" "#define SIZEOF_UNSIGNED_SHORT $ac_cv_sizeof_unsigned_short" >>confdefs.h # Checks for library functions. ac_fn_c_check_func "$LINENO" "mmap" "ac_cv_func_mmap" if test "x$ac_cv_func_mmap" = xyes then : printf "%s\n" "#define HAVE_MMAP 1" >>confdefs.h fi ac_fn_c_check_func "$LINENO" "logwtmp" "ac_cv_func_logwtmp" if test "x$ac_cv_func_logwtmp" = xyes then : printf "%s\n" "#define HAVE_LOGWTMP 1" >>confdefs.h fi ac_fn_c_check_func "$LINENO" "strerror" "ac_cv_func_strerror" if test "x$ac_cv_func_strerror" = xyes then : printf "%s\n" "#define HAVE_STRERROR 1" >>confdefs.h fi # # If libc doesn't provide logwtmp, check if libutil provides logwtmp(), and if so link to it. if test "x${ac_cv_func_logwtmp}" != "xyes" then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for logwtmp in -lutil" >&5 printf %s "checking for logwtmp in -lutil... " >&6; } if test ${ac_cv_lib_util_logwtmp+y} then : printf %s "(cached) " >&6 else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-lutil $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ char logwtmp (); int main (void) { return logwtmp (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : ac_cv_lib_util_logwtmp=yes else $as_nop ac_cv_lib_util_logwtmp=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_util_logwtmp" >&5 printf "%s\n" "$ac_cv_lib_util_logwtmp" >&6; } if test "x$ac_cv_lib_util_logwtmp" = xyes then : printf "%s\n" "#define HAVE_LOGWTMP 1" >>confdefs.h UTIL_LIBS="-lutil" fi fi # # Check if libcrypt have crypt() function { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for crypt in -lcrypt" >&5 printf %s "checking for crypt in -lcrypt... " >&6; } if test ${ac_cv_lib_crypt_crypt+y} then : printf %s "(cached) " >&6 else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-lcrypt $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ char crypt (); int main (void) { return crypt (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : ac_cv_lib_crypt_crypt=yes else $as_nop ac_cv_lib_crypt_crypt=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_crypt_crypt" >&5 printf "%s\n" "$ac_cv_lib_crypt_crypt" >&6; } if test "x$ac_cv_lib_crypt_crypt" = xyes then : CRYPT_LIBS="-lcrypt" fi # # Should pppd link with -lsystemd (Linux only) # Check whether --enable-systemd was given. if test ${enable_systemd+y} then : enableval=$enable_systemd; fi if test "x${enable_systemd}" = "xyes"; then WITH_SYSTEMD_TRUE= WITH_SYSTEMD_FALSE='#' else WITH_SYSTEMD_TRUE='#' WITH_SYSTEMD_FALSE= fi if test -z "$WITH_SYSTEMD_TRUE"; then : printf "%s\n" "#define SYSTEMD 1" >>confdefs.h fi if test "x${enable_systemd}" = "xyes" then : pkg_failed=no { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for libsystemd" >&5 printf %s "checking for libsystemd... " >&6; } if test -n "$SYSTEMD_CFLAGS"; then pkg_cv_SYSTEMD_CFLAGS="$SYSTEMD_CFLAGS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libsystemd\""; } >&5 ($PKG_CONFIG --exists --print-errors "libsystemd") 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_SYSTEMD_CFLAGS=`$PKG_CONFIG --cflags "libsystemd" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test -n "$SYSTEMD_LIBS"; then pkg_cv_SYSTEMD_LIBS="$SYSTEMD_LIBS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libsystemd\""; } >&5 ($PKG_CONFIG --exists --print-errors "libsystemd") 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_SYSTEMD_LIBS=`$PKG_CONFIG --libs "libsystemd" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test $pkg_failed = yes; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then SYSTEMD_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libsystemd" 2>&1` else SYSTEMD_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libsystemd" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$SYSTEMD_PKG_ERRORS" >&5 as_fn_error $? "Package requirements (libsystemd) were not met: $SYSTEMD_PKG_ERRORS Consider adjusting the PKG_CONFIG_PATH environment variable if you installed software in a non-standard prefix. Alternatively, you may set the environment variables SYSTEMD_CFLAGS and SYSTEMD_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details." "$LINENO" 5 elif test $pkg_failed = untried; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it is in your PATH or set the PKG_CONFIG environment variable to the full path to pkg-config. Alternatively, you may set the environment variables SYSTEMD_CFLAGS and SYSTEMD_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details. To get pkg-config, see . See \`config.log' for more details" "$LINENO" 5; } else SYSTEMD_CFLAGS=$pkg_cv_SYSTEMD_CFLAGS SYSTEMD_LIBS=$pkg_cv_SYSTEMD_LIBS { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } fi fi # # Enable Callback Protocol Support, disabled by default # Check whether --enable-cbcp was given. if test ${enable_cbcp+y} then : enableval=$enable_cbcp; fi if test "x${enable_cbcp}" = "xyes"; then PPP_WITH_CBCP_TRUE= PPP_WITH_CBCP_FALSE='#' else PPP_WITH_CBCP_TRUE='#' PPP_WITH_CBCP_FALSE= fi if test -z "$PPP_WITH_CBCP_TRUE"; then : printf "%s\n" "#define PPP_WITH_CBCP 1" >>confdefs.h fi # # Disable Microsoft extensions will remove CHAP and MPPE support # Check whether --enable-microsoft-extensions was given. if test ${enable_microsoft_extensions+y} then : enableval=$enable_microsoft_extensions; fi if test "x${enable_microsoft_extensions}" != "xno"; then PPP_WITH_CHAPMS_TRUE= PPP_WITH_CHAPMS_FALSE='#' else PPP_WITH_CHAPMS_TRUE='#' PPP_WITH_CHAPMS_FALSE= fi if test -z "$PPP_WITH_CHAPMS_TRUE"; then : printf "%s\n" "#define PPP_WITH_CHAPMS 1" >>confdefs.h fi if test "x${enable_microsoft_extensions}" != "xno"; then PPP_WITH_MPPE_TRUE= PPP_WITH_MPPE_FALSE='#' else PPP_WITH_MPPE_TRUE='#' PPP_WITH_MPPE_FALSE= fi if test -z "$PPP_WITH_MPPE_TRUE"; then : printf "%s\n" "#define PPP_WITH_MPPE 1" >>confdefs.h fi # # Enable Microsoft LAN Manager support, depends on Microsoft Extensions # Check whether --enable-mslanman was given. if test ${enable_mslanman+y} then : enableval=$enable_mslanman; fi if test "x${enable_mslanman}" = "xyes" && test "x${enable_microsoft_extensions}" != "xno" then : printf "%s\n" "#define PPP_WITH_MSLANMAN 1" >>confdefs.h fi # # Disable IPv6 support # Check whether --enable-ipv6cp was given. if test ${enable_ipv6cp+y} then : enableval=$enable_ipv6cp; fi if test "x${enable_ipv6cp}" != "xno"; then PPP_WITH_IPV6CP_TRUE= PPP_WITH_IPV6CP_FALSE='#' else PPP_WITH_IPV6CP_TRUE='#' PPP_WITH_IPV6CP_FALSE= fi if test -z "$PPP_WITH_IPV6CP_TRUE"; then : printf "%s\n" "#define PPP_WITH_IPV6CP 1" >>confdefs.h fi # # Disable Multilink support # Check whether --enable-multilink was given. if test ${enable_multilink+y} then : enableval=$enable_multilink; fi if test "x${enable_multilink}" = "xyes"; then PPP_WITH_MULTILINK_TRUE= PPP_WITH_MULTILINK_FALSE='#' else PPP_WITH_MULTILINK_TRUE='#' PPP_WITH_MULTILINK_FALSE= fi if test -z "$PPP_WITH_MULTILINK_TRUE"; then : printf "%s\n" "#define PPP_WITH_MULTILINK 1" >>confdefs.h fi if test "x${build_sunos}" = "xyes" && test "x${enable_multilink}" = "xyes" then : as_fn_error $? "Multilink is not supported on SunOS" "$LINENO" 5 fi # # Multilink require Trivial Database Support if test "x${enable_multilink}" = "xyes"; then PPP_WITH_TDB_TRUE= PPP_WITH_TDB_FALSE='#' else PPP_WITH_TDB_TRUE='#' PPP_WITH_TDB_FALSE= fi if test -z "$PPP_WITH_TDB_TRUE"; then : printf "%s\n" "#define PPP_WITH_TDB 1" >>confdefs.h fi # # Enable support for loadable plugins # Check whether --enable-plugins was given. if test ${enable_plugins+y} then : enableval=$enable_plugins; fi if test "x$enable_plugins" != "xno" then : printf "%s\n" "#define PPP_WITH_PLUGINS 1" >>confdefs.h fi if test "x${enable_plugins}" != "xno"; then PPP_WITH_PLUGINS_TRUE= PPP_WITH_PLUGINS_FALSE='#' else PPP_WITH_PLUGINS_TRUE='#' PPP_WITH_PLUGINS_FALSE= fi # # Disable EAP-TLS support # Check whether --enable-eaptls was given. if test ${enable_eaptls+y} then : enableval=$enable_eaptls; fi if test "x$enable_eaptls" != "xno" then : printf "%s\n" "#define PPP_WITH_EAPTLS 1" >>confdefs.h fi if test "x${enable_eaptls}" != "xno"; then PPP_WITH_EAPTLS_TRUE= PPP_WITH_EAPTLS_FALSE='#' else PPP_WITH_EAPTLS_TRUE='#' PPP_WITH_EAPTLS_FALSE= fi # # Disable PEAP support # Check whether --enable-peap was given. if test ${enable_peap+y} then : enableval=$enable_peap; fi if test "x${enable_peap}" != "xno" then : printf "%s\n" "#define PPP_WITH_PEAP 1" >>confdefs.h fi if test "x${enable_peap}" != "xno"; then PPP_WITH_PEAP_TRUE= PPP_WITH_PEAP_FALSE='#' else PPP_WITH_PEAP_TRUE='#' PPP_WITH_PEAP_FALSE= fi # # Disable OpenSSL engine support # Check whether --enable-openssl-engine was given. if test ${enable_openssl_engine+y} then : enableval=$enable_openssl_engine; fi if test "x$enable_openssl_engine" != "xno" then : else $as_nop printf "%s\n" "#define OPENSSL_NO_ENGINE 1" >>confdefs.h fi # # Specify runtime directory # Check whether --with-plugin-dir was given. if test ${with_plugin_dir+y} then : withval=$with_plugin_dir; fi if test -n "$with_plugin_dir" then : PPPD_PLUGIN_DIR="$with_plugin_dir" else $as_nop PPPD_PLUGIN_DIR="${libdir}/pppd/$VERSION" fi PPPD_PLUGIN_DIR="$PPPD_PLUGIN_DIR" # # Specify runtime directory # Check whether --with-runtime-dir was given. if test ${with_runtime_dir+y} then : withval=$with_runtime_dir; fi if test -n "$with_runtime_dir" then : PPPD_RUNTIME_DIR="$with_runtime_dir" else $as_nop PPPD_RUNTIME_DIR="${runstatedir}/pppd" fi # # Specify runtime directory # Check whether --with-logfile-dir was given. if test ${with_logfile_dir+y} then : withval=$with_logfile_dir; fi if test -n "$with_logfile_dir" then : PPPD_LOGFILE_DIR="$with_logfile_dir" else $as_nop PPPD_LOGFILE_DIR="${localstatedir}/log/ppp" fi # # System CA certificates path # Check whether --with-system-ca-path was given. if test ${with_system_ca_path+y} then : withval=$with_system_ca_path; case "$withval" in "" | y | ye | yes) with_system_ca_path="${sysconfdir}/ssl/certs" ;; n | no) ;; *) with_system_ca_path="$withval" ;; esac else $as_nop with_system_ca_path="${sysconfdir}/ssl/certs" fi if test "$with_system_ca_path" != "no"; then PPP_WITH_SYSTEM_CA_PATH_TRUE= PPP_WITH_SYSTEM_CA_PATH_FALSE='#' else PPP_WITH_SYSTEM_CA_PATH_TRUE='#' PPP_WITH_SYSTEM_CA_PATH_FALSE= fi if test -z "$PPP_WITH_SYSTEM_CA_PATH_TRUE"; then : SYSTEM_CA_PATH="$with_system_ca_path" fi # # Check for OpenSSL found=false # Check whether --with-openssl was given. if test ${with_openssl+y} then : withval=$with_openssl; case "$withval" in "" | y | ye | yes ) ssldirs="/usr/local/ssl /usr/lib/ssl /usr/ssl /usr/pkg /usr/local /usr" ;; n | no ) ;; *) ssldirs="$withval" ;; esac else $as_nop ssldirs="/usr/local/ssl /usr/lib/ssl /usr/ssl /usr/pkg /usr/local /usr" fi if test "${with_openssl}" != "no" then : OPENSSL_INCLUDES= for ssldir in $ssldirs; do { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for openssl/ssl.h in $ssldir" >&5 printf %s "checking for openssl/ssl.h in $ssldir... " >&6; } if test -f "$ssldir/include/openssl/ssl.h" then : OPENSSL_INCLUDES="-I$ssldir/include" OPENSSL_LDFLAGS="-L$ssldir/lib" OPENSSL_LIBS="-lssl -lcrypto" found=true { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } break else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi done fi if test "${with_openssl}" != "no" && test ! ${found} then : # if pkg-config is installed and openssl has installed a .pc file, # then use that information and don't search ssldirs # Extract the first word of "pkg-config", so it can be a program name with args. set dummy pkg-config; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_path_PKG_CONFIG+y} then : printf %s "(cached) " >&6 else $as_nop case $PKG_CONFIG in [\\/]* | ?:[\\/]*) ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_path_PKG_CONFIG="$as_dir$ac_word$ac_exec_ext" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi PKG_CONFIG=$ac_cv_path_PKG_CONFIG if test -n "$PKG_CONFIG"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5 printf "%s\n" "$PKG_CONFIG" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test x"$PKG_CONFIG" != x""; then OPENSSL_LDFLAGS=`$PKG_CONFIG openssl --libs-only-L 2>/dev/null` if test $? = 0; then OPENSSL_LIBS=`$PKG_CONFIG openssl --libs-only-l 2>/dev/null` OPENSSL_INCLUDES=`$PKG_CONFIG openssl --cflags-only-I 2>/dev/null` found=true fi fi fi if test "${with_openssl}" != "no" && test ${found} then : # try the preprocessor and linker with our new flags, # being careful not to pollute the global LIBS, LDFLAGS, and CPPFLAGS { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether compiling and linking against OpenSSL works" >&5 printf %s "checking whether compiling and linking against OpenSSL works... " >&6; } echo "Trying link with OPENSSL_LDFLAGS=$OPENSSL_LDFLAGS;" \ "OPENSSL_LIBS=$OPENSSL_LIBS; OPENSSL_INCLUDES=$OPENSSL_INCLUDES" >&5 save_LIBS="$LIBS" save_LDFLAGS="$LDFLAGS" save_CPPFLAGS="$CPPFLAGS" LDFLAGS="$LDFLAGS $OPENSSL_LDFLAGS" LIBS="$OPENSSL_LIBS $LIBS" CPPFLAGS="$OPENSSL_INCLUDES $CPPFLAGS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main (void) { SSL_new(NULL) ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext CPPFLAGS="$save_CPPFLAGS" LDFLAGS="$save_LDFLAGS" LIBS="$save_LIBS" fi if test "x${with_openssl}" != "xno"; then PPP_WITH_OPENSSL_TRUE= PPP_WITH_OPENSSL_FALSE='#' else PPP_WITH_OPENSSL_TRUE='#' PPP_WITH_OPENSSL_FALSE= fi if test -z "$PPP_WITH_OPENSSL_TRUE"; then : printf "%s\n" "#define PPP_WITH_OPENSSL 1" >>confdefs.h fi # # Check if OpenSSL has compiled in support for various ciphers ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 printf %s "checking how to run the C preprocessor... " >&6; } # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= fi if test -z "$CPP"; then if test ${ac_cv_prog_CPP+y} then : printf %s "(cached) " >&6 else $as_nop # Double quotes because $CC needs to be expanded for CPP in "$CC -E" "$CC -E -traditional-cpp" cpp /lib/cpp do ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO" then : else $as_nop # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO" then : # Broken: success on invalid input. continue else $as_nop # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok then : break fi done ac_cv_prog_CPP=$CPP fi CPP=$ac_cv_prog_CPP else ac_cv_prog_CPP=$CPP fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 printf "%s\n" "$CPP" >&6; } ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO" then : else $as_nop # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO" then : # Broken: success on invalid input. continue else $as_nop # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok then : else $as_nop { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details" "$LINENO" 5; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test "x${with_openssl}" != "xno" then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for md4 support in openssl" >&5 printf %s "checking for md4 support in openssl... " >&6; } save_CPPFLAGS="$CPPFLAGS" CPPFLAGS="$OPENSSL_INCLUDES $CPPFLAGS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main (void) { #ifdef OPENSSL_NO_MD4 #error "No support for OPENSSL_NO_MD4" #endif ; return 0; } _ACEOF if ac_fn_c_try_cpp "$LINENO" then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } ac_cv_openssl_md4=yes else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } ac_cv_openssl_md4=no fi rm -f conftest.err conftest.i conftest.$ac_ext CPPFLAGS="$save_CPPFLAGS" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for md5 support in openssl" >&5 printf %s "checking for md5 support in openssl... " >&6; } save_CPPFLAGS="$CPPFLAGS" CPPFLAGS="$OPENSSL_INCLUDES $CPPFLAGS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main (void) { #ifdef OPENSSL_NO_MD5 #error "No support for OPENSSL_NO_MD5" #endif ; return 0; } _ACEOF if ac_fn_c_try_cpp "$LINENO" then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } ac_cv_openssl_md5=yes else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } ac_cv_openssl_md5=no fi rm -f conftest.err conftest.i conftest.$ac_ext CPPFLAGS="$save_CPPFLAGS" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for des support in openssl" >&5 printf %s "checking for des support in openssl... " >&6; } save_CPPFLAGS="$CPPFLAGS" CPPFLAGS="$OPENSSL_INCLUDES $CPPFLAGS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main (void) { #ifdef OPENSSL_NO_DES #error "No support for OPENSSL_NO_DES" #endif ; return 0; } _ACEOF if ac_fn_c_try_cpp "$LINENO" then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } ac_cv_openssl_des=yes else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } ac_cv_openssl_des=no fi rm -f conftest.err conftest.i conftest.$ac_ext CPPFLAGS="$save_CPPFLAGS" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for sha support in openssl" >&5 printf %s "checking for sha support in openssl... " >&6; } save_CPPFLAGS="$CPPFLAGS" CPPFLAGS="$OPENSSL_INCLUDES $CPPFLAGS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main (void) { #ifdef OPENSSL_NO_SHA #error "No support for OPENSSL_NO_SHA" #endif ; return 0; } _ACEOF if ac_fn_c_try_cpp "$LINENO" then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } ac_cv_openssl_sha=yes else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } ac_cv_openssl_sha=no fi rm -f conftest.err conftest.i conftest.$ac_ext CPPFLAGS="$save_CPPFLAGS" else $as_nop if test "x${enable_eaptls}" != "xno" || test "x${enable_peap}" != "xno" then : as_fn_error $? "OpenSSL not found, and if this is your intention then run configure --disable-eaptls and --disable-peap" "$LINENO" 5 fi fi if test "x${ac_cv_openssl_md4}" = "xyes"; then OPENSSL_HAVE_MD4_TRUE= OPENSSL_HAVE_MD4_FALSE='#' else OPENSSL_HAVE_MD4_TRUE='#' OPENSSL_HAVE_MD4_FALSE= fi if test -z "$OPENSSL_HAVE_MD4_TRUE"; then : printf "%s\n" "#define OPENSSL_HAVE_MD4 1" >>confdefs.h fi if test "x${ac_cv_openssl_md5}" = "xyes"; then OPENSSL_HAVE_MD5_TRUE= OPENSSL_HAVE_MD5_FALSE='#' else OPENSSL_HAVE_MD5_TRUE='#' OPENSSL_HAVE_MD5_FALSE= fi if test -z "$OPENSSL_HAVE_MD5_TRUE"; then : printf "%s\n" "#define OPENSSL_HAVE_MD5 1" >>confdefs.h fi if test "x${ac_cv_openssl_sha}" = "xyes"; then OPENSSL_HAVE_SHA_TRUE= OPENSSL_HAVE_SHA_FALSE='#' else OPENSSL_HAVE_SHA_TRUE='#' OPENSSL_HAVE_SHA_FALSE= fi if test -z "$OPENSSL_HAVE_SHA_TRUE"; then : printf "%s\n" "#define OPENSSL_HAVE_SHA 1" >>confdefs.h fi if test "x${ac_cv_openssl_des}" = "xyes"; then OPENSSL_HAVE_DES_TRUE= OPENSSL_HAVE_DES_FALSE='#' else OPENSSL_HAVE_DES_TRUE='#' OPENSSL_HAVE_DES_FALSE= fi if test -z "$OPENSSL_HAVE_DES_TRUE"; then : printf "%s\n" "#define OPENSSL_HAVE_DES 1" >>confdefs.h fi # # With libsrp support # Check whether --with-srp was given. if test ${with_srp+y} then : withval=$with_srp; case "$withval" in "" | y | ye | yes) srpdirs="/usr/local /usr/lib /usr" ;; n | no) with_srp="no" ;; *) srpdirs="$withval" ;; esac fi if test "x${with_srp}" != "xno" ; then SRP_LIBS="-lsrp" for srpdir in $srpdirs; do { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for srp.h in $srpdir" >&5 printf %s "checking for srp.h in $srpdir... " >&6; } if test -f "$srpdir/include/srp.h"; then SRP_CFLAGS="-I$srpdir/include" SRP_LDFLAGS="-L$srpdir/lib" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } break else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi done # try the preprocessor and linker with our new flags, # being careful not to pollute the global LIBS, LDFLAGS, and CPPFLAGS { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if compiling and linking against libsrp works" >&5 printf %s "checking if compiling and linking against libsrp works... " >&6; } save_LIBS="$LIBS" save_LDFLAGS="$LDFLAGS" save_CPPFLAGS="$CPPFLAGS" LDFLAGS="$SRP_LDFLAGS $OPENSSL_LDFLAGS $LDFLAGS" LIBS="$SRP_LIBS $OPENSSL_LIBS $LIBS" CPPFLAGS="$SRP_CFLAGS $OPENSSL_INCLUDES $CPPFLAGS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main (void) { SRP_use_engine(NULL); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } with_srp=yes printf "%s\n" "#define PPP_WITH_SRP 1" >>confdefs.h else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } with_srp="no" fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext CPPFLAGS="$save_CPPFLAGS" LDFLAGS="$save_LDFLAGS" LIBS="$save_LIBS" fi if test "x${with_srp}" != "xno"; then WITH_SRP_TRUE= WITH_SRP_FALSE='#' else WITH_SRP_TRUE='#' WITH_SRP_FALSE= fi # # With libatm support # Check whether --with-atm was given. if test ${with_atm+y} then : withval=$with_atm; case "$withval" in "" | y | ye | yes) atmdirs="/usr/local /usr/lib /usr" ;; n | no) with_atm="no" ;; *) atmdirs="$withval" ;; esac fi if test "x${with_atm}" != "xno" ; then ATM_LIBS="-latm" for atmdir in $atmdirs; do { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for atm.h in $atmdir" >&5 printf %s "checking for atm.h in $atmdir... " >&6; } if test -f "$atmdir/include/atm.h"; then ATM_CFLAGS="-I$atmdir/include" ATM_LDFLAGS="-L$atmdir/lib" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } break else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi done # try the preprocessor and linker with our new flags, # being careful not to pollute the global LIBS, LDFLAGS, and CPPFLAGS { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if compiling and linking against libatm works" >&5 printf %s "checking if compiling and linking against libatm works... " >&6; } save_LIBS="$LIBS" save_LDFLAGS="$LDFLAGS" save_CPPFLAGS="$CPPFLAGS" LDFLAGS="$LDFLAGS $ATM_LDFLAGS" LIBS="$ATM_LIBS $LIBS" CPPFLAGS="$ATM_CFLAGS $CPPFLAGS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main (void) { text2atm(NULL,NULL,0,0); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } with_atm=yes else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } with_atm="no" fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext CPPFLAGS="$save_CPPFLAGS" LDFLAGS="$save_LDFLAGS" LIBS="$save_LIBS" fi if test "x${with_atm}" != "xno"; then WITH_LIBATM_TRUE= WITH_LIBATM_FALSE='#' else WITH_LIBATM_TRUE='#' WITH_LIBATM_FALSE= fi # # With libpam support # Check whether --with-pam was given. if test ${with_pam+y} then : withval=$with_pam; case "$withval" in "" | y | ye | yes) pamdirs="/usr/local /usr/lib /usr" ;; n | no) with_pam="no" ;; *) pamdirs="$withval" ;; esac fi if test "x${with_pam}" != "xno" ; then PAM_LIBS="-lpam" for pamdir in $pamdirs; do { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for pam_appl.h in $pamdir" >&5 printf %s "checking for pam_appl.h in $pamdir... " >&6; } if test -f "$pamdir/include/security/pam_appl.h"; then PAM_CFLAGS="-I$pamdir/include" PAM_LDFLAGS="-L$pamdir/lib" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } break else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi done # try the preprocessor and linker with our new flags, # being careful not to pollute the global LIBS, LDFLAGS, and CPPFLAGS { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if compiling and linking against libpam works" >&5 printf %s "checking if compiling and linking against libpam works... " >&6; } save_LIBS="$LIBS" save_LDFLAGS="$LDFLAGS" save_CPPFLAGS="$CPPFLAGS" LDFLAGS="$LDFLAGS $PAM_LDFLAGS" LIBS="$PAM_LIBS $LIBS" CPPFLAGS="$PAM_CFLAGS $CPPFLAGS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main (void) { pam_authenticate(NULL, 0); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } with_pam=yes printf "%s\n" "#define PPP_WITH_PAM 1" >>confdefs.h else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } with_pam="no" fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext CPPFLAGS="$save_CPPFLAGS" LDFLAGS="$save_LDFLAGS" LIBS="$save_LIBS" fi if test "x${with_pam}" != "xno"; then WITH_LIBPAM_TRUE= WITH_LIBPAM_FALSE='#' else WITH_LIBPAM_TRUE='#' WITH_LIBPAM_FALSE= fi if test "x${with_pam}" = "xyes"; then PPP_WITH_PAM_TRUE= PPP_WITH_PAM_FALSE='#' else PPP_WITH_PAM_TRUE='#' PPP_WITH_PAM_FALSE= fi # # With libpcap support, activate pppd on network activity # Check whether --with-pcap was given. if test ${with_pcap+y} then : withval=$with_pcap; case "$withval" in "" | y | ye | yes) pcapdirs="/usr/local /usr/lib /usr" ;; n | no) with_pcap="no" ;; *) pcapdirs="$withval" ;; esac fi if test "x${with_pcap}" != "xno" ; then PCAP_LIBS="-lpcap" for pcapdir in $pcapdirs; do { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for pcap.h in $pcapdir" >&5 printf %s "checking for pcap.h in $pcapdir... " >&6; } if test -f "$pcapdir/include/pcap.h"; then PCAP_CFLAGS="-I$pcapdir/include" PCAP_LDFLAGS="-L$pcapdir/lib" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } break else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi done # try the preprocessor and linker with our new flags, # being careful not to pollute the global LIBS, LDFLAGS, and CPPFLAGS { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if compiling and linking against libpcap works" >&5 printf %s "checking if compiling and linking against libpcap works... " >&6; } save_LIBS="$LIBS" save_LDFLAGS="$LDFLAGS" save_CPPFLAGS="$CPPFLAGS" LDFLAGS="$PCAP_LDFLAGS $LDFLAGS" LIBS="$PCAP_LIBS $LIBS" CPPFLAGS="$PCAP_CFLAGS $CPPFLAGS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main (void) { pcap_create(0,0); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } with_pcap=yes else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } with_pcap="no" fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext CPPFLAGS="$save_CPPFLAGS" LDFLAGS="$save_LDFLAGS" LIBS="$save_LIBS" fi if test "x${with_pcap}" != "xno"; then WITH_PCAP_TRUE= WITH_PCAP_FALSE='#' else WITH_PCAP_TRUE='#' WITH_PCAP_FALSE= fi # # SunOS provides a version of libpcap that would work, but SunOS has no support for activity filter if test "x${with_pcap}" = "xyes" && test "x${build_sunos}" != "xyes" ; then PPP_WITH_FILTER_TRUE= PPP_WITH_FILTER_FALSE='#' else PPP_WITH_FILTER_TRUE='#' PPP_WITH_FILTER_FALSE= fi if test -z "$PPP_WITH_FILTER_TRUE"; then : printf "%s\n" "#define PPP_WITH_FILTER 1" >>confdefs.h else if test "x${build_sunos}" = "xyes" then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: Packet activity filter not supported on SunOS" >&5 printf "%s\n" "$as_me: WARNING: Packet activity filter not supported on SunOS" >&2;} with_pcap="no" fi fi # # Some contributions require GTK/GLIB # Check whether --with-gtk was given. if test ${with_gtk+y} then : withval=$with_gtk; fi if test "x${with_gtk}" = "xyes"; then pkg_failed=no { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for gtk+-2.0" >&5 printf %s "checking for gtk+-2.0... " >&6; } if test -n "$GTK_CFLAGS"; then pkg_cv_GTK_CFLAGS="$GTK_CFLAGS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"gtk+-2.0\""; } >&5 ($PKG_CONFIG --exists --print-errors "gtk+-2.0") 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_GTK_CFLAGS=`$PKG_CONFIG --cflags "gtk+-2.0" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test -n "$GTK_LIBS"; then pkg_cv_GTK_LIBS="$GTK_LIBS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"gtk+-2.0\""; } >&5 ($PKG_CONFIG --exists --print-errors "gtk+-2.0") 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_GTK_LIBS=`$PKG_CONFIG --libs "gtk+-2.0" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test $pkg_failed = yes; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then GTK_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "gtk+-2.0" 2>&1` else GTK_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "gtk+-2.0" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$GTK_PKG_ERRORS" >&5 as_fn_error $? "Package requirements (gtk+-2.0) were not met: $GTK_PKG_ERRORS Consider adjusting the PKG_CONFIG_PATH environment variable if you installed software in a non-standard prefix. Alternatively, you may set the environment variables GTK_CFLAGS and GTK_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details." "$LINENO" 5 elif test $pkg_failed = untried; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it is in your PATH or set the PKG_CONFIG environment variable to the full path to pkg-config. Alternatively, you may set the environment variables GTK_CFLAGS and GTK_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details. To get pkg-config, see . See \`config.log' for more details" "$LINENO" 5; } else GTK_CFLAGS=$pkg_cv_GTK_CFLAGS GTK_LIBS=$pkg_cv_GTK_LIBS { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } fi pkg_failed=no { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for glib-2.0" >&5 printf %s "checking for glib-2.0... " >&6; } if test -n "$GLIB_CFLAGS"; then pkg_cv_GLIB_CFLAGS="$GLIB_CFLAGS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"glib-2.0\""; } >&5 ($PKG_CONFIG --exists --print-errors "glib-2.0") 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_GLIB_CFLAGS=`$PKG_CONFIG --cflags "glib-2.0" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test -n "$GLIB_LIBS"; then pkg_cv_GLIB_LIBS="$GLIB_LIBS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"glib-2.0\""; } >&5 ($PKG_CONFIG --exists --print-errors "glib-2.0") 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_GLIB_LIBS=`$PKG_CONFIG --libs "glib-2.0" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test $pkg_failed = yes; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then GLIB_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "glib-2.0" 2>&1` else GLIB_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "glib-2.0" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$GLIB_PKG_ERRORS" >&5 as_fn_error $? "Package requirements (glib-2.0) were not met: $GLIB_PKG_ERRORS Consider adjusting the PKG_CONFIG_PATH environment variable if you installed software in a non-standard prefix. Alternatively, you may set the environment variables GLIB_CFLAGS and GLIB_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details." "$LINENO" 5 elif test $pkg_failed = untried; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it is in your PATH or set the PKG_CONFIG environment variable to the full path to pkg-config. Alternatively, you may set the environment variables GLIB_CFLAGS and GLIB_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details. To get pkg-config, see . See \`config.log' for more details" "$LINENO" 5; } else GLIB_CFLAGS=$pkg_cv_GLIB_CFLAGS GLIB_LIBS=$pkg_cv_GLIB_LIBS { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } fi fi if test "x${with_gtk}" = "xyes"; then WITH_GTK_TRUE= WITH_GTK_FALSE='#' else WITH_GTK_TRUE='#' WITH_GTK_FALSE= fi printf "%s\n" "#define PPPD_VERSION \"$VERSION\"" >>confdefs.h ac_config_files="$ac_config_files Makefile chat/Makefile contrib/Makefile contrib/pppgetpass/Makefile common/Makefile include/Makefile modules/Makefile pppd/Makefile pppd/pppd.pc pppd/plugins/Makefile pppd/plugins/pppoe/Makefile pppd/plugins/pppoatm/Makefile pppd/plugins/pppol2tp/Makefile pppd/plugins/radius/Makefile pppdump/Makefile pppstats/Makefile scripts/Makefile" cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure # scripts and configure runs, see configure's option --config-cache. # It is not useful on other systems. If it contains results you don't # want to keep, you may remove or edit it. # # config.status only pays attention to the cache file if you give it # the --recheck option to rerun configure. # # `ac_cv_env_foo' variables (set or unset) will be overridden when # loading this file, other *unset* `ac_cv_foo' will be assigned the # following values. _ACEOF # The following way of writing the cache mishandles newlines in values, # but we know of no workaround that is simple, portable, and efficient. # So, we kill variables containing newlines. # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. ( for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 printf "%s\n" "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space=' '; set) 2>&1` in #( *${as_nl}ac_space=\ *) # `set' does not quote correctly, so add quotes: double-quote # substitution turns \\\\ into \\, and sed turns \\ into \. sed -n \ "s/'/'\\\\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" ;; #( *) # `set' quotes correctly as required by POSIX, so do not add quotes. sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) | sed ' /^ac_cv_env_/b end t clear :clear s/^\([^=]*\)=\(.*[{}].*\)$/test ${\1+y} || &/ t end s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ :end' >>confcache if diff "$cache_file" confcache >/dev/null 2>&1; then :; else if test -w "$cache_file"; then if test "x$cache_file" != "x/dev/null"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 printf "%s\n" "$as_me: updating cache $cache_file" >&6;} if test ! -f "$cache_file" || test -h "$cache_file"; then cat confcache >"$cache_file" else case $cache_file in #( */* | ?:*) mv -f confcache "$cache_file"$$ && mv -f "$cache_file"$$ "$cache_file" ;; #( *) mv -f confcache "$cache_file" ;; esac fi fi else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 printf "%s\n" "$as_me: not updating unwritable cache $cache_file" >&6;} fi fi rm -f confcache test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' DEFS=-DHAVE_CONFIG_H ac_libobjs= ac_ltlibobjs= U= for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue # 1. Remove the extension, and $U if already installed. ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' ac_i=`printf "%s\n" "$ac_i" | sed "$ac_script"` # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR # will be set to the directory where LIBOBJS objects are built. as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' done LIBOBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking that generated files are newer than configure" >&5 printf %s "checking that generated files are newer than configure... " >&6; } if test -n "$am_sleep_pid"; then # Hide warnings about reused PIDs. wait $am_sleep_pid 2>/dev/null fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: done" >&5 printf "%s\n" "done" >&6; } if test -n "$EXEEXT"; then am__EXEEXT_TRUE= am__EXEEXT_FALSE='#' else am__EXEEXT_TRUE='#' am__EXEEXT_FALSE= fi if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then as_fn_error $? "conditional \"MAINTAINER_MODE\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then as_fn_error $? "conditional \"AMDEP\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then as_fn_error $? "conditional \"am__fastdepCC\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${LINUX_TRUE}" && test -z "${LINUX_FALSE}"; then as_fn_error $? "conditional \"LINUX\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${SUNOS_TRUE}" && test -z "${SUNOS_FALSE}"; then as_fn_error $? "conditional \"SUNOS\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${WITH_SYSTEMD_TRUE}" && test -z "${WITH_SYSTEMD_FALSE}"; then as_fn_error $? "conditional \"WITH_SYSTEMD\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${PPP_WITH_CBCP_TRUE}" && test -z "${PPP_WITH_CBCP_FALSE}"; then as_fn_error $? "conditional \"PPP_WITH_CBCP\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${PPP_WITH_CHAPMS_TRUE}" && test -z "${PPP_WITH_CHAPMS_FALSE}"; then as_fn_error $? "conditional \"PPP_WITH_CHAPMS\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${PPP_WITH_MPPE_TRUE}" && test -z "${PPP_WITH_MPPE_FALSE}"; then as_fn_error $? "conditional \"PPP_WITH_MPPE\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${PPP_WITH_IPV6CP_TRUE}" && test -z "${PPP_WITH_IPV6CP_FALSE}"; then as_fn_error $? "conditional \"PPP_WITH_IPV6CP\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${PPP_WITH_MULTILINK_TRUE}" && test -z "${PPP_WITH_MULTILINK_FALSE}"; then as_fn_error $? "conditional \"PPP_WITH_MULTILINK\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${PPP_WITH_TDB_TRUE}" && test -z "${PPP_WITH_TDB_FALSE}"; then as_fn_error $? "conditional \"PPP_WITH_TDB\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${PPP_WITH_PLUGINS_TRUE}" && test -z "${PPP_WITH_PLUGINS_FALSE}"; then as_fn_error $? "conditional \"PPP_WITH_PLUGINS\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${PPP_WITH_EAPTLS_TRUE}" && test -z "${PPP_WITH_EAPTLS_FALSE}"; then as_fn_error $? "conditional \"PPP_WITH_EAPTLS\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${PPP_WITH_PEAP_TRUE}" && test -z "${PPP_WITH_PEAP_FALSE}"; then as_fn_error $? "conditional \"PPP_WITH_PEAP\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${PPP_WITH_SYSTEM_CA_PATH_TRUE}" && test -z "${PPP_WITH_SYSTEM_CA_PATH_FALSE}"; then as_fn_error $? "conditional \"PPP_WITH_SYSTEM_CA_PATH\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${PPP_WITH_OPENSSL_TRUE}" && test -z "${PPP_WITH_OPENSSL_FALSE}"; then as_fn_error $? "conditional \"PPP_WITH_OPENSSL\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${OPENSSL_HAVE_MD4_TRUE}" && test -z "${OPENSSL_HAVE_MD4_FALSE}"; then as_fn_error $? "conditional \"OPENSSL_HAVE_MD4\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${OPENSSL_HAVE_MD5_TRUE}" && test -z "${OPENSSL_HAVE_MD5_FALSE}"; then as_fn_error $? "conditional \"OPENSSL_HAVE_MD5\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${OPENSSL_HAVE_SHA_TRUE}" && test -z "${OPENSSL_HAVE_SHA_FALSE}"; then as_fn_error $? "conditional \"OPENSSL_HAVE_SHA\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${OPENSSL_HAVE_DES_TRUE}" && test -z "${OPENSSL_HAVE_DES_FALSE}"; then as_fn_error $? "conditional \"OPENSSL_HAVE_DES\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${WITH_SRP_TRUE}" && test -z "${WITH_SRP_FALSE}"; then as_fn_error $? "conditional \"WITH_SRP\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${WITH_LIBATM_TRUE}" && test -z "${WITH_LIBATM_FALSE}"; then as_fn_error $? "conditional \"WITH_LIBATM\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${WITH_LIBPAM_TRUE}" && test -z "${WITH_LIBPAM_FALSE}"; then as_fn_error $? "conditional \"WITH_LIBPAM\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${PPP_WITH_PAM_TRUE}" && test -z "${PPP_WITH_PAM_FALSE}"; then as_fn_error $? "conditional \"PPP_WITH_PAM\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${WITH_PCAP_TRUE}" && test -z "${WITH_PCAP_FALSE}"; then as_fn_error $? "conditional \"WITH_PCAP\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${PPP_WITH_FILTER_TRUE}" && test -z "${PPP_WITH_FILTER_FALSE}"; then as_fn_error $? "conditional \"PPP_WITH_FILTER\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${WITH_GTK_TRUE}" && test -z "${WITH_GTK_FALSE}"; then as_fn_error $? "conditional \"WITH_GTK\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi : "${CONFIG_STATUS=./config.status}" ac_write_fail=0 ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files $CONFIG_STATUS" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 printf "%s\n" "$as_me: creating $CONFIG_STATUS" >&6;} as_write_fail=0 cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 #! $SHELL # Generated by $as_me. # Run this file to recreate the current configuration. # Compiler output produced by configure, useful for debugging # configure, is in config.log if it exists. debug=false ac_cs_recheck=false ac_cs_silent=false SHELL=\${CONFIG_SHELL-$SHELL} export SHELL _ASEOF cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh as_nop=: if test ${ZSH_VERSION+y} && (emulate sh) >/dev/null 2>&1 then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else $as_nop case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi # Reset variables that may have inherited troublesome values from # the environment. # IFS needs to be set, to space, tab, and newline, in precisely that order. # (If _AS_PATH_WALK were called with IFS unset, it would have the # side effect of setting IFS to empty, thus disabling word splitting.) # Quoting is to prevent editors from complaining about space-tab. as_nl=' ' export as_nl IFS=" "" $as_nl" PS1='$ ' PS2='> ' PS4='+ ' # Ensure predictable behavior from utilities with locale-dependent output. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # We cannot yet rely on "unset" to work, but we need these variables # to be unset--not just set to an empty or harmless value--now, to # avoid bugs in old shells (e.g. pre-3.0 UWIN ksh). This construct # also avoids known problems related to "unset" and subshell syntax # in other old shells (e.g. bash 2.01 and pdksh 5.2.14). for as_var in BASH_ENV ENV MAIL MAILPATH CDPATH do eval test \${$as_var+y} \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done # Ensure that fds 0, 1, and 2 are open. if (exec 3>&0) 2>/dev/null; then :; else exec 0&1) 2>/dev/null; then :; else exec 1>/dev/null; fi if (exec 3>&2) ; then :; else exec 2>/dev/null; fi # The user is always right. if ${PATH_SEPARATOR+false} :; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac test -r "$as_dir$0" && as_myself=$as_dir$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then printf "%s\n" "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi printf "%s\n" "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null then : eval 'as_fn_append () { eval $1+=\$2 }' else $as_nop as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null then : eval 'as_fn_arith () { as_val=$(( $* )) }' else $as_nop as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || printf "%s\n" X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits # Determine whether it's possible to make 'echo' print without a newline. # These variables are no longer used directly by Autoconf, but are AC_SUBSTed # for compatibility with existing Makefiles. ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac # For backward compatibility with old third-party macros, we provide # the shell variables $as_echo and $as_echo_n. New code should use # AS_ECHO(["message"]) and AS_ECHO_N(["message"]), respectively. as_echo='printf %s\n' as_echo_n='printf %s' rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -pR' fi else as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`printf "%s\n" "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || printf "%s\n" X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi # as_fn_executable_p FILE # ----------------------- # Test if FILE is an executable regular file. as_fn_executable_p () { test -f "$1" && test -x "$1" } # as_fn_executable_p as_test_x='test -x' as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" exec 6>&1 ## ----------------------------------- ## ## Main body of $CONFIG_STATUS script. ## ## ----------------------------------- ## _ASEOF test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Save the log message, to keep $0 and so on meaningful, and to # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" This file was extended by ppp $as_me 2.5.0, which was generated by GNU Autoconf 2.71. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS CONFIG_LINKS = $CONFIG_LINKS CONFIG_COMMANDS = $CONFIG_COMMANDS $ $0 $@ on `(hostname || uname -n) 2>/dev/null | sed 1q` " _ACEOF case $ac_config_files in *" "*) set x $ac_config_files; shift; ac_config_files=$*;; esac case $ac_config_headers in *" "*) set x $ac_config_headers; shift; ac_config_headers=$*;; esac cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # Files that config.status was made for. config_files="$ac_config_files" config_headers="$ac_config_headers" config_commands="$ac_config_commands" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 ac_cs_usage="\ \`$as_me' instantiates files and other configuration actions from templates according to the current configuration. Unless the files and actions are specified as TAGs, all are instantiated by default. Usage: $0 [OPTION]... [TAG]... -h, --help print this help, then exit -V, --version print version number and configuration settings, then exit --config print configuration, then exit -q, --quiet, --silent do not print progress messages -d, --debug don't remove temporary files --recheck update $as_me by reconfiguring in the same conditions --file=FILE[:TEMPLATE] instantiate the configuration file FILE --header=FILE[:TEMPLATE] instantiate the configuration header FILE Configuration files: $config_files Configuration headers: $config_headers Configuration commands: $config_commands Report bugs to ." _ACEOF ac_cs_config=`printf "%s\n" "$ac_configure_args" | sed "$ac_safe_unquote"` ac_cs_config_escaped=`printf "%s\n" "$ac_cs_config" | sed "s/^ //; s/'/'\\\\\\\\''/g"` cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config='$ac_cs_config_escaped' ac_cs_version="\\ ppp config.status 2.5.0 configured by $0, generated by GNU Autoconf 2.71, with options \\"\$ac_cs_config\\" Copyright (C) 2021 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." ac_pwd='$ac_pwd' srcdir='$srcdir' INSTALL='$INSTALL' MKDIR_P='$MKDIR_P' AWK='$AWK' test -n "\$AWK" || AWK=awk _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # The default lists apply if the user does not specify any file. ac_need_defaults=: while test $# != 0 do case $1 in --*=?*) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` ac_shift=: ;; --*=) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg= ac_shift=: ;; *) ac_option=$1 ac_optarg=$2 ac_shift=shift ;; esac case $ac_option in # Handling of the options. -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) ac_cs_recheck=: ;; --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) printf "%s\n" "$ac_cs_version"; exit ;; --config | --confi | --conf | --con | --co | --c ) printf "%s\n" "$ac_cs_config"; exit ;; --debug | --debu | --deb | --de | --d | -d ) debug=: ;; --file | --fil | --fi | --f ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`printf "%s\n" "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; '') as_fn_error $? "missing file argument" ;; esac as_fn_append CONFIG_FILES " '$ac_optarg'" ac_need_defaults=false;; --header | --heade | --head | --hea ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`printf "%s\n" "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; esac as_fn_append CONFIG_HEADERS " '$ac_optarg'" ac_need_defaults=false;; --he | --h) # Conflict between --help and --header as_fn_error $? "ambiguous option: \`$1' Try \`$0 --help' for more information.";; --help | --hel | -h ) printf "%s\n" "$ac_cs_usage"; exit ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil | --si | --s) ac_cs_silent=: ;; # This is an error. -*) as_fn_error $? "unrecognized option: \`$1' Try \`$0 --help' for more information." ;; *) as_fn_append ac_config_targets " $1" ac_need_defaults=false ;; esac shift done ac_configure_extra_args= if $ac_cs_silent; then exec 6>/dev/null ac_configure_extra_args="$ac_configure_extra_args --silent" fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 if \$ac_cs_recheck; then set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion shift \printf "%s\n" "running CONFIG_SHELL=$SHELL \$*" >&6 CONFIG_SHELL='$SHELL' export CONFIG_SHELL exec "\$@" fi _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 exec 5>>config.log { echo sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX ## Running $as_me. ## _ASBOX printf "%s\n" "$ac_log" } >&5 _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # # INIT-COMMANDS # AMDEP_TRUE="$AMDEP_TRUE" MAKE="${MAKE-make}" # The HP-UX ksh and POSIX shell print the target directory to stdout # if CDPATH is set. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH sed_quote_subst='$sed_quote_subst' double_quote_subst='$double_quote_subst' delay_variable_subst='$delay_variable_subst' enable_static='`$ECHO "$enable_static" | $SED "$delay_single_quote_subst"`' macro_version='`$ECHO "$macro_version" | $SED "$delay_single_quote_subst"`' macro_revision='`$ECHO "$macro_revision" | $SED "$delay_single_quote_subst"`' enable_shared='`$ECHO "$enable_shared" | $SED "$delay_single_quote_subst"`' pic_mode='`$ECHO "$pic_mode" | $SED "$delay_single_quote_subst"`' enable_fast_install='`$ECHO "$enable_fast_install" | $SED "$delay_single_quote_subst"`' shared_archive_member_spec='`$ECHO "$shared_archive_member_spec" | $SED "$delay_single_quote_subst"`' SHELL='`$ECHO "$SHELL" | $SED "$delay_single_quote_subst"`' ECHO='`$ECHO "$ECHO" | $SED "$delay_single_quote_subst"`' PATH_SEPARATOR='`$ECHO "$PATH_SEPARATOR" | $SED "$delay_single_quote_subst"`' host_alias='`$ECHO "$host_alias" | $SED "$delay_single_quote_subst"`' host='`$ECHO "$host" | $SED "$delay_single_quote_subst"`' host_os='`$ECHO "$host_os" | $SED "$delay_single_quote_subst"`' build_alias='`$ECHO "$build_alias" | $SED "$delay_single_quote_subst"`' build='`$ECHO "$build" | $SED "$delay_single_quote_subst"`' build_os='`$ECHO "$build_os" | $SED "$delay_single_quote_subst"`' SED='`$ECHO "$SED" | $SED "$delay_single_quote_subst"`' Xsed='`$ECHO "$Xsed" | $SED "$delay_single_quote_subst"`' GREP='`$ECHO "$GREP" | $SED "$delay_single_quote_subst"`' EGREP='`$ECHO "$EGREP" | $SED "$delay_single_quote_subst"`' FGREP='`$ECHO "$FGREP" | $SED "$delay_single_quote_subst"`' LD='`$ECHO "$LD" | $SED "$delay_single_quote_subst"`' NM='`$ECHO "$NM" | $SED "$delay_single_quote_subst"`' LN_S='`$ECHO "$LN_S" | $SED "$delay_single_quote_subst"`' max_cmd_len='`$ECHO "$max_cmd_len" | $SED "$delay_single_quote_subst"`' ac_objext='`$ECHO "$ac_objext" | $SED "$delay_single_quote_subst"`' exeext='`$ECHO "$exeext" | $SED "$delay_single_quote_subst"`' lt_unset='`$ECHO "$lt_unset" | $SED "$delay_single_quote_subst"`' lt_SP2NL='`$ECHO "$lt_SP2NL" | $SED "$delay_single_quote_subst"`' lt_NL2SP='`$ECHO "$lt_NL2SP" | $SED "$delay_single_quote_subst"`' lt_cv_to_host_file_cmd='`$ECHO "$lt_cv_to_host_file_cmd" | $SED "$delay_single_quote_subst"`' lt_cv_to_tool_file_cmd='`$ECHO "$lt_cv_to_tool_file_cmd" | $SED "$delay_single_quote_subst"`' reload_flag='`$ECHO "$reload_flag" | $SED "$delay_single_quote_subst"`' reload_cmds='`$ECHO "$reload_cmds" | $SED "$delay_single_quote_subst"`' FILECMD='`$ECHO "$FILECMD" | $SED "$delay_single_quote_subst"`' OBJDUMP='`$ECHO "$OBJDUMP" | $SED "$delay_single_quote_subst"`' deplibs_check_method='`$ECHO "$deplibs_check_method" | $SED "$delay_single_quote_subst"`' file_magic_cmd='`$ECHO "$file_magic_cmd" | $SED "$delay_single_quote_subst"`' file_magic_glob='`$ECHO "$file_magic_glob" | $SED "$delay_single_quote_subst"`' want_nocaseglob='`$ECHO "$want_nocaseglob" | $SED "$delay_single_quote_subst"`' DLLTOOL='`$ECHO "$DLLTOOL" | $SED "$delay_single_quote_subst"`' sharedlib_from_linklib_cmd='`$ECHO "$sharedlib_from_linklib_cmd" | $SED "$delay_single_quote_subst"`' AR='`$ECHO "$AR" | $SED "$delay_single_quote_subst"`' lt_ar_flags='`$ECHO "$lt_ar_flags" | $SED "$delay_single_quote_subst"`' AR_FLAGS='`$ECHO "$AR_FLAGS" | $SED "$delay_single_quote_subst"`' archiver_list_spec='`$ECHO "$archiver_list_spec" | $SED "$delay_single_quote_subst"`' STRIP='`$ECHO "$STRIP" | $SED "$delay_single_quote_subst"`' RANLIB='`$ECHO "$RANLIB" | $SED "$delay_single_quote_subst"`' old_postinstall_cmds='`$ECHO "$old_postinstall_cmds" | $SED "$delay_single_quote_subst"`' old_postuninstall_cmds='`$ECHO "$old_postuninstall_cmds" | $SED "$delay_single_quote_subst"`' old_archive_cmds='`$ECHO "$old_archive_cmds" | $SED "$delay_single_quote_subst"`' lock_old_archive_extraction='`$ECHO "$lock_old_archive_extraction" | $SED "$delay_single_quote_subst"`' CC='`$ECHO "$CC" | $SED "$delay_single_quote_subst"`' CFLAGS='`$ECHO "$CFLAGS" | $SED "$delay_single_quote_subst"`' compiler='`$ECHO "$compiler" | $SED "$delay_single_quote_subst"`' GCC='`$ECHO "$GCC" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_pipe='`$ECHO "$lt_cv_sys_global_symbol_pipe" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_to_cdecl='`$ECHO "$lt_cv_sys_global_symbol_to_cdecl" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_to_import='`$ECHO "$lt_cv_sys_global_symbol_to_import" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $SED "$delay_single_quote_subst"`' lt_cv_nm_interface='`$ECHO "$lt_cv_nm_interface" | $SED "$delay_single_quote_subst"`' nm_file_list_spec='`$ECHO "$nm_file_list_spec" | $SED "$delay_single_quote_subst"`' lt_sysroot='`$ECHO "$lt_sysroot" | $SED "$delay_single_quote_subst"`' lt_cv_truncate_bin='`$ECHO "$lt_cv_truncate_bin" | $SED "$delay_single_quote_subst"`' objdir='`$ECHO "$objdir" | $SED "$delay_single_quote_subst"`' MAGIC_CMD='`$ECHO "$MAGIC_CMD" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_no_builtin_flag='`$ECHO "$lt_prog_compiler_no_builtin_flag" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_pic='`$ECHO "$lt_prog_compiler_pic" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_wl='`$ECHO "$lt_prog_compiler_wl" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_static='`$ECHO "$lt_prog_compiler_static" | $SED "$delay_single_quote_subst"`' lt_cv_prog_compiler_c_o='`$ECHO "$lt_cv_prog_compiler_c_o" | $SED "$delay_single_quote_subst"`' need_locks='`$ECHO "$need_locks" | $SED "$delay_single_quote_subst"`' MANIFEST_TOOL='`$ECHO "$MANIFEST_TOOL" | $SED "$delay_single_quote_subst"`' DSYMUTIL='`$ECHO "$DSYMUTIL" | $SED "$delay_single_quote_subst"`' NMEDIT='`$ECHO "$NMEDIT" | $SED "$delay_single_quote_subst"`' LIPO='`$ECHO "$LIPO" | $SED "$delay_single_quote_subst"`' OTOOL='`$ECHO "$OTOOL" | $SED "$delay_single_quote_subst"`' OTOOL64='`$ECHO "$OTOOL64" | $SED "$delay_single_quote_subst"`' libext='`$ECHO "$libext" | $SED "$delay_single_quote_subst"`' shrext_cmds='`$ECHO "$shrext_cmds" | $SED "$delay_single_quote_subst"`' extract_expsyms_cmds='`$ECHO "$extract_expsyms_cmds" | $SED "$delay_single_quote_subst"`' archive_cmds_need_lc='`$ECHO "$archive_cmds_need_lc" | $SED "$delay_single_quote_subst"`' enable_shared_with_static_runtimes='`$ECHO "$enable_shared_with_static_runtimes" | $SED "$delay_single_quote_subst"`' export_dynamic_flag_spec='`$ECHO "$export_dynamic_flag_spec" | $SED "$delay_single_quote_subst"`' whole_archive_flag_spec='`$ECHO "$whole_archive_flag_spec" | $SED "$delay_single_quote_subst"`' compiler_needs_object='`$ECHO "$compiler_needs_object" | $SED "$delay_single_quote_subst"`' old_archive_from_new_cmds='`$ECHO "$old_archive_from_new_cmds" | $SED "$delay_single_quote_subst"`' old_archive_from_expsyms_cmds='`$ECHO "$old_archive_from_expsyms_cmds" | $SED "$delay_single_quote_subst"`' archive_cmds='`$ECHO "$archive_cmds" | $SED "$delay_single_quote_subst"`' archive_expsym_cmds='`$ECHO "$archive_expsym_cmds" | $SED "$delay_single_quote_subst"`' module_cmds='`$ECHO "$module_cmds" | $SED "$delay_single_quote_subst"`' module_expsym_cmds='`$ECHO "$module_expsym_cmds" | $SED "$delay_single_quote_subst"`' with_gnu_ld='`$ECHO "$with_gnu_ld" | $SED "$delay_single_quote_subst"`' allow_undefined_flag='`$ECHO "$allow_undefined_flag" | $SED "$delay_single_quote_subst"`' no_undefined_flag='`$ECHO "$no_undefined_flag" | $SED "$delay_single_quote_subst"`' hardcode_libdir_flag_spec='`$ECHO "$hardcode_libdir_flag_spec" | $SED "$delay_single_quote_subst"`' hardcode_libdir_separator='`$ECHO "$hardcode_libdir_separator" | $SED "$delay_single_quote_subst"`' hardcode_direct='`$ECHO "$hardcode_direct" | $SED "$delay_single_quote_subst"`' hardcode_direct_absolute='`$ECHO "$hardcode_direct_absolute" | $SED "$delay_single_quote_subst"`' hardcode_minus_L='`$ECHO "$hardcode_minus_L" | $SED "$delay_single_quote_subst"`' hardcode_shlibpath_var='`$ECHO "$hardcode_shlibpath_var" | $SED "$delay_single_quote_subst"`' hardcode_automatic='`$ECHO "$hardcode_automatic" | $SED "$delay_single_quote_subst"`' inherit_rpath='`$ECHO "$inherit_rpath" | $SED "$delay_single_quote_subst"`' link_all_deplibs='`$ECHO "$link_all_deplibs" | $SED "$delay_single_quote_subst"`' always_export_symbols='`$ECHO "$always_export_symbols" | $SED "$delay_single_quote_subst"`' export_symbols_cmds='`$ECHO "$export_symbols_cmds" | $SED "$delay_single_quote_subst"`' exclude_expsyms='`$ECHO "$exclude_expsyms" | $SED "$delay_single_quote_subst"`' include_expsyms='`$ECHO "$include_expsyms" | $SED "$delay_single_quote_subst"`' prelink_cmds='`$ECHO "$prelink_cmds" | $SED "$delay_single_quote_subst"`' postlink_cmds='`$ECHO "$postlink_cmds" | $SED "$delay_single_quote_subst"`' file_list_spec='`$ECHO "$file_list_spec" | $SED "$delay_single_quote_subst"`' variables_saved_for_relink='`$ECHO "$variables_saved_for_relink" | $SED "$delay_single_quote_subst"`' need_lib_prefix='`$ECHO "$need_lib_prefix" | $SED "$delay_single_quote_subst"`' need_version='`$ECHO "$need_version" | $SED "$delay_single_quote_subst"`' version_type='`$ECHO "$version_type" | $SED "$delay_single_quote_subst"`' runpath_var='`$ECHO "$runpath_var" | $SED "$delay_single_quote_subst"`' shlibpath_var='`$ECHO "$shlibpath_var" | $SED "$delay_single_quote_subst"`' shlibpath_overrides_runpath='`$ECHO "$shlibpath_overrides_runpath" | $SED "$delay_single_quote_subst"`' libname_spec='`$ECHO "$libname_spec" | $SED "$delay_single_quote_subst"`' library_names_spec='`$ECHO "$library_names_spec" | $SED "$delay_single_quote_subst"`' soname_spec='`$ECHO "$soname_spec" | $SED "$delay_single_quote_subst"`' install_override_mode='`$ECHO "$install_override_mode" | $SED "$delay_single_quote_subst"`' postinstall_cmds='`$ECHO "$postinstall_cmds" | $SED "$delay_single_quote_subst"`' postuninstall_cmds='`$ECHO "$postuninstall_cmds" | $SED "$delay_single_quote_subst"`' finish_cmds='`$ECHO "$finish_cmds" | $SED "$delay_single_quote_subst"`' finish_eval='`$ECHO "$finish_eval" | $SED "$delay_single_quote_subst"`' hardcode_into_libs='`$ECHO "$hardcode_into_libs" | $SED "$delay_single_quote_subst"`' sys_lib_search_path_spec='`$ECHO "$sys_lib_search_path_spec" | $SED "$delay_single_quote_subst"`' configure_time_dlsearch_path='`$ECHO "$configure_time_dlsearch_path" | $SED "$delay_single_quote_subst"`' configure_time_lt_sys_library_path='`$ECHO "$configure_time_lt_sys_library_path" | $SED "$delay_single_quote_subst"`' hardcode_action='`$ECHO "$hardcode_action" | $SED "$delay_single_quote_subst"`' enable_dlopen='`$ECHO "$enable_dlopen" | $SED "$delay_single_quote_subst"`' enable_dlopen_self='`$ECHO "$enable_dlopen_self" | $SED "$delay_single_quote_subst"`' enable_dlopen_self_static='`$ECHO "$enable_dlopen_self_static" | $SED "$delay_single_quote_subst"`' old_striplib='`$ECHO "$old_striplib" | $SED "$delay_single_quote_subst"`' striplib='`$ECHO "$striplib" | $SED "$delay_single_quote_subst"`' LTCC='$LTCC' LTCFLAGS='$LTCFLAGS' compiler='$compiler_DEFAULT' # A function that is used when there is no print builtin or printf. func_fallback_echo () { eval 'cat <<_LTECHO_EOF \$1 _LTECHO_EOF' } # Quote evaled strings. for var in SHELL \ ECHO \ PATH_SEPARATOR \ SED \ GREP \ EGREP \ FGREP \ LD \ NM \ LN_S \ lt_SP2NL \ lt_NL2SP \ reload_flag \ FILECMD \ OBJDUMP \ deplibs_check_method \ file_magic_cmd \ file_magic_glob \ want_nocaseglob \ DLLTOOL \ sharedlib_from_linklib_cmd \ AR \ archiver_list_spec \ STRIP \ RANLIB \ CC \ CFLAGS \ compiler \ lt_cv_sys_global_symbol_pipe \ lt_cv_sys_global_symbol_to_cdecl \ lt_cv_sys_global_symbol_to_import \ lt_cv_sys_global_symbol_to_c_name_address \ lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \ lt_cv_nm_interface \ nm_file_list_spec \ lt_cv_truncate_bin \ lt_prog_compiler_no_builtin_flag \ lt_prog_compiler_pic \ lt_prog_compiler_wl \ lt_prog_compiler_static \ lt_cv_prog_compiler_c_o \ need_locks \ MANIFEST_TOOL \ DSYMUTIL \ NMEDIT \ LIPO \ OTOOL \ OTOOL64 \ shrext_cmds \ export_dynamic_flag_spec \ whole_archive_flag_spec \ compiler_needs_object \ with_gnu_ld \ allow_undefined_flag \ no_undefined_flag \ hardcode_libdir_flag_spec \ hardcode_libdir_separator \ exclude_expsyms \ include_expsyms \ file_list_spec \ variables_saved_for_relink \ libname_spec \ library_names_spec \ soname_spec \ install_override_mode \ finish_eval \ old_striplib \ striplib; do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[\\\\\\\`\\"\\\$]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done # Double-quote double-evaled strings. for var in reload_cmds \ old_postinstall_cmds \ old_postuninstall_cmds \ old_archive_cmds \ extract_expsyms_cmds \ old_archive_from_new_cmds \ old_archive_from_expsyms_cmds \ archive_cmds \ archive_expsym_cmds \ module_cmds \ module_expsym_cmds \ export_symbols_cmds \ prelink_cmds \ postlink_cmds \ postinstall_cmds \ postuninstall_cmds \ finish_cmds \ sys_lib_search_path_spec \ configure_time_dlsearch_path \ configure_time_lt_sys_library_path; do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[\\\\\\\`\\"\\\$]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done ac_aux_dir='$ac_aux_dir' # See if we are running on zsh, and set the options that allow our # commands through without removal of \ escapes INIT. if test -n "\${ZSH_VERSION+set}"; then setopt NO_GLOB_SUBST fi PACKAGE='$PACKAGE' VERSION='$VERSION' RM='$RM' ofile='$ofile' _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Handling of arguments. for ac_config_target in $ac_config_targets do case $ac_config_target in "pppd/config.h") CONFIG_HEADERS="$CONFIG_HEADERS pppd/config.h" ;; "pppd/pppdconf.h") CONFIG_HEADERS="$CONFIG_HEADERS pppd/pppdconf.h" ;; "pppd/plugins/pppoe/config.h") CONFIG_HEADERS="$CONFIG_HEADERS pppd/plugins/pppoe/config.h" ;; "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;; "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; "chat/Makefile") CONFIG_FILES="$CONFIG_FILES chat/Makefile" ;; "contrib/Makefile") CONFIG_FILES="$CONFIG_FILES contrib/Makefile" ;; "contrib/pppgetpass/Makefile") CONFIG_FILES="$CONFIG_FILES contrib/pppgetpass/Makefile" ;; "common/Makefile") CONFIG_FILES="$CONFIG_FILES common/Makefile" ;; "include/Makefile") CONFIG_FILES="$CONFIG_FILES include/Makefile" ;; "modules/Makefile") CONFIG_FILES="$CONFIG_FILES modules/Makefile" ;; "pppd/Makefile") CONFIG_FILES="$CONFIG_FILES pppd/Makefile" ;; "pppd/pppd.pc") CONFIG_FILES="$CONFIG_FILES pppd/pppd.pc" ;; "pppd/plugins/Makefile") CONFIG_FILES="$CONFIG_FILES pppd/plugins/Makefile" ;; "pppd/plugins/pppoe/Makefile") CONFIG_FILES="$CONFIG_FILES pppd/plugins/pppoe/Makefile" ;; "pppd/plugins/pppoatm/Makefile") CONFIG_FILES="$CONFIG_FILES pppd/plugins/pppoatm/Makefile" ;; "pppd/plugins/pppol2tp/Makefile") CONFIG_FILES="$CONFIG_FILES pppd/plugins/pppol2tp/Makefile" ;; "pppd/plugins/radius/Makefile") CONFIG_FILES="$CONFIG_FILES pppd/plugins/radius/Makefile" ;; "pppdump/Makefile") CONFIG_FILES="$CONFIG_FILES pppdump/Makefile" ;; "pppstats/Makefile") CONFIG_FILES="$CONFIG_FILES pppstats/Makefile" ;; "scripts/Makefile") CONFIG_FILES="$CONFIG_FILES scripts/Makefile" ;; *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; esac done # If the user did not use the arguments to specify the items to instantiate, # then the envvar interface is used. Set only those that are not. # We use the long form for the default assignment because of an extremely # bizarre bug on SunOS 4.1.3. if $ac_need_defaults; then test ${CONFIG_FILES+y} || CONFIG_FILES=$config_files test ${CONFIG_HEADERS+y} || CONFIG_HEADERS=$config_headers test ${CONFIG_COMMANDS+y} || CONFIG_COMMANDS=$config_commands fi # Have a temporary directory for convenience. Make it in the build tree # simply because there is no reason against having it here, and in addition, # creating and moving files from /tmp can sometimes cause problems. # Hook for its removal unless debugging. # Note that there is a small window in which the directory will not be cleaned: # after its creation but before its name has been assigned to `$tmp'. $debug || { tmp= ac_tmp= trap 'exit_status=$? : "${ac_tmp:=$tmp}" { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status ' 0 trap 'as_fn_exit 1' 1 2 13 15 } # Create a (secure) tmp directory for tmp files. { tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && test -d "$tmp" } || { tmp=./conf$$-$RANDOM (umask 077 && mkdir "$tmp") } || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 ac_tmp=$tmp # Set up the scripts for CONFIG_FILES section. # No need to generate them if there are no CONFIG_FILES. # This happens for instance with `./config.status config.h'. if test -n "$CONFIG_FILES"; then ac_cr=`echo X | tr X '\015'` # On cygwin, bash can eat \r inside `` if the user requested igncr. # But we know of no other shell where ac_cr would be empty at this # point, so we can use a bashism as a fallback. if test "x$ac_cr" = x; then eval ac_cr=\$\'\\r\' fi ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then ac_cs_awk_cr='\\r' else ac_cs_awk_cr=$ac_cr fi echo 'BEGIN {' >"$ac_tmp/subs1.awk" && _ACEOF { echo "cat >conf$$subs.awk <<_ACEOF" && echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && echo "_ACEOF" } >conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` ac_delim='%!_!# ' for ac_last_try in false false false false false :; do . ./conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` if test $ac_delim_n = $ac_delim_num; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done rm -f conf$$subs.sh cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && _ACEOF sed -n ' h s/^/S["/; s/!.*/"]=/ p g s/^[^!]*!// :repl t repl s/'"$ac_delim"'$// t delim :nl h s/\(.\{148\}\)..*/\1/ t more1 s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ p n b repl :more1 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t nl :delim h s/\(.\{148\}\)..*/\1/ t more2 s/["\\]/\\&/g; s/^/"/; s/$/"/ p b :more2 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t delim ' >$CONFIG_STATUS || ac_write_fail=1 rm -f conf$$subs.awk cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 _ACAWK cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && for (key in S) S_is_set[key] = 1 FS = "" } { line = $ 0 nfields = split(line, field, "@") substed = 0 len = length(field[1]) for (i = 2; i < nfields; i++) { key = field[i] keylen = length(key) if (S_is_set[key]) { value = S[key] line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) len += length(value) + length(field[++i]) substed = 1 } else len += 1 + keylen } print line } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" else cat fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 _ACEOF # VPATH may cause trouble with some makes, so we remove sole $(srcdir), # ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and # trailing colons and then remove the whole line if VPATH becomes empty # (actually we leave an empty line to preserve line numbers). if test "x$srcdir" = x.; then ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ h s/// s/^/:/ s/[ ]*$/:/ s/:\$(srcdir):/:/g s/:\${srcdir}:/:/g s/:@srcdir@:/:/g s/^:*// s/:*$// x s/\(=[ ]*\).*/\1/ G s/\n// s/^[^=]*=[ ]*$// }' fi cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 fi # test -n "$CONFIG_FILES" # Set up the scripts for CONFIG_HEADERS section. # No need to generate them if there are no CONFIG_HEADERS. # This happens for instance with `./config.status Makefile'. if test -n "$CONFIG_HEADERS"; then cat >"$ac_tmp/defines.awk" <<\_ACAWK || BEGIN { _ACEOF # Transform confdefs.h into an awk script `defines.awk', embedded as # here-document in config.status, that substitutes the proper values into # config.h.in to produce config.h. # Create a delimiter string that does not exist in confdefs.h, to ease # handling of long lines. ac_delim='%!_!# ' for ac_last_try in false false :; do ac_tt=`sed -n "/$ac_delim/p" confdefs.h` if test -z "$ac_tt"; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done # For the awk script, D is an array of macro values keyed by name, # likewise P contains macro parameters if any. Preserve backslash # newline sequences. ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* sed -n ' s/.\{148\}/&'"$ac_delim"'/g t rset :rset s/^[ ]*#[ ]*define[ ][ ]*/ / t def d :def s/\\$// t bsnl s/["\\]/\\&/g s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ D["\1"]=" \3"/p s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p d :bsnl s/["\\]/\\&/g s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ D["\1"]=" \3\\\\\\n"\\/p t cont s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p t cont d :cont n s/.\{148\}/&'"$ac_delim"'/g t clear :clear s/\\$// t bsnlc s/["\\]/\\&/g; s/^/"/; s/$/"/p d :bsnlc s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p b cont ' >$CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 for (key in D) D_is_set[key] = 1 FS = "" } /^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { line = \$ 0 split(line, arg, " ") if (arg[1] == "#") { defundef = arg[2] mac1 = arg[3] } else { defundef = substr(arg[1], 2) mac1 = arg[2] } split(mac1, mac2, "(") #) macro = mac2[1] prefix = substr(line, 1, index(line, defundef) - 1) if (D_is_set[macro]) { # Preserve the white space surrounding the "#". print prefix "define", macro P[macro] D[macro] next } else { # Replace #undef with comments. This is necessary, for example, # in the case of _POSIX_SOURCE, which is predefined and required # on some systems where configure will not decide to define it. if (defundef == "undef") { print "/*", prefix defundef, macro, "*/" next } } } { print } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 fi # test -n "$CONFIG_HEADERS" eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS" shift for ac_tag do case $ac_tag in :[FHLC]) ac_mode=$ac_tag; continue;; esac case $ac_mode$ac_tag in :[FHL]*:*);; :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; :[FH]-) ac_tag=-:-;; :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; esac ac_save_IFS=$IFS IFS=: set x $ac_tag IFS=$ac_save_IFS shift ac_file=$1 shift case $ac_mode in :L) ac_source=$1;; :[FH]) ac_file_inputs= for ac_f do case $ac_f in -) ac_f="$ac_tmp/stdin";; *) # Look for the file first in the build tree, then in the source tree # (if the path is not absolute). The absolute path cannot be DOS-style, # because $ac_f cannot contain `:'. test -f "$ac_f" || case $ac_f in [\\/$]*) false;; *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; esac || as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; esac case $ac_f in *\'*) ac_f=`printf "%s\n" "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac as_fn_append ac_file_inputs " '$ac_f'" done # Let's still pretend it is `configure' which instantiates (i.e., don't # use $as_me), people would be surprised to read: # /* config.h. Generated by config.status. */ configure_input='Generated from '` printf "%s\n" "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' `' by configure.' if test x"$ac_file" != x-; then configure_input="$ac_file. $configure_input" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 printf "%s\n" "$as_me: creating $ac_file" >&6;} fi # Neutralize special characters interpreted by sed in replacement strings. case $configure_input in #( *\&* | *\|* | *\\* ) ac_sed_conf_input=`printf "%s\n" "$configure_input" | sed 's/[\\\\&|]/\\\\&/g'`;; #( *) ac_sed_conf_input=$configure_input;; esac case $ac_tag in *:-:* | *:-) cat >"$ac_tmp/stdin" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; esac ;; esac ac_dir=`$as_dirname -- "$ac_file" || $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_file" : 'X\(//\)[^/]' \| \ X"$ac_file" : 'X\(//\)$' \| \ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || printf "%s\n" X"$ac_file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` as_dir="$ac_dir"; as_fn_mkdir_p ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`printf "%s\n" "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`printf "%s\n" "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix case $ac_mode in :F) # # CONFIG_FILE # case $INSTALL in [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; esac ac_MKDIR_P=$MKDIR_P case $MKDIR_P in [\\/$]* | ?:[\\/]* ) ;; */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; esac _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # If the template does not know about datarootdir, expand it. # FIXME: This hack should be removed a few years after 2.60. ac_datarootdir_hack=; ac_datarootdir_seen= ac_sed_dataroot=' /datarootdir/ { p q } /@datadir@/p /@docdir@/p /@infodir@/p /@localedir@/p /@mandir@/p' case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in *datarootdir*) ac_datarootdir_seen=yes;; *@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 printf "%s\n" "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_datarootdir_hack=' s&@datadir@&$datadir&g s&@docdir@&$docdir&g s&@infodir@&$infodir&g s&@localedir@&$localedir&g s&@mandir@&$mandir&g s&\\\${datarootdir}&$datarootdir&g' ;; esac _ACEOF # Neutralize VPATH when `$srcdir' = `.'. # Shell code in configure.ac might set extrasub. # FIXME: do we really want to maintain this feature? cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_sed_extra="$ac_vpsub $extrasub _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 :t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b s|@configure_input@|$ac_sed_conf_input|;t t s&@top_builddir@&$ac_top_builddir_sub&;t t s&@top_build_prefix@&$ac_top_build_prefix&;t t s&@srcdir@&$ac_srcdir&;t t s&@abs_srcdir@&$ac_abs_srcdir&;t t s&@top_srcdir@&$ac_top_srcdir&;t t s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t s&@builddir@&$ac_builddir&;t t s&@abs_builddir@&$ac_abs_builddir&;t t s&@abs_top_builddir@&$ac_abs_top_builddir&;t t s&@INSTALL@&$ac_INSTALL&;t t s&@MKDIR_P@&$ac_MKDIR_P&;t t $ac_datarootdir_hack " eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ "$ac_tmp/out"`; test -z "$ac_out"; } && { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&5 printf "%s\n" "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&2;} rm -f "$ac_tmp/stdin" case $ac_file in -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; esac \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; :H) # # CONFIG_HEADER # if test x"$ac_file" != x-; then { printf "%s\n" "/* $configure_input */" >&1 \ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" } >"$ac_tmp/config.h" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 printf "%s\n" "$as_me: $ac_file is unchanged" >&6;} else rm -f "$ac_file" mv "$ac_tmp/config.h" "$ac_file" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 fi else printf "%s\n" "/* $configure_input */" >&1 \ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ || as_fn_error $? "could not create -" "$LINENO" 5 fi # Compute "$ac_file"'s index in $config_headers. _am_arg="$ac_file" _am_stamp_count=1 for _am_header in $config_headers :; do case $_am_header in $_am_arg | $_am_arg:* ) break ;; * ) _am_stamp_count=`expr $_am_stamp_count + 1` ;; esac done echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" || $as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$_am_arg" : 'X\(//\)[^/]' \| \ X"$_am_arg" : 'X\(//\)$' \| \ X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null || printf "%s\n" X"$_am_arg" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'`/stamp-h$_am_stamp_count ;; :C) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 printf "%s\n" "$as_me: executing $ac_file commands" >&6;} ;; esac case $ac_file$ac_mode in "depfiles":C) test x"$AMDEP_TRUE" != x"" || { # Older Autoconf quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. # TODO: see whether this extra hack can be removed once we start # requiring Autoconf 2.70 or later. case $CONFIG_FILES in #( *\'*) : eval set x "$CONFIG_FILES" ;; #( *) : set x $CONFIG_FILES ;; #( *) : ;; esac shift # Used to flag and report bootstrapping failures. am_rc=0 for am_mf do # Strip MF so we end up with the name of the file. am_mf=`printf "%s\n" "$am_mf" | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile which includes # dependency-tracking related rules and includes. # Grep'ing the whole file directly is not great: AIX grep has a line # limit of 2048, but all sed's we know have understand at least 4000. sed -n 's,^am--depfiles:.*,X,p' "$am_mf" | grep X >/dev/null 2>&1 \ || continue am_dirpart=`$as_dirname -- "$am_mf" || $as_expr X"$am_mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$am_mf" : 'X\(//\)[^/]' \| \ X"$am_mf" : 'X\(//\)$' \| \ X"$am_mf" : 'X\(/\)' \| . 2>/dev/null || printf "%s\n" X"$am_mf" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` am_filepart=`$as_basename -- "$am_mf" || $as_expr X/"$am_mf" : '.*/\([^/][^/]*\)/*$' \| \ X"$am_mf" : 'X\(//\)$' \| \ X"$am_mf" : 'X\(/\)' \| . 2>/dev/null || printf "%s\n" X/"$am_mf" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` { echo "$as_me:$LINENO: cd "$am_dirpart" \ && sed -e '/# am--include-marker/d' "$am_filepart" \ | $MAKE -f - am--depfiles" >&5 (cd "$am_dirpart" \ && sed -e '/# am--include-marker/d' "$am_filepart" \ | $MAKE -f - am--depfiles) >&5 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } || am_rc=$? done if test $am_rc -ne 0; then { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "Something went wrong bootstrapping makefile fragments for automatic dependency tracking. If GNU make was not used, consider re-running the configure script with MAKE=\"gmake\" (or whatever is necessary). You can also try re-running configure with the '--disable-dependency-tracking' option to at least be able to build the package (albeit without support for automatic dependency tracking). See \`config.log' for more details" "$LINENO" 5; } fi { am_dirpart=; unset am_dirpart;} { am_filepart=; unset am_filepart;} { am_mf=; unset am_mf;} { am_rc=; unset am_rc;} rm -f conftest-deps.mk } ;; "libtool":C) # See if we are running on zsh, and set the options that allow our # commands through without removal of \ escapes. if test -n "${ZSH_VERSION+set}"; then setopt NO_GLOB_SUBST fi cfgfile=${ofile}T trap "$RM \"$cfgfile\"; exit 1" 1 2 15 $RM "$cfgfile" cat <<_LT_EOF >> "$cfgfile" #! $SHELL # Generated automatically by $as_me ($PACKAGE) $VERSION # Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: # NOTE: Changes made to this file will be lost: look at ltmain.sh. # Provide generalized library-building support services. # Written by Gordon Matzigkeit, 1996 # Copyright (C) 2014 Free Software Foundation, Inc. # This is free software; see the source for copying conditions. There is NO # warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # GNU Libtool is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of of the License, or # (at your option) any later version. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program or library that is built # using GNU Libtool, you may include this file under the same # distribution terms that you use for the rest of that program. # # GNU Libtool is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # The names of the tagged configurations supported by this script. available_tags='' # Configured defaults for sys_lib_dlsearch_path munging. : \${LT_SYS_LIBRARY_PATH="$configure_time_lt_sys_library_path"} # ### BEGIN LIBTOOL CONFIG # Whether or not to build static libraries. build_old_libs=$enable_static # Which release of libtool.m4 was used? macro_version=$macro_version macro_revision=$macro_revision # Whether or not to build shared libraries. build_libtool_libs=$enable_shared # What type of objects to build. pic_mode=$pic_mode # Whether or not to optimize for fast installation. fast_install=$enable_fast_install # Shared archive member basename,for filename based shared library versioning on AIX. shared_archive_member_spec=$shared_archive_member_spec # Shell to use when invoking shell scripts. SHELL=$lt_SHELL # An echo program that protects backslashes. ECHO=$lt_ECHO # The PATH separator for the build system. PATH_SEPARATOR=$lt_PATH_SEPARATOR # The host system. host_alias=$host_alias host=$host host_os=$host_os # The build system. build_alias=$build_alias build=$build build_os=$build_os # A sed program that does not truncate output. SED=$lt_SED # Sed that helps us avoid accidentally triggering echo(1) options like -n. Xsed="\$SED -e 1s/^X//" # A grep program that handles long lines. GREP=$lt_GREP # An ERE matcher. EGREP=$lt_EGREP # A literal string matcher. FGREP=$lt_FGREP # A BSD- or MS-compatible name lister. NM=$lt_NM # Whether we need soft or hard links. LN_S=$lt_LN_S # What is the maximum length of a command? max_cmd_len=$max_cmd_len # Object file suffix (normally "o"). objext=$ac_objext # Executable file suffix (normally ""). exeext=$exeext # whether the shell understands "unset". lt_unset=$lt_unset # turn spaces into newlines. SP2NL=$lt_lt_SP2NL # turn newlines into spaces. NL2SP=$lt_lt_NL2SP # convert \$build file names to \$host format. to_host_file_cmd=$lt_cv_to_host_file_cmd # convert \$build files to toolchain format. to_tool_file_cmd=$lt_cv_to_tool_file_cmd # A file(cmd) program that detects file types. FILECMD=$lt_FILECMD # An object symbol dumper. OBJDUMP=$lt_OBJDUMP # Method to check whether dependent libraries are shared objects. deplibs_check_method=$lt_deplibs_check_method # Command to use when deplibs_check_method = "file_magic". file_magic_cmd=$lt_file_magic_cmd # How to find potential files when deplibs_check_method = "file_magic". file_magic_glob=$lt_file_magic_glob # Find potential files using nocaseglob when deplibs_check_method = "file_magic". want_nocaseglob=$lt_want_nocaseglob # DLL creation program. DLLTOOL=$lt_DLLTOOL # Command to associate shared and link libraries. sharedlib_from_linklib_cmd=$lt_sharedlib_from_linklib_cmd # The archiver. AR=$lt_AR # Flags to create an archive (by configure). lt_ar_flags=$lt_ar_flags # Flags to create an archive. AR_FLAGS=\${ARFLAGS-"\$lt_ar_flags"} # How to feed a file listing to the archiver. archiver_list_spec=$lt_archiver_list_spec # A symbol stripping program. STRIP=$lt_STRIP # Commands used to install an old-style archive. RANLIB=$lt_RANLIB old_postinstall_cmds=$lt_old_postinstall_cmds old_postuninstall_cmds=$lt_old_postuninstall_cmds # Whether to use a lock for old archive extraction. lock_old_archive_extraction=$lock_old_archive_extraction # A C compiler. LTCC=$lt_CC # LTCC compiler flags. LTCFLAGS=$lt_CFLAGS # Take the output of nm and produce a listing of raw symbols and C names. global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe # Transform the output of nm in a proper C declaration. global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl # Transform the output of nm into a list of symbols to manually relocate. global_symbol_to_import=$lt_lt_cv_sys_global_symbol_to_import # Transform the output of nm in a C name address pair. global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address # Transform the output of nm in a C name address pair when lib prefix is needed. global_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix # The name lister interface. nm_interface=$lt_lt_cv_nm_interface # Specify filename containing input files for \$NM. nm_file_list_spec=$lt_nm_file_list_spec # The root where to search for dependent libraries,and where our libraries should be installed. lt_sysroot=$lt_sysroot # Command to truncate a binary pipe. lt_truncate_bin=$lt_lt_cv_truncate_bin # The name of the directory that contains temporary libtool files. objdir=$objdir # Used to examine libraries when file_magic_cmd begins with "file". MAGIC_CMD=$MAGIC_CMD # Must we lock files when doing compilation? need_locks=$lt_need_locks # Manifest tool. MANIFEST_TOOL=$lt_MANIFEST_TOOL # Tool to manipulate archived DWARF debug symbol files on Mac OS X. DSYMUTIL=$lt_DSYMUTIL # Tool to change global to local symbols on Mac OS X. NMEDIT=$lt_NMEDIT # Tool to manipulate fat objects and archives on Mac OS X. LIPO=$lt_LIPO # ldd/readelf like tool for Mach-O binaries on Mac OS X. OTOOL=$lt_OTOOL # ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4. OTOOL64=$lt_OTOOL64 # Old archive suffix (normally "a"). libext=$libext # Shared library suffix (normally ".so"). shrext_cmds=$lt_shrext_cmds # The commands to extract the exported symbol list from a shared archive. extract_expsyms_cmds=$lt_extract_expsyms_cmds # Variables whose values should be saved in libtool wrapper scripts and # restored at link time. variables_saved_for_relink=$lt_variables_saved_for_relink # Do we need the "lib" prefix for modules? need_lib_prefix=$need_lib_prefix # Do we need a version for libraries? need_version=$need_version # Library versioning type. version_type=$version_type # Shared library runtime path variable. runpath_var=$runpath_var # Shared library path variable. shlibpath_var=$shlibpath_var # Is shlibpath searched before the hard-coded library search path? shlibpath_overrides_runpath=$shlibpath_overrides_runpath # Format of library name prefix. libname_spec=$lt_libname_spec # List of archive names. First name is the real one, the rest are links. # The last name is the one that the linker finds with -lNAME library_names_spec=$lt_library_names_spec # The coded name of the library, if different from the real name. soname_spec=$lt_soname_spec # Permission mode override for installation of shared libraries. install_override_mode=$lt_install_override_mode # Command to use after installation of a shared archive. postinstall_cmds=$lt_postinstall_cmds # Command to use after uninstallation of a shared archive. postuninstall_cmds=$lt_postuninstall_cmds # Commands used to finish a libtool library installation in a directory. finish_cmds=$lt_finish_cmds # As "finish_cmds", except a single script fragment to be evaled but # not shown. finish_eval=$lt_finish_eval # Whether we should hardcode library paths into libraries. hardcode_into_libs=$hardcode_into_libs # Compile-time system search path for libraries. sys_lib_search_path_spec=$lt_sys_lib_search_path_spec # Detected run-time system search path for libraries. sys_lib_dlsearch_path_spec=$lt_configure_time_dlsearch_path # Explicit LT_SYS_LIBRARY_PATH set during ./configure time. configure_time_lt_sys_library_path=$lt_configure_time_lt_sys_library_path # Whether dlopen is supported. dlopen_support=$enable_dlopen # Whether dlopen of programs is supported. dlopen_self=$enable_dlopen_self # Whether dlopen of statically linked programs is supported. dlopen_self_static=$enable_dlopen_self_static # Commands to strip libraries. old_striplib=$lt_old_striplib striplib=$lt_striplib # The linker used to build libraries. LD=$lt_LD # How to create reloadable object files. reload_flag=$lt_reload_flag reload_cmds=$lt_reload_cmds # Commands used to build an old-style archive. old_archive_cmds=$lt_old_archive_cmds # A language specific compiler. CC=$lt_compiler # Is the compiler the GNU compiler? with_gcc=$GCC # Compiler flag to turn off builtin functions. no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag # Additional compiler flags for building library objects. pic_flag=$lt_lt_prog_compiler_pic # How to pass a linker flag through the compiler. wl=$lt_lt_prog_compiler_wl # Compiler flag to prevent dynamic linking. link_static_flag=$lt_lt_prog_compiler_static # Does compiler simultaneously support -c and -o options? compiler_c_o=$lt_lt_cv_prog_compiler_c_o # Whether or not to add -lc for building shared libraries. build_libtool_need_lc=$archive_cmds_need_lc # Whether or not to disallow shared libs when runtime libs are static. allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes # Compiler flag to allow reflexive dlopens. export_dynamic_flag_spec=$lt_export_dynamic_flag_spec # Compiler flag to generate shared objects directly from archives. whole_archive_flag_spec=$lt_whole_archive_flag_spec # Whether the compiler copes with passing no objects directly. compiler_needs_object=$lt_compiler_needs_object # Create an old-style archive from a shared archive. old_archive_from_new_cmds=$lt_old_archive_from_new_cmds # Create a temporary old-style archive to link instead of a shared archive. old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds # Commands used to build a shared archive. archive_cmds=$lt_archive_cmds archive_expsym_cmds=$lt_archive_expsym_cmds # Commands used to build a loadable module if different from building # a shared archive. module_cmds=$lt_module_cmds module_expsym_cmds=$lt_module_expsym_cmds # Whether we are building with GNU ld or not. with_gnu_ld=$lt_with_gnu_ld # Flag that allows shared libraries with undefined symbols to be built. allow_undefined_flag=$lt_allow_undefined_flag # Flag that enforces no undefined symbols. no_undefined_flag=$lt_no_undefined_flag # Flag to hardcode \$libdir into a binary during linking. # This must work even if \$libdir does not exist hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec # Whether we need a single "-rpath" flag with a separated argument. hardcode_libdir_separator=$lt_hardcode_libdir_separator # Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes # DIR into the resulting binary. hardcode_direct=$hardcode_direct # Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes # DIR into the resulting binary and the resulting library dependency is # "absolute",i.e impossible to change by setting \$shlibpath_var if the # library is relocated. hardcode_direct_absolute=$hardcode_direct_absolute # Set to "yes" if using the -LDIR flag during linking hardcodes DIR # into the resulting binary. hardcode_minus_L=$hardcode_minus_L # Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR # into the resulting binary. hardcode_shlibpath_var=$hardcode_shlibpath_var # Set to "yes" if building a shared library automatically hardcodes DIR # into the library and all subsequent libraries and executables linked # against it. hardcode_automatic=$hardcode_automatic # Set to yes if linker adds runtime paths of dependent libraries # to runtime path list. inherit_rpath=$inherit_rpath # Whether libtool must link a program against all its dependency libraries. link_all_deplibs=$link_all_deplibs # Set to "yes" if exported symbols are required. always_export_symbols=$always_export_symbols # The commands to list exported symbols. export_symbols_cmds=$lt_export_symbols_cmds # Symbols that should not be listed in the preloaded symbols. exclude_expsyms=$lt_exclude_expsyms # Symbols that must always be exported. include_expsyms=$lt_include_expsyms # Commands necessary for linking programs (against libraries) with templates. prelink_cmds=$lt_prelink_cmds # Commands necessary for finishing linking programs. postlink_cmds=$lt_postlink_cmds # Specify filename containing input files. file_list_spec=$lt_file_list_spec # How to hardcode a shared library path into an executable. hardcode_action=$hardcode_action # ### END LIBTOOL CONFIG _LT_EOF cat <<'_LT_EOF' >> "$cfgfile" # ### BEGIN FUNCTIONS SHARED WITH CONFIGURE # func_munge_path_list VARIABLE PATH # ----------------------------------- # VARIABLE is name of variable containing _space_ separated list of # directories to be munged by the contents of PATH, which is string # having a format: # "DIR[:DIR]:" # string "DIR[ DIR]" will be prepended to VARIABLE # ":DIR[:DIR]" # string "DIR[ DIR]" will be appended to VARIABLE # "DIRP[:DIRP]::[DIRA:]DIRA" # string "DIRP[ DIRP]" will be prepended to VARIABLE and string # "DIRA[ DIRA]" will be appended to VARIABLE # "DIR[:DIR]" # VARIABLE will be replaced by "DIR[ DIR]" func_munge_path_list () { case x$2 in x) ;; *:) eval $1=\"`$ECHO $2 | $SED 's/:/ /g'` \$$1\" ;; x:*) eval $1=\"\$$1 `$ECHO $2 | $SED 's/:/ /g'`\" ;; *::*) eval $1=\"\$$1\ `$ECHO $2 | $SED -e 's/.*:://' -e 's/:/ /g'`\" eval $1=\"`$ECHO $2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \$$1\" ;; *) eval $1=\"`$ECHO $2 | $SED 's/:/ /g'`\" ;; esac } # Calculate cc_basename. Skip known compiler wrappers and cross-prefix. func_cc_basename () { for cc_temp in $*""; do case $cc_temp in compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; \-*) ;; *) break;; esac done func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` } # ### END FUNCTIONS SHARED WITH CONFIGURE _LT_EOF case $host_os in aix3*) cat <<\_LT_EOF >> "$cfgfile" # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test set != "${COLLECT_NAMES+set}"; then COLLECT_NAMES= export COLLECT_NAMES fi _LT_EOF ;; esac ltmain=$ac_aux_dir/ltmain.sh # We use sed instead of cat because bash on DJGPP gets confused if # if finds mixed CR/LF and LF-only lines. Since sed operates in # text mode, it properly converts lines to CR/LF. This bash problem # is reportedly fixed, but why not run on old versions too? $SED '$q' "$ltmain" >> "$cfgfile" \ || (rm -f "$cfgfile"; exit 1) mv -f "$cfgfile" "$ofile" || (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") chmod +x "$ofile" ;; esac done # for ac_tag as_fn_exit 0 _ACEOF ac_clean_files=$ac_clean_files_save test $ac_write_fail = 0 || as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 # configure is writing to config.log, and then calls config.status. # config.status does its own redirection, appending to config.log. # Unfortunately, on DOS this fails, as config.log is still kept open # by configure, so config.status won't be able to write to it; its # output is simply discarded. So we exec the FD to /dev/null, # effectively closing config.log, so it can be properly (re)opened and # appended to by config.status. When coming back to configure, we # need to make the FD available again. if test "$no_create" != yes; then ac_cs_success=: ac_config_status_args= test "$silent" = yes && ac_config_status_args="$ac_config_status_args --quiet" exec 5>/dev/null $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false exec 5>>config.log # Use ||, not &&, to avoid exiting from the if with $? = 1, which # would make configure fail if this is the last instruction. $ac_cs_success || as_fn_exit 1 fi if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 printf "%s\n" "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} fi if test "x${build_sunos}" = "xyes" then : echo " Setting up SunOS kernel module(s)" mkmkf() { rm -f $2 if [ -f $1 ]; then echo " $2 <= $1" sed -e "s,@DESTDIR@,$prefix,g" \ -e "s,@SYSCONF@,$sysconfdir,g" \ -e "s,@CC@,$CC,g" \ -e "s|@CFLAGS@|$CFLAGS|g" $1 > $2 fi } release=`uname -r` karch=`/usr/bin/isainfo -k` makext="sol2" archvariant= case "$karch" in amd64) archvariant='-64x' ;; sparcv9) archvariant='-64' ;; *) ;; esac usegcc=$CC if [ -x /opt/SUNWspro/bin/cc -a "$usegcc" != gcc ] && /opt/SUNWspro/bin/cc -flags >/dev/null 2>&1; then if [ "$archvariant" = "-64x" ]; then ( cd /tmp; echo "int x;" > ppp$$.c /opt/SUNWspro/bin/cc -c -errwarn -xchip=opteron -m64 ppp$$.c >/dev/null 2>&1 || ( echo "WorkShop C is unable to make 64 bit modules, and your $karch system needs" echo "them. Consider upgrading cc on this machine." rm -f ppp$$.c exit 1 ) || exit 1 rm -f ppp$$.c ppp$$.o ) || exit 1 fi elif gcc --version >/dev/null 2>&1; then archvariant=gcc$archvariant compiletype=.gcc if [ "$archvariant" = "gcc-64" -o"$archvariant" = "gcc-64x" ]; then ( cd /tmp; touch ppp$$.c gcc -c -m64 ppp$$.c >/dev/null 2>&1 || ( echo "gcc is unable to make 64 bit modules, and your $karch system needs them." echo "Consider upgrading gcc on this machine, or switching to Sun WorkShop." rm -f ppp$$.c exit 1 ) || exit 1 rm -f ppp$$.c ppp$$.o ) || exit 1 fi else echo "C compiler not found; hoping for the best." fi mkmkf solaris/Makedefs$compiletype Makedefs.com mkmkf solaris/Makefile.sol2$archvariant solaris/Makefile fi echo " $PACKAGE_NAME version $PACKAGE_VERSION Prefix...............: $prefix Runtime Dir..........: $PPPD_RUNTIME_DIR Logfile Dir..........: $PPPD_LOGFILE_DIR Plugin Dir...........: $PPPD_PLUGIN_DIR System CA Path ......: ${SYSTEM_CA_PATH:-not set} With OpenSSL.........: ${with_openssl:-yes} With libatm..........: ${with_atm:-no} With libpam..........: ${with_pam:-no} With libpcap.........: ${with_pcap:-no} With libsrp..........: ${with_srp:-no} C Compiler...........: $CC $CFLAGS Linker...............: $LD $LDFLAGS $LIBS Features enabled Microsoft Extensions.: ${enable_microsoft_extensions:-yes} Multilink............: ${enable_multilink:-no} Plugins..............: ${enable_plugins:-yes} CBCP.................: ${enable_cbcp:-no} IPV6CP...............: ${enable_ipv6cp:-yes} EAP-TLS..............: ${enable_eaptls:-yes} PEAP.................: ${enable_peap:-yes} systemd notifications: ${enable_systemd:-no} " ppp-2.5.0/configure.ac0000644000175000017500000003270514407475306011545 00000000000000AC_PREREQ([2.69]) AC_INIT([ppp], [2.5.0], [https://github.com/ppp-project/ppp]) m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])]) AC_CONFIG_MACRO_DIR([m4]) AM_INIT_AUTOMAKE AM_MAINTAINER_MODE([enable]) AC_LANG(C) AC_CONFIG_SRCDIR([pppd/main.c]) AC_CONFIG_HEADERS([pppd/config.h pppd/pppdconf.h pppd/plugins/pppoe/config.h]) AC_ENABLE_STATIC(no) # Checks for programs. AC_PROG_CC AM_PROG_CC_C_O AC_PROG_INSTALL AC_PROG_LN_S LT_INIT PKG_PROG_PKG_CONFIG AC_CANONICAL_HOST build_linux=no build_sunos=no case "${host_os}" in linux*) build_linux=yes ;; solaris2*) build_sunos=yes ;; *) AC_MSG_ERROR(["OS ${host_os} not supported"]) ;; esac AM_CONDITIONAL([LINUX], [test "x${build_linux}" = "xyes" ]) AM_CONDITIONAL([SUNOS], [test "x${build_sunos}" = "xyes" ]) AM_COND_IF([SUNOS], CFLAGS="$CFLAGS -DSOL2 -DSRV4") # # Checks for header files, these will set the HAVE_[FILE]_H macros in config.h AC_HEADER_STDBOOL AC_CHECK_HEADERS([ \ asm/types.h \ crypt.h \ paths.h \ shadow.h \ stddef.h \ stdarg.h \ sys/dlpi.h \ sys/ioctl.h \ sys/socket.h \ sys/time.h \ sys/uio.h \ time.h \ unistd.h \ utmp.h]) # # Check for linux specific headers, required by pppoe, or pppol2tp AM_COND_IF([LINUX], [ AC_CHECK_HEADERS([ \ net/bpf.h \ net/if.h \ net/if_types.h \ net/if_arp.h \ linux/if.h \ linux/if_ether.h \ linux/if_packet.h \ netinet/if_ether.h \ netpacket/packet.h])]) AC_CHECK_SIZEOF(unsigned int) AC_CHECK_SIZEOF(unsigned long) AC_CHECK_SIZEOF(unsigned short) # Checks for library functions. AC_CHECK_FUNCS([ \ mmap \ logwtmp \ strerror]) # # If libc doesn't provide logwtmp, check if libutil provides logwtmp(), and if so link to it. AS_IF([test "x${ac_cv_func_logwtmp}" != "xyes"], [ AC_CHECK_LIB([util], [logwtmp], [ AC_DEFINE(HAVE_LOGWTMP, 1, [System provides the logwtmp() function]) AC_SUBST([UTIL_LIBS], ["-lutil"]) ]) ]) # # Check if libcrypt have crypt() function AC_CHECK_LIB([crypt], [crypt], AC_SUBST([CRYPT_LIBS], ["-lcrypt"])) # # Should pppd link with -lsystemd (Linux only) AC_ARG_ENABLE([systemd], AS_HELP_STRING([--enable-systemd], [Enable support for systemd notification])) AM_CONDITIONAL(WITH_SYSTEMD, test "x${enable_systemd}" = "xyes") AM_COND_IF([WITH_SYSTEMD], AC_DEFINE([SYSTEMD], 1, [Enable support for systemd notifications])) AS_IF([test "x${enable_systemd}" = "xyes"], [ PKG_CHECK_MODULES([SYSTEMD], [libsystemd])]) # # Enable Callback Protocol Support, disabled by default AC_ARG_ENABLE([cbcp], AS_HELP_STRING([--enable-cbcp], [Enable Callback Protocol])) AM_CONDITIONAL(PPP_WITH_CBCP, test "x${enable_cbcp}" = "xyes") AM_COND_IF([PPP_WITH_CBCP], AC_DEFINE([PPP_WITH_CBCP], 1, [Have Callback Protocol support])) # # Disable Microsoft extensions will remove CHAP and MPPE support AC_ARG_ENABLE([microsoft-extensions], AS_HELP_STRING([--disable-microsoft-extensions], [Disable Microsoft CHAP / MPPE extensions])) AM_CONDITIONAL(PPP_WITH_CHAPMS, test "x${enable_microsoft_extensions}" != "xno") AM_COND_IF([PPP_WITH_CHAPMS], AC_DEFINE([PPP_WITH_CHAPMS], 1, [Have Microsoft CHAP support])) AM_CONDITIONAL(PPP_WITH_MPPE, test "x${enable_microsoft_extensions}" != "xno") AM_COND_IF([PPP_WITH_MPPE], AC_DEFINE([PPP_WITH_MPPE], 1, [Have Microsoft MPPE support])) # # Enable Microsoft LAN Manager support, depends on Microsoft Extensions AC_ARG_ENABLE([mslanman], AS_HELP_STRING([--enable-mslanman], [Enable Microsoft LAN Manager support])) AS_IF([test "x${enable_mslanman}" = "xyes" && test "x${enable_microsoft_extensions}" != "xno"], AC_DEFINE([PPP_WITH_MSLANMAN], 1, [Have Microsoft LAN Manager support])) # # Disable IPv6 support AC_ARG_ENABLE([ipv6cp], AS_HELP_STRING([--disable-ipv6cp], [Disable IPv6 Control Protocol])) AM_CONDITIONAL(PPP_WITH_IPV6CP, test "x${enable_ipv6cp}" != "xno") AM_COND_IF([PPP_WITH_IPV6CP], AC_DEFINE(PPP_WITH_IPV6CP, 1, [Have IPv6 Control Protocol])) # # Disable Multilink support AC_ARG_ENABLE([multilink], AS_HELP_STRING([--enable-multilink], [Enable multilink support])) AM_CONDITIONAL(PPP_WITH_MULTILINK, test "x${enable_multilink}" = "xyes") AM_COND_IF([PPP_WITH_MULTILINK], AC_DEFINE([PPP_WITH_MULTILINK], 1, [Have multilink support])) AS_IF([test "x${build_sunos}" = "xyes" && test "x${enable_multilink}" = "xyes"], [AC_MSG_ERROR([Multilink is not supported on SunOS])]) # # Multilink require Trivial Database Support AM_CONDITIONAL(PPP_WITH_TDB, test "x${enable_multilink}" = "xyes") AM_COND_IF([PPP_WITH_TDB], AC_DEFINE([PPP_WITH_TDB], 1, [Include TDB support])) # # Enable support for loadable plugins AC_ARG_ENABLE([plugins], AS_HELP_STRING([--disable-plugins], [Disable support for loadable plugins])) AS_IF([test "x$enable_plugins" != "xno"], AC_DEFINE([PPP_WITH_PLUGINS], 1, [Have support for loadable plugins])) AM_CONDITIONAL(PPP_WITH_PLUGINS, test "x${enable_plugins}" != "xno") # # Disable EAP-TLS support AC_ARG_ENABLE([eaptls], AS_HELP_STRING([--disable-eaptls], [Disable EAP-TLS authentication support])) AS_IF([test "x$enable_eaptls" != "xno"], AC_DEFINE([PPP_WITH_EAPTLS], 1, [Have EAP-TLS authentication support])) AM_CONDITIONAL(PPP_WITH_EAPTLS, test "x${enable_eaptls}" != "xno") # # Disable PEAP support AC_ARG_ENABLE([peap], AS_HELP_STRING([--disable-peap], [Disable PEAP authentication support])) AS_IF([test "x${enable_peap}" != "xno"], AC_DEFINE([PPP_WITH_PEAP], 1, [Have PEAP authentication support])) AM_CONDITIONAL([PPP_WITH_PEAP], test "x${enable_peap}" != "xno") # # Disable OpenSSL engine support AC_ARG_ENABLE([openssl-engine], AS_HELP_STRING([--disable-openssl-engine], [Disable OpenSSL engine support])) AS_IF([test "x$enable_openssl_engine" != "xno"], [], AC_DEFINE([OPENSSL_NO_ENGINE], 1, [OpenSSL engine support])) # # Specify runtime directory AC_ARG_WITH([plugin-dir], AS_HELP_STRING([--with-plugin-dir=DIR],[Specify the plugin directory for pppd])) AS_IF([test -n "$with_plugin_dir"], [PPPD_PLUGIN_DIR="$with_plugin_dir"], [PPPD_PLUGIN_DIR="${libdir}/pppd/$VERSION"]) AC_SUBST(PPPD_PLUGIN_DIR, "$PPPD_PLUGIN_DIR", [The pppd plugin directory]) # # Specify runtime directory AC_ARG_WITH([runtime-dir], AS_HELP_STRING([--with-runtime-dir=DIR],[Specify the runtime directory for pppd])) AS_IF([test -n "$with_runtime_dir"], [PPPD_RUNTIME_DIR="$with_runtime_dir"], [PPPD_RUNTIME_DIR="${runstatedir}/pppd"]) AC_SUBST(PPPD_RUNTIME_DIR) # # Specify runtime directory AC_ARG_WITH([logfile-dir], AS_HELP_STRING([--with-logfile-dir=DIR],[Specify the log directory for pppd])) AS_IF([test -n "$with_logfile_dir"], [PPPD_LOGFILE_DIR="$with_logfile_dir"], [PPPD_LOGFILE_DIR="${localstatedir}/log/ppp"]) AC_SUBST(PPPD_LOGFILE_DIR) # # System CA certificates path AC_ARG_WITH(system-ca-path, AS_HELP_STRING([--with-system-ca-path=/path/to/ssl/certs], [path to system CA certificates]), [ case "$withval" in "" | y | ye | yes) with_system_ca_path="${sysconfdir}/ssl/certs" ;; n | no) ;; *) with_system_ca_path="$withval" ;; esac ],[with_system_ca_path="${sysconfdir}/ssl/certs"]) AM_CONDITIONAL(PPP_WITH_SYSTEM_CA_PATH, [test "$with_system_ca_path" != "no"]) AM_COND_IF(PPP_WITH_SYSTEM_CA_PATH, [ SYSTEM_CA_PATH="$with_system_ca_path" ]) AC_SUBST(SYSTEM_CA_PATH) # # Check for OpenSSL AX_CHECK_OPENSSL AM_CONDITIONAL(PPP_WITH_OPENSSL, test "x${with_openssl}" != "xno") AM_COND_IF([PPP_WITH_OPENSSL], AC_DEFINE([PPP_WITH_OPENSSL], 1, [PPP is compiled with openssl support])) # # Check if OpenSSL has compiled in support for various ciphers AS_IF([test "x${with_openssl}" != "xno" ], [ AX_CHECK_OPENSSL_DEFINE([OPENSSL_NO_MD4], [md4]) AX_CHECK_OPENSSL_DEFINE([OPENSSL_NO_MD5], [md5]) AX_CHECK_OPENSSL_DEFINE([OPENSSL_NO_DES], [des]) AX_CHECK_OPENSSL_DEFINE([OPENSSL_NO_SHA], [sha]) ], [ AS_IF([test "x${enable_eaptls}" != "xno" || test "x${enable_peap}" != "xno"], [AC_MSG_ERROR([OpenSSL not found, and if this is your intention then run configure --disable-eaptls and --disable-peap])]) ]) AM_CONDITIONAL([OPENSSL_HAVE_MD4], test "x${ac_cv_openssl_md4}" = "xyes") AM_COND_IF([OPENSSL_HAVE_MD4], AC_DEFINE([OPENSSL_HAVE_MD4], 1, [Use MD4 included with openssl])) AM_CONDITIONAL([OPENSSL_HAVE_MD5], test "x${ac_cv_openssl_md5}" = "xyes") AM_COND_IF([OPENSSL_HAVE_MD5], AC_DEFINE([OPENSSL_HAVE_MD5], 1, [Use MD5 included with openssl])) AM_CONDITIONAL([OPENSSL_HAVE_SHA], test "x${ac_cv_openssl_sha}" = "xyes") AM_COND_IF([OPENSSL_HAVE_SHA], AC_DEFINE([OPENSSL_HAVE_SHA], 1, [Use SHA included with openssl])) AM_CONDITIONAL([OPENSSL_HAVE_DES], test "x${ac_cv_openssl_des}" = "xyes") AM_COND_IF([OPENSSL_HAVE_DES], AC_DEFINE([OPENSSL_HAVE_DES], 1, [Use DES included with openssl])) # # With libsrp support AX_CHECK_SRP([ AC_DEFINE([PPP_WITH_SRP], 1, [Support for libsrp authentication module])]) # # With libatm support AX_CHECK_ATM # # With libpam support AX_CHECK_PAM(AC_DEFINE([PPP_WITH_PAM], 1, [Support for Pluggable Authentication Modules])) AM_CONDITIONAL(PPP_WITH_PAM, test "x${with_pam}" = "xyes") # # With libpcap support, activate pppd on network activity AX_CHECK_PCAP # # SunOS provides a version of libpcap that would work, but SunOS has no support for activity filter AM_CONDITIONAL([PPP_WITH_FILTER], [ test "x${with_pcap}" = "xyes" && test "x${build_sunos}" != "xyes" ]) AM_COND_IF([PPP_WITH_FILTER], [ AC_DEFINE([PPP_WITH_FILTER], 1, [Have packet activity filter support])], [ AS_IF([test "x${build_sunos}" = "xyes"], [ AC_MSG_WARN([Packet activity filter not supported on SunOS]) with_pcap="no" ]) ]) # # Some contributions require GTK/GLIB AC_ARG_WITH([gtk], AS_HELP_STRING([--with-gtk], [Build contributions with the GTK+ interface])) if test "x${with_gtk}" = "xyes"; then PKG_CHECK_MODULES([GTK], [gtk+-2.0]) PKG_CHECK_MODULES([GLIB], [glib-2.0]) fi AM_CONDITIONAL([WITH_GTK], test "x${with_gtk}" = "xyes") AC_DEFINE_UNQUOTED(PPPD_VERSION, "$VERSION", [Version of pppd]) AC_CONFIG_FILES([ Makefile chat/Makefile contrib/Makefile contrib/pppgetpass/Makefile common/Makefile include/Makefile modules/Makefile pppd/Makefile pppd/pppd.pc pppd/plugins/Makefile pppd/plugins/pppoe/Makefile pppd/plugins/pppoatm/Makefile pppd/plugins/pppol2tp/Makefile pppd/plugins/radius/Makefile pppdump/Makefile pppstats/Makefile scripts/Makefile ]) AC_OUTPUT AS_IF([test "x${build_sunos}" = "xyes" ], [[ echo " Setting up SunOS kernel module(s)" mkmkf() { rm -f $2 if [ -f $1 ]; then echo " $2 <= $1" sed -e "s,@DESTDIR@,$prefix,g" \ -e "s,@SYSCONF@,$sysconfdir,g" \ -e "s,@CC@,$CC,g" \ -e "s|@CFLAGS@|$CFLAGS|g" $1 > $2 fi } release=`uname -r` karch=`/usr/bin/isainfo -k` makext="sol2" archvariant= case "$karch" in amd64) archvariant='-64x' ;; sparcv9) archvariant='-64' ;; *) ;; esac usegcc=$CC if [ -x /opt/SUNWspro/bin/cc -a "$usegcc" != gcc ] && /opt/SUNWspro/bin/cc -flags >/dev/null 2>&1; then if [ "$archvariant" = "-64x" ]; then ( cd /tmp; echo "int x;" > ppp$$.c /opt/SUNWspro/bin/cc -c -errwarn -xchip=opteron -m64 ppp$$.c >/dev/null 2>&1 || ( echo "WorkShop C is unable to make 64 bit modules, and your $karch system needs" echo "them. Consider upgrading cc on this machine." rm -f ppp$$.c exit 1 ) || exit 1 rm -f ppp$$.c ppp$$.o ) || exit 1 fi elif gcc --version >/dev/null 2>&1; then archvariant=gcc$archvariant compiletype=.gcc if [ "$archvariant" = "gcc-64" -o"$archvariant" = "gcc-64x" ]; then ( cd /tmp; touch ppp$$.c gcc -c -m64 ppp$$.c >/dev/null 2>&1 || ( echo "gcc is unable to make 64 bit modules, and your $karch system needs them." echo "Consider upgrading gcc on this machine, or switching to Sun WorkShop." rm -f ppp$$.c exit 1 ) || exit 1 rm -f ppp$$.c ppp$$.o ) || exit 1 fi else echo "C compiler not found; hoping for the best." fi mkmkf solaris/Makedefs$compiletype Makedefs.com mkmkf solaris/Makefile.sol2$archvariant solaris/Makefile ]]) echo " $PACKAGE_NAME version $PACKAGE_VERSION Prefix...............: $prefix Runtime Dir..........: $PPPD_RUNTIME_DIR Logfile Dir..........: $PPPD_LOGFILE_DIR Plugin Dir...........: $PPPD_PLUGIN_DIR System CA Path ......: ${SYSTEM_CA_PATH:-not set} With OpenSSL.........: ${with_openssl:-yes} With libatm..........: ${with_atm:-no} With libpam..........: ${with_pam:-no} With libpcap.........: ${with_pcap:-no} With libsrp..........: ${with_srp:-no} C Compiler...........: $CC $CFLAGS Linker...............: $LD $LDFLAGS $LIBS Features enabled Microsoft Extensions.: ${enable_microsoft_extensions:-yes} Multilink............: ${enable_multilink:-no} Plugins..............: ${enable_plugins:-yes} CBCP.................: ${enable_cbcp:-no} IPV6CP...............: ${enable_ipv6cp:-yes} EAP-TLS..............: ${enable_eaptls:-yes} PEAP.................: ${enable_peap:-yes} systemd notifications: ${enable_systemd:-no} " ppp-2.5.0/aclocal.m40000644000175000017500000013051214407475313011110 00000000000000# generated automatically by aclocal 1.16.5 -*- Autoconf -*- # Copyright (C) 1996-2021 Free Software Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])]) m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.71],, [m4_warning([this file was generated for autoconf 2.71. You have another version of autoconf. It may work, but is not guaranteed to. If you have problems, you may need to regenerate the build system entirely. To do so, use the procedure documented by the package, typically 'autoreconf'.])]) # Copyright (C) 2002-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_AUTOMAKE_VERSION(VERSION) # ---------------------------- # Automake X.Y traces this macro to ensure aclocal.m4 has been # generated from the m4 files accompanying Automake X.Y. # (This private macro should not be called outside this file.) AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version='1.16' dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to dnl require some minimum version. Point them to the right macro. m4_if([$1], [1.16.5], [], [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl ]) # _AM_AUTOCONF_VERSION(VERSION) # ----------------------------- # aclocal traces this macro to find the Autoconf version. # This is a private macro too. Using m4_define simplifies # the logic in aclocal, which can simply ignore this definition. m4_define([_AM_AUTOCONF_VERSION], []) # AM_SET_CURRENT_AUTOMAKE_VERSION # ------------------------------- # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. # This function is AC_REQUIREd by AM_INIT_AUTOMAKE. AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], [AM_AUTOMAKE_VERSION([1.16.5])dnl m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) # AM_AUX_DIR_EXPAND -*- Autoconf -*- # Copyright (C) 2001-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets # $ac_aux_dir to '$srcdir/foo'. In other projects, it is set to # '$srcdir', '$srcdir/..', or '$srcdir/../..'. # # Of course, Automake must honor this variable whenever it calls a # tool from the auxiliary directory. The problem is that $srcdir (and # therefore $ac_aux_dir as well) can be either absolute or relative, # depending on how configure is run. This is pretty annoying, since # it makes $ac_aux_dir quite unusable in subdirectories: in the top # source directory, any form will work fine, but in subdirectories a # relative path needs to be adjusted first. # # $ac_aux_dir/missing # fails when called from a subdirectory if $ac_aux_dir is relative # $top_srcdir/$ac_aux_dir/missing # fails if $ac_aux_dir is absolute, # fails when called from a subdirectory in a VPATH build with # a relative $ac_aux_dir # # The reason of the latter failure is that $top_srcdir and $ac_aux_dir # are both prefixed by $srcdir. In an in-source build this is usually # harmless because $srcdir is '.', but things will broke when you # start a VPATH build or use an absolute $srcdir. # # So we could use something similar to $top_srcdir/$ac_aux_dir/missing, # iff we strip the leading $srcdir from $ac_aux_dir. That would be: # am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` # and then we would define $MISSING as # MISSING="\${SHELL} $am_aux_dir/missing" # This will work as long as MISSING is not called from configure, because # unfortunately $(top_srcdir) has no meaning in configure. # However there are other variables, like CC, which are often used in # configure, and could therefore not use this "fixed" $ac_aux_dir. # # Another solution, used here, is to always expand $ac_aux_dir to an # absolute PATH. The drawback is that using absolute paths prevent a # configured tree to be moved without reconfiguration. AC_DEFUN([AM_AUX_DIR_EXPAND], [AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl # Expand $ac_aux_dir to an absolute path. am_aux_dir=`cd "$ac_aux_dir" && pwd` ]) # AM_COND_IF -*- Autoconf -*- # Copyright (C) 2008-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_COND_IF # _AM_COND_ELSE # _AM_COND_ENDIF # -------------- # These macros are only used for tracing. m4_define([_AM_COND_IF]) m4_define([_AM_COND_ELSE]) m4_define([_AM_COND_ENDIF]) # AM_COND_IF(COND, [IF-TRUE], [IF-FALSE]) # --------------------------------------- # If the shell condition COND is true, execute IF-TRUE, otherwise execute # IF-FALSE. Allow automake to learn about conditional instantiating macros # (the AC_CONFIG_FOOS). AC_DEFUN([AM_COND_IF], [m4_ifndef([_AM_COND_VALUE_$1], [m4_fatal([$0: no such condition "$1"])])dnl _AM_COND_IF([$1])dnl if test -z "$$1_TRUE"; then : m4_n([$2])[]dnl m4_ifval([$3], [_AM_COND_ELSE([$1])dnl else $3 ])dnl _AM_COND_ENDIF([$1])dnl fi[]dnl ]) # AM_CONDITIONAL -*- Autoconf -*- # Copyright (C) 1997-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_CONDITIONAL(NAME, SHELL-CONDITION) # ------------------------------------- # Define a conditional. AC_DEFUN([AM_CONDITIONAL], [AC_PREREQ([2.52])dnl m4_if([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl AC_SUBST([$1_TRUE])dnl AC_SUBST([$1_FALSE])dnl _AM_SUBST_NOTMAKE([$1_TRUE])dnl _AM_SUBST_NOTMAKE([$1_FALSE])dnl m4_define([_AM_COND_VALUE_$1], [$2])dnl if $2; then $1_TRUE= $1_FALSE='#' else $1_TRUE='#' $1_FALSE= fi AC_CONFIG_COMMANDS_PRE( [if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then AC_MSG_ERROR([[conditional "$1" was never defined. Usually this means the macro was only invoked conditionally.]]) fi])]) # Copyright (C) 1999-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # There are a few dirty hacks below to avoid letting 'AC_PROG_CC' be # written in clear, in which case automake, when reading aclocal.m4, # will think it sees a *use*, and therefore will trigger all it's # C support machinery. Also note that it means that autoscan, seeing # CC etc. in the Makefile, will ask for an AC_PROG_CC use... # _AM_DEPENDENCIES(NAME) # ---------------------- # See how the compiler implements dependency checking. # NAME is "CC", "CXX", "OBJC", "OBJCXX", "UPC", or "GJC". # We try a few techniques and use that to set a single cache variable. # # We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was # modified to invoke _AM_DEPENDENCIES(CC); we would have a circular # dependency, and given that the user is not expected to run this macro, # just rely on AC_PROG_CC. AC_DEFUN([_AM_DEPENDENCIES], [AC_REQUIRE([AM_SET_DEPDIR])dnl AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl AC_REQUIRE([AM_MAKE_INCLUDE])dnl AC_REQUIRE([AM_DEP_TRACK])dnl m4_if([$1], [CC], [depcc="$CC" am_compiler_list=], [$1], [CXX], [depcc="$CXX" am_compiler_list=], [$1], [OBJC], [depcc="$OBJC" am_compiler_list='gcc3 gcc'], [$1], [OBJCXX], [depcc="$OBJCXX" am_compiler_list='gcc3 gcc'], [$1], [UPC], [depcc="$UPC" am_compiler_list=], [$1], [GCJ], [depcc="$GCJ" am_compiler_list='gcc3 gcc'], [depcc="$$1" am_compiler_list=]) AC_CACHE_CHECK([dependency style of $depcc], [am_cv_$1_dependencies_compiler_type], [if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named 'D' -- because '-MD' means "put the output # in D". rm -rf conftest.dir mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_$1_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` fi am__universal=false m4_case([$1], [CC], [case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac], [CXX], [case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac]) for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with # Solaris 10 /bin/sh. echo '/* dummy */' > sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf # We check with '-c' and '-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle '-M -o', and we need to detect this. Also, some Intel # versions had trouble with output in subdirs. am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in gcc) # This depmode causes a compiler race in universal mode. test "$am__universal" = false || continue ;; nosideeffect) # After this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested. if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; msvc7 | msvc7msys | msvisualcpp | msvcmsys) # This compiler won't grok '-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} am__minus_obj= ;; none) break ;; esac if depmode=$depmode \ source=sub/conftest.c object=$am__obj \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_$1_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_$1_dependencies_compiler_type=none fi ]) AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) AM_CONDITIONAL([am__fastdep$1], [ test "x$enable_dependency_tracking" != xno \ && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) ]) # AM_SET_DEPDIR # ------------- # Choose a directory name for dependency files. # This macro is AC_REQUIREd in _AM_DEPENDENCIES. AC_DEFUN([AM_SET_DEPDIR], [AC_REQUIRE([AM_SET_LEADING_DOT])dnl AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl ]) # AM_DEP_TRACK # ------------ AC_DEFUN([AM_DEP_TRACK], [AC_ARG_ENABLE([dependency-tracking], [dnl AS_HELP_STRING( [--enable-dependency-tracking], [do not reject slow dependency extractors]) AS_HELP_STRING( [--disable-dependency-tracking], [speeds up one-time build])]) if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' am__nodep='_no' fi AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) AC_SUBST([AMDEPBACKSLASH])dnl _AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl AC_SUBST([am__nodep])dnl _AM_SUBST_NOTMAKE([am__nodep])dnl ]) # Generate code to set up dependency tracking. -*- Autoconf -*- # Copyright (C) 1999-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_OUTPUT_DEPENDENCY_COMMANDS # ------------------------------ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], [{ # Older Autoconf quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. # TODO: see whether this extra hack can be removed once we start # requiring Autoconf 2.70 or later. AS_CASE([$CONFIG_FILES], [*\'*], [eval set x "$CONFIG_FILES"], [*], [set x $CONFIG_FILES]) shift # Used to flag and report bootstrapping failures. am_rc=0 for am_mf do # Strip MF so we end up with the name of the file. am_mf=`AS_ECHO(["$am_mf"]) | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile which includes # dependency-tracking related rules and includes. # Grep'ing the whole file directly is not great: AIX grep has a line # limit of 2048, but all sed's we know have understand at least 4000. sed -n 's,^am--depfiles:.*,X,p' "$am_mf" | grep X >/dev/null 2>&1 \ || continue am_dirpart=`AS_DIRNAME(["$am_mf"])` am_filepart=`AS_BASENAME(["$am_mf"])` AM_RUN_LOG([cd "$am_dirpart" \ && sed -e '/# am--include-marker/d' "$am_filepart" \ | $MAKE -f - am--depfiles]) || am_rc=$? done if test $am_rc -ne 0; then AC_MSG_FAILURE([Something went wrong bootstrapping makefile fragments for automatic dependency tracking. If GNU make was not used, consider re-running the configure script with MAKE="gmake" (or whatever is necessary). You can also try re-running configure with the '--disable-dependency-tracking' option to at least be able to build the package (albeit without support for automatic dependency tracking).]) fi AS_UNSET([am_dirpart]) AS_UNSET([am_filepart]) AS_UNSET([am_mf]) AS_UNSET([am_rc]) rm -f conftest-deps.mk } ])# _AM_OUTPUT_DEPENDENCY_COMMANDS # AM_OUTPUT_DEPENDENCY_COMMANDS # ----------------------------- # This macro should only be invoked once -- use via AC_REQUIRE. # # This code is only required when automatic dependency tracking is enabled. # This creates each '.Po' and '.Plo' makefile fragment that we'll need in # order to bootstrap the dependency handling code. AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], [AC_CONFIG_COMMANDS([depfiles], [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], [AMDEP_TRUE="$AMDEP_TRUE" MAKE="${MAKE-make}"])]) # Do all the work for Automake. -*- Autoconf -*- # Copyright (C) 1996-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This macro actually does too much. Some checks are only needed if # your package does certain things. But this isn't really a big deal. dnl Redefine AC_PROG_CC to automatically invoke _AM_PROG_CC_C_O. m4_define([AC_PROG_CC], m4_defn([AC_PROG_CC]) [_AM_PROG_CC_C_O ]) # AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) # AM_INIT_AUTOMAKE([OPTIONS]) # ----------------------------------------------- # The call with PACKAGE and VERSION arguments is the old style # call (pre autoconf-2.50), which is being phased out. PACKAGE # and VERSION should now be passed to AC_INIT and removed from # the call to AM_INIT_AUTOMAKE. # We support both call styles for the transition. After # the next Automake release, Autoconf can make the AC_INIT # arguments mandatory, and then we can depend on a new Autoconf # release and drop the old call support. AC_DEFUN([AM_INIT_AUTOMAKE], [AC_PREREQ([2.65])dnl m4_ifdef([_$0_ALREADY_INIT], [m4_fatal([$0 expanded multiple times ]m4_defn([_$0_ALREADY_INIT]))], [m4_define([_$0_ALREADY_INIT], m4_expansion_stack)])dnl dnl Autoconf wants to disallow AM_ names. We explicitly allow dnl the ones we care about. m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl AC_REQUIRE([AC_PROG_INSTALL])dnl if test "`cd $srcdir && pwd`" != "`pwd`"; then # Use -I$(srcdir) only when $(srcdir) != ., so that make's output # is not polluted with repeated "-I." AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl # test to see if srcdir already configured if test -f $srcdir/config.status; then AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) fi fi # test whether we have cygpath if test -z "$CYGPATH_W"; then if (cygpath --version) >/dev/null 2>/dev/null; then CYGPATH_W='cygpath -w' else CYGPATH_W=echo fi fi AC_SUBST([CYGPATH_W]) # Define the identity of the package. dnl Distinguish between old-style and new-style calls. m4_ifval([$2], [AC_DIAGNOSE([obsolete], [$0: two- and three-arguments forms are deprecated.]) m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl AC_SUBST([PACKAGE], [$1])dnl AC_SUBST([VERSION], [$2])], [_AM_SET_OPTIONS([$1])dnl dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. m4_if( m4_ifset([AC_PACKAGE_NAME], [ok]):m4_ifset([AC_PACKAGE_VERSION], [ok]), [ok:ok],, [m4_fatal([AC_INIT should be called with package and version arguments])])dnl AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl _AM_IF_OPTION([no-define],, [AC_DEFINE_UNQUOTED([PACKAGE], ["$PACKAGE"], [Name of package]) AC_DEFINE_UNQUOTED([VERSION], ["$VERSION"], [Version number of package])])dnl # Some tools Automake needs. AC_REQUIRE([AM_SANITY_CHECK])dnl AC_REQUIRE([AC_ARG_PROGRAM])dnl AM_MISSING_PROG([ACLOCAL], [aclocal-${am__api_version}]) AM_MISSING_PROG([AUTOCONF], [autoconf]) AM_MISSING_PROG([AUTOMAKE], [automake-${am__api_version}]) AM_MISSING_PROG([AUTOHEADER], [autoheader]) AM_MISSING_PROG([MAKEINFO], [makeinfo]) AC_REQUIRE([AM_PROG_INSTALL_SH])dnl AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl AC_REQUIRE([AC_PROG_MKDIR_P])dnl # For better backward compatibility. To be removed once Automake 1.9.x # dies out for good. For more background, see: # # AC_SUBST([mkdir_p], ['$(MKDIR_P)']) # We need awk for the "check" target (and possibly the TAP driver). The # system "awk" is bad on some platforms. AC_REQUIRE([AC_PROG_AWK])dnl AC_REQUIRE([AC_PROG_MAKE_SET])dnl AC_REQUIRE([AM_SET_LEADING_DOT])dnl _AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], [_AM_PROG_TAR([v7])])]) _AM_IF_OPTION([no-dependencies],, [AC_PROVIDE_IFELSE([AC_PROG_CC], [_AM_DEPENDENCIES([CC])], [m4_define([AC_PROG_CC], m4_defn([AC_PROG_CC])[_AM_DEPENDENCIES([CC])])])dnl AC_PROVIDE_IFELSE([AC_PROG_CXX], [_AM_DEPENDENCIES([CXX])], [m4_define([AC_PROG_CXX], m4_defn([AC_PROG_CXX])[_AM_DEPENDENCIES([CXX])])])dnl AC_PROVIDE_IFELSE([AC_PROG_OBJC], [_AM_DEPENDENCIES([OBJC])], [m4_define([AC_PROG_OBJC], m4_defn([AC_PROG_OBJC])[_AM_DEPENDENCIES([OBJC])])])dnl AC_PROVIDE_IFELSE([AC_PROG_OBJCXX], [_AM_DEPENDENCIES([OBJCXX])], [m4_define([AC_PROG_OBJCXX], m4_defn([AC_PROG_OBJCXX])[_AM_DEPENDENCIES([OBJCXX])])])dnl ]) # Variables for tags utilities; see am/tags.am if test -z "$CTAGS"; then CTAGS=ctags fi AC_SUBST([CTAGS]) if test -z "$ETAGS"; then ETAGS=etags fi AC_SUBST([ETAGS]) if test -z "$CSCOPE"; then CSCOPE=cscope fi AC_SUBST([CSCOPE]) AC_REQUIRE([AM_SILENT_RULES])dnl dnl The testsuite driver may need to know about EXEEXT, so add the dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This dnl macro is hooked onto _AC_COMPILER_EXEEXT early, see below. AC_CONFIG_COMMANDS_PRE(dnl [m4_provide_if([_AM_COMPILER_EXEEXT], [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl # POSIX will say in a future version that running "rm -f" with no argument # is OK; and we want to be able to make that assumption in our Makefile # recipes. So use an aggressive probe to check that the usage we want is # actually supported "in the wild" to an acceptable degree. # See automake bug#10828. # To make any issue more visible, cause the running configure to be aborted # by default if the 'rm' program in use doesn't match our expectations; the # user can still override this though. if rm -f && rm -fr && rm -rf; then : OK; else cat >&2 <<'END' Oops! Your 'rm' program seems unable to run without file operands specified on the command line, even when the '-f' option is present. This is contrary to the behaviour of most rm programs out there, and not conforming with the upcoming POSIX standard: Please tell bug-automake@gnu.org about your system, including the value of your $PATH and any error possibly output before this message. This can help us improve future automake versions. END if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then echo 'Configuration will proceed anyway, since you have set the' >&2 echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 echo >&2 else cat >&2 <<'END' Aborting the configuration process, to ensure you take notice of the issue. You can download and install GNU coreutils to get an 'rm' implementation that behaves properly: . If you want to complete the configuration process using your problematic 'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM to "yes", and re-run configure. END AC_MSG_ERROR([Your 'rm' program is bad, sorry.]) fi fi dnl The trailing newline in this macro's definition is deliberate, for dnl backward compatibility and to allow trailing 'dnl'-style comments dnl after the AM_INIT_AUTOMAKE invocation. See automake bug#16841. ]) dnl Hook into '_AC_COMPILER_EXEEXT' early to learn its expansion. Do not dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further dnl mangled by Autoconf and run in a shell conditional statement. m4_define([_AC_COMPILER_EXEEXT], m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])]) # When config.status generates a header, we must update the stamp-h file. # This file resides in the same directory as the config header # that is generated. The stamp files are numbered to have different names. # Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the # loop where config.status creates the headers, so we can generate # our stamp files there. AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], [# Compute $1's index in $config_headers. _am_arg=$1 _am_stamp_count=1 for _am_header in $config_headers :; do case $_am_header in $_am_arg | $_am_arg:* ) break ;; * ) _am_stamp_count=`expr $_am_stamp_count + 1` ;; esac done echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) # Copyright (C) 2001-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_PROG_INSTALL_SH # ------------------ # Define $install_sh. AC_DEFUN([AM_PROG_INSTALL_SH], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl if test x"${install_sh+set}" != xset; then case $am_aux_dir in *\ * | *\ *) install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; *) install_sh="\${SHELL} $am_aux_dir/install-sh" esac fi AC_SUBST([install_sh])]) # Copyright (C) 2003-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # Check whether the underlying file-system supports filenames # with a leading dot. For instance MS-DOS doesn't. AC_DEFUN([AM_SET_LEADING_DOT], [rm -rf .tst 2>/dev/null mkdir .tst 2>/dev/null if test -d .tst; then am__leading_dot=. else am__leading_dot=_ fi rmdir .tst 2>/dev/null AC_SUBST([am__leading_dot])]) # Add --enable-maintainer-mode option to configure. -*- Autoconf -*- # From Jim Meyering # Copyright (C) 1996-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_MAINTAINER_MODE([DEFAULT-MODE]) # ---------------------------------- # Control maintainer-specific portions of Makefiles. # Default is to disable them, unless 'enable' is passed literally. # For symmetry, 'disable' may be passed as well. Anyway, the user # can override the default with the --enable/--disable switch. AC_DEFUN([AM_MAINTAINER_MODE], [m4_case(m4_default([$1], [disable]), [enable], [m4_define([am_maintainer_other], [disable])], [disable], [m4_define([am_maintainer_other], [enable])], [m4_define([am_maintainer_other], [enable]) m4_warn([syntax], [unexpected argument to AM@&t@_MAINTAINER_MODE: $1])]) AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles]) dnl maintainer-mode's default is 'disable' unless 'enable' is passed AC_ARG_ENABLE([maintainer-mode], [AS_HELP_STRING([--]am_maintainer_other[-maintainer-mode], am_maintainer_other[ make rules and dependencies not useful (and sometimes confusing) to the casual installer])], [USE_MAINTAINER_MODE=$enableval], [USE_MAINTAINER_MODE=]m4_if(am_maintainer_other, [enable], [no], [yes])) AC_MSG_RESULT([$USE_MAINTAINER_MODE]) AM_CONDITIONAL([MAINTAINER_MODE], [test $USE_MAINTAINER_MODE = yes]) MAINT=$MAINTAINER_MODE_TRUE AC_SUBST([MAINT])dnl ] ) # Check to see how 'make' treats includes. -*- Autoconf -*- # Copyright (C) 2001-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_MAKE_INCLUDE() # ----------------- # Check whether make has an 'include' directive that can support all # the idioms we need for our automatic dependency tracking code. AC_DEFUN([AM_MAKE_INCLUDE], [AC_MSG_CHECKING([whether ${MAKE-make} supports the include directive]) cat > confinc.mk << 'END' am__doit: @echo this is the am__doit target >confinc.out .PHONY: am__doit END am__include="#" am__quote= # BSD make does it like this. echo '.include "confinc.mk" # ignored' > confmf.BSD # Other make implementations (GNU, Solaris 10, AIX) do it like this. echo 'include confinc.mk # ignored' > confmf.GNU _am_result=no for s in GNU BSD; do AM_RUN_LOG([${MAKE-make} -f confmf.$s && cat confinc.out]) AS_CASE([$?:`cat confinc.out 2>/dev/null`], ['0:this is the am__doit target'], [AS_CASE([$s], [BSD], [am__include='.include' am__quote='"'], [am__include='include' am__quote=''])]) if test "$am__include" != "#"; then _am_result="yes ($s style)" break fi done rm -f confinc.* confmf.* AC_MSG_RESULT([${_am_result}]) AC_SUBST([am__include])]) AC_SUBST([am__quote])]) # Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- # Copyright (C) 1997-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_MISSING_PROG(NAME, PROGRAM) # ------------------------------ AC_DEFUN([AM_MISSING_PROG], [AC_REQUIRE([AM_MISSING_HAS_RUN]) $1=${$1-"${am_missing_run}$2"} AC_SUBST($1)]) # AM_MISSING_HAS_RUN # ------------------ # Define MISSING if not defined so far and test if it is modern enough. # If it is, set am_missing_run to use it, otherwise, to nothing. AC_DEFUN([AM_MISSING_HAS_RUN], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl AC_REQUIRE_AUX_FILE([missing])dnl if test x"${MISSING+set}" != xset; then MISSING="\${SHELL} '$am_aux_dir/missing'" fi # Use eval to expand $SHELL if eval "$MISSING --is-lightweight"; then am_missing_run="$MISSING " else am_missing_run= AC_MSG_WARN(['missing' script is too old or missing]) fi ]) # Helper functions for option handling. -*- Autoconf -*- # Copyright (C) 2001-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_MANGLE_OPTION(NAME) # ----------------------- AC_DEFUN([_AM_MANGLE_OPTION], [[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) # _AM_SET_OPTION(NAME) # -------------------- # Set option NAME. Presently that only means defining a flag for this option. AC_DEFUN([_AM_SET_OPTION], [m4_define(_AM_MANGLE_OPTION([$1]), [1])]) # _AM_SET_OPTIONS(OPTIONS) # ------------------------ # OPTIONS is a space-separated list of Automake options. AC_DEFUN([_AM_SET_OPTIONS], [m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) # _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) # ------------------------------------------- # Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. AC_DEFUN([_AM_IF_OPTION], [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) # Copyright (C) 1999-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_PROG_CC_C_O # --------------- # Like AC_PROG_CC_C_O, but changed for automake. We rewrite AC_PROG_CC # to automatically call this. AC_DEFUN([_AM_PROG_CC_C_O], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl AC_REQUIRE_AUX_FILE([compile])dnl AC_LANG_PUSH([C])dnl AC_CACHE_CHECK( [whether $CC understands -c and -o together], [am_cv_prog_cc_c_o], [AC_LANG_CONFTEST([AC_LANG_PROGRAM([])]) # Make sure it works both with $CC and with simple cc. # Following AC_PROG_CC_C_O, we do the test twice because some # compilers refuse to overwrite an existing .o file with -o, # though they will create one. am_cv_prog_cc_c_o=yes for am_i in 1 2; do if AM_RUN_LOG([$CC -c conftest.$ac_ext -o conftest2.$ac_objext]) \ && test -f conftest2.$ac_objext; then : OK else am_cv_prog_cc_c_o=no break fi done rm -f core conftest* unset am_i]) if test "$am_cv_prog_cc_c_o" != yes; then # Losing compiler, so override with the script. # FIXME: It is wrong to rewrite CC. # But if we don't then we get into trouble of one sort or another. # A longer-term fix would be to have automake use am__CC in this case, # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" CC="$am_aux_dir/compile $CC" fi AC_LANG_POP([C])]) # For backward compatibility. AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])]) # Copyright (C) 2001-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_RUN_LOG(COMMAND) # ------------------- # Run COMMAND, save the exit status in ac_status, and log it. # (This has been adapted from Autoconf's _AC_RUN_LOG macro.) AC_DEFUN([AM_RUN_LOG], [{ echo "$as_me:$LINENO: $1" >&AS_MESSAGE_LOG_FD ($1) >&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD (exit $ac_status); }]) # Check to make sure that the build environment is sane. -*- Autoconf -*- # Copyright (C) 1996-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_SANITY_CHECK # --------------- AC_DEFUN([AM_SANITY_CHECK], [AC_MSG_CHECKING([whether build environment is sane]) # Reject unsafe characters in $srcdir or the absolute working directory # name. Accept space and tab only in the latter. am_lf=' ' case `pwd` in *[[\\\"\#\$\&\'\`$am_lf]]*) AC_MSG_ERROR([unsafe absolute working directory name]);; esac case $srcdir in *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*) AC_MSG_ERROR([unsafe srcdir value: '$srcdir']);; esac # Do 'set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( am_has_slept=no for am_try in 1 2; do echo "timestamp, slept: $am_has_slept" > conftest.file set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` if test "$[*]" = "X"; then # -L didn't work. set X `ls -t "$srcdir/configure" conftest.file` fi if test "$[*]" != "X $srcdir/configure conftest.file" \ && test "$[*]" != "X conftest.file $srcdir/configure"; then # If neither matched, then we have a broken ls. This can happen # if, for instance, CONFIG_SHELL is bash and it inherits a # broken ls alias from the environment. This has actually # happened. Such a system could not be considered "sane". AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken alias in your environment]) fi if test "$[2]" = conftest.file || test $am_try -eq 2; then break fi # Just in case. sleep 1 am_has_slept=yes done test "$[2]" = conftest.file ) then # Ok. : else AC_MSG_ERROR([newly created file is older than distributed files! Check your system clock]) fi AC_MSG_RESULT([yes]) # If we didn't sleep, we still need to ensure time stamps of config.status and # generated files are strictly newer. am_sleep_pid= if grep 'slept: no' conftest.file >/dev/null 2>&1; then ( sleep 1 ) & am_sleep_pid=$! fi AC_CONFIG_COMMANDS_PRE( [AC_MSG_CHECKING([that generated files are newer than configure]) if test -n "$am_sleep_pid"; then # Hide warnings about reused PIDs. wait $am_sleep_pid 2>/dev/null fi AC_MSG_RESULT([done])]) rm -f conftest.file ]) # Copyright (C) 2009-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_SILENT_RULES([DEFAULT]) # -------------------------- # Enable less verbose build rules; with the default set to DEFAULT # ("yes" being less verbose, "no" or empty being verbose). AC_DEFUN([AM_SILENT_RULES], [AC_ARG_ENABLE([silent-rules], [dnl AS_HELP_STRING( [--enable-silent-rules], [less verbose build output (undo: "make V=1")]) AS_HELP_STRING( [--disable-silent-rules], [verbose build output (undo: "make V=0")])dnl ]) case $enable_silent_rules in @%:@ ((( yes) AM_DEFAULT_VERBOSITY=0;; no) AM_DEFAULT_VERBOSITY=1;; *) AM_DEFAULT_VERBOSITY=m4_if([$1], [yes], [0], [1]);; esac dnl dnl A few 'make' implementations (e.g., NonStop OS and NextStep) dnl do not support nested variable expansions. dnl See automake bug#9928 and bug#10237. am_make=${MAKE-make} AC_CACHE_CHECK([whether $am_make supports nested variables], [am_cv_make_support_nested_variables], [if AS_ECHO([['TRUE=$(BAR$(V)) BAR0=false BAR1=true V=1 am__doit: @$(TRUE) .PHONY: am__doit']]) | $am_make -f - >/dev/null 2>&1; then am_cv_make_support_nested_variables=yes else am_cv_make_support_nested_variables=no fi]) if test $am_cv_make_support_nested_variables = yes; then dnl Using '$V' instead of '$(V)' breaks IRIX make. AM_V='$(V)' AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' else AM_V=$AM_DEFAULT_VERBOSITY AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY fi AC_SUBST([AM_V])dnl AM_SUBST_NOTMAKE([AM_V])dnl AC_SUBST([AM_DEFAULT_V])dnl AM_SUBST_NOTMAKE([AM_DEFAULT_V])dnl AC_SUBST([AM_DEFAULT_VERBOSITY])dnl AM_BACKSLASH='\' AC_SUBST([AM_BACKSLASH])dnl _AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl ]) # Copyright (C) 2001-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_PROG_INSTALL_STRIP # --------------------- # One issue with vendor 'install' (even GNU) is that you can't # specify the program used to strip binaries. This is especially # annoying in cross-compiling environments, where the build's strip # is unlikely to handle the host's binaries. # Fortunately install-sh will honor a STRIPPROG variable, so we # always use install-sh in "make install-strip", and initialize # STRIPPROG with the value of the STRIP variable (set by the user). AC_DEFUN([AM_PROG_INSTALL_STRIP], [AC_REQUIRE([AM_PROG_INSTALL_SH])dnl # Installed binaries are usually stripped using 'strip' when the user # run "make install-strip". However 'strip' might not be the right # tool to use in cross-compilation environments, therefore Automake # will honor the 'STRIP' environment variable to overrule this program. dnl Don't test for $cross_compiling = yes, because it might be 'maybe'. if test "$cross_compiling" != no; then AC_CHECK_TOOL([STRIP], [strip], :) fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" AC_SUBST([INSTALL_STRIP_PROGRAM])]) # Copyright (C) 2006-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_SUBST_NOTMAKE(VARIABLE) # --------------------------- # Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. # This macro is traced by Automake. AC_DEFUN([_AM_SUBST_NOTMAKE]) # AM_SUBST_NOTMAKE(VARIABLE) # -------------------------- # Public sister of _AM_SUBST_NOTMAKE. AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) # Check how to create a tarball. -*- Autoconf -*- # Copyright (C) 2004-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_PROG_TAR(FORMAT) # -------------------- # Check how to create a tarball in format FORMAT. # FORMAT should be one of 'v7', 'ustar', or 'pax'. # # Substitute a variable $(am__tar) that is a command # writing to stdout a FORMAT-tarball containing the directory # $tardir. # tardir=directory && $(am__tar) > result.tar # # Substitute a variable $(am__untar) that extract such # a tarball read from stdin. # $(am__untar) < result.tar # AC_DEFUN([_AM_PROG_TAR], [# Always define AMTAR for backward compatibility. Yes, it's still used # in the wild :-( We should find a proper way to deprecate it ... AC_SUBST([AMTAR], ['$${TAR-tar}']) # We'll loop over all known methods to create a tar archive until one works. _am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' m4_if([$1], [v7], [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'], [m4_case([$1], [ustar], [# The POSIX 1988 'ustar' format is defined with fixed-size fields. # There is notably a 21 bits limit for the UID and the GID. In fact, # the 'pax' utility can hang on bigger UID/GID (see automake bug#8343 # and bug#13588). am_max_uid=2097151 # 2^21 - 1 am_max_gid=$am_max_uid # The $UID and $GID variables are not portable, so we need to resort # to the POSIX-mandated id(1) utility. Errors in the 'id' calls # below are definitely unexpected, so allow the users to see them # (that is, avoid stderr redirection). am_uid=`id -u || echo unknown` am_gid=`id -g || echo unknown` AC_MSG_CHECKING([whether UID '$am_uid' is supported by ustar format]) if test $am_uid -le $am_max_uid; then AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) _am_tools=none fi AC_MSG_CHECKING([whether GID '$am_gid' is supported by ustar format]) if test $am_gid -le $am_max_gid; then AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) _am_tools=none fi], [pax], [], [m4_fatal([Unknown tar format])]) AC_MSG_CHECKING([how to create a $1 tar archive]) # Go ahead even if we have the value already cached. We do so because we # need to set the values for the 'am__tar' and 'am__untar' variables. _am_tools=${am_cv_prog_tar_$1-$_am_tools} for _am_tool in $_am_tools; do case $_am_tool in gnutar) for _am_tar in tar gnutar gtar; do AM_RUN_LOG([$_am_tar --version]) && break done am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' am__untar="$_am_tar -xf -" ;; plaintar) # Must skip GNU tar: if it does not support --format= it doesn't create # ustar tarball either. (tar --version) >/dev/null 2>&1 && continue am__tar='tar chf - "$$tardir"' am__tar_='tar chf - "$tardir"' am__untar='tar xf -' ;; pax) am__tar='pax -L -x $1 -w "$$tardir"' am__tar_='pax -L -x $1 -w "$tardir"' am__untar='pax -r' ;; cpio) am__tar='find "$$tardir" -print | cpio -o -H $1 -L' am__tar_='find "$tardir" -print | cpio -o -H $1 -L' am__untar='cpio -i -H $1 -d' ;; none) am__tar=false am__tar_=false am__untar=false ;; esac # If the value was cached, stop now. We just wanted to have am__tar # and am__untar set. test -n "${am_cv_prog_tar_$1}" && break # tar/untar a dummy directory, and stop if the command works. rm -rf conftest.dir mkdir conftest.dir echo GrepMe > conftest.dir/file AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) rm -rf conftest.dir if test -s conftest.tar; then AM_RUN_LOG([$am__untar /dev/null 2>&1 && break fi done rm -rf conftest.dir AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) AC_MSG_RESULT([$am_cv_prog_tar_$1])]) AC_SUBST([am__tar]) AC_SUBST([am__untar]) ]) # _AM_PROG_TAR m4_include([m4/ax_check_atm.m4]) m4_include([m4/ax_check_openssl.m4]) m4_include([m4/ax_check_openssl_func.m4]) m4_include([m4/ax_check_pam.m4]) m4_include([m4/ax_check_pcap.m4]) m4_include([m4/ax_check_srp.m4]) m4_include([m4/libtool.m4]) m4_include([m4/ltoptions.m4]) m4_include([m4/ltsugar.m4]) m4_include([m4/ltversion.m4]) m4_include([m4/lt~obsolete.m4]) m4_include([m4/pkg.m4]) ppp-2.5.0/Makefile.in0000644000175000017500000007366214407475314011332 00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ @PPP_WITH_PLUGINS_TRUE@am__append_1 = pppd/plugins subdir = . ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_atm.m4 \ $(top_srcdir)/m4/ax_check_openssl.m4 \ $(top_srcdir)/m4/ax_check_openssl_func.m4 \ $(top_srcdir)/m4/ax_check_pam.m4 \ $(top_srcdir)/m4/ax_check_pcap.m4 \ $(top_srcdir)/m4/ax_check_srp.m4 $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/pkg.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(top_srcdir)/configure \ $(am__configure_deps) $(am__DIST_COMMON) am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ configure.lineno config.status.lineno mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/pppd/config.h \ $(top_builddir)/pppd/pppdconf.h \ $(top_builddir)/pppd/plugins/pppoe/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(sampledir)" DATA = $(sample_DATA) RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ cscope distdir distdir-am dist dist-all distcheck am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in AUTHORS COPYING ChangeLog \ INSTALL NEWS README compile config.guess config.sub depcomp \ install-sh ltmain.sh missing DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) distdir = $(PACKAGE)-$(VERSION) top_distdir = $(distdir) am__remove_distdir = \ if test -d "$(distdir)"; then \ find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \ && rm -rf "$(distdir)" \ || { sleep 5 && rm -rf "$(distdir)"; }; \ else :; fi am__post_remove_distdir = $(am__remove_distdir) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" DIST_ARCHIVES = $(distdir).tar.gz GZIP_ENV = --best DIST_TARGETS = dist-gzip # Exists only to be overridden by the user if desired. AM_DISTCHECK_DVI_TARGET = dvi distuninstallcheck_listfiles = find . -type f -print am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \ | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$' distcleancheck_listfiles = find . -type f -print ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ ATM_CFLAGS = @ATM_CFLAGS@ ATM_LDFLAGS = @ATM_LDFLAGS@ ATM_LIBS = @ATM_LIBS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CRYPT_LIBS = @CRYPT_LIBS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GREP = @GREP@ GTK_CFLAGS = @GTK_CFLAGS@ GTK_LIBS = @GTK_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_INCLUDES = @OPENSSL_INCLUDES@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAM_CFLAGS = @PAM_CFLAGS@ PAM_LDFLAGS = @PAM_LDFLAGS@ PAM_LIBS = @PAM_LIBS@ PATH_SEPARATOR = @PATH_SEPARATOR@ PCAP_CFLAGS = @PCAP_CFLAGS@ PCAP_LDFLAGS = @PCAP_LDFLAGS@ PCAP_LIBS = @PCAP_LIBS@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PPPD_LOGFILE_DIR = @PPPD_LOGFILE_DIR@ PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@ PPPD_RUNTIME_DIR = @PPPD_RUNTIME_DIR@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SRP_CFLAGS = @SRP_CFLAGS@ SRP_LDFLAGS = @SRP_LDFLAGS@ SRP_LIBS = @SRP_LIBS@ STRIP = @STRIP@ SYSTEMD_CFLAGS = @SYSTEMD_CFLAGS@ SYSTEMD_LIBS = @SYSTEMD_LIBS@ SYSTEM_CA_PATH = @SYSTEM_CA_PATH@ UTIL_LIBS = @UTIL_LIBS@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ ACLOCAL_AMFLAGS = "-Im4" SUBDIRS = chat contrib pppd pppstats pppdump $(am__append_1) DIST_SUBDIRS = $(SUBDIRS) common include modules scripts sampledir = $(sysconfdir)/$(PACKAGE) sample_DATA = \ etc.ppp/options \ etc.ppp/chap-secrets \ etc.ppp/pap-secrets \ etc.ppp/eaptls-server \ etc.ppp/eaptls-client \ etc.ppp/openssl.cnf EXTRA_README = \ Changes-2.3 \ FAQ \ README \ README.cbcp \ README.eap-srp \ README.eap-tls \ README.linux \ README.MPPE \ README.MSCHAP80 \ README.MSCHAP81 \ README.pppoe \ README.pppol2tp \ README.pwfd \ README.sol2 \ PLUGINS \ SETUP \ Submitting-patches.md EXTRA_SOLARIS = \ solaris/Makedefs \ solaris/Makedefs.gcc \ solaris/Makedefs.sol2 \ solaris/Makefile.sol2 \ solaris/Makefile.sol2-64 \ solaris/Makefile.sol2-64x \ solaris/Makefile.sol2gcc \ solaris/Makefile.sol2gcc-64 \ solaris/Makefile.sol2gcc-64x \ solaris/Makefile.top \ solaris/ppp_ahdlc.c \ solaris/ppp_ahdlc_mod.c \ solaris/ppp.c \ solaris/ppp_comp.c \ solaris/ppp_comp_mod.c \ solaris/ppp.conf \ solaris/ppp_mod.c \ solaris/ppp_mod.h EXTRA_DIST = \ $(sample_DATA) \ $(EXTRA_README) \ $(EXTRA_SOLARIS) all: all-recursive .SUFFIXES: am--refresh: Makefile @: $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ echo ' cd $(srcdir) && $(AUTOMAKE) --gnu'; \ $(am__cd) $(srcdir) && $(AUTOMAKE) --gnu \ && exit 0; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ echo ' $(SHELL) ./config.status'; \ $(SHELL) ./config.status;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) $(SHELL) ./config.status --recheck $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) $(am__cd) $(srcdir) && $(AUTOCONF) $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs distclean-libtool: -rm -f libtool config.lt install-sampleDATA: $(sample_DATA) @$(NORMAL_INSTALL) @list='$(sample_DATA)'; test -n "$(sampledir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(sampledir)'"; \ $(MKDIR_P) "$(DESTDIR)$(sampledir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(sampledir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(sampledir)" || exit $$?; \ done uninstall-sampleDATA: @$(NORMAL_UNINSTALL) @list='$(sample_DATA)'; test -n "$(sampledir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(sampledir)'; $(am__uninstall_files_from_dir) # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscope: cscope.files test ! -s cscope.files \ || $(CSCOPE) -b -q $(AM_CSCOPEFLAGS) $(CSCOPEFLAGS) -i cscope.files $(CSCOPE_ARGS) clean-cscope: -rm -f cscope.files cscope.files: clean-cscope cscopelist cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags -rm -f cscope.out cscope.in.out cscope.po.out cscope.files distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) $(am__remove_distdir) test -d "$(distdir)" || mkdir "$(distdir)" @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done -test -n "$(am__skip_mode_fix)" \ || find "$(distdir)" -type d ! -perm -755 \ -exec chmod u+rwx,go+rx {} \; -o \ ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ || chmod -R a+r "$(distdir)" dist-gzip: distdir tardir=$(distdir) && $(am__tar) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).tar.gz $(am__post_remove_distdir) dist-bzip2: distdir tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2 $(am__post_remove_distdir) dist-lzip: distdir tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz $(am__post_remove_distdir) dist-xz: distdir tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz $(am__post_remove_distdir) dist-zstd: distdir tardir=$(distdir) && $(am__tar) | zstd -c $${ZSTD_CLEVEL-$${ZSTD_OPT--19}} >$(distdir).tar.zst $(am__post_remove_distdir) dist-tarZ: distdir @echo WARNING: "Support for distribution archives compressed with" \ "legacy program 'compress' is deprecated." >&2 @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z $(am__post_remove_distdir) dist-shar: distdir @echo WARNING: "Support for shar distribution archives is" \ "deprecated." >&2 @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 shar $(distdir) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).shar.gz $(am__post_remove_distdir) dist-zip: distdir -rm -f $(distdir).zip zip -rq $(distdir).zip $(distdir) $(am__post_remove_distdir) dist dist-all: $(MAKE) $(AM_MAKEFLAGS) $(DIST_TARGETS) am__post_remove_distdir='@:' $(am__post_remove_distdir) # This target untars the dist file and tries a VPATH configuration. Then # it guarantees that the distribution is self-contained by making another # tarfile. distcheck: dist case '$(DIST_ARCHIVES)' in \ *.tar.gz*) \ eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).tar.gz | $(am__untar) ;;\ *.tar.bz2*) \ bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ *.tar.lz*) \ lzip -dc $(distdir).tar.lz | $(am__untar) ;;\ *.tar.xz*) \ xz -dc $(distdir).tar.xz | $(am__untar) ;;\ *.tar.Z*) \ uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ *.shar.gz*) \ eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).shar.gz | unshar ;;\ *.zip*) \ unzip $(distdir).zip ;;\ *.tar.zst*) \ zstd -dc $(distdir).tar.zst | $(am__untar) ;;\ esac chmod -R a-w $(distdir) chmod u+w $(distdir) mkdir $(distdir)/_build $(distdir)/_build/sub $(distdir)/_inst chmod a-w $(distdir) test -d $(distdir)/_build || exit 0; \ dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ && am__cwd=`pwd` \ && $(am__cd) $(distdir)/_build/sub \ && ../../configure \ $(AM_DISTCHECK_CONFIGURE_FLAGS) \ $(DISTCHECK_CONFIGURE_FLAGS) \ --srcdir=../.. --prefix="$$dc_install_base" \ && $(MAKE) $(AM_MAKEFLAGS) \ && $(MAKE) $(AM_MAKEFLAGS) $(AM_DISTCHECK_DVI_TARGET) \ && $(MAKE) $(AM_MAKEFLAGS) check \ && $(MAKE) $(AM_MAKEFLAGS) install \ && $(MAKE) $(AM_MAKEFLAGS) installcheck \ && $(MAKE) $(AM_MAKEFLAGS) uninstall \ && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ distuninstallcheck \ && chmod -R a-w "$$dc_install_base" \ && ({ \ (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ } || { rm -rf "$$dc_destdir"; exit 1; }) \ && rm -rf "$$dc_destdir" \ && $(MAKE) $(AM_MAKEFLAGS) dist \ && rm -rf $(DIST_ARCHIVES) \ && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \ && cd "$$am__cwd" \ || exit 1 $(am__post_remove_distdir) @(echo "$(distdir) archives ready for distribution: "; \ list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' distuninstallcheck: @test -n '$(distuninstallcheck_dir)' || { \ echo 'ERROR: trying to run $@ with an empty' \ '$$(distuninstallcheck_dir)' >&2; \ exit 1; \ }; \ $(am__cd) '$(distuninstallcheck_dir)' || { \ echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \ exit 1; \ }; \ test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \ || { echo "ERROR: files left after uninstall:" ; \ if test -n "$(DESTDIR)"; then \ echo " (check DESTDIR support)"; \ fi ; \ $(distuninstallcheck_listfiles) ; \ exit 1; } >&2 distcleancheck: distclean @if test '$(srcdir)' = . ; then \ echo "ERROR: distcleancheck can only run from a VPATH build" ; \ exit 1 ; \ fi @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ || { echo "ERROR: files left in build directory after distclean:" ; \ $(distcleancheck_listfiles) ; \ exit 1; } >&2 check-am: all-am check: check-recursive all-am: Makefile $(DATA) installdirs: installdirs-recursive installdirs-am: for dir in "$(DESTDIR)$(sampledir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive @SUNOS_FALSE@install-am: all-am @SUNOS_FALSE@ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: @SUNOS_FALSE@clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -f Makefile distclean-am: clean-am distclean-generic distclean-libtool \ distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-sampleDATA @$(NORMAL_INSTALL) $(MAKE) $(AM_MAKEFLAGS) install-data-hook install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -rf $(top_srcdir)/autom4te.cache -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: uninstall-sampleDATA .MAKE: $(am__recursive_targets) install-am install-data-am \ install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \ am--refresh check check-am clean clean-cscope clean-generic \ clean-libtool cscope cscopelist-am ctags ctags-am dist \ dist-all dist-bzip2 dist-gzip dist-lzip dist-shar dist-tarZ \ dist-xz dist-zip dist-zstd distcheck distclean \ distclean-generic distclean-libtool distclean-tags \ distcleancheck distdir distuninstallcheck dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-data-hook install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-sampleDATA \ install-strip installcheck installcheck-am installdirs \ installdirs-am maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ ps ps-am tags tags-am uninstall uninstall-am \ uninstall-sampleDATA .PRECIOUS: Makefile # # *HACK* # This is to work around the kernel module for PPP on Sun Solaris @SUNOS_TRUE@all-am: @SUNOS_TRUE@ (cd solaris ; $(MAKE) -f Makefile) @SUNOS_TRUE@clean-generic: @SUNOS_TRUE@ (cd solaris ; $(MAKE) -f Makefile clean) @SUNOS_TRUE@install-am: @SUNOS_TRUE@ (cd solaris ; $(MAKE) -f Makefile install) install-data-hook: (cd $(DESTDIR)/$(sysconfdir)/$(PACKAGE) ; \ chmod 600 chap-secrets pap-secrets eaptls-server eaptls-client) # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: ppp-2.5.0/AUTHORS0000664000175000017500000000026214076444143010317 00000000000000The pppd Project https://github.com/ppp-project/ppp Primary Author of this package: Linux Paul Mackerras Solaris James Carlson ppp-2.5.0/COPYING0000664000175000017500000000042614076444143010304 00000000000000Copyrights: *********** All of the code can be freely used and redistributed. The individual source files each have their own copyright and permission notice. Pppd, pppstats and pppdump are under BSD-style notices. Some of the pppd plugins are GPL'd. Chat is public domain. ppp-2.5.0/ChangeLog0000664000175000017500000000013214076444143011015 000000000000002021-07-11 Eivind Naess Introduction of Autotools to pppd project ppp-2.5.0/INSTALL0000644000175000017500000003662614071237055010310 00000000000000Installation Instructions ************************* Copyright (C) 1994-1996, 1999-2002, 2004-2017, 2020-2021 Free Software Foundation, Inc. Copying and distribution of this file, with or without modification, are permitted in any medium without royalty provided the copyright notice and this notice are preserved. This file is offered as-is, without warranty of any kind. Basic Installation ================== Briefly, the shell command './configure && make && make install' should configure, build, and install this package. The following more-detailed instructions are generic; see the 'README' file for instructions specific to this package. Some packages provide this 'INSTALL' file but do not implement all of the features documented below. The lack of an optional feature in a given package is not necessarily a bug. More recommendations for GNU packages can be found in *note Makefile Conventions: (standards)Makefile Conventions. The 'configure' shell script attempts to guess correct values for various system-dependent variables used during compilation. It uses those values to create a 'Makefile' in each directory of the package. It may also create one or more '.h' files containing system-dependent definitions. Finally, it creates a shell script 'config.status' that you can run in the future to recreate the current configuration, and a file 'config.log' containing compiler output (useful mainly for debugging 'configure'). It can also use an optional file (typically called 'config.cache' and enabled with '--cache-file=config.cache' or simply '-C') that saves the results of its tests to speed up reconfiguring. Caching is disabled by default to prevent problems with accidental use of stale cache files. If you need to do unusual things to compile the package, please try to figure out how 'configure' could check whether to do them, and mail diffs or instructions to the address given in the 'README' so they can be considered for the next release. If you are using the cache, and at some point 'config.cache' contains results you don't want to keep, you may remove or edit it. The file 'configure.ac' (or 'configure.in') is used to create 'configure' by a program called 'autoconf'. You need 'configure.ac' if you want to change it or regenerate 'configure' using a newer version of 'autoconf'. The simplest way to compile this package is: 1. 'cd' to the directory containing the package's source code and type './configure' to configure the package for your system. Running 'configure' might take a while. While running, it prints some messages telling which features it is checking for. 2. Type 'make' to compile the package. 3. Optionally, type 'make check' to run any self-tests that come with the package, generally using the just-built uninstalled binaries. 4. Type 'make install' to install the programs and any data files and documentation. When installing into a prefix owned by root, it is recommended that the package be configured and built as a regular user, and only the 'make install' phase executed with root privileges. 5. Optionally, type 'make installcheck' to repeat any self-tests, but this time using the binaries in their final installed location. This target does not install anything. Running this target as a regular user, particularly if the prior 'make install' required root privileges, verifies that the installation completed correctly. 6. You can remove the program binaries and object files from the source code directory by typing 'make clean'. To also remove the files that 'configure' created (so you can compile the package for a different kind of computer), type 'make distclean'. There is also a 'make maintainer-clean' target, but that is intended mainly for the package's developers. If you use it, you may have to get all sorts of other programs in order to regenerate files that came with the distribution. 7. Often, you can also type 'make uninstall' to remove the installed files again. In practice, not all packages have tested that uninstallation works correctly, even though it is required by the GNU Coding Standards. 8. Some packages, particularly those that use Automake, provide 'make distcheck', which can by used by developers to test that all other targets like 'make install' and 'make uninstall' work correctly. This target is generally not run by end users. Compilers and Options ===================== Some systems require unusual options for compilation or linking that the 'configure' script does not know about. Run './configure --help' for details on some of the pertinent environment variables. You can give 'configure' initial values for configuration parameters by setting variables in the command line or in the environment. Here is an example: ./configure CC=c99 CFLAGS=-g LIBS=-lposix *Note Defining Variables::, for more details. Compiling For Multiple Architectures ==================================== You can compile the package for more than one kind of computer at the same time, by placing the object files for each architecture in their own directory. To do this, you can use GNU 'make'. 'cd' to the directory where you want the object files and executables to go and run the 'configure' script. 'configure' automatically checks for the source code in the directory that 'configure' is in and in '..'. This is known as a "VPATH" build. With a non-GNU 'make', it is safer to compile the package for one architecture at a time in the source code directory. After you have installed the package for one architecture, use 'make distclean' before reconfiguring for another architecture. On MacOS X 10.5 and later systems, you can create libraries and executables that work on multiple system types--known as "fat" or "universal" binaries--by specifying multiple '-arch' options to the compiler but only a single '-arch' option to the preprocessor. Like this: ./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ CPP="gcc -E" CXXCPP="g++ -E" This is not guaranteed to produce working output in all cases, you may have to build one architecture at a time and combine the results using the 'lipo' tool if you have problems. Installation Names ================== By default, 'make install' installs the package's commands under '/usr/local/bin', include files under '/usr/local/include', etc. You can specify an installation prefix other than '/usr/local' by giving 'configure' the option '--prefix=PREFIX', where PREFIX must be an absolute file name. You can specify separate installation prefixes for architecture-specific files and architecture-independent files. If you pass the option '--exec-prefix=PREFIX' to 'configure', the package uses PREFIX as the prefix for installing programs and libraries. Documentation and other data files still use the regular prefix. In addition, if you use an unusual directory layout you can give options like '--bindir=DIR' to specify different values for particular kinds of files. Run 'configure --help' for a list of the directories you can set and what kinds of files go in them. In general, the default for these options is expressed in terms of '${prefix}', so that specifying just '--prefix' will affect all of the other directory specifications that were not explicitly provided. The most portable way to affect installation locations is to pass the correct locations to 'configure'; however, many packages provide one or both of the following shortcuts of passing variable assignments to the 'make install' command line to change installation locations without having to reconfigure or recompile. The first method involves providing an override variable for each affected directory. For example, 'make install prefix=/alternate/directory' will choose an alternate location for all directory configuration variables that were expressed in terms of '${prefix}'. Any directories that were specified during 'configure', but not in terms of '${prefix}', must each be overridden at install time for the entire installation to be relocated. The approach of makefile variable overrides for each directory variable is required by the GNU Coding Standards, and ideally causes no recompilation. However, some platforms have known limitations with the semantics of shared libraries that end up requiring recompilation when using this method, particularly noticeable in packages that use GNU Libtool. The second method involves providing the 'DESTDIR' variable. For example, 'make install DESTDIR=/alternate/directory' will prepend '/alternate/directory' before all installation names. The approach of 'DESTDIR' overrides is not required by the GNU Coding Standards, and does not work on platforms that have drive letters. On the other hand, it does better at avoiding recompilation issues, and works well even when some directory options were not specified in terms of '${prefix}' at 'configure' time. Optional Features ================= If the package supports it, you can cause programs to be installed with an extra prefix or suffix on their names by giving 'configure' the option '--program-prefix=PREFIX' or '--program-suffix=SUFFIX'. Some packages pay attention to '--enable-FEATURE' options to 'configure', where FEATURE indicates an optional part of the package. They may also pay attention to '--with-PACKAGE' options, where PACKAGE is something like 'gnu-as' or 'x' (for the X Window System). The 'README' should mention any '--enable-' and '--with-' options that the package recognizes. For packages that use the X Window System, 'configure' can usually find the X include and library files automatically, but if it doesn't, you can use the 'configure' options '--x-includes=DIR' and '--x-libraries=DIR' to specify their locations. Some packages offer the ability to configure how verbose the execution of 'make' will be. For these packages, running './configure --enable-silent-rules' sets the default to minimal output, which can be overridden with 'make V=1'; while running './configure --disable-silent-rules' sets the default to verbose, which can be overridden with 'make V=0'. Particular systems ================== On HP-UX, the default C compiler is not ANSI C compatible. If GNU CC is not installed, it is recommended to use the following options in order to use an ANSI C compiler: ./configure CC="cc -Ae -D_XOPEN_SOURCE=500" and if that doesn't work, install pre-built binaries of GCC for HP-UX. HP-UX 'make' updates targets which have the same timestamps as their prerequisites, which makes it generally unusable when shipped generated files such as 'configure' are involved. Use GNU 'make' instead. On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot parse its '' header file. The option '-nodtk' can be used as a workaround. If GNU CC is not installed, it is therefore recommended to try ./configure CC="cc" and if that doesn't work, try ./configure CC="cc -nodtk" On Solaris, don't put '/usr/ucb' early in your 'PATH'. This directory contains several dysfunctional programs; working variants of these programs are available in '/usr/bin'. So, if you need '/usr/ucb' in your 'PATH', put it _after_ '/usr/bin'. On Haiku, software installed for all users goes in '/boot/common', not '/usr/local'. It is recommended to use the following options: ./configure --prefix=/boot/common Specifying the System Type ========================== There may be some features 'configure' cannot figure out automatically, but needs to determine by the type of machine the package will run on. Usually, assuming the package is built to be run on the _same_ architectures, 'configure' can figure that out, but if it prints a message saying it cannot guess the machine type, give it the '--build=TYPE' option. TYPE can either be a short name for the system type, such as 'sun4', or a canonical name which has the form: CPU-COMPANY-SYSTEM where SYSTEM can have one of these forms: OS KERNEL-OS See the file 'config.sub' for the possible values of each field. If 'config.sub' isn't included in this package, then this package doesn't need to know the machine type. If you are _building_ compiler tools for cross-compiling, you should use the option '--target=TYPE' to select the type of system they will produce code for. If you want to _use_ a cross compiler, that generates code for a platform different from the build platform, you should specify the "host" platform (i.e., that on which the generated programs will eventually be run) with '--host=TYPE'. Sharing Defaults ================ If you want to set default values for 'configure' scripts to share, you can create a site shell script called 'config.site' that gives default values for variables like 'CC', 'cache_file', and 'prefix'. 'configure' looks for 'PREFIX/share/config.site' if it exists, then 'PREFIX/etc/config.site' if it exists. Or, you can set the 'CONFIG_SITE' environment variable to the location of the site script. A warning: not all 'configure' scripts look for a site script. Defining Variables ================== Variables not defined in a site shell script can be set in the environment passed to 'configure'. However, some packages may run configure again during the build, and the customized values of these variables may be lost. In order to avoid this problem, you should set them in the 'configure' command line, using 'VAR=value'. For example: ./configure CC=/usr/local2/bin/gcc causes the specified 'gcc' to be used as the C compiler (unless it is overridden in the site shell script). Unfortunately, this technique does not work for 'CONFIG_SHELL' due to an Autoconf limitation. Until the limitation is lifted, you can use this workaround: CONFIG_SHELL=/bin/bash ./configure CONFIG_SHELL=/bin/bash 'configure' Invocation ====================== 'configure' recognizes the following options to control how it operates. '--help' '-h' Print a summary of all of the options to 'configure', and exit. '--help=short' '--help=recursive' Print a summary of the options unique to this package's 'configure', and exit. The 'short' variant lists options used only in the top level, while the 'recursive' variant lists options also present in any nested packages. '--version' '-V' Print the version of Autoconf used to generate the 'configure' script, and exit. '--cache-file=FILE' Enable the cache: use and save the results of the tests in FILE, traditionally 'config.cache'. FILE defaults to '/dev/null' to disable caching. '--config-cache' '-C' Alias for '--cache-file=config.cache'. '--quiet' '--silent' '-q' Do not print messages saying which checks are being made. To suppress all normal output, redirect it to '/dev/null' (any error messages will still be shown). '--srcdir=DIR' Look for the package's source code in directory DIR. Usually 'configure' can determine that directory automatically. '--prefix=DIR' Use DIR as the installation prefix. *note Installation Names:: for more details, including other options available for fine-tuning the installation locations. '--no-create' '-n' Run the configure checks, but stop before creating any output files. 'configure' also accepts some other, not widely useful, options. Run 'configure --help' for more details. ppp-2.5.0/NEWS0000664000175000017500000002340314146100255007737 00000000000000What's new since ppp-2.4.9 (unreleased) *************************************** * New pppd options: - ipv6-up-script - ipv6-down-script What's new in ppp-2.4.9. ************************ * Support for new EAP (Extensible Authentication Protocol) methods: - Support for EAP-TLS, from Jan Just Keijser and others - Support for EAP-MSCHAPv2, from Eivind Næss, Thomas Omerzu, Tijs Van Buggenhout and others * New pppd options: - chap-timeout - chapms-strip-domain - replacedefaultroute - noreplacedefaultroute - ipv6cp-accept-remote - lcp-echo-adaptive - ip-up-script - ip-down-script - ca - capath - cert - key - crl-dir - crl - max-tls-version - need-peer-eap * Fixes for CVE-2020-8597 and CVE-2015-3310. * libpcap is now required when compiling on Linux (previously, if libpcap was not present, pppd would be compiled without packet filtering support). * The rp-pppoe plugin has been renamed to pppoe, to distinguish it from the upstream rp-pppoe code. Its options have changed names, but the old names are kept as aliases. * The configure script now supports cross-compilation. * Many bug fixes and cleanups. What was new in ppp-2.4.8. ************************** * New pppd options have been added: - ifname, to set the name for the PPP interface device - defaultroute-metric, to set the metric for the default route - defaultroute6, to add an IPv6 default route (with nodefaultroute6 to prevent adding an IPv6 default route) - up_sdnotify, to have pppd notify systemd when the link is up. * The rp-pppoe plugin has new options: - host-uniq, to set the Host-Uniq value to send - pppoe-padi-timeout, to set the timeout for discovery packets - pppoe-padi-attempts, to set the number of discovery attempts. * Added the CLASS attribute in radius packets. * Sundry bug fixes. * Fixed warnings and issues found by static analysis. * Added Submitting-patches.md. What was new in ppp-2.4.7. ************************** * Fixed a potential security issue in parsing option files (CVE-2014-3158). * There is a new "stop-bits" option, which takes an argument of 1 or 2, indicating the number of stop bits to use for async serial ports. * Various bug fixes. What was new in ppp-2.4.6. ************************** * Man page updates. * Several bug fixes. * Options files can now set and unset environment variables for scripts. * The timeout for chat scripts can now be taken from an environment variable. * There is a new option, master_detach, which allows pppd to detach from the controlling terminal when it is the multilink bundle master but its own link has terminated, even if the nodetach option has been given. What was new in ppp-2.4.5. ************************** * Under Linux, pppd can now operate in a mode where it doesn't request the peer's IP address, as some peers refuse to supply an IP address. Since Linux supports device routes as well as gateway routes, it's possible to have no remote IP address assigned to the ppp interface and still route traffic over it. * Pppd now works better with 3G modems that do strange things such as sending IPCP Configure-Naks with the same values over and over again. * The PPP over L2TP plugin is included, which works with the pppol2tp PPP channel code in the Linux kernel. This allows pppd to be used to set up tunnels using the Layer 2 Tunneling Protocol. * A new 'enable-session' option has been added, which enables session accounting via PAM or wtwp/wtmpx, as appropriate. See the pppd man page for details. * Several bugs have been fixed. What was new in ppp-2.4.4. ************************** * Pppd will now run /etc/ppp/ip-pre-up, if it exists, after creating the ppp interface and configuring its IP addresses but before bringing it up. This can be used, for example, for adding firewall rules for the interface. * Lots of bugs fixed, particularly in the area of demand-dialled and persistent connections. * The rp-pppoe plugin now accepts any interface name (that isn't an existing pppd option name) without putting "nic-" on the front of it, not just eth*, nas*, tap* and br*. What was new in ppp-2.4.3. ************************** * The configure script now accepts --prefix and --sysconfdir options. These default to /usr/local and /etc. If you want pppd put in /usr/sbin as before, use ./configure --prefix=/usr. * Doing `make install' no longer puts example configuration files in /etc/ppp. Use `make install-etcppp' if you want that. * The code has been updated to work with version 0.8.3 of libpcap. Unfortunately the libpcap maintainers removed support for the "inbound" and "outbound" keywords on PPP links, meaning that if you link pppd with libpcap-0.8.3, you can't use those keywords in the active-filter and pass-filter expressions. The support has been reinstated in the CVS version and should be in future libpcap releases. If you need the in/outbound keywords, use a later release than 0.8.3, or get the CVS version from http://www.tcpdump.org. * There is a new option, child-timeout, which sets the length of time that pppd will wait for child processes (such as the command specified with the pty option) to exit before exiting itself. It defaults to 5 seconds. After the timeout, pppd will send a SIGTERM to any remaining child processes and exit. A value of 0 means no timeout. * Various bugs have been fixed, including some CBCP packet parsing bugs that could lead to the peer being able to crash pppd if CBCP support is enabled. * Various fixes and enhancements to the radius and rp-pppoe plugins have been added. * There is a new winbind plugin, from Andrew Bartlet of the Samba team, which provides the ability to authenticate the peer against an NT domain controller using MS-CHAP or MS-CHAPV2. * There is a new pppoatm plugin, by various authors, sent in by David Woodhouse. * The multilink code has been substantially reworked. The first pppd for a bundle still controls the ppp interface, but it doesn't exit until all the links in the bundle have terminated. If the first pppd is signalled to exit, it signals all the other pppds controlling links in the bundle. * The TDB code has been updated to the latest version. This should eliminate the problem that some people have seen where the database file (/var/run/pppd.tdb) keeps on growing. Unfortunately, however, the new code uses an incompatible database format. For this reason, pppd now uses /var/run/pppd2.tdb as the database filename. What was new in ppp-2.4.2. ************************** * The CHAP code has been rewritten. Pppd now has support for MS-CHAP V1 and V2 authentication, both as server and client. The new CHAP code is cleaner than the old code and avoids some copyright problems that existed in the old code. * MPPE (Microsoft Point-to-Point Encryption) support has been added, although the current implementation shouldn't be considered completely secure. (There is no assurance that the current code won't ever transmit an unencrypted packet.) * James Carlson's implementation of the Extensible Authentication Protocol (EAP) has been added. * Support for the Encryption Control Protocol (ECP) has been added. * Some new plug-ins have been included: - A plug-in for kernel-mode PPPoE (PPP over Ethernet) - A plug-in for supplying the PAP password over a pipe from another process - A plug-in for authenticating using a Radius server. * Updates and bug-fixes for the Solaris port. * The CBCP (Call Back Control Protocol) code has been updated. There are new options `remotenumber' and `allow-number'. * Extra hooks for plugins to use have been added. * There is now a `maxoctets' option, which causes pppd to terminate the link once the number of bytes passed on the link exceeds a given value. * There are now options to control whether pppd can use the IPCP IP-Address and IP-Addresses options: `ipcp-no-address' and `ipcp-no-addresses'. * Fixed several bugs, including potential buffer overflows in chat. What was new in ppp-2.4.1. ************************** * Pppd can now print out the set of options that are in effect. The new `dump' option causes pppd to print out the option values after option parsing is complete. The `dryrun' option causes pppd to print the options and then exit. * The option parsing code has been fixed so that options in the per-tty options file are parsed correctly, and don't override values from the command line in most cases. * The plugin option now looks in /usr/lib/pppd/ (for example, /usr/lib/pppd/2.4.1b1) for shared objects for plugins if there is no slash in the plugin name. * When loading a plugin, pppd will now check the version of pppd for which the plugin was compiled, and refuse to load it if it is different to pppd's version string. To enable this, the plugin source needs to #include "pppd.h" and have a line saying: char pppd_version[] = VERSION; * There is a bug in zlib, discovered by James Carlson, which can cause kernel memory corruption if Deflate is used with the lowest setting, 8. As a workaround pppd will now insist on using at least 9. * Pppd should compile on Solaris and SunOS again. * Pppd should now set the MTU correctly on demand-dialled interfaces. What was new in ppp-2.4.0. ************************** * Multilink: this package now allows you to combine multiple serial links into one logical link or `bundle', for increased bandwidth and reduced latency. This is currently only supported under the 2.4.x and later Linux kernels. * All the pppd processes running on a system now write information into a common database. I used the `tdb' code from samba for this. * New hooks have been added. For a list of the changes made during the 2.3 series releases of this package, see the Changes-2.3 file. ppp-2.5.0/README0000644000175000017500000001371614407475306010140 00000000000000This is the README file for ppp-2.5, a package which implements the Point-to-Point Protocol (PPP) to provide Internet connections over serial lines and other types of links which can be considered to be point-to-point links. Introduction. ************* The Point-to-Point Protocol (PPP) provides a standard way to establish a network connection over a serial link. At present, this package supports IP and IPV6 and the protocols layered above them, such as TCP and UDP. This PPP implementation consists of two parts: - Kernel code, which establishes a network interface and passes packets between the serial port, the kernel networking code and the PPP daemon (pppd). This code is implemented using STREAMS modules on Solaris, and as a line discipline under Linux. - The PPP daemon (pppd), which negotiates with the peer to establish the link and sets up the ppp network interface. Pppd includes support for authentication, so you can control which other systems may make a PPP connection and what IP addresses they may use. The platforms supported by this package are Linux and Solaris. I have code for NeXTStep, FreeBSD, SunOS 4.x, SVR4, Tru64 (Digital Unix), AIX and Ultrix but no active maintainers for these platforms. Code for all of these except AIX is included in the ppp-2.3.11 release. The kernel code for Linux is no longer distributed with this package, since the relevant kernel code is in the official Linux kernel source (and has been for many years) and is included in all reasonably modern Linux distributions. The Linux kernel code supports using PPP over things other than serial ports, such as PPP over Ethernet and PPP over ATM. Installation. ************* The file SETUP contains general information about setting up your system for using PPP. There is also a README file for each supported system, which contains more specific details for installing PPP on that system. The supported systems, and the corresponding README files, are: Linux README.linux Solaris README.sol2 In each case you start by running the ./configure script. This works out which operating system you are using and creates the appropriate makefiles. You then run `make' to compile the user-level code, and (as root) `make install' to install the user-level programs pppd, chat and pppstats. N.B. Since 2.3.0, leaving the permitted IP addresses column of the pap-secrets or chap-secrets file empty means that no addresses are permitted. You need to put a "*" in that column to allow the peer to use any IP address. (This only applies where the peer is authenticating itself to you, of course.) What's new in ppp-2.5.0. ************************ The 2.5.0 release is a major release of pppd which contains breaking changes for third-party plugins, a complete revamp of the build-system and that allows for flexibility of configuring features as needed. In Summary: * Support for PEAP authentication by Eivind Næss and Rustam Kovhaev * Support for loading PKCS12 certificate envelopes * Adoption of GNU Autoconf / Automake build environment, by Eivind Næss and others. * Support for pkgconfig tool has been added by Eivind Næss. * Bunch of fixes and cleanup to PPPoE and IPv6 support by Pali Rohár. * Major revision to PPPD's Plugin API by Eivind Næss. - Defines in which describes what features was included in pppd - Functions now prefixed with explicit ppp_* to indicate that pppd functions being called. - Header files were renamed to better align with their features, and now use proper include guards - A pppdconf.h file is supplied to allow third-party modules to use the same feature defines pppd was compiled with. - No extern declarations of internal variable names of pppd, continued use of these extern variables are considered unstable. * Lots of internal fixes and cleanups for Radius and PPPoE by Jaco Kroon * Dropped IPX support, as Linux has dropped support in version 5.15 for this protocol. * Many more fixes and cleanups. * Pppd is no longer installed setuid-root. * New pppd options: - ipv6cp-noremote, ipv6cp-nosend, ipv6cp-use-remotenumber, ipv6-up-script, ipv6-down-script - -v, show-options - usepeerwins, ipcp-no-address, ipcp-no-addresses, nosendip * On Linux, any baud rate can be set on a serial port provided the kernel serial driver supports that. Note that if you have built and installed previous versions of this package and you want to continue having configuration and TDB files in /etc/ppp, you will need to use the --sysconfdir option to ./configure. For a list of the changes made during the 2.4 series releases of this package, see the Changes-2.4 file. Compression methods. ******************** This package supports two packet compression methods: Deflate and BSD-Compress. Other compression methods which are in common use include Predictor, LZS, and MPPC. These methods are not supported for two reasons - they are patent-encumbered, and they cause some packets to expand slightly, which pppd doesn't currently allow for. BSD-Compress and Deflate (which uses the same algorithm as gzip) don't ever expand packets. Contacts. ********* Most communication relating to this package happens on github at https://github.com/ppp-project/ppp/. The linux-ppp@vger.kernel.org mailing list also exists and can be used. If you find bugs in this package, the best thing to do is to create an issue on github. If you can't or don't want to do that, you can post to linux-ppp@vger.kernel.org, or report them to the maintainer for the port for the operating system you are using: Linux Paul Mackerras Solaris James Carlson Copyrights: *********** All of the code can be freely used and redistributed. The individual source files each have their own copyright and permission notice. Pppd, pppstats and pppdump are under BSD-style notices. Some of the pppd plugins are GPL'd. Chat is public domain. Distribution: ************* The primary site for releases of this software is: ftp://ftp.samba.org/pub/ppp/ ppp-2.5.0/compile0000755000175000017500000001635014072725711010627 00000000000000#! /bin/sh # Wrapper for compilers which do not understand '-c -o'. scriptversion=2018-03-07.03; # UTC # Copyright (C) 1999-2021 Free Software Foundation, Inc. # Written by Tom Tromey . # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # This file is maintained in Automake, please report # bugs to or send patches to # . nl=' ' # We need space, tab and new line, in precisely that order. Quoting is # there to prevent tools from complaining about whitespace usage. IFS=" "" $nl" file_conv= # func_file_conv build_file lazy # Convert a $build file to $host form and store it in $file # Currently only supports Windows hosts. If the determined conversion # type is listed in (the comma separated) LAZY, no conversion will # take place. func_file_conv () { file=$1 case $file in / | /[!/]*) # absolute file, and not a UNC file if test -z "$file_conv"; then # lazily determine how to convert abs files case `uname -s` in MINGW*) file_conv=mingw ;; CYGWIN* | MSYS*) file_conv=cygwin ;; *) file_conv=wine ;; esac fi case $file_conv/,$2, in *,$file_conv,*) ;; mingw/*) file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'` ;; cygwin/* | msys/*) file=`cygpath -m "$file" || echo "$file"` ;; wine/*) file=`winepath -w "$file" || echo "$file"` ;; esac ;; esac } # func_cl_dashL linkdir # Make cl look for libraries in LINKDIR func_cl_dashL () { func_file_conv "$1" if test -z "$lib_path"; then lib_path=$file else lib_path="$lib_path;$file" fi linker_opts="$linker_opts -LIBPATH:$file" } # func_cl_dashl library # Do a library search-path lookup for cl func_cl_dashl () { lib=$1 found=no save_IFS=$IFS IFS=';' for dir in $lib_path $LIB do IFS=$save_IFS if $shared && test -f "$dir/$lib.dll.lib"; then found=yes lib=$dir/$lib.dll.lib break fi if test -f "$dir/$lib.lib"; then found=yes lib=$dir/$lib.lib break fi if test -f "$dir/lib$lib.a"; then found=yes lib=$dir/lib$lib.a break fi done IFS=$save_IFS if test "$found" != yes; then lib=$lib.lib fi } # func_cl_wrapper cl arg... # Adjust compile command to suit cl func_cl_wrapper () { # Assume a capable shell lib_path= shared=: linker_opts= for arg do if test -n "$eat"; then eat= else case $1 in -o) # configure might choose to run compile as 'compile cc -o foo foo.c'. eat=1 case $2 in *.o | *.[oO][bB][jJ]) func_file_conv "$2" set x "$@" -Fo"$file" shift ;; *) func_file_conv "$2" set x "$@" -Fe"$file" shift ;; esac ;; -I) eat=1 func_file_conv "$2" mingw set x "$@" -I"$file" shift ;; -I*) func_file_conv "${1#-I}" mingw set x "$@" -I"$file" shift ;; -l) eat=1 func_cl_dashl "$2" set x "$@" "$lib" shift ;; -l*) func_cl_dashl "${1#-l}" set x "$@" "$lib" shift ;; -L) eat=1 func_cl_dashL "$2" ;; -L*) func_cl_dashL "${1#-L}" ;; -static) shared=false ;; -Wl,*) arg=${1#-Wl,} save_ifs="$IFS"; IFS=',' for flag in $arg; do IFS="$save_ifs" linker_opts="$linker_opts $flag" done IFS="$save_ifs" ;; -Xlinker) eat=1 linker_opts="$linker_opts $2" ;; -*) set x "$@" "$1" shift ;; *.cc | *.CC | *.cxx | *.CXX | *.[cC]++) func_file_conv "$1" set x "$@" -Tp"$file" shift ;; *.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO]) func_file_conv "$1" mingw set x "$@" "$file" shift ;; *) set x "$@" "$1" shift ;; esac fi shift done if test -n "$linker_opts"; then linker_opts="-link$linker_opts" fi exec "$@" $linker_opts exit 1 } eat= case $1 in '') echo "$0: No command. Try '$0 --help' for more information." 1>&2 exit 1; ;; -h | --h*) cat <<\EOF Usage: compile [--help] [--version] PROGRAM [ARGS] Wrapper for compilers which do not understand '-c -o'. Remove '-o dest.o' from ARGS, run PROGRAM with the remaining arguments, and rename the output as expected. If you are trying to build a whole package this is not the right script to run: please start by reading the file 'INSTALL'. Report bugs to . EOF exit $? ;; -v | --v*) echo "compile $scriptversion" exit $? ;; cl | *[/\\]cl | cl.exe | *[/\\]cl.exe | \ icl | *[/\\]icl | icl.exe | *[/\\]icl.exe ) func_cl_wrapper "$@" # Doesn't return... ;; esac ofile= cfile= for arg do if test -n "$eat"; then eat= else case $1 in -o) # configure might choose to run compile as 'compile cc -o foo foo.c'. # So we strip '-o arg' only if arg is an object. eat=1 case $2 in *.o | *.obj) ofile=$2 ;; *) set x "$@" -o "$2" shift ;; esac ;; *.c) cfile=$1 set x "$@" "$1" shift ;; *) set x "$@" "$1" shift ;; esac fi shift done if test -z "$ofile" || test -z "$cfile"; then # If no '-o' option was seen then we might have been invoked from a # pattern rule where we don't need one. That is ok -- this is a # normal compilation that the losing compiler can handle. If no # '.c' file was seen then we are probably linking. That is also # ok. exec "$@" fi # Name of file we expect compiler to create. cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'` # Create the lock directory. # Note: use '[/\\:.-]' here to ensure that we don't use the same name # that we are using for the .o file. Also, base the name on the expected # object file name, since that is what matters with a parallel build. lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d while true; do if mkdir "$lockdir" >/dev/null 2>&1; then break fi sleep 1 done # FIXME: race condition here if user kills between mkdir and trap. trap "rmdir '$lockdir'; exit 1" 1 2 15 # Run the compile. "$@" ret=$? if test -f "$cofile"; then test "$cofile" = "$ofile" || mv "$cofile" "$ofile" elif test -f "${cofile}bj"; then test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile" fi rmdir "$lockdir" exit $ret # Local Variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC0" # time-stamp-end: "; # UTC" # End: ppp-2.5.0/config.guess0000755000175000017500000014120514247602205011563 00000000000000#!/usr/bin/sh # Attempt to guess a canonical system name. # Copyright 1992-2022 Free Software Foundation, Inc. # shellcheck disable=SC2006,SC2268 # see below for rationale timestamp='2022-05-25' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, see . # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that # program. This Exception is an additional permission under section 7 # of the GNU General Public License, version 3 ("GPLv3"). # # Originally written by Per Bothner; maintained since 2000 by Ben Elliston. # # You can get the latest version of this script from: # https://git.savannah.gnu.org/cgit/config.git/plain/config.guess # # Please send patches to . # The "shellcheck disable" line above the timestamp inhibits complaints # about features and limitations of the classic Bourne shell that were # superseded or lifted in POSIX. However, this script identifies a wide # variety of pre-POSIX systems that do not have POSIX shells at all, and # even some reasonably current systems (Solaris 10 as case-in-point) still # have a pre-POSIX /bin/sh. me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] Output the configuration name of the system \`$me' is run on. Options: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.guess ($timestamp) Originally written by Per Bothner. Copyright 1992-2022 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit ;; --version | -v ) echo "$version" ; exit ;; --help | --h* | -h ) echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" >&2 exit 1 ;; * ) break ;; esac done if test $# != 0; then echo "$me: too many arguments$help" >&2 exit 1 fi # Just in case it came from the environment. GUESS= # CC_FOR_BUILD -- compiler used by this script. Note that the use of a # compiler to aid in system detection is discouraged as it requires # temporary files to be created and, as you can see below, it is a # headache to deal with in a portable fashion. # Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still # use `HOST_CC' if defined, but it is deprecated. # Portable tmp directory creation inspired by the Autoconf team. tmp= # shellcheck disable=SC2172 trap 'test -z "$tmp" || rm -fr "$tmp"' 0 1 2 13 15 set_cc_for_build() { # prevent multiple calls if $tmp is already set test "$tmp" && return 0 : "${TMPDIR=/tmp}" # shellcheck disable=SC2039,SC3028 { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir "$tmp" 2>/dev/null) ; } || { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir "$tmp" 2>/dev/null) && echo "Warning: creating insecure temp directory" >&2 ; } || { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } dummy=$tmp/dummy case ${CC_FOR_BUILD-},${HOST_CC-},${CC-} in ,,) echo "int x;" > "$dummy.c" for driver in cc gcc c89 c99 ; do if ($driver -c -o "$dummy.o" "$dummy.c") >/dev/null 2>&1 ; then CC_FOR_BUILD=$driver break fi done if test x"$CC_FOR_BUILD" = x ; then CC_FOR_BUILD=no_compiler_found fi ;; ,,*) CC_FOR_BUILD=$CC ;; ,*,*) CC_FOR_BUILD=$HOST_CC ;; esac } # This is needed to find uname on a Pyramid OSx when run in the BSD universe. # (ghazi@noc.rutgers.edu 1994-08-24) if test -f /.attbin/uname ; then PATH=$PATH:/.attbin ; export PATH fi UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown case $UNAME_SYSTEM in Linux|GNU|GNU/*) LIBC=unknown set_cc_for_build cat <<-EOF > "$dummy.c" #include #if defined(__UCLIBC__) LIBC=uclibc #elif defined(__dietlibc__) LIBC=dietlibc #elif defined(__GLIBC__) LIBC=gnu #else #include /* First heuristic to detect musl libc. */ #ifdef __DEFINED_va_list LIBC=musl #endif #endif EOF cc_set_libc=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^LIBC' | sed 's, ,,g'` eval "$cc_set_libc" # Second heuristic to detect musl libc. if [ "$LIBC" = unknown ] && command -v ldd >/dev/null && ldd --version 2>&1 | grep -q ^musl; then LIBC=musl fi # If the system lacks a compiler, then just pick glibc. # We could probably try harder. if [ "$LIBC" = unknown ]; then LIBC=gnu fi ;; esac # Note: order is significant - the case branches are not exclusive. case $UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION in *:NetBSD:*:*) # NetBSD (nbsd) targets should (where applicable) match one or # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*, # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently # switched to ELF, *-*-netbsd* would select the old # object file format. This provides both forward # compatibility and a consistent mechanism for selecting the # object file format. # # Note: NetBSD doesn't particularly care about the vendor # portion of the name. We always set it to "unknown". UNAME_MACHINE_ARCH=`(uname -p 2>/dev/null || \ /sbin/sysctl -n hw.machine_arch 2>/dev/null || \ /usr/sbin/sysctl -n hw.machine_arch 2>/dev/null || \ echo unknown)` case $UNAME_MACHINE_ARCH in aarch64eb) machine=aarch64_be-unknown ;; armeb) machine=armeb-unknown ;; arm*) machine=arm-unknown ;; sh3el) machine=shl-unknown ;; sh3eb) machine=sh-unknown ;; sh5el) machine=sh5le-unknown ;; earmv*) arch=`echo "$UNAME_MACHINE_ARCH" | sed -e 's,^e\(armv[0-9]\).*$,\1,'` endian=`echo "$UNAME_MACHINE_ARCH" | sed -ne 's,^.*\(eb\)$,\1,p'` machine=${arch}${endian}-unknown ;; *) machine=$UNAME_MACHINE_ARCH-unknown ;; esac # The Operating System including object format, if it has switched # to ELF recently (or will in the future) and ABI. case $UNAME_MACHINE_ARCH in earm*) os=netbsdelf ;; arm*|i386|m68k|ns32k|sh3*|sparc|vax) set_cc_for_build if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ELF__ then # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). # Return netbsd for either. FIX? os=netbsd else os=netbsdelf fi ;; *) os=netbsd ;; esac # Determine ABI tags. case $UNAME_MACHINE_ARCH in earm*) expr='s/^earmv[0-9]/-eabi/;s/eb$//' abi=`echo "$UNAME_MACHINE_ARCH" | sed -e "$expr"` ;; esac # The OS release # Debian GNU/NetBSD machines have a different userland, and # thus, need a distinct triplet. However, they do not need # kernel version information, so it can be replaced with a # suitable tag, in the style of linux-gnu. case $UNAME_VERSION in Debian*) release='-gnu' ;; *) release=`echo "$UNAME_RELEASE" | sed -e 's/[-_].*//' | cut -d. -f1,2` ;; esac # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: # contains redundant information, the shorter form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. GUESS=$machine-${os}${release}${abi-} ;; *:Bitrig:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` GUESS=$UNAME_MACHINE_ARCH-unknown-bitrig$UNAME_RELEASE ;; *:OpenBSD:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` GUESS=$UNAME_MACHINE_ARCH-unknown-openbsd$UNAME_RELEASE ;; *:SecBSD:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/SecBSD.//'` GUESS=$UNAME_MACHINE_ARCH-unknown-secbsd$UNAME_RELEASE ;; *:LibertyBSD:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/^.*BSD\.//'` GUESS=$UNAME_MACHINE_ARCH-unknown-libertybsd$UNAME_RELEASE ;; *:MidnightBSD:*:*) GUESS=$UNAME_MACHINE-unknown-midnightbsd$UNAME_RELEASE ;; *:ekkoBSD:*:*) GUESS=$UNAME_MACHINE-unknown-ekkobsd$UNAME_RELEASE ;; *:SolidBSD:*:*) GUESS=$UNAME_MACHINE-unknown-solidbsd$UNAME_RELEASE ;; *:OS108:*:*) GUESS=$UNAME_MACHINE-unknown-os108_$UNAME_RELEASE ;; macppc:MirBSD:*:*) GUESS=powerpc-unknown-mirbsd$UNAME_RELEASE ;; *:MirBSD:*:*) GUESS=$UNAME_MACHINE-unknown-mirbsd$UNAME_RELEASE ;; *:Sortix:*:*) GUESS=$UNAME_MACHINE-unknown-sortix ;; *:Twizzler:*:*) GUESS=$UNAME_MACHINE-unknown-twizzler ;; *:Redox:*:*) GUESS=$UNAME_MACHINE-unknown-redox ;; mips:OSF1:*.*) GUESS=mips-dec-osf1 ;; alpha:OSF1:*:*) # Reset EXIT trap before exiting to avoid spurious non-zero exit code. trap '' 0 case $UNAME_RELEASE in *4.0) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` ;; *5.*) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` ;; esac # According to Compaq, /usr/sbin/psrinfo has been available on # OSF/1 and Tru64 systems produced since 1995. I hope that # covers most systems running today. This code pipes the CPU # types through head -n 1, so we only detect the type of CPU 0. ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` case $ALPHA_CPU_TYPE in "EV4 (21064)") UNAME_MACHINE=alpha ;; "EV4.5 (21064)") UNAME_MACHINE=alpha ;; "LCA4 (21066/21068)") UNAME_MACHINE=alpha ;; "EV5 (21164)") UNAME_MACHINE=alphaev5 ;; "EV5.6 (21164A)") UNAME_MACHINE=alphaev56 ;; "EV5.6 (21164PC)") UNAME_MACHINE=alphapca56 ;; "EV5.7 (21164PC)") UNAME_MACHINE=alphapca57 ;; "EV6 (21264)") UNAME_MACHINE=alphaev6 ;; "EV6.7 (21264A)") UNAME_MACHINE=alphaev67 ;; "EV6.8CB (21264C)") UNAME_MACHINE=alphaev68 ;; "EV6.8AL (21264B)") UNAME_MACHINE=alphaev68 ;; "EV6.8CX (21264D)") UNAME_MACHINE=alphaev68 ;; "EV6.9A (21264/EV69A)") UNAME_MACHINE=alphaev69 ;; "EV7 (21364)") UNAME_MACHINE=alphaev7 ;; "EV7.9 (21364A)") UNAME_MACHINE=alphaev79 ;; esac # A Pn.n version is a patched version. # A Vn.n version is a released version. # A Tn.n version is a released field test version. # A Xn.n version is an unreleased experimental baselevel. # 1.2 uses "1.2" for uname -r. OSF_REL=`echo "$UNAME_RELEASE" | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz` GUESS=$UNAME_MACHINE-dec-osf$OSF_REL ;; Amiga*:UNIX_System_V:4.0:*) GUESS=m68k-unknown-sysv4 ;; *:[Aa]miga[Oo][Ss]:*:*) GUESS=$UNAME_MACHINE-unknown-amigaos ;; *:[Mm]orph[Oo][Ss]:*:*) GUESS=$UNAME_MACHINE-unknown-morphos ;; *:OS/390:*:*) GUESS=i370-ibm-openedition ;; *:z/VM:*:*) GUESS=s390-ibm-zvmoe ;; *:OS400:*:*) GUESS=powerpc-ibm-os400 ;; arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) GUESS=arm-acorn-riscix$UNAME_RELEASE ;; arm*:riscos:*:*|arm*:RISCOS:*:*) GUESS=arm-unknown-riscos ;; SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) GUESS=hppa1.1-hitachi-hiuxmpp ;; Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. case `(/bin/universe) 2>/dev/null` in att) GUESS=pyramid-pyramid-sysv3 ;; *) GUESS=pyramid-pyramid-bsd ;; esac ;; NILE*:*:*:dcosx) GUESS=pyramid-pyramid-svr4 ;; DRS?6000:unix:4.0:6*) GUESS=sparc-icl-nx6 ;; DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) case `/usr/bin/uname -p` in sparc) GUESS=sparc-icl-nx7 ;; esac ;; s390x:SunOS:*:*) SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` GUESS=$UNAME_MACHINE-ibm-solaris2$SUN_REL ;; sun4H:SunOS:5.*:*) SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` GUESS=sparc-hal-solaris2$SUN_REL ;; sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` GUESS=sparc-sun-solaris2$SUN_REL ;; i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) GUESS=i386-pc-auroraux$UNAME_RELEASE ;; i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) set_cc_for_build SUN_ARCH=i386 # If there is a compiler, see if it is configured for 64-bit objects. # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. # This test works for both compilers. if test "$CC_FOR_BUILD" != no_compiler_found; then if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ (CCOPTS="" $CC_FOR_BUILD -m64 -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null then SUN_ARCH=x86_64 fi fi SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` GUESS=$SUN_ARCH-pc-solaris2$SUN_REL ;; sun4*:SunOS:6*:*) # According to config.sub, this is the proper way to canonicalize # SunOS6. Hard to guess exactly what SunOS6 will be like, but # it's likely to be more like Solaris than SunOS4. SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` GUESS=sparc-sun-solaris3$SUN_REL ;; sun4*:SunOS:*:*) case `/usr/bin/arch -k` in Series*|S4*) UNAME_RELEASE=`uname -v` ;; esac # Japanese Language versions have a version number like `4.1.3-JL'. SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/-/_/'` GUESS=sparc-sun-sunos$SUN_REL ;; sun3*:SunOS:*:*) GUESS=m68k-sun-sunos$UNAME_RELEASE ;; sun*:*:4.2BSD:*) UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` test "x$UNAME_RELEASE" = x && UNAME_RELEASE=3 case `/bin/arch` in sun3) GUESS=m68k-sun-sunos$UNAME_RELEASE ;; sun4) GUESS=sparc-sun-sunos$UNAME_RELEASE ;; esac ;; aushp:SunOS:*:*) GUESS=sparc-auspex-sunos$UNAME_RELEASE ;; # The situation for MiNT is a little confusing. The machine name # can be virtually everything (everything which is not # "atarist" or "atariste" at least should have a processor # > m68000). The system name ranges from "MiNT" over "FreeMiNT" # to the lowercase version "mint" (or "freemint"). Finally # the system name "TOS" denotes a system which is actually not # MiNT. But MiNT is downward compatible to TOS, so this should # be no problem. atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) GUESS=m68k-atari-mint$UNAME_RELEASE ;; atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) GUESS=m68k-atari-mint$UNAME_RELEASE ;; *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) GUESS=m68k-atari-mint$UNAME_RELEASE ;; milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) GUESS=m68k-milan-mint$UNAME_RELEASE ;; hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) GUESS=m68k-hades-mint$UNAME_RELEASE ;; *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) GUESS=m68k-unknown-mint$UNAME_RELEASE ;; m68k:machten:*:*) GUESS=m68k-apple-machten$UNAME_RELEASE ;; powerpc:machten:*:*) GUESS=powerpc-apple-machten$UNAME_RELEASE ;; RISC*:Mach:*:*) GUESS=mips-dec-mach_bsd4.3 ;; RISC*:ULTRIX:*:*) GUESS=mips-dec-ultrix$UNAME_RELEASE ;; VAX*:ULTRIX*:*:*) GUESS=vax-dec-ultrix$UNAME_RELEASE ;; 2020:CLIX:*:* | 2430:CLIX:*:*) GUESS=clipper-intergraph-clix$UNAME_RELEASE ;; mips:*:*:UMIPS | mips:*:*:RISCos) set_cc_for_build sed 's/^ //' << EOF > "$dummy.c" #ifdef __cplusplus #include /* for printf() prototype */ int main (int argc, char *argv[]) { #else int main (argc, argv) int argc; char *argv[]; { #endif #if defined (host_mips) && defined (MIPSEB) #if defined (SYSTYPE_SYSV) printf ("mips-mips-riscos%ssysv\\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_SVR4) printf ("mips-mips-riscos%ssvr4\\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) printf ("mips-mips-riscos%sbsd\\n", argv[1]); exit (0); #endif #endif exit (-1); } EOF $CC_FOR_BUILD -o "$dummy" "$dummy.c" && dummyarg=`echo "$UNAME_RELEASE" | sed -n 's/\([0-9]*\).*/\1/p'` && SYSTEM_NAME=`"$dummy" "$dummyarg"` && { echo "$SYSTEM_NAME"; exit; } GUESS=mips-mips-riscos$UNAME_RELEASE ;; Motorola:PowerMAX_OS:*:*) GUESS=powerpc-motorola-powermax ;; Motorola:*:4.3:PL8-*) GUESS=powerpc-harris-powermax ;; Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) GUESS=powerpc-harris-powermax ;; Night_Hawk:Power_UNIX:*:*) GUESS=powerpc-harris-powerunix ;; m88k:CX/UX:7*:*) GUESS=m88k-harris-cxux7 ;; m88k:*:4*:R4*) GUESS=m88k-motorola-sysv4 ;; m88k:*:3*:R3*) GUESS=m88k-motorola-sysv3 ;; AViiON:dgux:*:*) # DG/UX returns AViiON for all architectures UNAME_PROCESSOR=`/usr/bin/uname -p` if test "$UNAME_PROCESSOR" = mc88100 || test "$UNAME_PROCESSOR" = mc88110 then if test "$TARGET_BINARY_INTERFACE"x = m88kdguxelfx || \ test "$TARGET_BINARY_INTERFACE"x = x then GUESS=m88k-dg-dgux$UNAME_RELEASE else GUESS=m88k-dg-dguxbcs$UNAME_RELEASE fi else GUESS=i586-dg-dgux$UNAME_RELEASE fi ;; M88*:DolphinOS:*:*) # DolphinOS (SVR3) GUESS=m88k-dolphin-sysv3 ;; M88*:*:R3*:*) # Delta 88k system running SVR3 GUESS=m88k-motorola-sysv3 ;; XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) GUESS=m88k-tektronix-sysv3 ;; Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) GUESS=m68k-tektronix-bsd ;; *:IRIX*:*:*) IRIX_REL=`echo "$UNAME_RELEASE" | sed -e 's/-/_/g'` GUESS=mips-sgi-irix$IRIX_REL ;; ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. GUESS=romp-ibm-aix # uname -m gives an 8 hex-code CPU id ;; # Note that: echo "'`uname -s`'" gives 'AIX ' i*86:AIX:*:*) GUESS=i386-ibm-aix ;; ia64:AIX:*:*) if test -x /usr/bin/oslevel ; then IBM_REV=`/usr/bin/oslevel` else IBM_REV=$UNAME_VERSION.$UNAME_RELEASE fi GUESS=$UNAME_MACHINE-ibm-aix$IBM_REV ;; *:AIX:2:3) if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then set_cc_for_build sed 's/^ //' << EOF > "$dummy.c" #include main() { if (!__power_pc()) exit(1); puts("powerpc-ibm-aix3.2.5"); exit(0); } EOF if $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` then GUESS=$SYSTEM_NAME else GUESS=rs6000-ibm-aix3.2.5 fi elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then GUESS=rs6000-ibm-aix3.2.4 else GUESS=rs6000-ibm-aix3.2 fi ;; *:AIX:*:[4567]) IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` if /usr/sbin/lsattr -El "$IBM_CPU_ID" | grep ' POWER' >/dev/null 2>&1; then IBM_ARCH=rs6000 else IBM_ARCH=powerpc fi if test -x /usr/bin/lslpp ; then IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc | \ awk -F: '{ print $3 }' | sed s/[0-9]*$/0/` else IBM_REV=$UNAME_VERSION.$UNAME_RELEASE fi GUESS=$IBM_ARCH-ibm-aix$IBM_REV ;; *:AIX:*:*) GUESS=rs6000-ibm-aix ;; ibmrt:4.4BSD:*|romp-ibm:4.4BSD:*) GUESS=romp-ibm-bsd4.4 ;; ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and GUESS=romp-ibm-bsd$UNAME_RELEASE # 4.3 with uname added to ;; # report: romp-ibm BSD 4.3 *:BOSX:*:*) GUESS=rs6000-bull-bosx ;; DPX/2?00:B.O.S.:*:*) GUESS=m68k-bull-sysv3 ;; 9000/[34]??:4.3bsd:1.*:*) GUESS=m68k-hp-bsd ;; hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) GUESS=m68k-hp-bsd4.4 ;; 9000/[34678]??:HP-UX:*:*) HPUX_REV=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*.[0B]*//'` case $UNAME_MACHINE in 9000/31?) HP_ARCH=m68000 ;; 9000/[34]??) HP_ARCH=m68k ;; 9000/[678][0-9][0-9]) if test -x /usr/bin/getconf; then sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` case $sc_cpu_version in 523) HP_ARCH=hppa1.0 ;; # CPU_PA_RISC1_0 528) HP_ARCH=hppa1.1 ;; # CPU_PA_RISC1_1 532) # CPU_PA_RISC2_0 case $sc_kernel_bits in 32) HP_ARCH=hppa2.0n ;; 64) HP_ARCH=hppa2.0w ;; '') HP_ARCH=hppa2.0 ;; # HP-UX 10.20 esac ;; esac fi if test "$HP_ARCH" = ""; then set_cc_for_build sed 's/^ //' << EOF > "$dummy.c" #define _HPUX_SOURCE #include #include int main () { #if defined(_SC_KERNEL_BITS) long bits = sysconf(_SC_KERNEL_BITS); #endif long cpu = sysconf (_SC_CPU_VERSION); switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0"); break; case CPU_PA_RISC1_1: puts ("hppa1.1"); break; case CPU_PA_RISC2_0: #if defined(_SC_KERNEL_BITS) switch (bits) { case 64: puts ("hppa2.0w"); break; case 32: puts ("hppa2.0n"); break; default: puts ("hppa2.0"); break; } break; #else /* !defined(_SC_KERNEL_BITS) */ puts ("hppa2.0"); break; #endif default: puts ("hppa1.0"); break; } exit (0); } EOF (CCOPTS="" $CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null) && HP_ARCH=`"$dummy"` test -z "$HP_ARCH" && HP_ARCH=hppa fi ;; esac if test "$HP_ARCH" = hppa2.0w then set_cc_for_build # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler # generating 64-bit code. GNU and HP use different nomenclature: # # $ CC_FOR_BUILD=cc ./config.guess # => hppa2.0w-hp-hpux11.23 # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess # => hppa64-hp-hpux11.23 if echo __LP64__ | (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | grep -q __LP64__ then HP_ARCH=hppa2.0w else HP_ARCH=hppa64 fi fi GUESS=$HP_ARCH-hp-hpux$HPUX_REV ;; ia64:HP-UX:*:*) HPUX_REV=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*.[0B]*//'` GUESS=ia64-hp-hpux$HPUX_REV ;; 3050*:HI-UX:*:*) set_cc_for_build sed 's/^ //' << EOF > "$dummy.c" #include int main () { long cpu = sysconf (_SC_CPU_VERSION); /* The order matters, because CPU_IS_HP_MC68K erroneously returns true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct results, however. */ if (CPU_IS_PA_RISC (cpu)) { switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; default: puts ("hppa-hitachi-hiuxwe2"); break; } } else if (CPU_IS_HP_MC68K (cpu)) puts ("m68k-hitachi-hiuxwe2"); else puts ("unknown-hitachi-hiuxwe2"); exit (0); } EOF $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` && { echo "$SYSTEM_NAME"; exit; } GUESS=unknown-hitachi-hiuxwe2 ;; 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:*) GUESS=hppa1.1-hp-bsd ;; 9000/8??:4.3bsd:*:*) GUESS=hppa1.0-hp-bsd ;; *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) GUESS=hppa1.0-hp-mpeix ;; hp7??:OSF1:*:* | hp8?[79]:OSF1:*:*) GUESS=hppa1.1-hp-osf ;; hp8??:OSF1:*:*) GUESS=hppa1.0-hp-osf ;; i*86:OSF1:*:*) if test -x /usr/sbin/sysversion ; then GUESS=$UNAME_MACHINE-unknown-osf1mk else GUESS=$UNAME_MACHINE-unknown-osf1 fi ;; parisc*:Lites*:*:*) GUESS=hppa1.1-hp-lites ;; C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) GUESS=c1-convex-bsd ;; C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi exit ;; C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) GUESS=c34-convex-bsd ;; C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) GUESS=c38-convex-bsd ;; C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) GUESS=c4-convex-bsd ;; CRAY*Y-MP:*:*:*) CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'` GUESS=ymp-cray-unicos$CRAY_REL ;; CRAY*[A-Z]90:*:*:*) echo "$UNAME_MACHINE"-cray-unicos"$UNAME_RELEASE" \ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ -e 's/\.[^.]*$/.X/' exit ;; CRAY*TS:*:*:*) CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'` GUESS=t90-cray-unicos$CRAY_REL ;; CRAY*T3E:*:*:*) CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'` GUESS=alphaev5-cray-unicosmk$CRAY_REL ;; CRAY*SV1:*:*:*) CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'` GUESS=sv1-cray-unicos$CRAY_REL ;; *:UNICOS/mp:*:*) CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'` GUESS=craynv-cray-unicosmp$CRAY_REL ;; F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) FUJITSU_PROC=`uname -m | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz` FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` FUJITSU_REL=`echo "$UNAME_RELEASE" | sed -e 's/ /_/'` GUESS=${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL} ;; 5000:UNIX_System_V:4.*:*) FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` FUJITSU_REL=`echo "$UNAME_RELEASE" | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/'` GUESS=sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL} ;; i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) GUESS=$UNAME_MACHINE-pc-bsdi$UNAME_RELEASE ;; sparc*:BSD/OS:*:*) GUESS=sparc-unknown-bsdi$UNAME_RELEASE ;; *:BSD/OS:*:*) GUESS=$UNAME_MACHINE-unknown-bsdi$UNAME_RELEASE ;; arm:FreeBSD:*:*) UNAME_PROCESSOR=`uname -p` set_cc_for_build if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_PCS_VFP then FREEBSD_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` GUESS=$UNAME_PROCESSOR-unknown-freebsd$FREEBSD_REL-gnueabi else FREEBSD_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` GUESS=$UNAME_PROCESSOR-unknown-freebsd$FREEBSD_REL-gnueabihf fi ;; *:FreeBSD:*:*) UNAME_PROCESSOR=`/usr/bin/uname -p` case $UNAME_PROCESSOR in amd64) UNAME_PROCESSOR=x86_64 ;; i386) UNAME_PROCESSOR=i586 ;; esac FREEBSD_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` GUESS=$UNAME_PROCESSOR-unknown-freebsd$FREEBSD_REL ;; i*:CYGWIN*:*) GUESS=$UNAME_MACHINE-pc-cygwin ;; *:MINGW64*:*) GUESS=$UNAME_MACHINE-pc-mingw64 ;; *:MINGW*:*) GUESS=$UNAME_MACHINE-pc-mingw32 ;; *:MSYS*:*) GUESS=$UNAME_MACHINE-pc-msys ;; i*:PW*:*) GUESS=$UNAME_MACHINE-pc-pw32 ;; *:SerenityOS:*:*) GUESS=$UNAME_MACHINE-pc-serenity ;; *:Interix*:*) case $UNAME_MACHINE in x86) GUESS=i586-pc-interix$UNAME_RELEASE ;; authenticamd | genuineintel | EM64T) GUESS=x86_64-unknown-interix$UNAME_RELEASE ;; IA64) GUESS=ia64-unknown-interix$UNAME_RELEASE ;; esac ;; i*:UWIN*:*) GUESS=$UNAME_MACHINE-pc-uwin ;; amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) GUESS=x86_64-pc-cygwin ;; prep*:SunOS:5.*:*) SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` GUESS=powerpcle-unknown-solaris2$SUN_REL ;; *:GNU:*:*) # the GNU system GNU_ARCH=`echo "$UNAME_MACHINE" | sed -e 's,[-/].*$,,'` GNU_REL=`echo "$UNAME_RELEASE" | sed -e 's,/.*$,,'` GUESS=$GNU_ARCH-unknown-$LIBC$GNU_REL ;; *:GNU/*:*:*) # other systems with GNU libc and userland GNU_SYS=`echo "$UNAME_SYSTEM" | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]"` GNU_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` GUESS=$UNAME_MACHINE-unknown-$GNU_SYS$GNU_REL-$LIBC ;; *:Minix:*:*) GUESS=$UNAME_MACHINE-unknown-minix ;; aarch64:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; aarch64_be:Linux:*:*) UNAME_MACHINE=aarch64_be GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; alpha:Linux:*:*) case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' /proc/cpuinfo 2>/dev/null` in EV5) UNAME_MACHINE=alphaev5 ;; EV56) UNAME_MACHINE=alphaev56 ;; PCA56) UNAME_MACHINE=alphapca56 ;; PCA57) UNAME_MACHINE=alphapca56 ;; EV6) UNAME_MACHINE=alphaev6 ;; EV67) UNAME_MACHINE=alphaev67 ;; EV68*) UNAME_MACHINE=alphaev68 ;; esac objdump --private-headers /bin/sh | grep -q ld.so.1 if test "$?" = 0 ; then LIBC=gnulibc1 ; fi GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; arc:Linux:*:* | arceb:Linux:*:* | arc32:Linux:*:* | arc64:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; arm*:Linux:*:*) set_cc_for_build if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_EABI__ then GUESS=$UNAME_MACHINE-unknown-linux-$LIBC else if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_PCS_VFP then GUESS=$UNAME_MACHINE-unknown-linux-${LIBC}eabi else GUESS=$UNAME_MACHINE-unknown-linux-${LIBC}eabihf fi fi ;; avr32*:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; cris:Linux:*:*) GUESS=$UNAME_MACHINE-axis-linux-$LIBC ;; crisv32:Linux:*:*) GUESS=$UNAME_MACHINE-axis-linux-$LIBC ;; e2k:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; frv:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; hexagon:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; i*86:Linux:*:*) GUESS=$UNAME_MACHINE-pc-linux-$LIBC ;; ia64:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; k1om:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; loongarch32:Linux:*:* | loongarch64:Linux:*:* | loongarchx32:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; m32r*:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; m68*:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; mips:Linux:*:* | mips64:Linux:*:*) set_cc_for_build IS_GLIBC=0 test x"${LIBC}" = xgnu && IS_GLIBC=1 sed 's/^ //' << EOF > "$dummy.c" #undef CPU #undef mips #undef mipsel #undef mips64 #undef mips64el #if ${IS_GLIBC} && defined(_ABI64) LIBCABI=gnuabi64 #else #if ${IS_GLIBC} && defined(_ABIN32) LIBCABI=gnuabin32 #else LIBCABI=${LIBC} #endif #endif #if ${IS_GLIBC} && defined(__mips64) && defined(__mips_isa_rev) && __mips_isa_rev>=6 CPU=mipsisa64r6 #else #if ${IS_GLIBC} && !defined(__mips64) && defined(__mips_isa_rev) && __mips_isa_rev>=6 CPU=mipsisa32r6 #else #if defined(__mips64) CPU=mips64 #else CPU=mips #endif #endif #endif #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) MIPS_ENDIAN=el #else #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) MIPS_ENDIAN= #else MIPS_ENDIAN= #endif #endif EOF cc_set_vars=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^CPU\|^MIPS_ENDIAN\|^LIBCABI'` eval "$cc_set_vars" test "x$CPU" != x && { echo "$CPU${MIPS_ENDIAN}-unknown-linux-$LIBCABI"; exit; } ;; mips64el:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; openrisc*:Linux:*:*) GUESS=or1k-unknown-linux-$LIBC ;; or32:Linux:*:* | or1k*:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; padre:Linux:*:*) GUESS=sparc-unknown-linux-$LIBC ;; parisc64:Linux:*:* | hppa64:Linux:*:*) GUESS=hppa64-unknown-linux-$LIBC ;; parisc:Linux:*:* | hppa:Linux:*:*) # Look for CPU level case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in PA7*) GUESS=hppa1.1-unknown-linux-$LIBC ;; PA8*) GUESS=hppa2.0-unknown-linux-$LIBC ;; *) GUESS=hppa-unknown-linux-$LIBC ;; esac ;; ppc64:Linux:*:*) GUESS=powerpc64-unknown-linux-$LIBC ;; ppc:Linux:*:*) GUESS=powerpc-unknown-linux-$LIBC ;; ppc64le:Linux:*:*) GUESS=powerpc64le-unknown-linux-$LIBC ;; ppcle:Linux:*:*) GUESS=powerpcle-unknown-linux-$LIBC ;; riscv32:Linux:*:* | riscv32be:Linux:*:* | riscv64:Linux:*:* | riscv64be:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; s390:Linux:*:* | s390x:Linux:*:*) GUESS=$UNAME_MACHINE-ibm-linux-$LIBC ;; sh64*:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; sh*:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; sparc:Linux:*:* | sparc64:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; tile*:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; vax:Linux:*:*) GUESS=$UNAME_MACHINE-dec-linux-$LIBC ;; x86_64:Linux:*:*) set_cc_for_build CPU=$UNAME_MACHINE LIBCABI=$LIBC if test "$CC_FOR_BUILD" != no_compiler_found; then ABI=64 sed 's/^ //' << EOF > "$dummy.c" #ifdef __i386__ ABI=x86 #else #ifdef __ILP32__ ABI=x32 #endif #endif EOF cc_set_abi=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^ABI' | sed 's, ,,g'` eval "$cc_set_abi" case $ABI in x86) CPU=i686 ;; x32) LIBCABI=${LIBC}x32 ;; esac fi GUESS=$CPU-pc-linux-$LIBCABI ;; xtensa*:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; i*86:DYNIX/ptx:4*:*) # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. # earlier versions are messed up and put the nodename in both # sysname and nodename. GUESS=i386-sequent-sysv4 ;; i*86:UNIX_SV:4.2MP:2.*) # Unixware is an offshoot of SVR4, but it has its own version # number series starting with 2... # I am not positive that other SVR4 systems won't match this, # I just have to hope. -- rms. # Use sysv4.2uw... so that sysv4* matches it. GUESS=$UNAME_MACHINE-pc-sysv4.2uw$UNAME_VERSION ;; i*86:OS/2:*:*) # If we were able to find `uname', then EMX Unix compatibility # is probably installed. GUESS=$UNAME_MACHINE-pc-os2-emx ;; i*86:XTS-300:*:STOP) GUESS=$UNAME_MACHINE-unknown-stop ;; i*86:atheos:*:*) GUESS=$UNAME_MACHINE-unknown-atheos ;; i*86:syllable:*:*) GUESS=$UNAME_MACHINE-pc-syllable ;; i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) GUESS=i386-unknown-lynxos$UNAME_RELEASE ;; i*86:*DOS:*:*) GUESS=$UNAME_MACHINE-pc-msdosdjgpp ;; i*86:*:4.*:*) UNAME_REL=`echo "$UNAME_RELEASE" | sed 's/\/MP$//'` if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then GUESS=$UNAME_MACHINE-univel-sysv$UNAME_REL else GUESS=$UNAME_MACHINE-pc-sysv$UNAME_REL fi ;; i*86:*:5:[678]*) # UnixWare 7.x, OpenUNIX and OpenServer 6. case `/bin/uname -X | grep "^Machine"` in *486*) UNAME_MACHINE=i486 ;; *Pentium) UNAME_MACHINE=i586 ;; *Pent*|*Celeron) UNAME_MACHINE=i686 ;; esac GUESS=$UNAME_MACHINE-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} ;; i*86:*:3.2:*) if test -f /usr/options/cb.name; then UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ && UNAME_MACHINE=i586 (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ && UNAME_MACHINE=i686 (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ && UNAME_MACHINE=i686 GUESS=$UNAME_MACHINE-pc-sco$UNAME_REL else GUESS=$UNAME_MACHINE-pc-sysv32 fi ;; pc:*:*:*) # Left here for compatibility: # uname -m prints for DJGPP always 'pc', but it prints nothing about # the processor, so we play safe by assuming i586. # Note: whatever this is, it MUST be the same as what config.sub # prints for the "djgpp" host, or else GDB configure will decide that # this is a cross-build. GUESS=i586-pc-msdosdjgpp ;; Intel:Mach:3*:*) GUESS=i386-pc-mach3 ;; paragon:*:*:*) GUESS=i860-intel-osf1 ;; i860:*:4.*:*) # i860-SVR4 if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then GUESS=i860-stardent-sysv$UNAME_RELEASE # Stardent Vistra i860-SVR4 else # Add other i860-SVR4 vendors below as they are discovered. GUESS=i860-unknown-sysv$UNAME_RELEASE # Unknown i860-SVR4 fi ;; mini*:CTIX:SYS*5:*) # "miniframe" GUESS=m68010-convergent-sysv ;; mc68k:UNIX:SYSTEM5:3.51m) GUESS=m68k-convergent-sysv ;; M680?0:D-NIX:5.3:*) GUESS=m68k-diab-dnix ;; M68*:*:R3V[5678]*:*) test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) OS_REL='' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4.3"$OS_REL"; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;; 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4; exit; } ;; NCR*:*:4.2:* | MPRAS*:*:4.2:*) OS_REL='.3' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4.3"$OS_REL"; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;; m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) GUESS=m68k-unknown-lynxos$UNAME_RELEASE ;; mc68030:UNIX_System_V:4.*:*) GUESS=m68k-atari-sysv4 ;; TSUNAMI:LynxOS:2.*:*) GUESS=sparc-unknown-lynxos$UNAME_RELEASE ;; rs6000:LynxOS:2.*:*) GUESS=rs6000-unknown-lynxos$UNAME_RELEASE ;; PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) GUESS=powerpc-unknown-lynxos$UNAME_RELEASE ;; SM[BE]S:UNIX_SV:*:*) GUESS=mips-dde-sysv$UNAME_RELEASE ;; RM*:ReliantUNIX-*:*:*) GUESS=mips-sni-sysv4 ;; RM*:SINIX-*:*:*) GUESS=mips-sni-sysv4 ;; *:SINIX-*:*:*) if uname -p 2>/dev/null >/dev/null ; then UNAME_MACHINE=`(uname -p) 2>/dev/null` GUESS=$UNAME_MACHINE-sni-sysv4 else GUESS=ns32k-sni-sysv fi ;; PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort # says GUESS=i586-unisys-sysv4 ;; *:UNIX_System_V:4*:FTX*) # From Gerald Hewes . # How about differentiating between stratus architectures? -djm GUESS=hppa1.1-stratus-sysv4 ;; *:*:*:FTX*) # From seanf@swdc.stratus.com. GUESS=i860-stratus-sysv4 ;; i*86:VOS:*:*) # From Paul.Green@stratus.com. GUESS=$UNAME_MACHINE-stratus-vos ;; *:VOS:*:*) # From Paul.Green@stratus.com. GUESS=hppa1.1-stratus-vos ;; mc68*:A/UX:*:*) GUESS=m68k-apple-aux$UNAME_RELEASE ;; news*:NEWS-OS:6*:*) GUESS=mips-sony-newsos6 ;; R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) if test -d /usr/nec; then GUESS=mips-nec-sysv$UNAME_RELEASE else GUESS=mips-unknown-sysv$UNAME_RELEASE fi ;; BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. GUESS=powerpc-be-beos ;; BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. GUESS=powerpc-apple-beos ;; BePC:BeOS:*:*) # BeOS running on Intel PC compatible. GUESS=i586-pc-beos ;; BePC:Haiku:*:*) # Haiku running on Intel PC compatible. GUESS=i586-pc-haiku ;; ppc:Haiku:*:*) # Haiku running on Apple PowerPC GUESS=powerpc-apple-haiku ;; *:Haiku:*:*) # Haiku modern gcc (not bound by BeOS compat) GUESS=$UNAME_MACHINE-unknown-haiku ;; SX-4:SUPER-UX:*:*) GUESS=sx4-nec-superux$UNAME_RELEASE ;; SX-5:SUPER-UX:*:*) GUESS=sx5-nec-superux$UNAME_RELEASE ;; SX-6:SUPER-UX:*:*) GUESS=sx6-nec-superux$UNAME_RELEASE ;; SX-7:SUPER-UX:*:*) GUESS=sx7-nec-superux$UNAME_RELEASE ;; SX-8:SUPER-UX:*:*) GUESS=sx8-nec-superux$UNAME_RELEASE ;; SX-8R:SUPER-UX:*:*) GUESS=sx8r-nec-superux$UNAME_RELEASE ;; SX-ACE:SUPER-UX:*:*) GUESS=sxace-nec-superux$UNAME_RELEASE ;; Power*:Rhapsody:*:*) GUESS=powerpc-apple-rhapsody$UNAME_RELEASE ;; *:Rhapsody:*:*) GUESS=$UNAME_MACHINE-apple-rhapsody$UNAME_RELEASE ;; arm64:Darwin:*:*) GUESS=aarch64-apple-darwin$UNAME_RELEASE ;; *:Darwin:*:*) UNAME_PROCESSOR=`uname -p` case $UNAME_PROCESSOR in unknown) UNAME_PROCESSOR=powerpc ;; esac if command -v xcode-select > /dev/null 2> /dev/null && \ ! xcode-select --print-path > /dev/null 2> /dev/null ; then # Avoid executing cc if there is no toolchain installed as # cc will be a stub that puts up a graphical alert # prompting the user to install developer tools. CC_FOR_BUILD=no_compiler_found else set_cc_for_build fi if test "$CC_FOR_BUILD" != no_compiler_found; then if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null then case $UNAME_PROCESSOR in i386) UNAME_PROCESSOR=x86_64 ;; powerpc) UNAME_PROCESSOR=powerpc64 ;; esac fi # On 10.4-10.6 one might compile for PowerPC via gcc -arch ppc if (echo '#ifdef __POWERPC__'; echo IS_PPC; echo '#endif') | \ (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_PPC >/dev/null then UNAME_PROCESSOR=powerpc fi elif test "$UNAME_PROCESSOR" = i386 ; then # uname -m returns i386 or x86_64 UNAME_PROCESSOR=$UNAME_MACHINE fi GUESS=$UNAME_PROCESSOR-apple-darwin$UNAME_RELEASE ;; *:procnto*:*:* | *:QNX:[0123456789]*:*) UNAME_PROCESSOR=`uname -p` if test "$UNAME_PROCESSOR" = x86; then UNAME_PROCESSOR=i386 UNAME_MACHINE=pc fi GUESS=$UNAME_PROCESSOR-$UNAME_MACHINE-nto-qnx$UNAME_RELEASE ;; *:QNX:*:4*) GUESS=i386-pc-qnx ;; NEO-*:NONSTOP_KERNEL:*:*) GUESS=neo-tandem-nsk$UNAME_RELEASE ;; NSE-*:NONSTOP_KERNEL:*:*) GUESS=nse-tandem-nsk$UNAME_RELEASE ;; NSR-*:NONSTOP_KERNEL:*:*) GUESS=nsr-tandem-nsk$UNAME_RELEASE ;; NSV-*:NONSTOP_KERNEL:*:*) GUESS=nsv-tandem-nsk$UNAME_RELEASE ;; NSX-*:NONSTOP_KERNEL:*:*) GUESS=nsx-tandem-nsk$UNAME_RELEASE ;; *:NonStop-UX:*:*) GUESS=mips-compaq-nonstopux ;; BS2000:POSIX*:*:*) GUESS=bs2000-siemens-sysv ;; DS/*:UNIX_System_V:*:*) GUESS=$UNAME_MACHINE-$UNAME_SYSTEM-$UNAME_RELEASE ;; *:Plan9:*:*) # "uname -m" is not consistent, so use $cputype instead. 386 # is converted to i386 for consistency with other x86 # operating systems. if test "${cputype-}" = 386; then UNAME_MACHINE=i386 elif test "x${cputype-}" != x; then UNAME_MACHINE=$cputype fi GUESS=$UNAME_MACHINE-unknown-plan9 ;; *:TOPS-10:*:*) GUESS=pdp10-unknown-tops10 ;; *:TENEX:*:*) GUESS=pdp10-unknown-tenex ;; KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) GUESS=pdp10-dec-tops20 ;; XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) GUESS=pdp10-xkl-tops20 ;; *:TOPS-20:*:*) GUESS=pdp10-unknown-tops20 ;; *:ITS:*:*) GUESS=pdp10-unknown-its ;; SEI:*:*:SEIUX) GUESS=mips-sei-seiux$UNAME_RELEASE ;; *:DragonFly:*:*) DRAGONFLY_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` GUESS=$UNAME_MACHINE-unknown-dragonfly$DRAGONFLY_REL ;; *:*VMS:*:*) UNAME_MACHINE=`(uname -p) 2>/dev/null` case $UNAME_MACHINE in A*) GUESS=alpha-dec-vms ;; I*) GUESS=ia64-dec-vms ;; V*) GUESS=vax-dec-vms ;; esac ;; *:XENIX:*:SysV) GUESS=i386-pc-xenix ;; i*86:skyos:*:*) SKYOS_REL=`echo "$UNAME_RELEASE" | sed -e 's/ .*$//'` GUESS=$UNAME_MACHINE-pc-skyos$SKYOS_REL ;; i*86:rdos:*:*) GUESS=$UNAME_MACHINE-pc-rdos ;; i*86:Fiwix:*:*) GUESS=$UNAME_MACHINE-pc-fiwix ;; *:AROS:*:*) GUESS=$UNAME_MACHINE-unknown-aros ;; x86_64:VMkernel:*:*) GUESS=$UNAME_MACHINE-unknown-esx ;; amd64:Isilon\ OneFS:*:*) GUESS=x86_64-unknown-onefs ;; *:Unleashed:*:*) GUESS=$UNAME_MACHINE-unknown-unleashed$UNAME_RELEASE ;; esac # Do we have a guess based on uname results? if test "x$GUESS" != x; then echo "$GUESS" exit fi # No uname command or uname output not recognized. set_cc_for_build cat > "$dummy.c" < #include #endif #if defined(ultrix) || defined(_ultrix) || defined(__ultrix) || defined(__ultrix__) #if defined (vax) || defined (__vax) || defined (__vax__) || defined(mips) || defined(__mips) || defined(__mips__) || defined(MIPS) || defined(__MIPS__) #include #if defined(_SIZE_T_) || defined(SIGLOST) #include #endif #endif #endif main () { #if defined (sony) #if defined (MIPSEB) /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, I don't know.... */ printf ("mips-sony-bsd\n"); exit (0); #else #include printf ("m68k-sony-newsos%s\n", #ifdef NEWSOS4 "4" #else "" #endif ); exit (0); #endif #endif #if defined (NeXT) #if !defined (__ARCHITECTURE__) #define __ARCHITECTURE__ "m68k" #endif int version; version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; if (version < 4) printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); else printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); exit (0); #endif #if defined (MULTIMAX) || defined (n16) #if defined (UMAXV) printf ("ns32k-encore-sysv\n"); exit (0); #else #if defined (CMU) printf ("ns32k-encore-mach\n"); exit (0); #else printf ("ns32k-encore-bsd\n"); exit (0); #endif #endif #endif #if defined (__386BSD__) printf ("i386-pc-bsd\n"); exit (0); #endif #if defined (sequent) #if defined (i386) printf ("i386-sequent-dynix\n"); exit (0); #endif #if defined (ns32000) printf ("ns32k-sequent-dynix\n"); exit (0); #endif #endif #if defined (_SEQUENT_) struct utsname un; uname(&un); if (strncmp(un.version, "V2", 2) == 0) { printf ("i386-sequent-ptx2\n"); exit (0); } if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ printf ("i386-sequent-ptx1\n"); exit (0); } printf ("i386-sequent-ptx\n"); exit (0); #endif #if defined (vax) #if !defined (ultrix) #include #if defined (BSD) #if BSD == 43 printf ("vax-dec-bsd4.3\n"); exit (0); #else #if BSD == 199006 printf ("vax-dec-bsd4.3reno\n"); exit (0); #else printf ("vax-dec-bsd\n"); exit (0); #endif #endif #else printf ("vax-dec-bsd\n"); exit (0); #endif #else #if defined(_SIZE_T_) || defined(SIGLOST) struct utsname un; uname (&un); printf ("vax-dec-ultrix%s\n", un.release); exit (0); #else printf ("vax-dec-ultrix\n"); exit (0); #endif #endif #endif #if defined(ultrix) || defined(_ultrix) || defined(__ultrix) || defined(__ultrix__) #if defined(mips) || defined(__mips) || defined(__mips__) || defined(MIPS) || defined(__MIPS__) #if defined(_SIZE_T_) || defined(SIGLOST) struct utsname *un; uname (&un); printf ("mips-dec-ultrix%s\n", un.release); exit (0); #else printf ("mips-dec-ultrix\n"); exit (0); #endif #endif #endif #if defined (alliant) && defined (i860) printf ("i860-alliant-bsd\n"); exit (0); #endif exit (1); } EOF $CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null && SYSTEM_NAME=`"$dummy"` && { echo "$SYSTEM_NAME"; exit; } # Apollos put the system type in the environment. test -d /usr/apollo && { echo "$ISP-apollo-$SYSTYPE"; exit; } echo "$0: unable to guess system type" >&2 case $UNAME_MACHINE:$UNAME_SYSTEM in mips:Linux | mips64:Linux) # If we got here on MIPS GNU/Linux, output extra information. cat >&2 <&2 <&2 </dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` /bin/uname -X = `(/bin/uname -X) 2>/dev/null` hostinfo = `(hostinfo) 2>/dev/null` /bin/universe = `(/bin/universe) 2>/dev/null` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` /bin/arch = `(/bin/arch) 2>/dev/null` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` UNAME_MACHINE = "$UNAME_MACHINE" UNAME_RELEASE = "$UNAME_RELEASE" UNAME_SYSTEM = "$UNAME_SYSTEM" UNAME_VERSION = "$UNAME_VERSION" EOF fi exit 1 # Local variables: # eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: ppp-2.5.0/config.sub0000755000175000017500000010512114247602205011223 00000000000000#!/usr/bin/sh # Configuration validation subroutine script. # Copyright 1992-2022 Free Software Foundation, Inc. # shellcheck disable=SC2006,SC2268 # see below for rationale timestamp='2022-01-03' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, see . # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that # program. This Exception is an additional permission under section 7 # of the GNU General Public License, version 3 ("GPLv3"). # Please send patches to . # # Configuration subroutine to validate and canonicalize a configuration type. # Supply the specified configuration type as an argument. # If it is invalid, we print an error message on stderr and exit with code 1. # Otherwise, we print the canonical config type on stdout and succeed. # You can get the latest version of this script from: # https://git.savannah.gnu.org/cgit/config.git/plain/config.sub # This file is supposed to be the same for all GNU packages # and recognize all the CPU types, system types and aliases # that are meaningful with *any* GNU software. # Each package is responsible for reporting which valid configurations # it does not support. The user should be able to distinguish # a failure to support a valid configuration from a meaningless # configuration. # The goal of this file is to map all the various variations of a given # machine specification into a single specification in the form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM # or in some cases, the newer four-part form: # CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM # It is wrong to echo any other type of specification. # The "shellcheck disable" line above the timestamp inhibits complaints # about features and limitations of the classic Bourne shell that were # superseded or lifted in POSIX. However, this script identifies a wide # variety of pre-POSIX systems that do not have POSIX shells at all, and # even some reasonably current systems (Solaris 10 as case-in-point) still # have a pre-POSIX /bin/sh. me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] CPU-MFR-OPSYS or ALIAS Canonicalize a configuration name. Options: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.sub ($timestamp) Copyright 1992-2022 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit ;; --version | -v ) echo "$version" ; exit ;; --help | --h* | -h ) echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" >&2 exit 1 ;; *local*) # First pass through any local machine types. echo "$1" exit ;; * ) break ;; esac done case $# in 0) echo "$me: missing argument$help" >&2 exit 1;; 1) ;; *) echo "$me: too many arguments$help" >&2 exit 1;; esac # Split fields of configuration type # shellcheck disable=SC2162 saved_IFS=$IFS IFS="-" read field1 field2 field3 field4 <&2 exit 1 ;; *-*-*-*) basic_machine=$field1-$field2 basic_os=$field3-$field4 ;; *-*-*) # Ambiguous whether COMPANY is present, or skipped and KERNEL-OS is two # parts maybe_os=$field2-$field3 case $maybe_os in nto-qnx* | linux-* | uclinux-uclibc* \ | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* \ | netbsd*-eabi* | kopensolaris*-gnu* | cloudabi*-eabi* \ | storm-chaos* | os2-emx* | rtmk-nova*) basic_machine=$field1 basic_os=$maybe_os ;; android-linux) basic_machine=$field1-unknown basic_os=linux-android ;; *) basic_machine=$field1-$field2 basic_os=$field3 ;; esac ;; *-*) # A lone config we happen to match not fitting any pattern case $field1-$field2 in decstation-3100) basic_machine=mips-dec basic_os= ;; *-*) # Second component is usually, but not always the OS case $field2 in # Prevent following clause from handling this valid os sun*os*) basic_machine=$field1 basic_os=$field2 ;; zephyr*) basic_machine=$field1-unknown basic_os=$field2 ;; # Manufacturers dec* | mips* | sequent* | encore* | pc533* | sgi* | sony* \ | att* | 7300* | 3300* | delta* | motorola* | sun[234]* \ | unicom* | ibm* | next | hp | isi* | apollo | altos* \ | convergent* | ncr* | news | 32* | 3600* | 3100* \ | hitachi* | c[123]* | convex* | sun | crds | omron* | dg \ | ultra | tti* | harris | dolphin | highlevel | gould \ | cbm | ns | masscomp | apple | axis | knuth | cray \ | microblaze* | sim | cisco \ | oki | wec | wrs | winbond) basic_machine=$field1-$field2 basic_os= ;; *) basic_machine=$field1 basic_os=$field2 ;; esac ;; esac ;; *) # Convert single-component short-hands not valid as part of # multi-component configurations. case $field1 in 386bsd) basic_machine=i386-pc basic_os=bsd ;; a29khif) basic_machine=a29k-amd basic_os=udi ;; adobe68k) basic_machine=m68010-adobe basic_os=scout ;; alliant) basic_machine=fx80-alliant basic_os= ;; altos | altos3068) basic_machine=m68k-altos basic_os= ;; am29k) basic_machine=a29k-none basic_os=bsd ;; amdahl) basic_machine=580-amdahl basic_os=sysv ;; amiga) basic_machine=m68k-unknown basic_os= ;; amigaos | amigados) basic_machine=m68k-unknown basic_os=amigaos ;; amigaunix | amix) basic_machine=m68k-unknown basic_os=sysv4 ;; apollo68) basic_machine=m68k-apollo basic_os=sysv ;; apollo68bsd) basic_machine=m68k-apollo basic_os=bsd ;; aros) basic_machine=i386-pc basic_os=aros ;; aux) basic_machine=m68k-apple basic_os=aux ;; balance) basic_machine=ns32k-sequent basic_os=dynix ;; blackfin) basic_machine=bfin-unknown basic_os=linux ;; cegcc) basic_machine=arm-unknown basic_os=cegcc ;; convex-c1) basic_machine=c1-convex basic_os=bsd ;; convex-c2) basic_machine=c2-convex basic_os=bsd ;; convex-c32) basic_machine=c32-convex basic_os=bsd ;; convex-c34) basic_machine=c34-convex basic_os=bsd ;; convex-c38) basic_machine=c38-convex basic_os=bsd ;; cray) basic_machine=j90-cray basic_os=unicos ;; crds | unos) basic_machine=m68k-crds basic_os= ;; da30) basic_machine=m68k-da30 basic_os= ;; decstation | pmax | pmin | dec3100 | decstatn) basic_machine=mips-dec basic_os= ;; delta88) basic_machine=m88k-motorola basic_os=sysv3 ;; dicos) basic_machine=i686-pc basic_os=dicos ;; djgpp) basic_machine=i586-pc basic_os=msdosdjgpp ;; ebmon29k) basic_machine=a29k-amd basic_os=ebmon ;; es1800 | OSE68k | ose68k | ose | OSE) basic_machine=m68k-ericsson basic_os=ose ;; gmicro) basic_machine=tron-gmicro basic_os=sysv ;; go32) basic_machine=i386-pc basic_os=go32 ;; h8300hms) basic_machine=h8300-hitachi basic_os=hms ;; h8300xray) basic_machine=h8300-hitachi basic_os=xray ;; h8500hms) basic_machine=h8500-hitachi basic_os=hms ;; harris) basic_machine=m88k-harris basic_os=sysv3 ;; hp300 | hp300hpux) basic_machine=m68k-hp basic_os=hpux ;; hp300bsd) basic_machine=m68k-hp basic_os=bsd ;; hppaosf) basic_machine=hppa1.1-hp basic_os=osf ;; hppro) basic_machine=hppa1.1-hp basic_os=proelf ;; i386mach) basic_machine=i386-mach basic_os=mach ;; isi68 | isi) basic_machine=m68k-isi basic_os=sysv ;; m68knommu) basic_machine=m68k-unknown basic_os=linux ;; magnum | m3230) basic_machine=mips-mips basic_os=sysv ;; merlin) basic_machine=ns32k-utek basic_os=sysv ;; mingw64) basic_machine=x86_64-pc basic_os=mingw64 ;; mingw32) basic_machine=i686-pc basic_os=mingw32 ;; mingw32ce) basic_machine=arm-unknown basic_os=mingw32ce ;; monitor) basic_machine=m68k-rom68k basic_os=coff ;; morphos) basic_machine=powerpc-unknown basic_os=morphos ;; moxiebox) basic_machine=moxie-unknown basic_os=moxiebox ;; msdos) basic_machine=i386-pc basic_os=msdos ;; msys) basic_machine=i686-pc basic_os=msys ;; mvs) basic_machine=i370-ibm basic_os=mvs ;; nacl) basic_machine=le32-unknown basic_os=nacl ;; ncr3000) basic_machine=i486-ncr basic_os=sysv4 ;; netbsd386) basic_machine=i386-pc basic_os=netbsd ;; netwinder) basic_machine=armv4l-rebel basic_os=linux ;; news | news700 | news800 | news900) basic_machine=m68k-sony basic_os=newsos ;; news1000) basic_machine=m68030-sony basic_os=newsos ;; necv70) basic_machine=v70-nec basic_os=sysv ;; nh3000) basic_machine=m68k-harris basic_os=cxux ;; nh[45]000) basic_machine=m88k-harris basic_os=cxux ;; nindy960) basic_machine=i960-intel basic_os=nindy ;; mon960) basic_machine=i960-intel basic_os=mon960 ;; nonstopux) basic_machine=mips-compaq basic_os=nonstopux ;; os400) basic_machine=powerpc-ibm basic_os=os400 ;; OSE68000 | ose68000) basic_machine=m68000-ericsson basic_os=ose ;; os68k) basic_machine=m68k-none basic_os=os68k ;; paragon) basic_machine=i860-intel basic_os=osf ;; parisc) basic_machine=hppa-unknown basic_os=linux ;; psp) basic_machine=mipsallegrexel-sony basic_os=psp ;; pw32) basic_machine=i586-unknown basic_os=pw32 ;; rdos | rdos64) basic_machine=x86_64-pc basic_os=rdos ;; rdos32) basic_machine=i386-pc basic_os=rdos ;; rom68k) basic_machine=m68k-rom68k basic_os=coff ;; sa29200) basic_machine=a29k-amd basic_os=udi ;; sei) basic_machine=mips-sei basic_os=seiux ;; sequent) basic_machine=i386-sequent basic_os= ;; sps7) basic_machine=m68k-bull basic_os=sysv2 ;; st2000) basic_machine=m68k-tandem basic_os= ;; stratus) basic_machine=i860-stratus basic_os=sysv4 ;; sun2) basic_machine=m68000-sun basic_os= ;; sun2os3) basic_machine=m68000-sun basic_os=sunos3 ;; sun2os4) basic_machine=m68000-sun basic_os=sunos4 ;; sun3) basic_machine=m68k-sun basic_os= ;; sun3os3) basic_machine=m68k-sun basic_os=sunos3 ;; sun3os4) basic_machine=m68k-sun basic_os=sunos4 ;; sun4) basic_machine=sparc-sun basic_os= ;; sun4os3) basic_machine=sparc-sun basic_os=sunos3 ;; sun4os4) basic_machine=sparc-sun basic_os=sunos4 ;; sun4sol2) basic_machine=sparc-sun basic_os=solaris2 ;; sun386 | sun386i | roadrunner) basic_machine=i386-sun basic_os= ;; sv1) basic_machine=sv1-cray basic_os=unicos ;; symmetry) basic_machine=i386-sequent basic_os=dynix ;; t3e) basic_machine=alphaev5-cray basic_os=unicos ;; t90) basic_machine=t90-cray basic_os=unicos ;; toad1) basic_machine=pdp10-xkl basic_os=tops20 ;; tpf) basic_machine=s390x-ibm basic_os=tpf ;; udi29k) basic_machine=a29k-amd basic_os=udi ;; ultra3) basic_machine=a29k-nyu basic_os=sym1 ;; v810 | necv810) basic_machine=v810-nec basic_os=none ;; vaxv) basic_machine=vax-dec basic_os=sysv ;; vms) basic_machine=vax-dec basic_os=vms ;; vsta) basic_machine=i386-pc basic_os=vsta ;; vxworks960) basic_machine=i960-wrs basic_os=vxworks ;; vxworks68) basic_machine=m68k-wrs basic_os=vxworks ;; vxworks29k) basic_machine=a29k-wrs basic_os=vxworks ;; xbox) basic_machine=i686-pc basic_os=mingw32 ;; ymp) basic_machine=ymp-cray basic_os=unicos ;; *) basic_machine=$1 basic_os= ;; esac ;; esac # Decode 1-component or ad-hoc basic machines case $basic_machine in # Here we handle the default manufacturer of certain CPU types. It is in # some cases the only manufacturer, in others, it is the most popular. w89k) cpu=hppa1.1 vendor=winbond ;; op50n) cpu=hppa1.1 vendor=oki ;; op60c) cpu=hppa1.1 vendor=oki ;; ibm*) cpu=i370 vendor=ibm ;; orion105) cpu=clipper vendor=highlevel ;; mac | mpw | mac-mpw) cpu=m68k vendor=apple ;; pmac | pmac-mpw) cpu=powerpc vendor=apple ;; # Recognize the various machine names and aliases which stand # for a CPU type and a company and sometimes even an OS. 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) cpu=m68000 vendor=att ;; 3b*) cpu=we32k vendor=att ;; bluegene*) cpu=powerpc vendor=ibm basic_os=cnk ;; decsystem10* | dec10*) cpu=pdp10 vendor=dec basic_os=tops10 ;; decsystem20* | dec20*) cpu=pdp10 vendor=dec basic_os=tops20 ;; delta | 3300 | motorola-3300 | motorola-delta \ | 3300-motorola | delta-motorola) cpu=m68k vendor=motorola ;; dpx2*) cpu=m68k vendor=bull basic_os=sysv3 ;; encore | umax | mmax) cpu=ns32k vendor=encore ;; elxsi) cpu=elxsi vendor=elxsi basic_os=${basic_os:-bsd} ;; fx2800) cpu=i860 vendor=alliant ;; genix) cpu=ns32k vendor=ns ;; h3050r* | hiux*) cpu=hppa1.1 vendor=hitachi basic_os=hiuxwe2 ;; hp3k9[0-9][0-9] | hp9[0-9][0-9]) cpu=hppa1.0 vendor=hp ;; hp9k2[0-9][0-9] | hp9k31[0-9]) cpu=m68000 vendor=hp ;; hp9k3[2-9][0-9]) cpu=m68k vendor=hp ;; hp9k6[0-9][0-9] | hp6[0-9][0-9]) cpu=hppa1.0 vendor=hp ;; hp9k7[0-79][0-9] | hp7[0-79][0-9]) cpu=hppa1.1 vendor=hp ;; hp9k78[0-9] | hp78[0-9]) # FIXME: really hppa2.0-hp cpu=hppa1.1 vendor=hp ;; hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) # FIXME: really hppa2.0-hp cpu=hppa1.1 vendor=hp ;; hp9k8[0-9][13679] | hp8[0-9][13679]) cpu=hppa1.1 vendor=hp ;; hp9k8[0-9][0-9] | hp8[0-9][0-9]) cpu=hppa1.0 vendor=hp ;; i*86v32) cpu=`echo "$1" | sed -e 's/86.*/86/'` vendor=pc basic_os=sysv32 ;; i*86v4*) cpu=`echo "$1" | sed -e 's/86.*/86/'` vendor=pc basic_os=sysv4 ;; i*86v) cpu=`echo "$1" | sed -e 's/86.*/86/'` vendor=pc basic_os=sysv ;; i*86sol2) cpu=`echo "$1" | sed -e 's/86.*/86/'` vendor=pc basic_os=solaris2 ;; j90 | j90-cray) cpu=j90 vendor=cray basic_os=${basic_os:-unicos} ;; iris | iris4d) cpu=mips vendor=sgi case $basic_os in irix*) ;; *) basic_os=irix4 ;; esac ;; miniframe) cpu=m68000 vendor=convergent ;; *mint | mint[0-9]* | *MiNT | *MiNT[0-9]*) cpu=m68k vendor=atari basic_os=mint ;; news-3600 | risc-news) cpu=mips vendor=sony basic_os=newsos ;; next | m*-next) cpu=m68k vendor=next case $basic_os in openstep*) ;; nextstep*) ;; ns2*) basic_os=nextstep2 ;; *) basic_os=nextstep3 ;; esac ;; np1) cpu=np1 vendor=gould ;; op50n-* | op60c-*) cpu=hppa1.1 vendor=oki basic_os=proelf ;; pa-hitachi) cpu=hppa1.1 vendor=hitachi basic_os=hiuxwe2 ;; pbd) cpu=sparc vendor=tti ;; pbb) cpu=m68k vendor=tti ;; pc532) cpu=ns32k vendor=pc532 ;; pn) cpu=pn vendor=gould ;; power) cpu=power vendor=ibm ;; ps2) cpu=i386 vendor=ibm ;; rm[46]00) cpu=mips vendor=siemens ;; rtpc | rtpc-*) cpu=romp vendor=ibm ;; sde) cpu=mipsisa32 vendor=sde basic_os=${basic_os:-elf} ;; simso-wrs) cpu=sparclite vendor=wrs basic_os=vxworks ;; tower | tower-32) cpu=m68k vendor=ncr ;; vpp*|vx|vx-*) cpu=f301 vendor=fujitsu ;; w65) cpu=w65 vendor=wdc ;; w89k-*) cpu=hppa1.1 vendor=winbond basic_os=proelf ;; none) cpu=none vendor=none ;; leon|leon[3-9]) cpu=sparc vendor=$basic_machine ;; leon-*|leon[3-9]-*) cpu=sparc vendor=`echo "$basic_machine" | sed 's/-.*//'` ;; *-*) # shellcheck disable=SC2162 saved_IFS=$IFS IFS="-" read cpu vendor <&2 exit 1 ;; esac ;; esac # Here we canonicalize certain aliases for manufacturers. case $vendor in digital*) vendor=dec ;; commodore*) vendor=cbm ;; *) ;; esac # Decode manufacturer-specific aliases for certain operating systems. if test x$basic_os != x then # First recognize some ad-hoc cases, or perhaps split kernel-os, or else just # set os. case $basic_os in gnu/linux*) kernel=linux os=`echo "$basic_os" | sed -e 's|gnu/linux|gnu|'` ;; os2-emx) kernel=os2 os=`echo "$basic_os" | sed -e 's|os2-emx|emx|'` ;; nto-qnx*) kernel=nto os=`echo "$basic_os" | sed -e 's|nto-qnx|qnx|'` ;; *-*) # shellcheck disable=SC2162 saved_IFS=$IFS IFS="-" read kernel os <&2 exit 1 ;; esac # As a final step for OS-related things, validate the OS-kernel combination # (given a valid OS), if there is a kernel. case $kernel-$os in linux-gnu* | linux-dietlibc* | linux-android* | linux-newlib* \ | linux-musl* | linux-relibc* | linux-uclibc* ) ;; uclinux-uclibc* ) ;; -dietlibc* | -newlib* | -musl* | -relibc* | -uclibc* ) # These are just libc implementations, not actual OSes, and thus # require a kernel. echo "Invalid configuration \`$1': libc \`$os' needs explicit kernel." 1>&2 exit 1 ;; kfreebsd*-gnu* | kopensolaris*-gnu*) ;; vxworks-simlinux | vxworks-simwindows | vxworks-spe) ;; nto-qnx*) ;; os2-emx) ;; *-eabi* | *-gnueabi*) ;; -*) # Blank kernel with real OS is always fine. ;; *-*) echo "Invalid configuration \`$1': Kernel \`$kernel' not known to work with OS \`$os'." 1>&2 exit 1 ;; esac # Here we handle the case where we know the os, and the CPU type, but not the # manufacturer. We pick the logical manufacturer. case $vendor in unknown) case $cpu-$os in *-riscix*) vendor=acorn ;; *-sunos*) vendor=sun ;; *-cnk* | *-aix*) vendor=ibm ;; *-beos*) vendor=be ;; *-hpux*) vendor=hp ;; *-mpeix*) vendor=hp ;; *-hiux*) vendor=hitachi ;; *-unos*) vendor=crds ;; *-dgux*) vendor=dg ;; *-luna*) vendor=omron ;; *-genix*) vendor=ns ;; *-clix*) vendor=intergraph ;; *-mvs* | *-opened*) vendor=ibm ;; *-os400*) vendor=ibm ;; s390-* | s390x-*) vendor=ibm ;; *-ptx*) vendor=sequent ;; *-tpf*) vendor=ibm ;; *-vxsim* | *-vxworks* | *-windiss*) vendor=wrs ;; *-aux*) vendor=apple ;; *-hms*) vendor=hitachi ;; *-mpw* | *-macos*) vendor=apple ;; *-*mint | *-mint[0-9]* | *-*MiNT | *-MiNT[0-9]*) vendor=atari ;; *-vos*) vendor=stratus ;; esac ;; esac echo "$cpu-$vendor-${kernel:+$kernel-}$os" exit # Local variables: # eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: ppp-2.5.0/depcomp0000755000175000017500000005602014072725711010624 00000000000000#! /bin/sh # depcomp - compile a program generating dependencies as side-effects scriptversion=2018-03-07.03; # UTC # Copyright (C) 1999-2021 Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program. If not, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Originally written by Alexandre Oliva . case $1 in '') echo "$0: No command. Try '$0 --help' for more information." 1>&2 exit 1; ;; -h | --h*) cat <<\EOF Usage: depcomp [--help] [--version] PROGRAM [ARGS] Run PROGRAMS ARGS to compile a file, generating dependencies as side-effects. Environment variables: depmode Dependency tracking mode. source Source file read by 'PROGRAMS ARGS'. object Object file output by 'PROGRAMS ARGS'. DEPDIR directory where to store dependencies. depfile Dependency file to output. tmpdepfile Temporary file to use when outputting dependencies. libtool Whether libtool is used (yes/no). Report bugs to . EOF exit $? ;; -v | --v*) echo "depcomp $scriptversion" exit $? ;; esac # Get the directory component of the given path, and save it in the # global variables '$dir'. Note that this directory component will # be either empty or ending with a '/' character. This is deliberate. set_dir_from () { case $1 in */*) dir=`echo "$1" | sed -e 's|/[^/]*$|/|'`;; *) dir=;; esac } # Get the suffix-stripped basename of the given path, and save it the # global variable '$base'. set_base_from () { base=`echo "$1" | sed -e 's|^.*/||' -e 's/\.[^.]*$//'` } # If no dependency file was actually created by the compiler invocation, # we still have to create a dummy depfile, to avoid errors with the # Makefile "include basename.Plo" scheme. make_dummy_depfile () { echo "#dummy" > "$depfile" } # Factor out some common post-processing of the generated depfile. # Requires the auxiliary global variable '$tmpdepfile' to be set. aix_post_process_depfile () { # If the compiler actually managed to produce a dependency file, # post-process it. if test -f "$tmpdepfile"; then # Each line is of the form 'foo.o: dependency.h'. # Do two passes, one to just change these to # $object: dependency.h # and one to simply output # dependency.h: # which is needed to avoid the deleted-header problem. { sed -e "s,^.*\.[$lower]*:,$object:," < "$tmpdepfile" sed -e "s,^.*\.[$lower]*:[$tab ]*,," -e 's,$,:,' < "$tmpdepfile" } > "$depfile" rm -f "$tmpdepfile" else make_dummy_depfile fi } # A tabulation character. tab=' ' # A newline character. nl=' ' # Character ranges might be problematic outside the C locale. # These definitions help. upper=ABCDEFGHIJKLMNOPQRSTUVWXYZ lower=abcdefghijklmnopqrstuvwxyz digits=0123456789 alpha=${upper}${lower} if test -z "$depmode" || test -z "$source" || test -z "$object"; then echo "depcomp: Variables source, object and depmode must be set" 1>&2 exit 1 fi # Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po. depfile=${depfile-`echo "$object" | sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`} tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} rm -f "$tmpdepfile" # Avoid interferences from the environment. gccflag= dashmflag= # Some modes work just like other modes, but use different flags. We # parameterize here, but still list the modes in the big case below, # to make depend.m4 easier to write. Note that we *cannot* use a case # here, because this file can only contain one case statement. if test "$depmode" = hp; then # HP compiler uses -M and no extra arg. gccflag=-M depmode=gcc fi if test "$depmode" = dashXmstdout; then # This is just like dashmstdout with a different argument. dashmflag=-xM depmode=dashmstdout fi cygpath_u="cygpath -u -f -" if test "$depmode" = msvcmsys; then # This is just like msvisualcpp but w/o cygpath translation. # Just convert the backslash-escaped backslashes to single forward # slashes to satisfy depend.m4 cygpath_u='sed s,\\\\,/,g' depmode=msvisualcpp fi if test "$depmode" = msvc7msys; then # This is just like msvc7 but w/o cygpath translation. # Just convert the backslash-escaped backslashes to single forward # slashes to satisfy depend.m4 cygpath_u='sed s,\\\\,/,g' depmode=msvc7 fi if test "$depmode" = xlc; then # IBM C/C++ Compilers xlc/xlC can output gcc-like dependency information. gccflag=-qmakedep=gcc,-MF depmode=gcc fi case "$depmode" in gcc3) ## gcc 3 implements dependency tracking that does exactly what ## we want. Yay! Note: for some reason libtool 1.4 doesn't like ## it if -MD -MP comes after the -MF stuff. Hmm. ## Unfortunately, FreeBSD c89 acceptance of flags depends upon ## the command line argument order; so add the flags where they ## appear in depend2.am. Note that the slowdown incurred here ## affects only configure: in makefiles, %FASTDEP% shortcuts this. for arg do case $arg in -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;; *) set fnord "$@" "$arg" ;; esac shift # fnord shift # $arg done "$@" stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi mv "$tmpdepfile" "$depfile" ;; gcc) ## Note that this doesn't just cater to obsosete pre-3.x GCC compilers. ## but also to in-use compilers like IMB xlc/xlC and the HP C compiler. ## (see the conditional assignment to $gccflag above). ## There are various ways to get dependency output from gcc. Here's ## why we pick this rather obscure method: ## - Don't want to use -MD because we'd like the dependencies to end ## up in a subdir. Having to rename by hand is ugly. ## (We might end up doing this anyway to support other compilers.) ## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like ## -MM, not -M (despite what the docs say). Also, it might not be ## supported by the other compilers which use the 'gcc' depmode. ## - Using -M directly means running the compiler twice (even worse ## than renaming). if test -z "$gccflag"; then gccflag=-MD, fi "$@" -Wp,"$gccflag$tmpdepfile" stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" echo "$object : \\" > "$depfile" # The second -e expression handles DOS-style file names with drive # letters. sed -e 's/^[^:]*: / /' \ -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" ## This next piece of magic avoids the "deleted header file" problem. ## The problem is that when a header file which appears in a .P file ## is deleted, the dependency causes make to die (because there is ## typically no way to rebuild the header). We avoid this by adding ## dummy dependencies for each header file. Too bad gcc doesn't do ## this for us directly. ## Some versions of gcc put a space before the ':'. On the theory ## that the space means something, we add a space to the output as ## well. hp depmode also adds that space, but also prefixes the VPATH ## to the object. Take care to not repeat it in the output. ## Some versions of the HPUX 10.20 sed can't process this invocation ## correctly. Breaking it into two sed invocations is a workaround. tr ' ' "$nl" < "$tmpdepfile" \ | sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -e '/:$/d' \ | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; hp) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; sgi) if test "$libtool" = yes; then "$@" "-Wp,-MDupdate,$tmpdepfile" else "$@" -MDupdate "$tmpdepfile" fi stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files echo "$object : \\" > "$depfile" # Clip off the initial element (the dependent). Don't try to be # clever and replace this with sed code, as IRIX sed won't handle # lines with more than a fixed number of characters (4096 in # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; # the IRIX cc adds comments like '#:fec' to the end of the # dependency line. tr ' ' "$nl" < "$tmpdepfile" \ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' \ | tr "$nl" ' ' >> "$depfile" echo >> "$depfile" # The second pass generates a dummy entry for each header file. tr ' ' "$nl" < "$tmpdepfile" \ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ >> "$depfile" else make_dummy_depfile fi rm -f "$tmpdepfile" ;; xlc) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; aix) # The C for AIX Compiler uses -M and outputs the dependencies # in a .u file. In older versions, this file always lives in the # current directory. Also, the AIX compiler puts '$object:' at the # start of each line; $object doesn't have directory information. # Version 6 uses the directory in both cases. set_dir_from "$object" set_base_from "$object" if test "$libtool" = yes; then tmpdepfile1=$dir$base.u tmpdepfile2=$base.u tmpdepfile3=$dir.libs/$base.u "$@" -Wc,-M else tmpdepfile1=$dir$base.u tmpdepfile2=$dir$base.u tmpdepfile3=$dir$base.u "$@" -M fi stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" exit $stat fi for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" do test -f "$tmpdepfile" && break done aix_post_process_depfile ;; tcc) # tcc (Tiny C Compiler) understand '-MD -MF file' since version 0.9.26 # FIXME: That version still under development at the moment of writing. # Make that this statement remains true also for stable, released # versions. # It will wrap lines (doesn't matter whether long or short) with a # trailing '\', as in: # # foo.o : \ # foo.c \ # foo.h \ # # It will put a trailing '\' even on the last line, and will use leading # spaces rather than leading tabs (at least since its commit 0394caf7 # "Emit spaces for -MD"). "$@" -MD -MF "$tmpdepfile" stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" # Each non-empty line is of the form 'foo.o : \' or ' dep.h \'. # We have to change lines of the first kind to '$object: \'. sed -e "s|.*:|$object :|" < "$tmpdepfile" > "$depfile" # And for each line of the second kind, we have to emit a 'dep.h:' # dummy dependency, to avoid the deleted-header problem. sed -n -e 's|^ *\(.*\) *\\$|\1:|p' < "$tmpdepfile" >> "$depfile" rm -f "$tmpdepfile" ;; ## The order of this option in the case statement is important, since the ## shell code in configure will try each of these formats in the order ## listed in this file. A plain '-MD' option would be understood by many ## compilers, so we must ensure this comes after the gcc and icc options. pgcc) # Portland's C compiler understands '-MD'. # Will always output deps to 'file.d' where file is the root name of the # source file under compilation, even if file resides in a subdirectory. # The object file name does not affect the name of the '.d' file. # pgcc 10.2 will output # foo.o: sub/foo.c sub/foo.h # and will wrap long lines using '\' : # foo.o: sub/foo.c ... \ # sub/foo.h ... \ # ... set_dir_from "$object" # Use the source, not the object, to determine the base name, since # that's sadly what pgcc will do too. set_base_from "$source" tmpdepfile=$base.d # For projects that build the same source file twice into different object # files, the pgcc approach of using the *source* file root name can cause # problems in parallel builds. Use a locking strategy to avoid stomping on # the same $tmpdepfile. lockdir=$base.d-lock trap " echo '$0: caught signal, cleaning up...' >&2 rmdir '$lockdir' exit 1 " 1 2 13 15 numtries=100 i=$numtries while test $i -gt 0; do # mkdir is a portable test-and-set. if mkdir "$lockdir" 2>/dev/null; then # This process acquired the lock. "$@" -MD stat=$? # Release the lock. rmdir "$lockdir" break else # If the lock is being held by a different process, wait # until the winning process is done or we timeout. while test -d "$lockdir" && test $i -gt 0; do sleep 1 i=`expr $i - 1` done fi i=`expr $i - 1` done trap - 1 2 13 15 if test $i -le 0; then echo "$0: failed to acquire lock after $numtries attempts" >&2 echo "$0: check lockdir '$lockdir'" >&2 exit 1 fi if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" # Each line is of the form `foo.o: dependent.h', # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'. # Do two passes, one to just change these to # `$object: dependent.h' and one to simply `dependent.h:'. sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile" # Some versions of the HPUX 10.20 sed can't process this invocation # correctly. Breaking it into two sed invocations is a workaround. sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" \ | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; hp2) # The "hp" stanza above does not work with aCC (C++) and HP's ia64 # compilers, which have integrated preprocessors. The correct option # to use with these is +Maked; it writes dependencies to a file named # 'foo.d', which lands next to the object file, wherever that # happens to be. # Much of this is similar to the tru64 case; see comments there. set_dir_from "$object" set_base_from "$object" if test "$libtool" = yes; then tmpdepfile1=$dir$base.d tmpdepfile2=$dir.libs/$base.d "$@" -Wc,+Maked else tmpdepfile1=$dir$base.d tmpdepfile2=$dir$base.d "$@" +Maked fi stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile1" "$tmpdepfile2" exit $stat fi for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" do test -f "$tmpdepfile" && break done if test -f "$tmpdepfile"; then sed -e "s,^.*\.[$lower]*:,$object:," "$tmpdepfile" > "$depfile" # Add 'dependent.h:' lines. sed -ne '2,${ s/^ *// s/ \\*$// s/$/:/ p }' "$tmpdepfile" >> "$depfile" else make_dummy_depfile fi rm -f "$tmpdepfile" "$tmpdepfile2" ;; tru64) # The Tru64 compiler uses -MD to generate dependencies as a side # effect. 'cc -MD -o foo.o ...' puts the dependencies into 'foo.o.d'. # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put # dependencies in 'foo.d' instead, so we check for that too. # Subdirectories are respected. set_dir_from "$object" set_base_from "$object" if test "$libtool" = yes; then # Libtool generates 2 separate objects for the 2 libraries. These # two compilations output dependencies in $dir.libs/$base.o.d and # in $dir$base.o.d. We have to check for both files, because # one of the two compilations can be disabled. We should prefer # $dir$base.o.d over $dir.libs/$base.o.d because the latter is # automatically cleaned when .libs/ is deleted, while ignoring # the former would cause a distcleancheck panic. tmpdepfile1=$dir$base.o.d # libtool 1.5 tmpdepfile2=$dir.libs/$base.o.d # Likewise. tmpdepfile3=$dir.libs/$base.d # Compaq CCC V6.2-504 "$@" -Wc,-MD else tmpdepfile1=$dir$base.d tmpdepfile2=$dir$base.d tmpdepfile3=$dir$base.d "$@" -MD fi stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" exit $stat fi for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" do test -f "$tmpdepfile" && break done # Same post-processing that is required for AIX mode. aix_post_process_depfile ;; msvc7) if test "$libtool" = yes; then showIncludes=-Wc,-showIncludes else showIncludes=-showIncludes fi "$@" $showIncludes > "$tmpdepfile" stat=$? grep -v '^Note: including file: ' "$tmpdepfile" if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" echo "$object : \\" > "$depfile" # The first sed program below extracts the file names and escapes # backslashes for cygpath. The second sed program outputs the file # name when reading, but also accumulates all include files in the # hold buffer in order to output them again at the end. This only # works with sed implementations that can handle large buffers. sed < "$tmpdepfile" -n ' /^Note: including file: *\(.*\)/ { s//\1/ s/\\/\\\\/g p }' | $cygpath_u | sort -u | sed -n ' s/ /\\ /g s/\(.*\)/'"$tab"'\1 \\/p s/.\(.*\) \\/\1:/ H $ { s/.*/'"$tab"'/ G p }' >> "$depfile" echo >> "$depfile" # make sure the fragment doesn't end with a backslash rm -f "$tmpdepfile" ;; msvc7msys) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; #nosideeffect) # This comment above is used by automake to tell side-effect # dependency tracking mechanisms from slower ones. dashmstdout) # Important note: in order to support this mode, a compiler *must* # always write the preprocessed file to stdout, regardless of -o. "$@" || exit $? # Remove the call to Libtool. if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi # Remove '-o $object'. IFS=" " for arg do case $arg in -o) shift ;; $object) shift ;; *) set fnord "$@" "$arg" shift # fnord shift # $arg ;; esac done test -z "$dashmflag" && dashmflag=-M # Require at least two characters before searching for ':' # in the target name. This is to cope with DOS-style filenames: # a dependency such as 'c:/foo/bar' could be seen as target 'c' otherwise. "$@" $dashmflag | sed "s|^[$tab ]*[^:$tab ][^:][^:]*:[$tab ]*|$object: |" > "$tmpdepfile" rm -f "$depfile" cat < "$tmpdepfile" > "$depfile" # Some versions of the HPUX 10.20 sed can't process this sed invocation # correctly. Breaking it into two sed invocations is a workaround. tr ' ' "$nl" < "$tmpdepfile" \ | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \ | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; dashXmstdout) # This case only exists to satisfy depend.m4. It is never actually # run, as this mode is specially recognized in the preamble. exit 1 ;; makedepend) "$@" || exit $? # Remove any Libtool call if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi # X makedepend shift cleared=no eat=no for arg do case $cleared in no) set ""; shift cleared=yes ;; esac if test $eat = yes; then eat=no continue fi case "$arg" in -D*|-I*) set fnord "$@" "$arg"; shift ;; # Strip any option that makedepend may not understand. Remove # the object too, otherwise makedepend will parse it as a source file. -arch) eat=yes ;; -*|$object) ;; *) set fnord "$@" "$arg"; shift ;; esac done obj_suffix=`echo "$object" | sed 's/^.*\././'` touch "$tmpdepfile" ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" rm -f "$depfile" # makedepend may prepend the VPATH from the source file name to the object. # No need to regex-escape $object, excess matching of '.' is harmless. sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile" # Some versions of the HPUX 10.20 sed can't process the last invocation # correctly. Breaking it into two sed invocations is a workaround. sed '1,2d' "$tmpdepfile" \ | tr ' ' "$nl" \ | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \ | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" "$tmpdepfile".bak ;; cpp) # Important note: in order to support this mode, a compiler *must* # always write the preprocessed file to stdout. "$@" || exit $? # Remove the call to Libtool. if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi # Remove '-o $object'. IFS=" " for arg do case $arg in -o) shift ;; $object) shift ;; *) set fnord "$@" "$arg" shift # fnord shift # $arg ;; esac done "$@" -E \ | sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ | sed '$ s: \\$::' > "$tmpdepfile" rm -f "$depfile" echo "$object : \\" > "$depfile" cat < "$tmpdepfile" >> "$depfile" sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; msvisualcpp) # Important note: in order to support this mode, a compiler *must* # always write the preprocessed file to stdout. "$@" || exit $? # Remove the call to Libtool. if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi IFS=" " for arg do case "$arg" in -o) shift ;; $object) shift ;; "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") set fnord "$@" shift shift ;; *) set fnord "$@" "$arg" shift shift ;; esac done "$@" -E 2>/dev/null | sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile" rm -f "$depfile" echo "$object : \\" > "$depfile" sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::'"$tab"'\1 \\:p' >> "$depfile" echo "$tab" >> "$depfile" sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile" rm -f "$tmpdepfile" ;; msvcmsys) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; none) exec "$@" ;; *) echo "Unknown depmode $depmode" 1>&2 exit 1 ;; esac exit 0 # Local Variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC0" # time-stamp-end: "; # UTC" # End: ppp-2.5.0/install-sh0000755000175000017500000003577613753651557011305 00000000000000#!/bin/sh # install - install a program, script, or datafile scriptversion=2020-11-14.01; # UTC # This originates from X11R5 (mit/util/scripts/install.sh), which was # later released in X11R6 (xc/config/util/install.sh) with the # following copyright and license. # # Copyright (C) 1994 X Consortium # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to # deal in the Software without restriction, including without limitation the # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or # sell copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN # AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- # TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # # Except as contained in this notice, the name of the X Consortium shall not # be used in advertising or otherwise to promote the sale, use or other deal- # ings in this Software without prior written authorization from the X Consor- # tium. # # # FSF changes to this file are in the public domain. # # Calling this script install-sh is preferred over install.sh, to prevent # 'make' implicit rules from creating a file called install from it # when there is no Makefile. # # This script is compatible with the BSD install script, but was written # from scratch. tab=' ' nl=' ' IFS=" $tab$nl" # Set DOITPROG to "echo" to test this script. doit=${DOITPROG-} doit_exec=${doit:-exec} # Put in absolute file names if you don't have them in your path; # or use environment vars. chgrpprog=${CHGRPPROG-chgrp} chmodprog=${CHMODPROG-chmod} chownprog=${CHOWNPROG-chown} cmpprog=${CMPPROG-cmp} cpprog=${CPPROG-cp} mkdirprog=${MKDIRPROG-mkdir} mvprog=${MVPROG-mv} rmprog=${RMPROG-rm} stripprog=${STRIPPROG-strip} posix_mkdir= # Desired mode of installed file. mode=0755 # Create dirs (including intermediate dirs) using mode 755. # This is like GNU 'install' as of coreutils 8.32 (2020). mkdir_umask=22 backupsuffix= chgrpcmd= chmodcmd=$chmodprog chowncmd= mvcmd=$mvprog rmcmd="$rmprog -f" stripcmd= src= dst= dir_arg= dst_arg= copy_on_change=false is_target_a_directory=possibly usage="\ Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE or: $0 [OPTION]... SRCFILES... DIRECTORY or: $0 [OPTION]... -t DIRECTORY SRCFILES... or: $0 [OPTION]... -d DIRECTORIES... In the 1st form, copy SRCFILE to DSTFILE. In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. In the 4th, create DIRECTORIES. Options: --help display this help and exit. --version display version info and exit. -c (ignored) -C install only if different (preserve data modification time) -d create directories instead of installing files. -g GROUP $chgrpprog installed files to GROUP. -m MODE $chmodprog installed files to MODE. -o USER $chownprog installed files to USER. -p pass -p to $cpprog. -s $stripprog installed files. -S SUFFIX attempt to back up existing files, with suffix SUFFIX. -t DIRECTORY install into DIRECTORY. -T report an error if DSTFILE is a directory. Environment variables override the default commands: CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG By default, rm is invoked with -f; when overridden with RMPROG, it's up to you to specify -f if you want it. If -S is not specified, no backups are attempted. Email bug reports to bug-automake@gnu.org. Automake home page: https://www.gnu.org/software/automake/ " while test $# -ne 0; do case $1 in -c) ;; -C) copy_on_change=true;; -d) dir_arg=true;; -g) chgrpcmd="$chgrpprog $2" shift;; --help) echo "$usage"; exit $?;; -m) mode=$2 case $mode in *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*) echo "$0: invalid mode: $mode" >&2 exit 1;; esac shift;; -o) chowncmd="$chownprog $2" shift;; -p) cpprog="$cpprog -p";; -s) stripcmd=$stripprog;; -S) backupsuffix="$2" shift;; -t) is_target_a_directory=always dst_arg=$2 # Protect names problematic for 'test' and other utilities. case $dst_arg in -* | [=\(\)!]) dst_arg=./$dst_arg;; esac shift;; -T) is_target_a_directory=never;; --version) echo "$0 $scriptversion"; exit $?;; --) shift break;; -*) echo "$0: invalid option: $1" >&2 exit 1;; *) break;; esac shift done # We allow the use of options -d and -T together, by making -d # take the precedence; this is for compatibility with GNU install. if test -n "$dir_arg"; then if test -n "$dst_arg"; then echo "$0: target directory not allowed when installing a directory." >&2 exit 1 fi fi if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then # When -d is used, all remaining arguments are directories to create. # When -t is used, the destination is already specified. # Otherwise, the last argument is the destination. Remove it from $@. for arg do if test -n "$dst_arg"; then # $@ is not empty: it contains at least $arg. set fnord "$@" "$dst_arg" shift # fnord fi shift # arg dst_arg=$arg # Protect names problematic for 'test' and other utilities. case $dst_arg in -* | [=\(\)!]) dst_arg=./$dst_arg;; esac done fi if test $# -eq 0; then if test -z "$dir_arg"; then echo "$0: no input file specified." >&2 exit 1 fi # It's OK to call 'install-sh -d' without argument. # This can happen when creating conditional directories. exit 0 fi if test -z "$dir_arg"; then if test $# -gt 1 || test "$is_target_a_directory" = always; then if test ! -d "$dst_arg"; then echo "$0: $dst_arg: Is not a directory." >&2 exit 1 fi fi fi if test -z "$dir_arg"; then do_exit='(exit $ret); exit $ret' trap "ret=129; $do_exit" 1 trap "ret=130; $do_exit" 2 trap "ret=141; $do_exit" 13 trap "ret=143; $do_exit" 15 # Set umask so as not to create temps with too-generous modes. # However, 'strip' requires both read and write access to temps. case $mode in # Optimize common cases. *644) cp_umask=133;; *755) cp_umask=22;; *[0-7]) if test -z "$stripcmd"; then u_plus_rw= else u_plus_rw='% 200' fi cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; *) if test -z "$stripcmd"; then u_plus_rw= else u_plus_rw=,u+rw fi cp_umask=$mode$u_plus_rw;; esac fi for src do # Protect names problematic for 'test' and other utilities. case $src in -* | [=\(\)!]) src=./$src;; esac if test -n "$dir_arg"; then dst=$src dstdir=$dst test -d "$dstdir" dstdir_status=$? # Don't chown directories that already exist. if test $dstdir_status = 0; then chowncmd="" fi else # Waiting for this to be detected by the "$cpprog $src $dsttmp" command # might cause directories to be created, which would be especially bad # if $src (and thus $dsttmp) contains '*'. if test ! -f "$src" && test ! -d "$src"; then echo "$0: $src does not exist." >&2 exit 1 fi if test -z "$dst_arg"; then echo "$0: no destination specified." >&2 exit 1 fi dst=$dst_arg # If destination is a directory, append the input filename. if test -d "$dst"; then if test "$is_target_a_directory" = never; then echo "$0: $dst_arg: Is a directory" >&2 exit 1 fi dstdir=$dst dstbase=`basename "$src"` case $dst in */) dst=$dst$dstbase;; *) dst=$dst/$dstbase;; esac dstdir_status=0 else dstdir=`dirname "$dst"` test -d "$dstdir" dstdir_status=$? fi fi case $dstdir in */) dstdirslash=$dstdir;; *) dstdirslash=$dstdir/;; esac obsolete_mkdir_used=false if test $dstdir_status != 0; then case $posix_mkdir in '') # With -d, create the new directory with the user-specified mode. # Otherwise, rely on $mkdir_umask. if test -n "$dir_arg"; then mkdir_mode=-m$mode else mkdir_mode= fi posix_mkdir=false # The $RANDOM variable is not portable (e.g., dash). Use it # here however when possible just to lower collision chance. tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ trap ' ret=$? rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null exit $ret ' 0 # Because "mkdir -p" follows existing symlinks and we likely work # directly in world-writeable /tmp, make sure that the '$tmpdir' # directory is successfully created first before we actually test # 'mkdir -p'. if (umask $mkdir_umask && $mkdirprog $mkdir_mode "$tmpdir" && exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1 then if test -z "$dir_arg" || { # Check for POSIX incompatibilities with -m. # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or # other-writable bit of parent directory when it shouldn't. # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. test_tmpdir="$tmpdir/a" ls_ld_tmpdir=`ls -ld "$test_tmpdir"` case $ls_ld_tmpdir in d????-?r-*) different_mode=700;; d????-?--*) different_mode=755;; *) false;; esac && $mkdirprog -m$different_mode -p -- "$test_tmpdir" && { ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"` test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" } } then posix_mkdir=: fi rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" else # Remove any dirs left behind by ancient mkdir implementations. rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null fi trap '' 0;; esac if $posix_mkdir && ( umask $mkdir_umask && $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" ) then : else # mkdir does not conform to POSIX, # or it failed possibly due to a race condition. Create the # directory the slow way, step by step, checking for races as we go. case $dstdir in /*) prefix='/';; [-=\(\)!]*) prefix='./';; *) prefix='';; esac oIFS=$IFS IFS=/ set -f set fnord $dstdir shift set +f IFS=$oIFS prefixes= for d do test X"$d" = X && continue prefix=$prefix$d if test -d "$prefix"; then prefixes= else if $posix_mkdir; then (umask $mkdir_umask && $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break # Don't fail if two instances are running concurrently. test -d "$prefix" || exit 1 else case $prefix in *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; *) qprefix=$prefix;; esac prefixes="$prefixes '$qprefix'" fi fi prefix=$prefix/ done if test -n "$prefixes"; then # Don't fail if two instances are running concurrently. (umask $mkdir_umask && eval "\$doit_exec \$mkdirprog $prefixes") || test -d "$dstdir" || exit 1 obsolete_mkdir_used=true fi fi fi if test -n "$dir_arg"; then { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 else # Make a couple of temp file names in the proper directory. dsttmp=${dstdirslash}_inst.$$_ rmtmp=${dstdirslash}_rm.$$_ # Trap to clean up those temp files at exit. trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 # Copy the file name to the temp name. (umask $cp_umask && { test -z "$stripcmd" || { # Create $dsttmp read-write so that cp doesn't create it read-only, # which would cause strip to fail. if test -z "$doit"; then : >"$dsttmp" # No need to fork-exec 'touch'. else $doit touch "$dsttmp" fi } } && $doit_exec $cpprog "$src" "$dsttmp") && # and set any options; do chmod last to preserve setuid bits. # # If any of these fail, we abort the whole thing. If we want to # ignore errors from any of these, just make sure not to ignore # errors from the above "$doit $cpprog $src $dsttmp" command. # { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && # If -C, don't bother to copy if it wouldn't change the file. if $copy_on_change && old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && set -f && set X $old && old=:$2:$4:$5:$6 && set X $new && new=:$2:$4:$5:$6 && set +f && test "$old" = "$new" && $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 then rm -f "$dsttmp" else # If $backupsuffix is set, and the file being installed # already exists, attempt a backup. Don't worry if it fails, # e.g., if mv doesn't support -f. if test -n "$backupsuffix" && test -f "$dst"; then $doit $mvcmd -f "$dst" "$dst$backupsuffix" 2>/dev/null fi # Rename the file to the real destination. $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || # The rename failed, perhaps because mv can't rename something else # to itself, or perhaps because mv is so ancient that it does not # support -f. { # Now remove or move aside any old file at destination location. # We try this two ways since rm can't unlink itself on some # systems and the destination file might be busy for other # reasons. In this case, the final cleanup might fail but the new # file should still install successfully. { test ! -f "$dst" || $doit $rmcmd "$dst" 2>/dev/null || { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && { $doit $rmcmd "$rmtmp" 2>/dev/null; :; } } || { echo "$0: cannot unlink or rename $dst" >&2 (exit 1); exit 1 } } && # Now rename the file to the real destination. $doit $mvcmd "$dsttmp" "$dst" } fi || exit 1 trap '' 0 fi done # Local variables: # eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC0" # time-stamp-end: "; # UTC" # End: ppp-2.5.0/ltmain.sh0000644000175000017500000121201014246131576011064 00000000000000#! /usr/bin/env sh ## DO NOT EDIT - This file generated from ./build-aux/ltmain.in ## by inline-source v2019-02-19.15 # libtool (GNU libtool) 2.4.7 # Provide generalized library-building support services. # Written by Gordon Matzigkeit , 1996 # Copyright (C) 1996-2019, 2021-2022 Free Software Foundation, Inc. # This is free software; see the source for copying conditions. There is NO # warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # GNU Libtool is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # As a special exception to the GNU General Public License, # if you distribute this file as part of a program or library that # is built using GNU Libtool, you may include this file under the # same distribution terms that you use for the rest of that program. # # GNU Libtool is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . PROGRAM=libtool PACKAGE=libtool VERSION=2.4.7 package_revision=2.4.7 ## ------ ## ## Usage. ## ## ------ ## # Run './libtool --help' for help with using this script from the # command line. ## ------------------------------- ## ## User overridable command paths. ## ## ------------------------------- ## # After configure completes, it has a better idea of some of the # shell tools we need than the defaults used by the functions shared # with bootstrap, so set those here where they can still be over- # ridden by the user, but otherwise take precedence. : ${AUTOCONF="autoconf"} : ${AUTOMAKE="automake"} ## -------------------------- ## ## Source external libraries. ## ## -------------------------- ## # Much of our low-level functionality needs to be sourced from external # libraries, which are installed to $pkgauxdir. # Set a version string for this script. scriptversion=2019-02-19.15; # UTC # General shell script boiler plate, and helper functions. # Written by Gary V. Vaughan, 2004 # This is free software. There is NO warranty; not even for # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # # Copyright (C) 2004-2019, 2021 Bootstrap Authors # # This file is dual licensed under the terms of the MIT license # , and GPL version 2 or later # . You must apply one of # these licenses when using or redistributing this software or any of # the files within it. See the URLs above, or the file `LICENSE` # included in the Bootstrap distribution for the full license texts. # Please report bugs or propose patches to: # ## ------ ## ## Usage. ## ## ------ ## # Evaluate this file near the top of your script to gain access to # the functions and variables defined here: # # . `echo "$0" | ${SED-sed} 's|[^/]*$||'`/build-aux/funclib.sh # # If you need to override any of the default environment variable # settings, do that before evaluating this file. ## -------------------- ## ## Shell normalisation. ## ## -------------------- ## # Some shells need a little help to be as Bourne compatible as possible. # Before doing anything else, make sure all that help has been provided! DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in *posix*) set -o posix ;; esac fi # NLS nuisances: We save the old values in case they are required later. _G_user_locale= _G_safe_locale= for _G_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES do eval "if test set = \"\${$_G_var+set}\"; then save_$_G_var=\$$_G_var $_G_var=C export $_G_var _G_user_locale=\"$_G_var=\\\$save_\$_G_var; \$_G_user_locale\" _G_safe_locale=\"$_G_var=C; \$_G_safe_locale\" fi" done # These NLS vars are set unconditionally (bootstrap issue #24). Unset those # in case the environment reset is needed later and the $save_* variant is not # defined (see the code above). LC_ALL=C LANGUAGE=C export LANGUAGE LC_ALL # Make sure IFS has a sensible default sp=' ' nl=' ' IFS="$sp $nl" # There are apparently some retarded systems that use ';' as a PATH separator! if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # func_unset VAR # -------------- # Portably unset VAR. # In some shells, an 'unset VAR' statement leaves a non-zero return # status if VAR is already unset, which might be problematic if the # statement is used at the end of a function (thus poisoning its return # value) or when 'set -e' is active (causing even a spurious abort of # the script in this case). func_unset () { { eval $1=; (eval unset $1) >/dev/null 2>&1 && eval unset $1 || : ; } } # Make sure CDPATH doesn't cause `cd` commands to output the target dir. func_unset CDPATH # Make sure ${,E,F}GREP behave sanely. func_unset GREP_OPTIONS ## ------------------------- ## ## Locate command utilities. ## ## ------------------------- ## # func_executable_p FILE # ---------------------- # Check that FILE is an executable regular file. func_executable_p () { test -f "$1" && test -x "$1" } # func_path_progs PROGS_LIST CHECK_FUNC [PATH] # -------------------------------------------- # Search for either a program that responds to --version with output # containing "GNU", or else returned by CHECK_FUNC otherwise, by # trying all the directories in PATH with each of the elements of # PROGS_LIST. # # CHECK_FUNC should accept the path to a candidate program, and # set $func_check_prog_result if it truncates its output less than # $_G_path_prog_max characters. func_path_progs () { _G_progs_list=$1 _G_check_func=$2 _G_PATH=${3-"$PATH"} _G_path_prog_max=0 _G_path_prog_found=false _G_save_IFS=$IFS; IFS=${PATH_SEPARATOR-:} for _G_dir in $_G_PATH; do IFS=$_G_save_IFS test -z "$_G_dir" && _G_dir=. for _G_prog_name in $_G_progs_list; do for _exeext in '' .EXE; do _G_path_prog=$_G_dir/$_G_prog_name$_exeext func_executable_p "$_G_path_prog" || continue case `"$_G_path_prog" --version 2>&1` in *GNU*) func_path_progs_result=$_G_path_prog _G_path_prog_found=: ;; *) $_G_check_func $_G_path_prog func_path_progs_result=$func_check_prog_result ;; esac $_G_path_prog_found && break 3 done done done IFS=$_G_save_IFS test -z "$func_path_progs_result" && { echo "no acceptable sed could be found in \$PATH" >&2 exit 1 } } # We want to be able to use the functions in this file before configure # has figured out where the best binaries are kept, which means we have # to search for them ourselves - except when the results are already set # where we skip the searches. # Unless the user overrides by setting SED, search the path for either GNU # sed, or the sed that truncates its output the least. test -z "$SED" && { _G_sed_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ for _G_i in 1 2 3 4 5 6 7; do _G_sed_script=$_G_sed_script$nl$_G_sed_script done echo "$_G_sed_script" 2>/dev/null | sed 99q >conftest.sed _G_sed_script= func_check_prog_sed () { _G_path_prog=$1 _G_count=0 printf 0123456789 >conftest.in while : do cat conftest.in conftest.in >conftest.tmp mv conftest.tmp conftest.in cp conftest.in conftest.nl echo '' >> conftest.nl "$_G_path_prog" -f conftest.sed conftest.out 2>/dev/null || break diff conftest.out conftest.nl >/dev/null 2>&1 || break _G_count=`expr $_G_count + 1` if test "$_G_count" -gt "$_G_path_prog_max"; then # Best one so far, save it but keep looking for a better one func_check_prog_result=$_G_path_prog _G_path_prog_max=$_G_count fi # 10*(2^10) chars as input seems more than enough test 10 -lt "$_G_count" && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out } func_path_progs "sed gsed" func_check_prog_sed "$PATH:/usr/xpg4/bin" rm -f conftest.sed SED=$func_path_progs_result } # Unless the user overrides by setting GREP, search the path for either GNU # grep, or the grep that truncates its output the least. test -z "$GREP" && { func_check_prog_grep () { _G_path_prog=$1 _G_count=0 _G_path_prog_max=0 printf 0123456789 >conftest.in while : do cat conftest.in conftest.in >conftest.tmp mv conftest.tmp conftest.in cp conftest.in conftest.nl echo 'GREP' >> conftest.nl "$_G_path_prog" -e 'GREP$' -e '-(cannot match)-' conftest.out 2>/dev/null || break diff conftest.out conftest.nl >/dev/null 2>&1 || break _G_count=`expr $_G_count + 1` if test "$_G_count" -gt "$_G_path_prog_max"; then # Best one so far, save it but keep looking for a better one func_check_prog_result=$_G_path_prog _G_path_prog_max=$_G_count fi # 10*(2^10) chars as input seems more than enough test 10 -lt "$_G_count" && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out } func_path_progs "grep ggrep" func_check_prog_grep "$PATH:/usr/xpg4/bin" GREP=$func_path_progs_result } ## ------------------------------- ## ## User overridable command paths. ## ## ------------------------------- ## # All uppercase variable names are used for environment variables. These # variables can be overridden by the user before calling a script that # uses them if a suitable command of that name is not already available # in the command search PATH. : ${CP="cp -f"} : ${ECHO="printf %s\n"} : ${EGREP="$GREP -E"} : ${FGREP="$GREP -F"} : ${LN_S="ln -s"} : ${MAKE="make"} : ${MKDIR="mkdir"} : ${MV="mv -f"} : ${RM="rm -f"} : ${SHELL="${CONFIG_SHELL-/bin/sh}"} ## -------------------- ## ## Useful sed snippets. ## ## -------------------- ## sed_dirname='s|/[^/]*$||' sed_basename='s|^.*/||' # Sed substitution that helps us do robust quoting. It backslashifies # metacharacters that are still active within double-quoted strings. sed_quote_subst='s|\([`"$\\]\)|\\\1|g' # Same as above, but do not quote variable references. sed_double_quote_subst='s/\(["`\\]\)/\\\1/g' # Sed substitution that turns a string into a regex matching for the # string literally. sed_make_literal_regex='s|[].[^$\\*\/]|\\&|g' # Sed substitution that converts a w32 file name or path # that contains forward slashes, into one that contains # (escaped) backslashes. A very naive implementation. sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g' # Re-'\' parameter expansions in output of sed_double_quote_subst that # were '\'-ed in input to the same. If an odd number of '\' preceded a # '$' in input to sed_double_quote_subst, that '$' was protected from # expansion. Since each input '\' is now two '\'s, look for any number # of runs of four '\'s followed by two '\'s and then a '$'. '\' that '$'. _G_bs='\\' _G_bs2='\\\\' _G_bs4='\\\\\\\\' _G_dollar='\$' sed_double_backslash="\ s/$_G_bs4/&\\ /g s/^$_G_bs2$_G_dollar/$_G_bs&/ s/\\([^$_G_bs]\\)$_G_bs2$_G_dollar/\\1$_G_bs2$_G_bs$_G_dollar/g s/\n//g" # require_check_ifs_backslash # --------------------------- # Check if we can use backslash as IFS='\' separator, and set # $check_ifs_backshlash_broken to ':' or 'false'. require_check_ifs_backslash=func_require_check_ifs_backslash func_require_check_ifs_backslash () { _G_save_IFS=$IFS IFS='\' _G_check_ifs_backshlash='a\\b' for _G_i in $_G_check_ifs_backshlash do case $_G_i in a) check_ifs_backshlash_broken=false ;; '') break ;; *) check_ifs_backshlash_broken=: break ;; esac done IFS=$_G_save_IFS require_check_ifs_backslash=: } ## ----------------- ## ## Global variables. ## ## ----------------- ## # Except for the global variables explicitly listed below, the following # functions in the '^func_' namespace, and the '^require_' namespace # variables initialised in the 'Resource management' section, sourcing # this file will not pollute your global namespace with anything # else. There's no portable way to scope variables in Bourne shell # though, so actually running these functions will sometimes place # results into a variable named after the function, and often use # temporary variables in the '^_G_' namespace. If you are careful to # avoid using those namespaces casually in your sourcing script, things # should continue to work as you expect. And, of course, you can freely # overwrite any of the functions or variables defined here before # calling anything to customize them. EXIT_SUCCESS=0 EXIT_FAILURE=1 EXIT_MISMATCH=63 # $? = 63 is used to indicate version mismatch to missing. EXIT_SKIP=77 # $? = 77 is used to indicate a skipped test to automake. # Allow overriding, eg assuming that you follow the convention of # putting '$debug_cmd' at the start of all your functions, you can get # bash to show function call trace with: # # debug_cmd='eval echo "${FUNCNAME[0]} $*" >&2' bash your-script-name debug_cmd=${debug_cmd-":"} exit_cmd=: # By convention, finish your script with: # # exit $exit_status # # so that you can set exit_status to non-zero if you want to indicate # something went wrong during execution without actually bailing out at # the point of failure. exit_status=$EXIT_SUCCESS # Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh # is ksh but when the shell is invoked as "sh" and the current value of # the _XPG environment variable is not equal to 1 (one), the special # positional parameter $0, within a function call, is the name of the # function. progpath=$0 # The name of this program. progname=`$ECHO "$progpath" |$SED "$sed_basename"` # Make sure we have an absolute progpath for reexecution: case $progpath in [\\/]*|[A-Za-z]:\\*) ;; *[\\/]*) progdir=`$ECHO "$progpath" |$SED "$sed_dirname"` progdir=`cd "$progdir" && pwd` progpath=$progdir/$progname ;; *) _G_IFS=$IFS IFS=${PATH_SEPARATOR-:} for progdir in $PATH; do IFS=$_G_IFS test -x "$progdir/$progname" && break done IFS=$_G_IFS test -n "$progdir" || progdir=`pwd` progpath=$progdir/$progname ;; esac ## ----------------- ## ## Standard options. ## ## ----------------- ## # The following options affect the operation of the functions defined # below, and should be set appropriately depending on run-time para- # meters passed on the command line. opt_dry_run=false opt_quiet=false opt_verbose=false # Categories 'all' and 'none' are always available. Append any others # you will pass as the first argument to func_warning from your own # code. warning_categories= # By default, display warnings according to 'opt_warning_types'. Set # 'warning_func' to ':' to elide all warnings, or func_fatal_error to # treat the next displayed warning as a fatal error. warning_func=func_warn_and_continue # Set to 'all' to display all warnings, 'none' to suppress all # warnings, or a space delimited list of some subset of # 'warning_categories' to display only the listed warnings. opt_warning_types=all ## -------------------- ## ## Resource management. ## ## -------------------- ## # This section contains definitions for functions that each ensure a # particular resource (a file, or a non-empty configuration variable for # example) is available, and if appropriate to extract default values # from pertinent package files. Call them using their associated # 'require_*' variable to ensure that they are executed, at most, once. # # It's entirely deliberate that calling these functions can set # variables that don't obey the namespace limitations obeyed by the rest # of this file, in order that that they be as useful as possible to # callers. # require_term_colors # ------------------- # Allow display of bold text on terminals that support it. require_term_colors=func_require_term_colors func_require_term_colors () { $debug_cmd test -t 1 && { # COLORTERM and USE_ANSI_COLORS environment variables take # precedence, because most terminfo databases neglect to describe # whether color sequences are supported. test -n "${COLORTERM+set}" && : ${USE_ANSI_COLORS="1"} if test 1 = "$USE_ANSI_COLORS"; then # Standard ANSI escape sequences tc_reset='' tc_bold=''; tc_standout='' tc_red=''; tc_green='' tc_blue=''; tc_cyan='' else # Otherwise trust the terminfo database after all. test -n "`tput sgr0 2>/dev/null`" && { tc_reset=`tput sgr0` test -n "`tput bold 2>/dev/null`" && tc_bold=`tput bold` tc_standout=$tc_bold test -n "`tput smso 2>/dev/null`" && tc_standout=`tput smso` test -n "`tput setaf 1 2>/dev/null`" && tc_red=`tput setaf 1` test -n "`tput setaf 2 2>/dev/null`" && tc_green=`tput setaf 2` test -n "`tput setaf 4 2>/dev/null`" && tc_blue=`tput setaf 4` test -n "`tput setaf 5 2>/dev/null`" && tc_cyan=`tput setaf 5` } fi } require_term_colors=: } ## ----------------- ## ## Function library. ## ## ----------------- ## # This section contains a variety of useful functions to call in your # scripts. Take note of the portable wrappers for features provided by # some modern shells, which will fall back to slower equivalents on # less featureful shells. # func_append VAR VALUE # --------------------- # Append VALUE onto the existing contents of VAR. # We should try to minimise forks, especially on Windows where they are # unreasonably slow, so skip the feature probes when bash or zsh are # being used: if test set = "${BASH_VERSION+set}${ZSH_VERSION+set}"; then : ${_G_HAVE_ARITH_OP="yes"} : ${_G_HAVE_XSI_OPS="yes"} # The += operator was introduced in bash 3.1 case $BASH_VERSION in [12].* | 3.0 | 3.0*) ;; *) : ${_G_HAVE_PLUSEQ_OP="yes"} ;; esac fi # _G_HAVE_PLUSEQ_OP # Can be empty, in which case the shell is probed, "yes" if += is # useable or anything else if it does not work. test -z "$_G_HAVE_PLUSEQ_OP" \ && (eval 'x=a; x+=" b"; test "a b" = "$x"') 2>/dev/null \ && _G_HAVE_PLUSEQ_OP=yes if test yes = "$_G_HAVE_PLUSEQ_OP" then # This is an XSI compatible shell, allowing a faster implementation... eval 'func_append () { $debug_cmd eval "$1+=\$2" }' else # ...otherwise fall back to using expr, which is often a shell builtin. func_append () { $debug_cmd eval "$1=\$$1\$2" } fi # func_append_quoted VAR VALUE # ---------------------------- # Quote VALUE and append to the end of shell variable VAR, separated # by a space. if test yes = "$_G_HAVE_PLUSEQ_OP"; then eval 'func_append_quoted () { $debug_cmd func_quote_arg pretty "$2" eval "$1+=\\ \$func_quote_arg_result" }' else func_append_quoted () { $debug_cmd func_quote_arg pretty "$2" eval "$1=\$$1\\ \$func_quote_arg_result" } fi # func_append_uniq VAR VALUE # -------------------------- # Append unique VALUE onto the existing contents of VAR, assuming # entries are delimited by the first character of VALUE. For example: # # func_append_uniq options " --another-option option-argument" # # will only append to $options if " --another-option option-argument " # is not already present somewhere in $options already (note spaces at # each end implied by leading space in second argument). func_append_uniq () { $debug_cmd eval _G_current_value='`$ECHO $'$1'`' _G_delim=`expr "$2" : '\(.\)'` case $_G_delim$_G_current_value$_G_delim in *"$2$_G_delim"*) ;; *) func_append "$@" ;; esac } # func_arith TERM... # ------------------ # Set func_arith_result to the result of evaluating TERMs. test -z "$_G_HAVE_ARITH_OP" \ && (eval 'test 2 = $(( 1 + 1 ))') 2>/dev/null \ && _G_HAVE_ARITH_OP=yes if test yes = "$_G_HAVE_ARITH_OP"; then eval 'func_arith () { $debug_cmd func_arith_result=$(( $* )) }' else func_arith () { $debug_cmd func_arith_result=`expr "$@"` } fi # func_basename FILE # ------------------ # Set func_basename_result to FILE with everything up to and including # the last / stripped. if test yes = "$_G_HAVE_XSI_OPS"; then # If this shell supports suffix pattern removal, then use it to avoid # forking. Hide the definitions single quotes in case the shell chokes # on unsupported syntax... _b='func_basename_result=${1##*/}' _d='case $1 in */*) func_dirname_result=${1%/*}$2 ;; * ) func_dirname_result=$3 ;; esac' else # ...otherwise fall back to using sed. _b='func_basename_result=`$ECHO "$1" |$SED "$sed_basename"`' _d='func_dirname_result=`$ECHO "$1" |$SED "$sed_dirname"` if test "X$func_dirname_result" = "X$1"; then func_dirname_result=$3 else func_append func_dirname_result "$2" fi' fi eval 'func_basename () { $debug_cmd '"$_b"' }' # func_dirname FILE APPEND NONDIR_REPLACEMENT # ------------------------------------------- # Compute the dirname of FILE. If nonempty, add APPEND to the result, # otherwise set result to NONDIR_REPLACEMENT. eval 'func_dirname () { $debug_cmd '"$_d"' }' # func_dirname_and_basename FILE APPEND NONDIR_REPLACEMENT # -------------------------------------------------------- # Perform func_basename and func_dirname in a single function # call: # dirname: Compute the dirname of FILE. If nonempty, # add APPEND to the result, otherwise set result # to NONDIR_REPLACEMENT. # value returned in "$func_dirname_result" # basename: Compute filename of FILE. # value retuned in "$func_basename_result" # For efficiency, we do not delegate to the functions above but instead # duplicate the functionality here. eval 'func_dirname_and_basename () { $debug_cmd '"$_b"' '"$_d"' }' # func_echo ARG... # ---------------- # Echo program name prefixed message. func_echo () { $debug_cmd _G_message=$* func_echo_IFS=$IFS IFS=$nl for _G_line in $_G_message; do IFS=$func_echo_IFS $ECHO "$progname: $_G_line" done IFS=$func_echo_IFS } # func_echo_all ARG... # -------------------- # Invoke $ECHO with all args, space-separated. func_echo_all () { $ECHO "$*" } # func_echo_infix_1 INFIX ARG... # ------------------------------ # Echo program name, followed by INFIX on the first line, with any # additional lines not showing INFIX. func_echo_infix_1 () { $debug_cmd $require_term_colors _G_infix=$1; shift _G_indent=$_G_infix _G_prefix="$progname: $_G_infix: " _G_message=$* # Strip color escape sequences before counting printable length for _G_tc in "$tc_reset" "$tc_bold" "$tc_standout" "$tc_red" "$tc_green" "$tc_blue" "$tc_cyan" do test -n "$_G_tc" && { _G_esc_tc=`$ECHO "$_G_tc" | $SED "$sed_make_literal_regex"` _G_indent=`$ECHO "$_G_indent" | $SED "s|$_G_esc_tc||g"` } done _G_indent="$progname: "`echo "$_G_indent" | $SED 's|.| |g'`" " ## exclude from sc_prohibit_nested_quotes func_echo_infix_1_IFS=$IFS IFS=$nl for _G_line in $_G_message; do IFS=$func_echo_infix_1_IFS $ECHO "$_G_prefix$tc_bold$_G_line$tc_reset" >&2 _G_prefix=$_G_indent done IFS=$func_echo_infix_1_IFS } # func_error ARG... # ----------------- # Echo program name prefixed message to standard error. func_error () { $debug_cmd $require_term_colors func_echo_infix_1 " $tc_standout${tc_red}error$tc_reset" "$*" >&2 } # func_fatal_error ARG... # ----------------------- # Echo program name prefixed message to standard error, and exit. func_fatal_error () { $debug_cmd func_error "$*" exit $EXIT_FAILURE } # func_grep EXPRESSION FILENAME # ----------------------------- # Check whether EXPRESSION matches any line of FILENAME, without output. func_grep () { $debug_cmd $GREP "$1" "$2" >/dev/null 2>&1 } # func_len STRING # --------------- # Set func_len_result to the length of STRING. STRING may not # start with a hyphen. test -z "$_G_HAVE_XSI_OPS" \ && (eval 'x=a/b/c; test 5aa/bb/cc = "${#x}${x%%/*}${x%/*}${x#*/}${x##*/}"') 2>/dev/null \ && _G_HAVE_XSI_OPS=yes if test yes = "$_G_HAVE_XSI_OPS"; then eval 'func_len () { $debug_cmd func_len_result=${#1} }' else func_len () { $debug_cmd func_len_result=`expr "$1" : ".*" 2>/dev/null || echo $max_cmd_len` } fi # func_mkdir_p DIRECTORY-PATH # --------------------------- # Make sure the entire path to DIRECTORY-PATH is available. func_mkdir_p () { $debug_cmd _G_directory_path=$1 _G_dir_list= if test -n "$_G_directory_path" && test : != "$opt_dry_run"; then # Protect directory names starting with '-' case $_G_directory_path in -*) _G_directory_path=./$_G_directory_path ;; esac # While some portion of DIR does not yet exist... while test ! -d "$_G_directory_path"; do # ...make a list in topmost first order. Use a colon delimited # list incase some portion of path contains whitespace. _G_dir_list=$_G_directory_path:$_G_dir_list # If the last portion added has no slash in it, the list is done case $_G_directory_path in */*) ;; *) break ;; esac # ...otherwise throw away the child directory and loop _G_directory_path=`$ECHO "$_G_directory_path" | $SED -e "$sed_dirname"` done _G_dir_list=`$ECHO "$_G_dir_list" | $SED 's|:*$||'` func_mkdir_p_IFS=$IFS; IFS=: for _G_dir in $_G_dir_list; do IFS=$func_mkdir_p_IFS # mkdir can fail with a 'File exist' error if two processes # try to create one of the directories concurrently. Don't # stop in that case! $MKDIR "$_G_dir" 2>/dev/null || : done IFS=$func_mkdir_p_IFS # Bail out if we (or some other process) failed to create a directory. test -d "$_G_directory_path" || \ func_fatal_error "Failed to create '$1'" fi } # func_mktempdir [BASENAME] # ------------------------- # Make a temporary directory that won't clash with other running # libtool processes, and avoids race conditions if possible. If # given, BASENAME is the basename for that directory. func_mktempdir () { $debug_cmd _G_template=${TMPDIR-/tmp}/${1-$progname} if test : = "$opt_dry_run"; then # Return a directory name, but don't create it in dry-run mode _G_tmpdir=$_G_template-$$ else # If mktemp works, use that first and foremost _G_tmpdir=`mktemp -d "$_G_template-XXXXXXXX" 2>/dev/null` if test ! -d "$_G_tmpdir"; then # Failing that, at least try and use $RANDOM to avoid a race _G_tmpdir=$_G_template-${RANDOM-0}$$ func_mktempdir_umask=`umask` umask 0077 $MKDIR "$_G_tmpdir" umask $func_mktempdir_umask fi # If we're not in dry-run mode, bomb out on failure test -d "$_G_tmpdir" || \ func_fatal_error "cannot create temporary directory '$_G_tmpdir'" fi $ECHO "$_G_tmpdir" } # func_normal_abspath PATH # ------------------------ # Remove doubled-up and trailing slashes, "." path components, # and cancel out any ".." path components in PATH after making # it an absolute path. func_normal_abspath () { $debug_cmd # These SED scripts presuppose an absolute path with a trailing slash. _G_pathcar='s|^/\([^/]*\).*$|\1|' _G_pathcdr='s|^/[^/]*||' _G_removedotparts=':dotsl s|/\./|/|g t dotsl s|/\.$|/|' _G_collapseslashes='s|/\{1,\}|/|g' _G_finalslash='s|/*$|/|' # Start from root dir and reassemble the path. func_normal_abspath_result= func_normal_abspath_tpath=$1 func_normal_abspath_altnamespace= case $func_normal_abspath_tpath in "") # Empty path, that just means $cwd. func_stripname '' '/' "`pwd`" func_normal_abspath_result=$func_stripname_result return ;; # The next three entries are used to spot a run of precisely # two leading slashes without using negated character classes; # we take advantage of case's first-match behaviour. ///*) # Unusual form of absolute path, do nothing. ;; //*) # Not necessarily an ordinary path; POSIX reserves leading '//' # and for example Cygwin uses it to access remote file shares # over CIFS/SMB, so we conserve a leading double slash if found. func_normal_abspath_altnamespace=/ ;; /*) # Absolute path, do nothing. ;; *) # Relative path, prepend $cwd. func_normal_abspath_tpath=`pwd`/$func_normal_abspath_tpath ;; esac # Cancel out all the simple stuff to save iterations. We also want # the path to end with a slash for ease of parsing, so make sure # there is one (and only one) here. func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ -e "$_G_removedotparts" -e "$_G_collapseslashes" -e "$_G_finalslash"` while :; do # Processed it all yet? if test / = "$func_normal_abspath_tpath"; then # If we ascended to the root using ".." the result may be empty now. if test -z "$func_normal_abspath_result"; then func_normal_abspath_result=/ fi break fi func_normal_abspath_tcomponent=`$ECHO "$func_normal_abspath_tpath" | $SED \ -e "$_G_pathcar"` func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ -e "$_G_pathcdr"` # Figure out what to do with it case $func_normal_abspath_tcomponent in "") # Trailing empty path component, ignore it. ;; ..) # Parent dir; strip last assembled component from result. func_dirname "$func_normal_abspath_result" func_normal_abspath_result=$func_dirname_result ;; *) # Actual path component, append it. func_append func_normal_abspath_result "/$func_normal_abspath_tcomponent" ;; esac done # Restore leading double-slash if one was found on entry. func_normal_abspath_result=$func_normal_abspath_altnamespace$func_normal_abspath_result } # func_notquiet ARG... # -------------------- # Echo program name prefixed message only when not in quiet mode. func_notquiet () { $debug_cmd $opt_quiet || func_echo ${1+"$@"} # A bug in bash halts the script if the last line of a function # fails when set -e is in force, so we need another command to # work around that: : } # func_relative_path SRCDIR DSTDIR # -------------------------------- # Set func_relative_path_result to the relative path from SRCDIR to DSTDIR. func_relative_path () { $debug_cmd func_relative_path_result= func_normal_abspath "$1" func_relative_path_tlibdir=$func_normal_abspath_result func_normal_abspath "$2" func_relative_path_tbindir=$func_normal_abspath_result # Ascend the tree starting from libdir while :; do # check if we have found a prefix of bindir case $func_relative_path_tbindir in $func_relative_path_tlibdir) # found an exact match func_relative_path_tcancelled= break ;; $func_relative_path_tlibdir*) # found a matching prefix func_stripname "$func_relative_path_tlibdir" '' "$func_relative_path_tbindir" func_relative_path_tcancelled=$func_stripname_result if test -z "$func_relative_path_result"; then func_relative_path_result=. fi break ;; *) func_dirname $func_relative_path_tlibdir func_relative_path_tlibdir=$func_dirname_result if test -z "$func_relative_path_tlibdir"; then # Have to descend all the way to the root! func_relative_path_result=../$func_relative_path_result func_relative_path_tcancelled=$func_relative_path_tbindir break fi func_relative_path_result=../$func_relative_path_result ;; esac done # Now calculate path; take care to avoid doubling-up slashes. func_stripname '' '/' "$func_relative_path_result" func_relative_path_result=$func_stripname_result func_stripname '/' '/' "$func_relative_path_tcancelled" if test -n "$func_stripname_result"; then func_append func_relative_path_result "/$func_stripname_result" fi # Normalisation. If bindir is libdir, return '.' else relative path. if test -n "$func_relative_path_result"; then func_stripname './' '' "$func_relative_path_result" func_relative_path_result=$func_stripname_result fi test -n "$func_relative_path_result" || func_relative_path_result=. : } # func_quote_portable EVAL ARG # ---------------------------- # Internal function to portably implement func_quote_arg. Note that we still # keep attention to performance here so we as much as possible try to avoid # calling sed binary (so far O(N) complexity as long as func_append is O(1)). func_quote_portable () { $debug_cmd $require_check_ifs_backslash func_quote_portable_result=$2 # one-time-loop (easy break) while true do if $1; then func_quote_portable_result=`$ECHO "$2" | $SED \ -e "$sed_double_quote_subst" -e "$sed_double_backslash"` break fi # Quote for eval. case $func_quote_portable_result in *[\\\`\"\$]*) # Fallback to sed for $func_check_bs_ifs_broken=:, or when the string # contains the shell wildcard characters. case $check_ifs_backshlash_broken$func_quote_portable_result in :*|*[\[\*\?]*) func_quote_portable_result=`$ECHO "$func_quote_portable_result" \ | $SED "$sed_quote_subst"` break ;; esac func_quote_portable_old_IFS=$IFS for _G_char in '\' '`' '"' '$' do # STATE($1) PREV($2) SEPARATOR($3) set start "" "" func_quote_portable_result=dummy"$_G_char$func_quote_portable_result$_G_char"dummy IFS=$_G_char for _G_part in $func_quote_portable_result do case $1 in quote) func_append func_quote_portable_result "$3$2" set quote "$_G_part" "\\$_G_char" ;; start) set first "" "" func_quote_portable_result= ;; first) set quote "$_G_part" "" ;; esac done done IFS=$func_quote_portable_old_IFS ;; *) ;; esac break done func_quote_portable_unquoted_result=$func_quote_portable_result case $func_quote_portable_result in # double-quote args containing shell metacharacters to delay # word splitting, command substitution and variable expansion # for a subsequent eval. # many bourne shells cannot handle close brackets correctly # in scan sets, so we specify it separately. *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") func_quote_portable_result=\"$func_quote_portable_result\" ;; esac } # func_quotefast_eval ARG # ----------------------- # Quote one ARG (internal). This is equivalent to 'func_quote_arg eval ARG', # but optimized for speed. Result is stored in $func_quotefast_eval. if test xyes = `(x=; printf -v x %q yes; echo x"$x") 2>/dev/null`; then printf -v _GL_test_printf_tilde %q '~' if test '\~' = "$_GL_test_printf_tilde"; then func_quotefast_eval () { printf -v func_quotefast_eval_result %q "$1" } else # Broken older Bash implementations. Make those faster too if possible. func_quotefast_eval () { case $1 in '~'*) func_quote_portable false "$1" func_quotefast_eval_result=$func_quote_portable_result ;; *) printf -v func_quotefast_eval_result %q "$1" ;; esac } fi else func_quotefast_eval () { func_quote_portable false "$1" func_quotefast_eval_result=$func_quote_portable_result } fi # func_quote_arg MODEs ARG # ------------------------ # Quote one ARG to be evaled later. MODEs argument may contain zero or more # specifiers listed below separated by ',' character. This function returns two # values: # i) func_quote_arg_result # double-quoted (when needed), suitable for a subsequent eval # ii) func_quote_arg_unquoted_result # has all characters that are still active within double # quotes backslashified. Available only if 'unquoted' is specified. # # Available modes: # ---------------- # 'eval' (default) # - escape shell special characters # 'expand' # - the same as 'eval'; but do not quote variable references # 'pretty' # - request aesthetic output, i.e. '"a b"' instead of 'a\ b'. This might # be used later in func_quote to get output like: 'echo "a b"' instead # of 'echo a\ b'. This is slower than default on some shells. # 'unquoted' # - produce also $func_quote_arg_unquoted_result which does not contain # wrapping double-quotes. # # Examples for 'func_quote_arg pretty,unquoted string': # # string | *_result | *_unquoted_result # ------------+-----------------------+------------------- # " | \" | \" # a b | "a b" | a b # "a b" | "\"a b\"" | \"a b\" # * | "*" | * # z="${x-$y}" | "z=\"\${x-\$y}\"" | z=\"\${x-\$y}\" # # Examples for 'func_quote_arg pretty,unquoted,expand string': # # string | *_result | *_unquoted_result # --------------+---------------------+-------------------- # z="${x-$y}" | "z=\"${x-$y}\"" | z=\"${x-$y}\" func_quote_arg () { _G_quote_expand=false case ,$1, in *,expand,*) _G_quote_expand=: ;; esac case ,$1, in *,pretty,*|*,expand,*|*,unquoted,*) func_quote_portable $_G_quote_expand "$2" func_quote_arg_result=$func_quote_portable_result func_quote_arg_unquoted_result=$func_quote_portable_unquoted_result ;; *) # Faster quote-for-eval for some shells. func_quotefast_eval "$2" func_quote_arg_result=$func_quotefast_eval_result ;; esac } # func_quote MODEs ARGs... # ------------------------ # Quote all ARGs to be evaled later and join them into single command. See # func_quote_arg's description for more info. func_quote () { $debug_cmd _G_func_quote_mode=$1 ; shift func_quote_result= while test 0 -lt $#; do func_quote_arg "$_G_func_quote_mode" "$1" if test -n "$func_quote_result"; then func_append func_quote_result " $func_quote_arg_result" else func_append func_quote_result "$func_quote_arg_result" fi shift done } # func_stripname PREFIX SUFFIX NAME # --------------------------------- # strip PREFIX and SUFFIX from NAME, and store in func_stripname_result. # PREFIX and SUFFIX must not contain globbing or regex special # characters, hashes, percent signs, but SUFFIX may contain a leading # dot (in which case that matches only a dot). if test yes = "$_G_HAVE_XSI_OPS"; then eval 'func_stripname () { $debug_cmd # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are # positional parameters, so assign one to ordinary variable first. func_stripname_result=$3 func_stripname_result=${func_stripname_result#"$1"} func_stripname_result=${func_stripname_result%"$2"} }' else func_stripname () { $debug_cmd case $2 in .*) func_stripname_result=`$ECHO "$3" | $SED -e "s%^$1%%" -e "s%\\\\$2\$%%"`;; *) func_stripname_result=`$ECHO "$3" | $SED -e "s%^$1%%" -e "s%$2\$%%"`;; esac } fi # func_show_eval CMD [FAIL_EXP] # ----------------------------- # Unless opt_quiet is true, then output CMD. Then, if opt_dryrun is # not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP # is given, then evaluate it. func_show_eval () { $debug_cmd _G_cmd=$1 _G_fail_exp=${2-':'} func_quote_arg pretty,expand "$_G_cmd" eval "func_notquiet $func_quote_arg_result" $opt_dry_run || { eval "$_G_cmd" _G_status=$? if test 0 -ne "$_G_status"; then eval "(exit $_G_status); $_G_fail_exp" fi } } # func_show_eval_locale CMD [FAIL_EXP] # ------------------------------------ # Unless opt_quiet is true, then output CMD. Then, if opt_dryrun is # not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP # is given, then evaluate it. Use the saved locale for evaluation. func_show_eval_locale () { $debug_cmd _G_cmd=$1 _G_fail_exp=${2-':'} $opt_quiet || { func_quote_arg expand,pretty "$_G_cmd" eval "func_echo $func_quote_arg_result" } $opt_dry_run || { eval "$_G_user_locale $_G_cmd" _G_status=$? eval "$_G_safe_locale" if test 0 -ne "$_G_status"; then eval "(exit $_G_status); $_G_fail_exp" fi } } # func_tr_sh # ---------- # Turn $1 into a string suitable for a shell variable name. # Result is stored in $func_tr_sh_result. All characters # not in the set a-zA-Z0-9_ are replaced with '_'. Further, # if $1 begins with a digit, a '_' is prepended as well. func_tr_sh () { $debug_cmd case $1 in [0-9]* | *[!a-zA-Z0-9_]*) func_tr_sh_result=`$ECHO "$1" | $SED -e 's/^\([0-9]\)/_\1/' -e 's/[^a-zA-Z0-9_]/_/g'` ;; * ) func_tr_sh_result=$1 ;; esac } # func_verbose ARG... # ------------------- # Echo program name prefixed message in verbose mode only. func_verbose () { $debug_cmd $opt_verbose && func_echo "$*" : } # func_warn_and_continue ARG... # ----------------------------- # Echo program name prefixed warning message to standard error. func_warn_and_continue () { $debug_cmd $require_term_colors func_echo_infix_1 "${tc_red}warning$tc_reset" "$*" >&2 } # func_warning CATEGORY ARG... # ---------------------------- # Echo program name prefixed warning message to standard error. Warning # messages can be filtered according to CATEGORY, where this function # elides messages where CATEGORY is not listed in the global variable # 'opt_warning_types'. func_warning () { $debug_cmd # CATEGORY must be in the warning_categories list! case " $warning_categories " in *" $1 "*) ;; *) func_internal_error "invalid warning category '$1'" ;; esac _G_category=$1 shift case " $opt_warning_types " in *" $_G_category "*) $warning_func ${1+"$@"} ;; esac } # func_sort_ver VER1 VER2 # ----------------------- # 'sort -V' is not generally available. # Note this deviates from the version comparison in automake # in that it treats 1.5 < 1.5.0, and treats 1.4.4a < 1.4-p3a # but this should suffice as we won't be specifying old # version formats or redundant trailing .0 in bootstrap.conf. # If we did want full compatibility then we should probably # use m4_version_compare from autoconf. func_sort_ver () { $debug_cmd printf '%s\n%s\n' "$1" "$2" \ | sort -t. -k 1,1n -k 2,2n -k 3,3n -k 4,4n -k 5,5n -k 6,6n -k 7,7n -k 8,8n -k 9,9n } # func_lt_ver PREV CURR # --------------------- # Return true if PREV and CURR are in the correct order according to # func_sort_ver, otherwise false. Use it like this: # # func_lt_ver "$prev_ver" "$proposed_ver" || func_fatal_error "..." func_lt_ver () { $debug_cmd test "x$1" = x`func_sort_ver "$1" "$2" | $SED 1q` } # Local variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-pattern: "10/scriptversion=%:y-%02m-%02d.%02H; # UTC" # time-stamp-time-zone: "UTC" # End: #! /bin/sh # A portable, pluggable option parser for Bourne shell. # Written by Gary V. Vaughan, 2010 # This is free software. There is NO warranty; not even for # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # # Copyright (C) 2010-2019, 2021 Bootstrap Authors # # This file is dual licensed under the terms of the MIT license # , and GPL version 2 or later # . You must apply one of # these licenses when using or redistributing this software or any of # the files within it. See the URLs above, or the file `LICENSE` # included in the Bootstrap distribution for the full license texts. # Please report bugs or propose patches to: # # Set a version string for this script. scriptversion=2019-02-19.15; # UTC ## ------ ## ## Usage. ## ## ------ ## # This file is a library for parsing options in your shell scripts along # with assorted other useful supporting features that you can make use # of too. # # For the simplest scripts you might need only: # # #!/bin/sh # . relative/path/to/funclib.sh # . relative/path/to/options-parser # scriptversion=1.0 # func_options ${1+"$@"} # eval set dummy "$func_options_result"; shift # ...rest of your script... # # In order for the '--version' option to work, you will need to have a # suitably formatted comment like the one at the top of this file # starting with '# Written by ' and ending with '# Copyright'. # # For '-h' and '--help' to work, you will also need a one line # description of your script's purpose in a comment directly above the # '# Written by ' line, like the one at the top of this file. # # The default options also support '--debug', which will turn on shell # execution tracing (see the comment above debug_cmd below for another # use), and '--verbose' and the func_verbose function to allow your script # to display verbose messages only when your user has specified # '--verbose'. # # After sourcing this file, you can plug in processing for additional # options by amending the variables from the 'Configuration' section # below, and following the instructions in the 'Option parsing' # section further down. ## -------------- ## ## Configuration. ## ## -------------- ## # You should override these variables in your script after sourcing this # file so that they reflect the customisations you have added to the # option parser. # The usage line for option parsing errors and the start of '-h' and # '--help' output messages. You can embed shell variables for delayed # expansion at the time the message is displayed, but you will need to # quote other shell meta-characters carefully to prevent them being # expanded when the contents are evaled. usage='$progpath [OPTION]...' # Short help message in response to '-h' and '--help'. Add to this or # override it after sourcing this library to reflect the full set of # options your script accepts. usage_message="\ --debug enable verbose shell tracing -W, --warnings=CATEGORY report the warnings falling in CATEGORY [all] -v, --verbose verbosely report processing --version print version information and exit -h, --help print short or long help message and exit " # Additional text appended to 'usage_message' in response to '--help'. long_help_message=" Warning categories include: 'all' show all warnings 'none' turn off all the warnings 'error' warnings are treated as fatal errors" # Help message printed before fatal option parsing errors. fatal_help="Try '\$progname --help' for more information." ## ------------------------- ## ## Hook function management. ## ## ------------------------- ## # This section contains functions for adding, removing, and running hooks # in the main code. A hook is just a list of function names that can be # run in order later on. # func_hookable FUNC_NAME # ----------------------- # Declare that FUNC_NAME will run hooks added with # 'func_add_hook FUNC_NAME ...'. func_hookable () { $debug_cmd func_append hookable_fns " $1" } # func_add_hook FUNC_NAME HOOK_FUNC # --------------------------------- # Request that FUNC_NAME call HOOK_FUNC before it returns. FUNC_NAME must # first have been declared "hookable" by a call to 'func_hookable'. func_add_hook () { $debug_cmd case " $hookable_fns " in *" $1 "*) ;; *) func_fatal_error "'$1' does not accept hook functions." ;; esac eval func_append ${1}_hooks '" $2"' } # func_remove_hook FUNC_NAME HOOK_FUNC # ------------------------------------ # Remove HOOK_FUNC from the list of hook functions to be called by # FUNC_NAME. func_remove_hook () { $debug_cmd eval ${1}_hooks='`$ECHO "\$'$1'_hooks" |$SED "s| '$2'||"`' } # func_propagate_result FUNC_NAME_A FUNC_NAME_B # --------------------------------------------- # If the *_result variable of FUNC_NAME_A _is set_, assign its value to # *_result variable of FUNC_NAME_B. func_propagate_result () { $debug_cmd func_propagate_result_result=: if eval "test \"\${${1}_result+set}\" = set" then eval "${2}_result=\$${1}_result" else func_propagate_result_result=false fi } # func_run_hooks FUNC_NAME [ARG]... # --------------------------------- # Run all hook functions registered to FUNC_NAME. # It's assumed that the list of hook functions contains nothing more # than a whitespace-delimited list of legal shell function names, and # no effort is wasted trying to catch shell meta-characters or preserve # whitespace. func_run_hooks () { $debug_cmd case " $hookable_fns " in *" $1 "*) ;; *) func_fatal_error "'$1' does not support hook functions." ;; esac eval _G_hook_fns=\$$1_hooks; shift for _G_hook in $_G_hook_fns; do func_unset "${_G_hook}_result" eval $_G_hook '${1+"$@"}' func_propagate_result $_G_hook func_run_hooks if $func_propagate_result_result; then eval set dummy "$func_run_hooks_result"; shift fi done } ## --------------- ## ## Option parsing. ## ## --------------- ## # In order to add your own option parsing hooks, you must accept the # full positional parameter list from your hook function. You may remove # or edit any options that you action, and then pass back the remaining # unprocessed options in '_result', escaped # suitably for 'eval'. # # The '_result' variable is automatically unset # before your hook gets called; for best performance, only set the # *_result variable when necessary (i.e. don't call the 'func_quote' # function unnecessarily because it can be an expensive operation on some # machines). # # Like this: # # my_options_prep () # { # $debug_cmd # # # Extend the existing usage message. # usage_message=$usage_message' # -s, --silent don'\''t print informational messages # ' # # No change in '$@' (ignored completely by this hook). Leave # # my_options_prep_result variable intact. # } # func_add_hook func_options_prep my_options_prep # # # my_silent_option () # { # $debug_cmd # # args_changed=false # # # Note that, for efficiency, we parse as many options as we can # # recognise in a loop before passing the remainder back to the # # caller on the first unrecognised argument we encounter. # while test $# -gt 0; do # opt=$1; shift # case $opt in # --silent|-s) opt_silent=: # args_changed=: # ;; # # Separate non-argument short options: # -s*) func_split_short_opt "$_G_opt" # set dummy "$func_split_short_opt_name" \ # "-$func_split_short_opt_arg" ${1+"$@"} # shift # args_changed=: # ;; # *) # Make sure the first unrecognised option "$_G_opt" # # is added back to "$@" in case we need it later, # # if $args_changed was set to 'true'. # set dummy "$_G_opt" ${1+"$@"}; shift; break ;; # esac # done # # # Only call 'func_quote' here if we processed at least one argument. # if $args_changed; then # func_quote eval ${1+"$@"} # my_silent_option_result=$func_quote_result # fi # } # func_add_hook func_parse_options my_silent_option # # # my_option_validation () # { # $debug_cmd # # $opt_silent && $opt_verbose && func_fatal_help "\ # '--silent' and '--verbose' options are mutually exclusive." # } # func_add_hook func_validate_options my_option_validation # # You'll also need to manually amend $usage_message to reflect the extra # options you parse. It's preferable to append if you can, so that # multiple option parsing hooks can be added safely. # func_options_finish [ARG]... # ---------------------------- # Finishing the option parse loop (call 'func_options' hooks ATM). func_options_finish () { $debug_cmd func_run_hooks func_options ${1+"$@"} func_propagate_result func_run_hooks func_options_finish } # func_options [ARG]... # --------------------- # All the functions called inside func_options are hookable. See the # individual implementations for details. func_hookable func_options func_options () { $debug_cmd _G_options_quoted=false for my_func in options_prep parse_options validate_options options_finish do func_unset func_${my_func}_result func_unset func_run_hooks_result eval func_$my_func '${1+"$@"}' func_propagate_result func_$my_func func_options if $func_propagate_result_result; then eval set dummy "$func_options_result"; shift _G_options_quoted=: fi done $_G_options_quoted || { # As we (func_options) are top-level options-parser function and # nobody quoted "$@" for us yet, we need to do it explicitly for # caller. func_quote eval ${1+"$@"} func_options_result=$func_quote_result } } # func_options_prep [ARG]... # -------------------------- # All initialisations required before starting the option parse loop. # Note that when calling hook functions, we pass through the list of # positional parameters. If a hook function modifies that list, and # needs to propagate that back to rest of this script, then the complete # modified list must be put in 'func_run_hooks_result' before returning. func_hookable func_options_prep func_options_prep () { $debug_cmd # Option defaults: opt_verbose=false opt_warning_types= func_run_hooks func_options_prep ${1+"$@"} func_propagate_result func_run_hooks func_options_prep } # func_parse_options [ARG]... # --------------------------- # The main option parsing loop. func_hookable func_parse_options func_parse_options () { $debug_cmd _G_parse_options_requote=false # this just eases exit handling while test $# -gt 0; do # Defer to hook functions for initial option parsing, so they # get priority in the event of reusing an option name. func_run_hooks func_parse_options ${1+"$@"} func_propagate_result func_run_hooks func_parse_options if $func_propagate_result_result; then eval set dummy "$func_parse_options_result"; shift # Even though we may have changed "$@", we passed the "$@" array # down into the hook and it quoted it for us (because we are in # this if-branch). No need to quote it again. _G_parse_options_requote=false fi # Break out of the loop if we already parsed every option. test $# -gt 0 || break # We expect that one of the options parsed in this function matches # and thus we remove _G_opt from "$@" and need to re-quote. _G_match_parse_options=: _G_opt=$1 shift case $_G_opt in --debug|-x) debug_cmd='set -x' func_echo "enabling shell trace mode" >&2 $debug_cmd ;; --no-warnings|--no-warning|--no-warn) set dummy --warnings none ${1+"$@"} shift ;; --warnings|--warning|-W) if test $# = 0 && func_missing_arg $_G_opt; then _G_parse_options_requote=: break fi case " $warning_categories $1" in *" $1 "*) # trailing space prevents matching last $1 above func_append_uniq opt_warning_types " $1" ;; *all) opt_warning_types=$warning_categories ;; *none) opt_warning_types=none warning_func=: ;; *error) opt_warning_types=$warning_categories warning_func=func_fatal_error ;; *) func_fatal_error \ "unsupported warning category: '$1'" ;; esac shift ;; --verbose|-v) opt_verbose=: ;; --version) func_version ;; -\?|-h) func_usage ;; --help) func_help ;; # Separate optargs to long options (plugins may need this): --*=*) func_split_equals "$_G_opt" set dummy "$func_split_equals_lhs" \ "$func_split_equals_rhs" ${1+"$@"} shift ;; # Separate optargs to short options: -W*) func_split_short_opt "$_G_opt" set dummy "$func_split_short_opt_name" \ "$func_split_short_opt_arg" ${1+"$@"} shift ;; # Separate non-argument short options: -\?*|-h*|-v*|-x*) func_split_short_opt "$_G_opt" set dummy "$func_split_short_opt_name" \ "-$func_split_short_opt_arg" ${1+"$@"} shift ;; --) _G_parse_options_requote=: ; break ;; -*) func_fatal_help "unrecognised option: '$_G_opt'" ;; *) set dummy "$_G_opt" ${1+"$@"}; shift _G_match_parse_options=false break ;; esac if $_G_match_parse_options; then _G_parse_options_requote=: fi done if $_G_parse_options_requote; then # save modified positional parameters for caller func_quote eval ${1+"$@"} func_parse_options_result=$func_quote_result fi } # func_validate_options [ARG]... # ------------------------------ # Perform any sanity checks on option settings and/or unconsumed # arguments. func_hookable func_validate_options func_validate_options () { $debug_cmd # Display all warnings if -W was not given. test -n "$opt_warning_types" || opt_warning_types=" $warning_categories" func_run_hooks func_validate_options ${1+"$@"} func_propagate_result func_run_hooks func_validate_options # Bail if the options were screwed! $exit_cmd $EXIT_FAILURE } ## ----------------- ## ## Helper functions. ## ## ----------------- ## # This section contains the helper functions used by the rest of the # hookable option parser framework in ascii-betical order. # func_fatal_help ARG... # ---------------------- # Echo program name prefixed message to standard error, followed by # a help hint, and exit. func_fatal_help () { $debug_cmd eval \$ECHO \""Usage: $usage"\" eval \$ECHO \""$fatal_help"\" func_error ${1+"$@"} exit $EXIT_FAILURE } # func_help # --------- # Echo long help message to standard output and exit. func_help () { $debug_cmd func_usage_message $ECHO "$long_help_message" exit 0 } # func_missing_arg ARGNAME # ------------------------ # Echo program name prefixed message to standard error and set global # exit_cmd. func_missing_arg () { $debug_cmd func_error "Missing argument for '$1'." exit_cmd=exit } # func_split_equals STRING # ------------------------ # Set func_split_equals_lhs and func_split_equals_rhs shell variables # after splitting STRING at the '=' sign. test -z "$_G_HAVE_XSI_OPS" \ && (eval 'x=a/b/c; test 5aa/bb/cc = "${#x}${x%%/*}${x%/*}${x#*/}${x##*/}"') 2>/dev/null \ && _G_HAVE_XSI_OPS=yes if test yes = "$_G_HAVE_XSI_OPS" then # This is an XSI compatible shell, allowing a faster implementation... eval 'func_split_equals () { $debug_cmd func_split_equals_lhs=${1%%=*} func_split_equals_rhs=${1#*=} if test "x$func_split_equals_lhs" = "x$1"; then func_split_equals_rhs= fi }' else # ...otherwise fall back to using expr, which is often a shell builtin. func_split_equals () { $debug_cmd func_split_equals_lhs=`expr "x$1" : 'x\([^=]*\)'` func_split_equals_rhs= test "x$func_split_equals_lhs=" = "x$1" \ || func_split_equals_rhs=`expr "x$1" : 'x[^=]*=\(.*\)$'` } fi #func_split_equals # func_split_short_opt SHORTOPT # ----------------------------- # Set func_split_short_opt_name and func_split_short_opt_arg shell # variables after splitting SHORTOPT after the 2nd character. if test yes = "$_G_HAVE_XSI_OPS" then # This is an XSI compatible shell, allowing a faster implementation... eval 'func_split_short_opt () { $debug_cmd func_split_short_opt_arg=${1#??} func_split_short_opt_name=${1%"$func_split_short_opt_arg"} }' else # ...otherwise fall back to using expr, which is often a shell builtin. func_split_short_opt () { $debug_cmd func_split_short_opt_name=`expr "x$1" : 'x\(-.\)'` func_split_short_opt_arg=`expr "x$1" : 'x-.\(.*\)$'` } fi #func_split_short_opt # func_usage # ---------- # Echo short help message to standard output and exit. func_usage () { $debug_cmd func_usage_message $ECHO "Run '$progname --help |${PAGER-more}' for full usage" exit 0 } # func_usage_message # ------------------ # Echo short help message to standard output. func_usage_message () { $debug_cmd eval \$ECHO \""Usage: $usage"\" echo $SED -n 's|^# || /^Written by/{ x;p;x } h /^Written by/q' < "$progpath" echo eval \$ECHO \""$usage_message"\" } # func_version # ------------ # Echo version message to standard output and exit. # The version message is extracted from the calling file's header # comments, with leading '# ' stripped: # 1. First display the progname and version # 2. Followed by the header comment line matching /^# Written by / # 3. Then a blank line followed by the first following line matching # /^# Copyright / # 4. Immediately followed by any lines between the previous matches, # except lines preceding the intervening completely blank line. # For example, see the header comments of this file. func_version () { $debug_cmd printf '%s\n' "$progname $scriptversion" $SED -n ' /^# Written by /!b s|^# ||; p; n :fwd2blnk /./ { n b fwd2blnk } p; n :holdwrnt s|^# || s|^# *$|| /^Copyright /!{ /./H n b holdwrnt } s|\((C)\)[ 0-9,-]*[ ,-]\([1-9][0-9]* \)|\1 \2| G s|\(\n\)\n*|\1|g p; q' < "$progpath" exit $? } # Local variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-pattern: "30/scriptversion=%:y-%02m-%02d.%02H; # UTC" # time-stamp-time-zone: "UTC" # End: # Set a version string. scriptversion='(GNU libtool) 2.4.7' # func_echo ARG... # ---------------- # Libtool also displays the current mode in messages, so override # funclib.sh func_echo with this custom definition. func_echo () { $debug_cmd _G_message=$* func_echo_IFS=$IFS IFS=$nl for _G_line in $_G_message; do IFS=$func_echo_IFS $ECHO "$progname${opt_mode+: $opt_mode}: $_G_line" done IFS=$func_echo_IFS } # func_warning ARG... # ------------------- # Libtool warnings are not categorized, so override funclib.sh # func_warning with this simpler definition. func_warning () { $debug_cmd $warning_func ${1+"$@"} } ## ---------------- ## ## Options parsing. ## ## ---------------- ## # Hook in the functions to make sure our own options are parsed during # the option parsing loop. usage='$progpath [OPTION]... [MODE-ARG]...' # Short help message in response to '-h'. usage_message="Options: --config show all configuration variables --debug enable verbose shell tracing -n, --dry-run display commands without modifying any files --features display basic configuration information and exit --mode=MODE use operation mode MODE --no-warnings equivalent to '-Wnone' --preserve-dup-deps don't remove duplicate dependency libraries --quiet, --silent don't print informational messages --tag=TAG use configuration variables from tag TAG -v, --verbose print more informational messages than default --version print version information -W, --warnings=CATEGORY report the warnings falling in CATEGORY [all] -h, --help, --help-all print short, long, or detailed help message " # Additional text appended to 'usage_message' in response to '--help'. func_help () { $debug_cmd func_usage_message $ECHO "$long_help_message MODE must be one of the following: clean remove files from the build directory compile compile a source file into a libtool object execute automatically set library path, then run a program finish complete the installation of libtool libraries install install libraries or executables link create a library or an executable uninstall remove libraries from an installed directory MODE-ARGS vary depending on the MODE. When passed as first option, '--mode=MODE' may be abbreviated as 'MODE' or a unique abbreviation of that. Try '$progname --help --mode=MODE' for a more detailed description of MODE. When reporting a bug, please describe a test case to reproduce it and include the following information: host-triplet: $host shell: $SHELL compiler: $LTCC compiler flags: $LTCFLAGS linker: $LD (gnu? $with_gnu_ld) version: $progname (GNU libtool) 2.4.7 automake: `($AUTOMAKE --version) 2>/dev/null |$SED 1q` autoconf: `($AUTOCONF --version) 2>/dev/null |$SED 1q` Report bugs to . GNU libtool home page: . General help using GNU software: ." exit 0 } # func_lo2o OBJECT-NAME # --------------------- # Transform OBJECT-NAME from a '.lo' suffix to the platform specific # object suffix. lo2o=s/\\.lo\$/.$objext/ o2lo=s/\\.$objext\$/.lo/ if test yes = "$_G_HAVE_XSI_OPS"; then eval 'func_lo2o () { case $1 in *.lo) func_lo2o_result=${1%.lo}.$objext ;; * ) func_lo2o_result=$1 ;; esac }' # func_xform LIBOBJ-OR-SOURCE # --------------------------- # Transform LIBOBJ-OR-SOURCE from a '.o' or '.c' (or otherwise) # suffix to a '.lo' libtool-object suffix. eval 'func_xform () { func_xform_result=${1%.*}.lo }' else # ...otherwise fall back to using sed. func_lo2o () { func_lo2o_result=`$ECHO "$1" | $SED "$lo2o"` } func_xform () { func_xform_result=`$ECHO "$1" | $SED 's|\.[^.]*$|.lo|'` } fi # func_fatal_configuration ARG... # ------------------------------- # Echo program name prefixed message to standard error, followed by # a configuration failure hint, and exit. func_fatal_configuration () { func_fatal_error ${1+"$@"} \ "See the $PACKAGE documentation for more information." \ "Fatal configuration error." } # func_config # ----------- # Display the configuration for all the tags in this script. func_config () { re_begincf='^# ### BEGIN LIBTOOL' re_endcf='^# ### END LIBTOOL' # Default configuration. $SED "1,/$re_begincf CONFIG/d;/$re_endcf CONFIG/,\$d" < "$progpath" # Now print the configurations for the tags. for tagname in $taglist; do $SED -n "/$re_begincf TAG CONFIG: $tagname\$/,/$re_endcf TAG CONFIG: $tagname\$/p" < "$progpath" done exit $? } # func_features # ------------- # Display the features supported by this script. func_features () { echo "host: $host" if test yes = "$build_libtool_libs"; then echo "enable shared libraries" else echo "disable shared libraries" fi if test yes = "$build_old_libs"; then echo "enable static libraries" else echo "disable static libraries" fi exit $? } # func_enable_tag TAGNAME # ----------------------- # Verify that TAGNAME is valid, and either flag an error and exit, or # enable the TAGNAME tag. We also add TAGNAME to the global $taglist # variable here. func_enable_tag () { # Global variable: tagname=$1 re_begincf="^# ### BEGIN LIBTOOL TAG CONFIG: $tagname\$" re_endcf="^# ### END LIBTOOL TAG CONFIG: $tagname\$" sed_extractcf=/$re_begincf/,/$re_endcf/p # Validate tagname. case $tagname in *[!-_A-Za-z0-9,/]*) func_fatal_error "invalid tag name: $tagname" ;; esac # Don't test for the "default" C tag, as we know it's # there but not specially marked. case $tagname in CC) ;; *) if $GREP "$re_begincf" "$progpath" >/dev/null 2>&1; then taglist="$taglist $tagname" # Evaluate the configuration. Be careful to quote the path # and the sed script, to avoid splitting on whitespace, but # also don't use non-portable quotes within backquotes within # quotes we have to do it in 2 steps: extractedcf=`$SED -n -e "$sed_extractcf" < "$progpath"` eval "$extractedcf" else func_error "ignoring unknown tag $tagname" fi ;; esac } # func_check_version_match # ------------------------ # Ensure that we are using m4 macros, and libtool script from the same # release of libtool. func_check_version_match () { if test "$package_revision" != "$macro_revision"; then if test "$VERSION" != "$macro_version"; then if test -z "$macro_version"; then cat >&2 <<_LT_EOF $progname: Version mismatch error. This is $PACKAGE $VERSION, but the $progname: definition of this LT_INIT comes from an older release. $progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION $progname: and run autoconf again. _LT_EOF else cat >&2 <<_LT_EOF $progname: Version mismatch error. This is $PACKAGE $VERSION, but the $progname: definition of this LT_INIT comes from $PACKAGE $macro_version. $progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION $progname: and run autoconf again. _LT_EOF fi else cat >&2 <<_LT_EOF $progname: Version mismatch error. This is $PACKAGE $VERSION, revision $package_revision, $progname: but the definition of this LT_INIT comes from revision $macro_revision. $progname: You should recreate aclocal.m4 with macros from revision $package_revision $progname: of $PACKAGE $VERSION and run autoconf again. _LT_EOF fi exit $EXIT_MISMATCH fi } # libtool_options_prep [ARG]... # ----------------------------- # Preparation for options parsed by libtool. libtool_options_prep () { $debug_mode # Option defaults: opt_config=false opt_dlopen= opt_dry_run=false opt_help=false opt_mode= opt_preserve_dup_deps=false opt_quiet=false nonopt= preserve_args= _G_rc_lt_options_prep=: # Shorthand for --mode=foo, only valid as the first argument case $1 in clean|clea|cle|cl) shift; set dummy --mode clean ${1+"$@"}; shift ;; compile|compil|compi|comp|com|co|c) shift; set dummy --mode compile ${1+"$@"}; shift ;; execute|execut|execu|exec|exe|ex|e) shift; set dummy --mode execute ${1+"$@"}; shift ;; finish|finis|fini|fin|fi|f) shift; set dummy --mode finish ${1+"$@"}; shift ;; install|instal|insta|inst|ins|in|i) shift; set dummy --mode install ${1+"$@"}; shift ;; link|lin|li|l) shift; set dummy --mode link ${1+"$@"}; shift ;; uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u) shift; set dummy --mode uninstall ${1+"$@"}; shift ;; *) _G_rc_lt_options_prep=false ;; esac if $_G_rc_lt_options_prep; then # Pass back the list of options. func_quote eval ${1+"$@"} libtool_options_prep_result=$func_quote_result fi } func_add_hook func_options_prep libtool_options_prep # libtool_parse_options [ARG]... # --------------------------------- # Provide handling for libtool specific options. libtool_parse_options () { $debug_cmd _G_rc_lt_parse_options=false # Perform our own loop to consume as many options as possible in # each iteration. while test $# -gt 0; do _G_match_lt_parse_options=: _G_opt=$1 shift case $_G_opt in --dry-run|--dryrun|-n) opt_dry_run=: ;; --config) func_config ;; --dlopen|-dlopen) opt_dlopen="${opt_dlopen+$opt_dlopen }$1" shift ;; --preserve-dup-deps) opt_preserve_dup_deps=: ;; --features) func_features ;; --finish) set dummy --mode finish ${1+"$@"}; shift ;; --help) opt_help=: ;; --help-all) opt_help=': help-all' ;; --mode) test $# = 0 && func_missing_arg $_G_opt && break opt_mode=$1 case $1 in # Valid mode arguments: clean|compile|execute|finish|install|link|relink|uninstall) ;; # Catch anything else as an error *) func_error "invalid argument for $_G_opt" exit_cmd=exit break ;; esac shift ;; --no-silent|--no-quiet) opt_quiet=false func_append preserve_args " $_G_opt" ;; --no-warnings|--no-warning|--no-warn) opt_warning=false func_append preserve_args " $_G_opt" ;; --no-verbose) opt_verbose=false func_append preserve_args " $_G_opt" ;; --silent|--quiet) opt_quiet=: opt_verbose=false func_append preserve_args " $_G_opt" ;; --tag) test $# = 0 && func_missing_arg $_G_opt && break opt_tag=$1 func_append preserve_args " $_G_opt $1" func_enable_tag "$1" shift ;; --verbose|-v) opt_quiet=false opt_verbose=: func_append preserve_args " $_G_opt" ;; # An option not handled by this hook function: *) set dummy "$_G_opt" ${1+"$@"} ; shift _G_match_lt_parse_options=false break ;; esac $_G_match_lt_parse_options && _G_rc_lt_parse_options=: done if $_G_rc_lt_parse_options; then # save modified positional parameters for caller func_quote eval ${1+"$@"} libtool_parse_options_result=$func_quote_result fi } func_add_hook func_parse_options libtool_parse_options # libtool_validate_options [ARG]... # --------------------------------- # Perform any sanity checks on option settings and/or unconsumed # arguments. libtool_validate_options () { # save first non-option argument if test 0 -lt $#; then nonopt=$1 shift fi # preserve --debug test : = "$debug_cmd" || func_append preserve_args " --debug" # Keeping compiler generated duplicates in $postdeps and $predeps is not # harmful, and is necessary in a majority of systems that use it to satisfy # symbol dependencies. opt_duplicate_compiler_generated_deps=: $opt_help || { # Sanity checks first: func_check_version_match test yes != "$build_libtool_libs" \ && test yes != "$build_old_libs" \ && func_fatal_configuration "not configured to build any kind of library" # Darwin sucks eval std_shrext=\"$shrext_cmds\" # Only execute mode is allowed to have -dlopen flags. if test -n "$opt_dlopen" && test execute != "$opt_mode"; then func_error "unrecognized option '-dlopen'" $ECHO "$help" 1>&2 exit $EXIT_FAILURE fi # Change the help message to a mode-specific one. generic_help=$help help="Try '$progname --help --mode=$opt_mode' for more information." } # Pass back the unparsed argument list func_quote eval ${1+"$@"} libtool_validate_options_result=$func_quote_result } func_add_hook func_validate_options libtool_validate_options # Process options as early as possible so that --help and --version # can return quickly. func_options ${1+"$@"} eval set dummy "$func_options_result"; shift ## ----------- ## ## Main. ## ## ----------- ## magic='%%%MAGIC variable%%%' magic_exe='%%%MAGIC EXE variable%%%' # Global variables. extracted_archives= extracted_serial=0 # If this variable is set in any of the actions, the command in it # will be execed at the end. This prevents here-documents from being # left over by shells. exec_cmd= # A function that is used when there is no print builtin or printf. func_fallback_echo () { eval 'cat <<_LTECHO_EOF $1 _LTECHO_EOF' } # func_generated_by_libtool # True iff stdin has been generated by Libtool. This function is only # a basic sanity check; it will hardly flush out determined imposters. func_generated_by_libtool_p () { $GREP "^# Generated by .*$PACKAGE" > /dev/null 2>&1 } # func_lalib_p file # True iff FILE is a libtool '.la' library or '.lo' object file. # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_lalib_p () { test -f "$1" && $SED -e 4q "$1" 2>/dev/null | func_generated_by_libtool_p } # func_lalib_unsafe_p file # True iff FILE is a libtool '.la' library or '.lo' object file. # This function implements the same check as func_lalib_p without # resorting to external programs. To this end, it redirects stdin and # closes it afterwards, without saving the original file descriptor. # As a safety measure, use it only where a negative result would be # fatal anyway. Works if 'file' does not exist. func_lalib_unsafe_p () { lalib_p=no if test -f "$1" && test -r "$1" && exec 5<&0 <"$1"; then for lalib_p_l in 1 2 3 4 do read lalib_p_line case $lalib_p_line in \#\ Generated\ by\ *$PACKAGE* ) lalib_p=yes; break;; esac done exec 0<&5 5<&- fi test yes = "$lalib_p" } # func_ltwrapper_script_p file # True iff FILE is a libtool wrapper script # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_ltwrapper_script_p () { test -f "$1" && $lt_truncate_bin < "$1" 2>/dev/null | func_generated_by_libtool_p } # func_ltwrapper_executable_p file # True iff FILE is a libtool wrapper executable # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_ltwrapper_executable_p () { func_ltwrapper_exec_suffix= case $1 in *.exe) ;; *) func_ltwrapper_exec_suffix=.exe ;; esac $GREP "$magic_exe" "$1$func_ltwrapper_exec_suffix" >/dev/null 2>&1 } # func_ltwrapper_scriptname file # Assumes file is an ltwrapper_executable # uses $file to determine the appropriate filename for a # temporary ltwrapper_script. func_ltwrapper_scriptname () { func_dirname_and_basename "$1" "" "." func_stripname '' '.exe' "$func_basename_result" func_ltwrapper_scriptname_result=$func_dirname_result/$objdir/${func_stripname_result}_ltshwrapper } # func_ltwrapper_p file # True iff FILE is a libtool wrapper script or wrapper executable # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_ltwrapper_p () { func_ltwrapper_script_p "$1" || func_ltwrapper_executable_p "$1" } # func_execute_cmds commands fail_cmd # Execute tilde-delimited COMMANDS. # If FAIL_CMD is given, eval that upon failure. # FAIL_CMD may read-access the current command in variable CMD! func_execute_cmds () { $debug_cmd save_ifs=$IFS; IFS='~' for cmd in $1; do IFS=$sp$nl eval cmd=\"$cmd\" IFS=$save_ifs func_show_eval "$cmd" "${2-:}" done IFS=$save_ifs } # func_source file # Source FILE, adding directory component if necessary. # Note that it is not necessary on cygwin/mingw to append a dot to # FILE even if both FILE and FILE.exe exist: automatic-append-.exe # behavior happens only for exec(3), not for open(2)! Also, sourcing # 'FILE.' does not work on cygwin managed mounts. func_source () { $debug_cmd case $1 in */* | *\\*) . "$1" ;; *) . "./$1" ;; esac } # func_resolve_sysroot PATH # Replace a leading = in PATH with a sysroot. Store the result into # func_resolve_sysroot_result func_resolve_sysroot () { func_resolve_sysroot_result=$1 case $func_resolve_sysroot_result in =*) func_stripname '=' '' "$func_resolve_sysroot_result" func_resolve_sysroot_result=$lt_sysroot$func_stripname_result ;; esac } # func_replace_sysroot PATH # If PATH begins with the sysroot, replace it with = and # store the result into func_replace_sysroot_result. func_replace_sysroot () { case $lt_sysroot:$1 in ?*:"$lt_sysroot"*) func_stripname "$lt_sysroot" '' "$1" func_replace_sysroot_result='='$func_stripname_result ;; *) # Including no sysroot. func_replace_sysroot_result=$1 ;; esac } # func_infer_tag arg # Infer tagged configuration to use if any are available and # if one wasn't chosen via the "--tag" command line option. # Only attempt this if the compiler in the base compile # command doesn't match the default compiler. # arg is usually of the form 'gcc ...' func_infer_tag () { $debug_cmd if test -n "$available_tags" && test -z "$tagname"; then CC_quoted= for arg in $CC; do func_append_quoted CC_quoted "$arg" done CC_expanded=`func_echo_all $CC` CC_quoted_expanded=`func_echo_all $CC_quoted` case $@ in # Blanks in the command may have been stripped by the calling shell, # but not from the CC environment variable when configure was run. " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \ " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) ;; # Blanks at the start of $base_compile will cause this to fail # if we don't check for them as well. *) for z in $available_tags; do if $GREP "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then # Evaluate the configuration. eval "`$SED -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`" CC_quoted= for arg in $CC; do # Double-quote args containing other shell metacharacters. func_append_quoted CC_quoted "$arg" done CC_expanded=`func_echo_all $CC` CC_quoted_expanded=`func_echo_all $CC_quoted` case "$@ " in " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \ " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) # The compiler in the base compile command matches # the one in the tagged configuration. # Assume this is the tagged configuration we want. tagname=$z break ;; esac fi done # If $tagname still isn't set, then no tagged configuration # was found and let the user know that the "--tag" command # line option must be used. if test -z "$tagname"; then func_echo "unable to infer tagged configuration" func_fatal_error "specify a tag with '--tag'" # else # func_verbose "using $tagname tagged configuration" fi ;; esac fi } # func_write_libtool_object output_name pic_name nonpic_name # Create a libtool object file (analogous to a ".la" file), # but don't create it if we're doing a dry run. func_write_libtool_object () { write_libobj=$1 if test yes = "$build_libtool_libs"; then write_lobj=\'$2\' else write_lobj=none fi if test yes = "$build_old_libs"; then write_oldobj=\'$3\' else write_oldobj=none fi $opt_dry_run || { cat >${write_libobj}T </dev/null` if test "$?" -eq 0 && test -n "$func_convert_core_file_wine_to_w32_tmp"; then func_convert_core_file_wine_to_w32_result=`$ECHO "$func_convert_core_file_wine_to_w32_tmp" | $SED -e "$sed_naive_backslashify"` else func_convert_core_file_wine_to_w32_result= fi fi } # end: func_convert_core_file_wine_to_w32 # func_convert_core_path_wine_to_w32 ARG # Helper function used by path conversion functions when $build is *nix, and # $host is mingw, cygwin, or some other w32 environment. Relies on a correctly # configured wine environment available, with the winepath program in $build's # $PATH. Assumes ARG has no leading or trailing path separator characters. # # ARG is path to be converted from $build format to win32. # Result is available in $func_convert_core_path_wine_to_w32_result. # Unconvertible file (directory) names in ARG are skipped; if no directory names # are convertible, then the result may be empty. func_convert_core_path_wine_to_w32 () { $debug_cmd # unfortunately, winepath doesn't convert paths, only file names func_convert_core_path_wine_to_w32_result= if test -n "$1"; then oldIFS=$IFS IFS=: for func_convert_core_path_wine_to_w32_f in $1; do IFS=$oldIFS func_convert_core_file_wine_to_w32 "$func_convert_core_path_wine_to_w32_f" if test -n "$func_convert_core_file_wine_to_w32_result"; then if test -z "$func_convert_core_path_wine_to_w32_result"; then func_convert_core_path_wine_to_w32_result=$func_convert_core_file_wine_to_w32_result else func_append func_convert_core_path_wine_to_w32_result ";$func_convert_core_file_wine_to_w32_result" fi fi done IFS=$oldIFS fi } # end: func_convert_core_path_wine_to_w32 # func_cygpath ARGS... # Wrapper around calling the cygpath program via LT_CYGPATH. This is used when # when (1) $build is *nix and Cygwin is hosted via a wine environment; or (2) # $build is MSYS and $host is Cygwin, or (3) $build is Cygwin. In case (1) or # (2), returns the Cygwin file name or path in func_cygpath_result (input # file name or path is assumed to be in w32 format, as previously converted # from $build's *nix or MSYS format). In case (3), returns the w32 file name # or path in func_cygpath_result (input file name or path is assumed to be in # Cygwin format). Returns an empty string on error. # # ARGS are passed to cygpath, with the last one being the file name or path to # be converted. # # Specify the absolute *nix (or w32) name to cygpath in the LT_CYGPATH # environment variable; do not put it in $PATH. func_cygpath () { $debug_cmd if test -n "$LT_CYGPATH" && test -f "$LT_CYGPATH"; then func_cygpath_result=`$LT_CYGPATH "$@" 2>/dev/null` if test "$?" -ne 0; then # on failure, ensure result is empty func_cygpath_result= fi else func_cygpath_result= func_error "LT_CYGPATH is empty or specifies non-existent file: '$LT_CYGPATH'" fi } #end: func_cygpath # func_convert_core_msys_to_w32 ARG # Convert file name or path ARG from MSYS format to w32 format. Return # result in func_convert_core_msys_to_w32_result. func_convert_core_msys_to_w32 () { $debug_cmd # awkward: cmd appends spaces to result func_convert_core_msys_to_w32_result=`( cmd //c echo "$1" ) 2>/dev/null | $SED -e 's/[ ]*$//' -e "$sed_naive_backslashify"` } #end: func_convert_core_msys_to_w32 # func_convert_file_check ARG1 ARG2 # Verify that ARG1 (a file name in $build format) was converted to $host # format in ARG2. Otherwise, emit an error message, but continue (resetting # func_to_host_file_result to ARG1). func_convert_file_check () { $debug_cmd if test -z "$2" && test -n "$1"; then func_error "Could not determine host file name corresponding to" func_error " '$1'" func_error "Continuing, but uninstalled executables may not work." # Fallback: func_to_host_file_result=$1 fi } # end func_convert_file_check # func_convert_path_check FROM_PATHSEP TO_PATHSEP FROM_PATH TO_PATH # Verify that FROM_PATH (a path in $build format) was converted to $host # format in TO_PATH. Otherwise, emit an error message, but continue, resetting # func_to_host_file_result to a simplistic fallback value (see below). func_convert_path_check () { $debug_cmd if test -z "$4" && test -n "$3"; then func_error "Could not determine the host path corresponding to" func_error " '$3'" func_error "Continuing, but uninstalled executables may not work." # Fallback. This is a deliberately simplistic "conversion" and # should not be "improved". See libtool.info. if test "x$1" != "x$2"; then lt_replace_pathsep_chars="s|$1|$2|g" func_to_host_path_result=`echo "$3" | $SED -e "$lt_replace_pathsep_chars"` else func_to_host_path_result=$3 fi fi } # end func_convert_path_check # func_convert_path_front_back_pathsep FRONTPAT BACKPAT REPL ORIG # Modifies func_to_host_path_result by prepending REPL if ORIG matches FRONTPAT # and appending REPL if ORIG matches BACKPAT. func_convert_path_front_back_pathsep () { $debug_cmd case $4 in $1 ) func_to_host_path_result=$3$func_to_host_path_result ;; esac case $4 in $2 ) func_append func_to_host_path_result "$3" ;; esac } # end func_convert_path_front_back_pathsep ################################################## # $build to $host FILE NAME CONVERSION FUNCTIONS # ################################################## # invoked via '$to_host_file_cmd ARG' # # In each case, ARG is the path to be converted from $build to $host format. # Result will be available in $func_to_host_file_result. # func_to_host_file ARG # Converts the file name ARG from $build format to $host format. Return result # in func_to_host_file_result. func_to_host_file () { $debug_cmd $to_host_file_cmd "$1" } # end func_to_host_file # func_to_tool_file ARG LAZY # converts the file name ARG from $build format to toolchain format. Return # result in func_to_tool_file_result. If the conversion in use is listed # in (the comma separated) LAZY, no conversion takes place. func_to_tool_file () { $debug_cmd case ,$2, in *,"$to_tool_file_cmd",*) func_to_tool_file_result=$1 ;; *) $to_tool_file_cmd "$1" func_to_tool_file_result=$func_to_host_file_result ;; esac } # end func_to_tool_file # func_convert_file_noop ARG # Copy ARG to func_to_host_file_result. func_convert_file_noop () { func_to_host_file_result=$1 } # end func_convert_file_noop # func_convert_file_msys_to_w32 ARG # Convert file name ARG from (mingw) MSYS to (mingw) w32 format; automatic # conversion to w32 is not available inside the cwrapper. Returns result in # func_to_host_file_result. func_convert_file_msys_to_w32 () { $debug_cmd func_to_host_file_result=$1 if test -n "$1"; then func_convert_core_msys_to_w32 "$1" func_to_host_file_result=$func_convert_core_msys_to_w32_result fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_msys_to_w32 # func_convert_file_cygwin_to_w32 ARG # Convert file name ARG from Cygwin to w32 format. Returns result in # func_to_host_file_result. func_convert_file_cygwin_to_w32 () { $debug_cmd func_to_host_file_result=$1 if test -n "$1"; then # because $build is cygwin, we call "the" cygpath in $PATH; no need to use # LT_CYGPATH in this case. func_to_host_file_result=`cygpath -m "$1"` fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_cygwin_to_w32 # func_convert_file_nix_to_w32 ARG # Convert file name ARG from *nix to w32 format. Requires a wine environment # and a working winepath. Returns result in func_to_host_file_result. func_convert_file_nix_to_w32 () { $debug_cmd func_to_host_file_result=$1 if test -n "$1"; then func_convert_core_file_wine_to_w32 "$1" func_to_host_file_result=$func_convert_core_file_wine_to_w32_result fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_nix_to_w32 # func_convert_file_msys_to_cygwin ARG # Convert file name ARG from MSYS to Cygwin format. Requires LT_CYGPATH set. # Returns result in func_to_host_file_result. func_convert_file_msys_to_cygwin () { $debug_cmd func_to_host_file_result=$1 if test -n "$1"; then func_convert_core_msys_to_w32 "$1" func_cygpath -u "$func_convert_core_msys_to_w32_result" func_to_host_file_result=$func_cygpath_result fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_msys_to_cygwin # func_convert_file_nix_to_cygwin ARG # Convert file name ARG from *nix to Cygwin format. Requires Cygwin installed # in a wine environment, working winepath, and LT_CYGPATH set. Returns result # in func_to_host_file_result. func_convert_file_nix_to_cygwin () { $debug_cmd func_to_host_file_result=$1 if test -n "$1"; then # convert from *nix to w32, then use cygpath to convert from w32 to cygwin. func_convert_core_file_wine_to_w32 "$1" func_cygpath -u "$func_convert_core_file_wine_to_w32_result" func_to_host_file_result=$func_cygpath_result fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_nix_to_cygwin ############################################# # $build to $host PATH CONVERSION FUNCTIONS # ############################################# # invoked via '$to_host_path_cmd ARG' # # In each case, ARG is the path to be converted from $build to $host format. # The result will be available in $func_to_host_path_result. # # Path separators are also converted from $build format to $host format. If # ARG begins or ends with a path separator character, it is preserved (but # converted to $host format) on output. # # All path conversion functions are named using the following convention: # file name conversion function : func_convert_file_X_to_Y () # path conversion function : func_convert_path_X_to_Y () # where, for any given $build/$host combination the 'X_to_Y' value is the # same. If conversion functions are added for new $build/$host combinations, # the two new functions must follow this pattern, or func_init_to_host_path_cmd # will break. # func_init_to_host_path_cmd # Ensures that function "pointer" variable $to_host_path_cmd is set to the # appropriate value, based on the value of $to_host_file_cmd. to_host_path_cmd= func_init_to_host_path_cmd () { $debug_cmd if test -z "$to_host_path_cmd"; then func_stripname 'func_convert_file_' '' "$to_host_file_cmd" to_host_path_cmd=func_convert_path_$func_stripname_result fi } # func_to_host_path ARG # Converts the path ARG from $build format to $host format. Return result # in func_to_host_path_result. func_to_host_path () { $debug_cmd func_init_to_host_path_cmd $to_host_path_cmd "$1" } # end func_to_host_path # func_convert_path_noop ARG # Copy ARG to func_to_host_path_result. func_convert_path_noop () { func_to_host_path_result=$1 } # end func_convert_path_noop # func_convert_path_msys_to_w32 ARG # Convert path ARG from (mingw) MSYS to (mingw) w32 format; automatic # conversion to w32 is not available inside the cwrapper. Returns result in # func_to_host_path_result. func_convert_path_msys_to_w32 () { $debug_cmd func_to_host_path_result=$1 if test -n "$1"; then # Remove leading and trailing path separator characters from ARG. MSYS # behavior is inconsistent here; cygpath turns them into '.;' and ';.'; # and winepath ignores them completely. func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_convert_core_msys_to_w32 "$func_to_host_path_tmp1" func_to_host_path_result=$func_convert_core_msys_to_w32_result func_convert_path_check : ";" \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" fi } # end func_convert_path_msys_to_w32 # func_convert_path_cygwin_to_w32 ARG # Convert path ARG from Cygwin to w32 format. Returns result in # func_to_host_file_result. func_convert_path_cygwin_to_w32 () { $debug_cmd func_to_host_path_result=$1 if test -n "$1"; then # See func_convert_path_msys_to_w32: func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_to_host_path_result=`cygpath -m -p "$func_to_host_path_tmp1"` func_convert_path_check : ";" \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" fi } # end func_convert_path_cygwin_to_w32 # func_convert_path_nix_to_w32 ARG # Convert path ARG from *nix to w32 format. Requires a wine environment and # a working winepath. Returns result in func_to_host_file_result. func_convert_path_nix_to_w32 () { $debug_cmd func_to_host_path_result=$1 if test -n "$1"; then # See func_convert_path_msys_to_w32: func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1" func_to_host_path_result=$func_convert_core_path_wine_to_w32_result func_convert_path_check : ";" \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" fi } # end func_convert_path_nix_to_w32 # func_convert_path_msys_to_cygwin ARG # Convert path ARG from MSYS to Cygwin format. Requires LT_CYGPATH set. # Returns result in func_to_host_file_result. func_convert_path_msys_to_cygwin () { $debug_cmd func_to_host_path_result=$1 if test -n "$1"; then # See func_convert_path_msys_to_w32: func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_convert_core_msys_to_w32 "$func_to_host_path_tmp1" func_cygpath -u -p "$func_convert_core_msys_to_w32_result" func_to_host_path_result=$func_cygpath_result func_convert_path_check : : \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" : "$1" fi } # end func_convert_path_msys_to_cygwin # func_convert_path_nix_to_cygwin ARG # Convert path ARG from *nix to Cygwin format. Requires Cygwin installed in a # a wine environment, working winepath, and LT_CYGPATH set. Returns result in # func_to_host_file_result. func_convert_path_nix_to_cygwin () { $debug_cmd func_to_host_path_result=$1 if test -n "$1"; then # Remove leading and trailing path separator characters from # ARG. msys behavior is inconsistent here, cygpath turns them # into '.;' and ';.', and winepath ignores them completely. func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1" func_cygpath -u -p "$func_convert_core_path_wine_to_w32_result" func_to_host_path_result=$func_cygpath_result func_convert_path_check : : \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" : "$1" fi } # end func_convert_path_nix_to_cygwin # func_dll_def_p FILE # True iff FILE is a Windows DLL '.def' file. # Keep in sync with _LT_DLL_DEF_P in libtool.m4 func_dll_def_p () { $debug_cmd func_dll_def_p_tmp=`$SED -n \ -e 's/^[ ]*//' \ -e '/^\(;.*\)*$/d' \ -e 's/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p' \ -e q \ "$1"` test DEF = "$func_dll_def_p_tmp" } # func_mode_compile arg... func_mode_compile () { $debug_cmd # Get the compilation command and the source file. base_compile= srcfile=$nonopt # always keep a non-empty value in "srcfile" suppress_opt=yes suppress_output= arg_mode=normal libobj= later= pie_flag= for arg do case $arg_mode in arg ) # do not "continue". Instead, add this to base_compile lastarg=$arg arg_mode=normal ;; target ) libobj=$arg arg_mode=normal continue ;; normal ) # Accept any command-line options. case $arg in -o) test -n "$libobj" && \ func_fatal_error "you cannot specify '-o' more than once" arg_mode=target continue ;; -pie | -fpie | -fPIE) func_append pie_flag " $arg" continue ;; -shared | -static | -prefer-pic | -prefer-non-pic) func_append later " $arg" continue ;; -no-suppress) suppress_opt=no continue ;; -Xcompiler) arg_mode=arg # the next one goes into the "base_compile" arg list continue # The current "srcfile" will either be retained or ;; # replaced later. I would guess that would be a bug. -Wc,*) func_stripname '-Wc,' '' "$arg" args=$func_stripname_result lastarg= save_ifs=$IFS; IFS=, for arg in $args; do IFS=$save_ifs func_append_quoted lastarg "$arg" done IFS=$save_ifs func_stripname ' ' '' "$lastarg" lastarg=$func_stripname_result # Add the arguments to base_compile. func_append base_compile " $lastarg" continue ;; *) # Accept the current argument as the source file. # The previous "srcfile" becomes the current argument. # lastarg=$srcfile srcfile=$arg ;; esac # case $arg ;; esac # case $arg_mode # Aesthetically quote the previous argument. func_append_quoted base_compile "$lastarg" done # for arg case $arg_mode in arg) func_fatal_error "you must specify an argument for -Xcompile" ;; target) func_fatal_error "you must specify a target with '-o'" ;; *) # Get the name of the library object. test -z "$libobj" && { func_basename "$srcfile" libobj=$func_basename_result } ;; esac # Recognize several different file suffixes. # If the user specifies -o file.o, it is replaced with file.lo case $libobj in *.[cCFSifmso] | \ *.ada | *.adb | *.ads | *.asm | \ *.c++ | *.cc | *.ii | *.class | *.cpp | *.cxx | \ *.[fF][09]? | *.for | *.java | *.go | *.obj | *.sx | *.cu | *.cup) func_xform "$libobj" libobj=$func_xform_result ;; esac case $libobj in *.lo) func_lo2o "$libobj"; obj=$func_lo2o_result ;; *) func_fatal_error "cannot determine name of library object from '$libobj'" ;; esac func_infer_tag $base_compile for arg in $later; do case $arg in -shared) test yes = "$build_libtool_libs" \ || func_fatal_configuration "cannot build a shared library" build_old_libs=no continue ;; -static) build_libtool_libs=no build_old_libs=yes continue ;; -prefer-pic) pic_mode=yes continue ;; -prefer-non-pic) pic_mode=no continue ;; esac done func_quote_arg pretty "$libobj" test "X$libobj" != "X$func_quote_arg_result" \ && $ECHO "X$libobj" | $GREP '[]~#^*{};<>?"'"'"' &()|`$[]' \ && func_warning "libobj name '$libobj' may not contain shell special characters." func_dirname_and_basename "$obj" "/" "" objname=$func_basename_result xdir=$func_dirname_result lobj=$xdir$objdir/$objname test -z "$base_compile" && \ func_fatal_help "you must specify a compilation command" # Delete any leftover library objects. if test yes = "$build_old_libs"; then removelist="$obj $lobj $libobj ${libobj}T" else removelist="$lobj $libobj ${libobj}T" fi # On Cygwin there's no "real" PIC flag so we must build both object types case $host_os in cygwin* | mingw* | pw32* | os2* | cegcc*) pic_mode=default ;; esac if test no = "$pic_mode" && test pass_all != "$deplibs_check_method"; then # non-PIC code in shared libraries is not supported pic_mode=default fi # Calculate the filename of the output object if compiler does # not support -o with -c if test no = "$compiler_c_o"; then output_obj=`$ECHO "$srcfile" | $SED 's%^.*/%%; s%\.[^.]*$%%'`.$objext lockfile=$output_obj.lock else output_obj= need_locks=no lockfile= fi # Lock this critical section if it is needed # We use this script file to make the link, it avoids creating a new file if test yes = "$need_locks"; then until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do func_echo "Waiting for $lockfile to be removed" sleep 2 done elif test warn = "$need_locks"; then if test -f "$lockfile"; then $ECHO "\ *** ERROR, $lockfile exists and contains: `cat $lockfile 2>/dev/null` This indicates that another process is trying to use the same temporary object file, and libtool could not work around it because your compiler does not support '-c' and '-o' together. If you repeat this compilation, it may succeed, by chance, but you had better avoid parallel builds (make -j) in this platform, or get a better compiler." $opt_dry_run || $RM $removelist exit $EXIT_FAILURE fi func_append removelist " $output_obj" $ECHO "$srcfile" > "$lockfile" fi $opt_dry_run || $RM $removelist func_append removelist " $lockfile" trap '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' 1 2 15 func_to_tool_file "$srcfile" func_convert_file_msys_to_w32 srcfile=$func_to_tool_file_result func_quote_arg pretty "$srcfile" qsrcfile=$func_quote_arg_result # Only build a PIC object if we are building libtool libraries. if test yes = "$build_libtool_libs"; then # Without this assignment, base_compile gets emptied. fbsd_hideous_sh_bug=$base_compile if test no != "$pic_mode"; then command="$base_compile $qsrcfile $pic_flag" else # Don't build PIC code command="$base_compile $qsrcfile" fi func_mkdir_p "$xdir$objdir" if test -z "$output_obj"; then # Place PIC objects in $objdir func_append command " -o $lobj" fi func_show_eval_locale "$command" \ 'test -n "$output_obj" && $RM $removelist; exit $EXIT_FAILURE' if test warn = "$need_locks" && test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then $ECHO "\ *** ERROR, $lockfile contains: `cat $lockfile 2>/dev/null` but it should contain: $srcfile This indicates that another process is trying to use the same temporary object file, and libtool could not work around it because your compiler does not support '-c' and '-o' together. If you repeat this compilation, it may succeed, by chance, but you had better avoid parallel builds (make -j) in this platform, or get a better compiler." $opt_dry_run || $RM $removelist exit $EXIT_FAILURE fi # Just move the object if needed, then go on to compile the next one if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then func_show_eval '$MV "$output_obj" "$lobj"' \ 'error=$?; $opt_dry_run || $RM $removelist; exit $error' fi # Allow error messages only from the first compilation. if test yes = "$suppress_opt"; then suppress_output=' >/dev/null 2>&1' fi fi # Only build a position-dependent object if we build old libraries. if test yes = "$build_old_libs"; then if test yes != "$pic_mode"; then # Don't build PIC code command="$base_compile $qsrcfile$pie_flag" else command="$base_compile $qsrcfile $pic_flag" fi if test yes = "$compiler_c_o"; then func_append command " -o $obj" fi # Suppress compiler output if we already did a PIC compilation. func_append command "$suppress_output" func_show_eval_locale "$command" \ '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' if test warn = "$need_locks" && test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then $ECHO "\ *** ERROR, $lockfile contains: `cat $lockfile 2>/dev/null` but it should contain: $srcfile This indicates that another process is trying to use the same temporary object file, and libtool could not work around it because your compiler does not support '-c' and '-o' together. If you repeat this compilation, it may succeed, by chance, but you had better avoid parallel builds (make -j) in this platform, or get a better compiler." $opt_dry_run || $RM $removelist exit $EXIT_FAILURE fi # Just move the object if needed if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then func_show_eval '$MV "$output_obj" "$obj"' \ 'error=$?; $opt_dry_run || $RM $removelist; exit $error' fi fi $opt_dry_run || { func_write_libtool_object "$libobj" "$objdir/$objname" "$objname" # Unlock the critical section if it was locked if test no != "$need_locks"; then removelist=$lockfile $RM "$lockfile" fi } exit $EXIT_SUCCESS } $opt_help || { test compile = "$opt_mode" && func_mode_compile ${1+"$@"} } func_mode_help () { # We need to display help for each of the modes. case $opt_mode in "") # Generic help is extracted from the usage comments # at the start of this file. func_help ;; clean) $ECHO \ "Usage: $progname [OPTION]... --mode=clean RM [RM-OPTION]... FILE... Remove files from the build directory. RM is the name of the program to use to delete files associated with each FILE (typically '/bin/rm'). RM-OPTIONS are options (such as '-f') to be passed to RM. If FILE is a libtool library, object or program, all the files associated with it are deleted. Otherwise, only FILE itself is deleted using RM." ;; compile) $ECHO \ "Usage: $progname [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE Compile a source file into a libtool library object. This mode accepts the following additional options: -o OUTPUT-FILE set the output file name to OUTPUT-FILE -no-suppress do not suppress compiler output for multiple passes -prefer-pic try to build PIC objects only -prefer-non-pic try to build non-PIC objects only -shared do not build a '.o' file suitable for static linking -static only build a '.o' file suitable for static linking -Wc,FLAG -Xcompiler FLAG pass FLAG directly to the compiler COMPILE-COMMAND is a command to be used in creating a 'standard' object file from the given SOURCEFILE. The output file name is determined by removing the directory component from SOURCEFILE, then substituting the C source code suffix '.c' with the library object suffix, '.lo'." ;; execute) $ECHO \ "Usage: $progname [OPTION]... --mode=execute COMMAND [ARGS]... Automatically set library path, then run a program. This mode accepts the following additional options: -dlopen FILE add the directory containing FILE to the library path This mode sets the library path environment variable according to '-dlopen' flags. If any of the ARGS are libtool executable wrappers, then they are translated into their corresponding uninstalled binary, and any of their required library directories are added to the library path. Then, COMMAND is executed, with ARGS as arguments." ;; finish) $ECHO \ "Usage: $progname [OPTION]... --mode=finish [LIBDIR]... Complete the installation of libtool libraries. Each LIBDIR is a directory that contains libtool libraries. The commands that this mode executes may require superuser privileges. Use the '--dry-run' option if you just want to see what would be executed." ;; install) $ECHO \ "Usage: $progname [OPTION]... --mode=install INSTALL-COMMAND... Install executables or libraries. INSTALL-COMMAND is the installation command. The first component should be either the 'install' or 'cp' program. The following components of INSTALL-COMMAND are treated specially: -inst-prefix-dir PREFIX-DIR Use PREFIX-DIR as a staging area for installation The rest of the components are interpreted as arguments to that command (only BSD-compatible install options are recognized)." ;; link) $ECHO \ "Usage: $progname [OPTION]... --mode=link LINK-COMMAND... Link object files or libraries together to form another library, or to create an executable program. LINK-COMMAND is a command using the C compiler that you would use to create a program from several object files. The following components of LINK-COMMAND are treated specially: -all-static do not do any dynamic linking at all -avoid-version do not add a version suffix if possible -bindir BINDIR specify path to binaries directory (for systems where libraries must be found in the PATH setting at runtime) -dlopen FILE '-dlpreopen' FILE if it cannot be dlopened at runtime -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3) -export-symbols SYMFILE try to export only the symbols listed in SYMFILE -export-symbols-regex REGEX try to export only the symbols matching REGEX -LLIBDIR search LIBDIR for required installed libraries -lNAME OUTPUT-FILE requires the installed library libNAME -module build a library that can dlopened -no-fast-install disable the fast-install mode -no-install link a not-installable executable -no-undefined declare that a library does not refer to external symbols -o OUTPUT-FILE create OUTPUT-FILE from the specified objects -objectlist FILE use a list of object files found in FILE to specify objects -os2dllname NAME force a short DLL name on OS/2 (no effect on other OSes) -precious-files-regex REGEX don't remove output files matching REGEX -release RELEASE specify package release information -rpath LIBDIR the created library will eventually be installed in LIBDIR -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries -shared only do dynamic linking of libtool libraries -shrext SUFFIX override the standard shared library file extension -static do not do any dynamic linking of uninstalled libtool libraries -static-libtool-libs do not do any dynamic linking of libtool libraries -version-info CURRENT[:REVISION[:AGE]] specify library version info [each variable defaults to 0] -weak LIBNAME declare that the target provides the LIBNAME interface -Wc,FLAG -Xcompiler FLAG pass linker-specific FLAG directly to the compiler -Wa,FLAG -Xassembler FLAG pass linker-specific FLAG directly to the assembler -Wl,FLAG -Xlinker FLAG pass linker-specific FLAG directly to the linker -XCClinker FLAG pass link-specific FLAG to the compiler driver (CC) All other options (arguments beginning with '-') are ignored. Every other argument is treated as a filename. Files ending in '.la' are treated as uninstalled libtool libraries, other files are standard or library object files. If the OUTPUT-FILE ends in '.la', then a libtool library is created, only library objects ('.lo' files) may be specified, and '-rpath' is required, except when creating a convenience library. If OUTPUT-FILE ends in '.a' or '.lib', then a standard library is created using 'ar' and 'ranlib', or on Windows using 'lib'. If OUTPUT-FILE ends in '.lo' or '.$objext', then a reloadable object file is created, otherwise an executable program is created." ;; uninstall) $ECHO \ "Usage: $progname [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE... Remove libraries from an installation directory. RM is the name of the program to use to delete files associated with each FILE (typically '/bin/rm'). RM-OPTIONS are options (such as '-f') to be passed to RM. If FILE is a libtool library, all the files associated with it are deleted. Otherwise, only FILE itself is deleted using RM." ;; *) func_fatal_help "invalid operation mode '$opt_mode'" ;; esac echo $ECHO "Try '$progname --help' for more information about other modes." } # Now that we've collected a possible --mode arg, show help if necessary if $opt_help; then if test : = "$opt_help"; then func_mode_help else { func_help noexit for opt_mode in compile link execute install finish uninstall clean; do func_mode_help done } | $SED -n '1p; 2,$s/^Usage:/ or: /p' { func_help noexit for opt_mode in compile link execute install finish uninstall clean; do echo func_mode_help done } | $SED '1d /^When reporting/,/^Report/{ H d } $x /information about other modes/d /more detailed .*MODE/d s/^Usage:.*--mode=\([^ ]*\) .*/Description of \1 mode:/' fi exit $? fi # func_mode_execute arg... func_mode_execute () { $debug_cmd # The first argument is the command name. cmd=$nonopt test -z "$cmd" && \ func_fatal_help "you must specify a COMMAND" # Handle -dlopen flags immediately. for file in $opt_dlopen; do test -f "$file" \ || func_fatal_help "'$file' is not a file" dir= case $file in *.la) func_resolve_sysroot "$file" file=$func_resolve_sysroot_result # Check to see that this really is a libtool archive. func_lalib_unsafe_p "$file" \ || func_fatal_help "'$lib' is not a valid libtool archive" # Read the libtool library. dlname= library_names= func_source "$file" # Skip this library if it cannot be dlopened. if test -z "$dlname"; then # Warn if it was a shared library. test -n "$library_names" && \ func_warning "'$file' was not linked with '-export-dynamic'" continue fi func_dirname "$file" "" "." dir=$func_dirname_result if test -f "$dir/$objdir/$dlname"; then func_append dir "/$objdir" else if test ! -f "$dir/$dlname"; then func_fatal_error "cannot find '$dlname' in '$dir' or '$dir/$objdir'" fi fi ;; *.lo) # Just add the directory containing the .lo file. func_dirname "$file" "" "." dir=$func_dirname_result ;; *) func_warning "'-dlopen' is ignored for non-libtool libraries and objects" continue ;; esac # Get the absolute pathname. absdir=`cd "$dir" && pwd` test -n "$absdir" && dir=$absdir # Now add the directory to shlibpath_var. if eval "test -z \"\$$shlibpath_var\""; then eval "$shlibpath_var=\"\$dir\"" else eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\"" fi done # This variable tells wrapper scripts just to set shlibpath_var # rather than running their programs. libtool_execute_magic=$magic # Check if any of the arguments is a wrapper script. args= for file do case $file in -* | *.la | *.lo ) ;; *) # Do a test to see if this is really a libtool program. if func_ltwrapper_script_p "$file"; then func_source "$file" # Transform arg to wrapped name. file=$progdir/$program elif func_ltwrapper_executable_p "$file"; then func_ltwrapper_scriptname "$file" func_source "$func_ltwrapper_scriptname_result" # Transform arg to wrapped name. file=$progdir/$program fi ;; esac # Quote arguments (to preserve shell metacharacters). func_append_quoted args "$file" done if $opt_dry_run; then # Display what would be done. if test -n "$shlibpath_var"; then eval "\$ECHO \"\$shlibpath_var=\$$shlibpath_var\"" echo "export $shlibpath_var" fi $ECHO "$cmd$args" exit $EXIT_SUCCESS else if test -n "$shlibpath_var"; then # Export the shlibpath_var. eval "export $shlibpath_var" fi # Restore saved environment variables for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES do eval "if test \"\${save_$lt_var+set}\" = set; then $lt_var=\$save_$lt_var; export $lt_var else $lt_unset $lt_var fi" done # Now prepare to actually exec the command. exec_cmd=\$cmd$args fi } test execute = "$opt_mode" && func_mode_execute ${1+"$@"} # func_mode_finish arg... func_mode_finish () { $debug_cmd libs= libdirs= admincmds= for opt in "$nonopt" ${1+"$@"} do if test -d "$opt"; then func_append libdirs " $opt" elif test -f "$opt"; then if func_lalib_unsafe_p "$opt"; then func_append libs " $opt" else func_warning "'$opt' is not a valid libtool archive" fi else func_fatal_error "invalid argument '$opt'" fi done if test -n "$libs"; then if test -n "$lt_sysroot"; then sysroot_regex=`$ECHO "$lt_sysroot" | $SED "$sed_make_literal_regex"` sysroot_cmd="s/\([ ']\)$sysroot_regex/\1/g;" else sysroot_cmd= fi # Remove sysroot references if $opt_dry_run; then for lib in $libs; do echo "removing references to $lt_sysroot and '=' prefixes from $lib" done else tmpdir=`func_mktempdir` for lib in $libs; do $SED -e "$sysroot_cmd s/\([ ']-[LR]\)=/\1/g; s/\([ ']\)=/\1/g" $lib \ > $tmpdir/tmp-la mv -f $tmpdir/tmp-la $lib done ${RM}r "$tmpdir" fi fi if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then for libdir in $libdirs; do if test -n "$finish_cmds"; then # Do each command in the finish commands. func_execute_cmds "$finish_cmds" 'admincmds="$admincmds '"$cmd"'"' fi if test -n "$finish_eval"; then # Do the single finish_eval. eval cmds=\"$finish_eval\" $opt_dry_run || eval "$cmds" || func_append admincmds " $cmds" fi done fi # Exit here if they wanted silent mode. $opt_quiet && exit $EXIT_SUCCESS if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then echo "----------------------------------------------------------------------" echo "Libraries have been installed in:" for libdir in $libdirs; do $ECHO " $libdir" done echo echo "If you ever happen to want to link against installed libraries" echo "in a given directory, LIBDIR, you must either use libtool, and" echo "specify the full pathname of the library, or use the '-LLIBDIR'" echo "flag during linking and do at least one of the following:" if test -n "$shlibpath_var"; then echo " - add LIBDIR to the '$shlibpath_var' environment variable" echo " during execution" fi if test -n "$runpath_var"; then echo " - add LIBDIR to the '$runpath_var' environment variable" echo " during linking" fi if test -n "$hardcode_libdir_flag_spec"; then libdir=LIBDIR eval flag=\"$hardcode_libdir_flag_spec\" $ECHO " - use the '$flag' linker flag" fi if test -n "$admincmds"; then $ECHO " - have your system administrator run these commands:$admincmds" fi if test -f /etc/ld.so.conf; then echo " - have your system administrator add LIBDIR to '/etc/ld.so.conf'" fi echo echo "See any operating system documentation about shared libraries for" case $host in solaris2.[6789]|solaris2.1[0-9]) echo "more information, such as the ld(1), crle(1) and ld.so(8) manual" echo "pages." ;; *) echo "more information, such as the ld(1) and ld.so(8) manual pages." ;; esac echo "----------------------------------------------------------------------" fi exit $EXIT_SUCCESS } test finish = "$opt_mode" && func_mode_finish ${1+"$@"} # func_mode_install arg... func_mode_install () { $debug_cmd # There may be an optional sh(1) argument at the beginning of # install_prog (especially on Windows NT). if test "$SHELL" = "$nonopt" || test /bin/sh = "$nonopt" || # Allow the use of GNU shtool's install command. case $nonopt in *shtool*) :;; *) false;; esac then # Aesthetically quote it. func_quote_arg pretty "$nonopt" install_prog="$func_quote_arg_result " arg=$1 shift else install_prog= arg=$nonopt fi # The real first argument should be the name of the installation program. # Aesthetically quote it. func_quote_arg pretty "$arg" func_append install_prog "$func_quote_arg_result" install_shared_prog=$install_prog case " $install_prog " in *[\\\ /]cp\ *) install_cp=: ;; *) install_cp=false ;; esac # We need to accept at least all the BSD install flags. dest= files= opts= prev= install_type= isdir=false stripme= no_mode=: for arg do arg2= if test -n "$dest"; then func_append files " $dest" dest=$arg continue fi case $arg in -d) isdir=: ;; -f) if $install_cp; then :; else prev=$arg fi ;; -g | -m | -o) prev=$arg ;; -s) stripme=" -s" continue ;; -*) ;; *) # If the previous option needed an argument, then skip it. if test -n "$prev"; then if test X-m = "X$prev" && test -n "$install_override_mode"; then arg2=$install_override_mode no_mode=false fi prev= else dest=$arg continue fi ;; esac # Aesthetically quote the argument. func_quote_arg pretty "$arg" func_append install_prog " $func_quote_arg_result" if test -n "$arg2"; then func_quote_arg pretty "$arg2" fi func_append install_shared_prog " $func_quote_arg_result" done test -z "$install_prog" && \ func_fatal_help "you must specify an install program" test -n "$prev" && \ func_fatal_help "the '$prev' option requires an argument" if test -n "$install_override_mode" && $no_mode; then if $install_cp; then :; else func_quote_arg pretty "$install_override_mode" func_append install_shared_prog " -m $func_quote_arg_result" fi fi if test -z "$files"; then if test -z "$dest"; then func_fatal_help "no file or destination specified" else func_fatal_help "you must specify a destination" fi fi # Strip any trailing slash from the destination. func_stripname '' '/' "$dest" dest=$func_stripname_result # Check to see that the destination is a directory. test -d "$dest" && isdir=: if $isdir; then destdir=$dest destname= else func_dirname_and_basename "$dest" "" "." destdir=$func_dirname_result destname=$func_basename_result # Not a directory, so check to see that there is only one file specified. set dummy $files; shift test "$#" -gt 1 && \ func_fatal_help "'$dest' is not a directory" fi case $destdir in [\\/]* | [A-Za-z]:[\\/]*) ;; *) for file in $files; do case $file in *.lo) ;; *) func_fatal_help "'$destdir' must be an absolute directory name" ;; esac done ;; esac # This variable tells wrapper scripts just to set variables rather # than running their programs. libtool_install_magic=$magic staticlibs= future_libdirs= current_libdirs= for file in $files; do # Do each installation. case $file in *.$libext) # Do the static libraries later. func_append staticlibs " $file" ;; *.la) func_resolve_sysroot "$file" file=$func_resolve_sysroot_result # Check to see that this really is a libtool archive. func_lalib_unsafe_p "$file" \ || func_fatal_help "'$file' is not a valid libtool archive" library_names= old_library= relink_command= func_source "$file" # Add the libdir to current_libdirs if it is the destination. if test "X$destdir" = "X$libdir"; then case "$current_libdirs " in *" $libdir "*) ;; *) func_append current_libdirs " $libdir" ;; esac else # Note the libdir as a future libdir. case "$future_libdirs " in *" $libdir "*) ;; *) func_append future_libdirs " $libdir" ;; esac fi func_dirname "$file" "/" "" dir=$func_dirname_result func_append dir "$objdir" if test -n "$relink_command"; then # Determine the prefix the user has applied to our future dir. inst_prefix_dir=`$ECHO "$destdir" | $SED -e "s%$libdir\$%%"` # Don't allow the user to place us outside of our expected # location b/c this prevents finding dependent libraries that # are installed to the same prefix. # At present, this check doesn't affect windows .dll's that # are installed into $libdir/../bin (currently, that works fine) # but it's something to keep an eye on. test "$inst_prefix_dir" = "$destdir" && \ func_fatal_error "error: cannot install '$file' to a directory not ending in $libdir" if test -n "$inst_prefix_dir"; then # Stick the inst_prefix_dir data into the link command. relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"` else relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%%"` fi func_warning "relinking '$file'" func_show_eval "$relink_command" \ 'func_fatal_error "error: relink '\''$file'\'' with the above command before installing it"' fi # See the names of the shared library. set dummy $library_names; shift if test -n "$1"; then realname=$1 shift srcname=$realname test -n "$relink_command" && srcname=${realname}T # Install the shared library and build the symlinks. func_show_eval "$install_shared_prog $dir/$srcname $destdir/$realname" \ 'exit $?' tstripme=$stripme case $host_os in cygwin* | mingw* | pw32* | cegcc*) case $realname in *.dll.a) tstripme= ;; esac ;; os2*) case $realname in *_dll.a) tstripme= ;; esac ;; esac if test -n "$tstripme" && test -n "$striplib"; then func_show_eval "$striplib $destdir/$realname" 'exit $?' fi if test "$#" -gt 0; then # Delete the old symlinks, and create new ones. # Try 'ln -sf' first, because the 'ln' binary might depend on # the symlink we replace! Solaris /bin/ln does not understand -f, # so we also need to try rm && ln -s. for linkname do test "$linkname" != "$realname" \ && func_show_eval "(cd $destdir && { $LN_S -f $realname $linkname || { $RM $linkname && $LN_S $realname $linkname; }; })" done fi # Do each command in the postinstall commands. lib=$destdir/$realname func_execute_cmds "$postinstall_cmds" 'exit $?' fi # Install the pseudo-library for information purposes. func_basename "$file" name=$func_basename_result instname=$dir/${name}i func_show_eval "$install_prog $instname $destdir/$name" 'exit $?' # Maybe install the static library, too. test -n "$old_library" && func_append staticlibs " $dir/$old_library" ;; *.lo) # Install (i.e. copy) a libtool object. # Figure out destination file name, if it wasn't already specified. if test -n "$destname"; then destfile=$destdir/$destname else func_basename "$file" destfile=$func_basename_result destfile=$destdir/$destfile fi # Deduce the name of the destination old-style object file. case $destfile in *.lo) func_lo2o "$destfile" staticdest=$func_lo2o_result ;; *.$objext) staticdest=$destfile destfile= ;; *) func_fatal_help "cannot copy a libtool object to '$destfile'" ;; esac # Install the libtool object if requested. test -n "$destfile" && \ func_show_eval "$install_prog $file $destfile" 'exit $?' # Install the old object if enabled. if test yes = "$build_old_libs"; then # Deduce the name of the old-style object file. func_lo2o "$file" staticobj=$func_lo2o_result func_show_eval "$install_prog \$staticobj \$staticdest" 'exit $?' fi exit $EXIT_SUCCESS ;; *) # Figure out destination file name, if it wasn't already specified. if test -n "$destname"; then destfile=$destdir/$destname else func_basename "$file" destfile=$func_basename_result destfile=$destdir/$destfile fi # If the file is missing, and there is a .exe on the end, strip it # because it is most likely a libtool script we actually want to # install stripped_ext= case $file in *.exe) if test ! -f "$file"; then func_stripname '' '.exe' "$file" file=$func_stripname_result stripped_ext=.exe fi ;; esac # Do a test to see if this is really a libtool program. case $host in *cygwin* | *mingw*) if func_ltwrapper_executable_p "$file"; then func_ltwrapper_scriptname "$file" wrapper=$func_ltwrapper_scriptname_result else func_stripname '' '.exe' "$file" wrapper=$func_stripname_result fi ;; *) wrapper=$file ;; esac if func_ltwrapper_script_p "$wrapper"; then notinst_deplibs= relink_command= func_source "$wrapper" # Check the variables that should have been set. test -z "$generated_by_libtool_version" && \ func_fatal_error "invalid libtool wrapper script '$wrapper'" finalize=: for lib in $notinst_deplibs; do # Check to see that each library is installed. libdir= if test -f "$lib"; then func_source "$lib" fi libfile=$libdir/`$ECHO "$lib" | $SED 's%^.*/%%g'` if test -n "$libdir" && test ! -f "$libfile"; then func_warning "'$lib' has not been installed in '$libdir'" finalize=false fi done relink_command= func_source "$wrapper" outputname= if test no = "$fast_install" && test -n "$relink_command"; then $opt_dry_run || { if $finalize; then tmpdir=`func_mktempdir` func_basename "$file$stripped_ext" file=$func_basename_result outputname=$tmpdir/$file # Replace the output file specification. relink_command=`$ECHO "$relink_command" | $SED 's%@OUTPUT@%'"$outputname"'%g'` $opt_quiet || { func_quote_arg expand,pretty "$relink_command" eval "func_echo $func_quote_arg_result" } if eval "$relink_command"; then : else func_error "error: relink '$file' with the above command before installing it" $opt_dry_run || ${RM}r "$tmpdir" continue fi file=$outputname else func_warning "cannot relink '$file'" fi } else # Install the binary that we compiled earlier. file=`$ECHO "$file$stripped_ext" | $SED "s%\([^/]*\)$%$objdir/\1%"` fi fi # remove .exe since cygwin /usr/bin/install will append another # one anyway case $install_prog,$host in */usr/bin/install*,*cygwin*) case $file:$destfile in *.exe:*.exe) # this is ok ;; *.exe:*) destfile=$destfile.exe ;; *:*.exe) func_stripname '' '.exe' "$destfile" destfile=$func_stripname_result ;; esac ;; esac func_show_eval "$install_prog\$stripme \$file \$destfile" 'exit $?' $opt_dry_run || if test -n "$outputname"; then ${RM}r "$tmpdir" fi ;; esac done for file in $staticlibs; do func_basename "$file" name=$func_basename_result # Set up the ranlib parameters. oldlib=$destdir/$name func_to_tool_file "$oldlib" func_convert_file_msys_to_w32 tool_oldlib=$func_to_tool_file_result func_show_eval "$install_prog \$file \$oldlib" 'exit $?' if test -n "$stripme" && test -n "$old_striplib"; then func_show_eval "$old_striplib $tool_oldlib" 'exit $?' fi # Do each command in the postinstall commands. func_execute_cmds "$old_postinstall_cmds" 'exit $?' done test -n "$future_libdirs" && \ func_warning "remember to run '$progname --finish$future_libdirs'" if test -n "$current_libdirs"; then # Maybe just do a dry run. $opt_dry_run && current_libdirs=" -n$current_libdirs" exec_cmd='$SHELL "$progpath" $preserve_args --finish$current_libdirs' else exit $EXIT_SUCCESS fi } test install = "$opt_mode" && func_mode_install ${1+"$@"} # func_generate_dlsyms outputname originator pic_p # Extract symbols from dlprefiles and create ${outputname}S.o with # a dlpreopen symbol table. func_generate_dlsyms () { $debug_cmd my_outputname=$1 my_originator=$2 my_pic_p=${3-false} my_prefix=`$ECHO "$my_originator" | $SED 's%[^a-zA-Z0-9]%_%g'` my_dlsyms= if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then if test -n "$NM" && test -n "$global_symbol_pipe"; then my_dlsyms=${my_outputname}S.c else func_error "not configured to extract global symbols from dlpreopened files" fi fi if test -n "$my_dlsyms"; then case $my_dlsyms in "") ;; *.c) # Discover the nlist of each of the dlfiles. nlist=$output_objdir/$my_outputname.nm func_show_eval "$RM $nlist ${nlist}S ${nlist}T" # Parse the name list into a source file. func_verbose "creating $output_objdir/$my_dlsyms" $opt_dry_run || $ECHO > "$output_objdir/$my_dlsyms" "\ /* $my_dlsyms - symbol resolution table for '$my_outputname' dlsym emulation. */ /* Generated by $PROGRAM (GNU $PACKAGE) $VERSION */ #ifdef __cplusplus extern \"C\" { #endif #if defined __GNUC__ && (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 4)) || (__GNUC__ > 4)) #pragma GCC diagnostic ignored \"-Wstrict-prototypes\" #endif /* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ #if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE /* DATA imports from DLLs on WIN32 can't be const, because runtime relocations are performed -- see ld's documentation on pseudo-relocs. */ # define LT_DLSYM_CONST #elif defined __osf__ /* This system does not cope well with relocations in const data. */ # define LT_DLSYM_CONST #else # define LT_DLSYM_CONST const #endif #define STREQ(s1, s2) (strcmp ((s1), (s2)) == 0) /* External symbol declarations for the compiler. */\ " if test yes = "$dlself"; then func_verbose "generating symbol list for '$output'" $opt_dry_run || echo ': @PROGRAM@ ' > "$nlist" # Add our own program objects to the symbol list. progfiles=`$ECHO "$objs$old_deplibs" | $SP2NL | $SED "$lo2o" | $NL2SP` for progfile in $progfiles; do func_to_tool_file "$progfile" func_convert_file_msys_to_w32 func_verbose "extracting global C symbols from '$func_to_tool_file_result'" $opt_dry_run || eval "$NM $func_to_tool_file_result | $global_symbol_pipe >> '$nlist'" done if test -n "$exclude_expsyms"; then $opt_dry_run || { eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T' eval '$MV "$nlist"T "$nlist"' } fi if test -n "$export_symbols_regex"; then $opt_dry_run || { eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T' eval '$MV "$nlist"T "$nlist"' } fi # Prepare the list of exported symbols if test -z "$export_symbols"; then export_symbols=$output_objdir/$outputname.exp $opt_dry_run || { $RM $export_symbols eval "$SED -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"' case $host in *cygwin* | *mingw* | *cegcc* ) eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"' ;; esac } else $opt_dry_run || { eval "$SED -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"' eval '$GREP -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T' eval '$MV "$nlist"T "$nlist"' case $host in *cygwin* | *mingw* | *cegcc* ) eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' eval 'cat "$nlist" >> "$output_objdir/$outputname.def"' ;; esac } fi fi for dlprefile in $dlprefiles; do func_verbose "extracting global C symbols from '$dlprefile'" func_basename "$dlprefile" name=$func_basename_result case $host in *cygwin* | *mingw* | *cegcc* ) # if an import library, we need to obtain dlname if func_win32_import_lib_p "$dlprefile"; then func_tr_sh "$dlprefile" eval "curr_lafile=\$libfile_$func_tr_sh_result" dlprefile_dlbasename= if test -n "$curr_lafile" && func_lalib_p "$curr_lafile"; then # Use subshell, to avoid clobbering current variable values dlprefile_dlname=`source "$curr_lafile" && echo "$dlname"` if test -n "$dlprefile_dlname"; then func_basename "$dlprefile_dlname" dlprefile_dlbasename=$func_basename_result else # no lafile. user explicitly requested -dlpreopen . $sharedlib_from_linklib_cmd "$dlprefile" dlprefile_dlbasename=$sharedlib_from_linklib_result fi fi $opt_dry_run || { if test -n "$dlprefile_dlbasename"; then eval '$ECHO ": $dlprefile_dlbasename" >> "$nlist"' else func_warning "Could not compute DLL name from $name" eval '$ECHO ": $name " >> "$nlist"' fi func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe | $SED -e '/I __imp/d' -e 's/I __nm_/D /;s/_nm__//' >> '$nlist'" } else # not an import lib $opt_dry_run || { eval '$ECHO ": $name " >> "$nlist"' func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'" } fi ;; *) $opt_dry_run || { eval '$ECHO ": $name " >> "$nlist"' func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'" } ;; esac done $opt_dry_run || { # Make sure we have at least an empty file. test -f "$nlist" || : > "$nlist" if test -n "$exclude_expsyms"; then $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T $MV "$nlist"T "$nlist" fi # Try sorting and uniquifying the output. if $GREP -v "^: " < "$nlist" | if sort -k 3 /dev/null 2>&1; then sort -k 3 else sort +2 fi | uniq > "$nlist"S; then : else $GREP -v "^: " < "$nlist" > "$nlist"S fi if test -f "$nlist"S; then eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$my_dlsyms"' else echo '/* NONE */' >> "$output_objdir/$my_dlsyms" fi func_show_eval '$RM "${nlist}I"' if test -n "$global_symbol_to_import"; then eval "$global_symbol_to_import"' < "$nlist"S > "$nlist"I' fi echo >> "$output_objdir/$my_dlsyms" "\ /* The mapping between symbol names and symbols. */ typedef struct { const char *name; void *address; } lt_dlsymlist; extern LT_DLSYM_CONST lt_dlsymlist lt_${my_prefix}_LTX_preloaded_symbols[];\ " if test -s "$nlist"I; then echo >> "$output_objdir/$my_dlsyms" "\ static void lt_syminit(void) { LT_DLSYM_CONST lt_dlsymlist *symbol = lt_${my_prefix}_LTX_preloaded_symbols; for (; symbol->name; ++symbol) {" $SED 's/.*/ if (STREQ (symbol->name, \"&\")) symbol->address = (void *) \&&;/' < "$nlist"I >> "$output_objdir/$my_dlsyms" echo >> "$output_objdir/$my_dlsyms" "\ } }" fi echo >> "$output_objdir/$my_dlsyms" "\ LT_DLSYM_CONST lt_dlsymlist lt_${my_prefix}_LTX_preloaded_symbols[] = { {\"$my_originator\", (void *) 0}," if test -s "$nlist"I; then echo >> "$output_objdir/$my_dlsyms" "\ {\"@INIT@\", (void *) <_syminit}," fi case $need_lib_prefix in no) eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$my_dlsyms" ;; *) eval "$global_symbol_to_c_name_address_lib_prefix" < "$nlist" >> "$output_objdir/$my_dlsyms" ;; esac echo >> "$output_objdir/$my_dlsyms" "\ {0, (void *) 0} }; /* This works around a problem in FreeBSD linker */ #ifdef FREEBSD_WORKAROUND static const void *lt_preloaded_setup() { return lt_${my_prefix}_LTX_preloaded_symbols; } #endif #ifdef __cplusplus } #endif\ " } # !$opt_dry_run pic_flag_for_symtable= case "$compile_command " in *" -static "*) ;; *) case $host in # compiling the symbol table file with pic_flag works around # a FreeBSD bug that causes programs to crash when -lm is # linked before any other PIC object. But we must not use # pic_flag when linking with -static. The problem exists in # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1. *-*-freebsd2.*|*-*-freebsd3.0*|*-*-freebsdelf3.0*) pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND" ;; *-*-hpux*) pic_flag_for_symtable=" $pic_flag" ;; *) $my_pic_p && pic_flag_for_symtable=" $pic_flag" ;; esac ;; esac symtab_cflags= for arg in $LTCFLAGS; do case $arg in -pie | -fpie | -fPIE) ;; *) func_append symtab_cflags " $arg" ;; esac done # Now compile the dynamic symbol file. func_show_eval '(cd $output_objdir && $LTCC$symtab_cflags -c$no_builtin_flag$pic_flag_for_symtable "$my_dlsyms")' 'exit $?' # Clean up the generated files. func_show_eval '$RM "$output_objdir/$my_dlsyms" "$nlist" "${nlist}S" "${nlist}T" "${nlist}I"' # Transform the symbol file into the correct name. symfileobj=$output_objdir/${my_outputname}S.$objext case $host in *cygwin* | *mingw* | *cegcc* ) if test -f "$output_objdir/$my_outputname.def"; then compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` else compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"` finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"` fi ;; *) compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"` finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"` ;; esac ;; *) func_fatal_error "unknown suffix for '$my_dlsyms'" ;; esac else # We keep going just in case the user didn't refer to # lt_preloaded_symbols. The linker will fail if global_symbol_pipe # really was required. # Nullify the symbol file. compile_command=`$ECHO "$compile_command" | $SED "s% @SYMFILE@%%"` finalize_command=`$ECHO "$finalize_command" | $SED "s% @SYMFILE@%%"` fi } # func_cygming_gnu_implib_p ARG # This predicate returns with zero status (TRUE) if # ARG is a GNU/binutils-style import library. Returns # with nonzero status (FALSE) otherwise. func_cygming_gnu_implib_p () { $debug_cmd func_to_tool_file "$1" func_convert_file_msys_to_w32 func_cygming_gnu_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $EGREP ' (_head_[A-Za-z0-9_]+_[ad]l*|[A-Za-z0-9_]+_[ad]l*_iname)$'` test -n "$func_cygming_gnu_implib_tmp" } # func_cygming_ms_implib_p ARG # This predicate returns with zero status (TRUE) if # ARG is an MS-style import library. Returns # with nonzero status (FALSE) otherwise. func_cygming_ms_implib_p () { $debug_cmd func_to_tool_file "$1" func_convert_file_msys_to_w32 func_cygming_ms_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $GREP '_NULL_IMPORT_DESCRIPTOR'` test -n "$func_cygming_ms_implib_tmp" } # func_win32_libid arg # return the library type of file 'arg' # # Need a lot of goo to handle *both* DLLs and import libs # Has to be a shell function in order to 'eat' the argument # that is supplied when $file_magic_command is called. # Despite the name, also deal with 64 bit binaries. func_win32_libid () { $debug_cmd win32_libid_type=unknown win32_fileres=`file -L $1 2>/dev/null` case $win32_fileres in *ar\ archive\ import\ library*) # definitely import win32_libid_type="x86 archive import" ;; *ar\ archive*) # could be an import, or static # Keep the egrep pattern in sync with the one in _LT_CHECK_MAGIC_METHOD. if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null | $EGREP 'file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' >/dev/null; then case $nm_interface in "MS dumpbin") if func_cygming_ms_implib_p "$1" || func_cygming_gnu_implib_p "$1" then win32_nmres=import else win32_nmres= fi ;; *) func_to_tool_file "$1" func_convert_file_msys_to_w32 win32_nmres=`eval $NM -f posix -A \"$func_to_tool_file_result\" | $SED -n -e ' 1,100{ / I /{ s|.*|import| p q } }'` ;; esac case $win32_nmres in import*) win32_libid_type="x86 archive import";; *) win32_libid_type="x86 archive static";; esac fi ;; *DLL*) win32_libid_type="x86 DLL" ;; *executable*) # but shell scripts are "executable" too... case $win32_fileres in *MS\ Windows\ PE\ Intel*) win32_libid_type="x86 DLL" ;; esac ;; esac $ECHO "$win32_libid_type" } # func_cygming_dll_for_implib ARG # # Platform-specific function to extract the # name of the DLL associated with the specified # import library ARG. # Invoked by eval'ing the libtool variable # $sharedlib_from_linklib_cmd # Result is available in the variable # $sharedlib_from_linklib_result func_cygming_dll_for_implib () { $debug_cmd sharedlib_from_linklib_result=`$DLLTOOL --identify-strict --identify "$1"` } # func_cygming_dll_for_implib_fallback_core SECTION_NAME LIBNAMEs # # The is the core of a fallback implementation of a # platform-specific function to extract the name of the # DLL associated with the specified import library LIBNAME. # # SECTION_NAME is either .idata$6 or .idata$7, depending # on the platform and compiler that created the implib. # # Echos the name of the DLL associated with the # specified import library. func_cygming_dll_for_implib_fallback_core () { $debug_cmd match_literal=`$ECHO "$1" | $SED "$sed_make_literal_regex"` $OBJDUMP -s --section "$1" "$2" 2>/dev/null | $SED '/^Contents of section '"$match_literal"':/{ # Place marker at beginning of archive member dllname section s/.*/====MARK====/ p d } # These lines can sometimes be longer than 43 characters, but # are always uninteresting /:[ ]*file format pe[i]\{,1\}-/d /^In archive [^:]*:/d # Ensure marker is printed /^====MARK====/p # Remove all lines with less than 43 characters /^.\{43\}/!d # From remaining lines, remove first 43 characters s/^.\{43\}//' | $SED -n ' # Join marker and all lines until next marker into a single line /^====MARK====/ b para H $ b para b :para x s/\n//g # Remove the marker s/^====MARK====// # Remove trailing dots and whitespace s/[\. \t]*$// # Print /./p' | # we now have a list, one entry per line, of the stringified # contents of the appropriate section of all members of the # archive that possess that section. Heuristic: eliminate # all those that have a first or second character that is # a '.' (that is, objdump's representation of an unprintable # character.) This should work for all archives with less than # 0x302f exports -- but will fail for DLLs whose name actually # begins with a literal '.' or a single character followed by # a '.'. # # Of those that remain, print the first one. $SED -e '/^\./d;/^.\./d;q' } # func_cygming_dll_for_implib_fallback ARG # Platform-specific function to extract the # name of the DLL associated with the specified # import library ARG. # # This fallback implementation is for use when $DLLTOOL # does not support the --identify-strict option. # Invoked by eval'ing the libtool variable # $sharedlib_from_linklib_cmd # Result is available in the variable # $sharedlib_from_linklib_result func_cygming_dll_for_implib_fallback () { $debug_cmd if func_cygming_gnu_implib_p "$1"; then # binutils import library sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$7' "$1"` elif func_cygming_ms_implib_p "$1"; then # ms-generated import library sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$6' "$1"` else # unknown sharedlib_from_linklib_result= fi } # func_extract_an_archive dir oldlib func_extract_an_archive () { $debug_cmd f_ex_an_ar_dir=$1; shift f_ex_an_ar_oldlib=$1 if test yes = "$lock_old_archive_extraction"; then lockfile=$f_ex_an_ar_oldlib.lock until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do func_echo "Waiting for $lockfile to be removed" sleep 2 done fi func_show_eval "(cd \$f_ex_an_ar_dir && $AR x \"\$f_ex_an_ar_oldlib\")" \ 'stat=$?; rm -f "$lockfile"; exit $stat' if test yes = "$lock_old_archive_extraction"; then $opt_dry_run || rm -f "$lockfile" fi if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then : else func_fatal_error "object name conflicts in archive: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib" fi } # func_extract_archives gentop oldlib ... func_extract_archives () { $debug_cmd my_gentop=$1; shift my_oldlibs=${1+"$@"} my_oldobjs= my_xlib= my_xabs= my_xdir= for my_xlib in $my_oldlibs; do # Extract the objects. case $my_xlib in [\\/]* | [A-Za-z]:[\\/]*) my_xabs=$my_xlib ;; *) my_xabs=`pwd`"/$my_xlib" ;; esac func_basename "$my_xlib" my_xlib=$func_basename_result my_xlib_u=$my_xlib while :; do case " $extracted_archives " in *" $my_xlib_u "*) func_arith $extracted_serial + 1 extracted_serial=$func_arith_result my_xlib_u=lt$extracted_serial-$my_xlib ;; *) break ;; esac done extracted_archives="$extracted_archives $my_xlib_u" my_xdir=$my_gentop/$my_xlib_u func_mkdir_p "$my_xdir" case $host in *-darwin*) func_verbose "Extracting $my_xabs" # Do not bother doing anything if just a dry run $opt_dry_run || { darwin_orig_dir=`pwd` cd $my_xdir || exit $? darwin_archive=$my_xabs darwin_curdir=`pwd` func_basename "$darwin_archive" darwin_base_archive=$func_basename_result darwin_arches=`$LIPO -info "$darwin_archive" 2>/dev/null | $GREP Architectures 2>/dev/null || true` if test -n "$darwin_arches"; then darwin_arches=`$ECHO "$darwin_arches" | $SED -e 's/.*are://'` darwin_arch= func_verbose "$darwin_base_archive has multiple architectures $darwin_arches" for darwin_arch in $darwin_arches; do func_mkdir_p "unfat-$$/$darwin_base_archive-$darwin_arch" $LIPO -thin $darwin_arch -output "unfat-$$/$darwin_base_archive-$darwin_arch/$darwin_base_archive" "$darwin_archive" cd "unfat-$$/$darwin_base_archive-$darwin_arch" func_extract_an_archive "`pwd`" "$darwin_base_archive" cd "$darwin_curdir" $RM "unfat-$$/$darwin_base_archive-$darwin_arch/$darwin_base_archive" done # $darwin_arches ## Okay now we've a bunch of thin objects, gotta fatten them up :) darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print | $SED -e "$sed_basename" | sort -u` darwin_file= darwin_files= for darwin_file in $darwin_filelist; do darwin_files=`find unfat-$$ -name $darwin_file -print | sort | $NL2SP` $LIPO -create -output "$darwin_file" $darwin_files done # $darwin_filelist $RM -rf unfat-$$ cd "$darwin_orig_dir" else cd $darwin_orig_dir func_extract_an_archive "$my_xdir" "$my_xabs" fi # $darwin_arches } # !$opt_dry_run ;; *) func_extract_an_archive "$my_xdir" "$my_xabs" ;; esac my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | sort | $NL2SP` done func_extract_archives_result=$my_oldobjs } # func_emit_wrapper [arg=no] # # Emit a libtool wrapper script on stdout. # Don't directly open a file because we may want to # incorporate the script contents within a cygwin/mingw # wrapper executable. Must ONLY be called from within # func_mode_link because it depends on a number of variables # set therein. # # ARG is the value that the WRAPPER_SCRIPT_BELONGS_IN_OBJDIR # variable will take. If 'yes', then the emitted script # will assume that the directory where it is stored is # the $objdir directory. This is a cygwin/mingw-specific # behavior. func_emit_wrapper () { func_emit_wrapper_arg1=${1-no} $ECHO "\ #! $SHELL # $output - temporary wrapper script for $objdir/$outputname # Generated by $PROGRAM (GNU $PACKAGE) $VERSION # # The $output program cannot be directly executed until all the libtool # libraries that it depends on are installed. # # This wrapper script should never be moved out of the build directory. # If it is, it will not operate correctly. # Sed substitution that helps us do robust quoting. It backslashifies # metacharacters that are still active within double-quoted strings. sed_quote_subst='$sed_quote_subst' # Be Bourne compatible if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs word splitting on \${1+\"\$@\"}, which # is contrary to our usage. Disable this feature. alias -g '\${1+\"\$@\"}'='\"\$@\"' setopt NO_GLOB_SUBST else case \`(set -o) 2>/dev/null\` in *posix*) set -o posix;; esac fi BIN_SH=xpg4; export BIN_SH # for Tru64 DUALCASE=1; export DUALCASE # for MKS sh # The HP-UX ksh and POSIX shell print the target directory to stdout # if CDPATH is set. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH relink_command=\"$relink_command\" # This environment variable determines our operation mode. if test \"\$libtool_install_magic\" = \"$magic\"; then # install mode needs the following variables: generated_by_libtool_version='$macro_version' notinst_deplibs='$notinst_deplibs' else # When we are sourced in execute mode, \$file and \$ECHO are already set. if test \"\$libtool_execute_magic\" != \"$magic\"; then file=\"\$0\"" func_quote_arg pretty "$ECHO" qECHO=$func_quote_arg_result $ECHO "\ # A function that is used when there is no print builtin or printf. func_fallback_echo () { eval 'cat <<_LTECHO_EOF \$1 _LTECHO_EOF' } ECHO=$qECHO fi # Very basic option parsing. These options are (a) specific to # the libtool wrapper, (b) are identical between the wrapper # /script/ and the wrapper /executable/ that is used only on # windows platforms, and (c) all begin with the string "--lt-" # (application programs are unlikely to have options that match # this pattern). # # There are only two supported options: --lt-debug and # --lt-dump-script. There is, deliberately, no --lt-help. # # The first argument to this parsing function should be the # script's $0 value, followed by "$@". lt_option_debug= func_parse_lt_options () { lt_script_arg0=\$0 shift for lt_opt do case \"\$lt_opt\" in --lt-debug) lt_option_debug=1 ;; --lt-dump-script) lt_dump_D=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%/[^/]*$%%'\` test \"X\$lt_dump_D\" = \"X\$lt_script_arg0\" && lt_dump_D=. lt_dump_F=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%^.*/%%'\` cat \"\$lt_dump_D/\$lt_dump_F\" exit 0 ;; --lt-*) \$ECHO \"Unrecognized --lt- option: '\$lt_opt'\" 1>&2 exit 1 ;; esac done # Print the debug banner immediately: if test -n \"\$lt_option_debug\"; then echo \"$outputname:$output:\$LINENO: libtool wrapper (GNU $PACKAGE) $VERSION\" 1>&2 fi } # Used when --lt-debug. Prints its arguments to stdout # (redirection is the responsibility of the caller) func_lt_dump_args () { lt_dump_args_N=1; for lt_arg do \$ECHO \"$outputname:$output:\$LINENO: newargv[\$lt_dump_args_N]: \$lt_arg\" lt_dump_args_N=\`expr \$lt_dump_args_N + 1\` done } # Core function for launching the target application func_exec_program_core () { " case $host in # Backslashes separate directories on plain windows *-*-mingw | *-*-os2* | *-cegcc*) $ECHO "\ if test -n \"\$lt_option_debug\"; then \$ECHO \"$outputname:$output:\$LINENO: newargv[0]: \$progdir\\\\\$program\" 1>&2 func_lt_dump_args \${1+\"\$@\"} 1>&2 fi exec \"\$progdir\\\\\$program\" \${1+\"\$@\"} " ;; *) $ECHO "\ if test -n \"\$lt_option_debug\"; then \$ECHO \"$outputname:$output:\$LINENO: newargv[0]: \$progdir/\$program\" 1>&2 func_lt_dump_args \${1+\"\$@\"} 1>&2 fi exec \"\$progdir/\$program\" \${1+\"\$@\"} " ;; esac $ECHO "\ \$ECHO \"\$0: cannot exec \$program \$*\" 1>&2 exit 1 } # A function to encapsulate launching the target application # Strips options in the --lt-* namespace from \$@ and # launches target application with the remaining arguments. func_exec_program () { case \" \$* \" in *\\ --lt-*) for lt_wr_arg do case \$lt_wr_arg in --lt-*) ;; *) set x \"\$@\" \"\$lt_wr_arg\"; shift;; esac shift done ;; esac func_exec_program_core \${1+\"\$@\"} } # Parse options func_parse_lt_options \"\$0\" \${1+\"\$@\"} # Find the directory that this script lives in. thisdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*$%%'\` test \"x\$thisdir\" = \"x\$file\" && thisdir=. # Follow symbolic links until we get to the real thisdir. file=\`ls -ld \"\$file\" | $SED -n 's/.*-> //p'\` while test -n \"\$file\"; do destdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*\$%%'\` # If there was a directory component, then change thisdir. if test \"x\$destdir\" != \"x\$file\"; then case \"\$destdir\" in [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;; *) thisdir=\"\$thisdir/\$destdir\" ;; esac fi file=\`\$ECHO \"\$file\" | $SED 's%^.*/%%'\` file=\`ls -ld \"\$thisdir/\$file\" | $SED -n 's/.*-> //p'\` done # Usually 'no', except on cygwin/mingw when embedded into # the cwrapper. WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=$func_emit_wrapper_arg1 if test \"\$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR\" = \"yes\"; then # special case for '.' if test \"\$thisdir\" = \".\"; then thisdir=\`pwd\` fi # remove .libs from thisdir case \"\$thisdir\" in *[\\\\/]$objdir ) thisdir=\`\$ECHO \"\$thisdir\" | $SED 's%[\\\\/][^\\\\/]*$%%'\` ;; $objdir ) thisdir=. ;; esac fi # Try to get the absolute directory name. absdir=\`cd \"\$thisdir\" && pwd\` test -n \"\$absdir\" && thisdir=\"\$absdir\" " if test yes = "$fast_install"; then $ECHO "\ program=lt-'$outputname'$exeext progdir=\"\$thisdir/$objdir\" if test ! -f \"\$progdir/\$program\" || { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | $SED 1q\`; \\ test \"X\$file\" != \"X\$progdir/\$program\"; }; then file=\"\$\$-\$program\" if test ! -d \"\$progdir\"; then $MKDIR \"\$progdir\" else $RM \"\$progdir/\$file\" fi" $ECHO "\ # relink executable if necessary if test -n \"\$relink_command\"; then if relink_command_output=\`eval \$relink_command 2>&1\`; then : else \$ECHO \"\$relink_command_output\" >&2 $RM \"\$progdir/\$file\" exit 1 fi fi $MV \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null || { $RM \"\$progdir/\$program\"; $MV \"\$progdir/\$file\" \"\$progdir/\$program\"; } $RM \"\$progdir/\$file\" fi" else $ECHO "\ program='$outputname' progdir=\"\$thisdir/$objdir\" " fi $ECHO "\ if test -f \"\$progdir/\$program\"; then" # fixup the dll searchpath if we need to. # # Fix the DLL searchpath if we need to. Do this before prepending # to shlibpath, because on Windows, both are PATH and uninstalled # libraries must come first. if test -n "$dllsearchpath"; then $ECHO "\ # Add the dll search path components to the executable PATH PATH=$dllsearchpath:\$PATH " fi # Export our shlibpath_var if we have one. if test yes = "$shlibpath_overrides_runpath" && test -n "$shlibpath_var" && test -n "$temp_rpath"; then $ECHO "\ # Add our own library path to $shlibpath_var $shlibpath_var=\"$temp_rpath\$$shlibpath_var\" # Some systems cannot cope with colon-terminated $shlibpath_var # The second colon is a workaround for a bug in BeOS R4 sed $shlibpath_var=\`\$ECHO \"\$$shlibpath_var\" | $SED 's/::*\$//'\` export $shlibpath_var " fi $ECHO "\ if test \"\$libtool_execute_magic\" != \"$magic\"; then # Run the actual program with our arguments. func_exec_program \${1+\"\$@\"} fi else # The program doesn't exist. \$ECHO \"\$0: error: '\$progdir/\$program' does not exist\" 1>&2 \$ECHO \"This script is just a wrapper for \$program.\" 1>&2 \$ECHO \"See the $PACKAGE documentation for more information.\" 1>&2 exit 1 fi fi\ " } # func_emit_cwrapperexe_src # emit the source code for a wrapper executable on stdout # Must ONLY be called from within func_mode_link because # it depends on a number of variable set therein. func_emit_cwrapperexe_src () { cat < #include #ifdef _MSC_VER # include # include # include #else # include # include # ifdef __CYGWIN__ # include # endif #endif #include #include #include #include #include #include #include #include #define STREQ(s1, s2) (strcmp ((s1), (s2)) == 0) /* declarations of non-ANSI functions */ #if defined __MINGW32__ # ifdef __STRICT_ANSI__ int _putenv (const char *); # endif #elif defined __CYGWIN__ # ifdef __STRICT_ANSI__ char *realpath (const char *, char *); int putenv (char *); int setenv (const char *, const char *, int); # endif /* #elif defined other_platform || defined ... */ #endif /* portability defines, excluding path handling macros */ #if defined _MSC_VER # define setmode _setmode # define stat _stat # define chmod _chmod # define getcwd _getcwd # define putenv _putenv # define S_IXUSR _S_IEXEC #elif defined __MINGW32__ # define setmode _setmode # define stat _stat # define chmod _chmod # define getcwd _getcwd # define putenv _putenv #elif defined __CYGWIN__ # define HAVE_SETENV # define FOPEN_WB "wb" /* #elif defined other platforms ... */ #endif #if defined PATH_MAX # define LT_PATHMAX PATH_MAX #elif defined MAXPATHLEN # define LT_PATHMAX MAXPATHLEN #else # define LT_PATHMAX 1024 #endif #ifndef S_IXOTH # define S_IXOTH 0 #endif #ifndef S_IXGRP # define S_IXGRP 0 #endif /* path handling portability macros */ #ifndef DIR_SEPARATOR # define DIR_SEPARATOR '/' # define PATH_SEPARATOR ':' #endif #if defined _WIN32 || defined __MSDOS__ || defined __DJGPP__ || \ defined __OS2__ # define HAVE_DOS_BASED_FILE_SYSTEM # define FOPEN_WB "wb" # ifndef DIR_SEPARATOR_2 # define DIR_SEPARATOR_2 '\\' # endif # ifndef PATH_SEPARATOR_2 # define PATH_SEPARATOR_2 ';' # endif #endif #ifndef DIR_SEPARATOR_2 # define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR) #else /* DIR_SEPARATOR_2 */ # define IS_DIR_SEPARATOR(ch) \ (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2)) #endif /* DIR_SEPARATOR_2 */ #ifndef PATH_SEPARATOR_2 # define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR) #else /* PATH_SEPARATOR_2 */ # define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR_2) #endif /* PATH_SEPARATOR_2 */ #ifndef FOPEN_WB # define FOPEN_WB "w" #endif #ifndef _O_BINARY # define _O_BINARY 0 #endif #define XMALLOC(type, num) ((type *) xmalloc ((num) * sizeof(type))) #define XFREE(stale) do { \ if (stale) { free (stale); stale = 0; } \ } while (0) #if defined LT_DEBUGWRAPPER static int lt_debug = 1; #else static int lt_debug = 0; #endif const char *program_name = "libtool-wrapper"; /* in case xstrdup fails */ void *xmalloc (size_t num); char *xstrdup (const char *string); const char *base_name (const char *name); char *find_executable (const char *wrapper); char *chase_symlinks (const char *pathspec); int make_executable (const char *path); int check_executable (const char *path); char *strendzap (char *str, const char *pat); void lt_debugprintf (const char *file, int line, const char *fmt, ...); void lt_fatal (const char *file, int line, const char *message, ...); static const char *nonnull (const char *s); static const char *nonempty (const char *s); void lt_setenv (const char *name, const char *value); char *lt_extend_str (const char *orig_value, const char *add, int to_end); void lt_update_exe_path (const char *name, const char *value); void lt_update_lib_path (const char *name, const char *value); char **prepare_spawn (char **argv); void lt_dump_script (FILE *f); EOF cat <= 0) && (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))) return 1; else return 0; } int make_executable (const char *path) { int rval = 0; struct stat st; lt_debugprintf (__FILE__, __LINE__, "(make_executable): %s\n", nonempty (path)); if ((!path) || (!*path)) return 0; if (stat (path, &st) >= 0) { rval = chmod (path, st.st_mode | S_IXOTH | S_IXGRP | S_IXUSR); } return rval; } /* Searches for the full path of the wrapper. Returns newly allocated full path name if found, NULL otherwise Does not chase symlinks, even on platforms that support them. */ char * find_executable (const char *wrapper) { int has_slash = 0; const char *p; const char *p_next; /* static buffer for getcwd */ char tmp[LT_PATHMAX + 1]; size_t tmp_len; char *concat_name; lt_debugprintf (__FILE__, __LINE__, "(find_executable): %s\n", nonempty (wrapper)); if ((wrapper == NULL) || (*wrapper == '\0')) return NULL; /* Absolute path? */ #if defined HAVE_DOS_BASED_FILE_SYSTEM if (isalpha ((unsigned char) wrapper[0]) && wrapper[1] == ':') { concat_name = xstrdup (wrapper); if (check_executable (concat_name)) return concat_name; XFREE (concat_name); } else { #endif if (IS_DIR_SEPARATOR (wrapper[0])) { concat_name = xstrdup (wrapper); if (check_executable (concat_name)) return concat_name; XFREE (concat_name); } #if defined HAVE_DOS_BASED_FILE_SYSTEM } #endif for (p = wrapper; *p; p++) if (*p == '/') { has_slash = 1; break; } if (!has_slash) { /* no slashes; search PATH */ const char *path = getenv ("PATH"); if (path != NULL) { for (p = path; *p; p = p_next) { const char *q; size_t p_len; for (q = p; *q; q++) if (IS_PATH_SEPARATOR (*q)) break; p_len = (size_t) (q - p); p_next = (*q == '\0' ? q : q + 1); if (p_len == 0) { /* empty path: current directory */ if (getcwd (tmp, LT_PATHMAX) == NULL) lt_fatal (__FILE__, __LINE__, "getcwd failed: %s", nonnull (strerror (errno))); tmp_len = strlen (tmp); concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); memcpy (concat_name, tmp, tmp_len); concat_name[tmp_len] = '/'; strcpy (concat_name + tmp_len + 1, wrapper); } else { concat_name = XMALLOC (char, p_len + 1 + strlen (wrapper) + 1); memcpy (concat_name, p, p_len); concat_name[p_len] = '/'; strcpy (concat_name + p_len + 1, wrapper); } if (check_executable (concat_name)) return concat_name; XFREE (concat_name); } } /* not found in PATH; assume curdir */ } /* Relative path | not found in path: prepend cwd */ if (getcwd (tmp, LT_PATHMAX) == NULL) lt_fatal (__FILE__, __LINE__, "getcwd failed: %s", nonnull (strerror (errno))); tmp_len = strlen (tmp); concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); memcpy (concat_name, tmp, tmp_len); concat_name[tmp_len] = '/'; strcpy (concat_name + tmp_len + 1, wrapper); if (check_executable (concat_name)) return concat_name; XFREE (concat_name); return NULL; } char * chase_symlinks (const char *pathspec) { #ifndef S_ISLNK return xstrdup (pathspec); #else char buf[LT_PATHMAX]; struct stat s; char *tmp_pathspec = xstrdup (pathspec); char *p; int has_symlinks = 0; while (strlen (tmp_pathspec) && !has_symlinks) { lt_debugprintf (__FILE__, __LINE__, "checking path component for symlinks: %s\n", tmp_pathspec); if (lstat (tmp_pathspec, &s) == 0) { if (S_ISLNK (s.st_mode) != 0) { has_symlinks = 1; break; } /* search backwards for last DIR_SEPARATOR */ p = tmp_pathspec + strlen (tmp_pathspec) - 1; while ((p > tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) p--; if ((p == tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) { /* no more DIR_SEPARATORS left */ break; } *p = '\0'; } else { lt_fatal (__FILE__, __LINE__, "error accessing file \"%s\": %s", tmp_pathspec, nonnull (strerror (errno))); } } XFREE (tmp_pathspec); if (!has_symlinks) { return xstrdup (pathspec); } tmp_pathspec = realpath (pathspec, buf); if (tmp_pathspec == 0) { lt_fatal (__FILE__, __LINE__, "could not follow symlinks for %s", pathspec); } return xstrdup (tmp_pathspec); #endif } char * strendzap (char *str, const char *pat) { size_t len, patlen; assert (str != NULL); assert (pat != NULL); len = strlen (str); patlen = strlen (pat); if (patlen <= len) { str += len - patlen; if (STREQ (str, pat)) *str = '\0'; } return str; } void lt_debugprintf (const char *file, int line, const char *fmt, ...) { va_list args; if (lt_debug) { (void) fprintf (stderr, "%s:%s:%d: ", program_name, file, line); va_start (args, fmt); (void) vfprintf (stderr, fmt, args); va_end (args); } } static void lt_error_core (int exit_status, const char *file, int line, const char *mode, const char *message, va_list ap) { fprintf (stderr, "%s:%s:%d: %s: ", program_name, file, line, mode); vfprintf (stderr, message, ap); fprintf (stderr, ".\n"); if (exit_status >= 0) exit (exit_status); } void lt_fatal (const char *file, int line, const char *message, ...) { va_list ap; va_start (ap, message); lt_error_core (EXIT_FAILURE, file, line, "FATAL", message, ap); va_end (ap); } static const char * nonnull (const char *s) { return s ? s : "(null)"; } static const char * nonempty (const char *s) { return (s && !*s) ? "(empty)" : nonnull (s); } void lt_setenv (const char *name, const char *value) { lt_debugprintf (__FILE__, __LINE__, "(lt_setenv) setting '%s' to '%s'\n", nonnull (name), nonnull (value)); { #ifdef HAVE_SETENV /* always make a copy, for consistency with !HAVE_SETENV */ char *str = xstrdup (value); setenv (name, str, 1); #else size_t len = strlen (name) + 1 + strlen (value) + 1; char *str = XMALLOC (char, len); sprintf (str, "%s=%s", name, value); if (putenv (str) != EXIT_SUCCESS) { XFREE (str); } #endif } } char * lt_extend_str (const char *orig_value, const char *add, int to_end) { char *new_value; if (orig_value && *orig_value) { size_t orig_value_len = strlen (orig_value); size_t add_len = strlen (add); new_value = XMALLOC (char, add_len + orig_value_len + 1); if (to_end) { strcpy (new_value, orig_value); strcpy (new_value + orig_value_len, add); } else { strcpy (new_value, add); strcpy (new_value + add_len, orig_value); } } else { new_value = xstrdup (add); } return new_value; } void lt_update_exe_path (const char *name, const char *value) { lt_debugprintf (__FILE__, __LINE__, "(lt_update_exe_path) modifying '%s' by prepending '%s'\n", nonnull (name), nonnull (value)); if (name && *name && value && *value) { char *new_value = lt_extend_str (getenv (name), value, 0); /* some systems can't cope with a ':'-terminated path #' */ size_t len = strlen (new_value); while ((len > 0) && IS_PATH_SEPARATOR (new_value[len-1])) { new_value[--len] = '\0'; } lt_setenv (name, new_value); XFREE (new_value); } } void lt_update_lib_path (const char *name, const char *value) { lt_debugprintf (__FILE__, __LINE__, "(lt_update_lib_path) modifying '%s' by prepending '%s'\n", nonnull (name), nonnull (value)); if (name && *name && value && *value) { char *new_value = lt_extend_str (getenv (name), value, 0); lt_setenv (name, new_value); XFREE (new_value); } } EOF case $host_os in mingw*) cat <<"EOF" /* Prepares an argument vector before calling spawn(). Note that spawn() does not by itself call the command interpreter (getenv ("COMSPEC") != NULL ? getenv ("COMSPEC") : ({ OSVERSIONINFO v; v.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); GetVersionEx(&v); v.dwPlatformId == VER_PLATFORM_WIN32_NT; }) ? "cmd.exe" : "command.com"). Instead it simply concatenates the arguments, separated by ' ', and calls CreateProcess(). We must quote the arguments since Win32 CreateProcess() interprets characters like ' ', '\t', '\\', '"' (but not '<' and '>') in a special way: - Space and tab are interpreted as delimiters. They are not treated as delimiters if they are surrounded by double quotes: "...". - Unescaped double quotes are removed from the input. Their only effect is that within double quotes, space and tab are treated like normal characters. - Backslashes not followed by double quotes are not special. - But 2*n+1 backslashes followed by a double quote become n backslashes followed by a double quote (n >= 0): \" -> " \\\" -> \" \\\\\" -> \\" */ #define SHELL_SPECIAL_CHARS "\"\\ \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037" #define SHELL_SPACE_CHARS " \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037" char ** prepare_spawn (char **argv) { size_t argc; char **new_argv; size_t i; /* Count number of arguments. */ for (argc = 0; argv[argc] != NULL; argc++) ; /* Allocate new argument vector. */ new_argv = XMALLOC (char *, argc + 1); /* Put quoted arguments into the new argument vector. */ for (i = 0; i < argc; i++) { const char *string = argv[i]; if (string[0] == '\0') new_argv[i] = xstrdup ("\"\""); else if (strpbrk (string, SHELL_SPECIAL_CHARS) != NULL) { int quote_around = (strpbrk (string, SHELL_SPACE_CHARS) != NULL); size_t length; unsigned int backslashes; const char *s; char *quoted_string; char *p; length = 0; backslashes = 0; if (quote_around) length++; for (s = string; *s != '\0'; s++) { char c = *s; if (c == '"') length += backslashes + 1; length++; if (c == '\\') backslashes++; else backslashes = 0; } if (quote_around) length += backslashes + 1; quoted_string = XMALLOC (char, length + 1); p = quoted_string; backslashes = 0; if (quote_around) *p++ = '"'; for (s = string; *s != '\0'; s++) { char c = *s; if (c == '"') { unsigned int j; for (j = backslashes + 1; j > 0; j--) *p++ = '\\'; } *p++ = c; if (c == '\\') backslashes++; else backslashes = 0; } if (quote_around) { unsigned int j; for (j = backslashes; j > 0; j--) *p++ = '\\'; *p++ = '"'; } *p = '\0'; new_argv[i] = quoted_string; } else new_argv[i] = (char *) string; } new_argv[argc] = NULL; return new_argv; } EOF ;; esac cat <<"EOF" void lt_dump_script (FILE* f) { EOF func_emit_wrapper yes | $SED -n -e ' s/^\(.\{79\}\)\(..*\)/\1\ \2/ h s/\([\\"]\)/\\\1/g s/$/\\n/ s/\([^\n]*\).*/ fputs ("\1", f);/p g D' cat <<"EOF" } EOF } # end: func_emit_cwrapperexe_src # func_win32_import_lib_p ARG # True if ARG is an import lib, as indicated by $file_magic_cmd func_win32_import_lib_p () { $debug_cmd case `eval $file_magic_cmd \"\$1\" 2>/dev/null | $SED -e 10q` in *import*) : ;; *) false ;; esac } # func_suncc_cstd_abi # !!ONLY CALL THIS FOR SUN CC AFTER $compile_command IS FULLY EXPANDED!! # Several compiler flags select an ABI that is incompatible with the # Cstd library. Avoid specifying it if any are in CXXFLAGS. func_suncc_cstd_abi () { $debug_cmd case " $compile_command " in *" -compat=g "*|*\ -std=c++[0-9][0-9]\ *|*" -library=stdcxx4 "*|*" -library=stlport4 "*) suncc_use_cstd_abi=no ;; *) suncc_use_cstd_abi=yes ;; esac } # func_mode_link arg... func_mode_link () { $debug_cmd case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) # It is impossible to link a dll without this setting, and # we shouldn't force the makefile maintainer to figure out # what system we are compiling for in order to pass an extra # flag for every libtool invocation. # allow_undefined=no # FIXME: Unfortunately, there are problems with the above when trying # to make a dll that has undefined symbols, in which case not # even a static library is built. For now, we need to specify # -no-undefined on the libtool link line when we can be certain # that all symbols are satisfied, otherwise we get a static library. allow_undefined=yes ;; *) allow_undefined=yes ;; esac libtool_args=$nonopt base_compile="$nonopt $@" compile_command=$nonopt finalize_command=$nonopt compile_rpath= finalize_rpath= compile_shlibpath= finalize_shlibpath= convenience= old_convenience= deplibs= old_deplibs= compiler_flags= linker_flags= dllsearchpath= lib_search_path=`pwd` inst_prefix_dir= new_inherited_linker_flags= avoid_version=no bindir= dlfiles= dlprefiles= dlself=no export_dynamic=no export_symbols= export_symbols_regex= generated= libobjs= ltlibs= module=no no_install=no objs= os2dllname= non_pic_objects= precious_files_regex= prefer_static_libs=no preload=false prev= prevarg= release= rpath= xrpath= perm_rpath= temp_rpath= thread_safe=no vinfo= vinfo_number=no weak_libs= single_module=$wl-single_module func_infer_tag $base_compile # We need to know -static, to get the right output filenames. for arg do case $arg in -shared) test yes != "$build_libtool_libs" \ && func_fatal_configuration "cannot build a shared library" build_old_libs=no break ;; -all-static | -static | -static-libtool-libs) case $arg in -all-static) if test yes = "$build_libtool_libs" && test -z "$link_static_flag"; then func_warning "complete static linking is impossible in this configuration" fi if test -n "$link_static_flag"; then dlopen_self=$dlopen_self_static fi prefer_static_libs=yes ;; -static) if test -z "$pic_flag" && test -n "$link_static_flag"; then dlopen_self=$dlopen_self_static fi prefer_static_libs=built ;; -static-libtool-libs) if test -z "$pic_flag" && test -n "$link_static_flag"; then dlopen_self=$dlopen_self_static fi prefer_static_libs=yes ;; esac build_libtool_libs=no build_old_libs=yes break ;; esac done # See if our shared archives depend on static archives. test -n "$old_archive_from_new_cmds" && build_old_libs=yes # Go through the arguments, transforming them on the way. while test "$#" -gt 0; do arg=$1 shift func_quote_arg pretty,unquoted "$arg" qarg=$func_quote_arg_unquoted_result func_append libtool_args " $func_quote_arg_result" # If the previous option needs an argument, assign it. if test -n "$prev"; then case $prev in output) func_append compile_command " @OUTPUT@" func_append finalize_command " @OUTPUT@" ;; esac case $prev in bindir) bindir=$arg prev= continue ;; dlfiles|dlprefiles) $preload || { # Add the symbol object into the linking commands. func_append compile_command " @SYMFILE@" func_append finalize_command " @SYMFILE@" preload=: } case $arg in *.la | *.lo) ;; # We handle these cases below. force) if test no = "$dlself"; then dlself=needless export_dynamic=yes fi prev= continue ;; self) if test dlprefiles = "$prev"; then dlself=yes elif test dlfiles = "$prev" && test yes != "$dlopen_self"; then dlself=yes else dlself=needless export_dynamic=yes fi prev= continue ;; *) if test dlfiles = "$prev"; then func_append dlfiles " $arg" else func_append dlprefiles " $arg" fi prev= continue ;; esac ;; expsyms) export_symbols=$arg test -f "$arg" \ || func_fatal_error "symbol file '$arg' does not exist" prev= continue ;; expsyms_regex) export_symbols_regex=$arg prev= continue ;; framework) case $host in *-*-darwin*) case "$deplibs " in *" $qarg.ltframework "*) ;; *) func_append deplibs " $qarg.ltframework" # this is fixed later ;; esac ;; esac prev= continue ;; inst_prefix) inst_prefix_dir=$arg prev= continue ;; mllvm) # Clang does not use LLVM to link, so we can simply discard any # '-mllvm $arg' options when doing the link step. prev= continue ;; objectlist) if test -f "$arg"; then save_arg=$arg moreargs= for fil in `cat "$save_arg"` do # func_append moreargs " $fil" arg=$fil # A libtool-controlled object. # Check to see that this really is a libtool object. if func_lalib_unsafe_p "$arg"; then pic_object= non_pic_object= # Read the .lo file func_source "$arg" if test -z "$pic_object" || test -z "$non_pic_object" || test none = "$pic_object" && test none = "$non_pic_object"; then func_fatal_error "cannot find name of object for '$arg'" fi # Extract subdirectory from the argument. func_dirname "$arg" "/" "" xdir=$func_dirname_result if test none != "$pic_object"; then # Prepend the subdirectory the object is found in. pic_object=$xdir$pic_object if test dlfiles = "$prev"; then if test yes = "$build_libtool_libs" && test yes = "$dlopen_support"; then func_append dlfiles " $pic_object" prev= continue else # If libtool objects are unsupported, then we need to preload. prev=dlprefiles fi fi # CHECK ME: I think I busted this. -Ossama if test dlprefiles = "$prev"; then # Preload the old-style object. func_append dlprefiles " $pic_object" prev= fi # A PIC object. func_append libobjs " $pic_object" arg=$pic_object fi # Non-PIC object. if test none != "$non_pic_object"; then # Prepend the subdirectory the object is found in. non_pic_object=$xdir$non_pic_object # A standard non-PIC object func_append non_pic_objects " $non_pic_object" if test -z "$pic_object" || test none = "$pic_object"; then arg=$non_pic_object fi else # If the PIC object exists, use it instead. # $xdir was prepended to $pic_object above. non_pic_object=$pic_object func_append non_pic_objects " $non_pic_object" fi else # Only an error if not doing a dry-run. if $opt_dry_run; then # Extract subdirectory from the argument. func_dirname "$arg" "/" "" xdir=$func_dirname_result func_lo2o "$arg" pic_object=$xdir$objdir/$func_lo2o_result non_pic_object=$xdir$func_lo2o_result func_append libobjs " $pic_object" func_append non_pic_objects " $non_pic_object" else func_fatal_error "'$arg' is not a valid libtool object" fi fi done else func_fatal_error "link input file '$arg' does not exist" fi arg=$save_arg prev= continue ;; os2dllname) os2dllname=$arg prev= continue ;; precious_regex) precious_files_regex=$arg prev= continue ;; release) release=-$arg prev= continue ;; rpath | xrpath) # We need an absolute path. case $arg in [\\/]* | [A-Za-z]:[\\/]*) ;; *) func_fatal_error "only absolute run-paths are allowed" ;; esac if test rpath = "$prev"; then case "$rpath " in *" $arg "*) ;; *) func_append rpath " $arg" ;; esac else case "$xrpath " in *" $arg "*) ;; *) func_append xrpath " $arg" ;; esac fi prev= continue ;; shrext) shrext_cmds=$arg prev= continue ;; weak) func_append weak_libs " $arg" prev= continue ;; xassembler) func_append compiler_flags " -Xassembler $qarg" prev= func_append compile_command " -Xassembler $qarg" func_append finalize_command " -Xassembler $qarg" continue ;; xcclinker) func_append linker_flags " $qarg" func_append compiler_flags " $qarg" prev= func_append compile_command " $qarg" func_append finalize_command " $qarg" continue ;; xcompiler) func_append compiler_flags " $qarg" prev= func_append compile_command " $qarg" func_append finalize_command " $qarg" continue ;; xlinker) func_append linker_flags " $qarg" func_append compiler_flags " $wl$qarg" prev= func_append compile_command " $wl$qarg" func_append finalize_command " $wl$qarg" continue ;; *) eval "$prev=\"\$arg\"" prev= continue ;; esac fi # test -n "$prev" prevarg=$arg case $arg in -all-static) if test -n "$link_static_flag"; then # See comment for -static flag below, for more details. func_append compile_command " $link_static_flag" func_append finalize_command " $link_static_flag" fi continue ;; -allow-undefined) # FIXME: remove this flag sometime in the future. func_fatal_error "'-allow-undefined' must not be used because it is the default" ;; -avoid-version) avoid_version=yes continue ;; -bindir) prev=bindir continue ;; -dlopen) prev=dlfiles continue ;; -dlpreopen) prev=dlprefiles continue ;; -export-dynamic) export_dynamic=yes continue ;; -export-symbols | -export-symbols-regex) if test -n "$export_symbols" || test -n "$export_symbols_regex"; then func_fatal_error "more than one -exported-symbols argument is not allowed" fi if test X-export-symbols = "X$arg"; then prev=expsyms else prev=expsyms_regex fi continue ;; -framework) prev=framework continue ;; -inst-prefix-dir) prev=inst_prefix continue ;; # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:* # so, if we see these flags be careful not to treat them like -L -L[A-Z][A-Z]*:*) case $with_gcc/$host in no/*-*-irix* | /*-*-irix*) func_append compile_command " $arg" func_append finalize_command " $arg" ;; esac continue ;; -L*) func_stripname "-L" '' "$arg" if test -z "$func_stripname_result"; then if test "$#" -gt 0; then func_fatal_error "require no space between '-L' and '$1'" else func_fatal_error "need path for '-L' option" fi fi func_resolve_sysroot "$func_stripname_result" dir=$func_resolve_sysroot_result # We need an absolute path. case $dir in [\\/]* | [A-Za-z]:[\\/]*) ;; *) absdir=`cd "$dir" && pwd` test -z "$absdir" && \ func_fatal_error "cannot determine absolute directory name of '$dir'" dir=$absdir ;; esac case "$deplibs " in *" -L$dir "* | *" $arg "*) # Will only happen for absolute or sysroot arguments ;; *) # Preserve sysroot, but never include relative directories case $dir in [\\/]* | [A-Za-z]:[\\/]* | =*) func_append deplibs " $arg" ;; *) func_append deplibs " -L$dir" ;; esac func_append lib_search_path " $dir" ;; esac case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) testbindir=`$ECHO "$dir" | $SED 's*/lib$*/bin*'` case :$dllsearchpath: in *":$dir:"*) ;; ::) dllsearchpath=$dir;; *) func_append dllsearchpath ":$dir";; esac case :$dllsearchpath: in *":$testbindir:"*) ;; ::) dllsearchpath=$testbindir;; *) func_append dllsearchpath ":$testbindir";; esac ;; esac continue ;; -l*) if test X-lc = "X$arg" || test X-lm = "X$arg"; then case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos* | *-cegcc* | *-*-haiku*) # These systems don't actually have a C or math library (as such) continue ;; *-*-os2*) # These systems don't actually have a C library (as such) test X-lc = "X$arg" && continue ;; *-*-openbsd* | *-*-freebsd* | *-*-dragonfly* | *-*-bitrig* | *-*-midnightbsd*) # Do not include libc due to us having libc/libc_r. test X-lc = "X$arg" && continue ;; *-*-rhapsody* | *-*-darwin1.[012]) # Rhapsody C and math libraries are in the System framework func_append deplibs " System.ltframework" continue ;; *-*-sco3.2v5* | *-*-sco5v6*) # Causes problems with __ctype test X-lc = "X$arg" && continue ;; *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) # Compiler inserts libc in the correct place for threads to work test X-lc = "X$arg" && continue ;; esac elif test X-lc_r = "X$arg"; then case $host in *-*-openbsd* | *-*-freebsd* | *-*-dragonfly* | *-*-bitrig* | *-*-midnightbsd*) # Do not include libc_r directly, use -pthread flag. continue ;; esac fi func_append deplibs " $arg" continue ;; -mllvm) prev=mllvm continue ;; -module) module=yes continue ;; # Tru64 UNIX uses -model [arg] to determine the layout of C++ # classes, name mangling, and exception handling. # Darwin uses the -arch flag to determine output architecture. -model|-arch|-isysroot|--sysroot) func_append compiler_flags " $arg" func_append compile_command " $arg" func_append finalize_command " $arg" prev=xcompiler continue ;; # Solaris ld rejects as of 11.4. Refer to Oracle bug 22985199. -pthread) case $host in *solaris2*) ;; *) case "$new_inherited_linker_flags " in *" $arg "*) ;; * ) func_append new_inherited_linker_flags " $arg" ;; esac ;; esac continue ;; -mt|-mthreads|-kthread|-Kthread|-pthreads|--thread-safe \ |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*) func_append compiler_flags " $arg" func_append compile_command " $arg" func_append finalize_command " $arg" case "$new_inherited_linker_flags " in *" $arg "*) ;; * ) func_append new_inherited_linker_flags " $arg" ;; esac continue ;; -multi_module) single_module=$wl-multi_module continue ;; -no-fast-install) fast_install=no continue ;; -no-install) case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-darwin* | *-cegcc*) # The PATH hackery in wrapper scripts is required on Windows # and Darwin in order for the loader to find any dlls it needs. func_warning "'-no-install' is ignored for $host" func_warning "assuming '-no-fast-install' instead" fast_install=no ;; *) no_install=yes ;; esac continue ;; -no-undefined) allow_undefined=no continue ;; -objectlist) prev=objectlist continue ;; -os2dllname) prev=os2dllname continue ;; -o) prev=output ;; -precious-files-regex) prev=precious_regex continue ;; -release) prev=release continue ;; -rpath) prev=rpath continue ;; -R) prev=xrpath continue ;; -R*) func_stripname '-R' '' "$arg" dir=$func_stripname_result # We need an absolute path. case $dir in [\\/]* | [A-Za-z]:[\\/]*) ;; =*) func_stripname '=' '' "$dir" dir=$lt_sysroot$func_stripname_result ;; *) func_fatal_error "only absolute run-paths are allowed" ;; esac case "$xrpath " in *" $dir "*) ;; *) func_append xrpath " $dir" ;; esac continue ;; -shared) # The effects of -shared are defined in a previous loop. continue ;; -shrext) prev=shrext continue ;; -static | -static-libtool-libs) # The effects of -static are defined in a previous loop. # We used to do the same as -all-static on platforms that # didn't have a PIC flag, but the assumption that the effects # would be equivalent was wrong. It would break on at least # Digital Unix and AIX. continue ;; -thread-safe) thread_safe=yes continue ;; -version-info) prev=vinfo continue ;; -version-number) prev=vinfo vinfo_number=yes continue ;; -weak) prev=weak continue ;; -Wc,*) func_stripname '-Wc,' '' "$arg" args=$func_stripname_result arg= save_ifs=$IFS; IFS=, for flag in $args; do IFS=$save_ifs func_quote_arg pretty "$flag" func_append arg " $func_quote_arg_result" func_append compiler_flags " $func_quote_arg_result" done IFS=$save_ifs func_stripname ' ' '' "$arg" arg=$func_stripname_result ;; -Wl,*) func_stripname '-Wl,' '' "$arg" args=$func_stripname_result arg= save_ifs=$IFS; IFS=, for flag in $args; do IFS=$save_ifs func_quote_arg pretty "$flag" func_append arg " $wl$func_quote_arg_result" func_append compiler_flags " $wl$func_quote_arg_result" func_append linker_flags " $func_quote_arg_result" done IFS=$save_ifs func_stripname ' ' '' "$arg" arg=$func_stripname_result ;; -Xassembler) prev=xassembler continue ;; -Xcompiler) prev=xcompiler continue ;; -Xlinker) prev=xlinker continue ;; -XCClinker) prev=xcclinker continue ;; # -msg_* for osf cc -msg_*) func_quote_arg pretty "$arg" arg=$func_quote_arg_result ;; # Flags to be passed through unchanged, with rationale: # -64, -mips[0-9] enable 64-bit mode for the SGI compiler # -r[0-9][0-9]* specify processor for the SGI compiler # -xarch=*, -xtarget=* enable 64-bit mode for the Sun compiler # +DA*, +DD* enable 64-bit mode for the HP compiler # -q* compiler args for the IBM compiler # -m*, -t[45]*, -txscale* architecture-specific flags for GCC # -F/path path to uninstalled frameworks, gcc on darwin # -p, -pg, --coverage, -fprofile-* profiling flags for GCC # -fstack-protector* stack protector flags for GCC # @file GCC response files # -tp=* Portland pgcc target processor selection # --sysroot=* for sysroot support # -O*, -g*, -flto*, -fwhopr*, -fuse-linker-plugin GCC link-time optimization # -specs=* GCC specs files # -stdlib=* select c++ std lib with clang # -fsanitize=* Clang/GCC memory and address sanitizer # -fuse-ld=* Linker select flags for GCC # -Wa,* Pass flags directly to the assembler -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \ -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*|-tp=*|--sysroot=*| \ -O*|-g*|-flto*|-fwhopr*|-fuse-linker-plugin|-fstack-protector*|-stdlib=*| \ -specs=*|-fsanitize=*|-fuse-ld=*|-Wa,*) func_quote_arg pretty "$arg" arg=$func_quote_arg_result func_append compile_command " $arg" func_append finalize_command " $arg" func_append compiler_flags " $arg" continue ;; -Z*) if test os2 = "`expr $host : '.*\(os2\)'`"; then # OS/2 uses -Zxxx to specify OS/2-specific options compiler_flags="$compiler_flags $arg" func_append compile_command " $arg" func_append finalize_command " $arg" case $arg in -Zlinker | -Zstack) prev=xcompiler ;; esac continue else # Otherwise treat like 'Some other compiler flag' below func_quote_arg pretty "$arg" arg=$func_quote_arg_result fi ;; # Some other compiler flag. -* | +*) func_quote_arg pretty "$arg" arg=$func_quote_arg_result ;; *.$objext) # A standard object. func_append objs " $arg" ;; *.lo) # A libtool-controlled object. # Check to see that this really is a libtool object. if func_lalib_unsafe_p "$arg"; then pic_object= non_pic_object= # Read the .lo file func_source "$arg" if test -z "$pic_object" || test -z "$non_pic_object" || test none = "$pic_object" && test none = "$non_pic_object"; then func_fatal_error "cannot find name of object for '$arg'" fi # Extract subdirectory from the argument. func_dirname "$arg" "/" "" xdir=$func_dirname_result test none = "$pic_object" || { # Prepend the subdirectory the object is found in. pic_object=$xdir$pic_object if test dlfiles = "$prev"; then if test yes = "$build_libtool_libs" && test yes = "$dlopen_support"; then func_append dlfiles " $pic_object" prev= continue else # If libtool objects are unsupported, then we need to preload. prev=dlprefiles fi fi # CHECK ME: I think I busted this. -Ossama if test dlprefiles = "$prev"; then # Preload the old-style object. func_append dlprefiles " $pic_object" prev= fi # A PIC object. func_append libobjs " $pic_object" arg=$pic_object } # Non-PIC object. if test none != "$non_pic_object"; then # Prepend the subdirectory the object is found in. non_pic_object=$xdir$non_pic_object # A standard non-PIC object func_append non_pic_objects " $non_pic_object" if test -z "$pic_object" || test none = "$pic_object"; then arg=$non_pic_object fi else # If the PIC object exists, use it instead. # $xdir was prepended to $pic_object above. non_pic_object=$pic_object func_append non_pic_objects " $non_pic_object" fi else # Only an error if not doing a dry-run. if $opt_dry_run; then # Extract subdirectory from the argument. func_dirname "$arg" "/" "" xdir=$func_dirname_result func_lo2o "$arg" pic_object=$xdir$objdir/$func_lo2o_result non_pic_object=$xdir$func_lo2o_result func_append libobjs " $pic_object" func_append non_pic_objects " $non_pic_object" else func_fatal_error "'$arg' is not a valid libtool object" fi fi ;; *.$libext) # An archive. func_append deplibs " $arg" func_append old_deplibs " $arg" continue ;; *.la) # A libtool-controlled library. func_resolve_sysroot "$arg" if test dlfiles = "$prev"; then # This library was specified with -dlopen. func_append dlfiles " $func_resolve_sysroot_result" prev= elif test dlprefiles = "$prev"; then # The library was specified with -dlpreopen. func_append dlprefiles " $func_resolve_sysroot_result" prev= else func_append deplibs " $func_resolve_sysroot_result" fi continue ;; # Some other compiler argument. *) # Unknown arguments in both finalize_command and compile_command need # to be aesthetically quoted because they are evaled later. func_quote_arg pretty "$arg" arg=$func_quote_arg_result ;; esac # arg # Now actually substitute the argument into the commands. if test -n "$arg"; then func_append compile_command " $arg" func_append finalize_command " $arg" fi done # argument parsing loop test -n "$prev" && \ func_fatal_help "the '$prevarg' option requires an argument" if test yes = "$export_dynamic" && test -n "$export_dynamic_flag_spec"; then eval arg=\"$export_dynamic_flag_spec\" func_append compile_command " $arg" func_append finalize_command " $arg" fi oldlibs= # calculate the name of the file, without its directory func_basename "$output" outputname=$func_basename_result libobjs_save=$libobjs if test -n "$shlibpath_var"; then # get the directories listed in $shlibpath_var eval shlib_search_path=\`\$ECHO \"\$$shlibpath_var\" \| \$SED \'s/:/ /g\'\` else shlib_search_path= fi eval sys_lib_search_path=\"$sys_lib_search_path_spec\" eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\" # Definition is injected by LT_CONFIG during libtool generation. func_munge_path_list sys_lib_dlsearch_path "$LT_SYS_LIBRARY_PATH" func_dirname "$output" "/" "" output_objdir=$func_dirname_result$objdir func_to_tool_file "$output_objdir/" tool_output_objdir=$func_to_tool_file_result # Create the object directory. func_mkdir_p "$output_objdir" # Determine the type of output case $output in "") func_fatal_help "you must specify an output file" ;; *.$libext) linkmode=oldlib ;; *.lo | *.$objext) linkmode=obj ;; *.la) linkmode=lib ;; *) linkmode=prog ;; # Anything else should be a program. esac specialdeplibs= libs= # Find all interdependent deplibs by searching for libraries # that are linked more than once (e.g. -la -lb -la) for deplib in $deplibs; do if $opt_preserve_dup_deps; then case "$libs " in *" $deplib "*) func_append specialdeplibs " $deplib" ;; esac fi func_append libs " $deplib" done if test lib = "$linkmode"; then libs="$predeps $libs $compiler_lib_search_path $postdeps" # Compute libraries that are listed more than once in $predeps # $postdeps and mark them as special (i.e., whose duplicates are # not to be eliminated). pre_post_deps= if $opt_duplicate_compiler_generated_deps; then for pre_post_dep in $predeps $postdeps; do case "$pre_post_deps " in *" $pre_post_dep "*) func_append specialdeplibs " $pre_post_deps" ;; esac func_append pre_post_deps " $pre_post_dep" done fi pre_post_deps= fi deplibs= newdependency_libs= newlib_search_path= need_relink=no # whether we're linking any uninstalled libtool libraries notinst_deplibs= # not-installed libtool libraries notinst_path= # paths that contain not-installed libtool libraries case $linkmode in lib) passes="conv dlpreopen link" for file in $dlfiles $dlprefiles; do case $file in *.la) ;; *) func_fatal_help "libraries can '-dlopen' only libtool libraries: $file" ;; esac done ;; prog) compile_deplibs= finalize_deplibs= alldeplibs=false newdlfiles= newdlprefiles= passes="conv scan dlopen dlpreopen link" ;; *) passes="conv" ;; esac for pass in $passes; do # The preopen pass in lib mode reverses $deplibs; put it back here # so that -L comes before libs that need it for instance... if test lib,link = "$linkmode,$pass"; then ## FIXME: Find the place where the list is rebuilt in the wrong ## order, and fix it there properly tmp_deplibs= for deplib in $deplibs; do tmp_deplibs="$deplib $tmp_deplibs" done deplibs=$tmp_deplibs fi if test lib,link = "$linkmode,$pass" || test prog,scan = "$linkmode,$pass"; then libs=$deplibs deplibs= fi if test prog = "$linkmode"; then case $pass in dlopen) libs=$dlfiles ;; dlpreopen) libs=$dlprefiles ;; link) libs="$deplibs %DEPLIBS% $dependency_libs" ;; esac fi if test lib,dlpreopen = "$linkmode,$pass"; then # Collect and forward deplibs of preopened libtool libs for lib in $dlprefiles; do # Ignore non-libtool-libs dependency_libs= func_resolve_sysroot "$lib" case $lib in *.la) func_source "$func_resolve_sysroot_result" ;; esac # Collect preopened libtool deplibs, except any this library # has declared as weak libs for deplib in $dependency_libs; do func_basename "$deplib" deplib_base=$func_basename_result case " $weak_libs " in *" $deplib_base "*) ;; *) func_append deplibs " $deplib" ;; esac done done libs=$dlprefiles fi if test dlopen = "$pass"; then # Collect dlpreopened libraries save_deplibs=$deplibs deplibs= fi for deplib in $libs; do lib= found=false case $deplib in -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \ |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*) if test prog,link = "$linkmode,$pass"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else func_append compiler_flags " $deplib" if test lib = "$linkmode"; then case "$new_inherited_linker_flags " in *" $deplib "*) ;; * ) func_append new_inherited_linker_flags " $deplib" ;; esac fi fi continue ;; -l*) if test lib != "$linkmode" && test prog != "$linkmode"; then func_warning "'-l' is ignored for archives/objects" continue fi func_stripname '-l' '' "$deplib" name=$func_stripname_result if test lib = "$linkmode"; then searchdirs="$newlib_search_path $lib_search_path $compiler_lib_search_dirs $sys_lib_search_path $shlib_search_path" else searchdirs="$newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path" fi for searchdir in $searchdirs; do for search_ext in .la $std_shrext .so .a; do # Search the libtool library lib=$searchdir/lib$name$search_ext if test -f "$lib"; then if test .la = "$search_ext"; then found=: else found=false fi break 2 fi done done if $found; then # deplib is a libtool library # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib, # We need to do some special things here, and not later. if test yes = "$allow_libtool_libs_with_static_runtimes"; then case " $predeps $postdeps " in *" $deplib "*) if func_lalib_p "$lib"; then library_names= old_library= func_source "$lib" for l in $old_library $library_names; do ll=$l done if test "X$ll" = "X$old_library"; then # only static version available found=false func_dirname "$lib" "" "." ladir=$func_dirname_result lib=$ladir/$old_library if test prog,link = "$linkmode,$pass"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else deplibs="$deplib $deplibs" test lib = "$linkmode" && newdependency_libs="$deplib $newdependency_libs" fi continue fi fi ;; *) ;; esac fi else # deplib doesn't seem to be a libtool library if test prog,link = "$linkmode,$pass"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else deplibs="$deplib $deplibs" test lib = "$linkmode" && newdependency_libs="$deplib $newdependency_libs" fi continue fi ;; # -l *.ltframework) if test prog,link = "$linkmode,$pass"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else deplibs="$deplib $deplibs" if test lib = "$linkmode"; then case "$new_inherited_linker_flags " in *" $deplib "*) ;; * ) func_append new_inherited_linker_flags " $deplib" ;; esac fi fi continue ;; -L*) case $linkmode in lib) deplibs="$deplib $deplibs" test conv = "$pass" && continue newdependency_libs="$deplib $newdependency_libs" func_stripname '-L' '' "$deplib" func_resolve_sysroot "$func_stripname_result" func_append newlib_search_path " $func_resolve_sysroot_result" ;; prog) if test conv = "$pass"; then deplibs="$deplib $deplibs" continue fi if test scan = "$pass"; then deplibs="$deplib $deplibs" else compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" fi func_stripname '-L' '' "$deplib" func_resolve_sysroot "$func_stripname_result" func_append newlib_search_path " $func_resolve_sysroot_result" ;; *) func_warning "'-L' is ignored for archives/objects" ;; esac # linkmode continue ;; # -L -R*) if test link = "$pass"; then func_stripname '-R' '' "$deplib" func_resolve_sysroot "$func_stripname_result" dir=$func_resolve_sysroot_result # Make sure the xrpath contains only unique directories. case "$xrpath " in *" $dir "*) ;; *) func_append xrpath " $dir" ;; esac fi deplibs="$deplib $deplibs" continue ;; *.la) func_resolve_sysroot "$deplib" lib=$func_resolve_sysroot_result ;; *.$libext) if test conv = "$pass"; then deplibs="$deplib $deplibs" continue fi case $linkmode in lib) # Linking convenience modules into shared libraries is allowed, # but linking other static libraries is non-portable. case " $dlpreconveniencelibs " in *" $deplib "*) ;; *) valid_a_lib=false case $deplibs_check_method in match_pattern*) set dummy $deplibs_check_method; shift match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` if eval "\$ECHO \"$deplib\"" 2>/dev/null | $SED 10q \ | $EGREP "$match_pattern_regex" > /dev/null; then valid_a_lib=: fi ;; pass_all) valid_a_lib=: ;; esac if $valid_a_lib; then echo $ECHO "*** Warning: Linking the shared library $output against the" $ECHO "*** static library $deplib is not portable!" deplibs="$deplib $deplibs" else echo $ECHO "*** Warning: Trying to link with static lib archive $deplib." echo "*** I have the capability to make that library automatically link in when" echo "*** you link to this library. But I can only do this if you have a" echo "*** shared version of the library, which you do not appear to have" echo "*** because the file extensions .$libext of this argument makes me believe" echo "*** that it is just a static archive that I should not use here." fi ;; esac continue ;; prog) if test link != "$pass"; then deplibs="$deplib $deplibs" else compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" fi continue ;; esac # linkmode ;; # *.$libext *.lo | *.$objext) if test conv = "$pass"; then deplibs="$deplib $deplibs" elif test prog = "$linkmode"; then if test dlpreopen = "$pass" || test yes != "$dlopen_support" || test no = "$build_libtool_libs"; then # If there is no dlopen support or we're linking statically, # we need to preload. func_append newdlprefiles " $deplib" compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else func_append newdlfiles " $deplib" fi fi continue ;; %DEPLIBS%) alldeplibs=: continue ;; esac # case $deplib $found || test -f "$lib" \ || func_fatal_error "cannot find the library '$lib' or unhandled argument '$deplib'" # Check to see that this really is a libtool archive. func_lalib_unsafe_p "$lib" \ || func_fatal_error "'$lib' is not a valid libtool archive" func_dirname "$lib" "" "." ladir=$func_dirname_result dlname= dlopen= dlpreopen= libdir= library_names= old_library= inherited_linker_flags= # If the library was installed with an old release of libtool, # it will not redefine variables installed, or shouldnotlink installed=yes shouldnotlink=no avoidtemprpath= # Read the .la file func_source "$lib" # Convert "-framework foo" to "foo.ltframework" if test -n "$inherited_linker_flags"; then tmp_inherited_linker_flags=`$ECHO "$inherited_linker_flags" | $SED 's/-framework \([^ $]*\)/\1.ltframework/g'` for tmp_inherited_linker_flag in $tmp_inherited_linker_flags; do case " $new_inherited_linker_flags " in *" $tmp_inherited_linker_flag "*) ;; *) func_append new_inherited_linker_flags " $tmp_inherited_linker_flag";; esac done fi dependency_libs=`$ECHO " $dependency_libs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` if test lib,link = "$linkmode,$pass" || test prog,scan = "$linkmode,$pass" || { test prog != "$linkmode" && test lib != "$linkmode"; }; then test -n "$dlopen" && func_append dlfiles " $dlopen" test -n "$dlpreopen" && func_append dlprefiles " $dlpreopen" fi if test conv = "$pass"; then # Only check for convenience libraries deplibs="$lib $deplibs" if test -z "$libdir"; then if test -z "$old_library"; then func_fatal_error "cannot find name of link library for '$lib'" fi # It is a libtool convenience library, so add in its objects. func_append convenience " $ladir/$objdir/$old_library" func_append old_convenience " $ladir/$objdir/$old_library" elif test prog != "$linkmode" && test lib != "$linkmode"; then func_fatal_error "'$lib' is not a convenience library" fi tmp_libs= for deplib in $dependency_libs; do deplibs="$deplib $deplibs" if $opt_preserve_dup_deps; then case "$tmp_libs " in *" $deplib "*) func_append specialdeplibs " $deplib" ;; esac fi func_append tmp_libs " $deplib" done continue fi # $pass = conv # Get the name of the library we link against. linklib= if test -n "$old_library" && { test yes = "$prefer_static_libs" || test built,no = "$prefer_static_libs,$installed"; }; then linklib=$old_library else for l in $old_library $library_names; do linklib=$l done fi if test -z "$linklib"; then func_fatal_error "cannot find name of link library for '$lib'" fi # This library was specified with -dlopen. if test dlopen = "$pass"; then test -z "$libdir" \ && func_fatal_error "cannot -dlopen a convenience library: '$lib'" if test -z "$dlname" || test yes != "$dlopen_support" || test no = "$build_libtool_libs" then # If there is no dlname, no dlopen support or we're linking # statically, we need to preload. We also need to preload any # dependent libraries so libltdl's deplib preloader doesn't # bomb out in the load deplibs phase. func_append dlprefiles " $lib $dependency_libs" else func_append newdlfiles " $lib" fi continue fi # $pass = dlopen # We need an absolute path. case $ladir in [\\/]* | [A-Za-z]:[\\/]*) abs_ladir=$ladir ;; *) abs_ladir=`cd "$ladir" && pwd` if test -z "$abs_ladir"; then func_warning "cannot determine absolute directory name of '$ladir'" func_warning "passing it literally to the linker, although it might fail" abs_ladir=$ladir fi ;; esac func_basename "$lib" laname=$func_basename_result # Find the relevant object directory and library name. if test yes = "$installed"; then if test ! -f "$lt_sysroot$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then func_warning "library '$lib' was moved." dir=$ladir absdir=$abs_ladir libdir=$abs_ladir else dir=$lt_sysroot$libdir absdir=$lt_sysroot$libdir fi test yes = "$hardcode_automatic" && avoidtemprpath=yes else if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then dir=$ladir absdir=$abs_ladir # Remove this search path later func_append notinst_path " $abs_ladir" else dir=$ladir/$objdir absdir=$abs_ladir/$objdir # Remove this search path later func_append notinst_path " $abs_ladir" fi fi # $installed = yes func_stripname 'lib' '.la' "$laname" name=$func_stripname_result # This library was specified with -dlpreopen. if test dlpreopen = "$pass"; then if test -z "$libdir" && test prog = "$linkmode"; then func_fatal_error "only libraries may -dlpreopen a convenience library: '$lib'" fi case $host in # special handling for platforms with PE-DLLs. *cygwin* | *mingw* | *cegcc* ) # Linker will automatically link against shared library if both # static and shared are present. Therefore, ensure we extract # symbols from the import library if a shared library is present # (otherwise, the dlopen module name will be incorrect). We do # this by putting the import library name into $newdlprefiles. # We recover the dlopen module name by 'saving' the la file # name in a special purpose variable, and (later) extracting the # dlname from the la file. if test -n "$dlname"; then func_tr_sh "$dir/$linklib" eval "libfile_$func_tr_sh_result=\$abs_ladir/\$laname" func_append newdlprefiles " $dir/$linklib" else func_append newdlprefiles " $dir/$old_library" # Keep a list of preopened convenience libraries to check # that they are being used correctly in the link pass. test -z "$libdir" && \ func_append dlpreconveniencelibs " $dir/$old_library" fi ;; * ) # Prefer using a static library (so that no silly _DYNAMIC symbols # are required to link). if test -n "$old_library"; then func_append newdlprefiles " $dir/$old_library" # Keep a list of preopened convenience libraries to check # that they are being used correctly in the link pass. test -z "$libdir" && \ func_append dlpreconveniencelibs " $dir/$old_library" # Otherwise, use the dlname, so that lt_dlopen finds it. elif test -n "$dlname"; then func_append newdlprefiles " $dir/$dlname" else func_append newdlprefiles " $dir/$linklib" fi ;; esac fi # $pass = dlpreopen if test -z "$libdir"; then # Link the convenience library if test lib = "$linkmode"; then deplibs="$dir/$old_library $deplibs" elif test prog,link = "$linkmode,$pass"; then compile_deplibs="$dir/$old_library $compile_deplibs" finalize_deplibs="$dir/$old_library $finalize_deplibs" else deplibs="$lib $deplibs" # used for prog,scan pass fi continue fi if test prog = "$linkmode" && test link != "$pass"; then func_append newlib_search_path " $ladir" deplibs="$lib $deplibs" linkalldeplibs=false if test no != "$link_all_deplibs" || test -z "$library_names" || test no = "$build_libtool_libs"; then linkalldeplibs=: fi tmp_libs= for deplib in $dependency_libs; do case $deplib in -L*) func_stripname '-L' '' "$deplib" func_resolve_sysroot "$func_stripname_result" func_append newlib_search_path " $func_resolve_sysroot_result" ;; esac # Need to link against all dependency_libs? if $linkalldeplibs; then deplibs="$deplib $deplibs" else # Need to hardcode shared library paths # or/and link against static libraries newdependency_libs="$deplib $newdependency_libs" fi if $opt_preserve_dup_deps; then case "$tmp_libs " in *" $deplib "*) func_append specialdeplibs " $deplib" ;; esac fi func_append tmp_libs " $deplib" done # for deplib continue fi # $linkmode = prog... if test prog,link = "$linkmode,$pass"; then if test -n "$library_names" && { { test no = "$prefer_static_libs" || test built,yes = "$prefer_static_libs,$installed"; } || test -z "$old_library"; }; then # We need to hardcode the library path if test -n "$shlibpath_var" && test -z "$avoidtemprpath"; then # Make sure the rpath contains only unique directories. case $temp_rpath: in *"$absdir:"*) ;; *) func_append temp_rpath "$absdir:" ;; esac fi # Hardcode the library path. # Skip directories that are in the system default run-time # search path. case " $sys_lib_dlsearch_path " in *" $absdir "*) ;; *) case "$compile_rpath " in *" $absdir "*) ;; *) func_append compile_rpath " $absdir" ;; esac ;; esac case " $sys_lib_dlsearch_path " in *" $libdir "*) ;; *) case "$finalize_rpath " in *" $libdir "*) ;; *) func_append finalize_rpath " $libdir" ;; esac ;; esac fi # $linkmode,$pass = prog,link... if $alldeplibs && { test pass_all = "$deplibs_check_method" || { test yes = "$build_libtool_libs" && test -n "$library_names"; }; }; then # We only need to search for static libraries continue fi fi link_static=no # Whether the deplib will be linked statically use_static_libs=$prefer_static_libs if test built = "$use_static_libs" && test yes = "$installed"; then use_static_libs=no fi if test -n "$library_names" && { test no = "$use_static_libs" || test -z "$old_library"; }; then case $host in *cygwin* | *mingw* | *cegcc* | *os2*) # No point in relinking DLLs because paths are not encoded func_append notinst_deplibs " $lib" need_relink=no ;; *) if test no = "$installed"; then func_append notinst_deplibs " $lib" need_relink=yes fi ;; esac # This is a shared library # Warn about portability, can't link against -module's on some # systems (darwin). Don't bleat about dlopened modules though! dlopenmodule= for dlpremoduletest in $dlprefiles; do if test "X$dlpremoduletest" = "X$lib"; then dlopenmodule=$dlpremoduletest break fi done if test -z "$dlopenmodule" && test yes = "$shouldnotlink" && test link = "$pass"; then echo if test prog = "$linkmode"; then $ECHO "*** Warning: Linking the executable $output against the loadable module" else $ECHO "*** Warning: Linking the shared library $output against the loadable module" fi $ECHO "*** $linklib is not portable!" fi if test lib = "$linkmode" && test yes = "$hardcode_into_libs"; then # Hardcode the library path. # Skip directories that are in the system default run-time # search path. case " $sys_lib_dlsearch_path " in *" $absdir "*) ;; *) case "$compile_rpath " in *" $absdir "*) ;; *) func_append compile_rpath " $absdir" ;; esac ;; esac case " $sys_lib_dlsearch_path " in *" $libdir "*) ;; *) case "$finalize_rpath " in *" $libdir "*) ;; *) func_append finalize_rpath " $libdir" ;; esac ;; esac fi if test -n "$old_archive_from_expsyms_cmds"; then # figure out the soname set dummy $library_names shift realname=$1 shift libname=`eval "\\$ECHO \"$libname_spec\""` # use dlname if we got it. it's perfectly good, no? if test -n "$dlname"; then soname=$dlname elif test -n "$soname_spec"; then # bleh windows case $host in *cygwin* | mingw* | *cegcc* | *os2*) func_arith $current - $age major=$func_arith_result versuffix=-$major ;; esac eval soname=\"$soname_spec\" else soname=$realname fi # Make a new name for the extract_expsyms_cmds to use soroot=$soname func_basename "$soroot" soname=$func_basename_result func_stripname 'lib' '.dll' "$soname" newlib=libimp-$func_stripname_result.a # If the library has no export list, then create one now if test -f "$output_objdir/$soname-def"; then : else func_verbose "extracting exported symbol list from '$soname'" func_execute_cmds "$extract_expsyms_cmds" 'exit $?' fi # Create $newlib if test -f "$output_objdir/$newlib"; then :; else func_verbose "generating import library for '$soname'" func_execute_cmds "$old_archive_from_expsyms_cmds" 'exit $?' fi # make sure the library variables are pointing to the new library dir=$output_objdir linklib=$newlib fi # test -n "$old_archive_from_expsyms_cmds" if test prog = "$linkmode" || test relink != "$opt_mode"; then add_shlibpath= add_dir= add= lib_linked=yes case $hardcode_action in immediate | unsupported) if test no = "$hardcode_direct"; then add=$dir/$linklib case $host in *-*-sco3.2v5.0.[024]*) add_dir=-L$dir ;; *-*-sysv4*uw2*) add_dir=-L$dir ;; *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \ *-*-unixware7*) add_dir=-L$dir ;; *-*-darwin* ) # if the lib is a (non-dlopened) module then we cannot # link against it, someone is ignoring the earlier warnings if /usr/bin/file -L $add 2> /dev/null | $GREP ": [^:]* bundle" >/dev/null; then if test "X$dlopenmodule" != "X$lib"; then $ECHO "*** Warning: lib $linklib is a module, not a shared library" if test -z "$old_library"; then echo echo "*** And there doesn't seem to be a static archive available" echo "*** The link will probably fail, sorry" else add=$dir/$old_library fi elif test -n "$old_library"; then add=$dir/$old_library fi fi esac elif test no = "$hardcode_minus_L"; then case $host in *-*-sunos*) add_shlibpath=$dir ;; esac add_dir=-L$dir add=-l$name elif test no = "$hardcode_shlibpath_var"; then add_shlibpath=$dir add=-l$name else lib_linked=no fi ;; relink) if test yes = "$hardcode_direct" && test no = "$hardcode_direct_absolute"; then add=$dir/$linklib elif test yes = "$hardcode_minus_L"; then add_dir=-L$absdir # Try looking first in the location we're being installed to. if test -n "$inst_prefix_dir"; then case $libdir in [\\/]*) func_append add_dir " -L$inst_prefix_dir$libdir" ;; esac fi add=-l$name elif test yes = "$hardcode_shlibpath_var"; then add_shlibpath=$dir add=-l$name else lib_linked=no fi ;; *) lib_linked=no ;; esac if test yes != "$lib_linked"; then func_fatal_configuration "unsupported hardcode properties" fi if test -n "$add_shlibpath"; then case :$compile_shlibpath: in *":$add_shlibpath:"*) ;; *) func_append compile_shlibpath "$add_shlibpath:" ;; esac fi if test prog = "$linkmode"; then test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs" test -n "$add" && compile_deplibs="$add $compile_deplibs" else test -n "$add_dir" && deplibs="$add_dir $deplibs" test -n "$add" && deplibs="$add $deplibs" if test yes != "$hardcode_direct" && test yes != "$hardcode_minus_L" && test yes = "$hardcode_shlibpath_var"; then case :$finalize_shlibpath: in *":$libdir:"*) ;; *) func_append finalize_shlibpath "$libdir:" ;; esac fi fi fi if test prog = "$linkmode" || test relink = "$opt_mode"; then add_shlibpath= add_dir= add= # Finalize command for both is simple: just hardcode it. if test yes = "$hardcode_direct" && test no = "$hardcode_direct_absolute"; then add=$libdir/$linklib elif test yes = "$hardcode_minus_L"; then add_dir=-L$libdir add=-l$name elif test yes = "$hardcode_shlibpath_var"; then case :$finalize_shlibpath: in *":$libdir:"*) ;; *) func_append finalize_shlibpath "$libdir:" ;; esac add=-l$name elif test yes = "$hardcode_automatic"; then if test -n "$inst_prefix_dir" && test -f "$inst_prefix_dir$libdir/$linklib"; then add=$inst_prefix_dir$libdir/$linklib else add=$libdir/$linklib fi else # We cannot seem to hardcode it, guess we'll fake it. add_dir=-L$libdir # Try looking first in the location we're being installed to. if test -n "$inst_prefix_dir"; then case $libdir in [\\/]*) func_append add_dir " -L$inst_prefix_dir$libdir" ;; esac fi add=-l$name fi if test prog = "$linkmode"; then test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs" test -n "$add" && finalize_deplibs="$add $finalize_deplibs" else test -n "$add_dir" && deplibs="$add_dir $deplibs" test -n "$add" && deplibs="$add $deplibs" fi fi elif test prog = "$linkmode"; then # Here we assume that one of hardcode_direct or hardcode_minus_L # is not unsupported. This is valid on all known static and # shared platforms. if test unsupported != "$hardcode_direct"; then test -n "$old_library" && linklib=$old_library compile_deplibs="$dir/$linklib $compile_deplibs" finalize_deplibs="$dir/$linklib $finalize_deplibs" else compile_deplibs="-l$name -L$dir $compile_deplibs" finalize_deplibs="-l$name -L$dir $finalize_deplibs" fi elif test yes = "$build_libtool_libs"; then # Not a shared library if test pass_all != "$deplibs_check_method"; then # We're trying link a shared library against a static one # but the system doesn't support it. # Just print a warning and add the library to dependency_libs so # that the program can be linked against the static library. echo $ECHO "*** Warning: This system cannot link to static lib archive $lib." echo "*** I have the capability to make that library automatically link in when" echo "*** you link to this library. But I can only do this if you have a" echo "*** shared version of the library, which you do not appear to have." if test yes = "$module"; then echo "*** But as you try to build a module library, libtool will still create " echo "*** a static module, that should work as long as the dlopening application" echo "*** is linked with the -dlopen flag to resolve symbols at runtime." if test -z "$global_symbol_pipe"; then echo echo "*** However, this would only work if libtool was able to extract symbol" echo "*** lists from a program, using 'nm' or equivalent, but libtool could" echo "*** not find such a program. So, this module is probably useless." echo "*** 'nm' from GNU binutils and a full rebuild may help." fi if test no = "$build_old_libs"; then build_libtool_libs=module build_old_libs=yes else build_libtool_libs=no fi fi else deplibs="$dir/$old_library $deplibs" link_static=yes fi fi # link shared/static library? if test lib = "$linkmode"; then if test -n "$dependency_libs" && { test yes != "$hardcode_into_libs" || test yes = "$build_old_libs" || test yes = "$link_static"; }; then # Extract -R from dependency_libs temp_deplibs= for libdir in $dependency_libs; do case $libdir in -R*) func_stripname '-R' '' "$libdir" temp_xrpath=$func_stripname_result case " $xrpath " in *" $temp_xrpath "*) ;; *) func_append xrpath " $temp_xrpath";; esac;; *) func_append temp_deplibs " $libdir";; esac done dependency_libs=$temp_deplibs fi func_append newlib_search_path " $absdir" # Link against this library test no = "$link_static" && newdependency_libs="$abs_ladir/$laname $newdependency_libs" # ... and its dependency_libs tmp_libs= for deplib in $dependency_libs; do newdependency_libs="$deplib $newdependency_libs" case $deplib in -L*) func_stripname '-L' '' "$deplib" func_resolve_sysroot "$func_stripname_result";; *) func_resolve_sysroot "$deplib" ;; esac if $opt_preserve_dup_deps; then case "$tmp_libs " in *" $func_resolve_sysroot_result "*) func_append specialdeplibs " $func_resolve_sysroot_result" ;; esac fi func_append tmp_libs " $func_resolve_sysroot_result" done if test no != "$link_all_deplibs"; then # Add the search paths of all dependency libraries for deplib in $dependency_libs; do path= case $deplib in -L*) path=$deplib ;; *.la) func_resolve_sysroot "$deplib" deplib=$func_resolve_sysroot_result func_dirname "$deplib" "" "." dir=$func_dirname_result # We need an absolute path. case $dir in [\\/]* | [A-Za-z]:[\\/]*) absdir=$dir ;; *) absdir=`cd "$dir" && pwd` if test -z "$absdir"; then func_warning "cannot determine absolute directory name of '$dir'" absdir=$dir fi ;; esac if $GREP "^installed=no" $deplib > /dev/null; then case $host in *-*-darwin*) depdepl= eval deplibrary_names=`$SED -n -e 's/^library_names=\(.*\)$/\1/p' $deplib` if test -n "$deplibrary_names"; then for tmp in $deplibrary_names; do depdepl=$tmp done if test -f "$absdir/$objdir/$depdepl"; then depdepl=$absdir/$objdir/$depdepl darwin_install_name=`$OTOOL -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` if test -z "$darwin_install_name"; then darwin_install_name=`$OTOOL64 -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` fi func_append compiler_flags " $wl-dylib_file $wl$darwin_install_name:$depdepl" func_append linker_flags " -dylib_file $darwin_install_name:$depdepl" path= fi fi ;; *) path=-L$absdir/$objdir ;; esac else eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` test -z "$libdir" && \ func_fatal_error "'$deplib' is not a valid libtool archive" test "$absdir" != "$libdir" && \ func_warning "'$deplib' seems to be moved" path=-L$absdir fi ;; esac case " $deplibs " in *" $path "*) ;; *) deplibs="$path $deplibs" ;; esac done fi # link_all_deplibs != no fi # linkmode = lib done # for deplib in $libs if test link = "$pass"; then if test prog = "$linkmode"; then compile_deplibs="$new_inherited_linker_flags $compile_deplibs" finalize_deplibs="$new_inherited_linker_flags $finalize_deplibs" else compiler_flags="$compiler_flags "`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` fi fi dependency_libs=$newdependency_libs if test dlpreopen = "$pass"; then # Link the dlpreopened libraries before other libraries for deplib in $save_deplibs; do deplibs="$deplib $deplibs" done fi if test dlopen != "$pass"; then test conv = "$pass" || { # Make sure lib_search_path contains only unique directories. lib_search_path= for dir in $newlib_search_path; do case "$lib_search_path " in *" $dir "*) ;; *) func_append lib_search_path " $dir" ;; esac done newlib_search_path= } if test prog,link = "$linkmode,$pass"; then vars="compile_deplibs finalize_deplibs" else vars=deplibs fi for var in $vars dependency_libs; do # Add libraries to $var in reverse order eval tmp_libs=\"\$$var\" new_libs= for deplib in $tmp_libs; do # FIXME: Pedantically, this is the right thing to do, so # that some nasty dependency loop isn't accidentally # broken: #new_libs="$deplib $new_libs" # Pragmatically, this seems to cause very few problems in # practice: case $deplib in -L*) new_libs="$deplib $new_libs" ;; -R*) ;; *) # And here is the reason: when a library appears more # than once as an explicit dependence of a library, or # is implicitly linked in more than once by the # compiler, it is considered special, and multiple # occurrences thereof are not removed. Compare this # with having the same library being listed as a # dependency of multiple other libraries: in this case, # we know (pedantically, we assume) the library does not # need to be listed more than once, so we keep only the # last copy. This is not always right, but it is rare # enough that we require users that really mean to play # such unportable linking tricks to link the library # using -Wl,-lname, so that libtool does not consider it # for duplicate removal. case " $specialdeplibs " in *" $deplib "*) new_libs="$deplib $new_libs" ;; *) case " $new_libs " in *" $deplib "*) ;; *) new_libs="$deplib $new_libs" ;; esac ;; esac ;; esac done tmp_libs= for deplib in $new_libs; do case $deplib in -L*) case " $tmp_libs " in *" $deplib "*) ;; *) func_append tmp_libs " $deplib" ;; esac ;; *) func_append tmp_libs " $deplib" ;; esac done eval $var=\"$tmp_libs\" done # for var fi # Add Sun CC postdeps if required: test CXX = "$tagname" && { case $host_os in linux*) case `$CC -V 2>&1 | $SED 5q` in *Sun\ C*) # Sun C++ 5.9 func_suncc_cstd_abi if test no != "$suncc_use_cstd_abi"; then func_append postdeps ' -library=Cstd -library=Crun' fi ;; esac ;; solaris*) func_cc_basename "$CC" case $func_cc_basename_result in CC* | sunCC*) func_suncc_cstd_abi if test no != "$suncc_use_cstd_abi"; then func_append postdeps ' -library=Cstd -library=Crun' fi ;; esac ;; esac } # Last step: remove runtime libs from dependency_libs # (they stay in deplibs) tmp_libs= for i in $dependency_libs; do case " $predeps $postdeps $compiler_lib_search_path " in *" $i "*) i= ;; esac if test -n "$i"; then func_append tmp_libs " $i" fi done dependency_libs=$tmp_libs done # for pass if test prog = "$linkmode"; then dlfiles=$newdlfiles fi if test prog = "$linkmode" || test lib = "$linkmode"; then dlprefiles=$newdlprefiles fi case $linkmode in oldlib) if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then func_warning "'-dlopen' is ignored for archives" fi case " $deplibs" in *\ -l* | *\ -L*) func_warning "'-l' and '-L' are ignored for archives" ;; esac test -n "$rpath" && \ func_warning "'-rpath' is ignored for archives" test -n "$xrpath" && \ func_warning "'-R' is ignored for archives" test -n "$vinfo" && \ func_warning "'-version-info/-version-number' is ignored for archives" test -n "$release" && \ func_warning "'-release' is ignored for archives" test -n "$export_symbols$export_symbols_regex" && \ func_warning "'-export-symbols' is ignored for archives" # Now set the variables for building old libraries. build_libtool_libs=no oldlibs=$output func_append objs "$old_deplibs" ;; lib) # Make sure we only generate libraries of the form 'libNAME.la'. case $outputname in lib*) func_stripname 'lib' '.la' "$outputname" name=$func_stripname_result eval shared_ext=\"$shrext_cmds\" eval libname=\"$libname_spec\" ;; *) test no = "$module" \ && func_fatal_help "libtool library '$output' must begin with 'lib'" if test no != "$need_lib_prefix"; then # Add the "lib" prefix for modules if required func_stripname '' '.la' "$outputname" name=$func_stripname_result eval shared_ext=\"$shrext_cmds\" eval libname=\"$libname_spec\" else func_stripname '' '.la' "$outputname" libname=$func_stripname_result fi ;; esac if test -n "$objs"; then if test pass_all != "$deplibs_check_method"; then func_fatal_error "cannot build libtool library '$output' from non-libtool objects on this host:$objs" else echo $ECHO "*** Warning: Linking the shared library $output against the non-libtool" $ECHO "*** objects $objs is not portable!" func_append libobjs " $objs" fi fi test no = "$dlself" \ || func_warning "'-dlopen self' is ignored for libtool libraries" set dummy $rpath shift test 1 -lt "$#" \ && func_warning "ignoring multiple '-rpath's for a libtool library" install_libdir=$1 oldlibs= if test -z "$rpath"; then if test yes = "$build_libtool_libs"; then # Building a libtool convenience library. # Some compilers have problems with a '.al' extension so # convenience libraries should have the same extension an # archive normally would. oldlibs="$output_objdir/$libname.$libext $oldlibs" build_libtool_libs=convenience build_old_libs=yes fi test -n "$vinfo" && \ func_warning "'-version-info/-version-number' is ignored for convenience libraries" test -n "$release" && \ func_warning "'-release' is ignored for convenience libraries" else # Parse the version information argument. save_ifs=$IFS; IFS=: set dummy $vinfo 0 0 0 shift IFS=$save_ifs test -n "$7" && \ func_fatal_help "too many parameters to '-version-info'" # convert absolute version numbers to libtool ages # this retains compatibility with .la files and attempts # to make the code below a bit more comprehensible case $vinfo_number in yes) number_major=$1 number_minor=$2 number_revision=$3 # # There are really only two kinds -- those that # use the current revision as the major version # and those that subtract age and use age as # a minor version. But, then there is irix # that has an extra 1 added just for fun # case $version_type in # correct linux to gnu/linux during the next big refactor darwin|freebsd-elf|linux|midnightbsd-elf|osf|windows|none) func_arith $number_major + $number_minor current=$func_arith_result age=$number_minor revision=$number_revision ;; freebsd-aout|qnx|sunos) current=$number_major revision=$number_minor age=0 ;; irix|nonstopux) func_arith $number_major + $number_minor current=$func_arith_result age=$number_minor revision=$number_minor lt_irix_increment=no ;; esac ;; no) current=$1 revision=$2 age=$3 ;; esac # Check that each of the things are valid numbers. case $current in 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; *) func_error "CURRENT '$current' must be a nonnegative integer" func_fatal_error "'$vinfo' is not valid version information" ;; esac case $revision in 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; *) func_error "REVISION '$revision' must be a nonnegative integer" func_fatal_error "'$vinfo' is not valid version information" ;; esac case $age in 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; *) func_error "AGE '$age' must be a nonnegative integer" func_fatal_error "'$vinfo' is not valid version information" ;; esac if test "$age" -gt "$current"; then func_error "AGE '$age' is greater than the current interface number '$current'" func_fatal_error "'$vinfo' is not valid version information" fi # Calculate the version variables. major= versuffix= verstring= case $version_type in none) ;; darwin) # Like Linux, but with the current version available in # verstring for coding it into the library header func_arith $current - $age major=.$func_arith_result versuffix=$major.$age.$revision # Darwin ld doesn't like 0 for these options... func_arith $current + 1 minor_current=$func_arith_result xlcverstring="$wl-compatibility_version $wl$minor_current $wl-current_version $wl$minor_current.$revision" verstring="-compatibility_version $minor_current -current_version $minor_current.$revision" # On Darwin other compilers case $CC in nagfor*) verstring="$wl-compatibility_version $wl$minor_current $wl-current_version $wl$minor_current.$revision" ;; *) verstring="-compatibility_version $minor_current -current_version $minor_current.$revision" ;; esac ;; freebsd-aout) major=.$current versuffix=.$current.$revision ;; freebsd-elf | midnightbsd-elf) func_arith $current - $age major=.$func_arith_result versuffix=$major.$age.$revision ;; irix | nonstopux) if test no = "$lt_irix_increment"; then func_arith $current - $age else func_arith $current - $age + 1 fi major=$func_arith_result case $version_type in nonstopux) verstring_prefix=nonstopux ;; *) verstring_prefix=sgi ;; esac verstring=$verstring_prefix$major.$revision # Add in all the interfaces that we are compatible with. loop=$revision while test 0 -ne "$loop"; do func_arith $revision - $loop iface=$func_arith_result func_arith $loop - 1 loop=$func_arith_result verstring=$verstring_prefix$major.$iface:$verstring done # Before this point, $major must not contain '.'. major=.$major versuffix=$major.$revision ;; linux) # correct to gnu/linux during the next big refactor func_arith $current - $age major=.$func_arith_result versuffix=$major.$age.$revision ;; osf) func_arith $current - $age major=.$func_arith_result versuffix=.$current.$age.$revision verstring=$current.$age.$revision # Add in all the interfaces that we are compatible with. loop=$age while test 0 -ne "$loop"; do func_arith $current - $loop iface=$func_arith_result func_arith $loop - 1 loop=$func_arith_result verstring=$verstring:$iface.0 done # Make executables depend on our current version. func_append verstring ":$current.0" ;; qnx) major=.$current versuffix=.$current ;; sco) major=.$current versuffix=.$current ;; sunos) major=.$current versuffix=.$current.$revision ;; windows) # Use '-' rather than '.', since we only want one # extension on DOS 8.3 file systems. func_arith $current - $age major=$func_arith_result versuffix=-$major ;; *) func_fatal_configuration "unknown library version type '$version_type'" ;; esac # Clear the version info if we defaulted, and they specified a release. if test -z "$vinfo" && test -n "$release"; then major= case $version_type in darwin) # we can't check for "0.0" in archive_cmds due to quoting # problems, so we reset it completely verstring= ;; *) verstring=0.0 ;; esac if test no = "$need_version"; then versuffix= else versuffix=.0.0 fi fi # Remove version info from name if versioning should be avoided if test yes,no = "$avoid_version,$need_version"; then major= versuffix= verstring= fi # Check to see if the archive will have undefined symbols. if test yes = "$allow_undefined"; then if test unsupported = "$allow_undefined_flag"; then if test yes = "$build_old_libs"; then func_warning "undefined symbols not allowed in $host shared libraries; building static only" build_libtool_libs=no else func_fatal_error "can't build $host shared library unless -no-undefined is specified" fi fi else # Don't allow undefined symbols. allow_undefined_flag=$no_undefined_flag fi fi func_generate_dlsyms "$libname" "$libname" : func_append libobjs " $symfileobj" test " " = "$libobjs" && libobjs= if test relink != "$opt_mode"; then # Remove our outputs, but don't remove object files since they # may have been created when compiling PIC objects. removelist= tempremovelist=`$ECHO "$output_objdir/*"` for p in $tempremovelist; do case $p in *.$objext | *.gcno) ;; $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/$libname$release.*) if test -n "$precious_files_regex"; then if $ECHO "$p" | $EGREP -e "$precious_files_regex" >/dev/null 2>&1 then continue fi fi func_append removelist " $p" ;; *) ;; esac done test -n "$removelist" && \ func_show_eval "${RM}r \$removelist" fi # Now set the variables for building old libraries. if test yes = "$build_old_libs" && test convenience != "$build_libtool_libs"; then func_append oldlibs " $output_objdir/$libname.$libext" # Transform .lo files to .o files. oldobjs="$objs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.$libext$/d; $lo2o" | $NL2SP` fi # Eliminate all temporary directories. #for path in $notinst_path; do # lib_search_path=`$ECHO "$lib_search_path " | $SED "s% $path % %g"` # deplibs=`$ECHO "$deplibs " | $SED "s% -L$path % %g"` # dependency_libs=`$ECHO "$dependency_libs " | $SED "s% -L$path % %g"` #done if test -n "$xrpath"; then # If the user specified any rpath flags, then add them. temp_xrpath= for libdir in $xrpath; do func_replace_sysroot "$libdir" func_append temp_xrpath " -R$func_replace_sysroot_result" case "$finalize_rpath " in *" $libdir "*) ;; *) func_append finalize_rpath " $libdir" ;; esac done if test yes != "$hardcode_into_libs" || test yes = "$build_old_libs"; then dependency_libs="$temp_xrpath $dependency_libs" fi fi # Make sure dlfiles contains only unique files that won't be dlpreopened old_dlfiles=$dlfiles dlfiles= for lib in $old_dlfiles; do case " $dlprefiles $dlfiles " in *" $lib "*) ;; *) func_append dlfiles " $lib" ;; esac done # Make sure dlprefiles contains only unique files old_dlprefiles=$dlprefiles dlprefiles= for lib in $old_dlprefiles; do case "$dlprefiles " in *" $lib "*) ;; *) func_append dlprefiles " $lib" ;; esac done if test yes = "$build_libtool_libs"; then if test -n "$rpath"; then case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos* | *-cegcc* | *-*-haiku*) # these systems don't actually have a c library (as such)! ;; *-*-rhapsody* | *-*-darwin1.[012]) # Rhapsody C library is in the System framework func_append deplibs " System.ltframework" ;; *-*-netbsd*) # Don't link with libc until the a.out ld.so is fixed. ;; *-*-openbsd* | *-*-freebsd* | *-*-dragonfly* | *-*-midnightbsd*) # Do not include libc due to us having libc/libc_r. ;; *-*-sco3.2v5* | *-*-sco5v6*) # Causes problems with __ctype ;; *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) # Compiler inserts libc in the correct place for threads to work ;; *) # Add libc to deplibs on all other systems if necessary. if test yes = "$build_libtool_need_lc"; then func_append deplibs " -lc" fi ;; esac fi # Transform deplibs into only deplibs that can be linked in shared. name_save=$name libname_save=$libname release_save=$release versuffix_save=$versuffix major_save=$major # I'm not sure if I'm treating the release correctly. I think # release should show up in the -l (ie -lgmp5) so we don't want to # add it in twice. Is that correct? release= versuffix= major= newdeplibs= droppeddeps=no case $deplibs_check_method in pass_all) # Don't check for shared/static. Everything works. # This might be a little naive. We might want to check # whether the library exists or not. But this is on # osf3 & osf4 and I'm not really sure... Just # implementing what was already the behavior. newdeplibs=$deplibs ;; test_compile) # This code stresses the "libraries are programs" paradigm to its # limits. Maybe even breaks it. We compile a program, linking it # against the deplibs as a proxy for the library. Then we can check # whether they linked in statically or dynamically with ldd. $opt_dry_run || $RM conftest.c cat > conftest.c </dev/null` $nocaseglob else potential_libs=`ls $i/$libnameglob[.-]* 2>/dev/null` fi for potent_lib in $potential_libs; do # Follow soft links. if ls -lLd "$potent_lib" 2>/dev/null | $GREP " -> " >/dev/null; then continue fi # The statement above tries to avoid entering an # endless loop below, in case of cyclic links. # We might still enter an endless loop, since a link # loop can be closed while we follow links, # but so what? potlib=$potent_lib while test -h "$potlib" 2>/dev/null; do potliblink=`ls -ld $potlib | $SED 's/.* -> //'` case $potliblink in [\\/]* | [A-Za-z]:[\\/]*) potlib=$potliblink;; *) potlib=`$ECHO "$potlib" | $SED 's|[^/]*$||'`"$potliblink";; esac done if eval $file_magic_cmd \"\$potlib\" 2>/dev/null | $SED -e 10q | $EGREP "$file_magic_regex" > /dev/null; then func_append newdeplibs " $a_deplib" a_deplib= break 2 fi done done fi if test -n "$a_deplib"; then droppeddeps=yes echo $ECHO "*** Warning: linker path does not have real file for library $a_deplib." echo "*** I have the capability to make that library automatically link in when" echo "*** you link to this library. But I can only do this if you have a" echo "*** shared version of the library, which you do not appear to have" echo "*** because I did check the linker path looking for a file starting" if test -z "$potlib"; then $ECHO "*** with $libname but no candidates were found. (...for file magic test)" else $ECHO "*** with $libname and none of the candidates passed a file format test" $ECHO "*** using a file magic. Last file checked: $potlib" fi fi ;; *) # Add a -L argument. func_append newdeplibs " $a_deplib" ;; esac done # Gone through all deplibs. ;; match_pattern*) set dummy $deplibs_check_method; shift match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` for a_deplib in $deplibs; do case $a_deplib in -l*) func_stripname -l '' "$a_deplib" name=$func_stripname_result if test yes = "$allow_libtool_libs_with_static_runtimes"; then case " $predeps $postdeps " in *" $a_deplib "*) func_append newdeplibs " $a_deplib" a_deplib= ;; esac fi if test -n "$a_deplib"; then libname=`eval "\\$ECHO \"$libname_spec\""` for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do potential_libs=`ls $i/$libname[.-]* 2>/dev/null` for potent_lib in $potential_libs; do potlib=$potent_lib # see symlink-check above in file_magic test if eval "\$ECHO \"$potent_lib\"" 2>/dev/null | $SED 10q | \ $EGREP "$match_pattern_regex" > /dev/null; then func_append newdeplibs " $a_deplib" a_deplib= break 2 fi done done fi if test -n "$a_deplib"; then droppeddeps=yes echo $ECHO "*** Warning: linker path does not have real file for library $a_deplib." echo "*** I have the capability to make that library automatically link in when" echo "*** you link to this library. But I can only do this if you have a" echo "*** shared version of the library, which you do not appear to have" echo "*** because I did check the linker path looking for a file starting" if test -z "$potlib"; then $ECHO "*** with $libname but no candidates were found. (...for regex pattern test)" else $ECHO "*** with $libname and none of the candidates passed a file format test" $ECHO "*** using a regex pattern. Last file checked: $potlib" fi fi ;; *) # Add a -L argument. func_append newdeplibs " $a_deplib" ;; esac done # Gone through all deplibs. ;; none | unknown | *) newdeplibs= tmp_deplibs=`$ECHO " $deplibs" | $SED 's/ -lc$//; s/ -[LR][^ ]*//g'` if test yes = "$allow_libtool_libs_with_static_runtimes"; then for i in $predeps $postdeps; do # can't use Xsed below, because $i might contain '/' tmp_deplibs=`$ECHO " $tmp_deplibs" | $SED "s|$i||"` done fi case $tmp_deplibs in *[!\ \ ]*) echo if test none = "$deplibs_check_method"; then echo "*** Warning: inter-library dependencies are not supported in this platform." else echo "*** Warning: inter-library dependencies are not known to be supported." fi echo "*** All declared inter-library dependencies are being dropped." droppeddeps=yes ;; esac ;; esac versuffix=$versuffix_save major=$major_save release=$release_save libname=$libname_save name=$name_save case $host in *-*-rhapsody* | *-*-darwin1.[012]) # On Rhapsody replace the C library with the System framework newdeplibs=`$ECHO " $newdeplibs" | $SED 's/ -lc / System.ltframework /'` ;; esac if test yes = "$droppeddeps"; then if test yes = "$module"; then echo echo "*** Warning: libtool could not satisfy all declared inter-library" $ECHO "*** dependencies of module $libname. Therefore, libtool will create" echo "*** a static module, that should work as long as the dlopening" echo "*** application is linked with the -dlopen flag." if test -z "$global_symbol_pipe"; then echo echo "*** However, this would only work if libtool was able to extract symbol" echo "*** lists from a program, using 'nm' or equivalent, but libtool could" echo "*** not find such a program. So, this module is probably useless." echo "*** 'nm' from GNU binutils and a full rebuild may help." fi if test no = "$build_old_libs"; then oldlibs=$output_objdir/$libname.$libext build_libtool_libs=module build_old_libs=yes else build_libtool_libs=no fi else echo "*** The inter-library dependencies that have been dropped here will be" echo "*** automatically added whenever a program is linked with this library" echo "*** or is declared to -dlopen it." if test no = "$allow_undefined"; then echo echo "*** Since this library must not contain undefined symbols," echo "*** because either the platform does not support them or" echo "*** it was explicitly requested with -no-undefined," echo "*** libtool will only create a static version of it." if test no = "$build_old_libs"; then oldlibs=$output_objdir/$libname.$libext build_libtool_libs=module build_old_libs=yes else build_libtool_libs=no fi fi fi fi # Done checking deplibs! deplibs=$newdeplibs fi # Time to change all our "foo.ltframework" stuff back to "-framework foo" case $host in *-*-darwin*) newdeplibs=`$ECHO " $newdeplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` new_inherited_linker_flags=`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` deplibs=`$ECHO " $deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` ;; esac # move library search paths that coincide with paths to not yet # installed libraries to the beginning of the library search list new_libs= for path in $notinst_path; do case " $new_libs " in *" -L$path/$objdir "*) ;; *) case " $deplibs " in *" -L$path/$objdir "*) func_append new_libs " -L$path/$objdir" ;; esac ;; esac done for deplib in $deplibs; do case $deplib in -L*) case " $new_libs " in *" $deplib "*) ;; *) func_append new_libs " $deplib" ;; esac ;; *) func_append new_libs " $deplib" ;; esac done deplibs=$new_libs # All the library-specific variables (install_libdir is set above). library_names= old_library= dlname= # Test again, we may have decided not to build it any more if test yes = "$build_libtool_libs"; then # Remove $wl instances when linking with ld. # FIXME: should test the right _cmds variable. case $archive_cmds in *\$LD\ *) wl= ;; esac if test yes = "$hardcode_into_libs"; then # Hardcode the library paths hardcode_libdirs= dep_rpath= rpath=$finalize_rpath test relink = "$opt_mode" || rpath=$compile_rpath$rpath for libdir in $rpath; do if test -n "$hardcode_libdir_flag_spec"; then if test -n "$hardcode_libdir_separator"; then func_replace_sysroot "$libdir" libdir=$func_replace_sysroot_result if test -z "$hardcode_libdirs"; then hardcode_libdirs=$libdir else # Just accumulate the unique libdirs. case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) ;; *) func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" ;; esac fi else eval flag=\"$hardcode_libdir_flag_spec\" func_append dep_rpath " $flag" fi elif test -n "$runpath_var"; then case "$perm_rpath " in *" $libdir "*) ;; *) func_append perm_rpath " $libdir" ;; esac fi done # Substitute the hardcoded libdirs into the rpath. if test -n "$hardcode_libdir_separator" && test -n "$hardcode_libdirs"; then libdir=$hardcode_libdirs eval "dep_rpath=\"$hardcode_libdir_flag_spec\"" fi if test -n "$runpath_var" && test -n "$perm_rpath"; then # We should set the runpath_var. rpath= for dir in $perm_rpath; do func_append rpath "$dir:" done eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var" fi test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs" fi shlibpath=$finalize_shlibpath test relink = "$opt_mode" || shlibpath=$compile_shlibpath$shlibpath if test -n "$shlibpath"; then eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var" fi # Get the real and link names of the library. eval shared_ext=\"$shrext_cmds\" eval library_names=\"$library_names_spec\" set dummy $library_names shift realname=$1 shift if test -n "$soname_spec"; then eval soname=\"$soname_spec\" else soname=$realname fi if test -z "$dlname"; then dlname=$soname fi lib=$output_objdir/$realname linknames= for link do func_append linknames " $link" done # Use standard objects if they are pic test -z "$pic_flag" && libobjs=`$ECHO "$libobjs" | $SP2NL | $SED "$lo2o" | $NL2SP` test "X$libobjs" = "X " && libobjs= delfiles= if test -n "$export_symbols" && test -n "$include_expsyms"; then $opt_dry_run || cp "$export_symbols" "$output_objdir/$libname.uexp" export_symbols=$output_objdir/$libname.uexp func_append delfiles " $export_symbols" fi orig_export_symbols= case $host_os in cygwin* | mingw* | cegcc*) if test -n "$export_symbols" && test -z "$export_symbols_regex"; then # exporting using user supplied symfile func_dll_def_p "$export_symbols" || { # and it's NOT already a .def file. Must figure out # which of the given symbols are data symbols and tag # them as such. So, trigger use of export_symbols_cmds. # export_symbols gets reassigned inside the "prepare # the list of exported symbols" if statement, so the # include_expsyms logic still works. orig_export_symbols=$export_symbols export_symbols= always_export_symbols=yes } fi ;; esac # Prepare the list of exported symbols if test -z "$export_symbols"; then if test yes = "$always_export_symbols" || test -n "$export_symbols_regex"; then func_verbose "generating symbol list for '$libname.la'" export_symbols=$output_objdir/$libname.exp $opt_dry_run || $RM $export_symbols cmds=$export_symbols_cmds save_ifs=$IFS; IFS='~' for cmd1 in $cmds; do IFS=$save_ifs # Take the normal branch if the nm_file_list_spec branch # doesn't work or if tool conversion is not needed. case $nm_file_list_spec~$to_tool_file_cmd in *~func_convert_file_noop | *~func_convert_file_msys_to_w32 | ~*) try_normal_branch=yes eval cmd=\"$cmd1\" func_len " $cmd" len=$func_len_result ;; *) try_normal_branch=no ;; esac if test yes = "$try_normal_branch" \ && { test "$len" -lt "$max_cmd_len" \ || test "$max_cmd_len" -le -1; } then func_show_eval "$cmd" 'exit $?' skipped_export=false elif test -n "$nm_file_list_spec"; then func_basename "$output" output_la=$func_basename_result save_libobjs=$libobjs save_output=$output output=$output_objdir/$output_la.nm func_to_tool_file "$output" libobjs=$nm_file_list_spec$func_to_tool_file_result func_append delfiles " $output" func_verbose "creating $NM input file list: $output" for obj in $save_libobjs; do func_to_tool_file "$obj" $ECHO "$func_to_tool_file_result" done > "$output" eval cmd=\"$cmd1\" func_show_eval "$cmd" 'exit $?' output=$save_output libobjs=$save_libobjs skipped_export=false else # The command line is too long to execute in one step. func_verbose "using reloadable object file for export list..." skipped_export=: # Break out early, otherwise skipped_export may be # set to false by a later but shorter cmd. break fi done IFS=$save_ifs if test -n "$export_symbols_regex" && test : != "$skipped_export"; then func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' func_show_eval '$MV "${export_symbols}T" "$export_symbols"' fi fi fi if test -n "$export_symbols" && test -n "$include_expsyms"; then tmp_export_symbols=$export_symbols test -n "$orig_export_symbols" && tmp_export_symbols=$orig_export_symbols $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"' fi if test : != "$skipped_export" && test -n "$orig_export_symbols"; then # The given exports_symbols file has to be filtered, so filter it. func_verbose "filter symbol list for '$libname.la' to tag DATA exports" # FIXME: $output_objdir/$libname.filter potentially contains lots of # 's' commands, which not all seds can handle. GNU sed should be fine # though. Also, the filter scales superlinearly with the number of # global variables. join(1) would be nice here, but unfortunately # isn't a blessed tool. $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter func_append delfiles " $export_symbols $output_objdir/$libname.filter" export_symbols=$output_objdir/$libname.def $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols fi tmp_deplibs= for test_deplib in $deplibs; do case " $convenience " in *" $test_deplib "*) ;; *) func_append tmp_deplibs " $test_deplib" ;; esac done deplibs=$tmp_deplibs if test -n "$convenience"; then if test -n "$whole_archive_flag_spec" && test yes = "$compiler_needs_object" && test -z "$libobjs"; then # extract the archives, so we have objects to list. # TODO: could optimize this to just extract one archive. whole_archive_flag_spec= fi if test -n "$whole_archive_flag_spec"; then save_libobjs=$libobjs eval libobjs=\"\$libobjs $whole_archive_flag_spec\" test "X$libobjs" = "X " && libobjs= else gentop=$output_objdir/${outputname}x func_append generated " $gentop" func_extract_archives $gentop $convenience func_append libobjs " $func_extract_archives_result" test "X$libobjs" = "X " && libobjs= fi fi if test yes = "$thread_safe" && test -n "$thread_safe_flag_spec"; then eval flag=\"$thread_safe_flag_spec\" func_append linker_flags " $flag" fi # Make a backup of the uninstalled library when relinking if test relink = "$opt_mode"; then $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}U && $MV $realname ${realname}U)' || exit $? fi # Do each of the archive commands. if test yes = "$module" && test -n "$module_cmds"; then if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then eval test_cmds=\"$module_expsym_cmds\" cmds=$module_expsym_cmds else eval test_cmds=\"$module_cmds\" cmds=$module_cmds fi else if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then eval test_cmds=\"$archive_expsym_cmds\" cmds=$archive_expsym_cmds else eval test_cmds=\"$archive_cmds\" cmds=$archive_cmds fi fi if test : != "$skipped_export" && func_len " $test_cmds" && len=$func_len_result && test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then : else # The command line is too long to link in one step, link piecewise # or, if using GNU ld and skipped_export is not :, use a linker # script. # Save the value of $output and $libobjs because we want to # use them later. If we have whole_archive_flag_spec, we # want to use save_libobjs as it was before # whole_archive_flag_spec was expanded, because we can't # assume the linker understands whole_archive_flag_spec. # This may have to be revisited, in case too many # convenience libraries get linked in and end up exceeding # the spec. if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then save_libobjs=$libobjs fi save_output=$output func_basename "$output" output_la=$func_basename_result # Clear the reloadable object creation command queue and # initialize k to one. test_cmds= concat_cmds= objlist= last_robj= k=1 if test -n "$save_libobjs" && test : != "$skipped_export" && test yes = "$with_gnu_ld"; then output=$output_objdir/$output_la.lnkscript func_verbose "creating GNU ld script: $output" echo 'INPUT (' > $output for obj in $save_libobjs do func_to_tool_file "$obj" $ECHO "$func_to_tool_file_result" >> $output done echo ')' >> $output func_append delfiles " $output" func_to_tool_file "$output" output=$func_to_tool_file_result elif test -n "$save_libobjs" && test : != "$skipped_export" && test -n "$file_list_spec"; then output=$output_objdir/$output_la.lnk func_verbose "creating linker input file list: $output" : > $output set x $save_libobjs shift firstobj= if test yes = "$compiler_needs_object"; then firstobj="$1 " shift fi for obj do func_to_tool_file "$obj" $ECHO "$func_to_tool_file_result" >> $output done func_append delfiles " $output" func_to_tool_file "$output" output=$firstobj\"$file_list_spec$func_to_tool_file_result\" else if test -n "$save_libobjs"; then func_verbose "creating reloadable object files..." output=$output_objdir/$output_la-$k.$objext eval test_cmds=\"$reload_cmds\" func_len " $test_cmds" len0=$func_len_result len=$len0 # Loop over the list of objects to be linked. for obj in $save_libobjs do func_len " $obj" func_arith $len + $func_len_result len=$func_arith_result if test -z "$objlist" || test "$len" -lt "$max_cmd_len"; then func_append objlist " $obj" else # The command $test_cmds is almost too long, add a # command to the queue. if test 1 -eq "$k"; then # The first file doesn't have a previous command to add. reload_objs=$objlist eval concat_cmds=\"$reload_cmds\" else # All subsequent reloadable object files will link in # the last one created. reload_objs="$objlist $last_robj" eval concat_cmds=\"\$concat_cmds~$reload_cmds~\$RM $last_robj\" fi last_robj=$output_objdir/$output_la-$k.$objext func_arith $k + 1 k=$func_arith_result output=$output_objdir/$output_la-$k.$objext objlist=" $obj" func_len " $last_robj" func_arith $len0 + $func_len_result len=$func_arith_result fi done # Handle the remaining objects by creating one last # reloadable object file. All subsequent reloadable object # files will link in the last one created. test -z "$concat_cmds" || concat_cmds=$concat_cmds~ reload_objs="$objlist $last_robj" eval concat_cmds=\"\$concat_cmds$reload_cmds\" if test -n "$last_robj"; then eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\" fi func_append delfiles " $output" else output= fi ${skipped_export-false} && { func_verbose "generating symbol list for '$libname.la'" export_symbols=$output_objdir/$libname.exp $opt_dry_run || $RM $export_symbols libobjs=$output # Append the command to create the export file. test -z "$concat_cmds" || concat_cmds=$concat_cmds~ eval concat_cmds=\"\$concat_cmds$export_symbols_cmds\" if test -n "$last_robj"; then eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\" fi } test -n "$save_libobjs" && func_verbose "creating a temporary reloadable object file: $output" # Loop through the commands generated above and execute them. save_ifs=$IFS; IFS='~' for cmd in $concat_cmds; do IFS=$save_ifs $opt_quiet || { func_quote_arg expand,pretty "$cmd" eval "func_echo $func_quote_arg_result" } $opt_dry_run || eval "$cmd" || { lt_exit=$? # Restore the uninstalled library and exit if test relink = "$opt_mode"; then ( cd "$output_objdir" && \ $RM "${realname}T" && \ $MV "${realname}U" "$realname" ) fi exit $lt_exit } done IFS=$save_ifs if test -n "$export_symbols_regex" && ${skipped_export-false}; then func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' func_show_eval '$MV "${export_symbols}T" "$export_symbols"' fi fi ${skipped_export-false} && { if test -n "$export_symbols" && test -n "$include_expsyms"; then tmp_export_symbols=$export_symbols test -n "$orig_export_symbols" && tmp_export_symbols=$orig_export_symbols $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"' fi if test -n "$orig_export_symbols"; then # The given exports_symbols file has to be filtered, so filter it. func_verbose "filter symbol list for '$libname.la' to tag DATA exports" # FIXME: $output_objdir/$libname.filter potentially contains lots of # 's' commands, which not all seds can handle. GNU sed should be fine # though. Also, the filter scales superlinearly with the number of # global variables. join(1) would be nice here, but unfortunately # isn't a blessed tool. $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter func_append delfiles " $export_symbols $output_objdir/$libname.filter" export_symbols=$output_objdir/$libname.def $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols fi } libobjs=$output # Restore the value of output. output=$save_output if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then eval libobjs=\"\$libobjs $whole_archive_flag_spec\" test "X$libobjs" = "X " && libobjs= fi # Expand the library linking commands again to reset the # value of $libobjs for piecewise linking. # Do each of the archive commands. if test yes = "$module" && test -n "$module_cmds"; then if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then cmds=$module_expsym_cmds else cmds=$module_cmds fi else if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then cmds=$archive_expsym_cmds else cmds=$archive_cmds fi fi fi if test -n "$delfiles"; then # Append the command to remove temporary files to $cmds. eval cmds=\"\$cmds~\$RM $delfiles\" fi # Add any objects from preloaded convenience libraries if test -n "$dlprefiles"; then gentop=$output_objdir/${outputname}x func_append generated " $gentop" func_extract_archives $gentop $dlprefiles func_append libobjs " $func_extract_archives_result" test "X$libobjs" = "X " && libobjs= fi save_ifs=$IFS; IFS='~' for cmd in $cmds; do IFS=$sp$nl eval cmd=\"$cmd\" IFS=$save_ifs $opt_quiet || { func_quote_arg expand,pretty "$cmd" eval "func_echo $func_quote_arg_result" } $opt_dry_run || eval "$cmd" || { lt_exit=$? # Restore the uninstalled library and exit if test relink = "$opt_mode"; then ( cd "$output_objdir" && \ $RM "${realname}T" && \ $MV "${realname}U" "$realname" ) fi exit $lt_exit } done IFS=$save_ifs # Restore the uninstalled library and exit if test relink = "$opt_mode"; then $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}T && $MV $realname ${realname}T && $MV ${realname}U $realname)' || exit $? if test -n "$convenience"; then if test -z "$whole_archive_flag_spec"; then func_show_eval '${RM}r "$gentop"' fi fi exit $EXIT_SUCCESS fi # Create links to the real library. for linkname in $linknames; do if test "$realname" != "$linkname"; then func_show_eval '(cd "$output_objdir" && $RM "$linkname" && $LN_S "$realname" "$linkname")' 'exit $?' fi done # If -module or -export-dynamic was specified, set the dlname. if test yes = "$module" || test yes = "$export_dynamic"; then # On all known operating systems, these are identical. dlname=$soname fi fi ;; obj) if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then func_warning "'-dlopen' is ignored for objects" fi case " $deplibs" in *\ -l* | *\ -L*) func_warning "'-l' and '-L' are ignored for objects" ;; esac test -n "$rpath" && \ func_warning "'-rpath' is ignored for objects" test -n "$xrpath" && \ func_warning "'-R' is ignored for objects" test -n "$vinfo" && \ func_warning "'-version-info' is ignored for objects" test -n "$release" && \ func_warning "'-release' is ignored for objects" case $output in *.lo) test -n "$objs$old_deplibs" && \ func_fatal_error "cannot build library object '$output' from non-libtool objects" libobj=$output func_lo2o "$libobj" obj=$func_lo2o_result ;; *) libobj= obj=$output ;; esac # Delete the old objects. $opt_dry_run || $RM $obj $libobj # Objects from convenience libraries. This assumes # single-version convenience libraries. Whenever we create # different ones for PIC/non-PIC, this we'll have to duplicate # the extraction. reload_conv_objs= gentop= # if reload_cmds runs $LD directly, get rid of -Wl from # whole_archive_flag_spec and hope we can get by with turning comma # into space. case $reload_cmds in *\$LD[\ \$]*) wl= ;; esac if test -n "$convenience"; then if test -n "$whole_archive_flag_spec"; then eval tmp_whole_archive_flags=\"$whole_archive_flag_spec\" test -n "$wl" || tmp_whole_archive_flags=`$ECHO "$tmp_whole_archive_flags" | $SED 's|,| |g'` reload_conv_objs=$reload_objs\ $tmp_whole_archive_flags else gentop=$output_objdir/${obj}x func_append generated " $gentop" func_extract_archives $gentop $convenience reload_conv_objs="$reload_objs $func_extract_archives_result" fi fi # If we're not building shared, we need to use non_pic_objs test yes = "$build_libtool_libs" || libobjs=$non_pic_objects # Create the old-style object. reload_objs=$objs$old_deplibs' '`$ECHO "$libobjs" | $SP2NL | $SED "/\.$libext$/d; /\.lib$/d; $lo2o" | $NL2SP`' '$reload_conv_objs output=$obj func_execute_cmds "$reload_cmds" 'exit $?' # Exit if we aren't doing a library object file. if test -z "$libobj"; then if test -n "$gentop"; then func_show_eval '${RM}r "$gentop"' fi exit $EXIT_SUCCESS fi test yes = "$build_libtool_libs" || { if test -n "$gentop"; then func_show_eval '${RM}r "$gentop"' fi # Create an invalid libtool object if no PIC, so that we don't # accidentally link it into a program. # $show "echo timestamp > $libobj" # $opt_dry_run || eval "echo timestamp > $libobj" || exit $? exit $EXIT_SUCCESS } if test -n "$pic_flag" || test default != "$pic_mode"; then # Only do commands if we really have different PIC objects. reload_objs="$libobjs $reload_conv_objs" output=$libobj func_execute_cmds "$reload_cmds" 'exit $?' fi if test -n "$gentop"; then func_show_eval '${RM}r "$gentop"' fi exit $EXIT_SUCCESS ;; prog) case $host in *cygwin*) func_stripname '' '.exe' "$output" output=$func_stripname_result.exe;; esac test -n "$vinfo" && \ func_warning "'-version-info' is ignored for programs" test -n "$release" && \ func_warning "'-release' is ignored for programs" $preload \ && test unknown,unknown,unknown = "$dlopen_support,$dlopen_self,$dlopen_self_static" \ && func_warning "'LT_INIT([dlopen])' not used. Assuming no dlopen support." case $host in *-*-rhapsody* | *-*-darwin1.[012]) # On Rhapsody replace the C library is the System framework compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's/ -lc / System.ltframework /'` finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's/ -lc / System.ltframework /'` ;; esac case $host in *-*-darwin*) # Don't allow lazy linking, it breaks C++ global constructors # But is supposedly fixed on 10.4 or later (yay!). if test CXX = "$tagname"; then case ${MACOSX_DEPLOYMENT_TARGET-10.0} in 10.[0123]) func_append compile_command " $wl-bind_at_load" func_append finalize_command " $wl-bind_at_load" ;; esac fi # Time to change all our "foo.ltframework" stuff back to "-framework foo" compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` ;; esac # move library search paths that coincide with paths to not yet # installed libraries to the beginning of the library search list new_libs= for path in $notinst_path; do case " $new_libs " in *" -L$path/$objdir "*) ;; *) case " $compile_deplibs " in *" -L$path/$objdir "*) func_append new_libs " -L$path/$objdir" ;; esac ;; esac done for deplib in $compile_deplibs; do case $deplib in -L*) case " $new_libs " in *" $deplib "*) ;; *) func_append new_libs " $deplib" ;; esac ;; *) func_append new_libs " $deplib" ;; esac done compile_deplibs=$new_libs func_append compile_command " $compile_deplibs" func_append finalize_command " $finalize_deplibs" if test -n "$rpath$xrpath"; then # If the user specified any rpath flags, then add them. for libdir in $rpath $xrpath; do # This is the magic to use -rpath. case "$finalize_rpath " in *" $libdir "*) ;; *) func_append finalize_rpath " $libdir" ;; esac done fi # Now hardcode the library paths rpath= hardcode_libdirs= for libdir in $compile_rpath $finalize_rpath; do if test -n "$hardcode_libdir_flag_spec"; then if test -n "$hardcode_libdir_separator"; then if test -z "$hardcode_libdirs"; then hardcode_libdirs=$libdir else # Just accumulate the unique libdirs. case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) ;; *) func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" ;; esac fi else eval flag=\"$hardcode_libdir_flag_spec\" func_append rpath " $flag" fi elif test -n "$runpath_var"; then case "$perm_rpath " in *" $libdir "*) ;; *) func_append perm_rpath " $libdir" ;; esac fi case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) testbindir=`$ECHO "$libdir" | $SED -e 's*/lib$*/bin*'` case :$dllsearchpath: in *":$libdir:"*) ;; ::) dllsearchpath=$libdir;; *) func_append dllsearchpath ":$libdir";; esac case :$dllsearchpath: in *":$testbindir:"*) ;; ::) dllsearchpath=$testbindir;; *) func_append dllsearchpath ":$testbindir";; esac ;; esac done # Substitute the hardcoded libdirs into the rpath. if test -n "$hardcode_libdir_separator" && test -n "$hardcode_libdirs"; then libdir=$hardcode_libdirs eval rpath=\" $hardcode_libdir_flag_spec\" fi compile_rpath=$rpath rpath= hardcode_libdirs= for libdir in $finalize_rpath; do if test -n "$hardcode_libdir_flag_spec"; then if test -n "$hardcode_libdir_separator"; then if test -z "$hardcode_libdirs"; then hardcode_libdirs=$libdir else # Just accumulate the unique libdirs. case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) ;; *) func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" ;; esac fi else eval flag=\"$hardcode_libdir_flag_spec\" func_append rpath " $flag" fi elif test -n "$runpath_var"; then case "$finalize_perm_rpath " in *" $libdir "*) ;; *) func_append finalize_perm_rpath " $libdir" ;; esac fi done # Substitute the hardcoded libdirs into the rpath. if test -n "$hardcode_libdir_separator" && test -n "$hardcode_libdirs"; then libdir=$hardcode_libdirs eval rpath=\" $hardcode_libdir_flag_spec\" fi finalize_rpath=$rpath if test -n "$libobjs" && test yes = "$build_old_libs"; then # Transform all the library objects into standard objects. compile_command=`$ECHO "$compile_command" | $SP2NL | $SED "$lo2o" | $NL2SP` finalize_command=`$ECHO "$finalize_command" | $SP2NL | $SED "$lo2o" | $NL2SP` fi func_generate_dlsyms "$outputname" "@PROGRAM@" false # template prelinking step if test -n "$prelink_cmds"; then func_execute_cmds "$prelink_cmds" 'exit $?' fi wrappers_required=: case $host in *cegcc* | *mingw32ce*) # Disable wrappers for cegcc and mingw32ce hosts, we are cross compiling anyway. wrappers_required=false ;; *cygwin* | *mingw* ) test yes = "$build_libtool_libs" || wrappers_required=false ;; *) if test no = "$need_relink" || test yes != "$build_libtool_libs"; then wrappers_required=false fi ;; esac $wrappers_required || { # Replace the output file specification. compile_command=`$ECHO "$compile_command" | $SED 's%@OUTPUT@%'"$output"'%g'` link_command=$compile_command$compile_rpath # We have no uninstalled library dependencies, so finalize right now. exit_status=0 func_show_eval "$link_command" 'exit_status=$?' if test -n "$postlink_cmds"; then func_to_tool_file "$output" postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` func_execute_cmds "$postlink_cmds" 'exit $?' fi # Delete the generated files. if test -f "$output_objdir/${outputname}S.$objext"; then func_show_eval '$RM "$output_objdir/${outputname}S.$objext"' fi exit $exit_status } if test -n "$compile_shlibpath$finalize_shlibpath"; then compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command" fi if test -n "$finalize_shlibpath"; then finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command" fi compile_var= finalize_var= if test -n "$runpath_var"; then if test -n "$perm_rpath"; then # We should set the runpath_var. rpath= for dir in $perm_rpath; do func_append rpath "$dir:" done compile_var="$runpath_var=\"$rpath\$$runpath_var\" " fi if test -n "$finalize_perm_rpath"; then # We should set the runpath_var. rpath= for dir in $finalize_perm_rpath; do func_append rpath "$dir:" done finalize_var="$runpath_var=\"$rpath\$$runpath_var\" " fi fi if test yes = "$no_install"; then # We don't need to create a wrapper script. link_command=$compile_var$compile_command$compile_rpath # Replace the output file specification. link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output"'%g'` # Delete the old output file. $opt_dry_run || $RM $output # Link the executable and exit func_show_eval "$link_command" 'exit $?' if test -n "$postlink_cmds"; then func_to_tool_file "$output" postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` func_execute_cmds "$postlink_cmds" 'exit $?' fi exit $EXIT_SUCCESS fi case $hardcode_action,$fast_install in relink,*) # Fast installation is not supported link_command=$compile_var$compile_command$compile_rpath relink_command=$finalize_var$finalize_command$finalize_rpath func_warning "this platform does not like uninstalled shared libraries" func_warning "'$output' will be relinked during installation" ;; *,yes) link_command=$finalize_var$compile_command$finalize_rpath relink_command=`$ECHO "$compile_var$compile_command$compile_rpath" | $SED 's%@OUTPUT@%\$progdir/\$file%g'` ;; *,no) link_command=$compile_var$compile_command$compile_rpath relink_command=$finalize_var$finalize_command$finalize_rpath ;; *,needless) link_command=$finalize_var$compile_command$finalize_rpath relink_command= ;; esac # Replace the output file specification. link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'` # Delete the old output files. $opt_dry_run || $RM $output $output_objdir/$outputname $output_objdir/lt-$outputname func_show_eval "$link_command" 'exit $?' if test -n "$postlink_cmds"; then func_to_tool_file "$output_objdir/$outputname" postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` func_execute_cmds "$postlink_cmds" 'exit $?' fi # Now create the wrapper script. func_verbose "creating $output" # Quote the relink command for shipping. if test -n "$relink_command"; then # Preserve any variables that may affect compiler behavior for var in $variables_saved_for_relink; do if eval test -z \"\${$var+set}\"; then relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" elif eval var_value=\$$var; test -z "$var_value"; then relink_command="$var=; export $var; $relink_command" else func_quote_arg pretty "$var_value" relink_command="$var=$func_quote_arg_result; export $var; $relink_command" fi done func_quote eval cd "`pwd`" func_quote_arg pretty,unquoted "($func_quote_result; $relink_command)" relink_command=$func_quote_arg_unquoted_result fi # Only actually do things if not in dry run mode. $opt_dry_run || { # win32 will think the script is a binary if it has # a .exe suffix, so we strip it off here. case $output in *.exe) func_stripname '' '.exe' "$output" output=$func_stripname_result ;; esac # test for cygwin because mv fails w/o .exe extensions case $host in *cygwin*) exeext=.exe func_stripname '' '.exe' "$outputname" outputname=$func_stripname_result ;; *) exeext= ;; esac case $host in *cygwin* | *mingw* ) func_dirname_and_basename "$output" "" "." output_name=$func_basename_result output_path=$func_dirname_result cwrappersource=$output_path/$objdir/lt-$output_name.c cwrapper=$output_path/$output_name.exe $RM $cwrappersource $cwrapper trap "$RM $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15 func_emit_cwrapperexe_src > $cwrappersource # The wrapper executable is built using the $host compiler, # because it contains $host paths and files. If cross- # compiling, it, like the target executable, must be # executed on the $host or under an emulation environment. $opt_dry_run || { $LTCC $LTCFLAGS -o $cwrapper $cwrappersource $STRIP $cwrapper } # Now, create the wrapper script for func_source use: func_ltwrapper_scriptname $cwrapper $RM $func_ltwrapper_scriptname_result trap "$RM $func_ltwrapper_scriptname_result; exit $EXIT_FAILURE" 1 2 15 $opt_dry_run || { # note: this script will not be executed, so do not chmod. if test "x$build" = "x$host"; then $cwrapper --lt-dump-script > $func_ltwrapper_scriptname_result else func_emit_wrapper no > $func_ltwrapper_scriptname_result fi } ;; * ) $RM $output trap "$RM $output; exit $EXIT_FAILURE" 1 2 15 func_emit_wrapper no > $output chmod +x $output ;; esac } exit $EXIT_SUCCESS ;; esac # See if we need to build an old-fashioned archive. for oldlib in $oldlibs; do case $build_libtool_libs in convenience) oldobjs="$libobjs_save $symfileobj" addlibs=$convenience build_libtool_libs=no ;; module) oldobjs=$libobjs_save addlibs=$old_convenience build_libtool_libs=no ;; *) oldobjs="$old_deplibs $non_pic_objects" $preload && test -f "$symfileobj" \ && func_append oldobjs " $symfileobj" addlibs=$old_convenience ;; esac if test -n "$addlibs"; then gentop=$output_objdir/${outputname}x func_append generated " $gentop" func_extract_archives $gentop $addlibs func_append oldobjs " $func_extract_archives_result" fi # Do each command in the archive commands. if test -n "$old_archive_from_new_cmds" && test yes = "$build_libtool_libs"; then cmds=$old_archive_from_new_cmds else # Add any objects from preloaded convenience libraries if test -n "$dlprefiles"; then gentop=$output_objdir/${outputname}x func_append generated " $gentop" func_extract_archives $gentop $dlprefiles func_append oldobjs " $func_extract_archives_result" fi # POSIX demands no paths to be encoded in archives. We have # to avoid creating archives with duplicate basenames if we # might have to extract them afterwards, e.g., when creating a # static archive out of a convenience library, or when linking # the entirety of a libtool archive into another (currently # not supported by libtool). if (for obj in $oldobjs do func_basename "$obj" $ECHO "$func_basename_result" done | sort | sort -uc >/dev/null 2>&1); then : else echo "copying selected object files to avoid basename conflicts..." gentop=$output_objdir/${outputname}x func_append generated " $gentop" func_mkdir_p "$gentop" save_oldobjs=$oldobjs oldobjs= counter=1 for obj in $save_oldobjs do func_basename "$obj" objbase=$func_basename_result case " $oldobjs " in " ") oldobjs=$obj ;; *[\ /]"$objbase "*) while :; do # Make sure we don't pick an alternate name that also # overlaps. newobj=lt$counter-$objbase func_arith $counter + 1 counter=$func_arith_result case " $oldobjs " in *[\ /]"$newobj "*) ;; *) if test ! -f "$gentop/$newobj"; then break; fi ;; esac done func_show_eval "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj" func_append oldobjs " $gentop/$newobj" ;; *) func_append oldobjs " $obj" ;; esac done fi func_to_tool_file "$oldlib" func_convert_file_msys_to_w32 tool_oldlib=$func_to_tool_file_result eval cmds=\"$old_archive_cmds\" func_len " $cmds" len=$func_len_result if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then cmds=$old_archive_cmds elif test -n "$archiver_list_spec"; then func_verbose "using command file archive linking..." for obj in $oldobjs do func_to_tool_file "$obj" $ECHO "$func_to_tool_file_result" done > $output_objdir/$libname.libcmd func_to_tool_file "$output_objdir/$libname.libcmd" oldobjs=" $archiver_list_spec$func_to_tool_file_result" cmds=$old_archive_cmds else # the command line is too long to link in one step, link in parts func_verbose "using piecewise archive linking..." save_RANLIB=$RANLIB RANLIB=: objlist= concat_cmds= save_oldobjs=$oldobjs oldobjs= # Is there a better way of finding the last object in the list? for obj in $save_oldobjs do last_oldobj=$obj done eval test_cmds=\"$old_archive_cmds\" func_len " $test_cmds" len0=$func_len_result len=$len0 for obj in $save_oldobjs do func_len " $obj" func_arith $len + $func_len_result len=$func_arith_result func_append objlist " $obj" if test "$len" -lt "$max_cmd_len"; then : else # the above command should be used before it gets too long oldobjs=$objlist if test "$obj" = "$last_oldobj"; then RANLIB=$save_RANLIB fi test -z "$concat_cmds" || concat_cmds=$concat_cmds~ eval concat_cmds=\"\$concat_cmds$old_archive_cmds\" objlist= len=$len0 fi done RANLIB=$save_RANLIB oldobjs=$objlist if test -z "$oldobjs"; then eval cmds=\"\$concat_cmds\" else eval cmds=\"\$concat_cmds~\$old_archive_cmds\" fi fi fi func_execute_cmds "$cmds" 'exit $?' done test -n "$generated" && \ func_show_eval "${RM}r$generated" # Now create the libtool archive. case $output in *.la) old_library= test yes = "$build_old_libs" && old_library=$libname.$libext func_verbose "creating $output" # Preserve any variables that may affect compiler behavior for var in $variables_saved_for_relink; do if eval test -z \"\${$var+set}\"; then relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" elif eval var_value=\$$var; test -z "$var_value"; then relink_command="$var=; export $var; $relink_command" else func_quote_arg pretty,unquoted "$var_value" relink_command="$var=$func_quote_arg_unquoted_result; export $var; $relink_command" fi done # Quote the link command for shipping. func_quote eval cd "`pwd`" relink_command="($func_quote_result; $SHELL \"$progpath\" $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)" func_quote_arg pretty,unquoted "$relink_command" relink_command=$func_quote_arg_unquoted_result if test yes = "$hardcode_automatic"; then relink_command= fi # Only create the output if not a dry run. $opt_dry_run || { for installed in no yes; do if test yes = "$installed"; then if test -z "$install_libdir"; then break fi output=$output_objdir/${outputname}i # Replace all uninstalled libtool libraries with the installed ones newdependency_libs= for deplib in $dependency_libs; do case $deplib in *.la) func_basename "$deplib" name=$func_basename_result func_resolve_sysroot "$deplib" eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $func_resolve_sysroot_result` test -z "$libdir" && \ func_fatal_error "'$deplib' is not a valid libtool archive" func_append newdependency_libs " ${lt_sysroot:+=}$libdir/$name" ;; -L*) func_stripname -L '' "$deplib" func_replace_sysroot "$func_stripname_result" func_append newdependency_libs " -L$func_replace_sysroot_result" ;; -R*) func_stripname -R '' "$deplib" func_replace_sysroot "$func_stripname_result" func_append newdependency_libs " -R$func_replace_sysroot_result" ;; *) func_append newdependency_libs " $deplib" ;; esac done dependency_libs=$newdependency_libs newdlfiles= for lib in $dlfiles; do case $lib in *.la) func_basename "$lib" name=$func_basename_result eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $lib` test -z "$libdir" && \ func_fatal_error "'$lib' is not a valid libtool archive" func_append newdlfiles " ${lt_sysroot:+=}$libdir/$name" ;; *) func_append newdlfiles " $lib" ;; esac done dlfiles=$newdlfiles newdlprefiles= for lib in $dlprefiles; do case $lib in *.la) # Only pass preopened files to the pseudo-archive (for # eventual linking with the app. that links it) if we # didn't already link the preopened objects directly into # the library: func_basename "$lib" name=$func_basename_result eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $lib` test -z "$libdir" && \ func_fatal_error "'$lib' is not a valid libtool archive" func_append newdlprefiles " ${lt_sysroot:+=}$libdir/$name" ;; esac done dlprefiles=$newdlprefiles else newdlfiles= for lib in $dlfiles; do case $lib in [\\/]* | [A-Za-z]:[\\/]*) abs=$lib ;; *) abs=`pwd`"/$lib" ;; esac func_append newdlfiles " $abs" done dlfiles=$newdlfiles newdlprefiles= for lib in $dlprefiles; do case $lib in [\\/]* | [A-Za-z]:[\\/]*) abs=$lib ;; *) abs=`pwd`"/$lib" ;; esac func_append newdlprefiles " $abs" done dlprefiles=$newdlprefiles fi $RM $output # place dlname in correct position for cygwin # In fact, it would be nice if we could use this code for all target # systems that can't hard-code library paths into their executables # and that have no shared library path variable independent of PATH, # but it turns out we can't easily determine that from inspecting # libtool variables, so we have to hard-code the OSs to which it # applies here; at the moment, that means platforms that use the PE # object format with DLL files. See the long comment at the top of # tests/bindir.at for full details. tdlname=$dlname case $host,$output,$installed,$module,$dlname in *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll | *cegcc*,*lai,yes,no,*.dll) # If a -bindir argument was supplied, place the dll there. if test -n "$bindir"; then func_relative_path "$install_libdir" "$bindir" tdlname=$func_relative_path_result/$dlname else # Otherwise fall back on heuristic. tdlname=../bin/$dlname fi ;; esac $ECHO > $output "\ # $outputname - a libtool library file # Generated by $PROGRAM (GNU $PACKAGE) $VERSION # # Please DO NOT delete this file! # It is necessary for linking the library. # The name that we can dlopen(3). dlname='$tdlname' # Names of this library. library_names='$library_names' # The name of the static archive. old_library='$old_library' # Linker flags that cannot go in dependency_libs. inherited_linker_flags='$new_inherited_linker_flags' # Libraries that this one depends upon. dependency_libs='$dependency_libs' # Names of additional weak libraries provided by this library weak_library_names='$weak_libs' # Version information for $libname. current=$current age=$age revision=$revision # Is this an already installed library? installed=$installed # Should we warn about portability when linking against -modules? shouldnotlink=$module # Files to dlopen/dlpreopen dlopen='$dlfiles' dlpreopen='$dlprefiles' # Directory that this library needs to be installed in: libdir='$install_libdir'" if test no,yes = "$installed,$need_relink"; then $ECHO >> $output "\ relink_command=\"$relink_command\"" fi done } # Do a symbolic link so that the libtool archive can be found in # LD_LIBRARY_PATH before the program is installed. func_show_eval '( cd "$output_objdir" && $RM "$outputname" && $LN_S "../$outputname" "$outputname" )' 'exit $?' ;; esac exit $EXIT_SUCCESS } if test link = "$opt_mode" || test relink = "$opt_mode"; then func_mode_link ${1+"$@"} fi # func_mode_uninstall arg... func_mode_uninstall () { $debug_cmd RM=$nonopt files= rmforce=false exit_status=0 # This variable tells wrapper scripts just to set variables rather # than running their programs. libtool_install_magic=$magic for arg do case $arg in -f) func_append RM " $arg"; rmforce=: ;; -*) func_append RM " $arg" ;; *) func_append files " $arg" ;; esac done test -z "$RM" && \ func_fatal_help "you must specify an RM program" rmdirs= for file in $files; do func_dirname "$file" "" "." dir=$func_dirname_result if test . = "$dir"; then odir=$objdir else odir=$dir/$objdir fi func_basename "$file" name=$func_basename_result test uninstall = "$opt_mode" && odir=$dir # Remember odir for removal later, being careful to avoid duplicates if test clean = "$opt_mode"; then case " $rmdirs " in *" $odir "*) ;; *) func_append rmdirs " $odir" ;; esac fi # Don't error if the file doesn't exist and rm -f was used. if { test -L "$file"; } >/dev/null 2>&1 || { test -h "$file"; } >/dev/null 2>&1 || test -f "$file"; then : elif test -d "$file"; then exit_status=1 continue elif $rmforce; then continue fi rmfiles=$file case $name in *.la) # Possibly a libtool archive, so verify it. if func_lalib_p "$file"; then func_source $dir/$name # Delete the libtool libraries and symlinks. for n in $library_names; do func_append rmfiles " $odir/$n" done test -n "$old_library" && func_append rmfiles " $odir/$old_library" case $opt_mode in clean) case " $library_names " in *" $dlname "*) ;; *) test -n "$dlname" && func_append rmfiles " $odir/$dlname" ;; esac test -n "$libdir" && func_append rmfiles " $odir/$name $odir/${name}i" ;; uninstall) if test -n "$library_names"; then # Do each command in the postuninstall commands. func_execute_cmds "$postuninstall_cmds" '$rmforce || exit_status=1' fi if test -n "$old_library"; then # Do each command in the old_postuninstall commands. func_execute_cmds "$old_postuninstall_cmds" '$rmforce || exit_status=1' fi # FIXME: should reinstall the best remaining shared library. ;; esac fi ;; *.lo) # Possibly a libtool object, so verify it. if func_lalib_p "$file"; then # Read the .lo file func_source $dir/$name # Add PIC object to the list of files to remove. if test -n "$pic_object" && test none != "$pic_object"; then func_append rmfiles " $dir/$pic_object" fi # Add non-PIC object to the list of files to remove. if test -n "$non_pic_object" && test none != "$non_pic_object"; then func_append rmfiles " $dir/$non_pic_object" fi fi ;; *) if test clean = "$opt_mode"; then noexename=$name case $file in *.exe) func_stripname '' '.exe' "$file" file=$func_stripname_result func_stripname '' '.exe' "$name" noexename=$func_stripname_result # $file with .exe has already been added to rmfiles, # add $file without .exe func_append rmfiles " $file" ;; esac # Do a test to see if this is a libtool program. if func_ltwrapper_p "$file"; then if func_ltwrapper_executable_p "$file"; then func_ltwrapper_scriptname "$file" relink_command= func_source $func_ltwrapper_scriptname_result func_append rmfiles " $func_ltwrapper_scriptname_result" else relink_command= func_source $dir/$noexename fi # note $name still contains .exe if it was in $file originally # as does the version of $file that was added into $rmfiles func_append rmfiles " $odir/$name $odir/${name}S.$objext" if test yes = "$fast_install" && test -n "$relink_command"; then func_append rmfiles " $odir/lt-$name" fi if test "X$noexename" != "X$name"; then func_append rmfiles " $odir/lt-$noexename.c" fi fi fi ;; esac func_show_eval "$RM $rmfiles" 'exit_status=1' done # Try to remove the $objdir's in the directories where we deleted files for dir in $rmdirs; do if test -d "$dir"; then func_show_eval "rmdir $dir >/dev/null 2>&1" fi done exit $exit_status } if test uninstall = "$opt_mode" || test clean = "$opt_mode"; then func_mode_uninstall ${1+"$@"} fi test -z "$opt_mode" && { help=$generic_help func_fatal_help "you must specify a MODE" } test -z "$exec_cmd" && \ func_fatal_help "invalid operation mode '$opt_mode'" if test -n "$exec_cmd"; then eval exec "$exec_cmd" exit $EXIT_FAILURE fi exit $exit_status # The TAGs below are defined such that we never get into a situation # where we disable both kinds of libraries. Given conflicting # choices, we go for a static library, that is the most portable, # since we can't tell whether shared libraries were disabled because # the user asked for that or because the platform doesn't support # them. This is particularly important on AIX, because we don't # support having both static and shared libraries enabled at the same # time on that platform, so we default to a shared-only configuration. # If a disable-shared tag is given, we'll fallback to a static-only # configuration. But we'll never go from static-only to shared-only. # ### BEGIN LIBTOOL TAG CONFIG: disable-shared build_libtool_libs=no build_old_libs=yes # ### END LIBTOOL TAG CONFIG: disable-shared # ### BEGIN LIBTOOL TAG CONFIG: disable-static build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac` # ### END LIBTOOL TAG CONFIG: disable-static # Local Variables: # mode:shell-script # sh-indentation:2 # End: ppp-2.5.0/missing0000755000175000017500000001533614072725711010653 00000000000000#! /bin/sh # Common wrapper for a few potentially missing GNU programs. scriptversion=2018-03-07.03; # UTC # Copyright (C) 1996-2021 Free Software Foundation, Inc. # Originally written by Fran,cois Pinard , 1996. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program. If not, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. if test $# -eq 0; then echo 1>&2 "Try '$0 --help' for more information" exit 1 fi case $1 in --is-lightweight) # Used by our autoconf macros to check whether the available missing # script is modern enough. exit 0 ;; --run) # Back-compat with the calling convention used by older automake. shift ;; -h|--h|--he|--hel|--help) echo "\ $0 [OPTION]... PROGRAM [ARGUMENT]... Run 'PROGRAM [ARGUMENT]...', returning a proper advice when this fails due to PROGRAM being missing or too old. Options: -h, --help display this help and exit -v, --version output version information and exit Supported PROGRAM values: aclocal autoconf autoheader autom4te automake makeinfo bison yacc flex lex help2man Version suffixes to PROGRAM as well as the prefixes 'gnu-', 'gnu', and 'g' are ignored when checking the name. Send bug reports to ." exit $? ;; -v|--v|--ve|--ver|--vers|--versi|--versio|--version) echo "missing $scriptversion (GNU Automake)" exit $? ;; -*) echo 1>&2 "$0: unknown '$1' option" echo 1>&2 "Try '$0 --help' for more information" exit 1 ;; esac # Run the given program, remember its exit status. "$@"; st=$? # If it succeeded, we are done. test $st -eq 0 && exit 0 # Also exit now if we it failed (or wasn't found), and '--version' was # passed; such an option is passed most likely to detect whether the # program is present and works. case $2 in --version|--help) exit $st;; esac # Exit code 63 means version mismatch. This often happens when the user # tries to use an ancient version of a tool on a file that requires a # minimum version. if test $st -eq 63; then msg="probably too old" elif test $st -eq 127; then # Program was missing. msg="missing on your system" else # Program was found and executed, but failed. Give up. exit $st fi perl_URL=https://www.perl.org/ flex_URL=https://github.com/westes/flex gnu_software_URL=https://www.gnu.org/software program_details () { case $1 in aclocal|automake) echo "The '$1' program is part of the GNU Automake package:" echo "<$gnu_software_URL/automake>" echo "It also requires GNU Autoconf, GNU m4 and Perl in order to run:" echo "<$gnu_software_URL/autoconf>" echo "<$gnu_software_URL/m4/>" echo "<$perl_URL>" ;; autoconf|autom4te|autoheader) echo "The '$1' program is part of the GNU Autoconf package:" echo "<$gnu_software_URL/autoconf/>" echo "It also requires GNU m4 and Perl in order to run:" echo "<$gnu_software_URL/m4/>" echo "<$perl_URL>" ;; esac } give_advice () { # Normalize program name to check for. normalized_program=`echo "$1" | sed ' s/^gnu-//; t s/^gnu//; t s/^g//; t'` printf '%s\n' "'$1' is $msg." configure_deps="'configure.ac' or m4 files included by 'configure.ac'" case $normalized_program in autoconf*) echo "You should only need it if you modified 'configure.ac'," echo "or m4 files included by it." program_details 'autoconf' ;; autoheader*) echo "You should only need it if you modified 'acconfig.h' or" echo "$configure_deps." program_details 'autoheader' ;; automake*) echo "You should only need it if you modified 'Makefile.am' or" echo "$configure_deps." program_details 'automake' ;; aclocal*) echo "You should only need it if you modified 'acinclude.m4' or" echo "$configure_deps." program_details 'aclocal' ;; autom4te*) echo "You might have modified some maintainer files that require" echo "the 'autom4te' program to be rebuilt." program_details 'autom4te' ;; bison*|yacc*) echo "You should only need it if you modified a '.y' file." echo "You may want to install the GNU Bison package:" echo "<$gnu_software_URL/bison/>" ;; lex*|flex*) echo "You should only need it if you modified a '.l' file." echo "You may want to install the Fast Lexical Analyzer package:" echo "<$flex_URL>" ;; help2man*) echo "You should only need it if you modified a dependency" \ "of a man page." echo "You may want to install the GNU Help2man package:" echo "<$gnu_software_URL/help2man/>" ;; makeinfo*) echo "You should only need it if you modified a '.texi' file, or" echo "any other file indirectly affecting the aspect of the manual." echo "You might want to install the Texinfo package:" echo "<$gnu_software_URL/texinfo/>" echo "The spurious makeinfo call might also be the consequence of" echo "using a buggy 'make' (AIX, DU, IRIX), in which case you might" echo "want to install GNU make:" echo "<$gnu_software_URL/make/>" ;; *) echo "You might have modified some files without having the proper" echo "tools for further handling them. Check the 'README' file, it" echo "often tells you about the needed prerequisites for installing" echo "this package. You may also peek at any GNU archive site, in" echo "case some other package contains this missing '$1' program." ;; esac } give_advice "$1" | sed -e '1s/^/WARNING: /' \ -e '2,$s/^/ /' >&2 # Propagate the correct exit status (expected to be 127 for a program # not found, 63 for a program that failed due to version mismatch). exit $st # Local variables: # eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC0" # time-stamp-end: "; # UTC" # End: ppp-2.5.0/Changes-2.30000644000175000017500000004336207075316623011052 00000000000000What was new in ppp-2.3.11. *************************** * Support for Solaris 8 has been added, including support for replumbing and IPV6. * The Solaris `snoop' utility should now work on ppp interfaces. * New hooks have been added - pap_logout_hook, ip_up_hook, and ip_down_hook. * A new `passprompt' plugin is included, thanks to Alan Curry, which makes it possible for pppd to call an external program to get the PAP password to send to the peer. * The error messages for the situation where authentication is required because the system has a default route have been improved. * There is a new connect_delay option which specifies how long pppd should pause after the connect script finishes. Previously this delay was fixed at 1 second. (This delay terminates as soon as pppd sees a valid PPP frame from the peer.) * The `hide-password' option is now the default, and there is a new `show-password' option to enable the printing of password strings in the debug output. * A fairly complete list of the names of PPP protocols has been added so that when pppd rejects a frame because its protocol is not supported, it can print the name of the unsupported protocol. * Synchronous serial lines are supported under Linux 2.3.x. * The bug where pppd would not recognize a modem hangup under Linux 2.3.x kernels has been fixed. What was new in ppp-2.3.10. *************************** * Pppd now supports `plugins', which are pieces of code (packaged as shared libraries) which can be loaded into pppd at runtime and which can affect its behaviour. The intention is that plugins provide a way for people to customize the behaviour of pppd for their own needs without needing to change the base pppd source. I have added some hooks into pppd (places where pppd will call a function pointer, if non-zero, to replace some of pppd's code) and I will be receptive to suggestions about places to add more hooks. Plugins are supported under Linux and Solaris at present. * We have a new maintainer for the Solaris port, Adi Masputra of Sun Microsystems, and he has updated the Solaris port so that it should work on 64-bit machines under Solaris 7 and later. * Pppd now has an `allow-ip' option, which takes an argument which is an IP address (or subnet) which peers are permitted to use without authenticating themselves. The argument takes the same form as each element of the allowed IP address list in the secrets files. The allow-ip option is privileged and may be specified multiple times. Using the allow-ip option should be cleaner than putting a line like `"" * "" address' in /etc/ppp/pap-secrets. * Chat can now substitute environment variables into the script. This is enabled by the -E flag. (Thanks to Andreas Arens for the patch.) * If the PAP username and password from the peer contains unprintable characters, they will be translated to a printable form before looking in the pap-secrets file. Characters >= 0x80 are translated to a M- form, and characters from 0 to 0x1f (and 0x7f as well) are translated to a ^X form. If this change causes you grief, let me know what would be a better translation. It appears that some peers send nulls or other control characters in their usernames and passwords. * Pppd has new `ktune' and `noktune' options, which enable/disable it to change kernel settings as appropriate. This is only implemented under Linux, and requires the /proc filesystem to be mounted. Under Linux, with the ktune option, pppd will enable IP forwarding in the kernel if the proxyarp option is used, and will enable the dynamic IP address kernel option in demand mode if the local IP address changes. * Pppd no longer requires a remote address to be specified for demand dialling. If none is specified, it will use a default value of 10.112.112.112+unit_number. (It will not propose this default to the peer.) * The default holdoff is now 0 if no connect script is given. * The IPV6 code from Tommi Komulainen, which I unfortunately only partially merged in to ppp-2.3.9, has been fixed and updated. * The linux compilation glitches should be fixed now. What was new in ppp-2.3.9. ************************** * Support for the new generic PPP layer under development for the Linux kernel. * You can now place extra options to apply to specific users at the end of the line with their password in the pap-secrets or chap-secrets file, separated from the IP address(es) with a "--" separator. These options are parsed after the peer is authenticated but before network protocol (IPCP, IPXCP) or CCP negotiation commences. * Pppd will apply the holdoff period if the link was terminated by the peer. It doesn't apply it if the link was terminated because the local pppd thought it was idle. * Synchronous support for Solaris has been added, thanks to John Morrison, and for FreeBSD, thanks to Paul Fulghum. * IPV6 support has been merged in, from Tommi Komulainen. At the moment it only supports Linux and it is not tested by me. * The `nodefaultip' option can be used in demand mode to say that pppd should not suggest its local IP address to the peer. * The `init' option has been added; this causes pppd to run a script to initialize the serial device (e.g. by sending an init string to the modem). Unlike the connect option, this can be used in a dial-in situation. (Thanks to Tobias Ringstrom.) * There is a new `logfile' option to send log messages to a file as well as syslog. * There is a new, privileged `linkname' option which sets a logical name for the link. Pppd will create a /var/run/ppp-.pid file containing its process ID. * There is a new `maxfail' option which specifies how many consecutive failed connection attempts are permitted before pppd will exit. The default value is 10, and 0 means infinity. :-) * Sundry bugs fixed. What was new in ppp-2.3.8. ************************** * The exit status of pppd will now indicate whether the link was successfully established, or if not, what error was encountered. * Pppd has two new options: fdlog will send log messages to file descriptor instead of standard output, and nofdlog will stop log messages from being sent to any file descriptor (they will still be sent to syslog). Pppd now will not send log messages to a file descriptor if the serial port is open on that file descriptor. * Pppd sets an environment variable called PPPLOGNAME for scripts that it runs, indicating the login name of the user who invoked pppd. * Pppd sets environment variables CONNECT_TIME, BYTES_SENT and BYTES_RCVD for the ip-down and auth-down scripts indicating the statistics for the connection just terminated. (CONNECT_TIME is in seconds.) * If the user has the serial device open on standard input and specifies a symbolic link to the serial device on the command line, pppd will detect this and behave correctly (i.e. not detach from its controlling terminal). Furthermore, if the serial port is open for reading and writing on standard input, pppd will assume that it is locked by its invoker and not lock it itself. * Chat now has a feature where if a string to be sent begins with an at sign (@), the rest of the string is taken as the name of a file (regular file or named pipe), and the actual string to send is taken from that file. * Support for FreeBSD-2.2.8 and 3.0 has been added, thanks to Paul Fulghum. * The Tru64 (aka Digital Unix aka OSF/1) port has been updated. * The system panics on Solaris SMP systems related to PPP connections being established and terminated should no longer occur. * Fixed quite a few bugs. What was new in ppp-2.3.7. ************************** * Pppd can now automatically allocate itself a pseudo-tty to use as the serial device. This has made three new options possible: - `pty script' will run `script' with its standard input and output connected to the master side of the pty. For example: pppd pty 'ssh -t server.my.net pppd' is a basic command for setting up a PPP link (tunnel) over ssh. (In practice you may need to specify other options such as IP addresses, etc.) - `notty' tells pppd to communicate over its standard input and output, which do not have to be a terminal device. - `record filename' tells pppd to record all of the characters sent and received over the serial device to a file called `filename'. The data is recorded in a tagged format with timestamps, which can be printed in a readable form with the pppdump program, which is included in this distribution. * Pppd now logs the connect time and number of bytes sent and received (at the level of the serial device) when the connection is terminated. * If you use the updetach or nodetach option, pppd will print its messages to standard output as well as logging them with syslog (provided of course pppd isn't using its standard input or output as its serial device). * There is a new `privgroup groupname' option (a privileged option). If the user running pppd is in group `groupname', s/he can use privileged options without restriction. * There is a new `receive-all' option, which causes pppd to accept all control characters, even the ones that the peer should be escaping (i.e. the receive asyncmap is 0). This is useful with some buggy peers. * The default asyncmap is now 0. * There is a new `sync' option, currently only implemented under Linux, which allows pppd to run on synchronous HDLC devices. * If a value for the device name or for the connect, disconnect, welcome or pty option is given in a privileged option file (i.e. /etc/ppp/options or a file loaded with the `call' option), it cannot be overridden by a non-privileged user. * Many bugs have been fixed, notably: - signals are not blocked unnecessarily, as they were in 2.3.6. - the usepeerdns option should work now. - the SPEED environment variable for scripts is set correctly. - the /etc/ppp/auth-down script is not run until auth-up completes. - the device is opened as root if it is the device on standard input. - pppd doesn't die with the ioctl(PPPIOCSASYNCMAP) error under linux if a hangup occurs at the wrong time. * Some error messages have been changed to be clearer (I hope :-) What was new in ppp-2.3.6. ************************** * Pppd now opens the tty device as the user (rather than as root) if the device name was given by the user, i.e. on the command line or in the ~/.ppprc file. If the device name was given in /etc/ppp/options or in a file loaded with the `call' option, the device is opened as root. * The default behaviour of pppd is now to let a peer which has not authenticated itself (e.g. your ISP) use any IP address to which the system does not already have a route. (This is currently only supported under Linux, Solaris and Digital Unix; on the other systems, the peer must now authenticate itself unless the noauth option is used.) * Added new option `usepeerdns', thanks to Nick Walker . If the peer supplies DNS addresses, these will be written to /etc/ppp/resolv.conf. The ip-up script can then be used to add these addresses to /etc/resolv.conf if desired (see the ip-up.local.add and ip-down.local.add files in the scripts directory). * The Solaris ppp driver should now work correctly on SMP systems. * Minor corrections so that the code can compile under Solaris 7, and under Linux with glibc-2.1. * The Linux kernel driver has been restructured for improved performance. * Pppd now won't start the ip-down script until the ip-up script has finished. What was new in ppp-2.3.5. ************************** * Minor corrections to the Digital UNIX and NetBSD ports. * A workaround to avoid tickling a bug in the `se' serial port driver on Sun PCI Ultra machines running Solaris. * Fixed a bug in the negotiation of the Microsoft WINS server address option. * Fixed a bug in the Linux port where it would fail for kernel versions above 2.1.99. What was new in ppp-2.3.4. ************************** * The NeXT port has been updated, thanks to Steve Perkins. * ppp-2.3.4 compiles and works under Solaris 2.6, using either gcc or cc. * With the Solaris, SVR4 and SunOS ports, you can control the choice of C compiler, C compiler options, and installation directories by editing the svr4/Makedefs or sunos4/Makedefs file. * Until now, we have been using the number 24 to identify Deflate compression in the CCP negotiations, which was the number in the draft RFC describing Deflate. The number actually assigned to Deflate is 26. The code has been changed to use 26, but to allow the use of 24 for now for backwards compatibility. (This can be disabled with the `nodeflatedraft' option to pppd.) * Fixed some bugs in the linux driver and deflate compressor which were causing compression problems, including corrupting long incompressible packets sometimes. * Fixes to the PAM and shadow password support in pppd, from Al Longyear and others. * Pppd now sets some environment variables for scripts it invokes (ip-up/down, auth-ip/down), giving information about the connection. The variables it sets are PEERNAME, IPLOCAL, IPREMOTE, UID, DEVICE, SPEED, and IFNAME. * Pppd now has an `updetach' option, which will cause it to detach from its controlling terminal once the link has come up (i.e. once it is available for IP traffic). What was new in ppp-2.3.3. ************************** * Fixed compilation problems under SunOS. * Fixed a bug introduced into chat in 2.3.2, and compilation problems introduced into the MS-CHAP implementation in 2.3.2. * The linux kernel driver has been updated for recent 2.1-series kernel changes, and it now will ask kerneld to load compression modules when required, if the kernel is configured to support kerneld. * Pppd should now compile correctly under linux on systems with glibc. What was new in ppp-2.3.2. ************************** * In 2.3.1, I made a change which was intended to make pppd able to detect loss of CD during or immediately after the connection script runs. Unfortunately, this had the side-effect that the connection script wouldn't work at all on some systems. This change has been reversed. * Fix compilation problems in the Linux kernel driver. What was new in ppp-2.3.1. ************************** * Enhancements to chat, thanks to Francis Demierre. Chat can now accept comments in the chat script file, and has new SAY, HANGUP, CLR_ABORT and CLR_REPORT keywords. * Fixed a bug which causes 2.3.0 to crash Solaris systems. * Bug-fixes and restructuring of the Linux kernel driver. * The holdoff behaviour of pppd has been changed slightly: now, if the link comes up for IP (or other network protocol) traffic, we consider that the link has been successfully established, and don't enforce the holdoff period after the link goes down. * Pppd should now correctly wait for CD (carrier detect) from the modem, even when the serial port initially had CLOCAL set, and it should also detect loss of CD during or immediately after the connection script runs. * Under linux, pppd will work with older 2.2.0* version kernel drivers, although demand-dialling is not supported with them. * Minor bugfixes for pppd. What was new in ppp-2.3. ************************ * Demand-dialling. Pppd now has a mode where it will establish the network interface immediately when it starts, but not actually bring the link up until it sees some data to be sent. Look for the demand option description in the pppd man page. Demand-dialling is not supported under Ultrix or NeXTStep. * Idle timeout. Pppd will optionally terminate the link if no data packets are sent or received within a certain time interval. * Pppd now runs the /etc/ppp/auth-up script, if it exists, when the peer successfully authenticates itself, and /etc/ppp/auth-down when the connection is subsequently terminated. This can be useful for accounting purposes. * A new packet compression scheme, Deflate, has been implemented. This uses the same compression method as `gzip'. This method is free of patent or copyright restrictions, and it achieves better compression than BSD-Compress. It does consume more CPU cycles for compression than BSD-Compress, but this shouldn't be a problem for links running at 100kbit/s or less. * There is no code in this distribution which is covered by Brad Clements' restrictive copyright notice. The STREAMS modules for SunOS and OSF/1 have been rewritten, based on the Solaris 2 modules, which were written from scratch without any Clements code. * Pppstats has been reworked to clean up the output format somewhat. It also has a new -d option which displays data rate in kbyte/s for those columns which would normally display bytes. * Pppd options beginning with - or + have been renamed, e.g. -ip became noip, +chap became require-chap, etc. The old options are still accepted for compatibility but may be removed in future. * Pppd now has some options (such as the new `noauth' option) which can only be specified if it is being run by root, or in an "privileged" options file: /etc/ppp/options or an options file in the /etc/ppp/peers directory. There is a new "call" option to read options from a file in /etc/ppp/peers, making it possible for non-root users to make unauthenticated connections, but only to certain trusted peers. My intention is to make the `auth' option the default in a future release. * Several minor new features have been added to pppd, including the maxconnect and welcome options. Pppd will now terminate the connection when there are no network control protocols running. The allowed IP address(es) field in the secrets files can now specify subnets (with a notation like 123.45.67.89/24) and addresses which are not acceptable (put a ! on the front). * Numerous bugs have been fixed (no doubt some have been introduced :-) Thanks to those who reported bugs in ppp-2.2. ppp-2.5.0/FAQ0000644000175000017500000006246207563132011007600 00000000000000This is a list of Frequently Asked Questions about using ppp-2.x and their answers. ------------------------------------------------------------------------ Q: Can you give me an example of how I might set up my machine to dial out to an ISP? A: Here's an example for dialling out to an ISP via a modem on /dev/tty02. The modem uses hardware (CTS/RTS) flow control, and the serial port is run at 38400 baud. The ISP assigns our IP address. To configure pppd for this connection, create a file under /etc/ppp/peers called (say) my-isp containing the following: tty02 crtscts 38400 connect 'chat -v -f /etc/ppp/chat/my-isp' defaultroute The ppp connection is then initiated using the following command: pppd call my-isp Of course, if the directory containing pppd is not in your path, you will need to give the full pathname for pppd, for example, /usr/sbin/pppd. When you run this, pppd will use the chat program to dial the ISP and invoke its ppp service. Chat will read the file specified with -f, namely /etc/ppp/chat/my-isp, to find a list of strings to expect to receive, and strings to send. This file would contain something like this: ABORT "NO CARRIER" ABORT "NO DIALTONE" ABORT "ERROR" ABORT "NO ANSWER" ABORT "BUSY" ABORT "Username/Password Incorrect" "" "at" OK "at&d2&c1" OK "atdt2479381" "name:" "^Uusername" "word:" "\qpassword" "annex" "\q^Uppp" "Switching to PPP-ppp-Switching to PPP" You will need to change the details here. The first string on each line is a string to expect to receive; the second is the string to send. You can add or delete lines according to the dialog required to access your ISP's system. This example is for a modem with a standard AT command set, dialling out to an Annex terminal server. The \q toggles "quiet" mode; when quiet mode is on, the strings to be sent are replaced by ?????? in the log. You may need to go through the dialog manually using kermit or tip first to determine what should go in the script. To terminate the link, run the following script, called (say) kill-ppp: #!/bin/sh unit=ppp${1-0} piddir=/var/run if [ -f $piddir/$unit.pid ]; then kill -1 `cat $piddir/$unit.pid` fi On some systems (SunOS, Solaris, Ultrix), you will need to change /var/run to /etc/ppp. ------------------------------------------------------------------------ Q: Can you give me an example of how I could set up my office machine so I can dial in to it from home? A: Let's assume that the office machine is called "office" and is on a local ethernet subnet. Call the home machine "home" and give it an IP address on the same subnet as "office". We'll require both machines to authenticate themselves to each other. Set up the files on "office" as follows: /etc/ppp/options contains: auth # require the peer to authenticate itself lock # other options can go here if desired /etc/ppp/chap-secrets contains: home office "beware the frub-jub" home office home "bird, my son!%&*" - Set up a modem on a serial port so that users can dial in to the modem and get a login prompt. On "home", set up the files as follows: /etc/ppp/options contains the same as on "office". /etc/ppp/chap-secrets contains: home office "beware the frub-jub" - office home "bird, my son!%&*" office Create a file called /etc/ppp/peers/office containing the following: tty02 crtscts 38400 connect 'chat -v -f /etc/ppp/chat/office' defaultroute (You may need to change some of the details here.) Create the /etc/ppp/chat/office file containing the following: ABORT "NO CARRIER" ABORT "NO DIALTONE" ABORT "ERROR" ABORT "NO ANSWER" ABORT "BUSY" ABORT "ogin incorrect" "" "at" OK "at&d2&c1" OK "atdt2479381" "name:" "^Uusername" "word:" "\qpassword" "$" "\q^U/usr/sbin/pppd proxyarp" "~" You will need to change the details. Note that the "$" in the second-last line is expecting the shell prompt after a successful login - you may need to change it to "%" or something else. You then initiate the connection (from home) with the command: pppd call office ------------------------------------------------------------------------ Q: When I try to establish a connection, the modem successfully dials the remote system, but then hangs up a few seconds later. How do I find out what's going wrong? A: There are a number of possible problems here. The first thing to do is to ensure that pppd's messages are visible. Pppd uses the syslog facility to log messages which help to identify specific problems. Messages from pppd have facility "daemon" and levels ranging from "debug" to "error". Usually it is useful to see messages of level "notice" or higher on the console. To see these, find the line in /etc/syslog.conf which has /dev/console on the right-hand side, and add "daemon.notice" in the list on the left. The line will end up looking something like this: *.err;kern.debug;auth.notice;mail.crit;daemon.notice /dev/console Note that the whitespace is tabs, *not* spaces. If you are having problems, it may be useful to see messages of level "info" as well, in which case you would change "daemon.notice" to "daemon.info". In addition, it is useful to collect pppd's debugging output in a file - the debug option to pppd causes it to log the contents of all control packets sent and received in human-readable form. To do this, add a line like this to /etc/syslog.conf: daemon,local2.debug /etc/ppp/log and create an empty /etc/ppp/log file. When you change syslog.conf, you will need to send a HUP signal to syslogd to causes it to re-read syslog.conf. You can do this with a command like this (as root): kill -HUP `cat /etc/syslogd.pid` (On some systems, you need to use /var/run/syslog.pid instead of /etc/syslogd.pid.) After setting up syslog like this, you can use the -v flag to chat and the `debug' option to pppd to get more information. Try initiating the connection again; when it fails, inspect /etc/ppp/log to see what happened and where the connection failed. ------------------------------------------------------------------------ Q: When I try to establish a connection, I get an error message saying "Serial link is not 8-bit clean". Why? A: The most common cause is that your connection script hasn't successfully dialled out to the remote system and invoked ppp service there. Instead, pppd is talking to something (a shell or login process on the remote machine, or maybe just the modem) which is only outputting 7-bit characters. This can also arise with a modem which uses an AT command set if the dial command is issued before pppd is invoked, rather than within a connect script started by pppd. If the serial port is set to 7 bits/character plus parity when the last AT command is issued, the modem serial port will be set to the same setting. Note that pppd *always* sets the local serial port to 8 bits per character, with no parity and 1 stop bit. So you shouldn't need to issue an stty command before invoking pppd. ------------------------------------------------------------------------ Q: When I try to establish a connection, I get an error message saying "Serial line is looped back". Why? A: Probably your connection script hasn't successfully dialled out to the remote system and invoked ppp service there. Instead, pppd is talking to something which is just echoing back the characters it receives. The -v option to chat can help you find out what's going on. It can be useful to include "~" as the last expect string to chat, so chat won't return until it's seen the start of the first PPP frame from the remote system. Another possibility is that your phone connection has dropped for some obscure reason and the modem is echoing the characters it receives from your system. ------------------------------------------------------------------------ Q: I installed pppd successfully, but when I try to run it, I get a message saying something like "peer authentication required but no authentication files accessible". A: When pppd is used on a machine which already has a connection to the Internet (or to be more precise, one which has a default route in its routing table), it will require all peers to authenticate themselves. The reason for this is that if you don't require authentication, you have a security hole, because the peer can basically choose any IP address it wants, even the IP address of some trusted host (for example, a host mentioned in some .rhosts file). On machines which don't have a default route, pppd does not require the peer to authenticate itself. The reason is that such machines would mostly be using pppd to dial out to an ISP which will refuse to authenticate itself. In that case the peer can use any IP address as long as the system does not already have a route to that address. For example, if you have a local ethernet network, the peer can't use an address on that network. (In fact it could if it authenticated itself and it was permitted to use that address by the pap-secrets or chap-secrets file.) There are 3 ways around the problem: 1. If possible, arrange for the peer to authenticate itself, and create the necessary secrets files (/etc/ppp/pap-secrets and/or /etc/ppp/chap-secrets). 2. If the peer refuses to authenticate itself, and will always be using the same IP address, or one of a small set of IP addresses, you can create an entry in the /etc/ppp/pap-secrets file like this: "" * "" his-ip.his-domain his-other-ip.other-domain (that is, using the empty string for the client name and password fields). Of couse, you replace the 4th and following fields in the example above with the IP address(es) that the peer may use. You can use either hostnames or numeric IP addresses. 3. You can add the `noauth' option to the /etc/ppp/options file. Pppd will then not ask the peer to authenticate itself. If you do this, I *strongly* recommend that you remove the set-uid bit from the permissions on the pppd executable, with a command like this: chmod u-s /usr/sbin/pppd Then, an intruder could only use pppd maliciously if they had already become root, in which case they couldn't do any more damage using pppd than they could anyway. ------------------------------------------------------------------------ Q: What do I need to put in the secrets files? A: Three things: - secrets (i.e. passwords) to use for authenticating this host to other hosts (i.e., for proving our identity to others); - secrets which other hosts can use for authenticating themselves to us (i.e., so that they can prove their identity to us); and - information about which IP addresses other hosts may use, once they have authenticated themselves. There are two authentication files: /etc/ppp/pap-secrets, which contains secrets for use with PAP (the Password Authentication Protocol), and /etc/ppp/chap-secrets, which contains secrets for use with CHAP (the Challenge Handshake Authentication Protocol). Both files have the same simple format, which is as follows: - The file contains a series of entries, each of which contains a secret for authenticating one machine to another. - Each entry is contained on a single logical line. A logical line may be continued across several lines by placing a backslash (\) at the end of each line except the last. - Each entry has 3 or more fields, separated by whitespace (spaces and/or tabs). These fields are, in order: * The name of the machine that is authenticating itself (the "client"). * The name of the machine that is authenticating the client (the "server"). * The secret to be used for authenticating that client to that server. If this field begins with the at-sign `@', the rest of the field is taken as the name of a file containing the actual secret. * The 4th and any following fields list the IP address(es) that the client may use. - The file may contain comments, which begin with a `#' and continue to the end of the line. - Double quotes `"' should be used around a field if it contains characters with special significance, such as space, tab, `#', etc. - The backslash `\' may be used before characters with special significance (space, tab, `#', `\', etc.) to remove that significance. Some important points to note: * A machine can be *both* a "client" and a "server" for the purposes of authentication - this happens when both peers require the other to authenticate itself. So A would authenticate itself to B, and B would also authenticate itself to A (possibly using a different authentication protocol). * If both the "client" and the "server" are running ppp-2.x, they need to have a similar entry in the appropriate secrets file; the first two fields are *not* swapped on the client, compared to the server. So the client might have an entry like this: ay bee "our little secret" - and the corresponding entry on the server could look like this: ay bee "our little secret" 123.45.67.89 ------------------------------------------------------------------------ Q: Explain about PAP and CHAP? PAP stands for the Password Authentication Protocol. With this protocol, the "client" (the machine that needs to authenticate itself) sends its name and a password, in clear text, to the "server". The server returns a message indicating whether the name and password are valid. CHAP stands for the Challenge Handshake Authentication Protocol. It is designed to address some of the deficiencies and vulnerabilities of PAP. Like PAP, it is based on the client and server having a shared secret, but the secret is never passed in clear text over the link. Instead, the server sends a "challenge" - an arbitrary string of bytes, and the client must prove it knows the shared secret by generating a hash value from the challenge combined with the shared secret, and sending the hash value back to the server. The server also generates the hash value and compares it with the value received from the client. At a practical level, CHAP can be slightly easier to configure than PAP because the server sends its name with the challenge. Thus, when finding the appropriate secret in the secrets file, the client knows the server's name. In contrast, with PAP, the client has to find its password (i.e. the shared secret) before it has received anything from the server. Thus, it may be necessary to use the `remotename' option to pppd when using PAP authentication so that it can select the appropriate secret from /etc/ppp/pap-secrets. Microsoft also has a variant of CHAP which uses a different hashing arrangement from normal CHAP. There is a client-side (authenticatee) implementation of Microsoft's CHAP in ppp-2.3; see README.MSCHAP80. In ppp-2.4.2, server-side (authenticator) support was added as well as support for Microsoft CHAP v2; see README.MSCHAP81. ------------------------------------------------------------------------ Q: When the modem hangs up, without the remote system having terminated the connection properly, pppd does not notice the hangup, but just keeps running. How do I get pppd to notice the hangup and exit? A: Pppd detects modem hangup by looking for an end-of-file indication from the serial driver, which should be generated when the CD (carrier detect) signal on the serial port is deasserted. For this to work: - The modem has to be set to assert CD when the connection is made and deassert it when the phone line hangs up. Usually the AT&C1 modem command sets this mode. - The cable from the modem to the serial port must connect the CD signal (on pin 8). - Some serial drivers have a "software carrier detect" mode, which must be *disabled*. The method of doing this varies between systems. Under SunOS, use the ttysoftcar command. Under NetBSD, edit /etc/ttys to remove the "softcar" flag from the line for the serial port, and run ttyflags. ------------------------------------------------------------------------ Q: Why should I use PPP compression (BSD-Compress or Deflate) when my modem already does V.42 compression? Won't it slow the CPU down a lot? A: Using PPP compression is preferable, especially when using modems over phone lines, for the following reasons: - The V.42 compression in the modem isn't very strong - it's an LZW technique (same as BSD-Compress) with a 10, 11 or 12 bit code size. With BSD-Compress you can use a code size of up to 15 bits and get much better compression, or you can use Deflate and get even better compression ratios. - I have found that enabling V.42 compression in my 14.4k modem increases the round-trip time for a character to be sent, echoed and returned by around 40ms, from 160ms to 200ms (with error correction enabled). This is enough to make it feel less responsive on rlogin or telnet sessions. Using PPP compression adds less than 5ms (small enough that I couldn't measure it reliably). I admit my modem is a cheapie and other modems may well perform better. - While compression and decompression do require some CPU time, they reduce the amount of time spent in the serial driver to transmit a given amount of data. Many machines require an interrupt for each character sent or received, and the interrupt handler can take a significant amount of CPU time. So the increase in CPU load isn't as great as you might think. My measurements indicate that a system with a 33MHz 486 CPU should be able to do Deflate compression for serial link speeds of up to 100kb/s or more. It depends somewhat on the type of data, of course; for example, when compressing a string of nulls with Deflate, it's hard to get a high output data rate from the compressor, simply because it compresses strings of nulls so well that it has to eat a very large amount of input data to get each byte of output. ------------------------------------------------------------------------ Q: I get messages saying "Unsupported protocol (...) received". What do these mean? A: If you only get one or two when pppd starts negotiating with the peer, they mean that the peer wanted to negotiate some PPP protocol that pppd doesn't understand. This doesn't represent a problem, it simply means that there is some functionality that the peer supports that pppd doesn't, so that functionality can't be used. If you get them sporadically while the link is operating, or if the protocol numbers (in parentheses) don't correspond to any valid PPP protocol that the peer might be using, then the problem is probably that characters are getting corrupted on the receive side, or that extra characters are being inserted into the receive stream somehow. If this is happening, most packets that get corrupted should get discarded by the FCS (Frame Check Sequence, a 16-bit CRC) check, but a small number may get through. One possibility may be that you are receiving broadcast messages on the remote system which are being sent over your serial link. Another possibility is that your modem is set for XON/XOFF (software) flow control and is inserting ^Q and ^S characters into the receive data stream. ------------------------------------------------------------------------ Q: I get messages saying "Protocol-Reject for unsupported protocol ...". What do these mean? A: This is the other side of the previous question. If characters are getting corrupted on the way to the peer, or if your system is inserting extra bogus characters into the transmit data stream, the peer may send protocol-reject messages to you, resulting in the above message (since your pppd doesn't recognize the protocol number either.) ------------------------------------------------------------------------ Q: I get a message saying something like "ioctl(TIOCSETD): Operation not permitted". How do I fix this? A: This is because pppd is not running as root. If you have not installed pppd setuid-root, you will have to be root to run it. If you have installed pppd setuid-root and you still get this message, it is probably because your shell is using some other copy of pppd than the installed one - for example, if you are in the pppd directory where you've just built pppd and your $PATH has . before /usr/sbin (or wherever pppd gets installed). ------------------------------------------------------------------------ Q: Has your package been ported to HP/UX or IRIX or AIX? A: No. I don't have access to systems running HP/UX or AIX. No-one has volunteered to port it to HP/UX. I had someone who did a port for AIX 4.x, but who is no longer able to maintain it. And apparently AIX 3.x is quite different, so it would need a separate port. IRIX includes a good PPP implementation in the standard distribution, as far as I know. ------------------------------------------------------------------------ Q: Under SunOS 4, when I try to modload the ppp modules, I get the message "can't open /dev/vd: No such device". A: First check in /dev that there is an entry like this: crw-r--r-- 1 root 57, 0 Oct 2 1991 vd If not, make one (mknod /dev/vd c 57 0). If the problem still exists, probably your kernel has been configured without the vd driver included. The vd driver is needed for loadable module support. First, identify the config file that was used. When you boot your machine, or if you run /etc/dmesg, you'll see a line that looks something like this: SunOS Release 4.1.3_U1 (CAP_XBOX) #7: Thu Mar 21 15:31:56 EST 1996 ^^^^^^^^ this is the config file name The config file will be in the /sys/`arch -k`/conf directory (arch -k should return sun4m for a SparcStation 10, sun3x for a Sun 3/80, etc.). Look in there for a line saying "options VDDRV". If that line isn't present (or is commented out), add it (or uncomment it). You then need to rebuild the kernel as described in the SunOS manuals. Basically you need to run config and make like this: /usr/etc/config CAP_XBOX cd ../CAP_XBOX make (replacing the string CAP_XBOX by the name of the config file for your kernel, of course). Then copy the new kernel to /: mv /vmunix /vmunix.working cp vmunix / and reboot. Modload should then work. ------------------------------------------------------------------------ Q: I'm running Linux (or NetBSD or FreeBSD), and my system comes with PPP already. Should I consider installing this package? Why? A: The PPP that is already installed in your system is (or is derived from) some version of this PPP package. You can find out what version of this package is already installed with the command "pppd --help". If this is older than the latest version, you may wish to install the latest version so that you can take advantage of the new features or bug fixes. ------------------------------------------------------------------------ Q: I'm running pppd in demand mode, and I find that pppd often dials out unnecessarily when I try to make a connection within my local machine or with a machine on my local LAN. What can I do about this? A: Very often the cause of this is that a program is trying to contact a nameserver to resolve a hostname, and the nameserver (specified in /etc/resolv.conf, usually) is on the far side of the ppp link. You can try executing a command such as `ping myhost' (where myhost is the name of the local machine, or some other machine on a local LAN), to see whether that starts the ppp link. If it does, check the setup of your /etc/hosts file to make sure you have the local machine and any hosts on your local LAN listed, and /etc/resolv.conf and/or /etc/nsswitch.conf files to make sure you resolve hostnames from /etc/hosts if possible before trying to contact a nameserver. ------------------------------------------------------------------------ Q: Since I installed ppp-2.3.6, dialin users to my server have been getting this message when they run pppd: peer authentication required but no suitable secret(s) found for authenticating any peer to us (ispserver) A: In 2.3.6, the default is to let an unauthenticated peer only use IP addresses to which the machine doesn't already have a route. So on a machine with a default route, everyone has to authenticate. If you really don't want that, you can put `noauth' in the /etc/ppp/options file. Note that there is then no check on who is using which IP address. IMHO, this is undesirably insecure, but I guess it may be tolerable as long as you don't use any .rhosts files or anything like that. I recommend that you require dialin users to authenticate, even if just with PAP using their login password (using the `login' option to pppd). If you do use `noauth', you should at least have a pppusers group and set the permissions on pppd to allow only user and group to execute it. ------------------------------------------------------------------------ Q: When running pppd as a dial-in server, I often get the message "LCP: timeout sending Config-Requests" from pppd. It seems to be random, but dial-out always works fine. What is wrong? A: Most modern modems auto-detects the speed of the serial line between the modem and the computer. This auto-detection occurs when the computer sends characters to the modem, when the modem is in command mode. It does not occur when the modem is in data mode. Thus, if you send commands to the modem at 2400 bps, and then change the serial port speed to 115200 bps, the modem will not detect this change until something is transmitted from the computer to the modem. When running pppd in dial-in mode (i.e. without a connect script), pppd sets the speed of the serial port, but does not transmit anything. If the modem was already running at the specified speed, everything is fine, but if not, you will just receive garbage from the modem. To cure this, use an init script such as the following: pppd ttyS0 115200 modem crtscts init "chat '' AT OK" To reset the modem and enable auto-answer, use: pppd ttyS0 115200 modem crtscts init "chat '' ATZ OK ATS0=1 OK" ppp-2.5.0/README.cbcp0000644000175000017500000000373507761465564011060 00000000000000 Microsoft Call Back Configuration Protocol. by Pedro Roque Marques (updated by Paul Mackerras) The CBCP is a method by which the Microsoft Windows NT Server may implement additional security. It is possible to configure the server in such a manner so as to require that the client systems which connect with it are required that following a valid authentication to leave a method by which the number may be returned call. It is a requirement of servers to be so configured that the protocol be exchanged. So, this set of patches may be applied to the pppd process to enable the cbcp client *only* portion of the specification. It is primarily meant to permit connection with Windows NT Servers. The ietf-working specification may be obtained from ftp.microsoft.com in the developr/rfc directory. The ietf task group has decided to recommend that the LCP sequence be extended to permit the callback operation. For this reason, these patches are not 'part' of pppd but are an adjunct to the code. To enable CBCP support, all that is required is to uncomment the line in Makefile.linux that sets CBCP=y and recompile pppd. I use such script to make a callback: pppd debug nodetach /dev/modem 115200 crtscts modem \ callback 222222 name NAME remotename SERVER \ connect 'chat -v "" atz OK atdt111111 CONNECT ""' sleep 1 pppd debug /dev/modem 115200 crtscts modem \ name NAME remotename SERVER defaultroute \ connect 'chat -v RING ATA CONNECT "\c"' First we invoke pppd with 'nodetach' option in order to not detach from the controlling terminal and 'callback NUMBER' option, then wait for 1 second and invoke pppd again which waits for a callback (RING) and then answers (ATA). Number 222222 is a callback number, i.e. server will call us back at this number, while number 111111 is the number we are calling to. You have to put in /etc/ppp/chap-secrets the following two lines: NAME SERVER PASSWORD SERVER NAME PASSWORD You have to use your real login name, remote server name and password. ppp-2.5.0/README.eap-srp0000644000175000017500000001426407561025774011510 00000000000000EAP with MD5-Challenge and SRP-SHA1 support by James Carlson, Sun Microsystems Version 2, September 22nd, 2002 1. What it does The Extensible Authentication Protocol (EAP; RFC 2284) is a security protocol that can be used with PPP. It provides a means to plug in multiple optional authentication methods. This implementation includes the required default MD5-Challenge method, which is similar to CHAP (RFC 1994), as well as the new SRP-SHA1 method. This latter method relies on an exchange that is not vulnerable to dictionary attacks (as is CHAP), does not require the server to keep a cleartext copy of the secret (as in CHAP), supports identity privacy, and produces a temporary shared key that could be used for data encryption. The SRP-SHA1 method is based on draft-ietf-pppext-eap-srp-03.txt, a work in progress. 2. Required libraries Two other packages are required first. Download and install OpenSSL and Thomas Wu's SRP implementation. http://www.openssl.org/ (or ftp://ftp.openssl.org/source/) http://srp.stanford.edu/ Follow the directions in each package to install the SSL and SRP libraries. Once SRP is installed, you may run tconf as root to create known fields, if desired. (This step is not required.) 3. Installing the patch The EAP-SRP patch described here is integrated into this version of pppd. The following patch may be used with older pppd sources: ftp://playground.sun.com/carlsonj/eap/ppp-2.4.1-eap-1.tar.gz Configure, compile, and install as root. You may want to edit pppd/Makefile after configuring to enable or disable optional features. % ./configure % make % su # make install If you use csh or tcsh, run "rehash" to pick up the new commands. If you're using Solaris, and you run into trouble with the pseudonym feature on the server side ("no DES here" shows in the log file), make sure that you have the "domestic" versions of the DES libraries linked. You should see "crypt_d" in "ldd /usr/local/bin/pppd". If you see "crypt_i" instead, then make sure that /usr/lib/libcrypt.* links to /usr/lib/libcrypt_d.*. (If you have the international version of Solaris, then you won't have crypt_d. You might want to find an alternative DES library.) 4. Adding the secrets On the EAP SRP-SHA1 client side, access to the cleartext secret is required. This can be done in two ways: - Enter the client name, server name, and password in the /etc/ppp/srp-secrets file. This file has the same format as the existing chap-secrets and pap-secrets files. clientname servername "secret here" - Use the "password" option in any of the standard configuration files (or the command line) to specify the secret. password "secret here" On the EAP SRP-SHA1 server side, a secret verifier is required. This is a one-way hash of the client's name and password. To generate this value, run the srp-entry program (see srp-entry(8)). This program prompts for the client name and the passphrase (the secret). The output will be an entry, such as the following, suitable for use in the server's srp-secrets file. Note that if this is transferred by cut-and-paste, the entry must be a single line of text in the file. pppuser srpserver 0:LFDpwg4HBLi4/kWByzbZpW6pE95/iIWBSt7L.DAkHsvwQphtiq0f6reoUy/1LC1qYqjcrV97lCDmQHQd4KIACGgtkhttLdP3KMowvS0wLXLo25FPJeG2sMAUEWu/HlJPn2/gHyh9aT.ZxUs5MsoQ1E61sJkVBc.2qze1CdZiQGTK3qtWRP6DOpM1bfhKtPoVm.g.MiCcTMWzc54xJUIA0mgKtpthE3JrqCc81cXUt4DYi5yBzeeGTqrI0z2/Gj8Jp7pS4Fkq3GmnYjMxnKfQorFXNwl3m7JSaPa8Gj9/BqnorJOsnSMlIhBe6dy4CYytuTbNb4Wv/nFkmSThK782V:2cIyMp1yKslQgE * The "secret" field consists of three entries separated by colons. The first entry is the index of the modulus and generator from SRP's /etc/tpasswd.conf. If the special value 0 is used, then the well-known modulus/generator value is used (this is recommended, because it is much faster). The second value is the verifier value. The third is the password "salt." These latter two values are encoded in base64 notation. For EAP MD5-Challenge, both client and server use the existing /etc/ppp/chap-secrets file. 5. Configuration options There are two main options relating to EAP available for the client. These are: refuse-eap - refuse to authenticate with EAP srp-use-pseudonym - use the identity privacy if offered by server The second option stores a pseudonym, if offered by the EAP SRP-SHA1 server, in the $HOME/.ppp_pseudonym file. The pseudonym is typically an encrypted version of the client identity. During EAP start-up, the pseudonym stored in this file is offered to the peer as the identity. If this is accepted by the peer, then eavesdroppers will be unable to determine the identity of the client. Each time the client is authenticated, the server will offer a new pseudoname to the client using an obscured (reversibly encrypted) message. Thus, access across successive sessions cannot be tracked. There are two main options for EAP on the server: require-eap - require client to use EAP srp-pn-secret "string" - set server's pseudoname secret The second option sets the long-term secret used on the server to encrypt the user's identity to produce pseudonames. The pseudoname is constructed by hashing this string with the current date (to the nearest day) with SHA1, then using this hash as the key for a DES encryption of the client's name. The date is added to the hash for two reasons. First, this allows the pseudonym to change daily. Second, it allows the server to decode any previous pseudonym by trying previous dates. See the pppd(8) man page for additional options. 6. Comments welcome! This is still an experimental implementation. It has been tested and reviewed carefully for correctness, but may still be incomplete or have other flaws. All comments are welcome. Please address them to the author: james.d.carlson@sun.com or, for EAP itself or the SRP extensions to EAP, to the IETF PPP Extensions working group: ietf-ppp@merit.edu ppp-2.5.0/README.eap-tls0000664000175000017500000002112514056552272011475 00000000000000EAP-TLS authentication support for PPP ====================================== 1. Intro The Extensible Authentication Protocol (EAP; RFC 3748) is a security protocol that can be used with PPP. It provides a means to plug in multiple optional authentication methods. Transport Level Security (TLS; RFC 5216) provides for mutual authentication, integrity-protected ciphersuite negotiation and key exchange between two endpoints. It also provides for optional MPPE encryption. EAP-TLS (RFC 2716) incapsulates the TLS messages in EAP packets, allowing TLS mutual authentication to be used as a generic EAP mechanism. It also provides optional encryption using the MPPE protocol. This patch provide EAP-TLS support to pppd. This authentication method can be used in both client or server mode. 2. Building To build pppd with EAP-TLS support, OpenSSL (http://www.openssl.org) is required. Any version from 0.9.7 should work. Configure, compile, and install as usual. 3. Configuration On the client side there are two ways to configure EAP-TLS: 1. supply the appropriate 'ca', 'cert' and 'key' command-line parameters 2. edit the /etc/ppp/eaptls-client file. Insert a line for each system with which you use EAP-TLS. The line is composed of this fields separated by tab: - Client name The name used by the client for authentication, can be * - Server name The name of the server, can be * - Client certificate file The file containing the certificate chain for the client in PEM format - Server certificate file If you want to specify the certificate that the server is allowed to use, put the certificate file name. Else put a dash '-'. - CA certificate file The file containing the trusted CA certificates in PEM format. - Client private key file The file containing the client private key in PEM format. On the server side edit the /etc/ppp/eaptls-server file. Insert a line for each system with which you use EAP-TLS. The line is composed of this fields separated by tab: - Client name The name used by the client for authentication, can be * - Server name The name of the server, can be * - Client certificate file If you want to specify the certificate that the client is allowed to use, put the certificate file name. Else put a dash '-'. - Server certificate file The file containing the certificate chain for the server in PEM format - CA certificate file The file containing the trusted CA certificates in PEM format. - Client private key file The file containing the server private key in PEM format. - addresses A list of IP addresses the client is allowed to use. OpenSSL engine support is included starting with v0.95 of this patch. Currently the only engine tested is the 'pkcs11' engine (hardware token support). To use the 'pksc11' engine: - Use a special private key fileiname in the /etc/ppp/eaptls-client file: : e.g. pkcs11:123456 - The certificate can also be loaded from the 'pkcs11' engine using a special client certificate filename in the /etc/ppp/eaptls-client file: : e.g. pkcs11:123456 - Create an /etc/ppp/openssl.cnf file to load the right OpenSSL engine prior to starting 'pppd'. A sample openssl.cnf file is openssl_conf = openssl_def [ openssl_def ] engines = engine_section [ engine_section ] pkcs11 = pkcs11_section [ pkcs11_section ] engine_id = pkcs11 dynamic_path = /usr/lib64/openssl/engines/engine_pkcs11.so MODULE_PATH = /usr/lib64/libeTPkcs11.so init = 0 - There are two ways to specify a password/PIN for the PKCS11 engine: - inside the openssl.cnf file using PIN = your-secret-pin Note The keyword 'PIN' is case sensitive! - Using the 'password' in the ppp options file. From v0.97 of the eap-tls patch the password can also be supplied using the appropriate 'eaptls_passwd_hook' (see plugins/passprompt.c for an example). 4. Options These pppd options are available: ca Use the CA public certificate found in in PEM format capath Use the directory as the CA public certificate directory cert Use the client public certificate found in in PEM format or in engine:engine_id format key Use the client private key found in in PEM format or in engine:engine_id format pkcs12 Use a pkcs12 envelope as a substitute for cert and key. A password may be required to use this file. crl Use the Certificate Revocation List (CRL) file in PEM format. crl-dir Use CRL files from directory . It contains CRL files in PEM format and each file contains a CRL. The files are looked up by the issuer name hash value. Use the c_rehash utility to create necessary links. need-peer-eap If the peer doesn't ask us to authenticate or doesn't use eap to authenticate us, disconnect. max-tls-version <1.0|1.1|1.2 (default)|1.3> Specify the maximum TLS protocol version to negotiate with peers. Defaults to TLSv1.2 as the TLSv1.3 code is experimental. tls-verify-key-usage Validate certificate purpose and extended key usage tls-verify-method Compare the remotename against the subject, certificate name, or match by suffix. Default is 'name'. Note: password-encrypted certificates can be used as of v0.94 of this patch. The password for the eap-tls.key file is specified using the regular password .... statement in the ppp options file, or by using the appropriate plugin which supplies a 'eaptls_passwd_hook' routine. 5. Connecting If you're setting up a pppd server, edit the EAP-TLS configuration file as written above and then run pppd with the 'auth' option to authenticate the client. The EAP-TLS method will be used if the other eap methods can't be used (no secrets). If you're setting up a client, edit the configuration file and then run pppd with 'remotename' option to specify the server name. Add the 'need-peer-eap' option if you want to be sure the peer ask you to authenticate (and to use eap) and to disconnect if it doesn't. 6. Example The following example can be used to connect a Linux client with the 'pptp' package to a Linux server running the 'pptpd' (PoPToP) package. The server was configured with a certificate with name (CN) 'pptp-server', the client was configured with a certificate with name (CN) 'pptp-client', both signed by the same Certificate Authority (CA). Server side: - /etc/pptpd.conf file: option /etc/ppp/options-pptpd-eaptls localip 172.16.1.1 remoteip 172.16.1.10-20 - /etc/ppp/options-pptpd-eaptls file: name pptp-server lock mtu 1500 mru 1450 auth lcp-echo-failure 3 lcp-echo-interval 5 nodeflate nobsdcomp nopredictor1 nopcomp noaccomp require-eap require-mppe-128 crl /home/janjust/ppp/keys/crl.pem debug logfile /tmp/pppd.log - /etc/ppp/eaptls-server file: * pptp-server - /etc/ppp/pptp-server.crt /etc/ppp/ca.crt /etc/ppp/pptp-server.key * - On the server, run pptdp --conf /etc/pptpd.conf Client side: - Run pppd noauth require-eap require-mppe-128 \ ipcp-accept-local ipcp-accept-remote noipdefault \ cert /etc/ppp/keys/pptp-client.crt \ key /etc/ppp/keys/pptp-client.key \ ca /etc/ppp/keys/ca.crt \ name pptp-client remotename pptp-server \ debug logfile /tmp/pppd.log pty "pptp pptp-server.example.com --nolaunchpppd" Check /var/log/messages and the files /tmp/pppd.log on both sides for debugging info. 7. Notes This is experimental code. Send suggestions and comments to Jan Just Keijser ppp-2.5.0/README.linux0000644000175000017500000002615211060440357011262 00000000000000 PPP for Linux ------------- Paul Mackerras 8 March 2001 for ppp-2.4.2 Updated for ppp-2.4.5, Sep 08 1. Introduction --------------- The Linux PPP implementation includes both kernel and user-level parts. This package contains the user-level part, which consists of the PPP daemon (pppd) and associated utilities. In the past this package has contained updated kernel drivers. This is no longer necessary, as the current kernel sources contain up-to-date drivers (and have done since the 2.4.x kernel series). The Linux PPP implementation is capable of being used both for initiating PPP connections (as a `client') or for handling incoming PPP connections (as a `server'). Note that this is an operational distinction, based on how the connection is created, rather than a distinction that is made in the PPP protocols themselves. Mostly this package is used for PPP connections over modems connected via asynchronous serial ports, so this guide concentrates on this situation. The PPP protocol consists of two parts. One is a scheme for framing and encoding packets, the other is a series of protocols called LCP, IPCP, PAP and CHAP, for negotiating link options and for authentication. This package similarly consists of two parts: a kernel module which handles PPP's low-level framing protocol, and a user-level program called pppd which implements PPP's negotiation protocols. The kernel module assembles/disassembles PPP frames, handles error detection, and forwards packets between the serial port and either the kernel network code or the user-level program pppd. IP packets go directly to the kernel network code. So once pppd has negotiated the link, it in practice lies completely dormant until you want to take the link down, when it negotiates a graceful disconnect. 2. Installation --------------- 2.1 Kernel driver Assuming you are running a recent 2.4 or 2.6 (or later) series kernel, the kernel source code will contain an up-to-date kernel PPP driver. If the PPP driver was included in your kernel configuration when your kernel was built, then you only need to install the user-level programs. Otherwise you will need to get the source tree for your kernel version, configure it with PPP included, and recompile. Most Linux distribution vendors ship kernels with PPP included in the configuration. The PPP driver can be either compiled into the kernel or compiled as a kernel module. If it is compiled into the kernel, the PPP driver is included in the kernel image which is loaded at boot time. If it is compiled as a module, the PPP driver is present in one or more files under /lib/modules and is loaded into the kernel when needed. The 2.2 series kernels contain an older version of the kernel PPP driver, one which doesn't support multilink. If you want multilink, you need to run a 2.4 or 2.6 series kernel. The kernel PPP driver was completely rewritten for the 2.4 series kernels to support multilink and to allow it to operate over diverse kinds of communication medium (the 2.2 driver only operates over serial ports and devices which look like serial ports, such as pseudo-ttys). Under the 2.2 kernels, if PPP is compiled as a module, the PPP driver modules should be present in the /lib/modules/`uname -r`/net directory (where `uname -r` represents the kernel version number). The PPP driver module itself is called ppp.o, and there will usually be compression modules there, ppp_deflate.o and bsd_comp.o, as well as slhc.o, which handles TCP/IP header compression. If the PPP driver is compiled into the kernel, the compression code will still be compiled as modules, for kernels before 2.2.17pre12. For 2.2.17pre12 and later, if the PPP driver is compiled in, the compression code will also. Under the 2.4 kernels, there are two PPP modules, ppp_generic.o and ppp_async.o, plus the compression modules (ppp_deflate.o, bsd_comp.o and slhc.o). If the PPP generic driver is compiled into the kernel, the other four can then be present either as modules or compiled into the kernel. There is a sixth module, ppp_synctty.o, which is used for synchronous tty devices such as high-speed WAN adaptors. 2.2 User-level programs If you obtained this package in .rpm or .deb format, you simply follow the usual procedure for installing the package. If you are using the .tar.gz form of this package, then cd into the ppp-2.4.5 directory you obtained by unpacking the archive and issue the following commands: $ ./configure $ make # make install The `make install' has to be done as root. This makes and installs four programs and their man pages: pppd, chat, pppstats and pppdump. If the /etc/ppp configuration directory doesn't exist, the `make install' step will create it and install some default configuration files. 2.3 System setup for 2.4 kernels Under the 2.4 series kernels, pppd needs to be able to open /dev/ppp, character device (108,0). If you are using udev (as most distributions do), the /dev/ppp node should be created by udevd. Otherwise you may need to create a /dev/ppp device node with the commands: # mknod /dev/ppp c 108 0 # chmod 600 /dev/ppp 2.4 System setup under 2.2 series kernels Under the 2.2 series kernels, you should add the following to your /etc/modules.conf or /etc/conf.modules: alias tty-ldisc-3 ppp alias ppp-compress-21 bsd_comp alias ppp-compress-24 ppp_deflate alias ppp-compress-26 ppp_deflate 3. Getting help with problems ----------------------------- If you have problems with your PPP setup, or you just want to ask some questions, or better yet if you can help others with their PPP questions, then you should join the linux-ppp mailing list. Send an email to majordomo@vger.kernel.org with a line in the body saying subscribe linux-ppp To leave the mailing list, send an email to majordomo@vger.kernel.org with a line in the body saying unsubscribe linux-ppp To send a message to the list, email it to linux-ppp@vger.kernel.org. You don't have to be subscribed to send messages to the list. You can also email me (paulus@samba.org) but I am overloaded with email and I can't respond to most messages I get in a timely fashion. There are also several relevant news groups, such as comp.protocols.ppp, comp.os.linux.networking, or comp.os.linux.setup. 4. Configuring your dial-out PPP connections -------------------------------------------- Some Linux distribution makers include tools in their distributions for setting up PPP connections. For example, for Red Hat Linux and derivatives, you should probably use linuxconf or netcfg to set up your PPP connections. The two main windowing environments for Linux, KDE and Gnome, both come with GUI utilities for configuring and controlling PPP dial-out connections. They are convenient and relatively easy to configure. A third alternative is to use a PPP front-end package such as wvdial or ezppp. These also will handle most of the details of talking to the modem and setting up the PPP connection for you. Assuming that you don't want to use any of these tools, you want to set up the configuration manually yourself, then read on. This document gives a brief description and example. More details can be found by reading the pppd and chat man pages and the PPP-HOWTO. We assume that you have a modem that uses the Hayes-compatible AT command set connected to an async serial port (e.g. /dev/ttyS0) and that you are dialling out to an ISP. The trickiest and most variable part of setting up a dial-out PPP connection is the part which involves getting the modem to dial and then invoking PPP service at the far end. Generally, once both ends are talking PPP the rest is relatively straightforward. Now in fact pppd doesn't know anything about how to get modems to dial or what you have to say to the system at the far end to get it to talk PPP. That's handled by an external program such as chat, specified with the connect option to pppd. Chat takes a series of strings to expect from the modem interleaved with a series of strings to send to the modem. See the chat man page for more information. Here is a simple example for connecting to an ISP, assuming that the ISP's system starts talking PPP as soon as it answers the phone: pppd connect 'chat -v "" AT OK ATDT5551212 ~' \ /dev/ttyS0 57600 crtscts debug defaultroute Going through pppd's options in order: connect 'chat ...' This gives a command to run to contact the PPP server. Here the supplied 'chat' program is used to dial a remote computer. The whole command is enclosed in single quotes because pppd expects a one-word argument for the 'connect' option. The options to 'chat' itself are: -v verbose mode; log what we do to syslog "" don't wait for any prompt, but instead... AT send the string "AT" OK expect the response "OK", then ATDT5551212 dial the modem, then ~ wait for a ~ character, indicating the start of a PPP frame from the server /dev/ttyS0 specifies which serial port the modem is connected to 57600 specifies the baud rate to use crtscts use hardware flow control using the RTS & CTS signals debug log the PPP negotiation with syslog defaultroute add default network route via the PPP link Pppd will write error messages and debugging logs to the syslogd daemon using the facility name "daemon". These messages may already be logged to the console or to a file like /var/log/messages; consult your /etc/syslog.conf file to see. If you want to make all pppd messages go to a file such as /var/log/ppp-debug, add the line daemon.* /var/log/ppp-debug ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ This is one or more tabs. Do not use spaces. to syslog.conf; make sure to put one or more TAB characters (not spaces!) between the two fields. Then you need to create an empty /var/log/ppp-debug file with a command such as touch /var/log/ppp-debug and then restart syslogd, usually by sending it a SIGHUP signal with a command like this: killall -HUP syslogd 4.1 Is the link up? The main way to tell if your PPP link is up and operational is the ifconfig ("interface configuration") command. Type /sbin/ifconfig at a shell prompt. It should print a list of interfaces including one like this example: ppp0 Link encap Point-to-Point Protocol inet addr 192.76.32.3 P-t-P 129.67.1.165 Mask 255.255.255.0 UP POINTOPOINT RUNNING MTU 1500 Metric 1 RX packets 33 errors 0 dropped 0 overrun 0 TX packets 42 errors 0 dropped 0 overrun 0 Assuming that ifconfig shows the ppp network interface, you can test the link using the ping command like this: /sbin/ping -c 3 129.67.1.165 where the address you give is the address shown as the P-t-P address in the ifconfig output. If the link is operating correctly, you should see output like this: PING 129.67.1.165 (129.67.1.165): 56 data bytes 64 bytes from 129.67.1.165: icmp_seq=0 ttl=255 time=268 ms 64 bytes from 129.67.1.165: icmp_seq=1 ttl=255 time=247 ms 64 bytes from 129.67.1.165: icmp_seq=2 ttl=255 time=266 ms --- 129.67.1.165 ping statistics --- 3 packets transmitted, 3 packets received, 0% packet loss round-trip min/avg/max = 247/260/268 ms ppp-2.5.0/README.MPPE0000644000175000017500000000545411060423633010664 00000000000000PPP Support for MPPE (Microsoft Point to Point Encryption) ========================================================== Frank Cusack frank@google.com Mar 19, 2002 Updated by Paul Mackerras, Sep 2008 DISCUSSION MPPE is Microsoft's encryption scheme for PPP links. It is pretty much solely intended for use with PPP over Internet links -- if you have a true point to point link you have little need for encryption. It is generally used with PPTP. MPPE is negotiated within CCP (Compression Control Protocol) as option 18. In order for MPPE to work, both peers must agree to do it. This complicates things enough that I chose to implement it as strictly a binary option, off by default. If you turn it on, all other compression options are disabled and MPPE *must* be negotiated successfully in both directions (CCP is unidirectional) or the link will be disconnected. I think this is reasonable since, if you want encryption, you want encryption. That is, I am not convinced that optional encryption is useful. While PPP regards MPPE as a "compressor", it actually expands every frame by 4 bytes, the MPPE overhead (encapsulation). Because of the data expansion, you'll see that ppp interfaces get their mtu reduced by 4 bytes whenever MPPE is negotiated. This is because when MPPE is active, it is *required* that *every* packet be encrypted. PPPD sets the mtu = MIN(peer mru, configured mtu). To ensure that MPPE frames are not larger than the peer's mru, we reduce the mtu by 4 bytes so that the network layer never sends ppp a packet that's too large. There is an option to compress the data before encrypting (MPPC), however the algorithm is patented and requires execution of a license with Hifn. MPPC as an RFC is a complete farce. I have no further details on MPPC. Some recommendations: - Use stateless mode. Stateful mode is disabled by default. Unfortunately, stateless mode is very expensive as the peers must rekey for every packet. - Use 128-bit encryption. - Use MS-CHAPv2 only. Reference documents: MPPE MPPE Key Derivation MPPC PPTP MS RADIUS Attributes You might be interested in PoPToP, a Linux PPTP server. You can find it at RADIUS support for MPPE is from Ralf Hofmann, . BUILDING THE PPPD The userland component of PPPD has no additional requirements above those for MS-CHAP and MS-CHAPv2. MPPE support is now included in the mainline Linux kernel releases. CONFIGURATION See pppd(8) for the MPPE options. Under Linux, if your modutils is earlier than 2.4.15, you will need to add alias ppp-compress-18 ppp_mppe to /etc/modules.conf. ppp-2.5.0/README.MSCHAP800000644000175000017500000001377011060430345011244 00000000000000PPP Support for Microsoft's CHAP-80 =================================== Eric Rosenquist rosenqui@strataware.com (updated by Paul Mackerras) (updated by Al Longyear) (updated by Farrell Woods) (updated by Frank Cusack) INTRODUCTION Microsoft has introduced an extension to the Challenge/Handshake Authentication Protocol (CHAP) which avoids storing cleartext passwords on a server. (Unfortunately, this is not as secure as it sounds, because the encrypted password stored on a server can be used by a bogus client to gain access to the server just as easily as if the password were stored in cleartext.) The details of the Microsoft extensions can be found in the document: In short, MS-CHAP is identified as since the hex value of 80 is used to designate Microsoft's scheme. Standard PPP CHAP uses a value of 5. If you enable PPP debugging with the "debug" option and see something like the following in your logs, the remote server is requesting MS-CHAP: rcvd [LCP ConfReq id=0x2 ] ^^^^^^^ MS-CHAP is enabled by default under Linux in pppd/Makefile.linux by the line "CHAPMS=y". CONFIGURATION If you've never used PPPD with CHAP before, read the man page (type "man pppd") and read the description in there. Basically, you need to edit the "chap-secrets" file typically named /etc/ppp/chap-secrets. This should contain the following two lines for each system with which you use CHAP (with no leading blanks): RemoteHost Account Secret Account RemoteHost Secret Note that you need both lines and that item 1 and 2 are swapped in the second line. I'm not sure why you need it twice, but it works and I didn't have time to look into it further. The "RemoteHost" is a somewhat arbitrary name for the remote Windows NT system you're dialing. It doesn't have to match the NT system's name, but it *does* have to match what you use with the "remotename" parameter. The "Account" is the Windows NT account name you have been told to use when dialing, and the "Secret" is the password for that account. For example, if your service provider calls their machine "DialupNT" and tells you your account and password are "customer47" and "foobar", add the following to your chap-secrets file: DialupNT customer47 foobar customer47 DialupNT foobar The only other thing you need to do for MS-CHAP (compared to normal CHAP) is to always use the "remotename" option, either on the command line or in your "options" file (see the pppd man page for details). In the case of the above example, you would need to use the following command line: pppd name customer47 remotename DialupNT or add: name customer47 remotename DialupNT to your PPPD "options" file. The "remotename" option is required for MS-CHAP since Microsoft PPP servers don't send their system name in the CHAP challenge packet. E=691 (AUTHENTICATION_FAILURE) ERRORS WHEN YOU HAVE THE VALID SECRET (PASSWORD) If your RAS server is not the domain controller and is not a 'stand-alone' server then it must make a query to the domain controller for your domain. You need to specify the domain name with the user name when you attempt to use this type of a configuration. The domain name is specified with the local name in the chap-secrets file and with the option for the 'name' parameter. For example, the previous example would become: DialupNT domain\\customer47 foobar domain\\customer47 DialupNT foobar and pppd name 'domain\\customer47' remotename DialupNT or add: name domain\\customer47 remotename DialupNT when the Windows NT domain name is simply called 'domain'. TROUBLESHOOTING Assuming that everything else has been configured correctly for PPP and CHAP, the MS-CHAP-specific problems you're likely to encounter are mostly related to your Windows NT account and its settings. A Microsoft server returns error codes in its CHAP response. The following are extracted from RFC 2433: 646 ERROR_RESTRICTED_LOGON_HOURS 647 ERROR_ACCT_DISABLED 648 ERROR_PASSWD_EXPIRED 649 ERROR_NO_DIALIN_PERMISSION 691 ERROR_AUTHENTICATION_FAILURE 709 ERROR_CHANGING_PASSWORD You'll see these in your pppd log as a line similar to: Remote message: E=649 R=0 The "E=" is the error number from the table above, and the "R=" flag indicates whether the error is transient and the client should retry. If you consistently get error 691, then either you're using the wrong account name/password, or the DES library or MD4 hashing (in md4.c) aren't working properly. Verify your account name and password (use a Windows NT or Windows 95 system to dial-in if you have one available). If that checks out, test the DES library with the "destest" program included with the DES library. If DES checks out, the md4.c routines are probably failing (system byte ordering may be a problem) or my code is screwing up. I've only got access to a Linux system, so you're on your own for anything else. Another thing that might cause problems is that some RAS servers won't respond at all to LCP config requests without seeing the word "CLIENT" from the other end. If you see pppd sending out LCP config requests without getting any reply, try putting something in your chat script to send the word CLIENT after the modem has connected. STILL TO DO A site using only MS-CHAP to authenticate has no need to store cleartext passwords in the "chap-secrets" file. A utility that spits out the ASCII hex MD4 hash of a given password would be nice, and would allow that hash to be used in chap-secrets in place of the password. The code to do this could quite easily be lifted from chap_ms.c (you have to convert the password to Unicode before hashing it). The chap_ms.c file would also have to be changed to recognize a password hash (16 binary bytes == 32 ASCII hex characters) and skip the hashing stage. This would have no real security value as the hash is plaintext-equivalent. ppp-2.5.0/README.MSCHAP810000644000175000017500000000456511060472670011256 00000000000000PPP Support for Microsoft's CHAP-81 =================================== Frank Cusack frank@google.com Some text verbatim from README.MSCHAP80, by Eric Rosenquist, rosenqui@strataware.com INTRODUCTION First, please read README.MSCHAP80; almost everything there applies here. MS-CHAP was basically devised by Microsoft because rather than store plaintext passwords, they (Microsoft) store the md4 hash of passwords. It provides no advantage over standard CHAP, since the hash is used as plaintext-equivalent. (Well, the Change-Password packet is arguably an advantage.) It does introduce a significant weakness if the LM hash is used. Additionally, the format of the failure packet potentially gives information to an attacker. The weakness of the LM hash is partly addressed in RFC 2433, which deprecates its use. MS-CHAPv2 adds 2 benefits to MS-CHAP. (1) The LM hash is no longer used. (2) Mutual authentication is required. Note that the mutual authentication in MS-CHAPv2 is different than the case where both PPP peers require authentication from the other; the former proves that the server has access to the client's password, the latter proves that the server has access to a secret which the client also has -- which may or may not be the same as the client's password (but should not be the same, per RFC 1994). Whether this provides any actual benefit is outside the scope of this document. The details of MS-CHAPv2 can be found in the document: BUILDING THE PPPD In addition to the requirements for MS-CHAP, MS-CHAPv2 uses the SHA-1 hash algorithm. A public domain implementation is provided with pppd. TROUBLESHOOTING Assuming that everything else has been configured correctly for PPP and CHAP, the MS-CHAPv2-specific problems you're likely to encounter are mostly related to your Windows NT account and its settings. A Microsoft server returns error codes in its CHAP response. The following are extracted from RFC 2759: 646 ERROR_RESTRICTED_LOGON_HOURS 647 ERROR_ACCT_DISABLED 648 ERROR_PASSWD_EXPIRED 649 ERROR_NO_DIALIN_PERMISSION 691 ERROR_AUTHENTICATION_FAILURE 709 ERROR_CHANGING_PASSWORD You'll see these in your pppd log as a line similar to: Remote message: E=649 No dialin permission Previously, pppd would log this as: Remote message: E=649 R=0 Now, the text message is logged (both for MS-CHAP and MS-CHAPv2). ppp-2.5.0/README.pppoe0000664000175000017500000000664714121243216011253 00000000000000 PPPoE Support ------------- Michal Ostrowski 8 August 2001 for ppp-2.4.2 Updated for ppp-2.4.5 by Paul Mackerras, Sep 08 1. Introduction --------------- This document describes the support for PPP over Ethernet (PPPoE) included with this package. It is assumed that the reader is familiar with Linux PPP (as it pertains to tty/modem-based connections). In particular, users of PPP in the Linux 2.2 series kernels should ensure they are familiar with the changes to the PPP implementation in the 2.4 series kernels before attempting to use PPPoE features. If you are not familiar with PPP, I recommend looking at other packages which include end-user configuration tools, such as Roaring Penguin (http://www.roaringpenguin.com/pppoe). PPPoE is a protocol typically used by *DSL providers to manage IP addresses and authenticate users. Essentially, PPPoE provides for a PPP connection to be established not over a physical serial-line or modem, but over a logical connection between two unique MAC-addresses on an ethernet network. Once the PPPoE layer discovers the end-points to be used in the link and negotiates it, frames may be sent to and received from the PPPoE layer just as if the link was a serial line (or that is how it's supposed to be). With this in mind, the goal of the implementation of PPPoE support in Linux is to allow users to simply specify that the device they intend to use for the PPP connection is an ethernet device (e.g. "eth0") and the rest of the system should function as usual. 2. Using PPPoE -------------- This section is a quick guide for getting PPPoE working, to allow one to connect to their ISP who is providing PPPoE based services. 1. Enable "Prompt for development and/or incomplete code/drivers" and "PPP over Ethernet" in your kernel configuration. Most distributions will include the kernel PPPoE module by default. 2. Compile and install your kernel. 3. Install the ppp package. 4. Add the following line to /etc/ppp/options: plugin pppoe.so The effect of this line is simply to make "eth0", "eth1", ....,"ethx" all valid device names for pppd (just like ttyS0, ttyS1). 5. Add the necessary authentication options to your pppd configuration (i.e. PAP/CHAP information). If you wish to maintain separate configurations for different devices you may place configuration options in device-specific configuration files: /etc/ppp/options.devname (devname=ttyS0, ttyS1, eth0, eth1 or any other valid device name). 6. Invoke pppd with the appropriate device name: e.g. "pppd eth0" Do not include any compression or flow control options in your PPPoE configuration. They will be ignored. Again, here it is assumed that the reader is familiar with the general process of configuring PPP. The steps outlined here refer only to the steps and configuration options which are PPPoE specific, and it is assumed that the reader will also configure other aspects of the system (e.g. PAP authentication parameters). 3. Advanced Functionality -------------------------- For more advanced functionality (such as providing PPPoE services) and user configuration tools, look to the Roaring Penguin PPPoE software package (http://www.roaringpenguin.com/pppoe). 4. Credits ----------- The PPPoE plugin included in this package is a component of the Roaring Penguin PPPoE package, included in this package courtesy of Roaring Penguin Software. (http://www.roaringpenguin.com). ppp-2.5.0/README.pppol2tp0000644000175000017500000000476011025137335011704 00000000000000PPPoL2TP plugin =============== The pppol2tp plugin lets pppd use the Linux kernel driver pppol2tp.ko to pass PPP frames in L2TP tunnels. The driver was integrated into the kernel in the 2.6.23 release. For kernels before 2.6.23, an out-of-tree kernel module is available from the pppol2tp-kmod package in the OpenL2TP project. Note that pppd receives only PPP control frames over the PPPoL2TP socket; data frames are handled entirely by the kernel. The pppol2tp plugin adds extra arguments to pppd and uses the Linux kernel PPP-over-L2TP driver to set up each session's data path. Arguments are:- pppol2tp - FD for PPPoL2TP socket pppol2tp_lns_mode - PPPoL2TP LNS behavior. Default off. pppol2tp_send_seq - PPPoL2TP enable sequence numbers in transmitted data packets. Default off. pppol2tp_recv_seq - PPPoL2TP enforce sequence numbers in received data packets. Default off. pppol2tp_reorderto - PPPoL2TP data packet reorder timeout. Default 0 (no reordering). pppol2tp_debug_mask - PPPoL2TP debug mask. Bitwise OR of 1 - verbose debug 2 - control 4 - kernel transport 8 - ppp packet data Default: 0 (no debug). pppol2tp_ifname - Name of PPP network interface visible to "ifconfig" and "ip link". Default: "pppN" pppol2tp_tunnel_id - L2TP tunnel_id tunneling this PPP session. pppol2tp_session_id - L2TP session_id of this PPP session. The tunnel_id/session_id pair is used when sending event messages to openl2tpd. pppd will typically be started by an L2TP daemon for each L2TP sesion, supplying one or more of the above arguments as required. The pppd user will usually have no visibility of these arguments. Two hooks are exported by this plugin. void (*pppol2tp_send_accm_hook)(int tunnel_id, int session_id, uint32_t send_accm, uint32_t recv_accm); void (*pppol2tp_ip_updown_hook)(int tunnel_id, int session_id, int up); Credits ======= This plugin was developed by Katalix Systems as part of the OpenL2TP project, http://openl2tp.sourceforge.net. OpenL2TP is a full-featured L2TP client-server, suitable for use as an enterprise L2TP VPN server or a VPN client. Please copy problems to the OpenL2TP mailing list: openl2tp-users@lists.sourceforge.net. Maintained by: James Chapman jchapman@katalix.com Katalix Systems Ltd http://www.katalix.com ppp-2.5.0/README.pwfd0000644000175000017500000000674411060440671011067 00000000000000 Support to pass the password via a pipe to the pppd --------------------------------------------------- Arvin Schnell 2002-02-08 1. Introduction --------------- Normally programs like wvdial or kppp read the online password from their config file and store them in the pap- and chap-secrets before they start the pppd and remove them afterwards. Sure they need special privileges to do so. The passwordfd feature offers a simpler and more secure solution. The program that starts the pppd opens a pipe and writes the password into it. The pppd simply reads the password from that pipe. This methods is used for quite a while on SuSE Linux by the programs wvdial, kppp and smpppd. 2. Example ---------- Here is a short C program that uses the passwordfd feature. It starts the pppd to buildup a pppoe connection. --snip-- #include #include #include #include #include #include #ifndef _PATH_PPPD #define _PATH_PPPD "/usr/sbin/pppd" #endif // Of course these values can be read from a configuration file or // entered in a graphical dialog. char *device = "eth0"; char *username = "1122334455661122334455660001@t-online.de"; char *password = "hello"; pid_t pid = 0; void sigproc (int src) { fprintf (stderr, "Sending signal %d to pid %d\n", src, pid); kill (pid, src); exit (EXIT_SUCCESS); } void sigchild (int src) { fprintf (stderr, "Daemon died\n"); exit (EXIT_SUCCESS); } int start_pppd () { signal (SIGINT, &sigproc); signal (SIGTERM, &sigproc); signal (SIGCHLD, &sigchild); pid = fork (); if (pid < 0) { fprintf (stderr, "unable to fork() for pppd: %m\n"); return 0; } if (pid == 0) { int i, pppd_argc = 0; char *pppd_argv[20]; char buffer[32] = ""; int pppd_passwdfd[2]; for (i = 0; i < 20; i++) pppd_argv[i] = NULL; pppd_argv[pppd_argc++] = "pppd"; pppd_argv[pppd_argc++] = "call"; pppd_argv[pppd_argc++] = "pwfd-test"; // The device must be after the call, since the call loads the plugin. pppd_argv[pppd_argc++] = device; pppd_argv[pppd_argc++] = "user"; pppd_argv[pppd_argc++] = username; // Open a pipe to pass the password to pppd. if (pipe (pppd_passwdfd) == -1) { fprintf (stderr, "pipe failed: %m\n"); exit (EXIT_FAILURE); } // Of course this only works it the password is shorter // than the pipe buffer. Otherwise you have to fork to // prevent that your main program blocks. write (pppd_passwdfd[1], password, strlen (password)); close (pppd_passwdfd[1]); // Tell the pppd to read the password from the fd. pppd_argv[pppd_argc++] = "passwordfd"; snprintf (buffer, 32, "%d", pppd_passwdfd[0]); pppd_argv[pppd_argc++] = buffer; if (execv (_PATH_PPPD, (char **) pppd_argv) < 0) { fprintf (stderr, "cannot execl %s: %m\n", _PATH_PPPD); exit (EXIT_FAILURE); } } pause (); return 1; } int main (int argc, char **argv) { if (start_pppd ()) exit (EXIT_SUCCESS); exit (EXIT_FAILURE); } ---snip--- Copy this file to /etc/ppp/peers/pwfd-test. The plugins can't be loaded on the command line (unless you are root) since the plugin option is privileged. ---snip--- # # PPPoE plugin for kernel 2.4 # plugin pppoe.so # # This plugin enables us to pipe the password to pppd, thus we don't have # to fiddle with pap-secrets and chap-secrets. The user is also passed # on the command line. # plugin passwordfd.so noauth usepeerdns defaultroute hide-password nodetach nopcomp novjccomp noccp ---snip--- ppp-2.5.0/README.sol20000644000175000017500000002402507536326177011017 00000000000000This file describes the installation process for ppp-2.4 on systems running Solaris. The Solaris and SVR4 ports share a lot of code but are not identical. The STREAMS kernel modules and driver for Solaris are in the solaris directory (and use some code from the modules directory). NOTE: Although the kernel driver and modules have been designed to operate correctly on SMP systems, they have not been extensively tested on SMP machines. Some users of SMP Solaris x86 systems have reported system problems apparently linked to the use of previous versions of this software. I believe these problems have been fixed. Installation. ************* 1. Run the configure script and make the user-level programs and the kernel modules. ./configure make The configure script will automatically find Sun's cc if it's in the standard location (/opt/SUNWspro/bin/cc). If you do not have Sun's WorkShop compiler, configure will attempt to use 'gcc'. If this is found and you have a 64 bit kernel, it will check that gcc accepts the "-m64" option, which is required to build kernel modules. You should not have to edit the Makefiles for most ordinary cases. 2. Install the programs and kernel modules: as root, do make install This installs pppd, chat and pppstats in /usr/local/bin and the kernel modules in /kernel/drv and /kernel/strmod, and creates the /etc/ppp directory and populates it with default configuration files. You can change the installation directories by editing solaris/Makedefs. If you have a 64 bit kernel, the 64-bit drivers are installed in /kernel/drv/sparcv9 and /kernel/strmod/sparcv9. If your system normally has only one network interface at boot time, the default Solaris system startup scripts will disable IP forwarding in the IP kernel module. This will prevent the remote machine from using the local machine as a gateway to access other hosts. The solution is to create an /etc/ppp/ip-up script containing something like this: #!/bin/sh /usr/sbin/ndd -set /dev/ip ip_forwarding 1 See the man page for ip(7p) for details. Integrated pppd *************** Solaris 8 07/01 (Update 5) and later have an integrated version of pppd, known as "Solaris PPP 4.0," and is based on ppp-2.4.0. This version comes with the standard Solaris software distribution and is supported by Sun. It is fully tested in 64-bit and SMP modes, and with bundled and unbundled synchronous drivers. Solaris 8 10/01 (Update 6) and later includes integrated PPPoE client and server support, with kernel-resident data handling. See pppd(1M). The feature is part of the regular full installation, and is provided by these packages: SUNWpppd - 32-bit mode kernel drivers SUNWpppdr - root-resident /etc/ppp config samples SUNWpppdu - /usr/bin/pppd itself, plus chat SUNWpppdx - 64-bit mode kernel drivers SUNWpppdt - PPPoE support SUNWpppg - GPL'd optional 'pppdump' and plugins SUNWpppgS - Source for GPL'd optional features Use the open source version of pppd if you wish to recompile to add new features or to experiment with the code. Production systems, however, should run the Sun-supplied version, if at all possible. You can run both versions on a single system if you wish. The Solaris PPP 4.0 interfaces are named "spppN," while this open source version names its interfaces as "pppN". The STREAMS modules are similarly separated. The Sun-supplied pppd lives in /usr/bin/pppd, while the open source version installs (by default) in /usr/local/bin/pppd. Dynamic STREAMS Re-Plumbing Support. ************************************ Solaris 8 (and later) includes dynamic re-plumbing support. With this feature, modules below ip can be inserted, or removed, without having the ip stream be unplumbed, and re-plumbed again. All state in ip for the interface will be preserved as modules are added or removed. Users can install (or upgrade) modules such as firewall, bandwidth manager, cache manager, tunneling, etc., without shutting the interface down. To support this, ppp driver now uses /dev/udp instead of /dev/ip for the ip stream. The interface stream (where ip module pushed on top of ppp) is then I_PLINK'ed below the ip stream. /dev/udp is used because STREAMS will not let a driver be PLINK'ed under itself, and /dev/ip is typically the driver at the bottom of the tunneling interfaces stream. The mux ids of the ip streams are then added using SIOCSxIFMUXID ioctl. Users will be able to see the modules on the interface stream by, for example: pikapon# ifconfig ppp modlist 0 ip 1 ppp Or arbitrarily if bandwidth manager and firewall modules are installed: pikapon# ifconfig hme0 modlist 0 arp 1 ip 2 ipqos 3 firewall 4 hme Snoop Support. ************** This version includes support for /usr/sbin/snoop. Tests have been done on Solaris 7 through 9. Only IPv4 and IPv6 packets will be sent up to stream(s) marked as promiscuous (i.e., those used by snoop). Users will be able to see the packets on the ppp interface by, for example: snoop -d ppp0 See the man page for snoop(1M) for details. IPv6 Support. ************* This is for Solaris 8 and later. This version has been tested under Solaris 8 and 9 running IPv6. Interoperability testing has only been done between Solaris machines in terms of the IPV6 NCP. An additional command line option for the pppd daemon has been added: ipv6cp-use-persistent. By default, compilation for IPv6 support is not enabled. Uncomment the necessary lines in pppd/Makefile.sol2 to enable it. Once done, the quickest way to get IPv6 running is to add the following somewhere in the command line option: +ipv6 ipv6cp-use-persistent The persistent id for the link-local address was added to conform to RFC 2472; such that if there's an EUI-48 available, use that to make up the EUI-64. As of now, the Solaris implementation extracts the EUI-48 id from the Ethernet's MAC address (the ethernet interface needs to be up). Future work might support other ways of obtaining a unique yet persistent id, such as EEPROM serial numbers, etc. There need not be any up/down scripts for ipv6, e.g. /etc/ppp/ipv6-up or /etc/ppp/ipv6-down, to trigger IPv6 neighbor discovery for auto configuration and routing. The in.ndpd daemon will perform all of the necessary jobs in the background. /etc/inet/ndpd.conf can be further customized to enable the machine as an IPv6 router. See the man page for in.ndpd(1M) and ndpd.conf(4) for details. Below is a sample output of "ifconfig -a" with persistent link-local address. Note the UNNUMBERED flag is set because hme0 and ppp0 both have identical link-local IPv6 addresses: lo0: flags=1000849 mtu 8232 index 1 inet 127.0.0.1 netmask ff000000 hme0: flags=1000843 mtu 1500 index 2 inet 129.146.86.248 netmask ffffff00 broadcast 129.146.86.255 ether 8:0:20:8d:38:c1 lo0: flags=2000849 mtu 8252 index 1 inet6 ::1/128 hme0: flags=2000841 mtu 1500 index 2 ether 8:0:20:8d:38:c1 inet6 fe80::a00:20ff:fe8d:38c1/10 hme0:1: flags=2080841 mtu 1500 index 2 inet6 fec0::56:a00:20ff:fe8d:38c1/64 hme0:2: flags=2080841 mtu 1500 index 2 inet6 2000::56:a00:20ff:fe8d:38c1/64 hme0:3: flags=2080841 mtu 1500 index 2 inet6 2::56:a00:20ff:fe8d:38c1/64 ppp0: flags=10008d1 mtu 1500 index 12 inet 172.16.1.1 --> 172.16.1.2 netmask ffffff00 ppp0: flags=2202851 mtu 1500 index 12 inet6 fe80::a00:20ff:fe8d:38c1/10 --> fe80::a00:20ff:fe7a:24fb Note also that a plumbed ipv6 interface stream will exist throughout the entire PPP session in the case where the peer rejects IPV6CP, which further causes the interface state to stay down. Unplumbing will happen when the daemon exits. This is done by design and is not a bug. 64-bit Support. *************** This version has been tested under Solaris 7 through 9 in both 32- and 64-bit environments (Ultra class machines). Installing the package by executing "make install" will result in additional files residing in /kernel/drv/sparcv9 and /kernel/strmod/sparcv9 subdirectories. 64-bit modules and driver have been compiled and tested using Sun's cc and gcc. Synchronous Serial Support. *************************** This version has working but limited support for the on-board synchronous HDLC interfaces. It has been tested with the /dev/se_hdlc, /dev/zsh, HSI/S, and HSI/P drivers. Synchronous mode was tested with a Cisco router. The ppp daemon does not directly support controlling the serial interface. It relies on the /usr/sbin/syncinit command to initialize HDLC mode and clocking. There is a confirmed bug with NRZ/NRZI mode in the /dev/se_hdlc driver, and Solaris patch 104596-11 is needed to correct it. (However this patch seems to introduce other serial problems. If you don't apply the patch, the workaround is to change the nrzi mode to yes or no, whichever works.) How to start pppd with synchronous support: #!/bin/sh local=1.1.1.1 # your ip address here baud=38400 # needed, but ignored by serial driver # Change to the correct serial driver/port #dev=/dev/zsh0 dev=/dev/se_hdlc0 # Change the driver, nrzi mode, speed and clocking to match # your setup. # This configuration is for external clocking from the DCE connect="syncinit se_hdlc0 nrzi=no speed=64000 txc=rxc rxc=rxc" /usr/sbin/pppd $dev sync $baud novj noauth $local: connect "$connect" Sample Cisco router config excerpt: ! ! Cisco router setup as DCE with RS-232 DCE cable ! ! interface Serial0 ip address 1.1.1.2 255.255.255.0 encapsulation ppp clockrate 64000 no nrzi-encoding no shutdown ! ppp-2.5.0/PLUGINS0000644000175000017500000003406714407475306010326 00000000000000Starting with version 2.3.10, pppd includes support for `plugins' - pieces of code which can be loaded into pppd at runtime and which can affect its behaviour in various ways. The idea of plugins is to provide a way for people to customize the behaviour of pppd without having to either apply local patches to each version or get their patches accepted into the standard distribution. A plugin is a standard shared library object, typically with a name ending in .so. They are loaded using the standard dlopen() library call, so plugins are only supported on systems which support shared libraries and the dlopen call. At present pppd is compiled with plugin support only under Linux and Solaris. Plugins are loaded into pppd using the `plugin' option, which takes one argument, the name of a shared object file. The plugin option is a privileged option. If the name given does not contain a slash, pppd will look in the /usr/lib/pppd/ directory for the file, where is the version number of pppd, for example, 2.4.2. I suggest that you either give the full path name of the shared object file or just the base name; if you don't, it may be possible for unscrupulous users to substitute another shared object file for the one you mean to load, e.g. by setting the LD_LIBRARY_PATH variable. Plugins are usually written in C and compiled and linked to a shared object file in the appropriate manner for your platform. Using gcc under Linux, a plugin called `xyz' could be compiled and linked with the following commands: gcc -c -O xyz.c gcc -shared -o xyz.so xyz.o There are some example plugins in the pppd/plugins directory in the ppp distribution. Currently there is one example, minconn.c, which implements a `minconnect' option, which specifies a minimum connect time before the idle timeout applies. Plugins can access global variables within pppd, so it is useful for them to #include "pppd.h" from the pppd source directory. Other header files can be included such as chap.h, mppe.h, and upap.h as needed per project. Every plugin must contain a global procedure called `plugin_init'. This procedure will get called (with no arguments) immediately after the plugin is loaded. Every plugin should also contain a variable called pppd_version declared as follows: char pppd_version[] = PPPD_VERSION; If this declaration is included, pppd will not load the module if its version number differs from that compiled into the plugin binary. Plugins can affect the behaviour of pppd in at least four ways: 1. They can add extra options which pppd will then recognize. This is done by calling the ppp_add_options() procedure with a pointer to an array of option_t structures. The last entry in the array must have its name field set to NULL. 2. Pppd contains `hook' variables which are procedure pointers. If a given hook is not NULL, pppd will call the procedure it points to at the appropriate point in its processing. The plugin can set any of these hooks to point to its own procedures. See below for a description of the hooks which are currently implemented. 3. Plugin code can call any global procedures and access any global variables in pppd. 4. Plugins can register procedures to be called when particular events occur, using the `notifier' mechanism in pppd. The differences between hooks and notifiers are that a hook will only call one function, whereas a notifier can call an arbitrary number, and that a hook usually returns some value to pppd, whereas a notifier function returns nothing. Here is a list of the currently implemented hooks in pppd. int (*idle_time_hook)(struct ppp_idle *idlep); The idle_time_hook is called when the link first comes up (i.e. when the first network protocol comes up) and at intervals thereafter. On the first call, the idlep parameter is NULL, and the return value is the number of seconds before pppd should check the link activity, or 0 if there is to be no idle timeout. On subsequent calls, idlep points to a structure giving the number of seconds since the last packets were sent and received. If the return value is > 0, pppd will wait that many seconds before checking again. If it is <= 0, that indicates that the link should be terminated due to lack of activity. int (*holdoff_hook)(void); The holdoff_hook is called when an attempt to bring up the link fails, or the link is terminated, and the persist or demand option was used. It returns the number of seconds that pppd should wait before trying to reestablish the link (0 means immediately). int (*pap_check_hook)(void); int (*pap_passwd_hook)(char *user, char *passwd); int (*pap_auth_hook)(char *user, char *passwd, char **msgp, struct wordlist **paddrs, struct wordlist **popts); void (*pap_logout_hook)(void); These hooks are designed to allow a plugin to replace the normal PAP password processing in pppd with something different (e.g. contacting an external server). The pap_check_hook is called to check whether there is any possibility that the peer could authenticate itself to us. If it returns 1, pppd will ask the peer to authenticate itself. If it returns 0, pppd will not ask the peer to authenticate itself (but if authentication is required, pppd may exit, or terminate the link before network protocol negotiation). If it returns -1, pppd will look in the pap-secrets file as it would normally. The pap_passwd_hook is called to determine what username and password pppd should use in authenticating itself to the peer with PAP. The user string will already be initialized, by the `user' option, the `name' option, or from the hostname, but can be changed if necessary. MAXNAMELEN bytes of space are available at *user, and MAXSECRETLEN bytes of space at *passwd. If this hook returns 0, pppd will use the values at *user and *passwd; if it returns -1, pppd will look in the pap-secrets file, or use the value from the +ua or password option, as it would normally. The pap_auth_hook is called to determine whether the username and password supplied by the peer are valid. user and passwd point to null-terminated strings containing the username and password supplied by the peer, with non-printable characters converted to a printable form. The pap_auth_hook function should set msg to a string to be returned to the peer and return 1 if the username/password was valid and 0 if not. If the hook returns -1, pppd will look in the pap-secrets file as usual. If the username/password was valid, the hook can set *paddrs to point to a wordlist containing the IP address(es) which the peer is permitted to use, formatted as in the pap-secrets file. It can also set *popts to a wordlist containing any extra options for this user which pppd should apply at this point. The pap_logout_hook is called when the link is terminated, instead of pppd's internal `plogout' function. It can be used for accounting purposes. This hook is deprecated and will be replaced by a notifier. int (*chap_check_hook)(void); int (*chap_passwd_hook)(char *user, char *passwd); int (*chap_verify_hook)(char *name, char *ourname, int id, struct chap_digest_type *digest, unsigned char *challenge, unsigned char *response, char *message, int message_space) These hooks are designed to allow a plugin to replace the normal CHAP password processing in pppd with something different (e.g. contacting an external server). The chap_check_hook is called to check whether there is any possibility that the peer could authenticate itself to us. If it returns 1, pppd will ask the peer to authenticate itself. If it returns 0, pppd will not ask the peer to authenticate itself (but if authentication is required, pppd may exit, or terminate the link before network protocol negotiation). If it returns -1, pppd will look in the chap-secrets file as it would normally. The chap_passwd_hook is called to determine what password pppd should use in authenticating itself to the peer with CHAP. The user string will already be initialized, by the `user' option, the `name' option, or from the hostname, but can be changed if necessary. This hook is called only if pppd is a client, not if it is a server. MAXSECRETLEN bytes of space are available at *passwd. If this hook returns 0, pppd will use the value *passwd; if it returns -1, pppd will fail to authenticate. The chap_verify_hook is called to determine whether the peer's response to our CHAP challenge is valid -- it should return 1 if valid or 0 if not. The parameters are: * name points to a null-terminated string containing the username supplied by the peer, or the remote name specified with the "remotename" option. * ourname points to a null-terminated string containing the name of the local machine (the hostname, or the name specified with the "name" option). * id is the value of the id field from the challenge. * digest points to a chap_digest_type struct, which contains an identifier for the type of digest in use plus function pointers for functions for dealing with digests of that type. * challenge points to the challenge as a counted string (length byte followed by the actual challenge bytes). * response points to the response as a counted string. * message points to an area of message_space bytes in which to store any message that should be returned to the peer. int (*null_auth_hook)(struct wordlist **paddrs, struct wordlist **popts); This hook allows a plugin to determine what the policy should be if the peer refuses to authenticate when it is requested to. If the return value is 0, the link will be terminated; if it is 1, the connection is allowed to proceed, and in this case *paddrs and *popts can be set as for pap_auth_hook, to specify what IP addresses are permitted and any extra options to be applied. If the return value is -1, pppd will look in the pap-secrets file as usual. void (*ip_choose_hook)(u_int32_t *addrp); This hook is called at the beginning of IPCP negotiation. It gives a plugin the opportunity to set the IP address for the peer; the address should be stored in *addrp. If nothing is stored in *addrp, pppd will determine the peer's address in the usual manner. int (*allowed_address_hook)(u_int32_t addr) This hook is called to see if a peer is allowed to use the specified address. If the hook returns 1, the address is accepted. If it returns 0, the address is rejected. If it returns -1, the address is verified in the normal away against the appropriate options and secrets files. void (*snoop_recv_hook)(unsigned char *p, int len) void (*snoop_send_hook)(unsigned char *p, int len) These hooks are called whenever pppd receives or sends a packet. The packet is in p; its length is len. This allows plugins to "snoop in" on the pppd conversation. The hooks may prove useful in implmenting L2TP. void (*multilink_join_hook)(); This is called whenever a new link completes LCP negotiation and joins the bundle, if we are doing multilink. A plugin registers itself with a notifier by declaring a procedure of the form: void (ppp_notify_fn)(void *opaque, int arg); and then registering the procedure with the appropriate notifier with a call of the form ppp_add_notify(ppp_notify_t, ppp_notify_fn, opaque); The ppp_notify_t is an enumerated type that describes which notifier to attach the function to. Example: NF_EXIT, NF_SIGNALED, NF_IP_UP The `opaque' parameter in the add_notifier call will be passed to my_notify_proc every time it is called. The `arg' parameter to my_notify_proc depends on the notifier. A notify procedure can be removed from the list for a notifier with a call of the form ppp_del_notify(ppp_notify_t, ppp_notify_fn, opaque); Here is a list of the currently-implemented notifiers in pppd. * NF_PID_CHANGE. This notifier is called in the parent when pppd has forked and the child is continuing pppd's processing, i.e. when pppd detaches from its controlling terminal. The argument is the pid of the child. * NF_PHASE_CHANGE. This is called when pppd moves from one phase of operation to another. The argument is the new phase number. * NF_EXIT. This is called just before pppd exits. The argument is the status with which pppd will exit (i.e. the argument to exit()). * NF_SIGNALED. This is called when a signal is received, from within the signal handler. The argument is the signal number. * NF_IP_UP. This is called when IPCP has come up. * NF_IP_DOWN. This is called when IPCP goes down. * NF_IPV6_UP. This is called when IP6CP has come up. * NF_IPV6_DOWN. This is called when IP6CP goes down. * NF_AUTH_UP. This is called when the peer has successfully authenticated itself. * NF_LINK_DOWN. This is called when the link goes down. * NF_FORK. Called for each time pppd exists as a new process (child). Regarding MPPE keys and key-material for 2.5.0 release Sometimes it is necessary for a plugin to access details related to the authentication process. The NF_AUTH_UP callback notifier (client only) allows a plugin to inspect e.g. key details after authentication has been completed, but before the key material is cleared from memory for security reasons. There are in particularly 3 functions that allow one to inspect these keys: * bool mppe_keys_isset() * int mppe_get_recv_key(unsigned char *key, int length) * int mppe_get_send_key(unsigned char *key, int length) The first function indicates whether or not the key material is set and is valid. The two latter functions will allow one to obtain a copy of the respective receive and send keys. The return value of these functions is the length of the valid key material. For security reasons, one should take care to clear these copies when work is complete. The max length of MPPE receive ands send keys are up to 32 bytes long, or of MPPE_MAX_KEY_SIZE length. The previous definitions of MPPE_MAX_KEY_LEN is the maximum length in which the Linux kernel will accept for MPPE key lengths. Plugins would access the MPPE keys directly via the: extern u_char mppe_send_key[MPPE_MAX_KEY_LEN] extern u_char mppe_recv_key[MPPE_MAX_KEY_LEN] variables. The 2.5.0 release prohibits the direct access of these variables by making them static and private in favor of using the new API. ## $Id: PLUGINS,v 1.8 2008/06/15 07:02:18 paulus Exp $ ##ppp-2.5.0/SETUP0000644000175000017500000001016010007342715010056 00000000000000 Configuring a PPP link. After you have compiled and installed this package, there are some configuration files which will generally need to be set up. The pppd(8) man page is the best reference for the full details; this file outlines the configuration process for the most common case, where this package is being used to enable a machine to dial an ISP and connect to the internet. The FAQ and README.linux files also provide useful information about setting up PPP. Dialling an ISP. **************** Usually, an ISP will assign an IP address to your machine, and will refuse to authenticate itself to you. Some ISPs require a username and password to be entered before PPP service commences, while others use PPP authentication (using either the PAP or CHAP protocols). The recommended way to set up to dial an ISP is for the system administrator to create a file under /etc/ppp/peers, named for the ISP that you will be dialling. For example, suppose the file is called /etc/ppp/peers/isp. This file would contain something like this: ttyS0 # modem is connected to /dev/ttyS0 38400 # run the serial port at 38400 baud crtscts # use hardware flow control noauth # don't require the ISP to authenticate itself defaultroute # use the ISP as our default route connect '/usr/sbin/chat -v -f /etc/ppp/chat-isp' If there are any other pppd options that should apply when calling this ISP, they can also be placed in this file. The /etc/ppp/chat-isp file named in the last line contains the script for chat(8) to use to dial the ISP and go through any username/ password authentication required before PPP service starts. Here is an example (for dialling an Annex terminal server): ABORT "NO CARRIER" ABORT "NO DIALTONE" ABORT "ERROR" ABORT "NO ANSWER" ABORT "BUSY" ABORT "Username/Password Incorrect" "" "at" OK "at&d2&c1" OK "atdt2479381" "name:" "^Uusername" "word:" "\qpassword" "annex" "ppp" "Switching to PPP-ppp-Switching to PPP" See the chat(8) man page for details of the script. If you are not sure how the initial dialog with your ISP will go, you could use a terminal emulator such as kermit or minicom to go through the process manually. If your ISP requires PAP or CHAP authentication, you will have to create a line in /etc/ppp/pap-secrets or /etc/ppp/chap-secrets like this: myhostname * "password" (Replace myhostname with the hostname of your machine.) At this point, you can initiate the link with the command: /usr/sbin/pppd call isp (N.B.: pppd might be installed in a different directory on some systems). This will return to the shell prompt immediately, as pppd will detach itself from its controlling terminal. (If you don't want it to do this, use the "nodetach" option.) Pppd will log messages describing the progress of the connection and any errors using the syslog facility (see the syslogd(8) and syslog.conf(5) man pages). Pppd issues messages using syslog facility daemon (or local2 if it has been compiled with debugging enabled); chat uses facility local2. It is often useful to see messages of priority notice or higher on the console. To see these, find the line in /etc/syslog.conf which has /dev/console on the right-hand side, and add `daemon.notice' on the left. This line should end up something like this: *.err;kern.debug;daemon,local2,auth.notice;mail.crit /dev/console If you want to see more messages from pppd, request messages of priority info or higher for facility daemon, like this: *.err;kern.debug;daemon.info;local2,auth.notice;mail.crit /dev/console It is also useful to add a line like this: daemon,local2.debug /etc/ppp/ppp-log If you do this, you will need to create an empty /etc/ppp/ppp-log file. After modifying syslog.conf, you will then need to send a HUP signal to syslogd (or reboot). When you wish terminate the PPP link, you should send a TERM or INTR signal to pppd. Pppd writes its process ID to a file called ppp.pid in /var/run (or /etc/ppp on older systems such as SunOS or Ultrix). Here is the PPP interface unit number, which will be 0 unless you have more than one PPP link running simultaneously. Thus you can terminate the link with a command like kill `cat /var/run/ppp0.pid` ppp-2.5.0/Submitting-patches.md0000644000175000017500000001107013477365265013353 00000000000000How to contribute patches to the PPP project. ============================================= The PPP project source code is maintained in a Git repository, which is publicly available at git://git.ozlabs.org/~paulus/ppp.git and https://github.com/paulusmack/ppp.git The linux-ppp@vger.kernel.org mailing list is a suitable place to discuss issues relating to the PPP code and to post patches. Although there is a copy of the repository on github.com, the PPP project is not a "github project", in the sense that the development of the code does not depend on github infrastructure. In particular, patch descriptions should be understandable without reference to any github.com web page. Thus, patches or commits whose description consists only of something like "Closes #123" will be rejected. See below for the minimum standards for patch descriptions. There are two ways in which patches can be submitted for review: 1. Post the patch on the linux-ppp@vger.kernel.org mailing list. This is my preferred way to receive patches, because it provides more opportunity for other interested people to review the patches. 2. Create a pull request on github.com. However, please don't make the mistake of creating a commit with a minimal commit message and then explaining the rationale for the change in the pull request. Put the rationale in the commit message. Requirements for patch/commit description ----------------------------------------- The description on a patch, which becomes the commit message in the resulting commit, should describe the reason why the change is being made. If it fixes a bug, it should describe the bug in enough detail for the reader to understand why and how the change being made fixes the bug. If it adds a feature, it should describe the feature and how it might be used and why it would be desirable to have the feature. Normally the patch description should be a few paragraphs in length -- it can be longer for a really subtle bug or complex feature, or shorter for obvious or trivial changes such as fixing spelling mistakes. The first line of the commit message is the "headline", corresponding to the subject line of an emailed patch. If the patch is concerned with one particular area of the package, it is helpful to put that at the beginning, followed by a colon (':'), for example, "pppd: Fix bug in vslprintf". The remainder of the headline should be a sentence and should start with a capital letter. Note that as maintainer I will edit the headline or the commit message if necessary to make it clearer or to fix spelling or grammatical errors. For a github pull request I may cherry-pick the commits and modify their commit messages. References to information on web sites are permitted provided that the full URL is given, and that reference to the web site is not essential for understanding the change being made. For example, you can refer to a github issue provided that you also put the essential details of the issue in the commit message, and put the full URL for the issue, not just the issue number. Signoff ------- In order to forestall possible (though unlikely) future legal problems, this project requires a "Signed-off-by" line on all non-trivial patches, with a real name (not just initials, and no pseudonyms). Signing off indicates that you certify that your patch meets the 'Developer's Certificate of Origin' below (taken from the DCO 1.1 in the Linux kernel source tree). Developer's Certificate of Origin --------------------------------- By making a contribution to this project, I certify that: (a) The contribution was created in whole or in part by me and I have the right to submit it under the open source license indicated in the file; or (b) The contribution is based upon previous work that, to the best of my knowledge, is covered under an appropriate open source license and I have the right under that license to submit that work with modifications, whether created in whole or in part by me, under the same open source license (unless I am permitted to submit under a different license), as indicated in the file; or (c) The contribution was provided directly to me by some other person who certified (a), (b) or (c) and I have not modified it. (d) I understand and agree that this project and the contribution are public and that a record of the contribution (including all personal information I submit with it, including my sign-off) is maintained indefinitely and may be redistributed consistent with this project or the open source license(s) involved. ppp-2.5.0/chat/0000755000175000017500000000000014412736275010250 500000000000000ppp-2.5.0/chat/Makefile.am0000664000175000017500000000021314076444143012216 00000000000000sbin_PROGRAMS = chat dist_man8_MANS = chat.8 chat_SOURCES = chat.c chat_CPPFLAGS = -DTERMIOS -DSIGTYPE=void -UNO_SLEEP -DFNDELAY=O_NDELAY ppp-2.5.0/chat/chat.80000644000175000017500000004454512155232627011206 00000000000000.\" -*- nroff -*- .\" manual page [] for chat 1.8 .\" $Id: chat.8,v 1.11 2004/11/13 12:22:49 paulus Exp $ .\" SH section heading .\" SS subsection heading .\" LP paragraph .\" IP indented paragraph .\" TP hanging label .TH CHAT 8 "22 May 1999" "Chat Version 1.22" .SH NAME chat \- Automated conversational script with a modem .SH SYNOPSIS .B chat [ .I options ] .I script .SH DESCRIPTION .LP The \fIchat\fR program defines a conversational exchange between the computer and the modem. Its primary purpose is to establish the connection between the Point-to-Point Protocol Daemon (\fIpppd\fR) and the remote's \fIpppd\fR process. .SH OPTIONS .TP .B \-f \fI Read the chat script from the chat \fIfile\fR. The use of this option is mutually exclusive with the chat script parameters. The user must have read access to the file. Multiple lines are permitted in the file. Space or horizontal tab characters should be used to separate the strings. .TP .B \-t \fI Set the timeout for the expected string to be received. If the string is not received within the time limit then the reply string is not sent. An alternate reply may be sent or the script will fail if there is no alternate reply string. A failed script will cause the \fIchat\fR program to terminate with a non-zero error code. .TP .B \-r \fI Set the file for output of the report strings. If you use the keyword \fIREPORT\fR, the resulting strings are written to this file. If this option is not used and you still use \fIREPORT\fR keywords, the \fIstderr\fR file is used for the report strings. .TP .B \-e Start with the echo option turned on. Echoing may also be turned on or off at specific points in the chat script by using the \fIECHO\fR keyword. When echoing is enabled, all output from the modem is echoed to \fIstderr\fR. .TP .B \-E Enables environment variable substitution within chat scripts using the standard \fI$xxx\fR syntax. .TP .B \-v Request that the \fIchat\fR script be executed in a verbose mode. The \fIchat\fR program will then log the execution state of the chat script as well as all text received from the modem and the output strings sent to the modem. The default is to log through the SYSLOG; the logging method may be altered with the \-S and \-s flags. .TP .B \-V Request that the \fIchat\fR script be executed in a stderr verbose mode. The \fIchat\fR program will then log all text received from the modem and the output strings sent to the modem to the stderr device. This device is usually the local console at the station running the chat or pppd program. .TP .B \-s Use stderr. All log messages from '\-v' and all error messages will be sent to stderr. .TP .B \-S Do not use the SYSLOG. By default, error messages are sent to the SYSLOG. The use of \-S will prevent both log messages from '\-v' and error messages from being sent to the SYSLOG. .TP .B \-T \fI Pass in an arbitrary string, usually a phone number, that will be substituted for the \eT substitution metacharacter in a send string. .TP .B \-U \fI Pass in a second string, usually a phone number, that will be substituted for the \eU substitution metacharacter in a send string. This is useful when dialing an ISDN terminal adapter that requires two numbers. .TP .B script If the script is not specified in a file with the \fI\-f\fR option then the script is included as parameters to the \fIchat\fR program. .SH CHAT SCRIPT .LP The \fIchat\fR script defines the communications. .LP A script consists of one or more "expect\-send" pairs of strings, separated by spaces, with an optional "subexpect\-subsend" string pair, separated by a dash as in the following example: .IP ogin:\-BREAK\-ogin: ppp ssword: hello2u2 .LP This line indicates that the \fIchat\fR program should expect the string "ogin:". If it fails to receive a login prompt within the time interval allotted, it is to send a break sequence to the remote and then expect the string "ogin:". If the first "ogin:" is received then the break sequence is not generated. .LP Once it received the login prompt the \fIchat\fR program will send the string ppp and then expect the prompt "ssword:". When it receives the prompt for the password, it will send the password hello2u2. .LP A carriage return is normally sent following the reply string. It is not expected in the "expect" string unless it is specifically requested by using the \er character sequence. .LP The expect sequence should contain only what is needed to identify the string. Since it is normally stored on a disk file, it should not contain variable information. It is generally not acceptable to look for time strings, network identification strings, or other variable pieces of data as an expect string. .LP To help correct for characters which may be corrupted during the initial sequence, look for the string "ogin:" rather than "login:". It is possible that the leading "l" character may be received in error and you may never find the string even though it was sent by the system. For this reason, scripts look for "ogin:" rather than "login:" and "ssword:" rather than "password:". .LP A very simple script might look like this: .IP ogin: ppp ssword: hello2u2 .LP In other words, expect ....ogin:, send ppp, expect ...ssword:, send hello2u2. .LP In actual practice, simple scripts are rare. At the vary least, you should include sub-expect sequences should the original string not be received. For example, consider the following script: .IP ogin:\-\-ogin: ppp ssword: hello2u2 .LP This would be a better script than the simple one used earlier. This would look for the same login: prompt, however, if one was not received, a single return sequence is sent and then it will look for login: again. Should line noise obscure the first login prompt then sending the empty line will usually generate a login prompt again. .SH COMMENTS Comments can be embedded in the chat script. A comment is a line which starts with the \fB#\fR (hash) character in column 1. Such comment lines are just ignored by the chat program. If a '#' character is to be expected as the first character of the expect sequence, you should quote the expect string. If you want to wait for a prompt that starts with a # (hash) character, you would have to write something like this: .IP # Now wait for the prompt and send logout string .br \&'# ' logout .LP .SH SENDING DATA FROM A FILE If the string to send starts with an at sign (@), the rest of the string is taken to be the name of a file to read to get the string to send. If the last character of the data read is a newline, it is removed. The file can be a named pipe (or fifo) instead of a regular file. This provides a way for \fBchat\fR to communicate with another program, for example, a program to prompt the user and receive a password typed in. .LP .SH ABORT STRINGS Many modems will report the status of the call as a string. These strings may be \fBCONNECTED\fR or \fBNO CARRIER\fR or \fBBUSY\fR. It is often desirable to terminate the script should the modem fail to connect to the remote. The difficulty is that a script would not know exactly which modem string it may receive. On one attempt, it may receive \fBBUSY\fR while the next time it may receive \fBNO CARRIER\fR. .LP These "abort" strings may be specified in the script using the \fIABORT\fR sequence. It is written in the script as in the following example: .IP ABORT BUSY ABORT 'NO CARRIER' '' ATZ OK ATDT5551212 CONNECT .LP This sequence will expect nothing; and then send the string ATZ. The expected response to this is the string \fIOK\fR. When it receives \fIOK\fR, the string ATDT5551212 to dial the telephone. The expected string is \fICONNECT\fR. If the string \fICONNECT\fR is received the remainder of the script is executed. However, should the modem find a busy telephone, it will send the string \fIBUSY\fR. This will cause the string to match the abort character sequence. The script will then fail because it found a match to the abort string. If it received the string \fINO CARRIER\fR, it will abort for the same reason. Either string may be received. Either string will terminate the \fIchat\fR script. .SH CLR_ABORT STRINGS This sequence allows for clearing previously set \fBABORT\fR strings. \fBABORT\fR strings are kept in an array of a pre-determined size (at compilation time); \fBCLR_ABORT\fR will reclaim the space for cleared entries so that new strings can use that space. .SH SAY STRINGS The \fBSAY\fR directive allows the script to send strings to the user at the terminal via standard error. If \fBchat\fR is being run by pppd, and pppd is running as a daemon (detached from its controlling terminal), standard error will normally be redirected to the file /etc/ppp/connect\-errors. .LP \fBSAY\fR strings must be enclosed in single or double quotes. If carriage return and line feed are needed in the string to be output, you must explicitly add them to your string. .LP The SAY strings could be used to give progress messages in sections of the script where you want to have 'ECHO OFF' but still let the user know what is happening. An example is: .IP ABORT BUSY .br ECHO OFF .br SAY "Dialling your ISP...\en" .br \&'' ATDT5551212 .br TIMEOUT 120 .br SAY "Waiting up to 2 minutes for connection ... " .br CONNECT '' .br SAY "Connected, now logging in ...\en" .br ogin: account .br ssword: pass .br $ \ec .br SAY "Logged in OK ...\en" \fIetc ...\fR .LP This sequence will only present the SAY strings to the user and all the details of the script will remain hidden. For example, if the above script works, the user will see: .IP Dialling your ISP... .br Waiting up to 2 minutes for connection ... Connected, now logging in ... .br Logged in OK ... .LP .SH REPORT STRINGS A \fBreport\fR string is similar to the ABORT string. The difference is that the strings, and all characters to the next control character such as a carriage return, are written to the report file. .LP The report strings may be used to isolate the transmission rate of the modem's connect string and return the value to the chat user. The analysis of the report string logic occurs in conjunction with the other string processing such as looking for the expect string. The use of the same string for a report and abort sequence is probably not very useful, however, it is possible. .LP The report strings to no change the completion code of the program. .LP These "report" strings may be specified in the script using the \fIREPORT\fR sequence. It is written in the script as in the following example: .IP REPORT CONNECT ABORT BUSY '' ATDT5551212 CONNECT '' ogin: account .LP This sequence will expect nothing; and then send the string ATDT5551212 to dial the telephone. The expected string is \fICONNECT\fR. If the string \fICONNECT\fR is received the remainder of the script is executed. In addition the program will write to the expect\-file the string "CONNECT" plus any characters which follow it such as the connection rate. .SH CLR_REPORT STRINGS This sequence allows for clearing previously set \fBREPORT\fR strings. \fBREPORT\fR strings are kept in an array of a pre-determined size (at compilation time); \fBCLR_REPORT\fR will reclaim the space for cleared entries so that new strings can use that space. .SH ECHO The echo options controls whether the output from the modem is echoed to \fIstderr\fR. This option may be set with the \fI\-e\fR option, but it can also be controlled by the \fIECHO\fR keyword. The "expect\-send" pair \fIECHO\fR \fION\fR enables echoing, and \fIECHO\fR \fIOFF\fR disables it. With this keyword you can select which parts of the conversation should be visible. For instance, with the following script: .IP ABORT 'BUSY' .br ABORT 'NO CARRIER' .br \&'' ATZ .br OK\er\en ATD1234567 .br \er\en \ec .br ECHO ON .br CONNECT \ec .br ogin: account .LP all output resulting from modem configuration and dialing is not visible, but starting with the \fICONNECT\fR (or \fIBUSY\fR) message, everything will be echoed. .SH HANGUP The HANGUP options control whether a modem hangup should be considered as an error or not. This option is useful in scripts for dialling systems which will hang up and call your system back. The HANGUP options can be \fBON\fR or \fBOFF\fR. .br When HANGUP is set OFF and the modem hangs up (e.g., after the first stage of logging in to a callback system), \fBchat\fR will continue running the script (e.g., waiting for the incoming call and second stage login prompt). As soon as the incoming call is connected, you should use the \fBHANGUP ON\fR directive to reinstall normal hang up signal behavior. Here is an (simple) example script: .IP ABORT 'BUSY' .br \&'' ATZ .br OK\er\en ATD1234567 .br \er\en \ec .br CONNECT \ec .br \&'Callback login:' call_back_ID .br HANGUP OFF .br ABORT "Bad Login" .br \&'Callback Password:' Call_back_password .br TIMEOUT 120 .br CONNECT \ec .br HANGUP ON .br ABORT "NO CARRIER" .br ogin:\-\-BREAK\-\-ogin: real_account .br \fIetc ...\fR .LP .SH TIMEOUT The initial timeout value is 45 seconds. This may be changed using the \fB\-t\fR parameter. .LP To change the timeout value for the next expect string, the following example may be used: .IP ATZ OK ATDT5551212 CONNECT TIMEOUT 10 ogin:\-\-ogin: TIMEOUT 5 assword: hello2u2 .LP This will change the timeout to 10 seconds when it expects the login: prompt. The timeout is then changed to 5 seconds when it looks for the password prompt. .LP The timeout, once changed, remains in effect until it is changed again. .SH SENDING EOT The special reply string of \fIEOT\fR indicates that the chat program should send an EOT character to the remote. This is normally the End-of-file character sequence. A return character is not sent following the EOT. The EOT sequence may be embedded into the send string using the sequence \fI^D\fR. .SH GENERATING BREAK The special reply string of \fIBREAK\fR will cause a break condition to be sent. The break is a special signal on the transmitter. The normal processing on the receiver is to change the transmission rate. It may be used to cycle through the available transmission rates on the remote until you are able to receive a valid login prompt. The break sequence may be embedded into the send string using the \fI\eK\fR sequence. .SH ESCAPE SEQUENCES The expect and reply strings may contain escape sequences. All of the sequences are legal in the reply string. Many are legal in the expect. Those which are not valid in the expect sequence are so indicated. .TP .B '' Expects or sends a null string. If you send a null string then it will still send the return character. This sequence may either be a pair of apostrophe or quote characters. .TP .B \eb represents a backspace character. .TP .B \ec Suppresses the newline at the end of the reply string. This is the only method to send a string without a trailing return character. It must be at the end of the send string. For example, the sequence hello\ec will simply send the characters h, e, l, l, o. .I (not valid in expect.) .TP .B \ed Delay for one second. The program uses sleep(1) which will delay to a maximum of one second. .I (not valid in expect.) .TP .B \eK Insert a BREAK .I (not valid in expect.) .TP .B \en Send a newline or linefeed character. .TP .B \eN Send a null character. The same sequence may be represented by \e0. .I (not valid in expect.) .TP .B \ep Pause for a fraction of a second. The delay is 1/10th of a second. .I (not valid in expect.) .TP .B \eq Suppress writing the string to the SYSLOG file. The string ?????? is written to the log in its place. .I (not valid in expect.) .TP .B \er Send or expect a carriage return. .TP .B \es Represents a space character in the string. This may be used when it is not desirable to quote the strings which contains spaces. The sequence 'HI TIM' and HI\esTIM are the same. .TP .B \et Send or expect a tab character. .TP .B \eT Send the phone number string as specified with the \fI\-T\fR option .I (not valid in expect.) .TP .B \eU Send the phone number 2 string as specified with the \fI\-U\fR option .I (not valid in expect.) .TP .B \e\e Send or expect a backslash character. .TP .B \eddd Collapse the octal digits (ddd) into a single ASCII character and send that character. .I (some characters are not valid in expect.) .TP .B \^^C Substitute the sequence with the control character represented by C. For example, the character DC1 (17) is shown as \^^Q. .I (some characters are not valid in expect.) .SH ENVIRONMENT VARIABLES Environment variables are available within chat scripts, if the \fI\-E\fR option was specified in the command line. The metacharacter \fI$\fR is used to introduce the name of the environment variable to substitute. If the substitution fails, because the requested environment variable is not set, \fInothing\fR is replaced for the variable. .SH TERMINATION CODES The \fIchat\fR program will terminate with the following completion codes. .TP .B 0 The normal termination of the program. This indicates that the script was executed without error to the normal conclusion. .TP .B 1 One or more of the parameters are invalid or an expect string was too large for the internal buffers. This indicates that the program as not properly executed. .TP .B 2 An error occurred during the execution of the program. This may be due to a read or write operation failing for some reason or chat receiving a signal such as SIGINT. .TP .B 3 A timeout event occurred when there was an \fIexpect\fR string without having a "\-subsend" string. This may mean that you did not program the script correctly for the condition or that some unexpected event has occurred and the expected string could not be found. .TP .B 4 The first string marked as an \fIABORT\fR condition occurred. .TP .B 5 The second string marked as an \fIABORT\fR condition occurred. .TP .B 6 The third string marked as an \fIABORT\fR condition occurred. .TP .B 7 The fourth string marked as an \fIABORT\fR condition occurred. .TP .B ... The other termination codes are also strings marked as an \fIABORT\fR condition. .LP Using the termination code, it is possible to determine which event terminated the script. It is possible to decide if the string "BUSY" was received from the modem as opposed to "NO DIAL TONE". While the first event may be retried, the second will probably have little chance of succeeding during a retry. .SH SEE ALSO Additional information about \fIchat\fR scripts may be found with UUCP documentation. The \fIchat\fR script was taken from the ideas proposed by the scripts used by the \fIuucico\fR program. .LP uucico(1), uucp(1) .SH COPYRIGHT The \fIchat\fR program is in public domain. This is not the GNU public license. If it breaks then you get to keep both pieces. ppp-2.5.0/chat/Makefile.in0000644000175000017500000006176314407475314012250 00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ sbin_PROGRAMS = chat$(EXEEXT) subdir = chat ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_atm.m4 \ $(top_srcdir)/m4/ax_check_openssl.m4 \ $(top_srcdir)/m4/ax_check_openssl_func.m4 \ $(top_srcdir)/m4/ax_check_pam.m4 \ $(top_srcdir)/m4/ax_check_pcap.m4 \ $(top_srcdir)/m4/ax_check_srp.m4 $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/pkg.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/pppd/config.h \ $(top_builddir)/pppd/pppdconf.h \ $(top_builddir)/pppd/plugins/pppoe/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__installdirs = "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(man8dir)" PROGRAMS = $(sbin_PROGRAMS) am_chat_OBJECTS = chat-chat.$(OBJEXT) chat_OBJECTS = $(am_chat_OBJECTS) chat_LDADD = $(LDADD) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/pppd -I$(top_builddir)/pppd/plugins/pppoe depcomp = $(SHELL) $(top_srcdir)/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/chat-chat.Po am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(chat_SOURCES) DIST_SOURCES = $(chat_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } man8dir = $(mandir)/man8 NROFF = nroff MANS = $(dist_man8_MANS) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(dist_man8_MANS) $(srcdir)/Makefile.in \ $(top_srcdir)/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ ATM_CFLAGS = @ATM_CFLAGS@ ATM_LDFLAGS = @ATM_LDFLAGS@ ATM_LIBS = @ATM_LIBS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CRYPT_LIBS = @CRYPT_LIBS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GREP = @GREP@ GTK_CFLAGS = @GTK_CFLAGS@ GTK_LIBS = @GTK_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_INCLUDES = @OPENSSL_INCLUDES@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAM_CFLAGS = @PAM_CFLAGS@ PAM_LDFLAGS = @PAM_LDFLAGS@ PAM_LIBS = @PAM_LIBS@ PATH_SEPARATOR = @PATH_SEPARATOR@ PCAP_CFLAGS = @PCAP_CFLAGS@ PCAP_LDFLAGS = @PCAP_LDFLAGS@ PCAP_LIBS = @PCAP_LIBS@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PPPD_LOGFILE_DIR = @PPPD_LOGFILE_DIR@ PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@ PPPD_RUNTIME_DIR = @PPPD_RUNTIME_DIR@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SRP_CFLAGS = @SRP_CFLAGS@ SRP_LDFLAGS = @SRP_LDFLAGS@ SRP_LIBS = @SRP_LIBS@ STRIP = @STRIP@ SYSTEMD_CFLAGS = @SYSTEMD_CFLAGS@ SYSTEMD_LIBS = @SYSTEMD_LIBS@ SYSTEM_CA_PATH = @SYSTEM_CA_PATH@ UTIL_LIBS = @UTIL_LIBS@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ dist_man8_MANS = chat.8 chat_SOURCES = chat.c chat_CPPFLAGS = -DTERMIOS -DSIGTYPE=void -UNO_SLEEP -DFNDELAY=O_NDELAY all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu chat/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu chat/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-sbinPROGRAMS: $(sbin_PROGRAMS) @$(NORMAL_INSTALL) @list='$(sbin_PROGRAMS)'; test -n "$(sbindir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(sbindir)'"; \ $(MKDIR_P) "$(DESTDIR)$(sbindir)" || exit 1; \ fi; \ for p in $$list; do echo "$$p $$p"; done | \ sed 's/$(EXEEXT)$$//' | \ while read p p1; do if test -f $$p \ || test -f $$p1 \ ; then echo "$$p"; echo "$$p"; else :; fi; \ done | \ sed -e 'p;s,.*/,,;n;h' \ -e 's|.*|.|' \ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ if ($$2 == $$4) files[d] = files[d] " " $$1; \ else { print "f", $$3 "/" $$4, $$1; } } \ END { for (d in files) print "f", d, files[d] }' | \ while read type dir files; do \ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ test -z "$$files" || { \ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(sbindir)$$dir'"; \ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(sbindir)$$dir" || exit $$?; \ } \ ; done uninstall-sbinPROGRAMS: @$(NORMAL_UNINSTALL) @list='$(sbin_PROGRAMS)'; test -n "$(sbindir)" || list=; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ -e 's/$$/$(EXEEXT)/' \ `; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(sbindir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(sbindir)" && rm -f $$files clean-sbinPROGRAMS: @list='$(sbin_PROGRAMS)'; test -n "$$list" || exit 0; \ echo " rm -f" $$list; \ rm -f $$list || exit $$?; \ test -n "$(EXEEXT)" || exit 0; \ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list chat$(EXEEXT): $(chat_OBJECTS) $(chat_DEPENDENCIES) $(EXTRA_chat_DEPENDENCIES) @rm -f chat$(EXEEXT) $(AM_V_CCLD)$(LINK) $(chat_OBJECTS) $(chat_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/chat-chat.Po@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< chat-chat.o: chat.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(chat_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT chat-chat.o -MD -MP -MF $(DEPDIR)/chat-chat.Tpo -c -o chat-chat.o `test -f 'chat.c' || echo '$(srcdir)/'`chat.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/chat-chat.Tpo $(DEPDIR)/chat-chat.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='chat.c' object='chat-chat.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(chat_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o chat-chat.o `test -f 'chat.c' || echo '$(srcdir)/'`chat.c chat-chat.obj: chat.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(chat_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT chat-chat.obj -MD -MP -MF $(DEPDIR)/chat-chat.Tpo -c -o chat-chat.obj `if test -f 'chat.c'; then $(CYGPATH_W) 'chat.c'; else $(CYGPATH_W) '$(srcdir)/chat.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/chat-chat.Tpo $(DEPDIR)/chat-chat.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='chat.c' object='chat-chat.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(chat_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o chat-chat.obj `if test -f 'chat.c'; then $(CYGPATH_W) 'chat.c'; else $(CYGPATH_W) '$(srcdir)/chat.c'; fi` mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs install-man8: $(dist_man8_MANS) @$(NORMAL_INSTALL) @list1='$(dist_man8_MANS)'; \ list2=''; \ test -n "$(man8dir)" \ && test -n "`echo $$list1$$list2`" \ || exit 0; \ echo " $(MKDIR_P) '$(DESTDIR)$(man8dir)'"; \ $(MKDIR_P) "$(DESTDIR)$(man8dir)" || exit 1; \ { for i in $$list1; do echo "$$i"; done; \ if test -n "$$list2"; then \ for i in $$list2; do echo "$$i"; done \ | sed -n '/\.8[a-z]*$$/p'; \ fi; \ } | while read p; do \ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; echo "$$p"; \ done | \ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ sed 'N;N;s,\n, ,g' | { \ list=; while read file base inst; do \ if test "$$base" = "$$inst"; then list="$$list $$file"; else \ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man8dir)/$$inst'"; \ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man8dir)/$$inst" || exit $$?; \ fi; \ done; \ for i in $$list; do echo "$$i"; done | $(am__base_list) | \ while read files; do \ test -z "$$files" || { \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man8dir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(man8dir)" || exit $$?; }; \ done; } uninstall-man8: @$(NORMAL_UNINSTALL) @list='$(dist_man8_MANS)'; test -n "$(man8dir)" || exit 0; \ files=`{ for i in $$list; do echo "$$i"; done; \ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ dir='$(DESTDIR)$(man8dir)'; $(am__uninstall_files_from_dir) ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(PROGRAMS) $(MANS) installdirs: for dir in "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(man8dir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-sbinPROGRAMS \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/chat-chat.Po -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-man install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-sbinPROGRAMS install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-man8 install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/chat-chat.Po -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-man uninstall-sbinPROGRAMS uninstall-man: uninstall-man8 .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-sbinPROGRAMS cscopelist-am \ ctags ctags-am distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-man8 install-pdf \ install-pdf-am install-ps install-ps-am install-sbinPROGRAMS \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ pdf pdf-am ps ps-am tags tags-am uninstall uninstall-am \ uninstall-man uninstall-man8 uninstall-sbinPROGRAMS .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: ppp-2.5.0/chat/chat.c0000644000175000017500000010202314407475306011250 00000000000000/* * Chat -- a program for automatic session establishment (i.e. dial * the phone and log in). * * Standard termination codes: * 0 - successful completion of the script * 1 - invalid argument, expect string too large, etc. * 2 - error on an I/O operation or fatal error condition. * 3 - timeout waiting for a simple string. * 4 - the first string declared as "ABORT" * 5 - the second string declared as "ABORT" * 6 - ... and so on for successive ABORT strings. * * This software is in the public domain. * * ----------------- * 22-May-99 added environment substitutuion, enabled with -E switch. * Andreas Arens . * * 12-May-99 added a feature to read data to be sent from a file, * if the send string starts with @. Idea from gpk . * * added -T and -U option and \T and \U substitution to pass a phone * number into chat script. Two are needed for some ISDN TA applications. * Keith Dart * * * Added SAY keyword to send output to stderr. * This allows to turn ECHO OFF and to output specific, user selected, * text to give progress messages. This best works when stderr * exists (i.e.: pppd in nodetach mode). * * Added HANGUP directives to allow for us to be called * back. When HANGUP is set to NO, chat will not hangup at HUP signal. * We rely on timeouts in that case. * * Added CLR_ABORT to clear previously set ABORT string. This has been * dictated by the HANGUP above as "NO CARRIER" (for example) must be * an ABORT condition until we know the other host is going to close * the connection for call back. As soon as we have completed the * first stage of the call back sequence, "NO CARRIER" is a valid, non * fatal string. As soon as we got called back (probably get "CONNECT"), * we should re-arm the ABORT "NO CARRIER". Hence the CLR_ABORT command. * Note that CLR_ABORT packs the abort_strings[] array so that we do not * have unused entries not being reclaimed. * * In the same vein as above, added CLR_REPORT keyword. * * Allow for comments. Line starting with '#' are comments and are * ignored. If a '#' is to be expected as the first character, the * expect string must be quoted. * * * Francis Demierre * Thu May 15 17:15:40 MET DST 1997 * * * Added -r "report file" switch & REPORT keyword. * Robert Geer * * Added -s "use stderr" and -S "don't use syslog" switches. * June 18, 1997 * Karl O. Pinc * * * Added -e "echo" switch & ECHO keyword * Dick Streefland * * * Considerable updates and modifications by * Al Longyear * Paul Mackerras * * * The original author is: * * Karl Fox * Morning Star Technologies, Inc. * 1760 Zollinger Road * Columbus, OH 43221 * (614)451-1883 * */ #include #include #include #include #include #include #include #include #include #include #include #include #include #ifndef TERMIO #undef TERMIOS #define TERMIOS #endif #ifdef TERMIO #include #endif #ifdef TERMIOS #include #endif #define STR_LEN 1024 #ifndef SIGTYPE #define SIGTYPE void #endif #ifndef O_NONBLOCK #define O_NONBLOCK O_NDELAY #endif #ifdef SUNOS extern int sys_nerr; extern char *sys_errlist[]; #define memmove(to, from, n) bcopy(from, to, n) #define strerror(n) ((unsigned)(n) < sys_nerr? sys_errlist[(n)] :\ "unknown error") #endif /*************** Micro getopt() *********************************************/ #define OPTION(c,v) (_O&2&&**v?*(*v)++:!c||_O&4?0:(!(_O&1)&& \ (--c,++v),_O=4,c&&**v=='-'&&v[0][1]?*++*v=='-'\ &&!v[0][1]?(--c,++v,0):(_O=2,*(*v)++):0)) #define OPTARG(c,v) (_O&2?**v||(++v,--c)?(_O=1,--c,*v++): \ (_O=4,(char*)0):(char*)0) #define OPTONLYARG(c,v) (_O&2&&**v?(_O=1,--c,*v++):(char*)0) #define ARG(c,v) (c?(--c,*v++):(char*)0) static int _O = 0; /* Internal state */ /*************** Micro getopt() *********************************************/ char *program_name; #define MAX_ABORTS 50 #define MAX_REPORTS 50 #define DEFAULT_CHAT_TIMEOUT 45 int echo = 0; int verbose = 0; int to_log = 1; int to_stderr = 0; int Verbose = 0; int quiet = 0; int report = 0; int use_env = 0; int exit_code = 0; FILE* report_fp = (FILE *) 0; char *report_file = (char *) 0; char *chat_file = (char *) 0; char *phone_num = (char *) 0; char *phone_num2 = (char *) 0; int timeout = DEFAULT_CHAT_TIMEOUT; int have_tty_parameters = 0; #ifdef TERMIO #define term_parms struct termio #define get_term_param(param) ioctl(0, TCGETA, param) #define set_term_param(param) ioctl(0, TCSETA, param) struct termio saved_tty_parameters; #endif #ifdef TERMIOS #define term_parms struct termios #define get_term_param(param) tcgetattr(0, param) #define set_term_param(param) tcsetattr(0, TCSANOW, param) struct termios saved_tty_parameters; #endif char *abort_string[MAX_ABORTS], *fail_reason = (char *)0, fail_buffer[50]; int n_aborts = 0, abort_next = 0, timeout_next = 0, echo_next = 0; int clear_abort_next = 0; char *report_string[MAX_REPORTS] ; char report_buffer[4096] ; int n_reports = 0, report_next = 0, report_gathering = 0 ; int clear_report_next = 0; int say_next = 0, hup_next = 0; void *dup_mem (void *b, size_t c); void *copy_of (char *s); char *grow (char *s, char **p, size_t len); void usage (void); void msgf (const char *fmt, ...); void fatal (int code, const char *fmt, ...); SIGTYPE sigalrm (int signo); SIGTYPE sigint (int signo); SIGTYPE sigterm (int signo); SIGTYPE sighup (int signo); void checksigs(void); void init (void); void set_tty_parameters (void); int echo_stderr (int); void break_sequence (void); void terminate (int status); void do_file (char *chat_file); int get_string (register char *string); int put_string (register char *s); int write_char (int c); int put_char (int c); int get_char (void); int chat_send (register char *s); char *character (int c); void chat_expect (register char *s); char *clean (register char *s, int sending); void break_sequence (void); void pack_array (char **array, int end); char *expect_strtok (char *, char *); int vfmtmsg (char *, int, const char *, va_list); /* vsprintf++ */ int main (int, char *[]); void *dup_mem(void *b, size_t c) { void *ans = malloc (c); if (!ans) fatal(2, "memory error!"); memcpy (ans, b, c); return ans; } void *copy_of (char *s) { return dup_mem (s, strlen (s) + 1); } /* grow a char buffer and keep a pointer offset */ char *grow(char *s, char **p, size_t len) { size_t l = *p - s; /* save p as distance into s */ s = realloc(s, len); if (!s) fatal(2, "memory error!"); *p = s + l; /* restore p */ return s; } /* * chat [ -v ] [ -E ] [ -T number ] [ -U number ] [ -t timeout ] [ -f chat-file ] \ * [ -r report-file ] \ * [...[[expect[-say[-expect...]] say expect[-say[-expect]] ...]]] * * Perform a UUCP-dialer-like chat script on stdin and stdout. */ int main(int argc, char **argv) { int option; char *arg; program_name = *argv; tzset(); while ((option = OPTION(argc, argv)) != 0) { switch (option) { case 'e': ++echo; break; case 'E': ++use_env; break; case 'v': ++verbose; break; case 'V': ++Verbose; break; case 's': ++to_stderr; break; case 'S': to_log = 0; break; case 'f': if ((arg = OPTARG(argc, argv)) != NULL) chat_file = copy_of(arg); else usage(); break; case 't': if ((arg = OPTARG(argc, argv)) != NULL) timeout = atoi(arg); else usage(); break; case 'r': arg = OPTARG (argc, argv); if (arg) { if (report_fp != NULL) fclose (report_fp); report_file = copy_of (arg); report_fp = fopen (report_file, "a"); if (report_fp != NULL) { if (verbose) fprintf (report_fp, "Opening \"%s\"...\n", report_file); report = 1; } } break; case 'T': if ((arg = OPTARG(argc, argv)) != NULL) phone_num = copy_of(arg); else usage(); break; case 'U': if ((arg = OPTARG(argc, argv)) != NULL) phone_num2 = copy_of(arg); else usage(); break; default: usage(); break; } } /* * Default the report file to the stderr location */ if (report_fp == NULL) report_fp = stderr; if (to_log) { openlog("chat", LOG_PID | LOG_NDELAY, LOG_LOCAL2); if (verbose) setlogmask(LOG_UPTO(LOG_INFO)); else setlogmask(LOG_UPTO(LOG_WARNING)); } init(); if (chat_file != NULL) { arg = ARG(argc, argv); if (arg != NULL) usage(); else do_file (chat_file); } else { while ((arg = ARG(argc, argv)) != NULL) { chat_expect(arg); if ((arg = ARG(argc, argv)) != NULL) chat_send(arg); checksigs(); } } terminate(0); return 0; } /* * Process a chat script when read from a file. */ void do_file (char *chat_file) { int linect, sendflg; char *sp, *arg, quote; char buf [STR_LEN]; FILE *cfp; cfp = fopen (chat_file, "r"); if (cfp == NULL) fatal(1, "%s -- open failed: %m", chat_file); linect = 0; sendflg = 0; while (fgets(buf, STR_LEN, cfp) != NULL) { sp = strchr (buf, '\n'); if (sp) *sp = '\0'; linect++; sp = buf; /* lines starting with '#' are comments. If a real '#' is to be expected, it should be quoted .... */ if ( *sp == '#' ) continue; while (*sp != '\0') { if (*sp == ' ' || *sp == '\t') { ++sp; continue; } if (*sp == '"' || *sp == '\'') { quote = *sp++; arg = sp; while (*sp != quote) { if (*sp == '\0') fatal(1, "unterminated quote (line %d)", linect); if (*sp++ == '\\') { if (*sp != '\0') ++sp; } } } else { arg = sp; while (*sp != '\0' && *sp != ' ' && *sp != '\t') ++sp; } if (*sp != '\0') *sp++ = '\0'; if (sendflg) chat_send (arg); else chat_expect (arg); sendflg = !sendflg; checksigs(); } } checksigs(); fclose (cfp); } /* * We got an error parsing the command line. */ void usage(void) { fprintf(stderr, "\ Usage: %s [-e] [-E] [-v] [-V] [-t timeout] [-r report-file]\n\ [-T phone-number] [-U phone-number2] {-f chat-file | chat-script}\n", program_name); exit(1); } char line[1024]; /* * Send a message to syslog and/or stderr. */ void msgf(const char *fmt, ...) { va_list args; va_start(args, fmt); vfmtmsg(line, sizeof(line), fmt, args); if (to_log) syslog(LOG_INFO, "%s", line); if (to_stderr) fprintf(stderr, "%s\n", line); va_end(args); } /* * Print an error message and terminate. */ void fatal(int code, const char *fmt, ...) { va_list args; va_start(args, fmt); vfmtmsg(line, sizeof(line), fmt, args); if (to_log) syslog(LOG_ERR, "%s", line); if (to_stderr) fprintf(stderr, "%s\n", line); va_end(args); terminate(code); } int alarmed = 0; int alarmsig = 0; SIGTYPE sigalrm(int signo) { int flags; alarm(1); alarmed = 1; alarmsig = 1; } const char *fatalsig = NULL; SIGTYPE sigint(int signo) { fatalsig = "SIGINT"; } SIGTYPE sigterm(int signo) { fatalsig = "SIGTERM"; } SIGTYPE sighup(int signo) { fatalsig = "SIGHUP"; } void checksigs(void) { int err; const char *signame; if (fatalsig) { signame = fatalsig; fatalsig = NULL; alarmsig = 0; fatal(2, signame); } if (alarmsig && verbose) { err = errno; msgf("alarm"); errno = err; alarmsig = 0; } } void init(void) { struct sigaction sa; memset(&sa, 0, sizeof(sa)); sa.sa_handler = sigint; sigaction(SIGINT, &sa, NULL); sa.sa_handler = sigterm; sigaction(SIGTERM, &sa, NULL); sa.sa_handler = sighup; sigaction(SIGHUP, &sa, NULL); set_tty_parameters(); sa.sa_handler = sigalrm; sigaction(SIGALRM, &sa, NULL); alarm(0); alarmed = 0; } void set_tty_parameters(void) { #if defined(get_term_param) term_parms t; if (get_term_param (&t) < 0) fatal(2, "Can't get terminal parameters: %m"); saved_tty_parameters = t; have_tty_parameters = 1; t.c_iflag |= IGNBRK | ISTRIP | IGNPAR; t.c_oflag = 0; t.c_lflag = 0; t.c_cc[VERASE] = t.c_cc[VKILL] = 0; t.c_cc[VMIN] = 1; t.c_cc[VTIME] = 0; if (set_term_param (&t) < 0) fatal(2, "Can't set terminal parameters: %m"); #endif } void break_sequence(void) { #ifdef TERMIOS tcsendbreak (0, 0); #endif } void terminate(int status) { static int terminating = 0; if (terminating) exit(status); terminating = 1; echo_stderr(-1); /* * Allow the last of the report string to be gathered before we terminate. */ if (report_gathering) { int c, rep_len; rep_len = strlen(report_buffer); while (rep_len + 1 < sizeof(report_buffer)) { alarm(1); c = get_char(); alarm(0); if (c < 0 || iscntrl(c)) break; report_buffer[rep_len] = c; ++rep_len; } report_buffer[rep_len] = 0; fprintf (report_fp, "chat: %s\n", report_buffer); } if (report_file != (char *) 0 && report_fp != (FILE *) NULL) { if (verbose) fprintf (report_fp, "Closing \"%s\".\n", report_file); fclose (report_fp); report_fp = (FILE *) NULL; } #if defined(get_term_param) if (have_tty_parameters) { if (set_term_param (&saved_tty_parameters) < 0) fatal(2, "Can't restore terminal parameters: %m"); } #endif exit(status); } /* * 'Clean up' this string. */ char *clean(register char *s, int sending) /* set to 1 when sending (putting) this string. */ { char cur_chr; char *s1, *p, *phchar; int add_return = sending; size_t len = strlen(s) + 3; /* see len comments below */ #define isoctal(chr) (((chr) >= '0') && ((chr) <= '7')) #define isalnumx(chr) ((((chr) >= '0') && ((chr) <= '9')) \ || (((chr) >= 'a') && ((chr) <= 'z')) \ || (((chr) >= 'A') && ((chr) <= 'Z')) \ || (chr) == '_') p = s1 = malloc(len); if (!p) fatal(2, "memory error!"); while (*s) { cur_chr = *s++; if (cur_chr == '^') { cur_chr = *s++; if (cur_chr == '\0') { *p++ = '^'; break; } cur_chr &= 0x1F; if (cur_chr != 0) { *p++ = cur_chr; } continue; } if (use_env && cur_chr == '$') { /* ARI */ char c; phchar = s; while (isalnumx(*s)) s++; c = *s; /* save */ *s = '\0'; phchar = getenv(phchar); *s = c; /* restore */ if (phchar) { len += strlen(phchar); s1 = grow(s1, &p, len); while (*phchar) *p++ = *phchar++; } continue; } if (cur_chr != '\\') { *p++ = cur_chr; continue; } cur_chr = *s++; if (cur_chr == '\0') { if (sending) { *p++ = '\\'; *p++ = '\\'; /* +1 for len */ } break; } switch (cur_chr) { case 'b': *p++ = '\b'; break; case 'c': if (sending && *s == '\0') add_return = 0; else *p++ = cur_chr; break; case '\\': case 'K': case 'p': case 'd': if (sending) *p++ = '\\'; *p++ = cur_chr; break; case 'T': if (sending && phone_num) { len += strlen(phone_num); s1 = grow(s1, &p, len); for (phchar = phone_num; *phchar != '\0'; phchar++) *p++ = *phchar; } else { *p++ = '\\'; *p++ = 'T'; } break; case 'U': if (sending && phone_num2) { len += strlen(phone_num2); s1 = grow(s1, &p, len); for (phchar = phone_num2; *phchar != '\0'; phchar++) *p++ = *phchar; } else { *p++ = '\\'; *p++ = 'U'; } break; case 'q': quiet = 1; break; case 'r': *p++ = '\r'; break; case 'n': *p++ = '\n'; break; case 's': *p++ = ' '; break; case 't': *p++ = '\t'; break; case 'N': if (sending) { *p++ = '\\'; *p++ = '\0'; } else *p++ = 'N'; break; case '$': /* ARI */ if (use_env) { *p++ = cur_chr; break; } /* FALL THROUGH */ default: if (isoctal (cur_chr)) { cur_chr &= 0x07; if (isoctal (*s)) { cur_chr <<= 3; cur_chr |= *s++ - '0'; if (isoctal (*s)) { cur_chr <<= 3; cur_chr |= *s++ - '0'; } } if (cur_chr != 0 || sending) { if (sending && (cur_chr == '\\' || cur_chr == 0)) *p++ = '\\'; *p++ = cur_chr; } break; } if (sending) *p++ = '\\'; *p++ = cur_chr; break; } } if (add_return) *p++ = '\r'; /* +2 for len */ *p = '\0'; /* +3 for len */ return s1; } /* * A modified version of 'strtok'. This version skips \ sequences. */ char *expect_strtok (char *s, char *term) { static char *str = ""; int escape_flag = 0; char *result; /* * If a string was specified then do initial processing. */ if (s) str = s; /* * If this is the escape flag then reset it and ignore the character. */ if (*str) result = str; else result = (char *) 0; while (*str) { if (escape_flag) { escape_flag = 0; ++str; continue; } if (*str == '\\') { ++str; escape_flag = 1; continue; } /* * If this is not in the termination string, continue. */ if (strchr (term, *str) == (char *) 0) { ++str; continue; } /* * This is the terminator. Mark the end of the string and stop. */ *str++ = '\0'; break; } return (result); } /* * Process the expect string */ void chat_expect (char *s) { char *expect; char *reply; if (strcmp(s, "HANGUP") == 0) { ++hup_next; return; } if (strcmp(s, "ABORT") == 0) { ++abort_next; return; } if (strcmp(s, "CLR_ABORT") == 0) { ++clear_abort_next; return; } if (strcmp(s, "REPORT") == 0) { ++report_next; return; } if (strcmp(s, "CLR_REPORT") == 0) { ++clear_report_next; return; } if (strcmp(s, "TIMEOUT") == 0) { ++timeout_next; return; } if (strcmp(s, "ECHO") == 0) { ++echo_next; return; } if (strcmp(s, "SAY") == 0) { ++say_next; return; } /* * Fetch the expect and reply string. */ for (;;) { expect = expect_strtok (s, "-"); s = (char *) 0; if (expect == (char *) 0) return; reply = expect_strtok (s, "-"); /* * Handle the expect string. If successful then exit. */ if (get_string (expect)) return; /* * If there is a sub-reply string then send it. Otherwise any condition * is terminal. */ if (reply == (char *) 0 || exit_code != 3) break; chat_send (reply); checksigs(); } /* * The expectation did not occur. This is terminal. */ if (fail_reason) msgf("Failed (%s)", fail_reason); else msgf("Failed"); terminate(exit_code); } /* * Translate the input character to the appropriate string for printing * the data. */ char *character(int c) { static char string[10]; char *meta; meta = (c & 0x80) ? "M-" : ""; c &= 0x7F; if (c < 32) sprintf(string, "%s^%c", meta, (int)c + '@'); else if (c == 127) sprintf(string, "%s^?", meta); else sprintf(string, "%s%c", meta, c); return (string); } /* * process the reply string */ int chat_send (register char *s) { char file_data[STR_LEN]; int len, ret = 0; struct sigaction sa; if (say_next) { say_next = 0; s = clean(s, 1); len = strlen(s); ret = write(2, s, len) != len; free(s); return ret; } if (hup_next) { hup_next = 0; memset(&sa, 0, sizeof(sa)); if (strcmp(s, "OFF") == 0) sa.sa_handler = SIG_IGN; else sa.sa_handler = sighup; sigaction(SIGHUP, &sa, NULL); return 0; } if (echo_next) { echo_next = 0; echo = (strcmp(s, "ON") == 0); return 0; } if (abort_next) { char *s1; abort_next = 0; if (n_aborts >= MAX_ABORTS) fatal(2, "Too many ABORT strings"); s1 = clean(s, 0); if (strlen(s1) + 1 > sizeof(fail_buffer)) fatal(1, "Illegal or too-long ABORT string ('%v')", s); abort_string[n_aborts++] = s1; if (verbose) msgf("abort on (%v)", s1); return 0; } if (clear_abort_next) { char *s1; int i; int old_max; int pack = 0; clear_abort_next = 0; s1 = clean(s, 0); if (strlen(s1) + 1 > sizeof(fail_buffer)) fatal(1, "Illegal or too-long CLR_ABORT string ('%v')", s); old_max = n_aborts; for (i=0; i < n_aborts; i++) { if ( strcmp(s1,abort_string[i]) == 0 ) { free(abort_string[i]); abort_string[i] = NULL; pack++; n_aborts--; if (verbose) msgf("clear abort on (%v)", s1); } } free(s1); if (pack) pack_array(abort_string,old_max); return 0; } if (report_next) { char *s1; report_next = 0; if (n_reports >= MAX_REPORTS) fatal(2, "Too many REPORT strings"); s1 = clean(s, 0); if (strlen(s1) + 1 > sizeof(fail_buffer)) fatal(1, "Illegal or too-long REPORT string ('%v')", s); report_string[n_reports++] = s1; if (verbose) msgf("report (%v)", s1); return 0; } if (clear_report_next) { char *s1; int i; int old_max; int pack = 0; clear_report_next = 0; s1 = clean(s, 0); if (strlen(s1) + 1 > sizeof(fail_buffer)) fatal(1, "Illegal or too-long REPORT string ('%v')", s); old_max = n_reports; for (i=0; i < n_reports; i++) { if ( strcmp(s1,report_string[i]) == 0 ) { free(report_string[i]); report_string[i] = NULL; pack++; n_reports--; if (verbose) msgf("clear report (%v)", s1); } } free(s1); if (pack) pack_array(report_string,old_max); return 0; } if (timeout_next) { timeout_next = 0; s = clean(s, 0); timeout = atoi(s); if (timeout <= 0) timeout = DEFAULT_CHAT_TIMEOUT; if (verbose) msgf("timeout set to %d seconds", timeout); free(s); return 0; } /* * The syntax @filename means read the string to send from the * file `filename'. */ if (s[0] == '@') { /* skip the @ and any following white-space */ char *fn = s; while (*++fn == ' ' || *fn == '\t') ; if (*fn != 0) { FILE *f; int n = 0; /* open the file and read until STR_LEN-1 bytes or end-of-file */ f = fopen(fn, "r"); if (f == NULL) fatal(1, "%s -- open failed: %m", fn); while (n < STR_LEN - 1) { int nr = fread(&file_data[n], 1, STR_LEN - 1 - n, f); if (nr < 0) fatal(1, "%s -- read error", fn); if (nr == 0) break; n += nr; } fclose(f); /* use the string we got as the string to send, but trim off the final newline if any. */ if (n > 0 && file_data[n-1] == '\n') --n; file_data[n] = 0; s = file_data; } } if (strcmp(s, "EOT") == 0) s = "^D\\c"; else if (strcmp(s, "BREAK") == 0) s = "\\K\\c"; if (!put_string(s)) fatal(1, "Failed"); return 0; } int get_char(void) { int status; char c; status = read(0, &c, 1); checksigs(); switch (status) { case 1: return ((int)c & 0x7F); default: msgf("warning: read() on stdin returned %d", status); case -1: return (-1); } } int put_char(int c) { int status; char ch = c; usleep(10000); /* inter-character typing delay (?) */ checksigs(); status = write(1, &ch, 1); checksigs(); switch (status) { case 1: return (0); default: msgf("warning: write() on stdout returned %d", status); case -1: return (-1); } } int write_char(int c) { if (alarmed || put_char(c) < 0) { alarm(0); alarmed = 0; if (verbose) { if (errno == EINTR || errno == EWOULDBLOCK) msgf(" -- write timed out"); else msgf(" -- write failed: %m"); } return (0); } return (1); } int put_string(register char *s) { char *s1; quiet = 0; s = clean(s, 1); s1 = s; if (verbose) { if (quiet) msgf("send (?????\?)"); else msgf("send (%v)", s); } alarm(timeout); alarmed = 0; while (*s) { register char c = *s++; if (c != '\\') { if (!write_char (c)) { free(s1); return 0; } continue; } c = *s++; switch (c) { case 'd': sleep(1); break; case 'K': break_sequence(); break; case 'p': usleep(10000); /* 1/100th of a second (arg is microseconds) */ break; default: if (!write_char (c)) { free(s1); return 0; } break; } checksigs(); } alarm(0); alarmed = 0; free(s1); return (1); } /* * Echo a character to stderr. * When called with -1, a '\n' character is generated when * the cursor is not at the beginning of a line. */ int echo_stderr(int n) { static int need_lf; char *s; int len, ret = 0; switch (n) { case '\r': /* ignore '\r' */ break; case -1: if (need_lf == 0) break; /* fall through */ case '\n': ret = write(2, "\n", 1) != 1; need_lf = 0; break; default: s = character(n); len = strlen(s); ret = write(2, s, len) != len; need_lf = 1; break; } checksigs(); return ret; } /* * 'Wait for' this string to appear on this file descriptor. */ int get_string(register char *string) { char temp[STR_LEN]; int c, printed = 0, len, minlen; register char *s = temp, *end = s + STR_LEN; char *s1, *logged = temp; fail_reason = (char *)0; string = s1 = clean(string, 0); len = strlen(string); minlen = (len > sizeof(fail_buffer)? len: sizeof(fail_buffer)) - 1; if (verbose) msgf("expect (%v)", string); if (len > STR_LEN) { msgf("expect string is too long"); exit_code = 1; free(s1); return 0; } if (len == 0) { if (verbose) msgf("got it"); free(s1); return (1); } alarm(timeout); alarmed = 0; while ( ! alarmed && (c = get_char()) >= 0) { int n, abort_len, report_len; if (echo) { if (echo_stderr(c) != 0) { fatal(2, "Could not write to stderr, %m"); } } if (verbose && c == '\n') { if (s == logged) msgf(""); /* blank line */ else msgf("%0.*v", s - logged, logged); logged = s + 1; } *s++ = c; if (verbose && s >= logged + 80) { msgf("%0.*v", s - logged, logged); logged = s; } if (Verbose) { if (c == '\n') fputc( '\n', stderr ); else if (c != '\r') fprintf( stderr, "%s", character(c) ); } if (!report_gathering) { for (n = 0; n < n_reports; ++n) { if ((report_string[n] != (char*) NULL) && s - temp >= (report_len = strlen(report_string[n])) && strncmp(s - report_len, report_string[n], report_len) == 0) { time_t time_now = time ((time_t*) NULL); struct tm* tm_now = localtime (&time_now); strftime (report_buffer, 20, "%b %d %H:%M:%S ", tm_now); strcat (report_buffer, report_string[n]); free(report_string[n]); report_string[n] = (char *) NULL; report_gathering = 1; break; } } } else { if (!iscntrl (c)) { int rep_len = strlen (report_buffer); if ((rep_len + 1) < sizeof(report_buffer)) { report_buffer[rep_len] = c; report_buffer[rep_len + 1] = '\0'; } } else { report_gathering = 0; fprintf (report_fp, "chat: %s\n", report_buffer); } } if (s - temp >= len && c == string[len - 1] && strncmp(s - len, string, len) == 0) { if (verbose) { if (s > logged) msgf("%0.*v", s - logged, logged); msgf(" -- got it\n"); } alarm(0); alarmed = 0; free(s1); return (1); } for (n = 0; n < n_aborts; ++n) { if (s - temp >= (abort_len = strlen(abort_string[n])) && strncmp(s - abort_len, abort_string[n], abort_len) == 0) { if (verbose) { if (s > logged) msgf("%0.*v", s - logged, logged); msgf(" -- failed"); } alarm(0); alarmed = 0; exit_code = n + 4; strcpy(fail_reason = fail_buffer, abort_string[n]); free(s1); return (0); } } if (s >= end) { if (logged < s - minlen) { if (verbose) msgf("%0.*v", s - logged, logged); logged = s; } s -= minlen; memmove(temp, s, minlen); logged = temp + (logged - s); s = temp + minlen; } if (alarmed && verbose) msgf("warning: alarm synchronization problem"); } alarm(0); if (verbose && printed) { if (alarmed) msgf(" -- read timed out"); else msgf(" -- read failed: %m"); } exit_code = 3; alarmed = 0; free(s1); return (0); } /* * Gross kludge to handle Solaris versions >= 2.6 having usleep. */ #ifdef SOL2 #include #if MAXUID > 65536 /* then this is Solaris 2.6 or later */ #undef NO_USLEEP #endif #endif /* SOL2 */ #ifdef NO_USLEEP #include #include /* usleep -- support routine for 4.2BSD system call emulations last edit: 29-Oct-1984 D A Gwyn */ extern int select(); /* returns 0 if ok, else -1 */ int usleep(long usec) /* delay in microseconds */ { static struct { /* `timeval' */ long tv_sec; /* seconds */ long tv_usec; /* microsecs */ } delay; /* _select() timeout */ delay.tv_sec = usec / 1000000L; delay.tv_usec = usec % 1000000L; return select(0, (long *)0, (long *)0, (long *)0, &delay); } #endif void pack_array ( char **array, /* The address of the array of string pointers */ int end) /* The index of the next free entry before CLR_ */ { int i, j; for (i = 0; i < end; i++) { if (array[i] == NULL) { for (j = i+1; j < end; ++j) if (array[j] != NULL) array[i++] = array[j]; for (; i < end; ++i) array[i] = NULL; break; } } } /* * vfmtmsg - format a message into a buffer. Like vsprintf except we * also specify the length of the output buffer, and we handle the * %m (error message) format. * Doesn't do floating-point formats. * Returns the number of chars put into buf. */ #define OUTCHAR(c) (buflen > 0? (--buflen, *buf++ = (c)): 0) int vfmtmsg(char *buf, int buflen, const char *fmt, va_list args) { int c, i, n; int width, prec, fillch; int base, len, neg, quoted; unsigned long val = 0; char *str, *buf0; const char *f; unsigned char *p; char num[32]; static char hexchars[] = "0123456789abcdef"; buf0 = buf; --buflen; while (buflen > 0) { for (f = fmt; *f != '%' && *f != 0; ++f) ; if (f > fmt) { len = f - fmt; if (len > buflen) len = buflen; memcpy(buf, fmt, len); buf += len; buflen -= len; fmt = f; } if (*fmt == 0) break; c = *++fmt; width = prec = 0; fillch = ' '; if (c == '0') { fillch = '0'; c = *++fmt; } if (c == '*') { width = va_arg(args, int); c = *++fmt; } else { while (isdigit(c)) { width = width * 10 + c - '0'; c = *++fmt; } } if (c == '.') { c = *++fmt; if (c == '*') { prec = va_arg(args, int); c = *++fmt; } else { while (isdigit(c)) { prec = prec * 10 + c - '0'; c = *++fmt; } } } str = 0; base = 0; neg = 0; ++fmt; switch (c) { case 'd': i = va_arg(args, int); if (i < 0) { neg = 1; val = -i; } else val = i; base = 10; break; case 'o': val = va_arg(args, unsigned int); base = 8; break; case 'x': val = va_arg(args, unsigned int); base = 16; break; case 'p': val = (unsigned long) va_arg(args, void *); base = 16; neg = 2; break; case 's': str = va_arg(args, char *); break; case 'c': num[0] = va_arg(args, int); num[1] = 0; str = num; break; case 'm': str = strerror(errno); break; case 'v': /* "visible" string */ case 'q': /* quoted string */ quoted = c == 'q'; p = va_arg(args, unsigned char *); if (fillch == '0' && prec > 0) { n = prec; } else { n = strlen((char *)p); if (prec > 0 && prec < n) n = prec; } while (n > 0 && buflen > 0) { c = *p++; --n; if (!quoted && c >= 0x80) { OUTCHAR('M'); OUTCHAR('-'); c -= 0x80; } if (quoted && (c == '"' || c == '\\')) OUTCHAR('\\'); if (c < 0x20 || (0x7f <= c && c < 0xa0)) { if (quoted) { OUTCHAR('\\'); switch (c) { case '\t': OUTCHAR('t'); break; case '\n': OUTCHAR('n'); break; case '\b': OUTCHAR('b'); break; case '\f': OUTCHAR('f'); break; default: OUTCHAR('x'); OUTCHAR(hexchars[c >> 4]); OUTCHAR(hexchars[c & 0xf]); } } else { if (c == '\t') OUTCHAR(c); else { OUTCHAR('^'); OUTCHAR(c ^ 0x40); } } } else OUTCHAR(c); } continue; default: *buf++ = '%'; if (c != '%') --fmt; /* so %z outputs %z etc. */ --buflen; continue; } if (base != 0) { str = num + sizeof(num); *--str = 0; while (str > num + neg) { *--str = hexchars[val % base]; val = val / base; if (--prec <= 0 && val == 0) break; } switch (neg) { case 1: *--str = '-'; break; case 2: *--str = 'x'; *--str = '0'; break; } len = num + sizeof(num) - 1 - str; } else { len = strlen(str); if (prec > 0 && len > prec) len = prec; } if (width > 0) { if (width > buflen) width = buflen; if ((n = width - len) > 0) { buflen -= n; for (; n > 0; --n) *buf++ = fillch; } } if (len > buflen) len = buflen; memcpy(buf, str, len); buf += len; buflen -= len; } *buf = 0; return buf - buf0; } ppp-2.5.0/contrib/0000755000175000017500000000000014412736275010771 500000000000000ppp-2.5.0/contrib/Makefile.am0000664000175000017500000000002514076444143012740 00000000000000SUBDIRS = pppgetpass ppp-2.5.0/contrib/Makefile.in0000644000175000017500000004644214407475314012766 00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = contrib ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_atm.m4 \ $(top_srcdir)/m4/ax_check_openssl.m4 \ $(top_srcdir)/m4/ax_check_openssl_func.m4 \ $(top_srcdir)/m4/ax_check_pam.m4 \ $(top_srcdir)/m4/ax_check_pcap.m4 \ $(top_srcdir)/m4/ax_check_srp.m4 $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/pkg.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/pppd/config.h \ $(top_builddir)/pppd/pppdconf.h \ $(top_builddir)/pppd/plugins/pppoe/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir distdir-am am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` DIST_SUBDIRS = $(SUBDIRS) am__DIST_COMMON = $(srcdir)/Makefile.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ ATM_CFLAGS = @ATM_CFLAGS@ ATM_LDFLAGS = @ATM_LDFLAGS@ ATM_LIBS = @ATM_LIBS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CRYPT_LIBS = @CRYPT_LIBS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GREP = @GREP@ GTK_CFLAGS = @GTK_CFLAGS@ GTK_LIBS = @GTK_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_INCLUDES = @OPENSSL_INCLUDES@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAM_CFLAGS = @PAM_CFLAGS@ PAM_LDFLAGS = @PAM_LDFLAGS@ PAM_LIBS = @PAM_LIBS@ PATH_SEPARATOR = @PATH_SEPARATOR@ PCAP_CFLAGS = @PCAP_CFLAGS@ PCAP_LDFLAGS = @PCAP_LDFLAGS@ PCAP_LIBS = @PCAP_LIBS@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PPPD_LOGFILE_DIR = @PPPD_LOGFILE_DIR@ PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@ PPPD_RUNTIME_DIR = @PPPD_RUNTIME_DIR@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SRP_CFLAGS = @SRP_CFLAGS@ SRP_LDFLAGS = @SRP_LDFLAGS@ SRP_LIBS = @SRP_LIBS@ STRIP = @STRIP@ SYSTEMD_CFLAGS = @SYSTEMD_CFLAGS@ SYSTEMD_LIBS = @SYSTEMD_LIBS@ SYSTEM_CA_PATH = @SYSTEM_CA_PATH@ UTIL_LIBS = @UTIL_LIBS@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = pppgetpass all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu contrib/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu contrib/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ check-am clean clean-generic clean-libtool cscopelist-am ctags \ ctags-am distclean distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ installdirs-am maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ ps ps-am tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: ppp-2.5.0/contrib/pppgetpass/0000755000175000017500000000000014412736275013157 500000000000000ppp-2.5.0/contrib/pppgetpass/Makefile.am0000664000175000017500000000072014076444143015130 00000000000000noinst_PROGRAMS = pppgetpass.vt noinst_man8_MANS = pppgetpass.8 pppgetpass_vt_SOURCES = pppgetpass.vt.c pppgetpass_vt_CPPFLAGS = -Wno-unused-result if WITH_GTK noinst_PROGRAMS += pppgetpass.gtk pppgetpass_gtk_SOURCES = pppgetpass.gtk.c pppgetpass_gtk_CPPFLAGS = -Wno-deprecated-declarations -Wno-discarded-qualifiers pppgetpass_gtk_CPPFLAGS += $(GLIB_CFLAGS) $(GTK_CFLAGS) pppgetpass_gtk_LDADD = $(GLIB_LIBS) $(GTK_LIBS) endif EXTRA_DIST = \ pppgetpass.sh ppp-2.5.0/contrib/pppgetpass/Makefile.in0000644000175000017500000006042414407475314015150 00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ noinst_PROGRAMS = pppgetpass.vt$(EXEEXT) $(am__EXEEXT_1) @WITH_GTK_TRUE@am__append_1 = pppgetpass.gtk subdir = contrib/pppgetpass ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_atm.m4 \ $(top_srcdir)/m4/ax_check_openssl.m4 \ $(top_srcdir)/m4/ax_check_openssl_func.m4 \ $(top_srcdir)/m4/ax_check_pam.m4 \ $(top_srcdir)/m4/ax_check_pcap.m4 \ $(top_srcdir)/m4/ax_check_srp.m4 $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/pkg.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/pppd/config.h \ $(top_builddir)/pppd/pppdconf.h \ $(top_builddir)/pppd/plugins/pppoe/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = @WITH_GTK_TRUE@am__EXEEXT_1 = pppgetpass.gtk$(EXEEXT) PROGRAMS = $(noinst_PROGRAMS) am__pppgetpass_gtk_SOURCES_DIST = pppgetpass.gtk.c @WITH_GTK_TRUE@am_pppgetpass_gtk_OBJECTS = \ @WITH_GTK_TRUE@ pppgetpass_gtk-pppgetpass.gtk.$(OBJEXT) pppgetpass_gtk_OBJECTS = $(am_pppgetpass_gtk_OBJECTS) am__DEPENDENCIES_1 = @WITH_GTK_TRUE@pppgetpass_gtk_DEPENDENCIES = $(am__DEPENDENCIES_1) \ @WITH_GTK_TRUE@ $(am__DEPENDENCIES_1) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = am_pppgetpass_vt_OBJECTS = pppgetpass_vt-pppgetpass.vt.$(OBJEXT) pppgetpass_vt_OBJECTS = $(am_pppgetpass_vt_OBJECTS) pppgetpass_vt_LDADD = $(LDADD) AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/pppd -I$(top_builddir)/pppd/plugins/pppoe depcomp = $(SHELL) $(top_srcdir)/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/pppgetpass_gtk-pppgetpass.gtk.Po \ ./$(DEPDIR)/pppgetpass_vt-pppgetpass.vt.Po am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(pppgetpass_gtk_SOURCES) $(pppgetpass_vt_SOURCES) DIST_SOURCES = $(am__pppgetpass_gtk_SOURCES_DIST) \ $(pppgetpass_vt_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ ATM_CFLAGS = @ATM_CFLAGS@ ATM_LDFLAGS = @ATM_LDFLAGS@ ATM_LIBS = @ATM_LIBS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CRYPT_LIBS = @CRYPT_LIBS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GREP = @GREP@ GTK_CFLAGS = @GTK_CFLAGS@ GTK_LIBS = @GTK_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_INCLUDES = @OPENSSL_INCLUDES@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAM_CFLAGS = @PAM_CFLAGS@ PAM_LDFLAGS = @PAM_LDFLAGS@ PAM_LIBS = @PAM_LIBS@ PATH_SEPARATOR = @PATH_SEPARATOR@ PCAP_CFLAGS = @PCAP_CFLAGS@ PCAP_LDFLAGS = @PCAP_LDFLAGS@ PCAP_LIBS = @PCAP_LIBS@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PPPD_LOGFILE_DIR = @PPPD_LOGFILE_DIR@ PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@ PPPD_RUNTIME_DIR = @PPPD_RUNTIME_DIR@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SRP_CFLAGS = @SRP_CFLAGS@ SRP_LDFLAGS = @SRP_LDFLAGS@ SRP_LIBS = @SRP_LIBS@ STRIP = @STRIP@ SYSTEMD_CFLAGS = @SYSTEMD_CFLAGS@ SYSTEMD_LIBS = @SYSTEMD_LIBS@ SYSTEM_CA_PATH = @SYSTEM_CA_PATH@ UTIL_LIBS = @UTIL_LIBS@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ noinst_man8_MANS = pppgetpass.8 pppgetpass_vt_SOURCES = pppgetpass.vt.c pppgetpass_vt_CPPFLAGS = -Wno-unused-result @WITH_GTK_TRUE@pppgetpass_gtk_SOURCES = pppgetpass.gtk.c @WITH_GTK_TRUE@pppgetpass_gtk_CPPFLAGS = -Wno-deprecated-declarations \ @WITH_GTK_TRUE@ -Wno-discarded-qualifiers $(GLIB_CFLAGS) \ @WITH_GTK_TRUE@ $(GTK_CFLAGS) @WITH_GTK_TRUE@pppgetpass_gtk_LDADD = $(GLIB_LIBS) $(GTK_LIBS) EXTRA_DIST = \ pppgetpass.sh all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu contrib/pppgetpass/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu contrib/pppgetpass/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstPROGRAMS: @list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \ echo " rm -f" $$list; \ rm -f $$list || exit $$?; \ test -n "$(EXEEXT)" || exit 0; \ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list pppgetpass.gtk$(EXEEXT): $(pppgetpass_gtk_OBJECTS) $(pppgetpass_gtk_DEPENDENCIES) $(EXTRA_pppgetpass_gtk_DEPENDENCIES) @rm -f pppgetpass.gtk$(EXEEXT) $(AM_V_CCLD)$(LINK) $(pppgetpass_gtk_OBJECTS) $(pppgetpass_gtk_LDADD) $(LIBS) pppgetpass.vt$(EXEEXT): $(pppgetpass_vt_OBJECTS) $(pppgetpass_vt_DEPENDENCIES) $(EXTRA_pppgetpass_vt_DEPENDENCIES) @rm -f pppgetpass.vt$(EXEEXT) $(AM_V_CCLD)$(LINK) $(pppgetpass_vt_OBJECTS) $(pppgetpass_vt_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pppgetpass_gtk-pppgetpass.gtk.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pppgetpass_vt-pppgetpass.vt.Po@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< pppgetpass_gtk-pppgetpass.gtk.o: pppgetpass.gtk.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppgetpass_gtk_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pppgetpass_gtk-pppgetpass.gtk.o -MD -MP -MF $(DEPDIR)/pppgetpass_gtk-pppgetpass.gtk.Tpo -c -o pppgetpass_gtk-pppgetpass.gtk.o `test -f 'pppgetpass.gtk.c' || echo '$(srcdir)/'`pppgetpass.gtk.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pppgetpass_gtk-pppgetpass.gtk.Tpo $(DEPDIR)/pppgetpass_gtk-pppgetpass.gtk.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pppgetpass.gtk.c' object='pppgetpass_gtk-pppgetpass.gtk.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppgetpass_gtk_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pppgetpass_gtk-pppgetpass.gtk.o `test -f 'pppgetpass.gtk.c' || echo '$(srcdir)/'`pppgetpass.gtk.c pppgetpass_gtk-pppgetpass.gtk.obj: pppgetpass.gtk.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppgetpass_gtk_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pppgetpass_gtk-pppgetpass.gtk.obj -MD -MP -MF $(DEPDIR)/pppgetpass_gtk-pppgetpass.gtk.Tpo -c -o pppgetpass_gtk-pppgetpass.gtk.obj `if test -f 'pppgetpass.gtk.c'; then $(CYGPATH_W) 'pppgetpass.gtk.c'; else $(CYGPATH_W) '$(srcdir)/pppgetpass.gtk.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pppgetpass_gtk-pppgetpass.gtk.Tpo $(DEPDIR)/pppgetpass_gtk-pppgetpass.gtk.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pppgetpass.gtk.c' object='pppgetpass_gtk-pppgetpass.gtk.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppgetpass_gtk_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pppgetpass_gtk-pppgetpass.gtk.obj `if test -f 'pppgetpass.gtk.c'; then $(CYGPATH_W) 'pppgetpass.gtk.c'; else $(CYGPATH_W) '$(srcdir)/pppgetpass.gtk.c'; fi` pppgetpass_vt-pppgetpass.vt.o: pppgetpass.vt.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppgetpass_vt_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pppgetpass_vt-pppgetpass.vt.o -MD -MP -MF $(DEPDIR)/pppgetpass_vt-pppgetpass.vt.Tpo -c -o pppgetpass_vt-pppgetpass.vt.o `test -f 'pppgetpass.vt.c' || echo '$(srcdir)/'`pppgetpass.vt.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pppgetpass_vt-pppgetpass.vt.Tpo $(DEPDIR)/pppgetpass_vt-pppgetpass.vt.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pppgetpass.vt.c' object='pppgetpass_vt-pppgetpass.vt.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppgetpass_vt_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pppgetpass_vt-pppgetpass.vt.o `test -f 'pppgetpass.vt.c' || echo '$(srcdir)/'`pppgetpass.vt.c pppgetpass_vt-pppgetpass.vt.obj: pppgetpass.vt.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppgetpass_vt_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pppgetpass_vt-pppgetpass.vt.obj -MD -MP -MF $(DEPDIR)/pppgetpass_vt-pppgetpass.vt.Tpo -c -o pppgetpass_vt-pppgetpass.vt.obj `if test -f 'pppgetpass.vt.c'; then $(CYGPATH_W) 'pppgetpass.vt.c'; else $(CYGPATH_W) '$(srcdir)/pppgetpass.vt.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pppgetpass_vt-pppgetpass.vt.Tpo $(DEPDIR)/pppgetpass_vt-pppgetpass.vt.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pppgetpass.vt.c' object='pppgetpass_vt-pppgetpass.vt.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppgetpass_vt_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pppgetpass_vt-pppgetpass.vt.obj `if test -f 'pppgetpass.vt.c'; then $(CYGPATH_W) 'pppgetpass.vt.c'; else $(CYGPATH_W) '$(srcdir)/pppgetpass.vt.c'; fi` mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(PROGRAMS) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstPROGRAMS \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/pppgetpass_gtk-pppgetpass.gtk.Po -rm -f ./$(DEPDIR)/pppgetpass_vt-pppgetpass.vt.Po -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/pppgetpass_gtk-pppgetpass.gtk.Po -rm -f ./$(DEPDIR)/pppgetpass_vt-pppgetpass.vt.Po -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstPROGRAMS cscopelist-am \ ctags ctags-am distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: ppp-2.5.0/contrib/pppgetpass/pppgetpass.gtk.c0000644000175000017500000000454707013703470016215 00000000000000#include #include #include #include #include #include #include #include #include #include #include #include #include #include int outfd; int err; static void okpressed(void *widget, void *clientdata) { GtkWidget *answer=clientdata; gchar *pass; int passlen; ssize_t wrote; (void)widget; pass=gtk_entry_get_text(GTK_ENTRY(answer)); passlen=strlen(pass); if(!passlen) return; if((wrote=write(outfd, pass, passlen))!=passlen) { if(wrote<0) syslog(LOG_ERR, "write error on outpipe: %m"); else syslog(LOG_ERR, "short write on outpipe"); err=1; } gtk_main_quit(); } int main(int argc, char **argv) { GtkWidget *mainwindow, *vbox, *question, *answer, *ok; char buf[1024]; gtk_init(&argc, &argv); openlog(argv[0], LOG_PID, LOG_DAEMON); if(argc!=4) { syslog(LOG_WARNING, "Usage error"); return 1; } outfd=atoi(argv[3]); mainwindow=gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_title(GTK_WINDOW(mainwindow), "pppgetpass"); gtk_signal_connect(GTK_OBJECT(mainwindow), "destroy", GTK_SIGNAL_FUNC(gtk_main_quit), 0); vbox=gtk_vbox_new(FALSE, 5); gtk_container_add(GTK_CONTAINER(mainwindow), vbox); gtk_widget_show(vbox); if(argv[1][0] && argv[2][0]) snprintf(buf, sizeof buf, "Password for PPP client %s on server %s: ", argv[1], argv[2]); else if(argv[1][0] && !argv[2][0]) snprintf(buf, sizeof buf, "Password for PPP client %s: ", argv[1]); else if(!argv[1][0] && argv[2][0]) snprintf(buf, sizeof buf, "Password for PPP on server %s: ", argv[2]); else snprintf(buf, sizeof buf, "Enter PPP password: "); question=gtk_label_new(buf); gtk_box_pack_start(GTK_BOX(vbox), question, FALSE, TRUE, 0); gtk_widget_show(question); answer=gtk_entry_new(); gtk_entry_set_visibility(GTK_ENTRY(answer), 0); gtk_box_pack_start(GTK_BOX(vbox), answer, FALSE, TRUE, 0); gtk_widget_show(answer); ok=gtk_button_new_with_label("OK"); gtk_box_pack_start(GTK_BOX(vbox), ok, FALSE, TRUE, 0); gtk_signal_connect(GTK_OBJECT(ok), "clicked", GTK_SIGNAL_FUNC(okpressed), answer); gtk_widget_show(ok); gtk_widget_show(mainwindow); gtk_main(); return err; } ppp-2.5.0/contrib/pppgetpass/pppgetpass.vt.c0000644000175000017500000001173407013703470016055 00000000000000#include #include #include #include #include #include #include #include #include #include #include static int console_owner(uid_t, int); int main(int argc, char **argv) { int console; uid_t uid; struct vt_stat origstate; int openvtnum; char openvtname[256]; int openvt; gid_t gid; int chowned; FILE *fp; struct termios t; char pass[256], *nl; int outfd, passlen; ssize_t wrote; console=open("/dev/console", O_RDWR); uid=getuid(); gid=getgid(); seteuid(uid); openlog(argv[0], LOG_PID, LOG_DAEMON); if(argc!=4) { syslog(LOG_WARNING, "Usage error"); return 1; } if(console<0) { syslog(LOG_ERR, "open(/dev/console): %m"); return 1; } if(ioctl(console, VT_GETSTATE, &origstate)<0) { syslog(LOG_ERR, "VT_GETSTATE: %m"); return 1; } if(uid) { if(!console_owner(uid, origstate.v_active)) { int i; for(i=0;i<64;++i) { if(i!=origstate.v_active && console_owner(uid, i)) break; } if(i==64) { syslog(LOG_WARNING, "run by uid %lu not at console", (unsigned long)uid); return 1; } } } if(ioctl(console, VT_OPENQRY, &openvtnum)<0) { syslog(LOG_ERR, "VT_OPENQRY: %m"); return 1; } if(openvtnum==-1) { syslog(LOG_ERR, "No free VTs"); return 1; } snprintf(openvtname, sizeof openvtname, "/dev/tty%d", openvtnum); seteuid(0); openvt=open(openvtname, O_RDWR); if(openvt<0) { seteuid(uid); syslog(LOG_ERR, "open(%s): %m", openvtname); return 1; } chowned=fchown(openvt, uid, gid); if(chowned<0) { seteuid(uid); syslog(LOG_ERR, "fchown(%s): %m", openvtname); return 1; } close(console); if(ioctl(openvt, VT_ACTIVATE, openvtnum)<0) { seteuid(uid); syslog(LOG_ERR, "VT_ACTIVATE(%d): %m", openvtnum); return 1; } while(ioctl(openvt, VT_WAITACTIVE, openvtnum)<0) { if(errno!=EINTR) { ioctl(openvt, VT_ACTIVATE, origstate.v_active); seteuid(uid); syslog(LOG_ERR, "VT_WAITACTIVE(%d): %m", openvtnum); return 1; } } seteuid(uid); fp=fdopen(openvt, "r+"); if(!fp) { seteuid(0); ioctl(openvt, VT_ACTIVATE, origstate.v_active); seteuid(uid); syslog(LOG_ERR, "fdopen(%s): %m", openvtname); return 1; } if(tcgetattr(openvt, &t)<0) { seteuid(0); ioctl(openvt, VT_ACTIVATE, origstate.v_active); seteuid(uid); syslog(LOG_ERR, "tcgetattr(%s): %m", openvtname); return 1; } t.c_lflag &= ~ECHO; if(tcsetattr(openvt, TCSANOW, &t)<0) { seteuid(0); ioctl(openvt, VT_ACTIVATE, origstate.v_active); seteuid(uid); syslog(LOG_ERR, "tcsetattr(%s): %m", openvtname); return 1; } if(fprintf(fp, "\033[2J\033[H")<0) { seteuid(0); ioctl(openvt, VT_ACTIVATE, origstate.v_active); seteuid(uid); syslog(LOG_ERR, "write error on %s: %m", openvtname); return 1; } if(argv[1][0] && argv[2][0]) { if(fprintf(fp, "Password for PPP client %s on server %s: ", argv[1], argv[2])<0) { seteuid(0); ioctl(openvt, VT_ACTIVATE, origstate.v_active); seteuid(uid); syslog(LOG_ERR, "write error on %s: %m", openvtname); return 1; } } else if(argv[1][0] && !argv[2][0]) { if(fprintf(fp, "Password for PPP client %s: ", argv[1])<0) { syslog(LOG_ERR, "write error on %s: %m", openvtname); seteuid(0); ioctl(openvt, VT_ACTIVATE, origstate.v_active); seteuid(uid); return 1; } } else if(!argv[1][0] && argv[2][0]) { if(fprintf(fp, "Password for PPP on server %s: ", argv[2])<0) { seteuid(0); ioctl(openvt, VT_ACTIVATE, origstate.v_active); seteuid(uid); syslog(LOG_ERR, "write error on %s: %m", openvtname); return 1; } } else { if(fprintf(fp, "Enter PPP password: ")<0) { seteuid(0); ioctl(openvt, VT_ACTIVATE, origstate.v_active); seteuid(uid); syslog(LOG_ERR, "write error on %s: %m", openvtname); return 1; } } if(!fgets(pass, sizeof pass, fp)) { seteuid(0); ioctl(openvt, VT_ACTIVATE, origstate.v_active); seteuid(uid); if(ferror(fp)) { syslog(LOG_ERR, "read error on %s: %m", openvtname); } return 1; } if((nl=strchr(pass, '\n'))) *nl=0; passlen=strlen(pass); outfd=atoi(argv[3]); if((wrote=write(outfd, pass, passlen))!=passlen) { seteuid(0); ioctl(openvt, VT_ACTIVATE, origstate.v_active); seteuid(uid); if(wrote<0) syslog(LOG_ERR, "write error on outpipe: %m"); else syslog(LOG_ERR, "short write on outpipe"); return 1; } seteuid(0); ioctl(openvt, VT_ACTIVATE, origstate.v_active); seteuid(uid); return 0; } static int console_owner(uid_t uid, int cons) { char name[256]; struct stat st; snprintf(name, sizeof name, "/dev/tty%d", cons); if(stat(name, &st)<0) { if(errno!=ENOENT) syslog(LOG_ERR, "stat(%s): %m", name); return 0; } return uid==st.st_uid; } ppp-2.5.0/contrib/pppgetpass/pppgetpass.sh0000644000175000017500000000014307013703470015605 00000000000000#!/bin/sh if [ -z "$DISPLAY" ]; then exec pppgetpass.vt "$@" else exec pppgetpass.gtk "$@" fi ppp-2.5.0/pppd/0000755000175000017500000000000014412736275010274 500000000000000ppp-2.5.0/pppd/Makefile.am0000644000175000017500000000754714407475306012264 00000000000000sbin_PROGRAMS = pppd dist_man8_MANS = pppd.8 check_PROGRAMS = utest_chap_SOURCES = chap_ms.c utils.c crypto_ms.c utest_chap_CPPFLAGS = -DUNIT_TEST utest_chap_LDFLAGS = utest_peap_SOURCES = peap.c utils.c mppe.c utest_peap_CPPFLAGS = -DUNIT_TEST utest_peap_LDFLAGS = utest_crypto_SOURCES = crypto.c utest_crypto_CPPFLAGS = -DUNIT_TEST utest_crypto_LDFLAGS = utest_pppcrypt_SOURCES = crypto_ms.c utest_pppcrypt_CPPFLAGS = -DUNIT_TEST_MSCRYPTO utest_pppcrypt_LDFLAGS = check_PROGRAMS += utest_crypto if WITH_SRP sbin_PROGRAMS += srp-entry dist_man8_MANS += srp-entry.8 endif pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = pppd.pc pppd_includedir = $(includedir)/pppd pppd_include_HEADERS = \ cbcp.h \ ccp.h \ chap.h \ chap_ms.h \ crypto.h \ crypto_ms.h \ eap.h \ ecp.h \ eui64.h \ fsm.h \ ipcp.h \ ipv6cp.h \ lcp.h \ magic.h \ mppe.h \ multilink.h \ pppd.h \ options.h \ pppdconf.h \ session.h \ upap.h # Headers to be distributed, but not installed in /usr/include/pppd noinst_HEADERS = \ chap-md5.h \ crypto-priv.h \ eap-tls.h \ pathnames.h \ peap.h \ pppd-private.h \ spinlock.h \ tls.h \ tdb.h pppd_SOURCES = \ auth.c \ ccp.c \ chap-md5.c \ chap.c \ demand.c \ eap.c \ ecp.c \ fsm.c \ ipcp.c \ lcp.c \ magic.c \ main.c \ options.c \ session.c \ tty.c \ upap.c \ utils.c pppd_CPPFLAGS = -DSYSCONFDIR=\"${sysconfdir}\" -DLOCALSTATEDIR=\"${localstatedir}\" -DPPPD_RUNTIME_DIR='"@PPPD_RUNTIME_DIR@"' -DPPPD_LOGFILE_DIR='"@PPPD_LOGFILE_DIR@"' pppd_LDFLAGS = pppd_LIBS = if PPP_WITH_SYSTEM_CA_PATH pppd_CPPFLAGS += -DSYSTEM_CA_PATH='"@SYSTEM_CA_PATH@"' endif if LINUX pppd_SOURCES += sys-linux.c noinst_HEADERS += termios_linux.h pppd_LIBS += $(CRYPT_LIBS) $(UTIL_LIBS) endif if SUNOS pppd_SOURCES += sys-solaris.c pppd_CPPFLAGS += -I${top_srcdir}/include pppd_LIBS += -lsocket -lnsl endif if PPP_WITH_CHAPMS pppd_SOURCES += chap_ms.c crypto_ms.c check_PROGRAMS += utest_chap check_PROGRAMS += utest_pppcrypt else if WITH_SRP pppd_SOURCES += crypto_ms.c check_PROGRAMS += utest_pppcrypt endif endif if PPP_WITH_CBCP pppd_SOURCES += cbcp.c endif if PPP_WITH_MPPE pppd_SOURCES += mppe.c endif if PPP_WITH_FILTER pppd_CPPFLAGS += $(PCAP_CFLAGS) pppd_LDFLAGS += $(PCAP_LDFLAGS) pppd_LIBS += $(PCAP_LIBS) endif if PPP_WITH_PLUGINS pppd_CPPFLAGS += -DPPPD_PLUGIN_DIR='"@PPPD_PLUGIN_DIR@"' pppd_LIBS += -ldl if LINUX pppd_LDFLAGS += -Wl,-E endif endif if PPP_WITH_MULTILINK pppd_SOURCES += multilink.c endif if PPP_WITH_TDB pppd_SOURCES += tdb.c spinlock.c endif if PPP_WITH_IPV6CP pppd_SOURCES += ipv6cp.c eui64.c endif if PPP_WITH_PAM pppd_CPPFLAGS += $(PAM_CFLAGS) pppd_LIBS += $(PAM_LIBS) -ldl pppd_LDFLAGS += $(PAM_LDFLAGS) endif if PPP_WITH_EAPTLS pppd_SOURCES += eap-tls.c tls.c else if PPP_WITH_PEAP pppd_SOURCES += tls.c endif endif if PPP_WITH_PEAP pppd_SOURCES += peap.c check_PROGRAMS += utest_peap endif noinst_LTLIBRARIES = libppp_crypto.la libppp_crypto_la_SOURCES=crypto.c ppp-md5.c ppp-md4.c ppp-sha1.c ppp-des.c if PPP_WITH_OPENSSL libppp_crypto_la_CPPFLAGS=$(OPENSSL_INCLUDES) libppp_crypto_la_LDFLAGS=$(OPENSSL_LDFLAGS) libppp_crypto_la_LIBADD=$(OPENSSL_LIBS) endif utest_peap_LDADD = libppp_crypto.la utest_chap_LDADD = libppp_crypto.la utest_crypto_LDADD = libppp_crypto.la utest_pppcrypt_LDADD = libppp_crypto.la pppd_LIBS += libppp_crypto.la if WITH_SYSTEMD pppd_CPPFLAGS += $(SYSTEMD_CFLAGS) pppd_LIBS += $(SYSTEMD_LIBS) endif if WITH_SRP srp_entry_SOURCES = srp-entry.c srp_entry_CPPFLAGS = $(OPENSSL_INCLUDES) $(SRP_CFLAGS) srp_entry_LDADD = $(SRP_LIBS) $(OPENSSL_LIBS) srp_entry_LDFLAGS = $(OPENSSL_LDFLAGS) $(SRP_LDFLAGS) pppd_CPPFLAGS += $(SRP_CFLAGS) pppd_LDFLAGS += $(SRP_LDFLAGS) pppd_LIBS += $(SRP_LIBS) endif pppd_LDADD = $(pppd_LIBS) EXTRA_DIST = \ ppp.pam TESTS = $(check_PROGRAMS) ppp-2.5.0/pppd/chap-md5.h0000664000175000017500000000253014273050614011754 00000000000000/* * chap-md5.h - New CHAP/MD5 implementation. * * Copyright (c) 2003 Paul Mackerras. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. The name(s) of the authors of this software must not be used to * endorse or promote products derived from this software without * prior written permission. * * 3. Redistributions of any form whatsoever must retain the following * acknowledgment: * "This product includes software developed by Paul Mackerras * ". * * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #ifndef PPP_CHAP_MD5_H #define PPP_CHAP_MD5_H #include "pppdconf.h" extern void chap_md5_init(void); #endif ppp-2.5.0/pppd/crypto-priv.h0000644000175000017500000000427314353435407012666 00000000000000/* ppp-crypo-priv.h - Crypto private data structures * * Copyright (c) 2022 Eivind Næss. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The name(s) of the authors of this software must not be used to * endorse or promote products derived from this software without * prior written permission. * * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #ifndef PPP_CRYPTO_PRIV_H #define PPP_CRYPTO_PRIV_H #include "crypto.h" #define MAX_KEY_SIZE 32 #define MAX_IV_SIZE 32 struct _PPP_MD { int (*init_fn)(PPP_MD_CTX *ctx); int (*update_fn)(PPP_MD_CTX *ctx, const void *data, size_t cnt); int (*final_fn)(PPP_MD_CTX *ctx, unsigned char *out, unsigned int *outlen); void (*clean_fn)(PPP_MD_CTX *ctx); }; struct _PPP_MD_CTX { PPP_MD md; void *priv; }; struct _PPP_CIPHER { int (*init_fn)(PPP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv); int (*update_fn)(PPP_CIPHER_CTX *ctx, unsigned char *out, int *outl, const unsigned char *in, int inl); int (*final_fn)(PPP_CIPHER_CTX *ctx, unsigned char *out, int *outl); void (*clean_fn)(PPP_CIPHER_CTX *ctx); }; struct _PPP_CIPHER_CTX { PPP_CIPHER cipher; unsigned char key[MAX_KEY_SIZE]; unsigned char iv[MAX_IV_SIZE]; int is_encr; void *priv; }; #endif ppp-2.5.0/pppd/eap-tls.h0000664000175000017500000000645714273050614011737 00000000000000/* * eap-tls.h * * Copyright (c) Beniamino Galvani 2005 All rights reserved. * Jan Just Keijser 2006-2019 All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The name(s) of the authors of this software must not be used to * endorse or promote products derived from this software without * prior written permission. * * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * */ #ifndef PPP_EAP_TLS_H #define PPP_EAP_TLS_H #include "pppdconf.h" #include "eap.h" #include #include #define EAP_TLS_FLAGS_LI 128 /* length included flag */ #define EAP_TLS_FLAGS_MF 64 /* more fragments flag */ #define EAP_TLS_FLAGS_START 32 /* start flag */ #define EAP_TLS_MAX_LEN 65536 /* max eap tls packet size */ struct tls_info; struct eaptls_session { u_char *data; /* buffered data */ int datalen; /* buffered data len */ int offset; /* from where to send */ int tlslen; /* total length of tls data */ bool frag; /* packet is fragmented */ bool tls_v13; /* whether we've negotiated TLSv1.3 */ SSL_CTX *ctx; SSL *ssl; /* ssl connection */ BIO *from_ssl; BIO *into_ssl; char peercertfile[MAXWORDLEN]; bool alert_sent; u_char alert_sent_desc; bool alert_recv; u_char alert_recv_desc; char rtx[EAP_TLS_MAX_LEN]; /* retransmission buffer */ int rtx_len; int mtu; /* unit mtu */ struct tls_info *info; }; SSL_CTX *eaptls_init_ssl(int init_server, char *cacertfile, char *capath, char *certfile, char *privkeyfile, char *pkcs12); int eaptls_init_ssl_server(eap_state * esp); int eaptls_init_ssl_client(eap_state * esp); void eaptls_free_session(struct eaptls_session *ets); int eaptls_is_init_finished(struct eaptls_session *ets); int eaptls_receive(struct eaptls_session *ets, u_char * inp, int len); int eaptls_send(struct eaptls_session *ets, u_char ** outp); void eaptls_retransmit(struct eaptls_session *ets, u_char ** outp); int get_eaptls_secret(int unit, char *client, char *server, char *clicertfile, char *servcertfile, char *cacertfile, char *capath, char *pkfile, char *pkcs12, int am_server); #ifdef PPP_WITH_MPPE void eaptls_gen_mppe_keys(struct eaptls_session *ets, int client); #endif #endif ppp-2.5.0/pppd/pathnames.h0000664000175000017500000001125414314203161012332 00000000000000/* * pathnames.h - define default paths for pppd * * Copyright (c) 1999-2002 Paul Mackerras. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. The name(s) of the authors of this software must not be used to * endorse or promote products derived from this software without * prior written permission. * * 3. Redistributions of any form whatsoever must retain the following * acknowledgment: * "This product includes software developed by Paul Mackerras * ". * * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /* * Paths are controlled by configure. Typically, one would pass the following options * to configure: * ./configure --prefix=/usr --sysconfdir=/etc --localstatedir=/var * * Note that if the prefix variable do control all the other directory variables, e.g * sysconfdir is ${prefix}/etc. Setting prefix to /usr, you'll have to override * sysconfdir with /etc to avoid installing config files into /usr/etc. * * In addition, there are three explicit variables that has overrides via configure: * - PPPD_RUNTIME_DIR, set by --with-runtime-dir= * - PPPD_LOGFILE_DIR, set by --with-logfile-dir= * - PPPD_PLUGIN_DIR, set by --with-plugin-dir= */ #ifndef PPP_PATHNAMES_H #define PPP_PATHNAMES_H #include "pppdconf.h" #ifdef HAVE_PATHS_H #include #endif /* HAVE_PATHS_H */ #ifndef _PATH_DEVNULL #define _PATH_DEVNULL "/dev/null" #endif #define PPP_DEVNULL _PATH_DEVNULL /* * PPPD_RUNTIME_DIR is set by passing --with-runtime-dir= via configure * the default value set by configure when option is absent is ${localstatedir}/run/pppd */ #ifdef PPPD_RUNTIME_DIR #define PPP_PATH_VARRUN PPPD_RUNTIME_DIR #else #define PPP_PATH_VARRUN _PATH_VARRUN #endif /* * PPPD_LOGFILE_DIR is set by passing --with-logfile-dir= via configure * the default value set by configure when option is absent is ${localstatedir}/log/ppp */ #ifdef PPPD_LOGFILE_DIR #define PPP_PATH_VARLOG PPPD_LOGFILE_DIR #else #define PPP_PATH_VARLOG _PATH_VARRUN "/log/ppp" #endif /* * PPPD_PLUGIN_DIR is set by passing --with-plugin-dir= via configure * the default value set by configure when option is absent is ${libdir}/pppd/${version} */ #ifdef PPPD_PLUGIN_DIR #define PPP_PATH_PLUGIN PPPD_PLUGIN_DIR #endif /* PPPD_PLUGIN_DIR */ #define PPP_PATH_CONFDIR SYSCONFDIR "/ppp" #define PPP_PATH_UPAPFILE PPP_PATH_CONFDIR "/pap-secrets" #define PPP_PATH_CHAPFILE PPP_PATH_CONFDIR "/chap-secrets" #define PPP_PATH_SRPFILE PPP_PATH_CONFDIR "/srp-secrets" #ifdef PPP_WITH_EAPTLS #define PPP_PATH_EAPTLSCLIFILE PPP_PATH_CONFDIR "/eaptls-client" #define PPP_PATH_EAPTLSSERVFILE PPP_PATH_CONFDIR "/eaptls-server" #define PPP_PATH_OPENSSLCONFFILE PPP_PATH_CONFDIR "/openssl.cnf" #endif /* PPP_WITH_EAPTLS */ #define PPP_PATH_SYSOPTIONS PPP_PATH_CONFDIR "/options" #define PPP_PATH_IPUP PPP_PATH_CONFDIR "/ip-up" #define PPP_PATH_IPDOWN PPP_PATH_CONFDIR "/ip-down" #define PPP_PATH_IPPREUP PPP_PATH_CONFDIR "/ip-pre-up" #define PPP_PATH_AUTHUP PPP_PATH_CONFDIR "/auth-up" #define PPP_PATH_AUTHDOWN PPP_PATH_CONFDIR "/auth-down" #define PPP_PATH_TTYOPT PPP_PATH_CONFDIR "/options." #define PPP_PATH_PEERFILES PPP_PATH_CONFDIR "/peers/" #define PPP_PATH_RESOLV PPP_PATH_CONFDIR "/resolv.conf" #define PPP_PATH_CONNERRS PPP_PATH_VARLOG "/connect-errors" #define PPP_PATH_USEROPT ".ppprc" #define PPP_PATH_PSEUDONYM ".ppp_pseudonym" #ifdef PPP_WITH_IPV6CP #define PPP_PATH_IPV6UP PPP_PATH_CONFDIR "/ipv6-up" #define PPP_PATH_IPV6DOWN PPP_PATH_CONFDIR "/ipv6-down" #endif #define PPP_PATH_PPPDB PPP_PATH_VARRUN "/pppd2.tdb" #ifdef __linux__ #define PPP_PATH_LOCKDIR PPP_PATH_VARRUN "/lock" #else #ifdef SVR4 #define PPP_PATH_LOCKDIR LOCALSTATEDIR "/spool/locks" #else #define PPP_PATH_LOCKDIR LOCALSTATEDIR "/spool/lock" #endif #endif #endif /* PPP_PATHNAMES_H */ ppp-2.5.0/pppd/peap.h0000664000175000017500000000564314273050614011313 00000000000000/* * Copyright (c) 2011 Rustam Kovhaev. All rights reserved. * Copyright (c) 2021 Eivind Næss. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The name(s) of the authors of this software must not be used to * endorse or promote products derived from this software without * prior written permission. * * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #ifndef PPP_PEAP_H #define PPP_PEAP_H #include "pppdconf.h" #define PEAP_PHASE_1 1 #define PEAP_PHASE_2 2 #define PEAP_HEADERLEN 6 #define PEAP_FRAGMENT_LENGTH_FIELD 4 #define PEAP_FLAGS_FIELD 1 #define PEAP_FLAGS_ACK 0 #define PEAP_CAPABILITIES_TYPE 254 #define PEAP_CAPABILITIES_LEN 12 #define PEAP_TLV_TYPE 12 #define PEAP_TLV_LENGTH_FIELD 56 #define PEAP_TLV_SUBTYPE_REQUEST 0 #define PEAP_TLV_SUBTYPE_RESPONSE 1 #define PEAP_TLV_HEADERLEN 8 #define PEAP_TLV_RESULT_LEN 7 #define PEAP_TLV_LEN 71 /* * Microsoft PEAP client/server never exchange * outer TLVs during PEAP authentication */ #define PEAP_TLV_DATA_LEN 61 #define PEAP_TLV_TK_LEN 60 #define PEAP_TLV_ISK_LEN 32 #define PEAP_TLV_IPMKSEED_LEN 59 #define PEAP_TLV_TEMPKEY_LEN 40 #define PEAP_TLV_IPMK_LEN 40 #define PEAP_TLV_CMK_LEN 20 #define PEAP_TLV_NONCE_LEN 32 #define PEAP_TLV_COMP_MAC_LEN 20 #define PEAP_TLV_CSK_LEN 128 #define PEAP_TLV_TK_SEED_LABEL "client EAP encryption" #define PEAP_TLV_IPMK_SEED_LABEL "Inner Methods Compound Keys" #define PEAP_TLV_CSK_SEED_LABEL "Session Key Generating Function" #define PEAP_S_FLAG_SET 0x20 #define PEAP_L_FLAG_SET 0x80 #define PEAP_LM_FLAG_SET 0xC0 #define PEAP_M_FLAG_SET 0x40 #define PEAP_NO_FLAGS 0x00 #define EAP_TLS_KEY_LEN 0x40 #define TLS_RECORD_MAX_SIZE 0x4000 struct peap_state; /** * Initialize the PEAP structure */ int peap_init(struct peap_state** psm, const char *remote_name); /** * Process a PEAP packet */ int peap_process(eap_state *esp, u_char id, u_char *inp, int len); /** * Clean up the PEAP structure */ void peap_finish(struct peap_state **psm); #endif /* PPP_PEAP_H */ ppp-2.5.0/pppd/pppd-private.h0000644000175000017500000005637614353435407013016 00000000000000/* * pppd-private.h - PPP daemon private declarations. * * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The name "Carnegie Mellon University" must not be used to * endorse or promote products derived from this software without * prior written permission. For permission or any legal * details, please contact * Office of Technology Transfer * Carnegie Mellon University * 5000 Forbes Avenue * Pittsburgh, PA 15213-3890 * (412) 268-4387, fax: (412) 268-7395 * tech-transfer@andrew.cmu.edu * * 4. Redistributions of any form whatsoever must retain the following * acknowledgment: * "This product includes software developed by Computing Services * at Carnegie Mellon University (http://www.cmu.edu/computing/)." * * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * $Id: pppd.h,v 1.96 2008/06/23 11:47:18 paulus Exp $ */ #ifndef PPP_PPPD_PRIVATE_H #define PPP_PPPD_PRIVATE_H #include /* for FILE */ #include /* for encrypt */ #include /* for setkey */ #if defined(SOL2) #include #else #include #endif #include "pppd.h" #ifdef PPP_WITH_IPV6CP #include "eui64.h" #endif /* * If PPP_DRV_NAME is not defined, use the default "ppp" as the device name. * Where should PPP_DRV_NAME come from? Do we include it here? */ #if !defined(PPP_DRV_NAME) #define PPP_DRV_NAME "ppp" #endif /* !defined(PPP_DRV_NAME) */ #ifndef GIDSET_TYPE #define GIDSET_TYPE gid_t #endif /* Structure representing a list of permitted IP addresses. */ struct permitted_ip { int permit; /* 1 = permit, 0 = forbid */ u_int32_t base; /* match if (addr & mask) == base */ u_int32_t mask; /* base and mask are in network byte order */ }; struct notifier { struct notifier *next; ppp_notify_fn *func; void *arg; }; /* * Global variables. */ extern int hungup; /* Physical layer has disconnected */ extern int ifunit; /* Interface unit number */ extern char ifname[]; /* Interface name (IFNAMSIZ) */ extern char hostname[]; /* Our hostname */ extern unsigned char outpacket_buf[]; /* Buffer for outgoing packets */ extern int devfd; /* fd of underlying device */ extern int fd_ppp; /* fd for talking PPP */ extern int baud_rate; /* Current link speed in bits/sec */ extern char *progname; /* Name of this program */ extern int redirect_stderr;/* Connector's stderr should go to file */ extern char peer_authname[];/* Authenticated name of peer */ extern int auth_done[NUM_PPP]; /* Methods actually used for auth */ extern int privileged; /* We were run by real-uid root */ extern int need_holdoff; /* Need holdoff period after link terminates */ extern char **script_env; /* Environment variables for scripts */ extern int detached; /* Have detached from controlling tty */ extern GIDSET_TYPE groups[]; /* groups the user is in */ extern int ngroups; /* How many groups valid in groups */ extern int link_stats_valid; /* set if link_stats is valid */ extern int link_stats_print; /* set if link_stats is to be printed on link termination */ extern int log_to_fd; /* logging to this fd as well as syslog */ extern bool log_default; /* log_to_fd is default (stdout) */ extern char *no_ppp_msg; /* message to print if ppp not in kernel */ extern bool devnam_fixed; /* can no longer change devnam */ extern int unsuccess; /* # unsuccessful connection attempts */ extern int do_callback; /* set if we want to do callback next */ extern int doing_callback; /* set if this is a callback */ extern int error_count; /* # of times error() has been called */ extern char ppp_devname[]; /* name of PPP tty (maybe ttypx) */ extern int fd_devnull; /* fd open to /dev/null */ extern int listen_time; /* time to listen first (ms) */ extern bool bundle_eof; extern bool bundle_terminating; extern struct notifier *pidchange; /* for notifications of pid changing */ extern struct notifier *phasechange; /* for notifications of phase changes */ extern struct notifier *exitnotify; /* for notification that we're exiting */ extern struct notifier *sigreceived; /* notification of received signal */ extern struct notifier *ip_up_notifier; /* IPCP has come up */ extern struct notifier *ip_down_notifier; /* IPCP has gone down */ extern struct notifier *ipv6_up_notifier; /* IPV6CP has come up */ extern struct notifier *ipv6_down_notifier; /* IPV6CP has gone down */ extern struct notifier *auth_up_notifier; /* peer has authenticated */ extern struct notifier *link_down_notifier; /* link has gone down */ extern struct notifier *fork_notifier; /* we are a new child process */ /* Values for do_callback and doing_callback */ #define CALLBACK_DIALIN 1 /* we are expecting the call back */ #define CALLBACK_DIALOUT 2 /* we are dialling out to call back */ /* * Variables set by command-line options. */ extern int debug; /* Debug flag */ extern int kdebugflag; /* Tell kernel to print debug messages */ extern int default_device; /* Using /dev/tty or equivalent */ extern char devnam[]; /* Device name */ extern char remote_number[MAXNAMELEN]; /* Remote telephone number, if avail. */ extern int ppp_session_number; /* Session number (eg PPPoE session) */ extern int crtscts; /* Use hardware flow control */ extern int stop_bits; /* Number of serial port stop bits */ extern bool modem; /* Use modem control lines */ extern int inspeed; /* Input/Output speed requested */ extern u_int32_t netmask; /* IP netmask to set on interface */ extern bool lockflag; /* Create lock file to lock the serial dev */ extern bool nodetach; /* Don't detach from controlling tty */ #ifdef SYSTEMD extern bool up_sdnotify; /* Notify systemd once link is up (implies nodetach) */ #endif extern bool updetach; /* Detach from controlling tty when link up */ extern bool master_detach; /* Detach when multilink master without link (options.c) */ extern char *initializer; /* Script to initialize physical link */ extern char *connect_script; /* Script to establish physical link */ extern char *disconnect_script; /* Script to disestablish physical link */ extern char *welcomer; /* Script to welcome client after connection */ extern char *ptycommand; /* Command to run on other side of pty */ extern char user[MAXNAMELEN];/* Our name for authenticating ourselves */ extern char passwd[MAXSECRETLEN]; /* Password for PAP or CHAP */ extern bool auth_required; /* Peer is required to authenticate */ extern bool persist; /* Reopen link after it goes down */ extern bool uselogin; /* Use /etc/passwd for checking PAP */ extern bool session_mgmt; /* Do session management (login records) */ extern char our_name[MAXNAMELEN];/* Our name for authentication purposes */ extern char remote_name[MAXNAMELEN]; /* Peer's name for authentication */ extern bool explicit_remote;/* remote_name specified with remotename opt */ extern bool demand; /* Do dial-on-demand */ extern char *ipparam; /* Extra parameter for ip up/down scripts */ extern bool cryptpap; /* Others' PAP passwords are encrypted */ extern int holdoff; /* Dead time before restarting */ extern bool holdoff_specified; /* true if user gave a holdoff value */ extern bool notty; /* Stdin/out is not a tty */ extern char *pty_socket; /* Socket to connect to pty */ extern char *record_file; /* File to record chars sent/received */ extern int maxfail; /* Max # of unsuccessful connection attempts */ extern char linkname[]; /* logical name for link */ extern bool tune_kernel; /* May alter kernel settings as necessary */ extern int connect_delay; /* Time to delay after connect script */ extern int max_data_rate; /* max bytes/sec through charshunt */ extern int req_unit; /* interface unit number to use */ extern char path_ipup[]; /* pathname of ip-up script */ extern char path_ipdown[]; /* pathname of ip-down script */ extern char req_ifname[]; /* interface name to use (IFNAMSIZ) */ extern bool multilink; /* enable multilink operation (options.c) */ extern bool noendpoint; /* don't send or accept endpt. discrim. */ extern char *bundle_name; /* bundle name for multilink */ extern bool dump_options; /* print out option values */ extern bool show_options; /* show all option names and descriptions */ extern bool dryrun; /* check everything, print options, exit */ extern int child_wait; /* # seconds to wait for children at end */ extern char *current_option; /* the name of the option being parsed */ extern int privileged_option; /* set iff the current option came from root */ extern char *option_source; /* string saying where the option came from */ extern int option_priority; /* priority of current options */ #ifdef PPP_WITH_IPV6CP extern char path_ipv6up[]; /* pathname of ipv6-up script */ extern char path_ipv6down[]; /* pathname of ipv6-down script */ #endif #if defined(PPP_WITH_EAPTLS) || defined(PPP_WITH_PEAP) #define TLS_VERIFY_NONE "none" #define TLS_VERIFY_NAME "name" #define TLS_VERIFY_SUBJECT "subject" #define TLS_VERIFY_SUFFIX "suffix" extern char *crl_dir; extern char *crl_file; extern char *ca_path; extern char *cacert_file; extern char *max_tls_version; extern bool tls_verify_key_usage; extern char *tls_verify_method; #endif /* PPP_WITH_EAPTLS || PPP_WITH_PEAP */ #ifdef PPP_WITH_EAPTLS extern char *pkcs12_file; #endif /* PPP_WITH_EAPTLS */ typedef enum { PPP_OCTETS_DIRECTION_SUM, PPP_OCTETS_DIRECTION_IN, PPP_OCTETS_DIRECTION_OUT, PPP_OCTETS_DIRECTION_MAXOVERAL, PPP_OCTETS_DIRECTION_MAXSESSION /* Same as MAXOVERALL, but a little different for RADIUS */ } session_limit_dir_t; extern unsigned int maxoctets; /* Maximum octetes per session (in bytes) */ extern session_limit_dir_t maxoctets_dir; /* Direction */ extern int maxoctets_timeout; /* Timeout for check of octets limit */ #ifdef PPP_WITH_FILTER extern struct bpf_program pass_filter; /* Filter for pkts to pass */ extern struct bpf_program active_filter; /* Filter for link-active pkts */ #endif #ifdef PPP_WITH_MSLANMAN extern bool ms_lanman; /* Use LanMan password instead of NT */ /* Has meaning only with MS-CHAP challenges */ #endif /* Values for auth_pending, auth_done */ #define PAP_WITHPEER 0x1 #define PAP_PEER 0x2 #define CHAP_WITHPEER 0x4 #define CHAP_PEER 0x8 #define EAP_WITHPEER 0x10 #define EAP_PEER 0x20 /* Values for auth_done only */ #define CHAP_MD5_WITHPEER 0x40 #define CHAP_MD5_PEER 0x80 #define CHAP_MS_SHIFT 8 /* LSB position for MS auths */ #define CHAP_MS_WITHPEER 0x100 #define CHAP_MS_PEER 0x200 #define CHAP_MS2_WITHPEER 0x400 #define CHAP_MS2_PEER 0x800 /* * This structure contains environment variables that are set or unset * by the user. */ struct userenv { struct userenv *ue_next; char *ue_value; /* value (set only) */ bool ue_isset; /* 1 for set, 0 for unset */ bool ue_priv; /* from privileged source */ const char *ue_source; /* source name */ char ue_name[1]; /* variable name */ }; extern struct userenv *userenv_list; /* * Prototypes. */ /* Procedures exported from main.c. */ void set_ifunit(int); /* set stuff that depends on ifunit */ void detach(void); /* Detach from controlling tty */ void die(int); /* Cleanup and exit */ void quit(void); /* like die(1) */ void record_child(int, char *, void (*) (void *), void *, int); int device_script(char *cmd, int in, int out, int dont_wait); /* Run `cmd' with given stdin and stdout */ pid_t run_program(char *prog, char * const * args, int must_exist, void (*done)(void *), void *arg, int wait); /* Run program prog with args in child */ void reopen_log(void); /* (re)open the connection to syslog */ void print_link_stats(void); /* Print stats, if available */ void reset_link_stats(int); /* Reset (init) stats when link goes up */ void new_phase(ppp_phase_t); /* signal start of new phase */ bool in_phase(ppp_phase_t); void notify(struct notifier *, int); int ppp_send_config(int, int, u_int32_t, int, int); int ppp_recv_config(int, int, u_int32_t, int, int); const char *protocol_name(int); void remove_pidfiles(void); void lock_db(void); void unlock_db(void); /* Procedures exported from tty.c. */ void tty_init(void); void print_string(char *, int, printer_func, void *); /* Format a string for output */ ssize_t complete_read(int, void *, size_t); /* read a complete buffer */ /* Procedures exported from auth.c */ void link_required(int); /* we are starting to use the link */ void start_link(int); /* bring the link up now */ void link_terminated(int); /* we are finished with the link */ void link_down(int); /* the LCP layer has left the Opened state */ void upper_layers_down(int);/* take all NCPs down */ void link_established(int); /* the link is up; authenticate now */ void start_networks(int); /* start all the network control protos */ void continue_networks(int); /* start network [ip, etc] control protos */ void np_up(int, int); /* a network protocol has come up */ void np_down(int, int); /* a network protocol has gone down */ void np_finished(int, int); /* a network protocol no longer needs link */ void auth_peer_fail(int, int); /* peer failed to authenticate itself */ void auth_peer_success(int, int, int, char *, int); /* peer successfully authenticated itself */ void auth_withpeer_fail(int, int); /* we failed to authenticate ourselves */ void auth_withpeer_success(int, int, int); /* we successfully authenticated ourselves */ void auth_check_options(void); /* check authentication options supplied */ void auth_reset(int); /* check what secrets we have */ int check_passwd(int, char *, int, char *, int, char **); /* Check peer-supplied username/password */ int get_secret(int, char *, char *, char *, int *, int); /* get "secret" for chap */ int get_srp_secret(int unit, char *client, char *server, char *secret, int am_server); int auth_ip_addr(int, u_int32_t); /* check if IP address is authorized */ int auth_number(void); /* check if remote number is authorized */ /* Procedures exported from demand.c */ void demand_conf(void); /* config interface(s) for demand-dial */ void demand_block(void); /* set all NPs to queue up packets */ void demand_unblock(void); /* set all NPs to pass packets */ void demand_discard(void); /* set all NPs to discard packets */ void demand_rexmit(int); /* retransmit saved frames for an NP */ int loop_chars(unsigned char *, int); /* process chars from loopback */ int loop_frame(unsigned char *, int); /* should we bring link up? */ /* Procedures exported from sys-*.c */ void sys_init(void); /* Do system-dependent initialization */ void sys_cleanup(void); /* Restore system state before exiting */ int sys_check_options(void); /* Check options specified */ int get_pty(int *, int *, char *, int); /* Get pty master/slave */ int open_ppp_loopback(void); /* Open loopback for demand-dialling */ int tty_establish_ppp(int); /* Turn serial port into a ppp interface */ void tty_disestablish_ppp(int); /* Restore port to normal operation */ void make_new_bundle(int, int, int, int); /* Create new bundle */ int bundle_attach(int); /* Attach link to existing bundle */ void cfg_bundle(int, int, int, int); /* Configure existing bundle */ void destroy_bundle(void); /* Tell driver to destroy bundle */ void clean_check(void); /* Check if line was 8-bit clean */ void set_up_tty(int, int); /* Set up port's speed, parameters, etc. */ void restore_tty(int); /* Restore port's original parameters */ void setdtr(int, int); /* Raise or lower port's DTR line */ void output(int, unsigned char *, int); /* Output a PPP packet */ void wait_input(struct timeval *); /* Wait for input, with timeout */ void add_fd(int); /* Add fd to set to wait for */ void remove_fd(int); /* Remove fd from set to wait for */ int read_packet(unsigned char *); /* Read PPP packet */ int get_loop_output(void); /* Read pkts from loopback */ void tty_send_config(int, u_int32_t, int, int); /* Configure i/f transmit parameters */ void tty_set_xaccm(ext_accm); /* Set extended transmit ACCM */ void tty_recv_config(int, u_int32_t, int, int); /* Configure i/f receive parameters */ int ccp_test(int, unsigned char *, int, int); /* Test support for compression scheme */ void ccp_flags_set(int, int, int); /* Set kernel CCP state */ int ccp_fatal_error(int); /* Test for fatal decomp error in kernel */ int get_idle_time(int, struct ppp_idle *); /* Find out how long link has been idle */ int get_ppp_stats(int, struct pppd_stats *); /* Return link statistics */ int sifvjcomp(int, int, int, int); /* Configure VJ TCP header compression */ int sifup(int); /* Configure i/f up for one protocol */ int sifnpmode(int u, int proto, enum NPmode mode); /* Set mode for handling packets for proto */ int sifdown(int); /* Configure i/f down for one protocol */ int sifaddr(int, u_int32_t, u_int32_t, u_int32_t); /* Configure IPv4 addresses for i/f */ int cifaddr(int, u_int32_t, u_int32_t); /* Reset i/f IP addresses */ #ifdef PPP_WITH_IPV6CP int sif6up(int); /* Configure i/f up for IPv6 */ int sif6down(int); /* Configure i/f down for IPv6 */ int sif6addr(int, eui64_t, eui64_t); /* Configure IPv6 addresses for i/f */ int cif6addr(int, eui64_t, eui64_t); /* Remove an IPv6 address from i/f */ #endif int sifdefaultroute(int, u_int32_t, u_int32_t, bool replace_default_rt); /* Create default route through i/f */ int cifdefaultroute(int, u_int32_t, u_int32_t); /* Delete default route through i/f */ #ifdef PPP_WITH_IPV6CP int sif6defaultroute(int, eui64_t, eui64_t); /* Create default IPv6 route through i/f */ int cif6defaultroute(int, eui64_t, eui64_t); /* Delete default IPv6 route through i/f */ #endif int sifproxyarp(int, u_int32_t); /* Add proxy ARP entry for peer */ int cifproxyarp(int, u_int32_t); /* Delete proxy ARP entry for peer */ u_int32_t GetMask(u_int32_t); /* Get appropriate netmask for address */ int lock(char *); /* Create lock file for device */ int relock(int); /* Rewrite lock file with new pid */ void unlock(void); /* Delete previously-created lock file */ void logwtmp(const char *, const char *, const char *); /* Write entry to wtmp file */ int get_host_seed(void); /* Get host-dependent random number seed */ int have_route_to(u_int32_t); /* Check if route to addr exists */ #ifdef PPP_WITH_FILTER int set_filters(struct bpf_program *pass, struct bpf_program *active); /* Set filter programs in kernel */ #endif int get_if_hwaddr(unsigned char *addr, char *name); int get_first_ether_hwaddr(unsigned char *addr); /* Procedures exported from options.c */ int setipaddr(char *, char **, int); /* Set local/remote ip addresses */ int parse_args(int argc, char **argv); /* Parse options from arguments given */ int getword(FILE *f, char *word, int *newlinep, char *filename); /* Read a word from a file */ int options_from_user(void); /* Parse options from user's .ppprc */ int options_for_tty(void); /* Parse options from /etc/ppp/options.tty */ struct wordlist; int options_from_list(struct wordlist *, int privileged); /* Parse options from a wordlist */ void check_options(void); /* check values after all options parsed */ int override_value(char *, int, const char *); /* override value if permitted by priority */ void print_options(printer_func, void *); /* print out values of all options */ void showopts(void); /* show all option names and description */ int parse_dotted_ip(char *, u_int32_t *); /* * Inline versions of get/put char/short/long. * Pointer is advanced; we assume that both arguments * are lvalues and will already be in registers. * cp MUST be unsigned char *. */ #define GETCHAR(c, cp) { \ (c) = *(cp)++; \ } #define PUTCHAR(c, cp) { \ *(cp)++ = (unsigned char) (c); \ } #define GETSHORT(s, cp) { \ (s) = *(cp)++ << 8; \ (s) |= *(cp)++; \ } #define PUTSHORT(s, cp) { \ *(cp)++ = (unsigned char) ((s) >> 8); \ *(cp)++ = (unsigned char) (s); \ } #define GETLONG(l, cp) { \ (l) = *(cp)++ << 8; \ (l) |= *(cp)++; (l) <<= 8; \ (l) |= *(cp)++; (l) <<= 8; \ (l) |= *(cp)++; \ } #define PUTLONG(l, cp) { \ *(cp)++ = (unsigned char) ((l) >> 24); \ *(cp)++ = (unsigned char) ((l) >> 16); \ *(cp)++ = (unsigned char) ((l) >> 8); \ *(cp)++ = (unsigned char) (l); \ } #define INCPTR(n, cp) ((cp) += (n)) #define DECPTR(n, cp) ((cp) -= (n)) /* * System dependent definitions for user-level 4.3BSD UNIX implementation. */ #define TIMEOUT(r, f, t) ppp_timeout((r), (f), (t), 0) #define UNTIMEOUT(r, f) ppp_untimeout((r), (f)) #define BCOPY(s, d, l) memcpy(d, s, l) #define BZERO(s, n) memset(s, 0, n) #define BCMP(s1, s2, l) memcmp(s1, s2, l) #define PRINTMSG(m, l) { info("Remote message: %0.*v", l, m); } /* * MAKEHEADER - Add Header fields to a packet. */ #define MAKEHEADER(p, t) { \ PUTCHAR(PPP_ALLSTATIONS, p); \ PUTCHAR(PPP_UI, p); \ PUTSHORT(t, p); } /* * Debug macros. Slightly useful for finding bugs in pppd, not particularly * useful for finding out why your connection isn't being established. */ #ifdef DEBUGALL #define DEBUGMAIN 1 #define DEBUGFSM 1 #define DEBUGLCP 1 #define DEBUGIPCP 1 #define DEBUGIPV6CP 1 #define DEBUGUPAP 1 #define DEBUGCHAP 1 #endif #ifndef LOG_PPP /* we use LOG_LOCAL2 for syslog by default */ #if defined(DEBUGMAIN) || defined(DEBUGFSM) || defined(DEBUGSYS) \ || defined(DEBUGLCP) || defined(DEBUGIPCP) || defined(DEBUGUPAP) \ || defined(DEBUGCHAP) || defined(DEBUG) || defined(DEBUGIPV6CP) #define LOG_PPP LOG_LOCAL2 #else #define LOG_PPP LOG_DAEMON #endif #endif /* LOG_PPP */ #ifdef DEBUGMAIN #define MAINDEBUG(x) if (debug) dbglog x #else #define MAINDEBUG(x) #endif #ifdef DEBUGSYS #define SYSDEBUG(x) if (debug) dbglog x #else #define SYSDEBUG(x) #endif #ifdef DEBUGFSM #define FSMDEBUG(x) if (debug) dbglog x #else #define FSMDEBUG(x) #endif #ifdef DEBUGLCP #define LCPDEBUG(x) if (debug) dbglog x #else #define LCPDEBUG(x) #endif #ifdef DEBUGIPCP #define IPCPDEBUG(x) if (debug) dbglog x #else #define IPCPDEBUG(x) #endif #ifdef DEBUGIPV6CP #define IPV6CPDEBUG(x) if (debug) dbglog x #else #define IPV6CPDEBUG(x) #endif #ifdef DEBUGUPAP #define UPAPDEBUG(x) if (debug) dbglog x #else #define UPAPDEBUG(x) #endif #ifdef DEBUGCHAP #define CHAPDEBUG(x) if (debug) dbglog x #else #define CHAPDEBUG(x) #endif #ifndef SIGTYPE #if defined(sun) || defined(SYSV) || defined(POSIX_SOURCE) #define SIGTYPE void #else #define SIGTYPE int #endif /* defined(sun) || defined(SYSV) || defined(POSIX_SOURCE) */ #endif /* SIGTYPE */ #ifndef MIN #define MIN(a, b) ((a) < (b)? (a): (b)) #endif #ifndef MAX #define MAX(a, b) ((a) > (b)? (a): (b)) #endif #ifndef offsetof #define offsetof(type, member) ((size_t) &((type *)0)->member) #endif #endif ppp-2.5.0/pppd/spinlock.h0000644000175000017500000000470514407475306012214 00000000000000/* Unix SMB/CIFS implementation. trivial database library Copyright (C) Anton Blanchard 2001 ** NOTE! The following LGPL license applies to the tdb ** library. This does NOT imply that all of Samba is released ** under the LGPL This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef PPP_SPINLOCK_H #define PPP_SPINLOCK_H #include "pppdconf.h" #include "tdb.h" #ifdef USE_SPINLOCKS #define RWLOCK_BIAS 0x1000UL /* OS SPECIFIC */ #define MAX_BUSY_LOOPS 1000 #undef USE_SCHED_YIELD /* ARCH SPECIFIC */ /* We should make sure these are padded to a cache line */ #if defined(SPARC_SPINLOCKS) typedef volatile char spinlock_t; #elif defined(POWERPC_SPINLOCKS) typedef volatile unsigned long spinlock_t; #elif defined(INTEL_SPINLOCKS) typedef volatile int spinlock_t; #elif defined(MIPS_SPINLOCKS) typedef volatile unsigned long spinlock_t; #else #error Need to implement spinlock code in spinlock.h #endif typedef struct { spinlock_t lock; volatile int count; } tdb_rwlock_t; int tdb_spinlock(TDB_CONTEXT *tdb, int list, int rw_type); int tdb_spinunlock(TDB_CONTEXT *tdb, int list, int rw_type); int tdb_create_rwlocks(int fd, unsigned int hash_size); int tdb_clear_spinlocks(TDB_CONTEXT *tdb); #define TDB_SPINLOCK_SIZE(hash_size) (((hash_size) + 1) * sizeof(tdb_rwlock_t)) #else /* !USE_SPINLOCKS */ #if 0 #define tdb_create_rwlocks(fd, hash_size) 0 #define tdb_spinlock(tdb, list, rw_type) (-1) #define tdb_spinunlock(tdb, list, rw_type) (-1) #else int tdb_spinlock(TDB_CONTEXT *tdb, int list, int rw_type); int tdb_spinunlock(TDB_CONTEXT *tdb, int list, int rw_type); int tdb_create_rwlocks(int fd, unsigned int hash_size); #endif int tdb_clear_spinlocks(TDB_CONTEXT *tdb); #define TDB_SPINLOCK_SIZE(hash_size) 0 #endif #endif // PPP_SPINLOCK_H ppp-2.5.0/pppd/tls.h0000664000175000017500000000457614273050614011174 00000000000000/* * Copyright (c) 2021 Eivind Næss. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The name(s) of the authors of this software must not be used to * endorse or promote products derived from this software without * prior written permission. * * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #ifndef PPP_TLS_H #define PPP_TLS_H #include "pppdconf.h" /** * Structure used in verifying the peer certificate */ struct tls_info; /** * Initialize the SSL library */ int tls_init(); /** * Get the SSL_METHOD */ const SSL_METHOD* tls_method(); /** * Configure the SSL options */ int tls_set_opts(SSL_CTX *ctx); /** * Configure the SSL context's max TLS version */ int tls_set_version(SSL_CTX *ctx, const char *max_version); /** * Configure the SSL context's verify callback */ int tls_set_verify(SSL_CTX *ctx, int depth); /** * Configure the SSL verify information */ int tls_set_verify_info(SSL *ssl, const char *peer_name, const char *peer_cert_file, bool client, struct tls_info **out); /** * Free the tls_info structure and it's members */ void tls_free_verify_info(struct tls_info **in); /** * Configure the SSL context's CRL details */ int tls_set_crl(SSL_CTX *ctx, const char *crl_dir, const char *crl_file); /** * Configure the SSL context's CA verify locations */ int tls_set_ca(SSL_CTX *ctx, const char *ca_dir, const char *ca_file); /** * Log all errors from ssl library */ void tls_log_sslerr( void ); #endif /* PPP_TLS_H */ ppp-2.5.0/pppd/tdb.h0000664000175000017500000001261414273050614011133 00000000000000#ifndef PPP_TDB_H #define PPP_TDB_H #include "pppdconf.h" /* Unix SMB/CIFS implementation. trivial database library Copyright (C) Andrew Tridgell 1999-2004 ** NOTE! The following LGPL license applies to the tdb ** library. This does NOT imply that all of Samba is released ** under the LGPL This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifdef __cplusplus extern "C" { #endif #ifndef PRINTF_ATTRIBUTE /** Use gcc attribute to check printf fns. a1 is the 1-based index of * the parameter containing the format, and a2 the index of the first * argument. Note that some gcc 2.x versions don't handle this * properly **/ #if (__GNUC__ >= 3) #define PRINTF_ATTRIBUTE(a1, a2) __attribute__ ((format (__printf__, a1, a2))) #else #define PRINTF_ATTRIBUTE(a1, a2) #endif #endif /* flags to tdb_store() */ #define TDB_REPLACE 1 #define TDB_INSERT 2 #define TDB_MODIFY 3 /* flags for tdb_open() */ #define TDB_DEFAULT 0 /* just a readability place holder */ #define TDB_CLEAR_IF_FIRST 1 #define TDB_INTERNAL 2 /* don't store on disk */ #define TDB_NOLOCK 4 /* don't do any locking */ #define TDB_NOMMAP 8 /* don't use mmap */ #define TDB_CONVERT 16 /* convert endian (internal use) */ #define TDB_BIGENDIAN 32 /* header is big-endian (internal use) */ #define TDB_ERRCODE(code, ret) ((tdb->ecode = (code)), ret) /* error codes */ enum TDB_ERROR {TDB_SUCCESS=0, TDB_ERR_CORRUPT, TDB_ERR_IO, TDB_ERR_LOCK, TDB_ERR_OOM, TDB_ERR_EXISTS, TDB_ERR_NOLOCK, TDB_ERR_LOCK_TIMEOUT, TDB_ERR_NOEXIST}; #ifndef u32 #define u32 unsigned #endif typedef struct { char *dptr; size_t dsize; } TDB_DATA; typedef u32 tdb_len; typedef u32 tdb_off; /* this is stored at the front of every database */ struct tdb_header { char magic_food[32]; /* for /etc/magic */ u32 version; /* version of the code */ u32 hash_size; /* number of hash entries */ tdb_off rwlocks; tdb_off reserved[31]; }; struct tdb_lock_type { u32 count; u32 ltype; }; struct tdb_traverse_lock { struct tdb_traverse_lock *next; u32 off; u32 hash; }; /* this is the context structure that is returned from a db open */ typedef struct tdb_context { char *name; /* the name of the database */ void *map_ptr; /* where it is currently mapped */ int fd; /* open file descriptor for the database */ tdb_len map_size; /* how much space has been mapped */ int read_only; /* opened read-only */ struct tdb_lock_type *locked; /* array of chain locks */ enum TDB_ERROR ecode; /* error code for last tdb error */ struct tdb_header header; /* a cached copy of the header */ u32 flags; /* the flags passed to tdb_open */ struct tdb_traverse_lock travlocks; /* current traversal locks */ struct tdb_context *next; /* all tdbs to avoid multiple opens */ dev_t device; /* uniquely identifies this tdb */ ino_t inode; /* uniquely identifies this tdb */ void (*log_fn)(struct tdb_context *tdb, int level, const char *, ...) PRINTF_ATTRIBUTE(3,4); /* logging function */ u32 (*hash_fn)(TDB_DATA *key); int open_flags; /* flags used in the open - needed by reopen */ } TDB_CONTEXT; typedef int (*tdb_traverse_func)(TDB_CONTEXT *, TDB_DATA, TDB_DATA, void *); typedef void (*tdb_log_func)(TDB_CONTEXT *, int , const char *, ...); typedef u32 (*tdb_hash_func)(TDB_DATA *key); TDB_CONTEXT *tdb_open(const char *name, int hash_size, int tdb_flags, int open_flags, mode_t mode); TDB_CONTEXT *tdb_open_ex(const char *name, int hash_size, int tdb_flags, int open_flags, mode_t mode, tdb_log_func log_fn, tdb_hash_func hash_fn); int tdb_reopen(TDB_CONTEXT *tdb); int tdb_reopen_all(void); void tdb_logging_function(TDB_CONTEXT *tdb, tdb_log_func); enum TDB_ERROR tdb_error(TDB_CONTEXT *tdb); const char *tdb_errorstr(TDB_CONTEXT *tdb); TDB_DATA tdb_fetch(TDB_CONTEXT *tdb, TDB_DATA key); int tdb_delete(TDB_CONTEXT *tdb, TDB_DATA key); int tdb_store(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, int flag); int tdb_append(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA new_dbuf); int tdb_close(TDB_CONTEXT *tdb); TDB_DATA tdb_firstkey(TDB_CONTEXT *tdb); TDB_DATA tdb_nextkey(TDB_CONTEXT *tdb, TDB_DATA key); int tdb_traverse(TDB_CONTEXT *tdb, tdb_traverse_func fn, void *); int tdb_exists(TDB_CONTEXT *tdb, TDB_DATA key); int tdb_lockkeys(TDB_CONTEXT *tdb, u32 number, TDB_DATA keys[]); void tdb_unlockkeys(TDB_CONTEXT *tdb); int tdb_lockall(TDB_CONTEXT *tdb); void tdb_unlockall(TDB_CONTEXT *tdb); /* Low level locking functions: use with care */ void tdb_set_lock_alarm(sig_atomic_t *palarm); int tdb_chainlock(TDB_CONTEXT *tdb, TDB_DATA key); int tdb_chainunlock(TDB_CONTEXT *tdb, TDB_DATA key); /* Debug functions. Not used in production. */ void tdb_dump_all(TDB_CONTEXT *tdb); int tdb_printfreelist(TDB_CONTEXT *tdb); extern TDB_DATA tdb_null; #ifdef __cplusplus } #endif #endif /* PPP_TBD_H */ ppp-2.5.0/pppd/termios_linux.h0000664000175000017500000000740114273050614013261 00000000000000/* SPDX-License-Identifier: GPL-2.0+ OR BSD-4-Clause OR BSD-3-Clause OR BSD-2-Clause */ /* * termios fuctions to support arbitrary baudrates (on Linux) * * Copyright (c) 2021 Pali Rohár * Copyright (c) 2021 Marek Behún */ #ifndef PPP_TERMIOS_LINUX_H #define PPP_TERMIOS_LINUX_H #include "pppdconf.h" /* * We need to use raw TCGETS2/TCSETS2 or TCGETS/TCSETS ioctls with the BOTHER * flag in struct termios2/termios, defined in Linux headers * and . Since these headers conflict with glibc's header file * , it is not possible to use libc's termios functions and we need * to reimplement them via ioctl() calls. * * An arbitrary baudrate is supported when the macro BOTHER is defined. The * baudrate value itself is then stored into the c_ospeed and c_ispeed members. * If ioctls TCGETS2/TCSETS2 are defined and supported then these fields are * present in struct termios2, otherwise these fields are present in struct * termios. * * Note that the Bnnn constants from need not be compatible with * Bnnn constants from . */ #include #include #include #include #include #if defined(BOTHER) && defined(TCGETS2) #define termios termios2 #endif static inline int tcgetattr(int fd, struct termios *t) { #if defined(BOTHER) && defined(TCGETS2) return ioctl(fd, TCGETS2, t); #else return ioctl(fd, TCGETS, t); #endif } static inline int tcsetattr(int fd, int a, const struct termios *t) { int cmd; switch (a) { #if defined(BOTHER) && defined(TCGETS2) case TCSANOW: cmd = TCSETS2; break; case TCSADRAIN: cmd = TCSETSW2; break; case TCSAFLUSH: cmd = TCSETSF2; break; #else case TCSANOW: cmd = TCSETS; break; case TCSADRAIN: cmd = TCSETSW; break; case TCSAFLUSH: cmd = TCSETSF; break; #endif default: errno = EINVAL; return -1; } return ioctl(fd, cmd, t); } static inline int tcdrain(int fd) { return ioctl(fd, TCSBRK, 1); } static inline int tcflush(int fd, int q) { return ioctl(fd, TCFLSH, q); } static inline int tcsendbreak(int fd, int d) { #ifdef TCSBRKP return ioctl(fd, TCSBRKP, d); #else return ioctl(fd, TCSBRK, 0); #endif } static inline int tcflow(int fd, int a) { return ioctl(fd, TCXONC, a); } static inline pid_t tcgetsid(int fd) { pid_t sid; if (ioctl(fd, TIOCGSID, &sid) < 0) return (pid_t)-1; return sid; } static inline speed_t cfgetospeed(const struct termios *t) { return t->c_cflag & CBAUD; } static inline int cfsetospeed(struct termios *t, speed_t s) { if (s & ~CBAUD) { errno = EINVAL; return -1; } t->c_cflag &= ~CBAUD; t->c_cflag |= s; return 0; } #ifdef IBSHIFT static inline speed_t cfgetispeed(const struct termios *t) { speed_t s = (t->c_cflag >> IBSHIFT) & CBAUD; if (s == B0) return cfgetospeed(t); else return s; } static inline int cfsetispeed(struct termios *t, speed_t s) { if (s == 0) s = B0; if (s & ~CBAUD) { errno = EINVAL; return -1; } t->c_cflag &= ~(CBAUD << IBSHIFT); t->c_cflag |= s << IBSHIFT; return 0; } #else /* !IBSHIFT */ static inline speed_t cfgetispeed(const struct termios *t) { return cfgetospeed(t); } static inline int cfsetispeed(struct termios *t, speed_t s) { return cfsetospeed(t, s); } #endif /* !IBSHIFT */ static inline int cfsetspeed(struct termios *t, speed_t s) { if (cfsetospeed(t, s)) return -1; #ifdef IBSHIFT if (cfsetispeed(t, s)) return -1; #endif return 0; } static void cfmakeraw(struct termios *t) { t->c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON); t->c_oflag &= ~OPOST; t->c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN); t->c_cflag &= ~(CSIZE | PARENB); t->c_cflag |= CS8; } #endif /* PPP_TERMIOS_LINUX_H */ ppp-2.5.0/pppd/cbcp.h0000644000175000017500000000403114407475306011271 00000000000000/* * Copyright (c) 1995 Pedro Roque Marques. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The names of the authors of this software must not be used to * endorse or promote products derived from this software without * prior written permission. * * 4. Redistributions of any form whatsoever must retain the following * acknowledgment: * "This product includes software developed by Pedro Roque Marques * " * * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #ifndef PPP_CBCP_H #define PPP_CBCP_H #include "pppdconf.h" #ifdef __cplusplus extern "C" { #endif typedef struct cbcp_state { int us_unit; /* Interface unit number */ u_char us_id; /* Current id */ u_char us_allowed; int us_type; char *us_number; /* Telefone Number */ } cbcp_state; extern cbcp_state cbcp[]; extern struct protent cbcp_protent; #define CBCP_MINLEN 4 #define CBCP_REQ 1 #define CBCP_RESP 2 #define CBCP_ACK 3 #define CB_CONF_NO 1 #define CB_CONF_USER 2 #define CB_CONF_ADMIN 3 #define CB_CONF_LIST 4 #ifdef __cplusplus } #endif #endif // PPP_CBCP_H ppp-2.5.0/pppd/ccp.h0000644000175000017500000000434314407475306011135 00000000000000/* * ccp.h - Definitions for PPP Compression Control Protocol. * * Copyright (c) 1994-2002 Paul Mackerras. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. The name(s) of the authors of this software must not be used to * endorse or promote products derived from this software without * prior written permission. * * 3. Redistributions of any form whatsoever must retain the following * acknowledgment: * "This product includes software developed by Paul Mackerras * ". * * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * $Id: ccp.h,v 1.12 2004/11/04 10:02:26 paulus Exp $ */ #ifndef PPP_CCP_H #define PPP_CCP_H #include "pppdconf.h" #ifdef __cplusplus extern "C" { #endif typedef struct ccp_options { bool bsd_compress; /* do BSD Compress? */ bool deflate; /* do Deflate? */ bool predictor_1; /* do Predictor-1? */ bool predictor_2; /* do Predictor-2? */ bool deflate_correct; /* use correct code for deflate? */ bool deflate_draft; /* use draft RFC code for deflate? */ unsigned char mppe; /* MPPE bitfield */ unsigned short bsd_bits; /* # bits/code for BSD Compress */ unsigned short deflate_size; /* lg(window size) for Deflate */ short method; /* code for chosen compression method */ } ccp_options; extern fsm ccp_fsm[]; extern ccp_options ccp_wantoptions[]; extern ccp_options ccp_gotoptions[]; extern ccp_options ccp_allowoptions[]; extern ccp_options ccp_hisoptions[]; extern struct protent ccp_protent; #ifdef __cplusplus } #endif #endif // PPP_CCP_H ppp-2.5.0/pppd/chap.h0000644000175000017500000001276314407475306011310 00000000000000/* * chap-new.c - New CHAP implementation. * * Copyright (c) 2003 Paul Mackerras. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. The name(s) of the authors of this software must not be used to * endorse or promote products derived from this software without * prior written permission. * * 3. Redistributions of any form whatsoever must retain the following * acknowledgment: * "This product includes software developed by Paul Mackerras * ". * * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #ifndef PPP_CHAP_NEW_H #define PPP_CHAP_NEW_H #include "pppdconf.h" #ifdef __cplusplus extern "C" { #endif /* * CHAP packets begin with a standard header with code, id, len (2 bytes). */ #define CHAP_HDRLEN 4 /* * Values for the code field. */ #define CHAP_CHALLENGE 1 #define CHAP_RESPONSE 2 #define CHAP_SUCCESS 3 #define CHAP_FAILURE 4 /* * CHAP digest codes. */ #define CHAP_MD5 5 #define CHAP_MICROSOFT 0x80 #define CHAP_MICROSOFT_V2 0x81 /* * Semi-arbitrary limits on challenge and response fields. */ #define MAX_CHALLENGE_LEN 64 #define MAX_RESPONSE_LEN 64 /* bitmask of supported algorithms */ #define MDTYPE_MICROSOFT_V2 0x1 #define MDTYPE_MICROSOFT 0x2 #define MDTYPE_MD5 0x4 #define MDTYPE_NONE 0 /* hashes supported by this instance of pppd */ extern int chap_mdtype_all; /* Return the digest alg. ID for the most preferred digest type. */ #define CHAP_DIGEST(mdtype) \ ((mdtype) & MDTYPE_MD5)? CHAP_MD5: \ ((mdtype) & MDTYPE_MICROSOFT_V2)? CHAP_MICROSOFT_V2: \ ((mdtype) & MDTYPE_MICROSOFT)? CHAP_MICROSOFT: \ 0 /* Return the bit flag (lsb set) for our most preferred digest type. */ #define CHAP_MDTYPE(mdtype) ((mdtype) ^ ((mdtype) - 1)) & (mdtype) /* Return the bit flag for a given digest algorithm ID. */ #define CHAP_MDTYPE_D(digest) \ ((digest) == CHAP_MICROSOFT_V2)? MDTYPE_MICROSOFT_V2: \ ((digest) == CHAP_MICROSOFT)? MDTYPE_MICROSOFT: \ ((digest) == CHAP_MD5)? MDTYPE_MD5: \ 0 /* Can we do the requested digest? */ #define CHAP_CANDIGEST(mdtype, digest) \ ((digest) == CHAP_MICROSOFT_V2)? (mdtype) & MDTYPE_MICROSOFT_V2: \ ((digest) == CHAP_MICROSOFT)? (mdtype) & MDTYPE_MICROSOFT: \ ((digest) == CHAP_MD5)? (mdtype) & MDTYPE_MD5: \ 0 /* * The code for each digest type has to supply one of these. */ struct chap_digest_type { int code; /* * Note: challenge and response arguments below are formatted as * a length byte followed by the actual challenge/response data. */ void (*generate_challenge)(unsigned char *challenge); int (*verify_response)(int id, char *name, unsigned char *secret, int secret_len, unsigned char *challenge, unsigned char *response, char *message, int message_space); void (*make_response)(unsigned char *response, int id, char *our_name, unsigned char *challenge, char *secret, int secret_len, unsigned char *priv); int (*check_success)(int id, unsigned char *pkt, int len); void (*handle_failure)(unsigned char *pkt, int len); struct chap_digest_type *next; }; /* * This function will return a value of 1 to indicate that a plugin intend to supply * a username or a password to pppd through the chap_passwd_hook callback. * * Return a value > 0 to avoid parsing the chap-secrets file. */ typedef int (chap_check_hook_fn)(void); extern chap_check_hook_fn *chap_check_hook; /* * A plugin can chose to supply its own user and password overriding whatever * has been provided by the configuration. Hook is only valid when pppd is * acting as a client. * * The maximum size of the user argument is always MAXNAMELEN * The length of the password is always MAXWORDLEN, however; secrets can't be * longer than MAXSECRETLEN * * Return a value < 0 to fail the connection. */ typedef int (chap_passwd_hook_fn)(char *user, char *password); extern chap_passwd_hook_fn *chap_passwd_hook; /* * A plugin can chose to replace the default chap_verify_response function with * one of their own. */ typedef int (chap_verify_hook_fn)(char *name, char *ourname, int id, struct chap_digest_type *digest, unsigned char *challenge, unsigned char *response, char *message, int message_space); extern chap_verify_hook_fn *chap_verify_hook; /* Called by digest code to register a digest type */ extern void chap_register_digest(struct chap_digest_type *); /* Lookup a digest handler by type */ extern struct chap_digest_type *chap_find_digest(int digest_code); /* Called by authentication code to start authenticating the peer. */ extern void chap_auth_peer(int unit, char *our_name, int digest_code); /* Called by auth. code to start authenticating us to the peer. */ extern void chap_auth_with_peer(int unit, char *our_name, int digest_code); /* Represents the CHAP protocol to the main pppd code */ extern struct protent chap_protent; #ifdef __cplusplus } #endif #endif // PPP_CHAP_NEW_H ppp-2.5.0/pppd/chap_ms.h0000644000175000017500000000703514407475306012003 00000000000000/* * chap_ms.h - Challenge Handshake Authentication Protocol definitions. * * Copyright (c) 1995 Eric Rosenquist. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The name(s) of the authors of this software must not be used to * endorse or promote products derived from this software without * prior written permission. * * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * $Id: chap_ms.h,v 1.13 2004/11/15 22:13:26 paulus Exp $ */ #ifndef PPP_CHAPMS_H #define PPP_CHAPMS_H #include "pppdconf.h" #ifdef __cplusplus extern "C" { #endif #define MAX_NT_PASSWORD 256 /* Max (Unicode) chars in an NT pass */ #define MS_CHAP_RESPONSE_LEN 49 /* Response length for MS-CHAP */ #define MS_CHAP2_RESPONSE_LEN 49 /* Response length for MS-CHAPv2 */ #define MS_AUTH_RESPONSE_LENGTH 40 /* MS-CHAPv2 authenticator response, */ #define MS_AUTH_NTRESP_LEN 24 /* Length of NT-response field */ /* as ASCII */ /* E=eeeeeeeeee error codes for MS-CHAP failure messages. */ #define MS_CHAP_ERROR_RESTRICTED_LOGON_HOURS 646 #define MS_CHAP_ERROR_ACCT_DISABLED 647 #define MS_CHAP_ERROR_PASSWD_EXPIRED 648 #define MS_CHAP_ERROR_NO_DIALIN_PERMISSION 649 #define MS_CHAP_ERROR_AUTHENTICATION_FAILURE 691 #define MS_CHAP_ERROR_CHANGING_PASSWORD 709 /* * Offsets within the response field for MS-CHAP */ #define MS_CHAP_LANMANRESP 0 #define MS_CHAP_LANMANRESP_LEN 24 #define MS_CHAP_NTRESP 24 #define MS_CHAP_NTRESP_LEN 24 #define MS_CHAP_USENT 48 /* * Offsets within the response field for MS-CHAP2 */ #define MS_CHAP2_PEER_CHALLENGE 0 #define MS_CHAP2_PEER_CHAL_LEN 16 #define MS_CHAP2_RESERVED_LEN 8 #define MS_CHAP2_NTRESP 24 #define MS_CHAP2_NTRESP_LEN 24 #define MS_CHAP2_FLAGS 48 /* Are we the authenticator or authenticatee? For MS-CHAPv2 key derivation. */ #define MS_CHAP2_AUTHENTICATEE 0 #define MS_CHAP2_AUTHENTICATOR 1 void ChapMS (u_char *, char *, int, u_char *); void ChapMS2 (u_char *, u_char *, char *, char *, int, u_char *, u_char[MS_AUTH_RESPONSE_LENGTH+1], int); void ChallengeHash (u_char[16], u_char *, char *, u_char[8]); /** * PasswordHashHash - 16 bytes representing the NT Password Hash Hash * NTResponse - 24 bytes represending the NTResponse parameter * PeerChallenge - 16 bytes challange for peer * rchallenge - 16 bytes challenge provided by peer * authResponse - 24 + 1 byte to store the authenticator response */ void GenerateAuthenticatorResponse(unsigned char *PasswordHashHash, unsigned char *NTResponse, unsigned char *PeerChallenge, unsigned char *rchallenge, char *username, unsigned char *authResponse); void chapms_init(void); #ifdef __cplusplus } #endif #endif /* PPP_CHAPMS_H */ ppp-2.5.0/pppd/crypto.h0000644000175000017500000000721214407475306011706 00000000000000/* ppp-crypto.h - Generic API for access to crypto/digest functions. * * Copyright (c) 2022 Eivind Næss. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The name(s) of the authors of this software must not be used to * endorse or promote products derived from this software without * prior written permission. * * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #ifndef PPP_CRYPTO_H #define PPP_CRYPTO_H #ifdef __cplusplus extern "C" { #endif #ifndef MD5_DIGEST_LENGTH #define MD5_DIGEST_LENGTH 16 #endif #ifndef MD4_DIGEST_LENGTH #define MD4_DIGEST_LENGTH 16 #endif #ifndef SHA_DIGEST_LENGTH #define SHA_DIGEST_LENGTH 20 #endif struct _PPP_MD_CTX; struct _PPP_MD; typedef struct _PPP_MD_CTX PPP_MD_CTX; typedef struct _PPP_MD PPP_MD; /* * Create a new Message Digest context object */ PPP_MD_CTX *PPP_MD_CTX_new(); /* * Free the Message Digest context */ void PPP_MD_CTX_free(PPP_MD_CTX*); /* * Fetch the MD4 algorithm */ const PPP_MD *PPP_md4(void); /* * Fetch the MD5 algorithm */ const PPP_MD *PPP_md5(void); /* * Fetch the SHA1 algorithm */ const PPP_MD *PPP_sha1(void); /* * Initializes a context object */ int PPP_DigestInit(PPP_MD_CTX *ctx, const PPP_MD *type); /* * For each iteration update the context with more input */ int PPP_DigestUpdate(PPP_MD_CTX *ctx, const void *data, size_t cnt); /* * Perform the final operation, and output the digest */ int PPP_DigestFinal(PPP_MD_CTX *ctx, unsigned char *out, unsigned int *outlen); struct _PPP_CIPHER_CTX; struct _PPP_CIPHER; typedef struct _PPP_CIPHER_CTX PPP_CIPHER_CTX; typedef struct _PPP_CIPHER PPP_CIPHER; /* * Create a new Cipher Context */ PPP_CIPHER_CTX *PPP_CIPHER_CTX_new(void); /* * Release the Cipher Context */ void PPP_CIPHER_CTX_free(PPP_CIPHER_CTX *ctx); /* * Fetch the DES in ECB mode cipher algorithm */ const PPP_CIPHER *PPP_des_ecb(void); /* * Set the particular data directly */ void PPP_CIPHER_CTX_set_cipher_data(PPP_CIPHER_CTX *ctx, const unsigned char *key); /* * Initialize the crypto operation */ int PPP_CipherInit(PPP_CIPHER_CTX *ctx, const PPP_CIPHER *cipher, const unsigned char *key, const unsigned char *iv, int encr); /* * Encrypt input data, and store it in the output buffer */ int PPP_CipherUpdate(PPP_CIPHER_CTX *ctx, unsigned char *out, int *outl, const unsigned char *in, int inl); /* * Finish the crypto operation, and fetch any outstanding bytes */ int PPP_CipherFinal(PPP_CIPHER_CTX *ctx, unsigned char *out, int *outl); /* * Global initialization, must be called once per process */ int PPP_crypto_init(); /* * Global deinitialization */ int PPP_crypto_deinit(); #ifdef __cplusplus } #endif #endif // PPP_CRYPTO_H ppp-2.5.0/pppd/crypto_ms.h0000644000175000017500000000512214407475306012403 00000000000000/* * pppcrypt.c - PPP/DES linkage for MS-CHAP and EAP SRP-SHA1 * * Extracted from chap_ms.c by James Carlson. * Updated to better reflect RFC2759 by Eivind Naess * * Copyright (c) 2022 Eivind Naess. All rights reserved. * Copyright (c) 1995 Eric Rosenquist. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The name(s) of the authors of this software must not be used to * endorse or promote products derived from this software without * prior written permission. * * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #ifndef PPP_PPPCRYPT_H #define PPP_PPPCRYPT_H #include "pppdconf.h" #ifdef __cplusplus extern "C" { #endif /** * This is the DES encrypt functions as described by RFC2759. * * Parameters: * const unsigned char *clear: * A 8 byte input array to be encrypted * * const unsigned char *key: * A raw 7-byte array to be expanded to 8 with odd-parity * * unsigned char *cipher: * A 8 byte outut array providing space for the output data * * DesEncrypt returns 1 on success */ int DesEncrypt(const unsigned char *clear, const unsigned char *key, unsigned char *cipher); /** * This is the DES decrypt functions as described by RFC2759. * * Parameters: * const unsigned char *cipher: * A 8 byte input array to be decrypted * * const unsigned char *key: * A raw 7-byte array to be expanded to a 8-byte key with odd-parity * * unsigned char *clear: * A 8 byte output array providing space for the output data * * DesDecrypt returns 1 on success */ int DesDecrypt(const unsigned char *cipher, const unsigned char *key, unsigned char *clear); #ifdef __cplusplus } #endif #endif /* PPP_PPPCRYPT_H */ ppp-2.5.0/pppd/eap.h0000644000175000017500000001627714353435407011144 00000000000000/* * eap.h - Extensible Authentication Protocol for PPP (RFC 2284) * * Copyright (c) 2001 by Sun Microsystems, Inc. * All rights reserved. * * Non-exclusive rights to redistribute, modify, translate, and use * this software in source and binary forms, in whole or in part, is * hereby granted, provided that the above copyright notice is * duplicated in any source form, and that neither the name of the * copyright holder nor the author is used to endorse or promote * products derived from this software. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * * Original version by James Carlson * * $Id: eap.h,v 1.2 2003/06/11 23:56:26 paulus Exp $ */ #ifndef PPP_EAP_H #define PPP_EAP_H #include "pppdconf.h" #ifdef __cplusplus extern "C" { #endif #ifndef PPP_EAP #define PPP_EAP 0xc227 #endif /* * Packet header = Code, id, length. */ #define EAP_HEADERLEN 4 /* EAP message codes. */ #define EAP_REQUEST 1 #define EAP_RESPONSE 2 #define EAP_SUCCESS 3 #define EAP_FAILURE 4 /* EAP types */ #define EAPT_IDENTITY 1 #define EAPT_NOTIFICATION 2 #define EAPT_NAK 3 /* (response only) */ #define EAPT_MD5CHAP 4 #define EAPT_OTP 5 /* One-Time Password; RFC 1938 */ #define EAPT_TOKEN 6 /* Generic Token Card */ /* 7 and 8 are unassigned. */ #define EAPT_RSA 9 /* RSA Public Key Authentication */ #define EAPT_DSS 10 /* DSS Unilateral */ #define EAPT_KEA 11 /* KEA */ #define EAPT_KEA_VALIDATE 12 /* KEA-VALIDATE */ #define EAPT_TLS 13 /* EAP-TLS */ #define EAPT_DEFENDER 14 /* Defender Token (AXENT) */ #define EAPT_W2K 15 /* Windows 2000 EAP */ #define EAPT_ARCOT 16 /* Arcot Systems */ #define EAPT_CISCOWIRELESS 17 /* Cisco Wireless */ #define EAPT_NOKIACARD 18 /* Nokia IP smart card */ #define EAPT_SRP 19 /* Secure Remote Password */ /* 20 is deprecated */ #define EAPT_TTLS 21 /* EAP Tunneled TLS Authentication Protocol RFC5281 */ #define EAPT_RAS 22 /* Remote Access Service */ #define EAPT_AKA 23 /* EAP method for 3rd Generation Authentication and Key Agreement RFC4187 */ #define EAPT_3COM 24 /* EAP-3Com Wireless */ #define EAPT_PEAP 25 /* Protected EAP */ #define EAPT_MSCHAPV2 26 /* EAP-MSCHAPv2 RFC-draft-kamath-pppext-eap-mschapv2-02 */ /* OpCodes for MSCHAPv2 */ #define CHAP_CHALLENGE 1 #define CHAP_RESPONSE 2 #define CHAP_SUCCESS 3 #define CHAP_FAILURE 4 /* EAP SRP-SHA1 Subtypes */ #define EAPSRP_CHALLENGE 1 /* Request 1 - Challenge */ #define EAPSRP_CKEY 1 /* Response 1 - Client Key */ #define EAPSRP_SKEY 2 /* Request 2 - Server Key */ #define EAPSRP_CVALIDATOR 2 /* Response 2 - Client Validator */ #define EAPSRP_SVALIDATOR 3 /* Request 3 - Server Validator */ #define EAPSRP_ACK 3 /* Response 3 - final ack */ #define EAPSRP_LWRECHALLENGE 4 /* Req/resp 4 - Lightweight rechal */ #define SRPVAL_EBIT 0x00000001 /* Use shared key for ECP */ #define SRP_PSEUDO_ID "pseudo_" #define SRP_PSEUDO_LEN 7 #define MIN_CHALLENGE_LENGTH 16 #define MAX_CHALLENGE_LENGTH 24 enum eap_state_code { eapInitial = 0, /* No EAP authentication yet requested */ eapPending, /* Waiting for LCP (no timer) */ eapClosed, /* Authentication not in use */ eapListen, /* Client ready (and timer running) */ eapIdentify, /* EAP Identify sent */ eapTlsStart, /* Send EAP-TLS start packet */ eapTlsRecv, /* Receive EAP-TLS tls data */ eapTlsSendAck, /* Send EAP-TLS ack */ eapTlsSend, /* Send EAP-TLS tls data */ eapTlsRecvAck, /* Receive EAP-TLS ack */ eapTlsRecvClient, /* Receive EAP-TLS auth response from client*/ eapTlsSendAlert, /* Send EAP-TLS tls alert (server)*/ eapTlsRecvAlertAck, /* Receive EAP-TLS ack after sending alert */ eapTlsRecvSuccess, /* Receive EAP success */ eapTlsRecvFailure, /* Receive EAP failure */ eapSRP1, /* Sent EAP SRP-SHA1 Subtype 1 */ eapSRP2, /* Sent EAP SRP-SHA1 Subtype 2 */ eapSRP3, /* Sent EAP SRP-SHA1 Subtype 3 */ eapMD5Chall, /* Sent MD5-Challenge */ eapMSCHAPv2Chall, /* Sent MSCHAPv2-Challenge */ eapOpen, /* Completed authentication */ eapSRP4, /* Sent EAP SRP-SHA1 Subtype 4 */ eapBadAuth /* Failed authentication */ }; #define EAP_STATES \ "Initial", "Pending", "Closed", "Listen", "Identify", \ "TlsStart", "TlsRecv", "TlsSendAck", "TlsSend", "TlsRecvAck", "TlsRecvClient",\ "TlsSendAlert", "TlsRecvAlertAck" , "TlsRecvSuccess", "TlsRecvFailure", \ "SRP1", "SRP2", "SRP3", "MD5Chall", "MSCHAPv2Chall", "Open", "SRP4", "BadAuth" #ifdef PPP_WITH_EAPTLS #define eap_client_active(esp) ((esp)->es_client.ea_state != eapInitial &&\ (esp)->es_client.ea_state != eapPending &&\ (esp)->es_client.ea_state != eapClosed) #else #define eap_client_active(esp) ((esp)->es_client.ea_state == eapListen) #endif /* PPP_WITH_EAPTLS */ #define eap_server_active(esp) \ ((esp)->es_server.ea_state >= eapIdentify && \ (esp)->es_server.ea_state <= eapMD5Chall) struct eap_auth { char *ea_name; /* Our name */ char *ea_peer; /* Peer's name */ void *ea_session; /* Authentication library linkage */ unsigned char *ea_skey; /* Shared encryption key */ int ea_timeout; /* Time to wait (for retransmit/fail) */ int ea_maxrequests; /* Max Requests allowed */ unsigned short ea_namelen; /* Length of our name */ unsigned short ea_peerlen; /* Length of peer's name */ enum eap_state_code ea_state; #ifdef PPP_WITH_EAPTLS enum eap_state_code ea_prev_state; #endif #ifdef PPP_WITH_CHAPMS struct chap_digest_type *digest; #endif unsigned char ea_id; /* Current id */ unsigned char ea_requests; /* Number of Requests sent/received */ unsigned char ea_responses; /* Number of Responses */ unsigned char ea_type; /* One of EAPT_* */ uint32_t ea_keyflags; /* SRP shared key usage flags */ #ifdef PPP_WITH_EAPTLS bool ea_using_eaptls; #endif }; /* * Complete EAP state for one PPP session. */ typedef struct eap_state { int es_unit; /* Interface unit number */ struct eap_auth es_client; /* Client (authenticatee) data */ struct eap_auth es_server; /* Server (authenticator) data */ #ifdef PPP_WITH_PEAP struct peap_state *ea_peap; /* Client PEAP (authenticator) data */ #endif int es_savedtime; /* Saved timeout */ int es_rechallenge; /* EAP rechallenge interval */ int es_lwrechallenge; /* SRP lightweight rechallenge inter */ bool es_usepseudo; /* Use SRP Pseudonym if offered one */ int es_usedpseudo; /* Set if we already sent PN */ int es_challen; /* Length of challenge string */ unsigned char es_challenge[MAX_CHALLENGE_LENGTH]; } eap_state; /* * Timeouts. */ #define EAP_DEFTIMEOUT 3 /* Timeout (seconds) for rexmit */ #ifdef PPP_WITH_EAPTLS #define EAP_DEFTRANSMITS 30 /* max # times to transmit */ /* certificates can be long ... */ #else #define EAP_DEFTRANSMITS 10 /* max # times to transmit */ #endif /* PPP_WITH_EAPTLS */ #define EAP_DEFREQTIME 20 /* Time to wait for peer request */ #define EAP_DEFALLOWREQ 20 /* max # times to accept requests */ extern eap_state eap_states[]; void eap_authwithpeer (int unit, char *localname); void eap_authpeer (int unit, char *localname); extern struct protent eap_protent; #ifdef PPP_WITH_EAPTLS typedef int (eaptls_passwd_hook_fn)(char *user, char *passwd); extern eaptls_passwd_hook_fn *eaptls_passwd_hook; #endif #ifdef __cplusplus } #endif #endif /* PPP_EAP_H */ ppp-2.5.0/pppd/ecp.h0000644000175000017500000000356414407475306011143 00000000000000/* * ecp.h - Definitions for PPP Encryption Control Protocol. * * Copyright (c) 2002 Google, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The name(s) of the authors of this software must not be used to * endorse or promote products derived from this software without * prior written permission. * * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * $Id: ecp.h,v 1.2 2003/01/10 07:12:36 fcusack Exp $ */ #ifndef PPP_ECP_H #define PPP_ECP_H #include "pppdconf.h" #ifdef __cplusplus extern "C" { #endif #ifndef PPP_ECP #define PPP_ECP 0x8053 #endif typedef struct ecp_options { bool required; /* Is ECP required? */ unsigned enctype; /* Encryption type */ } ecp_options; extern fsm ecp_fsm[]; extern ecp_options ecp_wantoptions[]; extern ecp_options ecp_gotoptions[]; extern ecp_options ecp_allowoptions[]; extern ecp_options ecp_hisoptions[]; extern struct protent ecp_protent; #ifdef __cplusplus } #endif #endif // PPP_ECP_H ppp-2.5.0/pppd/eui64.h0000644000175000017500000000637714407475306011335 00000000000000/* * eui64.h - EUI64 routines for IPv6CP. * * Copyright (c) 1999 Tommi Komulainen. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The name(s) of the authors of this software must not be used to * endorse or promote products derived from this software without * prior written permission. * * 4. Redistributions of any form whatsoever must retain the following * acknowledgment: * "This product includes software developed by Tommi Komulainen * ". * * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * */ #ifndef PPP_EUI64_H #define PPP_EUI64_H #include "pppdconf.h" #ifdef __cplusplus extern "C" { #endif #if defined(SOL2) #include typedef union { uint8_t e8[8]; /* lower 64-bit IPv6 address */ uint32_t e32[2]; /* lower 64-bit IPv6 address */ } eui64_t; /* * Declare the two below, since in.h only defines them when _KERNEL * is declared - which shouldn't be true when dealing with user-land programs */ #define s6_addr8 _S6_un._S6_u8 #define s6_addr32 _S6_un._S6_u32 #else /* else if not defined(SOL2) */ /* * TODO: * * Maybe this should be done by processing struct in6_addr directly... */ typedef union { u_int8_t e8[8]; u_int16_t e16[4]; u_int32_t e32[2]; } eui64_t; #endif /* defined(SOL2) */ #define eui64_iszero(e) (((e).e32[0] | (e).e32[1]) == 0) #define eui64_equals(e, o) (((e).e32[0] == (o).e32[0]) && \ ((e).e32[1] == (o).e32[1])) #define eui64_zero(e) (e).e32[0] = (e).e32[1] = 0; #define eui64_copy(s, d) memcpy(&(d), &(s), sizeof(eui64_t)) #define eui64_magic(e) do { \ (e).e32[0] = magic(); \ (e).e32[1] = magic(); \ (e).e8[0] &= ~2; \ } while (0) #define eui64_magic_nz(x) do { \ eui64_magic(x); \ } while (eui64_iszero(x)) #define eui64_magic_ne(x, y) do { \ eui64_magic(x); \ } while (eui64_equals(x, y)) #define eui64_get(ll, cp) do { \ eui64_copy((*cp), (ll)); \ (cp) += sizeof(eui64_t); \ } while (0) #define eui64_put(ll, cp) do { \ eui64_copy((ll), (*cp)); \ (cp) += sizeof(eui64_t); \ } while (0) #define eui64_set32(e, l) do { \ (e).e32[0] = 0; \ (e).e32[1] = htonl(l); \ } while (0) #define eui64_setlo32(e, l) eui64_set32(e, l) char *eui64_ntoa(eui64_t); /* Returns ascii representation of id */ #ifdef __cplusplus } #endif #endif /* PPP_EUI64_H */ ppp-2.5.0/pppd/fsm.h0000644000175000017500000001411414407475306011152 00000000000000/* * fsm.h - {Link, IP} Control Protocol Finite State Machine definitions. * * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The name "Carnegie Mellon University" must not be used to * endorse or promote products derived from this software without * prior written permission. For permission or any legal * details, please contact * Office of Technology Transfer * Carnegie Mellon University * 5000 Forbes Avenue * Pittsburgh, PA 15213-3890 * (412) 268-4387, fax: (412) 268-7395 * tech-transfer@andrew.cmu.edu * * 4. Redistributions of any form whatsoever must retain the following * acknowledgment: * "This product includes software developed by Computing Services * at Carnegie Mellon University (http://www.cmu.edu/computing/)." * * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * $Id: fsm.h,v 1.10 2004/11/13 02:28:15 paulus Exp $ */ #ifndef PPP_FSM_H #define PPP_FSM_H #include "pppdconf.h" #ifdef __cplusplus extern "C" { #endif /* * Packet header = Code, id, length. */ #define HEADERLEN 4 /* * CP (LCP, IPCP, etc.) codes. */ #define CONFREQ 1 /* Configuration Request */ #define CONFACK 2 /* Configuration Ack */ #define CONFNAK 3 /* Configuration Nak */ #define CONFREJ 4 /* Configuration Reject */ #define TERMREQ 5 /* Termination Request */ #define TERMACK 6 /* Termination Ack */ #define CODEREJ 7 /* Code Reject */ /* * Each FSM is described by an fsm structure and fsm callbacks. */ typedef struct fsm { int unit; /* Interface unit number */ int protocol; /* Data Link Layer Protocol field value */ int state; /* State */ int flags; /* Contains option bits */ unsigned char id; /* Current id */ unsigned char reqid; /* Current request id */ unsigned char seen_ack; /* Have received valid Ack/Nak/Rej to Req */ int timeouttime; /* Timeout time in milliseconds */ int maxconfreqtransmits; /* Maximum Configure-Request transmissions */ int retransmits; /* Number of retransmissions left */ int maxtermtransmits; /* Maximum Terminate-Request transmissions */ int nakloops; /* Number of nak loops since last ack */ int rnakloops; /* Number of naks received */ int maxnakloops; /* Maximum number of nak loops tolerated */ struct fsm_callbacks *callbacks; /* Callback routines */ char *term_reason; /* Reason for closing protocol */ int term_reason_len; /* Length of term_reason */ } fsm; typedef struct fsm_callbacks { void (*resetci)(fsm *); /* Reset our Configuration Information */ int (*cilen)(fsm *); /* Length of our Configuration Information */ void (*addci) /* Add our Configuration Information */ (fsm *, unsigned char *, int *); int (*ackci) /* ACK our Configuration Information */ (fsm *, unsigned char *, int); int (*nakci) /* NAK our Configuration Information */ (fsm *, unsigned char *, int, int); int (*rejci) /* Reject our Configuration Information */ (fsm *, unsigned char *, int); int (*reqci) /* Request peer's Configuration Information */ (fsm *, unsigned char *, int *, int); void (*up)(fsm *); /* Called when fsm reaches OPENED state */ void (*down)(fsm *); /* Called when fsm leaves OPENED state */ void (*starting)(fsm *); /* Called when we want the lower layer */ void (*finished)(fsm *); /* Called when we don't want the lower layer */ void (*protreject)(int); /* Called when Protocol-Reject received */ void (*retransmit)(fsm *); /* Retransmission is necessary */ int (*extcode) /* Called when unknown code received */ (fsm *, int, int, unsigned char *, int); char *proto_name; /* String name for protocol (for messages) */ } fsm_callbacks; /* * Link states. */ #define INITIAL 0 /* Down, hasn't been opened */ #define STARTING 1 /* Down, been opened */ #define CLOSED 2 /* Up, hasn't been opened */ #define STOPPED 3 /* Open, waiting for down event */ #define CLOSING 4 /* Terminating the connection, not open */ #define STOPPING 5 /* Terminating, but open */ #define REQSENT 6 /* We've sent a Config Request */ #define ACKRCVD 7 /* We've received a Config Ack */ #define ACKSENT 8 /* We've sent a Config Ack */ #define OPENED 9 /* Connection available */ /* * Flags - indicate options controlling FSM operation */ #define OPT_PASSIVE 1 /* Don't die if we don't get a response */ #define OPT_RESTART 2 /* Treat 2nd OPEN as DOWN, UP */ #define OPT_SILENT 4 /* Wait for peer to speak first */ /* * Timeouts. */ #define DEFTIMEOUT 3 /* Timeout time in seconds */ #define DEFMAXTERMREQS 2 /* Maximum Terminate-Request transmissions */ #define DEFMAXCONFREQS 10 /* Maximum Configure-Request transmissions */ #define DEFMAXNAKLOOPS 5 /* Maximum number of nak loops */ /* * Prototypes */ void fsm_init (fsm *); void fsm_lowerup (fsm *); void fsm_lowerdown (fsm *); void fsm_open (fsm *); void fsm_close (fsm *, char *); void fsm_input (fsm *, unsigned char *, int); void fsm_protreject (fsm *); void fsm_sdata (fsm *, int, int, unsigned char *, int); /* * Variables */ extern int peer_mru[]; /* currently negotiated peer MRU (per unit) */ #ifdef __cplusplus } #endif #endif // PPP_FSM_H ppp-2.5.0/pppd/ipcp.h0000644000175000017500000001122514407475306011320 00000000000000/* * ipcp.h - IP Control Protocol definitions. * * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The name "Carnegie Mellon University" must not be used to * endorse or promote products derived from this software without * prior written permission. For permission or any legal * details, please contact * Office of Technology Transfer * Carnegie Mellon University * 5000 Forbes Avenue * Pittsburgh, PA 15213-3890 * (412) 268-4387, fax: (412) 268-7395 * tech-transfer@andrew.cmu.edu * * 4. Redistributions of any form whatsoever must retain the following * acknowledgment: * "This product includes software developed by Computing Services * at Carnegie Mellon University (http://www.cmu.edu/computing/)." * * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #ifndef PPP_IPCP_H #define PPP_IPCP_H #include "pppdconf.h" #ifdef __cplusplus extern "C" { #endif /* * Options. */ #define CI_ADDRS 1 /* IP Addresses */ #define CI_COMPRESSTYPE 2 /* Compression Type */ #define CI_ADDR 3 #define CI_MS_DNS1 129 /* Primary DNS value */ #define CI_MS_WINS1 130 /* Primary WINS value */ #define CI_MS_DNS2 131 /* Secondary DNS value */ #define CI_MS_WINS2 132 /* Secondary WINS value */ #define MAX_STATES 16 /* from slcompress.h */ #define IPCP_VJMODE_OLD 1 /* "old" mode (option # = 0x0037) */ #define IPCP_VJMODE_RFC1172 2 /* "old-rfc"mode (option # = 0x002d) */ #define IPCP_VJMODE_RFC1332 3 /* "new-rfc"mode (option # = 0x002d, */ /* maxslot and slot number compression) */ #define IPCP_VJ_COMP 0x002d /* current value for VJ compression option*/ #define IPCP_VJ_COMP_OLD 0x0037 /* "old" (i.e, broken) value for VJ */ /* compression option*/ typedef struct ipcp_options { bool neg_addr; /* Negotiate IP Address? */ bool old_addrs; /* Use old (IP-Addresses) option? */ bool req_addr; /* Ask peer to send IP address? */ bool default_route; /* Assign default route through interface? */ bool replace_default_route; /* Replace default route through interface? */ bool proxy_arp; /* Make proxy ARP entry for peer? */ bool neg_vj; /* Van Jacobson Compression? */ bool old_vj; /* use old (short) form of VJ option? */ bool accept_local; /* accept peer's value for ouraddr */ bool accept_remote; /* accept peer's value for hisaddr */ bool req_dns1; /* Ask peer to send primary DNS address? */ bool req_dns2; /* Ask peer to send secondary DNS address? */ bool req_wins1; /* Ask peer to send primary WINS address? */ bool req_wins2; /* Ask peer to send secondary WINS address? */ int vj_protocol; /* protocol value to use in VJ option */ int maxslotindex; /* values for RFC1332 VJ compression neg. */ bool cflag; uint32_t ouraddr, hisaddr; /* Addresses in NETWORK BYTE ORDER */ uint32_t dnsaddr[2]; /* Primary and secondary MS DNS entries */ uint32_t winsaddr[2]; /* Primary and secondary MS WINS entries */ } ipcp_options; extern fsm ipcp_fsm[]; extern ipcp_options ipcp_wantoptions[]; extern ipcp_options ipcp_gotoptions[]; extern ipcp_options ipcp_allowoptions[]; extern ipcp_options ipcp_hisoptions[]; char *ip_ntoa(uint32_t); extern struct protent ipcp_protent; /* * Hook for a plugin to know when IP protocol has come up */ typedef void (ip_up_hook_fn)(void); extern ip_up_hook_fn *ip_up_hook; /* * Hook for a plugin to know when IP protocol has come down */ typedef void (ip_down_hook_fn)(void); extern ip_down_hook_fn *ip_down_hook; /* * Hook for a plugin to choose the remote IP address */ typedef void (ip_choose_hook_fn)(uint32_t *); extern ip_choose_hook_fn *ip_choose_hook; #ifdef __cplusplus } #endif #endif /* PPP_IPCP_H */ ppp-2.5.0/pppd/ipv6cp.h0000644000175000017500000001716614407475306011606 00000000000000/* * ipv6cp.h - PPP IPV6 Control Protocol. * * Copyright (c) 1999 Tommi Komulainen. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The name(s) of the authors of this software must not be used to * endorse or promote products derived from this software without * prior written permission. * * 4. Redistributions of any form whatsoever must retain the following * acknowledgment: * "This product includes software developed by Tommi Komulainen * ". * * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * */ #ifndef PPP_IPV6CP_H #define PPP_IPV6CP_H #include "pppdconf.h" #ifdef __cplusplus extern "C" { #endif /* Original version, based on RFC2023 : Copyright (c) 1995, 1996, 1997 Francis.Dupont@inria.fr, INRIA Rocquencourt, Alain.Durand@imag.fr, IMAG, Jean-Luc.Richier@imag.fr, IMAG-LSR. Copyright (c) 1998, 1999 Francis.Dupont@inria.fr, GIE DYADE, Alain.Durand@imag.fr, IMAG, Jean-Luc.Richier@imag.fr, IMAG-LSR. Ce travail a été fait au sein du GIE DYADE (Groupement d'Intérêt Économique ayant pour membres BULL S.A. et l'INRIA). Ce logiciel informatique est disponible aux conditions usuelles dans la recherche, c'est-à-dire qu'il peut être utilisé, copié, modifié, distribué à l'unique condition que ce texte soit conservé afin que l'origine de ce logiciel soit reconnue. Le nom de l'Institut National de Recherche en Informatique et en Automatique (INRIA), de l'IMAG, ou d'une personne morale ou physique ayant participé à l'élaboration de ce logiciel ne peut être utilisé sans son accord préalable explicite. Ce logiciel est fourni tel quel sans aucune garantie, support ou responsabilité d'aucune sorte. Ce logiciel est dérivé de sources d'origine "University of California at Berkeley" et "Digital Equipment Corporation" couvertes par des copyrights. L'Institut d'Informatique et de Mathématiques Appliquées de Grenoble (IMAG) est une fédération d'unités mixtes de recherche du CNRS, de l'Institut National Polytechnique de Grenoble et de l'Université Joseph Fourier regroupant sept laboratoires dont le laboratoire Logiciels, Systèmes, Réseaux (LSR). This work has been done in the context of GIE DYADE (joint R & D venture between BULL S.A. and INRIA). This software is available with usual "research" terms with the aim of retain credits of the software. Permission to use, copy, modify and distribute this software for any purpose and without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies, and the name of INRIA, IMAG, or any contributor not be used in advertising or publicity pertaining to this material without the prior explicit permission. The software is provided "as is" without any warranties, support or liabilities of any kind. This software is derived from source code from "University of California at Berkeley" and "Digital Equipment Corporation" protected by copyrights. Grenoble's Institute of Computer Science and Applied Mathematics (IMAG) is a federation of seven research units funded by the CNRS, National Polytechnic Institute of Grenoble and University Joseph Fourier. The research unit in Software, Systems, Networks (LSR) is member of IMAG. */ /* * Derived from : * * * ipcp.h - IP Control Protocol definitions. * * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The name "Carnegie Mellon University" must not be used to * endorse or promote products derived from this software without * prior written permission. For permission or any legal * details, please contact * Office of Technology Transfer * Carnegie Mellon University * 5000 Forbes Avenue * Pittsburgh, PA 15213-3890 * (412) 268-4387, fax: (412) 268-7395 * tech-transfer@andrew.cmu.edu * * 4. Redistributions of any form whatsoever must retain the following * acknowledgment: * "This product includes software developed by Computing Services * at Carnegie Mellon University (http://www.cmu.edu/computing/)." * * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /* * Options. */ #define CI_IFACEID 1 /* Interface Identifier */ #define CI_COMPRESSTYPE 2 /* Compression Type */ /* No compression types yet defined. *#define IPV6CP_COMP 0x004f */ typedef struct ipv6cp_options { int neg_ifaceid; /* Negotiate interface identifier? */ int req_ifaceid; /* Ask peer to send interface identifier? */ int default_route; /* Assign default route through interface? */ int accept_local; /* accept peer's value for our iface id? */ int accept_remote; /* accept peer's value for his iface id? */ int opt_local; /* ourtoken set by option */ int opt_remote; /* histoken set by option */ int use_ip; /* use IP as interface identifier */ int use_persistent; /* use uniquely persistent value for address */ int use_remotenumber; /* use remote number value for address */ int neg_vj; /* Van Jacobson Compression? */ u_short vj_protocol; /* protocol value to use in VJ option */ eui64_t ourid, hisid; /* Interface identifiers */ } ipv6cp_options; extern fsm ipv6cp_fsm[]; extern ipv6cp_options ipv6cp_wantoptions[]; extern ipv6cp_options ipv6cp_gotoptions[]; extern ipv6cp_options ipv6cp_allowoptions[]; extern ipv6cp_options ipv6cp_hisoptions[]; extern struct protent ipv6cp_protent; /* * Hook for a plugin to know when IPv6 protocol has come up */ typedef void (ipv6_up_hook_fn)(void); extern ipv6_up_hook_fn *ipv6_up_hook; /* * Hook for a plugin to know when IPv6 protocol has come down */ typedef void (ipv6_down_hook_fn)(void); extern ipv6_down_hook_fn *ipv6_down_hook; #ifdef __cplusplus } #endif #endif ppp-2.5.0/pppd/lcp.h0000644000175000017500000001343414407475306011147 00000000000000/* * lcp.h - Link Control Protocol definitions. * * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The name "Carnegie Mellon University" must not be used to * endorse or promote products derived from this software without * prior written permission. For permission or any legal * details, please contact * Office of Technology Transfer * Carnegie Mellon University * 5000 Forbes Avenue * Pittsburgh, PA 15213-3890 * (412) 268-4387, fax: (412) 268-7395 * tech-transfer@andrew.cmu.edu * * 4. Redistributions of any form whatsoever must retain the following * acknowledgment: * "This product includes software developed by Computing Services * at Carnegie Mellon University (http://www.cmu.edu/computing/)." * * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #ifndef PPP_LCP_H #define PPP_LCP_H #include "pppdconf.h" #ifdef __cplusplus extern "C" { #endif /* * Options. */ #define CI_VENDOR 0 /* Vendor Specific */ #define CI_MRU 1 /* Maximum Receive Unit */ #define CI_ASYNCMAP 2 /* Async Control Character Map */ #define CI_AUTHTYPE 3 /* Authentication Type */ #define CI_QUALITY 4 /* Quality Protocol */ #define CI_MAGICNUMBER 5 /* Magic Number */ #define CI_PCOMPRESSION 7 /* Protocol Field Compression */ #define CI_ACCOMPRESSION 8 /* Address/Control Field Compression */ #define CI_FCSALTERN 9 /* FCS-Alternatives */ #define CI_SDP 10 /* Self-Describing-Pad */ #define CI_NUMBERED 11 /* Numbered-Mode */ #define CI_CALLBACK 13 /* callback */ #define CI_MRRU 17 /* max reconstructed receive unit; multilink */ #define CI_SSNHF 18 /* short sequence numbers for multilink */ #define CI_EPDISC 19 /* endpoint discriminator */ #define CI_MPPLUS 22 /* Multi-Link-Plus-Procedure */ #define CI_LDISC 23 /* Link-Discriminator */ #define CI_LCPAUTH 24 /* LCP Authentication */ #define CI_COBS 25 /* Consistent Overhead Byte Stuffing */ #define CI_PREFELIS 26 /* Prefix Elision */ #define CI_MPHDRFMT 27 /* MP Header Format */ #define CI_I18N 28 /* Internationalization */ #define CI_SDL 29 /* Simple Data Link */ /* * LCP-specific packet types (code numbers). */ #define PROTREJ 8 /* Protocol Reject */ #define ECHOREQ 9 /* Echo Request */ #define ECHOREP 10 /* Echo Reply */ #define DISCREQ 11 /* Discard Request */ #define IDENTIF 12 /* Identification */ #define TIMEREM 13 /* Time Remaining */ /* Value used as data for CI_CALLBACK option */ #define CBCP_OPT 6 /* Use callback control protocol */ /* An endpoint discriminator, used with multilink. */ #define MAX_ENDP_LEN 20 /* maximum length of discriminator value */ struct epdisc { unsigned char class; unsigned char length; unsigned char value[MAX_ENDP_LEN]; }; /* * The state of options is described by an lcp_options structure. */ typedef struct lcp_options { bool passive; /* Don't die if we don't get a response */ bool silent; /* Wait for the other end to start first */ bool restart; /* Restart vs. exit after close */ bool neg_mru; /* Negotiate the MRU? */ bool neg_asyncmap; /* Negotiate the async map? */ bool neg_upap; /* Ask for UPAP authentication? */ bool neg_chap; /* Ask for CHAP authentication? */ bool neg_eap; /* Ask for EAP authentication? */ bool neg_magicnumber; /* Ask for magic number? */ bool neg_pcompression; /* HDLC Protocol Field Compression? */ bool neg_accompression; /* HDLC Address/Control Field Compression? */ bool neg_lqr; /* Negotiate use of Link Quality Reports */ bool neg_cbcp; /* Negotiate use of CBCP */ bool neg_mrru; /* negotiate multilink MRRU */ bool neg_ssnhf; /* negotiate short sequence numbers */ bool neg_endpoint; /* negotiate endpoint discriminator */ int mru; /* Value of MRU */ int mrru; /* Value of MRRU, and multilink enable */ unsigned char chap_mdtype; /* which MD types (hashing algorithm) */ uint32_t asyncmap; /* Value of async map */ uint32_t magicnumber; int numloops; /* Number of loops during magic number neg. */ uint32_t lqr_period; /* Reporting period for LQR 1/100ths second */ struct epdisc endpoint; /* endpoint discriminator */ } lcp_options; extern fsm lcp_fsm[]; extern lcp_options lcp_wantoptions[]; extern lcp_options lcp_gotoptions[]; extern lcp_options lcp_allowoptions[]; extern lcp_options lcp_hisoptions[]; #define DEFMRU 1500 /* Try for this */ #define MINMRU 128 /* No MRUs below this */ #define MAXMRU 16384 /* Normally limit MRU to this */ void lcp_open(int); void lcp_close(int, char *); void lcp_lowerup(int); void lcp_lowerdown(int); void lcp_sprotrej(int, unsigned char *, int); /* send protocol reject */ extern struct protent lcp_protent; /* Default number of times we receive our magic number from the peer before deciding the link is looped-back. */ #define DEFLOOPBACKFAIL 10 #ifdef __cplusplus } #endif #endif // PPP_LCP_H ppp-2.5.0/pppd/magic.h0000644000175000017500000000423014407475306011443 00000000000000/* * magic.h - PPP Magic Number definitions. * * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The name "Carnegie Mellon University" must not be used to * endorse or promote products derived from this software without * prior written permission. For permission or any legal * details, please contact * Office of Technology Transfer * Carnegie Mellon University * 5000 Forbes Avenue * Pittsburgh, PA 15213-3890 * (412) 268-4387, fax: (412) 268-7395 * tech-transfer@andrew.cmu.edu * * 4. Redistributions of any form whatsoever must retain the following * acknowledgment: * "This product includes software developed by Computing Services * at Carnegie Mellon University (http://www.cmu.edu/computing/)." * * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #ifndef PPP_MAGIC_H #define PPP_MAGIC_H #include "pppdconf.h" #ifdef __cplusplus extern "C" { #endif void magic_init (void); /* Initialize the magic number generator */ u_int32_t magic (void); /* Returns the next magic number */ /* Fill buffer with random bytes */ void random_bytes (unsigned char *buf, int len); #ifdef __cplusplus } #endif #endif // PPP_MAGIC_H ppp-2.5.0/pppd/mppe.h0000644000175000017500000001303614407475306011330 00000000000000/* * mppe.h - Definitions for MPPE * * Copyright (c) 2008 Paul Mackerras. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The name(s) of the authors of this software must not be used to * endorse or promote products derived from this software without * prior written permission. * * 4. Redistributions of any form whatsoever must retain the following * acknowledgment: * "This product includes software developed by Paul Mackerras * ". * * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #ifndef PPP_MPPE_H #define PPP_MPPE_H #include "pppdconf.h" #ifdef __cplusplus extern "C" { #endif #define MPPE_PAD 4 /* MPPE growth per frame */ #define MPPE_MAX_KEY_SIZE 32 /* Largest key length */ #define MPPE_MAX_KEY_LEN 16 /* Largest key size accepted by the kernel */ /* option bits for ccp_options.mppe */ #define MPPE_OPT_40 0x01 /* 40 bit */ #define MPPE_OPT_128 0x02 /* 128 bit */ #define MPPE_OPT_STATEFUL 0x04 /* stateful mode */ /* unsupported opts */ #define MPPE_OPT_56 0x08 /* 56 bit */ #define MPPE_OPT_MPPC 0x10 /* MPPC compression */ #define MPPE_OPT_D 0x20 /* Unknown */ #define MPPE_OPT_UNSUPPORTED (MPPE_OPT_56|MPPE_OPT_MPPC|MPPE_OPT_D) #define MPPE_OPT_UNKNOWN 0x40 /* Bits !defined in RFC 3078 were set */ /* * This is not nice ... the alternative is a bitfield struct though. * And unfortunately, we cannot share the same bits for the option * names above since C and H are the same bit. We could do a u_int32 * but then we have to do a htonl() all the time and/or we still need * to know which octet is which. */ #define MPPE_C_BIT 0x01 /* MPPC */ #define MPPE_D_BIT 0x10 /* Obsolete, usage unknown */ #define MPPE_L_BIT 0x20 /* 40-bit */ #define MPPE_S_BIT 0x40 /* 128-bit */ #define MPPE_M_BIT 0x80 /* 56-bit, not supported */ #define MPPE_H_BIT 0x01 /* Stateless (in a different byte) */ /* Does not include H bit; used for least significant octet only. */ #define MPPE_ALL_BITS (MPPE_D_BIT|MPPE_L_BIT|MPPE_S_BIT|MPPE_M_BIT|MPPE_H_BIT) /* Build a CI from mppe opts (see RFC 3078) */ #define MPPE_OPTS_TO_CI(opts, ci) \ do { \ unsigned char *ptr = ci; /* unsigned char[4] */ \ \ /* H bit */ \ if (opts & MPPE_OPT_STATEFUL) \ *ptr++ = 0x0; \ else \ *ptr++ = MPPE_H_BIT; \ *ptr++ = 0; \ *ptr++ = 0; \ \ /* S,L bits */ \ *ptr = 0; \ if (opts & MPPE_OPT_128) \ *ptr |= MPPE_S_BIT; \ if (opts & MPPE_OPT_40) \ *ptr |= MPPE_L_BIT; \ /* M,D,C bits not supported */ \ } while (/* CONSTCOND */ 0) /* The reverse of the above */ #define MPPE_CI_TO_OPTS(ci, opts) \ do { \ unsigned char *ptr = ci; /* unsigned char[4] */ \ \ opts = 0; \ \ /* H bit */ \ if (!(ptr[0] & MPPE_H_BIT)) \ opts |= MPPE_OPT_STATEFUL; \ \ /* S,L bits */ \ if (ptr[3] & MPPE_S_BIT) \ opts |= MPPE_OPT_128; \ if (ptr[3] & MPPE_L_BIT) \ opts |= MPPE_OPT_40; \ \ /* M,D,C bits */ \ if (ptr[3] & MPPE_M_BIT) \ opts |= MPPE_OPT_56; \ if (ptr[3] & MPPE_D_BIT) \ opts |= MPPE_OPT_D; \ if (ptr[3] & MPPE_C_BIT) \ opts |= MPPE_OPT_MPPC; \ \ /* Other bits */ \ if (ptr[0] & ~MPPE_H_BIT) \ opts |= MPPE_OPT_UNKNOWN; \ if (ptr[1] || ptr[2]) \ opts |= MPPE_OPT_UNKNOWN; \ if (ptr[3] & ~MPPE_ALL_BITS) \ opts |= MPPE_OPT_UNKNOWN; \ } while (/* CONSTCOND */ 0) #if PPP_WITH_MPPE /* These values are the RADIUS attribute values--see RFC 2548. */ #define MPPE_ENC_POL_ENC_ALLOWED 1 #define MPPE_ENC_POL_ENC_REQUIRED 2 #define MPPE_ENC_TYPES_RC4_40 2 #define MPPE_ENC_TYPES_RC4_128 4 /* used by plugins (using above values) */ void mppe_set_enc_types (int policy, int types); /* * Set the MPPE send and recv keys. NULL values for keys are ignored * and input values are cleared to avoid leaving them on the stack */ void mppe_set_keys(unsigned char *send_key, unsigned char *recv_key, int keylen); /* * Get the MPPE recv key */ int mppe_get_recv_key(unsigned char *recv_key, int length); /* * Get the MPPE send key */ int mppe_get_send_key(unsigned char *send_key, int length); /* * Clear the MPPE keys */ void mppe_clear_keys(void); /* * Check if the MPPE keys are set */ bool mppe_keys_isset(void); /* * Set mppe_xxxx_key from NT Password Hash Hash (MSCHAPv1), see RFC3079 */ void mppe_set_chapv1(unsigned char *rchallenge, unsigned char *PasswordHashHash); /* * Set the mppe_xxxx_key from MS-CHAP-v2 credentials, see RFC3079 */ void mppe_set_chapv2(unsigned char *PasswordHashHash, unsigned char *NTResponse, int IsServer); #endif // #ifdef PPP_WITH_MPPE #ifdef __cplusplus } #endif #endif // #ifdef PPP_MPPE_H ppp-2.5.0/pppd/multilink.h0000644000175000017500000000534314407475306012401 00000000000000/* * multilink.h - support routines for multilink. * * Copyright (c) 2000-2002 Paul Mackerras. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. The name(s) of the authors of this software must not be used to * endorse or promote products derived from this software without * prior written permission. * * 3. Redistributions of any form whatsoever must retain the following * acknowledgment: * "This product includes software developed by Paul Mackerras * ". * * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #ifndef PPP_MULTILINK_H #define PPP_MULTILINK_H #include "pppdconf.h" #ifdef __cplusplus extern "C" { #endif /* * values for epdisc.class */ #define EPD_NULL 0 /* null discriminator, no data */ #define EPD_LOCAL 1 #define EPD_IP 2 #define EPD_MAC 3 #define EPD_MAGIC 4 #define EPD_PHONENUM 5 struct epdisc; #ifdef PPP_WITH_MULTILINK /* * Check multilink-related options */ void mp_check_options(void); /* * Join our link to an appropriate bundle */ int mp_join_bundle(void); /* * Disconnected our link from the bundle */ void mp_exit_bundle(void); /* * Multipoint bundle terminated */ void mp_bundle_terminated(void); /* * Acting as a multilink master */ bool mp_master(); /* * Was multilink negotiated */ bool mp_on(); /* * Convert an endpoint discriminator to a string */ char *epdisc_to_str(struct epdisc *); /* * Convert a string to an endpoint discriminator */ int str_to_epdisc(struct epdisc *, char *); /* * Hook for plugin to hear when an interface joins a multilink bundle */ typedef void (multilink_join_hook_fn)(void); extern multilink_join_hook_fn *multilink_join_hook; #else #define mp_check_options(x) ((void)0) #define mp_join_bundle(x) ((void)0) #define mp_exit_bundle(x) ((void)0) #define mp_bundle_terminated(x) ((void)0) static inline bool mp_on() { return false; } static inline bool mp_master() { return false; } #endif // PPP_WITH_MULTILINK #ifdef __cplusplus } #endif #endif // PPP_MULTILINK_H ppp-2.5.0/pppd/pppd.h0000644000175000017500000003252014407475306011331 00000000000000/* * pppd.h - PPP daemon global declarations. * * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The name "Carnegie Mellon University" must not be used to * endorse or promote products derived from this software without * prior written permission. For permission or any legal * details, please contact * Office of Technology Transfer * Carnegie Mellon University * 5000 Forbes Avenue * Pittsburgh, PA 15213-3890 * (412) 268-4387, fax: (412) 268-7395 * tech-transfer@andrew.cmu.edu * * 4. Redistributions of any form whatsoever must retain the following * acknowledgment: * "This product includes software developed by Computing Services * at Carnegie Mellon University (http://www.cmu.edu/computing/)." * * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #ifndef PPP_PPPD_H #define PPP_PPPD_H #include #include #include #include #include #include "pppdconf.h" #ifdef __cplusplus extern "C" { #endif /* * Limits */ #define NUM_PPP 1 /* One PPP interface supported (per process) */ #define MAXWORDLEN 1024 /* max length of word in file (incl null) */ #define MAXARGS 1 /* max # args to a command */ #define MAXNAMELEN 256 /* max length of hostname or name for auth */ #define MAXSECRETLEN 256 /* max length of password or secret */ /* * Values for phase. */ typedef enum ppp_phase { PHASE_DEAD, PHASE_INITIALIZE, PHASE_SERIALCONN, PHASE_DORMANT, PHASE_ESTABLISH, PHASE_AUTHENTICATE, PHASE_CALLBACK, PHASE_NETWORK, PHASE_RUNNING, PHASE_TERMINATE, PHASE_DISCONNECT, PHASE_HOLDOFF, PHASE_MASTER, } ppp_phase_t; /* * Values for exit codes */ typedef enum ppp_exit_code { EXIT_OK = 0, EXIT_FATAL_ERROR = 1, EXIT_OPTION_ERROR = 2, EXIT_NOT_ROOT = 3, EXIT_NO_KERNEL_SUPPORT = 4, EXIT_USER_REQUEST = 5, EXIT_LOCK_FAILED = 6, EXIT_OPEN_FAILED = 7, EXIT_CONNECT_FAILED = 8, EXIT_PTYCMD_FAILED = 9, EXIT_NEGOTIATION_FAILED = 10, EXIT_PEER_AUTH_FAILED = 11, EXIT_IDLE_TIMEOUT = 12, EXIT_CONNECT_TIME = 13, EXIT_CALLBACK = 14, EXIT_PEER_DEAD = 15, EXIT_HANGUP = 16, EXIT_LOOPBACK = 17, EXIT_INIT_FAILED = 18, EXIT_AUTH_TOPEER_FAILED = 19, EXIT_TRAFFIC_LIMIT = 20, EXIT_CNID_AUTH_FAILED = 21 } ppp_exit_code_t; /* * Type of notifier callbacks */ typedef enum { NF_PID_CHANGE, NF_PHASE_CHANGE, NF_EXIT, NF_SIGNALED, NF_IP_UP, NF_IP_DOWN, NF_IPV6_UP, NF_IPV6_DOWN, NF_AUTH_UP, NF_LINK_DOWN, NF_FORK, NF_MAX_NOTIFY } ppp_notify_t; typedef enum { PPP_DIR_LOG, PPP_DIR_RUNTIME, PPP_DIR_CONF, PPP_DIR_PLUGIN, } ppp_path_t; /* * Unfortunately, the linux kernel driver uses a different structure * for statistics from the rest of the ports. * This structure serves as a common representation for the bits * pppd needs. */ struct pppd_stats { uint64_t bytes_in; uint64_t bytes_out; unsigned int pkts_in; unsigned int pkts_out; }; typedef struct pppd_stats ppp_link_stats_st; /* * Used for storing a sequence of words. Usually malloced. */ struct wordlist { struct wordlist *next; char *word; }; struct option; typedef void (*printer_func)(void *, char *, ...); /* * The following struct gives the addresses of procedures to call for a particular protocol. */ struct protent { /* PPP protocol number */ unsigned short protocol; /* Initialization procedure */ void (*init)(int unit); /* Process a received packet */ void (*input)(int unit, unsigned char *pkt, int len); /* Process a received protocol-reject */ void (*protrej)(int unit); /* Lower layer has come up */ void (*lowerup)(int unit); /* Lower layer has gone down */ void (*lowerdown)(int unit); /* Open the protocol */ void (*open)(int unit); /* Close the protocol */ void (*close)(int unit, char *reason); /* Print a packet in readable form */ int (*printpkt)(unsigned char *pkt, int len, printer_func printer, void *arg); /* Process a received data packet */ void (*datainput)(int unit, unsigned char *pkt, int len); /* 0 iff protocol is disabled */ bool enabled_flag; /* Text name of protocol */ char *name; /* Text name of corresponding data protocol */ char *data_name; /* List of command-line options */ struct option *options; /* Check requested options, assign defaults */ void (*check_options)(void); /* Configure interface for demand-dial */ int (*demand_conf)(int unit); /* Say whether to bring up link for this pkt */ int (*active_pkt)(unsigned char *pkt, int len); }; /* Table of pointers to supported protocols */ extern struct protent *protocols[]; /* * This struct contains pointers to a set of procedures for doing operations on a "channel". * A channel provides a way to send and receive PPP packets - the canonical example is a serial * port device in PPP line discipline (or equivalently with PPP STREAMS modules pushed onto it). */ struct channel { /* set of options for this channel */ struct option *options; /* find and process a per-channel options file */ void (*process_extra_options)(void); /* check all the options that have been given */ void (*check_options)(void); /* get the channel ready to do PPP, return a file descriptor */ int (*connect)(void); /* we're finished with the channel */ void (*disconnect)(void); /* put the channel into PPP `mode' */ int (*establish_ppp)(int); /* take the channel out of PPP `mode', restore loopback if demand */ void (*disestablish_ppp)(int); /* set the transmit-side PPP parameters of the channel */ void (*send_config)(int, uint32_t, int, int); /* set the receive-side PPP parameters of the channel */ void (*recv_config)(int, uint32_t, int, int); /* cleanup on error or normal exit */ void (*cleanup)(void); /* close the device, called in children after fork */ void (*close)(void); }; extern struct channel *the_channel; /* * Functions for string formatting and debugging */ /* Is debug enabled */ bool debug_on(); /* Safe sprintf++ */ int slprintf(char *, int, char *, ...); /* vsprintf++ */ int vslprintf(char *, int, char *, va_list); /* safe strcpy */ size_t strlcpy(char *, const char *, size_t); /* safe strncpy */ size_t strlcat(char *, const char *, size_t); /* log a debug message */ void dbglog(char *, ...); /* log an informational message */ void info(char *, ...); /* log a notice-level message */ void notice(char *, ...); /* log a warning message */ void warn(char *, ...); /* log an error message */ void error(char *, ...); /* log an error message and die(1) */ void fatal(char *, ...); /* Say we ran out of memory, and die */ void novm(char *); /* Format a packet and log it with syslog */ void log_packet(unsigned char *, int, char *, int); /* dump packet to debug log if interesting */ void dump_packet(const char *, unsigned char *, int); /* initialize for using pr_log */ void init_pr_log(const char *, int); /* printer fn, output to syslog */ void pr_log(void *, char *, ...); /* finish up after using pr_log */ void end_pr_log(void); /* * Get the current exist status of pppd */ ppp_exit_code_t ppp_status(); /* * Set the exit status */ void ppp_set_status(ppp_exit_code_t code); /* * Configure the session's maximum number of octets */ void ppp_set_session_limit(unsigned int octets); /* * Which direction to limit the number of octets */ void ppp_set_session_limit_dir(unsigned int direction); /* * Get the current link stats, returns true when valid and false if otherwise */ bool ppp_get_link_stats(ppp_link_stats_st *stats); /* * Get pppd's notion of time */ int ppp_get_time(struct timeval *); /* * Schedule a callback in s.us seconds from now */ typedef void (*ppp_timer_cb)(void *arg); void ppp_timeout(ppp_timer_cb func, void *arg, int s, int us); /* * Cancel any pending timer callbacks */ void ppp_untimeout(void (*func)(void *), void *arg); /* * Clean up in a child before execing */ void ppp_sys_close(void); /* * Fork & close stuff in child */ pid_t ppp_safe_fork(int, int, int); /* * Get the current hostname */ const char *ppp_hostname(); /* * Is pppd using pty as a device (opposed to notty or pty opt). */ bool ppp_using_pty(); /* * Device is synchronous serial device */ bool ppp_sync_serial(); /* * Modem mode */ bool ppp_get_modem(); /* * Control the mode of the tty terminal */ void ppp_set_modem(bool on); /* * Set the current session number, e.g. for PPPoE */ void ppp_set_session_number(int number); /* * Set the current session number, e.g. for PPPoE */ int ppp_get_session_number(void); /* * Check if pppd got signaled, returns 0 if not signaled, returns -1 on failure, and the signal number when signaled. */ bool ppp_signaled(int sig); /* * Maximum connect time in seconds */ int ppp_get_max_connect_time(void); /* * Set the maximum connect time in seconds */ void ppp_set_max_connect_time(unsigned int max); /* * Get the link idle time before shutting the link down */ int ppp_get_max_idle_time(void); /* * Set the link idle time before shutting the link down */ void ppp_set_max_idle_time(unsigned int idle); /* * Get the duration the link was up (uptime) */ int ppp_get_link_uptime(); /* * Get the ipparam configured with pppd */ const char *ppp_ipparam(); /* * check if IP address is unreasonable */ bool ppp_bad_ip_addr(uint32_t); /* * Expose an environment variable to scripts */ void ppp_script_setenv(char *, char *, int); /* * Unexpose an environment variable to scripts */ void ppp_script_unsetenv(char *); /* * Test whether ppp kernel support exists */ int ppp_check_kernel_support(void); /* * Restore device setting */ void ppp_generic_disestablish(int dev_fd); /* * Set the interface MTU */ void ppp_set_mtu(int, int); /* * Get the interface MTU */ int ppp_get_mtu(int); /* * Make a ppp interface */ int ppp_generic_establish(int dev_fd); /* * Get the peer's authentication name */ const char *ppp_peer_authname(char *buf, size_t bufsz); /* * Get the remote name */ const char *ppp_remote_name(); /* * Get the remote number (if set), otherwise return NULL */ const char *ppp_get_remote_number(void); /* * Set the remote number, typically it's a MAC address */ void ppp_set_remote_number(const char *buf); /* * Get the current interface unit for the pppX device */ int ppp_ifunit(); /* * Get the current interface name */ const char *ppp_ifname(); /* * Get the current interface name */ int ppp_get_ifname(char *buf, size_t bufsz); /* * Set the current interface name, ifname is a \0 terminated string */ void ppp_set_ifname(const char *ifname); /* * Set the original devnam (prior to any renaming, etc). */ int ppp_set_pppdevnam(const char *name); /* * Get the original devnam (prior to any renaming, etc). */ const char *ppp_pppdevnam(); /* * Get the current devnam, e.g. /dev/ttyS0, /dev/ptmx */ const char *ppp_devnam(); /* * Set the device name */ int ppp_set_devnam(const char *name); /* * Definition for the notify callback function * ctx - contextual argument provided with the registration * arg - anything passed by the notification, e.g. phase, pid, etc */ typedef void (ppp_notify_fn)(void *ctx, int arg); /* * Add a callback notification for when a given event has occured */ void ppp_add_notify(ppp_notify_t type, ppp_notify_fn *func, void *ctx); /* * Remove a callback notification previously registered */ void ppp_del_notify(ppp_notify_t type, ppp_notify_fn *func, void *ctx); /* * Get the path prefix in which a file is installed */ int ppp_get_path(ppp_path_t type, char *buf, size_t bufsz); /* * Get the file with path prefix */ int ppp_get_filepath(ppp_path_t type, const char *name, char *buf, size_t bufsz); /* * Check if pppd is to re-open link after it goes down */ bool ppp_persist(); /* * Hooks to enable plugins to hook into various parts of the code */ struct ppp_idle; /* Declared in */ extern int (*idle_time_hook)(struct ppp_idle *); extern int (*new_phase_hook)(int); extern int (*holdoff_hook)(void); extern int (*allowed_address_hook)(uint32_t addr); extern void (*snoop_recv_hook)(unsigned char *p, int len); extern void (*snoop_send_hook)(unsigned char *p, int len); #ifdef __cplusplus } #endif #endif /* PPP_PPPD_H */ ppp-2.5.0/pppd/options.h0000644000175000017500000001071414407475306012062 00000000000000/* * options.h - header declarations for option processing for PPP. * * Copyright (c) 2000-2002 Paul Mackerras. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. The name(s) of the authors of this software must not be used to * endorse or promote products derived from this software without * prior written permission. * * 3. Redistributions of any form whatsoever must retain the following * acknowledgment: * "This product includes software developed by Paul Mackerras * ". * * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #ifndef PPP_OPTIONS_H #define PPP_OPTIONS_H #ifdef __cplusplus extern "C" { #endif enum opt_type { o_special_noarg, o_special, o_bool, o_int, o_uint32, o_string, o_wild }; struct option { char *name; /* name of the option */ enum opt_type type; void *addr; char *description; unsigned int flags; void *addr2; int upper_limit; int lower_limit; const char *source; short int priority; short int winner; }; typedef struct option option_t; /* Values for flags */ #define OPT_VALUE 0xff /* mask for presupplied value */ #define OPT_HEX 0x100 /* int option is in hex */ #define OPT_NOARG 0x200 /* option doesn't take argument */ #define OPT_OR 0x400 /* for u32, OR in argument to value */ #define OPT_INC 0x400 /* for o_int, increment value */ #define OPT_A2OR 0x800 /* for o_bool, OR arg to *(u_char *)addr2 */ #define OPT_PRIV 0x1000 /* privileged option */ #define OPT_STATIC 0x2000 /* string option goes into static array */ #define OPT_NOINCR 0x2000 /* for o_int, value mustn't be increased */ #define OPT_LLIMIT 0x4000 /* check value against lower limit */ #define OPT_ULIMIT 0x8000 /* check value against upper limit */ #define OPT_LIMITS (OPT_LLIMIT|OPT_ULIMIT) #define OPT_ZEROOK 0x10000 /* 0 value is OK even if not within limits */ #define OPT_HIDE 0x10000 /* for o_string, print value as ?????? */ #define OPT_A2LIST 0x20000 /* for o_special, keep list of values */ #define OPT_A2CLRB 0x20000 /* o_bool, clr val bits in *(u_char *)addr2 */ #define OPT_ZEROINF 0x40000 /* with OPT_NOINCR, 0 == infinity */ #define OPT_PRIO 0x80000 /* process option priorities for this option */ #define OPT_PRIOSUB 0x100000 /* subsidiary member of priority group */ #define OPT_ALIAS 0x200000 /* option is alias for previous option */ #define OPT_A2COPY 0x400000 /* addr2 -> second location to rcv value */ #define OPT_ENABLE 0x800000 /* use *addr2 as enable for option */ #define OPT_A2CLR 0x1000000 /* clear *(bool *)addr2 */ #define OPT_PRIVFIX 0x2000000 /* user can't override if set by root */ #define OPT_INITONLY 0x4000000 /* option can only be set in init phase */ #define OPT_DEVEQUIV 0x8000000 /* equiv to device name */ #define OPT_DEVNAM (OPT_INITONLY | OPT_DEVEQUIV) #define OPT_A2PRINTER 0x10000000 /* *addr2 printer_func to print option */ #define OPT_A2STRVAL 0x20000000 /* *addr2 points to current string value */ #define OPT_NOPRINT 0x40000000 /* don't print this option at all */ #define OPT_VAL(x) ((x) & OPT_VALUE) /* Values for priority */ #define OPRIO_DEFAULT 0 /* a default value */ #define OPRIO_CFGFILE 1 /* value from a configuration file */ #define OPRIO_CMDLINE 2 /* value from the command line */ #define OPRIO_SECFILE 3 /* value from options in a secrets file */ #define OPRIO_ROOT 100 /* added to priority if OPT_PRIVFIX && root */ /* Add additional supported options by e.g. plug-in */ void ppp_add_options(struct option *options); /* Parse options from an options file */ int ppp_options_from_file(char *filename, int must_exist, int check_prot, int privileged); /* Simplified number_option for decimal ints */ int ppp_int_option(char *name, int *value); /* Print an error message about an option */ void ppp_option_error(char *fmt, ...); #ifdef __cplusplus } #endif #endif // PPP_OPTIONS_H ppp-2.5.0/pppd/pppdconf.h0000644000175000017500000000451714407475316012205 00000000000000/* pppd/pppdconf.h. Generated from pppdconf.h.in by configure. */ /* * Copyright (c) 2022 Eivind Næss. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The name(s) of the authors of this software must not be used to * endorse or promote products derived from this software without * prior written permission. * * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /* * This file is generated by configure and sets the features enabled * in pppd when configured. */ #ifndef PPP_PPPDCONF_H #define PPP_PPPDCONF_H /* Have Microsoft CHAP support */ #define PPP_WITH_CHAPMS 1 /* Have Microsoft LAN Manager support */ /* #undef PPP_WITH_MSLANMAN */ /* Have Microsoft MPPE support */ #define PPP_WITH_MPPE 1 /* Have multilink support */ /* #undef PPP_WITH_MULTILINK */ /* Have packet activity filter support */ /* #undef PPP_WITH_FILTER */ /* Have support for loadable plugins */ #define PPP_WITH_PLUGINS 1 /* Have Callback Protocol support */ /* #undef PPP_WITH_CBCP */ /* Include TDB support */ /* #undef PPP_WITH_TDB */ /* Have IPv6 Control Protocol */ #define PPP_WITH_IPV6CP 1 /* Support for Pluggable Authentication Modules */ /* #undef PPP_WITH_PAM */ /* Have EAP-SRP authentication support */ /* #undef PPP_WITH_SRP */ /* Have EAP-TLS authentication support */ #define PPP_WITH_EAPTLS 1 /* Have PEAP authentication support */ #define PPP_WITH_PEAP 1 /* The pppd version */ #define PPPD_VERSION "2.5.0" #endif ppp-2.5.0/pppd/session.h0000644000175000017500000000565414407475306012061 00000000000000/* * session.c - PPP session control. * * Copyright (c) 2007 Diego Rivera. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. The name(s) of the authors of this software must not be used to * endorse or promote products derived from this software without * prior written permission. * * 3. Redistributions of any form whatsoever must retain the following * acknowledgment: * "This product includes software developed by Paul Mackerras * ". * * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #ifndef PPP_SESSION_H #define PPP_SESSION_H #include "pppdconf.h" #ifdef __cplusplus extern "C" { #endif #define SESS_AUTH 1 /* Check User Authentication */ #define SESS_ACCT 2 /* Check Account Validity */ /* Convenience parameter to do the whole enchilada */ #define SESS_ALL (SESS_AUTH | SESS_ACCT) /* * int session_start(...) * * Start a session, performing any necessary validations. * * Parameters: * const int flags : * Any combination of the SESS_XXX flags, to indicate what the function * should do as part of its checks * * const char* user : * The username to validate. May safely be null. * * const char* passwd : * The password to validate the user with. May safely be null. * * const char* tty : * The TTY the user is connected on. May safely be null. * * char** msg : * A char* to return an error or success message. This message will be returned * regardless of the result. May safely be null. * * Return Value: * Zero value for failure, non-zero value for successful session verification. */ int session_start(const int flags, const char* user, const char* passwd, const char* tty, char** msg); /* Added these macros for convenience... */ #define session_auth(user, pass, tty, msg) \ session_start(SESS_AUTH, user, pass, tty, msg) #define session_check(user, pass, tty, msg) \ session_start(SESS_ACCT, user, pass, tty, msg) #define session_full(user, pass, tty, msg) \ session_start(SESS_ALL, user, pass, tty, msg) /* * void session_end(...) * * End a previously-started session. * * Parameters: * const char* tty : * The TTY the user is connected on. May safely be null. */ void session_end(const char* tty); #ifdef __cplusplus } #endif #endif // PPP_SESSION_H ppp-2.5.0/pppd/upap.h0000644000175000017500000001160114407475306011330 00000000000000/* * upap.h - User/Password Authentication Protocol definitions. * * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The name "Carnegie Mellon University" must not be used to * endorse or promote products derived from this software without * prior written permission. For permission or any legal * details, please contact * Office of Technology Transfer * Carnegie Mellon University * 5000 Forbes Avenue * Pittsburgh, PA 15213-3890 * (412) 268-4387, fax: (412) 268-7395 * tech-transfer@andrew.cmu.edu * * 4. Redistributions of any form whatsoever must retain the following * acknowledgment: * "This product includes software developed by Computing Services * at Carnegie Mellon University (http://www.cmu.edu/computing/)." * * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #ifndef PPP_UPAP_H #define PPP_UPAP_H #include "pppdconf.h" #ifdef __cplusplus extern "C" { #endif /* * Packet header = Code, id, length. */ #define UPAP_HEADERLEN 4 /* * UPAP codes. */ #define UPAP_AUTHREQ 1 /* Authenticate-Request */ #define UPAP_AUTHACK 2 /* Authenticate-Ack */ #define UPAP_AUTHNAK 3 /* Authenticate-Nak */ /* * Each interface is described by upap structure. */ typedef struct upap_state { int us_unit; /* Interface unit number */ char *us_user; /* User */ int us_userlen; /* User length */ char *us_passwd; /* Password */ int us_passwdlen; /* Password length */ int us_clientstate; /* Client state */ int us_serverstate; /* Server state */ unsigned char us_id; /* Current id */ int us_timeouttime; /* Timeout (seconds) for auth-req retrans. */ int us_transmits; /* Number of auth-reqs sent */ int us_maxtransmits; /* Maximum number of auth-reqs to send */ int us_reqtimeout; /* Time to wait for auth-req from peer */ } upap_state; /* * Client states. */ #define UPAPCS_INITIAL 0 /* Connection down */ #define UPAPCS_CLOSED 1 /* Connection up, haven't requested auth */ #define UPAPCS_PENDING 2 /* Connection down, have requested auth */ #define UPAPCS_AUTHREQ 3 /* We've sent an Authenticate-Request */ #define UPAPCS_OPEN 4 /* We've received an Ack */ #define UPAPCS_BADAUTH 5 /* We've received a Nak */ /* * Server states. */ #define UPAPSS_INITIAL 0 /* Connection down */ #define UPAPSS_CLOSED 1 /* Connection up, haven't requested auth */ #define UPAPSS_PENDING 2 /* Connection down, have requested auth */ #define UPAPSS_LISTEN 3 /* Listening for an Authenticate */ #define UPAPSS_OPEN 4 /* We've sent an Ack */ #define UPAPSS_BADAUTH 5 /* We've sent a Nak */ /* * Timeouts. */ #define UPAP_DEFTIMEOUT 3 /* Timeout (seconds) for retransmitting req */ #define UPAP_DEFREQTIME 30 /* Time to wait for auth-req from peer */ extern upap_state upap[]; void upap_authwithpeer(int, char *, char *); void upap_authpeer(int); extern struct protent pap_protent; typedef int (pap_check_hook_fn)(void); typedef int (pap_auth_hook_fn)(char *user, char *passwd, char **msgp, struct wordlist **paddrs, struct wordlist **popts); typedef void (pap_logout_hook_fn)(void); typedef int (pap_passwd_hook_fn)(char *user, char *passwd); /* * This function will return a value of 1 to indicate that a plugin intent to * supply a username or a password through the pap_auth_hook callback. * * A return value of > 0 will avoid parsing pap-secrets file. */ extern pap_check_hook_fn *pap_check_hook; /* * This hook is used to check if a username and password matches against the * PAP secrets. */ extern pap_auth_hook_fn *pap_auth_hook; /* * Hook for plugin to know about PAP user logout. */ extern pap_logout_hook_fn *pap_logout_hook; /* * A plugin can chose to supply its own user and password overriding what * previously has been configured. Hook is only valid when pppd is acting * as a client */ extern pap_passwd_hook_fn *pap_passwd_hook; #ifdef __cplusplus } #endif #endif // PPP_UPAP_H ppp-2.5.0/pppd/pppd.80000664000175000017500000026045214260516066011256 00000000000000.\" manual page [] for pppd 2.4 .\" $Id: pppd.8,v 1.90 2008/03/26 12:09:40 paulus Exp $ .\" SH section heading .\" SS subsection heading .\" LP paragraph .\" IP indented paragraph .\" TP hanging label .\" .\" Copyright (c) 1993-2003 Paul Mackerras .\" .\" Permission to use, copy, modify, and distribute this software for any .\" purpose with or without fee is hereby granted, provided that the above .\" copyright notice and this permission notice appear in all copies. .\" .\" THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES .\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF .\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR .\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES .\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" .TH PPPD 8 .SH NAME pppd \- Point-to-Point Protocol Daemon .SH SYNOPSIS .B pppd [ .I options ] .SH DESCRIPTION .LP PPP is the protocol used for establishing internet links over dial-up modems, DSL connections, and many other types of point-to-point links. The \fIpppd\fR daemon works together with the kernel PPP driver to establish and maintain a PPP link with another system (called the \fIpeer\fR) and to negotiate Internet Protocol (IP) addresses for each end of the link. Pppd can also authenticate the peer and/or supply authentication information to the peer. PPP can be used with other network protocols besides IP, but such use is becoming increasingly rare. .SH FREQUENTLY USED OPTIONS .TP .I ttyname Use the serial port called \fIttyname\fR to communicate with the peer. If \fIttyname\fR does not begin with a slash (/), the string "/dev/" is prepended to \fIttyname\fR to form the name of the device to open. If no device name is given, or if the name of the terminal connected to the standard input is given, pppd will use that terminal, and will not fork to put itself in the background. A value for this option from a privileged source cannot be overridden by a non-privileged user. .TP .I speed An option that is a decimal number is taken as the desired baud rate for the serial device. On systems such as Linux, 4.4BSD and NetBSD, any speed can be specified. Other systems (e.g. SunOS) only support the commonly-used baud rates. .TP .B asyncmap \fImap This option sets the Async-Control-Character-Map (ACCM) for this end of the link. The ACCM is a set of 32 bits, one for each of the ASCII control characters with values from 0 to 31, where a 1 bit indicates that the corresponding control character should not be used in PPP packets sent to this system. The map is encoded as a hexadecimal number (without a leading 0x) where the least significant bit (00000001) represents character 0 and the most significant bit (80000000) represents character 31. Pppd will ask the peer to send these characters as a 2-byte escape sequence. If multiple \fIasyncmap\fR options are given, the values are ORed together. If no \fIasyncmap\fR option is given, the default is zero, so pppd will ask the peer not to escape any control characters. To escape transmitted characters, use the \fIescape\fR option. .TP .B auth Require the peer to authenticate itself before allowing network packets to be sent or received. This option is the default if the system has a default route. If neither this option nor the \fInoauth\fR option is specified, pppd will only allow the peer to use IP addresses to which the system does not already have a route. .TP .B call \fIname Read additional options from the file /etc/ppp/peers/\fIname\fR. This file may contain privileged options, such as \fInoauth\fR, even if pppd is not being run by root. The \fIname\fR string may not begin with / or include .. as a pathname component. The format of the options file is described below. .TP .B connect \fIscript Usually there is something which needs to be done to prepare the link before the PPP protocol can be started; for instance, with a dial-up modem, commands need to be sent to the modem to dial the appropriate phone number. This option specifies an command for pppd to execute (by passing it to a shell) before attempting to start PPP negotiation. The chat (8) program is often useful here, as it provides a way to send arbitrary strings to a modem and respond to received characters. A value for this option from a privileged source cannot be overridden by a non-privileged user. .TP .B crtscts Specifies that pppd should set the serial port to use hardware flow control using the RTS and CTS signals in the RS-232 interface. If neither the \fIcrtscts\fR, the \fInocrtscts\fR, the \fIcdtrcts\fR nor the \fInocdtrcts\fR option is given, the hardware flow control setting for the serial port is left unchanged. Some serial ports (such as Macintosh serial ports) lack a true RTS output. Such serial ports use this mode to implement unidirectional flow control. The serial port will suspend transmission when requested by the modem (via CTS) but will be unable to request the modem to stop sending to the computer. This mode retains the ability to use DTR as a modem control line. .TP .B defaultroute Add a default route to the system routing tables, using the peer as the gateway, when IPCP negotiation is successfully completed. This entry is removed when the PPP connection is broken. This option is privileged if the \fInodefaultroute\fR option has been specified. .TP .B defaultroute-metric Define the metric of the \fIdefaultroute\fR and only add it if there is no other default route with the same metric. With the default value of -1, the route is only added if there is no default route at all. .TP .B replacedefaultroute This option is a flag to the defaultroute option. If defaultroute is set and this flag is also set, pppd replaces an existing default route with the new default route. This option is privileged. .TP .B disconnect \fIscript Execute the command specified by \fIscript\fR, by passing it to a shell, after pppd has terminated the link. This command could, for example, issue commands to the modem to cause it to hang up if hardware modem control signals were not available. The disconnect script is not run if the modem has already hung up. A value for this option from a privileged source cannot be overridden by a non-privileged user. .TP .B escape \fIxx,yy,... Specifies that certain characters should be escaped on transmission (regardless of whether the peer requests them to be escaped with its async control character map). The characters to be escaped are specified as a list of hex numbers separated by commas. Note that almost any character can be specified for the \fIescape\fR option, unlike the \fIasyncmap\fR option which only allows control characters to be specified. The characters which may not be escaped are those with hex values 0x20 - 0x3f or 0x5e. .TP .B file \fIname Read options from file \fIname\fR (the format is described below). The file must be readable by the user who has invoked pppd. .TP .B init \fIscript Execute the command specified by \fIscript\fR, by passing it to a shell, to initialize the serial line. This script would typically use the chat(8) program to configure the modem to enable auto answer. A value for this option from a privileged source cannot be overridden by a non-privileged user. .TP .B lock Specifies that pppd should create a UUCP-style lock file for the serial device to ensure exclusive access to the device. By default, pppd will not create a lock file. .TP .B mru \fIn Set the MRU [Maximum Receive Unit] value to \fIn\fR. Pppd will ask the peer to send packets of no more than \fIn\fR bytes. The value of \fIn\fR must be between 128 and 16384; the default is 1500. A value of 296 works well on very slow links (40 bytes for TCP/IP header + 256 bytes of data). Note that for the IPv6 protocol, the MRU must be at least 1280. .TP .B mtu \fIn Set the MTU [Maximum Transmit Unit] value to \fIn\fR. Unless the peer requests a smaller value via MRU negotiation, pppd will request that the kernel networking code send data packets of no more than \fIn\fR bytes through the PPP network interface. Note that for the IPv6 protocol, the MTU must be at least 1280. .TP .B passive Enables the "passive" option in the LCP. With this option, pppd will attempt to initiate a connection; if no reply is received from the peer, pppd will then just wait passively for a valid LCP packet from the peer, instead of exiting, as it would without this option. .SH OPTIONS .TP .I \fB:\fI Set the local and/or remote interface IP addresses. Either one may be omitted. The IP addresses can be specified with a host name or in decimal dot notation (e.g. 150.234.56.78). The default local address is the (first) IP address of the system (unless the \fInoipdefault\fR option is given). The remote address will be obtained from the peer if not specified in any option. Thus, in simple cases, this option is not required. If a local and/or remote IP address is specified with this option, pppd will not accept a different value from the peer in the IPCP negotiation, unless the \fIipcp\-accept\-local\fR and/or \fIipcp\-accept\-remote\fR options are given, respectively. .TP .B +ipv6 Enable the IPv6CP and IPv6 protocols. .TP .B ipv6 \fI\fR,\fI Set the local and/or remote 64-bit interface identifier. Either one may be omitted. The identifier must be specified in standard ASCII notation of IPv6 addresses (e.g. ::dead:beef). If the \fIipv6cp\-use\-ipaddr\fR option is given, the local identifier is the local IPv4 address and the remote identifier is the remote IPv4 address (see above). If the \fIipv6cp-use-remotenumber\fR option is given, the remote identifier is set to the value from \fIremotenumber\fR option. On systems which supports a unique persistent id, such as EUI\-48 derived from the Ethernet MAC address, \fIipv6cp\-use\-persistent\fR option can be used to set local identifier. Otherwise both local and remote identifiers are randomized. .TP .B active\-filter \fIfilter\-expression Specifies a packet filter to be applied to data packets to determine which packets are to be regarded as link activity, and therefore reset the idle timer, or cause the link to be brought up in demand-dialling mode. This option is useful in conjunction with the \fBidle\fR option if there are packets being sent or received regularly over the link (for example, routing information packets) which would otherwise prevent the link from ever appearing to be idle. The \fIfilter\-expression\fR syntax is as described for tcpdump(1), except that qualifiers which are inappropriate for a PPP link, such as \fBether\fR and \fBarp\fR, are not permitted. Generally the filter expression should be enclosed in single-quotes to prevent whitespace in the expression from being interpreted by the shell. This option is currently only available under Linux, and requires that the kernel was configured to include PPP filtering support (CONFIG_PPP_FILTER). Note that it is possible to apply different constraints to incoming and outgoing packets using the \fBinbound\fR and \fBoutbound\fR qualifiers. .TP .B allow\-ip \fIaddress(es) Allow peers to use the given IP address or subnet without authenticating themselves. The parameter is parsed as for each element of the list of allowed IP addresses in the secrets files (see the AUTHENTICATION section below). .TP .B allow\-number \fInumber Allow peers to connect from the given telephone number. A trailing `*' character will match all numbers beginning with the leading part. .TP .B bsdcomp \fInr,nt Request that the peer compress packets that it sends, using the BSD-Compress scheme, with a maximum code size of \fInr\fR bits, and agree to compress packets sent to the peer with a maximum code size of \fInt\fR bits. If \fInt\fR is not specified, it defaults to the value given for \fInr\fR. Values in the range 9 to 15 may be used for \fInr\fR and \fInt\fR; larger values give better compression but consume more kernel memory for compression dictionaries. Alternatively, a value of 0 for \fInr\fR or \fInt\fR disables compression in the corresponding direction. Use \fInobsdcomp\fR or \fIbsdcomp 0\fR to disable BSD-Compress compression entirely. .TP .B ca \fIca-file (EAP-TLS, or PEAP) Use the file \fIca-file\fR as the X.509 Certificate Authority (CA) file (in PEM format), needed for setting up an EAP-TLS connection. This option is used on the client-side in conjunction with the \fBcert\fR and \fBkey\fR options. Either \fIca\fR, or \fIcapath\fR options are required for PEAP. EAP-TLS may also use the entry in eaptls-client or eaptls-server for a CA certificate associated with a particular peer. .TP .B capath \fIpath (EAP-TLS, or PEAP) Specify a location that contains public CA certificates. Either \fIca\fR, or \fIcapath\fR options are required for PEAP. .TP .B cdtrcts Use a non-standard hardware flow control (i.e. DTR/CTS) to control the flow of data on the serial port. If neither the \fIcrtscts\fR, the \fInocrtscts\fR, the \fIcdtrcts\fR nor the \fInocdtrcts\fR option is given, the hardware flow control setting for the serial port is left unchanged. Some serial ports (such as Macintosh serial ports) lack a true RTS output. Such serial ports use this mode to implement true bi-directional flow control. The sacrifice is that this flow control mode does not permit using DTR as a modem control line. .TP .B cert \fIcertfile (EAP-TLS) Use the file \fIcertfile\fR as the X.509 certificate (in PEM format), needed for setting up an EAP-TLS connection. This option is used on the client-side in conjunction with the \fBca\fR and \fBkey\fR options. .TP .B chap\-interval \fIn If this option is given, pppd will rechallenge the peer every \fIn\fR seconds. .TP .B chap\-max\-challenge \fIn Set the maximum number of CHAP challenge transmissions to \fIn\fR (default 10). .TP .B chap\-restart \fIn Set the CHAP restart interval (retransmission timeout for challenges) to \fIn\fR seconds (default 3). .TP .B chap-timeout \fIn Set timeout for CHAP authentication by peer to \fIn\fR seconds (default 60). .TP .B chapms\-strip\-domain Some Windows 9x/ME clients might be transmitting the MS domain before the username in the provided client name. This option enables stripping the domain from the client name on the server side before matching it against the secret file. .TP .B child\-timeout \fIn When exiting, wait for up to \fIn\fR seconds for any child processes (such as the command specified with the \fBpty\fR command) to exit before exiting. At the end of the timeout, pppd will send a SIGTERM signal to any remaining child processes and exit. A value of 0 means no timeout, that is, pppd will wait until all child processes have exited. .TP .B connect\-delay \fIn Wait for up to \fIn\fR milliseconds after the connect script finishes for a valid PPP packet from the peer. At the end of this time, or when a valid PPP packet is received from the peer, pppd will commence negotiation by sending its first LCP packet. The default value is 1000 (1 second). This wait period only applies if the \fBconnect\fR or \fBpty\fR option is used. .TP .B crl \fIfilename (EAP-TLS, or PEAP) Use the file \fIfilename\fR as the Certificate Revocation List to check for the validity of the peer's certificate. This option is not mandatory for setting up a TLS connection. Also see the \fBcrl-dir\fR option. .TP .B crl-dir \fIdirectory (EAP-TLS, or PEAP) Use the directory \fIdirectory\fR to scan for CRL files in has format ($hash.r0) to check for the validity of the peer's certificate. This option is not mandatory for setting up a TLS connection. Also see the \fBcrl\fR option. .TP .B debug Enables connection debugging facilities. If this option is given, pppd will log the contents of all control packets sent or received in a readable form. The packets are logged through syslog with facility \fIdaemon\fR and level \fIdebug\fR. This information can be directed to a file by setting up /etc/syslog.conf appropriately (see syslog.conf(5)). .TP .B default\-asyncmap Disable asyncmap negotiation, forcing all control characters to be escaped for both the transmit and the receive direction. .TP .B default\-mru Disable MRU [Maximum Receive Unit] negotiation. With this option, pppd will use the default MRU value of 1500 bytes for both the transmit and receive direction. .TP .B defaultroute6 Add a default IPv6 route to the system routing tables, using the peer as the gateway, when IPv6CP negotiation is successfully completed. This entry is removed when the PPP connection is broken. This option is privileged if the \fInodefaultroute6\fR option has been specified. \fBWARNING: Do not enable this option by default\fR. IPv6 routing tables are managed by kernel (as apposite to IPv4) and IPv6 default route is configured by kernel automatically too based on ICMPv6 Router Advertisement packets. This option may conflict with kernel IPv6 route setup and should be used only for broken IPv6 networks. .TP .B deflate \fInr,nt Request that the peer compress packets that it sends, using the Deflate scheme, with a maximum window size of \fI2**nr\fR bytes, and agree to compress packets sent to the peer with a maximum window size of \fI2**nt\fR bytes. If \fInt\fR is not specified, it defaults to the value given for \fInr\fR. Values in the range 9 to 15 may be used for \fInr\fR and \fInt\fR; larger values give better compression but consume more kernel memory for compression dictionaries. Alternatively, a value of 0 for \fInr\fR or \fInt\fR disables compression in the corresponding direction. Use \fInodeflate\fR or \fIdeflate 0\fR to disable Deflate compression entirely. (Note: pppd requests Deflate compression in preference to BSD-Compress if the peer can do either.) .TP .B demand Initiate the link only on demand, i.e. when data traffic is present. With this option, the remote IP address may be specified by the user on the command line or in an options file, or if not, pppd will use an arbitrary address in the 10.x.x.x range. Pppd will initially configure the interface and enable it for IP traffic without connecting to the peer. When traffic is available, pppd will connect to the peer and perform negotiation, authentication, etc. When this is completed, pppd will commence passing data packets (i.e., IP packets) across the link. The \fIdemand\fR option implies the \fIpersist\fR option. If this behaviour is not desired, use the \fInopersist\fR option after the \fIdemand\fR option. The \fIidle\fR and \fIholdoff\fR options are also useful in conjunction with the \fIdemand\fR option. .TP .B domain \fId Append the domain name \fId\fR to the local host name for authentication purposes. For example, if gethostname() returns the name porsche, but the fully qualified domain name is porsche.Quotron.COM, you could specify \fIdomain Quotron.COM\fR. Pppd would then use the name \fIporsche.Quotron.COM\fR for looking up secrets in the secrets file, and as the default name to send to the peer when authenticating itself to the peer. This option is privileged. .TP .B dryrun With the \fBdryrun\fR option, pppd will print out all the option values which have been set and then exit, after parsing the command line and options files and checking the option values, but before initiating the link. The option values are logged at level info, and also printed to standard output unless the device on standard output is the device that pppd would be using to communicate with the peer. .TP .B dump With the \fBdump\fR option, pppd will print out all the option values which have been set. This option is like the \fBdryrun\fR option except that pppd proceeds as normal rather than exiting. .TP .B enable-session Enables session accounting via PAM or wtwp/wtmpx, as appropriate. When PAM is enabled, the PAM "account" and "session" module stacks determine behavior, and are enabled for all PPP authentication protocols. When PAM is disabled, wtmp/wtmpx entries are recorded regardless of whether the peer name identifies a valid user on the local system, making peers visible in the last(1) log. This feature is automatically enabled when the pppd \fBlogin\fR option is used. Session accounting is disabled by default. .TP .B endpoint \fI Sets the endpoint discriminator sent by the local machine to the peer during multilink negotiation to \fI\fR. The default is to use the MAC address of the first ethernet interface on the system, if any, otherwise the IPv4 address corresponding to the hostname, if any, provided it is not in the multicast or locally-assigned IP address ranges, or the localhost address. The endpoint discriminator can be the string \fBnull\fR or of the form \fItype\fR:\fIvalue\fR, where type is a decimal number or one of the strings \fBlocal\fR, \fBIP\fR, \fBMAC\fR, \fBmagic\fR, or \fBphone\fR. The value is an IP address in dotted-decimal notation for the \fBIP\fR type, or a string of bytes in hexadecimal, separated by periods or colons for the other types. For the MAC type, the value may also be the name of an ethernet or similar network interface. This option is currently only available under Linux. .TP .B eap\-interval \fIn If this option is given and pppd authenticates the peer with EAP (i.e., is the server), pppd will restart EAP authentication every \fIn\fR seconds. For EAP SRP\-SHA1, see also the \fBsrp\-interval\fR option, which enables lightweight rechallenge. .TP .B eap\-max\-rreq \fIn Set the maximum number of EAP Requests to which pppd will respond (as a client) without hearing EAP Success or Failure. (Default is 20.) .TP .B eap\-max\-sreq \fIn Set the maximum number of EAP Requests that pppd will issue (as a server) while attempting authentication. (Default is 10.) .TP .B eap\-restart \fIn Set the retransmit timeout for EAP Requests when acting as a server (authenticator). (Default is 3 seconds.) .TP .B eap\-timeout \fIn Set the maximum time to wait for the peer to send an EAP Request when acting as a client (authenticatee). (Default is 20 seconds.) .TP .B hide\-password When logging the contents of PAP packets, this option causes pppd to exclude the password string from the log. This is the default. .TP .B holdoff \fIn Specifies how many seconds to wait before re-initiating the link after it terminates. This option only has any effect if the \fIpersist\fR or \fIdemand\fR option is used. The holdoff period is not applied if the link was terminated because it was idle. .TP .B idle \fIn Specifies that pppd should disconnect if the link is idle for \fIn\fR seconds. The link is idle when no data packets (i.e. IP packets) are being sent or received. Note: it is not advisable to use this option with the \fIpersist\fR option without the \fIdemand\fR option. If the \fBactive\-filter\fR option is given, data packets which are rejected by the specified activity filter also count as the link being idle. .TP .B ipcp\-accept\-local With this option, pppd will accept the peer's idea of our local IP address, even if the local IP address was specified in an option. .TP .B ipcp\-accept\-remote With this option, pppd will accept the peer's idea of its (remote) IP address, even if the remote IP address was specified in an option. .TP .B ipcp\-max\-configure \fIn Set the maximum number of IPCP configure-request transmissions to \fIn\fR (default 10). .TP .B ipcp\-max\-failure \fIn Set the maximum number of IPCP configure-NAKs returned before starting to send configure-Rejects instead to \fIn\fR (default 10). .TP .B ipcp\-max\-terminate \fIn Set the maximum number of IPCP terminate-request transmissions to \fIn\fR (default 3). .TP .B ipcp\-no\-address Disable negotiation of addresses via IP-Address IPCP option. .TP .B ipcp\-no\-addresses Disable negotiation of addresses via old-style deprecated IP-Addresses IPCP option. pppd by default try to use new-style IP-Address IPCP option. If new-style is not supported by peer or is disabled by \fBipcp\-no\-address\fR option then pppd fallbacks to old-style deprecated IP-Addresses IPCP option. When both new-style and old-style are disabled by both \fBipcp\-no\-address\fR and \fBipcp\-no\-addresses\fR options then negotiation of IP addresses is completely disabled. .TP .B ipcp\-restart \fIn Set the IPCP restart interval (retransmission timeout) to \fIn\fR seconds (default 3). .TP .B ipparam \fIstring Provides an extra parameter most of the notification scripts, most notably ip\-up, ip\-pre\-up, ip\-down, ipv6\-up, ipv6\-down, auth\-up and auth\-down scripts. If this option is given, the \fIstring\fR supplied is given as the 6th parameter to those scripts. .TP .B ipv6cp\-accept\-local With this option, pppd will accept the peer's idea of our local IPv6 interface identifier, even if the local IPv6 interface identifier was specified in an option. .TP .B ipv6cp\-accept\-remote With this option, pppd will accept the peer's idea of its (remote) IPv6 interface identifier, even if the remote IPv6 interface identifier was specified in an option. .TP .B ipv6cp\-noremote Allow pppd to operate without having an IPv6 link local address for the peer. This option is only available under Linux. Normally, pppd will request the peer's IPv6 interface identifier (used for composing IPv6 link local address), and if the peer does not supply it, pppd will generate one for the peer. With this option, if the peer does not supply its IPv6 interface identifier, pppd will not ask the peer for it, and will not set the destination IPv6 link local address of the ppp interface. In this situation, the ppp interface can be used for routing by creating device routes, but the peer itself cannot be addressed directly for IPv6 traffic until the peer starts announcing ICMPv6 Router Advertisement or ICMPv6 Neighbor Advertisement packets. Note that IPv6 router must announce ICMPv6 Router Advertisement packets. .TP .B ipv6cp\-nosendip Don't send our local IPv6 interface identifier to peer during IPv6 interface identifier negotiation. .TP .B ipv6cp\-max\-configure \fIn Set the maximum number of IPv6CP configure-request transmissions to \fIn\fR (default 10). .TP .B ipv6cp\-max\-failure \fIn Set the maximum number of IPv6CP configure-NAKs returned before starting to send configure-Rejects instead to \fIn\fR (default 10). .TP .B ipv6cp\-max\-terminate \fIn Set the maximum number of IPv6CP terminate-request transmissions to \fIn\fR (default 3). .TP .B ipv6cp\-restart \fIn Set the IPv6CP restart interval (retransmission timeout) to \fIn\fR seconds (default 3). .TP .B kdebug \fIn Enable debugging code in the kernel-level PPP driver. The argument values depend on the specific kernel driver, but in general a value of 1 will enable general kernel debug messages. (Note that these messages are usually only useful for debugging the kernel driver itself.) For the Linux 2.2.x kernel driver, the value is a sum of bits: 1 to enable general debug messages, 2 to request that the contents of received packets be printed, and 4 to request that the contents of transmitted packets be printed. On most systems, messages printed by the kernel are logged by syslog(1) to a file as directed in the /etc/syslog.conf configuration file. .TP .B key \fIkeyfile (EAP-TLS) Use the file \fIkeyfile\fR as the private key file (in PEM format), needed for setting up an EAP-TLS connection. This option is used on the client-side in conjunction with the \fBca\fR and \fBcert\fR options. .TP .B ktune Enables pppd to alter kernel settings as appropriate. Under Linux, pppd will enable IP forwarding (i.e. set /proc/sys/net/ipv4/ip_forward to 1) if the \fIproxyarp\fR option is used, and will enable the dynamic IP address option (i.e. set /proc/sys/net/ipv4/ip_dynaddr to 1) in demand mode if the local address changes. .TP .B lcp\-echo\-adaptive If this option is used with the \fIlcp\-echo\-failure\fR option then pppd will send LCP echo\-request frames only if no traffic was received from the peer since the last echo\-request was sent. .TP .B lcp\-echo\-failure \fIn If this option is given, pppd will presume the peer to be dead if \fIn\fR LCP echo\-requests are sent without receiving a valid LCP echo\-reply. If this happens, pppd will terminate the connection. Use of this option requires a non-zero value for the \fIlcp\-echo\-interval\fR parameter. This option can be used to enable pppd to terminate after the physical connection has been broken (e.g., the modem has hung up) in situations where no hardware modem control lines are available. .TP .B lcp\-echo\-interval \fIn If this option is given, pppd will send an LCP echo\-request frame to the peer every \fIn\fR seconds. Normally the peer should respond to the echo\-request by sending an echo\-reply. This option can be used with the \fIlcp\-echo\-failure\fR option to detect that the peer is no longer connected. .TP .B lcp\-max\-configure \fIn Set the maximum number of LCP configure-request transmissions to \fIn\fR (default 10). .TP .B lcp\-max\-failure \fIn Set the maximum number of LCP configure-NAKs returned before starting to send configure-Rejects instead to \fIn\fR (default 10). .TP .B lcp\-max\-terminate \fIn Set the maximum number of LCP terminate-request transmissions to \fIn\fR (default 3). .TP .B lcp\-restart \fIn Set the LCP restart interval (retransmission timeout) to \fIn\fR seconds (default 3). .TP .B linkname \fIname\fR Sets the logical name of the link to \fIname\fR. Pppd will create a file named \fBppp\-\fIname\fB.pid\fR in /var/run (or /etc/ppp on some systems) containing its process ID. This can be useful in determining which instance of pppd is responsible for the link to a given peer system. This is a privileged option. .TP .B local Don't use the modem control lines. With this option, pppd will ignore the state of the CD (Carrier Detect) signal from the modem and will not change the state of the DTR (Data Terminal Ready) signal. This is the opposite of the \fBmodem\fR option. .TP .B logfd \fIn Send log messages to file descriptor \fIn\fR. Pppd will send log messages to at most one file or file descriptor (as well as sending the log messages to syslog), so this option and the \fBlogfile\fR option are mutually exclusive. The default is for pppd to send log messages to stdout (file descriptor 1), unless the serial port is already open on stdout. .TP .B logfile \fIfilename Append log messages to the file \fIfilename\fR (as well as sending the log messages to syslog). The file is opened with the privileges of the user who invoked pppd, in append mode. .TP .B login Use the system password database for authenticating the peer using PAP, and record the user in the system wtmp file. Note that the peer must have an entry in the /etc/ppp/pap\-secrets file as well as the system password database to be allowed access. See also the \fBenable\-session\fR option. .TP .B master_detach If multilink is enabled and this pppd process is the multilink bundle master, and the link controlled by this pppd process terminates, this pppd process continues to run in order to maintain the bundle. If the \fBmaster_detach\fR option has been given, pppd will detach from its controlling terminal in this situation, even if the \fBnodetach\fR option has been given. .TP .B maxconnect \fIn Terminate the connection when it has been available for network traffic for \fIn\fR seconds (i.e. \fIn\fR seconds after the first network control protocol comes up). .TP .B maxfail \fIn Terminate after \fIn\fR consecutive failed connection attempts. A value of 0 means no limit. The default value is 10. .TP .B max-tls-version \fIstring (EAP-TLS, or PEAP) Configures the max allowed TLS version used during negotiation with a peer. The default value for this is \fI1.2\fR. Values allowed for this option is \fI1.0.\fR, \fI1.1\fR, \fI1.2\fR, \fI1.3\fR. .TP .B modem Use the modem control lines. This option is the default. With this option, pppd will wait for the CD (Carrier Detect) signal from the modem to be asserted when opening the serial device (unless a connect script is specified), and it will drop the DTR (Data Terminal Ready) signal briefly when the connection is terminated and before executing the connect script. On Ultrix, this option implies hardware flow control, as for the \fIcrtscts\fR option. This is the opposite of the \fBlocal\fR option. .TP .B mp Enables the use of PPP multilink; this is an alias for the `multilink' option. This option is currently only available under Linux. .TP .B mppe\-stateful Allow MPPE to use stateful mode. Stateless mode is still attempted first. The default is to disallow stateful mode. .TP .B mpshortseq Enables the use of short (12-bit) sequence numbers in multilink headers, as opposed to 24-bit sequence numbers. This option is only available under Linux, and only has any effect if multilink is enabled (see the multilink option). .TP .B mrru \fIn Sets the Maximum Reconstructed Receive Unit to \fIn\fR. The MRRU is the maximum size for a received packet on a multilink bundle, and is analogous to the MRU for the individual links. This option is currently only available under Linux, and only has any effect if multilink is enabled (see the multilink option). .TP .B ms\-dns \fI If pppd is acting as a server for Microsoft Windows clients, this option allows pppd to supply one or two DNS (Domain Name Server) addresses to the clients. The first instance of this option specifies the primary DNS address; the second instance (if given) specifies the secondary DNS address. (This option was present in some older versions of pppd under the name \fBdns\-addr\fR.) .TP .B ms\-wins \fI If pppd is acting as a server for Microsoft Windows or "Samba" clients, this option allows pppd to supply one or two WINS (Windows Internet Name Services) server addresses to the clients. The first instance of this option specifies the primary WINS address; the second instance (if given) specifies the secondary WINS address. .TP .B multilink Enables the use of the PPP multilink protocol. If the peer also supports multilink, then this link can become part of a bundle between the local system and the peer. If there is an existing bundle to the peer, pppd will join this link to that bundle, otherwise pppd will create a new bundle. See the MULTILINK section below. This option is currently only available under Linux. .TP .B name \fIname Set the name of the local system for authentication purposes to \fIname\fR. This is a privileged option. With this option, pppd will use lines in the secrets files which have \fIname\fR as the second field when looking for a secret to use in authenticating the peer. In addition, unless overridden with the \fIuser\fR option, \fIname\fR will be used as the name to send to the peer when authenticating the local system to the peer. (Note that pppd does not append the domain name to \fIname\fR.) .TP .B noaccomp Disable Address/Control compression in both directions (send and receive). .TP .B need-peer-eap (EAP-TLS) Require the peer to verify our authentication credentials. .TP .B noauth Do not require the peer to authenticate itself. This option is privileged. .TP .B nobsdcomp Disables BSD-Compress compression; \fBpppd\fR will not request or agree to compress packets using the BSD-Compress scheme. .TP .B noccp Disable CCP (Compression Control Protocol) negotiation. This option should only be required if the peer is buggy and gets confused by requests from pppd for CCP negotiation. .TP .B nocrtscts Disable hardware flow control (i.e. RTS/CTS) on the serial port. If neither the \fIcrtscts\fR nor the \fInocrtscts\fR nor the \fIcdtrcts\fR nor the \fInocdtrcts\fR option is given, the hardware flow control setting for the serial port is left unchanged. .TP .B nocdtrcts This option is a synonym for \fInocrtscts\fR. Either of these options will disable both forms of hardware flow control. .TP .B nodefaultroute Disable the \fIdefaultroute\fR option. The system administrator who wishes to prevent users from adding a default route with pppd can do so by placing this option in the /etc/ppp/options file. .TP .B noreplacedefaultroute Disable the \fIreplacedefaultroute\fR option. This allows to disable a \fIreplacedefaultroute\fR option set previously in the configuration. .TP .B nodefaultroute6 Disable the \fIdefaultroute6\fR option. The system administrator who wishes to prevent users from adding a default route with pppd can do so by placing this option in the /etc/ppp/options file. .TP .B nodeflate Disables Deflate compression; pppd will not request or agree to compress packets using the Deflate scheme. .TP .B nodetach Don't detach from the controlling terminal. Without this option, if a serial device other than the terminal on the standard input is specified, pppd will fork to become a background process. .TP .B noendpoint Disables pppd from sending an endpoint discriminator to the peer or accepting one from the peer (see the MULTILINK section below). This option should only be required if the peer is buggy. .TP .B noip Disable IPCP negotiation and IP communication. This option should only be required if the peer is buggy and gets confused by requests from pppd for IPCP negotiation. .TP .B noipv6 Disable IPv6CP negotiation and IPv6 communication. This option should only be required if the peer is buggy and gets confused by requests from pppd for IPv6CP negotiation. .TP .B noipdefault Disables the default behaviour when no local IP address is specified, which is to determine (if possible) the local IP address from the hostname. With this option, the peer will have to supply the local IP address during IPCP negotiation (unless it specified explicitly on the command line or in an options file). .TP .B noktune Opposite of the \fIktune\fR option; disables pppd from changing system settings. .TP .B nolock Opposite of the \fIlock\fR option; specifies that pppd should not create a UUCP-style lock file for the serial device. This option is privileged. .TP .B nolog Do not send log messages to a file or file descriptor. This option cancels the \fBlogfd\fR and \fBlogfile\fR options. .TP .B nomagic Disable magic number negotiation. With this option, pppd cannot detect a looped-back line. This option should only be needed if the peer is buggy. .TP .B nomp Disables the use of PPP multilink. This option is currently only available under Linux. .TP .B nomppe Disables MPPE (Microsoft Point to Point Encryption). This is the default. .TP .B nomppe\-40 Disable 40-bit encryption with MPPE. .TP .B nomppe\-128 Disable 128-bit encryption with MPPE. .TP .B nomppe\-stateful Disable MPPE stateful mode. This is the default. .TP .B nompshortseq Disables the use of short (12-bit) sequence numbers in the PPP multilink protocol, forcing the use of 24-bit sequence numbers. This option is currently only available under Linux, and only has any effect if multilink is enabled. .TP .B nomultilink Disables the use of PPP multilink. This option is currently only available under Linux. .TP .B nopcomp Disable protocol field compression negotiation in both the receive and the transmit direction. .TP .B nopersist Exit once a connection has been made and terminated. This is the default unless the \fIpersist\fR or \fIdemand\fR option has been specified. .TP .B nopredictor1 Do not accept or agree to Predictor\-1 compression. .TP .B noproxyarp Disable the \fIproxyarp\fR option. The system administrator who wishes to prevent users from creating proxy ARP entries with pppd can do so by placing this option in the /etc/ppp/options file. .TP .B noremoteip Allow pppd to operate without having an IP address for the peer. This option is only available under Linux. Normally, pppd will request the peer's IP address, and if the peer does not supply it, pppd will use an arbitrary address in the 10.x.x.x subnet. With this option, if the peer does not supply its IP address, pppd will not ask the peer for it, and will not set the destination address of the ppp interface. In this situation, the ppp interface can be used for routing by creating device routes, but the peer itself cannot be addressed directly for IP traffic. .TP .B nosendip Don't send our local IP address to peer during IP address negotiation. .TP .B notty Normally, pppd requires a terminal device. With this option, pppd will allocate itself a pseudo-tty master/slave pair and use the slave as its terminal device. Pppd will create a child process to act as a `character shunt' to transfer characters between the pseudo-tty master and its standard input and output. Thus pppd will transmit characters on its standard output and receive characters on its standard input even if they are not terminal devices. This option increases the latency and CPU overhead of transferring data over the ppp interface as all of the characters sent and received must flow through the character shunt process. An explicit device name may not be given if this option is used. .TP .B novj Disable Van Jacobson style TCP/IP header compression in both the transmit and the receive direction. .TP .B novjccomp Disable the connection-ID compression option in Van Jacobson style TCP/IP header compression. With this option, pppd will not omit the connection-ID byte from Van Jacobson compressed TCP/IP headers, nor ask the peer to do so. .TP .B papcrypt Indicates that all secrets in the /etc/ppp/pap\-secrets file which are used for checking the identity of the peer are encrypted, and thus pppd should not accept a password which, before encryption, is identical to the secret from the /etc/ppp/pap\-secrets file. .TP .B pap\-max\-authreq \fIn Set the maximum number of PAP authenticate-request transmissions to \fIn\fR (default 10). .TP .B pap\-restart \fIn Set the PAP restart interval (retransmission timeout) to \fIn\fR seconds (default 3). .TP .B pap\-timeout \fIn Set the maximum time that pppd will wait for the peer to authenticate itself with PAP to \fIn\fR seconds (0 means no limit). .TP .B pass\-filter \fIfilter\-expression Specifies a packet filter to applied to data packets being sent or received to determine which packets should be allowed to pass. Packets which are rejected by the filter are silently discarded. This option can be used to prevent specific network daemons (such as routed) using up link bandwidth, or to provide a very basic firewall capability. The \fIfilter\-expression\fR syntax is as described for tcpdump(1), except that qualifiers which are inappropriate for a PPP link, such as \fBether\fR and \fBarp\fR, are not permitted. Generally the filter expression should be enclosed in single-quotes to prevent whitespace in the expression from being interpreted by the shell. Note that it is possible to apply different constraints to incoming and outgoing packets using the \fBinbound\fR and \fBoutbound\fR qualifiers. This option is currently only available under Linux, and requires that the kernel was configured to include PPP filtering support (CONFIG_PPP_FILTER). .TP .B password \fIpassword\-string Specifies the password to use for authenticating to the peer. Use of this option is discouraged, as the password is likely to be visible to other users on the system (for example, by using ps(1)). .TP .B persist Do not exit after a connection is terminated; instead try to reopen the connection. The \fBmaxfail\fR option still has an effect on persistent connections. .TP .B plugin \fIfilename Load the shared library object file \fIfilename\fR as a plugin. This is a privileged option. If \fIfilename\fR does not contain a slash (/), pppd will look in the \fB/usr/lib/pppd/\fIversion\fR directory for the plugin, where \fIversion\fR is the version number of pppd (for example, 2.4.2). .TP .B predictor1 Request that the peer compress frames that it sends using Predictor-1 compression, and agree to compress transmitted frames with Predictor-1 if requested. This option has no effect unless the kernel driver supports Predictor-1 compression. .TP .B privgroup \fIgroup\-name Allows members of group \fIgroup\-name\fR to use privileged options. This is a privileged option. Use of this option requires care as there is no guarantee that members of \fIgroup\-name\fR cannot use pppd to become root themselves. Consider it equivalent to putting the members of \fIgroup\-name\fR in the kmem or disk group. .TP .B proxyarp Add an entry to this system's ARP [Address Resolution Protocol] table with the IP address of the peer and the Ethernet address of this system. This will have the effect of making the peer appear to other systems to be on the local ethernet. .TP .B pty \fIscript Specifies that the command \fIscript\fR is to be used to communicate rather than a specific terminal device. Pppd will allocate itself a pseudo-tty master/slave pair and use the slave as its terminal device. The \fIscript\fR will be run in a child process with the pseudo-tty master as its standard input and output. An explicit device name may not be given if this option is used. (Note: if the \fIrecord\fR option is used in conjunction with the \fIpty\fR option, the child process will have pipes on its standard input and output.) .TP .B receive\-all With this option, pppd will accept all control characters from the peer, including those marked in the receive asyncmap. Without this option, pppd will discard those characters as specified in RFC1662. This option should only be needed if the peer is buggy. .TP .B record \fIfilename Specifies that pppd should record all characters sent and received to a file named \fIfilename\fR. This file is opened in append mode, using the user's user-ID and permissions. This option is implemented using a pseudo-tty and a process to transfer characters between the pseudo-tty and the real serial device, so it will increase the latency and CPU overhead of transferring data over the ppp interface. The characters are stored in a tagged format with timestamps, which can be displayed in readable form using the pppdump(8) program. .TP .B remotename \fIname Set the assumed name of the remote system for authentication purposes to \fIname\fR. .TP .B remotenumber \fInumber Set the assumed telephone number of the remote system for authentication purposes to \fInumber\fR. .TP .B refuse\-chap With this option, pppd will not agree to authenticate itself to the peer using CHAP. .TP .B refuse\-mschap With this option, pppd will not agree to authenticate itself to the peer using MS\-CHAP. .TP .B refuse\-mschap\-v2 With this option, pppd will not agree to authenticate itself to the peer using MS\-CHAPv2. .TP .B refuse\-eap With this option, pppd will not agree to authenticate itself to the peer using EAP. .TP .B refuse\-pap With this option, pppd will not agree to authenticate itself to the peer using PAP. .TP .B require\-chap Require the peer to authenticate itself using CHAP [Challenge Handshake Authentication Protocol] authentication. .TP .B require\-mppe Require the use of MPPE (Microsoft Point to Point Encryption). This option disables all other compression types. This option enables both 40-bit and 128-bit encryption. In order for MPPE to successfully come up, you must have authenticated with either MS\-CHAP or MS\-CHAPv2. This option is presently only supported under Linux, and only if your kernel has been configured to include MPPE support. .TP .B require\-mppe\-40 Require the use of MPPE, with 40-bit encryption. .TP .B require\-mppe\-128 Require the use of MPPE, with 128-bit encryption. .TP .B require\-mschap Require the peer to authenticate itself using MS\-CHAP [Microsoft Challenge Handshake Authentication Protocol] authentication. .TP .B require\-mschap\-v2 Require the peer to authenticate itself using MS\-CHAPv2 [Microsoft Challenge Handshake Authentication Protocol, Version 2] authentication. .TP .B require\-eap Require the peer to authenticate itself using EAP [Extensible Authentication Protocol] authentication. .TP .B require\-pap Require the peer to authenticate itself using PAP [Password Authentication Protocol] authentication. .TP .B set \fIname\fR=\fIvalue Set an environment variable for scripts that are invoked by pppd. When set by a privileged source, the variable specified by \fIname\fR cannot be changed by options contained in an unprivileged source. See also the \fIunset\fR option and the environment described in \fISCRIPTS\fR. .TP .B show\-password When logging the contents of PAP packets, this option causes pppd to show the password string in the log message. .TP .B silent With this option, pppd will not transmit LCP packets to initiate a connection until a valid LCP packet is received from the peer (as for the `passive' option with ancient versions of pppd). .TP .B srp\-interval \fIn If this parameter is given and pppd uses EAP SRP\-SHA1 to authenticate the peer (i.e., is the server), then pppd will use the optional lightweight SRP rechallenge mechanism at intervals of \fIn\fR seconds. This option is faster than \fBeap\-interval\fR reauthentication because it uses a hash\-based mechanism and does not derive a new session key. .TP .B srp\-pn\-secret \fIstring Set the long-term pseudonym-generating secret for the server. This value is optional and if set, needs to be known at the server (authenticator) side only, and should be different for each server (or poll of identical servers). It is used along with the current date to generate a key to encrypt and decrypt the client's identity contained in the pseudonym. .TP .B srp\-use\-pseudonym When operating as an EAP SRP\-SHA1 client, attempt to use the pseudonym stored in ~/.ppp_pseudonym first as the identity, and save in this file any pseudonym offered by the peer during authentication. .TP .B stop\-bits \fIn Set the number of stop bits for the serial port. Valid values are 1 or 2. The default value is 1. .TP .B sync Use synchronous HDLC serial encoding instead of asynchronous. The device used by pppd with this option must have sync support. Currently supports Microgate SyncLink adapters under Linux and FreeBSD 2.2.8 and later. .TP .B tls-verify-method \fIstring (EAP-TLS, or PEAP) Match the value specified for \fIremotename\fR to that that of the X509 certificates subject name, common name, or suffix of the common name. Respective values allowed for this option is: \fInone\fR, \fIsubject\fR, \fIname\fR, or \fIsuffix\fR. The default value for this option is \fIname\fR. .TP .B tls-verify-key-usage (EAP-TLS, or PEAP) Enables examination of peer certificate's purpose, and extended key usage attributes. .TP .B unit \fInum Sets the ppp unit number (for a ppp0 or ppp1 etc interface name) for outbound connections. If the unit is already in use a dynamically allocated number will be used. .TP .B ifname \fIstring Set the ppp interface name for outbound connections. If the interface name is already in use, or if the name cannot be used for any other reason, pppd will terminate. .TP .B unset \fIname Remove a variable from the environment variable for scripts that are invoked by pppd. When specified by a privileged source, the variable \fIname\fR cannot be set by options contained in an unprivileged source. See also the \fIset\fR option and the environment described in \fISCRIPTS\fR. .TP .B updetach With this option, pppd will detach from its controlling terminal once it has successfully established the ppp connection (to the point where the first network control protocol, usually the IP control protocol, has come up). .TP .B up_sdnotify Use this option to run pppd in systemd service units of Type=notify (\fBup_sdnotify\fR implies \fBnodetach\fR). When \fBup_sdnotify\fR is enabled, pppd will notify systemd once it has successfully established the ppp connection (to the point where the first network control protocl, usually the IP control protocol, has come up). This option is only availble when pppd is compiled with systemd support. .TP .B usehostname Enforce the use of the hostname (with domain name appended, if given) as the name of the local system for authentication purposes (overrides the \fIname\fR option). This option is not normally needed since the \fIname\fR option is privileged. .TP .B usepeerdns Ask the peer for up to 2 DNS server addresses. The addresses supplied by the peer (if any) are passed to the /etc/ppp/ip\-up script in the environment variables DNS1 and DNS2, and the environment variable USEPEERDNS will be set to 1. In addition, pppd will create an /etc/ppp/resolv.conf file containing one or two nameserver lines with the address(es) supplied by the peer. .TP .B usepeerwins Ask the peer for up to 2 WINS server addresses. The addresses supplied by the peer (if any) are passed to the /etc/ppp/ip\-up script in the environment variables WINS1 and WINS2, and the environment variable USEPEERWINS will be set to 1. .LP Please note that some modems (like the Huawei E220) requires this option in order to avoid a race condition that results in the incorrect DNS servers being assigned. .TP .B user \fIname Sets the name used for authenticating the local system to the peer to \fIname\fR. .TP .B vj\-max\-slots \fIn Sets the number of connection slots to be used by the Van Jacobson TCP/IP header compression and decompression code to \fIn\fR, which must be between 2 and 16 (inclusive). .TP .B welcome \fIscript Run the executable or shell command specified by \fIscript\fR before initiating PPP negotiation, after the connect script (if any) has completed. A value for this option from a privileged source cannot be overridden by a non-privileged user. .TP .B xonxoff Use software flow control (i.e. XON/XOFF) to control the flow of data on the serial port. .SH PPPOE OPTIONS To establish PPP link over Ethernet (PPPoE) it is needed to load pppd's \fBplugin pppoe.so\fR and then specify option \fBnic-\fIinterface\fR instead of modem options \fIttyname\fR and \fIspeed\fR. Recognized pppd's PPPoE options are: .TP .B nic-\fIinterface Use the ethernet device \fIinterface\fR to communicate with the peer. For example, establishing PPPoE link on \fIeth0\fR interface is done by specifying ppp'd option \fBnic-eth0\fR. Prefix \fBnic-\fR for this option may be avoided if interface name is unambiguous and does not look like any other pppd's option. .TP .B pppoe-service \fIname Connect to specified PPPoE service name. For backward compatibility also \fBrp_pppoe_service\fP option name is supported. .TP .B pppoe-ac \fIname Connect to specified PPPoE access concentrator name. For backward compatibility also \fBrp_pppoe_ac\fP option name is supported. .TP .B pppoe-sess \fIsessid\fP:\fImacaddr Attach to existing PPPoE session. For backward compatibility also \fBrp_pppoe_sess\fP option name is supported. .TP .B pppoe-verbose \fIn Be verbose about discovered access concentrators. When set to 2 or bigger value then dump also discovery packets. For backward compatibility also \fBrp_pppoe_verbose\fP option name is supported. .TP .B pppoe-mac \fImacaddr Connect to specified MAC address. .TP .B pppoe-host-uniq \fIstring Set the PPPoE Host-Uniq tag to the supplied hex string. By default PPPoE Host-Uniq tag is set to the pppd's process PID. For backward compatibility this option may be specified without \fBpppoe-\fP prefix. .TP .B pppoe-padi-timeout \fIn Initial timeout for discovery packets in seconds (default 5). .TP .B pppoe-padi-attempts \fIn Number of discovery attempts (default 3). .SH OPTIONS FILES Options can be taken from files as well as the command line. Pppd reads options from the files /etc/ppp/options, ~/.ppprc and /etc/ppp/options.\fIttyname\fR (in that order) before processing the options on the command line. (In fact, the command-line options are scanned to find the terminal name before the options.\fIttyname\fR file is read.) In forming the name of the options.\fIttyname\fR file, the initial /dev/ is removed from the terminal name, and any remaining / characters are replaced with dots. .PP An options file is parsed into a series of words, delimited by whitespace. Whitespace can be included in a word by enclosing the word in double-quotes ("). A backslash (\e) quotes the following character. A hash (#) starts a comment, which continues until the end of the line. There is no restriction on using the \fIfile\fR or \fIcall\fR options within an options file. .SH SECURITY .I pppd provides system administrators with sufficient access control that PPP access to a server machine can be provided to legitimate users without fear of compromising the security of the server or the network it's on. This control is provided through restrictions on which IP addresses the peer may use, based on its authenticated identity (if any), and through restrictions on which options a non-privileged user may use. Several of pppd's options are privileged, in particular those which permit potentially insecure configurations; these options are only accepted in files which are under the control of the system administrator, or if pppd is being run by root. .PP The default behaviour of pppd is to allow an unauthenticated peer to use a given IP address only if the system does not already have a route to that IP address. For example, a system with a permanent connection to the wider internet will normally have a default route, and thus all peers will have to authenticate themselves in order to set up a connection. On such a system, the \fIauth\fR option is the default. On the other hand, a system where the PPP link is the only connection to the internet will not normally have a default route, so the peer will be able to use almost any IP address without authenticating itself. .PP As indicated above, some security-sensitive options are privileged, which means that they may not be used by an ordinary non-privileged user running a setuid-root pppd, either on the command line, in the user's ~/.ppprc file, or in an options file read using the \fIfile\fR option. Privileged options may be used in /etc/ppp/options file or in an options file read using the \fIcall\fR option. If pppd is being run by the root user, privileged options can be used without restriction. .PP When opening the device, pppd uses either the invoking user's user ID or the root UID (that is, 0), depending on whether the device name was specified by the user or the system administrator. If the device name comes from a privileged source, that is, /etc/ppp/options or an options file read using the \fIcall\fR option, pppd uses full root privileges when opening the device. Thus, by creating an appropriate file under /etc/ppp/peers, the system administrator can allow users to establish a ppp connection via a device which they would not normally have permission to access. Otherwise pppd uses the invoking user's real UID when opening the device. .SH AUTHENTICATION Authentication is the process whereby one peer convinces the other of its identity. This involves the first peer sending its name to the other, together with some kind of secret information which could only come from the genuine authorized user of that name. In such an exchange, we will call the first peer the "client" and the other the "server". The client has a name by which it identifies itself to the server, and the server also has a name by which it identifies itself to the client. Generally the genuine client shares some secret (or password) with the server, and authenticates itself by proving that it knows that secret. Very often, the names used for authentication correspond to the internet hostnames of the peers, but this is not essential. .LP At present, pppd supports three authentication protocols: the Password Authentication Protocol (PAP), Challenge Handshake Authentication Protocol (CHAP), and Extensible Authentication Protocol (EAP). PAP involves the client sending its name and a cleartext password to the server to authenticate itself. In contrast, the server initiates the CHAP authentication exchange by sending a challenge to the client (the challenge packet includes the server's name). The client must respond with a response which includes its name plus a hash value derived from the shared secret and the challenge, in order to prove that it knows the secret. EAP supports CHAP-style authentication, and also includes the SRP\-SHA1 mechanism, which is resistant to dictionary-based attacks and does not require a cleartext password on the server side. .LP The PPP protocol, being symmetrical, allows both peers to require the other to authenticate itself. In that case, two separate and independent authentication exchanges will occur. The two exchanges could use different authentication protocols, and in principle, different names could be used in the two exchanges. .LP The default behaviour of pppd is to agree to authenticate if requested, and to not require authentication from the peer. However, pppd will not agree to authenticate itself with a particular protocol if it has no secrets which could be used to do so. .LP Pppd stores secrets for use in authentication in secrets files (/etc/ppp/pap\-secrets for PAP, /etc/ppp/chap\-secrets for CHAP, MS\-CHAP, MS\-CHAPv2, and EAP MD5-Challenge, and /etc/ppp/srp\-secrets for EAP SRP\-SHA1). All secrets files have the same format. The secrets files can contain secrets for pppd to use in authenticating itself to other systems, as well as secrets for pppd to use when authenticating other systems to itself. .LP Each line in a secrets file contains one secret. A given secret is specific to a particular combination of client and server - it can only be used by that client to authenticate itself to that server. Thus each line in a secrets file has at least 3 fields: the name of the client, the name of the server, and the secret. These fields may be followed by a list of the IP addresses that the specified client may use when connecting to the specified server. .LP A secrets file is parsed into words as for a options file, so the client name, server name and secrets fields must each be one word, with any embedded spaces or other special characters quoted or escaped. Note that case is significant in the client and server names and in the secret. .LP If the secret starts with an `@', what follows is assumed to be the name of a file from which to read the secret. A "*" as the client or server name matches any name. When selecting a secret, pppd takes the best match, i.e. the match with the fewest wildcards. .LP Any following words on the same line are taken to be a list of acceptable IP addresses for that client. If there are only 3 words on the line, or if the first word is "\-", then all IP addresses are disallowed. To allow any address, use "*". A word starting with "!" indicates that the specified address is \fInot\fR acceptable. An address may be followed by "/" and a number \fIn\fR, to indicate a whole subnet, i.e. all addresses which have the same value in the most significant \fIn\fR bits. In this form, the address may be followed by a plus sign ("+") to indicate that one address from the subnet is authorized, based on the ppp network interface unit number in use. In this case, the host part of the address will be set to the unit number plus one. .LP Thus a secrets file contains both secrets for use in authenticating other hosts, plus secrets which we use for authenticating ourselves to others. When pppd is authenticating the peer (checking the peer's identity), it chooses a secret with the peer's name in the first field and the name of the local system in the second field. The name of the local system defaults to the hostname, with the domain name appended if the \fIdomain\fR option is used. This default can be overridden with the \fIname\fR option, except when the \fIusehostname\fR option is used. (For EAP SRP\-SHA1, see the srp\-entry(8) utility for generating proper validator entries to be used in the "secret" field.) .LP When pppd is choosing a secret to use in authenticating itself to the peer, it first determines what name it is going to use to identify itself to the peer. This name can be specified by the user with the \fIuser\fR option. If this option is not used, the name defaults to the name of the local system, determined as described in the previous paragraph. Then pppd looks for a secret with this name in the first field and the peer's name in the second field. Pppd will know the name of the peer if CHAP or EAP authentication is being used, because the peer will have sent it in the challenge packet. However, if PAP is being used, pppd will have to determine the peer's name from the options specified by the user. The user can specify the peer's name directly with the \fIremotename\fR option. Otherwise, if the remote IP address was specified by a name (rather than in numeric form), that name will be used as the peer's name. Failing that, pppd will use the null string as the peer's name. .LP When authenticating the peer with PAP, the supplied password is first compared with the secret from the secrets file. If the password doesn't match the secret, the password is encrypted using crypt() and checked against the secret again. Thus secrets for authenticating the peer can be stored in encrypted form if desired. If the \fIpapcrypt\fR option is given, the first (unencrypted) comparison is omitted, for better security. .LP Furthermore, if the \fIlogin\fR option was specified, the username and password are also checked against the system password database. Thus, the system administrator can set up the pap\-secrets file to allow PPP access only to certain users, and to restrict the set of IP addresses that each user can use. Typically, when using the \fIlogin\fR option, the secret in /etc/ppp/pap\-secrets would be "", which will match any password supplied by the peer. This avoids the need to have the same secret in two places. .LP Authentication must be satisfactorily completed before IPCP (or any other Network Control Protocol) can be started. If the peer is required to authenticate itself, and fails to do so, pppd will terminated the link (by closing LCP). If IPCP negotiates an unacceptable IP address for the remote host, IPCP will be closed. IP packets can only be sent or received when IPCP is open. .LP In some cases it is desirable to allow some hosts which can't authenticate themselves to connect and use one of a restricted set of IP addresses, even when the local host generally requires authentication. If the peer refuses to authenticate itself when requested, pppd takes that as equivalent to authenticating with PAP using the empty string for the username and password. Thus, by adding a line to the pap\-secrets file which specifies the empty string for the client and password, it is possible to allow restricted access to hosts which refuse to authenticate themselves. .SH ROUTING .LP When IPCP negotiation is completed successfully, pppd will inform the kernel of the local and remote IP addresses for the ppp interface. This is sufficient to create a host route to the remote end of the link, which will enable the peers to exchange IP packets. Communication with other machines generally requires further modification to routing tables and/or ARP (Address Resolution Protocol) tables. In most cases the \fIdefaultroute\fR and/or \fIproxyarp\fR options are sufficient for this, but in some cases further intervention is required. The /etc/ppp/ip\-up script can be used for this. .LP Sometimes it is desirable to add a default route through the remote host, as in the case of a machine whose only connection to the Internet is through the ppp interface. The \fIdefaultroute\fR option causes pppd to create such a default route when IPCP comes up, and delete it when the link is terminated. .LP In some cases it is desirable to use proxy ARP, for example on a server machine connected to a LAN, in order to allow other hosts to communicate with the remote host. The \fIproxyarp\fR option causes pppd to look for a network interface on the same subnet as the remote host (an interface supporting broadcast and ARP, which is up and not a point-to-point or loopback interface). If found, pppd creates a permanent, published ARP entry with the IP address of the remote host and the hardware address of the network interface found. .LP When the \fIdemand\fR option is used, the interface IP addresses have already been set at the point when IPCP comes up. If pppd has not been able to negotiate the same addresses that it used to configure the interface (for example when the peer is an ISP that uses dynamic IP address assignment), pppd has to change the interface IP addresses to the negotiated addresses. This may disrupt existing connections, and the use of demand dialling with peers that do dynamic IP address assignment is not recommended. .SH MULTILINK Multilink PPP provides the capability to combine two or more PPP links between a pair of machines into a single `bundle', which appears as a single virtual PPP link which has the combined bandwidth of the individual links. Currently, multilink PPP is only supported under Linux. .LP Pppd detects that the link it is controlling is connected to the same peer as another link using the peer's endpoint discriminator and the authenticated identity of the peer (if it authenticates itself). The endpoint discriminator is a block of data which is hopefully unique for each peer. Several types of data can be used, including locally-assigned strings of bytes, IP addresses, MAC addresses, randomly strings of bytes, or E\-164 phone numbers. The endpoint discriminator sent to the peer by pppd can be set using the endpoint option. .LP In some circumstances the peer may send no endpoint discriminator or a non-unique value. The bundle option adds an extra string which is added to the peer's endpoint discriminator and authenticated identity when matching up links to be joined together in a bundle. The bundle option can also be used to allow the establishment of multiple bundles between the local system and the peer. Pppd uses a TDB database in /var/run/pppd2.tdb to match up links. .LP Assuming that multilink is enabled and the peer is willing to negotiate multilink, then when pppd is invoked to bring up the first link to the peer, it will detect that no other link is connected to the peer and create a new bundle, that is, another ppp network interface unit. When another pppd is invoked to bring up another link to the peer, it will detect the existing bundle and join its link to it. .LP If the first link terminates (for example, because of a hangup or a received LCP terminate-request) the bundle is not destroyed unless there are no other links remaining in the bundle. Rather than exiting, the first pppd keeps running after its link terminates, until all the links in the bundle have terminated. If the first pppd receives a SIGTERM or SIGINT signal, it will destroy the bundle and send a SIGHUP to the pppd processes for each of the links in the bundle. If the first pppd receives a SIGHUP signal, it will terminate its link but not the bundle. .LP Note: demand mode is not currently supported with multilink. .SH EXAMPLES .LP The following examples assume that the /etc/ppp/options file contains the \fIauth\fR option (as in the default /etc/ppp/options file in the ppp distribution). .LP Probably the most common use of pppd is to dial out to an ISP. This can be done with a command such as .IP pppd call isp .LP where the /etc/ppp/peers/isp file is set up by the system administrator to contain something like this: .IP ttyS0 19200 crtscts .br connect '/usr/sbin/chat \-v \-f /etc/ppp/chat\-isp' .br noauth .LP In this example, we are using chat to dial the ISP's modem and go through any logon sequence required. The /etc/ppp/chat\-isp file contains the script used by chat; it could for example contain something like this: .IP ABORT "NO CARRIER" .br ABORT "NO DIALTONE" .br ABORT "ERROR" .br ABORT "NO ANSWER" .br ABORT "BUSY" .br ABORT "Username/Password Incorrect" .br "" "at" .br OK "at&d0&c1" .br OK "atdt2468135" .br "name:" "^Umyuserid" .br "word:" "\eqmypassword" .br "ispts" "\eq^Uppp" .br "~\-^Uppp\-~" .LP See the chat(8) man page for details of chat scripts. .LP Pppd can also be used to provide a dial-in ppp service for users. If the users already have login accounts, the simplest way to set up the ppp service is to let the users log in to their accounts and run pppd (installed setuid-root) with a command such as .IP pppd proxyarp .LP To allow a user to use the PPP facilities, you need to allocate an IP address for that user's machine and create an entry in /etc/ppp/pap\-secrets, /etc/ppp/chap\-secrets, or /etc/ppp/srp\-secrets (depending on which authentication method the PPP implementation on the user's machine supports), so that the user's machine can authenticate itself. For example, if Joe has a machine called "joespc" that is to be allowed to dial in to the machine called "server" and use the IP address joespc.my.net, you would add an entry like this to /etc/ppp/pap\-secrets or /etc/ppp/chap\-secrets: .IP joespc server "joe's secret" joespc.my.net .LP (See srp\-entry(8) for a means to generate the server's entry when SRP\-SHA1 is in use.) Alternatively, you can create a username called (for example) "ppp", whose login shell is pppd and whose home directory is /etc/ppp. Options to be used when pppd is run this way can be put in /etc/ppp/.ppprc. .LP If your serial connection is any more complicated than a piece of wire, you may need to arrange for some control characters to be escaped. In particular, it is often useful to escape XON (^Q) and XOFF (^S), using \fIasyncmap a0000\fR. If the path includes a telnet, you probably should escape ^] as well (\fIasyncmap 200a0000\fR). If the path includes an rlogin, you will need to use the \fIescape ff\fR option on the end which is running the rlogin client, since many rlogin implementations are not transparent; they will remove the sequence [0xff, 0xff, 0x73, 0x73, followed by any 8 bytes] from the stream. .SH DIAGNOSTICS .LP Messages are sent to the syslog daemon using facility LOG_DAEMON. (This can be overridden by recompiling pppd with the macro LOG_PPP defined as the desired facility.) See the syslog(8) documentation for details of where the syslog daemon will write the messages. On most systems, the syslog daemon uses the /etc/syslog.conf file to specify the destination(s) for syslog messages. You may need to edit that file to suit. .LP The \fIdebug\fR option causes the contents of all control packets sent or received to be logged, that is, all LCP, PAP, CHAP, EAP, or IPCP packets. This can be useful if the PPP negotiation does not succeed or if authentication fails. If debugging is enabled at compile time, the \fIdebug\fR option also causes other debugging messages to be logged. .LP Debugging can also be enabled or disabled by sending a SIGUSR1 signal to the pppd process. This signal acts as a toggle. .SH EXIT STATUS The exit status of pppd is set to indicate whether any error was detected, or the reason for the link being terminated. The values used are: .TP .B 0 Pppd has detached, or otherwise the connection was successfully established and terminated at the peer's request. .TP .B 1 An immediately fatal error of some kind occurred, such as an essential system call failing, or running out of virtual memory. .TP .B 2 An error was detected in processing the options given, such as two mutually exclusive options being used. .TP .B 3 Pppd is not setuid-root and the invoking user is not root. .TP .B 4 The kernel does not support PPP, for example, the PPP kernel driver is not included or cannot be loaded. .TP .B 5 Pppd terminated because it was sent a SIGINT, SIGTERM or SIGHUP signal. .TP .B 6 The serial port could not be locked. .TP .B 7 The serial port could not be opened. .TP .B 8 The connect script failed (returned a non-zero exit status). .TP .B 9 The command specified as the argument to the \fIpty\fR option could not be run. .TP .B 10 The PPP negotiation failed, that is, it didn't reach the point where at least one network protocol (e.g. IP) was running. .TP .B 11 The peer system failed (or refused) to authenticate itself. .TP .B 12 The link was established successfully and terminated because it was idle. .TP .B 13 The link was established successfully and terminated because the connect time limit was reached. .TP .B 14 Callback was negotiated and an incoming call should arrive shortly. .TP .B 15 The link was terminated because the peer is not responding to echo requests. .TP .B 16 The link was terminated by the modem hanging up. .TP .B 17 The PPP negotiation failed because serial loopback was detected. .TP .B 18 The init script failed (returned a non-zero exit status). .TP .B 19 We failed to authenticate ourselves to the peer. .SH SCRIPTS Pppd invokes scripts at various stages in its processing which can be used to perform site-specific ancillary processing. These scripts are usually shell scripts, but could be executable code files instead. Pppd does not wait for the scripts to finish (except for the ip-pre-up script). The scripts are executed as root (with the real and effective user-id set to 0), so that they can do things such as update routing tables or run privileged daemons. Be careful that the contents of these scripts do not compromise your system's security. Pppd runs the scripts with standard input, output and error redirected to /dev/null, and with an environment that is empty except for some environment variables that give information about the link. The environment variables that pppd sets are: .TP .B DEVICE The name of the serial tty device being used. .TP .B IFNAME The name of the network interface being used. .TP .B IPLOCAL The IP address for the local end of the link. This is only set when IPCP has come up. .TP .B IPREMOTE The IP address for the remote end of the link. This is only set when IPCP has come up. .TP .B LLLOCAL The Link-Local IPv6 address for the local end of the link. This is only set when IPV6CP has come up. .TP .B LLREMOTE The Link-Local IPv6 address for the remote end of the link. This is only set when IPV6CP has come up. .TP .B PEERNAME The authenticated name of the peer. This is only set if the peer authenticates itself. .TP .B SPEED The baud rate of the tty device. .TP .B ORIG_UID The real user-id of the user who invoked pppd. .TP .B PPPLOGNAME The username of the real user-id that invoked pppd. This is always set. .P For the ip-down and auth-down scripts, pppd also sets the following variables giving statistics for the connection: .TP .B CONNECT_TIME The number of seconds from when the PPP negotiation started until the connection was terminated. .TP .B BYTES_SENT The number of bytes sent (at the level of the serial port) during the connection. .TP .B BYTES_RCVD The number of bytes received (at the level of the serial port) during the connection. .TP .B LINKNAME The logical name of the link, set with the \fIlinkname\fR option. .TP .B CALL_FILE The value of the \fIcall\fR option. .TP .B DNS1 If the peer supplies DNS server addresses, this variable is set to the first DNS server address supplied (whether or not the usepeerdns option was given). .TP .B DNS2 If the peer supplies DNS server addresses, this variable is set to the second DNS server address supplied (whether or not the usepeerdns option was given). .TP .B WINS1 If the peer supplies WINS server addresses, this variable is set to the first WINS server address supplied. .TP .B WINS2 If the peer supplies WINS server addresses, this variable is set to the second WINS server address supplied. .P .P Pppd invokes the following scripts, if they exist. It is not an error if they don't exist. .TP .B /etc/ppp/auth\-up A program or script which is executed after the remote system successfully authenticates itself. It is executed with the parameters .IP \fIinterface\-name peer\-name user\-name tty\-device speed ipparam\fR .IP Note that this script is not executed if the peer doesn't authenticate itself, for example when the \fInoauth\fR option is used. .TP .B /etc/ppp/auth\-down A program or script which is executed when the link goes down, if /etc/ppp/auth\-up was previously executed. It is executed in the same manner with the same parameters as /etc/ppp/auth\-up. .TP .B /etc/ppp/ip\-pre\-up A program or script which is executed just before the ppp network interface is brought up. It is executed with the same parameters as the ip\-up script (below). At this point the interface exists and has IP addresses assigned but is still down. This can be used to add firewall rules before any IP traffic can pass through the interface. Pppd will wait for this script to finish before bringing the interface up, so this script should run quickly. .TP .B /etc/ppp/ip\-up A program or script which is executed when the link is available for sending and receiving IP packets (that is, IPCP has come up). It is executed with the parameters .IP \fIinterface\-name tty\-device speed local\-IP\-address remote\-IP\-address ipparam\fR .TP .B /etc/ppp/ip\-down A program or script which is executed when the link is no longer available for sending and receiving IP packets. This script can be used for undoing the effects of the /etc/ppp/ip\-up and /etc/ppp/ip\-pre\-up scripts. It is invoked in the same manner and with the same parameters as the ip\-up script. .TP .B /etc/ppp/ipv6\-up Like /etc/ppp/ip\-up, except that it is executed when the link is available for sending and receiving IPv6 packets. It is executed with the parameters .IP \fIinterface\-name tty\-device speed local\-link\-local\-address remote\-link\-local\-address ipparam\fR .TP .B /etc/ppp/ipv6\-down Similar to /etc/ppp/ip\-down, but it is executed when IPv6 packets can no longer be transmitted on the link. It is executed with the same parameters as the ipv6\-up script. .TP .B /var/run/ppp\fIn\fB.pid \fR(BSD or Linux), \fB/etc/ppp/ppp\fIn\fB.pid \fR(others) Process-ID for pppd process on ppp interface unit \fIn\fR. .TP .B /var/run/ppp\-\fIname\fB.pid \fR(BSD or Linux), \fB/etc/ppp/ppp\-\fIname\fB.pid \fR(others) Process-ID for pppd process for logical link \fIname\fR (see the \fIlinkname\fR option). .TP .B /var/run/pppd2.tdb Database containing information about pppd processes, interfaces and links, used for matching links to bundles in multilink operation. May be examined by external programs to obtain information about running pppd instances, the interfaces and devices they are using, IP address assignments, etc. .B /etc/ppp/pap\-secrets Usernames, passwords and IP addresses for PAP authentication. This file should be owned by root and not readable or writable by any other user. Pppd will log a warning if this is not the case. .TP .B /etc/ppp/chap\-secrets Names, secrets and IP addresses for CHAP/MS\-CHAP/MS\-CHAPv2 authentication. As for /etc/ppp/pap\-secrets, this file should be owned by root and not readable or writable by any other user. Pppd will log a warning if this is not the case. .TP .B /etc/ppp/srp\-secrets Names, secrets, and IP addresses for EAP authentication. As for /etc/ppp/pap\-secrets, this file should be owned by root and not readable or writable by any other user. Pppd will log a warning if this is not the case. .TP .B ~/.ppp_pseudonym Saved client-side SRP\-SHA1 pseudonym. See the \fIsrp\-use\-pseudonym\fR option for details. .TP .B /etc/ppp/options System default options for pppd, read before user default options or command-line options. .TP .B ~/.ppprc User default options, read before /etc/ppp/options.\fIttyname\fR. .TP .B /etc/ppp/options.\fIttyname System default options for the serial port being used, read after ~/.ppprc. In forming the \fIttyname\fR part of this filename, an initial /dev/ is stripped from the port name (if present), and any slashes in the remaining part are converted to dots. .TP .B /etc/ppp/peers A directory containing options files which may contain privileged options, even if pppd was invoked by a user other than root. The system administrator can create options files in this directory to permit non-privileged users to dial out without requiring the peer to authenticate, but only to certain trusted peers. .SH SEE ALSO .BR chat (8), .BR pppstats (8) .TP .B RFC1144 Jacobson, V. \fICompressing TCP/IP headers for low-speed serial links.\fR February 1990. .TP .B RFC1321 Rivest, R. .I The MD5 Message-Digest Algorithm. April 1992. .TP .B RFC1332 McGregor, G. .I PPP Internet Protocol Control Protocol (IPCP). May 1992. .TP .B RFC1334 Lloyd, B.; Simpson, W.A. .I PPP authentication protocols. October 1992. .TP .B RFC1661 Simpson, W.A. .I The Point-to-Point Protocol (PPP). July 1994. .TP .B RFC1662 Simpson, W.A. .I PPP in HDLC-like Framing. July 1994. .TP .B RFC1990 Sklower, K.; et al., .I The PPP Multilink Protocol (MP). August 1996. .TP .B RFC2284 Blunk, L.; Vollbrecht, J., .I PPP Extensible Authentication Protocol (EAP). March 1998. .TP .B RFC2472 Haskin, D. .I IP Version 6 over PPP December 1998. .TP .B RFC2945 Wu, T., .I The SRP Authentication and Key Exchange System September 2000. .TP .B draft\-ietf\-pppext\-eap\-srp\-03.txt Carlson, J.; et al., .I EAP SRP\-SHA1 Authentication Protocol. July 2001. .SH NOTES Some limited degree of control can be exercised over a running pppd process by sending it a signal from the list below. .TP .B SIGINT, SIGTERM These signals cause pppd to terminate the link (by closing LCP), restore the serial device settings, and exit. If a connector or disconnector process is currently running, pppd will send the same signal to its process group, so as to terminate the connector or disconnector process. .TP .B SIGHUP This signal causes pppd to terminate the link, restore the serial device settings, and close the serial device. If the \fIpersist\fR or \fIdemand\fR option has been specified, pppd will try to reopen the serial device and start another connection (after the holdoff period). Otherwise pppd will exit. If this signal is received during the holdoff period, it causes pppd to end the holdoff period immediately. If a connector or disconnector process is running, pppd will send the same signal to its process group. .TP .B SIGUSR1 This signal toggles the state of the \fIdebug\fR option. .TP .B SIGUSR2 This signal causes pppd to renegotiate compression. This can be useful to re-enable compression after it has been disabled as a result of a fatal decompression error. (Fatal decompression errors generally indicate a bug in one or other implementation.) .SH AUTHORS Paul Mackerras (paulus@samba.org), based on earlier work by Drew Perkins, Brad Clements, Karl Fox, Greg Christy, and Brad Parker. .SH COPYRIGHT Pppd is copyrighted and made available under conditions which provide that it may be copied and used in source or binary forms provided that the conditions listed below are met. Portions of pppd are covered by the following copyright notices: .LP Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved. .br Copyright (c) 1993-2004 Paul Mackerras. All rights reserved. .br Copyright (c) 1995 Pedro Roque Marques. All rights reserved. .br Copyright (c) 1995 Eric Rosenquist. All rights reserved. .br Copyright (c) 1999 Tommi Komulainen. All rights reserved. .br Copyright (C) Andrew Tridgell 1999 .br Copyright (c) 2000 by Sun Microsystems, Inc. All rights reserved. .br Copyright (c) 2001 by Sun Microsystems, Inc. All rights reserved. .br Copyright (c) 2002 Google, Inc. All rights reserved. .LP The copyright notices contain the following statements. .LP Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: .LP 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. .LP 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. .LP 3. The name "Carnegie Mellon University" must not be used to endorse or promote products derived from this software without prior written permission. For permission or any legal details, please contact .br Office of Technology Transfer .br Carnegie Mellon University .br 5000 Forbes Avenue .br Pittsburgh, PA 15213-3890 .br (412) 268-4387, fax: (412) 268-7395 .br tech-transfer@andrew.cmu.edu .LP 3b. The name(s) of the authors of this software must not be used to endorse or promote products derived from this software without prior written permission. .LP 4. Redistributions of any form whatsoever must retain the following acknowledgements: .br "This product includes software developed by Computing Services at Carnegie Mellon University (http://www.cmu.edu/computing/)." .br "This product includes software developed by Paul Mackerras ". .br "This product includes software developed by Pedro Roque Marques ". .br "This product includes software developed by Tommi Komulainen ". .LP CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .LP THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ppp-2.5.0/pppd/Makefile.in0000644000175000017500000041070714407475314012270 00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ sbin_PROGRAMS = pppd$(EXEEXT) $(am__EXEEXT_4) check_PROGRAMS = utest_crypto$(EXEEXT) $(am__EXEEXT_1) $(am__EXEEXT_2) \ $(am__EXEEXT_3) @WITH_SRP_TRUE@am__append_1 = srp-entry @WITH_SRP_TRUE@am__append_2 = srp-entry.8 @PPP_WITH_SYSTEM_CA_PATH_TRUE@am__append_3 = -DSYSTEM_CA_PATH='"@SYSTEM_CA_PATH@"' @LINUX_TRUE@am__append_4 = sys-linux.c @LINUX_TRUE@am__append_5 = termios_linux.h @LINUX_TRUE@am__append_6 = $(CRYPT_LIBS) $(UTIL_LIBS) @SUNOS_TRUE@am__append_7 = sys-solaris.c @SUNOS_TRUE@am__append_8 = -I${top_srcdir}/include @SUNOS_TRUE@am__append_9 = -lsocket -lnsl @PPP_WITH_CHAPMS_TRUE@am__append_10 = chap_ms.c crypto_ms.c @PPP_WITH_CHAPMS_TRUE@am__append_11 = utest_chap utest_pppcrypt @PPP_WITH_CHAPMS_FALSE@@WITH_SRP_TRUE@am__append_12 = crypto_ms.c @PPP_WITH_CHAPMS_FALSE@@WITH_SRP_TRUE@am__append_13 = utest_pppcrypt @PPP_WITH_CBCP_TRUE@am__append_14 = cbcp.c @PPP_WITH_MPPE_TRUE@am__append_15 = mppe.c @PPP_WITH_FILTER_TRUE@am__append_16 = $(PCAP_CFLAGS) @PPP_WITH_FILTER_TRUE@am__append_17 = $(PCAP_LDFLAGS) @PPP_WITH_FILTER_TRUE@am__append_18 = $(PCAP_LIBS) @PPP_WITH_PLUGINS_TRUE@am__append_19 = -DPPPD_PLUGIN_DIR='"@PPPD_PLUGIN_DIR@"' @PPP_WITH_PLUGINS_TRUE@am__append_20 = -ldl @LINUX_TRUE@@PPP_WITH_PLUGINS_TRUE@am__append_21 = -Wl,-E @PPP_WITH_MULTILINK_TRUE@am__append_22 = multilink.c @PPP_WITH_TDB_TRUE@am__append_23 = tdb.c spinlock.c @PPP_WITH_IPV6CP_TRUE@am__append_24 = ipv6cp.c eui64.c @PPP_WITH_PAM_TRUE@am__append_25 = $(PAM_CFLAGS) @PPP_WITH_PAM_TRUE@am__append_26 = $(PAM_LIBS) -ldl @PPP_WITH_PAM_TRUE@am__append_27 = $(PAM_LDFLAGS) @PPP_WITH_EAPTLS_TRUE@am__append_28 = eap-tls.c tls.c @PPP_WITH_EAPTLS_FALSE@@PPP_WITH_PEAP_TRUE@am__append_29 = tls.c @PPP_WITH_PEAP_TRUE@am__append_30 = peap.c @PPP_WITH_PEAP_TRUE@am__append_31 = utest_peap @WITH_SYSTEMD_TRUE@am__append_32 = $(SYSTEMD_CFLAGS) @WITH_SYSTEMD_TRUE@am__append_33 = $(SYSTEMD_LIBS) @WITH_SRP_TRUE@am__append_34 = $(SRP_CFLAGS) @WITH_SRP_TRUE@am__append_35 = $(SRP_LDFLAGS) @WITH_SRP_TRUE@am__append_36 = $(SRP_LIBS) subdir = pppd ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_atm.m4 \ $(top_srcdir)/m4/ax_check_openssl.m4 \ $(top_srcdir)/m4/ax_check_openssl_func.m4 \ $(top_srcdir)/m4/ax_check_pam.m4 \ $(top_srcdir)/m4/ax_check_pcap.m4 \ $(top_srcdir)/m4/ax_check_srp.m4 $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/pkg.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__noinst_HEADERS_DIST) \ $(pppd_include_HEADERS) $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = config.h pppdconf.h \ $(top_builddir)/pppd/plugins/pppoe/config.h CONFIG_CLEAN_FILES = pppd.pc CONFIG_CLEAN_VPATH_FILES = @PPP_WITH_CHAPMS_TRUE@am__EXEEXT_1 = utest_chap$(EXEEXT) \ @PPP_WITH_CHAPMS_TRUE@ utest_pppcrypt$(EXEEXT) @PPP_WITH_CHAPMS_FALSE@@WITH_SRP_TRUE@am__EXEEXT_2 = \ @PPP_WITH_CHAPMS_FALSE@@WITH_SRP_TRUE@ utest_pppcrypt$(EXEEXT) @PPP_WITH_PEAP_TRUE@am__EXEEXT_3 = utest_peap$(EXEEXT) @WITH_SRP_TRUE@am__EXEEXT_4 = srp-entry$(EXEEXT) am__installdirs = "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(man8dir)" \ "$(DESTDIR)$(pkgconfigdir)" "$(DESTDIR)$(pppd_includedir)" PROGRAMS = $(sbin_PROGRAMS) LTLIBRARIES = $(noinst_LTLIBRARIES) am__DEPENDENCIES_1 = @PPP_WITH_OPENSSL_TRUE@libppp_crypto_la_DEPENDENCIES = \ @PPP_WITH_OPENSSL_TRUE@ $(am__DEPENDENCIES_1) am_libppp_crypto_la_OBJECTS = libppp_crypto_la-crypto.lo \ libppp_crypto_la-ppp-md5.lo libppp_crypto_la-ppp-md4.lo \ libppp_crypto_la-ppp-sha1.lo libppp_crypto_la-ppp-des.lo libppp_crypto_la_OBJECTS = $(am_libppp_crypto_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = libppp_crypto_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(AM_CFLAGS) $(CFLAGS) $(libppp_crypto_la_LDFLAGS) $(LDFLAGS) \ -o $@ am__pppd_SOURCES_DIST = auth.c ccp.c chap-md5.c chap.c demand.c eap.c \ ecp.c fsm.c ipcp.c lcp.c magic.c main.c options.c session.c \ tty.c upap.c utils.c sys-linux.c sys-solaris.c chap_ms.c \ crypto_ms.c cbcp.c mppe.c multilink.c tdb.c spinlock.c \ ipv6cp.c eui64.c eap-tls.c tls.c peap.c @LINUX_TRUE@am__objects_1 = pppd-sys-linux.$(OBJEXT) @SUNOS_TRUE@am__objects_2 = pppd-sys-solaris.$(OBJEXT) @PPP_WITH_CHAPMS_TRUE@am__objects_3 = pppd-chap_ms.$(OBJEXT) \ @PPP_WITH_CHAPMS_TRUE@ pppd-crypto_ms.$(OBJEXT) @PPP_WITH_CHAPMS_FALSE@@WITH_SRP_TRUE@am__objects_4 = pppd-crypto_ms.$(OBJEXT) @PPP_WITH_CBCP_TRUE@am__objects_5 = pppd-cbcp.$(OBJEXT) @PPP_WITH_MPPE_TRUE@am__objects_6 = pppd-mppe.$(OBJEXT) @PPP_WITH_MULTILINK_TRUE@am__objects_7 = pppd-multilink.$(OBJEXT) @PPP_WITH_TDB_TRUE@am__objects_8 = pppd-tdb.$(OBJEXT) \ @PPP_WITH_TDB_TRUE@ pppd-spinlock.$(OBJEXT) @PPP_WITH_IPV6CP_TRUE@am__objects_9 = pppd-ipv6cp.$(OBJEXT) \ @PPP_WITH_IPV6CP_TRUE@ pppd-eui64.$(OBJEXT) @PPP_WITH_EAPTLS_TRUE@am__objects_10 = pppd-eap-tls.$(OBJEXT) \ @PPP_WITH_EAPTLS_TRUE@ pppd-tls.$(OBJEXT) @PPP_WITH_EAPTLS_FALSE@@PPP_WITH_PEAP_TRUE@am__objects_11 = \ @PPP_WITH_EAPTLS_FALSE@@PPP_WITH_PEAP_TRUE@ pppd-tls.$(OBJEXT) @PPP_WITH_PEAP_TRUE@am__objects_12 = pppd-peap.$(OBJEXT) am_pppd_OBJECTS = pppd-auth.$(OBJEXT) pppd-ccp.$(OBJEXT) \ pppd-chap-md5.$(OBJEXT) pppd-chap.$(OBJEXT) \ pppd-demand.$(OBJEXT) pppd-eap.$(OBJEXT) pppd-ecp.$(OBJEXT) \ pppd-fsm.$(OBJEXT) pppd-ipcp.$(OBJEXT) pppd-lcp.$(OBJEXT) \ pppd-magic.$(OBJEXT) pppd-main.$(OBJEXT) \ pppd-options.$(OBJEXT) pppd-session.$(OBJEXT) \ pppd-tty.$(OBJEXT) pppd-upap.$(OBJEXT) pppd-utils.$(OBJEXT) \ $(am__objects_1) $(am__objects_2) $(am__objects_3) \ $(am__objects_4) $(am__objects_5) $(am__objects_6) \ $(am__objects_7) $(am__objects_8) $(am__objects_9) \ $(am__objects_10) $(am__objects_11) $(am__objects_12) pppd_OBJECTS = $(am_pppd_OBJECTS) @LINUX_TRUE@am__DEPENDENCIES_2 = $(am__DEPENDENCIES_1) \ @LINUX_TRUE@ $(am__DEPENDENCIES_1) @PPP_WITH_FILTER_TRUE@am__DEPENDENCIES_3 = $(am__DEPENDENCIES_1) @PPP_WITH_PAM_TRUE@am__DEPENDENCIES_4 = $(am__DEPENDENCIES_1) @WITH_SYSTEMD_TRUE@am__DEPENDENCIES_5 = $(am__DEPENDENCIES_1) @WITH_SRP_TRUE@am__DEPENDENCIES_6 = $(am__DEPENDENCIES_1) am__DEPENDENCIES_7 = $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_3) $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_4) libppp_crypto.la $(am__DEPENDENCIES_5) \ $(am__DEPENDENCIES_6) pppd_DEPENDENCIES = $(am__DEPENDENCIES_7) pppd_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(pppd_LDFLAGS) $(LDFLAGS) -o $@ am__srp_entry_SOURCES_DIST = srp-entry.c @WITH_SRP_TRUE@am_srp_entry_OBJECTS = srp_entry-srp-entry.$(OBJEXT) srp_entry_OBJECTS = $(am_srp_entry_OBJECTS) @WITH_SRP_TRUE@srp_entry_DEPENDENCIES = $(am__DEPENDENCIES_1) \ @WITH_SRP_TRUE@ $(am__DEPENDENCIES_1) srp_entry_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(srp_entry_LDFLAGS) $(LDFLAGS) -o $@ am_utest_chap_OBJECTS = utest_chap-chap_ms.$(OBJEXT) \ utest_chap-utils.$(OBJEXT) utest_chap-crypto_ms.$(OBJEXT) utest_chap_OBJECTS = $(am_utest_chap_OBJECTS) utest_chap_DEPENDENCIES = libppp_crypto.la utest_chap_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(utest_chap_LDFLAGS) $(LDFLAGS) -o $@ am_utest_crypto_OBJECTS = utest_crypto-crypto.$(OBJEXT) utest_crypto_OBJECTS = $(am_utest_crypto_OBJECTS) utest_crypto_DEPENDENCIES = libppp_crypto.la utest_crypto_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(utest_crypto_LDFLAGS) $(LDFLAGS) -o $@ am_utest_peap_OBJECTS = utest_peap-peap.$(OBJEXT) \ utest_peap-utils.$(OBJEXT) utest_peap-mppe.$(OBJEXT) utest_peap_OBJECTS = $(am_utest_peap_OBJECTS) utest_peap_DEPENDENCIES = libppp_crypto.la utest_peap_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(utest_peap_LDFLAGS) $(LDFLAGS) -o $@ am_utest_pppcrypt_OBJECTS = utest_pppcrypt-crypto_ms.$(OBJEXT) utest_pppcrypt_OBJECTS = $(am_utest_pppcrypt_OBJECTS) utest_pppcrypt_DEPENDENCIES = libppp_crypto.la utest_pppcrypt_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(AM_CFLAGS) $(CFLAGS) $(utest_pppcrypt_LDFLAGS) $(LDFLAGS) -o \ $@ AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/pppd/plugins/pppoe depcomp = $(SHELL) $(top_srcdir)/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/libppp_crypto_la-crypto.Plo \ ./$(DEPDIR)/libppp_crypto_la-ppp-des.Plo \ ./$(DEPDIR)/libppp_crypto_la-ppp-md4.Plo \ ./$(DEPDIR)/libppp_crypto_la-ppp-md5.Plo \ ./$(DEPDIR)/libppp_crypto_la-ppp-sha1.Plo \ ./$(DEPDIR)/pppd-auth.Po ./$(DEPDIR)/pppd-cbcp.Po \ ./$(DEPDIR)/pppd-ccp.Po ./$(DEPDIR)/pppd-chap-md5.Po \ ./$(DEPDIR)/pppd-chap.Po ./$(DEPDIR)/pppd-chap_ms.Po \ ./$(DEPDIR)/pppd-crypto_ms.Po ./$(DEPDIR)/pppd-demand.Po \ ./$(DEPDIR)/pppd-eap-tls.Po ./$(DEPDIR)/pppd-eap.Po \ ./$(DEPDIR)/pppd-ecp.Po ./$(DEPDIR)/pppd-eui64.Po \ ./$(DEPDIR)/pppd-fsm.Po ./$(DEPDIR)/pppd-ipcp.Po \ ./$(DEPDIR)/pppd-ipv6cp.Po ./$(DEPDIR)/pppd-lcp.Po \ ./$(DEPDIR)/pppd-magic.Po ./$(DEPDIR)/pppd-main.Po \ ./$(DEPDIR)/pppd-mppe.Po ./$(DEPDIR)/pppd-multilink.Po \ ./$(DEPDIR)/pppd-options.Po ./$(DEPDIR)/pppd-peap.Po \ ./$(DEPDIR)/pppd-session.Po ./$(DEPDIR)/pppd-spinlock.Po \ ./$(DEPDIR)/pppd-sys-linux.Po ./$(DEPDIR)/pppd-sys-solaris.Po \ ./$(DEPDIR)/pppd-tdb.Po ./$(DEPDIR)/pppd-tls.Po \ ./$(DEPDIR)/pppd-tty.Po ./$(DEPDIR)/pppd-upap.Po \ ./$(DEPDIR)/pppd-utils.Po ./$(DEPDIR)/srp_entry-srp-entry.Po \ ./$(DEPDIR)/utest_chap-chap_ms.Po \ ./$(DEPDIR)/utest_chap-crypto_ms.Po \ ./$(DEPDIR)/utest_chap-utils.Po \ ./$(DEPDIR)/utest_crypto-crypto.Po \ ./$(DEPDIR)/utest_peap-mppe.Po ./$(DEPDIR)/utest_peap-peap.Po \ ./$(DEPDIR)/utest_peap-utils.Po \ ./$(DEPDIR)/utest_pppcrypt-crypto_ms.Po am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libppp_crypto_la_SOURCES) $(pppd_SOURCES) \ $(srp_entry_SOURCES) $(utest_chap_SOURCES) \ $(utest_crypto_SOURCES) $(utest_peap_SOURCES) \ $(utest_pppcrypt_SOURCES) DIST_SOURCES = $(libppp_crypto_la_SOURCES) $(am__pppd_SOURCES_DIST) \ $(am__srp_entry_SOURCES_DIST) $(utest_chap_SOURCES) \ $(utest_crypto_SOURCES) $(utest_peap_SOURCES) \ $(utest_pppcrypt_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } man8dir = $(mandir)/man8 NROFF = nroff MANS = $(dist_man8_MANS) DATA = $(pkgconfig_DATA) am__noinst_HEADERS_DIST = chap-md5.h crypto-priv.h eap-tls.h \ pathnames.h peap.h pppd-private.h spinlock.h tls.h tdb.h \ termios_linux.h HEADERS = $(noinst_HEADERS) $(pppd_include_HEADERS) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) \ config.h.in pppdconf.h.in # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__tty_colors_dummy = \ mgn= red= grn= lgn= blu= brg= std=; \ am__color_tests=no am__tty_colors = { \ $(am__tty_colors_dummy); \ if test "X$(AM_COLOR_TESTS)" = Xno; then \ am__color_tests=no; \ elif test "X$(AM_COLOR_TESTS)" = Xalways; then \ am__color_tests=yes; \ elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \ am__color_tests=yes; \ fi; \ if test $$am__color_tests = yes; then \ red=''; \ grn=''; \ lgn=''; \ blu=''; \ mgn=''; \ brg=''; \ std=''; \ fi; \ } am__recheck_rx = ^[ ]*:recheck:[ ]* am__global_test_result_rx = ^[ ]*:global-test-result:[ ]* am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]* # A command that, given a newline-separated list of test names on the # standard input, print the name of the tests that are to be re-run # upon "make recheck". am__list_recheck_tests = $(AWK) '{ \ recheck = 1; \ while ((rc = (getline line < ($$0 ".trs"))) != 0) \ { \ if (rc < 0) \ { \ if ((getline line2 < ($$0 ".log")) < 0) \ recheck = 0; \ break; \ } \ else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \ { \ recheck = 0; \ break; \ } \ else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \ { \ break; \ } \ }; \ if (recheck) \ print $$0; \ close ($$0 ".trs"); \ close ($$0 ".log"); \ }' # A command that, given a newline-separated list of test names on the # standard input, create the global log from their .trs and .log files. am__create_global_log = $(AWK) ' \ function fatal(msg) \ { \ print "fatal: making $@: " msg | "cat >&2"; \ exit 1; \ } \ function rst_section(header) \ { \ print header; \ len = length(header); \ for (i = 1; i <= len; i = i + 1) \ printf "="; \ printf "\n\n"; \ } \ { \ copy_in_global_log = 1; \ global_test_result = "RUN"; \ while ((rc = (getline line < ($$0 ".trs"))) != 0) \ { \ if (rc < 0) \ fatal("failed to read from " $$0 ".trs"); \ if (line ~ /$(am__global_test_result_rx)/) \ { \ sub("$(am__global_test_result_rx)", "", line); \ sub("[ ]*$$", "", line); \ global_test_result = line; \ } \ else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \ copy_in_global_log = 0; \ }; \ if (copy_in_global_log) \ { \ rst_section(global_test_result ": " $$0); \ while ((rc = (getline line < ($$0 ".log"))) != 0) \ { \ if (rc < 0) \ fatal("failed to read from " $$0 ".log"); \ print line; \ }; \ printf "\n"; \ }; \ close ($$0 ".trs"); \ close ($$0 ".log"); \ }' # Restructured Text title. am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; } # Solaris 10 'make', and several other traditional 'make' implementations, # pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it # by disabling -e (using the XSI extension "set +e") if it's set. am__sh_e_setup = case $$- in *e*) set +e;; esac # Default flags passed to test drivers. am__common_driver_flags = \ --color-tests "$$am__color_tests" \ --enable-hard-errors "$$am__enable_hard_errors" \ --expect-failure "$$am__expect_failure" # To be inserted before the command running the test. Creates the # directory for the log if needed. Stores in $dir the directory # containing $f, in $tst the test, in $log the log. Executes the # developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and # passes TESTS_ENVIRONMENT. Set up options for the wrapper that # will run the test scripts (or their associated LOG_COMPILER, if # thy have one). am__check_pre = \ $(am__sh_e_setup); \ $(am__vpath_adj_setup) $(am__vpath_adj) \ $(am__tty_colors); \ srcdir=$(srcdir); export srcdir; \ case "$@" in \ */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \ *) am__odir=.;; \ esac; \ test "x$$am__odir" = x"." || test -d "$$am__odir" \ || $(MKDIR_P) "$$am__odir" || exit $$?; \ if test -f "./$$f"; then dir=./; \ elif test -f "$$f"; then dir=; \ else dir="$(srcdir)/"; fi; \ tst=$$dir$$f; log='$@'; \ if test -n '$(DISABLE_HARD_ERRORS)'; then \ am__enable_hard_errors=no; \ else \ am__enable_hard_errors=yes; \ fi; \ case " $(XFAIL_TESTS) " in \ *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \ am__expect_failure=yes;; \ *) \ am__expect_failure=no;; \ esac; \ $(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT) # A shell command to get the names of the tests scripts with any registered # extension removed (i.e., equivalently, the names of the test logs, with # the '.log' extension removed). The result is saved in the shell variable # '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly, # we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)", # since that might cause problem with VPATH rewrites for suffix-less tests. # See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'. am__set_TESTS_bases = \ bases='$(TEST_LOGS)'; \ bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \ bases=`echo $$bases` AM_TESTSUITE_SUMMARY_HEADER = ' for $(PACKAGE_STRING)' RECHECK_LOGS = $(TEST_LOGS) AM_RECURSIVE_TARGETS = check recheck TEST_SUITE_LOG = test-suite.log TEST_EXTENSIONS = @EXEEXT@ .test LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS) am__set_b = \ case '$@' in \ */*) \ case '$*' in \ */*) b='$*';; \ *) b=`echo '$@' | sed 's/\.log$$//'`; \ esac;; \ *) \ b='$*';; \ esac am__test_logs1 = $(TESTS:=.log) am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log) TEST_LOGS = $(am__test_logs2:.test.log=.log) TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \ $(TEST_LOG_FLAGS) am__DIST_COMMON = $(dist_man8_MANS) $(srcdir)/Makefile.in \ $(srcdir)/config.h.in $(srcdir)/pppd.pc.in \ $(srcdir)/pppdconf.h.in $(top_srcdir)/depcomp \ $(top_srcdir)/test-driver DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ ATM_CFLAGS = @ATM_CFLAGS@ ATM_LDFLAGS = @ATM_LDFLAGS@ ATM_LIBS = @ATM_LIBS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CRYPT_LIBS = @CRYPT_LIBS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GREP = @GREP@ GTK_CFLAGS = @GTK_CFLAGS@ GTK_LIBS = @GTK_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_INCLUDES = @OPENSSL_INCLUDES@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAM_CFLAGS = @PAM_CFLAGS@ PAM_LDFLAGS = @PAM_LDFLAGS@ PAM_LIBS = @PAM_LIBS@ PATH_SEPARATOR = @PATH_SEPARATOR@ PCAP_CFLAGS = @PCAP_CFLAGS@ PCAP_LDFLAGS = @PCAP_LDFLAGS@ PCAP_LIBS = @PCAP_LIBS@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PPPD_LOGFILE_DIR = @PPPD_LOGFILE_DIR@ PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@ PPPD_RUNTIME_DIR = @PPPD_RUNTIME_DIR@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SRP_CFLAGS = @SRP_CFLAGS@ SRP_LDFLAGS = @SRP_LDFLAGS@ SRP_LIBS = @SRP_LIBS@ STRIP = @STRIP@ SYSTEMD_CFLAGS = @SYSTEMD_CFLAGS@ SYSTEMD_LIBS = @SYSTEMD_LIBS@ SYSTEM_CA_PATH = @SYSTEM_CA_PATH@ UTIL_LIBS = @UTIL_LIBS@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ dist_man8_MANS = pppd.8 $(am__append_2) utest_chap_SOURCES = chap_ms.c utils.c crypto_ms.c utest_chap_CPPFLAGS = -DUNIT_TEST utest_chap_LDFLAGS = utest_peap_SOURCES = peap.c utils.c mppe.c utest_peap_CPPFLAGS = -DUNIT_TEST utest_peap_LDFLAGS = utest_crypto_SOURCES = crypto.c utest_crypto_CPPFLAGS = -DUNIT_TEST utest_crypto_LDFLAGS = utest_pppcrypt_SOURCES = crypto_ms.c utest_pppcrypt_CPPFLAGS = -DUNIT_TEST_MSCRYPTO utest_pppcrypt_LDFLAGS = pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = pppd.pc pppd_includedir = $(includedir)/pppd pppd_include_HEADERS = \ cbcp.h \ ccp.h \ chap.h \ chap_ms.h \ crypto.h \ crypto_ms.h \ eap.h \ ecp.h \ eui64.h \ fsm.h \ ipcp.h \ ipv6cp.h \ lcp.h \ magic.h \ mppe.h \ multilink.h \ pppd.h \ options.h \ pppdconf.h \ session.h \ upap.h # Headers to be distributed, but not installed in /usr/include/pppd noinst_HEADERS = chap-md5.h crypto-priv.h eap-tls.h pathnames.h peap.h \ pppd-private.h spinlock.h tls.h tdb.h $(am__append_5) pppd_SOURCES = auth.c ccp.c chap-md5.c chap.c demand.c eap.c ecp.c \ fsm.c ipcp.c lcp.c magic.c main.c options.c session.c tty.c \ upap.c utils.c $(am__append_4) $(am__append_7) \ $(am__append_10) $(am__append_12) $(am__append_14) \ $(am__append_15) $(am__append_22) $(am__append_23) \ $(am__append_24) $(am__append_28) $(am__append_29) \ $(am__append_30) pppd_CPPFLAGS = -DSYSCONFDIR=\"${sysconfdir}\" \ -DLOCALSTATEDIR=\"${localstatedir}\" \ -DPPPD_RUNTIME_DIR='"@PPPD_RUNTIME_DIR@"' \ -DPPPD_LOGFILE_DIR='"@PPPD_LOGFILE_DIR@"' $(am__append_3) \ $(am__append_8) $(am__append_16) $(am__append_19) \ $(am__append_25) $(am__append_32) $(am__append_34) pppd_LDFLAGS = $(am__append_17) $(am__append_21) $(am__append_27) \ $(am__append_35) pppd_LIBS = $(am__append_6) $(am__append_9) $(am__append_18) \ $(am__append_20) $(am__append_26) libppp_crypto.la \ $(am__append_33) $(am__append_36) noinst_LTLIBRARIES = libppp_crypto.la libppp_crypto_la_SOURCES = crypto.c ppp-md5.c ppp-md4.c ppp-sha1.c ppp-des.c @PPP_WITH_OPENSSL_TRUE@libppp_crypto_la_CPPFLAGS = $(OPENSSL_INCLUDES) @PPP_WITH_OPENSSL_TRUE@libppp_crypto_la_LDFLAGS = $(OPENSSL_LDFLAGS) @PPP_WITH_OPENSSL_TRUE@libppp_crypto_la_LIBADD = $(OPENSSL_LIBS) utest_peap_LDADD = libppp_crypto.la utest_chap_LDADD = libppp_crypto.la utest_crypto_LDADD = libppp_crypto.la utest_pppcrypt_LDADD = libppp_crypto.la @WITH_SRP_TRUE@srp_entry_SOURCES = srp-entry.c @WITH_SRP_TRUE@srp_entry_CPPFLAGS = $(OPENSSL_INCLUDES) $(SRP_CFLAGS) @WITH_SRP_TRUE@srp_entry_LDADD = $(SRP_LIBS) $(OPENSSL_LIBS) @WITH_SRP_TRUE@srp_entry_LDFLAGS = $(OPENSSL_LDFLAGS) $(SRP_LDFLAGS) pppd_LDADD = $(pppd_LIBS) EXTRA_DIST = \ ppp.pam TESTS = $(check_PROGRAMS) all: config.h pppdconf.h $(MAKE) $(AM_MAKEFLAGS) all-am .SUFFIXES: .SUFFIXES: .c .lo .log .o .obj .test .test$(EXEEXT) .trs $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu pppd/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu pppd/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): config.h: stamp-h1 @test -f $@ || rm -f stamp-h1 @test -f $@ || $(MAKE) $(AM_MAKEFLAGS) stamp-h1 stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status @rm -f stamp-h1 cd $(top_builddir) && $(SHELL) ./config.status pppd/config.h $(srcdir)/config.h.in: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) ($(am__cd) $(top_srcdir) && $(AUTOHEADER)) rm -f stamp-h1 touch $@ pppdconf.h: stamp-h2 @test -f $@ || rm -f stamp-h2 @test -f $@ || $(MAKE) $(AM_MAKEFLAGS) stamp-h2 stamp-h2: $(srcdir)/pppdconf.h.in $(top_builddir)/config.status @rm -f stamp-h2 cd $(top_builddir) && $(SHELL) ./config.status pppd/pppdconf.h distclean-hdr: -rm -f config.h stamp-h1 pppdconf.h stamp-h2 pppd.pc: $(top_builddir)/config.status $(srcdir)/pppd.pc.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ clean-checkPROGRAMS: @list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \ echo " rm -f" $$list; \ rm -f $$list || exit $$?; \ test -n "$(EXEEXT)" || exit 0; \ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list install-sbinPROGRAMS: $(sbin_PROGRAMS) @$(NORMAL_INSTALL) @list='$(sbin_PROGRAMS)'; test -n "$(sbindir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(sbindir)'"; \ $(MKDIR_P) "$(DESTDIR)$(sbindir)" || exit 1; \ fi; \ for p in $$list; do echo "$$p $$p"; done | \ sed 's/$(EXEEXT)$$//' | \ while read p p1; do if test -f $$p \ || test -f $$p1 \ ; then echo "$$p"; echo "$$p"; else :; fi; \ done | \ sed -e 'p;s,.*/,,;n;h' \ -e 's|.*|.|' \ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ if ($$2 == $$4) files[d] = files[d] " " $$1; \ else { print "f", $$3 "/" $$4, $$1; } } \ END { for (d in files) print "f", d, files[d] }' | \ while read type dir files; do \ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ test -z "$$files" || { \ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(sbindir)$$dir'"; \ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(sbindir)$$dir" || exit $$?; \ } \ ; done uninstall-sbinPROGRAMS: @$(NORMAL_UNINSTALL) @list='$(sbin_PROGRAMS)'; test -n "$(sbindir)" || list=; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ -e 's/$$/$(EXEEXT)/' \ `; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(sbindir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(sbindir)" && rm -f $$files clean-sbinPROGRAMS: @list='$(sbin_PROGRAMS)'; test -n "$$list" || exit 0; \ echo " rm -f" $$list; \ rm -f $$list || exit $$?; \ test -n "$(EXEEXT)" || exit 0; \ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libppp_crypto.la: $(libppp_crypto_la_OBJECTS) $(libppp_crypto_la_DEPENDENCIES) $(EXTRA_libppp_crypto_la_DEPENDENCIES) $(AM_V_CCLD)$(libppp_crypto_la_LINK) $(libppp_crypto_la_OBJECTS) $(libppp_crypto_la_LIBADD) $(LIBS) pppd$(EXEEXT): $(pppd_OBJECTS) $(pppd_DEPENDENCIES) $(EXTRA_pppd_DEPENDENCIES) @rm -f pppd$(EXEEXT) $(AM_V_CCLD)$(pppd_LINK) $(pppd_OBJECTS) $(pppd_LDADD) $(LIBS) srp-entry$(EXEEXT): $(srp_entry_OBJECTS) $(srp_entry_DEPENDENCIES) $(EXTRA_srp_entry_DEPENDENCIES) @rm -f srp-entry$(EXEEXT) $(AM_V_CCLD)$(srp_entry_LINK) $(srp_entry_OBJECTS) $(srp_entry_LDADD) $(LIBS) utest_chap$(EXEEXT): $(utest_chap_OBJECTS) $(utest_chap_DEPENDENCIES) $(EXTRA_utest_chap_DEPENDENCIES) @rm -f utest_chap$(EXEEXT) $(AM_V_CCLD)$(utest_chap_LINK) $(utest_chap_OBJECTS) $(utest_chap_LDADD) $(LIBS) utest_crypto$(EXEEXT): $(utest_crypto_OBJECTS) $(utest_crypto_DEPENDENCIES) $(EXTRA_utest_crypto_DEPENDENCIES) @rm -f utest_crypto$(EXEEXT) $(AM_V_CCLD)$(utest_crypto_LINK) $(utest_crypto_OBJECTS) $(utest_crypto_LDADD) $(LIBS) utest_peap$(EXEEXT): $(utest_peap_OBJECTS) $(utest_peap_DEPENDENCIES) $(EXTRA_utest_peap_DEPENDENCIES) @rm -f utest_peap$(EXEEXT) $(AM_V_CCLD)$(utest_peap_LINK) $(utest_peap_OBJECTS) $(utest_peap_LDADD) $(LIBS) utest_pppcrypt$(EXEEXT): $(utest_pppcrypt_OBJECTS) $(utest_pppcrypt_DEPENDENCIES) $(EXTRA_utest_pppcrypt_DEPENDENCIES) @rm -f utest_pppcrypt$(EXEEXT) $(AM_V_CCLD)$(utest_pppcrypt_LINK) $(utest_pppcrypt_OBJECTS) $(utest_pppcrypt_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libppp_crypto_la-crypto.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libppp_crypto_la-ppp-des.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libppp_crypto_la-ppp-md4.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libppp_crypto_la-ppp-md5.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libppp_crypto_la-ppp-sha1.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pppd-auth.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pppd-cbcp.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pppd-ccp.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pppd-chap-md5.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pppd-chap.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pppd-chap_ms.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pppd-crypto_ms.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pppd-demand.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pppd-eap-tls.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pppd-eap.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pppd-ecp.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pppd-eui64.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pppd-fsm.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pppd-ipcp.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pppd-ipv6cp.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pppd-lcp.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pppd-magic.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pppd-main.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pppd-mppe.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pppd-multilink.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pppd-options.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pppd-peap.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pppd-session.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pppd-spinlock.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pppd-sys-linux.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pppd-sys-solaris.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pppd-tdb.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pppd-tls.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pppd-tty.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pppd-upap.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pppd-utils.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/srp_entry-srp-entry.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/utest_chap-chap_ms.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/utest_chap-crypto_ms.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/utest_chap-utils.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/utest_crypto-crypto.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/utest_peap-mppe.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/utest_peap-peap.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/utest_peap-utils.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/utest_pppcrypt-crypto_ms.Po@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< libppp_crypto_la-crypto.lo: crypto.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libppp_crypto_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libppp_crypto_la-crypto.lo -MD -MP -MF $(DEPDIR)/libppp_crypto_la-crypto.Tpo -c -o libppp_crypto_la-crypto.lo `test -f 'crypto.c' || echo '$(srcdir)/'`crypto.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libppp_crypto_la-crypto.Tpo $(DEPDIR)/libppp_crypto_la-crypto.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='crypto.c' object='libppp_crypto_la-crypto.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libppp_crypto_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libppp_crypto_la-crypto.lo `test -f 'crypto.c' || echo '$(srcdir)/'`crypto.c libppp_crypto_la-ppp-md5.lo: ppp-md5.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libppp_crypto_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libppp_crypto_la-ppp-md5.lo -MD -MP -MF $(DEPDIR)/libppp_crypto_la-ppp-md5.Tpo -c -o libppp_crypto_la-ppp-md5.lo `test -f 'ppp-md5.c' || echo '$(srcdir)/'`ppp-md5.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libppp_crypto_la-ppp-md5.Tpo $(DEPDIR)/libppp_crypto_la-ppp-md5.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ppp-md5.c' object='libppp_crypto_la-ppp-md5.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libppp_crypto_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libppp_crypto_la-ppp-md5.lo `test -f 'ppp-md5.c' || echo '$(srcdir)/'`ppp-md5.c libppp_crypto_la-ppp-md4.lo: ppp-md4.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libppp_crypto_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libppp_crypto_la-ppp-md4.lo -MD -MP -MF $(DEPDIR)/libppp_crypto_la-ppp-md4.Tpo -c -o libppp_crypto_la-ppp-md4.lo `test -f 'ppp-md4.c' || echo '$(srcdir)/'`ppp-md4.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libppp_crypto_la-ppp-md4.Tpo $(DEPDIR)/libppp_crypto_la-ppp-md4.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ppp-md4.c' object='libppp_crypto_la-ppp-md4.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libppp_crypto_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libppp_crypto_la-ppp-md4.lo `test -f 'ppp-md4.c' || echo '$(srcdir)/'`ppp-md4.c libppp_crypto_la-ppp-sha1.lo: ppp-sha1.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libppp_crypto_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libppp_crypto_la-ppp-sha1.lo -MD -MP -MF $(DEPDIR)/libppp_crypto_la-ppp-sha1.Tpo -c -o libppp_crypto_la-ppp-sha1.lo `test -f 'ppp-sha1.c' || echo '$(srcdir)/'`ppp-sha1.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libppp_crypto_la-ppp-sha1.Tpo $(DEPDIR)/libppp_crypto_la-ppp-sha1.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ppp-sha1.c' object='libppp_crypto_la-ppp-sha1.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libppp_crypto_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libppp_crypto_la-ppp-sha1.lo `test -f 'ppp-sha1.c' || echo '$(srcdir)/'`ppp-sha1.c libppp_crypto_la-ppp-des.lo: ppp-des.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libppp_crypto_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libppp_crypto_la-ppp-des.lo -MD -MP -MF $(DEPDIR)/libppp_crypto_la-ppp-des.Tpo -c -o libppp_crypto_la-ppp-des.lo `test -f 'ppp-des.c' || echo '$(srcdir)/'`ppp-des.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libppp_crypto_la-ppp-des.Tpo $(DEPDIR)/libppp_crypto_la-ppp-des.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ppp-des.c' object='libppp_crypto_la-ppp-des.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libppp_crypto_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libppp_crypto_la-ppp-des.lo `test -f 'ppp-des.c' || echo '$(srcdir)/'`ppp-des.c pppd-auth.o: auth.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pppd-auth.o -MD -MP -MF $(DEPDIR)/pppd-auth.Tpo -c -o pppd-auth.o `test -f 'auth.c' || echo '$(srcdir)/'`auth.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pppd-auth.Tpo $(DEPDIR)/pppd-auth.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='auth.c' object='pppd-auth.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pppd-auth.o `test -f 'auth.c' || echo '$(srcdir)/'`auth.c pppd-auth.obj: auth.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pppd-auth.obj -MD -MP -MF $(DEPDIR)/pppd-auth.Tpo -c -o pppd-auth.obj `if test -f 'auth.c'; then $(CYGPATH_W) 'auth.c'; else $(CYGPATH_W) '$(srcdir)/auth.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pppd-auth.Tpo $(DEPDIR)/pppd-auth.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='auth.c' object='pppd-auth.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pppd-auth.obj `if test -f 'auth.c'; then $(CYGPATH_W) 'auth.c'; else $(CYGPATH_W) '$(srcdir)/auth.c'; fi` pppd-ccp.o: ccp.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pppd-ccp.o -MD -MP -MF $(DEPDIR)/pppd-ccp.Tpo -c -o pppd-ccp.o `test -f 'ccp.c' || echo '$(srcdir)/'`ccp.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pppd-ccp.Tpo $(DEPDIR)/pppd-ccp.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ccp.c' object='pppd-ccp.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pppd-ccp.o `test -f 'ccp.c' || echo '$(srcdir)/'`ccp.c pppd-ccp.obj: ccp.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pppd-ccp.obj -MD -MP -MF $(DEPDIR)/pppd-ccp.Tpo -c -o pppd-ccp.obj `if test -f 'ccp.c'; then $(CYGPATH_W) 'ccp.c'; else $(CYGPATH_W) '$(srcdir)/ccp.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pppd-ccp.Tpo $(DEPDIR)/pppd-ccp.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ccp.c' object='pppd-ccp.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pppd-ccp.obj `if test -f 'ccp.c'; then $(CYGPATH_W) 'ccp.c'; else $(CYGPATH_W) '$(srcdir)/ccp.c'; fi` pppd-chap-md5.o: chap-md5.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pppd-chap-md5.o -MD -MP -MF $(DEPDIR)/pppd-chap-md5.Tpo -c -o pppd-chap-md5.o `test -f 'chap-md5.c' || echo '$(srcdir)/'`chap-md5.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pppd-chap-md5.Tpo $(DEPDIR)/pppd-chap-md5.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='chap-md5.c' object='pppd-chap-md5.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pppd-chap-md5.o `test -f 'chap-md5.c' || echo '$(srcdir)/'`chap-md5.c pppd-chap-md5.obj: chap-md5.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pppd-chap-md5.obj -MD -MP -MF $(DEPDIR)/pppd-chap-md5.Tpo -c -o pppd-chap-md5.obj `if test -f 'chap-md5.c'; then $(CYGPATH_W) 'chap-md5.c'; else $(CYGPATH_W) '$(srcdir)/chap-md5.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pppd-chap-md5.Tpo $(DEPDIR)/pppd-chap-md5.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='chap-md5.c' object='pppd-chap-md5.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pppd-chap-md5.obj `if test -f 'chap-md5.c'; then $(CYGPATH_W) 'chap-md5.c'; else $(CYGPATH_W) '$(srcdir)/chap-md5.c'; fi` pppd-chap.o: chap.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pppd-chap.o -MD -MP -MF $(DEPDIR)/pppd-chap.Tpo -c -o pppd-chap.o `test -f 'chap.c' || echo '$(srcdir)/'`chap.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pppd-chap.Tpo $(DEPDIR)/pppd-chap.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='chap.c' object='pppd-chap.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pppd-chap.o `test -f 'chap.c' || echo '$(srcdir)/'`chap.c pppd-chap.obj: chap.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pppd-chap.obj -MD -MP -MF $(DEPDIR)/pppd-chap.Tpo -c -o pppd-chap.obj `if test -f 'chap.c'; then $(CYGPATH_W) 'chap.c'; else $(CYGPATH_W) '$(srcdir)/chap.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pppd-chap.Tpo $(DEPDIR)/pppd-chap.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='chap.c' object='pppd-chap.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pppd-chap.obj `if test -f 'chap.c'; then $(CYGPATH_W) 'chap.c'; else $(CYGPATH_W) '$(srcdir)/chap.c'; fi` pppd-demand.o: demand.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pppd-demand.o -MD -MP -MF $(DEPDIR)/pppd-demand.Tpo -c -o pppd-demand.o `test -f 'demand.c' || echo '$(srcdir)/'`demand.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pppd-demand.Tpo $(DEPDIR)/pppd-demand.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='demand.c' object='pppd-demand.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pppd-demand.o `test -f 'demand.c' || echo '$(srcdir)/'`demand.c pppd-demand.obj: demand.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pppd-demand.obj -MD -MP -MF $(DEPDIR)/pppd-demand.Tpo -c -o pppd-demand.obj `if test -f 'demand.c'; then $(CYGPATH_W) 'demand.c'; else $(CYGPATH_W) '$(srcdir)/demand.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pppd-demand.Tpo $(DEPDIR)/pppd-demand.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='demand.c' object='pppd-demand.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pppd-demand.obj `if test -f 'demand.c'; then $(CYGPATH_W) 'demand.c'; else $(CYGPATH_W) '$(srcdir)/demand.c'; fi` pppd-eap.o: eap.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pppd-eap.o -MD -MP -MF $(DEPDIR)/pppd-eap.Tpo -c -o pppd-eap.o `test -f 'eap.c' || echo '$(srcdir)/'`eap.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pppd-eap.Tpo $(DEPDIR)/pppd-eap.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='eap.c' object='pppd-eap.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pppd-eap.o `test -f 'eap.c' || echo '$(srcdir)/'`eap.c pppd-eap.obj: eap.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pppd-eap.obj -MD -MP -MF $(DEPDIR)/pppd-eap.Tpo -c -o pppd-eap.obj `if test -f 'eap.c'; then $(CYGPATH_W) 'eap.c'; else $(CYGPATH_W) '$(srcdir)/eap.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pppd-eap.Tpo $(DEPDIR)/pppd-eap.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='eap.c' object='pppd-eap.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pppd-eap.obj `if test -f 'eap.c'; then $(CYGPATH_W) 'eap.c'; else $(CYGPATH_W) '$(srcdir)/eap.c'; fi` pppd-ecp.o: ecp.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pppd-ecp.o -MD -MP -MF $(DEPDIR)/pppd-ecp.Tpo -c -o pppd-ecp.o `test -f 'ecp.c' || echo '$(srcdir)/'`ecp.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pppd-ecp.Tpo $(DEPDIR)/pppd-ecp.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ecp.c' object='pppd-ecp.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pppd-ecp.o `test -f 'ecp.c' || echo '$(srcdir)/'`ecp.c pppd-ecp.obj: ecp.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pppd-ecp.obj -MD -MP -MF $(DEPDIR)/pppd-ecp.Tpo -c -o pppd-ecp.obj `if test -f 'ecp.c'; then $(CYGPATH_W) 'ecp.c'; else $(CYGPATH_W) '$(srcdir)/ecp.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pppd-ecp.Tpo $(DEPDIR)/pppd-ecp.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ecp.c' object='pppd-ecp.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pppd-ecp.obj `if test -f 'ecp.c'; then $(CYGPATH_W) 'ecp.c'; else $(CYGPATH_W) '$(srcdir)/ecp.c'; fi` pppd-fsm.o: fsm.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pppd-fsm.o -MD -MP -MF $(DEPDIR)/pppd-fsm.Tpo -c -o pppd-fsm.o `test -f 'fsm.c' || echo '$(srcdir)/'`fsm.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pppd-fsm.Tpo $(DEPDIR)/pppd-fsm.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fsm.c' object='pppd-fsm.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pppd-fsm.o `test -f 'fsm.c' || echo '$(srcdir)/'`fsm.c pppd-fsm.obj: fsm.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pppd-fsm.obj -MD -MP -MF $(DEPDIR)/pppd-fsm.Tpo -c -o pppd-fsm.obj `if test -f 'fsm.c'; then $(CYGPATH_W) 'fsm.c'; else $(CYGPATH_W) '$(srcdir)/fsm.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pppd-fsm.Tpo $(DEPDIR)/pppd-fsm.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fsm.c' object='pppd-fsm.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pppd-fsm.obj `if test -f 'fsm.c'; then $(CYGPATH_W) 'fsm.c'; else $(CYGPATH_W) '$(srcdir)/fsm.c'; fi` pppd-ipcp.o: ipcp.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pppd-ipcp.o -MD -MP -MF $(DEPDIR)/pppd-ipcp.Tpo -c -o pppd-ipcp.o `test -f 'ipcp.c' || echo '$(srcdir)/'`ipcp.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pppd-ipcp.Tpo $(DEPDIR)/pppd-ipcp.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ipcp.c' object='pppd-ipcp.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pppd-ipcp.o `test -f 'ipcp.c' || echo '$(srcdir)/'`ipcp.c pppd-ipcp.obj: ipcp.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pppd-ipcp.obj -MD -MP -MF $(DEPDIR)/pppd-ipcp.Tpo -c -o pppd-ipcp.obj `if test -f 'ipcp.c'; then $(CYGPATH_W) 'ipcp.c'; else $(CYGPATH_W) '$(srcdir)/ipcp.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pppd-ipcp.Tpo $(DEPDIR)/pppd-ipcp.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ipcp.c' object='pppd-ipcp.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pppd-ipcp.obj `if test -f 'ipcp.c'; then $(CYGPATH_W) 'ipcp.c'; else $(CYGPATH_W) '$(srcdir)/ipcp.c'; fi` pppd-lcp.o: lcp.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pppd-lcp.o -MD -MP -MF $(DEPDIR)/pppd-lcp.Tpo -c -o pppd-lcp.o `test -f 'lcp.c' || echo '$(srcdir)/'`lcp.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pppd-lcp.Tpo $(DEPDIR)/pppd-lcp.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='lcp.c' object='pppd-lcp.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pppd-lcp.o `test -f 'lcp.c' || echo '$(srcdir)/'`lcp.c pppd-lcp.obj: lcp.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pppd-lcp.obj -MD -MP -MF $(DEPDIR)/pppd-lcp.Tpo -c -o pppd-lcp.obj `if test -f 'lcp.c'; then $(CYGPATH_W) 'lcp.c'; else $(CYGPATH_W) '$(srcdir)/lcp.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pppd-lcp.Tpo $(DEPDIR)/pppd-lcp.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='lcp.c' object='pppd-lcp.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pppd-lcp.obj `if test -f 'lcp.c'; then $(CYGPATH_W) 'lcp.c'; else $(CYGPATH_W) '$(srcdir)/lcp.c'; fi` pppd-magic.o: magic.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pppd-magic.o -MD -MP -MF $(DEPDIR)/pppd-magic.Tpo -c -o pppd-magic.o `test -f 'magic.c' || echo '$(srcdir)/'`magic.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pppd-magic.Tpo $(DEPDIR)/pppd-magic.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='magic.c' object='pppd-magic.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pppd-magic.o `test -f 'magic.c' || echo '$(srcdir)/'`magic.c pppd-magic.obj: magic.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pppd-magic.obj -MD -MP -MF $(DEPDIR)/pppd-magic.Tpo -c -o pppd-magic.obj `if test -f 'magic.c'; then $(CYGPATH_W) 'magic.c'; else $(CYGPATH_W) '$(srcdir)/magic.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pppd-magic.Tpo $(DEPDIR)/pppd-magic.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='magic.c' object='pppd-magic.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pppd-magic.obj `if test -f 'magic.c'; then $(CYGPATH_W) 'magic.c'; else $(CYGPATH_W) '$(srcdir)/magic.c'; fi` pppd-main.o: main.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pppd-main.o -MD -MP -MF $(DEPDIR)/pppd-main.Tpo -c -o pppd-main.o `test -f 'main.c' || echo '$(srcdir)/'`main.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pppd-main.Tpo $(DEPDIR)/pppd-main.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='main.c' object='pppd-main.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pppd-main.o `test -f 'main.c' || echo '$(srcdir)/'`main.c pppd-main.obj: main.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pppd-main.obj -MD -MP -MF $(DEPDIR)/pppd-main.Tpo -c -o pppd-main.obj `if test -f 'main.c'; then $(CYGPATH_W) 'main.c'; else $(CYGPATH_W) '$(srcdir)/main.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pppd-main.Tpo $(DEPDIR)/pppd-main.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='main.c' object='pppd-main.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pppd-main.obj `if test -f 'main.c'; then $(CYGPATH_W) 'main.c'; else $(CYGPATH_W) '$(srcdir)/main.c'; fi` pppd-options.o: options.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pppd-options.o -MD -MP -MF $(DEPDIR)/pppd-options.Tpo -c -o pppd-options.o `test -f 'options.c' || echo '$(srcdir)/'`options.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pppd-options.Tpo $(DEPDIR)/pppd-options.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='options.c' object='pppd-options.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pppd-options.o `test -f 'options.c' || echo '$(srcdir)/'`options.c pppd-options.obj: options.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pppd-options.obj -MD -MP -MF $(DEPDIR)/pppd-options.Tpo -c -o pppd-options.obj `if test -f 'options.c'; then $(CYGPATH_W) 'options.c'; else $(CYGPATH_W) '$(srcdir)/options.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pppd-options.Tpo $(DEPDIR)/pppd-options.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='options.c' object='pppd-options.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pppd-options.obj `if test -f 'options.c'; then $(CYGPATH_W) 'options.c'; else $(CYGPATH_W) '$(srcdir)/options.c'; fi` pppd-session.o: session.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pppd-session.o -MD -MP -MF $(DEPDIR)/pppd-session.Tpo -c -o pppd-session.o `test -f 'session.c' || echo '$(srcdir)/'`session.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pppd-session.Tpo $(DEPDIR)/pppd-session.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='session.c' object='pppd-session.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pppd-session.o `test -f 'session.c' || echo '$(srcdir)/'`session.c pppd-session.obj: session.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pppd-session.obj -MD -MP -MF $(DEPDIR)/pppd-session.Tpo -c -o pppd-session.obj `if test -f 'session.c'; then $(CYGPATH_W) 'session.c'; else $(CYGPATH_W) '$(srcdir)/session.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pppd-session.Tpo $(DEPDIR)/pppd-session.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='session.c' object='pppd-session.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pppd-session.obj `if test -f 'session.c'; then $(CYGPATH_W) 'session.c'; else $(CYGPATH_W) '$(srcdir)/session.c'; fi` pppd-tty.o: tty.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pppd-tty.o -MD -MP -MF $(DEPDIR)/pppd-tty.Tpo -c -o pppd-tty.o `test -f 'tty.c' || echo '$(srcdir)/'`tty.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pppd-tty.Tpo $(DEPDIR)/pppd-tty.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tty.c' object='pppd-tty.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pppd-tty.o `test -f 'tty.c' || echo '$(srcdir)/'`tty.c pppd-tty.obj: tty.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pppd-tty.obj -MD -MP -MF $(DEPDIR)/pppd-tty.Tpo -c -o pppd-tty.obj `if test -f 'tty.c'; then $(CYGPATH_W) 'tty.c'; else $(CYGPATH_W) '$(srcdir)/tty.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pppd-tty.Tpo $(DEPDIR)/pppd-tty.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tty.c' object='pppd-tty.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pppd-tty.obj `if test -f 'tty.c'; then $(CYGPATH_W) 'tty.c'; else $(CYGPATH_W) '$(srcdir)/tty.c'; fi` pppd-upap.o: upap.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pppd-upap.o -MD -MP -MF $(DEPDIR)/pppd-upap.Tpo -c -o pppd-upap.o `test -f 'upap.c' || echo '$(srcdir)/'`upap.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pppd-upap.Tpo $(DEPDIR)/pppd-upap.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='upap.c' object='pppd-upap.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pppd-upap.o `test -f 'upap.c' || echo '$(srcdir)/'`upap.c pppd-upap.obj: upap.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pppd-upap.obj -MD -MP -MF $(DEPDIR)/pppd-upap.Tpo -c -o pppd-upap.obj `if test -f 'upap.c'; then $(CYGPATH_W) 'upap.c'; else $(CYGPATH_W) '$(srcdir)/upap.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pppd-upap.Tpo $(DEPDIR)/pppd-upap.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='upap.c' object='pppd-upap.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pppd-upap.obj `if test -f 'upap.c'; then $(CYGPATH_W) 'upap.c'; else $(CYGPATH_W) '$(srcdir)/upap.c'; fi` pppd-utils.o: utils.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pppd-utils.o -MD -MP -MF $(DEPDIR)/pppd-utils.Tpo -c -o pppd-utils.o `test -f 'utils.c' || echo '$(srcdir)/'`utils.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pppd-utils.Tpo $(DEPDIR)/pppd-utils.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='utils.c' object='pppd-utils.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pppd-utils.o `test -f 'utils.c' || echo '$(srcdir)/'`utils.c pppd-utils.obj: utils.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pppd-utils.obj -MD -MP -MF $(DEPDIR)/pppd-utils.Tpo -c -o pppd-utils.obj `if test -f 'utils.c'; then $(CYGPATH_W) 'utils.c'; else $(CYGPATH_W) '$(srcdir)/utils.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pppd-utils.Tpo $(DEPDIR)/pppd-utils.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='utils.c' object='pppd-utils.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pppd-utils.obj `if test -f 'utils.c'; then $(CYGPATH_W) 'utils.c'; else $(CYGPATH_W) '$(srcdir)/utils.c'; fi` pppd-sys-linux.o: sys-linux.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pppd-sys-linux.o -MD -MP -MF $(DEPDIR)/pppd-sys-linux.Tpo -c -o pppd-sys-linux.o `test -f 'sys-linux.c' || echo '$(srcdir)/'`sys-linux.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pppd-sys-linux.Tpo $(DEPDIR)/pppd-sys-linux.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='sys-linux.c' object='pppd-sys-linux.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pppd-sys-linux.o `test -f 'sys-linux.c' || echo '$(srcdir)/'`sys-linux.c pppd-sys-linux.obj: sys-linux.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pppd-sys-linux.obj -MD -MP -MF $(DEPDIR)/pppd-sys-linux.Tpo -c -o pppd-sys-linux.obj `if test -f 'sys-linux.c'; then $(CYGPATH_W) 'sys-linux.c'; else $(CYGPATH_W) '$(srcdir)/sys-linux.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pppd-sys-linux.Tpo $(DEPDIR)/pppd-sys-linux.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='sys-linux.c' object='pppd-sys-linux.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pppd-sys-linux.obj `if test -f 'sys-linux.c'; then $(CYGPATH_W) 'sys-linux.c'; else $(CYGPATH_W) '$(srcdir)/sys-linux.c'; fi` pppd-sys-solaris.o: sys-solaris.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pppd-sys-solaris.o -MD -MP -MF $(DEPDIR)/pppd-sys-solaris.Tpo -c -o pppd-sys-solaris.o `test -f 'sys-solaris.c' || echo '$(srcdir)/'`sys-solaris.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pppd-sys-solaris.Tpo $(DEPDIR)/pppd-sys-solaris.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='sys-solaris.c' object='pppd-sys-solaris.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pppd-sys-solaris.o `test -f 'sys-solaris.c' || echo '$(srcdir)/'`sys-solaris.c pppd-sys-solaris.obj: sys-solaris.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pppd-sys-solaris.obj -MD -MP -MF $(DEPDIR)/pppd-sys-solaris.Tpo -c -o pppd-sys-solaris.obj `if test -f 'sys-solaris.c'; then $(CYGPATH_W) 'sys-solaris.c'; else $(CYGPATH_W) '$(srcdir)/sys-solaris.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pppd-sys-solaris.Tpo $(DEPDIR)/pppd-sys-solaris.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='sys-solaris.c' object='pppd-sys-solaris.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pppd-sys-solaris.obj `if test -f 'sys-solaris.c'; then $(CYGPATH_W) 'sys-solaris.c'; else $(CYGPATH_W) '$(srcdir)/sys-solaris.c'; fi` pppd-chap_ms.o: chap_ms.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pppd-chap_ms.o -MD -MP -MF $(DEPDIR)/pppd-chap_ms.Tpo -c -o pppd-chap_ms.o `test -f 'chap_ms.c' || echo '$(srcdir)/'`chap_ms.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pppd-chap_ms.Tpo $(DEPDIR)/pppd-chap_ms.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='chap_ms.c' object='pppd-chap_ms.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pppd-chap_ms.o `test -f 'chap_ms.c' || echo '$(srcdir)/'`chap_ms.c pppd-chap_ms.obj: chap_ms.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pppd-chap_ms.obj -MD -MP -MF $(DEPDIR)/pppd-chap_ms.Tpo -c -o pppd-chap_ms.obj `if test -f 'chap_ms.c'; then $(CYGPATH_W) 'chap_ms.c'; else $(CYGPATH_W) '$(srcdir)/chap_ms.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pppd-chap_ms.Tpo $(DEPDIR)/pppd-chap_ms.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='chap_ms.c' object='pppd-chap_ms.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pppd-chap_ms.obj `if test -f 'chap_ms.c'; then $(CYGPATH_W) 'chap_ms.c'; else $(CYGPATH_W) '$(srcdir)/chap_ms.c'; fi` pppd-crypto_ms.o: crypto_ms.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pppd-crypto_ms.o -MD -MP -MF $(DEPDIR)/pppd-crypto_ms.Tpo -c -o pppd-crypto_ms.o `test -f 'crypto_ms.c' || echo '$(srcdir)/'`crypto_ms.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pppd-crypto_ms.Tpo $(DEPDIR)/pppd-crypto_ms.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='crypto_ms.c' object='pppd-crypto_ms.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pppd-crypto_ms.o `test -f 'crypto_ms.c' || echo '$(srcdir)/'`crypto_ms.c pppd-crypto_ms.obj: crypto_ms.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pppd-crypto_ms.obj -MD -MP -MF $(DEPDIR)/pppd-crypto_ms.Tpo -c -o pppd-crypto_ms.obj `if test -f 'crypto_ms.c'; then $(CYGPATH_W) 'crypto_ms.c'; else $(CYGPATH_W) '$(srcdir)/crypto_ms.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pppd-crypto_ms.Tpo $(DEPDIR)/pppd-crypto_ms.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='crypto_ms.c' object='pppd-crypto_ms.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pppd-crypto_ms.obj `if test -f 'crypto_ms.c'; then $(CYGPATH_W) 'crypto_ms.c'; else $(CYGPATH_W) '$(srcdir)/crypto_ms.c'; fi` pppd-cbcp.o: cbcp.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pppd-cbcp.o -MD -MP -MF $(DEPDIR)/pppd-cbcp.Tpo -c -o pppd-cbcp.o `test -f 'cbcp.c' || echo '$(srcdir)/'`cbcp.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pppd-cbcp.Tpo $(DEPDIR)/pppd-cbcp.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cbcp.c' object='pppd-cbcp.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pppd-cbcp.o `test -f 'cbcp.c' || echo '$(srcdir)/'`cbcp.c pppd-cbcp.obj: cbcp.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pppd-cbcp.obj -MD -MP -MF $(DEPDIR)/pppd-cbcp.Tpo -c -o pppd-cbcp.obj `if test -f 'cbcp.c'; then $(CYGPATH_W) 'cbcp.c'; else $(CYGPATH_W) '$(srcdir)/cbcp.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pppd-cbcp.Tpo $(DEPDIR)/pppd-cbcp.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cbcp.c' object='pppd-cbcp.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pppd-cbcp.obj `if test -f 'cbcp.c'; then $(CYGPATH_W) 'cbcp.c'; else $(CYGPATH_W) '$(srcdir)/cbcp.c'; fi` pppd-mppe.o: mppe.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pppd-mppe.o -MD -MP -MF $(DEPDIR)/pppd-mppe.Tpo -c -o pppd-mppe.o `test -f 'mppe.c' || echo '$(srcdir)/'`mppe.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pppd-mppe.Tpo $(DEPDIR)/pppd-mppe.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='mppe.c' object='pppd-mppe.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pppd-mppe.o `test -f 'mppe.c' || echo '$(srcdir)/'`mppe.c pppd-mppe.obj: mppe.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pppd-mppe.obj -MD -MP -MF $(DEPDIR)/pppd-mppe.Tpo -c -o pppd-mppe.obj `if test -f 'mppe.c'; then $(CYGPATH_W) 'mppe.c'; else $(CYGPATH_W) '$(srcdir)/mppe.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pppd-mppe.Tpo $(DEPDIR)/pppd-mppe.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='mppe.c' object='pppd-mppe.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pppd-mppe.obj `if test -f 'mppe.c'; then $(CYGPATH_W) 'mppe.c'; else $(CYGPATH_W) '$(srcdir)/mppe.c'; fi` pppd-multilink.o: multilink.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pppd-multilink.o -MD -MP -MF $(DEPDIR)/pppd-multilink.Tpo -c -o pppd-multilink.o `test -f 'multilink.c' || echo '$(srcdir)/'`multilink.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pppd-multilink.Tpo $(DEPDIR)/pppd-multilink.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='multilink.c' object='pppd-multilink.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pppd-multilink.o `test -f 'multilink.c' || echo '$(srcdir)/'`multilink.c pppd-multilink.obj: multilink.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pppd-multilink.obj -MD -MP -MF $(DEPDIR)/pppd-multilink.Tpo -c -o pppd-multilink.obj `if test -f 'multilink.c'; then $(CYGPATH_W) 'multilink.c'; else $(CYGPATH_W) '$(srcdir)/multilink.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pppd-multilink.Tpo $(DEPDIR)/pppd-multilink.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='multilink.c' object='pppd-multilink.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pppd-multilink.obj `if test -f 'multilink.c'; then $(CYGPATH_W) 'multilink.c'; else $(CYGPATH_W) '$(srcdir)/multilink.c'; fi` pppd-tdb.o: tdb.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pppd-tdb.o -MD -MP -MF $(DEPDIR)/pppd-tdb.Tpo -c -o pppd-tdb.o `test -f 'tdb.c' || echo '$(srcdir)/'`tdb.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pppd-tdb.Tpo $(DEPDIR)/pppd-tdb.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tdb.c' object='pppd-tdb.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pppd-tdb.o `test -f 'tdb.c' || echo '$(srcdir)/'`tdb.c pppd-tdb.obj: tdb.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pppd-tdb.obj -MD -MP -MF $(DEPDIR)/pppd-tdb.Tpo -c -o pppd-tdb.obj `if test -f 'tdb.c'; then $(CYGPATH_W) 'tdb.c'; else $(CYGPATH_W) '$(srcdir)/tdb.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pppd-tdb.Tpo $(DEPDIR)/pppd-tdb.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tdb.c' object='pppd-tdb.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pppd-tdb.obj `if test -f 'tdb.c'; then $(CYGPATH_W) 'tdb.c'; else $(CYGPATH_W) '$(srcdir)/tdb.c'; fi` pppd-spinlock.o: spinlock.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pppd-spinlock.o -MD -MP -MF $(DEPDIR)/pppd-spinlock.Tpo -c -o pppd-spinlock.o `test -f 'spinlock.c' || echo '$(srcdir)/'`spinlock.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pppd-spinlock.Tpo $(DEPDIR)/pppd-spinlock.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='spinlock.c' object='pppd-spinlock.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pppd-spinlock.o `test -f 'spinlock.c' || echo '$(srcdir)/'`spinlock.c pppd-spinlock.obj: spinlock.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pppd-spinlock.obj -MD -MP -MF $(DEPDIR)/pppd-spinlock.Tpo -c -o pppd-spinlock.obj `if test -f 'spinlock.c'; then $(CYGPATH_W) 'spinlock.c'; else $(CYGPATH_W) '$(srcdir)/spinlock.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pppd-spinlock.Tpo $(DEPDIR)/pppd-spinlock.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='spinlock.c' object='pppd-spinlock.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pppd-spinlock.obj `if test -f 'spinlock.c'; then $(CYGPATH_W) 'spinlock.c'; else $(CYGPATH_W) '$(srcdir)/spinlock.c'; fi` pppd-ipv6cp.o: ipv6cp.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pppd-ipv6cp.o -MD -MP -MF $(DEPDIR)/pppd-ipv6cp.Tpo -c -o pppd-ipv6cp.o `test -f 'ipv6cp.c' || echo '$(srcdir)/'`ipv6cp.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pppd-ipv6cp.Tpo $(DEPDIR)/pppd-ipv6cp.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ipv6cp.c' object='pppd-ipv6cp.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pppd-ipv6cp.o `test -f 'ipv6cp.c' || echo '$(srcdir)/'`ipv6cp.c pppd-ipv6cp.obj: ipv6cp.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pppd-ipv6cp.obj -MD -MP -MF $(DEPDIR)/pppd-ipv6cp.Tpo -c -o pppd-ipv6cp.obj `if test -f 'ipv6cp.c'; then $(CYGPATH_W) 'ipv6cp.c'; else $(CYGPATH_W) '$(srcdir)/ipv6cp.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pppd-ipv6cp.Tpo $(DEPDIR)/pppd-ipv6cp.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ipv6cp.c' object='pppd-ipv6cp.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pppd-ipv6cp.obj `if test -f 'ipv6cp.c'; then $(CYGPATH_W) 'ipv6cp.c'; else $(CYGPATH_W) '$(srcdir)/ipv6cp.c'; fi` pppd-eui64.o: eui64.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pppd-eui64.o -MD -MP -MF $(DEPDIR)/pppd-eui64.Tpo -c -o pppd-eui64.o `test -f 'eui64.c' || echo '$(srcdir)/'`eui64.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pppd-eui64.Tpo $(DEPDIR)/pppd-eui64.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='eui64.c' object='pppd-eui64.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pppd-eui64.o `test -f 'eui64.c' || echo '$(srcdir)/'`eui64.c pppd-eui64.obj: eui64.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pppd-eui64.obj -MD -MP -MF $(DEPDIR)/pppd-eui64.Tpo -c -o pppd-eui64.obj `if test -f 'eui64.c'; then $(CYGPATH_W) 'eui64.c'; else $(CYGPATH_W) '$(srcdir)/eui64.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pppd-eui64.Tpo $(DEPDIR)/pppd-eui64.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='eui64.c' object='pppd-eui64.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pppd-eui64.obj `if test -f 'eui64.c'; then $(CYGPATH_W) 'eui64.c'; else $(CYGPATH_W) '$(srcdir)/eui64.c'; fi` pppd-eap-tls.o: eap-tls.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pppd-eap-tls.o -MD -MP -MF $(DEPDIR)/pppd-eap-tls.Tpo -c -o pppd-eap-tls.o `test -f 'eap-tls.c' || echo '$(srcdir)/'`eap-tls.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pppd-eap-tls.Tpo $(DEPDIR)/pppd-eap-tls.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='eap-tls.c' object='pppd-eap-tls.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pppd-eap-tls.o `test -f 'eap-tls.c' || echo '$(srcdir)/'`eap-tls.c pppd-eap-tls.obj: eap-tls.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pppd-eap-tls.obj -MD -MP -MF $(DEPDIR)/pppd-eap-tls.Tpo -c -o pppd-eap-tls.obj `if test -f 'eap-tls.c'; then $(CYGPATH_W) 'eap-tls.c'; else $(CYGPATH_W) '$(srcdir)/eap-tls.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pppd-eap-tls.Tpo $(DEPDIR)/pppd-eap-tls.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='eap-tls.c' object='pppd-eap-tls.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pppd-eap-tls.obj `if test -f 'eap-tls.c'; then $(CYGPATH_W) 'eap-tls.c'; else $(CYGPATH_W) '$(srcdir)/eap-tls.c'; fi` pppd-tls.o: tls.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pppd-tls.o -MD -MP -MF $(DEPDIR)/pppd-tls.Tpo -c -o pppd-tls.o `test -f 'tls.c' || echo '$(srcdir)/'`tls.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pppd-tls.Tpo $(DEPDIR)/pppd-tls.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tls.c' object='pppd-tls.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pppd-tls.o `test -f 'tls.c' || echo '$(srcdir)/'`tls.c pppd-tls.obj: tls.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pppd-tls.obj -MD -MP -MF $(DEPDIR)/pppd-tls.Tpo -c -o pppd-tls.obj `if test -f 'tls.c'; then $(CYGPATH_W) 'tls.c'; else $(CYGPATH_W) '$(srcdir)/tls.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pppd-tls.Tpo $(DEPDIR)/pppd-tls.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tls.c' object='pppd-tls.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pppd-tls.obj `if test -f 'tls.c'; then $(CYGPATH_W) 'tls.c'; else $(CYGPATH_W) '$(srcdir)/tls.c'; fi` pppd-peap.o: peap.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pppd-peap.o -MD -MP -MF $(DEPDIR)/pppd-peap.Tpo -c -o pppd-peap.o `test -f 'peap.c' || echo '$(srcdir)/'`peap.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pppd-peap.Tpo $(DEPDIR)/pppd-peap.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='peap.c' object='pppd-peap.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pppd-peap.o `test -f 'peap.c' || echo '$(srcdir)/'`peap.c pppd-peap.obj: peap.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pppd-peap.obj -MD -MP -MF $(DEPDIR)/pppd-peap.Tpo -c -o pppd-peap.obj `if test -f 'peap.c'; then $(CYGPATH_W) 'peap.c'; else $(CYGPATH_W) '$(srcdir)/peap.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pppd-peap.Tpo $(DEPDIR)/pppd-peap.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='peap.c' object='pppd-peap.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pppd-peap.obj `if test -f 'peap.c'; then $(CYGPATH_W) 'peap.c'; else $(CYGPATH_W) '$(srcdir)/peap.c'; fi` srp_entry-srp-entry.o: srp-entry.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(srp_entry_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT srp_entry-srp-entry.o -MD -MP -MF $(DEPDIR)/srp_entry-srp-entry.Tpo -c -o srp_entry-srp-entry.o `test -f 'srp-entry.c' || echo '$(srcdir)/'`srp-entry.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/srp_entry-srp-entry.Tpo $(DEPDIR)/srp_entry-srp-entry.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='srp-entry.c' object='srp_entry-srp-entry.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(srp_entry_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o srp_entry-srp-entry.o `test -f 'srp-entry.c' || echo '$(srcdir)/'`srp-entry.c srp_entry-srp-entry.obj: srp-entry.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(srp_entry_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT srp_entry-srp-entry.obj -MD -MP -MF $(DEPDIR)/srp_entry-srp-entry.Tpo -c -o srp_entry-srp-entry.obj `if test -f 'srp-entry.c'; then $(CYGPATH_W) 'srp-entry.c'; else $(CYGPATH_W) '$(srcdir)/srp-entry.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/srp_entry-srp-entry.Tpo $(DEPDIR)/srp_entry-srp-entry.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='srp-entry.c' object='srp_entry-srp-entry.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(srp_entry_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o srp_entry-srp-entry.obj `if test -f 'srp-entry.c'; then $(CYGPATH_W) 'srp-entry.c'; else $(CYGPATH_W) '$(srcdir)/srp-entry.c'; fi` utest_chap-chap_ms.o: chap_ms.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(utest_chap_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT utest_chap-chap_ms.o -MD -MP -MF $(DEPDIR)/utest_chap-chap_ms.Tpo -c -o utest_chap-chap_ms.o `test -f 'chap_ms.c' || echo '$(srcdir)/'`chap_ms.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/utest_chap-chap_ms.Tpo $(DEPDIR)/utest_chap-chap_ms.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='chap_ms.c' object='utest_chap-chap_ms.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(utest_chap_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o utest_chap-chap_ms.o `test -f 'chap_ms.c' || echo '$(srcdir)/'`chap_ms.c utest_chap-chap_ms.obj: chap_ms.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(utest_chap_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT utest_chap-chap_ms.obj -MD -MP -MF $(DEPDIR)/utest_chap-chap_ms.Tpo -c -o utest_chap-chap_ms.obj `if test -f 'chap_ms.c'; then $(CYGPATH_W) 'chap_ms.c'; else $(CYGPATH_W) '$(srcdir)/chap_ms.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/utest_chap-chap_ms.Tpo $(DEPDIR)/utest_chap-chap_ms.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='chap_ms.c' object='utest_chap-chap_ms.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(utest_chap_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o utest_chap-chap_ms.obj `if test -f 'chap_ms.c'; then $(CYGPATH_W) 'chap_ms.c'; else $(CYGPATH_W) '$(srcdir)/chap_ms.c'; fi` utest_chap-utils.o: utils.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(utest_chap_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT utest_chap-utils.o -MD -MP -MF $(DEPDIR)/utest_chap-utils.Tpo -c -o utest_chap-utils.o `test -f 'utils.c' || echo '$(srcdir)/'`utils.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/utest_chap-utils.Tpo $(DEPDIR)/utest_chap-utils.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='utils.c' object='utest_chap-utils.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(utest_chap_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o utest_chap-utils.o `test -f 'utils.c' || echo '$(srcdir)/'`utils.c utest_chap-utils.obj: utils.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(utest_chap_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT utest_chap-utils.obj -MD -MP -MF $(DEPDIR)/utest_chap-utils.Tpo -c -o utest_chap-utils.obj `if test -f 'utils.c'; then $(CYGPATH_W) 'utils.c'; else $(CYGPATH_W) '$(srcdir)/utils.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/utest_chap-utils.Tpo $(DEPDIR)/utest_chap-utils.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='utils.c' object='utest_chap-utils.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(utest_chap_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o utest_chap-utils.obj `if test -f 'utils.c'; then $(CYGPATH_W) 'utils.c'; else $(CYGPATH_W) '$(srcdir)/utils.c'; fi` utest_chap-crypto_ms.o: crypto_ms.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(utest_chap_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT utest_chap-crypto_ms.o -MD -MP -MF $(DEPDIR)/utest_chap-crypto_ms.Tpo -c -o utest_chap-crypto_ms.o `test -f 'crypto_ms.c' || echo '$(srcdir)/'`crypto_ms.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/utest_chap-crypto_ms.Tpo $(DEPDIR)/utest_chap-crypto_ms.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='crypto_ms.c' object='utest_chap-crypto_ms.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(utest_chap_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o utest_chap-crypto_ms.o `test -f 'crypto_ms.c' || echo '$(srcdir)/'`crypto_ms.c utest_chap-crypto_ms.obj: crypto_ms.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(utest_chap_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT utest_chap-crypto_ms.obj -MD -MP -MF $(DEPDIR)/utest_chap-crypto_ms.Tpo -c -o utest_chap-crypto_ms.obj `if test -f 'crypto_ms.c'; then $(CYGPATH_W) 'crypto_ms.c'; else $(CYGPATH_W) '$(srcdir)/crypto_ms.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/utest_chap-crypto_ms.Tpo $(DEPDIR)/utest_chap-crypto_ms.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='crypto_ms.c' object='utest_chap-crypto_ms.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(utest_chap_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o utest_chap-crypto_ms.obj `if test -f 'crypto_ms.c'; then $(CYGPATH_W) 'crypto_ms.c'; else $(CYGPATH_W) '$(srcdir)/crypto_ms.c'; fi` utest_crypto-crypto.o: crypto.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(utest_crypto_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT utest_crypto-crypto.o -MD -MP -MF $(DEPDIR)/utest_crypto-crypto.Tpo -c -o utest_crypto-crypto.o `test -f 'crypto.c' || echo '$(srcdir)/'`crypto.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/utest_crypto-crypto.Tpo $(DEPDIR)/utest_crypto-crypto.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='crypto.c' object='utest_crypto-crypto.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(utest_crypto_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o utest_crypto-crypto.o `test -f 'crypto.c' || echo '$(srcdir)/'`crypto.c utest_crypto-crypto.obj: crypto.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(utest_crypto_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT utest_crypto-crypto.obj -MD -MP -MF $(DEPDIR)/utest_crypto-crypto.Tpo -c -o utest_crypto-crypto.obj `if test -f 'crypto.c'; then $(CYGPATH_W) 'crypto.c'; else $(CYGPATH_W) '$(srcdir)/crypto.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/utest_crypto-crypto.Tpo $(DEPDIR)/utest_crypto-crypto.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='crypto.c' object='utest_crypto-crypto.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(utest_crypto_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o utest_crypto-crypto.obj `if test -f 'crypto.c'; then $(CYGPATH_W) 'crypto.c'; else $(CYGPATH_W) '$(srcdir)/crypto.c'; fi` utest_peap-peap.o: peap.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(utest_peap_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT utest_peap-peap.o -MD -MP -MF $(DEPDIR)/utest_peap-peap.Tpo -c -o utest_peap-peap.o `test -f 'peap.c' || echo '$(srcdir)/'`peap.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/utest_peap-peap.Tpo $(DEPDIR)/utest_peap-peap.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='peap.c' object='utest_peap-peap.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(utest_peap_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o utest_peap-peap.o `test -f 'peap.c' || echo '$(srcdir)/'`peap.c utest_peap-peap.obj: peap.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(utest_peap_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT utest_peap-peap.obj -MD -MP -MF $(DEPDIR)/utest_peap-peap.Tpo -c -o utest_peap-peap.obj `if test -f 'peap.c'; then $(CYGPATH_W) 'peap.c'; else $(CYGPATH_W) '$(srcdir)/peap.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/utest_peap-peap.Tpo $(DEPDIR)/utest_peap-peap.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='peap.c' object='utest_peap-peap.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(utest_peap_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o utest_peap-peap.obj `if test -f 'peap.c'; then $(CYGPATH_W) 'peap.c'; else $(CYGPATH_W) '$(srcdir)/peap.c'; fi` utest_peap-utils.o: utils.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(utest_peap_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT utest_peap-utils.o -MD -MP -MF $(DEPDIR)/utest_peap-utils.Tpo -c -o utest_peap-utils.o `test -f 'utils.c' || echo '$(srcdir)/'`utils.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/utest_peap-utils.Tpo $(DEPDIR)/utest_peap-utils.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='utils.c' object='utest_peap-utils.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(utest_peap_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o utest_peap-utils.o `test -f 'utils.c' || echo '$(srcdir)/'`utils.c utest_peap-utils.obj: utils.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(utest_peap_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT utest_peap-utils.obj -MD -MP -MF $(DEPDIR)/utest_peap-utils.Tpo -c -o utest_peap-utils.obj `if test -f 'utils.c'; then $(CYGPATH_W) 'utils.c'; else $(CYGPATH_W) '$(srcdir)/utils.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/utest_peap-utils.Tpo $(DEPDIR)/utest_peap-utils.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='utils.c' object='utest_peap-utils.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(utest_peap_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o utest_peap-utils.obj `if test -f 'utils.c'; then $(CYGPATH_W) 'utils.c'; else $(CYGPATH_W) '$(srcdir)/utils.c'; fi` utest_peap-mppe.o: mppe.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(utest_peap_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT utest_peap-mppe.o -MD -MP -MF $(DEPDIR)/utest_peap-mppe.Tpo -c -o utest_peap-mppe.o `test -f 'mppe.c' || echo '$(srcdir)/'`mppe.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/utest_peap-mppe.Tpo $(DEPDIR)/utest_peap-mppe.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='mppe.c' object='utest_peap-mppe.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(utest_peap_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o utest_peap-mppe.o `test -f 'mppe.c' || echo '$(srcdir)/'`mppe.c utest_peap-mppe.obj: mppe.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(utest_peap_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT utest_peap-mppe.obj -MD -MP -MF $(DEPDIR)/utest_peap-mppe.Tpo -c -o utest_peap-mppe.obj `if test -f 'mppe.c'; then $(CYGPATH_W) 'mppe.c'; else $(CYGPATH_W) '$(srcdir)/mppe.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/utest_peap-mppe.Tpo $(DEPDIR)/utest_peap-mppe.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='mppe.c' object='utest_peap-mppe.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(utest_peap_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o utest_peap-mppe.obj `if test -f 'mppe.c'; then $(CYGPATH_W) 'mppe.c'; else $(CYGPATH_W) '$(srcdir)/mppe.c'; fi` utest_pppcrypt-crypto_ms.o: crypto_ms.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(utest_pppcrypt_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT utest_pppcrypt-crypto_ms.o -MD -MP -MF $(DEPDIR)/utest_pppcrypt-crypto_ms.Tpo -c -o utest_pppcrypt-crypto_ms.o `test -f 'crypto_ms.c' || echo '$(srcdir)/'`crypto_ms.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/utest_pppcrypt-crypto_ms.Tpo $(DEPDIR)/utest_pppcrypt-crypto_ms.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='crypto_ms.c' object='utest_pppcrypt-crypto_ms.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(utest_pppcrypt_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o utest_pppcrypt-crypto_ms.o `test -f 'crypto_ms.c' || echo '$(srcdir)/'`crypto_ms.c utest_pppcrypt-crypto_ms.obj: crypto_ms.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(utest_pppcrypt_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT utest_pppcrypt-crypto_ms.obj -MD -MP -MF $(DEPDIR)/utest_pppcrypt-crypto_ms.Tpo -c -o utest_pppcrypt-crypto_ms.obj `if test -f 'crypto_ms.c'; then $(CYGPATH_W) 'crypto_ms.c'; else $(CYGPATH_W) '$(srcdir)/crypto_ms.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/utest_pppcrypt-crypto_ms.Tpo $(DEPDIR)/utest_pppcrypt-crypto_ms.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='crypto_ms.c' object='utest_pppcrypt-crypto_ms.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(utest_pppcrypt_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o utest_pppcrypt-crypto_ms.obj `if test -f 'crypto_ms.c'; then $(CYGPATH_W) 'crypto_ms.c'; else $(CYGPATH_W) '$(srcdir)/crypto_ms.c'; fi` mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs install-man8: $(dist_man8_MANS) @$(NORMAL_INSTALL) @list1='$(dist_man8_MANS)'; \ list2=''; \ test -n "$(man8dir)" \ && test -n "`echo $$list1$$list2`" \ || exit 0; \ echo " $(MKDIR_P) '$(DESTDIR)$(man8dir)'"; \ $(MKDIR_P) "$(DESTDIR)$(man8dir)" || exit 1; \ { for i in $$list1; do echo "$$i"; done; \ if test -n "$$list2"; then \ for i in $$list2; do echo "$$i"; done \ | sed -n '/\.8[a-z]*$$/p'; \ fi; \ } | while read p; do \ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; echo "$$p"; \ done | \ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ sed 'N;N;s,\n, ,g' | { \ list=; while read file base inst; do \ if test "$$base" = "$$inst"; then list="$$list $$file"; else \ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man8dir)/$$inst'"; \ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man8dir)/$$inst" || exit $$?; \ fi; \ done; \ for i in $$list; do echo "$$i"; done | $(am__base_list) | \ while read files; do \ test -z "$$files" || { \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man8dir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(man8dir)" || exit $$?; }; \ done; } uninstall-man8: @$(NORMAL_UNINSTALL) @list='$(dist_man8_MANS)'; test -n "$(man8dir)" || exit 0; \ files=`{ for i in $$list; do echo "$$i"; done; \ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ dir='$(DESTDIR)$(man8dir)'; $(am__uninstall_files_from_dir) install-pkgconfigDATA: $(pkgconfig_DATA) @$(NORMAL_INSTALL) @list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(pkgconfigdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(pkgconfigdir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pkgconfigdir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(pkgconfigdir)" || exit $$?; \ done uninstall-pkgconfigDATA: @$(NORMAL_UNINSTALL) @list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(pkgconfigdir)'; $(am__uninstall_files_from_dir) install-pppd_includeHEADERS: $(pppd_include_HEADERS) @$(NORMAL_INSTALL) @list='$(pppd_include_HEADERS)'; test -n "$(pppd_includedir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(pppd_includedir)'"; \ $(MKDIR_P) "$(DESTDIR)$(pppd_includedir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(pppd_includedir)'"; \ $(INSTALL_HEADER) $$files "$(DESTDIR)$(pppd_includedir)" || exit $$?; \ done uninstall-pppd_includeHEADERS: @$(NORMAL_UNINSTALL) @list='$(pppd_include_HEADERS)'; test -n "$(pppd_includedir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(pppd_includedir)'; $(am__uninstall_files_from_dir) ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags # Recover from deleted '.trs' file; this should ensure that # "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create # both 'foo.log' and 'foo.trs'. Break the recipe in two subshells # to avoid problems with "make -n". .log.trs: rm -f $< $@ $(MAKE) $(AM_MAKEFLAGS) $< # Leading 'am--fnord' is there to ensure the list of targets does not # expand to empty, as could happen e.g. with make check TESTS=''. am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck) am--force-recheck: @: $(TEST_SUITE_LOG): $(TEST_LOGS) @$(am__set_TESTS_bases); \ am__f_ok () { test -f "$$1" && test -r "$$1"; }; \ redo_bases=`for i in $$bases; do \ am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \ done`; \ if test -n "$$redo_bases"; then \ redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \ redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \ if $(am__make_dryrun); then :; else \ rm -f $$redo_logs && rm -f $$redo_results || exit 1; \ fi; \ fi; \ if test -n "$$am__remaking_logs"; then \ echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \ "recursion detected" >&2; \ elif test -n "$$redo_logs"; then \ am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \ fi; \ if $(am__make_dryrun); then :; else \ st=0; \ errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \ for i in $$redo_bases; do \ test -f $$i.trs && test -r $$i.trs \ || { echo "$$errmsg $$i.trs" >&2; st=1; }; \ test -f $$i.log && test -r $$i.log \ || { echo "$$errmsg $$i.log" >&2; st=1; }; \ done; \ test $$st -eq 0 || exit 1; \ fi @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \ ws='[ ]'; \ results=`for b in $$bases; do echo $$b.trs; done`; \ test -n "$$results" || results=/dev/null; \ all=` grep "^$$ws*:test-result:" $$results | wc -l`; \ pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \ fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \ skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \ xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \ xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \ error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \ if test `expr $$fail + $$xpass + $$error` -eq 0; then \ success=true; \ else \ success=false; \ fi; \ br='==================='; br=$$br$$br$$br$$br; \ result_count () \ { \ if test x"$$1" = x"--maybe-color"; then \ maybe_colorize=yes; \ elif test x"$$1" = x"--no-color"; then \ maybe_colorize=no; \ else \ echo "$@: invalid 'result_count' usage" >&2; exit 4; \ fi; \ shift; \ desc=$$1 count=$$2; \ if test $$maybe_colorize = yes && test $$count -gt 0; then \ color_start=$$3 color_end=$$std; \ else \ color_start= color_end=; \ fi; \ echo "$${color_start}# $$desc $$count$${color_end}"; \ }; \ create_testsuite_report () \ { \ result_count $$1 "TOTAL:" $$all "$$brg"; \ result_count $$1 "PASS: " $$pass "$$grn"; \ result_count $$1 "SKIP: " $$skip "$$blu"; \ result_count $$1 "XFAIL:" $$xfail "$$lgn"; \ result_count $$1 "FAIL: " $$fail "$$red"; \ result_count $$1 "XPASS:" $$xpass "$$red"; \ result_count $$1 "ERROR:" $$error "$$mgn"; \ }; \ { \ echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \ $(am__rst_title); \ create_testsuite_report --no-color; \ echo; \ echo ".. contents:: :depth: 2"; \ echo; \ for b in $$bases; do echo $$b; done \ | $(am__create_global_log); \ } >$(TEST_SUITE_LOG).tmp || exit 1; \ mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \ if $$success; then \ col="$$grn"; \ else \ col="$$red"; \ test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \ fi; \ echo "$${col}$$br$${std}"; \ echo "$${col}Testsuite summary"$(AM_TESTSUITE_SUMMARY_HEADER)"$${std}"; \ echo "$${col}$$br$${std}"; \ create_testsuite_report --maybe-color; \ echo "$$col$$br$$std"; \ if $$success; then :; else \ echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \ if test -n "$(PACKAGE_BUGREPORT)"; then \ echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \ fi; \ echo "$$col$$br$$std"; \ fi; \ $$success || exit 1 check-TESTS: $(check_PROGRAMS) @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) @set +e; $(am__set_TESTS_bases); \ log_list=`for i in $$bases; do echo $$i.log; done`; \ trs_list=`for i in $$bases; do echo $$i.trs; done`; \ log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \ exit $$?; recheck: all $(check_PROGRAMS) @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) @set +e; $(am__set_TESTS_bases); \ bases=`for i in $$bases; do echo $$i; done \ | $(am__list_recheck_tests)` || exit 1; \ log_list=`for i in $$bases; do echo $$i.log; done`; \ log_list=`echo $$log_list`; \ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \ am__force_recheck=am--force-recheck \ TEST_LOGS="$$log_list"; \ exit $$? utest_crypto.log: utest_crypto$(EXEEXT) @p='utest_crypto$(EXEEXT)'; \ b='utest_crypto'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) utest_chap.log: utest_chap$(EXEEXT) @p='utest_chap$(EXEEXT)'; \ b='utest_chap'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) utest_pppcrypt.log: utest_pppcrypt$(EXEEXT) @p='utest_pppcrypt$(EXEEXT)'; \ b='utest_pppcrypt'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) utest_peap.log: utest_peap$(EXEEXT) @p='utest_peap$(EXEEXT)'; \ b='utest_peap'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) .test.log: @p='$<'; \ $(am__set_b); \ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) @am__EXEEXT_TRUE@.test$(EXEEXT).log: @am__EXEEXT_TRUE@ @p='$<'; \ @am__EXEEXT_TRUE@ $(am__set_b); \ @am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ @am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \ @am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ @am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT) distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) $(MAKE) $(AM_MAKEFLAGS) check-TESTS check: check-am all-am: Makefile $(PROGRAMS) $(LTLIBRARIES) $(MANS) $(DATA) $(HEADERS) \ config.h pppdconf.h installdirs: for dir in "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(man8dir)" "$(DESTDIR)$(pkgconfigdir)" "$(DESTDIR)$(pppd_includedir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS) -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs) -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-checkPROGRAMS clean-generic clean-libtool \ clean-noinstLTLIBRARIES clean-sbinPROGRAMS mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/libppp_crypto_la-crypto.Plo -rm -f ./$(DEPDIR)/libppp_crypto_la-ppp-des.Plo -rm -f ./$(DEPDIR)/libppp_crypto_la-ppp-md4.Plo -rm -f ./$(DEPDIR)/libppp_crypto_la-ppp-md5.Plo -rm -f ./$(DEPDIR)/libppp_crypto_la-ppp-sha1.Plo -rm -f ./$(DEPDIR)/pppd-auth.Po -rm -f ./$(DEPDIR)/pppd-cbcp.Po -rm -f ./$(DEPDIR)/pppd-ccp.Po -rm -f ./$(DEPDIR)/pppd-chap-md5.Po -rm -f ./$(DEPDIR)/pppd-chap.Po -rm -f ./$(DEPDIR)/pppd-chap_ms.Po -rm -f ./$(DEPDIR)/pppd-crypto_ms.Po -rm -f ./$(DEPDIR)/pppd-demand.Po -rm -f ./$(DEPDIR)/pppd-eap-tls.Po -rm -f ./$(DEPDIR)/pppd-eap.Po -rm -f ./$(DEPDIR)/pppd-ecp.Po -rm -f ./$(DEPDIR)/pppd-eui64.Po -rm -f ./$(DEPDIR)/pppd-fsm.Po -rm -f ./$(DEPDIR)/pppd-ipcp.Po -rm -f ./$(DEPDIR)/pppd-ipv6cp.Po -rm -f ./$(DEPDIR)/pppd-lcp.Po -rm -f ./$(DEPDIR)/pppd-magic.Po -rm -f ./$(DEPDIR)/pppd-main.Po -rm -f ./$(DEPDIR)/pppd-mppe.Po -rm -f ./$(DEPDIR)/pppd-multilink.Po -rm -f ./$(DEPDIR)/pppd-options.Po -rm -f ./$(DEPDIR)/pppd-peap.Po -rm -f ./$(DEPDIR)/pppd-session.Po -rm -f ./$(DEPDIR)/pppd-spinlock.Po -rm -f ./$(DEPDIR)/pppd-sys-linux.Po -rm -f ./$(DEPDIR)/pppd-sys-solaris.Po -rm -f ./$(DEPDIR)/pppd-tdb.Po -rm -f ./$(DEPDIR)/pppd-tls.Po -rm -f ./$(DEPDIR)/pppd-tty.Po -rm -f ./$(DEPDIR)/pppd-upap.Po -rm -f ./$(DEPDIR)/pppd-utils.Po -rm -f ./$(DEPDIR)/srp_entry-srp-entry.Po -rm -f ./$(DEPDIR)/utest_chap-chap_ms.Po -rm -f ./$(DEPDIR)/utest_chap-crypto_ms.Po -rm -f ./$(DEPDIR)/utest_chap-utils.Po -rm -f ./$(DEPDIR)/utest_crypto-crypto.Po -rm -f ./$(DEPDIR)/utest_peap-mppe.Po -rm -f ./$(DEPDIR)/utest_peap-peap.Po -rm -f ./$(DEPDIR)/utest_peap-utils.Po -rm -f ./$(DEPDIR)/utest_pppcrypt-crypto_ms.Po -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-hdr distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-man install-pkgconfigDATA \ install-pppd_includeHEADERS install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-sbinPROGRAMS install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-man8 install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/libppp_crypto_la-crypto.Plo -rm -f ./$(DEPDIR)/libppp_crypto_la-ppp-des.Plo -rm -f ./$(DEPDIR)/libppp_crypto_la-ppp-md4.Plo -rm -f ./$(DEPDIR)/libppp_crypto_la-ppp-md5.Plo -rm -f ./$(DEPDIR)/libppp_crypto_la-ppp-sha1.Plo -rm -f ./$(DEPDIR)/pppd-auth.Po -rm -f ./$(DEPDIR)/pppd-cbcp.Po -rm -f ./$(DEPDIR)/pppd-ccp.Po -rm -f ./$(DEPDIR)/pppd-chap-md5.Po -rm -f ./$(DEPDIR)/pppd-chap.Po -rm -f ./$(DEPDIR)/pppd-chap_ms.Po -rm -f ./$(DEPDIR)/pppd-crypto_ms.Po -rm -f ./$(DEPDIR)/pppd-demand.Po -rm -f ./$(DEPDIR)/pppd-eap-tls.Po -rm -f ./$(DEPDIR)/pppd-eap.Po -rm -f ./$(DEPDIR)/pppd-ecp.Po -rm -f ./$(DEPDIR)/pppd-eui64.Po -rm -f ./$(DEPDIR)/pppd-fsm.Po -rm -f ./$(DEPDIR)/pppd-ipcp.Po -rm -f ./$(DEPDIR)/pppd-ipv6cp.Po -rm -f ./$(DEPDIR)/pppd-lcp.Po -rm -f ./$(DEPDIR)/pppd-magic.Po -rm -f ./$(DEPDIR)/pppd-main.Po -rm -f ./$(DEPDIR)/pppd-mppe.Po -rm -f ./$(DEPDIR)/pppd-multilink.Po -rm -f ./$(DEPDIR)/pppd-options.Po -rm -f ./$(DEPDIR)/pppd-peap.Po -rm -f ./$(DEPDIR)/pppd-session.Po -rm -f ./$(DEPDIR)/pppd-spinlock.Po -rm -f ./$(DEPDIR)/pppd-sys-linux.Po -rm -f ./$(DEPDIR)/pppd-sys-solaris.Po -rm -f ./$(DEPDIR)/pppd-tdb.Po -rm -f ./$(DEPDIR)/pppd-tls.Po -rm -f ./$(DEPDIR)/pppd-tty.Po -rm -f ./$(DEPDIR)/pppd-upap.Po -rm -f ./$(DEPDIR)/pppd-utils.Po -rm -f ./$(DEPDIR)/srp_entry-srp-entry.Po -rm -f ./$(DEPDIR)/utest_chap-chap_ms.Po -rm -f ./$(DEPDIR)/utest_chap-crypto_ms.Po -rm -f ./$(DEPDIR)/utest_chap-utils.Po -rm -f ./$(DEPDIR)/utest_crypto-crypto.Po -rm -f ./$(DEPDIR)/utest_peap-mppe.Po -rm -f ./$(DEPDIR)/utest_peap-peap.Po -rm -f ./$(DEPDIR)/utest_peap-utils.Po -rm -f ./$(DEPDIR)/utest_pppcrypt-crypto_ms.Po -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-man uninstall-pkgconfigDATA \ uninstall-pppd_includeHEADERS uninstall-sbinPROGRAMS uninstall-man: uninstall-man8 .MAKE: all check-am install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-TESTS \ check-am clean clean-checkPROGRAMS clean-generic clean-libtool \ clean-noinstLTLIBRARIES clean-sbinPROGRAMS cscopelist-am ctags \ ctags-am distclean distclean-compile distclean-generic \ distclean-hdr distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-man8 \ install-pdf install-pdf-am install-pkgconfigDATA \ install-pppd_includeHEADERS install-ps install-ps-am \ install-sbinPROGRAMS install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ recheck tags tags-am uninstall uninstall-am uninstall-man \ uninstall-man8 uninstall-pkgconfigDATA \ uninstall-pppd_includeHEADERS uninstall-sbinPROGRAMS .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: ppp-2.5.0/pppd/config.h.in0000644000175000017500000001262714407475317012250 00000000000000/* pppd/config.h.in. Generated from configure.ac by autoheader. */ /* Define to 1 if you have the header file. */ #undef HAVE_ASM_TYPES_H /* Define to 1 if you have the header file. */ #undef HAVE_CRYPT_H /* Define to 1 if you have the header file. */ #undef HAVE_DLFCN_H /* Define to 1 if you have the header file. */ #undef HAVE_INTTYPES_H /* Define to 1 if you have the header file. */ #undef HAVE_LINUX_IF_ETHER_H /* Define to 1 if you have the header file. */ #undef HAVE_LINUX_IF_H /* Define to 1 if you have the header file. */ #undef HAVE_LINUX_IF_PACKET_H /* System provides the logwtmp() function */ #undef HAVE_LOGWTMP /* Define to 1 if you have the `mmap' function. */ #undef HAVE_MMAP /* Define to 1 if you have the header file. */ #undef HAVE_NETINET_IF_ETHER_H /* Define to 1 if you have the header file. */ #undef HAVE_NETPACKET_PACKET_H /* Define to 1 if you have the header file. */ #undef HAVE_NET_BPF_H /* Define to 1 if you have the header file. */ #undef HAVE_NET_IF_ARP_H /* Define to 1 if you have the header file. */ #undef HAVE_NET_IF_H /* Define to 1 if you have the header file. */ #undef HAVE_NET_IF_TYPES_H /* Define to 1 if you have the header file. */ #undef HAVE_PATHS_H /* Define to 1 if you have the header file. */ #undef HAVE_SHADOW_H /* Define to 1 if you have the header file. */ #undef HAVE_STDARG_H /* Define to 1 if stdbool.h conforms to C99. */ #undef HAVE_STDBOOL_H /* Define to 1 if you have the header file. */ #undef HAVE_STDDEF_H /* Define to 1 if you have the header file. */ #undef HAVE_STDINT_H /* Define to 1 if you have the header file. */ #undef HAVE_STDIO_H /* Define to 1 if you have the header file. */ #undef HAVE_STDLIB_H /* Define to 1 if you have the `strerror' function. */ #undef HAVE_STRERROR /* Define to 1 if you have the header file. */ #undef HAVE_STRINGS_H /* Define to 1 if you have the header file. */ #undef HAVE_STRING_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_DLPI_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_IOCTL_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_SOCKET_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_STAT_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TIME_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TYPES_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_UIO_H /* Define to 1 if you have the header file. */ #undef HAVE_TIME_H /* Define to 1 if you have the header file. */ #undef HAVE_UNISTD_H /* Define to 1 if you have the header file. */ #undef HAVE_UTMP_H /* Define to 1 if the system has the type `_Bool'. */ #undef HAVE__BOOL /* Define to the sub-directory where libtool stores uninstalled libraries. */ #undef LT_OBJDIR /* Use DES included with openssl */ #undef OPENSSL_HAVE_DES /* Use MD4 included with openssl */ #undef OPENSSL_HAVE_MD4 /* Use MD5 included with openssl */ #undef OPENSSL_HAVE_MD5 /* Use SHA included with openssl */ #undef OPENSSL_HAVE_SHA /* OpenSSL engine support */ #undef OPENSSL_NO_ENGINE /* Name of package */ #undef PACKAGE /* Define to the address where bug reports for this package should be sent. */ #undef PACKAGE_BUGREPORT /* Define to the full name of this package. */ #undef PACKAGE_NAME /* Define to the full name and version of this package. */ #undef PACKAGE_STRING /* Define to the one symbol short name of this package. */ #undef PACKAGE_TARNAME /* Define to the home page for this package. */ #undef PACKAGE_URL /* Define to the version of this package. */ #undef PACKAGE_VERSION /* Version of pppd */ #undef PPPD_VERSION /* Have Callback Protocol support */ #undef PPP_WITH_CBCP /* Have Microsoft CHAP support */ #undef PPP_WITH_CHAPMS /* Have EAP-TLS authentication support */ #undef PPP_WITH_EAPTLS /* Have packet activity filter support */ #undef PPP_WITH_FILTER /* Have IPv6 Control Protocol */ #undef PPP_WITH_IPV6CP /* Have Microsoft MPPE support */ #undef PPP_WITH_MPPE /* Have Microsoft LAN Manager support */ #undef PPP_WITH_MSLANMAN /* Have multilink support */ #undef PPP_WITH_MULTILINK /* PPP is compiled with openssl support */ #undef PPP_WITH_OPENSSL /* Support for Pluggable Authentication Modules */ #undef PPP_WITH_PAM /* Have PEAP authentication support */ #undef PPP_WITH_PEAP /* Have support for loadable plugins */ #undef PPP_WITH_PLUGINS /* Support for libsrp authentication module */ #undef PPP_WITH_SRP /* Include TDB support */ #undef PPP_WITH_TDB /* The size of `unsigned int', as computed by sizeof. */ #undef SIZEOF_UNSIGNED_INT /* The size of `unsigned long', as computed by sizeof. */ #undef SIZEOF_UNSIGNED_LONG /* The size of `unsigned short', as computed by sizeof. */ #undef SIZEOF_UNSIGNED_SHORT /* Define to 1 if all of the C90 standard headers exist (not just the ones required in a freestanding environment). This macro is provided for backward compatibility; new code need not use it. */ #undef STDC_HEADERS /* Enable support for systemd notifications */ #undef SYSTEMD /* Version number of package */ #undef VERSION ppp-2.5.0/pppd/pppd.pc.in0000664000175000017500000000033714076444143012111 00000000000000prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@ plugindir=@PPPD_PLUGIN_DIR@ Name: pppd Description: Point-to-Point Protocol (PPP) daemon Version: @PACKAGE_VERSION@ Cflags: -I${includedir} ppp-2.5.0/pppd/pppdconf.h.in0000644000175000017500000000430614407475306012605 00000000000000/* * Copyright (c) 2022 Eivind Næss. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The name(s) of the authors of this software must not be used to * endorse or promote products derived from this software without * prior written permission. * * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /* * This file is generated by configure and sets the features enabled * in pppd when configured. */ #ifndef PPP_PPPDCONF_H #define PPP_PPPDCONF_H /* Have Microsoft CHAP support */ #undef PPP_WITH_CHAPMS /* Have Microsoft LAN Manager support */ #undef PPP_WITH_MSLANMAN /* Have Microsoft MPPE support */ #undef PPP_WITH_MPPE /* Have multilink support */ #undef PPP_WITH_MULTILINK /* Have packet activity filter support */ #undef PPP_WITH_FILTER /* Have support for loadable plugins */ #undef PPP_WITH_PLUGINS /* Have Callback Protocol support */ #undef PPP_WITH_CBCP /* Include TDB support */ #undef PPP_WITH_TDB /* Have IPv6 Control Protocol */ #undef PPP_WITH_IPV6CP /* Support for Pluggable Authentication Modules */ #undef PPP_WITH_PAM /* Have EAP-SRP authentication support */ #undef PPP_WITH_SRP /* Have EAP-TLS authentication support */ #undef PPP_WITH_EAPTLS /* Have PEAP authentication support */ #undef PPP_WITH_PEAP /* The pppd version */ #undef PPPD_VERSION #endif ppp-2.5.0/pppd/crypto.c0000644000175000017500000003224414353435407011702 00000000000000/* ppp-crypto.c - Generic API for access to crypto/digest functions. * * Copyright (c) 2022 Eivind Næss. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The name(s) of the authors of this software must not be used to * endorse or promote products derived from this software without * prior written permission. * * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include "crypto.h" #include "crypto-priv.h" #ifdef PPP_WITH_OPENSSL #include #endif #if OPENSSL_VERSION_NUMBER >= 0x30000000L #include struct crypto_ctx { OSSL_PROVIDER *legacy; OSSL_PROVIDER *provider; } g_crypto_ctx; #endif PPP_MD_CTX *PPP_MD_CTX_new() { return (PPP_MD_CTX*) calloc(1, sizeof(PPP_MD_CTX)); } void PPP_MD_CTX_free(PPP_MD_CTX* ctx) { if (ctx) { if (ctx->md.clean_fn) { ctx->md.clean_fn(ctx); } free(ctx); } } int PPP_DigestInit(PPP_MD_CTX *ctx, const PPP_MD *type) { if (ctx) { ctx->md = *type; if (ctx->md.init_fn) { return ctx->md.init_fn(ctx); } } return 0; } int PPP_DigestUpdate(PPP_MD_CTX *ctx, const void *data, size_t length) { if (ctx && ctx->md.update_fn) { return ctx->md.update_fn(ctx, data, length); } return 0; } int PPP_DigestFinal(PPP_MD_CTX *ctx, unsigned char *out, unsigned int *outlen) { if (ctx && ctx->md.final_fn) { return ctx->md.final_fn(ctx, out, outlen); } return 0; } PPP_CIPHER_CTX *PPP_CIPHER_CTX_new(void) { return calloc(1, sizeof(PPP_CIPHER_CTX)); } void PPP_CIPHER_CTX_free(PPP_CIPHER_CTX *ctx) { if (ctx) { if (ctx->cipher.clean_fn) { ctx->cipher.clean_fn(ctx); } memset(ctx->iv, 0, sizeof(ctx->iv)); memset(ctx->key, 0, sizeof(ctx->key)); free(ctx); } } int PPP_CipherInit(PPP_CIPHER_CTX *ctx, const PPP_CIPHER *cipher, const unsigned char *key, const unsigned char *iv, int encr) { if (ctx && cipher) { ctx->is_encr = encr; ctx->cipher = *cipher; if (ctx->cipher.init_fn) { ctx->cipher.init_fn(ctx, key, iv); } return 1; } return 0; } int PPP_CipherUpdate(PPP_CIPHER_CTX *ctx, unsigned char *out, int *outl, const unsigned char *in, int inl) { if (ctx && ctx->cipher.update_fn) { return ctx->cipher.update_fn(ctx, out, outl, in, inl); } return 0; } int PPP_CipherFinal(PPP_CIPHER_CTX *ctx, unsigned char *out, int *outl) { if (ctx && ctx->cipher.final_fn) { return ctx->cipher.final_fn(ctx, out, outl); } return 0; } int PPP_crypto_init() { int retval = 0; #if OPENSSL_VERSION_NUMBER >= 0x30000000L g_crypto_ctx.legacy = OSSL_PROVIDER_load(NULL, "legacy"); if (g_crypto_ctx.legacy == NULL) { goto done; } g_crypto_ctx.provider = OSSL_PROVIDER_load(NULL, "default"); if (g_crypto_ctx.provider == NULL) { goto done; } #endif retval = 1; done: return retval; } int PPP_crypto_deinit() { #if OPENSSL_VERSION_NUMBER >= 0x30000000L if (g_crypto_ctx.legacy) { OSSL_PROVIDER_unload(g_crypto_ctx.legacy); g_crypto_ctx.legacy = NULL; } if (g_crypto_ctx.provider) { OSSL_PROVIDER_unload(g_crypto_ctx.provider); g_crypto_ctx.provider = NULL; } #endif return 1; } #ifdef UNIT_TEST #include int test_md4() { PPP_MD_CTX* ctx = NULL; int success = 0; unsigned char data[84] = { 0x4f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x20, 0x73, 0x69, 0x64, 0x65, 0x2c, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x65, 0x6e, 0x64, 0x20, 0x6b, 0x65, 0x79, 0x3b, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x73, 0x69, 0x64, 0x65, 0x2c, 0x20, 0x69, 0x74, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x20, 0x6b, 0x65, 0x79, 0x2e }; unsigned int hash_len; unsigned char hash[MD4_DIGEST_LENGTH]; unsigned char result[MD4_DIGEST_LENGTH] = { 0x58, 0xcb, 0x37, 0x91, 0x1d, 0x06, 0x7b, 0xdf, 0xfd, 0x48, 0x6d, 0x87, 0x4a, 0x35, 0x5b, 0xd4 }; ctx = PPP_MD_CTX_new(); if (ctx) { if (PPP_DigestInit(ctx, PPP_md4())) { if (PPP_DigestUpdate(ctx, &data, sizeof(data))) { hash_len = sizeof(hash); if (PPP_DigestFinal(ctx, hash, &hash_len)) { if (memcmp(hash, result, MD4_DIGEST_LENGTH) == 0) { success = 1; } } } } PPP_MD_CTX_free(ctx); } return success; } int test_md5() { PPP_MD_CTX* ctx = NULL; int success = 0; unsigned char data[84] = { 0x4f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x20, 0x73, 0x69, 0x64, 0x65, 0x2c, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x65, 0x6e, 0x64, 0x20, 0x6b, 0x65, 0x79, 0x3b, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x73, 0x69, 0x64, 0x65, 0x2c, 0x20, 0x69, 0x74, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x20, 0x6b, 0x65, 0x79, 0x2e }; unsigned int hash_len; unsigned char hash[MD5_DIGEST_LENGTH]; unsigned char result[MD5_DIGEST_LENGTH] = { 0x8b, 0xe3, 0x5e, 0x2c, 0x9f, 0x95, 0xbf, 0x4e, 0x16, 0xe4, 0x53, 0xbe, 0x52, 0xf4, 0xbc, 0x4e }; ctx = PPP_MD_CTX_new(); if (ctx) { if (PPP_DigestInit(ctx, PPP_md5())) { if (PPP_DigestUpdate(ctx, &data, sizeof(data))) { hash_len = sizeof(hash); if (PPP_DigestFinal(ctx, hash, &hash_len)) { if (memcmp(hash, result, MD5_DIGEST_LENGTH) == 0) { success = 1; } } } } PPP_MD_CTX_free(ctx); } return success; } int test_sha() { PPP_MD_CTX* ctx = NULL; int success = 0; unsigned char data[84] = { 0x4f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x20, 0x73, 0x69, 0x64, 0x65, 0x2c, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x65, 0x6e, 0x64, 0x20, 0x6b, 0x65, 0x79, 0x3b, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x73, 0x69, 0x64, 0x65, 0x2c, 0x20, 0x69, 0x74, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x20, 0x6b, 0x65, 0x79, 0x2e }; unsigned int hash_len; unsigned char hash[SHA_DIGEST_LENGTH]; unsigned char result[SHA_DIGEST_LENGTH] = { 0xa8, 0x03, 0xae, 0x21, 0x30, 0xd8, 0x40, 0xbe, 0x27, 0xa3, 0x47, 0xc7, 0x7a, 0x90, 0xe6, 0xa3, 0x5b, 0xd5, 0x0e, 0x45 }; ctx = PPP_MD_CTX_new(); if (ctx) { if (PPP_DigestInit(ctx, PPP_sha1())) { if (PPP_DigestUpdate(ctx, &data, sizeof(data))) { hash_len = sizeof(hash); if (PPP_DigestFinal(ctx, hash, &hash_len)) { if (memcmp(hash, result, SHA_DIGEST_LENGTH) == 0) { success = 1; } } } } PPP_MD_CTX_free(ctx); } return success; } int test_des_encrypt() { PPP_CIPHER_CTX* ctx = NULL; int success = 0; unsigned char key[8] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 }; unsigned char plain[80] = { 0x4f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x20, 0x73, 0x69, 0x64, 0x65, 0x2c, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x65, 0x6e, 0x64, 0x20, 0x6b, 0x65, 0x79, 0x3b, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x73, 0x69, 0x64, 0x65, 0x2c, 0x20, 0x69, 0x74, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x20 }; unsigned char expect[80] = { 0x45, 0xdb, 0x80, 0x45, 0x16, 0xd0, 0x6d, 0x60, 0x92, 0x23, 0x4b, 0xd3, 0x9d, 0x36, 0xb8, 0x1a, 0xa4, 0x1a, 0xf7, 0xb1, 0x60, 0xfb, 0x74, 0x16, 0xa6, 0xdc, 0xe1, 0x14, 0xb7, 0xed, 0x48, 0x5a, 0x2b, 0xed, 0x68, 0x9d, 0x19, 0xd6, 0xb1, 0xb8, 0x91, 0xff, 0xea, 0x62, 0xac, 0xe7, 0x49, 0xdd, 0xfa, 0x4d, 0xa4, 0x01, 0x3f, 0xea, 0xca, 0xb4, 0xb6, 0xdc, 0xd3, 0x04, 0x45, 0x07, 0x74, 0xed, 0xa6, 0xdc, 0xe1, 0x14, 0xb7, 0xed, 0x48, 0x5a, 0xbb, 0x9b, 0x13, 0x31, 0xf4, 0xa9, 0x32, 0x49 }; unsigned char cipher[80] = {}; int cipher_len = 0; int offset = 0; ctx = PPP_CIPHER_CTX_new(); if (ctx) { if (PPP_CipherInit(ctx, PPP_des_ecb(), key, NULL, 1)) { if (PPP_CipherUpdate(ctx, cipher, &cipher_len, plain, sizeof(plain))) { offset += cipher_len; if (PPP_CipherFinal(ctx, cipher+offset, &cipher_len)) { if (memcmp(cipher, expect, 80) == 0) { success = 1; } } } } PPP_CIPHER_CTX_free(ctx); } return success; } int test_des_decrypt() { PPP_CIPHER_CTX* ctx = NULL; int success = 0; unsigned char key[8] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 }; unsigned char cipher[80] = { 0x45, 0xdb, 0x80, 0x45, 0x16, 0xd0, 0x6d, 0x60, 0x92, 0x23, 0x4b, 0xd3, 0x9d, 0x36, 0xb8, 0x1a, 0xa4, 0x1a, 0xf7, 0xb1, 0x60, 0xfb, 0x74, 0x16, 0xa6, 0xdc, 0xe1, 0x14, 0xb7, 0xed, 0x48, 0x5a, 0x2b, 0xed, 0x68, 0x9d, 0x19, 0xd6, 0xb1, 0xb8, 0x91, 0xff, 0xea, 0x62, 0xac, 0xe7, 0x49, 0xdd, 0xfa, 0x4d, 0xa4, 0x01, 0x3f, 0xea, 0xca, 0xb4, 0xb6, 0xdc, 0xd3, 0x04, 0x45, 0x07, 0x74, 0xed, 0xa6, 0xdc, 0xe1, 0x14, 0xb7, 0xed, 0x48, 0x5a, 0xbb, 0x9b, 0x13, 0x31, 0xf4, 0xa9, 0x32, 0x49 }; unsigned char expect[80] = { 0x4f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x20, 0x73, 0x69, 0x64, 0x65, 0x2c, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x65, 0x6e, 0x64, 0x20, 0x6b, 0x65, 0x79, 0x3b, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x73, 0x69, 0x64, 0x65, 0x2c, 0x20, 0x69, 0x74, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x20 }; unsigned char plain[80] = {}; int outlen = 0; int offset = 0; ctx = PPP_CIPHER_CTX_new(); if (ctx) { if (PPP_CipherInit(ctx, PPP_des_ecb(), key, NULL, 0)) { if (PPP_CipherUpdate(ctx, plain, &outlen, cipher, sizeof(cipher))) { offset += outlen; if (PPP_CipherFinal(ctx, plain+offset, &outlen)) { if (memcmp(plain, expect, 80) == 0) { success = 1; } } } } PPP_CIPHER_CTX_free(ctx); } return success; } int main(int argc, char *argv[]) { int failure = 0; if (!PPP_crypto_init()) { printf("Couldn't initialize crypto test\n"); return -1; } if (!test_md4()) { printf("MD4 test failed\n"); failure++; } if (!test_md5()) { printf("MD5 test failed\n"); failure++; } if (!test_sha()) { printf("SHA test failed\n"); failure++; } if (!test_des_encrypt()) { printf("DES encryption test failed\n"); failure++; } if (!test_des_decrypt()) { printf("DES decryption test failed\n"); failure++; } if (!PPP_crypto_deinit()) { printf("Couldn't deinitialize crypto test\n"); return -1; } return failure; } #endif ppp-2.5.0/pppd/ppp-md5.c0000644000175000017500000003610114353435407011640 00000000000000/* ppp-md5.c - MD5 Digest implementation * * Copyright (c) 2022 Eivind Næss. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The name(s) of the authors of this software must not be used to * endorse or promote products derived from this software without * prior written permission. * * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * Sections of this code holds different copyright information. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include "crypto-priv.h" #ifdef OPENSSL_HAVE_MD5 #include #if OPENSSL_VERSION_NUMBER < 0x10100000L #define EVP_MD_CTX_free EVP_MD_CTX_destroy #define EVP_MD_CTX_new EVP_MD_CTX_create #endif static int md5_init(PPP_MD_CTX *ctx) { if (ctx) { EVP_MD_CTX *mctx = EVP_MD_CTX_new(); if (mctx) { if (EVP_DigestInit((EVP_MD_CTX*) mctx, EVP_md5())) { ctx->priv = mctx; return 1; } EVP_MD_CTX_free(mctx); } } return 0; } static int md5_update(PPP_MD_CTX *ctx, const void *data, size_t len) { if (EVP_DigestUpdate((EVP_MD_CTX*) ctx->priv, data, len)) { return 1; } return 0; } static int md5_final(PPP_MD_CTX *ctx, unsigned char *out, unsigned int *len) { if (EVP_DigestFinal((EVP_MD_CTX*) ctx->priv, out, len)) { return 1; } return 0; } static void md5_clean(PPP_MD_CTX *ctx) { if (ctx->priv) { EVP_MD_CTX_free((EVP_MD_CTX*) ctx->priv); ctx->priv = NULL; } } #else // !OPENSSL_HAVE_MD5 /* *********************************************************************** ** md5.c -- the source code for MD5 routines ** ** RSA Data Security, Inc. MD5 Message-Digest Algorithm ** ** Created: 2/17/90 RLR ** ** Revised: 1/91 SRD,AJ,BSK,JT Reference C ver., 7/10 constant corr. ** *********************************************************************** */ /* *********************************************************************** ** Copyright (C) 1990, RSA Data Security, Inc. All rights reserved. ** ** ** ** License to copy and use this software is granted provided that ** ** it is identified as the "RSA Data Security, Inc. MD5 Message- ** ** Digest Algorithm" in all material mentioning or referencing this ** ** software or this function. ** ** ** ** License is also granted to make and use derivative works ** ** provided that such works are identified as "derived from the RSA ** ** Data Security, Inc. MD5 Message-Digest Algorithm" in all ** ** material mentioning or referencing the derived work. ** ** ** ** RSA Data Security, Inc. makes no representations concerning ** ** either the merchantability of this software or the suitability ** ** of this software for any particular purpose. It is provided "as ** ** is" without express or implied warranty of any kind. ** ** ** ** These notices must be retained in any copies of any part of this ** ** documentation and/or software. ** *********************************************************************** */ /* typedef a 32-bit type */ #ifdef _LP64 typedef unsigned int UINT4; typedef int INT4; #else typedef unsigned long UINT4; typedef long INT4; #endif #define _UINT4_T /* Data structure for MD5 (Message-Digest) computation */ typedef struct { UINT4 i[2]; /* number of _bits_ handled mod 2^64 */ UINT4 buf[4]; /* scratch buffer */ unsigned char in[64]; /* input buffer */ unsigned char digest[16]; /* actual digest after MD5Final call */ } MD5_CTX; /* *********************************************************************** ** Message-digest routines: ** ** To form the message digest for a message M ** ** (1) Initialize a context buffer mdContext using MD5_Init ** ** (2) Call MD5_Update on mdContext and M ** ** (3) Call MD5_Final on mdContext ** ** The message digest is now in mdContext->digest[0...15] ** *********************************************************************** */ /* forward declaration */ static void Transform (UINT4 *buf, UINT4 *in); static unsigned char PADDING[64] = { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; /* F, G, H and I are basic MD5 functions */ #define F(x, y, z) (((x) & (y)) | ((~x) & (z))) #define G(x, y, z) (((x) & (z)) | ((y) & (~z))) #define H(x, y, z) ((x) ^ (y) ^ (z)) #define I(x, y, z) ((y) ^ ((x) | (~z))) /* ROTATE_LEFT rotates x left n bits */ #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n)))) /* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4 */ /* Rotation is separate from addition to prevent recomputation */ #define FF(a, b, c, d, x, s, ac) \ {(a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \ (a) = ROTATE_LEFT ((a), (s)); \ (a) += (b); \ } #define GG(a, b, c, d, x, s, ac) \ {(a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \ (a) = ROTATE_LEFT ((a), (s)); \ (a) += (b); \ } #define HH(a, b, c, d, x, s, ac) \ {(a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \ (a) = ROTATE_LEFT ((a), (s)); \ (a) += (b); \ } #define II(a, b, c, d, x, s, ac) \ {(a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \ (a) = ROTATE_LEFT ((a), (s)); \ (a) += (b); \ } #ifdef __STDC__ #define UL(x) x##U #else #define UL(x) x #endif /* The routine MD5_Init initializes the message-digest context mdContext. All fields are set to zero. */ static void MD5_Init (MD5_CTX *mdContext) { mdContext->i[0] = mdContext->i[1] = (UINT4)0; /* Load magic initialization constants. */ mdContext->buf[0] = (UINT4)0x67452301; mdContext->buf[1] = (UINT4)0xefcdab89; mdContext->buf[2] = (UINT4)0x98badcfe; mdContext->buf[3] = (UINT4)0x10325476; } /* The routine MD5Update updates the message-digest context to account for the presence of each of the characters inBuf[0..inLen-1] in the message whose digest is being computed. */ static void MD5_Update (MD5_CTX *mdContext, unsigned char *inBuf, unsigned int inLen) { UINT4 in[16]; int mdi; unsigned int i, ii; /* compute number of bytes mod 64 */ mdi = (int)((mdContext->i[0] >> 3) & 0x3F); /* update number of bits */ if ((mdContext->i[0] + ((UINT4)inLen << 3)) < mdContext->i[0]) mdContext->i[1]++; mdContext->i[0] += ((UINT4)inLen << 3); mdContext->i[1] += ((UINT4)inLen >> 29); while (inLen--) { /* add new character to buffer, increment mdi */ mdContext->in[mdi++] = *inBuf++; /* transform if necessary */ if (mdi == 0x40) { for (i = 0, ii = 0; i < 16; i++, ii += 4) in[i] = (((UINT4)mdContext->in[ii+3]) << 24) | (((UINT4)mdContext->in[ii+2]) << 16) | (((UINT4)mdContext->in[ii+1]) << 8) | ((UINT4)mdContext->in[ii]); Transform (mdContext->buf, in); mdi = 0; } } } /* The routine MD5Final terminates the message-digest computation and ends with the desired message digest in mdContext->digest[0...15]. */ static void MD5_Final (unsigned char hash[], MD5_CTX *mdContext) { UINT4 in[16]; int mdi; unsigned int i, ii; unsigned int padLen; /* save number of bits */ in[14] = mdContext->i[0]; in[15] = mdContext->i[1]; /* compute number of bytes mod 64 */ mdi = (int)((mdContext->i[0] >> 3) & 0x3F); /* pad out to 56 mod 64 */ padLen = (mdi < 56) ? (56 - mdi) : (120 - mdi); MD5_Update (mdContext, PADDING, padLen); /* append length in bits and transform */ for (i = 0, ii = 0; i < 14; i++, ii += 4) in[i] = (((UINT4)mdContext->in[ii+3]) << 24) | (((UINT4)mdContext->in[ii+2]) << 16) | (((UINT4)mdContext->in[ii+1]) << 8) | ((UINT4)mdContext->in[ii]); Transform (mdContext->buf, in); /* store buffer in digest */ for (i = 0, ii = 0; i < 4; i++, ii += 4) { mdContext->digest[ii] = (unsigned char)(mdContext->buf[i] & 0xFF); mdContext->digest[ii+1] = (unsigned char)((mdContext->buf[i] >> 8) & 0xFF); mdContext->digest[ii+2] = (unsigned char)((mdContext->buf[i] >> 16) & 0xFF); mdContext->digest[ii+3] = (unsigned char)((mdContext->buf[i] >> 24) & 0xFF); } memcpy(hash, mdContext->digest, 16); } /* Basic MD5 step. Transforms buf based on in. */ static void Transform (UINT4 *buf, UINT4 *in) { UINT4 a = buf[0], b = buf[1], c = buf[2], d = buf[3]; /* Round 1 */ #define S11 7 #define S12 12 #define S13 17 #define S14 22 FF ( a, b, c, d, in[ 0], S11, UL(3614090360)); /* 1 */ FF ( d, a, b, c, in[ 1], S12, UL(3905402710)); /* 2 */ FF ( c, d, a, b, in[ 2], S13, UL( 606105819)); /* 3 */ FF ( b, c, d, a, in[ 3], S14, UL(3250441966)); /* 4 */ FF ( a, b, c, d, in[ 4], S11, UL(4118548399)); /* 5 */ FF ( d, a, b, c, in[ 5], S12, UL(1200080426)); /* 6 */ FF ( c, d, a, b, in[ 6], S13, UL(2821735955)); /* 7 */ FF ( b, c, d, a, in[ 7], S14, UL(4249261313)); /* 8 */ FF ( a, b, c, d, in[ 8], S11, UL(1770035416)); /* 9 */ FF ( d, a, b, c, in[ 9], S12, UL(2336552879)); /* 10 */ FF ( c, d, a, b, in[10], S13, UL(4294925233)); /* 11 */ FF ( b, c, d, a, in[11], S14, UL(2304563134)); /* 12 */ FF ( a, b, c, d, in[12], S11, UL(1804603682)); /* 13 */ FF ( d, a, b, c, in[13], S12, UL(4254626195)); /* 14 */ FF ( c, d, a, b, in[14], S13, UL(2792965006)); /* 15 */ FF ( b, c, d, a, in[15], S14, UL(1236535329)); /* 16 */ /* Round 2 */ #define S21 5 #define S22 9 #define S23 14 #define S24 20 GG ( a, b, c, d, in[ 1], S21, UL(4129170786)); /* 17 */ GG ( d, a, b, c, in[ 6], S22, UL(3225465664)); /* 18 */ GG ( c, d, a, b, in[11], S23, UL( 643717713)); /* 19 */ GG ( b, c, d, a, in[ 0], S24, UL(3921069994)); /* 20 */ GG ( a, b, c, d, in[ 5], S21, UL(3593408605)); /* 21 */ GG ( d, a, b, c, in[10], S22, UL( 38016083)); /* 22 */ GG ( c, d, a, b, in[15], S23, UL(3634488961)); /* 23 */ GG ( b, c, d, a, in[ 4], S24, UL(3889429448)); /* 24 */ GG ( a, b, c, d, in[ 9], S21, UL( 568446438)); /* 25 */ GG ( d, a, b, c, in[14], S22, UL(3275163606)); /* 26 */ GG ( c, d, a, b, in[ 3], S23, UL(4107603335)); /* 27 */ GG ( b, c, d, a, in[ 8], S24, UL(1163531501)); /* 28 */ GG ( a, b, c, d, in[13], S21, UL(2850285829)); /* 29 */ GG ( d, a, b, c, in[ 2], S22, UL(4243563512)); /* 30 */ GG ( c, d, a, b, in[ 7], S23, UL(1735328473)); /* 31 */ GG ( b, c, d, a, in[12], S24, UL(2368359562)); /* 32 */ /* Round 3 */ #define S31 4 #define S32 11 #define S33 16 #define S34 23 HH ( a, b, c, d, in[ 5], S31, UL(4294588738)); /* 33 */ HH ( d, a, b, c, in[ 8], S32, UL(2272392833)); /* 34 */ HH ( c, d, a, b, in[11], S33, UL(1839030562)); /* 35 */ HH ( b, c, d, a, in[14], S34, UL(4259657740)); /* 36 */ HH ( a, b, c, d, in[ 1], S31, UL(2763975236)); /* 37 */ HH ( d, a, b, c, in[ 4], S32, UL(1272893353)); /* 38 */ HH ( c, d, a, b, in[ 7], S33, UL(4139469664)); /* 39 */ HH ( b, c, d, a, in[10], S34, UL(3200236656)); /* 40 */ HH ( a, b, c, d, in[13], S31, UL( 681279174)); /* 41 */ HH ( d, a, b, c, in[ 0], S32, UL(3936430074)); /* 42 */ HH ( c, d, a, b, in[ 3], S33, UL(3572445317)); /* 43 */ HH ( b, c, d, a, in[ 6], S34, UL( 76029189)); /* 44 */ HH ( a, b, c, d, in[ 9], S31, UL(3654602809)); /* 45 */ HH ( d, a, b, c, in[12], S32, UL(3873151461)); /* 46 */ HH ( c, d, a, b, in[15], S33, UL( 530742520)); /* 47 */ HH ( b, c, d, a, in[ 2], S34, UL(3299628645)); /* 48 */ /* Round 4 */ #define S41 6 #define S42 10 #define S43 15 #define S44 21 II ( a, b, c, d, in[ 0], S41, UL(4096336452)); /* 49 */ II ( d, a, b, c, in[ 7], S42, UL(1126891415)); /* 50 */ II ( c, d, a, b, in[14], S43, UL(2878612391)); /* 51 */ II ( b, c, d, a, in[ 5], S44, UL(4237533241)); /* 52 */ II ( a, b, c, d, in[12], S41, UL(1700485571)); /* 53 */ II ( d, a, b, c, in[ 3], S42, UL(2399980690)); /* 54 */ II ( c, d, a, b, in[10], S43, UL(4293915773)); /* 55 */ II ( b, c, d, a, in[ 1], S44, UL(2240044497)); /* 56 */ II ( a, b, c, d, in[ 8], S41, UL(1873313359)); /* 57 */ II ( d, a, b, c, in[15], S42, UL(4264355552)); /* 58 */ II ( c, d, a, b, in[ 6], S43, UL(2734768916)); /* 59 */ II ( b, c, d, a, in[13], S44, UL(1309151649)); /* 60 */ II ( a, b, c, d, in[ 4], S41, UL(4149444226)); /* 61 */ II ( d, a, b, c, in[11], S42, UL(3174756917)); /* 62 */ II ( c, d, a, b, in[ 2], S43, UL( 718787259)); /* 63 */ II ( b, c, d, a, in[ 9], S44, UL(3951481745)); /* 64 */ buf[0] += a; buf[1] += b; buf[2] += c; buf[3] += d; } /* *********************************************************************** ** End of md5.c ** ******************************** (cut) ******************************** */ static int md5_init(PPP_MD_CTX *ctx) { if (ctx) { MD5_CTX *md5 = calloc(1, sizeof(MD5_CTX)); if (md5 != NULL) { MD5_Init(md5); ctx->priv = md5; return 1; } } return 0; } static int md5_update(PPP_MD_CTX *ctx, const void *data, size_t len) { MD5_Update((MD5_CTX*) ctx->priv, (void*) data, len); return 1; } static int md5_final(PPP_MD_CTX *ctx, unsigned char *out, unsigned int *len) { MD5_Final(out, (MD5_CTX*) ctx->priv); return 1; } static void md5_clean(PPP_MD_CTX *ctx) { if (ctx->priv) { free(ctx->priv); ctx->priv = NULL; } } #endif static PPP_MD ppp_md5 = { .init_fn = md5_init, .update_fn = md5_update, .final_fn = md5_final, .clean_fn = md5_clean, }; const PPP_MD *PPP_md5(void) { return &ppp_md5; } ppp-2.5.0/pppd/ppp-md4.c0000644000175000017500000003041314407475306011641 00000000000000/* ppp-md4.c - MD4 Digest implementation * * Copyright (c) 2022 Eivind Næss. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The name(s) of the authors of this software must not be used to * endorse or promote products derived from this software without * prior written permission. * * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * Sections of this code holds different copyright information. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include "crypto-priv.h" #ifdef OPENSSL_HAVE_MD4 #include #if OPENSSL_VERSION_NUMBER < 0x10100000L #define EVP_MD_CTX_free EVP_MD_CTX_destroy #define EVP_MD_CTX_new EVP_MD_CTX_create #endif static int md4_init(PPP_MD_CTX *ctx) { if (ctx) { EVP_MD_CTX *mctx = EVP_MD_CTX_new(); if (mctx) { if (EVP_DigestInit(mctx, EVP_md4())) { ctx->priv = mctx; return 1; } EVP_MD_CTX_free(mctx); } } return 0; } static int md4_update(PPP_MD_CTX *ctx, const void *data, size_t len) { if (EVP_DigestUpdate((EVP_MD_CTX*) ctx->priv, data, len)) { return 1; } return 0; } static int md4_final(PPP_MD_CTX *ctx, unsigned char *out, unsigned int *len) { if (EVP_DigestFinal((EVP_MD_CTX*) ctx->priv, out, len)) { return 1; } return 0; } static void md4_clean(PPP_MD_CTX *ctx) { if (ctx->priv) { EVP_MD_CTX_free(ctx->priv); ctx->priv = NULL; } } #else // !OPENSSL_HAVE_MD4 #define TRUE 1 #define FALSE 0 /* ** ******************************************************************** ** md4.c -- Implementation of MD4 Message Digest Algorithm ** ** Updated: 2/16/90 by Ronald L. Rivest ** ** (C) 1990 RSA Data Security, Inc. ** ** ******************************************************************** */ /* ** To use MD4: ** -- Include md4.h in your program ** -- Declare an MDstruct MD to hold the state of the digest ** computation. ** -- Initialize MD using MDbegin(&MD) ** -- For each full block (64 bytes) X you wish to process, call ** MD4Update(&MD,X,512) ** (512 is the number of bits in a full block.) ** -- For the last block (less than 64 bytes) you wish to process, ** MD4Update(&MD,X,n) ** where n is the number of bits in the partial block. A partial ** block terminates the computation, so every MD computation ** should terminate by processing a partial block, even if it ** has n = 0. ** -- The message digest is available in MD.buffer[0] ... ** MD.buffer[3]. (Least-significant byte of each word ** should be output first.) ** -- You can print out the digest using MDprint(&MD) */ /* Implementation notes: ** This implementation assumes that ints are 32-bit quantities. */ /* MDstruct is the data structure for a message digest computation. */ typedef struct { unsigned int buffer[4]; /* Holds 4-word result of MD computation */ unsigned char count[8]; /* Number of bits processed so far */ unsigned int done; /* Nonzero means MD computation finished */ } MD4_CTX; /* Compile-time declarations of MD4 "magic constants". */ #define I0 0x67452301 /* Initial values for MD buffer */ #define I1 0xefcdab89 #define I2 0x98badcfe #define I3 0x10325476 #define C2 013240474631 /* round 2 constant = sqrt(2) in octal */ #define C3 015666365641 /* round 3 constant = sqrt(3) in octal */ /* C2 and C3 are from Knuth, The Art of Programming, Volume 2 ** (Seminumerical Algorithms), Second Edition (1981), Addison-Wesley. ** Table 2, page 660. */ #define fs1 3 /* round 1 shift amounts */ #define fs2 7 #define fs3 11 #define fs4 19 #define gs1 3 /* round 2 shift amounts */ #define gs2 5 #define gs3 9 #define gs4 13 #define hs1 3 /* round 3 shift amounts */ #define hs2 9 #define hs3 11 #define hs4 15 /* Compile-time macro declarations for MD4. ** Note: The "rot" operator uses the variable "tmp". ** It assumes tmp is declared as unsigned int, so that the >> ** operator will shift in zeros rather than extending the sign bit. */ #define f(X,Y,Z) ((X&Y) | ((~X)&Z)) #define g(X,Y,Z) ((X&Y) | (X&Z) | (Y&Z)) #define h(X,Y,Z) (X^Y^Z) #define rot(X,S) (tmp=X,(tmp<>(32-S))) #define ff(A,B,C,D,i,s) A = rot((A + f(B,C,D) + X[i]),s) #define gg(A,B,C,D,i,s) A = rot((A + g(B,C,D) + X[i] + C2),s) #define hh(A,B,C,D,i,s) A = rot((A + h(B,C,D) + X[i] + C3),s) /* MD4print(MDp) ** Print message digest buffer MDp as 32 hexadecimal digits. ** Order is from low-order byte of buffer[0] to high-order byte of ** buffer[3]. ** Each byte is printed with high-order hexadecimal digit first. ** This is a user-callable routine. */ static void MD4Print(MD4_CTX *MDp) { int i,j; for (i=0;i<4;i++) for (j=0;j<32;j=j+8) printf("%02x",(MDp->buffer[i]>>j) & 0xFF); } /* MD4Init(MDp) ** Initialize message digest buffer MDp. ** This is a user-callable routine. */ static void MD4Init(MD4_CTX *MDp) { int i; MDp->buffer[0] = I0; MDp->buffer[1] = I1; MDp->buffer[2] = I2; MDp->buffer[3] = I3; for (i=0;i<8;i++) MDp->count[i] = 0; MDp->done = 0; } /* MDblock(MDp,X) ** Update message digest buffer MDp->buffer using 16-word data block X. ** Assumes all 16 words of X are full of data. ** Does not update MDp->count. ** This routine is not user-callable. */ static void MDblock(MD4_CTX *MDp, unsigned char *Xb) { register unsigned int tmp, A, B, C, D; unsigned int X[16]; int i; for (i = 0; i < 16; ++i) { X[i] = Xb[0] + (Xb[1] << 8) + (Xb[2] << 16) + (Xb[3] << 24); Xb += 4; } A = MDp->buffer[0]; B = MDp->buffer[1]; C = MDp->buffer[2]; D = MDp->buffer[3]; /* Update the message digest buffer */ ff(A , B , C , D , 0 , fs1); /* Round 1 */ ff(D , A , B , C , 1 , fs2); ff(C , D , A , B , 2 , fs3); ff(B , C , D , A , 3 , fs4); ff(A , B , C , D , 4 , fs1); ff(D , A , B , C , 5 , fs2); ff(C , D , A , B , 6 , fs3); ff(B , C , D , A , 7 , fs4); ff(A , B , C , D , 8 , fs1); ff(D , A , B , C , 9 , fs2); ff(C , D , A , B , 10 , fs3); ff(B , C , D , A , 11 , fs4); ff(A , B , C , D , 12 , fs1); ff(D , A , B , C , 13 , fs2); ff(C , D , A , B , 14 , fs3); ff(B , C , D , A , 15 , fs4); gg(A , B , C , D , 0 , gs1); /* Round 2 */ gg(D , A , B , C , 4 , gs2); gg(C , D , A , B , 8 , gs3); gg(B , C , D , A , 12 , gs4); gg(A , B , C , D , 1 , gs1); gg(D , A , B , C , 5 , gs2); gg(C , D , A , B , 9 , gs3); gg(B , C , D , A , 13 , gs4); gg(A , B , C , D , 2 , gs1); gg(D , A , B , C , 6 , gs2); gg(C , D , A , B , 10 , gs3); gg(B , C , D , A , 14 , gs4); gg(A , B , C , D , 3 , gs1); gg(D , A , B , C , 7 , gs2); gg(C , D , A , B , 11 , gs3); gg(B , C , D , A , 15 , gs4); hh(A , B , C , D , 0 , hs1); /* Round 3 */ hh(D , A , B , C , 8 , hs2); hh(C , D , A , B , 4 , hs3); hh(B , C , D , A , 12 , hs4); hh(A , B , C , D , 2 , hs1); hh(D , A , B , C , 10 , hs2); hh(C , D , A , B , 6 , hs3); hh(B , C , D , A , 14 , hs4); hh(A , B , C , D , 1 , hs1); hh(D , A , B , C , 9 , hs2); hh(C , D , A , B , 5 , hs3); hh(B , C , D , A , 13 , hs4); hh(A , B , C , D , 3 , hs1); hh(D , A , B , C , 11 , hs2); hh(C , D , A , B , 7 , hs3); hh(B , C , D , A , 15 , hs4); MDp->buffer[0] += A; MDp->buffer[1] += B; MDp->buffer[2] += C; MDp->buffer[3] += D; } /* MD4Update(MDp,X,count) ** Input: X -- a pointer to an array of unsigned characters. ** count -- the number of bits of X to use. ** (if not a multiple of 8, uses high bits of last byte.) ** Update MDp using the number of bits of X given by count. ** This is the basic input routine for an MD4 user. ** The routine completes the MD computation when count < 512, so ** every MD computation should end with one call to MD4Update with a ** count less than 512. A call with count 0 will be ignored if the ** MD has already been terminated (done != 0), so an extra call with ** count 0 can be given as a "courtesy close" to force termination ** if desired. */ static void MD4Update(MD4_CTX *MDp, unsigned char *X, unsigned int count) { unsigned int i, tmp, bit, byte, mask; unsigned char XX[64]; unsigned char *p; /* return with no error if this is a courtesy close with count ** zero and MDp->done is true. */ if (count == 0 && MDp->done) return; /* check to see if MD is already done and report error */ if (MDp->done) { printf("\nError: MD4Update MD already done."); return; } /* Add count to MDp->count */ tmp = count; p = MDp->count; while (tmp) { tmp += *p; *p++ = tmp; tmp = tmp >> 8; } /* Process data */ if (count == 512) { /* Full block of data to handle */ MDblock(MDp,X); } else if (count > 512) /* Check for count too large */ { printf("\nError: MD4Update called with illegal count value %u.", count); return; } else /* partial block -- must be last block so finish up */ { /* Find out how many bytes and residual bits there are */ byte = count >> 3; bit = count & 7; /* Copy X into XX since we need to modify it */ if (count) for (i=0;i<=byte;i++) XX[i] = X[i]; for (i=byte+1;i<64;i++) XX[i] = 0; /* Add padding '1' bit and low-order zeros in last byte */ mask = 1 << (7 - bit); XX[byte] = (XX[byte] | mask) & ~( mask - 1); /* If room for bit count, finish up with this block */ if (byte <= 55) { for (i=0;i<8;i++) XX[56+i] = MDp->count[i]; MDblock(MDp,XX); } else /* need to do two blocks to finish up */ { MDblock(MDp,XX); for (i=0;i<56;i++) XX[i] = 0; for (i=0;i<8;i++) XX[56+i] = MDp->count[i]; MDblock(MDp,XX); } /* Set flag saying we're done with MD computation */ MDp->done = 1; } } /* ** Finish up MD4 computation and return message digest. */ static void MD4Final(unsigned char *buf, MD4_CTX *MD) { int i, j; unsigned int w; MD4Update(MD, NULL, 0); for (i = 0; i < 4; ++i) { w = MD->buffer[i]; for (j = 0; j < 4; ++j) { *buf++ = w; w >>= 8; } } } /* ** End of md4.c ****************************(cut)***********************************/ static int md4_init(PPP_MD_CTX *ctx) { if (ctx) { MD4_CTX *mctx = calloc(1, sizeof(MD4_CTX)); if (mctx) { MD4Init(mctx); ctx->priv = mctx; return 1; } } return 0; } static int md4_update(PPP_MD_CTX *ctx, const void *data, size_t len) { #if defined(__NetBSD__) /* NetBSD uses the libc md4 routines which take bytes instead of bits */ int mdlen = len; #else int mdlen = len * 8; #endif /* Internal MD4Update can take at most 64 bytes at a time */ while (mdlen > 512) { MD4Update((MD4_CTX*) ctx->priv, (unsigned char*) data, 512); data += 64; mdlen -= 512; } MD4Update((MD4_CTX*) ctx->priv, (unsigned char*) data, mdlen); return 1; } static int md4_final(PPP_MD_CTX *ctx, unsigned char *out, unsigned int *len) { MD4Final(out, (MD4_CTX*) ctx->priv); return 1; } static void md4_clean(PPP_MD_CTX *ctx) { if (ctx->priv) { free(ctx->priv); ctx->priv = NULL; } } #endif static PPP_MD ppp_md4 = { .init_fn = md4_init, .update_fn = md4_update, .final_fn = md4_final, .clean_fn = md4_clean, }; const PPP_MD *PPP_md4(void) { return &ppp_md4; } ppp-2.5.0/pppd/ppp-sha1.c0000644000175000017500000002201614353435407012007 00000000000000/* ppp-sha1.c - SHA1 Digest implementation * * Copyright (c) 2022 Eivind Næss. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The name(s) of the authors of this software must not be used to * endorse or promote products derived from this software without * prior written permission. * * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * Sections of this code holds different copyright information. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include "crypto-priv.h" /* #define SHA1HANDSOFF * Copies data before messing with it. */ #ifdef OPENSSL_HAVE_SHA #include #if OPENSSL_VERSION_NUMBER < 0x10100000L #define EVP_MD_CTX_free EVP_MD_CTX_destroy #define EVP_MD_CTX_new EVP_MD_CTX_create #endif static int sha1_init(PPP_MD_CTX *ctx) { if (ctx) { EVP_MD_CTX *mctx = EVP_MD_CTX_new(); if (mctx) { if (EVP_DigestInit(mctx, EVP_sha1())) { ctx->priv = mctx; return 1; } EVP_MD_CTX_free(mctx); } } return 0; } static int sha1_update(PPP_MD_CTX *ctx, const void *data, size_t len) { if (EVP_DigestUpdate((EVP_MD_CTX*) ctx->priv, data, len)) { return 1; } return 0; } static int sha1_final(PPP_MD_CTX *ctx, unsigned char *out, unsigned int *len) { if (EVP_DigestFinal((EVP_MD_CTX*) ctx->priv, out, len)) { return 1; } return 0; } static void sha1_clean(PPP_MD_CTX *ctx) { if (ctx->priv) { EVP_MD_CTX_free((EVP_MD_CTX*) ctx->priv); ctx->priv = NULL; } } #else // !OPENSSL_HAVE_SHA /* * ftp://ftp.funet.fi/pub/crypt/hash/sha/sha1.c * * SHA-1 in C * By Steve Reid * 100% Public Domain * * Test Vectors (from FIPS PUB 180-1) * "abc" * A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D * "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" * 84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1 * A million repetitions of "a" * 34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F */ #include #include /* htonl() */ typedef struct { u_int32_t state[5]; u_int32_t count[2]; unsigned char buffer[64]; } SHA1_CTX; static void SHA1_Transform(u_int32_t[5], const unsigned char[64]); #define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits)))) /* blk0() and blk() perform the initial expand. */ /* I got the idea of expanding during the round function from SSLeay */ #define blk0(i) (block->l[i] = htonl(block->l[i])) #define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \ ^block->l[(i+2)&15]^block->l[i&15],1)) /* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */ #define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30); #define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30); #define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30); #define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30); #define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30); /* Hash a single 512-bit block. This is the core of the algorithm. */ static void SHA1_Transform(u_int32_t state[5], const unsigned char buffer[64]) { u_int32_t a, b, c, d, e; typedef union { unsigned char c[64]; u_int32_t l[16]; } CHAR64LONG16; CHAR64LONG16 *block; #ifdef SHA1HANDSOFF static unsigned char workspace[64]; block = (CHAR64LONG16 *) workspace; memcpy(block, buffer, 64); #else block = (CHAR64LONG16 *) buffer; #endif /* Copy context->state[] to working vars */ a = state[0]; b = state[1]; c = state[2]; d = state[3]; e = state[4]; /* 4 rounds of 20 operations each. Loop unrolled. */ R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3); R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7); R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11); R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15); R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19); R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23); R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27); R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31); R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35); R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39); R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43); R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47); R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51); R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55); R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59); R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63); R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67); R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71); R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75); R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79); /* Add the working vars back into context.state[] */ state[0] += a; state[1] += b; state[2] += c; state[3] += d; state[4] += e; /* Wipe variables */ a = b = c = d = e = 0; } /* SHA1Init - Initialize new context */ static void SHA1_Init(SHA1_CTX *context) { /* SHA1 initialization constants */ context->state[0] = 0x67452301; context->state[1] = 0xEFCDAB89; context->state[2] = 0x98BADCFE; context->state[3] = 0x10325476; context->state[4] = 0xC3D2E1F0; context->count[0] = context->count[1] = 0; } /* Run your data through this. */ static void SHA1_Update(SHA1_CTX *context, const unsigned char *data, unsigned int len) { unsigned int i, j; j = (context->count[0] >> 3) & 63; if ((context->count[0] += len << 3) < (len << 3)) context->count[1]++; context->count[1] += (len >> 29); i = 64 - j; while (len >= i) { memcpy(&context->buffer[j], data, i); SHA1_Transform(context->state, context->buffer); data += i; len -= i; i = 64; j = 0; } memcpy(&context->buffer[j], data, len); } /* Add padding and return the message digest. */ static void SHA1_Final(unsigned char digest[20], SHA1_CTX *context) { u_int32_t i, j; unsigned char finalcount[8]; for (i = 0; i < 8; i++) { finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)] >> ((3-(i & 3)) * 8) ) & 255); /* Endian independent */ } SHA1_Update(context, (unsigned char *) "\200", 1); while ((context->count[0] & 504) != 448) { SHA1_Update(context, (unsigned char *) "\0", 1); } SHA1_Update(context, finalcount, 8); /* Should cause a SHA1Transform() */ for (i = 0; i < 20; i++) { digest[i] = (unsigned char) ((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255); } /* Wipe variables */ i = j = 0; memset(context->buffer, 0, 64); memset(context->state, 0, 20); memset(context->count, 0, 8); memset(&finalcount, 0, 8); #ifdef SHA1HANDSOFF /* make SHA1Transform overwrite it's own static vars */ SHA1Transform(context->state, context->buffer); #endif } static int sha1_init(PPP_MD_CTX *ctx) { if (ctx) { SHA1_CTX *mctx = calloc(1, sizeof(SHA1_CTX)); if (mctx) { SHA1_Init(mctx); ctx->priv = mctx; return 1; } } return 0; } static int sha1_update(PPP_MD_CTX* ctx, const void *data, size_t len) { SHA1_Update((SHA1_CTX*) ctx->priv, (void*) data, len); return 1; } static int sha1_final(PPP_MD_CTX *ctx, unsigned char *out, unsigned int *len) { SHA1_Final(out, (SHA1_CTX*) ctx->priv); return 1; } static void sha1_clean(PPP_MD_CTX *ctx) { if (ctx->priv) { free(ctx->priv); ctx->priv = NULL; } } #endif static PPP_MD ppp_sha1 = { .init_fn = sha1_init, .update_fn = sha1_update, .final_fn = sha1_final, .clean_fn = sha1_clean, }; const PPP_MD *PPP_sha1(void) { return &ppp_sha1; } ppp-2.5.0/pppd/ppp-des.c0000644000175000017500000006672414353435407011744 00000000000000/* * ppp-des.c - PPP/DES implementation for MS-CHAP and EAP SRP-SHA1 * * Extracted from chap_ms.c by James Carlson. * Added abstraction via PPP_Digest* callbacks by Eivind Næss * * Copyright (c) 1995 Eric Rosenquist. All rights reserved. * Copyright (c) 2022 Eivind Næss. All rights reserved. * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The name(s) of the authors of this software must not be used to * endorse or promote products derived from this software without * prior written permission. * * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * Sections of this code holds different copyright information. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include "crypto-priv.h" #ifdef OPENSSL_HAVE_DES #include #if OPENSSL_VERSION_NUMBER < 0x10100000L #define EVP_CIPHER_CTX_reset EVP_CIPHER_CTX_cleanup #endif static int des_init(PPP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv) { if (ctx) { EVP_CIPHER_CTX *cc = EVP_CIPHER_CTX_new(); if (cc) { if (key) { memcpy(ctx->key, key, 8); } if (iv) { memcpy(ctx->iv, iv, 8); } if (EVP_CipherInit(cc, EVP_des_ecb(), ctx->key, ctx->iv, ctx->is_encr)) { if (EVP_CIPHER_CTX_set_padding(cc, 0)) { ctx->priv = cc; return 1; } } EVP_CIPHER_CTX_free(cc); } } return 0; } static int des_update(PPP_CIPHER_CTX *ctx, unsigned char *out, int *outl, const unsigned char *in, int inl) { if (ctx) { return EVP_CipherUpdate((EVP_CIPHER_CTX*) ctx->priv, out, outl, in, inl); } return 0; } static int des_final(PPP_CIPHER_CTX *ctx, unsigned char *out, int *outl) { if (ctx) { return EVP_CipherFinal((EVP_CIPHER_CTX*) ctx->priv, out, outl); } return 0; } static void des_clean(PPP_CIPHER_CTX *ctx) { if (ctx->priv) { EVP_CIPHER_CTX_free((EVP_CIPHER_CTX*) ctx->priv); ctx->priv = NULL; } } #else /* * DES related functions are imported from openssl 3.0 project with the * follwoing license: * * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy * in the file LICENSE in the source distribution or at * https://www.openssl.org/source/license.html */ typedef unsigned int DES_LONG; typedef unsigned char DES_cblock[8]; typedef struct DES_ks { union { DES_cblock cblock; /* * make sure things are correct size on machines with 8 byte longs */ DES_LONG deslong[2]; } ks[16]; } DES_key_schedule; #define c2l(c,l) (l =((DES_LONG)(*((c)++))) , \ l|=((DES_LONG)(*((c)++)))<< 8L, \ l|=((DES_LONG)(*((c)++)))<<16L, \ l|=((DES_LONG)(*((c)++)))<<24L) # define l2c(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \ *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \ *((c)++)=(unsigned char)(((l)>>16L)&0xff), \ *((c)++)=(unsigned char)(((l)>>24L)&0xff)) #define ITERATIONS 16 #define ROTATE(a,n) (((a)>>(n))+((a)<<(32-(n)))) # define PERM_OP(a,b,t,n,m) ((t)=((((a)>>(n))^(b))&(m)),\ (b)^=(t),\ (a)^=((t)<<(n))) #define HPERM_OP(a,t,n,m) ((t)=((((a)<<(16-(n)))^(a))&(m)),\ (a)=(a)^(t)^(t>>(16-(n)))) # define IP(l,r) \ { \ register DES_LONG tt; \ PERM_OP(r,l,tt, 4,0x0f0f0f0fL); \ PERM_OP(l,r,tt,16,0x0000ffffL); \ PERM_OP(r,l,tt, 2,0x33333333L); \ PERM_OP(l,r,tt, 8,0x00ff00ffL); \ PERM_OP(r,l,tt, 1,0x55555555L); \ } # define FP(l,r) \ { \ register DES_LONG tt; \ PERM_OP(l,r,tt, 1,0x55555555L); \ PERM_OP(r,l,tt, 8,0x00ff00ffL); \ PERM_OP(l,r,tt, 2,0x33333333L); \ PERM_OP(r,l,tt,16,0x0000ffffL); \ PERM_OP(l,r,tt, 4,0x0f0f0f0fL); \ } #define LOAD_DATA_tmp(a,b,c,d,e,f) LOAD_DATA(a,b,c,d,e,f,g) #define LOAD_DATA(R,S,u,t,E0,E1,tmp) \ u=R^s[S ]; \ t=R^s[S+1] #define D_ENCRYPT(LL,R,S) { \ LOAD_DATA_tmp(R,S,u,t,E0,E1); \ t=ROTATE(t,4); \ LL^= \ DES_SPtrans[0][(u>> 2L)&0x3f]^ \ DES_SPtrans[2][(u>>10L)&0x3f]^ \ DES_SPtrans[4][(u>>18L)&0x3f]^ \ DES_SPtrans[6][(u>>26L)&0x3f]^ \ DES_SPtrans[1][(t>> 2L)&0x3f]^ \ DES_SPtrans[3][(t>>10L)&0x3f]^ \ DES_SPtrans[5][(t>>18L)&0x3f]^ \ DES_SPtrans[7][(t>>26L)&0x3f]; } static const DES_LONG DES_SPtrans[8][64] = { { /* nibble 0 */ 0x02080800L, 0x00080000L, 0x02000002L, 0x02080802L, 0x02000000L, 0x00080802L, 0x00080002L, 0x02000002L, 0x00080802L, 0x02080800L, 0x02080000L, 0x00000802L, 0x02000802L, 0x02000000L, 0x00000000L, 0x00080002L, 0x00080000L, 0x00000002L, 0x02000800L, 0x00080800L, 0x02080802L, 0x02080000L, 0x00000802L, 0x02000800L, 0x00000002L, 0x00000800L, 0x00080800L, 0x02080002L, 0x00000800L, 0x02000802L, 0x02080002L, 0x00000000L, 0x00000000L, 0x02080802L, 0x02000800L, 0x00080002L, 0x02080800L, 0x00080000L, 0x00000802L, 0x02000800L, 0x02080002L, 0x00000800L, 0x00080800L, 0x02000002L, 0x00080802L, 0x00000002L, 0x02000002L, 0x02080000L, 0x02080802L, 0x00080800L, 0x02080000L, 0x02000802L, 0x02000000L, 0x00000802L, 0x00080002L, 0x00000000L, 0x00080000L, 0x02000000L, 0x02000802L, 0x02080800L, 0x00000002L, 0x02080002L, 0x00000800L, 0x00080802L, }, { /* nibble 1 */ 0x40108010L, 0x00000000L, 0x00108000L, 0x40100000L, 0x40000010L, 0x00008010L, 0x40008000L, 0x00108000L, 0x00008000L, 0x40100010L, 0x00000010L, 0x40008000L, 0x00100010L, 0x40108000L, 0x40100000L, 0x00000010L, 0x00100000L, 0x40008010L, 0x40100010L, 0x00008000L, 0x00108010L, 0x40000000L, 0x00000000L, 0x00100010L, 0x40008010L, 0x00108010L, 0x40108000L, 0x40000010L, 0x40000000L, 0x00100000L, 0x00008010L, 0x40108010L, 0x00100010L, 0x40108000L, 0x40008000L, 0x00108010L, 0x40108010L, 0x00100010L, 0x40000010L, 0x00000000L, 0x40000000L, 0x00008010L, 0x00100000L, 0x40100010L, 0x00008000L, 0x40000000L, 0x00108010L, 0x40008010L, 0x40108000L, 0x00008000L, 0x00000000L, 0x40000010L, 0x00000010L, 0x40108010L, 0x00108000L, 0x40100000L, 0x40100010L, 0x00100000L, 0x00008010L, 0x40008000L, 0x40008010L, 0x00000010L, 0x40100000L, 0x00108000L, }, { /* nibble 2 */ 0x04000001L, 0x04040100L, 0x00000100L, 0x04000101L, 0x00040001L, 0x04000000L, 0x04000101L, 0x00040100L, 0x04000100L, 0x00040000L, 0x04040000L, 0x00000001L, 0x04040101L, 0x00000101L, 0x00000001L, 0x04040001L, 0x00000000L, 0x00040001L, 0x04040100L, 0x00000100L, 0x00000101L, 0x04040101L, 0x00040000L, 0x04000001L, 0x04040001L, 0x04000100L, 0x00040101L, 0x04040000L, 0x00040100L, 0x00000000L, 0x04000000L, 0x00040101L, 0x04040100L, 0x00000100L, 0x00000001L, 0x00040000L, 0x00000101L, 0x00040001L, 0x04040000L, 0x04000101L, 0x00000000L, 0x04040100L, 0x00040100L, 0x04040001L, 0x00040001L, 0x04000000L, 0x04040101L, 0x00000001L, 0x00040101L, 0x04000001L, 0x04000000L, 0x04040101L, 0x00040000L, 0x04000100L, 0x04000101L, 0x00040100L, 0x04000100L, 0x00000000L, 0x04040001L, 0x00000101L, 0x04000001L, 0x00040101L, 0x00000100L, 0x04040000L, }, { /* nibble 3 */ 0x00401008L, 0x10001000L, 0x00000008L, 0x10401008L, 0x00000000L, 0x10400000L, 0x10001008L, 0x00400008L, 0x10401000L, 0x10000008L, 0x10000000L, 0x00001008L, 0x10000008L, 0x00401008L, 0x00400000L, 0x10000000L, 0x10400008L, 0x00401000L, 0x00001000L, 0x00000008L, 0x00401000L, 0x10001008L, 0x10400000L, 0x00001000L, 0x00001008L, 0x00000000L, 0x00400008L, 0x10401000L, 0x10001000L, 0x10400008L, 0x10401008L, 0x00400000L, 0x10400008L, 0x00001008L, 0x00400000L, 0x10000008L, 0x00401000L, 0x10001000L, 0x00000008L, 0x10400000L, 0x10001008L, 0x00000000L, 0x00001000L, 0x00400008L, 0x00000000L, 0x10400008L, 0x10401000L, 0x00001000L, 0x10000000L, 0x10401008L, 0x00401008L, 0x00400000L, 0x10401008L, 0x00000008L, 0x10001000L, 0x00401008L, 0x00400008L, 0x00401000L, 0x10400000L, 0x10001008L, 0x00001008L, 0x10000000L, 0x10000008L, 0x10401000L, }, { /* nibble 4 */ 0x08000000L, 0x00010000L, 0x00000400L, 0x08010420L, 0x08010020L, 0x08000400L, 0x00010420L, 0x08010000L, 0x00010000L, 0x00000020L, 0x08000020L, 0x00010400L, 0x08000420L, 0x08010020L, 0x08010400L, 0x00000000L, 0x00010400L, 0x08000000L, 0x00010020L, 0x00000420L, 0x08000400L, 0x00010420L, 0x00000000L, 0x08000020L, 0x00000020L, 0x08000420L, 0x08010420L, 0x00010020L, 0x08010000L, 0x00000400L, 0x00000420L, 0x08010400L, 0x08010400L, 0x08000420L, 0x00010020L, 0x08010000L, 0x00010000L, 0x00000020L, 0x08000020L, 0x08000400L, 0x08000000L, 0x00010400L, 0x08010420L, 0x00000000L, 0x00010420L, 0x08000000L, 0x00000400L, 0x00010020L, 0x08000420L, 0x00000400L, 0x00000000L, 0x08010420L, 0x08010020L, 0x08010400L, 0x00000420L, 0x00010000L, 0x00010400L, 0x08010020L, 0x08000400L, 0x00000420L, 0x00000020L, 0x00010420L, 0x08010000L, 0x08000020L, }, { /* nibble 5 */ 0x80000040L, 0x00200040L, 0x00000000L, 0x80202000L, 0x00200040L, 0x00002000L, 0x80002040L, 0x00200000L, 0x00002040L, 0x80202040L, 0x00202000L, 0x80000000L, 0x80002000L, 0x80000040L, 0x80200000L, 0x00202040L, 0x00200000L, 0x80002040L, 0x80200040L, 0x00000000L, 0x00002000L, 0x00000040L, 0x80202000L, 0x80200040L, 0x80202040L, 0x80200000L, 0x80000000L, 0x00002040L, 0x00000040L, 0x00202000L, 0x00202040L, 0x80002000L, 0x00002040L, 0x80000000L, 0x80002000L, 0x00202040L, 0x80202000L, 0x00200040L, 0x00000000L, 0x80002000L, 0x80000000L, 0x00002000L, 0x80200040L, 0x00200000L, 0x00200040L, 0x80202040L, 0x00202000L, 0x00000040L, 0x80202040L, 0x00202000L, 0x00200000L, 0x80002040L, 0x80000040L, 0x80200000L, 0x00202040L, 0x00000000L, 0x00002000L, 0x80000040L, 0x80002040L, 0x80202000L, 0x80200000L, 0x00002040L, 0x00000040L, 0x80200040L, }, { /* nibble 6 */ 0x00004000L, 0x00000200L, 0x01000200L, 0x01000004L, 0x01004204L, 0x00004004L, 0x00004200L, 0x00000000L, 0x01000000L, 0x01000204L, 0x00000204L, 0x01004000L, 0x00000004L, 0x01004200L, 0x01004000L, 0x00000204L, 0x01000204L, 0x00004000L, 0x00004004L, 0x01004204L, 0x00000000L, 0x01000200L, 0x01000004L, 0x00004200L, 0x01004004L, 0x00004204L, 0x01004200L, 0x00000004L, 0x00004204L, 0x01004004L, 0x00000200L, 0x01000000L, 0x00004204L, 0x01004000L, 0x01004004L, 0x00000204L, 0x00004000L, 0x00000200L, 0x01000000L, 0x01004004L, 0x01000204L, 0x00004204L, 0x00004200L, 0x00000000L, 0x00000200L, 0x01000004L, 0x00000004L, 0x01000200L, 0x00000000L, 0x01000204L, 0x01000200L, 0x00004200L, 0x00000204L, 0x00004000L, 0x01004204L, 0x01000000L, 0x01004200L, 0x00000004L, 0x00004004L, 0x01004204L, 0x01000004L, 0x01004200L, 0x01004000L, 0x00004004L, }, { /* nibble 7 */ 0x20800080L, 0x20820000L, 0x00020080L, 0x00000000L, 0x20020000L, 0x00800080L, 0x20800000L, 0x20820080L, 0x00000080L, 0x20000000L, 0x00820000L, 0x00020080L, 0x00820080L, 0x20020080L, 0x20000080L, 0x20800000L, 0x00020000L, 0x00820080L, 0x00800080L, 0x20020000L, 0x20820080L, 0x20000080L, 0x00000000L, 0x00820000L, 0x20000000L, 0x00800000L, 0x20020080L, 0x20800080L, 0x00800000L, 0x00020000L, 0x20820000L, 0x00000080L, 0x00800000L, 0x00020000L, 0x20000080L, 0x20820080L, 0x00020080L, 0x20000000L, 0x00000000L, 0x00820000L, 0x20800080L, 0x20020080L, 0x20020000L, 0x00800080L, 0x20820000L, 0x00000080L, 0x00800080L, 0x20020000L, 0x20820080L, 0x00800000L, 0x20800000L, 0x20000080L, 0x00820000L, 0x00020080L, 0x20020080L, 0x20800000L, 0x00000080L, 0x20820000L, 0x00820080L, 0x00000000L, 0x20000000L, 0x20800080L, 0x00020000L, 0x00820080L, } }; static const DES_LONG des_skb[8][64] = { { /* for C bits (numbered as per FIPS 46) 1 2 3 4 5 6 */ 0x00000000L, 0x00000010L, 0x20000000L, 0x20000010L, 0x00010000L, 0x00010010L, 0x20010000L, 0x20010010L, 0x00000800L, 0x00000810L, 0x20000800L, 0x20000810L, 0x00010800L, 0x00010810L, 0x20010800L, 0x20010810L, 0x00000020L, 0x00000030L, 0x20000020L, 0x20000030L, 0x00010020L, 0x00010030L, 0x20010020L, 0x20010030L, 0x00000820L, 0x00000830L, 0x20000820L, 0x20000830L, 0x00010820L, 0x00010830L, 0x20010820L, 0x20010830L, 0x00080000L, 0x00080010L, 0x20080000L, 0x20080010L, 0x00090000L, 0x00090010L, 0x20090000L, 0x20090010L, 0x00080800L, 0x00080810L, 0x20080800L, 0x20080810L, 0x00090800L, 0x00090810L, 0x20090800L, 0x20090810L, 0x00080020L, 0x00080030L, 0x20080020L, 0x20080030L, 0x00090020L, 0x00090030L, 0x20090020L, 0x20090030L, 0x00080820L, 0x00080830L, 0x20080820L, 0x20080830L, 0x00090820L, 0x00090830L, 0x20090820L, 0x20090830L, }, { /* for C bits (numbered as per FIPS 46) 7 8 10 11 12 13 */ 0x00000000L, 0x02000000L, 0x00002000L, 0x02002000L, 0x00200000L, 0x02200000L, 0x00202000L, 0x02202000L, 0x00000004L, 0x02000004L, 0x00002004L, 0x02002004L, 0x00200004L, 0x02200004L, 0x00202004L, 0x02202004L, 0x00000400L, 0x02000400L, 0x00002400L, 0x02002400L, 0x00200400L, 0x02200400L, 0x00202400L, 0x02202400L, 0x00000404L, 0x02000404L, 0x00002404L, 0x02002404L, 0x00200404L, 0x02200404L, 0x00202404L, 0x02202404L, 0x10000000L, 0x12000000L, 0x10002000L, 0x12002000L, 0x10200000L, 0x12200000L, 0x10202000L, 0x12202000L, 0x10000004L, 0x12000004L, 0x10002004L, 0x12002004L, 0x10200004L, 0x12200004L, 0x10202004L, 0x12202004L, 0x10000400L, 0x12000400L, 0x10002400L, 0x12002400L, 0x10200400L, 0x12200400L, 0x10202400L, 0x12202400L, 0x10000404L, 0x12000404L, 0x10002404L, 0x12002404L, 0x10200404L, 0x12200404L, 0x10202404L, 0x12202404L, }, { /* for C bits (numbered as per FIPS 46) 14 15 16 17 19 20 */ 0x00000000L, 0x00000001L, 0x00040000L, 0x00040001L, 0x01000000L, 0x01000001L, 0x01040000L, 0x01040001L, 0x00000002L, 0x00000003L, 0x00040002L, 0x00040003L, 0x01000002L, 0x01000003L, 0x01040002L, 0x01040003L, 0x00000200L, 0x00000201L, 0x00040200L, 0x00040201L, 0x01000200L, 0x01000201L, 0x01040200L, 0x01040201L, 0x00000202L, 0x00000203L, 0x00040202L, 0x00040203L, 0x01000202L, 0x01000203L, 0x01040202L, 0x01040203L, 0x08000000L, 0x08000001L, 0x08040000L, 0x08040001L, 0x09000000L, 0x09000001L, 0x09040000L, 0x09040001L, 0x08000002L, 0x08000003L, 0x08040002L, 0x08040003L, 0x09000002L, 0x09000003L, 0x09040002L, 0x09040003L, 0x08000200L, 0x08000201L, 0x08040200L, 0x08040201L, 0x09000200L, 0x09000201L, 0x09040200L, 0x09040201L, 0x08000202L, 0x08000203L, 0x08040202L, 0x08040203L, 0x09000202L, 0x09000203L, 0x09040202L, 0x09040203L, }, { /* for C bits (numbered as per FIPS 46) 21 23 24 26 27 28 */ 0x00000000L, 0x00100000L, 0x00000100L, 0x00100100L, 0x00000008L, 0x00100008L, 0x00000108L, 0x00100108L, 0x00001000L, 0x00101000L, 0x00001100L, 0x00101100L, 0x00001008L, 0x00101008L, 0x00001108L, 0x00101108L, 0x04000000L, 0x04100000L, 0x04000100L, 0x04100100L, 0x04000008L, 0x04100008L, 0x04000108L, 0x04100108L, 0x04001000L, 0x04101000L, 0x04001100L, 0x04101100L, 0x04001008L, 0x04101008L, 0x04001108L, 0x04101108L, 0x00020000L, 0x00120000L, 0x00020100L, 0x00120100L, 0x00020008L, 0x00120008L, 0x00020108L, 0x00120108L, 0x00021000L, 0x00121000L, 0x00021100L, 0x00121100L, 0x00021008L, 0x00121008L, 0x00021108L, 0x00121108L, 0x04020000L, 0x04120000L, 0x04020100L, 0x04120100L, 0x04020008L, 0x04120008L, 0x04020108L, 0x04120108L, 0x04021000L, 0x04121000L, 0x04021100L, 0x04121100L, 0x04021008L, 0x04121008L, 0x04021108L, 0x04121108L, }, { /* for D bits (numbered as per FIPS 46) 1 2 3 4 5 6 */ 0x00000000L, 0x10000000L, 0x00010000L, 0x10010000L, 0x00000004L, 0x10000004L, 0x00010004L, 0x10010004L, 0x20000000L, 0x30000000L, 0x20010000L, 0x30010000L, 0x20000004L, 0x30000004L, 0x20010004L, 0x30010004L, 0x00100000L, 0x10100000L, 0x00110000L, 0x10110000L, 0x00100004L, 0x10100004L, 0x00110004L, 0x10110004L, 0x20100000L, 0x30100000L, 0x20110000L, 0x30110000L, 0x20100004L, 0x30100004L, 0x20110004L, 0x30110004L, 0x00001000L, 0x10001000L, 0x00011000L, 0x10011000L, 0x00001004L, 0x10001004L, 0x00011004L, 0x10011004L, 0x20001000L, 0x30001000L, 0x20011000L, 0x30011000L, 0x20001004L, 0x30001004L, 0x20011004L, 0x30011004L, 0x00101000L, 0x10101000L, 0x00111000L, 0x10111000L, 0x00101004L, 0x10101004L, 0x00111004L, 0x10111004L, 0x20101000L, 0x30101000L, 0x20111000L, 0x30111000L, 0x20101004L, 0x30101004L, 0x20111004L, 0x30111004L, }, { /* for D bits (numbered as per FIPS 46) 8 9 11 12 13 14 */ 0x00000000L, 0x08000000L, 0x00000008L, 0x08000008L, 0x00000400L, 0x08000400L, 0x00000408L, 0x08000408L, 0x00020000L, 0x08020000L, 0x00020008L, 0x08020008L, 0x00020400L, 0x08020400L, 0x00020408L, 0x08020408L, 0x00000001L, 0x08000001L, 0x00000009L, 0x08000009L, 0x00000401L, 0x08000401L, 0x00000409L, 0x08000409L, 0x00020001L, 0x08020001L, 0x00020009L, 0x08020009L, 0x00020401L, 0x08020401L, 0x00020409L, 0x08020409L, 0x02000000L, 0x0A000000L, 0x02000008L, 0x0A000008L, 0x02000400L, 0x0A000400L, 0x02000408L, 0x0A000408L, 0x02020000L, 0x0A020000L, 0x02020008L, 0x0A020008L, 0x02020400L, 0x0A020400L, 0x02020408L, 0x0A020408L, 0x02000001L, 0x0A000001L, 0x02000009L, 0x0A000009L, 0x02000401L, 0x0A000401L, 0x02000409L, 0x0A000409L, 0x02020001L, 0x0A020001L, 0x02020009L, 0x0A020009L, 0x02020401L, 0x0A020401L, 0x02020409L, 0x0A020409L, }, { /* for D bits (numbered as per FIPS 46) 16 17 18 19 20 21 */ 0x00000000L, 0x00000100L, 0x00080000L, 0x00080100L, 0x01000000L, 0x01000100L, 0x01080000L, 0x01080100L, 0x00000010L, 0x00000110L, 0x00080010L, 0x00080110L, 0x01000010L, 0x01000110L, 0x01080010L, 0x01080110L, 0x00200000L, 0x00200100L, 0x00280000L, 0x00280100L, 0x01200000L, 0x01200100L, 0x01280000L, 0x01280100L, 0x00200010L, 0x00200110L, 0x00280010L, 0x00280110L, 0x01200010L, 0x01200110L, 0x01280010L, 0x01280110L, 0x00000200L, 0x00000300L, 0x00080200L, 0x00080300L, 0x01000200L, 0x01000300L, 0x01080200L, 0x01080300L, 0x00000210L, 0x00000310L, 0x00080210L, 0x00080310L, 0x01000210L, 0x01000310L, 0x01080210L, 0x01080310L, 0x00200200L, 0x00200300L, 0x00280200L, 0x00280300L, 0x01200200L, 0x01200300L, 0x01280200L, 0x01280300L, 0x00200210L, 0x00200310L, 0x00280210L, 0x00280310L, 0x01200210L, 0x01200310L, 0x01280210L, 0x01280310L, }, { /* for D bits (numbered as per FIPS 46) 22 23 24 25 27 28 */ 0x00000000L, 0x04000000L, 0x00040000L, 0x04040000L, 0x00000002L, 0x04000002L, 0x00040002L, 0x04040002L, 0x00002000L, 0x04002000L, 0x00042000L, 0x04042000L, 0x00002002L, 0x04002002L, 0x00042002L, 0x04042002L, 0x00000020L, 0x04000020L, 0x00040020L, 0x04040020L, 0x00000022L, 0x04000022L, 0x00040022L, 0x04040022L, 0x00002020L, 0x04002020L, 0x00042020L, 0x04042020L, 0x00002022L, 0x04002022L, 0x00042022L, 0x04042022L, 0x00000800L, 0x04000800L, 0x00040800L, 0x04040800L, 0x00000802L, 0x04000802L, 0x00040802L, 0x04040802L, 0x00002800L, 0x04002800L, 0x00042800L, 0x04042800L, 0x00002802L, 0x04002802L, 0x00042802L, 0x04042802L, 0x00000820L, 0x04000820L, 0x00040820L, 0x04040820L, 0x00000822L, 0x04000822L, 0x00040822L, 0x04040822L, 0x00002820L, 0x04002820L, 0x00042820L, 0x04042820L, 0x00002822L, 0x04002822L, 0x00042822L, 0x04042822L, } }; static void DES_encrypt1(DES_LONG *data, DES_key_schedule *ks, int enc) { register DES_LONG l, r, t, u; register DES_LONG *s; r = data[0]; l = data[1]; IP(r, l); /* * Things have been modified so that the initial rotate is done outside * the loop. This required the DES_SPtrans values in sp.h to be rotated * 1 bit to the right. One perl script later and things have a 5% speed * up on a sparc2. Thanks to Richard Outerbridge for pointing this out. */ /* clear the top bits on machines with 8byte longs */ /* shift left by 2 */ r = ROTATE(r, 29) & 0xffffffffL; l = ROTATE(l, 29) & 0xffffffffL; s = ks->ks->deslong; /* * I don't know if it is worth the effort of loop unrolling the inner * loop */ if (enc) { D_ENCRYPT(l, r, 0); /* 1 */ D_ENCRYPT(r, l, 2); /* 2 */ D_ENCRYPT(l, r, 4); /* 3 */ D_ENCRYPT(r, l, 6); /* 4 */ D_ENCRYPT(l, r, 8); /* 5 */ D_ENCRYPT(r, l, 10); /* 6 */ D_ENCRYPT(l, r, 12); /* 7 */ D_ENCRYPT(r, l, 14); /* 8 */ D_ENCRYPT(l, r, 16); /* 9 */ D_ENCRYPT(r, l, 18); /* 10 */ D_ENCRYPT(l, r, 20); /* 11 */ D_ENCRYPT(r, l, 22); /* 12 */ D_ENCRYPT(l, r, 24); /* 13 */ D_ENCRYPT(r, l, 26); /* 14 */ D_ENCRYPT(l, r, 28); /* 15 */ D_ENCRYPT(r, l, 30); /* 16 */ } else { D_ENCRYPT(l, r, 30); /* 16 */ D_ENCRYPT(r, l, 28); /* 15 */ D_ENCRYPT(l, r, 26); /* 14 */ D_ENCRYPT(r, l, 24); /* 13 */ D_ENCRYPT(l, r, 22); /* 12 */ D_ENCRYPT(r, l, 20); /* 11 */ D_ENCRYPT(l, r, 18); /* 10 */ D_ENCRYPT(r, l, 16); /* 9 */ D_ENCRYPT(l, r, 14); /* 8 */ D_ENCRYPT(r, l, 12); /* 7 */ D_ENCRYPT(l, r, 10); /* 6 */ D_ENCRYPT(r, l, 8); /* 5 */ D_ENCRYPT(l, r, 6); /* 4 */ D_ENCRYPT(r, l, 4); /* 3 */ D_ENCRYPT(l, r, 2); /* 2 */ D_ENCRYPT(r, l, 0); /* 1 */ } /* rotate and clear the top bits on machines with 8byte longs */ l = ROTATE(l, 3) & 0xffffffffL; r = ROTATE(r, 3) & 0xffffffffL; FP(r, l); data[0] = l; data[1] = r; l = r = t = u = 0; } static void DES_ecb_encrypt(const DES_cblock *input, DES_cblock *output, DES_key_schedule *ks, int enc) { register DES_LONG l; DES_LONG ll[2]; const unsigned char *in = &(*input)[0]; unsigned char *out = &(*output)[0]; c2l(in, l); ll[0] = l; c2l(in, l); ll[1] = l; DES_encrypt1(ll, ks, enc); l = ll[0]; l2c(l, out); l = ll[1]; l2c(l, out); l = ll[0] = ll[1] = 0; } static void DES_set_key(const DES_cblock *key, DES_key_schedule *schedule) { static const int shifts2[16] = { 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0 }; register DES_LONG c, d, t, s, t2; register const unsigned char *in; register DES_LONG *k; register int i; #ifdef OPENBSD_DEV_CRYPTO memcpy(schedule->key, key, sizeof(schedule->key)); schedule->session = NULL; #endif k = &schedule->ks->deslong[0]; in = &(*key)[0]; c2l(in, c); c2l(in, d); /* * do PC1 in 47 simple operations. Thanks to John Fletcher * for the inspiration. */ PERM_OP(d, c, t, 4, 0x0f0f0f0fL); HPERM_OP(c, t, -2, 0xcccc0000L); HPERM_OP(d, t, -2, 0xcccc0000L); PERM_OP(d, c, t, 1, 0x55555555L); PERM_OP(c, d, t, 8, 0x00ff00ffL); PERM_OP(d, c, t, 1, 0x55555555L); d = (((d & 0x000000ffL) << 16L) | (d & 0x0000ff00L) | ((d & 0x00ff0000L) >> 16L) | ((c & 0xf0000000L) >> 4L)); c &= 0x0fffffffL; for (i = 0; i < ITERATIONS; i++) { if (shifts2[i]) { c = ((c >> 2L) | (c << 26L)); d = ((d >> 2L) | (d << 26L)); } else { c = ((c >> 1L) | (c << 27L)); d = ((d >> 1L) | (d << 27L)); } c &= 0x0fffffffL; d &= 0x0fffffffL; /* * could be a few less shifts but I am to lazy at this point in time * to investigate */ s = des_skb[0][(c) & 0x3f] | des_skb[1][((c >> 6L) & 0x03) | ((c >> 7L) & 0x3c)] | des_skb[2][((c >> 13L) & 0x0f) | ((c >> 14L) & 0x30)] | des_skb[3][((c >> 20L) & 0x01) | ((c >> 21L) & 0x06) | ((c >> 22L) & 0x38)]; t = des_skb[4][(d) & 0x3f] | des_skb[5][((d >> 7L) & 0x03) | ((d >> 8L) & 0x3c)] | des_skb[6][(d >> 15L) & 0x3f] | des_skb[7][((d >> 21L) & 0x0f) | ((d >> 22L) & 0x30)]; /* table contained 0213 4657 */ t2 = ((t << 16L) | (s & 0x0000ffffL)) & 0xffffffffL; *(k++) = ROTATE(t2, 30) & 0xffffffffL; t2 = ((s >> 16L) | (t & 0xffff0000L)); *(k++) = ROTATE(t2, 26) & 0xffffffffL; } } /* End of import of OpenSSL DES encryption functions */ static int des_init(PPP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv) { DES_key_schedule *ks = calloc(1, sizeof(DES_key_schedule)); if (ks) { if (key) { memcpy(ctx->key, key, 8); } if (iv) { memcpy(ctx->iv, iv, 8); } if (key) { DES_set_key((DES_cblock*) &ctx->key, ks); } ctx->priv = ks; return 1; } return 0; } static int des_update(PPP_CIPHER_CTX *ctx, unsigned char *out, int *outl, const unsigned char *in, int inl) { int offset = 0; inl = inl / 8; while (offset < inl) { DES_ecb_encrypt((DES_cblock *)in + offset, (DES_cblock *)out + offset, (DES_key_schedule*) ctx->priv, ctx->is_encr); offset ++; } *outl = offset * 8; return 1; } static int des_final(PPP_CIPHER_CTX *ctx, unsigned char *out, int *outl) { return 1; } static void des_clean(PPP_CIPHER_CTX *ctx) { if (ctx->priv) { free(ctx->priv); ctx->priv = NULL; } } #endif static PPP_CIPHER ppp_des = { .init_fn = des_init, .update_fn = des_update, .final_fn = des_final, .clean_fn = des_clean, }; const PPP_CIPHER *PPP_des_ecb(void) { return &ppp_des; } ppp-2.5.0/pppd/auth.c0000644000175000017500000021362214407475306011326 00000000000000/* * auth.c - PPP authentication and phase control. * * Copyright (c) 1993-2002 Paul Mackerras. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. The name(s) of the authors of this software must not be used to * endorse or promote products derived from this software without * prior written permission. * * 3. Redistributions of any form whatsoever must retain the following * acknowledgment: * "This product includes software developed by Paul Mackerras * ". * * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * Derived from main.c, which is: * * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The name "Carnegie Mellon University" must not be used to * endorse or promote products derived from this software without * prior written permission. For permission or any legal * details, please contact * Office of Technology Transfer * Carnegie Mellon University * 5000 Forbes Avenue * Pittsburgh, PA 15213-3890 * (412) 268-4387, fax: (412) 268-7395 * tech-transfer@andrew.cmu.edu * * 4. Redistributions of any form whatsoever must retain the following * acknowledgment: * "This product includes software developed by Computing Services * at Carnegie Mellon University (http://www.cmu.edu/computing/)." * * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #define RCSID "$Id: auth.c,v 1.117 2008/07/01 12:27:56 paulus Exp $" #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #if defined(_PATH_LASTLOG) && defined(__linux__) #include #endif #include #include #include #ifdef HAVE_SHADOW_H #include #ifndef PW_PPP #define PW_PPP PW_LOGIN #endif #endif #include #ifdef HAVE_CRYPT_H #include #endif #ifdef SYSTEMD #include #endif #include "pppd-private.h" #include "options.h" #include "fsm.h" #include "lcp.h" #include "ccp.h" #include "ecp.h" #include "ipcp.h" #include "upap.h" #include "chap.h" #include "eap.h" #ifdef PPP_WITH_EAPTLS #include "eap-tls.h" #endif #ifdef PPP_WITH_CBCP #include "cbcp.h" #endif #include "multilink.h" #include "pathnames.h" #include "session.h" /* Bits in scan_authfile return value */ #define NONWILD_SERVER 1 #define NONWILD_CLIENT 2 #define ISWILD(word) (word[0] == '*' && word[1] == 0) /* The name by which the peer authenticated itself to us. */ char peer_authname[MAXNAMELEN]; /* Records which authentication operations haven't completed yet. */ static int auth_pending[NUM_PPP]; /* Records which authentication operations have been completed. */ int auth_done[NUM_PPP]; /* List of addresses which the peer may use. */ static struct permitted_ip *addresses[NUM_PPP]; /* Wordlist giving addresses which the peer may use without authenticating itself. */ static struct wordlist *noauth_addrs; /* Remote telephone number, if available */ char remote_number[MAXNAMELEN]; /* Wordlist giving remote telephone numbers which may connect. */ static struct wordlist *permitted_numbers; /* Extra options to apply, from the secrets file entry for the peer. */ static struct wordlist *extra_options; /* Number of network protocols which we have opened. */ static int num_np_open; /* Number of network protocols which have come up. */ static int num_np_up; /* Set if we got the contents of passwd[] from the pap-secrets file. */ static int passwd_from_file; /* Set if we require authentication only because we have a default route. */ static bool default_auth; /* Hook to enable a plugin to control the idle time limit */ int (*idle_time_hook)(struct ppp_idle *) = NULL; /* Hook for a plugin to say whether we can possibly authenticate any peer */ pap_check_hook_fn *pap_check_hook = NULL; /* Hook for a plugin to check the PAP user and password */ pap_auth_hook_fn *pap_auth_hook = NULL; /* Hook for a plugin to know about the PAP user logout */ pap_logout_hook_fn *pap_logout_hook = NULL; /* Hook for a plugin to get the PAP password for authenticating us */ pap_passwd_hook_fn *pap_passwd_hook = NULL; /* Hook for a plugin to say if we can possibly authenticate a peer using CHAP */ chap_check_hook_fn *chap_check_hook = NULL; /* Hook for a plugin to get the CHAP password for authenticating us */ chap_passwd_hook_fn *chap_passwd_hook = NULL; #ifdef PPP_WITH_EAPTLS /* Hook for a plugin to get the EAP-TLS password for authenticating us */ eaptls_passwd_hook_fn *eaptls_passwd_hook = NULL; #endif /* Hook for a plugin to say whether it is OK if the peer refuses to authenticate. */ int (*null_auth_hook)(struct wordlist **paddrs, struct wordlist **popts) = NULL; int (*allowed_address_hook)(u_int32_t addr) = NULL; /* A notifier for when the peer has authenticated itself, and we are proceeding to the network phase. */ struct notifier *auth_up_notifier = NULL; /* A notifier for when the link goes down. */ struct notifier *link_down_notifier = NULL; /* * This is used to ensure that we don't start an auth-up/down * script while one is already running. */ enum script_state { s_down, s_up }; static enum script_state auth_state = s_down; static enum script_state auth_script_state = s_down; static pid_t auth_script_pid = 0; /* * Option variables. */ bool uselogin = 0; /* Use /etc/passwd for checking PAP */ bool session_mgmt = 0; /* Do session management (login records) */ bool cryptpap = 0; /* Passwords in pap-secrets are encrypted */ bool refuse_pap = 0; /* Don't wanna auth. ourselves with PAP */ bool refuse_chap = 0; /* Don't wanna auth. ourselves with CHAP */ bool refuse_eap = 0; /* Don't wanna auth. ourselves with EAP */ #ifdef PPP_WITH_CHAPMS bool refuse_mschap = 0; /* Don't wanna auth. ourselves with MS-CHAP */ bool refuse_mschap_v2 = 0; /* Don't wanna auth. ourselves with MS-CHAPv2 */ #else bool refuse_mschap = 1; /* Don't wanna auth. ourselves with MS-CHAP */ bool refuse_mschap_v2 = 1; /* Don't wanna auth. ourselves with MS-CHAPv2 */ #endif bool usehostname = 0; /* Use hostname for our_name */ bool auth_required = 0; /* Always require authentication from peer */ bool allow_any_ip = 0; /* Allow peer to use any IP address */ bool explicit_remote = 0; /* User specified explicit remote name */ bool explicit_user = 0; /* Set if "user" option supplied */ bool explicit_passwd = 0; /* Set if "password" option supplied */ char remote_name[MAXNAMELEN]; /* Peer's name for authentication */ #if defined(PPP_WITH_EAPTLS) || defined(PPP_WITH_PEAP) char *cacert_file = NULL; /* CA certificate file (pem format) */ char *ca_path = NULL; /* Directory with CA certificates */ char *crl_dir = NULL; /* Directory containing CRL files */ char *crl_file = NULL; /* Certificate Revocation List (CRL) file (pem format) */ char *max_tls_version = NULL; /* Maximum TLS protocol version (default=1.2) */ char *tls_verify_method = NULL; /* Verify certificate method */ bool tls_verify_key_usage = 0; /* Verify peer certificate key usage */ #endif #if defined(PPP_WITH_EAPTLS) char *cert_file = NULL; /* Client certificate file (pem format) */ char *privkey_file = NULL; /* Client private key file (pem format) */ char *pkcs12_file = NULL; /* Client private key envelope file (pkcs12 format) */ bool need_peer_eap = 0; /* Require peer to authenticate us */ #endif static char *uafname; /* name of most recent +ua file */ /* Prototypes for procedures local to this file. */ static void network_phase (int); static void check_idle (void *); static void connect_time_expired (void *); static int null_login (int); static int get_pap_passwd (char *); static int have_pap_secret (int *); static int have_chap_secret (char *, char *, int, int *); static int have_srp_secret(char *client, char *server, int need_ip, int *lacks_ipp); #ifdef PPP_WITH_EAPTLS static int have_eaptls_secret_server (char *client, char *server, int need_ip, int *lacks_ipp); static int have_eaptls_secret_client (char *client, char *server); static int scan_authfile_eaptls(FILE * f, char *client, char *server, char *cli_cert, char *serv_cert, char *ca_cert, char *pk, struct wordlist ** addrs, struct wordlist ** opts, char *filename, int flags); #endif static int ip_addr_check (u_int32_t, struct permitted_ip *); static int scan_authfile(FILE *, char *, char *, char *, struct wordlist **, struct wordlist **, char *, int); static void free_wordlist (struct wordlist *); static void auth_script (char *); static void auth_script_done (void *); static void set_allowed_addrs (int, struct wordlist *, struct wordlist *); static int some_ip_ok (struct wordlist *); static int setupapfile (char **); static int privgroup (char **); static int set_noauth_addr (char **); static int set_permitted_number (char **); static void check_access (FILE *, char *); static int wordlist_count (struct wordlist *); static void check_maxoctets (void *); /* * Authentication-related options. */ struct option auth_options[] = { { "auth", o_bool, &auth_required, "Require authentication from peer", OPT_PRIO | 1 }, { "noauth", o_bool, &auth_required, "Don't require peer to authenticate", OPT_PRIOSUB | OPT_PRIV, &allow_any_ip }, { "require-pap", o_bool, &lcp_wantoptions[0].neg_upap, "Require PAP authentication from peer", OPT_PRIOSUB | 1, &auth_required }, { "+pap", o_bool, &lcp_wantoptions[0].neg_upap, "Require PAP authentication from peer", OPT_ALIAS | OPT_PRIOSUB | 1, &auth_required }, { "require-chap", o_bool, &auth_required, "Require CHAP authentication from peer", OPT_PRIOSUB | OPT_A2OR | MDTYPE_MD5, &lcp_wantoptions[0].chap_mdtype }, { "+chap", o_bool, &auth_required, "Require CHAP authentication from peer", OPT_ALIAS | OPT_PRIOSUB | OPT_A2OR | MDTYPE_MD5, &lcp_wantoptions[0].chap_mdtype }, #ifdef PPP_WITH_CHAPMS { "require-mschap", o_bool, &auth_required, "Require MS-CHAP authentication from peer", OPT_PRIOSUB | OPT_A2OR | MDTYPE_MICROSOFT, &lcp_wantoptions[0].chap_mdtype }, { "+mschap", o_bool, &auth_required, "Require MS-CHAP authentication from peer", OPT_ALIAS | OPT_PRIOSUB | OPT_A2OR | MDTYPE_MICROSOFT, &lcp_wantoptions[0].chap_mdtype }, { "require-mschap-v2", o_bool, &auth_required, "Require MS-CHAPv2 authentication from peer", OPT_PRIOSUB | OPT_A2OR | MDTYPE_MICROSOFT_V2, &lcp_wantoptions[0].chap_mdtype }, { "+mschap-v2", o_bool, &auth_required, "Require MS-CHAPv2 authentication from peer", OPT_ALIAS | OPT_PRIOSUB | OPT_A2OR | MDTYPE_MICROSOFT_V2, &lcp_wantoptions[0].chap_mdtype }, #endif { "refuse-pap", o_bool, &refuse_pap, "Don't agree to auth to peer with PAP", 1 }, { "-pap", o_bool, &refuse_pap, "Don't allow PAP authentication with peer", OPT_ALIAS | 1 }, { "refuse-chap", o_bool, &refuse_chap, "Don't agree to auth to peer with CHAP", OPT_A2CLRB | MDTYPE_MD5, &lcp_allowoptions[0].chap_mdtype }, { "-chap", o_bool, &refuse_chap, "Don't allow CHAP authentication with peer", OPT_ALIAS | OPT_A2CLRB | MDTYPE_MD5, &lcp_allowoptions[0].chap_mdtype }, #ifdef PPP_WITH_CHAPMS { "refuse-mschap", o_bool, &refuse_mschap, "Don't agree to auth to peer with MS-CHAP", OPT_A2CLRB | MDTYPE_MICROSOFT, &lcp_allowoptions[0].chap_mdtype }, { "-mschap", o_bool, &refuse_mschap, "Don't allow MS-CHAP authentication with peer", OPT_ALIAS | OPT_A2CLRB | MDTYPE_MICROSOFT, &lcp_allowoptions[0].chap_mdtype }, { "refuse-mschap-v2", o_bool, &refuse_mschap_v2, "Don't agree to auth to peer with MS-CHAPv2", OPT_A2CLRB | MDTYPE_MICROSOFT_V2, &lcp_allowoptions[0].chap_mdtype }, { "-mschap-v2", o_bool, &refuse_mschap_v2, "Don't allow MS-CHAPv2 authentication with peer", OPT_ALIAS | OPT_A2CLRB | MDTYPE_MICROSOFT_V2, &lcp_allowoptions[0].chap_mdtype }, #endif { "require-eap", o_bool, &lcp_wantoptions[0].neg_eap, "Require EAP authentication from peer", OPT_PRIOSUB | 1, &auth_required }, { "refuse-eap", o_bool, &refuse_eap, "Don't agree to authenticate to peer with EAP", 1 }, { "name", o_string, our_name, "Set local name for authentication", OPT_PRIO | OPT_PRIV | OPT_STATIC, NULL, MAXNAMELEN }, { "+ua", o_special, (void *)setupapfile, "Get PAP user and password from file", OPT_PRIO | OPT_A2STRVAL, &uafname }, { "user", o_string, user, "Set name for auth with peer", OPT_PRIO | OPT_STATIC, &explicit_user, MAXNAMELEN }, { "password", o_string, passwd, "Password for authenticating us to the peer", OPT_PRIO | OPT_STATIC | OPT_HIDE, &explicit_passwd, MAXSECRETLEN }, { "usehostname", o_bool, &usehostname, "Must use hostname for authentication", 1 }, { "remotename", o_string, remote_name, "Set remote name for authentication", OPT_PRIO | OPT_STATIC, &explicit_remote, MAXNAMELEN }, { "login", o_bool, &uselogin, "Use system password database for PAP", OPT_A2COPY | 1 , &session_mgmt }, { "enable-session", o_bool, &session_mgmt, "Enable session accounting for remote peers", OPT_PRIV | 1 }, { "papcrypt", o_bool, &cryptpap, "PAP passwords are encrypted", 1 }, { "privgroup", o_special, (void *)privgroup, "Allow group members to use privileged options", OPT_PRIV | OPT_A2LIST }, { "allow-ip", o_special, (void *)set_noauth_addr, "Set IP address(es) which can be used without authentication", OPT_PRIV | OPT_A2LIST }, { "remotenumber", o_string, remote_number, "Set remote telephone number for authentication", OPT_PRIO | OPT_STATIC, NULL, MAXNAMELEN }, { "allow-number", o_special, (void *)set_permitted_number, "Set telephone number(s) which are allowed to connect", OPT_PRIV | OPT_A2LIST }, #if defined(PPP_WITH_EAPTLS) || defined(PPP_WITH_PEAP) { "ca", o_string, &cacert_file, "CA certificate in PEM format" }, { "capath", o_string, &ca_path, "TLS CA certificate directory" }, { "crl-dir", o_string, &crl_dir, "Use CRLs in directory" }, { "crl", o_string, &crl_file, "Use specific CRL file" }, { "max-tls-version", o_string, &max_tls_version, "Maximum TLS version (1.0/1.1/1.2 (default)/1.3)" }, { "tls-verify-key-usage", o_bool, &tls_verify_key_usage, "Verify certificate type and extended key usage" }, { "tls-verify-method", o_string, &tls_verify_method, "Verify peer by method (none|subject|name|suffix)" }, #endif #if defined(PPP_WITH_EAPTLS) { "cert", o_string, &cert_file, "client certificate in PEM format" }, { "key", o_string, &privkey_file, "client private key in PEM format" }, { "pkcs12", o_string, &pkcs12_file, "EAP-TLS client credentials in PKCS12 format" }, { "need-peer-eap", o_bool, &need_peer_eap, "Require the peer to authenticate us", 1 }, #endif /* PPP_WITH_EAPTLS */ { NULL } }; const char * ppp_remote_name() { return remote_name; } const char * ppp_get_remote_number(void) { return remote_number; } void ppp_set_remote_number(const char *buf) { if (buf) { strlcpy(remote_number, buf, sizeof(remote_number)); } } const char * ppp_peer_authname(char *buf, size_t bufsz) { if (buf && bufsz > 0) { strlcpy(buf, peer_authname, bufsz); return buf; } return peer_authname; } /* * setupapfile - specifies UPAP info for authenticating with peer. */ static int setupapfile(char **argv) { FILE *ufile; int l; uid_t euid; char u[MAXNAMELEN], p[MAXSECRETLEN]; char *fname; lcp_allowoptions[0].neg_upap = 1; /* open user info file */ fname = strdup(*argv); if (fname == NULL) novm("+ua file name"); euid = geteuid(); if (seteuid(getuid()) == -1) { ppp_option_error("unable to reset uid before opening %s: %m", fname); free(fname); return 0; } ufile = fopen(fname, "r"); if (seteuid(euid) == -1) fatal("unable to regain privileges: %m"); if (ufile == NULL) { ppp_option_error("unable to open user login data file %s", fname); free(fname); return 0; } check_access(ufile, fname); uafname = fname; /* get username */ if (fgets(u, MAXNAMELEN - 1, ufile) == NULL || fgets(p, MAXSECRETLEN - 1, ufile) == NULL) { fclose(ufile); ppp_option_error("unable to read user login data file %s", fname); free(fname); return 0; } fclose(ufile); /* get rid of newlines */ l = strlen(u); if (l > 0 && u[l-1] == '\n') u[l-1] = 0; l = strlen(p); if (l > 0 && p[l-1] == '\n') p[l-1] = 0; if (override_value("user", option_priority, fname)) { strlcpy(user, u, sizeof(user)); explicit_user = 1; } if (override_value("passwd", option_priority, fname)) { strlcpy(passwd, p, sizeof(passwd)); explicit_passwd = 1; } free(fname); return (1); } /* * privgroup - allow members of the group to have privileged access. */ static int privgroup(char **argv) { struct group *g; int i; g = getgrnam(*argv); if (g == 0) { ppp_option_error("group %s is unknown", *argv); return 0; } for (i = 0; i < ngroups; ++i) { if (groups[i] == g->gr_gid) { privileged = 1; break; } } return 1; } /* * set_noauth_addr - set address(es) that can be used without authentication. * Equivalent to specifying an entry like `"" * "" addr' in pap-secrets. */ static int set_noauth_addr(char **argv) { char *addr = *argv; int l = strlen(addr) + 1; struct wordlist *wp; wp = (struct wordlist *) malloc(sizeof(struct wordlist) + l); if (wp == NULL) novm("allow-ip argument"); wp->word = (char *) (wp + 1); wp->next = noauth_addrs; BCOPY(addr, wp->word, l); noauth_addrs = wp; return 1; } /* * set_permitted_number - set remote telephone number(s) that may connect. */ static int set_permitted_number(char **argv) { char *number = *argv; int l = strlen(number) + 1; struct wordlist *wp; wp = (struct wordlist *) malloc(sizeof(struct wordlist) + l); if (wp == NULL) novm("allow-number argument"); wp->word = (char *) (wp + 1); wp->next = permitted_numbers; BCOPY(number, wp->word, l); permitted_numbers = wp; return 1; } /* * An Open on LCP has requested a change from Dead to Establish phase. */ void link_required(int unit) { } /* * Bring the link up to the point of being able to do ppp. */ void start_link(int unit) { ppp_set_status(EXIT_CONNECT_FAILED); new_phase(PHASE_SERIALCONN); hungup = 0; devfd = the_channel->connect(); if (devfd < 0) goto fail; /* set up the serial device as a ppp interface */ /* * N.B. we used to do tdb_writelock/tdb_writeunlock around this * (from establish_ppp to set_ifunit). However, we won't be * doing the set_ifunit in multilink mode, which is the only time * we need the atomicity that the tdb_writelock/tdb_writeunlock * gives us. Thus we don't need the tdb_writelock/tdb_writeunlock. */ fd_ppp = the_channel->establish_ppp(devfd); if (fd_ppp < 0) { ppp_set_status(EXIT_FATAL_ERROR); goto disconnect; } if (!demand && ifunit >= 0) set_ifunit(1); /* * Start opening the connection and wait for * incoming events (reply, timeout, etc.). */ if (ifunit >= 0) notice("Connect: %s <--> %s", ifname, ppp_devname); else notice("Starting negotiation on %s", ppp_devname); add_fd(fd_ppp); ppp_set_status(EXIT_NEGOTIATION_FAILED); new_phase(PHASE_ESTABLISH); lcp_lowerup(0); return; disconnect: new_phase(PHASE_DISCONNECT); if (the_channel->disconnect) the_channel->disconnect(); fail: new_phase(PHASE_DEAD); if (the_channel->cleanup) (*the_channel->cleanup)(); } /* * LCP has terminated the link; go to the Dead phase and take the * physical layer down. */ void link_terminated(int unit) { if (in_phase(PHASE_DEAD) || in_phase(PHASE_MASTER)) return; new_phase(PHASE_DISCONNECT); if (pap_logout_hook) { pap_logout_hook(); } session_end(devnam); if (!mp_on()) { notice("Connection terminated."); print_link_stats(); } else notice("Link terminated."); /* * Delete pid files before disestablishing ppp. Otherwise it * can happen that another pppd gets the same unit and then * we delete its pid file. */ if (!demand && !mp_on()) remove_pidfiles(); /* * If we may want to bring the link up again, transfer * the ppp unit back to the loopback. Set the * real serial device back to its normal mode of operation. */ if (fd_ppp >= 0) { remove_fd(fd_ppp); clean_check(); the_channel->disestablish_ppp(devfd); if (mp_on()) mp_exit_bundle(); fd_ppp = -1; } if (!hungup) lcp_lowerdown(0); if (!mp_on() && !demand) ppp_script_unsetenv("IFNAME"); /* * Run disconnector script, if requested. * XXX we may not be able to do this if the line has hung up! */ if (devfd >= 0 && the_channel->disconnect) { the_channel->disconnect(); devfd = -1; } if (the_channel->cleanup) (*the_channel->cleanup)(); if (mp_on() && mp_master()) { if (!bundle_terminating) { new_phase(PHASE_MASTER); if (master_detach && !detached) detach(); } else mp_bundle_terminated(); } else new_phase(PHASE_DEAD); } /* * LCP has gone down; it will either die or try to re-establish. */ void link_down(int unit) { if (auth_state != s_down) { notify(link_down_notifier, 0); auth_state = s_down; if (auth_script_state == s_up && auth_script_pid == 0) { ppp_get_link_stats(NULL); auth_script_state = s_down; auth_script(PPP_PATH_AUTHDOWN); } } if (!mp_on()) { upper_layers_down(unit); if (!in_phase(PHASE_DEAD) && !in_phase(PHASE_MASTER)) new_phase(PHASE_ESTABLISH); } /* XXX if doing_multilink, should do something to stop network-layer traffic on the link */ } void upper_layers_down(int unit) { int i; struct protent *protp; for (i = 0; (protp = protocols[i]) != NULL; ++i) { if (!protp->enabled_flag) continue; if (protp->protocol != PPP_LCP && protp->lowerdown != NULL) (*protp->lowerdown)(unit); if (protp->protocol < 0xC000 && protp->close != NULL) (*protp->close)(unit, "LCP down"); } num_np_open = 0; num_np_up = 0; } /* * The link is established. * Proceed to the Dead, Authenticate or Network phase as appropriate. */ void link_established(int unit) { int auth; lcp_options *wo = &lcp_wantoptions[unit]; lcp_options *go = &lcp_gotoptions[unit]; lcp_options *ho = &lcp_hisoptions[unit]; #ifdef PPP_WITH_EAPTLS lcp_options *ao = &lcp_allowoptions[unit]; #endif int i; struct protent *protp; /* * Tell higher-level protocols that LCP is up. */ if (!mp_on()) for (i = 0; (protp = protocols[i]) != NULL; ++i) if (protp->protocol != PPP_LCP && protp->enabled_flag && protp->lowerup != NULL) (*protp->lowerup)(unit); if (!auth_required && noauth_addrs != NULL) set_allowed_addrs(unit, NULL, NULL); if (auth_required && !(go->neg_upap || go->neg_chap || go->neg_eap)) { /* * We wanted the peer to authenticate itself, and it refused: * if we have some address(es) it can use without auth, fine, * otherwise treat it as though it authenticated with PAP using * a username of "" and a password of "". If that's not OK, * boot it out. */ if (noauth_addrs != NULL) { set_allowed_addrs(unit, NULL, NULL); } else if (!wo->neg_upap || uselogin || !null_login(unit)) { warn("peer refused to authenticate: terminating link"); ppp_set_status(EXIT_PEER_AUTH_FAILED); lcp_close(unit, "peer refused to authenticate"); return; } } #ifdef PPP_WITH_EAPTLS if (need_peer_eap && !ao->neg_eap) { warn("eap required to authenticate us but no suitable secrets"); lcp_close(unit, "couldn't negotiate eap"); ppp_set_status(EXIT_AUTH_TOPEER_FAILED); return; } if (need_peer_eap && !ho->neg_eap) { warn("peer doesn't want to authenticate us with eap"); lcp_close(unit, "couldn't negotiate eap"); ppp_set_status(EXIT_PEER_AUTH_FAILED); return; } #endif new_phase(PHASE_AUTHENTICATE); auth = 0; if (go->neg_eap) { eap_authpeer(unit, our_name); auth |= EAP_PEER; } else if (go->neg_chap) { chap_auth_peer(unit, our_name, CHAP_DIGEST(go->chap_mdtype)); auth |= CHAP_PEER; } else if (go->neg_upap) { upap_authpeer(unit); auth |= PAP_PEER; } if (ho->neg_eap) { eap_authwithpeer(unit, user); auth |= EAP_WITHPEER; } else if (ho->neg_chap) { chap_auth_with_peer(unit, user, CHAP_DIGEST(ho->chap_mdtype)); auth |= CHAP_WITHPEER; } else if (ho->neg_upap) { /* If a blank password was explicitly given as an option, trust the user and don't try to look up one. */ if (passwd[0] == 0 && !explicit_passwd) { passwd_from_file = 1; if (!get_pap_passwd(passwd)) error("No secret found for PAP login"); } upap_authwithpeer(unit, user, passwd); auth |= PAP_WITHPEER; } auth_pending[unit] = auth; auth_done[unit] = 0; if (!auth) network_phase(unit); } /* * Proceed to the network phase. */ static void network_phase(int unit) { lcp_options *go = &lcp_gotoptions[unit]; /* Log calling number. */ if (*remote_number) notice("peer from calling number %q authorized", remote_number); /* * If the peer had to authenticate, run the auth-up script now. */ notify(auth_up_notifier, 0); if (go->neg_chap || go->neg_upap || go->neg_eap) { auth_state = s_up; if (auth_script_state == s_down && auth_script_pid == 0) { auth_script_state = s_up; auth_script(PPP_PATH_AUTHUP); } } #ifdef PPP_WITH_CBCP /* * If we negotiated callback, do it now. */ if (go->neg_cbcp) { new_phase(PHASE_CALLBACK); (*cbcp_protent.open)(unit); return; } #endif /* * Process extra options from the secrets file */ if (extra_options) { options_from_list(extra_options, 1); free_wordlist(extra_options); extra_options = 0; } start_networks(unit); } void start_networks(int unit) { int i; struct protent *protp; int ecp_required, mppe_required; new_phase(PHASE_NETWORK); #ifdef PPP_WITH_MULTILINK if (multilink) { if (mp_join_bundle()) { if (multilink_join_hook) (*multilink_join_hook)(); if (updetach && !nodetach) detach(); return; } } #endif /* PPP_WITH_MULTILINK */ #ifdef PPP_WITH_FILTER if (!demand) set_filters(&pass_filter, &active_filter); #endif /* Start CCP and ECP */ for (i = 0; (protp = protocols[i]) != NULL; ++i) if ((protp->protocol == PPP_ECP || protp->protocol == PPP_CCP) && protp->enabled_flag && protp->open != NULL) (*protp->open)(0); /* * Bring up other network protocols iff encryption is not required. */ ecp_required = ecp_gotoptions[unit].required; mppe_required = ccp_gotoptions[unit].mppe; if (!ecp_required && !mppe_required) continue_networks(unit); } void continue_networks(int unit) { int i; struct protent *protp; /* * Start the "real" network protocols. */ for (i = 0; (protp = protocols[i]) != NULL; ++i) if (protp->protocol < 0xC000 && protp->protocol != PPP_CCP && protp->protocol != PPP_ECP && protp->enabled_flag && protp->open != NULL) { (*protp->open)(0); ++num_np_open; } if (num_np_open == 0) /* nothing to do */ lcp_close(0, "No network protocols running"); } /* * The peer has failed to authenticate himself using `protocol'. */ void auth_peer_fail(int unit, int protocol) { /* * Authentication failure: take the link down */ ppp_set_status(EXIT_PEER_AUTH_FAILED); lcp_close(unit, "Authentication failed"); } /* * The peer has been successfully authenticated using `protocol'. */ void auth_peer_success(int unit, int protocol, int prot_flavor, char *name, int namelen) { int bit; switch (protocol) { case PPP_CHAP: bit = CHAP_PEER; switch (prot_flavor) { case CHAP_MD5: bit |= CHAP_MD5_PEER; break; #ifdef PPP_WITH_CHAPMS case CHAP_MICROSOFT: bit |= CHAP_MS_PEER; break; case CHAP_MICROSOFT_V2: bit |= CHAP_MS2_PEER; break; #endif } break; case PPP_PAP: bit = PAP_PEER; break; case PPP_EAP: bit = EAP_PEER; break; default: warn("auth_peer_success: unknown protocol %x", protocol); return; } /* * Save the authenticated name of the peer for later. */ if (namelen > sizeof(peer_authname) - 1) namelen = sizeof(peer_authname) - 1; BCOPY(name, peer_authname, namelen); peer_authname[namelen] = 0; ppp_script_setenv("PEERNAME", peer_authname, 0); /* Save the authentication method for later. */ auth_done[unit] |= bit; /* * If there is no more authentication still to be done, * proceed to the network (or callback) phase. */ if ((auth_pending[unit] &= ~bit) == 0) network_phase(unit); } /* * We have failed to authenticate ourselves to the peer using `protocol'. */ void auth_withpeer_fail(int unit, int protocol) { if (passwd_from_file) BZERO(passwd, MAXSECRETLEN); /* * We've failed to authenticate ourselves to our peer. * Some servers keep sending CHAP challenges, but there * is no point in persisting without any way to get updated * authentication secrets. */ ppp_set_status(EXIT_AUTH_TOPEER_FAILED); lcp_close(unit, "Failed to authenticate ourselves to peer"); } /* * We have successfully authenticated ourselves with the peer using `protocol'. */ void auth_withpeer_success(int unit, int protocol, int prot_flavor) { int bit; const char *prot = ""; switch (protocol) { case PPP_CHAP: bit = CHAP_WITHPEER; prot = "CHAP"; switch (prot_flavor) { case CHAP_MD5: bit |= CHAP_MD5_WITHPEER; break; #ifdef PPP_WITH_CHAPMS case CHAP_MICROSOFT: bit |= CHAP_MS_WITHPEER; break; case CHAP_MICROSOFT_V2: bit |= CHAP_MS2_WITHPEER; break; #endif } break; case PPP_PAP: if (passwd_from_file) BZERO(passwd, MAXSECRETLEN); bit = PAP_WITHPEER; prot = "PAP"; break; case PPP_EAP: bit = EAP_WITHPEER; prot = "EAP"; break; default: warn("auth_withpeer_success: unknown protocol %x", protocol); bit = 0; } notice("%s authentication succeeded", prot); /* Save the authentication method for later. */ auth_done[unit] |= bit; /* * If there is no more authentication still being done, * proceed to the network (or callback) phase. */ if ((auth_pending[unit] &= ~bit) == 0) network_phase(unit); } /* * np_up - a network protocol has come up. */ void np_up(int unit, int proto) { int tlim; if (num_np_up == 0) { /* * At this point we consider that the link has come up successfully. */ ppp_set_status(EXIT_OK); unsuccess = 0; new_phase(PHASE_RUNNING); if (idle_time_hook != 0) tlim = (*idle_time_hook)(NULL); else tlim = ppp_get_max_idle_time(); if (tlim > 0) TIMEOUT(check_idle, NULL, tlim); /* * Set a timeout to close the connection once the maximum * connect time has expired. */ if (ppp_get_max_connect_time() > 0) TIMEOUT(connect_time_expired, 0, ppp_get_max_connect_time()); /* * Configure a check to see if session has outlived it's limit * in terms of octets */ if (maxoctets > 0) TIMEOUT(check_maxoctets, NULL, maxoctets_timeout); /* * Detach now, if the updetach option was given. */ if (updetach && !nodetach) { dbglog("updetach is set. Now detaching."); detach(); #ifdef SYSTEMD } else if (nodetach && up_sdnotify) { dbglog("up_sdnotify is set. Now notifying systemd: READY=1"); sd_notify(0, "READY=1"); #endif } } ++num_np_up; } /* * np_down - a network protocol has gone down. */ void np_down(int unit, int proto) { if (--num_np_up == 0) { UNTIMEOUT(check_idle, NULL); UNTIMEOUT(connect_time_expired, NULL); UNTIMEOUT(check_maxoctets, NULL); new_phase(PHASE_NETWORK); } } /* * np_finished - a network protocol has finished using the link. */ void np_finished(int unit, int proto) { if (--num_np_open <= 0) { /* no further use for the link: shut up shop. */ lcp_close(0, "No network protocols running"); } } /* * Periodic callback to check if session has reached its limit. The period defaults * to 1 second and is configurable by setting "mo-timeout" in configuration */ static void check_maxoctets(void *arg) { unsigned int used = 0; ppp_link_stats_st stats; if (ppp_get_link_stats(&stats)) { switch(maxoctets_dir) { case PPP_OCTETS_DIRECTION_IN: used = stats.bytes_in; break; case PPP_OCTETS_DIRECTION_OUT: used = stats.bytes_out; break; case PPP_OCTETS_DIRECTION_MAXOVERAL: case PPP_OCTETS_DIRECTION_MAXSESSION: used = (stats.bytes_in > stats.bytes_out) ? stats.bytes_in : stats.bytes_out; break; default: used = stats.bytes_in+stats.bytes_out; break; } } if (used > maxoctets) { notice("Traffic limit reached. Limit: %u Used: %u", maxoctets, used); ppp_set_status(EXIT_TRAFFIC_LIMIT); lcp_close(0, "Traffic limit"); link_stats_print = 0; need_holdoff = 0; } else { TIMEOUT(check_maxoctets, NULL, maxoctets_timeout); } } /* * check_idle - check whether the link has been idle for long * enough that we can shut it down. */ static void check_idle(void *arg) { struct ppp_idle idle; time_t itime; int tlim; if (!get_idle_time(0, &idle)) return; if (idle_time_hook != 0) { tlim = idle_time_hook(&idle); } else { itime = MIN(idle.xmit_idle, idle.recv_idle); tlim = ppp_get_max_idle_time() - itime; } if (tlim <= 0) { /* link is idle: shut it down. */ notice("Terminating connection due to lack of activity."); ppp_set_status(EXIT_IDLE_TIMEOUT); lcp_close(0, "Link inactive"); need_holdoff = 0; } else { TIMEOUT(check_idle, NULL, tlim); } } /* * connect_time_expired - log a message and close the connection. */ static void connect_time_expired(void *arg) { info("Connect time expired"); ppp_set_status(EXIT_CONNECT_TIME); lcp_close(0, "Connect time expired"); /* Close connection */ } /* * auth_check_options - called to check authentication options. */ void auth_check_options(void) { lcp_options *wo = &lcp_wantoptions[0]; int can_auth; int lacks_ip; /* Default our_name to hostname, and user to our_name */ if (our_name[0] == 0 || usehostname) strlcpy(our_name, hostname, sizeof(our_name)); /* If a blank username was explicitly given as an option, trust the user and don't use our_name */ if (user[0] == 0 && !explicit_user) strlcpy(user, our_name, sizeof(user)); #if defined(SYSTEM_CA_PATH) && (defined(PPP_WITH_EAPTLS) || defined(PPP_WITH_PEAP)) /* Use system default for CA Path if not specified */ if (!ca_path) { ca_path = SYSTEM_CA_PATH; } #endif /* * If we have a default route, require the peer to authenticate * unless the noauth option was given or the real user is root. */ if (!auth_required && !allow_any_ip && have_route_to(0) && !privileged) { auth_required = 1; default_auth = 1; } /* If we selected any CHAP flavors, we should probably negotiate it. :-) */ if (wo->chap_mdtype) wo->neg_chap = 1; /* If authentication is required, ask peer for CHAP, PAP, or EAP. */ if (auth_required) { allow_any_ip = 0; if (!wo->neg_chap && !wo->neg_upap && !wo->neg_eap) { wo->neg_chap = chap_mdtype_all != MDTYPE_NONE; wo->chap_mdtype = chap_mdtype_all; wo->neg_upap = 1; wo->neg_eap = 1; } } else { wo->neg_chap = 0; wo->chap_mdtype = MDTYPE_NONE; wo->neg_upap = 0; wo->neg_eap = 0; } /* * Check whether we have appropriate secrets to use * to authenticate the peer. Note that EAP can authenticate by way * of a CHAP-like exchanges as well as SRP. */ lacks_ip = 0; can_auth = wo->neg_upap && (uselogin || have_pap_secret(&lacks_ip)); if (!can_auth && (wo->neg_chap || wo->neg_eap)) { can_auth = have_chap_secret((explicit_remote? remote_name: NULL), our_name, 1, &lacks_ip); } if (!can_auth && wo->neg_eap) { can_auth = have_srp_secret((explicit_remote? remote_name: NULL), our_name, 1, &lacks_ip); } #ifdef PPP_WITH_EAPTLS if (!can_auth && wo->neg_eap) { can_auth = have_eaptls_secret_server((explicit_remote ? remote_name : NULL), our_name, 1, &lacks_ip); } #endif if (auth_required && !can_auth && noauth_addrs == NULL) { if (default_auth) { ppp_option_error( "By default the remote system is required to authenticate itself"); ppp_option_error( "(because this system has a default route to the internet)"); } else if (explicit_remote) ppp_option_error( "The remote system (%s) is required to authenticate itself", remote_name); else ppp_option_error( "The remote system is required to authenticate itself"); ppp_option_error( "but I couldn't find any suitable secret (password) for it to use to do so."); if (lacks_ip) ppp_option_error( "(None of the available passwords would let it use an IP address.)"); exit(1); } /* * Early check for remote number authorization. */ if (!auth_number()) { warn("calling number %q is not authorized", remote_number); exit(EXIT_CNID_AUTH_FAILED); } } /* * auth_reset - called when LCP is starting negotiations to recheck * authentication options, i.e. whether we have appropriate secrets * to use for authenticating ourselves and/or the peer. */ void auth_reset(int unit) { lcp_options *go = &lcp_gotoptions[unit]; lcp_options *ao = &lcp_allowoptions[unit]; int hadchap; hadchap = -1; ao->neg_upap = !refuse_pap && (passwd[0] != 0 || get_pap_passwd(NULL)); ao->neg_chap = (!refuse_chap || !refuse_mschap || !refuse_mschap_v2) && ((passwd[0] != 0 || explicit_passwd) || (hadchap = have_chap_secret(user, (explicit_remote? remote_name: NULL), 0, NULL))); ao->neg_eap = !refuse_eap && ( passwd[0] != 0 || (hadchap == 1 || (hadchap == -1 && have_chap_secret(user, (explicit_remote? remote_name: NULL), 0, NULL))) || have_srp_secret(user, (explicit_remote? remote_name: NULL), 0, NULL) #ifdef PPP_WITH_EAPTLS || have_eaptls_secret_client(user, (explicit_remote? remote_name: NULL)) #endif ); hadchap = -1; if (go->neg_upap && !uselogin && !have_pap_secret(NULL)) go->neg_upap = 0; if (go->neg_chap) { if (!(hadchap = have_chap_secret((explicit_remote? remote_name: NULL), our_name, 1, NULL))) go->neg_chap = 0; } if (go->neg_eap && (hadchap == 0 || (hadchap == -1 && !have_chap_secret((explicit_remote? remote_name: NULL), our_name, 1, NULL))) && !have_srp_secret((explicit_remote? remote_name: NULL), our_name, 1, NULL) #ifdef PPP_WITH_EAPTLS && !have_eaptls_secret_server((explicit_remote? remote_name: NULL), our_name, 1, NULL) #endif ) go->neg_eap = 0; } /* * check_passwd - Check the user name and passwd against the PAP secrets * file. If requested, also check against the system password database, * and login the user if OK. * * returns: * UPAP_AUTHNAK: Authentication failed. * UPAP_AUTHACK: Authentication succeeded. * In either case, msg points to an appropriate message. */ int check_passwd(int unit, char *auser, int userlen, char *apasswd, int passwdlen, char **msg) { int ret; char *filename; FILE *f; struct wordlist *addrs = NULL, *opts = NULL; char passwd[256], user[256]; char secret[MAXWORDLEN]; static int attempts = 0; /* * Make copies of apasswd and auser, then null-terminate them. * If there are unprintable characters in the password, make * them visible. */ slprintf(passwd, sizeof(passwd), "%.*v", passwdlen, apasswd); slprintf(user, sizeof(user), "%.*v", userlen, auser); *msg = ""; /* * Check if a plugin wants to handle this. */ if (pap_auth_hook) { ret = (*pap_auth_hook)(user, passwd, msg, &addrs, &opts); if (ret >= 0) { /* note: set_allowed_addrs() saves opts (but not addrs): don't free it! */ if (ret) set_allowed_addrs(unit, addrs, opts); else if (opts != 0) free_wordlist(opts); if (addrs != 0) free_wordlist(addrs); BZERO(passwd, sizeof(passwd)); return ret? UPAP_AUTHACK: UPAP_AUTHNAK; } } /* * Open the file of pap secrets and scan for a suitable secret * for authenticating this user. */ filename = PPP_PATH_UPAPFILE; addrs = opts = NULL; ret = UPAP_AUTHNAK; f = fopen(filename, "r"); if (f == NULL) { error("Can't open PAP password file %s: %m", filename); } else { check_access(f, filename); if (scan_authfile(f, user, our_name, secret, &addrs, &opts, filename, 0) < 0) { warn("no PAP secret found for %s", user); } else { /* * If the secret is "@login", it means to check * the password against the login database. */ int login_secret = strcmp(secret, "@login") == 0; ret = UPAP_AUTHACK; if (uselogin || login_secret) { /* login option or secret is @login */ if (session_full(user, passwd, devnam, msg) == 0) { ret = UPAP_AUTHNAK; } } else if (session_mgmt) { if (session_check(user, NULL, devnam, NULL) == 0) { warn("Peer %q failed PAP Session verification", user); ret = UPAP_AUTHNAK; } } if (secret[0] != 0 && !login_secret) { /* password given in pap-secrets - must match */ if (cryptpap || strcmp(passwd, secret) != 0) { #ifdef HAVE_CRYPT_H char *cbuf = crypt(passwd, secret); if (!cbuf || strcmp(cbuf, secret) != 0) #endif ret = UPAP_AUTHNAK; } } } fclose(f); } if (ret == UPAP_AUTHNAK) { if (**msg == 0) *msg = "Login incorrect"; /* * XXX can we ever get here more than once?? * Frustrate passwd stealer programs. * Allow 10 tries, but start backing off after 3 (stolen from login). * On 10'th, drop the connection. */ if (attempts++ >= 10) { warn("%d LOGIN FAILURES ON %s, %s", attempts, devnam, user); lcp_close(unit, "login failed"); } if (attempts > 3) sleep((u_int) (attempts - 3) * 5); if (opts != NULL) free_wordlist(opts); } else { attempts = 0; /* Reset count */ if (**msg == 0) *msg = "Login ok"; set_allowed_addrs(unit, addrs, opts); } if (addrs != NULL) free_wordlist(addrs); BZERO(passwd, sizeof(passwd)); BZERO(secret, sizeof(secret)); return ret; } /* * null_login - Check if a username of "" and a password of "" are * acceptable, and iff so, set the list of acceptable IP addresses * and return 1. */ static int null_login(int unit) { char *filename; FILE *f; int i, ret; struct wordlist *addrs, *opts; char secret[MAXWORDLEN]; /* * Check if a plugin wants to handle this. */ ret = -1; if (null_auth_hook) ret = (*null_auth_hook)(&addrs, &opts); /* * Open the file of pap secrets and scan for a suitable secret. */ if (ret <= 0) { filename = PPP_PATH_UPAPFILE; addrs = NULL; f = fopen(filename, "r"); if (f == NULL) return 0; check_access(f, filename); i = scan_authfile(f, "", our_name, secret, &addrs, &opts, filename, 0); ret = i >= 0 && secret[0] == 0; BZERO(secret, sizeof(secret)); fclose(f); } if (ret) set_allowed_addrs(unit, addrs, opts); else if (opts != 0) free_wordlist(opts); if (addrs != 0) free_wordlist(addrs); return ret; } /* * get_pap_passwd - get a password for authenticating ourselves with * our peer using PAP. Returns 1 on success, 0 if no suitable password * could be found. * Assumes passwd points to MAXSECRETLEN bytes of space (if non-null). */ static int get_pap_passwd(char *passwd) { char *filename; FILE *f; int ret; char secret[MAXWORDLEN]; /* * Check whether a plugin wants to supply this. */ if (pap_passwd_hook) { ret = (*pap_passwd_hook)(user, passwd); if (ret >= 0) return ret; } filename = PPP_PATH_UPAPFILE; f = fopen(filename, "r"); if (f == NULL) return 0; check_access(f, filename); ret = scan_authfile(f, user, (remote_name[0]? remote_name: NULL), secret, NULL, NULL, filename, 0); fclose(f); if (ret < 0) return 0; if (passwd != NULL) strlcpy(passwd, secret, MAXSECRETLEN); BZERO(secret, sizeof(secret)); return 1; } /* * have_pap_secret - check whether we have a PAP file with any * secrets that we could possibly use for authenticating the peer. */ static int have_pap_secret(int *lacks_ipp) { FILE *f; int ret; char *filename; struct wordlist *addrs; /* let the plugin decide, if there is one */ if (pap_check_hook) { ret = (*pap_check_hook)(); if (ret >= 0) return ret; } filename = PPP_PATH_UPAPFILE; f = fopen(filename, "r"); if (f == NULL) return 0; ret = scan_authfile(f, (explicit_remote? remote_name: NULL), our_name, NULL, &addrs, NULL, filename, 0); fclose(f); if (ret >= 0 && !some_ip_ok(addrs)) { if (lacks_ipp != 0) *lacks_ipp = 1; ret = -1; } if (addrs != 0) free_wordlist(addrs); return ret >= 0; } /* * have_chap_secret - check whether we have a CHAP file with a * secret that we could possibly use for authenticating `client' * on `server'. Either can be the null string, meaning we don't * know the identity yet. */ static int have_chap_secret(char *client, char *server, int need_ip, int *lacks_ipp) { FILE *f; int ret; char *filename; struct wordlist *addrs; if (chap_check_hook) { ret = (*chap_check_hook)(); if (ret >= 0) { return ret; } } filename = PPP_PATH_CHAPFILE; f = fopen(filename, "r"); if (f == NULL) return 0; if (client != NULL && client[0] == 0) client = NULL; else if (server != NULL && server[0] == 0) server = NULL; ret = scan_authfile(f, client, server, NULL, &addrs, NULL, filename, 0); fclose(f); if (ret >= 0 && need_ip && !some_ip_ok(addrs)) { if (lacks_ipp != 0) *lacks_ipp = 1; ret = -1; } if (addrs != 0) free_wordlist(addrs); return ret >= 0; } /* * have_srp_secret - check whether we have a SRP file with a * secret that we could possibly use for authenticating `client' * on `server'. Either can be the null string, meaning we don't * know the identity yet. */ static int have_srp_secret(char *client, char *server, int need_ip, int *lacks_ipp) { FILE *f; int ret; char *filename; struct wordlist *addrs; filename = PPP_PATH_SRPFILE; f = fopen(filename, "r"); if (f == NULL) return 0; if (client != NULL && client[0] == 0) client = NULL; else if (server != NULL && server[0] == 0) server = NULL; ret = scan_authfile(f, client, server, NULL, &addrs, NULL, filename, 0); fclose(f); if (ret >= 0 && need_ip && !some_ip_ok(addrs)) { if (lacks_ipp != 0) *lacks_ipp = 1; ret = -1; } if (addrs != 0) free_wordlist(addrs); return ret >= 0; } /* * get_secret - open the CHAP secret file and return the secret * for authenticating the given client on the given server. * (We could be either client or server). */ int get_secret(int unit, char *client, char *server, char *secret, int *secret_len, int am_server) { FILE *f; int ret, len; char *filename; struct wordlist *addrs, *opts; char secbuf[MAXWORDLEN]; if (!am_server && passwd[0] != 0) { strlcpy(secbuf, passwd, sizeof(secbuf)); } else if (!am_server && chap_passwd_hook) { if ( (*chap_passwd_hook)(client, secbuf) < 0) { error("Unable to obtain CHAP password for %s on %s from plugin", client, server); return 0; } } else { filename = PPP_PATH_CHAPFILE; addrs = NULL; secbuf[0] = 0; f = fopen(filename, "r"); if (f == NULL) { error("Can't open chap secret file %s: %m", filename); return 0; } check_access(f, filename); ret = scan_authfile(f, client, server, secbuf, &addrs, &opts, filename, 0); fclose(f); if (ret < 0) return 0; if (am_server) set_allowed_addrs(unit, addrs, opts); else if (opts != 0) free_wordlist(opts); if (addrs != 0) free_wordlist(addrs); } len = strlen(secbuf); if (len > MAXSECRETLEN) { error("Secret for %s on %s is too long", client, server); len = MAXSECRETLEN; } BCOPY(secbuf, secret, len); BZERO(secbuf, sizeof(secbuf)); *secret_len = len; return 1; } /* * get_srp_secret - open the SRP secret file and return the secret * for authenticating the given client on the given server. * (We could be either client or server). */ int get_srp_secret(int unit, char *client, char *server, char *secret, int am_server) { FILE *fp; int ret; char *filename; struct wordlist *addrs, *opts; if (!am_server && passwd[0] != '\0') { strlcpy(secret, passwd, MAXWORDLEN); } else { filename = PPP_PATH_SRPFILE; addrs = NULL; fp = fopen(filename, "r"); if (fp == NULL) { error("Can't open srp secret file %s: %m", filename); return 0; } check_access(fp, filename); secret[0] = '\0'; ret = scan_authfile(fp, client, server, secret, &addrs, &opts, filename, am_server); fclose(fp); if (ret < 0) return 0; if (am_server) set_allowed_addrs(unit, addrs, opts); else if (opts != NULL) free_wordlist(opts); if (addrs != NULL) free_wordlist(addrs); } return 1; } /* * set_allowed_addrs() - set the list of allowed addresses. * Also looks for `--' indicating options to apply for this peer * and leaves the following words in extra_options. */ static void set_allowed_addrs(int unit, struct wordlist *addrs, struct wordlist *opts) { int n; struct wordlist *ap, **plink; struct permitted_ip *ip; char *ptr_word, *ptr_mask; struct hostent *hp; struct netent *np; u_int32_t a, mask, ah, offset; struct ipcp_options *wo = &ipcp_wantoptions[unit]; u_int32_t suggested_ip = 0; if (addresses[unit] != NULL) free(addresses[unit]); addresses[unit] = NULL; if (extra_options != NULL) free_wordlist(extra_options); extra_options = opts; /* * Count the number of IP addresses given. */ n = wordlist_count(addrs) + wordlist_count(noauth_addrs); if (n == 0) return; ip = (struct permitted_ip *) malloc((n + 1) * sizeof(struct permitted_ip)); if (ip == 0) return; /* temporarily append the noauth_addrs list to addrs */ for (plink = &addrs; *plink != NULL; plink = &(*plink)->next) ; *plink = noauth_addrs; n = 0; for (ap = addrs; ap != NULL; ap = ap->next) { /* "-" means no addresses authorized, "*" means any address allowed */ ptr_word = ap->word; if (strcmp(ptr_word, "-") == 0) break; if (strcmp(ptr_word, "*") == 0) { ip[n].permit = 1; ip[n].base = ip[n].mask = 0; ++n; break; } ip[n].permit = 1; if (*ptr_word == '!') { ip[n].permit = 0; ++ptr_word; } mask = ~ (u_int32_t) 0; offset = 0; ptr_mask = strchr (ptr_word, '/'); if (ptr_mask != NULL) { int bit_count; char *endp; bit_count = (int) strtol (ptr_mask+1, &endp, 10); if (bit_count <= 0 || bit_count > 32) { warn("invalid address length %v in auth. address list", ptr_mask+1); continue; } bit_count = 32 - bit_count; /* # bits in host part */ if (*endp == '+') { offset = ifunit + 1; ++endp; } if (*endp != 0) { warn("invalid address length syntax: %v", ptr_mask+1); continue; } *ptr_mask = '\0'; mask <<= bit_count; } hp = gethostbyname(ptr_word); if (hp != NULL && hp->h_addrtype == AF_INET) { a = *(u_int32_t *)hp->h_addr; } else { np = getnetbyname (ptr_word); if (np != NULL && np->n_addrtype == AF_INET) { a = htonl ((u_int32_t)np->n_net); if (ptr_mask == NULL) { /* calculate appropriate mask for net */ ah = ntohl(a); if (IN_CLASSA(ah)) mask = IN_CLASSA_NET; else if (IN_CLASSB(ah)) mask = IN_CLASSB_NET; else if (IN_CLASSC(ah)) mask = IN_CLASSC_NET; } } else { a = inet_addr (ptr_word); } } if (ptr_mask != NULL) *ptr_mask = '/'; if (a == (u_int32_t)-1L) { warn("unknown host %s in auth. address list", ap->word); continue; } if (offset != 0) { if (offset >= ~mask) { warn("interface unit %d too large for subnet %v", ifunit, ptr_word); continue; } a = htonl((ntohl(a) & mask) + offset); mask = ~(u_int32_t)0; } ip[n].mask = htonl(mask); ip[n].base = a & ip[n].mask; ++n; if (~mask == 0 && suggested_ip == 0) suggested_ip = a; } *plink = NULL; ip[n].permit = 0; /* make the last entry forbid all addresses */ ip[n].base = 0; /* to terminate the list */ ip[n].mask = 0; addresses[unit] = ip; /* * If the address given for the peer isn't authorized, or if * the user hasn't given one, AND there is an authorized address * which is a single host, then use that if we find one. */ if (suggested_ip != 0 && (wo->hisaddr == 0 || !auth_ip_addr(unit, wo->hisaddr))) { wo->hisaddr = suggested_ip; /* * Do we insist on this address? No, if there are other * addresses authorized than the suggested one. */ if (n > 1) wo->accept_remote = 1; } } /* * auth_ip_addr - check whether the peer is authorized to use * a given IP address. Returns 1 if authorized, 0 otherwise. */ int auth_ip_addr(int unit, u_int32_t addr) { int ok; /* don't allow loopback or multicast address */ if (ppp_bad_ip_addr(addr)) return 0; if (allowed_address_hook) { ok = allowed_address_hook(addr); if (ok >= 0) return ok; } if (addresses[unit] != NULL) { ok = ip_addr_check(addr, addresses[unit]); if (ok >= 0) return ok; } if (auth_required) return 0; /* no addresses authorized */ return allow_any_ip || privileged || !have_route_to(addr); } static int ip_addr_check(u_int32_t addr, struct permitted_ip *addrs) { for (; ; ++addrs) if ((addr & addrs->mask) == addrs->base) return addrs->permit; } /* * Check if given addr in network byte order is in the looback network, or a multicast address. */ bool ppp_bad_ip_addr(u_int32_t addr) { addr = ntohl(addr); return (addr >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET || IN_MULTICAST(addr) || IN_BADCLASS(addr); } /* * some_ip_ok - check a wordlist to see if it authorizes any * IP address(es). */ static int some_ip_ok(struct wordlist *addrs) { for (; addrs != 0; addrs = addrs->next) { if (addrs->word[0] == '-') break; if (addrs->word[0] != '!') return 1; /* some IP address is allowed */ } return 0; } /* * auth_number - check whether the remote number is allowed to connect. * Returns 1 if authorized, 0 otherwise. */ int auth_number(void) { struct wordlist *wp = permitted_numbers; int l; /* Allow all if no authorization list. */ if (!wp) return 1; /* Allow if we have a match in the authorization list. */ while (wp) { /* trailing '*' wildcard */ l = strlen(wp->word); if ((wp->word)[l - 1] == '*') l--; if (!strncasecmp(wp->word, remote_number, l)) return 1; wp = wp->next; } return 0; } /* * check_access - complain if a secret file has too-liberal permissions. */ static void check_access(FILE *f, char *filename) { struct stat sbuf; if (fstat(fileno(f), &sbuf) < 0) { warn("cannot stat secret file %s: %m", filename); } else if ((sbuf.st_mode & (S_IRWXG | S_IRWXO)) != 0) { warn("Warning - secret file %s has world and/or group access", filename); } } /* * scan_authfile - Scan an authorization file for a secret suitable * for authenticating `client' on `server'. The return value is -1 * if no secret is found, otherwise >= 0. The return value has * NONWILD_CLIENT set if the secret didn't have "*" for the client, and * NONWILD_SERVER set if the secret didn't have "*" for the server. * Any following words on the line up to a "--" (i.e. address authorization * info) are placed in a wordlist and returned in *addrs. Any * following words (extra options) are placed in a wordlist and * returned in *opts. * We assume secret is NULL or points to MAXWORDLEN bytes of space. * Flags are non-zero if we need two colons in the secret in order to * match. */ static int scan_authfile(FILE *f, char *client, char *server, char *secret, struct wordlist **addrs, struct wordlist **opts, char *filename, int flags) { int newline, xxx; int got_flag, best_flag; FILE *sf; struct wordlist *ap, *addr_list, *alist, **app; char word[MAXWORDLEN]; char atfile[MAXWORDLEN]; char lsecret[MAXWORDLEN]; char *cp; if (addrs != NULL) *addrs = NULL; if (opts != NULL) *opts = NULL; addr_list = NULL; if (!getword(f, word, &newline, filename)) return -1; /* file is empty??? */ newline = 1; best_flag = -1; for (;;) { /* * Skip until we find a word at the start of a line. */ while (!newline && getword(f, word, &newline, filename)) ; if (!newline) break; /* got to end of file */ /* * Got a client - check if it's a match or a wildcard. */ got_flag = 0; if (client != NULL && strcmp(word, client) != 0 && !ISWILD(word)) { newline = 0; continue; } if (!ISWILD(word)) got_flag = NONWILD_CLIENT; /* * Now get a server and check if it matches. */ if (!getword(f, word, &newline, filename)) break; if (newline) continue; if (!ISWILD(word)) { if (server != NULL && strcmp(word, server) != 0) continue; got_flag |= NONWILD_SERVER; } /* * Got some sort of a match - see if it's better than what * we have already. */ if (got_flag <= best_flag) continue; /* * Get the secret. */ if (!getword(f, word, &newline, filename)) break; if (newline) continue; /* * SRP-SHA1 authenticator should never be reading secrets from * a file. (Authenticatee may, though.) */ if (flags && ((cp = strchr(word, ':')) == NULL || strchr(cp + 1, ':') == NULL)) continue; if (secret != NULL) { /* * Special syntax: @/pathname means read secret from file. */ if (word[0] == '@' && word[1] == '/') { strlcpy(atfile, word+1, sizeof(atfile)); if ((sf = fopen(atfile, "r")) == NULL) { warn("can't open indirect secret file %s", atfile); continue; } check_access(sf, atfile); if (!getword(sf, word, &xxx, atfile)) { warn("no secret in indirect secret file %s", atfile); fclose(sf); continue; } fclose(sf); } strlcpy(lsecret, word, sizeof(lsecret)); } /* * Now read address authorization info and make a wordlist. */ app = &alist; for (;;) { if (!getword(f, word, &newline, filename) || newline) break; ap = (struct wordlist *) malloc(sizeof(struct wordlist) + strlen(word) + 1); if (ap == NULL) novm("authorized addresses"); ap->word = (char *) (ap + 1); strcpy(ap->word, word); *app = ap; app = &ap->next; } *app = NULL; /* * This is the best so far; remember it. */ best_flag = got_flag; if (addr_list) free_wordlist(addr_list); addr_list = alist; if (secret != NULL) strlcpy(secret, lsecret, MAXWORDLEN); if (!newline) break; } /* scan for a -- word indicating the start of options */ for (app = &addr_list; (ap = *app) != NULL; app = &ap->next) if (strcmp(ap->word, "--") == 0) break; /* ap = start of options */ if (ap != NULL) { ap = ap->next; /* first option */ free(*app); /* free the "--" word */ *app = NULL; /* terminate addr list */ } if (opts != NULL) *opts = ap; else if (ap != NULL) free_wordlist(ap); if (addrs != NULL) *addrs = addr_list; else if (addr_list != NULL) free_wordlist(addr_list); return best_flag; } /* * wordlist_count - return the number of items in a wordlist */ static int wordlist_count(struct wordlist *wp) { int n; for (n = 0; wp != NULL; wp = wp->next) ++n; return n; } /* * free_wordlist - release memory allocated for a wordlist. */ static void free_wordlist(struct wordlist *wp) { struct wordlist *next; while (wp != NULL) { next = wp->next; free(wp); wp = next; } } /* * auth_script_done - called when the auth-up or auth-down script * has finished. */ static void auth_script_done(void *arg) { auth_script_pid = 0; switch (auth_script_state) { case s_up: if (auth_state == s_down) { auth_script_state = s_down; auth_script(PPP_PATH_AUTHDOWN); } break; case s_down: if (auth_state == s_up) { auth_script_state = s_up; auth_script(PPP_PATH_AUTHUP); } break; } } /* * auth_script - execute a script with arguments * interface-name peer-name real-user tty speed */ static void auth_script(char *script) { char strspeed[32]; struct passwd *pw; char struid[32]; char *user_name; char *argv[8]; if ((pw = getpwuid(getuid())) != NULL && pw->pw_name != NULL) user_name = pw->pw_name; else { slprintf(struid, sizeof(struid), "%d", getuid()); user_name = struid; } slprintf(strspeed, sizeof(strspeed), "%d", baud_rate); argv[0] = script; argv[1] = ifname; argv[2] = peer_authname; argv[3] = user_name; argv[4] = devnam; argv[5] = strspeed; argv[6] = ipparam; argv[7] = NULL; auth_script_pid = run_program(script, argv, 0, auth_script_done, NULL, 0); } #ifdef PPP_WITH_EAPTLS static int have_eaptls_secret_server(char *client, char *server, int need_ip, int *lacks_ipp) { FILE *f; int ret; char *filename; struct wordlist *addrs; char servcertfile[MAXWORDLEN]; char clicertfile[MAXWORDLEN]; char cacertfile[MAXWORDLEN]; char pkfile[MAXWORDLEN]; filename = PPP_PATH_EAPTLSSERVFILE; f = fopen(filename, "r"); if (f == NULL) return 0; if (client != NULL && client[0] == 0) client = NULL; else if (server != NULL && server[0] == 0) server = NULL; ret = scan_authfile_eaptls(f, client, server, clicertfile, servcertfile, cacertfile, pkfile, &addrs, NULL, filename, 0); fclose(f); /* if (ret >= 0 && !eaptls_init_ssl(1, cacertfile, servcertfile, clicertfile, pkfile)) ret = -1; */ if (ret >= 0 && need_ip && !some_ip_ok(addrs)) { if (lacks_ipp != 0) *lacks_ipp = 1; ret = -1; } if (addrs != 0) free_wordlist(addrs); return ret >= 0; } static int have_eaptls_secret_client(char *client, char *server) { FILE *f; int ret; char *filename; struct wordlist *addrs = NULL; char servcertfile[MAXWORDLEN]; char clicertfile[MAXWORDLEN]; char cacertfile[MAXWORDLEN]; char pkfile[MAXWORDLEN]; if (client != NULL && client[0] == 0) client = NULL; else if (server != NULL && server[0] == 0) server = NULL; if ((cacert_file || ca_path) && cert_file && privkey_file) return 1; if (pkcs12_file) return 1; filename = PPP_PATH_EAPTLSCLIFILE; f = fopen(filename, "r"); if (f == NULL) return 0; ret = scan_authfile_eaptls(f, client, server, clicertfile, servcertfile, cacertfile, pkfile, &addrs, NULL, filename, 0); fclose(f); /* if (ret >= 0 && !eaptls_init_ssl(0, cacertfile, clicertfile, servcertfile, pkfile)) ret = -1; */ if (addrs != 0) free_wordlist(addrs); return ret >= 0; } static int scan_authfile_eaptls(FILE *f, char *client, char *server, char *cli_cert, char *serv_cert, char *ca_cert, char *pk, struct wordlist **addrs, struct wordlist **opts, char *filename, int flags) { int newline; int got_flag, best_flag; struct wordlist *ap, *addr_list, *alist, **app; char word[MAXWORDLEN]; if (addrs != NULL) *addrs = NULL; if (opts != NULL) *opts = NULL; addr_list = NULL; if (!getword(f, word, &newline, filename)) return -1; /* file is empty??? */ newline = 1; best_flag = -1; for (;;) { /* * Skip until we find a word at the start of a line. */ while (!newline && getword(f, word, &newline, filename)); if (!newline) break; /* got to end of file */ /* * Got a client - check if it's a match or a wildcard. */ got_flag = 0; if (client != NULL && strcmp(word, client) != 0 && !ISWILD(word)) { newline = 0; continue; } if (!ISWILD(word)) got_flag = NONWILD_CLIENT; /* * Now get a server and check if it matches. */ if (!getword(f, word, &newline, filename)) break; if (newline) continue; if (!ISWILD(word)) { if (server != NULL && strcmp(word, server) != 0) continue; got_flag |= NONWILD_SERVER; } /* * Got some sort of a match - see if it's better than what * we have already. */ if (got_flag <= best_flag) continue; /* * Get the cli_cert */ if (!getword(f, word, &newline, filename)) break; if (newline) continue; if (strcmp(word, "-") != 0) { strlcpy(cli_cert, word, MAXWORDLEN); } else cli_cert[0] = 0; /* * Get serv_cert */ if (!getword(f, word, &newline, filename)) break; if (newline) continue; if (strcmp(word, "-") != 0) { strlcpy(serv_cert, word, MAXWORDLEN); } else serv_cert[0] = 0; /* * Get ca_cert */ if (!getword(f, word, &newline, filename)) break; if (newline) continue; strlcpy(ca_cert, word, MAXWORDLEN); /* * Get pk */ if (!getword(f, word, &newline, filename)) break; if (newline) continue; strlcpy(pk, word, MAXWORDLEN); /* * Now read address authorization info and make a wordlist. */ app = &alist; for (;;) { if (!getword(f, word, &newline, filename) || newline) break; ap = (struct wordlist *) malloc(sizeof(struct wordlist) + strlen(word) + 1); if (ap == NULL) novm("authorized addresses"); ap->word = (char *) (ap + 1); strcpy(ap->word, word); *app = ap; app = &ap->next; } *app = NULL; /* * This is the best so far; remember it. */ best_flag = got_flag; if (addr_list) free_wordlist(addr_list); addr_list = alist; if (!newline) break; } /* scan for a -- word indicating the start of options */ for (app = &addr_list; (ap = *app) != NULL; app = &ap->next) if (strcmp(ap->word, "--") == 0) break; /* ap = start of options */ if (ap != NULL) { ap = ap->next; /* first option */ free(*app); /* free the "--" word */ *app = NULL; /* terminate addr list */ } if (opts != NULL) *opts = ap; else if (ap != NULL) free_wordlist(ap); if (addrs != NULL) *addrs = addr_list; else if (addr_list != NULL) free_wordlist(addr_list); return best_flag; } int get_eaptls_secret(int unit, char *client, char *server, char *clicertfile, char *servcertfile, char *cacertfile, char *capath, char *pkfile, char *pkcs12, int am_server) { FILE *fp; int ret; char *filename = NULL; struct wordlist *addrs = NULL; struct wordlist *opts = NULL; /* maybe overkill, but it eases debugging */ bzero(clicertfile, MAXWORDLEN); bzero(servcertfile, MAXWORDLEN); bzero(cacertfile, MAXWORDLEN); bzero(capath, MAXWORDLEN); bzero(pkfile, MAXWORDLEN); bzero(pkcs12, MAXWORDLEN); /* the ca+cert+privkey can also be specified as options */ if (!am_server && (cacert_file || ca_path) && cert_file && privkey_file ) { strlcpy( clicertfile, cert_file, MAXWORDLEN ); if (cacert_file) strlcpy( cacertfile, cacert_file, MAXWORDLEN ); if (ca_path) strlcpy( capath, ca_path, MAXWORDLEN ); strlcpy( pkfile, privkey_file, MAXWORDLEN ); } else if (!am_server && pkcs12_file) { strlcpy( pkcs12, pkcs12_file, MAXWORDLEN ); if (cacert_file) strlcpy( cacertfile, cacert_file, MAXWORDLEN ); if (ca_path) strlcpy( capath, ca_path, MAXWORDLEN ); } else { filename = (am_server ? PPP_PATH_EAPTLSSERVFILE : PPP_PATH_EAPTLSCLIFILE); addrs = NULL; fp = fopen(filename, "r"); if (fp == NULL) { error("Can't open eap-tls secret file %s: %m", filename); return 0; } check_access(fp, filename); ret = scan_authfile_eaptls(fp, client, server, clicertfile, servcertfile, cacertfile, pkfile, &addrs, &opts, filename, 0); fclose(fp); if (ret < 0) return 0; } if (eaptls_passwd_hook) { dbglog( "Calling eaptls password hook" ); if ( (*eaptls_passwd_hook)(pkfile, passwd) < 0) { error("Unable to obtain EAP-TLS password for %s (%s) from plugin", client, pkfile); return 0; } } if (am_server) set_allowed_addrs(unit, addrs, opts); else if (opts != NULL) free_wordlist(opts); if (addrs != NULL) free_wordlist(addrs); return 1; } #endif ppp-2.5.0/pppd/ccp.c0000644000175000017500000013034114353435407011124 00000000000000/* * ccp.c - PPP Compression Control Protocol. * * Copyright (c) 1994-2002 Paul Mackerras. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. The name(s) of the authors of this software must not be used to * endorse or promote products derived from this software without * prior written permission. * * 3. Redistributions of any form whatsoever must retain the following * acknowledgment: * "This product includes software developed by Paul Mackerras * ". * * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #define RCSID "$Id: ccp.c,v 1.50 2005/06/26 19:34:41 carlsonj Exp $" #include #include #if defined(SOL2) #include #else #include #endif #include "pppd-private.h" #include "options.h" #include "fsm.h" #include "ccp.h" #include "chap_ms.h" #include "mppe.h" #include "lcp.h" /* lcp_close(), lcp_fsm */ /* * Unfortunately there is a bug in zlib which means that using a * size of 8 (window size = 256) for Deflate compression will cause * buffer overruns and kernel crashes in the deflate module. * Until this is fixed we only accept sizes in the range 9 .. 15. * Thanks to James Carlson for pointing this out. */ #define DEFLATE_MIN_WORKS 9 /* * Command-line options. */ static int setbsdcomp (char **); static int setdeflate (char **); static char bsd_value[8]; static char deflate_value[8]; /* * Option variables. */ #ifdef PPP_WITH_MPPE bool refuse_mppe_stateful = 1; /* Allow stateful mode? */ #endif static struct option ccp_option_list[] = { { "noccp", o_bool, &ccp_protent.enabled_flag, "Disable CCP negotiation" }, { "-ccp", o_bool, &ccp_protent.enabled_flag, "Disable CCP negotiation", OPT_ALIAS }, { "bsdcomp", o_special, (void *)setbsdcomp, "Request BSD-Compress packet compression", OPT_PRIO | OPT_A2STRVAL | OPT_STATIC, bsd_value }, { "nobsdcomp", o_bool, &ccp_wantoptions[0].bsd_compress, "don't allow BSD-Compress", OPT_PRIOSUB | OPT_A2CLR, &ccp_allowoptions[0].bsd_compress }, { "-bsdcomp", o_bool, &ccp_wantoptions[0].bsd_compress, "don't allow BSD-Compress", OPT_ALIAS | OPT_PRIOSUB | OPT_A2CLR, &ccp_allowoptions[0].bsd_compress }, { "deflate", o_special, (void *)setdeflate, "request Deflate compression", OPT_PRIO | OPT_A2STRVAL | OPT_STATIC, deflate_value }, { "nodeflate", o_bool, &ccp_wantoptions[0].deflate, "don't allow Deflate compression", OPT_PRIOSUB | OPT_A2CLR, &ccp_allowoptions[0].deflate }, { "-deflate", o_bool, &ccp_wantoptions[0].deflate, "don't allow Deflate compression", OPT_ALIAS | OPT_PRIOSUB | OPT_A2CLR, &ccp_allowoptions[0].deflate }, { "nodeflatedraft", o_bool, &ccp_wantoptions[0].deflate_draft, "don't use draft deflate #", OPT_A2COPY, &ccp_allowoptions[0].deflate_draft }, { "predictor1", o_bool, &ccp_wantoptions[0].predictor_1, "request Predictor-1", OPT_PRIO | 1 }, { "nopredictor1", o_bool, &ccp_wantoptions[0].predictor_1, "don't allow Predictor-1", OPT_PRIOSUB | OPT_A2CLR, &ccp_allowoptions[0].predictor_1 }, { "-predictor1", o_bool, &ccp_wantoptions[0].predictor_1, "don't allow Predictor-1", OPT_ALIAS | OPT_PRIOSUB | OPT_A2CLR, &ccp_allowoptions[0].predictor_1 }, #ifdef PPP_WITH_MPPE /* MPPE options are symmetrical ... we only set wantoptions here */ { "require-mppe", o_bool, &ccp_wantoptions[0].mppe, "require MPPE encryption", OPT_PRIO | MPPE_OPT_40 | MPPE_OPT_128 }, { "+mppe", o_bool, &ccp_wantoptions[0].mppe, "require MPPE encryption", OPT_ALIAS | OPT_PRIO | MPPE_OPT_40 | MPPE_OPT_128 }, { "nomppe", o_bool, &ccp_wantoptions[0].mppe, "don't allow MPPE encryption", OPT_PRIO }, { "-mppe", o_bool, &ccp_wantoptions[0].mppe, "don't allow MPPE encryption", OPT_ALIAS | OPT_PRIO }, /* We use ccp_allowoptions[0].mppe as a junk var ... it is reset later */ { "require-mppe-40", o_bool, &ccp_allowoptions[0].mppe, "require MPPE 40-bit encryption", OPT_PRIO | OPT_A2OR | MPPE_OPT_40, &ccp_wantoptions[0].mppe }, { "+mppe-40", o_bool, &ccp_allowoptions[0].mppe, "require MPPE 40-bit encryption", OPT_PRIO | OPT_A2OR | MPPE_OPT_40, &ccp_wantoptions[0].mppe }, { "nomppe-40", o_bool, &ccp_allowoptions[0].mppe, "don't allow MPPE 40-bit encryption", OPT_PRIOSUB | OPT_A2CLRB | MPPE_OPT_40, &ccp_wantoptions[0].mppe }, { "-mppe-40", o_bool, &ccp_allowoptions[0].mppe, "don't allow MPPE 40-bit encryption", OPT_ALIAS | OPT_PRIOSUB | OPT_A2CLRB | MPPE_OPT_40, &ccp_wantoptions[0].mppe }, { "require-mppe-128", o_bool, &ccp_allowoptions[0].mppe, "require MPPE 128-bit encryption", OPT_PRIO | OPT_A2OR | MPPE_OPT_128, &ccp_wantoptions[0].mppe }, { "+mppe-128", o_bool, &ccp_allowoptions[0].mppe, "require MPPE 128-bit encryption", OPT_ALIAS | OPT_PRIO | OPT_A2OR | MPPE_OPT_128, &ccp_wantoptions[0].mppe }, { "nomppe-128", o_bool, &ccp_allowoptions[0].mppe, "don't allow MPPE 128-bit encryption", OPT_PRIOSUB | OPT_A2CLRB | MPPE_OPT_128, &ccp_wantoptions[0].mppe }, { "-mppe-128", o_bool, &ccp_allowoptions[0].mppe, "don't allow MPPE 128-bit encryption", OPT_ALIAS | OPT_PRIOSUB | OPT_A2CLRB | MPPE_OPT_128, &ccp_wantoptions[0].mppe }, /* strange one; we always request stateless, but will we allow stateful? */ { "mppe-stateful", o_bool, &refuse_mppe_stateful, "allow MPPE stateful mode", OPT_PRIO }, { "nomppe-stateful", o_bool, &refuse_mppe_stateful, "disallow MPPE stateful mode", OPT_PRIO | 1 }, #endif /* MPPE */ { NULL } }; /* * Protocol entry points from main code. */ static void ccp_init (int unit); static void ccp_open (int unit); static void ccp_close (int unit, char *); static void ccp_lowerup (int unit); static void ccp_lowerdown (int); static void ccp_input (int unit, u_char *pkt, int len); static void ccp_protrej (int unit); static int ccp_printpkt (u_char *pkt, int len, void (*printer)(void *, char *, ...), void *arg); static void ccp_datainput (int unit, u_char *pkt, int len); struct protent ccp_protent = { PPP_CCP, ccp_init, ccp_input, ccp_protrej, ccp_lowerup, ccp_lowerdown, ccp_open, ccp_close, ccp_printpkt, ccp_datainput, 1, "CCP", "Compressed", ccp_option_list, NULL, NULL, NULL }; fsm ccp_fsm[NUM_PPP]; ccp_options ccp_wantoptions[NUM_PPP]; /* what to request the peer to use */ ccp_options ccp_gotoptions[NUM_PPP]; /* what the peer agreed to do */ ccp_options ccp_allowoptions[NUM_PPP]; /* what we'll agree to do */ ccp_options ccp_hisoptions[NUM_PPP]; /* what we agreed to do */ /* * Callbacks for fsm code. */ static void ccp_resetci (fsm *); static int ccp_cilen (fsm *); static void ccp_addci (fsm *, u_char *, int *); static int ccp_ackci (fsm *, u_char *, int); static int ccp_nakci (fsm *, u_char *, int, int); static int ccp_rejci (fsm *, u_char *, int); static int ccp_reqci (fsm *, u_char *, int *, int); static void ccp_up (fsm *); static void ccp_down (fsm *); static int ccp_extcode (fsm *, int, int, u_char *, int); static void ccp_rack_timeout (void *); static char *method_name (ccp_options *, ccp_options *); static fsm_callbacks ccp_callbacks = { ccp_resetci, ccp_cilen, ccp_addci, ccp_ackci, ccp_nakci, ccp_rejci, ccp_reqci, ccp_up, ccp_down, NULL, NULL, NULL, NULL, ccp_extcode, "CCP" }; /* * Do we want / did we get any compression? */ #define ANY_COMPRESS(opt) ((opt).deflate || (opt).bsd_compress \ || (opt).predictor_1 || (opt).predictor_2 \ || (opt).mppe) /* * Local state (mainly for handling reset-reqs and reset-acks). */ static int ccp_localstate[NUM_PPP]; #define RACK_PENDING 1 /* waiting for reset-ack */ #define RREQ_REPEAT 2 /* send another reset-req if no reset-ack */ #define RACKTIMEOUT 1 /* second */ static int all_rejected[NUM_PPP]; /* we rejected all peer's options */ /* * Option parsing. */ static int setbsdcomp(char **argv) { int rbits, abits; char *str, *endp; str = *argv; abits = rbits = strtol(str, &endp, 0); if (endp != str && *endp == ',') { str = endp + 1; abits = strtol(str, &endp, 0); } if (*endp != 0 || endp == str) { ppp_option_error("invalid parameter '%s' for bsdcomp option", *argv); return 0; } if ((rbits != 0 && (rbits < BSD_MIN_BITS || rbits > BSD_MAX_BITS)) || (abits != 0 && (abits < BSD_MIN_BITS || abits > BSD_MAX_BITS))) { ppp_option_error("bsdcomp option values must be 0 or %d .. %d", BSD_MIN_BITS, BSD_MAX_BITS); return 0; } if (rbits > 0) { ccp_wantoptions[0].bsd_compress = 1; ccp_wantoptions[0].bsd_bits = rbits; } else ccp_wantoptions[0].bsd_compress = 0; if (abits > 0) { ccp_allowoptions[0].bsd_compress = 1; ccp_allowoptions[0].bsd_bits = abits; } else ccp_allowoptions[0].bsd_compress = 0; slprintf(bsd_value, sizeof(bsd_value), rbits == abits? "%d": "%d,%d", rbits, abits); return 1; } static int setdeflate(char **argv) { int rbits, abits; char *str, *endp; str = *argv; abits = rbits = strtol(str, &endp, 0); if (endp != str && *endp == ',') { str = endp + 1; abits = strtol(str, &endp, 0); } if (*endp != 0 || endp == str) { ppp_option_error("invalid parameter '%s' for deflate option", *argv); return 0; } if ((rbits != 0 && (rbits < DEFLATE_MIN_SIZE || rbits > DEFLATE_MAX_SIZE)) || (abits != 0 && (abits < DEFLATE_MIN_SIZE || abits > DEFLATE_MAX_SIZE))) { ppp_option_error("deflate option values must be 0 or %d .. %d", DEFLATE_MIN_SIZE, DEFLATE_MAX_SIZE); return 0; } if (rbits == DEFLATE_MIN_SIZE || abits == DEFLATE_MIN_SIZE) { if (rbits == DEFLATE_MIN_SIZE) rbits = DEFLATE_MIN_WORKS; if (abits == DEFLATE_MIN_SIZE) abits = DEFLATE_MIN_WORKS; warn("deflate option value of %d changed to %d to avoid zlib bug", DEFLATE_MIN_SIZE, DEFLATE_MIN_WORKS); } if (rbits > 0) { ccp_wantoptions[0].deflate = 1; ccp_wantoptions[0].deflate_size = rbits; } else ccp_wantoptions[0].deflate = 0; if (abits > 0) { ccp_allowoptions[0].deflate = 1; ccp_allowoptions[0].deflate_size = abits; } else ccp_allowoptions[0].deflate = 0; slprintf(deflate_value, sizeof(deflate_value), rbits == abits? "%d": "%d,%d", rbits, abits); return 1; } /* * ccp_init - initialize CCP. */ static void ccp_init(int unit) { fsm *f = &ccp_fsm[unit]; f->unit = unit; f->protocol = PPP_CCP; f->callbacks = &ccp_callbacks; fsm_init(f); memset(&ccp_wantoptions[unit], 0, sizeof(ccp_options)); memset(&ccp_gotoptions[unit], 0, sizeof(ccp_options)); memset(&ccp_allowoptions[unit], 0, sizeof(ccp_options)); memset(&ccp_hisoptions[unit], 0, sizeof(ccp_options)); ccp_wantoptions[0].deflate = 1; ccp_wantoptions[0].deflate_size = DEFLATE_MAX_SIZE; ccp_wantoptions[0].deflate_correct = 1; ccp_wantoptions[0].deflate_draft = 1; ccp_allowoptions[0].deflate = 1; ccp_allowoptions[0].deflate_size = DEFLATE_MAX_SIZE; ccp_allowoptions[0].deflate_correct = 1; ccp_allowoptions[0].deflate_draft = 1; ccp_wantoptions[0].bsd_compress = 1; ccp_wantoptions[0].bsd_bits = BSD_MAX_BITS; ccp_allowoptions[0].bsd_compress = 1; ccp_allowoptions[0].bsd_bits = BSD_MAX_BITS; ccp_allowoptions[0].predictor_1 = 1; } /* * ccp_open - CCP is allowed to come up. */ static void ccp_open(int unit) { fsm *f = &ccp_fsm[unit]; if (f->state != OPENED) ccp_flags_set(unit, 1, 0); /* * Find out which compressors the kernel supports before * deciding whether to open in silent mode. */ ccp_resetci(f); if (!ANY_COMPRESS(ccp_gotoptions[unit])) f->flags |= OPT_SILENT; fsm_open(f); } /* * ccp_close - Terminate CCP. */ static void ccp_close(int unit, char *reason) { ccp_flags_set(unit, 0, 0); fsm_close(&ccp_fsm[unit], reason); } /* * ccp_lowerup - we may now transmit CCP packets. */ static void ccp_lowerup(int unit) { fsm_lowerup(&ccp_fsm[unit]); } /* * ccp_lowerdown - we may not transmit CCP packets. */ static void ccp_lowerdown(int unit) { fsm_lowerdown(&ccp_fsm[unit]); } /* * ccp_input - process a received CCP packet. */ static void ccp_input(int unit, u_char *p, int len) { fsm *f = &ccp_fsm[unit]; int oldstate; /* * Check for a terminate-request so we can print a message. */ oldstate = f->state; fsm_input(f, p, len); if (oldstate == OPENED && p[0] == TERMREQ && f->state != OPENED) { notice("Compression disabled by peer."); #ifdef PPP_WITH_MPPE if (ccp_gotoptions[unit].mppe) { error("MPPE disabled, closing LCP"); lcp_close(unit, "MPPE disabled by peer"); } #endif } /* * If we get a terminate-ack and we're not asking for compression, * close CCP. */ if (oldstate == REQSENT && p[0] == TERMACK && !ANY_COMPRESS(ccp_gotoptions[unit])) ccp_close(unit, "No compression negotiated"); } /* * Handle a CCP-specific code. */ static int ccp_extcode(fsm *f, int code, int id, u_char *p, int len) { switch (code) { case CCP_RESETREQ: if (f->state != OPENED) break; /* send a reset-ack, which the transmitter will see and reset its compression state. */ fsm_sdata(f, CCP_RESETACK, id, NULL, 0); break; case CCP_RESETACK: if (ccp_localstate[f->unit] & RACK_PENDING && id == f->reqid) { ccp_localstate[f->unit] &= ~(RACK_PENDING | RREQ_REPEAT); UNTIMEOUT(ccp_rack_timeout, f); } break; default: return 0; } return 1; } /* * ccp_protrej - peer doesn't talk CCP. */ static void ccp_protrej(int unit) { ccp_flags_set(unit, 0, 0); fsm_lowerdown(&ccp_fsm[unit]); #ifdef PPP_WITH_MPPE if (ccp_gotoptions[unit].mppe) { error("MPPE required but peer negotiation failed"); lcp_close(unit, "MPPE required but peer negotiation failed"); } #endif } /* * ccp_resetci - initialize at start of negotiation. */ static void ccp_resetci(fsm *f) { ccp_options *go = &ccp_gotoptions[f->unit]; u_char opt_buf[CCP_MAX_OPTION_LENGTH]; *go = ccp_wantoptions[f->unit]; all_rejected[f->unit] = 0; #ifdef PPP_WITH_MPPE if (go->mppe) { ccp_options *ao = &ccp_allowoptions[f->unit]; int auth_mschap_bits = auth_done[f->unit]; #ifdef PPP_WITH_EAPTLS int auth_eap_bits = auth_done[f->unit]; #endif int numbits; /* * Start with a basic sanity check: mschap[v2] auth must be in * exactly one direction. RFC 3079 says that the keys are * 'derived from the credentials of the peer that initiated the call', * however the PPP protocol doesn't have such a concept, and pppd * cannot get this info externally. Instead we do the best we can. * NB: If MPPE is required, all other compression opts are invalid. * So, we return right away if we can't do it. */ /* Leave only the mschap auth bits set */ auth_mschap_bits &= (CHAP_MS_WITHPEER | CHAP_MS_PEER | CHAP_MS2_WITHPEER | CHAP_MS2_PEER); /* Count the mschap auths */ auth_mschap_bits >>= CHAP_MS_SHIFT; numbits = 0; do { numbits += auth_mschap_bits & 1; auth_mschap_bits >>= 1; } while (auth_mschap_bits); if (numbits > 1) { error("MPPE required, but auth done in both directions."); lcp_close(f->unit, "MPPE required but not available"); return; } #ifdef PPP_WITH_EAPTLS /* * MPPE is also possible in combination with EAP-TLS. * It is not possible to detect if we're doing EAP or EAP-TLS * at this stage, hence we accept all forms of EAP. If TLS is * not used then the MPPE keys will not be derived anyway. */ /* Leave only the eap auth bits set */ auth_eap_bits &= (EAP_WITHPEER | EAP_PEER ); if ((numbits == 0) && (auth_eap_bits == 0)) { error("MPPE required, but MS-CHAP[v2] nor EAP-TLS auth are performed."); #else if (!numbits) { error("MPPE required, but MS-CHAP[v2] auth not performed."); #endif lcp_close(f->unit, "MPPE required but not available"); return; } /* A plugin (eg radius) may not have obtained key material. */ if (!mppe_keys_isset()) { error("MPPE required, but keys are not available. " "Possible plugin problem?"); lcp_close(f->unit, "MPPE required but not available"); return; } /* LM auth not supported for MPPE */ if (auth_done[f->unit] & (CHAP_MS_WITHPEER | CHAP_MS_PEER)) { /* This might be noise */ if (go->mppe & MPPE_OPT_40) { notice("Disabling 40-bit MPPE; MS-CHAP LM not supported"); go->mppe &= ~MPPE_OPT_40; ccp_wantoptions[f->unit].mppe &= ~MPPE_OPT_40; } } /* Last check: can we actually negotiate something? */ if (!(go->mppe & (MPPE_OPT_40 | MPPE_OPT_128))) { /* Could be misconfig, could be 40-bit disabled above. */ error("MPPE required, but both 40-bit and 128-bit disabled."); lcp_close(f->unit, "MPPE required but not available"); return; } /* sync options */ ao->mppe = go->mppe; /* MPPE is not compatible with other compression types */ ao->bsd_compress = go->bsd_compress = 0; ao->predictor_1 = go->predictor_1 = 0; ao->predictor_2 = go->predictor_2 = 0; ao->deflate = go->deflate = 0; } /* * Check whether the kernel knows about the various * compression methods we might request. */ if (go->mppe) { opt_buf[0] = CI_MPPE; opt_buf[1] = CILEN_MPPE; MPPE_OPTS_TO_CI(go->mppe, &opt_buf[2]); /* Key material unimportant here. */ if (ccp_test(f->unit, opt_buf, CILEN_MPPE + MPPE_MAX_KEY_LEN, 0) <= 0) { error("MPPE required, but kernel has no support."); lcp_close(f->unit, "MPPE required but not available"); } } #endif /* PPP_WITH_MPPE */ if (go->bsd_compress) { opt_buf[0] = CI_BSD_COMPRESS; opt_buf[1] = CILEN_BSD_COMPRESS; opt_buf[2] = BSD_MAKE_OPT(BSD_CURRENT_VERSION, BSD_MIN_BITS); if (ccp_test(f->unit, opt_buf, CILEN_BSD_COMPRESS, 0) <= 0) go->bsd_compress = 0; } if (go->deflate) { if (go->deflate_correct) { opt_buf[0] = CI_DEFLATE; opt_buf[1] = CILEN_DEFLATE; opt_buf[2] = DEFLATE_MAKE_OPT(DEFLATE_MIN_WORKS); opt_buf[3] = DEFLATE_CHK_SEQUENCE; if (ccp_test(f->unit, opt_buf, CILEN_DEFLATE, 0) <= 0) go->deflate_correct = 0; } if (go->deflate_draft) { opt_buf[0] = CI_DEFLATE_DRAFT; opt_buf[1] = CILEN_DEFLATE; opt_buf[2] = DEFLATE_MAKE_OPT(DEFLATE_MIN_WORKS); opt_buf[3] = DEFLATE_CHK_SEQUENCE; if (ccp_test(f->unit, opt_buf, CILEN_DEFLATE, 0) <= 0) go->deflate_draft = 0; } if (!go->deflate_correct && !go->deflate_draft) go->deflate = 0; } if (go->predictor_1) { opt_buf[0] = CI_PREDICTOR_1; opt_buf[1] = CILEN_PREDICTOR_1; if (ccp_test(f->unit, opt_buf, CILEN_PREDICTOR_1, 0) <= 0) go->predictor_1 = 0; } if (go->predictor_2) { opt_buf[0] = CI_PREDICTOR_2; opt_buf[1] = CILEN_PREDICTOR_2; if (ccp_test(f->unit, opt_buf, CILEN_PREDICTOR_2, 0) <= 0) go->predictor_2 = 0; } } /* * ccp_cilen - Return total length of our configuration info. */ static int ccp_cilen(fsm *f) { ccp_options *go = &ccp_gotoptions[f->unit]; return (go->bsd_compress? CILEN_BSD_COMPRESS: 0) + (go->deflate && go->deflate_correct? CILEN_DEFLATE: 0) + (go->deflate && go->deflate_draft? CILEN_DEFLATE: 0) + (go->predictor_1? CILEN_PREDICTOR_1: 0) + (go->predictor_2? CILEN_PREDICTOR_2: 0) + (go->mppe? CILEN_MPPE: 0); } /* * ccp_addci - put our requests in a packet. */ static void ccp_addci(fsm *f, u_char *p, int *lenp) { int res; ccp_options *go = &ccp_gotoptions[f->unit]; u_char *p0 = p; /* * Add the compression types that we can receive, in decreasing * preference order. Get the kernel to allocate the first one * in case it gets Acked. */ #ifdef PPP_WITH_MPPE if (go->mppe) { u_char opt_buf[CILEN_MPPE + MPPE_MAX_KEY_LEN]; p[0] = opt_buf[0] = CI_MPPE; p[1] = opt_buf[1] = CILEN_MPPE; MPPE_OPTS_TO_CI(go->mppe, &p[2]); MPPE_OPTS_TO_CI(go->mppe, &opt_buf[2]); mppe_get_recv_key(&opt_buf[CILEN_MPPE], MPPE_MAX_KEY_LEN); res = ccp_test(f->unit, opt_buf, CILEN_MPPE + MPPE_MAX_KEY_LEN, 0); if (res > 0) p += CILEN_MPPE; else /* This shouldn't happen, we've already tested it! */ lcp_close(f->unit, "MPPE required but not available in kernel"); } #endif if (go->deflate) { p[0] = go->deflate_correct? CI_DEFLATE: CI_DEFLATE_DRAFT; p[1] = CILEN_DEFLATE; p[2] = DEFLATE_MAKE_OPT(go->deflate_size); p[3] = DEFLATE_CHK_SEQUENCE; if (p != p0) { p += CILEN_DEFLATE; } else { for (;;) { if (go->deflate_size < DEFLATE_MIN_WORKS) { go->deflate = 0; break; } res = ccp_test(f->unit, p, CILEN_DEFLATE, 0); if (res > 0) { p += CILEN_DEFLATE; break; } else if (res < 0) { go->deflate = 0; break; } --go->deflate_size; p[2] = DEFLATE_MAKE_OPT(go->deflate_size); } } if (p != p0 && go->deflate_correct && go->deflate_draft) { p[0] = CI_DEFLATE_DRAFT; p[1] = CILEN_DEFLATE; p[2] = p[2 - CILEN_DEFLATE]; p[3] = DEFLATE_CHK_SEQUENCE; p += CILEN_DEFLATE; } } if (go->bsd_compress) { p[0] = CI_BSD_COMPRESS; p[1] = CILEN_BSD_COMPRESS; p[2] = BSD_MAKE_OPT(BSD_CURRENT_VERSION, go->bsd_bits); if (p != p0) { p += CILEN_BSD_COMPRESS; /* not the first option */ } else { for (;;) { if (go->bsd_bits < BSD_MIN_BITS) { go->bsd_compress = 0; break; } res = ccp_test(f->unit, p, CILEN_BSD_COMPRESS, 0); if (res > 0) { p += CILEN_BSD_COMPRESS; break; } else if (res < 0) { go->bsd_compress = 0; break; } --go->bsd_bits; p[2] = BSD_MAKE_OPT(BSD_CURRENT_VERSION, go->bsd_bits); } } } /* XXX Should Predictor 2 be preferable to Predictor 1? */ if (go->predictor_1) { p[0] = CI_PREDICTOR_1; p[1] = CILEN_PREDICTOR_1; if (p == p0 && ccp_test(f->unit, p, CILEN_PREDICTOR_1, 0) <= 0) { go->predictor_1 = 0; } else { p += CILEN_PREDICTOR_1; } } if (go->predictor_2) { p[0] = CI_PREDICTOR_2; p[1] = CILEN_PREDICTOR_2; if (p == p0 && ccp_test(f->unit, p, CILEN_PREDICTOR_2, 0) <= 0) { go->predictor_2 = 0; } else { p += CILEN_PREDICTOR_2; } } go->method = (p > p0)? p0[0]: -1; *lenp = p - p0; } /* * ccp_ackci - process a received configure-ack, and return * 1 iff the packet was OK. */ static int ccp_ackci(fsm *f, u_char *p, int len) { ccp_options *go = &ccp_gotoptions[f->unit]; u_char *p0 = p; #ifdef PPP_WITH_MPPE if (go->mppe) { u_char opt_buf[CILEN_MPPE]; opt_buf[0] = CI_MPPE; opt_buf[1] = CILEN_MPPE; MPPE_OPTS_TO_CI(go->mppe, &opt_buf[2]); if (len < CILEN_MPPE || memcmp(opt_buf, p, CILEN_MPPE)) return 0; p += CILEN_MPPE; len -= CILEN_MPPE; /* XXX Cope with first/fast ack */ if (len == 0) return 1; } #endif if (go->deflate) { if (len < CILEN_DEFLATE || p[0] != (go->deflate_correct? CI_DEFLATE: CI_DEFLATE_DRAFT) || p[1] != CILEN_DEFLATE || p[2] != DEFLATE_MAKE_OPT(go->deflate_size) || p[3] != DEFLATE_CHK_SEQUENCE) return 0; p += CILEN_DEFLATE; len -= CILEN_DEFLATE; /* XXX Cope with first/fast ack */ if (len == 0) return 1; if (go->deflate_correct && go->deflate_draft) { if (len < CILEN_DEFLATE || p[0] != CI_DEFLATE_DRAFT || p[1] != CILEN_DEFLATE || p[2] != DEFLATE_MAKE_OPT(go->deflate_size) || p[3] != DEFLATE_CHK_SEQUENCE) return 0; p += CILEN_DEFLATE; len -= CILEN_DEFLATE; } } if (go->bsd_compress) { if (len < CILEN_BSD_COMPRESS || p[0] != CI_BSD_COMPRESS || p[1] != CILEN_BSD_COMPRESS || p[2] != BSD_MAKE_OPT(BSD_CURRENT_VERSION, go->bsd_bits)) return 0; p += CILEN_BSD_COMPRESS; len -= CILEN_BSD_COMPRESS; /* XXX Cope with first/fast ack */ if (p == p0 && len == 0) return 1; } if (go->predictor_1) { if (len < CILEN_PREDICTOR_1 || p[0] != CI_PREDICTOR_1 || p[1] != CILEN_PREDICTOR_1) return 0; p += CILEN_PREDICTOR_1; len -= CILEN_PREDICTOR_1; /* XXX Cope with first/fast ack */ if (p == p0 && len == 0) return 1; } if (go->predictor_2) { if (len < CILEN_PREDICTOR_2 || p[0] != CI_PREDICTOR_2 || p[1] != CILEN_PREDICTOR_2) return 0; p += CILEN_PREDICTOR_2; len -= CILEN_PREDICTOR_2; /* XXX Cope with first/fast ack */ if (p == p0 && len == 0) return 1; } if (len != 0) return 0; return 1; } /* * ccp_nakci - process received configure-nak. * Returns 1 iff the nak was OK. */ static int ccp_nakci(fsm *f, u_char *p, int len, int treat_as_reject) { ccp_options *go = &ccp_gotoptions[f->unit]; ccp_options no; /* options we've seen already */ ccp_options try; /* options to ask for next time */ memset(&no, 0, sizeof(no)); try = *go; #ifdef PPP_WITH_MPPE if (go->mppe && len >= CILEN_MPPE && p[0] == CI_MPPE && p[1] == CILEN_MPPE) { no.mppe = 1; /* * Peer wants us to use a different strength or other setting. * Fail if we aren't willing to use his suggestion. */ MPPE_CI_TO_OPTS(&p[2], try.mppe); if ((try.mppe & MPPE_OPT_STATEFUL) && refuse_mppe_stateful) { error("Refusing MPPE stateful mode offered by peer"); try.mppe = 0; } else if (((go->mppe | MPPE_OPT_STATEFUL) & try.mppe) != try.mppe) { /* Peer must have set options we didn't request (suggest) */ try.mppe = 0; } if (!try.mppe) { error("MPPE required but peer negotiation failed"); lcp_close(f->unit, "MPPE required but peer negotiation failed"); } } #endif /* PPP_WITH_MPPE */ if (go->deflate && len >= CILEN_DEFLATE && p[0] == (go->deflate_correct? CI_DEFLATE: CI_DEFLATE_DRAFT) && p[1] == CILEN_DEFLATE) { no.deflate = 1; /* * Peer wants us to use a different code size or something. * Stop asking for Deflate if we don't understand his suggestion. */ if (DEFLATE_METHOD(p[2]) != DEFLATE_METHOD_VAL || DEFLATE_SIZE(p[2]) < DEFLATE_MIN_WORKS || p[3] != DEFLATE_CHK_SEQUENCE) try.deflate = 0; else if (DEFLATE_SIZE(p[2]) < go->deflate_size) try.deflate_size = DEFLATE_SIZE(p[2]); p += CILEN_DEFLATE; len -= CILEN_DEFLATE; if (go->deflate_correct && go->deflate_draft && len >= CILEN_DEFLATE && p[0] == CI_DEFLATE_DRAFT && p[1] == CILEN_DEFLATE) { p += CILEN_DEFLATE; len -= CILEN_DEFLATE; } } if (go->bsd_compress && len >= CILEN_BSD_COMPRESS && p[0] == CI_BSD_COMPRESS && p[1] == CILEN_BSD_COMPRESS) { no.bsd_compress = 1; /* * Peer wants us to use a different number of bits * or a different version. */ if (BSD_VERSION(p[2]) != BSD_CURRENT_VERSION) try.bsd_compress = 0; else if (BSD_NBITS(p[2]) < go->bsd_bits) try.bsd_bits = BSD_NBITS(p[2]); p += CILEN_BSD_COMPRESS; len -= CILEN_BSD_COMPRESS; } /* * Predictor-1 and 2 have no options, so they can't be Naked. * * There may be remaining options but we ignore them. */ if (f->state != OPENED) *go = try; return 1; } /* * ccp_rejci - reject some of our suggested compression methods. */ static int ccp_rejci(fsm *f, u_char *p, int len) { ccp_options *go = &ccp_gotoptions[f->unit]; ccp_options try; /* options to request next time */ try = *go; /* * Cope with empty configure-rejects by ceasing to send * configure-requests. */ if (len == 0 && all_rejected[f->unit]) return -1; #ifdef PPP_WITH_MPPE if (go->mppe && len >= CILEN_MPPE && p[0] == CI_MPPE && p[1] == CILEN_MPPE) { error("MPPE required but peer refused"); lcp_close(f->unit, "MPPE required but peer refused"); p += CILEN_MPPE; len -= CILEN_MPPE; } #endif if (go->deflate_correct && len >= CILEN_DEFLATE && p[0] == CI_DEFLATE && p[1] == CILEN_DEFLATE) { if (p[2] != DEFLATE_MAKE_OPT(go->deflate_size) || p[3] != DEFLATE_CHK_SEQUENCE) return 0; /* Rej is bad */ try.deflate_correct = 0; p += CILEN_DEFLATE; len -= CILEN_DEFLATE; } if (go->deflate_draft && len >= CILEN_DEFLATE && p[0] == CI_DEFLATE_DRAFT && p[1] == CILEN_DEFLATE) { if (p[2] != DEFLATE_MAKE_OPT(go->deflate_size) || p[3] != DEFLATE_CHK_SEQUENCE) return 0; /* Rej is bad */ try.deflate_draft = 0; p += CILEN_DEFLATE; len -= CILEN_DEFLATE; } if (!try.deflate_correct && !try.deflate_draft) try.deflate = 0; if (go->bsd_compress && len >= CILEN_BSD_COMPRESS && p[0] == CI_BSD_COMPRESS && p[1] == CILEN_BSD_COMPRESS) { if (p[2] != BSD_MAKE_OPT(BSD_CURRENT_VERSION, go->bsd_bits)) return 0; try.bsd_compress = 0; p += CILEN_BSD_COMPRESS; len -= CILEN_BSD_COMPRESS; } if (go->predictor_1 && len >= CILEN_PREDICTOR_1 && p[0] == CI_PREDICTOR_1 && p[1] == CILEN_PREDICTOR_1) { try.predictor_1 = 0; p += CILEN_PREDICTOR_1; len -= CILEN_PREDICTOR_1; } if (go->predictor_2 && len >= CILEN_PREDICTOR_2 && p[0] == CI_PREDICTOR_2 && p[1] == CILEN_PREDICTOR_2) { try.predictor_2 = 0; p += CILEN_PREDICTOR_2; len -= CILEN_PREDICTOR_2; } if (len != 0) return 0; if (f->state != OPENED) *go = try; return 1; } /* * ccp_reqci - processed a received configure-request. * Returns CONFACK, CONFNAK or CONFREJ and the packet modified * appropriately. */ static int ccp_reqci(fsm *f, u_char *p, int *lenp, int dont_nak) { int ret, newret, res; u_char *p0, *retp; int len, clen, type, nb; ccp_options *ho = &ccp_hisoptions[f->unit]; ccp_options *ao = &ccp_allowoptions[f->unit]; #ifdef PPP_WITH_MPPE bool rej_for_ci_mppe = 1; /* Are we rejecting based on a bad/missing */ /* CI_MPPE, or due to other options? */ #endif ret = CONFACK; retp = p0 = p; len = *lenp; memset(ho, 0, sizeof(ccp_options)); ho->method = (len > 0)? p[0]: -1; while (len > 0) { newret = CONFACK; if (len < 2 || p[1] < 2 || p[1] > len) { /* length is bad */ clen = len; newret = CONFREJ; } else { type = p[0]; clen = p[1]; switch (type) { #ifdef PPP_WITH_MPPE case CI_MPPE: if (!ao->mppe || clen != CILEN_MPPE) { newret = CONFREJ; break; } MPPE_CI_TO_OPTS(&p[2], ho->mppe); /* Nak if anything unsupported or unknown are set. */ if (ho->mppe & MPPE_OPT_UNSUPPORTED) { newret = CONFNAK; ho->mppe &= ~MPPE_OPT_UNSUPPORTED; } if (ho->mppe & MPPE_OPT_UNKNOWN) { newret = CONFNAK; ho->mppe &= ~MPPE_OPT_UNKNOWN; } /* Check state opt */ if (ho->mppe & MPPE_OPT_STATEFUL) { /* * We can Nak and request stateless, but it's a * lot easier to just assume the peer will request * it if he can do it; stateful mode is bad over * the Internet -- which is where we expect MPPE. */ if (refuse_mppe_stateful) { error("Refusing MPPE stateful mode offered by peer"); newret = CONFREJ; break; } } /* Find out which of {S,L} are set. */ if ((ho->mppe & MPPE_OPT_128) && (ho->mppe & MPPE_OPT_40)) { /* Both are set, negotiate the strongest. */ newret = CONFNAK; if (ao->mppe & MPPE_OPT_128) ho->mppe &= ~MPPE_OPT_40; else if (ao->mppe & MPPE_OPT_40) ho->mppe &= ~MPPE_OPT_128; else { newret = CONFREJ; break; } } else if (ho->mppe & MPPE_OPT_128) { if (!(ao->mppe & MPPE_OPT_128)) { newret = CONFREJ; break; } } else if (ho->mppe & MPPE_OPT_40) { if (!(ao->mppe & MPPE_OPT_40)) { newret = CONFREJ; break; } } else { /* Neither are set. */ /* We cannot accept this. */ newret = CONFNAK; /* Give the peer our idea of what can be used, so it can choose and confirm */ ho->mppe = ao->mppe; } /* rebuild the opts */ MPPE_OPTS_TO_CI(ho->mppe, &p[2]); if (newret == CONFACK) { u_char opt_buf[CILEN_MPPE + MPPE_MAX_KEY_LEN]; int mtu; BCOPY(p, opt_buf, CILEN_MPPE); mppe_get_send_key(&opt_buf[CILEN_MPPE], MPPE_MAX_KEY_LEN); if (ccp_test(f->unit, opt_buf, CILEN_MPPE + MPPE_MAX_KEY_LEN, 1) <= 0) { /* This shouldn't happen, we've already tested it! */ error("MPPE required, but kernel has no support."); lcp_close(f->unit, "MPPE required but not available"); newret = CONFREJ; break; } /* * We need to decrease the interface MTU by MPPE_PAD * because MPPE frames **grow**. The kernel [must] * allocate MPPE_PAD extra bytes in xmit buffers. */ mtu = ppp_get_mtu(f->unit); if (mtu) ppp_set_mtu(f->unit, mtu - MPPE_PAD); else newret = CONFREJ; } /* * We have accepted MPPE or are willing to negotiate * MPPE parameters. A CONFREJ is due to subsequent * (non-MPPE) processing. */ rej_for_ci_mppe = 0; break; #endif /* PPP_WITH_MPPE */ case CI_DEFLATE: case CI_DEFLATE_DRAFT: if (!ao->deflate || clen != CILEN_DEFLATE || (!ao->deflate_correct && type == CI_DEFLATE) || (!ao->deflate_draft && type == CI_DEFLATE_DRAFT)) { newret = CONFREJ; break; } ho->deflate = 1; ho->deflate_size = nb = DEFLATE_SIZE(p[2]); if (DEFLATE_METHOD(p[2]) != DEFLATE_METHOD_VAL || p[3] != DEFLATE_CHK_SEQUENCE || nb > ao->deflate_size || nb < DEFLATE_MIN_WORKS) { newret = CONFNAK; if (!dont_nak) { p[2] = DEFLATE_MAKE_OPT(ao->deflate_size); p[3] = DEFLATE_CHK_SEQUENCE; /* fall through to test this #bits below */ } else break; } /* * Check whether we can do Deflate with the window * size they want. If the window is too big, reduce * it until the kernel can cope and nak with that. * We only check this for the first option. */ if (p == p0) { for (;;) { res = ccp_test(f->unit, p, CILEN_DEFLATE, 1); if (res > 0) break; /* it's OK now */ if (res < 0 || nb == DEFLATE_MIN_WORKS || dont_nak) { newret = CONFREJ; p[2] = DEFLATE_MAKE_OPT(ho->deflate_size); break; } newret = CONFNAK; --nb; p[2] = DEFLATE_MAKE_OPT(nb); } } break; case CI_BSD_COMPRESS: if (!ao->bsd_compress || clen != CILEN_BSD_COMPRESS) { newret = CONFREJ; break; } ho->bsd_compress = 1; ho->bsd_bits = nb = BSD_NBITS(p[2]); if (BSD_VERSION(p[2]) != BSD_CURRENT_VERSION || nb > ao->bsd_bits || nb < BSD_MIN_BITS) { newret = CONFNAK; if (!dont_nak) { p[2] = BSD_MAKE_OPT(BSD_CURRENT_VERSION, ao->bsd_bits); /* fall through to test this #bits below */ } else break; } /* * Check whether we can do BSD-Compress with the code * size they want. If the code size is too big, reduce * it until the kernel can cope and nak with that. * We only check this for the first option. */ if (p == p0) { for (;;) { res = ccp_test(f->unit, p, CILEN_BSD_COMPRESS, 1); if (res > 0) break; if (res < 0 || nb == BSD_MIN_BITS || dont_nak) { newret = CONFREJ; p[2] = BSD_MAKE_OPT(BSD_CURRENT_VERSION, ho->bsd_bits); break; } newret = CONFNAK; --nb; p[2] = BSD_MAKE_OPT(BSD_CURRENT_VERSION, nb); } } break; case CI_PREDICTOR_1: if (!ao->predictor_1 || clen != CILEN_PREDICTOR_1) { newret = CONFREJ; break; } ho->predictor_1 = 1; if (p == p0 && ccp_test(f->unit, p, CILEN_PREDICTOR_1, 1) <= 0) { newret = CONFREJ; } break; case CI_PREDICTOR_2: if (!ao->predictor_2 || clen != CILEN_PREDICTOR_2) { newret = CONFREJ; break; } ho->predictor_2 = 1; if (p == p0 && ccp_test(f->unit, p, CILEN_PREDICTOR_2, 1) <= 0) { newret = CONFREJ; } break; default: newret = CONFREJ; } } if (newret == CONFNAK && dont_nak) newret = CONFREJ; if (!(newret == CONFACK || (newret == CONFNAK && ret == CONFREJ))) { /* we're returning this option */ if (newret == CONFREJ && ret == CONFNAK) retp = p0; ret = newret; if (p != retp) BCOPY(p, retp, clen); retp += clen; } p += clen; len -= clen; } if (ret != CONFACK) { if (ret == CONFREJ && *lenp == retp - p0) all_rejected[f->unit] = 1; else *lenp = retp - p0; } #ifdef PPP_WITH_MPPE if (ret == CONFREJ && ao->mppe && rej_for_ci_mppe) { error("MPPE required but peer negotiation failed"); lcp_close(f->unit, "MPPE required but peer negotiation failed"); } #endif return ret; } /* * Make a string name for a compression method (or 2). */ static char * method_name(ccp_options *opt, ccp_options *opt2) { static char result[64]; if (!ANY_COMPRESS(*opt)) return "(none)"; switch (opt->method) { #ifdef PPP_WITH_MPPE case CI_MPPE: { char *p = result; char *q = result + sizeof(result); /* 1 past result */ slprintf(p, q - p, "MPPE "); p += 5; if (opt->mppe & MPPE_OPT_128) { slprintf(p, q - p, "128-bit "); p += 8; } if (opt->mppe & MPPE_OPT_40) { slprintf(p, q - p, "40-bit "); p += 7; } if (opt->mppe & MPPE_OPT_STATEFUL) slprintf(p, q - p, "stateful"); else slprintf(p, q - p, "stateless"); break; } #endif case CI_DEFLATE: case CI_DEFLATE_DRAFT: if (opt2 != NULL && opt2->deflate_size != opt->deflate_size) slprintf(result, sizeof(result), "Deflate%s (%d/%d)", (opt->method == CI_DEFLATE_DRAFT? "(old#)": ""), opt->deflate_size, opt2->deflate_size); else slprintf(result, sizeof(result), "Deflate%s (%d)", (opt->method == CI_DEFLATE_DRAFT? "(old#)": ""), opt->deflate_size); break; case CI_BSD_COMPRESS: if (opt2 != NULL && opt2->bsd_bits != opt->bsd_bits) slprintf(result, sizeof(result), "BSD-Compress (%d/%d)", opt->bsd_bits, opt2->bsd_bits); else slprintf(result, sizeof(result), "BSD-Compress (%d)", opt->bsd_bits); break; case CI_PREDICTOR_1: return "Predictor 1"; case CI_PREDICTOR_2: return "Predictor 2"; default: slprintf(result, sizeof(result), "Method %d", opt->method); } return result; } /* * CCP has come up - inform the kernel driver and log a message. */ static void ccp_up(fsm *f) { ccp_options *go = &ccp_gotoptions[f->unit]; ccp_options *ho = &ccp_hisoptions[f->unit]; char method1[64]; ccp_flags_set(f->unit, 1, 1); if (ANY_COMPRESS(*go)) { if (ANY_COMPRESS(*ho)) { if (go->method == ho->method) { notice("%s compression enabled", method_name(go, ho)); } else { strlcpy(method1, method_name(go, NULL), sizeof(method1)); notice("%s / %s compression enabled", method1, method_name(ho, NULL)); } } else notice("%s receive compression enabled", method_name(go, NULL)); } else if (ANY_COMPRESS(*ho)) notice("%s transmit compression enabled", method_name(ho, NULL)); #ifdef PPP_WITH_MPPE if (go->mppe) { mppe_clear_keys(); continue_networks(f->unit); /* Bring up IP et al */ } #endif } /* * CCP has gone down - inform the kernel driver. */ static void ccp_down(fsm *f) { if (ccp_localstate[f->unit] & RACK_PENDING) UNTIMEOUT(ccp_rack_timeout, f); ccp_localstate[f->unit] = 0; ccp_flags_set(f->unit, 1, 0); #ifdef PPP_WITH_MPPE if (ccp_gotoptions[f->unit].mppe) { ccp_gotoptions[f->unit].mppe = 0; if (lcp_fsm[f->unit].state == OPENED) { /* If LCP is not already going down, make sure it does. */ error("MPPE disabled"); lcp_close(f->unit, "MPPE disabled"); } } #endif } /* * Print the contents of a CCP packet. */ static char *ccp_codenames[] = { "ConfReq", "ConfAck", "ConfNak", "ConfRej", "TermReq", "TermAck", "CodeRej", NULL, NULL, NULL, NULL, NULL, NULL, "ResetReq", "ResetAck", }; static int ccp_printpkt(u_char *p, int plen, void (*printer) (void *, char *, ...), void *arg) { u_char *p0, *optend; int code, id, len; int optlen; p0 = p; if (plen < HEADERLEN) return 0; code = p[0]; id = p[1]; len = (p[2] << 8) + p[3]; if (len < HEADERLEN || len > plen) return 0; if (code >= 1 && code <= sizeof(ccp_codenames) / sizeof(char *) && ccp_codenames[code-1] != NULL) printer(arg, " %s", ccp_codenames[code-1]); else printer(arg, " code=0x%x", code); printer(arg, " id=0x%x", id); len -= HEADERLEN; p += HEADERLEN; switch (code) { case CONFREQ: case CONFACK: case CONFNAK: case CONFREJ: /* print list of possible compression methods */ while (len >= 2) { code = p[0]; optlen = p[1]; if (optlen < 2 || optlen > len) break; printer(arg, " <"); len -= optlen; optend = p + optlen; switch (code) { #ifdef PPP_WITH_MPPE case CI_MPPE: if (optlen >= CILEN_MPPE) { u_char mppe_opts; MPPE_CI_TO_OPTS(&p[2], mppe_opts); printer(arg, "mppe %s %s %s %s %s %s%s", (p[2] & MPPE_H_BIT)? "+H": "-H", (p[5] & MPPE_M_BIT)? "+M": "-M", (p[5] & MPPE_S_BIT)? "+S": "-S", (p[5] & MPPE_L_BIT)? "+L": "-L", (p[5] & MPPE_D_BIT)? "+D": "-D", (p[5] & MPPE_C_BIT)? "+C": "-C", (mppe_opts & MPPE_OPT_UNKNOWN)? " +U": ""); if (mppe_opts & MPPE_OPT_UNKNOWN) printer(arg, " (%.2x %.2x %.2x %.2x)", p[2], p[3], p[4], p[5]); p += CILEN_MPPE; } break; #endif case CI_DEFLATE: case CI_DEFLATE_DRAFT: if (optlen >= CILEN_DEFLATE) { printer(arg, "deflate%s %d", (code == CI_DEFLATE_DRAFT? "(old#)": ""), DEFLATE_SIZE(p[2])); if (DEFLATE_METHOD(p[2]) != DEFLATE_METHOD_VAL) printer(arg, " method %d", DEFLATE_METHOD(p[2])); if (p[3] != DEFLATE_CHK_SEQUENCE) printer(arg, " check %d", p[3]); p += CILEN_DEFLATE; } break; case CI_BSD_COMPRESS: if (optlen >= CILEN_BSD_COMPRESS) { printer(arg, "bsd v%d %d", BSD_VERSION(p[2]), BSD_NBITS(p[2])); p += CILEN_BSD_COMPRESS; } break; case CI_PREDICTOR_1: if (optlen >= CILEN_PREDICTOR_1) { printer(arg, "predictor 1"); p += CILEN_PREDICTOR_1; } break; case CI_PREDICTOR_2: if (optlen >= CILEN_PREDICTOR_2) { printer(arg, "predictor 2"); p += CILEN_PREDICTOR_2; } break; } while (p < optend) printer(arg, " %.2x", *p++); printer(arg, ">"); } break; case TERMACK: case TERMREQ: if (len > 0 && *p >= ' ' && *p < 0x7f) { print_string((char *)p, len, printer, arg); p += len; len = 0; } break; } /* dump out the rest of the packet in hex */ while (--len >= 0) printer(arg, " %.2x", *p++); return p - p0; } /* * We have received a packet that the decompressor failed to * decompress. Here we would expect to issue a reset-request, but * Motorola has a patent on resetting the compressor as a result of * detecting an error in the decompressed data after decompression. * (See US patent 5,130,993; international patent publication number * WO 91/10289; Australian patent 73296/91.) * * So we ask the kernel whether the error was detected after * decompression; if it was, we take CCP down, thus disabling * compression :-(, otherwise we issue the reset-request. */ static void ccp_datainput(int unit, u_char *pkt, int len) { fsm *f; f = &ccp_fsm[unit]; if (f->state == OPENED) { if (ccp_fatal_error(unit)) { /* * Disable compression by taking CCP down. */ error("Lost compression sync: disabling compression"); ccp_close(unit, "Lost compression sync"); #ifdef PPP_WITH_MPPE /* * If we were doing MPPE, we must also take the link down. */ if (ccp_gotoptions[unit].mppe) { error("Too many MPPE errors, closing LCP"); lcp_close(unit, "Too many MPPE errors"); } #endif } else { /* * Send a reset-request to reset the peer's compressor. * We don't do that if we are still waiting for an * acknowledgement to a previous reset-request. */ if (!(ccp_localstate[f->unit] & RACK_PENDING)) { fsm_sdata(f, CCP_RESETREQ, f->reqid = ++f->id, NULL, 0); TIMEOUT(ccp_rack_timeout, f, RACKTIMEOUT); ccp_localstate[f->unit] |= RACK_PENDING; } else ccp_localstate[f->unit] |= RREQ_REPEAT; } } } /* * Timeout waiting for reset-ack. */ static void ccp_rack_timeout(void *arg) { fsm *f = arg; if (f->state == OPENED && ccp_localstate[f->unit] & RREQ_REPEAT) { fsm_sdata(f, CCP_RESETREQ, f->reqid, NULL, 0); TIMEOUT(ccp_rack_timeout, f, RACKTIMEOUT); ccp_localstate[f->unit] &= ~RREQ_REPEAT; } else ccp_localstate[f->unit] &= ~RACK_PENDING; } ppp-2.5.0/pppd/chap-md5.c0000644000175000017500000000741614353435407011763 00000000000000/* * chap-md5.c - New CHAP/MD5 implementation. * * Copyright (c) 2003 Paul Mackerras. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. The name(s) of the authors of this software must not be used to * endorse or promote products derived from this software without * prior written permission. * * 3. Redistributions of any form whatsoever must retain the following * acknowledgment: * "This product includes software developed by Paul Mackerras * ". * * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #define RCSID "$Id: chap-md5.c,v 1.4 2004/11/09 22:39:25 paulus Exp $" #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include "pppd-private.h" #include "chap.h" #include "chap-md5.h" #include "magic.h" #include "crypto.h" #define MD5_MIN_CHALLENGE 16 #define MD5_MAX_CHALLENGE 24 static void chap_md5_generate_challenge(unsigned char *cp) { int clen; clen = (int)(drand48() * (MD5_MAX_CHALLENGE - MD5_MIN_CHALLENGE)) + MD5_MIN_CHALLENGE; *cp++ = clen; random_bytes(cp, clen); } static int chap_md5_verify_response(int id, char *name, unsigned char *secret, int secret_len, unsigned char *challenge, unsigned char *response, char *message, int message_space) { unsigned char idbyte = id; unsigned char hash[MD5_DIGEST_LENGTH]; unsigned int hash_len = MD5_DIGEST_LENGTH; int challenge_len, response_len; bool success = 0; challenge_len = *challenge++; response_len = *response++; if (response_len == MD5_DIGEST_LENGTH) { /* Generate hash of ID, secret, challenge */ PPP_MD_CTX* ctx = PPP_MD_CTX_new(); if (ctx) { if (PPP_DigestInit(ctx, PPP_md5())) { if (PPP_DigestUpdate(ctx, &idbyte, 1)) { if (PPP_DigestUpdate(ctx, secret, secret_len)) { if (PPP_DigestUpdate(ctx, challenge, challenge_len)) { if (PPP_DigestFinal(ctx, hash, &hash_len)) { success = 1; } } } } } PPP_MD_CTX_free(ctx); } } if (success && memcmp(hash, response, hash_len) == 0) { slprintf(message, message_space, "Access granted"); return 1; } slprintf(message, message_space, "Access denied"); return 0; } static void chap_md5_make_response(unsigned char *response, int id, char *our_name, unsigned char *challenge, char *secret, int secret_len, unsigned char *private) { unsigned char idbyte = id; int challenge_len = *challenge++; int hash_len = MD5_DIGEST_LENGTH; PPP_MD_CTX* ctx = PPP_MD_CTX_new(); if (ctx) { if (PPP_DigestInit(ctx, PPP_md5())) { if (PPP_DigestUpdate(ctx, &idbyte, 1)) { if (PPP_DigestUpdate(ctx, secret, secret_len)) { if (PPP_DigestUpdate(ctx, challenge, challenge_len)) { if (PPP_DigestFinal(ctx, &response[1], &hash_len)) { response[0] = hash_len; } } } } } PPP_MD_CTX_free(ctx); } } static struct chap_digest_type md5_digest = { CHAP_MD5, /* code */ chap_md5_generate_challenge, chap_md5_verify_response, chap_md5_make_response, NULL, /* check_success */ NULL, /* handle_failure */ }; void chap_md5_init(void) { chap_register_digest(&md5_digest); } ppp-2.5.0/pppd/chap.c0000644000175000017500000004270514353435407011300 00000000000000/* * chap-new.c - New CHAP implementation. * * Copyright (c) 2003 Paul Mackerras. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. The name(s) of the authors of this software must not be used to * endorse or promote products derived from this software without * prior written permission. * * 3. Redistributions of any form whatsoever must retain the following * acknowledgment: * "This product includes software developed by Paul Mackerras * ". * * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #define RCSID "$Id: chap-new.c,v 1.9 2007/06/19 02:08:35 carlsonj Exp $" #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include "pppd-private.h" #include "options.h" #include "session.h" #include "chap.h" #include "chap-md5.h" #ifdef PPP_WITH_CHAPMS #include "chap_ms.h" #define MDTYPE_ALL (MDTYPE_MICROSOFT_V2 | MDTYPE_MICROSOFT | MDTYPE_MD5) #else #define MDTYPE_ALL (MDTYPE_MD5) #endif int chap_mdtype_all = MDTYPE_ALL; /* Hook for a plugin to validate CHAP challenge */ chap_verify_hook_fn *chap_verify_hook = NULL; /* * Option variables. */ int chap_server_timeout_time = 3; int chap_max_transmits = 10; int chap_rechallenge_time = 0; int chap_client_timeout_time = 60; int chapms_strip_domain = 0; /* * Command-line options. */ static struct option chap_option_list[] = { { "chap-restart", o_int, &chap_server_timeout_time, "Set timeout for CHAP (as server)", OPT_PRIO }, { "chap-max-challenge", o_int, &chap_max_transmits, "Set max #xmits for challenge", OPT_PRIO }, { "chap-interval", o_int, &chap_rechallenge_time, "Set interval for rechallenge", OPT_PRIO }, { "chap-timeout", o_int, &chap_client_timeout_time, "Set timeout for CHAP (as client)", OPT_PRIO }, { "chapms-strip-domain", o_bool, &chapms_strip_domain, "Strip the domain prefix before the Username", 1 }, { NULL } }; /* * Internal state. */ static struct chap_client_state { int flags; char *name; struct chap_digest_type *digest; unsigned char priv[64]; /* private area for digest's use */ } client; /* * These limits apply to challenge and response packets we send. * The +4 is the +1 that we actually need rounded up. */ #define CHAL_MAX_PKTLEN (PPP_HDRLEN + CHAP_HDRLEN + 4 + MAX_CHALLENGE_LEN + MAXNAMELEN) #define RESP_MAX_PKTLEN (PPP_HDRLEN + CHAP_HDRLEN + 4 + MAX_RESPONSE_LEN + MAXNAMELEN) static struct chap_server_state { int flags; int id; char *name; struct chap_digest_type *digest; int challenge_xmits; int challenge_pktlen; unsigned char challenge[CHAL_MAX_PKTLEN]; char message[256]; } server; /* Values for flags in chap_client_state and chap_server_state */ #define LOWERUP 1 #define AUTH_STARTED 2 #define AUTH_DONE 4 #define AUTH_FAILED 8 #define TIMEOUT_PENDING 0x10 #define CHALLENGE_VALID 0x20 /* * Prototypes. */ static void chap_init(int unit); static void chap_lowerup(int unit); static void chap_lowerdown(int unit); static void chap_server_timeout(void *arg); static void chap_client_timeout(void *arg); static void chap_generate_challenge(struct chap_server_state *ss); static void chap_handle_response(struct chap_server_state *ss, int code, unsigned char *pkt, int len); static chap_verify_hook_fn chap_verify_response; static void chap_respond(struct chap_client_state *cs, int id, unsigned char *pkt, int len); static void chap_handle_status(struct chap_client_state *cs, int code, int id, unsigned char *pkt, int len); static void chap_protrej(int unit); static void chap_input(int unit, unsigned char *pkt, int pktlen); static int chap_print_pkt(unsigned char *p, int plen, void (*printer)(void *, char *, ...), void *arg); /* List of digest types that we know about */ static struct chap_digest_type *chap_digests; /* * chap_init - reset to initial state. */ static void chap_init(int unit) { memset(&client, 0, sizeof(client)); memset(&server, 0, sizeof(server)); chap_md5_init(); #ifdef PPP_WITH_CHAPMS chapms_init(); #endif } /* * Add a new digest type to the list. */ void chap_register_digest(struct chap_digest_type *dp) { dp->next = chap_digests; chap_digests = dp; } /* * Lookup a digest type by code */ struct chap_digest_type * chap_find_digest(int digest_code) { struct chap_digest_type *dp = NULL; for (dp = chap_digests; dp != NULL; dp = dp->next) if (dp->code == digest_code) break; return dp; } /* * chap_lowerup - we can start doing stuff now. */ static void chap_lowerup(int unit) { struct chap_client_state *cs = &client; struct chap_server_state *ss = &server; cs->flags |= LOWERUP; ss->flags |= LOWERUP; if (ss->flags & AUTH_STARTED) chap_server_timeout(ss); } static void chap_lowerdown(int unit) { struct chap_client_state *cs = &client; struct chap_server_state *ss = &server; if (cs->flags & TIMEOUT_PENDING) UNTIMEOUT(chap_client_timeout, cs); cs->flags = 0; if (ss->flags & TIMEOUT_PENDING) UNTIMEOUT(chap_server_timeout, ss); ss->flags = 0; } /* * chap_auth_peer - Start authenticating the peer. * If the lower layer is already up, we start sending challenges, * otherwise we wait for the lower layer to come up. */ void chap_auth_peer(int unit, char *our_name, int digest_code) { struct chap_server_state *ss = &server; struct chap_digest_type *dp; if (ss->flags & AUTH_STARTED) { error("CHAP: peer authentication already started!"); return; } dp = chap_find_digest(digest_code); if (dp == NULL) fatal("CHAP digest 0x%x requested but not available", digest_code); ss->digest = dp; ss->name = our_name; /* Start with a random ID value */ ss->id = (unsigned char)(drand48() * 256); ss->flags |= AUTH_STARTED; if (ss->flags & LOWERUP) chap_server_timeout(ss); } /* * chap_auth_with_peer - Prepare to authenticate ourselves to the peer. * There isn't much to do until we receive a challenge. */ void chap_auth_with_peer(int unit, char *our_name, int digest_code) { struct chap_client_state *cs = &client; struct chap_digest_type *dp; if (cs->flags & AUTH_STARTED) { error("CHAP: authentication with peer already started!"); return; } for (dp = chap_digests; dp != NULL; dp = dp->next) if (dp->code == digest_code) break; if (dp == NULL) fatal("CHAP digest 0x%x requested but not available", digest_code); cs->digest = dp; cs->name = our_name; cs->flags |= AUTH_STARTED | TIMEOUT_PENDING; TIMEOUT(chap_client_timeout, cs, chap_client_timeout_time); } /* * chap_server_timeout - It's time to send another challenge to the peer. * This could be either a retransmission of a previous challenge, * or a new challenge to start re-authentication. */ static void chap_server_timeout(void *arg) { struct chap_server_state *ss = arg; ss->flags &= ~TIMEOUT_PENDING; if ((ss->flags & CHALLENGE_VALID) == 0) { ss->challenge_xmits = 0; chap_generate_challenge(ss); ss->flags |= CHALLENGE_VALID; } else if (ss->challenge_xmits >= chap_max_transmits) { ss->flags &= ~CHALLENGE_VALID; ss->flags |= AUTH_DONE | AUTH_FAILED; auth_peer_fail(0, PPP_CHAP); return; } output(0, ss->challenge, ss->challenge_pktlen); ++ss->challenge_xmits; ss->flags |= TIMEOUT_PENDING; TIMEOUT(chap_server_timeout, arg, chap_server_timeout_time); } /* chap_client_timeout - Authentication with peer timed out. */ static void chap_client_timeout(void *arg) { struct chap_client_state *cs = arg; cs->flags &= ~TIMEOUT_PENDING; cs->flags |= AUTH_DONE | AUTH_FAILED; error("CHAP authentication timed out"); auth_withpeer_fail(0, PPP_CHAP); } /* * chap_generate_challenge - generate a challenge string and format * the challenge packet in ss->challenge_pkt. */ static void chap_generate_challenge(struct chap_server_state *ss) { int clen = 1, nlen, len; unsigned char *p; p = ss->challenge; MAKEHEADER(p, PPP_CHAP); p += CHAP_HDRLEN; ss->digest->generate_challenge(p); clen = *p; nlen = strlen(ss->name); memcpy(p + 1 + clen, ss->name, nlen); len = CHAP_HDRLEN + 1 + clen + nlen; ss->challenge_pktlen = PPP_HDRLEN + len; p = ss->challenge + PPP_HDRLEN; p[0] = CHAP_CHALLENGE; p[1] = ++ss->id; p[2] = len >> 8; p[3] = len; } /* * chap_handle_response - check the response to our challenge. */ static void chap_handle_response(struct chap_server_state *ss, int id, unsigned char *pkt, int len) { int response_len, ok, mlen; unsigned char *response, *p; char *name = NULL; chap_verify_hook_fn *verifier; char rname[MAXNAMELEN+1]; if ((ss->flags & LOWERUP) == 0) return; if (id != ss->challenge[PPP_HDRLEN+1] || len < 2) return; if (ss->flags & CHALLENGE_VALID) { response = pkt; GETCHAR(response_len, pkt); len -= response_len + 1; /* length of name */ name = (char *)pkt + response_len; if (len < 0) return; if (ss->flags & TIMEOUT_PENDING) { ss->flags &= ~TIMEOUT_PENDING; UNTIMEOUT(chap_server_timeout, ss); } if (explicit_remote) { name = remote_name; } else { /* Null terminate and clean remote name. */ slprintf(rname, sizeof(rname), "%.*v", len, name); name = rname; /* strip the MS domain name */ if (chapms_strip_domain && strrchr(rname, '\\')) { char tmp[MAXNAMELEN+1]; strcpy(tmp, strrchr(rname, '\\') + 1); strcpy(rname, tmp); } } if (chap_verify_hook) verifier = chap_verify_hook; else verifier = chap_verify_response; ok = (*verifier)(name, ss->name, id, ss->digest, ss->challenge + PPP_HDRLEN + CHAP_HDRLEN, response, ss->message, sizeof(ss->message)); if (!ok || !auth_number()) { ss->flags |= AUTH_FAILED; warn("Peer %q failed CHAP authentication", name); } } else if ((ss->flags & AUTH_DONE) == 0) return; /* send the response */ p = outpacket_buf; MAKEHEADER(p, PPP_CHAP); mlen = strlen(ss->message); len = CHAP_HDRLEN + mlen; p[0] = (ss->flags & AUTH_FAILED)? CHAP_FAILURE: CHAP_SUCCESS; p[1] = id; p[2] = len >> 8; p[3] = len; if (mlen > 0) memcpy(p + CHAP_HDRLEN, ss->message, mlen); output(0, outpacket_buf, PPP_HDRLEN + len); if (ss->flags & CHALLENGE_VALID) { ss->flags &= ~CHALLENGE_VALID; if (!(ss->flags & AUTH_DONE) && !(ss->flags & AUTH_FAILED)) { /* * Auth is OK, so now we need to check session restrictions * to ensure everything is OK, but only if we used a * plugin, and only if we're configured to check. This * allows us to do PAM checks on PPP servers that * authenticate against ActiveDirectory, and use AD for * account info (like when using Winbind integrated with * PAM). */ if (session_mgmt && session_check(name, NULL, devnam, NULL) == 0) { ss->flags |= AUTH_FAILED; warn("Peer %q failed CHAP Session verification", name); } } if (ss->flags & AUTH_FAILED) { auth_peer_fail(0, PPP_CHAP); } else { if ((ss->flags & AUTH_DONE) == 0) auth_peer_success(0, PPP_CHAP, ss->digest->code, name, strlen(name)); if (chap_rechallenge_time) { ss->flags |= TIMEOUT_PENDING; TIMEOUT(chap_server_timeout, ss, chap_rechallenge_time); } } ss->flags |= AUTH_DONE; } } /* * chap_verify_response - check whether the peer's response matches * what we think it should be. Returns 1 if it does (authentication * succeeded), or 0 if it doesn't. */ static int chap_verify_response(char *name, char *ourname, int id, struct chap_digest_type *digest, unsigned char *challenge, unsigned char *response, char *message, int message_space) { int ok; unsigned char secret[MAXSECRETLEN]; int secret_len; /* Get the secret that the peer is supposed to know */ if (!get_secret(0, name, ourname, (char *)secret, &secret_len, 1)) { error("No CHAP secret found for authenticating %q", name); return 0; } ok = digest->verify_response(id, name, secret, secret_len, challenge, response, message, message_space); memset(secret, 0, sizeof(secret)); return ok; } /* * chap_respond - Generate and send a response to a challenge. */ static void chap_respond(struct chap_client_state *cs, int id, unsigned char *pkt, int len) { int clen, nlen; int secret_len; unsigned char *p; unsigned char response[RESP_MAX_PKTLEN]; char rname[MAXNAMELEN+1]; char secret[MAXSECRETLEN+1]; if ((cs->flags & (LOWERUP | AUTH_STARTED)) != (LOWERUP | AUTH_STARTED)) return; /* not ready */ if (len < 2 || len < pkt[0] + 1) return; /* too short */ clen = pkt[0]; nlen = len - (clen + 1); /* Null terminate and clean remote name. */ slprintf(rname, sizeof(rname), "%.*v", nlen, pkt + clen + 1); /* Microsoft doesn't send their name back in the PPP packet */ if (explicit_remote || (remote_name[0] != 0 && rname[0] == 0)) strlcpy(rname, remote_name, sizeof(rname)); /* get secret for authenticating ourselves with the specified host */ if (!get_secret(0, cs->name, rname, secret, &secret_len, 0)) { secret_len = 0; /* assume null secret if can't find one */ warn("No CHAP secret found for authenticating us to %q", rname); } p = response; MAKEHEADER(p, PPP_CHAP); p += CHAP_HDRLEN; cs->digest->make_response(p, id, cs->name, pkt, secret, secret_len, cs->priv); memset(secret, 0, secret_len); clen = *p; nlen = strlen(cs->name); memcpy(p + clen + 1, cs->name, nlen); p = response + PPP_HDRLEN; len = CHAP_HDRLEN + clen + 1 + nlen; p[0] = CHAP_RESPONSE; p[1] = id; p[2] = len >> 8; p[3] = len; output(0, response, PPP_HDRLEN + len); } static void chap_handle_status(struct chap_client_state *cs, int code, int id, unsigned char *pkt, int len) { const char *msg = NULL; if ((cs->flags & (AUTH_DONE|AUTH_STARTED|LOWERUP)) != (AUTH_STARTED|LOWERUP)) return; cs->flags |= AUTH_DONE; UNTIMEOUT(chap_client_timeout, cs); cs->flags &= ~TIMEOUT_PENDING; if (code == CHAP_SUCCESS) { /* used for MS-CHAP v2 mutual auth, yuck */ if (cs->digest->check_success != NULL) { if (!(*cs->digest->check_success)(id, pkt, len)) code = CHAP_FAILURE; } else msg = "CHAP authentication succeeded"; } else { if (cs->digest->handle_failure != NULL) (*cs->digest->handle_failure)(pkt, len); else msg = "CHAP authentication failed"; } if (msg) { if (len > 0) info("%s: %.*v", msg, len, pkt); else info("%s", msg); } if (code == CHAP_SUCCESS) auth_withpeer_success(0, PPP_CHAP, cs->digest->code); else { cs->flags |= AUTH_FAILED; error("CHAP authentication failed"); auth_withpeer_fail(0, PPP_CHAP); } } static void chap_input(int unit, unsigned char *pkt, int pktlen) { struct chap_client_state *cs = &client; struct chap_server_state *ss = &server; unsigned char code, id; int len; if (pktlen < CHAP_HDRLEN) return; GETCHAR(code, pkt); GETCHAR(id, pkt); GETSHORT(len, pkt); if (len < CHAP_HDRLEN || len > pktlen) return; len -= CHAP_HDRLEN; switch (code) { case CHAP_CHALLENGE: chap_respond(cs, id, pkt, len); break; case CHAP_RESPONSE: chap_handle_response(ss, id, pkt, len); break; case CHAP_FAILURE: case CHAP_SUCCESS: chap_handle_status(cs, code, id, pkt, len); break; } } static void chap_protrej(int unit) { struct chap_client_state *cs = &client; struct chap_server_state *ss = &server; if (ss->flags & TIMEOUT_PENDING) { ss->flags &= ~TIMEOUT_PENDING; UNTIMEOUT(chap_server_timeout, ss); } if (ss->flags & AUTH_STARTED) { ss->flags = 0; auth_peer_fail(0, PPP_CHAP); } if ((cs->flags & (AUTH_STARTED|AUTH_DONE)) == AUTH_STARTED) { cs->flags &= ~AUTH_STARTED; error("CHAP authentication failed due to protocol-reject"); auth_withpeer_fail(0, PPP_CHAP); } } /* * chap_print_pkt - print the contents of a CHAP packet. */ static char *chap_code_names[] = { "Challenge", "Response", "Success", "Failure" }; static int chap_print_pkt(unsigned char *p, int plen, void (*printer)(void *, char *, ...), void *arg) { int code, id, len; int clen, nlen; unsigned char x; if (plen < CHAP_HDRLEN) return 0; GETCHAR(code, p); GETCHAR(id, p); GETSHORT(len, p); if (len < CHAP_HDRLEN || len > plen) return 0; if (code >= 1 && code <= sizeof(chap_code_names) / sizeof(char *)) printer(arg, " %s", chap_code_names[code-1]); else printer(arg, " code=0x%x", code); printer(arg, " id=0x%x", id); len -= CHAP_HDRLEN; switch (code) { case CHAP_CHALLENGE: case CHAP_RESPONSE: if (len < 1) break; clen = p[0]; if (len < clen + 1) break; ++p; nlen = len - clen - 1; printer(arg, " <"); for (; clen > 0; --clen) { GETCHAR(x, p); printer(arg, "%.2x", x); } printer(arg, ">, name = "); print_string((char *)p, nlen, printer, arg); break; case CHAP_FAILURE: case CHAP_SUCCESS: printer(arg, " "); print_string((char *)p, len, printer, arg); break; default: for (clen = len; clen > 0; --clen) { GETCHAR(x, p); printer(arg, " %.2x", x); } } return len + CHAP_HDRLEN; } struct protent chap_protent = { PPP_CHAP, chap_init, chap_input, chap_protrej, chap_lowerup, chap_lowerdown, NULL, /* open */ NULL, /* close */ chap_print_pkt, NULL, /* datainput */ 1, /* enabled_flag */ "CHAP", /* name */ NULL, /* data_name */ chap_option_list, NULL, /* check_options */ }; ppp-2.5.0/pppd/demand.c0000644000175000017500000002350414353435407011611 00000000000000/* * demand.c - Support routines for demand-dialling. * * Copyright (c) 1996-2002 Paul Mackerras. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. The name(s) of the authors of this software must not be used to * endorse or promote products derived from this software without * prior written permission. * * 3. Redistributions of any form whatsoever must retain the following * acknowledgment: * "This product includes software developed by Paul Mackerras * ". * * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #define RCSID "$Id: demand.c,v 1.20 2005/08/25 12:14:18 paulus Exp $" #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef PPP_WITH_FILTER #include #endif #include "pppd-private.h" #include "fsm.h" #include "ipcp.h" #include "lcp.h" char *frame; int framelen; int framemax; int escape_flag; int flush_flag; int fcs; struct packet { int length; struct packet *next; unsigned char data[1]; }; struct packet *pend_q; struct packet *pend_qtail; static int active_packet(unsigned char *, int); /* * demand_conf - configure the interface for doing dial-on-demand. */ void demand_conf(void) { int i; struct protent *protp; /* framemax = lcp_allowoptions[0].mru; if (framemax < PPP_MRU) */ framemax = PPP_MRU; framemax += PPP_HDRLEN + PPP_FCSLEN; frame = malloc(framemax); if (frame == NULL) novm("demand frame"); framelen = 0; pend_q = NULL; escape_flag = 0; flush_flag = 0; fcs = PPP_INITFCS; ppp_set_mtu(0, MIN(lcp_allowoptions[0].mru, PPP_MRU)); if (ppp_send_config(0, PPP_MRU, (u_int32_t) 0, 0, 0) < 0 || ppp_recv_config(0, PPP_MRU, (u_int32_t) 0, 0, 0) < 0) fatal("Couldn't set up demand-dialled PPP interface: %m"); #ifdef PPP_WITH_FILTER set_filters(&pass_filter, &active_filter); #endif /* * Call the demand_conf procedure for each protocol that's got one. */ for (i = 0; (protp = protocols[i]) != NULL; ++i) if (protp->enabled_flag && protp->demand_conf != NULL) if (!((*protp->demand_conf)(0))) die(1); } /* * demand_block - set each network protocol to block further packets. */ void demand_block(void) { int i; struct protent *protp; for (i = 0; (protp = protocols[i]) != NULL; ++i) if (protp->enabled_flag && protp->demand_conf != NULL) sifnpmode(0, protp->protocol & ~0x8000, NPMODE_QUEUE); get_loop_output(); } /* * demand_discard - set each network protocol to discard packets * with an error. */ void demand_discard(void) { struct packet *pkt, *nextpkt; int i; struct protent *protp; for (i = 0; (protp = protocols[i]) != NULL; ++i) if (protp->enabled_flag && protp->demand_conf != NULL) sifnpmode(0, protp->protocol & ~0x8000, NPMODE_ERROR); get_loop_output(); /* discard all saved packets */ for (pkt = pend_q; pkt != NULL; pkt = nextpkt) { nextpkt = pkt->next; free(pkt); } pend_q = NULL; framelen = 0; flush_flag = 0; escape_flag = 0; fcs = PPP_INITFCS; } /* * demand_unblock - set each enabled network protocol to pass packets. */ void demand_unblock(void) { int i; struct protent *protp; for (i = 0; (protp = protocols[i]) != NULL; ++i) if (protp->enabled_flag && protp->demand_conf != NULL) sifnpmode(0, protp->protocol & ~0x8000, NPMODE_PASS); } /* * FCS lookup table as calculated by genfcstab. */ static u_short fcstab[256] = { 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf, 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7, 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e, 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876, 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd, 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5, 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c, 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974, 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb, 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3, 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a, 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72, 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9, 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1, 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738, 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70, 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7, 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff, 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036, 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e, 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5, 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd, 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134, 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c, 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3, 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb, 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232, 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a, 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1, 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9, 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330, 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78 }; #define PPP_FCS(fcs, c) (((fcs) >> 8) ^ fcstab[((fcs) ^ (c)) & 0xff]) /* * loop_chars - process characters received from the loopback. * Calls loop_frame when a complete frame has been accumulated. * Return value is 1 if we need to bring up the link, 0 otherwise. */ int loop_chars(unsigned char *p, int n) { int c, rv; rv = 0; for (; n > 0; --n) { c = *p++; if (c == PPP_FLAG) { if (!escape_flag && !flush_flag && framelen > 2 && fcs == PPP_GOODFCS) { framelen -= 2; if (loop_frame((unsigned char *)frame, framelen)) rv = 1; } framelen = 0; flush_flag = 0; escape_flag = 0; fcs = PPP_INITFCS; continue; } if (flush_flag) continue; if (escape_flag) { c ^= PPP_TRANS; escape_flag = 0; } else if (c == PPP_ESCAPE) { escape_flag = 1; continue; } if (framelen >= framemax) { flush_flag = 1; continue; } frame[framelen++] = c; fcs = PPP_FCS(fcs, c); } return rv; } /* * loop_frame - given a frame obtained from the loopback, * decide whether to bring up the link or not, and, if we want * to transmit this frame later, put it on the pending queue. * Return value is 1 if we need to bring up the link, 0 otherwise. * We assume that the kernel driver has already applied the * pass_filter, so we won't get packets it rejected. * We apply the active_filter to see if we want this packet to * bring up the link. */ int loop_frame(unsigned char *frame, int len) { struct packet *pkt; /* dbglog("from loop: %P", frame, len); */ if (len < PPP_HDRLEN) return 0; if ((PPP_PROTOCOL(frame) & 0x8000) != 0) return 0; /* shouldn't get any of these anyway */ if (!active_packet(frame, len)) return 0; pkt = (struct packet *) malloc(sizeof(struct packet) + len); if (pkt != NULL) { pkt->length = len; pkt->next = NULL; memcpy(pkt->data, frame, len); if (pend_q == NULL) pend_q = pkt; else pend_qtail->next = pkt; pend_qtail = pkt; } return 1; } /* * demand_rexmit - Resend all those frames which we got via the * loopback, now that the real serial link is up. */ void demand_rexmit(int proto) { struct packet *pkt, *prev, *nextpkt; prev = NULL; pkt = pend_q; pend_q = NULL; for (; pkt != NULL; pkt = nextpkt) { nextpkt = pkt->next; if (PPP_PROTOCOL(pkt->data) == proto) { output(0, pkt->data, pkt->length); free(pkt); } else { if (prev == NULL) pend_q = pkt; else prev->next = pkt; prev = pkt; } } pend_qtail = prev; if (prev != NULL) prev->next = NULL; } /* * Scan a packet to decide whether it is an "active" packet, * that is, whether it is worth bringing up the link for. */ static int active_packet(unsigned char *p, int len) { int proto, i; struct protent *protp; if (len < PPP_HDRLEN) return 0; proto = PPP_PROTOCOL(p); #ifdef PPP_WITH_FILTER p[0] = 1; /* outbound packet indicator */ if ((pass_filter.bf_len != 0 && bpf_filter(pass_filter.bf_insns, p, len, len) == 0) || (active_filter.bf_len != 0 && bpf_filter(active_filter.bf_insns, p, len, len) == 0)) { p[0] = 0xff; return 0; } p[0] = 0xff; #endif for (i = 0; (protp = protocols[i]) != NULL; ++i) { if (protp->protocol < 0xC000 && (protp->protocol & ~0x8000) == proto) { if (!protp->enabled_flag) return 0; if (protp->active_pkt == NULL) return 1; return (*protp->active_pkt)(p, len); } } return 0; /* not a supported protocol !!?? */ } ppp-2.5.0/pppd/eap.c0000644000175000017500000024420414407475306011132 00000000000000/* * eap.c - Extensible Authentication Protocol for PPP (RFC 2284) * * Copyright (c) 2001 by Sun Microsystems, Inc. * All rights reserved. * * Non-exclusive rights to redistribute, modify, translate, and use * this software in source and binary forms, in whole or in part, is * hereby granted, provided that the above copyright notice is * duplicated in any source form, and that neither the name of the * copyright holder nor the author is used to endorse or promote * products derived from this software. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * * Original version by James Carlson * * This implementation of EAP supports MD5-Challenge and SRP-SHA1 * authentication styles. Note that support of MD5-Challenge is a * requirement of RFC 2284, and that it's essentially just a * reimplementation of regular RFC 1994 CHAP using EAP messages. * * As an authenticator ("server"), there are multiple phases for each * style. In the first phase of each style, the unauthenticated peer * name is queried using the EAP Identity request type. If the * "remotename" option is used, then this phase is skipped, because * the peer's name is presumed to be known. * * For MD5-Challenge, there are two phases, and the second phase * consists of sending the challenge itself and handling the * associated response. * * For SRP-SHA1, there are four phases. The second sends 's', 'N', * and 'g'. The reply contains 'A'. The third sends 'B', and the * reply contains 'M1'. The forth sends the 'M2' value. * * As an authenticatee ("client"), there's just a single phase -- * responding to the queries generated by the peer. EAP is an * authenticator-driven protocol. * * Based on draft-ietf-pppext-eap-srp-03.txt. */ /* * Modification by Beniamino Galvani, Mar 2005 * Implemented EAP-TLS authentication */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include #include #include #include #include "pppd-private.h" #include "options.h" #include "pathnames.h" #include "crypto.h" #include "crypto_ms.h" #include "eap.h" #ifdef PPP_WITH_PEAP #include "peap.h" #endif /* PPP_WITH_PEAP */ #ifdef PPP_WITH_SRP #ifdef HAVE_TIME_H #include #endif #include #include #include #endif /* PPP_WITH_SRP */ #ifdef PPP_WITH_EAPTLS #include "eap-tls.h" #endif /* PPP_WITH_EAPTLS */ #ifdef PPP_WITH_CHAPMS #include "chap.h" #include "chap_ms.h" extern int chapms_strip_domain; #endif /* PPP_WITH_CHAPMS */ eap_state eap_states[NUM_PPP]; /* EAP state; one for each unit */ #ifdef PPP_WITH_SRP static char *pn_secret = NULL; /* Pseudonym generating secret */ #endif /* * Command-line options. */ static struct option eap_option_list[] = { { "eap-restart", o_int, &eap_states[0].es_server.ea_timeout, "Set retransmit timeout for EAP Requests (server)" }, { "eap-max-sreq", o_int, &eap_states[0].es_server.ea_maxrequests, "Set max number of EAP Requests sent (server)" }, { "eap-timeout", o_int, &eap_states[0].es_client.ea_timeout, "Set time limit for peer EAP authentication" }, { "eap-max-rreq", o_int, &eap_states[0].es_client.ea_maxrequests, "Set max number of EAP Requests allows (client)" }, { "eap-interval", o_int, &eap_states[0].es_rechallenge, "Set interval for EAP rechallenge" }, #ifdef PPP_WITH_SRP { "srp-interval", o_int, &eap_states[0].es_lwrechallenge, "Set interval for SRP lightweight rechallenge" }, { "srp-pn-secret", o_string, &pn_secret, "Long term pseudonym generation secret" }, { "srp-use-pseudonym", o_bool, &eap_states[0].es_usepseudo, "Use pseudonym if offered one by server", 1 }, #endif { NULL } }; /* * Protocol entry points. */ static void eap_init (int unit); static void eap_input (int unit, u_char *inp, int inlen); static void eap_protrej (int unit); static void eap_lowerup (int unit); static void eap_lowerdown (int unit); static int eap_printpkt (u_char *inp, int inlen, void (*)(void *arg, char *fmt, ...), void *arg); struct protent eap_protent = { PPP_EAP, /* protocol number */ eap_init, /* initialization procedure */ eap_input, /* process a received packet */ eap_protrej, /* process a received protocol-reject */ eap_lowerup, /* lower layer has gone up */ eap_lowerdown, /* lower layer has gone down */ NULL, /* open the protocol */ NULL, /* close the protocol */ eap_printpkt, /* print a packet in readable form */ NULL, /* process a received data packet */ 1, /* protocol enabled */ "EAP", /* text name of protocol */ NULL, /* text name of corresponding data protocol */ eap_option_list, /* list of command-line options */ NULL, /* check requested options; assign defaults */ NULL, /* configure interface for demand-dial */ NULL /* say whether to bring up link for this pkt */ }; #ifdef PPP_WITH_SRP /* * A well-known 2048 bit modulus. */ static const u_char wkmodulus[] = { 0xAC, 0x6B, 0xDB, 0x41, 0x32, 0x4A, 0x9A, 0x9B, 0xF1, 0x66, 0xDE, 0x5E, 0x13, 0x89, 0x58, 0x2F, 0xAF, 0x72, 0xB6, 0x65, 0x19, 0x87, 0xEE, 0x07, 0xFC, 0x31, 0x92, 0x94, 0x3D, 0xB5, 0x60, 0x50, 0xA3, 0x73, 0x29, 0xCB, 0xB4, 0xA0, 0x99, 0xED, 0x81, 0x93, 0xE0, 0x75, 0x77, 0x67, 0xA1, 0x3D, 0xD5, 0x23, 0x12, 0xAB, 0x4B, 0x03, 0x31, 0x0D, 0xCD, 0x7F, 0x48, 0xA9, 0xDA, 0x04, 0xFD, 0x50, 0xE8, 0x08, 0x39, 0x69, 0xED, 0xB7, 0x67, 0xB0, 0xCF, 0x60, 0x95, 0x17, 0x9A, 0x16, 0x3A, 0xB3, 0x66, 0x1A, 0x05, 0xFB, 0xD5, 0xFA, 0xAA, 0xE8, 0x29, 0x18, 0xA9, 0x96, 0x2F, 0x0B, 0x93, 0xB8, 0x55, 0xF9, 0x79, 0x93, 0xEC, 0x97, 0x5E, 0xEA, 0xA8, 0x0D, 0x74, 0x0A, 0xDB, 0xF4, 0xFF, 0x74, 0x73, 0x59, 0xD0, 0x41, 0xD5, 0xC3, 0x3E, 0xA7, 0x1D, 0x28, 0x1E, 0x44, 0x6B, 0x14, 0x77, 0x3B, 0xCA, 0x97, 0xB4, 0x3A, 0x23, 0xFB, 0x80, 0x16, 0x76, 0xBD, 0x20, 0x7A, 0x43, 0x6C, 0x64, 0x81, 0xF1, 0xD2, 0xB9, 0x07, 0x87, 0x17, 0x46, 0x1A, 0x5B, 0x9D, 0x32, 0xE6, 0x88, 0xF8, 0x77, 0x48, 0x54, 0x45, 0x23, 0xB5, 0x24, 0xB0, 0xD5, 0x7D, 0x5E, 0xA7, 0x7A, 0x27, 0x75, 0xD2, 0xEC, 0xFA, 0x03, 0x2C, 0xFB, 0xDB, 0xF5, 0x2F, 0xB3, 0x78, 0x61, 0x60, 0x27, 0x90, 0x04, 0xE5, 0x7A, 0xE6, 0xAF, 0x87, 0x4E, 0x73, 0x03, 0xCE, 0x53, 0x29, 0x9C, 0xCC, 0x04, 0x1C, 0x7B, 0xC3, 0x08, 0xD8, 0x2A, 0x56, 0x98, 0xF3, 0xA8, 0xD0, 0xC3, 0x82, 0x71, 0xAE, 0x35, 0xF8, 0xE9, 0xDB, 0xFB, 0xB6, 0x94, 0xB5, 0xC8, 0x03, 0xD8, 0x9F, 0x7A, 0xE4, 0x35, 0xDE, 0x23, 0x6D, 0x52, 0x5F, 0x54, 0x75, 0x9B, 0x65, 0xE3, 0x72, 0xFC, 0xD6, 0x8E, 0xF2, 0x0F, 0xA7, 0x11, 0x1F, 0x9E, 0x4A, 0xFF, 0x73 }; #endif /* PPP_WITH_SRP */ /* Local forward declarations. */ static void eap_server_timeout (void *arg); /* * Convert EAP state code to printable string for debug. */ static const char * eap_state_name(enum eap_state_code esc) { static const char *state_names[] = { EAP_STATES }; return (state_names[(int)esc]); } /* * eap_init - Initialize state for an EAP user. This is currently * called once by main() during start-up. */ static void eap_init(int unit) { eap_state *esp = &eap_states[unit]; BZERO(esp, sizeof (*esp)); esp->es_unit = unit; esp->es_server.ea_timeout = EAP_DEFTIMEOUT; esp->es_server.ea_maxrequests = EAP_DEFTRANSMITS; esp->es_server.ea_id = (u_char)(drand48() * 0x100); esp->es_client.ea_timeout = EAP_DEFREQTIME; esp->es_client.ea_maxrequests = EAP_DEFALLOWREQ; #ifdef PPP_WITH_EAPTLS esp->es_client.ea_using_eaptls = 0; #endif /* PPP_WITH_EAPTLS */ #ifdef PPP_WITH_CHAPMS esp->es_client.digest = chap_find_digest(CHAP_MICROSOFT_V2); esp->es_server.digest = chap_find_digest(CHAP_MICROSOFT_V2); #endif } /* * eap_client_timeout - Give up waiting for the peer to send any * Request messages. */ static void eap_client_timeout(void *arg) { eap_state *esp = (eap_state *) arg; if (!eap_client_active(esp)) return; error("EAP: timeout waiting for Request from peer"); auth_withpeer_fail(esp->es_unit, PPP_EAP); esp->es_client.ea_state = eapBadAuth; } /* * eap_authwithpeer - Authenticate to our peer (behave as client). * * Start client state and wait for requests. This is called only * after eap_lowerup. */ void eap_authwithpeer(int unit, char *localname) { eap_state *esp = &eap_states[unit]; /* Save the peer name we're given */ esp->es_client.ea_name = localname; esp->es_client.ea_namelen = strlen(localname); esp->es_client.ea_state = eapListen; /* * Start a timer so that if the other end just goes * silent, we don't sit here waiting forever. */ if (esp->es_client.ea_timeout > 0) TIMEOUT(eap_client_timeout, (void *)esp, esp->es_client.ea_timeout); } /* * Format a standard EAP Failure message and send it to the peer. * (Server operation) */ static void eap_send_failure(eap_state *esp) { u_char *outp; outp = outpacket_buf; MAKEHEADER(outp, PPP_EAP); PUTCHAR(EAP_FAILURE, outp); esp->es_server.ea_id++; PUTCHAR(esp->es_server.ea_id, outp); PUTSHORT(EAP_HEADERLEN, outp); output(esp->es_unit, outpacket_buf, EAP_HEADERLEN + PPP_HDRLEN); esp->es_server.ea_state = eapBadAuth; auth_peer_fail(esp->es_unit, PPP_EAP); } /* * Format a standard EAP Success message and send it to the peer. * (Server operation) */ static void eap_send_success(eap_state *esp) { u_char *outp; outp = outpacket_buf; MAKEHEADER(outp, PPP_EAP); PUTCHAR(EAP_SUCCESS, outp); esp->es_server.ea_id++; PUTCHAR(esp->es_server.ea_id, outp); PUTSHORT(EAP_HEADERLEN, outp); output(esp->es_unit, outpacket_buf, PPP_HDRLEN + EAP_HEADERLEN); auth_peer_success(esp->es_unit, PPP_EAP, 0, esp->es_server.ea_peer, esp->es_server.ea_peerlen); } #ifdef PPP_WITH_SRP /* * Set DES key according to pseudonym-generating secret and current * date. */ static bool pncrypt_getkey(int timeoffs, unsigned char *key, int keylen) { struct tm *tp; char tbuf[9]; PPP_MD_CTX *ctxt; time_t reftime; if (pn_secret == NULL) return (0); reftime = time(NULL) + timeoffs; tp = localtime(&reftime); ctxt = PPP_MD_CTX_new(); if (ctxt) { strftime(tbuf, sizeof (tbuf), "%Y%m%d", tp); PPP_DigestInit(ctxt, PPP_sha1()); PPP_DigestUpdate(ctxt, pn_secret, strlen(pn_secret)); PPP_DigestUpdate(ctxt, tbuf, strlen(tbuf)); PPP_DigestFinal(ctxt, key, &keylen); PPP_MD_CTX_free(ctxt); return 1; } return (0); } static char base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; struct b64state { u_int32_t bs_bits; int bs_offs; }; static int b64enc(struct b64state *bs, u_char *inp, int inlen, u_char *outp) { int outlen = 0; while (inlen > 0) { bs->bs_bits = (bs->bs_bits << 8) | *inp++; inlen--; bs->bs_offs += 8; if (bs->bs_offs >= 24) { *outp++ = base64[(bs->bs_bits >> 18) & 0x3F]; *outp++ = base64[(bs->bs_bits >> 12) & 0x3F]; *outp++ = base64[(bs->bs_bits >> 6) & 0x3F]; *outp++ = base64[bs->bs_bits & 0x3F]; outlen += 4; bs->bs_offs = 0; bs->bs_bits = 0; } } return (outlen); } static int b64flush(struct b64state *bs, u_char *outp) { int outlen = 0; if (bs->bs_offs == 8) { *outp++ = base64[(bs->bs_bits >> 2) & 0x3F]; *outp++ = base64[(bs->bs_bits << 4) & 0x3F]; outlen = 2; } else if (bs->bs_offs == 16) { *outp++ = base64[(bs->bs_bits >> 10) & 0x3F]; *outp++ = base64[(bs->bs_bits >> 4) & 0x3F]; *outp++ = base64[(bs->bs_bits << 2) & 0x3F]; outlen = 3; } bs->bs_offs = 0; bs->bs_bits = 0; return (outlen); } static int b64dec(struct b64state *bs, u_char *inp, int inlen, u_char *outp) { int outlen = 0; char *cp; while (inlen > 0) { if ((cp = strchr(base64, *inp++)) == NULL) break; bs->bs_bits = (bs->bs_bits << 6) | (cp - base64); inlen--; bs->bs_offs += 6; if (bs->bs_offs >= 8) { *outp++ = bs->bs_bits >> (bs->bs_offs - 8); outlen++; bs->bs_offs -= 8; } } return (outlen); } #endif /* PPP_WITH_SRP */ /* * Assume that current waiting server state is complete and figure * next state to use based on available authentication data. 'status' * indicates if there was an error in handling the last query. It is * 0 for success and non-zero for failure. */ static void eap_figure_next_state(eap_state *esp, int status) { #ifdef PPP_WITH_SRP unsigned char secbuf[MAXWORDLEN], clear[8], *sp, *dp, key[SHA_DIGEST_LENGTH]; struct t_pw tpw; struct t_confent *tce, mytce; char *cp, *cp2; struct t_server *ts; int id, i, plen, clen, toffs, keylen; u_char vals[2]; struct b64state bs; #endif /* PPP_WITH_SRP */ #ifdef PPP_WITH_EAPTLS struct eaptls_session *ets; int secret_len; char secret[MAXWORDLEN]; #endif /* PPP_WITH_EAPTLS */ esp->es_server.ea_timeout = esp->es_savedtime; #ifdef PPP_WITH_EAPTLS esp->es_server.ea_prev_state = esp->es_server.ea_state; #endif /* PPP_WITH_EAPTLS */ switch (esp->es_server.ea_state) { case eapBadAuth: return; case eapIdentify: #ifdef PPP_WITH_SRP /* Discard any previous session. */ ts = (struct t_server *)esp->es_server.ea_session; if (ts != NULL) { t_serverclose(ts); esp->es_server.ea_session = NULL; esp->es_server.ea_skey = NULL; } #endif /* PPP_WITH_SRP */ if (status != 0) { esp->es_server.ea_state = eapBadAuth; break; } #ifdef PPP_WITH_SRP /* If we've got a pseudonym, try to decode to real name. */ if (esp->es_server.ea_peerlen > SRP_PSEUDO_LEN && strncmp(esp->es_server.ea_peer, SRP_PSEUDO_ID, SRP_PSEUDO_LEN) == 0 && (esp->es_server.ea_peerlen - SRP_PSEUDO_LEN) * 3 / 4 < sizeof (secbuf)) { BZERO(&bs, sizeof (bs)); plen = b64dec(&bs, esp->es_server.ea_peer + SRP_PSEUDO_LEN, esp->es_server.ea_peerlen - SRP_PSEUDO_LEN, secbuf); toffs = 0; for (i = 0; i < 5; i++) { pncrypt_getkey(toffs, key, keylen); toffs -= 86400; if (!DesDecrypt(secbuf, key, clear)) { dbglog("no DES here; cannot decode " "pseudonym"); return; } id = *(unsigned char *)clear; if (id + 1 <= plen && id + 9 > plen) break; } if (plen % 8 == 0 && i < 5) { /* * Note that this is always shorter than the * original stored string, so there's no need * to realloc. */ if ((i = plen = *(unsigned char *)clear) > 7) i = 7; esp->es_server.ea_peerlen = plen; dp = (unsigned char *)esp->es_server.ea_peer; BCOPY(clear + 1, dp, i); plen -= i; dp += i; sp = secbuf + 8; while (plen > 0) { DesDecrypt(sp, key, dp); sp += 8; dp += 8; plen -= 8; } esp->es_server.ea_peer[ esp->es_server.ea_peerlen] = '\0'; dbglog("decoded pseudonym to \"%.*q\"", esp->es_server.ea_peerlen, esp->es_server.ea_peer); } else { dbglog("failed to decode real name"); /* Stay in eapIdentfy state; requery */ break; } } /* Look up user in secrets database. */ if (get_srp_secret(esp->es_unit, esp->es_server.ea_peer, esp->es_server.ea_name, (char *)secbuf, 1) != 0) { /* Set up default in case SRP entry is bad */ esp->es_server.ea_state = eapMD5Chall; /* Get t_confent based on index in srp-secrets */ id = strtol((char *)secbuf, &cp, 10); if (*cp++ != ':' || id < 0) break; if (id == 0) { mytce.index = 0; mytce.modulus.data = (u_char *)wkmodulus; mytce.modulus.len = sizeof (wkmodulus); mytce.generator.data = (u_char *)"\002"; mytce.generator.len = 1; tce = &mytce; } else if ((tce = gettcid(id)) != NULL) { /* * Client will have to verify this modulus/ * generator combination, and that will take * a while. Lengthen the timeout here. */ if (esp->es_server.ea_timeout > 0 && esp->es_server.ea_timeout < 30) esp->es_server.ea_timeout = 30; } else { break; } if ((cp2 = strchr(cp, ':')) == NULL) break; *cp2++ = '\0'; tpw.pebuf.name = esp->es_server.ea_peer; tpw.pebuf.password.len = t_fromb64((char *)tpw.pwbuf, cp); tpw.pebuf.password.data = (char*) tpw.pwbuf; tpw.pebuf.salt.len = t_fromb64((char *)tpw.saltbuf, cp2); tpw.pebuf.salt.data = tpw.saltbuf; if ((ts = t_serveropenraw(&tpw.pebuf, tce)) == NULL) break; esp->es_server.ea_session = (void *)ts; esp->es_server.ea_state = eapSRP1; vals[0] = esp->es_server.ea_id + 1; vals[1] = EAPT_SRP; t_serveraddexdata(ts, vals, 2); /* Generate B; must call before t_servergetkey() */ t_servergenexp(ts); break; } #endif /* PPP_WITH_SRP */ #ifdef PPP_WITH_EAPTLS if (!get_secret(esp->es_unit, esp->es_server.ea_peer, esp->es_server.ea_name, secret, &secret_len, 1)) { esp->es_server.ea_state = eapTlsStart; break; } #endif /* PPP_WITH_EAPTLS */ esp->es_server.ea_state = eapMD5Chall; break; #ifdef PPP_WITH_EAPTLS case eapTlsStart: /* Initialize ssl session */ if(!eaptls_init_ssl_server(esp)) { esp->es_server.ea_state = eapBadAuth; break; } esp->es_server.ea_state = eapTlsRecv; break; case eapTlsRecv: ets = (struct eaptls_session *) esp->es_server.ea_session; if(ets->alert_sent) { esp->es_server.ea_state = eapTlsSendAlert; break; } if (status) { esp->es_server.ea_state = eapBadAuth; break; } ets = (struct eaptls_session *) esp->es_server.ea_session; if(ets->frag) esp->es_server.ea_state = eapTlsSendAck; else esp->es_server.ea_state = eapTlsSend; break; case eapTlsSend: ets = (struct eaptls_session *) esp->es_server.ea_session; if(ets->frag) esp->es_server.ea_state = eapTlsRecvAck; else if(SSL_is_init_finished(ets->ssl)) esp->es_server.ea_state = eapTlsRecvClient; else /* JJK Add "TLS empty record" message here ??? */ esp->es_server.ea_state = eapTlsRecv; break; case eapTlsSendAck: esp->es_server.ea_state = eapTlsRecv; break; case eapTlsRecvAck: if (status) { esp->es_server.ea_state = eapBadAuth; break; } esp->es_server.ea_state = eapTlsSend; break; case eapTlsSendAlert: esp->es_server.ea_state = eapTlsRecvAlertAck; break; #endif /* PPP_WITH_EAPTLS */ case eapSRP1: #ifdef PPP_WITH_SRP ts = (struct t_server *)esp->es_server.ea_session; if (ts != NULL && status != 0) { t_serverclose(ts); esp->es_server.ea_session = NULL; esp->es_server.ea_skey = NULL; } #endif /* PPP_WITH_SRP */ if (status == 1) { esp->es_server.ea_state = eapMD5Chall; } else if (status != 0 || esp->es_server.ea_session == NULL) { esp->es_server.ea_state = eapBadAuth; } else { esp->es_server.ea_state = eapSRP2; } break; case eapSRP2: #ifdef PPP_WITH_SRP ts = (struct t_server *)esp->es_server.ea_session; if (ts != NULL && status != 0) { t_serverclose(ts); esp->es_server.ea_session = NULL; esp->es_server.ea_skey = NULL; } #endif /* PPP_WITH_SRP */ if (status != 0 || esp->es_server.ea_session == NULL) { esp->es_server.ea_state = eapBadAuth; } else { esp->es_server.ea_state = eapSRP3; } break; case eapSRP3: case eapSRP4: #ifdef PPP_WITH_SRP ts = (struct t_server *)esp->es_server.ea_session; if (ts != NULL && status != 0) { t_serverclose(ts); esp->es_server.ea_session = NULL; esp->es_server.ea_skey = NULL; } #endif /* PPP_WITH_SRP */ if (status != 0 || esp->es_server.ea_session == NULL) { esp->es_server.ea_state = eapBadAuth; } else { esp->es_server.ea_state = eapOpen; } break; #ifdef PPP_WITH_CHAPMS case eapMSCHAPv2Chall: #endif case eapMD5Chall: if (status != 0) { esp->es_server.ea_state = eapBadAuth; } else { esp->es_server.ea_state = eapOpen; } break; default: esp->es_server.ea_state = eapBadAuth; break; } if (esp->es_server.ea_state == eapBadAuth) eap_send_failure(esp); #ifdef PPP_WITH_EAPTLS dbglog("EAP id=0x%2x '%s' -> '%s'", esp->es_server.ea_id, eap_state_name(esp->es_server.ea_prev_state), eap_state_name(esp->es_server.ea_state)); #endif /* PPP_WITH_EAPTLS */ } #if PPP_WITH_CHAPMS /* * eap_chap_verify_response - check whether the peer's response matches * what we think it should be. Returns 1 if it does (authentication * succeeded), or 0 if it doesn't. */ static int eap_chap_verify_response(char *name, char *ourname, int id, struct chap_digest_type *digest, unsigned char *challenge, unsigned char *response, char *message, int message_space) { int ok; unsigned char secret[MAXSECRETLEN]; int secret_len; /* Get the secret that the peer is supposed to know */ if (!get_secret(0, name, ourname, (char *)secret, &secret_len, 1)) { error("No CHAP secret found for authenticating %q", name); return 0; } ok = digest->verify_response(id, name, secret, secret_len, challenge, response, message, message_space); memset(secret, 0, sizeof(secret)); return ok; } /* * Format and send an CHAPV2-Success/Failure EAP Request message. */ static void eap_chapms2_send_request(eap_state *esp, u_char id, u_char opcode, u_char chapid, char *message, int message_len) { u_char *outp; int msglen; outp = outpacket_buf; MAKEHEADER(outp, PPP_EAP); msglen = EAP_HEADERLEN + 5 * sizeof (u_char); msglen += message_len; PUTCHAR(EAP_REQUEST, outp); PUTCHAR(id, outp); PUTSHORT(msglen, outp); PUTCHAR(EAPT_MSCHAPV2, outp); PUTCHAR(opcode, outp); PUTCHAR(chapid, outp); /* MS len */ PUTSHORT(msglen - 5, outp); BCOPY(message, outp, message_len); output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen); if (opcode == CHAP_SUCCESS) { auth_peer_success(esp->es_unit, PPP_EAP, 0, esp->es_server.ea_peer, esp->es_server.ea_peerlen); } else { esp->es_server.ea_state = eapBadAuth; auth_peer_fail(esp->es_unit, PPP_EAP); } } #endif /* PPP_WITH_CHAPMS */ /* * Format an EAP Request message and send it to the peer. Message * type depends on current state. (Server operation) */ static void eap_send_request(eap_state *esp) { u_char *outp; u_char *lenloc; u_char *ptr; int outlen; int challen; char *str; #ifdef PPP_WITH_SRP struct t_server *ts; u_char clear[8], cipher[8], dig[SHA_DIGEST_LENGTH], *optr, *cp, key[SHA_DIGEST_LENGTH]; int i, j, diglen, clen, keylen = sizeof(key); struct b64state b64; PPP_MD_CTX *ctxt; #endif /* PPP_WITH_SRP */ /* Handle both initial auth and restart */ if (esp->es_server.ea_state < eapIdentify && esp->es_server.ea_state != eapInitial) { esp->es_server.ea_state = eapIdentify; if (explicit_remote) { /* * If we already know the peer's * unauthenticated name, then there's no * reason to ask. Go to next state instead. */ esp->es_server.ea_peer = remote_name; esp->es_server.ea_peerlen = strlen(remote_name); eap_figure_next_state(esp, 0); } } if (esp->es_server.ea_maxrequests > 0 && esp->es_server.ea_requests >= esp->es_server.ea_maxrequests) { if (esp->es_server.ea_responses > 0) error("EAP: too many Requests sent"); else error("EAP: no response to Requests"); eap_send_failure(esp); return; } outp = outpacket_buf; MAKEHEADER(outp, PPP_EAP); PUTCHAR(EAP_REQUEST, outp); PUTCHAR(esp->es_server.ea_id, outp); lenloc = outp; INCPTR(2, outp); switch (esp->es_server.ea_state) { case eapIdentify: PUTCHAR(EAPT_IDENTITY, outp); str = "Name"; challen = strlen(str); BCOPY(str, outp, challen); INCPTR(challen, outp); break; case eapMD5Chall: PUTCHAR(EAPT_MD5CHAP, outp); /* * pick a random challenge length between * MIN_CHALLENGE_LENGTH and MAX_CHALLENGE_LENGTH */ challen = (drand48() * (MAX_CHALLENGE_LENGTH - MIN_CHALLENGE_LENGTH)) + MIN_CHALLENGE_LENGTH; PUTCHAR(challen, outp); esp->es_challen = challen; ptr = esp->es_challenge; while (--challen >= 0) *ptr++ = (u_char) (drand48() * 0x100); BCOPY(esp->es_challenge, outp, esp->es_challen); INCPTR(esp->es_challen, outp); BCOPY(esp->es_server.ea_name, outp, esp->es_server.ea_namelen); INCPTR(esp->es_server.ea_namelen, outp); break; #ifdef PPP_WITH_CHAPMS case eapMSCHAPv2Chall: esp->es_server.digest->generate_challenge(esp->es_challenge); challen = esp->es_challenge[0]; esp->es_challen = challen; PUTCHAR(EAPT_MSCHAPV2, outp); PUTCHAR(CHAP_CHALLENGE, outp); PUTCHAR(esp->es_server.ea_id, outp); /* MS len */ PUTSHORT(5 + challen + esp->es_server.ea_namelen, outp); /* challen + challenge */ BCOPY(esp->es_challenge, outp, challen+1); INCPTR(challen+1, outp); BCOPY(esp->es_server.ea_name, outp, esp->es_server.ea_namelen); INCPTR(esp->es_server.ea_namelen, outp); break; #endif /* PPP_WITH_CHAPMS */ #ifdef PPP_WITH_EAPTLS case eapTlsStart: PUTCHAR(EAPT_TLS, outp); PUTCHAR(EAP_TLS_FLAGS_START, outp); eap_figure_next_state(esp, 0); break; case eapTlsSend: eaptls_send(esp->es_server.ea_session, &outp); eap_figure_next_state(esp, 0); break; case eapTlsSendAck: PUTCHAR(EAPT_TLS, outp); PUTCHAR(0, outp); eap_figure_next_state(esp, 0); break; case eapTlsSendAlert: eaptls_send(esp->es_server.ea_session, &outp); eap_figure_next_state(esp, 0); break; #endif /* PPP_WITH_EAPTLS */ #ifdef PPP_WITH_SRP case eapSRP1: PUTCHAR(EAPT_SRP, outp); PUTCHAR(EAPSRP_CHALLENGE, outp); PUTCHAR(esp->es_server.ea_namelen, outp); BCOPY(esp->es_server.ea_name, outp, esp->es_server.ea_namelen); INCPTR(esp->es_server.ea_namelen, outp); ts = (struct t_server *)esp->es_server.ea_session; assert(ts != NULL); PUTCHAR(ts->s.len, outp); BCOPY(ts->s.data, outp, ts->s.len); INCPTR(ts->s.len, outp); if (ts->g.len == 1 && ts->g.data[0] == 2) { PUTCHAR(0, outp); } else { PUTCHAR(ts->g.len, outp); BCOPY(ts->g.data, outp, ts->g.len); INCPTR(ts->g.len, outp); } if (ts->n.len != sizeof (wkmodulus) || BCMP(ts->n.data, wkmodulus, sizeof (wkmodulus)) != 0) { BCOPY(ts->n.data, outp, ts->n.len); INCPTR(ts->n.len, outp); } break; case eapSRP2: PUTCHAR(EAPT_SRP, outp); PUTCHAR(EAPSRP_SKEY, outp); ts = (struct t_server *)esp->es_server.ea_session; assert(ts != NULL); BCOPY(ts->B.data, outp, ts->B.len); INCPTR(ts->B.len, outp); break; case eapSRP3: PUTCHAR(EAPT_SRP, outp); PUTCHAR(EAPSRP_SVALIDATOR, outp); PUTLONG(SRPVAL_EBIT, outp); ts = (struct t_server *)esp->es_server.ea_session; assert(ts != NULL); BCOPY(t_serverresponse(ts), outp, SHA_DIGEST_LENGTH); INCPTR(SHA_DIGEST_LENGTH, outp); if (pncrypt_getkey(0, key, keylen)) { /* Generate pseudonym */ optr = outp; cp = (unsigned char *)esp->es_server.ea_peer; if ((j = i = esp->es_server.ea_peerlen) > 7) j = 7; clear[0] = i; BCOPY(cp, clear + 1, j); i -= j; cp += j; if (!DesEncrypt(clear, key, cipher)) { dbglog("no DES here; not generating pseudonym"); break; } BZERO(&b64, sizeof (b64)); outp++; /* space for pseudonym length */ outp += b64enc(&b64, cipher, 8, outp); while (i >= 8) { DesEncrypt(cp, key, cipher); outp += b64enc(&b64, cipher, 8, outp); cp += 8; i -= 8; } if (i > 0) { BCOPY(cp, clear, i); cp += i; while (i < 8) { *cp++ = drand48() * 0x100; i++; } DesEncrypt(clear, key, cipher); outp += b64enc(&b64, cipher, 8, outp); } outp += b64flush(&b64, outp); /* Set length and pad out to next 20 octet boundary */ i = outp - optr - 1; *optr = i; i %= SHA_DIGEST_LENGTH; if (i != 0) { while (i < SHA_DIGEST_LENGTH) { *outp++ = drand48() * 0x100; i++; } } /* Obscure the pseudonym with SHA1 hash */ ctxt = PPP_MD_CTX_new(); if (ctxt) { PPP_DigestInit(ctxt, PPP_sha1()); PPP_DigestUpdate(ctxt, &esp->es_server.ea_id, 1); PPP_DigestUpdate(ctxt, &esp->es_server.ea_skey, SESSION_KEY_LEN); PPP_DigestUpdate(ctxt, esp->es_server.ea_peer, esp->es_server.ea_peerlen); while (optr < outp) { diglen = SHA_DIGEST_LENGTH; PPP_DigestFinal(ctxt, dig, &diglen); cp = dig; while (cp < dig + SHA_DIGEST_LENGTH) *optr++ ^= *cp++; PPP_DigestInit(ctxt, PPP_sha1()); PPP_DigestUpdate(ctxt, &esp->es_server.ea_id, 1); PPP_DigestUpdate(ctxt, esp->es_server.ea_skey, SESSION_KEY_LEN); PPP_DigestUpdate(ctxt, optr - SHA_DIGEST_LENGTH, SHA_DIGEST_LENGTH); } PPP_MD_CTX_free(ctxt); } } break; case eapSRP4: PUTCHAR(EAPT_SRP, outp); PUTCHAR(EAPSRP_LWRECHALLENGE, outp); challen = MIN_CHALLENGE_LENGTH + ((MAX_CHALLENGE_LENGTH - MIN_CHALLENGE_LENGTH) * drand48()); esp->es_challen = challen; ptr = esp->es_challenge; while (--challen >= 0) *ptr++ = drand48() * 0x100; BCOPY(esp->es_challenge, outp, esp->es_challen); INCPTR(esp->es_challen, outp); break; #endif /* PPP_WITH_SRP */ default: return; } outlen = (outp - outpacket_buf) - PPP_HDRLEN; PUTSHORT(outlen, lenloc); output(esp->es_unit, outpacket_buf, outlen + PPP_HDRLEN); esp->es_server.ea_requests++; if (esp->es_server.ea_timeout > 0) TIMEOUT(eap_server_timeout, esp, esp->es_server.ea_timeout); } /* * eap_authpeer - Authenticate our peer (behave as server). * * Start server state and send first request. This is called only * after eap_lowerup. */ void eap_authpeer(int unit, char *localname) { eap_state *esp = &eap_states[unit]; /* Save the name we're given. */ esp->es_server.ea_name = localname; esp->es_server.ea_namelen = strlen(localname); esp->es_savedtime = esp->es_server.ea_timeout; /* Lower layer up yet? */ if (esp->es_server.ea_state == eapInitial || esp->es_server.ea_state == eapPending) { esp->es_server.ea_state = eapPending; return; } esp->es_server.ea_state = eapPending; /* ID number not updated here intentionally; hashed into M1 */ eap_send_request(esp); } /* * eap_server_timeout - Retransmission timer for sending Requests * expired. */ static void eap_server_timeout(void *arg) { #ifdef PPP_WITH_EAPTLS u_char *outp; u_char *lenloc; int outlen; #endif /* PPP_WITH_EAPTLS */ eap_state *esp = (eap_state *) arg; if (!eap_server_active(esp)) return; #ifdef PPP_WITH_EAPTLS switch(esp->es_server.ea_prev_state) { /* * In eap-tls the state changes after a request, so we return to * previous state ... */ case(eapTlsStart): case(eapTlsSendAck): esp->es_server.ea_state = esp->es_server.ea_prev_state; break; /* * ... or resend the stored data */ case(eapTlsSend): case(eapTlsSendAlert): outp = outpacket_buf; MAKEHEADER(outp, PPP_EAP); PUTCHAR(EAP_REQUEST, outp); PUTCHAR(esp->es_server.ea_id, outp); lenloc = outp; INCPTR(2, outp); eaptls_retransmit(esp->es_server.ea_session, &outp); outlen = (outp - outpacket_buf) - PPP_HDRLEN; PUTSHORT(outlen, lenloc); output(esp->es_unit, outpacket_buf, outlen + PPP_HDRLEN); esp->es_server.ea_requests++; if (esp->es_server.ea_timeout > 0) TIMEOUT(eap_server_timeout, esp, esp->es_server.ea_timeout); return; default: break; } #endif /* PPP_WITH_EAPTLS */ /* EAP ID number must not change on timeout. */ eap_send_request(esp); } /* * When it's time to send rechallenge the peer, this timeout is * called. Once the rechallenge is successful, the response handler * will restart the timer. If it fails, then the link is dropped. */ static void eap_rechallenge(void *arg) { eap_state *esp = (eap_state *)arg; if (esp->es_server.ea_state != eapOpen && esp->es_server.ea_state != eapSRP4) return; esp->es_server.ea_requests = 0; esp->es_server.ea_state = eapIdentify; eap_figure_next_state(esp, 0); esp->es_server.ea_id++; eap_send_request(esp); } static void srp_lwrechallenge(void *arg) { eap_state *esp = (eap_state *)arg; if (esp->es_server.ea_state != eapOpen || esp->es_server.ea_type != EAPT_SRP) return; esp->es_server.ea_requests = 0; esp->es_server.ea_state = eapSRP4; esp->es_server.ea_id++; eap_send_request(esp); } /* * eap_lowerup - The lower layer is now up. * * This is called before either eap_authpeer or eap_authwithpeer. See * link_established() in auth.c. All that's necessary here is to * return to closed state so that those two routines will do the right * thing. */ static void eap_lowerup(int unit) { eap_state *esp = &eap_states[unit]; /* Discard any (possibly authenticated) peer name. */ if (esp->es_server.ea_peer != NULL && esp->es_server.ea_peer != remote_name) free(esp->es_server.ea_peer); esp->es_server.ea_peer = NULL; if (esp->es_client.ea_peer != NULL) free(esp->es_client.ea_peer); esp->es_client.ea_peer = NULL; esp->es_client.ea_state = eapClosed; esp->es_server.ea_state = eapClosed; } /* * eap_lowerdown - The lower layer is now down. * * Cancel all timeouts and return to initial state. */ static void eap_lowerdown(int unit) { eap_state *esp = &eap_states[unit]; if (eap_client_active(esp) && esp->es_client.ea_timeout > 0) { UNTIMEOUT(eap_client_timeout, (void *)esp); } if (eap_server_active(esp)) { if (esp->es_server.ea_timeout > 0) { UNTIMEOUT(eap_server_timeout, (void *)esp); } } else { if ((esp->es_server.ea_state == eapOpen || esp->es_server.ea_state == eapSRP4) && esp->es_rechallenge > 0) { UNTIMEOUT(eap_rechallenge, (void *)esp); } if (esp->es_server.ea_state == eapOpen && esp->es_lwrechallenge > 0) { UNTIMEOUT(srp_lwrechallenge, (void *)esp); } } esp->es_client.ea_state = esp->es_server.ea_state = eapInitial; esp->es_client.ea_requests = esp->es_server.ea_requests = 0; } /* * eap_protrej - Peer doesn't speak this protocol. * * This shouldn't happen. If it does, it represents authentication * failure. */ static void eap_protrej(int unit) { eap_state *esp = &eap_states[unit]; if (eap_client_active(esp)) { error("EAP authentication failed due to Protocol-Reject"); auth_withpeer_fail(unit, PPP_EAP); } if (eap_server_active(esp)) { error("EAP authentication of peer failed on Protocol-Reject"); auth_peer_fail(unit, PPP_EAP); } eap_lowerdown(unit); } /* * Format and send a regular EAP Response message. */ static void eap_send_response(eap_state *esp, u_char id, u_char typenum, u_char *str, int lenstr) { u_char *outp; int msglen; outp = outpacket_buf; MAKEHEADER(outp, PPP_EAP); PUTCHAR(EAP_RESPONSE, outp); PUTCHAR(id, outp); esp->es_client.ea_id = id; msglen = EAP_HEADERLEN + sizeof (u_char) + lenstr; PUTSHORT(msglen, outp); PUTCHAR(typenum, outp); if (lenstr > 0) { BCOPY(str, outp, lenstr); } output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen); } /* * Format and send an MD5-Challenge EAP Response message. */ static void eap_chap_response(eap_state *esp, u_char id, u_char *hash, char *name, int namelen) { u_char *outp; int msglen; outp = outpacket_buf; MAKEHEADER(outp, PPP_EAP); PUTCHAR(EAP_RESPONSE, outp); PUTCHAR(id, outp); esp->es_client.ea_id = id; msglen = EAP_HEADERLEN + 2 * sizeof (u_char) + MD5_DIGEST_LENGTH + namelen; PUTSHORT(msglen, outp); PUTCHAR(EAPT_MD5CHAP, outp); PUTCHAR(MD5_DIGEST_LENGTH, outp); BCOPY(hash, outp, MD5_DIGEST_LENGTH); INCPTR(MD5_DIGEST_LENGTH, outp); if (namelen > 0) { BCOPY(name, outp, namelen); } output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen); } #ifdef PPP_WITH_SRP /* * Format and send a SRP EAP Response message. */ static void eap_srp_response(eap_state *esp, u_char id, u_char subtypenum, u_char *str, int lenstr) { u_char *outp; int msglen; outp = outpacket_buf; MAKEHEADER(outp, PPP_EAP); PUTCHAR(EAP_RESPONSE, outp); PUTCHAR(id, outp); esp->es_client.ea_id = id; msglen = EAP_HEADERLEN + 2 * sizeof (u_char) + lenstr; PUTSHORT(msglen, outp); PUTCHAR(EAPT_SRP, outp); PUTCHAR(subtypenum, outp); if (lenstr > 0) { BCOPY(str, outp, lenstr); } output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen); } /* * Format and send a SRP EAP Client Validator Response message. */ static void eap_srpval_response(eap_state *esp, u_char id, u_int32_t flags, u_char *str) { u_char *outp; int msglen; outp = outpacket_buf; MAKEHEADER(outp, PPP_EAP); PUTCHAR(EAP_RESPONSE, outp); PUTCHAR(id, outp); esp->es_client.ea_id = id; msglen = EAP_HEADERLEN + 2 * sizeof (u_char) + sizeof (u_int32_t) + SHA_DIGEST_LENGTH; PUTSHORT(msglen, outp); PUTCHAR(EAPT_SRP, outp); PUTCHAR(EAPSRP_CVALIDATOR, outp); PUTLONG(flags, outp); BCOPY(str, outp, SHA_DIGEST_LENGTH); output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen); } #endif /* PPP_WITH_SRP */ #ifdef PPP_WITH_EAPTLS /* * Send an EAP-TLS response message with tls data */ static void eap_tls_response(eap_state *esp, u_char id) { u_char *outp; int outlen; u_char *lenloc; outp = outpacket_buf; MAKEHEADER(outp, PPP_EAP); PUTCHAR(EAP_RESPONSE, outp); PUTCHAR(id, outp); lenloc = outp; INCPTR(2, outp); /* If the id in the request is unchanged, we must retransmit the old data */ if(id == esp->es_client.ea_id) eaptls_retransmit(esp->es_client.ea_session, &outp); else eaptls_send(esp->es_client.ea_session, &outp); outlen = (outp - outpacket_buf) - PPP_HDRLEN; PUTSHORT(outlen, lenloc); output(esp->es_unit, outpacket_buf, PPP_HDRLEN + outlen); esp->es_client.ea_id = id; } /* * Send an EAP-TLS ack */ static void eap_tls_sendack(eap_state *esp, u_char id) { u_char *outp; int outlen; u_char *lenloc; outp = outpacket_buf; MAKEHEADER(outp, PPP_EAP); PUTCHAR(EAP_RESPONSE, outp); PUTCHAR(id, outp); esp->es_client.ea_id = id; lenloc = outp; INCPTR(2, outp); PUTCHAR(EAPT_TLS, outp); PUTCHAR(0, outp); outlen = (outp - outpacket_buf) - PPP_HDRLEN; PUTSHORT(outlen, lenloc); output(esp->es_unit, outpacket_buf, PPP_HDRLEN + outlen); } #endif /* PPP_WITH_EAPTLS */ static void eap_send_nak(eap_state *esp, u_char id, u_char type) { u_char *outp; int msglen; outp = outpacket_buf; MAKEHEADER(outp, PPP_EAP); PUTCHAR(EAP_RESPONSE, outp); PUTCHAR(id, outp); esp->es_client.ea_id = id; msglen = EAP_HEADERLEN + 2 * sizeof (u_char); PUTSHORT(msglen, outp); PUTCHAR(EAPT_NAK, outp); PUTCHAR(type, outp); output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen); } #ifdef PPP_WITH_SRP static char * name_of_pn_file(void) { char *user, *path, *file; struct passwd *pw; size_t pl; static bool pnlogged = 0; pw = getpwuid(getuid()); if (pw == NULL || (user = pw->pw_dir) == NULL || user[0] == 0) { errno = EINVAL; return (NULL); } file = PPP_PATH_PSEUDONYM; pl = strlen(user) + strlen(file) + 2; path = malloc(pl); if (path == NULL) return (NULL); (void) slprintf(path, pl, "%s/%s", user, file); if (!pnlogged) { dbglog("pseudonym file: %s", path); pnlogged = 1; } return (path); } static int open_pn_file(mode_t modebits) { char *path; int fd, err; if ((path = name_of_pn_file()) == NULL) return (-1); fd = open(path, modebits, S_IRUSR | S_IWUSR); err = errno; free(path); errno = err; return (fd); } static void remove_pn_file(void) { char *path; if ((path = name_of_pn_file()) != NULL) { (void) unlink(path); (void) free(path); } } static void write_pseudonym(eap_state *esp, u_char *inp, int len, int id) { u_char val; u_char *datp, *digp; PPP_MD_CTX *ctxt; u_char dig[SHA_DIGEST_LENGTH]; int dsize, fd, olen = len, diglen = sizeof(dig); /* * Do the decoding by working backwards. This eliminates the need * to save the decoded output in a separate buffer. */ val = id; while (len > 0) { if ((dsize = len % SHA_DIGEST_LENGTH) == 0) dsize = SHA_DIGEST_LENGTH; len -= dsize; datp = inp + len; ctxt = PPP_MD_CTX_new(); if (ctxt) { PPP_DigestInit(ctxt, PPP_sha1()); PPP_DigestUpdate(ctxt, &val, 1); PPP_DigestUpdate(ctxt, esp->es_client.ea_skey, SESSION_KEY_LEN); if (len > 0) { PPP_DigestUpdate(ctxt, datp, SHA_DIGEST_LENGTH); } else { PPP_DigestUpdate(ctxt, esp->es_client.ea_name, esp->es_client.ea_namelen); } PPP_DigestFinal(ctxt, dig, &diglen); for (digp = dig; digp < dig + SHA_DIGEST_LENGTH; digp++) *datp++ ^= *digp; PPP_MD_CTX_free(ctxt); } } /* Now check that the result is sane */ if (olen <= 0 || *inp + 1 > olen) { dbglog("EAP: decoded pseudonym is unusable <%.*B>", olen, inp); return; } /* Save it away */ fd = open_pn_file(O_WRONLY | O_CREAT | O_TRUNC); if (fd < 0) { dbglog("EAP: error saving pseudonym: %m"); return; } len = write(fd, inp + 1, *inp); if (close(fd) != -1 && len == *inp) { dbglog("EAP: saved pseudonym"); esp->es_usedpseudo = 0; } else { dbglog("EAP: failed to save pseudonym"); remove_pn_file(); } } #endif /* PPP_WITH_SRP */ #if PPP_WITH_CHAPMS /* * Format and send an CHAPV2-Challenge EAP Response message. */ static void eap_chapv2_response(eap_state *esp, u_char id, u_char chapid, u_char *response, char *user, int user_len) { u_char *outp; int msglen; outp = outpacket_buf; MAKEHEADER(outp, PPP_EAP); PUTCHAR(EAP_RESPONSE, outp); PUTCHAR(id, outp); esp->es_client.ea_id = id; msglen = EAP_HEADERLEN + 6 * sizeof (u_char) + MS_CHAP2_RESPONSE_LEN + user_len; PUTSHORT(msglen, outp); PUTCHAR(EAPT_MSCHAPV2, outp); PUTCHAR(CHAP_RESPONSE, outp); PUTCHAR(chapid, outp); PUTCHAR(0, outp); /* len */ PUTCHAR(5 + user_len + MS_CHAP2_RESPONSE_LEN, outp); BCOPY(response, outp, MS_CHAP2_RESPONSE_LEN+1); // VLEN + VALUE INCPTR(MS_CHAP2_RESPONSE_LEN+1, outp); BCOPY(user, outp, user_len); output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen); } #endif /* * eap_request - Receive EAP Request message (client mode). */ static void eap_request(eap_state *esp, u_char *inp, int id, int len) { u_char typenum; u_char vallen; int secret_len; char secret[MAXWORDLEN]; char rhostname[256]; PPP_MD_CTX *mdctx; u_char hash[MD5_DIGEST_LENGTH]; int hashlen = MD5_DIGEST_LENGTH; #ifdef PPP_WITH_EAPTLS u_char flags; struct eaptls_session *ets = esp->es_client.ea_session; #endif /* PPP_WITH_EAPTLS */ #ifdef PPP_WITH_SRP struct t_client *tc; struct t_num sval, gval, Nval, *Ap, Bval; u_char vals[2]; PPP_MD_CTX *ctxt; u_char dig[SHA_DIGEST_LENGTH]; int diglen = sizeof(dig); int fd; #endif /* PPP_WITH_SRP */ /* * Ignore requests if we're not open */ if (esp->es_client.ea_state <= eapClosed) return; /* * Note: we update es_client.ea_id *only if* a Response * message is being generated. Otherwise, we leave it the * same for duplicate detection purposes. */ esp->es_client.ea_requests++; if (esp->es_client.ea_maxrequests != 0 && esp->es_client.ea_requests > esp->es_client.ea_maxrequests) { info("EAP: received too many Request messages"); if (esp->es_client.ea_timeout > 0) { UNTIMEOUT(eap_client_timeout, (void *)esp); } auth_withpeer_fail(esp->es_unit, PPP_EAP); return; } if (len <= 0) { error("EAP: empty Request message discarded"); return; } GETCHAR(typenum, inp); len--; switch (typenum) { case EAPT_IDENTITY: if (len > 0) info("EAP: Identity prompt \"%.*q\"", len, inp); #ifdef PPP_WITH_SRP if (esp->es_usepseudo && (esp->es_usedpseudo == 0 || (esp->es_usedpseudo == 1 && id == esp->es_client.ea_id))) { esp->es_usedpseudo = 1; /* Try to get a pseudonym */ if ((fd = open_pn_file(O_RDONLY)) >= 0) { strcpy(rhostname, SRP_PSEUDO_ID); len = read(fd, rhostname + SRP_PSEUDO_LEN, sizeof (rhostname) - SRP_PSEUDO_LEN); /* XXX NAI unsupported */ if (len > 0) { eap_send_response(esp, id, typenum, rhostname, len + SRP_PSEUDO_LEN); } (void) close(fd); if (len > 0) break; } } /* Stop using pseudonym now. */ if (esp->es_usepseudo && esp->es_usedpseudo != 2) { remove_pn_file(); esp->es_usedpseudo = 2; } #endif /* PPP_WITH_SRP */ eap_send_response(esp, id, typenum, (u_char *)esp->es_client.ea_name, esp->es_client.ea_namelen); break; case EAPT_NOTIFICATION: if (len > 0) info("EAP: Notification \"%.*q\"", len, inp); eap_send_response(esp, id, typenum, NULL, 0); break; case EAPT_NAK: /* * Avoid the temptation to send Response Nak in reply * to Request Nak here. It can only lead to trouble. */ warn("EAP: unexpected Nak in Request; ignored"); /* Return because we're waiting for something real. */ return; case EAPT_MD5CHAP: if (len < 1) { error("EAP: received MD5-Challenge with no data"); /* Bogus request; wait for something real. */ return; } GETCHAR(vallen, inp); len--; if (vallen < 8 || vallen > len) { error("EAP: MD5-Challenge with bad length %d (8..%d)", vallen, len); /* Try something better. */ eap_send_nak(esp, id, EAPT_SRP); break; } /* Not so likely to happen. */ if (len - vallen >= sizeof (rhostname)) { dbglog("EAP: trimming really long peer name down"); BCOPY(inp + vallen, rhostname, sizeof (rhostname) - 1); rhostname[sizeof (rhostname) - 1] = '\0'; } else { BCOPY(inp + vallen, rhostname, len - vallen); rhostname[len - vallen] = '\0'; } /* In case the remote doesn't give us his name. */ if (explicit_remote || (remote_name[0] != '\0' && vallen == len)) strlcpy(rhostname, remote_name, sizeof (rhostname)); /* * Get the secret for authenticating ourselves with * the specified host. */ if (!get_secret(esp->es_unit, esp->es_client.ea_name, rhostname, secret, &secret_len, 0)) { dbglog("EAP: no MD5 secret for auth to %q", rhostname); eap_send_nak(esp, id, EAPT_SRP); break; } mdctx = PPP_MD_CTX_new(); if (mdctx != NULL) { if (PPP_DigestInit(mdctx, PPP_md5())) { typenum = id; if (PPP_DigestUpdate(mdctx, &typenum, 1)) { if (PPP_DigestUpdate(mdctx, secret, secret_len)) { BZERO(secret, sizeof(secret)); if (PPP_DigestUpdate(mdctx, inp, vallen)) { if (PPP_DigestFinal(mdctx, hash, &hashlen)) { eap_chap_response(esp, id, hash, esp->es_client.ea_name, esp->es_client.ea_namelen); PPP_MD_CTX_free(mdctx); break; } } } } } PPP_MD_CTX_free(mdctx); } dbglog("EAP: Invalid MD5 checksum"); eap_send_nak(esp, id, EAPT_SRP); break; #ifdef PPP_WITH_EAPTLS case EAPT_TLS: switch(esp->es_client.ea_state) { case eapListen: if (len < 1) { error("EAP: received EAP-TLS Listen packet with no data"); /* Bogus request; wait for something real. */ return; } GETCHAR(flags, inp); if(flags & EAP_TLS_FLAGS_START){ esp->es_client.ea_using_eaptls = 1; if (explicit_remote){ esp->es_client.ea_peer = strdup(remote_name); esp->es_client.ea_peerlen = strlen(remote_name); } else esp->es_client.ea_peer = NULL; /* Init ssl session */ if(!eaptls_init_ssl_client(esp)) { dbglog("cannot init ssl"); eap_send_nak(esp, id, EAPT_MSCHAPV2); esp->es_client.ea_using_eaptls = 0; break; } ets = esp->es_client.ea_session; eap_tls_response(esp, id); esp->es_client.ea_state = (ets->frag ? eapTlsRecvAck : eapTlsRecv); break; } /* The server has sent a bad start packet. */ eap_send_nak(esp, id, EAPT_MSCHAPV2); break; case eapTlsRecvAck: eap_tls_response(esp, id); esp->es_client.ea_state = (ets->frag ? eapTlsRecvAck : eapTlsRecv); break; case eapTlsRecv: if (len < 1) { error("EAP: discarding EAP-TLS Receive packet with no data"); /* Bogus request; wait for something real. */ return; } eaptls_receive(ets, inp, len); if(ets->frag) { eap_tls_sendack(esp, id); esp->es_client.ea_state = eapTlsRecv; break; } if(ets->alert_recv) { eap_tls_sendack(esp, id); esp->es_client.ea_state = eapTlsRecvFailure; break; } /* Check if TLS handshake is finished */ if(eaptls_is_init_finished(ets)) { #ifdef PPP_WITH_MPPE eaptls_gen_mppe_keys(ets, 1); #endif eaptls_free_session(ets); eap_tls_sendack(esp, id); esp->es_client.ea_state = eapTlsRecvSuccess; break; } eap_tls_response(esp,id); esp->es_client.ea_state = (ets->frag ? eapTlsRecvAck : eapTlsRecv); break; default: eap_send_nak(esp, id, EAPT_MSCHAPV2); esp->es_client.ea_using_eaptls = 0; break; } break; #endif /* PPP_WITH_EAPTLS */ #ifdef PPP_WITH_SRP case EAPT_SRP: if (len < 1) { error("EAP: received empty SRP Request"); /* Bogus request; wait for something real. */ return; } /* Get subtype */ GETCHAR(vallen, inp); len--; switch (vallen) { case EAPSRP_CHALLENGE: tc = NULL; if (esp->es_client.ea_session != NULL) { tc = (struct t_client *)esp->es_client. ea_session; /* * If this is a new challenge, then start * over with a new client session context. * Otherwise, just resend last response. */ if (id != esp->es_client.ea_id) { t_clientclose(tc); esp->es_client.ea_session = NULL; tc = NULL; } } /* No session key just yet */ esp->es_client.ea_skey = NULL; if (tc == NULL) { GETCHAR(vallen, inp); len--; if (vallen >= len) { error("EAP: badly-formed SRP Challenge" " (name)"); /* Ignore badly-formed messages */ return; } BCOPY(inp, rhostname, vallen); rhostname[vallen] = '\0'; INCPTR(vallen, inp); len -= vallen; /* * In case the remote doesn't give us his name, * use configured name. */ if (explicit_remote || (remote_name[0] != '\0' && vallen == 0)) { strlcpy(rhostname, remote_name, sizeof (rhostname)); } if (esp->es_client.ea_peer != NULL) free(esp->es_client.ea_peer); esp->es_client.ea_peer = strdup(rhostname); esp->es_client.ea_peerlen = strlen(rhostname); GETCHAR(vallen, inp); len--; if (vallen >= len) { error("EAP: badly-formed SRP Challenge" " (s)"); /* Ignore badly-formed messages */ return; } sval.data = inp; sval.len = vallen; INCPTR(vallen, inp); len -= vallen; GETCHAR(vallen, inp); len--; if (vallen > len) { error("EAP: badly-formed SRP Challenge" " (g)"); /* Ignore badly-formed messages */ return; } /* If no generator present, then use value 2 */ if (vallen == 0) { gval.data = (u_char *)"\002"; gval.len = 1; } else { gval.data = inp; gval.len = vallen; } INCPTR(vallen, inp); len -= vallen; /* * If no modulus present, then use well-known * value. */ if (len == 0) { Nval.data = (u_char *)wkmodulus; Nval.len = sizeof (wkmodulus); } else { Nval.data = inp; Nval.len = len; } tc = t_clientopen(esp->es_client.ea_name, &Nval, &gval, &sval); if (tc == NULL) { eap_send_nak(esp, id, EAPT_MD5CHAP); break; } esp->es_client.ea_session = (void *)tc; /* Add Challenge ID & type to verifier */ vals[0] = id; vals[1] = EAPT_SRP; t_clientaddexdata(tc, vals, 2); } Ap = t_clientgenexp(tc); eap_srp_response(esp, id, EAPSRP_CKEY, Ap->data, Ap->len); break; case EAPSRP_SKEY: tc = (struct t_client *)esp->es_client.ea_session; if (tc == NULL) { warn("EAP: peer sent Subtype 2 without 1"); eap_send_nak(esp, id, EAPT_MD5CHAP); break; } if (esp->es_client.ea_skey != NULL) { /* * ID number should not change here. Warn * if it does (but otherwise ignore). */ if (id != esp->es_client.ea_id) { warn("EAP: ID changed from %d to %d " "in SRP Subtype 2 rexmit", esp->es_client.ea_id, id); } } else { if (get_srp_secret(esp->es_unit, esp->es_client.ea_name, esp->es_client.ea_peer, secret, 0) == 0) { /* * Can't work with this peer because * the secret is missing. Just give * up. */ eap_send_nak(esp, id, EAPT_MD5CHAP); break; } Bval.data = inp; Bval.len = len; t_clientpasswd(tc, secret); BZERO(secret, sizeof (secret)); esp->es_client.ea_skey = t_clientgetkey(tc, &Bval); if (esp->es_client.ea_skey == NULL) { /* Server is rogue; stop now */ error("EAP: SRP server is rogue"); goto client_failure; } } eap_srpval_response(esp, id, SRPVAL_EBIT, t_clientresponse(tc)); break; case EAPSRP_SVALIDATOR: tc = (struct t_client *)esp->es_client.ea_session; if (tc == NULL || esp->es_client.ea_skey == NULL) { warn("EAP: peer sent Subtype 3 without 1/2"); eap_send_nak(esp, id, EAPT_MD5CHAP); break; } /* * If we're already open, then this ought to be a * duplicate. Otherwise, check that the server is * who we think it is. */ if (esp->es_client.ea_state == eapOpen) { if (id != esp->es_client.ea_id) { warn("EAP: ID changed from %d to %d " "in SRP Subtype 3 rexmit", esp->es_client.ea_id, id); } } else { len -= sizeof (u_int32_t) + SHA_DIGEST_LENGTH; if (len < 0 || t_clientverify(tc, inp + sizeof (u_int32_t)) != 0) { error("EAP: SRP server verification " "failed"); goto client_failure; } GETLONG(esp->es_client.ea_keyflags, inp); /* Save pseudonym if user wants it. */ if (len > 0 && esp->es_usepseudo) { INCPTR(SHA_DIGEST_LENGTH, inp); write_pseudonym(esp, inp, len, id); } } /* * We've verified our peer. We're now mostly done, * except for waiting on the regular EAP Success * message. */ eap_srp_response(esp, id, EAPSRP_ACK, NULL, 0); break; case EAPSRP_LWRECHALLENGE: if (len < 4) { warn("EAP: malformed Lightweight rechallenge"); return; } ctxt = PPP_MD_CTX_new(); if (ctxt) { vals[0] = id; PPP_DigestInit(ctxt, PPP_sha1()); PPP_DigestUpdate(ctxt, vals, 1); PPP_DigestUpdate(ctxt, esp->es_client.ea_skey, SESSION_KEY_LEN); PPP_DigestUpdate(ctxt, inp, len); PPP_DigestUpdate(ctxt, esp->es_client.ea_name, esp->es_client.ea_namelen); PPP_DigestFinal(ctxt, dig, &diglen); PPP_MD_CTX_free(ctxt); eap_srp_response(esp, id, EAPSRP_LWRECHALLENGE, dig, SHA_DIGEST_LENGTH); } break; default: error("EAP: unknown SRP Subtype %d", vallen); eap_send_nak(esp, id, EAPT_MD5CHAP); break; } break; #endif /* PPP_WITH_SRP */ #ifdef PPP_WITH_CHAPMS case EAPT_MSCHAPV2: if (len < 4) { error("EAP: received invalid MSCHAPv2 packet, too short"); return; } unsigned char opcode; GETCHAR(opcode, inp); unsigned char chapid; /* Chapv2-ID */ GETCHAR(chapid, inp); short mssize; GETSHORT(mssize, inp); /* Validate the mssize field */ if (len != mssize) { error("EAP: received invalid MSCHAPv2 packet, invalid length"); return; } len -= 4; /* If MSCHAPv2 digest was not found, NAK the packet */ if (!esp->es_client.digest) { error("EAP MSCHAPv2 not supported"); eap_send_nak(esp, id, EAPT_SRP); return; } switch (opcode) { case CHAP_CHALLENGE: { /* make_response() expects: VLEN + VALUE */ u_char *challenge = inp; unsigned char vsize; GETCHAR(vsize, inp); len -= 1; /* Validate the VALUE field */ if (vsize != MS_CHAP2_PEER_CHAL_LEN || len < MS_CHAP2_PEER_CHAL_LEN) { error("EAP: received invalid MSCHAPv2 packet, invalid value-length: %d", vsize); return; } /* Increment past the VALUE field */ INCPTR(MS_CHAP2_PEER_CHAL_LEN, inp); len -= MS_CHAP2_PEER_CHAL_LEN; /* Extract the hostname */ rhostname[0] = '\0'; if (len > 0) { if (len >= sizeof (rhostname)) { dbglog("EAP: trimming really long peer name down"); len = sizeof(rhostname) - 1; } BCOPY(inp, rhostname, len); rhostname[len] = '\0'; } /* In case the remote doesn't give us his name. */ if (explicit_remote || (remote_name[0] != '\0' && len == 0)) strlcpy(rhostname, remote_name, sizeof(rhostname)); /* Get the secret for authenticating ourselves with the specified host. */ if (!get_secret(esp->es_unit, esp->es_client.ea_name, rhostname, secret, &secret_len, 0)) { dbglog("EAP: no CHAP secret for auth to %q", rhostname); eap_send_nak(esp, id, EAPT_SRP); break; } esp->es_client.ea_namelen = strlen(esp->es_client.ea_name); /* Create the MSCHAPv2 response (and add to cache) */ unsigned char response[MS_CHAP2_RESPONSE_LEN+1]; // VLEN + VALUE esp->es_client.digest->make_response(response, chapid, esp->es_client.ea_name, challenge, secret, secret_len, NULL); eap_chapv2_response(esp, id, chapid, response, esp->es_client.ea_name, esp->es_client.ea_namelen); break; } case CHAP_SUCCESS: { /* Check response for mutual authentication */ u_char status = CHAP_FAILURE; if (esp->es_client.digest->check_success(chapid, inp, len) == 1) { info("Chap authentication succeeded! %.*v", len, inp); status = CHAP_SUCCESS; } eap_send_response(esp, id, EAPT_MSCHAPV2, &status, sizeof(status)); break; } case CHAP_FAILURE: { /* Process the failure string, and log appropriate information */ esp->es_client.digest->handle_failure(inp, len); u_char status = CHAP_FAILURE; eap_send_response(esp, id, EAPT_MSCHAPV2, &status, sizeof(status)); goto client_failure; /* force termination */ } default: error("EAP: received invalid MSCHAPv2 packet, invalid or unsupported opcode: %d", opcode); eap_send_nak(esp, id, EAPT_SRP); } break; #endif /* PPP_WITH_CHAPMS */ #ifdef PPP_WITH_PEAP case EAPT_PEAP: /* Initialize the PEAP context (if not already initialized) */ if (!esp->ea_peap) { rhostname[0] = '\0'; if (explicit_remote || (remote_name[0] != '\0')) { strlcpy(rhostname, remote_name, sizeof (rhostname)); } if (peap_init(&esp->ea_peap, rhostname)) { eap_send_nak(esp, id, EAPT_TLS); break; } } /* Process the PEAP packet */ if (peap_process(esp, id, inp, len)) { eap_send_nak(esp, id, EAPT_TLS); } break; #endif // PPP_WITH_PEAP default: info("EAP: unknown authentication type %d; Naking", typenum); eap_send_nak(esp, id, EAPT_SRP); break; } if (esp->es_client.ea_timeout > 0) { UNTIMEOUT(eap_client_timeout, (void *)esp); TIMEOUT(eap_client_timeout, (void *)esp, esp->es_client.ea_timeout); } return; client_failure: esp->es_client.ea_state = eapBadAuth; if (esp->es_client.ea_timeout > 0) { UNTIMEOUT(eap_client_timeout, (void *)esp); } esp->es_client.ea_session = NULL; #ifdef PPP_WITH_SRP t_clientclose(tc); auth_withpeer_fail(esp->es_unit, PPP_EAP); #endif /* PPP_WITH_SRP */ } /* * eap_response - Receive EAP Response message (server mode). */ static void eap_response(eap_state *esp, u_char *inp, int id, int len) { u_char typenum; u_char vallen; int secret_len; char secret[MAXSECRETLEN]; char rhostname[256]; PPP_MD_CTX *mdctx; u_char hash[MD5_DIGEST_LENGTH]; int hashlen = MD5_DIGEST_LENGTH; #ifdef PPP_WITH_SRP struct t_server *ts; struct t_num A; PPP_MD_CTX *ctxt; u_char dig[SHA_DIGEST_LENGTH]; int diglen = sizeof(dig); #endif /* PPP_WITH_SRP */ #ifdef PPP_WITH_EAPTLS struct eaptls_session *ets; u_char flags; #endif /* PPP_WITH_EAPTLS */ #ifdef PPP_WITH_CHAPMS u_char opcode; chap_verify_hook_fn *chap_verifier; char response_message[256]; #endif /* PPP_WITH_CHAPMS */ /* * Ignore responses if we're not open */ if (esp->es_server.ea_state <= eapClosed) return; if (esp->es_server.ea_id != id) { dbglog("EAP: discarding Response %d; expected ID %d", id, esp->es_server.ea_id); return; } esp->es_server.ea_responses++; if (len <= 0) { error("EAP: empty Response message discarded"); return; } GETCHAR(typenum, inp); len--; switch (typenum) { case EAPT_IDENTITY: if (esp->es_server.ea_state != eapIdentify) { dbglog("EAP discarding unwanted Identify \"%.q\"", len, inp); break; } info("EAP: unauthenticated peer name \"%.*q\"", len, inp); if (esp->es_server.ea_peer != NULL && esp->es_server.ea_peer != remote_name) free(esp->es_server.ea_peer); esp->es_server.ea_peer = malloc(len + 1); if (esp->es_server.ea_peer == NULL) { esp->es_server.ea_peerlen = 0; eap_figure_next_state(esp, 1); break; } BCOPY(inp, esp->es_server.ea_peer, len); esp->es_server.ea_peer[len] = '\0'; esp->es_server.ea_peerlen = len; eap_figure_next_state(esp, 0); break; #ifdef PPP_WITH_EAPTLS case EAPT_TLS: switch(esp->es_server.ea_state) { case eapTlsRecv: ets = (struct eaptls_session *) esp->es_server.ea_session; eap_figure_next_state(esp, eaptls_receive(esp->es_server.ea_session, inp, len)); if(ets->alert_recv) { eap_send_failure(esp); break; } break; case eapTlsRecvAck: if(len > 1) { dbglog("EAP-TLS ACK with extra data"); } eap_figure_next_state(esp, 0); break; case eapTlsRecvClient: /* Receive authentication response from client */ if (len > 0) { GETCHAR(flags, inp); if(len == 1 && !flags) { /* Ack = ok */ #ifdef PPP_WITH_MPPE eaptls_gen_mppe_keys( esp->es_server.ea_session, 0 ); #endif eap_send_success(esp); } else { /* failure */ warn("Server authentication failed"); eap_send_failure(esp); } } else warn("Bogus EAP-TLS packet received from client"); eaptls_free_session(esp->es_server.ea_session); break; case eapTlsRecvAlertAck: eap_send_failure(esp); break; default: eap_figure_next_state(esp, 1); break; } break; #endif /* PPP_WITH_EAPTLS */ case EAPT_NOTIFICATION: dbglog("EAP unexpected Notification; response discarded"); break; case EAPT_NAK: if (len < 1) { info("EAP: Nak Response with no suggested protocol"); eap_figure_next_state(esp, 1); break; } GETCHAR(vallen, inp); len--; if (!explicit_remote && esp->es_server.ea_state == eapIdentify){ /* Peer cannot Nak Identify Request */ eap_figure_next_state(esp, 1); break; } switch (vallen) { case EAPT_SRP: /* Run through SRP validator selection again. */ esp->es_server.ea_state = eapIdentify; eap_figure_next_state(esp, 0); break; case EAPT_MD5CHAP: esp->es_server.ea_state = eapMD5Chall; break; #ifdef PPP_WITH_EAPTLS /* Send EAP-TLS start packet */ case EAPT_TLS: esp->es_server.ea_state = eapTlsStart; break; #endif /* PPP_WITH_EAPTLS */ #ifdef PPP_WITH_CHAPMS case EAPT_MSCHAPV2: info("EAP: peer proposes MSCHAPv2"); /* If MSCHAPv2 digest was not found, NAK the packet */ if (!esp->es_server.digest) { error("EAP MSCHAPv2 not supported"); eap_send_nak(esp, id, EAPT_SRP); break; } esp->es_server.ea_state = eapMSCHAPv2Chall; break; #endif /* PPP_WITH_CHAPMS */ default: dbglog("EAP: peer requesting unknown Type %d", vallen); switch (esp->es_server.ea_state) { case eapSRP1: case eapSRP2: case eapSRP3: esp->es_server.ea_state = eapMD5Chall; break; case eapMD5Chall: case eapSRP4: esp->es_server.ea_state = eapIdentify; eap_figure_next_state(esp, 0); break; default: break; } break; } break; case EAPT_MD5CHAP: if (esp->es_server.ea_state != eapMD5Chall) { error("EAP: unexpected MD5-Response"); eap_figure_next_state(esp, 1); break; } if (len < 1) { error("EAP: received MD5-Response with no data"); eap_figure_next_state(esp, 1); break; } GETCHAR(vallen, inp); len--; if (vallen != 16 || vallen > len) { error("EAP: MD5-Response with bad length %d", vallen); eap_figure_next_state(esp, 1); break; } /* Not so likely to happen. */ if (len - vallen >= sizeof (rhostname)) { dbglog("EAP: trimming really long peer name down"); BCOPY(inp + vallen, rhostname, sizeof (rhostname) - 1); rhostname[sizeof (rhostname) - 1] = '\0'; } else { BCOPY(inp + vallen, rhostname, len - vallen); rhostname[len - vallen] = '\0'; } /* In case the remote doesn't give us his name. */ if (explicit_remote || (remote_name[0] != '\0' && vallen == len)) strlcpy(rhostname, remote_name, sizeof (rhostname)); /* * Get the secret for authenticating the specified * host. */ if (!get_secret(esp->es_unit, rhostname, esp->es_server.ea_name, secret, &secret_len, 1)) { dbglog("EAP: no MD5 secret for auth of %q", rhostname); eap_send_failure(esp); break; } mdctx = PPP_MD_CTX_new(); if (mdctx != NULL) { if (PPP_DigestInit(mdctx, PPP_md5())) { if (PPP_DigestUpdate(mdctx, &esp->es_server.ea_id, 1)) { if (PPP_DigestUpdate(mdctx, &secret, secret_len)) { BZERO(secret, sizeof(secret)); if (PPP_DigestUpdate(mdctx, esp->es_challenge, esp->es_challen)) { if (PPP_DigestFinal(mdctx, hash, &hashlen)) { if (BCMP(hash, inp, MD5_DIGEST_LENGTH) == 0) { esp->es_server.ea_type = EAPT_MD5CHAP; eap_send_success(esp); eap_figure_next_state(esp, 0); if (esp->es_rechallenge != 0) { TIMEOUT(eap_rechallenge, esp, esp->es_rechallenge); } PPP_MD_CTX_free(mdctx); break; } } } } } } PPP_MD_CTX_free(mdctx); } eap_send_failure(esp); break; #ifdef PPP_WITH_CHAPMS case EAPT_MSCHAPV2: if (len < 1) { error("EAP: received MSCHAPv2 with no data"); eap_figure_next_state(esp, 1); break; } GETCHAR(opcode, inp); len--; switch (opcode) { case CHAP_RESPONSE: if (esp->es_server.ea_state != eapMSCHAPv2Chall) { error("EAP: unexpected MSCHAPv2-Response"); eap_figure_next_state(esp, 1); break; } /* skip MS ID + len */ INCPTR(3, inp); GETCHAR(vallen, inp); len -= 4; if (vallen != MS_CHAP2_RESPONSE_LEN || vallen > len) { error("EAP: Invalid MSCHAPv2-Response " "length %d", vallen); eap_figure_next_state(esp, 1); break; } /* Not so likely to happen. */ if (len - vallen >= sizeof (rhostname)) { dbglog("EAP: trimming really long peer name down"); BCOPY(inp + vallen, rhostname, sizeof (rhostname) - 1); rhostname[sizeof (rhostname) - 1] = '\0'; } else { BCOPY(inp + vallen, rhostname, len - vallen); rhostname[len - vallen] = '\0'; } /* In case the remote doesn't give us his name. */ if (explicit_remote || (remote_name[0] != '\0' && vallen == len)) strlcpy(rhostname, remote_name, sizeof (rhostname)); /* strip the MS domain name */ if (chapms_strip_domain && strrchr(rhostname, '\\')) { char tmp[MAXNAMELEN+1]; strcpy(tmp, strrchr(rhostname, '\\') + 1); strlcpy(rhostname, tmp, sizeof(rhostname)); } if (chap_verify_hook) chap_verifier = chap_verify_hook; else chap_verifier = eap_chap_verify_response; esp->es_server.ea_id += 1; if ((*chap_verifier)(rhostname, esp->es_server.ea_name, id, esp->es_server.digest, esp->es_challenge, inp - 1, response_message, sizeof(response_message))) { info("EAP: MSCHAPv2 success for peer %q", rhostname); esp->es_server.ea_type = EAPT_MSCHAPV2; eap_chapms2_send_request(esp, esp->es_server.ea_id, CHAP_SUCCESS, esp->es_server.ea_id, response_message, strlen(response_message)); eap_figure_next_state(esp, 0); if (esp->es_rechallenge != 0) TIMEOUT(eap_rechallenge, esp, esp->es_rechallenge); } else { warn("EAP: MSCHAPv2 failure for peer %q", rhostname); eap_chapms2_send_request(esp, esp->es_server.ea_id, CHAP_FAILURE, esp->es_server.ea_id, response_message, strlen(response_message)); } break; case CHAP_SUCCESS: info("EAP: MSCHAPv2 success confirmed"); break; case CHAP_FAILURE: info("EAP: MSCHAPv2 failure confirmed"); break; default: error("EAP: Unhandled MSCHAPv2 opcode %d", opcode); eap_send_nak(esp, id, EAPT_SRP); } break; #endif /* PPP_WITH_CHAPMS */ #ifdef PPP_WITH_SRP case EAPT_SRP: if (len < 1) { error("EAP: empty SRP Response"); eap_figure_next_state(esp, 1); break; } GETCHAR(typenum, inp); len--; switch (typenum) { case EAPSRP_CKEY: if (esp->es_server.ea_state != eapSRP1) { error("EAP: unexpected SRP Subtype 1 Response"); eap_figure_next_state(esp, 1); break; } A.data = inp; A.len = len; ts = (struct t_server *)esp->es_server.ea_session; assert(ts != NULL); esp->es_server.ea_skey = t_servergetkey(ts, &A); if (esp->es_server.ea_skey == NULL) { /* Client's A value is bogus; terminate now */ error("EAP: bogus A value from client"); eap_send_failure(esp); } else { eap_figure_next_state(esp, 0); } break; case EAPSRP_CVALIDATOR: if (esp->es_server.ea_state != eapSRP2) { error("EAP: unexpected SRP Subtype 2 Response"); eap_figure_next_state(esp, 1); break; } if (len < sizeof (u_int32_t) + SHA_DIGEST_LENGTH) { error("EAP: M1 length %d < %d", len, sizeof (u_int32_t) + SHA_DIGEST_LENGTH); eap_figure_next_state(esp, 1); break; } GETLONG(esp->es_server.ea_keyflags, inp); ts = (struct t_server *)esp->es_server.ea_session; assert(ts != NULL); if (t_serververify(ts, inp)) { info("EAP: unable to validate client identity"); eap_send_failure(esp); break; } eap_figure_next_state(esp, 0); break; case EAPSRP_ACK: if (esp->es_server.ea_state != eapSRP3) { error("EAP: unexpected SRP Subtype 3 Response"); eap_send_failure(esp); break; } esp->es_server.ea_type = EAPT_SRP; eap_send_success(esp); eap_figure_next_state(esp, 0); if (esp->es_rechallenge != 0) TIMEOUT(eap_rechallenge, esp, esp->es_rechallenge); if (esp->es_lwrechallenge != 0) TIMEOUT(srp_lwrechallenge, esp, esp->es_lwrechallenge); break; case EAPSRP_LWRECHALLENGE: if (esp->es_server.ea_state != eapSRP4) { info("EAP: unexpected SRP Subtype 4 Response"); return; } if (len != SHA_DIGEST_LENGTH) { error("EAP: bad Lightweight rechallenge " "response"); return; } ctxt = PPP_MD_CTX_new(); if (ctxt) { vallen = id; PPP_DigestInit(ctxt, PPP_sha1()); PPP_DigestUpdate(ctxt, &vallen, 1); PPP_DigestUpdate(ctxt, esp->es_server.ea_skey, SESSION_KEY_LEN); PPP_DigestUpdate(ctxt, esp->es_challenge, esp->es_challen); PPP_DigestUpdate(ctxt, esp->es_server.ea_peer, esp->es_server.ea_peerlen); PPP_DigestFinal(ctxt, dig, &diglen); PPP_MD_CTX_free(ctxt); if (BCMP(dig, inp, SHA_DIGEST_LENGTH) != 0) { error("EAP: failed Lightweight rechallenge"); eap_send_failure(esp); break; } esp->es_server.ea_state = eapOpen; if (esp->es_lwrechallenge != 0) TIMEOUT(srp_lwrechallenge, esp, esp->es_lwrechallenge); } break; } break; #endif /* PPP_WITH_SRP */ default: /* This can't happen. */ error("EAP: unknown Response type %d; ignored", typenum); return; } if (esp->es_server.ea_timeout > 0) { UNTIMEOUT(eap_server_timeout, (void *)esp); } if (esp->es_server.ea_state != eapBadAuth && esp->es_server.ea_state != eapOpen) { esp->es_server.ea_id++; eap_send_request(esp); } } /* * eap_success - Receive EAP Success message (client mode). */ static void eap_success(eap_state *esp, u_char *inp, int id, int len) { if (esp->es_client.ea_state != eapOpen && !eap_client_active(esp) #ifdef PPP_WITH_EAPTLS && esp->es_client.ea_state != eapTlsRecvSuccess #endif /* PPP_WITH_EAPTLS */ ) { dbglog("EAP unexpected success message in state %s (%d)", eap_state_name(esp->es_client.ea_state), esp->es_client.ea_state); return; } #ifdef PPP_WITH_EAPTLS if(esp->es_client.ea_using_eaptls && esp->es_client.ea_state != eapTlsRecvSuccess) { dbglog("EAP-TLS unexpected success message in state %s (%d)", eap_state_name(esp->es_client.ea_state), esp->es_client.ea_state); return; } #endif /* PPP_WITH_EAPTLS */ if (esp->es_client.ea_timeout > 0) { UNTIMEOUT(eap_client_timeout, (void *)esp); } if (len > 0) { /* This is odd. The spec doesn't allow for this. */ PRINTMSG(inp, len); } #ifdef PPP_WITH_PEAP peap_finish(&esp->ea_peap); #endif esp->es_client.ea_state = eapOpen; auth_withpeer_success(esp->es_unit, PPP_EAP, 0); } /* * eap_failure - Receive EAP Failure message (client mode). */ static void eap_failure(eap_state *esp, u_char *inp, int id, int len) { /* * Ignore failure messages if we're not open */ if (esp->es_client.ea_state <= eapClosed) return; if (!eap_client_active(esp)) { dbglog("EAP unexpected failure message in state %s (%d)", eap_state_name(esp->es_client.ea_state), esp->es_client.ea_state); } if (esp->es_client.ea_timeout > 0) { UNTIMEOUT(eap_client_timeout, (void *)esp); } if (len > 0) { /* This is odd. The spec doesn't allow for this. */ PRINTMSG(inp, len); } esp->es_client.ea_state = eapBadAuth; error("EAP: peer reports authentication failure"); #ifdef PPP_WITH_PEAP peap_finish(&esp->ea_peap); #endif auth_withpeer_fail(esp->es_unit, PPP_EAP); } /* * eap_input - Handle received EAP message. */ static void eap_input(int unit, u_char *inp, int inlen) { eap_state *esp = &eap_states[unit]; u_char code, id; int len; /* * Parse header (code, id and length). If packet too short, * drop it. */ if (inlen < EAP_HEADERLEN) { error("EAP: packet too short: %d < %d", inlen, EAP_HEADERLEN); return; } GETCHAR(code, inp); GETCHAR(id, inp); GETSHORT(len, inp); if (len < EAP_HEADERLEN || len > inlen) { error("EAP: packet has illegal length field %d (%d..%d)", len, EAP_HEADERLEN, inlen); return; } len -= EAP_HEADERLEN; /* Dispatch based on message code */ switch (code) { case EAP_REQUEST: eap_request(esp, inp, id, len); break; case EAP_RESPONSE: eap_response(esp, inp, id, len); break; case EAP_SUCCESS: eap_success(esp, inp, id, len); break; case EAP_FAILURE: eap_failure(esp, inp, id, len); break; default: /* XXX Need code reject */ /* Note: it's not legal to send EAP Nak here. */ warn("EAP: unknown code %d received", code); break; } } /* * eap_printpkt - print the contents of an EAP packet. */ static char *eap_codenames[] = { "Request", "Response", "Success", "Failure" }; static char *eap_typenames[] = { "Identity", "Notification", "Nak", "MD5-Challenge", "OTP", "Generic-Token", NULL, NULL, "RSA", "DSS", "KEA", "KEA-Validate", "TLS", "Defender", "Windows 2000", "Arcot", "Cisco", "Nokia", "SRP", NULL, "TTLS", "RAS", "AKA", "3COM", "PEAP", "MSCHAPv2" }; static int eap_printpkt(u_char *inp, int inlen, void (*printer) (void *, char *, ...), void *arg) { int code, id, len, rtype, vallen; u_char *pstart; u_int32_t uval; #ifdef PPP_WITH_EAPTLS u_char flags; #endif /* PPP_WITH_EAPTLS */ #ifdef PPP_WITH_CHAPMS u_char opcode; #endif /* PPP_WITH_CHAPMS */ if (inlen < EAP_HEADERLEN) return (0); pstart = inp; GETCHAR(code, inp); GETCHAR(id, inp); GETSHORT(len, inp); if (len < EAP_HEADERLEN || len > inlen) return (0); if (code >= 1 && code <= sizeof(eap_codenames) / sizeof(char *)) printer(arg, " %s", eap_codenames[code-1]); else printer(arg, " code=0x%x", code); printer(arg, " id=0x%x", id); len -= EAP_HEADERLEN; switch (code) { case EAP_REQUEST: if (len < 1) { printer(arg, " "); break; } GETCHAR(rtype, inp); len--; if (rtype >= 1 && rtype <= sizeof (eap_typenames) / sizeof (char *)) printer(arg, " %s", eap_typenames[rtype-1]); else printer(arg, " type=0x%x", rtype); switch (rtype) { case EAPT_IDENTITY: case EAPT_NOTIFICATION: if (len > 0) { printer(arg, " "); INCPTR(len, inp); len = 0; } else { printer(arg, " "); } break; case EAPT_MD5CHAP: if (len <= 0) break; GETCHAR(vallen, inp); len--; if (vallen > len) goto truncated; printer(arg, " ", vallen, inp); INCPTR(vallen, inp); len -= vallen; if (len > 0) { printer(arg, " "); INCPTR(len, inp); len = 0; } else { printer(arg, " "); } break; #ifdef PPP_WITH_CHAPMS case EAPT_MSCHAPV2: if (len <= 0) break; GETCHAR(opcode, inp); len--; switch (opcode) { case CHAP_CHALLENGE: INCPTR(3, inp); len -= 3; GETCHAR(vallen, inp); len--; if (vallen > len) goto truncated; len -= vallen; printer(arg, " Challenge <"); for (; vallen > 0; --vallen) { u_char val; GETCHAR(val, inp); printer(arg, "%.2x", val); } printer(arg, ">"); if (len > 0) { printer(arg, ", "); INCPTR(len, inp); len = 0; } else { printer(arg, ", "); } break; case CHAP_SUCCESS: INCPTR(3, inp); len -= 3; printer(arg, " Success "); break; case CHAP_FAILURE: INCPTR(3, inp); len -= 3; printer(arg, " Failure "); break; default: INCPTR(3, inp); len -= 3; printer(arg, " opcode=0x%x <%.*B>", opcode, len, inp); break; } break; #endif /* PPP_WITH_CHAPMS */ #ifdef PPP_WITH_EAPTLS case EAPT_TLS: if (len < 1) break; GETCHAR(flags, inp); len--; if(flags == 0 && len == 0){ printer(arg, " Ack"); break; } printer(arg, flags & EAP_TLS_FLAGS_LI ? " L":" -"); printer(arg, flags & EAP_TLS_FLAGS_MF ? "M":"-"); printer(arg, flags & EAP_TLS_FLAGS_START ? "S":"- "); break; #endif /* PPP_WITH_EAPTLS */ #ifdef PPP_WITH_SRP case EAPT_SRP: if (len < 3) goto truncated; GETCHAR(vallen, inp); len--; printer(arg, "-%d", vallen); switch (vallen) { case EAPSRP_CHALLENGE: GETCHAR(vallen, inp); len--; if (vallen >= len) goto truncated; if (vallen > 0) { printer(arg, " "); } else { printer(arg, " "); } INCPTR(vallen, inp); len -= vallen; GETCHAR(vallen, inp); len--; if (vallen >= len) goto truncated; printer(arg, " ", vallen, inp); INCPTR(vallen, inp); len -= vallen; GETCHAR(vallen, inp); len--; if (vallen > len) goto truncated; if (vallen == 0) { printer(arg, " "); } else { printer(arg, " ", vallen, inp); } INCPTR(vallen, inp); len -= vallen; if (len == 0) { printer(arg, " "); } else { printer(arg, " ", len, inp); INCPTR(len, inp); len = 0; } break; case EAPSRP_SKEY: printer(arg, " ", len, inp); INCPTR(len, inp); len = 0; break; case EAPSRP_SVALIDATOR: if (len < sizeof (u_int32_t)) break; GETLONG(uval, inp); len -= sizeof (u_int32_t); if (uval & SRPVAL_EBIT) { printer(arg, " E"); uval &= ~SRPVAL_EBIT; } if (uval != 0) { printer(arg, " f<%X>", uval); } if ((vallen = len) > SHA_DIGEST_LENGTH) vallen = SHA_DIGEST_LENGTH; printer(arg, " ", len, inp, len < SHA_DIGEST_LENGTH ? "?" : ""); INCPTR(vallen, inp); len -= vallen; if (len > 0) { printer(arg, " ", len, inp); INCPTR(len, inp); len = 0; } break; case EAPSRP_LWRECHALLENGE: printer(arg, " ", len, inp); INCPTR(len, inp); len = 0; break; } break; #endif /* PPP_WITH_SRP */ } break; case EAP_RESPONSE: if (len < 1) break; GETCHAR(rtype, inp); len--; if (rtype >= 1 && rtype <= sizeof (eap_typenames) / sizeof (char *)) printer(arg, " %s", eap_typenames[rtype-1]); else printer(arg, " type=0x%x", rtype); switch (rtype) { case EAPT_IDENTITY: if (len > 0) { printer(arg, " "); INCPTR(len, inp); len = 0; } break; #ifdef PPP_WITH_EAPTLS case EAPT_TLS: if (len < 1) break; GETCHAR(flags, inp); len--; if(flags == 0 && len == 0){ printer(arg, " Ack"); break; } printer(arg, flags & EAP_TLS_FLAGS_LI ? " L":" -"); printer(arg, flags & EAP_TLS_FLAGS_MF ? "M":"-"); printer(arg, flags & EAP_TLS_FLAGS_START ? "S":"- "); break; #endif /* PPP_WITH_EAPTLS */ case EAPT_NAK: if (len <= 0) { printer(arg, " "); break; } GETCHAR(rtype, inp); len--; printer(arg, " = 1 && rtype <= sizeof (eap_typenames) / sizeof (char *)) printer(arg, " (%s)", eap_typenames[rtype-1]); printer(arg, ">"); break; case EAPT_MD5CHAP: if (len <= 0) { printer(arg, " "); break; } GETCHAR(vallen, inp); len--; if (vallen > len) goto truncated; printer(arg, " ", vallen, inp); INCPTR(vallen, inp); len -= vallen; if (len > 0) { printer(arg, " "); INCPTR(len, inp); len = 0; } else { printer(arg, " "); } break; #ifdef PPP_WITH_CHAPMS case EAPT_MSCHAPV2: if (len <= 0) break; GETCHAR(opcode, inp); len--; switch (opcode) { case CHAP_RESPONSE: INCPTR(3, inp); len -= 3; GETCHAR(vallen, inp); len--; if (vallen > len) goto truncated; len -= vallen; printer(arg, " Response <"); for (; vallen > 0; --vallen) { u_char val; GETCHAR(val, inp); printer(arg, "%.2x", val); } printer(arg, ">"); if (len > 0) { printer(arg, ", "); INCPTR(len, inp); len = 0; } else { printer(arg, ", "); } break; case CHAP_SUCCESS: printer(arg, " Success"); break; case CHAP_FAILURE: printer(arg, " Failure"); break; default: printer(arg, " opcode=0x%x <%.*B>", opcode, len, inp); break; } break; #endif /* PPP_WITH_CHAPMS */ #ifdef PPP_WITH_SRP case EAPT_SRP: if (len < 1) goto truncated; GETCHAR(vallen, inp); len--; printer(arg, "-%d", vallen); switch (vallen) { case EAPSRP_CKEY: printer(arg, " ", len, inp); INCPTR(len, inp); len = 0; break; case EAPSRP_CVALIDATOR: if (len < sizeof (u_int32_t)) break; GETLONG(uval, inp); len -= sizeof (u_int32_t); if (uval & SRPVAL_EBIT) { printer(arg, " E"); uval &= ~SRPVAL_EBIT; } if (uval != 0) { printer(arg, " f<%X>", uval); } printer(arg, " ", len, inp, len == SHA_DIGEST_LENGTH ? "" : "?"); INCPTR(len, inp); len = 0; break; case EAPSRP_ACK: break; case EAPSRP_LWRECHALLENGE: printer(arg, " ", len, inp, len == SHA_DIGEST_LENGTH ? "" : "?"); if ((vallen = len) > SHA_DIGEST_LENGTH) vallen = SHA_DIGEST_LENGTH; INCPTR(vallen, inp); len -= vallen; break; } break; #endif /* PPP_WITH_SRP */ } break; case EAP_SUCCESS: /* No payload expected for these! */ case EAP_FAILURE: break; truncated: printer(arg, " "); break; } if (len > 8) printer(arg, "%8B...", inp); else if (len > 0) printer(arg, "%.*B", len, inp); INCPTR(len, inp); return (inp - pstart); } ppp-2.5.0/pppd/ecp.c0000644000175000017500000001164514353435407011133 00000000000000/* * ecp.c - PPP Encryption Control Protocol. * * Copyright (c) 2002 Google, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The name(s) of the authors of this software must not be used to * endorse or promote products derived from this software without * prior written permission. * * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * Derived from ccp.c, which is: * * Copyright (c) 1994-2002 Paul Mackerras. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. The name(s) of the authors of this software must not be used to * endorse or promote products derived from this software without * prior written permission. * * 3. Redistributions of any form whatsoever must retain the following * acknowledgment: * "This product includes software developed by Paul Mackerras * ". * * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include "pppd-private.h" #include "options.h" #include "fsm.h" #include "ecp.h" static struct option ecp_option_list[] = { { "noecp", o_bool, &ecp_protent.enabled_flag, "Disable ECP negotiation" }, { "-ecp", o_bool, &ecp_protent.enabled_flag, "Disable ECP negotiation", OPT_ALIAS }, { NULL } }; /* * Protocol entry points from main code. */ static void ecp_init (int unit); /* static void ecp_open (int unit); static void ecp_close (int unit, char *); static void ecp_lowerup (int unit); static void ecp_lowerdown (int); static void ecp_input (int unit, u_char *pkt, int len); static void ecp_protrej (int unit); */ static int ecp_printpkt (u_char *pkt, int len, void (*printer)(void *, char *, ...), void *arg); /* static void ecp_datainput (int unit, u_char *pkt, int len); */ struct protent ecp_protent = { PPP_ECP, ecp_init, NULL, /* ecp_input, */ NULL, /* ecp_protrej, */ NULL, /* ecp_lowerup, */ NULL, /* ecp_lowerdown, */ NULL, /* ecp_open, */ NULL, /* ecp_close, */ ecp_printpkt, NULL, /* ecp_datainput, */ 0, "ECP", "Encrypted", ecp_option_list, NULL, NULL, NULL }; fsm ecp_fsm[NUM_PPP]; ecp_options ecp_wantoptions[NUM_PPP]; /* what to request the peer to use */ ecp_options ecp_gotoptions[NUM_PPP]; /* what the peer agreed to do */ ecp_options ecp_allowoptions[NUM_PPP]; /* what we'll agree to do */ ecp_options ecp_hisoptions[NUM_PPP]; /* what we agreed to do */ static fsm_callbacks ecp_callbacks = { NULL, /* ecp_resetci, */ NULL, /* ecp_cilen, */ NULL, /* ecp_addci, */ NULL, /* ecp_ackci, */ NULL, /* ecp_nakci, */ NULL, /* ecp_rejci, */ NULL, /* ecp_reqci, */ NULL, /* ecp_up, */ NULL, /* ecp_down, */ NULL, NULL, NULL, NULL, NULL, /* ecp_extcode, */ "ECP" }; /* * ecp_init - initialize ECP. */ static void ecp_init(int unit) { fsm *f = &ecp_fsm[unit]; f->unit = unit; f->protocol = PPP_ECP; f->callbacks = &ecp_callbacks; fsm_init(f); memset(&ecp_wantoptions[unit], 0, sizeof(ecp_options)); memset(&ecp_gotoptions[unit], 0, sizeof(ecp_options)); memset(&ecp_allowoptions[unit], 0, sizeof(ecp_options)); memset(&ecp_hisoptions[unit], 0, sizeof(ecp_options)); } static int ecp_printpkt(u_char *p, int plen, void (*printer)(void *, char *, ...), void *arg) { return 0; } ppp-2.5.0/pppd/fsm.c0000644000175000017500000004235414353435407011152 00000000000000/* * fsm.c - {Link, IP} Control Protocol Finite State Machine. * * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The name "Carnegie Mellon University" must not be used to * endorse or promote products derived from this software without * prior written permission. For permission or any legal * details, please contact * Office of Technology Transfer * Carnegie Mellon University * 5000 Forbes Avenue * Pittsburgh, PA 15213-3890 * (412) 268-4387, fax: (412) 268-7395 * tech-transfer@andrew.cmu.edu * * 4. Redistributions of any form whatsoever must retain the following * acknowledgment: * "This product includes software developed by Computing Services * at Carnegie Mellon University (http://www.cmu.edu/computing/)." * * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif /* * TODO: * Randomize fsm id on link/init. * Deal with variable outgoing MTU. */ #include #include #include #include "pppd-private.h" #include "fsm.h" static void fsm_timeout (void *); static void fsm_rconfreq (fsm *, int, u_char *, int); static void fsm_rconfack (fsm *, int, u_char *, int); static void fsm_rconfnakrej (fsm *, int, int, u_char *, int); static void fsm_rtermreq (fsm *, int, u_char *, int); static void fsm_rtermack (fsm *); static void fsm_rcoderej (fsm *, u_char *, int); static void fsm_sconfreq (fsm *, int); #define PROTO_NAME(f) ((f)->callbacks->proto_name) int peer_mru[NUM_PPP]; /* * fsm_init - Initialize fsm. * * Initialize fsm state. */ void fsm_init(fsm *f) { f->state = INITIAL; f->flags = 0; f->id = 0; /* XXX Start with random id? */ f->timeouttime = DEFTIMEOUT; f->maxconfreqtransmits = DEFMAXCONFREQS; f->maxtermtransmits = DEFMAXTERMREQS; f->maxnakloops = DEFMAXNAKLOOPS; f->term_reason_len = 0; } /* * fsm_lowerup - The lower layer is up. */ void fsm_lowerup(fsm *f) { switch( f->state ){ case INITIAL: f->state = CLOSED; break; case STARTING: if( f->flags & OPT_SILENT ) f->state = STOPPED; else { /* Send an initial configure-request */ fsm_sconfreq(f, 0); f->state = REQSENT; } break; default: FSMDEBUG(("%s: Up event in state %d!", PROTO_NAME(f), f->state)); } } /* * fsm_lowerdown - The lower layer is down. * * Cancel all timeouts and inform upper layers. */ void fsm_lowerdown(fsm *f) { switch( f->state ){ case CLOSED: f->state = INITIAL; break; case STOPPED: f->state = STARTING; if( f->callbacks->starting ) (*f->callbacks->starting)(f); break; case CLOSING: f->state = INITIAL; UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */ break; case STOPPING: case REQSENT: case ACKRCVD: case ACKSENT: f->state = STARTING; UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */ break; case OPENED: if( f->callbacks->down ) (*f->callbacks->down)(f); f->state = STARTING; break; default: FSMDEBUG(("%s: Down event in state %d!", PROTO_NAME(f), f->state)); } } /* * fsm_open - Link is allowed to come up. */ void fsm_open(fsm *f) { switch( f->state ){ case INITIAL: f->state = STARTING; if( f->callbacks->starting ) (*f->callbacks->starting)(f); break; case CLOSED: if( f->flags & OPT_SILENT ) f->state = STOPPED; else { /* Send an initial configure-request */ fsm_sconfreq(f, 0); f->state = REQSENT; } break; case CLOSING: f->state = STOPPING; /* fall through */ case STOPPED: case OPENED: if( f->flags & OPT_RESTART ){ fsm_lowerdown(f); fsm_lowerup(f); } break; } } /* * terminate_layer - Start process of shutting down the FSM * * Cancel any timeout running, notify upper layers we're done, and * send a terminate-request message as configured. */ static void terminate_layer(fsm *f, int nextstate) { if( f->state != OPENED ) UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */ else if( f->callbacks->down ) (*f->callbacks->down)(f); /* Inform upper layers we're down */ /* Init restart counter and send Terminate-Request */ f->retransmits = f->maxtermtransmits; fsm_sdata(f, TERMREQ, f->reqid = ++f->id, (u_char *) f->term_reason, f->term_reason_len); if (f->retransmits == 0) { /* * User asked for no terminate requests at all; just close it. * We've already fired off one Terminate-Request just to be nice * to the peer, but we're not going to wait for a reply. */ f->state = nextstate == CLOSING ? CLOSED : STOPPED; if( f->callbacks->finished ) (*f->callbacks->finished)(f); return; } TIMEOUT(fsm_timeout, f, f->timeouttime); --f->retransmits; f->state = nextstate; } /* * fsm_close - Start closing connection. * * Cancel timeouts and either initiate close or possibly go directly to * the CLOSED state. */ void fsm_close(fsm *f, char *reason) { f->term_reason = reason; f->term_reason_len = (reason == NULL? 0: strlen(reason)); switch( f->state ){ case STARTING: f->state = INITIAL; break; case STOPPED: f->state = CLOSED; break; case STOPPING: f->state = CLOSING; break; case REQSENT: case ACKRCVD: case ACKSENT: case OPENED: terminate_layer(f, CLOSING); break; } } /* * fsm_timeout - Timeout expired. */ static void fsm_timeout(void *arg) { fsm *f = (fsm *) arg; switch (f->state) { case CLOSING: case STOPPING: if( f->retransmits <= 0 ){ /* * We've waited for an ack long enough. Peer probably heard us. */ f->state = (f->state == CLOSING)? CLOSED: STOPPED; if( f->callbacks->finished ) (*f->callbacks->finished)(f); } else { /* Send Terminate-Request */ fsm_sdata(f, TERMREQ, f->reqid = ++f->id, (u_char *) f->term_reason, f->term_reason_len); TIMEOUT(fsm_timeout, f, f->timeouttime); --f->retransmits; } break; case REQSENT: case ACKRCVD: case ACKSENT: if (f->retransmits <= 0) { warn("%s: timeout sending Config-Requests\n", PROTO_NAME(f)); f->state = STOPPED; if( (f->flags & OPT_PASSIVE) == 0 && f->callbacks->finished ) (*f->callbacks->finished)(f); } else { /* Retransmit the configure-request */ if (f->callbacks->retransmit) (*f->callbacks->retransmit)(f); fsm_sconfreq(f, 1); /* Re-send Configure-Request */ if( f->state == ACKRCVD ) f->state = REQSENT; } break; default: FSMDEBUG(("%s: Timeout event in state %d!", PROTO_NAME(f), f->state)); } } /* * fsm_input - Input packet. */ void fsm_input(fsm *f, u_char *inpacket, int l) { u_char *inp; u_char code, id; int len; /* * Parse header (code, id and length). * If packet too short, drop it. */ inp = inpacket; if (l < HEADERLEN) { FSMDEBUG(("fsm_input(%x): Rcvd short header.", f->protocol)); return; } GETCHAR(code, inp); GETCHAR(id, inp); GETSHORT(len, inp); if (len < HEADERLEN) { FSMDEBUG(("fsm_input(%x): Rcvd illegal length.", f->protocol)); return; } if (len > l) { FSMDEBUG(("fsm_input(%x): Rcvd short packet.", f->protocol)); return; } len -= HEADERLEN; /* subtract header length */ if( f->state == INITIAL || f->state == STARTING ){ FSMDEBUG(("fsm_input(%x): Rcvd packet in state %d.", f->protocol, f->state)); return; } /* * Action depends on code. */ switch (code) { case CONFREQ: fsm_rconfreq(f, id, inp, len); break; case CONFACK: fsm_rconfack(f, id, inp, len); break; case CONFNAK: case CONFREJ: fsm_rconfnakrej(f, code, id, inp, len); break; case TERMREQ: fsm_rtermreq(f, id, inp, len); break; case TERMACK: fsm_rtermack(f); break; case CODEREJ: fsm_rcoderej(f, inp, len); break; default: if( !f->callbacks->extcode || !(*f->callbacks->extcode)(f, code, id, inp, len) ) fsm_sdata(f, CODEREJ, ++f->id, inpacket, len + HEADERLEN); break; } } /* * fsm_rconfreq - Receive Configure-Request. */ static void fsm_rconfreq(fsm *f, int id, u_char *inp, int len) { int code, reject_if_disagree; switch( f->state ){ case CLOSED: /* Go away, we're closed */ fsm_sdata(f, TERMACK, id, NULL, 0); return; case CLOSING: case STOPPING: return; case OPENED: /* Go down and restart negotiation */ if( f->callbacks->down ) (*f->callbacks->down)(f); /* Inform upper layers */ fsm_sconfreq(f, 0); /* Send initial Configure-Request */ f->state = REQSENT; break; case STOPPED: /* Negotiation started by our peer */ fsm_sconfreq(f, 0); /* Send initial Configure-Request */ f->state = REQSENT; break; } /* * Pass the requested configuration options * to protocol-specific code for checking. */ if (f->callbacks->reqci){ /* Check CI */ reject_if_disagree = (f->nakloops >= f->maxnakloops); code = (*f->callbacks->reqci)(f, inp, &len, reject_if_disagree); } else if (len) code = CONFREJ; /* Reject all CI */ else code = CONFACK; /* send the Ack, Nak or Rej to the peer */ fsm_sdata(f, code, id, inp, len); if (code == CONFACK) { if (f->state == ACKRCVD) { UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */ f->state = OPENED; if (f->callbacks->up) (*f->callbacks->up)(f); /* Inform upper layers */ } else f->state = ACKSENT; f->nakloops = 0; } else { /* we sent CONFNAK or CONFREJ */ if (f->state != ACKRCVD) f->state = REQSENT; if( code == CONFNAK ) ++f->nakloops; } } /* * fsm_rconfack - Receive Configure-Ack. */ static void fsm_rconfack(fsm *f, int id, u_char *inp, int len) { if (id != f->reqid || f->seen_ack) /* Expected id? */ return; /* Nope, toss... */ if( !(f->callbacks->ackci? (*f->callbacks->ackci)(f, inp, len): (len == 0)) ){ /* Ack is bad - ignore it */ error("Received bad configure-ack: %P", inp, len); return; } f->seen_ack = 1; f->rnakloops = 0; switch (f->state) { case CLOSED: case STOPPED: fsm_sdata(f, TERMACK, id, NULL, 0); break; case REQSENT: f->state = ACKRCVD; f->retransmits = f->maxconfreqtransmits; break; case ACKRCVD: /* Huh? an extra valid Ack? oh well... */ UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */ fsm_sconfreq(f, 0); f->state = REQSENT; break; case ACKSENT: UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */ f->state = OPENED; f->retransmits = f->maxconfreqtransmits; if (f->callbacks->up) (*f->callbacks->up)(f); /* Inform upper layers */ break; case OPENED: /* Go down and restart negotiation */ if (f->callbacks->down) (*f->callbacks->down)(f); /* Inform upper layers */ fsm_sconfreq(f, 0); /* Send initial Configure-Request */ f->state = REQSENT; break; } } /* * fsm_rconfnakrej - Receive Configure-Nak or Configure-Reject. */ static void fsm_rconfnakrej(fsm *f, int code, int id, u_char *inp, int len) { int ret; int treat_as_reject; if (id != f->reqid || f->seen_ack) /* Expected id? */ return; /* Nope, toss... */ if (code == CONFNAK) { ++f->rnakloops; treat_as_reject = (f->rnakloops >= f->maxnakloops); if (f->callbacks->nakci == NULL || !(ret = f->callbacks->nakci(f, inp, len, treat_as_reject))) { error("Received bad configure-nak: %P", inp, len); return; } } else { f->rnakloops = 0; if (f->callbacks->rejci == NULL || !(ret = f->callbacks->rejci(f, inp, len))) { error("Received bad configure-rej: %P", inp, len); return; } } f->seen_ack = 1; switch (f->state) { case CLOSED: case STOPPED: fsm_sdata(f, TERMACK, id, NULL, 0); break; case REQSENT: case ACKSENT: /* They didn't agree to what we wanted - try another request */ UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */ if (ret < 0) f->state = STOPPED; /* kludge for stopping CCP */ else fsm_sconfreq(f, 0); /* Send Configure-Request */ break; case ACKRCVD: /* Got a Nak/reject when we had already had an Ack?? oh well... */ UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */ fsm_sconfreq(f, 0); f->state = REQSENT; break; case OPENED: /* Go down and restart negotiation */ if (f->callbacks->down) (*f->callbacks->down)(f); /* Inform upper layers */ fsm_sconfreq(f, 0); /* Send initial Configure-Request */ f->state = REQSENT; break; } } /* * fsm_rtermreq - Receive Terminate-Req. */ static void fsm_rtermreq(fsm *f, int id, u_char *p, int len) { switch (f->state) { case ACKRCVD: case ACKSENT: f->state = REQSENT; /* Start over but keep trying */ break; case OPENED: if (len > 0) { info("%s terminated by peer (%0.*v)", PROTO_NAME(f), len, p); } else info("%s terminated by peer", PROTO_NAME(f)); f->retransmits = 0; f->state = STOPPING; if (f->callbacks->down) (*f->callbacks->down)(f); /* Inform upper layers */ TIMEOUT(fsm_timeout, f, f->timeouttime); break; } fsm_sdata(f, TERMACK, id, NULL, 0); } /* * fsm_rtermack - Receive Terminate-Ack. */ static void fsm_rtermack(fsm *f) { switch (f->state) { case CLOSING: UNTIMEOUT(fsm_timeout, f); f->state = CLOSED; if( f->callbacks->finished ) (*f->callbacks->finished)(f); break; case STOPPING: UNTIMEOUT(fsm_timeout, f); f->state = STOPPED; if( f->callbacks->finished ) (*f->callbacks->finished)(f); break; case ACKRCVD: f->state = REQSENT; break; case OPENED: if (f->callbacks->down) (*f->callbacks->down)(f); /* Inform upper layers */ fsm_sconfreq(f, 0); f->state = REQSENT; break; } } /* * fsm_rcoderej - Receive an Code-Reject. */ static void fsm_rcoderej(fsm *f, u_char *inp, int len) { u_char code, id; if (len < HEADERLEN) { FSMDEBUG(("fsm_rcoderej: Rcvd short Code-Reject packet!")); return; } GETCHAR(code, inp); GETCHAR(id, inp); warn("%s: Rcvd Code-Reject for code %d, id %d", PROTO_NAME(f), code, id); if( f->state == ACKRCVD ) f->state = REQSENT; } /* * fsm_protreject - Peer doesn't speak this protocol. * * Treat this as a catastrophic error (RXJ-). */ void fsm_protreject(fsm *f) { switch( f->state ){ case CLOSING: UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */ /* fall through */ case CLOSED: f->state = CLOSED; if( f->callbacks->finished ) (*f->callbacks->finished)(f); break; case STOPPING: case REQSENT: case ACKRCVD: case ACKSENT: UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */ /* fall through */ case STOPPED: f->state = STOPPED; if( f->callbacks->finished ) (*f->callbacks->finished)(f); break; case OPENED: terminate_layer(f, STOPPING); break; default: FSMDEBUG(("%s: Protocol-reject event in state %d!", PROTO_NAME(f), f->state)); } } /* * fsm_sconfreq - Send a Configure-Request. */ static void fsm_sconfreq(fsm *f, int retransmit) { u_char *outp; int cilen; if( f->state != REQSENT && f->state != ACKRCVD && f->state != ACKSENT ){ /* Not currently negotiating - reset options */ if( f->callbacks->resetci ) (*f->callbacks->resetci)(f); f->nakloops = 0; f->rnakloops = 0; } if( !retransmit ){ /* New request - reset retransmission counter, use new ID */ f->retransmits = f->maxconfreqtransmits; f->reqid = ++f->id; } f->seen_ack = 0; /* * Make up the request packet */ outp = outpacket_buf + PPP_HDRLEN + HEADERLEN; if( f->callbacks->cilen && f->callbacks->addci ){ cilen = (*f->callbacks->cilen)(f); if( cilen > peer_mru[f->unit] - HEADERLEN ) cilen = peer_mru[f->unit] - HEADERLEN; if (f->callbacks->addci) (*f->callbacks->addci)(f, outp, &cilen); } else cilen = 0; /* send the request to our peer */ fsm_sdata(f, CONFREQ, f->reqid, outp, cilen); /* start the retransmit timer */ --f->retransmits; TIMEOUT(fsm_timeout, f, f->timeouttime); } /* * fsm_sdata - Send some data. * * Used for all packets sent to our peer by this module. */ void fsm_sdata(fsm *f, int code, int id, u_char *data, int datalen) { u_char *outp; int outlen; /* Adjust length to be smaller than MTU */ outp = outpacket_buf; if (datalen > peer_mru[f->unit] - HEADERLEN) datalen = peer_mru[f->unit] - HEADERLEN; if (datalen && data != outp + PPP_HDRLEN + HEADERLEN) BCOPY(data, outp + PPP_HDRLEN + HEADERLEN, datalen); outlen = datalen + HEADERLEN; MAKEHEADER(outp, f->protocol); PUTCHAR(code, outp); PUTCHAR(id, outp); PUTSHORT(outlen, outp); output(f->unit, outpacket_buf, outlen + PPP_HDRLEN); } ppp-2.5.0/pppd/ipcp.c0000644000175000017500000017042014353435407011314 00000000000000/* * ipcp.c - PPP IP Control Protocol. * * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The name "Carnegie Mellon University" must not be used to * endorse or promote products derived from this software without * prior written permission. For permission or any legal * details, please contact * Office of Technology Transfer * Carnegie Mellon University * 5000 Forbes Avenue * Pittsburgh, PA 15213-3890 * (412) 268-4387, fax: (412) 268-7395 * tech-transfer@andrew.cmu.edu * * 4. Redistributions of any form whatsoever must retain the following * acknowledgment: * "This product includes software developed by Computing Services * at Carnegie Mellon University (http://www.cmu.edu/computing/)." * * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include #include #include #include #include "pppd-private.h" #include "options.h" #include "fsm.h" #include "ipcp.h" #include "pathnames.h" /* global vars */ ipcp_options ipcp_wantoptions[NUM_PPP]; /* Options that we want to request */ ipcp_options ipcp_gotoptions[NUM_PPP]; /* Options that peer ack'd */ ipcp_options ipcp_allowoptions[NUM_PPP]; /* Options we allow peer to request */ ipcp_options ipcp_hisoptions[NUM_PPP]; /* Options that we ack'd */ char *ipparam = NULL; /* Extra parameter for ip up/down scripts */ u_int32_t netmask = 0; /* IP netmask to set on interface */ bool disable_defaultip = 0; /* Don't use hostname for default IP adrs */ bool noremoteip = 0; /* Let him have no IP address */ ip_up_hook_fn *ip_up_hook = NULL; ip_down_hook_fn *ip_down_hook = NULL; ip_choose_hook_fn *ip_choose_hook = NULL; /* Notifiers for when IPCP goes up and down */ struct notifier *ip_up_notifier = NULL; struct notifier *ip_down_notifier = NULL; /* local vars */ static int default_route_set[NUM_PPP]; /* Have set up a default route */ static int proxy_arp_set[NUM_PPP]; /* Have created proxy arp entry */ static bool usepeerdns; /* Ask peer for DNS addrs */ static bool usepeerwins; /* Ask peer for WINS addrs */ static int ipcp_is_up; /* have called np_up() */ static int ipcp_is_open; /* haven't called np_finished() */ static bool ask_for_local; /* request our address from peer */ static char vj_value[8]; /* string form of vj option value */ static char netmask_str[20]; /* string form of netmask value */ /* * Callbacks for fsm code. (CI = Configuration Information) */ static void ipcp_resetci (fsm *); /* Reset our CI */ static int ipcp_cilen (fsm *); /* Return length of our CI */ static void ipcp_addci (fsm *, u_char *, int *); /* Add our CI */ static int ipcp_ackci (fsm *, u_char *, int); /* Peer ack'd our CI */ static int ipcp_nakci (fsm *, u_char *, int, int);/* Peer nak'd our CI */ static int ipcp_rejci (fsm *, u_char *, int); /* Peer rej'd our CI */ static int ipcp_reqci (fsm *, u_char *, int *, int); /* Rcv CI */ static void ipcp_up (fsm *); /* We're UP */ static void ipcp_down (fsm *); /* We're DOWN */ static void ipcp_finished (fsm *); /* Don't need lower layer */ fsm ipcp_fsm[NUM_PPP]; /* IPCP fsm structure */ static fsm_callbacks ipcp_callbacks = { /* IPCP callback routines */ ipcp_resetci, /* Reset our Configuration Information */ ipcp_cilen, /* Length of our Configuration Information */ ipcp_addci, /* Add our Configuration Information */ ipcp_ackci, /* ACK our Configuration Information */ ipcp_nakci, /* NAK our Configuration Information */ ipcp_rejci, /* Reject our Configuration Information */ ipcp_reqci, /* Request peer's Configuration Information */ ipcp_up, /* Called when fsm reaches OPENED state */ ipcp_down, /* Called when fsm leaves OPENED state */ NULL, /* Called when we want the lower layer up */ ipcp_finished, /* Called when we want the lower layer down */ NULL, /* Called when Protocol-Reject received */ NULL, /* Retransmission is necessary */ NULL, /* Called to handle protocol-specific codes */ "IPCP" /* String name of protocol */ }; /* * Command-line options. */ static int setvjslots (char **); static int setdnsaddr (char **); static int setwinsaddr (char **); static int setnetmask (char **); int setipaddr (char *, char **, int); static void printipaddr (struct option *, void (*)(void *, char *,...),void *); static struct option ipcp_option_list[] = { { "noip", o_bool, &ipcp_protent.enabled_flag, "Disable IP and IPCP" }, { "-ip", o_bool, &ipcp_protent.enabled_flag, "Disable IP and IPCP", OPT_ALIAS }, { "novj", o_bool, &ipcp_wantoptions[0].neg_vj, "Disable VJ compression", OPT_A2CLR, &ipcp_allowoptions[0].neg_vj }, { "-vj", o_bool, &ipcp_wantoptions[0].neg_vj, "Disable VJ compression", OPT_ALIAS | OPT_A2CLR, &ipcp_allowoptions[0].neg_vj }, { "novjccomp", o_bool, &ipcp_wantoptions[0].cflag, "Disable VJ connection-ID compression", OPT_A2CLR, &ipcp_allowoptions[0].cflag }, { "-vjccomp", o_bool, &ipcp_wantoptions[0].cflag, "Disable VJ connection-ID compression", OPT_ALIAS | OPT_A2CLR, &ipcp_allowoptions[0].cflag }, { "vj-max-slots", o_special, (void *)setvjslots, "Set maximum VJ header slots", OPT_PRIO | OPT_A2STRVAL | OPT_STATIC, vj_value }, { "ipcp-accept-local", o_bool, &ipcp_wantoptions[0].accept_local, "Accept peer's address for us", 1 }, { "ipcp-accept-remote", o_bool, &ipcp_wantoptions[0].accept_remote, "Accept peer's address for it", 1 }, { "ipparam", o_string, &ipparam, "Set ip script parameter", OPT_PRIO }, { "noipdefault", o_bool, &disable_defaultip, "Don't use name for default IP adrs", 1 }, { "ms-dns", o_special, (void *)setdnsaddr, "DNS address for the peer's use", OPT_A2LIST }, { "ms-wins", o_special, (void *)setwinsaddr, "Nameserver for SMB over TCP/IP for peer", OPT_A2LIST }, { "ipcp-restart", o_int, &ipcp_fsm[0].timeouttime, "Set timeout for IPCP", OPT_PRIO }, { "ipcp-max-terminate", o_int, &ipcp_fsm[0].maxtermtransmits, "Set max #xmits for term-reqs", OPT_PRIO }, { "ipcp-max-configure", o_int, &ipcp_fsm[0].maxconfreqtransmits, "Set max #xmits for conf-reqs", OPT_PRIO }, { "ipcp-max-failure", o_int, &ipcp_fsm[0].maxnakloops, "Set max #conf-naks for IPCP", OPT_PRIO }, { "defaultroute", o_bool, &ipcp_wantoptions[0].default_route, "Add default route", OPT_ENABLE|1, &ipcp_allowoptions[0].default_route }, { "nodefaultroute", o_bool, &ipcp_allowoptions[0].default_route, "disable defaultroute option", OPT_A2CLR, &ipcp_wantoptions[0].default_route }, { "-defaultroute", o_bool, &ipcp_allowoptions[0].default_route, "disable defaultroute option", OPT_ALIAS | OPT_A2CLR, &ipcp_wantoptions[0].default_route }, #ifdef __linux__ { "replacedefaultroute", o_bool, &ipcp_wantoptions[0].replace_default_route, "Replace default route", OPT_PRIV | 1 }, { "noreplacedefaultroute", o_bool, &ipcp_wantoptions[0].replace_default_route, "Do not replace default route", 0 }, #endif { "proxyarp", o_bool, &ipcp_wantoptions[0].proxy_arp, "Add proxy ARP entry", OPT_ENABLE|1, &ipcp_allowoptions[0].proxy_arp }, { "noproxyarp", o_bool, &ipcp_allowoptions[0].proxy_arp, "disable proxyarp option", OPT_A2CLR, &ipcp_wantoptions[0].proxy_arp }, { "-proxyarp", o_bool, &ipcp_allowoptions[0].proxy_arp, "disable proxyarp option", OPT_ALIAS | OPT_A2CLR, &ipcp_wantoptions[0].proxy_arp }, { "usepeerdns", o_bool, &usepeerdns, "Ask peer for DNS address(es)", 1 }, { "usepeerwins", o_bool, &usepeerwins, "Ask peer for WINS address(es)", 1 }, { "netmask", o_special, (void *)setnetmask, "set netmask", OPT_PRIO | OPT_A2STRVAL | OPT_STATIC, netmask_str }, { "ipcp-no-addresses", o_bool, &ipcp_wantoptions[0].old_addrs, "Disable old-style IP-Addresses usage", OPT_A2CLR, &ipcp_allowoptions[0].old_addrs }, { "ipcp-no-address", o_bool, &ipcp_wantoptions[0].neg_addr, "Disable IP-Address usage", OPT_A2CLR, &ipcp_allowoptions[0].neg_addr }, #ifdef __linux__ { "noremoteip", o_bool, &noremoteip, "Allow peer to have no IP address", 1 }, #endif { "nosendip", o_bool, &ipcp_wantoptions[0].neg_addr, "Don't send our IP address to peer", OPT_A2CLR, &ipcp_wantoptions[0].old_addrs}, { "IP addresses", o_wild, (void *) &setipaddr, "set local and remote IP addresses", OPT_NOARG | OPT_A2PRINTER, (void *) &printipaddr }, { NULL } }; /* * Protocol entry points from main code. */ static void ipcp_init (int); static void ipcp_open (int); static void ipcp_close (int, char *); static void ipcp_lowerup (int); static void ipcp_lowerdown (int); static void ipcp_input (int, u_char *, int); static void ipcp_protrej (int); static int ipcp_printpkt (u_char *, int, void (*) (void *, char *, ...), void *); static void ip_check_options (void); static int ip_demand_conf (int); static int ip_active_pkt (u_char *, int); static void create_resolv (u_int32_t, u_int32_t); struct protent ipcp_protent = { PPP_IPCP, ipcp_init, ipcp_input, ipcp_protrej, ipcp_lowerup, ipcp_lowerdown, ipcp_open, ipcp_close, ipcp_printpkt, NULL, 1, "IPCP", "IP", ipcp_option_list, ip_check_options, ip_demand_conf, ip_active_pkt }; static void ipcp_clear_addrs (int, u_int32_t, u_int32_t, bool); static void ipcp_script (char *, int); /* Run an up/down script */ static void ipcp_script_done (void *); /* * Lengths of configuration options. */ #define CILEN_VOID 2 #define CILEN_COMPRESS 4 /* min length for compression protocol opt. */ #define CILEN_VJ 6 /* length for RFC1332 Van-Jacobson opt. */ #define CILEN_ADDR 6 /* new-style single address option */ #define CILEN_ADDRS 10 /* old-style dual address option */ #define CODENAME(x) ((x) == CONFACK ? "ACK" : \ (x) == CONFNAK ? "NAK" : "REJ") /* * This state variable is used to ensure that we don't * run an ipcp-up/down script while one is already running. */ static enum script_state { s_down, s_up, } ipcp_script_state; static pid_t ipcp_script_pid; /* * Make a string representation of a network IP address. */ char * ip_ntoa(u_int32_t ipaddr) { static char b[64]; slprintf(b, sizeof(b), "%I", ipaddr); return b; } /* * Option parsing. */ /* * setvjslots - set maximum number of connection slots for VJ compression */ static int setvjslots(char **argv) { int value; if (!ppp_int_option(*argv, &value)) return 0; if (value < 2 || value > 16) { ppp_option_error("vj-max-slots value must be between 2 and 16"); return 0; } ipcp_wantoptions [0].maxslotindex = ipcp_allowoptions[0].maxslotindex = value - 1; slprintf(vj_value, sizeof(vj_value), "%d", value); return 1; } /* * setdnsaddr - set the dns address(es) */ static int setdnsaddr(char **argv) { u_int32_t dns; struct hostent *hp; dns = inet_addr(*argv); if (dns == (u_int32_t) -1) { if ((hp = gethostbyname(*argv)) == NULL) { ppp_option_error("invalid address parameter '%s' for ms-dns option", *argv); return 0; } dns = *(u_int32_t *)hp->h_addr; } /* We take the last 2 values given, the 2nd-last as the primary and the last as the secondary. If only one is given it becomes both primary and secondary. */ if (ipcp_allowoptions[0].dnsaddr[1] == 0) ipcp_allowoptions[0].dnsaddr[0] = dns; else ipcp_allowoptions[0].dnsaddr[0] = ipcp_allowoptions[0].dnsaddr[1]; /* always set the secondary address value. */ ipcp_allowoptions[0].dnsaddr[1] = dns; return (1); } /* * setwinsaddr - set the wins address(es) * This is primrarly used with the Samba package under UNIX or for pointing * the caller to the existing WINS server on a Windows NT platform. */ static int setwinsaddr(char **argv) { u_int32_t wins; struct hostent *hp; wins = inet_addr(*argv); if (wins == (u_int32_t) -1) { if ((hp = gethostbyname(*argv)) == NULL) { ppp_option_error("invalid address parameter '%s' for ms-wins option", *argv); return 0; } wins = *(u_int32_t *)hp->h_addr; } /* We take the last 2 values given, the 2nd-last as the primary and the last as the secondary. If only one is given it becomes both primary and secondary. */ if (ipcp_allowoptions[0].winsaddr[1] == 0) ipcp_allowoptions[0].winsaddr[0] = wins; else ipcp_allowoptions[0].winsaddr[0] = ipcp_allowoptions[0].winsaddr[1]; /* always set the secondary address value. */ ipcp_allowoptions[0].winsaddr[1] = wins; return (1); } /* * setipaddr - Set the IP address * If doit is 0, the call is to check whether this option is * potentially an IP address specification. * Not static so that plugins can call it to set the addresses */ int setipaddr(char *arg, char **argv, int doit) { struct hostent *hp; char *colon; u_int32_t local, remote; ipcp_options *wo = &ipcp_wantoptions[0]; static int prio_local = 0, prio_remote = 0; /* * IP address pair separated by ":". */ if ((colon = strchr(arg, ':')) == NULL) return 0; if (!doit) return 1; /* * If colon first character, then no local addr. */ if (colon != arg && option_priority >= prio_local) { *colon = '\0'; if ((local = inet_addr(arg)) == (u_int32_t) -1) { if ((hp = gethostbyname(arg)) == NULL) { ppp_option_error("unknown host: %s", arg); return 0; } local = *(u_int32_t *)hp->h_addr; } if (ppp_bad_ip_addr(local)) { ppp_option_error("bad local IP address %s", ip_ntoa(local)); return 0; } if (local != 0) wo->ouraddr = local; *colon = ':'; prio_local = option_priority; } /* * If colon last character, then no remote addr. */ if (*++colon != '\0' && option_priority >= prio_remote) { if ((remote = inet_addr(colon)) == (u_int32_t) -1) { if ((hp = gethostbyname(colon)) == NULL) { ppp_option_error("unknown host: %s", colon); return 0; } remote = *(u_int32_t *)hp->h_addr; if (remote_name[0] == 0) strlcpy(remote_name, colon, sizeof(remote_name)); } if (ppp_bad_ip_addr(remote)) { ppp_option_error("bad remote IP address %s", ip_ntoa(remote)); return 0; } if (remote != 0) wo->hisaddr = remote; prio_remote = option_priority; } return 1; } static void printipaddr(struct option *opt, void (*printer) (void *, char *, ...), void *arg) { ipcp_options *wo = &ipcp_wantoptions[0]; if (wo->ouraddr != 0) printer(arg, "%I", wo->ouraddr); printer(arg, ":"); if (wo->hisaddr != 0) printer(arg, "%I", wo->hisaddr); } /* * setnetmask - set the netmask to be used on the interface. */ static int setnetmask(char **argv) { u_int32_t mask; int n; char *p; /* * Unfortunately, if we use inet_addr, we can't tell whether * a result of all 1s is an error or a valid 255.255.255.255. */ p = *argv; n = parse_dotted_ip(p, &mask); mask = htonl(mask); if (n == 0 || p[n] != 0 || (netmask & ~mask) != 0) { ppp_option_error("invalid netmask value '%s'", *argv); return 0; } netmask = mask; slprintf(netmask_str, sizeof(netmask_str), "%I", mask); return (1); } int parse_dotted_ip(char *p, u_int32_t *vp) { int n; u_int32_t v, b; char *endp, *p0 = p; v = 0; for (n = 3;; --n) { b = strtoul(p, &endp, 0); if (endp == p) return 0; if (b > 255) { if (n < 3) return 0; /* accept e.g. 0xffffff00 */ *vp = b; return endp - p0; } v |= b << (n * 8); p = endp; if (n == 0) break; if (*p != '.') return 0; ++p; } *vp = v; return p - p0; } const char *ppp_ipparam() { return ipparam; } /* * ipcp_init - Initialize IPCP. */ static void ipcp_init(int unit) { fsm *f = &ipcp_fsm[unit]; ipcp_options *wo = &ipcp_wantoptions[unit]; ipcp_options *ao = &ipcp_allowoptions[unit]; f->unit = unit; f->protocol = PPP_IPCP; f->callbacks = &ipcp_callbacks; fsm_init(&ipcp_fsm[unit]); /* * Some 3G modems use repeated IPCP NAKs as a way of stalling * until they can contact a server on the network, so we increase * the default number of NAKs we accept before we start treating * them as rejects. */ f->maxnakloops = 100; memset(wo, 0, sizeof(*wo)); memset(ao, 0, sizeof(*ao)); wo->neg_addr = wo->old_addrs = 1; wo->neg_vj = 1; wo->vj_protocol = IPCP_VJ_COMP; wo->maxslotindex = MAX_STATES - 1; /* really max index */ wo->cflag = 1; /* max slots and slot-id compression are currently hardwired in */ /* ppp_if.c to 16 and 1, this needs to be changed (among other */ /* things) gmc */ ao->neg_addr = ao->old_addrs = 1; ao->neg_vj = 1; ao->maxslotindex = MAX_STATES - 1; ao->cflag = 1; /* * XXX These control whether the user may use the proxyarp * and defaultroute options. */ ao->proxy_arp = 1; ao->default_route = 1; } /* * ipcp_open - IPCP is allowed to come up. */ static void ipcp_open(int unit) { fsm_open(&ipcp_fsm[unit]); ipcp_is_open = 1; } /* * ipcp_close - Take IPCP down. */ static void ipcp_close(int unit, char *reason) { fsm_close(&ipcp_fsm[unit], reason); } /* * ipcp_lowerup - The lower layer is up. */ static void ipcp_lowerup(int unit) { fsm_lowerup(&ipcp_fsm[unit]); } /* * ipcp_lowerdown - The lower layer is down. */ static void ipcp_lowerdown(int unit) { fsm_lowerdown(&ipcp_fsm[unit]); } /* * ipcp_input - Input IPCP packet. */ static void ipcp_input(int unit, u_char *p, int len) { fsm_input(&ipcp_fsm[unit], p, len); } /* * ipcp_protrej - A Protocol-Reject was received for IPCP. * * Pretend the lower layer went down, so we shut up. */ static void ipcp_protrej(int unit) { fsm_lowerdown(&ipcp_fsm[unit]); } /* * ipcp_resetci - Reset our CI. * Called by fsm_sconfreq, Send Configure Request. */ static void ipcp_resetci(fsm *f) { ipcp_options *wo = &ipcp_wantoptions[f->unit]; ipcp_options *go = &ipcp_gotoptions[f->unit]; ipcp_options *ao = &ipcp_allowoptions[f->unit]; wo->req_addr = ((wo->neg_addr || wo->old_addrs) && (ao->neg_addr || ao->old_addrs)) || (wo->hisaddr && !wo->accept_remote); if (wo->ouraddr == 0) wo->accept_local = 1; if (wo->hisaddr == 0) wo->accept_remote = 1; wo->req_dns1 = usepeerdns; /* Request DNS addresses from the peer */ wo->req_dns2 = usepeerdns; wo->req_wins1 = usepeerwins; /* Request WINS addresses from the peer */ wo->req_wins2 = usepeerwins; *go = *wo; if (!ask_for_local) go->ouraddr = 0; if (ip_choose_hook) { ip_choose_hook(&wo->hisaddr); if (wo->hisaddr) { wo->accept_remote = 0; } } BZERO(&ipcp_hisoptions[f->unit], sizeof(ipcp_options)); } /* * ipcp_cilen - Return length of our CI. * Called by fsm_sconfreq, Send Configure Request. */ static int ipcp_cilen(fsm *f) { ipcp_options *go = &ipcp_gotoptions[f->unit]; ipcp_options *wo = &ipcp_wantoptions[f->unit]; ipcp_options *ho = &ipcp_hisoptions[f->unit]; #define LENCIADDRS(neg) (neg ? CILEN_ADDRS : 0) #define LENCIVJ(neg, old) (neg ? (old? CILEN_COMPRESS : CILEN_VJ) : 0) #define LENCIADDR(neg) (neg ? CILEN_ADDR : 0) #define LENCIDNS(neg) LENCIADDR(neg) #define LENCIWINS(neg) LENCIADDR(neg) /* * First see if we want to change our options to the old * forms because we have received old forms from the peer. */ if (go->neg_addr && go->old_addrs && !ho->neg_addr && ho->old_addrs) go->neg_addr = 0; if (wo->neg_vj && !go->neg_vj && !go->old_vj) { /* try an older style of VJ negotiation */ /* use the old style only if the peer did */ if (ho->neg_vj && ho->old_vj) { go->neg_vj = 1; go->old_vj = 1; go->vj_protocol = ho->vj_protocol; } } return (LENCIADDRS(!go->neg_addr && go->old_addrs) + LENCIVJ(go->neg_vj, go->old_vj) + LENCIADDR(go->neg_addr) + LENCIDNS(go->req_dns1) + LENCIDNS(go->req_dns2) + LENCIWINS(go->req_wins1) + LENCIWINS(go->req_wins2)) ; } /* * ipcp_addci - Add our desired CIs to a packet. * Called by fsm_sconfreq, Send Configure Request. */ static void ipcp_addci(fsm *f, u_char *ucp, int *lenp) { ipcp_options *go = &ipcp_gotoptions[f->unit]; int len = *lenp; #define ADDCIADDRS(opt, neg, val1, val2) \ if (neg) { \ if (len >= CILEN_ADDRS) { \ u_int32_t l; \ PUTCHAR(opt, ucp); \ PUTCHAR(CILEN_ADDRS, ucp); \ l = ntohl(val1); \ PUTLONG(l, ucp); \ l = ntohl(val2); \ PUTLONG(l, ucp); \ len -= CILEN_ADDRS; \ } else \ go->old_addrs = 0; \ } #define ADDCIVJ(opt, neg, val, old, maxslotindex, cflag) \ if (neg) { \ int vjlen = old? CILEN_COMPRESS : CILEN_VJ; \ if (len >= vjlen) { \ PUTCHAR(opt, ucp); \ PUTCHAR(vjlen, ucp); \ PUTSHORT(val, ucp); \ if (!old) { \ PUTCHAR(maxslotindex, ucp); \ PUTCHAR(cflag, ucp); \ } \ len -= vjlen; \ } else \ neg = 0; \ } #define ADDCIADDR(opt, neg, val) \ if (neg) { \ if (len >= CILEN_ADDR) { \ u_int32_t l; \ PUTCHAR(opt, ucp); \ PUTCHAR(CILEN_ADDR, ucp); \ l = ntohl(val); \ PUTLONG(l, ucp); \ len -= CILEN_ADDR; \ } else \ neg = 0; \ } #define ADDCIDNS(opt, neg, addr) \ if (neg) { \ if (len >= CILEN_ADDR) { \ u_int32_t l; \ PUTCHAR(opt, ucp); \ PUTCHAR(CILEN_ADDR, ucp); \ l = ntohl(addr); \ PUTLONG(l, ucp); \ len -= CILEN_ADDR; \ } else \ neg = 0; \ } #define ADDCIWINS(opt, neg, addr) \ if (neg) { \ if (len >= CILEN_ADDR) { \ u_int32_t l; \ PUTCHAR(opt, ucp); \ PUTCHAR(CILEN_ADDR, ucp); \ l = ntohl(addr); \ PUTLONG(l, ucp); \ len -= CILEN_ADDR; \ } else \ neg = 0; \ } ADDCIADDRS(CI_ADDRS, !go->neg_addr && go->old_addrs, go->ouraddr, go->hisaddr); ADDCIVJ(CI_COMPRESSTYPE, go->neg_vj, go->vj_protocol, go->old_vj, go->maxslotindex, go->cflag); ADDCIADDR(CI_ADDR, go->neg_addr, go->ouraddr); ADDCIDNS(CI_MS_DNS1, go->req_dns1, go->dnsaddr[0]); ADDCIDNS(CI_MS_DNS2, go->req_dns2, go->dnsaddr[1]); ADDCIWINS(CI_MS_WINS1, go->req_wins1, go->winsaddr[0]); ADDCIWINS(CI_MS_WINS2, go->req_wins2, go->winsaddr[1]); *lenp -= len; } /* * ipcp_ackci - Ack our CIs. * Called by fsm_rconfack, Receive Configure ACK. * * Returns: * 0 - Ack was bad. * 1 - Ack was good. */ static int ipcp_ackci(fsm *f, u_char *p, int len) { ipcp_options *go = &ipcp_gotoptions[f->unit]; u_short cilen, citype, cishort; u_int32_t cilong; u_char cimaxslotindex, cicflag; /* * CIs must be in exactly the same order that we sent... * Check packet length and CI length at each step. * If we find any deviations, then this packet is bad. */ #define ACKCIADDRS(opt, neg, val1, val2) \ if (neg) { \ u_int32_t l; \ if ((len -= CILEN_ADDRS) < 0) \ goto bad; \ GETCHAR(citype, p); \ GETCHAR(cilen, p); \ if (cilen != CILEN_ADDRS || \ citype != opt) \ goto bad; \ GETLONG(l, p); \ cilong = htonl(l); \ if (val1 != cilong) \ goto bad; \ GETLONG(l, p); \ cilong = htonl(l); \ if (val2 != cilong) \ goto bad; \ } #define ACKCIVJ(opt, neg, val, old, maxslotindex, cflag) \ if (neg) { \ int vjlen = old? CILEN_COMPRESS : CILEN_VJ; \ if ((len -= vjlen) < 0) \ goto bad; \ GETCHAR(citype, p); \ GETCHAR(cilen, p); \ if (cilen != vjlen || \ citype != opt) \ goto bad; \ GETSHORT(cishort, p); \ if (cishort != val) \ goto bad; \ if (!old) { \ GETCHAR(cimaxslotindex, p); \ if (cimaxslotindex != maxslotindex) \ goto bad; \ GETCHAR(cicflag, p); \ if (cicflag != cflag) \ goto bad; \ } \ } #define ACKCIADDR(opt, neg, val) \ if (neg) { \ u_int32_t l; \ if ((len -= CILEN_ADDR) < 0) \ goto bad; \ GETCHAR(citype, p); \ GETCHAR(cilen, p); \ if (cilen != CILEN_ADDR || \ citype != opt) \ goto bad; \ GETLONG(l, p); \ cilong = htonl(l); \ if (val != cilong) \ goto bad; \ } #define ACKCIDNS(opt, neg, addr) \ if (neg) { \ u_int32_t l; \ if ((len -= CILEN_ADDR) < 0) \ goto bad; \ GETCHAR(citype, p); \ GETCHAR(cilen, p); \ if (cilen != CILEN_ADDR || citype != opt) \ goto bad; \ GETLONG(l, p); \ cilong = htonl(l); \ if (addr != cilong) \ goto bad; \ } #define ACKCIWINS(opt, neg, addr) \ if (neg) { \ u_int32_t l; \ if ((len -= CILEN_ADDR) < 0) \ goto bad; \ GETCHAR(citype, p); \ GETCHAR(cilen, p); \ if (cilen != CILEN_ADDR || citype != opt) \ goto bad; \ GETLONG(l, p); \ cilong = htonl(l); \ if (addr != cilong) \ goto bad; \ } ACKCIADDRS(CI_ADDRS, !go->neg_addr && go->old_addrs, go->ouraddr, go->hisaddr); ACKCIVJ(CI_COMPRESSTYPE, go->neg_vj, go->vj_protocol, go->old_vj, go->maxslotindex, go->cflag); ACKCIADDR(CI_ADDR, go->neg_addr, go->ouraddr); ACKCIDNS(CI_MS_DNS1, go->req_dns1, go->dnsaddr[0]); ACKCIDNS(CI_MS_DNS2, go->req_dns2, go->dnsaddr[1]); ACKCIWINS(CI_MS_WINS1, go->req_wins1, go->winsaddr[0]); ACKCIWINS(CI_MS_WINS2, go->req_wins2, go->winsaddr[1]); /* * If there are any remaining CIs, then this packet is bad. */ if (len != 0) goto bad; return (1); bad: IPCPDEBUG(("ipcp_ackci: received bad Ack!")); return (0); } /* * ipcp_nakci - Peer has sent a NAK for some of our CIs. * This should not modify any state if the Nak is bad * or if IPCP is in the OPENED state. * Calback from fsm_rconfnakrej - Receive Configure-Nak or Configure-Reject. * * Returns: * 0 - Nak was bad. * 1 - Nak was good. */ static int ipcp_nakci(fsm *f, u_char *p, int len, int treat_as_reject) { ipcp_options *wo = &ipcp_wantoptions[f->unit]; ipcp_options *go = &ipcp_gotoptions[f->unit]; u_char cimaxslotindex, cicflag; u_char citype, cilen, *next; u_short cishort; u_int32_t ciaddr1, ciaddr2, l, cidnsaddr, ciwinsaddr; ipcp_options no; /* options we've seen Naks for */ ipcp_options try; /* options to request next time */ BZERO(&no, sizeof(no)); try = *go; /* * Any Nak'd CIs must be in exactly the same order that we sent. * Check packet length and CI length at each step. * If we find any deviations, then this packet is bad. */ #define NAKCIADDRS(opt, neg, code) \ if ((neg) && \ (cilen = p[1]) == CILEN_ADDRS && \ len >= cilen && \ p[0] == opt) { \ len -= cilen; \ INCPTR(2, p); \ GETLONG(l, p); \ ciaddr1 = htonl(l); \ GETLONG(l, p); \ ciaddr2 = htonl(l); \ no.old_addrs = 1; \ code \ } #define NAKCIVJ(opt, neg, code) \ if (go->neg && \ ((cilen = p[1]) == CILEN_COMPRESS || cilen == CILEN_VJ) && \ len >= cilen && \ p[0] == opt) { \ len -= cilen; \ INCPTR(2, p); \ GETSHORT(cishort, p); \ no.neg = 1; \ code \ } #define NAKCIADDR(opt, neg, code) \ if (go->neg && \ (cilen = p[1]) == CILEN_ADDR && \ len >= cilen && \ p[0] == opt) { \ len -= cilen; \ INCPTR(2, p); \ GETLONG(l, p); \ ciaddr1 = htonl(l); \ no.neg = 1; \ code \ } #define NAKCIDNS(opt, neg, code) \ if (go->neg && \ ((cilen = p[1]) == CILEN_ADDR) && \ len >= cilen && \ p[0] == opt) { \ len -= cilen; \ INCPTR(2, p); \ GETLONG(l, p); \ cidnsaddr = htonl(l); \ no.neg = 1; \ code \ } #define NAKCIWINS(opt, neg, code) \ if (go->neg && \ ((cilen = p[1]) == CILEN_ADDR) && \ len >= cilen && \ p[0] == opt) { \ len -= cilen; \ INCPTR(2, p); \ GETLONG(l, p); \ ciwinsaddr = htonl(l); \ no.neg = 1; \ code \ } /* * Accept the peer's idea of {our,his} address, if different * from our idea, only if the accept_{local,remote} flag is set. */ NAKCIADDRS(CI_ADDRS, !go->neg_addr && go->old_addrs, if (treat_as_reject) { try.old_addrs = 0; } else { if (go->accept_local && ciaddr1) { /* take his idea of our address */ try.ouraddr = ciaddr1; } if (go->accept_remote && ciaddr2) { /* take his idea of his address */ try.hisaddr = ciaddr2; } } ); /* * Accept the peer's value of maxslotindex provided that it * is less than what we asked for. Turn off slot-ID compression * if the peer wants. Send old-style compress-type option if * the peer wants. */ NAKCIVJ(CI_COMPRESSTYPE, neg_vj, if (treat_as_reject) { try.neg_vj = 0; } else if (cilen == CILEN_VJ) { GETCHAR(cimaxslotindex, p); GETCHAR(cicflag, p); if (cishort == IPCP_VJ_COMP) { try.old_vj = 0; if (cimaxslotindex < go->maxslotindex) try.maxslotindex = cimaxslotindex; if (!cicflag) try.cflag = 0; } else { try.neg_vj = 0; } } else { if (cishort == IPCP_VJ_COMP || cishort == IPCP_VJ_COMP_OLD) { try.old_vj = 1; try.vj_protocol = cishort; } else { try.neg_vj = 0; } } ); NAKCIADDR(CI_ADDR, neg_addr, if (treat_as_reject) { try.neg_addr = 0; try.old_addrs = 0; } else if (go->accept_local && ciaddr1) { /* take his idea of our address */ try.ouraddr = ciaddr1; } ); NAKCIDNS(CI_MS_DNS1, req_dns1, if (treat_as_reject) { try.req_dns1 = 0; } else { try.dnsaddr[0] = cidnsaddr; } ); NAKCIDNS(CI_MS_DNS2, req_dns2, if (treat_as_reject) { try.req_dns2 = 0; } else { try.dnsaddr[1] = cidnsaddr; } ); NAKCIWINS(CI_MS_WINS1, req_wins1, if (treat_as_reject) { try.req_wins1 = 0; } else { try.winsaddr[0] = ciwinsaddr; } ); NAKCIWINS(CI_MS_WINS2, req_wins2, if (treat_as_reject) { try.req_wins2 = 0; } else { try.winsaddr[1] = ciwinsaddr; } ); /* * There may be remaining CIs, if the peer is requesting negotiation * on an option that we didn't include in our request packet. * If they want to negotiate about IP addresses, we comply. * If they want us to ask for compression, we refuse. * If they want us to ask for ms-dns, we do that, since some * peers get huffy if we don't. */ while (len >= CILEN_VOID) { GETCHAR(citype, p); GETCHAR(cilen, p); if ( cilen < CILEN_VOID || (len -= cilen) < 0 ) goto bad; next = p + cilen - 2; switch (citype) { case CI_COMPRESSTYPE: if (go->neg_vj || no.neg_vj || (cilen != CILEN_VJ && cilen != CILEN_COMPRESS)) goto bad; no.neg_vj = 1; break; case CI_ADDRS: if ((!go->neg_addr && go->old_addrs) || no.old_addrs || cilen != CILEN_ADDRS) goto bad; try.neg_addr = 0; GETLONG(l, p); ciaddr1 = htonl(l); if (ciaddr1 && go->accept_local) try.ouraddr = wo->old_addrs ? ciaddr1 : 0; GETLONG(l, p); ciaddr2 = htonl(l); if (ciaddr2 && go->accept_remote) try.hisaddr = ciaddr2; no.old_addrs = 1; break; case CI_ADDR: if (go->neg_addr || no.neg_addr || cilen != CILEN_ADDR) goto bad; try.old_addrs = 0; GETLONG(l, p); ciaddr1 = htonl(l); if (ciaddr1 && go->accept_local) try.ouraddr = ciaddr1; if (try.ouraddr != 0 && wo->neg_addr) try.neg_addr = 1; no.neg_addr = 1; break; case CI_MS_DNS1: if (go->req_dns1 || no.req_dns1 || cilen != CILEN_ADDR) goto bad; GETLONG(l, p); try.dnsaddr[0] = htonl(l); try.req_dns1 = 1; no.req_dns1 = 1; break; case CI_MS_DNS2: if (go->req_dns2 || no.req_dns2 || cilen != CILEN_ADDR) goto bad; GETLONG(l, p); try.dnsaddr[1] = htonl(l); try.req_dns2 = 1; no.req_dns2 = 1; break; case CI_MS_WINS1: if (go->req_wins1 || no.req_wins1 || cilen != CILEN_ADDR) goto bad; GETLONG(l, p); try.winsaddr[0] = htonl(l); try.req_wins1 = 1; no.req_wins1 = 1; break; case CI_MS_WINS2: if (go->req_wins2 || no.req_wins2 || cilen != CILEN_ADDR) goto bad; GETLONG(l, p); try.winsaddr[1] = htonl(l); try.req_wins2 = 1; no.req_wins2 = 1; break; } p = next; } /* * OK, the Nak is good. Now we can update state. * If there are any remaining options, we ignore them. */ if (f->state != OPENED) *go = try; return 1; bad: IPCPDEBUG(("ipcp_nakci: received bad Nak!")); return 0; } /* * ipcp_rejci - Reject some of our CIs. * Callback from fsm_rconfnakrej. */ static int ipcp_rejci(fsm *f, u_char *p, int len) { ipcp_options *go = &ipcp_gotoptions[f->unit]; u_char cimaxslotindex, ciflag, cilen; u_short cishort; u_int32_t cilong; ipcp_options try; /* options to request next time */ try = *go; /* * Any Rejected CIs must be in exactly the same order that we sent. * Check packet length and CI length at each step. * If we find any deviations, then this packet is bad. */ #define REJCIADDRS(opt, neg, val1, val2) \ if ((neg) && \ (cilen = p[1]) == CILEN_ADDRS && \ len >= cilen && \ p[0] == opt) { \ u_int32_t l; \ len -= cilen; \ INCPTR(2, p); \ GETLONG(l, p); \ cilong = htonl(l); \ /* Check rejected value. */ \ if (cilong != val1) \ goto bad; \ GETLONG(l, p); \ cilong = htonl(l); \ /* Check rejected value. */ \ if (cilong != val2) \ goto bad; \ try.old_addrs = 0; \ } #define REJCIVJ(opt, neg, val, old, maxslot, cflag) \ if (go->neg && \ p[1] == (old? CILEN_COMPRESS : CILEN_VJ) && \ len >= p[1] && \ p[0] == opt) { \ len -= p[1]; \ INCPTR(2, p); \ GETSHORT(cishort, p); \ /* Check rejected value. */ \ if (cishort != val) \ goto bad; \ if (!old) { \ GETCHAR(cimaxslotindex, p); \ if (cimaxslotindex != maxslot) \ goto bad; \ GETCHAR(ciflag, p); \ if (ciflag != cflag) \ goto bad; \ } \ try.neg = 0; \ } #define REJCIADDR(opt, neg, val) \ if (go->neg && \ (cilen = p[1]) == CILEN_ADDR && \ len >= cilen && \ p[0] == opt) { \ u_int32_t l; \ len -= cilen; \ INCPTR(2, p); \ GETLONG(l, p); \ cilong = htonl(l); \ /* Check rejected value. */ \ if (cilong != val) \ goto bad; \ try.neg = 0; \ } #define REJCIDNS(opt, neg, dnsaddr) \ if (go->neg && \ ((cilen = p[1]) == CILEN_ADDR) && \ len >= cilen && \ p[0] == opt) { \ u_int32_t l; \ len -= cilen; \ INCPTR(2, p); \ GETLONG(l, p); \ cilong = htonl(l); \ /* Check rejected value. */ \ if (cilong != dnsaddr) \ goto bad; \ try.neg = 0; \ } #define REJCIWINS(opt, neg, addr) \ if (go->neg && \ ((cilen = p[1]) == CILEN_ADDR) && \ len >= cilen && \ p[0] == opt) { \ u_int32_t l; \ len -= cilen; \ INCPTR(2, p); \ GETLONG(l, p); \ cilong = htonl(l); \ /* Check rejected value. */ \ if (cilong != addr) \ goto bad; \ try.neg = 0; \ } REJCIADDRS(CI_ADDRS, !go->neg_addr && go->old_addrs, go->ouraddr, go->hisaddr); REJCIVJ(CI_COMPRESSTYPE, neg_vj, go->vj_protocol, go->old_vj, go->maxslotindex, go->cflag); REJCIADDR(CI_ADDR, neg_addr, go->ouraddr); REJCIDNS(CI_MS_DNS1, req_dns1, go->dnsaddr[0]); REJCIDNS(CI_MS_DNS2, req_dns2, go->dnsaddr[1]); REJCIWINS(CI_MS_WINS1, req_wins1, go->winsaddr[0]); REJCIWINS(CI_MS_WINS2, req_wins2, go->winsaddr[1]); /* * If there are any remaining CIs, then this packet is bad. */ if (len != 0) goto bad; /* * Now we can update state. */ if (f->state != OPENED) *go = try; return 1; bad: IPCPDEBUG(("ipcp_rejci: received bad Reject!")); return 0; } /* * ipcp_reqci - Check the peer's requested CIs and send appropriate response. * Callback from fsm_rconfreq, Receive Configure Request * * Returns: CONFACK, CONFNAK or CONFREJ and input packet modified * appropriately. If reject_if_disagree is non-zero, doesn't return * CONFNAK; returns CONFREJ if it can't return CONFACK. */ static int ipcp_reqci(fsm *f, u_char *inp, int *len, int reject_if_disagree) { ipcp_options *wo = &ipcp_wantoptions[f->unit]; ipcp_options *ho = &ipcp_hisoptions[f->unit]; ipcp_options *ao = &ipcp_allowoptions[f->unit]; u_char *cip, *next; /* Pointer to current and next CIs */ u_short cilen, citype; /* Parsed len, type */ u_short cishort; /* Parsed short value */ u_int32_t tl, ciaddr1, ciaddr2;/* Parsed address values */ int rc = CONFACK; /* Final packet return code */ int orc; /* Individual option return code */ u_char *p; /* Pointer to next char to parse */ u_char *ucp = inp; /* Pointer to current output char */ int l = *len; /* Length left */ u_char maxslotindex, cflag; int d; /* * Reset all his options. */ BZERO(ho, sizeof(*ho)); /* * Process all his options. */ next = inp; while (l) { orc = CONFACK; /* Assume success */ cip = p = next; /* Remember begining of CI */ if (l < 2 || /* Not enough data for CI header or */ p[1] < 2 || /* CI length too small or */ p[1] > l) { /* CI length too big? */ IPCPDEBUG(("ipcp_reqci: bad CI length!")); orc = CONFREJ; /* Reject bad CI */ cilen = l; /* Reject till end of packet */ l = 0; /* Don't loop again */ goto endswitch; } GETCHAR(citype, p); /* Parse CI type */ GETCHAR(cilen, p); /* Parse CI length */ l -= cilen; /* Adjust remaining length */ next += cilen; /* Step to next CI */ switch (citype) { /* Check CI type */ case CI_ADDRS: if (!ao->old_addrs || ho->neg_addr || cilen != CILEN_ADDRS) { /* Check CI length */ orc = CONFREJ; /* Reject CI */ break; } /* * If he has no address, or if we both have his address but * disagree about it, then NAK it with our idea. * In particular, if we don't know his address, but he does, * then accept it. */ GETLONG(tl, p); /* Parse source address (his) */ ciaddr1 = htonl(tl); if (ciaddr1 != wo->hisaddr && (ciaddr1 == 0 || !wo->accept_remote)) { orc = CONFNAK; if (!reject_if_disagree) { DECPTR(sizeof(u_int32_t), p); tl = ntohl(wo->hisaddr); PUTLONG(tl, p); } } else if (ciaddr1 == 0 && wo->hisaddr == 0) { /* * If neither we nor he knows his address, reject the option. */ orc = CONFREJ; wo->req_addr = 0; /* don't NAK with 0.0.0.0 later */ break; } /* * If he doesn't know our address, or if we both have our address * but disagree about it, then NAK it with our idea. */ GETLONG(tl, p); /* Parse desination address (ours) */ ciaddr2 = htonl(tl); if (ciaddr2 != wo->ouraddr) { if (ciaddr2 == 0 || !wo->accept_local) { orc = CONFNAK; if (!reject_if_disagree && wo->old_addrs) { DECPTR(sizeof(u_int32_t), p); tl = ntohl(wo->ouraddr); PUTLONG(tl, p); } } else { wo->ouraddr = ciaddr2; /* accept peer's idea */ } } ho->old_addrs = 1; ho->hisaddr = ciaddr1; ho->ouraddr = ciaddr2; break; case CI_ADDR: if (!ao->neg_addr || ho->old_addrs || cilen != CILEN_ADDR) { /* Check CI length */ orc = CONFREJ; /* Reject CI */ break; } /* * If he has no address, or if we both have his address but * disagree about it, then NAK it with our idea. * In particular, if we don't know his address, but he does, * then accept it. */ GETLONG(tl, p); /* Parse source address (his) */ ciaddr1 = htonl(tl); if (ciaddr1 != wo->hisaddr && (ciaddr1 == 0 || !wo->accept_remote)) { orc = CONFNAK; if (!reject_if_disagree) { DECPTR(sizeof(u_int32_t), p); tl = ntohl(wo->hisaddr); PUTLONG(tl, p); } } else if (ciaddr1 == 0 && wo->hisaddr == 0) { /* * Don't ACK an address of 0.0.0.0 - reject it instead. */ orc = CONFREJ; wo->req_addr = 0; /* don't NAK with 0.0.0.0 later */ break; } ho->neg_addr = 1; ho->hisaddr = ciaddr1; break; case CI_MS_DNS1: case CI_MS_DNS2: /* Microsoft primary or secondary DNS request */ d = citype == CI_MS_DNS2; /* If we do not have a DNS address then we cannot send it */ if (ao->dnsaddr[d] == 0 || cilen != CILEN_ADDR) { /* Check CI length */ orc = CONFREJ; /* Reject CI */ break; } GETLONG(tl, p); if (htonl(tl) != ao->dnsaddr[d]) { DECPTR(sizeof(u_int32_t), p); tl = ntohl(ao->dnsaddr[d]); PUTLONG(tl, p); orc = CONFNAK; } break; case CI_MS_WINS1: case CI_MS_WINS2: /* Microsoft primary or secondary WINS request */ d = citype == CI_MS_WINS2; /* If we do not have a WINS address then we cannot send it */ if (ao->winsaddr[d] == 0 || cilen != CILEN_ADDR) { /* Check CI length */ orc = CONFREJ; /* Reject CI */ break; } GETLONG(tl, p); if (htonl(tl) != ao->winsaddr[d]) { DECPTR(sizeof(u_int32_t), p); tl = ntohl(ao->winsaddr[d]); PUTLONG(tl, p); orc = CONFNAK; } break; case CI_COMPRESSTYPE: if (!ao->neg_vj || (cilen != CILEN_VJ && cilen != CILEN_COMPRESS)) { orc = CONFREJ; break; } GETSHORT(cishort, p); if (!(cishort == IPCP_VJ_COMP || (cishort == IPCP_VJ_COMP_OLD && cilen == CILEN_COMPRESS))) { orc = CONFREJ; break; } ho->neg_vj = 1; ho->vj_protocol = cishort; if (cilen == CILEN_VJ) { GETCHAR(maxslotindex, p); if (maxslotindex > ao->maxslotindex) { orc = CONFNAK; if (!reject_if_disagree){ DECPTR(1, p); PUTCHAR(ao->maxslotindex, p); } } GETCHAR(cflag, p); if (cflag && !ao->cflag) { orc = CONFNAK; if (!reject_if_disagree){ DECPTR(1, p); PUTCHAR(wo->cflag, p); } } ho->maxslotindex = maxslotindex; ho->cflag = cflag; } else { ho->old_vj = 1; ho->maxslotindex = MAX_STATES - 1; ho->cflag = 1; } break; default: orc = CONFREJ; break; } endswitch: if (orc == CONFACK && /* Good CI */ rc != CONFACK) /* but prior CI wasnt? */ continue; /* Don't send this one */ if (orc == CONFNAK) { /* Nak this CI? */ if (reject_if_disagree) /* Getting fed up with sending NAKs? */ orc = CONFREJ; /* Get tough if so */ else { if (rc == CONFREJ) /* Rejecting prior CI? */ continue; /* Don't send this one */ if (rc == CONFACK) { /* Ack'd all prior CIs? */ rc = CONFNAK; /* Not anymore... */ ucp = inp; /* Backup */ } } } if (orc == CONFREJ && /* Reject this CI */ rc != CONFREJ) { /* but no prior ones? */ rc = CONFREJ; ucp = inp; /* Backup */ } /* Need to move CI? */ if (ucp != cip) BCOPY(cip, ucp, cilen); /* Move it */ /* Update output pointer */ INCPTR(cilen, ucp); } /* * If we aren't rejecting this packet, and we want to negotiate * their address, and they didn't send their address, then we * send a NAK with a CI_ADDR option appended. We assume the * input buffer is long enough that we can append the extra * option safely. */ if (rc != CONFREJ && !ho->neg_addr && !ho->old_addrs && wo->req_addr && !reject_if_disagree && ((wo->hisaddr && !wo->accept_remote) || !noremoteip)) { if (rc == CONFACK) { rc = CONFNAK; ucp = inp; /* reset pointer */ wo->req_addr = 0; /* don't ask again */ } PUTCHAR(CI_ADDR, ucp); PUTCHAR(CILEN_ADDR, ucp); tl = ntohl(wo->hisaddr); PUTLONG(tl, ucp); } *len = ucp - inp; /* Compute output length */ IPCPDEBUG(("ipcp: returning Configure-%s", CODENAME(rc))); return (rc); /* Return final code */ } /* * ip_check_options - check that any IP-related options are OK, * and assign appropriate defaults. */ static void ip_check_options(void) { struct hostent *hp; u_int32_t local; ipcp_options *wo = &ipcp_wantoptions[0]; /* * Default our local IP address based on our hostname. * If local IP address already given, don't bother. */ if (wo->ouraddr == 0 && !disable_defaultip) { /* * Look up our hostname (possibly with domain name appended) * and take the first IP address as our local IP address. * If there isn't an IP address for our hostname, too bad. */ wo->accept_local = 1; /* don't insist on this default value */ if ((hp = gethostbyname(hostname)) != NULL) { local = *(u_int32_t *)hp->h_addr; if (local != 0 && !ppp_bad_ip_addr(local)) wo->ouraddr = local; } } ask_for_local = wo->ouraddr != 0 || !disable_defaultip; } /* * ip_demand_conf - configure the interface as though * IPCP were up, for use with dial-on-demand. */ static int ip_demand_conf(int u) { ipcp_options *wo = &ipcp_wantoptions[u]; if (wo->hisaddr == 0 && !noremoteip) { /* make up an arbitrary address for the peer */ wo->hisaddr = htonl(0x0a707070 + ifunit); wo->accept_remote = 1; } if (wo->ouraddr == 0) { /* make up an arbitrary address for us */ wo->ouraddr = htonl(0x0a404040 + ifunit); wo->accept_local = 1; ask_for_local = 0; /* don't tell the peer this address */ } if (!sifaddr(u, wo->ouraddr, wo->hisaddr, GetMask(wo->ouraddr))) return 0; ipcp_script(PPP_PATH_IPPREUP, 1); if (!sifup(u)) return 0; if (!sifnpmode(u, PPP_IP, NPMODE_QUEUE)) return 0; if (wo->default_route) if (sifdefaultroute(u, wo->ouraddr, wo->hisaddr, wo->replace_default_route)) default_route_set[u] = 1; if (wo->proxy_arp) if (sifproxyarp(u, wo->hisaddr)) proxy_arp_set[u] = 1; notice("local IP address %I", wo->ouraddr); if (wo->hisaddr) notice("remote IP address %I", wo->hisaddr); return 1; } /* * ipcp_up - IPCP has come UP. * * Configure the IP network interface appropriately and bring it up. */ static void ipcp_up(fsm *f) { u_int32_t mask; ipcp_options *ho = &ipcp_hisoptions[f->unit]; ipcp_options *go = &ipcp_gotoptions[f->unit]; ipcp_options *wo = &ipcp_wantoptions[f->unit]; int ifindex; IPCPDEBUG(("ipcp: up")); /* * We must have a non-zero IP address for both ends of the link. */ if (wo->hisaddr && !wo->accept_remote && (!(ho->neg_addr || ho->old_addrs) || ho->hisaddr != wo->hisaddr)) { error("Peer refused to agree to his IP address"); ipcp_close(f->unit, "Refused his IP address"); return; } if (!ho->neg_addr && !ho->old_addrs) ho->hisaddr = wo->hisaddr; if (!(go->neg_addr || go->old_addrs) && (wo->neg_addr || wo->old_addrs) && wo->ouraddr != 0) { error("Peer refused to agree to our IP address"); ipcp_close(f->unit, "Refused our IP address"); return; } if (go->ouraddr == 0) { error("Could not determine local IP address"); ipcp_close(f->unit, "Could not determine local IP address"); return; } if (ho->hisaddr == 0 && !noremoteip) { ho->hisaddr = htonl(0x0a404040 + ifunit); warn("Could not determine remote IP address: defaulting to %I", ho->hisaddr); } ppp_script_setenv("IPLOCAL", ip_ntoa(go->ouraddr), 0); if (ho->hisaddr != 0) ppp_script_setenv("IPREMOTE", ip_ntoa(ho->hisaddr), 1); if (!go->req_dns1) go->dnsaddr[0] = 0; if (!go->req_dns2) go->dnsaddr[1] = 0; if (go->dnsaddr[0]) ppp_script_setenv("DNS1", ip_ntoa(go->dnsaddr[0]), 0); if (go->dnsaddr[1]) ppp_script_setenv("DNS2", ip_ntoa(go->dnsaddr[1]), 0); if (usepeerdns && (go->dnsaddr[0] || go->dnsaddr[1])) { ppp_script_setenv("USEPEERDNS", "1", 0); create_resolv(go->dnsaddr[0], go->dnsaddr[1]); } if (go->winsaddr[0]) ppp_script_setenv("WINS1", ip_ntoa(go->winsaddr[0]), 0); if (go->winsaddr[1]) ppp_script_setenv("WINS2", ip_ntoa(go->winsaddr[1]), 0); if (usepeerwins && (go->winsaddr[0] || go->winsaddr[1])) ppp_script_setenv("USEPEERWINS", "1", 0); /* * Check that the peer is allowed to use the IP address it wants. */ if (ho->hisaddr != 0 && !auth_ip_addr(f->unit, ho->hisaddr)) { error("Peer is not authorized to use remote address %I", ho->hisaddr); ipcp_close(f->unit, "Unauthorized remote IP address"); return; } /* set tcp compression */ sifvjcomp(f->unit, ho->neg_vj, ho->cflag, ho->maxslotindex); /* * If we are doing dial-on-demand, the interface is already * configured, so we put out any saved-up packets, then set the * interface to pass IP packets. */ if (demand) { if (go->ouraddr != wo->ouraddr || ho->hisaddr != wo->hisaddr) { ipcp_clear_addrs(f->unit, wo->ouraddr, wo->hisaddr, wo->replace_default_route); if (go->ouraddr != wo->ouraddr) { warn("Local IP address changed to %I", go->ouraddr); ppp_script_setenv("OLDIPLOCAL", ip_ntoa(wo->ouraddr), 0); wo->ouraddr = go->ouraddr; } else ppp_script_unsetenv("OLDIPLOCAL"); if (ho->hisaddr != wo->hisaddr) { warn("Remote IP address changed to %I", ho->hisaddr); if (wo->hisaddr != 0) ppp_script_setenv("OLDIPREMOTE", ip_ntoa(wo->hisaddr), 0); wo->hisaddr = ho->hisaddr; } else ppp_script_unsetenv("OLDIPREMOTE"); /* Set the interface to the new addresses */ mask = GetMask(go->ouraddr); if (!sifaddr(f->unit, go->ouraddr, ho->hisaddr, mask)) { if (debug) warn("Interface configuration failed"); ipcp_close(f->unit, "Interface configuration failed"); return; } /* assign a default route through the interface if required */ if (ipcp_wantoptions[f->unit].default_route) if (sifdefaultroute(f->unit, go->ouraddr, ho->hisaddr, wo->replace_default_route)) default_route_set[f->unit] = 1; /* Make a proxy ARP entry if requested. */ if (ho->hisaddr != 0 && ipcp_wantoptions[f->unit].proxy_arp) if (sifproxyarp(f->unit, ho->hisaddr)) proxy_arp_set[f->unit] = 1; } demand_rexmit(PPP_IP); sifnpmode(f->unit, PPP_IP, NPMODE_PASS); } else { /* * Set IP addresses and (if specified) netmask. */ mask = GetMask(go->ouraddr); #if !(defined(SVR4) && (defined(SNI) || defined(__USLC__))) if (!sifaddr(f->unit, go->ouraddr, ho->hisaddr, mask)) { if (debug) warn("Interface configuration failed"); ipcp_close(f->unit, "Interface configuration failed"); return; } #endif ifindex = if_nametoindex(ifname); /* run the pre-up script, if any, and wait for it to finish */ ipcp_script(PPP_PATH_IPPREUP, 1); /* check if preup script renamed the interface */ if (!if_indextoname(ifindex, ifname)) { error("Interface index %d failed to get renamed by a pre-up script", ifindex); ipcp_close(f->unit, "Interface configuration failed"); return; } /* bring the interface up for IP */ if (!sifup(f->unit)) { if (debug) warn("Interface failed to come up"); ipcp_close(f->unit, "Interface configuration failed"); return; } #if (defined(SVR4) && (defined(SNI) || defined(__USLC__))) if (!sifaddr(f->unit, go->ouraddr, ho->hisaddr, mask)) { if (debug) warn("Interface configuration failed"); ipcp_close(f->unit, "Interface configuration failed"); return; } #endif sifnpmode(f->unit, PPP_IP, NPMODE_PASS); /* assign a default route through the interface if required */ if (ipcp_wantoptions[f->unit].default_route) if (sifdefaultroute(f->unit, go->ouraddr, ho->hisaddr, wo->replace_default_route)) default_route_set[f->unit] = 1; /* Make a proxy ARP entry if requested. */ if (ho->hisaddr != 0 && ipcp_wantoptions[f->unit].proxy_arp) if (sifproxyarp(f->unit, ho->hisaddr)) proxy_arp_set[f->unit] = 1; ipcp_wantoptions[0].ouraddr = go->ouraddr; notice("local IP address %I", go->ouraddr); if (ho->hisaddr != 0) notice("remote IP address %I", ho->hisaddr); if (go->dnsaddr[0]) notice("primary DNS address %I", go->dnsaddr[0]); if (go->dnsaddr[1]) notice("secondary DNS address %I", go->dnsaddr[1]); } reset_link_stats(f->unit); np_up(f->unit, PPP_IP); ipcp_is_up = 1; notify(ip_up_notifier, 0); if (ip_up_hook) ip_up_hook(); /* * Execute the ip-up script, like this: * /etc/ppp/ip-up interface tty speed local-IP remote-IP */ if (ipcp_script_state == s_down && ipcp_script_pid == 0) { ipcp_script_state = s_up; ipcp_script(path_ipup, 0); } } /* * ipcp_down - IPCP has gone DOWN. * * Take the IP network interface down, clear its addresses * and delete routes through it. */ static void ipcp_down(fsm *f) { IPCPDEBUG(("ipcp: down")); /* XXX a bit IPv4-centric here, we only need to get the stats * before the interface is marked down. */ /* XXX more correct: we must get the stats before running the notifiers, * at least for the radius plugin */ ppp_get_link_stats(NULL); notify(ip_down_notifier, 0); if (ip_down_hook) ip_down_hook(); if (ipcp_is_up) { ipcp_is_up = 0; np_down(f->unit, PPP_IP); } sifvjcomp(f->unit, 0, 0, 0); print_link_stats(); /* _after_ running the notifiers and ip_down_hook(), * because print_link_stats() sets link_stats_valid * to 0 (zero) */ /* * If we are doing dial-on-demand, set the interface * to queue up outgoing packets (for now). */ if (demand) { sifnpmode(f->unit, PPP_IP, NPMODE_QUEUE); } else { sifnpmode(f->unit, PPP_IP, NPMODE_DROP); sifdown(f->unit); ipcp_clear_addrs(f->unit, ipcp_gotoptions[f->unit].ouraddr, ipcp_hisoptions[f->unit].hisaddr, 0); } /* Execute the ip-down script */ if (ipcp_script_state == s_up && ipcp_script_pid == 0) { ipcp_script_state = s_down; ipcp_script(path_ipdown, 0); } } /* * ipcp_clear_addrs() - clear the interface addresses, routes, * proxy arp entries, etc. */ static void ipcp_clear_addrs(int unit, u_int32_t ouraddr, u_int32_t hisaddr, bool replacedefaultroute) { if (proxy_arp_set[unit]) { cifproxyarp(unit, hisaddr); proxy_arp_set[unit] = 0; } /* If replacedefaultroute, sifdefaultroute will be called soon * with replacedefaultroute set and that will overwrite the current * default route. This is the case only when doing demand, otherwise * during demand, this cifdefaultroute would restore the old default * route which is not what we want in this case. In the non-demand * case, we'll delete the default route and restore the old if there * is one saved by an sifdefaultroute with replacedefaultroute. */ if (!replacedefaultroute && default_route_set[unit]) { cifdefaultroute(unit, ouraddr, hisaddr); default_route_set[unit] = 0; } cifaddr(unit, ouraddr, hisaddr); } /* * ipcp_finished - possibly shut down the lower layers. */ static void ipcp_finished(fsm *f) { if (ipcp_is_open) { ipcp_is_open = 0; np_finished(f->unit, PPP_IP); } } /* * ipcp_script_done - called when the ip-up or ip-down script * has finished. */ static void ipcp_script_done(void *arg) { ipcp_script_pid = 0; switch (ipcp_script_state) { case s_up: if (ipcp_fsm[0].state != OPENED) { ipcp_script_state = s_down; ipcp_script(path_ipdown, 0); } break; case s_down: if (ipcp_fsm[0].state == OPENED) { ipcp_script_state = s_up; ipcp_script(path_ipup, 0); } break; } } /* * ipcp_script - Execute a script with arguments * interface-name tty-name speed local-IP remote-IP. */ static void ipcp_script(char *script, int wait) { char strspeed[32], strlocal[32], strremote[32]; char *argv[8]; slprintf(strspeed, sizeof(strspeed), "%d", baud_rate); slprintf(strlocal, sizeof(strlocal), "%I", ipcp_gotoptions[0].ouraddr); slprintf(strremote, sizeof(strremote), "%I", ipcp_hisoptions[0].hisaddr); argv[0] = script; argv[1] = ifname; argv[2] = devnam; argv[3] = strspeed; argv[4] = strlocal; argv[5] = strremote; argv[6] = ipparam; argv[7] = NULL; if (wait) run_program(script, argv, 0, NULL, NULL, 1); else ipcp_script_pid = run_program(script, argv, 0, ipcp_script_done, NULL, 0); } /* * create_resolv - create the replacement resolv.conf file */ static void create_resolv(u_int32_t peerdns1, u_int32_t peerdns2) { FILE *f; f = fopen(PPP_PATH_RESOLV, "w"); if (f == NULL) { error("Failed to create %s: %m", PPP_PATH_RESOLV); return; } if (peerdns1) fprintf(f, "nameserver %s\n", ip_ntoa(peerdns1)); if (peerdns2 && peerdns2 != peerdns1) fprintf(f, "nameserver %s\n", ip_ntoa(peerdns2)); if (ferror(f)) error("Write failed to %s: %m", PPP_PATH_RESOLV); fclose(f); } /* * ipcp_printpkt - print the contents of an IPCP packet. */ static char *ipcp_codenames[] = { "ConfReq", "ConfAck", "ConfNak", "ConfRej", "TermReq", "TermAck", "CodeRej" }; static int ipcp_printpkt(u_char *p, int plen, void (*printer) (void *, char *, ...), void *arg) { int code, id, len, olen; u_char *pstart, *optend; u_short cishort; u_int32_t cilong; if (plen < HEADERLEN) return 0; pstart = p; GETCHAR(code, p); GETCHAR(id, p); GETSHORT(len, p); if (len < HEADERLEN || len > plen) return 0; if (code >= 1 && code <= sizeof(ipcp_codenames) / sizeof(char *)) printer(arg, " %s", ipcp_codenames[code-1]); else printer(arg, " code=0x%x", code); printer(arg, " id=0x%x", id); len -= HEADERLEN; switch (code) { case CONFREQ: case CONFACK: case CONFNAK: case CONFREJ: /* print option list */ while (len >= 2) { GETCHAR(code, p); GETCHAR(olen, p); p -= 2; if (olen < 2 || olen > len) { break; } printer(arg, " <"); len -= olen; optend = p + olen; switch (code) { case CI_ADDRS: if (olen == CILEN_ADDRS) { p += 2; GETLONG(cilong, p); printer(arg, "addrs %I", htonl(cilong)); GETLONG(cilong, p); printer(arg, " %I", htonl(cilong)); } break; case CI_COMPRESSTYPE: if (olen >= CILEN_COMPRESS) { p += 2; GETSHORT(cishort, p); printer(arg, "compress "); switch (cishort) { case IPCP_VJ_COMP: printer(arg, "VJ"); break; case IPCP_VJ_COMP_OLD: printer(arg, "old-VJ"); break; default: printer(arg, "0x%x", cishort); } } break; case CI_ADDR: if (olen == CILEN_ADDR) { p += 2; GETLONG(cilong, p); printer(arg, "addr %I", htonl(cilong)); } break; case CI_MS_DNS1: case CI_MS_DNS2: p += 2; GETLONG(cilong, p); printer(arg, "ms-dns%d %I", (code == CI_MS_DNS1? 1: 2), htonl(cilong)); break; case CI_MS_WINS1: case CI_MS_WINS2: p += 2; GETLONG(cilong, p); printer(arg, "ms-wins %I", htonl(cilong)); break; } while (p < optend) { GETCHAR(code, p); printer(arg, " %.2x", code); } printer(arg, ">"); } break; case TERMACK: case TERMREQ: if (len > 0 && *p >= ' ' && *p < 0x7f) { printer(arg, " "); print_string((char *)p, len, printer, arg); p += len; len = 0; } break; } /* print the rest of the bytes in the packet */ for (; len > 0; --len) { GETCHAR(code, p); printer(arg, " %.2x", code); } return p - pstart; } /* * ip_active_pkt - see if this IP packet is worth bringing the link up for. * We don't bring the link up for IP fragments or for TCP FIN packets * with no data. */ #define IP_HDRLEN 20 /* bytes */ #define IP_OFFMASK 0x1fff #ifndef IPPROTO_TCP #define IPPROTO_TCP 6 #endif #define TCP_HDRLEN 20 #define TH_FIN 0x01 /* * We use these macros because the IP header may be at an odd address, * and some compilers might use word loads to get th_off or ip_hl. */ #define net_short(x) (((x)[0] << 8) + (x)[1]) #define get_iphl(x) (((unsigned char *)(x))[0] & 0xF) #define get_ipoff(x) net_short((unsigned char *)(x) + 6) #define get_ipproto(x) (((unsigned char *)(x))[9]) #define get_tcpoff(x) (((unsigned char *)(x))[12] >> 4) #define get_tcpflags(x) (((unsigned char *)(x))[13]) static int ip_active_pkt(u_char *pkt, int len) { u_char *tcp; int hlen; len -= PPP_HDRLEN; pkt += PPP_HDRLEN; if (len < IP_HDRLEN) return 0; if ((get_ipoff(pkt) & IP_OFFMASK) != 0) return 0; if (get_ipproto(pkt) != IPPROTO_TCP) return 1; hlen = get_iphl(pkt) * 4; if (len < hlen + TCP_HDRLEN) return 0; tcp = pkt + hlen; if ((get_tcpflags(tcp) & TH_FIN) != 0 && len == hlen + get_tcpoff(tcp) * 4) return 0; return 1; } ppp-2.5.0/pppd/lcp.c0000644000175000017500000016605214353435407011145 00000000000000/* * lcp.c - PPP Link Control Protocol. * * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The name "Carnegie Mellon University" must not be used to * endorse or promote products derived from this software without * prior written permission. For permission or any legal * details, please contact * Office of Technology Transfer * Carnegie Mellon University * 5000 Forbes Avenue * Pittsburgh, PA 15213-3890 * (412) 268-4387, fax: (412) 268-7395 * tech-transfer@andrew.cmu.edu * * 4. Redistributions of any form whatsoever must retain the following * acknowledgment: * "This product includes software developed by Computing Services * at Carnegie Mellon University (http://www.cmu.edu/computing/)." * * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include "pppd-private.h" #include "options.h" #include "fsm.h" #include "lcp.h" #include "eap.h" #include "chap.h" #include "magic.h" #include "multilink.h" /* * When the link comes up we want to be able to wait for a short while, * or until seeing some input from the peer, before starting to send * configure-requests. We do this by delaying the fsm_lowerup call. */ /* steal a bit in fsm flags word */ #define DELAYED_UP 0x100 static void lcp_delayed_up(void *); /* * LCP-related command-line options. */ int lcp_echo_interval = 0; /* Interval between LCP echo-requests */ int lcp_echo_fails = 0; /* Tolerance to unanswered echo-requests */ bool lcp_echo_adaptive = 0; /* request echo only if the link was idle */ bool lax_recv = 0; /* accept control chars in asyncmap */ bool noendpoint = 0; /* don't send/accept endpoint discriminator */ static int noopt(char **); #ifdef PPP_WITH_MULTILINK static int setendpoint(char **); static void printendpoint(option_t *, void (*)(void *, char *, ...), void *); #endif /* PPP_WITH_MULTILINK */ static struct option lcp_option_list[] = { /* LCP options */ { "-all", o_special_noarg, (void *)noopt, "Don't request/allow any LCP options" }, { "noaccomp", o_bool, &lcp_wantoptions[0].neg_accompression, "Disable address/control compression", OPT_A2CLR, &lcp_allowoptions[0].neg_accompression }, { "-ac", o_bool, &lcp_wantoptions[0].neg_accompression, "Disable address/control compression", OPT_ALIAS | OPT_A2CLR, &lcp_allowoptions[0].neg_accompression }, { "asyncmap", o_uint32, &lcp_wantoptions[0].asyncmap, "Set asyncmap (for received packets)", OPT_OR, &lcp_wantoptions[0].neg_asyncmap }, { "-as", o_uint32, &lcp_wantoptions[0].asyncmap, "Set asyncmap (for received packets)", OPT_ALIAS | OPT_OR, &lcp_wantoptions[0].neg_asyncmap }, { "default-asyncmap", o_uint32, &lcp_wantoptions[0].asyncmap, "Disable asyncmap negotiation", OPT_OR | OPT_NOARG | OPT_VAL(~0U) | OPT_A2CLR, &lcp_allowoptions[0].neg_asyncmap }, { "-am", o_uint32, &lcp_wantoptions[0].asyncmap, "Disable asyncmap negotiation", OPT_ALIAS | OPT_OR | OPT_NOARG | OPT_VAL(~0U) | OPT_A2CLR, &lcp_allowoptions[0].neg_asyncmap }, { "nomagic", o_bool, &lcp_wantoptions[0].neg_magicnumber, "Disable magic number negotiation (looped-back line detection)", OPT_A2CLR, &lcp_allowoptions[0].neg_magicnumber }, { "-mn", o_bool, &lcp_wantoptions[0].neg_magicnumber, "Disable magic number negotiation (looped-back line detection)", OPT_ALIAS | OPT_A2CLR, &lcp_allowoptions[0].neg_magicnumber }, { "mru", o_int, &lcp_wantoptions[0].mru, "Set MRU (maximum received packet size) for negotiation", OPT_PRIO, &lcp_wantoptions[0].neg_mru }, { "default-mru", o_bool, &lcp_wantoptions[0].neg_mru, "Disable MRU negotiation (use default 1500)", OPT_PRIOSUB | OPT_A2CLR, &lcp_allowoptions[0].neg_mru }, { "-mru", o_bool, &lcp_wantoptions[0].neg_mru, "Disable MRU negotiation (use default 1500)", OPT_ALIAS | OPT_PRIOSUB | OPT_A2CLR, &lcp_allowoptions[0].neg_mru }, { "mtu", o_int, &lcp_allowoptions[0].mru, "Set our MTU", OPT_LIMITS, NULL, MAXMRU, MINMRU }, { "nopcomp", o_bool, &lcp_wantoptions[0].neg_pcompression, "Disable protocol field compression", OPT_A2CLR, &lcp_allowoptions[0].neg_pcompression }, { "-pc", o_bool, &lcp_wantoptions[0].neg_pcompression, "Disable protocol field compression", OPT_ALIAS | OPT_A2CLR, &lcp_allowoptions[0].neg_pcompression }, { "passive", o_bool, &lcp_wantoptions[0].passive, "Set passive mode", 1 }, { "-p", o_bool, &lcp_wantoptions[0].passive, "Set passive mode", OPT_ALIAS | 1 }, { "silent", o_bool, &lcp_wantoptions[0].silent, "Set silent mode", 1 }, { "lcp-echo-failure", o_int, &lcp_echo_fails, "Set number of consecutive echo failures to indicate link failure", OPT_PRIO }, { "lcp-echo-interval", o_int, &lcp_echo_interval, "Set time in seconds between LCP echo requests", OPT_PRIO }, { "lcp-echo-adaptive", o_bool, &lcp_echo_adaptive, "Suppress LCP echo requests if traffic was received", 1 }, { "lcp-restart", o_int, &lcp_fsm[0].timeouttime, "Set time in seconds between LCP retransmissions", OPT_PRIO }, { "lcp-max-terminate", o_int, &lcp_fsm[0].maxtermtransmits, "Set maximum number of LCP terminate-request transmissions", OPT_PRIO }, { "lcp-max-configure", o_int, &lcp_fsm[0].maxconfreqtransmits, "Set maximum number of LCP configure-request transmissions", OPT_PRIO }, { "lcp-max-failure", o_int, &lcp_fsm[0].maxnakloops, "Set limit on number of LCP configure-naks", OPT_PRIO }, { "receive-all", o_bool, &lax_recv, "Accept all received control characters", 1 }, #ifdef PPP_WITH_MULTILINK { "mrru", o_int, &lcp_wantoptions[0].mrru, "Maximum received packet size for multilink bundle", OPT_PRIO, &lcp_wantoptions[0].neg_mrru }, { "mpshortseq", o_bool, &lcp_wantoptions[0].neg_ssnhf, "Use short sequence numbers in multilink headers", OPT_PRIO | 1, &lcp_allowoptions[0].neg_ssnhf }, { "nompshortseq", o_bool, &lcp_wantoptions[0].neg_ssnhf, "Don't use short sequence numbers in multilink headers", OPT_PRIOSUB | OPT_A2CLR, &lcp_allowoptions[0].neg_ssnhf }, { "endpoint", o_special, (void *) setendpoint, "Endpoint discriminator for multilink", OPT_PRIO | OPT_A2PRINTER, (void *) printendpoint }, #endif /* PPP_WITH_MULTILINK */ { "noendpoint", o_bool, &noendpoint, "Don't send or accept multilink endpoint discriminator", 1 }, {NULL} }; /* global vars */ fsm lcp_fsm[NUM_PPP]; /* LCP fsm structure (global)*/ lcp_options lcp_wantoptions[NUM_PPP]; /* Options that we want to request */ lcp_options lcp_gotoptions[NUM_PPP]; /* Options that peer ack'd */ lcp_options lcp_allowoptions[NUM_PPP]; /* Options we allow peer to request */ lcp_options lcp_hisoptions[NUM_PPP]; /* Options that we ack'd */ static int lcp_echos_pending = 0; /* Number of outstanding echo msgs */ static int lcp_echo_number = 0; /* ID number of next echo frame */ static int lcp_echo_timer_running = 0; /* set if a timer is running */ static u_char nak_buffer[PPP_MRU]; /* where we construct a nak packet */ /* * Callbacks for fsm code. (CI = Configuration Information) */ static void lcp_resetci(fsm *); /* Reset our CI */ static int lcp_cilen(fsm *); /* Return length of our CI */ static void lcp_addci(fsm *, u_char *, int *); /* Add our CI to pkt */ static int lcp_ackci(fsm *, u_char *, int); /* Peer ack'd our CI */ static int lcp_nakci(fsm *, u_char *, int, int); /* Peer nak'd our CI */ static int lcp_rejci(fsm *, u_char *, int); /* Peer rej'd our CI */ static int lcp_reqci(fsm *, u_char *, int *, int); /* Rcv peer CI */ static void lcp_up(fsm *); /* We're UP */ static void lcp_down(fsm *); /* We're DOWN */ static void lcp_starting(fsm *); /* We need lower layer up */ static void lcp_finished(fsm *); /* We need lower layer down */ static int lcp_extcode(fsm *, int, int, u_char *, int); static void lcp_rprotrej(fsm *, u_char *, int); /* * routines to send LCP echos to peer */ static void lcp_echo_lowerup(int); static void lcp_echo_lowerdown(int); static void LcpEchoTimeout(void *); static void lcp_received_echo_reply(fsm *, int, u_char *, int); static void LcpSendEchoRequest(fsm *); static void LcpLinkFailure(fsm *); static void LcpEchoCheck(fsm *); static fsm_callbacks lcp_callbacks = { /* LCP callback routines */ lcp_resetci, /* Reset our Configuration Information */ lcp_cilen, /* Length of our Configuration Information */ lcp_addci, /* Add our Configuration Information */ lcp_ackci, /* ACK our Configuration Information */ lcp_nakci, /* NAK our Configuration Information */ lcp_rejci, /* Reject our Configuration Information */ lcp_reqci, /* Request peer's Configuration Information */ lcp_up, /* Called when fsm reaches OPENED state */ lcp_down, /* Called when fsm leaves OPENED state */ lcp_starting, /* Called when we want the lower layer up */ lcp_finished, /* Called when we want the lower layer down */ NULL, /* Called when Protocol-Reject received */ NULL, /* Retransmission is necessary */ lcp_extcode, /* Called to handle LCP-specific codes */ "LCP" /* String name of protocol */ }; /* * Protocol entry points. * Some of these are called directly. */ static void lcp_init(int); static void lcp_input(int, u_char *, int); static void lcp_protrej(int); static int lcp_printpkt(u_char *, int, void (*)(void *, char *, ...), void *); struct protent lcp_protent = { PPP_LCP, lcp_init, lcp_input, lcp_protrej, lcp_lowerup, lcp_lowerdown, lcp_open, lcp_close, lcp_printpkt, NULL, 1, "LCP", NULL, lcp_option_list, NULL, NULL, NULL }; int lcp_loopbackfail = DEFLOOPBACKFAIL; /* * Length of each type of configuration option (in octets) */ #define CILEN_VOID 2 #define CILEN_CHAR 3 #define CILEN_SHORT 4 /* CILEN_VOID + 2 */ #define CILEN_CHAP 5 /* CILEN_VOID + 2 + 1 */ #define CILEN_LONG 6 /* CILEN_VOID + 4 */ #define CILEN_LQR 8 /* CILEN_VOID + 2 + 4 */ #define CILEN_CBCP 3 #define CODENAME(x) ((x) == CONFACK ? "ACK" : \ (x) == CONFNAK ? "NAK" : "REJ") /* * noopt - Disable all options (why?). */ static int noopt(char **argv) { BZERO((char *) &lcp_wantoptions[0], sizeof (struct lcp_options)); BZERO((char *) &lcp_allowoptions[0], sizeof (struct lcp_options)); return (1); } #ifdef PPP_WITH_MULTILINK static int setendpoint(char **argv) { if (str_to_epdisc(&lcp_wantoptions[0].endpoint, *argv)) { lcp_wantoptions[0].neg_endpoint = 1; return 1; } ppp_option_error("Can't parse '%s' as an endpoint discriminator", *argv); return 0; } static void printendpoint(option_t *opt, void (*printer)(void *, char *, ...), void *arg) { printer(arg, "%s", epdisc_to_str(&lcp_wantoptions[0].endpoint)); } #endif /* PPP_WITH_MULTILINK */ /* * lcp_init - Initialize LCP. */ static void lcp_init(int unit) { fsm *f = &lcp_fsm[unit]; lcp_options *wo = &lcp_wantoptions[unit]; lcp_options *ao = &lcp_allowoptions[unit]; f->unit = unit; f->protocol = PPP_LCP; f->callbacks = &lcp_callbacks; fsm_init(f); BZERO(wo, sizeof(*wo)); wo->neg_mru = 1; wo->mru = DEFMRU; wo->neg_asyncmap = 1; wo->neg_magicnumber = 1; wo->neg_pcompression = 1; wo->neg_accompression = 1; BZERO(ao, sizeof(*ao)); ao->neg_mru = 1; ao->mru = MAXMRU; ao->neg_asyncmap = 1; ao->neg_chap = 1; ao->chap_mdtype = chap_mdtype_all; ao->neg_upap = 1; ao->neg_eap = 1; ao->neg_magicnumber = 1; ao->neg_pcompression = 1; ao->neg_accompression = 1; ao->neg_endpoint = 1; } /* * lcp_open - LCP is allowed to come up. */ void lcp_open(int unit) { fsm *f = &lcp_fsm[unit]; lcp_options *wo = &lcp_wantoptions[unit]; f->flags &= ~(OPT_PASSIVE | OPT_SILENT); if (wo->passive) f->flags |= OPT_PASSIVE; if (wo->silent) f->flags |= OPT_SILENT; fsm_open(f); } /* * lcp_close - Take LCP down. */ void lcp_close(int unit, char *reason) { fsm *f = &lcp_fsm[unit]; int oldstate; if (!in_phase(PHASE_DEAD) && !in_phase(PHASE_MASTER)) new_phase(PHASE_TERMINATE); if (f->flags & DELAYED_UP) { UNTIMEOUT(lcp_delayed_up, f); f->state = STOPPED; } oldstate = f->state; fsm_close(f, reason); if (oldstate == STOPPED && f->flags & (OPT_PASSIVE|OPT_SILENT|DELAYED_UP)) { /* * This action is not strictly according to the FSM in RFC1548, * but it does mean that the program terminates if you do a * lcp_close() when a connection hasn't been established * because we are in passive/silent mode or because we have * delayed the fsm_lowerup() call and it hasn't happened yet. */ f->flags &= ~DELAYED_UP; lcp_finished(f); } } /* * lcp_lowerup - The lower layer is up. */ void lcp_lowerup(int unit) { lcp_options *wo = &lcp_wantoptions[unit]; fsm *f = &lcp_fsm[unit]; /* * Don't use A/C or protocol compression on transmission, * but accept A/C and protocol compressed packets * if we are going to ask for A/C and protocol compression. */ if (ppp_send_config(unit, PPP_MRU, 0xffffffff, 0, 0) < 0 || ppp_recv_config(unit, PPP_MRU, (lax_recv? 0: 0xffffffff), wo->neg_pcompression, wo->neg_accompression) < 0) return; peer_mru[unit] = PPP_MRU; if (listen_time != 0) { f->flags |= DELAYED_UP; ppp_timeout(lcp_delayed_up, f, 0, listen_time * 1000); } else fsm_lowerup(f); } /* * lcp_lowerdown - The lower layer is down. */ void lcp_lowerdown(int unit) { fsm *f = &lcp_fsm[unit]; if (f->flags & DELAYED_UP) { f->flags &= ~DELAYED_UP; UNTIMEOUT(lcp_delayed_up, f); } else fsm_lowerdown(&lcp_fsm[unit]); } /* * lcp_delayed_up - Bring the lower layer up now. */ static void lcp_delayed_up(void *arg) { fsm *f = arg; if (f->flags & DELAYED_UP) { f->flags &= ~DELAYED_UP; fsm_lowerup(f); } } /* * lcp_input - Input LCP packet. */ static void lcp_input(int unit, u_char *p, int len) { fsm *f = &lcp_fsm[unit]; if (f->flags & DELAYED_UP) { f->flags &= ~DELAYED_UP; UNTIMEOUT(lcp_delayed_up, f); fsm_lowerup(f); } fsm_input(f, p, len); } /* * lcp_extcode - Handle a LCP-specific code. */ static int lcp_extcode(fsm *f, int code, int id, u_char *inp, int len) { u_char *magp; switch( code ){ case PROTREJ: lcp_rprotrej(f, inp, len); break; case ECHOREQ: if (f->state != OPENED) break; magp = inp; PUTLONG(lcp_gotoptions[f->unit].magicnumber, magp); fsm_sdata(f, ECHOREP, id, inp, len); break; case ECHOREP: lcp_received_echo_reply(f, id, inp, len); break; case DISCREQ: case IDENTIF: case TIMEREM: break; default: return 0; } return 1; } /* * lcp_rprotrej - Receive an Protocol-Reject. * * Figure out which protocol is rejected and inform it. */ static void lcp_rprotrej(fsm *f, u_char *inp, int len) { int i; struct protent *protp; u_short prot; const char *pname; if (len < 2) { LCPDEBUG(("lcp_rprotrej: Rcvd short Protocol-Reject packet!")); return; } GETSHORT(prot, inp); /* * Protocol-Reject packets received in any state other than the LCP * OPENED state SHOULD be silently discarded. */ if( f->state != OPENED ){ LCPDEBUG(("Protocol-Reject discarded: LCP in state %d", f->state)); return; } pname = protocol_name(prot); /* * Upcall the proper Protocol-Reject routine. */ for (i = 0; (protp = protocols[i]) != NULL; ++i) if (protp->protocol == prot && protp->enabled_flag) { if (pname == NULL) dbglog("Protocol-Reject for 0x%x received", prot); else dbglog("Protocol-Reject for '%s' (0x%x) received", pname, prot); (*protp->protrej)(f->unit); return; } if (pname == NULL) warn("Protocol-Reject for unsupported protocol 0x%x", prot); else warn("Protocol-Reject for unsupported protocol '%s' (0x%x)", pname, prot); } /* * lcp_protrej - A Protocol-Reject was received. */ /*ARGSUSED*/ static void lcp_protrej(int unit) { /* * Can't reject LCP! */ error("Received Protocol-Reject for LCP!"); fsm_protreject(&lcp_fsm[unit]); } /* * lcp_sprotrej - Send a Protocol-Reject for some protocol. */ void lcp_sprotrej(int unit, u_char *p, int len) { /* * Send back the protocol and the information field of the * rejected packet. We only get here if LCP is in the OPENED state. */ p += 2; len -= 2; fsm_sdata(&lcp_fsm[unit], PROTREJ, ++lcp_fsm[unit].id, p, len); } /* * lcp_resetci - Reset our CI. */ static void lcp_resetci(fsm *f) { lcp_options *wo = &lcp_wantoptions[f->unit]; lcp_options *go = &lcp_gotoptions[f->unit]; lcp_options *ao = &lcp_allowoptions[f->unit]; wo->magicnumber = magic(); wo->numloops = 0; *go = *wo; if (!multilink) { go->neg_mrru = 0; go->neg_ssnhf = 0; go->neg_endpoint = 0; } if (noendpoint) ao->neg_endpoint = 0; peer_mru[f->unit] = PPP_MRU; auth_reset(f->unit); } /* * lcp_cilen - Return length of our CI. */ static int lcp_cilen(fsm *f) { lcp_options *go = &lcp_gotoptions[f->unit]; #define LENCIVOID(neg) ((neg) ? CILEN_VOID : 0) #define LENCICHAP(neg) ((neg) ? CILEN_CHAP : 0) #define LENCISHORT(neg) ((neg) ? CILEN_SHORT : 0) #define LENCILONG(neg) ((neg) ? CILEN_LONG : 0) #define LENCILQR(neg) ((neg) ? CILEN_LQR: 0) #define LENCICBCP(neg) ((neg) ? CILEN_CBCP: 0) /* * NB: we only ask for one of CHAP, UPAP, or EAP, even if we will * accept more than one. We prefer EAP first, then CHAP, then * PAP. */ return (LENCISHORT(go->neg_mru && go->mru != DEFMRU) + LENCILONG(go->neg_asyncmap && go->asyncmap != 0xFFFFFFFF) + LENCISHORT(go->neg_eap) + LENCICHAP(!go->neg_eap && go->neg_chap) + LENCISHORT(!go->neg_eap && !go->neg_chap && go->neg_upap) + LENCILQR(go->neg_lqr) + LENCICBCP(go->neg_cbcp) + LENCILONG(go->neg_magicnumber) + LENCIVOID(go->neg_pcompression) + LENCIVOID(go->neg_accompression) + LENCISHORT(go->neg_mrru) + LENCIVOID(go->neg_ssnhf) + (go->neg_endpoint? CILEN_CHAR + go->endpoint.length: 0)); } /* * lcp_addci - Add our desired CIs to a packet. */ static void lcp_addci(fsm *f, u_char *ucp, int *lenp) { lcp_options *go = &lcp_gotoptions[f->unit]; u_char *start_ucp = ucp; #define ADDCIVOID(opt, neg) \ if (neg) { \ PUTCHAR(opt, ucp); \ PUTCHAR(CILEN_VOID, ucp); \ } #define ADDCISHORT(opt, neg, val) \ if (neg) { \ PUTCHAR(opt, ucp); \ PUTCHAR(CILEN_SHORT, ucp); \ PUTSHORT(val, ucp); \ } #define ADDCICHAP(opt, neg, val) \ if (neg) { \ PUTCHAR((opt), ucp); \ PUTCHAR(CILEN_CHAP, ucp); \ PUTSHORT(PPP_CHAP, ucp); \ PUTCHAR((CHAP_DIGEST(val)), ucp); \ } #define ADDCILONG(opt, neg, val) \ if (neg) { \ PUTCHAR(opt, ucp); \ PUTCHAR(CILEN_LONG, ucp); \ PUTLONG(val, ucp); \ } #define ADDCILQR(opt, neg, val) \ if (neg) { \ PUTCHAR(opt, ucp); \ PUTCHAR(CILEN_LQR, ucp); \ PUTSHORT(PPP_LQR, ucp); \ PUTLONG(val, ucp); \ } #define ADDCICHAR(opt, neg, val) \ if (neg) { \ PUTCHAR(opt, ucp); \ PUTCHAR(CILEN_CHAR, ucp); \ PUTCHAR(val, ucp); \ } #define ADDCIENDP(opt, neg, class, val, len) \ if (neg) { \ int i; \ PUTCHAR(opt, ucp); \ PUTCHAR(CILEN_CHAR + len, ucp); \ PUTCHAR(class, ucp); \ for (i = 0; i < len; ++i) \ PUTCHAR(val[i], ucp); \ } ADDCISHORT(CI_MRU, go->neg_mru && go->mru != DEFMRU, go->mru); ADDCILONG(CI_ASYNCMAP, go->neg_asyncmap && go->asyncmap != 0xFFFFFFFF, go->asyncmap); ADDCISHORT(CI_AUTHTYPE, go->neg_eap, PPP_EAP); ADDCICHAP(CI_AUTHTYPE, !go->neg_eap && go->neg_chap, go->chap_mdtype); ADDCISHORT(CI_AUTHTYPE, !go->neg_eap && !go->neg_chap && go->neg_upap, PPP_PAP); ADDCILQR(CI_QUALITY, go->neg_lqr, go->lqr_period); ADDCICHAR(CI_CALLBACK, go->neg_cbcp, CBCP_OPT); ADDCILONG(CI_MAGICNUMBER, go->neg_magicnumber, go->magicnumber); ADDCIVOID(CI_PCOMPRESSION, go->neg_pcompression); ADDCIVOID(CI_ACCOMPRESSION, go->neg_accompression); ADDCISHORT(CI_MRRU, go->neg_mrru, go->mrru); ADDCIVOID(CI_SSNHF, go->neg_ssnhf); ADDCIENDP(CI_EPDISC, go->neg_endpoint, go->endpoint.class, go->endpoint.value, go->endpoint.length); if (ucp - start_ucp != *lenp) { /* this should never happen, because peer_mtu should be 1500 */ error("Bug in lcp_addci: wrong length"); } } /* * lcp_ackci - Ack our CIs. * This should not modify any state if the Ack is bad. * * Returns: * 0 - Ack was bad. * 1 - Ack was good. */ static int lcp_ackci(fsm *f, u_char *p, int len) { lcp_options *go = &lcp_gotoptions[f->unit]; u_char cilen, citype, cichar; u_short cishort; u_int32_t cilong; /* * CIs must be in exactly the same order that we sent. * Check packet length and CI length at each step. * If we find any deviations, then this packet is bad. */ #define ACKCIVOID(opt, neg) \ if (neg) { \ if ((len -= CILEN_VOID) < 0) \ goto bad; \ GETCHAR(citype, p); \ GETCHAR(cilen, p); \ if (cilen != CILEN_VOID || \ citype != opt) \ goto bad; \ } #define ACKCISHORT(opt, neg, val) \ if (neg) { \ if ((len -= CILEN_SHORT) < 0) \ goto bad; \ GETCHAR(citype, p); \ GETCHAR(cilen, p); \ if (cilen != CILEN_SHORT || \ citype != opt) \ goto bad; \ GETSHORT(cishort, p); \ if (cishort != val) \ goto bad; \ } #define ACKCICHAR(opt, neg, val) \ if (neg) { \ if ((len -= CILEN_CHAR) < 0) \ goto bad; \ GETCHAR(citype, p); \ GETCHAR(cilen, p); \ if (cilen != CILEN_CHAR || \ citype != opt) \ goto bad; \ GETCHAR(cichar, p); \ if (cichar != val) \ goto bad; \ } #define ACKCICHAP(opt, neg, val) \ if (neg) { \ if ((len -= CILEN_CHAP) < 0) \ goto bad; \ GETCHAR(citype, p); \ GETCHAR(cilen, p); \ if (cilen != CILEN_CHAP || \ citype != (opt)) \ goto bad; \ GETSHORT(cishort, p); \ if (cishort != PPP_CHAP) \ goto bad; \ GETCHAR(cichar, p); \ if (cichar != (CHAP_DIGEST(val))) \ goto bad; \ } #define ACKCILONG(opt, neg, val) \ if (neg) { \ if ((len -= CILEN_LONG) < 0) \ goto bad; \ GETCHAR(citype, p); \ GETCHAR(cilen, p); \ if (cilen != CILEN_LONG || \ citype != opt) \ goto bad; \ GETLONG(cilong, p); \ if (cilong != val) \ goto bad; \ } #define ACKCILQR(opt, neg, val) \ if (neg) { \ if ((len -= CILEN_LQR) < 0) \ goto bad; \ GETCHAR(citype, p); \ GETCHAR(cilen, p); \ if (cilen != CILEN_LQR || \ citype != opt) \ goto bad; \ GETSHORT(cishort, p); \ if (cishort != PPP_LQR) \ goto bad; \ GETLONG(cilong, p); \ if (cilong != val) \ goto bad; \ } #define ACKCIENDP(opt, neg, class, val, vlen) \ if (neg) { \ int i; \ if ((len -= CILEN_CHAR + vlen) < 0) \ goto bad; \ GETCHAR(citype, p); \ GETCHAR(cilen, p); \ if (cilen != CILEN_CHAR + vlen || \ citype != opt) \ goto bad; \ GETCHAR(cichar, p); \ if (cichar != class) \ goto bad; \ for (i = 0; i < vlen; ++i) { \ GETCHAR(cichar, p); \ if (cichar != val[i]) \ goto bad; \ } \ } ACKCISHORT(CI_MRU, go->neg_mru && go->mru != DEFMRU, go->mru); ACKCILONG(CI_ASYNCMAP, go->neg_asyncmap && go->asyncmap != 0xFFFFFFFF, go->asyncmap); ACKCISHORT(CI_AUTHTYPE, go->neg_eap, PPP_EAP); ACKCICHAP(CI_AUTHTYPE, !go->neg_eap && go->neg_chap, go->chap_mdtype); ACKCISHORT(CI_AUTHTYPE, !go->neg_eap && !go->neg_chap && go->neg_upap, PPP_PAP); ACKCILQR(CI_QUALITY, go->neg_lqr, go->lqr_period); ACKCICHAR(CI_CALLBACK, go->neg_cbcp, CBCP_OPT); ACKCILONG(CI_MAGICNUMBER, go->neg_magicnumber, go->magicnumber); ACKCIVOID(CI_PCOMPRESSION, go->neg_pcompression); ACKCIVOID(CI_ACCOMPRESSION, go->neg_accompression); ACKCISHORT(CI_MRRU, go->neg_mrru, go->mrru); ACKCIVOID(CI_SSNHF, go->neg_ssnhf); ACKCIENDP(CI_EPDISC, go->neg_endpoint, go->endpoint.class, go->endpoint.value, go->endpoint.length); /* * If there are any remaining CIs, then this packet is bad. */ if (len != 0) goto bad; return (1); bad: LCPDEBUG(("lcp_acki: received bad Ack!")); return (0); } /* * lcp_nakci - Peer has sent a NAK for some of our CIs. * This should not modify any state if the Nak is bad * or if LCP is in the OPENED state. * * Returns: * 0 - Nak was bad. * 1 - Nak was good. */ static int lcp_nakci(fsm *f, u_char *p, int len, int treat_as_reject) { lcp_options *go = &lcp_gotoptions[f->unit]; lcp_options *wo = &lcp_wantoptions[f->unit]; u_char citype, cichar, *next; u_short cishort; u_int32_t cilong; lcp_options no; /* options we've seen Naks for */ lcp_options try; /* options to request next time */ int looped_back = 0; int cilen; BZERO(&no, sizeof(no)); try = *go; /* * Any Nak'd CIs must be in exactly the same order that we sent. * Check packet length and CI length at each step. * If we find any deviations, then this packet is bad. */ #define NAKCIVOID(opt, neg) \ if (go->neg && \ len >= CILEN_VOID && \ p[1] == CILEN_VOID && \ p[0] == opt) { \ len -= CILEN_VOID; \ INCPTR(CILEN_VOID, p); \ no.neg = 1; \ try.neg = 0; \ } #define NAKCICHAP(opt, neg, code) \ if (go->neg && \ len >= CILEN_CHAP && \ p[1] == CILEN_CHAP && \ p[0] == opt) { \ len -= CILEN_CHAP; \ INCPTR(2, p); \ GETSHORT(cishort, p); \ GETCHAR(cichar, p); \ no.neg = 1; \ code \ } #define NAKCICHAR(opt, neg, code) \ if (go->neg && \ len >= CILEN_CHAR && \ p[1] == CILEN_CHAR && \ p[0] == opt) { \ len -= CILEN_CHAR; \ INCPTR(2, p); \ GETCHAR(cichar, p); \ no.neg = 1; \ code \ } #define NAKCISHORT(opt, neg, code) \ if (go->neg && \ len >= CILEN_SHORT && \ p[1] == CILEN_SHORT && \ p[0] == opt) { \ len -= CILEN_SHORT; \ INCPTR(2, p); \ GETSHORT(cishort, p); \ no.neg = 1; \ code \ } #define NAKCILONG(opt, neg, code) \ if (go->neg && \ len >= CILEN_LONG && \ p[1] == CILEN_LONG && \ p[0] == opt) { \ len -= CILEN_LONG; \ INCPTR(2, p); \ GETLONG(cilong, p); \ no.neg = 1; \ code \ } #define NAKCILQR(opt, neg, code) \ if (go->neg && \ len >= CILEN_LQR && \ p[1] == CILEN_LQR && \ p[0] == opt) { \ len -= CILEN_LQR; \ INCPTR(2, p); \ GETSHORT(cishort, p); \ GETLONG(cilong, p); \ no.neg = 1; \ code \ } #define NAKCIENDP(opt, neg) \ if (go->neg && \ len >= CILEN_CHAR && \ p[0] == opt && \ p[1] >= CILEN_CHAR && \ p[1] <= len) { \ len -= p[1]; \ INCPTR(p[1], p); \ no.neg = 1; \ try.neg = 0; \ } /* * NOTE! There must be no assignments to individual fields of *go in * the code below. Any such assignment is a BUG! */ /* * We don't care if they want to send us smaller packets than * we want. Therefore, accept any MRU less than what we asked for, * but then ignore the new value when setting the MRU in the kernel. * If they send us a bigger MRU than what we asked, accept it, up to * the limit of the default MRU we'd get if we didn't negotiate. */ if (go->neg_mru && go->mru != DEFMRU) { NAKCISHORT(CI_MRU, neg_mru, if (cishort <= wo->mru || cishort <= DEFMRU) try.mru = cishort; ); } /* * Add any characters they want to our (receive-side) asyncmap. */ if (go->neg_asyncmap && go->asyncmap != 0xFFFFFFFF) { NAKCILONG(CI_ASYNCMAP, neg_asyncmap, try.asyncmap = go->asyncmap | cilong; ); } /* * If they've nak'd our authentication-protocol, check whether * they are proposing a different protocol, or a different * hash algorithm for CHAP. */ if ((go->neg_chap || go->neg_upap || go->neg_eap) && len >= CILEN_SHORT && p[0] == CI_AUTHTYPE && p[1] >= CILEN_SHORT && p[1] <= len) { cilen = p[1]; len -= cilen; no.neg_chap = go->neg_chap; no.neg_upap = go->neg_upap; no.neg_eap = go->neg_eap; INCPTR(2, p); GETSHORT(cishort, p); if (cishort == PPP_PAP && cilen == CILEN_SHORT) { /* If we were asking for EAP, then we need to stop that. */ if (go->neg_eap) try.neg_eap = 0; /* If we were asking for CHAP, then we need to stop that. */ else if (go->neg_chap) try.neg_chap = 0; /* * If we weren't asking for CHAP or EAP, then we were asking for * PAP, in which case this Nak is bad. */ else goto bad; } else if (cishort == PPP_CHAP && cilen == CILEN_CHAP) { GETCHAR(cichar, p); /* Stop asking for EAP, if we were. */ if (go->neg_eap) { try.neg_eap = 0; /* Try to set up to use their suggestion, if possible */ if (CHAP_CANDIGEST(go->chap_mdtype, cichar)) try.chap_mdtype = CHAP_MDTYPE_D(cichar); } else if (go->neg_chap) { /* * We were asking for our preferred algorithm, they must * want something different. */ if (cichar != CHAP_DIGEST(go->chap_mdtype)) { if (CHAP_CANDIGEST(go->chap_mdtype, cichar)) { /* Use their suggestion if we support it ... */ try.chap_mdtype = CHAP_MDTYPE_D(cichar); } else { /* ... otherwise, try our next-preferred algorithm. */ try.chap_mdtype &= ~(CHAP_MDTYPE(try.chap_mdtype)); if (try.chap_mdtype == MDTYPE_NONE) /* out of algos */ try.neg_chap = 0; } } else { /* * Whoops, they Nak'd our algorithm of choice * but then suggested it back to us. */ goto bad; } } else { /* * Stop asking for PAP if we were asking for it. */ try.neg_upap = 0; } } else { /* * If we were asking for EAP, and they're Conf-Naking EAP, * well, that's just strange. Nobody should do that. */ if (cishort == PPP_EAP && cilen == CILEN_SHORT && go->neg_eap) dbglog("Unexpected Conf-Nak for EAP"); /* * We don't recognize what they're suggesting. * Stop asking for what we were asking for. */ if (go->neg_eap) try.neg_eap = 0; else if (go->neg_chap) try.neg_chap = 0; else try.neg_upap = 0; p += cilen - CILEN_SHORT; } } /* * If they can't cope with our link quality protocol, we'll have * to stop asking for LQR. We haven't got any other protocol. * If they Nak the reporting period, take their value XXX ? */ NAKCILQR(CI_QUALITY, neg_lqr, if (cishort != PPP_LQR) try.neg_lqr = 0; else try.lqr_period = cilong; ); /* * Only implementing CBCP...not the rest of the callback options */ NAKCICHAR(CI_CALLBACK, neg_cbcp, try.neg_cbcp = 0; ); /* * Check for a looped-back line. */ NAKCILONG(CI_MAGICNUMBER, neg_magicnumber, try.magicnumber = magic(); looped_back = 1; ); /* * Peer shouldn't send Nak for protocol compression or * address/control compression requests; they should send * a Reject instead. If they send a Nak, treat it as a Reject. */ NAKCIVOID(CI_PCOMPRESSION, neg_pcompression); NAKCIVOID(CI_ACCOMPRESSION, neg_accompression); /* * Nak for MRRU option - accept their value if it is smaller * than the one we want. */ if (go->neg_mrru) { NAKCISHORT(CI_MRRU, neg_mrru, if (treat_as_reject) try.neg_mrru = 0; else if (cishort <= wo->mrru) try.mrru = cishort; ); } /* * Nak for short sequence numbers shouldn't be sent, treat it * like a reject. */ NAKCIVOID(CI_SSNHF, neg_ssnhf); /* * Nak of the endpoint discriminator option is not permitted, * treat it like a reject. */ NAKCIENDP(CI_EPDISC, neg_endpoint); /* * There may be remaining CIs, if the peer is requesting negotiation * on an option that we didn't include in our request packet. * If we see an option that we requested, or one we've already seen * in this packet, then this packet is bad. * If we wanted to respond by starting to negotiate on the requested * option(s), we could, but we don't, because except for the * authentication type and quality protocol, if we are not negotiating * an option, it is because we were told not to. * For the authentication type, the Nak from the peer means * `let me authenticate myself with you' which is a bit pointless. * For the quality protocol, the Nak means `ask me to send you quality * reports', but if we didn't ask for them, we don't want them. * An option we don't recognize represents the peer asking to * negotiate some option we don't support, so ignore it. */ while (len >= CILEN_VOID) { GETCHAR(citype, p); GETCHAR(cilen, p); if (cilen < CILEN_VOID || (len -= cilen) < 0) goto bad; next = p + cilen - 2; switch (citype) { case CI_MRU: if ((go->neg_mru && go->mru != DEFMRU) || no.neg_mru || cilen != CILEN_SHORT) goto bad; GETSHORT(cishort, p); if (cishort < DEFMRU) { try.neg_mru = 1; try.mru = cishort; } break; case CI_ASYNCMAP: if ((go->neg_asyncmap && go->asyncmap != 0xFFFFFFFF) || no.neg_asyncmap || cilen != CILEN_LONG) goto bad; break; case CI_AUTHTYPE: if (go->neg_chap || no.neg_chap || go->neg_upap || no.neg_upap || go->neg_eap || no.neg_eap) goto bad; break; case CI_MAGICNUMBER: if (go->neg_magicnumber || no.neg_magicnumber || cilen != CILEN_LONG) goto bad; break; case CI_PCOMPRESSION: if (go->neg_pcompression || no.neg_pcompression || cilen != CILEN_VOID) goto bad; break; case CI_ACCOMPRESSION: if (go->neg_accompression || no.neg_accompression || cilen != CILEN_VOID) goto bad; break; case CI_QUALITY: if (go->neg_lqr || no.neg_lqr || cilen != CILEN_LQR) goto bad; break; case CI_MRRU: if (go->neg_mrru || no.neg_mrru || cilen != CILEN_SHORT) goto bad; break; case CI_SSNHF: if (go->neg_ssnhf || no.neg_ssnhf || cilen != CILEN_VOID) goto bad; try.neg_ssnhf = 1; break; case CI_EPDISC: if (go->neg_endpoint || no.neg_endpoint || cilen < CILEN_CHAR) goto bad; break; } p = next; } /* * OK, the Nak is good. Now we can update state. * If there are any options left we ignore them. */ if (f->state != OPENED) { if (looped_back) { if (++try.numloops >= lcp_loopbackfail) { notice("Serial line is looped back."); ppp_set_status(EXIT_LOOPBACK); lcp_close(f->unit, "Loopback detected"); } } else try.numloops = 0; *go = try; } return 1; bad: LCPDEBUG(("lcp_nakci: received bad Nak!")); return 0; } /* * lcp_rejci - Peer has Rejected some of our CIs. * This should not modify any state if the Reject is bad * or if LCP is in the OPENED state. * * Returns: * 0 - Reject was bad. * 1 - Reject was good. */ static int lcp_rejci(fsm *f, u_char *p, int len) { lcp_options *go = &lcp_gotoptions[f->unit]; u_char cichar; u_short cishort; u_int32_t cilong; lcp_options try; /* options to request next time */ try = *go; /* * Any Rejected CIs must be in exactly the same order that we sent. * Check packet length and CI length at each step. * If we find any deviations, then this packet is bad. */ #define REJCIVOID(opt, neg) \ if (go->neg && \ len >= CILEN_VOID && \ p[1] == CILEN_VOID && \ p[0] == opt) { \ len -= CILEN_VOID; \ INCPTR(CILEN_VOID, p); \ try.neg = 0; \ } #define REJCISHORT(opt, neg, val) \ if (go->neg && \ len >= CILEN_SHORT && \ p[1] == CILEN_SHORT && \ p[0] == opt) { \ len -= CILEN_SHORT; \ INCPTR(2, p); \ GETSHORT(cishort, p); \ /* Check rejected value. */ \ if (cishort != val) \ goto bad; \ try.neg = 0; \ } #define REJCICHAP(opt, neg, val) \ if (go->neg && \ len >= CILEN_CHAP && \ p[1] == CILEN_CHAP && \ p[0] == opt) { \ len -= CILEN_CHAP; \ INCPTR(2, p); \ GETSHORT(cishort, p); \ GETCHAR(cichar, p); \ /* Check rejected value. */ \ if ((cishort != PPP_CHAP) || (cichar != (CHAP_DIGEST(val)))) \ goto bad; \ try.neg = 0; \ try.neg_eap = try.neg_upap = 0; \ } #define REJCILONG(opt, neg, val) \ if (go->neg && \ len >= CILEN_LONG && \ p[1] == CILEN_LONG && \ p[0] == opt) { \ len -= CILEN_LONG; \ INCPTR(2, p); \ GETLONG(cilong, p); \ /* Check rejected value. */ \ if (cilong != val) \ goto bad; \ try.neg = 0; \ } #define REJCILQR(opt, neg, val) \ if (go->neg && \ len >= CILEN_LQR && \ p[1] == CILEN_LQR && \ p[0] == opt) { \ len -= CILEN_LQR; \ INCPTR(2, p); \ GETSHORT(cishort, p); \ GETLONG(cilong, p); \ /* Check rejected value. */ \ if (cishort != PPP_LQR || cilong != val) \ goto bad; \ try.neg = 0; \ } #define REJCICBCP(opt, neg, val) \ if (go->neg && \ len >= CILEN_CBCP && \ p[1] == CILEN_CBCP && \ p[0] == opt) { \ len -= CILEN_CBCP; \ INCPTR(2, p); \ GETCHAR(cichar, p); \ /* Check rejected value. */ \ if (cichar != val) \ goto bad; \ try.neg = 0; \ } #define REJCIENDP(opt, neg, class, val, vlen) \ if (go->neg && \ len >= CILEN_CHAR + vlen && \ p[0] == opt && \ p[1] == CILEN_CHAR + vlen) { \ int i; \ len -= CILEN_CHAR + vlen; \ INCPTR(2, p); \ GETCHAR(cichar, p); \ if (cichar != class) \ goto bad; \ for (i = 0; i < vlen; ++i) { \ GETCHAR(cichar, p); \ if (cichar != val[i]) \ goto bad; \ } \ try.neg = 0; \ } REJCISHORT(CI_MRU, neg_mru, go->mru); REJCILONG(CI_ASYNCMAP, neg_asyncmap, go->asyncmap); REJCISHORT(CI_AUTHTYPE, neg_eap, PPP_EAP); if (!go->neg_eap) { REJCICHAP(CI_AUTHTYPE, neg_chap, go->chap_mdtype); if (!go->neg_chap) { REJCISHORT(CI_AUTHTYPE, neg_upap, PPP_PAP); } } REJCILQR(CI_QUALITY, neg_lqr, go->lqr_period); REJCICBCP(CI_CALLBACK, neg_cbcp, CBCP_OPT); REJCILONG(CI_MAGICNUMBER, neg_magicnumber, go->magicnumber); REJCIVOID(CI_PCOMPRESSION, neg_pcompression); REJCIVOID(CI_ACCOMPRESSION, neg_accompression); REJCISHORT(CI_MRRU, neg_mrru, go->mrru); REJCIVOID(CI_SSNHF, neg_ssnhf); REJCIENDP(CI_EPDISC, neg_endpoint, go->endpoint.class, go->endpoint.value, go->endpoint.length); /* * If there are any remaining CIs, then this packet is bad. */ if (len != 0) goto bad; /* * Now we can update state. */ if (f->state != OPENED) *go = try; return 1; bad: LCPDEBUG(("lcp_rejci: received bad Reject!")); return 0; } /* * lcp_reqci - Check the peer's requested CIs and send appropriate response. * * Returns: CONFACK, CONFNAK or CONFREJ and input packet modified * appropriately. If reject_if_disagree is non-zero, doesn't return * CONFNAK; returns CONFREJ if it can't return CONFACK. */ static int lcp_reqci(fsm *f, u_char *inp, int *lenp, int reject_if_disagree) { lcp_options *go = &lcp_gotoptions[f->unit]; lcp_options *ho = &lcp_hisoptions[f->unit]; lcp_options *ao = &lcp_allowoptions[f->unit]; u_char *cip, *next; /* Pointer to current and next CIs */ int cilen, citype, cichar; /* Parsed len, type, char value */ u_short cishort; /* Parsed short value */ u_int32_t cilong; /* Parse long value */ int rc = CONFACK; /* Final packet return code */ int orc; /* Individual option return code */ u_char *p; /* Pointer to next char to parse */ u_char *rejp; /* Pointer to next char in reject frame */ u_char *nakp; /* Pointer to next char in Nak frame */ int l = *lenp; /* Length left */ /* * Reset all his options. */ BZERO(ho, sizeof(*ho)); /* * Process all his options. */ next = inp; nakp = nak_buffer; rejp = inp; while (l) { orc = CONFACK; /* Assume success */ cip = p = next; /* Remember begining of CI */ if (l < 2 || /* Not enough data for CI header or */ p[1] < 2 || /* CI length too small or */ p[1] > l) { /* CI length too big? */ LCPDEBUG(("lcp_reqci: bad CI length!")); orc = CONFREJ; /* Reject bad CI */ cilen = l; /* Reject till end of packet */ l = 0; /* Don't loop again */ citype = 0; goto endswitch; } GETCHAR(citype, p); /* Parse CI type */ GETCHAR(cilen, p); /* Parse CI length */ l -= cilen; /* Adjust remaining length */ next += cilen; /* Step to next CI */ switch (citype) { /* Check CI type */ case CI_MRU: if (!ao->neg_mru || /* Allow option? */ cilen != CILEN_SHORT) { /* Check CI length */ orc = CONFREJ; /* Reject CI */ break; } GETSHORT(cishort, p); /* Parse MRU */ /* * He must be able to receive at least our minimum. * No need to check a maximum. If he sends a large number, * we'll just ignore it. */ if (cishort < MINMRU) { orc = CONFNAK; /* Nak CI */ PUTCHAR(CI_MRU, nakp); PUTCHAR(CILEN_SHORT, nakp); PUTSHORT(MINMRU, nakp); /* Give him a hint */ break; } ho->neg_mru = 1; /* Remember he sent MRU */ ho->mru = cishort; /* And remember value */ break; case CI_ASYNCMAP: if (!ao->neg_asyncmap || cilen != CILEN_LONG) { orc = CONFREJ; break; } GETLONG(cilong, p); /* * Asyncmap must have set at least the bits * which are set in lcp_allowoptions[unit].asyncmap. */ if ((ao->asyncmap & ~cilong) != 0) { orc = CONFNAK; PUTCHAR(CI_ASYNCMAP, nakp); PUTCHAR(CILEN_LONG, nakp); PUTLONG(ao->asyncmap | cilong, nakp); break; } ho->neg_asyncmap = 1; ho->asyncmap = cilong; break; case CI_AUTHTYPE: if (cilen < CILEN_SHORT || !(ao->neg_upap || ao->neg_chap || ao->neg_eap)) { /* * Reject the option if we're not willing to authenticate. */ dbglog("No auth is possible"); orc = CONFREJ; break; } GETSHORT(cishort, p); /* * Authtype must be PAP, CHAP, or EAP. * * Note: if more than one of ao->neg_upap, ao->neg_chap, and * ao->neg_eap are set, and the peer sends a Configure-Request * with two or more authenticate-protocol requests, then we will * reject the second request. * Whether we end up doing CHAP, UPAP, or EAP depends then on * the ordering of the CIs in the peer's Configure-Request. */ if (cishort == PPP_PAP) { /* we've already accepted CHAP or EAP */ if (ho->neg_chap || ho->neg_eap || cilen != CILEN_SHORT) { LCPDEBUG(("lcp_reqci: rcvd AUTHTYPE PAP, rejecting...")); orc = CONFREJ; break; } if (!ao->neg_upap) { /* we don't want to do PAP */ orc = CONFNAK; /* NAK it and suggest CHAP or EAP */ PUTCHAR(CI_AUTHTYPE, nakp); if (ao->neg_eap) { PUTCHAR(CILEN_SHORT, nakp); PUTSHORT(PPP_EAP, nakp); } else { PUTCHAR(CILEN_CHAP, nakp); PUTSHORT(PPP_CHAP, nakp); PUTCHAR(CHAP_DIGEST(ao->chap_mdtype), nakp); } break; } ho->neg_upap = 1; break; } if (cishort == PPP_CHAP) { /* we've already accepted PAP or EAP */ if (ho->neg_upap || ho->neg_eap || cilen != CILEN_CHAP) { LCPDEBUG(("lcp_reqci: rcvd AUTHTYPE CHAP, rejecting...")); orc = CONFREJ; break; } if (!ao->neg_chap) { /* we don't want to do CHAP */ orc = CONFNAK; /* NAK it and suggest EAP or PAP */ PUTCHAR(CI_AUTHTYPE, nakp); PUTCHAR(CILEN_SHORT, nakp); if (ao->neg_eap) { PUTSHORT(PPP_EAP, nakp); } else { PUTSHORT(PPP_PAP, nakp); } break; } GETCHAR(cichar, p); /* get digest type */ if (!(CHAP_CANDIGEST(ao->chap_mdtype, cichar))) { /* * We can't/won't do the requested type, * suggest something else. */ orc = CONFNAK; PUTCHAR(CI_AUTHTYPE, nakp); PUTCHAR(CILEN_CHAP, nakp); PUTSHORT(PPP_CHAP, nakp); PUTCHAR(CHAP_DIGEST(ao->chap_mdtype), nakp); break; } ho->chap_mdtype = CHAP_MDTYPE_D(cichar); /* save md type */ ho->neg_chap = 1; break; } if (cishort == PPP_EAP) { /* we've already accepted CHAP or PAP */ if (ho->neg_chap || ho->neg_upap || cilen != CILEN_SHORT) { LCPDEBUG(("lcp_reqci: rcvd AUTHTYPE EAP, rejecting...")); orc = CONFREJ; break; } if (!ao->neg_eap) { /* we don't want to do EAP */ orc = CONFNAK; /* NAK it and suggest CHAP or PAP */ PUTCHAR(CI_AUTHTYPE, nakp); if (ao->neg_chap) { PUTCHAR(CILEN_CHAP, nakp); PUTSHORT(PPP_CHAP, nakp); PUTCHAR(CHAP_DIGEST(ao->chap_mdtype), nakp); } else { PUTCHAR(CILEN_SHORT, nakp); PUTSHORT(PPP_PAP, nakp); } break; } ho->neg_eap = 1; break; } /* * We don't recognize the protocol they're asking for. * Nak it with something we're willing to do. * (At this point we know ao->neg_upap || ao->neg_chap || * ao->neg_eap.) */ orc = CONFNAK; PUTCHAR(CI_AUTHTYPE, nakp); if (ao->neg_eap) { PUTCHAR(CILEN_SHORT, nakp); PUTSHORT(PPP_EAP, nakp); } else if (ao->neg_chap) { PUTCHAR(CILEN_CHAP, nakp); PUTSHORT(PPP_CHAP, nakp); PUTCHAR(CHAP_DIGEST(ao->chap_mdtype), nakp); } else { PUTCHAR(CILEN_SHORT, nakp); PUTSHORT(PPP_PAP, nakp); } break; case CI_QUALITY: if (!ao->neg_lqr || cilen != CILEN_LQR) { orc = CONFREJ; break; } GETSHORT(cishort, p); GETLONG(cilong, p); /* * Check the protocol and the reporting period. * XXX When should we Nak this, and what with? */ if (cishort != PPP_LQR) { orc = CONFNAK; PUTCHAR(CI_QUALITY, nakp); PUTCHAR(CILEN_LQR, nakp); PUTSHORT(PPP_LQR, nakp); PUTLONG(ao->lqr_period, nakp); break; } break; case CI_MAGICNUMBER: if (!(ao->neg_magicnumber || go->neg_magicnumber) || cilen != CILEN_LONG) { orc = CONFREJ; break; } GETLONG(cilong, p); /* * He must have a different magic number. */ if (go->neg_magicnumber && cilong == go->magicnumber) { cilong = magic(); /* Don't put magic() inside macro! */ orc = CONFNAK; PUTCHAR(CI_MAGICNUMBER, nakp); PUTCHAR(CILEN_LONG, nakp); PUTLONG(cilong, nakp); break; } ho->neg_magicnumber = 1; ho->magicnumber = cilong; break; case CI_PCOMPRESSION: if (!ao->neg_pcompression || cilen != CILEN_VOID) { orc = CONFREJ; break; } ho->neg_pcompression = 1; break; case CI_ACCOMPRESSION: if (!ao->neg_accompression || cilen != CILEN_VOID) { orc = CONFREJ; break; } ho->neg_accompression = 1; break; case CI_MRRU: if (!ao->neg_mrru || !multilink || cilen != CILEN_SHORT) { orc = CONFREJ; break; } GETSHORT(cishort, p); /* possibly should insist on a minimum/maximum MRRU here */ ho->neg_mrru = 1; ho->mrru = cishort; break; case CI_SSNHF: if (!ao->neg_ssnhf || !multilink || cilen != CILEN_VOID) { orc = CONFREJ; break; } ho->neg_ssnhf = 1; break; case CI_EPDISC: if (!ao->neg_endpoint || cilen < CILEN_CHAR || cilen > CILEN_CHAR + MAX_ENDP_LEN) { orc = CONFREJ; break; } GETCHAR(cichar, p); cilen -= CILEN_CHAR; ho->neg_endpoint = 1; ho->endpoint.class = cichar; ho->endpoint.length = cilen; BCOPY(p, ho->endpoint.value, cilen); INCPTR(cilen, p); break; default: LCPDEBUG(("lcp_reqci: rcvd unknown option %d", citype)); orc = CONFREJ; break; } endswitch: if (orc == CONFACK && /* Good CI */ rc != CONFACK) /* but prior CI wasnt? */ continue; /* Don't send this one */ if (orc == CONFNAK) { /* Nak this CI? */ if (reject_if_disagree /* Getting fed up with sending NAKs? */ && citype != CI_MAGICNUMBER) { orc = CONFREJ; /* Get tough if so */ } else { if (rc == CONFREJ) /* Rejecting prior CI? */ continue; /* Don't send this one */ rc = CONFNAK; } } if (orc == CONFREJ) { /* Reject this CI */ rc = CONFREJ; if (cip != rejp) /* Need to move rejected CI? */ BCOPY(cip, rejp, cilen); /* Move it */ INCPTR(cilen, rejp); /* Update output pointer */ } } /* * If we wanted to send additional NAKs (for unsent CIs), the * code would go here. The extra NAKs would go at *nakp. * At present there are no cases where we want to ask the * peer to negotiate an option. */ switch (rc) { case CONFACK: *lenp = next - inp; break; case CONFNAK: /* * Copy the Nak'd options from the nak_buffer to the caller's buffer. */ *lenp = nakp - nak_buffer; BCOPY(nak_buffer, inp, *lenp); break; case CONFREJ: *lenp = rejp - inp; break; } LCPDEBUG(("lcp_reqci: returning CONF%s.", CODENAME(rc))); return (rc); /* Return final code */ } /* * lcp_up - LCP has come UP. */ static void lcp_up(fsm *f) { lcp_options *wo = &lcp_wantoptions[f->unit]; lcp_options *ho = &lcp_hisoptions[f->unit]; lcp_options *go = &lcp_gotoptions[f->unit]; lcp_options *ao = &lcp_allowoptions[f->unit]; int mtu, mru; if (!go->neg_magicnumber) go->magicnumber = 0; if (!ho->neg_magicnumber) ho->magicnumber = 0; /* * Set our MTU to the smaller of the MTU we wanted and * the MRU our peer wanted. If we negotiated an MRU, * set our MRU to the larger of value we wanted and * the value we got in the negotiation. * Note on the MTU: the link MTU can be the MRU the peer wanted, * the interface MTU is set to the lowest of that, the * MTU we want to use, and our link MRU. */ mtu = ho->neg_mru? ho->mru: PPP_MRU; mru = go->neg_mru? MAX(wo->mru, go->mru): PPP_MRU; #ifdef PPP_WITH_MULTILINK if (!(multilink && go->neg_mrru && ho->neg_mrru)) #endif /* PPP_WITH_MULTILINK */ ppp_set_mtu(f->unit, MIN(MIN(mtu, mru), ao->mru)); ppp_send_config(f->unit, mtu, (ho->neg_asyncmap? ho->asyncmap: 0xffffffff), ho->neg_pcompression, ho->neg_accompression); ppp_recv_config(f->unit, mru, (lax_recv? 0: go->neg_asyncmap? go->asyncmap: 0xffffffff), go->neg_pcompression, go->neg_accompression); if (ho->neg_mru) peer_mru[f->unit] = ho->mru; lcp_echo_lowerup(f->unit); /* Enable echo messages */ link_established(f->unit); } /* * lcp_down - LCP has gone DOWN. * * Alert other protocols. */ static void lcp_down(fsm *f) { lcp_options *go = &lcp_gotoptions[f->unit]; lcp_echo_lowerdown(f->unit); link_down(f->unit); ppp_send_config(f->unit, PPP_MRU, 0xffffffff, 0, 0); ppp_recv_config(f->unit, PPP_MRU, (go->neg_asyncmap? go->asyncmap: 0xffffffff), go->neg_pcompression, go->neg_accompression); peer_mru[f->unit] = PPP_MRU; } /* * lcp_starting - LCP needs the lower layer up. */ static void lcp_starting(fsm *f) { link_required(f->unit); } /* * lcp_finished - LCP has finished with the lower layer. */ static void lcp_finished(fsm *f) { link_terminated(f->unit); } /* * lcp_printpkt - print the contents of an LCP packet. */ static char *lcp_codenames[] = { "ConfReq", "ConfAck", "ConfNak", "ConfRej", "TermReq", "TermAck", "CodeRej", "ProtRej", "EchoReq", "EchoRep", "DiscReq", "Ident", "TimeRem" }; static int lcp_printpkt(u_char *p, int plen, void (*printer)(void *, char *, ...), void *arg) { int code, id, len, olen, i; u_char *pstart, *optend; u_short cishort; u_int32_t cilong; if (plen < HEADERLEN) return 0; pstart = p; GETCHAR(code, p); GETCHAR(id, p); GETSHORT(len, p); if (len < HEADERLEN || len > plen) return 0; if (code >= 1 && code <= sizeof(lcp_codenames) / sizeof(char *)) printer(arg, " %s", lcp_codenames[code-1]); else printer(arg, " code=0x%x", code); printer(arg, " id=0x%x", id); len -= HEADERLEN; switch (code) { case CONFREQ: case CONFACK: case CONFNAK: case CONFREJ: /* print option list */ while (len >= 2) { GETCHAR(code, p); GETCHAR(olen, p); p -= 2; if (olen < 2 || olen > len) { break; } printer(arg, " <"); len -= olen; optend = p + olen; switch (code) { case CI_MRU: if (olen == CILEN_SHORT) { p += 2; GETSHORT(cishort, p); printer(arg, "mru %d", cishort); } break; case CI_ASYNCMAP: if (olen == CILEN_LONG) { p += 2; GETLONG(cilong, p); printer(arg, "asyncmap 0x%x", cilong); } break; case CI_AUTHTYPE: if (olen >= CILEN_SHORT) { p += 2; printer(arg, "auth "); GETSHORT(cishort, p); switch (cishort) { case PPP_PAP: printer(arg, "pap"); break; case PPP_CHAP: printer(arg, "chap"); if (p < optend) { switch (*p) { case CHAP_MD5: printer(arg, " MD5"); ++p; break; case CHAP_MICROSOFT: printer(arg, " MS"); ++p; break; case CHAP_MICROSOFT_V2: printer(arg, " MS-v2"); ++p; break; } } break; case PPP_EAP: printer(arg, "eap"); break; default: printer(arg, "0x%x", cishort); } } break; case CI_QUALITY: if (olen >= CILEN_SHORT) { p += 2; printer(arg, "quality "); GETSHORT(cishort, p); switch (cishort) { case PPP_LQR: printer(arg, "lqr"); break; default: printer(arg, "0x%x", cishort); } } break; case CI_CALLBACK: if (olen >= CILEN_CHAR) { p += 2; printer(arg, "callback "); GETCHAR(cishort, p); switch (cishort) { case CBCP_OPT: printer(arg, "CBCP"); break; default: printer(arg, "0x%x", cishort); } } break; case CI_MAGICNUMBER: if (olen == CILEN_LONG) { p += 2; GETLONG(cilong, p); printer(arg, "magic 0x%x", cilong); } break; case CI_PCOMPRESSION: if (olen == CILEN_VOID) { p += 2; printer(arg, "pcomp"); } break; case CI_ACCOMPRESSION: if (olen == CILEN_VOID) { p += 2; printer(arg, "accomp"); } break; case CI_MRRU: if (olen == CILEN_SHORT) { p += 2; GETSHORT(cishort, p); printer(arg, "mrru %d", cishort); } break; case CI_SSNHF: if (olen == CILEN_VOID) { p += 2; printer(arg, "ssnhf"); } break; case CI_EPDISC: #ifdef PPP_WITH_MULTILINK if (olen >= CILEN_CHAR) { struct epdisc epd; p += 2; GETCHAR(epd.class, p); epd.length = olen - CILEN_CHAR; if (epd.length > MAX_ENDP_LEN) epd.length = MAX_ENDP_LEN; if (epd.length > 0) { BCOPY(p, epd.value, epd.length); p += epd.length; } printer(arg, "endpoint [%s]", epdisc_to_str(&epd)); } #else printer(arg, "endpoint"); #endif break; } while (p < optend) { GETCHAR(code, p); printer(arg, " %.2x", code); } printer(arg, ">"); } break; case TERMACK: case TERMREQ: if (len > 0 && *p >= ' ' && *p < 0x7f) { printer(arg, " "); print_string((char *)p, len, printer, arg); p += len; len = 0; } break; case ECHOREQ: case ECHOREP: case DISCREQ: if (len >= 4) { GETLONG(cilong, p); printer(arg, " magic=0x%x", cilong); len -= 4; } break; case IDENTIF: case TIMEREM: if (len >= 4) { GETLONG(cilong, p); printer(arg, " magic=0x%x", cilong); len -= 4; } if (code == TIMEREM) { if (len < 4) break; GETLONG(cilong, p); printer(arg, " seconds=%u", cilong); len -= 4; } if (len > 0) { printer(arg, " "); print_string((char *)p, len, printer, arg); p += len; len = 0; } break; } /* print the rest of the bytes in the packet */ for (i = 0; i < len && i < 32; ++i) { GETCHAR(code, p); printer(arg, " %.2x", code); } if (i < len) { printer(arg, " ..."); p += len - i; } return p - pstart; } /* * Time to shut down the link because there is nothing out there. */ static void LcpLinkFailure (fsm *f) { if (f->state == OPENED) { info("No response to %d echo-requests", lcp_echos_pending); notice("Serial link appears to be disconnected."); ppp_set_status(EXIT_PEER_DEAD); lcp_close(f->unit, "Peer not responding"); } } /* * Timer expired for the LCP echo requests from this process. */ static void LcpEchoCheck (fsm *f) { LcpSendEchoRequest (f); if (f->state != OPENED) return; /* * Start the timer for the next interval. */ if (lcp_echo_timer_running) warn("assertion lcp_echo_timer_running==0 failed"); TIMEOUT (LcpEchoTimeout, f, lcp_echo_interval); lcp_echo_timer_running = 1; } /* * LcpEchoTimeout - Timer expired on the LCP echo */ static void LcpEchoTimeout (void *arg) { if (lcp_echo_timer_running != 0) { lcp_echo_timer_running = 0; LcpEchoCheck ((fsm *) arg); } } /* * LcpEchoReply - LCP has received a reply to the echo */ static void lcp_received_echo_reply (fsm *f, int id, u_char *inp, int len) { u_int32_t magic; /* Check the magic number - don't count replies from ourselves. */ if (len < 4) { dbglog("lcp: received short Echo-Reply, length %d", len); return; } GETLONG(magic, inp); if (lcp_gotoptions[f->unit].neg_magicnumber && magic == lcp_gotoptions[f->unit].magicnumber) { warn("appear to have received our own echo-reply!"); return; } /* Reset the number of outstanding echo frames */ lcp_echos_pending = 0; } /* * LcpSendEchoRequest - Send an echo request frame to the peer */ static void LcpSendEchoRequest (fsm *f) { u_int32_t lcp_magic; u_char pkt[4], *pktp; /* * Detect the failure of the peer at this point. */ if (lcp_echo_fails != 0) { if (lcp_echos_pending >= lcp_echo_fails) { LcpLinkFailure(f); lcp_echos_pending = 0; } } /* * If adaptive echos have been enabled, only send the echo request if * no traffic was received since the last one. */ if (lcp_echo_adaptive) { static unsigned int last_pkts_in = 0; struct pppd_stats cur_stats; if (get_ppp_stats(f->unit, &cur_stats) && cur_stats.pkts_in != last_pkts_in) { last_pkts_in = cur_stats.pkts_in; /* receipt of traffic indicates the link is working... */ lcp_echos_pending = 0; return; } } /* * Make and send the echo request frame. */ if (f->state == OPENED) { lcp_magic = lcp_gotoptions[f->unit].magicnumber; pktp = pkt; PUTLONG(lcp_magic, pktp); fsm_sdata(f, ECHOREQ, lcp_echo_number++ & 0xFF, pkt, pktp - pkt); ++lcp_echos_pending; } } /* * lcp_echo_lowerup - Start the timer for the LCP frame */ static void lcp_echo_lowerup (int unit) { fsm *f = &lcp_fsm[unit]; /* Clear the parameters for generating echo frames */ lcp_echos_pending = 0; lcp_echo_number = 0; lcp_echo_timer_running = 0; /* If a timeout interval is specified then start the timer */ if (lcp_echo_interval != 0) LcpEchoCheck (f); } /* * lcp_echo_lowerdown - Stop the timer for the LCP frame */ static void lcp_echo_lowerdown (int unit) { fsm *f = &lcp_fsm[unit]; if (lcp_echo_timer_running != 0) { UNTIMEOUT (LcpEchoTimeout, f); lcp_echo_timer_running = 0; } } ppp-2.5.0/pppd/magic.c0000644000175000017500000000601014353435407011432 00000000000000/* * magic.c - PPP Magic Number routines. * * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The name "Carnegie Mellon University" must not be used to * endorse or promote products derived from this software without * prior written permission. For permission or any legal * details, please contact * Office of Technology Transfer * Carnegie Mellon University * 5000 Forbes Avenue * Pittsburgh, PA 15213-3890 * (412) 268-4387, fax: (412) 268-7395 * tech-transfer@andrew.cmu.edu * * 4. Redistributions of any form whatsoever must retain the following * acknowledgment: * "This product includes software developed by Computing Services * at Carnegie Mellon University (http://www.cmu.edu/computing/)." * * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include "pppd-private.h" #include "magic.h" extern long mrand48 (void); extern void srand48 (long); /* * magic_init - Initialize the magic number generator. * * Attempts to compute a random number seed which will not repeat. * The current method uses the current hostid, current process ID * and current time, currently. */ void magic_init(void) { long seed; struct timeval t; gettimeofday(&t, NULL); seed = get_host_seed() ^ t.tv_sec ^ t.tv_usec ^ getpid(); srand48(seed); } /* * magic - Returns the next magic number. */ u_int32_t magic(void) { return (u_int32_t) mrand48(); } /* * random_bytes - Fill a buffer with random bytes. */ void random_bytes(unsigned char *buf, int len) { int i; for (i = 0; i < len; ++i) buf[i] = mrand48() >> 24; } #ifdef NO_DRAND48 /* * Substitute procedures for those systems which don't have * drand48 et al. */ double drand48(void) { return (double)random() / (double)0x7fffffffL; /* 2**31-1 */ } long mrand48(void) { return random(); } void srand48(long seedval) { srandom((int)seedval); } #endif ppp-2.5.0/pppd/main.c0000644000175000017500000016022514407475306011311 00000000000000/* * main.c - Point-to-Point Protocol main module * * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The name "Carnegie Mellon University" must not be used to * endorse or promote products derived from this software without * prior written permission. For permission or any legal * details, please contact * Office of Technology Transfer * Carnegie Mellon University * 5000 Forbes Avenue * Pittsburgh, PA 15213-3890 * (412) 268-4387, fax: (412) 268-7395 * tech-transfer@andrew.cmu.edu * * 4. Redistributions of any form whatsoever must retain the following * acknowledgment: * "This product includes software developed by Computing Services * at Carnegie Mellon University (http://www.cmu.edu/computing/)." * * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * Copyright (c) 1999-2020 Paul Mackerras. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. The name(s) of the authors of this software must not be used to * endorse or promote products derived from this software without * prior written permission. * * 3. Redistributions of any form whatsoever must retain the following * acknowledgment: * "This product includes software developed by Paul Mackerras * ". * * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "pppd-private.h" #include "options.h" #include "magic.h" #include "fsm.h" #include "lcp.h" #include "ipcp.h" #ifdef PPP_WITH_IPV6CP #include "ipv6cp.h" #endif #include "upap.h" #include "chap.h" #include "eap.h" #include "ccp.h" #include "ecp.h" #include "pathnames.h" #include "crypto.h" #include "multilink.h" #ifdef PPP_WITH_TDB #include "tdb.h" #endif #ifdef PPP_WITH_CBCP #include "cbcp.h" #endif #ifdef AT_CHANGE #include "atcp.h" #endif /* interface vars */ char ifname[IFNAMSIZ]; /* Interface name */ int ifunit; /* Interface unit number */ struct channel *the_channel; char *progname; /* Name of this program */ char hostname[MAXNAMELEN]; /* Our hostname */ static char pidfilename[MAXPATHLEN]; /* name of pid file */ static char linkpidfile[MAXPATHLEN]; /* name of linkname pid file */ uid_t uid; /* Our real user-id */ struct notifier *pidchange = NULL; struct notifier *phasechange = NULL; struct notifier *exitnotify = NULL; struct notifier *sigreceived = NULL; struct notifier *fork_notifier = NULL; int hungup; /* terminal has been hung up */ int privileged; /* we're running as real uid root */ int need_holdoff; /* need holdoff period before restarting */ int detached; /* have detached from terminal */ volatile int code; /* exit status for pppd */ int unsuccess; /* # unsuccessful connection attempts */ int do_callback; /* != 0 if we should do callback next */ int doing_callback; /* != 0 if we are doing callback */ int ppp_session_number; /* Session number, for channels with such a concept (eg PPPoE) */ int childwait_done; /* have timed out waiting for children */ #ifdef PPP_WITH_TDB TDB_CONTEXT *pppdb; /* database for storing status etc. */ #endif char db_key[32]; int (*holdoff_hook)(void) = NULL; int (*new_phase_hook)(int) = NULL; void (*snoop_recv_hook)(unsigned char *p, int len) = NULL; void (*snoop_send_hook)(unsigned char *p, int len) = NULL; static int conn_running; /* we have a [dis]connector running */ static int fd_loop; /* fd for getting demand-dial packets */ int fd_devnull; /* fd for /dev/null */ int devfd = -1; /* fd of underlying device */ int fd_ppp = -1; /* fd for talking PPP */ ppp_phase_t phase; /* where the link is at */ int kill_link; int asked_to_quit; int open_ccp_flag; int listen_time; int got_sigusr2; int got_sigterm; int got_sighup; static sigset_t signals_handled; static int waiting; static int sigpipe[2]; char **script_env; /* Env. variable values for scripts */ int s_env_nalloc; /* # words avail at script_env */ u_char outpacket_buf[PPP_MRU+PPP_HDRLEN]; /* buffer for outgoing packet */ u_char inpacket_buf[PPP_MRU+PPP_HDRLEN]; /* buffer for incoming packet */ static int n_children; /* # child processes still running */ static int got_sigchld; /* set if we have received a SIGCHLD */ int privopen; /* don't lock, open device as root */ char *no_ppp_msg = "Sorry - this system lacks PPP kernel support\n"; GIDSET_TYPE groups[NGROUPS_MAX];/* groups the user is in */ int ngroups; /* How many groups valid in groups */ static struct timeval start_time; /* Time when link was started. */ static struct pppd_stats old_link_stats; struct pppd_stats link_stats; unsigned link_connect_time; int link_stats_valid; int link_stats_print; int error_count; bool bundle_eof; bool bundle_terminating; /* * We maintain a list of child process pids and * functions to call when they exit. */ struct subprocess { pid_t pid; char *prog; void (*done)(void *); void *arg; int killable; struct subprocess *next; }; static struct subprocess *children; /* Prototypes for procedures local to this file. */ static void setup_signals(void); static void create_pidfile(int pid); static void create_linkpidfile(int pid); static void cleanup(void); static void get_input(void); static void calltimeout(void); static struct timeval *timeleft(struct timeval *); static void kill_my_pg(int); static void hup(int); static void term(int); static void chld(int); static void toggle_debug(int); static void open_ccp(int); static void bad_signal(int); static void holdoff_end(void *); static void forget_child(int pid, int status); static int reap_kids(void); static void childwait_end(void *); #ifdef PPP_WITH_TDB static void update_db_entry(void); static void add_db_key(const char *); static void delete_db_key(const char *); static void cleanup_db(void); #endif static void handle_events(void); void print_link_stats(void); extern char *getlogin(void); int main(int, char *[]); const char *ppp_hostname() { return hostname; } bool ppp_signaled(int sig) { if (sig == SIGTERM) return !!got_sigterm; if (sig == SIGUSR2) return !!got_sigusr2; if (sig == SIGHUP) return !!got_sighup; return false; } ppp_exit_code_t ppp_status() { return code; } void ppp_set_status(ppp_exit_code_t value) { code = value; } void ppp_set_session_number(int number) { ppp_session_number = number; } int ppp_get_session_number() { return ppp_session_number; } const char *ppp_ifname() { return ifname; } int ppp_get_ifname(char *buf, size_t bufsz) { if (buf) { return strlcpy(buf, ifname, bufsz); } return false; } void ppp_set_ifname(const char *name) { if (name) { strlcpy(ifname, name, sizeof(ifname)); } } int ppp_ifunit() { return ifunit; } int ppp_get_link_uptime() { return link_connect_time; } /* * PPP Data Link Layer "protocol" table. * One entry per supported protocol. * The last entry must be NULL. */ struct protent *protocols[] = { &lcp_protent, &pap_protent, &chap_protent, #ifdef PPP_WITH_CBCP &cbcp_protent, #endif &ipcp_protent, #ifdef PPP_WITH_IPV6CP &ipv6cp_protent, #endif &ccp_protent, &ecp_protent, #ifdef AT_CHANGE &atcp_protent, #endif &eap_protent, NULL }; int main(int argc, char *argv[]) { int i, t; char *p; struct passwd *pw; struct protent *protp; char numbuf[16]; PPP_crypto_init(); strlcpy(path_ipup, PPP_PATH_IPUP, MAXPATHLEN); strlcpy(path_ipdown, PPP_PATH_IPDOWN, MAXPATHLEN); #ifdef PPP_WITH_IPV6CP strlcpy(path_ipv6up, PPP_PATH_IPV6UP, MAXPATHLEN); strlcpy(path_ipv6down, PPP_PATH_IPV6DOWN, MAXPATHLEN); #endif link_stats_valid = 0; link_stats_print = 1; new_phase(PHASE_INITIALIZE); script_env = NULL; /* Initialize syslog facilities */ reopen_log(); if (gethostname(hostname, sizeof(hostname)) < 0 ) { ppp_option_error("Couldn't get hostname: %m"); exit(1); } hostname[MAXNAMELEN-1] = 0; /* make sure we don't create world or group writable files. */ umask(umask(0777) | 022); uid = getuid(); privileged = uid == 0; slprintf(numbuf, sizeof(numbuf), "%d", uid); ppp_script_setenv("ORIG_UID", numbuf, 0); ngroups = getgroups(NGROUPS_MAX, groups); /* * Initialize magic number generator now so that protocols may * use magic numbers in initialization. */ magic_init(); /* * Initialize each protocol. */ for (i = 0; (protp = protocols[i]) != NULL; ++i) (*protp->init)(0); /* * Initialize the default channel. */ tty_init(); progname = *argv; /* * Parse, in order, the system options file, the user's options file, * and the command line arguments. */ if (!ppp_options_from_file(PPP_PATH_SYSOPTIONS, !privileged, 0, 1) || !options_from_user() || !parse_args(argc-1, argv+1)) exit(EXIT_OPTION_ERROR); devnam_fixed = 1; /* can no longer change device name */ /* * Work out the device name, if it hasn't already been specified, * and parse the tty's options file. */ if (the_channel->process_extra_options) (*the_channel->process_extra_options)(); if (debug) setlogmask(LOG_UPTO(LOG_DEBUG)); if (show_options) { showopts(); die(0); } /* * Check that we are running as root. */ if (geteuid() != 0) { ppp_option_error("must be root to run %s, since it is not setuid-root", argv[0]); exit(EXIT_NOT_ROOT); } if (!ppp_check_kernel_support()) { ppp_option_error("%s", no_ppp_msg); exit(EXIT_NO_KERNEL_SUPPORT); } /* * Check that the options given are valid and consistent. */ check_options(); if (!sys_check_options()) exit(EXIT_OPTION_ERROR); auth_check_options(); mp_check_options(); for (i = 0; (protp = protocols[i]) != NULL; ++i) if (protp->check_options != NULL) (*protp->check_options)(); if (the_channel->check_options) (*the_channel->check_options)(); if (dump_options || dryrun) { init_pr_log(NULL, LOG_INFO); print_options(pr_log, NULL); end_pr_log(); } if (dryrun) die(0); /* Make sure fds 0, 1, 2 are open to somewhere. */ fd_devnull = open(PPP_DEVNULL, O_RDWR); if (fd_devnull < 0) fatal("Couldn't open %s: %m", PPP_DEVNULL); while (fd_devnull <= 2) { i = dup(fd_devnull); if (i < 0) fatal("Critical shortage of file descriptors: dup failed: %m"); fd_devnull = i; } /* * Initialize system-dependent stuff. */ sys_init(); #ifdef PPP_WITH_TDB pppdb = tdb_open(PPP_PATH_PPPDB, 0, 0, O_RDWR|O_CREAT, 0644); if (pppdb != NULL) { slprintf(db_key, sizeof(db_key), "pppd%d", getpid()); update_db_entry(); } else { warn("Warning: couldn't open ppp database %s", PPP_PATH_PPPDB); if (multilink) { warn("Warning: disabling multilink"); multilink = 0; } } #endif /* * Detach ourselves from the terminal, if required, * and identify who is running us. */ if (!nodetach && !updetach) detach(); p = getlogin(); if (p == NULL) { pw = getpwuid(uid); if (pw != NULL && pw->pw_name != NULL) p = pw->pw_name; else p = "(unknown)"; } syslog(LOG_NOTICE, "pppd %s started by %s, uid %d", VERSION, p, uid); ppp_script_setenv("PPPLOGNAME", p, 0); if (devnam[0]) ppp_script_setenv("DEVICE", devnam, 1); slprintf(numbuf, sizeof(numbuf), "%d", getpid()); ppp_script_setenv("PPPD_PID", numbuf, 1); setup_signals(); create_linkpidfile(getpid()); waiting = 0; /* * If we're doing dial-on-demand, set up the interface now. */ if (demand) { /* * Open the loopback channel and set it up to be the ppp interface. */ fd_loop = open_ppp_loopback(); set_ifunit(1); /* * Configure the interface and mark it up, etc. */ demand_conf(); } do_callback = 0; for (;;) { bundle_eof = 0; bundle_terminating = 0; listen_time = 0; need_holdoff = 1; devfd = -1; code = EXIT_OK; ++unsuccess; doing_callback = do_callback; do_callback = 0; if (demand && !doing_callback) { /* * Don't do anything until we see some activity. */ new_phase(PHASE_DORMANT); demand_unblock(); add_fd(fd_loop); for (;;) { handle_events(); if (asked_to_quit) break; if (get_loop_output()) break; } remove_fd(fd_loop); if (asked_to_quit) break; /* * Now we want to bring up the link. */ demand_block(); info("Starting link"); } ppp_get_time(&start_time); ppp_script_unsetenv("CONNECT_TIME"); ppp_script_unsetenv("BYTES_SENT"); ppp_script_unsetenv("BYTES_RCVD"); lcp_open(0); /* Start protocol */ start_link(0); while (phase != PHASE_DEAD) { handle_events(); get_input(); if (kill_link) lcp_close(0, "User request"); if (asked_to_quit) { bundle_terminating = 1; if (phase == PHASE_MASTER) mp_bundle_terminated(); } if (open_ccp_flag) { if (phase == PHASE_NETWORK || phase == PHASE_RUNNING) { ccp_fsm[0].flags = OPT_RESTART; /* clears OPT_SILENT */ (*ccp_protent.open)(0); } } } /* restore FSMs to original state */ lcp_close(0, ""); if (!persist || asked_to_quit || (maxfail > 0 && unsuccess >= maxfail)) break; if (demand) demand_discard(); t = need_holdoff? holdoff: 0; if (holdoff_hook) t = (*holdoff_hook)(); if (t > 0) { new_phase(PHASE_HOLDOFF); TIMEOUT(holdoff_end, NULL, t); do { handle_events(); if (kill_link) new_phase(PHASE_DORMANT); /* allow signal to end holdoff */ } while (phase == PHASE_HOLDOFF); if (!persist) break; } } /* Wait for scripts to finish */ reap_kids(); if (n_children > 0) { if (child_wait > 0) TIMEOUT(childwait_end, NULL, child_wait); if (debug) { struct subprocess *chp; dbglog("Waiting for %d child processes...", n_children); for (chp = children; chp != NULL; chp = chp->next) dbglog(" script %s, pid %d", chp->prog, chp->pid); } while (n_children > 0 && !childwait_done) { handle_events(); if (kill_link && !childwait_done) childwait_end(NULL); } } PPP_crypto_deinit(); die(code); return 0; } /* * handle_events - wait for something to happen and respond to it. */ static void handle_events(void) { struct timeval timo; unsigned char buf[16]; kill_link = open_ccp_flag = 0; /* alert via signal pipe */ waiting = 1; /* flush signal pipe */ for (; read(sigpipe[0], buf, sizeof(buf)) > 0; ); add_fd(sigpipe[0]); /* wait if necessary */ if (!(got_sighup || got_sigterm || got_sigusr2 || got_sigchld)) wait_input(timeleft(&timo)); waiting = 0; remove_fd(sigpipe[0]); calltimeout(); if (got_sighup) { info("Hangup (SIGHUP)"); kill_link = 1; got_sighup = 0; if (code != EXIT_HANGUP) code = EXIT_USER_REQUEST; } if (got_sigterm) { info("Terminating on signal %d", got_sigterm); kill_link = 1; asked_to_quit = 1; persist = 0; code = EXIT_USER_REQUEST; got_sigterm = 0; } if (got_sigchld) { got_sigchld = 0; reap_kids(); /* Don't leave dead kids lying around */ } if (got_sigusr2) { open_ccp_flag = 1; got_sigusr2 = 0; } } /* * setup_signals - initialize signal handling. */ static void setup_signals(void) { struct sigaction sa; /* create pipe to wake up event handler from signal handler */ if (pipe(sigpipe) < 0) fatal("Couldn't create signal pipe: %m"); fcntl(sigpipe[0], F_SETFD, fcntl(sigpipe[0], F_GETFD) | FD_CLOEXEC); fcntl(sigpipe[1], F_SETFD, fcntl(sigpipe[1], F_GETFD) | FD_CLOEXEC); fcntl(sigpipe[0], F_SETFL, fcntl(sigpipe[0], F_GETFL) | O_NONBLOCK); fcntl(sigpipe[1], F_SETFL, fcntl(sigpipe[1], F_GETFL) | O_NONBLOCK); /* * Compute mask of all interesting signals and install signal handlers * for each. Only one signal handler may be active at a time. Therefore, * all other signals should be masked when any handler is executing. */ sigemptyset(&signals_handled); sigaddset(&signals_handled, SIGHUP); sigaddset(&signals_handled, SIGINT); sigaddset(&signals_handled, SIGTERM); sigaddset(&signals_handled, SIGCHLD); sigaddset(&signals_handled, SIGUSR2); #define SIGNAL(s, handler) do { \ sa.sa_handler = handler; \ if (sigaction(s, &sa, NULL) < 0) \ fatal("Couldn't establish signal handler (%d): %m", s); \ } while (0) sa.sa_mask = signals_handled; sa.sa_flags = 0; SIGNAL(SIGHUP, hup); /* Hangup */ SIGNAL(SIGINT, term); /* Interrupt */ SIGNAL(SIGTERM, term); /* Terminate */ SIGNAL(SIGCHLD, chld); SIGNAL(SIGUSR1, toggle_debug); /* Toggle debug flag */ SIGNAL(SIGUSR2, open_ccp); /* Reopen CCP */ /* * Install a handler for other signals which would otherwise * cause pppd to exit without cleaning up. */ SIGNAL(SIGABRT, bad_signal); SIGNAL(SIGALRM, bad_signal); SIGNAL(SIGFPE, bad_signal); SIGNAL(SIGILL, bad_signal); SIGNAL(SIGPIPE, bad_signal); SIGNAL(SIGQUIT, bad_signal); SIGNAL(SIGSEGV, bad_signal); #ifdef SIGBUS SIGNAL(SIGBUS, bad_signal); #endif #ifdef SIGEMT SIGNAL(SIGEMT, bad_signal); #endif #ifdef SIGPOLL SIGNAL(SIGPOLL, bad_signal); #endif #ifdef SIGPROF SIGNAL(SIGPROF, bad_signal); #endif #ifdef SIGSYS SIGNAL(SIGSYS, bad_signal); #endif #ifdef SIGTRAP SIGNAL(SIGTRAP, bad_signal); #endif #ifdef SIGVTALRM SIGNAL(SIGVTALRM, bad_signal); #endif #ifdef SIGXCPU SIGNAL(SIGXCPU, bad_signal); #endif #ifdef SIGXFSZ SIGNAL(SIGXFSZ, bad_signal); #endif /* * Apparently we can get a SIGPIPE when we call syslog, if * syslogd has died and been restarted. Ignoring it seems * be sufficient. */ signal(SIGPIPE, SIG_IGN); } /* * set_ifunit - do things we need to do once we know which ppp * unit we are using. */ void set_ifunit(int iskey) { char ifkey[32]; if (req_ifname[0] != '\0') slprintf(ifname, sizeof(ifname), "%s", req_ifname); else slprintf(ifname, sizeof(ifname), "%s%d", PPP_DRV_NAME, ifunit); info("Using interface %s", ifname); ppp_script_setenv("IFNAME", ifname, iskey); slprintf(ifkey, sizeof(ifkey), "%d", ifunit); ppp_script_setenv("UNIT", ifkey, iskey); if (iskey) { create_pidfile(getpid()); /* write pid to file */ create_linkpidfile(getpid()); } } /* * detach - detach us from the controlling terminal. */ void detach(void) { int pid; int ret; char numbuf[16]; int pipefd[2]; if (detached) return; if (pipe(pipefd) == -1) pipefd[0] = pipefd[1] = -1; if ((pid = fork()) < 0) { error("Couldn't detach (fork failed: %m)"); die(1); /* or just return? */ } if (pid != 0) { /* parent */ notify(pidchange, pid); /* update pid files if they have been written already */ if (pidfilename[0]) create_pidfile(pid); create_linkpidfile(pid); exit(0); /* parent dies */ } setsid(); ret = chdir("/"); if (ret != 0) { fatal("Could not change directory to '/', %m"); } dup2(fd_devnull, 0); dup2(fd_devnull, 1); dup2(fd_devnull, 2); detached = 1; if (log_default) log_to_fd = -1; slprintf(numbuf, sizeof(numbuf), "%d", getpid()); ppp_script_setenv("PPPD_PID", numbuf, 1); /* wait for parent to finish updating pid & lock files and die */ close(pipefd[1]); complete_read(pipefd[0], numbuf, 1); close(pipefd[0]); } /* * reopen_log - (re)open our connection to syslog. */ void reopen_log(void) { openlog("pppd", LOG_PID | LOG_NDELAY, LOG_PPP); setlogmask(LOG_UPTO(LOG_INFO)); } /* * Create a file containing our process ID. */ static void create_pidfile(int pid) { FILE *pidfile; slprintf(pidfilename, sizeof(pidfilename), "%s%s.pid", PPP_PATH_VARRUN, ifname); if ((pidfile = fopen(pidfilename, "w")) != NULL) { fprintf(pidfile, "%d\n", pid); (void) fclose(pidfile); } else { error("Failed to create pid file %s: %m", pidfilename); pidfilename[0] = 0; } } void create_linkpidfile(int pid) { FILE *pidfile; if (linkname[0] == 0) return; ppp_script_setenv("LINKNAME", linkname, 1); slprintf(linkpidfile, sizeof(linkpidfile), "%sppp-%s.pid", PPP_PATH_VARRUN, linkname); if ((pidfile = fopen(linkpidfile, "w")) != NULL) { fprintf(pidfile, "%d\n", pid); if (ifname[0]) fprintf(pidfile, "%s\n", ifname); (void) fclose(pidfile); } else { error("Failed to create pid file %s: %m", linkpidfile); linkpidfile[0] = 0; } } /* * remove_pidfile - remove our pid files */ void remove_pidfiles(void) { if (pidfilename[0] != 0 && unlink(pidfilename) < 0 && errno != ENOENT) warn("unable to delete pid file %s: %m", pidfilename); pidfilename[0] = 0; if (linkpidfile[0] != 0 && unlink(linkpidfile) < 0 && errno != ENOENT) warn("unable to delete pid file %s: %m", linkpidfile); linkpidfile[0] = 0; } /* * holdoff_end - called via a timeout when the holdoff period ends. */ static void holdoff_end(void *arg) { new_phase(PHASE_DORMANT); } /* List of protocol names, to make our messages a little more informative. */ struct protocol_list { u_short proto; const char *name; } protocol_list[] = { { 0x21, "IP" }, { 0x23, "OSI Network Layer" }, { 0x25, "Xerox NS IDP" }, { 0x27, "DECnet Phase IV" }, { 0x29, "Appletalk" }, { 0x2b, "Novell IPX" }, { 0x2d, "VJ compressed TCP/IP" }, { 0x2f, "VJ uncompressed TCP/IP" }, { 0x31, "Bridging PDU" }, { 0x33, "Stream Protocol ST-II" }, { 0x35, "Banyan Vines" }, { 0x39, "AppleTalk EDDP" }, { 0x3b, "AppleTalk SmartBuffered" }, { 0x3d, "Multi-Link" }, { 0x3f, "NETBIOS Framing" }, { 0x41, "Cisco Systems" }, { 0x43, "Ascom Timeplex" }, { 0x45, "Fujitsu Link Backup and Load Balancing (LBLB)" }, { 0x47, "DCA Remote Lan" }, { 0x49, "Serial Data Transport Protocol (PPP-SDTP)" }, { 0x4b, "SNA over 802.2" }, { 0x4d, "SNA" }, { 0x4f, "IP6 Header Compression" }, { 0x51, "KNX Bridging Data" }, { 0x53, "Encryption" }, { 0x55, "Individual Link Encryption" }, { 0x57, "IPv6" }, { 0x59, "PPP Muxing" }, { 0x5b, "Vendor-Specific Network Protocol" }, { 0x61, "RTP IPHC Full Header" }, { 0x63, "RTP IPHC Compressed TCP" }, { 0x65, "RTP IPHC Compressed non-TCP" }, { 0x67, "RTP IPHC Compressed UDP 8" }, { 0x69, "RTP IPHC Compressed RTP 8" }, { 0x6f, "Stampede Bridging" }, { 0x73, "MP+" }, { 0xc1, "NTCITS IPI" }, { 0xfb, "single-link compression" }, { 0xfd, "Compressed Datagram" }, { 0x0201, "802.1d Hello Packets" }, { 0x0203, "IBM Source Routing BPDU" }, { 0x0205, "DEC LANBridge100 Spanning Tree" }, { 0x0207, "Cisco Discovery Protocol" }, { 0x0209, "Netcs Twin Routing" }, { 0x020b, "STP - Scheduled Transfer Protocol" }, { 0x020d, "EDP - Extreme Discovery Protocol" }, { 0x0211, "Optical Supervisory Channel Protocol" }, { 0x0213, "Optical Supervisory Channel Protocol" }, { 0x0231, "Luxcom" }, { 0x0233, "Sigma Network Systems" }, { 0x0235, "Apple Client Server Protocol" }, { 0x0281, "MPLS Unicast" }, { 0x0283, "MPLS Multicast" }, { 0x0285, "IEEE p1284.4 standard - data packets" }, { 0x0287, "ETSI TETRA Network Protocol Type 1" }, { 0x0289, "Multichannel Flow Treatment Protocol" }, { 0x2063, "RTP IPHC Compressed TCP No Delta" }, { 0x2065, "RTP IPHC Context State" }, { 0x2067, "RTP IPHC Compressed UDP 16" }, { 0x2069, "RTP IPHC Compressed RTP 16" }, { 0x4001, "Cray Communications Control Protocol" }, { 0x4003, "CDPD Mobile Network Registration Protocol" }, { 0x4005, "Expand accelerator protocol" }, { 0x4007, "ODSICP NCP" }, { 0x4009, "DOCSIS DLL" }, { 0x400B, "Cetacean Network Detection Protocol" }, { 0x4021, "Stacker LZS" }, { 0x4023, "RefTek Protocol" }, { 0x4025, "Fibre Channel" }, { 0x4027, "EMIT Protocols" }, { 0x405b, "Vendor-Specific Protocol (VSP)" }, { 0x8021, "Internet Protocol Control Protocol" }, { 0x8023, "OSI Network Layer Control Protocol" }, { 0x8025, "Xerox NS IDP Control Protocol" }, { 0x8027, "DECnet Phase IV Control Protocol" }, { 0x8029, "Appletalk Control Protocol" }, { 0x802b, "Novell IPX Control Protocol" }, { 0x8031, "Bridging NCP" }, { 0x8033, "Stream Protocol Control Protocol" }, { 0x8035, "Banyan Vines Control Protocol" }, { 0x803d, "Multi-Link Control Protocol" }, { 0x803f, "NETBIOS Framing Control Protocol" }, { 0x8041, "Cisco Systems Control Protocol" }, { 0x8043, "Ascom Timeplex" }, { 0x8045, "Fujitsu LBLB Control Protocol" }, { 0x8047, "DCA Remote Lan Network Control Protocol (RLNCP)" }, { 0x8049, "Serial Data Control Protocol (PPP-SDCP)" }, { 0x804b, "SNA over 802.2 Control Protocol" }, { 0x804d, "SNA Control Protocol" }, { 0x804f, "IP6 Header Compression Control Protocol" }, { 0x8051, "KNX Bridging Control Protocol" }, { 0x8053, "Encryption Control Protocol" }, { 0x8055, "Individual Link Encryption Control Protocol" }, { 0x8057, "IPv6 Control Protocol" }, { 0x8059, "PPP Muxing Control Protocol" }, { 0x805b, "Vendor-Specific Network Control Protocol (VSNCP)" }, { 0x806f, "Stampede Bridging Control Protocol" }, { 0x8073, "MP+ Control Protocol" }, { 0x80c1, "NTCITS IPI Control Protocol" }, { 0x80fb, "Single Link Compression Control Protocol" }, { 0x80fd, "Compression Control Protocol" }, { 0x8207, "Cisco Discovery Protocol Control" }, { 0x8209, "Netcs Twin Routing" }, { 0x820b, "STP - Control Protocol" }, { 0x820d, "EDPCP - Extreme Discovery Protocol Ctrl Prtcl" }, { 0x8235, "Apple Client Server Protocol Control" }, { 0x8281, "MPLSCP" }, { 0x8285, "IEEE p1284.4 standard - Protocol Control" }, { 0x8287, "ETSI TETRA TNP1 Control Protocol" }, { 0x8289, "Multichannel Flow Treatment Protocol" }, { 0xc021, "Link Control Protocol" }, { 0xc023, "Password Authentication Protocol" }, { 0xc025, "Link Quality Report" }, { 0xc027, "Shiva Password Authentication Protocol" }, { 0xc029, "CallBack Control Protocol (CBCP)" }, { 0xc02b, "BACP Bandwidth Allocation Control Protocol" }, { 0xc02d, "BAP" }, { 0xc05b, "Vendor-Specific Authentication Protocol (VSAP)" }, { 0xc081, "Container Control Protocol" }, { 0xc223, "Challenge Handshake Authentication Protocol" }, { 0xc225, "RSA Authentication Protocol" }, { 0xc227, "Extensible Authentication Protocol" }, { 0xc229, "Mitsubishi Security Info Exch Ptcl (SIEP)" }, { 0xc26f, "Stampede Bridging Authorization Protocol" }, { 0xc281, "Proprietary Authentication Protocol" }, { 0xc283, "Proprietary Authentication Protocol" }, { 0xc481, "Proprietary Node ID Authentication Protocol" }, { 0, NULL }, }; /* * protocol_name - find a name for a PPP protocol. */ const char * protocol_name(int proto) { struct protocol_list *lp; for (lp = protocol_list; lp->proto != 0; ++lp) if (proto == lp->proto) return lp->name; return NULL; } /* * get_input - called when incoming data is available. */ static void get_input(void) { int len, i; u_char *p; u_short protocol; struct protent *protp; p = inpacket_buf; /* point to beginning of packet buffer */ len = read_packet(inpacket_buf); if (len < 0) return; if (len == 0) { if (bundle_eof && mp_master()) { notice("Last channel has disconnected"); mp_bundle_terminated(); return; } notice("Modem hangup"); hungup = 1; code = EXIT_HANGUP; lcp_lowerdown(0); /* serial link is no longer available */ link_terminated(0); return; } if (len < PPP_HDRLEN) { dbglog("received short packet:%.*B", len, p); return; } dump_packet("rcvd", p, len); if (snoop_recv_hook) snoop_recv_hook(p, len); p += 2; /* Skip address and control */ GETSHORT(protocol, p); len -= PPP_HDRLEN; /* * Toss all non-LCP packets unless LCP is OPEN. */ if (protocol != PPP_LCP && lcp_fsm[0].state != OPENED) { dbglog("Discarded non-LCP packet when LCP not open"); return; } /* * Until we get past the authentication phase, toss all packets * except LCP, LQR and authentication packets. */ if (phase <= PHASE_AUTHENTICATE && !(protocol == PPP_LCP || protocol == PPP_LQR || protocol == PPP_PAP || protocol == PPP_CHAP || protocol == PPP_EAP)) { dbglog("discarding proto 0x%x in phase %d", protocol, phase); return; } /* * Upcall the proper protocol input routine. */ for (i = 0; (protp = protocols[i]) != NULL; ++i) { if (protp->protocol == protocol && protp->enabled_flag) { (*protp->input)(0, p, len); return; } if (protocol == (protp->protocol & ~0x8000) && protp->enabled_flag && protp->datainput != NULL) { (*protp->datainput)(0, p, len); return; } } if (debug) { const char *pname = protocol_name(protocol); if (pname != NULL) warn("Unsupported protocol '%s' (0x%x) received", pname, protocol); else warn("Unsupported protocol 0x%x received", protocol); } lcp_sprotrej(0, p - PPP_HDRLEN, len + PPP_HDRLEN); } /* * ppp_send_config - configure the transmit-side characteristics of * the ppp interface. Returns -1, indicating an error, if the channel * send_config procedure called error() (or incremented error_count * itself), otherwise 0. */ int ppp_send_config(int unit, int mtu, u_int32_t accm, int pcomp, int accomp) { int errs; if (the_channel->send_config == NULL) return 0; errs = error_count; (*the_channel->send_config)(mtu, accm, pcomp, accomp); return (error_count != errs)? -1: 0; } /* * ppp_recv_config - configure the receive-side characteristics of * the ppp interface. Returns -1, indicating an error, if the channel * recv_config procedure called error() (or incremented error_count * itself), otherwise 0. */ int ppp_recv_config(int unit, int mru, u_int32_t accm, int pcomp, int accomp) { int errs; if (the_channel->recv_config == NULL) return 0; errs = error_count; (*the_channel->recv_config)(mru, accm, pcomp, accomp); return (error_count != errs)? -1: 0; } /* * new_phase - signal the start of a new phase of pppd's operation. */ void new_phase(ppp_phase_t p) { phase = p; if (new_phase_hook) (*new_phase_hook)(p); notify(phasechange, p); } bool in_phase(ppp_phase_t p) { return (phase == p); } /* * die - clean up state and exit with the specified status. */ void die(int status) { if (!mp_on() || mp_master()) print_link_stats(); cleanup(); notify(exitnotify, status); syslog(LOG_INFO, "Exit."); exit(status); } /* * cleanup - restore anything which needs to be restored before we exit */ /* ARGSUSED */ static void cleanup(void) { sys_cleanup(); if (fd_ppp >= 0) the_channel->disestablish_ppp(devfd); if (the_channel->cleanup) (*the_channel->cleanup)(); remove_pidfiles(); #ifdef PPP_WITH_TDB if (pppdb != NULL) cleanup_db(); #endif } void print_link_stats(void) { /* * Print connect time and statistics. */ if (link_stats_print && link_stats_valid) { int t = (link_connect_time + 5) / 6; /* 1/10ths of minutes */ info("Connect time %d.%d minutes.", t/10, t%10); info("Sent %u bytes, received %u bytes.", link_stats.bytes_out, link_stats.bytes_in); link_stats_print = 0; } } /* * reset_link_stats - "reset" stats when link goes up. */ void reset_link_stats(int u) { if (!get_ppp_stats(u, &old_link_stats)) return; ppp_get_time(&start_time); } /* * update_link_stats - get stats at link termination. */ void update_link_stats(int u) { struct timeval now; char numbuf[32]; if (!get_ppp_stats(u, &link_stats) || ppp_get_time(&now) < 0) return; link_connect_time = now.tv_sec - start_time.tv_sec; link_stats_valid = 1; link_stats.bytes_in -= old_link_stats.bytes_in; link_stats.bytes_out -= old_link_stats.bytes_out; link_stats.pkts_in -= old_link_stats.pkts_in; link_stats.pkts_out -= old_link_stats.pkts_out; slprintf(numbuf, sizeof(numbuf), "%u", link_connect_time); ppp_script_setenv("CONNECT_TIME", numbuf, 0); snprintf(numbuf, sizeof(numbuf), "%" PRIu64, link_stats.bytes_out); ppp_script_setenv("BYTES_SENT", numbuf, 0); snprintf(numbuf, sizeof(numbuf), "%" PRIu64, link_stats.bytes_in); ppp_script_setenv("BYTES_RCVD", numbuf, 0); } bool ppp_get_link_stats(ppp_link_stats_st *stats) { update_link_stats(0); if (stats != NULL && link_stats_valid) { memcpy(stats, &link_stats, sizeof(*stats)); return true; } return false; } struct callout { struct timeval c_time; /* time at which to call routine */ void *c_arg; /* argument to routine */ void (*c_func)(void *); /* routine */ struct callout *c_next; }; static struct callout *callout = NULL; /* Callout list */ static struct timeval timenow; /* Current time */ /* * timeout - Schedule a timeout. */ void ppp_timeout(void (*func)(void *), void *arg, int secs, int usecs) { struct callout *newp, *p, **pp; /* * Allocate timeout. */ if ((newp = (struct callout *) malloc(sizeof(struct callout))) == NULL) fatal("Out of memory in timeout()!"); newp->c_arg = arg; newp->c_func = func; ppp_get_time(&timenow); newp->c_time.tv_sec = timenow.tv_sec + secs; newp->c_time.tv_usec = timenow.tv_usec + usecs; if (newp->c_time.tv_usec >= 1000000) { newp->c_time.tv_sec += newp->c_time.tv_usec / 1000000; newp->c_time.tv_usec %= 1000000; } /* * Find correct place and link it in. */ for (pp = &callout; (p = *pp); pp = &p->c_next) if (newp->c_time.tv_sec < p->c_time.tv_sec || (newp->c_time.tv_sec == p->c_time.tv_sec && newp->c_time.tv_usec < p->c_time.tv_usec)) break; newp->c_next = p; *pp = newp; } /* * untimeout - Unschedule a timeout. */ void ppp_untimeout(void (*func)(void *), void *arg) { struct callout **copp, *freep; /* * Find first matching timeout and remove it from the list. */ for (copp = &callout; (freep = *copp); copp = &freep->c_next) if (freep->c_func == func && freep->c_arg == arg) { *copp = freep->c_next; free((char *) freep); break; } } /* * calltimeout - Call any timeout routines which are now due. */ static void calltimeout(void) { struct callout *p; while (callout != NULL) { p = callout; if (ppp_get_time(&timenow) < 0) fatal("Failed to get time of day: %m"); if (!(p->c_time.tv_sec < timenow.tv_sec || (p->c_time.tv_sec == timenow.tv_sec && p->c_time.tv_usec <= timenow.tv_usec))) break; /* no, it's not time yet */ callout = p->c_next; (*p->c_func)(p->c_arg); free((char *) p); } } /* * timeleft - return the length of time until the next timeout is due. */ static struct timeval * timeleft(struct timeval *tvp) { if (callout == NULL) return NULL; ppp_get_time(&timenow); tvp->tv_sec = callout->c_time.tv_sec - timenow.tv_sec; tvp->tv_usec = callout->c_time.tv_usec - timenow.tv_usec; if (tvp->tv_usec < 0) { tvp->tv_usec += 1000000; tvp->tv_sec -= 1; } if (tvp->tv_sec < 0) tvp->tv_sec = tvp->tv_usec = 0; return tvp; } /* * kill_my_pg - send a signal to our process group, and ignore it ourselves. * We assume that sig is currently blocked. */ static void kill_my_pg(int sig) { struct sigaction act, oldact; struct subprocess *chp; if (!detached) { /* * There might be other things in our process group that we * didn't start that would get hit if we did a kill(0), so * just send the signal individually to our children. */ for (chp = children; chp != NULL; chp = chp->next) if (chp->killable) kill(chp->pid, sig); return; } /* We've done a setsid(), so we can just use a kill(0) */ sigemptyset(&act.sa_mask); /* unnecessary in fact */ act.sa_handler = SIG_IGN; act.sa_flags = 0; kill(0, sig); /* * The kill() above made the signal pending for us, as well as * the rest of our process group, but we don't want it delivered * to us. It is blocked at the moment. Setting it to be ignored * will cause the pending signal to be discarded. If we did the * kill() after setting the signal to be ignored, it is unspecified * (by POSIX) whether the signal is immediately discarded or left * pending, and in fact Linux would leave it pending, and so it * would be delivered after the current signal handler exits, * leading to an infinite loop. */ sigaction(sig, &act, &oldact); sigaction(sig, &oldact, NULL); } /* * hup - Catch SIGHUP signal. * * Indicates that the physical layer has been disconnected. * We don't rely on this indication; if the user has sent this * signal, we just take the link down. */ static void hup(int sig) { /* can't log a message here, it can deadlock */ got_sighup = 1; if (conn_running) /* Send the signal to the [dis]connector process(es) also */ kill_my_pg(sig); notify(sigreceived, sig); if (waiting) { #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-result" write(sigpipe[1], &sig, sizeof(sig)); #pragma GCC diagnostic pop } } /* * term - Catch SIGTERM signal and SIGINT signal (^C/del). * * Indicates that we should initiate a graceful disconnect and exit. */ /*ARGSUSED*/ static void term(int sig) { /* can't log a message here, it can deadlock */ got_sigterm = sig; if (conn_running) /* Send the signal to the [dis]connector process(es) also */ kill_my_pg(sig); notify(sigreceived, sig); if (waiting) { #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-result" write(sigpipe[1], &sig, sizeof(sig)); #pragma GCC diagnostic pop } } /* * chld - Catch SIGCHLD signal. * Sets a flag so we will call reap_kids in the mainline. */ static void chld(int sig) { got_sigchld = 1; if (waiting) { #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-result" write(sigpipe[1], &sig, sizeof(sig)); #pragma GCC diagnostic pop } } /* * toggle_debug - Catch SIGUSR1 signal. * * Toggle debug flag. */ /*ARGSUSED*/ static void toggle_debug(int sig) { debug = !debug; if (debug) { setlogmask(LOG_UPTO(LOG_DEBUG)); } else { setlogmask(LOG_UPTO(LOG_WARNING)); } } /* * open_ccp - Catch SIGUSR2 signal. * * Try to (re)negotiate compression. */ /*ARGSUSED*/ static void open_ccp(int sig) { got_sigusr2 = 1; if (waiting) { #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-result" write(sigpipe[1], &sig, sizeof(sig)); #pragma GCC diagnostic pop } } /* * bad_signal - We've caught a fatal signal. Clean up state and exit. */ static void bad_signal(int sig) { static int crashed = 0; if (crashed) _exit(127); crashed = 1; error("Fatal signal %d", sig); if (conn_running) kill_my_pg(SIGTERM); notify(sigreceived, sig); die(127); } /* * ppp_safe_fork - Create a child process. The child closes all the * file descriptors that we don't want to leak to a script. * The parent waits for the child to do this before returning. * This also arranges for the specified fds to be dup'd to * fds 0, 1, 2 in the child. */ pid_t ppp_safe_fork(int infd, int outfd, int errfd) { pid_t pid; int fd, pipefd[2]; char buf[1]; /* make sure fds 0, 1, 2 are occupied (probably not necessary) */ while ((fd = dup(fd_devnull)) >= 0) { if (fd > 2) { close(fd); break; } } if (pipe(pipefd) == -1) pipefd[0] = pipefd[1] = -1; pid = fork(); if (pid < 0) { error("fork failed: %m"); return -1; } if (pid > 0) { /* parent */ close(pipefd[1]); /* this read() blocks until the close(pipefd[1]) below */ complete_read(pipefd[0], buf, 1); close(pipefd[0]); return pid; } /* Executing in the child */ ppp_sys_close(); #ifdef PPP_WITH_TDB if (pppdb != NULL) tdb_close(pppdb); #endif /* make sure infd, outfd and errfd won't get tromped on below */ if (infd == 1 || infd == 2) infd = dup(infd); if (outfd == 0 || outfd == 2) outfd = dup(outfd); if (errfd == 0 || errfd == 1) errfd = dup(errfd); closelog(); /* dup the in, out, err fds to 0, 1, 2 */ if (infd != 0) dup2(infd, 0); if (outfd != 1) dup2(outfd, 1); if (errfd != 2) dup2(errfd, 2); if (log_to_fd > 2) close(log_to_fd); if (the_channel->close) (*the_channel->close)(); else close(devfd); /* some plugins don't have a close function */ close(fd_ppp); close(fd_devnull); if (infd != 0) close(infd); if (outfd != 1) close(outfd); if (errfd != 2) close(errfd); notify(fork_notifier, 0); close(pipefd[0]); /* this close unblocks the read() call above in the parent */ close(pipefd[1]); return 0; } static bool add_script_env(int pos, char *newstring) { if (pos + 1 >= s_env_nalloc) { int new_n = pos + 17; char **newenv = realloc(script_env, new_n * sizeof(char *)); if (newenv == NULL) { free(newstring - 1); return 0; } script_env = newenv; s_env_nalloc = new_n; } script_env[pos] = newstring; script_env[pos + 1] = NULL; return 1; } static void remove_script_env(int pos) { free(script_env[pos] - 1); while ((script_env[pos] = script_env[pos + 1]) != NULL) pos++; } /* * update_system_environment - process the list of set/unset options * and update the system environment. */ static void update_system_environment(void) { struct userenv *uep; for (uep = userenv_list; uep != NULL; uep = uep->ue_next) { if (uep->ue_isset) setenv(uep->ue_name, uep->ue_value, 1); else unsetenv(uep->ue_name); } } /* * device_script - run a program to talk to the specified fds * (e.g. to run the connector or disconnector script). * stderr gets connected to the log fd or to the PPP_PATH_CONNERRS file. */ int device_script(char *program, int in, int out, int dont_wait) { int pid; int status = -1; int errfd; int ret; if (log_to_fd >= 0) errfd = log_to_fd; else errfd = open(PPP_PATH_CONNERRS, O_WRONLY | O_APPEND | O_CREAT, 0644); ++conn_running; pid = ppp_safe_fork(in, out, errfd); if (pid != 0 && log_to_fd < 0) close(errfd); if (pid < 0) { --conn_running; error("Failed to create child process: %m"); return -1; } if (pid != 0) { record_child(pid, program, NULL, NULL, 1); status = 0; if (!dont_wait) { while (waitpid(pid, &status, 0) < 0) { if (errno == EINTR) continue; fatal("error waiting for (dis)connection process: %m"); } forget_child(pid, status); --conn_running; } return (status == 0 ? 0 : -1); } /* here we are executing in the child */ ret = setgid(getgid()); if (ret != 0) { perror("pppd: setgid failed\n"); exit(1); } ret = setuid(uid); if (ret != 0 || getuid() != uid) { perror("pppd: setuid failed\n"); exit(1); } update_system_environment(); execl("/bin/sh", "sh", "-c", program, (char *)0); perror("pppd: could not exec /bin/sh"); _exit(99); /* NOTREACHED */ } /* * update_script_environment - process the list of set/unset options * and update the script environment. Note that we intentionally do * not update the TDB. These changes are layered on top right before * exec. It is not possible to use script_setenv() or * ppp_script_unsetenv() safely after this routine is run. */ static void update_script_environment(void) { struct userenv *uep; for (uep = userenv_list; uep != NULL; uep = uep->ue_next) { int i; char *p, *newstring; int nlen = strlen(uep->ue_name); for (i = 0; (p = script_env[i]) != NULL; i++) { if (strncmp(p, uep->ue_name, nlen) == 0 && p[nlen] == '=') break; } if (uep->ue_isset) { nlen += strlen(uep->ue_value) + 2; newstring = malloc(nlen + 1); if (newstring == NULL) continue; *newstring++ = 0; slprintf(newstring, nlen, "%s=%s", uep->ue_name, uep->ue_value); if (p != NULL) script_env[i] = newstring; else add_script_env(i, newstring); } else if (p != NULL) { remove_script_env(i); } } } /* * run_program - execute a program with given arguments, * but don't wait for it unless wait is non-zero. * If the program can't be executed, logs an error unless * must_exist is 0 and the program file doesn't exist. * Returns -1 if it couldn't fork, 0 if the file doesn't exist * or isn't an executable plain file, or the process ID of the child. * If done != NULL, (*done)(arg) will be called later (within * reap_kids) iff the return value is > 0. */ pid_t run_program(char *prog, char * const *args, int must_exist, void (*done)(void *), void *arg, int wait) { int pid, status, ret; struct stat sbuf; /* * First check if the file exists and is executable. * We don't use access() because that would use the * real user-id, which might not be root, and the script * might be accessible only to root. */ errno = EINVAL; if (stat(prog, &sbuf) < 0 || !S_ISREG(sbuf.st_mode) || (sbuf.st_mode & (S_IXUSR|S_IXGRP|S_IXOTH)) == 0) { if (must_exist || errno != ENOENT) warn("Can't execute %s: %m", prog); return 0; } pid = ppp_safe_fork(fd_devnull, fd_devnull, fd_devnull); if (pid == -1) { error("Failed to create child process for %s: %m", prog); return -1; } if (pid != 0) { if (debug) dbglog("Script %s started (pid %d)", prog, pid); record_child(pid, prog, done, arg, 0); if (wait) { while (waitpid(pid, &status, 0) < 0) { if (errno == EINTR) continue; fatal("error waiting for script %s: %m", prog); } forget_child(pid, status); } return pid; } /* Leave the current location */ (void) setsid(); /* No controlling tty. */ (void) umask (S_IRWXG|S_IRWXO); ret = chdir ("/"); /* no current directory. */ if (ret != 0) { fatal("Failed to change directory to '/', %m"); } ret = setuid(0); /* set real UID = root */ if (ret != 0) { fatal("Failed to set uid, %m"); } ret = setgid(getegid()); if (ret != 0) { fatal("failed to set gid, %m"); } #ifdef BSD /* Force the priority back to zero if pppd is running higher. */ if (setpriority (PRIO_PROCESS, 0, 0) < 0) warn("can't reset priority to 0: %m"); #endif /* run the program */ update_script_environment(); execve(prog, args, script_env); if (must_exist || errno != ENOENT) { /* have to reopen the log, there's nowhere else for the message to go. */ reopen_log(); syslog(LOG_ERR, "Can't execute %s: %m", prog); closelog(); } _exit(99); } /* * record_child - add a child process to the list for reap_kids * to use. */ void record_child(int pid, char *prog, void (*done)(void *), void *arg, int killable) { struct subprocess *chp; ++n_children; chp = (struct subprocess *) malloc(sizeof(struct subprocess)); if (chp == NULL) { warn("losing track of %s process", prog); } else { chp->pid = pid; chp->prog = prog; chp->done = done; chp->arg = arg; chp->next = children; chp->killable = killable; children = chp; } } /* * childwait_end - we got fed up waiting for the child processes to * exit, send them all a SIGTERM. */ static void childwait_end(void *arg) { struct subprocess *chp; for (chp = children; chp != NULL; chp = chp->next) { if (debug) dbglog("sending SIGTERM to process %d", chp->pid); kill(chp->pid, SIGTERM); } childwait_done = 1; } /* * forget_child - clean up after a dead child */ static void forget_child(int pid, int status) { struct subprocess *chp, **prevp; for (prevp = &children; (chp = *prevp) != NULL; prevp = &chp->next) { if (chp->pid == pid) { --n_children; *prevp = chp->next; break; } } if (WIFSIGNALED(status)) { warn("Child process %s (pid %d) terminated with signal %d", (chp? chp->prog: "??"), pid, WTERMSIG(status)); } else if (debug) dbglog("Script %s finished (pid %d), status = 0x%x", (chp? chp->prog: "??"), pid, WIFEXITED(status) ? WEXITSTATUS(status) : status); if (chp && chp->done) (*chp->done)(chp->arg); if (chp) free(chp); } /* * reap_kids - get status from any dead child processes, * and log a message for abnormal terminations. */ static int reap_kids(void) { int pid, status; if (n_children == 0) return 0; while ((pid = waitpid(-1, &status, WNOHANG)) != -1 && pid != 0) { forget_child(pid, status); } if (pid == -1) { if (errno == ECHILD) return -1; if (errno != EINTR) error("Error waiting for child process: %m"); } return 0; } struct notifier **get_notifier_by_type(ppp_notify_t type) { struct notifier **list[NF_MAX_NOTIFY] = { [NF_PID_CHANGE ] = &pidchange, [NF_PHASE_CHANGE] = &phasechange, [NF_EXIT ] = &exitnotify, [NF_SIGNALED ] = &sigreceived, [NF_IP_UP ] = &ip_up_notifier, [NF_IP_DOWN ] = &ip_down_notifier, #ifdef PPP_WITH_IPV6CP [NF_IPV6_UP ] = &ipv6_up_notifier, [NF_IPV6_DOWN ] = &ipv6_down_notifier, #endif [NF_AUTH_UP ] = &auth_up_notifier, [NF_LINK_DOWN ] = &link_down_notifier, [NF_FORK ] = &fork_notifier, }; return list[type]; } /* * add_notifier - add a new function to be called when something happens. */ void ppp_add_notify(ppp_notify_t type, ppp_notify_fn *func, void *arg) { struct notifier **notif = get_notifier_by_type(type); if (notif) { struct notifier *np = malloc(sizeof(struct notifier)); if (np == 0) novm("notifier struct"); np->next = *notif; np->func = func; np->arg = arg; *notif = np; } else { error("Could not find notifier function for: %d", type); } } /* * remove_notifier - remove a function from the list of things to * be called when something happens. */ void ppp_del_notify(ppp_notify_t type, ppp_notify_fn *func, void *arg) { struct notifier **notif = get_notifier_by_type(type); if (notif) { struct notifier *np; for (; (np = *notif) != 0; notif = &np->next) { if (np->func == func && np->arg == arg) { *notif = np->next; free(np); break; } } } else { error("Could not find notifier function for: %d", type); } } /* * notify - call a set of functions registered with add_notifier. */ void notify(struct notifier *notif, int val) { struct notifier *np; while ((np = notif) != 0) { notif = np->next; (*np->func)(np->arg, val); } } /* * novm - log an error message saying we ran out of memory, and die. */ void novm(char *msg) { fatal("Virtual memory exhausted allocating %s\n", msg); } /* * ppp_script_setenv - set an environment variable value to be used * for scripts that we run (e.g. ip-up, auth-up, etc.) */ void ppp_script_setenv(char *var, char *value, int iskey) { size_t varl = strlen(var); size_t vl = varl + strlen(value) + 2; int i; char *p, *newstring; newstring = (char *) malloc(vl+1); if (newstring == 0) return; *newstring++ = iskey; slprintf(newstring, vl, "%s=%s", var, value); /* check if this variable is already set */ if (script_env != 0) { for (i = 0; (p = script_env[i]) != 0; ++i) { if (strncmp(p, var, varl) == 0 && p[varl] == '=') { #ifdef PPP_WITH_TDB if (p[-1] && pppdb != NULL) delete_db_key(p); #endif free(p-1); script_env[i] = newstring; #ifdef PPP_WITH_TDB if (pppdb != NULL) { if (iskey) add_db_key(newstring); update_db_entry(); } #endif return; } } } else { /* no space allocated for script env. ptrs. yet */ i = 0; script_env = malloc(16 * sizeof(char *)); if (script_env == 0) { free(newstring - 1); return; } s_env_nalloc = 16; } if (!add_script_env(i, newstring)) return; #ifdef PPP_WITH_TDB if (pppdb != NULL) { if (iskey) add_db_key(newstring); update_db_entry(); } #endif } /* * ppp_script_unsetenv - remove a variable from the environment * for scripts. */ void ppp_script_unsetenv(char *var) { int vl = strlen(var); int i; char *p; if (script_env == 0) return; for (i = 0; (p = script_env[i]) != 0; ++i) { if (strncmp(p, var, vl) == 0 && p[vl] == '=') { #ifdef PPP_WITH_TDB if (p[-1] && pppdb != NULL) delete_db_key(p); #endif remove_script_env(i); break; } } #ifdef PPP_WITH_TDB if (pppdb != NULL) update_db_entry(); #endif } /* * Any arbitrary string used as a key for locking the database. * It doesn't matter what it is as long as all pppds use the same string. */ #define PPPD_LOCK_KEY "pppd lock" /* * lock_db - get an exclusive lock on the TDB database. * Used to ensure atomicity of various lookup/modify operations. */ void lock_db(void) { #ifdef PPP_WITH_TDB TDB_DATA key; key.dptr = PPPD_LOCK_KEY; key.dsize = strlen(key.dptr); tdb_chainlock(pppdb, key); #endif } /* * unlock_db - remove the exclusive lock obtained by lock_db. */ void unlock_db(void) { #ifdef PPP_WITH_TDB TDB_DATA key; key.dptr = PPPD_LOCK_KEY; key.dsize = strlen(key.dptr); tdb_chainunlock(pppdb, key); #endif } #ifdef PPP_WITH_TDB /* * update_db_entry - update our entry in the database. */ static void update_db_entry(void) { TDB_DATA key, dbuf; int vlen, i; char *p, *q, *vbuf; if (script_env == NULL) return; vlen = 0; for (i = 0; (p = script_env[i]) != 0; ++i) vlen += strlen(p) + 1; vbuf = malloc(vlen + 1); if (vbuf == 0) novm("database entry"); q = vbuf; for (i = 0; (p = script_env[i]) != 0; ++i) q += slprintf(q, vbuf + vlen - q, "%s;", p); key.dptr = db_key; key.dsize = strlen(db_key); dbuf.dptr = vbuf; dbuf.dsize = vlen; if (tdb_store(pppdb, key, dbuf, TDB_REPLACE)) error("tdb_store failed: %s", tdb_errorstr(pppdb)); if (vbuf) free(vbuf); } /* * add_db_key - add a key that we can use to look up our database entry. */ static void add_db_key(const char *str) { TDB_DATA key, dbuf; key.dptr = (char *) str; key.dsize = strlen(str); dbuf.dptr = db_key; dbuf.dsize = strlen(db_key); if (tdb_store(pppdb, key, dbuf, TDB_REPLACE)) error("tdb_store key failed: %s", tdb_errorstr(pppdb)); } /* * delete_db_key - delete a key for looking up our database entry. */ static void delete_db_key(const char *str) { TDB_DATA key; key.dptr = (char *) str; key.dsize = strlen(str); tdb_delete(pppdb, key); } /* * cleanup_db - delete all the entries we put in the database. */ static void cleanup_db(void) { TDB_DATA key; int i; char *p; key.dptr = db_key; key.dsize = strlen(db_key); tdb_delete(pppdb, key); for (i = 0; (p = script_env[i]) != 0; ++i) if (p[-1]) delete_db_key(p); } #endif /* PPP_WITH_TDB */ ppp-2.5.0/pppd/options.c0000644000175000017500000014204514407475306012060 00000000000000/* * options.c - handles option processing for PPP. * * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The name "Carnegie Mellon University" must not be used to * endorse or promote products derived from this software without * prior written permission. For permission or any legal * details, please contact * Office of Technology Transfer * Carnegie Mellon University * 5000 Forbes Avenue * Pittsburgh, PA 15213-3890 * (412) 268-4387, fax: (412) 268-7395 * tech-transfer@andrew.cmu.edu * * 4. Redistributions of any form whatsoever must retain the following * acknowledgment: * "This product includes software developed by Computing Services * at Carnegie Mellon University (http://www.cmu.edu/computing/)." * * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include #include #include #include #include #include #ifdef PPP_WITH_PLUGINS #include #endif #ifdef PPP_WITH_FILTER #include /* * There have been 3 or 4 different names for this in libpcap CVS, but * this seems to be what they have settled on... * For older versions of libpcap, use DLT_PPP - but that means * we lose the inbound and outbound qualifiers. */ #ifndef DLT_PPP_PPPD #ifdef DLT_PPP_WITHDIRECTION #define DLT_PPP_PPPD DLT_PPP_WITHDIRECTION #else #define DLT_PPP_PPPD DLT_PPP #endif #endif #endif /* PPP_WITH_FILTER */ #include "pppd-private.h" #include "options.h" #include "upap.h" #include "pathnames.h" #if defined(ultrix) || defined(NeXT) char *strdup(char *); #endif struct option_value { struct option_value *next; const char *source; char value[1]; }; /* * Option variables and default values. */ int debug = 0; /* Debug flag */ int kdebugflag = 0; /* Tell kernel to print debug messages */ int default_device = 1; /* Using /dev/tty or equivalent */ bool nodetach = 0; /* Don't detach from controlling tty */ bool updetach = 0; /* Detach once link is up */ bool master_detach; /* Detach when we're (only) multilink master */ #ifdef SYSTEMD bool up_sdnotify = 0; /* Notify systemd once link is up */ #endif int maxconnect = 0; /* Maximum connect time */ char user[MAXNAMELEN]; /* Username for PAP */ char passwd[MAXSECRETLEN]; /* Password for PAP */ bool persist = 0; /* Reopen link after it goes down */ char our_name[MAXNAMELEN]; /* Our name for authentication purposes */ bool demand = 0; /* do dial-on-demand */ int idle_time_limit = 0; /* Disconnect if idle for this many seconds */ int holdoff = 30; /* # seconds to pause before reconnecting */ bool holdoff_specified; /* true if a holdoff value has been given */ int log_to_fd = 1; /* send log messages to this fd too */ bool log_default = 1; /* log_to_fd is default (stdout) */ int maxfail = 10; /* max # of unsuccessful connection attempts */ char linkname[MAXPATHLEN]; /* logical name for link */ bool tune_kernel; /* may alter kernel settings */ int connect_delay = 1000; /* wait this many ms after connect script */ int req_unit = -1; /* requested interface unit */ char path_ipup[MAXPATHLEN]; /* pathname of ip-up script */ char path_ipdown[MAXPATHLEN];/* pathname of ip-down script */ char req_ifname[IFNAMSIZ]; /* requested interface name */ bool multilink = 0; /* Enable multilink operation */ char *bundle_name = NULL; /* bundle name for multilink */ bool dump_options; /* print out option values */ bool show_options; /* print all supported options and exit */ bool dryrun; /* print out option values and exit */ char *domain; /* domain name set by domain option */ int child_wait = 5; /* # seconds to wait for children at exit */ struct userenv *userenv_list; /* user environment variables */ int dfl_route_metric = -1; /* metric of the default route to set over the PPP link */ #ifdef PPP_WITH_IPV6CP char path_ipv6up[MAXPATHLEN]; /* pathname of ipv6-up script */ char path_ipv6down[MAXPATHLEN]; /* pathname of ipv6-down script */ #endif unsigned int maxoctets = 0; /* default - no limit */ session_limit_dir_t maxoctets_dir = PPP_OCTETS_DIRECTION_SUM; /* default - sum of traffic */ int maxoctets_timeout = 1; /* default 1 second */ extern struct option auth_options[]; extern struct stat devstat; #ifdef PPP_WITH_FILTER struct bpf_program pass_filter;/* Filter program for packets to pass */ struct bpf_program active_filter; /* Filter program for link-active pkts */ #endif static struct option *curopt; /* pointer to option being processed */ char *current_option; /* the name of the option being parsed */ int privileged_option; /* set iff the current option came from root */ char *option_source; /* string saying where the option came from */ int option_priority = OPRIO_CFGFILE; /* priority of the current options */ bool devnam_fixed; /* can no longer change device name */ static int logfile_fd = -1; /* fd opened for log file */ static char logfile_name[MAXPATHLEN]; /* name of log file */ static bool noipx_opt; /* dummy for noipx option */ /* * Prototypes */ static int setdomain(char **); static int readfile(char **); static int callfile(char **); static int showversion(char **); static int showhelp(char **); static void usage(void); static int setlogfile(char **); #ifdef PPP_WITH_PLUGINS static int loadplugin(char **); #endif #ifdef PPP_WITH_FILTER static int setpassfilter(char **); static int setactivefilter(char **); #endif static int setmodir(char **); static int user_setenv(char **); static void user_setprint(struct option *, printer_func, void *); static int user_unsetenv(char **); static void user_unsetprint(struct option *, printer_func, void *); static struct option *find_option(char *name); static int process_option(struct option *, char *, char **); static int n_arguments(struct option *); static int number_option(char *, u_int32_t *, int); /* * Structure to store extra lists of options. */ struct option_list { struct option *options; struct option_list *next; }; static struct option_list *extra_options = NULL; /* * Valid arguments. */ struct option general_options[] = { { "debug", o_int, &debug, "Increase debugging level", OPT_INC | OPT_NOARG | 1 }, { "-d", o_int, &debug, "Increase debugging level", OPT_ALIAS | OPT_INC | OPT_NOARG | 1 }, { "kdebug", o_int, &kdebugflag, "Set kernel driver debug level", OPT_PRIO }, { "nodetach", o_bool, &nodetach, "Don't detach from controlling tty", OPT_PRIO | 1 }, { "-detach", o_bool, &nodetach, "Don't detach from controlling tty", OPT_ALIAS | OPT_PRIOSUB | 1 }, #ifdef SYSTEMD { "up_sdnotify", o_bool, &up_sdnotify, "Notify systemd once link is up (implies nodetach)", OPT_PRIOSUB | OPT_A2COPY | 1, &nodetach }, #endif { "updetach", o_bool, &updetach, "Detach from controlling tty once link is up", OPT_PRIOSUB | OPT_A2CLR | 1, &nodetach }, { "master_detach", o_bool, &master_detach, "Detach when we're multilink master but have no link", 1 }, { "holdoff", o_int, &holdoff, "Set time in seconds before retrying connection", OPT_PRIO, &holdoff_specified }, { "idle", o_int, &idle_time_limit, "Set time in seconds before disconnecting idle link", OPT_PRIO }, { "maxconnect", o_int, &maxconnect, "Set connection time limit", OPT_PRIO | OPT_LLIMIT | OPT_NOINCR | OPT_ZEROINF }, { "domain", o_special, (void *)setdomain, "Add given domain name to hostname", OPT_PRIO | OPT_PRIV | OPT_A2STRVAL, &domain }, { "file", o_special, (void *)readfile, "Take options from a file", OPT_NOPRINT }, { "call", o_special, (void *)callfile, "Take options from a privileged file", OPT_NOPRINT }, { "persist", o_bool, &persist, "Keep on reopening connection after close", OPT_PRIO | 1 }, { "nopersist", o_bool, &persist, "Turn off persist option", OPT_PRIOSUB }, { "demand", o_bool, &demand, "Dial on demand", OPT_INITONLY | 1, &persist }, { "--version", o_special_noarg, (void *)showversion, "Show version number" }, { "-v", o_special_noarg, (void *)showversion, "Show version number" }, { "show-options", o_bool, &show_options, "Show all options and exit", 1 }, { "--help", o_special_noarg, (void *)showhelp, "Show brief listing of options" }, { "-h", o_special_noarg, (void *)showhelp, "Show brief listing of options", OPT_ALIAS }, { "logfile", o_special, (void *)setlogfile, "Append log messages to this file", OPT_PRIO | OPT_A2STRVAL | OPT_STATIC, &logfile_name }, { "logfd", o_int, &log_to_fd, "Send log messages to this file descriptor", OPT_PRIOSUB | OPT_A2CLR, &log_default }, { "nolog", o_int, &log_to_fd, "Don't send log messages to any file", OPT_PRIOSUB | OPT_NOARG | OPT_VAL(-1) }, { "nologfd", o_int, &log_to_fd, "Don't send log messages to any file descriptor", OPT_PRIOSUB | OPT_ALIAS | OPT_NOARG | OPT_VAL(-1) }, { "linkname", o_string, linkname, "Set logical name for link", OPT_PRIO | OPT_PRIV | OPT_STATIC, NULL, MAXPATHLEN }, { "maxfail", o_int, &maxfail, "Maximum number of unsuccessful connection attempts to allow", OPT_PRIO }, { "ktune", o_bool, &tune_kernel, "Alter kernel settings as necessary", OPT_PRIO | 1 }, { "noktune", o_bool, &tune_kernel, "Don't alter kernel settings", OPT_PRIOSUB }, { "connect-delay", o_int, &connect_delay, "Maximum time (in ms) to wait after connect script finishes", OPT_PRIO }, { "unit", o_int, &req_unit, "PPP interface unit number to use if possible", OPT_PRIO | OPT_LLIMIT, 0, 0 }, { "ifname", o_string, req_ifname, "Set PPP interface name", OPT_PRIO | OPT_PRIV | OPT_STATIC, NULL, IFNAMSIZ }, { "dump", o_bool, &dump_options, "Print out option values after parsing all options", 1 }, { "dryrun", o_bool, &dryrun, "Stop after parsing, printing, and checking options", 1 }, { "child-timeout", o_int, &child_wait, "Number of seconds to wait for child processes at exit", OPT_PRIO }, { "set", o_special, (void *)user_setenv, "Set user environment variable", OPT_A2PRINTER | OPT_NOPRINT, (void *)user_setprint }, { "unset", o_special, (void *)user_unsetenv, "Unset user environment variable", OPT_A2PRINTER | OPT_NOPRINT, (void *)user_unsetprint }, { "defaultroute-metric", o_int, &dfl_route_metric, "Metric to use for the default route (Linux only; -1 for default behavior)", OPT_PRIV|OPT_LLIMIT|OPT_INITONLY, NULL, 0, -1 }, { "ip-up-script", o_string, path_ipup, "Set pathname of ip-up script", OPT_PRIV|OPT_STATIC, NULL, MAXPATHLEN }, { "ip-down-script", o_string, path_ipdown, "Set pathname of ip-down script", OPT_PRIV|OPT_STATIC, NULL, MAXPATHLEN }, #ifdef PPP_WITH_IPV6CP { "ipv6-up-script", o_string, path_ipv6up, "Set pathname of ipv6-up script", OPT_PRIV|OPT_STATIC, NULL, MAXPATHLEN }, { "ipv6-down-script", o_string, path_ipv6down, "Set pathname of ipv6-down script", OPT_PRIV|OPT_STATIC, NULL, MAXPATHLEN }, #endif #ifdef PPP_WITH_MULTILINK { "multilink", o_bool, &multilink, "Enable multilink operation", OPT_PRIO | 1 }, { "mp", o_bool, &multilink, "Enable multilink operation", OPT_PRIOSUB | OPT_ALIAS | 1 }, { "nomultilink", o_bool, &multilink, "Disable multilink operation", OPT_PRIOSUB | 0 }, { "nomp", o_bool, &multilink, "Disable multilink operation", OPT_PRIOSUB | OPT_ALIAS | 0 }, { "bundle", o_string, &bundle_name, "Bundle name for multilink", OPT_PRIO }, #endif /* PPP_WITH_MULTILINK */ #ifdef PPP_WITH_PLUGINS { "plugin", o_special, (void *)loadplugin, "Load a plug-in module into pppd", OPT_PRIV | OPT_A2LIST }, #endif #ifdef PPP_WITH_FILTER { "pass-filter", o_special, setpassfilter, "set filter for packets to pass", OPT_PRIO }, { "active-filter", o_special, setactivefilter, "set filter for active pkts", OPT_PRIO }, #endif { "maxoctets", o_int, &maxoctets, "Set connection traffic limit", OPT_PRIO | OPT_LLIMIT | OPT_NOINCR | OPT_ZEROINF }, { "mo", o_int, &maxoctets, "Set connection traffic limit", OPT_ALIAS | OPT_PRIO | OPT_LLIMIT | OPT_NOINCR | OPT_ZEROINF }, { "mo-direction", o_special, setmodir, "Set direction for limit traffic (sum,in,out,max)" }, { "mo-timeout", o_int, &maxoctets_timeout, "Check for traffic limit every N seconds", OPT_PRIO | OPT_LLIMIT | 1 }, /* Dummy option, does nothing */ { "noipx", o_bool, &noipx_opt, NULL, OPT_NOPRINT | 1 }, { NULL } }; #ifndef IMPLEMENTATION #define IMPLEMENTATION "" #endif int ppp_get_max_idle_time() { return idle_time_limit; } void ppp_set_max_idle_time(unsigned int max) { idle_time_limit = max; } int ppp_get_max_connect_time() { return maxconnect; } void ppp_set_max_connect_time(unsigned int max) { maxconnect = max; } void ppp_set_session_limit(unsigned int octets) { maxoctets = octets; } void ppp_set_session_limit_dir(unsigned int dir) { if (dir > 4) dir = PPP_OCTETS_DIRECTION_SUM; maxoctets_dir = (session_limit_dir_t) dir; } bool debug_on() { return !!debug; } int ppp_get_path(ppp_path_t type, char *buf, size_t bufsz) { const char *path; if (buf && bufsz > 0) { switch (type) { case PPP_DIR_LOG: path = PPP_PATH_VARLOG; break; case PPP_DIR_RUNTIME: path = PPP_PATH_VARRUN; break; #ifdef PPP_WITH_PLUGINS case PPP_DIR_PLUGIN: path = PPP_PATH_PLUGIN; break; #endif case PPP_DIR_CONF: path = PPP_PATH_CONFDIR; break; } return strlcpy(buf, path, bufsz); } return -1; } int ppp_get_filepath(ppp_path_t type, const char *name, char *buf, size_t bufsz) { const char *path; if (buf && bufsz > 0) { switch (type) { case PPP_DIR_LOG: path = PPP_PATH_VARLOG; break; case PPP_DIR_RUNTIME: path = PPP_PATH_VARRUN; break; #ifdef PPP_WITH_PLUGINS case PPP_DIR_PLUGIN: path = PPP_PATH_PLUGIN; break; #endif case PPP_DIR_CONF: path = PPP_PATH_CONFDIR; break; } return slprintf(buf, bufsz, "%s/%s", path, name); } return -1; } bool ppp_persist() { return !!persist; } /* * parse_args - parse a string of arguments from the command line. */ int parse_args(int argc, char **argv) { char *arg; struct option *opt; int n; privileged_option = privileged; option_source = "command line"; option_priority = OPRIO_CMDLINE; while (argc > 0) { arg = *argv++; --argc; opt = find_option(arg); if (opt == NULL) { ppp_option_error("unrecognized option '%s'", arg); usage(); return 0; } n = n_arguments(opt); if (argc < n) { ppp_option_error("too few parameters for option %s", arg); return 0; } if (!process_option(opt, arg, argv)) return 0; argc -= n; argv += n; } return 1; } /* * options_from_file - Read a string of options from a file, * and interpret them. */ int ppp_options_from_file(char *filename, int must_exist, int check_prot, int priv) { FILE *f; int i, newline, ret, err; struct option *opt; int oldpriv, n; char *oldsource; uid_t euid; char *argv[MAXARGS]; char args[MAXARGS][MAXWORDLEN]; char cmd[MAXWORDLEN]; euid = geteuid(); if (check_prot && seteuid(getuid()) == -1) { ppp_option_error("unable to drop privileges to open %s: %m", filename); return 0; } f = fopen(filename, "r"); err = errno; if (check_prot && seteuid(euid) == -1) fatal("unable to regain privileges"); if (f == NULL) { errno = err; if (!must_exist) { if (err != ENOENT && err != ENOTDIR) warn("Warning: can't open options file %s: %m", filename); return 1; } ppp_option_error("Can't open options file %s: %m", filename); return 0; } oldpriv = privileged_option; privileged_option = priv; oldsource = option_source; option_source = strdup(filename); if (option_source == NULL) option_source = "file"; ret = 0; while (getword(f, cmd, &newline, filename)) { opt = find_option(cmd); if (opt == NULL) { ppp_option_error("In file %s: unrecognized option '%s'", filename, cmd); goto err; } n = n_arguments(opt); for (i = 0; i < n; ++i) { if (!getword(f, args[i], &newline, filename)) { ppp_option_error( "In file %s: too few parameters for option '%s'", filename, cmd); goto err; } argv[i] = args[i]; } if (!process_option(opt, cmd, argv)) goto err; } ret = 1; err: fclose(f); privileged_option = oldpriv; option_source = oldsource; return ret; } /* * options_from_user - See if the use has a ~/.ppprc file, * and if so, interpret options from it. */ int options_from_user(void) { char *user, *path, *file; int ret; struct passwd *pw; size_t pl; pw = getpwuid(getuid()); if (pw == NULL || (user = pw->pw_dir) == NULL || user[0] == 0) return 1; file = PPP_PATH_USEROPT; pl = strlen(user) + strlen(file) + 2; path = malloc(pl); if (path == NULL) novm("init file name"); slprintf(path, pl, "%s/%s", user, file); option_priority = OPRIO_CFGFILE; ret = ppp_options_from_file(path, 0, 1, privileged); free(path); return ret; } /* * options_for_tty - See if an options file exists for the serial * device, and if so, interpret options from it. * We only allow the per-tty options file to override anything from * the command line if it is something that the user can't override * once it has been set by root; this is done by giving configuration * files a lower priority than the command line. */ int options_for_tty(void) { char *dev, *path, *p; int ret; size_t pl; dev = devnam; if ((p = strstr(dev, "/dev/")) != NULL) dev = p + 5; if (dev[0] == 0 || strcmp(dev, "tty") == 0) return 1; /* don't look for /etc/ppp/options.tty */ pl = strlen(PPP_PATH_TTYOPT) + strlen(dev) + 1; path = malloc(pl); if (path == NULL) novm("tty init file name"); slprintf(path, pl, "%s%s", PPP_PATH_TTYOPT, dev); /* Turn slashes into dots, for Solaris case (e.g. /dev/term/a) */ for (p = path + strlen(PPP_PATH_TTYOPT); *p != 0; ++p) if (*p == '/') *p = '.'; option_priority = OPRIO_CFGFILE; ret = ppp_options_from_file(path, 0, 0, 1); free(path); return ret; } /* * options_from_list - process a string of options in a wordlist. */ int options_from_list(struct wordlist *w, int priv) { char *argv[MAXARGS]; struct option *opt; int i, n, ret = 0; struct wordlist *w0; privileged_option = priv; option_source = "secrets file"; option_priority = OPRIO_SECFILE; while (w != NULL) { opt = find_option(w->word); if (opt == NULL) { ppp_option_error("In secrets file: unrecognized option '%s'", w->word); goto err; } n = n_arguments(opt); w0 = w; for (i = 0; i < n; ++i) { w = w->next; if (w == NULL) { ppp_option_error( "In secrets file: too few parameters for option '%s'", w0->word); goto err; } argv[i] = w->word; } if (!process_option(opt, w0->word, argv)) goto err; w = w->next; } ret = 1; err: return ret; } /* * match_option - see if this option matches an option structure. */ static int match_option(char *name, struct option *opt, int dowild) { int (*match)(char *, char **, int); if (dowild != (opt->type == o_wild)) return 0; if (!dowild) return strcmp(name, opt->name) == 0; match = (int (*)(char *, char **, int)) opt->addr; return (*match)(name, NULL, 0); } /* * find_option - scan the option lists for the various protocols * looking for an entry with the given name. * This could be optimized by using a hash table. */ static struct option * find_option(char *name) { struct option *opt; struct option_list *list; int i, dowild; for (dowild = 0; dowild <= 1; ++dowild) { for (opt = general_options; opt->name != NULL; ++opt) if (match_option(name, opt, dowild)) return opt; for (opt = auth_options; opt->name != NULL; ++opt) if (match_option(name, opt, dowild)) return opt; for (list = extra_options; list != NULL; list = list->next) for (opt = list->options; opt->name != NULL; ++opt) if (match_option(name, opt, dowild)) return opt; for (opt = the_channel->options; opt->name != NULL; ++opt) if (match_option(name, opt, dowild)) return opt; for (i = 0; protocols[i] != NULL; ++i) if ((opt = protocols[i]->options) != NULL) for (; opt->name != NULL; ++opt) if (match_option(name, opt, dowild)) return opt; } return NULL; } /* * process_option - process one new-style option. */ static int process_option(struct option *opt, char *cmd, char **argv) { u_int32_t v; int iv, a; char *sv; int (*parser)(char **); int (*wildp)(char *, char **, int); char *optopt = (opt->type == o_wild)? "": " option"; int prio = option_priority; struct option *mainopt = opt; current_option = opt->name; if ((opt->flags & OPT_PRIVFIX) && privileged_option) prio += OPRIO_ROOT; while (mainopt->flags & OPT_PRIOSUB) --mainopt; if (mainopt->flags & OPT_PRIO) { if (prio < mainopt->priority) { /* new value doesn't override old */ if (prio == OPRIO_CMDLINE && mainopt->priority > OPRIO_ROOT) { ppp_option_error("%s%s set in %s cannot be overridden\n", opt->name, optopt, mainopt->source); return 0; } return 1; } if (prio > OPRIO_ROOT && mainopt->priority == OPRIO_CMDLINE) warn("%s%s from %s overrides command line", opt->name, optopt, option_source); } if ((opt->flags & OPT_INITONLY) && !in_phase(PHASE_INITIALIZE)) { ppp_option_error("%s%s cannot be changed after initialization", opt->name, optopt); return 0; } if ((opt->flags & OPT_PRIV) && !privileged_option) { ppp_option_error("using the %s%s requires root privilege", opt->name, optopt); return 0; } if ((opt->flags & OPT_ENABLE) && *(bool *)(opt->addr2) == 0) { ppp_option_error("%s%s is disabled", opt->name, optopt); return 0; } if ((opt->flags & OPT_DEVEQUIV) && devnam_fixed) { ppp_option_error("the %s%s may not be changed in %s", opt->name, optopt, option_source); return 0; } switch (opt->type) { case o_bool: v = opt->flags & OPT_VALUE; *(bool *)(opt->addr) = v; if (opt->addr2 && (opt->flags & OPT_A2COPY)) *(bool *)(opt->addr2) = v; else if (opt->addr2 && (opt->flags & OPT_A2CLR)) *(bool *)(opt->addr2) = 0; else if (opt->addr2 && (opt->flags & OPT_A2CLRB)) *(u_char *)(opt->addr2) &= ~v; else if (opt->addr2 && (opt->flags & OPT_A2OR)) *(u_char *)(opt->addr2) |= v; break; case o_int: iv = 0; if ((opt->flags & OPT_NOARG) == 0) { if (!ppp_int_option(*argv, &iv)) return 0; if ((((opt->flags & OPT_LLIMIT) && iv < opt->lower_limit) || ((opt->flags & OPT_ULIMIT) && iv > opt->upper_limit)) && !((opt->flags & OPT_ZEROOK && iv == 0))) { char *zok = (opt->flags & OPT_ZEROOK)? " zero or": ""; switch (opt->flags & OPT_LIMITS) { case OPT_LLIMIT: ppp_option_error("%s value must be%s >= %d", opt->name, zok, opt->lower_limit); break; case OPT_ULIMIT: ppp_option_error("%s value must be%s <= %d", opt->name, zok, opt->upper_limit); break; case OPT_LIMITS: ppp_option_error("%s value must be%s between %d and %d", opt->name, zok, opt->lower_limit, opt->upper_limit); break; } return 0; } } a = opt->flags & OPT_VALUE; if (a >= 128) a -= 256; /* sign extend */ iv += a; if (opt->flags & OPT_INC) iv += *(int *)(opt->addr); if ((opt->flags & OPT_NOINCR) && !privileged_option) { int oldv = *(int *)(opt->addr); if ((opt->flags & OPT_ZEROINF) ? (oldv != 0 && (iv == 0 || iv > oldv)) : (iv > oldv)) { ppp_option_error("%s value cannot be increased", opt->name); return 0; } } *(int *)(opt->addr) = iv; if (opt->addr2 && (opt->flags & OPT_A2COPY)) *(int *)(opt->addr2) = iv; break; case o_uint32: if (opt->flags & OPT_NOARG) { v = opt->flags & OPT_VALUE; if (v & 0x80) v |= 0xffffff00U; } else if (!number_option(*argv, &v, 16)) return 0; if (opt->flags & OPT_OR) v |= *(u_int32_t *)(opt->addr); *(u_int32_t *)(opt->addr) = v; if (opt->addr2 && (opt->flags & OPT_A2COPY)) *(u_int32_t *)(opt->addr2) = v; break; case o_string: if (opt->flags & OPT_STATIC) { strlcpy((char *)(opt->addr), *argv, opt->upper_limit); } else { char **optptr = (char **)(opt->addr); sv = strdup(*argv); if (sv == NULL) novm("option argument"); if (*optptr) free(*optptr); *optptr = sv; } /* obfuscate original argument for things like password */ if (opt->flags & OPT_HIDE) { memset(*argv, '?', strlen(*argv)); *argv = "********"; } break; case o_special_noarg: case o_special: parser = (int (*)(char **)) opt->addr; curopt = opt; if (!(*parser)(argv)) return 0; if (opt->flags & OPT_A2LIST) { struct option_value *ovp, *pp; ovp = malloc(sizeof(*ovp) + strlen(*argv)); if (ovp != 0) { strcpy(ovp->value, *argv); ovp->source = option_source; ovp->next = NULL; if (opt->addr2 == NULL) { opt->addr2 = ovp; } else { for (pp = opt->addr2; pp->next != NULL; pp = pp->next) ; pp->next = ovp; } } } break; case o_wild: wildp = (int (*)(char *, char **, int)) opt->addr; if (!(*wildp)(cmd, argv, 1)) return 0; break; } /* * If addr2 wasn't used by any flag (OPT_A2COPY, etc.) but is set, * treat it as a bool and set/clear it based on the OPT_A2CLR bit. */ if (opt->addr2 && (opt->flags & (OPT_A2COPY|OPT_ENABLE |OPT_A2PRINTER|OPT_A2STRVAL|OPT_A2LIST|OPT_A2OR)) == 0) *(bool *)(opt->addr2) = !(opt->flags & OPT_A2CLR); mainopt->source = option_source; mainopt->priority = prio; mainopt->winner = opt - mainopt; return 1; } /* * override_value - if the option priorities would permit us to * override the value of option, return 1 and update the priority * and source of the option value. Otherwise returns 0. */ int override_value(char *option, int priority, const char *source) { struct option *opt; opt = find_option(option); if (opt == NULL) return 0; while (opt->flags & OPT_PRIOSUB) --opt; if ((opt->flags & OPT_PRIO) && priority < opt->priority) return 0; opt->priority = priority; opt->source = source; opt->winner = -1; return 1; } /* * n_arguments - tell how many arguments an option takes */ static int n_arguments(struct option *opt) { return (opt->type == o_bool || opt->type == o_special_noarg || (opt->flags & OPT_NOARG))? 0: 1; } /* * add_options - add a list of options to the set we grok. */ void ppp_add_options(struct option *opt) { struct option_list *list; list = malloc(sizeof(*list)); if (list == 0) novm("option list entry"); list->options = opt; list->next = extra_options; extra_options = list; } /* * check_options - check that options are valid and consistent. */ void check_options(void) { if (logfile_fd >= 0 && logfile_fd != log_to_fd) close(logfile_fd); } /* * print_option - print out an option and its value */ static void print_option(struct option *opt, struct option *mainopt, printer_func printer, void *arg) { int i, v; char *p; if (opt->flags & OPT_NOPRINT) return; switch (opt->type) { case o_bool: v = opt->flags & OPT_VALUE; if (*(bool *)opt->addr != v) /* this can happen legitimately, e.g. lock option turned off for default device */ break; printer(arg, "%s", opt->name); break; case o_int: v = opt->flags & OPT_VALUE; if (v >= 128) v -= 256; i = *(int *)opt->addr; if (opt->flags & OPT_NOARG) { printer(arg, "%s", opt->name); if (i != v) { if (opt->flags & OPT_INC) { for (; i > v; i -= v) printer(arg, " %s", opt->name); } else printer(arg, " # oops: %d not %d\n", i, v); } } else { printer(arg, "%s %d", opt->name, i); } break; case o_uint32: printer(arg, "%s", opt->name); if ((opt->flags & OPT_NOARG) == 0) printer(arg, " %x", *(u_int32_t *)opt->addr); break; case o_string: if (opt->flags & OPT_HIDE) { p = "??????"; } else { p = (char *) opt->addr; if ((opt->flags & OPT_STATIC) == 0) p = *(char **)p; } printer(arg, "%s %q", opt->name, p); break; case o_special: case o_special_noarg: case o_wild: if (opt->type != o_wild) { printer(arg, "%s", opt->name); if (n_arguments(opt) == 0) break; printer(arg, " "); } if (opt->flags & OPT_A2PRINTER) { void (*oprt)(struct option *, printer_func, void *); oprt = (void (*)(struct option *, printer_func, void *)) opt->addr2; (*oprt)(opt, printer, arg); } else if (opt->flags & OPT_A2STRVAL) { p = (char *) opt->addr2; if ((opt->flags & OPT_STATIC) == 0) p = *(char **)p; printer(arg, "%q", p); } else if (opt->flags & OPT_A2LIST) { struct option_value *ovp; ovp = (struct option_value *) opt->addr2; for (;;) { printer(arg, "%q", ovp->value); if ((ovp = ovp->next) == NULL) break; printer(arg, "\t\t# (from %s)\n%s ", ovp->source, opt->name); } } else { printer(arg, "xxx # [don't know how to print value]"); } break; default: printer(arg, "# %s value (type %d\?\?)", opt->name, opt->type); break; } printer(arg, "\t\t# (from %s)\n", mainopt->source); } /* * print_option_list - print out options in effect from an * array of options. */ static void print_option_list(struct option *opt, printer_func printer, void *arg) { while (opt->name != NULL) { if (opt->priority != OPRIO_DEFAULT && opt->winner != (short int) -1) print_option(opt + opt->winner, opt, printer, arg); do { ++opt; } while (opt->flags & OPT_PRIOSUB); } } /* * print_options - print out what options are in effect. */ void print_options(printer_func printer, void *arg) { struct option_list *list; int i; printer(arg, "pppd options in effect:\n"); print_option_list(general_options, printer, arg); print_option_list(auth_options, printer, arg); for (list = extra_options; list != NULL; list = list->next) print_option_list(list->options, printer, arg); print_option_list(the_channel->options, printer, arg); for (i = 0; protocols[i] != NULL; ++i) print_option_list(protocols[i]->options, printer, arg); } /* * usage - print out a message telling how to use the program. */ static void usage(void) { FILE *fp = stderr; if (in_phase(PHASE_INITIALIZE)) { fprintf(fp, "%s v%s\n", PACKAGE_NAME, PACKAGE_VERSION); fprintf(fp, "Copyright (C) 1999-2022 Paul Mackerras, and others. All rights reserved.\n\n"); fprintf(fp, "License BSD: The 3 clause BSD license \n"); fprintf(fp, "This is free software: you are free to change and redistribute it.\n"); fprintf(fp, "There is NO WARRANTY, to the extent permitted by law.\n\n"); fprintf(fp, "Report Bugs:\n %s\n\n", PACKAGE_BUGREPORT); fprintf(fp, "Usage: %s [ options ], where options are:\n", progname); fprintf(fp, " Communicate over the named device\n"); fprintf(fp, " Set the baud rate to \n"); fprintf(fp, " : Set the local and/or remote interface IP\n"); fprintf(fp, " addresses. Either one may be omitted.\n"); fprintf(fp, " asyncmap Set the desired async map to hex \n"); fprintf(fp, " auth Require authentication from peer\n"); fprintf(fp, " connect

Invoke shell command

to set up the serial line\n"); fprintf(fp, " crtscts Use hardware RTS/CTS flow control\n"); fprintf(fp, " defaultroute Add default route through interface\n"); fprintf(fp, " file Take options from file \n"); fprintf(fp, " modem Use modem control lines\n"); fprintf(fp, " mru Set MRU value to for negotiation\n"); fprintf(fp, " show-options Display an extended list of options\n"); fprintf(fp, "See pppd(8) for more options.\n"); } } /* * showhelp - print out usage message and exit. */ static int showhelp(char **argv) { if (in_phase(PHASE_INITIALIZE)) { usage(); exit(0); } return 0; } /* * showversion - print out the version number and exit. */ static int showversion(char **argv) { if (in_phase(PHASE_INITIALIZE)) { fprintf(stdout, "pppd version %s\n", VERSION); exit(0); } return 0; } /* * Print a set of options including the name of the group of options */ static void showopts_list(FILE *fp, const char *title, struct option *list, ...) { struct option *opt = list; va_list varg; if (opt && opt->name) { va_start(varg, list); vfprintf(fp, title, varg); fprintf(fp, ":\n"); va_end(varg); do { fprintf(fp, " %-22s %s\n", opt->name, opt->description?:""); opt++; } while (opt && opt->name); fprintf(fp, "\n"); } } /* * Dumps the list of available options */ void showopts(void) { struct option_list *list; FILE *fp = stderr; int i = 0; showopts_list(fp, "General Options", general_options); showopts_list(fp, "Authentication Options", auth_options); for (list = extra_options; list != NULL; list = list->next) showopts_list(fp, "Extra Options", list->options); showopts_list(fp, "Channel Options", the_channel->options); for (i = 0; protocols[i] != NULL; ++i) { if (protocols[i]->options != NULL) { showopts_list(fp, "%s Options", protocols[i]->options, protocols[i]->name); } } } /* * ppp_option_error - print a message about an error in an option. * The message is logged, and also sent to * stderr if in_phase(PHASE_INITIALIZE). */ void ppp_option_error(char *fmt, ...) { va_list args; char buf[1024]; va_start(args, fmt); vslprintf(buf, sizeof(buf), fmt, args); va_end(args); if (in_phase(PHASE_INITIALIZE)) fprintf(stderr, "%s: %s\n", progname, buf); syslog(LOG_ERR, "%s", buf); } #if 0 /* * readable - check if a file is readable by the real user. */ int readable(int fd) { uid_t uid; int i; struct stat sbuf; uid = getuid(); if (uid == 0) return 1; if (fstat(fd, &sbuf) != 0) return 0; if (sbuf.st_uid == uid) return sbuf.st_mode & S_IRUSR; if (sbuf.st_gid == getgid()) return sbuf.st_mode & S_IRGRP; for (i = 0; i < ngroups; ++i) if (sbuf.st_gid == groups[i]) return sbuf.st_mode & S_IRGRP; return sbuf.st_mode & S_IROTH; } #endif /* * Read a word from a file. * Words are delimited by white-space or by quotes (" or '). * Quotes, white-space and \ may be escaped with \. * \ is ignored. */ int getword(FILE *f, char *word, int *newlinep, char *filename) { int c, len, escape; int quoted, comment; int value, digit, got, n; #define isoctal(c) ((c) >= '0' && (c) < '8') *newlinep = 0; len = 0; escape = 0; comment = 0; quoted = 0; /* * First skip white-space and comments. */ for (;;) { c = getc(f); if (c == EOF) break; /* * A newline means the end of a comment; backslash-newline * is ignored. Note that we cannot have escape && comment. */ if (c == '\n') { if (!escape) { *newlinep = 1; comment = 0; } else escape = 0; continue; } /* * Ignore characters other than newline in a comment. */ if (comment) continue; /* * If this character is escaped, we have a word start. */ if (escape) break; /* * If this is the escape character, look at the next character. */ if (c == '\\') { escape = 1; continue; } /* * If this is the start of a comment, ignore the rest of the line. */ if (c == '#') { comment = 1; continue; } /* * A non-whitespace character is the start of a word. */ if (!isspace(c)) break; } /* * Process characters until the end of the word. */ while (c != EOF) { if (escape) { /* * This character is escaped: backslash-newline is ignored, * various other characters indicate particular values * as for C backslash-escapes. */ escape = 0; if (c == '\n') { c = getc(f); continue; } got = 0; switch (c) { case 'a': value = '\a'; break; case 'b': value = '\b'; break; case 'f': value = '\f'; break; case 'n': value = '\n'; break; case 'r': value = '\r'; break; case 's': value = ' '; break; case 't': value = '\t'; break; default: if (isoctal(c)) { /* * \ddd octal sequence */ value = 0; for (n = 0; n < 3 && isoctal(c); ++n) { value = (value << 3) + (c & 07); c = getc(f); } got = 1; break; } if (c == 'x') { /* * \x sequence */ value = 0; c = getc(f); for (n = 0; n < 2 && isxdigit(c); ++n) { digit = toupper(c) - '0'; if (digit > 10) digit += '0' + 10 - 'A'; value = (value << 4) + digit; c = getc (f); } got = 1; break; } /* * Otherwise the character stands for itself. */ value = c; break; } /* * Store the resulting character for the escape sequence. */ if (len < MAXWORDLEN) { word[len] = value; ++len; } if (!got) c = getc(f); continue; } /* * Backslash starts a new escape sequence. */ if (c == '\\') { escape = 1; c = getc(f); continue; } /* * Not escaped: check for the start or end of a quoted * section and see if we've reached the end of the word. */ if (quoted) { if (c == quoted) { quoted = 0; c = getc(f); continue; } } else if (c == '"' || c == '\'') { quoted = c; c = getc(f); continue; } else if (isspace(c) || c == '#') { ungetc (c, f); break; } /* * An ordinary character: store it in the word and get another. */ if (len < MAXWORDLEN) { word[len] = c; ++len; } c = getc(f); } word[MAXWORDLEN-1] = 0; /* make sure word is null-terminated */ /* * End of the word: check for errors. */ if (c == EOF) { if (ferror(f)) { if (errno == 0) errno = EIO; ppp_option_error("Error reading %s: %m", filename); die(1); } /* * If len is zero, then we didn't find a word before the * end of the file. */ if (len == 0) return 0; if (quoted) ppp_option_error("warning: quoted word runs to end of file (%.20s...)", filename, word); } /* * Warn if the word was too long, and append a terminating null. */ if (len >= MAXWORDLEN) { ppp_option_error("warning: word in file %s too long (%.20s...)", filename, word); len = MAXWORDLEN - 1; } word[len] = 0; return 1; #undef isoctal } /* * number_option - parse an unsigned numeric parameter for an option. */ static int number_option(char *str, u_int32_t *valp, int base) { char *ptr; *valp = strtoul(str, &ptr, base); if (ptr == str) { ppp_option_error("invalid numeric parameter '%s' for %s option", str, current_option); return 0; } return 1; } /* * int_option - like number_option, but valp is int *, * the base is assumed to be 0, and *valp is not changed * if there is an error. */ int ppp_int_option(char *str, int *valp) { u_int32_t v; if (!number_option(str, &v, 0)) return 0; *valp = (int) v; return 1; } /* * The following procedures parse options. */ /* * readfile - take commands from a file. */ static int readfile(char **argv) { return ppp_options_from_file(*argv, 1, 1, privileged_option); } /* * callfile - take commands from /etc/ppp/peers/. * Name may not contain /../, start with / or ../, or end in /.. */ static int callfile(char **argv) { char *fname, *arg, *p; int l, ok; arg = *argv; ok = 1; if (arg[0] == '/' || arg[0] == 0) ok = 0; else { for (p = arg; *p != 0; ) { if (p[0] == '.' && p[1] == '.' && (p[2] == '/' || p[2] == 0)) { ok = 0; break; } while (*p != '/' && *p != 0) ++p; if (*p == '/') ++p; } } if (!ok) { ppp_option_error("call option value may not contain .. or start with /"); return 0; } l = strlen(arg) + strlen(PPP_PATH_PEERFILES) + 1; if ((fname = (char *) malloc(l)) == NULL) novm("call file name"); slprintf(fname, l, "%s%s", PPP_PATH_PEERFILES, arg); ppp_script_setenv("CALL_FILE", arg, 0); ok = ppp_options_from_file(fname, 1, 1, 1); free(fname); return ok; } #ifdef PPP_WITH_FILTER /* * setpassfilter - Set the pass filter for packets */ static int setpassfilter(char **argv) { pcap_t *pc; int ret = 1; pc = pcap_open_dead(DLT_PPP_PPPD, 65535); if (pcap_compile(pc, &pass_filter, *argv, 1, netmask) == -1) { ppp_option_error("error in pass-filter expression: %s\n", pcap_geterr(pc)); ret = 0; } pcap_close(pc); return ret; } /* * setactivefilter - Set the active filter for packets */ static int setactivefilter(char **argv) { pcap_t *pc; int ret = 1; pc = pcap_open_dead(DLT_PPP_PPPD, 65535); if (pcap_compile(pc, &active_filter, *argv, 1, netmask) == -1) { ppp_option_error("error in active-filter expression: %s\n", pcap_geterr(pc)); ret = 0; } pcap_close(pc); return ret; } #endif /* * setdomain - Set domain name to append to hostname */ static int setdomain(char **argv) { gethostname(hostname, MAXNAMELEN); if (**argv != 0) { if (**argv != '.') strncat(hostname, ".", MAXNAMELEN - strlen(hostname)); domain = hostname + strlen(hostname); strncat(hostname, *argv, MAXNAMELEN - strlen(hostname)); } hostname[MAXNAMELEN-1] = 0; return (1); } static int setlogfile(char **argv) { int fd, err; uid_t euid; euid = geteuid(); if (!privileged_option && seteuid(getuid()) == -1) { ppp_option_error("unable to drop permissions to open %s: %m", *argv); return 0; } fd = open(*argv, O_WRONLY | O_APPEND | O_CREAT | O_EXCL, 0644); if (fd < 0 && errno == EEXIST) fd = open(*argv, O_WRONLY | O_APPEND); err = errno; if (!privileged_option && seteuid(euid) == -1) fatal("unable to regain privileges: %m"); if (fd < 0) { errno = err; ppp_option_error("Can't open log file %s: %m", *argv); return 0; } strlcpy(logfile_name, *argv, sizeof(logfile_name)); if (logfile_fd >= 0) close(logfile_fd); logfile_fd = fd; log_to_fd = fd; log_default = 0; return 1; } static int setmodir(char **argv) { if(*argv == NULL) return 0; if(!strcmp(*argv,"in")) { maxoctets_dir = PPP_OCTETS_DIRECTION_IN; } else if (!strcmp(*argv,"out")) { maxoctets_dir = PPP_OCTETS_DIRECTION_OUT; } else if (!strcmp(*argv,"max")) { maxoctets_dir = PPP_OCTETS_DIRECTION_MAXOVERAL; } else { maxoctets_dir = PPP_OCTETS_DIRECTION_SUM; } return 1; } #ifdef PPP_WITH_PLUGINS static int loadplugin(char **argv) { char *arg = *argv; void *handle; const char *err; void (*init)(void); char *path = arg; const char *vers; if (strchr(arg, '/') == 0) { const char *base = PPP_PATH_PLUGIN; int l = strlen(base) + strlen(arg) + 2; path = malloc(l); if (path == 0) novm("plugin file path"); strlcpy(path, base, l); strlcat(path, "/", l); strlcat(path, arg, l); } handle = dlopen(path, RTLD_GLOBAL | RTLD_NOW); if (handle == 0) { err = dlerror(); if (err != 0) ppp_option_error("%s", err); ppp_option_error("Couldn't load plugin %s", arg); goto err; } init = (void (*)(void))dlsym(handle, "plugin_init"); if (init == 0) { ppp_option_error("%s has no initialization entry point", arg); goto errclose; } vers = (const char *) dlsym(handle, "pppd_version"); if (vers == 0) { warn("Warning: plugin %s has no version information", arg); } else if (strcmp(vers, VERSION) != 0) { ppp_option_error("Plugin %s is for pppd version %s, this is %s", arg, vers, VERSION); goto errclose; } info("Plugin %s loaded.", arg); (*init)(); if (path != arg) free(path); return 1; errclose: dlclose(handle); err: if (path != arg) free(path); return 0; } #endif /* PPP_WITH_PLUGINS */ /* * Set an environment variable specified by the user. */ static int user_setenv(char **argv) { char *arg = argv[0]; char *eqp; struct userenv *uep, **insp; if ((eqp = strchr(arg, '=')) == NULL) { ppp_option_error("missing = in name=value: %s", arg); return 0; } if (eqp == arg) { ppp_option_error("missing variable name: %s", arg); return 0; } for (uep = userenv_list; uep != NULL; uep = uep->ue_next) { int nlen = strlen(uep->ue_name); if (nlen == (eqp - arg) && strncmp(arg, uep->ue_name, nlen) == 0) break; } /* Ignore attempts by unprivileged users to override privileged sources */ if (uep != NULL && !privileged_option && uep->ue_priv) return 1; /* The name never changes, so allocate it with the structure */ if (uep == NULL) { uep = malloc(sizeof (*uep) + (eqp-arg)); strncpy(uep->ue_name, arg, eqp-arg); uep->ue_name[eqp-arg] = '\0'; uep->ue_next = NULL; insp = &userenv_list; while (*insp != NULL) insp = &(*insp)->ue_next; *insp = uep; } else { struct userenv *uep2; for (uep2 = userenv_list; uep2 != NULL; uep2 = uep2->ue_next) { if (uep2 != uep && !uep2->ue_isset) break; } if (uep2 == NULL && !uep->ue_isset) find_option("unset")->flags |= OPT_NOPRINT; free(uep->ue_value); } uep->ue_isset = 1; uep->ue_priv = privileged_option; uep->ue_source = option_source; uep->ue_value = strdup(eqp + 1); curopt->flags &= ~OPT_NOPRINT; return 1; } static void user_setprint(struct option *opt, printer_func printer, void *arg) { struct userenv *uep, *uepnext; uepnext = userenv_list; while (uepnext != NULL && !uepnext->ue_isset) uepnext = uepnext->ue_next; while ((uep = uepnext) != NULL) { uepnext = uep->ue_next; while (uepnext != NULL && !uepnext->ue_isset) uepnext = uepnext->ue_next; (*printer)(arg, "%s=%s", uep->ue_name, uep->ue_value); if (uepnext != NULL) (*printer)(arg, "\t\t# (from %s)\n%s ", uep->ue_source, opt->name); else opt->source = uep->ue_source; } } static int user_unsetenv(char **argv) { struct userenv *uep, **insp; char *arg = argv[0]; if (strchr(arg, '=') != NULL) { ppp_option_error("unexpected = in name: %s", arg); return 0; } if (*arg == '\0') { ppp_option_error("missing variable name for unset"); return 0; } for (uep = userenv_list; uep != NULL; uep = uep->ue_next) { if (strcmp(arg, uep->ue_name) == 0) break; } /* Ignore attempts by unprivileged users to override privileged sources */ if (uep != NULL && !privileged_option && uep->ue_priv) return 1; /* The name never changes, so allocate it with the structure */ if (uep == NULL) { uep = malloc(sizeof (*uep) + strlen(arg)); strcpy(uep->ue_name, arg); uep->ue_next = NULL; insp = &userenv_list; while (*insp != NULL) insp = &(*insp)->ue_next; *insp = uep; } else { struct userenv *uep2; for (uep2 = userenv_list; uep2 != NULL; uep2 = uep2->ue_next) { if (uep2 != uep && uep2->ue_isset) break; } if (uep2 == NULL && uep->ue_isset) find_option("set")->flags |= OPT_NOPRINT; free(uep->ue_value); } uep->ue_isset = 0; uep->ue_priv = privileged_option; uep->ue_source = option_source; uep->ue_value = NULL; curopt->flags &= ~OPT_NOPRINT; return 1; } static void user_unsetprint(struct option *opt, printer_func printer, void *arg) { struct userenv *uep, *uepnext; uepnext = userenv_list; while (uepnext != NULL && uepnext->ue_isset) uepnext = uepnext->ue_next; while ((uep = uepnext) != NULL) { uepnext = uep->ue_next; while (uepnext != NULL && uepnext->ue_isset) uepnext = uepnext->ue_next; (*printer)(arg, "%s", uep->ue_name); if (uepnext != NULL) (*printer)(arg, "\t\t# (from %s)\n%s ", uep->ue_source, opt->name); else opt->source = uep->ue_source; } } ppp-2.5.0/pppd/session.c0000644000175000017500000003211014353435407012035 00000000000000/* * session.c - PPP session control. * * Copyright (c) 2007 Diego Rivera. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. The name(s) of the authors of this software must not be used to * endorse or promote products derived from this software without * prior written permission. * * 3. Redistributions of any form whatsoever must retain the following * acknowledgment: * "This product includes software developed by Paul Mackerras * ". * * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * Derived from auth.c, which is: * * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The name "Carnegie Mellon University" must not be used to * endorse or promote products derived from this software without * prior written permission. For permission or any legal * details, please contact * Office of Technology Transfer * Carnegie Mellon University * 5000 Forbes Avenue * Pittsburgh, PA 15213-3890 * (412) 268-4387, fax: (412) 268-7395 * tech-transfer@andrew.cmu.edu * * 4. Redistributions of any form whatsoever must retain the following * acknowledgment: * "This product includes software developed by Computing Services * at Carnegie Mellon University (http://www.cmu.edu/computing/)." * * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #ifdef HAVE_CRYPT_H #include #endif #ifdef HAVE_SHADOW_H #include #endif #include #include #include #include #include "pppd-private.h" #include "session.h" #ifdef PPP_WITH_PAM #include #endif /* #ifdef PPP_WITH_PAM */ #define SET_MSG(var, msg) if (var != NULL) { var[0] = msg; } #define COPY_STRING(s) ((s) ? strdup(s) : NULL) #define SUCCESS_MSG "Session started successfully" #define ABORT_MSG "Session can't be started without a username" #define SERVICE_NAME "ppp" #define SESSION_FAILED 0 #define SESSION_OK 1 /* We have successfully started a session */ static bool logged_in = 0; #ifdef PPP_WITH_PAM /* * Static variables used to communicate between the conversation function * and the server_login function */ static const char *PAM_username; static const char *PAM_password; static int PAM_session = 0; static pam_handle_t *pamh = NULL; /* PAM conversation function * Here we assume (for now, at least) that echo on means login name, and * echo off means password. */ static int conversation (int num_msg, const struct pam_message **msg, struct pam_response **resp, void *appdata_ptr) { int replies = 0; struct pam_response *reply = NULL; reply = malloc(sizeof(struct pam_response) * num_msg); if (!reply) return PAM_CONV_ERR; for (replies = 0; replies < num_msg; replies++) { switch (msg[replies]->msg_style) { case PAM_PROMPT_ECHO_ON: reply[replies].resp_retcode = PAM_SUCCESS; reply[replies].resp = COPY_STRING(PAM_username); /* PAM frees resp */ break; case PAM_PROMPT_ECHO_OFF: reply[replies].resp_retcode = PAM_SUCCESS; reply[replies].resp = COPY_STRING(PAM_password); /* PAM frees resp */ break; case PAM_TEXT_INFO: /* fall through */ case PAM_ERROR_MSG: /* ignore it, but pam still wants a NULL response... */ reply[replies].resp_retcode = PAM_SUCCESS; reply[replies].resp = NULL; break; default: /* Must be an error of some sort... */ free (reply); return PAM_CONV_ERR; } } *resp = reply; return PAM_SUCCESS; } static struct pam_conv pam_conv_data = { &conversation, NULL }; #endif /* #ifdef PPP_WITH_PAM */ int session_start(const int flags, const char *user, const char *passwd, const char *ttyName, char **msg) { #ifdef PPP_WITH_PAM bool ok = 1; const char *usr; int pam_error; bool try_session = 0; #else /* #ifdef PPP_WITH_PAM */ struct passwd *pw; char *cbuf; #ifdef HAVE_SHADOW_H struct spwd *spwd; struct spwd *getspnam(); long now = 0; #endif /* #ifdef HAVE_SHADOW_H */ #endif /* #ifdef PPP_WITH_PAM */ SET_MSG(msg, SUCCESS_MSG); /* If no verification is requested, then simply return an OK */ if (!(SESS_ALL & flags)) { return SESSION_OK; } if (user == NULL) { SET_MSG(msg, ABORT_MSG); return SESSION_FAILED; } #ifdef PPP_WITH_PAM /* Find the '\\' in the username */ /* This needs to be fixed to support different username schemes */ if ((usr = strchr(user, '\\')) == NULL) usr = user; else usr++; PAM_session = 0; PAM_username = usr; PAM_password = passwd; dbglog("Initializing PAM (%d) for user %s", flags, usr); pam_error = pam_start (SERVICE_NAME, usr, &pam_conv_data, &pamh); dbglog("---> PAM INIT Result = %d", pam_error); ok = (pam_error == PAM_SUCCESS); if (ok) { ok = (pam_set_item(pamh, PAM_TTY, ttyName) == PAM_SUCCESS) && (pam_set_item(pamh, PAM_RHOST, ifname) == PAM_SUCCESS); } if (ok && (SESS_AUTH & flags)) { dbglog("Attempting PAM authentication"); pam_error = pam_authenticate (pamh, PAM_SILENT); if (pam_error == PAM_SUCCESS) { /* PAM auth was OK */ dbglog("PAM Authentication OK for %s", user); } else { /* No matter the reason, we fail because we're authenticating */ ok = 0; if (pam_error == PAM_USER_UNKNOWN) { dbglog("User unknown, failing PAM authentication"); SET_MSG(msg, "User unknown - cannot authenticate via PAM"); } else { /* Any other error means authentication was bad */ dbglog("PAM Authentication failed: %d: %s", pam_error, pam_strerror(pamh, pam_error)); SET_MSG(msg, (char *) pam_strerror (pamh, pam_error)); } } } if (ok && (SESS_ACCT & flags)) { dbglog("Attempting PAM account checks"); pam_error = pam_acct_mgmt (pamh, PAM_SILENT); if (pam_error == PAM_SUCCESS) { /* * PAM account was OK, set the flag which indicates that we should * try to perform the session checks. */ try_session = 1; dbglog("PAM Account OK for %s", user); } else { /* * If the account checks fail, then we should not try to perform * the session check, because they don't make sense. */ try_session = 0; if (pam_error == PAM_USER_UNKNOWN) { /* * We're checking the account, so it's ok to not have one * because the user might come from the secrets files, or some * other plugin. */ dbglog("User unknown, ignoring PAM restrictions"); SET_MSG(msg, "User unknown - ignoring PAM restrictions"); } else { /* Any other error means session is rejected */ ok = 0; dbglog("PAM Account checks failed: %d: %s", pam_error, pam_strerror(pamh, pam_error)); SET_MSG(msg, (char *) pam_strerror (pamh, pam_error)); } } } if (ok && try_session && (SESS_ACCT & flags)) { /* Only open a session if the user's account was found */ pam_error = pam_open_session (pamh, PAM_SILENT); if (pam_error == PAM_SUCCESS) { dbglog("PAM Session opened for user %s", user); PAM_session = 1; } else { dbglog("PAM Session denied for user %s", user); SET_MSG(msg, (char *) pam_strerror (pamh, pam_error)); ok = 0; } } /* This is needed because apparently the PAM stuff closes the log */ reopen_log(); /* If our PAM checks have already failed, then we must return a failure */ if (!ok) return SESSION_FAILED; #else /* #ifdef PPP_WITH_PAM */ /* * Use the non-PAM methods directly. 'pw' will remain NULL if the user * has not been authenticated using local UNIX system services. */ pw = NULL; if ((SESS_AUTH & flags)) { pw = getpwnam(user); endpwent(); /* * Here, we bail if we have no user account, because there is nothing * to verify against. */ if (pw == NULL) return SESSION_FAILED; #ifdef HAVE_SHADOW_H spwd = getspnam(user); endspent(); /* * If there is no shadow entry for the user, then we can't verify the * account. */ if (spwd == NULL) return SESSION_FAILED; /* * We check validity all the time, because if the password has expired, * then clearly we should not authenticate against it (if we're being * called for authentication only). Thus, in this particular instance, * there is no real difference between using the AUTH, SESS or ACCT * flags, or combinations thereof. */ now = time(NULL) / 86400L; if ((spwd->sp_expire > 0 && now >= spwd->sp_expire) || ((spwd->sp_max >= 0 && spwd->sp_max < 10000) && spwd->sp_lstchg >= 0 && now >= spwd->sp_lstchg + spwd->sp_max)) { warn("Password for %s has expired", user); return SESSION_FAILED; } /* We have a valid shadow entry, keep the password */ pw->pw_passwd = spwd->sp_pwdp; #endif /* #ifdef HAVE_SHADOW_H */ /* * If no passwd, don't let them login if we're authenticating. */ if (pw->pw_passwd == NULL || strlen(pw->pw_passwd) < 2) return SESSION_FAILED; #ifdef HAVE_CRYPT_H cbuf = crypt(passwd, pw->pw_passwd); if (!cbuf || strcmp(cbuf, pw->pw_passwd) != 0) #endif return SESSION_FAILED; } #endif /* #ifdef PPP_WITH_PAM */ /* * Write a wtmp entry for this user. */ if (SESS_ACCT & flags) { if (strncmp(ttyName, "/dev/", 5) == 0) ttyName += 5; logwtmp(ttyName, user, ifname); /* Add wtmp login entry */ logged_in = 1; #if defined(_PATH_LASTLOG) && !defined(PPP_WITH_PAM) /* * Enter the user in lastlog only if he has been authenticated using * local system services. If he has not, then we don't know what his * UID might be, and lastlog is indexed by UID. */ if (pw != NULL) { struct lastlog ll; int fd; time_t tnow; if ((fd = open(_PATH_LASTLOG, O_RDWR, 0)) >= 0) { (void)lseek(fd, (off_t)(pw->pw_uid * sizeof(ll)), SEEK_SET); memset((void *)&ll, 0, sizeof(ll)); (void)time(&tnow); ll.ll_time = tnow; strlcpy(ll.ll_line, ttyName, sizeof(ll.ll_line)); strlcpy(ll.ll_host, ifname, sizeof(ll.ll_host)); (void)write(fd, (char *)&ll, sizeof(ll)); (void)close(fd); } } #endif /* _PATH_LASTLOG and not PPP_WITH_PAM */ info("user %s logged in on tty %s intf %s", user, ttyName, ifname); } return SESSION_OK; } /* * session_end - Logout the user. */ void session_end(const char* ttyName) { #ifdef PPP_WITH_PAM int pam_error = PAM_SUCCESS; if (pamh != NULL) { if (PAM_session) pam_error = pam_close_session (pamh, PAM_SILENT); PAM_session = 0; pam_end (pamh, pam_error); pamh = NULL; /* Apparently the pam stuff does closelog(). */ reopen_log(); } #endif if (logged_in) { if (strncmp(ttyName, "/dev/", 5) == 0) ttyName += 5; logwtmp(ttyName, "", ""); /* Wipe out utmp logout entry */ logged_in = 0; } } ppp-2.5.0/pppd/tty.c0000644000175000017500000010160614407475306011203 00000000000000/* * tty.c - code for handling serial ports in pppd. * * Copyright (C) 2000-2004 Paul Mackerras. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. The name(s) of the authors of this software must not be used to * endorse or promote products derived from this software without * prior written permission. * * 3. Redistributions of any form whatsoever must retain the following * acknowledgment: * "This product includes software developed by Paul Mackerras * ". * * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * Portions derived from main.c, which is: * * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The name "Carnegie Mellon University" must not be used to * endorse or promote products derived from this software without * prior written permission. For permission or any legal * details, please contact * Office of Technology Transfer * Carnegie Mellon University * 5000 Forbes Avenue * Pittsburgh, PA 15213-3890 * (412) 268-4387, fax: (412) 268-7395 * tech-transfer@andrew.cmu.edu * * 4. Redistributions of any form whatsoever must retain the following * acknowledgment: * "This product includes software developed by Computing Services * at Carnegie Mellon University (http://www.cmu.edu/computing/)." * * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "pppd-private.h" #include "options.h" #include "fsm.h" #include "lcp.h" void tty_process_extra_options(void); void tty_check_options(void); int connect_tty(void); void disconnect_tty(void); void tty_close_fds(void); void cleanup_tty(void); void tty_do_send_config(int, u_int32_t, int, int); static int setdevname(char *, char **, int); static int setspeed(char *, char **, int); static int setxonxoff(char **); static int setescape(char **); static void printescape(struct option *, void (*)(void *, char *,...),void *); static void finish_tty(void); static int start_charshunt(int, int); static void stop_charshunt(void *, int); static void charshunt_done(void *); static void charshunt(int, int, char *); static int record_write(FILE *, int code, u_char *buf, int nb, struct timeval *); static int open_socket(char *); static void maybe_relock(void *, int); static int pty_master; /* fd for master side of pty */ static int pty_slave; /* fd for slave side of pty */ static int real_ttyfd; /* fd for actual serial port (not pty) */ static int ttyfd; /* Serial port file descriptor */ static char speed_str[16]; /* Serial port speed as string */ mode_t tty_mode = (mode_t)-1; /* Original access permissions to tty */ int baud_rate; /* Actual bits/second for serial device */ char *callback_script; /* script for doing callback */ int charshunt_pid; /* Process ID for charshunt */ int locked; /* lock() has succeeded */ struct stat devstat; /* result of stat() on devnam */ /* option variables */ char devnam[MAXPATHLEN]; /* Device name */ char ppp_devname[MAXPATHLEN];/* name of PPP tty (maybe ttypx) */ int crtscts = 0; /* Use hardware flow control */ int stop_bits = 1; /* Number of serial port stop bits */ bool modem = 1; /* Use modem control lines */ int inspeed = 0; /* Input/Output speed requested */ bool lockflag = 0; /* Create lock file to lock the serial dev */ char *initializer = NULL; /* Script to initialize physical link */ char *connect_script = NULL; /* Script to establish physical link */ char *disconnect_script = NULL; /* Script to disestablish physical link */ char *welcomer = NULL; /* Script to run after phys link estab. */ char *ptycommand = NULL; /* Command to run on other side of pty */ bool notty = 0; /* Stdin/out is not a tty */ char *record_file = NULL; /* File to record chars sent/received */ int max_data_rate; /* max bytes/sec through charshunt */ bool sync_serial = 0; /* Device is synchronous serial device */ char *pty_socket = NULL; /* Socket to connect to pty */ int using_pty = 0; /* we're allocating a pty as the device */ extern uid_t uid; extern int kill_link; extern int asked_to_quit; extern int got_sigterm; /* XXX */ extern int privopen; /* don't lock, open device as root */ u_int32_t xmit_accm[8]; /* extended transmit ACCM */ /* option descriptors */ static struct option tty_options[] = { /* device name must be first, or change connect_tty() below! */ { "device name", o_wild, (void *) &setdevname, "Serial port device name", OPT_DEVNAM | OPT_PRIVFIX | OPT_NOARG | OPT_A2STRVAL | OPT_STATIC, devnam}, { "tty speed", o_wild, (void *) &setspeed, "Baud rate for serial port", OPT_PRIO | OPT_NOARG | OPT_A2STRVAL | OPT_STATIC, speed_str }, { "lock", o_bool, &lockflag, "Lock serial device with UUCP-style lock file", OPT_PRIO | 1 }, { "nolock", o_bool, &lockflag, "Don't lock serial device", OPT_PRIOSUB | OPT_PRIV }, { "init", o_string, &initializer, "A program to initialize the device", OPT_PRIO | OPT_PRIVFIX }, { "connect", o_string, &connect_script, "A program to set up a connection", OPT_PRIO | OPT_PRIVFIX }, { "disconnect", o_string, &disconnect_script, "Program to disconnect serial device", OPT_PRIO | OPT_PRIVFIX }, { "welcome", o_string, &welcomer, "Script to welcome client", OPT_PRIO | OPT_PRIVFIX }, { "pty", o_string, &ptycommand, "Script to run on pseudo-tty master side", OPT_PRIO | OPT_PRIVFIX | OPT_DEVNAM }, { "notty", o_bool, ¬ty, "Input/output is not a tty", OPT_DEVNAM | 1 }, { "socket", o_string, &pty_socket, "Send and receive over socket, arg is host:port", OPT_PRIO | OPT_DEVNAM }, { "record", o_string, &record_file, "Record characters sent/received to file", OPT_PRIO }, { "crtscts", o_int, &crtscts, "Set hardware (RTS/CTS) flow control", OPT_PRIO | OPT_NOARG | OPT_VAL(1) }, { "cdtrcts", o_int, &crtscts, "Set alternate hardware (DTR/CTS) flow control", OPT_PRIOSUB | OPT_NOARG | OPT_VAL(2) }, { "nocrtscts", o_int, &crtscts, "Disable hardware flow control", OPT_PRIOSUB | OPT_NOARG | OPT_VAL(-1) }, { "-crtscts", o_int, &crtscts, "Disable hardware flow control", OPT_PRIOSUB | OPT_ALIAS | OPT_NOARG | OPT_VAL(-1) }, { "nocdtrcts", o_int, &crtscts, "Disable hardware flow control", OPT_PRIOSUB | OPT_ALIAS | OPT_NOARG | OPT_VAL(-1) }, { "xonxoff", o_special_noarg, (void *)setxonxoff, "Set software (XON/XOFF) flow control", OPT_PRIOSUB }, { "stop-bits", o_int, &stop_bits, "Number of stop bits in serial port", OPT_PRIO | OPT_PRIVFIX | OPT_LIMITS, NULL, 2, 1 }, { "modem", o_bool, &modem, "Use modem control lines", OPT_PRIO | 1 }, { "local", o_bool, &modem, "Don't use modem control lines", OPT_PRIOSUB | 0 }, { "sync", o_bool, &sync_serial, "Use synchronous HDLC serial encoding", 1 }, { "datarate", o_int, &max_data_rate, "Maximum data rate in bytes/sec (with pty, notty or record option)", OPT_PRIO }, { "escape", o_special, (void *)setescape, "List of character codes to escape on transmission", OPT_A2PRINTER, (void *)printescape }, { NULL } }; struct channel tty_channel = { tty_options, &tty_process_extra_options, &tty_check_options, &connect_tty, &disconnect_tty, &tty_establish_ppp, &tty_disestablish_ppp, &tty_do_send_config, &tty_recv_config, &cleanup_tty, &tty_close_fds }; bool ppp_sync_serial() { return sync_serial; } bool ppp_get_modem() { return modem; } void ppp_set_modem(bool on) { modem = on; } bool ppp_using_pty() { return using_pty; } int ppp_set_pppdevnam(const char *name) { if (name) { return strlcpy(ppp_devname, name, sizeof(ppp_devname)); } return -1; } const char * ppp_pppdevnam() { return ppp_devname; } const char * ppp_devnam() { return devnam; } int ppp_set_devnam(const char *name) { if (name) { return strlcpy(devnam, name, sizeof(devnam)); } return -1; } /* * setspeed - Set the serial port baud rate. * If doit is 0, the call is to check whether this option is * potentially a speed value. */ static int setspeed(char *arg, char **argv, int doit) { char *ptr; int spd; spd = strtol(arg, &ptr, 0); if (ptr == arg || *ptr != 0 || spd == 0) return 0; if (doit) { inspeed = spd; slprintf(speed_str, sizeof(speed_str), "%d", spd); } return 1; } /* * setdevname - Set the device name. * If doit is 0, the call is to check whether this option is * potentially a device name. */ static int setdevname(char *cp, char **argv, int doit) { struct stat statbuf; char dev[MAXPATHLEN]; if (*cp == 0) return 0; if (*cp != '/') { strlcpy(dev, "/dev/", sizeof(dev)); strlcat(dev, cp, sizeof(dev)); cp = dev; } /* * Check if there is a character device by this name. */ if (stat(cp, &statbuf) < 0) { if (!doit) return errno != ENOENT; ppp_option_error("Couldn't stat %s: %m", cp); return 0; } if (!S_ISCHR(statbuf.st_mode)) { if (doit) ppp_option_error("%s is not a character device", cp); return 0; } if (doit) { strlcpy(devnam, cp, MAXPATHLEN); devstat = statbuf; default_device = 0; } return 1; } static int setxonxoff(char **argv) { lcp_wantoptions[0].asyncmap |= 0x000A0000; /* escape ^S and ^Q */ lcp_wantoptions[0].neg_asyncmap = 1; crtscts = -2; return 1; } /* * setescape - add chars to the set we escape on transmission. */ static int setescape(char **argv) { int n, ret; char *p, *endp; p = *argv; ret = 1; while (*p) { n = strtol(p, &endp, 16); if (p == endp) { ppp_option_error("escape parameter contains invalid hex number '%s'", p); return 0; } p = endp; if (n < 0 || n == 0x5E || n > 0xFF) { ppp_option_error("can't escape character 0x%x", n); ret = 0; } else xmit_accm[n >> 5] |= 1U << (n & 0x1F); while (*p == ',' || *p == ' ') ++p; } lcp_allowoptions[0].asyncmap = xmit_accm[0]; return ret; } static void printescape(struct option *opt, void (*printer)(void *, char *, ...), void *arg) { int n; int first = 1; for (n = 0; n < 256; ++n) { if (n == 0x7d) n += 2; /* skip 7d, 7e */ if (xmit_accm[n >> 5] & (1U << (n & 0x1f))) { if (!first) printer(arg, ","); else first = 0; printer(arg, "%x", n); } } if (first) printer(arg, "oops # nothing escaped"); } /* * tty_init - do various tty-related initializations. */ void tty_init(void) { ppp_add_notify(NF_PID_CHANGE, maybe_relock, 0); the_channel = &tty_channel; xmit_accm[3] = 0x60000000U; } /* * tty_process_extra_options - work out which tty device we are using * and read its options file. */ void tty_process_extra_options(void) { using_pty = notty || ptycommand != NULL || pty_socket != NULL; if (using_pty) return; if (default_device) { char *p; if (!isatty(0) || (p = ttyname(0)) == NULL) { ppp_option_error("no device specified and stdin is not a tty"); exit(EXIT_OPTION_ERROR); } strlcpy(devnam, p, MAXPATHLEN); if (stat(devnam, &devstat) < 0) fatal("Couldn't stat default device %s: %m", devnam); } /* * Parse the tty options file. * The per-tty options file should not change * ptycommand, pty_socket, notty or devnam. * options_for_tty doesn't override options set on the command line, * except for some privileged options. */ if (!options_for_tty()) exit(EXIT_OPTION_ERROR); } /* * tty_check_options - do consistency checks on the options we were given. */ void tty_check_options(void) { struct stat statbuf; int fdflags; if (demand && notty) { ppp_option_error("demand-dialling is incompatible with notty"); exit(EXIT_OPTION_ERROR); } if (demand && connect_script == 0 && ptycommand == NULL && pty_socket == NULL) { ppp_option_error("connect script is required for demand-dialling\n"); exit(EXIT_OPTION_ERROR); } /* default holdoff to 0 if no connect script has been given */ if (connect_script == 0 && !holdoff_specified) holdoff = 0; if (using_pty) { if (!default_device) { ppp_option_error("%s option precludes specifying device name", pty_socket? "socket": notty? "notty": "pty"); exit(EXIT_OPTION_ERROR); } if (ptycommand != NULL && notty) { ppp_option_error("pty option is incompatible with notty option"); exit(EXIT_OPTION_ERROR); } if (pty_socket != NULL && (ptycommand != NULL || notty)) { ppp_option_error("socket option is incompatible with pty and notty"); exit(EXIT_OPTION_ERROR); } default_device = notty; lockflag = 0; modem = 0; if (notty && log_to_fd <= 1) log_to_fd = -1; } else { /* * If the user has specified a device which is the same as * the one on stdin, pretend they didn't specify any. * If the device is already open read/write on stdin, * we assume we don't need to lock it, and we can open it * as root. */ if (fstat(0, &statbuf) >= 0 && S_ISCHR(statbuf.st_mode) && statbuf.st_rdev == devstat.st_rdev) { default_device = 1; fdflags = fcntl(0, F_GETFL); if (fdflags != -1 && (fdflags & O_ACCMODE) == O_RDWR) privopen = 1; } } if (default_device) nodetach = 1; /* * Don't send log messages to the serial port, it tends to * confuse the peer. :-) */ if (log_to_fd >= 0 && fstat(log_to_fd, &statbuf) >= 0 && S_ISCHR(statbuf.st_mode) && statbuf.st_rdev == devstat.st_rdev) log_to_fd = -1; } /* * connect_tty - get the serial port ready to start doing PPP. * That is, open the serial port, set its speed and mode, and run * the connector and/or welcomer. */ int connect_tty(void) { char *connector; int fdflags; #ifndef __linux__ struct stat statbuf; #endif char numbuf[16]; /* * Get a pty master/slave pair if the pty, notty, socket, * or record options were specified. */ strlcpy(ppp_devname, devnam, MAXPATHLEN); pty_master = -1; pty_slave = -1; real_ttyfd = -1; if (using_pty || record_file != NULL) { if (!get_pty(&pty_master, &pty_slave, ppp_devname, uid)) { error("Couldn't allocate pseudo-tty"); ppp_set_status(EXIT_FATAL_ERROR); return -1; } set_up_tty(pty_slave, 1); } /* * Lock the device if we've been asked to. */ ppp_set_status(EXIT_LOCK_FAILED); if (lockflag && !privopen) { if (lock(devnam) < 0) goto errret; locked = 1; } /* * Open the serial device and set it up to be the ppp interface. * First we open it in non-blocking mode so we can set the * various termios flags appropriately. If we aren't dialling * out and we want to use the modem lines, we reopen it later * in order to wait for the carrier detect signal from the modem. */ got_sigterm = 0; connector = doing_callback? callback_script: connect_script; if (devnam[0] != 0) { for (;;) { /* If the user specified the device name, become the user before opening it. */ int err, prio; prio = privopen? OPRIO_ROOT: tty_options[0].priority; if (prio < OPRIO_ROOT && seteuid(uid) == -1) { error("Unable to drop privileges before opening %s: %m\n", devnam); ppp_set_status(EXIT_OPEN_FAILED); goto errret; } real_ttyfd = open(devnam, O_NONBLOCK | O_RDWR, 0); err = errno; if (prio < OPRIO_ROOT && seteuid(0) == -1) fatal("Unable to regain privileges"); if (real_ttyfd >= 0) break; errno = err; if (err != EINTR) { error("Failed to open %s: %m", devnam); ppp_set_status(EXIT_OPEN_FAILED); } if (!persist || err != EINTR) goto errret; } ttyfd = real_ttyfd; if ((fdflags = fcntl(ttyfd, F_GETFL)) == -1 || fcntl(ttyfd, F_SETFL, fdflags & ~O_NONBLOCK) < 0) warn("Couldn't reset non-blocking mode on device: %m"); #ifndef __linux__ /* * Linux 2.4 and above blocks normal writes to the tty * when it is in PPP line discipline, so this isn't needed. */ /* * Do the equivalent of `mesg n' to stop broadcast messages. */ if (fstat(ttyfd, &statbuf) < 0 || fchmod(ttyfd, statbuf.st_mode & ~(S_IWGRP | S_IWOTH)) < 0) { warn("Couldn't restrict write permissions to %s: %m", devnam); } else tty_mode = statbuf.st_mode; #endif /* __linux__ */ /* * Set line speed, flow control, etc. * If we have a non-null connection or initializer script, * on most systems we set CLOCAL for now so that we can talk * to the modem before carrier comes up. But this has the * side effect that we might miss it if CD drops before we * get to clear CLOCAL below. On systems where we can talk * successfully to the modem with CLOCAL clear and CD down, * we could clear CLOCAL at this point. */ set_up_tty(ttyfd, ((connector != NULL && connector[0] != 0) || initializer != NULL)); } /* * If the pty, socket, notty and/or record option was specified, * start up the character shunt now. */ ppp_set_status(EXIT_PTYCMD_FAILED); if (ptycommand != NULL) { if (record_file != NULL) { int ipipe[2], opipe[2], ok; if (pipe(ipipe) < 0 || pipe(opipe) < 0) fatal("Couldn't create pipes for record option: %m"); /* don't leak these to the ptycommand */ (void) fcntl(ipipe[0], F_SETFD, FD_CLOEXEC); (void) fcntl(opipe[1], F_SETFD, FD_CLOEXEC); ok = device_script(ptycommand, opipe[0], ipipe[1], 1) == 0 && start_charshunt(ipipe[0], opipe[1]); close(ipipe[0]); close(ipipe[1]); close(opipe[0]); close(opipe[1]); if (!ok) goto errret; } else { if (device_script(ptycommand, pty_master, pty_master, 1) < 0) goto errret; } } else if (pty_socket != NULL) { int fd = open_socket(pty_socket); if (fd < 0) goto errret; if (!start_charshunt(fd, fd)) goto errret; close(fd); } else if (notty) { if (!start_charshunt(0, 1)) goto errret; dup2(fd_devnull, 0); dup2(fd_devnull, 1); if (log_to_fd == 1) log_to_fd = -1; if (log_to_fd != 2) dup2(fd_devnull, 2); } else if (record_file != NULL) { int fd = dup(ttyfd); if (!start_charshunt(fd, fd)) goto errret; } if (using_pty || record_file != NULL) { ttyfd = pty_slave; close(pty_master); pty_master = -1; } /* run connection script */ if ((connector && connector[0]) || initializer) { if (real_ttyfd != -1) { /* XXX do this if doing_callback == CALLBACK_DIALIN? */ if (!default_device && modem) { setdtr(real_ttyfd, 0); /* in case modem is off hook */ sleep(1); setdtr(real_ttyfd, 1); } } if (initializer && initializer[0]) { if (device_script(initializer, ttyfd, ttyfd, 0) < 0) { error("Initializer script failed"); ppp_set_status(EXIT_INIT_FAILED); goto errretf; } if (got_sigterm) { disconnect_tty(); goto errretf; } info("Serial port initialized."); } if (connector && connector[0]) { if (device_script(connector, ttyfd, ttyfd, 0) < 0) { error("Connect script failed"); ppp_set_status(EXIT_CONNECT_FAILED); goto errretf; } if (got_sigterm) { disconnect_tty(); goto errretf; } info("Serial connection established."); } /* set line speed, flow control, etc.; clear CLOCAL if modem option */ if (real_ttyfd != -1) set_up_tty(real_ttyfd, 0); if (doing_callback == CALLBACK_DIALIN) connector = NULL; } /* reopen tty if necessary to wait for carrier */ if (connector == NULL && modem && devnam[0] != 0) { int i; for (;;) { if ((i = open(devnam, O_RDWR)) >= 0) break; if (errno != EINTR) { error("Failed to reopen %s: %m", devnam); ppp_set_status(EXIT_OPEN_FAILED); } if (!persist || errno != EINTR || hungup || got_sigterm) goto errret; } close(i); } slprintf(numbuf, sizeof(numbuf), "%d", baud_rate); ppp_script_setenv("SPEED", numbuf, 0); /* run welcome script, if any */ if (welcomer && welcomer[0]) { if (device_script(welcomer, ttyfd, ttyfd, 0) < 0) warn("Welcome script failed"); } /* * If we are initiating this connection, wait for a short * time for something from the peer. This can avoid bouncing * our packets off his tty before he has it set up. */ if (connector != NULL || ptycommand != NULL || pty_socket != NULL) listen_time = connect_delay; return ttyfd; errretf: if (real_ttyfd >= 0) tcflush(real_ttyfd, TCIOFLUSH); errret: if (pty_master >= 0) { close(pty_master); pty_master = -1; } ttyfd = -1; if (got_sigterm) asked_to_quit = 1; return -1; } void disconnect_tty(void) { if (disconnect_script == NULL || hungup) return; if (real_ttyfd >= 0) set_up_tty(real_ttyfd, 1); if (device_script(disconnect_script, ttyfd, ttyfd, 0) < 0) { warn("disconnect script failed"); } else { info("Serial link disconnected."); } stop_charshunt(NULL, 0); } void tty_close_fds(void) { if (pty_slave >= 0) close(pty_slave); if (real_ttyfd >= 0) { close(real_ttyfd); real_ttyfd = -1; } /* N.B. ttyfd will == either pty_slave or real_ttyfd */ } void cleanup_tty(void) { if (real_ttyfd >= 0) finish_tty(); tty_close_fds(); if (locked) { unlock(); locked = 0; } } /* * tty_do_send_config - set transmit-side PPP configuration. * We set the extended transmit ACCM here as well. */ void tty_do_send_config(int mtu, u_int32_t accm, int pcomp, int accomp) { tty_set_xaccm(xmit_accm); tty_send_config(mtu, accm, pcomp, accomp); } /* * finish_tty - restore the terminal device to its original settings */ static void finish_tty(void) { /* drop dtr to hang up */ if (!default_device && modem) { setdtr(real_ttyfd, 0); /* * This sleep is in case the serial port has CLOCAL set by default, * and consequently will reassert DTR when we close the device. */ sleep(1); } restore_tty(real_ttyfd); #ifndef __linux__ if (tty_mode != (mode_t) -1) { if (fchmod(real_ttyfd, tty_mode) != 0) error("Couldn't restore tty permissions"); } #endif /* __linux__ */ close(real_ttyfd); real_ttyfd = -1; } /* * maybe_relock - our PID has changed, maybe update the lock file. */ static void maybe_relock(void *arg, int pid) { if (locked) relock(pid); } /* * open_socket - establish a stream socket connection to the nominated * host and port. */ static int open_socket(char *dest) { char *sep, *endp = NULL; int sock, port = -1; u_int32_t host; struct hostent *hent; struct sockaddr_in sad; /* parse host:port and resolve host to an IP address */ sep = strchr(dest, ':'); if (sep != NULL) port = strtol(sep+1, &endp, 10); if (port < 0 || endp == sep+1 || sep == dest) { error("Can't parse host:port for socket destination"); return -1; } *sep = 0; host = inet_addr(dest); if (host == (u_int32_t) -1) { hent = gethostbyname(dest); if (hent == NULL) { error("%s: unknown host in socket option", dest); *sep = ':'; return -1; } host = *(u_int32_t *)(hent->h_addr_list[0]); } *sep = ':'; /* get a socket and connect it to the other end */ sock = socket(PF_INET, SOCK_STREAM, 0); if (sock < 0) { error("Can't create socket: %m"); return -1; } memset(&sad, 0, sizeof(sad)); sad.sin_family = AF_INET; sad.sin_port = htons(port); sad.sin_addr.s_addr = host; if (connect(sock, (struct sockaddr *)&sad, sizeof(sad)) < 0) { error("Can't connect to %s: %m", dest); close(sock); return -1; } return sock; } /* * start_charshunt - create a child process to run the character shunt. */ static int start_charshunt(int ifd, int ofd) { int cpid, ret; cpid = ppp_safe_fork(ifd, ofd, (log_to_fd >= 0? log_to_fd: 2)); if (cpid == -1) { error("Can't fork process for character shunt: %m"); return 0; } if (cpid == 0) { /* child */ reopen_log(); if (!nodetach) log_to_fd = -1; else if (log_to_fd >= 0) log_to_fd = 2; ret = setgid(getgid()); if (ret != 0) { fatal("setgid failed, %m"); } ret = setuid(uid); if (ret != 0 || getuid() != uid) { fatal("setuid failed, %m"); } charshunt(0, 1, record_file); exit(0); } charshunt_pid = cpid; record_child(cpid, "pppd (charshunt)", charshunt_done, NULL, 1); return 1; } static void charshunt_done(void *arg) { charshunt_pid = 0; } static void stop_charshunt(void *arg, int sig) { if (charshunt_pid) kill(charshunt_pid, (sig == SIGINT? sig: SIGTERM)); } /* * charshunt - the character shunt, which passes characters between * the pty master side and the serial port (or stdin/stdout). * This runs as the user (not as root). * (We assume ofd >= ifd which is true the way this gets called. :-). */ static void charshunt(int ifd, int ofd, char *record_file) { int n, nfds; fd_set ready, writey; u_char *ibufp, *obufp; int nibuf, nobuf; int flags; int pty_readable, stdin_readable; struct timeval lasttime; FILE *recordf = NULL; int ilevel, olevel, max_level; struct timeval levelt, tout, *top; extern u_char inpacket_buf[]; /* * Reset signal handlers. */ signal(SIGHUP, SIG_IGN); /* Hangup */ signal(SIGINT, SIG_DFL); /* Interrupt */ signal(SIGTERM, SIG_DFL); /* Terminate */ signal(SIGCHLD, SIG_DFL); signal(SIGUSR1, SIG_DFL); signal(SIGUSR2, SIG_DFL); signal(SIGABRT, SIG_DFL); signal(SIGALRM, SIG_DFL); signal(SIGFPE, SIG_DFL); signal(SIGILL, SIG_DFL); signal(SIGPIPE, SIG_DFL); signal(SIGQUIT, SIG_DFL); signal(SIGSEGV, SIG_DFL); #ifdef SIGBUS signal(SIGBUS, SIG_DFL); #endif #ifdef SIGEMT signal(SIGEMT, SIG_DFL); #endif #ifdef SIGPOLL signal(SIGPOLL, SIG_DFL); #endif #ifdef SIGPROF signal(SIGPROF, SIG_DFL); #endif #ifdef SIGSYS signal(SIGSYS, SIG_DFL); #endif #ifdef SIGTRAP signal(SIGTRAP, SIG_DFL); #endif #ifdef SIGVTALRM signal(SIGVTALRM, SIG_DFL); #endif #ifdef SIGXCPU signal(SIGXCPU, SIG_DFL); #endif #ifdef SIGXFSZ signal(SIGXFSZ, SIG_DFL); #endif /* * Check that the fds won't overrun the fd_sets */ if (ifd >= FD_SETSIZE || ofd >= FD_SETSIZE || pty_master >= FD_SETSIZE) fatal("internal error: file descriptor too large (%d, %d, %d)", ifd, ofd, pty_master); /* * Open the record file if required. */ if (record_file != NULL) { recordf = fopen(record_file, "a"); if (recordf == NULL) error("Couldn't create record file %s: %m", record_file); } /* set all the fds to non-blocking mode */ flags = fcntl(pty_master, F_GETFL); if (flags == -1 || fcntl(pty_master, F_SETFL, flags | O_NONBLOCK) == -1) warn("couldn't set pty master to nonblock: %m"); flags = fcntl(ifd, F_GETFL); if (flags == -1 || fcntl(ifd, F_SETFL, flags | O_NONBLOCK) == -1) warn("couldn't set %s to nonblock: %m", (ifd==0? "stdin": "tty")); if (ofd != ifd) { flags = fcntl(ofd, F_GETFL); if (flags == -1 || fcntl(ofd, F_SETFL, flags | O_NONBLOCK) == -1) warn("couldn't set stdout to nonblock: %m"); } nibuf = nobuf = 0; ibufp = obufp = NULL; pty_readable = stdin_readable = 1; ilevel = olevel = 0; ppp_get_time(&levelt); if (max_data_rate) { max_level = max_data_rate / 10; if (max_level < 100) max_level = 100; } else max_level = PPP_MRU + PPP_HDRLEN + 1; nfds = (ofd > pty_master? ofd: pty_master) + 1; if (recordf != NULL) { gettimeofday(&lasttime, NULL); putc(7, recordf); /* put start marker */ putc(lasttime.tv_sec >> 24, recordf); putc(lasttime.tv_sec >> 16, recordf); putc(lasttime.tv_sec >> 8, recordf); putc(lasttime.tv_sec, recordf); lasttime.tv_usec = 0; } while (nibuf != 0 || nobuf != 0 || pty_readable || stdin_readable) { top = 0; tout.tv_sec = 0; tout.tv_usec = 10000; FD_ZERO(&ready); FD_ZERO(&writey); if (nibuf != 0) { if (ilevel >= max_level) top = &tout; else FD_SET(pty_master, &writey); } else if (stdin_readable) FD_SET(ifd, &ready); if (nobuf != 0) { if (olevel >= max_level) top = &tout; else FD_SET(ofd, &writey); } else if (pty_readable) FD_SET(pty_master, &ready); if (select(nfds, &ready, &writey, NULL, top) < 0) { if (errno != EINTR) fatal("select"); continue; } if (max_data_rate) { double dt; int nbt; struct timeval now; ppp_get_time(&now); dt = (now.tv_sec - levelt.tv_sec + (now.tv_usec - levelt.tv_usec) / 1e6); nbt = (int)(dt * max_data_rate); ilevel = (nbt < 0 || nbt > ilevel)? 0: ilevel - nbt; olevel = (nbt < 0 || nbt > olevel)? 0: olevel - nbt; levelt = now; } else ilevel = olevel = 0; if (FD_ISSET(ifd, &ready)) { ibufp = inpacket_buf; nibuf = read(ifd, ibufp, PPP_MRU + PPP_HDRLEN); if (nibuf < 0 && errno == EIO) nibuf = 0; if (nibuf < 0) { if (!(errno == EINTR || errno == EAGAIN)) { error("Error reading standard input: %m"); break; } nibuf = 0; } else if (nibuf == 0) { /* end of file from stdin */ stdin_readable = 0; if (recordf) if (!record_write(recordf, 4, NULL, 0, &lasttime)) recordf = NULL; } else { FD_SET(pty_master, &writey); if (recordf) if (!record_write(recordf, 2, ibufp, nibuf, &lasttime)) recordf = NULL; } } if (FD_ISSET(pty_master, &ready)) { obufp = outpacket_buf; nobuf = read(pty_master, obufp, PPP_MRU + PPP_HDRLEN); if (nobuf < 0 && errno == EIO) nobuf = 0; if (nobuf < 0) { if (!(errno == EINTR || errno == EAGAIN)) { error("Error reading pseudo-tty master: %m"); break; } nobuf = 0; } else if (nobuf == 0) { /* end of file from the pty - slave side has closed */ pty_readable = 0; stdin_readable = 0; /* pty is not writable now */ nibuf = 0; close(ofd); if (recordf) if (!record_write(recordf, 3, NULL, 0, &lasttime)) recordf = NULL; } else { FD_SET(ofd, &writey); if (recordf) if (!record_write(recordf, 1, obufp, nobuf, &lasttime)) recordf = NULL; } } else if (!stdin_readable) pty_readable = 0; if (FD_ISSET(ofd, &writey)) { n = nobuf; if (olevel + n > max_level) n = max_level - olevel; n = write(ofd, obufp, n); if (n < 0) { if (errno == EIO) { pty_readable = 0; nobuf = 0; } else if (errno != EAGAIN && errno != EINTR) { error("Error writing standard output: %m"); break; } } else { obufp += n; nobuf -= n; olevel += n; } } if (FD_ISSET(pty_master, &writey)) { n = nibuf; if (ilevel + n > max_level) n = max_level - ilevel; n = write(pty_master, ibufp, n); if (n < 0) { if (errno == EIO) { stdin_readable = 0; nibuf = 0; } else if (errno != EAGAIN && errno != EINTR) { error("Error writing pseudo-tty master: %m"); break; } } else { ibufp += n; nibuf -= n; ilevel += n; } } } exit(0); } static int record_write(FILE *f, int code, u_char *buf, int nb, struct timeval *tp) { struct timeval now; int diff; gettimeofday(&now, NULL); now.tv_usec /= 100000; /* actually 1/10 s, not usec now */ diff = (now.tv_sec - tp->tv_sec) * 10 + (now.tv_usec - tp->tv_usec); if (diff > 0) { if (diff > 255) { putc(5, f); putc(diff >> 24, f); putc(diff >> 16, f); putc(diff >> 8, f); putc(diff, f); } else { putc(6, f); putc(diff, f); } *tp = now; } putc(code, f); if (buf != NULL) { putc(nb >> 8, f); putc(nb, f); fwrite(buf, nb, 1, f); } fflush(f); if (ferror(f)) { error("Error writing record file: %m"); return 0; } return 1; } ppp-2.5.0/pppd/upap.c0000644000175000017500000003574314353435407011336 00000000000000/* * upap.c - User/Password Authentication Protocol. * * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The name "Carnegie Mellon University" must not be used to * endorse or promote products derived from this software without * prior written permission. For permission or any legal * details, please contact * Office of Technology Transfer * Carnegie Mellon University * 5000 Forbes Avenue * Pittsburgh, PA 15213-3890 * (412) 268-4387, fax: (412) 268-7395 * tech-transfer@andrew.cmu.edu * * 4. Redistributions of any form whatsoever must retain the following * acknowledgment: * "This product includes software developed by Computing Services * at Carnegie Mellon University (http://www.cmu.edu/computing/)." * * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif /* * TODO: */ #include #include #include "pppd-private.h" #include "options.h" #include "upap.h" static bool hide_password = 1; /* * Command-line options. */ static struct option pap_option_list[] = { { "hide-password", o_bool, &hide_password, "Don't output passwords to log", OPT_PRIO | 1 }, { "show-password", o_bool, &hide_password, "Show password string in debug log messages", OPT_PRIOSUB | 0 }, { "pap-restart", o_int, &upap[0].us_timeouttime, "Set retransmit timeout for PAP", OPT_PRIO }, { "pap-max-authreq", o_int, &upap[0].us_maxtransmits, "Set max number of transmissions for auth-reqs", OPT_PRIO }, { "pap-timeout", o_int, &upap[0].us_reqtimeout, "Set time limit for peer PAP authentication", OPT_PRIO }, { NULL } }; /* * Protocol entry points. */ static void upap_init(int); static void upap_lowerup(int); static void upap_lowerdown(int); static void upap_input(int, u_char *, int); static void upap_protrej(int); static int upap_printpkt(u_char *, int, void (*)(void *, char *, ...), void *); struct protent pap_protent = { PPP_PAP, upap_init, upap_input, upap_protrej, upap_lowerup, upap_lowerdown, NULL, NULL, upap_printpkt, NULL, 1, "PAP", NULL, pap_option_list, NULL, NULL, NULL }; upap_state upap[NUM_PPP]; /* UPAP state; one for each unit */ static void upap_timeout(void *); static void upap_reqtimeout(void *); static void upap_rauthreq(upap_state *, u_char *, int, int); static void upap_rauthack(upap_state *, u_char *, int, int); static void upap_rauthnak(upap_state *, u_char *, int, int); static void upap_sauthreq(upap_state *); static void upap_sresp(upap_state *, int, int, char *, int); /* * upap_init - Initialize a UPAP unit. */ static void upap_init(int unit) { upap_state *u = &upap[unit]; u->us_unit = unit; u->us_user = NULL; u->us_userlen = 0; u->us_passwd = NULL; u->us_passwdlen = 0; u->us_clientstate = UPAPCS_INITIAL; u->us_serverstate = UPAPSS_INITIAL; u->us_id = 0; u->us_timeouttime = UPAP_DEFTIMEOUT; u->us_maxtransmits = 10; u->us_reqtimeout = UPAP_DEFREQTIME; } /* * upap_authwithpeer - Authenticate us with our peer (start client). * * Set new state and send authenticate's. */ void upap_authwithpeer(int unit, char *user, char *password) { upap_state *u = &upap[unit]; /* Save the username and password we're given */ u->us_user = user; u->us_userlen = strlen(user); u->us_passwd = password; u->us_passwdlen = strlen(password); u->us_transmits = 0; /* Lower layer up yet? */ if (u->us_clientstate == UPAPCS_INITIAL || u->us_clientstate == UPAPCS_PENDING) { u->us_clientstate = UPAPCS_PENDING; return; } upap_sauthreq(u); /* Start protocol */ } /* * upap_authpeer - Authenticate our peer (start server). * * Set new state. */ void upap_authpeer(int unit) { upap_state *u = &upap[unit]; /* Lower layer up yet? */ if (u->us_serverstate == UPAPSS_INITIAL || u->us_serverstate == UPAPSS_PENDING) { u->us_serverstate = UPAPSS_PENDING; return; } u->us_serverstate = UPAPSS_LISTEN; if (u->us_reqtimeout > 0) TIMEOUT(upap_reqtimeout, u, u->us_reqtimeout); } /* * upap_timeout - Retransmission timer for sending auth-reqs expired. */ static void upap_timeout(void *arg) { upap_state *u = (upap_state *) arg; if (u->us_clientstate != UPAPCS_AUTHREQ) return; if (u->us_transmits >= u->us_maxtransmits) { /* give up in disgust */ error("No response to PAP authenticate-requests"); u->us_clientstate = UPAPCS_BADAUTH; auth_withpeer_fail(u->us_unit, PPP_PAP); return; } upap_sauthreq(u); /* Send Authenticate-Request */ } /* * upap_reqtimeout - Give up waiting for the peer to send an auth-req. */ static void upap_reqtimeout(void *arg) { upap_state *u = (upap_state *) arg; if (u->us_serverstate != UPAPSS_LISTEN) return; /* huh?? */ auth_peer_fail(u->us_unit, PPP_PAP); u->us_serverstate = UPAPSS_BADAUTH; } /* * upap_lowerup - The lower layer is up. * * Start authenticating if pending. */ static void upap_lowerup(int unit) { upap_state *u = &upap[unit]; if (u->us_clientstate == UPAPCS_INITIAL) u->us_clientstate = UPAPCS_CLOSED; else if (u->us_clientstate == UPAPCS_PENDING) { upap_sauthreq(u); /* send an auth-request */ } if (u->us_serverstate == UPAPSS_INITIAL) u->us_serverstate = UPAPSS_CLOSED; else if (u->us_serverstate == UPAPSS_PENDING) { u->us_serverstate = UPAPSS_LISTEN; if (u->us_reqtimeout > 0) TIMEOUT(upap_reqtimeout, u, u->us_reqtimeout); } } /* * upap_lowerdown - The lower layer is down. * * Cancel all timeouts. */ static void upap_lowerdown(int unit) { upap_state *u = &upap[unit]; if (u->us_clientstate == UPAPCS_AUTHREQ) /* Timeout pending? */ UNTIMEOUT(upap_timeout, u); /* Cancel timeout */ if (u->us_serverstate == UPAPSS_LISTEN && u->us_reqtimeout > 0) UNTIMEOUT(upap_reqtimeout, u); u->us_clientstate = UPAPCS_INITIAL; u->us_serverstate = UPAPSS_INITIAL; } /* * upap_protrej - Peer doesn't speak this protocol. * * This shouldn't happen. In any case, pretend lower layer went down. */ static void upap_protrej(int unit) { upap_state *u = &upap[unit]; if (u->us_clientstate == UPAPCS_AUTHREQ) { error("PAP authentication failed due to protocol-reject"); auth_withpeer_fail(unit, PPP_PAP); } if (u->us_serverstate == UPAPSS_LISTEN) { error("PAP authentication of peer failed (protocol-reject)"); auth_peer_fail(unit, PPP_PAP); } upap_lowerdown(unit); } /* * upap_input - Input UPAP packet. */ static void upap_input(int unit, u_char *inpacket, int l) { upap_state *u = &upap[unit]; u_char *inp; u_char code, id; int len; /* * Parse header (code, id and length). * If packet too short, drop it. */ inp = inpacket; if (l < UPAP_HEADERLEN) { UPAPDEBUG(("pap_input: rcvd short header.")); return; } GETCHAR(code, inp); GETCHAR(id, inp); GETSHORT(len, inp); if (len < UPAP_HEADERLEN) { UPAPDEBUG(("pap_input: rcvd illegal length.")); return; } if (len > l) { UPAPDEBUG(("pap_input: rcvd short packet.")); return; } len -= UPAP_HEADERLEN; /* * Action depends on code. */ switch (code) { case UPAP_AUTHREQ: upap_rauthreq(u, inp, id, len); break; case UPAP_AUTHACK: upap_rauthack(u, inp, id, len); break; case UPAP_AUTHNAK: upap_rauthnak(u, inp, id, len); break; default: /* XXX Need code reject */ break; } } /* * upap_rauth - Receive Authenticate. */ static void upap_rauthreq(upap_state *u, u_char *inp, int id, int len) { u_char ruserlen, rpasswdlen; char *ruser, *rpasswd; char rhostname[256]; int retcode; char *msg; int msglen; if (u->us_serverstate < UPAPSS_LISTEN) return; /* * If we receive a duplicate authenticate-request, we are * supposed to return the same status as for the first request. */ if (u->us_serverstate == UPAPSS_OPEN) { upap_sresp(u, UPAP_AUTHACK, id, "", 0); /* return auth-ack */ return; } if (u->us_serverstate == UPAPSS_BADAUTH) { upap_sresp(u, UPAP_AUTHNAK, id, "", 0); /* return auth-nak */ return; } /* * Parse user/passwd. */ if (len < 1) { UPAPDEBUG(("pap_rauth: rcvd short packet.")); return; } GETCHAR(ruserlen, inp); len -= sizeof (u_char) + ruserlen + sizeof (u_char); if (len < 0) { UPAPDEBUG(("pap_rauth: rcvd short packet.")); return; } ruser = (char *) inp; INCPTR(ruserlen, inp); GETCHAR(rpasswdlen, inp); if (len < rpasswdlen) { UPAPDEBUG(("pap_rauth: rcvd short packet.")); return; } rpasswd = (char *) inp; /* * Check the username and password given. */ retcode = check_passwd(u->us_unit, ruser, ruserlen, rpasswd, rpasswdlen, &msg); BZERO(rpasswd, rpasswdlen); /* * Check remote number authorization. A plugin may have filled in * the remote number or added an allowed number, and rather than * return an authenticate failure, is leaving it for us to verify. */ if (retcode == UPAP_AUTHACK) { if (!auth_number()) { /* We do not want to leak info about the pap result. */ retcode = UPAP_AUTHNAK; /* XXX exit value will be "wrong" */ warn("calling number %q is not authorized", remote_number); } } msglen = strlen(msg); if (msglen > 255) msglen = 255; upap_sresp(u, retcode, id, msg, msglen); /* Null terminate and clean remote name. */ slprintf(rhostname, sizeof(rhostname), "%.*v", ruserlen, ruser); if (retcode == UPAP_AUTHACK) { u->us_serverstate = UPAPSS_OPEN; notice("PAP peer authentication succeeded for %q", rhostname); auth_peer_success(u->us_unit, PPP_PAP, 0, ruser, ruserlen); } else { u->us_serverstate = UPAPSS_BADAUTH; warn("PAP peer authentication failed for %q", rhostname); auth_peer_fail(u->us_unit, PPP_PAP); } if (u->us_reqtimeout > 0) UNTIMEOUT(upap_reqtimeout, u); } /* * upap_rauthack - Receive Authenticate-Ack. */ static void upap_rauthack(upap_state *u, u_char *inp, int id, int len) { u_char msglen; char *msg; if (u->us_clientstate != UPAPCS_AUTHREQ) /* XXX */ return; /* * Parse message. */ if (len < 1) { UPAPDEBUG(("pap_rauthack: ignoring missing msg-length.")); } else { GETCHAR(msglen, inp); if (msglen > 0) { len -= sizeof (u_char); if (len < msglen) { UPAPDEBUG(("pap_rauthack: rcvd short packet.")); return; } msg = (char *) inp; PRINTMSG(msg, msglen); } } u->us_clientstate = UPAPCS_OPEN; auth_withpeer_success(u->us_unit, PPP_PAP, 0); } /* * upap_rauthnak - Receive Authenticate-Nak. */ static void upap_rauthnak(upap_state *u, u_char *inp, int id, int len) { u_char msglen; char *msg; if (u->us_clientstate != UPAPCS_AUTHREQ) /* XXX */ return; /* * Parse message. */ if (len < 1) { UPAPDEBUG(("pap_rauthnak: ignoring missing msg-length.")); } else { GETCHAR(msglen, inp); if (msglen > 0) { len -= sizeof (u_char); if (len < msglen) { UPAPDEBUG(("pap_rauthnak: rcvd short packet.")); return; } msg = (char *) inp; PRINTMSG(msg, msglen); } } u->us_clientstate = UPAPCS_BADAUTH; error("PAP authentication failed"); auth_withpeer_fail(u->us_unit, PPP_PAP); } /* * upap_sauthreq - Send an Authenticate-Request. */ static void upap_sauthreq(upap_state *u) { u_char *outp; int outlen; outlen = UPAP_HEADERLEN + 2 * sizeof (u_char) + u->us_userlen + u->us_passwdlen; outp = outpacket_buf; MAKEHEADER(outp, PPP_PAP); PUTCHAR(UPAP_AUTHREQ, outp); PUTCHAR(++u->us_id, outp); PUTSHORT(outlen, outp); PUTCHAR(u->us_userlen, outp); BCOPY(u->us_user, outp, u->us_userlen); INCPTR(u->us_userlen, outp); PUTCHAR(u->us_passwdlen, outp); BCOPY(u->us_passwd, outp, u->us_passwdlen); output(u->us_unit, outpacket_buf, outlen + PPP_HDRLEN); TIMEOUT(upap_timeout, u, u->us_timeouttime); ++u->us_transmits; u->us_clientstate = UPAPCS_AUTHREQ; } /* * upap_sresp - Send a response (ack or nak). */ static void upap_sresp(upap_state *u, int code, int id, char *msg, int msglen) { u_char *outp; int outlen; outlen = UPAP_HEADERLEN + sizeof (u_char) + msglen; outp = outpacket_buf; MAKEHEADER(outp, PPP_PAP); PUTCHAR(code, outp); PUTCHAR(id, outp); PUTSHORT(outlen, outp); PUTCHAR(msglen, outp); BCOPY(msg, outp, msglen); output(u->us_unit, outpacket_buf, outlen + PPP_HDRLEN); } /* * upap_printpkt - print the contents of a PAP packet. */ static char *upap_codenames[] = { "AuthReq", "AuthAck", "AuthNak" }; static int upap_printpkt(u_char *p, int plen, void (*printer)(void *, char *, ...), void *arg) { int code, id, len; int mlen, ulen, wlen; char *user, *pwd, *msg; u_char *pstart; if (plen < UPAP_HEADERLEN) return 0; pstart = p; GETCHAR(code, p); GETCHAR(id, p); GETSHORT(len, p); if (len < UPAP_HEADERLEN || len > plen) return 0; if (code >= 1 && code <= sizeof(upap_codenames) / sizeof(char *)) printer(arg, " %s", upap_codenames[code-1]); else printer(arg, " code=0x%x", code); printer(arg, " id=0x%x", id); len -= UPAP_HEADERLEN; switch (code) { case UPAP_AUTHREQ: if (len < 1) break; ulen = p[0]; if (len < ulen + 2) break; wlen = p[ulen + 1]; if (len < ulen + wlen + 2) break; user = (char *) (p + 1); pwd = (char *) (p + ulen + 2); p += ulen + wlen + 2; len -= ulen + wlen + 2; printer(arg, " user="); print_string(user, ulen, printer, arg); printer(arg, " password="); if (!hide_password) print_string(pwd, wlen, printer, arg); else printer(arg, ""); break; case UPAP_AUTHACK: case UPAP_AUTHNAK: if (len < 1) break; mlen = p[0]; if (len < mlen + 1) break; msg = (char *) (p + 1); p += mlen + 1; len -= mlen + 1; printer(arg, " "); print_string(msg, mlen, printer, arg); break; } /* print the rest of the bytes in the packet */ for (; len > 0; --len) { GETCHAR(code, p); printer(arg, " %.2x", code); } return p - pstart; } ppp-2.5.0/pppd/utils.c0000644000175000017500000004646214353435407011531 00000000000000/* * utils.c - various utility functions used in pppd. * * Copyright (c) 1999-2002 Paul Mackerras. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. The name(s) of the authors of this software must not be used to * endorse or promote products derived from this software without * prior written permission. * * 3. Redistributions of any form whatsoever must retain the following * acknowledgment: * "This product includes software developed by Paul Mackerras * ". * * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef SVR4 #include #endif #include "pppd-private.h" #include "fsm.h" #include "lcp.h" #include "pathnames.h" #if defined(SUNOS4) extern char *strerror(); #endif static void logit(int, char *, va_list); static void log_write(int, char *); static void vslp_printer(void *, char *, ...); static void format_packet(u_char *, int, printer_func, void *); struct buffer_info { char *ptr; int len; }; /* * strlcpy - like strcpy/strncpy, doesn't overflow destination buffer, * always leaves destination null-terminated (for len > 0). */ size_t strlcpy(char *dest, const char *src, size_t len) { size_t ret = strlen(src); if (len != 0) { if (ret < len) strcpy(dest, src); else { strncpy(dest, src, len - 1); dest[len-1] = 0; } } return ret; } /* * strlcat - like strcat/strncat, doesn't overflow destination buffer, * always leaves destination null-terminated (for len > 0). */ size_t strlcat(char *dest, const char *src, size_t len) { size_t dlen = strlen(dest); return dlen + strlcpy(dest + dlen, src, (len > dlen? len - dlen: 0)); } /* * slprintf - format a message into a buffer. Like sprintf except we * also specify the length of the output buffer, and we handle * %m (error message), %v (visible string), * %q (quoted string), %t (current time) and %I (IP address) formats. * Doesn't do floating-point formats. * Returns the number of chars put into buf. */ int slprintf(char *buf, int buflen, char *fmt, ...) { va_list args; int n; va_start(args, fmt); n = vslprintf(buf, buflen, fmt, args); va_end(args); return n; } /* * vslprintf - like slprintf, takes a va_list instead of a list of args. */ #define OUTCHAR(c) (buflen > 0? (--buflen, *buf++ = (c)): 0) int vslprintf(char *buf, int buflen, char *fmt, va_list args) { int c, i, n; int width, prec, fillch; int base, len, neg, quoted; long lval = 0; unsigned long val = 0; char *str, *f, *buf0; unsigned char *p; char num[32]; time_t t; u_int32_t ip; static char hexchars[] = "0123456789abcdef"; struct buffer_info bufinfo; int termch; buf0 = buf; --buflen; while (buflen > 0) { for (f = fmt; *f != '%' && *f != 0; ++f) ; if (f > fmt) { len = f - fmt; if (len > buflen) len = buflen; memcpy(buf, fmt, len); buf += len; buflen -= len; fmt = f; } if (*fmt == 0) break; c = *++fmt; width = 0; prec = -1; fillch = ' '; if (c == '0') { fillch = '0'; c = *++fmt; } if (c == '*') { width = va_arg(args, int); c = *++fmt; } else { while (isdigit(c)) { width = width * 10 + c - '0'; c = *++fmt; } } if (c == '.') { c = *++fmt; if (c == '*') { prec = va_arg(args, int); c = *++fmt; } else { prec = 0; while (isdigit(c)) { prec = prec * 10 + c - '0'; c = *++fmt; } } } str = 0; base = 0; neg = 0; ++fmt; switch (c) { case 'l': c = *fmt++; switch (c) { case 'd': lval = va_arg(args, long); if (lval < 0) { neg = 1; val = -lval; } else val = lval; base = 10; break; case 'u': val = va_arg(args, unsigned long); base = 10; break; default: OUTCHAR('%'); OUTCHAR('l'); --fmt; /* so %lz outputs %lz etc. */ continue; } break; case 'd': i = va_arg(args, int); if (i < 0) { neg = 1; val = -i; } else val = i; base = 10; break; case 'u': val = va_arg(args, unsigned int); base = 10; break; case 'o': val = va_arg(args, unsigned int); base = 8; break; case 'x': case 'X': val = va_arg(args, unsigned int); base = 16; break; case 'p': val = (unsigned long) va_arg(args, void *); base = 16; neg = 2; break; case 's': str = va_arg(args, char *); break; case 'c': num[0] = va_arg(args, int); num[1] = 0; str = num; break; case 'm': str = strerror(errno); break; case 'I': ip = va_arg(args, u_int32_t); ip = ntohl(ip); slprintf(num, sizeof(num), "%d.%d.%d.%d", (ip >> 24) & 0xff, (ip >> 16) & 0xff, (ip >> 8) & 0xff, ip & 0xff); str = num; break; case 't': time(&t); str = ctime(&t); str += 4; /* chop off the day name */ str[15] = 0; /* chop off year and newline */ break; case 'v': /* "visible" string */ case 'q': /* quoted string */ quoted = c == 'q'; p = va_arg(args, unsigned char *); if (p == NULL) p = (unsigned char *)""; if (fillch == '0' && prec >= 0) { n = prec; termch = -1; /* matches no unsigned char value */ } else { n = buflen; if (prec != -1 && n > prec) n = prec; termch = 0; /* stop on null byte */ } while (n > 0 && buflen > 0) { c = *p++; if (c == termch) break; --n; if (!quoted && c >= 0x80) { OUTCHAR('M'); OUTCHAR('-'); c -= 0x80; } if (quoted && (c == '"' || c == '\\')) OUTCHAR('\\'); if (c < 0x20 || (0x7f <= c && c < 0xa0)) { if (quoted) { OUTCHAR('\\'); switch (c) { case '\t': OUTCHAR('t'); break; case '\n': OUTCHAR('n'); break; case '\b': OUTCHAR('b'); break; case '\f': OUTCHAR('f'); break; default: OUTCHAR('x'); OUTCHAR(hexchars[c >> 4]); OUTCHAR(hexchars[c & 0xf]); } } else { if (c == '\t') OUTCHAR(c); else { OUTCHAR('^'); OUTCHAR(c ^ 0x40); } } } else OUTCHAR(c); } continue; #ifndef UNIT_TEST case 'P': /* print PPP packet */ bufinfo.ptr = buf; bufinfo.len = buflen + 1; p = va_arg(args, unsigned char *); n = va_arg(args, int); format_packet(p, n, vslp_printer, &bufinfo); buf = bufinfo.ptr; buflen = bufinfo.len - 1; continue; #endif case 'B': p = va_arg(args, unsigned char *); for (n = prec; n > 0; --n) { c = *p++; if (fillch == ' ') OUTCHAR(' '); OUTCHAR(hexchars[(c >> 4) & 0xf]); OUTCHAR(hexchars[c & 0xf]); } continue; default: *buf++ = '%'; if (c != '%') --fmt; /* so %z outputs %z etc. */ --buflen; continue; } if (base != 0) { str = num + sizeof(num); *--str = 0; while (str > num + neg) { *--str = hexchars[val % base]; val = val / base; if (--prec <= 0 && val == 0) break; } switch (neg) { case 1: *--str = '-'; break; case 2: *--str = 'x'; *--str = '0'; break; } len = num + sizeof(num) - 1 - str; } else { for (len = 0; len < buflen && (prec == -1 || len < prec); ++len) if (str[len] == 0) break; } if (width > 0) { if (width > buflen) width = buflen; if ((n = width - len) > 0) { buflen -= n; for (; n > 0; --n) *buf++ = fillch; } } if (len > buflen) len = buflen; memcpy(buf, str, len); buf += len; buflen -= len; } *buf = 0; return buf - buf0; } /* * vslp_printer - used in processing a %P format */ static void vslp_printer(void *arg, char *fmt, ...) { int n; va_list pvar; struct buffer_info *bi; va_start(pvar, fmt); bi = (struct buffer_info *) arg; n = vslprintf(bi->ptr, bi->len, fmt, pvar); va_end(pvar); bi->ptr += n; bi->len -= n; } #ifdef unused /* * log_packet - format a packet and log it. */ void log_packet(u_char *p, int len, char *prefix, int level) { init_pr_log(prefix, level); format_packet(p, len, pr_log, &level); end_pr_log(); } #endif /* unused */ #ifndef UNIT_TEST /* * format_packet - make a readable representation of a packet, * calling `printer(arg, format, ...)' to output it. */ static void format_packet(u_char *p, int len, printer_func printer, void *arg) { int i, n; u_short proto; struct protent *protp; if (len >= PPP_HDRLEN && p[0] == PPP_ALLSTATIONS && p[1] == PPP_UI) { p += 2; GETSHORT(proto, p); len -= PPP_HDRLEN; for (i = 0; (protp = protocols[i]) != NULL; ++i) if (proto == protp->protocol) break; if (protp != NULL) { printer(arg, "[%s", protp->name); n = (*protp->printpkt)(p, len, printer, arg); printer(arg, "]"); p += n; len -= n; } else { for (i = 0; (protp = protocols[i]) != NULL; ++i) if (proto == (protp->protocol & ~0x8000)) break; if (protp != 0 && protp->data_name != 0) { printer(arg, "[%s data]", protp->data_name); if (len > 8) printer(arg, "%.8B ...", p); else printer(arg, "%.*B", len, p); len = 0; } else printer(arg, "[proto=0x%x]", proto); } } if (len > 32) printer(arg, "%.32B ...", p); else printer(arg, "%.*B", len, p); } #endif /* UNIT_TEST */ /* * init_pr_log, end_pr_log - initialize and finish use of pr_log. */ static char line[256]; /* line to be logged accumulated here */ static char *linep; /* current pointer within line */ static int llevel; /* level for logging */ void init_pr_log(const char *prefix, int level) { linep = line; if (prefix != NULL) { strlcpy(line, prefix, sizeof(line)); linep = line + strlen(line); } llevel = level; } void end_pr_log(void) { if (linep != line) { *linep = 0; log_write(llevel, line); } } /* * pr_log - printer routine for outputting to syslog */ void pr_log(void *arg, char *fmt, ...) { int l, n; va_list pvar; char *p, *eol; char buf[256]; va_start(pvar, fmt); n = vslprintf(buf, sizeof(buf), fmt, pvar); va_end(pvar); p = buf; eol = strchr(buf, '\n'); if (linep != line) { l = (eol == NULL)? n: eol - buf; if (linep + l < line + sizeof(line)) { if (l > 0) { memcpy(linep, buf, l); linep += l; } if (eol == NULL) return; p = eol + 1; eol = strchr(p, '\n'); } *linep = 0; log_write(llevel, line); linep = line; } while (eol != NULL) { *eol = 0; log_write(llevel, p); p = eol + 1; eol = strchr(p, '\n'); } /* assumes sizeof(buf) <= sizeof(line) */ l = buf + n - p; if (l > 0) { memcpy(line, p, n); linep = line + l; } } /* * print_string - print a readable representation of a string using * printer. */ void print_string(char *p, int len, printer_func printer, void *arg) { int c; printer(arg, "\""); for (; len > 0; --len) { c = *p++; if (' ' <= c && c <= '~') { if (c == '\\' || c == '"') printer(arg, "\\"); printer(arg, "%c", c); } else { switch (c) { case '\n': printer(arg, "\\n"); break; case '\r': printer(arg, "\\r"); break; case '\t': printer(arg, "\\t"); break; default: printer(arg, "\\%.3o", (unsigned char) c); } } } printer(arg, "\""); } /* * logit - does the hard work for fatal et al. */ static void logit(int level, char *fmt, va_list args) { char buf[1024]; vslprintf(buf, sizeof(buf), fmt, args); log_write(level, buf); } #ifndef UNIT_TEST static void log_write(int level, char *buf) { syslog(level, "%s", buf); if (log_to_fd >= 0 && (level != LOG_DEBUG || debug)) { int n = strlen(buf); if (n > 0 && buf[n-1] == '\n') --n; if (write(log_to_fd, buf, n) != n || write(log_to_fd, "\n", 1) != 1) log_to_fd = -1; } } #else static void log_write(int level, char *buf) { printf("<%d>: %s\n", level, buf); } #endif /* * fatal - log an error message and die horribly. */ void fatal(char *fmt, ...) { va_list pvar; va_start(pvar, fmt); logit(LOG_ERR, fmt, pvar); va_end(pvar); #ifndef UNIT_TEST die(1); /* as promised */ #else exit(-1); #endif } /* * error - log an error message. */ void error(char *fmt, ...) { va_list pvar; va_start(pvar, fmt); logit(LOG_ERR, fmt, pvar); va_end(pvar); ++error_count; } /* * warn - log a warning message. */ void warn(char *fmt, ...) { va_list pvar; va_start(pvar, fmt); logit(LOG_WARNING, fmt, pvar); va_end(pvar); } /* * notice - log a notice-level message. */ void notice(char *fmt, ...) { va_list pvar; va_start(pvar, fmt); logit(LOG_NOTICE, fmt, pvar); va_end(pvar); } /* * info - log an informational message. */ void info(char *fmt, ...) { va_list pvar; va_start(pvar, fmt); logit(LOG_INFO, fmt, pvar); va_end(pvar); } /* * dbglog - log a debug message. */ void dbglog(char *fmt, ...) { va_list pvar; va_start(pvar, fmt); logit(LOG_DEBUG, fmt, pvar); va_end(pvar); } /* * dump_packet - print out a packet in readable form if it is interesting. * Assumes len >= PPP_HDRLEN. */ void dump_packet(const char *tag, unsigned char *p, int len) { int proto; if (!debug) return; /* * don't print LCP echo request/reply packets if debug <= 1 * and the link is up. */ proto = (p[2] << 8) + p[3]; if (debug <= 1 && unsuccess == 0 && proto == PPP_LCP && len >= PPP_HDRLEN + HEADERLEN) { unsigned char *lcp = p + PPP_HDRLEN; int l = (lcp[2] << 8) + lcp[3]; if ((lcp[0] == ECHOREQ || lcp[0] == ECHOREP) && l >= HEADERLEN && l <= len - PPP_HDRLEN) return; } dbglog("%s %P", tag, p, len); } #ifndef UNIT_TEST /* * complete_read - read a full `count' bytes from fd, * unless end-of-file or an error other than EINTR is encountered. */ ssize_t complete_read(int fd, void *buf, size_t count) { size_t done; ssize_t nb; char *ptr = buf; for (done = 0; done < count; ) { nb = read(fd, ptr, count - done); if (nb < 0) { if (errno == EINTR && !ppp_signaled(SIGTERM)) continue; return -1; } if (nb == 0) break; done += nb; ptr += nb; } return done; } #endif /* Procedures for locking the serial device using a lock file. */ static char lock_file[MAXPATHLEN]; /* * lock - create a lock file for the named device */ int lock(char *dev) { #ifdef LOCKLIB int result; result = mklock (dev, (void *) 0); if (result == 0) { strlcpy(lock_file, dev, sizeof(lock_file)); return 0; } if (result > 0) notice("Device %s is locked by pid %d", dev, result); else error("Can't create lock file %s", lock_file); return -1; #else /* LOCKLIB */ char lock_buffer[12]; int fd, pid, n, siz; #ifdef SVR4 struct stat sbuf; if (stat(dev, &sbuf) < 0) { error("Can't get device number for %s: %m", dev); return -1; } if ((sbuf.st_mode & S_IFMT) != S_IFCHR) { error("Can't lock %s: not a character device", dev); return -1; } slprintf(lock_file, sizeof(lock_file), "%s/LK.%03d.%03d.%03d", PPP_PATH_LOCKDIR, major(sbuf.st_dev), major(sbuf.st_rdev), minor(sbuf.st_rdev)); #else char *p; char lockdev[MAXPATHLEN]; if ((p = strstr(dev, "dev/")) != NULL) { dev = p + 4; strncpy(lockdev, dev, MAXPATHLEN-1); lockdev[MAXPATHLEN-1] = 0; while ((p = strrchr(lockdev, '/')) != NULL) { *p = '_'; } dev = lockdev; } else if ((p = strrchr(dev, '/')) != NULL) dev = p + 1; slprintf(lock_file, sizeof(lock_file), "%s/LCK..%s", PPP_PATH_LOCKDIR, dev); #endif while ((fd = open(lock_file, O_EXCL | O_CREAT | O_RDWR, 0644)) < 0) { if (errno != EEXIST) { error("Can't create lock file %s: %m", lock_file); break; } /* Read the lock file to find out who has the device locked. */ fd = open(lock_file, O_RDONLY, 0); if (fd < 0) { if (errno == ENOENT) /* This is just a timing problem. */ continue; error("Can't open existing lock file %s: %m", lock_file); break; } #ifndef LOCK_BINARY n = read(fd, lock_buffer, 11); #else n = read(fd, &pid, sizeof(pid)); #endif /* LOCK_BINARY */ close(fd); fd = -1; if (n <= 0) { error("Can't read pid from lock file %s", lock_file); break; } /* See if the process still exists. */ #ifndef LOCK_BINARY lock_buffer[n] = 0; pid = atoi(lock_buffer); #endif /* LOCK_BINARY */ if (pid == getpid()) return 1; /* somebody else locked it for us */ if (pid == 0 || (kill(pid, 0) == -1 && errno == ESRCH)) { if (unlink (lock_file) == 0) { notice("Removed stale lock on %s (pid %d)", dev, pid); continue; } warn("Couldn't remove stale lock on %s", dev); } else notice("Device %s is locked by pid %d", dev, pid); break; } if (fd < 0) { lock_file[0] = 0; return -1; } pid = getpid(); #ifndef LOCK_BINARY siz = 11; slprintf(lock_buffer, sizeof(lock_buffer), "%10d\n", pid); n = write (fd, lock_buffer, siz); #else siz = sizeof (pid); n = write(fd, &pid, siz); #endif if (n != siz) { error("Could not write pid to lock file when locking"); } close(fd); return 0; #endif } /* * relock - called to update our lockfile when we are about to detach, * thus changing our pid (we fork, the child carries on, and the parent dies). * Note that this is called by the parent, with pid equal to the pid * of the child. This avoids a potential race which would exist if * we had the child rewrite the lockfile (the parent might die first, * and another process could think the lock was stale if it checked * between when the parent died and the child rewrote the lockfile). */ int relock(int pid) { #ifdef LOCKLIB /* XXX is there a way to do this? */ return -1; #else /* LOCKLIB */ int fd, n, siz; char lock_buffer[12]; if (lock_file[0] == 0) return -1; fd = open(lock_file, O_WRONLY, 0); if (fd < 0) { error("Couldn't reopen lock file %s: %m", lock_file); lock_file[0] = 0; return -1; } #ifndef LOCK_BINARY siz = 11; slprintf(lock_buffer, sizeof(lock_buffer), "%10d\n", pid); n = write (fd, lock_buffer, siz); #else siz = sizeof(pid); n = write(fd, &pid, siz); #endif /* LOCK_BINARY */ if (n != siz) { error("Could not write pid to lock file when locking"); } close(fd); return 0; #endif /* LOCKLIB */ } /* * unlock - remove our lockfile */ void unlock(void) { if (lock_file[0]) { #ifdef LOCKLIB (void) rmlock(lock_file, (void *) 0); #else unlink(lock_file); #endif lock_file[0] = 0; } } ppp-2.5.0/pppd/sys-linux.c0000644000175000017500000027701614402506361012336 00000000000000/* * sys-linux.c - System-dependent procedures for setting up * PPP interfaces on Linux systems * * Copyright (c) 1994-2004 Paul Mackerras. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. The name(s) of the authors of this software must not be used to * endorse or promote products derived from this software without * prior written permission. * * 3. Redistributions of any form whatsoever must retain the following * acknowledgment: * "This product includes software developed by Paul Mackerras * ". * * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * Derived from main.c and pppd.h, which are: * * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The name "Carnegie Mellon University" must not be used to * endorse or promote products derived from this software without * prior written permission. For permission or any legal * details, please contact * Office of Technology Transfer * Carnegie Mellon University * 5000 Forbes Avenue * Pittsburgh, PA 15213-3890 * (412) 268-4387, fax: (412) 268-7395 * tech-transfer@andrew.cmu.edu * * 4. Redistributions of any form whatsoever must retain the following * acknowledgment: * "This product includes software developed by Computing Services * at Carnegie Mellon University (http://www.cmu.edu/computing/)." * * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef HAVE_UTMP_H #include #endif #include #include #include #include #include #include /* This is in netdevice.h. However, this compile will fail miserably if you attempt to include netdevice.h because it has so many references to __memcpy functions which it should not attempt to do. So, since I really don't use it, but it must be defined, define it now. */ #ifndef MAX_ADDR_LEN #define MAX_ADDR_LEN 7 #endif #if !defined(__GLIBC__) || __GLIBC__ >= 2 #include /* glibc 2 conflicts with linux/types.h */ #include #include #include #include #else #include #include #include #include #include #endif #include #include #include #include #include #include /* Attempt at retaining compile-support with older than 4.7 kernels, or kernels * where RTM_NEWSTATS isn't defined for whatever reason. */ #ifndef RTM_NEWSTATS #define RTM_NEWSTATS 92 #define RTM_GETSTATS 94 #define IFLA_STATS_LINK_64 1 #endif #include /* glibc versions prior to 2.24 do not define SOL_NETLINK */ #ifndef SOL_NETLINK #define SOL_NETLINK 270 #endif /* linux kernel versions prior to 4.3 do not define/support NETLINK_CAP_ACK */ #ifndef NETLINK_CAP_ACK #define NETLINK_CAP_ACK 10 #endif /* linux kernel versions prior to 4.7 do not define/support IFLA_PPP_DEV_FD */ #ifndef IFLA_PPP_MAX /* IFLA_PPP_DEV_FD is declared as enum when IFLA_PPP_MAX is defined */ #define IFLA_PPP_DEV_FD 1 #endif #include "pppd-private.h" #include "options.h" #include "fsm.h" #include "ipcp.h" #ifdef PPP_WITH_IPV6CP #include "eui64.h" #endif /* PPP_WITH_IPV6CP */ #include "multilink.h" #ifdef PPP_WITH_FILTER #include #include #endif /* PPP_WITH_FILTER */ #ifdef LOCKLIB #include #endif /* * Instead of system header file use local "termios_linux.h" header * file as it provides additional support for arbitrary baud rates via BOTHER. */ #include "termios_linux.h" #ifdef PPP_WITH_IPV6CP #ifndef _LINUX_IN6_H /* * This is in linux/include/net/ipv6.h. */ struct in6_ifreq { struct in6_addr ifr6_addr; __u32 ifr6_prefixlen; unsigned int ifr6_ifindex; }; #endif #define IN6_LLADDR_FROM_EUI64(sin6, eui64) do { \ memset(&(sin6).s6_addr, 0, sizeof(struct in6_addr)); \ (sin6).s6_addr16[0] = htons(0xfe80); \ eui64_copy(eui64, (sin6).s6_addr32[2]); \ } while (0) static const eui64_t nulleui64; #endif /* PPP_WITH_IPV6CP */ /* We can get an EIO error on an ioctl if the modem has hung up */ #define ok_error(num) ((num)==EIO) static int tty_disc = N_TTY; /* The TTY discipline */ static int ppp_disc = N_PPP; /* The PPP discpline */ static int initfdflags = -1; /* Initial file descriptor flags for fd */ static int ppp_fd = -1; /* fd which is set to PPP discipline */ static int sock_fd = -1; /* socket for doing interface ioctls */ static int slave_fd = -1; /* pty for old-style demand mode, slave */ static int master_fd = -1; /* pty for old-style demand mode, master */ #ifdef PPP_WITH_IPV6CP static int sock6_fd = -1; #endif /* PPP_WITH_IPV6CP */ /* * For the old-style kernel driver, this is the same as ppp_fd. * For the new-style driver, it is the fd of an instance of /dev/ppp * which is attached to the ppp unit and is used for controlling it. */ int ppp_dev_fd = -1; /* fd for /dev/ppp (new style driver) */ static int chindex; /* channel index (new style driver) */ static fd_set in_fds; /* set of fds that wait_input waits for */ static int max_in_fd; /* highest fd set in in_fds */ static int has_proxy_arp = 0; static int driver_version = 0; static int driver_modification = 0; static int driver_patch = 0; static int driver_is_old = 0; static int restore_term = 0; /* 1 => we've munged the terminal */ static struct termios inittermios; /* Initial TTY termios */ int new_style_driver = 0; static char loop_name[20]; static unsigned char inbuf[512]; /* buffer for chars read from loopback */ static int if_is_up; /* Interface has been marked up */ static int if6_is_up; /* Interface has been marked up for IPv6, to help differentiate */ static int have_default_route; /* Gateway for default route added */ static int have_default_route6; /* Gateway for default IPv6 route added */ static struct rtentry old_def_rt; /* Old default route */ static int default_rt_repl_rest; /* replace and restore old default rt */ static u_int32_t proxy_arp_addr; /* Addr for proxy arp entry added */ static char proxy_arp_dev[16]; /* Device for proxy arp entry */ static u_int32_t our_old_addr; /* for detecting address changes */ static int dynaddr_set; /* 1 if ip_dynaddr set */ static int looped; /* 1 if using loop */ static int link_mtu; /* mtu for the link (not bundle) */ static struct utsname utsname; /* for the kernel version */ static int kernel_version; #define KVERSION(j,n,p) ((j)*1000000 + (n)*1000 + (p)) #define MAX_IFS 100 #define FLAGS_GOOD (IFF_UP | IFF_BROADCAST) #define FLAGS_MASK (IFF_UP | IFF_BROADCAST | \ IFF_POINTOPOINT | IFF_LOOPBACK | IFF_NOARP) #define SIN_ADDR(x) (((struct sockaddr_in *) (&(x)))->sin_addr.s_addr) /* Prototypes for procedures local to this file. */ static int modify_flags(int fd, int clear_bits, int set_bits); static int translate_speed (int bps); static int baud_rate_of (int speed); static void close_route_table (void); static int open_route_table (void); static int read_route_table (struct rtentry *rt); static int defaultroute_exists (struct rtentry *rt, int metric); static int defaultroute6_exists (struct in6_rtmsg *rt, int metric); static int get_ether_addr (u_int32_t ipaddr, struct sockaddr *hwaddr, char *name, int namelen); static void decode_version (char *buf, int *version, int *mod, int *patch); static int set_kdebugflag(int level); static int ppp_registered(void); static int make_ppp_unit(void); static int setifstate (int u, int state); extern u_char inpacket_buf[]; /* borrowed from main.c */ extern int dfl_route_metric; /* * SET_SA_FAMILY - set the sa_family field of a struct sockaddr, * if it exists. */ #define SET_SA_FAMILY(addr, family) \ memset ((char *) &(addr), '\0', sizeof(addr)); \ addr.sa_family = (family); /* * rtnetlink_msg - send rtnetlink message, receive response * and return received error code: * 0 - success * positive value - error during sending / receiving message * negative value - rtnetlink responce error code */ static int rtnetlink_msg(const char *desc, int *shared_fd, void *nlreq, size_t nlreq_len, void *nlresp_data, size_t *nlresp_size, unsigned nlresp_type) { struct nlresp_hdr { struct nlmsghdr nlh; struct nlmsgerr nlerr; } nlresp_hdr; struct sockaddr_nl nladdr; struct iovec iov[2]; struct msghdr msg; ssize_t nlresp_len; int one; int fd; if (shared_fd && *shared_fd >= 0) { fd = *shared_fd; } else { fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE); if (fd < 0) { error("rtnetlink_msg: socket(NETLINK_ROUTE): %m (line %d)", __LINE__); return 1; } /* * Tell kernel to not send to us payload of acknowledgment error message. * NETLINK_CAP_ACK option is supported since Linux kernel version 4.3 and * older kernel versions always send full payload in acknowledgment netlink * message. We ignore payload of this message as we need only error code, * to check if our set remote peer address request succeeded or failed. * So ignore return value from the following setsockopt() call as setting * option NETLINK_CAP_ACK means for us just a kernel hint / optimization. */ one = 1; setsockopt(fd, SOL_NETLINK, NETLINK_CAP_ACK, &one, sizeof(one)); memset(&nladdr, 0, sizeof(nladdr)); nladdr.nl_family = AF_NETLINK; if (bind(fd, (struct sockaddr *)&nladdr, sizeof(nladdr)) < 0) { error("rtnetlink_msg: bind(AF_NETLINK): %m (line %d)", __LINE__); close(fd); return 1; } if (shared_fd) *shared_fd = fd; } memset(&nladdr, 0, sizeof(nladdr)); nladdr.nl_family = AF_NETLINK; memset(&iov[0], 0, sizeof(iov[0])); iov[0].iov_base = nlreq; iov[0].iov_len = nlreq_len; memset(&msg, 0, sizeof(msg)); msg.msg_name = &nladdr; msg.msg_namelen = sizeof(nladdr); msg.msg_iov = &iov[0]; msg.msg_iovlen = 1; if (sendmsg(fd, &msg, 0) < 0) { error("rtnetlink_msg: sendmsg(%s): %m (line %d)", desc, __LINE__); if (!shared_fd) close(fd); return 1; } memset(iov, 0, sizeof(iov)); iov[0].iov_base = &nlresp_hdr; if (nlresp_size && *nlresp_size > sizeof(nlresp_hdr)) { iov[0].iov_len = offsetof(struct nlresp_hdr, nlerr); iov[1].iov_base = nlresp_data; iov[1].iov_len = *nlresp_size; } else { iov[0].iov_len = sizeof(nlresp_hdr); } memset(&msg, 0, sizeof(msg)); msg.msg_name = &nladdr; msg.msg_namelen = sizeof(nladdr); msg.msg_iov = iov; msg.msg_iovlen = (nlresp_size && *nlresp_size > sizeof(nlresp_hdr)) ? 2 : 1; nlresp_len = recvmsg(fd, &msg, 0); if (!shared_fd) close(fd); if (nlresp_len < 0) { error("rtnetlink_msg: recvmsg(%s): %m (line %d)", desc, __LINE__); return 1; } if (nladdr.nl_family != AF_NETLINK) { error("rtnetlink_msg: recvmsg(%s): Not a netlink packet (line %d)", desc, __LINE__); return 1; } if (!nlresp_size) { if ((size_t)nlresp_len < sizeof(nlresp_hdr) || nlresp_hdr.nlh.nlmsg_len < sizeof(nlresp_hdr)) { error("rtnetlink_msg: recvmsg(%s): Acknowledgment netlink packet too short (line %d)", desc, __LINE__); return 1; } /* acknowledgment packet for NLM_F_ACK is NLMSG_ERROR */ if (nlresp_hdr.nlh.nlmsg_type != NLMSG_ERROR) { error("rtnetlink_msg: recvmsg(%s): Not an acknowledgment netlink packet (line %d)", desc, __LINE__); return 1; } } if (nlresp_size) { if (*nlresp_size > sizeof(nlresp_hdr)) memcpy((unsigned char *)&nlresp_hdr + offsetof(struct nlresp_hdr, nlerr), nlresp_data, sizeof(nlresp_hdr.nlerr)); else memcpy(nlresp_data, (unsigned char *)&nlresp_hdr + offsetof(struct nlresp_hdr, nlerr), *nlresp_size); } /* error == 0 indicates success, negative value is errno code */ if (nlresp_hdr.nlh.nlmsg_type == NLMSG_ERROR && nlresp_hdr.nlerr.error) return nlresp_hdr.nlerr.error; if (nlresp_size) { if (nlresp_hdr.nlh.nlmsg_type != nlresp_type) { error("rtnetlink_msg: recvmsg(%s): Not a netlink packet of type 0x%x (line %d)", desc, nlresp_type, __LINE__); return 1; } *nlresp_size = nlresp_len - offsetof(struct nlresp_hdr, nlerr); } return 0; } /* * Determine if the PPP connection should still be present. */ extern int hungup; /* new_fd is the fd of a tty */ static void set_ppp_fd (int new_fd) { ppp_fd = new_fd; if (!new_style_driver) ppp_dev_fd = new_fd; } static int still_ppp(void) { if (new_style_driver) return !hungup && ppp_fd >= 0; if (!hungup || ppp_fd == slave_fd) return 1; if (slave_fd >= 0) { set_ppp_fd(slave_fd); return 1; } return 0; } /* * modify_flags - set and clear flag bits controlling the kernel * PPP driver. */ static int modify_flags(int fd, int clear_bits, int set_bits) { int flags; if (ioctl(fd, PPPIOCGFLAGS, &flags) == -1) goto err; flags = (flags & ~clear_bits) | set_bits; if (ioctl(fd, PPPIOCSFLAGS, &flags) == -1) goto err; return 0; err: if (errno != EIO) error("Failed to set PPP kernel option flags: %m"); return -1; } /******************************************************************** * * sys_init - System-dependent initialization. */ void sys_init(void) { /* Get an internet socket for doing socket ioctls. */ sock_fd = socket(AF_INET, SOCK_DGRAM, 0); if (sock_fd < 0) fatal("Couldn't create IP socket: %m(%d)", errno); #ifdef PPP_WITH_IPV6CP sock6_fd = socket(AF_INET6, SOCK_DGRAM, 0); if (sock6_fd < 0) sock6_fd = -errno; /* save errno for later */ #endif FD_ZERO(&in_fds); max_in_fd = 0; } /******************************************************************** * * sys_cleanup - restore any system state we modified before exiting: * mark the interface down, delete default route and/or proxy arp entry. * This shouldn't call die() because it's called from die(). */ void sys_cleanup(void) { /* * Take down the device */ if (if_is_up) { if_is_up = 0; sifdown(0); } #ifdef PPP_WITH_IPV6CP if (if6_is_up) sif6down(0); #endif /* * Delete any routes through the device. */ if (have_default_route) cifdefaultroute(0, 0, 0); #ifdef PPP_WITH_IPV6CP if (have_default_route6) cif6defaultroute(0, nulleui64, nulleui64); #endif if (has_proxy_arp) cifproxyarp(0, proxy_arp_addr); } /******************************************************************** * * ppp_sys_close - Clean up in a child process before execing. */ void ppp_sys_close(void) { if (new_style_driver && ppp_dev_fd >= 0) close(ppp_dev_fd); if (sock_fd >= 0) close(sock_fd); #ifdef PPP_WITH_IPV6CP if (sock6_fd >= 0) close(sock6_fd); #endif if (slave_fd >= 0) close(slave_fd); if (master_fd >= 0) close(master_fd); } /******************************************************************** * * set_kdebugflag - Define the debugging level for the kernel */ static int set_kdebugflag (int requested_level) { if (ppp_dev_fd < 0) return 1; if (ioctl(ppp_dev_fd, PPPIOCSDEBUG, &requested_level) < 0) { if ( ! ok_error (errno) ) error("ioctl(PPPIOCSDEBUG): %m (line %d)", __LINE__); return (0); } return (1); } /******************************************************************** * * tty_establish_ppp - Turn the serial port into a ppp interface. */ int tty_establish_ppp (int tty_fd) { int ret_fd; /* * Ensure that the tty device is in exclusive mode. */ if (ioctl(tty_fd, TIOCEXCL, 0) < 0) { if ( ! ok_error ( errno )) warn("Couldn't make tty exclusive: %m"); } /* * Demand mode - prime the old ppp device to relinquish the unit. */ if (!new_style_driver && looped && ioctl(slave_fd, PPPIOCXFERUNIT, 0) < 0) { error("ioctl(transfer ppp unit): %m, line %d", __LINE__); return -1; } /* * Set the current tty to the PPP discpline */ #ifndef N_SYNC_PPP #define N_SYNC_PPP 14 #endif ppp_disc = (new_style_driver && ppp_sync_serial())? N_SYNC_PPP: N_PPP; if (ioctl(tty_fd, TIOCSETD, &ppp_disc) < 0) { if ( ! ok_error (errno) ) { error("Couldn't set tty to PPP discipline: %m"); return -1; } } ret_fd = ppp_generic_establish(tty_fd); #define SC_RCVB (SC_RCV_B7_0 | SC_RCV_B7_1 | SC_RCV_EVNP | SC_RCV_ODDP) #define SC_LOGB (SC_DEBUG | SC_LOG_INPKT | SC_LOG_OUTPKT | SC_LOG_RAWIN \ | SC_LOG_FLUSH) if (ret_fd >= 0) { modify_flags(ppp_fd, SC_RCVB | SC_LOGB, (kdebugflag * SC_DEBUG) & SC_LOGB); } else { if (ioctl(tty_fd, TIOCSETD, &tty_disc) < 0 && !ok_error(errno)) warn("Couldn't reset tty to normal line discipline: %m"); } return ret_fd; } /******************************************************************** * * generic_establish_ppp - Turn the fd into a ppp interface. */ int ppp_generic_establish (int fd) { int x; if (new_style_driver) { int flags; /* If a ppp_fd is already open, close it first */ if (ppp_fd >= 0) { close(ppp_fd); remove_fd(ppp_fd); ppp_fd = -1; } /* Open an instance of /dev/ppp and connect the channel to it */ if (ioctl(fd, PPPIOCGCHAN, &chindex) == -1) { error("Couldn't get channel number: %m"); goto err; } dbglog("using channel %d", chindex); fd = open("/dev/ppp", O_RDWR); if (fd < 0) { error("Couldn't reopen /dev/ppp: %m"); goto err; } (void) fcntl(fd, F_SETFD, FD_CLOEXEC); if (ioctl(fd, PPPIOCATTCHAN, &chindex) < 0) { error("Couldn't attach to channel %d: %m", chindex); goto err_close; } flags = fcntl(fd, F_GETFL); if (flags == -1 || fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1) warn("Couldn't set /dev/ppp (channel) to nonblock: %m"); set_ppp_fd(fd); if (!looped) ifunit = -1; if (!looped && !multilink) { /* * Create a new PPP unit. */ if (make_ppp_unit() < 0) goto err_close; } if (looped) modify_flags(ppp_dev_fd, SC_LOOP_TRAFFIC, 0); if (!multilink) { add_fd(ppp_dev_fd); if (ioctl(fd, PPPIOCCONNECT, &ifunit) < 0) { error("Couldn't attach to PPP unit %d: %m", ifunit); goto err_close; } } } else { /* * Old-style driver: find out which interface we were given. */ set_ppp_fd (fd); if (ioctl(fd, PPPIOCGUNIT, &x) < 0) { if (ok_error (errno)) goto err; fatal("ioctl(PPPIOCGUNIT): %m (line %d)", __LINE__); } /* Check that we got the same unit again. */ if (looped && x != ifunit) fatal("transfer_ppp failed: wanted unit %d, got %d", ifunit, x); ifunit = x; /* * Fetch the initial file flags and reset blocking mode on the file. */ initfdflags = fcntl(fd, F_GETFL); if (initfdflags == -1 || fcntl(fd, F_SETFL, initfdflags | O_NONBLOCK) == -1) { if ( ! ok_error (errno)) warn("Couldn't set device to non-blocking mode: %m"); } } /* * Enable debug in the driver if requested. */ if (!looped) set_kdebugflag (kdebugflag); looped = 0; return ppp_fd; err_close: close(fd); err: return -1; } /******************************************************************** * * tty_disestablish_ppp - Restore the serial port to normal operation. * This shouldn't call die() because it's called from die(). */ void tty_disestablish_ppp(int tty_fd) { if (!hungup) { /* * Flush the tty output buffer so that the TIOCSETD doesn't hang. */ if (tcflush(tty_fd, TCIOFLUSH) < 0) { warn("tcflush failed: %m"); goto flushfailed; } /* * Restore the previous line discipline */ if (ioctl(tty_fd, TIOCSETD, &tty_disc) < 0) { if ( ! ok_error (errno)) error("ioctl(TIOCSETD, N_TTY): %m (line %d)", __LINE__); } if (ioctl(tty_fd, TIOCNXCL, 0) < 0) { if ( ! ok_error (errno)) warn("ioctl(TIOCNXCL): %m (line %d)", __LINE__); } /* Reset non-blocking mode on fd. */ if (initfdflags != -1 && fcntl(tty_fd, F_SETFL, initfdflags) < 0) { if ( ! ok_error (errno)) warn("Couldn't restore device fd flags: %m"); } } flushfailed: initfdflags = -1; ppp_generic_disestablish(tty_fd); } /******************************************************************** * * ppp_generic_disestablish - Restore device components to normal * operation, and reconnect the ppp unit to the loopback if in demand * mode. This shouldn't call die() because it's called from die(). */ void ppp_generic_disestablish(int dev_fd) { if (new_style_driver) { close(ppp_fd); ppp_fd = -1; if (demand) { modify_flags(ppp_dev_fd, 0, SC_LOOP_TRAFFIC); looped = 1; } else if (!mp_on() && ppp_dev_fd >= 0) { close(ppp_dev_fd); remove_fd(ppp_dev_fd); ppp_dev_fd = -1; } } else { /* old-style driver */ if (demand) set_ppp_fd(slave_fd); else ppp_dev_fd = -1; } } /* * make_ppp_unit_rtnetlink - register a new ppp network interface for ppp_dev_fd * with specified req_ifname via rtnetlink. Interface name req_ifname must not * be empty. Custom ppp unit id req_unit is ignored and kernel choose some free. */ static int make_ppp_unit_rtnetlink(void) { struct { struct nlmsghdr nlh; struct ifinfomsg ifm; struct { struct rtattr rta; char ifname[IFNAMSIZ]; } ifn; struct { struct rtattr rta; struct { struct rtattr rta; char ifkind[sizeof("ppp")]; } ifik; struct { struct rtattr rta; struct { struct rtattr rta; union { int ppp_dev_fd; } ppp; } ifdata[1]; } ifid; } ifli; } nlreq; int resp; memset(&nlreq, 0, sizeof(nlreq)); nlreq.nlh.nlmsg_len = sizeof(nlreq); nlreq.nlh.nlmsg_type = RTM_NEWLINK; nlreq.nlh.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK | NLM_F_EXCL | NLM_F_CREATE; nlreq.ifm.ifi_family = AF_UNSPEC; nlreq.ifm.ifi_type = ARPHRD_NETROM; nlreq.ifn.rta.rta_len = sizeof(nlreq.ifn); nlreq.ifn.rta.rta_type = IFLA_IFNAME; strlcpy(nlreq.ifn.ifname, req_ifname, sizeof(nlreq.ifn.ifname)); nlreq.ifli.rta.rta_len = sizeof(nlreq.ifli); nlreq.ifli.rta.rta_type = IFLA_LINKINFO; nlreq.ifli.ifik.rta.rta_len = sizeof(nlreq.ifli.ifik); nlreq.ifli.ifik.rta.rta_type = IFLA_INFO_KIND; strcpy(nlreq.ifli.ifik.ifkind, "ppp"); nlreq.ifli.ifid.rta.rta_len = sizeof(nlreq.ifli.ifid); nlreq.ifli.ifid.rta.rta_type = IFLA_INFO_DATA; nlreq.ifli.ifid.ifdata[0].rta.rta_len = sizeof(nlreq.ifli.ifid.ifdata[0]); nlreq.ifli.ifid.ifdata[0].rta.rta_type = IFLA_PPP_DEV_FD; nlreq.ifli.ifid.ifdata[0].ppp.ppp_dev_fd = ppp_dev_fd; /* * See kernel function ppp_nl_newlink(), which may return -EBUSY to prevent * possible deadlock in kernel and ask userspace to retry request again. */ do { resp = rtnetlink_msg("RTM_NEWLINK/NLM_F_CREATE", NULL, &nlreq, sizeof(nlreq), NULL, NULL, 0); } while (resp == -EBUSY); if (resp) { /* * Linux kernel versions prior to 4.7 do not support creating ppp * interfaces via rtnetlink API and therefore error response is * expected. On older kernel versions do not show this error message. * When error is different than EEXIST then pppd tries to fallback to * the old ioctl method. */ errno = (resp < 0) ? -resp : EINVAL; if (kernel_version >= KVERSION(4,7,0)) error("Couldn't create ppp interface %s: %m", req_ifname); return 0; } return 1; } /* * make_ppp_unit - make a new ppp unit for ppp_dev_fd. * Assumes new_style_driver. */ static int make_ppp_unit(void) { int x, flags; if (ppp_dev_fd >= 0) { dbglog("in make_ppp_unit, already had /dev/ppp open?"); close(ppp_dev_fd); } ppp_dev_fd = open("/dev/ppp", O_RDWR); if (ppp_dev_fd < 0) fatal("Couldn't open /dev/ppp: %m"); flags = fcntl(ppp_dev_fd, F_GETFL); if (flags == -1 || fcntl(ppp_dev_fd, F_SETFL, flags | O_NONBLOCK) == -1) warn("Couldn't set /dev/ppp to nonblock: %m"); /* * Via rtnetlink it is possible to create ppp network interface with * custom ifname atomically. But it is not possible to specify custom * ppp unit id. * * Tools like systemd, udev or NetworkManager are trying to query * interface attributes based on interface name immediately when new * network interface is created. And therefore immediate interface * renaming is causing issues. * * So use rtnetlink API only when user requested custom ifname. It will * avoid system issues with interface renaming. */ if (req_unit == -1 && req_ifname[0] != '\0' && kernel_version >= KVERSION(2,1,16)) { if (make_ppp_unit_rtnetlink()) { if (ioctl(ppp_dev_fd, PPPIOCGUNIT, &ifunit)) fatal("Couldn't retrieve PPP unit id: %m"); return 0; } /* * If interface with requested name already exist return error * otherwise fallback to old ioctl method. */ if (errno == EEXIST) return -1; } ifunit = req_unit; x = ioctl(ppp_dev_fd, PPPIOCNEWUNIT, &ifunit); if (x < 0 && req_unit >= 0 && errno == EEXIST) { warn("Couldn't allocate PPP unit %d as it is already in use", req_unit); ifunit = -1; x = ioctl(ppp_dev_fd, PPPIOCNEWUNIT, &ifunit); } if (x < 0 && errno == EEXIST) { srand(time(NULL) * getpid()); ifunit = rand() % 10000; x = ioctl(ppp_dev_fd, PPPIOCNEWUNIT, &ifunit); } if (x < 0) error("Couldn't create new ppp unit: %m"); if (x == 0 && req_ifname[0] != '\0') { struct ifreq ifr; char t[IFNAMSIZ]; memset(&ifr, 0, sizeof(struct ifreq)); slprintf(t, sizeof(t), "%s%d", PPP_DRV_NAME, ifunit); strlcpy(ifr.ifr_name, t, IFNAMSIZ); strlcpy(ifr.ifr_newname, req_ifname, IFNAMSIZ); x = ioctl(sock_fd, SIOCSIFNAME, &ifr); if (x < 0) error("Couldn't rename interface %s to %s: %m", t, req_ifname); else info("Renamed interface %s to %s", t, req_ifname); } return x; } /* * cfg_bundle - configure the existing bundle. * Used in demand mode. */ void cfg_bundle(int mrru, int mtru, int rssn, int tssn) { if (!new_style_driver) return; /* set the mrru, mtu and flags */ if (ioctl(ppp_dev_fd, PPPIOCSMRRU, &mrru) < 0) error("Couldn't set MRRU: %m"); modify_flags(ppp_dev_fd, SC_MP_SHORTSEQ|SC_MP_XSHORTSEQ|SC_MULTILINK, ((rssn? SC_MP_SHORTSEQ: 0) | (tssn? SC_MP_XSHORTSEQ: 0) | (mrru? SC_MULTILINK: 0))); /* connect up the channel */ if (ioctl(ppp_fd, PPPIOCCONNECT, &ifunit) < 0) fatal("Couldn't attach to PPP unit %d: %m", ifunit); add_fd(ppp_dev_fd); } /* * make_new_bundle - create a new PPP unit (i.e. a bundle) * and connect our channel to it. This should only get called * if `multilink' was set at the time establish_ppp was called. * In demand mode this uses our existing bundle instead of making * a new one. */ void make_new_bundle(int mrru, int mtru, int rssn, int tssn) { if (!new_style_driver) return; /* make us a ppp unit */ if (make_ppp_unit() < 0) die(1); /* set the mrru and flags */ cfg_bundle(mrru, mtru, rssn, tssn); } /* * bundle_attach - attach our link to a given PPP unit. * We assume the unit is controlled by another pppd. */ int bundle_attach(int ifnum) { int master_fd; if (!new_style_driver) return -1; master_fd = open("/dev/ppp", O_RDWR); if (master_fd < 0) fatal("Couldn't open /dev/ppp: %m"); if (ioctl(master_fd, PPPIOCATTACH, &ifnum) < 0) { if (errno == ENXIO) { close(master_fd); return 0; /* doesn't still exist */ } fatal("Couldn't attach to interface unit %d: %m\n", ifnum); } if (ioctl(ppp_fd, PPPIOCCONNECT, &ifnum) < 0) fatal("Couldn't connect to interface unit %d: %m", ifnum); modify_flags(master_fd, 0, SC_MULTILINK); close(master_fd); ifunit = ifnum; return 1; } /* * destroy_bundle - tell the driver to destroy our bundle. */ void destroy_bundle(void) { if (ppp_dev_fd >= 0) { close(ppp_dev_fd); remove_fd(ppp_dev_fd); ppp_dev_fd = -1; } } /******************************************************************** * * clean_check - Fetch the flags for the device and generate * appropriate error messages. */ void clean_check(void) { int x; char *s; if (still_ppp()) { if (ioctl(ppp_fd, PPPIOCGFLAGS, (caddr_t) &x) == 0) { s = NULL; switch (~x & (SC_RCV_B7_0|SC_RCV_B7_1|SC_RCV_EVNP|SC_RCV_ODDP)) { case SC_RCV_B7_0: s = "all had bit 7 set to 1"; break; case SC_RCV_B7_1: s = "all had bit 7 set to 0"; break; case SC_RCV_EVNP: s = "all had odd parity"; break; case SC_RCV_ODDP: s = "all had even parity"; break; } if (s != NULL) { warn("Receive serial link is not 8-bit clean:"); warn("Problem: %s", s); } } } } /* * List of valid speeds. */ struct speed { int speed_int, speed_val; } speeds[] = { #ifdef B50 { 50, B50 }, #endif #ifdef B75 { 75, B75 }, #endif #ifdef B110 { 110, B110 }, #endif #ifdef B134 { 134, B134 }, #endif #ifdef B150 { 150, B150 }, #endif #ifdef B200 { 200, B200 }, #endif #ifdef B300 { 300, B300 }, #endif #ifdef B600 { 600, B600 }, #endif #ifdef B1200 { 1200, B1200 }, #endif #ifdef B1800 { 1800, B1800 }, #endif #ifdef B2000 { 2000, B2000 }, #endif #ifdef B2400 { 2400, B2400 }, #endif #ifdef B3600 { 3600, B3600 }, #endif #ifdef B4800 { 4800, B4800 }, #endif #ifdef B7200 { 7200, B7200 }, #endif #ifdef B9600 { 9600, B9600 }, #endif #ifdef B19200 { 19200, B19200 }, #endif #ifdef B38400 { 38400, B38400 }, #endif #ifdef B57600 { 57600, B57600 }, #endif #ifdef B76800 { 76800, B76800 }, #endif #ifdef B115200 { 115200, B115200 }, #endif #ifdef B153600 { 153600, B153600 }, #endif #ifdef EXTA { 19200, EXTA }, #endif #ifdef EXTB { 38400, EXTB }, #endif #ifdef B230400 { 230400, B230400 }, #endif #ifdef B307200 { 307200, B307200 }, #endif #ifdef B460800 { 460800, B460800 }, #endif #ifdef B500000 { 500000, B500000 }, #endif #ifdef B576000 { 576000, B576000 }, #endif #ifdef B614400 { 614400, B614400 }, #endif #ifdef B921600 { 921600, B921600 }, #endif #ifdef B1000000 { 1000000, B1000000 }, #endif #ifdef B1152000 { 1152000, B1152000 }, #endif #ifdef B1500000 { 1500000, B1500000 }, #endif #ifdef B2000000 { 2000000, B2000000 }, #endif #ifdef B2500000 { 2500000, B2500000 }, #endif #ifdef B3000000 { 3000000, B3000000 }, #endif #ifdef B3500000 { 3500000, B3500000 }, #endif #ifdef B4000000 { 4000000, B4000000 }, #endif { 0, 0 } }; /******************************************************************** * * Translate from bits/second to a speed_t. */ static int translate_speed (int bps) { struct speed *speedp; if (bps != 0) { for (speedp = speeds; speedp->speed_int; speedp++) { if (bps == speedp->speed_int) return speedp->speed_val; } } return 0; } /******************************************************************** * * Translate from a speed_t to bits/second. */ static int baud_rate_of (int speed) { struct speed *speedp; if (speed != 0) { for (speedp = speeds; speedp->speed_int; speedp++) { if (speed == speedp->speed_val) return speedp->speed_int; } } return 0; } /******************************************************************** * * set_up_tty: Set up the serial port on `fd' for 8 bits, no parity, * at the requested speed, etc. If `local' is true, set CLOCAL * regardless of whether the modem option was specified. */ void set_up_tty(int tty_fd, int local) { int speed; struct termios tios; setdtr(tty_fd, 1); if (tcgetattr(tty_fd, &tios) < 0) { if (!ok_error(errno)) fatal("tcgetattr: %m (line %d)", __LINE__); return; } if (!restore_term) inittermios = tios; tios.c_cflag &= ~(CSIZE | CSTOPB | PARENB | CLOCAL); tios.c_cflag |= CS8 | CREAD | HUPCL; tios.c_iflag = IGNBRK | IGNPAR; tios.c_oflag = 0; tios.c_lflag = 0; tios.c_cc[VMIN] = 1; tios.c_cc[VTIME] = 0; if (local || !modem) tios.c_cflag ^= (CLOCAL | HUPCL); switch (crtscts) { case 1: tios.c_cflag |= CRTSCTS; break; case -2: tios.c_iflag |= IXON | IXOFF; tios.c_cc[VSTOP] = 0x13; /* DC3 = XOFF = ^S */ tios.c_cc[VSTART] = 0x11; /* DC1 = XON = ^Q */ break; case -1: tios.c_cflag &= ~CRTSCTS; break; default: break; } if (stop_bits >= 2) tios.c_cflag |= CSTOPB; if (inspeed) { speed = translate_speed(inspeed); if (speed) { cfsetospeed (&tios, speed); cfsetispeed (&tios, speed); speed = cfgetospeed(&tios); baud_rate = baud_rate_of(speed); } else { #ifdef BOTHER tios.c_cflag &= ~CBAUD; tios.c_cflag |= BOTHER; tios.c_ospeed = inspeed; #ifdef IBSHIFT /* B0 sets input baudrate to the output baudrate */ tios.c_cflag &= ~(CBAUD << IBSHIFT); tios.c_cflag |= B0 << IBSHIFT; tios.c_ispeed = inspeed; #endif baud_rate = inspeed; #else baud_rate = 0; #endif } } else { speed = cfgetospeed(&tios); baud_rate = baud_rate_of(speed); #ifdef BOTHER if (!baud_rate) baud_rate = tios.c_ospeed; #endif } /* * We can't proceed if the serial port baud rate is unknown, * since that implies that the serial port is disabled. */ if (!baud_rate) { if (inspeed) fatal("speed %d not supported", inspeed); else fatal("Baud rate for %s is 0; need explicit baud rate", devnam); } while (tcsetattr(tty_fd, TCSAFLUSH, &tios) < 0 && !ok_error(errno)) if (errno != EINTR) fatal("tcsetattr: %m (line %d)", __LINE__); restore_term = 1; } /******************************************************************** * * setdtr - control the DTR line on the serial port. * This is called from die(), so it shouldn't call die(). */ void setdtr (int tty_fd, int on) { int modembits = TIOCM_DTR; ioctl(tty_fd, (on ? TIOCMBIS : TIOCMBIC), &modembits); } /******************************************************************** * * restore_tty - restore the terminal to the saved settings. */ void restore_tty (int tty_fd) { if (restore_term) { restore_term = 0; /* * Turn off echoing, because otherwise we can get into * a loop with the tty and the modem echoing to each other. * We presume we are the sole user of this tty device, so * when we close it, it will revert to its defaults anyway. */ if (!default_device) inittermios.c_lflag &= ~(ECHO | ECHONL); if (tcsetattr(tty_fd, TCSAFLUSH, &inittermios) < 0) { if (! ok_error (errno)) warn("tcsetattr: %m (line %d)", __LINE__); } } } /******************************************************************** * * output - Output PPP packet. */ void output (int unit, unsigned char *p, int len) { int fd = ppp_fd; int proto; dump_packet("sent", p, len); if (snoop_send_hook) snoop_send_hook(p, len); if (len < PPP_HDRLEN) return; if (new_style_driver) { p += 2; len -= 2; proto = (p[0] << 8) + p[1]; if (ppp_dev_fd >= 0 && !(proto >= 0xc000 || proto == PPP_CCPFRAG)) fd = ppp_dev_fd; } if (write(fd, p, len) < 0) { if (errno == EWOULDBLOCK || errno == EAGAIN || errno == ENOBUFS || errno == ENXIO || errno == EIO || errno == EINTR) warn("write: warning: %m (%d)", errno); else error("write: %m (%d)", errno); } } /******************************************************************** * * wait_input - wait until there is data available, * for the length of time specified by *timo (indefinite * if timo is NULL). */ void wait_input(struct timeval *timo) { fd_set ready, exc; int n; ready = in_fds; exc = in_fds; n = select(max_in_fd + 1, &ready, NULL, &exc, timo); if (n < 0 && errno != EINTR) fatal("select: %m"); } /* * add_fd - add an fd to the set that wait_input waits for. */ void add_fd(int fd) { if (fd >= FD_SETSIZE) fatal("internal error: file descriptor too large (%d)", fd); FD_SET(fd, &in_fds); if (fd > max_in_fd) max_in_fd = fd; } /* * remove_fd - remove an fd from the set that wait_input waits for. */ void remove_fd(int fd) { FD_CLR(fd, &in_fds); } /******************************************************************** * * read_packet - get a PPP packet from the serial device. */ int read_packet (unsigned char *buf) { int len, nr; len = PPP_MRU + PPP_HDRLEN; if (new_style_driver) { *buf++ = PPP_ALLSTATIONS; *buf++ = PPP_UI; len -= 2; } nr = -1; if (ppp_fd >= 0) { nr = read(ppp_fd, buf, len); if (nr < 0 && errno != EWOULDBLOCK && errno != EAGAIN && errno != EIO && errno != EINTR) error("read: %m"); if (nr < 0 && errno == ENXIO) return 0; } if (nr < 0 && new_style_driver && ppp_dev_fd >= 0 && !bundle_eof) { /* N.B. we read ppp_fd first since LCP packets come in there. */ nr = read(ppp_dev_fd, buf, len); if (nr < 0 && errno != EWOULDBLOCK && errno != EAGAIN && errno != EIO && errno != EINTR) error("read /dev/ppp: %m"); if (nr < 0 && errno == ENXIO) nr = 0; if (nr == 0 && mp_on()) { remove_fd(ppp_dev_fd); bundle_eof = 1; } } if (new_style_driver && ppp_fd < 0 && ppp_dev_fd < 0) nr = 0; return (new_style_driver && nr > 0)? nr+2: nr; } /******************************************************************** * * get_loop_output - get outgoing packets from the ppp device, * and detect when we want to bring the real link up. * Return value is 1 if we need to bring up the link, 0 otherwise. */ int get_loop_output(void) { int rv = 0; int n; if (new_style_driver) { while ((n = read_packet(inpacket_buf)) > 0) if (loop_frame(inpacket_buf, n)) rv = 1; return rv; } while ((n = read(master_fd, inbuf, sizeof(inbuf))) > 0) if (loop_chars(inbuf, n)) rv = 1; if (n == 0) fatal("eof on loopback"); if (errno != EWOULDBLOCK && errno != EAGAIN) fatal("read from loopback: %m(%d)", errno); return rv; } /* * netif_set_mtu - set the MTU on the PPP network interface. */ void ppp_set_mtu(int unit, int mtu) { struct ifreq ifr; memset (&ifr, '\0', sizeof (ifr)); strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name)); ifr.ifr_mtu = mtu; if (ifunit >= 0 && ioctl(sock_fd, SIOCSIFMTU, (caddr_t) &ifr) < 0) error("ioctl(SIOCSIFMTU): %m (line %d)", __LINE__); } /* * netif_get_mtu - get the MTU on the PPP network interface. */ int ppp_get_mtu(int unit) { struct ifreq ifr; memset (&ifr, '\0', sizeof (ifr)); strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name)); if (ifunit >= 0 && ioctl(sock_fd, SIOCGIFMTU, (caddr_t) &ifr) < 0) { error("ioctl(SIOCGIFMTU): %m (line %d)", __LINE__); return 0; } return ifr.ifr_mtu; } /******************************************************************** * * tty_send_config - configure the transmit characteristics of * the ppp interface. */ void tty_send_config(int mtu, u_int32_t asyncmap, int pcomp, int accomp) { int x; if (!still_ppp()) return; link_mtu = mtu; if (ioctl(ppp_fd, PPPIOCSASYNCMAP, (caddr_t) &asyncmap) < 0) { if (errno != EIO && errno != ENOTTY) error("Couldn't set transmit async character map: %m"); ++error_count; return; } x = (pcomp? SC_COMP_PROT: 0) | (accomp? SC_COMP_AC: 0) | (ppp_sync_serial()? SC_SYNC: 0); modify_flags(ppp_fd, SC_COMP_PROT|SC_COMP_AC|SC_SYNC, x); } /******************************************************************** * * tty_set_xaccm - set the extended transmit ACCM for the interface. */ void tty_set_xaccm (ext_accm accm) { if (!still_ppp()) return; if (ioctl(ppp_fd, PPPIOCSXASYNCMAP, accm) < 0 && errno != ENOTTY) { if ( ! ok_error (errno)) warn("ioctl(set extended ACCM): %m (line %d)", __LINE__); } } /******************************************************************** * * tty_recv_config - configure the receive-side characteristics of * the ppp interface. */ void tty_recv_config(int mru, u_int32_t asyncmap, int pcomp, int accomp) { /* * If we were called because the link has gone down then there is nothing * which may be done. Just return without incident. */ if (!still_ppp()) return; /* * Set the receiver parameters */ if (ioctl(ppp_fd, PPPIOCSMRU, (caddr_t) &mru) < 0) { if (errno != EIO && errno != ENOTTY) error("Couldn't set channel receive MRU: %m"); } if (new_style_driver && ppp_dev_fd >= 0 && ioctl(ppp_dev_fd, PPPIOCSMRU, (caddr_t) &mru) < 0) error("Couldn't set MRU in generic PPP layer: %m"); if (ioctl(ppp_fd, PPPIOCSRASYNCMAP, (caddr_t) &asyncmap) < 0) { if (errno != EIO && errno != ENOTTY) error("Couldn't set channel receive asyncmap: %m"); } } /******************************************************************** * * ccp_test - ask kernel whether a given compression method * is acceptable for use. */ int ccp_test(int unit, u_char *opt_ptr, int opt_len, int for_transmit) { struct ppp_option_data data; memset (&data, '\0', sizeof (data)); data.ptr = opt_ptr; data.length = opt_len; data.transmit = for_transmit; if (ioctl(ppp_dev_fd, PPPIOCSCOMPRESS, (caddr_t) &data) >= 0) return 1; return (errno == ENOBUFS)? 0: -1; } /******************************************************************** * * ccp_flags_set - inform kernel about the current state of CCP. */ void ccp_flags_set (int unit, int isopen, int isup) { int x; x = (isopen? SC_CCP_OPEN: 0) | (isup? SC_CCP_UP: 0); if (still_ppp() && ppp_dev_fd >= 0) modify_flags(ppp_dev_fd, SC_CCP_OPEN|SC_CCP_UP, x); } #ifdef PPP_WITH_FILTER /* * set_filters - set the active and pass filters in the kernel driver. */ int set_filters(struct bpf_program *pass, struct bpf_program *active) { struct sock_fprog fp; fp.len = pass->bf_len; fp.filter = (struct sock_filter *) pass->bf_insns; if (ioctl(ppp_dev_fd, PPPIOCSPASS, &fp) < 0) { if (errno == ENOTTY) warn("kernel does not support PPP filtering"); else error("Couldn't set pass-filter in kernel: %m"); return 0; } fp.len = active->bf_len; fp.filter = (struct sock_filter *) active->bf_insns; if (ioctl(ppp_dev_fd, PPPIOCSACTIVE, &fp) < 0) { error("Couldn't set active-filter in kernel: %m"); return 0; } return 1; } #endif /* PPP_WITH_FILTER */ /******************************************************************** * * get_idle_time - return how long the link has been idle. */ int get_idle_time(int u, struct ppp_idle *ip) { return ioctl(ppp_dev_fd, PPPIOCGIDLE, ip) >= 0; } /******************************************************************** * * get_ppp_stats_iocl - return statistics for the link, using the ioctl() method, * this only supports 32-bit counters, so need to count the wraps. */ static int get_ppp_stats_ioctl(int u, struct pppd_stats *stats) { static u_int32_t previbytes = 0; static u_int32_t prevobytes = 0; static u_int32_t iwraps = 0; static u_int32_t owraps = 0; struct ifreq req; struct ppp_stats data; memset (&req, 0, sizeof (req)); req.ifr_data = (caddr_t) &data; strlcpy(req.ifr_name, ifname, sizeof(req.ifr_name)); if (ioctl(sock_fd, SIOCGPPPSTATS, &req) < 0) { error("Couldn't get PPP statistics: %m"); return 0; } stats->bytes_in = data.p.ppp_ibytes; stats->bytes_out = data.p.ppp_obytes; stats->pkts_in = data.p.ppp_ipackets; stats->pkts_out = data.p.ppp_opackets; if (stats->bytes_in < previbytes) ++iwraps; if (stats->bytes_out < prevobytes) ++owraps; previbytes = stats->bytes_in; prevobytes = stats->bytes_out; stats->bytes_in += (uint64_t)iwraps << 32; stats->bytes_out += (uint64_t)owraps << 32; return 1; } /******************************************************************** * get_ppp_stats_rtnetlink - return statistics for the link, using rtnetlink * This provides native 64-bit counters. */ static int get_ppp_stats_rtnetlink(int u, struct pppd_stats *stats) { static int fd = -1; struct { struct nlmsghdr nlh; struct if_stats_msg ifsm; } nlreq; struct { struct rtmsg rth; struct { /* We only case about these first fields from rtnl_link_stats64 */ uint64_t rx_packets; uint64_t tx_packets; uint64_t rx_bytes; uint64_t tx_bytes; } stats; } nlresp_data; size_t nlresp_size; int resp; memset(&nlreq, 0, sizeof(nlreq)); nlreq.nlh.nlmsg_len = sizeof(nlreq); nlreq.nlh.nlmsg_type = RTM_GETSTATS; nlreq.nlh.nlmsg_flags = NLM_F_REQUEST; nlreq.ifsm.ifindex = if_nametoindex(ifname); nlreq.ifsm.filter_mask = IFLA_STATS_LINK_64; nlresp_size = sizeof(nlresp_data); resp = rtnetlink_msg("RTM_GETSTATS/NLM_F_REQUEST", &fd, &nlreq, sizeof(nlreq), &nlresp_data, &nlresp_size, RTM_NEWSTATS); if (resp) { errno = (resp < 0) ? -resp : EINVAL; if (kernel_version >= KVERSION(4,7,0)) error("get_ppp_stats_rtnetlink: %m (line %d)", __LINE__); goto err; } if (nlresp_size < sizeof(nlresp_data)) { error("get_ppp_stats_rtnetlink: Obtained an insufficiently sized rtnl_link_stats64 struct from the kernel (line %d).", __LINE__); goto err; } stats->bytes_in = nlresp_data.stats.rx_bytes; stats->bytes_out = nlresp_data.stats.tx_bytes; stats->pkts_in = nlresp_data.stats.rx_packets; stats->pkts_out = nlresp_data.stats.tx_packets; return 1; err: close(fd); fd = -1; return 0; } /******************************************************************** * get_ppp_stats_sysfs - return statistics for the link, using the files in sysfs, * this provides native 64-bit counters. */ static int get_ppp_stats_sysfs(int u, struct pppd_stats *stats) { char fname[PATH_MAX+1]; char buf[21], *err; /* 2^64 < 10^20 */ int blen, fd, rlen; unsigned long long val; struct { const char* fname; void* ptr; unsigned size; } slist[] = { #define statfield(fn, field) { .fname = #fn, .ptr = &stats->field, .size = sizeof(stats->field) } statfield(rx_bytes, bytes_in), statfield(tx_bytes, bytes_out), statfield(rx_packets, pkts_in), statfield(tx_packets, pkts_out), #undef statfield }; blen = snprintf(fname, sizeof(fname), "/sys/class/net/%s/statistics/", ifname); if (blen >= sizeof(fname)) return 0; /* ifname max 15, so this should be impossible */ for (int i = 0; i < sizeof(slist) / sizeof(*slist); ++i) { if (snprintf(fname + blen, sizeof(fname) - blen, "%s", slist[i].fname) >= sizeof(fname) - blen) { fname[blen] = 0; error("sysfs stats: filename %s/%s overflowed PATH_MAX", fname, slist[i].fname); return 0; } fd = open(fname, O_RDONLY); if (fd < 0) { error("%s: %m", fname); return 0; } rlen = read(fd, buf, sizeof(buf) - 1); close(fd); if (rlen < 0) { error("%s: %m", fname); return 0; } /* trim trailing \n if present */ while (rlen > 0 && buf[rlen-1] == '\n') rlen--; buf[rlen] = 0; errno = 0; val = strtoull(buf, &err, 10); if (*buf < '0' || *buf > '9' || errno != 0 || *err) { error("string to number conversion error converting %s (from %s) for remaining string %s%s%s", buf, fname, err, errno ? ": " : "", errno ? strerror(errno) : ""); return 0; } switch (slist[i].size) { #define stattype(type) case sizeof(type): *(type*)slist[i].ptr = (type)val; break stattype(uint64_t); stattype(uint32_t); stattype(uint16_t); stattype(uint8_t); #undef stattype default: error("Don't know how to store stats for %s of size %u", slist[i].fname, slist[i].size); return 0; } } return 1; } /******************************************************************** * Periodic timer function to be used to keep stats up to date in case of ioctl * polling. * * Given the 25s interval this should be fine up to data rates of 1.37Gbps. * If you do change the timer, remember to also bring the get_ppp_stats (which * sets up the initial trigger) as well. */ static void ppp_stats_poller(void* u) { struct pppd_stats dummy; get_ppp_stats_ioctl((long)u, &dummy); TIMEOUT(ppp_stats_poller, u, 25); } /******************************************************************** * get_ppp_stats - return statistics for the link. */ int get_ppp_stats(int u, struct pppd_stats *stats) { static int (*func)(int, struct pppd_stats*) = NULL; if (!func) { if (get_ppp_stats_rtnetlink(u, stats)) { func = get_ppp_stats_rtnetlink; return 1; } if (get_ppp_stats_sysfs(u, stats)) { func = get_ppp_stats_sysfs; return 1; } warn("statistics falling back to ioctl which only supports 32-bit counters"); func = get_ppp_stats_ioctl; TIMEOUT(ppp_stats_poller, (void*)(long)u, 25); } return func(u, stats); } /******************************************************************** * * ccp_fatal_error - returns 1 if decompression was disabled as a * result of an error detected after decompression of a packet, * 0 otherwise. This is necessary because of patent nonsense. */ int ccp_fatal_error (int unit) { int flags; if (ioctl(ppp_dev_fd, PPPIOCGFLAGS, &flags) < 0) { error("Couldn't read compression error flags: %m"); flags = 0; } return flags & SC_DC_FERROR; } /******************************************************************** * * path_to_procfs - find the path to the proc file system mount point */ static char proc_path[MAXPATHLEN]; static int proc_path_len; static char *path_to_procfs(const char *tail) { struct mntent *mntent; FILE *fp; if (proc_path_len == 0) { /* Default the mount location of /proc */ strlcpy (proc_path, "/proc", sizeof(proc_path)); proc_path_len = 5; fp = fopen(MOUNTED, "r"); if (fp != NULL) { while ((mntent = getmntent(fp)) != NULL) { if (strcmp(mntent->mnt_type, MNTTYPE_IGNORE) == 0) continue; if (strcmp(mntent->mnt_type, "proc") == 0) { strlcpy(proc_path, mntent->mnt_dir, sizeof(proc_path)); proc_path_len = strlen(proc_path); break; } } fclose (fp); } } strlcpy(proc_path + proc_path_len, tail, sizeof(proc_path) - proc_path_len); return proc_path; } /* * /proc/net/route parsing stuff. */ #define ROUTE_MAX_COLS 12 FILE *route_fd = (FILE *) 0; static char route_buffer[512]; static int route_dev_col, route_dest_col, route_gw_col; static int route_flags_col, route_metric_col, route_mask_col; static int route_num_cols; static int open_route_table (void); static void close_route_table (void); static int read_route_table (struct rtentry *rt); /******************************************************************** * * close_route_table - close the interface to the route table */ static void close_route_table (void) { if (route_fd != (FILE *) 0) { fclose (route_fd); route_fd = (FILE *) 0; } } /******************************************************************** * * open_route_table - open the interface to the route table */ static char route_delims[] = " \t\n"; static int open_route_table (void) { char *path; close_route_table(); path = path_to_procfs("/net/route"); route_fd = fopen (path, "r"); if (route_fd == NULL) { error("can't open routing table %s: %m", path); return 0; } route_dev_col = 0; /* default to usual columns */ route_dest_col = 1; route_gw_col = 2; route_flags_col = 3; route_metric_col = 6; route_mask_col = 7; route_num_cols = 8; /* parse header line */ if (fgets(route_buffer, sizeof(route_buffer), route_fd) != 0) { char *p = route_buffer, *q; int col; for (col = 0; col < ROUTE_MAX_COLS; ++col) { int used = 1; if ((q = strtok(p, route_delims)) == 0) break; if (strcasecmp(q, "iface") == 0) route_dev_col = col; else if (strcasecmp(q, "destination") == 0) route_dest_col = col; else if (strcasecmp(q, "gateway") == 0) route_gw_col = col; else if (strcasecmp(q, "flags") == 0) route_flags_col = col; else if (strcasecmp(q, "mask") == 0) route_mask_col = col; else used = 0; if (used && col >= route_num_cols) route_num_cols = col + 1; p = NULL; } } return 1; } /******************************************************************** * * read_route_table - read the next entry from the route table */ static int read_route_table(struct rtentry *rt) { char *cols[ROUTE_MAX_COLS], *p; int col; memset (rt, '\0', sizeof (struct rtentry)); if (fgets (route_buffer, sizeof (route_buffer), route_fd) == (char *) 0) return 0; p = route_buffer; for (col = 0; col < route_num_cols; ++col) { cols[col] = strtok(p, route_delims); if (cols[col] == NULL) return 0; /* didn't get enough columns */ p = NULL; } SET_SA_FAMILY (rt->rt_dst, AF_INET); SET_SA_FAMILY (rt->rt_gateway, AF_INET); SIN_ADDR(rt->rt_dst) = strtoul(cols[route_dest_col], NULL, 16); SIN_ADDR(rt->rt_gateway) = strtoul(cols[route_gw_col], NULL, 16); SIN_ADDR(rt->rt_genmask) = strtoul(cols[route_mask_col], NULL, 16); rt->rt_flags = (short) strtoul(cols[route_flags_col], NULL, 16); rt->rt_metric = (short) strtoul(cols[route_metric_col], NULL, 10); rt->rt_dev = cols[route_dev_col]; return 1; } /******************************************************************** * * defaultroute_exists - determine if there is a default route * with the given metric (or negative for any) */ static int defaultroute_exists (struct rtentry *rt, int metric) { int result = 0; if (!open_route_table()) return 0; while (read_route_table(rt) != 0) { if ((rt->rt_flags & RTF_UP) == 0) continue; if (kernel_version > KVERSION(2,1,0) && SIN_ADDR(rt->rt_genmask) != 0) continue; if (SIN_ADDR(rt->rt_dst) == 0L && (metric < 0 || rt->rt_metric == metric)) { result = 1; break; } } close_route_table(); return result; } /* * have_route_to - determine if the system has any route to * a given IP address. `addr' is in network byte order. * Return value is 1 if yes, 0 if no, -1 if don't know. * For demand mode to work properly, we have to ignore routes * through our own interface. */ int have_route_to(u_int32_t addr) { struct rtentry rt; int result = 0; if (!open_route_table()) return -1; /* don't know */ while (read_route_table(&rt)) { if ((rt.rt_flags & RTF_UP) == 0 || strcmp(rt.rt_dev, ifname) == 0) continue; if ((addr & SIN_ADDR(rt.rt_genmask)) == SIN_ADDR(rt.rt_dst)) { result = 1; break; } } close_route_table(); return result; } /******************************************************************** * * sifdefaultroute - assign a default route through the address given. * * If the global default_rt_repl_rest flag is set, then this function * already replaced the original system defaultroute with some other * route and it should just replace the current defaultroute with * another one, without saving the current route. Use: demand mode, * when pppd sets first a defaultroute it it's temporary ppp0 addresses * and then changes the temporary addresses to the addresses for the real * ppp connection when it has come up. */ int sifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway, bool replace) { struct rtentry rt, tmp_rt; struct rtentry *del_rt = NULL; if (default_rt_repl_rest) { /* We have already replaced the original defaultroute, if we * are called again, we will delete the current default route * and set the new default route in this function. * - this is normally only the case the doing demand: */ if (defaultroute_exists(&tmp_rt, -1)) del_rt = &tmp_rt; } else if (defaultroute_exists(&old_def_rt, -1 ) && strcmp( old_def_rt.rt_dev, ifname) != 0) { /* * We did not yet replace an existing default route, let's * check if we should save and replace a default route: */ u_int32_t old_gateway = SIN_ADDR(old_def_rt.rt_gateway); if (old_gateway != gateway) { if (!replace) { error("not replacing default route to %s [%I]", old_def_rt.rt_dev, old_gateway); return 0; } else { /* we need to copy rt_dev because we need it permanent too: */ char * tmp_dev = malloc(strlen(old_def_rt.rt_dev)+1); strcpy(tmp_dev, old_def_rt.rt_dev); old_def_rt.rt_dev = tmp_dev; notice("replacing old default route to %s [%I]", old_def_rt.rt_dev, old_gateway); default_rt_repl_rest = 1; del_rt = &old_def_rt; } } } memset (&rt, 0, sizeof (rt)); SET_SA_FAMILY (rt.rt_dst, AF_INET); rt.rt_dev = ifname; rt.rt_metric = dfl_route_metric + 1; /* +1 for binary compatibility */ if (kernel_version > KVERSION(2,1,0)) { SET_SA_FAMILY (rt.rt_genmask, AF_INET); SIN_ADDR(rt.rt_genmask) = 0L; } rt.rt_flags = RTF_UP; if (ioctl(sock_fd, SIOCADDRT, &rt) < 0) { if ( ! ok_error ( errno )) error("default route ioctl(SIOCADDRT): %m"); return 0; } if (default_rt_repl_rest && del_rt) if (ioctl(sock_fd, SIOCDELRT, del_rt) < 0) { if ( ! ok_error ( errno )) error("del old default route ioctl(SIOCDELRT): %m(%d)", errno); return 0; } have_default_route = 1; return 1; } /******************************************************************** * * cifdefaultroute - delete a default route through the address given. */ int cifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway) { struct rtentry rt; have_default_route = 0; memset (&rt, '\0', sizeof (rt)); SET_SA_FAMILY (rt.rt_dst, AF_INET); SET_SA_FAMILY (rt.rt_gateway, AF_INET); rt.rt_dev = ifname; rt.rt_dev = ifname; rt.rt_metric = dfl_route_metric + 1; /* +1 for binary compatibility */ if (kernel_version > KVERSION(2,1,0)) { SET_SA_FAMILY (rt.rt_genmask, AF_INET); SIN_ADDR(rt.rt_genmask) = 0L; } rt.rt_flags = RTF_UP; if (ioctl(sock_fd, SIOCDELRT, &rt) < 0 && errno != ESRCH) { if (still_ppp()) { if ( ! ok_error ( errno )) error("default route ioctl(SIOCDELRT): %m"); return 0; } } if (default_rt_repl_rest) { notice("restoring old default route to %s [%I]", old_def_rt.rt_dev, SIN_ADDR(old_def_rt.rt_gateway)); if (ioctl(sock_fd, SIOCADDRT, &old_def_rt) < 0) { if ( ! ok_error ( errno )) error("restore default route ioctl(SIOCADDRT): %m(%d)", errno); return 0; } default_rt_repl_rest = 0; } return 1; } #ifdef PPP_WITH_IPV6CP /* * /proc/net/ipv6_route parsing stuff. */ static int route_dest_plen_col; static int open_route6_table (void); static int read_route6_table (struct in6_rtmsg *rt); /******************************************************************** * * open_route6_table - open the interface to the route table */ static int open_route6_table (void) { char *path; close_route_table(); path = path_to_procfs("/net/ipv6_route"); route_fd = fopen (path, "r"); if (route_fd == NULL) { error("can't open routing table %s: %m", path); return 0; } /* default to usual columns */ route_dest_col = 0; route_dest_plen_col = 1; route_gw_col = 4; route_metric_col = 5; route_flags_col = 8; route_dev_col = 9; route_num_cols = 10; return 1; } /******************************************************************** * * read_route6_table - read the next entry from the route table */ static void hex_to_in6_addr(struct in6_addr *addr, const char *s) { char hex8[9]; unsigned i; uint32_t v; hex8[8] = 0; for (i = 0; i < 4; i++) { memcpy(hex8, s + 8*i, 8); v = strtoul(hex8, NULL, 16); addr->s6_addr32[i] = v; } } static int read_route6_table(struct in6_rtmsg *rt) { char *cols[ROUTE_MAX_COLS], *p; int col; memset (rt, '\0', sizeof (struct in6_rtmsg)); if (fgets (route_buffer, sizeof (route_buffer), route_fd) == (char *) 0) return 0; p = route_buffer; for (col = 0; col < route_num_cols; ++col) { cols[col] = strtok(p, route_delims); if (cols[col] == NULL) return 0; /* didn't get enough columns */ p = NULL; } hex_to_in6_addr(&rt->rtmsg_dst, cols[route_dest_col]); rt->rtmsg_dst_len = strtoul(cols[route_dest_plen_col], NULL, 16); hex_to_in6_addr(&rt->rtmsg_gateway, cols[route_gw_col]); rt->rtmsg_metric = strtoul(cols[route_metric_col], NULL, 16); rt->rtmsg_flags = strtoul(cols[route_flags_col], NULL, 16); rt->rtmsg_ifindex = if_nametoindex(cols[route_dev_col]); return 1; } /******************************************************************** * * defaultroute6_exists - determine if there is a default route */ static int defaultroute6_exists (struct in6_rtmsg *rt, int metric) { int result = 0; if (!open_route6_table()) return 0; while (read_route6_table(rt) != 0) { if ((rt->rtmsg_flags & RTF_UP) == 0) continue; if (rt->rtmsg_dst_len != 0) continue; if (rt->rtmsg_dst.s6_addr32[0] == 0L && rt->rtmsg_dst.s6_addr32[1] == 0L && rt->rtmsg_dst.s6_addr32[2] == 0L && rt->rtmsg_dst.s6_addr32[3] == 0L && (metric < 0 || rt->rtmsg_metric == metric)) { result = 1; break; } } close_route_table(); return result; } /******************************************************************** * * sif6defaultroute - assign a default route through the address given. * * If the global default_rt_repl_rest flag is set, then this function * already replaced the original system defaultroute with some other * route and it should just replace the current defaultroute with * another one, without saving the current route. Use: demand mode, * when pppd sets first a defaultroute it it's temporary ppp0 addresses * and then changes the temporary addresses to the addresses for the real * ppp connection when it has come up. */ int sif6defaultroute (int unit, eui64_t ouraddr, eui64_t gateway) { struct in6_rtmsg rt; char buf[IF_NAMESIZE]; if (defaultroute6_exists(&rt, dfl_route_metric) && rt.rtmsg_ifindex != if_nametoindex(ifname)) { if (rt.rtmsg_flags & RTF_GATEWAY) error("not replacing existing default route via gateway"); else error("not replacing existing default route through %s", if_indextoname(rt.rtmsg_ifindex, buf)); return 0; } memset (&rt, 0, sizeof (rt)); rt.rtmsg_ifindex = if_nametoindex(ifname); rt.rtmsg_metric = dfl_route_metric + 1; /* +1 for binary compatibility */ rt.rtmsg_dst_len = 0; rt.rtmsg_flags = RTF_UP; if (ioctl(sock6_fd, SIOCADDRT, &rt) < 0) { if ( ! ok_error ( errno )) error("default route ioctl(SIOCADDRT): %m"); return 0; } have_default_route6 = 1; return 1; } /******************************************************************** * * cif6defaultroute - delete a default route through the address given. */ int cif6defaultroute (int unit, eui64_t ouraddr, eui64_t gateway) { struct in6_rtmsg rt; have_default_route6 = 0; memset (&rt, '\0', sizeof (rt)); rt.rtmsg_ifindex = if_nametoindex(ifname); rt.rtmsg_metric = dfl_route_metric + 1; /* +1 for binary compatibility */ rt.rtmsg_dst_len = 0; rt.rtmsg_flags = RTF_UP; if (ioctl(sock6_fd, SIOCDELRT, &rt) < 0 && errno != ESRCH) { if (still_ppp()) { if ( ! ok_error ( errno )) error("default route ioctl(SIOCDELRT): %m"); return 0; } } return 1; } #endif /* PPP_WITH_IPV6CP */ /******************************************************************** * * sifproxyarp - Make a proxy ARP entry for the peer. */ int sifproxyarp (int unit, u_int32_t his_adr) { struct arpreq arpreq; char *forw_path; if (has_proxy_arp == 0) { memset (&arpreq, '\0', sizeof(arpreq)); SET_SA_FAMILY(arpreq.arp_pa, AF_INET); SIN_ADDR(arpreq.arp_pa) = his_adr; arpreq.arp_flags = ATF_PERM | ATF_PUBL; /* * Get the hardware address of an interface on the same subnet * as our local address. */ if (!get_ether_addr(his_adr, &arpreq.arp_ha, proxy_arp_dev, sizeof(proxy_arp_dev))) { error("Cannot determine ethernet address for proxy ARP"); return 0; } strlcpy(arpreq.arp_dev, proxy_arp_dev, sizeof(arpreq.arp_dev)); if (ioctl(sock_fd, SIOCSARP, (caddr_t)&arpreq) < 0) { if ( ! ok_error ( errno )) error("ioctl(SIOCSARP): %m"); return 0; } proxy_arp_addr = his_adr; has_proxy_arp = 1; if (tune_kernel) { forw_path = path_to_procfs("/sys/net/ipv4/ip_forward"); if (forw_path != 0) { int fd = open(forw_path, O_WRONLY); if (fd >= 0) { if (write(fd, "1", 1) != 1) error("Couldn't enable IP forwarding: %m"); close(fd); } } } } return 1; } /******************************************************************** * * cifproxyarp - Delete the proxy ARP entry for the peer. */ int cifproxyarp (int unit, u_int32_t his_adr) { struct arpreq arpreq; if (has_proxy_arp) { has_proxy_arp = 0; memset (&arpreq, '\0', sizeof(arpreq)); SET_SA_FAMILY(arpreq.arp_pa, AF_INET); SIN_ADDR(arpreq.arp_pa) = his_adr; arpreq.arp_flags = ATF_PERM | ATF_PUBL; strlcpy(arpreq.arp_dev, proxy_arp_dev, sizeof(arpreq.arp_dev)); if (ioctl(sock_fd, SIOCDARP, (caddr_t)&arpreq) < 0) { if ( ! ok_error ( errno )) warn("ioctl(SIOCDARP): %m"); return 0; } } return 1; } /******************************************************************** * * get_ether_addr - get the hardware address of an interface on the * the same subnet as ipaddr. */ static int get_ether_addr (u_int32_t ipaddr, struct sockaddr *hwaddr, char *name, int namelen) { struct ifreq *ifr, *ifend; u_int32_t ina, mask; char *aliasp; struct ifreq ifreq, bestifreq; struct ifconf ifc; struct ifreq ifs[MAX_IFS]; u_int32_t bestmask=0; int found_interface = 0; ifc.ifc_len = sizeof(ifs); ifc.ifc_req = ifs; if (ioctl(sock_fd, SIOCGIFCONF, &ifc) < 0) { if ( ! ok_error ( errno )) error("ioctl(SIOCGIFCONF): %m (line %d)", __LINE__); return 0; } /* * Scan through looking for an interface with an Internet * address on the same subnet as `ipaddr'. */ ifend = ifs + (ifc.ifc_len / sizeof(struct ifreq)); for (ifr = ifc.ifc_req; ifr < ifend; ifr++) { if (ifr->ifr_addr.sa_family == AF_INET) { ina = SIN_ADDR(ifr->ifr_addr); strlcpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name)); /* * Check that the interface is up, and not point-to-point * nor loopback. */ if (ioctl(sock_fd, SIOCGIFFLAGS, &ifreq) < 0) continue; if (((ifreq.ifr_flags ^ FLAGS_GOOD) & FLAGS_MASK) != 0) continue; /* * Get its netmask and check that it's on the right subnet. */ if (ioctl(sock_fd, SIOCGIFNETMASK, &ifreq) < 0) continue; mask = SIN_ADDR(ifreq.ifr_addr); if (((ipaddr ^ ina) & mask) != 0) continue; /* no match */ /* matched */ if (mask >= bestmask) { /* Compare using >= instead of > -- it is possible for an interface to have a netmask of 0.0.0.0 */ found_interface = 1; bestifreq = ifreq; bestmask = mask; } } } if (!found_interface) return 0; strlcpy(name, bestifreq.ifr_name, namelen); /* trim off the :1 in eth0:1 */ aliasp = strchr(name, ':'); if (aliasp != 0) *aliasp = 0; info("found interface %s for proxy arp", name); /* * Now get the hardware address. */ memset (&bestifreq.ifr_hwaddr, 0, sizeof (struct sockaddr)); if (ioctl (sock_fd, SIOCGIFHWADDR, &bestifreq) < 0) { error("SIOCGIFHWADDR(%s): %m", bestifreq.ifr_name); return 0; } memcpy (hwaddr, &bestifreq.ifr_hwaddr, sizeof (struct sockaddr)); return 1; } /* * get_if_hwaddr - get the hardware address for the specified * network interface device. */ int get_if_hwaddr(u_char *addr, char *name) { struct ifreq ifreq; int ret, sock_fd; sock_fd = socket(AF_INET, SOCK_DGRAM, 0); if (sock_fd < 0) return -1; memset(&ifreq.ifr_hwaddr, 0, sizeof(struct sockaddr)); strlcpy(ifreq.ifr_name, name, sizeof(ifreq.ifr_name)); ret = ioctl(sock_fd, SIOCGIFHWADDR, &ifreq); close(sock_fd); if (ret >= 0) memcpy(addr, ifreq.ifr_hwaddr.sa_data, 6); return ret; } /* * get_first_ether_hwaddr - get the hardware address for the first * ethernet-style interface on this system. */ int get_first_ether_hwaddr(u_char *addr) { struct if_nameindex *if_ni, *i; struct ifreq ifreq; int ret, sock_fd; sock_fd = socket(AF_INET, SOCK_DGRAM, 0); if (sock_fd < 0) return -1; if_ni = if_nameindex(); if (!if_ni) { close(sock_fd); return -1; } ret = -1; for (i = if_ni; !(i->if_index == 0 && i->if_name == NULL); i++) { memset(&ifreq.ifr_hwaddr, 0, sizeof(struct sockaddr)); strlcpy(ifreq.ifr_name, i->if_name, sizeof(ifreq.ifr_name)); ret = ioctl(sock_fd, SIOCGIFHWADDR, &ifreq); if (ret >= 0 && ifreq.ifr_hwaddr.sa_family == ARPHRD_ETHER) { memcpy(addr, ifreq.ifr_hwaddr.sa_data, 6); break; } ret = -1; } if_freenameindex(if_ni); close(sock_fd); return ret; } /******************************************************************** * * Return user specified netmask, modified by any mask we might determine * for address `addr' (in network byte order). * Here we scan through the system's list of interfaces, looking for * any non-point-to-point interfaces which might appear to be on the same * network as `addr'. If we find any, we OR in their netmask to the * user-specified netmask. */ u_int32_t GetMask (u_int32_t addr) { u_int32_t mask, nmask, ina; struct ifreq *ifr, *ifend, ifreq; struct ifconf ifc; struct ifreq ifs[MAX_IFS]; addr = ntohl(addr); if (IN_CLASSA(addr)) /* determine network mask for address class */ nmask = IN_CLASSA_NET; else if (IN_CLASSB(addr)) nmask = IN_CLASSB_NET; else nmask = IN_CLASSC_NET; /* class D nets are disallowed by bad_ip_adrs */ mask = netmask | htonl(nmask); /* * Scan through the system's network interfaces. */ ifc.ifc_len = sizeof(ifs); ifc.ifc_req = ifs; if (ioctl(sock_fd, SIOCGIFCONF, &ifc) < 0) { if ( ! ok_error ( errno )) warn("ioctl(SIOCGIFCONF): %m (line %d)", __LINE__); return mask; } ifend = (struct ifreq *) (ifc.ifc_buf + ifc.ifc_len); for (ifr = ifc.ifc_req; ifr < ifend; ifr++) { /* * Check the interface's internet address. */ if (ifr->ifr_addr.sa_family != AF_INET) continue; ina = SIN_ADDR(ifr->ifr_addr); if (((ntohl(ina) ^ addr) & nmask) != 0) continue; /* * Check that the interface is up, and not point-to-point nor loopback. */ strlcpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name)); if (ioctl(sock_fd, SIOCGIFFLAGS, &ifreq) < 0) continue; if (((ifreq.ifr_flags ^ FLAGS_GOOD) & FLAGS_MASK) != 0) continue; /* * Get its netmask and OR it into our mask. */ if (ioctl(sock_fd, SIOCGIFNETMASK, &ifreq) < 0) continue; mask |= SIN_ADDR(ifreq.ifr_addr); break; } return mask; } /******************************************************************** * * Internal routine to decode the version.modification.patch level */ static void decode_version (char *buf, int *version, int *modification, int *patch) { char *endp; *version = (int) strtoul (buf, &endp, 10); *modification = 0; *patch = 0; if (endp != buf && *endp == '.') { buf = endp + 1; *modification = (int) strtoul (buf, &endp, 10); if (endp != buf && *endp == '.') { buf = endp + 1; *patch = (int) strtoul (buf, &buf, 10); } } } /******************************************************************** * * Procedure to determine if the PPP line discipline is registered. */ static int ppp_registered(void) { int local_fd; int mfd = -1; int ret = 0; char slave[16]; /* * We used to open the serial device and set it to the ppp line * discipline here, in order to create a ppp unit. But that is * not a good idea - the user might have specified a device that * they can't open (permission, or maybe it doesn't really exist). * So we grab a pty master/slave pair and use that. */ if (!get_pty(&mfd, &local_fd, slave, 0)) { no_ppp_msg = "Couldn't determine if PPP is supported (no free ptys)"; return 0; } /* * Try to put the device into the PPP discipline. */ if (ioctl(local_fd, TIOCSETD, &ppp_disc) < 0) { error("ioctl(TIOCSETD(PPP)): %m (line %d)", __LINE__); } else ret = 1; close(local_fd); close(mfd); return ret; } /******************************************************************** * * ppp_check_kernel_support - check whether the system has any ppp interfaces * (in fact we check whether we can do an ioctl on ppp0). */ int ppp_check_kernel_support(void) { int s, ok, fd; struct ifreq ifr; int size; int my_version, my_modification, my_patch; int osmaj, osmin, ospatch; /* get the kernel version now, since we are called before sys_init */ uname(&utsname); osmaj = osmin = ospatch = 0; sscanf(utsname.release, "%d.%d.%d", &osmaj, &osmin, &ospatch); kernel_version = KVERSION(osmaj, osmin, ospatch); fd = open("/dev/ppp", O_RDWR); if (fd >= 0) { new_style_driver = 1; /* XXX should get from driver */ driver_version = 2; driver_modification = 4; driver_patch = 0; close(fd); return 1; } if (kernel_version >= KVERSION(2,3,13)) { error("Couldn't open the /dev/ppp device: %m"); if (errno == ENOENT) no_ppp_msg = "You need to create the /dev/ppp device node by\n" "executing the following command as root:\n" " mknod /dev/ppp c 108 0\n"; else if (errno == ENODEV || errno == ENXIO) no_ppp_msg = "Please load the ppp_generic kernel module.\n"; return 0; } /* we are running on a really really old kernel */ no_ppp_msg = "This system lacks kernel support for PPP. This could be because\n" "the PPP kernel module could not be loaded, or because PPP was not\n" "included in the kernel configuration. If PPP was included as a\n" "module, try `/sbin/modprobe -v ppp'. If that fails, check that\n" "ppp.o exists in /lib/modules/`uname -r`/net.\n" "See README.linux file in the ppp distribution for more details.\n"; /* * Open a socket for doing the ioctl operations. */ s = socket(AF_INET, SOCK_DGRAM, 0); if (s < 0) return 0; strlcpy (ifr.ifr_name, "ppp0", sizeof (ifr.ifr_name)); ok = ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) >= 0; /* * If the device did not exist then attempt to create one by putting the * current tty into the PPP discipline. If this works then obtain the * flags for the device again. */ if (!ok) { if (ppp_registered()) { strlcpy (ifr.ifr_name, "ppp0", sizeof (ifr.ifr_name)); ok = ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) >= 0; } } /* * Ensure that the hardware address is for PPP and not something else */ if (ok) ok = ioctl (s, SIOCGIFHWADDR, (caddr_t) &ifr) >= 0; if (ok && ((ifr.ifr_hwaddr.sa_family & ~0xFF) != ARPHRD_PPP)) ok = 0; /* * This is the PPP device. Validate the version of the driver at this * point to ensure that this program will work with the driver. */ if (ok) { char abBuffer [1024]; ifr.ifr_data = abBuffer; size = ioctl (s, SIOCGPPPVER, (caddr_t) &ifr); if (size < 0) { error("Couldn't read driver version: %m"); ok = 0; no_ppp_msg = "Sorry, couldn't verify kernel driver version\n"; } else { decode_version(abBuffer, &driver_version, &driver_modification, &driver_patch); /* * Validate the version of the driver against the version that we used. */ decode_version(VERSION, &my_version, &my_modification, &my_patch); /* The version numbers must match */ if (driver_version != my_version) ok = 0; /* The modification levels must be legal */ if (driver_modification < 3) { if (driver_modification >= 2) { /* we can cope with 2.2.0 and above */ driver_is_old = 1; } else { ok = 0; } } if (!ok) { slprintf(route_buffer, sizeof(route_buffer), "Sorry - PPP driver version %d.%d.%d is out of date\n", driver_version, driver_modification, driver_patch); no_ppp_msg = route_buffer; } } } close(s); return ok; } #ifndef HAVE_LOGWTMP /******************************************************************** * * Update the wtmp file with the appropriate user name and tty device. */ void logwtmp (const char *line, const char *name, const char *host) { struct utmp ut, *utp; pid_t mypid = getpid(); #if __GLIBC__ < 2 int wtmp; #endif /* * Update the signon database for users. * Christoph Lameter: Copied from poeigl-1.36 Jan 3, 1996 */ utmpname(_PATH_UTMP); setutent(); while ((utp = getutent()) && (utp->ut_pid != mypid)) /* nothing */; if (utp) memcpy(&ut, utp, sizeof(ut)); else /* some gettys/telnetds don't initialize utmp... */ memset(&ut, 0, sizeof(ut)); if (ut.ut_id[0] == 0) strncpy(ut.ut_id, line + 3, sizeof(ut.ut_id)); strncpy(ut.ut_user, name, sizeof(ut.ut_user)); strncpy(ut.ut_line, line, sizeof(ut.ut_line)); time(&ut.ut_time); ut.ut_type = USER_PROCESS; ut.ut_pid = mypid; /* Insert the host name if one is supplied */ if (*host) strncpy (ut.ut_host, host, sizeof(ut.ut_host)); /* Insert the IP address of the remote system if IP is enabled */ if (ipcp_protent.enabled_flag && ipcp_hisoptions[0].neg_addr) memcpy(&ut.ut_addr, (char *) &ipcp_hisoptions[0].hisaddr, sizeof(ut.ut_addr)); /* CL: Makes sure that the logout works */ if (*host == 0 && *name==0) ut.ut_host[0]=0; pututline(&ut); endutent(); /* * Update the wtmp file. */ #if __GLIBC__ >= 2 updwtmp(_PATH_WTMP, &ut); #else wtmp = open(_PATH_WTMP, O_APPEND|O_WRONLY); if (wtmp >= 0) { flock(wtmp, LOCK_EX); if (write (wtmp, (char *)&ut, sizeof(ut)) != sizeof(ut)) warn("error writing %s: %m", _PATH_WTMP); flock(wtmp, LOCK_UN); close (wtmp); } #endif } #endif /* HAVE_LOGWTMP */ /******************************************************************** * * sifvjcomp - config tcp header compression */ int sifvjcomp (int u, int vjcomp, int cidcomp, int maxcid) { u_int x; if (vjcomp) { if (ioctl(ppp_dev_fd, PPPIOCSMAXCID, (caddr_t) &maxcid) < 0) { error("Couldn't set up TCP header compression: %m"); vjcomp = 0; } } x = (vjcomp? SC_COMP_TCP: 0) | (cidcomp? 0: SC_NO_TCP_CCID); modify_flags(ppp_dev_fd, SC_COMP_TCP|SC_NO_TCP_CCID, x); return 1; } /******************************************************************** * * sifup - Config the interface up and enable IP packets to pass. */ int sifup(int u) { int ret; if ((ret = setifstate(u, 1))) if_is_up++; return ret; } /******************************************************************** * * sifdown - Disable the indicated protocol and config the interface * down if there are no remaining protocols. */ int sifdown (int u) { if (if_is_up && --if_is_up > 0) return 1; #ifdef PPP_WITH_IPV6CP if (if6_is_up) return 1; #endif /* PPP_WITH_IPV6CP */ return setifstate(u, 0); } #ifdef PPP_WITH_IPV6CP /******************************************************************** * * sif6up - Config the interface up for IPv6 */ int sif6up(int u) { int ret; if ((ret = setifstate(u, 1))) if6_is_up = 1; return ret; } /******************************************************************** * * sif6down - Disable the IPv6CP protocol and config the interface * down if there are no remaining protocols. */ int sif6down (int u) { if6_is_up = 0; if (if_is_up) return 1; return setifstate(u, 0); } #endif /* PPP_WITH_IPV6CP */ /******************************************************************** * * setifstate - Config the interface up or down */ static int setifstate (int u, int state) { struct ifreq ifr; memset (&ifr, '\0', sizeof (ifr)); strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name)); if (ioctl(sock_fd, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) { if (! ok_error (errno)) error("ioctl (SIOCGIFFLAGS): %m (line %d)", __LINE__); return 0; } if (state) ifr.ifr_flags |= IFF_UP; else ifr.ifr_flags &= ~IFF_UP; ifr.ifr_flags |= IFF_POINTOPOINT; if (ioctl(sock_fd, SIOCSIFFLAGS, (caddr_t) &ifr) < 0) { if (! ok_error (errno)) error("ioctl(SIOCSIFFLAGS): %m (line %d)", __LINE__); return 0; } return 1; } /******************************************************************** * * sifaddr - Config the interface IP addresses and netmask. */ int sifaddr (int unit, u_int32_t our_adr, u_int32_t his_adr, u_int32_t net_mask) { struct ifreq ifr; struct rtentry rt; memset (&ifr, '\0', sizeof (ifr)); memset (&rt, '\0', sizeof (rt)); SET_SA_FAMILY (ifr.ifr_addr, AF_INET); SET_SA_FAMILY (ifr.ifr_dstaddr, AF_INET); SET_SA_FAMILY (ifr.ifr_netmask, AF_INET); strlcpy (ifr.ifr_name, ifname, sizeof (ifr.ifr_name)); /* * Set our IP address */ SIN_ADDR(ifr.ifr_addr) = our_adr; if (ioctl(sock_fd, SIOCSIFADDR, (caddr_t) &ifr) < 0) { if (errno != EEXIST) { if (! ok_error (errno)) error("ioctl(SIOCSIFADDR): %m (line %d)", __LINE__); } else { warn("ioctl(SIOCSIFADDR): Address already exists"); } return (0); } /* * Set the gateway address */ if (his_adr != 0) { SIN_ADDR(ifr.ifr_dstaddr) = his_adr; if (ioctl(sock_fd, SIOCSIFDSTADDR, (caddr_t) &ifr) < 0) { if (! ok_error (errno)) error("ioctl(SIOCSIFDSTADDR): %m (line %d)", __LINE__); return (0); } } /* * Set the netmask. * For recent kernels, force the netmask to 255.255.255.255. */ if (kernel_version >= KVERSION(2,1,16)) net_mask = ~0L; if (net_mask != 0) { SIN_ADDR(ifr.ifr_netmask) = net_mask; if (ioctl(sock_fd, SIOCSIFNETMASK, (caddr_t) &ifr) < 0) { if (! ok_error (errno)) error("ioctl(SIOCSIFNETMASK): %m (line %d)", __LINE__); return (0); } } /* * Add the device route */ if (kernel_version < KVERSION(2,1,16)) { SET_SA_FAMILY (rt.rt_dst, AF_INET); SET_SA_FAMILY (rt.rt_gateway, AF_INET); rt.rt_dev = ifname; SIN_ADDR(rt.rt_gateway) = 0L; SIN_ADDR(rt.rt_dst) = his_adr; rt.rt_flags = RTF_UP | RTF_HOST; if (kernel_version > KVERSION(2,1,0)) { SET_SA_FAMILY (rt.rt_genmask, AF_INET); SIN_ADDR(rt.rt_genmask) = -1L; } if (ioctl(sock_fd, SIOCADDRT, &rt) < 0) { if (! ok_error (errno)) error("ioctl(SIOCADDRT) device route: %m (line %d)", __LINE__); return (0); } } /* set ip_dynaddr in demand mode if address changes */ if (demand && tune_kernel && !dynaddr_set && our_old_addr && our_old_addr != our_adr) { /* set ip_dynaddr if possible */ char *path; int fd; path = path_to_procfs("/sys/net/ipv4/ip_dynaddr"); if (path != 0 && (fd = open(path, O_WRONLY)) >= 0) { if (write(fd, "1", 1) != 1) error("Couldn't enable dynamic IP addressing: %m"); close(fd); } dynaddr_set = 1; /* only 1 attempt */ } our_old_addr = 0; return 1; } /******************************************************************** * * cifaddr - Clear the interface IP addresses, and delete routes * through the interface if possible. */ int cifaddr (int unit, u_int32_t our_adr, u_int32_t his_adr) { struct ifreq ifr; if (kernel_version < KVERSION(2,1,16)) { /* * Delete the route through the device */ struct rtentry rt; memset (&rt, '\0', sizeof (rt)); SET_SA_FAMILY (rt.rt_dst, AF_INET); SET_SA_FAMILY (rt.rt_gateway, AF_INET); rt.rt_dev = ifname; SIN_ADDR(rt.rt_gateway) = 0; SIN_ADDR(rt.rt_dst) = his_adr; rt.rt_flags = RTF_UP | RTF_HOST; if (kernel_version > KVERSION(2,1,0)) { SET_SA_FAMILY (rt.rt_genmask, AF_INET); SIN_ADDR(rt.rt_genmask) = -1L; } if (ioctl(sock_fd, SIOCDELRT, &rt) < 0 && errno != ESRCH) { if (still_ppp() && ! ok_error (errno)) error("ioctl(SIOCDELRT) device route: %m (line %d)", __LINE__); return (0); } } /* This way it is possible to have an IPv6-only interface */ memset(&ifr, 0, sizeof(ifr)); SET_SA_FAMILY(ifr.ifr_addr, AF_INET); strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); if (ioctl(sock_fd, SIOCSIFADDR, (caddr_t) &ifr) < 0) { if (! ok_error (errno)) { error("ioctl(SIOCSIFADDR): %m (line %d)", __LINE__); return 0; } } our_old_addr = our_adr; return 1; } #ifdef PPP_WITH_IPV6CP /******************************************************************** * * sif6addr_rtnetlink - Config the interface with both IPv6 link-local addresses via rtnetlink */ static int sif6addr_rtnetlink(unsigned int iface, eui64_t our_eui64, eui64_t his_eui64) { struct { struct nlmsghdr nlh; struct ifaddrmsg ifa; struct { struct rtattr rta; struct in6_addr addr; } addrs[2]; } nlreq; int resp; memset(&nlreq, 0, sizeof(nlreq)); nlreq.nlh.nlmsg_len = sizeof(nlreq); nlreq.nlh.nlmsg_type = RTM_NEWADDR; nlreq.nlh.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK | NLM_F_EXCL | NLM_F_CREATE; nlreq.ifa.ifa_family = AF_INET6; nlreq.ifa.ifa_prefixlen = 128; nlreq.ifa.ifa_flags = IFA_F_NODAD | IFA_F_PERMANENT; nlreq.ifa.ifa_scope = RT_SCOPE_LINK; nlreq.ifa.ifa_index = iface; nlreq.addrs[0].rta.rta_len = sizeof(nlreq.addrs[0]); nlreq.addrs[0].rta.rta_type = IFA_LOCAL; IN6_LLADDR_FROM_EUI64(nlreq.addrs[0].addr, our_eui64); nlreq.addrs[1].rta.rta_len = sizeof(nlreq.addrs[1]); nlreq.addrs[1].rta.rta_type = IFA_ADDRESS; /* * To set only local address, older kernel expects that local address is * in IFA_ADDRESS field (not IFA_LOCAL). New kernels with support for peer * address, ignore IFA_ADDRESS if is same as IFA_LOCAL. So for backward * compatibility when setting only local address, set it via both IFA_LOCAL * and IFA_ADDRESS fields. Same logic is implemented in 'ip address' command * from iproute2 project. */ if (!eui64_iszero(his_eui64)) IN6_LLADDR_FROM_EUI64(nlreq.addrs[1].addr, his_eui64); else IN6_LLADDR_FROM_EUI64(nlreq.addrs[1].addr, our_eui64); resp = rtnetlink_msg("RTM_NEWADDR/NLM_F_CREATE", NULL, &nlreq, sizeof(nlreq), NULL, NULL, 0); if (resp) { /* * Linux kernel versions prior 3.11 do not support setting IPv6 peer * addresses and error response is expected. On older kernel versions * do not show this error message. On error pppd tries to fallback to * the old IOCTL method. */ errno = (resp < 0) ? -resp : EINVAL; if (kernel_version >= KVERSION(3,11,0)) error("sif6addr_rtnetlink: %m (line %d)", __LINE__); return 0; } return 1; } /******************************************************************** * * sif6addr - Config the interface with an IPv6 link-local address */ int sif6addr (int unit, eui64_t our_eui64, eui64_t his_eui64) { struct in6_ifreq ifr6; struct ifreq ifr; struct in6_rtmsg rt6; int ret; if (sock6_fd < 0) { errno = -sock6_fd; error("IPv6 socket creation failed: %m"); return 0; } memset(&ifr, 0, sizeof (ifr)); strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); if (ioctl(sock6_fd, SIOCGIFINDEX, (caddr_t) &ifr) < 0) { error("sif6addr: ioctl(SIOCGIFINDEX): %m (line %d)", __LINE__); return 0; } if (kernel_version >= KVERSION(2,1,16)) { /* Set both local address and remote peer address (with route for it) via rtnetlink */ ret = sif6addr_rtnetlink(ifr.ifr_ifindex, our_eui64, his_eui64); } else { ret = 0; } /* * Linux kernel versions prior 3.11 do not support setting IPv6 peer address * via rtnetlink. So if sif6addr_rtnetlink() fails then try old IOCTL method. */ if (!ret) { /* Local interface */ memset(&ifr6, 0, sizeof(ifr6)); IN6_LLADDR_FROM_EUI64(ifr6.ifr6_addr, our_eui64); ifr6.ifr6_ifindex = ifr.ifr_ifindex; ifr6.ifr6_prefixlen = 128; if (ioctl(sock6_fd, SIOCSIFADDR, &ifr6) < 0) { error("sif6addr: ioctl(SIOCSIFADDR): %m (line %d)", __LINE__); return 0; } } if (!ret && !eui64_iszero(his_eui64)) { /* * Linux kernel does not provide AF_INET6 ioctl SIOCSIFDSTADDR for * setting remote peer host address, so set only route to remote host. */ /* Route to remote host */ memset(&rt6, 0, sizeof(rt6)); IN6_LLADDR_FROM_EUI64(rt6.rtmsg_dst, his_eui64); rt6.rtmsg_flags = RTF_UP; rt6.rtmsg_dst_len = 128; rt6.rtmsg_ifindex = ifr.ifr_ifindex; rt6.rtmsg_metric = 1; if (ioctl(sock6_fd, SIOCADDRT, &rt6) < 0) { error("sif6addr: ioctl(SIOCADDRT): %m (line %d)", __LINE__); return 0; } } return 1; } /******************************************************************** * * cif6addr - Remove IPv6 address from interface */ int cif6addr (int unit, eui64_t our_eui64, eui64_t his_eui64) { struct ifreq ifr; struct in6_ifreq ifr6; if (sock6_fd < 0) { errno = -sock6_fd; error("IPv6 socket creation failed: %m"); return 0; } memset(&ifr, 0, sizeof(ifr)); strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); if (ioctl(sock6_fd, SIOCGIFINDEX, (caddr_t) &ifr) < 0) { error("cif6addr: ioctl(SIOCGIFINDEX): %m (line %d)", __LINE__); return 0; } memset(&ifr6, 0, sizeof(ifr6)); IN6_LLADDR_FROM_EUI64(ifr6.ifr6_addr, our_eui64); ifr6.ifr6_ifindex = ifr.ifr_ifindex; ifr6.ifr6_prefixlen = 128; if (ioctl(sock6_fd, SIOCDIFADDR, &ifr6) < 0) { if (errno != EADDRNOTAVAIL) { if (! ok_error (errno)) error("cif6addr: ioctl(SIOCDIFADDR): %m (line %d)", __LINE__); } else { warn("cif6addr: ioctl(SIOCDIFADDR): No such address"); } return (0); } return 1; } #endif /* PPP_WITH_IPV6CP */ /* * get_pty - get a pty master/slave pair and chown the slave side * to the uid given. Assumes slave_name points to >= 16 bytes of space. */ int get_pty(int *master_fdp, int *slave_fdp, char *slave_name, int uid) { int i, mfd, ret, sfd = -1; char pty_name[16]; struct termios tios; #ifdef TIOCGPTN /* * Try the unix98 way first. */ mfd = open("/dev/ptmx", O_RDWR); if (mfd >= 0) { int ptn; if (ioctl(mfd, TIOCGPTN, &ptn) >= 0) { slprintf(pty_name, sizeof(pty_name), "/dev/pts/%d", ptn); chmod(pty_name, S_IRUSR | S_IWUSR); #ifdef TIOCSPTLCK ptn = 0; if (ioctl(mfd, TIOCSPTLCK, &ptn) < 0) warn("Couldn't unlock pty slave %s: %m", pty_name); #endif if ((sfd = open(pty_name, O_RDWR | O_NOCTTY)) < 0) { warn("Couldn't open pty slave %s: %m", pty_name); close(mfd); } } } #endif /* TIOCGPTN */ if (sfd < 0) { /* the old way - scan through the pty name space */ for (i = 0; i < 64; ++i) { slprintf(pty_name, sizeof(pty_name), "/dev/pty%c%x", 'p' + i / 16, i % 16); mfd = open(pty_name, O_RDWR, 0); if (mfd >= 0) { pty_name[5] = 't'; sfd = open(pty_name, O_RDWR | O_NOCTTY, 0); if (sfd >= 0) { ret = fchown(sfd, uid, -1); if (ret != 0) { warn("Couldn't change ownership of %s, %m", pty_name); } ret = fchmod(sfd, S_IRUSR | S_IWUSR); if (ret != 0) { warn("Couldn't change permissions of %s, %m", pty_name); } break; } close(mfd); } } } if (sfd < 0) return 0; strlcpy(slave_name, pty_name, 16); *master_fdp = mfd; *slave_fdp = sfd; if (tcgetattr(sfd, &tios) == 0) { tios.c_cflag &= ~(CSIZE | CSTOPB | PARENB); tios.c_cflag |= CS8 | CREAD | CLOCAL; tios.c_iflag = IGNPAR; tios.c_oflag = 0; tios.c_lflag = 0; if (tcsetattr(sfd, TCSAFLUSH, &tios) < 0) warn("couldn't set attributes on pty: %m"); } else warn("couldn't get attributes on pty: %m"); return 1; } /******************************************************************** * * open_loopback - open the device we use for getting packets * in demand mode. Under Linux, we use a pty master/slave pair. */ int open_ppp_loopback(void) { int flags; looped = 1; if (new_style_driver) { /* allocate ourselves a ppp unit */ if (make_ppp_unit() < 0) die(1); modify_flags(ppp_dev_fd, 0, SC_LOOP_TRAFFIC); set_kdebugflag(kdebugflag); ppp_fd = -1; return ppp_dev_fd; } if (!get_pty(&master_fd, &slave_fd, loop_name, 0)) fatal("No free pty for loopback"); set_ppp_fd(slave_fd); flags = fcntl(master_fd, F_GETFL); if (flags == -1 || fcntl(master_fd, F_SETFL, flags | O_NONBLOCK) == -1) warn("couldn't set master loopback to nonblock: %m"); flags = fcntl(ppp_fd, F_GETFL); if (flags == -1 || fcntl(ppp_fd, F_SETFL, flags | O_NONBLOCK) == -1) warn("couldn't set slave loopback to nonblock: %m"); if (ioctl(ppp_fd, TIOCSETD, &ppp_disc) < 0) fatal("ioctl(TIOCSETD): %m (line %d)", __LINE__); /* * Find out which interface we were given. */ if (ioctl(ppp_fd, PPPIOCGUNIT, &ifunit) < 0) fatal("ioctl(PPPIOCGUNIT): %m (line %d)", __LINE__); /* * Enable debug in the driver if requested. */ set_kdebugflag (kdebugflag); return master_fd; } /******************************************************************** * * sifnpmode - Set the mode for handling packets for a given NP. */ int sifnpmode(int u, int proto, enum NPmode mode) { struct npioctl npi; npi.protocol = proto; npi.mode = mode; if (ioctl(ppp_dev_fd, PPPIOCSNPMODE, (caddr_t) &npi) < 0) { if (! ok_error (errno)) error("ioctl(PPPIOCSNPMODE, %d, %d): %m", proto, mode); return 0; } return 1; } /* * Use the hostname as part of the random number seed. */ int get_host_seed(void) { int h; const char *p; h = 407; for (p = hostname; *p != 0; ++p) h = h * 37 + *p; return h; } /******************************************************************** * * sys_check_options - check the options that the user specified */ int sys_check_options(void) { if (demand && driver_is_old) { ppp_option_error("demand dialling is not supported by kernel driver " "version %d.%d.%d", driver_version, driver_modification, driver_patch); return 0; } if (multilink && !new_style_driver) { warn("Warning: multilink is not supported by the kernel driver"); multilink = 0; } return 1; } /******************************************************************** * * get_time - Get current time, monotonic if possible. */ int ppp_get_time(struct timeval *tv) { /* Old glibc (< 2.3.4) does define CLOCK_MONOTONIC, but kernel may have it. * Runtime checking makes it safe. */ #ifndef CLOCK_MONOTONIC #define CLOCK_MONOTONIC 1 #endif static int monotonic = -1; struct timespec ts; int ret; if (monotonic) { ret = clock_gettime(CLOCK_MONOTONIC, &ts); if (ret == 0) { monotonic = 1; if (tv) { tv->tv_sec = ts.tv_sec; tv->tv_usec = ts.tv_nsec / 1000; } return ret; } else if (monotonic > 0) return ret; monotonic = 0; warn("Couldn't use monotonic clock source: %m"); } return gettimeofday(tv, NULL); } ppp-2.5.0/pppd/sys-solaris.c0000644000175000017500000020166114353435407012653 00000000000000/* * System-dependent procedures for pppd under Solaris 2. * * Parts re-written by Adi Masputra , based on * the original sys-svr4.c * * Copyright (c) 2000 by Sun Microsystems, Inc. * All rights reserved. * * Permission to use, copy, modify, and distribute this software and its * documentation is hereby granted, provided that the above copyright * notice appears in all copies. * * SUN MAKES NO REPRESENTATION OR WARRANTIES ABOUT THE SUITABILITY OF * THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * PARTICULAR PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES * * Copyright (c) 1995-2002 Paul Mackerras. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. The name(s) of the authors of this software must not be used to * endorse or promote products derived from this software without * prior written permission. * * 3. Redistributions of any form whatsoever must retain the following * acknowledgment: * "This product includes software developed by Paul Mackerras * ". * * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * Derived from main.c and pppd.h, which are: * * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The name "Carnegie Mellon University" must not be used to * endorse or promote products derived from this software without * prior written permission. For permission or any legal * details, please contact * Office of Technology Transfer * Carnegie Mellon University * 5000 Forbes Avenue * Pittsburgh, PA 15213-3890 * (412) 268-4387, fax: (412) 268-7395 * tech-transfer@andrew.cmu.edu * * 4. Redistributions of any form whatsoever must retain the following * acknowledgment: * "This product includes software developed by Computing Services * at Carnegie Mellon University (http://www.cmu.edu/computing/)." * * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include #include #include #include #ifndef CRTSCTS #include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef SOL2 #include #include #include #include #include #endif #ifdef PPP_WITH_FILTER #include #endif #include "pppd-private.h" #include "fsm.h" #include "lcp.h" #include "ipcp.h" #include "ccp.h" #ifdef PPP_WITH_IPV6CP #include "eui64.h" #endif #if !defined(PPP_DRV_NAME) #define PPP_DRV_NAME "ppp" #endif /* !defined(PPP_DRV_NAME) */ #if !defined(PPP_DEV_NAME) #define PPP_DEV_NAME "/dev/" PPP_DRV_NAME #endif /* !defined(PPP_DEV_NAME) */ #if !defined(AHDLC_MOD_NAME) #define AHDLC_MOD_NAME "ppp_ahdl" #endif /* !defined(AHDLC_MOD_NAME) */ #if !defined(COMP_MOD_NAME) #define COMP_MOD_NAME "ppp_comp" #endif /* !defined(COMP_MOD_NAME) */ #if !defined(IP_DEV_NAME) #define IP_DEV_NAME "/dev/ip" #endif /* !defined(IP_DEV_NAME) */ #if !defined(IP_MOD_NAME) #define IP_MOD_NAME "ip" #endif /* !defined(IP_MOD_NAME) */ #if !defined(UDP_DEV_NAME) && defined(SOL2) #define UDP_DEV_NAME "/dev/udp" #endif /* !defined(UDP_DEV_NAME) && defined(SOL2) */ #if !defined(UDP6_DEV_NAME) && defined(SOL2) #define UDP6_DEV_NAME "/dev/udp6" #endif /* !defined(UDP6_DEV_NAME) && defined(SOL2) */ #if defined(SOL2) /* * "/dev/udp" is used as a multiplexor to PLINK the interface stream * under. It is used in place of "/dev/ip" since STREAMS will not let * a driver be PLINK'ed under itself, and "/dev/ip" is typically the * driver at the bottom of the tunneling interfaces stream. */ static char *mux_dev_name = UDP_DEV_NAME; #else static char *mux_dev_name = IP_DEV_NAME; #endif static int pppfd; static int fdmuxid = -1; static int ipfd; static int ipmuxid = -1; #if defined(PPP_WITH_IPV6CP) && defined(SOL2) static int ip6fd; /* IP file descriptor */ static int ip6muxid = -1; /* Multiplexer file descriptor */ static int if6_is_up = 0; /* IPv6 interface has been marked up */ #define IN6_SOCKADDR_FROM_EUI64(s, eui64) do { \ (s)->sin6_family = AF_INET6; \ (s)->sin6_addr.s6_addr32[0] = htonl(0xfe800000); \ eui64_copy(eui64, (s)->sin6_addr.s6_addr32[2]); \ } while(0) #define _IN6_LLX_FROM_EUI64(l, s, eui64, as) do { \ s->sin6_addr.s6_addr32[0] = htonl(as); \ eui64_copy(eui64, s->sin6_addr.s6_addr32[2]); \ s->sin6_family = AF_INET6; \ l.lifr_addr.ss_family = AF_INET6; \ l.lifr_addrlen = 64; \ l.lifr_addr = laddr; \ } while (0) #define _IN6A_LLX_FROM_EUI64(s, eui64, as) do { \ s->s6_addr32[0] = htonl(as); \ eui64_copy(eui64, s->s6_addr32[2]); \ } while (0) #define IN6_LLADDR_FROM_EUI64(l, s, eui64) \ _IN6_LLX_FROM_EUI64(l, s, eui64, 0xfe800000) #define IN6_LLTOKEN_FROM_EUI64(l, s, eui64) \ _IN6_LLX_FROM_EUI64(l, s, eui64, 0) #define IN6A_LLADDR_FROM_EUI64(s, eui64) \ _IN6A_LLX_FROM_EUI64(s, eui64, 0xfe800000) #endif /* defined(PPP_WITH_IPV6CP) && defined(SOL2) */ #if !defined(PPP_WITH_IPV6CP) || !defined(SOL2) #define MAXIFS 256 /* Max # of interfaces */ #endif /* defined(PPP_WITH_IPV6CP) && defined(SOL2) */ static int restore_term; static struct termios inittermios; #ifndef CRTSCTS static struct termiox inittermiox; static int termiox_ok; #endif static struct winsize wsinfo; /* Initial window size info */ static pid_t tty_sid; /* original session ID for terminal */ extern u_char inpacket_buf[]; /* borrowed from main.c */ #define MAX_POLLFDS 32 static struct pollfd pollfds[MAX_POLLFDS]; static int n_pollfds; static int link_mtu, link_mru; #define NMODULES 32 static int tty_nmodules; static char tty_modules[NMODULES][FMNAMESZ+1]; static int tty_npushed; static int if_is_up; /* Interface has been marked up */ static u_int32_t remote_addr; /* IP address of peer */ static u_int32_t default_route_gateway; /* Gateway for default route added */ static eui64_t default_route_gateway6; /* Gateway for default IPv6 route added */ static u_int32_t proxy_arp_addr; /* Addr for proxy arp entry added */ /* Prototypes for procedures local to this file. */ static int translate_speed(int); static int baud_rate_of(int); static int get_ether_addr(u_int32_t, struct sockaddr *); static int get_hw_addr(char *, u_int32_t, struct sockaddr *); static int get_hw_addr_dlpi(char *, struct sockaddr *); static int dlpi_attach(int, int); static int dlpi_info_req(int); static int dlpi_get_reply(int, union DL_primitives *, int, size_t); static int strioctl(int, int, void *, int, int); #ifdef SOL2 /* * sifppa - Sets interface ppa * * without setting the ppa, ip module will return EINVAL upon setting the * interface UP (SIOCSxIFFLAGS). This is because ip module in 2.8 expects * two DLPI_INFO_REQ to be sent down to the driver (below ip) before * IFF_UP can be set. Plumbing the device causes one DLPI_INFO_REQ to * be sent down, and the second DLPI_INFO_REQ is sent upon receiving * IF_UNITSEL (old) or SIOCSLIFNAME (new) ioctls. Such setting of the ppa * is required because the ppp DLPI provider advertises itself as * a DLPI style 2 type, which requires a point of attachment to be * specified. The only way the user can specify a point of attachment * is via SIOCSLIFNAME or IF_UNITSEL. * * Such changes in the behavior of ip module was made to meet new or * evolving standards requirements. * */ static int sifppa(fd, ppa) int fd; int ppa; { return (int)ioctl(fd, IF_UNITSEL, (char *)&ppa); } #endif /* SOL2 */ #if defined(SOL2) && defined(PPP_WITH_IPV6CP) /* * get_first_ether_hwaddr - get the hardware address for the first * ethernet-style interface on this system. * * NOTE: This is the lifreq version (Solaris 8 and above) */ int get_first_ether_hwaddr(u_char *addr) { struct lifnum lifn; struct lifconf lifc; struct lifreq *plifreq; struct lifreq lifr; int fd, num_ifs, i, found; uint_t fl, req_size; char *req; fd = socket(AF_INET, SOCK_DGRAM, 0); if (fd < 0) { return -1; } /* * Find out how many interfaces are running */ lifn.lifn_family = AF_UNSPEC; lifn.lifn_flags = LIFC_NOXMIT; if (ioctl(fd, SIOCGLIFNUM, &lifn) < 0) { close(fd); error("could not determine number of interfaces: %m"); return -1; } num_ifs = lifn.lifn_count; req_size = num_ifs * sizeof(struct lifreq); req = malloc(req_size); if (req == NULL) { close(fd); error("out of memory"); return -1; } /* * Get interface configuration info for all interfaces */ lifc.lifc_family = AF_UNSPEC; lifc.lifc_flags = LIFC_NOXMIT; lifc.lifc_len = req_size; lifc.lifc_buf = req; if (ioctl(fd, SIOCGLIFCONF, &lifc) < 0) { close(fd); free(req); error("SIOCGLIFCONF: %m"); return -1; } /* * And traverse each interface to look specifically for the first * occurence of an Ethernet interface which has been marked up */ plifreq = lifc.lifc_req; found = 0; for (i = lifc.lifc_len / sizeof(struct lifreq); i > 0; i--, plifreq++) { if (strchr(plifreq->lifr_name, ':') != NULL) continue; memset(&lifr, 0, sizeof(lifr)); strncpy(lifr.lifr_name, plifreq->lifr_name, sizeof(lifr.lifr_name)); if (ioctl(fd, SIOCGLIFFLAGS, &lifr) < 0) { error("SIOCGLIFFLAGS: %m"); break; } fl = lifr.lifr_flags; if ((fl & (IFF_UP|IFF_BROADCAST|IFF_POINTOPOINT|IFF_LOOPBACK|IFF_NOARP)) != (IFF_UP | IFF_BROADCAST)) continue; if (get_if_hwaddr(addr, lifr.lifr_name) < 0) continue; found = 1; break; } free(req); close(fd); if (found) return 0; else return -1; } #else /* * get_first_ether_hwaddr - get the hardware address for the first * ethernet-style interface on this system. * * NOTE: This is the ifreq version (before Solaris 8). */ int get_first_ether_hwaddr(u_char *addr) { struct ifconf ifc; struct ifreq *pifreq; struct ifreq ifr; int fd, num_ifs, i, found; uint_t fl, req_size; char *req; fd = socket(AF_INET, SOCK_DGRAM, 0); if (fd < 0) { return -1; } /* * Find out how many interfaces are running */ if (ioctl(fd, SIOCGIFNUM, (char *)&num_ifs) < 0) { num_ifs = MAXIFS; } req_size = num_ifs * sizeof(struct ifreq); req = malloc(req_size); if (req == NULL) { close(fd); error("out of memory"); return -1; } /* * Get interface configuration info for all interfaces */ ifc.ifc_len = req_size; ifc.ifc_buf = req; if (ioctl(fd, SIOCGIFCONF, &ifc) < 0) { close(fd); free(req); error("SIOCGIFCONF: %m"); return -1; } /* * And traverse each interface to look specifically for the first * occurence of an Ethernet interface which has been marked up */ pifreq = ifc.ifc_req; found = 0; for (i = ifc.ifc_len / sizeof(struct ifreq); i > 0; i--, pifreq++) { if (strchr(pifreq->ifr_name, ':') != NULL) continue; memset(&ifr, 0, sizeof(ifr)); strncpy(ifr.ifr_name, pifreq->ifr_name, sizeof(ifr.ifr_name)); if (ioctl(fd, SIOCGIFFLAGS, &ifr) < 0) { error("SIOCGIFFLAGS: %m"); break; } fl = ifr.ifr_flags; if ((fl & (IFF_UP|IFF_BROADCAST|IFF_POINTOPOINT|IFF_LOOPBACK|IFF_NOARP)) != (IFF_UP | IFF_BROADCAST)) continue; if (get_if_hwaddr(addr, ifr.ifr_name) < 0) continue; found = 1; break; } free(req); close(fd); if (found) return 0; else return -1; } #endif /* defined(SOL2) && defined(PPP_WITH_IPV6CP) */ #if defined(SOL2) /* * get_if_hwaddr - get the hardware address for the specified * network interface device. */ int get_if_hwaddr(u_char *addr, char *if_name) { struct sockaddr s_eth_addr; struct ether_addr *eth_addr = (struct ether_addr *)&s_eth_addr.sa_data; if (if_name == NULL) return -1; /* * Send DL_INFO_REQ to the driver to solicit its MAC address */ if (!get_hw_addr_dlpi(if_name, &s_eth_addr)) { error("could not obtain hardware address for %s", if_name); return -1; } memcpy(addr, eth_addr->ether_addr_octet, 6); return 1; } #endif /* SOL2 */ #if defined(SOL2) && defined(PPP_WITH_IPV6CP) /* * slifname - Sets interface ppa and flags * * in addition to the comments stated in sifppa(), IFF_IPV6 bit must * be set in order to declare this as an IPv6 interface */ static int slifname(int fd, int ppa) { struct lifreq lifr; int ret; memset(&lifr, 0, sizeof(lifr)); ret = ioctl(fd, SIOCGLIFFLAGS, &lifr); if (ret < 0) goto slifname_done; lifr.lifr_flags |= IFF_IPV6; lifr.lifr_flags &= ~(IFF_BROADCAST | IFF_IPV4); lifr.lifr_ppa = ppa; strlcpy(lifr.lifr_name, ifname, sizeof(lifr.lifr_name)); ret = ioctl(fd, SIOCSLIFNAME, &lifr); slifname_done: return ret; } #endif /* defined(SOL2) && defined(PPP_WITH_IPV6CP) */ /* * sys_init - System-dependent initialization. */ void sys_init(void) { int ifd, x; struct ifreq ifr; #if defined(PPP_WITH_IPV6CP) && defined(SOL2) int i6fd; struct lifreq lifr; #endif /* defined(PPP_WITH_IPV6CP) && defined(SOL2) */ #if !defined(SOL2) struct { union DL_primitives prim; char space[64]; } reply; #endif /* !defined(SOL2) */ ipfd = open(mux_dev_name, O_RDWR, 0); if (ipfd < 0) fatal("Couldn't open IP device: %m"); #if defined(PPP_WITH_IPV6CP) && defined(SOL2) ip6fd = open(UDP6_DEV_NAME, O_RDWR, 0); if (ip6fd < 0) fatal("Couldn't open IP device (2): %m"); #endif /* defined(PPP_WITH_IPV6CP) && defined(SOL2) */ if (default_device && !notty) tty_sid = getsid((pid_t)0); pppfd = open(PPP_DEV_NAME, O_RDWR | O_NONBLOCK, 0); if (pppfd < 0) fatal("Can't open %s: %m", PPP_DEV_NAME); if (kdebugflag & 1) { x = PPPDBG_LOG + PPPDBG_DRIVER; strioctl(pppfd, PPPIO_DEBUG, &x, sizeof(int), 0); } /* Assign a new PPA and get its unit number. */ if (strioctl(pppfd, PPPIO_NEWPPA, &ifunit, 0, sizeof(int)) < 0) fatal("Can't create new PPP interface: %m"); #if defined(SOL2) /* * Since sys_init() is called prior to ifname being set in main(), * we need to get the ifname now, otherwise slifname(), and others, * will fail, or maybe, I should move them to a later point ? * */ sprintf(ifname, PPP_DRV_NAME "%d", ifunit); #endif /* defined(SOL2) */ /* * Open the ppp device again and link it under the ip multiplexor. * IP will assign a unit number which hopefully is the same as ifunit. * I don't know any way to be certain they will be the same. :-( */ ifd = open(PPP_DEV_NAME, O_RDWR, 0); if (ifd < 0) fatal("Can't open %s (2): %m", PPP_DEV_NAME); if (kdebugflag & 1) { x = PPPDBG_LOG + PPPDBG_DRIVER; strioctl(ifd, PPPIO_DEBUG, &x, sizeof(int), 0); } #if defined(PPP_WITH_IPV6CP) && defined(SOL2) i6fd = open(PPP_DEV_NAME, O_RDWR, 0); if (i6fd < 0) { close(ifd); fatal("Can't open %s (3): %m", PPP_DEV_NAME); } if (kdebugflag & 1) { x = PPPDBG_LOG + PPPDBG_DRIVER; strioctl(i6fd, PPPIO_DEBUG, &x, sizeof(int), 0); } #endif /* defined(PPP_WITH_IPV6CP) && defined(SOL2) */ #if defined(SOL2) if (ioctl(ifd, I_PUSH, IP_MOD_NAME) < 0) { close(ifd); #if defined(PPP_WITH_IPV6CP) close(i6fd); #endif /* defined(PPP_WITH_IPV6CP) */ fatal("Can't push IP module: %m"); } /* * Assign ppa according to the unit number returned by ppp device * after plumbing is completed above. */ if (sifppa(ifd, ifunit) < 0) { close (ifd); #if defined(PPP_WITH_IPV6CP) close(i6fd); #endif /* defined(PPP_WITH_IPV6CP) */ fatal("Can't set ppa for unit %d: %m", ifunit); } #if defined(PPP_WITH_IPV6CP) /* * An IPv6 interface is created anyway, even when the user does not * explicitly enable it. Note that the interface will be marked * IPv6 during slifname(). */ if (ioctl(i6fd, I_PUSH, IP_MOD_NAME) < 0) { close(ifd); close(i6fd); fatal("Can't push IP module (2): %m"); } /* * Assign ppa according to the unit number returned by ppp device * after plumbing is completed above. In addition, mark the interface * as an IPv6 interface. */ if (slifname(i6fd, ifunit) < 0) { close(ifd); close(i6fd); fatal("Can't set ifname for unit %d: %m", ifunit); } #endif /* defined(PPP_WITH_IPV6CP) */ ipmuxid = ioctl(ipfd, I_PLINK, ifd); close(ifd); if (ipmuxid < 0) { #if defined(PPP_WITH_IPV6CP) close(i6fd); #endif /* defined(PPP_WITH_IPV6CP) */ fatal("Can't I_PLINK PPP device to IP: %m"); } memset(&ifr, 0, sizeof(ifr)); sprintf(ifr.ifr_name, "%s", ifname); ifr.ifr_ip_muxid = ipmuxid; /* * In Sol 8 and later, STREAMS dynamic module plumbing feature exists. * This is so that an arbitrary module can be inserted, or deleted, * between ip module and the device driver without tearing down the * existing stream. Such feature requires the mux ids, which is set * by SIOCSIFMUXID (or SIOCLSIFMUXID). */ if (ioctl(ipfd, SIOCSIFMUXID, &ifr) < 0) { ioctl(ipfd, I_PUNLINK, ipmuxid); #if defined(PPP_WITH_IPV6CP) close(i6fd); #endif /* defined(PPP_WITH_IPV6CP) */ fatal("SIOCSIFMUXID: %m"); } #else /* else if !defined(SOL2) */ if (dlpi_attach(ifd, ifunit) < 0 || dlpi_get_reply(ifd, &reply.prim, DL_OK_ACK, sizeof(reply)) < 0) { close(ifd); fatal("Can't attach to ppp%d: %m", ifunit); } ipmuxid = ioctl(ipfd, I_LINK, ifd); close(ifd); if (ipmuxid < 0) fatal("Can't link PPP device to IP: %m"); #endif /* defined(SOL2) */ #if defined(PPP_WITH_IPV6CP) && defined(SOL2) ip6muxid = ioctl(ip6fd, I_PLINK, i6fd); close(i6fd); if (ip6muxid < 0) { ioctl(ipfd, I_PUNLINK, ipmuxid); fatal("Can't I_PLINK PPP device to IP (2): %m"); } memset(&lifr, 0, sizeof(lifr)); sprintf(lifr.lifr_name, "%s", ifname); lifr.lifr_ip_muxid = ip6muxid; /* * Let IP know of the mux id [see comment for SIOCSIFMUXID above] */ if (ioctl(ip6fd, SIOCSLIFMUXID, &lifr) < 0) { ioctl(ipfd, I_PUNLINK, ipmuxid); ioctl(ip6fd, I_PUNLINK, ip6muxid); fatal("Can't link PPP device to IP (2): %m"); } #endif /* defined(PPP_WITH_IPV6CP) && defined(SOL2) */ #if !defined(SOL2) /* Set the interface name for the link. */ slprintf(ifr.ifr_name, sizeof(ifr.ifr_name), PPP_DRV_NAME "%d", ifunit); ifr.ifr_metric = ipmuxid; if (strioctl(ipfd, SIOCSIFNAME, (char *)&ifr, sizeof ifr, 0) < 0) fatal("Can't set interface name %s: %m", ifr.ifr_name); #endif /* !defined(SOL2) */ n_pollfds = 0; } /* * sys_cleanup - restore any system state we modified before exiting: * mark the interface down, delete default route and/or proxy arp entry. * This should call die() because it's called from die(). */ void sys_cleanup(void) { #if defined(SOL2) struct ifreq ifr; #if defined(PPP_WITH_IPV6CP) struct lifreq lifr; #endif /* defined(PPP_WITH_IPV6CP) */ #endif /* defined(SOL2) */ #if defined(SOL2) && defined(PPP_WITH_IPV6CP) if (if6_is_up) sif6down(0); #endif /* defined(SOL2) && defined(PPP_WITH_IPV6CP) */ if (if_is_up) sifdown(0); if (default_route_gateway) cifdefaultroute(0, default_route_gateway, default_route_gateway); if (default_route_gateway6.e32[0] != 0 || default_route_gateway6.e32[1] != 0) cif6defaultroute(0, default_route_gateway6, default_route_gateway6); if (proxy_arp_addr) cifproxyarp(0, proxy_arp_addr); #if defined(SOL2) /* * Make sure we ask ip what the muxid, because 'ifconfig modlist' will * unlink and re-link the modules, causing the muxid to change. */ memset(&ifr, 0, sizeof(ifr)); sprintf(ifr.ifr_name, "%s", ifname); if (ioctl(ipfd, SIOCGIFFLAGS, &ifr) < 0) { error("SIOCGIFFLAGS: %m"); return; } if (ioctl(ipfd, SIOCGIFMUXID, &ifr) < 0) { error("SIOCGIFMUXID: %m"); return; } ipmuxid = ifr.ifr_ip_muxid; if (ioctl(ipfd, I_PUNLINK, ipmuxid) < 0) { error("Can't I_PUNLINK PPP from IP: %m"); return; } #if defined(PPP_WITH_IPV6CP) /* * Make sure we ask ip what the muxid, because 'ifconfig modlist' will * unlink and re-link the modules, causing the muxid to change. */ memset(&lifr, 0, sizeof(lifr)); sprintf(lifr.lifr_name, "%s", ifname); if (ioctl(ip6fd, SIOCGLIFFLAGS, &lifr) < 0) { error("SIOCGLIFFLAGS: %m"); return; } if (ioctl(ip6fd, SIOCGLIFMUXID, &lifr) < 0) { error("SIOCGLIFMUXID: %m"); return; } ip6muxid = lifr.lifr_ip_muxid; if (ioctl(ip6fd, I_PUNLINK, ip6muxid) < 0) { error("Can't I_PUNLINK PPP from IP (2): %m"); } #endif /* defined(PPP_WITH_IPV6CP) */ #endif /* defined(SOL2) */ } /* * sys_close - Clean up in a child process before execing. */ void ppp_sys_close(void) { close(ipfd); #if defined(PPP_WITH_IPV6CP) && defined(SOL2) close(ip6fd); #endif /* defined(PPP_WITH_IPV6CP) && defined(SOL2) */ if (pppfd >= 0) close(pppfd); } /* * sys_check_options - check the options that the user specified */ int sys_check_options(void) { return 1; } #if 0 /* * daemon - Detach us from controlling terminal session. */ int daemon(int nochdir, int noclose) { int pid; if ((pid = fork()) < 0) return -1; if (pid != 0) exit(0); /* parent dies */ setsid(); if (!nochdir) chdir("/"); if (!noclose) { fclose(stdin); /* don't need stdin, stdout, stderr */ fclose(stdout); fclose(stderr); } return 0; } #endif /* * ppp_check_kernel_support - check whether the system has any ppp interfaces */ int ppp_check_kernel_support(void) { struct stat buf; return stat(PPP_DEV_NAME, &buf) >= 0; } /* * any_compressions - see if compression is enabled or not * * In the STREAMS implementation of kernel-portion pppd, * the comp STREAMS module performs the ACFC, PFC, as well * CCP and VJ compressions. However, if the user has explicitly * declare to not enable them from the command line, there is * no point of having the comp module be pushed on the stream. */ static int any_compressions(void) { if ((!lcp_wantoptions[0].neg_accompression) && (!lcp_wantoptions[0].neg_pcompression) && (!ccp_protent.enabled_flag) && (!ipcp_wantoptions[0].neg_vj)) { return 0; } return 1; } /* * tty_establish_ppp - Turn the serial port into a ppp interface. */ int tty_establish_ppp(int fd) { int i; /* Pop any existing modules off the tty stream. */ for (i = 0;; ++i) if (ioctl(fd, I_LOOK, tty_modules[i]) < 0 || strcmp(tty_modules[i], "ptem") == 0 || ioctl(fd, I_POP, 0) < 0) break; tty_nmodules = i; /* Push the async hdlc module and the compressor module. */ tty_npushed = 0; if(!ppp_sync_serial()) { if (ioctl(fd, I_PUSH, AHDLC_MOD_NAME) < 0) { error("Couldn't push PPP Async HDLC module: %m"); return -1; } ++tty_npushed; } if (kdebugflag & 4) { i = PPPDBG_LOG + PPPDBG_AHDLC; strioctl(pppfd, PPPIO_DEBUG, &i, sizeof(int), 0); } /* * There's no need to push comp module if we don't intend * to compress anything */ if (any_compressions()) { if (ioctl(fd, I_PUSH, COMP_MOD_NAME) < 0) error("Couldn't push PPP compression module: %m"); else ++tty_npushed; } if (kdebugflag & 2) { i = PPPDBG_LOG; if (any_compressions()) i += PPPDBG_COMP; strioctl(pppfd, PPPIO_DEBUG, &i, sizeof(int), 0); } /* Link the serial port under the PPP multiplexor. */ if ((fdmuxid = ioctl(pppfd, I_LINK, fd)) < 0) { error("Can't link tty to PPP mux: %m"); return -1; } return pppfd; } /* * tty_disestablish_ppp - Restore the serial port to normal operation. * It attempts to reconstruct the stream with the previously popped * modules. This shouldn't call die() because it's called from die(). */ void tty_disestablish_ppp(int fd) { int i; if (fdmuxid >= 0) { if (ioctl(pppfd, I_UNLINK, fdmuxid) < 0) { if (!hungup) error("Can't unlink tty from PPP mux: %m"); } fdmuxid = -1; if (!hungup) { while (tty_npushed > 0 && ioctl(fd, I_POP, 0) >= 0) --tty_npushed; for (i = tty_nmodules - 1; i >= 0; --i) if (ioctl(fd, I_PUSH, tty_modules[i]) < 0) error("Couldn't restore tty module %s: %m", tty_modules[i]); } if (hungup && default_device && tty_sid > 0) { /* * If we have received a hangup, we need to send a SIGHUP * to the terminal's controlling process. The reason is * that the original stream head for the terminal hasn't * seen the M_HANGUP message (it went up through the ppp * driver to the stream head for our fd to /dev/ppp). */ kill(tty_sid, SIGHUP); } } } /* * Check whether the link seems not to be 8-bit clean. */ void clean_check(void) { int x; char *s; if (strioctl(pppfd, PPPIO_GCLEAN, &x, 0, sizeof(x)) < 0) return; s = NULL; switch (~x) { case RCV_B7_0: s = "bit 7 set to 1"; break; case RCV_B7_1: s = "bit 7 set to 0"; break; case RCV_EVNP: s = "odd parity"; break; case RCV_ODDP: s = "even parity"; break; } if (s != NULL) { warn("Serial link is not 8-bit clean:"); warn("All received characters had %s", s); } } /* * List of valid speeds. */ struct speed { int speed_int, speed_val; } speeds[] = { #ifdef B50 { 50, B50 }, #endif #ifdef B75 { 75, B75 }, #endif #ifdef B110 { 110, B110 }, #endif #ifdef B134 { 134, B134 }, #endif #ifdef B150 { 150, B150 }, #endif #ifdef B200 { 200, B200 }, #endif #ifdef B300 { 300, B300 }, #endif #ifdef B600 { 600, B600 }, #endif #ifdef B1200 { 1200, B1200 }, #endif #ifdef B1800 { 1800, B1800 }, #endif #ifdef B2000 { 2000, B2000 }, #endif #ifdef B2400 { 2400, B2400 }, #endif #ifdef B3600 { 3600, B3600 }, #endif #ifdef B4800 { 4800, B4800 }, #endif #ifdef B7200 { 7200, B7200 }, #endif #ifdef B9600 { 9600, B9600 }, #endif #ifdef B19200 { 19200, B19200 }, #endif #ifdef B38400 { 38400, B38400 }, #endif #ifdef EXTA { 19200, EXTA }, #endif #ifdef EXTB { 38400, EXTB }, #endif #ifdef B57600 { 57600, B57600 }, #endif #ifdef B76800 { 76800, B76800 }, #endif #ifdef B115200 { 115200, B115200 }, #endif #ifdef B153600 { 153600, B153600 }, #endif #ifdef B230400 { 230400, B230400 }, #endif #ifdef B307200 { 307200, B307200 }, #endif #ifdef B460800 { 460800, B460800 }, #endif { 0, 0 } }; /* * Translate from bits/second to a speed_t. */ static int translate_speed(int bps) { struct speed *speedp; if (bps == 0) return 0; for (speedp = speeds; speedp->speed_int; speedp++) if (bps == speedp->speed_int) return speedp->speed_val; warn("speed %d not supported", bps); return 0; } /* * Translate from a speed_t to bits/second. */ static int baud_rate_of(int speed) { struct speed *speedp; if (speed == 0) return 0; for (speedp = speeds; speedp->speed_int; speedp++) if (speed == speedp->speed_val) return speedp->speed_int; return 0; } /* * set_up_tty: Set up the serial port on `fd' for 8 bits, no parity, * at the requested speed, etc. If `local' is true, set CLOCAL * regardless of whether the modem option was specified. */ void set_up_tty(int fd, int local) { int speed; struct termios tios; #if !defined (CRTSCTS) struct termiox tiox; #endif if (!ppp_sync_serial() && tcgetattr(fd, &tios) < 0) fatal("tcgetattr: %m"); #ifndef CRTSCTS termiox_ok = 1; if (!ppp_sync_serial() && ioctl (fd, TCGETX, &tiox) < 0) { termiox_ok = 0; if (errno != ENOTTY) error("TCGETX: %m"); } #endif if (!restore_term) { inittermios = tios; #ifndef CRTSCTS inittermiox = tiox; #endif if (!ppp_sync_serial()) ioctl(fd, TIOCGWINSZ, &wsinfo); } tios.c_cflag &= ~(CSIZE | CSTOPB | PARENB | CLOCAL); #ifdef CRTSCTS if (crtscts > 0) tios.c_cflag |= CRTSCTS; else if (crtscts < 0) tios.c_cflag &= ~CRTSCTS; #else if (crtscts != 0 && !termiox_ok) { error("Can't set RTS/CTS flow control"); } else if (crtscts > 0) { tiox.x_hflag |= RTSXOFF|CTSXON; } else if (crtscts < 0) { tiox.x_hflag &= ~(RTSXOFF|CTSXON); } #endif if (stop_bits >= 2) tios.c_cflag |= CSTOPB; tios.c_cflag |= CS8 | CREAD | HUPCL; if (local || !modem) tios.c_cflag |= CLOCAL; tios.c_iflag = IGNBRK | IGNPAR; tios.c_oflag = 0; tios.c_lflag = 0; tios.c_cc[VMIN] = 1; tios.c_cc[VTIME] = 0; if (crtscts == -2) { tios.c_iflag |= IXON | IXOFF; tios.c_cc[VSTOP] = 0x13; /* DC3 = XOFF = ^S */ tios.c_cc[VSTART] = 0x11; /* DC1 = XON = ^Q */ } speed = translate_speed(inspeed); if (speed) { cfsetospeed(&tios, speed); cfsetispeed(&tios, speed); } else { speed = cfgetospeed(&tios); /* * We can't proceed if the serial port speed is 0, * since that implies that the serial port is disabled. */ if ((speed == B0) && !ppp_sync_serial()) fatal("Baud rate for %s is 0; need explicit baud rate", devnam); } if (!ppp_sync_serial() && tcsetattr(fd, TCSAFLUSH, &tios) < 0) fatal("tcsetattr: %m"); #ifndef CRTSCTS if (!ppp_sync_serial() && termiox_ok && ioctl (fd, TCSETXF, &tiox) < 0){ error("TCSETXF: %m"); } #endif baud_rate = inspeed = baud_rate_of(speed); if (!ppp_sync_serial()) restore_term = 1; } /* * restore_tty - restore the terminal to the saved settings. */ void restore_tty(int fd) { if (restore_term) { if (!default_device) { /* * Turn off echoing, because otherwise we can get into * a loop with the tty and the modem echoing to each other. * We presume we are the sole user of this tty device, so * when we close it, it will revert to its defaults anyway. */ inittermios.c_lflag &= ~(ECHO | ECHONL); } if (!ppp_sync_serial() && tcsetattr(fd, TCSAFLUSH, &inittermios) < 0) if (!hungup && errno != ENXIO) warn("tcsetattr: %m"); #ifndef CRTSCTS if (!ppp_sync_serial() && ioctl (fd, TCSETXF, &inittermiox) < 0){ if (!hungup && errno != ENXIO) error("TCSETXF: %m"); } #endif if (!ppp_sync_serial()) ioctl(fd, TIOCSWINSZ, &wsinfo); restore_term = 0; } } /* * setdtr - control the DTR line on the serial port. * This is called from die(), so it shouldn't call die(). */ void setdtr(int fd, int on) { int modembits = TIOCM_DTR; ioctl(fd, (on? TIOCMBIS: TIOCMBIC), &modembits); } /* * open_loopback - open the device we use for getting packets * in demand mode. Under Solaris 2, we use our existing fd * to the ppp driver. */ int open_ppp_loopback(void) { return pppfd; } /* * output - Output PPP packet. */ void output(int unit, u_char *p, int len) { struct strbuf data; int retries; struct pollfd pfd; dump_packet("sent", p, len); if (snoop_send_hook) snoop_send_hook(p, len); data.len = len; data.buf = (caddr_t) p; retries = 4; while (putmsg(pppfd, NULL, &data, 0) < 0) { if (--retries < 0 || (errno != EWOULDBLOCK && errno != EAGAIN)) { if (errno != ENXIO) error("Couldn't send packet: %m"); break; } pfd.fd = pppfd; pfd.events = POLLOUT; poll(&pfd, 1, 250); /* wait for up to 0.25 seconds */ } } /* * wait_input - wait until there is data available, * for the length of time specified by *timo (indefinite * if timo is NULL). */ void wait_input(struct timeval *timo) { int t; t = timo == NULL? -1: timo->tv_sec * 1000 + timo->tv_usec / 1000; if (poll(pollfds, n_pollfds, t) < 0 && errno != EINTR) fatal("poll: %m"); } /* * add_fd - add an fd to the set that wait_input waits for. */ void add_fd(int fd) { int n; for (n = 0; n < n_pollfds; ++n) if (pollfds[n].fd == fd) return; if (n_pollfds < MAX_POLLFDS) { pollfds[n_pollfds].fd = fd; pollfds[n_pollfds].events = POLLIN | POLLPRI | POLLHUP; ++n_pollfds; } else error("Too many inputs!"); } /* * remove_fd - remove an fd from the set that wait_input waits for. */ void remove_fd(int fd) { int n; for (n = 0; n < n_pollfds; ++n) { if (pollfds[n].fd == fd) { while (++n < n_pollfds) pollfds[n-1] = pollfds[n]; --n_pollfds; break; } } } #if 0 /* * wait_loop_output - wait until there is data available on the * loopback, for the length of time specified by *timo (indefinite * if timo is NULL). */ void wait_loop_output(struct timeval *timo) { wait_input(timo); } /* * wait_time - wait for a given length of time or until a * signal is received. */ void wait_time(struct timeval *timo) { int n; n = select(0, NULL, NULL, NULL, timo); if (n < 0 && errno != EINTR) fatal("select: %m"); } #endif /* * read_packet - get a PPP packet from the serial device. */ int read_packet(u_char *buf) { struct strbuf ctrl, data; int flags, len; unsigned char ctrlbuf[sizeof(union DL_primitives) + 64]; for (;;) { data.maxlen = PPP_MRU + PPP_HDRLEN; data.buf = (caddr_t) buf; ctrl.maxlen = sizeof(ctrlbuf); ctrl.buf = (caddr_t) ctrlbuf; flags = 0; len = getmsg(pppfd, &ctrl, &data, &flags); if (len < 0) { if (errno == EAGAIN || errno == EINTR) return -1; fatal("Error reading packet: %m"); } if (ctrl.len <= 0) return data.len; /* * Got a M_PROTO or M_PCPROTO message. Interpret it * as a DLPI primitive?? */ if (debug) dbglog("got dlpi prim 0x%x, len=%d", ((union DL_primitives *)ctrlbuf)->dl_primitive, ctrl.len); } } /* * get_loop_output - get outgoing packets from the ppp device, * and detect when we want to bring the real link up. * Return value is 1 if we need to bring up the link, 0 otherwise. */ int get_loop_output(void) { int len; int rv = 0; while ((len = read_packet(inpacket_buf)) > 0) { if (loop_frame(inpacket_buf, len)) rv = 1; } return rv; } /* * ppp_set_mtu - set the MTU on the PPP network interface. */ void ppp_set_mtu(int unit, int mtu) { struct ifreq ifr; #if defined(PPP_WITH_IPV6CP) && defined(SOL2) struct lifreq lifr; int fd; #endif /* defined(PPP_WITH_IPV6CP) && defined(SOL2) */ memset(&ifr, 0, sizeof(ifr)); strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); ifr.ifr_metric = mtu; if (ioctl(ipfd, SIOCSIFMTU, &ifr) < 0) { error("Couldn't set IP MTU (%s): %m", ifr.ifr_name); } #if defined(PPP_WITH_IPV6CP) && defined(SOL2) fd = socket(AF_INET6, SOCK_DGRAM, 0); if (fd < 0) error("Couldn't open IPv6 socket: %m"); memset(&lifr, 0, sizeof(lifr)); strlcpy(lifr.lifr_name, ifname, sizeof(lifr.lifr_name)); lifr.lifr_mtu = mtu; if (ioctl(fd, SIOCSLIFMTU, &lifr) < 0) { close(fd); error("Couldn't set IPv6 MTU (%s): %m", ifr.ifr_name); } close(fd); #endif /* defined(PPP_WITH_IPV6CP) && defined(SOL2) */ } /* * ppp_get_mtu - get the MTU on the PPP network interface. */ int ppp_get_mtu(int unit) { struct ifreq ifr; memset (&ifr, '\0', sizeof (ifr)); strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name)); if (ioctl(ipfd, SIOCGIFMTU, (caddr_t) &ifr) < 0) { error("ioctl(SIOCGIFMTU): %m (line %d)", __LINE__); return 0; } return ifr.ifr_metric; } /* * tty_send_config - configure the transmit characteristics of * the ppp interface. */ void tty_send_config(int mtu, u_int32_t asyncmap, int pcomp, int accomp) { int cf[2]; link_mtu = mtu; if (strioctl(pppfd, PPPIO_MTU, &mtu, sizeof(mtu), 0) < 0) { if (hungup && errno == ENXIO) { ++error_count; return; } error("Couldn't set MTU: %m"); } if (fdmuxid >= 0) { if (!ppp_sync_serial()) { if (strioctl(pppfd, PPPIO_XACCM, &asyncmap, sizeof(asyncmap), 0) < 0) error("Couldn't set transmit ACCM: %m"); } cf[0] = (pcomp? COMP_PROT: 0) + (accomp? COMP_AC: 0); cf[1] = COMP_PROT | COMP_AC; if (any_compressions() && strioctl(pppfd, PPPIO_CFLAGS, cf, sizeof(cf), sizeof(int)) < 0) error("Couldn't set prot/AC compression: %m"); } } /* * tty_set_xaccm - set the extended transmit ACCM for the interface. */ void tty_set_xaccm(ext_accm accm) { if (ppp_sync_serial()) return; if (fdmuxid >= 0 && strioctl(pppfd, PPPIO_XACCM, accm, sizeof(ext_accm), 0) < 0) { if (!hungup || errno != ENXIO) warn("Couldn't set extended ACCM: %m"); } } /* * tty_recv_config - configure the receive-side characteristics of * the ppp interface. */ void tty_recv_config(int mru, u_int32_t asyncmap, int pcomp, int accomp) { int cf[2]; link_mru = mru; if (strioctl(pppfd, PPPIO_MRU, &mru, sizeof(mru), 0) < 0) { if (hungup && errno == ENXIO) { ++error_count; return; } error("Couldn't set MRU: %m"); } if (fdmuxid >= 0) { if (!ppp_sync_serial()) { if (strioctl(pppfd, PPPIO_RACCM, &asyncmap, sizeof(asyncmap), 0) < 0) error("Couldn't set receive ACCM: %m"); } cf[0] = (pcomp? DECOMP_PROT: 0) + (accomp? DECOMP_AC: 0); cf[1] = DECOMP_PROT | DECOMP_AC; if (any_compressions() && strioctl(pppfd, PPPIO_CFLAGS, cf, sizeof(cf), sizeof(int)) < 0) error("Couldn't set prot/AC decompression: %m"); } } /* * ccp_test - ask kernel whether a given compression method * is acceptable for use. */ int ccp_test(int unit, u_char *opt_ptr, int opt_len, int for_transmit) { if (strioctl(pppfd, (for_transmit? PPPIO_XCOMP: PPPIO_RCOMP), opt_ptr, opt_len, 0) >= 0) return 1; return (errno == ENOSR)? 0: -1; } /* * ccp_flags_set - inform kernel about the current state of CCP. */ void ccp_flags_set(int unit, int isopen, int isup) { int cf[2]; cf[0] = (isopen? CCP_ISOPEN: 0) + (isup? CCP_ISUP: 0); cf[1] = CCP_ISOPEN | CCP_ISUP | CCP_ERROR | CCP_FATALERROR; if (strioctl(pppfd, PPPIO_CFLAGS, cf, sizeof(cf), sizeof(int)) < 0) { if (!hungup || errno != ENXIO) error("Couldn't set kernel CCP state: %m"); } } /* * get_idle_time - return how long the link has been idle. */ int get_idle_time(int u, struct ppp_idle *ip) { return strioctl(pppfd, PPPIO_GIDLE, ip, 0, sizeof(struct ppp_idle)) >= 0; } /* * get_ppp_stats - return statistics for the link. */ int get_ppp_stats(int u, struct pppd_stats *stats) { struct ppp_stats s; if (!ppp_sync_serial() && strioctl(pppfd, PPPIO_GETSTAT, &s, 0, sizeof(s)) < 0) { error("Couldn't get link statistics: %m"); return 0; } stats->bytes_in = s.p.ppp_ibytes; stats->bytes_out = s.p.ppp_obytes; stats->pkts_in = s.p.ppp_ipackets; stats->pkts_out = s.p.ppp_opackets; return 1; } /* * ccp_fatal_error - returns 1 if decompression was disabled as a * result of an error detected after decompression of a packet, * 0 otherwise. This is necessary because of patent nonsense. */ int ccp_fatal_error(int unit) { int cf[2]; cf[0] = cf[1] = 0; if (strioctl(pppfd, PPPIO_CFLAGS, cf, sizeof(cf), sizeof(int)) < 0) { if (errno != ENXIO && errno != EINVAL) error("Couldn't get compression flags: %m"); return 0; } return cf[0] & CCP_FATALERROR; } /* * sifvjcomp - config tcp header compression */ int sifvjcomp(int u, int vjcomp, int xcidcomp, int xmaxcid) { int cf[2]; char maxcid[2]; if (vjcomp) { maxcid[0] = xcidcomp; maxcid[1] = 15; /* XXX should be rmaxcid */ if (strioctl(pppfd, PPPIO_VJINIT, maxcid, sizeof(maxcid), 0) < 0) { error("Couldn't initialize VJ compression: %m"); } } cf[0] = (vjcomp? COMP_VJC + DECOMP_VJC: 0) /* XXX this is wrong */ + (xcidcomp? COMP_VJCCID + DECOMP_VJCCID: 0); cf[1] = COMP_VJC + DECOMP_VJC + COMP_VJCCID + DECOMP_VJCCID; if (strioctl(pppfd, PPPIO_CFLAGS, cf, sizeof(cf), sizeof(int)) < 0) { if (vjcomp) error("Couldn't enable VJ compression: %m"); } return 1; } /* * sifup - Config the interface up and enable IP packets to pass. */ int sifup(int u) { struct ifreq ifr; strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); if (ioctl(ipfd, SIOCGIFFLAGS, &ifr) < 0) { error("Couldn't mark interface up (get): %m"); return 0; } ifr.ifr_flags |= IFF_UP; if (ioctl(ipfd, SIOCSIFFLAGS, &ifr) < 0) { error("Couldn't mark interface up (set): %m"); return 0; } if_is_up = 1; return 1; } /* * sifdown - Config the interface down and disable IP. */ int sifdown(int u) { struct ifreq ifr; if (ipmuxid < 0) return 1; strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); if (ioctl(ipfd, SIOCGIFFLAGS, &ifr) < 0) { error("Couldn't mark interface down (get): %m"); return 0; } ifr.ifr_flags &= ~IFF_UP; if (ioctl(ipfd, SIOCSIFFLAGS, &ifr) < 0) { error("Couldn't mark interface down (set): %m"); return 0; } if_is_up = 0; return 1; } /* * sifnpmode - Set the mode for handling packets for a given NP. */ int sifnpmode(int u, int proto, enum NPmode mode) { int npi[2]; npi[0] = proto; npi[1] = (int) mode; if (strioctl(pppfd, PPPIO_NPMODE, &npi, 2 * sizeof(int), 0) < 0) { error("ioctl(set NP %d mode to %d): %m", proto, mode); return 0; } return 1; } #if defined(SOL2) && defined(PPP_WITH_IPV6CP) /* * sif6up - Config the IPv6 interface up and enable IPv6 packets to pass. */ int sif6up(int u) { struct lifreq lifr; int fd; fd = socket(AF_INET6, SOCK_DGRAM, 0); if (fd < 0) { return 0; } memset(&lifr, 0, sizeof(lifr)); strlcpy(lifr.lifr_name, ifname, sizeof(lifr.lifr_name)); if (ioctl(fd, SIOCGLIFFLAGS, &lifr) < 0) { close(fd); return 0; } lifr.lifr_flags |= IFF_UP; strlcpy(lifr.lifr_name, ifname, sizeof(lifr.lifr_name)); if (ioctl(fd, SIOCSLIFFLAGS, &lifr) < 0) { close(fd); return 0; } if6_is_up = 1; close(fd); return 1; } /* * sifdown - Config the IPv6 interface down and disable IPv6. */ int sif6down(int u) { struct lifreq lifr; int fd; fd = socket(AF_INET6, SOCK_DGRAM, 0); if (fd < 0) return 0; memset(&lifr, 0, sizeof(lifr)); strlcpy(lifr.lifr_name, ifname, sizeof(lifr.lifr_name)); if (ioctl(fd, SIOCGLIFFLAGS, &lifr) < 0) { close(fd); return 0; } lifr.lifr_flags &= ~IFF_UP; strlcpy(lifr.lifr_name, ifname, sizeof(lifr.lifr_name)); if (ioctl(fd, SIOCGLIFFLAGS, &lifr) < 0) { close(fd); return 0; } if6_is_up = 0; close(fd); return 1; } /* * sif6addr - Config the interface with an IPv6 link-local address */ int sif6addr(int u, eui64_t o, eui64_t h) { struct lifreq lifr; struct sockaddr_storage laddr; struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)&laddr; int fd; fd = socket(AF_INET6, SOCK_DGRAM, 0); if (fd < 0) return 0; memset(&lifr, 0, sizeof(lifr)); strlcpy(lifr.lifr_name, ifname, sizeof(lifr.lifr_name)); /* * Do this because /dev/ppp responds to DL_PHYS_ADDR_REQ with * zero values, hence the interface token came to be zero too, * and without this, in.ndpd will complain */ IN6_LLTOKEN_FROM_EUI64(lifr, sin6, o); if (ioctl(fd, SIOCSLIFTOKEN, &lifr) < 0) { close(fd); return 0; } /* * Set the interface address and destination address */ IN6_LLADDR_FROM_EUI64(lifr, sin6, o); if (ioctl(fd, SIOCSLIFADDR, &lifr) < 0) { close(fd); return 0; } memset(&lifr, 0, sizeof(lifr)); strlcpy(lifr.lifr_name, ifname, sizeof(lifr.lifr_name)); IN6_LLADDR_FROM_EUI64(lifr, sin6, h); if (ioctl(fd, SIOCSLIFDSTADDR, &lifr) < 0) { close(fd); return 0; } return 1; } /* * cif6addr - Remove the IPv6 address from interface */ int cif6addr(int u, eui64_t o, eui64_t h) { return 1; } /* * sif6defaultroute - assign a default route through the address given. */ int sif6defaultroute(int u, eui64_t l, eui64_t g) { struct { struct rt_msghdr rtm; struct sockaddr_in6 dst; struct sockaddr_in6 gw; } rmsg; static int seq; int rtsock; #if defined(__USLC__) g = l; /* use the local address as gateway */ #endif memset(&rmsg, 0, sizeof(rmsg)); rmsg.rtm.rtm_msglen = sizeof (rmsg); rmsg.rtm.rtm_version = RTM_VERSION; rmsg.rtm.rtm_type = RTM_ADD; rmsg.rtm.rtm_flags = RTF_GATEWAY; rmsg.rtm.rtm_addrs = RTA_DST | RTA_GATEWAY; rmsg.rtm.rtm_pid = getpid(); rmsg.rtm.rtm_seq = seq++; rmsg.dst.sin6_family = AF_INET6; rmsg.gw.sin6_family = AF_INET6; IN6_SOCKADDR_FROM_EUI64(&rmsg.gw, g); rtsock = socket(PF_ROUTE, SOCK_RAW, 0); if (rtsock < 0) { error("Can't add default route: %m"); return 0; } if (write(rtsock, &rmsg, sizeof(rmsg)) < 0) error("Can't add default route: %m"); close(rtsock); default_route_gateway6 = g; return 1; } /* * cif6defaultroute - delete a default route through the address given. */ int cif6defaultroute(int u, eui64_t l, eui64_t g) { /* No need to do this on Solaris; the kernel deletes the route when the interface goes down. */ memset(&default_route_gateway6, 0, sizeof(default_route_gateway6)); return 1; } #endif /* defined(SOL2) && defined(PPP_WITH_IPV6CP) */ #define INET_ADDR(x) (((struct sockaddr_in *) &(x))->sin_addr.s_addr) /* * sifaddr - Config the interface IP addresses and netmask. */ int sifaddr(int u, u_int32_t o, u_int32_t h, u_int32_t m) { struct ifreq ifr; int ret = 1; memset(&ifr, 0, sizeof(ifr)); strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); ifr.ifr_addr.sa_family = AF_INET; INET_ADDR(ifr.ifr_addr) = m; if (ioctl(ipfd, SIOCSIFNETMASK, &ifr) < 0) { error("Couldn't set IP netmask: %m"); ret = 0; } ifr.ifr_addr.sa_family = AF_INET; INET_ADDR(ifr.ifr_addr) = o; if (ioctl(ipfd, SIOCSIFADDR, &ifr) < 0) { error("Couldn't set local IP address: %m"); ret = 0; } /* * On some systems, we have to explicitly set the point-to-point * flag bit before we can set a destination address. */ if (ioctl(ipfd, SIOCGIFFLAGS, &ifr) >= 0 && (ifr.ifr_flags & IFF_POINTOPOINT) == 0) { ifr.ifr_flags |= IFF_POINTOPOINT; if (ioctl(ipfd, SIOCSIFFLAGS, &ifr) < 0) { error("Couldn't mark interface pt-to-pt: %m"); ret = 0; } } ifr.ifr_dstaddr.sa_family = AF_INET; INET_ADDR(ifr.ifr_dstaddr) = h; if (ioctl(ipfd, SIOCSIFDSTADDR, &ifr) < 0) { error("Couldn't set remote IP address: %m"); ret = 0; } remote_addr = h; return ret; } /* * cifaddr - Clear the interface IP addresses, and delete routes * through the interface if possible. */ int cifaddr(int u, u_int32_t o, u_int32_t h) { #if defined(__USLC__) /* was: #if 0 */ cifroute(unit, ouraddr, hisaddr); if (ipmuxid >= 0) { notice("Removing ppp interface unit"); if (ioctl(ipfd, I_UNLINK, ipmuxid) < 0) { error("Can't remove ppp interface unit: %m"); return 0; } ipmuxid = -1; } #endif remote_addr = 0; return 1; } /* * sifdefaultroute - assign a default route through the address given. */ int sifdefaultroute(int u, u_int32_t l, u_int32_t g, bool replace) { struct rtentry rt; if (replace) { error("Replacing the default route is not implemented on Solaris yet"); return 0; } #if defined(__USLC__) g = l; /* use the local address as gateway */ #endif memset(&rt, 0, sizeof(rt)); rt.rt_dst.sa_family = AF_INET; INET_ADDR(rt.rt_dst) = 0; rt.rt_gateway.sa_family = AF_INET; INET_ADDR(rt.rt_gateway) = g; rt.rt_flags = RTF_GATEWAY; if (ioctl(ipfd, SIOCADDRT, &rt) < 0) { error("Can't add default route: %m"); return 0; } default_route_gateway = g; return 1; } /* * cifdefaultroute - delete a default route through the address given. */ int cifdefaultroute(int u, u_int32_t l, u_int32_t g) { struct rtentry rt; #if defined(__USLC__) g = l; /* use the local address as gateway */ #endif memset(&rt, 0, sizeof(rt)); rt.rt_dst.sa_family = AF_INET; INET_ADDR(rt.rt_dst) = 0; rt.rt_gateway.sa_family = AF_INET; INET_ADDR(rt.rt_gateway) = g; rt.rt_flags = RTF_GATEWAY; if (ioctl(ipfd, SIOCDELRT, &rt) < 0) { error("Can't delete default route: %m"); return 0; } default_route_gateway = 0; return 1; } /* * sifproxyarp - Make a proxy ARP entry for the peer. */ int sifproxyarp(int unit, u_int32_t hisaddr) { struct arpreq arpreq; memset(&arpreq, 0, sizeof(arpreq)); if (!get_ether_addr(hisaddr, &arpreq.arp_ha)) return 0; arpreq.arp_pa.sa_family = AF_INET; INET_ADDR(arpreq.arp_pa) = hisaddr; arpreq.arp_flags = ATF_PERM | ATF_PUBL; if (ioctl(ipfd, SIOCSARP, (caddr_t) &arpreq) < 0) { error("Couldn't set proxy ARP entry: %m"); return 0; } proxy_arp_addr = hisaddr; return 1; } /* * cifproxyarp - Delete the proxy ARP entry for the peer. */ int cifproxyarp(int unit, u_int32_t hisaddr) { struct arpreq arpreq; memset(&arpreq, 0, sizeof(arpreq)); arpreq.arp_pa.sa_family = AF_INET; INET_ADDR(arpreq.arp_pa) = hisaddr; if (ioctl(ipfd, SIOCDARP, (caddr_t)&arpreq) < 0) { error("Couldn't delete proxy ARP entry: %m"); return 0; } proxy_arp_addr = 0; return 1; } /* * get_ether_addr - get the hardware address of an interface on the * the same subnet as ipaddr. */ #define MAX_IFS 32 static int get_ether_addr(u_int32_t ipaddr, struct sockaddr *hwaddr) { struct ifreq *ifr, *ifend, ifreq; int nif; struct ifconf ifc; u_int32_t ina, mask; /* * Scan through the system's network interfaces. */ #ifdef SIOCGIFNUM if (ioctl(ipfd, SIOCGIFNUM, &nif) < 0) #endif nif = MAX_IFS; ifc.ifc_len = nif * sizeof(struct ifreq); ifc.ifc_buf = (caddr_t) malloc(ifc.ifc_len); if (ifc.ifc_buf == 0) return 0; if (ioctl(ipfd, SIOCGIFCONF, &ifc) < 0) { warn("Couldn't get system interface list: %m"); free(ifc.ifc_buf); return 0; } ifend = (struct ifreq *) (ifc.ifc_buf + ifc.ifc_len); for (ifr = ifc.ifc_req; ifr < ifend; ++ifr) { if (ifr->ifr_addr.sa_family != AF_INET) continue; /* * Check that the interface is up, and not point-to-point or loopback. */ strlcpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name)); if (ioctl(ipfd, SIOCGIFFLAGS, &ifreq) < 0) continue; if ((ifreq.ifr_flags & (IFF_UP|IFF_BROADCAST|IFF_POINTOPOINT|IFF_LOOPBACK|IFF_NOARP)) != (IFF_UP|IFF_BROADCAST)) continue; /* * Get its netmask and check that it's on the right subnet. */ if (ioctl(ipfd, SIOCGIFNETMASK, &ifreq) < 0) continue; ina = INET_ADDR(ifr->ifr_addr); mask = INET_ADDR(ifreq.ifr_addr); if ((ipaddr & mask) == (ina & mask)) break; } if (ifr >= ifend) { warn("No suitable interface found for proxy ARP"); free(ifc.ifc_buf); return 0; } info("found interface %s for proxy ARP", ifr->ifr_name); if (!get_hw_addr(ifr->ifr_name, ina, hwaddr)) { error("Couldn't get hardware address for %s", ifr->ifr_name); free(ifc.ifc_buf); return 0; } free(ifc.ifc_buf); return 1; } /* * get_hw_addr_dlpi - obtain the hardware address using DLPI */ static int get_hw_addr_dlpi(char *name, struct sockaddr *hwaddr) { char *q; int unit, iffd, adrlen; unsigned char *adrp; char ifdev[24]; struct { union DL_primitives prim; char space[64]; } reply; /* * We have to open the device and ask it for its hardware address. * First split apart the device name and unit. */ slprintf(ifdev, sizeof(ifdev), "/dev/%s", name); for (q = ifdev + strlen(ifdev); --q >= ifdev; ) if (!isdigit(*q)) break; unit = atoi(q+1); q[1] = 0; /* * Open the device and do a DLPI attach and phys_addr_req. */ iffd = open(ifdev, O_RDWR); if (iffd < 0) { error("Can't open %s: %m", ifdev); return 0; } if (dlpi_attach(iffd, unit) < 0 || dlpi_get_reply(iffd, &reply.prim, DL_OK_ACK, sizeof(reply)) < 0 || dlpi_info_req(iffd) < 0 || dlpi_get_reply(iffd, &reply.prim, DL_INFO_ACK, sizeof(reply)) < 0) { close(iffd); return 0; } adrlen = reply.prim.info_ack.dl_addr_length; adrp = (unsigned char *)&reply + reply.prim.info_ack.dl_addr_offset; #if DL_CURRENT_VERSION >= 2 if (reply.prim.info_ack.dl_sap_length < 0) adrlen += reply.prim.info_ack.dl_sap_length; else adrp += reply.prim.info_ack.dl_sap_length; #endif hwaddr->sa_family = AF_UNSPEC; memcpy(hwaddr->sa_data, adrp, adrlen); return 1; } /* * get_hw_addr - obtain the hardware address for a named interface. */ static int get_hw_addr(char *name, u_int32_t ina, struct sockaddr *hwaddr) { /* New way - get the address by doing an arp request. */ int s; struct arpreq req; s = socket(AF_INET, SOCK_DGRAM, 0); if (s < 0) return 0; memset(&req, 0, sizeof(req)); req.arp_pa.sa_family = AF_INET; INET_ADDR(req.arp_pa) = ina; if (ioctl(s, SIOCGARP, &req) < 0) { error("Couldn't get ARP entry for %s: %m", ip_ntoa(ina)); return 0; } *hwaddr = req.arp_ha; hwaddr->sa_family = AF_UNSPEC; return 1; } static int dlpi_attach(int fd, int ppa) { dl_attach_req_t req; struct strbuf buf; req.dl_primitive = DL_ATTACH_REQ; req.dl_ppa = ppa; buf.len = sizeof(req); buf.buf = (void *) &req; return putmsg(fd, &buf, NULL, RS_HIPRI); } static int dlpi_info_req(int fd) { dl_info_req_t req; struct strbuf buf; req.dl_primitive = DL_INFO_REQ; buf.len = sizeof(req); buf.buf = (void *) &req; return putmsg(fd, &buf, NULL, RS_HIPRI); } static int dlpi_get_reply(int fd, union DL_primitives *reply, int expected_prim, size_t maxlen) { struct strbuf buf; int flags, n; struct pollfd pfd; /* * Use poll to wait for a message with a timeout. */ pfd.fd = fd; pfd.events = POLLIN | POLLPRI; do { n = poll(&pfd, 1, 1000); } while (n == -1 && errno == EINTR && !ppp_signaled(SIGTERM)); if (n <= 0) return -1; /* * Get the reply. */ buf.maxlen = maxlen; buf.buf = (void *) reply; flags = 0; if (getmsg(fd, &buf, NULL, &flags) < 0) return -1; if (buf.len < sizeof(ulong)) { if (debug) dbglog("dlpi response short (len=%d)\n", buf.len); return -1; } if (reply->dl_primitive == expected_prim) return 0; if (debug) { if (reply->dl_primitive == DL_ERROR_ACK) { dbglog("dlpi error %d (unix errno %d) for prim %x\n", reply->error_ack.dl_errno, reply->error_ack.dl_unix_errno, reply->error_ack.dl_error_primitive); } else { dbglog("dlpi unexpected response prim %x\n", reply->dl_primitive); } } return -1; } /* * Return user specified netmask, modified by any mask we might determine * for address `addr' (in network byte order). * Here we scan through the system's list of interfaces, looking for * any non-point-to-point interfaces which might appear to be on the same * network as `addr'. If we find any, we OR in their netmask to the * user-specified netmask. */ u_int32_t GetMask(u_int32_t addr) { u_int32_t mask, nmask, ina; struct ifreq *ifr, *ifend, ifreq; int nif; struct ifconf ifc; addr = ntohl(addr); if (IN_CLASSA(addr)) /* determine network mask for address class */ nmask = IN_CLASSA_NET; else if (IN_CLASSB(addr)) nmask = IN_CLASSB_NET; else nmask = IN_CLASSC_NET; /* class D nets are disallowed by bad_ip_adrs */ mask = netmask | htonl(nmask); /* * Scan through the system's network interfaces. */ #ifdef SIOCGIFNUM if (ioctl(ipfd, SIOCGIFNUM, &nif) < 0) #endif nif = MAX_IFS; ifc.ifc_len = nif * sizeof(struct ifreq); ifc.ifc_buf = (caddr_t) malloc(ifc.ifc_len); if (ifc.ifc_buf == 0) return mask; if (ioctl(ipfd, SIOCGIFCONF, &ifc) < 0) { warn("Couldn't get system interface list: %m"); free(ifc.ifc_buf); return mask; } ifend = (struct ifreq *) (ifc.ifc_buf + ifc.ifc_len); for (ifr = ifc.ifc_req; ifr < ifend; ++ifr) { /* * Check the interface's internet address. */ if (ifr->ifr_addr.sa_family != AF_INET) continue; ina = INET_ADDR(ifr->ifr_addr); if ((ntohl(ina) & nmask) != (addr & nmask)) continue; /* * Check that the interface is up, and not point-to-point or loopback. */ strlcpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name)); if (ioctl(ipfd, SIOCGIFFLAGS, &ifreq) < 0) continue; if ((ifreq.ifr_flags & (IFF_UP|IFF_POINTOPOINT|IFF_LOOPBACK)) != IFF_UP) continue; /* * Get its netmask and OR it into our mask. */ if (ioctl(ipfd, SIOCGIFNETMASK, &ifreq) < 0) continue; mask |= INET_ADDR(ifreq.ifr_addr); } free(ifc.ifc_buf); return mask; } /* * logwtmp - write an accounting record to the /var/adm/wtmp file. */ void logwtmp(const char *line, const char *name, const char *host) { static struct utmpx utmpx; if (name[0] != 0) { /* logging in */ strncpy(utmpx.ut_user, name, sizeof(utmpx.ut_user)); strncpy(utmpx.ut_line, line, sizeof(utmpx.ut_line)); strncpy(utmpx.ut_host, host, sizeof(utmpx.ut_host)); if (*host != '\0') { utmpx.ut_syslen = strlen(host) + 1; if (utmpx.ut_syslen > sizeof(utmpx.ut_host)) utmpx.ut_syslen = sizeof(utmpx.ut_host); } utmpx.ut_pid = getpid(); utmpx.ut_type = USER_PROCESS; } else { utmpx.ut_type = DEAD_PROCESS; } gettimeofday(&utmpx.ut_tv, NULL); updwtmpx("/var/adm/wtmpx", &utmpx); } /* * get_host_seed - return the serial number of this machine. */ int get_host_seed(void) { char buf[32]; if (sysinfo(SI_HW_SERIAL, buf, sizeof(buf)) < 0) { error("sysinfo: %m"); return 0; } return (int) strtoul(buf, NULL, 16); } static int strioctl(int fd, int cmd, void *ptr, int ilen, int olen) { struct strioctl str; str.ic_cmd = cmd; str.ic_timout = 0; str.ic_len = ilen; str.ic_dp = ptr; if (ioctl(fd, I_STR, &str) == -1) return -1; if (str.ic_len != olen) dbglog("strioctl: expected %d bytes, got %d for cmd %x\n", olen, str.ic_len, cmd); return 0; } #if 0 /* * lock - create a lock file for the named lock device */ #define LOCK_PREFIX "/var/spool/locks/LK." static char lock_file[40]; /* name of lock file created */ int lock(char *dev) { int n, fd, pid; struct stat sbuf; char ascii_pid[12]; if (stat(dev, &sbuf) < 0) { error("Can't get device number for %s: %m", dev); return -1; } if ((sbuf.st_mode & S_IFMT) != S_IFCHR) { error("Can't lock %s: not a character device", dev); return -1; } slprintf(lock_file, sizeof(lock_file), "%s%03d.%03d.%03d", LOCK_PREFIX, major(sbuf.st_dev), major(sbuf.st_rdev), minor(sbuf.st_rdev)); while ((fd = open(lock_file, O_EXCL | O_CREAT | O_RDWR, 0644)) < 0) { if (errno == EEXIST && (fd = open(lock_file, O_RDONLY, 0)) >= 0) { /* Read the lock file to find out who has the device locked */ n = read(fd, ascii_pid, 11); if (n <= 0) { error("Can't read pid from lock file %s", lock_file); close(fd); } else { ascii_pid[n] = 0; pid = atoi(ascii_pid); if (pid > 0 && kill(pid, 0) == -1 && errno == ESRCH) { /* pid no longer exists - remove the lock file */ if (unlink(lock_file) == 0) { close(fd); notice("Removed stale lock on %s (pid %d)", dev, pid); continue; } else warn("Couldn't remove stale lock on %s", dev); } else notice("Device %s is locked by pid %d", dev, pid); } close(fd); } else error("Can't create lock file %s: %m", lock_file); lock_file[0] = 0; return -1; } slprintf(ascii_pid, sizeof(ascii_pid), "%10d\n", getpid()); write(fd, ascii_pid, 11); close(fd); return 1; } /* * unlock - remove our lockfile */ void unlock(void) { if (lock_file[0]) { unlink(lock_file); lock_file[0] = 0; } } #endif /* * cifroute - delete a route through the addresses given. */ int cifroute(int u, u_int32_t our, u_int32_t his) { struct rtentry rt; memset(&rt, 0, sizeof(rt)); rt.rt_dst.sa_family = AF_INET; INET_ADDR(rt.rt_dst) = his; rt.rt_gateway.sa_family = AF_INET; INET_ADDR(rt.rt_gateway) = our; rt.rt_flags = RTF_HOST; if (ioctl(ipfd, SIOCDELRT, &rt) < 0) { error("Can't delete route: %m"); return 0; } return 1; } /* * have_route_to - determine if the system has a route to the specified * IP address. Returns 0 if not, 1 if so, -1 if we can't tell. * `addr' is in network byte order. * For demand mode to work properly, we have to ignore routes * through our own interface. */ #ifndef T_CURRENT /* needed for Solaris 2.5 */ #define T_CURRENT MI_T_CURRENT #endif int have_route_to(u_int32_t addr) { #ifdef SOL2 int fd, r, flags, i; struct { struct T_optmgmt_req req; struct opthdr hdr; } req; union { struct T_optmgmt_ack ack; unsigned char space[64]; } ack; struct opthdr *rh; struct strbuf cbuf, dbuf; int nroutes; mib2_ipRouteEntry_t routes[8]; mib2_ipRouteEntry_t *rp; fd = open(mux_dev_name, O_RDWR); if (fd < 0) { warn("have_route_to: couldn't open %s: %m", mux_dev_name); return -1; } req.req.PRIM_type = T_OPTMGMT_REQ; req.req.OPT_offset = (char *) &req.hdr - (char *) &req; req.req.OPT_length = sizeof(req.hdr); req.req.MGMT_flags = T_CURRENT; req.hdr.level = MIB2_IP; req.hdr.name = 0; req.hdr.len = 0; cbuf.buf = (char *) &req; cbuf.len = sizeof(req); if (putmsg(fd, &cbuf, NULL, 0) == -1) { warn("have_route_to: putmsg: %m"); close(fd); return -1; } for (;;) { cbuf.buf = (char *) &ack; cbuf.maxlen = sizeof(ack); dbuf.buf = (char *) routes; dbuf.maxlen = sizeof(routes); flags = 0; r = getmsg(fd, &cbuf, &dbuf, &flags); if (r == -1) { warn("have_route_to: getmsg: %m"); close(fd); return -1; } if (cbuf.len < sizeof(struct T_optmgmt_ack) || ack.ack.PRIM_type != T_OPTMGMT_ACK || ack.ack.MGMT_flags != T_SUCCESS || ack.ack.OPT_length < sizeof(struct opthdr)) { dbglog("have_route_to: bad message len=%d prim=%d", cbuf.len, ack.ack.PRIM_type); close(fd); return -1; } rh = (struct opthdr *) ((char *)&ack + ack.ack.OPT_offset); if (rh->level == 0 && rh->name == 0) break; if (rh->level != MIB2_IP || rh->name != MIB2_IP_21) { while (r == MOREDATA) r = getmsg(fd, NULL, &dbuf, &flags); continue; } for (;;) { nroutes = dbuf.len / sizeof(mib2_ipRouteEntry_t); for (rp = routes, i = 0; i < nroutes; ++i, ++rp) { if (rp->ipRouteMask != ~0) { dbglog("have_route_to: dest=%x gw=%x mask=%x\n", rp->ipRouteDest, rp->ipRouteNextHop, rp->ipRouteMask); if (((addr ^ rp->ipRouteDest) & rp->ipRouteMask) == 0 && rp->ipRouteNextHop != remote_addr) return 1; } } if (r == 0) break; r = getmsg(fd, NULL, &dbuf, &flags); } } close(fd); return 0; #else return -1; #endif /* SOL2 */ } /* * get_pty - get a pty master/slave pair and chown the slave side to * the uid given. Assumes slave_name points to MAXPATHLEN bytes of space. */ int get_pty(int *master_fdp, int *slave_fdp, char *slave_name, int uid) { int mfd, sfd; char *pty_name; mfd = open("/dev/ptmx", O_RDWR); if (mfd < 0) { error("Couldn't open pty master: %m"); return 0; } pty_name = ptsname(mfd); if (pty_name == NULL) { error("Couldn't get name of pty slave"); close(mfd); return 0; } if (chown(pty_name, uid, -1) < 0) warn("Couldn't change owner of pty slave: %m"); if (chmod(pty_name, S_IRUSR | S_IWUSR) < 0) warn("Couldn't change permissions on pty slave: %m"); if (unlockpt(mfd) < 0) warn("Couldn't unlock pty slave: %m"); sfd = open(pty_name, O_RDWR); if (sfd < 0) { error("Couldn't open pty slave %s: %m", pty_name); close(mfd); return 0; } if (ioctl(sfd, I_PUSH, "ptem") < 0) warn("Couldn't push ptem module on pty slave: %m"); dbglog("Using %s", pty_name); strlcpy(slave_name, pty_name, MAXPATHLEN); *master_fdp = mfd; *slave_fdp = sfd; return 1; } /******************************************************************** * * get_time - Get current time, monotonic if possible. */ int ppp_get_time(struct timeval *tv) { return gettimeofday(tv, NULL); } ppp-2.5.0/pppd/chap_ms.c0000644000175000017500000007166014407475306012003 00000000000000/* * chap_ms.c - Microsoft MS-CHAP compatible implementation. * * Copyright (c) 1995 Eric Rosenquist. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The name(s) of the authors of this software must not be used to * endorse or promote products derived from this software without * prior written permission. * * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /* * Modifications by Lauri Pesonen / lpesonen@clinet.fi, april 1997 * * Implemented LANManager type password response to MS-CHAP challenges. * Now pppd provides both NT style and LANMan style blocks, and the * prefered is set by option "ms-lanman". Default is to use NT. * The hash text (StdText) was taken from Win95 RASAPI32.DLL. * * You should also use DOMAIN\\USERNAME as described in README.MSCHAP80 */ /* * Modifications by Frank Cusack, frank@google.com, March 2002. * * Implemented MS-CHAPv2 functionality, heavily based on sample * implementation in RFC 2759. Implemented MPPE functionality, * heavily based on sample implementation in RFC 3079. * * Copyright (c) 2002 Google, Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The name(s) of the authors of this software must not be used to * endorse or promote products derived from this software without * prior written permission. * * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * */ #define RCSID "$Id: chap_ms.c,v 1.38 2007/12/01 20:10:51 carlsonj Exp $" #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include #if defined(SOL2) #include #else #include #endif #include "pppd-private.h" #include "options.h" #include "chap.h" #include "chap_ms.h" #include "magic.h" #include "mppe.h" #include "crypto.h" #include "crypto_ms.h" #ifdef UNIT_TEST #undef PPP_WITH_MPPE #endif static void ascii2unicode (char[], int, u_char[]); static void NTPasswordHash (u_char *, int, unsigned char *); static int ChallengeResponse (u_char *, u_char *, u_char*); static void ChapMS_NT (u_char *, char *, int, u_char[24]); static void ChapMS2_NT (u_char *, u_char[16], char *, char *, int, u_char[24]); static void GenerateAuthenticatorResponsePlain (char*, int, u_char[24], u_char[16], u_char *, char *, u_char[41]); #ifdef PPP_WITH_MSLANMAN static void ChapMS_LANMan (u_char *, char *, int, u_char *); #endif #ifdef PPP_WITH_MSLANMAN bool ms_lanman = 0; /* Use LanMan password instead of NT */ /* Has meaning only with MS-CHAP challenges */ #endif #ifdef PPP_WITH_MPPE #ifdef DEBUGMPPEKEY /* For MPPE debug */ /* Use "[]|}{?/><,`!2&&(" (sans quotes) for RFC 3079 MS-CHAPv2 test value */ static char *mschap_challenge = NULL; /* Use "!@\#$%^&*()_+:3|~" (sans quotes, backslash is to escape #) for ... */ static char *mschap2_peer_challenge = NULL; #endif #include "fsm.h" /* Need to poke MPPE options */ #include "ccp.h" #endif /* * Command-line options. */ static struct option chapms_option_list[] = { #ifdef PPP_WITH_MSLANMAN { "ms-lanman", o_bool, &ms_lanman, "Use LanMan passwd when using MS-CHAP", 1 }, #endif #ifdef DEBUGMPPEKEY { "mschap-challenge", o_string, &mschap_challenge, "specify CHAP challenge" }, { "mschap2-peer-challenge", o_string, &mschap2_peer_challenge, "specify CHAP peer challenge" }, #endif { NULL } }; /* * chapms_generate_challenge - generate a challenge for MS-CHAP. * For MS-CHAP the challenge length is fixed at 8 bytes. * The length goes in challenge[0] and the actual challenge starts * at challenge[1]. */ static void chapms_generate_challenge(unsigned char *challenge) { *challenge++ = 8; #ifdef DEBUGMPPEKEY if (mschap_challenge && strlen(mschap_challenge) == 8) memcpy(challenge, mschap_challenge, 8); else #endif random_bytes(challenge, 8); } static void chapms2_generate_challenge(unsigned char *challenge) { *challenge++ = 16; #ifdef DEBUGMPPEKEY if (mschap_challenge && strlen(mschap_challenge) == 16) memcpy(challenge, mschap_challenge, 16); else #endif random_bytes(challenge, 16); } static int chapms_verify_response(int id, char *name, unsigned char *secret, int secret_len, unsigned char *challenge, unsigned char *response, char *message, int message_space) { unsigned char md[MS_CHAP_RESPONSE_LEN]; int diff; int challenge_len, response_len; challenge_len = *challenge++; /* skip length, is 8 */ response_len = *response++; if (response_len != MS_CHAP_RESPONSE_LEN) goto bad; #ifndef PPP_WITH_MSLANMAN if (!response[MS_CHAP_USENT]) { /* Should really propagate this into the error packet. */ notice("Peer request for LANMAN auth not supported"); goto bad; } #endif /* Generate the expected response. */ ChapMS(challenge, (char *)secret, secret_len, md); #ifdef PPP_WITH_MSLANMAN /* Determine which part of response to verify against */ if (!response[MS_CHAP_USENT]) diff = memcmp(&response[MS_CHAP_LANMANRESP], &md[MS_CHAP_LANMANRESP], MS_CHAP_LANMANRESP_LEN); else #endif diff = memcmp(&response[MS_CHAP_NTRESP], &md[MS_CHAP_NTRESP], MS_CHAP_NTRESP_LEN); if (diff == 0) { slprintf(message, message_space, "Access granted"); return 1; } bad: /* See comments below for MS-CHAP V2 */ slprintf(message, message_space, "E=691 R=1 C=%0.*B V=0", challenge_len, challenge); return 0; } static int chapms2_verify_response(int id, char *name, unsigned char *secret, int secret_len, unsigned char *challenge, unsigned char *response, char *message, int message_space) { unsigned char md[MS_CHAP2_RESPONSE_LEN]; char saresponse[MS_AUTH_RESPONSE_LENGTH+1]; int challenge_len, response_len; challenge_len = *challenge++; /* skip length, is 16 */ response_len = *response++; if (response_len != MS_CHAP2_RESPONSE_LEN) goto bad; /* not even the right length */ /* Generate the expected response and our mutual auth. */ ChapMS2(challenge, &response[MS_CHAP2_PEER_CHALLENGE], name, (char *)secret, secret_len, md, (unsigned char *)saresponse, MS_CHAP2_AUTHENTICATOR); /* compare MDs and send the appropriate status */ /* * Per RFC 2759, success message must be formatted as * "S= M=" * where * is the Authenticator Response (mutual auth) * is a text message * * However, some versions of Windows (win98 tested) do not know * about the M= part (required per RFC 2759) and flag * it as an error (reported incorrectly as an encryption error * to the user). Since the RFC requires it, and it can be * useful information, we supply it if the peer is a conforming * system. Luckily (?), win98 sets the Flags field to 0x04 * (contrary to RFC requirements) so we can use that to * distinguish between conforming and non-conforming systems. * * Special thanks to Alex Swiridov for * help debugging this. */ if (memcmp(&md[MS_CHAP2_NTRESP], &response[MS_CHAP2_NTRESP], MS_CHAP2_NTRESP_LEN) == 0) { if (response[MS_CHAP2_FLAGS]) slprintf(message, message_space, "S=%s", saresponse); else slprintf(message, message_space, "S=%s M=%s", saresponse, "Access granted"); return 1; } bad: /* * Failure message must be formatted as * "E=e R=r C=c V=v M=m" * where * e = error code (we use 691, ERROR_AUTHENTICATION_FAILURE) * r = retry (we use 1, ok to retry) * c = challenge to use for next response, we reuse previous * v = Change Password version supported, we use 0 * m = text message * * The M=m part is only for MS-CHAPv2. Neither win2k nor * win98 (others untested) display the message to the user anyway. * They also both ignore the E=e code. * * Note that it's safe to reuse the same challenge as we don't * actually accept another response based on the error message * (and no clients try to resend a response anyway). * * Basically, this whole bit is useless code, even the small * implementation here is only because of overspecification. */ slprintf(message, message_space, "E=691 R=1 C=%0.*B V=0 M=%s", challenge_len, challenge, "Access denied"); return 0; } static void chapms_make_response(unsigned char *response, int id, char *our_name, unsigned char *challenge, char *secret, int secret_len, unsigned char *private) { challenge++; /* skip length, should be 8 */ *response++ = MS_CHAP_RESPONSE_LEN; ChapMS(challenge, secret, secret_len, response); } struct chapms2_response_cache_entry { int id; unsigned char challenge[16]; unsigned char response[MS_CHAP2_RESPONSE_LEN]; unsigned char auth_response[MS_AUTH_RESPONSE_LENGTH]; }; #define CHAPMS2_MAX_RESPONSE_CACHE_SIZE 10 static struct chapms2_response_cache_entry chapms2_response_cache[CHAPMS2_MAX_RESPONSE_CACHE_SIZE]; static int chapms2_response_cache_next_index = 0; static int chapms2_response_cache_size = 0; static void chapms2_add_to_response_cache(int id, unsigned char *challenge, unsigned char *response, unsigned char *auth_response) { int i = chapms2_response_cache_next_index; chapms2_response_cache[i].id = id; memcpy(chapms2_response_cache[i].challenge, challenge, 16); memcpy(chapms2_response_cache[i].response, response, MS_CHAP2_RESPONSE_LEN); memcpy(chapms2_response_cache[i].auth_response, auth_response, MS_AUTH_RESPONSE_LENGTH); chapms2_response_cache_next_index = (i + 1) % CHAPMS2_MAX_RESPONSE_CACHE_SIZE; if (chapms2_response_cache_next_index > chapms2_response_cache_size) chapms2_response_cache_size = chapms2_response_cache_next_index; dbglog("added response cache entry %d", i); } static struct chapms2_response_cache_entry* chapms2_find_in_response_cache(int id, unsigned char *challenge, unsigned char *auth_response) { int i; for (i = 0; i < chapms2_response_cache_size; i++) { if (id == chapms2_response_cache[i].id && (!challenge || memcmp(challenge, chapms2_response_cache[i].challenge, 16) == 0) && (!auth_response || memcmp(auth_response, chapms2_response_cache[i].auth_response, MS_AUTH_RESPONSE_LENGTH) == 0)) { dbglog("response found in cache (entry %d)", i); return &chapms2_response_cache[i]; } } return NULL; /* not found */ } static void chapms2_make_response(unsigned char *response, int id, char *our_name, unsigned char *challenge, char *secret, int secret_len, unsigned char *private) { const struct chapms2_response_cache_entry *cache_entry; unsigned char auth_response[MS_AUTH_RESPONSE_LENGTH+1]; challenge++; /* skip length, should be 16 */ *response++ = MS_CHAP2_RESPONSE_LEN; cache_entry = chapms2_find_in_response_cache(id, challenge, NULL); if (cache_entry) { memcpy(response, cache_entry->response, MS_CHAP2_RESPONSE_LEN); return; } ChapMS2(challenge, #ifdef DEBUGMPPEKEY mschap2_peer_challenge, #else NULL, #endif our_name, secret, secret_len, response, auth_response, MS_CHAP2_AUTHENTICATEE); chapms2_add_to_response_cache(id, challenge, response, auth_response); } static int chapms2_check_success(int id, unsigned char *msg, int len) { if ((len < MS_AUTH_RESPONSE_LENGTH + 2) || strncmp((char *)msg, "S=", 2) != 0) { /* Packet does not start with "S=" */ error("MS-CHAPv2 Success packet is badly formed."); return 0; } msg += 2; len -= 2; if (len < MS_AUTH_RESPONSE_LENGTH || !chapms2_find_in_response_cache(id, NULL /* challenge */, msg)) { /* Authenticator Response did not match expected. */ error("MS-CHAPv2 mutual authentication failed."); return 0; } /* Authenticator Response matches. */ msg += MS_AUTH_RESPONSE_LENGTH; /* Eat it */ len -= MS_AUTH_RESPONSE_LENGTH; if ((len >= 3) && !strncmp((char *)msg, " M=", 3)) { msg += 3; /* Eat the delimiter */ } else if ((len >= 2) && !strncmp((char *)msg, "M=", 2)) { msg += 2; /* Eat the delimiter */ } else if (len) { /* Packet has extra text which does not begin " M=" */ error("MS-CHAPv2 Success packet is badly formed."); return 0; } return 1; } static void chapms_handle_failure(unsigned char *inp, int len) { int err; char *p, *msg; /* We want a null-terminated string for strxxx(). */ msg = malloc(len + 1); if (!msg) { notice("Out of memory in chapms_handle_failure"); return; } BCOPY(inp, msg, len); msg[len] = 0; p = msg; /* * Deal with MS-CHAP formatted failure messages; just print the * M= part (if any). For MS-CHAP we're not really supposed * to use M=, but it shouldn't hurt. See * chapms[2]_verify_response. */ if (!strncmp(p, "E=", 2)) err = strtol(p+2, NULL, 10); /* Remember the error code. */ else goto print_msg; /* Message is badly formatted. */ if (len && ((p = strstr(p, " M=")) != NULL)) { /* M= field found. */ p += 3; } else { /* No M=; use the error code. */ switch (err) { case MS_CHAP_ERROR_RESTRICTED_LOGON_HOURS: p = "E=646 Restricted logon hours"; break; case MS_CHAP_ERROR_ACCT_DISABLED: p = "E=647 Account disabled"; break; case MS_CHAP_ERROR_PASSWD_EXPIRED: p = "E=648 Password expired"; break; case MS_CHAP_ERROR_NO_DIALIN_PERMISSION: p = "E=649 No dialin permission"; break; case MS_CHAP_ERROR_AUTHENTICATION_FAILURE: p = "E=691 Authentication failure"; break; case MS_CHAP_ERROR_CHANGING_PASSWORD: /* Should never see this, we don't support Change Password. */ p = "E=709 Error changing password"; break; default: free(msg); error("Unknown MS-CHAP authentication failure: %.*v", len, inp); return; } } print_msg: if (p != NULL) error("MS-CHAP authentication failed: %v", p); free(msg); } static int ChallengeResponse(u_char *challenge, u_char *PasswordHash, u_char *response) { u_char ZPasswordHash[24]; PPP_CIPHER_CTX *ctx; BZERO(ZPasswordHash, sizeof(ZPasswordHash)); BCOPY(PasswordHash, ZPasswordHash, MD4_DIGEST_LENGTH); #if 0 dbglog("ChallengeResponse - ZPasswordHash %.*B", sizeof(ZPasswordHash), ZPasswordHash); #endif if (DesEncrypt(challenge, ZPasswordHash + 0, response + 0) && DesEncrypt(challenge, ZPasswordHash + 7, response + 8) && DesEncrypt(challenge, ZPasswordHash + 14, response + 16)) return 1; #if 0 dbglog("ChallengeResponse - response %.24B", response); #endif return 0; } void ChallengeHash(u_char PeerChallenge[16], u_char *rchallenge, char *username, u_char Challenge[8]) { PPP_MD_CTX* ctx; u_char hash[SHA_DIGEST_LENGTH]; int hash_len; const char *user; /* remove domain from "domain\username" */ if ((user = strrchr(username, '\\')) != NULL) ++user; else user = username; ctx = PPP_MD_CTX_new(); if (ctx != NULL) { if (PPP_DigestInit(ctx, PPP_sha1())) { if (PPP_DigestUpdate(ctx, PeerChallenge, 16)) { if (PPP_DigestUpdate(ctx, rchallenge, 16)) { if (PPP_DigestUpdate(ctx, user, strlen(user))) { hash_len = SHA_DIGEST_LENGTH; if (PPP_DigestFinal(ctx, hash, &hash_len)) { BCOPY(hash, Challenge, 8); } } } } } PPP_MD_CTX_free(ctx); } } /* * Convert the ASCII version of the password to Unicode. * This implicitly supports 8-bit ISO8859/1 characters. * This gives us the little-endian representation, which * is assumed by all M$ CHAP RFCs. (Unicode byte ordering * is machine-dependent.) */ static void ascii2unicode(char ascii[], int ascii_len, u_char unicode[]) { int i; BZERO(unicode, ascii_len * 2); for (i = 0; i < ascii_len; i++) unicode[i * 2] = (u_char) ascii[i]; } static void NTPasswordHash(u_char *secret, int secret_len, unsigned char* hash) { PPP_MD_CTX* ctx = PPP_MD_CTX_new(); if (ctx != NULL) { if (PPP_DigestInit(ctx, PPP_md4())) { if (PPP_DigestUpdate(ctx, secret, secret_len)) { int hash_len = MD4_DIGEST_LENGTH; PPP_DigestFinal(ctx, hash, &hash_len); } } PPP_MD_CTX_free(ctx); } } static void ChapMS_NT(u_char *rchallenge, char *secret, int secret_len, u_char NTResponse[24]) { u_char unicodePassword[MAX_NT_PASSWORD * 2]; u_char PasswordHash[MD4_DIGEST_LENGTH]; /* Hash the Unicode version of the secret (== password). */ ascii2unicode(secret, secret_len, unicodePassword); NTPasswordHash(unicodePassword, secret_len * 2, PasswordHash); ChallengeResponse(rchallenge, PasswordHash, NTResponse); } static void ChapMS2_NT(u_char *rchallenge, u_char PeerChallenge[16], char *username, char *secret, int secret_len, u_char NTResponse[24]) { u_char unicodePassword[MAX_NT_PASSWORD * 2]; u_char PasswordHash[MD4_DIGEST_LENGTH]; u_char Challenge[8]; ChallengeHash(PeerChallenge, rchallenge, username, Challenge); /* Hash the Unicode version of the secret (== password). */ ascii2unicode(secret, secret_len, unicodePassword); NTPasswordHash(unicodePassword, secret_len * 2, PasswordHash); ChallengeResponse(Challenge, PasswordHash, NTResponse); } #ifdef PPP_WITH_MSLANMAN static u_char *StdText = (u_char *)"KGS!@#$%"; /* key from rasapi32.dll */ static void ChapMS_LANMan(u_char *rchallenge, char *secret, int secret_len, unsigned char *response) { int i; u_char UcasePassword[MAX_NT_PASSWORD]; /* max is actually 14 */ u_char PasswordHash[MD4_DIGEST_LENGTH]; /* LANMan password is case insensitive */ BZERO(UcasePassword, sizeof(UcasePassword)); for (i = 0; i < secret_len; i++) UcasePassword[i] = (u_char)toupper(secret[i]); if (DesEncrypt(StdText, UcasePassword + 0, PasswordHash + 0) && DesEncrypt(StdText, UcasePassword + 7, PasswordHash + 8)) { ChallengeResponse(rchallenge, PasswordHash, &response[MS_CHAP_LANMANRESP]); } } #endif void GenerateAuthenticatorResponse(unsigned char* PasswordHashHash, unsigned char *NTResponse, unsigned char *PeerChallenge, unsigned char *rchallenge, char *username, unsigned char *authResponse) { /* * "Magic" constants used in response generation, from RFC 2759. */ u_char Magic1[39] = /* "Magic server to client signing constant" */ { 0x4D, 0x61, 0x67, 0x69, 0x63, 0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x74, 0x6F, 0x20, 0x63, 0x6C, 0x69, 0x65, 0x6E, 0x74, 0x20, 0x73, 0x69, 0x67, 0x6E, 0x69, 0x6E, 0x67, 0x20, 0x63, 0x6F, 0x6E, 0x73, 0x74, 0x61, 0x6E, 0x74 }; u_char Magic2[41] = /* "Pad to make it do more than one iteration" */ { 0x50, 0x61, 0x64, 0x20, 0x74, 0x6F, 0x20, 0x6D, 0x61, 0x6B, 0x65, 0x20, 0x69, 0x74, 0x20, 0x64, 0x6F, 0x20, 0x6D, 0x6F, 0x72, 0x65, 0x20, 0x74, 0x68, 0x61, 0x6E, 0x20, 0x6F, 0x6E, 0x65, 0x20, 0x69, 0x74, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6F, 0x6E }; int i; PPP_MD_CTX *ctx; u_char Digest[SHA_DIGEST_LENGTH] = {}; int hash_len; u_char Challenge[8]; ctx = PPP_MD_CTX_new(); if (ctx != NULL) { if (PPP_DigestInit(ctx, PPP_sha1())) { if (PPP_DigestUpdate(ctx, PasswordHashHash, MD4_DIGEST_LENGTH)) { if (PPP_DigestUpdate(ctx, NTResponse, 24)) { if (PPP_DigestUpdate(ctx, Magic1, sizeof(Magic1))) { hash_len = sizeof(Digest); PPP_DigestFinal(ctx, Digest, &hash_len); } } } } PPP_MD_CTX_free(ctx); } ChallengeHash(PeerChallenge, rchallenge, username, Challenge); ctx = PPP_MD_CTX_new(); if (ctx != NULL) { if (PPP_DigestInit(ctx, PPP_sha1())) { if (PPP_DigestUpdate(ctx, Digest, sizeof(Digest))) { if (PPP_DigestUpdate(ctx, Challenge, sizeof(Challenge))) { if (PPP_DigestUpdate(ctx, Magic2, sizeof(Magic2))) { hash_len = sizeof(Digest); PPP_DigestFinal(ctx, Digest, &hash_len); } } } } PPP_MD_CTX_free(ctx); } /* Convert to ASCII hex string. */ for (i = 0; i < MAX((MS_AUTH_RESPONSE_LENGTH / 2), sizeof(Digest)); i++) { sprintf((char *)&authResponse[i * 2], "%02X", Digest[i]); } } static void GenerateAuthenticatorResponsePlain (char *secret, int secret_len, u_char NTResponse[24], u_char PeerChallenge[16], u_char *rchallenge, char *username, u_char authResponse[MS_AUTH_RESPONSE_LENGTH+1]) { u_char unicodePassword[MAX_NT_PASSWORD * 2]; u_char PasswordHash[MD4_DIGEST_LENGTH]; u_char PasswordHashHash[MD4_DIGEST_LENGTH]; /* Hash (x2) the Unicode version of the secret (== password). */ ascii2unicode(secret, secret_len, unicodePassword); NTPasswordHash(unicodePassword, secret_len * 2, PasswordHash); NTPasswordHash(PasswordHash, sizeof(PasswordHash), PasswordHashHash); GenerateAuthenticatorResponse(PasswordHashHash, NTResponse, PeerChallenge, rchallenge, username, authResponse); } #ifdef PPP_WITH_MPPE /* * Set mppe_xxxx_key from MS-CHAP credentials. (see RFC 3079) */ static void Set_Start_Key(u_char *rchallenge, char *secret, int secret_len) { u_char unicodePassword[MAX_NT_PASSWORD * 2]; u_char PasswordHash[MD4_DIGEST_LENGTH]; u_char PasswordHashHash[MD4_DIGEST_LENGTH]; /* Hash (x2) the Unicode version of the secret (== password). */ ascii2unicode(secret, secret_len, unicodePassword); NTPasswordHash(unicodePassword, secret_len * 2, PasswordHash); NTPasswordHash(PasswordHash, sizeof(PasswordHash), PasswordHashHash); mppe_set_chapv1(rchallenge, PasswordHashHash); } /* * Set mppe_xxxx_key from MS-CHAPv2 credentials. (see RFC 3079) */ static void SetMasterKeys(char *secret, int secret_len, u_char NTResponse[24], int IsServer) { u_char unicodePassword[MAX_NT_PASSWORD * 2]; u_char PasswordHash[MD4_DIGEST_LENGTH]; u_char PasswordHashHash[MD4_DIGEST_LENGTH]; /* Hash (x2) the Unicode version of the secret (== password). */ ascii2unicode(secret, secret_len, unicodePassword); NTPasswordHash(unicodePassword, secret_len * 2, PasswordHash); NTPasswordHash(PasswordHash, sizeof(PasswordHash), PasswordHashHash); mppe_set_chapv2(PasswordHashHash, NTResponse, IsServer); } #endif /* PPP_WITH_MPPE */ void ChapMS(u_char *rchallenge, char *secret, int secret_len, unsigned char *response) { BZERO(response, MS_CHAP_RESPONSE_LEN); ChapMS_NT(rchallenge, secret, secret_len, &response[MS_CHAP_NTRESP]); #ifdef PPP_WITH_MSLANMAN ChapMS_LANMan(rchallenge, secret, secret_len, &response[MS_CHAP_LANMANRESP]); /* preferred method is set by option */ response[MS_CHAP_USENT] = !ms_lanman; #else response[MS_CHAP_USENT] = 1; #endif #ifdef PPP_WITH_MPPE Set_Start_Key(rchallenge, secret, secret_len); #endif } /* * If PeerChallenge is NULL, one is generated and the PeerChallenge * field of response is filled in. Call this way when generating a response. * If PeerChallenge is supplied, it is copied into the PeerChallenge field. * Call this way when verifying a response (or debugging). * Do not call with PeerChallenge = response. * * The PeerChallenge field of response is then used for calculation of the * Authenticator Response. */ void ChapMS2(unsigned char *rchallenge, unsigned char *PeerChallenge, char *user, char *secret, int secret_len, unsigned char *response, u_char authResponse[], int authenticator) { /* ARGSUSED */ u_char *p = &response[MS_CHAP2_PEER_CHALLENGE]; int i; BZERO(response, MS_CHAP2_RESPONSE_LEN); /* Generate the Peer-Challenge if requested, or copy it if supplied. */ if (!PeerChallenge) for (i = 0; i < MS_CHAP2_PEER_CHAL_LEN; i++) *p++ = (u_char) (drand48() * 0xff); else BCOPY(PeerChallenge, &response[MS_CHAP2_PEER_CHALLENGE], MS_CHAP2_PEER_CHAL_LEN); /* Generate the NT-Response */ ChapMS2_NT(rchallenge, &response[MS_CHAP2_PEER_CHALLENGE], user, secret, secret_len, &response[MS_CHAP2_NTRESP]); /* Generate the Authenticator Response. */ GenerateAuthenticatorResponsePlain(secret, secret_len, &response[MS_CHAP2_NTRESP], &response[MS_CHAP2_PEER_CHALLENGE], rchallenge, user, authResponse); #ifdef PPP_WITH_MPPE SetMasterKeys(secret, secret_len, &response[MS_CHAP2_NTRESP], authenticator); #endif } static struct chap_digest_type chapms_digest = { CHAP_MICROSOFT, /* code */ chapms_generate_challenge, chapms_verify_response, chapms_make_response, NULL, /* check_success */ chapms_handle_failure, }; static struct chap_digest_type chapms2_digest = { CHAP_MICROSOFT_V2, /* code */ chapms2_generate_challenge, chapms2_verify_response, chapms2_make_response, chapms2_check_success, chapms_handle_failure, }; #ifndef UNIT_TEST void chapms_init(void) { chap_register_digest(&chapms_digest); chap_register_digest(&chapms2_digest); ppp_add_options(chapms_option_list); } #else #include int debug = 1; int error_count = 0; int unsuccess = 0; void random_bytes(unsigned char *bytes, int len) { int i = 0; srand(time(NULL)); while (i < len) { bytes[i++] = (unsigned char) rand(); } } int test_chap_v1(void) { char *secret = "MyPw"; unsigned char challenge[8] = { 0x10, 0x2D, 0xB5, 0xDF, 0x08, 0x5D, 0x30, 0x41 }; unsigned char response[MS_CHAP_RESPONSE_LEN] = { }; unsigned char result[MS_CHAP_RESPONSE_LEN] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4E, 0x9D, 0x3C, 0x8F, 0x9C, 0xFD, 0x38, 0x5D, 0x5B, 0xF4, 0xD3, 0x24, 0x67, 0x91, 0x95, 0x6C, 0xA4, 0xC3, 0x51, 0xAB, 0x40, 0x9A, 0x3D, 0x61, 0x01 }; ChapMS(challenge, secret, strlen(secret), response); return memcmp(response, result, MS_CHAP_RESPONSE_LEN); } int test_chap_v2(void) { char *secret = "clientPass"; char *name = "User"; char saresponse[MS_AUTH_RESPONSE_LENGTH+1]; char *saresult = "407A5589115FD0D6209F510FE9C04566932CDA56"; unsigned char authenticator[16] = { 0x5B, 0x5D, 0x7C, 0x7D, 0x7B, 0x3F, 0x2F, 0x3E, 0x3C, 0x2C, 0x60, 0x21, 0x32, 0x26, 0x26, 0x28 }; unsigned char peerchallenge[16] = { 0x21, 0x40, 0x23, 0x24, 0x25, 0x5E, 0x26, 0x2A, 0x28, 0x29, 0x5F, 0x2B, 0x3A, 0x33, 0x7C, 0x7E }; unsigned char result[MS_CHAP_NTRESP_LEN] = { 0x82, 0x30, 0x9E, 0xCD, 0x8D, 0x70, 0x8B, 0x5E, 0xA0, 0x8F, 0xAA, 0x39, 0x81, 0xCD, 0x83, 0x54, 0x42, 0x33, 0x11, 0x4A, 0x3D, 0x85, 0xD6, 0xDF }; unsigned char response[MS_CHAP2_RESPONSE_LEN] = { }; ChapMS2(authenticator, peerchallenge, name, secret, strlen(secret), response, (unsigned char *)saresponse, MS_CHAP2_AUTHENTICATOR); return memcmp(&response[MS_CHAP2_NTRESP], result, MS_CHAP2_NTRESP_LEN) || strncmp(saresponse, saresult, MS_AUTH_RESPONSE_LENGTH); } int main(int argc, char *argv[]) { PPP_crypto_init(); if (test_chap_v1()) { printf("CHAPv1 failed\n"); return -1; } if (test_chap_v2()) { printf("CHAPv2 failed\n"); return -1; } PPP_crypto_deinit(); printf("Success\n"); return 0; } #endif /* UNIT_TEST */ ppp-2.5.0/pppd/crypto_ms.c0000644000175000017500000001747014402506361012376 00000000000000/* * pppcrypt.c - PPP/DES linkage for MS-CHAP and EAP SRP-SHA1 * * Extracted from chap_ms.c by James Carlson. * * Copyright (c) 1995 Eric Rosenquist. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The name(s) of the authors of this software must not be used to * endorse or promote products derived from this software without * prior written permission. * * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * Sections of this code holds different copyright information. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include "crypto.h" #include "crypto_ms.h" /* * DES_set_odd_parity function are imported from openssl 3.0 project with the * follwoing license: * * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy * in the file LICENSE in the source distribution or at * https://www.openssl.org/source/license.html */ typedef unsigned char DES_cblock[8]; #define DES_KEY_SZ (sizeof(DES_cblock)) static const unsigned char odd_parity[256] = { 1, 1, 2, 2, 4, 4, 7, 7, 8, 8, 11, 11, 13, 13, 14, 14, 16, 16, 19, 19, 21, 21, 22, 22, 25, 25, 26, 26, 28, 28, 31, 31, 32, 32, 35, 35, 37, 37, 38, 38, 41, 41, 42, 42, 44, 44, 47, 47, 49, 49, 50, 50, 52, 52, 55, 55, 56, 56, 59, 59, 61, 61, 62, 62, 64, 64, 67, 67, 69, 69, 70, 70, 73, 73, 74, 74, 76, 76, 79, 79, 81, 81, 82, 82, 84, 84, 87, 87, 88, 88, 91, 91, 93, 93, 94, 94, 97, 97, 98, 98, 100, 100, 103, 103, 104, 104, 107, 107, 109, 109, 110, 110, 112, 112, 115, 115, 117, 117, 118, 118, 121, 121, 122, 122, 124, 124, 127, 127, 128, 128, 131, 131, 133, 133, 134, 134, 137, 137, 138, 138, 140, 140, 143, 143, 145, 145, 146, 146, 148, 148, 151, 151, 152, 152, 155, 155, 157, 157, 158, 158, 161, 161, 162, 162, 164, 164, 167, 167, 168, 168, 171, 171, 173, 173, 174, 174, 176, 176, 179, 179, 181, 181, 182, 182, 185, 185, 186, 186, 188, 188, 191, 191, 193, 193, 194, 194, 196, 196, 199, 199, 200, 200, 203, 203, 205, 205, 206, 206, 208, 208, 211, 211, 213, 213, 214, 214, 217, 217, 218, 218, 220, 220, 223, 223, 224, 224, 227, 227, 229, 229, 230, 230, 233, 233, 234, 234, 236, 236, 239, 239, 241, 241, 242, 242, 244, 244, 247, 247, 248, 248, 251, 251, 253, 253, 254, 254 }; static void DES_set_odd_parity(DES_cblock *key) { unsigned int i; for (i = 0; i < DES_KEY_SZ; i++) (*key)[i] = odd_parity[(*key)[i]]; } static unsigned char Get7Bits(const unsigned char *input, int startBit) { unsigned int word; word = (unsigned)input[startBit / 8] << 8; word |= (unsigned)input[startBit / 8 + 1]; word >>= 15 - (startBit % 8 + 7); return word & 0xFE; } static void MakeKey(const unsigned char *key, unsigned char *des_key) { /* key IN 56 bit DES key missing parity bits */ /* des_key OUT 64 bit DES key with parity bits added */ des_key[0] = Get7Bits(key, 0); des_key[1] = Get7Bits(key, 7); des_key[2] = Get7Bits(key, 14); des_key[3] = Get7Bits(key, 21); des_key[4] = Get7Bits(key, 28); des_key[5] = Get7Bits(key, 35); des_key[6] = Get7Bits(key, 42); des_key[7] = Get7Bits(key, 49); DES_set_odd_parity((DES_cblock *)des_key); } #include int DesEncrypt(const unsigned char *clear, const unsigned char *key, unsigned char *cipher) { int retval = 0; unsigned int clen = 0; unsigned char des_key[8]; PPP_CIPHER_CTX *ctx = PPP_CIPHER_CTX_new(); if (ctx) { MakeKey(key, des_key); if (PPP_CipherInit(ctx, PPP_des_ecb(), des_key, NULL, 1)) { if (PPP_CipherUpdate(ctx, cipher, &clen, clear, 8)) { if (PPP_CipherFinal(ctx, cipher + clen, &clen)) { retval = 1; } } } PPP_CIPHER_CTX_free(ctx); } return (retval); } int DesDecrypt(const unsigned char *cipher, const unsigned char *key, unsigned char *clear) { int retval = 0; unsigned int clen = 0; unsigned char des_key[8]; PPP_CIPHER_CTX *ctx = PPP_CIPHER_CTX_new(); if (ctx) { MakeKey(key, des_key); if (PPP_CipherInit(ctx, PPP_des_ecb(), des_key, NULL, 0)) { if (PPP_CipherUpdate(ctx, clear, &clen, cipher, 8)) { if (PPP_CipherFinal(ctx, clear + clen, &clen)) { retval = 1; } } } PPP_CIPHER_CTX_free(ctx); } return (retval); } #ifdef UNIT_TEST_MSCRYPTO #include #include /** * The test-vectors are taken from RFC2759. */ int test_encrypt() { unsigned char Challenge[8] = { 0xD0, 0x2E, 0x43, 0x86, 0xBC, 0xE9, 0x12, 0x26 }; unsigned char ZPasswordHash[24] = { 0x44, 0xEB, 0xBA, 0x8D, 0x53, 0x12, 0xB8, 0xD6, 0x11, 0x47, 0x44, 0x11, 0xF5, 0x69, 0x89, 0xAE }; unsigned char expected[24] = { 0x82, 0x30, 0x9E, 0xCD, 0x8D, 0x70, 0x8B, 0x5E, 0xA0, 0x8F, 0xAA, 0x39, 0x81, 0xCD, 0x83, 0x54, 0x42, 0x33, 0x11, 0x4A, 0x3D, 0x85, 0xD6, 0xDF }; unsigned char response[24] = {}; unsigned int retval = 0; DesEncrypt(Challenge, ZPasswordHash + 0, response + 0); DesEncrypt(Challenge, ZPasswordHash + 7, response + 8); DesEncrypt(Challenge, ZPasswordHash + 14, response + 16); return memcmp(response, expected, sizeof(response)) == 0; } int test_decrypt() { unsigned char Challenge[8] = { 0xD0, 0x2E, 0x43, 0x86, 0xBC, 0xE9, 0x12, 0x26 }; unsigned char ZPasswordHash[24] = { 0x44, 0xEB, 0xBA, 0x8D, 0x53, 0x12, 0xB8, 0xD6, 0x11, 0x47, 0x44, 0x11, 0xF5, 0x69, 0x89, 0xAE }; unsigned char Response[24] = { 0x82, 0x30, 0x9E, 0xCD, 0x8D, 0x70, 0x8B, 0x5E, 0xA0, 0x8F, 0xAA, 0x39, 0x81, 0xCD, 0x83, 0x54, 0x42, 0x33, 0x11, 0x4A, 0x3D, 0x85, 0xD6, 0xDF }; unsigned char Output[8]; unsigned int failure = 0; if (DesDecrypt(Response + 0, ZPasswordHash + 0, Output)) { failure += memcmp(Challenge, Output, sizeof(Challenge)); } if (DesDecrypt(Response + 8, ZPasswordHash + 7, Output)) { failure += memcmp(Challenge, Output, sizeof(Challenge)); } if (DesDecrypt(Response +16, ZPasswordHash +14, Output)) { failure += memcmp(Challenge, Output, sizeof(Challenge)); } return failure == 0; } int main(int argc, char *argv[]) { int failure = 0; if (!PPP_crypto_init()) { printf("Couldn't initialize crypto test\n"); return -1; } if (!test_encrypt()) { printf("CHAP DES encryption test failed\n"); failure++; } if (!test_decrypt()) { printf("CHAP DES decryption test failed\n"); failure++; } if (!PPP_crypto_deinit()) { printf("Couldn't deinitialize crypto test\n"); return -1; } return failure; } #endif ppp-2.5.0/pppd/cbcp.c0000644000175000017500000002307114353435407011267 00000000000000/* * cbcp - Call Back Configuration Protocol. * * Copyright (c) 1995 Pedro Roque Marques. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The names of the authors of this software must not be used to * endorse or promote products derived from this software without * prior written permission. * * 4. Redistributions of any form whatsoever must retain the following * acknowledgment: * "This product includes software developed by Pedro Roque Marques * " * * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include "pppd-private.h" #include "cbcp.h" #include "fsm.h" #include "lcp.h" #include "options.h" /* * Options. */ static int setcbcp (char **); static struct option cbcp_option_list[] = { { "callback", o_special, (void *)setcbcp, "Ask for callback", OPT_PRIO | OPT_A2STRVAL, &cbcp[0].us_number }, { NULL } }; /* * Protocol entry points. */ static void cbcp_init (int unit); static void cbcp_open (int unit); static void cbcp_lowerup (int unit); static void cbcp_input (int unit, u_char *pkt, int len); static void cbcp_protrej (int unit); static int cbcp_printpkt (u_char *pkt, int len, void (*printer)(void *, char *, ...), void *arg); struct protent cbcp_protent = { PPP_CBCP, cbcp_init, cbcp_input, cbcp_protrej, cbcp_lowerup, NULL, cbcp_open, NULL, cbcp_printpkt, NULL, 0, "CBCP", NULL, cbcp_option_list, NULL, NULL, NULL }; cbcp_state cbcp[NUM_PPP]; /* internal prototypes */ static void cbcp_recvreq (cbcp_state *us, u_char *pckt, int len); static void cbcp_resp (cbcp_state *us); static void cbcp_up (cbcp_state *us); static void cbcp_recvack (cbcp_state *us, u_char *pckt, int len); static void cbcp_send (cbcp_state *us, int code, u_char *buf, int len); /* option processing */ static int setcbcp(char **argv) { lcp_wantoptions[0].neg_cbcp = 1; cbcp_protent.enabled_flag = 1; cbcp[0].us_number = strdup(*argv); if (cbcp[0].us_number == 0) novm("callback number"); cbcp[0].us_type |= (1 << CB_CONF_USER); cbcp[0].us_type |= (1 << CB_CONF_ADMIN); return (1); } /* init state */ static void cbcp_init(int iface) { cbcp_state *us; us = &cbcp[iface]; memset(us, 0, sizeof(cbcp_state)); us->us_unit = iface; us->us_type |= (1 << CB_CONF_NO); } /* lower layer is up */ static void cbcp_lowerup(int iface) { cbcp_state *us = &cbcp[iface]; dbglog("cbcp_lowerup"); dbglog("want: %d", us->us_type); if (us->us_type == CB_CONF_USER) dbglog("phone no: %s", us->us_number); } static void cbcp_open(int unit) { dbglog("cbcp_open"); } /* process an incomming packet */ static void cbcp_input(int unit, u_char *inpacket, int pktlen) { u_char *inp; u_char code, id; u_short len; cbcp_state *us = &cbcp[unit]; inp = inpacket; if (pktlen < CBCP_MINLEN) { if (debug) dbglog("CBCP packet is too small"); return; } GETCHAR(code, inp); GETCHAR(id, inp); GETSHORT(len, inp); if (len > pktlen || len < CBCP_MINLEN) { if (debug) dbglog("CBCP packet: invalid length %d", len); return; } len -= CBCP_MINLEN; switch(code) { case CBCP_REQ: us->us_id = id; cbcp_recvreq(us, inp, len); break; case CBCP_RESP: if (debug) dbglog("CBCP_RESP received"); break; case CBCP_ACK: if (debug && id != us->us_id) dbglog("id doesn't match: expected %d recv %d", us->us_id, id); cbcp_recvack(us, inp, len); break; default: break; } } /* protocol was rejected by foe */ void cbcp_protrej(int iface) { } char *cbcp_codenames[] = { "Request", "Response", "Ack" }; char *cbcp_optionnames[] = { "NoCallback", "UserDefined", "AdminDefined", "List" }; /* pretty print a packet */ static int cbcp_printpkt(u_char *p, int plen, void (*printer) (void *, char *, ...), void *arg) { int code, opt, id, len, olen, delay; u_char *pstart; if (plen < HEADERLEN) return 0; pstart = p; GETCHAR(code, p); GETCHAR(id, p); GETSHORT(len, p); if (len < HEADERLEN || len > plen) return 0; if (code >= 1 && code <= sizeof(cbcp_codenames) / sizeof(char *)) printer(arg, " %s", cbcp_codenames[code-1]); else printer(arg, " code=0x%x", code); printer(arg, " id=0x%x", id); len -= HEADERLEN; switch (code) { case CBCP_REQ: case CBCP_RESP: case CBCP_ACK: while(len >= 2) { GETCHAR(opt, p); GETCHAR(olen, p); if (olen < 2 || olen > len) { break; } printer(arg, " <"); len -= olen; if (opt >= 1 && opt <= sizeof(cbcp_optionnames) / sizeof(char *)) printer(arg, " %s", cbcp_optionnames[opt-1]); else printer(arg, " option=0x%x", opt); if (olen > 2) { GETCHAR(delay, p); printer(arg, " delay = %d", delay); } if (olen > 3) { int addrt; char str[256]; GETCHAR(addrt, p); memcpy(str, p, olen - 4); str[olen - 4] = 0; printer(arg, " number = %s", str); } printer(arg, ">"); } break; default: break; } for (; len > 0; --len) { GETCHAR(code, p); printer(arg, " %.2x", code); } return p - pstart; } /* received CBCP request */ static void cbcp_recvreq(cbcp_state *us, u_char *pckt, int pcktlen) { u_char type, opt_len, delay, addr_type; char address[256]; int len = pcktlen; address[0] = 0; while (len >= 2) { dbglog("length: %d", len); GETCHAR(type, pckt); GETCHAR(opt_len, pckt); if (opt_len < 2 || opt_len > len) break; if (opt_len > 2) GETCHAR(delay, pckt); us->us_allowed |= (1 << type); switch(type) { case CB_CONF_NO: dbglog("no callback allowed"); break; case CB_CONF_USER: dbglog("user callback allowed"); if (opt_len > 4) { GETCHAR(addr_type, pckt); memcpy(address, pckt, opt_len - 4); address[opt_len - 4] = 0; if (address[0]) dbglog("address: %s", address); } break; case CB_CONF_ADMIN: dbglog("user admin defined allowed"); break; case CB_CONF_LIST: break; } len -= opt_len; } if (len != 0) { if (debug) dbglog("cbcp_recvreq: malformed packet (%d bytes left)", len); return; } cbcp_resp(us); } static void cbcp_resp(cbcp_state *us) { u_char cb_type; u_char buf[256]; u_char *bufp = buf; int len = 0; int slen; cb_type = us->us_allowed & us->us_type; dbglog("cbcp_resp cb_type=%d", cb_type); #if 0 if (!cb_type) lcp_down(us->us_unit); #endif if (cb_type & ( 1 << CB_CONF_USER ) ) { dbglog("cbcp_resp CONF_USER"); slen = strlen(us->us_number); if (slen > 250) { warn("callback number truncated to 250 characters"); slen = 250; } PUTCHAR(CB_CONF_USER, bufp); len = 3 + 1 + slen + 1; PUTCHAR(len , bufp); PUTCHAR(5, bufp); /* delay */ PUTCHAR(1, bufp); BCOPY(us->us_number, bufp, slen + 1); cbcp_send(us, CBCP_RESP, buf, len); return; } if (cb_type & ( 1 << CB_CONF_ADMIN ) ) { dbglog("cbcp_resp CONF_ADMIN"); PUTCHAR(CB_CONF_ADMIN, bufp); len = 3; PUTCHAR(len, bufp); PUTCHAR(5, bufp); /* delay */ cbcp_send(us, CBCP_RESP, buf, len); return; } if (cb_type & ( 1 << CB_CONF_NO ) ) { dbglog("cbcp_resp CONF_NO"); PUTCHAR(CB_CONF_NO, bufp); len = 2; PUTCHAR(len , bufp); cbcp_send(us, CBCP_RESP, buf, len); start_networks(us->us_unit); return; } } static void cbcp_send(cbcp_state *us, int code, u_char *buf, int len) { u_char *outp; int outlen; outp = outpacket_buf; outlen = 4 + len; MAKEHEADER(outp, PPP_CBCP); PUTCHAR(code, outp); PUTCHAR(us->us_id, outp); PUTSHORT(outlen, outp); if (len) BCOPY(buf, outp, len); output(us->us_unit, outpacket_buf, outlen + PPP_HDRLEN); } static void cbcp_recvack(cbcp_state *us, u_char *pckt, int len) { u_char type, delay, addr_type; int opt_len; char address[256]; if (len >= 2) { GETCHAR(type, pckt); GETCHAR(opt_len, pckt); if (opt_len >= 2 && opt_len <= len) { if (opt_len > 2) GETCHAR(delay, pckt); if (opt_len > 4) { GETCHAR(addr_type, pckt); memcpy(address, pckt, opt_len - 4); address[opt_len - 4] = 0; if (address[0]) dbglog("peer will call: %s", address); } if (type == CB_CONF_NO) return; cbcp_up(us); } else if (debug) dbglog("cbcp_recvack: malformed packet"); } } /* ok peer will do callback */ static void cbcp_up(cbcp_state *us) { persist = 0; ppp_set_status(EXIT_CALLBACK); lcp_close(0, "Call me back, please"); } ppp-2.5.0/pppd/mppe.c0000644000175000017500000002166214353435407011325 00000000000000/* mppe.c - MPPE key implementation * * Copyright (c) 2020 Eivind Naess. All rights reserved. * Copyright (c) 2008 Paul Mackerras. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The name(s) of the authors of this software must not be used to * endorse or promote products derived from this software without * prior written permission. * * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include "pppd-private.h" #include "fsm.h" #include "ccp.h" #include "chap_ms.h" #include "mppe.h" #include "crypto.h" u_char mppe_send_key[MPPE_MAX_KEY_SIZE]; u_char mppe_recv_key[MPPE_MAX_KEY_SIZE]; int mppe_keys_set = 0; void mppe_set_keys(u_char *send_key, u_char *recv_key, int keylen) { int length = keylen; if (length > MPPE_MAX_KEY_SIZE) length = MPPE_MAX_KEY_SIZE; if (send_key) { BCOPY(send_key, mppe_send_key, length); BZERO(send_key, keylen); } if (recv_key) { BCOPY(recv_key, mppe_recv_key, length); BZERO(recv_key, keylen); } mppe_keys_set = length; } bool mppe_keys_isset() { return !!mppe_keys_set; } int mppe_get_recv_key(u_char *recv_key, int length) { if (mppe_keys_isset()) { if (length > mppe_keys_set) length = mppe_keys_set; BCOPY(mppe_recv_key, recv_key, length); return length; } return 0; } int mppe_get_send_key(u_char *send_key, int length) { if (mppe_keys_isset()) { if (length > mppe_keys_set) length = mppe_keys_set; BCOPY(mppe_send_key, send_key, length); return length; } return 0; } void mppe_clear_keys(void) { mppe_keys_set = 0; BZERO(mppe_send_key, sizeof(mppe_send_key)); BZERO(mppe_recv_key, sizeof(mppe_recv_key)); } /* * Set mppe_xxxx_key from the NTPasswordHashHash. * RFC 2548 (RADIUS support) requires us to export this function (ugh). */ void mppe_set_chapv1(unsigned char *rchallenge, unsigned char *PasswordHashHash) { PPP_MD_CTX *ctx; u_char Digest[SHA_DIGEST_LENGTH]; int DigestLen; ctx = PPP_MD_CTX_new(); if (ctx != NULL) { if (PPP_DigestInit(ctx, PPP_sha1())) { if (PPP_DigestUpdate(ctx, PasswordHashHash, MD4_DIGEST_LENGTH)) { if (PPP_DigestUpdate(ctx, PasswordHashHash, MD4_DIGEST_LENGTH)) { if (PPP_DigestUpdate(ctx, rchallenge, 8)) { DigestLen = SHA_DIGEST_LENGTH; PPP_DigestFinal(ctx, Digest, &DigestLen); } } } } PPP_MD_CTX_free(ctx); } /* Same key in both directions. */ mppe_set_keys(Digest, Digest, sizeof(Digest)); } /* * Set mppe_xxxx_key from MS-CHAPv2 credentials. (see RFC 3079) * * This helper function used in the Winbind module, which gets the * NTHashHash from the server. */ void mppe_set_chapv2(unsigned char *PasswordHashHash, unsigned char *NTResponse, int IsServer) { PPP_MD_CTX *ctx; u_char MasterKey[SHA_DIGEST_LENGTH]; u_char SendKey[SHA_DIGEST_LENGTH]; u_char RecvKey[SHA_DIGEST_LENGTH]; int KeyLen; u_char SHApad1[40] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; u_char SHApad2[40] = { 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2 }; /* "This is the MPPE Master Key" */ u_char Magic1[27] = { 0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x4d, 0x50, 0x50, 0x45, 0x20, 0x4d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x20, 0x4b, 0x65, 0x79 }; /* "On the client side, this is the send key; " "on the server side, it is the receive key." */ u_char Magic2[84] = { 0x4f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x20, 0x73, 0x69, 0x64, 0x65, 0x2c, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x65, 0x6e, 0x64, 0x20, 0x6b, 0x65, 0x79, 0x3b, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x73, 0x69, 0x64, 0x65, 0x2c, 0x20, 0x69, 0x74, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x20, 0x6b, 0x65, 0x79, 0x2e }; /* "On the client side, this is the receive key; " "on the server side, it is the send key." */ u_char Magic3[84] = { 0x4f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x20, 0x73, 0x69, 0x64, 0x65, 0x2c, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x20, 0x6b, 0x65, 0x79, 0x3b, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x73, 0x69, 0x64, 0x65, 0x2c, 0x20, 0x69, 0x74, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x65, 0x6e, 0x64, 0x20, 0x6b, 0x65, 0x79, 0x2e }; u_char *s; ctx = PPP_MD_CTX_new(); if (ctx != NULL) { if (PPP_DigestInit(ctx, PPP_sha1())) { if (PPP_DigestUpdate(ctx, PasswordHashHash, MD4_DIGEST_LENGTH)) { if (PPP_DigestUpdate(ctx, NTResponse, 24)) { if (PPP_DigestUpdate(ctx, Magic1, sizeof(Magic1))) { KeyLen = SHA_DIGEST_LENGTH; PPP_DigestFinal(ctx, MasterKey, &KeyLen); } } } } PPP_MD_CTX_free(ctx); } /* * generate send key */ if (IsServer) s = Magic3; else s = Magic2; ctx = PPP_MD_CTX_new(); if (ctx != NULL) { if (PPP_DigestInit(ctx, PPP_sha1())) { if (PPP_DigestUpdate(ctx, MasterKey, 16)) { if (PPP_DigestUpdate(ctx, SHApad1, sizeof(SHApad1))) { if (PPP_DigestUpdate(ctx, s, 84)) { if (PPP_DigestUpdate(ctx, SHApad2, sizeof(SHApad2))) { KeyLen = SHA_DIGEST_LENGTH; PPP_DigestFinal(ctx, SendKey, &KeyLen); } } } } } PPP_MD_CTX_free(ctx); } /* * generate recv key */ if (IsServer) s = Magic2; else s = Magic3; ctx = PPP_MD_CTX_new(); if (ctx != NULL) { if (PPP_DigestInit(ctx, PPP_sha1())) { if (PPP_DigestUpdate(ctx, MasterKey, 16)) { if (PPP_DigestUpdate(ctx, SHApad1, sizeof(SHApad1))) { if (PPP_DigestUpdate(ctx, s, 84)) { if (PPP_DigestUpdate(ctx, SHApad2, sizeof(SHApad2))) { KeyLen = SHA_DIGEST_LENGTH; PPP_DigestFinal(ctx, RecvKey, &KeyLen); } } } } } PPP_MD_CTX_free(ctx); } mppe_set_keys(SendKey, RecvKey, SHA_DIGEST_LENGTH); } #ifndef UNIT_TEST /* * Set MPPE options from plugins. */ void mppe_set_enc_types(int policy, int types) { /* Early exit for unknown policies. */ if (policy != MPPE_ENC_POL_ENC_ALLOWED && policy != MPPE_ENC_POL_ENC_REQUIRED) return; /* Don't modify MPPE if it's optional and wasn't already configured. */ if (policy == MPPE_ENC_POL_ENC_ALLOWED && !ccp_wantoptions[0].mppe) return; /* * Disable undesirable encryption types. Note that we don't ENABLE * any encryption types, to avoid overriding manual configuration. */ switch(types) { case MPPE_ENC_TYPES_RC4_40: ccp_wantoptions[0].mppe &= ~MPPE_OPT_128; /* disable 128-bit */ break; case MPPE_ENC_TYPES_RC4_128: ccp_wantoptions[0].mppe &= ~MPPE_OPT_40; /* disable 40-bit */ break; default: break; } } #endif ppp-2.5.0/pppd/multilink.c0000644000175000017500000003245014353435407012371 00000000000000/* * multilink.c - support routines for multilink. * * Copyright (c) 2000-2002 Paul Mackerras. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. The name(s) of the authors of this software must not be used to * endorse or promote products derived from this software without * prior written permission. * * 3. Redistributions of any form whatsoever must retain the following * acknowledgment: * "This product includes software developed by Paul Mackerras * ". * * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include #include #include "pppd-private.h" #include "fsm.h" #include "lcp.h" #include "tdb.h" #include "multilink.h" bool endpoint_specified; /* user gave explicit endpoint discriminator */ char *bundle_id; /* identifier for our bundle */ char *blinks_id; /* key for the list of links */ bool doing_multilink; /* multilink was enabled and agreed to */ bool multilink_master; /* we own the multilink bundle */ extern TDB_CONTEXT *pppdb; extern char db_key[]; static void make_bundle_links(int append); static void remove_bundle_link(void); static void iterate_bundle_links(void (*func)(char *)); static int get_default_epdisc(struct epdisc *); static int parse_num(char *str, const char *key, int *valp); static int owns_unit(TDB_DATA pid, int unit); #define set_ip_epdisc(ep, addr) do { \ ep->length = 4; \ ep->value[0] = addr >> 24; \ ep->value[1] = addr >> 16; \ ep->value[2] = addr >> 8; \ ep->value[3] = addr; \ } while (0) #define LOCAL_IP_ADDR(addr) \ (((addr) & 0xff000000) == 0x0a000000 /* 10.x.x.x */ \ || ((addr) & 0xfff00000) == 0xac100000 /* 172.16.x.x */ \ || ((addr) & 0xffff0000) == 0xc0a80000) /* 192.168.x.x */ #define process_exists(n) (kill((n), 0) == 0 || errno != ESRCH) multilink_join_hook_fn *multilink_join_hook = NULL; bool mp_master() { return multilink_master; } bool mp_on() { return doing_multilink; } void mp_check_options(void) { lcp_options *wo = &lcp_wantoptions[0]; lcp_options *ao = &lcp_allowoptions[0]; doing_multilink = 0; if (!multilink) return; /* if we're doing multilink, we have to negotiate MRRU */ if (!wo->neg_mrru) { /* mrru not specified, default to mru */ wo->mrru = wo->mru; wo->neg_mrru = 1; } ao->mrru = ao->mru; ao->neg_mrru = 1; if (!wo->neg_endpoint && !noendpoint) { /* get a default endpoint value */ wo->neg_endpoint = get_default_epdisc(&wo->endpoint); } } /* * Make a new bundle or join us to an existing bundle * if we are doing multilink. */ int mp_join_bundle(void) { lcp_options *go = &lcp_gotoptions[0]; lcp_options *ho = &lcp_hisoptions[0]; lcp_options *ao = &lcp_allowoptions[0]; int unit, pppd_pid; int l, mtu; char *p; TDB_DATA key, pid, rec; if (doing_multilink) { /* have previously joined a bundle */ if (!go->neg_mrru || !ho->neg_mrru) { notice("oops, didn't get multilink on renegotiation"); lcp_close(0, "multilink required"); return 0; } /* XXX should check the peer_authname and ho->endpoint are the same as previously */ return 0; } if (!go->neg_mrru || !ho->neg_mrru) { /* not doing multilink */ if (go->neg_mrru) notice("oops, multilink negotiated only for receive"); mtu = ho->neg_mru? ho->mru: PPP_MRU; if (mtu > ao->mru) mtu = ao->mru; if (demand) { /* already have a bundle */ cfg_bundle(0, 0, 0, 0); ppp_set_mtu(0, mtu); return 0; } make_new_bundle(0, 0, 0, 0); set_ifunit(1); ppp_set_mtu(0, mtu); return 0; } doing_multilink = 1; /* * Find the appropriate bundle or join a new one. * First we make up a name for the bundle. * The length estimate is worst-case assuming every * character has to be quoted. */ l = 4 * strlen(peer_authname) + 10; if (ho->neg_endpoint) l += 3 * ho->endpoint.length + 8; if (bundle_name) l += 3 * strlen(bundle_name) + 2; bundle_id = malloc(l); if (bundle_id == 0) novm("bundle identifier"); p = bundle_id; p += slprintf(p, l-1, "BUNDLE=\"%q\"", peer_authname); if (ho->neg_endpoint || bundle_name) *p++ = '/'; if (ho->neg_endpoint) p += slprintf(p, bundle_id+l-p, "%s", epdisc_to_str(&ho->endpoint)); if (bundle_name) p += slprintf(p, bundle_id+l-p, "/%v", bundle_name); /* Make the key for the list of links belonging to the bundle */ l = p - bundle_id; blinks_id = malloc(l + 7); if (blinks_id == NULL) novm("bundle links key"); slprintf(blinks_id, l + 7, "BUNDLE_LINKS=%s", bundle_id + 7); /* * For demand mode, we only need to configure the bundle * and attach the link. */ mtu = MIN(ho->mrru, ao->mru); if (demand) { cfg_bundle(go->mrru, ho->mrru, go->neg_ssnhf, ho->neg_ssnhf); ppp_set_mtu(0, mtu); ppp_script_setenv("BUNDLE", bundle_id + 7, 1); return 0; } /* * Check if the bundle ID is already in the database. */ unit = -1; lock_db(); key.dptr = bundle_id; key.dsize = p - bundle_id; pid = tdb_fetch(pppdb, key); if (pid.dptr != NULL) { /* bundle ID exists, see if the pppd record exists */ rec = tdb_fetch(pppdb, pid); if (rec.dptr != NULL && rec.dsize > 0) { /* make sure the string is null-terminated */ rec.dptr[rec.dsize-1] = 0; /* parse the interface number */ parse_num(rec.dptr, "UNIT=", &unit); /* check the pid value */ if (!parse_num(rec.dptr, "PPPD_PID=", &pppd_pid) || !process_exists(pppd_pid) || !owns_unit(pid, unit)) unit = -1; free(rec.dptr); } free(pid.dptr); } if (unit >= 0) { /* attach to existing unit */ if (bundle_attach(unit)) { set_ifunit(0); ppp_script_setenv("BUNDLE", bundle_id + 7, 0); make_bundle_links(1); unlock_db(); info("Link attached to %s", ifname); return 1; } /* attach failed because bundle doesn't exist */ } /* we have to make a new bundle */ make_new_bundle(go->mrru, ho->mrru, go->neg_ssnhf, ho->neg_ssnhf); set_ifunit(1); ppp_set_mtu(0, mtu); ppp_script_setenv("BUNDLE", bundle_id + 7, 1); make_bundle_links(0); unlock_db(); info("New bundle %s created", ifname); multilink_master = 1; return 0; } void mp_exit_bundle(void) { lock_db(); remove_bundle_link(); unlock_db(); } static void sendhup(char *str) { int pid; if (parse_num(str, "PPPD_PID=", &pid) && pid != getpid()) { if (debug) dbglog("sending SIGHUP to process %d", pid); kill(pid, SIGHUP); } } void mp_bundle_terminated(void) { TDB_DATA key; bundle_terminating = 1; upper_layers_down(0); notice("Connection terminated."); print_link_stats(); if (!demand) { remove_pidfiles(); ppp_script_unsetenv("IFNAME"); } lock_db(); destroy_bundle(); iterate_bundle_links(sendhup); key.dptr = blinks_id; key.dsize = strlen(blinks_id); tdb_delete(pppdb, key); unlock_db(); new_phase(PHASE_DEAD); doing_multilink = 0; multilink_master = 0; } static void make_bundle_links(int append) { TDB_DATA key, rec; char *p; char entry[32]; int l; key.dptr = blinks_id; key.dsize = strlen(blinks_id); slprintf(entry, sizeof(entry), "%s;", db_key); p = entry; if (append) { rec = tdb_fetch(pppdb, key); if (rec.dptr != NULL && rec.dsize > 0) { rec.dptr[rec.dsize-1] = 0; if (strstr(rec.dptr, db_key) != NULL) { /* already in there? strange */ warn("link entry already exists in tdb"); return; } l = rec.dsize + strlen(entry); p = malloc(l); if (p == NULL) novm("bundle link list"); slprintf(p, l, "%s%s", rec.dptr, entry); } else { warn("bundle link list not found"); } if (rec.dptr != NULL) free(rec.dptr); } rec.dptr = p; rec.dsize = strlen(p) + 1; if (tdb_store(pppdb, key, rec, TDB_REPLACE)) error("couldn't %s bundle link list", append? "update": "create"); if (p != entry) free(p); } static void remove_bundle_link(void) { TDB_DATA key, rec; char entry[32]; char *p, *q; int l; key.dptr = blinks_id; key.dsize = strlen(blinks_id); slprintf(entry, sizeof(entry), "%s;", db_key); rec = tdb_fetch(pppdb, key); if (rec.dptr == NULL || rec.dsize <= 0) { if (rec.dptr != NULL) free(rec.dptr); return; } rec.dptr[rec.dsize-1] = 0; p = strstr(rec.dptr, entry); if (p != NULL) { q = p + strlen(entry); l = strlen(q) + 1; memmove(p, q, l); rec.dsize = p - rec.dptr + l; if (tdb_store(pppdb, key, rec, TDB_REPLACE)) error("couldn't update bundle link list (removal)"); } free(rec.dptr); } static void iterate_bundle_links(void (*func)(char *)) { TDB_DATA key, rec, pp; char *p, *q; key.dptr = blinks_id; key.dsize = strlen(blinks_id); rec = tdb_fetch(pppdb, key); if (rec.dptr == NULL || rec.dsize <= 0) { error("bundle link list not found (iterating list)"); if (rec.dptr != NULL) free(rec.dptr); return; } p = rec.dptr; p[rec.dsize-1] = 0; while ((q = strchr(p, ';')) != NULL) { *q = 0; key.dptr = p; key.dsize = q - p; pp = tdb_fetch(pppdb, key); if (pp.dptr != NULL && pp.dsize > 0) { pp.dptr[pp.dsize-1] = 0; func(pp.dptr); } if (pp.dptr != NULL) free(pp.dptr); p = q + 1; } free(rec.dptr); } static int parse_num(char *str, const char *key, int *valp) { char *p, *endp; int i; p = strstr(str, key); if (p != 0) { p += strlen(key); i = strtol(p, &endp, 10); if (endp != p && (*endp == 0 || *endp == ';')) { *valp = i; return 1; } } return 0; } /* * Check whether the pppd identified by `key' still owns ppp unit `unit'. */ static int owns_unit(TDB_DATA key, int unit) { char ifkey[32]; TDB_DATA kd, vd; int ret = 0; slprintf(ifkey, sizeof(ifkey), "UNIT=%d", unit); kd.dptr = ifkey; kd.dsize = strlen(ifkey); vd = tdb_fetch(pppdb, kd); if (vd.dptr != NULL) { ret = vd.dsize == key.dsize && memcmp(vd.dptr, key.dptr, vd.dsize) == 0; free(vd.dptr); } return ret; } static int get_default_epdisc(struct epdisc *ep) { struct hostent *hp; u_int32_t addr; /* First try for an ethernet MAC address */ if (get_first_ether_hwaddr(ep->value) >= 0) { ep->class = EPD_MAC; ep->length = 6; return 1; } /* see if our hostname corresponds to a reasonable IP address */ hp = gethostbyname(hostname); if (hp != NULL) { addr = *(u_int32_t *)hp->h_addr; if (!ppp_bad_ip_addr(addr)) { addr = ntohl(addr); if (!LOCAL_IP_ADDR(addr)) { ep->class = EPD_IP; set_ip_epdisc(ep, addr); return 1; } } } return 0; } /* * epdisc_to_str - make a printable string from an endpoint discriminator. */ static char *endp_class_names[] = { "null", "local", "IP", "MAC", "magic", "phone" }; char * epdisc_to_str(struct epdisc *ep) { static char str[MAX_ENDP_LEN*3+8]; u_char *p = ep->value; int i, mask = 0; char *q, c, c2; if (ep->class == EPD_NULL && ep->length == 0) return "null"; if (ep->class == EPD_IP && ep->length == 4) { u_int32_t addr; GETLONG(addr, p); slprintf(str, sizeof(str), "IP:%I", htonl(addr)); return str; } c = ':'; c2 = '.'; if (ep->class == EPD_MAC && ep->length == 6) c2 = ':'; else if (ep->class == EPD_MAGIC && (ep->length % 4) == 0) mask = 3; q = str; if (ep->class <= EPD_PHONENUM) q += slprintf(q, sizeof(str)-1, "%s", endp_class_names[ep->class]); else q += slprintf(q, sizeof(str)-1, "%d", ep->class); c = ':'; for (i = 0; i < ep->length && i < MAX_ENDP_LEN; ++i) { if ((i & mask) == 0) { *q++ = c; c = c2; } q += slprintf(q, str + sizeof(str) - q, "%.2x", ep->value[i]); } return str; } static int hexc_val(int c) { if (c >= 'a') return c - 'a' + 10; if (c >= 'A') return c - 'A' + 10; return c - '0'; } int str_to_epdisc(struct epdisc *ep, char *str) { int i, l; char *p, *endp; for (i = EPD_NULL; i <= EPD_PHONENUM; ++i) { int sl = strlen(endp_class_names[i]); if (strncasecmp(str, endp_class_names[i], sl) == 0) { str += sl; break; } } if (i > EPD_PHONENUM) { /* not a class name, try a decimal class number */ i = strtol(str, &endp, 10); if (endp == str) return 0; /* can't parse class number */ str = endp; } ep->class = i; if (*str == 0) { ep->length = 0; return 1; } if (*str != ':' && *str != '.') return 0; ++str; if (i == EPD_IP) { u_int32_t addr; i = parse_dotted_ip(str, &addr); if (i == 0 || str[i] != 0) return 0; set_ip_epdisc(ep, addr); return 1; } if (i == EPD_MAC && get_if_hwaddr(ep->value, str) >= 0) { ep->length = 6; return 1; } p = str; for (l = 0; l < MAX_ENDP_LEN; ++l) { if (*str == 0) break; if (p <= str) for (p = str; isxdigit(*p); ++p) ; i = p - str; if (i == 0) return 0; ep->value[l] = hexc_val(*str++); if ((i & 1) == 0) ep->value[l] = (ep->value[l] << 4) + hexc_val(*str++); if (*str == ':' || *str == '.') ++str; } if (*str != 0 || (ep->class == EPD_MAC && l != 6)) return 0; ep->length = l; return 1; } ppp-2.5.0/pppd/tdb.c0000664000175000017500000015256214076444143011142 00000000000000 /* Unix SMB/CIFS implementation. trivial database library Copyright (C) Andrew Tridgell 1999-2004 Copyright (C) Paul `Rusty' Russell 2000 Copyright (C) Jeremy Allison 2000-2003 ** NOTE! The following LGPL license applies to the tdb ** library. This does NOT imply that all of Samba is released ** under the LGPL This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* NOTE: If you use tdbs under valgrind, and in particular if you run * tdbtorture, you may get spurious "uninitialized value" warnings. I * think this is because valgrind doesn't understand that the mmap'd * area may be written to by other processes. Memory can, from the * point of view of the grinded process, spontaneously become * initialized. * * I can think of a few solutions. [mbp 20030311] * * 1 - Write suppressions for Valgrind so that it doesn't complain * about this. Probably the most reasonable but people need to * remember to use them. * * 2 - Use IO not mmap when running under valgrind. Not so nice. * * 3 - Use the special valgrind macros to mark memory as valid at the * right time. Probably too hard -- the process just doesn't know. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include #include #include #include #include "tdb.h" #include "spinlock.h" #define TDB_MAGIC_FOOD "TDB file\n" #define TDB_VERSION (0x26011967 + 6) #define TDB_MAGIC (0x26011999U) #define TDB_FREE_MAGIC (~TDB_MAGIC) #define TDB_DEAD_MAGIC (0xFEE1DEAD) #define TDB_ALIGNMENT 4 #define MIN_REC_SIZE (2*sizeof(struct list_struct) + TDB_ALIGNMENT) #define DEFAULT_HASH_SIZE 131 #define TDB_PAGE_SIZE 0x2000 #define FREELIST_TOP (sizeof(struct tdb_header)) #define TDB_ALIGN(x,a) (((x) + (a)-1) & ~((a)-1)) #define TDB_BYTEREV(x) (((((x)&0xff)<<24)|((x)&0xFF00)<<8)|(((x)>>8)&0xFF00)|((x)>>24)) #define TDB_DEAD(r) ((r)->magic == TDB_DEAD_MAGIC) #define TDB_BAD_MAGIC(r) ((r)->magic != TDB_MAGIC && !TDB_DEAD(r)) #define TDB_HASH_TOP(hash) (FREELIST_TOP + (BUCKET(hash)+1)*sizeof(tdb_off)) #define TDB_DATA_START(hash_size) (TDB_HASH_TOP(hash_size-1) + TDB_SPINLOCK_SIZE(hash_size)) /* NB assumes there is a local variable called "tdb" that is the * current context, also takes doubly-parenthesized print-style * argument. */ #define TDB_LOG(x) (tdb->log_fn?((tdb->log_fn x),0) : 0) /* lock offsets */ #define GLOBAL_LOCK 0 #define ACTIVE_LOCK 4 #ifndef MAP_FILE #define MAP_FILE 0 #endif #ifndef MAP_FAILED #define MAP_FAILED ((void *)-1) #endif /* free memory if the pointer is valid and zero the pointer */ #ifndef SAFE_FREE #define SAFE_FREE(x) do { if ((x) != NULL) {free((x)); (x)=NULL;} } while(0) #endif #define BUCKET(hash) ((hash) % tdb->header.hash_size) TDB_DATA tdb_null; /* all contexts, to ensure no double-opens (fcntl locks don't nest!) */ static TDB_CONTEXT *tdbs = NULL; static int tdb_munmap(TDB_CONTEXT *tdb) { if (tdb->flags & TDB_INTERNAL) return 0; #ifdef HAVE_MMAP if (tdb->map_ptr) { int ret = munmap(tdb->map_ptr, tdb->map_size); if (ret != 0) return ret; } #endif tdb->map_ptr = NULL; return 0; } static void tdb_mmap(TDB_CONTEXT *tdb) { if (tdb->flags & TDB_INTERNAL) return; #ifdef HAVE_MMAP if (!(tdb->flags & TDB_NOMMAP)) { tdb->map_ptr = mmap(NULL, tdb->map_size, PROT_READ|(tdb->read_only? 0:PROT_WRITE), MAP_SHARED|MAP_FILE, tdb->fd, 0); /* * NB. When mmap fails it returns MAP_FAILED *NOT* NULL !!!! */ if (tdb->map_ptr == MAP_FAILED) { tdb->map_ptr = NULL; TDB_LOG((tdb, 2, "tdb_mmap failed for size %d (%s)\n", tdb->map_size, strerror(errno))); } } else { tdb->map_ptr = NULL; } #else tdb->map_ptr = NULL; #endif } /* Endian conversion: we only ever deal with 4 byte quantities */ static void *convert(void *buf, u32 size) { u32 i, *p = buf; for (i = 0; i < size / 4; i++) p[i] = TDB_BYTEREV(p[i]); return buf; } #define DOCONV() (tdb->flags & TDB_CONVERT) #define CONVERT(x) (DOCONV() ? convert(&x, sizeof(x)) : &x) /* the body of the database is made of one list_struct for the free space plus a separate data list for each hash value */ struct list_struct { tdb_off next; /* offset of the next record in the list */ tdb_len rec_len; /* total byte length of record */ tdb_len key_len; /* byte length of key */ tdb_len data_len; /* byte length of data */ u32 full_hash; /* the full 32 bit hash of the key */ u32 magic; /* try to catch errors */ /* the following union is implied: union { char record[rec_len]; struct { char key[key_len]; char data[data_len]; } u32 totalsize; (tailer) } */ }; /*************************************************************** Allow a caller to set a "alarm" flag that tdb can check to abort a blocking lock on SIGALRM. ***************************************************************/ static sig_atomic_t *palarm_fired; void tdb_set_lock_alarm(sig_atomic_t *palarm) { palarm_fired = palarm; } /* a byte range locking function - return 0 on success this functions locks/unlocks 1 byte at the specified offset. On error, errno is also set so that errors are passed back properly through tdb_open(). */ static int tdb_brlock(TDB_CONTEXT *tdb, tdb_off offset, int rw_type, int lck_type, int probe) { struct flock fl; int ret; if (tdb->flags & TDB_NOLOCK) return 0; if ((rw_type == F_WRLCK) && (tdb->read_only)) { errno = EACCES; return -1; } fl.l_type = rw_type; fl.l_whence = SEEK_SET; fl.l_start = offset; fl.l_len = 1; fl.l_pid = 0; do { ret = fcntl(tdb->fd,lck_type,&fl); if (ret == -1 && errno == EINTR && palarm_fired && *palarm_fired) break; } while (ret == -1 && errno == EINTR); if (ret == -1) { if (!probe && lck_type != F_SETLK) { /* Ensure error code is set for log fun to examine. */ if (errno == EINTR && palarm_fired && *palarm_fired) tdb->ecode = TDB_ERR_LOCK_TIMEOUT; else tdb->ecode = TDB_ERR_LOCK; TDB_LOG((tdb, 5,"tdb_brlock failed (fd=%d) at offset %d rw_type=%d lck_type=%d\n", tdb->fd, offset, rw_type, lck_type)); } /* Was it an alarm timeout ? */ if (errno == EINTR && palarm_fired && *palarm_fired) { TDB_LOG((tdb, 5, "tdb_brlock timed out (fd=%d) at offset %d rw_type=%d lck_type=%d\n", tdb->fd, offset, rw_type, lck_type)); return TDB_ERRCODE(TDB_ERR_LOCK_TIMEOUT, -1); } /* Otherwise - generic lock error. errno set by fcntl. * EAGAIN is an expected return from non-blocking * locks. */ if (errno != EAGAIN) { TDB_LOG((tdb, 5, "tdb_brlock failed (fd=%d) at offset %d rw_type=%d lck_type=%d: %s\n", tdb->fd, offset, rw_type, lck_type, strerror(errno))); } return TDB_ERRCODE(TDB_ERR_LOCK, -1); } return 0; } /* lock a list in the database. list -1 is the alloc list */ static int tdb_lock(TDB_CONTEXT *tdb, int list, int ltype) { if (list < -1 || list >= (int)tdb->header.hash_size) { TDB_LOG((tdb, 0,"tdb_lock: invalid list %d for ltype=%d\n", list, ltype)); return -1; } if (tdb->flags & TDB_NOLOCK) return 0; /* Since fcntl locks don't nest, we do a lock for the first one, and simply bump the count for future ones */ if (tdb->locked[list+1].count == 0) { if (!tdb->read_only && tdb->header.rwlocks) { if (tdb_spinlock(tdb, list, ltype)) { TDB_LOG((tdb, 0, "tdb_lock spinlock failed on list %d ltype=%d\n", list, ltype)); return -1; } } else if (tdb_brlock(tdb,FREELIST_TOP+4*list,ltype,F_SETLKW, 0)) { TDB_LOG((tdb, 0,"tdb_lock failed on list %d ltype=%d (%s)\n", list, ltype, strerror(errno))); return -1; } tdb->locked[list+1].ltype = ltype; } tdb->locked[list+1].count++; return 0; } /* unlock the database: returns void because it's too late for errors. */ /* changed to return int it may be interesting to know there has been an error --simo */ static int tdb_unlock(TDB_CONTEXT *tdb, int list, int ltype) { int ret = -1; if (tdb->flags & TDB_NOLOCK) return 0; /* Sanity checks */ if (list < -1 || list >= (int)tdb->header.hash_size) { TDB_LOG((tdb, 0, "tdb_unlock: list %d invalid (%d)\n", list, tdb->header.hash_size)); return ret; } if (tdb->locked[list+1].count==0) { TDB_LOG((tdb, 0, "tdb_unlock: count is 0\n")); return ret; } if (tdb->locked[list+1].count == 1) { /* Down to last nested lock: unlock underneath */ if (!tdb->read_only && tdb->header.rwlocks) { ret = tdb_spinunlock(tdb, list, ltype); } else { ret = tdb_brlock(tdb, FREELIST_TOP+4*list, F_UNLCK, F_SETLKW, 0); } } else { ret = 0; } tdb->locked[list+1].count--; if (ret) TDB_LOG((tdb, 0,"tdb_unlock: An error occurred unlocking!\n")); return ret; } /* check for an out of bounds access - if it is out of bounds then see if the database has been expanded by someone else and expand if necessary note that "len" is the minimum length needed for the db */ static int tdb_oob(TDB_CONTEXT *tdb, tdb_off len, int probe) { struct stat st; if (len <= tdb->map_size) return 0; if (tdb->flags & TDB_INTERNAL) { if (!probe) { /* Ensure ecode is set for log fn. */ tdb->ecode = TDB_ERR_IO; TDB_LOG((tdb, 0,"tdb_oob len %d beyond internal malloc size %d\n", (int)len, (int)tdb->map_size)); } return TDB_ERRCODE(TDB_ERR_IO, -1); } if (fstat(tdb->fd, &st) == -1) return TDB_ERRCODE(TDB_ERR_IO, -1); if (st.st_size < (size_t)len) { if (!probe) { /* Ensure ecode is set for log fn. */ tdb->ecode = TDB_ERR_IO; TDB_LOG((tdb, 0,"tdb_oob len %d beyond eof at %d\n", (int)len, (int)st.st_size)); } return TDB_ERRCODE(TDB_ERR_IO, -1); } /* Unmap, update size, remap */ if (tdb_munmap(tdb) == -1) return TDB_ERRCODE(TDB_ERR_IO, -1); tdb->map_size = st.st_size; tdb_mmap(tdb); return 0; } /* write a lump of data at a specified offset */ static int tdb_write(TDB_CONTEXT *tdb, tdb_off off, void *buf, tdb_len len) { if (tdb_oob(tdb, off + len, 0) != 0) return -1; if (tdb->map_ptr) memcpy(off + (char *)tdb->map_ptr, buf, len); #ifdef HAVE_PWRITE else if (pwrite(tdb->fd, buf, len, off) != (ssize_t)len) { #else else if (lseek(tdb->fd, off, SEEK_SET) != off || write(tdb->fd, buf, len) != (ssize_t)len) { #endif /* Ensure ecode is set for log fn. */ tdb->ecode = TDB_ERR_IO; TDB_LOG((tdb, 0,"tdb_write failed at %d len=%d (%s)\n", off, len, strerror(errno))); return TDB_ERRCODE(TDB_ERR_IO, -1); } return 0; } /* read a lump of data at a specified offset, maybe convert */ static int tdb_read(TDB_CONTEXT *tdb,tdb_off off,void *buf,tdb_len len,int cv) { if (tdb_oob(tdb, off + len, 0) != 0) return -1; if (tdb->map_ptr) memcpy(buf, off + (char *)tdb->map_ptr, len); #ifdef HAVE_PREAD else if (pread(tdb->fd, buf, len, off) != (ssize_t)len) { #else else if (lseek(tdb->fd, off, SEEK_SET) != off || read(tdb->fd, buf, len) != (ssize_t)len) { #endif /* Ensure ecode is set for log fn. */ tdb->ecode = TDB_ERR_IO; TDB_LOG((tdb, 0,"tdb_read failed at %d len=%d (%s)\n", off, len, strerror(errno))); return TDB_ERRCODE(TDB_ERR_IO, -1); } if (cv) convert(buf, len); return 0; } /* read a lump of data, allocating the space for it */ static char *tdb_alloc_read(TDB_CONTEXT *tdb, tdb_off offset, tdb_len len) { char *buf; if (!(buf = malloc(len))) { /* Ensure ecode is set for log fn. */ tdb->ecode = TDB_ERR_OOM; TDB_LOG((tdb, 0,"tdb_alloc_read malloc failed len=%d (%s)\n", len, strerror(errno))); return TDB_ERRCODE(TDB_ERR_OOM, buf); } if (tdb_read(tdb, offset, buf, len, 0) == -1) { SAFE_FREE(buf); return NULL; } return buf; } /* read/write a tdb_off */ static int ofs_read(TDB_CONTEXT *tdb, tdb_off offset, tdb_off *d) { return tdb_read(tdb, offset, (char*)d, sizeof(*d), DOCONV()); } static int ofs_write(TDB_CONTEXT *tdb, tdb_off offset, tdb_off *d) { tdb_off off = *d; return tdb_write(tdb, offset, CONVERT(off), sizeof(*d)); } /* read/write a record */ static int rec_read(TDB_CONTEXT *tdb, tdb_off offset, struct list_struct *rec) { if (tdb_read(tdb, offset, rec, sizeof(*rec),DOCONV()) == -1) return -1; if (TDB_BAD_MAGIC(rec)) { /* Ensure ecode is set for log fn. */ tdb->ecode = TDB_ERR_CORRUPT; TDB_LOG((tdb, 0,"rec_read bad magic 0x%x at offset=%d\n", rec->magic, offset)); return TDB_ERRCODE(TDB_ERR_CORRUPT, -1); } return tdb_oob(tdb, rec->next+sizeof(*rec), 0); } static int rec_write(TDB_CONTEXT *tdb, tdb_off offset, struct list_struct *rec) { struct list_struct r = *rec; return tdb_write(tdb, offset, CONVERT(r), sizeof(r)); } /* read a freelist record and check for simple errors */ static int rec_free_read(TDB_CONTEXT *tdb, tdb_off off, struct list_struct *rec) { if (tdb_read(tdb, off, rec, sizeof(*rec),DOCONV()) == -1) return -1; if (rec->magic == TDB_MAGIC) { /* this happens when a app is showdown while deleting a record - we should not completely fail when this happens */ TDB_LOG((tdb, 0,"rec_free_read non-free magic 0x%x at offset=%d - fixing\n", rec->magic, off)); rec->magic = TDB_FREE_MAGIC; if (tdb_write(tdb, off, rec, sizeof(*rec)) == -1) return -1; } if (rec->magic != TDB_FREE_MAGIC) { /* Ensure ecode is set for log fn. */ tdb->ecode = TDB_ERR_CORRUPT; TDB_LOG((tdb, 0,"rec_free_read bad magic 0x%x at offset=%d\n", rec->magic, off)); return TDB_ERRCODE(TDB_ERR_CORRUPT, -1); } if (tdb_oob(tdb, rec->next+sizeof(*rec), 0) != 0) return -1; return 0; } /* update a record tailer (must hold allocation lock) */ static int update_tailer(TDB_CONTEXT *tdb, tdb_off offset, const struct list_struct *rec) { tdb_off totalsize; /* Offset of tailer from record header */ totalsize = sizeof(*rec) + rec->rec_len; return ofs_write(tdb, offset + totalsize - sizeof(tdb_off), &totalsize); } static tdb_off tdb_dump_record(TDB_CONTEXT *tdb, tdb_off offset) { struct list_struct rec; tdb_off tailer_ofs, tailer; if (tdb_read(tdb, offset, (char *)&rec, sizeof(rec), DOCONV()) == -1) { printf("ERROR: failed to read record at %u\n", offset); return 0; } printf(" rec: offset=%u next=%d rec_len=%d key_len=%d data_len=%d full_hash=0x%x magic=0x%x\n", offset, rec.next, rec.rec_len, rec.key_len, rec.data_len, rec.full_hash, rec.magic); tailer_ofs = offset + sizeof(rec) + rec.rec_len - sizeof(tdb_off); if (ofs_read(tdb, tailer_ofs, &tailer) == -1) { printf("ERROR: failed to read tailer at %u\n", tailer_ofs); return rec.next; } if (tailer != rec.rec_len + sizeof(rec)) { printf("ERROR: tailer does not match record! tailer=%u totalsize=%u\n", (unsigned)tailer, (unsigned)(rec.rec_len + sizeof(rec))); } return rec.next; } static int tdb_dump_chain(TDB_CONTEXT *tdb, int i) { tdb_off rec_ptr, top; top = TDB_HASH_TOP(i); if (tdb_lock(tdb, i, F_WRLCK) != 0) return -1; if (ofs_read(tdb, top, &rec_ptr) == -1) return tdb_unlock(tdb, i, F_WRLCK); if (rec_ptr) printf("hash=%d\n", i); while (rec_ptr) { rec_ptr = tdb_dump_record(tdb, rec_ptr); } return tdb_unlock(tdb, i, F_WRLCK); } void tdb_dump_all(TDB_CONTEXT *tdb) { int i; for (i=0;iheader.hash_size;i++) { tdb_dump_chain(tdb, i); } printf("freelist:\n"); tdb_dump_chain(tdb, -1); } int tdb_printfreelist(TDB_CONTEXT *tdb) { int ret; long total_free = 0; tdb_off offset, rec_ptr; struct list_struct rec; if ((ret = tdb_lock(tdb, -1, F_WRLCK)) != 0) return ret; offset = FREELIST_TOP; /* read in the freelist top */ if (ofs_read(tdb, offset, &rec_ptr) == -1) { tdb_unlock(tdb, -1, F_WRLCK); return 0; } printf("freelist top=[0x%08x]\n", rec_ptr ); while (rec_ptr) { if (tdb_read(tdb, rec_ptr, (char *)&rec, sizeof(rec), DOCONV()) == -1) { tdb_unlock(tdb, -1, F_WRLCK); return -1; } if (rec.magic != TDB_FREE_MAGIC) { printf("bad magic 0x%08x in free list\n", rec.magic); tdb_unlock(tdb, -1, F_WRLCK); return -1; } printf("entry offset=[0x%08x], rec.rec_len = [0x%08x (%d)]\n", rec.next, rec.rec_len, rec.rec_len ); total_free += rec.rec_len; /* move to the next record */ rec_ptr = rec.next; } printf("total rec_len = [0x%08x (%d)]\n", (int)total_free, (int)total_free); return tdb_unlock(tdb, -1, F_WRLCK); } /* Remove an element from the freelist. Must have alloc lock. */ static int remove_from_freelist(TDB_CONTEXT *tdb, tdb_off off, tdb_off next) { tdb_off last_ptr, i; /* read in the freelist top */ last_ptr = FREELIST_TOP; while (ofs_read(tdb, last_ptr, &i) != -1 && i != 0) { if (i == off) { /* We've found it! */ return ofs_write(tdb, last_ptr, &next); } /* Follow chain (next offset is at start of record) */ last_ptr = i; } TDB_LOG((tdb, 0,"remove_from_freelist: not on list at off=%d\n", off)); return TDB_ERRCODE(TDB_ERR_CORRUPT, -1); } /* Add an element into the freelist. Merge adjacent records if neccessary. */ static int tdb_free(TDB_CONTEXT *tdb, tdb_off offset, struct list_struct *rec) { tdb_off right, left; /* Allocation and tailer lock */ if (tdb_lock(tdb, -1, F_WRLCK) != 0) return -1; /* set an initial tailer, so if we fail we don't leave a bogus record */ if (update_tailer(tdb, offset, rec) != 0) { TDB_LOG((tdb, 0, "tdb_free: upfate_tailer failed!\n")); goto fail; } /* Look right first (I'm an Australian, dammit) */ right = offset + sizeof(*rec) + rec->rec_len; if (right + sizeof(*rec) <= tdb->map_size) { struct list_struct r; if (tdb_read(tdb, right, &r, sizeof(r), DOCONV()) == -1) { TDB_LOG((tdb, 0, "tdb_free: right read failed at %u\n", right)); goto left; } /* If it's free, expand to include it. */ if (r.magic == TDB_FREE_MAGIC) { if (remove_from_freelist(tdb, right, r.next) == -1) { TDB_LOG((tdb, 0, "tdb_free: right free failed at %u\n", right)); goto left; } rec->rec_len += sizeof(r) + r.rec_len; } } left: /* Look left */ left = offset - sizeof(tdb_off); if (left > TDB_DATA_START(tdb->header.hash_size)) { struct list_struct l; tdb_off leftsize; /* Read in tailer and jump back to header */ if (ofs_read(tdb, left, &leftsize) == -1) { TDB_LOG((tdb, 0, "tdb_free: left offset read failed at %u\n", left)); goto update; } left = offset - leftsize; /* Now read in record */ if (tdb_read(tdb, left, &l, sizeof(l), DOCONV()) == -1) { TDB_LOG((tdb, 0, "tdb_free: left read failed at %u (%u)\n", left, leftsize)); goto update; } /* If it's free, expand to include it. */ if (l.magic == TDB_FREE_MAGIC) { if (remove_from_freelist(tdb, left, l.next) == -1) { TDB_LOG((tdb, 0, "tdb_free: left free failed at %u\n", left)); goto update; } else { offset = left; rec->rec_len += leftsize; } } } update: if (update_tailer(tdb, offset, rec) == -1) { TDB_LOG((tdb, 0, "tdb_free: update_tailer failed at %u\n", offset)); goto fail; } /* Now, prepend to free list */ rec->magic = TDB_FREE_MAGIC; if (ofs_read(tdb, FREELIST_TOP, &rec->next) == -1 || rec_write(tdb, offset, rec) == -1 || ofs_write(tdb, FREELIST_TOP, &offset) == -1) { TDB_LOG((tdb, 0, "tdb_free record write failed at offset=%d\n", offset)); goto fail; } /* And we're done. */ tdb_unlock(tdb, -1, F_WRLCK); return 0; fail: tdb_unlock(tdb, -1, F_WRLCK); return -1; } /* expand a file. we prefer to use ftruncate, as that is what posix says to use for mmap expansion */ static int expand_file(TDB_CONTEXT *tdb, tdb_off size, tdb_off addition) { char buf[1024]; #if HAVE_FTRUNCATE_EXTEND if (ftruncate(tdb->fd, size+addition) != 0) { TDB_LOG((tdb, 0, "expand_file ftruncate to %d failed (%s)\n", size+addition, strerror(errno))); return -1; } #else char b = 0; #ifdef HAVE_PWRITE if (pwrite(tdb->fd, &b, 1, (size+addition) - 1) != 1) { #else if (lseek(tdb->fd, (size+addition) - 1, SEEK_SET) != (size+addition) - 1 || write(tdb->fd, &b, 1) != 1) { #endif TDB_LOG((tdb, 0, "expand_file to %d failed (%s)\n", size+addition, strerror(errno))); return -1; } #endif /* now fill the file with something. This ensures that the file isn't sparse, which would be very bad if we ran out of disk. This must be done with write, not via mmap */ memset(buf, 0x42, sizeof(buf)); while (addition) { int n = addition>sizeof(buf)?sizeof(buf):addition; #ifdef HAVE_PWRITE int ret = pwrite(tdb->fd, buf, n, size); #else int ret; if (lseek(tdb->fd, size, SEEK_SET) != size) return -1; ret = write(tdb->fd, buf, n); #endif if (ret != n) { TDB_LOG((tdb, 0, "expand_file write of %d failed (%s)\n", n, strerror(errno))); return -1; } addition -= n; size += n; } return 0; } /* expand the database at least size bytes by expanding the underlying file and doing the mmap again if necessary */ static int tdb_expand(TDB_CONTEXT *tdb, tdb_off size) { struct list_struct rec; tdb_off offset; if (tdb_lock(tdb, -1, F_WRLCK) == -1) { TDB_LOG((tdb, 0, "lock failed in tdb_expand\n")); return -1; } /* must know about any previous expansions by another process */ tdb_oob(tdb, tdb->map_size + 1, 1); /* always make room for at least 10 more records, and round the database up to a multiple of TDB_PAGE_SIZE */ size = TDB_ALIGN(tdb->map_size + size*10, TDB_PAGE_SIZE) - tdb->map_size; if (!(tdb->flags & TDB_INTERNAL)) tdb_munmap(tdb); /* * We must ensure the file is unmapped before doing this * to ensure consistency with systems like OpenBSD where * writes and mmaps are not consistent. */ /* expand the file itself */ if (!(tdb->flags & TDB_INTERNAL)) { if (expand_file(tdb, tdb->map_size, size) != 0) goto fail; } tdb->map_size += size; if (tdb->flags & TDB_INTERNAL) tdb->map_ptr = realloc(tdb->map_ptr, tdb->map_size); else { /* * We must ensure the file is remapped before adding the space * to ensure consistency with systems like OpenBSD where * writes and mmaps are not consistent. */ /* We're ok if the mmap fails as we'll fallback to read/write */ tdb_mmap(tdb); } /* form a new freelist record */ memset(&rec,'\0',sizeof(rec)); rec.rec_len = size - sizeof(rec); /* link it into the free list */ offset = tdb->map_size - size; if (tdb_free(tdb, offset, &rec) == -1) goto fail; tdb_unlock(tdb, -1, F_WRLCK); return 0; fail: tdb_unlock(tdb, -1, F_WRLCK); return -1; } /* allocate some space from the free list. The offset returned points to a unconnected list_struct within the database with room for at least length bytes of total data 0 is returned if the space could not be allocated */ static tdb_off tdb_allocate(TDB_CONTEXT *tdb, tdb_len length, struct list_struct *rec) { tdb_off rec_ptr, last_ptr, newrec_ptr; struct list_struct newrec; memset(&newrec, '\0', sizeof(newrec)); if (tdb_lock(tdb, -1, F_WRLCK) == -1) return 0; /* Extra bytes required for tailer */ length += sizeof(tdb_off); again: last_ptr = FREELIST_TOP; /* read in the freelist top */ if (ofs_read(tdb, FREELIST_TOP, &rec_ptr) == -1) goto fail; /* keep looking until we find a freelist record big enough */ while (rec_ptr) { if (rec_free_read(tdb, rec_ptr, rec) == -1) goto fail; if (rec->rec_len >= length) { /* found it - now possibly split it up */ if (rec->rec_len > length + MIN_REC_SIZE) { /* Length of left piece */ length = TDB_ALIGN(length, TDB_ALIGNMENT); /* Right piece to go on free list */ newrec.rec_len = rec->rec_len - (sizeof(*rec) + length); newrec_ptr = rec_ptr + sizeof(*rec) + length; /* And left record is shortened */ rec->rec_len = length; } else newrec_ptr = 0; /* Remove allocated record from the free list */ if (ofs_write(tdb, last_ptr, &rec->next) == -1) goto fail; /* Update header: do this before we drop alloc lock, otherwise tdb_free() might try to merge with us, thinking we're free. (Thanks Jeremy Allison). */ rec->magic = TDB_MAGIC; if (rec_write(tdb, rec_ptr, rec) == -1) goto fail; /* Did we create new block? */ if (newrec_ptr) { /* Update allocated record tailer (we shortened it). */ if (update_tailer(tdb, rec_ptr, rec) == -1) goto fail; /* Free new record */ if (tdb_free(tdb, newrec_ptr, &newrec) == -1) goto fail; } /* all done - return the new record offset */ tdb_unlock(tdb, -1, F_WRLCK); return rec_ptr; } /* move to the next record */ last_ptr = rec_ptr; rec_ptr = rec->next; } /* we didn't find enough space. See if we can expand the database and if we can then try again */ if (tdb_expand(tdb, length + sizeof(*rec)) == 0) goto again; fail: tdb_unlock(tdb, -1, F_WRLCK); return 0; } /* initialise a new database with a specified hash size */ static int tdb_new_database(TDB_CONTEXT *tdb, int hash_size) { struct tdb_header *newdb; int size, ret = -1; /* We make it up in memory, then write it out if not internal */ size = sizeof(struct tdb_header) + (hash_size+1)*sizeof(tdb_off); if (!(newdb = calloc(size, 1))) return TDB_ERRCODE(TDB_ERR_OOM, -1); /* Fill in the header */ newdb->version = TDB_VERSION; newdb->hash_size = hash_size; if (tdb->flags & TDB_INTERNAL) { tdb->map_size = size; tdb->map_ptr = (char *)newdb; memcpy(&tdb->header, newdb, sizeof(tdb->header)); /* Convert the `ondisk' version if asked. */ CONVERT(*newdb); return 0; } if (lseek(tdb->fd, 0, SEEK_SET) == -1) goto fail; if (ftruncate(tdb->fd, 0) == -1) goto fail; /* This creates an endian-converted header, as if read from disk */ CONVERT(*newdb); memcpy(&tdb->header, newdb, sizeof(tdb->header)); /* Don't endian-convert the magic food! */ memcpy(newdb->magic_food, TDB_MAGIC_FOOD, strlen(TDB_MAGIC_FOOD)+1); if (write(tdb->fd, newdb, size) != size) ret = -1; else ret = tdb_create_rwlocks(tdb->fd, hash_size); fail: SAFE_FREE(newdb); return ret; } /* Returns 0 on fail. On success, return offset of record, and fills in rec */ static tdb_off tdb_find(TDB_CONTEXT *tdb, TDB_DATA key, u32 hash, struct list_struct *r) { tdb_off rec_ptr; /* read in the hash top */ if (ofs_read(tdb, TDB_HASH_TOP(hash), &rec_ptr) == -1) return 0; /* keep looking until we find the right record */ while (rec_ptr) { if (rec_read(tdb, rec_ptr, r) == -1) return 0; if (!TDB_DEAD(r) && hash==r->full_hash && key.dsize==r->key_len) { char *k; /* a very likely hit - read the key */ k = tdb_alloc_read(tdb, rec_ptr + sizeof(*r), r->key_len); if (!k) return 0; if (memcmp(key.dptr, k, key.dsize) == 0) { SAFE_FREE(k); return rec_ptr; } SAFE_FREE(k); } rec_ptr = r->next; } return TDB_ERRCODE(TDB_ERR_NOEXIST, 0); } /* As tdb_find, but if you succeed, keep the lock */ static tdb_off tdb_find_lock_hash(TDB_CONTEXT *tdb, TDB_DATA key, u32 hash, int locktype, struct list_struct *rec) { u32 rec_ptr; if (tdb_lock(tdb, BUCKET(hash), locktype) == -1) return 0; if (!(rec_ptr = tdb_find(tdb, key, hash, rec))) tdb_unlock(tdb, BUCKET(hash), locktype); return rec_ptr; } enum TDB_ERROR tdb_error(TDB_CONTEXT *tdb) { return tdb->ecode; } static struct tdb_errname { enum TDB_ERROR ecode; const char *estring; } emap[] = { {TDB_SUCCESS, "Success"}, {TDB_ERR_CORRUPT, "Corrupt database"}, {TDB_ERR_IO, "IO Error"}, {TDB_ERR_LOCK, "Locking error"}, {TDB_ERR_OOM, "Out of memory"}, {TDB_ERR_EXISTS, "Record exists"}, {TDB_ERR_NOLOCK, "Lock exists on other keys"}, {TDB_ERR_NOEXIST, "Record does not exist"} }; /* Error string for the last tdb error */ const char *tdb_errorstr(TDB_CONTEXT *tdb) { u32 i; for (i = 0; i < sizeof(emap) / sizeof(struct tdb_errname); i++) if (tdb->ecode == emap[i].ecode) return emap[i].estring; return "Invalid error code"; } /* update an entry in place - this only works if the new data size is <= the old data size and the key exists. on failure return -1. */ static int tdb_update_hash(TDB_CONTEXT *tdb, TDB_DATA key, u32 hash, TDB_DATA dbuf) { struct list_struct rec; tdb_off rec_ptr; /* find entry */ if (!(rec_ptr = tdb_find(tdb, key, hash, &rec))) return -1; /* must be long enough key, data and tailer */ if (rec.rec_len < key.dsize + dbuf.dsize + sizeof(tdb_off)) { tdb->ecode = TDB_SUCCESS; /* Not really an error */ return -1; } if (tdb_write(tdb, rec_ptr + sizeof(rec) + rec.key_len, dbuf.dptr, dbuf.dsize) == -1) return -1; if (dbuf.dsize != rec.data_len) { /* update size */ rec.data_len = dbuf.dsize; return rec_write(tdb, rec_ptr, &rec); } return 0; } /* find an entry in the database given a key */ /* If an entry doesn't exist tdb_err will be set to * TDB_ERR_NOEXIST. If a key has no data attached * tdb_err will not be set. Both will return a * zero pptr and zero dsize. */ TDB_DATA tdb_fetch(TDB_CONTEXT *tdb, TDB_DATA key) { tdb_off rec_ptr; struct list_struct rec; TDB_DATA ret; u32 hash; /* find which hash bucket it is in */ hash = tdb->hash_fn(&key); if (!(rec_ptr = tdb_find_lock_hash(tdb,key,hash,F_RDLCK,&rec))) return tdb_null; if (rec.data_len) ret.dptr = tdb_alloc_read(tdb, rec_ptr + sizeof(rec) + rec.key_len, rec.data_len); else ret.dptr = NULL; ret.dsize = rec.data_len; tdb_unlock(tdb, BUCKET(rec.full_hash), F_RDLCK); return ret; } /* check if an entry in the database exists note that 1 is returned if the key is found and 0 is returned if not found this doesn't match the conventions in the rest of this module, but is compatible with gdbm */ static int tdb_exists_hash(TDB_CONTEXT *tdb, TDB_DATA key, u32 hash) { struct list_struct rec; if (tdb_find_lock_hash(tdb, key, hash, F_RDLCK, &rec) == 0) return 0; tdb_unlock(tdb, BUCKET(rec.full_hash), F_RDLCK); return 1; } int tdb_exists(TDB_CONTEXT *tdb, TDB_DATA key) { u32 hash = tdb->hash_fn(&key); return tdb_exists_hash(tdb, key, hash); } /* record lock stops delete underneath */ static int lock_record(TDB_CONTEXT *tdb, tdb_off off) { return off ? tdb_brlock(tdb, off, F_RDLCK, F_SETLKW, 0) : 0; } /* Write locks override our own fcntl readlocks, so check it here. Note this is meant to be F_SETLK, *not* F_SETLKW, as it's not an error to fail to get the lock here. */ static int write_lock_record(TDB_CONTEXT *tdb, tdb_off off) { struct tdb_traverse_lock *i; for (i = &tdb->travlocks; i; i = i->next) if (i->off == off) return -1; return tdb_brlock(tdb, off, F_WRLCK, F_SETLK, 1); } /* Note this is meant to be F_SETLK, *not* F_SETLKW, as it's not an error to fail to get the lock here. */ static int write_unlock_record(TDB_CONTEXT *tdb, tdb_off off) { return tdb_brlock(tdb, off, F_UNLCK, F_SETLK, 0); } /* fcntl locks don't stack: avoid unlocking someone else's */ static int unlock_record(TDB_CONTEXT *tdb, tdb_off off) { struct tdb_traverse_lock *i; u32 count = 0; if (off == 0) return 0; for (i = &tdb->travlocks; i; i = i->next) if (i->off == off) count++; return (count == 1 ? tdb_brlock(tdb, off, F_UNLCK, F_SETLKW, 0) : 0); } /* actually delete an entry in the database given the offset */ static int do_delete(TDB_CONTEXT *tdb, tdb_off rec_ptr, struct list_struct*rec) { tdb_off last_ptr, i; struct list_struct lastrec; if (tdb->read_only) return -1; if (write_lock_record(tdb, rec_ptr) == -1) { /* Someone traversing here: mark it as dead */ rec->magic = TDB_DEAD_MAGIC; return rec_write(tdb, rec_ptr, rec); } if (write_unlock_record(tdb, rec_ptr) != 0) return -1; /* find previous record in hash chain */ if (ofs_read(tdb, TDB_HASH_TOP(rec->full_hash), &i) == -1) return -1; for (last_ptr = 0; i != rec_ptr; last_ptr = i, i = lastrec.next) if (rec_read(tdb, i, &lastrec) == -1) return -1; /* unlink it: next ptr is at start of record. */ if (last_ptr == 0) last_ptr = TDB_HASH_TOP(rec->full_hash); if (ofs_write(tdb, last_ptr, &rec->next) == -1) return -1; /* recover the space */ if (tdb_free(tdb, rec_ptr, rec) == -1) return -1; return 0; } /* Uses traverse lock: 0 = finish, -1 = error, other = record offset */ static int tdb_next_lock(TDB_CONTEXT *tdb, struct tdb_traverse_lock *tlock, struct list_struct *rec) { int want_next = (tlock->off != 0); /* Lock each chain from the start one. */ for (; tlock->hash < tdb->header.hash_size; tlock->hash++) { if (tdb_lock(tdb, tlock->hash, F_WRLCK) == -1) return -1; /* No previous record? Start at top of chain. */ if (!tlock->off) { if (ofs_read(tdb, TDB_HASH_TOP(tlock->hash), &tlock->off) == -1) goto fail; } else { /* Otherwise unlock the previous record. */ if (unlock_record(tdb, tlock->off) != 0) goto fail; } if (want_next) { /* We have offset of old record: grab next */ if (rec_read(tdb, tlock->off, rec) == -1) goto fail; tlock->off = rec->next; } /* Iterate through chain */ while( tlock->off) { tdb_off current; if (rec_read(tdb, tlock->off, rec) == -1) goto fail; if (!TDB_DEAD(rec)) { /* Woohoo: we found one! */ if (lock_record(tdb, tlock->off) != 0) goto fail; return tlock->off; } /* Try to clean dead ones from old traverses */ current = tlock->off; tlock->off = rec->next; if (!tdb->read_only && do_delete(tdb, current, rec) != 0) goto fail; } tdb_unlock(tdb, tlock->hash, F_WRLCK); want_next = 0; } /* We finished iteration without finding anything */ return TDB_ERRCODE(TDB_SUCCESS, 0); fail: tlock->off = 0; if (tdb_unlock(tdb, tlock->hash, F_WRLCK) != 0) TDB_LOG((tdb, 0, "tdb_next_lock: On error unlock failed!\n")); return -1; } /* traverse the entire database - calling fn(tdb, key, data) on each element. return -1 on error or the record count traversed if fn is NULL then it is not called a non-zero return value from fn() indicates that the traversal should stop */ int tdb_traverse(TDB_CONTEXT *tdb, tdb_traverse_func fn, void *private) { TDB_DATA key, dbuf; struct list_struct rec; struct tdb_traverse_lock tl = { NULL, 0, 0 }; int ret, count = 0; /* This was in the initializaton, above, but the IRIX compiler * did not like it. crh */ tl.next = tdb->travlocks.next; /* fcntl locks don't stack: beware traverse inside traverse */ tdb->travlocks.next = &tl; /* tdb_next_lock places locks on the record returned, and its chain */ while ((ret = tdb_next_lock(tdb, &tl, &rec)) > 0) { count++; /* now read the full record */ key.dptr = tdb_alloc_read(tdb, tl.off + sizeof(rec), rec.key_len + rec.data_len); if (!key.dptr) { ret = -1; if (tdb_unlock(tdb, tl.hash, F_WRLCK) != 0) goto out; if (unlock_record(tdb, tl.off) != 0) TDB_LOG((tdb, 0, "tdb_traverse: key.dptr == NULL and unlock_record failed!\n")); goto out; } key.dsize = rec.key_len; dbuf.dptr = key.dptr + rec.key_len; dbuf.dsize = rec.data_len; /* Drop chain lock, call out */ if (tdb_unlock(tdb, tl.hash, F_WRLCK) != 0) { ret = -1; goto out; } if (fn && fn(tdb, key, dbuf, private)) { /* They want us to terminate traversal */ ret = count; if (unlock_record(tdb, tl.off) != 0) { TDB_LOG((tdb, 0, "tdb_traverse: unlock_record failed!\n"));; ret = -1; } tdb->travlocks.next = tl.next; SAFE_FREE(key.dptr); return count; } SAFE_FREE(key.dptr); } out: tdb->travlocks.next = tl.next; if (ret < 0) return -1; else return count; } /* find the first entry in the database and return its key */ TDB_DATA tdb_firstkey(TDB_CONTEXT *tdb) { TDB_DATA key; struct list_struct rec; /* release any old lock */ if (unlock_record(tdb, tdb->travlocks.off) != 0) return tdb_null; tdb->travlocks.off = tdb->travlocks.hash = 0; if (tdb_next_lock(tdb, &tdb->travlocks, &rec) <= 0) return tdb_null; /* now read the key */ key.dsize = rec.key_len; key.dptr =tdb_alloc_read(tdb,tdb->travlocks.off+sizeof(rec),key.dsize); if (tdb_unlock(tdb, BUCKET(tdb->travlocks.hash), F_WRLCK) != 0) TDB_LOG((tdb, 0, "tdb_firstkey: error occurred while tdb_unlocking!\n")); return key; } /* find the next entry in the database, returning its key */ TDB_DATA tdb_nextkey(TDB_CONTEXT *tdb, TDB_DATA oldkey) { u32 oldhash; TDB_DATA key = tdb_null; struct list_struct rec; char *k = NULL; /* Is locked key the old key? If so, traverse will be reliable. */ if (tdb->travlocks.off) { if (tdb_lock(tdb,tdb->travlocks.hash,F_WRLCK)) return tdb_null; if (rec_read(tdb, tdb->travlocks.off, &rec) == -1 || !(k = tdb_alloc_read(tdb,tdb->travlocks.off+sizeof(rec), rec.key_len)) || memcmp(k, oldkey.dptr, oldkey.dsize) != 0) { /* No, it wasn't: unlock it and start from scratch */ if (unlock_record(tdb, tdb->travlocks.off) != 0) return tdb_null; if (tdb_unlock(tdb, tdb->travlocks.hash, F_WRLCK) != 0) return tdb_null; tdb->travlocks.off = 0; } SAFE_FREE(k); } if (!tdb->travlocks.off) { /* No previous element: do normal find, and lock record */ tdb->travlocks.off = tdb_find_lock_hash(tdb, oldkey, tdb->hash_fn(&oldkey), F_WRLCK, &rec); if (!tdb->travlocks.off) return tdb_null; tdb->travlocks.hash = BUCKET(rec.full_hash); if (lock_record(tdb, tdb->travlocks.off) != 0) { TDB_LOG((tdb, 0, "tdb_nextkey: lock_record failed (%s)!\n", strerror(errno))); return tdb_null; } } oldhash = tdb->travlocks.hash; /* Grab next record: locks chain and returned record, unlocks old record */ if (tdb_next_lock(tdb, &tdb->travlocks, &rec) > 0) { key.dsize = rec.key_len; key.dptr = tdb_alloc_read(tdb, tdb->travlocks.off+sizeof(rec), key.dsize); /* Unlock the chain of this new record */ if (tdb_unlock(tdb, tdb->travlocks.hash, F_WRLCK) != 0) TDB_LOG((tdb, 0, "tdb_nextkey: WARNING tdb_unlock failed!\n")); } /* Unlock the chain of old record */ if (tdb_unlock(tdb, BUCKET(oldhash), F_WRLCK) != 0) TDB_LOG((tdb, 0, "tdb_nextkey: WARNING tdb_unlock failed!\n")); return key; } /* delete an entry in the database given a key */ static int tdb_delete_hash(TDB_CONTEXT *tdb, TDB_DATA key, u32 hash) { tdb_off rec_ptr; struct list_struct rec; int ret; if (!(rec_ptr = tdb_find_lock_hash(tdb, key, hash, F_WRLCK, &rec))) return -1; ret = do_delete(tdb, rec_ptr, &rec); if (tdb_unlock(tdb, BUCKET(rec.full_hash), F_WRLCK) != 0) TDB_LOG((tdb, 0, "tdb_delete: WARNING tdb_unlock failed!\n")); return ret; } int tdb_delete(TDB_CONTEXT *tdb, TDB_DATA key) { u32 hash = tdb->hash_fn(&key); return tdb_delete_hash(tdb, key, hash); } /* store an element in the database, replacing any existing element with the same key return 0 on success, -1 on failure */ int tdb_store(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, int flag) { struct list_struct rec; u32 hash; tdb_off rec_ptr; char *p = NULL; int ret = 0; /* find which hash bucket it is in */ hash = tdb->hash_fn(&key); if (tdb_lock(tdb, BUCKET(hash), F_WRLCK) == -1) return -1; /* check for it existing, on insert. */ if (flag == TDB_INSERT) { if (tdb_exists_hash(tdb, key, hash)) { tdb->ecode = TDB_ERR_EXISTS; goto fail; } } else { /* first try in-place update, on modify or replace. */ if (tdb_update_hash(tdb, key, hash, dbuf) == 0) goto out; if (tdb->ecode == TDB_ERR_NOEXIST && flag == TDB_MODIFY) { /* if the record doesn't exist and we are in TDB_MODIFY mode then we should fail the store */ goto fail; } } /* reset the error code potentially set by the tdb_update() */ tdb->ecode = TDB_SUCCESS; /* delete any existing record - if it doesn't exist we don't care. Doing this first reduces fragmentation, and avoids coalescing with `allocated' block before it's updated. */ if (flag != TDB_INSERT) tdb_delete_hash(tdb, key, hash); /* Copy key+value *before* allocating free space in case malloc fails and we are left with a dead spot in the tdb. */ if (!(p = (char *)malloc(key.dsize + dbuf.dsize))) { tdb->ecode = TDB_ERR_OOM; goto fail; } memcpy(p, key.dptr, key.dsize); if (dbuf.dsize) memcpy(p+key.dsize, dbuf.dptr, dbuf.dsize); /* we have to allocate some space */ if (!(rec_ptr = tdb_allocate(tdb, key.dsize + dbuf.dsize, &rec))) goto fail; /* Read hash top into next ptr */ if (ofs_read(tdb, TDB_HASH_TOP(hash), &rec.next) == -1) goto fail; rec.key_len = key.dsize; rec.data_len = dbuf.dsize; rec.full_hash = hash; rec.magic = TDB_MAGIC; /* write out and point the top of the hash chain at it */ if (rec_write(tdb, rec_ptr, &rec) == -1 || tdb_write(tdb, rec_ptr+sizeof(rec), p, key.dsize+dbuf.dsize)==-1 || ofs_write(tdb, TDB_HASH_TOP(hash), &rec_ptr) == -1) { /* Need to tdb_unallocate() here */ goto fail; } out: SAFE_FREE(p); tdb_unlock(tdb, BUCKET(hash), F_WRLCK); return ret; fail: ret = -1; goto out; } /* Attempt to append data to an entry in place - this only works if the new data size is <= the old data size and the key exists. on failure return -1. Record must be locked before calling. */ static int tdb_append_inplace(TDB_CONTEXT *tdb, TDB_DATA key, u32 hash, TDB_DATA new_dbuf) { struct list_struct rec; tdb_off rec_ptr; /* find entry */ if (!(rec_ptr = tdb_find(tdb, key, hash, &rec))) return -1; /* Append of 0 is always ok. */ if (new_dbuf.dsize == 0) return 0; /* must be long enough for key, old data + new data and tailer */ if (rec.rec_len < key.dsize + rec.data_len + new_dbuf.dsize + sizeof(tdb_off)) { /* No room. */ tdb->ecode = TDB_SUCCESS; /* Not really an error */ return -1; } if (tdb_write(tdb, rec_ptr + sizeof(rec) + rec.key_len + rec.data_len, new_dbuf.dptr, new_dbuf.dsize) == -1) return -1; /* update size */ rec.data_len += new_dbuf.dsize; return rec_write(tdb, rec_ptr, &rec); } /* Append to an entry. Create if not exist. */ int tdb_append(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA new_dbuf) { struct list_struct rec; u32 hash; tdb_off rec_ptr; char *p = NULL; int ret = 0; size_t new_data_size = 0; /* find which hash bucket it is in */ hash = tdb->hash_fn(&key); if (tdb_lock(tdb, BUCKET(hash), F_WRLCK) == -1) return -1; /* first try in-place. */ if (tdb_append_inplace(tdb, key, hash, new_dbuf) == 0) goto out; /* reset the error code potentially set by the tdb_append_inplace() */ tdb->ecode = TDB_SUCCESS; /* find entry */ if (!(rec_ptr = tdb_find(tdb, key, hash, &rec))) { if (tdb->ecode != TDB_ERR_NOEXIST) goto fail; /* Not found - create. */ ret = tdb_store(tdb, key, new_dbuf, TDB_INSERT); goto out; } new_data_size = rec.data_len + new_dbuf.dsize; /* Copy key+old_value+value *before* allocating free space in case malloc fails and we are left with a dead spot in the tdb. */ if (!(p = (char *)malloc(key.dsize + new_data_size))) { tdb->ecode = TDB_ERR_OOM; goto fail; } /* Copy the key in place. */ memcpy(p, key.dptr, key.dsize); /* Now read the old data into place. */ if (rec.data_len && tdb_read(tdb, rec_ptr + sizeof(rec) + rec.key_len, p + key.dsize, rec.data_len, 0) == -1) goto fail; /* Finally append the new data. */ if (new_dbuf.dsize) memcpy(p+key.dsize+rec.data_len, new_dbuf.dptr, new_dbuf.dsize); /* delete any existing record - if it doesn't exist we don't care. Doing this first reduces fragmentation, and avoids coalescing with `allocated' block before it's updated. */ tdb_delete_hash(tdb, key, hash); if (!(rec_ptr = tdb_allocate(tdb, key.dsize + new_data_size, &rec))) goto fail; /* Read hash top into next ptr */ if (ofs_read(tdb, TDB_HASH_TOP(hash), &rec.next) == -1) goto fail; rec.key_len = key.dsize; rec.data_len = new_data_size; rec.full_hash = hash; rec.magic = TDB_MAGIC; /* write out and point the top of the hash chain at it */ if (rec_write(tdb, rec_ptr, &rec) == -1 || tdb_write(tdb, rec_ptr+sizeof(rec), p, key.dsize+new_data_size)==-1 || ofs_write(tdb, TDB_HASH_TOP(hash), &rec_ptr) == -1) { /* Need to tdb_unallocate() here */ goto fail; } out: SAFE_FREE(p); tdb_unlock(tdb, BUCKET(hash), F_WRLCK); return ret; fail: ret = -1; goto out; } static int tdb_already_open(dev_t device, ino_t ino) { TDB_CONTEXT *i; for (i = tdbs; i; i = i->next) { if (i->device == device && i->inode == ino) { return 1; } } return 0; } /* This is based on the hash algorithm from gdbm */ static u32 default_tdb_hash(TDB_DATA *key) { u32 value; /* Used to compute the hash value. */ u32 i; /* Used to cycle through random values. */ /* Set the initial value from the key size. */ for (value = 0x238F13AF * key->dsize, i=0; i < key->dsize; i++) value = (value + (key->dptr[i] << (i*5 % 24))); return (1103515243 * value + 12345); } /* open the database, creating it if necessary The open_flags and mode are passed straight to the open call on the database file. A flags value of O_WRONLY is invalid. The hash size is advisory, use zero for a default value. Return is NULL on error, in which case errno is also set. Don't try to call tdb_error or tdb_errname, just do strerror(errno). @param name may be NULL for internal databases. */ TDB_CONTEXT *tdb_open(const char *name, int hash_size, int tdb_flags, int open_flags, mode_t mode) { return tdb_open_ex(name, hash_size, tdb_flags, open_flags, mode, NULL, NULL); } TDB_CONTEXT *tdb_open_ex(const char *name, int hash_size, int tdb_flags, int open_flags, mode_t mode, tdb_log_func log_fn, tdb_hash_func hash_fn) { TDB_CONTEXT *tdb; struct stat st; int rev = 0, locked = 0; unsigned char *vp; u32 vertest; if (!(tdb = calloc(1, sizeof *tdb))) { /* Can't log this */ errno = ENOMEM; goto fail; } tdb->fd = -1; tdb->name = NULL; tdb->map_ptr = NULL; tdb->flags = tdb_flags; tdb->open_flags = open_flags; tdb->log_fn = log_fn; tdb->hash_fn = hash_fn ? hash_fn : default_tdb_hash; if ((open_flags & O_ACCMODE) == O_WRONLY) { TDB_LOG((tdb, 0, "tdb_open_ex: can't open tdb %s write-only\n", name)); errno = EINVAL; goto fail; } if (hash_size == 0) hash_size = DEFAULT_HASH_SIZE; if ((open_flags & O_ACCMODE) == O_RDONLY) { tdb->read_only = 1; /* read only databases don't do locking or clear if first */ tdb->flags |= TDB_NOLOCK; tdb->flags &= ~TDB_CLEAR_IF_FIRST; } /* internal databases don't mmap or lock, and start off cleared */ if (tdb->flags & TDB_INTERNAL) { tdb->flags |= (TDB_NOLOCK | TDB_NOMMAP); tdb->flags &= ~TDB_CLEAR_IF_FIRST; if (tdb_new_database(tdb, hash_size) != 0) { TDB_LOG((tdb, 0, "tdb_open_ex: tdb_new_database failed!")); goto fail; } goto internal; } if ((tdb->fd = open(name, open_flags, mode)) == -1) { TDB_LOG((tdb, 5, "tdb_open_ex: could not open file %s: %s\n", name, strerror(errno))); goto fail; /* errno set by open(2) */ } /* ensure there is only one process initialising at once */ if (tdb_brlock(tdb, GLOBAL_LOCK, F_WRLCK, F_SETLKW, 0) == -1) { TDB_LOG((tdb, 0, "tdb_open_ex: failed to get global lock on %s: %s\n", name, strerror(errno))); goto fail; /* errno set by tdb_brlock */ } /* we need to zero database if we are the only one with it open */ if ((tdb_flags & TDB_CLEAR_IF_FIRST) && (locked = (tdb_brlock(tdb, ACTIVE_LOCK, F_WRLCK, F_SETLK, 0) == 0))) { open_flags |= O_CREAT; if (ftruncate(tdb->fd, 0) == -1) { TDB_LOG((tdb, 0, "tdb_open_ex: " "failed to truncate %s: %s\n", name, strerror(errno))); goto fail; /* errno set by ftruncate */ } } if (read(tdb->fd, &tdb->header, sizeof(tdb->header)) != sizeof(tdb->header) || strcmp(tdb->header.magic_food, TDB_MAGIC_FOOD) != 0 || (tdb->header.version != TDB_VERSION && !(rev = (tdb->header.version==TDB_BYTEREV(TDB_VERSION))))) { /* its not a valid database - possibly initialise it */ if (!(open_flags & O_CREAT) || tdb_new_database(tdb, hash_size) == -1) { errno = EIO; /* ie bad format or something */ goto fail; } rev = (tdb->flags & TDB_CONVERT); } vp = (unsigned char *)&tdb->header.version; vertest = (((u32)vp[0]) << 24) | (((u32)vp[1]) << 16) | (((u32)vp[2]) << 8) | (u32)vp[3]; tdb->flags |= (vertest==TDB_VERSION) ? TDB_BIGENDIAN : 0; if (!rev) tdb->flags &= ~TDB_CONVERT; else { tdb->flags |= TDB_CONVERT; convert(&tdb->header, sizeof(tdb->header)); } if (fstat(tdb->fd, &st) == -1) goto fail; /* Is it already in the open list? If so, fail. */ if (tdb_already_open(st.st_dev, st.st_ino)) { TDB_LOG((tdb, 2, "tdb_open_ex: " "%s (%d,%d) is already open in this process\n", name, (int)st.st_dev, (int)st.st_ino)); errno = EBUSY; goto fail; } if (!(tdb->name = (char *)strdup(name))) { errno = ENOMEM; goto fail; } tdb->map_size = st.st_size; tdb->device = st.st_dev; tdb->inode = st.st_ino; tdb->locked = calloc(tdb->header.hash_size+1, sizeof(tdb->locked[0])); if (!tdb->locked) { TDB_LOG((tdb, 2, "tdb_open_ex: " "failed to allocate lock structure for %s\n", name)); errno = ENOMEM; goto fail; } tdb_mmap(tdb); if (locked) { if (!tdb->read_only) if (tdb_clear_spinlocks(tdb) != 0) { TDB_LOG((tdb, 0, "tdb_open_ex: " "failed to clear spinlock\n")); goto fail; } if (tdb_brlock(tdb, ACTIVE_LOCK, F_UNLCK, F_SETLK, 0) == -1) { TDB_LOG((tdb, 0, "tdb_open_ex: " "failed to take ACTIVE_LOCK on %s: %s\n", name, strerror(errno))); goto fail; } } /* We always need to do this if the CLEAR_IF_FIRST flag is set, even if we didn't get the initial exclusive lock as we need to let all other users know we're using it. */ if (tdb_flags & TDB_CLEAR_IF_FIRST) { /* leave this lock in place to indicate it's in use */ if (tdb_brlock(tdb, ACTIVE_LOCK, F_RDLCK, F_SETLKW, 0) == -1) goto fail; } internal: /* Internal (memory-only) databases skip all the code above to * do with disk files, and resume here by releasing their * global lock and hooking into the active list. */ if (tdb_brlock(tdb, GLOBAL_LOCK, F_UNLCK, F_SETLKW, 0) == -1) goto fail; tdb->next = tdbs; tdbs = tdb; return tdb; fail: { int save_errno = errno; if (!tdb) return NULL; if (tdb->map_ptr) { if (tdb->flags & TDB_INTERNAL) SAFE_FREE(tdb->map_ptr); else tdb_munmap(tdb); } SAFE_FREE(tdb->name); if (tdb->fd != -1) if (close(tdb->fd) != 0) TDB_LOG((tdb, 5, "tdb_open_ex: failed to close tdb->fd on error!\n")); SAFE_FREE(tdb->locked); SAFE_FREE(tdb); errno = save_errno; return NULL; } } /** * Close a database. * * @returns -1 for error; 0 for success. **/ int tdb_close(TDB_CONTEXT *tdb) { TDB_CONTEXT **i; int ret = 0; if (tdb->map_ptr) { if (tdb->flags & TDB_INTERNAL) SAFE_FREE(tdb->map_ptr); else tdb_munmap(tdb); } SAFE_FREE(tdb->name); if (tdb->fd != -1) ret = close(tdb->fd); SAFE_FREE(tdb->locked); /* Remove from contexts list */ for (i = &tdbs; *i; i = &(*i)->next) { if (*i == tdb) { *i = tdb->next; break; } } memset(tdb, 0, sizeof(*tdb)); SAFE_FREE(tdb); return ret; } /* lock/unlock entire database */ int tdb_lockall(TDB_CONTEXT *tdb) { u32 i; /* There are no locks on read-only dbs */ if (tdb->read_only) return TDB_ERRCODE(TDB_ERR_LOCK, -1); for (i = 0; i < tdb->header.hash_size; i++) if (tdb_lock(tdb, i, F_WRLCK)) break; /* If error, release locks we have... */ if (i < tdb->header.hash_size) { u32 j; for ( j = 0; j < i; j++) tdb_unlock(tdb, j, F_WRLCK); return TDB_ERRCODE(TDB_ERR_NOLOCK, -1); } return 0; } void tdb_unlockall(TDB_CONTEXT *tdb) { u32 i; for (i=0; i < tdb->header.hash_size; i++) tdb_unlock(tdb, i, F_WRLCK); } /* lock/unlock one hash chain. This is meant to be used to reduce contention - it cannot guarantee how many records will be locked */ int tdb_chainlock(TDB_CONTEXT *tdb, TDB_DATA key) { return tdb_lock(tdb, BUCKET(tdb->hash_fn(&key)), F_WRLCK); } int tdb_chainunlock(TDB_CONTEXT *tdb, TDB_DATA key) { return tdb_unlock(tdb, BUCKET(tdb->hash_fn(&key)), F_WRLCK); } int tdb_chainlock_read(TDB_CONTEXT *tdb, TDB_DATA key) { return tdb_lock(tdb, BUCKET(tdb->hash_fn(&key)), F_RDLCK); } int tdb_chainunlock_read(TDB_CONTEXT *tdb, TDB_DATA key) { return tdb_unlock(tdb, BUCKET(tdb->hash_fn(&key)), F_RDLCK); } /* register a loging function */ void tdb_logging_function(TDB_CONTEXT *tdb, void (*fn)(TDB_CONTEXT *, int , const char *, ...)) { tdb->log_fn = fn; } /* reopen a tdb - this can be used after a fork to ensure that we have an independent seek pointer from our parent and to re-establish locks */ int tdb_reopen(TDB_CONTEXT *tdb) { struct stat st; if (tdb->flags & TDB_INTERNAL) return 0; /* Nothing to do. */ if (tdb_munmap(tdb) != 0) { TDB_LOG((tdb, 0, "tdb_reopen: munmap failed (%s)\n", strerror(errno))); goto fail; } if (close(tdb->fd) != 0) TDB_LOG((tdb, 0, "tdb_reopen: WARNING closing tdb->fd failed!\n")); tdb->fd = open(tdb->name, tdb->open_flags & ~(O_CREAT|O_TRUNC), 0); if (tdb->fd == -1) { TDB_LOG((tdb, 0, "tdb_reopen: open failed (%s)\n", strerror(errno))); goto fail; } if (fstat(tdb->fd, &st) != 0) { TDB_LOG((tdb, 0, "tdb_reopen: fstat failed (%s)\n", strerror(errno))); goto fail; } if (st.st_ino != tdb->inode || st.st_dev != tdb->device) { TDB_LOG((tdb, 0, "tdb_reopen: file dev/inode has changed!\n")); goto fail; } tdb_mmap(tdb); if ((tdb->flags & TDB_CLEAR_IF_FIRST) && (tdb_brlock(tdb, ACTIVE_LOCK, F_RDLCK, F_SETLKW, 0) == -1)) { TDB_LOG((tdb, 0, "tdb_reopen: failed to obtain active lock\n")); goto fail; } return 0; fail: tdb_close(tdb); return -1; } /* reopen all tdb's */ int tdb_reopen_all(void) { TDB_CONTEXT *tdb; for (tdb=tdbs; tdb; tdb = tdb->next) { /* Ensure no clear-if-first. */ tdb->flags &= ~TDB_CLEAR_IF_FIRST; if (tdb_reopen(tdb) != 0) return -1; } return 0; } ppp-2.5.0/pppd/spinlock.c0000664000175000017500000002177414076444143012213 00000000000000/* Unix SMB/CIFS implementation. trivial database library Copyright (C) Anton Blanchard 2001 ** NOTE! The following LGPL license applies to the tdb ** library. This does NOT imply that all of Samba is released ** under the LGPL This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include #include #include #include "tdb.h" #include "spinlock.h" #define DEBUG #ifdef USE_SPINLOCKS /* * ARCH SPECIFIC */ #if defined(SPARC_SPINLOCKS) static inline int __spin_trylock(spinlock_t *lock) { unsigned int result; asm volatile("ldstub [%1], %0" : "=r" (result) : "r" (lock) : "memory"); return (result == 0) ? 0 : EBUSY; } static inline void __spin_unlock(spinlock_t *lock) { asm volatile("":::"memory"); *lock = 0; } static inline void __spin_lock_init(spinlock_t *lock) { *lock = 0; } static inline int __spin_is_locked(spinlock_t *lock) { return (*lock != 0); } #elif defined(POWERPC_SPINLOCKS) static inline int __spin_trylock(spinlock_t *lock) { unsigned int result; __asm__ __volatile__( "1: lwarx %0,0,%1\n\ cmpwi 0,%0,0\n\ li %0,0\n\ bne- 2f\n\ li %0,1\n\ stwcx. %0,0,%1\n\ bne- 1b\n\ isync\n\ 2:" : "=&r"(result) : "r"(lock) : "cr0", "memory"); return (result == 1) ? 0 : EBUSY; } static inline void __spin_unlock(spinlock_t *lock) { asm volatile("eieio":::"memory"); *lock = 0; } static inline void __spin_lock_init(spinlock_t *lock) { *lock = 0; } static inline int __spin_is_locked(spinlock_t *lock) { return (*lock != 0); } #elif defined(INTEL_SPINLOCKS) static inline int __spin_trylock(spinlock_t *lock) { int oldval; asm volatile("xchgl %0,%1" : "=r" (oldval), "=m" (*lock) : "0" (0) : "memory"); return oldval > 0 ? 0 : EBUSY; } static inline void __spin_unlock(spinlock_t *lock) { asm volatile("":::"memory"); *lock = 1; } static inline void __spin_lock_init(spinlock_t *lock) { *lock = 1; } static inline int __spin_is_locked(spinlock_t *lock) { return (*lock != 1); } #elif defined(MIPS_SPINLOCKS) && defined(sgi) && (_COMPILER_VERSION >= 730) /* Implement spinlocks on IRIX using the MIPSPro atomic fetch operations. See * sync(3) for the details of the intrinsic operations. * * "sgi" and "_COMPILER_VERSION" are always defined by MIPSPro. */ #ifdef STANDALONE /* MIPSPro 7.3 has "__inline" as an extension, but not "inline. */ #define inline __inline #endif /* STANDALONE */ /* Returns 0 if the lock is acquired, EBUSY otherwise. */ static inline int __spin_trylock(spinlock_t *lock) { unsigned int val; val = __lock_test_and_set(lock, 1); return val == 0 ? 0 : EBUSY; } static inline void __spin_unlock(spinlock_t *lock) { __lock_release(lock); } static inline void __spin_lock_init(spinlock_t *lock) { __lock_release(lock); } /* Returns 1 if the lock is held, 0 otherwise. */ static inline int __spin_is_locked(spinlock_t *lock) { unsigned int val; val = __add_and_fetch(lock, 0); return val; } #elif defined(MIPS_SPINLOCKS) static inline unsigned int load_linked(unsigned long addr) { unsigned int res; __asm__ __volatile__("ll\t%0,(%1)" : "=r" (res) : "r" (addr)); return res; } static inline unsigned int store_conditional(unsigned long addr, unsigned int value) { unsigned int res; __asm__ __volatile__("sc\t%0,(%2)" : "=r" (res) : "0" (value), "r" (addr)); return res; } static inline int __spin_trylock(spinlock_t *lock) { unsigned int mw; do { mw = load_linked(lock); if (mw) return EBUSY; } while (!store_conditional(lock, 1)); asm volatile("":::"memory"); return 0; } static inline void __spin_unlock(spinlock_t *lock) { asm volatile("":::"memory"); *lock = 0; } static inline void __spin_lock_init(spinlock_t *lock) { *lock = 0; } static inline int __spin_is_locked(spinlock_t *lock) { return (*lock != 0); } #else #error Need to implement spinlock code in spinlock.c #endif /* * OS SPECIFIC */ static void yield_cpu(void) { struct timespec tm; #ifdef USE_SCHED_YIELD sched_yield(); #else /* Linux will busy loop for delays < 2ms on real time tasks */ tm.tv_sec = 0; tm.tv_nsec = 2000000L + 1; nanosleep(&tm, NULL); #endif } static int this_is_smp(void) { #if defined(HAVE_SYSCONF) && defined(SYSCONF_SC_NPROC_ONLN) return (sysconf(_SC_NPROC_ONLN) > 1) ? 1 : 0; #else return 0; #endif } /* * GENERIC */ static int smp_machine = 0; static inline void __spin_lock(spinlock_t *lock) { int ntries = 0; while(__spin_trylock(lock)) { while(__spin_is_locked(lock)) { if (smp_machine && ntries++ < MAX_BUSY_LOOPS) continue; yield_cpu(); } } } static void __read_lock(tdb_rwlock_t *rwlock) { int ntries = 0; while(1) { __spin_lock(&rwlock->lock); if (!(rwlock->count & RWLOCK_BIAS)) { rwlock->count++; __spin_unlock(&rwlock->lock); return; } __spin_unlock(&rwlock->lock); while(rwlock->count & RWLOCK_BIAS) { if (smp_machine && ntries++ < MAX_BUSY_LOOPS) continue; yield_cpu(); } } } static void __write_lock(tdb_rwlock_t *rwlock) { int ntries = 0; while(1) { __spin_lock(&rwlock->lock); if (rwlock->count == 0) { rwlock->count |= RWLOCK_BIAS; __spin_unlock(&rwlock->lock); return; } __spin_unlock(&rwlock->lock); while(rwlock->count != 0) { if (smp_machine && ntries++ < MAX_BUSY_LOOPS) continue; yield_cpu(); } } } static void __write_unlock(tdb_rwlock_t *rwlock) { __spin_lock(&rwlock->lock); #ifdef DEBUG if (!(rwlock->count & RWLOCK_BIAS)) fprintf(stderr, "bug: write_unlock\n"); #endif rwlock->count &= ~RWLOCK_BIAS; __spin_unlock(&rwlock->lock); } static void __read_unlock(tdb_rwlock_t *rwlock) { __spin_lock(&rwlock->lock); #ifdef DEBUG if (!rwlock->count) fprintf(stderr, "bug: read_unlock\n"); if (rwlock->count & RWLOCK_BIAS) fprintf(stderr, "bug: read_unlock\n"); #endif rwlock->count--; __spin_unlock(&rwlock->lock); } /* TDB SPECIFIC */ /* lock a list in the database. list -1 is the alloc list */ int tdb_spinlock(TDB_CONTEXT *tdb, int list, int rw_type) { tdb_rwlock_t *rwlocks; if (!tdb->map_ptr) return -1; rwlocks = (tdb_rwlock_t *)((char *)tdb->map_ptr + tdb->header.rwlocks); switch(rw_type) { case F_RDLCK: __read_lock(&rwlocks[list+1]); break; case F_WRLCK: __write_lock(&rwlocks[list+1]); break; default: return TDB_ERRCODE(TDB_ERR_LOCK, -1); } return 0; } /* unlock the database. */ int tdb_spinunlock(TDB_CONTEXT *tdb, int list, int rw_type) { tdb_rwlock_t *rwlocks; if (!tdb->map_ptr) return -1; rwlocks = (tdb_rwlock_t *)((char *)tdb->map_ptr + tdb->header.rwlocks); switch(rw_type) { case F_RDLCK: __read_unlock(&rwlocks[list+1]); break; case F_WRLCK: __write_unlock(&rwlocks[list+1]); break; default: return TDB_ERRCODE(TDB_ERR_LOCK, -1); } return 0; } int tdb_create_rwlocks(int fd, unsigned int hash_size) { unsigned size, i; tdb_rwlock_t *rwlocks; size = TDB_SPINLOCK_SIZE(hash_size); rwlocks = malloc(size); if (!rwlocks) return -1; for(i = 0; i < hash_size+1; i++) { __spin_lock_init(&rwlocks[i].lock); rwlocks[i].count = 0; } /* Write it out (appending to end) */ if (write(fd, rwlocks, size) != size) { free(rwlocks); return -1; } smp_machine = this_is_smp(); free(rwlocks); return 0; } int tdb_clear_spinlocks(TDB_CONTEXT *tdb) { tdb_rwlock_t *rwlocks; unsigned i; if (tdb->header.rwlocks == 0) return 0; if (!tdb->map_ptr) return -1; /* We're mmapped here */ rwlocks = (tdb_rwlock_t *)((char *)tdb->map_ptr + tdb->header.rwlocks); for(i = 0; i < tdb->header.hash_size+1; i++) { __spin_lock_init(&rwlocks[i].lock); rwlocks[i].count = 0; } return 0; } #else int tdb_create_rwlocks(int fd, unsigned int hash_size) { return 0; } int tdb_spinlock(TDB_CONTEXT *tdb, int list, int rw_type) { return -1; } int tdb_spinunlock(TDB_CONTEXT *tdb, int list, int rw_type) { return -1; } /* Non-spinlock version: remove spinlock pointer */ int tdb_clear_spinlocks(TDB_CONTEXT *tdb) { tdb_off off = (tdb_off)((char *)&tdb->header.rwlocks - (char *)&tdb->header); tdb->header.rwlocks = 0; if (lseek(tdb->fd, off, SEEK_SET) != off || write(tdb->fd, (void *)&tdb->header.rwlocks, sizeof(tdb->header.rwlocks)) != sizeof(tdb->header.rwlocks)) return -1; return 0; } #endif ppp-2.5.0/pppd/ipv6cp.c0000644000175000017500000013027514407475306011576 00000000000000/* * ipv6cp.c - PPP IPV6 Control Protocol. * * Copyright (c) 1999 Tommi Komulainen. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The name(s) of the authors of this software must not be used to * endorse or promote products derived from this software without * prior written permission. * * 4. Redistributions of any form whatsoever must retain the following * acknowledgment: * "This product includes software developed by Tommi Komulainen * ". * * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * */ /* Original version, based on RFC2023 : Copyright (c) 1995, 1996, 1997 Francis.Dupont@inria.fr, INRIA Rocquencourt, Alain.Durand@imag.fr, IMAG, Jean-Luc.Richier@imag.fr, IMAG-LSR. Copyright (c) 1998, 1999 Francis.Dupont@inria.fr, GIE DYADE, Alain.Durand@imag.fr, IMAG, Jean-Luc.Richier@imag.fr, IMAG-LSR. Ce travail a été fait au sein du GIE DYADE (Groupement d'Intérêt Économique ayant pour membres BULL S.A. et l'INRIA). Ce logiciel informatique est disponible aux conditions usuelles dans la recherche, c'est-à-dire qu'il peut être utilisé, copié, modifié, distribué à l'unique condition que ce texte soit conservé afin que l'origine de ce logiciel soit reconnue. Le nom de l'Institut National de Recherche en Informatique et en Automatique (INRIA), de l'IMAG, ou d'une personne morale ou physique ayant participé à l'élaboration de ce logiciel ne peut être utilisé sans son accord préalable explicite. Ce logiciel est fourni tel quel sans aucune garantie, support ou responsabilité d'aucune sorte. Ce logiciel est dérivé de sources d'origine "University of California at Berkeley" et "Digital Equipment Corporation" couvertes par des copyrights. L'Institut d'Informatique et de Mathématiques Appliquées de Grenoble (IMAG) est une fédération d'unités mixtes de recherche du CNRS, de l'Institut National Polytechnique de Grenoble et de l'Université Joseph Fourier regroupant sept laboratoires dont le laboratoire Logiciels, Systèmes, Réseaux (LSR). This work has been done in the context of GIE DYADE (joint R & D venture between BULL S.A. and INRIA). This software is available with usual "research" terms with the aim of retain credits of the software. Permission to use, copy, modify and distribute this software for any purpose and without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies, and the name of INRIA, IMAG, or any contributor not be used in advertising or publicity pertaining to this material without the prior explicit permission. The software is provided "as is" without any warranties, support or liabilities of any kind. This software is derived from source code from "University of California at Berkeley" and "Digital Equipment Corporation" protected by copyrights. Grenoble's Institute of Computer Science and Applied Mathematics (IMAG) is a federation of seven research units funded by the CNRS, National Polytechnic Institute of Grenoble and University Joseph Fourier. The research unit in Software, Systems, Networks (LSR) is member of IMAG. */ /* * Derived from : * * * ipcp.c - PPP IP Control Protocol. * * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The name "Carnegie Mellon University" must not be used to * endorse or promote products derived from this software without * prior written permission. For permission or any legal * details, please contact * Office of Technology Transfer * Carnegie Mellon University * 5000 Forbes Avenue * Pittsburgh, PA 15213-3890 * (412) 268-4387, fax: (412) 268-7395 * tech-transfer@andrew.cmu.edu * * 4. Redistributions of any form whatsoever must retain the following * acknowledgment: * "This product includes software developed by Computing Services * at Carnegie Mellon University (http://www.cmu.edu/computing/)." * * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /* * TODO: * * Proxy Neighbour Discovery. * * Better defines for selecting the ordering of * interface up / set address. (currently checks for __linux__, * since SVR4 && (SNI || __USLC__) didn't work properly) */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include #include #include #include #include #include "pppd-private.h" #include "options.h" #include "fsm.h" #include "eui64.h" #include "ipcp.h" #include "ipv6cp.h" #include "magic.h" #include "pathnames.h" /* global vars */ ipv6cp_options ipv6cp_wantoptions[NUM_PPP]; /* Options that we want to request */ ipv6cp_options ipv6cp_gotoptions[NUM_PPP]; /* Options that peer ack'd */ ipv6cp_options ipv6cp_allowoptions[NUM_PPP]; /* Options we allow peer to request */ ipv6cp_options ipv6cp_hisoptions[NUM_PPP]; /* Options that we ack'd */ int no_ifaceid_neg = 0; /* local vars */ static int default_route_set[NUM_PPP]; /* Have set up a default route */ static int ipv6cp_is_up; static bool ipv6cp_noremote; ipv6_up_hook_fn *ipv6_up_hook = NULL; ipv6_down_hook_fn *ipv6_down_hook = NULL; /* Notifiers for when IPCPv6 goes up and down */ struct notifier *ipv6_up_notifier = NULL; struct notifier *ipv6_down_notifier = NULL; /* * Callbacks for fsm code. (CI = Configuration Information) */ static void ipv6cp_resetci (fsm *); /* Reset our CI */ static int ipv6cp_cilen (fsm *); /* Return length of our CI */ static void ipv6cp_addci (fsm *, u_char *, int *); /* Add our CI */ static int ipv6cp_ackci (fsm *, u_char *, int); /* Peer ack'd our CI */ static int ipv6cp_nakci (fsm *, u_char *, int, int);/* Peer nak'd our CI */ static int ipv6cp_rejci (fsm *, u_char *, int); /* Peer rej'd our CI */ static int ipv6cp_reqci (fsm *, u_char *, int *, int); /* Rcv CI */ static void ipv6cp_up (fsm *); /* We're UP */ static void ipv6cp_down (fsm *); /* We're DOWN */ static void ipv6cp_finished (fsm *); /* Don't need lower layer */ fsm ipv6cp_fsm[NUM_PPP]; /* IPV6CP fsm structure */ static fsm_callbacks ipv6cp_callbacks = { /* IPV6CP callback routines */ ipv6cp_resetci, /* Reset our Configuration Information */ ipv6cp_cilen, /* Length of our Configuration Information */ ipv6cp_addci, /* Add our Configuration Information */ ipv6cp_ackci, /* ACK our Configuration Information */ ipv6cp_nakci, /* NAK our Configuration Information */ ipv6cp_rejci, /* Reject our Configuration Information */ ipv6cp_reqci, /* Request peer's Configuration Information */ ipv6cp_up, /* Called when fsm reaches OPENED state */ ipv6cp_down, /* Called when fsm leaves OPENED state */ NULL, /* Called when we want the lower layer up */ ipv6cp_finished, /* Called when we want the lower layer down */ NULL, /* Called when Protocol-Reject received */ NULL, /* Retransmission is necessary */ NULL, /* Called to handle protocol-specific codes */ "IPV6CP" /* String name of protocol */ }; /* * Command-line options. */ static int setifaceid (char **arg); static void printifaceid (struct option *, void (*)(void *, char *, ...), void *); static struct option ipv6cp_option_list[] = { { "ipv6", o_special, (void *)setifaceid, "Set interface identifiers for IPV6", OPT_A2PRINTER, (void *)printifaceid }, { "+ipv6", o_bool, &ipv6cp_protent.enabled_flag, "Enable IPv6 and IPv6CP", OPT_PRIO | 1 }, { "noipv6", o_bool, &ipv6cp_protent.enabled_flag, "Disable IPv6 and IPv6CP", OPT_PRIOSUB }, { "-ipv6", o_bool, &ipv6cp_protent.enabled_flag, "Disable IPv6 and IPv6CP", OPT_PRIOSUB | OPT_ALIAS }, { "ipv6cp-accept-local", o_bool, &ipv6cp_wantoptions[0].accept_local, "Accept peer's interface identifier for us", 1 }, { "ipv6cp-accept-remote", o_bool, &ipv6cp_wantoptions[0].accept_remote, "Accept peer's interface identifier for itself", 1 }, { "defaultroute6", o_bool, &ipv6cp_wantoptions[0].default_route, "Add default IPv6 route", OPT_ENABLE|1, &ipv6cp_allowoptions[0].default_route }, { "nodefaultroute6", o_bool, &ipv6cp_allowoptions[0].default_route, "disable defaultroute6 option", OPT_A2CLR, &ipv6cp_wantoptions[0].default_route }, { "-defaultroute6", o_bool, &ipv6cp_allowoptions[0].default_route, "disable defaultroute6 option", OPT_ALIAS | OPT_A2CLR, &ipv6cp_wantoptions[0].default_route }, { "ipv6cp-use-ipaddr", o_bool, &ipv6cp_allowoptions[0].use_ip, "Use (default) IPv4 addresses for both local and remote interface identifiers", 1 }, { "ipv6cp-use-persistent", o_bool, &ipv6cp_wantoptions[0].use_persistent, "Use uniquely-available persistent value for local interface identifier", 1 }, { "ipv6cp-use-remotenumber", o_bool, &ipv6cp_wantoptions[0].use_remotenumber, "Use remotenumber value for remote interface identifier", 1 }, #ifdef __linux__ { "ipv6cp-noremote", o_bool, &ipv6cp_noremote, "Allow peer to have no interface identifier", 1 }, #endif { "ipv6cp-nosend", o_bool, &ipv6cp_wantoptions[0].neg_ifaceid, "Don't send local interface identifier to peer", OPT_A2CLR }, { "ipv6cp-restart", o_int, &ipv6cp_fsm[0].timeouttime, "Set timeout for IPv6CP", OPT_PRIO }, { "ipv6cp-max-terminate", o_int, &ipv6cp_fsm[0].maxtermtransmits, "Set max #xmits for term-reqs", OPT_PRIO }, { "ipv6cp-max-configure", o_int, &ipv6cp_fsm[0].maxconfreqtransmits, "Set max #xmits for conf-reqs", OPT_PRIO }, { "ipv6cp-max-failure", o_int, &ipv6cp_fsm[0].maxnakloops, "Set max #conf-naks for IPv6CP", OPT_PRIO }, { NULL } }; /* * Protocol entry points from main code. */ static void ipv6cp_init (int); static void ipv6cp_open (int); static void ipv6cp_close (int, char *); static void ipv6cp_lowerup (int); static void ipv6cp_lowerdown (int); static void ipv6cp_input (int, u_char *, int); static void ipv6cp_protrej (int); static int ipv6cp_printpkt (u_char *, int, void (*) (void *, char *, ...), void *); static void ipv6_check_options (void); static int ipv6_demand_conf (int); static int ipv6_active_pkt (u_char *, int); struct protent ipv6cp_protent = { PPP_IPV6CP, ipv6cp_init, ipv6cp_input, ipv6cp_protrej, ipv6cp_lowerup, ipv6cp_lowerdown, ipv6cp_open, ipv6cp_close, ipv6cp_printpkt, NULL, 1, "IPV6CP", "IPV6", ipv6cp_option_list, ipv6_check_options, ipv6_demand_conf, ipv6_active_pkt }; static void ipv6cp_clear_addrs (int, eui64_t, eui64_t); static void ipv6cp_script (char *); static void ipv6cp_script_done (void *); /* * Lengths of configuration options. */ #define CILEN_VOID 2 #define CILEN_COMPRESS 4 /* length for RFC2023 compress opt. */ #define CILEN_IFACEID 10 /* RFC2472, interface identifier */ #define CODENAME(x) ((x) == CONFACK ? "ACK" : \ (x) == CONFNAK ? "NAK" : "REJ") /* * This state variable is used to ensure that we don't * run an ipcp-up/down script while one is already running. */ static enum script_state { s_down, s_up, } ipv6cp_script_state; static pid_t ipv6cp_script_pid; /* * setifaceid - set the interface identifiers manually */ static int setifaceid(char **argv) { char *comma, *arg, c; ipv6cp_options *wo = &ipv6cp_wantoptions[0]; struct in6_addr addr; static int prio_local, prio_remote; #define VALIDID(a) ( (((a).s6_addr32[0] == 0) && ((a).s6_addr32[1] == 0)) && \ (((a).s6_addr32[2] != 0) || ((a).s6_addr32[3] != 0)) ) arg = *argv; if ((comma = strchr(arg, ',')) == NULL) comma = arg + strlen(arg); /* * If comma first character, then no local identifier */ if (comma != arg) { c = *comma; *comma = '\0'; if (inet_pton(AF_INET6, arg, &addr) == 0 || !VALIDID(addr)) { ppp_option_error("Illegal interface identifier (local): %s", arg); return 0; } if (option_priority >= prio_local) { eui64_copy(addr.s6_addr32[2], wo->ourid); wo->opt_local = 1; prio_local = option_priority; } *comma = c; } /* * If comma last character, the no remote identifier */ if (*comma != 0 && *++comma != '\0') { if (inet_pton(AF_INET6, comma, &addr) == 0 || !VALIDID(addr)) { ppp_option_error("Illegal interface identifier (remote): %s", comma); return 0; } if (option_priority >= prio_remote) { eui64_copy(addr.s6_addr32[2], wo->hisid); wo->opt_remote = 1; prio_remote = option_priority; } } if (override_value("+ipv6", option_priority, option_source)) ipv6cp_protent.enabled_flag = 1; return 1; } char *llv6_ntoa(eui64_t ifaceid); static void printifaceid(struct option *opt, void (*printer) (void *, char *, ...), void *arg) { ipv6cp_options *wo = &ipv6cp_wantoptions[0]; if (wo->opt_local) printer(arg, "%s", llv6_ntoa(wo->ourid)); printer(arg, ","); if (wo->opt_remote) printer(arg, "%s", llv6_ntoa(wo->hisid)); } /* * Make a string representation of a network address. */ char * llv6_ntoa(eui64_t ifaceid) { static char b[64]; sprintf(b, "fe80::%s", eui64_ntoa(ifaceid)); return b; } /* * ipv6cp_init - Initialize IPV6CP. */ static void ipv6cp_init(int unit) { fsm *f = &ipv6cp_fsm[unit]; ipv6cp_options *wo = &ipv6cp_wantoptions[unit]; ipv6cp_options *ao = &ipv6cp_allowoptions[unit]; f->unit = unit; f->protocol = PPP_IPV6CP; f->callbacks = &ipv6cp_callbacks; fsm_init(&ipv6cp_fsm[unit]); memset(wo, 0, sizeof(*wo)); memset(ao, 0, sizeof(*ao)); wo->accept_local = 0; wo->accept_remote = 0; wo->neg_ifaceid = 1; ao->neg_ifaceid = 1; #ifdef IPV6CP_COMP wo->neg_vj = 1; ao->neg_vj = 1; wo->vj_protocol = IPV6CP_COMP; #endif /* * XXX This controls whether the user may use the defaultroute option. */ ao->default_route = 1; } /* * ipv6cp_open - IPV6CP is allowed to come up. */ static void ipv6cp_open(int unit) { fsm_open(&ipv6cp_fsm[unit]); } /* * ipv6cp_close - Take IPV6CP down. */ static void ipv6cp_close(int unit, char *reason) { fsm_close(&ipv6cp_fsm[unit], reason); } /* * ipv6cp_lowerup - The lower layer is up. */ static void ipv6cp_lowerup(int unit) { fsm_lowerup(&ipv6cp_fsm[unit]); } /* * ipv6cp_lowerdown - The lower layer is down. */ static void ipv6cp_lowerdown(int unit) { fsm_lowerdown(&ipv6cp_fsm[unit]); } /* * ipv6cp_input - Input IPV6CP packet. */ static void ipv6cp_input(int unit, u_char *p, int len) { fsm_input(&ipv6cp_fsm[unit], p, len); } /* * ipv6cp_protrej - A Protocol-Reject was received for IPV6CP. * * Pretend the lower layer went down, so we shut up. */ static void ipv6cp_protrej(int unit) { fsm_lowerdown(&ipv6cp_fsm[unit]); } /* * ipv6cp_resetci - Reset our CI. */ static void ipv6cp_resetci(fsm *f) { ipv6cp_options *wo = &ipv6cp_wantoptions[f->unit]; ipv6cp_options *go = &ipv6cp_gotoptions[f->unit]; wo->req_ifaceid = wo->neg_ifaceid && ipv6cp_allowoptions[f->unit].neg_ifaceid; if (!wo->opt_local) { wo->accept_local = 1; if (!demand) eui64_magic_nz(wo->ourid); } if (!wo->opt_remote) wo->accept_remote = 1; *go = *wo; eui64_zero(go->hisid); /* last proposed interface identifier */ } /* * ipv6cp_cilen - Return length of our CI. */ static int ipv6cp_cilen(fsm *f) { ipv6cp_options *go = &ipv6cp_gotoptions[f->unit]; #define LENCIVJ(neg) (neg ? CILEN_COMPRESS : 0) #define LENCIIFACEID(neg) (neg ? CILEN_IFACEID : 0) return (LENCIIFACEID(go->neg_ifaceid) + LENCIVJ(go->neg_vj)); } /* * ipv6cp_addci - Add our desired CIs to a packet. */ static void ipv6cp_addci(fsm *f, u_char *ucp, int *lenp) { ipv6cp_options *go = &ipv6cp_gotoptions[f->unit]; int len = *lenp; #define ADDCIVJ(opt, neg, val) \ if (neg) { \ int vjlen = CILEN_COMPRESS; \ if (len >= vjlen) { \ PUTCHAR(opt, ucp); \ PUTCHAR(vjlen, ucp); \ PUTSHORT(val, ucp); \ len -= vjlen; \ } else \ neg = 0; \ } #define ADDCIIFACEID(opt, neg, val1) \ if (neg) { \ int idlen = CILEN_IFACEID; \ if (len >= idlen) { \ PUTCHAR(opt, ucp); \ PUTCHAR(idlen, ucp); \ eui64_put(val1, ucp); \ len -= idlen; \ } else \ neg = 0; \ } ADDCIIFACEID(CI_IFACEID, go->neg_ifaceid, go->ourid); ADDCIVJ(CI_COMPRESSTYPE, go->neg_vj, go->vj_protocol); *lenp -= len; } /* * ipv6cp_ackci - Ack our CIs. * * Returns: * 0 - Ack was bad. * 1 - Ack was good. */ static int ipv6cp_ackci(fsm *f, u_char *p, int len) { ipv6cp_options *go = &ipv6cp_gotoptions[f->unit]; u_short cilen, citype, cishort; eui64_t ifaceid; /* * CIs must be in exactly the same order that we sent... * Check packet length and CI length at each step. * If we find any deviations, then this packet is bad. */ #define ACKCIVJ(opt, neg, val) \ if (neg) { \ int vjlen = CILEN_COMPRESS; \ if ((len -= vjlen) < 0) \ goto bad; \ GETCHAR(citype, p); \ GETCHAR(cilen, p); \ if (cilen != vjlen || \ citype != opt) \ goto bad; \ GETSHORT(cishort, p); \ if (cishort != val) \ goto bad; \ } #define ACKCIIFACEID(opt, neg, val1) \ if (neg) { \ int idlen = CILEN_IFACEID; \ if ((len -= idlen) < 0) \ goto bad; \ GETCHAR(citype, p); \ GETCHAR(cilen, p); \ if (cilen != idlen || \ citype != opt) \ goto bad; \ eui64_get(ifaceid, p); \ if (! eui64_equals(val1, ifaceid)) \ goto bad; \ } ACKCIIFACEID(CI_IFACEID, go->neg_ifaceid, go->ourid); ACKCIVJ(CI_COMPRESSTYPE, go->neg_vj, go->vj_protocol); /* * If there are any remaining CIs, then this packet is bad. */ if (len != 0) goto bad; return (1); bad: IPV6CPDEBUG(("ipv6cp_ackci: received bad Ack!")); return (0); } /* * ipv6cp_nakci - Peer has sent a NAK for some of our CIs. * This should not modify any state if the Nak is bad * or if IPV6CP is in the OPENED state. * * Returns: * 0 - Nak was bad. * 1 - Nak was good. */ static int ipv6cp_nakci(fsm *f, u_char *p, int len, int treat_as_reject) { ipv6cp_options *wo = &ipv6cp_wantoptions[f->unit]; ipv6cp_options *go = &ipv6cp_gotoptions[f->unit]; u_char citype, cilen, *next; u_short cishort; eui64_t ifaceid; ipv6cp_options no; /* options we've seen Naks for */ ipv6cp_options try; /* options to request next time */ BZERO(&no, sizeof(no)); try = *go; /* * Any Nak'd CIs must be in exactly the same order that we sent. * Check packet length and CI length at each step. * If we find any deviations, then this packet is bad. */ #define NAKCIIFACEID(opt, neg, code) \ if (go->neg && \ len >= (cilen = CILEN_IFACEID) && \ p[1] == cilen && \ p[0] == opt) { \ len -= cilen; \ INCPTR(2, p); \ eui64_get(ifaceid, p); \ no.neg = 1; \ code \ } #define NAKCIVJ(opt, neg, code) \ if (go->neg && \ ((cilen = p[1]) == CILEN_COMPRESS) && \ len >= cilen && \ p[0] == opt) { \ len -= cilen; \ INCPTR(2, p); \ GETSHORT(cishort, p); \ no.neg = 1; \ code \ } /* * Accept the peer's idea of {our,his} interface identifier, if different * from our idea, only if the accept_{local,remote} flag is set. */ NAKCIIFACEID(CI_IFACEID, neg_ifaceid, if (treat_as_reject) { try.neg_ifaceid = 0; } else if (go->accept_local && !eui64_iszero(ifaceid) && !eui64_equals(ifaceid, go->hisid)) { try.ourid = ifaceid; } else if (eui64_iszero(ifaceid) && !go->opt_local && wo->neg_ifaceid) { while (eui64_iszero(ifaceid) || eui64_equals(ifaceid, go->hisid)) /* bad luck */ eui64_magic(ifaceid); try.ourid = ifaceid; IPV6CPDEBUG(("local LL address %s", llv6_ntoa(ifaceid))); } ); #ifdef IPV6CP_COMP NAKCIVJ(CI_COMPRESSTYPE, neg_vj, { if (cishort == IPV6CP_COMP && !treat_as_reject) { try.vj_protocol = cishort; } else { try.neg_vj = 0; } } ); #else NAKCIVJ(CI_COMPRESSTYPE, neg_vj, { try.neg_vj = 0; } ); #endif /* * There may be remaining CIs, if the peer is requesting negotiation * on an option that we didn't include in our request packet. * If they want to negotiate about interface identifier, we comply. * If they want us to ask for compression, we refuse. */ while (len >= CILEN_VOID) { GETCHAR(citype, p); GETCHAR(cilen, p); if ( cilen < CILEN_VOID || (len -= cilen) < 0 ) goto bad; next = p + cilen - 2; switch (citype) { case CI_COMPRESSTYPE: if (go->neg_vj || no.neg_vj || (cilen != CILEN_COMPRESS)) goto bad; no.neg_vj = 1; break; case CI_IFACEID: if (go->neg_ifaceid || no.neg_ifaceid || cilen != CILEN_IFACEID) goto bad; try.neg_ifaceid = 1; eui64_get(ifaceid, p); if (go->accept_local && !eui64_iszero(ifaceid) && !eui64_equals(ifaceid, go->hisid)) { try.ourid = ifaceid; } else if (eui64_iszero(ifaceid) && !go->opt_local && wo->neg_ifaceid) { while (eui64_iszero(ifaceid) || eui64_equals(ifaceid, go->hisid)) /* bad luck */ eui64_magic(ifaceid); try.ourid = ifaceid; } else { try.neg_ifaceid = 0; } no.neg_ifaceid = 1; break; } p = next; } /* If there is still anything left, this packet is bad. */ if (len != 0) goto bad; /* * OK, the Nak is good. Now we can update state. */ if (f->state != OPENED) *go = try; return 1; bad: IPV6CPDEBUG(("ipv6cp_nakci: received bad Nak!")); return 0; } /* * ipv6cp_rejci - Reject some of our CIs. */ static int ipv6cp_rejci(fsm *f, u_char *p, int len) { ipv6cp_options *go = &ipv6cp_gotoptions[f->unit]; u_char cilen; u_short cishort; eui64_t ifaceid; ipv6cp_options try; /* options to request next time */ try = *go; /* * Any Rejected CIs must be in exactly the same order that we sent. * Check packet length and CI length at each step. * If we find any deviations, then this packet is bad. */ #define REJCIIFACEID(opt, neg, val1) \ if (go->neg && \ len >= (cilen = CILEN_IFACEID) && \ p[1] == cilen && \ p[0] == opt) { \ len -= cilen; \ INCPTR(2, p); \ eui64_get(ifaceid, p); \ /* Check rejected value. */ \ if (! eui64_equals(ifaceid, val1)) \ goto bad; \ try.neg = 0; \ } #define REJCIVJ(opt, neg, val) \ if (go->neg && \ p[1] == CILEN_COMPRESS && \ len >= p[1] && \ p[0] == opt) { \ len -= p[1]; \ INCPTR(2, p); \ GETSHORT(cishort, p); \ /* Check rejected value. */ \ if (cishort != val) \ goto bad; \ try.neg = 0; \ } REJCIIFACEID(CI_IFACEID, neg_ifaceid, go->ourid); REJCIVJ(CI_COMPRESSTYPE, neg_vj, go->vj_protocol); /* * If there are any remaining CIs, then this packet is bad. */ if (len != 0) goto bad; /* * Now we can update state. */ if (f->state != OPENED) *go = try; return 1; bad: IPV6CPDEBUG(("ipv6cp_rejci: received bad Reject!")); return 0; } /* * ipv6cp_reqci - Check the peer's requested CIs and send appropriate response. * * Returns: CONFACK, CONFNAK or CONFREJ and input packet modified * appropriately. If reject_if_disagree is non-zero, doesn't return * CONFNAK; returns CONFREJ if it can't return CONFACK. */ static int ipv6cp_reqci(fsm *f, u_char *inp, int *len, int reject_if_disagree) { ipv6cp_options *wo = &ipv6cp_wantoptions[f->unit]; ipv6cp_options *ho = &ipv6cp_hisoptions[f->unit]; ipv6cp_options *ao = &ipv6cp_allowoptions[f->unit]; ipv6cp_options *go = &ipv6cp_gotoptions[f->unit]; u_char *cip, *next; /* Pointer to current and next CIs */ u_short cilen, citype; /* Parsed len, type */ u_short cishort; /* Parsed short value */ eui64_t ifaceid; /* Parsed interface identifier */ int rc = CONFACK; /* Final packet return code */ int orc; /* Individual option return code */ u_char *p; /* Pointer to next char to parse */ u_char *ucp = inp; /* Pointer to current output char */ int l = *len; /* Length left */ /* * Reset all his options. */ BZERO(ho, sizeof(*ho)); /* * Process all his options. */ next = inp; while (l) { orc = CONFACK; /* Assume success */ cip = p = next; /* Remember begining of CI */ if (l < 2 || /* Not enough data for CI header or */ p[1] < 2 || /* CI length too small or */ p[1] > l) { /* CI length too big? */ IPV6CPDEBUG(("ipv6cp_reqci: bad CI length!")); orc = CONFREJ; /* Reject bad CI */ cilen = l; /* Reject till end of packet */ l = 0; /* Don't loop again */ goto endswitch; } GETCHAR(citype, p); /* Parse CI type */ GETCHAR(cilen, p); /* Parse CI length */ l -= cilen; /* Adjust remaining length */ next += cilen; /* Step to next CI */ switch (citype) { /* Check CI type */ case CI_IFACEID: IPV6CPDEBUG(("ipv6cp: received interface identifier ")); if (!ao->neg_ifaceid || cilen != CILEN_IFACEID) { /* Check CI length */ orc = CONFREJ; /* Reject CI */ break; } /* * If he has no interface identifier, or if we both have same * identifier then NAK it with new idea. * In particular, if we don't know his identifier, but he does, * then accept it. */ eui64_get(ifaceid, p); IPV6CPDEBUG(("(%s)", llv6_ntoa(ifaceid))); if (eui64_iszero(ifaceid) && eui64_iszero(go->ourid)) { orc = CONFREJ; /* Reject CI */ break; } if (!eui64_iszero(wo->hisid) && !wo->accept_remote && !eui64_equals(ifaceid, wo->hisid)) { orc = CONFNAK; ifaceid = wo->hisid; go->hisid = ifaceid; DECPTR(sizeof(ifaceid), p); eui64_put(ifaceid, p); } else if (eui64_iszero(ifaceid) || eui64_equals(ifaceid, go->ourid)) { orc = CONFNAK; if (eui64_iszero(go->hisid)) /* first time, try option */ ifaceid = wo->hisid; if (eui64_equals(ifaceid, go->ourid)) /* bad luck */ eui64_zero(ifaceid); if (eui64_iszero(ifaceid)) { if (wo->opt_remote) ifaceid = wo->hisid; else { while (eui64_iszero(ifaceid) || eui64_equals(ifaceid, go->ourid)) /* bad luck */ eui64_magic(ifaceid); } } go->hisid = ifaceid; DECPTR(sizeof(ifaceid), p); eui64_put(ifaceid, p); } ho->neg_ifaceid = 1; ho->hisid = ifaceid; break; case CI_COMPRESSTYPE: IPV6CPDEBUG(("ipv6cp: received COMPRESSTYPE ")); if (!ao->neg_vj || (cilen != CILEN_COMPRESS)) { orc = CONFREJ; break; } GETSHORT(cishort, p); IPV6CPDEBUG(("(%d)", cishort)); #ifdef IPV6CP_COMP if (!(cishort == IPV6CP_COMP)) { orc = CONFREJ; break; } ho->neg_vj = 1; ho->vj_protocol = cishort; break; #else orc = CONFREJ; break; #endif default: orc = CONFREJ; break; } endswitch: IPV6CPDEBUG((" (%s)\n", CODENAME(orc))); if (orc == CONFACK && /* Good CI */ rc != CONFACK) /* but prior CI wasnt? */ continue; /* Don't send this one */ if (orc == CONFNAK) { /* Nak this CI? */ if (reject_if_disagree) /* Getting fed up with sending NAKs? */ orc = CONFREJ; /* Get tough if so */ else { if (rc == CONFREJ) /* Rejecting prior CI? */ continue; /* Don't send this one */ if (rc == CONFACK) { /* Ack'd all prior CIs? */ rc = CONFNAK; /* Not anymore... */ ucp = inp; /* Backup */ } } } if (orc == CONFREJ && /* Reject this CI */ rc != CONFREJ) { /* but no prior ones? */ rc = CONFREJ; ucp = inp; /* Backup */ } /* Need to move CI? */ if (ucp != cip) BCOPY(cip, ucp, cilen); /* Move it */ /* Update output pointer */ INCPTR(cilen, ucp); } /* * If we aren't rejecting this packet, and we want to negotiate * their identifier and they didn't send their identifier, then we * send a NAK with a CI_IFACEID option appended. We assume the * input buffer is long enough that we can append the extra * option safely. */ if (rc != CONFREJ && !ho->neg_ifaceid && wo->req_ifaceid && !reject_if_disagree) { if (rc == CONFACK) { rc = CONFNAK; ucp = inp; /* reset pointer */ wo->req_ifaceid = 0; /* don't ask again */ } PUTCHAR(CI_IFACEID, ucp); PUTCHAR(CILEN_IFACEID, ucp); eui64_put(wo->hisid, ucp); } *len = ucp - inp; /* Compute output length */ IPV6CPDEBUG(("ipv6cp: returning Configure-%s", CODENAME(rc))); return (rc); /* Return final code */ } /* * eui48_to_eui64 - Convert the EUI-48 into EUI-64, per RFC 2472 [sec 4.1] */ static void eui48_to_eui64(eui64_t *p_eui64, const u_char addr[6]) { p_eui64->e8[0] = addr[0] | 0x02; p_eui64->e8[1] = addr[1]; p_eui64->e8[2] = addr[2]; p_eui64->e8[3] = 0xFF; p_eui64->e8[4] = 0xFE; p_eui64->e8[5] = addr[3]; p_eui64->e8[6] = addr[4]; p_eui64->e8[7] = addr[5]; } /* * ether_to_eui64 - Convert 48-bit Ethernet address into 64-bit EUI * * walks the list of valid ethernet interfaces, starting with devnam * (for PPPoE it is ethernet interface), and convert the first * found 48-bit MAC address into EUI 64. caller also assumes that * the system has a properly configured Ethernet interface for this * function to return non-zero. */ static int ether_to_eui64(eui64_t *p_eui64) { u_char addr[6]; if (get_if_hwaddr(addr, devnam) < 0 && get_first_ether_hwaddr(addr) < 0) { error("ipv6cp: no persistent id can be found"); return 0; } eui48_to_eui64(p_eui64, addr); return 1; } /* * ipv6_check_options - check that any IP-related options are OK, * and assign appropriate defaults. */ static void ipv6_check_options(void) { ipv6cp_options *wo = &ipv6cp_wantoptions[0]; if (!ipv6cp_protent.enabled_flag) return; /* * Persistent link-local id is only used when user has not explicitly * configure/hard-code the id */ if ((wo->use_persistent) && (!wo->opt_local)) { /* * On systems where there are no Ethernet interfaces used, there * may be other ways to obtain a persistent id. Right now, it * will fall back to using magic [see eui64_magic] below when * an EUI-48 from MAC address can't be obtained. Other possibilities * include obtaining EEPROM serial numbers, or some other unique * yet persistent number. On Sparc platforms, this is possible, * but too bad there's no standards yet for x86 machines. */ if (ether_to_eui64(&wo->ourid)) { wo->opt_local = 1; } } if (!wo->opt_remote && wo->use_remotenumber && *remote_number) { /* remote number can be either MAC address, IPv4 address, IPv6 address or telephone number */ struct in_addr addr; struct in6_addr addr6; unsigned long long tel; unsigned char mac[6]; const char *str; char *endptr; if (sscanf(remote_number, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", &mac[0], &mac[1], &mac[2], &mac[3], &mac[4], &mac[5]) == 6) { eui48_to_eui64(&wo->hisid, mac); } else if (inet_pton(AF_INET, remote_number, &addr) == 1) { eui64_setlo32(wo->hisid, ntohl(addr.s_addr)); } else if (inet_pton(AF_INET6, remote_number, &addr6) == 1) { /* use low 64 bits of IPv6 address for interface identifier */ wo->hisid.e8[0] = addr6.s6_addr[8]; wo->hisid.e8[1] = addr6.s6_addr[9]; wo->hisid.e8[2] = addr6.s6_addr[10]; wo->hisid.e8[3] = addr6.s6_addr[11]; wo->hisid.e8[4] = addr6.s6_addr[12]; wo->hisid.e8[5] = addr6.s6_addr[13]; wo->hisid.e8[6] = addr6.s6_addr[14]; wo->hisid.e8[7] = addr6.s6_addr[15]; } else { str = remote_number; /* telephone number may start with leading '+' sign, so skip it */ if (str[0] == '+') str++; errno = 0; tel = strtoull(str, &endptr, 10); if (!errno && *str && !*endptr && tel) { wo->hisid.e32[0] = htonl(tel >> 32); wo->hisid.e32[1] = htonl(tel & 0xFFFFFFFF); } } if (!eui64_iszero(wo->hisid)) wo->opt_remote = 1; } if (!wo->opt_local) { /* init interface identifier */ if (wo->use_ip && eui64_iszero(wo->ourid)) { eui64_setlo32(wo->ourid, ntohl(ipcp_wantoptions[0].ouraddr)); if (!eui64_iszero(wo->ourid)) wo->opt_local = 1; } while (eui64_iszero(wo->ourid)) eui64_magic(wo->ourid); } if (!wo->opt_remote) { if (wo->use_ip && eui64_iszero(wo->hisid)) { eui64_setlo32(wo->hisid, ntohl(ipcp_wantoptions[0].hisaddr)); if (!eui64_iszero(wo->hisid)) wo->opt_remote = 1; } } } /* * ipv6_demand_conf - configure the interface as though * IPV6CP were up, for use with dial-on-demand. */ static int ipv6_demand_conf(int u) { ipv6cp_options *wo = &ipv6cp_wantoptions[u]; if (eui64_iszero(wo->hisid) && !ipv6cp_noremote) { /* make up an arbitrary identifier for the peer */ eui64_magic_nz(wo->hisid); } if (eui64_iszero(wo->ourid)) { /* make up an arbitrary identifier for us */ eui64_magic_nz(wo->ourid); } if (!sif6up(u)) return 0; if (!sif6addr(u, wo->ourid, wo->hisid)) return 0; #if !defined(__linux__) && !(defined(SVR4) && (defined(SNI) || defined(__USLC__))) if (!sifup(u)) return 0; #endif if (!sifnpmode(u, PPP_IPV6, NPMODE_QUEUE)) return 0; if (wo->default_route) if (sif6defaultroute(u, wo->ourid, wo->hisid)) default_route_set[u] = 1; notice("local LL address %s", llv6_ntoa(wo->ourid)); if (!eui64_iszero(wo->hisid)) notice("remote LL address %s", llv6_ntoa(wo->hisid)); return 1; } /* * ipv6cp_up - IPV6CP has come UP. * * Configure the IPv6 network interface appropriately and bring it up. */ static void ipv6cp_up(fsm *f) { ipv6cp_options *ho = &ipv6cp_hisoptions[f->unit]; ipv6cp_options *go = &ipv6cp_gotoptions[f->unit]; ipv6cp_options *wo = &ipv6cp_wantoptions[f->unit]; IPV6CPDEBUG(("ipv6cp: up")); /* * We must have a non-zero LL address for both ends of the link. */ if (!eui64_iszero(wo->hisid) && !wo->accept_remote && (!ho->neg_ifaceid || !eui64_equals(ho->hisid, wo->hisid))) { error("Peer refused to agree to his interface identifier"); ipv6cp_close(f->unit, "Refused his interface identifier"); return; } if (!ho->neg_ifaceid) ho->hisid = wo->hisid; if(!no_ifaceid_neg) { if (eui64_iszero(ho->hisid) && !ipv6cp_noremote) { error("Could not determine remote LL address"); ipv6cp_close(f->unit, "Could not determine remote LL address"); return; } if (eui64_iszero(go->ourid)) { error("Could not determine local LL address"); ipv6cp_close(f->unit, "Could not determine local LL address"); return; } if (eui64_equals(go->ourid, ho->hisid)) { error("local and remote LL addresses are equal"); ipv6cp_close(f->unit, "local and remote LL addresses are equal"); return; } } ppp_script_setenv("LLLOCAL", llv6_ntoa(go->ourid), 0); if (!eui64_iszero(ho->hisid)) ppp_script_setenv("LLREMOTE", llv6_ntoa(ho->hisid), 0); #ifdef IPV6CP_COMP /* set tcp compression */ sif6comp(f->unit, ho->neg_vj); #endif /* * If we are doing dial-on-demand, the interface is already * configured, so we put out any saved-up packets, then set the * interface to pass IPv6 packets. */ if (demand) { if (! eui64_equals(go->ourid, wo->ourid) || ! eui64_equals(ho->hisid, wo->hisid)) { if (! eui64_equals(go->ourid, wo->ourid)) warn("Local LL address changed to %s", llv6_ntoa(go->ourid)); if (! eui64_equals(ho->hisid, wo->hisid)) warn("Remote LL address changed to %s", llv6_ntoa(ho->hisid)); ipv6cp_clear_addrs(f->unit, wo->ourid, wo->hisid); /* Set the interface to the new addresses */ if (!sif6addr(f->unit, go->ourid, ho->hisid)) { if (debug) warn("sif6addr failed"); ipv6cp_close(f->unit, "Interface configuration failed"); return; } /* assign a default route through the interface if required */ if (ipv6cp_wantoptions[f->unit].default_route) if (sif6defaultroute(f->unit, go->ourid, ho->hisid)) default_route_set[f->unit] = 1; } demand_rexmit(PPP_IPV6); sifnpmode(f->unit, PPP_IPV6, NPMODE_PASS); } else { /* bring the interface up for IPv6 */ if (!sif6up(f->unit)) { if (debug) warn("sif6up failed (IPV6)"); ipv6cp_close(f->unit, "Interface configuration failed"); return; } if (!sif6addr(f->unit, go->ourid, ho->hisid)) { if (debug) warn("sif6addr failed"); ipv6cp_close(f->unit, "Interface configuration failed"); return; } sifnpmode(f->unit, PPP_IPV6, NPMODE_PASS); /* assign a default route through the interface if required */ if (ipv6cp_wantoptions[f->unit].default_route) if (sif6defaultroute(f->unit, go->ourid, ho->hisid)) default_route_set[f->unit] = 1; notice("local LL address %s", llv6_ntoa(go->ourid)); if (!eui64_iszero(ho->hisid)) notice("remote LL address %s", llv6_ntoa(ho->hisid)); } np_up(f->unit, PPP_IPV6); ipv6cp_is_up = 1; notify(ipv6_up_notifier, 0); if (ipv6_up_hook) ipv6_up_hook(); /* * Execute the ipv6-up script, like this: * /etc/ppp/ipv6-up interface tty speed local-LL remote-LL */ if (ipv6cp_script_state == s_down && ipv6cp_script_pid == 0) { ipv6cp_script_state = s_up; ipv6cp_script(path_ipv6up); } } /* * ipv6cp_down - IPV6CP has gone DOWN. * * Take the IPv6 network interface down, clear its addresses * and delete routes through it. */ static void ipv6cp_down(fsm *f) { IPV6CPDEBUG(("ipv6cp: down")); ppp_get_link_stats(NULL); notify(ipv6_down_notifier, 0); if (ipv6_down_hook) ipv6_down_hook(); if (ipv6cp_is_up) { ipv6cp_is_up = 0; np_down(f->unit, PPP_IPV6); } #ifdef IPV6CP_COMP sif6comp(f->unit, 0); #endif /* * If we are doing dial-on-demand, set the interface * to queue up outgoing packets (for now). */ if (demand) { sifnpmode(f->unit, PPP_IPV6, NPMODE_QUEUE); } else { sifnpmode(f->unit, PPP_IPV6, NPMODE_DROP); #if !defined(__linux__) && !(defined(SVR4) && (defined(SNI) || defined(__USLC))) sif6down(f->unit); #endif ipv6cp_clear_addrs(f->unit, ipv6cp_gotoptions[f->unit].ourid, ipv6cp_hisoptions[f->unit].hisid); #if defined(__linux__) sif6down(f->unit); #elif defined(SVR4) && (defined(SNI) || defined(__USLC)) sifdown(f->unit); #endif } /* Execute the ipv6-down script */ if (ipv6cp_script_state == s_up && ipv6cp_script_pid == 0) { ipv6cp_script_state = s_down; ipv6cp_script(path_ipv6down); } } /* * ipv6cp_clear_addrs() - clear the interface addresses, routes, * proxy neighbour discovery entries, etc. */ static void ipv6cp_clear_addrs(int unit, eui64_t ourid, eui64_t hisid) { cif6addr(unit, ourid, hisid); } /* * ipv6cp_finished - possibly shut down the lower layers. */ static void ipv6cp_finished(fsm *f) { np_finished(f->unit, PPP_IPV6); } /* * ipv6cp_script_done - called when the ipv6-up or ipv6-down script * has finished. */ static void ipv6cp_script_done(void *arg) { ipv6cp_script_pid = 0; switch (ipv6cp_script_state) { case s_up: if (ipv6cp_fsm[0].state != OPENED) { ipv6cp_script_state = s_down; ipv6cp_script(path_ipv6down); } break; case s_down: if (ipv6cp_fsm[0].state == OPENED) { ipv6cp_script_state = s_up; ipv6cp_script(path_ipv6up); } break; } } /* * ipv6cp_script - Execute a script with arguments * interface-name tty-name speed local-LL remote-LL. */ static void ipv6cp_script(char *script) { char strspeed[32], strlocal[64], strremote[64]; char *argv[8]; sprintf(strspeed, "%d", baud_rate); strcpy(strlocal, llv6_ntoa(ipv6cp_gotoptions[0].ourid)); strcpy(strremote, llv6_ntoa(ipv6cp_hisoptions[0].hisid)); argv[0] = script; argv[1] = ifname; argv[2] = devnam; argv[3] = strspeed; argv[4] = strlocal; argv[5] = strremote; argv[6] = ipparam; argv[7] = NULL; ipv6cp_script_pid = run_program(script, argv, 0, ipv6cp_script_done, NULL, 0); } /* * ipv6cp_printpkt - print the contents of an IPV6CP packet. */ static char *ipv6cp_codenames[] = { "ConfReq", "ConfAck", "ConfNak", "ConfRej", "TermReq", "TermAck", "CodeRej" }; static int ipv6cp_printpkt(u_char *p, int plen, void (*printer) (void *, char *, ...), void *arg) { int code, id, len, olen; u_char *pstart, *optend; u_short cishort; eui64_t ifaceid; if (plen < HEADERLEN) return 0; pstart = p; GETCHAR(code, p); GETCHAR(id, p); GETSHORT(len, p); if (len < HEADERLEN || len > plen) return 0; if (code >= 1 && code <= sizeof(ipv6cp_codenames) / sizeof(char *)) printer(arg, " %s", ipv6cp_codenames[code-1]); else printer(arg, " code=0x%x", code); printer(arg, " id=0x%x", id); len -= HEADERLEN; switch (code) { case CONFREQ: case CONFACK: case CONFNAK: case CONFREJ: /* print option list */ while (len >= 2) { GETCHAR(code, p); GETCHAR(olen, p); p -= 2; if (olen < 2 || olen > len) { break; } printer(arg, " <"); len -= olen; optend = p + olen; switch (code) { case CI_COMPRESSTYPE: if (olen >= CILEN_COMPRESS) { p += 2; GETSHORT(cishort, p); printer(arg, "compress "); printer(arg, "0x%x", cishort); } break; case CI_IFACEID: if (olen == CILEN_IFACEID) { p += 2; eui64_get(ifaceid, p); printer(arg, "addr %s", llv6_ntoa(ifaceid)); } break; } while (p < optend) { GETCHAR(code, p); printer(arg, " %.2x", code); } printer(arg, ">"); } break; case TERMACK: case TERMREQ: if (len > 0 && *p >= ' ' && *p < 0x7f) { printer(arg, " "); print_string((char *)p, len, printer, arg); p += len; len = 0; } break; } /* print the rest of the bytes in the packet */ for (; len > 0; --len) { GETCHAR(code, p); printer(arg, " %.2x", code); } return p - pstart; } /* * ipv6_active_pkt - see if this IP packet is worth bringing the link up for. * We don't bring the link up for IP fragments or for TCP FIN packets * with no data. */ #define IP6_HDRLEN 40 /* bytes */ #define IP6_NHDR_FRAG 44 /* fragment IPv6 header */ #define TCP_HDRLEN 20 #define TH_FIN 0x01 /* * We use these macros because the IP header may be at an odd address, * and some compilers might use word loads to get th_off or ip_hl. */ #define get_ip6nh(x) (((unsigned char *)(x))[6]) #define get_tcpoff(x) (((unsigned char *)(x))[12] >> 4) #define get_tcpflags(x) (((unsigned char *)(x))[13]) static int ipv6_active_pkt(u_char *pkt, int len) { u_char *tcp; len -= PPP_HDRLEN; pkt += PPP_HDRLEN; if (len < IP6_HDRLEN) return 0; if (get_ip6nh(pkt) == IP6_NHDR_FRAG) return 0; if (get_ip6nh(pkt) != IPPROTO_TCP) return 1; if (len < IP6_HDRLEN + TCP_HDRLEN) return 0; tcp = pkt + IP6_HDRLEN; if ((get_tcpflags(tcp) & TH_FIN) != 0 && len == IP6_HDRLEN + get_tcpoff(tcp) * 4) return 0; return 1; } ppp-2.5.0/pppd/eui64.c0000644000175000017500000000352314353435407011314 00000000000000/* * eui64.c - EUI64 routines for IPv6CP. * * Copyright (c) 1999 Tommi Komulainen. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The name(s) of the authors of this software must not be used to * endorse or promote products derived from this software without * prior written permission. * * 4. Redistributions of any form whatsoever must retain the following * acknowledgment: * "This product includes software developed by Tommi Komulainen * ". * * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "pppd-private.h" /* * eui64_ntoa - Make an ascii representation of an interface identifier */ char * eui64_ntoa(eui64_t e) { static char buf[32]; snprintf(buf, 32, "%02x%02x:%02x%02x:%02x%02x:%02x%02x", e.e8[0], e.e8[1], e.e8[2], e.e8[3], e.e8[4], e.e8[5], e.e8[6], e.e8[7]); return buf; } ppp-2.5.0/pppd/eap-tls.c0000644000175000017500000007614214353435407011734 00000000000000/* * eap-tls.c - EAP-TLS implementation for PPP * * Copyright (c) Beniamino Galvani 2005 All rights reserved. * Jan Just Keijser 2006-2019 All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The name(s) of the authors of this software must not be used to * endorse or promote products derived from this software without * prior written permission. * * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include #ifndef OPENSSL_NO_ENGINE #include #endif #include #include #include #include #include #include #include "pppd-private.h" #include "tls.h" #include "eap.h" #include "eap-tls.h" #include "fsm.h" #include "lcp.h" #include "chap_ms.h" #include "mppe.h" #include "pathnames.h" #if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) #define SSL3_RT_HEADER 0x100 #endif typedef struct pw_cb_data { const void *password; const char *prompt_info; } PW_CB_DATA; #ifndef OPENSSL_NO_ENGINE /* The openssl configuration file and engines can be loaded only once */ static CONF *ssl_config = NULL; static ENGINE *cert_engine = NULL; static ENGINE *pkey_engine = NULL; #endif /* TLSv1.3 do we have a session ticket ? */ static int have_session_ticket = 0; void ssl_msg_callback(int write_p, int version, int ct, const void *buf, size_t len, SSL * ssl, void *arg); int ssl_new_session_cb(SSL *s, SSL_SESSION *sess); #ifdef PPP_WITH_MPPE #define EAPTLS_MPPE_KEY_LEN 32 /* * Generate keys according to RFC 2716 and add to reply */ void eaptls_gen_mppe_keys(struct eaptls_session *ets, int client) { unsigned char out[4*EAPTLS_MPPE_KEY_LEN]; const char *prf_label; size_t prf_size; unsigned char eap_tls13_context[] = { EAPT_TLS }; unsigned char *context = NULL; size_t context_len = 0; unsigned char *p; dbglog("EAP-TLS generating MPPE keys"); if (ets->tls_v13) { prf_label = "EXPORTER_EAP_TLS_Key_Material"; context = eap_tls13_context; context_len = 1; } else { prf_label = "client EAP encryption"; } dbglog("EAP-TLS PRF label = %s", prf_label); prf_size = strlen(prf_label); if (SSL_export_keying_material(ets->ssl, out, sizeof(out), prf_label, prf_size, context, context_len, 0) != 1) { warn( "EAP-TLS: Failed generating keying material" ); return; } /* * We now have the master send and receive keys. * From these, generate the session send and receive keys. * (see RFC3079 / draft-ietf-pppext-mppe-keys-03.txt for details) */ if (client) { mppe_set_keys(out, out + EAPTLS_MPPE_KEY_LEN, EAPTLS_MPPE_KEY_LEN); } else { mppe_set_keys(out + EAPTLS_MPPE_KEY_LEN, out, EAPTLS_MPPE_KEY_LEN); } } #endif /* PPP_WITH_MPPE */ int password_callback (char *buf, int size, int rwflag, void *u) { if (buf) { strlcpy (buf, passwd, size); return strlen (buf); } return 0; } CONF *eaptls_ssl_load_config( void ) { CONF *config; int ret_code; long error_line = 33; config = NCONF_new( NULL ); dbglog( "Loading OpenSSL config file" ); ret_code = NCONF_load( config, PPP_PATH_OPENSSLCONFFILE, &error_line ); if (ret_code == 0) { warn( "EAP-TLS: Error in OpenSSL config file %s at line %d", PPP_PATH_OPENSSLCONFFILE, error_line ); NCONF_free( config ); config = NULL; ERR_clear_error(); } dbglog( "Loading OpenSSL built-ins" ); #ifndef OPENSSL_NO_ENGINE ENGINE_load_builtin_engines(); #endif OPENSSL_load_builtin_modules(); dbglog( "Loading OpenSSL configured modules" ); if (CONF_modules_load( config, NULL, 0 ) <= 0 ) { warn( "EAP-TLS: Error loading OpenSSL modules" ); tls_log_sslerr(); config = NULL; } return config; } #ifndef OPENSSL_NO_ENGINE ENGINE *eaptls_ssl_load_engine( char *engine_name ) { ENGINE *e = NULL; dbglog( "Enabling OpenSSL auto engines" ); ENGINE_register_all_complete(); dbglog( "Loading OpenSSL '%s' engine support", engine_name ); e = ENGINE_by_id( engine_name ); if (!e) { dbglog( "EAP-TLS: Cannot load '%s' engine support, trying 'dynamic'", engine_name ); e = ENGINE_by_id( "dynamic" ); if (e) { if (!ENGINE_ctrl_cmd_string(e, "SO_PATH", engine_name, 0) || !ENGINE_ctrl_cmd_string(e, "LOAD", NULL, 0)) { warn( "EAP-TLS: Error loading dynamic engine '%s'", engine_name ); tls_log_sslerr(); ENGINE_free(e); e = NULL; } } else { warn( "EAP-TLS: Cannot load dynamic engine support" ); } } if (e) { dbglog( "Initialising engine" ); if(!ENGINE_set_default(e, ENGINE_METHOD_ALL)) { warn( "EAP-TLS: Cannot use that engine" ); tls_log_sslerr(); ENGINE_free(e); e = NULL; } } return e; } #endif #ifndef OPENSSL_NO_ENGINE static int eaptls_UI_writer(UI *ui, UI_STRING *uis) { PW_CB_DATA* cb_data = (PW_CB_DATA*)UI_get0_user_data(ui); UI_set_result(ui, uis, cb_data->password); return 1; } static int eaptls_UI_stub(UI* ui) { return 1; } static int eaptls_UI_reader(UI *ui, UI_STRING *uis) { return 1; } #endif /* * Initialize the SSL stacks and tests if certificates, key and crl * for client or server use can be loaded. */ SSL_CTX *eaptls_init_ssl(int init_server, char *cacertfile, char *capath, char *certfile, char *privkeyfile, char *pkcs12) { #ifndef OPENSSL_NO_ENGINE char *cert_engine_name = NULL; char *pkey_engine_name = NULL; char *idx; #endif SSL_CTX *ctx; SSL *ssl; X509 *tmp; X509 *cert = NULL; PKCS12 *p12 = NULL; EVP_PKEY *pkey = NULL; STACK_OF(X509) *chain = NULL; BIO *input; int ret; int reason; /* * Without these can't continue */ if (!pkcs12[0]) { if (!(cacertfile[0] || capath[0])) { error("EAP-TLS: CA certificate file or path missing"); return NULL; } if (!certfile[0]) { error("EAP-TLS: Certificate missing"); return NULL; } if (!privkeyfile[0]) { error("EAP-TLS: Private key missing"); return NULL; } } tls_init(); #ifndef OPENSSL_NO_ENGINE /* load the openssl config file only once and load it before triggering the loading of a global openssl config file via SSL_CTX_new() */ if (!ssl_config) ssl_config = eaptls_ssl_load_config(); #endif ctx = SSL_CTX_new(tls_method()); if (!ctx) { error("EAP-TLS: Cannot initialize SSL CTX context"); goto fail; } #ifndef OPENSSL_NO_ENGINE /* if the certificate filename is of the form engine:id. e.g. pkcs11:12345 then we try to load and use this engine. If the certificate filename starts with a / or . then we ALWAYS assume it is a file and not an engine/pkcs11 identifier */ if ( (idx = index( certfile, ':' )) != NULL ) { cert_engine_name = strdup( certfile ); cert_engine_name[idx - certfile] = 0; dbglog( "Using engine '%s' for certificate, URI: '%s'", cert_engine_name, certfile ); } /* if the privatekey filename is of the form engine:id. e.g. pkcs11:12345 then we try to load and use this engine. If the privatekey filename starts with a / or . then we ALWAYS assume it is a file and not an engine/pkcs11 identifier */ if ( (idx = index( privkeyfile, ':' )) != NULL ) { pkey_engine_name = strdup( privkeyfile ); pkey_engine_name[idx - privkeyfile] = 0; dbglog( "Using engine '%s' for private key, URI: '%s'", pkey_engine_name, privkeyfile ); } if (cert_engine_name && pkey_engine_name) { if (strlen( certfile ) - strlen( cert_engine_name ) == 1) { if (strlen( privkeyfile ) - strlen( pkey_engine_name ) == 1) error( "EAP-TLS: both the certificate and privatekey identifiers are missing!" ); else { dbglog( "Substituting privatekey identifier for certificate identifier" ); certfile = privkeyfile; } } else { if (strlen( privkeyfile ) - strlen( pkey_engine_name ) == 1) { dbglog( "Substituting certificate identifier for privatekey identifier" ); privkeyfile = certfile; } } } if (ssl_config && cert_engine_name) cert_engine = eaptls_ssl_load_engine( cert_engine_name ); if (ssl_config && pkey_engine_name) { /* don't load the same engine twice */ if ( cert_engine && strcmp( cert_engine_name, pkey_engine_name) == 0 ) pkey_engine = cert_engine; else pkey_engine = eaptls_ssl_load_engine( pkey_engine_name ); } if (cert_engine_name) free(cert_engine_name); if (pkey_engine_name) free(pkey_engine_name); #endif SSL_CTX_set_default_passwd_cb (ctx, password_callback); if (tls_set_ca(ctx, capath, cacertfile) != 0) { goto fail; } if (init_server) SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file(cacertfile)); #ifndef OPENSSL_NO_ENGINE if (cert_engine) { struct { const char *s_slot_cert_id; X509 *cert; } cert_info; cert_info.s_slot_cert_id = certfile; cert_info.cert = NULL; if (!ENGINE_ctrl_cmd( cert_engine, "LOAD_CERT_CTRL", 0, &cert_info, NULL, 0 ) ) { error( "EAP-TLS: Error loading certificate with URI '%s' from engine", certfile ); goto fail; } if (cert_info.cert) { dbglog( "Got the certificate" ); dbglog( "subject = %s", X509_NAME_oneline( X509_get_subject_name( cert_info.cert ), NULL, 0 ) ); cert = cert_info.cert; } else { warn("EAP-TLS: Cannot load key with URI: '%s'", certfile ); tls_log_sslerr(); } } else #endif { if (pkcs12[0]) { input = BIO_new_file(pkcs12, "r"); if (input == NULL) { error("EAP-TLS: Cannot open `%s' PKCS12 for input", pkcs12); goto fail; } p12 = d2i_PKCS12_bio(input, NULL); BIO_free(input); if (!p12) { error("EAP-TLS: Cannot load PKCS12 certificate"); goto fail; } if (PKCS12_parse(p12, passwd, &pkey, &cert, &chain) != 1) { error("EAP-TLS: Cannot parse PKCS12 certificate, invalid password"); PKCS12_free(p12); goto fail; } PKCS12_free(p12); } else { if (!SSL_CTX_use_certificate_chain_file(ctx, certfile)) { error( "EAP-TLS: Cannot load certificate %s", certfile ); goto fail; } } } if (cert) { if (!SSL_CTX_use_certificate(ctx, cert)) { error("EAP-TLS: Cannot use load certificate"); goto fail; } if (chain) { int i; for (i = 0; i < sk_X509_num(chain); i++) { if (!SSL_CTX_add_extra_chain_cert(ctx, sk_X509_value(chain, i))) { error("EAP-TLS: Cannot add extra chain certificate"); goto fail; } } } } /* * Check the Before and After dates of the certificate */ ssl = SSL_new(ctx); tmp = SSL_get_certificate(ssl); ret = X509_cmp_time(X509_get_notBefore(tmp), NULL); if (ret == 0) { warn( "EAP-TLS: Failed to read certificate notBefore field."); } if (ret > 0) { warn( "EAP-TLS: Your certificate is not yet valid!"); } ret = X509_cmp_time(X509_get_notAfter(tmp), NULL); if (ret == 0) { warn( "EAP-TLS: Failed to read certificate notAfter field."); } if (ret < 0) { warn( "EAP-TLS: Your certificate has expired!"); } SSL_free(ssl); #ifndef OPENSSL_NO_ENGINE if (pkey_engine) { PW_CB_DATA cb_data; cb_data.password = passwd; cb_data.prompt_info = privkeyfile; if (passwd[0] != 0) { UI_METHOD* transfer_pin = UI_create_method("transfer_pin"); UI_method_set_writer(transfer_pin, eaptls_UI_writer); UI_method_set_opener(transfer_pin, eaptls_UI_stub); UI_method_set_closer(transfer_pin, eaptls_UI_stub); UI_method_set_flusher(transfer_pin, eaptls_UI_stub); UI_method_set_reader(transfer_pin, eaptls_UI_reader); dbglog( "Using our private key URI: '%s' in engine", privkeyfile ); pkey = ENGINE_load_private_key(pkey_engine, privkeyfile, transfer_pin, &cb_data); if (transfer_pin) UI_destroy_method(transfer_pin); } else { dbglog( "Loading private key URI: '%s' from engine", privkeyfile ); pkey = ENGINE_load_private_key(pkey_engine, privkeyfile, NULL, NULL); } } else #endif { if (!pkey) { input = BIO_new_file(privkeyfile, "r"); if (!input) { error("EAP-TLS: Could not open private key, %s", privkeyfile); goto fail; } pkey = PEM_read_bio_PrivateKey(input, NULL, password_callback, NULL); BIO_free(input); if (!pkey) { error("EAP-TLS: Cannot load private key, %s", privkeyfile); goto fail; } } } if (SSL_CTX_use_PrivateKey(ctx, pkey) != 1) { error("EAP-TLS: Cannot use private key"); goto fail; } if (SSL_CTX_check_private_key(ctx) != 1) { error("EAP-TLS: Private key fails security check"); goto fail; } /* Configure the default options */ tls_set_opts(ctx); /* Set up a SSL Session cache with a callback. This is needed for TLSv1.3+. * During the initial handshake the server signals to the client early on * that the handshake is finished, even before the client has sent its * credentials to the server. The actual connection (and moment that the * client sends its credentials) only starts after the arrival of the first * session ticket. The 'ssl_new_session_cb' catches this ticket. */ SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_CLIENT | SSL_SESS_CACHE_NO_INTERNAL_STORE); SSL_CTX_sess_set_new_cb(ctx, ssl_new_session_cb); /* Configure the maximum SSL version */ tls_set_version(ctx, max_tls_version); /* Configure the callback */ if (tls_set_verify(ctx, 5)) { goto fail; } /* Configure CRL check (if any) */ if (tls_set_crl(ctx, crl_dir, crl_file)) { goto fail; } return ctx; fail: if (cert) X509_free(cert); if (pkey) EVP_PKEY_free(pkey); if (chain) sk_X509_pop_free(chain, X509_free); tls_log_sslerr(); SSL_CTX_free(ctx); return NULL; } /* * Determine the maximum packet size by looking at the LCP handshake */ int eaptls_get_mtu(int unit) { int mtu, mru; lcp_options *wo = &lcp_wantoptions[unit]; lcp_options *go = &lcp_gotoptions[unit]; lcp_options *ho = &lcp_hisoptions[unit]; lcp_options *ao = &lcp_allowoptions[unit]; mtu = ho->neg_mru? ho->mru: PPP_MRU; mru = go->neg_mru? MAX(wo->mru, go->mru): PPP_MRU; mtu = MIN(MIN(mtu, mru), ao->mru)- PPP_HDRLEN - 10; dbglog("MTU = %d", mtu); return mtu; } /* * Init the ssl handshake (server mode) */ int eaptls_init_ssl_server(eap_state * esp) { struct eaptls_session *ets; char servcertfile[MAXWORDLEN]; char clicertfile[MAXWORDLEN]; char cacertfile[MAXWORDLEN]; char capath[MAXWORDLEN]; char pkfile[MAXWORDLEN]; char pkcs12[MAXWORDLEN]; /* * Allocate new eaptls session */ esp->es_server.ea_session = malloc(sizeof(struct eaptls_session)); if (!esp->es_server.ea_session) fatal("Allocation error"); ets = esp->es_server.ea_session; if (!esp->es_server.ea_peer) { error("EAP-TLS: Error: client name not set (BUG)"); return 0; } dbglog( "getting eaptls secret" ); if (!get_eaptls_secret(esp->es_unit, esp->es_server.ea_peer, esp->es_server.ea_name, clicertfile, servcertfile, cacertfile, capath, pkfile, pkcs12, 1)) { error( "EAP-TLS: Cannot get secret/password for client \"%s\", server \"%s\"", esp->es_server.ea_peer, esp->es_server.ea_name ); return 0; } ets->mtu = eaptls_get_mtu(esp->es_unit); ets->ctx = eaptls_init_ssl(1, cacertfile, capath, servcertfile, pkfile, pkcs12); if (!ets->ctx) goto fail; if (!(ets->ssl = SSL_new(ets->ctx))) goto fail; if (tls_set_verify_info(ets->ssl, esp->es_server.ea_peer, clicertfile, 0, &ets->info)) goto fail; /* * Set auto-retry to avoid timeouts on BIO_read */ SSL_set_mode(ets->ssl, SSL_MODE_AUTO_RETRY); /* * Initialize the BIOs we use to read/write to ssl engine */ ets->into_ssl = BIO_new(BIO_s_mem()); ets->from_ssl = BIO_new(BIO_s_mem()); SSL_set_bio(ets->ssl, ets->into_ssl, ets->from_ssl); SSL_set_msg_callback(ets->ssl, ssl_msg_callback); SSL_set_msg_callback_arg(ets->ssl, ets); SSL_set_accept_state(ets->ssl); ets->tls_v13 = 0; ets->data = NULL; ets->datalen = 0; ets->alert_sent = 0; ets->alert_recv = 0; return 1; fail: SSL_CTX_free(ets->ctx); return 0; } /* * Init the ssl handshake (client mode) */ int eaptls_init_ssl_client(eap_state * esp) { struct eaptls_session *ets; char servcertfile[MAXWORDLEN]; char clicertfile[MAXWORDLEN]; char cacertfile[MAXWORDLEN]; char capath[MAXWORDLEN]; char pkfile[MAXWORDLEN]; char pkcs12[MAXWORDLEN]; /* * Allocate new eaptls session */ esp->es_client.ea_session = malloc(sizeof(struct eaptls_session)); if (!esp->es_client.ea_session) fatal("Allocation error"); ets = esp->es_client.ea_session; ets->mtu = eaptls_get_mtu(esp->es_unit); dbglog( "calling get_eaptls_secret" ); if (!get_eaptls_secret(esp->es_unit, esp->es_client.ea_name, esp->es_client.ea_peer, clicertfile, servcertfile, cacertfile, capath, pkfile, pkcs12, 0)) { error( "EAP-TLS: Cannot get secret/password for client \"%s\", server \"%s\"", esp->es_client.ea_name, esp->es_client.ea_peer); return 0; } dbglog( "calling eaptls_init_ssl" ); ets->ctx = eaptls_init_ssl(0, cacertfile, capath, clicertfile, pkfile, pkcs12); if (!ets->ctx) goto fail; ets->ssl = SSL_new(ets->ctx); if (!ets->ssl) goto fail; if (tls_set_verify_info(ets->ssl, esp->es_client.ea_peer, servcertfile, 0, &ets->info)) goto fail; /* * Initialize the BIOs we use to read/write to ssl engine */ dbglog( "Initializing SSL BIOs" ); ets->into_ssl = BIO_new(BIO_s_mem()); ets->from_ssl = BIO_new(BIO_s_mem()); SSL_set_bio(ets->ssl, ets->into_ssl, ets->from_ssl); SSL_set_msg_callback(ets->ssl, ssl_msg_callback); SSL_set_msg_callback_arg(ets->ssl, ets); SSL_set_connect_state(ets->ssl); ets->tls_v13 = 0; ets->data = NULL; ets->datalen = 0; ets->alert_sent = 0; ets->alert_recv = 0; return 1; fail: dbglog( "eaptls_init_ssl_client: fail" ); SSL_CTX_free(ets->ctx); return 0; } void eaptls_free_session(struct eaptls_session *ets) { if (ets->ssl) SSL_free(ets->ssl); if (ets->ctx) SSL_CTX_free(ets->ctx); if (ets->info) tls_free_verify_info(&ets->info); free(ets); } int eaptls_is_init_finished(struct eaptls_session *ets) { if (ets->ssl && SSL_is_init_finished(ets->ssl)) { if (ets->tls_v13) return have_session_ticket; else return 1; } return 0; } /* * Handle a received packet, reassembling fragmented messages and * passing them to the ssl engine */ int eaptls_receive(struct eaptls_session *ets, u_char * inp, int len) { u_char flags; u_int tlslen = 0; u_char dummy[65536]; if (len < 1) { warn("EAP-TLS: received no or invalid data"); return 1; } GETCHAR(flags, inp); len--; if (flags & EAP_TLS_FLAGS_LI && len > 4) { /* * LenghtIncluded flag set -> this is the first packet of a message */ /* * the first 4 octets are the length of the EAP-TLS message */ GETLONG(tlslen, inp); len -= 4; if (!ets->data) { if (tlslen > EAP_TLS_MAX_LEN) { error("EAP-TLS: TLS message length > %d, truncated", EAP_TLS_MAX_LEN); tlslen = EAP_TLS_MAX_LEN; } /* * Allocate memory for the whole message */ ets->data = malloc(tlslen); if (!ets->data) fatal("EAP-TLS: allocation error\n"); ets->datalen = 0; ets->tlslen = tlslen; } else warn("EAP-TLS: non-first LI packet? that's odd..."); } else if (!ets->data) { /* * A non fragmented message without LI flag */ ets->data = malloc(len); if (!ets->data) fatal("EAP-TLS: memory allocation error in eaptls_receive\n"); ets->datalen = 0; ets->tlslen = len; } if (flags & EAP_TLS_FLAGS_MF) ets->frag = 1; else ets->frag = 0; if (len < 0) { warn("EAP-TLS: received malformed data"); return 1; } if (len + ets->datalen > ets->tlslen) { warn("EAP-TLS: received data > TLS message length"); return 1; } BCOPY(inp, ets->data + ets->datalen, len); ets->datalen += len; if (!ets->frag) { /* * If we have the whole message, pass it to ssl */ if (ets->datalen != ets->tlslen) { warn("EAP-TLS: received data != TLS message length"); return 1; } if (BIO_write(ets->into_ssl, ets->data, ets->datalen) == -1) tls_log_sslerr(); SSL_read(ets->ssl, dummy, 65536); free(ets->data); ets->data = NULL; ets->datalen = 0; } return 0; } /* * Return an eap-tls packet in outp. * A TLS message read from the ssl engine is buffered in ets->data. * At each call we control if there is buffered data and send a * packet of mtu bytes. */ int eaptls_send(struct eaptls_session *ets, u_char ** outp) { bool first = 0; int size; u_char fromtls[65536]; int res; u_char *start; start = *outp; if (!ets->data) { if(!ets->alert_sent) { res = SSL_read(ets->ssl, fromtls, 65536); } /* * Read from ssl */ if ((res = BIO_read(ets->from_ssl, fromtls, 65536)) == -1) { warn("EAP-TLS send: No data from BIO_read"); return 1; } ets->datalen = res; ets->data = malloc(ets->datalen); if (!ets->data) fatal("EAP-TLS: memory allocation error in eaptls_send\n"); BCOPY(fromtls, ets->data, ets->datalen); ets->offset = 0; first = 1; } size = ets->datalen - ets->offset; if (size > ets->mtu) { size = ets->mtu; ets->frag = 1; } else ets->frag = 0; PUTCHAR(EAPT_TLS, *outp); /* * Set right flags and length if necessary */ if (ets->frag && first) { PUTCHAR(EAP_TLS_FLAGS_LI | EAP_TLS_FLAGS_MF, *outp); PUTLONG(ets->datalen, *outp); } else if (ets->frag) { PUTCHAR(EAP_TLS_FLAGS_MF, *outp); } else PUTCHAR(0, *outp); /* * Copy the data in outp */ BCOPY(ets->data + ets->offset, *outp, size); INCPTR(size, *outp); /* * Copy the packet in retransmission buffer */ BCOPY(start, &ets->rtx[0], *outp - start); ets->rtx_len = *outp - start; ets->offset += size; if (ets->offset >= ets->datalen) { /* * The whole message has been sent */ free(ets->data); ets->data = NULL; ets->datalen = 0; ets->offset = 0; } return 0; } /* * Get the sent packet from the retransmission buffer */ void eaptls_retransmit(struct eaptls_session *ets, u_char ** outp) { BCOPY(ets->rtx, *outp, ets->rtx_len); INCPTR(ets->rtx_len, *outp); } /* * Every sent & received message this callback function is invoked, * so we know when alert messages have arrived or are sent and * we can print debug information about TLS handshake. */ void ssl_msg_callback(int write_p, int version, int content_type, const void *buf, size_t len, SSL * ssl, void *arg) { char string[256]; struct eaptls_session *ets = (struct eaptls_session *)arg; unsigned char code; const unsigned char*msg = buf; int hvers = msg[1] << 8 | msg[2]; if(write_p) strcpy(string, " -> "); else strcpy(string, " <- "); switch(content_type) { case SSL3_RT_HEADER: strcat(string, "SSL/TLS Header: "); switch(hvers) { case SSL3_VERSION: strcat(string, "SSL 3.0"); break; case TLS1_VERSION: strcat(string, "TLS 1.0"); break; case TLS1_1_VERSION: strcat(string, "TLS 1.1"); break; case TLS1_2_VERSION: strcat(string, "TLS 1.2"); break; default: sprintf(string, "SSL/TLS Header: Unknown version (%d)", hvers); } break; case SSL3_RT_ALERT: strcat(string, "Alert: "); code = msg[1]; if (write_p) { ets->alert_sent = 1; ets->alert_sent_desc = code; } else { ets->alert_recv = 1; ets->alert_recv_desc = code; } strcat(string, SSL_alert_desc_string_long(code)); break; case SSL3_RT_CHANGE_CIPHER_SPEC: strcat(string, "ChangeCipherSpec"); break; #ifdef SSL3_RT_INNER_CONTENT_TYPE case SSL3_RT_INNER_CONTENT_TYPE: strcat(string, "InnerContentType (TLS1.3)"); break; #endif case SSL3_RT_HANDSHAKE: strcat(string, "Handshake: "); code = msg[0]; switch(code) { case SSL3_MT_HELLO_REQUEST: strcat(string,"Hello Request"); break; case SSL3_MT_CLIENT_HELLO: strcat(string,"Client Hello"); break; case SSL3_MT_SERVER_HELLO: strcat(string,"Server Hello"); break; #ifdef SSL3_MT_NEWSESSION_TICKET case SSL3_MT_NEWSESSION_TICKET: strcat(string,"New Session Ticket"); break; #endif #ifdef SSL3_MT_END_OF_EARLY_DATA case SSL3_MT_END_OF_EARLY_DATA: strcat(string,"End of Early Data"); break; #endif #ifdef SSL3_MT_ENCRYPTED_EXTENSIONS case SSL3_MT_ENCRYPTED_EXTENSIONS: strcat(string,"Encryped Extensions"); break; #endif case SSL3_MT_CERTIFICATE: strcat(string,"Certificate"); break; case SSL3_MT_SERVER_KEY_EXCHANGE: strcat(string,"Server Key Exchange"); break; case SSL3_MT_CERTIFICATE_REQUEST: strcat(string,"Certificate Request"); break; case SSL3_MT_SERVER_DONE: strcat(string,"Server Hello Done"); break; case SSL3_MT_CERTIFICATE_VERIFY: strcat(string,"Certificate Verify"); break; case SSL3_MT_CLIENT_KEY_EXCHANGE: strcat(string,"Client Key Exchange"); break; case SSL3_MT_FINISHED: strcat(string,"Finished: "); hvers = SSL_version(ssl); switch(hvers){ case SSL3_VERSION: strcat(string, "SSL 3.0"); break; case TLS1_VERSION: strcat(string, "TLS 1.0"); break; case TLS1_1_VERSION: strcat(string, "TLS 1.1"); break; case TLS1_2_VERSION: strcat(string, "TLS 1.2"); break; #ifdef TLS1_3_VERSION case TLS1_3_VERSION: strcat(string, "TLS 1.3 (experimental)"); ets->tls_v13 = 1; break; #endif default: strcat(string, "Unknown version"); } break; default: sprintf( string, "Handshake: Unknown SSL3 code received: %d", code ); } break; default: sprintf( string, "SSL message contains unknown content type: %d", content_type ); } /* Alert messages must always be displayed */ if(content_type == SSL3_RT_ALERT) error("%s", string); else dbglog("%s", string); } int ssl_new_session_cb(SSL *s, SSL_SESSION *sess) { dbglog("EAP-TLS: Post-Handshake New Session Ticket arrived:"); have_session_ticket = 1; /* always return success */ return 1; } ppp-2.5.0/pppd/tls.c0000644000175000017500000003000314353435407011153 00000000000000/* * Copyright (c) 2021 Eivind Næss. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The name(s) of the authors of this software must not be used to * endorse or promote products derived from this software without * prior written permission. * * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include "pppd-private.h" #include "tls.h" /** * Structure used in verifying the peer certificate */ struct tls_info { char *peer_name; X509 *peer_cert; bool client; }; #if OPENSSL_VERSION_NUMBER < 0x10100000L /* * OpenSSL 1.1+ introduced a generic TLS_method() * For older releases we substitute the appropriate method */ #define TLS_method SSLv23_method #ifndef SSL_CTX_set_max_proto_version /** Mimics SSL_CTX_set_max_proto_version for OpenSSL < 1.1 */ static inline int SSL_CTX_set_max_proto_version(SSL_CTX *ctx, long tls_ver_max) { long sslopt = 0; if (tls_ver_max < TLS1_VERSION) { sslopt |= SSL_OP_NO_TLSv1; } #ifdef SSL_OP_NO_TLSv1_1 if (tls_ver_max < TLS1_1_VERSION) { sslopt |= SSL_OP_NO_TLSv1_1; } #endif #ifdef SSL_OP_NO_TLSv1_2 if (tls_ver_max < TLS1_2_VERSION) { sslopt |= SSL_OP_NO_TLSv1_2; } #endif SSL_CTX_set_options(ctx, sslopt); return 1; } #endif /* SSL_CTX_set_max_proto_version */ #endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */ /* * Verify a certificate. Most of the work (signatures and issuer attributes checking) * is done by ssl; we check the CN in the peer certificate against the peer name. */ static int tls_verify_callback(int ok, X509_STORE_CTX *ctx) { char subject[256]; char cn_str[256]; X509 *peer_cert; int err, depth; SSL *ssl; struct tls_info *inf; char *ptr1 = NULL, *ptr2 = NULL; peer_cert = X509_STORE_CTX_get_current_cert(ctx); err = X509_STORE_CTX_get_error(ctx); depth = X509_STORE_CTX_get_error_depth(ctx); dbglog("certificate verify depth: %d", depth); if (auth_required && !ok) { X509_NAME_oneline(X509_get_subject_name(peer_cert), subject, 256); X509_NAME_get_text_by_NID(X509_get_subject_name(peer_cert), NID_commonName, cn_str, 256); dbglog("Certificate verification error:\n depth: %d CN: %s" "\n err: %d (%s)\n", depth, cn_str, err, X509_verify_cert_error_string(err)); return 0; } ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx()); inf = (struct tls_info*) SSL_get_ex_data(ssl, 0); if (inf == NULL) { error("Error: SSL_get_ex_data returned NULL"); return 0; } tls_log_sslerr(); if (!depth) { /* Verify certificate based on certificate type and extended key usage */ if (tls_verify_key_usage) { int purpose = inf->client ? X509_PURPOSE_SSL_SERVER : X509_PURPOSE_SSL_CLIENT ; if (X509_check_purpose(peer_cert, purpose, 0) == 0) { error("Certificate verification error: nsCertType mismatch"); return 0; } #if OPENSSL_VERSION_NUMBER >= 0x10100000L int flags = inf->client ? XKU_SSL_SERVER : XKU_SSL_CLIENT; if (!(X509_get_extended_key_usage(peer_cert) & flags)) { error("Certificate verification error: invalid extended key usage"); return 0; } #endif info("Certificate key usage: OK"); } /* * If acting as client and the name of the server wasn't specified * explicitely, we can't verify the server authenticity */ if (!tls_verify_method) tls_verify_method = TLS_VERIFY_NONE; if (!inf->peer_name || !strcmp(TLS_VERIFY_NONE, tls_verify_method)) { warn("Certificate verication disabled or no peer name was specified"); return ok; } /* This is the peer certificate */ X509_NAME_oneline(X509_get_subject_name(peer_cert), subject, 256); X509_NAME_get_text_by_NID(X509_get_subject_name(peer_cert), NID_commonName, cn_str, 256); /* Verify based on subject name */ ptr1 = inf->peer_name; if (!strcmp(TLS_VERIFY_SUBJECT, tls_verify_method)) { ptr2 = subject; } /* Verify based on common name (default) */ if (strlen(tls_verify_method) == 0 || !strcmp(TLS_VERIFY_NAME, tls_verify_method)) { ptr2 = cn_str; } /* Match the suffix of common name */ if (!strcmp(TLS_VERIFY_SUFFIX, tls_verify_method)) { int len = strlen(ptr1); int off = strlen(cn_str) - len; ptr2 = cn_str; if (off > 0) { ptr2 = cn_str + off; } } if (strcmp(ptr1, ptr2)) { error("Certificate verification error: CN (%s) != %s", ptr1, ptr2); return 0; } if (inf->peer_cert) { if (X509_cmp(inf->peer_cert, peer_cert) != 0) { error("Peer certificate doesn't match stored certificate"); return 0; } } info("Certificate CN: %s, peer name %s", cn_str, inf->peer_name); } return ok; } int tls_init() { #if OPENSSL_VERSION_NUMBER < 0x10100000L SSL_library_init(); SSL_load_error_strings(); #endif return 0; } int tls_set_verify(SSL_CTX *ctx, int depth) { SSL_CTX_set_verify_depth(ctx, depth); SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, &tls_verify_callback); return 0; } int tls_set_verify_info(SSL *ssl, const char *peer_name, const char *peer_cert, bool client, struct tls_info **out) { if (out != NULL) { struct tls_info *tmp = calloc(sizeof(struct tls_info), 1); if (!tmp) { fatal("Allocation error"); } tmp->client = client; if (peer_name) { tmp->peer_name = strdup(peer_name); } if (peer_cert && strlen(peer_cert) > 0) { FILE *fp = fopen(peer_cert, "r"); if (fp) { tmp->peer_cert = PEM_read_X509(fp, NULL, NULL, NULL); fclose(fp); } if (!tmp->peer_cert) { error("EAP-TLS: Error loading client certificate from file %s", peer_cert); tls_free_verify_info(&tmp); return -1; } } SSL_set_ex_data(ssl, 0, tmp); *out = tmp; return 0; } return -1; } void tls_free_verify_info(struct tls_info **in) { if (in && *in) { struct tls_info *tmp = *in; if (tmp->peer_name) { free(tmp->peer_name); } if (tmp->peer_cert) { X509_free(tmp->peer_cert); } free(tmp); *in = NULL; } } const SSL_METHOD* tls_method() { return TLS_method(); } int tls_set_version(SSL_CTX *ctx, const char *max_version) { #if defined(TLS1_2_VERSION) long tls_version = TLS1_2_VERSION; #elif defined(TLS1_1_VERSION) long tls_version = TLS1_1_VERSION; #else long tls_version = TLS1_VERSION; #endif /* As EAP-TLS+TLSv1.3 is highly experimental we offer the user a chance to override */ if (max_version) { if (strncmp(max_version, "1.0", 3) == 0) { tls_version = TLS1_VERSION; } else if (strncmp(max_version, "1.1", 3) == 0) { tls_version = TLS1_1_VERSION; } else if (strncmp(max_version, "1.2", 3) == 0) { #ifdef TLS1_2_VERSION tls_version = TLS1_2_VERSION; #else warn("TLSv1.2 not available. Defaulting to TLSv1.1"); tls_version = TLS_1_1_VERSION; #endif } else if (strncmp(max_version, "1.3", 3) == 0) { #ifdef TLS1_3_VERSION tls_version = TLS1_3_VERSION; #else warn("TLSv1.3 not available."); #endif } } dbglog("Setting max protocol version to 0x%X", tls_version); if (!SSL_CTX_set_max_proto_version(ctx, tls_version)) { error("Could not set max protocol version"); return -1; } return 0; } int tls_set_opts(SSL_CTX *ctx) { /* Explicitly set the NO_TICKETS flag to support Win7/Win8 clients */ SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 #ifdef SSL_OP_NO_TICKET | SSL_OP_NO_TICKET #endif | SSL_OP_NO_COMPRESSION ); /* OpenSSL 1.1.1+ does not include RC4 ciphers by default. * This causes totally obsolete WinXP clients to fail. If you really * need ppp+EAP-TLS+openssl 1.1.1+WinXP then enable RC4 cipers and * make sure that you use an OpenSSL that supports them SSL_CTX_set_cipher_list(ctx, "RC4"); */ return 0; } int tls_set_crl(SSL_CTX *ctx, const char *crl_dir, const char *crl_file) { X509_STORE *certstore = NULL; X509_LOOKUP *lookup = NULL; FILE *fp = NULL; int status = -1; if (crl_dir) { if (!(certstore = SSL_CTX_get_cert_store(ctx))) { error("Failed to get certificate store"); goto done; } if (!(lookup = X509_STORE_add_lookup(certstore, X509_LOOKUP_hash_dir()))) { error("Store lookup for CRL failed"); goto done; } X509_LOOKUP_add_dir(lookup, crl_dir, X509_FILETYPE_PEM); X509_STORE_set_flags(certstore, X509_V_FLAG_CRL_CHECK); } if (crl_file) { X509_CRL *crl = NULL; fp = fopen(crl_file, "r"); if (!fp) { error("Cannot open CRL file '%s'", crl_file); goto done; } crl = PEM_read_X509_CRL(fp, NULL, NULL, NULL); if (!crl) { error("Cannot read CRL file '%s'", crl_file); goto done; } if (!(certstore = SSL_CTX_get_cert_store(ctx))) { error("Failed to get certificate store"); goto done; } if (!X509_STORE_add_crl(certstore, crl)) { error("Cannot add CRL to certificate store"); goto done; } X509_STORE_set_flags(certstore, X509_V_FLAG_CRL_CHECK); } status = 0; done: if (fp != NULL) { fclose(fp); } return status; } int tls_set_ca(SSL_CTX *ctx, const char *ca_dir, const char *ca_file) { if (ca_file && strlen(ca_file) == 0) { ca_file = NULL; } if (ca_dir && strlen(ca_dir) == 0) { ca_dir = NULL; } if (!SSL_CTX_load_verify_locations(ctx, ca_file, ca_dir)) { error("Cannot load verify locations"); if (ca_file) { dbglog("CA certificate file = [%s]", ca_file); } if (ca_dir) { dbglog("CA certificate path = [%s]", ca_dir); } return -1; } return 0; } void tls_log_sslerr( void ) { unsigned long ssl_err = ERR_get_error(); if (ssl_err != 0) dbglog("EAP-TLS SSL error stack:"); while (ssl_err != 0) { dbglog( ERR_error_string( ssl_err, NULL ) ); ssl_err = ERR_get_error(); } } ppp-2.5.0/pppd/peap.c0000644000175000017500000005207714353435407011315 00000000000000/* * Copyright (c) 2011 Rustam Kovhaev. All rights reserved. * Copyright (c) 2021 Eivind Næss. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The name(s) of the authors of this software must not be used to * endorse or promote products derived from this software without * prior written permission. * * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * NOTES: * * PEAP has 2 phases, * 1 - Outer EAP, where TLS session gets established * 2 - Inner EAP, where inside TLS session with EAP MSCHAPV2 auth, or any other auth * * And so protocols encapsulation looks like this: * Outer EAP -> TLS -> Inner EAP -> MSCHAPV2 * PEAP can compress an inner EAP packet prior to encapsulating it within * the Data field of a PEAP packet by removing its Code, Identifier, * and Length fields, and Microsoft PEAP server/client always does that * * Current implementation does not support: * a) Fast reconnect * b) Inner EAP fragmentation * c) Any other auth other than MSCHAPV2 * * For details on the PEAP protocol, look to Microsoft: * https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-peap */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include #include #include #include "pppd-private.h" #include "eap.h" #include "tls.h" #include "chap.h" #include "chap_ms.h" #include "mppe.h" #include "peap.h" #ifdef UNIT_TEST #define novm(x) #endif struct peap_state { SSL_CTX *ctx; SSL *ssl; BIO *in_bio; BIO *out_bio; int phase; int written, read; u_char *in_buf; u_char *out_buf; u_char ipmk[PEAP_TLV_IPMK_LEN]; u_char tk[PEAP_TLV_TK_LEN]; u_char nonce[PEAP_TLV_NONCE_LEN]; struct tls_info *info; #ifdef PPP_WITH_CHAPMS struct chap_digest_type *chap; #endif }; /* * K = Key, S = Seed, LEN = output length * PRF+(K, S, LEN) = T1 | T2 | ... |Tn * Where: * T1 = HMAC-SHA1 (K, S | 0x01 | 0x00 | 0x00) * T2 = HMAC-SHA1 (K, T1 | S | 0x02 | 0x00 | 0x00) * ... * Tn = HMAC-SHA1 (K, Tn-1 | S | n | 0x00 | 0x00) * As shown, PRF+ is computed in iterations. The number of iterations (n) * depends on the output length (LEN). */ static void peap_prfplus(u_char *seed, size_t seed_len, u_char *key, size_t key_len, u_char *out_buf, size_t pfr_len) { int pos; u_char *buf, *hash; size_t max_iter, i, j, k; u_int len; max_iter = (pfr_len + SHA_DIGEST_LENGTH - 1) / SHA_DIGEST_LENGTH; buf = malloc(seed_len + max_iter * SHA_DIGEST_LENGTH); if (!buf) novm("pfr buffer"); hash = malloc(pfr_len + SHA_DIGEST_LENGTH); if (!hash) novm("hash buffer"); for (i = 0; i < max_iter; i++) { j = 0; k = 0; if (i > 0) j = SHA_DIGEST_LENGTH; for (k = 0; k < seed_len; k++) buf[j + k] = seed[k]; pos = j + k; buf[pos] = i + 1; pos++; buf[pos] = 0x00; pos++; buf[pos] = 0x00; pos++; if (!HMAC(EVP_sha1(), key, key_len, buf, pos, (hash + i * SHA_DIGEST_LENGTH), &len)) fatal("HMAC() failed"); for (j = 0; j < SHA_DIGEST_LENGTH; j++) buf[j] = hash[i * SHA_DIGEST_LENGTH + j]; } BCOPY(hash, out_buf, pfr_len); free(hash); free(buf); } static void generate_cmk(u_char *ipmk, u_char *tempkey, u_char *nonce, u_char *tlv_response_out, int client) { const char *label = PEAP_TLV_IPMK_SEED_LABEL; u_char data_tlv[PEAP_TLV_DATA_LEN] = {0}; u_char isk[PEAP_TLV_ISK_LEN] = {0}; u_char ipmkseed[PEAP_TLV_IPMKSEED_LEN] = {0}; u_char cmk[PEAP_TLV_CMK_LEN] = {0}; u_char buf[PEAP_TLV_CMK_LEN + PEAP_TLV_IPMK_LEN] = {0}; u_char compound_mac[PEAP_TLV_COMP_MAC_LEN] = {0}; u_int len; /* format outgoing CB TLV response packet */ data_tlv[1] = PEAP_TLV_TYPE; data_tlv[3] = PEAP_TLV_LENGTH_FIELD; if (client) data_tlv[7] = PEAP_TLV_SUBTYPE_RESPONSE; else data_tlv[7] = PEAP_TLV_SUBTYPE_REQUEST; BCOPY(nonce, (data_tlv + PEAP_TLV_HEADERLEN), PEAP_TLV_NONCE_LEN); data_tlv[60] = EAPT_PEAP; #ifdef PPP_WITH_MPPE mppe_get_send_key(isk, MPPE_MAX_KEY_LEN); mppe_get_recv_key(isk + MPPE_MAX_KEY_LEN, MPPE_MAX_KEY_LEN); #endif BCOPY(label, ipmkseed, strlen(label)); BCOPY(isk, ipmkseed + strlen(label), PEAP_TLV_ISK_LEN); peap_prfplus(ipmkseed, PEAP_TLV_IPMKSEED_LEN, tempkey, PEAP_TLV_TEMPKEY_LEN, buf, PEAP_TLV_CMK_LEN + PEAP_TLV_IPMK_LEN); BCOPY(buf, ipmk, PEAP_TLV_IPMK_LEN); BCOPY(buf + PEAP_TLV_IPMK_LEN, cmk, PEAP_TLV_CMK_LEN); if (!HMAC(EVP_sha1(), cmk, PEAP_TLV_CMK_LEN, data_tlv, PEAP_TLV_DATA_LEN, compound_mac, &len)) fatal("HMAC() failed"); BCOPY(compound_mac, data_tlv + PEAP_TLV_HEADERLEN + PEAP_TLV_NONCE_LEN, PEAP_TLV_COMP_MAC_LEN); /* do not copy last byte to response packet */ BCOPY(data_tlv, tlv_response_out, PEAP_TLV_DATA_LEN - 1); } static void verify_compound_mac(struct peap_state *psm, u_char *in_buf) { u_char nonce[PEAP_TLV_NONCE_LEN] = {0}; u_char out_buf[PEAP_TLV_LEN] = {0}; BCOPY(in_buf, nonce, PEAP_TLV_NONCE_LEN); generate_cmk(psm->ipmk, psm->tk, nonce, out_buf, 0); if (memcmp((in_buf + PEAP_TLV_NONCE_LEN), (out_buf + PEAP_TLV_HEADERLEN + PEAP_TLV_NONCE_LEN), PEAP_TLV_CMK_LEN)) fatal("server's CMK does not match client's CMK, potential MiTM"); } #ifdef PPP_WITH_MPPE #define PEAP_MPPE_KEY_LEN 32 static void generate_mppe_keys(u_char *ipmk, int client) { const char *label = PEAP_TLV_CSK_SEED_LABEL; u_char csk[PEAP_TLV_CSK_LEN] = {0}; size_t len; dbglog("PEAP CB: generate mppe keys"); len = strlen(label); len++; /* CSK requires NULL byte in seed */ peap_prfplus((u_char *)label, len, ipmk, PEAP_TLV_IPMK_LEN, csk, PEAP_TLV_CSK_LEN); /* * The first 64 bytes of the CSK are split into two MPPE keys, as follows. * * +-----------------------+------------------------+ * | First 32 bytes of CSK | Second 32 bytes of CSK | * +-----------------------+------------------------+ * | MS-MPPE-Send-Key | MS-MPPE-Recv-Key | * +-----------------------+------------------------+ */ if (client) { mppe_set_keys(csk, csk + PEAP_MPPE_KEY_LEN, PEAP_MPPE_KEY_LEN); } else { mppe_set_keys(csk + PEAP_MPPE_KEY_LEN, csk, PEAP_MPPE_KEY_LEN); } } #endif #ifndef UNIT_TEST static void peap_ack(eap_state *esp, u_char id) { u_char *outp; outp = outpacket_buf; MAKEHEADER(outp, PPP_EAP); PUTCHAR(EAP_RESPONSE, outp); PUTCHAR(id, outp); esp->es_client.ea_id = id; PUTSHORT(PEAP_HEADERLEN, outp); PUTCHAR(EAPT_PEAP, outp); PUTCHAR(PEAP_FLAGS_ACK, outp); output(esp->es_unit, outpacket_buf, PPP_HDRLEN + PEAP_HEADERLEN); } static void peap_response(eap_state *esp, u_char id, u_char *buf, int len) { struct peap_state *psm = esp->ea_peap; u_char *outp; int peap_len; outp = outpacket_buf; MAKEHEADER(outp, PPP_EAP); PUTCHAR(EAP_RESPONSE, outp); PUTCHAR(id, outp); esp->es_client.ea_id = id; if (psm->phase == PEAP_PHASE_1) peap_len = PEAP_HEADERLEN + PEAP_FRAGMENT_LENGTH_FIELD + len; else peap_len = PEAP_HEADERLEN + len; PUTSHORT(peap_len, outp); PUTCHAR(EAPT_PEAP, outp); if (psm->phase == PEAP_PHASE_1) { PUTCHAR(PEAP_L_FLAG_SET, outp); PUTLONG(len, outp); } else PUTCHAR(PEAP_NO_FLAGS, outp); BCOPY(buf, outp, len); output(esp->es_unit, outpacket_buf, PPP_HDRLEN + peap_len); } void peap_do_inner_eap(u_char *in_buf, int in_len, eap_state *esp, int id, u_char *out_buf, int *out_len) { struct peap_state *psm = esp->ea_peap; int used = 0; int typenum; int secret_len; char secret[MAXSECRETLEN + 1]; char rhostname[MAXWORDLEN]; u_char *outp = out_buf; dbglog("PEAP: EAP (in): %.*B", in_len, in_buf); if (*(in_buf + EAP_HEADERLEN) == PEAP_CAPABILITIES_TYPE && in_len == (EAP_HEADERLEN + PEAP_CAPABILITIES_LEN)) { /* use original packet as template for response */ BCOPY(in_buf, outp, EAP_HEADERLEN + PEAP_CAPABILITIES_LEN); PUTCHAR(EAP_RESPONSE, outp); PUTCHAR(id, outp); /* change last byte to 0 to disable fragmentation */ *(outp + PEAP_CAPABILITIES_LEN + 1) = 0x00; used = EAP_HEADERLEN + PEAP_CAPABILITIES_LEN; goto done; } if (*(in_buf + EAP_HEADERLEN + PEAP_TLV_HEADERLEN) == PEAP_TLV_TYPE && in_len == PEAP_TLV_LEN) { /* PEAP TLV message, do cryptobinding */ SSL_export_keying_material(psm->ssl, psm->tk, PEAP_TLV_TK_LEN, PEAP_TLV_TK_SEED_LABEL, strlen(PEAP_TLV_TK_SEED_LABEL), NULL, 0, 0); /* verify server's CMK */ verify_compound_mac(psm, in_buf + EAP_HEADERLEN + PEAP_TLV_RESULT_LEN + PEAP_TLV_HEADERLEN); /* generate client's CMK with new nonce */ PUTCHAR(EAP_RESPONSE, outp); PUTCHAR(id, outp); PUTSHORT(PEAP_TLV_LEN, outp); BCOPY(in_buf + EAP_HEADERLEN, outp, PEAP_TLV_RESULT_LEN); outp = outp + PEAP_TLV_RESULT_LEN; RAND_bytes(psm->nonce, PEAP_TLV_NONCE_LEN); generate_cmk(psm->ipmk, psm->tk, psm->nonce, outp, 1); #ifdef PPP_WITH_MPPE /* set mppe keys */ generate_mppe_keys(psm->ipmk, 1); #endif used = PEAP_TLV_LEN; goto done; } GETCHAR(typenum, in_buf); in_len--; switch (typenum) { case EAPT_IDENTITY: /* Respond with our identity to the peer */ PUTCHAR(EAPT_IDENTITY, outp); BCOPY(esp->es_client.ea_name, outp, esp->es_client.ea_namelen); used += (esp->es_client.ea_namelen + 1); break; case EAPT_TLS: /* Send NAK to EAP_TLS request */ PUTCHAR(EAPT_NAK, outp); PUTCHAR(EAPT_MSCHAPV2, outp); used += 2; break; #if PPP_WITH_CHAPMS case EAPT_MSCHAPV2: { // Must have at least 4 more bytes to process CHAP header if (in_len < 4) { error("PEAP: received invalid MSCHAPv2 packet, too short"); break; } u_char opcode; GETCHAR(opcode, in_buf); u_char chap_id; GETCHAR(chap_id, in_buf); short mssize; GETSHORT(mssize, in_buf); // Validate the CHAP packet (including header) if (in_len != mssize) { error("PEAP: received invalid MSCHAPv2 packet, invalid length"); break; } in_len -= 4; switch (opcode) { case CHAP_CHALLENGE: { u_char *challenge = in_buf; // VLEN + VALUE u_char vsize; GETCHAR(vsize, in_buf); in_len -= 1; if (vsize != MS_CHAP2_PEER_CHAL_LEN || in_len < MS_CHAP2_PEER_CHAL_LEN) { error("PEAP: received invalid MSCHAPv2 packet, invalid value-length: %d", vsize); goto done; } INCPTR(MS_CHAP2_PEER_CHAL_LEN, in_buf); in_len -= MS_CHAP2_PEER_CHAL_LEN; // Copy the provided remote host name rhostname[0] = '\0'; if (in_len > 0) { if (in_len >= sizeof(rhostname)) { dbglog("PEAP: trimming really long peer name down"); in_len = sizeof(rhostname) - 1; } BCOPY(in_buf, rhostname, in_len); rhostname[in_len] = '\0'; } // In case the remote doesn't give us his name, or user explictly specified remotename is config if (explicit_remote || (remote_name[0] != '\0' && in_len == 0)) strlcpy(rhostname, remote_name, sizeof(rhostname)); // Get the scrert for authenticating ourselves with the specified host if (get_secret(esp->es_unit, esp->es_client.ea_name, rhostname, secret, &secret_len, 0)) { u_char response[MS_CHAP2_RESPONSE_LEN+1]; u_char user_len = esp->es_client.ea_namelen; char *user = esp->es_client.ea_name; psm->chap->make_response(response, chap_id, user, challenge, secret, secret_len, NULL); PUTCHAR(EAPT_MSCHAPV2, outp); PUTCHAR(CHAP_RESPONSE, outp); PUTCHAR(chap_id, outp); PUTCHAR(0, outp); PUTCHAR(5 + user_len + MS_CHAP2_RESPONSE_LEN, outp); BCOPY(response, outp, MS_CHAP2_RESPONSE_LEN+1); // VLEN + VALUE INCPTR(MS_CHAP2_RESPONSE_LEN+1, outp); BCOPY(user, outp, user_len); used = 5 + user_len + MS_CHAP2_RESPONSE_LEN + 1; } else { dbglog("PEAP: no CHAP secret for auth to %q", rhostname); PUTCHAR(EAPT_NAK, outp); ++used; } break; } case CHAP_SUCCESS: { u_char status = CHAP_FAILURE; if (psm->chap->check_success(chap_id, in_buf, in_len)) { info("Chap authentication succeeded! %.*v", in_len, in_buf); status = CHAP_SUCCESS; } PUTCHAR(EAPT_MSCHAPV2, outp); PUTCHAR(status, outp); used += 2; break; } case CHAP_FAILURE: { u_char status = CHAP_FAILURE; psm->chap->handle_failure(in_buf, in_len); PUTCHAR(EAPT_MSCHAPV2, outp); PUTCHAR(status, outp); used += 2; break; } default: break; } break; } // EAPT_MSCHAPv2 #endif default: /* send compressed EAP NAK for any unknown packet */ PUTCHAR(EAPT_NAK, outp); ++used; } done: dbglog("PEAP: EAP (out): %.*B", used, psm->out_buf); *out_len = used; } int peap_init(struct peap_state **ctx, const char *rhostname) { const SSL_METHOD *method; if (!ctx) return -1; tls_init(); struct peap_state *psm = malloc(sizeof(*psm)); if (!psm) novm("peap psm struct"); psm->in_buf = malloc(TLS_RECORD_MAX_SIZE); if (!psm->in_buf) novm("peap tls buffer"); psm->out_buf = malloc(TLS_RECORD_MAX_SIZE); if (!psm->out_buf) novm("peap tls buffer"); method = tls_method(); if (!method) novm("TLS_method() failed"); psm->ctx = SSL_CTX_new(method); if (!psm->ctx) novm("SSL_CTX_new() failed"); /* Configure the default options */ tls_set_opts(psm->ctx); /* Configure the max TLS version */ tls_set_version(psm->ctx, max_tls_version); /* Configure the peer certificate callback */ tls_set_verify(psm->ctx, 5); /* Configure CA locations */ if (tls_set_ca(psm->ctx, ca_path, cacert_file)) { fatal("Could not set CA verify locations"); } /* Configure CRL check (if any) */ if (tls_set_crl(psm->ctx, crl_dir, crl_file)) { fatal("Could not set CRL verify locations"); } psm->out_bio = BIO_new(BIO_s_mem()); psm->in_bio = BIO_new(BIO_s_mem()); BIO_set_mem_eof_return(psm->out_bio, -1); BIO_set_mem_eof_return(psm->in_bio, -1); psm->ssl = SSL_new(psm->ctx); SSL_set_bio(psm->ssl, psm->in_bio, psm->out_bio); SSL_set_connect_state(psm->ssl); psm->phase = PEAP_PHASE_1; tls_set_verify_info(psm->ssl, explicit_remote ? rhostname : NULL, NULL, 1, &psm->info); psm->chap = chap_find_digest(CHAP_MICROSOFT_V2); *ctx = psm; return 0; } void peap_finish(struct peap_state **psm) { if (psm && *psm) { struct peap_state *tmp = *psm; if (tmp->ssl) SSL_free(tmp->ssl); if (tmp->ctx) SSL_CTX_free(tmp->ctx); if (tmp->info) tls_free_verify_info(&tmp->info); // NOTE: BIO and memory is freed as a part of SSL_free() free(*psm); *psm = NULL; } } int peap_process(eap_state *esp, u_char id, u_char *inp, int len) { int ret; int out_len; struct peap_state *psm = esp->ea_peap; if (esp->es_client.ea_id == id) { info("PEAP: retransmits are not supported.."); return -1; } switch (*inp) { case PEAP_S_FLAG_SET: dbglog("PEAP: S bit is set, starting PEAP phase 1"); ret = SSL_do_handshake(psm->ssl); if (ret != 1) { ret = SSL_get_error(psm->ssl, ret); if (ret != SSL_ERROR_WANT_READ && ret != SSL_ERROR_WANT_WRITE) fatal("SSL_do_handshake(): %s", ERR_error_string(ret, NULL)); } psm->read = BIO_read(psm->out_bio, psm->out_buf, TLS_RECORD_MAX_SIZE); peap_response(esp, id, psm->out_buf, psm->read); break; case PEAP_LM_FLAG_SET: dbglog("PEAP TLS: LM bits are set, need to get more TLS fragments"); inp = inp + PEAP_FRAGMENT_LENGTH_FIELD + PEAP_FLAGS_FIELD; psm->written = BIO_write(psm->in_bio, inp, len - PEAP_FRAGMENT_LENGTH_FIELD - PEAP_FLAGS_FIELD); peap_ack(esp, id); break; case PEAP_M_FLAG_SET: dbglog("PEAP TLS: M bit is set, need to get more TLS fragments"); inp = inp + PEAP_FLAGS_FIELD; psm->written = BIO_write(psm->in_bio, inp, len - PEAP_FLAGS_FIELD); peap_ack(esp, id); break; case PEAP_L_FLAG_SET: case PEAP_NO_FLAGS: if (*inp == PEAP_L_FLAG_SET) { dbglog("PEAP TLS: L bit is set"); inp = inp + PEAP_FRAGMENT_LENGTH_FIELD + PEAP_FLAGS_FIELD; psm->written = BIO_write(psm->in_bio, inp, len - PEAP_FRAGMENT_LENGTH_FIELD - PEAP_FLAGS_FIELD); } else { dbglog("PEAP TLS: all bits are off"); inp = inp + PEAP_FLAGS_FIELD; psm->written = BIO_write(psm->in_bio, inp, len - PEAP_FLAGS_FIELD); } if (psm->phase == PEAP_PHASE_1) { dbglog("PEAP TLS: continue handshake"); ret = SSL_do_handshake(psm->ssl); if (ret != 1) { ret = SSL_get_error(psm->ssl, ret); if (ret != SSL_ERROR_WANT_READ && ret != SSL_ERROR_WANT_WRITE) fatal("SSL_do_handshake(): %s", ERR_error_string(ret, NULL)); } if (SSL_is_init_finished(psm->ssl)) psm->phase = PEAP_PHASE_2; if (BIO_ctrl_pending(psm->out_bio) == 0) { peap_ack(esp, id); break; } psm->read = 0; psm->read = BIO_read(psm->out_bio, psm->out_buf, TLS_RECORD_MAX_SIZE); peap_response(esp, id, psm->out_buf, psm->read); break; } psm->read = SSL_read(psm->ssl, psm->in_buf, TLS_RECORD_MAX_SIZE); out_len = TLS_RECORD_MAX_SIZE; peap_do_inner_eap(psm->in_buf, psm->read, esp, id, psm->out_buf, &out_len); if (out_len > 0) { psm->written = SSL_write(psm->ssl, psm->out_buf, out_len); psm->read = BIO_read(psm->out_bio, psm->out_buf, TLS_RECORD_MAX_SIZE); peap_response(esp, id, psm->out_buf, psm->read); } break; } return 0; } #else u_char outpacket_buf[255]; int debug = 1; int error_count = 0; int unsuccess = 0; /** * Using the example in MS-PEAP, section 4.4.1. * see https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-peap/5308642b-90c9-4cc4-beec-fb367325c0f9 */ int test_cmk(u_char *ipmk) { u_char nonce[PEAP_TLV_NONCE_LEN] = { 0x6C, 0x6B, 0xA3, 0x87, 0x84, 0x23, 0x74, 0x57, 0xCC, 0xC9, 0x0B, 0x1A, 0x90, 0x8C, 0xBD, 0xF4, 0x71, 0x1B, 0x69, 0x99, 0x4D, 0x0C, 0xFE, 0x8D, 0x3D, 0xB4, 0x4E, 0xCB, 0xCD, 0xAD, 0x37, 0xE9 }; u_char tmpkey[PEAP_TLV_TEMPKEY_LEN] = { 0x73, 0x8B, 0xB5, 0xF4, 0x62, 0xD5, 0x8E, 0x7E, 0xD8, 0x44, 0xE1, 0xF0, 0x0D, 0x0E, 0xBE, 0x50, 0xC5, 0x0A, 0x20, 0x50, 0xDE, 0x11, 0x99, 0x77, 0x10, 0xD6, 0x5F, 0x45, 0xFB, 0x5F, 0xBA, 0xB7, 0xE3, 0x18, 0x1E, 0x92, 0x4F, 0x42, 0x97, 0x38, // 0xDE, 0x40, 0xC8, 0x46, 0xCD, 0xF5, 0x0B, 0xCB, // 0xF9, 0xCE, 0xDB, 0x1E, 0x85, 0x1D, 0x22, 0x52, // 0x45, 0x3B, 0xDF, 0x63 }; u_char expected[60] = { 0x00, 0x0C, 0x00, 0x38, 0x00, 0x00, 0x00, 0x01, 0x6C, 0x6B, 0xA3, 0x87, 0x84, 0x23, 0x74, 0x57, 0xCC, 0xC9, 0x0B, 0x1A, 0x90, 0x8C, 0xBD, 0xF4, 0x71, 0x1B, 0x69, 0x99, 0x4D, 0x0C, 0xFE, 0x8D, 0x3D, 0xB4, 0x4E, 0xCB, 0xCD, 0xAD, 0x37, 0xE9, 0x42, 0xE0, 0x86, 0x07, 0x1D, 0x1C, 0x8B, 0x8C, 0x8E, 0x45, 0x8F, 0x70, 0x21, 0xF0, 0x6A, 0x6E, 0xAB, 0x16, 0xB6, 0x46 }; u_char inner_mppe_keys[32] = { 0x67, 0x3E, 0x96, 0x14, 0x01, 0xBE, 0xFB, 0xA5, 0x60, 0x71, 0x7B, 0x3B, 0x5D, 0xDD, 0x40, 0x38, 0x65, 0x67, 0xF9, 0xF4, 0x16, 0xFD, 0x3E, 0x9D, 0xFC, 0x71, 0x16, 0x3B, 0xDF, 0xF2, 0xFA, 0x95 }; u_char response[60] = {}; // Set the inner MPPE keys (e.g. from CHAPv2) mppe_set_keys(inner_mppe_keys, inner_mppe_keys + 16, 16); // Generate and compare the response generate_cmk(ipmk, tmpkey, nonce, response, 1); if (memcmp(expected, response, sizeof(response)) != 0) { dbglog("Failed CMK key generation\n"); dbglog("%.*B", sizeof(response), response); dbglog("%.*B", sizeof(expected), expected); return -1; } return 0; } int test_mppe(u_char *ipmk) { u_char outer_mppe_send_key[MPPE_MAX_KEY_SIZE] = { 0x6A, 0x02, 0xD7, 0x82, 0x20, 0x1B, 0xC7, 0x13, 0x8B, 0xF8, 0xEF, 0xF7, 0x33, 0xB4, 0x96, 0x97, 0x0D, 0x7C, 0xAB, 0x30, 0x0A, 0xC9, 0x57, 0x72, 0x78, 0xE1, 0xDD, 0xD5, 0xAE, 0xF7, 0x66, 0x97 }; u_char outer_mppe_recv_key[MPPE_MAX_KEY_SIZE] = { 0x17, 0x52, 0xD4, 0xE5, 0x84, 0xA1, 0xC8, 0x95, 0x03, 0x9B, 0x4D, 0x05, 0xE3, 0xBC, 0x9A, 0x84, 0x84, 0xDD, 0xC2, 0xAA, 0x6E, 0x2C, 0xE1, 0x62, 0x76, 0x5C, 0x40, 0x68, 0xBF, 0xF6, 0x5A, 0x45 }; u_char result[MPPE_MAX_KEY_SIZE]; int len; mppe_clear_keys(); generate_mppe_keys(ipmk, 1); len = mppe_get_recv_key(result, sizeof(result)); if (len != sizeof(result)) { dbglog("Invalid length of resulting MPPE recv key"); return -1; } if (memcmp(result, outer_mppe_recv_key, len) != 0) { dbglog("Invalid result for outer mppe recv key"); return -1; } len = mppe_get_send_key(result, sizeof(result)); if (len != sizeof(result)) { dbglog("Invalid length of resulting MPPE send key"); return -1; } if (memcmp(result, outer_mppe_send_key, len) != 0) { dbglog("Invalid result for outer mppe send key"); return -1; } return 0; } int main(int argc, char *argv[]) { u_char ipmk[PEAP_TLV_IPMK_LEN] = { 0x3A, 0x91, 0x1C, 0x25, 0x54, 0x73, 0xE8, 0x3E, 0x9A, 0x0C, 0xC3, 0x33, 0xAE, 0x1F, 0x8A, 0x35, 0xCD, 0xC7, 0x41, 0x63, 0xE7, 0xF6, 0x0F, 0x6C, 0x65, 0xEF, 0x71, 0xC2, 0x64, 0x42, 0xAA, 0xAC, 0xA2, 0xB6, 0xF1, 0xEB, 0x4F, 0x25, 0xEC, 0xA3, }; int ret = -1; ret = test_cmk(ipmk); if (ret != 0) { return -1; } ret = test_mppe(ipmk); if (ret != 0) { return -1; } return 0; } #endif ppp-2.5.0/pppd/srp-entry.c0000664000175000017500000001262014076444143012322 00000000000000/* * Utility program for generating entries in /etc/ppp/srp-secrets * * Copyright (c) 2001 by Sun Microsystems, Inc. * All rights reserved. * * Non-exclusive rights to redistribute, modify, translate, and use * this software in source and binary forms, in whole or in part, is * hereby granted, provided that the above copyright notice is * duplicated in any source form, and that neither the name of the * copyright holder nor the author is used to endorse or promote * products derived from this software. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * * Original version by James Carlson * * Usage: * srp-entry [-i index] [clientname] * * Index, if supplied, is the modulus/generator index from * /etc/tpasswd.conf. If not supplied, then the last (highest * numbered) entry from that file is used. If the file doesn't exist, * then the default "well known" EAP SRP-SHA1 modulus/generator is * used. * * The default modulus/generator can be requested as index 0. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #ifndef SOL2 #define getpassphrase getpass #endif #define HAS_SPACE 1 #define HAS_DQUOTE 2 #define HAS_SQUOTE 4 #define HAS_BACKSLASH 8 static const u_char wkmodulus[] = { 0xAC, 0x6B, 0xDB, 0x41, 0x32, 0x4A, 0x9A, 0x9B, 0xF1, 0x66, 0xDE, 0x5E, 0x13, 0x89, 0x58, 0x2F, 0xAF, 0x72, 0xB6, 0x65, 0x19, 0x87, 0xEE, 0x07, 0xFC, 0x31, 0x92, 0x94, 0x3D, 0xB5, 0x60, 0x50, 0xA3, 0x73, 0x29, 0xCB, 0xB4, 0xA0, 0x99, 0xED, 0x81, 0x93, 0xE0, 0x75, 0x77, 0x67, 0xA1, 0x3D, 0xD5, 0x23, 0x12, 0xAB, 0x4B, 0x03, 0x31, 0x0D, 0xCD, 0x7F, 0x48, 0xA9, 0xDA, 0x04, 0xFD, 0x50, 0xE8, 0x08, 0x39, 0x69, 0xED, 0xB7, 0x67, 0xB0, 0xCF, 0x60, 0x95, 0x17, 0x9A, 0x16, 0x3A, 0xB3, 0x66, 0x1A, 0x05, 0xFB, 0xD5, 0xFA, 0xAA, 0xE8, 0x29, 0x18, 0xA9, 0x96, 0x2F, 0x0B, 0x93, 0xB8, 0x55, 0xF9, 0x79, 0x93, 0xEC, 0x97, 0x5E, 0xEA, 0xA8, 0x0D, 0x74, 0x0A, 0xDB, 0xF4, 0xFF, 0x74, 0x73, 0x59, 0xD0, 0x41, 0xD5, 0xC3, 0x3E, 0xA7, 0x1D, 0x28, 0x1E, 0x44, 0x6B, 0x14, 0x77, 0x3B, 0xCA, 0x97, 0xB4, 0x3A, 0x23, 0xFB, 0x80, 0x16, 0x76, 0xBD, 0x20, 0x7A, 0x43, 0x6C, 0x64, 0x81, 0xF1, 0xD2, 0xB9, 0x07, 0x87, 0x17, 0x46, 0x1A, 0x5B, 0x9D, 0x32, 0xE6, 0x88, 0xF8, 0x77, 0x48, 0x54, 0x45, 0x23, 0xB5, 0x24, 0xB0, 0xD5, 0x7D, 0x5E, 0xA7, 0x7A, 0x27, 0x75, 0xD2, 0xEC, 0xFA, 0x03, 0x2C, 0xFB, 0xDB, 0xF5, 0x2F, 0xB3, 0x78, 0x61, 0x60, 0x27, 0x90, 0x04, 0xE5, 0x7A, 0xE6, 0xAF, 0x87, 0x4E, 0x73, 0x03, 0xCE, 0x53, 0x29, 0x9C, 0xCC, 0x04, 0x1C, 0x7B, 0xC3, 0x08, 0xD8, 0x2A, 0x56, 0x98, 0xF3, 0xA8, 0xD0, 0xC3, 0x82, 0x71, 0xAE, 0x35, 0xF8, 0xE9, 0xDB, 0xFB, 0xB6, 0x94, 0xB5, 0xC8, 0x03, 0xD8, 0x9F, 0x7A, 0xE4, 0x35, 0xDE, 0x23, 0x6D, 0x52, 0x5F, 0x54, 0x75, 0x9B, 0x65, 0xE3, 0x72, 0xFC, 0xD6, 0x8E, 0xF2, 0x0F, 0xA7, 0x11, 0x1F, 0x9E, 0x4A, 0xFF, 0x73 }; static const char *myname; static void usage(void) { (void) fprintf(stderr, "Usage:\n\t%s [-i index] [clientname]\n", myname); exit(1); } int main(int argc, char **argv) { struct t_conf *tc; struct t_confent *tcent, mytce; struct t_pw pwval; char *name; char pname[256]; char *pass1, *pass2; int flags, idx; char *cp; char delimit; char strbuf[MAXB64PARAMLEN]; char saltbuf[MAXB64SALTLEN]; if ((myname = *argv) == NULL) myname = "srp-entry"; else argv++; idx = -1; if (*argv != NULL && strcmp(*argv, "-i") == 0) { if (*++argv == NULL) usage(); idx = atoi(*argv++); } tcent = NULL; if (idx != 0 && (tc = t_openconf(NULL)) != NULL) { if (idx == -1) tcent = t_getconflast(tc); else tcent = t_getconfbyindex(tc, idx); } if (idx <= 0 && tcent == NULL) { mytce.index = 0; mytce.modulus.data = (u_char *)wkmodulus; mytce.modulus.len = sizeof (wkmodulus); mytce.generator.data = (u_char *)"\002"; mytce.generator.len = 1; tcent = &mytce; } if (tcent == NULL) { (void) fprintf(stderr, "SRP modulus/generator %d not found\n", idx); exit(1); } if ((name = *argv) == NULL) { (void) printf("Client name: "); if (fgets(pname, sizeof (pname), stdin) == NULL) exit(1); if ((cp = strchr(pname, '\n')) != NULL) *cp = '\0'; name = pname; } for (;;) { if ((pass1 = getpassphrase("Pass phrase: ")) == NULL) exit(1); pass1 = strdup(pass1); if ((pass2 = getpassphrase("Re-enter phrase: ")) == NULL) exit(1); if (strcmp(pass1, pass2) == 0) break; free(pass1); (void) printf("Phrases don't match; try again.\n"); } memset(&pwval, 0, sizeof (pwval)); t_makepwent(&pwval, name, pass1, NULL, tcent); flags = 0; for (cp = name; *cp != '\0'; cp++) if (isspace(*cp)) flags |= HAS_SPACE; else if (*cp == '"') flags |= HAS_DQUOTE; else if (*cp == '\'') flags |= HAS_SQUOTE; else if (*cp == '\\') flags |= HAS_BACKSLASH; delimit = flags == 0 ? '\0' : (flags & HAS_DQUOTE) ? '\'' : '"'; if (delimit != '\0') (void) putchar(delimit); for (cp = name; *cp != '\0'; cp++) { if (*cp == delimit || *cp == '\\') (void) putchar('\\'); (void) putchar(*cp); } if (delimit != '\0') (void) putchar(delimit); (void) printf(" * %d:%s:%s *\n", pwval.pebuf.index, t_tob64(strbuf, (char *)pwval.pebuf.password.data, pwval.pebuf.password.len), t_tob64(saltbuf, (char *)pwval.pebuf.salt.data, pwval.pebuf.salt.len)); return 0; } ppp-2.5.0/pppd/ppp.pam0000644000175000017500000000026707536353376011525 00000000000000#%PAM-1.0 # Information for the PPPD process with the 'login' option. auth required pam_nologin.so auth required pam_unix.so account required pam_unix.so session required pam_unix.so ppp-2.5.0/pppd/plugins/0000755000175000017500000000000014412736275011755 500000000000000ppp-2.5.0/pppd/plugins/Makefile.am0000664000175000017500000000131414273050614013721 00000000000000pppd_plugin_LTLIBRARIES = minconn.la passprompt.la passwordfd.la winbind.la pppd_plugindir = $(PPPD_PLUGIN_DIR) PLUGIN_CPPFLAGS = -I${top_srcdir} PLUGIN_LDFLAGS = -module -avoid-version minconn_la_CPPFLAGS = $(PLUGIN_CPPFLAGS) minconn_la_LDFLAGS = $(PLUGIN_LDFLAGS) minconn_la_SOURCES = minconn.c passprompt_la_CPPFLAGS = $(PLUGIN_CPPFLAGS) passprompt_la_LDFLAGS = $(PLUGIN_LDFLAGS) passprompt_la_SOURCES = passprompt.c passwordfd_la_CPPFLAGS = $(PLUGIN_CPPFLAGS) passwordfd_la_LDFLAGS = $(PLUGIN_LDFLAGS) passwordfd_la_SOURCES = passwordfd.c winbind_la_CPPFLAGS = $(PLUGIN_CPPFLAGS) winbind_la_LDFLAGS = $(PLUGIN_LDFLAGS) winbind_la_SOURCES = winbind.c if !SUNOS SUBDIRS = pppoe pppoatm pppol2tp radius endif ppp-2.5.0/pppd/plugins/Makefile.in0000644000175000017500000010162014407475314013740 00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = pppd/plugins ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_atm.m4 \ $(top_srcdir)/m4/ax_check_openssl.m4 \ $(top_srcdir)/m4/ax_check_openssl_func.m4 \ $(top_srcdir)/m4/ax_check_pam.m4 \ $(top_srcdir)/m4/ax_check_pcap.m4 \ $(top_srcdir)/m4/ax_check_srp.m4 $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/pkg.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/pppd/config.h \ $(top_builddir)/pppd/pppdconf.h \ $(top_builddir)/pppd/plugins/pppoe/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(pppd_plugindir)" LTLIBRARIES = $(pppd_plugin_LTLIBRARIES) minconn_la_LIBADD = am_minconn_la_OBJECTS = minconn_la-minconn.lo minconn_la_OBJECTS = $(am_minconn_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = minconn_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(minconn_la_LDFLAGS) $(LDFLAGS) -o $@ passprompt_la_LIBADD = am_passprompt_la_OBJECTS = passprompt_la-passprompt.lo passprompt_la_OBJECTS = $(am_passprompt_la_OBJECTS) passprompt_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(passprompt_la_LDFLAGS) $(LDFLAGS) -o $@ passwordfd_la_LIBADD = am_passwordfd_la_OBJECTS = passwordfd_la-passwordfd.lo passwordfd_la_OBJECTS = $(am_passwordfd_la_OBJECTS) passwordfd_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(passwordfd_la_LDFLAGS) $(LDFLAGS) -o $@ winbind_la_LIBADD = am_winbind_la_OBJECTS = winbind_la-winbind.lo winbind_la_OBJECTS = $(am_winbind_la_OBJECTS) winbind_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(winbind_la_LDFLAGS) $(LDFLAGS) -o $@ AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/pppd -I$(top_builddir)/pppd/plugins/pppoe depcomp = $(SHELL) $(top_srcdir)/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/minconn_la-minconn.Plo \ ./$(DEPDIR)/passprompt_la-passprompt.Plo \ ./$(DEPDIR)/passwordfd_la-passwordfd.Plo \ ./$(DEPDIR)/winbind_la-winbind.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(minconn_la_SOURCES) $(passprompt_la_SOURCES) \ $(passwordfd_la_SOURCES) $(winbind_la_SOURCES) DIST_SOURCES = $(minconn_la_SOURCES) $(passprompt_la_SOURCES) \ $(passwordfd_la_SOURCES) $(winbind_la_SOURCES) RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir distdir-am am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` DIST_SUBDIRS = pppoe pppoatm pppol2tp radius am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ ATM_CFLAGS = @ATM_CFLAGS@ ATM_LDFLAGS = @ATM_LDFLAGS@ ATM_LIBS = @ATM_LIBS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CRYPT_LIBS = @CRYPT_LIBS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GREP = @GREP@ GTK_CFLAGS = @GTK_CFLAGS@ GTK_LIBS = @GTK_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_INCLUDES = @OPENSSL_INCLUDES@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAM_CFLAGS = @PAM_CFLAGS@ PAM_LDFLAGS = @PAM_LDFLAGS@ PAM_LIBS = @PAM_LIBS@ PATH_SEPARATOR = @PATH_SEPARATOR@ PCAP_CFLAGS = @PCAP_CFLAGS@ PCAP_LDFLAGS = @PCAP_LDFLAGS@ PCAP_LIBS = @PCAP_LIBS@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PPPD_LOGFILE_DIR = @PPPD_LOGFILE_DIR@ PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@ PPPD_RUNTIME_DIR = @PPPD_RUNTIME_DIR@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SRP_CFLAGS = @SRP_CFLAGS@ SRP_LDFLAGS = @SRP_LDFLAGS@ SRP_LIBS = @SRP_LIBS@ STRIP = @STRIP@ SYSTEMD_CFLAGS = @SYSTEMD_CFLAGS@ SYSTEMD_LIBS = @SYSTEMD_LIBS@ SYSTEM_CA_PATH = @SYSTEM_CA_PATH@ UTIL_LIBS = @UTIL_LIBS@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ pppd_plugin_LTLIBRARIES = minconn.la passprompt.la passwordfd.la winbind.la pppd_plugindir = $(PPPD_PLUGIN_DIR) PLUGIN_CPPFLAGS = -I${top_srcdir} PLUGIN_LDFLAGS = -module -avoid-version minconn_la_CPPFLAGS = $(PLUGIN_CPPFLAGS) minconn_la_LDFLAGS = $(PLUGIN_LDFLAGS) minconn_la_SOURCES = minconn.c passprompt_la_CPPFLAGS = $(PLUGIN_CPPFLAGS) passprompt_la_LDFLAGS = $(PLUGIN_LDFLAGS) passprompt_la_SOURCES = passprompt.c passwordfd_la_CPPFLAGS = $(PLUGIN_CPPFLAGS) passwordfd_la_LDFLAGS = $(PLUGIN_LDFLAGS) passwordfd_la_SOURCES = passwordfd.c winbind_la_CPPFLAGS = $(PLUGIN_CPPFLAGS) winbind_la_LDFLAGS = $(PLUGIN_LDFLAGS) winbind_la_SOURCES = winbind.c @SUNOS_FALSE@SUBDIRS = pppoe pppoatm pppol2tp radius all: all-recursive .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu pppd/plugins/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu pppd/plugins/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-pppd_pluginLTLIBRARIES: $(pppd_plugin_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(pppd_plugin_LTLIBRARIES)'; test -n "$(pppd_plugindir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(pppd_plugindir)'"; \ $(MKDIR_P) "$(DESTDIR)$(pppd_plugindir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(pppd_plugindir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(pppd_plugindir)"; \ } uninstall-pppd_pluginLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(pppd_plugin_LTLIBRARIES)'; test -n "$(pppd_plugindir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(pppd_plugindir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(pppd_plugindir)/$$f"; \ done clean-pppd_pluginLTLIBRARIES: -test -z "$(pppd_plugin_LTLIBRARIES)" || rm -f $(pppd_plugin_LTLIBRARIES) @list='$(pppd_plugin_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } minconn.la: $(minconn_la_OBJECTS) $(minconn_la_DEPENDENCIES) $(EXTRA_minconn_la_DEPENDENCIES) $(AM_V_CCLD)$(minconn_la_LINK) -rpath $(pppd_plugindir) $(minconn_la_OBJECTS) $(minconn_la_LIBADD) $(LIBS) passprompt.la: $(passprompt_la_OBJECTS) $(passprompt_la_DEPENDENCIES) $(EXTRA_passprompt_la_DEPENDENCIES) $(AM_V_CCLD)$(passprompt_la_LINK) -rpath $(pppd_plugindir) $(passprompt_la_OBJECTS) $(passprompt_la_LIBADD) $(LIBS) passwordfd.la: $(passwordfd_la_OBJECTS) $(passwordfd_la_DEPENDENCIES) $(EXTRA_passwordfd_la_DEPENDENCIES) $(AM_V_CCLD)$(passwordfd_la_LINK) -rpath $(pppd_plugindir) $(passwordfd_la_OBJECTS) $(passwordfd_la_LIBADD) $(LIBS) winbind.la: $(winbind_la_OBJECTS) $(winbind_la_DEPENDENCIES) $(EXTRA_winbind_la_DEPENDENCIES) $(AM_V_CCLD)$(winbind_la_LINK) -rpath $(pppd_plugindir) $(winbind_la_OBJECTS) $(winbind_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/minconn_la-minconn.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/passprompt_la-passprompt.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/passwordfd_la-passwordfd.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/winbind_la-winbind.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< minconn_la-minconn.lo: minconn.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(minconn_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT minconn_la-minconn.lo -MD -MP -MF $(DEPDIR)/minconn_la-minconn.Tpo -c -o minconn_la-minconn.lo `test -f 'minconn.c' || echo '$(srcdir)/'`minconn.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/minconn_la-minconn.Tpo $(DEPDIR)/minconn_la-minconn.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='minconn.c' object='minconn_la-minconn.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(minconn_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o minconn_la-minconn.lo `test -f 'minconn.c' || echo '$(srcdir)/'`minconn.c passprompt_la-passprompt.lo: passprompt.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(passprompt_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT passprompt_la-passprompt.lo -MD -MP -MF $(DEPDIR)/passprompt_la-passprompt.Tpo -c -o passprompt_la-passprompt.lo `test -f 'passprompt.c' || echo '$(srcdir)/'`passprompt.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/passprompt_la-passprompt.Tpo $(DEPDIR)/passprompt_la-passprompt.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='passprompt.c' object='passprompt_la-passprompt.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(passprompt_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o passprompt_la-passprompt.lo `test -f 'passprompt.c' || echo '$(srcdir)/'`passprompt.c passwordfd_la-passwordfd.lo: passwordfd.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(passwordfd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT passwordfd_la-passwordfd.lo -MD -MP -MF $(DEPDIR)/passwordfd_la-passwordfd.Tpo -c -o passwordfd_la-passwordfd.lo `test -f 'passwordfd.c' || echo '$(srcdir)/'`passwordfd.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/passwordfd_la-passwordfd.Tpo $(DEPDIR)/passwordfd_la-passwordfd.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='passwordfd.c' object='passwordfd_la-passwordfd.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(passwordfd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o passwordfd_la-passwordfd.lo `test -f 'passwordfd.c' || echo '$(srcdir)/'`passwordfd.c winbind_la-winbind.lo: winbind.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(winbind_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT winbind_la-winbind.lo -MD -MP -MF $(DEPDIR)/winbind_la-winbind.Tpo -c -o winbind_la-winbind.lo `test -f 'winbind.c' || echo '$(srcdir)/'`winbind.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/winbind_la-winbind.Tpo $(DEPDIR)/winbind_la-winbind.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='winbind.c' object='winbind_la-winbind.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(winbind_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o winbind_la-winbind.lo `test -f 'winbind.c' || echo '$(srcdir)/'`winbind.c mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile $(LTLIBRARIES) installdirs: installdirs-recursive installdirs-am: for dir in "$(DESTDIR)$(pppd_plugindir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool clean-pppd_pluginLTLIBRARIES \ mostlyclean-am distclean: distclean-recursive -rm -f ./$(DEPDIR)/minconn_la-minconn.Plo -rm -f ./$(DEPDIR)/passprompt_la-passprompt.Plo -rm -f ./$(DEPDIR)/passwordfd_la-passwordfd.Plo -rm -f ./$(DEPDIR)/winbind_la-winbind.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-pppd_pluginLTLIBRARIES install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f ./$(DEPDIR)/minconn_la-minconn.Plo -rm -f ./$(DEPDIR)/passprompt_la-passprompt.Plo -rm -f ./$(DEPDIR)/passwordfd_la-passwordfd.Plo -rm -f ./$(DEPDIR)/winbind_la-winbind.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: uninstall-pppd_pluginLTLIBRARIES .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \ am--depfiles check check-am clean clean-generic clean-libtool \ clean-pppd_pluginLTLIBRARIES cscopelist-am ctags ctags-am \ distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-pppd_pluginLTLIBRARIES install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ installdirs-am maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am uninstall-pppd_pluginLTLIBRARIES .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: ppp-2.5.0/pppd/plugins/minconn.c0000644000175000017500000000444314353435407013504 00000000000000/* * minconn.c - pppd plugin to implement a `minconnect' option. * * Copyright (c) 1999 Paul Mackerras. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The name(s) of the authors of this software must not be used to * endorse or promote products derived from this software without * prior written permission. * * 4. Redistributions of any form whatsoever must retain the following * acknowledgment: * "This product includes software developed by Paul Mackerras * ". * * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include #include #include #include #include #include #include #include #if !defined(SOL2) #include #else #include #endif char pppd_version[] = PPPD_VERSION; static int minconnect = 0; static struct option my_options[] = { { "minconnect", o_int, &minconnect, "Set minimum connect time before idle timeout applies" }, { NULL } }; static int my_get_idle(struct ppp_idle *idle) { time_t t; if (idle == NULL) return minconnect ? minconnect: ppp_get_max_idle_time(); t = idle->xmit_idle; if (idle->recv_idle < t) t = idle->recv_idle; return ppp_get_max_idle_time() - t; } void plugin_init(void) { info("plugin_init"); ppp_add_options(my_options); idle_time_hook = my_get_idle; } ppp-2.5.0/pppd/plugins/passprompt.c0000644000175000017500000000616314353435407014254 00000000000000/* * passprompt.c - pppd plugin to invoke an external PAP password prompter * * Copyright 1999 Paul Mackerras, Alan Curry. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include char pppd_version[] = PPPD_VERSION; static char promptprog[PATH_MAX+1]; static int promptprog_refused = 0; static struct option options[] = { { "promptprog", o_string, promptprog, "External PAP password prompting program", OPT_STATIC, NULL, PATH_MAX }, { NULL } }; static int promptpass(char *user, char *passwd) { int p[2]; pid_t kid; int readgood, wstat, ret; ssize_t red; if (promptprog_refused || promptprog[0] == 0 || access(promptprog, X_OK) < 0) return -1; /* sorry, can't help */ if (!passwd) return 1; if (pipe(p)) { warn("Can't make a pipe for %s", promptprog); return 0; } if ((kid = fork()) == (pid_t) -1) { warn("Can't fork to run %s", promptprog); close(p[0]); close(p[1]); return 0; } if (!kid) { /* we are the child, exec the program */ char *argv[5], fdstr[32]; ppp_sys_close(); closelog(); close(p[0]); ret = seteuid(getuid()); if (ret != 0) { warn("Couldn't set effective user id"); } ret = setegid(getgid()); if (ret != 0) { warn("Couldn't set effective user id"); } sprintf(fdstr, "%d", p[1]); argv[0] = promptprog; argv[1] = strdup(user); argv[2] = strdup(ppp_remote_name()); argv[3] = fdstr; argv[4] = 0; execv(*argv, argv); _exit(127); } /* we are the parent, read the password from the pipe */ close(p[1]); readgood = 0; do { red = read(p[0], passwd + readgood, MAXSECRETLEN-1 - readgood); if (red == 0) break; if (red < 0) { if (errno == EINTR && !ppp_signaled(SIGTERM)) continue; error("Can't read secret from %s: %m", promptprog); readgood = -1; break; } readgood += red; } while (readgood < MAXSECRETLEN - 1); close(p[0]); /* now wait for child to exit */ while (waitpid(kid, &wstat, 0) < 0) { if (errno != EINTR || ppp_signaled(SIGTERM)) { warn("error waiting for %s: %m", promptprog); break; } } if (readgood < 0) return 0; passwd[readgood] = 0; if (!WIFEXITED(wstat)) warn("%s terminated abnormally", promptprog); if (WEXITSTATUS(wstat)) { warn("%s exited with code %d", promptprog, WEXITSTATUS(wstat)); /* code when cancel was hit in the prompt prog */ if (WEXITSTATUS(wstat) == 128) { promptprog_refused = 1; } return -1; } return 1; } void plugin_init(void) { ppp_add_options(options); pap_passwd_hook = promptpass; #ifdef PPP_WITH_EAPTLS eaptls_passwd_hook = promptpass; #endif } ppp-2.5.0/pppd/plugins/passwordfd.c0000644000175000017500000000326214353435407014215 00000000000000 /* * Author: Arvin Schnell * * This plugin let's you pass the password to the pppd via * a file descriptor. That's easy and secure - no fiddling * with pap- and chap-secrets files. */ #include #include #include #include #include #include #include #include #include #include #include #include #include char pppd_version[] = PPPD_VERSION; static int passwdfd = -1; static char save_passwd[MAXSECRETLEN]; static struct option options[] = { { "passwordfd", o_int, &passwdfd, "Receive password on this file descriptor" }, { NULL } }; static int pwfd_check (void) { return 1; } static int pwfd_passwd (char *user, char *passwd) { int readgood, red; if (passwdfd == -1) return -1; if (passwd == NULL) return 1; if (passwdfd == -2) { strcpy (passwd, save_passwd); return 1; } readgood = 0; do { red = read (passwdfd, passwd + readgood, MAXSECRETLEN - 1 - readgood); if (red == 0) break; if (red < 0) { error ("Can't read secret from fd\n"); readgood = -1; break; } readgood += red; } while (readgood < MAXSECRETLEN - 1); close (passwdfd); if (readgood < 0) return 0; passwd[readgood] = 0; strcpy (save_passwd, passwd); passwdfd = -2; return 1; } void plugin_init (void) { ppp_add_options (options); pap_check_hook = pwfd_check; pap_passwd_hook = pwfd_passwd; chap_check_hook = pwfd_check; chap_passwd_hook = pwfd_passwd; #ifdef PPP_WITH_EAPTLS eaptls_passwd_hook = pwfd_passwd; #endif } ppp-2.5.0/pppd/plugins/winbind.c0000644000175000017500000004321214353435407013472 00000000000000/*********************************************************************** * * winbind.c * * WINBIND plugin for pppd. Performs PAP, CHAP, MS-CHAP, MS-CHAPv2 * authentication using WINBIND to contact a NT-style PDC. * * Based on the structure of the radius module. * * Copyright (C) 2003 Andrew Bartlet * * Copyright 1999 Paul Mackerras, Alan Curry. * (pipe read code from passpromt.c) * * Copyright (C) 2002 Roaring Penguin Software Inc. * * Based on a patch for ipppd, which is: * Copyright (C) 1996, Matjaz Godec * Copyright (C) 1996, Lars Fenneberg * Copyright (C) 1997, Miguel A.L. Paraz * * Uses radiusclient library, which is: * Copyright (C) 1995,1996,1997,1998 Lars Fenneberg * Copyright (C) 2002 Roaring Penguin Software Inc. * * MPPE support is by Ralf Hofmann, , with * modification from Frank Cusack, . * * Updated on 2003-12-12 to support updated PPP plugin API from latest CVS * Copyright (C) 2003, Sean E. Millichamp * * This plugin may be distributed according to the terms of the GNU * General Public License, version 2 or (at your option) any later version. * ***********************************************************************/ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define BUF_LEN 1024 #define NOT_AUTHENTICATED 0 #define AUTHENTICATED 1 static char *ntlm_auth = NULL; static int set_ntlm_auth(char **argv) { char *p; p = argv[0]; if (p[0] != '/') { ppp_option_error("ntlm_auth-helper argument must be full path"); return 0; } p = strdup(p); if (p == NULL) { novm("ntlm_auth-helper argument"); return 0; } if (ntlm_auth != NULL) free(ntlm_auth); ntlm_auth = p; return 1; } static struct option Options[] = { { "ntlm_auth-helper", o_special, (void *) &set_ntlm_auth, "Path to ntlm_auth executable", OPT_PRIV }, { NULL } }; static pap_check_hook_fn winbind_secret_check; static pap_auth_hook_fn winbind_pap_auth; static chap_verify_hook_fn winbind_chap_verify; static int winbind_allowed_address(uint32_t addr); char pppd_version[] = PPPD_VERSION; /********************************************************************** * %FUNCTION: plugin_init * %ARGUMENTS: * None * %RETURNS: * Nothing * %DESCRIPTION: * Initializes WINBIND plugin. ***********************************************************************/ void plugin_init(void) { pap_check_hook = winbind_secret_check; pap_auth_hook = winbind_pap_auth; chap_check_hook = winbind_secret_check; chap_verify_hook = winbind_chap_verify; allowed_address_hook = winbind_allowed_address; /* Don't ask the peer for anything other than MS-CHAP or MS-CHAP V2 */ chap_mdtype_all &= (MDTYPE_MICROSOFT_V2 | MDTYPE_MICROSOFT); ppp_add_options(Options); info("WINBIND plugin initialized."); } /** Routine to get hex characters and turn them into a 16 byte array. the array can be variable length, and any non-hex-numeric characters are skipped. "0xnn" or "0Xnn" is specially catered for. valid examples: "0A5D15"; "0x15, 0x49, 0xa2"; "59\ta9\te3\n" **/ /* Unix SMB/CIFS implementation. Samba utility functions Copyright (C) Andrew Tridgell 1992-2001 Copyright (C) Simo Sorce 2001-2002 Copyright (C) Martin Pool 2003 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ size_t strhex_to_str(unsigned char *p, size_t len, const char *strhex) { size_t i; size_t num_chars = 0; unsigned char lonybble, hinybble; const char *hexchars = "0123456789ABCDEF"; char *p1 = NULL, *p2 = NULL; for (i = 0; i < len && strhex[i] != 0; i++) { if (strncmp(hexchars, "0x", 2) == 0) { i++; /* skip two chars */ continue; } if (!(p1 = strchr(hexchars, toupper(strhex[i])))) break; i++; /* next hex digit */ if (!(p2 = strchr(hexchars, toupper(strhex[i])))) break; /* get the two nybbles */ hinybble = (p1 - hexchars); lonybble = (p2 - hexchars); p[num_chars] = (hinybble << 4) | lonybble; num_chars++; p1 = NULL; p2 = NULL; } return num_chars; } static const char *b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; /** * Encode a base64 string into a malloc()ed string caller to free. * *From SQUID: adopted from http://ftp.sunet.se/pub2/gnu/vm/base64-encode.c with adjustments **/ char * base64_encode(const char *data) { size_t out_cnt = 0; size_t len = strlen(data); size_t output_len = 4 * ((len + 2) / 3) + 2; const unsigned char *ptr = (const unsigned char *) data; char *result = malloc(output_len); /* get us plenty of space */ unsigned int bits; for (; len >= 3; len -= 3) { bits = (ptr[0] << 16) + (ptr[1] << 8) + ptr[2]; ptr += 3; result[out_cnt++] = b64[bits >> 18]; result[out_cnt++] = b64[(bits >> 12) & 0x3f]; result[out_cnt++] = b64[(bits >> 6) & 0x3f]; result[out_cnt++] = b64[bits & 0x3f]; } if (len != 0) { bits = ptr[0] << 16; if (len > 1) bits |= ptr[1] << 8; result[out_cnt++] = b64[bits >> 18]; result[out_cnt++] = b64[(bits >> 12) & 0x3f]; result[out_cnt++] = (len > 1)? b64[(bits >> 6) & 0x3f]: '='; result[out_cnt++] = '='; } result[out_cnt] = '\0'; /* terminate */ return result; } unsigned int run_ntlm_auth(const char *username, const char *domain, const char *full_username, const char *plaintext_password, const u_char *challenge, size_t challenge_length, const u_char *lm_response, size_t lm_response_length, const u_char *nt_response, size_t nt_response_length, u_char nt_key[16], char **error_string) { pid_t forkret; int child_in[2]; int child_out[2]; int status; int authenticated = NOT_AUTHENTICATED; /* not auth */ int got_user_session_key = 0; /* not got key */ char buffer[1024]; FILE *pipe_in; FILE *pipe_out; int i; char *challenge_hex; char *lm_hex_hash; char *nt_hex_hash; /* First see if we have a program to run... */ if (ntlm_auth == NULL) return NOT_AUTHENTICATED; /* Make first child */ if (pipe(child_out) == -1) { error("pipe creation failed for child OUT!"); return NOT_AUTHENTICATED; } if (pipe(child_in) == -1) { error("pipe creation failed for child IN!"); return NOT_AUTHENTICATED; } forkret = ppp_safe_fork(child_in[0], child_out[1], 2); if (forkret == -1) { if (error_string) { *error_string = strdup("fork failed!"); } return NOT_AUTHENTICATED; } if (forkret == 0) { /* child process */ uid_t uid; gid_t gid; close(child_out[0]); close(child_in[1]); /* run winbind as the user that invoked pppd */ gid = getgid(); if (setgid(gid) == -1 || getgid() != gid) { fatal("pppd/winbind: could not setgid to %d: %m", gid); } uid = getuid(); if (setuid(uid) == -1 || getuid() != uid) { fatal("pppd/winbind: could not setuid to %d: %m", uid); } execl("/bin/sh", "sh", "-c", ntlm_auth, NULL); fatal("pppd/winbind: could not exec /bin/sh: %m"); } /* parent */ close(child_out[1]); close(child_in[0]); /* Need to write the User's info onto the pipe */ pipe_in = fdopen(child_in[1], "w"); pipe_out = fdopen(child_out[0], "r"); /* look for session key coming back */ if (username) { char *b64_username = base64_encode(username); fprintf(pipe_in, "Username:: %s\n", b64_username); free(b64_username); } if (domain) { char *b64_domain = base64_encode(domain); fprintf(pipe_in, "NT-Domain:: %s\n", b64_domain); free(b64_domain); } if (full_username) { char *b64_full_username = base64_encode(full_username); fprintf(pipe_in, "Full-Username:: %s\n", b64_full_username); free(b64_full_username); } if (plaintext_password) { char *b64_plaintext_password = base64_encode(plaintext_password); fprintf(pipe_in, "Password:: %s\n", b64_plaintext_password); free(b64_plaintext_password); } if (challenge_length) { fprintf(pipe_in, "Request-User-Session-Key: yes\n"); challenge_hex = malloc(challenge_length*2+1); for (i = 0; i < challenge_length; i++) sprintf(challenge_hex + i * 2, "%02X", challenge[i]); fprintf(pipe_in, "LANMAN-Challenge: %s\n", challenge_hex); free(challenge_hex); } if (lm_response_length) { lm_hex_hash = malloc(lm_response_length*2+1); for (i = 0; i < lm_response_length; i++) sprintf(lm_hex_hash + i * 2, "%02X", lm_response[i]); fprintf(pipe_in, "LANMAN-response: %s\n", lm_hex_hash); free(lm_hex_hash); } if (nt_response_length) { nt_hex_hash = malloc(nt_response_length*2+1); for (i = 0; i < nt_response_length; i++) sprintf(nt_hex_hash + i * 2, "%02X", nt_response[i]); fprintf(pipe_in, "NT-response: %s\n", nt_hex_hash); free(nt_hex_hash); } fprintf(pipe_in, ".\n"); fflush(pipe_in); while (fgets(buffer, sizeof(buffer)-1, pipe_out) != NULL) { char *message, *parameter; if (buffer[strlen(buffer)-1] != '\n') { break; } buffer[strlen(buffer)-1] = '\0'; message = buffer; if (!(parameter = strstr(buffer, ": "))) { break; } parameter[0] = '\0'; parameter++; parameter[0] = '\0'; parameter++; if (strcmp(message, ".") == 0) { /* end of sequence */ break; } else if (strcasecmp(message, "Authenticated") == 0) { if (strcasecmp(parameter, "Yes") == 0) { authenticated = AUTHENTICATED; } else { notice("Winbind has declined authentication for user!"); authenticated = NOT_AUTHENTICATED; } } else if (strcasecmp(message, "User-session-key") == 0) { /* length is the number of characters to parse */ if (nt_key) { if (strhex_to_str(nt_key, 32, parameter) == 16) { got_user_session_key = 1; } else { notice("NT session key for user was not 16 bytes!"); } } } else if (strcasecmp(message, "Error") == 0) { authenticated = NOT_AUTHENTICATED; if (error_string) *error_string = strdup(parameter); } else if (strcasecmp(message, "Authentication-Error") == 0) { authenticated = NOT_AUTHENTICATED; if (error_string) *error_string = strdup(parameter); } else { notice("unrecognised input from ntlm_auth helper - %s: %s", message, parameter); } } /* parent */ if (close(child_out[0]) == -1) { close(child_in[1]); notice("error closing pipe?!? for child OUT[0]"); return NOT_AUTHENTICATED; } /* parent */ if (close(child_in[1]) == -1) { notice("error closing pipe?!? for child IN[1]"); return NOT_AUTHENTICATED; } while ((wait(&status) == -1) && errno == EINTR && !ppp_signaled(SIGTERM)) ; if ((authenticated == AUTHENTICATED) && nt_key && !got_user_session_key) { notice("Did not get user session key, despite being authenticated!"); return NOT_AUTHENTICATED; } return authenticated; } /********************************************************************** * %FUNCTION: winbind_secret_check * %ARGUMENTS: * None * %RETURNS: * 0 if we don't have an ntlm_auth program to run, otherwise 1. * %DESCRIPTION: * Tells pppd that we will try to authenticate the peer, and not to * worry about looking in /etc/ppp/ *-secrets ***********************************************************************/ static int winbind_secret_check(void) { return ntlm_auth != NULL; } /********************************************************************** * %FUNCTION: winbind_pap_auth * %ARGUMENTS: * user -- user-name of peer * passwd -- password supplied by peer * msgp -- Message which will be sent in PAP response * paddrs -- set to a list of possible peer IP addresses * popts -- set to a list of additional pppd options * %RETURNS: * 1 if we can authenticate, -1 if we cannot. * %DESCRIPTION: * Performs PAP authentication using WINBIND ***********************************************************************/ static int winbind_pap_auth(char *user, char *password, char **msgp, struct wordlist **paddrs, struct wordlist **popts) { if (run_ntlm_auth(NULL, NULL, user, password, NULL, 0, NULL, 0, NULL, 0, NULL, msgp) == AUTHENTICATED) { return 1; } return -1; } /********************************************************************** * %FUNCTION: winbind_chap_auth * %ARGUMENTS: * user -- user-name of peer * remmd -- hash received from peer * remmd_len -- length of remmd * cstate -- pppd's chap_state structure * %RETURNS: * AUTHENTICATED (1) if we can authenticate, NOT_AUTHENTICATED (0) if we cannot. * %DESCRIPTION: * Performs MS-CHAP and MS-CHAPv2 authentication using WINBIND. ***********************************************************************/ static int winbind_chap_verify(char *user, char *ourname, int id, struct chap_digest_type *digest, unsigned char *challenge, unsigned char *response, char *message, int message_space) { int challenge_len, response_len; char domainname[256]; char *domain; const char *username; char *p; unsigned char saresponse[MS_AUTH_RESPONSE_LENGTH+1]; /* The first byte of each of these strings contains their length */ challenge_len = *challenge++; response_len = *response++; /* remove domain from "domain\username" */ if ((username = strrchr(user, '\\')) != NULL) ++username; else username = user; strlcpy(domainname, user, sizeof(domainname)); /* remove domain from "domain\username" */ if ((p = strrchr(domainname, '\\')) != NULL) { *p = '\0'; domain = domainname; } else { domain = NULL; } /* generate MD based on negotiated type */ switch (digest->code) { case CHAP_MICROSOFT: { char *error_string = NULL; u_char *nt_response = NULL; u_char *lm_response = NULL; int nt_response_size = 0; int lm_response_size = 0; u_char session_key[MD4_DIGEST_LENGTH]; if (response_len != MS_CHAP_RESPONSE_LEN) break; /* not even the right length */ /* Determine which part of response to verify against */ if (response[MS_CHAP_USENT]) { nt_response = &response[MS_CHAP_NTRESP]; nt_response_size = MS_CHAP_NTRESP_LEN; } else { #ifdef PPP_WITH_MSLANMAN lm_response = &response[MS_CHAP_LANMANRESP]; lm_response_size = MS_CHAP_LANMANRESP_LEN; #else /* Should really propagate this into the error packet. */ notice("Peer request for LANMAN auth not supported"); return NOT_AUTHENTICATED; #endif /* PPP_WITH_MSLANMAN */ } /* ship off to winbind, and check */ if (run_ntlm_auth(username, domain, NULL, NULL, challenge, challenge_len, lm_response, lm_response_size, nt_response, nt_response_size, session_key, &error_string) == AUTHENTICATED) { #ifdef PPP_WITH_MPPE mppe_set_chapv1(challenge, session_key); #endif slprintf(message, message_space, "Access granted"); return AUTHENTICATED; } else { if (error_string) { notice(error_string); free(error_string); } slprintf(message, message_space, "E=691 R=1 C=%0.*B V=0", challenge_len, challenge); return NOT_AUTHENTICATED; } break; } case CHAP_MICROSOFT_V2: { u_char Challenge[8]; u_char session_key[MD4_DIGEST_LENGTH]; char *error_string = NULL; if (response_len != MS_CHAP2_RESPONSE_LEN) break; /* not even the right length */ ChallengeHash(&response[MS_CHAP2_PEER_CHALLENGE], challenge, user, Challenge); /* ship off to winbind, and check */ if (run_ntlm_auth(username, domain, NULL, NULL, Challenge, 8, NULL, 0, &response[MS_CHAP2_NTRESP], MS_CHAP2_NTRESP_LEN, session_key, &error_string) == AUTHENTICATED) { GenerateAuthenticatorResponse(session_key, &response[MS_CHAP2_NTRESP], &response[MS_CHAP2_PEER_CHALLENGE], challenge, user, saresponse); #ifdef PPP_WITH_MPPE mppe_set_chapv2(session_key, &response[MS_CHAP2_NTRESP], MS_CHAP2_AUTHENTICATOR); #endif if (response[MS_CHAP2_FLAGS]) { slprintf(message, message_space, "S=%s", saresponse); } else { slprintf(message, message_space, "S=%s M=%s", saresponse, "Access granted"); } return AUTHENTICATED; } else { if (error_string) { notice(error_string); slprintf(message, message_space, "E=691 R=1 C=%0.*B V=0 M=%s", challenge_len, challenge, error_string); free(error_string); } else { slprintf(message, message_space, "E=691 R=1 C=%0.*B V=0 M=%s", challenge_len, challenge, "Access denied"); } return NOT_AUTHENTICATED; } break; } default: error("WINBIND: Challenge type %u unsupported", digest->code); } return NOT_AUTHENTICATED; } static int winbind_allowed_address(uint32_t addr) { ipcp_options *wo = &ipcp_wantoptions[0]; if (wo->hisaddr !=0 && wo->hisaddr == addr) { return 1; } return -1; } ppp-2.5.0/pppd/plugins/pppoe/0000755000175000017500000000000014412736275013100 500000000000000ppp-2.5.0/pppd/plugins/pppoe/Makefile.am0000644000175000017500000000071214353435407015051 00000000000000pppd_plugin_LTLIBRARIES = pppoe.la pppd_plugindir = $(PPPD_PLUGIN_DIR) sbin_PROGRAMS = pppoe-discovery dist_man8_MANS = pppoe-discovery.8 noinst_HEADERS = \ pppoe.h pppoe_la_CPPFLAGS = -I${top_srcdir} -DSYSCONFDIR=\"${sysconfdir}\" -DPLUGIN pppoe_la_LDFLAGS = -module -avoid-version pppoe_la_SOURCES = plugin.c discovery.c if.c common.c pppoe_discovery_CPPFLAGS = -I${top_srcdir} pppoe_discovery_SOURCES = pppoe-discovery.c discovery.c if.c common.c ppp-2.5.0/pppd/plugins/pppoe/pppoe.h0000644000175000017500000002376214353435407014323 00000000000000/*********************************************************************** * * pppoe.h * * Declaration of various PPPoE constants * * Copyright (C) 2000 Roaring Penguin Software Inc. * * This program may be distributed according to the terms of the GNU * General Public License, version 2 or (at your option) any later version. * * $Id: pppoe.h,v 1.4 2008/06/15 04:35:50 paulus Exp $ * ***********************************************************************/ #include /* For FILE */ #include /* For pid_t */ #include #include #include /* For error */ /* How do we access raw Ethernet devices? */ #undef USE_LINUX_PACKET #undef USE_BPF #if defined(HAVE_NETPACKET_PACKET_H) || defined(HAVE_LINUX_IF_PACKET_H) #define USE_LINUX_PACKET 1 #elif defined(HAVE_SYS_DLPI_H) #define USE_DLPI #elif defined(HAVE_NET_BPF_H) #define USE_BPF 1 #endif /* Sanity check */ #if !defined(USE_BPF) && !defined(USE_LINUX_PACKET) && !defined(USE_DLPI) #error Unknown method for accessing raw Ethernet frames #endif #ifdef HAVE_SYS_SOCKET_H #include #endif /* This has to be included before Linux 4.8's linux/in.h * gets dragged in. */ #include /* Ugly header files on some Linux boxes... */ #if defined(HAVE_LINUX_IF_H) #include #elif defined(HAVE_NET_IF_H) #include #endif #ifdef HAVE_NET_IF_TYPES_H #include #endif #define BPF_BUFFER_IS_EMPTY 1 #define BPF_BUFFER_HAS_DATA 0 /* Define various integer types -- assumes a char is 8 bits */ #if SIZEOF_UNSIGNED_SHORT == 2 typedef unsigned short UINT16_t; #elif SIZEOF_UNSIGNED_INT == 2 typedef unsigned int UINT16_t; #else #error Could not find a 16-bit integer type #endif #if SIZEOF_UNSIGNED_SHORT == 4 typedef unsigned short UINT32_t; #elif SIZEOF_UNSIGNED_INT == 4 typedef unsigned int UINT32_t; #elif SIZEOF_UNSIGNED_LONG == 4 typedef unsigned long UINT32_t; #else #error Could not find a 32-bit integer type #endif #ifdef HAVE_LINUX_IF_ETHER_H #include #else #ifdef HAVE_NETINET_IF_ETHER_H #include #ifdef HAVE_SYS_SOCKET_H #include #endif #ifndef HAVE_SYS_DLPI_H #include #endif #endif #endif /* Ethernet frame types according to RFC 2516 */ #define ETH_PPPOE_DISCOVERY 0x8863 #define ETH_PPPOE_SESSION 0x8864 /* But some brain-dead peers disobey the RFC, so frame types are variables */ extern UINT16_t Eth_PPPOE_Discovery; extern UINT16_t Eth_PPPOE_Session; /* PPPoE codes */ #define CODE_PADI 0x09 #define CODE_PADO 0x07 #define CODE_PADR 0x19 #define CODE_PADS 0x65 #define CODE_PADT 0xA7 /* Extensions from draft-carrel-info-pppoe-ext-00 */ /* I do NOT like PADM or PADN, but they are here for completeness */ #define CODE_PADM 0xD3 #define CODE_PADN 0xD4 #define CODE_SESS 0x00 /* PPPoE Tags */ #define TAG_END_OF_LIST 0x0000 #define TAG_SERVICE_NAME 0x0101 #define TAG_AC_NAME 0x0102 #define TAG_HOST_UNIQ 0x0103 #define TAG_AC_COOKIE 0x0104 #define TAG_VENDOR_SPECIFIC 0x0105 #define TAG_RELAY_SESSION_ID 0x0110 #define TAG_PPP_MAX_PAYLOAD 0x0120 #define TAG_SERVICE_NAME_ERROR 0x0201 #define TAG_AC_SYSTEM_ERROR 0x0202 #define TAG_GENERIC_ERROR 0x0203 /* Extensions from draft-carrel-info-pppoe-ext-00 */ /* I do NOT like these tags one little bit */ #define TAG_HURL 0x111 #define TAG_MOTM 0x112 #define TAG_IP_ROUTE_ADD 0x121 /* Discovery phase states */ #define STATE_SENT_PADI 0 #define STATE_RECEIVED_PADO 1 #define STATE_SENT_PADR 2 #define STATE_SESSION 3 #define STATE_TERMINATED 4 /* How many PADI/PADS attempts? */ #define MAX_PADI_ATTEMPTS 3 /* Initial timeout for PADO/PADS */ #define PADI_TIMEOUT 5 /* States for scanning PPP frames */ #define STATE_WAITFOR_FRAME_ADDR 0 #define STATE_DROP_PROTO 1 #define STATE_BUILDING_PACKET 2 /* Special PPP frame characters */ #define FRAME_ESC 0x7D #define FRAME_FLAG 0x7E #define FRAME_ADDR 0xFF #define FRAME_CTRL 0x03 #define FRAME_ENC 0x20 #define IPV4ALEN 4 #define SMALLBUF 256 /* There are other fixed-size buffers preventing this from being increased to 16110. The buffer sizes would need to be properly de-coupled from the default MRU. For now, getting up to 1500 is enough. */ #define ETH_JUMBO_LEN 1508 /* A PPPoE Packet, including Ethernet headers */ typedef struct PPPoEPacketStruct { struct ethhdr ethHdr; /* Ethernet header */ unsigned int vertype:8; /* PPPoE Version and Type (must both be 1) */ unsigned int code:8; /* PPPoE code */ unsigned int session:16; /* PPPoE session */ unsigned int length:16; /* Payload length */ unsigned char payload[ETH_JUMBO_LEN]; /* A bit of room to spare */ } PPPoEPacket; #define PPPOE_VER(vt) ((vt) >> 4) #define PPPOE_TYPE(vt) ((vt) & 0xf) #define PPPOE_VER_TYPE(v, t) (((v) << 4) | (t)) /* Header size of a PPPoE packet */ #define PPPOE_OVERHEAD 6 /* type, code, session, length */ #define HDR_SIZE (sizeof(struct ethhdr) + PPPOE_OVERHEAD) #define MAX_PPPOE_PAYLOAD (ETH_JUMBO_LEN - PPPOE_OVERHEAD) #define PPP_OVERHEAD 2 /* protocol */ #define MAX_PPPOE_MTU (MAX_PPPOE_PAYLOAD - PPP_OVERHEAD) #define TOTAL_OVERHEAD (PPPOE_OVERHEAD + PPP_OVERHEAD) #define ETH_PPPOE_MTU (ETH_DATA_LEN - TOTAL_OVERHEAD) /* PPPoE Tag */ typedef struct PPPoETagStruct { unsigned int type:16; /* tag type */ unsigned int length:16; /* Length of payload */ unsigned char payload[ETH_JUMBO_LEN]; /* A LOT of room to spare */ } PPPoETag; /* Header size of a PPPoE tag */ #define TAG_HDR_SIZE 4 /* Chunk to read from stdin */ #define READ_CHUNK 4096 /* Function passed to parsePacket */ typedef void ParseFunc(UINT16_t type, UINT16_t len, unsigned char *data, void *extra); #define PPPINITFCS16 0xffff /* Initial FCS value */ /* Keep track of the state of a connection -- collect everything in one spot */ typedef struct PPPoEConnectionStruct { int discoveryState; /* Where we are in discovery */ int discoverySocket; /* Raw socket for discovery frames */ int sessionSocket; /* Raw socket for session frames */ unsigned char myEth[ETH_ALEN]; /* My MAC address */ unsigned char peerEth[ETH_ALEN]; /* Peer's MAC address */ unsigned char req_peer_mac[ETH_ALEN]; /* required peer MAC address */ unsigned char req_peer; /* require mac addr to match req_peer_mac */ UINT16_t session; /* Session ID */ char *ifName; /* Interface name */ char *serviceName; /* Desired service name, if any */ char *acName; /* Desired AC name, if any */ int synchronous; /* Use synchronous PPP */ PPPoETag hostUniq; /* Use Host-Uniq tag */ int numPADOs; /* Number of PADO packets received */ PPPoETag cookie; /* We have to send this if we get it */ PPPoETag relayId; /* Ditto */ int error; /* Error packet received */ int discoveryTimeout; /* Timeout for discovery packets */ int discoveryAttempts; /* Number of discovery attempts */ int seenMaxPayload; int storedmtu; /* Stored MTU */ int storedmru; /* Stored MRU */ int mtu; int mru; } PPPoEConnection; /* Structure used to determine acceptable PADO or PADS packet */ struct PacketCriteria { PPPoEConnection *conn; int acNameOK; int serviceNameOK; int seenACName; int seenServiceName; }; /* Function Prototypes */ UINT16_t etherType(PPPoEPacket *packet); int openInterface(char const *ifname, UINT16_t type, unsigned char *hwaddr); int sendPacket(PPPoEConnection *conn, int sock, PPPoEPacket *pkt, int size); int receivePacket(int sock, PPPoEPacket *pkt, int *size); int parsePacket(PPPoEPacket *packet, ParseFunc *func, void *extra); void parseLogErrs(UINT16_t typ, UINT16_t len, unsigned char *data, void *xtra); void syncReadFromPPP(PPPoEConnection *conn, PPPoEPacket *packet); void asyncReadFromPPP(PPPoEConnection *conn, PPPoEPacket *packet); void asyncReadFromEth(PPPoEConnection *conn, int sock, int clampMss); void syncReadFromEth(PPPoEConnection *conn, int sock, int clampMss); char *strDup(char const *str); void sendPADT(PPPoEConnection *conn, char const *msg); void sendSessionPacket(PPPoEConnection *conn, PPPoEPacket *packet, int len); void initPPP(void); void clampMSS(PPPoEPacket *packet, char const *dir, int clampMss); UINT16_t computeTCPChecksum(unsigned char *ipHdr, unsigned char *tcpHdr); UINT16_t pppFCS16(UINT16_t fcs, unsigned char *cp, int len); void discovery1(PPPoEConnection *conn); void discovery2(PPPoEConnection *conn); unsigned char *findTag(PPPoEPacket *packet, UINT16_t tagType, PPPoETag *tag); extern int pppoe_verbose; void pppoe_printpkt(PPPoEPacket *packet, void (*printer)(void *, char *, ...), void *arg); void pppoe_log_packet(const char *prefix, PPPoEPacket *packet); static inline int parseHostUniq(const char *uniq, PPPoETag *tag) { unsigned i, len = strlen(uniq); #define hex(x) \ (((x) <= '9') ? ((x) - '0') : \ (((x) <= 'F') ? ((x) - 'A' + 10) : \ ((x) - 'a' + 10))) if (!len || len % 2 || len / 2 > sizeof(tag->payload)) return 0; for (i = 0; i < len; i += 2) { if (!isxdigit(uniq[i]) || !isxdigit(uniq[i+1])) return 0; tag->payload[i / 2] = (char)(hex(uniq[i]) << 4 | hex(uniq[i+1])); } #undef hex tag->type = htons(TAG_HOST_UNIQ); tag->length = htons(len / 2); return 1; } #define SET_STRING(var, val) do { if (var) free(var); var = strDup(val); } while(0); #define CHECK_ROOM(cursor, start, len) \ do {\ if (((cursor)-(start))+(len) > MAX_PPPOE_PAYLOAD) { \ error("Would create too-long packet"); \ return; \ } \ } while(0) /* True if Ethernet address is broadcast or multicast */ #define NOT_UNICAST(e) ((e[0] & 0x01) != 0) #define BROADCAST(e) ((e[0] & e[1] & e[2] & e[3] & e[4] & e[5]) == 0xFF) #define NOT_BROADCAST(e) ((e[0] & e[1] & e[2] & e[3] & e[4] & e[5]) != 0xFF) #ifndef MIN #define MIN(a, b) ((a) < (b)? (a): (b)) #endif #ifndef MAX #define MAX(a, b) ((a) > (b)? (a): (b)) #endif ppp-2.5.0/pppd/plugins/pppoe/pppoe-discovery.80000644000175000017500000000467114402506361016237 00000000000000.\" pppoe-discovery.8 written by .\" Ben Hutchings , based on pppoe.8. .\" Licenced under the GPL version 2 or later. .TH PPPOE-DISCOVERY 8 .SH NAME pppoe\-discovery \- perform PPPoE discovery .SH SYNOPSIS .B pppoe\-discovery [ .I options ] .br .BR pppoe\-discovery " { " \-V " | " \-h " }" .SH DESCRIPTION .LP \fBpppoe\-discovery\fR performs the same discovery process as \fBpppoe\fR, but does not initiate a session. It sends a PADI packet and then prints the names of access concentrators in each PADO packet it receives. .SH OPTIONS .TP .BI \-I " interface" .RS The \fB\-I\fR option specifies the Ethernet interface to use. Under Linux, it is typically eth0 or eth1. The interface should be \(lqup\(rq before you start \fBpppoe\-discovery\fR, but should \fInot\fR be configured to have an IP address. This option is mandatory. .RE .TP .BI \-D " file_name" .RS The \fB\-D\fR option causes every packet to be dumped to the specified \fIfile_name\fR. This is intended for debugging only. .RE .TP .B \-U .RS Causes \fBpppoe\-discovery\fR to use the Host-Uniq tag in its discovery packets. This lets you run multiple instances of \fBpppoe\-discovery\fR and/or \fBpppoe\fR without having their discovery packets interfere with one another. You must supply this option to \fIall\fR instances that you intend to run simultaneously. .RE .TP .BI \-S " service_name" .RS Specifies the desired service name. \fBpppoe\-discovery\fR will only accept access concentrators which can provide the specified service. In most cases, you should \fInot\fR specify this option. Use it only if you know that there are multiple access concentrators or know that you need a specific service name. .RE .TP .BI \-C " ac_name" .RS Specifies the desired access concentrator name. \fBpppoe\-discovery\fR will only accept the specified access concentrator. In most cases, you should \fInot\fR specify this option. Use it only if you know that there are multiple access concentrators. If both the \fB\-S\fR and \fB\-C\fR options are specified, they must \fIboth\fR match. .RE .TP .B \-A .RS This option is accepted for compatibility with \fBpppoe\fR, but has no effect. .RE .TP .BR \-V " | " \-h .RS Either of these options causes \fBpppoe\-discovery\fR to print its version number and usage information, then exit. .RE .SH AUTHORS \fBpppoe\-discovery\fR was written by Marco d'Itri , based on \fBpppoe\fR by Dianne Skoll . .SH SEE ALSO pppoe(8), pppoe-sniff(8) ppp-2.5.0/pppd/plugins/pppoe/Makefile.in0000644000175000017500000011755414407475314015100 00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ sbin_PROGRAMS = pppoe-discovery$(EXEEXT) subdir = pppd/plugins/pppoe ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_atm.m4 \ $(top_srcdir)/m4/ax_check_openssl.m4 \ $(top_srcdir)/m4/ax_check_openssl_func.m4 \ $(top_srcdir)/m4/ax_check_pam.m4 \ $(top_srcdir)/m4/ax_check_pcap.m4 \ $(top_srcdir)/m4/ax_check_srp.m4 $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/pkg.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(noinst_HEADERS) \ $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/pppd/config.h \ $(top_builddir)/pppd/pppdconf.h config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__installdirs = "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(pppd_plugindir)" \ "$(DESTDIR)$(man8dir)" PROGRAMS = $(sbin_PROGRAMS) am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } LTLIBRARIES = $(pppd_plugin_LTLIBRARIES) pppoe_la_LIBADD = am_pppoe_la_OBJECTS = pppoe_la-plugin.lo pppoe_la-discovery.lo \ pppoe_la-if.lo pppoe_la-common.lo pppoe_la_OBJECTS = $(am_pppoe_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = pppoe_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(pppoe_la_LDFLAGS) $(LDFLAGS) -o $@ am_pppoe_discovery_OBJECTS = \ pppoe_discovery-pppoe-discovery.$(OBJEXT) \ pppoe_discovery-discovery.$(OBJEXT) \ pppoe_discovery-if.$(OBJEXT) pppoe_discovery-common.$(OBJEXT) pppoe_discovery_OBJECTS = $(am_pppoe_discovery_OBJECTS) pppoe_discovery_LDADD = $(LDADD) AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/pppd depcomp = $(SHELL) $(top_srcdir)/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/pppoe_discovery-common.Po \ ./$(DEPDIR)/pppoe_discovery-discovery.Po \ ./$(DEPDIR)/pppoe_discovery-if.Po \ ./$(DEPDIR)/pppoe_discovery-pppoe-discovery.Po \ ./$(DEPDIR)/pppoe_la-common.Plo \ ./$(DEPDIR)/pppoe_la-discovery.Plo ./$(DEPDIR)/pppoe_la-if.Plo \ ./$(DEPDIR)/pppoe_la-plugin.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(pppoe_la_SOURCES) $(pppoe_discovery_SOURCES) DIST_SOURCES = $(pppoe_la_SOURCES) $(pppoe_discovery_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac man8dir = $(mandir)/man8 NROFF = nroff MANS = $(dist_man8_MANS) HEADERS = $(noinst_HEADERS) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) \ config.h.in # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(dist_man8_MANS) $(srcdir)/Makefile.in \ $(srcdir)/config.h.in $(top_srcdir)/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ ATM_CFLAGS = @ATM_CFLAGS@ ATM_LDFLAGS = @ATM_LDFLAGS@ ATM_LIBS = @ATM_LIBS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CRYPT_LIBS = @CRYPT_LIBS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GREP = @GREP@ GTK_CFLAGS = @GTK_CFLAGS@ GTK_LIBS = @GTK_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_INCLUDES = @OPENSSL_INCLUDES@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAM_CFLAGS = @PAM_CFLAGS@ PAM_LDFLAGS = @PAM_LDFLAGS@ PAM_LIBS = @PAM_LIBS@ PATH_SEPARATOR = @PATH_SEPARATOR@ PCAP_CFLAGS = @PCAP_CFLAGS@ PCAP_LDFLAGS = @PCAP_LDFLAGS@ PCAP_LIBS = @PCAP_LIBS@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PPPD_LOGFILE_DIR = @PPPD_LOGFILE_DIR@ PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@ PPPD_RUNTIME_DIR = @PPPD_RUNTIME_DIR@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SRP_CFLAGS = @SRP_CFLAGS@ SRP_LDFLAGS = @SRP_LDFLAGS@ SRP_LIBS = @SRP_LIBS@ STRIP = @STRIP@ SYSTEMD_CFLAGS = @SYSTEMD_CFLAGS@ SYSTEMD_LIBS = @SYSTEMD_LIBS@ SYSTEM_CA_PATH = @SYSTEM_CA_PATH@ UTIL_LIBS = @UTIL_LIBS@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ pppd_plugin_LTLIBRARIES = pppoe.la pppd_plugindir = $(PPPD_PLUGIN_DIR) dist_man8_MANS = pppoe-discovery.8 noinst_HEADERS = \ pppoe.h pppoe_la_CPPFLAGS = -I${top_srcdir} -DSYSCONFDIR=\"${sysconfdir}\" -DPLUGIN pppoe_la_LDFLAGS = -module -avoid-version pppoe_la_SOURCES = plugin.c discovery.c if.c common.c pppoe_discovery_CPPFLAGS = -I${top_srcdir} pppoe_discovery_SOURCES = pppoe-discovery.c discovery.c if.c common.c all: config.h $(MAKE) $(AM_MAKEFLAGS) all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu pppd/plugins/pppoe/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu pppd/plugins/pppoe/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): config.h: stamp-h3 @test -f $@ || rm -f stamp-h3 @test -f $@ || $(MAKE) $(AM_MAKEFLAGS) stamp-h3 stamp-h3: $(srcdir)/config.h.in $(top_builddir)/config.status @rm -f stamp-h3 cd $(top_builddir) && $(SHELL) ./config.status pppd/plugins/pppoe/config.h distclean-hdr: -rm -f config.h stamp-h3 install-sbinPROGRAMS: $(sbin_PROGRAMS) @$(NORMAL_INSTALL) @list='$(sbin_PROGRAMS)'; test -n "$(sbindir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(sbindir)'"; \ $(MKDIR_P) "$(DESTDIR)$(sbindir)" || exit 1; \ fi; \ for p in $$list; do echo "$$p $$p"; done | \ sed 's/$(EXEEXT)$$//' | \ while read p p1; do if test -f $$p \ || test -f $$p1 \ ; then echo "$$p"; echo "$$p"; else :; fi; \ done | \ sed -e 'p;s,.*/,,;n;h' \ -e 's|.*|.|' \ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ if ($$2 == $$4) files[d] = files[d] " " $$1; \ else { print "f", $$3 "/" $$4, $$1; } } \ END { for (d in files) print "f", d, files[d] }' | \ while read type dir files; do \ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ test -z "$$files" || { \ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(sbindir)$$dir'"; \ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(sbindir)$$dir" || exit $$?; \ } \ ; done uninstall-sbinPROGRAMS: @$(NORMAL_UNINSTALL) @list='$(sbin_PROGRAMS)'; test -n "$(sbindir)" || list=; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ -e 's/$$/$(EXEEXT)/' \ `; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(sbindir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(sbindir)" && rm -f $$files clean-sbinPROGRAMS: @list='$(sbin_PROGRAMS)'; test -n "$$list" || exit 0; \ echo " rm -f" $$list; \ rm -f $$list || exit $$?; \ test -n "$(EXEEXT)" || exit 0; \ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list install-pppd_pluginLTLIBRARIES: $(pppd_plugin_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(pppd_plugin_LTLIBRARIES)'; test -n "$(pppd_plugindir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(pppd_plugindir)'"; \ $(MKDIR_P) "$(DESTDIR)$(pppd_plugindir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(pppd_plugindir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(pppd_plugindir)"; \ } uninstall-pppd_pluginLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(pppd_plugin_LTLIBRARIES)'; test -n "$(pppd_plugindir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(pppd_plugindir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(pppd_plugindir)/$$f"; \ done clean-pppd_pluginLTLIBRARIES: -test -z "$(pppd_plugin_LTLIBRARIES)" || rm -f $(pppd_plugin_LTLIBRARIES) @list='$(pppd_plugin_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } pppoe.la: $(pppoe_la_OBJECTS) $(pppoe_la_DEPENDENCIES) $(EXTRA_pppoe_la_DEPENDENCIES) $(AM_V_CCLD)$(pppoe_la_LINK) -rpath $(pppd_plugindir) $(pppoe_la_OBJECTS) $(pppoe_la_LIBADD) $(LIBS) pppoe-discovery$(EXEEXT): $(pppoe_discovery_OBJECTS) $(pppoe_discovery_DEPENDENCIES) $(EXTRA_pppoe_discovery_DEPENDENCIES) @rm -f pppoe-discovery$(EXEEXT) $(AM_V_CCLD)$(LINK) $(pppoe_discovery_OBJECTS) $(pppoe_discovery_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pppoe_discovery-common.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pppoe_discovery-discovery.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pppoe_discovery-if.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pppoe_discovery-pppoe-discovery.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pppoe_la-common.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pppoe_la-discovery.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pppoe_la-if.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pppoe_la-plugin.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< pppoe_la-plugin.lo: plugin.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppoe_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pppoe_la-plugin.lo -MD -MP -MF $(DEPDIR)/pppoe_la-plugin.Tpo -c -o pppoe_la-plugin.lo `test -f 'plugin.c' || echo '$(srcdir)/'`plugin.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pppoe_la-plugin.Tpo $(DEPDIR)/pppoe_la-plugin.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='plugin.c' object='pppoe_la-plugin.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppoe_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pppoe_la-plugin.lo `test -f 'plugin.c' || echo '$(srcdir)/'`plugin.c pppoe_la-discovery.lo: discovery.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppoe_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pppoe_la-discovery.lo -MD -MP -MF $(DEPDIR)/pppoe_la-discovery.Tpo -c -o pppoe_la-discovery.lo `test -f 'discovery.c' || echo '$(srcdir)/'`discovery.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pppoe_la-discovery.Tpo $(DEPDIR)/pppoe_la-discovery.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='discovery.c' object='pppoe_la-discovery.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppoe_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pppoe_la-discovery.lo `test -f 'discovery.c' || echo '$(srcdir)/'`discovery.c pppoe_la-if.lo: if.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppoe_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pppoe_la-if.lo -MD -MP -MF $(DEPDIR)/pppoe_la-if.Tpo -c -o pppoe_la-if.lo `test -f 'if.c' || echo '$(srcdir)/'`if.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pppoe_la-if.Tpo $(DEPDIR)/pppoe_la-if.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='if.c' object='pppoe_la-if.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppoe_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pppoe_la-if.lo `test -f 'if.c' || echo '$(srcdir)/'`if.c pppoe_la-common.lo: common.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppoe_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pppoe_la-common.lo -MD -MP -MF $(DEPDIR)/pppoe_la-common.Tpo -c -o pppoe_la-common.lo `test -f 'common.c' || echo '$(srcdir)/'`common.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pppoe_la-common.Tpo $(DEPDIR)/pppoe_la-common.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='common.c' object='pppoe_la-common.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppoe_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pppoe_la-common.lo `test -f 'common.c' || echo '$(srcdir)/'`common.c pppoe_discovery-pppoe-discovery.o: pppoe-discovery.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppoe_discovery_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pppoe_discovery-pppoe-discovery.o -MD -MP -MF $(DEPDIR)/pppoe_discovery-pppoe-discovery.Tpo -c -o pppoe_discovery-pppoe-discovery.o `test -f 'pppoe-discovery.c' || echo '$(srcdir)/'`pppoe-discovery.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pppoe_discovery-pppoe-discovery.Tpo $(DEPDIR)/pppoe_discovery-pppoe-discovery.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pppoe-discovery.c' object='pppoe_discovery-pppoe-discovery.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppoe_discovery_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pppoe_discovery-pppoe-discovery.o `test -f 'pppoe-discovery.c' || echo '$(srcdir)/'`pppoe-discovery.c pppoe_discovery-pppoe-discovery.obj: pppoe-discovery.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppoe_discovery_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pppoe_discovery-pppoe-discovery.obj -MD -MP -MF $(DEPDIR)/pppoe_discovery-pppoe-discovery.Tpo -c -o pppoe_discovery-pppoe-discovery.obj `if test -f 'pppoe-discovery.c'; then $(CYGPATH_W) 'pppoe-discovery.c'; else $(CYGPATH_W) '$(srcdir)/pppoe-discovery.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pppoe_discovery-pppoe-discovery.Tpo $(DEPDIR)/pppoe_discovery-pppoe-discovery.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pppoe-discovery.c' object='pppoe_discovery-pppoe-discovery.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppoe_discovery_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pppoe_discovery-pppoe-discovery.obj `if test -f 'pppoe-discovery.c'; then $(CYGPATH_W) 'pppoe-discovery.c'; else $(CYGPATH_W) '$(srcdir)/pppoe-discovery.c'; fi` pppoe_discovery-discovery.o: discovery.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppoe_discovery_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pppoe_discovery-discovery.o -MD -MP -MF $(DEPDIR)/pppoe_discovery-discovery.Tpo -c -o pppoe_discovery-discovery.o `test -f 'discovery.c' || echo '$(srcdir)/'`discovery.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pppoe_discovery-discovery.Tpo $(DEPDIR)/pppoe_discovery-discovery.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='discovery.c' object='pppoe_discovery-discovery.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppoe_discovery_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pppoe_discovery-discovery.o `test -f 'discovery.c' || echo '$(srcdir)/'`discovery.c pppoe_discovery-discovery.obj: discovery.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppoe_discovery_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pppoe_discovery-discovery.obj -MD -MP -MF $(DEPDIR)/pppoe_discovery-discovery.Tpo -c -o pppoe_discovery-discovery.obj `if test -f 'discovery.c'; then $(CYGPATH_W) 'discovery.c'; else $(CYGPATH_W) '$(srcdir)/discovery.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pppoe_discovery-discovery.Tpo $(DEPDIR)/pppoe_discovery-discovery.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='discovery.c' object='pppoe_discovery-discovery.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppoe_discovery_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pppoe_discovery-discovery.obj `if test -f 'discovery.c'; then $(CYGPATH_W) 'discovery.c'; else $(CYGPATH_W) '$(srcdir)/discovery.c'; fi` pppoe_discovery-if.o: if.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppoe_discovery_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pppoe_discovery-if.o -MD -MP -MF $(DEPDIR)/pppoe_discovery-if.Tpo -c -o pppoe_discovery-if.o `test -f 'if.c' || echo '$(srcdir)/'`if.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pppoe_discovery-if.Tpo $(DEPDIR)/pppoe_discovery-if.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='if.c' object='pppoe_discovery-if.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppoe_discovery_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pppoe_discovery-if.o `test -f 'if.c' || echo '$(srcdir)/'`if.c pppoe_discovery-if.obj: if.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppoe_discovery_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pppoe_discovery-if.obj -MD -MP -MF $(DEPDIR)/pppoe_discovery-if.Tpo -c -o pppoe_discovery-if.obj `if test -f 'if.c'; then $(CYGPATH_W) 'if.c'; else $(CYGPATH_W) '$(srcdir)/if.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pppoe_discovery-if.Tpo $(DEPDIR)/pppoe_discovery-if.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='if.c' object='pppoe_discovery-if.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppoe_discovery_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pppoe_discovery-if.obj `if test -f 'if.c'; then $(CYGPATH_W) 'if.c'; else $(CYGPATH_W) '$(srcdir)/if.c'; fi` pppoe_discovery-common.o: common.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppoe_discovery_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pppoe_discovery-common.o -MD -MP -MF $(DEPDIR)/pppoe_discovery-common.Tpo -c -o pppoe_discovery-common.o `test -f 'common.c' || echo '$(srcdir)/'`common.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pppoe_discovery-common.Tpo $(DEPDIR)/pppoe_discovery-common.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='common.c' object='pppoe_discovery-common.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppoe_discovery_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pppoe_discovery-common.o `test -f 'common.c' || echo '$(srcdir)/'`common.c pppoe_discovery-common.obj: common.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppoe_discovery_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pppoe_discovery-common.obj -MD -MP -MF $(DEPDIR)/pppoe_discovery-common.Tpo -c -o pppoe_discovery-common.obj `if test -f 'common.c'; then $(CYGPATH_W) 'common.c'; else $(CYGPATH_W) '$(srcdir)/common.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pppoe_discovery-common.Tpo $(DEPDIR)/pppoe_discovery-common.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='common.c' object='pppoe_discovery-common.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppoe_discovery_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pppoe_discovery-common.obj `if test -f 'common.c'; then $(CYGPATH_W) 'common.c'; else $(CYGPATH_W) '$(srcdir)/common.c'; fi` mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs install-man8: $(dist_man8_MANS) @$(NORMAL_INSTALL) @list1='$(dist_man8_MANS)'; \ list2=''; \ test -n "$(man8dir)" \ && test -n "`echo $$list1$$list2`" \ || exit 0; \ echo " $(MKDIR_P) '$(DESTDIR)$(man8dir)'"; \ $(MKDIR_P) "$(DESTDIR)$(man8dir)" || exit 1; \ { for i in $$list1; do echo "$$i"; done; \ if test -n "$$list2"; then \ for i in $$list2; do echo "$$i"; done \ | sed -n '/\.8[a-z]*$$/p'; \ fi; \ } | while read p; do \ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; echo "$$p"; \ done | \ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ sed 'N;N;s,\n, ,g' | { \ list=; while read file base inst; do \ if test "$$base" = "$$inst"; then list="$$list $$file"; else \ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man8dir)/$$inst'"; \ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man8dir)/$$inst" || exit $$?; \ fi; \ done; \ for i in $$list; do echo "$$i"; done | $(am__base_list) | \ while read files; do \ test -z "$$files" || { \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man8dir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(man8dir)" || exit $$?; }; \ done; } uninstall-man8: @$(NORMAL_UNINSTALL) @list='$(dist_man8_MANS)'; test -n "$(man8dir)" || exit 0; \ files=`{ for i in $$list; do echo "$$i"; done; \ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ dir='$(DESTDIR)$(man8dir)'; $(am__uninstall_files_from_dir) ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(PROGRAMS) $(LTLIBRARIES) $(MANS) $(HEADERS) \ config.h installdirs: for dir in "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(pppd_plugindir)" "$(DESTDIR)$(man8dir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-pppd_pluginLTLIBRARIES \ clean-sbinPROGRAMS mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/pppoe_discovery-common.Po -rm -f ./$(DEPDIR)/pppoe_discovery-discovery.Po -rm -f ./$(DEPDIR)/pppoe_discovery-if.Po -rm -f ./$(DEPDIR)/pppoe_discovery-pppoe-discovery.Po -rm -f ./$(DEPDIR)/pppoe_la-common.Plo -rm -f ./$(DEPDIR)/pppoe_la-discovery.Plo -rm -f ./$(DEPDIR)/pppoe_la-if.Plo -rm -f ./$(DEPDIR)/pppoe_la-plugin.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-hdr distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-man install-pppd_pluginLTLIBRARIES install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-sbinPROGRAMS install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-man8 install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/pppoe_discovery-common.Po -rm -f ./$(DEPDIR)/pppoe_discovery-discovery.Po -rm -f ./$(DEPDIR)/pppoe_discovery-if.Po -rm -f ./$(DEPDIR)/pppoe_discovery-pppoe-discovery.Po -rm -f ./$(DEPDIR)/pppoe_la-common.Plo -rm -f ./$(DEPDIR)/pppoe_la-discovery.Plo -rm -f ./$(DEPDIR)/pppoe_la-if.Plo -rm -f ./$(DEPDIR)/pppoe_la-plugin.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-man uninstall-pppd_pluginLTLIBRARIES \ uninstall-sbinPROGRAMS uninstall-man: uninstall-man8 .MAKE: all install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-pppd_pluginLTLIBRARIES \ clean-sbinPROGRAMS cscopelist-am ctags ctags-am distclean \ distclean-compile distclean-generic distclean-hdr \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-man8 install-pdf \ install-pdf-am install-pppd_pluginLTLIBRARIES install-ps \ install-ps-am install-sbinPROGRAMS install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am uninstall-man \ uninstall-man8 uninstall-pppd_pluginLTLIBRARIES \ uninstall-sbinPROGRAMS .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: ppp-2.5.0/pppd/plugins/pppoe/config.h.in0000644000175000017500000000401614353435407015041 00000000000000/* pppd/config.h.in. Generated from configure.ac by autoheader. */ /* Define to 1 if you have the header file. */ #undef HAVE_ASM_TYPES_H /* Define to 1 if you have the header file. */ #undef HAVE_LINUX_IF_ETHER_H /* Define to 1 if you have the header file. */ #undef HAVE_LINUX_IF_H /* Define to 1 if you have the header file. */ #undef HAVE_LINUX_IF_PACKET_H /* Define to 1 if you have the header file. */ #undef HAVE_NET_IF_ARP_H /* Define to 1 if you have the header file. */ #undef HAVE_NET_IF_TYPES_H /* Define to 1 if you have the header file. */ #undef HAVE_NETINET_IF_ETHER_H /* Define to 1 if you have the header file. */ #undef HAVE_NETPACKET_PACKET_H /* Define to 1 if you have the header file. */ #undef HAVE_NET_BPF_H /* Define to 1 if you have the header file. */ #undef HAVE_NET_IF_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_DLPI_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_IOCTL_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_SOCKET_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_UIO_H /* Define to 1 if you have the header file. */ #undef HAVE_UNISTD_H /* Define to 1 if you have the header file. */ #undef HAVE_STDARG_H /* Define to 1 if you have the header file. */ #undef HAVE_STDBOOL_H /* Define to 1 if you have the header file. */ #undef HAVE_STDDEF_H /* Define to 1 if you have the header file. */ #undef HAVE_STDINT_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TYPES_H /* The size of `unsigned int', as computed by sizeof. */ #undef SIZEOF_UNSIGNED_INT /* The size of `unsigned long', as computed by sizeof. */ #undef SIZEOF_UNSIGNED_LONG /* The size of `unsigned short', as computed by sizeof. */ #undef SIZEOF_UNSIGNED_SHORT ppp-2.5.0/pppd/plugins/pppoe/plugin.c0000644000175000017500000003414414407475306014467 00000000000000/*********************************************************************** * * plugin.c * * pppd plugin for kernel-mode PPPoE on Linux * * Copyright (C) 2001 by Roaring Penguin Software Inc., Michal Ostrowski * and Jamal Hadi Salim. * * Much code and many ideas derived from pppoe plugin by Michal * Ostrowski and Jamal Hadi Salim, which carries this copyright: * * Copyright 2000 Michal Ostrowski , * Jamal Hadi Salim * Borrows heavily from the PPPoATM plugin by Mitchell Blank Jr., * which is based in part on work from Jens Axboe and Paul Mackerras. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. * ***********************************************************************/ static char const RCSID[] = "$Id: plugin.c,v 1.17 2008/06/15 04:35:50 paulus Exp $"; #ifdef HAVE_CONFIG_H #include "config.h" #endif #define _GNU_SOURCE 1 #include "pppoe.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include char pppd_version[] = PPPD_VERSION; /* From sys-linux.c in pppd -- MUST FIX THIS! */ extern int new_style_driver; char *pppd_pppoe_service = NULL; static char *acName = NULL; static char *existingSession = NULL; int pppoe_verbose = 0; static char *pppoe_reqd_mac = NULL; unsigned char pppoe_reqd_mac_addr[6]; static char *pppoe_host_uniq; static int pppoe_padi_timeout = PADI_TIMEOUT; static int pppoe_padi_attempts = MAX_PADI_ATTEMPTS; static char devnam[MAXNAMELEN]; static int PPPoEDevnameHook(char *cmd, char **argv, int doit); static struct option Options[] = { { "device name", o_wild, (void *) &PPPoEDevnameHook, "PPPoE device name", OPT_DEVNAM | OPT_PRIVFIX | OPT_NOARG | OPT_A2STRVAL | OPT_STATIC, devnam}, { "pppoe-service", o_string, &pppd_pppoe_service, "Desired PPPoE service name" }, { "rp_pppoe_service", o_string, &pppd_pppoe_service, "Legacy alias for pppoe-service", OPT_ALIAS }, { "pppoe-ac", o_string, &acName, "Desired PPPoE access concentrator name" }, { "rp_pppoe_ac", o_string, &acName, "Legacy alias for pppoe-ac", OPT_ALIAS }, { "pppoe-sess", o_string, &existingSession, "Attach to existing session (sessid:macaddr)" }, { "rp_pppoe_sess", o_string, &existingSession, "Legacy alias for pppoe-sess", OPT_ALIAS }, { "pppoe-verbose", o_int, &pppoe_verbose, "Be verbose about discovered access concentrators" }, { "rp_pppoe_verbose", o_int, &pppoe_verbose, "Legacy alias for pppoe-verbose", OPT_ALIAS }, { "pppoe-mac", o_string, &pppoe_reqd_mac, "Only connect to specified MAC address" }, { "pppoe-host-uniq", o_string, &pppoe_host_uniq, "Set the Host-Uniq to the supplied hex string" }, { "host-uniq", o_string, &pppoe_host_uniq, "Legacy alias for pppoe-host-uniq", OPT_ALIAS }, { "pppoe-padi-timeout", o_int, &pppoe_padi_timeout, "Initial timeout for discovery packets in seconds" }, { "pppoe-padi-attempts", o_int, &pppoe_padi_attempts, "Number of discovery attempts" }, { NULL } }; int (*OldDevnameHook)(char *cmd, char **argv, int doit) = NULL; static PPPoEConnection *conn = NULL; /********************************************************************** * %FUNCTION: PPPOEInitDevice * %ARGUMENTS: * None * %RETURNS: * * %DESCRIPTION: * Initializes PPPoE device. ***********************************************************************/ static int PPPOEInitDevice(void) { conn = malloc(sizeof(PPPoEConnection)); if (!conn) { novm("PPPoE session data"); } memset(conn, 0, sizeof(PPPoEConnection)); conn->ifName = devnam; conn->discoverySocket = -1; conn->sessionSocket = -1; conn->discoveryTimeout = pppoe_padi_timeout; conn->discoveryAttempts = pppoe_padi_attempts; return 1; } /********************************************************************** * %FUNCTION: PPPOEConnectDevice * %ARGUMENTS: * None * %RETURNS: * Non-negative if all goes well; -1 otherwise * %DESCRIPTION: * Connects PPPoE device. ***********************************************************************/ static int PPPOEConnectDevice(void) { struct sockaddr_pppox sp; struct ifreq ifr; int s; char remote_number[MAXNAMELEN]; /* Open session socket before discovery phase, to avoid losing session */ /* packets sent by peer just after PADS packet (noted on some Cisco */ /* server equipment). */ /* Opening this socket just before waitForPADS in the discovery() */ /* function would be more appropriate, but it would mess-up the code */ conn->sessionSocket = socket(AF_PPPOX, SOCK_STREAM, PX_PROTO_OE); if (conn->sessionSocket < 0) { error("Failed to create PPPoE socket: %m"); return -1; } /* Restore configuration */ lcp_allowoptions[0].mru = conn->mtu = conn->storedmtu; lcp_wantoptions[0].mru = conn->mru = conn->storedmru; /* Update maximum MRU */ s = socket(AF_INET, SOCK_DGRAM, 0); if (s < 0) { error("Can't get MTU for %s: %m", conn->ifName); goto errout; } strlcpy(ifr.ifr_name, conn->ifName, sizeof(ifr.ifr_name)); if (ioctl(s, SIOCGIFMTU, &ifr) < 0) { error("Can't get MTU for %s: %m", conn->ifName); close(s); goto errout; } close(s); if (lcp_allowoptions[0].mru > ifr.ifr_mtu - TOTAL_OVERHEAD) lcp_allowoptions[0].mru = conn->mtu = ifr.ifr_mtu - TOTAL_OVERHEAD; if (lcp_wantoptions[0].mru > ifr.ifr_mtu - TOTAL_OVERHEAD) lcp_wantoptions[0].mru = conn->mru = ifr.ifr_mtu - TOTAL_OVERHEAD; if (pppoe_host_uniq) { if (!parseHostUniq(pppoe_host_uniq, &conn->hostUniq)) fatal("Illegal value for pppoe-host-uniq option"); } else { /* if a custom host-uniq is not supplied, use our PID */ pid_t pid = getpid(); conn->hostUniq.type = htons(TAG_HOST_UNIQ); conn->hostUniq.length = htons(sizeof(pid)); memcpy(conn->hostUniq.payload, &pid, sizeof(pid)); } conn->acName = acName; conn->serviceName = pppd_pppoe_service; ppp_set_pppdevnam(devnam); if (existingSession) { unsigned int mac[ETH_ALEN]; int i, ses; if (sscanf(existingSession, "%d:%x:%x:%x:%x:%x:%x", &ses, &mac[0], &mac[1], &mac[2], &mac[3], &mac[4], &mac[5]) != 7) { fatal("Illegal value for pppoe-sess option"); } conn->session = htons(ses); for (i=0; ipeerEth[i] = (unsigned char) mac[i]; } } else { conn->discoverySocket = openInterface(conn->ifName, Eth_PPPOE_Discovery, conn->myEth); if (conn->discoverySocket < 0) { error("Failed to create PPPoE discovery socket: %m"); goto errout; } discovery1(conn); /* discovery1() may update conn->mtu and conn->mru */ lcp_allowoptions[0].mru = conn->mtu; lcp_wantoptions[0].mru = conn->mru; if (conn->discoveryState != STATE_RECEIVED_PADO) { error("Unable to complete PPPoE Discovery phase 1"); goto errout; } discovery2(conn); /* discovery2() may update conn->mtu and conn->mru */ lcp_allowoptions[0].mru = conn->mtu; lcp_wantoptions[0].mru = conn->mru; if (conn->discoveryState != STATE_SESSION) { error("Unable to complete PPPoE Discovery phase 2"); goto errout; } } /* Set PPPoE session-number for further consumption */ ppp_set_session_number(ntohs(conn->session)); sp.sa_family = AF_PPPOX; sp.sa_protocol = PX_PROTO_OE; sp.sa_addr.pppoe.sid = conn->session; memcpy(sp.sa_addr.pppoe.dev, conn->ifName, IFNAMSIZ); memcpy(sp.sa_addr.pppoe.remote, conn->peerEth, ETH_ALEN); /* Set remote_number for ServPoET */ sprintf(remote_number, "%02X:%02X:%02X:%02X:%02X:%02X", (unsigned) conn->peerEth[0], (unsigned) conn->peerEth[1], (unsigned) conn->peerEth[2], (unsigned) conn->peerEth[3], (unsigned) conn->peerEth[4], (unsigned) conn->peerEth[5]); warn("Connected to %s via interface %s", remote_number, conn->ifName); ppp_set_remote_number(remote_number); ppp_script_setenv("MACREMOTE", remote_number, 0); if (connect(conn->sessionSocket, (struct sockaddr *) &sp, sizeof(struct sockaddr_pppox)) < 0) { error("Failed to connect PPPoE socket: %d %m", errno); goto errout; } return conn->sessionSocket; errout: if (conn->discoverySocket >= 0) { sendPADT(conn, NULL); close(conn->discoverySocket); conn->discoverySocket = -1; } close(conn->sessionSocket); return -1; } static void PPPOERecvConfig(int mru, u_int32_t asyncmap, int pcomp, int accomp) { #if 0 /* broken protocol, but no point harrassing the users I guess... */ if (mru > MAX_PPPOE_MTU) warn("Couldn't increase MRU to %d", mru); #endif } /********************************************************************** * %FUNCTION: PPPOEDisconnectDevice * %ARGUMENTS: * None * %RETURNS: * Nothing * %DESCRIPTION: * Disconnects PPPoE device ***********************************************************************/ static void PPPOEDisconnectDevice(void) { struct sockaddr_pppox sp; sp.sa_family = AF_PPPOX; sp.sa_protocol = PX_PROTO_OE; sp.sa_addr.pppoe.sid = 0; memcpy(sp.sa_addr.pppoe.dev, conn->ifName, IFNAMSIZ); memcpy(sp.sa_addr.pppoe.remote, conn->peerEth, ETH_ALEN); if (connect(conn->sessionSocket, (struct sockaddr *) &sp, sizeof(struct sockaddr_pppox)) < 0 && errno != EALREADY) error("Failed to disconnect PPPoE socket: %d %m", errno); close(conn->sessionSocket); if (conn->discoverySocket >= 0) { sendPADT(conn, NULL); close(conn->discoverySocket); } } static void PPPOEDeviceOptions(void) { char name[MAXPATHLEN]; char buf[MAXPATHLEN]; slprintf(name, sizeof(name), "options.%s", devnam); if (ppp_get_filepath(PPP_DIR_CONF, name, buf, sizeof(buf)) < sizeof(buf)) { if (!ppp_options_from_file(buf, 0, 0, 1)) { exit(EXIT_OPTION_ERROR); } } else { exit(EXIT_OPTION_ERROR); } } struct channel pppoe_channel; /********************************************************************** * %FUNCTION: PPPoEDevnameHook * %ARGUMENTS: * cmd -- the command (actually, the device name * argv -- argument vector * doit -- if non-zero, set device name. Otherwise, just check if possible * %RETURNS: * 1 if we will handle this device; 0 otherwise. * %DESCRIPTION: * Checks if name is a valid interface name; if so, returns 1. Also * sets up devnam (string representation of device). ***********************************************************************/ static int PPPoEDevnameHook(char *cmd, char **argv, int doit) { int r = 1; int fd; struct ifreq ifr; /* * Take any otherwise-unrecognized option as a possible device name, * and test if it is the name of a network interface with a * hardware address whose sa_family is ARPHRD_ETHER. */ if (strlen(cmd) > 4 && !strncmp(cmd, "nic-", 4)) { /* Strip off "nic-" */ cmd += 4; } /* Open a socket */ if ((fd = socket(PF_PACKET, SOCK_RAW, 0)) < 0) { r = 0; } /* Try getting interface index */ if (r) { strlcpy(ifr.ifr_name, cmd, sizeof(ifr.ifr_name)); if (ioctl(fd, SIOCGIFINDEX, &ifr) < 0) { r = 0; } else { if (ioctl(fd, SIOCGIFHWADDR, &ifr) < 0) { r = 0; } else { if (ifr.ifr_hwaddr.sa_family != ARPHRD_ETHER) { if (doit) error("Interface %s not Ethernet", cmd); r = 0; } } } } /* Close socket */ close(fd); if (r && doit) { strlcpy(devnam, cmd, sizeof(devnam)); if (the_channel != &pppoe_channel) { the_channel = &pppoe_channel; ppp_set_modem(0); PPPOEInitDevice(); } ppp_set_devnam(devnam); return 1; } return r; } /********************************************************************** * %FUNCTION: plugin_init * %ARGUMENTS: * None * %RETURNS: * Nothing * %DESCRIPTION: * Initializes hooks for pppd plugin ***********************************************************************/ void plugin_init(void) { if (!ppp_check_kernel_support() && !new_style_driver) { fatal("Linux kernel does not support PPPoE -- are you running 2.4.x?"); } ppp_add_options(Options); info("PPPoE plugin from pppd %s", PPPD_VERSION); } void pppoe_check_options(void) { unsigned int mac[6]; int i; if (pppoe_reqd_mac != NULL) { if (sscanf(pppoe_reqd_mac, "%x:%x:%x:%x:%x:%x", &mac[0], &mac[1], &mac[2], &mac[3], &mac[4], &mac[5]) != 6) { ppp_option_error("cannot parse pppoe-mac option value"); exit(EXIT_OPTION_ERROR); } for (i = 0; i < 6; ++i) conn->req_peer_mac[i] = mac[i]; conn->req_peer = 1; } lcp_allowoptions[0].neg_accompression = 0; lcp_wantoptions[0].neg_accompression = 0; lcp_allowoptions[0].neg_asyncmap = 0; lcp_wantoptions[0].neg_asyncmap = 0; lcp_allowoptions[0].neg_pcompression = 0; lcp_wantoptions[0].neg_pcompression = 0; if (lcp_allowoptions[0].mru > MAX_PPPOE_MTU) lcp_allowoptions[0].mru = MAX_PPPOE_MTU; if (lcp_wantoptions[0].mru > MAX_PPPOE_MTU) lcp_wantoptions[0].mru = MAX_PPPOE_MTU; /* Save configuration */ conn->storedmtu = lcp_allowoptions[0].mru; conn->storedmru = lcp_wantoptions[0].mru; ccp_allowoptions[0].deflate = 0; ccp_wantoptions[0].deflate = 0; ipcp_allowoptions[0].neg_vj = 0; ipcp_wantoptions[0].neg_vj = 0; ccp_allowoptions[0].bsd_compress = 0; ccp_wantoptions[0].bsd_compress = 0; } struct channel pppoe_channel = { .options = Options, .process_extra_options = &PPPOEDeviceOptions, .check_options = pppoe_check_options, .connect = &PPPOEConnectDevice, .disconnect = &PPPOEDisconnectDevice, .establish_ppp = &ppp_generic_establish, .disestablish_ppp = &ppp_generic_disestablish, .send_config = NULL, .recv_config = &PPPOERecvConfig, .close = NULL, .cleanup = NULL }; ppp-2.5.0/pppd/plugins/pppoe/discovery.c0000644000175000017500000004737414353435407015207 00000000000000/*********************************************************************** * * discovery.c * * Perform PPPoE discovery * * Copyright (C) 1999 by Roaring Penguin Software Inc. * ***********************************************************************/ static char const RCSID[] = "$Id: discovery.c,v 1.6 2008/06/15 04:35:50 paulus Exp $"; #ifdef HAVE_CONFIG_H #include "config.h" #endif #define _GNU_SOURCE 1 #include "pppoe.h" #include #include #include #include #include #include #ifdef HAVE_SYS_TIME_H #include #endif #ifdef HAVE_SYS_UIO_H #include #endif #ifdef HAVE_UNISTD_H #include #endif #ifdef USE_LINUX_PACKET #include #include #endif #include #ifdef PLUGIN #define signaled(x) ppp_signaled(x) #define get_time(x) ppp_get_time(x) #else int signaled(int signal); int get_time(struct timeval *tv); #endif /* Calculate time remaining until *exp, return 0 if now >= *exp */ static int time_left(struct timeval *diff, struct timeval *exp) { struct timeval now; if (get_time(&now) < 0) { error("get_time: %m"); return 0; } if (now.tv_sec > exp->tv_sec || (now.tv_sec == exp->tv_sec && now.tv_usec >= exp->tv_usec)) return 0; diff->tv_sec = exp->tv_sec - now.tv_sec; diff->tv_usec = exp->tv_usec - now.tv_usec; if (diff->tv_usec < 0) { diff->tv_usec += 1000000; --diff->tv_sec; } return 1; } /********************************************************************** *%FUNCTION: parseForHostUniq *%ARGUMENTS: * type -- tag type * len -- tag length * data -- tag data. * extra -- user-supplied pointer. This is assumed to be a pointer to int. *%RETURNS: * Nothing *%DESCRIPTION: * If a HostUnique tag is found which matches our PID, sets *extra to 1. ***********************************************************************/ static void parseForHostUniq(UINT16_t type, UINT16_t len, unsigned char *data, void *extra) { PPPoETag *tag = extra; if (type == TAG_HOST_UNIQ && len == ntohs(tag->length)) tag->length = memcmp(data, tag->payload, len); } /********************************************************************** *%FUNCTION: packetIsForMe *%ARGUMENTS: * conn -- PPPoE connection info * packet -- a received PPPoE packet *%RETURNS: * 1 if packet is for this PPPoE daemon; 0 otherwise. *%DESCRIPTION: * If we are using the Host-Unique tag, verifies that packet contains * our unique identifier. ***********************************************************************/ static int packetIsForMe(PPPoEConnection *conn, PPPoEPacket *packet) { PPPoETag hostUniq = conn->hostUniq; /* If packet is not directed to our MAC address, forget it */ if (memcmp(packet->ethHdr.h_dest, conn->myEth, ETH_ALEN)) return 0; /* If we're not using the Host-Unique tag, then accept the packet */ if (!conn->hostUniq.length) return 1; parsePacket(packet, parseForHostUniq, &hostUniq); return !hostUniq.length; } /********************************************************************** *%FUNCTION: parsePADOTags *%ARGUMENTS: * type -- tag type * len -- tag length * data -- tag data * extra -- extra user data. Should point to a PacketCriteria structure * which gets filled in according to selected AC name and service * name. *%RETURNS: * Nothing *%DESCRIPTION: * Picks interesting tags out of a PADO packet ***********************************************************************/ static void parsePADOTags(UINT16_t type, UINT16_t len, unsigned char *data, void *extra) { struct PacketCriteria *pc = (struct PacketCriteria *) extra; PPPoEConnection *conn = pc->conn; UINT16_t mru; int i; switch(type) { case TAG_AC_NAME: pc->seenACName = 1; if (pppoe_verbose >= 1) { info("Access-Concentrator: %.*s", (int) len, data); } if (conn->acName && len == strlen(conn->acName) && !strncmp((char *) data, conn->acName, len)) { pc->acNameOK = 1; } break; case TAG_SERVICE_NAME: pc->seenServiceName = 1; if (pppoe_verbose >= 1 && len > 0) { info("Service-Name: %.*s", (int) len, data); } if (conn->serviceName && len == strlen(conn->serviceName) && !strncmp((char *) data, conn->serviceName, len)) { pc->serviceNameOK = 1; } break; case TAG_AC_COOKIE: if (pppoe_verbose >= 1) { char buffer[100]; char *ptr = buffer; ptr += sprintf(ptr, "Cookie:"); /* Print first 20 bytes of cookie */ for (i=0; idiscoveryState != STATE_RECEIVED_PADO) { conn->cookie.type = htons(type); conn->cookie.length = htons(len); memcpy(conn->cookie.payload, data, len); } break; case TAG_RELAY_SESSION_ID: if (pppoe_verbose >= 1) { char buffer[100]; char *ptr = buffer; ptr += sprintf(ptr, "Relay-ID:"); /* Print first 20 bytes of relay ID */ for (i=0; idiscoveryState != STATE_RECEIVED_PADO) { conn->relayId.type = htons(type); conn->relayId.length = htons(len); memcpy(conn->relayId.payload, data, len); } break; case TAG_PPP_MAX_PAYLOAD: if (len == sizeof(mru)) { memcpy(&mru, data, sizeof(mru)); mru = ntohs(mru); info("Max-Payload: %u", (unsigned) mru); if (mru >= ETH_PPPOE_MTU && conn->discoveryState != STATE_RECEIVED_PADO) { if (conn->mtu > mru) conn->mtu = mru; if (conn->mru > mru) conn->mru = mru; conn->seenMaxPayload = 1; } } break; case TAG_SERVICE_NAME_ERROR: error("PADO: Service-Name-Error: %.*s", (int) len, data); conn->error = 1; break; case TAG_AC_SYSTEM_ERROR: error("PADO: System-Error: %.*s", (int) len, data); conn->error = 1; break; case TAG_GENERIC_ERROR: error("PADO: Generic-Error: %.*s", (int) len, data); conn->error = 1; break; } } /********************************************************************** *%FUNCTION: parsePADSTags *%ARGUMENTS: * type -- tag type * len -- tag length * data -- tag data * extra -- extra user data (pointer to PPPoEConnection structure) *%RETURNS: * Nothing *%DESCRIPTION: * Picks interesting tags out of a PADS packet ***********************************************************************/ static void parsePADSTags(UINT16_t type, UINT16_t len, unsigned char *data, void *extra) { PPPoEConnection *conn = (PPPoEConnection *) extra; UINT16_t mru; switch(type) { case TAG_SERVICE_NAME: if (pppoe_verbose >= 1 && len > 0) { info("PADS: Service-Name: '%.*s'", (int) len, data); } break; case TAG_PPP_MAX_PAYLOAD: if (len == sizeof(mru)) { memcpy(&mru, data, sizeof(mru)); mru = ntohs(mru); if (mru >= ETH_PPPOE_MTU) { if (conn->mtu > mru) conn->mtu = mru; if (conn->mru > mru) conn->mru = mru; conn->seenMaxPayload = 1; } } break; case TAG_SERVICE_NAME_ERROR: error("PADS: Service-Name-Error: %.*s", (int) len, data); conn->error = 1; break; case TAG_AC_SYSTEM_ERROR: error("PADS: System-Error: %.*s", (int) len, data); conn->error = 1; break; case TAG_GENERIC_ERROR: error("PADS: Generic-Error: %.*s", (int) len, data); conn->error = 1; break; case TAG_RELAY_SESSION_ID: conn->relayId.type = htons(type); conn->relayId.length = htons(len); memcpy(conn->relayId.payload, data, len); break; } } /*********************************************************************** *%FUNCTION: sendPADI *%ARGUMENTS: * conn -- PPPoEConnection structure *%RETURNS: * Nothing *%DESCRIPTION: * Sends a PADI packet ***********************************************************************/ static void sendPADI(PPPoEConnection *conn) { PPPoEPacket packet; unsigned char *cursor = packet.payload; PPPoETag *svc = (PPPoETag *) (&packet.payload); UINT16_t namelen = 0; UINT16_t plen; int omit_service_name = 0; if (conn->serviceName) { namelen = (UINT16_t) strlen(conn->serviceName); if (!strcmp(conn->serviceName, "NO-SERVICE-NAME-NON-RFC-COMPLIANT")) { omit_service_name = 1; } } /* Set destination to Ethernet broadcast address */ memset(packet.ethHdr.h_dest, 0xFF, ETH_ALEN); memcpy(packet.ethHdr.h_source, conn->myEth, ETH_ALEN); packet.ethHdr.h_proto = htons(Eth_PPPOE_Discovery); packet.vertype = PPPOE_VER_TYPE(1, 1); packet.code = CODE_PADI; packet.session = 0; if (!omit_service_name) { plen = TAG_HDR_SIZE + namelen; CHECK_ROOM(cursor, packet.payload, plen); svc->type = TAG_SERVICE_NAME; svc->length = htons(namelen); if (conn->serviceName) { memcpy(svc->payload, conn->serviceName, strlen(conn->serviceName)); } cursor += namelen + TAG_HDR_SIZE; } else { plen = 0; } /* If we're using Host-Uniq, copy it over */ if (conn->hostUniq.length) { int len = ntohs(conn->hostUniq.length); CHECK_ROOM(cursor, packet.payload, len + TAG_HDR_SIZE); memcpy(cursor, &conn->hostUniq, len + TAG_HDR_SIZE); cursor += len + TAG_HDR_SIZE; plen += len + TAG_HDR_SIZE; } /* Add our maximum MTU/MRU */ if (MIN(conn->mtu, conn->mru) > ETH_PPPOE_MTU) { PPPoETag maxPayload; UINT16_t mru = htons(MIN(conn->mtu, conn->mru)); maxPayload.type = htons(TAG_PPP_MAX_PAYLOAD); maxPayload.length = htons(sizeof(mru)); memcpy(maxPayload.payload, &mru, sizeof(mru)); CHECK_ROOM(cursor, packet.payload, sizeof(mru) + TAG_HDR_SIZE); memcpy(cursor, &maxPayload, sizeof(mru) + TAG_HDR_SIZE); cursor += sizeof(mru) + TAG_HDR_SIZE; plen += sizeof(mru) + TAG_HDR_SIZE; } packet.length = htons(plen); sendPacket(conn, conn->discoverySocket, &packet, (int) (plen + HDR_SIZE)); } /********************************************************************** *%FUNCTION: waitForPADO *%ARGUMENTS: * conn -- PPPoEConnection structure * timeout -- how long to wait (in seconds) *%RETURNS: * Nothing *%DESCRIPTION: * Waits for a PADO packet and copies useful information ***********************************************************************/ void waitForPADO(PPPoEConnection *conn, int timeout) { fd_set readable; int r; struct timeval tv; struct timeval expire_at; PPPoEPacket packet; int len; struct PacketCriteria pc; pc.conn = conn; pc.acNameOK = (conn->acName) ? 0 : 1; pc.serviceNameOK = (conn->serviceName) ? 0 : 1; pc.seenACName = 0; pc.seenServiceName = 0; conn->seenMaxPayload = 0; if (get_time(&expire_at) < 0) { error("get_time (waitForPADO): %m"); return; } expire_at.tv_sec += timeout; do { if (BPF_BUFFER_IS_EMPTY) { if (!time_left(&tv, &expire_at)) return; /* Timed out */ FD_ZERO(&readable); FD_SET(conn->discoverySocket, &readable); while(1) { r = select(conn->discoverySocket+1, &readable, NULL, NULL, &tv); if (r >= 0 || errno != EINTR || signaled(SIGTERM)) break; } if (r < 0) { error("select (waitForPADO): %m"); return; } if (r == 0) return; /* Timed out */ } conn->error = 0; /* Get the packet */ receivePacket(conn->discoverySocket, &packet, &len); /* Check length */ if (ntohs(packet.length) + HDR_SIZE > len) { error("Bogus PPPoE length field (%u)", (unsigned int) ntohs(packet.length)); continue; } #ifdef USE_BPF /* If it's not a Discovery packet, loop again */ if (etherType(&packet) != Eth_PPPOE_Discovery) continue; #endif /* If it's not for us, loop again */ if (!packetIsForMe(conn, &packet)) continue; if (packet.code == CODE_PADO) { if (NOT_UNICAST(packet.ethHdr.h_source)) { error("Ignoring PADO packet from non-unicast MAC address"); continue; } if (conn->req_peer && memcmp(packet.ethHdr.h_source, conn->req_peer_mac, ETH_ALEN) != 0) { warn("Ignoring PADO packet from wrong MAC address"); continue; } if (parsePacket(&packet, parsePADOTags, &pc) < 0) continue; if (conn->error) continue; if (!pc.seenACName) { error("Ignoring PADO packet with no AC-Name tag"); continue; } if (!pc.seenServiceName) { error("Ignoring PADO packet with no Service-Name tag"); continue; } if (pppoe_verbose >= 1) { info("AC-Ethernet-Address: %02x:%02x:%02x:%02x:%02x:%02x", (unsigned) packet.ethHdr.h_source[0], (unsigned) packet.ethHdr.h_source[1], (unsigned) packet.ethHdr.h_source[2], (unsigned) packet.ethHdr.h_source[3], (unsigned) packet.ethHdr.h_source[4], (unsigned) packet.ethHdr.h_source[5]); info("--------------------------------------------------"); } conn->numPADOs++; if (pc.acNameOK && pc.serviceNameOK && conn->discoveryState != STATE_RECEIVED_PADO) { memcpy(conn->peerEth, packet.ethHdr.h_source, ETH_ALEN); conn->discoveryState = STATE_RECEIVED_PADO; } } } while (pppoe_verbose >= 1 || conn->discoveryState != STATE_RECEIVED_PADO); } /*********************************************************************** *%FUNCTION: sendPADR *%ARGUMENTS: * conn -- PPPoE connection structur *%RETURNS: * Nothing *%DESCRIPTION: * Sends a PADR packet ***********************************************************************/ static void sendPADR(PPPoEConnection *conn) { PPPoEPacket packet; PPPoETag *svc = (PPPoETag *) packet.payload; unsigned char *cursor = packet.payload; UINT16_t namelen = 0; UINT16_t plen; if (conn->serviceName) { namelen = (UINT16_t) strlen(conn->serviceName); } plen = TAG_HDR_SIZE + namelen; CHECK_ROOM(cursor, packet.payload, plen); memcpy(packet.ethHdr.h_dest, conn->peerEth, ETH_ALEN); memcpy(packet.ethHdr.h_source, conn->myEth, ETH_ALEN); packet.ethHdr.h_proto = htons(Eth_PPPOE_Discovery); packet.vertype = PPPOE_VER_TYPE(1, 1); packet.code = CODE_PADR; packet.session = 0; svc->type = TAG_SERVICE_NAME; svc->length = htons(namelen); if (conn->serviceName) { memcpy(svc->payload, conn->serviceName, namelen); } cursor += namelen + TAG_HDR_SIZE; /* If we're using Host-Uniq, copy it over */ if (conn->hostUniq.length) { int len = ntohs(conn->hostUniq.length); CHECK_ROOM(cursor, packet.payload, len+TAG_HDR_SIZE); memcpy(cursor, &conn->hostUniq, len + TAG_HDR_SIZE); cursor += len + TAG_HDR_SIZE; plen += len + TAG_HDR_SIZE; } /* Add our maximum MTU/MRU */ if (MIN(conn->mtu, conn->mru) > ETH_PPPOE_MTU) { PPPoETag maxPayload; UINT16_t mru = htons(MIN(conn->mtu, conn->mru)); maxPayload.type = htons(TAG_PPP_MAX_PAYLOAD); maxPayload.length = htons(sizeof(mru)); memcpy(maxPayload.payload, &mru, sizeof(mru)); CHECK_ROOM(cursor, packet.payload, sizeof(mru) + TAG_HDR_SIZE); memcpy(cursor, &maxPayload, sizeof(mru) + TAG_HDR_SIZE); cursor += sizeof(mru) + TAG_HDR_SIZE; plen += sizeof(mru) + TAG_HDR_SIZE; } /* Copy cookie and relay-ID if needed */ if (conn->cookie.type) { CHECK_ROOM(cursor, packet.payload, ntohs(conn->cookie.length) + TAG_HDR_SIZE); memcpy(cursor, &conn->cookie, ntohs(conn->cookie.length) + TAG_HDR_SIZE); cursor += ntohs(conn->cookie.length) + TAG_HDR_SIZE; plen += ntohs(conn->cookie.length) + TAG_HDR_SIZE; } if (conn->relayId.type) { CHECK_ROOM(cursor, packet.payload, ntohs(conn->relayId.length) + TAG_HDR_SIZE); memcpy(cursor, &conn->relayId, ntohs(conn->relayId.length) + TAG_HDR_SIZE); cursor += ntohs(conn->relayId.length) + TAG_HDR_SIZE; plen += ntohs(conn->relayId.length) + TAG_HDR_SIZE; } packet.length = htons(plen); sendPacket(conn, conn->discoverySocket, &packet, (int) (plen + HDR_SIZE)); } /********************************************************************** *%FUNCTION: waitForPADS *%ARGUMENTS: * conn -- PPPoE connection info * timeout -- how long to wait (in seconds) *%RETURNS: * Nothing *%DESCRIPTION: * Waits for a PADS packet and copies useful information ***********************************************************************/ static void waitForPADS(PPPoEConnection *conn, int timeout) { fd_set readable; int r; struct timeval tv; struct timeval expire_at; PPPoEPacket packet; int len; if (get_time(&expire_at) < 0) { error("get_time (waitForPADS): %m"); return; } expire_at.tv_sec += timeout; conn->error = 0; do { if (BPF_BUFFER_IS_EMPTY) { if (!time_left(&tv, &expire_at)) return; /* Timed out */ FD_ZERO(&readable); FD_SET(conn->discoverySocket, &readable); while(1) { r = select(conn->discoverySocket+1, &readable, NULL, NULL, &tv); if (r >= 0 || errno != EINTR || signaled(SIGTERM)) break; } if (r < 0) { error("select (waitForPADS): %m"); return; } if (r == 0) return; /* Timed out */ } /* Get the packet */ receivePacket(conn->discoverySocket, &packet, &len); /* Check length */ if (ntohs(packet.length) + HDR_SIZE > len) { error("Bogus PPPoE length field (%u)", (unsigned int) ntohs(packet.length)); continue; } #ifdef USE_BPF /* If it's not a Discovery packet, loop again */ if (etherType(&packet) != Eth_PPPOE_Discovery) continue; #endif /* If it's not from the AC, it's not for me */ if (memcmp(packet.ethHdr.h_source, conn->peerEth, ETH_ALEN)) continue; /* If it's not for us, loop again */ if (!packetIsForMe(conn, &packet)) continue; /* Is it PADS? */ if (packet.code == CODE_PADS) { /* Parse for goodies */ if (parsePacket(&packet, parsePADSTags, conn) < 0) return; if (conn->error) return; conn->discoveryState = STATE_SESSION; break; } } while (conn->discoveryState != STATE_SESSION); /* Don't bother with ntohs; we'll just end up converting it back... */ conn->session = packet.session; info("PPP session is %d", (int) ntohs(conn->session)); /* RFC 2516 says session id MUST NOT be zero or 0xFFFF */ if (ntohs(conn->session) == 0 || ntohs(conn->session) == 0xFFFF) { error("Access concentrator used a session value of %x -- the AC is violating RFC 2516", (unsigned int) ntohs(conn->session)); } } /********************************************************************** *%FUNCTION: discovery1 *%ARGUMENTS: * conn -- PPPoE connection info structure *%RETURNS: * Nothing *%DESCRIPTION: * Performs the PPPoE discovery phase 1 ***********************************************************************/ void discovery1(PPPoEConnection *conn) { int padiAttempts = 0; int timeout = conn->discoveryTimeout; do { padiAttempts++; if (signaled(SIGTERM) || padiAttempts > conn->discoveryAttempts) { warn("Timeout waiting for PADO packets"); close(conn->discoverySocket); conn->discoverySocket = -1; return; } sendPADI(conn); conn->discoveryState = STATE_SENT_PADI; waitForPADO(conn, timeout); timeout *= 2; } while (conn->discoveryState == STATE_SENT_PADI); } /********************************************************************** *%FUNCTION: discovery2 *%ARGUMENTS: * conn -- PPPoE connection info structure *%RETURNS: * Nothing *%DESCRIPTION: * Performs the PPPoE discovery phase 2 ***********************************************************************/ void discovery2(PPPoEConnection *conn) { int padrAttempts = 0; int timeout = conn->discoveryTimeout; do { padrAttempts++; if (signaled(SIGTERM) || padrAttempts > conn->discoveryAttempts) { warn("Timeout waiting for PADS packets"); close(conn->discoverySocket); conn->discoverySocket = -1; return; } sendPADR(conn); conn->discoveryState = STATE_SENT_PADR; waitForPADS(conn, timeout); timeout *= 2; } while (conn->discoveryState == STATE_SENT_PADR); if (!conn->seenMaxPayload) { /* RFC 4638: MUST limit MTU/MRU to 1492 */ if (conn->mtu > ETH_PPPOE_MTU) conn->mtu = ETH_PPPOE_MTU; if (conn->mru > ETH_PPPOE_MTU) conn->mru = ETH_PPPOE_MTU; } /* We're done. */ close(conn->discoverySocket); conn->discoverySocket = -1; conn->discoveryState = STATE_SESSION; return; } ppp-2.5.0/pppd/plugins/pppoe/if.c0000644000175000017500000001467214353435407013571 00000000000000/*********************************************************************** * * if.c * * Implementation of user-space PPPoE redirector for Linux. * * Functions for opening a raw socket and reading/writing raw Ethernet frames. * * Copyright (C) 2000 by Roaring Penguin Software Inc. * * This program may be distributed according to the terms of the GNU * General Public License, version 2 or (at your option) any later version. * ***********************************************************************/ static char const RCSID[] = "$Id: if.c,v 1.2 2008/06/09 08:34:23 paulus Exp $"; #ifdef HAVE_CONFIG_H #include "config.h" #endif #define _GNU_SOURCE 1 #include "pppoe.h" #include #ifdef HAVE_UNISTD_H #include #endif #ifdef HAVE_NETPACKET_PACKET_H #include #elif defined(HAVE_LINUX_IF_PACKET_H) #include #endif #ifdef HAVE_ASM_TYPES_H #include #endif #ifdef HAVE_SYS_IOCTL_H #include #endif #include #include #include #ifdef HAVE_NET_IF_ARP_H #include #endif /* Initialize frame types to RFC 2516 values. Some broken peers apparently use different frame types... sigh... */ UINT16_t Eth_PPPOE_Discovery = ETH_PPPOE_DISCOVERY; UINT16_t Eth_PPPOE_Session = ETH_PPPOE_SESSION; /********************************************************************** *%FUNCTION: etherType *%ARGUMENTS: * packet -- a received PPPoE packet *%RETURNS: * ethernet packet type (see /usr/include/net/ethertypes.h) *%DESCRIPTION: * Checks the ethernet packet header to determine its type. * We should only be receveing DISCOVERY and SESSION types if the BPF * is set up correctly. Logs an error if an unexpected type is received. * Note that the ethernet type names come from "pppoe.h" and the packet * packet structure names use the LINUX dialect to maintain consistency * with the rest of this file. See the BSD section of "pppoe.h" for * translations of the data structure names. ***********************************************************************/ UINT16_t etherType(PPPoEPacket *packet) { UINT16_t type = (UINT16_t) ntohs(packet->ethHdr.h_proto); if (type != Eth_PPPOE_Discovery && type != Eth_PPPOE_Session) { error("Invalid ether type 0x%x", type); } return type; } /********************************************************************** *%FUNCTION: openInterface *%ARGUMENTS: * ifname -- name of interface * type -- Ethernet frame type * hwaddr -- if non-NULL, set to the hardware address *%RETURNS: * A raw socket for talking to the Ethernet card. Exits on error. *%DESCRIPTION: * Opens a raw Ethernet socket ***********************************************************************/ int openInterface(char const *ifname, UINT16_t type, unsigned char *hwaddr) { int optval=1; int fd; struct ifreq ifr; int domain, stype; #ifdef HAVE_STRUCT_SOCKADDR_LL struct sockaddr_ll sa; #else struct sockaddr sa; #endif memset(&sa, 0, sizeof(sa)); #ifdef HAVE_STRUCT_SOCKADDR_LL domain = PF_PACKET; stype = SOCK_RAW; #else domain = PF_INET; stype = SOCK_PACKET; #endif if ((fd = socket(domain, stype, htons(type))) < 0) { /* Give a more helpful message for the common error case */ if (errno == EPERM) { fatal("Cannot create raw socket -- pppoe must be run as root."); } error("Can't open socket for pppoe: %m"); return -1; } if (setsockopt(fd, SOL_SOCKET, SO_BROADCAST, &optval, sizeof(optval)) < 0) { error("Can't set socket options for pppoe: %m"); close(fd); return -1; } /* Fill in hardware address */ if (hwaddr) { strlcpy(ifr.ifr_name, ifname, IFNAMSIZ); if (ioctl(fd, SIOCGIFHWADDR, &ifr) < 0) { error("Can't get hardware address for %s: %m", ifname); close(fd); return -1; } memcpy(hwaddr, ifr.ifr_hwaddr.sa_data, ETH_ALEN); #ifdef ARPHRD_ETHER if (ifr.ifr_hwaddr.sa_family != ARPHRD_ETHER) { warn("Interface %.16s is not Ethernet", ifname); } #endif if (NOT_UNICAST(hwaddr)) { fatal("Can't use interface %.16s: it has broadcast/multicast MAC address", ifname); } } /* Sanity check on MTU */ strlcpy(ifr.ifr_name, ifname, IFNAMSIZ); if (ioctl(fd, SIOCGIFMTU, &ifr) < 0) { error("Can't get MTU for %s: %m", ifname); } else if (ifr.ifr_mtu < ETH_DATA_LEN) { error("Interface %.16s has MTU of %d -- should be at least %d.", ifname, ifr.ifr_mtu, ETH_DATA_LEN); error("This may cause serious connection problems."); } #ifdef HAVE_STRUCT_SOCKADDR_LL /* Get interface index */ sa.sll_family = AF_PACKET; sa.sll_protocol = htons(type); strlcpy(ifr.ifr_name, ifname, IFNAMSIZ); if (ioctl(fd, SIOCGIFINDEX, &ifr) < 0) { error("Could not get interface index for %s: %m", ifname); close(fd); return -1; } sa.sll_ifindex = ifr.ifr_ifindex; #else strcpy(sa.sa_data, ifname); #endif /* We're only interested in packets on specified interface */ if (bind(fd, (struct sockaddr *) &sa, sizeof(sa)) < 0) { error("Failed to bind to interface %s: %m", ifname); close(fd); return -1; } return fd; } /*********************************************************************** *%FUNCTION: sendPacket *%ARGUMENTS: * sock -- socket to send to * pkt -- the packet to transmit * size -- size of packet (in bytes) *%RETURNS: * 0 on success; -1 on failure *%DESCRIPTION: * Transmits a packet ***********************************************************************/ int sendPacket(PPPoEConnection *conn, int sock, PPPoEPacket *pkt, int size) { int err; if (debug_on()) pppoe_log_packet("Send ", pkt); #if defined(HAVE_STRUCT_SOCKADDR_LL) err = send(sock, pkt, size, 0); #else struct sockaddr sa; strcpy(sa.sa_data, conn->ifName); err = sendto(sock, pkt, size, 0, &sa, sizeof(sa)); #endif if (err < 0) { error("error sending pppoe packet: %m"); return -1; } return 0; } /*********************************************************************** *%FUNCTION: receivePacket *%ARGUMENTS: * sock -- socket to read from * pkt -- place to store the received packet * size -- set to size of packet in bytes *%RETURNS: * >= 0 if all OK; < 0 if error *%DESCRIPTION: * Receives a packet ***********************************************************************/ int receivePacket(int sock, PPPoEPacket *pkt, int *size) { if ((*size = recv(sock, pkt, sizeof(PPPoEPacket), 0)) < 0) { error("error receiving pppoe packet: %m"); return -1; } if (debug_on()) pppoe_log_packet("Recv ", pkt); return 0; } ppp-2.5.0/pppd/plugins/pppoe/common.c0000664000175000017500000002204614273050614014451 00000000000000/*********************************************************************** * * common.c * * Implementation of user-space PPPoE redirector for Linux. * * Common functions used by PPPoE client and server * * Copyright (C) 2000 by Roaring Penguin Software Inc. * * This program may be distributed according to the terms of the GNU * General Public License, version 2 or (at your option) any later version. * ***********************************************************************/ static char const RCSID[] = "$Id: common.c,v 1.3 2008/06/09 08:34:23 paulus Exp $"; #ifdef HAVE_CONFIG_H #include "config.h" #endif #define _GNU_SOURCE 1 #include "pppoe.h" #include #include #include #include #include /* for LOG_DEBUG */ #include #ifdef HAVE_UNISTD_H #include #endif /********************************************************************** *%FUNCTION: parsePacket *%ARGUMENTS: * packet -- the PPPoE discovery packet to parse * func -- function called for each tag in the packet * extra -- an opaque data pointer supplied to parsing function *%RETURNS: * 0 if everything went well; -1 if there was an error *%DESCRIPTION: * Parses a PPPoE discovery packet, calling "func" for each tag in the packet. * "func" is passed the additional argument "extra". ***********************************************************************/ int parsePacket(PPPoEPacket *packet, ParseFunc *func, void *extra) { UINT16_t len = ntohs(packet->length); unsigned char *curTag; UINT16_t tagType, tagLen; if (PPPOE_VER(packet->vertype) != 1) { error("Invalid PPPoE version (%d)", PPPOE_VER(packet->vertype)); return -1; } if (PPPOE_TYPE(packet->vertype) != 1) { error("Invalid PPPoE type (%d)", PPPOE_TYPE(packet->vertype)); return -1; } /* Do some sanity checks on packet */ if (len > ETH_JUMBO_LEN - PPPOE_OVERHEAD) { /* 6-byte overhead for PPPoE header */ error("Invalid PPPoE packet length (%u)", len); return -1; } /* Step through the tags */ curTag = packet->payload; while (curTag - packet->payload + TAG_HDR_SIZE <= len) { /* Alignment is not guaranteed, so do this by hand... */ tagType = (curTag[0] << 8) + curTag[1]; tagLen = (curTag[2] << 8) + curTag[3]; if (tagType == TAG_END_OF_LIST) { return 0; } if ((curTag - packet->payload) + tagLen + TAG_HDR_SIZE > len) { error("Invalid PPPoE tag length (%u)", tagLen); return -1; } func(tagType, tagLen, curTag+TAG_HDR_SIZE, extra); curTag = curTag + TAG_HDR_SIZE + tagLen; } return 0; } /*********************************************************************** *%FUNCTION: sendPADT *%ARGUMENTS: * conn -- PPPoE connection * msg -- if non-NULL, extra error message to include in PADT packet. *%RETURNS: * Nothing *%DESCRIPTION: * Sends a PADT packet ***********************************************************************/ void sendPADT(PPPoEConnection *conn, char const *msg) { PPPoEPacket packet; unsigned char *cursor = packet.payload; UINT16_t plen = 0; /* Do nothing if no session established yet */ if (!conn->session) return; /* Do nothing if no discovery socket */ if (conn->discoverySocket < 0) return; memcpy(packet.ethHdr.h_dest, conn->peerEth, ETH_ALEN); memcpy(packet.ethHdr.h_source, conn->myEth, ETH_ALEN); packet.ethHdr.h_proto = htons(Eth_PPPOE_Discovery); packet.vertype = PPPOE_VER_TYPE(1, 1); packet.code = CODE_PADT; packet.session = conn->session; /* Reset Session to zero so there is no possibility of recursive calls to this function by any signal handler */ conn->session = 0; /* If we're using Host-Uniq, copy it over */ if (conn->hostUniq.length) { int len = ntohs(conn->hostUniq.length); memcpy(cursor, &conn->hostUniq, len + TAG_HDR_SIZE); cursor += len + TAG_HDR_SIZE; plen += len + TAG_HDR_SIZE; } /* Copy error message */ if (msg) { PPPoETag err; size_t elen = strlen(msg); err.type = htons(TAG_GENERIC_ERROR); err.length = htons(elen); strcpy((char*) err.payload, msg); memcpy(cursor, &err, elen + TAG_HDR_SIZE); cursor += elen + TAG_HDR_SIZE; plen += elen + TAG_HDR_SIZE; } /* Copy cookie and relay-ID if needed */ if (conn->cookie.type) { CHECK_ROOM(cursor, packet.payload, ntohs(conn->cookie.length) + TAG_HDR_SIZE); memcpy(cursor, &conn->cookie, ntohs(conn->cookie.length) + TAG_HDR_SIZE); cursor += ntohs(conn->cookie.length) + TAG_HDR_SIZE; plen += ntohs(conn->cookie.length) + TAG_HDR_SIZE; } if (conn->relayId.type) { CHECK_ROOM(cursor, packet.payload, ntohs(conn->relayId.length) + TAG_HDR_SIZE); memcpy(cursor, &conn->relayId, ntohs(conn->relayId.length) + TAG_HDR_SIZE); cursor += ntohs(conn->relayId.length) + TAG_HDR_SIZE; plen += ntohs(conn->relayId.length) + TAG_HDR_SIZE; } packet.length = htons(plen); sendPacket(conn, conn->discoverySocket, &packet, (int) (plen + HDR_SIZE)); info("Sent PADT"); } static void pppoe_printpkt_hex(void (*printer)(void *, char *, ...), void *arg, unsigned char const *buf, int len) { int i; int base; /* do NOT dump PAP packets */ if (len >= 2 && buf[0] == 0xC0 && buf[1] == 0x23) { printer(arg, "(PAP Authentication Frame -- Contents not dumped)\n"); return; } for (base=0; baselength); int i, j, tag, tlen, text; switch (ntohs(packet->ethHdr.h_proto)) { case ETH_PPPOE_DISCOVERY: printer(arg, "PPPOE Discovery V%dT%d ", PPPOE_VER(packet->vertype), PPPOE_TYPE(packet->vertype)); switch (packet->code) { case CODE_PADI: printer(arg, "PADI"); break; case CODE_PADO: printer(arg, "PADO"); break; case CODE_PADR: printer(arg, "PADR"); break; case CODE_PADS: printer(arg, "PADS"); break; case CODE_PADT: printer(arg, "PADT"); break; default: printer(arg, "unknown code %x", packet->code); } printer(arg, " session 0x%x length %d\n", ntohs(packet->session), len); break; case ETH_PPPOE_SESSION: printer(arg, "PPPOE Session V%dT%d", PPPOE_VER(packet->vertype), PPPOE_TYPE(packet->vertype)); printer(arg, " code 0x%x session 0x%x length %d\n", packet->code, ntohs(packet->session), len); break; default: printer(arg, "Unknown ethernet frame with proto = 0x%x\n", ntohs(packet->ethHdr.h_proto)); } printer(arg, " dst %02x:%02x:%02x:%02x:%02x:%02x ", EH(packet->ethHdr.h_dest)); printer(arg, " src %02x:%02x:%02x:%02x:%02x:%02x\n", EH(packet->ethHdr.h_source)); if (pppoe_verbose >= 2) pppoe_printpkt_hex(printer, arg, packet->payload, ntohs(packet->length)); if (ntohs(packet->ethHdr.h_proto) != ETH_PPPOE_DISCOVERY) return; for (i = 0; i + TAG_HDR_SIZE <= len; i += tlen) { tag = (packet->payload[i] << 8) + packet->payload[i+1]; tlen = (packet->payload[i+2] << 8) + packet->payload[i+3]; if (i + tlen + TAG_HDR_SIZE > len) break; text = 0; i += TAG_HDR_SIZE; printer(arg, " ["); switch (tag) { case TAG_END_OF_LIST: printer(arg, "end-of-list"); break; case TAG_SERVICE_NAME: printer(arg, "service-name"); text = 1; break; case TAG_AC_NAME: printer(arg, "AC-name"); text = 1; break; case TAG_HOST_UNIQ: printer(arg, "host-uniq"); break; case TAG_AC_COOKIE: printer(arg, "AC-cookie"); break; case TAG_VENDOR_SPECIFIC: printer(arg, "vendor-specific"); break; case TAG_RELAY_SESSION_ID: printer(arg, "relay-session-id"); break; case TAG_PPP_MAX_PAYLOAD: printer(arg, "PPP-max-payload"); break; case TAG_SERVICE_NAME_ERROR: printer(arg, "service-name-error"); text = 1; break; case TAG_AC_SYSTEM_ERROR: printer(arg, "AC-system-error"); text = 1; break; case TAG_GENERIC_ERROR: printer(arg, "generic-error"); text = 1; break; default: printer(arg, "unknown tag 0x%x", tag); } if (tlen) { /* If it is supposed to be text, make sure it's all printing chars */ if (text) { for (j = 0; j < tlen; ++j) { if (!isprint(packet->payload[i+j])) { text = 0; break; } } } if (text) printer(arg, " %.*s", tlen, &packet->payload[i]); else { for (j = 0; j < tlen && j < 32; j++) printer(arg, " %02x", (unsigned) *(&packet->payload[i]+j)); if (j < tlen) printer(arg, "... (length %d)", tlen); } } printer(arg, "]"); } printer(arg, "\n"); } void pppoe_log_packet(const char *prefix, PPPoEPacket *packet) { init_pr_log(prefix, LOG_DEBUG); pppoe_printpkt(packet, pr_log, NULL); end_pr_log(); } ppp-2.5.0/pppd/plugins/pppoe/pppoe-discovery.c0000644000175000017500000001354314353435407016317 00000000000000/* * Perform PPPoE discovery * * Copyright (C) 2000-2001 by Roaring Penguin Software Inc. * Copyright (C) 2004 Marco d'Itri * * This program may be distributed according to the terms of the GNU * General Public License, version 2 or (at your option) any later version. * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include #include #include #include #include #include "pppoe.h" int debug; int got_sigterm; int pppoe_verbose; static FILE *debugFile; void fatal(char *fmt, ...) { va_list pvar; va_start(pvar, fmt); vfprintf(stderr, fmt, pvar); va_end(pvar); fputc('\n', stderr); exit(1); } void error(char *fmt, ...) { va_list pvar; va_start(pvar, fmt); vfprintf(stderr, fmt, pvar); fputc('\n', stderr); va_end(pvar); } void warn(char *fmt, ...) { va_list pvar; va_start(pvar, fmt); vfprintf(stderr, fmt, pvar); fputc('\n', stderr); va_end(pvar); } void info(char *fmt, ...) { va_list pvar; va_start(pvar, fmt); vprintf(fmt, pvar); putchar('\n'); va_end(pvar); } void init_pr_log(const char *prefix, int level) { } void end_pr_log(void) { fflush(debugFile); } void pr_log(void *arg, char *fmt, ...) { va_list ap; va_start(ap, fmt); vfprintf(debugFile, fmt, ap); va_end(ap); } size_t strlcpy(char *dest, const char *src, size_t len) { size_t ret = strlen(src); if (len != 0) { if (ret < len) strcpy(dest, src); else { strncpy(dest, src, len - 1); dest[len-1] = 0; } } return ret; } static char * xstrdup(const char *s) { char *ret = strdup(s); if (!ret) { perror("strdup"); exit(1); } return ret; } int get_time(struct timeval *tv) { return gettimeofday(tv, NULL); } int signaled(int signal) { if (signal == SIGTERM) return got_sigterm; return 0; } bool debug_on() { return !!debug; } static void term_handler(int signum) { got_sigterm = 1; } static void usage(void); int main(int argc, char *argv[]) { int opt; PPPoEConnection *conn; signal(SIGINT, term_handler); signal(SIGTERM, term_handler); conn = malloc(sizeof(PPPoEConnection)); if (!conn) { perror("malloc"); exit(1); } memset(conn, 0, sizeof(PPPoEConnection)); pppoe_verbose = 1; conn->discoveryTimeout = PADI_TIMEOUT; conn->discoveryAttempts = MAX_PADI_ATTEMPTS; while ((opt = getopt(argc, argv, "I:D:VUQS:C:W:t:a:h")) > 0) { switch(opt) { case 'S': conn->serviceName = xstrdup(optarg); break; case 'C': conn->acName = xstrdup(optarg); break; case 't': if (sscanf(optarg, "%d", &conn->discoveryTimeout) != 1) { fprintf(stderr, "Illegal argument to -t: Should be -t timeout\n"); exit(EXIT_FAILURE); } if (conn->discoveryTimeout < 1) { conn->discoveryTimeout = 1; } break; case 'a': if (sscanf(optarg, "%d", &conn->discoveryAttempts) != 1) { fprintf(stderr, "Illegal argument to -a: Should be -a attempts\n"); exit(EXIT_FAILURE); } if (conn->discoveryAttempts < 1) { conn->discoveryAttempts = 1; } break; case 'U': if(conn->hostUniq.length) { fprintf(stderr, "-U and -W are mutually exclusive\n"); exit(EXIT_FAILURE); } else { pid_t pid = getpid(); conn->hostUniq.type = htons(TAG_HOST_UNIQ); conn->hostUniq.length = htons(sizeof(pid)); memcpy(conn->hostUniq.payload, &pid, sizeof(pid)); } break; case 'W': if(conn->hostUniq.length) { fprintf(stderr, "-U and -W are mutually exclusive\n"); exit(EXIT_FAILURE); } if (!parseHostUniq(optarg, &conn->hostUniq)) { fprintf(stderr, "Invalid host-uniq argument: %s\n", optarg); exit(EXIT_FAILURE); } break; case 'D': pppoe_verbose = 2; debug = 1; debugFile = fopen(optarg, "w"); if (!debugFile) { fprintf(stderr, "Could not open %s: %s\n", optarg, strerror(errno)); exit(1); } fprintf(debugFile, "pppoe-discovery from pppd %s\n", PPPD_VERSION); break; case 'I': conn->ifName = xstrdup(optarg); break; case 'Q': pppoe_verbose = 0; break; case 'V': case 'h': usage(); exit(0); default: usage(); exit(1); } } if (optind != argc) { fprintf(stderr, "%s: extra argument '%s'\n", argv[0], argv[optind]); usage(); exit(EXIT_FAILURE); } if (!conn->ifName) { fprintf(stderr, "Interface was not specified\n"); exit(EXIT_FAILURE); } conn->sessionSocket = -1; conn->discoverySocket = openInterface(conn->ifName, Eth_PPPOE_Discovery, conn->myEth); if (conn->discoverySocket < 0) { perror("Cannot create PPPoE discovery socket"); exit(1); } discovery1(conn); if (!conn->numPADOs) exit(1); else exit(0); } static void usage(void) { fprintf(stderr, "Usage: pppoe-discovery [options]\n"); fprintf(stderr, "Options:\n"); fprintf(stderr, " -I if_name -- Specify interface (mandatory option)\n"); fprintf(stderr, " -D filename -- Log debugging information in filename.\n"); fprintf(stderr, " -t timeout -- Initial timeout for discovery packets in seconds\n" " -a attempts -- Number of discovery attempts\n" " -V -- Print version and exit.\n" " -Q -- Quit Mode: Do not print access concentrator names\n" " -S name -- Set desired service name.\n" " -C name -- Set desired access concentrator name.\n" " -U -- Use Host-Unique to allow multiple PPPoE sessions.\n" " -W hexvalue -- Set the Host-Unique to the supplied hex string.\n" " -h -- Print usage information.\n"); fprintf(stderr, "\npppoe-discovery from pppd " PPPD_VERSION "\n"); } ppp-2.5.0/pppd/plugins/pppoatm/0000755000175000017500000000000014412736275013435 500000000000000ppp-2.5.0/pppd/plugins/pppoatm/Makefile.am0000664000175000017500000000060214273050614015400 00000000000000pppd_plugin_LTLIBRARIES = pppoatm.la pppd_plugindir = $(PPPD_PLUGIN_DIR) noinst_HEADERS = \ atm.h \ atmres.h \ atmsap.h pppoatm_la_CPPFLAGS = -I${top_srcdir} pppoatm_la_LDFLAGS = -module -avoid-version pppoatm_la_SOURCES = pppoatm.c if WITH_LIBATM pppoatm_la_LIBADD = -latm else pppoatm_la_SOURCES += text2qos.c text2atm.c misc.c ans.c pppoatm_la_LIBADD = -lresolv endif ppp-2.5.0/pppd/plugins/pppoatm/atm.h0000644000175000017500000000601511043063522014272 00000000000000/* atm.h - Functions useful for ATM applications */ /* Written 1995-2000 by Werner Almesberger, EPFL-LRC/ICA */ #ifndef _ATM_H #define _ATM_H #include #include #include /* * For versions of glibc < 2.1 */ #ifndef AF_ATMPVC #define AF_ATMPVC 8 #endif #ifndef AF_ATMSVC #define AF_ATMSVC 20 #endif #ifndef PF_ATMPVC #define PF_ATMPVC AF_ATMPVC #endif #ifndef PF_ATMSVC #define PF_ATMSVC AF_ATMSVC #endif #ifndef SOL_ATM #define SOL_ATM 264 #endif #ifndef SOL_AAL #define SOL_AAL 265 #endif #define HOSTS_ATM "/etc/hosts.atm" /* text2atm flags */ #define T2A_PVC 1 /* address is PVC */ #define T2A_SVC 2 /* address is SVC */ #define T2A_UNSPEC 4 /* allow unspecified parts in PVC address */ #define T2A_WILDCARD 8 /* allow wildcards in PVC or SVC address */ #define T2A_NNI 16 /* allow NNI VPI range (PVC) */ #define T2A_NAME 32 /* allow name resolution */ #define T2A_REMOTE 64 /* OBSOLETE */ #define T2A_LOCAL 128 /* don't use ANS */ /* atm2text flags */ #define A2T_PRETTY 1 /* add syntactic sugar */ #define A2T_NAME 2 /* attempt name lookup */ #define A2T_REMOTE 4 /* OBSOLETE */ #define A2T_LOCAL 8 /* don't use ANS */ /* atm_equal flags */ #define AXE_WILDCARD 1 /* allow wildcard match */ #define AXE_PRVOPT 2 /* private part of SVC address is optional */ /* text2qos flags */ #define T2Q_DEFAULTS 1 /* structure contains default values */ /* text2sap flags */ #define T2S_NAME 1 /* attempt name lookup */ #define T2S_LOCAL 2 /* we may support NIS or such in the future */ /* sap2text flags */ #define S2T_NAME 1 /* attempt name lookup */ #define S2T_LOCAL 2 /* we may support NIS or such in the future */ /* sap_equal flags */ #define SXE_COMPATIBLE 1 /* check for compatibility instead of identity*/ #define SXE_NEGOTIATION 2 /* allow negotiation; requires SXE_COMPATIBLE; assumes "a" defines the available capabilities */ #define SXE_RESULT 4 /* return selected SAP */ #define MAX_ATM_ADDR_LEN (2*ATM_ESA_LEN+ATM_E164_LEN+5) /* 4 dots, 1 plus */ #define MAX_ATM_NAME_LEN 256 /* wild guess */ #define MAX_ATM_QOS_LEN 116 /* 5+4+2*(3+3*(7+9)+2)+1 */ #define MAX_ATM_SAP_LEN 255 /* BHLI(27)+1+3*BLLI(L2=33,L3=41,+1)+2 */ int text2atm(const char *text,struct sockaddr *addr,int length,int flags); int atm2text(char *buffer,int length,const struct sockaddr *addr,int flags); int atm_equal(const struct sockaddr *a,const struct sockaddr *b,int len, int flags); int sdu2cell(int s,int sizes,const int *sdu_size,int *num_sdu); int text2qos(const char *text,struct atm_qos *qos,int flags); int qos2text(char *buffer,int length,const struct atm_qos *qos,int flags); int qos_equal(const struct atm_qos *a,const struct atm_qos *b); int text2sap(const char *text,struct atm_sap *sap,int flags); int sap2text(char *buffer,int length,const struct atm_sap *sap,int flags); int sap_equal(const struct atm_sap *a,const struct atm_sap *b,int flags,...); int __t2q_get_rate(const char **text,int up); int __atmlib_fetch(const char **pos,...); /* internal use only */ #endif ppp-2.5.0/pppd/plugins/pppoatm/atmres.h0000644000175000017500000000132411043063522015002 00000000000000/* atmres.h - Common definitions and prototypes for resolver functions */ /* Written 1996,1998 by Werner Almesberger, EPFL-LRC/ICA */ #ifndef _ATMRES_H #define _ATMRES_H #include #include /* Some #defines that may be needed if ANS isn't installed on that system */ #ifndef T_ATMA #define T_ATMA 34 #endif #ifndef ATMA_AESA #define ATMA_AESA 0 #endif #ifndef ATMA_E164 #define ATMA_E164 1 #endif /* Return codes for text2atm and atm2text */ #define TRY_OTHER -2 #define FATAL -1 /* must be -1 */ int ans_byname(const char *text,struct sockaddr_atmsvc *addr,int length, int flags); int ans_byaddr(char *buffer,int length,const struct sockaddr_atmsvc *addr, int flags); #endif ppp-2.5.0/pppd/plugins/pppoatm/atmsap.h0000644000175000017500000000234011043063522014773 00000000000000/* atmsap.h - ATM Service Access Point addressing definitions */ /* Written 1996-1998 by Werner Almesberger, EPFL LRC/ICA */ #ifndef _ATMSAP_H #define _ATMSAP_H #include #include /* * Selected ISO/IEC TR 9577 Network Layer Protocol Identifiers (NLPID) */ #define NLPID_IEEE802_1_SNAP 0x80 /* IEEE 802.1 SNAP */ /* * Selected Organizationally Unique Identifiers (OUIs) */ #define ATM_FORUM_OUI "\x00\xA0\x3E" /* ATM Forum */ #define EPFL_OUI "\x00\x60\xD7" /* EPF Lausanne, CH */ /* * Selected vendor-specific application identifiers (for B-HLI). Such an * identifier consists of three bytes containing the OUI, followed by four * bytes assigned by the organization owning the OUI. */ #define ANS_HLT_VS_ID ATM_FORUM_OUI "\x00\x00\x00\x01" /* ATM Name System, af-saa-0069.000 */ #define VOD_HLT_VS_ID ATM_FORUM_OUI "\x00\x00\x00\x02" /* VoD, af-saa-0049.001 */ #define AREQUIPA_HLT_VS_ID EPFL_OUI "\x01\x00\x00\x01" /* Arequipa */ #define TTCP_HLT_VS_ID EPFL_OUI "\x01\x00\x00\x03" /* ttcp_atm */ /* Mapping of "well-known" TCP, UDP, etc. port numbers to ATM BHLIs. btd-saa-api-bhli-01.02 */ void atm_tcpip_port_mapping(char *vs_id,uint8_t protocol,uint16_t port); #endif ppp-2.5.0/pppd/plugins/pppoatm/Makefile.in0000644000175000017500000007000114407475314015416 00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ @WITH_LIBATM_FALSE@am__append_1 = text2qos.c text2atm.c misc.c ans.c subdir = pppd/plugins/pppoatm ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_atm.m4 \ $(top_srcdir)/m4/ax_check_openssl.m4 \ $(top_srcdir)/m4/ax_check_openssl_func.m4 \ $(top_srcdir)/m4/ax_check_pam.m4 \ $(top_srcdir)/m4/ax_check_pcap.m4 \ $(top_srcdir)/m4/ax_check_srp.m4 $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/pkg.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(noinst_HEADERS) \ $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/pppd/config.h \ $(top_builddir)/pppd/pppdconf.h \ $(top_builddir)/pppd/plugins/pppoe/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(pppd_plugindir)" LTLIBRARIES = $(pppd_plugin_LTLIBRARIES) pppoatm_la_DEPENDENCIES = am__pppoatm_la_SOURCES_DIST = pppoatm.c text2qos.c text2atm.c misc.c \ ans.c @WITH_LIBATM_FALSE@am__objects_1 = pppoatm_la-text2qos.lo \ @WITH_LIBATM_FALSE@ pppoatm_la-text2atm.lo pppoatm_la-misc.lo \ @WITH_LIBATM_FALSE@ pppoatm_la-ans.lo am_pppoatm_la_OBJECTS = pppoatm_la-pppoatm.lo $(am__objects_1) pppoatm_la_OBJECTS = $(am_pppoatm_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = pppoatm_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(pppoatm_la_LDFLAGS) $(LDFLAGS) -o $@ AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/pppd -I$(top_builddir)/pppd/plugins/pppoe depcomp = $(SHELL) $(top_srcdir)/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/pppoatm_la-ans.Plo \ ./$(DEPDIR)/pppoatm_la-misc.Plo \ ./$(DEPDIR)/pppoatm_la-pppoatm.Plo \ ./$(DEPDIR)/pppoatm_la-text2atm.Plo \ ./$(DEPDIR)/pppoatm_la-text2qos.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(pppoatm_la_SOURCES) DIST_SOURCES = $(am__pppoatm_la_SOURCES_DIST) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac HEADERS = $(noinst_HEADERS) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp COPYING DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ ATM_CFLAGS = @ATM_CFLAGS@ ATM_LDFLAGS = @ATM_LDFLAGS@ ATM_LIBS = @ATM_LIBS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CRYPT_LIBS = @CRYPT_LIBS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GREP = @GREP@ GTK_CFLAGS = @GTK_CFLAGS@ GTK_LIBS = @GTK_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_INCLUDES = @OPENSSL_INCLUDES@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAM_CFLAGS = @PAM_CFLAGS@ PAM_LDFLAGS = @PAM_LDFLAGS@ PAM_LIBS = @PAM_LIBS@ PATH_SEPARATOR = @PATH_SEPARATOR@ PCAP_CFLAGS = @PCAP_CFLAGS@ PCAP_LDFLAGS = @PCAP_LDFLAGS@ PCAP_LIBS = @PCAP_LIBS@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PPPD_LOGFILE_DIR = @PPPD_LOGFILE_DIR@ PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@ PPPD_RUNTIME_DIR = @PPPD_RUNTIME_DIR@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SRP_CFLAGS = @SRP_CFLAGS@ SRP_LDFLAGS = @SRP_LDFLAGS@ SRP_LIBS = @SRP_LIBS@ STRIP = @STRIP@ SYSTEMD_CFLAGS = @SYSTEMD_CFLAGS@ SYSTEMD_LIBS = @SYSTEMD_LIBS@ SYSTEM_CA_PATH = @SYSTEM_CA_PATH@ UTIL_LIBS = @UTIL_LIBS@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ pppd_plugin_LTLIBRARIES = pppoatm.la pppd_plugindir = $(PPPD_PLUGIN_DIR) noinst_HEADERS = \ atm.h \ atmres.h \ atmsap.h pppoatm_la_CPPFLAGS = -I${top_srcdir} pppoatm_la_LDFLAGS = -module -avoid-version pppoatm_la_SOURCES = pppoatm.c $(am__append_1) @WITH_LIBATM_FALSE@pppoatm_la_LIBADD = -lresolv @WITH_LIBATM_TRUE@pppoatm_la_LIBADD = -latm all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu pppd/plugins/pppoatm/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu pppd/plugins/pppoatm/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-pppd_pluginLTLIBRARIES: $(pppd_plugin_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(pppd_plugin_LTLIBRARIES)'; test -n "$(pppd_plugindir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(pppd_plugindir)'"; \ $(MKDIR_P) "$(DESTDIR)$(pppd_plugindir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(pppd_plugindir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(pppd_plugindir)"; \ } uninstall-pppd_pluginLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(pppd_plugin_LTLIBRARIES)'; test -n "$(pppd_plugindir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(pppd_plugindir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(pppd_plugindir)/$$f"; \ done clean-pppd_pluginLTLIBRARIES: -test -z "$(pppd_plugin_LTLIBRARIES)" || rm -f $(pppd_plugin_LTLIBRARIES) @list='$(pppd_plugin_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } pppoatm.la: $(pppoatm_la_OBJECTS) $(pppoatm_la_DEPENDENCIES) $(EXTRA_pppoatm_la_DEPENDENCIES) $(AM_V_CCLD)$(pppoatm_la_LINK) -rpath $(pppd_plugindir) $(pppoatm_la_OBJECTS) $(pppoatm_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pppoatm_la-ans.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pppoatm_la-misc.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pppoatm_la-pppoatm.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pppoatm_la-text2atm.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pppoatm_la-text2qos.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< pppoatm_la-pppoatm.lo: pppoatm.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppoatm_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pppoatm_la-pppoatm.lo -MD -MP -MF $(DEPDIR)/pppoatm_la-pppoatm.Tpo -c -o pppoatm_la-pppoatm.lo `test -f 'pppoatm.c' || echo '$(srcdir)/'`pppoatm.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pppoatm_la-pppoatm.Tpo $(DEPDIR)/pppoatm_la-pppoatm.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pppoatm.c' object='pppoatm_la-pppoatm.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppoatm_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pppoatm_la-pppoatm.lo `test -f 'pppoatm.c' || echo '$(srcdir)/'`pppoatm.c pppoatm_la-text2qos.lo: text2qos.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppoatm_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pppoatm_la-text2qos.lo -MD -MP -MF $(DEPDIR)/pppoatm_la-text2qos.Tpo -c -o pppoatm_la-text2qos.lo `test -f 'text2qos.c' || echo '$(srcdir)/'`text2qos.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pppoatm_la-text2qos.Tpo $(DEPDIR)/pppoatm_la-text2qos.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='text2qos.c' object='pppoatm_la-text2qos.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppoatm_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pppoatm_la-text2qos.lo `test -f 'text2qos.c' || echo '$(srcdir)/'`text2qos.c pppoatm_la-text2atm.lo: text2atm.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppoatm_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pppoatm_la-text2atm.lo -MD -MP -MF $(DEPDIR)/pppoatm_la-text2atm.Tpo -c -o pppoatm_la-text2atm.lo `test -f 'text2atm.c' || echo '$(srcdir)/'`text2atm.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pppoatm_la-text2atm.Tpo $(DEPDIR)/pppoatm_la-text2atm.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='text2atm.c' object='pppoatm_la-text2atm.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppoatm_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pppoatm_la-text2atm.lo `test -f 'text2atm.c' || echo '$(srcdir)/'`text2atm.c pppoatm_la-misc.lo: misc.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppoatm_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pppoatm_la-misc.lo -MD -MP -MF $(DEPDIR)/pppoatm_la-misc.Tpo -c -o pppoatm_la-misc.lo `test -f 'misc.c' || echo '$(srcdir)/'`misc.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pppoatm_la-misc.Tpo $(DEPDIR)/pppoatm_la-misc.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='misc.c' object='pppoatm_la-misc.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppoatm_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pppoatm_la-misc.lo `test -f 'misc.c' || echo '$(srcdir)/'`misc.c pppoatm_la-ans.lo: ans.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppoatm_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pppoatm_la-ans.lo -MD -MP -MF $(DEPDIR)/pppoatm_la-ans.Tpo -c -o pppoatm_la-ans.lo `test -f 'ans.c' || echo '$(srcdir)/'`ans.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pppoatm_la-ans.Tpo $(DEPDIR)/pppoatm_la-ans.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ans.c' object='pppoatm_la-ans.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppoatm_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pppoatm_la-ans.lo `test -f 'ans.c' || echo '$(srcdir)/'`ans.c mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) $(HEADERS) installdirs: for dir in "$(DESTDIR)$(pppd_plugindir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-pppd_pluginLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/pppoatm_la-ans.Plo -rm -f ./$(DEPDIR)/pppoatm_la-misc.Plo -rm -f ./$(DEPDIR)/pppoatm_la-pppoatm.Plo -rm -f ./$(DEPDIR)/pppoatm_la-text2atm.Plo -rm -f ./$(DEPDIR)/pppoatm_la-text2qos.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-pppd_pluginLTLIBRARIES install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/pppoatm_la-ans.Plo -rm -f ./$(DEPDIR)/pppoatm_la-misc.Plo -rm -f ./$(DEPDIR)/pppoatm_la-pppoatm.Plo -rm -f ./$(DEPDIR)/pppoatm_la-text2atm.Plo -rm -f ./$(DEPDIR)/pppoatm_la-text2qos.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-pppd_pluginLTLIBRARIES .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-pppd_pluginLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-pppd_pluginLTLIBRARIES install-ps \ install-ps-am install-strip installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am uninstall-pppd_pluginLTLIBRARIES .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: ppp-2.5.0/pppd/plugins/pppoatm/COPYING0000644000175000017500000000047111043063522014373 00000000000000The files ans.c, atm.h, atmres.h, atmsap.h, misc.c, text2atm.c and text2qos.c are taken from the linux-atm libraries. These are Copyright 1995-2000 EPFL-LRC/ICA, and are licensed under the GNU Lesser General Public License. The file pppoatm.c contains its own copyright notice, and is licensed under the GPL. ppp-2.5.0/pppd/plugins/pppoatm/pppoatm.c0000644000175000017500000001316514407475306015206 00000000000000/* pppoatm.c - pppd plugin to implement PPPoATM protocol. * * Copyright 2000 Mitchell Blank Jr. * Based in part on work from Jens Axboe and Paul Mackerras. * Updated to ppp-2.4.1 by Bernhard Kaindl * * Updated to ppp-2.4.2 by David Woodhouse 2004. * - disconnect method added * - remove_options() abuse removed. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* Needed for lcp.h to include cleanly */ #include const char pppd_version[] = PPPD_VERSION; static struct sockaddr_atmpvc pvcaddr; static char *qosstr = NULL; static bool llc_encaps = 0; static bool vc_encaps = 0; static int device_got_set = 0; static int pppoatm_max_mtu, pppoatm_max_mru; static int setdevname_pppoatm(const char *cp, const char **argv, int doit); struct channel pppoa_channel; static int pppoa_fd = -1; static char devnam[MAXNAMELEN]; static struct option pppoa_options[] = { { "device name", o_wild, (void *) &setdevname_pppoatm, "ATM service provider IDs: VPI.VCI", OPT_DEVNAM | OPT_PRIVFIX | OPT_NOARG | OPT_A2STRVAL | OPT_STATIC, devnam}, { "llc-encaps", o_bool, &llc_encaps, "use LLC encapsulation for PPPoATM", 1}, { "vc-encaps", o_bool, &vc_encaps, "use VC multiplexing for PPPoATM (default)", 1}, { "qos", o_string, &qosstr, "set QoS for PPPoATM connection", 1}, { NULL } }; /* returns: * -1 if there's a problem with setting the device * 0 if we can't parse "cp" as a valid name of a device * 1 if "cp" is a reasonable thing to name a device * Note that we don't actually open the device at this point * We do need to fill in: * devnam: a string representation of the device * devstat: a stat structure of the device. In this case * we're not opening a device, so we just make sure * to set up S_ISCHR(devstat.st_mode) != 1, so we * don't get confused that we're on stdin. */ int (*old_setdevname_hook)(const char* cp) = NULL; static int setdevname_pppoatm(const char *cp, const char **argv, int doit) { struct sockaddr_atmpvc addr; extern struct stat devstat; if (device_got_set) return 0; memset(&addr, 0, sizeof addr); if (text2atm(cp, (struct sockaddr *) &addr, sizeof(addr), T2A_PVC | T2A_NAME | T2A_WILDCARD) < 0) { if (doit) info("cannot parse the ATM address: %s", cp); return 0; } if (!doit) return 1; memcpy(&pvcaddr, &addr, sizeof pvcaddr); strlcpy(devnam, cp, sizeof(devnam)); ppp_set_devnam(devnam); devstat.st_mode = S_IFSOCK; if (the_channel != &pppoa_channel) { the_channel = &pppoa_channel; lcp_wantoptions[0].neg_accompression = 0; lcp_allowoptions[0].neg_accompression = 0; lcp_wantoptions[0].neg_asyncmap = 0; lcp_allowoptions[0].neg_asyncmap = 0; lcp_wantoptions[0].neg_pcompression = 0; } device_got_set = 1; return 1; } #define pppoatm_overhead() (llc_encaps ? 6 : 2) static void no_device_given_pppoatm(void) { fatal("No vpi.vci specified"); } static void set_line_discipline_pppoatm(int fd) { struct atm_backend_ppp be; be.backend_num = ATM_BACKEND_PPP; if (!llc_encaps) be.encaps = PPPOATM_ENCAPS_VC; else if (!vc_encaps) be.encaps = PPPOATM_ENCAPS_LLC; else be.encaps = PPPOATM_ENCAPS_AUTODETECT; if (ioctl(fd, ATM_SETBACKEND, &be) < 0) fatal("ioctl(ATM_SETBACKEND): %m"); } #if 0 static void reset_line_discipline_pppoatm(int fd) { atm_backend_t be = ATM_BACKEND_RAW; /* 2.4 doesn't support this yet */ (void) ioctl(fd, ATM_SETBACKEND, &be); } #endif static int connect_pppoatm(void) { int fd; struct atm_qos qos; if (!device_got_set) no_device_given_pppoatm(); fd = socket(AF_ATMPVC, SOCK_DGRAM, 0); if (fd < 0) fatal("failed to create socket: %m"); memset(&qos, 0, sizeof qos); qos.txtp.traffic_class = qos.rxtp.traffic_class = ATM_UBR; /* TODO: support simplified QoS setting */ if (qosstr != NULL) if (text2qos(qosstr, &qos, 0)) fatal("Can't parse QoS: \"%s\""); qos.txtp.max_sdu = lcp_allowoptions[0].mru + pppoatm_overhead(); qos.rxtp.max_sdu = lcp_wantoptions[0].mru + pppoatm_overhead(); qos.aal = ATM_AAL5; if (setsockopt(fd, SOL_ATM, SO_ATMQOS, &qos, sizeof(qos)) < 0) fatal("setsockopt(SO_ATMQOS): %m"); /* TODO: accept on SVCs... */ if (connect(fd, (struct sockaddr *) &pvcaddr, sizeof(struct sockaddr_atmpvc))) fatal("connect(%s): %m", devnam); pppoatm_max_mtu = lcp_allowoptions[0].mru; pppoatm_max_mru = lcp_wantoptions[0].mru; set_line_discipline_pppoatm(fd); ppp_set_pppdevnam(devnam); pppoa_fd = fd; return fd; } static void disconnect_pppoatm(void) { close(pppoa_fd); } void plugin_init(void) { #ifdef linux extern int new_style_driver; /* From sys-linux.c */ if (!ppp_check_kernel_support() && !new_style_driver) fatal("Kernel doesn't support ppp_generic - " "needed for PPPoATM"); #else fatal("No PPPoATM support on this OS"); #endif ppp_add_options(pppoa_options); } struct channel pppoa_channel = { .options = pppoa_options, .process_extra_options = NULL, .check_options = NULL, .connect = &connect_pppoatm, .disconnect = &disconnect_pppoatm, .establish_ppp = &ppp_generic_establish, .disestablish_ppp = &ppp_generic_disestablish, .send_config = NULL, .recv_config = NULL, .close = NULL, .cleanup = NULL }; ppp-2.5.0/pppd/plugins/pppoatm/text2qos.c0000644000175000017500000000773011043063522015302 00000000000000/* text2qos.c - Converts textual representation of QOS parameters to binary encoding */ /* Written 1996-2000 by Werner Almesberger, EPFL-LRC/ICA */ #if HAVE_CONFIG_H #include #endif #include #include #include #include #include #include "atm.h" #define fetch __atmlib_fetch #define RATE_ERROR -2 int __t2q_get_rate(const char **text,int up) { const char mult[] = "kKmMgGg"; const char *multiplier; char *end; unsigned int rate,fract; int power; if (!strncmp(*text,"max",3)) { *text += 3; return ATM_MAX_PCR; } rate = strtoul(*text,&end,10); power = fract = 0; if (*end == '.') for (end++; *end && isdigit(*end); end++) { fract = fract*10+*end-48; if (--power == -9) break; } multiplier = NULL; if (*end && (multiplier = strchr(mult,*end))) { while (multiplier >= mult) { if (rate > UINT_MAX/1000) return RATE_ERROR; rate *= 1000; power += 3; multiplier -= 2; } end++; } while (power && fract) if (power < 0) { fract /= 10; power++; } else { fract *= 10; power--; } rate += fract; if (strlen(end) < 3) { if (multiplier) return RATE_ERROR; } else if (!strncmp(end,"cps",3)) end += 3; else if (!strncmp(end,"bps",3)) { rate = (rate+(up ? 8*ATM_CELL_PAYLOAD-1 : 0))/8/ ATM_CELL_PAYLOAD; end += 3; } else if (multiplier) return RATE_ERROR; if (rate > INT_MAX) return RATE_ERROR; *text = end; return rate; } static int params(const char **text,struct atm_trafprm *a, struct atm_trafprm *b) { int value; char *end; if (*(*text)++ != ':') return -1; while (1) { if (!**text) return -1; switch (fetch(text,"max_pcr=","pcr=","min_pcr=","max_sdu=","sdu=", NULL)) { case 0: if ((value = __t2q_get_rate(text,0)) == RATE_ERROR) return -1; if (a) a->max_pcr = value; if (b) b->max_pcr = value; break; case 1: if ((value = __t2q_get_rate(text,0)) == RATE_ERROR) return -1; if (a) a->pcr = value; if (b) b->pcr = value; break; case 2: if ((value = __t2q_get_rate(text,1)) == RATE_ERROR) return -1; if (value == ATM_MAX_PCR) return -1; if (a) a->min_pcr = value; if (b) b->min_pcr = value; break; case 3: case 4: value = strtol(*text,&end,10); if (value < 0) return -1; *text = end; if (a) a->max_sdu = value; if (b) b->max_sdu = value; break; default: return 0; } if (!**text) break; if (*(*text)++ != ',') return -1; } return 0; } int text2qos(const char *text,struct atm_qos *qos,int flags) { int traffic_class,aal; traffic_class = ATM_NONE; aal = ATM_NO_AAL; do { static const unsigned char aal_number[] = { ATM_AAL0, ATM_AAL5 }; int item; item = fetch(&text,"!none","ubr","cbr","vbr","abr","aal0","aal5",NULL); switch (item) { case 1: case 2: /* we don't support VBR yet */ case 4: traffic_class = item; break; case 5: case 6: aal = aal_number[item-5]; break; default: return -1; } } while (*text == ',' ? text++ : 0); if (!traffic_class) return -1; if (qos && !(flags & T2Q_DEFAULTS)) memset(qos,0,sizeof(*qos)); if (qos) qos->txtp.traffic_class = qos->rxtp.traffic_class = traffic_class; if (qos && aal) qos->aal = aal; if (!*text) return 0; if (params(&text,qos ? &qos->txtp : NULL,qos ? &qos->rxtp : NULL)) return -1; if (!*text) return 0; switch (fetch(&text,"tx","rx",NULL)) { case 0: if (!fetch(&text,":none",NULL)) { if (qos) qos->txtp.traffic_class = ATM_NONE; if (*text == ',') text++; break; } if (params(&text,qos ? &qos->txtp : NULL,NULL)) return -1; break; case 1: text -= 2; break; default: return -1; } if (!*text) return 0; if (fetch(&text,"rx",NULL)) return -1; if (!fetch(&text,":none",NULL) && qos) qos->rxtp.traffic_class = ATM_NONE; else if (params(&text,qos ? &qos->rxtp : NULL,NULL)) return -1; return *text ? -1 : 0; } ppp-2.5.0/pppd/plugins/pppoatm/text2atm.c0000644000175000017500000001511311043063522015253 00000000000000/* text2atm.c - Converts textual representation of ATM address to binary encoding */ /* Written 1995-2000 by Werner Almesberger, EPFL-LRC/ICA */ #if HAVE_CONFIG_H #include #endif #include #include #include #include #include "atm.h" #include "atmsap.h" #include "atmres.h" static int try_pvc(const char *text,struct sockaddr_atmpvc *addr,int flags) { int part[3]; int i; part[0] = part[1] = part[2] = 0; i = 0; while (1) { if (!*text) return FATAL; /* empty or ends with a dot */ if (i == 3) return TRY_OTHER; /* too long */ if (isdigit(*text)) { if (*text == '0' && isdigit(text[1])) return TRY_OTHER; /* no leading zeroes */ do { if (part[i] > INT_MAX/10) return TRY_OTHER;/* number too big */ part[i] = part[i]*10+*text++-'0'; } while (isdigit(*text)); i++; if (!*text) break; if (*text++ != '.') return TRY_OTHER; /* non-PVC character */ continue; } if (*text == '*') { if (!(flags & T2A_WILDCARD)) return FATAL; /* not allowed */ part[i++] = ATM_ITF_ANY; /* all *_ANY have the same value */ } else { if (*text != '?') return TRY_OTHER; /* invalid character */ if (!(flags & T2A_UNSPEC)) return FATAL; /* not allowed */ part[i++] = ATM_VPI_UNSPEC; /* all *_UNSPEC have the same value */ } if (!*++text) break; if (*text++ != '.') return FATAL; /* dot required */ } if (i < 2) return TRY_OTHER; /* no dots */ if (i == 2) { part[2] = part[1]; part[1] = part[0]; part[0] = 0; /* default interface */ } if (part[0] > SHRT_MAX || part[2] > ATM_MAX_VCI) return TRY_OTHER; /* too big */ if (part[1] > (flags & T2A_NNI ? ATM_MAX_VPI_NNI : ATM_MAX_VPI)) return TRY_OTHER; /* too big */ if (part[0] == ATM_VPI_UNSPEC) return FATAL; /* bad */ addr->sap_family = AF_ATMPVC; addr->sap_addr.itf = part[0]; addr->sap_addr.vpi = part[1]; addr->sap_addr.vci = part[2]; return 0; } static int do_try_nsap(const char *text,struct sockaddr_atmsvc *addr,int flags) { const char *walk; int count,pos,dot; int offset,len; char value; count = dot = 0; for (walk = text; *walk; walk++) if (isdigit(*walk)) { if (count++ == 15) break; dot = 1; } else if (*text != '.') break; else if (!dot) return FATAL; /* two dots in a row */ else dot = 0; if (*walk != ':') { pos = 0; offset = 0; } else { if (!dot || *text == '0') return FATAL; addr->sas_addr.prv[0] = ATM_AFI_E164; addr->sas_addr.prv[1] = 0; memset(addr->sas_addr.prv+1,0,8); for (pos = 18-count-1; *text; text++) { if (*text == '.') continue; if (*text == ':') break; else { if (pos & 1) addr->sas_addr.prv[pos >> 1] |= *text-'0'; else addr->sas_addr.prv[pos >> 1] = (*text-'0') << 4; pos++; } } addr->sas_addr.prv[8] |= 0xf; text++; pos++; offset = 72; } for (dot = 0; *text; text++) if (isxdigit(*text)) { if (pos == ATM_ESA_LEN*2) return TRY_OTHER; /* too long */ value = isdigit(*text) ? *text-'0' : (islower(*text) ? toupper(*text) : *text)-'A'+10; if (pos & 1) addr->sas_addr.prv[pos >> 1] |= value; else addr->sas_addr.prv[pos >> 1] = value << 4; pos++; dot = 1; } else if (*text == '/' && (flags & T2A_WILDCARD)) break; else if (*text != '.') return TRY_OTHER; else { if (!dot) return FATAL; /* two dots in a row */ dot = 0; } if (!dot) return FATAL; if (pos > 1 && !*addr->sas_addr.prv) return TRY_OTHER; /* no leading zeroes */ if (!*text) return pos != ATM_ESA_LEN*2 ? TRY_OTHER : ATM_ESA_LEN*2; /* handle bad length */ len = 0; while (*++text) { if (!isdigit(*text)) return -1; /* non-digit in length */ if (len >= pos*4) return -1; /* too long */ len = len*10+*text-'0'; } if (len > 7 && addr->sas_addr.prv[0] != ATM_AFI_E164) offset = 72; if (len < offset) return FATAL; return len > pos*4 ? TRY_OTHER : len; } static int try_nsap(const char *text,struct sockaddr_atmsvc *addr,int flags) { int result; result = do_try_nsap(text,addr,flags); if (result < 0) return result; addr->sas_family = AF_ATMSVC; *addr->sas_addr.pub = 0; return result; } static int try_e164(const char *text,struct sockaddr_atmsvc *addr,int flags) { int i,dot,result; if (*text == ':' || *text == '+') text++; for (i = dot = 0; *text; text++) if (isdigit(*text)) { if (i == ATM_E164_LEN) return TRY_OTHER; /* too long */ addr->sas_addr.pub[i++] = *text; dot = 1; } else if (*text != '.') break; else { if (!dot) return TRY_OTHER; /* two dots in a row */ dot = 0; } if (!dot) return TRY_OTHER; addr->sas_addr.pub[i] = 0; *addr->sas_addr.prv = 0; result = 0; if (*text) { if (*text++ != '+') return TRY_OTHER; else { result = do_try_nsap(text,addr,flags); if (result < 0) return FATAL; } } addr->sas_family = AF_ATMSVC; return result; } static int search(FILE *file,const char *text,struct sockaddr *addr,int length, int flags) { char line[MAX_ATM_NAME_LEN+1]; const char *here; int result; while (fgets(line,MAX_ATM_NAME_LEN,file)) { if (!strtok(line,"\t\n ")) continue; while ((here = strtok(NULL,"\t\n "))) if (!strcasecmp(here,text)) { here = strtok(line,"\t\n "); result = text2atm(here,addr,length,flags); if (result >= 0) return result; } } return TRY_OTHER; } static int try_name(const char *text,struct sockaddr *addr,int length, int flags) { FILE *file; int result; if (!(file = fopen(HOSTS_ATM,"r"))) return TRY_OTHER; result = search(file,text,addr,length,flags); (void) fclose(file); return result; } int text2atm(const char *text,struct sockaddr *addr,int length,int flags) { int result; if (!*text) return -1; if (!(flags & (T2A_PVC | T2A_SVC))) flags |= T2A_PVC | T2A_SVC; if (length < sizeof(struct sockaddr_atmpvc)) return -1; if (flags & T2A_PVC) { result = try_pvc(text,(struct sockaddr_atmpvc *) addr,flags); if (result != TRY_OTHER) return result; } if ((flags & T2A_SVC) && length >= sizeof(struct sockaddr_atmsvc)) { result = try_nsap(text,(struct sockaddr_atmsvc *) addr,flags); if (result != TRY_OTHER) return result; result = try_e164(text,(struct sockaddr_atmsvc *) addr,flags); if (result != TRY_OTHER) return result; } if (!(flags & T2A_NAME)) return -1; result = try_name(text,addr,length,flags & ~T2A_NAME); if (result == TRY_OTHER && !(flags & T2A_LOCAL)) result = ans_byname(text,(struct sockaddr_atmsvc *) addr,length,flags); if (result != TRY_OTHER) return result; return -1; } ppp-2.5.0/pppd/plugins/pppoatm/misc.c0000644000175000017500000000214011043063522014432 00000000000000/* misc.c - Miscellaneous library functions */ /* Written 1997-2000 by Werner Almesberger, EPFL-ICA/ICA */ #if HAVE_CONFIG_H #include #endif #include #include #include #include #include #include /* for htons */ #include #include int __atmlib_fetch(const char **pos,...) { const char *value; int ref_len,best_len,len; int i,best; va_list ap; va_start(ap,pos); ref_len = strlen(*pos); best_len = 0; best = -1; for (i = 0; (value = va_arg(ap,const char *)); i++) { len = strlen(value); if (*value != '!' && len <= ref_len && len > best_len && !strncasecmp(*pos,value,len)) { best = i; best_len = len; } } va_end(ap); if (best > -1) (*pos) += best_len; return best; } void atm_tcpip_port_mapping(char *vs_id,uint8_t protocol,uint16_t port) { memcpy(vs_id,ATM_FORUM_OUI "\x01",4); vs_id[4] = protocol; /* e.g. IP_TCP or IP_UDP; from netinet/protocols.h */ vs_id[5] = (htons(port) >> 8) & 255; vs_id[6] = htons(port) & 255; } ppp-2.5.0/pppd/plugins/pppoatm/ans.c0000644000175000017500000001502311043063522014264 00000000000000/* ans.c - Interface for text2atm and atm2text to ANS */ /* Written 1996-2000 by Werner Almesberger, EPFL-LRC/ICA */ /* * This stuff is a temporary hack to avoid using gethostbyname_nsap and such * without doing the "full upgrade" to getaddrinfo/getnameinfo. This also * serves as an exercise for me to get all the details right before I propose * a patch that would eventually end up in libc (and that should therefore be * as stable as possible). */ #if HAVE_CONFIG_H #include #endif #include #include #include #include #include #include #include #include "atm.h" #include "atmres.h" #define MAX_ANSWER 2048 #define MAX_NAME 1024 #define MAX_LINE 2048 /* in /etc/e164_cc */ #define E164_CC_DEFAULT_LEN 2 #define E164_CC_FILE "/etc/e164_cc" #define GET16(pos) (((pos)[0] << 8) | (pos)[1]) static int ans(const char *text,int wanted,void *result,int res_len) { unsigned char answer[MAX_ANSWER]; unsigned char name[MAX_NAME]; unsigned char *pos,*data,*found; int answer_len,name_len,data_len,found_len; int questions,answers; found_len = 0; /* gcc wants it */ if ((answer_len = res_search(text,C_IN,wanted,answer,MAX_ANSWER)) < 0) return TRY_OTHER; /* * Response header: id, flags, #queries, #answers, #authority, * #additional (all 16 bits) */ pos = answer+12; if (answer[3] & 15) return TRY_OTHER; /* rcode != 0 */ questions = GET16(answer+4); if (questions != 1) return TRY_OTHER; /* trouble ... */ answers = GET16(answer+6); if (answers < 1) return TRY_OTHER; /* * Query: name, type (16), class (16) */ if ((name_len = dn_expand(answer,answer+answer_len,pos,name,MAX_NAME)) < 0) return TRY_OTHER; pos += name_len; if (GET16(pos) != wanted || GET16(pos+2) != C_IN) return TRY_OTHER; pos += 4; /* * Iterate over answers until we find something we like, giving priority * to ATMA_AESA (until signaling is fixed to work with E.164 too) */ found = NULL; while (answers--) { /* * RR: name, type (16), class (16), TTL (32), resource_len (16), * resource_data ... */ if ((name_len = dn_expand(answer,answer+answer_len,pos,name,MAX_NAME)) < 0) return TRY_OTHER; pos += name_len; data_len = GET16(pos+8); data = pos+10; pos = data+data_len; if (GET16(data-10) != wanted || GET16(data-8) != C_IN || !--data_len) continue; switch (wanted) { case T_NSAP: data_len++; if (data_len != ATM_ESA_LEN) continue; memcpy(((struct sockaddr_atmsvc *) result)-> sas_addr.prv,data,ATM_ESA_LEN); return 0; case T_ATMA: switch (*data++) { case ATMA_AESA: if (data_len != ATM_ESA_LEN) continue; memcpy(((struct sockaddr_atmsvc *) result)-> sas_addr.prv,data,ATM_ESA_LEN); return 0; case ATMA_E164: if (data_len > ATM_E164_LEN) continue; if (!found) { found = data; found_len = data_len; } break; default: continue; } case T_PTR: if (dn_expand(answer,answer+answer_len,data,result, res_len) < 0) return FATAL; return 0; default: continue; } } if (!found) return TRY_OTHER; memcpy(((struct sockaddr_atmsvc *) result)->sas_addr.pub,found, found_len); ((struct sockaddr_atmsvc *) result)->sas_addr.pub[found_len] = 0; return 0; } int ans_byname(const char *text,struct sockaddr_atmsvc *addr,int length, int flags) { if (!(flags & T2A_SVC) || length != sizeof(*addr)) return TRY_OTHER; memset(addr,0,sizeof(*addr)); addr->sas_family = AF_ATMSVC; if (!ans(text,T_ATMA,addr,length)) return 0; return ans(text,T_NSAP,addr,length); } static int encode_nsap(char *buf,const unsigned char *addr) { static int fmt_dcc[] = { 2,12,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 4,2,0 }; static int fmt_e164[] = { 2,12,1,1,1,1,1,1,1,1,16,2,0 }; int *fmt; int pos,i,j; switch (*addr) { case ATM_AFI_DCC: case ATM_AFI_ICD: case ATM_AFI_LOCAL: case ATM_AFI_DCC_GROUP: case ATM_AFI_ICD_GROUP: case ATM_AFI_LOCAL_GROUP: fmt = fmt_dcc; break; case ATM_AFI_E164: case ATM_AFI_E164_GROUP: fmt = fmt_e164; break; default: return TRY_OTHER; } pos = 2*ATM_ESA_LEN; for (i = 0; fmt[i]; i++) { pos -= fmt[i]; for (j = 0; j < fmt[i]; j++) sprintf(buf++,"%x", (addr[(pos+j) >> 1] >> 4*(1-((pos+j) & 1))) & 0xf); *buf++ = '.'; } strcpy(buf,"AESA.ATMA.INT."); return 0; } static int encode_nsap_new(char *buf,const unsigned char *addr) { int i; int digit; for (i = 20; i; ) { i--; digit = addr[i] & 0x0F; *(buf++) = digit + (digit >= 10 ? '7' : '0'); *(buf++) = '.'; digit = ((unsigned char) (addr[i])) >> 4; *(buf++) = digit + (digit >= 10 ? '7' : '0'); *(buf++) = '.'; } strcpy (buf, "NSAP.INT."); return 0; } static int cc_len(int p0,int p1) { static char *cc_table = NULL; FILE *file; char buffer[MAX_LINE]; char *here; int cc; if (!cc_table) { if (!(cc_table = malloc(100))) { perror("malloc"); return E164_CC_DEFAULT_LEN; } memset(cc_table,E164_CC_DEFAULT_LEN,100); if (!(file = fopen(E164_CC_FILE,"r"))) perror(E164_CC_FILE); else { while (fgets(buffer,MAX_LINE,file)) { here = strchr(buffer,'#'); if (here) *here = 0; if (sscanf(buffer,"%d",&cc) == 1) { if (cc < 10) cc_table[cc] = 1; else if (cc < 100) cc_table[cc] = 2; else cc_table[cc/10] = 3; } } fclose(file); } } if (cc_table[p0] == 1) return 1; return cc_table[p0*10+p1]; } static int encode_e164(char *buf,const char *addr) { const char *prefix,*here; prefix = addr+cc_len(addr[0]-48,addr[1]-48); here = strchr(addr,0); while (here > prefix) { *buf++ = *--here; *buf++ = '.'; } while (here > addr) *buf++ = *addr++; strcpy(buf,".E164.ATMA.INT."); return 0; } int ans_byaddr(char *buffer,int length,const struct sockaddr_atmsvc *addr, int flags) { char tmp[MAX_NAME]; /* could be smaller ... */ int res; if (addr->sas_addr.prv) { res = encode_nsap(tmp,addr->sas_addr.prv); if (!res && !ans(tmp,T_PTR,buffer,length)) return 0; res = encode_nsap_new(tmp,addr->sas_addr.prv); if (res < 0) return res; return ans(tmp,T_PTR,buffer,length); } else { res = encode_e164(tmp,addr->sas_addr.pub); if (res < 0) return res; return ans(tmp,T_PTR,buffer,length); } } ppp-2.5.0/pppd/plugins/pppol2tp/0000755000175000017500000000000014412736275013535 500000000000000ppp-2.5.0/pppd/plugins/pppol2tp/Makefile.am0000664000175000017500000000054714273050614015510 00000000000000pppd_plugin_LTLIBRARIES = pppol2tp.la openl2tp.la pppd_plugindir = $(PPPD_PLUGIN_DIR) noinst_HEADERS = \ l2tp_event.h pppol2tp_la_CPPFLAGS = -I${top_srcdir} pppol2tp_la_LDFLAGS = -module -avoid-version pppol2tp_la_SOURCES = pppol2tp.c openl2tp_la_CPPFLAGS = -I${top_srcdir} openl2tp_la_LDFLAGS = -module -avoid-version openl2tp_la_SOURCES = openl2tp.c ppp-2.5.0/pppd/plugins/pppol2tp/l2tp_event.h0000644000175000017500000000632711043063522015701 00000000000000/***************************************************************************** * Copyright (C) 2008 Katalix Systems Ltd * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * *****************************************************************************/ /* * OpenL2TP application event interface definition. * * This plugin is used by OpenL2TP to receive events from pppd. * * Events are used as follows:- * PPP_UPDOWN_IND - tells OpenL2TP of PPP session state changes. * PPP_ACCM_IND - tells OpenL2TP of PPP ACCM negotiated options * * Non-GPL applications are permitted to use this API, provided that * any changes to this source file are made available under GPL terms. */ #ifndef L2TP_EVENT_H #define L2TP_EVENT_H #include /***************************************************************************** * API definition *****************************************************************************/ #define OPENL2TP_EVENT_SOCKET_NAME "/tmp/openl2tp-event.sock" #define OPENL2TP_MSG_TYPE_NULL 0 #define OPENL2TP_MSG_TYPE_PPP_UPDOWN_IND 1 #define OPENL2TP_MSG_TYPE_PPP_ACCM_IND 2 #define OPENL2TP_MSG_TYPE_MAX 3 enum { OPENL2TP_TLV_TYPE_TUNNEL_ID, OPENL2TP_TLV_TYPE_SESSION_ID, OPENL2TP_TLV_TYPE_PPP_ACCM, OPENL2TP_TLV_TYPE_PPP_UNIT, OPENL2TP_TLV_TYPE_PPP_IFNAME, OPENL2TP_TLV_TYPE_PPP_USER_NAME, OPENL2TP_TLV_TYPE_PPP_STATE }; #define OPENL2TP_TLV_TYPE_MAX (OPENL2TP_TLV_TYPE_PPP_STATE + 1) #define OPENL2TP_MSG_MAX_LEN 512 #define OPENL2TP_MSG_SIGNATURE 0x6b6c7831 #define ALIGN32(n) (((n) + 3) & ~3) /* Each data field in a message is defined by a Type-Length-Value * (TLV) tuplet. */ struct openl2tp_event_tlv { uint16_t tlv_type; uint16_t tlv_len; uint8_t tlv_value[0]; }; /* Messages contain a small header followed by a list of TLVs. Each * TLV starts on a 4-byte boundary. */ struct openl2tp_event_msg { uint32_t msg_signature; /* OPENL2TP_MSG_SIGNATURE */ uint16_t msg_type; /* OPENL2TP_MSG_TYPE_* */ uint16_t msg_len; /* length of data that follows */ uint8_t msg_data[0]; /* list of TLVs, each always longword aligned */ }; /* These structs define the data field layout of each TLV. */ struct openl2tp_tlv_tunnel_id { uint16_t tunnel_id; }; struct openl2tp_tlv_session_id { uint16_t session_id; }; struct openl2tp_tlv_ppp_accm { uint32_t send_accm; uint32_t recv_accm; }; struct openl2tp_tlv_ppp_unit { uint32_t unit; }; struct openl2tp_tlv_ppp_state { uint8_t up; /* 0=down, 1=up */ }; struct openl2tp_tlv_ppp_ifname { char ifname[0]; }; struct openl2tp_tlv_ppp_user_name { char user_name[0]; }; #endif /* L2TP_EVENT_H */ ppp-2.5.0/pppd/plugins/pppol2tp/Makefile.in0000644000175000017500000006127114407475314015527 00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = pppd/plugins/pppol2tp ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_atm.m4 \ $(top_srcdir)/m4/ax_check_openssl.m4 \ $(top_srcdir)/m4/ax_check_openssl_func.m4 \ $(top_srcdir)/m4/ax_check_pam.m4 \ $(top_srcdir)/m4/ax_check_pcap.m4 \ $(top_srcdir)/m4/ax_check_srp.m4 $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/pkg.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(noinst_HEADERS) \ $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/pppd/config.h \ $(top_builddir)/pppd/pppdconf.h \ $(top_builddir)/pppd/plugins/pppoe/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(pppd_plugindir)" LTLIBRARIES = $(pppd_plugin_LTLIBRARIES) openl2tp_la_LIBADD = am_openl2tp_la_OBJECTS = openl2tp_la-openl2tp.lo openl2tp_la_OBJECTS = $(am_openl2tp_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = openl2tp_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(openl2tp_la_LDFLAGS) $(LDFLAGS) -o $@ pppol2tp_la_LIBADD = am_pppol2tp_la_OBJECTS = pppol2tp_la-pppol2tp.lo pppol2tp_la_OBJECTS = $(am_pppol2tp_la_OBJECTS) pppol2tp_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(pppol2tp_la_LDFLAGS) $(LDFLAGS) -o $@ AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/pppd -I$(top_builddir)/pppd/plugins/pppoe depcomp = $(SHELL) $(top_srcdir)/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/openl2tp_la-openl2tp.Plo \ ./$(DEPDIR)/pppol2tp_la-pppol2tp.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(openl2tp_la_SOURCES) $(pppol2tp_la_SOURCES) DIST_SOURCES = $(openl2tp_la_SOURCES) $(pppol2tp_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac HEADERS = $(noinst_HEADERS) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ ATM_CFLAGS = @ATM_CFLAGS@ ATM_LDFLAGS = @ATM_LDFLAGS@ ATM_LIBS = @ATM_LIBS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CRYPT_LIBS = @CRYPT_LIBS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GREP = @GREP@ GTK_CFLAGS = @GTK_CFLAGS@ GTK_LIBS = @GTK_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_INCLUDES = @OPENSSL_INCLUDES@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAM_CFLAGS = @PAM_CFLAGS@ PAM_LDFLAGS = @PAM_LDFLAGS@ PAM_LIBS = @PAM_LIBS@ PATH_SEPARATOR = @PATH_SEPARATOR@ PCAP_CFLAGS = @PCAP_CFLAGS@ PCAP_LDFLAGS = @PCAP_LDFLAGS@ PCAP_LIBS = @PCAP_LIBS@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PPPD_LOGFILE_DIR = @PPPD_LOGFILE_DIR@ PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@ PPPD_RUNTIME_DIR = @PPPD_RUNTIME_DIR@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SRP_CFLAGS = @SRP_CFLAGS@ SRP_LDFLAGS = @SRP_LDFLAGS@ SRP_LIBS = @SRP_LIBS@ STRIP = @STRIP@ SYSTEMD_CFLAGS = @SYSTEMD_CFLAGS@ SYSTEMD_LIBS = @SYSTEMD_LIBS@ SYSTEM_CA_PATH = @SYSTEM_CA_PATH@ UTIL_LIBS = @UTIL_LIBS@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ pppd_plugin_LTLIBRARIES = pppol2tp.la openl2tp.la pppd_plugindir = $(PPPD_PLUGIN_DIR) noinst_HEADERS = \ l2tp_event.h pppol2tp_la_CPPFLAGS = -I${top_srcdir} pppol2tp_la_LDFLAGS = -module -avoid-version pppol2tp_la_SOURCES = pppol2tp.c openl2tp_la_CPPFLAGS = -I${top_srcdir} openl2tp_la_LDFLAGS = -module -avoid-version openl2tp_la_SOURCES = openl2tp.c all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu pppd/plugins/pppol2tp/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu pppd/plugins/pppol2tp/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-pppd_pluginLTLIBRARIES: $(pppd_plugin_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(pppd_plugin_LTLIBRARIES)'; test -n "$(pppd_plugindir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(pppd_plugindir)'"; \ $(MKDIR_P) "$(DESTDIR)$(pppd_plugindir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(pppd_plugindir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(pppd_plugindir)"; \ } uninstall-pppd_pluginLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(pppd_plugin_LTLIBRARIES)'; test -n "$(pppd_plugindir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(pppd_plugindir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(pppd_plugindir)/$$f"; \ done clean-pppd_pluginLTLIBRARIES: -test -z "$(pppd_plugin_LTLIBRARIES)" || rm -f $(pppd_plugin_LTLIBRARIES) @list='$(pppd_plugin_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } openl2tp.la: $(openl2tp_la_OBJECTS) $(openl2tp_la_DEPENDENCIES) $(EXTRA_openl2tp_la_DEPENDENCIES) $(AM_V_CCLD)$(openl2tp_la_LINK) -rpath $(pppd_plugindir) $(openl2tp_la_OBJECTS) $(openl2tp_la_LIBADD) $(LIBS) pppol2tp.la: $(pppol2tp_la_OBJECTS) $(pppol2tp_la_DEPENDENCIES) $(EXTRA_pppol2tp_la_DEPENDENCIES) $(AM_V_CCLD)$(pppol2tp_la_LINK) -rpath $(pppd_plugindir) $(pppol2tp_la_OBJECTS) $(pppol2tp_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openl2tp_la-openl2tp.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pppol2tp_la-pppol2tp.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< openl2tp_la-openl2tp.lo: openl2tp.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(openl2tp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT openl2tp_la-openl2tp.lo -MD -MP -MF $(DEPDIR)/openl2tp_la-openl2tp.Tpo -c -o openl2tp_la-openl2tp.lo `test -f 'openl2tp.c' || echo '$(srcdir)/'`openl2tp.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/openl2tp_la-openl2tp.Tpo $(DEPDIR)/openl2tp_la-openl2tp.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='openl2tp.c' object='openl2tp_la-openl2tp.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(openl2tp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o openl2tp_la-openl2tp.lo `test -f 'openl2tp.c' || echo '$(srcdir)/'`openl2tp.c pppol2tp_la-pppol2tp.lo: pppol2tp.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppol2tp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pppol2tp_la-pppol2tp.lo -MD -MP -MF $(DEPDIR)/pppol2tp_la-pppol2tp.Tpo -c -o pppol2tp_la-pppol2tp.lo `test -f 'pppol2tp.c' || echo '$(srcdir)/'`pppol2tp.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pppol2tp_la-pppol2tp.Tpo $(DEPDIR)/pppol2tp_la-pppol2tp.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pppol2tp.c' object='pppol2tp_la-pppol2tp.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppol2tp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pppol2tp_la-pppol2tp.lo `test -f 'pppol2tp.c' || echo '$(srcdir)/'`pppol2tp.c mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) $(HEADERS) installdirs: for dir in "$(DESTDIR)$(pppd_plugindir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-pppd_pluginLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/openl2tp_la-openl2tp.Plo -rm -f ./$(DEPDIR)/pppol2tp_la-pppol2tp.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-pppd_pluginLTLIBRARIES install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/openl2tp_la-openl2tp.Plo -rm -f ./$(DEPDIR)/pppol2tp_la-pppol2tp.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-pppd_pluginLTLIBRARIES .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-pppd_pluginLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-pppd_pluginLTLIBRARIES install-ps \ install-ps-am install-strip installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am uninstall-pppd_pluginLTLIBRARIES .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: ppp-2.5.0/pppd/plugins/pppol2tp/openl2tp.c0000644000175000017500000002245014402506361015355 00000000000000/***************************************************************************** * Copyright (C) 2006,2007,2008 Katalix Systems Ltd * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * *****************************************************************************/ /* pppd plugin for interfacing to openl2tpd */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifndef aligned_u64 /* should be defined in sys/types.h */ #define aligned_u64 unsigned long long __attribute__((aligned(8))) #endif #include #include #include #include #include #include #include "l2tp_event.h" extern int pppol2tp_tunnel_id; extern int pppol2tp_session_id; extern void (*pppol2tp_send_accm_hook)(int tunnel_id, int session_id, uint32_t send_accm, uint32_t recv_accm); extern void (*pppol2tp_ip_updown_hook)(int tunnel_id, int session_id, int up); const char pppd_version[] = PPPD_VERSION; static int openl2tp_fd = -1; static void (*old_pppol2tp_send_accm_hook)(int tunnel_id, int session_id, uint32_t send_accm, uint32_t recv_accm) = NULL; static void (*old_pppol2tp_ip_updown_hook)(int tunnel_id, int session_id, int up) = NULL; #ifdef PPP_WITH_MULTILINK static multilink_join_hook_fn *old_multilink_join_hook = NULL; #endif /***************************************************************************** * OpenL2TP interface. * We send a PPP_ACCM_IND to openl2tpd to report ACCM values and * SESSION_PPP_UPDOWN_IND to indicate when the PPP link comes up or * goes down. *****************************************************************************/ static int openl2tp_client_create(void) { struct sockaddr_un addr; int result; if (openl2tp_fd < 0) { openl2tp_fd = socket(PF_UNIX, SOCK_DGRAM, 0); if (openl2tp_fd < 0) { error("openl2tp connection create: %m"); return -ENOTCONN; } addr.sun_family = AF_UNIX; strcpy(&addr.sun_path[0], OPENL2TP_EVENT_SOCKET_NAME); result = connect(openl2tp_fd, (struct sockaddr *) &addr, sizeof(addr)); if (result < 0) { error("openl2tp connection connect: %m"); return -ENOTCONN; } } return 0; } static void openl2tp_send_accm_ind(int tunnel_id, int session_id, uint32_t send_accm, uint32_t recv_accm) { int result; uint8_t buf[OPENL2TP_MSG_MAX_LEN]; struct openl2tp_event_msg *msg = (void *) &buf[0]; struct openl2tp_event_tlv *tlv; uint16_t tid = tunnel_id; uint16_t sid = session_id; struct openl2tp_tlv_ppp_accm accm; if (openl2tp_fd < 0) { result = openl2tp_client_create(); if (result < 0) { goto out; } } accm.send_accm = send_accm; accm.recv_accm = recv_accm; msg->msg_signature = OPENL2TP_MSG_SIGNATURE; msg->msg_type = OPENL2TP_MSG_TYPE_PPP_ACCM_IND; msg->msg_len = 0; tlv = (void *) &msg->msg_data[msg->msg_len]; tlv->tlv_type = OPENL2TP_TLV_TYPE_TUNNEL_ID; tlv->tlv_len = sizeof(tid); memcpy(&tlv->tlv_value[0], &tid, tlv->tlv_len); msg->msg_len += sizeof(*tlv) + ALIGN32(tlv->tlv_len); tlv = (void *) &msg->msg_data[msg->msg_len]; tlv->tlv_type = OPENL2TP_TLV_TYPE_SESSION_ID; tlv->tlv_len = sizeof(sid); memcpy(&tlv->tlv_value[0], &sid, tlv->tlv_len); msg->msg_len += sizeof(*tlv) + ALIGN32(tlv->tlv_len); tlv = (void *) &msg->msg_data[msg->msg_len]; tlv->tlv_type = OPENL2TP_TLV_TYPE_PPP_ACCM; tlv->tlv_len = sizeof(accm); memcpy(&tlv->tlv_value[0], &accm, tlv->tlv_len); msg->msg_len += sizeof(*tlv) + ALIGN32(tlv->tlv_len); result = send(openl2tp_fd, msg, sizeof(*msg) + msg->msg_len, MSG_NOSIGNAL); if (result < 0) { error("openl2tp send: %m"); } if (result != (sizeof(*msg) + msg->msg_len)) { warn("openl2tp send: unexpected byte count %d, expected %d", result, sizeof(msg) + msg->msg_len); } dbglog("openl2tp send: sent PPP_ACCM_IND, %d bytes", result); out: if (old_pppol2tp_send_accm_hook != NULL) { (*old_pppol2tp_send_accm_hook)(tunnel_id, session_id, send_accm, recv_accm); } return; } static void openl2tp_ppp_updown_ind(int tunnel_id, int session_id, int up) { int result; uint8_t buf[OPENL2TP_MSG_MAX_LEN]; struct openl2tp_event_msg *msg = (void *) &buf[0]; struct openl2tp_event_tlv *tlv; uint16_t tid = tunnel_id; uint16_t sid = session_id; uint8_t state = up; int unit = 0; char ifname[MAXNAMELEN]; char user_name[MAXNAMELEN]; unit = ppp_ifunit(); ppp_get_ifname(ifname, sizeof(ifname)); if (openl2tp_fd < 0) { result = openl2tp_client_create(); if (result < 0) { goto out; } } if (!ppp_peer_authname(user_name, sizeof(user_name))) user_name[0] = '\0'; msg->msg_signature = OPENL2TP_MSG_SIGNATURE; msg->msg_type = OPENL2TP_MSG_TYPE_PPP_UPDOWN_IND; msg->msg_len = 0; tlv = (void *) &msg->msg_data[msg->msg_len]; tlv->tlv_type = OPENL2TP_TLV_TYPE_TUNNEL_ID; tlv->tlv_len = sizeof(tid); memcpy(&tlv->tlv_value[0], &tid, tlv->tlv_len); msg->msg_len += sizeof(*tlv) + ALIGN32(tlv->tlv_len); tlv = (void *) &msg->msg_data[msg->msg_len]; tlv->tlv_type = OPENL2TP_TLV_TYPE_SESSION_ID; tlv->tlv_len = sizeof(sid); memcpy(&tlv->tlv_value[0], &sid, tlv->tlv_len); msg->msg_len += sizeof(*tlv) + ALIGN32(tlv->tlv_len); tlv = (void *) &msg->msg_data[msg->msg_len]; tlv->tlv_type = OPENL2TP_TLV_TYPE_PPP_STATE; tlv->tlv_len = sizeof(state); memcpy(&tlv->tlv_value[0], &state, tlv->tlv_len); msg->msg_len += sizeof(*tlv) + ALIGN32(tlv->tlv_len); tlv = (void *) &msg->msg_data[msg->msg_len]; tlv->tlv_type = OPENL2TP_TLV_TYPE_PPP_UNIT; tlv->tlv_len = sizeof(unit); memcpy(&tlv->tlv_value[0], &unit, tlv->tlv_len); msg->msg_len += sizeof(*tlv) + ALIGN32(tlv->tlv_len); tlv = (void *) &msg->msg_data[msg->msg_len]; tlv->tlv_type = OPENL2TP_TLV_TYPE_PPP_IFNAME; tlv->tlv_len = strlen(ifname) + 1; memcpy(&tlv->tlv_value[0], ifname, tlv->tlv_len); msg->msg_len += sizeof(*tlv) + ALIGN32(tlv->tlv_len); if (user_name[0] != '\0') { tlv = (void *) &msg->msg_data[msg->msg_len]; tlv->tlv_type = OPENL2TP_TLV_TYPE_PPP_USER_NAME; tlv->tlv_len = strlen(user_name) + 1; memcpy(&tlv->tlv_value[0], user_name, tlv->tlv_len); msg->msg_len += sizeof(*tlv) + ALIGN32(tlv->tlv_len); } result = send(openl2tp_fd, msg, sizeof(*msg) + msg->msg_len, MSG_NOSIGNAL); if (result < 0) { error("openl2tp send: %m"); } if (result != (sizeof(*msg) + msg->msg_len)) { warn("openl2tp send: unexpected byte count %d, expected %d", result, sizeof(msg) + msg->msg_len); } dbglog("openl2tp send: sent PPP_UPDOWN_IND, %d bytes", result); out: if (old_pppol2tp_ip_updown_hook != NULL) { (*old_pppol2tp_ip_updown_hook)(tunnel_id, session_id, up); } return; } /***************************************************************************** * When a multilink interface is created, there are 2 cases to consider. * * 1. The new interface is the first of a multilink bundle (master). * 2. The new interface is being attached to an existing bundle. * * The first case is handled by existing code because the interface * generates ip-up events just like standard interfaces. But in the * second case, where the interface is added to an existing ppp * bundle, pppd does not do IP negotiation and so as a result, no * ip-up event is generated when the interface is created. Since * openl2tpd needs the SESSION_PPP_UPDOWN_IND for all interfaces of a * PPP bundle, we must fake the event. * * We use the ip_multilink_join_hook to hear when an interface joins a * multilink bundle. *****************************************************************************/ #ifdef PPP_WITH_MULTILINK static void openl2tp_multilink_join_ind(void) { if (mp_on() && !mp_master()) { /* send event only if not master */ openl2tp_ppp_updown_ind(pppol2tp_tunnel_id, pppol2tp_session_id, 1); } } #endif /***************************************************************************** * Application init *****************************************************************************/ void plugin_init(void) { old_pppol2tp_send_accm_hook = pppol2tp_send_accm_hook; pppol2tp_send_accm_hook = openl2tp_send_accm_ind; old_pppol2tp_ip_updown_hook = pppol2tp_ip_updown_hook; pppol2tp_ip_updown_hook = openl2tp_ppp_updown_ind; #ifdef PPP_WITH_MULTILINK old_multilink_join_hook = multilink_join_hook; multilink_join_hook = openl2tp_multilink_join_ind; #endif } ppp-2.5.0/pppd/plugins/pppol2tp/pppol2tp.c0000644000175000017500000003520614353435407015404 00000000000000/* pppol2tp.c - pppd plugin to implement PPPoL2TP protocol * for Linux using kernel pppol2tp support. * * Requires kernel pppol2tp driver which is integrated into the kernel * from 2.6.23 onwards. For earlier kernels, a version can be obtained * from the OpenL2TP project at * http://www.sourceforge.net/projects/openl2tp/ * * Original by Martijn van Oosterhout * Modified by jchapman@katalix.com * * Heavily based upon pppoatm.c: original notice follows * * Copyright 2000 Mitchell Blank Jr. * Based in part on work from Jens Axboe and Paul Mackerras. * Updated to ppp-2.4.1 by Bernhard Kaindl * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifndef aligned_u64 /* should be defined in sys/types.h */ #define aligned_u64 unsigned long long __attribute__((aligned(8))) #endif #include #include #include #include #include #include #include #include #include #include #include #include /* should be added to system's socket.h... */ #ifndef SOL_PPPOL2TP #define SOL_PPPOL2TP 273 #endif const char pppd_version[] = PPPD_VERSION; static int setdevname_pppol2tp(char **argv); static int pppol2tp_fd = -1; static char *pppol2tp_fd_str; static bool pppol2tp_lns_mode = 0; static bool pppol2tp_recv_seq = 0; static bool pppol2tp_send_seq = 0; static int pppol2tp_debug_mask = 0; static int pppol2tp_reorder_timeout = 0; static char pppol2tp_ifname[32] = { 0, }; int pppol2tp_tunnel_id = 0; int pppol2tp_session_id = 0; static int device_got_set = 0; struct channel pppol2tp_channel; static void (*old_snoop_recv_hook)(unsigned char *p, int len) = NULL; static void (*old_snoop_send_hook)(unsigned char *p, int len) = NULL; /* Hook provided to allow other plugins to handle ACCM changes */ void (*pppol2tp_send_accm_hook)(int tunnel_id, int session_id, uint32_t send_accm, uint32_t recv_accm) = NULL; /* Hook provided to allow other plugins to handle IP up/down */ void (*pppol2tp_ip_updown_hook)(int tunnel_id, int session_id, int up) = NULL; static struct option pppol2tp_options[] = { { "pppol2tp", o_special, &setdevname_pppol2tp, "FD for PPPoL2TP socket", OPT_DEVNAM | OPT_A2STRVAL, &pppol2tp_fd_str }, { "pppol2tp_lns_mode", o_bool, &pppol2tp_lns_mode, "PPPoL2TP LNS behavior. Default off.", OPT_PRIO | OPRIO_CFGFILE }, { "pppol2tp_send_seq", o_bool, &pppol2tp_send_seq, "PPPoL2TP enable sequence numbers in transmitted data packets. " "Default off.", OPT_PRIO | OPRIO_CFGFILE }, { "pppol2tp_recv_seq", o_bool, &pppol2tp_recv_seq, "PPPoL2TP enforce sequence numbers in received data packets. " "Default off.", OPT_PRIO | OPRIO_CFGFILE }, { "pppol2tp_reorderto", o_int, &pppol2tp_reorder_timeout, "PPPoL2TP data packet reorder timeout. Default 0 (no reordering).", OPT_PRIO }, { "pppol2tp_debug_mask", o_int, &pppol2tp_debug_mask, "PPPoL2TP debug mask. Default: no debug.", OPT_PRIO }, { "pppol2tp_ifname", o_string, &pppol2tp_ifname, "Set interface name of PPP interface", OPT_PRIO | OPT_PRIV | OPT_STATIC, NULL, 16 }, { "pppol2tp_tunnel_id", o_int, &pppol2tp_tunnel_id, "PPPoL2TP tunnel_id.", OPT_PRIO }, { "pppol2tp_session_id", o_int, &pppol2tp_session_id, "PPPoL2TP session_id.", OPT_PRIO }, { NULL } }; static int setdevname_pppol2tp(char **argv) { union { char buffer[128]; struct sockaddr pppol2tp; } s; socklen_t len = sizeof(s); char **a; int tmp; socklen_t tmp_len = sizeof(tmp); if (device_got_set) return 0; if (!ppp_int_option(*argv, &pppol2tp_fd)) return 0; if(getsockname(pppol2tp_fd, (struct sockaddr *)&s, &len) < 0) { fatal("Given FD for PPPoL2TP socket invalid (%s)", strerror(errno)); } if(s.pppol2tp.sa_family != AF_PPPOX) { fatal("Socket of not a PPPoX socket"); } /* Do a test getsockopt() to ensure that the kernel has the necessary * feature available. */ if (getsockopt(pppol2tp_fd, SOL_PPPOL2TP, PPPOL2TP_SO_DEBUG, &tmp, &tmp_len) < 0) { fatal("PPPoL2TP kernel driver not installed"); } pppol2tp_fd_str = strdup(*argv); if (pppol2tp_fd_str == NULL) novm("PPPoL2TP FD"); /* Setup option defaults. Compression options are disabled! */ ppp_set_modem(false); lcp_allowoptions[0].neg_accompression = 1; lcp_wantoptions[0].neg_accompression = 0; lcp_allowoptions[0].neg_pcompression = 1; lcp_wantoptions[0].neg_pcompression = 0; ccp_allowoptions[0].deflate = 0; ccp_wantoptions[0].deflate = 0; ipcp_allowoptions[0].neg_vj = 0; ipcp_wantoptions[0].neg_vj = 0; ccp_allowoptions[0].bsd_compress = 0; ccp_wantoptions[0].bsd_compress = 0; the_channel = &pppol2tp_channel; device_got_set = 1; return 1; } static int connect_pppol2tp(void) { if(pppol2tp_fd == -1) { fatal("No PPPoL2TP FD specified"); } return pppol2tp_fd; } static void disconnect_pppol2tp(void) { if (pppol2tp_fd >= 0) { close(pppol2tp_fd); pppol2tp_fd = -1; } } static void send_config_pppol2tp(int mtu, uint32_t asyncmap, int pcomp, int accomp) { struct ifreq ifr; int on = 1; int fd; char reorderto[16]; char tid[12]; char sid[12]; if (pppol2tp_ifname[0]) { struct ifreq ifr; int fd; fd = socket(AF_INET, SOCK_DGRAM, 0); if (fd >= 0) { memset (&ifr, '\0', sizeof (ifr)); ppp_get_ifname(ifr.ifr_name, sizeof(ifr.ifr_name)); strlcpy(ifr.ifr_newname, pppol2tp_ifname, sizeof(ifr.ifr_name)); ioctl(fd, SIOCSIFNAME, (caddr_t) &ifr); ppp_set_ifname(pppol2tp_ifname); if (pppol2tp_debug_mask & PPPOL2TP_MSG_CONTROL) { dbglog("ppp%d: interface name %s", ppp_ifunit(), ppp_ifname()); } } close(fd); } if ((lcp_allowoptions[0].mru > 0) && (mtu > lcp_allowoptions[0].mru)) { warn("Overriding mtu %d to %d", mtu, lcp_allowoptions[0].mru); mtu = lcp_allowoptions[0].mru; } ppp_set_mtu(ppp_ifunit(), mtu); reorderto[0] = '\0'; if (pppol2tp_reorder_timeout > 0) sprintf(&reorderto[0], "%d ", pppol2tp_reorder_timeout); tid[0] = '\0'; if (pppol2tp_tunnel_id > 0) sprintf(&tid[0], "%u ", pppol2tp_tunnel_id); sid[0] = '\0'; if (pppol2tp_session_id > 0) sprintf(&sid[0], "%u ", pppol2tp_session_id); dbglog("PPPoL2TP options: %s%s%s%s%s%s%s%s%sdebugmask %d", pppol2tp_recv_seq ? "recvseq " : "", pppol2tp_send_seq ? "sendseq " : "", pppol2tp_lns_mode ? "lnsmode " : "", pppol2tp_reorder_timeout ? "reorderto " : "", reorderto, pppol2tp_tunnel_id ? "tid " : "", tid, pppol2tp_session_id ? "sid " : "", sid, pppol2tp_debug_mask); if (pppol2tp_recv_seq) if (setsockopt(pppol2tp_fd, SOL_PPPOL2TP, PPPOL2TP_SO_RECVSEQ, &on, sizeof(on)) < 0) fatal("setsockopt(PPPOL2TP_RECVSEQ): %m"); if (pppol2tp_send_seq) if (setsockopt(pppol2tp_fd, SOL_PPPOL2TP, PPPOL2TP_SO_SENDSEQ, &on, sizeof(on)) < 0) fatal("setsockopt(PPPOL2TP_SENDSEQ): %m"); if (pppol2tp_lns_mode) if (setsockopt(pppol2tp_fd, SOL_PPPOL2TP, PPPOL2TP_SO_LNSMODE, &on, sizeof(on)) < 0) fatal("setsockopt(PPPOL2TP_LNSMODE): %m"); if (pppol2tp_reorder_timeout) if (setsockopt(pppol2tp_fd, SOL_PPPOL2TP, PPPOL2TP_SO_REORDERTO, &pppol2tp_reorder_timeout, sizeof(pppol2tp_reorder_timeout)) < 0) fatal("setsockopt(PPPOL2TP_REORDERTO): %m"); if (pppol2tp_debug_mask) if (setsockopt(pppol2tp_fd, SOL_PPPOL2TP, PPPOL2TP_SO_DEBUG, &pppol2tp_debug_mask, sizeof(pppol2tp_debug_mask)) < 0) fatal("setsockopt(PPPOL2TP_DEBUG): %m"); } static void recv_config_pppol2tp(int mru, uint32_t asyncmap, int pcomp, int accomp) { if ((lcp_allowoptions[0].mru > 0) && (mru > lcp_allowoptions[0].mru)) { warn("Overriding mru %d to mtu value %d", mru, lcp_allowoptions[0].mru); mru = lcp_allowoptions[0].mru; } if ((ppp_ifunit() >= 0) && ioctl(pppol2tp_fd, PPPIOCSMRU, (caddr_t) &mru) < 0) error("Couldn't set PPP MRU: %m"); } /***************************************************************************** * Snoop LCP message exchanges to capture negotiated ACCM values. * When asyncmap values have been seen from both sides, give the values to * L2TP. * This code is derived from Roaring Penguin L2TP. *****************************************************************************/ static void pppol2tp_lcp_snoop(unsigned char *buf, int len, int incoming) { static bool got_send_accm = 0; static bool got_recv_accm = 0; static uint32_t recv_accm = 0xffffffff; static uint32_t send_accm = 0xffffffff; static bool snooping = 1; uint16_t protocol; uint16_t lcp_pkt_len; int opt, opt_len; int reject; unsigned char const *opt_data; uint32_t accm; /* Skip HDLC header */ buf += 2; len -= 2; /* Unreasonably short frame?? */ if (len <= 0) return; /* Get protocol */ if (buf[0] & 0x01) { /* Compressed protcol field */ protocol = buf[0]; } else { protocol = ((unsigned int) buf[0]) * 256 + buf[1]; } /* If it's a network protocol, stop snooping */ if (protocol <= 0x3fff) { if (pppol2tp_debug_mask & PPPOL2TP_MSG_DEBUG) { dbglog("Turning off snooping: " "Network protocol %04x found.", protocol); } snooping = 0; return; } /* If it's not LCP, do not snoop */ if (protocol != 0xc021) { return; } /* Skip protocol; go to packet data */ buf += 2; len -= 2; /* Unreasonably short frame?? */ if (len <= 0) return; /* Look for Configure-Ack or Configure-Reject code */ if (buf[0] != CONFACK && buf[0] != CONFREJ) return; reject = (buf[0] == CONFREJ); lcp_pkt_len = ((unsigned int) buf[2]) * 256 + buf[3]; /* Something fishy with length field? */ if (lcp_pkt_len > len) return; /* Skip to options */ len = lcp_pkt_len - 4; buf += 4; while (len > 0) { /* Pull off an option */ opt = buf[0]; opt_len = buf[1]; opt_data = &buf[2]; if (opt_len > len || opt_len < 2) break; len -= opt_len; buf += opt_len; if (pppol2tp_debug_mask & PPPOL2TP_MSG_DEBUG) { dbglog("Found option type %02x; len %d", opt, opt_len); } /* We are specifically interested in ACCM */ if (opt == CI_ASYNCMAP && opt_len == 0x06) { if (reject) { /* ACCM negotiation REJECTED; use default */ accm = 0xffffffff; if (pppol2tp_debug_mask & PPPOL2TP_MSG_DATA) { dbglog("Rejected ACCM negotiation; " "defaulting (%s)", incoming ? "incoming" : "outgoing"); } recv_accm = accm; send_accm = accm; got_recv_accm = 1; got_send_accm = 1; } else { memcpy(&accm, opt_data, sizeof(accm)); if (pppol2tp_debug_mask & PPPOL2TP_MSG_DATA) { dbglog("Found ACCM of %08x (%s)", accm, incoming ? "incoming" : "outgoing"); } if (incoming) { recv_accm = accm; got_recv_accm = 1; } else { send_accm = accm; got_send_accm = 1; } } if (got_recv_accm && got_send_accm) { if (pppol2tp_debug_mask & PPPOL2TP_MSG_CONTROL) { dbglog("Telling L2TP: Send ACCM = %08x; " "Receive ACCM = %08x", send_accm, recv_accm); } if (pppol2tp_send_accm_hook != NULL) { (*pppol2tp_send_accm_hook)(pppol2tp_tunnel_id, pppol2tp_session_id, send_accm, recv_accm); } got_recv_accm = 0; got_send_accm = 0; } } } } static void pppol2tp_lcp_snoop_recv(unsigned char *p, int len) { if (old_snoop_recv_hook != NULL) (*old_snoop_recv_hook)(p, len); pppol2tp_lcp_snoop(p, len, 1); } static void pppol2tp_lcp_snoop_send(unsigned char *p, int len) { if (old_snoop_send_hook != NULL) (*old_snoop_send_hook)(p, len); pppol2tp_lcp_snoop(p, len, 0); } /***************************************************************************** * Interface up/down events *****************************************************************************/ static void pppol2tp_ip_up(void *opaque, int arg) { /* may get called twice (for IPv4 and IPv6) but the hook handles that well */ if (pppol2tp_ip_updown_hook != NULL) { (*pppol2tp_ip_updown_hook)(pppol2tp_tunnel_id, pppol2tp_session_id, 1); } } static void pppol2tp_ip_down(void *opaque, int arg) { /* may get called twice (for IPv4 and IPv6) but the hook handles that well */ if (pppol2tp_ip_updown_hook != NULL) { (*pppol2tp_ip_updown_hook)(pppol2tp_tunnel_id, pppol2tp_session_id, 0); } } /***************************************************************************** * Application init *****************************************************************************/ static void pppol2tp_check_options(void) { /* Enable LCP snooping for ACCM options only for LNS */ if (pppol2tp_lns_mode) { if ((pppol2tp_tunnel_id == 0) || (pppol2tp_session_id == 0)) { fatal("tunnel_id/session_id values not specified"); } if (pppol2tp_debug_mask & PPPOL2TP_MSG_CONTROL) { dbglog("Enabling LCP snooping"); } old_snoop_recv_hook = snoop_recv_hook; old_snoop_send_hook = snoop_send_hook; snoop_recv_hook = pppol2tp_lcp_snoop_recv; snoop_send_hook = pppol2tp_lcp_snoop_send; } } /* Called just before pppd exits. */ static void pppol2tp_cleanup(void) { if (pppol2tp_debug_mask & PPPOL2TP_MSG_DEBUG) { dbglog("pppol2tp: exiting."); } disconnect_pppol2tp(); } void plugin_init(void) { #if defined(__linux__) extern int new_style_driver; /* From sys-linux.c */ if (!ppp_check_kernel_support() && !new_style_driver) fatal("Kernel doesn't support ppp_generic - " "needed for PPPoL2TP"); #else fatal("No PPPoL2TP support on this OS"); #endif ppp_add_options(pppol2tp_options); /* Hook up ip up/down notifiers to send indicator to openl2tpd * that the link is up */ ppp_add_notify(NF_IP_UP, pppol2tp_ip_up, NULL); ppp_add_notify(NF_IP_DOWN, pppol2tp_ip_down, NULL); #ifdef PPP_WITH_IPV6CP ppp_add_notify(NF_IPV6_UP, pppol2tp_ip_up, NULL); ppp_add_notify(NF_IPV6_DOWN, pppol2tp_ip_down, NULL); #endif } struct channel pppol2tp_channel = { .options = pppol2tp_options, .process_extra_options = NULL, .check_options = &pppol2tp_check_options, .connect = &connect_pppol2tp, .disconnect = &disconnect_pppol2tp, .establish_ppp = &ppp_generic_establish, .disestablish_ppp = &ppp_generic_disestablish, .send_config = &send_config_pppol2tp, .recv_config = &recv_config_pppol2tp, .close = NULL, .cleanup = NULL }; ppp-2.5.0/pppd/plugins/radius/0000755000175000017500000000000014412736275013244 500000000000000ppp-2.5.0/pppd/plugins/radius/etc/0000755000175000017500000000000014412736275014017 500000000000000ppp-2.5.0/pppd/plugins/radius/etc/dictionary0000664000175000017500000001707514167711773016046 00000000000000# # Updated 97/06/13 to livingston-radius-2.01 miquels@cistron.nl # # This file contains dictionary translations for parsing # requests and generating responses. All transactions are # composed of Attribute/Value Pairs. The value of each attribute # is specified as one of 4 data types. Valid data types are: # # string - 0-253 octets # ipaddr - 4 octets in network byte order # integer - 32 bit value in big endian order (high byte first) # date - 32 bit value in big endian order - seconds since # 00:00:00 GMT, Jan. 1, 1970 # # Enumerated values are stored in the user file with dictionary # VALUE translations for easy administration. # # Example: # # ATTRIBUTE VALUE # --------------- ----- # Framed-Protocol = PPP # 7 = 1 (integer encoding) # # The dictionary format now supports vendor-specific attributes. # Vendors are introduced like this: # # VENDOR vendor_name vendor_number # # For example: # # VENDOR RoaringPenguin 10055 # # Vendor-specific attributes have a fifth field with the name of the # vendor. For example: # # ATTRIBUTE RP-Upstream-Speed-Limit 1 integer RoaringPenguin # # introduces a Roaring Penguin vendor-specific attribbute with name # RP-Upstream-Speed-Limit, number 1, type integer and vendor RoaringPenguin. # # Following are the proper new names. Use these. # ATTRIBUTE User-Name 1 string ATTRIBUTE Password 2 string ATTRIBUTE CHAP-Password 3 string ATTRIBUTE NAS-IP-Address 4 ipaddr ATTRIBUTE NAS-Port-Id 5 integer ATTRIBUTE Service-Type 6 integer ATTRIBUTE Framed-Protocol 7 integer ATTRIBUTE Framed-IP-Address 8 ipaddr ATTRIBUTE Framed-IP-Netmask 9 ipaddr ATTRIBUTE Framed-Routing 10 integer ATTRIBUTE Filter-Id 11 string ATTRIBUTE Framed-MTU 12 integer ATTRIBUTE Framed-Compression 13 integer ATTRIBUTE Login-IP-Host 14 ipaddr ATTRIBUTE Login-Service 15 integer ATTRIBUTE Login-TCP-Port 16 integer ATTRIBUTE Reply-Message 18 string ATTRIBUTE Callback-Number 19 string ATTRIBUTE Callback-Id 20 string ATTRIBUTE Framed-Route 22 string ATTRIBUTE Framed-IPX-Network 23 ipaddr ATTRIBUTE State 24 string ATTRIBUTE Class 25 string ATTRIBUTE Session-Timeout 27 integer ATTRIBUTE Idle-Timeout 28 integer ATTRIBUTE Termination-Action 29 integer ATTRIBUTE Called-Station-Id 30 string ATTRIBUTE Calling-Station-Id 31 string ATTRIBUTE NAS-Identifier 32 string ATTRIBUTE Acct-Status-Type 40 integer ATTRIBUTE Acct-Delay-Time 41 integer ATTRIBUTE Acct-Input-Octets 42 integer ATTRIBUTE Acct-Output-Octets 43 integer ATTRIBUTE Acct-Session-Id 44 string ATTRIBUTE Acct-Authentic 45 integer ATTRIBUTE Acct-Session-Time 46 integer ATTRIBUTE Acct-Input-Packets 47 integer ATTRIBUTE Acct-Output-Packets 48 integer ATTRIBUTE Acct-Terminate-Cause 49 integer ATTRIBUTE Acct-Input-Gigawords 52 integer ATTRIBUTE Acct-Output-Gigawords 53 integer ATTRIBUTE Chap-Challenge 60 string ATTRIBUTE NAS-Port-Type 61 integer ATTRIBUTE Port-Limit 62 integer ATTRIBUTE Connect-Info 77 string # RFC 2869 ATTRIBUTE Acct-Interim-Interval 85 integer # # Experimental Non Protocol Attributes used by Cistron-Radiusd # ATTRIBUTE Huntgroup-Name 221 string ATTRIBUTE User-Category 1029 string ATTRIBUTE Group-Name 1030 string ATTRIBUTE Simultaneous-Use 1034 integer ATTRIBUTE Strip-User-Name 1035 integer ATTRIBUTE Fall-Through 1036 integer ATTRIBUTE Add-Port-To-IP-Address 1037 integer ATTRIBUTE Exec-Program 1038 string ATTRIBUTE Exec-Program-Wait 1039 string ATTRIBUTE Hint 1040 string # # Non-Protocol Attributes # These attributes are used internally by the server # ATTRIBUTE Expiration 21 date ATTRIBUTE Auth-Type 1000 integer ATTRIBUTE Menu 1001 string ATTRIBUTE Termination-Menu 1002 string ATTRIBUTE Prefix 1003 string ATTRIBUTE Suffix 1004 string ATTRIBUTE Group 1005 string ATTRIBUTE Crypt-Password 1006 string ATTRIBUTE Connect-Rate 1007 integer # # Experimental, implementation specific attributes # # Limit session traffic ATTRIBUTE Session-Octets-Limit 227 integer # What to assume as limit - 0 in+out, 1 in, 2 out, 3 max(in,out) ATTRIBUTE Octets-Direction 228 integer # # Integer Translations # # User Types VALUE Service-Type Login-User 1 VALUE Service-Type Framed-User 2 VALUE Service-Type Callback-Login-User 3 VALUE Service-Type Callback-Framed-User 4 VALUE Service-Type Outbound-User 5 VALUE Service-Type Administrative-User 6 VALUE Service-Type NAS-Prompt-User 7 # Framed Protocols VALUE Framed-Protocol PPP 1 VALUE Framed-Protocol SLIP 2 # Framed Routing Values VALUE Framed-Routing None 0 VALUE Framed-Routing Broadcast 1 VALUE Framed-Routing Listen 2 VALUE Framed-Routing Broadcast-Listen 3 # Framed Compression Types VALUE Framed-Compression None 0 VALUE Framed-Compression Van-Jacobson-TCP-IP 1 # Login Services VALUE Login-Service Telnet 0 VALUE Login-Service Rlogin 1 VALUE Login-Service TCP-Clear 2 VALUE Login-Service PortMaster 3 # Status Types VALUE Acct-Status-Type Start 1 VALUE Acct-Status-Type Stop 2 VALUE Acct-Status-Type Accounting-On 7 VALUE Acct-Status-Type Accounting-Off 8 # Authentication Types VALUE Acct-Authentic RADIUS 1 VALUE Acct-Authentic Local 2 VALUE Acct-Authentic PowerLink128 100 # Termination Options VALUE Termination-Action Default 0 VALUE Termination-Action RADIUS-Request 1 # NAS Port Types, available in 3.3.1 and later VALUE NAS-Port-Type Async 0 VALUE NAS-Port-Type Sync 1 VALUE NAS-Port-Type ISDN 2 VALUE NAS-Port-Type ISDN-V120 3 VALUE NAS-Port-Type ISDN-V110 4 # Acct Terminate Causes, available in 3.3.2 and later VALUE Acct-Terminate-Cause User-Request 1 VALUE Acct-Terminate-Cause Lost-Carrier 2 VALUE Acct-Terminate-Cause Lost-Service 3 VALUE Acct-Terminate-Cause Idle-Timeout 4 VALUE Acct-Terminate-Cause Session-Timeout 5 VALUE Acct-Terminate-Cause Admin-Reset 6 VALUE Acct-Terminate-Cause Admin-Reboot 7 VALUE Acct-Terminate-Cause Port-Error 8 VALUE Acct-Terminate-Cause NAS-Error 9 VALUE Acct-Terminate-Cause NAS-Request 10 VALUE Acct-Terminate-Cause NAS-Reboot 11 VALUE Acct-Terminate-Cause Port-Unneeded 12 VALUE Acct-Terminate-Cause Port-Preempted 13 VALUE Acct-Terminate-Cause Port-Suspended 14 VALUE Acct-Terminate-Cause Service-Unavailable 15 VALUE Acct-Terminate-Cause Callback 16 VALUE Acct-Terminate-Cause User-Error 17 VALUE Acct-Terminate-Cause Host-Request 18 # # Non-Protocol Integer Translations # VALUE Auth-Type Local 0 VALUE Auth-Type System 1 VALUE Auth-Type SecurID 2 VALUE Auth-Type Crypt-Local 3 VALUE Auth-Type Reject 4 # # Cistron extensions # VALUE Auth-Type Pam 253 VALUE Auth-Type None 254 # # Experimental Non-Protocol Integer Translations for Cistron-Radiusd # VALUE Fall-Through No 0 VALUE Fall-Through Yes 1 VALUE Add-Port-To-IP-Address No 0 VALUE Add-Port-To-IP-Address Yes 1 # # Configuration Values # uncomment these two lines to turn account expiration on # #VALUE Server-Config Password-Expiration 30 #VALUE Server-Config Password-Warning 5 # Octets-Direction VALUE Octets-Direction Sum 0 VALUE Octets-Direction Input 1 VALUE Octets-Direction Output 2 VALUE Octets-Direction MaxOveral 3 VALUE Octets-Direction MaxSession 4 INCLUDE /etc/radiusclient/dictionary.microsoft ppp-2.5.0/pppd/plugins/radius/etc/dictionary.ascend0000644000175000017500000003000711043063522017244 00000000000000# # Ascend dictionary. # # # Version: 1.00 21-Jul-1997 Jens Glaser # # # Ascend specific extensions # Used by ASCEND MAX/Pipeline products # ATTRIBUTE Ascend-FCP-Parameter 119 string ATTRIBUTE Ascend-Modem-PortNo 120 integer ATTRIBUTE Ascend-Modem-SlotNo 121 integer ATTRIBUTE Ascend-Modem-ShelfNo 122 integer ATTRIBUTE Ascend-Call-Attempt-Limit 123 integer ATTRIBUTE Ascend-Call-Block-Duration 124 integer ATTRIBUTE Ascend-Maximum-Call-Duration 125 integer ATTRIBUTE Ascend-Temporary-Rtes 126 integer ATTRIBUTE Tunneling-Protocol 127 integer ATTRIBUTE Ascend-Shared-Profile-Enable 128 integer ATTRIBUTE Ascend-Primary-Home-Agent 129 string ATTRIBUTE Ascend-Secondary-Home-Agent 130 string ATTRIBUTE Ascend-Dialout-Allowed 131 integer ATTRIBUTE Ascend-Client-Gateway 132 ipaddr ATTRIBUTE Ascend-BACP-Enable 133 integer ATTRIBUTE Ascend-DHCP-Maximum-Leases 134 integer ATTRIBUTE Ascend-Client-Primary-DNS 135 ipaddr ATTRIBUTE Ascend-Client-Secondary-DNS 136 ipaddr ATTRIBUTE Ascend-Client-Assign-DNS 137 integer ATTRIBUTE Ascend-User-Acct-Type 138 integer ATTRIBUTE Ascend-User-Acct-Host 139 ipaddr ATTRIBUTE Ascend-User-Acct-Port 140 integer ATTRIBUTE Ascend-User-Acct-Key 141 string ATTRIBUTE Ascend-User-Acct-Base 142 integer ATTRIBUTE Ascend-User-Acct-Time 143 integer ATTRIBUTE Ascend-Assign-IP-Client 144 ipaddr ATTRIBUTE Ascend-Assign-IP-Server 145 ipaddr ATTRIBUTE Ascend-Assign-IP-Global-Pool 146 string ATTRIBUTE Ascend-DHCP-Reply 147 integer ATTRIBUTE Ascend-DHCP-Pool-Number 148 integer ATTRIBUTE Ascend-Expect-Callback 149 integer ATTRIBUTE Ascend-Event-Type 150 integer ATTRIBUTE Ascend-Session-Svr-Key 151 string ATTRIBUTE Ascend-Multicast-Rate-Limit 152 integer ATTRIBUTE Ascend-IF-Netmask 153 ipaddr ATTRIBUTE Ascend-Remote-Addr 154 ipaddr ATTRIBUTE Ascend-Multicast-Client 155 integer ATTRIBUTE Ascend-FR-Circuit-Name 156 string ATTRIBUTE Ascend-FR-LinkUp 157 integer ATTRIBUTE Ascend-FR-Nailed-Grp 158 integer ATTRIBUTE Ascend-FR-Type 159 integer ATTRIBUTE Ascend-FR-Link-Mgt 160 integer ATTRIBUTE Ascend-FR-N391 161 integer ATTRIBUTE Ascend-FR-DCE-N392 162 integer ATTRIBUTE Ascend-FR-DTE-N392 163 integer ATTRIBUTE Ascend-FR-DCE-N393 164 integer ATTRIBUTE Ascend-FR-DTE-N393 165 integer ATTRIBUTE Ascend-FR-T391 166 integer ATTRIBUTE Ascend-FR-T392 167 integer ATTRIBUTE Ascend-Bridge-Address 168 string ATTRIBUTE Ascend-TS-Idle-Limit 169 integer ATTRIBUTE Ascend-TS-Idle-Mode 170 integer ATTRIBUTE Ascend-DBA-Monitor 171 integer ATTRIBUTE Ascend-Base-Channel-Count 172 integer ATTRIBUTE Ascend-Minimum-Channels 173 integer ATTRIBUTE Ascend-IPX-Route 174 string ATTRIBUTE Ascend-FT1-Caller 175 integer ATTRIBUTE Ascend-Backup 176 string ATTRIBUTE Ascend-Call-Type 177 integer ATTRIBUTE Ascend-Group 178 string ATTRIBUTE Ascend-FR-DLCI 179 integer ATTRIBUTE Ascend-FR-Profile-Name 180 string ATTRIBUTE Ascend-Ara-PW 181 string ATTRIBUTE Ascend-IPX-Node-Addr 182 string ATTRIBUTE Ascend-Home-Agent-IP-Addr 183 ipaddr ATTRIBUTE Ascend-Home-Agent-Password 184 string ATTRIBUTE Ascend-Home-Network-Name 185 string ATTRIBUTE Ascend-Home-Agent-UDP-Port 186 integer ATTRIBUTE Ascend-Multilink-ID 187 integer ATTRIBUTE Ascend-Num-In-Multilink 188 integer ATTRIBUTE Ascend-First-Dest 189 ipaddr ATTRIBUTE Ascend-Pre-Input-Octets 190 integer ATTRIBUTE Ascend-Pre-Output-Octets 191 integer ATTRIBUTE Ascend-Pre-Input-Packets 192 integer ATTRIBUTE Ascend-Pre-Output-Packets 193 integer ATTRIBUTE Ascend-Maximum-Time 194 integer ATTRIBUTE Ascend-Disconnect-Cause 195 integer ATTRIBUTE Ascend-Connect-Progress 196 integer ATTRIBUTE Ascend-Data-Rate 197 integer ATTRIBUTE Ascend-PreSession-Time 198 integer ATTRIBUTE Ascend-Token-Idle 199 integer ATTRIBUTE Ascend-Token-Immediate 200 integer ATTRIBUTE Ascend-Require-Auth 201 integer ATTRIBUTE Ascend-Number-Sessions 202 string ATTRIBUTE Ascend-Authen-Alias 203 string ATTRIBUTE Ascend-Token-Expiry 204 integer ATTRIBUTE Ascend-Menu-Selector 205 string ATTRIBUTE Ascend-Menu-Item 206 string ATTRIBUTE Ascend-PW-Warntime 207 integer ATTRIBUTE Ascend-PW-Lifetime 208 integer ATTRIBUTE Ascend-IP-Direct 209 ipaddr ATTRIBUTE Ascend-PPP-VJ-Slot-Comp 210 integer ATTRIBUTE Ascend-PPP-VJ-1172 211 integer ATTRIBUTE Ascend-PPP-Async-Map 212 integer ATTRIBUTE Ascend-Third-Prompt 213 string ATTRIBUTE Ascend-Send-Secret 214 string ATTRIBUTE Ascend-Receive-Secret 215 string ATTRIBUTE Ascend-IPX-Peer-Mode 216 integer ATTRIBUTE Ascend-IP-Pool-Definition 217 string ATTRIBUTE Ascend-Assign-IP-Pool 218 integer ATTRIBUTE Ascend-FR-Direct 219 integer ATTRIBUTE Ascend-FR-Direct-Profile 220 string ATTRIBUTE Ascend-FR-Direct-DLCI 221 integer ATTRIBUTE Ascend-Handle-IPX 222 integer ATTRIBUTE Ascend-Netware-timeout 223 integer ATTRIBUTE Ascend-IPX-Alias 224 integer ATTRIBUTE Ascend-Metric 225 integer ATTRIBUTE Ascend-PRI-Number-Type 226 integer ATTRIBUTE Ascend-Dial-Number 227 string ATTRIBUTE Ascend-Route-IP 228 integer ATTRIBUTE Ascend-Route-IPX 229 integer ATTRIBUTE Ascend-Bridge 230 integer ATTRIBUTE Ascend-Send-Auth 231 integer ATTRIBUTE Ascend-Send-Passwd 232 string ATTRIBUTE Ascend-Link-Compression 233 integer ATTRIBUTE Ascend-Target-Util 234 integer ATTRIBUTE Ascend-Maximum-Channels 235 integer ATTRIBUTE Ascend-Inc-Channel-Count 236 integer ATTRIBUTE Ascend-Dec-Channel-Count 237 integer ATTRIBUTE Ascend-Seconds-Of-History 238 integer ATTRIBUTE Ascend-History-Weigh-Type 239 integer ATTRIBUTE Ascend-Add-Seconds 240 integer ATTRIBUTE Ascend-Remove-Seconds 241 integer ATTRIBUTE Ascend-Idle-Limit 244 integer ATTRIBUTE Ascend-Preempt-Limit 245 integer ATTRIBUTE Ascend-Callback 246 integer ATTRIBUTE Ascend-Data-Svc 247 integer ATTRIBUTE Ascend-Force-56 248 integer ATTRIBUTE Ascend-Billing-Number 249 string ATTRIBUTE Ascend-Call-By-Call 250 integer ATTRIBUTE Ascend-Transit-Number 251 string ATTRIBUTE Ascend-Host-Info 252 string ATTRIBUTE Ascend-PPP-Address 253 ipaddr ATTRIBUTE Ascend-MPP-Idle-Percent 254 integer ATTRIBUTE Ascend-Xmit-Rate 255 integer # Ascend protocols VALUE Service-Type Dialout-Framed-User 5 VALUE Framed-Protocol ARA 255 VALUE Framed-Protocol MPP 256 VALUE Framed-Protocol EURAW 257 VALUE Framed-Protocol EUUI 258 VALUE Framed-Protocol X25 259 VALUE Framed-Protocol COMB 260 VALUE Framed-Protocol FR 261 VALUE Framed-Protocol MP 262 VALUE Framed-Protocol FR-CIR 263 # # Ascend specific extensions # Used by ASCEND MAX/Pipeline products (see above) # VALUE Ascend-FR-Direct FR-Direct-No 0 VALUE Ascend-FR-Direct FR-Direct-Yes 1 VALUE Ascend-Handle-IPX Handle-IPX-None 0 VALUE Ascend-Handle-IPX Handle-IPX-Client 1 VALUE Ascend-Handle-IPX Handle-IPX-Server 2 VALUE Ascend-IPX-Peer-Mode IPX-Peer-Router 0 VALUE Ascend-IPX-Peer-Mode IPX-Peer-Dialin 1 VALUE Ascend-Call-Type Nailed 1 VALUE Ascend-Call-Type Nailed/Mpp 2 VALUE Ascend-Call-Type Perm/Switched 3 VALUE Ascend-FT1-Caller FT1-No 0 VALUE Ascend-FT1-Caller FT1-Yes 1 VALUE Ascend-PRI-Number-Type Unknown-Number 0 VALUE Ascend-PRI-Number-Type Intl-Number 1 VALUE Ascend-PRI-Number-Type National-Number 2 VALUE Ascend-PRI-Number-Type Local-Number 4 VALUE Ascend-PRI-Number-Type Abbrev-Number 5 VALUE Ascend-Route-IPX Route-IPX-No 0 VALUE Ascend-Route-IPX Route-IPX-Yes 1 VALUE Ascend-Bridge Bridge-No 0 VALUE Ascend-Bridge Bridge-Yes 1 VALUE Ascend-TS-Idle-Mode TS-Idle-None 0 VALUE Ascend-TS-Idle-Mode TS-Idle-Input 1 VALUE Ascend-TS-Idle-Mode TS-Idle-Input-Output 2 VALUE Ascend-Send-Auth Send-Auth-None 0 VALUE Ascend-Send-Auth Send-Auth-PAP 1 VALUE Ascend-Send-Auth Send-Auth-CHAP 2 VALUE Ascend-Send-Auth Send-Auth-MS-CHAP 3 VALUE Ascend-Link-Compression Link-Comp-None 0 VALUE Ascend-Link-Compression Link-Comp-Stac 1 VALUE Ascend-Link-Compression Link-Comp-Stac-Draft-9 2 VALUE Ascend-Link-Compression Link-Comp-MS-Stac 3 VALUE Ascend-History-Weigh-Type History-Constant 0 VALUE Ascend-History-Weigh-Type History-Linear 1 VALUE Ascend-History-Weigh-Type History-Quadratic 2 VALUE Ascend-Callback Callback-No 0 VALUE Ascend-Callback Callback-Yes 1 VALUE Ascend-Expect-Callback Expect-Callback-No 0 VALUE Ascend-Expect-Callback Expect-Callback-Yes 1 VALUE Ascend-Data-Svc Switched-Voice-Bearer 0 VALUE Ascend-Data-Svc Switched-56KR 1 VALUE Ascend-Data-Svc Switched-64K 2 VALUE Ascend-Data-Svc Switched-64KR 3 VALUE Ascend-Data-Svc Switched-56K 4 VALUE Ascend-Data-Svc Switched-384KR 5 VALUE Ascend-Data-Svc Switched-384K 6 VALUE Ascend-Data-Svc Switched-1536K 7 VALUE Ascend-Data-Svc Switched-1536KR 8 VALUE Ascend-Data-Svc Switched-128K 9 VALUE Ascend-Data-Svc Switched-192K 10 VALUE Ascend-Data-Svc Switched-256K 11 VALUE Ascend-Data-Svc Switched-320K 12 VALUE Ascend-Data-Svc Switched-384K-MR 13 VALUE Ascend-Data-Svc Switched-448K 14 VALUE Ascend-Data-Svc Switched-512K 15 VALUE Ascend-Data-Svc Switched-576K 16 VALUE Ascend-Data-Svc Switched-640K 17 VALUE Ascend-Data-Svc Switched-704K 18 VALUE Ascend-Data-Svc Switched-768K 19 VALUE Ascend-Data-Svc Switched-832K 20 VALUE Ascend-Data-Svc Switched-896K 21 VALUE Ascend-Data-Svc Switched-960K 22 VALUE Ascend-Data-Svc Switched-1024K 23 VALUE Ascend-Data-Svc Switched-1088K 24 VALUE Ascend-Data-Svc Switched-1152K 25 VALUE Ascend-Data-Svc Switched-1216K 26 VALUE Ascend-Data-Svc Switched-1280K 27 VALUE Ascend-Data-Svc Switched-1344K 28 VALUE Ascend-Data-Svc Switched-1408K 29 VALUE Ascend-Data-Svc Switched-1472K 30 VALUE Ascend-Data-Svc Switched-1600K 31 VALUE Ascend-Data-Svc Switched-1664K 32 VALUE Ascend-Data-Svc Switched-1728K 33 VALUE Ascend-Data-Svc Switched-1792K 34 VALUE Ascend-Data-Svc Switched-1856K 35 VALUE Ascend-Data-Svc Switched-1920K 36 VALUE Ascend-Data-Svc Switched-inherited 37 VALUE Ascend-Data-Svc Switched-restricted-bearer-x30 38 VALUE Ascend-Data-Svc Switched-clear-bearer-v110 39 VALUE Ascend-Data-Svc Switched-restricted-64-x30 40 VALUE Ascend-Data-Svc Switched-clear-56-v110 41 VALUE Ascend-Data-Svc Switched-modem 42 VALUE Ascend-Data-Svc Switched-atmodem 43 VALUE Ascend-Data-Svc Nailed-56KR 1 VALUE Ascend-Data-Svc Nailed-64K 2 VALUE Ascend-Force-56 Force-56-No 0 VALUE Ascend-Force-56 Force-56-Yes 1 VALUE Ascend-PW-Lifetime Lifetime-In-Days 0 VALUE Ascend-PW-Warntime Days-Of-Warning 0 VALUE Ascend-PPP-VJ-1172 PPP-VJ-1172 1 VALUE Ascend-PPP-VJ-Slot-Comp VJ-Slot-Comp-No 1 VALUE Ascend-Require-Auth Not-Require-Auth 0 VALUE Ascend-Require-Auth Require-Auth 1 VALUE Ascend-Token-Immediate Tok-Imm-No 0 VALUE Ascend-Token-Immediate Tok-Imm-Yes 1 VALUE Ascend-DBA-Monitor DBA-Transmit 0 VALUE Ascend-DBA-Monitor DBA-Transmit-Recv 1 VALUE Ascend-DBA-Monitor DBA-None 2 VALUE Ascend-FR-Type Ascend-FR-DTE 0 VALUE Ascend-FR-Type Ascend-FR-DCE 1 VALUE Ascend-FR-Type Ascend-FR-NNI 2 VALUE Ascend-FR-Link-Mgt Ascend-FR-No-Link-Mgt 0 VALUE Ascend-FR-Link-Mgt Ascend-FR-T1-617D 1 VALUE Ascend-FR-Link-Mgt Ascend-FR-Q-933A 2 VALUE Ascend-FR-LinkUp Ascend-LinkUp-Default 0 VALUE Ascend-FR-LinkUp Ascend-LinkUp-AlwaysUp 1 VALUE Ascend-Multicast-Client Multicast-No 0 VALUE Ascend-Multicast-Client Multicast-Yes 1 VALUE Ascend-User-Acct-Type Ascend-User-Acct-None 0 VALUE Ascend-User-Acct-Type Ascend-User-Acct-User 1 VALUE Ascend-User-Acct-Type Ascend-User-Acct-User-Default 2 VALUE Ascend-User-Acct-Base Base-10 0 VALUE Ascend-User-Acct-Base Base-16 1 VALUE Ascend-DHCP-Reply DHCP-Reply-No 0 VALUE Ascend-DHCP-Reply DHCP-Reply-Yes 1 VALUE Ascend-Client-Assign-DNS DNS-Assign-No 0 VALUE Ascend-Client-Assign-DNS DNS-Assign-Yes 1 VALUE Ascend-Event-Type Ascend-ColdStart 1 VALUE Ascend-Event-Type Ascend-Session-Event 2 VALUE Ascend-BACP-Enable BACP-No 0 VALUE Ascend-BACP-Enable BACP-Yes 1 VALUE Ascend-Dialout-Allowed Dialout-Not-Allowed 0 VALUE Ascend-Dialout-Allowed Dialout-Allowed 1 VALUE Ascend-Shared-Profile-Enable Shared-Profile-No 0 VALUE Ascend-Shared-Profile-Enable Shared-Profile-Yes 1 VALUE Ascend-Temporary-Rtes Temp-Rtes-No 0 VALUE Ascend-Temporary-Rtes Temp-Rtes-Yes 1 ppp-2.5.0/pppd/plugins/radius/etc/dictionary.compat0000644000175000017500000000256311043063522017300 00000000000000# # Obsolete names for backwards compatibility with older users files. # ATTRIBUTE Client-Id 4 ipaddr ATTRIBUTE Client-Port-Id 5 integer ATTRIBUTE User-Service-Type 6 integer ATTRIBUTE Framed-Address 8 ipaddr ATTRIBUTE Framed-Netmask 9 ipaddr ATTRIBUTE Framed-Filter-Id 11 string ATTRIBUTE Login-Host 14 ipaddr ATTRIBUTE Login-Port 16 integer ATTRIBUTE Old-Password 17 string ATTRIBUTE Port-Message 18 string ATTRIBUTE Dialback-No 19 string ATTRIBUTE Dialback-Name 20 string ATTRIBUTE Challenge-State 24 string VALUE Framed-Compression Van-Jacobsen-TCP-IP 1 VALUE Framed-Compression VJ-TCP-IP 1 VALUE Service-Type Shell-User 6 VALUE Auth-Type Unix 1 VALUE Service-Type Dialback-Login-User 3 VALUE Service-Type Dialback-Framed-User 4 # # For compatibility with MERIT users files. # ATTRIBUTE NAS-Port 5 integer ATTRIBUTE Login-Host 14 ipaddr ATTRIBUTE Login-Callback-Number 19 string ATTRIBUTE Framed-Callback-Id 20 string ATTRIBUTE Client-Port-DNIS 30 string ATTRIBUTE Caller-ID 31 string VALUE Service-Type Login 1 VALUE Service-Type Framed 2 VALUE Service-Type Callback-Login 3 VALUE Service-Type Callback-Framed 4 VALUE Service-Type Exec-User 7 # # For compatibility with ESVA RADIUS, Old Cistron RADIUS # ATTRIBUTE Session 1034 integer ATTRIBUTE User-Name-Is-Star 1035 integer VALUE User-Name-Is-Star No 0 VALUE User-Name-Is-Star Yes 1 ppp-2.5.0/pppd/plugins/radius/etc/dictionary.merit0000644000175000017500000000112711043063522017130 00000000000000# # Experimental extensions, configuration only (for check-items) # Names/numbers as per the MERIT extensions (if possible). # ATTRIBUTE NAS-Identifier 32 string ATTRIBUTE Proxy-State 33 string ATTRIBUTE Login-LAT-Service 34 string ATTRIBUTE Login-LAT-Node 35 string ATTRIBUTE Login-LAT-Group 36 string ATTRIBUTE Framed-AppleTalk-Link 37 integer ATTRIBUTE Framed-AppleTalk-Network 38 integer ATTRIBUTE Framed-AppleTalk-Zone 39 string ATTRIBUTE Acct-Input-Packets 47 integer ATTRIBUTE Acct-Output-Packets 48 integer # 8 is a MERIT extension. VALUE Service-Type Authenticate-Only 8 ppp-2.5.0/pppd/plugins/radius/etc/dictionary.microsoft0000644000175000017500000000513111043063522020014 00000000000000# # Microsoft's VSA's, from RFC 2548 # # $Id: dictionary.microsoft,v 1.1 2004/11/14 07:26:26 paulus Exp $ # VENDOR Microsoft 311 Microsoft ATTRIBUTE MS-CHAP-Response 1 string Microsoft ATTRIBUTE MS-CHAP-Error 2 string Microsoft ATTRIBUTE MS-CHAP-CPW-1 3 string Microsoft ATTRIBUTE MS-CHAP-CPW-2 4 string Microsoft ATTRIBUTE MS-CHAP-LM-Enc-PW 5 string Microsoft ATTRIBUTE MS-CHAP-NT-Enc-PW 6 string Microsoft ATTRIBUTE MS-MPPE-Encryption-Policy 7 string Microsoft # This is referred to as both singular and plural in the RFC. # Plural seems to make more sense. ATTRIBUTE MS-MPPE-Encryption-Type 8 string Microsoft ATTRIBUTE MS-MPPE-Encryption-Types 8 string Microsoft ATTRIBUTE MS-RAS-Vendor 9 integer Microsoft ATTRIBUTE MS-CHAP-Domain 10 string Microsoft ATTRIBUTE MS-CHAP-Challenge 11 string Microsoft ATTRIBUTE MS-CHAP-MPPE-Keys 12 string Microsoft ATTRIBUTE MS-BAP-Usage 13 integer Microsoft ATTRIBUTE MS-Link-Utilization-Threshold 14 integer Microsoft ATTRIBUTE MS-Link-Drop-Time-Limit 15 integer Microsoft ATTRIBUTE MS-MPPE-Send-Key 16 string Microsoft ATTRIBUTE MS-MPPE-Recv-Key 17 string Microsoft ATTRIBUTE MS-RAS-Version 18 string Microsoft ATTRIBUTE MS-Old-ARAP-Password 19 string Microsoft ATTRIBUTE MS-New-ARAP-Password 20 string Microsoft ATTRIBUTE MS-ARAP-PW-Change-Reason 21 integer Microsoft ATTRIBUTE MS-Filter 22 string Microsoft ATTRIBUTE MS-Acct-Auth-Type 23 integer Microsoft ATTRIBUTE MS-Acct-EAP-Type 24 integer Microsoft ATTRIBUTE MS-CHAP2-Response 25 string Microsoft ATTRIBUTE MS-CHAP2-Success 26 string Microsoft ATTRIBUTE MS-CHAP2-CPW 27 string Microsoft ATTRIBUTE MS-Primary-DNS-Server 28 ipaddr Microsoft ATTRIBUTE MS-Secondary-DNS-Server 29 ipaddr Microsoft ATTRIBUTE MS-Primary-NBNS-Server 30 ipaddr Microsoft ATTRIBUTE MS-Secondary-NBNS-Server 31 ipaddr Microsoft #ATTRIBUTE MS-ARAP-Challenge 33 string Microsoft # # Integer Translations # # MS-BAP-Usage Values VALUE MS-BAP-Usage Not-Allowed 0 VALUE MS-BAP-Usage Allowed 1 VALUE MS-BAP-Usage Required 2 # MS-ARAP-Password-Change-Reason Values VALUE MS-ARAP-PW-Change-Reason Just-Change-Password 1 VALUE MS-ARAP-PW-Change-Reason Expired-Password 2 VALUE MS-ARAP-PW-Change-Reason Admin-Requires-Password-Change 3 VALUE MS-ARAP-PW-Change-Reason Password-Too-Short 4 # MS-Acct-Auth-Type Values VALUE MS-Acct-Auth-Type PAP 1 VALUE MS-Acct-Auth-Type CHAP 2 VALUE MS-Acct-Auth-Type MS-CHAP-1 3 VALUE MS-Acct-Auth-Type MS-CHAP-2 4 VALUE MS-Acct-Auth-Type EAP 5 # MS-Acct-EAP-Type Values VALUE MS-Acct-EAP-Type MD5 4 VALUE MS-Acct-EAP-Type OTP 5 VALUE MS-Acct-EAP-Type Generic-Token-Card 6 VALUE MS-Acct-EAP-Type TLS 13 ppp-2.5.0/pppd/plugins/radius/etc/issue0000644000175000017500000000020711043063522014772 00000000000000(\I) ----------------------------------------------------- \S \R (\N) (port \L) ----------------------------------------------------- ppp-2.5.0/pppd/plugins/radius/etc/port-id-map0000644000175000017500000000063211043063522015775 00000000000000# # port-id-map # # This file describes the ttyname to port id mapping. The port id # is reported as part of a RADIUS authentication or accouting request. # #ttyname (as returned by ttyname(3)) port-id /dev/tty1 1 /dev/tty2 2 /dev/tty3 3 /dev/tty4 4 /dev/tty5 5 /dev/tty6 6 /dev/tty7 7 /dev/tty8 8 /dev/ttyS0 9 /dev/ttyS1 10 /dev/ttyS2 11 /dev/ttyS3 12 /dev/ttyS4 13 /dev/ttyS5 14 /dev/ttyS6 15 /dev/ttyS7 16 ppp-2.5.0/pppd/plugins/radius/etc/radiusclient.conf0000644000175000017500000000610511043063522017257 00000000000000# General settings # specify which authentication comes first respectively which # authentication is used. possible values are: "radius" and "local". # if you specify "radius,local" then the RADIUS server is asked # first then the local one. if only one keyword is specified only # this server is asked. auth_order radius # maximum login tries a user has (default 4) login_tries 4 # timeout for all login tries (default 60) # if this time is exceeded the user is kicked out login_timeout 60 # name of the nologin file which when it exists disables logins. # it may be extended by the ttyname which will result in # a terminal specific lock (e.g. /etc/nologin.ttyS2 will disable # logins on /dev/ttyS2) (default /etc/nologin) nologin /etc/nologin # name of the issue file. it's only display when no username is passed # on the radlogin command line (default /etc/radiusclient/issue) issue /usr/local/etc/radiusclient/issue # RADIUS settings # RADIUS server to use for authentication requests. this config # item can appear more then one time. if multiple servers are # defined they are tried in a round robin fashion if one # server is not answering. # optionally you can specify a the port number on which is remote # RADIUS listens separated by a colon from the hostname. if # no port is specified /etc/services is consulted of the radius # service. if this fails also a compiled in default is used. authserver localhost:1812 # RADIUS server to use for accouting requests. All that I # said for authserver applies, too. # acctserver localhost:1813 # file holding shared secrets used for the communication # between the RADIUS client and server servers /usr/local/etc/radiusclient/servers # dictionary of allowed attributes and values # just like in the normal RADIUS distributions dictionary /usr/local/etc/radiusclient/dictionary # program to call for a RADIUS authenticated login # (default /usr/sbin/login.radius) login_radius /usr/local/sbin/login.radius # file which holds sequence number for communication with the # RADIUS server seqfile /var/run/radius.seq # file which specifies mapping between ttyname and NAS-Port attribute mapfile /usr/local/etc/radiusclient/port-id-map # default authentication realm to append to all usernames if no # realm was explicitly specified by the user # the radiusd directly form Livingston doesnt use any realms, so leave # it blank then default_realm # time to wait for a reply from the RADIUS server radius_timeout 10 # resend request this many times before trying the next server radius_retries 3 # NAS-Identifier # # If supplied, this option will cause the client to send the given string # as the contents of the NAS-Identifier attribute in RADIUS requests. No # NAS-IP-Address attribute will be sent in this case. # # The default behavior is to send a NAS-IP-Address option and not send # a NAS-Identifier. The value of the NAS-IP-Address option is chosen # by resolving the system hostname. # nas_identifier MyUniqueNASName # LOCAL settings # program to execute for local login # it must support the -f flag for preauthenticated login login_local /bin/login ppp-2.5.0/pppd/plugins/radius/etc/radiusclient.conf.in0000644000175000017500000000601711043063522017666 00000000000000# General settings # specify which authentication comes first respectively which # authentication is used. possible values are: "radius" and "local". # if you specify "radius,local" then the RADIUS server is asked # first then the local one. if only one keyword is specified only # this server is asked. auth_order radius # maximum login tries a user has (default 4) login_tries 4 # timeout for all login tries (default 60) # if this time is exceeded the user is kicked out login_timeout 60 # name of the nologin file which when it exists disables logins. # it may be extended by the ttyname which will result in # a terminal specific lock (e.g. /etc/nologin.ttyS2 will disable # logins on /dev/ttyS2) (default /etc/nologin) nologin /etc/nologin # name of the issue file. it's only display when no username is passed # on the radlogin command line (default /etc/radiusclient/issue) issue @pkgsysconfdir@/issue # RADIUS settings # RADIUS server to use for authentication requests. this config # item can appear more then one time. if multiple servers are # defined they are tried in a round robin fashion if one # server is not answering. # optionally you can specify a the port number on which is remote # RADIUS listens separated by a colon from the hostname. if # no port is specified /etc/services is consulted of the radius # service. if this fails also a compiled in default is used. authserver localhost:1812 # RADIUS server to use for accouting requests. All that I # said for authserver applies, too. # acctserver localhost:1813 # file holding shared secrets used for the communication # between the RADIUS client and server servers @pkgsysconfdir@/servers # dictionary of allowed attributes and values # just like in the normal RADIUS distributions dictionary @pkgsysconfdir@/dictionary # program to call for a RADIUS authenticated login # (default /usr/sbin/login.radius) login_radius @sbindir@/login.radius # file which holds sequence number for communication with the # RADIUS server seqfile /var/run/radius.seq # file which specifies mapping between ttyname and NAS-Port attribute mapfile @pkgsysconfdir@/port-id-map # default authentication realm to append to all usernames if no # realm was explicitly specified by the user # the radiusd directly form Livingston doesnt use any realms, so leave # it blank then default_realm # time to wait for a reply from the RADIUS server radius_timeout 10 # resend request this many times before trying the next server radius_retries 3 # NAS-Identifier # # If supplied, this option will cause the client to send the given string # as the contents of the NAS-Identifier attribute in RADIUS requests. No # NAS-IP-Address attribute will be sent in this case. # # The default behavior is to send a NAS-IP-Address option and not send # a NAS-Identifier. The value of the NAS-IP-Address option is chosen # by resolving the system hostname. # nas_identifier MyUniqueNASName # LOCAL settings # program to execute for local login # it must support the -f flag for preauthenticated login login_local /bin/login ppp-2.5.0/pppd/plugins/radius/etc/realms0000644000175000017500000000135511043063522015132 00000000000000# /etc/radiusclient/realms # # Handle realm @netservers.co.uk on an internal RADIUS server # (note the server must be told to strip the realm) #authserver netservers.co.uk 192.168.1.1:1812 #acctserver netservers.co.uk 192.168.1.1:1813 # users in realm @example.com are handled by separate servers #authserver example.com 10.0.0.1:1812 #acctserver example.com 10.0.0.2:1813 # the DEFAULT realm matches users that do not supply a realm #authserver DEFAULT 192.168.1.1:1812 #acctserver DEFAULT 192.168.1.1:1813 # Any realms that do not match in the realms file automatically fall # through to the standard radius plugin which uses the servers in the # radiusclient.conf file. Note that this is different than the # DEFAULT realm match, above. ppp-2.5.0/pppd/plugins/radius/etc/servers0000644000175000017500000000024711043063522015337 00000000000000#Server Name or Client/Server pair Key #---------------- --------------- #portmaster.elemental.net hardlyasecret #portmaster2.elemental.net donttellanyone ppp-2.5.0/pppd/plugins/radius/Makefile.am0000664000175000017500000000247314314203161015210 00000000000000pppd_plugin_LTLIBRARIES = radius.la radattr.la radrealms.la pppd_plugindir = $(PPPD_PLUGIN_DIR) noinst_LTLIBRARIES = libradiusclient.la dist_man8_MANS = pppd-radius.8 pppd-radattr.8 noinst_HEADERS = \ includes.h \ options.h \ pathnames.h \ radiusclient.h EXTRA_FILES = \ COPYRIGHT EXTRA_ETC = \ etc/dictionary \ etc/dictionary.ascend \ etc/dictionary.compat \ etc/dictionary.merit \ etc/dictionary.microsoft \ etc/issue \ etc/port-id-map \ etc/radiusclient.conf \ etc/radiusclient.conf.in \ etc/realms \ etc/servers RADIUS_CPPFLAGS = -I${top_srcdir} -DRC_LOG_FACILITY=LOG_DAEMON RADIUS_LDFLAGS = -module -avoid-version $(LDFLAGS) radius_la_CPPFLAGS = $(RADIUS_CPPFLAGS) radius_la_LDFLAGS = $(RADIUS_LDFLAGS) radius_la_SOURCES = radius.c radius_la_LIBADD = libradiusclient.la radattr_la_CPPFLAGS = $(RADIUS_CPPFLAGS) radattr_la_LDFLAGS = $(RADIUS_LDFLAGS) radattr_la_SOURCES = radattr.c radrealms_la_CPPFLAGS = $(RADIUS_CPPFLAGS) radrealms_la_LDFLAGS = $(RADIUS_LDFLAGS) radrealms_la_SOURCES = radrealms.c libradiusclient_la_SOURCES = \ avpair.c buildreq.c config.c dict.c ip_util.c \ clientid.c sendserver.c lock.c util.c md5.c libradiusclient_la_CPPFLAGS = $(RADIUS_CPPFLAGS) -DSYSCONFDIR=\"${sysconfdir}\" EXTRA_DIST = \ $(EXTRA_FILES) \ $(EXTRA_ETC) ppp-2.5.0/pppd/plugins/radius/includes.h0000664000175000017500000000176614273050614015146 00000000000000/* * $Id: includes.h,v 1.1 2004/11/14 07:26:26 paulus Exp $ * * Copyright (C) 1997 Lars Fenneberg * * Copyright 1992 Livingston Enterprises, Inc. * * Copyright 1992,1993, 1994,1995 The Regents of the University of Michigan * and Merit Network, Inc. All Rights Reserved * * See the file COPYRIGHT for the respective terms and conditions. * If the file is missing contact me at lf@elemental.net * and I'll send you a copy. * */ #include #include #include #include #include #include #include #include #include #include #include #include #include #ifndef PATH_MAX #define PATH_MAX 1024 #endif #ifndef UCHAR_MAX # define UCHAR_MAX 255 #endif #include #include #include #include #include #include /* rlib/lock.c */ int do_lock_exclusive(int); int do_unlock(int); ppp-2.5.0/pppd/plugins/radius/options.h0000644000175000017500000000375012143427351015024 00000000000000/* * $Id: options.h,v 1.1 2004/11/14 07:26:26 paulus Exp $ * * Copyright (C) 1996 Lars Fenneberg * * See the file COPYRIGHT for the respective terms and conditions. * If the file is missing contact me at lf@elemental.net * and I'll send you a copy. * */ #define OPTION_LEN 64 /* ids for different option types */ #define OT_STR (1<<0) /* string */ #define OT_INT (1<<1) /* integer */ #define OT_SRV (1<<2) /* server list */ #define OT_AUO (1<<3) /* authentication order */ #define OT_ANY ((unsigned int)~0) /* used internally */ /* status types */ #define ST_UNDEF (1<<0) /* option is undefined */ typedef struct _option { char name[OPTION_LEN]; /* name of the option */ int type, status; /* type and status */ void *val; /* pointer to option value */ } OPTION; static SERVER acctserver = {0}; static SERVER authserver = {0}; int default_tries = 4; int default_timeout = 60; static OPTION config_options[] = { /* internally used options */ {"config_file", OT_STR, ST_UNDEF, NULL}, /* General options */ {"auth_order", OT_AUO, ST_UNDEF, NULL}, {"login_tries", OT_INT, ST_UNDEF, &default_tries}, {"login_timeout", OT_INT, ST_UNDEF, &default_timeout}, {"nologin", OT_STR, ST_UNDEF, "/etc/nologin"}, {"issue", OT_STR, ST_UNDEF, "/etc/radiusclient/issue"}, /* RADIUS specific options */ {"authserver", OT_SRV, ST_UNDEF, &authserver}, {"acctserver", OT_SRV, ST_UNDEF, &acctserver}, {"servers", OT_STR, ST_UNDEF, NULL}, {"dictionary", OT_STR, ST_UNDEF, NULL}, {"login_radius", OT_STR, ST_UNDEF, "/usr/sbin/login.radius"}, {"seqfile", OT_STR, ST_UNDEF, NULL}, {"mapfile", OT_STR, ST_UNDEF, NULL}, {"default_realm", OT_STR, ST_UNDEF, NULL}, {"radius_timeout", OT_INT, ST_UNDEF, NULL}, {"radius_retries", OT_INT, ST_UNDEF, NULL}, {"nas_identifier", OT_STR, ST_UNDEF, ""}, {"bindaddr", OT_STR, ST_UNDEF, NULL}, /* local options */ {"login_local", OT_STR, ST_UNDEF, NULL}, }; static int num_options = ((sizeof(config_options))/(sizeof(config_options[0]))); ppp-2.5.0/pppd/plugins/radius/pathnames.h0000664000175000017500000000141414314203161015277 00000000000000/* * $Id: pathnames.h,v 1.1 2004/11/14 07:26:26 paulus Exp $ * * Copyright (C) 1995,1996 Lars Fenneberg * * Copyright 1992 Livingston Enterprises, Inc. * * Copyright 1992,1993, 1994,1995 The Regents of the University of Michigan * and Merit Network, Inc. All Rights Reserved * * See the file COPYRIGHT for the respective terms and conditions. * If the file is missing contact me at lf@elemental.net * and I'll send you a copy. * */ #ifndef PATHNAMES_H #define PATHNAMES_H #define PPP_PATH_DEV_URANDOM "/dev/urandom" /* Linux only */ #define PPP_PATH_ETC_ISSUE "/etc/issue" /* normally defined in the Makefile */ #ifndef PPP_PATH_ETC_RADIUSCLIENT_CONF #define PPP_PATH_ETC_RADIUSCLIENT_CONF SYSCONFDIR "/radiusclient.conf" #endif #endif /* PATHNAMES_H */ ppp-2.5.0/pppd/plugins/radius/radiusclient.h0000644000175000017500000003225114353435407016023 00000000000000/* * $Id: radiusclient.h,v 1.1 2004/11/14 07:26:26 paulus Exp $ * * Copyright (C) 1995,1996,1997,1998 Lars Fenneberg * * Copyright 1992 Livingston Enterprises, Inc. * * Copyright 1992,1993, 1994,1995 The Regents of the University of Michigan * and Merit Network, Inc. All Rights Reserved * * See the file COPYRIGHT for the respective terms and conditions. * If the file is missing contact me at lf@elemental.net * and I'll send you a copy. * */ #ifndef RADIUSCLIENT_H #define RADIUSCLIENT_H #include #include #include #include #include #include #ifndef _UINT4_T /* This works for all machines that Linux runs on... */ typedef unsigned int UINT4; typedef int INT4; #endif #define AUTH_VECTOR_LEN 16 #define AUTH_PASS_LEN (3 * 16) /* multiple of 16 */ #define AUTH_ID_LEN 64 #define AUTH_STRING_LEN 253 /* maximum of 253 */ #define BUFFER_LEN 8192 #define NAME_LENGTH 32 #define GETSTR_LENGTH 128 /* must be bigger than AUTH_PASS_LEN */ /* codes for radius_buildreq, radius_getport, etc. */ #define AUTH 0 #define ACCT 1 /* defines for config.c */ #define SERVER_MAX 8 #define AUTH_LOCAL_FST (1<<0) #define AUTH_RADIUS_FST (1<<1) #define AUTH_LOCAL_SND (1<<2) #define AUTH_RADIUS_SND (1<<3) typedef struct server { int max; char *name[SERVER_MAX]; unsigned short port[SERVER_MAX]; } SERVER; typedef struct pw_auth_hdr { u_char code; u_char id; u_short length; u_char vector[AUTH_VECTOR_LEN]; u_char data[2]; } AUTH_HDR; #define AUTH_HDR_LEN 20 #define MAX_SECRET_LENGTH (3 * 16) /* MUST be multiple of 16 */ #define CHAP_VALUE_LENGTH 16 #define PW_AUTH_UDP_PORT 1812 #define PW_ACCT_UDP_PORT 1813 #define PW_TYPE_STRING 0 #define PW_TYPE_INTEGER 1 #define PW_TYPE_IPADDR 2 #define PW_TYPE_DATE 3 #define PW_TYPE_ABINARY 4 #define PW_TYPE_OCTETS 5 #define PW_TYPE_IFID 6 #define PW_TYPE_IPV6ADDR 7 #define PW_TYPE_IPV6PREFIX 8 #define PW_TYPE_BYTE 9 #define PW_TYPE_SHORT 10 #define PW_TYPE_ETHERNET 11 #define PW_TYPE_SIGNED 12 #define PW_TYPE_COMBO_IP 13 #define PW_TYPE_TLV 14 /* standard RADIUS codes */ #define PW_ACCESS_REQUEST 1 #define PW_ACCESS_ACCEPT 2 #define PW_ACCESS_REJECT 3 #define PW_ACCOUNTING_REQUEST 4 #define PW_ACCOUNTING_RESPONSE 5 #define PW_ACCOUNTING_STATUS 6 #define PW_PASSWORD_REQUEST 7 #define PW_PASSWORD_ACK 8 #define PW_PASSWORD_REJECT 9 #define PW_ACCOUNTING_MESSAGE 10 #define PW_ACCESS_CHALLENGE 11 #define PW_STATUS_SERVER 12 #define PW_STATUS_CLIENT 13 /* standard RADIUS attribute-value pairs */ #define PW_USER_NAME 1 /* string */ #define PW_USER_PASSWORD 2 /* string */ #define PW_CHAP_PASSWORD 3 /* string */ #define PW_NAS_IP_ADDRESS 4 /* ipaddr */ #define PW_NAS_PORT 5 /* integer */ #define PW_SERVICE_TYPE 6 /* integer */ #define PW_FRAMED_PROTOCOL 7 /* integer */ #define PW_FRAMED_IP_ADDRESS 8 /* ipaddr */ #define PW_FRAMED_IP_NETMASK 9 /* ipaddr */ #define PW_FRAMED_ROUTING 10 /* integer */ #define PW_FILTER_ID 11 /* string */ #define PW_FRAMED_MTU 12 /* integer */ #define PW_FRAMED_COMPRESSION 13 /* integer */ #define PW_LOGIN_IP_HOST 14 /* ipaddr */ #define PW_LOGIN_SERVICE 15 /* integer */ #define PW_LOGIN_PORT 16 /* integer */ #define PW_OLD_PASSWORD 17 /* string */ /* deprecated */ #define PW_REPLY_MESSAGE 18 /* string */ #define PW_LOGIN_CALLBACK_NUMBER 19 /* string */ #define PW_FRAMED_CALLBACK_ID 20 /* string */ #define PW_EXPIRATION 21 /* date */ /* deprecated */ #define PW_FRAMED_ROUTE 22 /* string */ #define PW_FRAMED_IPX_NETWORK 23 /* integer */ #define PW_STATE 24 /* string */ #define PW_CLASS 25 /* string */ #define PW_VENDOR_SPECIFIC 26 /* string */ #define PW_SESSION_TIMEOUT 27 /* integer */ #define PW_IDLE_TIMEOUT 28 /* integer */ #define PW_TERMINATION_ACTION 29 /* integer */ #define PW_CALLED_STATION_ID 30 /* string */ #define PW_CALLING_STATION_ID 31 /* string */ #define PW_NAS_IDENTIFIER 32 /* string */ #define PW_PROXY_STATE 33 /* string */ #define PW_LOGIN_LAT_SERVICE 34 /* string */ #define PW_LOGIN_LAT_NODE 35 /* string */ #define PW_LOGIN_LAT_GROUP 36 /* string */ #define PW_FRAMED_APPLETALK_LINK 37 /* integer */ #define PW_FRAMED_APPLETALK_NETWORK 38 /* integer */ #define PW_FRAMED_APPLETALK_ZONE 39 /* string */ #define PW_CHAP_CHALLENGE 60 /* string */ #define PW_NAS_PORT_TYPE 61 /* integer */ #define PW_PORT_LIMIT 62 /* integer */ #define PW_LOGIN_LAT_PORT 63 /* string */ /* Vendor RADIUS attribute-value pairs */ #define PW_MS_CHAP_CHALLENGE 11 /* string */ #define PW_MS_CHAP_RESPONSE 1 /* string */ #define PW_MS_CHAP2_RESPONSE 25 /* string */ #define PW_MS_CHAP2_SUCCESS 26 /* string */ #define PW_MS_MPPE_ENCRYPTION_POLICY 7 /* string */ #define PW_MS_MPPE_ENCRYPTION_TYPE 8 /* string */ #define PW_MS_MPPE_ENCRYPTION_TYPES PW_MS_MPPE_ENCRYPTION_TYPE #define PW_MS_CHAP_MPPE_KEYS 12 /* string */ #define PW_MS_MPPE_SEND_KEY 16 /* string */ #define PW_MS_MPPE_RECV_KEY 17 /* string */ #define PW_MS_PRIMARY_DNS_SERVER 28 /* ipaddr */ #define PW_MS_SECONDARY_DNS_SERVER 29 /* ipaddr */ #define PW_MS_PRIMARY_NBNS_SERVER 30 /* ipaddr */ #define PW_MS_SECONDARY_NBNS_SERVER 31 /* ipaddr */ /* Accounting */ #define PW_ACCT_STATUS_TYPE 40 /* integer */ #define PW_ACCT_DELAY_TIME 41 /* integer */ #define PW_ACCT_INPUT_OCTETS 42 /* integer */ #define PW_ACCT_OUTPUT_OCTETS 43 /* integer */ #define PW_ACCT_SESSION_ID 44 /* string */ #define PW_ACCT_AUTHENTIC 45 /* integer */ #define PW_ACCT_SESSION_TIME 46 /* integer */ #define PW_ACCT_INPUT_PACKETS 47 /* integer */ #define PW_ACCT_OUTPUT_PACKETS 48 /* integer */ #define PW_ACCT_TERMINATE_CAUSE 49 /* integer */ #define PW_ACCT_MULTI_SESSION_ID 50 /* string */ #define PW_ACCT_LINK_COUNT 51 /* integer */ /* From RFC 2869 */ #define PW_ACCT_INPUT_GIGAWORDS 52 /* integer */ #define PW_ACCT_OUTPUT_GIGAWORDS 53 /* integer */ #define PW_ACCT_INTERIM_INTERVAL 85 /* integer */ /* Merit Experimental Extensions */ #define PW_USER_ID 222 /* string */ #define PW_USER_REALM 223 /* string */ /* Session limits */ #define PW_SESSION_OCTETS_LIMIT 227 /* integer */ #define PW_OCTETS_DIRECTION 228 /* integer */ /* Integer Translations */ /* SERVICE TYPES */ #define PW_LOGIN 1 #define PW_FRAMED 2 #define PW_CALLBACK_LOGIN 3 #define PW_CALLBACK_FRAMED 4 #define PW_OUTBOUND 5 #define PW_ADMINISTRATIVE 6 #define PW_NAS_PROMPT 7 #define PW_AUTHENTICATE_ONLY 8 #define PW_CALLBACK_NAS_PROMPT 9 /* FRAMED PROTOCOLS */ #define PW_PPP 1 #define PW_SLIP 2 #define PW_ARA 3 #define PW_GANDALF 4 #define PW_XYLOGICS 5 /* FRAMED ROUTING VALUES */ #define PW_NONE 0 #define PW_BROADCAST 1 #define PW_LISTEN 2 #define PW_BROADCAST_LISTEN 3 /* FRAMED COMPRESSION TYPES */ #define PW_VAN_JACOBSON_TCP_IP 1 #define PW_IPX_HEADER_COMPRESSION 2 /* LOGIN SERVICES */ #define PW_TELNET 0 #define PW_RLOGIN 1 #define PW_TCP_CLEAR 2 #define PW_PORTMASTER 3 #define PW_LAT 4 #define PW_X25_PAD 5 #define PW_X25_T3POS 6 /* TERMINATION ACTIONS */ #define PW_DEFAULT 0 #define PW_RADIUS_REQUEST 1 /* PROHIBIT PROTOCOL */ #define PW_DUMB 0 /* 1 and 2 are defined in FRAMED PROTOCOLS */ #define PW_AUTH_ONLY 3 #define PW_ALL 255 /* ACCOUNTING STATUS TYPES */ #define PW_STATUS_START 1 #define PW_STATUS_STOP 2 #define PW_STATUS_ALIVE 3 #define PW_STATUS_MODEM_START 4 #define PW_STATUS_MODEM_STOP 5 #define PW_STATUS_CANCEL 6 #define PW_ACCOUNTING_ON 7 #define PW_ACCOUNTING_OFF 8 /* ACCOUNTING TERMINATION CAUSES */ #define PW_USER_REQUEST 1 #define PW_LOST_CARRIER 2 #define PW_LOST_SERVICE 3 #define PW_ACCT_IDLE_TIMEOUT 4 #define PW_ACCT_SESSION_TIMEOUT 5 #define PW_ADMIN_RESET 6 #define PW_ADMIN_REBOOT 7 #define PW_PORT_ERROR 8 #define PW_NAS_ERROR 9 #define PW_NAS_REQUEST 10 #define PW_NAS_REBOOT 11 #define PW_PORT_UNNEEDED 12 #define PW_PORT_PREEMPTED 13 #define PW_PORT_SUSPENDED 14 #define PW_SERVICE_UNAVAILABLE 15 #define PW_CALLBACK 16 #define PW_USER_ERROR 17 #define PW_HOST_REQUEST 18 /* NAS PORT TYPES */ #define PW_ASYNC 0 #define PW_SYNC 1 #define PW_ISDN_SYNC 2 #define PW_ISDN_SYNC_V120 3 #define PW_ISDN_SYNC_V110 4 #define PW_VIRTUAL 5 /* AUTHENTIC TYPES */ #define PW_RADIUS 1 #define PW_LOCAL 2 #define PW_REMOTE 3 /* Session-Octets-Limit */ #define PW_OCTETS_DIRECTION_SUM 0 #define PW_OCTETS_DIRECTION_IN 1 #define PW_OCTETS_DIRECTION_OUT 2 #define PW_OCTETS_DIRECTION_MAX 3 /* Vendor codes */ #define VENDOR_NONE (-1) #define VENDOR_MICROSOFT 311 /* Server data structures */ typedef struct dict_attr { char name[NAME_LENGTH + 1]; /* attribute name */ int value; /* attribute index */ int type; /* string, int, etc. */ int vendorcode; /* vendor code */ struct dict_attr *next; } DICT_ATTR; typedef struct dict_value { char attrname[NAME_LENGTH +1]; char name[NAME_LENGTH + 1]; int value; struct dict_value *next; } DICT_VALUE; typedef struct vendor_dict { char vendorname[NAME_LENGTH + 1]; int vendorcode; DICT_ATTR *attributes; struct vendor_dict *next; } VENDOR_DICT; typedef struct value_pair { char name[NAME_LENGTH + 1]; int attribute; int vendorcode; int type; UINT4 lvalue; u_char strvalue[AUTH_STRING_LEN + 1]; struct value_pair *next; } VALUE_PAIR; /* don't change this, as it has to be the same as in the Merit radiusd code */ #define MGMT_POLL_SECRET "Hardlyasecret" /* Define return codes from "SendServer" utility */ #define BADRESP_RC -2 #define ERROR_RC -1 #define OK_RC 0 #define TIMEOUT_RC 1 typedef struct send_data /* Used to pass information to sendserver() function */ { u_char code; /* RADIUS packet code */ u_char seq_nbr; /* Packet sequence number */ char *server; /* Name/addrress of RADIUS server */ int svc_port; /* RADIUS protocol destination port */ int timeout; /* Session timeout in seconds */ int retries; VALUE_PAIR *send_pairs; /* More a/v pairs to send */ VALUE_PAIR *receive_pairs; /* Where to place received a/v pairs */ } SEND_DATA; typedef struct request_info { char secret[MAX_SECRET_LENGTH + 1]; u_char request_vector[AUTH_VECTOR_LEN]; } REQUEST_INFO; #ifndef MIN #define MIN(a, b) ((a) < (b) ? (a) : (b)) #endif #ifndef MAX #define MAX(a, b) ((a) > (b) ? (a) : (b)) #endif #ifndef PATH_MAX #define PATH_MAX 1024 #endif typedef struct env { int maxsize, size; char **env; } ENV; #define ENV_SIZE 128 /* Function prototypes */ /* avpair.c */ VALUE_PAIR *rc_avpair_add(VALUE_PAIR **, int, const void *, int, int); int rc_avpair_assign(VALUE_PAIR *, const void *, int); VALUE_PAIR *rc_avpair_new(int, const void *, int, int); VALUE_PAIR *rc_avpair_gen(AUTH_HDR *); VALUE_PAIR *rc_avpair_get(VALUE_PAIR *, UINT4); VALUE_PAIR *rc_avpair_copy(VALUE_PAIR *); void rc_avpair_insert(VALUE_PAIR **, VALUE_PAIR *, VALUE_PAIR *); void rc_avpair_free(VALUE_PAIR *); int rc_avpair_parse(char *, VALUE_PAIR **); int rc_avpair_tostr(VALUE_PAIR *, char *, int, char *, int); VALUE_PAIR *rc_avpair_readin(FILE *); /* buildreq.c */ void rc_buildreq(SEND_DATA *, int, char *, unsigned short, int, int); unsigned char rc_get_seqnbr(void); int rc_auth(UINT4, VALUE_PAIR *, VALUE_PAIR **, char *, REQUEST_INFO *); int rc_auth_using_server(SERVER *, UINT4, VALUE_PAIR *, VALUE_PAIR **, char *, REQUEST_INFO *); int rc_auth_proxy(VALUE_PAIR *, VALUE_PAIR **, char *); int rc_acct(UINT4, VALUE_PAIR *); int rc_acct_using_server(SERVER *, UINT4, VALUE_PAIR *); int rc_acct_proxy(VALUE_PAIR *); int rc_check(char *, unsigned short, char *); /* clientid.c */ int rc_read_mapfile(char *); UINT4 rc_map2id(const char *); /* config.c */ int rc_read_config(char *); char *rc_conf_str(char *); int rc_conf_int(char *); SERVER *rc_conf_srv(char *); int rc_find_server(char *, UINT4 *, char *); /* dict.c */ int rc_read_dictionary(char *); DICT_ATTR *rc_dict_getattr(int, int); DICT_ATTR *rc_dict_findattr(char *); DICT_VALUE *rc_dict_findval(char *); DICT_VALUE * rc_dict_getval(UINT4, char *); VENDOR_DICT * rc_dict_findvendor(char *); VENDOR_DICT * rc_dict_getvendor(int); /* ip_util.c */ UINT4 rc_get_ipaddr(const char *); int rc_good_ipaddr(const char *); const char *rc_ip_hostname(UINT4); UINT4 rc_own_ipaddress(void); UINT4 rc_own_bind_ipaddress(void); /* sendserver.c */ int rc_send_server(SEND_DATA *, char *, REQUEST_INFO *); /* util.c */ void rc_str2tm(char *, struct tm *); char *rc_mksid(void); void rc_mdelay(int); /* md5.c */ int rc_md5_calc(unsigned char *out, const unsigned char *in, unsigned int inl); #endif /* RADIUSCLIENT_H */ ppp-2.5.0/pppd/plugins/radius/pppd-radius.80000644000175000017500000000351714402506361015501 00000000000000.\" manual page [] for RADIUS plugin for pppd 2.4 .\" $Id: pppd-radius.8,v 1.5 2004/03/26 13:27:17 kad Exp $ .\" SH section heading .\" SS subsection heading .\" LP paragraph .\" IP indented paragraph .\" TP hanging label .TH PPPD-RADIUS 8 .SH NAME radius.so \- RADIUS authentication plugin for .BR pppd (8) .SH SYNOPSIS .B pppd [ .I options ] plugin radius.so .SH DESCRIPTION .LP The RADIUS plugin for pppd permits pppd to perform PAP, CHAP, MS-CHAP and MS-CHAPv2 authentication against a RADIUS server instead of the usual .I /etc/ppp/pap-secrets and .I /etc/ppp/chap-secrets files. .LP The RADIUS plugin is built on a library called .B radiusclient which has its own configuration files (usually in \fI/etc/radiusclient\fR), consult those files for more information on configuring the RADIUS plugin .SH OPTIONS The RADIUS plugin introduces one additional pppd option: .TP .BI "radius-config-file " filename The file .I filename is taken as the radiusclient configuration file. If this option is not used, then the plugin uses .I /etc/radiusclient/radiusclient.conf as the configuration file. .TP .BI "avpair " attribute=value Adds an Attribute-Value pair to be passed on to the RADIUS server on each request. .TP .BI map-to-ifname Sets Radius NAS-Port attribute to number equal to interface name (Default) .TP .BI map-to-ttyname Sets Radius NAS-Port attribute value via libradiusclient library .SH USAGE To use the plugin, simply supply the .B plugin radius.so option to pppd, and edit .I /etc/radiusclient/radiusclient.conf appropriately. If you use the RADIUS plugin, the normal pppd authentication schemes (login, checking the /etc/ppp/*-secrets files) are skipped. The RADIUS server should assign an IP address to the peer using the RADIUS Framed-IP-Address attribute. .SH SEE ALSO .BR pppd (8) " pppd-radattr" (8) .SH AUTHOR Dianne Skoll ppp-2.5.0/pppd/plugins/radius/pppd-radattr.80000644000175000017500000000214014402506361015642 00000000000000.\" manual page [] for RADATTR plugin for pppd 2.4 .\" $Id: pppd-radattr.8,v 1.2 2003/04/25 07:33:20 fcusack Exp $ .\" SH section heading .\" SS subsection heading .\" LP paragraph .\" IP indented paragraph .\" TP hanging label .TH PPPD-RADATTR 8 .SH NAME radattr.so \- RADIUS utility plugin for .BR pppd (8) .SH SYNOPSIS .B pppd [ .I options ] plugin radius.so plugin radattr.so .SH DESCRIPTION .LP The radattr plugin for pppd causes all radius attributes returned by the RADIUS server at authentication time to be stored in the file .I /var/run/radattr.pppN where .I pppN is the name of the PPP interface. The RADIUS attributes are stored one per line in the format "Attribute-Name Attribute-Value". This format is convenient for use in /etc/ppp/ip-up and /etc/ppp/ip-down scripts. .LP Note that you .I must load the radius.so plugin before loading the radattr.so plugin; radattr.so depends on symbols defined in radius.so. .SH USAGE To use the plugin, simply supply the .B plugin radius.so plugin radattr.so options to pppd. .SH SEE ALSO .BR pppd (8) " pppd-radius" (8) .SH AUTHOR Dianne Skoll ppp-2.5.0/pppd/plugins/radius/Makefile.in0000644000175000017500000012664714407475314015247 00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = pppd/plugins/radius ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_atm.m4 \ $(top_srcdir)/m4/ax_check_openssl.m4 \ $(top_srcdir)/m4/ax_check_openssl_func.m4 \ $(top_srcdir)/m4/ax_check_pam.m4 \ $(top_srcdir)/m4/ax_check_pcap.m4 \ $(top_srcdir)/m4/ax_check_srp.m4 $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/pkg.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(noinst_HEADERS) \ $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/pppd/config.h \ $(top_builddir)/pppd/pppdconf.h \ $(top_builddir)/pppd/plugins/pppoe/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(pppd_plugindir)" "$(DESTDIR)$(man8dir)" LTLIBRARIES = $(noinst_LTLIBRARIES) $(pppd_plugin_LTLIBRARIES) libradiusclient_la_LIBADD = am_libradiusclient_la_OBJECTS = libradiusclient_la-avpair.lo \ libradiusclient_la-buildreq.lo libradiusclient_la-config.lo \ libradiusclient_la-dict.lo libradiusclient_la-ip_util.lo \ libradiusclient_la-clientid.lo \ libradiusclient_la-sendserver.lo libradiusclient_la-lock.lo \ libradiusclient_la-util.lo libradiusclient_la-md5.lo libradiusclient_la_OBJECTS = $(am_libradiusclient_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = radattr_la_LIBADD = am_radattr_la_OBJECTS = radattr_la-radattr.lo radattr_la_OBJECTS = $(am_radattr_la_OBJECTS) radattr_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(radattr_la_LDFLAGS) $(LDFLAGS) -o $@ radius_la_DEPENDENCIES = libradiusclient.la am_radius_la_OBJECTS = radius_la-radius.lo radius_la_OBJECTS = $(am_radius_la_OBJECTS) radius_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(radius_la_LDFLAGS) $(LDFLAGS) -o $@ radrealms_la_LIBADD = am_radrealms_la_OBJECTS = radrealms_la-radrealms.lo radrealms_la_OBJECTS = $(am_radrealms_la_OBJECTS) radrealms_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(radrealms_la_LDFLAGS) $(LDFLAGS) -o $@ AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/pppd -I$(top_builddir)/pppd/plugins/pppoe depcomp = $(SHELL) $(top_srcdir)/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/libradiusclient_la-avpair.Plo \ ./$(DEPDIR)/libradiusclient_la-buildreq.Plo \ ./$(DEPDIR)/libradiusclient_la-clientid.Plo \ ./$(DEPDIR)/libradiusclient_la-config.Plo \ ./$(DEPDIR)/libradiusclient_la-dict.Plo \ ./$(DEPDIR)/libradiusclient_la-ip_util.Plo \ ./$(DEPDIR)/libradiusclient_la-lock.Plo \ ./$(DEPDIR)/libradiusclient_la-md5.Plo \ ./$(DEPDIR)/libradiusclient_la-sendserver.Plo \ ./$(DEPDIR)/libradiusclient_la-util.Plo \ ./$(DEPDIR)/radattr_la-radattr.Plo \ ./$(DEPDIR)/radius_la-radius.Plo \ ./$(DEPDIR)/radrealms_la-radrealms.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libradiusclient_la_SOURCES) $(radattr_la_SOURCES) \ $(radius_la_SOURCES) $(radrealms_la_SOURCES) DIST_SOURCES = $(libradiusclient_la_SOURCES) $(radattr_la_SOURCES) \ $(radius_la_SOURCES) $(radrealms_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac man8dir = $(mandir)/man8 NROFF = nroff MANS = $(dist_man8_MANS) HEADERS = $(noinst_HEADERS) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(dist_man8_MANS) $(srcdir)/Makefile.in \ $(top_srcdir)/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ ATM_CFLAGS = @ATM_CFLAGS@ ATM_LDFLAGS = @ATM_LDFLAGS@ ATM_LIBS = @ATM_LIBS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CRYPT_LIBS = @CRYPT_LIBS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GREP = @GREP@ GTK_CFLAGS = @GTK_CFLAGS@ GTK_LIBS = @GTK_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_INCLUDES = @OPENSSL_INCLUDES@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAM_CFLAGS = @PAM_CFLAGS@ PAM_LDFLAGS = @PAM_LDFLAGS@ PAM_LIBS = @PAM_LIBS@ PATH_SEPARATOR = @PATH_SEPARATOR@ PCAP_CFLAGS = @PCAP_CFLAGS@ PCAP_LDFLAGS = @PCAP_LDFLAGS@ PCAP_LIBS = @PCAP_LIBS@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PPPD_LOGFILE_DIR = @PPPD_LOGFILE_DIR@ PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@ PPPD_RUNTIME_DIR = @PPPD_RUNTIME_DIR@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SRP_CFLAGS = @SRP_CFLAGS@ SRP_LDFLAGS = @SRP_LDFLAGS@ SRP_LIBS = @SRP_LIBS@ STRIP = @STRIP@ SYSTEMD_CFLAGS = @SYSTEMD_CFLAGS@ SYSTEMD_LIBS = @SYSTEMD_LIBS@ SYSTEM_CA_PATH = @SYSTEM_CA_PATH@ UTIL_LIBS = @UTIL_LIBS@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ pppd_plugin_LTLIBRARIES = radius.la radattr.la radrealms.la pppd_plugindir = $(PPPD_PLUGIN_DIR) noinst_LTLIBRARIES = libradiusclient.la dist_man8_MANS = pppd-radius.8 pppd-radattr.8 noinst_HEADERS = \ includes.h \ options.h \ pathnames.h \ radiusclient.h EXTRA_FILES = \ COPYRIGHT EXTRA_ETC = \ etc/dictionary \ etc/dictionary.ascend \ etc/dictionary.compat \ etc/dictionary.merit \ etc/dictionary.microsoft \ etc/issue \ etc/port-id-map \ etc/radiusclient.conf \ etc/radiusclient.conf.in \ etc/realms \ etc/servers RADIUS_CPPFLAGS = -I${top_srcdir} -DRC_LOG_FACILITY=LOG_DAEMON RADIUS_LDFLAGS = -module -avoid-version $(LDFLAGS) radius_la_CPPFLAGS = $(RADIUS_CPPFLAGS) radius_la_LDFLAGS = $(RADIUS_LDFLAGS) radius_la_SOURCES = radius.c radius_la_LIBADD = libradiusclient.la radattr_la_CPPFLAGS = $(RADIUS_CPPFLAGS) radattr_la_LDFLAGS = $(RADIUS_LDFLAGS) radattr_la_SOURCES = radattr.c radrealms_la_CPPFLAGS = $(RADIUS_CPPFLAGS) radrealms_la_LDFLAGS = $(RADIUS_LDFLAGS) radrealms_la_SOURCES = radrealms.c libradiusclient_la_SOURCES = \ avpair.c buildreq.c config.c dict.c ip_util.c \ clientid.c sendserver.c lock.c util.c md5.c libradiusclient_la_CPPFLAGS = $(RADIUS_CPPFLAGS) -DSYSCONFDIR=\"${sysconfdir}\" EXTRA_DIST = \ $(EXTRA_FILES) \ $(EXTRA_ETC) all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu pppd/plugins/radius/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu pppd/plugins/radius/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } install-pppd_pluginLTLIBRARIES: $(pppd_plugin_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(pppd_plugin_LTLIBRARIES)'; test -n "$(pppd_plugindir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(pppd_plugindir)'"; \ $(MKDIR_P) "$(DESTDIR)$(pppd_plugindir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(pppd_plugindir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(pppd_plugindir)"; \ } uninstall-pppd_pluginLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(pppd_plugin_LTLIBRARIES)'; test -n "$(pppd_plugindir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(pppd_plugindir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(pppd_plugindir)/$$f"; \ done clean-pppd_pluginLTLIBRARIES: -test -z "$(pppd_plugin_LTLIBRARIES)" || rm -f $(pppd_plugin_LTLIBRARIES) @list='$(pppd_plugin_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libradiusclient.la: $(libradiusclient_la_OBJECTS) $(libradiusclient_la_DEPENDENCIES) $(EXTRA_libradiusclient_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libradiusclient_la_OBJECTS) $(libradiusclient_la_LIBADD) $(LIBS) radattr.la: $(radattr_la_OBJECTS) $(radattr_la_DEPENDENCIES) $(EXTRA_radattr_la_DEPENDENCIES) $(AM_V_CCLD)$(radattr_la_LINK) -rpath $(pppd_plugindir) $(radattr_la_OBJECTS) $(radattr_la_LIBADD) $(LIBS) radius.la: $(radius_la_OBJECTS) $(radius_la_DEPENDENCIES) $(EXTRA_radius_la_DEPENDENCIES) $(AM_V_CCLD)$(radius_la_LINK) -rpath $(pppd_plugindir) $(radius_la_OBJECTS) $(radius_la_LIBADD) $(LIBS) radrealms.la: $(radrealms_la_OBJECTS) $(radrealms_la_DEPENDENCIES) $(EXTRA_radrealms_la_DEPENDENCIES) $(AM_V_CCLD)$(radrealms_la_LINK) -rpath $(pppd_plugindir) $(radrealms_la_OBJECTS) $(radrealms_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libradiusclient_la-avpair.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libradiusclient_la-buildreq.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libradiusclient_la-clientid.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libradiusclient_la-config.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libradiusclient_la-dict.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libradiusclient_la-ip_util.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libradiusclient_la-lock.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libradiusclient_la-md5.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libradiusclient_la-sendserver.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libradiusclient_la-util.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/radattr_la-radattr.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/radius_la-radius.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/radrealms_la-radrealms.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< libradiusclient_la-avpair.lo: avpair.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libradiusclient_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libradiusclient_la-avpair.lo -MD -MP -MF $(DEPDIR)/libradiusclient_la-avpair.Tpo -c -o libradiusclient_la-avpair.lo `test -f 'avpair.c' || echo '$(srcdir)/'`avpair.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libradiusclient_la-avpair.Tpo $(DEPDIR)/libradiusclient_la-avpair.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='avpair.c' object='libradiusclient_la-avpair.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libradiusclient_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libradiusclient_la-avpair.lo `test -f 'avpair.c' || echo '$(srcdir)/'`avpair.c libradiusclient_la-buildreq.lo: buildreq.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libradiusclient_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libradiusclient_la-buildreq.lo -MD -MP -MF $(DEPDIR)/libradiusclient_la-buildreq.Tpo -c -o libradiusclient_la-buildreq.lo `test -f 'buildreq.c' || echo '$(srcdir)/'`buildreq.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libradiusclient_la-buildreq.Tpo $(DEPDIR)/libradiusclient_la-buildreq.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='buildreq.c' object='libradiusclient_la-buildreq.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libradiusclient_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libradiusclient_la-buildreq.lo `test -f 'buildreq.c' || echo '$(srcdir)/'`buildreq.c libradiusclient_la-config.lo: config.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libradiusclient_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libradiusclient_la-config.lo -MD -MP -MF $(DEPDIR)/libradiusclient_la-config.Tpo -c -o libradiusclient_la-config.lo `test -f 'config.c' || echo '$(srcdir)/'`config.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libradiusclient_la-config.Tpo $(DEPDIR)/libradiusclient_la-config.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='config.c' object='libradiusclient_la-config.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libradiusclient_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libradiusclient_la-config.lo `test -f 'config.c' || echo '$(srcdir)/'`config.c libradiusclient_la-dict.lo: dict.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libradiusclient_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libradiusclient_la-dict.lo -MD -MP -MF $(DEPDIR)/libradiusclient_la-dict.Tpo -c -o libradiusclient_la-dict.lo `test -f 'dict.c' || echo '$(srcdir)/'`dict.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libradiusclient_la-dict.Tpo $(DEPDIR)/libradiusclient_la-dict.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dict.c' object='libradiusclient_la-dict.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libradiusclient_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libradiusclient_la-dict.lo `test -f 'dict.c' || echo '$(srcdir)/'`dict.c libradiusclient_la-ip_util.lo: ip_util.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libradiusclient_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libradiusclient_la-ip_util.lo -MD -MP -MF $(DEPDIR)/libradiusclient_la-ip_util.Tpo -c -o libradiusclient_la-ip_util.lo `test -f 'ip_util.c' || echo '$(srcdir)/'`ip_util.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libradiusclient_la-ip_util.Tpo $(DEPDIR)/libradiusclient_la-ip_util.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ip_util.c' object='libradiusclient_la-ip_util.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libradiusclient_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libradiusclient_la-ip_util.lo `test -f 'ip_util.c' || echo '$(srcdir)/'`ip_util.c libradiusclient_la-clientid.lo: clientid.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libradiusclient_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libradiusclient_la-clientid.lo -MD -MP -MF $(DEPDIR)/libradiusclient_la-clientid.Tpo -c -o libradiusclient_la-clientid.lo `test -f 'clientid.c' || echo '$(srcdir)/'`clientid.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libradiusclient_la-clientid.Tpo $(DEPDIR)/libradiusclient_la-clientid.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='clientid.c' object='libradiusclient_la-clientid.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libradiusclient_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libradiusclient_la-clientid.lo `test -f 'clientid.c' || echo '$(srcdir)/'`clientid.c libradiusclient_la-sendserver.lo: sendserver.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libradiusclient_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libradiusclient_la-sendserver.lo -MD -MP -MF $(DEPDIR)/libradiusclient_la-sendserver.Tpo -c -o libradiusclient_la-sendserver.lo `test -f 'sendserver.c' || echo '$(srcdir)/'`sendserver.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libradiusclient_la-sendserver.Tpo $(DEPDIR)/libradiusclient_la-sendserver.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='sendserver.c' object='libradiusclient_la-sendserver.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libradiusclient_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libradiusclient_la-sendserver.lo `test -f 'sendserver.c' || echo '$(srcdir)/'`sendserver.c libradiusclient_la-lock.lo: lock.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libradiusclient_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libradiusclient_la-lock.lo -MD -MP -MF $(DEPDIR)/libradiusclient_la-lock.Tpo -c -o libradiusclient_la-lock.lo `test -f 'lock.c' || echo '$(srcdir)/'`lock.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libradiusclient_la-lock.Tpo $(DEPDIR)/libradiusclient_la-lock.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='lock.c' object='libradiusclient_la-lock.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libradiusclient_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libradiusclient_la-lock.lo `test -f 'lock.c' || echo '$(srcdir)/'`lock.c libradiusclient_la-util.lo: util.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libradiusclient_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libradiusclient_la-util.lo -MD -MP -MF $(DEPDIR)/libradiusclient_la-util.Tpo -c -o libradiusclient_la-util.lo `test -f 'util.c' || echo '$(srcdir)/'`util.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libradiusclient_la-util.Tpo $(DEPDIR)/libradiusclient_la-util.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='util.c' object='libradiusclient_la-util.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libradiusclient_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libradiusclient_la-util.lo `test -f 'util.c' || echo '$(srcdir)/'`util.c libradiusclient_la-md5.lo: md5.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libradiusclient_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libradiusclient_la-md5.lo -MD -MP -MF $(DEPDIR)/libradiusclient_la-md5.Tpo -c -o libradiusclient_la-md5.lo `test -f 'md5.c' || echo '$(srcdir)/'`md5.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libradiusclient_la-md5.Tpo $(DEPDIR)/libradiusclient_la-md5.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='md5.c' object='libradiusclient_la-md5.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libradiusclient_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libradiusclient_la-md5.lo `test -f 'md5.c' || echo '$(srcdir)/'`md5.c radattr_la-radattr.lo: radattr.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(radattr_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT radattr_la-radattr.lo -MD -MP -MF $(DEPDIR)/radattr_la-radattr.Tpo -c -o radattr_la-radattr.lo `test -f 'radattr.c' || echo '$(srcdir)/'`radattr.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/radattr_la-radattr.Tpo $(DEPDIR)/radattr_la-radattr.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='radattr.c' object='radattr_la-radattr.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(radattr_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o radattr_la-radattr.lo `test -f 'radattr.c' || echo '$(srcdir)/'`radattr.c radius_la-radius.lo: radius.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(radius_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT radius_la-radius.lo -MD -MP -MF $(DEPDIR)/radius_la-radius.Tpo -c -o radius_la-radius.lo `test -f 'radius.c' || echo '$(srcdir)/'`radius.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/radius_la-radius.Tpo $(DEPDIR)/radius_la-radius.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='radius.c' object='radius_la-radius.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(radius_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o radius_la-radius.lo `test -f 'radius.c' || echo '$(srcdir)/'`radius.c radrealms_la-radrealms.lo: radrealms.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(radrealms_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT radrealms_la-radrealms.lo -MD -MP -MF $(DEPDIR)/radrealms_la-radrealms.Tpo -c -o radrealms_la-radrealms.lo `test -f 'radrealms.c' || echo '$(srcdir)/'`radrealms.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/radrealms_la-radrealms.Tpo $(DEPDIR)/radrealms_la-radrealms.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='radrealms.c' object='radrealms_la-radrealms.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(radrealms_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o radrealms_la-radrealms.lo `test -f 'radrealms.c' || echo '$(srcdir)/'`radrealms.c mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs install-man8: $(dist_man8_MANS) @$(NORMAL_INSTALL) @list1='$(dist_man8_MANS)'; \ list2=''; \ test -n "$(man8dir)" \ && test -n "`echo $$list1$$list2`" \ || exit 0; \ echo " $(MKDIR_P) '$(DESTDIR)$(man8dir)'"; \ $(MKDIR_P) "$(DESTDIR)$(man8dir)" || exit 1; \ { for i in $$list1; do echo "$$i"; done; \ if test -n "$$list2"; then \ for i in $$list2; do echo "$$i"; done \ | sed -n '/\.8[a-z]*$$/p'; \ fi; \ } | while read p; do \ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; echo "$$p"; \ done | \ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ sed 'N;N;s,\n, ,g' | { \ list=; while read file base inst; do \ if test "$$base" = "$$inst"; then list="$$list $$file"; else \ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man8dir)/$$inst'"; \ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man8dir)/$$inst" || exit $$?; \ fi; \ done; \ for i in $$list; do echo "$$i"; done | $(am__base_list) | \ while read files; do \ test -z "$$files" || { \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man8dir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(man8dir)" || exit $$?; }; \ done; } uninstall-man8: @$(NORMAL_UNINSTALL) @list='$(dist_man8_MANS)'; test -n "$(man8dir)" || exit 0; \ files=`{ for i in $$list; do echo "$$i"; done; \ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ dir='$(DESTDIR)$(man8dir)'; $(am__uninstall_files_from_dir) ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) $(MANS) $(HEADERS) installdirs: for dir in "$(DESTDIR)$(pppd_plugindir)" "$(DESTDIR)$(man8dir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ clean-pppd_pluginLTLIBRARIES mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/libradiusclient_la-avpair.Plo -rm -f ./$(DEPDIR)/libradiusclient_la-buildreq.Plo -rm -f ./$(DEPDIR)/libradiusclient_la-clientid.Plo -rm -f ./$(DEPDIR)/libradiusclient_la-config.Plo -rm -f ./$(DEPDIR)/libradiusclient_la-dict.Plo -rm -f ./$(DEPDIR)/libradiusclient_la-ip_util.Plo -rm -f ./$(DEPDIR)/libradiusclient_la-lock.Plo -rm -f ./$(DEPDIR)/libradiusclient_la-md5.Plo -rm -f ./$(DEPDIR)/libradiusclient_la-sendserver.Plo -rm -f ./$(DEPDIR)/libradiusclient_la-util.Plo -rm -f ./$(DEPDIR)/radattr_la-radattr.Plo -rm -f ./$(DEPDIR)/radius_la-radius.Plo -rm -f ./$(DEPDIR)/radrealms_la-radrealms.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-man install-pppd_pluginLTLIBRARIES install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-man8 install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/libradiusclient_la-avpair.Plo -rm -f ./$(DEPDIR)/libradiusclient_la-buildreq.Plo -rm -f ./$(DEPDIR)/libradiusclient_la-clientid.Plo -rm -f ./$(DEPDIR)/libradiusclient_la-config.Plo -rm -f ./$(DEPDIR)/libradiusclient_la-dict.Plo -rm -f ./$(DEPDIR)/libradiusclient_la-ip_util.Plo -rm -f ./$(DEPDIR)/libradiusclient_la-lock.Plo -rm -f ./$(DEPDIR)/libradiusclient_la-md5.Plo -rm -f ./$(DEPDIR)/libradiusclient_la-sendserver.Plo -rm -f ./$(DEPDIR)/libradiusclient_la-util.Plo -rm -f ./$(DEPDIR)/radattr_la-radattr.Plo -rm -f ./$(DEPDIR)/radius_la-radius.Plo -rm -f ./$(DEPDIR)/radrealms_la-radrealms.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-man uninstall-pppd_pluginLTLIBRARIES uninstall-man: uninstall-man8 .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ clean-pppd_pluginLTLIBRARIES cscopelist-am ctags ctags-am \ distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-man8 install-pdf \ install-pdf-am install-pppd_pluginLTLIBRARIES install-ps \ install-ps-am install-strip installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am uninstall-man uninstall-man8 \ uninstall-pppd_pluginLTLIBRARIES .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: ppp-2.5.0/pppd/plugins/radius/avpair.c0000644000175000017500000004126214407475306014616 00000000000000/* * $Id: avpair.c,v 1.1 2004/11/14 07:26:26 paulus Exp $ * * Copyright (C) 1995 Lars Fenneberg * * Copyright 1992 Livingston Enterprises, Inc. * * Copyright 1992,1993, 1994,1995 The Regents of the University of Michigan * and Merit Network, Inc. All Rights Reserved * * See the file COPYRIGHT for the respective terms and conditions. * If the file is missing contact me at lf@elemental.net * and I'll send you a copy. * */ #include #include static void rc_extract_vendor_specific_attributes(int attrlen, unsigned char *ptr, VALUE_PAIR **vp); /* * Function: rc_avpair_add * * Purpose: add an attribute-value pair to the given list. * * Returns: pointer to added a/v pair upon success, NULL pointer upon failure. * * Remarks: Always appends the new pair to the end of the list. * */ VALUE_PAIR *rc_avpair_add (VALUE_PAIR **list, int attrid, const void *pval, int len, int vendorcode) { VALUE_PAIR *vp; vp = rc_avpair_new (attrid, pval, len, vendorcode); if (vp != (VALUE_PAIR *) NULL) { rc_avpair_insert (list, (VALUE_PAIR *) NULL, vp); } return vp; } /* * Function: rc_avpair_assign * * Purpose: assign the given value to an attribute-value pair. * * Returns: 0 on success, * -1 on failure. * */ int rc_avpair_assign (VALUE_PAIR *vp, const void *pval, int len) { int result = -1; switch (vp->type) { case PW_TYPE_STRING: if (((len == 0) && (strlen ((const char *) pval)) > AUTH_STRING_LEN) || (len > AUTH_STRING_LEN)) { error("rc_avpair_assign: bad attribute length"); return result; } if (len > 0) { memcpy(vp->strvalue, (const char *)pval, len); vp->strvalue[len] = '\0'; vp->lvalue = len; } else { strncpy ((char*) vp->strvalue, (const char *) pval, AUTH_STRING_LEN); vp->lvalue = strlen((const char *) pval); } result = 0; break; case PW_TYPE_DATE: case PW_TYPE_INTEGER: case PW_TYPE_IPADDR: vp->lvalue = * (UINT4 *) pval; result = 0; break; default: error("rc_avpair_assign: unknown attribute %d", vp->type); } return result; } /* * Function: rc_avpair_new * * Purpose: make a new attribute-value pair with given parameters. * * Returns: pointer to generated a/v pair when successful, NULL when failure. * */ VALUE_PAIR *rc_avpair_new (int attrid, const void *pval, int len, int vendorcode) { VALUE_PAIR *vp = (VALUE_PAIR *) NULL; DICT_ATTR *pda; if ((pda = rc_dict_getattr (attrid, vendorcode)) == (DICT_ATTR *) NULL) { error("rc_avpair_new: unknown attribute %d", attrid); } else { if ((vp = (VALUE_PAIR *) malloc (sizeof (VALUE_PAIR))) != (VALUE_PAIR *) NULL) { strlcpy (vp->name, pda->name, NAME_LENGTH); vp->attribute = attrid; vp->vendorcode = vendorcode; vp->next = (VALUE_PAIR *) NULL; vp->type = pda->type; if (rc_avpair_assign (vp, pval, len) == 0) { return vp; } free (vp); vp = (VALUE_PAIR *) NULL; } else novm("rc_avpair_new"); } return vp; } /* * * Function: rc_avpair_gen * * Purpose: takes attribute/value pairs from buffer and builds a * value_pair list using allocated memory. * * Returns: value_pair list or NULL on failure */ VALUE_PAIR *rc_avpair_gen (AUTH_HDR *auth) { int length; int x_len; int attribute; int attrlen; UINT4 lvalue; unsigned char *x_ptr; unsigned char *ptr; DICT_ATTR *attr; VALUE_PAIR *vp; VALUE_PAIR *pair; char hex[3]; /* For hex string conversion. */ char buffer[512]; /* * Extract attribute-value pairs */ ptr = auth->data; length = ntohs ((unsigned short) auth->length) - AUTH_HDR_LEN; vp = (VALUE_PAIR *) NULL; while (length > 0) { attribute = *ptr++; attrlen = *ptr++; if (attrlen < 2 || attrlen > length) { error("rc_avpair_gen: received attribute with invalid length"); break; } attrlen -= 2; /* Handle vendor-specific specially */ if (attribute == PW_VENDOR_SPECIFIC) { rc_extract_vendor_specific_attributes(attrlen, ptr, &vp); ptr += attrlen; length -= (attrlen + 2); continue; } if ((attr = rc_dict_getattr (attribute, VENDOR_NONE)) == (DICT_ATTR *) NULL) { *buffer= '\0'; /* Initial length. */ for (x_ptr = ptr, x_len = attrlen ; x_len > 0 ; x_len--, x_ptr++) { sprintf (hex, "%2.2X", *x_ptr); strcat (buffer, hex); } warn("rc_avpair_gen: received unknown attribute %d of length %d: 0x%s", attribute, attrlen, buffer); } else { if ((pair = (VALUE_PAIR *) malloc (sizeof (VALUE_PAIR))) == (VALUE_PAIR *) NULL) { novm("rc_avpair_gen"); rc_avpair_free(vp); return NULL; } strcpy (pair->name, attr->name); pair->attribute = attr->value; pair->vendorcode = VENDOR_NONE; pair->type = attr->type; pair->next = (VALUE_PAIR *) NULL; switch (attr->type) { case PW_TYPE_STRING: case PW_TYPE_IFID: case PW_TYPE_IPV6ADDR: case PW_TYPE_IPV6PREFIX: memcpy (pair->strvalue, (char *) ptr, (size_t) attrlen); pair->strvalue[attrlen] = '\0'; pair->lvalue = attrlen; rc_avpair_insert (&vp, (VALUE_PAIR *) NULL, pair); break; case PW_TYPE_INTEGER: case PW_TYPE_IPADDR: memcpy ((char *) &lvalue, (char *) ptr, sizeof (UINT4)); pair->lvalue = ntohl (lvalue); rc_avpair_insert (&vp, (VALUE_PAIR *) NULL, pair); break; default: warn("rc_avpair_gen: %s has unknown type", attr->name); free (pair); break; } } ptr += attrlen; length -= attrlen + 2; } return (vp); } /* * Function: rc_extract_vendor_specific_attributes * * Purpose: Extracts vendor-specific attributes, assuming they are in * the "SHOULD" format recommended by RCF 2138. * * Returns: found value_pair * */ static void rc_extract_vendor_specific_attributes(int attrlen, unsigned char *ptr, VALUE_PAIR **vp) { int vendor_id; int vtype; int vlen; UINT4 lvalue; DICT_ATTR *attr; VALUE_PAIR *pair; /* ptr is sitting at vendor-ID */ if (attrlen < 8) { /* Nothing to see here... */ return; } /* High-order octet of Vendor-Id must be zero (RFC2138) */ if (*ptr) { return; } /* Extract vendor_id */ vendor_id = (int) ( ((unsigned int) ptr[1]) * 256 * 256 + ((unsigned int) ptr[2]) * 256 + ((unsigned int) ptr[3])); /* Bump ptr up to contents */ ptr += 4; /* Set attrlen to length of data */ attrlen -= 4; for (; attrlen; attrlen -= vlen+2, ptr += vlen) { vtype = *ptr++; vlen = *ptr++; vlen -= 2; if (vlen < 0 || vlen > attrlen - 2) { /* Do not log an error. We are supposed to be able to cope with arbitrary vendor-specific gunk */ return; } /* Looks plausible... */ if ((attr = rc_dict_getattr(vtype, vendor_id)) == NULL) { continue; } /* TODO: Check that length matches data size!!!!! */ pair = (VALUE_PAIR *) malloc(sizeof(VALUE_PAIR)); if (!pair) { novm("rc_avpair_gen"); return; } strcpy(pair->name, attr->name); pair->attribute = attr->value; pair->vendorcode = vendor_id; pair->type = attr->type; pair->next = NULL; switch (attr->type) { case PW_TYPE_STRING: memcpy (pair->strvalue, (char *) ptr, (size_t) vlen); pair->strvalue[vlen] = '\0'; pair->lvalue = vlen; rc_avpair_insert (vp, (VALUE_PAIR *) NULL, pair); break; case PW_TYPE_INTEGER: case PW_TYPE_IPADDR: memcpy ((char *) &lvalue, (char *) ptr, sizeof (UINT4)); pair->lvalue = ntohl (lvalue); rc_avpair_insert (vp, (VALUE_PAIR *) NULL, pair); break; default: warn("rc_avpair_gen: %s has unknown type", attr->name); free (pair); break; } } } /* * Function: rc_avpair_get * * Purpose: Find the first attribute value-pair (which matches the given * attribute) from the specified value-pair list. * * Returns: found value_pair * */ VALUE_PAIR *rc_avpair_get (VALUE_PAIR *vp, UINT4 attr) { for (; vp != (VALUE_PAIR *) NULL && vp->attribute != attr; vp = vp->next) { continue; } return (vp); } /* * Function: rc_avpair_copy * * Purpose: Return a copy of the existing list "p" ala strdup(). * */ VALUE_PAIR *rc_avpair_copy(VALUE_PAIR *p) { VALUE_PAIR *vp, *fp = NULL, *lp = NULL; while (p) { vp = malloc(sizeof(VALUE_PAIR)); if (!vp) { novm("rc_avpair_copy"); return NULL; /* leaks a little but so what */ } *vp = *p; if (!fp) fp = vp; if (lp) lp->next = vp; lp = vp; p = p->next; } return fp; } /* * Function: rc_avpair_insert * * Purpose: Given the address of an existing list "a" and a pointer * to an entry "p" in that list, add the list "b" to * the "a" list after the "p" entry. If "p" is NULL, add * the list "b" to the end of "a". * */ void rc_avpair_insert (VALUE_PAIR **a, VALUE_PAIR *p, VALUE_PAIR *b) { VALUE_PAIR *this_node = NULL; VALUE_PAIR *vp; if (*a == (VALUE_PAIR *) NULL) { *a = b; return; } if (!b) return; vp = *a; if ( p == (VALUE_PAIR *) NULL) /* run to end of "a" list */ { while (vp != (VALUE_PAIR *) NULL) { this_node = vp; vp = vp->next; } } else /* look for the "p" entry in the "a" list (or run to end) */ { this_node = *a; while (this_node->next != (VALUE_PAIR *) NULL) { if (this_node == p) { break; } this_node = this_node->next; } } /* add "b" at this_node */ vp = this_node->next; this_node->next = b; /* run to end of "b" and connect the rest of "a" */ while (b->next) b = b->next; b->next = vp; return; } /* * Function: rc_avpair_free * * Purpose: frees all value_pairs in the list * */ void rc_avpair_free (VALUE_PAIR *pair) { VALUE_PAIR *next; while (pair != (VALUE_PAIR *) NULL) { next = pair->next; free (pair); pair = next; } } /* * Function: rc_fieldcpy * * Purpose: Copy a data field from the buffer. Advance the buffer * past the data field. * */ static void rc_fieldcpy (char *string, char **uptr) { char *ptr; ptr = *uptr; if (*ptr == '"') { ptr++; while (*ptr != '"' && *ptr != '\0' && *ptr != '\n') { *string++ = *ptr++; } *string = '\0'; if (*ptr == '"') { ptr++; } *uptr = ptr; return; } while (*ptr != ' ' && *ptr != '\t' && *ptr != '\0' && *ptr != '\n' && *ptr != '=' && *ptr != ',') { *string++ = *ptr++; } *string = '\0'; *uptr = ptr; return; } /* * Function: rc_avpair_parse * * Purpose: parses the buffer to extract the attribute-value pairs. * * Returns: 0 = successful parse of attribute-value pair, * -1 = syntax (or other) error detected. * */ #define PARSE_MODE_NAME 0 #define PARSE_MODE_EQUAL 1 #define PARSE_MODE_VALUE 2 #define PARSE_MODE_INVALID 3 int rc_avpair_parse (char *buffer, VALUE_PAIR **first_pair) { int mode; char attrstr[AUTH_ID_LEN]; char valstr[AUTH_ID_LEN]; DICT_ATTR *attr = NULL; DICT_VALUE *dval; VALUE_PAIR *pair; VALUE_PAIR *link; struct tm *tm; time_t timeval; mode = PARSE_MODE_NAME; while (*buffer != '\n' && *buffer != '\0') { if (*buffer == ' ' || *buffer == '\t') { buffer++; continue; } switch (mode) { case PARSE_MODE_NAME: /* Attribute Name */ rc_fieldcpy (attrstr, &buffer); if ((attr = rc_dict_findattr (attrstr)) == (DICT_ATTR *) NULL) { error("rc_avpair_parse: unknown attribute"); if (*first_pair) { rc_avpair_free(*first_pair); *first_pair = (VALUE_PAIR *) NULL; } return (-1); } mode = PARSE_MODE_EQUAL; break; case PARSE_MODE_EQUAL: /* Equal sign */ if (*buffer == '=') { mode = PARSE_MODE_VALUE; buffer++; } else { error("rc_avpair_parse: missing or misplaced equal sign"); if (*first_pair) { rc_avpair_free(*first_pair); *first_pair = (VALUE_PAIR *) NULL; } return (-1); } break; case PARSE_MODE_VALUE: /* Value */ rc_fieldcpy (valstr, &buffer); if ((pair = (VALUE_PAIR *) malloc (sizeof (VALUE_PAIR))) == (VALUE_PAIR *) NULL) { novm("rc_avpair_parse"); if (*first_pair) { rc_avpair_free(*first_pair); *first_pair = (VALUE_PAIR *) NULL; } return (-1); } strcpy (pair->name, attr->name); pair->attribute = attr->value; pair->type = attr->type; pair->vendorcode = attr->vendorcode; switch (pair->type) { case PW_TYPE_STRING: strcpy ((char*) pair->strvalue, valstr); pair->lvalue = strlen(valstr); break; case PW_TYPE_INTEGER: if (isdigit (*valstr)) { pair->lvalue = atoi (valstr); } else { if ((dval = rc_dict_findval (valstr)) == (DICT_VALUE *) NULL) { error("rc_avpair_parse: unknown attribute value: %s", valstr); if (*first_pair) { rc_avpair_free(*first_pair); *first_pair = (VALUE_PAIR *) NULL; } free (pair); return (-1); } else { pair->lvalue = dval->value; } } break; case PW_TYPE_IPADDR: pair->lvalue = rc_get_ipaddr(valstr); break; case PW_TYPE_DATE: timeval = time (0); tm = localtime (&timeval); tm->tm_hour = 0; tm->tm_min = 0; tm->tm_sec = 0; rc_str2tm (valstr, tm); #ifdef TIMELOCAL pair->lvalue = (UINT4) timelocal (tm); #else /* TIMELOCAL */ pair->lvalue = (UINT4) mktime (tm); #endif /* TIMELOCAL */ break; default: error("rc_avpair_parse: unknown attribute type %d", pair->type); if (*first_pair) { rc_avpair_free(*first_pair); *first_pair = (VALUE_PAIR *) NULL; } free (pair); return (-1); } pair->next = (VALUE_PAIR *) NULL; if (*first_pair == (VALUE_PAIR *) NULL) { *first_pair = pair; } else { link = *first_pair; while (link->next != (VALUE_PAIR *) NULL) { link = link->next; } link->next = pair; } mode = PARSE_MODE_NAME; break; default: mode = PARSE_MODE_NAME; break; } } return (0); } /* * Function: rc_avpair_tostr * * Purpose: Translate an av_pair into two strings * * Returns: 0 on success, -1 on failure * */ int rc_avpair_tostr (VALUE_PAIR *pair, char *name, int ln, char *value, int lv) { DICT_VALUE *dval; char buffer[INET6_ADDRSTRLEN + 4]; // for a prefix: addr + '/' + prefixlen struct in_addr inad; unsigned char *ptr; char *str; *name = *value = '\0'; if (!pair || pair->name[0] == '\0') { error("rc_avpair_tostr: pair is NULL or empty"); return (-1); } strncpy(name, pair->name, (size_t) ln); switch (pair->type) { case PW_TYPE_STRING: lv--; ptr = (unsigned char *) pair->strvalue; while (*ptr != '\0') { if (!(isprint (*ptr))) { sprintf (buffer, "\\%03o", *ptr); strncat(value, buffer, (size_t) lv); lv -= 4; if (lv < 0) break; } else { strncat(value, (char*) ptr, 1); lv--; if (lv < 0) break; } ptr++; } break; case PW_TYPE_INTEGER: dval = rc_dict_getval (pair->lvalue, pair->name); if (dval != (DICT_VALUE *) NULL) { strncpy(value, dval->name, (size_t) lv-1); } else { sprintf (buffer, "%d", pair->lvalue); strncpy(value, buffer, (size_t) lv); } break; case PW_TYPE_IPADDR: inad.s_addr = htonl(pair->lvalue); strncpy (value, inet_ntoa (inad), (size_t) lv-1); break; case PW_TYPE_DATE: strftime (buffer, sizeof (buffer), "%m/%d/%y %H:%M:%S", gmtime ((time_t *) & pair->lvalue)); strncpy(value, buffer, lv-1); break; case PW_TYPE_IFID: ptr = pair->strvalue; snprintf(buffer, sizeof (buffer), "%x:%x:%x:%x", (ptr[0] << 8) + ptr[1], (ptr[2] << 8) + ptr[3], (ptr[4] << 8) + ptr[5], (ptr[6] << 8) + ptr[7]); strncpy(value, buffer, lv-1); break; case PW_TYPE_IPV6ADDR: inet_ntop(AF_INET6, pair->strvalue, buffer, sizeof (buffer)); strncpy(value, buffer, lv-1); break; case PW_TYPE_IPV6PREFIX: inet_ntop(AF_INET6, pair->strvalue + 2, buffer, sizeof (buffer)); str = buffer + strlen(buffer); snprintf(str, sizeof (buffer) - (str - buffer), "/%d", *(pair->strvalue + 1)); strncpy(value, buffer, lv-1); break; default: error("rc_avpair_tostr: unknown attribute type %d", pair->type); return (-1); break; } return 0; } /* * Function: rc_avpair_readin * * Purpose: get a sequence of attribute value pairs from the file input * and make them into a list of value_pairs * */ VALUE_PAIR *rc_avpair_readin(FILE *input) { VALUE_PAIR *vp = NULL; char buffer[1024], *q; while (fgets(buffer, sizeof(buffer), input) != NULL) { q = buffer; while(*q && isspace(*q)) q++; if ((*q == '\n') || (*q == '#') || (*q == '\0')) continue; if (rc_avpair_parse(q, &vp) < 0) { error("rc_avpair_readin: malformed attribute: %s", buffer); rc_avpair_free(vp); return NULL; } } return vp; } ppp-2.5.0/pppd/plugins/radius/buildreq.c0000644000175000017500000002372514353435407015145 00000000000000/* * $Id: buildreq.c,v 1.1 2004/11/14 07:26:26 paulus Exp $ * * Copyright (C) 1995,1997 Lars Fenneberg * * See the file COPYRIGHT for the respective terms and conditions. * If the file is missing contact me at lf@elemental.net * and I'll send you a copy. * */ #include #include unsigned char rc_get_seqnbr(void); /* * Function: rc_get_nas_id * * Purpose: fills in NAS-Identifier or NAS-IP-Address in request * */ int rc_get_nas_id(VALUE_PAIR **sendpairs) { UINT4 client_id; char *nasid; nasid = rc_conf_str("nas_identifier"); if (strlen(nasid)) { /* * Fill in NAS-Identifier */ if (rc_avpair_add(sendpairs, PW_NAS_IDENTIFIER, nasid, 0, VENDOR_NONE) == NULL) return (ERROR_RC); return (OK_RC); } else { /* * Fill in NAS-IP-Address */ if ((client_id = rc_own_ipaddress()) == 0) return (ERROR_RC); if (rc_avpair_add(sendpairs, PW_NAS_IP_ADDRESS, &client_id, 0, VENDOR_NONE) == NULL) return (ERROR_RC); } return (OK_RC); } /* * Function: rc_buildreq * * Purpose: builds a skeleton RADIUS request using information from the * config file. * */ void rc_buildreq(SEND_DATA *data, int code, char *server, unsigned short port, int timeout, int retries) { data->server = server; data->svc_port = port; data->seq_nbr = rc_get_seqnbr(); data->timeout = timeout; data->retries = retries; data->code = code; } /* * Function: rc_guess_seqnbr * * Purpose: return a random sequence number * */ static unsigned char rc_guess_seqnbr(void) { return (unsigned char)(magic() & UCHAR_MAX); } /* * Function: rc_get_seqnbr * * Purpose: generate a sequence number * */ unsigned char rc_get_seqnbr(void) { FILE *sf; int tries = 1; int seq_nbr, pos, ret; char *seqfile = rc_conf_str("seqfile"); if ((sf = fopen(seqfile, "a+")) == NULL) { error("rc_get_seqnbr: couldn't open sequence file %s: %s", seqfile, strerror(errno)); /* well, so guess a sequence number */ return rc_guess_seqnbr(); } while (do_lock_exclusive(fileno(sf))!= 0) { if (errno != EWOULDBLOCK) { error("rc_get_seqnbr: flock failure: %s: %s", seqfile, strerror(errno)); fclose(sf); return rc_guess_seqnbr(); } tries++; if (tries <= 10) rc_mdelay(500); else break; } if (tries > 10) { error("rc_get_seqnbr: couldn't get lock after %d tries: %s", tries-1, seqfile); fclose(sf); return rc_guess_seqnbr(); } pos = ftell(sf); rewind(sf); if (fscanf(sf, "%d", &seq_nbr) != 1) { if (pos != ftell(sf)) { /* file was not empty */ error("rc_get_seqnbr: fscanf failure: %s", seqfile); } seq_nbr = rc_guess_seqnbr(); } rewind(sf); ret = ftruncate(fileno(sf),0); if (ret != 0) { error("rc_get_seqnbr: couldn't truncate sequence file, %m"); } fprintf(sf,"%d\n", (seq_nbr+1) & UCHAR_MAX); fflush(sf); /* fflush because a process may read it between the do_unlock and fclose */ if (do_unlock(fileno(sf)) != 0) error("rc_get_seqnbr: couldn't release lock on %s: %s", seqfile, strerror(errno)); fclose(sf); return (unsigned char)seq_nbr; } /* * Function: rc_auth * * Purpose: Builds an authentication request for port id client_port * with the value_pairs send and submits it to a server * * Returns: received value_pairs in received, messages from the server in msg * and 0 on success, negative on failure as return value * */ int rc_auth(UINT4 client_port, VALUE_PAIR *send, VALUE_PAIR **received, char *msg, REQUEST_INFO *info) { SERVER *authserver = rc_conf_srv("authserver"); if (!authserver) { return (ERROR_RC); } return rc_auth_using_server(authserver, client_port, send, received, msg, info); } /* * Function: rc_auth_using_server * * Purpose: Builds an authentication request for port id client_port * with the value_pairs send and submits it to a server. You * explicitly supply a server list. * * Returns: received value_pairs in received, messages from the server in msg * and 0 on success, negative on failure as return value * */ int rc_auth_using_server(SERVER *authserver, UINT4 client_port, VALUE_PAIR *send, VALUE_PAIR **received, char *msg, REQUEST_INFO *info) { SEND_DATA data; int result; int i; int timeout = rc_conf_int("radius_timeout"); int retries = rc_conf_int("radius_retries"); data.send_pairs = send; data.receive_pairs = NULL; /* * Fill in NAS-IP-Address or NAS-Identifier */ if (rc_get_nas_id(&(data.send_pairs)) == ERROR_RC) return (ERROR_RC); /* * Fill in NAS-Port */ if (rc_avpair_add(&(data.send_pairs), PW_NAS_PORT, &client_port, 0, VENDOR_NONE) == NULL) return (ERROR_RC); result = ERROR_RC; for(i=0; (imax) && (result != OK_RC) && (result != BADRESP_RC) ; i++) { if (data.receive_pairs != NULL) { rc_avpair_free(data.receive_pairs); data.receive_pairs = NULL; } rc_buildreq(&data, PW_ACCESS_REQUEST, authserver->name[i], authserver->port[i], timeout, retries); result = rc_send_server (&data, msg, info); } *received = data.receive_pairs; return result; } /* * Function: rc_auth_proxy * * Purpose: Builds an authentication request * with the value_pairs send and submits it to a server. * Works for a proxy; does not add IP address, and does * does not rely on config file. * * Returns: received value_pairs in received, messages from the server in msg * and 0 on success, negative on failure as return value * */ int rc_auth_proxy(VALUE_PAIR *send, VALUE_PAIR **received, char *msg) { SEND_DATA data; int result; int i; SERVER *authserver = rc_conf_srv("authserver"); int timeout = rc_conf_int("radius_timeout"); int retries = rc_conf_int("radius_retries"); data.send_pairs = send; data.receive_pairs = NULL; result = ERROR_RC; for(i=0; (imax) && (result != OK_RC) && (result != BADRESP_RC) ; i++) { if (data.receive_pairs != NULL) { rc_avpair_free(data.receive_pairs); data.receive_pairs = NULL; } rc_buildreq(&data, PW_ACCESS_REQUEST, authserver->name[i], authserver->port[i], timeout, retries); result = rc_send_server (&data, msg, NULL); } *received = data.receive_pairs; return result; } /* * Function: rc_acct_using_server * * Purpose: Builds an accounting request for port id client_port * with the value_pairs send. You explicitly supply server list. * * Remarks: NAS-Identifier/NAS-IP-Address, NAS-Port and Acct-Delay-Time get * filled in by this function, the rest has to be supplied. */ int rc_acct_using_server(SERVER *acctserver, UINT4 client_port, VALUE_PAIR *send) { SEND_DATA data; VALUE_PAIR *adt_vp; int result; struct timeval start_time, dtime; char msg[4096]; int i; int timeout = rc_conf_int("radius_timeout"); int retries = rc_conf_int("radius_retries"); data.send_pairs = send; data.receive_pairs = NULL; /* * Fill in NAS-IP-Address or NAS-Identifier */ if (rc_get_nas_id(&(data.send_pairs)) == ERROR_RC) return (ERROR_RC); /* * Fill in NAS-Port */ if (rc_avpair_add(&(data.send_pairs), PW_NAS_PORT, &client_port, 0, VENDOR_NONE) == NULL) return (ERROR_RC); /* * Fill in Acct-Delay-Time */ dtime.tv_sec = 0; if ((adt_vp = rc_avpair_add(&(data.send_pairs), PW_ACCT_DELAY_TIME, &dtime.tv_sec, 0, VENDOR_NONE)) == NULL) return (ERROR_RC); ppp_get_time(&start_time); result = ERROR_RC; for(i=0; (imax) && (result != OK_RC) && (result != BADRESP_RC) ; i++) { if (data.receive_pairs != NULL) { rc_avpair_free(data.receive_pairs); data.receive_pairs = NULL; } rc_buildreq(&data, PW_ACCOUNTING_REQUEST, acctserver->name[i], acctserver->port[i], timeout, retries); ppp_get_time(&dtime); dtime.tv_sec -= start_time.tv_sec; rc_avpair_assign(adt_vp, &dtime.tv_sec, 0); result = rc_send_server (&data, msg, NULL); } rc_avpair_free(data.receive_pairs); return result; } /* * Function: rc_acct * * Purpose: Builds an accounting request for port id client_port * with the value_pairs send * * Remarks: NAS-Identifier/NAS-IP-Address, NAS-Port and Acct-Delay-Time get * filled in by this function, the rest has to be supplied. */ int rc_acct(UINT4 client_port, VALUE_PAIR *send) { SERVER *acctserver = rc_conf_srv("acctserver"); if (!acctserver) return (ERROR_RC); return rc_acct_using_server(acctserver, client_port, send); } /* * Function: rc_acct_proxy * * Purpose: Builds an accounting request with the value_pairs send * */ int rc_acct_proxy(VALUE_PAIR *send) { SEND_DATA data; int result; char msg[4096]; int i; SERVER *acctserver = rc_conf_srv("authserver"); int timeout = rc_conf_int("radius_timeout"); int retries = rc_conf_int("radius_retries"); data.send_pairs = send; data.receive_pairs = NULL; result = ERROR_RC; for(i=0; (imax) && (result != OK_RC) && (result != BADRESP_RC) ; i++) { if (data.receive_pairs != NULL) { rc_avpair_free(data.receive_pairs); data.receive_pairs = NULL; } rc_buildreq(&data, PW_ACCOUNTING_REQUEST, acctserver->name[i], acctserver->port[i], timeout, retries); result = rc_send_server (&data, msg, NULL); } rc_avpair_free(data.receive_pairs); return result; } /* * Function: rc_check * * Purpose: ask the server hostname on the specified port for a * status message * */ int rc_check(char *host, unsigned short port, char *msg) { SEND_DATA data; int result; UINT4 service_type; int timeout = rc_conf_int("radius_timeout"); int retries = rc_conf_int("radius_retries"); data.send_pairs = data.receive_pairs = NULL; /* * Fill in NAS-IP-Address or NAS-Identifier, * although it isn't neccessary */ if (rc_get_nas_id(&(data.send_pairs)) == ERROR_RC) return (ERROR_RC); /* * Fill in Service-Type */ service_type = PW_ADMINISTRATIVE; rc_avpair_add(&(data.send_pairs), PW_SERVICE_TYPE, &service_type, 0, VENDOR_NONE); rc_buildreq(&data, PW_STATUS_SERVER, host, port, timeout, retries); result = rc_send_server (&data, msg, NULL); rc_avpair_free(data.receive_pairs); return result; } ppp-2.5.0/pppd/plugins/radius/config.c0000644000175000017500000002526614407475306014607 00000000000000/* * $Id: config.c,v 1.1 2004/11/14 07:26:26 paulus Exp $ * * Copyright (C) 1995,1996,1997 Lars Fenneberg * * Copyright 1992 Livingston Enterprises, Inc. * * Copyright 1992,1993, 1994,1995 The Regents of the University of Michigan * and Merit Network, Inc. All Rights Reserved * * See the file COPYRIGHT for the respective terms and conditions. * If the file is missing contact me at lf@elemental.net * and I'll send you a copy. * */ #include #include #include static int test_config(char *); /* * Function: find_option * * Purpose: find an option in the option list * * Returns: pointer to option on success, NULL otherwise */ static OPTION *find_option(char *optname, unsigned int type) { int i; /* there're so few options that a binary search seems not necessary */ for (i = 0; i < num_options; i++) { if (!strcmp(config_options[i].name, optname) && (config_options[i].type & type)) return &config_options[i]; } return NULL; } /* * Function: set_option_... * * Purpose: set a specific option doing type conversions * * Returns: 0 on success, -1 on failure */ static int set_option_str(char *filename, int line, OPTION *option, char *p) { if (p) option->val = (void *) strdup(p); else option->val = NULL; return 0; } static int set_option_int(char *filename, int line, OPTION *option, char *p) { int *iptr; if (p == NULL) { error("%s: line %d: bogus option value", filename, line); return (-1); } if ((iptr = (int *) malloc(sizeof(iptr))) == NULL) { novm("read_config"); return (-1); } *iptr = atoi(p); option->val = (void *) iptr; return 0; } static int set_option_srv(char *filename, int line, OPTION *option, char *p) { SERVER *serv; char *q; struct servent *svp; int i; if (p == NULL) { error("%s: line %d: bogus option value", filename, line); return (-1); } serv = (SERVER *) option->val; for (i = 0; i < serv->max; i++) { free(serv->name[i]); } serv->max = 0; while ((p = strtok(p, ", \t")) != NULL) { if ((q = strchr(p,':')) != NULL) { *q = '\0'; q++; serv->port[serv->max] = atoi(q); } else { if (!strcmp(option->name,"authserver")) if ((svp = getservbyname ("radius", "udp")) == NULL) serv->port[serv->max] = PW_AUTH_UDP_PORT; else serv->port[serv->max] = ntohs ((unsigned int) svp->s_port); else if (!strcmp(option->name, "acctserver")) if ((svp = getservbyname ("radacct", "udp")) == NULL) serv->port[serv->max] = PW_ACCT_UDP_PORT; else serv->port[serv->max] = ntohs ((unsigned int) svp->s_port); else { error("%s: line %d: no default port for %s", filename, line, option->name); return (-1); } } serv->name[serv->max++] = strdup(p); p = NULL; } return 0; } static int set_option_auo(char *filename, int line, OPTION *option, char *p) { int *iptr; if (p == NULL) { warn("%s: line %d: bogus option value", filename, line); return (-1); } if ((iptr = (int *) malloc(sizeof(iptr))) == NULL) { novm("read_config"); return (-1); } *iptr = 0; p = strtok(p, ", \t"); if (!strncmp(p, "local", 5)) *iptr = AUTH_LOCAL_FST; else if (!strncmp(p, "radius", 6)) *iptr = AUTH_RADIUS_FST; else { error("%s: auth_order: unknown keyword: %s", filename, p); free(iptr); return (-1); } p = strtok(NULL, ", \t"); if (p && (*p != '\0')) { if ((*iptr & AUTH_RADIUS_FST) && !strcmp(p, "local")) *iptr = (*iptr) | AUTH_LOCAL_SND; else if ((*iptr & AUTH_LOCAL_FST) && !strcmp(p, "radius")) *iptr = (*iptr) | AUTH_RADIUS_SND; else { error("%s: auth_order: unknown or unexpected keyword: %s", filename, p); free(iptr); return (-1); } } option->val = (void *) iptr; return 0; } /* * Function: rc_read_config * * Purpose: read the global config file * * Returns: 0 on success, -1 when failure */ int rc_read_config(char *filename) { FILE *configfd; char buffer[512], *p; OPTION *option; int line, pos; if ((configfd = fopen(filename,"r")) == NULL) { error("rc_read_config: can't open %s: %m", filename); return (-1); } line = 0; while ((fgets(buffer, sizeof(buffer), configfd) != NULL)) { line++; p = buffer; if ((*p == '\n') || (*p == '#') || (*p == '\0')) continue; p[strlen(p)-1] = '\0'; if ((pos = strcspn(p, "\t ")) == 0) { error("%s: line %d: bogus format: %s", filename, line, p); fclose(configfd); return (-1); } p[pos] = '\0'; if ((option = find_option(p, OT_ANY)) == NULL) { warn("%s: line %d: unrecognized keyword: %s", filename, line, p); continue; } if (option->status != ST_UNDEF) { error("%s: line %d: duplicate option line: %s", filename, line, p); fclose(configfd); return (-1); } p += pos+1; while (isspace(*p)) p++; switch (option->type) { case OT_STR: if (set_option_str(filename, line, option, p) < 0) fclose(configfd); return (-1); break; case OT_INT: if (set_option_int(filename, line, option, p) < 0) fclose(configfd); return (-1); break; case OT_SRV: if (set_option_srv(filename, line, option, p) < 0) fclose(configfd); return (-1); break; case OT_AUO: if (set_option_auo(filename, line, option, p) < 0) fclose(configfd); return (-1); break; default: fatal("rc_read_config: impossible case branch!"); abort(); } } fclose(configfd); return test_config(filename); } /* * Function: rc_conf_str, rc_conf_int, rc_conf_src * * Purpose: get the value of a config option * * Returns: config option value */ char *rc_conf_str(char *optname) { OPTION *option; option = find_option(optname, OT_STR); if (option == NULL) fatal("rc_conf_str: unknown config option requested: %s", optname); return (char *)option->val; } int rc_conf_int(char *optname) { OPTION *option; option = find_option(optname, OT_INT|OT_AUO); if (option == NULL) fatal("rc_conf_int: unknown config option requested: %s", optname); return *((int *)option->val); } SERVER *rc_conf_srv(char *optname) { OPTION *option; option = find_option(optname, OT_SRV); if (option == NULL) fatal("rc_conf_srv: unknown config option requested: %s", optname); return (SERVER *)option->val; } /* * Function: test_config * * Purpose: test the configuration the user supplied * * Returns: 0 on success, -1 when failure */ static int test_config(char *filename) { #if 0 struct stat st; char *file; #endif if (!(rc_conf_srv("authserver")->max)) { error("%s: no authserver specified", filename); return (-1); } if (!(rc_conf_srv("acctserver")->max)) { error("%s: no acctserver specified", filename); return (-1); } if (!rc_conf_str("servers")) { error("%s: no servers file specified", filename); return (-1); } if (!rc_conf_str("dictionary")) { error("%s: no dictionary specified", filename); return (-1); } if (rc_conf_int("radius_timeout") <= 0) { error("%s: radius_timeout <= 0 is illegal", filename); return (-1); } if (rc_conf_int("radius_retries") <= 0) { error("%s: radius_retries <= 0 is illegal", filename); return (-1); } #if 0 file = rc_conf_str("login_local"); if (stat(file, &st) == 0) { if (!S_ISREG(st.st_mode)) { error("%s: not a regular file: %s", filename, file); return (-1); } } else { error("%s: file not found: %s", filename, file); return (-1); } file = rc_conf_str("login_radius"); if (stat(file, &st) == 0) { if (!S_ISREG(st.st_mode)) { error("%s: not a regular file: %s", filename, file); return (-1); } } else { error("%s: file not found: %s", filename, file); return (-1); } #endif if (rc_conf_int("login_tries") <= 0) { error("%s: login_tries <= 0 is illegal", filename); return (-1); } if (rc_conf_str("seqfile") == NULL) { error("%s: seqfile not specified", filename); return (-1); } if (rc_conf_int("login_timeout") <= 0) { error("%s: login_timeout <= 0 is illegal", filename); return (-1); } if (rc_conf_str("mapfile") == NULL) { error("%s: mapfile not specified", filename); return (-1); } if (rc_conf_str("nologin") == NULL) { error("%s: nologin not specified", filename); return (-1); } return 0; } /* * Function: rc_find_match * * Purpose: see if ip_addr is one of the ip addresses of hostname * * Returns: 0 on success, -1 when failure * */ static int find_match (UINT4 *ip_addr, char *hostname) { UINT4 addr; char **paddr; struct hostent *hp; if (rc_good_ipaddr (hostname) == 0) { if (*ip_addr == ntohl(inet_addr (hostname))) { return (0); } } else { if ((hp = gethostbyname (hostname)) == (struct hostent *) NULL) { return (-1); } for (paddr = hp->h_addr_list; *paddr; paddr++) { addr = ** (UINT4 **) paddr; if (ntohl(addr) == *ip_addr) { return (0); } } } return (-1); } /* * Function: rc_find_server * * Purpose: search a server in the servers file * * Returns: 0 on success, -1 on failure * */ int rc_find_server (char *server_name, UINT4 *ip_addr, char *secret) { UINT4 myipaddr = 0; int len; int result; FILE *clientfd; char *h; char *s; char *host2; char buffer[128]; char hostnm[AUTH_ID_LEN + 1]; /* Get the IP address of the authentication server */ if ((*ip_addr = rc_get_ipaddr (server_name)) == (UINT4) 0) return (-1); if ((clientfd = fopen (rc_conf_str("servers"), "r")) == (FILE *) NULL) { error("rc_find_server: couldn't open file: %m: %s", rc_conf_str("servers")); return (-1); } myipaddr = rc_own_ipaddress(); result = 0; while (fgets (buffer, sizeof (buffer), clientfd) != (char *) NULL) { if (*buffer == '#') continue; if ((h = strtok (buffer, " \t\n")) == NULL) /* first hostname */ continue; memset (hostnm, '\0', AUTH_ID_LEN + 1); strlcpy (hostnm, h, AUTH_ID_LEN + 1); if ((s = strtok (NULL, " \t\n")) == NULL) /* and secret field */ continue; memset (secret, '\0', MAX_SECRET_LENGTH + 1); strlcpy (secret, s, MAX_SECRET_LENGTH + 1); if (!strchr (hostnm, '/')) /* If single name form */ { if (find_match (ip_addr, hostnm) == 0) { result++; break; } } else /* / "paired" form */ { strtok (hostnm, "/"); if (find_match (&myipaddr, hostnm) == 0) { /* If we're the 1st name, target is 2nd */ host2 = strtok (NULL, " "); if (find_match (ip_addr, host2) == 0) { result++; break; } } else /* If we were 2nd name, target is 1st name */ { if (find_match (ip_addr, hostnm) == 0) { result++; break; } } } } fclose (clientfd); if (result == 0) { memset (buffer, '\0', sizeof (buffer)); error("rc_find_server: couldn't find RADIUS server %s in %s", server_name, rc_conf_str("servers")); return (-1); } return 0; } ppp-2.5.0/pppd/plugins/radius/dict.c0000664000175000017500000002406514074250131014246 00000000000000/* * $Id: dict.c,v 1.1 2004/11/14 07:26:26 paulus Exp $ * * Copyright (C) 2002 Roaring Penguin Software Inc. * * Copyright (C) 1995,1996,1997 Lars Fenneberg * * Copyright 1992 Livingston Enterprises, Inc. * * Copyright 1992,1993, 1994,1995 The Regents of the University of Michigan * and Merit Network, Inc. All Rights Reserved * * See the file COPYRIGHT for the respective terms and conditions. * If the file is missing contact me at lf@elemental.net * and I'll send you a copy. * */ #include #include static DICT_ATTR *dictionary_attributes = NULL; static DICT_VALUE *dictionary_values = NULL; static VENDOR_DICT *vendor_dictionaries = NULL; /* * Function: rc_read_dictionary * * Purpose: Initialize the dictionary. Read all ATTRIBUTES into * the dictionary_attributes list. Read all VALUES into * the dictionary_values list. Construct VENDOR dictionaries * as required. * */ int rc_read_dictionary (char *filename) { FILE *dictfd; char dummystr[AUTH_ID_LEN]; char namestr[AUTH_ID_LEN]; char valstr[AUTH_ID_LEN]; char attrstr[AUTH_ID_LEN]; char typestr[AUTH_ID_LEN]; char vendorstr[AUTH_ID_LEN]; int line_no; DICT_ATTR *attr; DICT_VALUE *dval; VENDOR_DICT *vdict; char buffer[256]; int value; int type; int n; int retcode; if ((dictfd = fopen (filename, "r")) == (FILE *) NULL) { error( "rc_read_dictionary: couldn't open dictionary %s: %s", filename, strerror(errno)); return (-1); } line_no = 0; retcode = 0; while (fgets (buffer, sizeof (buffer), dictfd) != (char *) NULL) { line_no++; /* Skip empty space */ if (*buffer == '#' || *buffer == '\0' || *buffer == '\n') { continue; } if (strncmp (buffer, "VENDOR", 6) == 0) { /* Read the VENDOR line */ if (sscanf(buffer, "%s%s%d", dummystr, namestr, &value) != 3) { error("rc_read_dictionary: invalid vendor on line %d of dictionary %s", line_no, filename); retcode = -1; break; } /* Validate entry */ if (strlen (namestr) > NAME_LENGTH) { error("rc_read_dictionary: invalid name length on line %d of dictionary %s", line_no, filename); retcode = -1; break; } /* Create new vendor entry */ vdict = (VENDOR_DICT *) malloc (sizeof (VENDOR_DICT)); if (!vdict) { novm("rc_read_dictionary"); retcode = -1; break; } strcpy(vdict->vendorname, namestr); vdict->vendorcode = value; vdict->attributes = NULL; vdict->next = vendor_dictionaries; vendor_dictionaries = vdict; } else if (strncmp (buffer, "ATTRIBUTE", 9) == 0) { /* Read the ATTRIBUTE line. It is one of: * ATTRIBUTE attr_name attr_val type OR * ATTRIBUTE attr_name attr_val type vendor */ vendorstr[0] = 0; n = sscanf(buffer, "%s%s%s%s%s", dummystr, namestr, valstr, typestr, vendorstr); if (n != 4 && n != 5) { error("rc_read_dictionary: invalid attribute on line %d of dictionary %s", line_no, filename); retcode = -1; break; } /* * Validate all entries */ if (strlen (namestr) > NAME_LENGTH) { error("rc_read_dictionary: invalid name length on line %d of dictionary %s", line_no, filename); retcode = -1; break; } if (strlen (vendorstr) > NAME_LENGTH) { error("rc_read_dictionary: invalid name length on line %d of dictionary %s", line_no, filename); retcode = -1; break; } if (!isdigit (*valstr)) { error("rc_read_dictionary: invalid value on line %d of dictionary %s", line_no, filename); retcode = -1; break; } value = atoi (valstr); if (strcmp (typestr, "string") == 0) { type = PW_TYPE_STRING; } else if (strcmp (typestr, "integer") == 0) { type = PW_TYPE_INTEGER; } else if (strcmp (typestr, "ipaddr") == 0 || strcmp (typestr, "ipv4addr") == 0) { type = PW_TYPE_IPADDR; } else if (strcmp (typestr, "date") == 0) { type = PW_TYPE_DATE; } else if (strcmp (typestr, "ifid") == 0) { type = PW_TYPE_IFID; } else if (strcmp (typestr, "ipv6addr") == 0) { type = PW_TYPE_IPV6ADDR; } else if (strcmp (typestr, "ipv6prefix") == 0) { type = PW_TYPE_IPV6PREFIX; } else { error("rc_read_dictionary: invalid type on line %d of dictionary %s", line_no, filename); retcode = -1; break; } /* Search for vendor if supplied */ if (*vendorstr) { vdict = rc_dict_findvendor(vendorstr); if (!vdict) { error("rc_read_dictionary: unknown vendor on line %d of dictionary %s", line_no, filename); retcode = -1; break; } } else { vdict = NULL; } /* Create a new attribute for the list */ if ((attr = (DICT_ATTR *) malloc (sizeof (DICT_ATTR))) == (DICT_ATTR *) NULL) { novm("rc_read_dictionary"); retcode = -1; break; } strcpy (attr->name, namestr); if (vdict) { attr->vendorcode = vdict->vendorcode; } else { attr->vendorcode = VENDOR_NONE; } attr->value = value; attr->type = type; /* Insert it into the list */ if (vdict) { attr->next = vdict->attributes; vdict->attributes = attr; } else { attr->next = dictionary_attributes; dictionary_attributes = attr; } } else if (strncmp (buffer, "VALUE", 5) == 0) { /* Read the VALUE line */ if (sscanf (buffer, "%s%s%s%s", dummystr, attrstr, namestr, valstr) != 4) { error("rc_read_dictionary: invalid value entry on line %d of dictionary %s", line_no, filename); retcode = -1; break; } /* * Validate all entries */ if (strlen (attrstr) > NAME_LENGTH) { error("rc_read_dictionary: invalid attribute length on line %d of dictionary %s", line_no, filename); retcode = -1; break; } if (strlen (namestr) > NAME_LENGTH) { error("rc_read_dictionary: invalid name length on line %d of dictionary %s", line_no, filename); retcode = -1; break; } if (!isdigit (*valstr)) { error("rc_read_dictionary: invalid value on line %d of dictionary %s", line_no, filename); retcode = -1; break; } value = atoi (valstr); /* Create a new VALUE entry for the list */ if ((dval = (DICT_VALUE *) malloc (sizeof (DICT_VALUE))) == (DICT_VALUE *) NULL) { novm("rc_read_dictionary"); retcode = -1; break; } strcpy (dval->attrname, attrstr); strcpy (dval->name, namestr); dval->value = value; /* Insert it into the list */ dval->next = dictionary_values; dictionary_values = dval; } else if (strncmp (buffer, "INCLUDE", 7) == 0) { /* Read the INCLUDE line */ if (sscanf (buffer, "%s%s", dummystr, namestr) != 2) { error("rc_read_dictionary: invalid include entry on line %d of dictionary %s", line_no, filename); retcode = -1; break; } if (rc_read_dictionary(namestr) == -1) { retcode = -1; break; } } } fclose (dictfd); return retcode; } /* * Function: rc_dict_getattr * * Purpose: Return the full attribute structure based on the * attribute id number and vendor code. If vendor code is VENDOR_NONE, * non-vendor-specific attributes are used * */ DICT_ATTR *rc_dict_getattr (int attribute, int vendor) { DICT_ATTR *attr; VENDOR_DICT *dict; if (vendor == VENDOR_NONE) { attr = dictionary_attributes; while (attr != (DICT_ATTR *) NULL) { if (attr->value == attribute) { return (attr); } attr = attr->next; } } else { dict = rc_dict_getvendor(vendor); if (!dict) { return NULL; } attr = dict->attributes; while (attr) { if (attr->value == attribute) { return attr; } attr = attr->next; } } return NULL; } /* * Function: rc_dict_findattr * * Purpose: Return the full attribute structure based on the * attribute name. * */ DICT_ATTR *rc_dict_findattr (char *attrname) { DICT_ATTR *attr; VENDOR_DICT *dict; attr = dictionary_attributes; while (attr != (DICT_ATTR *) NULL) { if (strcasecmp (attr->name, attrname) == 0) { return (attr); } attr = attr->next; } /* Search vendor-specific dictionaries */ dict = vendor_dictionaries; while (dict) { attr = dict->attributes; while (attr) { if (strcasecmp (attr->name, attrname) == 0) { return (attr); } attr = attr->next; } dict = dict->next; } return ((DICT_ATTR *) NULL); } /* * Function: rc_dict_findval * * Purpose: Return the full value structure based on the * value name. * */ DICT_VALUE *rc_dict_findval (char *valname) { DICT_VALUE *val; val = dictionary_values; while (val != (DICT_VALUE *) NULL) { if (strcasecmp (val->name, valname) == 0) { return (val); } val = val->next; } return ((DICT_VALUE *) NULL); } /* * Function: dict_getval * * Purpose: Return the full value structure based on the * actual value and the associated attribute name. * */ DICT_VALUE * rc_dict_getval (UINT4 value, char *attrname) { DICT_VALUE *val; val = dictionary_values; while (val != (DICT_VALUE *) NULL) { if (strcmp (val->attrname, attrname) == 0 && val->value == value) { return (val); } val = val->next; } return ((DICT_VALUE *) NULL); } /* * Function: rc_dict_findvendor * * Purpose: Return the vendor's dictionary given the vendor name. * */ VENDOR_DICT * rc_dict_findvendor (char *vendorname) { VENDOR_DICT *dict; dict = vendor_dictionaries; while (dict) { if (!strcmp(vendorname, dict->vendorname)) { return dict; } dict = dict->next; } return NULL; } /* * Function: rc_dict_getvendor * * Purpose: Return the vendor's dictionary given the vendor ID * */ VENDOR_DICT * rc_dict_getvendor (int id) { VENDOR_DICT *dict; dict = vendor_dictionaries; while (dict) { if (id == dict->vendorcode) { return dict; } dict = dict->next; } return NULL; } ppp-2.5.0/pppd/plugins/radius/ip_util.c0000644000175000017500000000607414353435407015001 00000000000000/* * $Id: ip_util.c,v 1.1 2004/11/14 07:26:26 paulus Exp $ * * Copyright (C) 1995,1996,1997 Lars Fenneberg * * Copyright 1992 Livingston Enterprises, Inc. * * Copyright 1992,1993, 1994,1995 The Regents of the University of Michigan * and Merit Network, Inc. All Rights Reserved * * See the file COPYRIGHT for the respective terms and conditions. * If the file is missing contact me at lf@elemental.net * and I'll send you a copy. * */ #include #include /* * Function: rc_get_ipaddr * * Purpose: return an IP address in host long notation from a host * name or address in dot notation. * * Returns: 0 on failure */ UINT4 rc_get_ipaddr (const char *host) { struct hostent *hp; if (rc_good_ipaddr (host) == 0) { return ntohl(inet_addr (host)); } else if ((hp = gethostbyname (host)) == (struct hostent *) NULL) { error("rc_get_ipaddr: couldn't resolve hostname: %s", host); return ((UINT4) 0); } return ntohl((*(UINT4 *) hp->h_addr)); } /* * Function: rc_good_ipaddr * * Purpose: check for valid IP address in standard dot notation. * * Returns: 0 on success, -1 when failure * */ int rc_good_ipaddr (const char *addr) { int dot_count; int digit_count; if (addr == NULL) return (-1); dot_count = 0; digit_count = 0; while (*addr != '\0' && *addr != ' ') { if (*addr == '.') { dot_count++; digit_count = 0; } else if (!isdigit (*addr)) { dot_count = 5; } else { digit_count++; if (digit_count > 3) { dot_count = 5; } } addr++; } if (dot_count != 3) { return (-1); } else { return (0); } } /* * Function: rc_ip_hostname * * Purpose: Return a printable host name (or IP address in dot notation) * for the supplied IP address. * */ const char *rc_ip_hostname (UINT4 h_ipaddr) { struct hostent *hp; UINT4 n_ipaddr = htonl (h_ipaddr); if ((hp = gethostbyaddr ((char *) &n_ipaddr, sizeof (struct in_addr), AF_INET)) == NULL) { error("rc_ip_hostname: couldn't look up host by addr: %08lX", h_ipaddr); } return ((hp==NULL)?"unknown":hp->h_name); } /* * Function: rc_own_ipaddress * * Purpose: get the IP address of this host in host order * * Returns: IP address on success, 0 on failure * */ UINT4 rc_own_ipaddress(void) { static UINT4 this_host_ipaddr = 0; if (!this_host_ipaddr) { if ((this_host_ipaddr = rc_get_ipaddr (ppp_hostname())) == 0) { error("rc_own_ipaddress: couldn't get own IP address"); return 0; } } return this_host_ipaddr; } /* * Function: rc_own_bind_ipaddress * * Purpose: get the IP address to be used as a source address * for sending requests in host order * * Returns: IP address * */ UINT4 rc_own_bind_ipaddress(void) { char *bindaddr; UINT4 rval = 0; if ((bindaddr = rc_conf_str("bindaddr")) == NULL || strcmp(rc_conf_str("bindaddr"), "*") == 0) { rval = INADDR_ANY; } else { if ((rval = rc_get_ipaddr(bindaddr)) == 0) { error("rc_own_bind_ipaddress: couldn't get IP address from bindaddr"); rval = INADDR_ANY; } } return rval; } ppp-2.5.0/pppd/plugins/radius/clientid.c0000644000175000017500000000417114407475306015125 00000000000000/* * $Id: clientid.c,v 1.1 2004/11/14 07:26:26 paulus Exp $ * * Copyright (C) 1995,1996,1997 Lars Fenneberg * * See the file COPYRIGHT for the respective terms and conditions. * If the file is missing contact me at lf@elemental.net * and I'll send you a copy. * */ #include #include struct map2id_s { char *name; UINT4 id; struct map2id_s *next; }; static struct map2id_s *map2id_list = NULL; /* * Function: rc_read_mapfile * * Purpose: Read in the ttyname to port id map file * * Arguments: the file name of the map file * * Returns: zero on success, negative integer on failure */ int rc_read_mapfile(char *filename) { char buffer[1024]; FILE *mapfd; char *c, *name, *id, *q; struct map2id_s *p; int lnr = 0; if ((mapfd = fopen(filename,"r")) == NULL) { error("rc_read_mapfile: can't read %s: %s", filename, strerror(errno)); return (-1); } #define SKIP(p) while(*p && isspace(*p)) p++; while (fgets(buffer, sizeof(buffer), mapfd) != NULL) { lnr++; q = buffer; SKIP(q); if ((*q == '\n') || (*q == '#') || (*q == '\0')) continue; if (( c = strchr(q, ' ')) || (c = strchr(q,'\t'))) { *c = '\0'; c++; SKIP(c); name = q; id = c; if ((p = (struct map2id_s *)malloc(sizeof(*p))) == NULL) { novm("rc_read_mapfile"); fclose(mapfd); return (-1); } p->name = strdup(name); p->id = atoi(id); p->next = map2id_list; map2id_list = p; } else { error("rc_read_mapfile: malformed line in %s, line %d", filename, lnr); fclose(mapfd); return (-1); } } #undef SKIP fclose(mapfd); return 0; } /* * Function: rc_map2id * * Purpose: Map ttyname to port id * * Arguments: full pathname of the tty * * Returns: port id, zero if no entry found */ UINT4 rc_map2id(const char *name) { struct map2id_s *p; char ttyname[PATH_MAX]; *ttyname = '\0'; if (*name != '/') strcpy(ttyname, "/dev/"); strncat(ttyname, name, sizeof(ttyname) - strlen(ttyname) -1); for(p = map2id_list; p; p = p->next) if (!strcmp(ttyname, p->name)) return p->id; warn("rc_map2id: can't find tty %s in map database", ttyname); return 0; } ppp-2.5.0/pppd/plugins/radius/sendserver.c0000644000175000017500000003223314353435407015510 00000000000000/* * $Id: sendserver.c,v 1.1 2004/11/14 07:26:26 paulus Exp $ * * Copyright (C) 1995,1996,1997 Lars Fenneberg * * Copyright 1992 Livingston Enterprises, Inc. * * Copyright 1992,1993, 1994,1995 The Regents of the University of Michigan * and Merit Network, Inc. All Rights Reserved * * See the file COPYRIGHT for the respective terms and conditions. * If the file is missing contact me at lf@elemental.net * and I'll send you a copy. * */ #include #include #include #include static void rc_random_vector (unsigned char *); static int rc_check_reply (AUTH_HDR *, int, char *, unsigned char *, unsigned char); /* * Function: rc_pack_list * * Purpose: Packs an attribute value pair list into a buffer. * * Returns: Number of octets packed. * */ static int rc_pack_list (VALUE_PAIR *vp, char *secret, AUTH_HDR *auth) { int length, i, pc, secretlen, padded_length; int total_length = 0; UINT4 lvalue; unsigned char passbuf[MAX(AUTH_PASS_LEN, CHAP_VALUE_LENGTH)]; unsigned char md5buf[256]; unsigned char *buf, *vector, *lenptr; buf = auth->data; while (vp != (VALUE_PAIR *) NULL) { if (vp->vendorcode != VENDOR_NONE) { *buf++ = PW_VENDOR_SPECIFIC; /* Place-holder for where to put length */ lenptr = buf++; /* Insert vendor code */ *buf++ = 0; *buf++ = (((unsigned int) vp->vendorcode) >> 16) & 255; *buf++ = (((unsigned int) vp->vendorcode) >> 8) & 255; *buf++ = ((unsigned int) vp->vendorcode) & 255; /* Insert vendor-type */ *buf++ = vp->attribute; /* Insert value */ switch(vp->type) { case PW_TYPE_STRING: length = vp->lvalue; *lenptr = length + 8; *buf++ = length+2; memcpy(buf, vp->strvalue, (size_t) length); buf += length; total_length += length+8; break; case PW_TYPE_INTEGER: case PW_TYPE_IPADDR: length = sizeof(UINT4); *lenptr = length + 8; *buf++ = length+2; lvalue = htonl(vp->lvalue); memcpy(buf, (char *) &lvalue, sizeof(UINT4)); buf += length; total_length += length+8; break; default: break; } } else { *buf++ = vp->attribute; switch (vp->attribute) { case PW_USER_PASSWORD: /* Encrypt the password */ /* Chop off password at AUTH_PASS_LEN */ length = vp->lvalue; if (length > AUTH_PASS_LEN) length = AUTH_PASS_LEN; /* Calculate the padded length */ padded_length = (length+(AUTH_VECTOR_LEN-1)) & ~(AUTH_VECTOR_LEN-1); /* Record the attribute length */ *buf++ = padded_length + 2; /* Pad the password with zeros */ memset ((char *) passbuf, '\0', AUTH_PASS_LEN); memcpy ((char *) passbuf, vp->strvalue, (size_t) length); secretlen = strlen (secret); vector = auth->vector; for(i = 0; i < padded_length; i += AUTH_VECTOR_LEN) { /* Calculate the MD5 digest*/ strcpy ((char *) md5buf, secret); memcpy ((char *) md5buf + secretlen, vector, AUTH_VECTOR_LEN); rc_md5_calc (buf, md5buf, secretlen + AUTH_VECTOR_LEN); /* Remeber the start of the digest */ vector = buf; /* Xor the password into the MD5 digest */ for (pc = i; pc < (i + AUTH_VECTOR_LEN); pc++) { *buf++ ^= passbuf[pc]; } } total_length += padded_length + 2; break; #if 0 case PW_CHAP_PASSWORD: *buf++ = CHAP_VALUE_LENGTH + 2; /* Encrypt the Password */ length = vp->lvalue; if (length > CHAP_VALUE_LENGTH) { length = CHAP_VALUE_LENGTH; } memset ((char *) passbuf, '\0', CHAP_VALUE_LENGTH); memcpy ((char *) passbuf, vp->strvalue, (size_t) length); /* Calculate the MD5 Digest */ secretlen = strlen (secret); strcpy ((char *) md5buf, secret); memcpy ((char *) md5buf + secretlen, (char *) auth->vector, AUTH_VECTOR_LEN); rc_md5_calc (buf, md5buf, secretlen + AUTH_VECTOR_LEN); /* Xor the password into the MD5 digest */ for (i = 0; i < CHAP_VALUE_LENGTH; i++) { *buf++ ^= passbuf[i]; } total_length += CHAP_VALUE_LENGTH + 2; break; #endif default: switch (vp->type) { case PW_TYPE_STRING: length = vp->lvalue; *buf++ = length + 2; memcpy (buf, vp->strvalue, (size_t) length); buf += length; total_length += length + 2; break; case PW_TYPE_INTEGER: case PW_TYPE_IPADDR: *buf++ = sizeof (UINT4) + 2; lvalue = htonl (vp->lvalue); memcpy (buf, (char *) &lvalue, sizeof (UINT4)); buf += sizeof (UINT4); total_length += sizeof (UINT4) + 2; break; default: break; } break; } } vp = vp->next; } return total_length; } /* * Function: rc_send_server * * Purpose: send a request to a RADIUS server and wait for the reply * */ int rc_send_server (SEND_DATA *data, char *msg, REQUEST_INFO *info) { int sockfd; struct sockaddr salocal; struct sockaddr saremote; struct sockaddr_in *sin; struct timeval authtime; fd_set readfds; AUTH_HDR *auth, *recv_auth; UINT4 auth_ipaddr; char *server_name; /* Name of server to query */ socklen_t salen; int result; int total_length; socklen_t length; int retry_max; int secretlen; char secret[MAX_SECRET_LENGTH + 1]; unsigned char vector[AUTH_VECTOR_LEN]; char recv_buffer[BUFFER_LEN]; char send_buffer[BUFFER_LEN]; int retries; VALUE_PAIR *vp; server_name = data->server; if (server_name == (char *) NULL || server_name[0] == '\0') return (ERROR_RC); if ((vp = rc_avpair_get(data->send_pairs, PW_SERVICE_TYPE)) && \ (vp->lvalue == PW_ADMINISTRATIVE)) { strcpy(secret, MGMT_POLL_SECRET); if ((auth_ipaddr = rc_get_ipaddr(server_name)) == 0) return (ERROR_RC); } else { if (rc_find_server (server_name, &auth_ipaddr, secret) != 0) { memset (secret, '\0', sizeof (secret)); return (ERROR_RC); } } sockfd = socket (AF_INET, SOCK_DGRAM, 0); if (sockfd < 0) { memset (secret, '\0', sizeof (secret)); error("rc_send_server: socket: %s", strerror(errno)); return (ERROR_RC); } length = sizeof (salocal); sin = (struct sockaddr_in *) & salocal; memset ((char *) sin, '\0', (size_t) length); sin->sin_family = AF_INET; sin->sin_addr.s_addr = htonl(rc_own_bind_ipaddress()); sin->sin_port = htons ((unsigned short) 0); if (bind (sockfd, (struct sockaddr *) sin, length) < 0 || getsockname (sockfd, (struct sockaddr *) sin, &length) < 0) { close (sockfd); memset (secret, '\0', sizeof (secret)); error("rc_send_server: bind: %s: %m", server_name); return (ERROR_RC); } retry_max = data->retries; /* Max. numbers to try for reply */ retries = 0; /* Init retry cnt for blocking call */ /* Build a request */ auth = (AUTH_HDR *) send_buffer; auth->code = data->code; auth->id = data->seq_nbr; if (data->code == PW_ACCOUNTING_REQUEST) { total_length = rc_pack_list(data->send_pairs, secret, auth) + AUTH_HDR_LEN; auth->length = htons ((unsigned short) total_length); memset((char *) auth->vector, 0, AUTH_VECTOR_LEN); secretlen = strlen (secret); memcpy ((char *) auth + total_length, secret, secretlen); rc_md5_calc (vector, (unsigned char *) auth, total_length + secretlen); memcpy ((char *) auth->vector, (char *) vector, AUTH_VECTOR_LEN); } else { rc_random_vector (vector); memcpy (auth->vector, vector, AUTH_VECTOR_LEN); total_length = rc_pack_list(data->send_pairs, secret, auth) + AUTH_HDR_LEN; auth->length = htons ((unsigned short) total_length); } sin = (struct sockaddr_in *) & saremote; memset ((char *) sin, '\0', sizeof (saremote)); sin->sin_family = AF_INET; sin->sin_addr.s_addr = htonl (auth_ipaddr); sin->sin_port = htons ((unsigned short) data->svc_port); for (;;) { sendto (sockfd, (char *) auth, (unsigned int) total_length, (int) 0, (struct sockaddr *) sin, sizeof (struct sockaddr_in)); authtime.tv_usec = 0L; authtime.tv_sec = (long) data->timeout; FD_ZERO (&readfds); FD_SET (sockfd, &readfds); if (select (sockfd + 1, &readfds, NULL, NULL, &authtime) < 0) { if (errno == EINTR && !ppp_signaled(SIGTERM)) continue; error("rc_send_server: select: %m"); memset (secret, '\0', sizeof (secret)); close (sockfd); return (ERROR_RC); } if (FD_ISSET (sockfd, &readfds)) break; /* * Timed out waiting for response. Retry "retry_max" times * before giving up. If retry_max = 0, don't retry at all. */ if (++retries >= retry_max) { error("rc_send_server: no reply from RADIUS server %s:%u", rc_ip_hostname (auth_ipaddr), data->svc_port); close (sockfd); memset (secret, '\0', sizeof (secret)); return (TIMEOUT_RC); } } salen = sizeof (saremote); length = recvfrom (sockfd, (char *) recv_buffer, (int) sizeof (recv_buffer), (int) 0, &saremote, &salen); if (length <= 0) { error("rc_send_server: recvfrom: %s:%d: %m", server_name,\ data->svc_port); close (sockfd); memset (secret, '\0', sizeof (secret)); return (ERROR_RC); } recv_auth = (AUTH_HDR *)recv_buffer; result = rc_check_reply (recv_auth, BUFFER_LEN, secret, vector, data->seq_nbr); data->receive_pairs = rc_avpair_gen(recv_auth); close (sockfd); if (info) { memcpy(info->secret, secret, sizeof(info->secret)); memcpy(info->request_vector, vector, sizeof(info->request_vector)); } memset (secret, '\0', sizeof (secret)); if (result != OK_RC) return (result); *msg = '\0'; vp = data->receive_pairs; while (vp) { if ((vp = rc_avpair_get(vp, PW_REPLY_MESSAGE))) { strcat(msg, (char*) vp->strvalue); strcat(msg, "\n"); vp = vp->next; } } if ((recv_auth->code == PW_ACCESS_ACCEPT) || (recv_auth->code == PW_PASSWORD_ACK) || (recv_auth->code == PW_ACCOUNTING_RESPONSE)) { result = OK_RC; } else { result = BADRESP_RC; } return (result); } /* * Function: rc_check_reply * * Purpose: verify items in returned packet. * * Returns: OK_RC -- upon success, * BADRESP_RC -- if anything looks funny. * */ static int rc_check_reply (AUTH_HDR *auth, int bufferlen, char *secret, unsigned char *vector, unsigned char seq_nbr) { int secretlen; int totallen; unsigned char calc_digest[AUTH_VECTOR_LEN]; unsigned char reply_digest[AUTH_VECTOR_LEN]; totallen = ntohs (auth->length); secretlen = strlen (secret); /* Do sanity checks on packet length */ if ((totallen < 20) || (totallen > 4096)) { error("rc_check_reply: received RADIUS server response with invalid length"); return (BADRESP_RC); } /* Verify buffer space, should never trigger with current buffer size and check above */ if ((totallen + secretlen) > bufferlen) { error("rc_check_reply: not enough buffer space to verify RADIUS server response"); return (BADRESP_RC); } /* Verify that id (seq. number) matches what we sent */ if (auth->id != seq_nbr) { error("rc_check_reply: received non-matching id in RADIUS server response"); return (BADRESP_RC); } /* Verify the reply digest */ memcpy ((char *) reply_digest, (char *) auth->vector, AUTH_VECTOR_LEN); memcpy ((char *) auth->vector, (char *) vector, AUTH_VECTOR_LEN); memcpy ((char *) auth + totallen, secret, secretlen); rc_md5_calc (calc_digest, (unsigned char *) auth, totallen + secretlen); #ifdef DIGEST_DEBUG { int i; fputs("reply_digest: ", stderr); for (i = 0; i < AUTH_VECTOR_LEN; i++) { fprintf(stderr,"%.2x ", (int) reply_digest[i]); } fputs("\ncalc_digest: ", stderr); for (i = 0; i < AUTH_VECTOR_LEN; i++) { fprintf(stderr,"%.2x ", (int) calc_digest[i]); } fputs("\n", stderr); } #endif if (memcmp ((char *) reply_digest, (char *) calc_digest, AUTH_VECTOR_LEN) != 0) { #ifdef RADIUS_116 /* the original Livingston radiusd v1.16 seems to have a bug in digest calculation with accounting requests, authentication request are ok. i looked at the code but couldn't find any bugs. any help to get this kludge out are welcome. preferably i want to reproduce the calculation bug here to be compatible to stock Livingston radiusd v1.16. -lf, 03/14/96 */ if (auth->code == PW_ACCOUNTING_RESPONSE) return (OK_RC); #endif error("rc_check_reply: received invalid reply digest from RADIUS server"); return (BADRESP_RC); } return (OK_RC); } /* * Function: rc_random_vector * * Purpose: generates a random vector of AUTH_VECTOR_LEN octets. * * Returns: the vector (call by reference) * */ static void rc_random_vector (unsigned char *vector) { int randno; int i; int fd; /* well, I added this to increase the security for user passwords. we use /dev/urandom here, as /dev/random might block and we don't need that much randomness. BTW, great idea, Ted! -lf, 03/18/95 */ if ((fd = open(PPP_PATH_DEV_URANDOM, O_RDONLY)) >= 0) { unsigned char *pos; int readcount; i = AUTH_VECTOR_LEN; pos = vector; while (i > 0) { readcount = read(fd, (char *)pos, i); pos += readcount; i -= readcount; } close(fd); return; } /* else fall through */ for (i = 0; i < AUTH_VECTOR_LEN;) { randno = magic(); memcpy ((char *) vector, (char *) &randno, sizeof (int)); vector += sizeof (int); i += sizeof (int); } return; } ppp-2.5.0/pppd/plugins/radius/lock.c0000644000175000017500000000152211043063522014241 00000000000000/* * $Id: lock.c,v 1.1 2004/11/14 07:26:26 paulus Exp $ * * Copyright (C) 1997 Lars Fenneberg * * See the file COPYRIGHT for the respective terms and conditions. * If the file is missing contact me at lf@elemental.net * and I'll send you a copy. * */ #include "includes.h" #include #include int do_lock_exclusive(int fd) { struct flock fl; int res; memset((void *)&fl, 0, sizeof(fl)); fl.l_type = F_WRLCK; fl.l_whence = fl.l_start = 0; fl.l_len = 0; /* 0 means "to end of file" */ res = fcntl(fd, F_SETLK, &fl); if ((res == -1) && (errno == EAGAIN)) errno = EWOULDBLOCK; return res; } int do_unlock(int fd) { struct flock fl; memset((void *)&fl, 0, sizeof(fl)); fl.l_type = F_UNLCK; fl.l_whence = fl.l_start = 0; fl.l_len = 0; /* 0 means "to end of file" */ return fcntl(fd, F_SETLK, &fl); } ppp-2.5.0/pppd/plugins/radius/util.c0000664000175000017500000000312014124267300014267 00000000000000/* * $Id: util.c,v 1.1 2004/11/14 07:26:26 paulus Exp $ * * Copyright (C) 1995,1996,1997 Lars Fenneberg * * Copyright 1992 Livingston Enterprises, Inc. * * Copyright 1992,1993, 1994,1995 The Regents of the University of Michigan * and Merit Network, Inc. All Rights Reserved * * See the file COPYRIGHT for the respective terms and conditions. * If the file is missing contact me at lf@elemental.net * and I'll send you a copy. * */ #include #include /* * Function: rc_str2tm * * Purpose: Turns printable string into correct tm struct entries. * */ static const char * months[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; void rc_str2tm (char *valstr, struct tm *tm) { int i; /* Get the month */ for (i = 0; i < 12; i++) { if (strncmp (months[i], valstr, 3) == 0) { tm->tm_mon = i; i = 13; } } /* Get the Day */ tm->tm_mday = atoi (&valstr[4]); /* Now the year */ tm->tm_year = atoi (&valstr[7]) - 1900; } void rc_mdelay(int msecs) { struct timeval tv; tv.tv_sec = (int) msecs / 1000; tv.tv_usec = (msecs % 1000) * 1000; select(0,(fd_set *)NULL,(fd_set *)NULL,(fd_set *)NULL, &tv); } /* * Function: rc_mksid * * Purpose: generate a quite unique string * * Remarks: not that unique at all... * */ char * rc_mksid (void) { static char buf[32]; static unsigned short int cnt = 0; snprintf(buf, sizeof(buf), "%08lX%04X%02hX", (unsigned long int) time (NULL), (unsigned int) getpid (), (unsigned short) (cnt & 0xFF)); cnt++; return buf; } ppp-2.5.0/pppd/plugins/radius/md5.c0000644000175000017500000000111214353435407014005 00000000000000/* * $Id: md5.c,v 1.1 2004/11/14 07:26:26 paulus Exp $ */ #include #include int rc_md5_calc(unsigned char *out, const unsigned char *in, unsigned int inl) { int retval = 0; int outl = MD5_DIGEST_LENGTH; PPP_MD_CTX *ctx = PPP_MD_CTX_new(); if (ctx) { if (PPP_DigestInit(ctx, PPP_md5())) { if (PPP_DigestUpdate(ctx, in, inl)) { if (PPP_DigestFinal(ctx, out, &outl)) { retval = 1; } } } PPP_MD_CTX_free(ctx); } return retval; } ppp-2.5.0/pppd/plugins/radius/radattr.c0000644000175000017500000000645314353435407014776 00000000000000/*********************************************************************** * * radattr.c * * A plugin which is stacked on top of radius.so. This plugin writes * all RADIUS attributes from the server's authentication confirmation * into /var/run/radattr.pppN. These attributes are available for * consumption by /etc/ppp/ip-{up,down} scripts. * * Copyright (C) 2002 Roaring Penguin Software Inc. * * This plugin may be distributed according to the terms of the GNU * General Public License, version 2 or (at your option) any later version. * ***********************************************************************/ static char const RCSID[] = "$Id: radattr.c,v 1.2 2004/10/28 00:24:40 paulus Exp $"; #include #include #include #include #include #include #include #include "radiusclient.h" extern void (*radius_attributes_hook)(VALUE_PAIR *); static void print_attributes(VALUE_PAIR *); static void cleanup(void *opaque, int arg); char pppd_version[] = PPPD_VERSION; /********************************************************************** * %FUNCTION: plugin_init * %ARGUMENTS: * None * %RETURNS: * Nothing * %DESCRIPTION: * Initializes radattr plugin. ***********************************************************************/ void plugin_init(void) { radius_attributes_hook = print_attributes; #if 0 /* calling cleanup() on link down is problematic because print_attributes() is called only after PAP or CHAP authentication, but not when the link should go up again for any other reason */ ppp_add_notify(NF_LINK_DOWN, cleanup, NULL); #endif /* Just in case... */ ppp_add_notify(NF_EXIT, cleanup, NULL); info("RADATTR plugin initialized."); } /********************************************************************** * %FUNCTION: print_attributes * %ARGUMENTS: * vp -- linked-list of RADIUS attribute-value pairs * %RETURNS: * Nothing * %DESCRIPTION: * Prints the attribute pairs to /var/run/radattr.pppN. Each line of the * file contains "name value" pairs. ***********************************************************************/ static void print_attributes(VALUE_PAIR *vp) { FILE *fp; char fname[512]; char name[2048]; char value[2048]; int cnt = 0; mode_t old_umask; slprintf(fname, sizeof(fname), "/var/run/radattr.%s", ppp_ifname()); old_umask = umask(077); fp = fopen(fname, "w"); umask(old_umask); if (!fp) { warn("radattr plugin: Could not open %s for writing: %m", fname); return; } for (; vp; vp=vp->next) { if (rc_avpair_tostr(vp, name, sizeof(name), value, sizeof(value)) < 0) { continue; } fprintf(fp, "%s %s\n", name, value); cnt++; } fclose(fp); dbglog("RADATTR plugin wrote %d line(s) to file %s.", cnt, fname); } /********************************************************************** * %FUNCTION: cleanup * %ARGUMENTS: * opaque -- not used * arg -- not used * %RETURNS: * Nothing * %DESCRIPTION: * Deletes /var/run/radattr.pppN ***********************************************************************/ static void cleanup(void *opaque, int arg) { char fname[512]; slprintf(fname, sizeof(fname), "/var/run/radattr.%s", ppp_get_ifname(NULL,0)); (void) remove(fname); dbglog("RADATTR plugin removed file %s.", fname); } ppp-2.5.0/pppd/plugins/radius/radius.c0000644000175000017500000012117414407475306014624 00000000000000/*********************************************************************** * * radius.c * * RADIUS plugin for pppd. Performs PAP, CHAP, MS-CHAP, MS-CHAPv2 * authentication using RADIUS. * * Copyright (C) 2002 Roaring Penguin Software Inc. * * Based on a patch for ipppd, which is: * Copyright (C) 1996, Matjaz Godec * Copyright (C) 1996, Lars Fenneberg * Copyright (C) 1997, Miguel A.L. Paraz * * Uses radiusclient library, which is: * Copyright (C) 1995,1996,1997,1998 Lars Fenneberg * Copyright (C) 2002 Roaring Penguin Software Inc. * * MPPE support is by Ralf Hofmann, , with * modification from Frank Cusack, . * * This plugin may be distributed according to the terms of the GNU * General Public License, version 2 or (at your option) any later version. * ***********************************************************************/ static char const RCSID[] = "$Id: radius.c,v 1.32 2008/05/26 09:18:08 paulus Exp $"; #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef PPP_WITH_CHAPMS #include #ifdef PPP_WITH_MPPE #include #endif #endif #include #include #include #include "radiusclient.h" #define BUF_LEN 1024 #define MSDNS 1 static char *config_file = NULL; static int add_avp(char **); static struct avpopt { char *vpstr; struct avpopt *next; } *avpopt = NULL; static bool portnummap = 0; static option_t Options[] = { { "radius-config-file", o_string, &config_file }, { "avpair", o_special, add_avp }, { "map-to-ttyname", o_bool, &portnummap, "Set Radius NAS-Port attribute value via libradiusclient library", OPT_PRIO | 1 }, { "map-to-ifname", o_bool, &portnummap, "Set Radius NAS-Port attribute to number as in interface name (Default)", OPT_PRIOSUB | 0 }, { NULL } }; static pap_check_hook_fn radius_secret_check; static pap_auth_hook_fn radius_pap_auth; static chap_verify_hook_fn radius_chap_verify; static void radius_ip_up(void *opaque, int arg); static void radius_ip_down(void *opaque, int arg); static void make_username_realm(const char *user); static int radius_setparams(VALUE_PAIR *vp, char *msg, REQUEST_INFO *req_info, struct chap_digest_type *digest, unsigned char *challenge, char *message, int message_space); static void radius_choose_ip(u_int32_t *addrp); static int radius_init(char *msg); static int get_client_port(const char *ifname); static int radius_allowed_address(u_int32_t addr); static void radius_acct_interim(void *); #ifdef PPP_WITH_MPPE static int radius_setmppekeys(VALUE_PAIR *vp, REQUEST_INFO *req_info, unsigned char *); static int radius_setmppekeys2(VALUE_PAIR *vp, REQUEST_INFO *req_info); #endif #ifndef MAXSESSIONID #define MAXSESSIONID 32 #endif #ifndef MAXCLASSLEN #define MAXCLASSLEN 500 #endif struct radius_state { int initialized; int client_port; int choose_ip; int any_ip_addr_ok; int done_chap_once; u_int32_t ip_addr; char user[MAXNAMELEN]; char config_file[MAXPATHLEN]; char session_id[MAXSESSIONID + 1]; time_t start_time; int acct_interim_interval; SERVER *authserver; /* Authentication server to use */ SERVER *acctserver; /* Accounting server to use */ int class_len; char class[MAXCLASSLEN]; VALUE_PAIR *avp; /* Additional (user supplied) vp's to send to server */ }; void (*radius_attributes_hook)(VALUE_PAIR *) = NULL; /* The pre_auth_hook MAY set authserver and acctserver if it wants. In that case, they override the values in the radiusclient.conf file */ void (*radius_pre_auth_hook)(char const *user, SERVER **authserver, SERVER **acctserver) = NULL; static struct radius_state rstate; char pppd_version[] = PPPD_VERSION; /********************************************************************** * %FUNCTION: plugin_init * %ARGUMENTS: * None * %RETURNS: * Nothing * %DESCRIPTION: * Initializes RADIUS plugin. ***********************************************************************/ void plugin_init(void) { pap_check_hook = radius_secret_check; pap_auth_hook = radius_pap_auth; chap_check_hook = radius_secret_check; chap_verify_hook = radius_chap_verify; ip_choose_hook = radius_choose_ip; allowed_address_hook = radius_allowed_address; ppp_add_notify(NF_IP_UP, radius_ip_up, NULL); ppp_add_notify(NF_IP_DOWN, radius_ip_down, NULL); memset(&rstate, 0, sizeof(rstate)); strlcpy(rstate.config_file, "/etc/radiusclient/radiusclient.conf", sizeof(rstate.config_file)); ppp_add_options(Options); info("RADIUS plugin initialized."); } /********************************************************************** * %FUNCTION: add_avp * %ARGUMENTS: * argv -- the pair to add * %RETURNS: * 1 * %DESCRIPTION: * Adds an av pair to be passed on to the RADIUS server on each request. ***********************************************************************/ static int add_avp(char **argv) { struct avpopt *p = malloc(sizeof(struct avpopt)); /* Append to a list of vp's for later parsing */ p->vpstr = strdup(*argv); p->next = avpopt; avpopt = p; return 1; } /********************************************************************** * %FUNCTION: radius_secret_check * %ARGUMENTS: * None * %RETURNS: * 1 -- we are ALWAYS willing to supply a secret. :-) * %DESCRIPTION: * Tells pppd that we will try to authenticate the peer, and not to * worry about looking in *-secrets file(s) ***********************************************************************/ static int radius_secret_check(void) { return 1; } /********************************************************************** * %FUNCTION: radius_choose_ip * %ARGUMENTS: * addrp -- where to store the IP address * %RETURNS: * Nothing * %DESCRIPTION: * If RADIUS server has specified an IP address, it is stored in *addrp. ***********************************************************************/ static void radius_choose_ip(u_int32_t *addrp) { if (rstate.choose_ip) { *addrp = rstate.ip_addr; } } /********************************************************************** * %FUNCTION: radius_pap_auth * %ARGUMENTS: * user -- user-name of peer * passwd -- password supplied by peer * msgp -- Message which will be sent in PAP response * paddrs -- set to a list of possible peer IP addresses * popts -- set to a list of additional pppd options * %RETURNS: * 1 if we can authenticate, -1 if we cannot. * %DESCRIPTION: * Performs PAP authentication using RADIUS ***********************************************************************/ static int radius_pap_auth(char *user, char *passwd, char **msgp, struct wordlist **paddrs, struct wordlist **popts) { VALUE_PAIR *send, *received; UINT4 av_type; int result; static char radius_msg[BUF_LEN]; const char *remote_number; const char *ipparam; radius_msg[0] = 0; *msgp = radius_msg; if (radius_init(radius_msg) < 0) { return 0; } /* Put user with potentially realm added in rstate.user */ make_username_realm(user); if (radius_pre_auth_hook) { radius_pre_auth_hook(rstate.user, &rstate.authserver, &rstate.acctserver); } send = NULL; received = NULL; /* Hack... the "port" is the ppp interface number. Should really be the tty */ rstate.client_port = get_client_port(portnummap ? ppp_devnam() : ppp_ifname()); av_type = PW_FRAMED; rc_avpair_add(&send, PW_SERVICE_TYPE, &av_type, 0, VENDOR_NONE); av_type = PW_PPP; rc_avpair_add(&send, PW_FRAMED_PROTOCOL, &av_type, 0, VENDOR_NONE); rc_avpair_add(&send, PW_USER_NAME, rstate.user , 0, VENDOR_NONE); rc_avpair_add(&send, PW_USER_PASSWORD, passwd, 0, VENDOR_NONE); remote_number = ppp_get_remote_number(); ipparam = ppp_ipparam(); if (remote_number) { rc_avpair_add(&send, PW_CALLING_STATION_ID, remote_number, 0, VENDOR_NONE); } else if (ipparam) rc_avpair_add(&send, PW_CALLING_STATION_ID, ipparam, 0, VENDOR_NONE); /* Add user specified vp's */ if (rstate.avp) rc_avpair_insert(&send, NULL, rc_avpair_copy(rstate.avp)); if (rstate.authserver) { result = rc_auth_using_server(rstate.authserver, rstate.client_port, send, &received, radius_msg, NULL); } else { result = rc_auth(rstate.client_port, send, &received, radius_msg, NULL); } if (result == OK_RC) { if (radius_setparams(received, radius_msg, NULL, NULL, NULL, NULL, 0) < 0) { result = ERROR_RC; } } /* free value pairs */ rc_avpair_free(received); rc_avpair_free(send); return (result == OK_RC) ? 1 : 0; } /********************************************************************** * %FUNCTION: radius_chap_verify * %ARGUMENTS: * user -- name of the peer * ourname -- name for this machine * id -- the ID byte in the challenge * digest -- points to the structure representing the digest type * challenge -- the challenge string we sent (length in first byte) * response -- the response (hash) the peer sent back (length in 1st byte) * message -- space for a message to be returned to the peer * message_space -- number of bytes available at *message. * %RETURNS: * 1 if the response is good, 0 if it is bad * %DESCRIPTION: * Performs CHAP, MS-CHAP and MS-CHAPv2 authentication using RADIUS. ***********************************************************************/ static int radius_chap_verify(char *user, char *ourname, int id, struct chap_digest_type *digest, unsigned char *challenge, unsigned char *response, char *message, int message_space) { VALUE_PAIR *send, *received; UINT4 av_type; static char radius_msg[BUF_LEN]; int result; int challenge_len, response_len; u_char cpassword[MAX_RESPONSE_LEN + 1]; #ifdef PPP_WITH_MPPE /* Need the RADIUS secret and Request Authenticator to decode MPPE */ REQUEST_INFO request_info, *req_info = &request_info; #else REQUEST_INFO *req_info = NULL; #endif const char *remote_number; const char *ipparam; challenge_len = *challenge++; response_len = *response++; radius_msg[0] = 0; if (radius_init(radius_msg) < 0) { error("%s", radius_msg); return 0; } /* return error for types we can't handle */ if ((digest->code != CHAP_MD5) #ifdef PPP_WITH_CHAPMS && (digest->code != CHAP_MICROSOFT) && (digest->code != CHAP_MICROSOFT_V2) #endif ) { error("RADIUS: Challenge type %u unsupported", digest->code); return 0; } /* Put user with potentially realm added in rstate.user */ if (!rstate.done_chap_once) { make_username_realm(user); rstate.client_port = get_client_port (portnummap ? ppp_devnam() : ppp_ifname()); if (radius_pre_auth_hook) { radius_pre_auth_hook(rstate.user, &rstate.authserver, &rstate.acctserver); } } send = received = NULL; av_type = PW_FRAMED; rc_avpair_add (&send, PW_SERVICE_TYPE, &av_type, 0, VENDOR_NONE); av_type = PW_PPP; rc_avpair_add (&send, PW_FRAMED_PROTOCOL, &av_type, 0, VENDOR_NONE); rc_avpair_add (&send, PW_USER_NAME, rstate.user , 0, VENDOR_NONE); /* * add the challenge and response fields */ switch (digest->code) { case CHAP_MD5: /* CHAP-Challenge and CHAP-Password */ if (response_len != MD5_DIGEST_LENGTH) return 0; cpassword[0] = id; memcpy(&cpassword[1], response, MD5_DIGEST_LENGTH); rc_avpair_add(&send, PW_CHAP_CHALLENGE, challenge, challenge_len, VENDOR_NONE); rc_avpair_add(&send, PW_CHAP_PASSWORD, cpassword, MD5_DIGEST_LENGTH + 1, VENDOR_NONE); break; #ifdef PPP_WITH_CHAPMS case CHAP_MICROSOFT: { /* MS-CHAP-Challenge and MS-CHAP-Response */ u_char *p = cpassword; if (response_len != MS_CHAP_RESPONSE_LEN) return 0; *p++ = id; /* The idiots use a different field order in RADIUS than PPP */ *p++ = response[MS_CHAP_USENT]; memcpy(p, response, MS_CHAP_LANMANRESP_LEN + MS_CHAP_NTRESP_LEN); rc_avpair_add(&send, PW_MS_CHAP_CHALLENGE, challenge, challenge_len, VENDOR_MICROSOFT); rc_avpair_add(&send, PW_MS_CHAP_RESPONSE, cpassword, MS_CHAP_RESPONSE_LEN + 1, VENDOR_MICROSOFT); break; } case CHAP_MICROSOFT_V2: { /* MS-CHAP-Challenge and MS-CHAP2-Response */ u_char *p = cpassword; if (response_len != MS_CHAP2_RESPONSE_LEN) return 0; *p++ = id; /* The idiots use a different field order in RADIUS than PPP */ *p++ = response[MS_CHAP2_FLAGS]; memcpy(p, response, (MS_CHAP2_PEER_CHAL_LEN + MS_CHAP2_RESERVED_LEN + MS_CHAP2_NTRESP_LEN)); rc_avpair_add(&send, PW_MS_CHAP_CHALLENGE, challenge, challenge_len, VENDOR_MICROSOFT); rc_avpair_add(&send, PW_MS_CHAP2_RESPONSE, cpassword, MS_CHAP2_RESPONSE_LEN + 1, VENDOR_MICROSOFT); break; } #endif } remote_number = ppp_get_remote_number(); ipparam = ppp_ipparam(); if (remote_number) { rc_avpair_add(&send, PW_CALLING_STATION_ID, remote_number, 0, VENDOR_NONE); } else if (ipparam) rc_avpair_add(&send, PW_CALLING_STATION_ID, ipparam, 0, VENDOR_NONE); /* Add user specified vp's */ if (rstate.avp) rc_avpair_insert(&send, NULL, rc_avpair_copy(rstate.avp)); /* * make authentication with RADIUS server */ if (rstate.authserver) { result = rc_auth_using_server(rstate.authserver, rstate.client_port, send, &received, radius_msg, req_info); } else { result = rc_auth(rstate.client_port, send, &received, radius_msg, req_info); } strlcpy(message, radius_msg, message_space); if (result == OK_RC) { if (!rstate.done_chap_once) { if (radius_setparams(received, radius_msg, req_info, digest, challenge, message, message_space) < 0) { error("%s", radius_msg); result = ERROR_RC; } else { rstate.done_chap_once = 1; } } } rc_avpair_free(received); rc_avpair_free (send); return (result == OK_RC); } /********************************************************************** * %FUNCTION: make_username_realm * %ARGUMENTS: * user -- the user given to pppd * %RETURNS: * Nothing * %DESCRIPTION: * Copies user into rstate.user. If it lacks a realm (no "@domain" part), * then the default realm from the radiusclient config file is added. ***********************************************************************/ static void make_username_realm(const char *user) { char *default_realm; if ( user != NULL ) { strlcpy(rstate.user, user, sizeof(rstate.user)); } else { rstate.user[0] = 0; } default_realm = rc_conf_str("default_realm"); if (!strchr(rstate.user, '@') && default_realm && (*default_realm != '\0')) { strlcat(rstate.user, "@", sizeof(rstate.user)); strlcat(rstate.user, default_realm, sizeof(rstate.user)); } } /********************************************************************** * %FUNCTION: radius_setparams * %ARGUMENTS: * vp -- received value-pairs * msg -- buffer in which to place error message. Holds up to BUF_LEN chars * %RETURNS: * >= 0 on success; -1 on failure * %DESCRIPTION: * Parses attributes sent by RADIUS server and sets them in pppd. ***********************************************************************/ static int radius_setparams(VALUE_PAIR *vp, char *msg, REQUEST_INFO *req_info, struct chap_digest_type *digest, unsigned char *challenge, char *message, int message_space) { u_int32_t remote; int ms_chap2_success = 0; #ifdef PPP_WITH_MPPE int mppe_enc_keys = 0; /* whether or not these were received */ int mppe_enc_policy = 0; int mppe_enc_types = 0; #endif #ifdef MSDNS ipcp_options *wo = &ipcp_wantoptions[0]; ipcp_options *ao = &ipcp_allowoptions[0]; int got_msdns_1 = 0; int got_msdns_2 = 0; int got_wins_1 = 0; int got_wins_2 = 0; #endif /* Send RADIUS attributes to anyone else who might be interested */ if (radius_attributes_hook) { (*radius_attributes_hook)(vp); } /* * service type (if not framed then quit), * new IP address (RADIUS can define static IP for some users), */ while (vp) { if (vp->vendorcode == VENDOR_NONE) { switch (vp->attribute) { case PW_SERVICE_TYPE: /* check for service type */ /* if not FRAMED then exit */ if (vp->lvalue != PW_FRAMED) { slprintf(msg, BUF_LEN, "RADIUS: wrong service type %ld for %s", vp->lvalue, rstate.user); return -1; } break; case PW_FRAMED_PROTOCOL: /* check for framed protocol type */ /* if not PPP then also exit */ if (vp->lvalue != PW_PPP) { slprintf(msg, BUF_LEN, "RADIUS: wrong framed protocol %ld for %s", vp->lvalue, rstate.user); return -1; } break; case PW_SESSION_TIMEOUT: /* Session timeout */ ppp_set_max_connect_time(vp->lvalue); break; case PW_FILTER_ID: /* packet filter, will be handled via ip-(up|down) script */ ppp_script_setenv("RADIUS_FILTER_ID", (char*) vp->strvalue, 1); break; case PW_FRAMED_ROUTE: /* route, will be handled via ip-(up|down) script */ ppp_script_setenv("RADIUS_FRAMED_ROUTE", (char*) vp->strvalue, 1); break; case PW_IDLE_TIMEOUT: /* idle parameter */ ppp_set_max_idle_time(vp->lvalue); break; case PW_SESSION_OCTETS_LIMIT: /* Session traffic limit */ ppp_set_session_limit(vp->lvalue); break; case PW_OCTETS_DIRECTION: /* Session traffic limit direction check */ ppp_set_session_limit_dir(vp->lvalue); break; case PW_ACCT_INTERIM_INTERVAL: /* Send accounting updates every few seconds */ rstate.acct_interim_interval = vp->lvalue; /* RFC says it MUST NOT be less than 60 seconds */ /* We use "0" to signify not sending updates */ if (rstate.acct_interim_interval && rstate.acct_interim_interval < 60) { rstate.acct_interim_interval = 60; } break; case PW_FRAMED_IP_ADDRESS: /* seting up remote IP addresses */ remote = vp->lvalue; if (remote == 0xffffffff) { /* 0xffffffff means user should be allowed to select one */ rstate.any_ip_addr_ok = 1; } else if (remote != 0xfffffffe) { /* 0xfffffffe means NAS should select an ip address */ remote = htonl(vp->lvalue); if (ppp_bad_ip_addr (remote)) { slprintf(msg, BUF_LEN, "RADIUS: bad remote IP address %I for %s", remote, rstate.user); return -1; } rstate.choose_ip = 1; rstate.ip_addr = remote; } break; case PW_NAS_IP_ADDRESS: wo->ouraddr = htonl(vp->lvalue); break; case PW_CLASS: /* Save Class attribute to pass it in accounting request */ // if (vp->lvalue <= MAXCLASSLEN) { // <- Attribute could be this big, but vp->strvalue is limited to AUTH_STRING_LEN characters if (vp->lvalue <= AUTH_STRING_LEN) { rstate.class_len=vp->lvalue; memcpy(rstate.class, vp->strvalue, rstate.class_len); } /* else too big for our buffer - ignore it */ break; case PW_FRAMED_MTU: ppp_set_mtu(rstate.client_port,MIN(ppp_get_mtu(rstate.client_port),vp->lvalue)); break; } } else if (vp->vendorcode == VENDOR_MICROSOFT) { #ifdef PPP_WITH_CHAPMS switch (vp->attribute) { case PW_MS_CHAP2_SUCCESS: if ((vp->lvalue != 43) || strncmp((char*) vp->strvalue + 1, "S=", 2)) { slprintf(msg,BUF_LEN,"RADIUS: bad MS-CHAP2-Success packet"); return -1; } if (message != NULL) strlcpy(message, (char*) vp->strvalue + 1, message_space); ms_chap2_success = 1; break; #ifdef PPP_WITH_MPPE case PW_MS_CHAP_MPPE_KEYS: if (radius_setmppekeys(vp, req_info, challenge) < 0) { slprintf(msg, BUF_LEN, "RADIUS: bad MS-CHAP-MPPE-Keys attribute"); return -1; } mppe_enc_keys = 1; break; case PW_MS_MPPE_SEND_KEY: case PW_MS_MPPE_RECV_KEY: if (radius_setmppekeys2(vp, req_info) < 0) { slprintf(msg, BUF_LEN, "RADIUS: bad MS-MPPE-%s-Key attribute", (vp->attribute == PW_MS_MPPE_SEND_KEY)? "Send": "Recv"); return -1; } mppe_enc_keys = 1; break; case PW_MS_MPPE_ENCRYPTION_POLICY: mppe_enc_policy = vp->lvalue; /* save for later */ break; case PW_MS_MPPE_ENCRYPTION_TYPES: mppe_enc_types = vp->lvalue; /* save for later */ break; #endif /* PPP_WITH_MPPE */ #ifdef MSDNS case PW_MS_PRIMARY_DNS_SERVER: ao->dnsaddr[0] = htonl(vp->lvalue); got_msdns_1 = 1; if (!got_msdns_2) ao->dnsaddr[1] = ao->dnsaddr[0]; break; case PW_MS_SECONDARY_DNS_SERVER: ao->dnsaddr[1] = htonl(vp->lvalue); got_msdns_2 = 1; if (!got_msdns_1) ao->dnsaddr[0] = ao->dnsaddr[1]; break; case PW_MS_PRIMARY_NBNS_SERVER: ao->winsaddr[0] = htonl(vp->lvalue); got_wins_1 = 1; if (!got_wins_2) ao->winsaddr[1] = ao->winsaddr[0]; break; case PW_MS_SECONDARY_NBNS_SERVER: ao->winsaddr[1] = htonl(vp->lvalue); got_wins_2 = 1; if (!got_wins_1) ao->winsaddr[0] = ao->winsaddr[1]; break; #endif /* MSDNS */ } #endif /* PPP_WITH_CHAPMS */ } vp = vp->next; } /* Require a valid MS-CHAP2-SUCCESS for MS-CHAPv2 auth */ if (digest && (digest->code == CHAP_MICROSOFT_V2) && !ms_chap2_success) return -1; #ifdef PPP_WITH_MPPE /* * Require both policy and key attributes to indicate a valid key. * Note that if the policy value was '0' we don't set the key! */ if (mppe_enc_policy && mppe_enc_keys) { /* Set/modify allowed encryption types. */ if (mppe_enc_types) mppe_set_enc_types(mppe_enc_policy, mppe_enc_types); return 0; } mppe_clear_keys(); #endif return 0; } #ifdef PPP_WITH_MPPE /********************************************************************** * %FUNCTION: radius_setmppekeys * %ARGUMENTS: * vp -- value pair holding MS-CHAP-MPPE-KEYS attribute * req_info -- radius request information used for encryption * %RETURNS: * >= 0 on success; -1 on failure * %DESCRIPTION: * Decrypt the "key" provided by the RADIUS server for MPPE encryption. * See RFC 2548. ***********************************************************************/ static int radius_setmppekeys(VALUE_PAIR *vp, REQUEST_INFO *req_info, unsigned char *challenge) { int i; int status = 0; PPP_MD_CTX *ctx; unsigned char plain[32]; unsigned char buf[MD5_DIGEST_LENGTH]; unsigned int buflen; if (vp->lvalue != 32) { error("RADIUS: Incorrect attribute length (%d) for MS-CHAP-MPPE-Keys", vp->lvalue); return -1; } memcpy(plain, vp->strvalue, sizeof(plain)); ctx = PPP_MD_CTX_new(); if (ctx) { if (PPP_DigestInit(ctx, PPP_md5())) { if (PPP_DigestUpdate(ctx, req_info->secret, strlen(req_info->secret))) { if (PPP_DigestUpdate(ctx, req_info->request_vector, AUTH_VECTOR_LEN)) { buflen = sizeof(buf); if (PPP_DigestFinal(ctx, buf, &buflen)) { status = 1; } } } } PPP_MD_CTX_free(ctx); } if (status) { for (i = 0; i < MD5_DIGEST_LENGTH; i++) { plain[i] ^= buf[i]; } status = 0; ctx = PPP_MD_CTX_new(); if (ctx) { if (PPP_DigestInit(ctx, PPP_md5())) { if (PPP_DigestUpdate(ctx, req_info->secret, strlen(req_info->secret))) { if (PPP_DigestUpdate(ctx, vp->strvalue, 16)) { buflen = MD5_DIGEST_LENGTH; if (PPP_DigestFinal(ctx, buf, &buflen)) { status = 1; } } } } PPP_MD_CTX_free(ctx); } if (status) { for(i = 0; i < MD5_DIGEST_LENGTH; i++) { plain[i + 16] ^= buf[i]; } /* * Annoying. The "key" returned is just the NTPasswordHashHash, which * the NAS (us) doesn't need; we only need the start key. So we have * to generate the start key, sigh. NB: We do not support the LM-Key. */ mppe_set_chapv1(challenge, &plain[8]); return 0; } } return -1; } /********************************************************************** * %FUNCTION: radius_setmppekeys2 * %ARGUMENTS: * vp -- value pair holding MS-MPPE-SEND-KEY or MS-MPPE-RECV-KEY attribute * req_info -- radius request information used for encryption * %RETURNS: * >= 0 on success; -1 on failure * %DESCRIPTION: * Decrypt the key provided by the RADIUS server for MPPE encryption. * See RFC 2548. ***********************************************************************/ static int radius_setmppekeys2(VALUE_PAIR *vp, REQUEST_INFO *req_info) { int i; int status = 0; PPP_MD_CTX *ctx; unsigned char *salt = vp->strvalue; unsigned char *crypt = vp->strvalue + 2; unsigned char plain[32]; unsigned char buf[MD5_DIGEST_LENGTH]; unsigned int buflen; char *type = "Send"; if (vp->attribute == PW_MS_MPPE_RECV_KEY) type = "Recv"; if (vp->lvalue != 34) { error("RADIUS: Incorrect attribute length (%d) for MS-MPPE-%s-Key", vp->lvalue, type); return -1; } if ((salt[0] & 0x80) == 0) { error("RADIUS: Illegal salt value for MS-MPPE-%s-Key attribute", type); return -1; } memcpy(plain, crypt, 32); ctx = PPP_MD_CTX_new(); if (ctx) { if (PPP_DigestInit(ctx, PPP_md5())) { if (PPP_DigestUpdate(ctx, req_info->secret, strlen(req_info->secret))) { if (PPP_DigestUpdate(ctx, req_info->request_vector, AUTH_VECTOR_LEN)) { if (PPP_DigestUpdate(ctx, salt, 2)) { buflen = sizeof(buf); if (PPP_DigestFinal(ctx, buf, &buflen)) { status = 1; } } } } } PPP_MD_CTX_free(ctx); } if (status) { for (i = 0; i < 16; i++) { plain[i] ^= buf[i]; } if (plain[0] != 16) { error("RADIUS: Incorrect key length (%d) for MS-MPPE-%s-Key attribute", (int) plain[0], type); return -1; } status = 0; ctx = PPP_MD_CTX_new(); if (ctx) { if (PPP_DigestInit(ctx, PPP_md5())) { if (PPP_DigestUpdate(ctx, req_info->secret, strlen(req_info->secret))) { if (PPP_DigestUpdate(ctx, crypt, 16)) { if (PPP_DigestUpdate(ctx, salt, 2)) { buflen = sizeof(buf); if (PPP_DigestFinal(ctx, buf, &buflen)) { status = 1; } } } } } PPP_MD_CTX_free(ctx); } if (status) { plain[16] ^= buf[0]; /* only need the first byte */ if (vp->attribute == PW_MS_MPPE_SEND_KEY) { mppe_set_keys(plain + 1, NULL, 16); } else { mppe_set_keys(NULL, plain + 1, 16); } return 0; } } return -1; } #endif /* PPP_WITH_MPPE */ /********************************************************************** * %FUNCTION: radius_acct_start * %ARGUMENTS: * None * %RETURNS: * Nothing * %DESCRIPTION: * Sends a "start" accounting message to the RADIUS server. ***********************************************************************/ static void radius_acct_start(void) { UINT4 av_type; int result; VALUE_PAIR *send = NULL; ipcp_options *ho = &ipcp_hisoptions[0]; u_int32_t hisaddr; const char *remote_number; const char *ipparam; if (!rstate.initialized) { return; } rstate.start_time = time(NULL); strlcpy(rstate.session_id, rc_mksid(), MAXSESSIONID); rc_avpair_add(&send, PW_ACCT_SESSION_ID, rstate.session_id, 0, VENDOR_NONE); rc_avpair_add(&send, PW_USER_NAME, rstate.user, 0, VENDOR_NONE); if (rstate.class_len > 0) rc_avpair_add(&send, PW_CLASS, rstate.class, rstate.class_len, VENDOR_NONE); av_type = PW_STATUS_START; rc_avpair_add(&send, PW_ACCT_STATUS_TYPE, &av_type, 0, VENDOR_NONE); av_type = PW_FRAMED; rc_avpair_add(&send, PW_SERVICE_TYPE, &av_type, 0, VENDOR_NONE); av_type = PW_PPP; rc_avpair_add(&send, PW_FRAMED_PROTOCOL, &av_type, 0, VENDOR_NONE); remote_number = ppp_get_remote_number(); ipparam = ppp_ipparam(); if (remote_number) { rc_avpair_add(&send, PW_CALLING_STATION_ID, remote_number, 0, VENDOR_NONE); } else if (ipparam) rc_avpair_add(&send, PW_CALLING_STATION_ID, ipparam, 0, VENDOR_NONE); av_type = PW_RADIUS; rc_avpair_add(&send, PW_ACCT_AUTHENTIC, &av_type, 0, VENDOR_NONE); av_type = ( ppp_using_pty() ? PW_VIRTUAL : ( ppp_sync_serial() ? PW_SYNC : PW_ASYNC ) ); rc_avpair_add(&send, PW_NAS_PORT_TYPE, &av_type, 0, VENDOR_NONE); hisaddr = ho->hisaddr; av_type = htonl(hisaddr); rc_avpair_add(&send, PW_FRAMED_IP_ADDRESS , &av_type , 0, VENDOR_NONE); /* Add user specified vp's */ if (rstate.avp) rc_avpair_insert(&send, NULL, rc_avpair_copy(rstate.avp)); if (rstate.acctserver) { result = rc_acct_using_server(rstate.acctserver, rstate.client_port, send); } else { result = rc_acct(rstate.client_port, send); } rc_avpair_free(send); if (result != OK_RC) { /* RADIUS server could be down so make this a warning */ syslog(LOG_WARNING, "Accounting START failed for %s", rstate.user); } /* Kick off periodic accounting reports */ if (rstate.acct_interim_interval) { ppp_timeout(radius_acct_interim, NULL, rstate.acct_interim_interval, 0); } } /********************************************************************** * %FUNCTION: radius_acct_stop * %ARGUMENTS: * None * %RETURNS: * Nothing * %DESCRIPTION: * Sends a "stop" accounting message to the RADIUS server. ***********************************************************************/ static void radius_acct_stop(void) { UINT4 av_type; VALUE_PAIR *send = NULL; ipcp_options *ho = &ipcp_hisoptions[0]; u_int32_t hisaddr; int result; const char *remote_number; const char *ipparam; ppp_link_stats_st stats; if (!rstate.initialized) { return; } if (rstate.acct_interim_interval) ppp_untimeout(radius_acct_interim, NULL); rc_avpair_add(&send, PW_ACCT_SESSION_ID, rstate.session_id, 0, VENDOR_NONE); rc_avpair_add(&send, PW_USER_NAME, rstate.user, 0, VENDOR_NONE); if (rstate.class_len > 0) rc_avpair_add(&send, PW_CLASS, rstate.class, rstate.class_len, VENDOR_NONE); av_type = PW_STATUS_STOP; rc_avpair_add(&send, PW_ACCT_STATUS_TYPE, &av_type, 0, VENDOR_NONE); av_type = PW_FRAMED; rc_avpair_add(&send, PW_SERVICE_TYPE, &av_type, 0, VENDOR_NONE); av_type = PW_PPP; rc_avpair_add(&send, PW_FRAMED_PROTOCOL, &av_type, 0, VENDOR_NONE); av_type = PW_RADIUS; rc_avpair_add(&send, PW_ACCT_AUTHENTIC, &av_type, 0, VENDOR_NONE); if (ppp_get_link_stats(&stats)) { av_type = ppp_get_link_uptime(); rc_avpair_add(&send, PW_ACCT_SESSION_TIME, &av_type, 0, VENDOR_NONE); av_type = stats.bytes_out & 0xFFFFFFFF; rc_avpair_add(&send, PW_ACCT_OUTPUT_OCTETS, &av_type, 0, VENDOR_NONE); if (stats.bytes_out > 0xFFFFFFFF) { av_type = stats.bytes_out >> 32; rc_avpair_add(&send, PW_ACCT_OUTPUT_GIGAWORDS, &av_type, 0, VENDOR_NONE); } av_type = stats.bytes_in & 0xFFFFFFFF; rc_avpair_add(&send, PW_ACCT_INPUT_OCTETS, &av_type, 0, VENDOR_NONE); if (stats.bytes_in > 0xFFFFFFFF) { av_type = stats.bytes_in >> 32; rc_avpair_add(&send, PW_ACCT_INPUT_GIGAWORDS, &av_type, 0, VENDOR_NONE); } av_type = stats.pkts_out; rc_avpair_add(&send, PW_ACCT_OUTPUT_PACKETS, &av_type, 0, VENDOR_NONE); av_type = stats.pkts_in; rc_avpair_add(&send, PW_ACCT_INPUT_PACKETS, &av_type, 0, VENDOR_NONE); } remote_number = ppp_get_remote_number(); ipparam = ppp_ipparam(); if (remote_number) { rc_avpair_add(&send, PW_CALLING_STATION_ID, remote_number, 0, VENDOR_NONE); } else if (ipparam) rc_avpair_add(&send, PW_CALLING_STATION_ID, ipparam, 0, VENDOR_NONE); av_type = ( ppp_using_pty() ? PW_VIRTUAL : ( ppp_sync_serial() ? PW_SYNC : PW_ASYNC ) ); rc_avpair_add(&send, PW_NAS_PORT_TYPE, &av_type, 0, VENDOR_NONE); av_type = PW_NAS_ERROR; switch( ppp_status() ) { case EXIT_OK: av_type = PW_USER_REQUEST; break; case EXIT_USER_REQUEST: av_type = PW_ADMIN_RESET; break; case EXIT_HANGUP: case EXIT_PEER_DEAD: case EXIT_CONNECT_FAILED: av_type = PW_LOST_CARRIER; break; case EXIT_INIT_FAILED: case EXIT_OPEN_FAILED: case EXIT_LOCK_FAILED: case EXIT_PTYCMD_FAILED: av_type = PW_PORT_ERROR; break; case EXIT_PEER_AUTH_FAILED: case EXIT_AUTH_TOPEER_FAILED: case EXIT_NEGOTIATION_FAILED: case EXIT_CNID_AUTH_FAILED: av_type = PW_SERVICE_UNAVAILABLE; break; case EXIT_IDLE_TIMEOUT: av_type = PW_ACCT_IDLE_TIMEOUT; break; case EXIT_CALLBACK: av_type = PW_CALLBACK; break; case EXIT_CONNECT_TIME: av_type = PW_ACCT_SESSION_TIMEOUT; break; case EXIT_TRAFFIC_LIMIT: av_type = PW_NAS_REQUEST; break; default: av_type = PW_NAS_ERROR; break; } rc_avpair_add(&send, PW_ACCT_TERMINATE_CAUSE, &av_type, 0, VENDOR_NONE); hisaddr = ho->hisaddr; av_type = htonl(hisaddr); rc_avpair_add(&send, PW_FRAMED_IP_ADDRESS , &av_type , 0, VENDOR_NONE); /* Add user specified vp's */ if (rstate.avp) rc_avpair_insert(&send, NULL, rc_avpair_copy(rstate.avp)); if (rstate.acctserver) { result = rc_acct_using_server(rstate.acctserver, rstate.client_port, send); } else { result = rc_acct(rstate.client_port, send); } if (result != OK_RC) { /* RADIUS server could be down so make this a warning */ syslog(LOG_WARNING, "Accounting STOP failed for %s", rstate.user); } rc_avpair_free(send); } /********************************************************************** * %FUNCTION: radius_acct_interim * %ARGUMENTS: * None * %RETURNS: * Nothing * %DESCRIPTION: * Sends an interim accounting message to the RADIUS server ***********************************************************************/ static void radius_acct_interim(void *ignored) { UINT4 av_type; VALUE_PAIR *send = NULL; ipcp_options *ho = &ipcp_hisoptions[0]; u_int32_t hisaddr; int result; const char *remote_number; const char *ipparam; ppp_link_stats_st stats; if (!rstate.initialized) { return; } rc_avpair_add(&send, PW_ACCT_SESSION_ID, rstate.session_id, 0, VENDOR_NONE); rc_avpair_add(&send, PW_USER_NAME, rstate.user, 0, VENDOR_NONE); if (rstate.class_len > 0) rc_avpair_add(&send, PW_CLASS, rstate.class, rstate.class_len, VENDOR_NONE); av_type = PW_STATUS_ALIVE; rc_avpair_add(&send, PW_ACCT_STATUS_TYPE, &av_type, 0, VENDOR_NONE); av_type = PW_FRAMED; rc_avpair_add(&send, PW_SERVICE_TYPE, &av_type, 0, VENDOR_NONE); av_type = PW_PPP; rc_avpair_add(&send, PW_FRAMED_PROTOCOL, &av_type, 0, VENDOR_NONE); av_type = PW_RADIUS; rc_avpair_add(&send, PW_ACCT_AUTHENTIC, &av_type, 0, VENDOR_NONE); if (ppp_get_link_stats(&stats)) { av_type = ppp_get_link_uptime(); rc_avpair_add(&send, PW_ACCT_SESSION_TIME, &av_type, 0, VENDOR_NONE); av_type = stats.bytes_out & 0xFFFFFFFF; rc_avpair_add(&send, PW_ACCT_OUTPUT_OCTETS, &av_type, 0, VENDOR_NONE); if (stats.bytes_out > 0xFFFFFFFF) { av_type = stats.bytes_out >> 32; rc_avpair_add(&send, PW_ACCT_OUTPUT_GIGAWORDS, &av_type, 0, VENDOR_NONE); } av_type = stats.bytes_in & 0xFFFFFFFF; rc_avpair_add(&send, PW_ACCT_INPUT_OCTETS, &av_type, 0, VENDOR_NONE); if (stats.bytes_in > 0xFFFFFFFF) { av_type = stats.bytes_in >> 32; rc_avpair_add(&send, PW_ACCT_INPUT_GIGAWORDS, &av_type, 0, VENDOR_NONE); } av_type = stats.pkts_out; rc_avpair_add(&send, PW_ACCT_OUTPUT_PACKETS, &av_type, 0, VENDOR_NONE); av_type = stats.pkts_in; rc_avpair_add(&send, PW_ACCT_INPUT_PACKETS, &av_type, 0, VENDOR_NONE); } remote_number = ppp_get_remote_number(); ipparam = ppp_ipparam(); if (remote_number) { rc_avpair_add(&send, PW_CALLING_STATION_ID, remote_number, 0, VENDOR_NONE); } else if (ipparam) rc_avpair_add(&send, PW_CALLING_STATION_ID, ipparam, 0, VENDOR_NONE); av_type = ( ppp_using_pty() ? PW_VIRTUAL : ( ppp_sync_serial() ? PW_SYNC : PW_ASYNC ) ); rc_avpair_add(&send, PW_NAS_PORT_TYPE, &av_type, 0, VENDOR_NONE); hisaddr = ho->hisaddr; av_type = htonl(hisaddr); rc_avpair_add(&send, PW_FRAMED_IP_ADDRESS , &av_type , 0, VENDOR_NONE); /* Add user specified vp's */ if (rstate.avp) rc_avpair_insert(&send, NULL, rc_avpair_copy(rstate.avp)); if (rstate.acctserver) { result = rc_acct_using_server(rstate.acctserver, rstate.client_port, send); } else { result = rc_acct(rstate.client_port, send); } if (result != OK_RC) { /* RADIUS server could be down so make this a warning */ syslog(LOG_WARNING, "Interim accounting failed for %s", rstate.user); } rc_avpair_free(send); /* Schedule another one */ ppp_timeout(radius_acct_interim, NULL, rstate.acct_interim_interval, 0); } /********************************************************************** * %FUNCTION: radius_ip_up * %ARGUMENTS: * opaque -- ignored * arg -- ignored * %RETURNS: * Nothing * %DESCRIPTION: * Called when IPCP is up. We'll do a start-accounting record. ***********************************************************************/ static void radius_ip_up(void *opaque, int arg) { radius_acct_start(); } /********************************************************************** * %FUNCTION: radius_ip_down * %ARGUMENTS: * opaque -- ignored * arg -- ignored * %RETURNS: * Nothing * %DESCRIPTION: * Called when IPCP is down. We'll do a stop-accounting record. ***********************************************************************/ static void radius_ip_down(void *opaque, int arg) { radius_acct_stop(); } /********************************************************************** * %FUNCTION: radius_init * %ARGUMENTS: * msg -- buffer of size BUF_LEN for error message * %RETURNS: * negative on failure; non-negative on success * %DESCRIPTION: * Initializes radiusclient library ***********************************************************************/ static int radius_init(char *msg) { if (rstate.initialized) { return 0; } if (config_file && *config_file) { strlcpy(rstate.config_file, config_file, MAXPATHLEN-1); } rstate.initialized = 1; if (rc_read_config(rstate.config_file) != 0) { slprintf(msg, BUF_LEN, "RADIUS: Can't read config file %s", rstate.config_file); return -1; } if (rc_read_dictionary(rc_conf_str("dictionary")) != 0) { slprintf(msg, BUF_LEN, "RADIUS: Can't read dictionary file %s", rc_conf_str("dictionary")); return -1; } if (rc_read_mapfile(rc_conf_str("mapfile")) != 0) { slprintf(msg, BUF_LEN, "RADIUS: Can't read map file %s", rc_conf_str("mapfile")); return -1; } /* Add av pairs saved during option parsing */ while (avpopt) { struct avpopt *n = avpopt->next; rc_avpair_parse(avpopt->vpstr, &rstate.avp); free(avpopt->vpstr); free(avpopt); avpopt = n; } return 0; } /********************************************************************** * %FUNCTION: get_client_port * %ARGUMENTS: * ifname -- PPP interface name (e.g. "ppp7") * %RETURNS: * The NAS port number (e.g. 7) * %DESCRIPTION: * Extracts the port number from the interface name ***********************************************************************/ static int get_client_port(const char *ifname) { int port; if (sscanf(ifname, "ppp%d", &port) == 1) { return port; } return rc_map2id(ifname); } /********************************************************************** * %FUNCTION: radius_allowed_address * %ARGUMENTS: * addr -- IP address * %RETURNS: * 1 if we're allowed to use that IP address; 0 if not; -1 if we do * not know. ***********************************************************************/ static int radius_allowed_address(u_int32_t addr) { ipcp_options *wo = &ipcp_wantoptions[0]; if (!rstate.choose_ip) { /* If RADIUS server said any address is OK, then fine... */ if (rstate.any_ip_addr_ok) { return 1; } /* Sigh... if an address was supplied for remote host in pppd options, it has to match that. */ if (wo->hisaddr != 0 && wo->hisaddr == addr) { return 1; } return 0; } if (addr == rstate.ip_addr) return 1; return 0; } /* Useful for other plugins */ char *radius_logged_in_user(void) { return rstate.user; } ppp-2.5.0/pppd/plugins/radius/radrealms.c0000644000175000017500000000731214407475306015304 00000000000000/* * * radrealms.c * * A pppd plugin which is stacked on top of radius.so. This plugin * allows selection of alternate set of servers based on the user's realm. * * Author: Ben McKeegan ben@netservers.co.uk * * Copyright (C) 2002 Netservers * * This plugin may be distributed according to the terms of the GNU * General Public License, version 2 or (at your option) any later version. * */ static char const RCSID[] = "$Id: radrealms.c,v 1.2 2004/11/14 07:26:26 paulus Exp $"; #include #include #include #include #include #include #include #include #include #include "radiusclient.h" char pppd_version[] = PPPD_VERSION; char radrealms_config[MAXPATHLEN] = "/etc/radiusclient/realms"; static option_t Options[] = { { "realms-config-file", o_string, &radrealms_config, "Configuration file for RADIUS realms", OPT_STATIC, NULL, MAXPATHLEN }, { NULL } }; extern void (*radius_pre_auth_hook)(char const *user, SERVER **authserver, SERVER **acctserver); static void lookup_realm(char const *user, SERVER **authserver, SERVER **acctserver) { char *realm; FILE *fd; SERVER *accts, *auths, *s; char buffer[512], *p; int line = 0; auths = (SERVER *) malloc(sizeof(SERVER)); auths->max = 0; accts = (SERVER *) malloc(sizeof(SERVER)); accts->max = 0; realm = strrchr(user, '@'); if (realm) { info("Looking up servers for realm '%s'", realm); } else { info("Looking up servers for DEFAULT realm"); } if (realm) { if (*(++realm) == '\0') { realm = NULL; } } if ((fd = fopen(radrealms_config, "r")) == NULL) { ppp_option_error("cannot open %s", radrealms_config); free(auths); free(accts); return; } info("Reading %s", radrealms_config); while ((fgets(buffer, sizeof(buffer), fd) != NULL)) { line++; if ((*buffer == '\n') || (*buffer == '#') || (*buffer == '\0')) continue; buffer[strlen(buffer)-1] = '\0'; p = strtok(buffer, "\t "); if (p == NULL || (strcmp(p, "authserver") !=0 && strcmp(p, "acctserver"))) { fclose(fd); ppp_option_error("%s: invalid line %d: %s", radrealms_config, line, buffer); free(auths); free(accts); return; } info("Parsing '%s' entry:", p); s = auths; if (p[1] == 'c') { s = accts; } if (s->max >= SERVER_MAX) continue; if ((p = strtok(NULL, "\t ")) == NULL) { fclose(fd); ppp_option_error("%s: realm name missing on line %d: %s", radrealms_config, line, buffer); free(auths); free(accts); return; } if ((realm != NULL && strcmp(p, realm) == 0) || (realm == NULL && strcmp(p, "DEFAULT") == 0) ) { info(" - Matched realm %s", p); if ((p = strtok(NULL, ":")) == NULL) { fclose(fd); ppp_option_error("%s: server address missing on line %d: %s", radrealms_config, line, buffer); free(auths); free(accts); return; } s->name[s->max] = strdup(p); info(" - Address is '%s'",p); if ((p = strtok(NULL, "\t ")) == NULL) { fclose(fd); ppp_option_error("%s: server port missing on line %d: %s", radrealms_config, line, buffer); free(auths); free(accts); return; } s->port[s->max] = atoi(p); info(" - Port is '%d'", s->port[s->max]); s->max++; } else info(" - Skipping realm '%s'", p); } fclose(fd); if (accts->max) *acctserver = accts; else free(accts); if (auths->max) *authserver = auths; else free(auths); return; } void plugin_init(void) { radius_pre_auth_hook = lookup_realm; ppp_add_options(Options); info("RADIUS Realms plugin initialized."); } ppp-2.5.0/pppd/plugins/radius/COPYRIGHT0000644000175000017500000001127511043063522014446 00000000000000See the respective source files to find out which copyrights apply. ------------------------------------------------------------------------------ Copyright (C) 2002 Roaring Penguin Software Inc. Permission to use, copy, modify, and distribute this software for any purpose and without fee is hereby granted, provided that this copyright and permission notice appear on all copies and supporting documentation, the name of Roaring Penguin Software Inc. not be used in advertising or publicity pertaining to distribution of the program without specific prior permission, and notice be given in supporting documentation that copying and distribution is by permission of Roaring Penguin Software Inc.. Roaring Penguin Software Inc. makes no representations about the suitability of this software for any purpose. It is provided "as is" without express or implied warranty. ------------------------------------------------------------------------------ Copyright (C) 1995,1996,1997,1998 Lars Fenneberg Permission to use, copy, modify, and distribute this software for any purpose and without fee is hereby granted, provided that this copyright and permission notice appear on all copies and supporting documentation, the name of Lars Fenneberg not be used in advertising or publicity pertaining to distribution of the program without specific prior permission, and notice be given in supporting documentation that copying and distribution is by permission of Lars Fenneberg. Lars Fenneberg makes no representations about the suitability of this software for any purpose. It is provided "as is" without express or implied warranty. ------------------------------------------------------------------------------ Copyright 1992 Livingston Enterprises, Inc. Livingston Enterprises, Inc. 6920 Koll Center Parkway Pleasanton, CA 94566 Permission to use, copy, modify, and distribute this software for any purpose and without fee is hereby granted, provided that this copyright and permission notice appear on all copies and supporting documentation, the name of Livingston Enterprises, Inc. not be used in advertising or publicity pertaining to distribution of the program without specific prior permission, and notice be given in supporting documentation that copying and distribution is by permission of Livingston Enterprises, Inc. Livingston Enterprises, Inc. makes no representations about the suitability of this software for any purpose. It is provided "as is" without express or implied warranty. ------------------------------------------------------------------------------ [C] The Regents of the University of Michigan and Merit Network, Inc. 1992, 1993, 1994, 1995 All Rights Reserved Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies of the software and derivative works or modified versions thereof, and that both the copyright notice and this permission and disclaimer notice appear in supporting documentation. THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE REGENTS OF THE UNIVERSITY OF MICHIGAN AND MERIT NETWORK, INC. DO NOT WARRANT THAT THE FUNCTIONS CONTAINED IN THE SOFTWARE WILL MEET LICENSEE'S REQUIREMENTS OR THAT OPERATION WILL BE UNINTERRUPTED OR ERROR FREE. The Regents of the University of Michigan and Merit Network, Inc. shall not be liable for any special, indirect, incidental or consequential damages with respect to any claim by Licensee or any third party arising from use of the software. ------------------------------------------------------------------------------ Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All rights reserved. License to copy and use this software is granted provided that it is identified as the "RSA Data Security, Inc. MD5 Message-Digest Algorithm" in all material mentioning or referencing this software or this function. License is also granted to make and use derivative works provided that such works are identified as "derived from the RSA Data Security, Inc. MD5 Message-Digest Algorithm" in all material mentioning or referencing the derived work. RSA Data Security, Inc. makes no representations concerning either the merchantability of this software or the suitability of this software for any particular purpose. It is provided "as is" without express or implied warranty of any kind. These notices must be retained in any copies of any part of this documentation and/or software. ------------------------------------------------------------------------------ ppp-2.5.0/test-driver0000755000175000017500000001141714072725711011446 00000000000000#! /bin/sh # test-driver - basic testsuite driver script. scriptversion=2018-03-07.03; # UTC # Copyright (C) 2011-2021 Free Software Foundation, Inc. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # This file is maintained in Automake, please report # bugs to or send patches to # . # Make unconditional expansion of undefined variables an error. This # helps a lot in preventing typo-related bugs. set -u usage_error () { echo "$0: $*" >&2 print_usage >&2 exit 2 } print_usage () { cat <"$log_file" "$@" >>"$log_file" 2>&1 estatus=$? if test $enable_hard_errors = no && test $estatus -eq 99; then tweaked_estatus=1 else tweaked_estatus=$estatus fi case $tweaked_estatus:$expect_failure in 0:yes) col=$red res=XPASS recheck=yes gcopy=yes;; 0:*) col=$grn res=PASS recheck=no gcopy=no;; 77:*) col=$blu res=SKIP recheck=no gcopy=yes;; 99:*) col=$mgn res=ERROR recheck=yes gcopy=yes;; *:yes) col=$lgn res=XFAIL recheck=no gcopy=yes;; *:*) col=$red res=FAIL recheck=yes gcopy=yes;; esac # Report the test outcome and exit status in the logs, so that one can # know whether the test passed or failed simply by looking at the '.log' # file, without the need of also peaking into the corresponding '.trs' # file (automake bug#11814). echo "$res $test_name (exit status: $estatus)" >>"$log_file" # Report outcome to console. echo "${col}${res}${std}: $test_name" # Register the test result, and other relevant metadata. echo ":test-result: $res" > $trs_file echo ":global-test-result: $res" >> $trs_file echo ":recheck: $recheck" >> $trs_file echo ":copy-in-global-log: $gcopy" >> $trs_file # Local Variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC0" # time-stamp-end: "; # UTC" # End: ppp-2.5.0/pppstats/0000755000175000017500000000000014412736275011207 500000000000000ppp-2.5.0/pppstats/Makefile.am0000664000175000017500000000025114273050614013152 00000000000000sbin_PROGRAMS = pppstats dist_man8_MANS = pppstats.8 pppstats_SOURCES = pppstats.c pppstats_CFLAGS = pppstats_CPPFLAGS = if SUNOS pppstats_CPPFLAGS += -DSTREAMS endif ppp-2.5.0/pppstats/pppstats.80000664000175000017500000001272413676022562013104 00000000000000.\" @(#) $Id: pppstats.8,v 1.4 2004/11/13 12:22:49 paulus Exp $ .TH PPPSTATS 8 "26 June 1995" .SH NAME pppstats \- print PPP statistics .SH SYNOPSIS .B pppstats [ .B \-a ] [ .B \-d ] [ .B \-v ] [ .B \-r ] [ .B \-z ] [ .B \-c .I ] [ .B \-w .I ] [ .I interface ] .ti 12 .SH DESCRIPTION The .B pppstats utility reports PPP\-related statistics at regular intervals for the specified PPP interface. If the interface is unspecified, it will default to ppp0. The display is split horizontally into input and output sections containing columns of statistics describing the properties and volume of packets received and transmitted by the interface. .PP The options are as follows: .TP .B \-a Display absolute values rather than deltas. With this option, all reports show statistics for the time since the link was initiated. Without this option, the second and subsequent reports show statistics for the time since the last report. .TP .B \-d Show data rate (kB/s) instead of bytes. .TP .B \-c \fIcount Repeat the display .I count times. If this option is not specified, the default repeat count is 1 if the .B \-w option is not specified, otherwise infinity. .TP .B \-r Display additional statistics summarizing the compression ratio achieved by the packet compression algorithm in use. .TP .B \-v Display additional statistics relating to the performance of the Van Jacobson TCP header compression algorithm. .TP .B \-w \fIwait Pause .I wait seconds between each display. If this option is not specified, the default interval is 5 seconds. .TP .B \-z Instead of the standard display, show statistics indicating the performance of the packet compression algorithm in use. .PP The following fields are printed on the input side when the .B \-z option is not used: .TP .B IN The total number of bytes received by this interface. .TP .B PACK The total number of packets received by this interface. .TP .B VJCOMP The number of header-compressed TCP packets received by this interface. .TP .B VJUNC The number of header-uncompressed TCP packets received by this interface. Not reported when the .B \-r option is specified. .TP .B VJERR The number of corrupted or bogus header-compressed TCP packets received by this interface. Not reported when the .B \-r option is specified. .TP .B VJTOSS The number of VJ header-compressed TCP packets dropped on reception by this interface because of preceding errors. Only reported when the .B \-v option is specified. .TP .B NON-VJ The total number of non-TCP packets received by this interface. Only reported when the .B \-v option is specified. .TP .B RATIO The compression ratio achieved for received packets by the packet compression scheme in use, defined as the uncompressed size divided by the compressed size. Only reported when the .B \-r option is specified. .TP .B UBYTE The total number of bytes received, after decompression of compressed packets. Only reported when the .B \-r option is specified. .PP The following fields are printed on the output side: .TP .B OUT The total number of bytes transmitted from this interface. .TP .B PACK The total number of packets transmitted from this interface. .TP .B VJCOMP The number of TCP packets transmitted from this interface with VJ-compressed TCP headers. .TP .B VJUNC The number of TCP packets transmitted from this interface with VJ-uncompressed TCP headers. Not reported when the .B \-r option is specified. .TP .B NON-VJ The total number of non-TCP packets transmitted from this interface. Not reported when the .B \-r option is specified. .TP .B VJSRCH The number of searches for the cached header entry for a VJ header compressed TCP packet. Only reported when the .B \-v option is specified. .TP .B VJMISS The number of failed searches for the cached header entry for a VJ header compressed TCP packet. Only reported when the .B \-v option is specified. .TP .B RATIO The compression ratio achieved for transmitted packets by the packet compression scheme in use, defined as the size before compression divided by the compressed size. Only reported when the .B \-r option is specified. .TP .B UBYTE The total number of bytes to be transmitted, before packet compression is applied. Only reported when the .B \-r option is specified. .PP When the .B \-z option is specified, .B pppstats instead displays the following fields, relating to the packet compression algorithm currently in use. If packet compression is not in use, these fields will all display zeroes. The fields displayed on the input side are: .TP .B COMPRESSED BYTE The number of bytes of compressed packets received. .TP .B COMPRESSED PACK The number of compressed packets received. .TP .B INCOMPRESSIBLE BYTE The number of bytes of incompressible packets (that is, those which were transmitted in uncompressed form) received. .TP .B INCOMPRESSIBLE PACK The number of incompressible packets received. .TP .B COMP RATIO The recent compression ratio for incoming packets, defined as the uncompressed size divided by the compressed size (including both compressible and incompressible packets). .PP The fields displayed on the output side are: .TP .B COMPRESSED BYTE The number of bytes of compressed packets transmitted. .TP .B COMPRESSED PACK The number of compressed packets transmitted. .TP .B INCOMPRESSIBLE BYTE The number of bytes of incompressible packets transmitted (that is, those which were transmitted in uncompressed form). .TP .B INCOMPRESSIBLE PACK The number of incompressible packets transmitted. .TP .B COMP RATIO The recent compression ratio for outgoing packets. .SH SEE ALSO pppd(8) ppp-2.5.0/pppstats/Makefile.in0000644000175000017500000006302114407475314013174 00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ sbin_PROGRAMS = pppstats$(EXEEXT) @SUNOS_TRUE@am__append_1 = -DSTREAMS subdir = pppstats ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_atm.m4 \ $(top_srcdir)/m4/ax_check_openssl.m4 \ $(top_srcdir)/m4/ax_check_openssl_func.m4 \ $(top_srcdir)/m4/ax_check_pam.m4 \ $(top_srcdir)/m4/ax_check_pcap.m4 \ $(top_srcdir)/m4/ax_check_srp.m4 $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/pkg.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/pppd/config.h \ $(top_builddir)/pppd/pppdconf.h \ $(top_builddir)/pppd/plugins/pppoe/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__installdirs = "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(man8dir)" PROGRAMS = $(sbin_PROGRAMS) am_pppstats_OBJECTS = pppstats-pppstats.$(OBJEXT) pppstats_OBJECTS = $(am_pppstats_OBJECTS) pppstats_LDADD = $(LDADD) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = pppstats_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(pppstats_CFLAGS) \ $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/pppd -I$(top_builddir)/pppd/plugins/pppoe depcomp = $(SHELL) $(top_srcdir)/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/pppstats-pppstats.Po am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(pppstats_SOURCES) DIST_SOURCES = $(pppstats_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } man8dir = $(mandir)/man8 NROFF = nroff MANS = $(dist_man8_MANS) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(dist_man8_MANS) $(srcdir)/Makefile.in \ $(top_srcdir)/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ ATM_CFLAGS = @ATM_CFLAGS@ ATM_LDFLAGS = @ATM_LDFLAGS@ ATM_LIBS = @ATM_LIBS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CRYPT_LIBS = @CRYPT_LIBS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GREP = @GREP@ GTK_CFLAGS = @GTK_CFLAGS@ GTK_LIBS = @GTK_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_INCLUDES = @OPENSSL_INCLUDES@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAM_CFLAGS = @PAM_CFLAGS@ PAM_LDFLAGS = @PAM_LDFLAGS@ PAM_LIBS = @PAM_LIBS@ PATH_SEPARATOR = @PATH_SEPARATOR@ PCAP_CFLAGS = @PCAP_CFLAGS@ PCAP_LDFLAGS = @PCAP_LDFLAGS@ PCAP_LIBS = @PCAP_LIBS@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PPPD_LOGFILE_DIR = @PPPD_LOGFILE_DIR@ PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@ PPPD_RUNTIME_DIR = @PPPD_RUNTIME_DIR@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SRP_CFLAGS = @SRP_CFLAGS@ SRP_LDFLAGS = @SRP_LDFLAGS@ SRP_LIBS = @SRP_LIBS@ STRIP = @STRIP@ SYSTEMD_CFLAGS = @SYSTEMD_CFLAGS@ SYSTEMD_LIBS = @SYSTEMD_LIBS@ SYSTEM_CA_PATH = @SYSTEM_CA_PATH@ UTIL_LIBS = @UTIL_LIBS@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ dist_man8_MANS = pppstats.8 pppstats_SOURCES = pppstats.c pppstats_CFLAGS = pppstats_CPPFLAGS = $(am__append_1) all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu pppstats/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu pppstats/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-sbinPROGRAMS: $(sbin_PROGRAMS) @$(NORMAL_INSTALL) @list='$(sbin_PROGRAMS)'; test -n "$(sbindir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(sbindir)'"; \ $(MKDIR_P) "$(DESTDIR)$(sbindir)" || exit 1; \ fi; \ for p in $$list; do echo "$$p $$p"; done | \ sed 's/$(EXEEXT)$$//' | \ while read p p1; do if test -f $$p \ || test -f $$p1 \ ; then echo "$$p"; echo "$$p"; else :; fi; \ done | \ sed -e 'p;s,.*/,,;n;h' \ -e 's|.*|.|' \ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ if ($$2 == $$4) files[d] = files[d] " " $$1; \ else { print "f", $$3 "/" $$4, $$1; } } \ END { for (d in files) print "f", d, files[d] }' | \ while read type dir files; do \ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ test -z "$$files" || { \ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(sbindir)$$dir'"; \ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(sbindir)$$dir" || exit $$?; \ } \ ; done uninstall-sbinPROGRAMS: @$(NORMAL_UNINSTALL) @list='$(sbin_PROGRAMS)'; test -n "$(sbindir)" || list=; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ -e 's/$$/$(EXEEXT)/' \ `; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(sbindir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(sbindir)" && rm -f $$files clean-sbinPROGRAMS: @list='$(sbin_PROGRAMS)'; test -n "$$list" || exit 0; \ echo " rm -f" $$list; \ rm -f $$list || exit $$?; \ test -n "$(EXEEXT)" || exit 0; \ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list pppstats$(EXEEXT): $(pppstats_OBJECTS) $(pppstats_DEPENDENCIES) $(EXTRA_pppstats_DEPENDENCIES) @rm -f pppstats$(EXEEXT) $(AM_V_CCLD)$(pppstats_LINK) $(pppstats_OBJECTS) $(pppstats_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pppstats-pppstats.Po@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< pppstats-pppstats.o: pppstats.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppstats_CPPFLAGS) $(CPPFLAGS) $(pppstats_CFLAGS) $(CFLAGS) -MT pppstats-pppstats.o -MD -MP -MF $(DEPDIR)/pppstats-pppstats.Tpo -c -o pppstats-pppstats.o `test -f 'pppstats.c' || echo '$(srcdir)/'`pppstats.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pppstats-pppstats.Tpo $(DEPDIR)/pppstats-pppstats.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pppstats.c' object='pppstats-pppstats.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppstats_CPPFLAGS) $(CPPFLAGS) $(pppstats_CFLAGS) $(CFLAGS) -c -o pppstats-pppstats.o `test -f 'pppstats.c' || echo '$(srcdir)/'`pppstats.c pppstats-pppstats.obj: pppstats.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppstats_CPPFLAGS) $(CPPFLAGS) $(pppstats_CFLAGS) $(CFLAGS) -MT pppstats-pppstats.obj -MD -MP -MF $(DEPDIR)/pppstats-pppstats.Tpo -c -o pppstats-pppstats.obj `if test -f 'pppstats.c'; then $(CYGPATH_W) 'pppstats.c'; else $(CYGPATH_W) '$(srcdir)/pppstats.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pppstats-pppstats.Tpo $(DEPDIR)/pppstats-pppstats.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pppstats.c' object='pppstats-pppstats.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pppstats_CPPFLAGS) $(CPPFLAGS) $(pppstats_CFLAGS) $(CFLAGS) -c -o pppstats-pppstats.obj `if test -f 'pppstats.c'; then $(CYGPATH_W) 'pppstats.c'; else $(CYGPATH_W) '$(srcdir)/pppstats.c'; fi` mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs install-man8: $(dist_man8_MANS) @$(NORMAL_INSTALL) @list1='$(dist_man8_MANS)'; \ list2=''; \ test -n "$(man8dir)" \ && test -n "`echo $$list1$$list2`" \ || exit 0; \ echo " $(MKDIR_P) '$(DESTDIR)$(man8dir)'"; \ $(MKDIR_P) "$(DESTDIR)$(man8dir)" || exit 1; \ { for i in $$list1; do echo "$$i"; done; \ if test -n "$$list2"; then \ for i in $$list2; do echo "$$i"; done \ | sed -n '/\.8[a-z]*$$/p'; \ fi; \ } | while read p; do \ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; echo "$$p"; \ done | \ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ sed 'N;N;s,\n, ,g' | { \ list=; while read file base inst; do \ if test "$$base" = "$$inst"; then list="$$list $$file"; else \ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man8dir)/$$inst'"; \ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man8dir)/$$inst" || exit $$?; \ fi; \ done; \ for i in $$list; do echo "$$i"; done | $(am__base_list) | \ while read files; do \ test -z "$$files" || { \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man8dir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(man8dir)" || exit $$?; }; \ done; } uninstall-man8: @$(NORMAL_UNINSTALL) @list='$(dist_man8_MANS)'; test -n "$(man8dir)" || exit 0; \ files=`{ for i in $$list; do echo "$$i"; done; \ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ dir='$(DESTDIR)$(man8dir)'; $(am__uninstall_files_from_dir) ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(PROGRAMS) $(MANS) installdirs: for dir in "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(man8dir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-sbinPROGRAMS \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/pppstats-pppstats.Po -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-man install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-sbinPROGRAMS install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-man8 install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/pppstats-pppstats.Po -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-man uninstall-sbinPROGRAMS uninstall-man: uninstall-man8 .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-sbinPROGRAMS cscopelist-am \ ctags ctags-am distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-man8 install-pdf \ install-pdf-am install-ps install-ps-am install-sbinPROGRAMS \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ pdf pdf-am ps ps-am tags tags-am uninstall uninstall-am \ uninstall-man uninstall-man8 uninstall-sbinPROGRAMS .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: ppp-2.5.0/pppstats/pppstats.c0000664000175000017500000003050214273050614013142 00000000000000/* * print PPP statistics: * pppstats [-a|-d] [-v|-r|-z] [-c count] [-w wait] [interface] * * -a Show absolute values rather than deltas * -d Show data rate (kB/s) rather than bytes * -v Show more stats for VJ TCP header compression * -r Show compression ratio * -z Show compression statistics instead of default display * * History: * perkins@cps.msu.edu: Added compression statistics and alternate * display. 11/94 * Brad Parker (brad@cayman.com) 6/92 * * from the original "slstats" by Van Jacobson * * Copyright (c) 1989 Regents of the University of California. * All rights reserved. * * Redistribution and use in source and binary forms are permitted * provided that the above copyright notice and this paragraph are * duplicated in all such forms and that any documentation, * advertising materials, and other materials related to such * distribution and use acknowledge that the software was developed * by the University of California, Berkeley. The name of the * University may not be used to endorse or promote products derived * from this software without specific prior written permission. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #ifndef __STDC__ #define const #endif #ifndef lint static const char rcsid[] = "$Id: pppstats.c,v 1.29 2002/10/27 12:56:26 fcusack Exp $"; #endif #include #include #include #include #include #include #include #include #include #include #include #include #ifndef STREAMS #if defined(__linux__) && defined(__powerpc__) \ && (__GLIBC__ == 2 && __GLIBC_MINOR__ == 0) /* kludge alert! */ #undef __GLIBC__ #endif #include /* *BSD, Linux, NeXT, Ultrix etc. */ #ifndef __linux__ #include #include #else /* Linux */ #if __GLIBC__ >= 2 #include /* glibc 2 conflicts with linux/types.h */ #include #else #include #include #endif #include #include #endif /* __linux__ */ #else /* STREAMS */ #include /* SVR4, Solaris 2, SunOS 4, OSF/1, etc. */ #include #include #endif /* STREAMS */ int vflag, rflag, zflag; /* select type of display */ int aflag; /* print absolute values, not deltas */ int dflag; /* print data rates, not bytes */ int interval, count; int infinite; int s; /* socket or /dev/ppp file descriptor */ int signalled; /* set if alarm goes off "early" */ char *progname; char *interface; #if defined(SUNOS4) || defined(ULTRIX) || defined(NeXT) extern int optind; extern char *optarg; #endif /* * If PPP_DRV_NAME is not defined, use the legacy "ppp" as the * device name. */ #if !defined(PPP_DRV_NAME) #define PPP_DRV_NAME "ppp" #endif /* !defined(PPP_DRV_NAME) */ static void usage(void); static void catchalarm(int); static void get_ppp_stats(struct ppp_stats *); static void get_ppp_cstats(struct ppp_comp_stats *); static void intpr(void); int main(int, char *argv[]); static void usage(void) { fprintf(stderr, "Usage: %s [-a|-d] [-v|-r|-z] [-c count] [-w wait] [interface]\n", progname); exit(1); } /* * Called if an interval expires before intpr has completed a loop. * Sets a flag to not wait for the alarm. */ static void catchalarm(int arg) { signalled = 1; } #ifndef STREAMS static void get_ppp_stats(struct ppp_stats *curp) { struct ifreq req; memset (&req, 0, sizeof (req)); req.ifr_data = (caddr_t) curp; strncpy(req.ifr_name, interface, IFNAMSIZ); req.ifr_name[IFNAMSIZ - 1] = 0; if (ioctl(s, SIOCGPPPSTATS, &req) < 0) { fprintf(stderr, "%s: ", progname); if (errno == ENOTTY) fprintf(stderr, "kernel support missing\n"); else perror("couldn't get PPP statistics"); exit(1); } } static void get_ppp_cstats(struct ppp_comp_stats *csp) { struct ifreq req; struct ppp_comp_stats stats; memset (&req, 0, sizeof (req)); req.ifr_data = (caddr_t) &stats; strncpy(req.ifr_name, interface, IFNAMSIZ); req.ifr_name[IFNAMSIZ - 1] = 0; if (ioctl(s, SIOCGPPPCSTATS, &req) < 0) { fprintf(stderr, "%s: ", progname); if (errno == ENOTTY) { fprintf(stderr, "no kernel compression support\n"); if (zflag) exit(1); rflag = 0; } else { perror("couldn't get PPP compression stats"); exit(1); } } #ifdef __linux__ if (stats.c.bytes_out == 0) { stats.c.bytes_out = stats.c.comp_bytes + stats.c.inc_bytes; stats.c.in_count = stats.c.unc_bytes; } if (stats.c.bytes_out == 0) stats.c.ratio = 0.0; else stats.c.ratio = 256.0 * stats.c.in_count / stats.c.bytes_out; if (stats.d.bytes_out == 0) { stats.d.bytes_out = stats.d.comp_bytes + stats.d.inc_bytes; stats.d.in_count = stats.d.unc_bytes; } if (stats.d.bytes_out == 0) stats.d.ratio = 0.0; else stats.d.ratio = 256.0 * stats.d.in_count / stats.d.bytes_out; #endif *csp = stats; } #else /* STREAMS */ int strioctl(int fd, int cmd, char *ptr, int ilen, int olen) { struct strioctl str; str.ic_cmd = cmd; str.ic_timout = 0; str.ic_len = ilen; str.ic_dp = ptr; if (ioctl(fd, I_STR, &str) == -1) return -1; if (str.ic_len != olen) fprintf(stderr, "strioctl: expected %d bytes, got %d for cmd %x\n", olen, str.ic_len, cmd); return 0; } static void get_ppp_stats(struct ppp_stats *curp) { if (strioctl(s, PPPIO_GETSTAT, (char*) curp, 0, sizeof(*curp)) < 0) { fprintf(stderr, "%s: ", progname); if (errno == EINVAL) fprintf(stderr, "kernel support missing\n"); else perror("couldn't get PPP statistics"); exit(1); } } static void get_ppp_cstats(struct ppp_comp_stats *csp) { if (strioctl(s, PPPIO_GETCSTAT, (char*) csp, 0, sizeof(*csp)) < 0) { fprintf(stderr, "%s: ", progname); if (errno == ENOTTY) { fprintf(stderr, "no kernel compression support\n"); if (zflag) exit(1); rflag = 0; } else { perror("couldn't get PPP compression statistics"); exit(1); } } } #endif /* STREAMS */ #define MAX0(a) ((int)(a) > 0? (a): 0) #define V(offset) MAX0(cur.offset - old.offset) #define W(offset) MAX0(ccs.offset - ocs.offset) #define RATIO(c, i, u) ((c) == 0? 1.0: (u) / ((double)(c) + (i))) #define CRATE(x) RATIO(W(x.comp_bytes), W(x.inc_bytes), W(x.unc_bytes)) #define KBPS(n) ((n) / (interval * 1000.0)) /* * Print a running summary of interface statistics. * Repeat display every interval seconds, showing statistics * collected over that interval. Assumes that interval is non-zero. * First line printed is cumulative. */ static void intpr(void) { register int line = 0; sigset_t oldmask, mask; char *bunit; int ratef = 0; struct ppp_stats cur, old; struct ppp_comp_stats ccs, ocs; memset(&old, 0, sizeof(old)); memset(&ocs, 0, sizeof(ocs)); while (1) { get_ppp_stats(&cur); if (zflag || rflag) get_ppp_cstats(&ccs); (void)signal(SIGALRM, catchalarm); signalled = 0; (void)alarm(interval); if ((line % 20) == 0) { if (zflag) { printf("IN: COMPRESSED INCOMPRESSIBLE COMP | "); printf("OUT: COMPRESSED INCOMPRESSIBLE COMP\n"); bunit = dflag? "KB/S": "BYTE"; printf(" %s PACK %s PACK RATIO | ", bunit, bunit); printf(" %s PACK %s PACK RATIO", bunit, bunit); } else { printf("%8.8s %6.6s %6.6s", "IN", "PACK", "VJCOMP"); if (!rflag) printf(" %6.6s %6.6s", "VJUNC", "VJERR"); if (vflag) printf(" %6.6s %6.6s", "VJTOSS", "NON-VJ"); if (rflag) printf(" %6.6s %6.6s", "RATIO", "UBYTE"); printf(" | %8.8s %6.6s %6.6s", "OUT", "PACK", "VJCOMP"); if (!rflag) printf(" %6.6s %6.6s", "VJUNC", "NON-VJ"); if (vflag) printf(" %6.6s %6.6s", "VJSRCH", "VJMISS"); if (rflag) printf(" %6.6s %6.6s", "RATIO", "UBYTE"); } putchar('\n'); } if (zflag) { if (ratef) { printf("%8.3f %6u %8.3f %6u %6.2f", KBPS(W(d.comp_bytes)), W(d.comp_packets), KBPS(W(d.inc_bytes)), W(d.inc_packets), ccs.d.ratio / 256.0); printf(" | %8.3f %6u %8.3f %6u %6.2f", KBPS(W(c.comp_bytes)), W(c.comp_packets), KBPS(W(c.inc_bytes)), W(c.inc_packets), ccs.c.ratio / 256.0); } else { printf("%8u %6u %8u %6u %6.2f", W(d.comp_bytes), W(d.comp_packets), W(d.inc_bytes), W(d.inc_packets), ccs.d.ratio / 256.0); printf(" | %8u %6u %8u %6u %6.2f", W(c.comp_bytes), W(c.comp_packets), W(c.inc_bytes), W(c.inc_packets), ccs.c.ratio / 256.0); } } else { if (ratef) printf("%8.3f", KBPS(V(p.ppp_ibytes))); else printf("%8u", V(p.ppp_ibytes)); printf(" %6u %6u", V(p.ppp_ipackets), V(vj.vjs_compressedin)); if (!rflag) printf(" %6u %6u", V(vj.vjs_uncompressedin), V(vj.vjs_errorin)); if (vflag) printf(" %6u %6u", V(vj.vjs_tossed), V(p.ppp_ipackets) - V(vj.vjs_compressedin) - V(vj.vjs_uncompressedin) - V(vj.vjs_errorin)); if (rflag) { printf(" %6.2f ", CRATE(d)); if (ratef) printf("%6.2f", KBPS(W(d.unc_bytes))); else printf("%6u", W(d.unc_bytes)); } if (ratef) printf(" | %8.3f", KBPS(V(p.ppp_obytes))); else printf(" | %8u", V(p.ppp_obytes)); printf(" %6u %6u", V(p.ppp_opackets), V(vj.vjs_compressed)); if (!rflag) printf(" %6u %6u", V(vj.vjs_packets) - V(vj.vjs_compressed), V(p.ppp_opackets) - V(vj.vjs_packets)); if (vflag) printf(" %6u %6u", V(vj.vjs_searches), V(vj.vjs_misses)); if (rflag) { printf(" %6.2f ", CRATE(c)); if (ratef) printf("%6.2f", KBPS(W(c.unc_bytes))); else printf("%6u", W(c.unc_bytes)); } } putchar('\n'); fflush(stdout); line++; count--; if (!infinite && !count) break; sigemptyset(&mask); sigaddset(&mask, SIGALRM); sigprocmask(SIG_BLOCK, &mask, &oldmask); if (!signalled) { sigemptyset(&mask); sigsuspend(&mask); } sigprocmask(SIG_SETMASK, &oldmask, NULL); signalled = 0; (void)alarm(interval); if (!aflag) { old = cur; ocs = ccs; ratef = dflag; } } } int main(int argc, char *argv[]) { int c; #ifdef STREAMS int unit; char *dev; #endif interface = PPP_DRV_NAME "0"; if ((progname = strrchr(argv[0], '/')) == NULL) progname = argv[0]; else ++progname; while ((c = getopt(argc, argv, "advrzc:w:")) != -1) { switch (c) { case 'a': ++aflag; break; case 'd': ++dflag; break; case 'v': ++vflag; break; case 'r': ++rflag; break; case 'z': ++zflag; break; case 'c': count = atoi(optarg); if (count <= 0) usage(); break; case 'w': interval = atoi(optarg); if (interval <= 0) usage(); break; default: usage(); } } argc -= optind; argv += optind; if (!interval && count) interval = 5; if (interval && !count) infinite = 1; if (!interval && !count) count = 1; if (aflag) dflag = 0; if (argc > 1) usage(); if (argc > 0) interface = argv[0]; #ifndef STREAMS { struct ifreq ifr; s = socket(AF_INET, SOCK_DGRAM, 0); if (s < 0) { fprintf(stderr, "%s: ", progname); perror("couldn't create IP socket"); exit(1); } #ifdef __linux__ #undef ifr_name #define ifr_name ifr_ifrn.ifrn_name #endif strncpy(ifr.ifr_name, interface, IFNAMSIZ); ifr.ifr_name[IFNAMSIZ - 1] = 0; if (ioctl(s, SIOCGIFFLAGS, (caddr_t)&ifr) < 0) { fprintf(stderr, "%s: nonexistent interface '%s' specified\n", progname, interface); exit(1); } } #else /* STREAMS */ if (sscanf(interface, PPP_DRV_NAME "%d", &unit) != 1) { fprintf(stderr, "%s: invalid interface '%s' specified\n", progname, interface); } #ifdef __osf__ dev = "/dev/streams/ppp"; #else dev = "/dev/" PPP_DRV_NAME; #endif if ((s = open(dev, O_RDONLY)) < 0) { fprintf(stderr, "%s: couldn't open ", progname); perror(dev); exit(1); } if (strioctl(s, PPPIO_ATTACH, (char*) &unit, sizeof(int), 0) < 0) { fprintf(stderr, "%s: ppp%d is not available\n", progname, unit); exit(1); } #endif /* STREAMS */ intpr(); exit(0); } ppp-2.5.0/pppdump/0000755000175000017500000000000014412736275011016 500000000000000ppp-2.5.0/pppdump/Makefile.am0000664000175000017500000000023414273050614012762 00000000000000sbin_PROGRAMS = pppdump dist_man8_MANS = pppdump.8 pppdump_SOURCES = pppdump.c bsd-comp.c deflate.c zlib.c noinst_HEADERS = \ ppp-comp.h \ zlib.h ppp-2.5.0/pppdump/ppp-comp.h0000664000175000017500000001245514273050614012642 00000000000000/* * ppp-comp.h - Definitions for doing PPP packet compression. * * Copyright (c) 1994 Paul Mackerras. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The name(s) of the authors of this software must not be used to * endorse or promote products derived from this software without * prior written permission. * * 4. Redistributions of any form whatsoever must retain the following * acknowledgment: * "This product includes software developed by Paul Mackerras * ". * * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * $Id: ppp-comp.h,v 1.2 2002/12/06 09:49:16 paulus Exp $ */ #ifndef _NET_PPP_COMP_H #define _NET_PPP_COMP_H /* * The following symbols control whether we include code for * various compression methods. */ #ifndef DO_BSD_COMPRESS #define DO_BSD_COMPRESS 1 /* by default, include BSD-Compress */ #endif #ifndef DO_DEFLATE #define DO_DEFLATE 1 /* by default, include Deflate */ #endif #define DO_PREDICTOR_1 0 #define DO_PREDICTOR_2 0 #if defined(SOL2) #include #else #include #endif /* * Structure giving methods for compression/decompression. */ struct compressor { int compress_proto; /* CCP compression protocol number */ /* Allocate space for a decompressor (receive side) */ void *(*decomp_alloc)(u_char *options, int opt_len); /* Free space used by a decompressor */ void (*decomp_free)(void *state); /* Initialize a decompressor */ int (*decomp_init)(void *state, u_char *options, int opt_len, int unit, int hdrlen, int mru, int debug); /* Reset a decompressor */ void (*decomp_reset)(void *state); /* Decompress a packet. */ int (*decompress)(void *state, u_char *mp, int inlen, u_char *dmp, int *outlen); /* Update state for an incompressible packet received */ void (*incomp)(void *state, u_char *mp, int len); /* Return decompression statistics */ void (*decomp_stat)(void *state, struct compstat *stats); }; /* * Return values for decompress routine. * We need to make these distinctions so that we can disable certain * useful functionality, namely sending a CCP reset-request as a result * of an error detected after decompression. This is to avoid infringing * a patent held by Motorola. * Don't you just lurve software patents. */ #define DECOMP_OK 0 /* everything went OK */ #define DECOMP_ERROR 1 /* error detected before decomp. */ #define DECOMP_FATALERROR 2 /* error detected after decomp. */ /* * CCP codes. */ #define CCP_CONFREQ 1 #define CCP_CONFACK 2 #define CCP_CONFNAK 3 #define CCP_CONFREJ 4 #define CCP_TERMREQ 5 #define CCP_TERMACK 6 #define CCP_RESETREQ 14 #define CCP_RESETACK 15 /* * Max # bytes for a CCP option */ #define CCP_MAX_OPTION_LENGTH 32 /* * Parts of a CCP packet. */ #define CCP_CODE(dp) ((dp)[0]) #define CCP_ID(dp) ((dp)[1]) #define CCP_LENGTH(dp) (((dp)[2] << 8) + (dp)[3]) #define CCP_HDRLEN 4 #define CCP_OPT_CODE(dp) ((dp)[0]) #define CCP_OPT_LENGTH(dp) ((dp)[1]) #define CCP_OPT_MINLEN 2 /* * Definitions for BSD-Compress. */ #define CI_BSD_COMPRESS 21 /* config. option for BSD-Compress */ #define CILEN_BSD_COMPRESS 3 /* length of config. option */ /* Macros for handling the 3rd byte of the BSD-Compress config option. */ #define BSD_NBITS(x) ((x) & 0x1F) /* number of bits requested */ #define BSD_VERSION(x) ((x) >> 5) /* version of option format */ #define BSD_CURRENT_VERSION 1 /* current version number */ #define BSD_MAKE_OPT(v, n) (((v) << 5) | (n)) #define BSD_MIN_BITS 9 /* smallest code size supported */ #define BSD_MAX_BITS 15 /* largest code size supported */ /* * Definitions for Deflate. */ #define CI_DEFLATE 26 /* config option for Deflate */ #define CI_DEFLATE_DRAFT 24 /* value used in original draft RFC */ #define CILEN_DEFLATE 4 /* length of its config option */ #define DEFLATE_MIN_SIZE 8 #define DEFLATE_MAX_SIZE 15 #define DEFLATE_METHOD_VAL 8 #define DEFLATE_SIZE(x) (((x) >> 4) + DEFLATE_MIN_SIZE) #define DEFLATE_METHOD(x) ((x) & 0x0F) #define DEFLATE_MAKE_OPT(w) ((((w) - DEFLATE_MIN_SIZE) << 4) \ + DEFLATE_METHOD_VAL) #define DEFLATE_CHK_SEQUENCE 0 /* * Definitions for other, as yet unsupported, compression methods. */ #define CI_PREDICTOR_1 1 /* config option for Predictor-1 */ #define CILEN_PREDICTOR_1 2 /* length of its config option */ #define CI_PREDICTOR_2 2 /* config option for Predictor-2 */ #define CILEN_PREDICTOR_2 2 /* length of its config option */ #endif /* _NET_PPP_COMP_H */ ppp-2.5.0/pppdump/zlib.h0000644000175000017500000004020114407475306012043 00000000000000/* $Id: zlib.h,v 1.1 1999/03/23 03:21:58 paulus Exp $ */ /* * This file is derived from zlib.h and zconf.h from the zlib-0.95 * distribution by Jean-loup Gailly and Mark Adler, with some additions * by Paul Mackerras to aid in implementing Deflate compression and * decompression for PPP packets. */ /* zlib.h -- interface of the 'zlib' general purpose compression library version 0.95, Aug 16th, 1995. Copyright (C) 1995 Jean-loup Gailly and Mark Adler This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. Jean-loup Gailly Mark Adler gzip@prep.ai.mit.edu madler@alumni.caltech.edu */ #ifndef _ZLIB_H #define _ZLIB_H /* #include "zconf.h" */ /* included directly here */ /* zconf.h -- configuration of the zlib compression library * Copyright (C) 1995 Jean-loup Gailly. * For conditions of distribution and use, see copyright notice in zlib.h */ /* From: zconf.h,v 1.12 1995/05/03 17:27:12 jloup Exp */ /* The library does not install any signal handler. It is recommended to add at least a handler for SIGSEGV when decompressing; the library checks the consistency of the input data whenever possible but may go nuts for some forms of corrupted input. */ /* * Compile with -DMAXSEG_64K if the alloc function cannot allocate more * than 64k bytes at a time (needed on systems with 16-bit int). * Compile with -DUNALIGNED_OK if it is OK to access shorts or ints * at addresses which are not a multiple of their size. * Under DOS, -DFAR=far or -DFAR=__far may be needed. */ #ifndef STDC # if defined(MSDOS) || defined(__STDC__) || defined(__cplusplus) # define STDC # endif #endif #ifdef __MWERKS__ /* Metrowerks CodeWarrior declares fileno() in unix.h */ # include #endif #ifndef FAR # define FAR #endif /* Maximum value for windowBits in deflateInit2 and inflateInit2 */ #ifndef MAX_WBITS # define MAX_WBITS 15 /* 32K LZ77 window */ #endif /* The memory requirements for inflate are (in bytes) 1 << windowBits that is, 32K for windowBits=15 (default value) plus a few kilobytes for small objects. */ /* Type declarations */ #ifndef OF /* function prototypes */ # ifdef STDC # define OF(args) args # else # define OF(args) () # endif #endif typedef unsigned char Byte; /* 8 bits */ typedef unsigned int uInt; /* 16 bits or more */ typedef unsigned long uLong; /* 32 bits or more */ typedef Byte FAR Bytef; typedef char FAR charf; typedef int FAR intf; typedef uInt FAR uIntf; typedef uLong FAR uLongf; #ifdef STDC typedef void FAR *voidpf; typedef void *voidp; #else typedef Byte FAR *voidpf; typedef Byte *voidp; #endif /* end of original zconf.h */ #define ZLIB_VERSION "0.95P" /* The 'zlib' compression library provides in-memory compression and decompression functions, including integrity checks of the uncompressed data. This version of the library supports only one compression method (deflation) but other algorithms may be added later and will have the same stream interface. For compression the application must provide the output buffer and may optionally provide the input buffer for optimization. For decompression, the application must provide the input buffer and may optionally provide the output buffer for optimization. Compression can be done in a single step if the buffers are large enough (for example if an input file is mmap'ed), or can be done by repeated calls of the compression function. In the latter case, the application must provide more input and/or consume the output (providing more output space) before each call. */ typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size)); typedef void (*free_func) OF((voidpf opaque, voidpf address, uInt nbytes)); struct internal_state; typedef struct z_stream_s { Bytef *next_in; /* next input byte */ uInt avail_in; /* number of bytes available at next_in */ uLong total_in; /* total nb of input bytes read so far */ Bytef *next_out; /* next output byte should be put there */ uInt avail_out; /* remaining free space at next_out */ uLong total_out; /* total nb of bytes output so far */ char *msg; /* last error message, NULL if no error */ struct internal_state FAR *state; /* not visible by applications */ alloc_func zalloc; /* used to allocate the internal state */ free_func zfree; /* used to free the internal state */ voidp opaque; /* private data object passed to zalloc and zfree */ Byte data_type; /* best guess about the data type: ascii or binary */ } z_stream; /* The application must update next_in and avail_in when avail_in has dropped to zero. It must update next_out and avail_out when avail_out has dropped to zero. The application must initialize zalloc, zfree and opaque before calling the init function. All other fields are set by the compression library and must not be updated by the application. The opaque value provided by the application will be passed as the first parameter for calls of zalloc and zfree. This can be useful for custom memory management. The compression library attaches no meaning to the opaque value. zalloc must return Z_NULL if there is not enough memory for the object. On 16-bit systems, the functions zalloc and zfree must be able to allocate exactly 65536 bytes, but will not be required to allocate more than this if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS, pointers returned by zalloc for objects of exactly 65536 bytes *must* have their offset normalized to zero. The default allocation function provided by this library ensures this (see zutil.c). To reduce memory requirements and avoid any allocation of 64K objects, at the expense of compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h). The fields total_in and total_out can be used for statistics or progress reports. After compression, total_in holds the total size of the uncompressed data and may be saved for use in the decompressor (particularly if the decompressor wants to decompress everything in a single step). */ /* constants */ #define Z_NO_FLUSH 0 #define Z_PARTIAL_FLUSH 1 #define Z_FULL_FLUSH 2 #define Z_SYNC_FLUSH 3 /* experimental: partial_flush + byte align */ #define Z_FINISH 4 #define Z_PACKET_FLUSH 5 /* See deflate() below for the usage of these constants */ #define Z_OK 0 #define Z_STREAM_END 1 #define Z_ERRNO (-1) #define Z_STREAM_ERROR (-2) #define Z_DATA_ERROR (-3) #define Z_MEM_ERROR (-4) #define Z_BUF_ERROR (-5) /* error codes for the compression/decompression functions */ #define Z_BEST_SPEED 1 #define Z_BEST_COMPRESSION 9 #define Z_DEFAULT_COMPRESSION (-1) /* compression levels */ #define Z_FILTERED 1 #define Z_HUFFMAN_ONLY 2 #define Z_DEFAULT_STRATEGY 0 #define Z_BINARY 0 #define Z_ASCII 1 #define Z_UNKNOWN 2 /* Used to set the data_type field */ #define Z_NULL 0 /* for initializing zalloc, zfree, opaque */ extern char *zlib_version; /* The application can compare zlib_version and ZLIB_VERSION for consistency. If the first character differs, the library code actually used is not compatible with the zlib.h header file used by the application. */ /* basic functions */ extern int inflateInit OF((z_stream *strm)); /* Initializes the internal stream state for decompression. The fields zalloc and zfree must be initialized before by the caller. If zalloc and zfree are set to Z_NULL, inflateInit updates them to use default allocation functions. inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough memory. msg is set to null if there is no error message. inflateInit does not perform any decompression: this will be done by inflate(). */ extern int inflate OF((z_stream *strm, int flush)); /* Performs one or both of the following actions: - Decompress more input starting at next_in and update next_in and avail_in accordingly. If not all input can be processed (because there is not enough room in the output buffer), next_in is updated and processing will resume at this point for the next call of inflate(). - Provide more output starting at next_out and update next_out and avail_out accordingly. inflate() always provides as much output as possible (until there is no more input data or no more space in the output buffer). Before the call of inflate(), the application should ensure that at least one of the actions is possible, by providing more input and/or consuming more output, and updating the next_* and avail_* values accordingly. The application can consume the uncompressed output when it wants, for example when the output buffer is full (avail_out == 0), or after each call of inflate(). If the parameter flush is set to Z_PARTIAL_FLUSH or Z_PACKET_FLUSH, inflate flushes as much output as possible to the output buffer. The flushing behavior of inflate is not specified for values of the flush parameter other than Z_PARTIAL_FLUSH, Z_PACKET_FLUSH or Z_FINISH, but the current implementation actually flushes as much output as possible anyway. For Z_PACKET_FLUSH, inflate checks that once all the input data has been consumed, it is expecting to see the length field of a stored block; if not, it returns Z_DATA_ERROR. inflate() should normally be called until it returns Z_STREAM_END or an error. However if all decompression is to be performed in a single step (a single call of inflate), the parameter flush should be set to Z_FINISH. In this case all pending input is processed and all pending output is flushed; avail_out must be large enough to hold all the uncompressed data. (The size of the uncompressed data may have been saved by the compressor for this purpose.) The next operation on this stream must be inflateEnd to deallocate the decompression state. The use of Z_FINISH is never required, but can be used to inform inflate that a faster routine may be used for the single inflate() call. inflate() returns Z_OK if some progress has been made (more input processed or more output produced), Z_STREAM_END if the end of the compressed data has been reached and all uncompressed output has been produced, Z_DATA_ERROR if the input data was corrupted, Z_STREAM_ERROR if the stream structure was inconsistent (for example if next_in or next_out was NULL), Z_MEM_ERROR if there was not enough memory, Z_BUF_ERROR if no progress is possible or if there was not enough room in the output buffer when Z_FINISH is used. In the Z_DATA_ERROR case, the application may then call inflateSync to look for a good compression block. */ extern int inflateEnd OF((z_stream *strm)); /* All dynamically allocated data structures for this stream are freed. This function discards any unprocessed input and does not flush any pending output. inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state was inconsistent. In the error case, msg may be set but then points to a static string (which must not be deallocated). */ /* advanced functions */ /* The following functions are needed only in some special applications. */ extern int inflateInit2 OF((z_stream *strm, int windowBits)); /* This is another version of inflateInit with more compression options. The fields next_out, zalloc and zfree must be initialized before by the caller. The windowBits parameter is the base two logarithm of the maximum window size (the size of the history buffer). It should be in the range 8..15 for this version of the library (the value 16 will be allowed soon). The default value is 15 if inflateInit is used instead. If a compressed stream with a larger window size is given as input, inflate() will return with the error code Z_DATA_ERROR instead of trying to allocate a larger window. If next_out is not null, the library will use this buffer for the history buffer; the buffer must either be large enough to hold the entire output data, or have at least 1<&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ sbin_PROGRAMS = pppdump$(EXEEXT) subdir = pppdump ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_atm.m4 \ $(top_srcdir)/m4/ax_check_openssl.m4 \ $(top_srcdir)/m4/ax_check_openssl_func.m4 \ $(top_srcdir)/m4/ax_check_pam.m4 \ $(top_srcdir)/m4/ax_check_pcap.m4 \ $(top_srcdir)/m4/ax_check_srp.m4 $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/pkg.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(noinst_HEADERS) \ $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/pppd/config.h \ $(top_builddir)/pppd/pppdconf.h \ $(top_builddir)/pppd/plugins/pppoe/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__installdirs = "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(man8dir)" PROGRAMS = $(sbin_PROGRAMS) am_pppdump_OBJECTS = pppdump.$(OBJEXT) bsd-comp.$(OBJEXT) \ deflate.$(OBJEXT) zlib.$(OBJEXT) pppdump_OBJECTS = $(am_pppdump_OBJECTS) pppdump_LDADD = $(LDADD) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/pppd -I$(top_builddir)/pppd/plugins/pppoe depcomp = $(SHELL) $(top_srcdir)/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/bsd-comp.Po ./$(DEPDIR)/deflate.Po \ ./$(DEPDIR)/pppdump.Po ./$(DEPDIR)/zlib.Po am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(pppdump_SOURCES) DIST_SOURCES = $(pppdump_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } man8dir = $(mandir)/man8 NROFF = nroff MANS = $(dist_man8_MANS) HEADERS = $(noinst_HEADERS) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(dist_man8_MANS) $(srcdir)/Makefile.in \ $(top_srcdir)/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ ATM_CFLAGS = @ATM_CFLAGS@ ATM_LDFLAGS = @ATM_LDFLAGS@ ATM_LIBS = @ATM_LIBS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CRYPT_LIBS = @CRYPT_LIBS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GREP = @GREP@ GTK_CFLAGS = @GTK_CFLAGS@ GTK_LIBS = @GTK_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_INCLUDES = @OPENSSL_INCLUDES@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAM_CFLAGS = @PAM_CFLAGS@ PAM_LDFLAGS = @PAM_LDFLAGS@ PAM_LIBS = @PAM_LIBS@ PATH_SEPARATOR = @PATH_SEPARATOR@ PCAP_CFLAGS = @PCAP_CFLAGS@ PCAP_LDFLAGS = @PCAP_LDFLAGS@ PCAP_LIBS = @PCAP_LIBS@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PPPD_LOGFILE_DIR = @PPPD_LOGFILE_DIR@ PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@ PPPD_RUNTIME_DIR = @PPPD_RUNTIME_DIR@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SRP_CFLAGS = @SRP_CFLAGS@ SRP_LDFLAGS = @SRP_LDFLAGS@ SRP_LIBS = @SRP_LIBS@ STRIP = @STRIP@ SYSTEMD_CFLAGS = @SYSTEMD_CFLAGS@ SYSTEMD_LIBS = @SYSTEMD_LIBS@ SYSTEM_CA_PATH = @SYSTEM_CA_PATH@ UTIL_LIBS = @UTIL_LIBS@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ dist_man8_MANS = pppdump.8 pppdump_SOURCES = pppdump.c bsd-comp.c deflate.c zlib.c noinst_HEADERS = \ ppp-comp.h \ zlib.h all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu pppdump/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu pppdump/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-sbinPROGRAMS: $(sbin_PROGRAMS) @$(NORMAL_INSTALL) @list='$(sbin_PROGRAMS)'; test -n "$(sbindir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(sbindir)'"; \ $(MKDIR_P) "$(DESTDIR)$(sbindir)" || exit 1; \ fi; \ for p in $$list; do echo "$$p $$p"; done | \ sed 's/$(EXEEXT)$$//' | \ while read p p1; do if test -f $$p \ || test -f $$p1 \ ; then echo "$$p"; echo "$$p"; else :; fi; \ done | \ sed -e 'p;s,.*/,,;n;h' \ -e 's|.*|.|' \ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ if ($$2 == $$4) files[d] = files[d] " " $$1; \ else { print "f", $$3 "/" $$4, $$1; } } \ END { for (d in files) print "f", d, files[d] }' | \ while read type dir files; do \ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ test -z "$$files" || { \ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(sbindir)$$dir'"; \ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(sbindir)$$dir" || exit $$?; \ } \ ; done uninstall-sbinPROGRAMS: @$(NORMAL_UNINSTALL) @list='$(sbin_PROGRAMS)'; test -n "$(sbindir)" || list=; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ -e 's/$$/$(EXEEXT)/' \ `; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(sbindir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(sbindir)" && rm -f $$files clean-sbinPROGRAMS: @list='$(sbin_PROGRAMS)'; test -n "$$list" || exit 0; \ echo " rm -f" $$list; \ rm -f $$list || exit $$?; \ test -n "$(EXEEXT)" || exit 0; \ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list pppdump$(EXEEXT): $(pppdump_OBJECTS) $(pppdump_DEPENDENCIES) $(EXTRA_pppdump_DEPENDENCIES) @rm -f pppdump$(EXEEXT) $(AM_V_CCLD)$(LINK) $(pppdump_OBJECTS) $(pppdump_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bsd-comp.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/deflate.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pppdump.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/zlib.Po@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs install-man8: $(dist_man8_MANS) @$(NORMAL_INSTALL) @list1='$(dist_man8_MANS)'; \ list2=''; \ test -n "$(man8dir)" \ && test -n "`echo $$list1$$list2`" \ || exit 0; \ echo " $(MKDIR_P) '$(DESTDIR)$(man8dir)'"; \ $(MKDIR_P) "$(DESTDIR)$(man8dir)" || exit 1; \ { for i in $$list1; do echo "$$i"; done; \ if test -n "$$list2"; then \ for i in $$list2; do echo "$$i"; done \ | sed -n '/\.8[a-z]*$$/p'; \ fi; \ } | while read p; do \ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; echo "$$p"; \ done | \ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ sed 'N;N;s,\n, ,g' | { \ list=; while read file base inst; do \ if test "$$base" = "$$inst"; then list="$$list $$file"; else \ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man8dir)/$$inst'"; \ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man8dir)/$$inst" || exit $$?; \ fi; \ done; \ for i in $$list; do echo "$$i"; done | $(am__base_list) | \ while read files; do \ test -z "$$files" || { \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man8dir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(man8dir)" || exit $$?; }; \ done; } uninstall-man8: @$(NORMAL_UNINSTALL) @list='$(dist_man8_MANS)'; test -n "$(man8dir)" || exit 0; \ files=`{ for i in $$list; do echo "$$i"; done; \ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ dir='$(DESTDIR)$(man8dir)'; $(am__uninstall_files_from_dir) ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(PROGRAMS) $(MANS) $(HEADERS) installdirs: for dir in "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(man8dir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-sbinPROGRAMS \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/bsd-comp.Po -rm -f ./$(DEPDIR)/deflate.Po -rm -f ./$(DEPDIR)/pppdump.Po -rm -f ./$(DEPDIR)/zlib.Po -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-man install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-sbinPROGRAMS install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-man8 install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/bsd-comp.Po -rm -f ./$(DEPDIR)/deflate.Po -rm -f ./$(DEPDIR)/pppdump.Po -rm -f ./$(DEPDIR)/zlib.Po -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-man uninstall-sbinPROGRAMS uninstall-man: uninstall-man8 .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-sbinPROGRAMS cscopelist-am \ ctags ctags-am distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-man8 install-pdf \ install-pdf-am install-ps install-ps-am install-sbinPROGRAMS \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ pdf pdf-am ps ps-am tags tags-am uninstall uninstall-am \ uninstall-man uninstall-man8 uninstall-sbinPROGRAMS .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: ppp-2.5.0/pppdump/pppdump.c0000664000175000017500000003133114273050614012561 00000000000000/* * pppdump - print out the contents of a record file generated by * pppd in readable form. * * Copyright (c) 1999 Paul Mackerras. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The name(s) of the authors of this software must not be used to * endorse or promote products derived from this software without * prior written permission. * * 4. Redistributions of any form whatsoever must retain the following * acknowledgment: * "This product includes software developed by Paul Mackerras * ". * * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include #include #include #include #include #include "ppp-comp.h" int hexmode; int pppmode; int reverse; int decompress; int mru = 1500; int abs_times; time_t start_time; int start_time_tenths; int tot_sent, tot_rcvd; extern int optind; extern char *optarg; void dumplog(); void dumpppp(); void show_time(); void handle_ccp(); int main(ac, av) int ac; char **av; { int i; char *p; FILE *f; while ((i = getopt(ac, av, "hprdm:a")) != -1) { switch (i) { case 'h': hexmode = 1; break; case 'p': pppmode = 1; break; case 'r': reverse = 1; break; case 'd': decompress = 1; break; case 'm': mru = atoi(optarg); break; case 'a': abs_times = 1; break; default: fprintf(stderr, "Usage: %s [-h | -p[d]] [-r] [-m mru] [-a] [file ...]\n", av[0]); exit(1); } } if (optind >= ac) dumplog(stdin); else { for (i = optind; i < ac; ++i) { p = av[i]; if ((f = fopen(p, "r")) == NULL) { perror(p); exit(1); } if (pppmode) dumpppp(f); else dumplog(f); fclose(f); } } exit(0); } void dumplog(f) FILE *f; { int c, n, k, col; int nb, c2; unsigned char buf[16]; while ((c = getc(f)) != EOF) { switch (c) { case 1: case 2: if (reverse) c = 3 - c; printf("%s %c", c==1? "sent": "rcvd", hexmode? ' ': '"'); col = 6; n = getc(f); n = (n << 8) + getc(f); *(c==1? &tot_sent: &tot_rcvd) += n; nb = 0; for (; n > 0; --n) { c = getc(f); if (c == EOF) { printf("\nEOF\n"); exit(0); } if (hexmode) { if (nb >= 16) { printf(" "); for (k = 0; k < nb; ++k) { c2 = buf[k]; putchar((' ' <= c2 && c2 <= '~')? c2: '.'); } printf("\n "); nb = 0; } buf[nb++] = c; printf(" %.2x", c); } else { k = (' ' <= c && c <= '~')? (c != '\\' && c != '"')? 1: 2: 3; if ((col += k) >= 78) { printf("\n "); col = 6 + k; } switch (k) { case 1: putchar(c); break; case 2: printf("\\%c", c); break; case 3: printf("\\%.2x", c); break; } } } if (hexmode) { for (k = nb; k < 16; ++k) printf(" "); printf(" "); for (k = 0; k < nb; ++k) { c2 = buf[k]; putchar((' ' <= c2 && c2 <= '~')? c2: '.'); } } else putchar('"'); printf("\n"); break; case 3: case 4: printf("end %s\n", c==3? "send": "recv"); break; case 5: case 6: case 7: show_time(f, c); break; default: printf("?%.2x\n", c); } } } /* * FCS lookup table as calculated by genfcstab. */ static u_short fcstab[256] = { 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf, 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7, 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e, 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876, 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd, 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5, 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c, 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974, 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb, 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3, 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a, 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72, 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9, 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1, 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738, 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70, 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7, 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff, 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036, 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e, 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5, 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd, 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134, 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c, 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3, 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb, 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232, 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a, 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1, 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9, 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330, 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78 }; #define PPP_FCS(fcs, c) (((fcs) >> 8) ^ fcstab[((fcs) ^ (c)) & 0xff]) struct pkt { int cnt; int esc; int flags; struct compressor *comp; void *state; unsigned char buf[8192]; } spkt, rpkt; /* Values for flags */ #define CCP_ISUP 1 #define CCP_ERROR 2 #define CCP_FATALERROR 4 #define CCP_ERR (CCP_ERROR | CCP_FATALERROR) #define CCP_DECOMP_RUN 8 unsigned char dbuf[8192]; void dumpppp(f) FILE *f; { int c, n, k; int nb, nl, dn, proto, rv; char *dir, *q; unsigned char *p, *r, *endp; unsigned char *d; unsigned short fcs; struct pkt *pkt; spkt.cnt = rpkt.cnt = 0; spkt.esc = rpkt.esc = 0; while ((c = getc(f)) != EOF) { switch (c) { case 1: case 2: if (reverse) c = 3 - c; dir = c==1? "sent": "rcvd"; pkt = c==1? &spkt: &rpkt; n = getc(f); n = (n << 8) + getc(f); *(c==1? &tot_sent: &tot_rcvd) += n; for (; n > 0; --n) { c = getc(f); switch (c) { case EOF: printf("\nEOF\n"); if (spkt.cnt > 0) printf("[%d bytes in incomplete send packet]\n", spkt.cnt); if (rpkt.cnt > 0) printf("[%d bytes in incomplete recv packet]\n", rpkt.cnt); exit(0); case '~': if (pkt->cnt > 0) { q = dir; if (pkt->esc) { printf("%s aborted packet:\n ", dir); q = " "; } if (pkt->cnt >= sizeof(pkt->buf)) { printf("%s over-long packet truncated:\n ", dir); q = " "; } nb = pkt->cnt; p = pkt->buf; pkt->cnt = 0; pkt->esc = 0; if (nb <= 2) { printf("%s short packet [%d bytes]:", q, nb); for (k = 0; k < nb; ++k) printf(" %.2x", p[k]); printf("\n"); break; } fcs = PPP_INITFCS; for (k = 0; k < nb; ++k) fcs = PPP_FCS(fcs, p[k]); fcs &= 0xFFFF; nb -= 2; endp = p + nb; r = p; if (r[0] == 0xff && r[1] == 3) r += 2; if ((r[0] & 1) == 0) ++r; ++r; if (endp - r > mru) printf(" ERROR: length (%zd) > MRU (%d)\n", endp - r, mru); if (decompress && fcs == PPP_GOODFCS) { /* See if this is a CCP or compressed packet */ d = dbuf; r = p; if (r[0] == 0xff && r[1] == 3) { *d++ = *r++; *d++ = *r++; } proto = r[0]; if ((proto & 1) == 0) proto = (proto << 8) + r[1]; if (proto == PPP_CCP) { handle_ccp(pkt, r + 2, endp - r - 2); } else if (proto == PPP_COMP) { if ((pkt->flags & CCP_ISUP) && (pkt->flags & CCP_DECOMP_RUN) && pkt->state && (pkt->flags & CCP_ERR) == 0) { rv = pkt->comp->decompress(pkt->state, r, endp - r, d, &dn); switch (rv) { case DECOMP_OK: p = dbuf; nb = d + dn - p; if ((d[0] & 1) == 0) --dn; --dn; if (dn > mru) printf(" ERROR: decompressed length (%d) > MRU (%d)\n", dn, mru); break; case DECOMP_ERROR: printf(" DECOMPRESSION ERROR\n"); pkt->flags |= CCP_ERROR; break; case DECOMP_FATALERROR: printf(" FATAL DECOMPRESSION ERROR\n"); pkt->flags |= CCP_FATALERROR; break; } } } else if (pkt->state && (pkt->flags & CCP_DECOMP_RUN)) { pkt->comp->incomp(pkt->state, r, endp - r); } } do { nl = nb < 16? nb: 16; printf("%s ", q); for (k = 0; k < nl; ++k) printf(" %.2x", p[k]); for (; k < 16; ++k) printf(" "); printf(" "); for (k = 0; k < nl; ++k) { c = p[k]; putchar((' ' <= c && c <= '~')? c: '.'); } printf("\n"); q = " "; p += nl; nb -= nl; } while (nb > 0); if (fcs != PPP_GOODFCS) printf(" BAD FCS: (residue = %x)\n", fcs); } break; case '}': if (!pkt->esc) { pkt->esc = 1; break; } /* else fall through */ default: if (pkt->esc) { c ^= 0x20; pkt->esc = 0; } if (pkt->cnt < sizeof(pkt->buf)) pkt->buf[pkt->cnt++] = c; break; } } break; case 3: case 4: if (reverse) c = 7 - c; dir = c==3? "send": "recv"; pkt = c==3? &spkt: &rpkt; printf("end %s", dir); if (pkt->cnt > 0) printf(" [%d bytes in incomplete packet]", pkt->cnt); printf("\n"); break; case 5: case 6: case 7: show_time(f, c); break; default: printf("?%.2x\n", c); } } } extern struct compressor ppp_bsd_compress, ppp_deflate; struct compressor *compressors[] = { #if DO_BSD_COMPRESS &ppp_bsd_compress, #endif #if DO_DEFLATE &ppp_deflate, #endif NULL }; void handle_ccp(cp, dp, len) struct pkt *cp; u_char *dp; int len; { int clen; struct compressor **comp; if (len < CCP_HDRLEN) return; clen = CCP_LENGTH(dp); if (clen > len) return; switch (CCP_CODE(dp)) { case CCP_CONFACK: cp->flags &= ~(CCP_DECOMP_RUN | CCP_ISUP); if (clen < CCP_HDRLEN + CCP_OPT_MINLEN || clen < CCP_HDRLEN + CCP_OPT_LENGTH(dp + CCP_HDRLEN)) break; dp += CCP_HDRLEN; clen -= CCP_HDRLEN; for (comp = compressors; *comp != NULL; ++comp) { if ((*comp)->compress_proto == dp[0]) { if (cp->state != NULL) { (*cp->comp->decomp_free)(cp->state); cp->state = NULL; } cp->comp = *comp; cp->state = (*comp)->decomp_alloc(dp, CCP_OPT_LENGTH(dp)); cp->flags |= CCP_ISUP; if (cp->state != NULL && (*cp->comp->decomp_init) (cp->state, dp, clen, 0, 0, 8192, 1)) cp->flags = (cp->flags & ~CCP_ERR) | CCP_DECOMP_RUN; break; } } break; case CCP_CONFNAK: case CCP_CONFREJ: cp->flags &= ~(CCP_DECOMP_RUN | CCP_ISUP); break; case CCP_RESETACK: if (cp->flags & CCP_ISUP) { if (cp->state && (cp->flags & CCP_DECOMP_RUN)) { (*cp->comp->decomp_reset)(cp->state); cp->flags &= ~CCP_ERROR; } } break; } } void show_time(f, c) FILE *f; int c; { time_t t; int n; struct tm *tm; if (c == 7) { t = getc(f); t = (t << 8) + getc(f); t = (t << 8) + getc(f); t = (t << 8) + getc(f); printf("start %s", ctime(&t)); start_time = t; start_time_tenths = 0; tot_sent = tot_rcvd = 0; } else { n = getc(f); if (c == 5) { for (c = 3; c > 0; --c) n = (n << 8) + getc(f); } if (abs_times) { n += start_time_tenths; start_time += n / 10; start_time_tenths = n % 10; tm = localtime(&start_time); printf("time %.2d:%.2d:%.2d.%d", tm->tm_hour, tm->tm_min, tm->tm_sec, start_time_tenths); printf(" (sent %d, rcvd %d)\n", tot_sent, tot_rcvd); } else printf("time %.1fs\n", (double) n / 10); } } ppp-2.5.0/pppdump/bsd-comp.c0000664000175000017500000004745414273050614012615 00000000000000/* Because this code is derived from the 4.3BSD compress source: * * * Copyright (c) 1985, 1986 The Regents of the University of California. * All rights reserved. * * This code is derived from software contributed to Berkeley by * James A. Woods, derived from original work by Spencer Thomas * and Joseph Orost. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* * $Id: bsd-comp.c,v 1.4 2004/01/17 05:47:55 carlsonj Exp $ */ #include #include #include #include #include #include "ppp-comp.h" #if DO_BSD_COMPRESS /* * PPP "BSD compress" compression * The differences between this compression and the classic BSD LZW * source are obvious from the requirement that the classic code worked * with files while this handles arbitrarily long streams that * are broken into packets. They are: * * When the code size expands, a block of junk is not emitted by * the compressor and not expected by the decompressor. * * New codes are not necessarily assigned every time an old * code is output by the compressor. This is because a packet * end forces a code to be emitted, but does not imply that a * new sequence has been seen. * * The compression ratio is checked at the first end of a packet * after the appropriate gap. Besides simplifying and speeding * things up, this makes it more likely that the transmitter * and receiver will agree when the dictionary is cleared when * compression is not going well. */ /* * A dictionary for doing BSD compress. */ struct bsd_db { int totlen; /* length of this structure */ u_int hsize; /* size of the hash table */ u_char hshift; /* used in hash function */ u_char n_bits; /* current bits/code */ u_char maxbits; u_char debug; u_char unit; u_short seqno; /* sequence number of next packet */ u_int hdrlen; /* header length to preallocate */ u_int mru; u_int maxmaxcode; /* largest valid code */ u_int max_ent; /* largest code in use */ u_int in_count; /* uncompressed bytes, aged */ u_int bytes_out; /* compressed bytes, aged */ u_int ratio; /* recent compression ratio */ u_int checkpoint; /* when to next check the ratio */ u_int clear_count; /* times dictionary cleared */ u_int incomp_count; /* incompressible packets */ u_int incomp_bytes; /* incompressible bytes */ u_int uncomp_count; /* uncompressed packets */ u_int uncomp_bytes; /* uncompressed bytes */ u_int comp_count; /* compressed packets */ u_int comp_bytes; /* compressed bytes */ u_short *lens; /* array of lengths of codes */ struct bsd_dict { union { /* hash value */ u_int32_t fcode; struct { #ifdef BSD_LITTLE_ENDIAN u_short prefix; /* preceding code */ u_char suffix; /* last character of new code */ u_char pad; #else u_char pad; u_char suffix; /* last character of new code */ u_short prefix; /* preceding code */ #endif } hs; } f; u_short codem1; /* output of hash table -1 */ u_short cptr; /* map code to hash table entry */ } dict[1]; }; #define BSD_OVHD 2 /* BSD compress overhead/packet */ #define BSD_INIT_BITS BSD_MIN_BITS static void *bsd_decomp_alloc(u_char *options, int opt_len); static void bsd_free(void *state); static int bsd_decomp_init(void *state, u_char *options, int opt_len, int unit, int hdrlen, int mru, int debug); static void bsd_incomp(void *state, u_char *dmsg, int len); static int bsd_decompress(void *state, u_char *cmp, int inlen, u_char *dmp, int *outlen); static void bsd_reset(void *state); static void bsd_comp_stats(void *state, struct compstat *stats); /* * Exported procedures. */ struct compressor ppp_bsd_compress = { CI_BSD_COMPRESS, /* compress_proto */ bsd_decomp_alloc, /* decomp_alloc */ bsd_free, /* decomp_free */ bsd_decomp_init, /* decomp_init */ bsd_reset, /* decomp_reset */ bsd_decompress, /* decompress */ bsd_incomp, /* incomp */ bsd_comp_stats, /* decomp_stat */ }; /* * the next two codes should not be changed lightly, as they must not * lie within the contiguous general code space. */ #define CLEAR 256 /* table clear output code */ #define FIRST 257 /* first free entry */ #define LAST 255 #define MAXCODE(b) ((1 << (b)) - 1) #define BADCODEM1 MAXCODE(BSD_MAX_BITS) #define BSD_HASH(prefix,suffix,hshift) ((((u_int32_t)(suffix)) << (hshift)) \ ^ (u_int32_t)(prefix)) #define BSD_KEY(prefix,suffix) ((((u_int32_t)(suffix)) << 16) \ + (u_int32_t)(prefix)) #define CHECK_GAP 10000 /* Ratio check interval */ #define RATIO_SCALE_LOG 8 #define RATIO_SCALE (1<>RATIO_SCALE_LOG) /* * clear the dictionary */ static void bsd_clear(struct bsd_db *db) { db->clear_count++; db->max_ent = FIRST-1; db->n_bits = BSD_INIT_BITS; db->ratio = 0; db->bytes_out = 0; db->in_count = 0; db->checkpoint = CHECK_GAP; } /* * If the dictionary is full, then see if it is time to reset it. * * Compute the compression ratio using fixed-point arithmetic * with 8 fractional bits. * * Since we have an infinite stream instead of a single file, * watch only the local compression ratio. * * Since both peers must reset the dictionary at the same time even in * the absence of CLEAR codes (while packets are incompressible), they * must compute the same ratio. */ static int /* 1=output CLEAR */ bsd_check(struct bsd_db *db) { u_int new_ratio; if (db->in_count >= db->checkpoint) { /* age the ratio by limiting the size of the counts */ if (db->in_count >= RATIO_MAX || db->bytes_out >= RATIO_MAX) { db->in_count -= db->in_count/4; db->bytes_out -= db->bytes_out/4; } db->checkpoint = db->in_count + CHECK_GAP; if (db->max_ent >= db->maxmaxcode) { /* Reset the dictionary only if the ratio is worse, * or if it looks as if it has been poisoned * by incompressible data. * * This does not overflow, because * db->in_count <= RATIO_MAX. */ new_ratio = db->in_count << RATIO_SCALE_LOG; if (db->bytes_out != 0) new_ratio /= db->bytes_out; if (new_ratio < db->ratio || new_ratio < 1 * RATIO_SCALE) { bsd_clear(db); return 1; } db->ratio = new_ratio; } } return 0; } /* * Return statistics. */ static void bsd_comp_stats(void *state, struct compstat *stats) { struct bsd_db *db = (struct bsd_db *) state; u_int out; stats->unc_bytes = db->uncomp_bytes; stats->unc_packets = db->uncomp_count; stats->comp_bytes = db->comp_bytes; stats->comp_packets = db->comp_count; stats->inc_bytes = db->incomp_bytes; stats->inc_packets = db->incomp_count; u_int ratio = db->in_count; out = db->bytes_out; if (ratio <= 0x7fffff) ratio <<= 8; else out >>= 8; if (out != 0) stats->ratio = ratio / out; } /* * Reset state, as on a CCP ResetReq. */ static void bsd_reset(void *state) { struct bsd_db *db = (struct bsd_db *) state; db->seqno = 0; bsd_clear(db); db->clear_count = 0; } /* * Allocate space for a (de) compressor. */ static void * bsd_alloc(u_char *options, int opt_len, int decomp) { int bits; u_int newlen, hsize, hshift, maxmaxcode; struct bsd_db *db; if (opt_len != 3 || options[0] != CI_BSD_COMPRESS || options[1] != 3 || BSD_VERSION(options[2]) != BSD_CURRENT_VERSION) return NULL; bits = BSD_NBITS(options[2]); switch (bits) { case 9: /* needs 82152 for both directions */ case 10: /* needs 84144 */ case 11: /* needs 88240 */ case 12: /* needs 96432 */ hsize = 5003; hshift = 4; break; case 13: /* needs 176784 */ hsize = 9001; hshift = 5; break; case 14: /* needs 353744 */ hsize = 18013; hshift = 6; break; case 15: /* needs 691440 */ hsize = 35023; hshift = 7; break; case 16: /* needs 1366160--far too much, */ /* hsize = 69001; */ /* and 69001 is too big for cptr */ /* hshift = 8; */ /* in struct bsd_db */ /* break; */ default: return NULL; } maxmaxcode = MAXCODE(bits); newlen = sizeof(*db) + (hsize-1) * (sizeof(db->dict[0])); db = (struct bsd_db *) malloc(newlen); if (!db) return NULL; memset(db, 0, sizeof(*db) - sizeof(db->dict)); if (!decomp) { db->lens = NULL; } else { db->lens = (u_short *) malloc((maxmaxcode+1) * sizeof(db->lens[0])); if (!db->lens) { free(db); return NULL; } } db->totlen = newlen; db->hsize = hsize; db->hshift = hshift; db->maxmaxcode = maxmaxcode; db->maxbits = bits; return (void *) db; } static void bsd_free(void *state) { struct bsd_db *db = (struct bsd_db *) state; if (db->lens) free(db->lens); free(db); } static void * bsd_decomp_alloc(u_char *options, int opt_len) { return bsd_alloc(options, opt_len, 1); } /* * Initialize the database. */ static int bsd_init(struct bsd_db *db, u_char *options, int opt_len, int unit, int hdrlen, int mru, int debug, int decomp) { int i; if (opt_len < CILEN_BSD_COMPRESS || options[0] != CI_BSD_COMPRESS || options[1] != CILEN_BSD_COMPRESS || BSD_VERSION(options[2]) != BSD_CURRENT_VERSION || BSD_NBITS(options[2]) != db->maxbits || (decomp && db->lens == NULL)) return 0; if (decomp) { i = LAST+1; while (i != 0) db->lens[--i] = 1; } i = db->hsize; while (i != 0) { db->dict[--i].codem1 = BADCODEM1; db->dict[i].cptr = 0; } db->unit = unit; db->hdrlen = hdrlen; db->mru = mru; if (debug) db->debug = 1; bsd_reset(db); return 1; } static int bsd_decomp_init(void *state, u_char *options, int opt_len, int unit, int hdrlen, int mru, int debug) { return bsd_init((struct bsd_db *) state, options, opt_len, unit, hdrlen, mru, debug, 1); } /* * Update the "BSD Compress" dictionary on the receiver for * incompressible data by pretending to compress the incoming data. */ static void bsd_incomp(void *state, u_char *dmsg, int mlen) { struct bsd_db *db = (struct bsd_db *) state; u_int hshift = db->hshift; u_int max_ent = db->max_ent; u_int n_bits = db->n_bits; struct bsd_dict *dictp; u_int32_t fcode; u_char c; long hval, disp; int slen, ilen; u_int bitno = 7; u_char *rptr; u_int ent; rptr = dmsg; ent = rptr[0]; /* get the protocol */ if (ent == 0) { ++rptr; --mlen; ent = rptr[0]; } if ((ent & 1) == 0 || ent < 0x21 || ent > 0xf9) return; db->seqno++; ilen = 1; /* count the protocol as 1 byte */ ++rptr; slen = dmsg + mlen - rptr; ilen += slen; for (; slen > 0; --slen) { c = *rptr++; fcode = BSD_KEY(ent, c); hval = BSD_HASH(ent, c, hshift); dictp = &db->dict[hval]; /* validate and then check the entry */ if (dictp->codem1 >= max_ent) goto nomatch; if (dictp->f.fcode == fcode) { ent = dictp->codem1+1; continue; /* found (prefix,suffix) */ } /* continue probing until a match or invalid entry */ disp = (hval == 0) ? 1 : hval; do { hval += disp; if (hval >= db->hsize) hval -= db->hsize; dictp = &db->dict[hval]; if (dictp->codem1 >= max_ent) goto nomatch; } while (dictp->f.fcode != fcode); ent = dictp->codem1+1; continue; /* finally found (prefix,suffix) */ nomatch: /* output (count) the prefix */ bitno += n_bits; /* code -> hashtable */ if (max_ent < db->maxmaxcode) { struct bsd_dict *dictp2; /* expand code size if needed */ if (max_ent >= MAXCODE(n_bits)) db->n_bits = ++n_bits; /* Invalidate previous hash table entry * assigned this code, and then take it over. */ dictp2 = &db->dict[max_ent+1]; if (db->dict[dictp2->cptr].codem1 == max_ent) db->dict[dictp2->cptr].codem1 = BADCODEM1; dictp2->cptr = hval; dictp->codem1 = max_ent; dictp->f.fcode = fcode; db->max_ent = ++max_ent; db->lens[max_ent] = db->lens[ent]+1; } ent = c; } bitno += n_bits; /* output (count) the last code */ db->bytes_out += bitno/8; db->in_count += ilen; (void)bsd_check(db); ++db->incomp_count; db->incomp_bytes += ilen; ++db->uncomp_count; db->uncomp_bytes += ilen; /* Increase code size if we would have without the packet * boundary and as the decompressor will. */ if (max_ent >= MAXCODE(n_bits) && max_ent < db->maxmaxcode) db->n_bits++; } /* * Decompress "BSD Compress" * * Because of patent problems, we return DECOMP_ERROR for errors * found by inspecting the input data and for system problems, but * DECOMP_FATALERROR for any errors which could possibly be said to * be being detected "after" decompression. For DECOMP_ERROR, * we can issue a CCP reset-request; for DECOMP_FATALERROR, we may be * infringing a patent of Motorola's if we do, so we take CCP down * instead. * * Given that the frame has the correct sequence number and a good FCS, * errors such as invalid codes in the input most likely indicate a * bug, so we return DECOMP_FATALERROR for them in order to turn off * compression, even though they are detected by inspecting the input. */ static int bsd_decompress(void *state, u_char *cmsg, int inlen, u_char *dmp, int *outlenp) { struct bsd_db *db = (struct bsd_db *) state; u_int max_ent = db->max_ent; u_int32_t accm = 0; u_int bitno = 32; /* 1st valid bit in accm */ u_int n_bits = db->n_bits; u_int tgtbitno = 32-n_bits; /* bitno when we have a code */ struct bsd_dict *dictp; int explen, seq, len; u_int incode, oldcode, finchar; u_char *p, *rptr, *wptr; int ilen; int codelen, extra; rptr = cmsg; if (*rptr == 0) ++rptr; ++rptr; /* skip protocol (assumed 0xfd) */ seq = (rptr[0] << 8) + rptr[1]; rptr += BSD_OVHD; ilen = len = cmsg + inlen - rptr; /* * Check the sequence number and give up if it is not what we expect. */ if (seq != db->seqno++) { if (db->debug) printf("bsd_decomp%d: bad sequence # %d, expected %d\n", db->unit, seq, db->seqno - 1); return DECOMP_ERROR; } wptr = dmp + db->hdrlen; oldcode = CLEAR; explen = 0; while (len > 0) { /* * Accumulate bytes until we have a complete code. * Then get the next code, relying on the 32-bit, * unsigned accm to mask the result. */ bitno -= 8; accm |= *rptr++ << bitno; --len; if (tgtbitno < bitno) continue; incode = accm >> tgtbitno; accm <<= n_bits; bitno += n_bits; if (incode == CLEAR) { /* * The dictionary must only be cleared at * the end of a packet. But there could be an * empty message block at the end. */ if (len > 0) { if (db->debug) printf("bsd_decomp%d: bad CLEAR\n", db->unit); return DECOMP_FATALERROR; } bsd_clear(db); explen = ilen = 0; break; } if (incode > max_ent + 2 || incode > db->maxmaxcode || (incode > max_ent && oldcode == CLEAR)) { if (db->debug) { printf("bsd_decomp%d: bad code 0x%x oldcode=0x%x ", db->unit, incode, oldcode); printf("max_ent=0x%x seqno=%d\n", max_ent, db->seqno); } return DECOMP_FATALERROR; /* probably a bug */ } /* Special case for KwKwK string. */ if (incode > max_ent) { finchar = oldcode; extra = 1; } else { finchar = incode; extra = 0; } codelen = db->lens[finchar]; explen += codelen + extra; if (explen > db->mru + 1) { if (db->debug) printf("bsd_decomp%d: ran out of mru\n", db->unit); return DECOMP_FATALERROR; } /* * Decode this code and install it in the decompressed buffer. */ p = (wptr += codelen); while (finchar > LAST) { dictp = &db->dict[db->dict[finchar].cptr]; #ifdef DEBUG --codelen; if (codelen <= 0) { printf("bsd_decomp%d: fell off end of chain ", db->unit); printf("0x%x at 0x%x by 0x%x, max_ent=0x%x\n", incode, finchar, db->dict[finchar].cptr, max_ent); return DECOMP_FATALERROR; } if (dictp->codem1 != finchar-1) { printf("bsd_decomp%d: bad code chain 0x%x finchar=0x%x ", db->unit, incode, finchar); printf("oldcode=0x%x cptr=0x%x codem1=0x%x\n", oldcode, db->dict[finchar].cptr, dictp->codem1); return DECOMP_FATALERROR; } #endif *--p = dictp->f.hs.suffix; finchar = dictp->f.hs.prefix; } *--p = finchar; #ifdef DEBUG if (--codelen != 0) printf("bsd_decomp%d: short by %d after code 0x%x, max_ent=0x%x\n", db->unit, codelen, incode, max_ent); #endif if (extra) /* the KwKwK case again */ *wptr++ = finchar; /* * If not first code in a packet, and * if not out of code space, then allocate a new code. * * Keep the hash table correct so it can be used * with uncompressed packets. */ if (oldcode != CLEAR && max_ent < db->maxmaxcode) { struct bsd_dict *dictp2; u_int32_t fcode; int hval, disp; fcode = BSD_KEY(oldcode,finchar); hval = BSD_HASH(oldcode,finchar,db->hshift); dictp = &db->dict[hval]; /* look for a free hash table entry */ if (dictp->codem1 < max_ent) { disp = (hval == 0) ? 1 : hval; do { hval += disp; if (hval >= db->hsize) hval -= db->hsize; dictp = &db->dict[hval]; } while (dictp->codem1 < max_ent); } /* * Invalidate previous hash table entry * assigned this code, and then take it over */ dictp2 = &db->dict[max_ent+1]; if (db->dict[dictp2->cptr].codem1 == max_ent) { db->dict[dictp2->cptr].codem1 = BADCODEM1; } dictp2->cptr = hval; dictp->codem1 = max_ent; dictp->f.fcode = fcode; db->max_ent = ++max_ent; db->lens[max_ent] = db->lens[oldcode]+1; /* Expand code size if needed. */ if (max_ent >= MAXCODE(n_bits) && max_ent < db->maxmaxcode) { db->n_bits = ++n_bits; tgtbitno = 32-n_bits; } } oldcode = incode; } *outlenp = wptr - (dmp + db->hdrlen); /* * Keep the checkpoint right so that incompressible packets * clear the dictionary at the right times. */ db->bytes_out += ilen; db->in_count += explen; if (bsd_check(db) && db->debug) { printf("bsd_decomp%d: peer should have cleared dictionary\n", db->unit); } ++db->comp_count; db->comp_bytes += ilen + BSD_OVHD; ++db->uncomp_count; db->uncomp_bytes += explen; return DECOMP_OK; } #endif /* DO_BSD_COMPRESS */ ppp-2.5.0/pppdump/deflate.c0000664000175000017500000002146714273050614012511 00000000000000/* * ppp_deflate.c - interface the zlib procedures for Deflate compression * and decompression (as used by gzip) to the PPP code. * * Copyright (c) 1994 Paul Mackerras. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The name(s) of the authors of this software must not be used to * endorse or promote products derived from this software without * prior written permission. * * 4. Redistributions of any form whatsoever must retain the following * acknowledgment: * "This product includes software developed by Paul Mackerras * ". * * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * $Id: deflate.c,v 1.5 2004/01/17 05:47:55 carlsonj Exp $ */ #include #include #include #include #include #include "ppp-comp.h" #include "zlib.h" #if DO_DEFLATE #define DEFLATE_DEBUG 1 /* * State for a Deflate (de)compressor. */ struct deflate_state { int seqno; int w_size; int unit; int hdrlen; int mru; int debug; z_stream strm; struct compstat stats; }; #define DEFLATE_OVHD 2 /* Deflate overhead/packet */ static void *z_alloc(void *, u_int items, u_int size); static void z_free(void *, void *ptr, u_int nb); static void *z_decomp_alloc(u_char *options, int opt_len); static void z_decomp_free(void *state); static int z_decomp_init(void *state, u_char *options, int opt_len, int unit, int hdrlen, int mru, int debug); static void z_incomp(void *state, u_char *dmsg, int len); static int z_decompress(void *state, u_char *cmp, int inlen, u_char *dmp, int *outlenp); static void z_decomp_reset(void *state); static void z_comp_stats(void *state, struct compstat *stats); /* * Procedures exported to if_ppp.c. */ struct compressor ppp_deflate = { CI_DEFLATE, /* compress_proto */ z_decomp_alloc, /* decomp_alloc */ z_decomp_free, /* decomp_free */ z_decomp_init, /* decomp_init */ z_decomp_reset, /* decomp_reset */ z_decompress, /* decompress */ z_incomp, /* incomp */ z_comp_stats, /* decomp_stat */ }; /* * Space allocation and freeing routines for use by zlib routines. */ static void * z_alloc(void *notused, u_int items, u_int size) { return malloc(items * size); } static void z_free(void *notused, void *ptr, u_int nbytes) { free(ptr); } static void z_comp_stats(void *arg, struct compstat *stats) { struct deflate_state *state = (struct deflate_state *) arg; u_int out; *stats = state->stats; stats->ratio = stats->unc_bytes; out = stats->comp_bytes + stats->unc_bytes; u_int ratio = stats->ratio; if (ratio <= 0x7ffffff) ratio <<= 8; else out >>= 8; if (out != 0) stats->ratio = ratio / out; } /* * Allocate space for a decompressor. */ static void * z_decomp_alloc(u_char *options, int opt_len) { struct deflate_state *state; int w_size; if (opt_len != CILEN_DEFLATE || options[0] != CI_DEFLATE || options[1] != CILEN_DEFLATE || DEFLATE_METHOD(options[2]) != DEFLATE_METHOD_VAL || options[3] != DEFLATE_CHK_SEQUENCE) return NULL; w_size = DEFLATE_SIZE(options[2]); if (w_size < DEFLATE_MIN_SIZE || w_size > DEFLATE_MAX_SIZE) return NULL; state = (struct deflate_state *) malloc(sizeof(*state)); if (state == NULL) return NULL; state->strm.next_out = NULL; state->strm.zalloc = (alloc_func) z_alloc; state->strm.zfree = (free_func) z_free; if (inflateInit2(&state->strm, -w_size) != Z_OK) { free(state); return NULL; } state->w_size = w_size; memset(&state->stats, 0, sizeof(state->stats)); return (void *) state; } static void z_decomp_free(void *arg) { struct deflate_state *state = (struct deflate_state *) arg; inflateEnd(&state->strm); free(state); } static int z_decomp_init(void *arg, u_char *options, int opt_len, int unit, int hdrlen, int mru, int debug) { struct deflate_state *state = (struct deflate_state *) arg; if (opt_len < CILEN_DEFLATE || options[0] != CI_DEFLATE || options[1] != CILEN_DEFLATE || DEFLATE_METHOD(options[2]) != DEFLATE_METHOD_VAL || DEFLATE_SIZE(options[2]) != state->w_size || options[3] != DEFLATE_CHK_SEQUENCE) return 0; state->seqno = 0; state->unit = unit; state->hdrlen = hdrlen; state->debug = debug; state->mru = mru; inflateReset(&state->strm); return 1; } static void z_decomp_reset(void *arg) { struct deflate_state *state = (struct deflate_state *) arg; state->seqno = 0; inflateReset(&state->strm); } /* * Decompress a Deflate-compressed packet. * * Because of patent problems, we return DECOMP_ERROR for errors * found by inspecting the input data and for system problems, but * DECOMP_FATALERROR for any errors which could possibly be said to * be being detected "after" decompression. For DECOMP_ERROR, * we can issue a CCP reset-request; for DECOMP_FATALERROR, we may be * infringing a patent of Motorola's if we do, so we take CCP down * instead. * * Given that the frame has the correct sequence number and a good FCS, * errors such as invalid codes in the input most likely indicate a * bug, so we return DECOMP_FATALERROR for them in order to turn off * compression, even though they are detected by inspecting the input. */ static int z_decompress(void *arg, u_char *mi, int inlen, u_char *mo, int *outlenp) { struct deflate_state *state = (struct deflate_state *) arg; u_char *rptr, *wptr; int rlen, olen; int seq, r; rptr = mi; if (*rptr == 0) ++rptr; ++rptr; /* Check the sequence number. */ seq = (rptr[0] << 8) + rptr[1]; rptr += 2; if (seq != state->seqno) { #if !DEFLATE_DEBUG if (state->debug) #endif printf("z_decompress%d: bad seq # %d, expected %d\n", state->unit, seq, state->seqno); return DECOMP_ERROR; } ++state->seqno; /* * Set up to call inflate. */ wptr = mo; state->strm.next_in = rptr; state->strm.avail_in = mi + inlen - rptr; rlen = state->strm.avail_in + PPP_HDRLEN + DEFLATE_OVHD; state->strm.next_out = wptr; state->strm.avail_out = state->mru + 2; r = inflate(&state->strm, Z_PACKET_FLUSH); if (r != Z_OK) { #if !DEFLATE_DEBUG if (state->debug) #endif printf("z_decompress%d: inflate returned %d (%s)\n", state->unit, r, (state->strm.msg? state->strm.msg: "")); return DECOMP_FATALERROR; } olen = state->mru + 2 - state->strm.avail_out; *outlenp = olen; if ((wptr[0] & 1) != 0) ++olen; /* for suppressed protocol high byte */ olen += 2; /* for address, control */ #if DEFLATE_DEBUG if (olen > state->mru + PPP_HDRLEN) printf("ppp_deflate%d: exceeded mru (%d > %d)\n", state->unit, olen, state->mru + PPP_HDRLEN); #endif state->stats.unc_bytes += olen; state->stats.unc_packets++; state->stats.comp_bytes += rlen; state->stats.comp_packets++; return DECOMP_OK; } /* * Incompressible data has arrived - add it to the history. */ static void z_incomp(void *arg, u_char *mi, int mlen) { struct deflate_state *state = (struct deflate_state *) arg; u_char *rptr; int rlen, proto, r; /* * Check that the protocol is one we handle. */ rptr = mi; proto = rptr[0]; if ((proto & 1) == 0) proto = (proto << 8) + rptr[1]; if (proto > 0x3fff || proto == 0xfd || proto == 0xfb) return; ++state->seqno; if (rptr[0] == 0) ++rptr; rlen = mi + mlen - rptr; state->strm.next_in = rptr; state->strm.avail_in = rlen; r = inflateIncomp(&state->strm); if (r != Z_OK) { /* gak! */ #if !DEFLATE_DEBUG if (state->debug) #endif printf("z_incomp%d: inflateIncomp returned %d (%s)\n", state->unit, r, (state->strm.msg? state->strm.msg: "")); return; } /* * Update stats. */ if (proto <= 0xff) ++rlen; rlen += 2; state->stats.inc_bytes += rlen; state->stats.inc_packets++; state->stats.unc_bytes += rlen; state->stats.unc_packets++; } #endif /* DO_DEFLATE */ ppp-2.5.0/pppdump/zlib.c0000644000175000017500000020121014407475306012035 00000000000000/* * This file is derived from various .h and .c files from the zlib-0.95 * distribution by Jean-loup Gailly and Mark Adler, with some additions * by Paul Mackerras to aid in implementing Deflate compression and * decompression for PPP packets. See zlib.h for conditions of * distribution and use. * * Changes that have been made include: * - changed functions not used outside this file to "local" * - added minCompression parameter to deflateInit2 * - added Z_PACKET_FLUSH (see zlib.h for details) * - added inflateIncomp * * $Id: zlib.c,v 1.2 1999/04/01 07:26:30 paulus Exp $ */ /*+++++*/ /* zutil.h -- internal interface and configuration of the compression library * Copyright (C) 1995 Jean-loup Gailly. * For conditions of distribution and use, see copyright notice in zlib.h */ /* WARNING: this file should *not* be used by applications. It is part of the implementation of the compression library and is subject to change. Applications should only use zlib.h. */ /* From: zutil.h,v 1.9 1995/05/03 17:27:12 jloup Exp */ #define _Z_UTIL_H #include "zlib.h" #ifdef STDC # include #endif #ifndef local # define local static #endif /* compile with -Dlocal if your debugger can't find static symbols */ #define FAR typedef unsigned char uch; typedef uch FAR uchf; typedef unsigned short ush; typedef ush FAR ushf; typedef unsigned long ulg; extern char *z_errmsg[]; /* indexed by 1-zlib_error */ #define ERR_RETURN(strm,err) return (strm->msg=z_errmsg[1-err], err) /* To be used only when the state is known to be valid */ #ifndef NULL #define NULL ((void *) 0) #endif /* common constants */ #define DEFLATED 8 #ifndef DEF_WBITS # define DEF_WBITS MAX_WBITS #endif /* default windowBits for decompression. MAX_WBITS is for compression only */ #if MAX_MEM_LEVEL >= 8 # define DEF_MEM_LEVEL 8 #else # define DEF_MEM_LEVEL MAX_MEM_LEVEL #endif /* default memLevel */ #define STORED_BLOCK 0 #define STATIC_TREES 1 #define DYN_TREES 2 /* The three kinds of block type */ #define MIN_MATCH 3 #define MAX_MATCH 258 /* The minimum and maximum match lengths */ /* functions */ #if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY) # define HAVE_MEMCPY #endif #ifdef HAVE_MEMCPY # define zmemcpy memcpy # define zmemzero(dest, len) memset(dest, 0, len) #else # define zmemcpy(d, s, n) bcopy((s), (d), (n)) # define zmemzero bzero #endif /* Diagnostic functions */ #ifdef DEBUG_ZLIB # include # ifndef verbose # define verbose 0 # endif # define Assert(cond,msg) {if(!(cond)) z_error(msg);} # define Trace(x) fprintf x # define Tracev(x) {if (verbose) fprintf x ;} # define Tracevv(x) {if (verbose>1) fprintf x ;} # define Tracec(c,x) {if (verbose && (c)) fprintf x ;} # define Tracecv(c,x) {if (verbose>1 && (c)) fprintf x ;} #else # define Assert(cond,msg) # define Trace(x) # define Tracev(x) # define Tracevv(x) # define Tracec(c,x) # define Tracecv(c,x) #endif typedef uLong (*check_func) OF((uLong check, Bytef *buf, uInt len)); /* voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size)); */ /* void zcfree OF((voidpf opaque, voidpf ptr)); */ #define ZALLOC(strm, items, size) \ (*((strm)->zalloc))((strm)->opaque, (items), (size)) #define ZFREE(strm, addr, size) \ (*((strm)->zfree))((strm)->opaque, (voidpf)(addr), (size)) #define TRY_FREE(s, p, n) {if (p) ZFREE(s, p, n);} /*+++++*/ /* infblock.h -- header to use infblock.c * Copyright (C) 1995 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ /* WARNING: this file should *not* be used by applications. It is part of the implementation of the compression library and is subject to change. Applications should only use zlib.h. */ struct inflate_blocks_state; typedef struct inflate_blocks_state FAR inflate_blocks_statef; local inflate_blocks_statef * inflate_blocks_new OF(( z_stream *z, check_func c, /* check function */ uInt w)); /* window size */ local int inflate_blocks OF(( inflate_blocks_statef *, z_stream *, int)); /* initial return code */ local void inflate_blocks_reset OF(( inflate_blocks_statef *, z_stream *, uLongf *)); /* check value on output */ local int inflate_blocks_free OF(( inflate_blocks_statef *, z_stream *, uLongf *)); /* check value on output */ local int inflate_addhistory OF(( inflate_blocks_statef *, z_stream *)); local int inflate_packet_flush OF(( inflate_blocks_statef *)); /*+++++*/ /* inftrees.h -- header to use inftrees.c * Copyright (C) 1995 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ /* WARNING: this file should *not* be used by applications. It is part of the implementation of the compression library and is subject to change. Applications should only use zlib.h. */ /* Huffman code lookup table entry--this entry is four bytes for machines that have 16-bit pointers (e.g. PC's in the small or medium model). */ typedef struct inflate_huft_s FAR inflate_huft; struct inflate_huft_s { union { struct { Byte Exop; /* number of extra bits or operation */ Byte Bits; /* number of bits in this code or subcode */ } what; uInt Nalloc; /* number of these allocated here */ Bytef *pad; /* pad structure to a power of 2 (4 bytes for */ } word; /* 16-bit, 8 bytes for 32-bit machines) */ union { uInt Base; /* literal, length base, or distance base */ inflate_huft *Next; /* pointer to next level of table */ } more; }; #ifdef DEBUG_ZLIB local uInt inflate_hufts; #endif local int inflate_trees_bits OF(( uIntf *, /* 19 code lengths */ uIntf *, /* bits tree desired/actual depth */ inflate_huft * FAR *, /* bits tree result */ z_stream *)); /* for zalloc, zfree functions */ local int inflate_trees_dynamic OF(( uInt, /* number of literal/length codes */ uInt, /* number of distance codes */ uIntf *, /* that many (total) code lengths */ uIntf *, /* literal desired/actual bit depth */ uIntf *, /* distance desired/actual bit depth */ inflate_huft * FAR *, /* literal/length tree result */ inflate_huft * FAR *, /* distance tree result */ z_stream *)); /* for zalloc, zfree functions */ local int inflate_trees_fixed OF(( uIntf *, /* literal desired/actual bit depth */ uIntf *, /* distance desired/actual bit depth */ inflate_huft * FAR *, /* literal/length tree result */ inflate_huft * FAR *)); /* distance tree result */ local int inflate_trees_free OF(( inflate_huft *, /* tables to free */ z_stream *)); /* for zfree function */ /*+++++*/ /* infcodes.h -- header to use infcodes.c * Copyright (C) 1995 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ /* WARNING: this file should *not* be used by applications. It is part of the implementation of the compression library and is subject to change. Applications should only use zlib.h. */ struct inflate_codes_state; typedef struct inflate_codes_state FAR inflate_codes_statef; local inflate_codes_statef *inflate_codes_new OF(( uInt, uInt, inflate_huft *, inflate_huft *, z_stream *)); local int inflate_codes OF(( inflate_blocks_statef *, z_stream *, int)); local void inflate_codes_free OF(( inflate_codes_statef *, z_stream *)); /*+++++*/ /* inflate.c -- zlib interface to inflate modules * Copyright (C) 1995 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ /* inflate private state */ struct internal_state { /* mode */ enum { METHOD, /* waiting for method byte */ FLAG, /* waiting for flag byte */ BLOCKS, /* decompressing blocks */ CHECK4, /* four check bytes to go */ CHECK3, /* three check bytes to go */ CHECK2, /* two check bytes to go */ CHECK1, /* one check byte to go */ DONE, /* finished check, done */ BAD} /* got an error--stay here */ mode; /* current inflate mode */ /* mode dependent information */ union { uInt method; /* if FLAGS, method byte */ struct { uLong was; /* computed check value */ uLong need; /* stream check value */ } check; /* if CHECK, check values to compare */ uInt marker; /* if BAD, inflateSync's marker bytes count */ } sub; /* submode */ /* mode independent information */ int nowrap; /* flag for no wrapper */ uInt wbits; /* log2(window size) (8..15, defaults to 15) */ inflate_blocks_statef *blocks; /* current inflate_blocks state */ }; int inflateReset(z) z_stream *z; { uLong c; if (z == Z_NULL || z->state == Z_NULL) return Z_STREAM_ERROR; z->total_in = z->total_out = 0; z->msg = Z_NULL; z->state->mode = z->state->nowrap ? BLOCKS : METHOD; inflate_blocks_reset(z->state->blocks, z, &c); Trace((stderr, "inflate: reset\n")); return Z_OK; } int inflateEnd(z) z_stream *z; { uLong c; if (z == Z_NULL || z->state == Z_NULL || z->zfree == Z_NULL) return Z_STREAM_ERROR; if (z->state->blocks != Z_NULL) inflate_blocks_free(z->state->blocks, z, &c); ZFREE(z, z->state, sizeof(struct internal_state)); z->state = Z_NULL; Trace((stderr, "inflate: end\n")); return Z_OK; } int inflateInit2(z, w) z_stream *z; int w; { /* initialize state */ if (z == Z_NULL) return Z_STREAM_ERROR; /* if (z->zalloc == Z_NULL) z->zalloc = zcalloc; */ /* if (z->zfree == Z_NULL) z->zfree = zcfree; */ if ((z->state = (struct internal_state FAR *) ZALLOC(z,1,sizeof(struct internal_state))) == Z_NULL) return Z_MEM_ERROR; z->state->blocks = Z_NULL; /* handle undocumented nowrap option (no zlib header or check) */ z->state->nowrap = 0; if (w < 0) { w = - w; z->state->nowrap = 1; } /* set window size */ if (w < 8 || w > 15) { inflateEnd(z); return Z_STREAM_ERROR; } z->state->wbits = (uInt)w; /* create inflate_blocks state */ if ((z->state->blocks = inflate_blocks_new(z, z->state->nowrap ? Z_NULL : adler32, 1 << w)) == Z_NULL) { inflateEnd(z); return Z_MEM_ERROR; } Trace((stderr, "inflate: allocated\n")); /* reset state */ inflateReset(z); return Z_OK; } int inflateInit(z) z_stream *z; { return inflateInit2(z, DEF_WBITS); } #define NEEDBYTE {if(z->avail_in==0)goto empty;r=Z_OK;} #define NEXTBYTE (z->avail_in--,z->total_in++,*z->next_in++) int inflate(z, f) z_stream *z; int f; { int r; uInt b; if (z == Z_NULL || z->next_in == Z_NULL) return Z_STREAM_ERROR; r = Z_BUF_ERROR; while (1) switch (z->state->mode) { case METHOD: NEEDBYTE if (((z->state->sub.method = NEXTBYTE) & 0xf) != DEFLATED) { z->state->mode = BAD; z->msg = "unknown compression method"; z->state->sub.marker = 5; /* can't try inflateSync */ break; } if ((z->state->sub.method >> 4) + 8 > z->state->wbits) { z->state->mode = BAD; z->msg = "invalid window size"; z->state->sub.marker = 5; /* can't try inflateSync */ break; } z->state->mode = FLAG; case FLAG: NEEDBYTE if ((b = NEXTBYTE) & 0x20) { z->state->mode = BAD; z->msg = "invalid reserved bit"; z->state->sub.marker = 5; /* can't try inflateSync */ break; } if (((z->state->sub.method << 8) + b) % 31) { z->state->mode = BAD; z->msg = "incorrect header check"; z->state->sub.marker = 5; /* can't try inflateSync */ break; } Trace((stderr, "inflate: zlib header ok\n")); z->state->mode = BLOCKS; case BLOCKS: r = inflate_blocks(z->state->blocks, z, r); if (f == Z_PACKET_FLUSH && z->avail_in == 0 && z->avail_out != 0) r = inflate_packet_flush(z->state->blocks); if (r == Z_DATA_ERROR) { z->state->mode = BAD; z->state->sub.marker = 0; /* can try inflateSync */ break; } if (r != Z_STREAM_END) return r; r = Z_OK; inflate_blocks_reset(z->state->blocks, z, &z->state->sub.check.was); if (z->state->nowrap) { z->state->mode = DONE; break; } z->state->mode = CHECK4; case CHECK4: NEEDBYTE z->state->sub.check.need = (uLong)NEXTBYTE << 24; z->state->mode = CHECK3; case CHECK3: NEEDBYTE z->state->sub.check.need += (uLong)NEXTBYTE << 16; z->state->mode = CHECK2; case CHECK2: NEEDBYTE z->state->sub.check.need += (uLong)NEXTBYTE << 8; z->state->mode = CHECK1; case CHECK1: NEEDBYTE z->state->sub.check.need += (uLong)NEXTBYTE; if (z->state->sub.check.was != z->state->sub.check.need) { z->state->mode = BAD; z->msg = "incorrect data check"; z->state->sub.marker = 5; /* can't try inflateSync */ break; } Trace((stderr, "inflate: zlib check ok\n")); z->state->mode = DONE; case DONE: return Z_STREAM_END; case BAD: return Z_DATA_ERROR; default: return Z_STREAM_ERROR; } empty: if (f != Z_PACKET_FLUSH) return r; z->state->mode = BAD; z->state->sub.marker = 0; /* can try inflateSync */ return Z_DATA_ERROR; } /* * This subroutine adds the data at next_in/avail_in to the output history * without performing any output. The output buffer must be "caught up"; * i.e. no pending output (hence s->read equals s->write), and the state must * be BLOCKS (i.e. we should be willing to see the start of a series of * BLOCKS). On exit, the output will also be caught up, and the checksum * will have been updated if need be. */ int inflateIncomp(z) z_stream *z; { if (z->state->mode != BLOCKS) return Z_DATA_ERROR; return inflate_addhistory(z->state->blocks, z); } int inflateSync(z) z_stream *z; { uInt n; /* number of bytes to look at */ Bytef *p; /* pointer to bytes */ uInt m; /* number of marker bytes found in a row */ uLong r, w; /* temporaries to save total_in and total_out */ /* set up */ if (z == Z_NULL || z->state == Z_NULL) return Z_STREAM_ERROR; if (z->state->mode != BAD) { z->state->mode = BAD; z->state->sub.marker = 0; } if ((n = z->avail_in) == 0) return Z_BUF_ERROR; p = z->next_in; m = z->state->sub.marker; /* search */ while (n && m < 4) { if (*p == (Byte)(m < 2 ? 0 : 0xff)) m++; else if (*p) m = 0; else m = 4 - m; p++, n--; } /* restore */ z->total_in += p - z->next_in; z->next_in = p; z->avail_in = n; z->state->sub.marker = m; /* return no joy or set up to restart on a new block */ if (m != 4) return Z_DATA_ERROR; r = z->total_in; w = z->total_out; inflateReset(z); z->total_in = r; z->total_out = w; z->state->mode = BLOCKS; return Z_OK; } #undef NEEDBYTE #undef NEXTBYTE /*+++++*/ /* infutil.h -- types and macros common to blocks and codes * Copyright (C) 1995 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ /* WARNING: this file should *not* be used by applications. It is part of the implementation of the compression library and is subject to change. Applications should only use zlib.h. */ /* inflate blocks semi-private state */ struct inflate_blocks_state { /* mode */ enum { TYPE, /* get type bits (3, including end bit) */ LENS, /* get lengths for stored */ STORED, /* processing stored block */ TABLE, /* get table lengths */ BTREE, /* get bit lengths tree for a dynamic block */ DTREE, /* get length, distance trees for a dynamic block */ CODES, /* processing fixed or dynamic block */ DRY, /* output remaining window bytes */ DONEB, /* finished last block, done */ BADB} /* got a data error--stuck here */ mode; /* current inflate_block mode */ /* mode dependent information */ union { uInt left; /* if STORED, bytes left to copy */ struct { uInt table; /* table lengths (14 bits) */ uInt index; /* index into blens (or border) */ uIntf *blens; /* bit lengths of codes */ uInt bb; /* bit length tree depth */ inflate_huft *tb; /* bit length decoding tree */ int nblens; /* # elements allocated at blens */ } trees; /* if DTREE, decoding info for trees */ struct { inflate_huft *tl, *td; /* trees to free */ inflate_codes_statef *codes; } decode; /* if CODES, current state */ } sub; /* submode */ uInt last; /* true if this block is the last block */ /* mode independent information */ uInt bitk; /* bits in bit buffer */ uLong bitb; /* bit buffer */ Bytef *window; /* sliding window */ Bytef *end; /* one byte after sliding window */ Bytef *read; /* window read pointer */ Bytef *write; /* window write pointer */ check_func checkfn; /* check function */ uLong check; /* check on output */ }; /* defines for inflate input/output */ /* update pointers and return */ #define UPDBITS {s->bitb=b;s->bitk=k;} #define UPDIN {z->avail_in=n;z->total_in+=p-z->next_in;z->next_in=p;} #define UPDOUT {s->write=q;} #define UPDATE {UPDBITS UPDIN UPDOUT} #define LEAVE {UPDATE return inflate_flush(s,z,r);} /* get bytes and bits */ #define LOADIN {p=z->next_in;n=z->avail_in;b=s->bitb;k=s->bitk;} #define NEEDBYTE {if(n)r=Z_OK;else LEAVE} #define NEXTBYTE (n--,*p++) #define NEEDBITS(j) {while(k<(j)){NEEDBYTE;b|=((uLong)NEXTBYTE)<>=(j);k-=(j);} /* output bytes */ #define WAVAIL (qread?s->read-q-1:s->end-q) #define LOADOUT {q=s->write;m=WAVAIL;} #define WRAP {if(q==s->end&&s->read!=s->window){q=s->window;m=WAVAIL;}} #define FLUSH {UPDOUT r=inflate_flush(s,z,r); LOADOUT} #define NEEDOUT {if(m==0){WRAP if(m==0){FLUSH WRAP if(m==0) LEAVE}}r=Z_OK;} #define OUTBYTE(a) {*q++=(Byte)(a);m--;} /* load local pointers */ #define LOAD {LOADIN LOADOUT} /* And'ing with mask[n] masks the lower n bits */ local uInt inflate_mask[] = { 0x0000, 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff, 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff }; /* copy as much as possible from the sliding window to the output area */ local int inflate_flush OF(( inflate_blocks_statef *, z_stream *, int)); /*+++++*/ /* inffast.h -- header to use inffast.c * Copyright (C) 1995 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ /* WARNING: this file should *not* be used by applications. It is part of the implementation of the compression library and is subject to change. Applications should only use zlib.h. */ local int inflate_fast OF(( uInt, uInt, inflate_huft *, inflate_huft *, inflate_blocks_statef *, z_stream *)); /*+++++*/ /* infblock.c -- interpret and process block types to last block * Copyright (C) 1995 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ /* Table for deflate from PKZIP's appnote.txt. */ local uInt border[] = { /* Order of the bit length code lengths */ 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; /* Notes beyond the 1.93a appnote.txt: 1. Distance pointers never point before the beginning of the output stream. 2. Distance pointers can point back across blocks, up to 32k away. 3. There is an implied maximum of 7 bits for the bit length table and 15 bits for the actual data. 4. If only one code exists, then it is encoded using one bit. (Zero would be more efficient, but perhaps a little confusing.) If two codes exist, they are coded using one bit each (0 and 1). 5. There is no way of sending zero distance codes--a dummy must be sent if there are none. (History: a pre 2.0 version of PKZIP would store blocks with no distance codes, but this was discovered to be too harsh a criterion.) Valid only for 1.93a. 2.04c does allow zero distance codes, which is sent as one code of zero bits in length. 6. There are up to 286 literal/length codes. Code 256 represents the end-of-block. Note however that the static length tree defines 288 codes just to fill out the Huffman codes. Codes 286 and 287 cannot be used though, since there is no length base or extra bits defined for them. Similarily, there are up to 30 distance codes. However, static trees define 32 codes (all 5 bits) to fill out the Huffman codes, but the last two had better not show up in the data. 7. Unzip can check dynamic Huffman blocks for complete code sets. The exception is that a single code would not be complete (see #4). 8. The five bits following the block type is really the number of literal codes sent minus 257. 9. Length codes 8,16,16 are interpreted as 13 length codes of 8 bits (1+6+6). Therefore, to output three times the length, you output three codes (1+1+1), whereas to output four times the same length, you only need two codes (1+3). Hmm. 10. In the tree reconstruction algorithm, Code = Code + Increment only if BitLength(i) is not zero. (Pretty obvious.) 11. Correction: 4 Bits: # of Bit Length codes - 4 (4 - 19) 12. Note: length code 284 can represent 227-258, but length code 285 really is 258. The last length deserves its own, short code since it gets used a lot in very redundant files. The length 258 is special since 258 - 3 (the min match length) is 255. 13. The literal/length and distance code bit lengths are read as a single stream of lengths. It is possible (and advantageous) for a repeat code (16, 17, or 18) to go across the boundary between the two sets of lengths. */ local void inflate_blocks_reset(s, z, c) inflate_blocks_statef *s; z_stream *z; uLongf *c; { if (s->checkfn != Z_NULL) *c = s->check; if (s->mode == BTREE || s->mode == DTREE) ZFREE(z, s->sub.trees.blens, s->sub.trees.nblens * sizeof(uInt)); if (s->mode == CODES) { inflate_codes_free(s->sub.decode.codes, z); inflate_trees_free(s->sub.decode.td, z); inflate_trees_free(s->sub.decode.tl, z); } s->mode = TYPE; s->bitk = 0; s->bitb = 0; s->read = s->write = s->window; if (s->checkfn != Z_NULL) s->check = (*s->checkfn)(0L, Z_NULL, 0); Trace((stderr, "inflate: blocks reset\n")); } local inflate_blocks_statef *inflate_blocks_new(z, c, w) z_stream *z; check_func c; uInt w; { inflate_blocks_statef *s; if ((s = (inflate_blocks_statef *)ZALLOC (z,1,sizeof(struct inflate_blocks_state))) == Z_NULL) return s; if ((s->window = (Bytef *)ZALLOC(z, 1, w)) == Z_NULL) { ZFREE(z, s, sizeof(struct inflate_blocks_state)); return Z_NULL; } s->end = s->window + w; s->checkfn = c; s->mode = TYPE; Trace((stderr, "inflate: blocks allocated\n")); inflate_blocks_reset(s, z, &s->check); return s; } local int inflate_blocks(s, z, r) inflate_blocks_statef *s; z_stream *z; int r; { uInt t; /* temporary storage */ uLong b; /* bit buffer */ uInt k; /* bits in bit buffer */ Bytef *p; /* input data pointer */ uInt n; /* bytes available there */ Bytef *q; /* output window write pointer */ uInt m; /* bytes to end of window or read pointer */ /* copy input/output information to locals (UPDATE macro restores) */ LOAD /* process input based on current state */ while (1) switch (s->mode) { case TYPE: NEEDBITS(3) t = (uInt)b & 7; s->last = t & 1; switch (t >> 1) { case 0: /* stored */ Trace((stderr, "inflate: stored block%s\n", s->last ? " (last)" : "")); DUMPBITS(3) t = k & 7; /* go to byte boundary */ DUMPBITS(t) s->mode = LENS; /* get length of stored block */ break; case 1: /* fixed */ Trace((stderr, "inflate: fixed codes block%s\n", s->last ? " (last)" : "")); { uInt bl, bd; inflate_huft *tl, *td; inflate_trees_fixed(&bl, &bd, &tl, &td); s->sub.decode.codes = inflate_codes_new(bl, bd, tl, td, z); if (s->sub.decode.codes == Z_NULL) { r = Z_MEM_ERROR; LEAVE } s->sub.decode.tl = Z_NULL; /* don't try to free these */ s->sub.decode.td = Z_NULL; } DUMPBITS(3) s->mode = CODES; break; case 2: /* dynamic */ Trace((stderr, "inflate: dynamic codes block%s\n", s->last ? " (last)" : "")); DUMPBITS(3) s->mode = TABLE; break; case 3: /* illegal */ DUMPBITS(3) s->mode = BADB; z->msg = "invalid block type"; r = Z_DATA_ERROR; LEAVE } break; case LENS: NEEDBITS(32) if (((~b) >> 16) != (b & 0xffff)) { s->mode = BADB; z->msg = "invalid stored block lengths"; r = Z_DATA_ERROR; LEAVE } s->sub.left = (uInt)b & 0xffff; b = k = 0; /* dump bits */ Tracev((stderr, "inflate: stored length %u\n", s->sub.left)); s->mode = s->sub.left ? STORED : TYPE; break; case STORED: if (n == 0) LEAVE NEEDOUT t = s->sub.left; if (t > n) t = n; if (t > m) t = m; zmemcpy(q, p, t); p += t; n -= t; q += t; m -= t; if ((s->sub.left -= t) != 0) break; Tracev((stderr, "inflate: stored end, %lu total out\n", z->total_out + (q >= s->read ? q - s->read : (s->end - s->read) + (q - s->window)))); s->mode = s->last ? DRY : TYPE; break; case TABLE: NEEDBITS(14) s->sub.trees.table = t = (uInt)b & 0x3fff; #ifndef PKZIP_BUG_WORKAROUND if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29) { s->mode = BADB; z->msg = "too many length or distance symbols"; r = Z_DATA_ERROR; LEAVE } #endif t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f); if (t < 19) t = 19; if ((s->sub.trees.blens = (uIntf*)ZALLOC(z, t, sizeof(uInt))) == Z_NULL) { r = Z_MEM_ERROR; LEAVE } s->sub.trees.nblens = t; DUMPBITS(14) s->sub.trees.index = 0; Tracev((stderr, "inflate: table sizes ok\n")); s->mode = BTREE; case BTREE: while (s->sub.trees.index < 4 + (s->sub.trees.table >> 10)) { NEEDBITS(3) s->sub.trees.blens[border[s->sub.trees.index++]] = (uInt)b & 7; DUMPBITS(3) } while (s->sub.trees.index < 19) s->sub.trees.blens[border[s->sub.trees.index++]] = 0; s->sub.trees.bb = 7; t = inflate_trees_bits(s->sub.trees.blens, &s->sub.trees.bb, &s->sub.trees.tb, z); if (t != Z_OK) { r = t; if (r == Z_DATA_ERROR) s->mode = BADB; LEAVE } s->sub.trees.index = 0; Tracev((stderr, "inflate: bits tree ok\n")); s->mode = DTREE; case DTREE: while (t = s->sub.trees.table, s->sub.trees.index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f)) { inflate_huft *h; uInt i, j, c; t = s->sub.trees.bb; NEEDBITS(t) h = s->sub.trees.tb + ((uInt)b & inflate_mask[t]); t = h->word.what.Bits; c = h->more.Base; if (c < 16) { DUMPBITS(t) s->sub.trees.blens[s->sub.trees.index++] = c; } else /* c == 16..18 */ { i = c == 18 ? 7 : c - 14; j = c == 18 ? 11 : 3; NEEDBITS(t + i) DUMPBITS(t) j += (uInt)b & inflate_mask[i]; DUMPBITS(i) i = s->sub.trees.index; t = s->sub.trees.table; if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) || (c == 16 && i < 1)) { s->mode = BADB; z->msg = "invalid bit length repeat"; r = Z_DATA_ERROR; LEAVE } c = c == 16 ? s->sub.trees.blens[i - 1] : 0; do { s->sub.trees.blens[i++] = c; } while (--j); s->sub.trees.index = i; } } inflate_trees_free(s->sub.trees.tb, z); s->sub.trees.tb = Z_NULL; { uInt bl, bd; inflate_huft *tl, *td; inflate_codes_statef *c; bl = 9; /* must be <= 9 for lookahead assumptions */ bd = 6; /* must be <= 9 for lookahead assumptions */ t = s->sub.trees.table; t = inflate_trees_dynamic(257 + (t & 0x1f), 1 + ((t >> 5) & 0x1f), s->sub.trees.blens, &bl, &bd, &tl, &td, z); if (t != Z_OK) { if (t == (uInt)Z_DATA_ERROR) s->mode = BADB; r = t; LEAVE } Tracev((stderr, "inflate: trees ok\n")); if ((c = inflate_codes_new(bl, bd, tl, td, z)) == Z_NULL) { inflate_trees_free(td, z); inflate_trees_free(tl, z); r = Z_MEM_ERROR; LEAVE } ZFREE(z, s->sub.trees.blens, s->sub.trees.nblens * sizeof(uInt)); s->sub.decode.codes = c; s->sub.decode.tl = tl; s->sub.decode.td = td; } s->mode = CODES; case CODES: UPDATE if ((r = inflate_codes(s, z, r)) != Z_STREAM_END) return inflate_flush(s, z, r); r = Z_OK; inflate_codes_free(s->sub.decode.codes, z); inflate_trees_free(s->sub.decode.td, z); inflate_trees_free(s->sub.decode.tl, z); LOAD Tracev((stderr, "inflate: codes end, %lu total out\n", z->total_out + (q >= s->read ? q - s->read : (s->end - s->read) + (q - s->window)))); if (!s->last) { s->mode = TYPE; break; } if (k > 7) /* return unused byte, if any */ { Assert(k < 16, "inflate_codes grabbed too many bytes") k -= 8; n++; p--; /* can always return one */ } s->mode = DRY; case DRY: FLUSH if (s->read != s->write) LEAVE s->mode = DONEB; case DONEB: r = Z_STREAM_END; LEAVE case BADB: r = Z_DATA_ERROR; LEAVE default: r = Z_STREAM_ERROR; LEAVE } } local int inflate_blocks_free(s, z, c) inflate_blocks_statef *s; z_stream *z; uLongf *c; { inflate_blocks_reset(s, z, c); ZFREE(z, s->window, s->end - s->window); ZFREE(z, s, sizeof(struct inflate_blocks_state)); Trace((stderr, "inflate: blocks freed\n")); return Z_OK; } /* * This subroutine adds the data at next_in/avail_in to the output history * without performing any output. The output buffer must be "caught up"; * i.e. no pending output (hence s->read equals s->write), and the state must * be BLOCKS (i.e. we should be willing to see the start of a series of * BLOCKS). On exit, the output will also be caught up, and the checksum * will have been updated if need be. */ local int inflate_addhistory(s, z) inflate_blocks_statef *s; z_stream *z; { uLong b; /* bit buffer */ /* NOT USED HERE */ uInt k; /* bits in bit buffer */ /* NOT USED HERE */ uInt t; /* temporary storage */ Bytef *p; /* input data pointer */ uInt n; /* bytes available there */ Bytef *q; /* output window write pointer */ uInt m; /* bytes to end of window or read pointer */ if (s->read != s->write) return Z_STREAM_ERROR; if (s->mode != TYPE) return Z_DATA_ERROR; /* we're ready to rock */ LOAD /* while there is input ready, copy to output buffer, moving * pointers as needed. */ while (n) { t = n; /* how many to do */ /* is there room until end of buffer? */ if (t > m) t = m; /* update check information */ if (s->checkfn != Z_NULL) s->check = (*s->checkfn)(s->check, q, t); zmemcpy(q, p, t); q += t; p += t; n -= t; z->total_out += t; s->read = q; /* drag read pointer forward */ /* WRAP */ /* expand WRAP macro by hand to handle s->read */ if (q == s->end) { s->read = q = s->window; m = WAVAIL; } } UPDATE return Z_OK; } /* * At the end of a Deflate-compressed PPP packet, we expect to have seen * a `stored' block type value but not the (zero) length bytes. */ local int inflate_packet_flush(s) inflate_blocks_statef *s; { if (s->mode != LENS) return Z_DATA_ERROR; s->mode = TYPE; return Z_OK; } /*+++++*/ /* inftrees.c -- generate Huffman trees for efficient decoding * Copyright (C) 1995 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ /* simplify the use of the inflate_huft type with some defines */ #define base more.Base #define next more.Next #define exop word.what.Exop #define bits word.what.Bits local int huft_build OF(( uIntf *, /* code lengths in bits */ uInt, /* number of codes */ uInt, /* number of "simple" codes */ uIntf *, /* list of base values for non-simple codes */ uIntf *, /* list of extra bits for non-simple codes */ inflate_huft * FAR*,/* result: starting table */ uIntf *, /* maximum lookup bits (returns actual) */ z_stream *)); /* for zalloc function */ local voidpf falloc OF(( voidpf, /* opaque pointer (not used) */ uInt, /* number of items */ uInt)); /* size of item */ local void ffree OF(( voidpf q, /* opaque pointer (not used) */ voidpf p, /* what to free (not used) */ uInt n)); /* number of bytes (not used) */ /* Tables for deflate from PKZIP's appnote.txt. */ local uInt cplens[] = { /* Copy lengths for literal codes 257..285 */ 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; /* actually lengths - 2; also see note #13 above about 258 */ local uInt cplext[] = { /* Extra bits for literal codes 257..285 */ 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 192, 192}; /* 192==invalid */ local uInt cpdist[] = { /* Copy offsets for distance codes 0..29 */ 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577}; local uInt cpdext[] = { /* Extra bits for distance codes */ 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13}; /* Huffman code decoding is performed using a multi-level table lookup. The fastest way to decode is to simply build a lookup table whose size is determined by the longest code. However, the time it takes to build this table can also be a factor if the data being decoded is not very long. The most common codes are necessarily the shortest codes, so those codes dominate the decoding time, and hence the speed. The idea is you can have a shorter table that decodes the shorter, more probable codes, and then point to subsidiary tables for the longer codes. The time it costs to decode the longer codes is then traded against the time it takes to make longer tables. This results of this trade are in the variables lbits and dbits below. lbits is the number of bits the first level table for literal/ length codes can decode in one step, and dbits is the same thing for the distance codes. Subsequent tables are also less than or equal to those sizes. These values may be adjusted either when all of the codes are shorter than that, in which case the longest code length in bits is used, or when the shortest code is *longer* than the requested table size, in which case the length of the shortest code in bits is used. There are two different values for the two tables, since they code a different number of possibilities each. The literal/length table codes 286 possible values, or in a flat code, a little over eight bits. The distance table codes 30 possible values, or a little less than five bits, flat. The optimum values for speed end up being about one bit more than those, so lbits is 8+1 and dbits is 5+1. The optimum values may differ though from machine to machine, and possibly even between compilers. Your mileage may vary. */ /* If BMAX needs to be larger than 16, then h and x[] should be uLong. */ #define BMAX 15 /* maximum bit length of any code */ #define N_MAX 288 /* maximum number of codes in any set */ #ifdef DEBUG_ZLIB uInt inflate_hufts; #endif local int huft_build(b, n, s, d, e, t, m, zs) uIntf *b; /* code lengths in bits (all assumed <= BMAX) */ uInt n; /* number of codes (assumed <= N_MAX) */ uInt s; /* number of simple-valued codes (0..s-1) */ uIntf *d; /* list of base values for non-simple codes */ uIntf *e; /* list of extra bits for non-simple codes */ inflate_huft * FAR *t; /* result: starting table */ uIntf *m; /* maximum lookup bits, returns actual */ z_stream *zs; /* for zalloc function */ /* Given a list of code lengths and a maximum table size, make a set of tables to decode that set of codes. Return Z_OK on success, Z_BUF_ERROR if the given code set is incomplete (the tables are still built in this case), Z_DATA_ERROR if the input is invalid (all zero length codes or an over-subscribed set of lengths), or Z_MEM_ERROR if not enough memory. */ { uInt a; /* counter for codes of length k */ uInt c[BMAX+1]; /* bit length count table */ uInt f; /* i repeats in table every f entries */ int g; /* maximum code length */ int h; /* table level */ register uInt i; /* counter, current code */ register uInt j; /* counter */ register int k; /* number of bits in current code */ int l; /* bits per table (returned in m) */ register uIntf *p; /* pointer into c[], b[], or v[] */ inflate_huft *q; /* points to current table */ struct inflate_huft_s r; /* table entry for structure assignment */ inflate_huft *u[BMAX]; /* table stack */ uInt v[N_MAX]; /* values in order of bit length */ register int w; /* bits before this table == (l * h) */ uInt x[BMAX+1]; /* bit offsets, then code stack */ uIntf *xp; /* pointer into x */ int y; /* number of dummy codes added */ uInt z; /* number of entries in current table */ /* Generate counts for each bit length */ p = c; #define C0 *p++ = 0; #define C2 C0 C0 C0 C0 #define C4 C2 C2 C2 C2 C4 /* clear c[]--assume BMAX+1 is 16 */ p = b; i = n; do { c[*p++]++; /* assume all entries <= BMAX */ } while (--i); if (c[0] == n) /* null input--all zero length codes */ { *t = (inflate_huft *)Z_NULL; *m = 0; return Z_OK; } /* Find minimum and maximum length, bound *m by those */ l = *m; for (j = 1; j <= BMAX; j++) if (c[j]) break; k = j; /* minimum code length */ if ((uInt)l < j) l = j; for (i = BMAX; i; i--) if (c[i]) break; g = i; /* maximum code length */ if ((uInt)l > i) l = i; *m = l; /* Adjust last length count to fill out codes, if needed */ for (y = 1 << j; j < i; j++, y <<= 1) if ((y -= c[j]) < 0) return Z_DATA_ERROR; if ((y -= c[i]) < 0) return Z_DATA_ERROR; c[i] += y; /* Generate starting offsets into the value table for each length */ x[1] = j = 0; p = c + 1; xp = x + 2; while (--i) { /* note that i == g from above */ *xp++ = (j += *p++); } /* Make a table of values in order of bit lengths */ p = b; i = 0; do { if ((j = *p++) != 0) v[x[j]++] = i; } while (++i < n); /* Generate the Huffman codes and for each, make the table entries */ x[0] = i = 0; /* first Huffman code is zero */ p = v; /* grab values in bit order */ h = -1; /* no tables yet--level -1 */ w = -l; /* bits decoded == (l * h) */ u[0] = (inflate_huft *)Z_NULL; /* just to keep compilers happy */ q = (inflate_huft *)Z_NULL; /* ditto */ z = 0; /* ditto */ /* go through the bit lengths (k already is bits in shortest code) */ for (; k <= g; k++) { a = c[k]; while (a--) { /* here i is the Huffman code of length k bits for value *p */ /* make tables up to required level */ while (k > w + l) { h++; w += l; /* previous table always l bits */ /* compute minimum size table less than or equal to l bits */ z = (z = g - w) > (uInt)l ? l : z; /* table size upper limit */ if ((f = 1 << (j = k - w)) > a + 1) /* try a k-w bit table */ { /* too few codes for k-w bit table */ f -= a + 1; /* deduct codes from patterns left */ xp = c + k; if (j < z) while (++j < z) /* try smaller tables up to z bits */ { if ((f <<= 1) <= *++xp) break; /* enough codes to use up j bits */ f -= *xp; /* else deduct codes from patterns */ } } z = 1 << j; /* table entries for j-bit table */ /* allocate and link in new table */ if ((q = (inflate_huft *)ZALLOC (zs,z + 1,sizeof(inflate_huft))) == Z_NULL) { if (h) inflate_trees_free(u[0], zs); return Z_MEM_ERROR; /* not enough memory */ } q->word.Nalloc = z + 1; #ifdef DEBUG_ZLIB inflate_hufts += z + 1; #endif *t = q + 1; /* link to list for huft_free() */ *(t = &(q->next)) = Z_NULL; u[h] = ++q; /* table starts after link */ /* connect to last table, if there is one */ if (h) { x[h] = i; /* save pattern for backing up */ r.bits = (Byte)l; /* bits to dump before this table */ r.exop = (Byte)j; /* bits in this table */ r.next = q; /* pointer to this table */ j = i >> (w - l); /* (get around Turbo C bug) */ u[h-1][j] = r; /* connect to last table */ } } /* set up table entry in r */ r.bits = (Byte)(k - w); if (p >= v + n) r.exop = 128 + 64; /* out of values--invalid code */ else if (*p < s) { r.exop = (Byte)(*p < 256 ? 0 : 32 + 64); /* 256 is end-of-block */ r.base = *p++; /* simple code is just the value */ } else { r.exop = (Byte)e[*p - s] + 16 + 64; /* non-simple--look up in lists */ r.base = d[*p++ - s]; } /* fill code-like entries with r */ f = 1 << (k - w); for (j = i >> w; j < z; j += f) q[j] = r; /* backwards increment the k-bit code i */ for (j = 1 << (k - 1); i & j; j >>= 1) i ^= j; i ^= j; /* backup over finished tables */ while ((i & ((1 << w) - 1)) != x[h]) { h--; /* don't need to update q */ w -= l; } } } /* Return Z_BUF_ERROR if we were given an incomplete table */ return y != 0 && g != 1 ? Z_BUF_ERROR : Z_OK; } local int inflate_trees_bits(c, bb, tb, z) uIntf *c; /* 19 code lengths */ uIntf *bb; /* bits tree desired/actual depth */ inflate_huft * FAR *tb; /* bits tree result */ z_stream *z; /* for zfree function */ { int r; r = huft_build(c, 19, 19, (uIntf*)Z_NULL, (uIntf*)Z_NULL, tb, bb, z); if (r == Z_DATA_ERROR) z->msg = "oversubscribed dynamic bit lengths tree"; else if (r == Z_BUF_ERROR) { inflate_trees_free(*tb, z); z->msg = "incomplete dynamic bit lengths tree"; r = Z_DATA_ERROR; } return r; } local int inflate_trees_dynamic(nl, nd, c, bl, bd, tl, td, z) uInt nl; /* number of literal/length codes */ uInt nd; /* number of distance codes */ uIntf *c; /* that many (total) code lengths */ uIntf *bl; /* literal desired/actual bit depth */ uIntf *bd; /* distance desired/actual bit depth */ inflate_huft * FAR *tl; /* literal/length tree result */ inflate_huft * FAR *td; /* distance tree result */ z_stream *z; /* for zfree function */ { int r; /* build literal/length tree */ if ((r = huft_build(c, nl, 257, cplens, cplext, tl, bl, z)) != Z_OK) { if (r == Z_DATA_ERROR) z->msg = "oversubscribed literal/length tree"; else if (r == Z_BUF_ERROR) { inflate_trees_free(*tl, z); z->msg = "incomplete literal/length tree"; r = Z_DATA_ERROR; } return r; } /* build distance tree */ if ((r = huft_build(c + nl, nd, 0, cpdist, cpdext, td, bd, z)) != Z_OK) { if (r == Z_DATA_ERROR) z->msg = "oversubscribed literal/length tree"; else if (r == Z_BUF_ERROR) { #ifdef PKZIP_BUG_WORKAROUND r = Z_OK; } #else inflate_trees_free(*td, z); z->msg = "incomplete literal/length tree"; r = Z_DATA_ERROR; } inflate_trees_free(*tl, z); return r; #endif } /* done */ return Z_OK; } /* build fixed tables only once--keep them here */ local int fixed_lock = 0; local int fixed_built = 0; #define FIXEDH 530 /* number of hufts used by fixed tables */ local uInt fixed_left = FIXEDH; local inflate_huft fixed_mem[FIXEDH]; local uInt fixed_bl; local uInt fixed_bd; local inflate_huft *fixed_tl; local inflate_huft *fixed_td; local voidpf falloc(q, n, s) voidpf q; /* opaque pointer (not used) */ uInt n; /* number of items */ uInt s; /* size of item */ { Assert(s == sizeof(inflate_huft) && n <= fixed_left, "inflate_trees falloc overflow"); if (q) s++; /* to make some compilers happy */ fixed_left -= n; return (voidpf)(fixed_mem + fixed_left); } local void ffree(q, p, n) voidpf q; voidpf p; uInt n; { Assert(0, "inflate_trees ffree called!"); if (q) q = p; /* to make some compilers happy */ } local int inflate_trees_fixed(bl, bd, tl, td) uIntf *bl; /* literal desired/actual bit depth */ uIntf *bd; /* distance desired/actual bit depth */ inflate_huft * FAR *tl; /* literal/length tree result */ inflate_huft * FAR *td; /* distance tree result */ { /* build fixed tables if not built already--lock out other instances */ while (++fixed_lock > 1) fixed_lock--; if (!fixed_built) { int k; /* temporary variable */ unsigned c[288]; /* length list for huft_build */ z_stream z; /* for falloc function */ /* set up fake z_stream for memory routines */ z.zalloc = falloc; z.zfree = ffree; z.opaque = Z_NULL; /* literal table */ for (k = 0; k < 144; k++) c[k] = 8; for (; k < 256; k++) c[k] = 9; for (; k < 280; k++) c[k] = 7; for (; k < 288; k++) c[k] = 8; fixed_bl = 7; huft_build(c, 288, 257, cplens, cplext, &fixed_tl, &fixed_bl, &z); /* distance table */ for (k = 0; k < 30; k++) c[k] = 5; fixed_bd = 5; huft_build(c, 30, 0, cpdist, cpdext, &fixed_td, &fixed_bd, &z); /* done */ fixed_built = 1; } fixed_lock--; *bl = fixed_bl; *bd = fixed_bd; *tl = fixed_tl; *td = fixed_td; return Z_OK; } local int inflate_trees_free(t, z) inflate_huft *t; /* table to free */ z_stream *z; /* for zfree function */ /* Free the malloc'ed tables built by huft_build(), which makes a linked list of the tables it made, with the links in a dummy first entry of each table. */ { register inflate_huft *p, *q; /* Go through linked list, freeing from the malloced (t[-1]) address. */ p = t; while (p != Z_NULL) { q = (--p)->next; ZFREE(z, p, p->word.Nalloc * sizeof(inflate_huft)); p = q; } return Z_OK; } /*+++++*/ /* infcodes.c -- process literals and length/distance pairs * Copyright (C) 1995 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ /* simplify the use of the inflate_huft type with some defines */ #define base more.Base #define next more.Next #define exop word.what.Exop #define bits word.what.Bits /* inflate codes private state */ struct inflate_codes_state { /* mode */ enum { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */ START, /* x: set up for LEN */ LEN, /* i: get length/literal/eob next */ LENEXT, /* i: getting length extra (have base) */ DIST, /* i: get distance next */ DISTEXT, /* i: getting distance extra */ COPY, /* o: copying bytes in window, waiting for space */ LIT, /* o: got literal, waiting for output space */ WASH, /* o: got eob, possibly still output waiting */ END, /* x: got eob and all data flushed */ BADCODE} /* x: got error */ mode; /* current inflate_codes mode */ /* mode dependent information */ uInt len; union { struct { inflate_huft *tree; /* pointer into tree */ uInt need; /* bits needed */ } code; /* if LEN or DIST, where in tree */ uInt lit; /* if LIT, literal */ struct { uInt get; /* bits to get for extra */ uInt dist; /* distance back to copy from */ } copy; /* if EXT or COPY, where and how much */ } sub; /* submode */ /* mode independent information */ Byte lbits; /* ltree bits decoded per branch */ Byte dbits; /* dtree bits decoder per branch */ inflate_huft *ltree; /* literal/length/eob tree */ inflate_huft *dtree; /* distance tree */ }; local inflate_codes_statef *inflate_codes_new(bl, bd, tl, td, z) uInt bl, bd; inflate_huft *tl, *td; z_stream *z; { inflate_codes_statef *c; if ((c = (inflate_codes_statef *) ZALLOC(z,1,sizeof(struct inflate_codes_state))) != Z_NULL) { c->mode = START; c->lbits = (Byte)bl; c->dbits = (Byte)bd; c->ltree = tl; c->dtree = td; Tracev((stderr, "inflate: codes new\n")); } return c; } local int inflate_codes(s, z, r) inflate_blocks_statef *s; z_stream *z; int r; { uInt j; /* temporary storage */ inflate_huft *t; /* temporary pointer */ uInt e; /* extra bits or operation */ uLong b; /* bit buffer */ uInt k; /* bits in bit buffer */ Bytef *p; /* input data pointer */ uInt n; /* bytes available there */ Bytef *q; /* output window write pointer */ uInt m; /* bytes to end of window or read pointer */ Bytef *f; /* pointer to copy strings from */ inflate_codes_statef *c = s->sub.decode.codes; /* codes state */ /* copy input/output information to locals (UPDATE macro restores) */ LOAD /* process input and output based on current state */ while (1) switch (c->mode) { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */ case START: /* x: set up for LEN */ #ifndef SLOW if (m >= 258 && n >= 10) { UPDATE r = inflate_fast(c->lbits, c->dbits, c->ltree, c->dtree, s, z); LOAD if (r != Z_OK) { c->mode = r == Z_STREAM_END ? WASH : BADCODE; break; } } #endif /* !SLOW */ c->sub.code.need = c->lbits; c->sub.code.tree = c->ltree; c->mode = LEN; case LEN: /* i: get length/literal/eob next */ j = c->sub.code.need; NEEDBITS(j) t = c->sub.code.tree + ((uInt)b & inflate_mask[j]); DUMPBITS(t->bits) e = (uInt)(t->exop); if (e == 0) /* literal */ { c->sub.lit = t->base; Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ? "inflate: literal '%c'\n" : "inflate: literal 0x%02x\n", t->base)); c->mode = LIT; break; } if (e & 16) /* length */ { c->sub.copy.get = e & 15; c->len = t->base; c->mode = LENEXT; break; } if ((e & 64) == 0) /* next table */ { c->sub.code.need = e; c->sub.code.tree = t->next; break; } if (e & 32) /* end of block */ { Tracevv((stderr, "inflate: end of block\n")); c->mode = WASH; break; } c->mode = BADCODE; /* invalid code */ z->msg = "invalid literal/length code"; r = Z_DATA_ERROR; LEAVE case LENEXT: /* i: getting length extra (have base) */ j = c->sub.copy.get; NEEDBITS(j) c->len += (uInt)b & inflate_mask[j]; DUMPBITS(j) c->sub.code.need = c->dbits; c->sub.code.tree = c->dtree; Tracevv((stderr, "inflate: length %u\n", c->len)); c->mode = DIST; case DIST: /* i: get distance next */ j = c->sub.code.need; NEEDBITS(j) t = c->sub.code.tree + ((uInt)b & inflate_mask[j]); DUMPBITS(t->bits) e = (uInt)(t->exop); if (e & 16) /* distance */ { c->sub.copy.get = e & 15; c->sub.copy.dist = t->base; c->mode = DISTEXT; break; } if ((e & 64) == 0) /* next table */ { c->sub.code.need = e; c->sub.code.tree = t->next; break; } c->mode = BADCODE; /* invalid code */ z->msg = "invalid distance code"; r = Z_DATA_ERROR; LEAVE case DISTEXT: /* i: getting distance extra */ j = c->sub.copy.get; NEEDBITS(j) c->sub.copy.dist += (uInt)b & inflate_mask[j]; DUMPBITS(j) Tracevv((stderr, "inflate: distance %u\n", c->sub.copy.dist)); c->mode = COPY; case COPY: /* o: copying bytes in window, waiting for space */ #ifndef __TURBOC__ /* Turbo C bug for following expression */ f = (uInt)(q - s->window) < c->sub.copy.dist ? s->end - (c->sub.copy.dist - (q - s->window)) : q - c->sub.copy.dist; #else f = q - c->sub.copy.dist; if ((uInt)(q - s->window) < c->sub.copy.dist) f = s->end - (c->sub.copy.dist - (q - s->window)); #endif while (c->len) { NEEDOUT OUTBYTE(*f++) if (f == s->end) f = s->window; c->len--; } c->mode = START; break; case LIT: /* o: got literal, waiting for output space */ NEEDOUT OUTBYTE(c->sub.lit) c->mode = START; break; case WASH: /* o: got eob, possibly more output */ FLUSH if (s->read != s->write) LEAVE c->mode = END; case END: r = Z_STREAM_END; LEAVE case BADCODE: /* x: got error */ r = Z_DATA_ERROR; LEAVE default: r = Z_STREAM_ERROR; LEAVE } } local void inflate_codes_free(c, z) inflate_codes_statef *c; z_stream *z; { ZFREE(z, c, sizeof(struct inflate_codes_state)); Tracev((stderr, "inflate: codes free\n")); } /*+++++*/ /* inflate_util.c -- data and routines common to blocks and codes * Copyright (C) 1995 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ /* copy as much as possible from the sliding window to the output area */ local int inflate_flush(s, z, r) inflate_blocks_statef *s; z_stream *z; int r; { uInt n; Bytef *p, *q; /* local copies of source and destination pointers */ p = z->next_out; q = s->read; /* compute number of bytes to copy as far as end of window */ n = (uInt)((q <= s->write ? s->write : s->end) - q); if (n > z->avail_out) n = z->avail_out; if (n && r == Z_BUF_ERROR) r = Z_OK; /* update counters */ z->avail_out -= n; z->total_out += n; /* update check information */ if (s->checkfn != Z_NULL) s->check = (*s->checkfn)(s->check, q, n); /* copy as far as end of window */ if (p != NULL) { zmemcpy(p, q, n); p += n; } q += n; /* see if more to copy at beginning of window */ if (q == s->end) { /* wrap pointers */ q = s->window; if (s->write == s->end) s->write = s->window; /* compute bytes to copy */ n = (uInt)(s->write - q); if (n > z->avail_out) n = z->avail_out; if (n && r == Z_BUF_ERROR) r = Z_OK; /* update counters */ z->avail_out -= n; z->total_out += n; /* update check information */ if (s->checkfn != Z_NULL) s->check = (*s->checkfn)(s->check, q, n); /* copy */ if (p != NULL) { zmemcpy(p, q, n); p += n; } q += n; } /* update pointers */ z->next_out = p; s->read = q; /* done */ return r; } /*+++++*/ /* inffast.c -- process literals and length/distance pairs fast * Copyright (C) 1995 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ /* simplify the use of the inflate_huft type with some defines */ #define base more.Base #define next more.Next #define exop word.what.Exop #define bits word.what.Bits /* macros for bit input with no checking and for returning unused bytes */ #define GRABBITS(j) {while(k<(j)){b|=((uLong)NEXTBYTE)<>3);p-=c;k&=7;} /* Called with number of bytes left to write in window at least 258 (the maximum string length) and number of input bytes available at least ten. The ten bytes are six bytes for the longest length/ distance pair plus four bytes for overloading the bit buffer. */ local int inflate_fast(bl, bd, tl, td, s, z) uInt bl, bd; inflate_huft *tl, *td; inflate_blocks_statef *s; z_stream *z; { inflate_huft *t; /* temporary pointer */ uInt e; /* extra bits or operation */ uLong b; /* bit buffer */ uInt k; /* bits in bit buffer */ Bytef *p; /* input data pointer */ uInt n; /* bytes available there */ Bytef *q; /* output window write pointer */ uInt m; /* bytes to end of window or read pointer */ uInt ml; /* mask for literal/length tree */ uInt md; /* mask for distance tree */ uInt c; /* bytes to copy */ uInt d; /* distance back to copy from */ Bytef *r; /* copy source pointer */ /* load input, output, bit values */ LOAD /* initialize masks */ ml = inflate_mask[bl]; md = inflate_mask[bd]; /* do until not enough input or output space for fast loop */ do { /* assume called with m >= 258 && n >= 10 */ /* get literal/length code */ GRABBITS(20) /* max bits for literal/length code */ if ((e = (t = tl + ((uInt)b & ml))->exop) == 0) { DUMPBITS(t->bits) Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ? "inflate: * literal '%c'\n" : "inflate: * literal 0x%02x\n", t->base)); *q++ = (Byte)t->base; m--; continue; } do { DUMPBITS(t->bits) if (e & 16) { /* get extra bits for length */ e &= 15; c = t->base + ((uInt)b & inflate_mask[e]); DUMPBITS(e) Tracevv((stderr, "inflate: * length %u\n", c)); /* decode distance base of block to copy */ GRABBITS(15); /* max bits for distance code */ e = (t = td + ((uInt)b & md))->exop; do { DUMPBITS(t->bits) if (e & 16) { /* get extra bits to add to distance base */ e &= 15; GRABBITS(e) /* get extra bits (up to 13) */ d = t->base + ((uInt)b & inflate_mask[e]); DUMPBITS(e) Tracevv((stderr, "inflate: * distance %u\n", d)); /* do the copy */ m -= c; if ((uInt)(q - s->window) >= d) /* offset before dest */ { /* just copy */ r = q - d; *q++ = *r++; c--; /* minimum count is three, */ *q++ = *r++; c--; /* so unroll loop a little */ } else /* else offset after destination */ { e = d - (q - s->window); /* bytes from offset to end */ r = s->end - e; /* pointer to offset */ if (c > e) /* if source crosses, */ { c -= e; /* copy to end of window */ do { *q++ = *r++; } while (--e); r = s->window; /* copy rest from start of window */ } } do { /* copy all or what's left */ *q++ = *r++; } while (--c); break; } else if ((e & 64) == 0) e = (t = t->next + ((uInt)b & inflate_mask[e]))->exop; else { z->msg = "invalid distance code"; UNGRAB UPDATE return Z_DATA_ERROR; } } while (1); break; } if ((e & 64) == 0) { if ((e = (t = t->next + ((uInt)b & inflate_mask[e]))->exop) == 0) { DUMPBITS(t->bits) Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ? "inflate: * literal '%c'\n" : "inflate: * literal 0x%02x\n", t->base)); *q++ = (Byte)t->base; m--; break; } } else if (e & 32) { Tracevv((stderr, "inflate: * end of block\n")); UNGRAB UPDATE return Z_STREAM_END; } else { z->msg = "invalid literal/length code"; UNGRAB UPDATE return Z_DATA_ERROR; } } while (1); } while (m >= 258 && n >= 10); /* not enough input or output--restore pointers and return */ UNGRAB UPDATE return Z_OK; } /*+++++*/ /* zutil.c -- target dependent utility functions for the compression library * Copyright (C) 1995 Jean-loup Gailly. * For conditions of distribution and use, see copyright notice in zlib.h */ /* From: zutil.c,v 1.8 1995/05/03 17:27:12 jloup Exp */ char *zlib_version = ZLIB_VERSION; char *z_errmsg[] = { "stream end", /* Z_STREAM_END 1 */ "", /* Z_OK 0 */ "file error", /* Z_ERRNO (-1) */ "stream error", /* Z_STREAM_ERROR (-2) */ "data error", /* Z_DATA_ERROR (-3) */ "insufficient memory", /* Z_MEM_ERROR (-4) */ "buffer error", /* Z_BUF_ERROR (-5) */ ""}; /*+++++*/ /* adler32.c -- compute the Adler-32 checksum of a data stream * Copyright (C) 1995 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ /* From: adler32.c,v 1.6 1995/05/03 17:27:08 jloup Exp */ #define BASE 65521L /* largest prime smaller than 65536 */ #define NMAX 5552 /* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */ #define DO1(buf) {s1 += *buf++; s2 += s1;} #define DO2(buf) DO1(buf); DO1(buf); #define DO4(buf) DO2(buf); DO2(buf); #define DO8(buf) DO4(buf); DO4(buf); #define DO16(buf) DO8(buf); DO8(buf); /* ========================================================================= */ uLong adler32(adler, buf, len) uLong adler; Bytef *buf; uInt len; { unsigned long s1 = adler & 0xffff; unsigned long s2 = (adler >> 16) & 0xffff; int k; if (buf == Z_NULL) return 1L; while (len > 0) { k = len < NMAX ? len : NMAX; len -= k; while (k >= 16) { DO16(buf); k -= 16; } if (k != 0) do { DO1(buf); } while (--k); s1 %= BASE; s2 %= BASE; } return (s2 << 16) | s1; } ppp-2.5.0/common/0000755000175000017500000000000014412736275010621 500000000000000ppp-2.5.0/common/Makefile.am0000664000175000017500000000011114076444143012564 00000000000000EXTRA_ZLIB = \ zlib.c \ zlib.h EXTRA_DIST = \ $(EXTRA_ZLIB) ppp-2.5.0/common/Makefile.in0000644000175000017500000003217014407475314012607 00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = common ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_atm.m4 \ $(top_srcdir)/m4/ax_check_openssl.m4 \ $(top_srcdir)/m4/ax_check_openssl_func.m4 \ $(top_srcdir)/m4/ax_check_pam.m4 \ $(top_srcdir)/m4/ax_check_pcap.m4 \ $(top_srcdir)/m4/ax_check_srp.m4 $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/pkg.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/pppd/config.h \ $(top_builddir)/pppd/pppdconf.h \ $(top_builddir)/pppd/plugins/pppoe/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) am__DIST_COMMON = $(srcdir)/Makefile.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ ATM_CFLAGS = @ATM_CFLAGS@ ATM_LDFLAGS = @ATM_LDFLAGS@ ATM_LIBS = @ATM_LIBS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CRYPT_LIBS = @CRYPT_LIBS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GREP = @GREP@ GTK_CFLAGS = @GTK_CFLAGS@ GTK_LIBS = @GTK_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_INCLUDES = @OPENSSL_INCLUDES@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAM_CFLAGS = @PAM_CFLAGS@ PAM_LDFLAGS = @PAM_LDFLAGS@ PAM_LIBS = @PAM_LIBS@ PATH_SEPARATOR = @PATH_SEPARATOR@ PCAP_CFLAGS = @PCAP_CFLAGS@ PCAP_LDFLAGS = @PCAP_LDFLAGS@ PCAP_LIBS = @PCAP_LIBS@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PPPD_LOGFILE_DIR = @PPPD_LOGFILE_DIR@ PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@ PPPD_RUNTIME_DIR = @PPPD_RUNTIME_DIR@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SRP_CFLAGS = @SRP_CFLAGS@ SRP_LDFLAGS = @SRP_LDFLAGS@ SRP_LIBS = @SRP_LIBS@ STRIP = @STRIP@ SYSTEMD_CFLAGS = @SYSTEMD_CFLAGS@ SYSTEMD_LIBS = @SYSTEMD_LIBS@ SYSTEM_CA_PATH = @SYSTEM_CA_PATH@ UTIL_LIBS = @UTIL_LIBS@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ EXTRA_ZLIB = \ zlib.c \ zlib.h EXTRA_DIST = \ $(EXTRA_ZLIB) all: all-am .SUFFIXES: $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu common/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu common/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs tags TAGS: ctags CTAGS: cscope cscopelist: distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic clean-libtool \ cscopelist-am ctags-am distclean distclean-generic \ distclean-libtool distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: ppp-2.5.0/common/zlib.c0000644000175000017500000053430507536353375011664 00000000000000/* * This file is derived from various .h and .c files from the zlib-1.0.4 * distribution by Jean-loup Gailly and Mark Adler, with some additions * by Paul Mackerras to aid in implementing Deflate compression and * decompression for PPP packets. See zlib.h for conditions of * distribution and use. * * Changes that have been made include: * - added Z_PACKET_FLUSH (see zlib.h for details) * - added inflateIncomp and deflateOutputPending * - allow strm->next_out to be NULL, meaning discard the output * * $Id: zlib.c,v 1.12 2002/04/02 13:34:03 dfs Exp $ */ /* * ==FILEVERSION 971210== * * This marker is used by the Linux installation script to determine * whether an up-to-date version of this file is already installed. */ #define NO_DUMMY_DECL #define NO_ZCFUNCS #define MY_ZCALLOC #if defined(__FreeBSD__) && (defined(KERNEL) || defined(_KERNEL)) #define inflate inflate_ppp /* FreeBSD already has an inflate :-( */ #endif /* +++ zutil.h */ /* zutil.h -- internal interface and configuration of the compression library * Copyright (C) 1995-1996 Jean-loup Gailly. * For conditions of distribution and use, see copyright notice in zlib.h */ /* WARNING: this file should *not* be used by applications. It is part of the implementation of the compression library and is subject to change. Applications should only use zlib.h. */ /* From: zutil.h,v 1.16 1996/07/24 13:41:13 me Exp $ */ #ifndef _Z_UTIL_H #define _Z_UTIL_H #include "zlib.h" #if defined(KERNEL) || defined(_KERNEL) /* Assume this is a *BSD or SVR4 kernel */ #include #include #include #undef u # define HAVE_MEMCPY # define memcpy(d, s, n) bcopy((s), (d), (n)) # define memset(d, v, n) bzero((d), (n)) # define memcmp bcmp #else #if defined(__KERNEL__) /* Assume this is a Linux kernel */ #include #define HAVE_MEMCPY #else /* not kernel */ #if defined(MSDOS)||defined(VMS)||defined(CRAY)||defined(WIN32)||defined(RISCOS) # include # include #else extern int errno; #endif #ifdef STDC # include # include #endif #endif /* __KERNEL__ */ #endif /* _KERNEL || KERNEL */ #ifndef local # define local static #endif /* compile with -Dlocal if your debugger can't find static symbols */ typedef unsigned char uch; typedef uch FAR uchf; typedef unsigned short ush; typedef ush FAR ushf; typedef unsigned long ulg; extern const char *z_errmsg[10]; /* indexed by 2-zlib_error */ /* (size given to avoid silly warnings with Visual C++) */ #define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)] #define ERR_RETURN(strm,err) \ return (strm->msg = (char*)ERR_MSG(err), (err)) /* To be used only when the state is known to be valid */ /* common constants */ #ifndef DEF_WBITS # define DEF_WBITS MAX_WBITS #endif /* default windowBits for decompression. MAX_WBITS is for compression only */ #if MAX_MEM_LEVEL >= 8 # define DEF_MEM_LEVEL 8 #else # define DEF_MEM_LEVEL MAX_MEM_LEVEL #endif /* default memLevel */ #define STORED_BLOCK 0 #define STATIC_TREES 1 #define DYN_TREES 2 /* The three kinds of block type */ #define MIN_MATCH 3 #define MAX_MATCH 258 /* The minimum and maximum match lengths */ #define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */ /* target dependencies */ #ifdef MSDOS # define OS_CODE 0x00 # ifdef __TURBOC__ # include # else /* MSC or DJGPP */ # include # endif #endif #ifdef OS2 # define OS_CODE 0x06 #endif #ifdef WIN32 /* Window 95 & Windows NT */ # define OS_CODE 0x0b #endif #if defined(VAXC) || defined(VMS) # define OS_CODE 0x02 # define FOPEN(name, mode) \ fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512") #endif #ifdef AMIGA # define OS_CODE 0x01 #endif #if defined(ATARI) || defined(atarist) # define OS_CODE 0x05 #endif #ifdef MACOS # define OS_CODE 0x07 #endif #ifdef __50SERIES /* Prime/PRIMOS */ # define OS_CODE 0x0F #endif #ifdef TOPS20 # define OS_CODE 0x0a #endif #if defined(_BEOS_) || defined(RISCOS) # define fdopen(fd,mode) NULL /* No fdopen() */ #endif /* Common defaults */ #ifndef OS_CODE # define OS_CODE 0x03 /* assume Unix */ #endif #ifndef FOPEN # define FOPEN(name, mode) fopen((name), (mode)) #endif /* functions */ #ifdef HAVE_STRERROR extern char *strerror OF((int)); # define zstrerror(errnum) strerror(errnum) #else # define zstrerror(errnum) "" #endif #if defined(pyr) # define NO_MEMCPY #endif #if (defined(M_I86SM) || defined(M_I86MM)) && !defined(_MSC_VER) /* Use our own functions for small and medium model with MSC <= 5.0. * You may have to use the same strategy for Borland C (untested). */ # define NO_MEMCPY #endif #if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY) # define HAVE_MEMCPY #endif #ifdef HAVE_MEMCPY # ifdef SMALL_MEDIUM /* MSDOS small or medium model */ # define zmemcpy _fmemcpy # define zmemcmp _fmemcmp # define zmemzero(dest, len) _fmemset(dest, 0, len) # else # define zmemcpy memcpy # define zmemcmp memcmp # define zmemzero(dest, len) memset(dest, 0, len) # endif #else extern void zmemcpy OF((Bytef* dest, Bytef* source, uInt len)); extern int zmemcmp OF((Bytef* s1, Bytef* s2, uInt len)); extern void zmemzero OF((Bytef* dest, uInt len)); #endif /* Diagnostic functions */ #ifdef DEBUG_ZLIB # include # ifndef verbose # define verbose 0 # endif extern void z_error OF((char *m)); # define Assert(cond,msg) {if(!(cond)) z_error(msg);} # define Trace(x) fprintf x # define Tracev(x) {if (verbose) fprintf x ;} # define Tracevv(x) {if (verbose>1) fprintf x ;} # define Tracec(c,x) {if (verbose && (c)) fprintf x ;} # define Tracecv(c,x) {if (verbose>1 && (c)) fprintf x ;} #else # define Assert(cond,msg) # define Trace(x) # define Tracev(x) # define Tracevv(x) # define Tracec(c,x) # define Tracecv(c,x) #endif typedef uLong (*check_func) OF((uLong check, const Bytef *buf, uInt len)); voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size)); void zcfree OF((voidpf opaque, voidpf ptr)); #define ZALLOC(strm, items, size) \ (*((strm)->zalloc))((strm)->opaque, (items), (size)) #define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr)) #define TRY_FREE(s, p) {if (p) ZFREE(s, p);} #endif /* _Z_UTIL_H */ /* --- zutil.h */ /* +++ deflate.h */ /* deflate.h -- internal compression state * Copyright (C) 1995-1996 Jean-loup Gailly * For conditions of distribution and use, see copyright notice in zlib.h */ /* WARNING: this file should *not* be used by applications. It is part of the implementation of the compression library and is subject to change. Applications should only use zlib.h. */ /* From: deflate.h,v 1.10 1996/07/02 12:41:00 me Exp $ */ #ifndef _DEFLATE_H #define _DEFLATE_H /* #include "zutil.h" */ /* =========================================================================== * Internal compression state. */ #define LENGTH_CODES 29 /* number of length codes, not counting the special END_BLOCK code */ #define LITERALS 256 /* number of literal bytes 0..255 */ #define L_CODES (LITERALS+1+LENGTH_CODES) /* number of Literal or Length codes, including the END_BLOCK code */ #define D_CODES 30 /* number of distance codes */ #define BL_CODES 19 /* number of codes used to transfer the bit lengths */ #define HEAP_SIZE (2*L_CODES+1) /* maximum heap size */ #define MAX_BITS 15 /* All codes must not exceed MAX_BITS bits */ #define INIT_STATE 42 #define BUSY_STATE 113 #define FINISH_STATE 666 /* Stream status */ /* Data structure describing a single value and its code string. */ typedef struct ct_data_s { union { ush freq; /* frequency count */ ush code; /* bit string */ } fc; union { ush dad; /* father node in Huffman tree */ ush len; /* length of bit string */ } dl; } FAR ct_data; #define Freq fc.freq #define Code fc.code #define Dad dl.dad #define Len dl.len typedef struct static_tree_desc_s static_tree_desc; typedef struct tree_desc_s { ct_data *dyn_tree; /* the dynamic tree */ int max_code; /* largest code with non zero frequency */ static_tree_desc *stat_desc; /* the corresponding static tree */ } FAR tree_desc; typedef ush Pos; typedef Pos FAR Posf; typedef unsigned IPos; /* A Pos is an index in the character window. We use short instead of int to * save space in the various tables. IPos is used only for parameter passing. */ typedef struct deflate_state { z_streamp strm; /* pointer back to this zlib stream */ int status; /* as the name implies */ Bytef *pending_buf; /* output still pending */ ulg pending_buf_size; /* size of pending_buf */ Bytef *pending_out; /* next pending byte to output to the stream */ int pending; /* nb of bytes in the pending buffer */ int noheader; /* suppress zlib header and adler32 */ Byte data_type; /* UNKNOWN, BINARY or ASCII */ Byte method; /* STORED (for zip only) or DEFLATED */ int last_flush; /* value of flush param for previous deflate call */ /* used by deflate.c: */ uInt w_size; /* LZ77 window size (32K by default) */ uInt w_bits; /* log2(w_size) (8..16) */ uInt w_mask; /* w_size - 1 */ Bytef *window; /* Sliding window. Input bytes are read into the second half of the window, * and move to the first half later to keep a dictionary of at least wSize * bytes. With this organization, matches are limited to a distance of * wSize-MAX_MATCH bytes, but this ensures that IO is always * performed with a length multiple of the block size. Also, it limits * the window size to 64K, which is quite useful on MSDOS. * To do: use the user input buffer as sliding window. */ ulg window_size; /* Actual size of window: 2*wSize, except when the user input buffer * is directly used as sliding window. */ Posf *prev; /* Link to older string with same hash index. To limit the size of this * array to 64K, this link is maintained only for the last 32K strings. * An index in this array is thus a window index modulo 32K. */ Posf *head; /* Heads of the hash chains or NIL. */ uInt ins_h; /* hash index of string to be inserted */ uInt hash_size; /* number of elements in hash table */ uInt hash_bits; /* log2(hash_size) */ uInt hash_mask; /* hash_size-1 */ uInt hash_shift; /* Number of bits by which ins_h must be shifted at each input * step. It must be such that after MIN_MATCH steps, the oldest * byte no longer takes part in the hash key, that is: * hash_shift * MIN_MATCH >= hash_bits */ long block_start; /* Window position at the beginning of the current output block. Gets * negative when the window is moved backwards. */ uInt match_length; /* length of best match */ IPos prev_match; /* previous match */ int match_available; /* set if previous match exists */ uInt strstart; /* start of string to insert */ uInt match_start; /* start of matching string */ uInt lookahead; /* number of valid bytes ahead in window */ uInt prev_length; /* Length of the best match at previous step. Matches not greater than this * are discarded. This is used in the lazy match evaluation. */ uInt max_chain_length; /* To speed up deflation, hash chains are never searched beyond this * length. A higher limit improves compression ratio but degrades the * speed. */ uInt max_lazy_match; /* Attempt to find a better match only when the current match is strictly * smaller than this value. This mechanism is used only for compression * levels >= 4. */ # define max_insert_length max_lazy_match /* Insert new strings in the hash table only if the match length is not * greater than this length. This saves time but degrades compression. * max_insert_length is used only for compression levels <= 3. */ int level; /* compression level (1..9) */ int strategy; /* favor or force Huffman coding*/ uInt good_match; /* Use a faster search when the previous match is longer than this */ int nice_match; /* Stop searching when current match exceeds this */ /* used by trees.c: */ /* Didn't use ct_data typedef below to supress compiler warning */ struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */ struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */ struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */ struct tree_desc_s l_desc; /* desc. for literal tree */ struct tree_desc_s d_desc; /* desc. for distance tree */ struct tree_desc_s bl_desc; /* desc. for bit length tree */ ush bl_count[MAX_BITS+1]; /* number of codes at each bit length for an optimal tree */ int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */ int heap_len; /* number of elements in the heap */ int heap_max; /* element of largest frequency */ /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used. * The same heap array is used to build all trees. */ uch depth[2*L_CODES+1]; /* Depth of each subtree used as tie breaker for trees of equal frequency */ uchf *l_buf; /* buffer for literals or lengths */ uInt lit_bufsize; /* Size of match buffer for literals/lengths. There are 4 reasons for * limiting lit_bufsize to 64K: * - frequencies can be kept in 16 bit counters * - if compression is not successful for the first block, all input * data is still in the window so we can still emit a stored block even * when input comes from standard input. (This can also be done for * all blocks if lit_bufsize is not greater than 32K.) * - if compression is not successful for a file smaller than 64K, we can * even emit a stored file instead of a stored block (saving 5 bytes). * This is applicable only for zip (not gzip or zlib). * - creating new Huffman trees less frequently may not provide fast * adaptation to changes in the input data statistics. (Take for * example a binary file with poorly compressible code followed by * a highly compressible string table.) Smaller buffer sizes give * fast adaptation but have of course the overhead of transmitting * trees more frequently. * - I can't count above 4 */ uInt last_lit; /* running index in l_buf */ ushf *d_buf; /* Buffer for distances. To simplify the code, d_buf and l_buf have * the same number of elements. To use different lengths, an extra flag * array would be necessary. */ ulg opt_len; /* bit length of current block with optimal trees */ ulg static_len; /* bit length of current block with static trees */ ulg compressed_len; /* total bit length of compressed file */ uInt matches; /* number of string matches in current block */ int last_eob_len; /* bit length of EOB code for last block */ #ifdef DEBUG_ZLIB ulg bits_sent; /* bit length of the compressed data */ #endif ush bi_buf; /* Output buffer. bits are inserted starting at the bottom (least * significant bits). */ int bi_valid; /* Number of valid bits in bi_buf. All bits above the last valid bit * are always zero. */ } FAR deflate_state; /* Output a byte on the stream. * IN assertion: there is enough room in pending_buf. */ #define put_byte(s, c) {s->pending_buf[s->pending++] = (c);} #define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1) /* Minimum amount of lookahead, except at the end of the input file. * See deflate.c for comments about the MIN_MATCH+1. */ #define MAX_DIST(s) ((s)->w_size-MIN_LOOKAHEAD) /* In order to simplify the code, particularly on 16 bit machines, match * distances are limited to MAX_DIST instead of WSIZE. */ /* in trees.c */ void _tr_init OF((deflate_state *s)); int _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc)); ulg _tr_flush_block OF((deflate_state *s, charf *buf, ulg stored_len, int eof)); void _tr_align OF((deflate_state *s)); void _tr_stored_block OF((deflate_state *s, charf *buf, ulg stored_len, int eof)); void _tr_stored_type_only OF((deflate_state *)); #endif /* --- deflate.h */ /* +++ deflate.c */ /* deflate.c -- compress data using the deflation algorithm * Copyright (C) 1995-1996 Jean-loup Gailly. * For conditions of distribution and use, see copyright notice in zlib.h */ /* * ALGORITHM * * The "deflation" process depends on being able to identify portions * of the input text which are identical to earlier input (within a * sliding window trailing behind the input currently being processed). * * The most straightforward technique turns out to be the fastest for * most input files: try all possible matches and select the longest. * The key feature of this algorithm is that insertions into the string * dictionary are very simple and thus fast, and deletions are avoided * completely. Insertions are performed at each input character, whereas * string matches are performed only when the previous match ends. So it * is preferable to spend more time in matches to allow very fast string * insertions and avoid deletions. The matching algorithm for small * strings is inspired from that of Rabin & Karp. A brute force approach * is used to find longer strings when a small match has been found. * A similar algorithm is used in comic (by Jan-Mark Wams) and freeze * (by Leonid Broukhis). * A previous version of this file used a more sophisticated algorithm * (by Fiala and Greene) which is guaranteed to run in linear amortized * time, but has a larger average cost, uses more memory and is patented. * However the F&G algorithm may be faster for some highly redundant * files if the parameter max_chain_length (described below) is too large. * * ACKNOWLEDGEMENTS * * The idea of lazy evaluation of matches is due to Jan-Mark Wams, and * I found it in 'freeze' written by Leonid Broukhis. * Thanks to many people for bug reports and testing. * * REFERENCES * * Deutsch, L.P.,"DEFLATE Compressed Data Format Specification". * Available in ftp://ds.internic.net/rfc/rfc1951.txt * * A description of the Rabin and Karp algorithm is given in the book * "Algorithms" by R. Sedgewick, Addison-Wesley, p252. * * Fiala,E.R., and Greene,D.H. * Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595 * */ /* From: deflate.c,v 1.15 1996/07/24 13:40:58 me Exp $ */ /* #include "deflate.h" */ char deflate_copyright[] = " deflate 1.0.4 Copyright 1995-1996 Jean-loup Gailly "; /* If you use the zlib library in a product, an acknowledgment is welcome in the documentation of your product. If for some reason you cannot include such an acknowledgment, I would appreciate that you keep this copyright string in the executable of your product. */ /* =========================================================================== * Function prototypes. */ typedef enum { need_more, /* block not completed, need more input or more output */ block_done, /* block flush performed */ finish_started, /* finish started, need only more output at next deflate */ finish_done /* finish done, accept no more input or output */ } block_state; typedef block_state (*compress_func) OF((deflate_state *s, int flush)); /* Compression function. Returns the block state after the call. */ local void fill_window OF((deflate_state *s)); local block_state deflate_stored OF((deflate_state *s, int flush)); local block_state deflate_fast OF((deflate_state *s, int flush)); local block_state deflate_slow OF((deflate_state *s, int flush)); local void lm_init OF((deflate_state *s)); local void putShortMSB OF((deflate_state *s, uInt b)); local void flush_pending OF((z_streamp strm)); local int read_buf OF((z_streamp strm, charf *buf, unsigned size)); #ifdef ASMV void match_init OF((void)); /* asm code initialization */ uInt longest_match OF((deflate_state *s, IPos cur_match)); #else local uInt longest_match OF((deflate_state *s, IPos cur_match)); #endif #ifdef DEBUG_ZLIB local void check_match OF((deflate_state *s, IPos start, IPos match, int length)); #endif /* =========================================================================== * Local data */ #define NIL 0 /* Tail of hash chains */ #ifndef TOO_FAR # define TOO_FAR 4096 #endif /* Matches of length 3 are discarded if their distance exceeds TOO_FAR */ #define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1) /* Minimum amount of lookahead, except at the end of the input file. * See deflate.c for comments about the MIN_MATCH+1. */ /* Values for max_lazy_match, good_match and max_chain_length, depending on * the desired pack level (0..9). The values given below have been tuned to * exclude worst case performance for pathological files. Better values may be * found for specific files. */ typedef struct config_s { ush good_length; /* reduce lazy search above this match length */ ush max_lazy; /* do not perform lazy search above this match length */ ush nice_length; /* quit search above this match length */ ush max_chain; compress_func func; } config; local config configuration_table[10] = { /* good lazy nice chain */ /* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */ /* 1 */ {4, 4, 8, 4, deflate_fast}, /* maximum speed, no lazy matches */ /* 2 */ {4, 5, 16, 8, deflate_fast}, /* 3 */ {4, 6, 32, 32, deflate_fast}, /* 4 */ {4, 4, 16, 16, deflate_slow}, /* lazy matches */ /* 5 */ {8, 16, 32, 32, deflate_slow}, /* 6 */ {8, 16, 128, 128, deflate_slow}, /* 7 */ {8, 32, 128, 256, deflate_slow}, /* 8 */ {32, 128, 258, 1024, deflate_slow}, /* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* maximum compression */ /* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4 * For deflate_fast() (levels <= 3) good is ignored and lazy has a different * meaning. */ #define EQUAL 0 /* result of memcmp for equal strings */ #ifndef NO_DUMMY_DECL struct static_tree_desc_s {int dummy;}; /* for buggy compilers */ #endif /* =========================================================================== * Update a hash value with the given input byte * IN assertion: all calls to to UPDATE_HASH are made with consecutive * input characters, so that a running hash key can be computed from the * previous key instead of complete recalculation each time. */ #define UPDATE_HASH(s,h,c) (h = (((h)<hash_shift) ^ (c)) & s->hash_mask) /* =========================================================================== * Insert string str in the dictionary and set match_head to the previous head * of the hash chain (the most recent string with same hash key). Return * the previous length of the hash chain. * IN assertion: all calls to to INSERT_STRING are made with consecutive * input characters and the first MIN_MATCH bytes of str are valid * (except for the last MIN_MATCH-1 bytes of the input file). */ #define INSERT_STRING(s, str, match_head) \ (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ s->prev[(str) & s->w_mask] = match_head = s->head[s->ins_h], \ s->head[s->ins_h] = (Pos)(str)) /* =========================================================================== * Initialize the hash table (avoiding 64K overflow for 16 bit systems). * prev[] will be initialized on the fly. */ #define CLEAR_HASH(s) \ s->head[s->hash_size-1] = NIL; \ zmemzero((charf *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head)); /* ========================================================================= */ int deflateInit_(strm, level, version, stream_size) z_streamp strm; int level; const char *version; int stream_size; { return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, version, stream_size); /* To do: ignore strm->next_in if we use it as window */ } /* ========================================================================= */ int deflateInit2_(strm, level, method, windowBits, memLevel, strategy, version, stream_size) z_streamp strm; int level; int method; int windowBits; int memLevel; int strategy; const char *version; int stream_size; { deflate_state *s; int noheader = 0; static char* my_version = ZLIB_VERSION; ushf *overlay; /* We overlay pending_buf and d_buf+l_buf. This works since the average * output size for (length,distance) codes is <= 24 bits. */ if (version == Z_NULL || version[0] != my_version[0] || stream_size != sizeof(z_stream)) { return Z_VERSION_ERROR; } if (strm == Z_NULL) return Z_STREAM_ERROR; strm->msg = Z_NULL; #ifndef NO_ZCFUNCS if (strm->zalloc == Z_NULL) { strm->zalloc = zcalloc; strm->opaque = (voidpf)0; } if (strm->zfree == Z_NULL) strm->zfree = zcfree; #endif if (level == Z_DEFAULT_COMPRESSION) level = 6; if (windowBits < 0) { /* undocumented feature: suppress zlib header */ noheader = 1; windowBits = -windowBits; } if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED || windowBits < 8 || windowBits > 15 || level < 0 || level > 9 || strategy < 0 || strategy > Z_HUFFMAN_ONLY) { return Z_STREAM_ERROR; } s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state)); if (s == Z_NULL) return Z_MEM_ERROR; strm->state = (struct internal_state FAR *)s; s->strm = strm; s->noheader = noheader; s->w_bits = windowBits; s->w_size = 1 << s->w_bits; s->w_mask = s->w_size - 1; s->hash_bits = memLevel + 7; s->hash_size = 1 << s->hash_bits; s->hash_mask = s->hash_size - 1; s->hash_shift = ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH); s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte)); s->prev = (Posf *) ZALLOC(strm, s->w_size, sizeof(Pos)); s->head = (Posf *) ZALLOC(strm, s->hash_size, sizeof(Pos)); s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */ overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2); s->pending_buf = (uchf *) overlay; s->pending_buf_size = (ulg)s->lit_bufsize * (sizeof(ush)+2L); if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL || s->pending_buf == Z_NULL) { strm->msg = (char*)ERR_MSG(Z_MEM_ERROR); deflateEnd (strm); return Z_MEM_ERROR; } s->d_buf = overlay + s->lit_bufsize/sizeof(ush); s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize; s->level = level; s->strategy = strategy; s->method = (Byte)method; return deflateReset(strm); } /* ========================================================================= */ int deflateSetDictionary (strm, dictionary, dictLength) z_streamp strm; const Bytef *dictionary; uInt dictLength; { deflate_state *s; uInt length = dictLength; uInt n; IPos hash_head = 0; if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL) return Z_STREAM_ERROR; s = (deflate_state *) strm->state; if (s->status != INIT_STATE) return Z_STREAM_ERROR; strm->adler = adler32(strm->adler, dictionary, dictLength); if (length < MIN_MATCH) return Z_OK; if (length > MAX_DIST(s)) { length = MAX_DIST(s); #ifndef USE_DICT_HEAD dictionary += dictLength - length; /* use the tail of the dictionary */ #endif } zmemcpy((charf *)s->window, dictionary, length); s->strstart = length; s->block_start = (long)length; /* Insert all strings in the hash table (except for the last two bytes). * s->lookahead stays null, so s->ins_h will be recomputed at the next * call of fill_window. */ s->ins_h = s->window[0]; UPDATE_HASH(s, s->ins_h, s->window[1]); for (n = 0; n <= length - MIN_MATCH; n++) { INSERT_STRING(s, n, hash_head); } if (hash_head) hash_head = 0; /* to make compiler happy */ return Z_OK; } /* ========================================================================= */ int deflateReset (strm) z_streamp strm; { deflate_state *s; if (strm == Z_NULL || strm->state == Z_NULL || strm->zalloc == Z_NULL || strm->zfree == Z_NULL) return Z_STREAM_ERROR; strm->total_in = strm->total_out = 0; strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */ strm->data_type = Z_UNKNOWN; s = (deflate_state *)strm->state; s->pending = 0; s->pending_out = s->pending_buf; if (s->noheader < 0) { s->noheader = 0; /* was set to -1 by deflate(..., Z_FINISH); */ } s->status = s->noheader ? BUSY_STATE : INIT_STATE; strm->adler = 1; s->last_flush = Z_NO_FLUSH; _tr_init(s); lm_init(s); return Z_OK; } /* ========================================================================= */ int deflateParams(strm, level, strategy) z_streamp strm; int level; int strategy; { deflate_state *s; compress_func func; int err = Z_OK; if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; s = (deflate_state *) strm->state; if (level == Z_DEFAULT_COMPRESSION) { level = 6; } if (level < 0 || level > 9 || strategy < 0 || strategy > Z_HUFFMAN_ONLY) { return Z_STREAM_ERROR; } func = configuration_table[s->level].func; if (func != configuration_table[level].func && strm->total_in != 0) { /* Flush the last buffer: */ err = deflate(strm, Z_PARTIAL_FLUSH); } if (s->level != level) { s->level = level; s->max_lazy_match = configuration_table[level].max_lazy; s->good_match = configuration_table[level].good_length; s->nice_match = configuration_table[level].nice_length; s->max_chain_length = configuration_table[level].max_chain; } s->strategy = strategy; return err; } /* ========================================================================= * Put a short in the pending buffer. The 16-bit value is put in MSB order. * IN assertion: the stream state is correct and there is enough room in * pending_buf. */ local void putShortMSB (s, b) deflate_state *s; uInt b; { put_byte(s, (Byte)(b >> 8)); put_byte(s, (Byte)(b & 0xff)); } /* ========================================================================= * Flush as much pending output as possible. All deflate() output goes * through this function so some applications may wish to modify it * to avoid allocating a large strm->next_out buffer and copying into it. * (See also read_buf()). */ local void flush_pending(strm) z_streamp strm; { deflate_state *s = (deflate_state *) strm->state; unsigned len = s->pending; if (len > strm->avail_out) len = strm->avail_out; if (len == 0) return; if (strm->next_out != Z_NULL) { zmemcpy(strm->next_out, s->pending_out, len); strm->next_out += len; } s->pending_out += len; strm->total_out += len; strm->avail_out -= len; s->pending -= len; if (s->pending == 0) { s->pending_out = s->pending_buf; } } /* ========================================================================= */ int deflate (strm, flush) z_streamp strm; int flush; { int old_flush; /* value of flush param for previous deflate call */ deflate_state *s; if (strm == Z_NULL || strm->state == Z_NULL || flush > Z_FINISH || flush < 0) { return Z_STREAM_ERROR; } s = (deflate_state *) strm->state; if ((strm->next_in == Z_NULL && strm->avail_in != 0) || (s->status == FINISH_STATE && flush != Z_FINISH)) { ERR_RETURN(strm, Z_STREAM_ERROR); } if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR); s->strm = strm; /* just in case */ old_flush = s->last_flush; s->last_flush = flush; /* Write the zlib header */ if (s->status == INIT_STATE) { uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8; uInt level_flags = (s->level-1) >> 1; if (level_flags > 3) level_flags = 3; header |= (level_flags << 6); if (s->strstart != 0) header |= PRESET_DICT; header += 31 - (header % 31); s->status = BUSY_STATE; putShortMSB(s, header); /* Save the adler32 of the preset dictionary: */ if (s->strstart != 0) { putShortMSB(s, (uInt)(strm->adler >> 16)); putShortMSB(s, (uInt)(strm->adler & 0xffff)); } strm->adler = 1L; } /* Flush as much pending output as possible */ if (s->pending != 0) { flush_pending(strm); if (strm->avail_out == 0) { /* Since avail_out is 0, deflate will be called again with * more output space, but possibly with both pending and * avail_in equal to zero. There won't be anything to do, * but this is not an error situation so make sure we * return OK instead of BUF_ERROR at next call of deflate: */ s->last_flush = -1; return Z_OK; } /* Make sure there is something to do and avoid duplicate consecutive * flushes. For repeated and useless calls with Z_FINISH, we keep * returning Z_STREAM_END instead of Z_BUFF_ERROR. */ } else if (strm->avail_in == 0 && flush <= old_flush && flush != Z_FINISH) { ERR_RETURN(strm, Z_BUF_ERROR); } /* User must not provide more input after the first FINISH: */ if (s->status == FINISH_STATE && strm->avail_in != 0) { ERR_RETURN(strm, Z_BUF_ERROR); } /* Start a new block or continue the current one. */ if (strm->avail_in != 0 || s->lookahead != 0 || (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) { block_state bstate; bstate = (*(configuration_table[s->level].func))(s, flush); if (bstate == finish_started || bstate == finish_done) { s->status = FINISH_STATE; } if (bstate == need_more || bstate == finish_started) { if (strm->avail_out == 0) { s->last_flush = -1; /* avoid BUF_ERROR next call, see above */ } return Z_OK; /* If flush != Z_NO_FLUSH && avail_out == 0, the next call * of deflate should use the same flush parameter to make sure * that the flush is complete. So we don't have to output an * empty block here, this will be done at next call. This also * ensures that for a very small output buffer, we emit at most * one empty block. */ } if (bstate == block_done) { if (flush == Z_PARTIAL_FLUSH) { _tr_align(s); } else if (flush == Z_PACKET_FLUSH) { /* Output just the 3-bit `stored' block type value, but not a zero length. */ _tr_stored_type_only(s); } else { /* FULL_FLUSH or SYNC_FLUSH */ _tr_stored_block(s, (char*)0, 0L, 0); /* For a full flush, this empty block will be recognized * as a special marker by inflate_sync(). */ if (flush == Z_FULL_FLUSH) { CLEAR_HASH(s); /* forget history */ } } flush_pending(strm); if (strm->avail_out == 0) { s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */ return Z_OK; } } } Assert(strm->avail_out > 0, "bug2"); if (flush != Z_FINISH) return Z_OK; if (s->noheader) return Z_STREAM_END; /* Write the zlib trailer (adler32) */ putShortMSB(s, (uInt)(strm->adler >> 16)); putShortMSB(s, (uInt)(strm->adler & 0xffff)); flush_pending(strm); /* If avail_out is zero, the application will call deflate again * to flush the rest. */ s->noheader = -1; /* write the trailer only once! */ return s->pending != 0 ? Z_OK : Z_STREAM_END; } /* ========================================================================= */ int deflateEnd (strm) z_streamp strm; { int status; deflate_state *s; if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; s = (deflate_state *) strm->state; status = s->status; if (status != INIT_STATE && status != BUSY_STATE && status != FINISH_STATE) { return Z_STREAM_ERROR; } /* Deallocate in reverse order of allocations: */ TRY_FREE(strm, s->pending_buf); TRY_FREE(strm, s->head); TRY_FREE(strm, s->prev); TRY_FREE(strm, s->window); ZFREE(strm, s); strm->state = Z_NULL; return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK; } /* ========================================================================= * Copy the source state to the destination state. */ int deflateCopy (dest, source) z_streamp dest; z_streamp source; { deflate_state *ds; deflate_state *ss; ushf *overlay; if (source == Z_NULL || dest == Z_NULL || source->state == Z_NULL) return Z_STREAM_ERROR; ss = (deflate_state *) source->state; zmemcpy(dest, source, sizeof(*dest)); ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state)); if (ds == Z_NULL) return Z_MEM_ERROR; dest->state = (struct internal_state FAR *) ds; zmemcpy(ds, ss, sizeof(*ds)); ds->strm = dest; ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte)); ds->prev = (Posf *) ZALLOC(dest, ds->w_size, sizeof(Pos)); ds->head = (Posf *) ZALLOC(dest, ds->hash_size, sizeof(Pos)); overlay = (ushf *) ZALLOC(dest, ds->lit_bufsize, sizeof(ush)+2); ds->pending_buf = (uchf *) overlay; if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL || ds->pending_buf == Z_NULL) { deflateEnd (dest); return Z_MEM_ERROR; } /* ??? following zmemcpy doesn't work for 16-bit MSDOS */ zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte)); zmemcpy(ds->prev, ss->prev, ds->w_size * sizeof(Pos)); zmemcpy(ds->head, ss->head, ds->hash_size * sizeof(Pos)); zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size); ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf); ds->d_buf = overlay + ds->lit_bufsize/sizeof(ush); ds->l_buf = ds->pending_buf + (1+sizeof(ush))*ds->lit_bufsize; ds->l_desc.dyn_tree = ds->dyn_ltree; ds->d_desc.dyn_tree = ds->dyn_dtree; ds->bl_desc.dyn_tree = ds->bl_tree; return Z_OK; } /* =========================================================================== * Return the number of bytes of output which are immediately available * for output from the decompressor. */ int deflateOutputPending (strm) z_streamp strm; { if (strm == Z_NULL || strm->state == Z_NULL) return 0; return ((deflate_state *)(strm->state))->pending; } /* =========================================================================== * Read a new buffer from the current input stream, update the adler32 * and total number of bytes read. All deflate() input goes through * this function so some applications may wish to modify it to avoid * allocating a large strm->next_in buffer and copying from it. * (See also flush_pending()). */ local int read_buf(strm, buf, size) z_streamp strm; charf *buf; unsigned size; { unsigned len = strm->avail_in; if (len > size) len = size; if (len == 0) return 0; strm->avail_in -= len; if (!((deflate_state *)(strm->state))->noheader) { strm->adler = adler32(strm->adler, strm->next_in, len); } zmemcpy(buf, strm->next_in, len); strm->next_in += len; strm->total_in += len; return (int)len; } /* =========================================================================== * Initialize the "longest match" routines for a new zlib stream */ local void lm_init (s) deflate_state *s; { s->window_size = (ulg)2L*s->w_size; CLEAR_HASH(s); /* Set the default configuration parameters: */ s->max_lazy_match = configuration_table[s->level].max_lazy; s->good_match = configuration_table[s->level].good_length; s->nice_match = configuration_table[s->level].nice_length; s->max_chain_length = configuration_table[s->level].max_chain; s->strstart = 0; s->block_start = 0L; s->lookahead = 0; s->match_length = s->prev_length = MIN_MATCH-1; s->match_available = 0; s->ins_h = 0; #ifdef ASMV match_init(); /* initialize the asm code */ #endif } /* =========================================================================== * Set match_start to the longest match starting at the given string and * return its length. Matches shorter or equal to prev_length are discarded, * in which case the result is equal to prev_length and match_start is * garbage. * IN assertions: cur_match is the head of the hash chain for the current * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1 * OUT assertion: the match length is not greater than s->lookahead. */ #ifndef ASMV /* For 80x86 and 680x0, an optimized version will be provided in match.asm or * match.S. The code will be functionally equivalent. */ local uInt longest_match(s, cur_match) deflate_state *s; IPos cur_match; /* current match */ { unsigned chain_length = s->max_chain_length;/* max hash chain length */ register Bytef *scan = s->window + s->strstart; /* current string */ register Bytef *match; /* matched string */ register int len; /* length of current match */ int best_len = s->prev_length; /* best match length so far */ int nice_match = s->nice_match; /* stop if match long enough */ IPos limit = s->strstart > (IPos)MAX_DIST(s) ? s->strstart - (IPos)MAX_DIST(s) : NIL; /* Stop when cur_match becomes <= limit. To simplify the code, * we prevent matches with the string of window index 0. */ Posf *prev = s->prev; uInt wmask = s->w_mask; #ifdef UNALIGNED_OK /* Compare two bytes at a time. Note: this is not always beneficial. * Try with and without -DUNALIGNED_OK to check. */ register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1; register ush scan_start = *(ushf*)scan; register ush scan_end = *(ushf*)(scan+best_len-1); #else register Bytef *strend = s->window + s->strstart + MAX_MATCH; register Byte scan_end1 = scan[best_len-1]; register Byte scan_end = scan[best_len]; #endif /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. * It is easy to get rid of this optimization if necessary. */ Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); /* Do not waste too much time if we already have a good match: */ if (s->prev_length >= s->good_match) { chain_length >>= 2; } /* Do not look for matches beyond the end of the input. This is necessary * to make deflate deterministic. */ if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); do { Assert(cur_match < s->strstart, "no future"); match = s->window + cur_match; /* Skip to next match if the match length cannot increase * or if the match length is less than 2: */ #if (defined(UNALIGNED_OK) && MAX_MATCH == 258) /* This code assumes sizeof(unsigned short) == 2. Do not use * UNALIGNED_OK if your compiler uses a different size. */ if (*(ushf*)(match+best_len-1) != scan_end || *(ushf*)match != scan_start) continue; /* It is not necessary to compare scan[2] and match[2] since they are * always equal when the other bytes match, given that the hash keys * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at * strstart+3, +5, ... up to strstart+257. We check for insufficient * lookahead only every 4th comparison; the 128th check will be made * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is * necessary to put more guard bytes at the end of the window, or * to check more often for insufficient lookahead. */ Assert(scan[2] == match[2], "scan[2]?"); scan++, match++; do { } while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) && *(ushf*)(scan+=2) == *(ushf*)(match+=2) && *(ushf*)(scan+=2) == *(ushf*)(match+=2) && *(ushf*)(scan+=2) == *(ushf*)(match+=2) && scan < strend); /* The funny "do {}" generates better code on most compilers */ /* Here, scan <= window+strstart+257 */ Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); if (*scan == *match) scan++; len = (MAX_MATCH - 1) - (int)(strend-scan); scan = strend - (MAX_MATCH-1); #else /* UNALIGNED_OK */ if (match[best_len] != scan_end || match[best_len-1] != scan_end1 || *match != *scan || *++match != scan[1]) continue; /* The check at best_len-1 can be removed because it will be made * again later. (This heuristic is not always a win.) * It is not necessary to compare scan[2] and match[2] since they * are always equal when the other bytes match, given that * the hash keys are equal and that HASH_BITS >= 8. */ scan += 2, match++; Assert(*scan == *match, "match[2]?"); /* We check for insufficient lookahead only every 8th comparison; * the 256th check will be made at strstart+258. */ do { } while (*++scan == *++match && *++scan == *++match && *++scan == *++match && *++scan == *++match && *++scan == *++match && *++scan == *++match && *++scan == *++match && *++scan == *++match && scan < strend); Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); len = MAX_MATCH - (int)(strend - scan); scan = strend - MAX_MATCH; #endif /* UNALIGNED_OK */ if (len > best_len) { s->match_start = cur_match; best_len = len; if (len >= nice_match) break; #ifdef UNALIGNED_OK scan_end = *(ushf*)(scan+best_len-1); #else scan_end1 = scan[best_len-1]; scan_end = scan[best_len]; #endif } } while ((cur_match = prev[cur_match & wmask]) > limit && --chain_length != 0); if ((uInt)best_len <= s->lookahead) return best_len; return s->lookahead; } #endif /* ASMV */ #ifdef DEBUG_ZLIB /* =========================================================================== * Check that the match at match_start is indeed a match. */ local void check_match(s, start, match, length) deflate_state *s; IPos start, match; int length; { /* check that the match is indeed a match */ if (zmemcmp((charf *)s->window + match, (charf *)s->window + start, length) != EQUAL) { fprintf(stderr, " start %u, match %u, length %d\n", start, match, length); do { fprintf(stderr, "%c%c", s->window[match++], s->window[start++]); } while (--length != 0); z_error("invalid match"); } if (z_verbose > 1) { fprintf(stderr,"\\[%d,%d]", start-match, length); do { putc(s->window[start++], stderr); } while (--length != 0); } } #else # define check_match(s, start, match, length) #endif /* =========================================================================== * Fill the window when the lookahead becomes insufficient. * Updates strstart and lookahead. * * IN assertion: lookahead < MIN_LOOKAHEAD * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD * At least one byte has been read, or avail_in == 0; reads are * performed for at least two bytes (required for the zip translate_eol * option -- not supported here). */ local void fill_window(s) deflate_state *s; { register unsigned n, m; register Posf *p; unsigned more; /* Amount of free space at the end of the window. */ uInt wsize = s->w_size; do { more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart); /* Deal with !@#$% 64K limit: */ if (more == 0 && s->strstart == 0 && s->lookahead == 0) { more = wsize; } else if (more == (unsigned)(-1)) { /* Very unlikely, but possible on 16 bit machine if strstart == 0 * and lookahead == 1 (input done one byte at time) */ more--; /* If the window is almost full and there is insufficient lookahead, * move the upper half to the lower one to make room in the upper half. */ } else if (s->strstart >= wsize+MAX_DIST(s)) { zmemcpy((charf *)s->window, (charf *)s->window+wsize, (unsigned)wsize); s->match_start -= wsize; s->strstart -= wsize; /* we now have strstart >= MAX_DIST */ s->block_start -= (long) wsize; /* Slide the hash table (could be avoided with 32 bit values at the expense of memory usage). We slide even when level == 0 to keep the hash table consistent if we switch back to level > 0 later. (Using level 0 permanently is not an optimal usage of zlib, so we don't care about this pathological case.) */ n = s->hash_size; p = &s->head[n]; do { m = *--p; *p = (Pos)(m >= wsize ? m-wsize : NIL); } while (--n); n = wsize; p = &s->prev[n]; do { m = *--p; *p = (Pos)(m >= wsize ? m-wsize : NIL); /* If n is not on any hash chain, prev[n] is garbage but * its value will never be used. */ } while (--n); more += wsize; } if (s->strm->avail_in == 0) return; /* If there was no sliding: * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 && * more == window_size - lookahead - strstart * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1) * => more >= window_size - 2*WSIZE + 2 * In the BIG_MEM or MMAP case (not yet supported), * window_size == input_size + MIN_LOOKAHEAD && * strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD. * Otherwise, window_size == 2*WSIZE so more >= 2. * If there was sliding, more >= WSIZE. So in all cases, more >= 2. */ Assert(more >= 2, "more < 2"); n = read_buf(s->strm, (charf *)s->window + s->strstart + s->lookahead, more); s->lookahead += n; /* Initialize the hash value now that we have some input: */ if (s->lookahead >= MIN_MATCH) { s->ins_h = s->window[s->strstart]; UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]); #if MIN_MATCH != 3 Call UPDATE_HASH() MIN_MATCH-3 more times #endif } /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage, * but this is not important since only literal bytes will be emitted. */ } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0); } /* =========================================================================== * Flush the current block, with given end-of-file flag. * IN assertion: strstart is set to the end of the current match. */ #define FLUSH_BLOCK_ONLY(s, eof) { \ _tr_flush_block(s, (s->block_start >= 0L ? \ (charf *)&s->window[(unsigned)s->block_start] : \ (charf *)Z_NULL), \ (ulg)((long)s->strstart - s->block_start), \ (eof)); \ s->block_start = s->strstart; \ flush_pending(s->strm); \ Tracev((stderr,"[FLUSH]")); \ } /* Same but force premature exit if necessary. */ #define FLUSH_BLOCK(s, eof) { \ FLUSH_BLOCK_ONLY(s, eof); \ if (s->strm->avail_out == 0) return (eof) ? finish_started : need_more; \ } /* =========================================================================== * Copy without compression as much as possible from the input stream, return * the current block state. * This function does not insert new strings in the dictionary since * uncompressible data is probably not useful. This function is used * only for the level=0 compression option. * NOTE: this function should be optimized to avoid extra copying from * window to pending_buf. */ local block_state deflate_stored(s, flush) deflate_state *s; int flush; { /* Stored blocks are limited to 0xffff bytes, pending_buf is limited * to pending_buf_size, and each stored block has a 5 byte header: */ ulg max_block_size = 0xffff; ulg max_start; if (max_block_size > s->pending_buf_size - 5) { max_block_size = s->pending_buf_size - 5; } /* Copy as much as possible from input to output: */ for (;;) { /* Fill the window as much as possible: */ if (s->lookahead <= 1) { Assert(s->strstart < s->w_size+MAX_DIST(s) || s->block_start >= (long)s->w_size, "slide too late"); fill_window(s); if (s->lookahead == 0 && flush == Z_NO_FLUSH) return need_more; if (s->lookahead == 0) break; /* flush the current block */ } Assert(s->block_start >= 0L, "block gone"); s->strstart += s->lookahead; s->lookahead = 0; /* Emit a stored block if pending_buf will be full: */ max_start = s->block_start + max_block_size; if (s->strstart == 0 || (ulg)s->strstart >= max_start) { /* strstart == 0 is possible when wraparound on 16-bit machine */ s->lookahead = (uInt)(s->strstart - max_start); s->strstart = (uInt)max_start; FLUSH_BLOCK(s, 0); } /* Flush if we may have to slide, otherwise block_start may become * negative and the data will be gone: */ if (s->strstart - (uInt)s->block_start >= MAX_DIST(s)) { FLUSH_BLOCK(s, 0); } } FLUSH_BLOCK(s, flush == Z_FINISH); return flush == Z_FINISH ? finish_done : block_done; } /* =========================================================================== * Compress as much as possible from the input stream, return the current * block state. * This function does not perform lazy evaluation of matches and inserts * new strings in the dictionary only for unmatched strings or for short * matches. It is used only for the fast compression options. */ local block_state deflate_fast(s, flush) deflate_state *s; int flush; { IPos hash_head = NIL; /* head of the hash chain */ int bflush; /* set if current block must be flushed */ for (;;) { /* Make sure that we always have enough lookahead, except * at the end of the input file. We need MAX_MATCH bytes * for the next match, plus MIN_MATCH bytes to insert the * string following the next match. */ if (s->lookahead < MIN_LOOKAHEAD) { fill_window(s); if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { return need_more; } if (s->lookahead == 0) break; /* flush the current block */ } /* Insert the string window[strstart .. strstart+2] in the * dictionary, and set hash_head to the head of the hash chain: */ if (s->lookahead >= MIN_MATCH) { INSERT_STRING(s, s->strstart, hash_head); } /* Find the longest match, discarding those <= prev_length. * At this point we have always match_length < MIN_MATCH */ if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) { /* To simplify the code, we prevent matches with the string * of window index 0 (in particular we have to avoid a match * of the string with itself at the start of the input file). */ if (s->strategy != Z_HUFFMAN_ONLY) { s->match_length = longest_match (s, hash_head); } /* longest_match() sets match_start */ } if (s->match_length >= MIN_MATCH) { check_match(s, s->strstart, s->match_start, s->match_length); bflush = _tr_tally(s, s->strstart - s->match_start, s->match_length - MIN_MATCH); s->lookahead -= s->match_length; /* Insert new strings in the hash table only if the match length * is not too large. This saves time but degrades compression. */ if (s->match_length <= s->max_insert_length && s->lookahead >= MIN_MATCH) { s->match_length--; /* string at strstart already in hash table */ do { s->strstart++; INSERT_STRING(s, s->strstart, hash_head); /* strstart never exceeds WSIZE-MAX_MATCH, so there are * always MIN_MATCH bytes ahead. */ } while (--s->match_length != 0); s->strstart++; } else { s->strstart += s->match_length; s->match_length = 0; s->ins_h = s->window[s->strstart]; UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]); #if MIN_MATCH != 3 Call UPDATE_HASH() MIN_MATCH-3 more times #endif /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not * matter since it will be recomputed at next deflate call. */ } } else { /* No match, output a literal byte */ Tracevv((stderr,"%c", s->window[s->strstart])); bflush = _tr_tally (s, 0, s->window[s->strstart]); s->lookahead--; s->strstart++; } if (bflush) FLUSH_BLOCK(s, 0); } FLUSH_BLOCK(s, flush == Z_FINISH); return flush == Z_FINISH ? finish_done : block_done; } /* =========================================================================== * Same as above, but achieves better compression. We use a lazy * evaluation for matches: a match is finally adopted only if there is * no better match at the next window position. */ local block_state deflate_slow(s, flush) deflate_state *s; int flush; { IPos hash_head = NIL; /* head of hash chain */ int bflush; /* set if current block must be flushed */ /* Process the input block. */ for (;;) { /* Make sure that we always have enough lookahead, except * at the end of the input file. We need MAX_MATCH bytes * for the next match, plus MIN_MATCH bytes to insert the * string following the next match. */ if (s->lookahead < MIN_LOOKAHEAD) { fill_window(s); if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { return need_more; } if (s->lookahead == 0) break; /* flush the current block */ } /* Insert the string window[strstart .. strstart+2] in the * dictionary, and set hash_head to the head of the hash chain: */ if (s->lookahead >= MIN_MATCH) { INSERT_STRING(s, s->strstart, hash_head); } /* Find the longest match, discarding those <= prev_length. */ s->prev_length = s->match_length, s->prev_match = s->match_start; s->match_length = MIN_MATCH-1; if (hash_head != NIL && s->prev_length < s->max_lazy_match && s->strstart - hash_head <= MAX_DIST(s)) { /* To simplify the code, we prevent matches with the string * of window index 0 (in particular we have to avoid a match * of the string with itself at the start of the input file). */ if (s->strategy != Z_HUFFMAN_ONLY) { s->match_length = longest_match (s, hash_head); } /* longest_match() sets match_start */ if (s->match_length <= 5 && (s->strategy == Z_FILTERED || (s->match_length == MIN_MATCH && s->strstart - s->match_start > TOO_FAR))) { /* If prev_match is also MIN_MATCH, match_start is garbage * but we will ignore the current match anyway. */ s->match_length = MIN_MATCH-1; } } /* If there was a match at the previous step and the current * match is not better, output the previous match: */ if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) { uInt max_insert = s->strstart + s->lookahead - MIN_MATCH; /* Do not insert strings in hash table beyond this. */ check_match(s, s->strstart-1, s->prev_match, s->prev_length); bflush = _tr_tally(s, s->strstart -1 - s->prev_match, s->prev_length - MIN_MATCH); /* Insert in hash table all strings up to the end of the match. * strstart-1 and strstart are already inserted. If there is not * enough lookahead, the last two strings are not inserted in * the hash table. */ s->lookahead -= s->prev_length-1; s->prev_length -= 2; do { if (++s->strstart <= max_insert) { INSERT_STRING(s, s->strstart, hash_head); } } while (--s->prev_length != 0); s->match_available = 0; s->match_length = MIN_MATCH-1; s->strstart++; if (bflush) FLUSH_BLOCK(s, 0); } else if (s->match_available) { /* If there was no match at the previous position, output a * single literal. If there was a match but the current match * is longer, truncate the previous match to a single literal. */ Tracevv((stderr,"%c", s->window[s->strstart-1])); if (_tr_tally (s, 0, s->window[s->strstart-1])) { FLUSH_BLOCK_ONLY(s, 0); } s->strstart++; s->lookahead--; if (s->strm->avail_out == 0) return need_more; } else { /* There is no previous match to compare with, wait for * the next step to decide. */ s->match_available = 1; s->strstart++; s->lookahead--; } } Assert (flush != Z_NO_FLUSH, "no flush?"); if (s->match_available) { Tracevv((stderr,"%c", s->window[s->strstart-1])); _tr_tally (s, 0, s->window[s->strstart-1]); s->match_available = 0; } FLUSH_BLOCK(s, flush == Z_FINISH); return flush == Z_FINISH ? finish_done : block_done; } /* --- deflate.c */ /* +++ trees.c */ /* trees.c -- output deflated data using Huffman coding * Copyright (C) 1995-1996 Jean-loup Gailly * For conditions of distribution and use, see copyright notice in zlib.h */ /* * ALGORITHM * * The "deflation" process uses several Huffman trees. The more * common source values are represented by shorter bit sequences. * * Each code tree is stored in a compressed form which is itself * a Huffman encoding of the lengths of all the code strings (in * ascending order by source values). The actual code strings are * reconstructed from the lengths in the inflate process, as described * in the deflate specification. * * REFERENCES * * Deutsch, L.P.,"'Deflate' Compressed Data Format Specification". * Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc * * Storer, James A. * Data Compression: Methods and Theory, pp. 49-50. * Computer Science Press, 1988. ISBN 0-7167-8156-5. * * Sedgewick, R. * Algorithms, p290. * Addison-Wesley, 1983. ISBN 0-201-06672-6. */ /* From: trees.c,v 1.11 1996/07/24 13:41:06 me Exp $ */ /* #include "deflate.h" */ #ifdef DEBUG_ZLIB # include #endif /* =========================================================================== * Constants */ #define MAX_BL_BITS 7 /* Bit length codes must not exceed MAX_BL_BITS bits */ #define END_BLOCK 256 /* end of block literal code */ #define REP_3_6 16 /* repeat previous bit length 3-6 times (2 bits of repeat count) */ #define REPZ_3_10 17 /* repeat a zero length 3-10 times (3 bits of repeat count) */ #define REPZ_11_138 18 /* repeat a zero length 11-138 times (7 bits of repeat count) */ local int extra_lbits[LENGTH_CODES] /* extra bits for each length code */ = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0}; local int extra_dbits[D_CODES] /* extra bits for each distance code */ = {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13}; local int extra_blbits[BL_CODES]/* extra bits for each bit length code */ = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7}; local uch bl_order[BL_CODES] = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15}; /* The lengths of the bit length codes are sent in order of decreasing * probability, to avoid transmitting the lengths for unused bit length codes. */ #define Buf_size (8 * 2*sizeof(char)) /* Number of bits used within bi_buf. (bi_buf might be implemented on * more than 16 bits on some systems.) */ /* =========================================================================== * Local data. These are initialized only once. */ local ct_data static_ltree[L_CODES+2]; /* The static literal tree. Since the bit lengths are imposed, there is no * need for the L_CODES extra codes used during heap construction. However * The codes 286 and 287 are needed to build a canonical tree (see _tr_init * below). */ local ct_data static_dtree[D_CODES]; /* The static distance tree. (Actually a trivial tree since all codes use * 5 bits.) */ local uch dist_code[512]; /* distance codes. The first 256 values correspond to the distances * 3 .. 258, the last 256 values correspond to the top 8 bits of * the 15 bit distances. */ local uch length_code[MAX_MATCH-MIN_MATCH+1]; /* length code for each normalized match length (0 == MIN_MATCH) */ local int base_length[LENGTH_CODES]; /* First normalized length for each code (0 = MIN_MATCH) */ local int base_dist[D_CODES]; /* First normalized distance for each code (0 = distance of 1) */ struct static_tree_desc_s { ct_data *static_tree; /* static tree or NULL */ intf *extra_bits; /* extra bits for each code or NULL */ int extra_base; /* base index for extra_bits */ int elems; /* max number of elements in the tree */ int max_length; /* max bit length for the codes */ }; local static_tree_desc static_l_desc = {static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS}; local static_tree_desc static_d_desc = {static_dtree, extra_dbits, 0, D_CODES, MAX_BITS}; local static_tree_desc static_bl_desc = {(ct_data *)0, extra_blbits, 0, BL_CODES, MAX_BL_BITS}; /* =========================================================================== * Local (static) routines in this file. */ local void tr_static_init OF((void)); local void init_block OF((deflate_state *s)); local void pqdownheap OF((deflate_state *s, ct_data *tree, int k)); local void gen_bitlen OF((deflate_state *s, tree_desc *desc)); local void gen_codes OF((ct_data *tree, int max_code, ushf *bl_count)); local void build_tree OF((deflate_state *s, tree_desc *desc)); local void scan_tree OF((deflate_state *s, ct_data *tree, int max_code)); local void send_tree OF((deflate_state *s, ct_data *tree, int max_code)); local int build_bl_tree OF((deflate_state *s)); local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes, int blcodes)); local void compress_block OF((deflate_state *s, ct_data *ltree, ct_data *dtree)); local void set_data_type OF((deflate_state *s)); local unsigned bi_reverse OF((unsigned value, int length)); local void bi_windup OF((deflate_state *s)); local void bi_flush OF((deflate_state *s)); local void copy_block OF((deflate_state *s, charf *buf, unsigned len, int header)); #ifndef DEBUG_ZLIB # define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len) /* Send a code of the given tree. c and tree must not have side effects */ #else /* DEBUG_ZLIB */ # define send_code(s, c, tree) \ { if (verbose>2) fprintf(stderr,"\ncd %3d ",(c)); \ send_bits(s, tree[c].Code, tree[c].Len); } #endif #define d_code(dist) \ ((dist) < 256 ? dist_code[dist] : dist_code[256+((dist)>>7)]) /* Mapping from a distance to a distance code. dist is the distance - 1 and * must not have side effects. dist_code[256] and dist_code[257] are never * used. */ /* =========================================================================== * Output a short LSB first on the stream. * IN assertion: there is enough room in pendingBuf. */ #define put_short(s, w) { \ put_byte(s, (uch)((w) & 0xff)); \ put_byte(s, (uch)((ush)(w) >> 8)); \ } /* =========================================================================== * Send a value on a given number of bits. * IN assertion: length <= 16 and value fits in length bits. */ #ifdef DEBUG_ZLIB local void send_bits OF((deflate_state *s, int value, int length)); local void send_bits(s, value, length) deflate_state *s; int value; /* value to send */ int length; /* number of bits */ { Tracevv((stderr," l %2d v %4x ", length, value)); Assert(length > 0 && length <= 15, "invalid length"); s->bits_sent += (ulg)length; /* If not enough room in bi_buf, use (valid) bits from bi_buf and * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid)) * unused bits in value. */ if (s->bi_valid > (int)Buf_size - length) { s->bi_buf |= (value << s->bi_valid); put_short(s, s->bi_buf); s->bi_buf = (ush)value >> (Buf_size - s->bi_valid); s->bi_valid += length - Buf_size; } else { s->bi_buf |= value << s->bi_valid; s->bi_valid += length; } } #else /* !DEBUG_ZLIB */ #define send_bits(s, value, length) \ { int len = length;\ if (s->bi_valid > (int)Buf_size - len) {\ int val = value;\ s->bi_buf |= (val << s->bi_valid);\ put_short(s, s->bi_buf);\ s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\ s->bi_valid += len - Buf_size;\ } else {\ s->bi_buf |= (value) << s->bi_valid;\ s->bi_valid += len;\ }\ } #endif /* DEBUG_ZLIB */ #define MAX(a,b) (a >= b ? a : b) /* the arguments must not have side effects */ /* =========================================================================== * Initialize the various 'constant' tables. In a multi-threaded environment, * this function may be called by two threads concurrently, but this is * harmless since both invocations do exactly the same thing. */ local void tr_static_init() { static int static_init_done = 0; int n; /* iterates over tree elements */ int bits; /* bit counter */ int length; /* length value */ int code; /* code value */ int dist; /* distance index */ ush bl_count[MAX_BITS+1]; /* number of codes at each bit length for an optimal tree */ if (static_init_done) return; /* Initialize the mapping length (0..255) -> length code (0..28) */ length = 0; for (code = 0; code < LENGTH_CODES-1; code++) { base_length[code] = length; for (n = 0; n < (1< dist code (0..29) */ dist = 0; for (code = 0 ; code < 16; code++) { base_dist[code] = dist; for (n = 0; n < (1<>= 7; /* from now on, all distances are divided by 128 */ for ( ; code < D_CODES; code++) { base_dist[code] = dist << 7; for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) { dist_code[256 + dist++] = (uch)code; } } Assert (dist == 256, "tr_static_init: 256+dist != 512"); /* Construct the codes of the static literal tree */ for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0; n = 0; while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++; while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++; while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++; while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++; /* Codes 286 and 287 do not exist, but we must include them in the * tree construction to get a canonical Huffman tree (longest code * all ones) */ gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count); /* The static distance tree is trivial: */ for (n = 0; n < D_CODES; n++) { static_dtree[n].Len = 5; static_dtree[n].Code = bi_reverse((unsigned)n, 5); } static_init_done = 1; } /* =========================================================================== * Initialize the tree data structures for a new zlib stream. */ void _tr_init(s) deflate_state *s; { tr_static_init(); s->compressed_len = 0L; s->l_desc.dyn_tree = s->dyn_ltree; s->l_desc.stat_desc = &static_l_desc; s->d_desc.dyn_tree = s->dyn_dtree; s->d_desc.stat_desc = &static_d_desc; s->bl_desc.dyn_tree = s->bl_tree; s->bl_desc.stat_desc = &static_bl_desc; s->bi_buf = 0; s->bi_valid = 0; s->last_eob_len = 8; /* enough lookahead for inflate */ #ifdef DEBUG_ZLIB s->bits_sent = 0L; #endif /* Initialize the first block of the first file: */ init_block(s); } /* =========================================================================== * Initialize a new block. */ local void init_block(s) deflate_state *s; { int n; /* iterates over tree elements */ /* Initialize the trees. */ for (n = 0; n < L_CODES; n++) s->dyn_ltree[n].Freq = 0; for (n = 0; n < D_CODES; n++) s->dyn_dtree[n].Freq = 0; for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0; s->dyn_ltree[END_BLOCK].Freq = 1; s->opt_len = s->static_len = 0L; s->last_lit = s->matches = 0; } #define SMALLEST 1 /* Index within the heap array of least frequent node in the Huffman tree */ /* =========================================================================== * Remove the smallest element from the heap and recreate the heap with * one less element. Updates heap and heap_len. */ #define pqremove(s, tree, top) \ {\ top = s->heap[SMALLEST]; \ s->heap[SMALLEST] = s->heap[s->heap_len--]; \ pqdownheap(s, tree, SMALLEST); \ } /* =========================================================================== * Compares to subtrees, using the tree depth as tie breaker when * the subtrees have equal frequency. This minimizes the worst case length. */ #define smaller(tree, n, m, depth) \ (tree[n].Freq < tree[m].Freq || \ (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m])) /* =========================================================================== * Restore the heap property by moving down the tree starting at node k, * exchanging a node with the smallest of its two sons if necessary, stopping * when the heap property is re-established (each father smaller than its * two sons). */ local void pqdownheap(s, tree, k) deflate_state *s; ct_data *tree; /* the tree to restore */ int k; /* node to move down */ { int v = s->heap[k]; int j = k << 1; /* left son of k */ while (j <= s->heap_len) { /* Set j to the smallest of the two sons: */ if (j < s->heap_len && smaller(tree, s->heap[j+1], s->heap[j], s->depth)) { j++; } /* Exit if v is smaller than both sons */ if (smaller(tree, v, s->heap[j], s->depth)) break; /* Exchange v with the smallest son */ s->heap[k] = s->heap[j]; k = j; /* And continue down the tree, setting j to the left son of k */ j <<= 1; } s->heap[k] = v; } /* =========================================================================== * Compute the optimal bit lengths for a tree and update the total bit length * for the current block. * IN assertion: the fields freq and dad are set, heap[heap_max] and * above are the tree nodes sorted by increasing frequency. * OUT assertions: the field len is set to the optimal bit length, the * array bl_count contains the frequencies for each bit length. * The length opt_len is updated; static_len is also updated if stree is * not null. */ local void gen_bitlen(s, desc) deflate_state *s; tree_desc *desc; /* the tree descriptor */ { ct_data *tree = desc->dyn_tree; int max_code = desc->max_code; ct_data *stree = desc->stat_desc->static_tree; intf *extra = desc->stat_desc->extra_bits; int base = desc->stat_desc->extra_base; int max_length = desc->stat_desc->max_length; int h; /* heap index */ int n, m; /* iterate over the tree elements */ int bits; /* bit length */ int xbits; /* extra bits */ ush f; /* frequency */ int overflow = 0; /* number of elements with bit length too large */ for (bits = 0; bits <= MAX_BITS; bits++) s->bl_count[bits] = 0; /* In a first pass, compute the optimal bit lengths (which may * overflow in the case of the bit length tree). */ tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */ for (h = s->heap_max+1; h < HEAP_SIZE; h++) { n = s->heap[h]; bits = tree[tree[n].Dad].Len + 1; if (bits > max_length) bits = max_length, overflow++; tree[n].Len = (ush)bits; /* We overwrite tree[n].Dad which is no longer needed */ if (n > max_code) continue; /* not a leaf node */ s->bl_count[bits]++; xbits = 0; if (n >= base) xbits = extra[n-base]; f = tree[n].Freq; s->opt_len += (ulg)f * (bits + xbits); if (stree) s->static_len += (ulg)f * (stree[n].Len + xbits); } if (overflow == 0) return; Trace((stderr,"\nbit length overflow\n")); /* This happens for example on obj2 and pic of the Calgary corpus */ /* Find the first bit length which could increase: */ do { bits = max_length-1; while (s->bl_count[bits] == 0) bits--; s->bl_count[bits]--; /* move one leaf down the tree */ s->bl_count[bits+1] += 2; /* move one overflow item as its brother */ s->bl_count[max_length]--; /* The brother of the overflow item also moves one step up, * but this does not affect bl_count[max_length] */ overflow -= 2; } while (overflow > 0); /* Now recompute all bit lengths, scanning in increasing frequency. * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all * lengths instead of fixing only the wrong ones. This idea is taken * from 'ar' written by Haruhiko Okumura.) */ for (bits = max_length; bits != 0; bits--) { n = s->bl_count[bits]; while (n != 0) { m = s->heap[--h]; if (m > max_code) continue; if (tree[m].Len != (unsigned) bits) { Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits)); s->opt_len += ((long)bits - (long)tree[m].Len) *(long)tree[m].Freq; tree[m].Len = (ush)bits; } n--; } } } /* =========================================================================== * Generate the codes for a given tree and bit counts (which need not be * optimal). * IN assertion: the array bl_count contains the bit length statistics for * the given tree and the field len is set for all tree elements. * OUT assertion: the field code is set for all tree elements of non * zero code length. */ local void gen_codes (tree, max_code, bl_count) ct_data *tree; /* the tree to decorate */ int max_code; /* largest code with non zero frequency */ ushf *bl_count; /* number of codes at each bit length */ { ush next_code[MAX_BITS+1]; /* next code value for each bit length */ ush code = 0; /* running code value */ int bits; /* bit index */ int n; /* code index */ /* The distribution counts are first used to generate the code values * without bit reversal. */ for (bits = 1; bits <= MAX_BITS; bits++) { next_code[bits] = code = (code + bl_count[bits-1]) << 1; } /* Check that the bit counts in bl_count are consistent. The last code * must be all ones. */ Assert (code + bl_count[MAX_BITS]-1 == (1<dyn_tree; ct_data *stree = desc->stat_desc->static_tree; int elems = desc->stat_desc->elems; int n, m; /* iterate over heap elements */ int max_code = -1; /* largest code with non zero frequency */ int node; /* new node being created */ /* Construct the initial heap, with least frequent element in * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1]. * heap[0] is not used. */ s->heap_len = 0, s->heap_max = HEAP_SIZE; for (n = 0; n < elems; n++) { if (tree[n].Freq != 0) { s->heap[++(s->heap_len)] = max_code = n; s->depth[n] = 0; } else { tree[n].Len = 0; } } /* The pkzip format requires that at least one distance code exists, * and that at least one bit should be sent even if there is only one * possible code. So to avoid special checks later on we force at least * two codes of non zero frequency. */ while (s->heap_len < 2) { node = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0); tree[node].Freq = 1; s->depth[node] = 0; s->opt_len--; if (stree) s->static_len -= stree[node].Len; /* node is 0 or 1 so it does not have extra bits */ } desc->max_code = max_code; /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree, * establish sub-heaps of increasing lengths: */ for (n = s->heap_len/2; n >= 1; n--) pqdownheap(s, tree, n); /* Construct the Huffman tree by repeatedly combining the least two * frequent nodes. */ node = elems; /* next internal node of the tree */ do { pqremove(s, tree, n); /* n = node of least frequency */ m = s->heap[SMALLEST]; /* m = node of next least frequency */ s->heap[--(s->heap_max)] = n; /* keep the nodes sorted by frequency */ s->heap[--(s->heap_max)] = m; /* Create a new node father of n and m */ tree[node].Freq = tree[n].Freq + tree[m].Freq; s->depth[node] = (uch) (MAX(s->depth[n], s->depth[m]) + 1); tree[n].Dad = tree[m].Dad = (ush)node; #ifdef DUMP_BL_TREE if (tree == s->bl_tree) { fprintf(stderr,"\nnode %d(%d), sons %d(%d) %d(%d)", node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq); } #endif /* and insert the new node in the heap */ s->heap[SMALLEST] = node++; pqdownheap(s, tree, SMALLEST); } while (s->heap_len >= 2); s->heap[--(s->heap_max)] = s->heap[SMALLEST]; /* At this point, the fields freq and dad are set. We can now * generate the bit lengths. */ gen_bitlen(s, (tree_desc *)desc); /* The field len is now set, we can generate the bit codes */ gen_codes ((ct_data *)tree, max_code, s->bl_count); } /* =========================================================================== * Scan a literal or distance tree to determine the frequencies of the codes * in the bit length tree. */ local void scan_tree (s, tree, max_code) deflate_state *s; ct_data *tree; /* the tree to be scanned */ int max_code; /* and its largest code of non zero frequency */ { int n; /* iterates over all tree elements */ int prevlen = -1; /* last emitted length */ int curlen; /* length of current code */ int nextlen = tree[0].Len; /* length of next code */ int count = 0; /* repeat count of the current code */ int max_count = 7; /* max repeat count */ int min_count = 4; /* min repeat count */ if (nextlen == 0) max_count = 138, min_count = 3; tree[max_code+1].Len = (ush)0xffff; /* guard */ for (n = 0; n <= max_code; n++) { curlen = nextlen; nextlen = tree[n+1].Len; if (++count < max_count && curlen == nextlen) { continue; } else if (count < min_count) { s->bl_tree[curlen].Freq += count; } else if (curlen != 0) { if (curlen != prevlen) s->bl_tree[curlen].Freq++; s->bl_tree[REP_3_6].Freq++; } else if (count <= 10) { s->bl_tree[REPZ_3_10].Freq++; } else { s->bl_tree[REPZ_11_138].Freq++; } count = 0; prevlen = curlen; if (nextlen == 0) { max_count = 138, min_count = 3; } else if (curlen == nextlen) { max_count = 6, min_count = 3; } else { max_count = 7, min_count = 4; } } } /* =========================================================================== * Send a literal or distance tree in compressed form, using the codes in * bl_tree. */ local void send_tree (s, tree, max_code) deflate_state *s; ct_data *tree; /* the tree to be scanned */ int max_code; /* and its largest code of non zero frequency */ { int n; /* iterates over all tree elements */ int prevlen = -1; /* last emitted length */ int curlen; /* length of current code */ int nextlen = tree[0].Len; /* length of next code */ int count = 0; /* repeat count of the current code */ int max_count = 7; /* max repeat count */ int min_count = 4; /* min repeat count */ /* tree[max_code+1].Len = -1; */ /* guard already set */ if (nextlen == 0) max_count = 138, min_count = 3; for (n = 0; n <= max_code; n++) { curlen = nextlen; nextlen = tree[n+1].Len; if (++count < max_count && curlen == nextlen) { continue; } else if (count < min_count) { do { send_code(s, curlen, s->bl_tree); } while (--count != 0); } else if (curlen != 0) { if (curlen != prevlen) { send_code(s, curlen, s->bl_tree); count--; } Assert(count >= 3 && count <= 6, " 3_6?"); send_code(s, REP_3_6, s->bl_tree); send_bits(s, count-3, 2); } else if (count <= 10) { send_code(s, REPZ_3_10, s->bl_tree); send_bits(s, count-3, 3); } else { send_code(s, REPZ_11_138, s->bl_tree); send_bits(s, count-11, 7); } count = 0; prevlen = curlen; if (nextlen == 0) { max_count = 138, min_count = 3; } else if (curlen == nextlen) { max_count = 6, min_count = 3; } else { max_count = 7, min_count = 4; } } } /* =========================================================================== * Construct the Huffman tree for the bit lengths and return the index in * bl_order of the last bit length code to send. */ local int build_bl_tree(s) deflate_state *s; { int max_blindex; /* index of last bit length code of non zero freq */ /* Determine the bit length frequencies for literal and distance trees */ scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code); scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code); /* Build the bit length tree: */ build_tree(s, (tree_desc *)(&(s->bl_desc))); /* opt_len now includes the length of the tree representations, except * the lengths of the bit lengths codes and the 5+5+4 bits for the counts. */ /* Determine the number of bit length codes to send. The pkzip format * requires that at least 4 bit length codes be sent. (appnote.txt says * 3 but the actual value used is 4.) */ for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) { if (s->bl_tree[bl_order[max_blindex]].Len != 0) break; } /* Update opt_len to include the bit length tree and counts */ s->opt_len += 3*(max_blindex+1) + 5+5+4; Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld", s->opt_len, s->static_len)); return max_blindex; } /* =========================================================================== * Send the header for a block using dynamic Huffman trees: the counts, the * lengths of the bit length codes, the literal tree and the distance tree. * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4. */ local void send_all_trees(s, lcodes, dcodes, blcodes) deflate_state *s; int lcodes, dcodes, blcodes; /* number of codes for each tree */ { int rank; /* index in bl_order */ Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes"); Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES, "too many codes"); Tracev((stderr, "\nbl counts: ")); send_bits(s, lcodes-257, 5); /* not +255 as stated in appnote.txt */ send_bits(s, dcodes-1, 5); send_bits(s, blcodes-4, 4); /* not -3 as stated in appnote.txt */ for (rank = 0; rank < blcodes; rank++) { Tracev((stderr, "\nbl code %2d ", bl_order[rank])); send_bits(s, s->bl_tree[bl_order[rank]].Len, 3); } Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent)); send_tree(s, (ct_data *)s->dyn_ltree, lcodes-1); /* literal tree */ Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent)); send_tree(s, (ct_data *)s->dyn_dtree, dcodes-1); /* distance tree */ Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent)); } /* =========================================================================== * Send a stored block */ void _tr_stored_block(s, buf, stored_len, eof) deflate_state *s; charf *buf; /* input block */ ulg stored_len; /* length of input block */ int eof; /* true if this is the last block for a file */ { send_bits(s, (STORED_BLOCK<<1)+eof, 3); /* send block type */ s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L; s->compressed_len += (stored_len + 4) << 3; copy_block(s, buf, (unsigned)stored_len, 1); /* with header */ } /* Send just the `stored block' type code without any length bytes or data. */ void _tr_stored_type_only(s) deflate_state *s; { send_bits(s, (STORED_BLOCK << 1), 3); bi_windup(s); s->compressed_len = (s->compressed_len + 3) & ~7L; } /* =========================================================================== * Send one empty static block to give enough lookahead for inflate. * This takes 10 bits, of which 7 may remain in the bit buffer. * The current inflate code requires 9 bits of lookahead. If the * last two codes for the previous block (real code plus EOB) were coded * on 5 bits or less, inflate may have only 5+3 bits of lookahead to decode * the last real code. In this case we send two empty static blocks instead * of one. (There are no problems if the previous block is stored or fixed.) * To simplify the code, we assume the worst case of last real code encoded * on one bit only. */ void _tr_align(s) deflate_state *s; { send_bits(s, STATIC_TREES<<1, 3); send_code(s, END_BLOCK, static_ltree); s->compressed_len += 10L; /* 3 for block type, 7 for EOB */ bi_flush(s); /* Of the 10 bits for the empty block, we have already sent * (10 - bi_valid) bits. The lookahead for the last real code (before * the EOB of the previous block) was thus at least one plus the length * of the EOB plus what we have just sent of the empty static block. */ if (1 + s->last_eob_len + 10 - s->bi_valid < 9) { send_bits(s, STATIC_TREES<<1, 3); send_code(s, END_BLOCK, static_ltree); s->compressed_len += 10L; bi_flush(s); } s->last_eob_len = 7; } /* =========================================================================== * Determine the best encoding for the current block: dynamic trees, static * trees or store, and output the encoded block to the zip file. This function * returns the total compressed length for the file so far. */ ulg _tr_flush_block(s, buf, stored_len, eof) deflate_state *s; charf *buf; /* input block, or NULL if too old */ ulg stored_len; /* length of input block */ int eof; /* true if this is the last block for a file */ { ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */ int max_blindex = 0; /* index of last bit length code of non zero freq */ /* Build the Huffman trees unless a stored block is forced */ if (s->level > 0) { /* Check if the file is ascii or binary */ if (s->data_type == Z_UNKNOWN) set_data_type(s); /* Construct the literal and distance trees */ build_tree(s, (tree_desc *)(&(s->l_desc))); Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len, s->static_len)); build_tree(s, (tree_desc *)(&(s->d_desc))); Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len, s->static_len)); /* At this point, opt_len and static_len are the total bit lengths of * the compressed block data, excluding the tree representations. */ /* Build the bit length tree for the above two trees, and get the index * in bl_order of the last bit length code to send. */ max_blindex = build_bl_tree(s); /* Determine the best encoding. Compute first the block length in bytes*/ opt_lenb = (s->opt_len+3+7)>>3; static_lenb = (s->static_len+3+7)>>3; Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ", opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len, s->last_lit)); if (static_lenb <= opt_lenb) opt_lenb = static_lenb; } else { Assert(buf != (char*)0, "lost buf"); opt_lenb = static_lenb = stored_len + 5; /* force a stored block */ } /* If compression failed and this is the first and last block, * and if the .zip file can be seeked (to rewrite the local header), * the whole file is transformed into a stored file: */ #ifdef STORED_FILE_OK # ifdef FORCE_STORED_FILE if (eof && s->compressed_len == 0L) { /* force stored file */ # else if (stored_len <= opt_lenb && eof && s->compressed_len==0L && seekable()) { # endif /* Since LIT_BUFSIZE <= 2*WSIZE, the input data must be there: */ if (buf == (charf*)0) error ("block vanished"); copy_block(s, buf, (unsigned)stored_len, 0); /* without header */ s->compressed_len = stored_len << 3; s->method = STORED; } else #endif /* STORED_FILE_OK */ #ifdef FORCE_STORED if (buf != (char*)0) { /* force stored block */ #else if (stored_len+4 <= opt_lenb && buf != (char*)0) { /* 4: two words for the lengths */ #endif /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE. * Otherwise we can't have processed more than WSIZE input bytes since * the last block flush, because compression would have been * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to * transform a block into a stored block. */ _tr_stored_block(s, buf, stored_len, eof); #ifdef FORCE_STATIC } else if (static_lenb >= 0) { /* force static trees */ #else } else if (static_lenb == opt_lenb) { #endif send_bits(s, (STATIC_TREES<<1)+eof, 3); compress_block(s, (ct_data *)static_ltree, (ct_data *)static_dtree); s->compressed_len += 3 + s->static_len; } else { send_bits(s, (DYN_TREES<<1)+eof, 3); send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1, max_blindex+1); compress_block(s, (ct_data *)s->dyn_ltree, (ct_data *)s->dyn_dtree); s->compressed_len += 3 + s->opt_len; } Assert (s->compressed_len == s->bits_sent, "bad compressed size"); init_block(s); if (eof) { bi_windup(s); s->compressed_len += 7; /* align on byte boundary */ } Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3, s->compressed_len-7*eof)); return s->compressed_len >> 3; } /* =========================================================================== * Save the match info and tally the frequency counts. Return true if * the current block must be flushed. */ int _tr_tally (s, dist, lc) deflate_state *s; unsigned dist; /* distance of matched string */ unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */ { s->d_buf[s->last_lit] = (ush)dist; s->l_buf[s->last_lit++] = (uch)lc; if (dist == 0) { /* lc is the unmatched char */ s->dyn_ltree[lc].Freq++; } else { s->matches++; /* Here, lc is the match length - MIN_MATCH */ dist--; /* dist = match distance - 1 */ Assert((ush)dist < (ush)MAX_DIST(s) && (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) && (ush)d_code(dist) < (ush)D_CODES, "_tr_tally: bad match"); s->dyn_ltree[length_code[lc]+LITERALS+1].Freq++; s->dyn_dtree[d_code(dist)].Freq++; } /* Try to guess if it is profitable to stop the current block here */ if (s->level > 2 && (s->last_lit & 0xfff) == 0) { /* Compute an upper bound for the compressed length */ ulg out_length = (ulg)s->last_lit*8L; ulg in_length = (ulg)((long)s->strstart - s->block_start); int dcode; for (dcode = 0; dcode < D_CODES; dcode++) { out_length += (ulg)s->dyn_dtree[dcode].Freq * (5L+extra_dbits[dcode]); } out_length >>= 3; Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ", s->last_lit, in_length, out_length, 100L - out_length*100L/in_length)); if (s->matches < s->last_lit/2 && out_length < in_length/2) return 1; } return (s->last_lit == s->lit_bufsize-1); /* We avoid equality with lit_bufsize because of wraparound at 64K * on 16 bit machines and because stored blocks are restricted to * 64K-1 bytes. */ } /* =========================================================================== * Send the block data compressed using the given Huffman trees */ local void compress_block(s, ltree, dtree) deflate_state *s; ct_data *ltree; /* literal tree */ ct_data *dtree; /* distance tree */ { unsigned dist; /* distance of matched string */ int lc; /* match length or unmatched char (if dist == 0) */ unsigned lx = 0; /* running index in l_buf */ unsigned code; /* the code to send */ int extra; /* number of extra bits to send */ if (s->last_lit != 0) do { dist = s->d_buf[lx]; lc = s->l_buf[lx++]; if (dist == 0) { send_code(s, lc, ltree); /* send a literal byte */ Tracecv(isgraph(lc), (stderr," '%c' ", lc)); } else { /* Here, lc is the match length - MIN_MATCH */ code = length_code[lc]; send_code(s, code+LITERALS+1, ltree); /* send the length code */ extra = extra_lbits[code]; if (extra != 0) { lc -= base_length[code]; send_bits(s, lc, extra); /* send the extra length bits */ } dist--; /* dist is now the match distance - 1 */ code = d_code(dist); Assert (code < D_CODES, "bad d_code"); send_code(s, code, dtree); /* send the distance code */ extra = extra_dbits[code]; if (extra != 0) { dist -= base_dist[code]; send_bits(s, dist, extra); /* send the extra distance bits */ } } /* literal or match pair ? */ /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */ Assert(s->pending < s->lit_bufsize + 2*lx, "pendingBuf overflow"); } while (lx < s->last_lit); send_code(s, END_BLOCK, ltree); s->last_eob_len = ltree[END_BLOCK].Len; } /* =========================================================================== * Set the data type to ASCII or BINARY, using a crude approximation: * binary if more than 20% of the bytes are <= 6 or >= 128, ascii otherwise. * IN assertion: the fields freq of dyn_ltree are set and the total of all * frequencies does not exceed 64K (to fit in an int on 16 bit machines). */ local void set_data_type(s) deflate_state *s; { int n = 0; unsigned ascii_freq = 0; unsigned bin_freq = 0; while (n < 7) bin_freq += s->dyn_ltree[n++].Freq; while (n < 128) ascii_freq += s->dyn_ltree[n++].Freq; while (n < LITERALS) bin_freq += s->dyn_ltree[n++].Freq; s->data_type = (Byte)(bin_freq > (ascii_freq >> 2) ? Z_BINARY : Z_ASCII); } /* =========================================================================== * Reverse the first len bits of a code, using straightforward code (a faster * method would use a table) * IN assertion: 1 <= len <= 15 */ local unsigned bi_reverse(code, len) unsigned code; /* the value to invert */ int len; /* its bit length */ { register unsigned res = 0; do { res |= code & 1; code >>= 1, res <<= 1; } while (--len > 0); return res >> 1; } /* =========================================================================== * Flush the bit buffer, keeping at most 7 bits in it. */ local void bi_flush(s) deflate_state *s; { if (s->bi_valid == 16) { put_short(s, s->bi_buf); s->bi_buf = 0; s->bi_valid = 0; } else if (s->bi_valid >= 8) { put_byte(s, (Byte)s->bi_buf); s->bi_buf >>= 8; s->bi_valid -= 8; } } /* =========================================================================== * Flush the bit buffer and align the output on a byte boundary */ local void bi_windup(s) deflate_state *s; { if (s->bi_valid > 8) { put_short(s, s->bi_buf); } else if (s->bi_valid > 0) { put_byte(s, (Byte)s->bi_buf); } s->bi_buf = 0; s->bi_valid = 0; #ifdef DEBUG_ZLIB s->bits_sent = (s->bits_sent+7) & ~7; #endif } /* =========================================================================== * Copy a stored block, storing first the length and its * one's complement if requested. */ local void copy_block(s, buf, len, header) deflate_state *s; charf *buf; /* the input data */ unsigned len; /* its length */ int header; /* true if block header must be written */ { bi_windup(s); /* align on byte boundary */ s->last_eob_len = 8; /* enough lookahead for inflate */ if (header) { put_short(s, (ush)len); put_short(s, (ush)~len); #ifdef DEBUG_ZLIB s->bits_sent += 2*16; #endif } #ifdef DEBUG_ZLIB s->bits_sent += (ulg)len<<3; #endif /* bundle up the put_byte(s, *buf++) calls */ zmemcpy(&s->pending_buf[s->pending], buf, len); s->pending += len; } /* --- trees.c */ /* +++ inflate.c */ /* inflate.c -- zlib interface to inflate modules * Copyright (C) 1995-1996 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ /* #include "zutil.h" */ /* +++ infblock.h */ /* infblock.h -- header to use infblock.c * Copyright (C) 1995-1996 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ /* WARNING: this file should *not* be used by applications. It is part of the implementation of the compression library and is subject to change. Applications should only use zlib.h. */ struct inflate_blocks_state; typedef struct inflate_blocks_state FAR inflate_blocks_statef; extern inflate_blocks_statef * inflate_blocks_new OF(( z_streamp z, check_func c, /* check function */ uInt w)); /* window size */ extern int inflate_blocks OF(( inflate_blocks_statef *, z_streamp , int)); /* initial return code */ extern void inflate_blocks_reset OF(( inflate_blocks_statef *, z_streamp , uLongf *)); /* check value on output */ extern int inflate_blocks_free OF(( inflate_blocks_statef *, z_streamp , uLongf *)); /* check value on output */ extern void inflate_set_dictionary OF(( inflate_blocks_statef *s, const Bytef *d, /* dictionary */ uInt n)); /* dictionary length */ extern int inflate_addhistory OF(( inflate_blocks_statef *, z_streamp)); extern int inflate_packet_flush OF(( inflate_blocks_statef *)); /* --- infblock.h */ #ifndef NO_DUMMY_DECL struct inflate_blocks_state {int dummy;}; /* for buggy compilers */ #endif /* inflate private state */ struct internal_state { /* mode */ enum { METHOD, /* waiting for method byte */ FLAG, /* waiting for flag byte */ DICT4, /* four dictionary check bytes to go */ DICT3, /* three dictionary check bytes to go */ DICT2, /* two dictionary check bytes to go */ DICT1, /* one dictionary check byte to go */ DICT0, /* waiting for inflateSetDictionary */ BLOCKS, /* decompressing blocks */ CHECK4, /* four check bytes to go */ CHECK3, /* three check bytes to go */ CHECK2, /* two check bytes to go */ CHECK1, /* one check byte to go */ DONE, /* finished check, done */ BAD} /* got an error--stay here */ mode; /* current inflate mode */ /* mode dependent information */ union { uInt method; /* if FLAGS, method byte */ struct { uLong was; /* computed check value */ uLong need; /* stream check value */ } check; /* if CHECK, check values to compare */ uInt marker; /* if BAD, inflateSync's marker bytes count */ } sub; /* submode */ /* mode independent information */ int nowrap; /* flag for no wrapper */ uInt wbits; /* log2(window size) (8..15, defaults to 15) */ inflate_blocks_statef *blocks; /* current inflate_blocks state */ }; int inflateReset(z) z_streamp z; { uLong c; if (z == Z_NULL || z->state == Z_NULL) return Z_STREAM_ERROR; z->total_in = z->total_out = 0; z->msg = Z_NULL; z->state->mode = z->state->nowrap ? BLOCKS : METHOD; inflate_blocks_reset(z->state->blocks, z, &c); Trace((stderr, "inflate: reset\n")); return Z_OK; } int inflateEnd(z) z_streamp z; { uLong c; if (z == Z_NULL || z->state == Z_NULL || z->zfree == Z_NULL) return Z_STREAM_ERROR; if (z->state->blocks != Z_NULL) inflate_blocks_free(z->state->blocks, z, &c); ZFREE(z, z->state); z->state = Z_NULL; Trace((stderr, "inflate: end\n")); return Z_OK; } int inflateInit2_(z, w, version, stream_size) z_streamp z; int w; const char *version; int stream_size; { if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || stream_size != sizeof(z_stream)) return Z_VERSION_ERROR; /* initialize state */ if (z == Z_NULL) return Z_STREAM_ERROR; z->msg = Z_NULL; #ifndef NO_ZCFUNCS if (z->zalloc == Z_NULL) { z->zalloc = zcalloc; z->opaque = (voidpf)0; } if (z->zfree == Z_NULL) z->zfree = zcfree; #endif if ((z->state = (struct internal_state FAR *) ZALLOC(z,1,sizeof(struct internal_state))) == Z_NULL) return Z_MEM_ERROR; z->state->blocks = Z_NULL; /* handle undocumented nowrap option (no zlib header or check) */ z->state->nowrap = 0; if (w < 0) { w = - w; z->state->nowrap = 1; } /* set window size */ if (w < 8 || w > 15) { inflateEnd(z); return Z_STREAM_ERROR; } z->state->wbits = (uInt)w; /* create inflate_blocks state */ if ((z->state->blocks = inflate_blocks_new(z, z->state->nowrap ? Z_NULL : adler32, (uInt)1 << w)) == Z_NULL) { inflateEnd(z); return Z_MEM_ERROR; } Trace((stderr, "inflate: allocated\n")); /* reset state */ inflateReset(z); return Z_OK; } int inflateInit_(z, version, stream_size) z_streamp z; const char *version; int stream_size; { return inflateInit2_(z, DEF_WBITS, version, stream_size); } #define NEEDBYTE {if(z->avail_in==0)goto empty;r=Z_OK;} #define NEXTBYTE (z->avail_in--,z->total_in++,*z->next_in++) int inflate(z, f) z_streamp z; int f; { int r; uInt b; if (z == Z_NULL || z->state == Z_NULL || z->next_in == Z_NULL || f < 0) return Z_STREAM_ERROR; r = Z_BUF_ERROR; while (1) switch (z->state->mode) { case METHOD: NEEDBYTE if (((z->state->sub.method = NEXTBYTE) & 0xf) != Z_DEFLATED) { z->state->mode = BAD; z->msg = (char*)"unknown compression method"; z->state->sub.marker = 5; /* can't try inflateSync */ break; } if ((z->state->sub.method >> 4) + 8 > z->state->wbits) { z->state->mode = BAD; z->msg = (char*)"invalid window size"; z->state->sub.marker = 5; /* can't try inflateSync */ break; } z->state->mode = FLAG; case FLAG: NEEDBYTE b = NEXTBYTE; if (((z->state->sub.method << 8) + b) % 31) { z->state->mode = BAD; z->msg = (char*)"incorrect header check"; z->state->sub.marker = 5; /* can't try inflateSync */ break; } Trace((stderr, "inflate: zlib header ok\n")); if (!(b & PRESET_DICT)) { z->state->mode = BLOCKS; break; } z->state->mode = DICT4; case DICT4: NEEDBYTE z->state->sub.check.need = (uLong)NEXTBYTE << 24; z->state->mode = DICT3; case DICT3: NEEDBYTE z->state->sub.check.need += (uLong)NEXTBYTE << 16; z->state->mode = DICT2; case DICT2: NEEDBYTE z->state->sub.check.need += (uLong)NEXTBYTE << 8; z->state->mode = DICT1; case DICT1: NEEDBYTE z->state->sub.check.need += (uLong)NEXTBYTE; z->adler = z->state->sub.check.need; z->state->mode = DICT0; return Z_NEED_DICT; case DICT0: z->state->mode = BAD; z->msg = (char*)"need dictionary"; z->state->sub.marker = 0; /* can try inflateSync */ return Z_STREAM_ERROR; case BLOCKS: r = inflate_blocks(z->state->blocks, z, r); if (f == Z_PACKET_FLUSH && z->avail_in == 0 && z->avail_out != 0) r = inflate_packet_flush(z->state->blocks); if (r == Z_DATA_ERROR) { z->state->mode = BAD; z->state->sub.marker = 0; /* can try inflateSync */ break; } if (r != Z_STREAM_END) return r; r = Z_OK; inflate_blocks_reset(z->state->blocks, z, &z->state->sub.check.was); if (z->state->nowrap) { z->state->mode = DONE; break; } z->state->mode = CHECK4; case CHECK4: NEEDBYTE z->state->sub.check.need = (uLong)NEXTBYTE << 24; z->state->mode = CHECK3; case CHECK3: NEEDBYTE z->state->sub.check.need += (uLong)NEXTBYTE << 16; z->state->mode = CHECK2; case CHECK2: NEEDBYTE z->state->sub.check.need += (uLong)NEXTBYTE << 8; z->state->mode = CHECK1; case CHECK1: NEEDBYTE z->state->sub.check.need += (uLong)NEXTBYTE; if (z->state->sub.check.was != z->state->sub.check.need) { z->state->mode = BAD; z->msg = (char*)"incorrect data check"; z->state->sub.marker = 5; /* can't try inflateSync */ break; } Trace((stderr, "inflate: zlib check ok\n")); z->state->mode = DONE; case DONE: return Z_STREAM_END; case BAD: return Z_DATA_ERROR; default: return Z_STREAM_ERROR; } empty: if (f != Z_PACKET_FLUSH) return r; z->state->mode = BAD; z->msg = (char *)"need more for packet flush"; z->state->sub.marker = 0; /* can try inflateSync */ return Z_DATA_ERROR; } int inflateSetDictionary(z, dictionary, dictLength) z_streamp z; const Bytef *dictionary; uInt dictLength; { uInt length = dictLength; if (z == Z_NULL || z->state == Z_NULL || z->state->mode != DICT0) return Z_STREAM_ERROR; if (adler32(1L, dictionary, dictLength) != z->adler) return Z_DATA_ERROR; z->adler = 1L; if (length >= ((uInt)1<state->wbits)) { length = (1<state->wbits)-1; dictionary += dictLength - length; } inflate_set_dictionary(z->state->blocks, dictionary, length); z->state->mode = BLOCKS; return Z_OK; } /* * This subroutine adds the data at next_in/avail_in to the output history * without performing any output. The output buffer must be "caught up"; * i.e. no pending output (hence s->read equals s->write), and the state must * be BLOCKS (i.e. we should be willing to see the start of a series of * BLOCKS). On exit, the output will also be caught up, and the checksum * will have been updated if need be. */ int inflateIncomp(z) z_stream *z; { if (z->state->mode != BLOCKS) return Z_DATA_ERROR; return inflate_addhistory(z->state->blocks, z); } int inflateSync(z) z_streamp z; { uInt n; /* number of bytes to look at */ Bytef *p; /* pointer to bytes */ uInt m; /* number of marker bytes found in a row */ uLong r, w; /* temporaries to save total_in and total_out */ /* set up */ if (z == Z_NULL || z->state == Z_NULL) return Z_STREAM_ERROR; if (z->state->mode != BAD) { z->state->mode = BAD; z->state->sub.marker = 0; } if ((n = z->avail_in) == 0) return Z_BUF_ERROR; p = z->next_in; m = z->state->sub.marker; /* search */ while (n && m < 4) { if (*p == (Byte)(m < 2 ? 0 : 0xff)) m++; else if (*p) m = 0; else m = 4 - m; p++, n--; } /* restore */ z->total_in += p - z->next_in; z->next_in = p; z->avail_in = n; z->state->sub.marker = m; /* return no joy or set up to restart on a new block */ if (m != 4) return Z_DATA_ERROR; r = z->total_in; w = z->total_out; inflateReset(z); z->total_in = r; z->total_out = w; z->state->mode = BLOCKS; return Z_OK; } #undef NEEDBYTE #undef NEXTBYTE /* --- inflate.c */ /* +++ infblock.c */ /* infblock.c -- interpret and process block types to last block * Copyright (C) 1995-1996 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ /* #include "zutil.h" */ /* #include "infblock.h" */ /* +++ inftrees.h */ /* inftrees.h -- header to use inftrees.c * Copyright (C) 1995-1996 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ /* WARNING: this file should *not* be used by applications. It is part of the implementation of the compression library and is subject to change. Applications should only use zlib.h. */ /* Huffman code lookup table entry--this entry is four bytes for machines that have 16-bit pointers (e.g. PC's in the small or medium model). */ typedef struct inflate_huft_s FAR inflate_huft; struct inflate_huft_s { union { struct { Byte Exop; /* number of extra bits or operation */ Byte Bits; /* number of bits in this code or subcode */ } what; Bytef *pad; /* pad structure to a power of 2 (4 bytes for */ } word; /* 16-bit, 8 bytes for 32-bit machines) */ union { uInt Base; /* literal, length base, or distance base */ inflate_huft *Next; /* pointer to next level of table */ } more; }; #ifdef DEBUG_ZLIB extern uInt inflate_hufts; #endif extern int inflate_trees_bits OF(( uIntf *, /* 19 code lengths */ uIntf *, /* bits tree desired/actual depth */ inflate_huft * FAR *, /* bits tree result */ z_streamp )); /* for zalloc, zfree functions */ extern int inflate_trees_dynamic OF(( uInt, /* number of literal/length codes */ uInt, /* number of distance codes */ uIntf *, /* that many (total) code lengths */ uIntf *, /* literal desired/actual bit depth */ uIntf *, /* distance desired/actual bit depth */ inflate_huft * FAR *, /* literal/length tree result */ inflate_huft * FAR *, /* distance tree result */ z_streamp )); /* for zalloc, zfree functions */ extern int inflate_trees_fixed OF(( uIntf *, /* literal desired/actual bit depth */ uIntf *, /* distance desired/actual bit depth */ inflate_huft * FAR *, /* literal/length tree result */ inflate_huft * FAR *)); /* distance tree result */ extern int inflate_trees_free OF(( inflate_huft *, /* tables to free */ z_streamp )); /* for zfree function */ /* --- inftrees.h */ /* +++ infcodes.h */ /* infcodes.h -- header to use infcodes.c * Copyright (C) 1995-1996 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ /* WARNING: this file should *not* be used by applications. It is part of the implementation of the compression library and is subject to change. Applications should only use zlib.h. */ struct inflate_codes_state; typedef struct inflate_codes_state FAR inflate_codes_statef; extern inflate_codes_statef *inflate_codes_new OF(( uInt, uInt, inflate_huft *, inflate_huft *, z_streamp )); extern int inflate_codes OF(( inflate_blocks_statef *, z_streamp , int)); extern void inflate_codes_free OF(( inflate_codes_statef *, z_streamp )); /* --- infcodes.h */ /* +++ infutil.h */ /* infutil.h -- types and macros common to blocks and codes * Copyright (C) 1995-1996 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ /* WARNING: this file should *not* be used by applications. It is part of the implementation of the compression library and is subject to change. Applications should only use zlib.h. */ #ifndef _INFUTIL_H #define _INFUTIL_H typedef enum { TYPE, /* get type bits (3, including end bit) */ LENS, /* get lengths for stored */ STORED, /* processing stored block */ TABLE, /* get table lengths */ BTREE, /* get bit lengths tree for a dynamic block */ DTREE, /* get length, distance trees for a dynamic block */ CODES, /* processing fixed or dynamic block */ DRY, /* output remaining window bytes */ DONEB, /* finished last block, done */ BADB} /* got a data error--stuck here */ inflate_block_mode; /* inflate blocks semi-private state */ struct inflate_blocks_state { /* mode */ inflate_block_mode mode; /* current inflate_block mode */ /* mode dependent information */ union { uInt left; /* if STORED, bytes left to copy */ struct { uInt table; /* table lengths (14 bits) */ uInt index; /* index into blens (or border) */ uIntf *blens; /* bit lengths of codes */ uInt bb; /* bit length tree depth */ inflate_huft *tb; /* bit length decoding tree */ } trees; /* if DTREE, decoding info for trees */ struct { inflate_huft *tl; inflate_huft *td; /* trees to free */ inflate_codes_statef *codes; } decode; /* if CODES, current state */ } sub; /* submode */ uInt last; /* true if this block is the last block */ /* mode independent information */ uInt bitk; /* bits in bit buffer */ uLong bitb; /* bit buffer */ Bytef *window; /* sliding window */ Bytef *end; /* one byte after sliding window */ Bytef *read; /* window read pointer */ Bytef *write; /* window write pointer */ check_func checkfn; /* check function */ uLong check; /* check on output */ }; /* defines for inflate input/output */ /* update pointers and return */ #define UPDBITS {s->bitb=b;s->bitk=k;} #define UPDIN {z->avail_in=n;z->total_in+=p-z->next_in;z->next_in=p;} #define UPDOUT {s->write=q;} #define UPDATE {UPDBITS UPDIN UPDOUT} #define LEAVE {UPDATE return inflate_flush(s,z,r);} /* get bytes and bits */ #define LOADIN {p=z->next_in;n=z->avail_in;b=s->bitb;k=s->bitk;} #define NEEDBYTE {if(n)r=Z_OK;else LEAVE} #define NEXTBYTE (n--,*p++) #define NEEDBITS(j) {while(k<(j)){NEEDBYTE;b|=((uLong)NEXTBYTE)<>=(j);k-=(j);} /* output bytes */ #define WAVAIL (uInt)(qread?s->read-q-1:s->end-q) #define LOADOUT {q=s->write;m=(uInt)WAVAIL;} #define WWRAP {if(q==s->end&&s->read!=s->window){q=s->window;m=(uInt)WAVAIL;}} #define FLUSH {UPDOUT r=inflate_flush(s,z,r); LOADOUT} #define NEEDOUT {if(m==0){WWRAP if(m==0){FLUSH WWRAP if(m==0) LEAVE}}r=Z_OK;} #define OUTBYTE(a) {*q++=(Byte)(a);m--;} /* load local pointers */ #define LOAD {LOADIN LOADOUT} /* masks for lower bits (size given to avoid silly warnings with Visual C++) */ extern uInt inflate_mask[17]; /* copy as much as possible from the sliding window to the output area */ extern int inflate_flush OF(( inflate_blocks_statef *, z_streamp , int)); #ifndef NO_DUMMY_DECL struct internal_state {int dummy;}; /* for buggy compilers */ #endif #endif /* --- infutil.h */ #ifndef NO_DUMMY_DECL struct inflate_codes_state {int dummy;}; /* for buggy compilers */ #endif /* Table for deflate from PKZIP's appnote.txt. */ local const uInt border[] = { /* Order of the bit length code lengths */ 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; /* Notes beyond the 1.93a appnote.txt: 1. Distance pointers never point before the beginning of the output stream. 2. Distance pointers can point back across blocks, up to 32k away. 3. There is an implied maximum of 7 bits for the bit length table and 15 bits for the actual data. 4. If only one code exists, then it is encoded using one bit. (Zero would be more efficient, but perhaps a little confusing.) If two codes exist, they are coded using one bit each (0 and 1). 5. There is no way of sending zero distance codes--a dummy must be sent if there are none. (History: a pre 2.0 version of PKZIP would store blocks with no distance codes, but this was discovered to be too harsh a criterion.) Valid only for 1.93a. 2.04c does allow zero distance codes, which is sent as one code of zero bits in length. 6. There are up to 286 literal/length codes. Code 256 represents the end-of-block. Note however that the static length tree defines 288 codes just to fill out the Huffman codes. Codes 286 and 287 cannot be used though, since there is no length base or extra bits defined for them. Similarily, there are up to 30 distance codes. However, static trees define 32 codes (all 5 bits) to fill out the Huffman codes, but the last two had better not show up in the data. 7. Unzip can check dynamic Huffman blocks for complete code sets. The exception is that a single code would not be complete (see #4). 8. The five bits following the block type is really the number of literal codes sent minus 257. 9. Length codes 8,16,16 are interpreted as 13 length codes of 8 bits (1+6+6). Therefore, to output three times the length, you output three codes (1+1+1), whereas to output four times the same length, you only need two codes (1+3). Hmm. 10. In the tree reconstruction algorithm, Code = Code + Increment only if BitLength(i) is not zero. (Pretty obvious.) 11. Correction: 4 Bits: # of Bit Length codes - 4 (4 - 19) 12. Note: length code 284 can represent 227-258, but length code 285 really is 258. The last length deserves its own, short code since it gets used a lot in very redundant files. The length 258 is special since 258 - 3 (the min match length) is 255. 13. The literal/length and distance code bit lengths are read as a single stream of lengths. It is possible (and advantageous) for a repeat code (16, 17, or 18) to go across the boundary between the two sets of lengths. */ void inflate_blocks_reset(s, z, c) inflate_blocks_statef *s; z_streamp z; uLongf *c; { if (s->checkfn != Z_NULL) *c = s->check; if (s->mode == BTREE || s->mode == DTREE) ZFREE(z, s->sub.trees.blens); if (s->mode == CODES) { inflate_codes_free(s->sub.decode.codes, z); inflate_trees_free(s->sub.decode.td, z); inflate_trees_free(s->sub.decode.tl, z); } s->mode = TYPE; s->bitk = 0; s->bitb = 0; s->read = s->write = s->window; if (s->checkfn != Z_NULL) z->adler = s->check = (*s->checkfn)(0L, Z_NULL, 0); Trace((stderr, "inflate: blocks reset\n")); } inflate_blocks_statef *inflate_blocks_new(z, c, w) z_streamp z; check_func c; uInt w; { inflate_blocks_statef *s; if ((s = (inflate_blocks_statef *)ZALLOC (z,1,sizeof(struct inflate_blocks_state))) == Z_NULL) return s; if ((s->window = (Bytef *)ZALLOC(z, 1, w)) == Z_NULL) { ZFREE(z, s); return Z_NULL; } s->end = s->window + w; s->checkfn = c; s->mode = TYPE; Trace((stderr, "inflate: blocks allocated\n")); inflate_blocks_reset(s, z, &s->check); return s; } #ifdef DEBUG_ZLIB extern uInt inflate_hufts; #endif int inflate_blocks(s, z, r) inflate_blocks_statef *s; z_streamp z; int r; { uInt t; /* temporary storage */ uLong b; /* bit buffer */ uInt k; /* bits in bit buffer */ Bytef *p; /* input data pointer */ uInt n; /* bytes available there */ Bytef *q; /* output window write pointer */ uInt m; /* bytes to end of window or read pointer */ /* copy input/output information to locals (UPDATE macro restores) */ LOAD /* process input based on current state */ while (1) switch (s->mode) { case TYPE: NEEDBITS(3) t = (uInt)b & 7; s->last = t & 1; switch (t >> 1) { case 0: /* stored */ Trace((stderr, "inflate: stored block%s\n", s->last ? " (last)" : "")); DUMPBITS(3) t = k & 7; /* go to byte boundary */ DUMPBITS(t) s->mode = LENS; /* get length of stored block */ break; case 1: /* fixed */ Trace((stderr, "inflate: fixed codes block%s\n", s->last ? " (last)" : "")); { uInt bl, bd; inflate_huft *tl, *td; inflate_trees_fixed(&bl, &bd, &tl, &td); s->sub.decode.codes = inflate_codes_new(bl, bd, tl, td, z); if (s->sub.decode.codes == Z_NULL) { r = Z_MEM_ERROR; LEAVE } s->sub.decode.tl = Z_NULL; /* don't try to free these */ s->sub.decode.td = Z_NULL; } DUMPBITS(3) s->mode = CODES; break; case 2: /* dynamic */ Trace((stderr, "inflate: dynamic codes block%s\n", s->last ? " (last)" : "")); DUMPBITS(3) s->mode = TABLE; break; case 3: /* illegal */ DUMPBITS(3) s->mode = BADB; z->msg = (char*)"invalid block type"; r = Z_DATA_ERROR; LEAVE } break; case LENS: NEEDBITS(32) if ((((~b) >> 16) & 0xffff) != (b & 0xffff)) { s->mode = BADB; z->msg = (char*)"invalid stored block lengths"; r = Z_DATA_ERROR; LEAVE } s->sub.left = (uInt)b & 0xffff; b = k = 0; /* dump bits */ Tracev((stderr, "inflate: stored length %u\n", s->sub.left)); s->mode = s->sub.left ? STORED : (s->last ? DRY : TYPE); break; case STORED: if (n == 0) LEAVE NEEDOUT t = s->sub.left; if (t > n) t = n; if (t > m) t = m; zmemcpy(q, p, t); p += t; n -= t; q += t; m -= t; if ((s->sub.left -= t) != 0) break; Tracev((stderr, "inflate: stored end, %lu total out\n", z->total_out + (q >= s->read ? q - s->read : (s->end - s->read) + (q - s->window)))); s->mode = s->last ? DRY : TYPE; break; case TABLE: NEEDBITS(14) s->sub.trees.table = t = (uInt)b & 0x3fff; #ifndef PKZIP_BUG_WORKAROUND if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29) { s->mode = BADB; z->msg = (char*)"too many length or distance symbols"; r = Z_DATA_ERROR; LEAVE } #endif t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f); if (t < 19) t = 19; if ((s->sub.trees.blens = (uIntf*)ZALLOC(z, t, sizeof(uInt))) == Z_NULL) { r = Z_MEM_ERROR; LEAVE } DUMPBITS(14) s->sub.trees.index = 0; Tracev((stderr, "inflate: table sizes ok\n")); s->mode = BTREE; case BTREE: while (s->sub.trees.index < 4 + (s->sub.trees.table >> 10)) { NEEDBITS(3) s->sub.trees.blens[border[s->sub.trees.index++]] = (uInt)b & 7; DUMPBITS(3) } while (s->sub.trees.index < 19) s->sub.trees.blens[border[s->sub.trees.index++]] = 0; s->sub.trees.bb = 7; t = inflate_trees_bits(s->sub.trees.blens, &s->sub.trees.bb, &s->sub.trees.tb, z); if (t != Z_OK) { r = t; if (r == Z_DATA_ERROR) { s->mode = BADB; ZFREE(z, s->sub.trees.blens); } LEAVE } s->sub.trees.index = 0; Tracev((stderr, "inflate: bits tree ok\n")); s->mode = DTREE; case DTREE: while (t = s->sub.trees.table, s->sub.trees.index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f)) { inflate_huft *h; uInt i, j, c; t = s->sub.trees.bb; NEEDBITS(t) h = s->sub.trees.tb + ((uInt)b & inflate_mask[t]); t = h->word.what.Bits; c = h->more.Base; if (c < 16) { DUMPBITS(t) s->sub.trees.blens[s->sub.trees.index++] = c; } else /* c == 16..18 */ { i = c == 18 ? 7 : c - 14; j = c == 18 ? 11 : 3; NEEDBITS(t + i) DUMPBITS(t) j += (uInt)b & inflate_mask[i]; DUMPBITS(i) i = s->sub.trees.index; t = s->sub.trees.table; if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) || (c == 16 && i < 1)) { inflate_trees_free(s->sub.trees.tb, z); ZFREE(z, s->sub.trees.blens); s->mode = BADB; z->msg = (char*)"invalid bit length repeat"; r = Z_DATA_ERROR; LEAVE } c = c == 16 ? s->sub.trees.blens[i - 1] : 0; do { s->sub.trees.blens[i++] = c; } while (--j); s->sub.trees.index = i; } } inflate_trees_free(s->sub.trees.tb, z); s->sub.trees.tb = Z_NULL; { uInt bl, bd; inflate_huft *tl, *td; inflate_codes_statef *c; bl = 9; /* must be <= 9 for lookahead assumptions */ bd = 6; /* must be <= 9 for lookahead assumptions */ t = s->sub.trees.table; #ifdef DEBUG_ZLIB inflate_hufts = 0; #endif t = inflate_trees_dynamic(257 + (t & 0x1f), 1 + ((t >> 5) & 0x1f), s->sub.trees.blens, &bl, &bd, &tl, &td, z); if (t != Z_OK) { if (t == (uInt)Z_DATA_ERROR) { s->mode = BADB; ZFREE(z, s->sub.trees.blens); } r = t; LEAVE } ZFREE(z, s->sub.trees.blens); Tracev((stderr, "inflate: trees ok, %d * %d bytes used\n", inflate_hufts, sizeof(inflate_huft))); if ((c = inflate_codes_new(bl, bd, tl, td, z)) == Z_NULL) { inflate_trees_free(td, z); inflate_trees_free(tl, z); r = Z_MEM_ERROR; LEAVE } s->sub.decode.codes = c; s->sub.decode.tl = tl; s->sub.decode.td = td; } s->mode = CODES; case CODES: UPDATE if ((r = inflate_codes(s, z, r)) != Z_STREAM_END) return inflate_flush(s, z, r); r = Z_OK; inflate_codes_free(s->sub.decode.codes, z); inflate_trees_free(s->sub.decode.td, z); inflate_trees_free(s->sub.decode.tl, z); LOAD Tracev((stderr, "inflate: codes end, %lu total out\n", z->total_out + (q >= s->read ? q - s->read : (s->end - s->read) + (q - s->window)))); if (!s->last) { s->mode = TYPE; break; } if (k > 7) /* return unused byte, if any */ { Assert(k < 16, "inflate_codes grabbed too many bytes") k -= 8; n++; p--; /* can always return one */ } s->mode = DRY; case DRY: FLUSH if (s->read != s->write) LEAVE s->mode = DONEB; case DONEB: r = Z_STREAM_END; LEAVE case BADB: r = Z_DATA_ERROR; LEAVE default: r = Z_STREAM_ERROR; LEAVE } } int inflate_blocks_free(s, z, c) inflate_blocks_statef *s; z_streamp z; uLongf *c; { inflate_blocks_reset(s, z, c); ZFREE(z, s->window); ZFREE(z, s); Trace((stderr, "inflate: blocks freed\n")); return Z_OK; } void inflate_set_dictionary(s, d, n) inflate_blocks_statef *s; const Bytef *d; uInt n; { zmemcpy((charf *)s->window, d, n); s->read = s->write = s->window + n; } /* * This subroutine adds the data at next_in/avail_in to the output history * without performing any output. The output buffer must be "caught up"; * i.e. no pending output (hence s->read equals s->write), and the state must * be BLOCKS (i.e. we should be willing to see the start of a series of * BLOCKS). On exit, the output will also be caught up, and the checksum * will have been updated if need be. */ int inflate_addhistory(s, z) inflate_blocks_statef *s; z_stream *z; { uLong b; /* bit buffer */ /* NOT USED HERE */ uInt k; /* bits in bit buffer */ /* NOT USED HERE */ uInt t; /* temporary storage */ Bytef *p; /* input data pointer */ uInt n; /* bytes available there */ Bytef *q; /* output window write pointer */ uInt m; /* bytes to end of window or read pointer */ if (s->read != s->write) return Z_STREAM_ERROR; if (s->mode != TYPE) return Z_DATA_ERROR; /* we're ready to rock */ LOAD /* while there is input ready, copy to output buffer, moving * pointers as needed. */ while (n) { t = n; /* how many to do */ /* is there room until end of buffer? */ if (t > m) t = m; /* update check information */ if (s->checkfn != Z_NULL) s->check = (*s->checkfn)(s->check, q, t); zmemcpy(q, p, t); q += t; p += t; n -= t; z->total_out += t; s->read = q; /* drag read pointer forward */ /* WWRAP */ /* expand WWRAP macro by hand to handle s->read */ if (q == s->end) { s->read = q = s->window; m = WAVAIL; } } UPDATE return Z_OK; } /* * At the end of a Deflate-compressed PPP packet, we expect to have seen * a `stored' block type value but not the (zero) length bytes. */ int inflate_packet_flush(s) inflate_blocks_statef *s; { if (s->mode != LENS) return Z_DATA_ERROR; s->mode = TYPE; return Z_OK; } /* --- infblock.c */ /* +++ inftrees.c */ /* inftrees.c -- generate Huffman trees for efficient decoding * Copyright (C) 1995-1996 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ /* #include "zutil.h" */ /* #include "inftrees.h" */ char inflate_copyright[] = " inflate 1.0.4 Copyright 1995-1996 Mark Adler "; /* If you use the zlib library in a product, an acknowledgment is welcome in the documentation of your product. If for some reason you cannot include such an acknowledgment, I would appreciate that you keep this copyright string in the executable of your product. */ #ifndef NO_DUMMY_DECL struct internal_state {int dummy;}; /* for buggy compilers */ #endif /* simplify the use of the inflate_huft type with some defines */ #define base more.Base #define next more.Next #define exop word.what.Exop #define bits word.what.Bits local int huft_build OF(( uIntf *, /* code lengths in bits */ uInt, /* number of codes */ uInt, /* number of "simple" codes */ const uIntf *, /* list of base values for non-simple codes */ const uIntf *, /* list of extra bits for non-simple codes */ inflate_huft * FAR*,/* result: starting table */ uIntf *, /* maximum lookup bits (returns actual) */ z_streamp )); /* for zalloc function */ local voidpf falloc OF(( voidpf, /* opaque pointer (not used) */ uInt, /* number of items */ uInt)); /* size of item */ /* Tables for deflate from PKZIP's appnote.txt. */ local const uInt cplens[31] = { /* Copy lengths for literal codes 257..285 */ 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; /* see note #13 above about 258 */ local const uInt cplext[31] = { /* Extra bits for literal codes 257..285 */ 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 112, 112}; /* 112==invalid */ local const uInt cpdist[30] = { /* Copy offsets for distance codes 0..29 */ 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577}; local const uInt cpdext[30] = { /* Extra bits for distance codes */ 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13}; /* Huffman code decoding is performed using a multi-level table lookup. The fastest way to decode is to simply build a lookup table whose size is determined by the longest code. However, the time it takes to build this table can also be a factor if the data being decoded is not very long. The most common codes are necessarily the shortest codes, so those codes dominate the decoding time, and hence the speed. The idea is you can have a shorter table that decodes the shorter, more probable codes, and then point to subsidiary tables for the longer codes. The time it costs to decode the longer codes is then traded against the time it takes to make longer tables. This results of this trade are in the variables lbits and dbits below. lbits is the number of bits the first level table for literal/ length codes can decode in one step, and dbits is the same thing for the distance codes. Subsequent tables are also less than or equal to those sizes. These values may be adjusted either when all of the codes are shorter than that, in which case the longest code length in bits is used, or when the shortest code is *longer* than the requested table size, in which case the length of the shortest code in bits is used. There are two different values for the two tables, since they code a different number of possibilities each. The literal/length table codes 286 possible values, or in a flat code, a little over eight bits. The distance table codes 30 possible values, or a little less than five bits, flat. The optimum values for speed end up being about one bit more than those, so lbits is 8+1 and dbits is 5+1. The optimum values may differ though from machine to machine, and possibly even between compilers. Your mileage may vary. */ /* If BMAX needs to be larger than 16, then h and x[] should be uLong. */ #define BMAX 15 /* maximum bit length of any code */ #define N_MAX 288 /* maximum number of codes in any set */ #ifdef DEBUG_ZLIB uInt inflate_hufts; #endif local int huft_build(b, n, s, d, e, t, m, zs) uIntf *b; /* code lengths in bits (all assumed <= BMAX) */ uInt n; /* number of codes (assumed <= N_MAX) */ uInt s; /* number of simple-valued codes (0..s-1) */ const uIntf *d; /* list of base values for non-simple codes */ const uIntf *e; /* list of extra bits for non-simple codes */ inflate_huft * FAR *t; /* result: starting table */ uIntf *m; /* maximum lookup bits, returns actual */ z_streamp zs; /* for zalloc function */ /* Given a list of code lengths and a maximum table size, make a set of tables to decode that set of codes. Return Z_OK on success, Z_BUF_ERROR if the given code set is incomplete (the tables are still built in this case), Z_DATA_ERROR if the input is invalid (an over-subscribed set of lengths), or Z_MEM_ERROR if not enough memory. */ { uInt a; /* counter for codes of length k */ uInt c[BMAX+1]; /* bit length count table */ uInt f; /* i repeats in table every f entries */ int g; /* maximum code length */ int h; /* table level */ register uInt i; /* counter, current code */ register uInt j; /* counter */ register int k; /* number of bits in current code */ int l; /* bits per table (returned in m) */ register uIntf *p; /* pointer into c[], b[], or v[] */ inflate_huft *q; /* points to current table */ struct inflate_huft_s r; /* table entry for structure assignment */ inflate_huft *u[BMAX]; /* table stack */ uInt v[N_MAX]; /* values in order of bit length */ register int w; /* bits before this table == (l * h) */ uInt x[BMAX+1]; /* bit offsets, then code stack */ uIntf *xp; /* pointer into x */ int y; /* number of dummy codes added */ uInt z; /* number of entries in current table */ /* Generate counts for each bit length */ p = c; #define C0 *p++ = 0; #define C2 C0 C0 C0 C0 #define C4 C2 C2 C2 C2 C4 /* clear c[]--assume BMAX+1 is 16 */ p = b; i = n; do { c[*p++]++; /* assume all entries <= BMAX */ } while (--i); if (c[0] == n) /* null input--all zero length codes */ { *t = (inflate_huft *)Z_NULL; *m = 0; return Z_OK; } /* Find minimum and maximum length, bound *m by those */ l = *m; for (j = 1; j <= BMAX; j++) if (c[j]) break; k = j; /* minimum code length */ if ((uInt)l < j) l = j; for (i = BMAX; i; i--) if (c[i]) break; g = i; /* maximum code length */ if ((uInt)l > i) l = i; *m = l; /* Adjust last length count to fill out codes, if needed */ for (y = 1 << j; j < i; j++, y <<= 1) if ((y -= c[j]) < 0) return Z_DATA_ERROR; if ((y -= c[i]) < 0) return Z_DATA_ERROR; c[i] += y; /* Generate starting offsets into the value table for each length */ x[1] = j = 0; p = c + 1; xp = x + 2; while (--i) { /* note that i == g from above */ *xp++ = (j += *p++); } /* Make a table of values in order of bit lengths */ p = b; i = 0; do { if ((j = *p++) != 0) v[x[j]++] = i; } while (++i < n); n = x[g]; /* set n to length of v */ /* Generate the Huffman codes and for each, make the table entries */ x[0] = i = 0; /* first Huffman code is zero */ p = v; /* grab values in bit order */ h = -1; /* no tables yet--level -1 */ w = -l; /* bits decoded == (l * h) */ u[0] = (inflate_huft *)Z_NULL; /* just to keep compilers happy */ q = (inflate_huft *)Z_NULL; /* ditto */ z = 0; /* ditto */ /* go through the bit lengths (k already is bits in shortest code) */ for (; k <= g; k++) { a = c[k]; while (a--) { /* here i is the Huffman code of length k bits for value *p */ /* make tables up to required level */ while (k > w + l) { h++; w += l; /* previous table always l bits */ /* compute minimum size table less than or equal to l bits */ z = g - w; z = z > (uInt)l ? l : z; /* table size upper limit */ if ((f = 1 << (j = k - w)) > a + 1) /* try a k-w bit table */ { /* too few codes for k-w bit table */ f -= a + 1; /* deduct codes from patterns left */ xp = c + k; if (j < z) while (++j < z) /* try smaller tables up to z bits */ { if ((f <<= 1) <= *++xp) break; /* enough codes to use up j bits */ f -= *xp; /* else deduct codes from patterns */ } } z = 1 << j; /* table entries for j-bit table */ /* allocate and link in new table */ if ((q = (inflate_huft *)ZALLOC (zs,z + 1,sizeof(inflate_huft))) == Z_NULL) { if (h) inflate_trees_free(u[0], zs); return Z_MEM_ERROR; /* not enough memory */ } #ifdef DEBUG_ZLIB inflate_hufts += z + 1; #endif *t = q + 1; /* link to list for huft_free() */ *(t = &(q->next)) = Z_NULL; u[h] = ++q; /* table starts after link */ /* connect to last table, if there is one */ if (h) { x[h] = i; /* save pattern for backing up */ r.bits = (Byte)l; /* bits to dump before this table */ r.exop = (Byte)j; /* bits in this table */ r.next = q; /* pointer to this table */ j = i >> (w - l); /* (get around Turbo C bug) */ u[h-1][j] = r; /* connect to last table */ } } /* set up table entry in r */ r.bits = (Byte)(k - w); if (p >= v + n) r.exop = 128 + 64; /* out of values--invalid code */ else if (*p < s) { r.exop = (Byte)(*p < 256 ? 0 : 32 + 64); /* 256 is end-of-block */ r.base = *p++; /* simple code is just the value */ } else { r.exop = (Byte)(e[*p - s] + 16 + 64);/* non-simple--look up in lists */ r.base = d[*p++ - s]; } /* fill code-like entries with r */ f = 1 << (k - w); for (j = i >> w; j < z; j += f) q[j] = r; /* backwards increment the k-bit code i */ for (j = 1 << (k - 1); i & j; j >>= 1) i ^= j; i ^= j; /* backup over finished tables */ while ((i & ((1 << w) - 1)) != x[h]) { h--; /* don't need to update q */ w -= l; } } } /* Return Z_BUF_ERROR if we were given an incomplete table */ return y != 0 && g != 1 ? Z_BUF_ERROR : Z_OK; } int inflate_trees_bits(c, bb, tb, z) uIntf *c; /* 19 code lengths */ uIntf *bb; /* bits tree desired/actual depth */ inflate_huft * FAR *tb; /* bits tree result */ z_streamp z; /* for zfree function */ { int r; r = huft_build(c, 19, 19, (uIntf*)Z_NULL, (uIntf*)Z_NULL, tb, bb, z); if (r == Z_DATA_ERROR) z->msg = (char*)"oversubscribed dynamic bit lengths tree"; else if (r == Z_BUF_ERROR || *bb == 0) { inflate_trees_free(*tb, z); z->msg = (char*)"incomplete dynamic bit lengths tree"; r = Z_DATA_ERROR; } return r; } int inflate_trees_dynamic(nl, nd, c, bl, bd, tl, td, z) uInt nl; /* number of literal/length codes */ uInt nd; /* number of distance codes */ uIntf *c; /* that many (total) code lengths */ uIntf *bl; /* literal desired/actual bit depth */ uIntf *bd; /* distance desired/actual bit depth */ inflate_huft * FAR *tl; /* literal/length tree result */ inflate_huft * FAR *td; /* distance tree result */ z_streamp z; /* for zfree function */ { int r; /* build literal/length tree */ r = huft_build(c, nl, 257, cplens, cplext, tl, bl, z); if (r != Z_OK || *bl == 0) { if (r == Z_DATA_ERROR) z->msg = (char*)"oversubscribed literal/length tree"; else if (r != Z_MEM_ERROR) { inflate_trees_free(*tl, z); z->msg = (char*)"incomplete literal/length tree"; r = Z_DATA_ERROR; } return r; } /* build distance tree */ r = huft_build(c + nl, nd, 0, cpdist, cpdext, td, bd, z); if (r != Z_OK || (*bd == 0 && nl > 257)) { if (r == Z_DATA_ERROR) z->msg = (char*)"oversubscribed distance tree"; else if (r == Z_BUF_ERROR) { #ifdef PKZIP_BUG_WORKAROUND r = Z_OK; } #else inflate_trees_free(*td, z); z->msg = (char*)"incomplete distance tree"; r = Z_DATA_ERROR; } else if (r != Z_MEM_ERROR) { z->msg = (char*)"empty distance tree with lengths"; r = Z_DATA_ERROR; } inflate_trees_free(*tl, z); return r; #endif } /* done */ return Z_OK; } /* build fixed tables only once--keep them here */ local int fixed_built = 0; #define FIXEDH 530 /* number of hufts used by fixed tables */ local inflate_huft fixed_mem[FIXEDH]; local uInt fixed_bl; local uInt fixed_bd; local inflate_huft *fixed_tl; local inflate_huft *fixed_td; local voidpf falloc(q, n, s) voidpf q; /* opaque pointer */ uInt n; /* number of items */ uInt s; /* size of item */ { Assert(s == sizeof(inflate_huft) && n <= *(intf *)q, "inflate_trees falloc overflow"); *(intf *)q -= n+s-s; /* s-s to avoid warning */ return (voidpf)(fixed_mem + *(intf *)q); } int inflate_trees_fixed(bl, bd, tl, td) uIntf *bl; /* literal desired/actual bit depth */ uIntf *bd; /* distance desired/actual bit depth */ inflate_huft * FAR *tl; /* literal/length tree result */ inflate_huft * FAR *td; /* distance tree result */ { /* build fixed tables if not already (multiple overlapped executions ok) */ if (!fixed_built) { int k; /* temporary variable */ unsigned c[288]; /* length list for huft_build */ z_stream z; /* for falloc function */ int f = FIXEDH; /* number of hufts left in fixed_mem */ /* set up fake z_stream for memory routines */ z.zalloc = falloc; z.zfree = Z_NULL; z.opaque = (voidpf)&f; /* literal table */ for (k = 0; k < 144; k++) c[k] = 8; for (; k < 256; k++) c[k] = 9; for (; k < 280; k++) c[k] = 7; for (; k < 288; k++) c[k] = 8; fixed_bl = 7; huft_build(c, 288, 257, cplens, cplext, &fixed_tl, &fixed_bl, &z); /* distance table */ for (k = 0; k < 30; k++) c[k] = 5; fixed_bd = 5; huft_build(c, 30, 0, cpdist, cpdext, &fixed_td, &fixed_bd, &z); /* done */ Assert(f == 0, "invalid build of fixed tables"); fixed_built = 1; } *bl = fixed_bl; *bd = fixed_bd; *tl = fixed_tl; *td = fixed_td; return Z_OK; } int inflate_trees_free(t, z) inflate_huft *t; /* table to free */ z_streamp z; /* for zfree function */ /* Free the malloc'ed tables built by huft_build(), which makes a linked list of the tables it made, with the links in a dummy first entry of each table. */ { register inflate_huft *p, *q, *r; /* Reverse linked list */ p = Z_NULL; q = t; while (q != Z_NULL) { r = (q - 1)->next; (q - 1)->next = p; p = q; q = r; } /* Go through linked list, freeing from the malloced (t[-1]) address. */ while (p != Z_NULL) { q = (--p)->next; ZFREE(z,p); p = q; } return Z_OK; } /* --- inftrees.c */ /* +++ infcodes.c */ /* infcodes.c -- process literals and length/distance pairs * Copyright (C) 1995-1996 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ /* #include "zutil.h" */ /* #include "inftrees.h" */ /* #include "infblock.h" */ /* #include "infcodes.h" */ /* #include "infutil.h" */ /* +++ inffast.h */ /* inffast.h -- header to use inffast.c * Copyright (C) 1995-1996 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ /* WARNING: this file should *not* be used by applications. It is part of the implementation of the compression library and is subject to change. Applications should only use zlib.h. */ extern int inflate_fast OF(( uInt, uInt, inflate_huft *, inflate_huft *, inflate_blocks_statef *, z_streamp )); /* --- inffast.h */ /* simplify the use of the inflate_huft type with some defines */ #define base more.Base #define next more.Next #define exop word.what.Exop #define bits word.what.Bits /* inflate codes private state */ struct inflate_codes_state { /* mode */ enum { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */ START, /* x: set up for LEN */ LEN, /* i: get length/literal/eob next */ LENEXT, /* i: getting length extra (have base) */ DIST, /* i: get distance next */ DISTEXT, /* i: getting distance extra */ COPY, /* o: copying bytes in window, waiting for space */ LIT, /* o: got literal, waiting for output space */ WASH, /* o: got eob, possibly still output waiting */ END, /* x: got eob and all data flushed */ BADCODE} /* x: got error */ mode; /* current inflate_codes mode */ /* mode dependent information */ uInt len; union { struct { inflate_huft *tree; /* pointer into tree */ uInt need; /* bits needed */ } code; /* if LEN or DIST, where in tree */ uInt lit; /* if LIT, literal */ struct { uInt get; /* bits to get for extra */ uInt dist; /* distance back to copy from */ } copy; /* if EXT or COPY, where and how much */ } sub; /* submode */ /* mode independent information */ Byte lbits; /* ltree bits decoded per branch */ Byte dbits; /* dtree bits decoder per branch */ inflate_huft *ltree; /* literal/length/eob tree */ inflate_huft *dtree; /* distance tree */ }; inflate_codes_statef *inflate_codes_new(bl, bd, tl, td, z) uInt bl, bd; inflate_huft *tl; inflate_huft *td; /* need separate declaration for Borland C++ */ z_streamp z; { inflate_codes_statef *c; if ((c = (inflate_codes_statef *) ZALLOC(z,1,sizeof(struct inflate_codes_state))) != Z_NULL) { c->mode = START; c->lbits = (Byte)bl; c->dbits = (Byte)bd; c->ltree = tl; c->dtree = td; Tracev((stderr, "inflate: codes new\n")); } return c; } int inflate_codes(s, z, r) inflate_blocks_statef *s; z_streamp z; int r; { uInt j; /* temporary storage */ inflate_huft *t; /* temporary pointer */ uInt e; /* extra bits or operation */ uLong b; /* bit buffer */ uInt k; /* bits in bit buffer */ Bytef *p; /* input data pointer */ uInt n; /* bytes available there */ Bytef *q; /* output window write pointer */ uInt m; /* bytes to end of window or read pointer */ Bytef *f; /* pointer to copy strings from */ inflate_codes_statef *c = s->sub.decode.codes; /* codes state */ /* copy input/output information to locals (UPDATE macro restores) */ LOAD /* process input and output based on current state */ while (1) switch (c->mode) { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */ case START: /* x: set up for LEN */ #ifndef SLOW if (m >= 258 && n >= 10) { UPDATE r = inflate_fast(c->lbits, c->dbits, c->ltree, c->dtree, s, z); LOAD if (r != Z_OK) { c->mode = r == Z_STREAM_END ? WASH : BADCODE; break; } } #endif /* !SLOW */ c->sub.code.need = c->lbits; c->sub.code.tree = c->ltree; c->mode = LEN; case LEN: /* i: get length/literal/eob next */ j = c->sub.code.need; NEEDBITS(j) t = c->sub.code.tree + ((uInt)b & inflate_mask[j]); DUMPBITS(t->bits) e = (uInt)(t->exop); if (e == 0) /* literal */ { c->sub.lit = t->base; Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ? "inflate: literal '%c'\n" : "inflate: literal 0x%02x\n", t->base)); c->mode = LIT; break; } if (e & 16) /* length */ { c->sub.copy.get = e & 15; c->len = t->base; c->mode = LENEXT; break; } if ((e & 64) == 0) /* next table */ { c->sub.code.need = e; c->sub.code.tree = t->next; break; } if (e & 32) /* end of block */ { Tracevv((stderr, "inflate: end of block\n")); c->mode = WASH; break; } c->mode = BADCODE; /* invalid code */ z->msg = (char*)"invalid literal/length code"; r = Z_DATA_ERROR; LEAVE case LENEXT: /* i: getting length extra (have base) */ j = c->sub.copy.get; NEEDBITS(j) c->len += (uInt)b & inflate_mask[j]; DUMPBITS(j) c->sub.code.need = c->dbits; c->sub.code.tree = c->dtree; Tracevv((stderr, "inflate: length %u\n", c->len)); c->mode = DIST; case DIST: /* i: get distance next */ j = c->sub.code.need; NEEDBITS(j) t = c->sub.code.tree + ((uInt)b & inflate_mask[j]); DUMPBITS(t->bits) e = (uInt)(t->exop); if (e & 16) /* distance */ { c->sub.copy.get = e & 15; c->sub.copy.dist = t->base; c->mode = DISTEXT; break; } if ((e & 64) == 0) /* next table */ { c->sub.code.need = e; c->sub.code.tree = t->next; break; } c->mode = BADCODE; /* invalid code */ z->msg = (char*)"invalid distance code"; r = Z_DATA_ERROR; LEAVE case DISTEXT: /* i: getting distance extra */ j = c->sub.copy.get; NEEDBITS(j) c->sub.copy.dist += (uInt)b & inflate_mask[j]; DUMPBITS(j) Tracevv((stderr, "inflate: distance %u\n", c->sub.copy.dist)); c->mode = COPY; case COPY: /* o: copying bytes in window, waiting for space */ #ifndef __TURBOC__ /* Turbo C bug for following expression */ f = (uInt)(q - s->window) < c->sub.copy.dist ? s->end - (c->sub.copy.dist - (q - s->window)) : q - c->sub.copy.dist; #else f = q - c->sub.copy.dist; if ((uInt)(q - s->window) < c->sub.copy.dist) f = s->end - (c->sub.copy.dist - (uInt)(q - s->window)); #endif while (c->len) { NEEDOUT OUTBYTE(*f++) if (f == s->end) f = s->window; c->len--; } c->mode = START; break; case LIT: /* o: got literal, waiting for output space */ NEEDOUT OUTBYTE(c->sub.lit) c->mode = START; break; case WASH: /* o: got eob, possibly more output */ FLUSH if (s->read != s->write) LEAVE c->mode = END; case END: r = Z_STREAM_END; LEAVE case BADCODE: /* x: got error */ r = Z_DATA_ERROR; LEAVE default: r = Z_STREAM_ERROR; LEAVE } } void inflate_codes_free(c, z) inflate_codes_statef *c; z_streamp z; { ZFREE(z, c); Tracev((stderr, "inflate: codes free\n")); } /* --- infcodes.c */ /* +++ infutil.c */ /* inflate_util.c -- data and routines common to blocks and codes * Copyright (C) 1995-1996 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ /* #include "zutil.h" */ /* #include "infblock.h" */ /* #include "inftrees.h" */ /* #include "infcodes.h" */ /* #include "infutil.h" */ #ifndef NO_DUMMY_DECL struct inflate_codes_state {int dummy;}; /* for buggy compilers */ #endif /* And'ing with mask[n] masks the lower n bits */ uInt inflate_mask[17] = { 0x0000, 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff, 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff }; /* copy as much as possible from the sliding window to the output area */ int inflate_flush(s, z, r) inflate_blocks_statef *s; z_streamp z; int r; { uInt n; Bytef *p; Bytef *q; /* local copies of source and destination pointers */ p = z->next_out; q = s->read; /* compute number of bytes to copy as far as end of window */ n = (uInt)((q <= s->write ? s->write : s->end) - q); if (n > z->avail_out) n = z->avail_out; if (n && r == Z_BUF_ERROR) r = Z_OK; /* update counters */ z->avail_out -= n; z->total_out += n; /* update check information */ if (s->checkfn != Z_NULL) z->adler = s->check = (*s->checkfn)(s->check, q, n); /* copy as far as end of window */ if (p != Z_NULL) { zmemcpy(p, q, n); p += n; } q += n; /* see if more to copy at beginning of window */ if (q == s->end) { /* wrap pointers */ q = s->window; if (s->write == s->end) s->write = s->window; /* compute bytes to copy */ n = (uInt)(s->write - q); if (n > z->avail_out) n = z->avail_out; if (n && r == Z_BUF_ERROR) r = Z_OK; /* update counters */ z->avail_out -= n; z->total_out += n; /* update check information */ if (s->checkfn != Z_NULL) z->adler = s->check = (*s->checkfn)(s->check, q, n); /* copy */ if (p != Z_NULL) { zmemcpy(p, q, n); p += n; } q += n; } /* update pointers */ z->next_out = p; s->read = q; /* done */ return r; } /* --- infutil.c */ /* +++ inffast.c */ /* inffast.c -- process literals and length/distance pairs fast * Copyright (C) 1995-1996 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ /* #include "zutil.h" */ /* #include "inftrees.h" */ /* #include "infblock.h" */ /* #include "infcodes.h" */ /* #include "infutil.h" */ /* #include "inffast.h" */ #ifndef NO_DUMMY_DECL struct inflate_codes_state {int dummy;}; /* for buggy compilers */ #endif /* simplify the use of the inflate_huft type with some defines */ #define base more.Base #define next more.Next #define exop word.what.Exop #define bits word.what.Bits /* macros for bit input with no checking and for returning unused bytes */ #define GRABBITS(j) {while(k<(j)){b|=((uLong)NEXTBYTE)<>3);p-=c;k&=7;} /* Called with number of bytes left to write in window at least 258 (the maximum string length) and number of input bytes available at least ten. The ten bytes are six bytes for the longest length/ distance pair plus four bytes for overloading the bit buffer. */ int inflate_fast(bl, bd, tl, td, s, z) uInt bl, bd; inflate_huft *tl; inflate_huft *td; /* need separate declaration for Borland C++ */ inflate_blocks_statef *s; z_streamp z; { inflate_huft *t; /* temporary pointer */ uInt e; /* extra bits or operation */ uLong b; /* bit buffer */ uInt k; /* bits in bit buffer */ Bytef *p; /* input data pointer */ uInt n; /* bytes available there */ Bytef *q; /* output window write pointer */ uInt m; /* bytes to end of window or read pointer */ uInt ml; /* mask for literal/length tree */ uInt md; /* mask for distance tree */ uInt c; /* bytes to copy */ uInt d; /* distance back to copy from */ Bytef *r; /* copy source pointer */ /* load input, output, bit values */ LOAD /* initialize masks */ ml = inflate_mask[bl]; md = inflate_mask[bd]; /* do until not enough input or output space for fast loop */ do { /* assume called with m >= 258 && n >= 10 */ /* get literal/length code */ GRABBITS(20) /* max bits for literal/length code */ if ((e = (t = tl + ((uInt)b & ml))->exop) == 0) { DUMPBITS(t->bits) Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ? "inflate: * literal '%c'\n" : "inflate: * literal 0x%02x\n", t->base)); *q++ = (Byte)t->base; m--; continue; } do { DUMPBITS(t->bits) if (e & 16) { /* get extra bits for length */ e &= 15; c = t->base + ((uInt)b & inflate_mask[e]); DUMPBITS(e) Tracevv((stderr, "inflate: * length %u\n", c)); /* decode distance base of block to copy */ GRABBITS(15); /* max bits for distance code */ e = (t = td + ((uInt)b & md))->exop; do { DUMPBITS(t->bits) if (e & 16) { /* get extra bits to add to distance base */ e &= 15; GRABBITS(e) /* get extra bits (up to 13) */ d = t->base + ((uInt)b & inflate_mask[e]); DUMPBITS(e) Tracevv((stderr, "inflate: * distance %u\n", d)); /* do the copy */ m -= c; if ((uInt)(q - s->window) >= d) /* offset before dest */ { /* just copy */ r = q - d; *q++ = *r++; c--; /* minimum count is three, */ *q++ = *r++; c--; /* so unroll loop a little */ } else /* else offset after destination */ { e = d - (uInt)(q - s->window); /* bytes from offset to end */ r = s->end - e; /* pointer to offset */ if (c > e) /* if source crosses, */ { c -= e; /* copy to end of window */ do { *q++ = *r++; } while (--e); r = s->window; /* copy rest from start of window */ } } do { /* copy all or what's left */ *q++ = *r++; } while (--c); break; } else if ((e & 64) == 0) e = (t = t->next + ((uInt)b & inflate_mask[e]))->exop; else { z->msg = (char*)"invalid distance code"; UNGRAB UPDATE return Z_DATA_ERROR; } } while (1); break; } if ((e & 64) == 0) { if ((e = (t = t->next + ((uInt)b & inflate_mask[e]))->exop) == 0) { DUMPBITS(t->bits) Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ? "inflate: * literal '%c'\n" : "inflate: * literal 0x%02x\n", t->base)); *q++ = (Byte)t->base; m--; break; } } else if (e & 32) { Tracevv((stderr, "inflate: * end of block\n")); UNGRAB UPDATE return Z_STREAM_END; } else { z->msg = (char*)"invalid literal/length code"; UNGRAB UPDATE return Z_DATA_ERROR; } } while (1); } while (m >= 258 && n >= 10); /* not enough input or output--restore pointers and return */ UNGRAB UPDATE return Z_OK; } /* --- inffast.c */ /* +++ zutil.c */ /* zutil.c -- target dependent utility functions for the compression library * Copyright (C) 1995-1996 Jean-loup Gailly. * For conditions of distribution and use, see copyright notice in zlib.h */ /* From: zutil.c,v 1.17 1996/07/24 13:41:12 me Exp $ */ #ifdef DEBUG_ZLIB #include #endif /* #include "zutil.h" */ #ifndef NO_DUMMY_DECL struct internal_state {int dummy;}; /* for buggy compilers */ #endif #ifndef STDC extern void exit OF((int)); #endif const char *z_errmsg[10] = { "need dictionary", /* Z_NEED_DICT 2 */ "stream end", /* Z_STREAM_END 1 */ "", /* Z_OK 0 */ "file error", /* Z_ERRNO (-1) */ "stream error", /* Z_STREAM_ERROR (-2) */ "data error", /* Z_DATA_ERROR (-3) */ "insufficient memory", /* Z_MEM_ERROR (-4) */ "buffer error", /* Z_BUF_ERROR (-5) */ "incompatible version",/* Z_VERSION_ERROR (-6) */ ""}; const char *zlibVersion() { return ZLIB_VERSION; } #ifdef DEBUG_ZLIB void z_error (m) char *m; { fprintf(stderr, "%s\n", m); exit(1); } #endif #ifndef HAVE_MEMCPY void zmemcpy(dest, source, len) Bytef* dest; Bytef* source; uInt len; { if (len == 0) return; do { *dest++ = *source++; /* ??? to be unrolled */ } while (--len != 0); } int zmemcmp(s1, s2, len) Bytef* s1; Bytef* s2; uInt len; { uInt j; for (j = 0; j < len; j++) { if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1; } return 0; } void zmemzero(dest, len) Bytef* dest; uInt len; { if (len == 0) return; do { *dest++ = 0; /* ??? to be unrolled */ } while (--len != 0); } #endif #ifdef __TURBOC__ #if (defined( __BORLANDC__) || !defined(SMALL_MEDIUM)) && !defined(__32BIT__) /* Small and medium model in Turbo C are for now limited to near allocation * with reduced MAX_WBITS and MAX_MEM_LEVEL */ # define MY_ZCALLOC /* Turbo C malloc() does not allow dynamic allocation of 64K bytes * and farmalloc(64K) returns a pointer with an offset of 8, so we * must fix the pointer. Warning: the pointer must be put back to its * original form in order to free it, use zcfree(). */ #define MAX_PTR 10 /* 10*64K = 640K */ local int next_ptr = 0; typedef struct ptr_table_s { voidpf org_ptr; voidpf new_ptr; } ptr_table; local ptr_table table[MAX_PTR]; /* This table is used to remember the original form of pointers * to large buffers (64K). Such pointers are normalized with a zero offset. * Since MSDOS is not a preemptive multitasking OS, this table is not * protected from concurrent access. This hack doesn't work anyway on * a protected system like OS/2. Use Microsoft C instead. */ voidpf zcalloc (voidpf opaque, unsigned items, unsigned size) { voidpf buf = opaque; /* just to make some compilers happy */ ulg bsize = (ulg)items*size; /* If we allocate less than 65520 bytes, we assume that farmalloc * will return a usable pointer which doesn't have to be normalized. */ if (bsize < 65520L) { buf = farmalloc(bsize); if (*(ush*)&buf != 0) return buf; } else { buf = farmalloc(bsize + 16L); } if (buf == NULL || next_ptr >= MAX_PTR) return NULL; table[next_ptr].org_ptr = buf; /* Normalize the pointer to seg:0 */ *((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4; *(ush*)&buf = 0; table[next_ptr++].new_ptr = buf; return buf; } void zcfree (voidpf opaque, voidpf ptr) { int n; if (*(ush*)&ptr != 0) { /* object < 64K */ farfree(ptr); return; } /* Find the original pointer */ for (n = 0; n < next_ptr; n++) { if (ptr != table[n].new_ptr) continue; farfree(table[n].org_ptr); while (++n < next_ptr) { table[n-1] = table[n]; } next_ptr--; return; } ptr = opaque; /* just to make some compilers happy */ Assert(0, "zcfree: ptr not found"); } #endif #endif /* __TURBOC__ */ #if defined(M_I86) && !defined(__32BIT__) /* Microsoft C in 16-bit mode */ # define MY_ZCALLOC #if (!defined(_MSC_VER) || (_MSC_VER < 600)) # define _halloc halloc # define _hfree hfree #endif voidpf zcalloc (voidpf opaque, unsigned items, unsigned size) { if (opaque) opaque = 0; /* to make compiler happy */ return _halloc((long)items, size); } void zcfree (voidpf opaque, voidpf ptr) { if (opaque) opaque = 0; /* to make compiler happy */ _hfree(ptr); } #endif /* MSC */ #ifndef MY_ZCALLOC /* Any system without a special alloc function */ #ifndef STDC extern voidp calloc OF((uInt items, uInt size)); extern void free OF((voidpf ptr)); #endif voidpf zcalloc (opaque, items, size) voidpf opaque; unsigned items; unsigned size; { if (opaque) items += size - size; /* make compiler happy */ return (voidpf)calloc(items, size); } void zcfree (opaque, ptr) voidpf opaque; voidpf ptr; { free(ptr); if (opaque) return; /* make compiler happy */ } #endif /* MY_ZCALLOC */ /* --- zutil.c */ /* +++ adler32.c */ /* adler32.c -- compute the Adler-32 checksum of a data stream * Copyright (C) 1995-1996 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ /* From: adler32.c,v 1.10 1996/05/22 11:52:18 me Exp $ */ /* #include "zlib.h" */ #define BASE 65521L /* largest prime smaller than 65536 */ #define NMAX 5552 /* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */ #define DO1(buf,i) {s1 += buf[i]; s2 += s1;} #define DO2(buf,i) DO1(buf,i); DO1(buf,i+1); #define DO4(buf,i) DO2(buf,i); DO2(buf,i+2); #define DO8(buf,i) DO4(buf,i); DO4(buf,i+4); #define DO16(buf) DO8(buf,0); DO8(buf,8); /* ========================================================================= */ uLong adler32(adler, buf, len) uLong adler; const Bytef *buf; uInt len; { unsigned long s1 = adler & 0xffff; unsigned long s2 = (adler >> 16) & 0xffff; int k; if (buf == Z_NULL) return 1L; while (len > 0) { k = len < NMAX ? len : NMAX; len -= k; while (k >= 16) { DO16(buf); buf += 16; k -= 16; } if (k != 0) do { s1 += *buf++; s2 += s1; } while (--k); s1 %= BASE; s2 %= BASE; } return (s2 << 16) | s1; } /* --- adler32.c */ ppp-2.5.0/common/zlib.h0000644000175000017500000012423206437206465011657 00000000000000/* $Id: zlib.h,v 1.7 1997/11/27 06:03:33 paulus Exp $ */ /* * This file is derived from zlib.h and zconf.h from the zlib-1.0.4 * distribution by Jean-loup Gailly and Mark Adler, with some additions * by Paul Mackerras to aid in implementing Deflate compression and * decompression for PPP packets. */ /* * ==FILEVERSION 971127== * * This marker is used by the Linux installation script to determine * whether an up-to-date version of this file is already installed. */ /* +++ zlib.h */ /* zlib.h -- interface of the 'zlib' general purpose compression library version 1.0.4, Jul 24th, 1996. Copyright (C) 1995-1996 Jean-loup Gailly and Mark Adler This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. Jean-loup Gailly Mark Adler gzip@prep.ai.mit.edu madler@alumni.caltech.edu The data format used by the zlib library is described by RFCs (Request for Comments) 1950 to 1952 in the files ftp://ds.internic.net/rfc/rfc1950.txt (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format). */ #ifndef _ZLIB_H #define _ZLIB_H #ifdef __cplusplus extern "C" { #endif /* +++ zconf.h */ /* zconf.h -- configuration of the zlib compression library * Copyright (C) 1995-1996 Jean-loup Gailly. * For conditions of distribution and use, see copyright notice in zlib.h */ /* From: zconf.h,v 1.20 1996/07/02 15:09:28 me Exp $ */ #ifndef _ZCONF_H #define _ZCONF_H /* * If you *really* need a unique prefix for all types and library functions, * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it. */ #ifdef Z_PREFIX # define deflateInit_ z_deflateInit_ # define deflate z_deflate # define deflateEnd z_deflateEnd # define inflateInit_ z_inflateInit_ # define inflate z_inflate # define inflateEnd z_inflateEnd # define deflateInit2_ z_deflateInit2_ # define deflateSetDictionary z_deflateSetDictionary # define deflateCopy z_deflateCopy # define deflateReset z_deflateReset # define deflateParams z_deflateParams # define inflateInit2_ z_inflateInit2_ # define inflateSetDictionary z_inflateSetDictionary # define inflateSync z_inflateSync # define inflateReset z_inflateReset # define compress z_compress # define uncompress z_uncompress # define adler32 z_adler32 # define crc32 z_crc32 # define get_crc_table z_get_crc_table # define Byte z_Byte # define uInt z_uInt # define uLong z_uLong # define Bytef z_Bytef # define charf z_charf # define intf z_intf # define uIntf z_uIntf # define uLongf z_uLongf # define voidpf z_voidpf # define voidp z_voidp #endif #if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32) # define WIN32 #endif #if defined(__GNUC__) || defined(WIN32) || defined(__386__) || defined(i386) # ifndef __32BIT__ # define __32BIT__ # endif #endif #if defined(__MSDOS__) && !defined(MSDOS) # define MSDOS #endif /* * Compile with -DMAXSEG_64K if the alloc function cannot allocate more * than 64k bytes at a time (needed on systems with 16-bit int). */ #if defined(MSDOS) && !defined(__32BIT__) # define MAXSEG_64K #endif #ifdef MSDOS # define UNALIGNED_OK #endif #if (defined(MSDOS) || defined(_WINDOWS) || defined(WIN32)) && !defined(STDC) # define STDC #endif #if (defined(__STDC__) || defined(__cplusplus)) && !defined(STDC) # define STDC #endif #ifndef STDC # ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */ # define const # endif #endif /* Some Mac compilers merge all .h files incorrectly: */ #if defined(__MWERKS__) || defined(applec) ||defined(THINK_C) ||defined(__SC__) # define NO_DUMMY_DECL #endif /* Maximum value for memLevel in deflateInit2 */ #ifndef MAX_MEM_LEVEL # ifdef MAXSEG_64K # define MAX_MEM_LEVEL 8 # else # define MAX_MEM_LEVEL 9 # endif #endif /* Maximum value for windowBits in deflateInit2 and inflateInit2 */ #ifndef MAX_WBITS # define MAX_WBITS 15 /* 32K LZ77 window */ #endif /* The memory requirements for deflate are (in bytes): 1 << (windowBits+2) + 1 << (memLevel+9) that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) plus a few kilobytes for small objects. For example, if you want to reduce the default memory requirements from 256K to 128K, compile with make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" Of course this will generally degrade compression (there's no free lunch). The memory requirements for inflate are (in bytes) 1 << windowBits that is, 32K for windowBits=15 (default value) plus a few kilobytes for small objects. */ /* Type declarations */ #ifndef OF /* function prototypes */ # ifdef STDC # define OF(args) args # else # define OF(args) () # endif #endif /* The following definitions for FAR are needed only for MSDOS mixed * model programming (small or medium model with some far allocations). * This was tested only with MSC; for other MSDOS compilers you may have * to define NO_MEMCPY in zutil.h. If you don't need the mixed model, * just define FAR to be empty. */ #if (defined(M_I86SM) || defined(M_I86MM)) && !defined(__32BIT__) /* MSC small or medium model */ # define SMALL_MEDIUM # ifdef _MSC_VER # define FAR __far # else # define FAR far # endif #endif #if defined(__BORLANDC__) && (defined(__SMALL__) || defined(__MEDIUM__)) # ifndef __32BIT__ # define SMALL_MEDIUM # define FAR __far # endif #endif #ifndef FAR # define FAR #endif typedef unsigned char Byte; /* 8 bits */ typedef unsigned int uInt; /* 16 bits or more */ typedef unsigned long uLong; /* 32 bits or more */ #if defined(__BORLANDC__) && defined(SMALL_MEDIUM) /* Borland C/C++ ignores FAR inside typedef */ # define Bytef Byte FAR #else typedef Byte FAR Bytef; #endif typedef char FAR charf; typedef int FAR intf; typedef uInt FAR uIntf; typedef uLong FAR uLongf; #ifdef STDC typedef void FAR *voidpf; typedef void *voidp; #else typedef Byte FAR *voidpf; typedef Byte *voidp; #endif /* Compile with -DZLIB_DLL for Windows DLL support */ #if (defined(_WINDOWS) || defined(WINDOWS)) && defined(ZLIB_DLL) # include # define EXPORT WINAPI #else # define EXPORT #endif #endif /* _ZCONF_H */ /* --- zconf.h */ #define ZLIB_VERSION "1.0.4P" /* The 'zlib' compression library provides in-memory compression and decompression functions, including integrity checks of the uncompressed data. This version of the library supports only one compression method (deflation) but other algorithms may be added later and will have the same stream interface. For compression the application must provide the output buffer and may optionally provide the input buffer for optimization. For decompression, the application must provide the input buffer and may optionally provide the output buffer for optimization. Compression can be done in a single step if the buffers are large enough (for example if an input file is mmap'ed), or can be done by repeated calls of the compression function. In the latter case, the application must provide more input and/or consume the output (providing more output space) before each call. The library does not install any signal handler. It is recommended to add at least a handler for SIGSEGV when decompressing; the library checks the consistency of the input data whenever possible but may go nuts for some forms of corrupted input. */ typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size)); typedef void (*free_func) OF((voidpf opaque, voidpf address)); struct internal_state; typedef struct z_stream_s { Bytef *next_in; /* next input byte */ uInt avail_in; /* number of bytes available at next_in */ uLong total_in; /* total nb of input bytes read so far */ Bytef *next_out; /* next output byte should be put there */ uInt avail_out; /* remaining free space at next_out */ uLong total_out; /* total nb of bytes output so far */ char *msg; /* last error message, NULL if no error */ struct internal_state FAR *state; /* not visible by applications */ alloc_func zalloc; /* used to allocate the internal state */ free_func zfree; /* used to free the internal state */ voidpf opaque; /* private data object passed to zalloc and zfree */ int data_type; /* best guess about the data type: ascii or binary */ uLong adler; /* adler32 value of the uncompressed data */ uLong reserved; /* reserved for future use */ } z_stream; typedef z_stream FAR *z_streamp; /* The application must update next_in and avail_in when avail_in has dropped to zero. It must update next_out and avail_out when avail_out has dropped to zero. The application must initialize zalloc, zfree and opaque before calling the init function. All other fields are set by the compression library and must not be updated by the application. The opaque value provided by the application will be passed as the first parameter for calls of zalloc and zfree. This can be useful for custom memory management. The compression library attaches no meaning to the opaque value. zalloc must return Z_NULL if there is not enough memory for the object. On 16-bit systems, the functions zalloc and zfree must be able to allocate exactly 65536 bytes, but will not be required to allocate more than this if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS, pointers returned by zalloc for objects of exactly 65536 bytes *must* have their offset normalized to zero. The default allocation function provided by this library ensures this (see zutil.c). To reduce memory requirements and avoid any allocation of 64K objects, at the expense of compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h). The fields total_in and total_out can be used for statistics or progress reports. After compression, total_in holds the total size of the uncompressed data and may be saved for use in the decompressor (particularly if the decompressor wants to decompress everything in a single step). */ /* constants */ #define Z_NO_FLUSH 0 #define Z_PARTIAL_FLUSH 1 #define Z_PACKET_FLUSH 2 #define Z_SYNC_FLUSH 3 #define Z_FULL_FLUSH 4 #define Z_FINISH 5 /* Allowed flush values; see deflate() below for details */ #define Z_OK 0 #define Z_STREAM_END 1 #define Z_NEED_DICT 2 #define Z_ERRNO (-1) #define Z_STREAM_ERROR (-2) #define Z_DATA_ERROR (-3) #define Z_MEM_ERROR (-4) #define Z_BUF_ERROR (-5) #define Z_VERSION_ERROR (-6) /* Return codes for the compression/decompression functions. Negative * values are errors, positive values are used for special but normal events. */ #define Z_NO_COMPRESSION 0 #define Z_BEST_SPEED 1 #define Z_BEST_COMPRESSION 9 #define Z_DEFAULT_COMPRESSION (-1) /* compression levels */ #define Z_FILTERED 1 #define Z_HUFFMAN_ONLY 2 #define Z_DEFAULT_STRATEGY 0 /* compression strategy; see deflateInit2() below for details */ #define Z_BINARY 0 #define Z_ASCII 1 #define Z_UNKNOWN 2 /* Possible values of the data_type field */ #define Z_DEFLATED 8 /* The deflate compression method (the only one supported in this version) */ #define Z_NULL 0 /* for initializing zalloc, zfree, opaque */ #define zlib_version zlibVersion() /* for compatibility with versions < 1.0.2 */ /* basic functions */ extern const char * EXPORT zlibVersion OF((void)); /* The application can compare zlibVersion and ZLIB_VERSION for consistency. If the first character differs, the library code actually used is not compatible with the zlib.h header file used by the application. This check is automatically made by deflateInit and inflateInit. */ /* extern int EXPORT deflateInit OF((z_streamp strm, int level)); Initializes the internal stream state for compression. The fields zalloc, zfree and opaque must be initialized before by the caller. If zalloc and zfree are set to Z_NULL, deflateInit updates them to use default allocation functions. The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9: 1 gives best speed, 9 gives best compression, 0 gives no compression at all (the input data is simply copied a block at a time). Z_DEFAULT_COMPRESSION requests a default compromise between speed and compression (currently equivalent to level 6). deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_STREAM_ERROR if level is not a valid compression level, Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible with the version assumed by the caller (ZLIB_VERSION). msg is set to null if there is no error message. deflateInit does not perform any compression: this will be done by deflate(). */ extern int EXPORT deflate OF((z_streamp strm, int flush)); /* Performs one or both of the following actions: - Compress more input starting at next_in and update next_in and avail_in accordingly. If not all input can be processed (because there is not enough room in the output buffer), next_in and avail_in are updated and processing will resume at this point for the next call of deflate(). - Provide more output starting at next_out and update next_out and avail_out accordingly. This action is forced if the parameter flush is non zero. Forcing flush frequently degrades the compression ratio, so this parameter should be set only when necessary (in interactive applications). Some output may be provided even if flush is not set. Before the call of deflate(), the application should ensure that at least one of the actions is possible, by providing more input and/or consuming more output, and updating avail_in or avail_out accordingly; avail_out should never be zero before the call. The application can consume the compressed output when it wants, for example when the output buffer is full (avail_out == 0), or after each call of deflate(). If deflate returns Z_OK and with zero avail_out, it must be called again after making room in the output buffer because there might be more output pending. If the parameter flush is set to Z_PARTIAL_FLUSH, the current compression block is terminated and flushed to the output buffer so that the decompressor can get all input data available so far. For method 9, a future variant on method 8, the current block will be flushed but not terminated. Z_SYNC_FLUSH has the same effect as partial flush except that the compressed output is byte aligned (the compressor can clear its internal bit buffer) and the current block is always terminated; this can be useful if the compressor has to be restarted from scratch after an interruption (in which case the internal state of the compressor may be lost). If flush is set to Z_FULL_FLUSH, the compression block is terminated, a special marker is output and the compression dictionary is discarded; this is useful to allow the decompressor to synchronize if one compressed block has been damaged (see inflateSync below). Flushing degrades compression and so should be used only when necessary. Using Z_FULL_FLUSH too often can seriously degrade the compression. If deflate returns with avail_out == 0, this function must be called again with the same value of the flush parameter and more output space (updated avail_out), until the flush is complete (deflate returns with non-zero avail_out). If the parameter flush is set to Z_PACKET_FLUSH, the compression block is terminated, and a zero-length stored block is output, omitting the length bytes (the effect of this is that the 3-bit type code 000 for a stored block is output, and the output is then byte-aligned). This is designed for use at the end of a PPP packet. If the parameter flush is set to Z_FINISH, pending input is processed, pending output is flushed and deflate returns with Z_STREAM_END if there was enough output space; if deflate returns with Z_OK, this function must be called again with Z_FINISH and more output space (updated avail_out) but no more input data, until it returns with Z_STREAM_END or an error. After deflate has returned Z_STREAM_END, the only possible operations on the stream are deflateReset or deflateEnd. Z_FINISH can be used immediately after deflateInit if all the compression is to be done in a single step. In this case, avail_out must be at least 0.1% larger than avail_in plus 12 bytes. If deflate does not return Z_STREAM_END, then it must be called again as described above. deflate() may update data_type if it can make a good guess about the input data type (Z_ASCII or Z_BINARY). In doubt, the data is considered binary. This field is only for information purposes and does not affect the compression algorithm in any manner. deflate() returns Z_OK if some progress has been made (more input processed or more output produced), Z_STREAM_END if all input has been consumed and all output has been produced (only when flush is set to Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example if next_in or next_out was NULL), Z_BUF_ERROR if no progress is possible. */ extern int EXPORT deflateEnd OF((z_streamp strm)); /* All dynamically allocated data structures for this stream are freed. This function discards any unprocessed input and does not flush any pending output. deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state was inconsistent, Z_DATA_ERROR if the stream was freed prematurely (some input or output was discarded). In the error case, msg may be set but then points to a static string (which must not be deallocated). */ /* extern int EXPORT inflateInit OF((z_streamp strm)); Initializes the internal stream state for decompression. The fields zalloc, zfree and opaque must be initialized before by the caller. If zalloc and zfree are set to Z_NULL, inflateInit updates them to use default allocation functions. inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_VERSION_ERROR if the zlib library version is incompatible with the version assumed by the caller. msg is set to null if there is no error message. inflateInit does not perform any decompression: this will be done by inflate(). */ extern int EXPORT inflate OF((z_streamp strm, int flush)); /* Performs one or both of the following actions: - Decompress more input starting at next_in and update next_in and avail_in accordingly. If not all input can be processed (because there is not enough room in the output buffer), next_in is updated and processing will resume at this point for the next call of inflate(). - Provide more output starting at next_out and update next_out and avail_out accordingly. inflate() provides as much output as possible, until there is no more input data or no more space in the output buffer (see below about the flush parameter). Before the call of inflate(), the application should ensure that at least one of the actions is possible, by providing more input and/or consuming more output, and updating the next_* and avail_* values accordingly. The application can consume the uncompressed output when it wants, for example when the output buffer is full (avail_out == 0), or after each call of inflate(). If inflate returns Z_OK and with zero avail_out, it must be called again after making room in the output buffer because there might be more output pending. If the parameter flush is set to Z_PARTIAL_FLUSH or Z_PACKET_FLUSH, inflate flushes as much output as possible to the output buffer. The flushing behavior of inflate is not specified for values of the flush parameter other than Z_PARTIAL_FLUSH, Z_PACKET_FLUSH or Z_FINISH, but the current implementation actually flushes as much output as possible anyway. For Z_PACKET_FLUSH, inflate checks that once all the input data has been consumed, it is expecting to see the length field of a stored block; if not, it returns Z_DATA_ERROR. inflate() should normally be called until it returns Z_STREAM_END or an error. However if all decompression is to be performed in a single step (a single call of inflate), the parameter flush should be set to Z_FINISH. In this case all pending input is processed and all pending output is flushed; avail_out must be large enough to hold all the uncompressed data. (The size of the uncompressed data may have been saved by the compressor for this purpose.) The next operation on this stream must be inflateEnd to deallocate the decompression state. The use of Z_FINISH is never required, but can be used to inform inflate that a faster routine may be used for the single inflate() call. inflate() returns Z_OK if some progress has been made (more input processed or more output produced), Z_STREAM_END if the end of the compressed data has been reached and all uncompressed output has been produced, Z_NEED_DICT if a preset dictionary is needed at this point (see inflateSetDictionary below), Z_DATA_ERROR if the input data was corrupted, Z_STREAM_ERROR if the stream structure was inconsistent (for example if next_in or next_out was NULL), Z_MEM_ERROR if there was not enough memory, Z_BUF_ERROR if no progress is possible or if there was not enough room in the output buffer when Z_FINISH is used. In the Z_DATA_ERROR case, the application may then call inflateSync to look for a good compression block. In the Z_NEED_DICT case, strm->adler is set to the Adler32 value of the dictionary chosen by the compressor. */ extern int EXPORT inflateEnd OF((z_streamp strm)); /* All dynamically allocated data structures for this stream are freed. This function discards any unprocessed input and does not flush any pending output. inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state was inconsistent. In the error case, msg may be set but then points to a static string (which must not be deallocated). */ /* Advanced functions */ /* The following functions are needed only in some special applications. */ /* extern int EXPORT deflateInit2 OF((z_streamp strm, int level, int method, int windowBits, int memLevel, int strategy)); This is another version of deflateInit with more compression options. The fields next_in, zalloc, zfree and opaque must be initialized before by the caller. The method parameter is the compression method. It must be Z_DEFLATED in this version of the library. (Method 9 will allow a 64K history buffer and partial block flushes.) The windowBits parameter is the base two logarithm of the window size (the size of the history buffer). It should be in the range 8..15 for this version of the library (the value 16 will be allowed for method 9). Larger values of this parameter result in better compression at the expense of memory usage. The default value is 15 if deflateInit is used instead. The memLevel parameter specifies how much memory should be allocated for the internal compression state. memLevel=1 uses minimum memory but is slow and reduces compression ratio; memLevel=9 uses maximum memory for optimal speed. The default value is 8. See zconf.h for total memory usage as a function of windowBits and memLevel. The strategy parameter is used to tune the compression algorithm. Use the value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a filter (or predictor), or Z_HUFFMAN_ONLY to force Huffman encoding only (no string match). Filtered data consists mostly of small values with a somewhat random distribution. In this case, the compression algorithm is tuned to compress them better. The effect of Z_FILTERED is to force more Huffman coding and less string matching; it is somewhat intermediate between Z_DEFAULT and Z_HUFFMAN_ONLY. The strategy parameter only affects the compression ratio but not the correctness of the compressed output even if it is not set appropriately. If next_in is not null, the library will use this buffer to hold also some history information; the buffer must either hold the entire input data, or have at least 1<<(windowBits+1) bytes and be writable. If next_in is null, the library will allocate its own history buffer (and leave next_in null). next_out need not be provided here but must be provided by the application for the next call of deflate(). If the history buffer is provided by the application, next_in must must never be changed by the application since the compressor maintains information inside this buffer from call to call; the application must provide more input only by increasing avail_in. next_in is always reset by the library in this case. deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_STREAM_ERROR if a parameter is invalid (such as an invalid method). msg is set to null if there is no error message. deflateInit2 does not perform any compression: this will be done by deflate(). */ extern int EXPORT deflateSetDictionary OF((z_streamp strm, const Bytef *dictionary, uInt dictLength)); /* Initializes the compression dictionary (history buffer) from the given byte sequence without producing any compressed output. This function must be called immediately after deflateInit or deflateInit2, before any call of deflate. The compressor and decompressor must use exactly the same dictionary (see inflateSetDictionary). The dictionary should consist of strings (byte sequences) that are likely to be encountered later in the data to be compressed, with the most commonly used strings preferably put towards the end of the dictionary. Using a dictionary is most useful when the data to be compressed is short and can be predicted with good accuracy; the data can then be compressed better than with the default empty dictionary. In this version of the library, only the last 32K bytes of the dictionary are used. Upon return of this function, strm->adler is set to the Adler32 value of the dictionary; the decompressor may later use this value to determine which dictionary has been used by the compressor. (The Adler32 value applies to the whole dictionary even if only a subset of the dictionary is actually used by the compressor.) deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a parameter is invalid (such as NULL dictionary) or the stream state is inconsistent (for example if deflate has already been called for this stream). deflateSetDictionary does not perform any compression: this will be done by deflate(). */ extern int EXPORT deflateCopy OF((z_streamp dest, z_streamp source)); /* Sets the destination stream as a complete copy of the source stream. If the source stream is using an application-supplied history buffer, a new buffer is allocated for the destination stream. The compressed output buffer is always application-supplied. It's the responsibility of the application to provide the correct values of next_out and avail_out for the next call of deflate. This function can be useful when several compression strategies will be tried, for example when there are several ways of pre-processing the input data with a filter. The streams that will be discarded should then be freed by calling deflateEnd. Note that deflateCopy duplicates the internal compression state which can be quite large, so this strategy is slow and can consume lots of memory. deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_STREAM_ERROR if the source stream state was inconsistent (such as zalloc being NULL). msg is left unchanged in both source and destination. */ extern int EXPORT deflateReset OF((z_streamp strm)); /* This function is equivalent to deflateEnd followed by deflateInit, but does not free and reallocate all the internal compression state. The stream will keep the same compression level and any other attributes that may have been set by deflateInit2. deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source stream state was inconsistent (such as zalloc or state being NULL). */ extern int EXPORT deflateParams OF((z_streamp strm, int level, int strategy)); /* Dynamically update the compression level and compression strategy. This can be used to switch between compression and straight copy of the input data, or to switch to a different kind of input data requiring a different strategy. If the compression level is changed, the input available so far is compressed with the old level (and may be flushed); the new level will take effect only at the next call of deflate(). Before the call of deflateParams, the stream state must be set as for a call of deflate(), since the currently available input may have to be compressed and flushed. In particular, strm->avail_out must be non-zero. deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR if strm->avail_out was zero. */ extern int EXPORT deflateOutputPending OF((z_streamp strm)); /* Returns the number of bytes of output which are immediately available from the compressor (i.e. without any further input or flush). */ /* extern int EXPORT inflateInit2 OF((z_streamp strm, int windowBits)); This is another version of inflateInit with more compression options. The fields next_out, zalloc, zfree and opaque must be initialized before by the caller. The windowBits parameter is the base two logarithm of the maximum window size (the size of the history buffer). It should be in the range 8..15 for this version of the library (the value 16 will be allowed soon). The default value is 15 if inflateInit is used instead. If a compressed stream with a larger window size is given as input, inflate() will return with the error code Z_DATA_ERROR instead of trying to allocate a larger window. If next_out is not null, the library will use this buffer for the history buffer; the buffer must either be large enough to hold the entire output data, or have at least 1<". * * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * $Id: ppp-comp.h,v 1.10 2002/12/06 09:49:15 paulus Exp $ */ /* * ==FILEVERSION 20020319== * * NOTE TO MAINTAINERS: * If you modify this file at all, please set the above date. * ppp-comp.h is shipped with a PPP distribution as well as with the kernel; * if everyone increases the FILEVERSION number above, then scripts * can do the right thing when deciding whether to install a new ppp-comp.h * file. Don't change the format of that line otherwise, so the * installation script can recognize it. */ #ifndef _NET_PPP_COMP_H #define _NET_PPP_COMP_H /* * The following symbols control whether we include code for * various compression methods. */ #ifndef DO_BSD_COMPRESS #define DO_BSD_COMPRESS 1 /* by default, include BSD-Compress */ #endif #ifndef DO_DEFLATE #define DO_DEFLATE 1 /* by default, include Deflate */ #endif #define DO_PREDICTOR_1 0 #define DO_PREDICTOR_2 0 /* * Structure giving methods for compression/decompression. */ struct compressor { int compress_proto; /* CCP compression protocol number */ /* Allocate space for a compressor (transmit side) */ void *(*comp_alloc) (unsigned char *options, int opt_len); /* Free space used by a compressor */ void (*comp_free) (void *state); /* Initialize a compressor */ int (*comp_init) (void *state, unsigned char *options, int opt_len, int unit, int opthdr, int debug); /* Reset a compressor */ void (*comp_reset) (void *state); /* Compress a packet */ int (*compress) (void *state, unsigned char *rptr, unsigned char *obuf, int isize, int osize); /* Return compression statistics */ void (*comp_stat) (void *state, struct compstat *stats); /* Allocate space for a decompressor (receive side) */ void *(*decomp_alloc) (unsigned char *options, int opt_len); /* Free space used by a decompressor */ void (*decomp_free) (void *state); /* Initialize a decompressor */ int (*decomp_init) (void *state, unsigned char *options, int opt_len, int unit, int opthdr, int mru, int debug); /* Reset a decompressor */ void (*decomp_reset) (void *state); /* Decompress a packet. */ int (*decompress) (void *state, unsigned char *ibuf, int isize, unsigned char *obuf, int osize); /* Update state for an incompressible packet received */ void (*incomp) (void *state, unsigned char *ibuf, int icnt); /* Return decompression statistics */ void (*decomp_stat) (void *state, struct compstat *stats); }; /* * The return value from decompress routine is the length of the * decompressed packet if successful, otherwise DECOMP_ERROR * or DECOMP_FATALERROR if an error occurred. * * We need to make this distinction so that we can disable certain * useful functionality, namely sending a CCP reset-request as a result * of an error detected after decompression. This is to avoid infringing * a patent held by Motorola. * Don't you just lurve software patents. */ #define DECOMP_ERROR -1 /* error detected before decomp. */ #define DECOMP_FATALERROR -2 /* error detected after decomp. */ /* * CCP codes. */ #define CCP_CONFREQ 1 #define CCP_CONFACK 2 #define CCP_TERMREQ 5 #define CCP_TERMACK 6 #define CCP_RESETREQ 14 #define CCP_RESETACK 15 /* * Max # bytes for a CCP option */ #define CCP_MAX_OPTION_LENGTH 32 /* * Parts of a CCP packet. */ #define CCP_CODE(dp) ((dp)[0]) #define CCP_ID(dp) ((dp)[1]) #define CCP_LENGTH(dp) (((dp)[2] << 8) + (dp)[3]) #define CCP_HDRLEN 4 #define CCP_OPT_CODE(dp) ((dp)[0]) #define CCP_OPT_LENGTH(dp) ((dp)[1]) #define CCP_OPT_MINLEN 2 /* * Definitions for BSD-Compress. */ #define CI_BSD_COMPRESS 21 /* config. option for BSD-Compress */ #define CILEN_BSD_COMPRESS 3 /* length of config. option */ /* Macros for handling the 3rd byte of the BSD-Compress config option. */ #define BSD_NBITS(x) ((x) & 0x1F) /* number of bits requested */ #define BSD_VERSION(x) ((x) >> 5) /* version of option format */ #define BSD_CURRENT_VERSION 1 /* current version number */ #define BSD_MAKE_OPT(v, n) (((v) << 5) | (n)) #define BSD_MIN_BITS 9 /* smallest code size supported */ #define BSD_MAX_BITS 15 /* largest code size supported */ /* * Definitions for Deflate. */ #define CI_DEFLATE 26 /* config option for Deflate */ #define CI_DEFLATE_DRAFT 24 /* value used in original draft RFC */ #define CILEN_DEFLATE 4 /* length of its config option */ #define DEFLATE_MIN_SIZE 8 #define DEFLATE_MAX_SIZE 15 #define DEFLATE_METHOD_VAL 8 #define DEFLATE_SIZE(x) (((x) >> 4) + DEFLATE_MIN_SIZE) #define DEFLATE_METHOD(x) ((x) & 0x0F) #define DEFLATE_MAKE_OPT(w) ((((w) - DEFLATE_MIN_SIZE) << 4) \ + DEFLATE_METHOD_VAL) #define DEFLATE_CHK_SEQUENCE 0 /* * Definitions for MPPE. */ #define CI_MPPE 18 /* config option for MPPE */ #define CILEN_MPPE 6 /* length of config option */ /* * Definitions for other, as yet unsupported, compression methods. */ #define CI_PREDICTOR_1 1 /* config option for Predictor-1 */ #define CILEN_PREDICTOR_1 2 /* length of its config option */ #define CI_PREDICTOR_2 2 /* config option for Predictor-2 */ #define CILEN_PREDICTOR_2 2 /* length of its config option */ #endif /* _NET_PPP_COMP_H */ ppp-2.5.0/include/linux/ppp_defs.h0000664000175000017500000001512413772530743014011 00000000000000/* $Id: ppp_defs.h,v 1.11 2002/12/06 09:49:15 paulus Exp $ */ /* * ppp_defs.h - PPP definitions. * * Copyright (c) 1989-2002 Paul Mackerras. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The name(s) of the authors of this software must not be used to * endorse or promote products derived from this software without * prior written permission. * * 4. Redistributions of any form whatsoever must retain the following * acknowledgment: * "This product includes software developed by Paul Mackerras * ". * * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /* * ==FILEVERSION 20020521== * * NOTE TO MAINTAINERS: * If you modify this file at all, please set the above date. * ppp_defs.h is shipped with a PPP distribution as well as with the kernel; * if everyone increases the FILEVERSION number above, then scripts * can do the right thing when deciding whether to install a new ppp_defs.h * file. Don't change the format of that line otherwise, so the * installation script can recognize it. */ #ifndef _PPP_DEFS_H_ #define _PPP_DEFS_H_ /* * The basic PPP frame. */ #define PPP_HDRLEN 4 /* octets for standard ppp header */ #define PPP_FCSLEN 2 /* octets for FCS */ #define PPP_MRU 1500 /* default MRU = max length of info field */ #define PPP_ADDRESS(p) (((__u8 *)(p))[0]) #define PPP_CONTROL(p) (((__u8 *)(p))[1]) #define PPP_PROTOCOL(p) ((((__u8 *)(p))[2] << 8) + ((__u8 *)(p))[3]) /* * Significant octet values. */ #define PPP_ALLSTATIONS 0xff /* All-Stations broadcast address */ #define PPP_UI 0x03 /* Unnumbered Information */ #define PPP_FLAG 0x7e /* Flag Sequence */ #define PPP_ESCAPE 0x7d /* Asynchronous Control Escape */ #define PPP_TRANS 0x20 /* Asynchronous transparency modifier */ /* * Protocol field values. */ #define PPP_IP 0x21 /* Internet Protocol */ #define PPP_AT 0x29 /* AppleTalk Protocol */ #define PPP_IPX 0x2b /* IPX protocol */ #define PPP_VJC_COMP 0x2d /* VJ compressed TCP */ #define PPP_VJC_UNCOMP 0x2f /* VJ uncompressed TCP */ #define PPP_MP 0x3d /* Multilink protocol */ #define PPP_IPV6 0x57 /* Internet Protocol Version 6 */ #define PPP_COMPFRAG 0xfb /* fragment compressed below bundle */ #define PPP_COMP 0xfd /* compressed packet */ #define PPP_IPCP 0x8021 /* IP Control Protocol */ #define PPP_ATCP 0x8029 /* AppleTalk Control Protocol */ #define PPP_IPXCP 0x802b /* IPX Control Protocol */ #define PPP_IPV6CP 0x8057 /* IPv6 Control Protocol */ #define PPP_CCPFRAG 0x80fb /* CCP at link level (below MP bundle) */ #define PPP_CCP 0x80fd /* Compression Control Protocol */ #define PPP_ECPFRAG 0x8055 /* ECP at link level (below MP bundle) */ #define PPP_ECP 0x8053 /* Encryption Control Protocol */ #define PPP_LCP 0xc021 /* Link Control Protocol */ #define PPP_PAP 0xc023 /* Password Authentication Protocol */ #define PPP_LQR 0xc025 /* Link Quality Report protocol */ #define PPP_CHAP 0xc223 /* Cryptographic Handshake Auth. Protocol */ #define PPP_CBCP 0xc029 /* Callback Control Protocol */ /* * Values for FCS calculations. */ #define PPP_INITFCS 0xffff /* Initial FCS value */ #define PPP_GOODFCS 0xf0b8 /* Good final FCS value */ #define PPP_FCS(fcs, c) (((fcs) >> 8) ^ fcstab[((fcs) ^ (c)) & 0xff]) /* * Extended asyncmap - allows any character to be escaped. */ typedef __u32 ext_accm[8]; /* * What to do with network protocol (NP) packets. */ enum NPmode { NPMODE_PASS, /* pass the packet through */ NPMODE_DROP, /* silently drop the packet */ NPMODE_ERROR, /* return an error */ NPMODE_QUEUE /* save it up for later. */ }; /* * Statistics for LQRP and pppstats */ struct pppstat { __u32 ppp_discards; /* # frames discarded */ __u32 ppp_ibytes; /* bytes received */ __u32 ppp_ioctects; /* bytes received not in error */ __u32 ppp_ipackets; /* packets received */ __u32 ppp_ierrors; /* receive errors */ __u32 ppp_ilqrs; /* # LQR frames received */ __u32 ppp_obytes; /* raw bytes sent */ __u32 ppp_ooctects; /* frame bytes sent */ __u32 ppp_opackets; /* packets sent */ __u32 ppp_oerrors; /* transmit errors */ __u32 ppp_olqrs; /* # LQR frames sent */ }; struct vjstat { __u32 vjs_packets; /* outbound packets */ __u32 vjs_compressed; /* outbound compressed packets */ __u32 vjs_searches; /* searches for connection state */ __u32 vjs_misses; /* times couldn't find conn. state */ __u32 vjs_uncompressedin; /* inbound uncompressed packets */ __u32 vjs_compressedin; /* inbound compressed packets */ __u32 vjs_errorin; /* inbound unknown type packets */ __u32 vjs_tossed; /* inbound packets tossed because of error */ }; struct compstat { __u32 unc_bytes; /* total uncompressed bytes */ __u32 unc_packets; /* total uncompressed packets */ __u32 comp_bytes; /* compressed bytes */ __u32 comp_packets; /* compressed packets */ __u32 inc_bytes; /* incompressible bytes */ __u32 inc_packets; /* incompressible packets */ /* the compression ratio is defined as in_count / bytes_out */ __u32 in_count; /* Bytes received */ __u32 bytes_out; /* Bytes transmitted */ double ratio; /* not computed in kernel. */ }; struct ppp_stats { struct pppstat p; /* basic PPP statistics */ struct vjstat vj; /* VJ header compression statistics */ }; struct ppp_comp_stats { struct compstat c; /* packet compression statistics */ struct compstat d; /* packet decompression statistics */ }; /* * The following structure records the time in seconds since * the last NP packet was sent or received. */ struct ppp_idle { time_t xmit_idle; /* time since last NP packet sent */ time_t recv_idle; /* time since last NP packet received */ }; #endif /* _PPP_DEFS_H_ */ ppp-2.5.0/include/net/0000755000175000017500000000000014412736275011542 500000000000000ppp-2.5.0/include/net/if_ppp.h0000664000175000017500000001441314273050614013104 00000000000000/* $Id: if_ppp.h,v 1.19 2002/12/06 09:49:15 paulus Exp $ */ /* * if_ppp.h - Point-to-Point Protocol definitions. * * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The name "Carnegie Mellon University" must not be used to * endorse or promote products derived from this software without * prior written permission. For permission or any legal * details, please contact * Office of Technology Transfer * Carnegie Mellon University * 5000 Forbes Avenue * Pittsburgh, PA 15213-3890 * (412) 268-4387, fax: (412) 268-7395 * tech-transfer@andrew.cmu.edu * * 4. Redistributions of any form whatsoever must retain the following * acknowledgment: * "This product includes software developed by Computing Services * at Carnegie Mellon University (http://www.cmu.edu/computing/)." * * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #ifndef _IF_PPP_H_ #define _IF_PPP_H_ /* * Bit definitions for flags. */ #define SC_COMP_PROT 0x00000001 /* protocol compression (output) */ #define SC_COMP_AC 0x00000002 /* header compression (output) */ #define SC_COMP_TCP 0x00000004 /* TCP (VJ) compression (output) */ #define SC_NO_TCP_CCID 0x00000008 /* disable VJ connection-id comp. */ #define SC_REJ_COMP_AC 0x00000010 /* reject adrs/ctrl comp. on input */ #define SC_REJ_COMP_TCP 0x00000020 /* reject TCP (VJ) comp. on input */ #define SC_CCP_OPEN 0x00000040 /* Look at CCP packets */ #define SC_CCP_UP 0x00000080 /* May send/recv compressed packets */ #define SC_DEBUG 0x00010000 /* enable debug messages */ #define SC_LOG_INPKT 0x00020000 /* log contents of good pkts recvd */ #define SC_LOG_OUTPKT 0x00040000 /* log contents of pkts sent */ #define SC_LOG_RAWIN 0x00080000 /* log all chars received */ #define SC_LOG_FLUSH 0x00100000 /* log all chars flushed */ #define SC_RCV_B7_0 0x01000000 /* have rcvd char with bit 7 = 0 */ #define SC_RCV_B7_1 0x02000000 /* have rcvd char with bit 7 = 1 */ #define SC_RCV_EVNP 0x04000000 /* have rcvd char with even parity */ #define SC_RCV_ODDP 0x08000000 /* have rcvd char with odd parity */ #define SC_SYNC 0x00200000 /* use synchronous HDLC framing */ #define SC_MASK 0x0fff00ff /* bits that user can change */ /* * State bits in sc_flags, not changeable by user. */ #define SC_TIMEOUT 0x00000400 /* timeout is currently pending */ #define SC_VJ_RESET 0x00000800 /* need to reset VJ decomp */ #define SC_COMP_RUN 0x00001000 /* compressor has been inited */ #define SC_DECOMP_RUN 0x00002000 /* decompressor has been inited */ #define SC_DC_ERROR 0x00004000 /* non-fatal decomp error detected */ #define SC_DC_FERROR 0x00008000 /* fatal decomp error detected */ #define SC_TBUSY 0x10000000 /* xmitter doesn't need a packet yet */ #define SC_PKTLOST 0x20000000 /* have lost or dropped a packet */ #define SC_FLUSH 0x40000000 /* flush input until next PPP_FLAG */ #define SC_ESCAPED 0x80000000 /* saw a PPP_ESCAPE */ /* * Ioctl definitions. */ struct npioctl { int protocol; /* PPP procotol, e.g. PPP_IP */ enum NPmode mode; }; /* Structure describing a CCP configuration option, for PPPIOCSCOMPRESS */ struct ppp_option_data { u_char *ptr; u_int length; int transmit; }; struct ifpppstatsreq { char ifr_name[IFNAMSIZ]; struct ppp_stats stats; }; struct ifpppcstatsreq { char ifr_name[IFNAMSIZ]; struct ppp_comp_stats stats; }; /* * Ioctl definitions. */ #define PPPIOCGFLAGS _IOR('t', 90, int) /* get configuration flags */ #define PPPIOCSFLAGS _IOW('t', 89, int) /* set configuration flags */ #define PPPIOCGASYNCMAP _IOR('t', 88, int) /* get async map */ #define PPPIOCSASYNCMAP _IOW('t', 87, int) /* set async map */ #define PPPIOCGUNIT _IOR('t', 86, int) /* get ppp unit number */ #define PPPIOCGRASYNCMAP _IOR('t', 85, int) /* get receive async map */ #define PPPIOCSRASYNCMAP _IOW('t', 84, int) /* set receive async map */ #define PPPIOCGMRU _IOR('t', 83, int) /* get max receive unit */ #define PPPIOCSMRU _IOW('t', 82, int) /* set max receive unit */ #define PPPIOCSMAXCID _IOW('t', 81, int) /* set VJ max slot ID */ #define PPPIOCGXASYNCMAP _IOR('t', 80, ext_accm) /* get extended ACCM */ #define PPPIOCSXASYNCMAP _IOW('t', 79, ext_accm) /* set extended ACCM */ #define PPPIOCXFERUNIT _IO('t', 78) /* transfer PPP unit */ #define PPPIOCSCOMPRESS _IOW('t', 77, struct ppp_option_data) #define PPPIOCGNPMODE _IOWR('t', 76, struct npioctl) /* get NP mode */ #define PPPIOCSNPMODE _IOW('t', 75, struct npioctl) /* set NP mode */ #define PPPIOCGIDLE _IOR('t', 74, struct ppp_idle) /* get idle time */ #ifdef PPP_WITH_FILTER #define PPPIOCSPASS _IOW('t', 71, struct bpf_program) /* set pass filter */ #define PPPIOCSACTIVE _IOW('t', 70, struct bpf_program) /* set active filt */ #endif /* PPP_WITH_FILTER */ /* PPPIOC[GS]MTU are alternatives to SIOC[GS]IFMTU, used under Ultrix */ #define PPPIOCGMTU _IOR('t', 73, int) /* get interface MTU */ #define PPPIOCSMTU _IOW('t', 72, int) /* set interface MTU */ /* * These two are interface ioctls so that pppstats can do them on * a socket without having to open the serial device. */ #define SIOCGPPPSTATS _IOWR('i', 123, struct ifpppstatsreq) #define SIOCGPPPCSTATS _IOWR('i', 122, struct ifpppcstatsreq) #if !defined(ifr_mtu) #define ifr_mtu ifr_ifru.ifru_metric #endif #if (defined(_KERNEL) || defined(KERNEL)) && !defined(NeXT) void pppattach(void); void pppintr(void); #endif #endif /* _IF_PPP_H_ */ ppp-2.5.0/include/net/ppp-comp.h0000664000175000017500000001361713772531041013370 00000000000000/* * ppp-comp.h - Definitions for doing PPP packet compression. * * Copyright (c) 1984 Paul Mackerras. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The name(s) of the authors of this software must not be used to * endorse or promote products derived from this software without * prior written permission. * * 4. Redistributions of any form whatsoever must retain the following * acknowledgment: * "This product includes software developed by Paul Mackerras * ". * * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * $Id: ppp-comp.h,v 1.13 2002/12/06 09:49:15 paulus Exp $ */ #ifndef _NET_PPP_COMP_H #define _NET_PPP_COMP_H /* * The following symbols control whether we include code for * various compression methods. */ #ifndef DO_BSD_COMPRESS #define DO_BSD_COMPRESS 1 /* by default, include BSD-Compress */ #endif #ifndef DO_DEFLATE #define DO_DEFLATE 1 /* by default, include Deflate */ #endif #define DO_PREDICTOR_1 0 #define DO_PREDICTOR_2 0 /* * Structure giving methods for compression/decompression. */ #ifdef PACKETPTR struct compressor { int compress_proto; /* CCP compression protocol number */ /* Allocate space for a compressor (transmit side) */ void *(*comp_alloc)(u_char *options, int opt_len); /* Free space used by a compressor */ void (*comp_free)(void *state); /* Initialize a compressor */ int (*comp_init)(void *state, u_char *options, int opt_len, int unit, int hdrlen, int debug); /* Reset a compressor */ void (*comp_reset)(void *state); /* Compress a packet */ int (*compress)(void *state, PACKETPTR *mret, PACKETPTR mp, int orig_len, int max_len); /* Return compression statistics */ void (*comp_stat)(void *state, struct compstat *stats); /* Allocate space for a decompressor (receive side) */ void *(*decomp_alloc)(u_char *options, int opt_len); /* Free space used by a decompressor */ void (*decomp_free)(void *state); /* Initialize a decompressor */ int (*decomp_init)(void *state, u_char *options, int opt_len, int unit, int hdrlen, int mru, int debug); /* Reset a decompressor */ void (*decomp_reset)(void *state); /* Decompress a packet. */ int (*decompress)(void *state, PACKETPTR mp, PACKETPTR *dmpp); /* Update state for an incompressible packet received */ void (*incomp)(void *state, PACKETPTR mp); /* Return decompression statistics */ void (*decomp_stat)(void *state, struct compstat *stats); }; #endif /* PACKETPTR */ /* * Return values for decompress routine. * We need to make these distinctions so that we can disable certain * useful functionality, namely sending a CCP reset-request as a result * of an error detected after decompression. This is to avoid infringing * a patent held by Motorola. * Don't you just lurve software patents. */ #define DECOMP_OK 0 /* everything went OK */ #define DECOMP_ERROR 1 /* error detected before decomp. */ #define DECOMP_FATALERROR 2 /* error detected after decomp. */ /* * CCP codes. */ #define CCP_CONFREQ 1 #define CCP_CONFACK 2 #define CCP_TERMREQ 5 #define CCP_TERMACK 6 #define CCP_RESETREQ 14 #define CCP_RESETACK 15 /* * Max # bytes for a CCP option */ #define CCP_MAX_OPTION_LENGTH 32 /* * Parts of a CCP packet. */ #define CCP_CODE(dp) ((dp)[0]) #define CCP_ID(dp) ((dp)[1]) #define CCP_LENGTH(dp) (((dp)[2] << 8) + (dp)[3]) #define CCP_HDRLEN 4 #define CCP_OPT_CODE(dp) ((dp)[0]) #define CCP_OPT_LENGTH(dp) ((dp)[1]) #define CCP_OPT_MINLEN 2 /* * Definitions for BSD-Compress. */ #define CI_BSD_COMPRESS 21 /* config. option for BSD-Compress */ #define CILEN_BSD_COMPRESS 3 /* length of config. option */ /* Macros for handling the 3rd byte of the BSD-Compress config option. */ #define BSD_NBITS(x) ((x) & 0x1F) /* number of bits requested */ #define BSD_VERSION(x) ((x) >> 5) /* version of option format */ #define BSD_CURRENT_VERSION 1 /* current version number */ #define BSD_MAKE_OPT(v, n) (((v) << 5) | (n)) #define BSD_MIN_BITS 9 /* smallest code size supported */ #define BSD_MAX_BITS 15 /* largest code size supported */ /* * Definitions for Deflate. */ #define CI_DEFLATE 26 /* config option for Deflate */ #define CI_DEFLATE_DRAFT 24 /* value used in original draft RFC */ #define CILEN_DEFLATE 4 /* length of its config option */ #define DEFLATE_MIN_SIZE 8 #define DEFLATE_MAX_SIZE 15 #define DEFLATE_METHOD_VAL 8 #define DEFLATE_SIZE(x) (((x) >> 4) + DEFLATE_MIN_SIZE) #define DEFLATE_METHOD(x) ((x) & 0x0F) #define DEFLATE_MAKE_OPT(w) ((((w) - DEFLATE_MIN_SIZE) << 4) \ + DEFLATE_METHOD_VAL) #define DEFLATE_CHK_SEQUENCE 0 /* * Definitions for MPPE. */ #define CI_MPPE 18 /* config option for MPPE */ #define CILEN_MPPE 6 /* length of config option */ /* * Definitions for other, as yet unsupported, compression methods. */ #define CI_PREDICTOR_1 1 /* config option for Predictor-1 */ #define CILEN_PREDICTOR_1 2 /* length of its config option */ #define CI_PREDICTOR_2 2 /* config option for Predictor-2 */ #define CILEN_PREDICTOR_2 2 /* length of its config option */ #endif /* _NET_PPP_COMP_H */ ppp-2.5.0/include/net/ppp_defs.h0000664000175000017500000001457013772531061013436 00000000000000/* $Id: ppp_defs.h,v 1.17 2002/12/06 09:49:15 paulus Exp $ */ /* * ppp_defs.h - PPP definitions. * * Copyright (c) 1984 Paul Mackerras. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The name(s) of the authors of this software must not be used to * endorse or promote products derived from this software without * prior written permission. * * 4. Redistributions of any form whatsoever must retain the following * acknowledgment: * "This product includes software developed by Paul Mackerras * ". * * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #ifndef _PPP_DEFS_H_ #define _PPP_DEFS_H_ /* * The basic PPP frame. */ #define PPP_HDRLEN 4 /* octets for standard ppp header */ #define PPP_FCSLEN 2 /* octets for FCS */ /* * Packet sizes * * Note - lcp shouldn't be allowed to negotiate stuff outside these * limits. See lcp.h in the pppd directory. * (XXX - these constants should simply be shared by lcp.c instead * of living in lcp.h) */ #define PPP_MTU 1500 /* Default MTU (size of Info field) */ #define PPP_MAXMTU 65535 - (PPP_HDRLEN + PPP_FCSLEN) #define PPP_MINMTU 64 #define PPP_MRU 1500 /* default MRU = max length of info field */ #define PPP_MAXMRU 65000 /* Largest MRU we allow */ #define PPP_MINMRU 128 #define PPP_ADDRESS(p) (((u_char *)(p))[0]) #define PPP_CONTROL(p) (((u_char *)(p))[1]) #define PPP_PROTOCOL(p) ((((u_char *)(p))[2] << 8) + ((u_char *)(p))[3]) /* * Significant octet values. */ #define PPP_ALLSTATIONS 0xff /* All-Stations broadcast address */ #define PPP_UI 0x03 /* Unnumbered Information */ #define PPP_FLAG 0x7e /* Flag Sequence */ #define PPP_ESCAPE 0x7d /* Asynchronous Control Escape */ #define PPP_TRANS 0x20 /* Asynchronous transparency modifier */ /* * Protocol field values. */ #define PPP_IP 0x21 /* Internet Protocol */ #define PPP_AT 0x29 /* AppleTalk Protocol */ #define PPP_IPX 0x2b /* IPX protocol */ #define PPP_VJC_COMP 0x2d /* VJ compressed TCP */ #define PPP_VJC_UNCOMP 0x2f /* VJ uncompressed TCP */ #define PPP_IPV6 0x57 /* Internet Protocol Version 6 */ #define PPP_COMP 0xfd /* compressed packet */ #define PPP_IPCP 0x8021 /* IP Control Protocol */ #define PPP_ATCP 0x8029 /* AppleTalk Control Protocol */ #define PPP_IPXCP 0x802b /* IPX Control Protocol */ #define PPP_IPV6CP 0x8057 /* IPv6 Control Protocol */ #define PPP_CCP 0x80fd /* Compression Control Protocol */ #define PPP_ECP 0x8053 /* Encryption Control Protocol */ #define PPP_LCP 0xc021 /* Link Control Protocol */ #define PPP_PAP 0xc023 /* Password Authentication Protocol */ #define PPP_LQR 0xc025 /* Link Quality Report protocol */ #define PPP_CHAP 0xc223 /* Cryptographic Handshake Auth. Protocol */ #define PPP_CBCP 0xc029 /* Callback Control Protocol */ #define PPP_EAP 0xc227 /* Extensible Authentication Protocol */ /* * Values for FCS calculations. */ #define PPP_INITFCS 0xffff /* Initial FCS value */ #define PPP_GOODFCS 0xf0b8 /* Good final FCS value */ #define PPP_FCS(fcs, c) (((fcs) >> 8) ^ fcstab[((fcs) ^ (c)) & 0xff]) /* * A 32-bit unsigned integral type. */ #if !defined(__BIT_TYPES_DEFINED__) && !defined(_BITYPES) \ && !defined(__FreeBSD__) && (NS_TARGET < 40) #ifdef UINT32_T typedef UINT32_T u_int32_t; #else typedef unsigned int u_int32_t; typedef unsigned short u_int16_t; #endif #endif /* * Extended asyncmap - allows any character to be escaped. */ typedef u_int32_t ext_accm[8]; /* * What to do with network protocol (NP) packets. */ enum NPmode { NPMODE_PASS, /* pass the packet through */ NPMODE_DROP, /* silently drop the packet */ NPMODE_ERROR, /* return an error */ NPMODE_QUEUE /* save it up for later. */ }; /* * Statistics. */ struct pppstat { unsigned int ppp_ibytes; /* bytes received */ unsigned int ppp_ipackets; /* packets received */ unsigned int ppp_ierrors; /* receive errors */ unsigned int ppp_obytes; /* bytes sent */ unsigned int ppp_opackets; /* packets sent */ unsigned int ppp_oerrors; /* transmit errors */ }; struct vjstat { unsigned int vjs_packets; /* outbound packets */ unsigned int vjs_compressed; /* outbound compressed packets */ unsigned int vjs_searches; /* searches for connection state */ unsigned int vjs_misses; /* times couldn't find conn. state */ unsigned int vjs_uncompressedin; /* inbound uncompressed packets */ unsigned int vjs_compressedin; /* inbound compressed packets */ unsigned int vjs_errorin; /* inbound unknown type packets */ unsigned int vjs_tossed; /* inbound packets tossed because of error */ }; struct ppp_stats { struct pppstat p; /* basic PPP statistics */ struct vjstat vj; /* VJ header compression statistics */ }; struct compstat { unsigned int unc_bytes; /* total uncompressed bytes */ unsigned int unc_packets; /* total uncompressed packets */ unsigned int comp_bytes; /* compressed bytes */ unsigned int comp_packets; /* compressed packets */ unsigned int inc_bytes; /* incompressible bytes */ unsigned int inc_packets; /* incompressible packets */ unsigned int ratio; /* recent compression ratio << 8 */ }; struct ppp_comp_stats { struct compstat c; /* packet compression statistics */ struct compstat d; /* packet decompression statistics */ }; /* * The following structure records the time in seconds since * the last NP packet was sent or received. */ struct ppp_idle { time_t xmit_idle; /* time since last NP packet sent */ time_t recv_idle; /* time since last NP packet received */ }; #endif /* _PPP_DEFS_H_ */ ppp-2.5.0/include/net/pppio.h0000644000175000017500000001125307574071233012761 00000000000000/* * pppio.h - ioctl and other misc. definitions for STREAMS modules. * * Copyright (c) 1994 Paul Mackerras. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The name(s) of the authors of this software must not be used to * endorse or promote products derived from this software without * prior written permission. * * 4. Redistributions of any form whatsoever must retain the following * acknowledgment: * "This product includes software developed by Paul Mackerras * ". * * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * $Id: pppio.h,v 1.9 2002/12/06 09:49:15 paulus Exp $ */ #define _PPPIO(n) (('p' << 8) + (n)) #define PPPIO_NEWPPA _PPPIO(130) /* allocate a new PPP unit */ #define PPPIO_GETSTAT _PPPIO(131) /* get PPP statistics */ #define PPPIO_GETCSTAT _PPPIO(132) /* get PPP compression stats */ #define PPPIO_MTU _PPPIO(133) /* set max transmission unit */ #define PPPIO_MRU _PPPIO(134) /* set max receive unit */ #define PPPIO_CFLAGS _PPPIO(135) /* set/clear/get compression flags */ #define PPPIO_XCOMP _PPPIO(136) /* alloc transmit compressor */ #define PPPIO_RCOMP _PPPIO(137) /* alloc receive decompressor */ #define PPPIO_XACCM _PPPIO(138) /* set transmit asyncmap */ #define PPPIO_RACCM _PPPIO(139) /* set receive asyncmap */ #define PPPIO_VJINIT _PPPIO(140) /* initialize VJ comp/decomp */ #define PPPIO_ATTACH _PPPIO(141) /* attach to a ppa (without putmsg) */ #define PPPIO_LASTMOD _PPPIO(142) /* mark last ppp module */ #define PPPIO_GCLEAN _PPPIO(143) /* get 8-bit-clean flags */ #define PPPIO_DEBUG _PPPIO(144) /* request debug information */ #define PPPIO_BIND _PPPIO(145) /* bind to SAP */ #define PPPIO_NPMODE _PPPIO(146) /* set mode for handling data pkts */ #define PPPIO_GIDLE _PPPIO(147) /* get time since last data pkt */ #define PPPIO_PASSFILT _PPPIO(148) /* set filter for packets to pass */ #define PPPIO_ACTIVEFILT _PPPIO(149) /* set filter for "link active" pkts */ /* * Values for PPPIO_CFLAGS */ #define COMP_AC 0x1 /* compress address/control */ #define DECOMP_AC 0x2 /* decompress address/control */ #define COMP_PROT 0x4 /* compress PPP protocol */ #define DECOMP_PROT 0x8 /* decompress PPP protocol */ #define COMP_VJC 0x10 /* compress TCP/IP headers */ #define COMP_VJCCID 0x20 /* compress connection ID as well */ #define DECOMP_VJC 0x40 /* decompress TCP/IP headers */ #define DECOMP_VJCCID 0x80 /* accept compressed connection ID */ #define CCP_ISOPEN 0x100 /* look at CCP packets */ #define CCP_ISUP 0x200 /* do packet comp/decomp */ #define CCP_ERROR 0x400 /* (status) error in packet decomp */ #define CCP_FATALERROR 0x800 /* (status) fatal error ditto */ #define CCP_COMP_RUN 0x1000 /* (status) seen CCP ack sent */ #define CCP_DECOMP_RUN 0x2000 /* (status) seen CCP ack rcvd */ /* * Values for 8-bit-clean flags. */ #define RCV_B7_0 1 /* have rcvd char with bit 7 = 0 */ #define RCV_B7_1 2 /* have rcvd char with bit 7 = 1 */ #define RCV_EVNP 4 /* have rcvd char with even parity */ #define RCV_ODDP 8 /* have rcvd char with odd parity */ /* * Values for the first byte of M_CTL messages passed between * PPP modules. */ #define PPPCTL_OERROR 0xe0 /* output error [up] */ #define PPPCTL_IERROR 0xe1 /* input error (e.g. FCS) [up] */ #define PPPCTL_MTU 0xe2 /* set MTU [down] */ #define PPPCTL_MRU 0xe3 /* set MRU [down] */ #define PPPCTL_UNIT 0xe4 /* note PPP unit number [down] */ /* * Values for the integer argument to PPPIO_DEBUG. */ #define PPPDBG_DUMP 0x10000 /* print out debug info now */ #define PPPDBG_LOG 0x100 /* log various things */ #define PPPDBG_DRIVER 0 /* identifies ppp driver as target */ #define PPPDBG_IF 1 /* identifies ppp network i/f target */ #define PPPDBG_COMP 2 /* identifies ppp compression target */ #define PPPDBG_AHDLC 3 /* identifies ppp async hdlc target */ ppp-2.5.0/include/net/slcompress.h0000664000175000017500000001333513772531107014027 00000000000000/* * Definitions for tcp compression routines. * * $Id: slcompress.h,v 1.4 1994/09/21 06:50:08 paulus Exp $ * * Copyright (c) 1989 Regents of the University of California. * All rights reserved. * * Redistribution and use in source and binary forms are permitted * provided that the above copyright notice and this paragraph are * duplicated in all such forms and that any documentation, * advertising materials, and other materials related to such * distribution and use acknowledge that the software was developed * by the University of California, Berkeley. The name of the * University may not be used to endorse or promote products derived * from this software without specific prior written permission. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * * Van Jacobson (van@helios.ee.lbl.gov), Dec 31, 1989: * - Initial distribution. */ #ifndef _SLCOMPRESS_H_ #define _SLCOMPRESS_H_ #define MAX_STATES 16 /* must be > 2 and < 256 */ #define MAX_HDR MLEN /* XXX 4bsd-ism: should really be 128 */ /* * Compressed packet format: * * The first octet contains the packet type (top 3 bits), TCP * 'push' bit, and flags that indicate which of the 4 TCP sequence * numbers have changed (bottom 5 bits). The next octet is a * conversation number that associates a saved IP/TCP header with * the compressed packet. The next two octets are the TCP checksum * from the original datagram. The next 0 to 15 octets are * sequence number changes, one change per bit set in the header * (there may be no changes and there are two special cases where * the receiver implicitly knows what changed -- see below). * * There are 5 numbers which can change (they are always inserted * in the following order): TCP urgent pointer, window, * acknowlegement, sequence number and IP ID. (The urgent pointer * is different from the others in that its value is sent, not the * change in value.) Since typical use of SLIP links is biased * toward small packets (see comments on MTU/MSS below), changes * use a variable length coding with one octet for numbers in the * range 1 - 255 and 3 octets (0, MSB, LSB) for numbers in the * range 256 - 65535 or 0. (If the change in sequence number or * ack is more than 65535, an uncompressed packet is sent.) */ /* * Packet types (must not conflict with IP protocol version) * * The top nibble of the first octet is the packet type. There are * three possible types: IP (not proto TCP or tcp with one of the * control flags set); uncompressed TCP (a normal IP/TCP packet but * with the 8-bit protocol field replaced by an 8-bit connection id -- * this type of packet syncs the sender & receiver); and compressed * TCP (described above). * * LSB of 4-bit field is TCP "PUSH" bit (a worthless anachronism) and * is logically part of the 4-bit "changes" field that follows. Top * three bits are actual packet type. For backward compatibility * and in the interest of conserving bits, numbers are chosen so the * IP protocol version number (4) which normally appears in this nibble * means "IP packet". */ /* packet types */ #define TYPE_IP 0x40 #define TYPE_UNCOMPRESSED_TCP 0x70 #define TYPE_COMPRESSED_TCP 0x80 #define TYPE_ERROR 0x00 /* Bits in first octet of compressed packet */ #define NEW_C 0x40 /* flag bits for what changed in a packet */ #define NEW_I 0x20 #define NEW_S 0x08 #define NEW_A 0x04 #define NEW_W 0x02 #define NEW_U 0x01 /* reserved, special-case values of above */ #define SPECIAL_I (NEW_S|NEW_W|NEW_U) /* echoed interactive traffic */ #define SPECIAL_D (NEW_S|NEW_A|NEW_W|NEW_U) /* unidirectional data */ #define SPECIALS_MASK (NEW_S|NEW_A|NEW_W|NEW_U) #define TCP_PUSH_BIT 0x10 /* * "state" data for each active tcp conversation on the wire. This is * basically a copy of the entire IP/TCP header from the last packet * we saw from the conversation together with a small identifier * the transmit & receive ends of the line use to locate saved header. */ struct cstate { struct cstate *cs_next; /* next most recently used cstate (xmit only) */ u_short cs_hlen; /* size of hdr (receive only) */ u_char cs_id; /* connection # associated with this state */ u_char cs_filler; union { char csu_hdr[MAX_HDR]; struct ip csu_ip; /* ip/tcp hdr from most recent packet */ } slcs_u; }; #define cs_ip slcs_u.csu_ip #define cs_hdr slcs_u.csu_hdr /* * all the state data for one serial line (we need one of these * per line). */ struct slcompress { struct cstate *last_cs; /* most recently used tstate */ u_char last_recv; /* last rcvd conn. id */ u_char last_xmit; /* last sent conn. id */ u_short flags; #ifndef SL_NO_STATS int sls_packets; /* outbound packets */ int sls_compressed; /* outbound compressed packets */ int sls_searches; /* searches for connection state */ int sls_misses; /* times couldn't find conn. state */ int sls_uncompressedin; /* inbound uncompressed packets */ int sls_compressedin; /* inbound compressed packets */ int sls_errorin; /* inbound unknown type packets */ int sls_tossed; /* inbound packets tossed because of error */ #endif struct cstate tstate[MAX_STATES]; /* xmit connection states */ struct cstate rstate[MAX_STATES]; /* receive connection states */ }; /* flag values */ #define SLF_TOSS 1 /* tossing rcvd frames because of input err */ void sl_compress_init(struct slcompress *); void sl_compress_setup(struct slcompress *, int); u_int sl_compress_tcp(struct mbuf *, struct ip *, struct slcompress *, int); int sl_uncompress_tcp(u_char **, int, u_int, struct slcompress *); int sl_uncompress_tcp_core(u_char *, int, int, u_int, struct slcompress *, u_char **, u_int *); #endif /* _SLCOMPRESS_H_ */ ppp-2.5.0/include/net/vjcompress.h0000664000175000017500000001270113772531142014023 00000000000000/* * Definitions for tcp compression routines. * * $Id: vjcompress.h,v 1.3 1996/05/28 00:55:33 paulus Exp $ * * Copyright (c) 1989 Regents of the University of California. * All rights reserved. * * Redistribution and use in source and binary forms are permitted * provided that the above copyright notice and this paragraph are * duplicated in all such forms and that any documentation, * advertising materials, and other materials related to such * distribution and use acknowledge that the software was developed * by the University of California, Berkeley. The name of the * University may not be used to endorse or promote products derived * from this software without specific prior written permission. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * * Van Jacobson (van@helios.ee.lbl.gov), Dec 31, 1989: * - Initial distribution. */ #ifndef _VJCOMPRESS_H_ #define _VJCOMPRESS_H_ #define MAX_STATES 16 /* must be > 2 and < 256 */ #define MAX_HDR 128 /* * Compressed packet format: * * The first octet contains the packet type (top 3 bits), TCP * 'push' bit, and flags that indicate which of the 4 TCP sequence * numbers have changed (bottom 5 bits). The next octet is a * conversation number that associates a saved IP/TCP header with * the compressed packet. The next two octets are the TCP checksum * from the original datagram. The next 0 to 15 octets are * sequence number changes, one change per bit set in the header * (there may be no changes and there are two special cases where * the receiver implicitly knows what changed -- see below). * * There are 5 numbers which can change (they are always inserted * in the following order): TCP urgent pointer, window, * acknowlegement, sequence number and IP ID. (The urgent pointer * is different from the others in that its value is sent, not the * change in value.) Since typical use of SLIP links is biased * toward small packets (see comments on MTU/MSS below), changes * use a variable length coding with one octet for numbers in the * range 1 - 255 and 3 octets (0, MSB, LSB) for numbers in the * range 256 - 65535 or 0. (If the change in sequence number or * ack is more than 65535, an uncompressed packet is sent.) */ /* * Packet types (must not conflict with IP protocol version) * * The top nibble of the first octet is the packet type. There are * three possible types: IP (not proto TCP or tcp with one of the * control flags set); uncompressed TCP (a normal IP/TCP packet but * with the 8-bit protocol field replaced by an 8-bit connection id -- * this type of packet syncs the sender & receiver); and compressed * TCP (described above). * * LSB of 4-bit field is TCP "PUSH" bit (a worthless anachronism) and * is logically part of the 4-bit "changes" field that follows. Top * three bits are actual packet type. For backward compatibility * and in the interest of conserving bits, numbers are chosen so the * IP protocol version number (4) which normally appears in this nibble * means "IP packet". */ /* packet types */ #define TYPE_IP 0x40 #define TYPE_UNCOMPRESSED_TCP 0x70 #define TYPE_COMPRESSED_TCP 0x80 #define TYPE_ERROR 0x00 /* Bits in first octet of compressed packet */ #define NEW_C 0x40 /* flag bits for what changed in a packet */ #define NEW_I 0x20 #define NEW_S 0x08 #define NEW_A 0x04 #define NEW_W 0x02 #define NEW_U 0x01 /* reserved, special-case values of above */ #define SPECIAL_I (NEW_S|NEW_W|NEW_U) /* echoed interactive traffic */ #define SPECIAL_D (NEW_S|NEW_A|NEW_W|NEW_U) /* unidirectional data */ #define SPECIALS_MASK (NEW_S|NEW_A|NEW_W|NEW_U) #define TCP_PUSH_BIT 0x10 /* * "state" data for each active tcp conversation on the wire. This is * basically a copy of the entire IP/TCP header from the last packet * we saw from the conversation together with a small identifier * the transmit & receive ends of the line use to locate saved header. */ struct cstate { struct cstate *cs_next; /* next most recently used state (xmit only) */ u_short cs_hlen; /* size of hdr (receive only) */ u_char cs_id; /* connection # associated with this state */ u_char cs_filler; union { char csu_hdr[MAX_HDR]; struct ip csu_ip; /* ip/tcp hdr from most recent packet */ } vjcs_u; }; #define cs_ip vjcs_u.csu_ip #define cs_hdr vjcs_u.csu_hdr /* * all the state data for one serial line (we need one of these per line). */ struct vjcompress { struct cstate *last_cs; /* most recently used tstate */ u_char last_recv; /* last rcvd conn. id */ u_char last_xmit; /* last sent conn. id */ u_short flags; #ifndef VJ_NO_STATS struct vjstat stats; #endif struct cstate tstate[MAX_STATES]; /* xmit connection states */ struct cstate rstate[MAX_STATES]; /* receive connection states */ }; /* flag values */ #define VJF_TOSS 1 /* tossing rcvd frames because of input err */ extern void vj_compress_init(struct vjcompress *comp, int max_state); extern u_int vj_compress_tcp(struct ip *ip, u_int mlen, struct vjcompress *comp, int compress_cid_flag, u_char **vjhdrp); extern void vj_uncompress_err(struct vjcompress *comp); extern int vj_uncompress_uncomp(u_char *buf, int buflen, struct vjcompress *comp); extern int vj_uncompress_tcp(u_char *buf, int buflen, int total_len, struct vjcompress *comp, u_char **hdrp, u_int *hlenp); #endif /* _VJCOMPRESS_H_ */ ppp-2.5.0/include/Makefile.am0000664000175000017500000000036514076444143012732 00000000000000EXTRA_HEADERS = \ linux/if_ppp.h \ linux/ppp-comp.h \ linux/ppp_defs.h \ net/if_ppp.h \ net/ppp-comp.h \ net/ppp_defs.h \ net/pppio.h \ net/slcompress.h \ net/vjcompress.h EXTRA_DIST = \ $(EXTRA_HEADERS) ppp-2.5.0/include/Makefile.in0000644000175000017500000003244714407475314012751 00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = include ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_atm.m4 \ $(top_srcdir)/m4/ax_check_openssl.m4 \ $(top_srcdir)/m4/ax_check_openssl_func.m4 \ $(top_srcdir)/m4/ax_check_pam.m4 \ $(top_srcdir)/m4/ax_check_pcap.m4 \ $(top_srcdir)/m4/ax_check_srp.m4 $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/pkg.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/pppd/config.h \ $(top_builddir)/pppd/pppdconf.h \ $(top_builddir)/pppd/plugins/pppoe/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) am__DIST_COMMON = $(srcdir)/Makefile.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ ATM_CFLAGS = @ATM_CFLAGS@ ATM_LDFLAGS = @ATM_LDFLAGS@ ATM_LIBS = @ATM_LIBS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CRYPT_LIBS = @CRYPT_LIBS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GREP = @GREP@ GTK_CFLAGS = @GTK_CFLAGS@ GTK_LIBS = @GTK_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_INCLUDES = @OPENSSL_INCLUDES@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAM_CFLAGS = @PAM_CFLAGS@ PAM_LDFLAGS = @PAM_LDFLAGS@ PAM_LIBS = @PAM_LIBS@ PATH_SEPARATOR = @PATH_SEPARATOR@ PCAP_CFLAGS = @PCAP_CFLAGS@ PCAP_LDFLAGS = @PCAP_LDFLAGS@ PCAP_LIBS = @PCAP_LIBS@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PPPD_LOGFILE_DIR = @PPPD_LOGFILE_DIR@ PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@ PPPD_RUNTIME_DIR = @PPPD_RUNTIME_DIR@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SRP_CFLAGS = @SRP_CFLAGS@ SRP_LDFLAGS = @SRP_LDFLAGS@ SRP_LIBS = @SRP_LIBS@ STRIP = @STRIP@ SYSTEMD_CFLAGS = @SYSTEMD_CFLAGS@ SYSTEMD_LIBS = @SYSTEMD_LIBS@ SYSTEM_CA_PATH = @SYSTEM_CA_PATH@ UTIL_LIBS = @UTIL_LIBS@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ EXTRA_HEADERS = \ linux/if_ppp.h \ linux/ppp-comp.h \ linux/ppp_defs.h \ net/if_ppp.h \ net/ppp-comp.h \ net/ppp_defs.h \ net/pppio.h \ net/slcompress.h \ net/vjcompress.h EXTRA_DIST = \ $(EXTRA_HEADERS) all: all-am .SUFFIXES: $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu include/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu include/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs tags TAGS: ctags CTAGS: cscope cscopelist: distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic clean-libtool \ cscopelist-am ctags-am distclean distclean-generic \ distclean-libtool distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: ppp-2.5.0/modules/0000755000175000017500000000000014412736275011001 500000000000000ppp-2.5.0/modules/Makefile.am0000664000175000017500000000026514076444143012756 00000000000000EXTRA_MODULE = \ bsd-comp.c \ deflate.c \ if_ppp.c \ ppp_ahdlc.c \ ppp.c \ ppp_comp.c \ ppp_mod.h \ vjcompress.c EXTRA_DIST = \ $(EXTRA_MODULE) ppp-2.5.0/modules/Makefile.in0000644000175000017500000003234714407475314012775 00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = modules ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_atm.m4 \ $(top_srcdir)/m4/ax_check_openssl.m4 \ $(top_srcdir)/m4/ax_check_openssl_func.m4 \ $(top_srcdir)/m4/ax_check_pam.m4 \ $(top_srcdir)/m4/ax_check_pcap.m4 \ $(top_srcdir)/m4/ax_check_srp.m4 $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/pkg.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/pppd/config.h \ $(top_builddir)/pppd/pppdconf.h \ $(top_builddir)/pppd/plugins/pppoe/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) am__DIST_COMMON = $(srcdir)/Makefile.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ ATM_CFLAGS = @ATM_CFLAGS@ ATM_LDFLAGS = @ATM_LDFLAGS@ ATM_LIBS = @ATM_LIBS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CRYPT_LIBS = @CRYPT_LIBS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GREP = @GREP@ GTK_CFLAGS = @GTK_CFLAGS@ GTK_LIBS = @GTK_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_INCLUDES = @OPENSSL_INCLUDES@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAM_CFLAGS = @PAM_CFLAGS@ PAM_LDFLAGS = @PAM_LDFLAGS@ PAM_LIBS = @PAM_LIBS@ PATH_SEPARATOR = @PATH_SEPARATOR@ PCAP_CFLAGS = @PCAP_CFLAGS@ PCAP_LDFLAGS = @PCAP_LDFLAGS@ PCAP_LIBS = @PCAP_LIBS@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PPPD_LOGFILE_DIR = @PPPD_LOGFILE_DIR@ PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@ PPPD_RUNTIME_DIR = @PPPD_RUNTIME_DIR@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SRP_CFLAGS = @SRP_CFLAGS@ SRP_LDFLAGS = @SRP_LDFLAGS@ SRP_LIBS = @SRP_LIBS@ STRIP = @STRIP@ SYSTEMD_CFLAGS = @SYSTEMD_CFLAGS@ SYSTEMD_LIBS = @SYSTEMD_LIBS@ SYSTEM_CA_PATH = @SYSTEM_CA_PATH@ UTIL_LIBS = @UTIL_LIBS@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ EXTRA_MODULE = \ bsd-comp.c \ deflate.c \ if_ppp.c \ ppp_ahdlc.c \ ppp.c \ ppp_comp.c \ ppp_mod.h \ vjcompress.c EXTRA_DIST = \ $(EXTRA_MODULE) all: all-am .SUFFIXES: $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu modules/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu modules/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs tags TAGS: ctags CTAGS: cscope cscopelist: distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic clean-libtool \ cscopelist-am ctags-am distclean distclean-generic \ distclean-libtool distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: ppp-2.5.0/modules/bsd-comp.c0000664000175000017500000007163513772531224012602 00000000000000/* Because this code is derived from the 4.3BSD compress source: * * * Copyright (c) 1985, 1986 The Regents of the University of California. * All rights reserved. * * This code is derived from software contributed to Berkeley by * James A. Woods, derived from original work by Spencer Thomas * and Joseph Orost. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* * This version is for use with STREAMS under SunOS 4.x, * Digital UNIX, AIX 4.x, and SVR4 systems including Solaris 2. * * $Id: bsd-comp.c,v 1.21 2004/01/17 05:47:55 carlsonj Exp $ */ #ifdef AIX4 #include #endif #include #include #include #include #include "ppp_mod.h" #ifdef SVR4 #include #ifndef _BIG_ENDIAN #define BSD_LITTLE_ENDIAN #endif #endif #ifdef __osf__ #undef FIRST #undef LAST #define BSD_LITTLE_ENDIAN #endif #ifdef SOL2 #include #endif #define PACKETPTR mblk_t * #include #if DO_BSD_COMPRESS /* * PPP "BSD compress" compression * The differences between this compression and the classic BSD LZW * source are obvious from the requirement that the classic code worked * with files while this handles arbitrarily long streams that * are broken into packets. They are: * * When the code size expands, a block of junk is not emitted by * the compressor and not expected by the decompressor. * * New codes are not necessarily assigned every time an old * code is output by the compressor. This is because a packet * end forces a code to be emitted, but does not imply that a * new sequence has been seen. * * The compression ratio is checked at the first end of a packet * after the appropriate gap. Besides simplifying and speeding * things up, this makes it more likely that the transmitter * and receiver will agree when the dictionary is cleared when * compression is not going well. */ /* * A dictionary for doing BSD compress. */ struct bsd_db { int totlen; /* length of this structure */ u_int hsize; /* size of the hash table */ u_char hshift; /* used in hash function */ u_char n_bits; /* current bits/code */ u_char maxbits; u_char debug; u_char unit; u_short seqno; /* sequence number of next packet */ u_int hdrlen; /* header length to preallocate */ u_int mru; u_int maxmaxcode; /* largest valid code */ u_int max_ent; /* largest code in use */ u_int in_count; /* uncompressed bytes, aged */ u_int bytes_out; /* compressed bytes, aged */ u_int ratio; /* recent compression ratio */ u_int checkpoint; /* when to next check the ratio */ u_int clear_count; /* times dictionary cleared */ u_int incomp_count; /* incompressible packets */ u_int incomp_bytes; /* incompressible bytes */ u_int uncomp_count; /* uncompressed packets */ u_int uncomp_bytes; /* uncompressed bytes */ u_int comp_count; /* compressed packets */ u_int comp_bytes; /* compressed bytes */ u_short *lens; /* array of lengths of codes */ struct bsd_dict { union { /* hash value */ u_int32_t fcode; struct { #ifdef BSD_LITTLE_ENDIAN u_short prefix; /* preceding code */ u_char suffix; /* last character of new code */ u_char pad; #else u_char pad; u_char suffix; /* last character of new code */ u_short prefix; /* preceding code */ #endif } hs; } f; u_short codem1; /* output of hash table -1 */ u_short cptr; /* map code to hash table entry */ } dict[1]; }; #define BSD_OVHD 2 /* BSD compress overhead/packet */ #define BSD_INIT_BITS BSD_MIN_BITS static void *bsd_comp_alloc(u_char *options, int opt_len); static void *bsd_decomp_alloc(u_char *options, int opt_len); static void bsd_free(void *state); static int bsd_comp_init(void *state, u_char *options, int opt_len, int unit, int hdrlen, int debug); static int bsd_decomp_init(void *state, u_char *options, int opt_len, int unit, int hdrlen, int mru, int debug); static int bsd_compress(void *state, mblk_t **mret, mblk_t *mp, int slen, int maxolen); static void bsd_incomp(void *state, mblk_t *dmsg); static int bsd_decompress(void *state, mblk_t *cmp, mblk_t **dmpp); static void bsd_reset(void *state); static void bsd_comp_stats(void *state, struct compstat *stats); /* * Procedures exported to ppp_comp.c. */ struct compressor ppp_bsd_compress = { CI_BSD_COMPRESS, /* compress_proto */ bsd_comp_alloc, /* comp_alloc */ bsd_free, /* comp_free */ bsd_comp_init, /* comp_init */ bsd_reset, /* comp_reset */ bsd_compress, /* compress */ bsd_comp_stats, /* comp_stat */ bsd_decomp_alloc, /* decomp_alloc */ bsd_free, /* decomp_free */ bsd_decomp_init, /* decomp_init */ bsd_reset, /* decomp_reset */ bsd_decompress, /* decompress */ bsd_incomp, /* incomp */ bsd_comp_stats, /* decomp_stat */ }; /* * the next two codes should not be changed lightly, as they must not * lie within the contiguous general code space. */ #define CLEAR 256 /* table clear output code */ #define FIRST 257 /* first free entry */ #define LAST 255 #define MAXCODE(b) ((1 << (b)) - 1) #define BADCODEM1 MAXCODE(BSD_MAX_BITS) #define BSD_HASH(prefix,suffix,hshift) ((((u_int32_t)(suffix)) << (hshift)) \ ^ (u_int32_t)(prefix)) #define BSD_KEY(prefix,suffix) ((((u_int32_t)(suffix)) << 16) \ + (u_int32_t)(prefix)) #define CHECK_GAP 10000 /* Ratio check interval */ #define RATIO_SCALE_LOG 8 #define RATIO_SCALE (1<>RATIO_SCALE_LOG) #define DECOMP_CHUNK 256 /* * clear the dictionary */ static void bsd_clear(db) struct bsd_db *db; { db->clear_count++; db->max_ent = FIRST-1; db->n_bits = BSD_INIT_BITS; db->ratio = 0; db->bytes_out = 0; db->in_count = 0; db->checkpoint = CHECK_GAP; } /* * If the dictionary is full, then see if it is time to reset it. * * Compute the compression ratio using fixed-point arithmetic * with 8 fractional bits. * * Since we have an infinite stream instead of a single file, * watch only the local compression ratio. * * Since both peers must reset the dictionary at the same time even in * the absence of CLEAR codes (while packets are incompressible), they * must compute the same ratio. */ static int /* 1=output CLEAR */ bsd_check(db) struct bsd_db *db; { u_int new_ratio; if (db->in_count >= db->checkpoint) { /* age the ratio by limiting the size of the counts */ if (db->in_count >= RATIO_MAX || db->bytes_out >= RATIO_MAX) { db->in_count -= db->in_count/4; db->bytes_out -= db->bytes_out/4; } db->checkpoint = db->in_count + CHECK_GAP; if (db->max_ent >= db->maxmaxcode) { /* Reset the dictionary only if the ratio is worse, * or if it looks as if it has been poisoned * by incompressible data. * * This does not overflow, because * db->in_count <= RATIO_MAX. */ new_ratio = db->in_count << RATIO_SCALE_LOG; if (db->bytes_out != 0) new_ratio /= db->bytes_out; if (new_ratio < db->ratio || new_ratio < 1 * RATIO_SCALE) { bsd_clear(db); return 1; } db->ratio = new_ratio; } } return 0; } /* * Return statistics. */ static void bsd_comp_stats(state, stats) void *state; struct compstat *stats; { struct bsd_db *db = (struct bsd_db *) state; u_int out; stats->unc_bytes = db->uncomp_bytes; stats->unc_packets = db->uncomp_count; stats->comp_bytes = db->comp_bytes; stats->comp_packets = db->comp_count; stats->inc_bytes = db->incomp_bytes; stats->inc_packets = db->incomp_count; stats->ratio = db->in_count; out = db->bytes_out; if (stats->ratio <= 0x7fffff) stats->ratio <<= 8; else out >>= 8; if (out != 0) stats->ratio /= out; } /* * Reset state, as on a CCP ResetReq. */ static void bsd_reset(state) void *state; { struct bsd_db *db = (struct bsd_db *) state; db->seqno = 0; bsd_clear(db); db->clear_count = 0; } /* * Allocate space for a (de) compressor. */ static void * bsd_alloc(options, opt_len, decomp) u_char *options; int opt_len, decomp; { int bits; u_int newlen, hsize, hshift, maxmaxcode; struct bsd_db *db; if (opt_len != 3 || options[0] != CI_BSD_COMPRESS || options[1] != 3 || BSD_VERSION(options[2]) != BSD_CURRENT_VERSION) return NULL; bits = BSD_NBITS(options[2]); switch (bits) { case 9: /* needs 82152 for both directions */ case 10: /* needs 84144 */ case 11: /* needs 88240 */ case 12: /* needs 96432 */ hsize = 5003; hshift = 4; break; case 13: /* needs 176784 */ hsize = 9001; hshift = 5; break; case 14: /* needs 353744 */ hsize = 18013; hshift = 6; break; case 15: /* needs 691440 */ hsize = 35023; hshift = 7; break; case 16: /* needs 1366160--far too much, */ /* hsize = 69001; */ /* and 69001 is too big for cptr */ /* hshift = 8; */ /* in struct bsd_db */ /* break; */ default: return NULL; } maxmaxcode = MAXCODE(bits); newlen = sizeof(*db) + (hsize-1) * (sizeof(db->dict[0])); #ifdef __osf__ db = (struct bsd_db *) ALLOC_SLEEP(newlen); #else db = (struct bsd_db *) ALLOC_NOSLEEP(newlen); #endif if (!db) return NULL; bzero(db, sizeof(*db) - sizeof(db->dict)); if (!decomp) { db->lens = NULL; } else { #ifdef __osf__ db->lens = (u_short *) ALLOC_SLEEP((maxmaxcode+1) * sizeof(db->lens[0])); #else db->lens = (u_short *) ALLOC_NOSLEEP((maxmaxcode+1) * sizeof(db->lens[0])); #endif if (!db->lens) { FREE(db, newlen); return NULL; } } db->totlen = newlen; db->hsize = hsize; db->hshift = hshift; db->maxmaxcode = maxmaxcode; db->maxbits = bits; return (void *) db; } static void bsd_free(state) void *state; { struct bsd_db *db = (struct bsd_db *) state; if (db->lens) FREE(db->lens, (db->maxmaxcode+1) * sizeof(db->lens[0])); FREE(db, db->totlen); } static void * bsd_comp_alloc(options, opt_len) u_char *options; int opt_len; { return bsd_alloc(options, opt_len, 0); } static void * bsd_decomp_alloc(options, opt_len) u_char *options; int opt_len; { return bsd_alloc(options, opt_len, 1); } /* * Initialize the database. */ static int bsd_init(db, options, opt_len, unit, hdrlen, mru, debug, decomp) struct bsd_db *db; u_char *options; int opt_len, unit, hdrlen, mru, debug, decomp; { int i; if (opt_len < CILEN_BSD_COMPRESS || options[0] != CI_BSD_COMPRESS || options[1] != CILEN_BSD_COMPRESS || BSD_VERSION(options[2]) != BSD_CURRENT_VERSION || BSD_NBITS(options[2]) != db->maxbits || decomp && db->lens == NULL) return 0; if (decomp) { i = LAST+1; while (i != 0) db->lens[--i] = 1; } i = db->hsize; while (i != 0) { db->dict[--i].codem1 = BADCODEM1; db->dict[i].cptr = 0; } db->unit = unit; db->hdrlen = hdrlen; db->mru = mru; if (debug) db->debug = 1; bsd_reset(db); return 1; } static int bsd_comp_init(state, options, opt_len, unit, hdrlen, debug) void *state; u_char *options; int opt_len, unit, hdrlen, debug; { return bsd_init((struct bsd_db *) state, options, opt_len, unit, hdrlen, 0, debug, 0); } static int bsd_decomp_init(state, options, opt_len, unit, hdrlen, mru, debug) void *state; u_char *options; int opt_len, unit, hdrlen, mru, debug; { return bsd_init((struct bsd_db *) state, options, opt_len, unit, hdrlen, mru, debug, 1); } /* * compress a packet * One change from the BSD compress command is that when the * code size expands, we do not output a bunch of padding. * * N.B. at present, we ignore the hdrlen specified in the comp_init call. */ static int /* new slen */ bsd_compress(state, mretp, mp, slen, maxolen) void *state; mblk_t **mretp; /* return compressed mbuf chain here */ mblk_t *mp; /* from here */ int slen; /* uncompressed length */ int maxolen; /* max compressed length */ { struct bsd_db *db = (struct bsd_db *) state; int hshift = db->hshift; u_int max_ent = db->max_ent; u_int n_bits = db->n_bits; u_int bitno = 32; u_int32_t accm = 0, fcode; struct bsd_dict *dictp; u_char c; int hval, disp, ent, ilen; mblk_t *np, *mret; u_char *rptr, *wptr; u_char *cp_end; int olen; mblk_t *m, **mnp; #define PUTBYTE(v) { \ if (wptr) { \ *wptr++ = (v); \ if (wptr >= cp_end) { \ m->b_wptr = wptr; \ m = m->b_cont; \ if (m) { \ wptr = m->b_wptr; \ cp_end = m->b_datap->db_lim; \ } else \ wptr = NULL; \ } \ } \ ++olen; \ } #define OUTPUT(ent) { \ bitno -= n_bits; \ accm |= ((ent) << bitno); \ do { \ PUTBYTE(accm >> 24); \ accm <<= 8; \ bitno += 8; \ } while (bitno <= 24); \ } /* * First get the protocol and check that we're * interested in this packet. */ *mretp = NULL; rptr = mp->b_rptr; if (rptr + PPP_HDRLEN > mp->b_wptr) { if (!pullupmsg(mp, PPP_HDRLEN)) return 0; rptr = mp->b_rptr; } ent = PPP_PROTOCOL(rptr); /* get the protocol */ if (ent < 0x21 || ent > 0xf9) return 0; /* Don't generate compressed packets which are larger than the uncompressed packet. */ if (maxolen > slen) maxolen = slen; /* Allocate enough message blocks to give maxolen total space. */ mnp = &mret; for (olen = maxolen; olen > 0; ) { m = allocb((olen < 4096? olen: 4096), BPRI_MED); *mnp = m; if (m == NULL) { if (mret != NULL) { freemsg(mret); mnp = &mret; } break; } mnp = &m->b_cont; olen -= m->b_datap->db_lim - m->b_wptr; } *mnp = NULL; if ((m = mret) != NULL) { wptr = m->b_wptr; cp_end = m->b_datap->db_lim; } else wptr = cp_end = NULL; olen = 0; /* * Copy the PPP header over, changing the protocol, * and install the 2-byte sequence number. */ if (wptr) { wptr[0] = PPP_ADDRESS(rptr); wptr[1] = PPP_CONTROL(rptr); wptr[2] = 0; /* change the protocol */ wptr[3] = PPP_COMP; wptr[4] = db->seqno >> 8; wptr[5] = db->seqno; wptr += PPP_HDRLEN + BSD_OVHD; } ++db->seqno; rptr += PPP_HDRLEN; slen = mp->b_wptr - rptr; ilen = slen + 1; np = mp->b_cont; for (;;) { if (slen <= 0) { if (!np) break; rptr = np->b_rptr; slen = np->b_wptr - rptr; np = np->b_cont; if (!slen) continue; /* handle 0-length buffers */ ilen += slen; } slen--; c = *rptr++; fcode = BSD_KEY(ent, c); hval = BSD_HASH(ent, c, hshift); dictp = &db->dict[hval]; /* Validate and then check the entry. */ if (dictp->codem1 >= max_ent) goto nomatch; if (dictp->f.fcode == fcode) { ent = dictp->codem1+1; continue; /* found (prefix,suffix) */ } /* continue probing until a match or invalid entry */ disp = (hval == 0) ? 1 : hval; do { hval += disp; if (hval >= db->hsize) hval -= db->hsize; dictp = &db->dict[hval]; if (dictp->codem1 >= max_ent) goto nomatch; } while (dictp->f.fcode != fcode); ent = dictp->codem1 + 1; /* finally found (prefix,suffix) */ continue; nomatch: OUTPUT(ent); /* output the prefix */ /* code -> hashtable */ if (max_ent < db->maxmaxcode) { struct bsd_dict *dictp2; /* expand code size if needed */ if (max_ent >= MAXCODE(n_bits)) db->n_bits = ++n_bits; /* Invalidate old hash table entry using * this code, and then take it over. */ dictp2 = &db->dict[max_ent+1]; if (db->dict[dictp2->cptr].codem1 == max_ent) db->dict[dictp2->cptr].codem1 = BADCODEM1; dictp2->cptr = hval; dictp->codem1 = max_ent; dictp->f.fcode = fcode; db->max_ent = ++max_ent; } ent = c; } OUTPUT(ent); /* output the last code */ db->bytes_out += olen; db->in_count += ilen; if (bitno < 32) ++db->bytes_out; /* count complete bytes */ if (bsd_check(db)) OUTPUT(CLEAR); /* do not count the CLEAR */ /* * Pad dribble bits of last code with ones. * Do not emit a completely useless byte of ones. */ if (bitno != 32) PUTBYTE((accm | (0xff << (bitno-8))) >> 24); /* * Increase code size if we would have without the packet * boundary and as the decompressor will. */ if (max_ent >= MAXCODE(n_bits) && max_ent < db->maxmaxcode) db->n_bits++; db->uncomp_bytes += ilen; ++db->uncomp_count; if (olen + PPP_HDRLEN + BSD_OVHD > maxolen && mret != NULL) { /* throw away the compressed stuff if it is longer than uncompressed */ freemsg(mret); mret = NULL; ++db->incomp_count; db->incomp_bytes += ilen; } else if (wptr != NULL) { m->b_wptr = wptr; if (m->b_cont) { freemsg(m->b_cont); m->b_cont = NULL; } ++db->comp_count; db->comp_bytes += olen + BSD_OVHD; } *mretp = mret; return olen + PPP_HDRLEN + BSD_OVHD; #undef OUTPUT #undef PUTBYTE } /* * Update the "BSD Compress" dictionary on the receiver for * incompressible data by pretending to compress the incoming data. */ static void bsd_incomp(state, dmsg) void *state; mblk_t *dmsg; { struct bsd_db *db = (struct bsd_db *) state; u_int hshift = db->hshift; u_int max_ent = db->max_ent; u_int n_bits = db->n_bits; struct bsd_dict *dictp; u_int32_t fcode; u_char c; long hval, disp; int slen, ilen; u_int bitno = 7; u_char *rptr; u_int ent; rptr = dmsg->b_rptr; if (rptr + PPP_HDRLEN > dmsg->b_wptr) { if (!pullupmsg(dmsg, PPP_HDRLEN)) return; rptr = dmsg->b_rptr; } ent = PPP_PROTOCOL(rptr); /* get the protocol */ if (ent < 0x21 || ent > 0xf9) return; db->seqno++; ilen = 1; /* count the protocol as 1 byte */ rptr += PPP_HDRLEN; for (;;) { slen = dmsg->b_wptr - rptr; if (slen <= 0) { dmsg = dmsg->b_cont; if (!dmsg) break; rptr = dmsg->b_rptr; continue; /* skip zero-length buffers */ } ilen += slen; do { c = *rptr++; fcode = BSD_KEY(ent, c); hval = BSD_HASH(ent, c, hshift); dictp = &db->dict[hval]; /* validate and then check the entry */ if (dictp->codem1 >= max_ent) goto nomatch; if (dictp->f.fcode == fcode) { ent = dictp->codem1+1; continue; /* found (prefix,suffix) */ } /* continue probing until a match or invalid entry */ disp = (hval == 0) ? 1 : hval; do { hval += disp; if (hval >= db->hsize) hval -= db->hsize; dictp = &db->dict[hval]; if (dictp->codem1 >= max_ent) goto nomatch; } while (dictp->f.fcode != fcode); ent = dictp->codem1+1; continue; /* finally found (prefix,suffix) */ nomatch: /* output (count) the prefix */ bitno += n_bits; /* code -> hashtable */ if (max_ent < db->maxmaxcode) { struct bsd_dict *dictp2; /* expand code size if needed */ if (max_ent >= MAXCODE(n_bits)) db->n_bits = ++n_bits; /* Invalidate previous hash table entry * assigned this code, and then take it over. */ dictp2 = &db->dict[max_ent+1]; if (db->dict[dictp2->cptr].codem1 == max_ent) db->dict[dictp2->cptr].codem1 = BADCODEM1; dictp2->cptr = hval; dictp->codem1 = max_ent; dictp->f.fcode = fcode; db->max_ent = ++max_ent; db->lens[max_ent] = db->lens[ent]+1; } ent = c; } while (--slen != 0); } bitno += n_bits; /* output (count) the last code */ db->bytes_out += bitno/8; db->in_count += ilen; (void)bsd_check(db); ++db->incomp_count; db->incomp_bytes += ilen; ++db->uncomp_count; db->uncomp_bytes += ilen; /* Increase code size if we would have without the packet * boundary and as the decompressor will. */ if (max_ent >= MAXCODE(n_bits) && max_ent < db->maxmaxcode) db->n_bits++; } /* * Decompress "BSD Compress" * * Because of patent problems, we return DECOMP_ERROR for errors * found by inspecting the input data and for system problems, but * DECOMP_FATALERROR for any errors which could possibly be said to * be being detected "after" decompression. For DECOMP_ERROR, * we can issue a CCP reset-request; for DECOMP_FATALERROR, we may be * infringing a patent of Motorola's if we do, so we take CCP down * instead. * * Given that the frame has the correct sequence number and a good FCS, * errors such as invalid codes in the input most likely indicate a * bug, so we return DECOMP_FATALERROR for them in order to turn off * compression, even though they are detected by inspecting the input. */ static int bsd_decompress(state, cmsg, dmpp) void *state; mblk_t *cmsg, **dmpp; { struct bsd_db *db = (struct bsd_db *) state; u_int max_ent = db->max_ent; u_int32_t accm = 0; u_int bitno = 32; /* 1st valid bit in accm */ u_int n_bits = db->n_bits; u_int tgtbitno = 32-n_bits; /* bitno when we have a code */ struct bsd_dict *dictp; int explen, i, seq, len; u_int incode, oldcode, finchar; u_char *p, *rptr, *wptr; mblk_t *dmsg, *mret; int adrs, ctrl, ilen; int dlen, space, codelen, extra; /* * Get at least the BSD Compress header in the first buffer */ rptr = cmsg->b_rptr; if (rptr + PPP_HDRLEN + BSD_OVHD >= cmsg->b_wptr) { if (!pullupmsg(cmsg, PPP_HDRLEN + BSD_OVHD + 1)) { if (db->debug) printf("bsd_decomp%d: failed to pullup\n", db->unit); return DECOMP_ERROR; } rptr = cmsg->b_rptr; } /* * Save the address/control from the PPP header * and then get the sequence number. */ adrs = PPP_ADDRESS(rptr); ctrl = PPP_CONTROL(rptr); rptr += PPP_HDRLEN; seq = (rptr[0] << 8) + rptr[1]; rptr += BSD_OVHD; ilen = len = cmsg->b_wptr - rptr; /* * Check the sequence number and give up if it is not what we expect. */ if (seq != db->seqno++) { if (db->debug) printf("bsd_decomp%d: bad sequence # %d, expected %d\n", db->unit, seq, db->seqno - 1); return DECOMP_ERROR; } /* * Allocate one message block to start with. */ if ((dmsg = allocb(DECOMP_CHUNK + db->hdrlen, BPRI_MED)) == NULL) return DECOMP_ERROR; mret = dmsg; dmsg->b_wptr += db->hdrlen; dmsg->b_rptr = wptr = dmsg->b_wptr; /* Fill in the ppp header, but not the last byte of the protocol (that comes from the decompressed data). */ wptr[0] = adrs; wptr[1] = ctrl; wptr[2] = 0; wptr += PPP_HDRLEN - 1; space = dmsg->b_datap->db_lim - wptr; oldcode = CLEAR; explen = 0; for (;;) { if (len == 0) { cmsg = cmsg->b_cont; if (!cmsg) /* quit at end of message */ break; rptr = cmsg->b_rptr; len = cmsg->b_wptr - rptr; ilen += len; continue; /* handle 0-length buffers */ } /* * Accumulate bytes until we have a complete code. * Then get the next code, relying on the 32-bit, * unsigned accm to mask the result. */ bitno -= 8; accm |= *rptr++ << bitno; --len; if (tgtbitno < bitno) continue; incode = accm >> tgtbitno; accm <<= n_bits; bitno += n_bits; if (incode == CLEAR) { /* * The dictionary must only be cleared at * the end of a packet. But there could be an * empty message block at the end. */ if (len > 0 || cmsg->b_cont != 0) { if (cmsg->b_cont) len += msgdsize(cmsg->b_cont); if (len > 0) { freemsg(dmsg); if (db->debug) printf("bsd_decomp%d: bad CLEAR\n", db->unit); return DECOMP_FATALERROR; } } bsd_clear(db); explen = ilen = 0; break; } if (incode > max_ent + 2 || incode > db->maxmaxcode || incode > max_ent && oldcode == CLEAR) { freemsg(dmsg); if (db->debug) { printf("bsd_decomp%d: bad code 0x%x oldcode=0x%x ", db->unit, incode, oldcode); printf("max_ent=0x%x dlen=%d seqno=%d\n", max_ent, dlen, db->seqno); } return DECOMP_FATALERROR; /* probably a bug */ } /* Special case for KwKwK string. */ if (incode > max_ent) { finchar = oldcode; extra = 1; } else { finchar = incode; extra = 0; } codelen = db->lens[finchar]; explen += codelen + extra; if (explen > db->mru + 1) { freemsg(dmsg); if (db->debug) printf("bsd_decomp%d: ran out of mru\n", db->unit); return DECOMP_FATALERROR; } /* * Decode this code and install it in the decompressed buffer. */ space -= codelen + extra; if (space < 0) { /* Allocate another message block. */ dmsg->b_wptr = wptr; dlen = codelen + extra; if (dlen < DECOMP_CHUNK) dlen = DECOMP_CHUNK; if ((dmsg->b_cont = allocb(dlen, BPRI_MED)) == NULL) { freemsg(dmsg); return DECOMP_ERROR; } dmsg = dmsg->b_cont; wptr = dmsg->b_wptr; space = dmsg->b_datap->db_lim - wptr - codelen - extra; } p = (wptr += codelen); while (finchar > LAST) { dictp = &db->dict[db->dict[finchar].cptr]; #ifdef DEBUG --codelen; if (codelen <= 0) { freemsg(dmsg); printf("bsd_decomp%d: fell off end of chain ", db->unit); printf("0x%x at 0x%x by 0x%x, max_ent=0x%x\n", incode, finchar, db->dict[finchar].cptr, max_ent); return DECOMP_FATALERROR; } if (dictp->codem1 != finchar-1) { freemsg(dmsg); printf("bsd_decomp%d: bad code chain 0x%x finchar=0x%x ", db->unit, incode, finchar); printf("oldcode=0x%x cptr=0x%x codem1=0x%x\n", oldcode, db->dict[finchar].cptr, dictp->codem1); return DECOMP_FATALERROR; } #endif *--p = dictp->f.hs.suffix; finchar = dictp->f.hs.prefix; } *--p = finchar; #ifdef DEBUG if (--codelen != 0) printf("bsd_decomp%d: short by %d after code 0x%x, max_ent=0x%x\n", db->unit, codelen, incode, max_ent); #endif if (extra) /* the KwKwK case again */ *wptr++ = finchar; /* * If not first code in a packet, and * if not out of code space, then allocate a new code. * * Keep the hash table correct so it can be used * with uncompressed packets. */ if (oldcode != CLEAR && max_ent < db->maxmaxcode) { struct bsd_dict *dictp2; u_int32_t fcode; int hval, disp; fcode = BSD_KEY(oldcode,finchar); hval = BSD_HASH(oldcode,finchar,db->hshift); dictp = &db->dict[hval]; /* look for a free hash table entry */ if (dictp->codem1 < max_ent) { disp = (hval == 0) ? 1 : hval; do { hval += disp; if (hval >= db->hsize) hval -= db->hsize; dictp = &db->dict[hval]; } while (dictp->codem1 < max_ent); } /* * Invalidate previous hash table entry * assigned this code, and then take it over */ dictp2 = &db->dict[max_ent+1]; if (db->dict[dictp2->cptr].codem1 == max_ent) { db->dict[dictp2->cptr].codem1 = BADCODEM1; } dictp2->cptr = hval; dictp->codem1 = max_ent; dictp->f.fcode = fcode; db->max_ent = ++max_ent; db->lens[max_ent] = db->lens[oldcode]+1; /* Expand code size if needed. */ if (max_ent >= MAXCODE(n_bits) && max_ent < db->maxmaxcode) { db->n_bits = ++n_bits; tgtbitno = 32-n_bits; } } oldcode = incode; } dmsg->b_wptr = wptr; /* * Keep the checkpoint right so that incompressible packets * clear the dictionary at the right times. */ db->bytes_out += ilen; db->in_count += explen; if (bsd_check(db) && db->debug) { printf("bsd_decomp%d: peer should have cleared dictionary\n", db->unit); } ++db->comp_count; db->comp_bytes += ilen + BSD_OVHD; ++db->uncomp_count; db->uncomp_bytes += explen; *dmpp = mret; return DECOMP_OK; } #endif /* DO_BSD_COMPRESS */ ppp-2.5.0/modules/deflate.c0000664000175000017500000004716413772531411012500 00000000000000/* * ppp_deflate.c - interface the zlib procedures for Deflate compression * and decompression (as used by gzip) to the PPP code. * This version is for use with STREAMS under SunOS 4.x, Solaris 2, * SVR4, OSF/1 and AIX 4.x. * * Copyright (c) 1994 Paul Mackerras. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The name(s) of the authors of this software must not be used to * endorse or promote products derived from this software without * prior written permission. * * 4. Redistributions of any form whatsoever must retain the following * acknowledgment: * "This product includes software developed by Paul Mackerras * ". * * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * $Id: deflate.c,v 1.12 2004/01/17 05:47:55 carlsonj Exp $ */ #ifdef AIX4 #include #endif #include #include #include #include #include "ppp_mod.h" #define PACKETPTR mblk_t * #include #ifdef __osf__ #include "zlib.h" #else #include "../common/zlib.h" #endif #ifdef SOL2 #include #endif #if DO_DEFLATE #define DEFLATE_DEBUG 1 /* * State for a Deflate (de)compressor. */ struct deflate_state { int seqno; int w_size; int unit; int hdrlen; int mru; int debug; z_stream strm; struct compstat stats; }; #define DEFLATE_OVHD 2 /* Deflate overhead/packet */ static void *z_alloc(void *, u_int items, u_int size); static void *z_alloc_init(void *, u_int items, u_int size); static void z_free(void *, void *ptr); static void *z_comp_alloc(u_char *options, int opt_len); static void *z_decomp_alloc(u_char *options, int opt_len); static void z_comp_free(void *state); static void z_decomp_free(void *state); static int z_comp_init(void *state, u_char *options, int opt_len, int unit, int hdrlen, int debug); static int z_decomp_init(void *state, u_char *options, int opt_len, int unit, int hdrlen, int mru, int debug); static int z_compress(void *state, mblk_t **mret, mblk_t *mp, int slen, int maxolen); static void z_incomp(void *state, mblk_t *dmsg); static int z_decompress(void *state, mblk_t *cmp, mblk_t **dmpp); static void z_comp_reset(void *state); static void z_decomp_reset(void *state); static void z_comp_stats(void *state, struct compstat *stats); /* * Procedures exported to ppp_comp.c. */ struct compressor ppp_deflate = { CI_DEFLATE, /* compress_proto */ z_comp_alloc, /* comp_alloc */ z_comp_free, /* comp_free */ z_comp_init, /* comp_init */ z_comp_reset, /* comp_reset */ z_compress, /* compress */ z_comp_stats, /* comp_stat */ z_decomp_alloc, /* decomp_alloc */ z_decomp_free, /* decomp_free */ z_decomp_init, /* decomp_init */ z_decomp_reset, /* decomp_reset */ z_decompress, /* decompress */ z_incomp, /* incomp */ z_comp_stats, /* decomp_stat */ }; struct compressor ppp_deflate_draft = { CI_DEFLATE_DRAFT, /* compress_proto */ z_comp_alloc, /* comp_alloc */ z_comp_free, /* comp_free */ z_comp_init, /* comp_init */ z_comp_reset, /* comp_reset */ z_compress, /* compress */ z_comp_stats, /* comp_stat */ z_decomp_alloc, /* decomp_alloc */ z_decomp_free, /* decomp_free */ z_decomp_init, /* decomp_init */ z_decomp_reset, /* decomp_reset */ z_decompress, /* decompress */ z_incomp, /* incomp */ z_comp_stats, /* decomp_stat */ }; #define DECOMP_CHUNK 512 /* * Space allocation and freeing routines for use by zlib routines. */ struct zchunk { u_int size; u_int guard; }; #define GUARD_MAGIC 0x77a6011a static void * z_alloc_init(notused, items, size) void *notused; u_int items, size; { struct zchunk *z; size = items * size + sizeof(struct zchunk); #ifdef __osf__ z = (struct zchunk *) ALLOC_SLEEP(size); #else z = (struct zchunk *) ALLOC_NOSLEEP(size); #endif z->size = size; z->guard = GUARD_MAGIC; return (void *) (z + 1); } static void * z_alloc(notused, items, size) void *notused; u_int items, size; { struct zchunk *z; size = items * size + sizeof(struct zchunk); z = (struct zchunk *) ALLOC_NOSLEEP(size); z->size = size; z->guard = GUARD_MAGIC; return (void *) (z + 1); } static void z_free(notused, ptr) void *notused; void *ptr; { struct zchunk *z = ((struct zchunk *) ptr) - 1; if (z->guard != GUARD_MAGIC) { printf("ppp: z_free of corrupted chunk at %x (%x, %x)\n", z, z->size, z->guard); return; } FREE(z, z->size); } /* * Allocate space for a compressor. */ static void * z_comp_alloc(options, opt_len) u_char *options; int opt_len; { struct deflate_state *state; int w_size; if (opt_len != CILEN_DEFLATE || (options[0] != CI_DEFLATE && options[0] != CI_DEFLATE_DRAFT) || options[1] != CILEN_DEFLATE || DEFLATE_METHOD(options[2]) != DEFLATE_METHOD_VAL || options[3] != DEFLATE_CHK_SEQUENCE) return NULL; w_size = DEFLATE_SIZE(options[2]); /* * N.B. the 9 below should be DEFLATE_MIN_SIZE (8), but using * 8 will cause kernel crashes because of a bug in zlib. */ if (w_size < 9 || w_size > DEFLATE_MAX_SIZE) return NULL; #ifdef __osf__ state = (struct deflate_state *) ALLOC_SLEEP(sizeof(*state)); #else state = (struct deflate_state *) ALLOC_NOSLEEP(sizeof(*state)); #endif if (state == NULL) return NULL; state->strm.next_in = NULL; state->strm.zalloc = (alloc_func) z_alloc_init; state->strm.zfree = (free_func) z_free; if (deflateInit2(&state->strm, Z_DEFAULT_COMPRESSION, DEFLATE_METHOD_VAL, -w_size, 8, Z_DEFAULT_STRATEGY) != Z_OK) { FREE(state, sizeof(*state)); return NULL; } state->strm.zalloc = (alloc_func) z_alloc; state->w_size = w_size; bzero(&state->stats, sizeof(state->stats)); return (void *) state; } static void z_comp_free(arg) void *arg; { struct deflate_state *state = (struct deflate_state *) arg; deflateEnd(&state->strm); FREE(state, sizeof(*state)); } static int z_comp_init(arg, options, opt_len, unit, hdrlen, debug) void *arg; u_char *options; int opt_len, unit, hdrlen, debug; { struct deflate_state *state = (struct deflate_state *) arg; if (opt_len < CILEN_DEFLATE || (options[0] != CI_DEFLATE && options[0] != CI_DEFLATE_DRAFT) || options[1] != CILEN_DEFLATE || DEFLATE_METHOD(options[2]) != DEFLATE_METHOD_VAL || DEFLATE_SIZE(options[2]) != state->w_size || options[3] != DEFLATE_CHK_SEQUENCE) return 0; state->seqno = 0; state->unit = unit; state->hdrlen = hdrlen; state->debug = debug; deflateReset(&state->strm); return 1; } static void z_comp_reset(arg) void *arg; { struct deflate_state *state = (struct deflate_state *) arg; state->seqno = 0; deflateReset(&state->strm); } static int z_compress(arg, mret, mp, orig_len, maxolen) void *arg; mblk_t **mret; /* compressed packet (out) */ mblk_t *mp; /* uncompressed packet (in) */ int orig_len, maxolen; { struct deflate_state *state = (struct deflate_state *) arg; u_char *rptr, *wptr; int proto, olen, wspace, r, flush; mblk_t *m; /* * Check that the protocol is in the range we handle. */ *mret = NULL; rptr = mp->b_rptr; if (rptr + PPP_HDRLEN > mp->b_wptr) { if (!pullupmsg(mp, PPP_HDRLEN)) return 0; rptr = mp->b_rptr; } proto = PPP_PROTOCOL(rptr); if (proto > 0x3fff || proto == 0xfd || proto == 0xfb) return orig_len; /* Allocate one mblk initially. */ if (maxolen > orig_len) maxolen = orig_len; if (maxolen <= PPP_HDRLEN + 2) { wspace = 0; m = NULL; } else { wspace = maxolen + state->hdrlen; if (wspace > 4096) wspace = 4096; m = allocb(wspace, BPRI_MED); } if (m != NULL) { *mret = m; if (state->hdrlen + PPP_HDRLEN + 2 < wspace) { m->b_rptr += state->hdrlen; m->b_wptr = m->b_rptr; wspace -= state->hdrlen; } wptr = m->b_wptr; /* * Copy over the PPP header and store the 2-byte sequence number. */ wptr[0] = PPP_ADDRESS(rptr); wptr[1] = PPP_CONTROL(rptr); wptr[2] = PPP_COMP >> 8; wptr[3] = PPP_COMP; wptr += PPP_HDRLEN; wptr[0] = state->seqno >> 8; wptr[1] = state->seqno; wptr += 2; state->strm.next_out = wptr; state->strm.avail_out = wspace - (PPP_HDRLEN + 2); } else { state->strm.next_out = NULL; state->strm.avail_out = 1000000; } ++state->seqno; rptr += (proto > 0xff)? 2: 3; /* skip 1st proto byte if 0 */ state->strm.next_in = rptr; state->strm.avail_in = mp->b_wptr - rptr; mp = mp->b_cont; flush = (mp == NULL)? Z_PACKET_FLUSH: Z_NO_FLUSH; olen = 0; for (;;) { r = deflate(&state->strm, flush); if (r != Z_OK) { printf("z_compress: deflate returned %d (%s)\n", r, (state->strm.msg? state->strm.msg: "")); break; } if (flush != Z_NO_FLUSH && state->strm.avail_out != 0) break; /* all done */ if (state->strm.avail_in == 0 && mp != NULL) { state->strm.next_in = mp->b_rptr; state->strm.avail_in = mp->b_wptr - mp->b_rptr; mp = mp->b_cont; if (mp == NULL) flush = Z_PACKET_FLUSH; } if (state->strm.avail_out == 0) { if (m != NULL) { m->b_wptr += wspace; olen += wspace; wspace = maxolen - olen; if (wspace <= 0) { wspace = 0; m->b_cont = NULL; } else { if (wspace < 32) wspace = 32; else if (wspace > 4096) wspace = 4096; m->b_cont = allocb(wspace, BPRI_MED); } m = m->b_cont; if (m != NULL) { state->strm.next_out = m->b_wptr; state->strm.avail_out = wspace; } } if (m == NULL) { state->strm.next_out = NULL; state->strm.avail_out = 1000000; } } } if (m != NULL) { m->b_wptr += wspace - state->strm.avail_out; olen += wspace - state->strm.avail_out; } /* * See if we managed to reduce the size of the packet. */ if (olen < orig_len && m != NULL) { state->stats.comp_bytes += olen; state->stats.comp_packets++; } else { if (*mret != NULL) { freemsg(*mret); *mret = NULL; } state->stats.inc_bytes += orig_len; state->stats.inc_packets++; olen = orig_len; } state->stats.unc_bytes += orig_len; state->stats.unc_packets++; return olen; } static void z_comp_stats(arg, stats) void *arg; struct compstat *stats; { struct deflate_state *state = (struct deflate_state *) arg; u_int out; *stats = state->stats; stats->ratio = stats->unc_bytes; out = stats->comp_bytes + stats->unc_bytes; if (stats->ratio <= 0x7ffffff) stats->ratio <<= 8; else out >>= 8; if (out != 0) stats->ratio /= out; } /* * Allocate space for a decompressor. */ static void * z_decomp_alloc(options, opt_len) u_char *options; int opt_len; { struct deflate_state *state; int w_size; if (opt_len != CILEN_DEFLATE || (options[0] != CI_DEFLATE && options[0] != CI_DEFLATE_DRAFT) || options[1] != CILEN_DEFLATE || DEFLATE_METHOD(options[2]) != DEFLATE_METHOD_VAL || options[3] != DEFLATE_CHK_SEQUENCE) return NULL; w_size = DEFLATE_SIZE(options[2]); /* * N.B. the 9 below should be DEFLATE_MIN_SIZE (8), but using * 8 will cause kernel crashes because of a bug in zlib. */ if (w_size < 9 || w_size > DEFLATE_MAX_SIZE) return NULL; #ifdef __osf__ state = (struct deflate_state *) ALLOC_SLEEP(sizeof(*state)); #else state = (struct deflate_state *) ALLOC_NOSLEEP(sizeof(*state)); #endif if (state == NULL) return NULL; state->strm.next_out = NULL; state->strm.zalloc = (alloc_func) z_alloc_init; state->strm.zfree = (free_func) z_free; if (inflateInit2(&state->strm, -w_size) != Z_OK) { FREE(state, sizeof(*state)); return NULL; } state->strm.zalloc = (alloc_func) z_alloc; state->w_size = w_size; bzero(&state->stats, sizeof(state->stats)); return (void *) state; } static void z_decomp_free(arg) void *arg; { struct deflate_state *state = (struct deflate_state *) arg; inflateEnd(&state->strm); FREE(state, sizeof(*state)); } static int z_decomp_init(arg, options, opt_len, unit, hdrlen, mru, debug) void *arg; u_char *options; int opt_len, unit, hdrlen, mru, debug; { struct deflate_state *state = (struct deflate_state *) arg; if (opt_len < CILEN_DEFLATE || (options[0] != CI_DEFLATE && options[0] != CI_DEFLATE_DRAFT) || options[1] != CILEN_DEFLATE || DEFLATE_METHOD(options[2]) != DEFLATE_METHOD_VAL || DEFLATE_SIZE(options[2]) != state->w_size || options[3] != DEFLATE_CHK_SEQUENCE) return 0; state->seqno = 0; state->unit = unit; state->hdrlen = hdrlen; state->debug = debug; state->mru = mru; inflateReset(&state->strm); return 1; } static void z_decomp_reset(arg) void *arg; { struct deflate_state *state = (struct deflate_state *) arg; state->seqno = 0; inflateReset(&state->strm); } /* * Decompress a Deflate-compressed packet. * * Because of patent problems, we return DECOMP_ERROR for errors * found by inspecting the input data and for system problems, but * DECOMP_FATALERROR for any errors which could possibly be said to * be being detected "after" decompression. For DECOMP_ERROR, * we can issue a CCP reset-request; for DECOMP_FATALERROR, we may be * infringing a patent of Motorola's if we do, so we take CCP down * instead. * * Given that the frame has the correct sequence number and a good FCS, * errors such as invalid codes in the input most likely indicate a * bug, so we return DECOMP_FATALERROR for them in order to turn off * compression, even though they are detected by inspecting the input. */ static int z_decompress(arg, mi, mop) void *arg; mblk_t *mi, **mop; { struct deflate_state *state = (struct deflate_state *) arg; mblk_t *mo, *mo_head; u_char *rptr, *wptr; int rlen, olen, ospace; int seq, i, flush, r, decode_proto; u_char hdr[PPP_HDRLEN + DEFLATE_OVHD]; *mop = NULL; rptr = mi->b_rptr; for (i = 0; i < PPP_HDRLEN + DEFLATE_OVHD; ++i) { while (rptr >= mi->b_wptr) { mi = mi->b_cont; if (mi == NULL) return DECOMP_ERROR; rptr = mi->b_rptr; } hdr[i] = *rptr++; } /* Check the sequence number. */ seq = (hdr[PPP_HDRLEN] << 8) + hdr[PPP_HDRLEN+1]; if (seq != state->seqno) { #if !DEFLATE_DEBUG if (state->debug) #endif printf("z_decompress%d: bad seq # %d, expected %d\n", state->unit, seq, state->seqno); return DECOMP_ERROR; } ++state->seqno; /* Allocate an output message block. */ mo = allocb(DECOMP_CHUNK + state->hdrlen, BPRI_MED); if (mo == NULL) return DECOMP_ERROR; mo_head = mo; mo->b_cont = NULL; mo->b_rptr += state->hdrlen; mo->b_wptr = wptr = mo->b_rptr; ospace = DECOMP_CHUNK; olen = 0; /* * Fill in the first part of the PPP header. The protocol field * comes from the decompressed data. */ wptr[0] = PPP_ADDRESS(hdr); wptr[1] = PPP_CONTROL(hdr); wptr[2] = 0; /* * Set up to call inflate. We set avail_out to 1 initially so we can * look at the first byte of the output and decide whether we have * a 1-byte or 2-byte protocol field. */ state->strm.next_in = rptr; state->strm.avail_in = mi->b_wptr - rptr; mi = mi->b_cont; flush = (mi == NULL)? Z_PACKET_FLUSH: Z_NO_FLUSH; rlen = state->strm.avail_in + PPP_HDRLEN + DEFLATE_OVHD; state->strm.next_out = wptr + 3; state->strm.avail_out = 1; decode_proto = 1; /* * Call inflate, supplying more input or output as needed. */ for (;;) { r = inflate(&state->strm, flush); if (r != Z_OK) { #if !DEFLATE_DEBUG if (state->debug) #endif printf("z_decompress%d: inflate returned %d (%s)\n", state->unit, r, (state->strm.msg? state->strm.msg: "")); freemsg(mo_head); return DECOMP_FATALERROR; } if (flush != Z_NO_FLUSH && state->strm.avail_out != 0) break; /* all done */ if (state->strm.avail_in == 0 && mi != NULL) { state->strm.next_in = mi->b_rptr; state->strm.avail_in = mi->b_wptr - mi->b_rptr; rlen += state->strm.avail_in; mi = mi->b_cont; if (mi == NULL) flush = Z_PACKET_FLUSH; } if (state->strm.avail_out == 0) { if (decode_proto) { state->strm.avail_out = ospace - PPP_HDRLEN; if ((wptr[3] & 1) == 0) { /* 2-byte protocol field */ wptr[2] = wptr[3]; --state->strm.next_out; ++state->strm.avail_out; } decode_proto = 0; } else { mo->b_wptr += ospace; olen += ospace; mo->b_cont = allocb(DECOMP_CHUNK, BPRI_MED); mo = mo->b_cont; if (mo == NULL) { freemsg(mo_head); return DECOMP_ERROR; } state->strm.next_out = mo->b_rptr; state->strm.avail_out = ospace = DECOMP_CHUNK; } } } if (decode_proto) { freemsg(mo_head); return DECOMP_ERROR; } mo->b_wptr += ospace - state->strm.avail_out; olen += ospace - state->strm.avail_out; #if DEFLATE_DEBUG if (olen > state->mru + PPP_HDRLEN) printf("ppp_deflate%d: exceeded mru (%d > %d)\n", state->unit, olen, state->mru + PPP_HDRLEN); #endif state->stats.unc_bytes += olen; state->stats.unc_packets++; state->stats.comp_bytes += rlen; state->stats.comp_packets++; *mop = mo_head; return DECOMP_OK; } /* * Incompressible data has arrived - add it to the history. */ static void z_incomp(arg, mi) void *arg; mblk_t *mi; { struct deflate_state *state = (struct deflate_state *) arg; u_char *rptr; int rlen, proto, r; /* * Check that the protocol is one we handle. */ rptr = mi->b_rptr; if (rptr + PPP_HDRLEN > mi->b_wptr) { if (!pullupmsg(mi, PPP_HDRLEN)) return; rptr = mi->b_rptr; } proto = PPP_PROTOCOL(rptr); if (proto > 0x3fff || proto == 0xfd || proto == 0xfb) return; ++state->seqno; /* * Iterate through the message blocks, adding the characters in them * to the decompressor's history. For the first block, we start * at the either the 1st or 2nd byte of the protocol field, * depending on whether the protocol value is compressible. */ rlen = mi->b_wptr - mi->b_rptr; state->strm.next_in = rptr + 3; state->strm.avail_in = rlen - 3; if (proto > 0xff) { --state->strm.next_in; ++state->strm.avail_in; } for (;;) { r = inflateIncomp(&state->strm); if (r != Z_OK) { /* gak! */ #if !DEFLATE_DEBUG if (state->debug) #endif printf("z_incomp%d: inflateIncomp returned %d (%s)\n", state->unit, r, (state->strm.msg? state->strm.msg: "")); return; } mi = mi->b_cont; if (mi == NULL) break; state->strm.next_in = mi->b_rptr; state->strm.avail_in = mi->b_wptr - mi->b_rptr; rlen += state->strm.avail_in; } /* * Update stats. */ state->stats.inc_bytes += rlen; state->stats.inc_packets++; state->stats.unc_bytes += rlen; state->stats.unc_packets++; } #endif /* DO_DEFLATE */ ppp-2.5.0/modules/if_ppp.c0000664000175000017500000004574413772531441012356 00000000000000/* * if_ppp.c - a network interface connected to a STREAMS module. * * Copyright (c) 1994 Paul Mackerras. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The name(s) of the authors of this software must not be used to * endorse or promote products derived from this software without * prior written permission. * * 4. Redistributions of any form whatsoever must retain the following * acknowledgment: * "This product includes software developed by Paul Mackerras * ". * * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * $Id: if_ppp.c,v 1.18 2002/12/06 09:49:15 paulus Exp $ */ /* * This file is used under SunOS 4 and Digital UNIX. * * This file provides the glue between PPP and IP. */ #define INET 1 #include #include #include #include #include #include #include #include #include #include #include #ifdef __osf__ #include #include #else #include #endif #include "ppp_mod.h" #include #ifdef SNIT_SUPPORT #include #include #include #endif #ifdef __osf__ #define SIOCSIFMTU SIOCSIPMTU #define SIOCGIFMTU SIOCRIPMTU #define IFA_ADDR(ifa) (*(ifa)->ifa_addr) #else #define IFA_ADDR(ifa) ((ifa)->ifa_addr) #endif #define ifr_mtu ifr_metric static int if_ppp_open(queue_t *, int, int, int); static int if_ppp_close(queue_t *, int); static int if_ppp_wput(queue_t *, mblk_t *); static int if_ppp_rput(queue_t *, mblk_t *); #define PPP_IF_ID 0x8021 static struct module_info minfo = { PPP_IF_ID, "if_ppp", 0, INFPSZ, 4096, 128 }; static struct qinit rinit = { if_ppp_rput, NULL, if_ppp_open, if_ppp_close, NULL, &minfo, NULL }; static struct qinit winit = { if_ppp_wput, NULL, NULL, NULL, NULL, &minfo, NULL }; struct streamtab if_pppinfo = { &rinit, &winit, NULL, NULL }; typedef struct if_ppp_state { int unit; queue_t *q; int flags; } if_ppp_t; /* Values for flags */ #define DBGLOG 1 static int if_ppp_count; /* Number of currently-active streams */ static int ppp_nalloc; /* Number of elements of ifs and states */ static struct ifnet **ifs; /* Array of pointers to interface structs */ static if_ppp_t **states; /* Array of pointers to state structs */ static int if_ppp_output(struct ifnet *, struct mbuf *, struct sockaddr *); static int if_ppp_ioctl(struct ifnet *, u_int, caddr_t); static struct mbuf *make_mbufs(mblk_t *, int); static mblk_t *make_message(struct mbuf *, int); #ifdef SNIT_SUPPORT /* Fake ether header for SNIT */ static struct ether_header snit_ehdr = {{0}, {0}, ETHERTYPE_IP}; #endif #ifndef __osf__ static void ppp_if_detach(struct ifnet *); /* * Detach all the interfaces before unloading. * Not sure this works. */ int if_ppp_unload() { int i; if (if_ppp_count > 0) return EBUSY; for (i = 0; i < ppp_nalloc; ++i) if (ifs[i] != 0) ppp_if_detach(ifs[i]); if (ifs) { FREE(ifs, ppp_nalloc * sizeof (struct ifnet *)); FREE(states, ppp_nalloc * sizeof (struct if_ppp_t *)); } ppp_nalloc = 0; return 0; } #endif /* __osf__ */ /* * STREAMS module entry points. */ static int if_ppp_open(q, dev, flag, sflag) queue_t *q; int dev; int flag, sflag; { if_ppp_t *sp; if (q->q_ptr == 0) { sp = (if_ppp_t *) ALLOC_SLEEP(sizeof (if_ppp_t)); if (sp == 0) return OPENFAIL; bzero(sp, sizeof (if_ppp_t)); q->q_ptr = (caddr_t) sp; WR(q)->q_ptr = (caddr_t) sp; sp->unit = -1; /* no interface unit attached at present */ sp->q = WR(q); sp->flags = 0; ++if_ppp_count; } return 0; } static int if_ppp_close(q, flag) queue_t *q; int flag; { if_ppp_t *sp; struct ifnet *ifp; sp = (if_ppp_t *) q->q_ptr; if (sp != 0) { if (sp->flags & DBGLOG) printf("if_ppp closed, q=%x sp=%x\n", q, sp); if (sp->unit >= 0) { if (sp->unit < ppp_nalloc) { states[sp->unit] = 0; ifp = ifs[sp->unit]; if (ifp != 0) ifp->if_flags &= ~(IFF_UP | IFF_RUNNING); #ifdef DEBUG } else { printf("if_ppp: unit %d nonexistent!\n", sp->unit); #endif } } FREE(sp, sizeof (if_ppp_t)); --if_ppp_count; } return 0; } static int if_ppp_wput(q, mp) queue_t *q; mblk_t *mp; { if_ppp_t *sp; struct iocblk *iop; int error, unit; struct ifnet *ifp; sp = (if_ppp_t *) q->q_ptr; switch (mp->b_datap->db_type) { case M_DATA: /* * Now why would we be getting data coming in here?? */ if (sp->flags & DBGLOG) printf("if_ppp: got M_DATA len=%d\n", msgdsize(mp)); freemsg(mp); break; case M_IOCTL: iop = (struct iocblk *) mp->b_rptr; error = EINVAL; if (sp->flags & DBGLOG) printf("if_ppp: got ioctl cmd=%x count=%d\n", iop->ioc_cmd, iop->ioc_count); switch (iop->ioc_cmd) { case PPPIO_NEWPPA: /* well almost */ if (iop->ioc_count != sizeof(int) || sp->unit >= 0) break; if ((error = NOTSUSER()) != 0) break; unit = *(int *)mp->b_cont->b_rptr; /* Check that this unit isn't already in use */ if (unit < ppp_nalloc && states[unit] != 0) { error = EADDRINUSE; break; } /* Extend ifs and states arrays if necessary. */ error = ENOSR; if (unit >= ppp_nalloc) { int newn; struct ifnet **newifs; if_ppp_t **newstates; newn = unit + 4; if (sp->flags & DBGLOG) printf("if_ppp: extending ifs to %d\n", newn); newifs = (struct ifnet **) ALLOC_NOSLEEP(newn * sizeof (struct ifnet *)); if (newifs == 0) break; bzero(newifs, newn * sizeof (struct ifnet *)); newstates = (if_ppp_t **) ALLOC_NOSLEEP(newn * sizeof (struct if_ppp_t *)); if (newstates == 0) { FREE(newifs, newn * sizeof (struct ifnet *)); break; } bzero(newstates, newn * sizeof (struct if_ppp_t *)); bcopy(ifs, newifs, ppp_nalloc * sizeof(struct ifnet *)); bcopy(states, newstates, ppp_nalloc * sizeof(if_ppp_t *)); if (ifs) { FREE(ifs, ppp_nalloc * sizeof(struct ifnet *)); FREE(states, ppp_nalloc * sizeof(if_ppp_t *)); } ifs = newifs; states = newstates; ppp_nalloc = newn; } /* Allocate a new ifnet struct if necessary. */ ifp = ifs[unit]; if (ifp == 0) { ifp = (struct ifnet *) ALLOC_NOSLEEP(sizeof (struct ifnet)); if (ifp == 0) break; bzero(ifp, sizeof (struct ifnet)); ifs[unit] = ifp; ifp->if_name = "ppp"; ifp->if_unit = unit; ifp->if_mtu = PPP_MTU; ifp->if_flags = IFF_POINTOPOINT | IFF_RUNNING; #ifndef __osf__ #ifdef IFF_MULTICAST ifp->if_flags |= IFF_MULTICAST; #endif #endif /* __osf__ */ ifp->if_output = if_ppp_output; #ifdef __osf__ ifp->if_version = "Point-to-Point Protocol, version 2.3.11"; ifp->if_mediamtu = PPP_MTU; ifp->if_type = IFT_PPP; ifp->if_hdrlen = PPP_HDRLEN; ifp->if_addrlen = 0; ifp->if_flags |= IFF_NOARP | IFF_SIMPLEX | IFF_NOTRAILERS; #ifdef IFF_VAR_MTU ifp->if_flags |= IFF_VAR_MTU; #endif #ifdef NETMASTERCPU ifp->if_affinity = NETMASTERCPU; #endif #endif ifp->if_ioctl = if_ppp_ioctl; ifp->if_snd.ifq_maxlen = IFQ_MAXLEN; if_attach(ifp); if (sp->flags & DBGLOG) printf("if_ppp: created unit %d\n", unit); } else { ifp->if_mtu = PPP_MTU; ifp->if_flags |= IFF_RUNNING; } states[unit] = sp; sp->unit = unit; error = 0; iop->ioc_count = 0; if (sp->flags & DBGLOG) printf("if_ppp: attached unit %d, sp=%x q=%x\n", unit, sp, sp->q); break; case PPPIO_DEBUG: error = -1; if (iop->ioc_count == sizeof(int)) { if (*(int *)mp->b_cont->b_rptr == PPPDBG_LOG + PPPDBG_IF) { printf("if_ppp: debug log enabled, q=%x sp=%x\n", q, sp); sp->flags |= DBGLOG; error = 0; iop->ioc_count = 0; } } break; default: error = -1; break; } if (sp->flags & DBGLOG) printf("if_ppp: ioctl result %d\n", error); if (error < 0) putnext(q, mp); else if (error == 0) { mp->b_datap->db_type = M_IOCACK; qreply(q, mp); } else { mp->b_datap->db_type = M_IOCNAK; iop->ioc_count = 0; iop->ioc_error = error; qreply(q, mp); } break; default: putnext(q, mp); } return 0; } static int if_ppp_rput(q, mp) queue_t *q; mblk_t *mp; { if_ppp_t *sp; int proto, s; struct mbuf *mb; struct ifqueue *inq; struct ifnet *ifp; int len; sp = (if_ppp_t *) q->q_ptr; switch (mp->b_datap->db_type) { case M_DATA: /* * Convert the message into an mbuf chain * and inject it into the network code. */ if (sp->flags & DBGLOG) printf("if_ppp: rput pkt len %d data %x %x %x %x %x %x %x %x\n", msgdsize(mp), mp->b_rptr[0], mp->b_rptr[1], mp->b_rptr[2], mp->b_rptr[3], mp->b_rptr[4], mp->b_rptr[5], mp->b_rptr[6], mp->b_rptr[7]); if (sp->unit < 0) { freemsg(mp); break; } if (sp->unit >= ppp_nalloc || (ifp = ifs[sp->unit]) == 0) { #ifdef DEBUG printf("if_ppp: no unit %d!\n", sp->unit); #endif freemsg(mp); break; } if ((ifp->if_flags & IFF_UP) == 0) { freemsg(mp); break; } ++ifp->if_ipackets; proto = PPP_PROTOCOL(mp->b_rptr); adjmsg(mp, PPP_HDRLEN); len = msgdsize(mp); mb = make_mbufs(mp, sizeof(struct ifnet *)); freemsg(mp); if (mb == NULL) { if (sp->flags & DBGLOG) printf("if_ppp%d: make_mbufs failed\n", ifp->if_unit); ++ifp->if_ierrors; break; } #ifdef SNIT_SUPPORT if (proto == PPP_IP && (ifp->if_flags & IFF_PROMISC)) { struct nit_if nif; nif.nif_header = (caddr_t) &snit_ehdr; nif.nif_hdrlen = sizeof(snit_ehdr); nif.nif_bodylen = len; nif.nif_promisc = 0; snit_intr(ifp, mb, &nif); } #endif /* * For Digital UNIX, there's space set aside in the header mbuf * for the interface info. * * For Sun it's smuggled around via a pointer at the front of the mbuf. */ #ifdef __osf__ mb->m_pkthdr.rcvif = ifp; mb->m_pkthdr.len = len; #else mb->m_off -= sizeof(struct ifnet *); mb->m_len += sizeof(struct ifnet *); *mtod(mb, struct ifnet **) = ifp; #endif inq = 0; switch (proto) { case PPP_IP: inq = &ipintrq; schednetisr(NETISR_IP); } if (inq != 0) { s = splhigh(); if (IF_QFULL(inq)) { IF_DROP(inq); ++ifp->if_ierrors; if (sp->flags & DBGLOG) printf("if_ppp: inq full, proto=%x\n", proto); m_freem(mb); } else { IF_ENQUEUE(inq, mb); } splx(s); } else { if (sp->flags & DBGLOG) printf("if_ppp%d: proto=%x?\n", ifp->if_unit, proto); ++ifp->if_ierrors; m_freem(mb); } break; default: putnext(q, mp); } return 0; } /* * Network code wants to output a packet. * Turn it into a STREAMS message and send it down. */ static int if_ppp_output(ifp, m0, dst) struct ifnet *ifp; struct mbuf *m0; struct sockaddr *dst; { mblk_t *mp; int proto, s; if_ppp_t *sp; u_char *p; if ((ifp->if_flags & IFF_UP) == 0) { m_freem(m0); return ENETDOWN; } if ((unsigned)ifp->if_unit >= ppp_nalloc) { #ifdef DEBUG printf("if_ppp_output: unit %d?\n", ifp->if_unit); #endif m_freem(m0); return EINVAL; } sp = states[ifp->if_unit]; if (sp == 0) { #ifdef DEBUG printf("if_ppp_output: no queue?\n"); #endif m_freem(m0); return ENETDOWN; } if (sp->flags & DBGLOG) { p = mtod(m0, u_char *); printf("if_ppp_output%d: af=%d data=%x %x %x %x %x %x %x %x q=%x\n", ifp->if_unit, dst->sa_family, p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7], sp->q); } switch (dst->sa_family) { case AF_INET: proto = PPP_IP; #ifdef SNIT_SUPPORT if (ifp->if_flags & IFF_PROMISC) { struct nit_if nif; struct mbuf *m; int len; for (len = 0, m = m0; m != NULL; m = m->m_next) len += m->m_len; nif.nif_header = (caddr_t) &snit_ehdr; nif.nif_hdrlen = sizeof(snit_ehdr); nif.nif_bodylen = len; nif.nif_promisc = 0; snit_intr(ifp, m0, &nif); } #endif break; default: m_freem(m0); return EAFNOSUPPORT; } ++ifp->if_opackets; mp = make_message(m0, PPP_HDRLEN); m_freem(m0); if (mp == 0) { ++ifp->if_oerrors; return ENOBUFS; } mp->b_rptr -= PPP_HDRLEN; mp->b_rptr[0] = PPP_ALLSTATIONS; mp->b_rptr[1] = PPP_UI; mp->b_rptr[2] = proto >> 8; mp->b_rptr[3] = proto; s = splstr(); if (sp->flags & DBGLOG) printf("if_ppp: putnext(%x, %x), r=%x w=%x p=%x\n", sp->q, mp, mp->b_rptr, mp->b_wptr, proto); putnext(sp->q, mp); splx(s); return 0; } /* * Socket ioctl routine for ppp interfaces. */ static int if_ppp_ioctl(ifp, cmd, data) struct ifnet *ifp; u_int cmd; caddr_t data; { int s, error; struct ifreq *ifr = (struct ifreq *) data; struct ifaddr *ifa = (struct ifaddr *) data; u_short mtu; error = 0; s = splimp(); switch (cmd) { case SIOCSIFFLAGS: if ((ifp->if_flags & IFF_RUNNING) == 0) ifp->if_flags &= ~IFF_UP; break; case SIOCSIFADDR: if (IFA_ADDR(ifa).sa_family != AF_INET) error = EAFNOSUPPORT; break; case SIOCSIFDSTADDR: if (IFA_ADDR(ifa).sa_family != AF_INET) error = EAFNOSUPPORT; break; case SIOCSIFMTU: if ((error = NOTSUSER()) != 0) break; #ifdef __osf__ /* this hack is necessary because ifioctl checks ifr_data * in 4.0 and 5.0, but ifr_data and ifr_metric overlay each * other in the definition of struct ifreq so pppd can't set both. */ bcopy(ifr->ifr_data, &mtu, sizeof (u_short)); ifr->ifr_mtu = mtu; #endif if (ifr->ifr_mtu < PPP_MINMTU || ifr->ifr_mtu > PPP_MAXMTU) { error = EINVAL; break; } ifp->if_mtu = ifr->ifr_mtu; break; case SIOCGIFMTU: ifr->ifr_mtu = ifp->if_mtu; break; case SIOCADDMULTI: case SIOCDELMULTI: switch(ifr->ifr_addr.sa_family) { case AF_INET: break; default: error = EAFNOSUPPORT; break; } break; default: error = EINVAL; } splx(s); return (error); } /* * Turn a STREAMS message into an mbuf chain. */ static struct mbuf * make_mbufs(mp, off) mblk_t *mp; int off; { struct mbuf *head, **prevp, *m; int len, space, n; unsigned char *cp, *dp; len = msgdsize(mp); if (len == 0) return 0; prevp = &head; space = 0; cp = mp->b_rptr; #ifdef __osf__ MGETHDR(m, M_DONTWAIT, MT_DATA); m->m_len = 0; space = MHLEN; *prevp = m; prevp = &m->m_next; dp = mtod(m, unsigned char *); len -= space; off = 0; #endif for (;;) { while (cp >= mp->b_wptr) { mp = mp->b_cont; if (mp == 0) { *prevp = 0; return head; } cp = mp->b_rptr; } n = mp->b_wptr - cp; if (space == 0) { MGET(m, M_DONTWAIT, MT_DATA); *prevp = m; if (m == 0) { if (head != 0) m_freem(head); return 0; } if (len + off > 2 * MLEN) { #ifdef __osf__ MCLGET(m, M_DONTWAIT); #else MCLGET(m); #endif } #ifdef __osf__ space = ((m->m_flags & M_EXT) ? MCLBYTES : MLEN); #else space = (m->m_off > MMAXOFF? MCLBYTES: MLEN) - off; m->m_off += off; #endif m->m_len = 0; len -= space; dp = mtod(m, unsigned char *); off = 0; prevp = &m->m_next; } if (n > space) n = space; bcopy(cp, dp, n); cp += n; dp += n; space -= n; m->m_len += n; } } /* * Turn an mbuf chain into a STREAMS message. */ #define ALLOCB_MAX 4096 static mblk_t * make_message(m, off) struct mbuf *m; int off; { mblk_t *head, **prevp, *mp; int len, space, n, nb; unsigned char *cp, *dp; struct mbuf *nm; len = 0; for (nm = m; nm != 0; nm = nm->m_next) len += nm->m_len; prevp = &head; space = 0; cp = mtod(m, unsigned char *); nb = m->m_len; for (;;) { while (nb <= 0) { m = m->m_next; if (m == 0) { *prevp = 0; return head; } cp = mtod(m, unsigned char *); nb = m->m_len; } if (space == 0) { space = len + off; if (space > ALLOCB_MAX) space = ALLOCB_MAX; mp = allocb(space, BPRI_LO); *prevp = mp; if (mp == 0) { if (head != 0) freemsg(head); return 0; } dp = mp->b_rptr += off; space -= off; len -= space; off = 0; prevp = &mp->b_cont; } n = nb < space? nb: space; bcopy(cp, dp, n); cp += n; dp += n; nb -= n; space -= n; mp->b_wptr = dp; } } /* * Digital UNIX doesn't allow for removing ifnet structures * from the list. But then we're not using this as a loadable * module anyway, so that's OK. * * Under SunOS, this should allow the module to be unloaded. * Unfortunately, it doesn't seem to detach all the references, * so your system may well crash after you unload this module :-( */ #ifndef __osf__ /* * Remove an interface from the system. * This routine contains magic. */ #include #include #include #include #include #include #include #include static void ppp_if_detach(ifp) struct ifnet *ifp; { int s; struct inpcb *pcb; struct ifaddr *ifa; struct in_ifaddr **inap; struct ifnet **ifpp; s = splhigh(); /* * Clear the interface from any routes currently cached in * TCP or UDP protocol control blocks. */ for (pcb = tcb.inp_next; pcb != &tcb; pcb = pcb->inp_next) if (pcb->inp_route.ro_rt && pcb->inp_route.ro_rt->rt_ifp == ifp) in_losing(pcb); for (pcb = udb.inp_next; pcb != &udb; pcb = pcb->inp_next) if (pcb->inp_route.ro_rt && pcb->inp_route.ro_rt->rt_ifp == ifp) in_losing(pcb); /* * Delete routes through all addresses of the interface. */ for (ifa = ifp->if_addrlist; ifa != 0; ifa = ifa->ifa_next) { rtinit(ifa, ifa, SIOCDELRT, RTF_HOST); rtinit(ifa, ifa, SIOCDELRT, 0); } /* * Unlink the interface's address(es) from the in_ifaddr list. */ for (inap = &in_ifaddr; *inap != 0; ) { if ((*inap)->ia_ifa.ifa_ifp == ifp) *inap = (*inap)->ia_next; else inap = &(*inap)->ia_next; } /* * Delete the interface from the ifnet list. */ for (ifpp = &ifnet; (*ifpp) != 0; ) { if (*ifpp == ifp) break; ifpp = &(*ifpp)->if_next; } if (*ifpp == 0) printf("couldn't find interface ppp%d in ifnet list\n", ifp->if_unit); else *ifpp = ifp->if_next; splx(s); } #endif /* __osf__ */ ppp-2.5.0/modules/ppp_ahdlc.c0000664000175000017500000005445413772531535013035 00000000000000/* * ppp_ahdlc.c - STREAMS module for doing PPP asynchronous HDLC. * * Re-written by Adi Masputra , based on * the original ppp_ahdlc.c * * Copyright (c) 2000 by Sun Microsystems, Inc. * All rights reserved. * * Permission to use, copy, modify, and distribute this software and its * documentation is hereby granted, provided that the above copyright * notice appears in all copies. * * SUN MAKES NO REPRESENTATION OR WARRANTIES ABOUT THE SUITABILITY OF * THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * PARTICULAR PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES * * Copyright (c) 1994 Paul Mackerras. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The name(s) of the authors of this software must not be used to * endorse or promote products derived from this software without * prior written permission. * * 4. Redistributions of any form whatsoever must retain the following * acknowledgment: * "This product includes software developed by Paul Mackerras * ". * * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * THE AUSTRALIAN NATIONAL UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS * ON AN "AS IS" BASIS, AND THE AUSTRALIAN NATIONAL UNIVERSITY HAS NO * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, * OR MODIFICATIONS. */ /* * This file is used under Solaris 2, SVR4, SunOS 4, and Digital UNIX. */ #include #include #include #include #ifdef SVR4 #include #include #include #include #else #include #ifdef __osf__ #include #endif #endif /* SVR4 */ #include #include #include "ppp_mod.h" /* * Right now, mutex is only enabled for Solaris 2.x */ #if defined(SOL2) #define USE_MUTEX #endif /* SOL2 */ /* * intpointer_t and uintpointer_t are signed and unsigned integer types * large enough to hold any data pointer; that is, data pointers can be * assigned into or from these integer types without losing precision. * On recent Solaris releases, these types are defined in sys/int_types.h, * but not on SunOS 4.x or the earlier Solaris versions. */ #if defined(_LP64) || defined(_I32LPx) typedef long intpointer_t; typedef unsigned long uintpointer_t; #else typedef int intpointer_t; typedef unsigned int uintpointer_t; #endif MOD_OPEN_DECL(ahdlc_open); MOD_CLOSE_DECL(ahdlc_close); static int ahdlc_wput(queue_t *, mblk_t *); static int ahdlc_rput(queue_t *, mblk_t *); static void ahdlc_encode(queue_t *, mblk_t *); static void ahdlc_decode(queue_t *, mblk_t *); static int msg_byte(mblk_t *, unsigned int); #if defined(SOL2) /* * Don't send HDLC start flag is last transmit is within 1.5 seconds - * FLAG_TIME is defined is microseconds */ #define FLAG_TIME 1500 #define ABS(x) (x >= 0 ? x : (-x)) #endif /* SOL2 */ /* * Extract byte i of message mp */ #define MSG_BYTE(mp, i) ((i) < (mp)->b_wptr - (mp)->b_rptr? (mp)->b_rptr[i]: \ msg_byte((mp), (i))) /* * Is this LCP packet one we have to transmit using LCP defaults? */ #define LCP_USE_DFLT(mp) (1 <= (code = MSG_BYTE((mp), 4)) && code <= 7) /* * Standard STREAMS declarations */ static struct module_info minfo = { 0x7d23, "ppp_ahdl", 0, INFPSZ, 32768, 512 }; static struct qinit rinit = { ahdlc_rput, NULL, ahdlc_open, ahdlc_close, NULL, &minfo, NULL }; static struct qinit winit = { ahdlc_wput, NULL, NULL, NULL, NULL, &minfo, NULL }; #if defined(SVR4) && !defined(SOL2) int phdldevflag = 0; #define ppp_ahdlcinfo phdlinfo #endif /* defined(SVR4) && !defined(SOL2) */ struct streamtab ppp_ahdlcinfo = { &rinit, /* ptr to st_rdinit */ &winit, /* ptr to st_wrinit */ NULL, /* ptr to st_muxrinit */ NULL, /* ptr to st_muxwinit */ #if defined(SUNOS4) NULL /* ptr to ptr to st_modlist */ #endif /* SUNOS4 */ }; #if defined(SUNOS4) int ppp_ahdlc_count = 0; /* open counter */ #endif /* SUNOS4 */ /* * Per-stream state structure */ typedef struct ahdlc_state { #if defined(USE_MUTEX) kmutex_t lock; /* lock for this structure */ #endif /* USE_MUTEX */ int flags; /* link flags */ mblk_t *rx_buf; /* ptr to receive buffer */ int rx_buf_size; /* receive buffer size */ ushort_t infcs; /* calculated rx HDLC FCS */ u_int32_t xaccm[8]; /* 256-bit xmit ACCM */ u_int32_t raccm; /* 32-bit rcv ACCM */ int mtu; /* interface MTU */ int mru; /* link MRU */ int unit; /* current PPP unit number */ struct pppstat stats; /* statistic structure */ #if defined(SOL2) clock_t flag_time; /* time in usec between flags */ clock_t lbolt; /* last updated lbolt */ #endif /* SOL2 */ } ahdlc_state_t; /* * Values for flags */ #define ESCAPED 0x100 /* last saw escape char on input */ #define IFLUSH 0x200 /* flushing input due to error */ /* * RCV_B7_1, etc., defined in net/pppio.h, are stored in flags also. */ #define RCV_FLAGS (RCV_B7_1|RCV_B7_0|RCV_ODDP|RCV_EVNP) /* * FCS lookup table as calculated by genfcstab. */ static u_short fcstab[256] = { 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf, 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7, 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e, 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876, 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd, 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5, 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c, 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974, 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb, 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3, 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a, 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72, 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9, 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1, 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738, 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70, 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7, 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff, 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036, 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e, 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5, 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd, 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134, 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c, 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3, 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb, 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232, 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a, 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1, 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9, 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330, 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78 }; static u_int32_t paritytab[8] = { 0x96696996, 0x69969669, 0x69969669, 0x96696996, 0x69969669, 0x96696996, 0x96696996, 0x69969669 }; /* * STREAMS module open (entry) point */ MOD_OPEN(ahdlc_open) { ahdlc_state_t *state; /* * Return if it's already opened */ if (q->q_ptr) { return 0; } /* * This can only be opened as a module */ if (sflag != MODOPEN) { return 0; } state = (ahdlc_state_t *) ALLOC_NOSLEEP(sizeof(ahdlc_state_t)); if (state == 0) OPEN_ERROR(ENOSR); bzero((caddr_t) state, sizeof(ahdlc_state_t)); q->q_ptr = (caddr_t) state; WR(q)->q_ptr = (caddr_t) state; #if defined(USE_MUTEX) mutex_init(&state->lock, NULL, MUTEX_DEFAULT, NULL); mutex_enter(&state->lock); #endif /* USE_MUTEX */ state->xaccm[0] = ~0; /* escape 0x00 through 0x1f */ state->xaccm[3] = 0x60000000; /* escape 0x7d and 0x7e */ state->mru = PPP_MRU; /* default of 1500 bytes */ #if defined(SOL2) state->flag_time = drv_usectohz(FLAG_TIME); #endif /* SOL2 */ #if defined(USE_MUTEX) mutex_exit(&state->lock); #endif /* USE_MUTEX */ #if defined(SUNOS4) ppp_ahdlc_count++; #endif /* SUNOS4 */ qprocson(q); return 0; } /* * STREAMS module close (exit) point */ MOD_CLOSE(ahdlc_close) { ahdlc_state_t *state; qprocsoff(q); state = (ahdlc_state_t *) q->q_ptr; if (state == 0) { DPRINT("state == 0 in ahdlc_close\n"); return 0; } #if defined(USE_MUTEX) mutex_enter(&state->lock); #endif /* USE_MUTEX */ if (state->rx_buf != 0) { freemsg(state->rx_buf); state->rx_buf = 0; } #if defined(USE_MUTEX) mutex_exit(&state->lock); mutex_destroy(&state->lock); #endif /* USE_MUTEX */ FREE(q->q_ptr, sizeof(ahdlc_state_t)); q->q_ptr = NULL; OTHERQ(q)->q_ptr = NULL; #if defined(SUNOS4) if (ppp_ahdlc_count) ppp_ahdlc_count--; #endif /* SUNOS4 */ return 0; } /* * Write side put routine */ static int ahdlc_wput(q, mp) queue_t *q; mblk_t *mp; { ahdlc_state_t *state; struct iocblk *iop; int error; mblk_t *np; struct ppp_stats *psp; state = (ahdlc_state_t *) q->q_ptr; if (state == 0) { DPRINT("state == 0 in ahdlc_wput\n"); freemsg(mp); return 0; } switch (mp->b_datap->db_type) { case M_DATA: /* * A data packet - do character-stuffing and FCS, and * send it onwards. */ ahdlc_encode(q, mp); freemsg(mp); break; case M_IOCTL: iop = (struct iocblk *) mp->b_rptr; error = EINVAL; switch (iop->ioc_cmd) { case PPPIO_XACCM: if ((iop->ioc_count < sizeof(u_int32_t)) || (iop->ioc_count > sizeof(ext_accm))) { break; } if (mp->b_cont == 0) { DPRINT1("ahdlc_wput/%d: PPPIO_XACCM b_cont = 0!\n", state->unit); break; } #if defined(USE_MUTEX) mutex_enter(&state->lock); #endif /* USE_MUTEX */ bcopy((caddr_t)mp->b_cont->b_rptr, (caddr_t)state->xaccm, iop->ioc_count); state->xaccm[2] &= ~0x40000000; /* don't escape 0x5e */ state->xaccm[3] |= 0x60000000; /* do escape 0x7d, 0x7e */ #if defined(USE_MUTEX) mutex_exit(&state->lock); #endif /* USE_MUTEX */ iop->ioc_count = 0; error = 0; break; case PPPIO_RACCM: if (iop->ioc_count != sizeof(u_int32_t)) break; if (mp->b_cont == 0) { DPRINT1("ahdlc_wput/%d: PPPIO_RACCM b_cont = 0!\n", state->unit); break; } #if defined(USE_MUTEX) mutex_enter(&state->lock); #endif /* USE_MUTEX */ bcopy((caddr_t)mp->b_cont->b_rptr, (caddr_t)&state->raccm, sizeof(u_int32_t)); #if defined(USE_MUTEX) mutex_exit(&state->lock); #endif /* USE_MUTEX */ iop->ioc_count = 0; error = 0; break; case PPPIO_GCLEAN: np = allocb(sizeof(int), BPRI_HI); if (np == 0) { error = ENOSR; break; } if (mp->b_cont != 0) freemsg(mp->b_cont); mp->b_cont = np; #if defined(USE_MUTEX) mutex_enter(&state->lock); #endif /* USE_MUTEX */ *(int *)np->b_wptr = state->flags & RCV_FLAGS; #if defined(USE_MUTEX) mutex_exit(&state->lock); #endif /* USE_MUTEX */ np->b_wptr += sizeof(int); iop->ioc_count = sizeof(int); error = 0; break; case PPPIO_GETSTAT: np = allocb(sizeof(struct ppp_stats), BPRI_HI); if (np == 0) { error = ENOSR; break; } if (mp->b_cont != 0) freemsg(mp->b_cont); mp->b_cont = np; psp = (struct ppp_stats *) np->b_wptr; np->b_wptr += sizeof(struct ppp_stats); bzero((caddr_t)psp, sizeof(struct ppp_stats)); psp->p = state->stats; iop->ioc_count = sizeof(struct ppp_stats); error = 0; break; case PPPIO_LASTMOD: /* we knew this anyway */ error = 0; break; default: error = -1; break; } if (error < 0) putnext(q, mp); else if (error == 0) { mp->b_datap->db_type = M_IOCACK; qreply(q, mp); } else { mp->b_datap->db_type = M_IOCNAK; iop->ioc_count = 0; iop->ioc_error = error; qreply(q, mp); } break; case M_CTL: switch (*mp->b_rptr) { case PPPCTL_MTU: #if defined(USE_MUTEX) mutex_enter(&state->lock); #endif /* USE_MUTEX */ state->mtu = ((unsigned short *)mp->b_rptr)[1]; #if defined(USE_MUTEX) mutex_exit(&state->lock); #endif /* USE_MUTEX */ freemsg(mp); break; case PPPCTL_MRU: #if defined(USE_MUTEX) mutex_enter(&state->lock); #endif /* USE_MUTEX */ state->mru = ((unsigned short *)mp->b_rptr)[1]; #if defined(USE_MUTEX) mutex_exit(&state->lock); #endif /* USE_MUTEX */ freemsg(mp); break; case PPPCTL_UNIT: #if defined(USE_MUTEX) mutex_enter(&state->lock); #endif /* USE_MUTEX */ state->unit = mp->b_rptr[1]; #if defined(USE_MUTEX) mutex_exit(&state->lock); #endif /* USE_MUTEX */ break; default: putnext(q, mp); } break; default: putnext(q, mp); } return 0; } /* * Read side put routine */ static int ahdlc_rput(q, mp) queue_t *q; mblk_t *mp; { ahdlc_state_t *state; state = (ahdlc_state_t *) q->q_ptr; if (state == 0) { DPRINT("state == 0 in ahdlc_rput\n"); freemsg(mp); return 0; } switch (mp->b_datap->db_type) { case M_DATA: ahdlc_decode(q, mp); break; case M_HANGUP: #if defined(USE_MUTEX) mutex_enter(&state->lock); #endif /* USE_MUTEX */ if (state->rx_buf != 0) { /* XXX would like to send this up for debugging */ freemsg(state->rx_buf); state->rx_buf = 0; } state->flags = IFLUSH; #if defined(USE_MUTEX) mutex_exit(&state->lock); #endif /* USE_MUTEX */ putnext(q, mp); break; default: putnext(q, mp); } return 0; } /* * Extract bit c from map m, to determine if c needs to be escaped */ #define IN_TX_MAP(c, m) ((m)[(c) >> 5] & (1 << ((c) & 0x1f))) static void ahdlc_encode(q, mp) queue_t *q; mblk_t *mp; { ahdlc_state_t *state; u_int32_t *xaccm, loc_xaccm[8]; ushort_t fcs; size_t outmp_len; mblk_t *outmp, *tmp; uchar_t *dp, fcs_val; int is_lcp, code; #if defined(SOL2) clock_t lbolt; #endif /* SOL2 */ if (msgdsize(mp) < 4) { return; } state = (ahdlc_state_t *)q->q_ptr; #if defined(USE_MUTEX) mutex_enter(&state->lock); #endif /* USE_MUTEX */ /* * Allocate an output buffer large enough to handle a case where all * characters need to be escaped */ outmp_len = (msgdsize(mp) << 1) + /* input block x 2 */ (sizeof(fcs) << 2) + /* HDLC FCS x 4 */ (sizeof(uchar_t) << 1); /* HDLC flags x 2 */ outmp = allocb(outmp_len, BPRI_MED); if (outmp == NULL) { state->stats.ppp_oerrors++; #if defined(USE_MUTEX) mutex_exit(&state->lock); #endif /* USE_MUTEX */ putctl1(RD(q)->q_next, M_CTL, PPPCTL_OERROR); return; } #if defined(SOL2) /* * Check if our last transmit happenned within flag_time, using * the system's LBOLT value in clock ticks */ if (drv_getparm(LBOLT, &lbolt) != -1) { if (ABS((clock_t)lbolt - state->lbolt) > state->flag_time) { *outmp->b_wptr++ = PPP_FLAG; } state->lbolt = lbolt; } else { *outmp->b_wptr++ = PPP_FLAG; } #else /* * If the driver below still has a message to process, skip the * HDLC flag, otherwise, put one in the beginning */ if (qsize(q->q_next) == 0) { *outmp->b_wptr++ = PPP_FLAG; } #endif /* * All control characters must be escaped for LCP packets with code * values between 1 (Conf-Req) and 7 (Code-Rej). */ is_lcp = ((MSG_BYTE(mp, 0) == PPP_ALLSTATIONS) && (MSG_BYTE(mp, 1) == PPP_UI) && (MSG_BYTE(mp, 2) == (PPP_LCP >> 8)) && (MSG_BYTE(mp, 3) == (PPP_LCP & 0xff)) && LCP_USE_DFLT(mp)); xaccm = state->xaccm; if (is_lcp) { bcopy((caddr_t)state->xaccm, (caddr_t)loc_xaccm, sizeof(loc_xaccm)); loc_xaccm[0] = ~0; /* force escape on 0x00 through 0x1f */ xaccm = loc_xaccm; } fcs = PPP_INITFCS; /* Initial FCS is 0xffff */ /* * Process this block and the rest (if any) attached to the this one */ for (tmp = mp; tmp; tmp = tmp->b_cont) { if (tmp->b_datap->db_type == M_DATA) { for (dp = tmp->b_rptr; dp < tmp->b_wptr; dp++) { fcs = PPP_FCS(fcs, *dp); if (IN_TX_MAP(*dp, xaccm)) { *outmp->b_wptr++ = PPP_ESCAPE; *outmp->b_wptr++ = *dp ^ PPP_TRANS; } else { *outmp->b_wptr++ = *dp; } } } else { continue; /* skip if db_type is something other than M_DATA */ } } /* * Append the HDLC FCS, making sure that escaping is done on any * necessary bytes */ fcs_val = (fcs ^ 0xffff) & 0xff; if (IN_TX_MAP(fcs_val, xaccm)) { *outmp->b_wptr++ = PPP_ESCAPE; *outmp->b_wptr++ = fcs_val ^ PPP_TRANS; } else { *outmp->b_wptr++ = fcs_val; } fcs_val = ((fcs ^ 0xffff) >> 8) & 0xff; if (IN_TX_MAP(fcs_val, xaccm)) { *outmp->b_wptr++ = PPP_ESCAPE; *outmp->b_wptr++ = fcs_val ^ PPP_TRANS; } else { *outmp->b_wptr++ = fcs_val; } /* * And finally, append the HDLC flag, and send it away */ *outmp->b_wptr++ = PPP_FLAG; state->stats.ppp_obytes += msgdsize(outmp); state->stats.ppp_opackets++; #if defined(USE_MUTEX) mutex_exit(&state->lock); #endif /* USE_MUTEX */ putnext(q, outmp); return; } /* * Checks the 32-bit receive ACCM to see if the byte needs un-escaping */ #define IN_RX_MAP(c, m) ((((unsigned int) (uchar_t) (c)) < 0x20) && \ (m) & (1 << (c))) /* * Process received characters. */ static void ahdlc_decode(q, mp) queue_t *q; mblk_t *mp; { ahdlc_state_t *state; mblk_t *om; uchar_t *dp; state = (ahdlc_state_t *) q->q_ptr; #if defined(USE_MUTEX) mutex_enter(&state->lock); #endif /* USE_MUTEX */ state->stats.ppp_ibytes += msgdsize(mp); for (; mp != 0; om = mp->b_cont, freeb(mp), mp = om) for (dp = mp->b_rptr; dp < mp->b_wptr; dp++) { /* * This should detect the lack of 8-bit communication channel * which is necessary for PPP to work. In addition, it also * checks on the parity. */ if (*dp & 0x80) state->flags |= RCV_B7_1; else state->flags |= RCV_B7_0; if (paritytab[*dp >> 5] & (1 << (*dp & 0x1f))) state->flags |= RCV_ODDP; else state->flags |= RCV_EVNP; /* * So we have a HDLC flag ... */ if (*dp == PPP_FLAG) { /* * If we think that it marks the beginning of the frame, * then continue to process the next octects */ if ((state->flags & IFLUSH) || (state->rx_buf == 0) || (msgdsize(state->rx_buf) == 0)) { state->flags &= ~IFLUSH; continue; } /* * We get here because the above condition isn't true, * in which case the HDLC flag was there to mark the end * of the frame (or so we think) */ om = state->rx_buf; if (state->infcs == PPP_GOODFCS) { state->stats.ppp_ipackets++; adjmsg(om, -PPP_FCSLEN); putnext(q, om); } else { DPRINT2("ppp%d: bad fcs (len=%d)\n", state->unit, msgdsize(state->rx_buf)); freemsg(state->rx_buf); state->flags &= ~(IFLUSH | ESCAPED); state->stats.ppp_ierrors++; putctl1(q->q_next, M_CTL, PPPCTL_IERROR); } state->rx_buf = 0; continue; } if (state->flags & IFLUSH) { continue; } /* * Allocate a receive buffer, large enough to store a frame (after * un-escaping) of at least 1500 octets. If MRU is negotiated to * be more than the default, then allocate that much. In addition, * we add an extra 32-bytes for a fudge factor */ if (state->rx_buf == 0) { state->rx_buf_size = (state->mru < PPP_MRU ? PPP_MRU : state->mru); state->rx_buf_size += (sizeof(u_int32_t) << 3); state->rx_buf = allocb(state->rx_buf_size, BPRI_MED); /* * If allocation fails, try again on the next frame */ if (state->rx_buf == 0) { state->flags |= IFLUSH; continue; } state->flags &= ~(IFLUSH | ESCAPED); state->infcs = PPP_INITFCS; } if (*dp == PPP_ESCAPE) { state->flags |= ESCAPED; continue; } /* * Make sure we un-escape the necessary characters, as well as the * ones in our receive async control character map */ if (state->flags & ESCAPED) { *dp ^= PPP_TRANS; state->flags &= ~ESCAPED; } else if (IN_RX_MAP(*dp, state->raccm)) continue; /* * Unless the peer lied to us about the negotiated MRU, we should * never get a frame which is too long. If it happens, toss it away * and grab the next incoming one */ if (msgdsize(state->rx_buf) < state->rx_buf_size) { state->infcs = PPP_FCS(state->infcs, *dp); *state->rx_buf->b_wptr++ = *dp; } else { DPRINT2("ppp%d: frame too long (%d)\n", state->unit, msgdsize(state->rx_buf)); freemsg(state->rx_buf); state->rx_buf = 0; state->flags |= IFLUSH; } } #if defined(USE_MUTEX) mutex_exit(&state->lock); #endif /* USE_MUTEX */ } static int msg_byte(mp, i) mblk_t *mp; unsigned int i; { while (mp != 0 && i >= mp->b_wptr - mp->b_rptr) mp = mp->b_cont; if (mp == 0) return -1; return mp->b_rptr[i]; } ppp-2.5.0/modules/ppp.c0000664000175000017500000017102313772531512011665 00000000000000/* * ppp.c - STREAMS multiplexing pseudo-device driver for PPP. * * Copyright (c) 1994 Paul Mackerras. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The name(s) of the authors of this software must not be used to * endorse or promote products derived from this software without * prior written permission. * * 4. Redistributions of any form whatsoever must retain the following * acknowledgment: * "This product includes software developed by Paul Mackerras * ". * * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /* * This file is used under Solaris 2, SVR4, SunOS 4, and Digital UNIX. */ #include #include #include #include #include #include #ifdef __osf__ #include #include #define queclass(mp) ((mp)->b_band & QPCTL) #else #include #endif #include #ifdef SVR4 #include #include #include #include #ifdef SOL2 #include #include #include #include #else #include #include #include #include #endif /* SOL2 */ #else /* not SVR4 */ #include #endif /* SVR4 */ #include #include #include "ppp_mod.h" /* * Modifications marked with #ifdef PRIOQ are for priority queueing of * interactive traffic, and are due to Marko Zec . */ #ifdef PRIOQ #endif /* PRIOQ */ #include /* leave this outside of PRIOQ for htons */ /* * The IP module may use this SAP value for IP packets. */ #ifndef ETHERTYPE_IP #define ETHERTYPE_IP 0x800 #endif #if !defined(ETHERTYPE_IPV6) #define ETHERTYPE_IPV6 0x86dd #endif /* !defined(ETHERTYPE_IPV6) */ #if !defined(ETHERTYPE_ALLSAP) && defined(SOL2) #define ETHERTYPE_ALLSAP 0 #endif /* !defined(ETHERTYPE_ALLSAP) && defined(SOL2) */ #if !defined(PPP_ALLSAP) && defined(SOL2) #define PPP_ALLSAP PPP_ALLSTATIONS #endif /* !defined(PPP_ALLSAP) && defined(SOL2) */ extern time_t time; #ifdef SOL2 /* * We use this reader-writer lock to ensure that the lower streams * stay connected to the upper streams while the lower-side put and * service procedures are running. Essentially it is an existence * lock for the upper stream associated with each lower stream. */ krwlock_t ppp_lower_lock; #define LOCK_LOWER_W rw_enter(&ppp_lower_lock, RW_WRITER) #define LOCK_LOWER_R rw_enter(&ppp_lower_lock, RW_READER) #define TRYLOCK_LOWER_R rw_tryenter(&ppp_lower_lock, RW_READER) #define UNLOCK_LOWER rw_exit(&ppp_lower_lock) #define MT_ENTER(x) mutex_enter(x) #define MT_EXIT(x) mutex_exit(x) /* * Notes on multithreaded implementation for Solaris 2: * * We use an inner perimeter around each queue pair and an outer * perimeter around the whole driver. The inner perimeter is * entered exclusively for all entry points (open, close, put, * service). The outer perimeter is entered exclusively for open * and close and shared for put and service. This is all done for * us by the streams framework. * * I used to think that the perimeters were entered for the lower * streams' put and service routines as well as for the upper streams'. * Because of problems experienced by people, and after reading the * documentation more closely, I now don't think that is true. So we * now use ppp_lower_lock to give us an existence guarantee on the * upper stream controlling each lower stream. * * Shared entry to the outer perimeter protects the existence of all * the upper streams and their upperstr_t structures, and guarantees * that the following fields of any upperstr_t won't change: * nextmn, next, nextppa. It guarantees that the lowerq field of an * upperstr_t won't go from non-zero to zero, that the global `ppas' * won't change and that the no lower stream will get unlinked. * * Shared (reader) access to ppa_lower_lock guarantees that no lower * stream will be unlinked and that the lowerq field of all upperstr_t * structures won't change. */ #else /* SOL2 */ #define LOCK_LOWER_W 0 #define LOCK_LOWER_R 0 #define TRYLOCK_LOWER_R 1 #define UNLOCK_LOWER 0 #define MT_ENTER(x) 0 #define MT_EXIT(x) 0 #endif /* SOL2 */ /* * Private information; one per upper stream. */ typedef struct upperstr { minor_t mn; /* minor device number */ struct upperstr *nextmn; /* next minor device */ queue_t *q; /* read q associated with this upper stream */ int flags; /* flag bits, see below */ int state; /* current DLPI state */ int sap; /* service access point */ int req_sap; /* which SAP the DLPI client requested */ struct upperstr *ppa; /* control stream for our ppa */ struct upperstr *next; /* next stream for this ppa */ uint ioc_id; /* last ioctl ID for this stream */ enum NPmode npmode; /* what to do with packets on this SAP */ unsigned char rblocked; /* flow control has blocked upper read strm */ /* N.B. rblocked is only changed by control stream's put/srv procs */ /* * There is exactly one control stream for each PPA. * The following fields are only used for control streams. */ int ppa_id; queue_t *lowerq; /* write queue attached below this PPA */ struct upperstr *nextppa; /* next control stream */ int mru; int mtu; struct pppstat stats; /* statistics */ time_t last_sent; /* time last NP packet sent */ time_t last_recv; /* time last NP packet rcvd */ #ifdef SOL2 kmutex_t stats_lock; /* lock for stats updates */ kstat_t *kstats; /* stats for netstat */ #endif /* SOL2 */ #ifdef LACHTCP int ifflags; char ifname[IFNAMSIZ]; struct ifstats ifstats; #endif /* LACHTCP */ } upperstr_t; /* Values for flags */ #define US_PRIV 1 /* stream was opened by superuser */ #define US_CONTROL 2 /* stream is a control stream */ #define US_BLOCKED 4 /* flow ctrl has blocked lower write stream */ #define US_LASTMOD 8 /* no PPP modules below us */ #define US_DBGLOG 0x10 /* log various occurrences */ #define US_RBLOCKED 0x20 /* flow ctrl has blocked upper read stream */ #if defined(SOL2) #if DL_CURRENT_VERSION >= 2 #define US_PROMISC 0x40 /* stream is promiscuous */ #endif /* DL_CURRENT_VERSION >= 2 */ #define US_RAWDATA 0x80 /* raw M_DATA, no DLPI header */ #endif /* defined(SOL2) */ #ifdef PRIOQ static u_char max_band=0; static u_char def_band=0; #define IPPORT_DEFAULT 65535 /* * Port priority table * Highest priority ports are listed first, lowest are listed last. * ICMP & packets using unlisted ports will be treated as "default". * If IPPORT_DEFAULT is not listed here, "default" packets will be * assigned lowest priority. * Each line should be terminated with "0". * Line containing only "0" marks the end of the list. */ static u_short prioq_table[]= { 113, 53, 0, 22, 23, 513, 517, 518, 0, 514, 21, 79, 111, 0, 25, 109, 110, 0, IPPORT_DEFAULT, 0, 20, 70, 80, 8001, 8008, 8080, 0, /* 8001,8008,8080 - common proxy ports */ 0 }; #endif /* PRIOQ */ static upperstr_t *minor_devs = NULL; static upperstr_t *ppas = NULL; #ifdef SVR4 static int pppopen(queue_t *, dev_t *, int, int, cred_t *); static int pppclose(queue_t *, int, cred_t *); #else static int pppopen(queue_t *, int, int, int); static int pppclose(queue_t *, int); #endif /* SVR4 */ static int pppurput(queue_t *, mblk_t *); static int pppuwput(queue_t *, mblk_t *); static int pppursrv(queue_t *); static int pppuwsrv(queue_t *); static int ppplrput(queue_t *, mblk_t *); static int ppplwput(queue_t *, mblk_t *); static int ppplrsrv(queue_t *); static int ppplwsrv(queue_t *); #ifndef NO_DLPI static void dlpi_request(queue_t *, mblk_t *, upperstr_t *); static void dlpi_error(queue_t *, upperstr_t *, int, int, int); static void dlpi_ok(queue_t *, int); #endif static int send_data(mblk_t *, upperstr_t *); static void new_ppa(queue_t *, mblk_t *); static void attach_ppa(queue_t *, mblk_t *); static void detach_ppa(queue_t *, mblk_t *); static void detach_lower(queue_t *, mblk_t *); static void debug_dump(queue_t *, mblk_t *); static upperstr_t *find_dest(upperstr_t *, int); #if defined(SOL2) static upperstr_t *find_promisc(upperstr_t *, int); static mblk_t *prepend_ether(upperstr_t *, mblk_t *, int); static mblk_t *prepend_udind(upperstr_t *, mblk_t *, int); static void promisc_sendup(upperstr_t *, mblk_t *, int, int); #endif /* defined(SOL2) */ static int putctl2(queue_t *, int, int, int); static int putctl4(queue_t *, int, int, int); static int pass_packet(upperstr_t *ppa, mblk_t *mp, int outbound); #ifdef FILTER_PACKETS static int ip_hard_filter(upperstr_t *ppa, mblk_t *mp, int outbound); #endif /* FILTER_PACKETS */ #define PPP_ID 0xb1a6 static struct module_info ppp_info = { #ifdef PRIOQ PPP_ID, "ppp", 0, 512, 512, 384 #else PPP_ID, "ppp", 0, 512, 512, 128 #endif /* PRIOQ */ }; static struct qinit pppurint = { pppurput, pppursrv, pppopen, pppclose, NULL, &ppp_info, NULL }; static struct qinit pppuwint = { pppuwput, pppuwsrv, NULL, NULL, NULL, &ppp_info, NULL }; static struct qinit ppplrint = { ppplrput, ppplrsrv, NULL, NULL, NULL, &ppp_info, NULL }; static struct qinit ppplwint = { ppplwput, ppplwsrv, NULL, NULL, NULL, &ppp_info, NULL }; #ifdef LACHTCP extern struct ifstats *ifstats; int pppdevflag = 0; #endif struct streamtab pppinfo = { &pppurint, &pppuwint, &ppplrint, &ppplwint }; int ppp_count; /* * How we maintain statistics. */ #ifdef SOL2 #define INCR_IPACKETS(ppa) \ if (ppa->kstats != 0) { \ KSTAT_NAMED_PTR(ppa->kstats)[0].value.ul++; \ } #define INCR_IERRORS(ppa) \ if (ppa->kstats != 0) { \ KSTAT_NAMED_PTR(ppa->kstats)[1].value.ul++; \ } #define INCR_OPACKETS(ppa) \ if (ppa->kstats != 0) { \ KSTAT_NAMED_PTR(ppa->kstats)[2].value.ul++; \ } #define INCR_OERRORS(ppa) \ if (ppa->kstats != 0) { \ KSTAT_NAMED_PTR(ppa->kstats)[3].value.ul++; \ } #endif #ifdef LACHTCP #define INCR_IPACKETS(ppa) ppa->ifstats.ifs_ipackets++; #define INCR_IERRORS(ppa) ppa->ifstats.ifs_ierrors++; #define INCR_OPACKETS(ppa) ppa->ifstats.ifs_opackets++; #define INCR_OERRORS(ppa) ppa->ifstats.ifs_oerrors++; #endif /* * STREAMS driver entry points. */ static int #ifdef SVR4 pppopen(q, devp, oflag, sflag, credp) queue_t *q; dev_t *devp; int oflag, sflag; cred_t *credp; #else pppopen(q, dev, oflag, sflag) queue_t *q; int dev; /* really dev_t */ int oflag, sflag; #endif { upperstr_t *up; upperstr_t **prevp; minor_t mn; #ifdef PRIOQ u_short *ptr; u_char new_band; #endif /* PRIOQ */ if (q->q_ptr) DRV_OPEN_OK(dev); /* device is already open */ #ifdef PRIOQ /* Calculate max_bband & def_band from definitions in prioq.h This colud be done at some more approtiate time (less often) but this way it works well so I'll just leave it here */ max_band = 1; def_band = 0; ptr = prioq_table; while (*ptr) { new_band = 1; while (*ptr) if (*ptr++ == IPPORT_DEFAULT) { new_band = 0; def_band = max_band; } max_band += new_band; ptr++; } if (def_band) def_band = max_band - def_band; --max_band; #endif /* PRIOQ */ if (sflag == CLONEOPEN) { mn = 0; for (prevp = &minor_devs; (up = *prevp) != 0; prevp = &up->nextmn) { if (up->mn != mn) break; ++mn; } } else { #ifdef SVR4 mn = getminor(*devp); #else mn = minor(dev); #endif for (prevp = &minor_devs; (up = *prevp) != 0; prevp = &up->nextmn) { if (up->mn >= mn) break; } if (up->mn == mn) { /* this can't happen */ q->q_ptr = WR(q)->q_ptr = (caddr_t) up; DRV_OPEN_OK(dev); } } /* * Construct a new minor node. */ up = (upperstr_t *) ALLOC_SLEEP(sizeof(upperstr_t)); bzero((caddr_t) up, sizeof(upperstr_t)); if (up == 0) { DPRINT("pppopen: out of kernel memory\n"); OPEN_ERROR(ENXIO); } up->nextmn = *prevp; *prevp = up; up->mn = mn; #ifdef SVR4 *devp = makedevice(getmajor(*devp), mn); #endif up->q = q; if (NOTSUSER() == 0) up->flags |= US_PRIV; #ifndef NO_DLPI up->state = DL_UNATTACHED; #endif #ifdef LACHTCP up->ifflags = IFF_UP | IFF_POINTOPOINT; #endif up->sap = -1; up->last_sent = up->last_recv = time; up->npmode = NPMODE_DROP; q->q_ptr = (caddr_t) up; WR(q)->q_ptr = (caddr_t) up; noenable(WR(q)); #ifdef SOL2 mutex_init(&up->stats_lock, NULL, MUTEX_DRIVER, NULL); #endif ++ppp_count; qprocson(q); DRV_OPEN_OK(makedev(major(dev), mn)); } static int #ifdef SVR4 pppclose(q, flag, credp) queue_t *q; int flag; cred_t *credp; #else pppclose(q, flag) queue_t *q; int flag; #endif { upperstr_t *up, **upp; upperstr_t *as, *asnext; upperstr_t **prevp; qprocsoff(q); up = (upperstr_t *) q->q_ptr; if (up == 0) { DPRINT("pppclose: q_ptr = 0\n"); return 0; } if (up->flags & US_DBGLOG) DPRINT2("ppp/%d: close, flags=%x\n", up->mn, up->flags); if (up->flags & US_CONTROL) { #ifdef LACHTCP struct ifstats *ifp, *pifp; #endif if (up->lowerq != 0) { /* Gack! the lower stream should have be unlinked earlier! */ DPRINT1("ppp%d: lower stream still connected on close?\n", up->mn); LOCK_LOWER_W; up->lowerq->q_ptr = 0; RD(up->lowerq)->q_ptr = 0; up->lowerq = 0; UNLOCK_LOWER; } /* * This stream represents a PPA: * For all streams attached to the PPA, clear their * references to this PPA. * Then remove this PPA from the list of PPAs. */ for (as = up->next; as != 0; as = asnext) { asnext = as->next; as->next = 0; as->ppa = 0; if (as->flags & US_BLOCKED) { as->flags &= ~US_BLOCKED; flushq(WR(as->q), FLUSHDATA); } } for (upp = &ppas; *upp != 0; upp = &(*upp)->nextppa) if (*upp == up) { *upp = up->nextppa; break; } #ifdef LACHTCP /* Remove the statistics from the active list. */ for (ifp = ifstats, pifp = 0; ifp; ifp = ifp->ifs_next) { if (ifp == &up->ifstats) { if (pifp) pifp->ifs_next = ifp->ifs_next; else ifstats = ifp->ifs_next; break; } pifp = ifp; } #endif } else { /* * If this stream is attached to a PPA, * remove it from the PPA's list. */ if ((as = up->ppa) != 0) { for (; as->next != 0; as = as->next) if (as->next == up) { as->next = up->next; break; } } } #ifdef SOL2 if (up->kstats) kstat_delete(up->kstats); mutex_destroy(&up->stats_lock); #endif q->q_ptr = NULL; WR(q)->q_ptr = NULL; for (prevp = &minor_devs; *prevp != 0; prevp = &(*prevp)->nextmn) { if (*prevp == up) { *prevp = up->nextmn; break; } } FREE(up, sizeof(upperstr_t)); --ppp_count; return 0; } /* * A message from on high. We do one of three things: * - qreply() * - put the message on the lower write stream * - queue it for our service routine */ static int pppuwput(q, mp) queue_t *q; mblk_t *mp; { upperstr_t *us, *ppa, *nps; struct iocblk *iop; struct linkblk *lb; #ifdef LACHTCP struct ifreq *ifr; int i; #endif queue_t *lq; int error, n, sap; mblk_t *mq; struct ppp_idle *pip; #ifdef PRIOQ queue_t *tlq; #endif /* PRIOQ */ #ifdef NO_DLPI upperstr_t *os; #endif us = (upperstr_t *) q->q_ptr; if (us == 0) { DPRINT("pppuwput: q_ptr = 0!\n"); return 0; } if (mp == 0) { DPRINT1("pppuwput/%d: mp = 0!\n", us->mn); return 0; } if (mp->b_datap == 0) { DPRINT1("pppuwput/%d: mp->b_datap = 0!\n", us->mn); return 0; } switch (mp->b_datap->db_type) { #ifndef NO_DLPI case M_PCPROTO: case M_PROTO: dlpi_request(q, mp, us); break; #endif /* NO_DLPI */ case M_DATA: if (us->flags & US_DBGLOG) DPRINT3("ppp/%d: uwput M_DATA len=%d flags=%x\n", us->mn, msgdsize(mp), us->flags); if (us->ppa == 0 || msgdsize(mp) > us->ppa->mtu + PPP_HDRLEN #ifndef NO_DLPI || (us->flags & US_CONTROL) == 0 #endif /* NO_DLPI */ ) { DPRINT1("pppuwput: junk data len=%d\n", msgdsize(mp)); freemsg(mp); break; } #ifdef NO_DLPI if ((us->flags & US_CONTROL) == 0 && !pass_packet(us, mp, 1)) break; #endif if (!send_data(mp, us)) putq(q, mp); break; case M_IOCTL: iop = (struct iocblk *) mp->b_rptr; error = EINVAL; if (us->flags & US_DBGLOG) DPRINT3("ppp/%d: ioctl %x count=%d\n", us->mn, iop->ioc_cmd, iop->ioc_count); switch (iop->ioc_cmd) { #if defined(SOL2) case DLIOCRAW: /* raw M_DATA mode */ us->flags |= US_RAWDATA; error = 0; break; #endif /* defined(SOL2) */ case I_LINK: if ((us->flags & US_CONTROL) == 0 || us->lowerq != 0) break; if (mp->b_cont == 0) { DPRINT1("pppuwput/%d: ioctl I_LINK b_cont = 0!\n", us->mn); break; } lb = (struct linkblk *) mp->b_cont->b_rptr; lq = lb->l_qbot; if (lq == 0) { DPRINT1("pppuwput/%d: ioctl I_LINK l_qbot = 0!\n", us->mn); break; } LOCK_LOWER_W; us->lowerq = lq; lq->q_ptr = (caddr_t) q; RD(lq)->q_ptr = (caddr_t) us->q; UNLOCK_LOWER; iop->ioc_count = 0; error = 0; us->flags &= ~US_LASTMOD; /* Unblock upper streams which now feed this lower stream. */ qenable(q); /* Send useful information down to the modules which are now linked below us. */ putctl2(lq, M_CTL, PPPCTL_UNIT, us->ppa_id); putctl4(lq, M_CTL, PPPCTL_MRU, us->mru); putctl4(lq, M_CTL, PPPCTL_MTU, us->mtu); #ifdef PRIOQ /* Lower tty driver's queue hiwat/lowat from default 4096/128 to 256/128 since we don't want queueing of data on output to physical device */ freezestr(lq); for (tlq = lq; tlq->q_next != NULL; tlq = tlq->q_next) ; strqset(tlq, QHIWAT, 0, 256); strqset(tlq, QLOWAT, 0, 128); unfreezestr(lq); #endif /* PRIOQ */ break; case I_UNLINK: if (mp->b_cont == 0) { DPRINT1("pppuwput/%d: ioctl I_UNLINK b_cont = 0!\n", us->mn); break; } lb = (struct linkblk *) mp->b_cont->b_rptr; #if DEBUG if (us->lowerq != lb->l_qbot) { DPRINT2("ppp unlink: lowerq=%x qbot=%x\n", us->lowerq, lb->l_qbot); break; } #endif iop->ioc_count = 0; qwriter(q, mp, detach_lower, PERIM_OUTER); error = -1; break; case PPPIO_NEWPPA: if (us->flags & US_CONTROL) break; if ((us->flags & US_PRIV) == 0) { error = EPERM; break; } /* Arrange to return an int */ if ((mq = mp->b_cont) == 0 || mq->b_datap->db_lim - mq->b_rptr < sizeof(int)) { mq = allocb(sizeof(int), BPRI_HI); if (mq == 0) { error = ENOSR; break; } if (mp->b_cont != 0) freemsg(mp->b_cont); mp->b_cont = mq; mq->b_cont = 0; } iop->ioc_count = sizeof(int); mq->b_wptr = mq->b_rptr + sizeof(int); qwriter(q, mp, new_ppa, PERIM_OUTER); error = -1; break; case PPPIO_ATTACH: /* like dlpi_attach, for programs which can't write to the stream (like pppstats) */ if (iop->ioc_count != sizeof(int) || us->ppa != 0) break; if (mp->b_cont == 0) { DPRINT1("pppuwput/%d: ioctl PPPIO_ATTACH b_cont = 0!\n", us->mn); break; } n = *(int *)mp->b_cont->b_rptr; for (ppa = ppas; ppa != 0; ppa = ppa->nextppa) if (ppa->ppa_id == n) break; if (ppa == 0) break; us->ppa = ppa; iop->ioc_count = 0; qwriter(q, mp, attach_ppa, PERIM_OUTER); error = -1; break; #ifdef NO_DLPI case PPPIO_BIND: /* Attach to a given SAP. */ if (iop->ioc_count != sizeof(int) || us->ppa == 0) break; if (mp->b_cont == 0) { DPRINT1("pppuwput/%d: ioctl PPPIO_BIND b_cont = 0!\n", us->mn); break; } n = *(int *)mp->b_cont->b_rptr; /* n must be a valid PPP network protocol number. */ if (n < 0x21 || n > 0x3fff || (n & 0x101) != 1) break; /* check that no other stream is bound to this sap already. */ for (os = us->ppa; os != 0; os = os->next) if (os->sap == n) break; if (os != 0) break; us->sap = n; iop->ioc_count = 0; error = 0; break; #endif /* NO_DLPI */ case PPPIO_MRU: if (iop->ioc_count != sizeof(int) || (us->flags & US_CONTROL) == 0) break; if (mp->b_cont == 0) { DPRINT1("pppuwput/%d: ioctl PPPIO_MRU b_cont = 0!\n", us->mn); break; } n = *(int *)mp->b_cont->b_rptr; if (n <= 0 || n > PPP_MAXMRU) break; if (n < PPP_MRU) n = PPP_MRU; us->mru = n; if (us->lowerq) putctl4(us->lowerq, M_CTL, PPPCTL_MRU, n); error = 0; iop->ioc_count = 0; break; case PPPIO_MTU: if (iop->ioc_count != sizeof(int) || (us->flags & US_CONTROL) == 0) break; if (mp->b_cont == 0) { DPRINT1("pppuwput/%d: ioctl PPPIO_MTU b_cont = 0!\n", us->mn); break; } n = *(int *)mp->b_cont->b_rptr; if (n <= 0 || n > PPP_MAXMTU) break; us->mtu = n; #ifdef LACHTCP /* The MTU reported in netstat, not used as IP max packet size! */ us->ifstats.ifs_mtu = n; #endif if (us->lowerq) putctl4(us->lowerq, M_CTL, PPPCTL_MTU, n); error = 0; iop->ioc_count = 0; break; case PPPIO_LASTMOD: us->flags |= US_LASTMOD; error = 0; break; case PPPIO_DEBUG: if (iop->ioc_count != sizeof(int)) break; if (mp->b_cont == 0) { DPRINT1("pppuwput/%d: ioctl PPPIO_DEBUG b_cont = 0!\n", us->mn); break; } n = *(int *)mp->b_cont->b_rptr; if (n == PPPDBG_DUMP + PPPDBG_DRIVER) { qwriter(q, NULL, debug_dump, PERIM_OUTER); iop->ioc_count = 0; error = -1; } else if (n == PPPDBG_LOG + PPPDBG_DRIVER) { DPRINT1("ppp/%d: debug log enabled\n", us->mn); us->flags |= US_DBGLOG; iop->ioc_count = 0; error = 0; } else { if (us->ppa == 0 || us->ppa->lowerq == 0) break; putnext(us->ppa->lowerq, mp); error = -1; } break; case PPPIO_NPMODE: if (iop->ioc_count != 2 * sizeof(int)) break; if ((us->flags & US_CONTROL) == 0) break; if (mp->b_cont == 0) { DPRINT1("pppuwput/%d: ioctl PPPIO_NPMODE b_cont = 0!\n", us->mn); break; } sap = ((int *)mp->b_cont->b_rptr)[0]; for (nps = us->next; nps != 0; nps = nps->next) { if (us->flags & US_DBGLOG) DPRINT2("us = 0x%x, us->next->sap = 0x%x\n", nps, nps->sap); if (nps->sap == sap) break; } if (nps == 0) { if (us->flags & US_DBGLOG) DPRINT2("ppp/%d: no stream for sap %x\n", us->mn, sap); break; } /* XXX possibly should use qwriter here */ nps->npmode = (enum NPmode) ((int *)mp->b_cont->b_rptr)[1]; if (nps->npmode != NPMODE_QUEUE && (nps->flags & US_BLOCKED) != 0) qenable(WR(nps->q)); iop->ioc_count = 0; error = 0; break; case PPPIO_GIDLE: if ((ppa = us->ppa) == 0) break; mq = allocb(sizeof(struct ppp_idle), BPRI_HI); if (mq == 0) { error = ENOSR; break; } if (mp->b_cont != 0) freemsg(mp->b_cont); mp->b_cont = mq; mq->b_cont = 0; pip = (struct ppp_idle *) mq->b_wptr; pip->xmit_idle = time - ppa->last_sent; pip->recv_idle = time - ppa->last_recv; mq->b_wptr += sizeof(struct ppp_idle); iop->ioc_count = sizeof(struct ppp_idle); error = 0; break; #ifdef LACHTCP case SIOCSIFNAME: /* Sent from IP down to us. Attach the ifstats structure. */ if (iop->ioc_count != sizeof(struct ifreq) || us->ppa == 0) break; ifr = (struct ifreq *)mp->b_cont->b_rptr; /* Find the unit number in the interface name. */ for (i = 0; i < IFNAMSIZ; i++) { if (ifr->ifr_name[i] == 0 || (ifr->ifr_name[i] >= '0' && ifr->ifr_name[i] <= '9')) break; else us->ifname[i] = ifr->ifr_name[i]; } us->ifname[i] = 0; /* Convert the unit number to binary. */ for (n = 0; i < IFNAMSIZ; i++) { if (ifr->ifr_name[i] == 0) { break; } else { n = n * 10 + ifr->ifr_name[i] - '0'; } } /* Verify the ppa. */ if (us->ppa->ppa_id != n) break; ppa = us->ppa; /* Set up the netstat block. */ strncpy (ppa->ifname, us->ifname, IFNAMSIZ); ppa->ifstats.ifs_name = ppa->ifname; ppa->ifstats.ifs_unit = n; ppa->ifstats.ifs_active = us->state != DL_UNBOUND; ppa->ifstats.ifs_mtu = ppa->mtu; /* Link in statistics used by netstat. */ ppa->ifstats.ifs_next = ifstats; ifstats = &ppa->ifstats; iop->ioc_count = 0; error = 0; break; case SIOCGIFFLAGS: if (!(us->flags & US_CONTROL)) { if (us->ppa) us = us->ppa; else break; } ((struct iocblk_in *)iop)->ioc_ifflags = us->ifflags; error = 0; break; case SIOCSIFFLAGS: if (!(us->flags & US_CONTROL)) { if (us->ppa) us = us->ppa; else break; } us->ifflags = ((struct iocblk_in *)iop)->ioc_ifflags; error = 0; break; case SIOCSIFADDR: if (!(us->flags & US_CONTROL)) { if (us->ppa) us = us->ppa; else break; } us->ifflags |= IFF_RUNNING; ((struct iocblk_in *)iop)->ioc_ifflags |= IFF_RUNNING; error = 0; break; case SIOCSIFMTU: /* * Vanilla SVR4 systems don't handle SIOCSIFMTU, rather * they take the MTU from the DL_INFO_ACK we sent in response * to their DL_INFO_REQ. Fortunately, they will update the * MTU if we send an unsolicited DL_INFO_ACK up. */ if ((mq = allocb(sizeof(dl_info_req_t), BPRI_HI)) == 0) break; /* should do bufcall */ ((union DL_primitives *)mq->b_rptr)->dl_primitive = DL_INFO_REQ; mq->b_wptr = mq->b_rptr + sizeof(dl_info_req_t); dlpi_request(q, mq, us); error = 0; break; case SIOCGIFNETMASK: case SIOCSIFNETMASK: case SIOCGIFADDR: case SIOCGIFDSTADDR: case SIOCSIFDSTADDR: case SIOCGIFMETRIC: error = 0; break; #endif /* LACHTCP */ default: if (us->ppa == 0 || us->ppa->lowerq == 0) break; us->ioc_id = iop->ioc_id; error = -1; switch (iop->ioc_cmd) { case PPPIO_GETSTAT: case PPPIO_GETCSTAT: if (us->flags & US_LASTMOD) { error = EINVAL; break; } putnext(us->ppa->lowerq, mp); break; default: if (us->flags & US_PRIV) putnext(us->ppa->lowerq, mp); else { DPRINT1("ppp ioctl %x rejected\n", iop->ioc_cmd); error = EPERM; } break; } break; } if (error > 0) { iop->ioc_error = error; mp->b_datap->db_type = M_IOCNAK; qreply(q, mp); } else if (error == 0) { mp->b_datap->db_type = M_IOCACK; qreply(q, mp); } break; case M_FLUSH: if (us->flags & US_DBGLOG) DPRINT2("ppp/%d: flush %x\n", us->mn, *mp->b_rptr); if (*mp->b_rptr & FLUSHW) flushq(q, FLUSHDATA); if (*mp->b_rptr & FLUSHR) { *mp->b_rptr &= ~FLUSHW; qreply(q, mp); } else freemsg(mp); break; default: freemsg(mp); break; } return 0; } #ifndef NO_DLPI static void dlpi_request(q, mp, us) queue_t *q; mblk_t *mp; upperstr_t *us; { union DL_primitives *d = (union DL_primitives *) mp->b_rptr; int size = mp->b_wptr - mp->b_rptr; mblk_t *reply, *np; upperstr_t *ppa, *os; int sap, len; dl_info_ack_t *info; dl_bind_ack_t *ackp; #if DL_CURRENT_VERSION >= 2 dl_phys_addr_ack_t *paddrack; static struct ether_addr eaddr = {0}; #endif if (us->flags & US_DBGLOG) DPRINT3("ppp/%d: dlpi prim %x len=%d\n", us->mn, d->dl_primitive, size); switch (d->dl_primitive) { case DL_INFO_REQ: if (size < sizeof(dl_info_req_t)) goto badprim; if ((reply = allocb(sizeof(dl_info_ack_t), BPRI_HI)) == 0) break; /* should do bufcall */ reply->b_datap->db_type = M_PCPROTO; info = (dl_info_ack_t *) reply->b_wptr; reply->b_wptr += sizeof(dl_info_ack_t); bzero((caddr_t) info, sizeof(dl_info_ack_t)); info->dl_primitive = DL_INFO_ACK; info->dl_max_sdu = us->ppa? us->ppa->mtu: PPP_MAXMTU; info->dl_min_sdu = 1; info->dl_addr_length = sizeof(uint); info->dl_mac_type = DL_ETHER; /* a bigger lie */ info->dl_current_state = us->state; info->dl_service_mode = DL_CLDLS; info->dl_provider_style = DL_STYLE2; #if DL_CURRENT_VERSION >= 2 info->dl_sap_length = sizeof(uint); info->dl_version = DL_CURRENT_VERSION; #endif qreply(q, reply); break; case DL_ATTACH_REQ: if (size < sizeof(dl_attach_req_t)) goto badprim; if (us->state != DL_UNATTACHED || us->ppa != 0) { dlpi_error(q, us, DL_ATTACH_REQ, DL_OUTSTATE, 0); break; } for (ppa = ppas; ppa != 0; ppa = ppa->nextppa) if (ppa->ppa_id == d->attach_req.dl_ppa) break; if (ppa == 0) { dlpi_error(q, us, DL_ATTACH_REQ, DL_BADPPA, 0); break; } us->ppa = ppa; qwriter(q, mp, attach_ppa, PERIM_OUTER); return; case DL_DETACH_REQ: if (size < sizeof(dl_detach_req_t)) goto badprim; if (us->state != DL_UNBOUND || us->ppa == 0) { dlpi_error(q, us, DL_DETACH_REQ, DL_OUTSTATE, 0); break; } qwriter(q, mp, detach_ppa, PERIM_OUTER); return; case DL_BIND_REQ: if (size < sizeof(dl_bind_req_t)) goto badprim; if (us->state != DL_UNBOUND || us->ppa == 0) { dlpi_error(q, us, DL_BIND_REQ, DL_OUTSTATE, 0); break; } #if 0 /* apparently this test fails (unnecessarily?) on some systems */ if (d->bind_req.dl_service_mode != DL_CLDLS) { dlpi_error(q, us, DL_BIND_REQ, DL_UNSUPPORTED, 0); break; } #endif /* saps must be valid PPP network protocol numbers, except that we accept ETHERTYPE_IP in place of PPP_IP. */ sap = d->bind_req.dl_sap; us->req_sap = sap; #if defined(SOL2) if (us->flags & US_DBGLOG) DPRINT2("DL_BIND_REQ: ip gives sap = 0x%x, us = 0x%x", sap, us); if (sap == ETHERTYPE_IP) /* normal IFF_IPV4 */ sap = PPP_IP; else if (sap == ETHERTYPE_IPV6) /* when IFF_IPV6 is set */ sap = PPP_IPV6; else if (sap == ETHERTYPE_ALLSAP) /* snoop gives sap of 0 */ sap = PPP_ALLSAP; else { DPRINT2("DL_BIND_REQ: unrecognized sap = 0x%x, us = 0x%x", sap, us); dlpi_error(q, us, DL_BIND_REQ, DL_BADADDR, 0); break; } #else if (sap == ETHERTYPE_IP) sap = PPP_IP; if (sap < 0x21 || sap > 0x3fff || (sap & 0x101) != 1) { dlpi_error(q, us, DL_BIND_REQ, DL_BADADDR, 0); break; } #endif /* defined(SOL2) */ /* check that no other stream is bound to this sap already. */ for (os = us->ppa; os != 0; os = os->next) if (os->sap == sap) break; if (os != 0) { dlpi_error(q, us, DL_BIND_REQ, DL_NOADDR, 0); break; } us->sap = sap; us->state = DL_IDLE; if ((reply = allocb(sizeof(dl_bind_ack_t) + sizeof(uint), BPRI_HI)) == 0) break; /* should do bufcall */ ackp = (dl_bind_ack_t *) reply->b_wptr; reply->b_wptr += sizeof(dl_bind_ack_t) + sizeof(uint); reply->b_datap->db_type = M_PCPROTO; bzero((caddr_t) ackp, sizeof(dl_bind_ack_t)); ackp->dl_primitive = DL_BIND_ACK; ackp->dl_sap = sap; ackp->dl_addr_length = sizeof(uint); ackp->dl_addr_offset = sizeof(dl_bind_ack_t); *(uint *)(ackp+1) = sap; qreply(q, reply); break; case DL_UNBIND_REQ: if (size < sizeof(dl_unbind_req_t)) goto badprim; if (us->state != DL_IDLE) { dlpi_error(q, us, DL_UNBIND_REQ, DL_OUTSTATE, 0); break; } us->sap = -1; us->state = DL_UNBOUND; #ifdef LACHTCP us->ppa->ifstats.ifs_active = 0; #endif dlpi_ok(q, DL_UNBIND_REQ); break; case DL_UNITDATA_REQ: if (size < sizeof(dl_unitdata_req_t)) goto badprim; if (us->state != DL_IDLE) { dlpi_error(q, us, DL_UNITDATA_REQ, DL_OUTSTATE, 0); break; } if ((ppa = us->ppa) == 0) { cmn_err(CE_CONT, "ppp: in state dl_idle but ppa == 0?\n"); break; } len = mp->b_cont == 0? 0: msgdsize(mp->b_cont); if (len > ppa->mtu) { DPRINT2("dlpi data too large (%d > %d)\n", len, ppa->mtu); break; } #if defined(SOL2) /* * Should there be any promiscuous stream(s), send the data * up for each promiscuous stream that we recognize. */ if (mp->b_cont) promisc_sendup(ppa, mp->b_cont, us->sap, 0); #endif /* defined(SOL2) */ mp->b_band = 0; #ifdef PRIOQ /* Extract s_port & d_port from IP-packet, the code is a bit dirty here, but so am I, too... */ if (mp->b_datap->db_type == M_PROTO && us->sap == PPP_IP && mp->b_cont != 0) { u_char *bb, *tlh; int iphlen, len; u_short *ptr; u_char band_unset, cur_band, syn; u_short s_port, d_port; bb = mp->b_cont->b_rptr; /* bb points to IP-header*/ len = mp->b_cont->b_wptr - mp->b_cont->b_rptr; syn = 0; s_port = IPPORT_DEFAULT; d_port = IPPORT_DEFAULT; if (len >= 20) { /* 20 = minimum length of IP header */ iphlen = (bb[0] & 0x0f) * 4; tlh = bb + iphlen; len -= iphlen; switch (bb[9]) { case IPPROTO_TCP: if (len >= 20) { /* min length of TCP header */ s_port = (tlh[0] << 8) + tlh[1]; d_port = (tlh[2] << 8) + tlh[3]; syn = tlh[13] & 0x02; } break; case IPPROTO_UDP: if (len >= 8) { /* min length of UDP header */ s_port = (tlh[0] << 8) + tlh[1]; d_port = (tlh[2] << 8) + tlh[3]; } break; } } /* * Now calculate b_band for this packet from the * port-priority table. */ ptr = prioq_table; cur_band = max_band; band_unset = 1; while (*ptr) { while (*ptr && band_unset) if (s_port == *ptr || d_port == *ptr++) { mp->b_band = cur_band; band_unset = 0; break; } ptr++; cur_band--; } if (band_unset) mp->b_band = def_band; /* It may be usable to urge SYN packets a bit */ if (syn) mp->b_band++; } #endif /* PRIOQ */ /* this assumes PPP_HDRLEN <= sizeof(dl_unitdata_req_t) */ if (mp->b_datap->db_ref > 1) { np = allocb(PPP_HDRLEN, BPRI_HI); if (np == 0) break; /* gak! */ np->b_cont = mp->b_cont; mp->b_cont = 0; freeb(mp); mp = np; } else mp->b_datap->db_type = M_DATA; /* XXX should use dl_dest_addr_offset/length here, but we would have to translate ETHERTYPE_IP -> PPP_IP */ mp->b_wptr = mp->b_rptr + PPP_HDRLEN; mp->b_rptr[0] = PPP_ALLSTATIONS; mp->b_rptr[1] = PPP_UI; mp->b_rptr[2] = us->sap >> 8; mp->b_rptr[3] = us->sap; if (pass_packet(us, mp, 1)) { if (!send_data(mp, us)) putq(q, mp); } return; #if DL_CURRENT_VERSION >= 2 case DL_PHYS_ADDR_REQ: if (size < sizeof(dl_phys_addr_req_t)) goto badprim; /* * Don't check state because ifconfig sends this one down too */ if ((reply = allocb(sizeof(dl_phys_addr_ack_t)+ETHERADDRL, BPRI_HI)) == 0) break; /* should do bufcall */ reply->b_datap->db_type = M_PCPROTO; paddrack = (dl_phys_addr_ack_t *) reply->b_wptr; reply->b_wptr += sizeof(dl_phys_addr_ack_t); bzero((caddr_t) paddrack, sizeof(dl_phys_addr_ack_t)+ETHERADDRL); paddrack->dl_primitive = DL_PHYS_ADDR_ACK; paddrack->dl_addr_length = ETHERADDRL; paddrack->dl_addr_offset = sizeof(dl_phys_addr_ack_t); bcopy(&eaddr, reply->b_wptr, ETHERADDRL); reply->b_wptr += ETHERADDRL; qreply(q, reply); break; #if defined(SOL2) case DL_PROMISCON_REQ: if (size < sizeof(dl_promiscon_req_t)) goto badprim; us->flags |= US_PROMISC; dlpi_ok(q, DL_PROMISCON_REQ); break; case DL_PROMISCOFF_REQ: if (size < sizeof(dl_promiscoff_req_t)) goto badprim; us->flags &= ~US_PROMISC; dlpi_ok(q, DL_PROMISCOFF_REQ); break; #else case DL_PROMISCON_REQ: /* fall thru */ case DL_PROMISCOFF_REQ: /* fall thru */ #endif /* defined(SOL2) */ #endif /* DL_CURRENT_VERSION >= 2 */ #if DL_CURRENT_VERSION >= 2 case DL_SET_PHYS_ADDR_REQ: case DL_SUBS_BIND_REQ: case DL_SUBS_UNBIND_REQ: case DL_ENABMULTI_REQ: case DL_DISABMULTI_REQ: case DL_XID_REQ: case DL_TEST_REQ: case DL_REPLY_UPDATE_REQ: case DL_REPLY_REQ: case DL_DATA_ACK_REQ: #endif case DL_CONNECT_REQ: case DL_TOKEN_REQ: dlpi_error(q, us, d->dl_primitive, DL_NOTSUPPORTED, 0); break; case DL_CONNECT_RES: case DL_DISCONNECT_REQ: case DL_RESET_REQ: case DL_RESET_RES: dlpi_error(q, us, d->dl_primitive, DL_OUTSTATE, 0); break; case DL_UDQOS_REQ: dlpi_error(q, us, d->dl_primitive, DL_BADQOSTYPE, 0); break; #if DL_CURRENT_VERSION >= 2 case DL_TEST_RES: case DL_XID_RES: break; #endif default: cmn_err(CE_CONT, "ppp: unknown dlpi prim 0x%x\n", d->dl_primitive); /* fall through */ badprim: dlpi_error(q, us, d->dl_primitive, DL_BADPRIM, 0); break; } freemsg(mp); } static void dlpi_error(q, us, prim, err, uerr) queue_t *q; upperstr_t *us; int prim, err, uerr; { mblk_t *reply; dl_error_ack_t *errp; if (us->flags & US_DBGLOG) DPRINT3("ppp/%d: dlpi error, prim=%x, err=%x\n", us->mn, prim, err); reply = allocb(sizeof(dl_error_ack_t), BPRI_HI); if (reply == 0) return; /* XXX should do bufcall */ reply->b_datap->db_type = M_PCPROTO; errp = (dl_error_ack_t *) reply->b_wptr; reply->b_wptr += sizeof(dl_error_ack_t); errp->dl_primitive = DL_ERROR_ACK; errp->dl_error_primitive = prim; errp->dl_errno = err; errp->dl_unix_errno = uerr; qreply(q, reply); } static void dlpi_ok(q, prim) queue_t *q; int prim; { mblk_t *reply; dl_ok_ack_t *okp; reply = allocb(sizeof(dl_ok_ack_t), BPRI_HI); if (reply == 0) return; /* XXX should do bufcall */ reply->b_datap->db_type = M_PCPROTO; okp = (dl_ok_ack_t *) reply->b_wptr; reply->b_wptr += sizeof(dl_ok_ack_t); okp->dl_primitive = DL_OK_ACK; okp->dl_correct_primitive = prim; qreply(q, reply); } #endif /* NO_DLPI */ static int pass_packet(us, mp, outbound) upperstr_t *us; mblk_t *mp; int outbound; { int pass; upperstr_t *ppa; if ((ppa = us->ppa) == 0) { freemsg(mp); return 0; } #ifdef FILTER_PACKETS pass = ip_hard_filter(us, mp, outbound); #else /* * Here is where we might, in future, decide whether to pass * or drop the packet, and whether it counts as link activity. */ pass = 1; #endif /* FILTER_PACKETS */ if (pass < 0) { /* pass only if link already up, and don't update time */ if (ppa->lowerq == 0) { freemsg(mp); return 0; } pass = 1; } else if (pass) { if (outbound) ppa->last_sent = time; else ppa->last_recv = time; } return pass; } /* * We have some data to send down to the lower stream (or up the * control stream, if we don't have a lower stream attached). * Returns 1 if the message was dealt with, 0 if it wasn't able * to be sent on and should therefore be queued up. */ static int send_data(mp, us) mblk_t *mp; upperstr_t *us; { upperstr_t *ppa; if ((us->flags & US_BLOCKED) || us->npmode == NPMODE_QUEUE) return 0; ppa = us->ppa; if (ppa == 0 || us->npmode == NPMODE_DROP || us->npmode == NPMODE_ERROR) { if (us->flags & US_DBGLOG) DPRINT2("ppp/%d: dropping pkt (npmode=%d)\n", us->mn, us->npmode); freemsg(mp); return 1; } if (ppa->lowerq == 0) { /* try to send it up the control stream */ if (bcanputnext(ppa->q, mp->b_band)) { /* * The message seems to get corrupted for some reason if * we just send the message up as it is, so we send a copy. */ mblk_t *np = copymsg(mp); freemsg(mp); if (np != 0) putnext(ppa->q, np); return 1; } } else { if (bcanputnext(ppa->lowerq, mp->b_band)) { MT_ENTER(&ppa->stats_lock); ppa->stats.ppp_opackets++; ppa->stats.ppp_obytes += msgdsize(mp); #ifdef INCR_OPACKETS INCR_OPACKETS(ppa); #endif MT_EXIT(&ppa->stats_lock); /* * The lower queue is only ever detached while holding an * exclusive lock on the whole driver. So we can be confident * that the lower queue is still there. */ putnext(ppa->lowerq, mp); return 1; } } us->flags |= US_BLOCKED; return 0; } /* * Allocate a new PPA id and link this stream into the list of PPAs. * This procedure is called with an exclusive lock on all queues in * this driver. */ static void new_ppa(q, mp) queue_t *q; mblk_t *mp; { upperstr_t *us, *up, **usp; int ppa_id; us = (upperstr_t *) q->q_ptr; if (us == 0) { DPRINT("new_ppa: q_ptr = 0!\n"); return; } usp = &ppas; ppa_id = 0; while ((up = *usp) != 0 && ppa_id == up->ppa_id) { ++ppa_id; usp = &up->nextppa; } us->ppa_id = ppa_id; us->ppa = us; us->next = 0; us->nextppa = *usp; *usp = us; us->flags |= US_CONTROL; us->npmode = NPMODE_PASS; us->mtu = PPP_MTU; us->mru = PPP_MRU; #ifdef SOL2 /* * Create a kstats record for our statistics, so netstat -i works. */ if (us->kstats == 0) { char unit[32]; sprintf(unit, "ppp%d", us->ppa->ppa_id); us->kstats = kstat_create("ppp", us->ppa->ppa_id, unit, "net", KSTAT_TYPE_NAMED, 4, 0); if (us->kstats != 0) { kstat_named_t *kn = KSTAT_NAMED_PTR(us->kstats); strcpy(kn[0].name, "ipackets"); kn[0].data_type = KSTAT_DATA_ULONG; strcpy(kn[1].name, "ierrors"); kn[1].data_type = KSTAT_DATA_ULONG; strcpy(kn[2].name, "opackets"); kn[2].data_type = KSTAT_DATA_ULONG; strcpy(kn[3].name, "oerrors"); kn[3].data_type = KSTAT_DATA_ULONG; kstat_install(us->kstats); } } #endif /* SOL2 */ *(int *)mp->b_cont->b_rptr = ppa_id; mp->b_datap->db_type = M_IOCACK; qreply(q, mp); } static void attach_ppa(q, mp) queue_t *q; mblk_t *mp; { upperstr_t *us, *t; us = (upperstr_t *) q->q_ptr; if (us == 0) { DPRINT("attach_ppa: q_ptr = 0!\n"); return; } #ifndef NO_DLPI us->state = DL_UNBOUND; #endif for (t = us->ppa; t->next != 0; t = t->next) ; t->next = us; us->next = 0; if (mp->b_datap->db_type == M_IOCTL) { mp->b_datap->db_type = M_IOCACK; qreply(q, mp); } else { #ifndef NO_DLPI dlpi_ok(q, DL_ATTACH_REQ); #endif } } static void detach_ppa(q, mp) queue_t *q; mblk_t *mp; { upperstr_t *us, *t; us = (upperstr_t *) q->q_ptr; if (us == 0) { DPRINT("detach_ppa: q_ptr = 0!\n"); return; } for (t = us->ppa; t->next != 0; t = t->next) if (t->next == us) { t->next = us->next; break; } us->next = 0; us->ppa = 0; #ifndef NO_DLPI us->state = DL_UNATTACHED; dlpi_ok(q, DL_DETACH_REQ); #endif } /* * We call this with qwriter in order to give the upper queue procedures * the guarantee that the lower queue is not going to go away while * they are executing. */ static void detach_lower(q, mp) queue_t *q; mblk_t *mp; { upperstr_t *us; us = (upperstr_t *) q->q_ptr; if (us == 0) { DPRINT("detach_lower: q_ptr = 0!\n"); return; } LOCK_LOWER_W; us->lowerq->q_ptr = 0; RD(us->lowerq)->q_ptr = 0; us->lowerq = 0; UNLOCK_LOWER; /* Unblock streams which now feed back up the control stream. */ qenable(us->q); mp->b_datap->db_type = M_IOCACK; qreply(q, mp); } static int pppuwsrv(q) queue_t *q; { upperstr_t *us, *as; mblk_t *mp; us = (upperstr_t *) q->q_ptr; if (us == 0) { DPRINT("pppuwsrv: q_ptr = 0!\n"); return 0; } /* * If this is a control stream, then this service procedure * probably got enabled because of flow control in the lower * stream being enabled (or because of the lower stream going * away). Therefore we enable the service procedure of all * attached upper streams. */ if (us->flags & US_CONTROL) { for (as = us->next; as != 0; as = as->next) qenable(WR(as->q)); } /* Try to send on any data queued here. */ us->flags &= ~US_BLOCKED; while ((mp = getq(q)) != 0) { if (!send_data(mp, us)) { putbq(q, mp); break; } } return 0; } /* should never get called... */ static int ppplwput(q, mp) queue_t *q; mblk_t *mp; { putnext(q, mp); return 0; } static int ppplwsrv(q) queue_t *q; { queue_t *uq; /* * Flow control has back-enabled this stream: * enable the upper write service procedure for * the upper control stream for this lower stream. */ LOCK_LOWER_R; uq = (queue_t *) q->q_ptr; if (uq != 0) qenable(uq); UNLOCK_LOWER; return 0; } /* * This should only get called for control streams. */ static int pppurput(q, mp) queue_t *q; mblk_t *mp; { upperstr_t *ppa, *us; int proto, len; struct iocblk *iop; ppa = (upperstr_t *) q->q_ptr; if (ppa == 0) { DPRINT("pppurput: q_ptr = 0!\n"); return 0; } switch (mp->b_datap->db_type) { case M_CTL: MT_ENTER(&ppa->stats_lock); switch (*mp->b_rptr) { case PPPCTL_IERROR: #ifdef INCR_IERRORS INCR_IERRORS(ppa); #endif ppa->stats.ppp_ierrors++; break; case PPPCTL_OERROR: #ifdef INCR_OERRORS INCR_OERRORS(ppa); #endif ppa->stats.ppp_oerrors++; break; } MT_EXIT(&ppa->stats_lock); freemsg(mp); break; case M_IOCACK: case M_IOCNAK: /* * Attempt to match up the response with the stream * that the request came from. */ iop = (struct iocblk *) mp->b_rptr; for (us = ppa; us != 0; us = us->next) if (us->ioc_id == iop->ioc_id) break; if (us == 0) freemsg(mp); else putnext(us->q, mp); break; case M_HANGUP: /* * The serial device has hung up. We don't want to send * the M_HANGUP message up to pppd because that will stop * us from using the control stream any more. Instead we * send a zero-length message as an end-of-file indication. */ freemsg(mp); mp = allocb(1, BPRI_HI); if (mp == 0) { DPRINT1("ppp/%d: couldn't allocate eof message!\n", ppa->mn); break; } putnext(ppa->q, mp); break; default: if (mp->b_datap->db_type == M_DATA) { len = msgdsize(mp); if (mp->b_wptr - mp->b_rptr < PPP_HDRLEN) { PULLUP(mp, PPP_HDRLEN); if (mp == 0) { DPRINT1("ppp_urput: msgpullup failed (len=%d)\n", len); break; } } MT_ENTER(&ppa->stats_lock); ppa->stats.ppp_ipackets++; ppa->stats.ppp_ibytes += len; #ifdef INCR_IPACKETS INCR_IPACKETS(ppa); #endif MT_EXIT(&ppa->stats_lock); proto = PPP_PROTOCOL(mp->b_rptr); #if defined(SOL2) /* * Should there be any promiscuous stream(s), send the data * up for each promiscuous stream that we recognize. */ promisc_sendup(ppa, mp, proto, 1); #endif /* defined(SOL2) */ if (proto < 0x8000 && (us = find_dest(ppa, proto)) != 0) { /* * A data packet for some network protocol. * Queue it on the upper stream for that protocol. * XXX could we just putnext it? (would require thought) * The rblocked flag is there to ensure that we keep * messages in order for each network protocol. */ if (!pass_packet(us, mp, 0)) break; if (!us->rblocked && !canput(us->q)) us->rblocked = 1; if (!us->rblocked) putq(us->q, mp); else putq(q, mp); break; } } /* * A control frame, a frame for an unknown protocol, * or some other message type. * Send it up to pppd via the control stream. */ if (queclass(mp) == QPCTL || canputnext(ppa->q)) putnext(ppa->q, mp); else putq(q, mp); break; } return 0; } static int pppursrv(q) queue_t *q; { upperstr_t *us, *as; mblk_t *mp, *hdr; #ifndef NO_DLPI dl_unitdata_ind_t *ud; #endif int proto; us = (upperstr_t *) q->q_ptr; if (us == 0) { DPRINT("pppursrv: q_ptr = 0!\n"); return 0; } if (us->flags & US_CONTROL) { /* * A control stream. * If there is no lower queue attached, run the write service * routines of other upper streams attached to this PPA. */ if (us->lowerq == 0) { as = us; do { if (as->flags & US_BLOCKED) qenable(WR(as->q)); as = as->next; } while (as != 0); } /* * Messages get queued on this stream's read queue if they * can't be queued on the read queue of the attached stream * that they are destined for. This is for flow control - * when this queue fills up, the lower read put procedure will * queue messages there and the flow control will propagate * down from there. */ while ((mp = getq(q)) != 0) { proto = PPP_PROTOCOL(mp->b_rptr); if (proto < 0x8000 && (as = find_dest(us, proto)) != 0) { if (!canput(as->q)) break; putq(as->q, mp); } else { if (!canputnext(q)) break; putnext(q, mp); } } if (mp) { putbq(q, mp); } else { /* can now put stuff directly on network protocol streams again */ for (as = us->next; as != 0; as = as->next) as->rblocked = 0; } /* * If this stream has a lower stream attached, * enable the read queue's service routine. * XXX we should really only do this if the queue length * has dropped below the low-water mark. */ if (us->lowerq != 0) qenable(RD(us->lowerq)); } else { /* * A network protocol stream. Put a DLPI header on each * packet and send it on. * (Actually, it seems that the IP module will happily * accept M_DATA messages without the DL_UNITDATA_IND header.) */ while ((mp = getq(q)) != 0) { if (!canputnext(q)) { putbq(q, mp); break; } #ifndef NO_DLPI proto = PPP_PROTOCOL(mp->b_rptr); mp->b_rptr += PPP_HDRLEN; hdr = allocb(sizeof(dl_unitdata_ind_t) + 2 * sizeof(uint), BPRI_MED); if (hdr == 0) { /* XXX should put it back and use bufcall */ freemsg(mp); continue; } hdr->b_datap->db_type = M_PROTO; ud = (dl_unitdata_ind_t *) hdr->b_wptr; hdr->b_wptr += sizeof(dl_unitdata_ind_t) + 2 * sizeof(uint); hdr->b_cont = mp; ud->dl_primitive = DL_UNITDATA_IND; ud->dl_dest_addr_length = sizeof(uint); ud->dl_dest_addr_offset = sizeof(dl_unitdata_ind_t); ud->dl_src_addr_length = sizeof(uint); ud->dl_src_addr_offset = ud->dl_dest_addr_offset + sizeof(uint); #if DL_CURRENT_VERSION >= 2 ud->dl_group_address = 0; #endif /* Send the DLPI client the data with the SAP they requested, (e.g. ETHERTYPE_IP) rather than the PPP protocol number (e.g. PPP_IP) */ ((uint *)(ud + 1))[0] = us->req_sap; /* dest SAP */ ((uint *)(ud + 1))[1] = us->req_sap; /* src SAP */ putnext(q, hdr); #else /* NO_DLPI */ putnext(q, mp); #endif /* NO_DLPI */ } /* * Now that we have consumed some packets from this queue, * enable the control stream's read service routine so that we * can process any packets for us that might have got queued * there for flow control reasons. */ if (us->ppa) qenable(us->ppa->q); } return 0; } static upperstr_t * find_dest(ppa, proto) upperstr_t *ppa; int proto; { upperstr_t *us; for (us = ppa->next; us != 0; us = us->next) if (proto == us->sap) break; return us; } #if defined (SOL2) /* * Test upstream promiscuous conditions. As of now, only pass IPv4 and * Ipv6 packets upstream (let PPP packets be decoded elsewhere). */ static upperstr_t * find_promisc(us, proto) upperstr_t *us; int proto; { if ((proto != PPP_IP) && (proto != PPP_IPV6)) return (upperstr_t *)0; for ( ; us; us = us->next) { if ((us->flags & US_PROMISC) && (us->state == DL_IDLE)) return us; } return (upperstr_t *)0; } /* * Prepend an empty Ethernet header to msg for snoop, et al. */ static mblk_t * prepend_ether(us, mp, proto) upperstr_t *us; mblk_t *mp; int proto; { mblk_t *eh; int type; if ((eh = allocb(sizeof(struct ether_header), BPRI_HI)) == 0) { freemsg(mp); return (mblk_t *)0; } if (proto == PPP_IP) type = ETHERTYPE_IP; else if (proto == PPP_IPV6) type = ETHERTYPE_IPV6; else type = proto; /* What else? Let decoder decide */ eh->b_wptr += sizeof(struct ether_header); bzero((caddr_t)eh->b_rptr, sizeof(struct ether_header)); ((struct ether_header *)eh->b_rptr)->ether_type = htons((short)type); eh->b_cont = mp; return (eh); } /* * Prepend DL_UNITDATA_IND mblk to msg */ static mblk_t * prepend_udind(us, mp, proto) upperstr_t *us; mblk_t *mp; int proto; { dl_unitdata_ind_t *dlu; mblk_t *dh; size_t size; size = sizeof(dl_unitdata_ind_t); if ((dh = allocb(size, BPRI_MED)) == 0) { freemsg(mp); return (mblk_t *)0; } dh->b_datap->db_type = M_PROTO; dh->b_wptr = dh->b_datap->db_lim; dh->b_rptr = dh->b_wptr - size; dlu = (dl_unitdata_ind_t *)dh->b_rptr; dlu->dl_primitive = DL_UNITDATA_IND; dlu->dl_dest_addr_length = 0; dlu->dl_dest_addr_offset = sizeof(dl_unitdata_ind_t); dlu->dl_src_addr_length = 0; dlu->dl_src_addr_offset = sizeof(dl_unitdata_ind_t); dlu->dl_group_address = 0; dh->b_cont = mp; return (dh); } /* * For any recognized promiscuous streams, send data upstream */ static void promisc_sendup(ppa, mp, proto, skip) upperstr_t *ppa; mblk_t *mp; int proto, skip; { mblk_t *dup_mp, *dup_dup_mp; upperstr_t *prus, *nprus; if ((prus = find_promisc(ppa, proto)) != 0) { if (dup_mp = dupmsg(mp)) { if (skip) dup_mp->b_rptr += PPP_HDRLEN; for ( ; nprus = find_promisc(prus->next, proto); prus = nprus) { if (dup_dup_mp = dupmsg(dup_mp)) { if (canputnext(prus->q)) { if (prus->flags & US_RAWDATA) { dup_dup_mp = prepend_ether(prus, dup_dup_mp, proto); putnext(prus->q, dup_dup_mp); } else { dup_dup_mp = prepend_udind(prus, dup_dup_mp, proto); putnext(prus->q, dup_dup_mp); } } else { DPRINT("ppp_urput: data to promisc q dropped\n"); freemsg(dup_dup_mp); } } } if (canputnext(prus->q)) { if (prus->flags & US_RAWDATA) { dup_mp = prepend_ether(prus, dup_mp, proto); putnext(prus->q, dup_mp); } else { dup_mp = prepend_udind(prus, dup_mp, proto); putnext(prus->q, dup_mp); } } else { DPRINT("ppp_urput: data to promisc q dropped\n"); freemsg(dup_mp); } } } } #endif /* defined(SOL2) */ /* * We simply put the message on to the associated upper control stream * (either here or in ppplrsrv). That way we enter the perimeters * before looking through the list of attached streams to decide which * stream it should go up. */ static int ppplrput(q, mp) queue_t *q; mblk_t *mp; { queue_t *uq; struct iocblk *iop; switch (mp->b_datap->db_type) { case M_IOCTL: iop = (struct iocblk *) mp->b_rptr; iop->ioc_error = EINVAL; mp->b_datap->db_type = M_IOCNAK; qreply(q, mp); return 0; case M_FLUSH: if (*mp->b_rptr & FLUSHR) flushq(q, FLUSHDATA); if (*mp->b_rptr & FLUSHW) { *mp->b_rptr &= ~FLUSHR; qreply(q, mp); } else freemsg(mp); return 0; } /* * If we can't get the lower lock straight away, queue this one * rather than blocking, to avoid the possibility of deadlock. */ if (!TRYLOCK_LOWER_R) { putq(q, mp); return 0; } /* * Check that we're still connected to the driver. */ uq = (queue_t *) q->q_ptr; if (uq == 0) { UNLOCK_LOWER; DPRINT1("ppplrput: q = %x, uq = 0??\n", q); freemsg(mp); return 0; } /* * Try to forward the message to the put routine for the upper * control stream for this lower stream. * If there are already messages queued here, queue this one so * they don't get out of order. */ if (queclass(mp) == QPCTL || (qsize(q) == 0 && canput(uq))) put(uq, mp); else putq(q, mp); UNLOCK_LOWER; return 0; } static int ppplrsrv(q) queue_t *q; { mblk_t *mp; queue_t *uq; /* * Packets get queued here for flow control reasons * or if the lrput routine couldn't get the lower lock * without blocking. */ LOCK_LOWER_R; uq = (queue_t *) q->q_ptr; if (uq == 0) { UNLOCK_LOWER; flushq(q, FLUSHALL); DPRINT1("ppplrsrv: q = %x, uq = 0??\n", q); return 0; } while ((mp = getq(q)) != 0) { if (queclass(mp) == QPCTL || canput(uq)) put(uq, mp); else { putbq(q, mp); break; } } UNLOCK_LOWER; return 0; } static int putctl2(q, type, code, val) queue_t *q; int type, code, val; { mblk_t *mp; mp = allocb(2, BPRI_HI); if (mp == 0) return 0; mp->b_datap->db_type = type; mp->b_wptr[0] = code; mp->b_wptr[1] = val; mp->b_wptr += 2; putnext(q, mp); return 1; } static int putctl4(q, type, code, val) queue_t *q; int type, code, val; { mblk_t *mp; mp = allocb(4, BPRI_HI); if (mp == 0) return 0; mp->b_datap->db_type = type; mp->b_wptr[0] = code; ((short *)mp->b_wptr)[1] = val; mp->b_wptr += 4; putnext(q, mp); return 1; } static void debug_dump(q, mp) queue_t *q; mblk_t *mp; { upperstr_t *us; queue_t *uq, *lq; DPRINT("ppp upper streams:\n"); for (us = minor_devs; us != 0; us = us->nextmn) { uq = us->q; DPRINT3(" %d: q=%x rlev=%d", us->mn, uq, (uq? qsize(uq): 0)); DPRINT3(" wlev=%d flags=0x%b", (uq? qsize(WR(uq)): 0), us->flags, "\020\1priv\2control\3blocked\4last"); DPRINT3(" state=%x sap=%x req_sap=%x", us->state, us->sap, us->req_sap); if (us->ppa == 0) DPRINT(" ppa=?\n"); else DPRINT1(" ppa=%d\n", us->ppa->ppa_id); if (us->flags & US_CONTROL) { lq = us->lowerq; DPRINT3(" control for %d lq=%x rlev=%d", us->ppa_id, lq, (lq? qsize(RD(lq)): 0)); DPRINT3(" wlev=%d mru=%d mtu=%d\n", (lq? qsize(lq): 0), us->mru, us->mtu); } } mp->b_datap->db_type = M_IOCACK; qreply(q, mp); } #ifdef FILTER_PACKETS #include #include #include #include #define MAX_IPHDR 128 /* max TCP/IP header size */ /* The following table contains a hard-coded list of protocol/port pairs. * Any matching packets are either discarded unconditionally, or, * if ok_if_link_up is non-zero when a connection does not currently exist * (i.e., they go through if the connection is present, but never initiate * a dial-out). * This idea came from a post by dm@garage.uun.org (David Mazieres) */ static struct pktfilt_tab { int proto; u_short port; u_short ok_if_link_up; } pktfilt_tab[] = { { IPPROTO_UDP, 520, 1 }, /* RIP, ok to pass if link is up */ { IPPROTO_UDP, 123, 1 }, /* NTP, don't keep up the link for it */ { -1, 0, 0 } /* terminator entry has port == -1 */ }; static int ip_hard_filter(us, mp, outbound) upperstr_t *us; mblk_t *mp; int outbound; { struct ip *ip; struct pktfilt_tab *pft; mblk_t *temp_mp; int proto; int len, hlen; /* Note, the PPP header has already been pulled up in all cases */ proto = PPP_PROTOCOL(mp->b_rptr); if (us->flags & US_DBGLOG) DPRINT3("ppp/%d: filter, proto=0x%x, out=%d\n", us->mn, proto, outbound); switch (proto) { case PPP_IP: if ((mp->b_wptr - mp->b_rptr) == PPP_HDRLEN && mp->b_cont != 0) { temp_mp = mp->b_cont; len = msgdsize(temp_mp); hlen = (len < MAX_IPHDR) ? len : MAX_IPHDR; PULLUP(temp_mp, hlen); if (temp_mp == 0) { DPRINT2("ppp/%d: filter, pullup next failed, len=%d\n", us->mn, hlen); mp->b_cont = 0; /* PULLUP() freed the rest */ freemsg(mp); return 0; } ip = (struct ip *)mp->b_cont->b_rptr; } else { len = msgdsize(mp); hlen = (len < (PPP_HDRLEN+MAX_IPHDR)) ? len : (PPP_HDRLEN+MAX_IPHDR); PULLUP(mp, hlen); if (mp == 0) { DPRINT2("ppp/%d: filter, pullup failed, len=%d\n", us->mn, hlen); return 0; } ip = (struct ip *)(mp->b_rptr + PPP_HDRLEN); } /* For IP traffic, certain packets (e.g., RIP) may be either * 1. ignored - dropped completely * 2. will not initiate a connection, but * will be passed if a connection is currently up. */ for (pft=pktfilt_tab; pft->proto != -1; pft++) { if (ip->ip_p == pft->proto) { switch(pft->proto) { case IPPROTO_UDP: if (((struct udphdr *) &((int *)ip)[ip->ip_hl])->uh_dport == htons(pft->port)) goto endfor; break; case IPPROTO_TCP: if (((struct tcphdr *) &((int *)ip)[ip->ip_hl])->th_dport == htons(pft->port)) goto endfor; break; } } } endfor: if (pft->proto != -1) { if (us->flags & US_DBGLOG) DPRINT3("ppp/%d: found IP pkt, proto=0x%x (%d)\n", us->mn, pft->proto, pft->port); /* Discard if not connected, or if not pass_with_link_up */ /* else, if link is up let go by, but don't update time */ return pft->ok_if_link_up? -1: 0; } break; } /* end switch (proto) */ return 1; } #endif /* FILTER_PACKETS */ ppp-2.5.0/modules/ppp_comp.c0000664000175000017500000006674513772531557012732 00000000000000/* * ppp_comp.c - STREAMS module for kernel-level compression and CCP support. * * Copyright (c) 1994 Paul Mackerras. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The name(s) of the authors of this software must not be used to * endorse or promote products derived from this software without * prior written permission. * * 4. Redistributions of any form whatsoever must retain the following * acknowledgment: * "This product includes software developed by Paul Mackerras * ". * * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /* * This file is used under SVR4, Solaris 2, SunOS 4, and Digital UNIX. */ #include #include #include #include #ifdef SVR4 #include #include #include #else #include #ifdef __osf__ #include #endif #endif /* SVR4 */ #include #include #include "ppp_mod.h" #ifdef __osf__ #include #include #endif #include #include #include #include #define PACKETPTR mblk_t * #include MOD_OPEN_DECL(ppp_comp_open); MOD_CLOSE_DECL(ppp_comp_close); static int ppp_comp_rput(queue_t *, mblk_t *); static int ppp_comp_rsrv(queue_t *); static int ppp_comp_wput(queue_t *, mblk_t *); static int ppp_comp_wsrv(queue_t *); static void ppp_comp_ccp(queue_t *, mblk_t *, int); static int msg_byte(mblk_t *, unsigned int); /* Extract byte i of message mp. */ #define MSG_BYTE(mp, i) ((i) < (mp)->b_wptr - (mp)->b_rptr? (mp)->b_rptr[i]: \ msg_byte((mp), (i))) /* Is this LCP packet one we have to transmit using LCP defaults? */ #define LCP_USE_DFLT(mp) (1 <= (code = MSG_BYTE((mp), 4)) && code <= 7) #define PPP_COMP_ID 0xbadf static struct module_info minfo = { #ifdef PRIOQ PPP_COMP_ID, "ppp_comp", 0, INFPSZ, 16512, 16384, #else PPP_COMP_ID, "ppp_comp", 0, INFPSZ, 16384, 4096, #endif }; static struct qinit r_init = { ppp_comp_rput, ppp_comp_rsrv, ppp_comp_open, ppp_comp_close, NULL, &minfo, NULL }; static struct qinit w_init = { ppp_comp_wput, ppp_comp_wsrv, NULL, NULL, NULL, &minfo, NULL }; #if defined(SVR4) && !defined(SOL2) int pcmpdevflag = 0; #define ppp_compinfo pcmpinfo #endif struct streamtab ppp_compinfo = { &r_init, &w_init, NULL, NULL }; int ppp_comp_count; /* number of module instances in use */ #ifdef __osf__ static void ppp_comp_alloc(comp_state_t *); typedef struct memreq { unsigned char comp_opts[20]; int cmd; int thread_status; char *returned_mem; } memreq_t; #endif typedef struct comp_state { int flags; int mru; int mtu; int unit; struct compressor *xcomp; void *xstate; struct compressor *rcomp; void *rstate; struct vjcompress vj_comp; int vj_last_ierrors; struct pppstat stats; #ifdef __osf__ memreq_t memreq; thread_t thread; #endif } comp_state_t; #ifdef __osf__ extern task_t first_task; #endif /* Bits in flags are as defined in pppio.h. */ #define CCP_ERR (CCP_ERROR | CCP_FATALERROR) #define LAST_MOD 0x1000000 /* no ppp modules below us */ #define DBGLOG 0x2000000 /* log debugging stuff */ #define MAX_IPHDR 128 /* max TCP/IP header size */ #define MAX_VJHDR 20 /* max VJ compressed header size (?) */ #undef MIN /* just in case */ #define MIN(a, b) ((a) < (b)? (a): (b)) /* * List of compressors we know about. */ #if DO_BSD_COMPRESS extern struct compressor ppp_bsd_compress; #endif #if DO_DEFLATE extern struct compressor ppp_deflate, ppp_deflate_draft; #endif struct compressor *ppp_compressors[] = { #if DO_BSD_COMPRESS &ppp_bsd_compress, #endif #if DO_DEFLATE &ppp_deflate, &ppp_deflate_draft, #endif NULL }; /* * STREAMS module entry points. */ MOD_OPEN(ppp_comp_open) { comp_state_t *cp; #ifdef __osf__ thread_t thread; #endif if (q->q_ptr == NULL) { cp = (comp_state_t *) ALLOC_SLEEP(sizeof(comp_state_t)); if (cp == NULL) OPEN_ERROR(ENOSR); bzero((caddr_t)cp, sizeof(comp_state_t)); WR(q)->q_ptr = q->q_ptr = (caddr_t) cp; cp->mru = PPP_MRU; cp->mtu = PPP_MTU; cp->xstate = NULL; cp->rstate = NULL; vj_compress_init(&cp->vj_comp, -1); #ifdef __osf__ if (!(thread = kernel_thread_w_arg(first_task, ppp_comp_alloc, (void *)cp))) OPEN_ERROR(ENOSR); cp->thread = thread; #endif ++ppp_comp_count; qprocson(q); } return 0; } MOD_CLOSE(ppp_comp_close) { comp_state_t *cp; qprocsoff(q); cp = (comp_state_t *) q->q_ptr; if (cp != NULL) { if (cp->xstate != NULL) (*cp->xcomp->comp_free)(cp->xstate); if (cp->rstate != NULL) (*cp->rcomp->decomp_free)(cp->rstate); #ifdef __osf__ if (!cp->thread) printf("ppp_comp_close: NULL thread!\n"); else thread_terminate(cp->thread); #endif FREE(cp, sizeof(comp_state_t)); q->q_ptr = NULL; OTHERQ(q)->q_ptr = NULL; --ppp_comp_count; } return 0; } #ifdef __osf__ /* thread for calling back to a compressor's memory allocator * Needed for Digital UNIX since it's VM can't handle requests * for large amounts of memory without blocking. The thread * provides a context in which we can call a memory allocator * that may block. */ static void ppp_comp_alloc(comp_state_t *cp) { int len, cmd; unsigned char *compressor_options; thread_t thread; void *(*comp_allocator)(); #if defined(MAJOR_VERSION) && (MAJOR_VERSION <= 2) /* In 2.x and earlier the argument gets passed * in the thread structure itself. Yuck. */ thread = current_thread(); cp = thread->reply_port; thread->reply_port = PORT_NULL; #endif for (;;) { assert_wait((vm_offset_t)&cp->memreq.thread_status, TRUE); thread_block(); if (thread_should_halt(current_thread())) thread_halt_self(); cmd = cp->memreq.cmd; compressor_options = &cp->memreq.comp_opts[0]; len = compressor_options[1]; if (cmd == PPPIO_XCOMP) { cp->memreq.returned_mem = cp->xcomp->comp_alloc(compressor_options, len); if (!cp->memreq.returned_mem) { cp->memreq.thread_status = ENOSR; } else { cp->memreq.thread_status = 0; } } else { cp->memreq.returned_mem = cp->rcomp->decomp_alloc(compressor_options, len); if (!cp->memreq.returned_mem) { cp->memreq.thread_status = ENOSR; } else { cp->memreq.thread_status = 0; } } } } #endif /* __osf__ */ /* here's the deal with memory allocation under Digital UNIX. * Some other may also benefit from this... * We can't ask for huge chunks of memory in a context where * the caller can't be put to sleep (like, here.) The alloc * is likely to fail. Instead we do this: the first time we * get called, kick off a thread to do the allocation. Return * immediately to the caller with EAGAIN, as an indication that * they should send down the ioctl again. By the time the * second call comes in it's likely that the memory allocation * thread will have returned with the requested memory. We will * continue to return EAGAIN however until the thread has completed. * When it has, we return zero (and the memory) if the allocator * was successful and ENOSR otherwise. * * Callers of the RCOMP and XCOMP ioctls are encouraged (but not * required) to loop for some number of iterations with a small * delay in the loop body (for instance a 1/10-th second "sleep" * via select.) */ static int ppp_comp_wput(q, mp) queue_t *q; mblk_t *mp; { struct iocblk *iop; comp_state_t *cp; int error, len, n; int flags, mask; mblk_t *np; struct compressor **comp; struct ppp_stats *psp; struct ppp_comp_stats *csp; unsigned char *opt_data; int nxslots, nrslots; cp = (comp_state_t *) q->q_ptr; if (cp == 0) { DPRINT("cp == 0 in ppp_comp_wput\n"); freemsg(mp); return 0; } switch (mp->b_datap->db_type) { case M_DATA: putq(q, mp); break; case M_IOCTL: iop = (struct iocblk *) mp->b_rptr; error = EINVAL; switch (iop->ioc_cmd) { case PPPIO_CFLAGS: /* set/get CCP state */ if (iop->ioc_count != 2 * sizeof(int)) break; if (mp->b_cont == 0) { DPRINT1("ppp_comp_wput/%d: PPPIO_CFLAGS b_cont = 0!\n", cp->unit); break; } flags = ((int *) mp->b_cont->b_rptr)[0]; mask = ((int *) mp->b_cont->b_rptr)[1]; cp->flags = (cp->flags & ~mask) | (flags & mask); if ((mask & CCP_ISOPEN) && (flags & CCP_ISOPEN) == 0) { if (cp->xstate != NULL) { (*cp->xcomp->comp_free)(cp->xstate); cp->xstate = NULL; } if (cp->rstate != NULL) { (*cp->rcomp->decomp_free)(cp->rstate); cp->rstate = NULL; } cp->flags &= ~CCP_ISUP; } error = 0; iop->ioc_count = sizeof(int); ((int *) mp->b_cont->b_rptr)[0] = cp->flags; mp->b_cont->b_wptr = mp->b_cont->b_rptr + sizeof(int); break; case PPPIO_VJINIT: /* * Initialize VJ compressor/decompressor */ if (iop->ioc_count != 2) break; if (mp->b_cont == 0) { DPRINT1("ppp_comp_wput/%d: PPPIO_VJINIT b_cont = 0!\n", cp->unit); break; } nxslots = mp->b_cont->b_rptr[0] + 1; nrslots = mp->b_cont->b_rptr[1] + 1; if (nxslots > MAX_STATES || nrslots > MAX_STATES) break; vj_compress_init(&cp->vj_comp, nxslots); cp->vj_last_ierrors = cp->stats.ppp_ierrors; error = 0; iop->ioc_count = 0; break; case PPPIO_XCOMP: case PPPIO_RCOMP: if (iop->ioc_count <= 0) break; if (mp->b_cont == 0) { DPRINT1("ppp_comp_wput/%d: PPPIO_[XR]COMP b_cont = 0!\n", cp->unit); break; } opt_data = mp->b_cont->b_rptr; len = mp->b_cont->b_wptr - opt_data; if (len > iop->ioc_count) len = iop->ioc_count; if (opt_data[1] < 2 || opt_data[1] > len) break; for (comp = ppp_compressors; *comp != NULL; ++comp) if ((*comp)->compress_proto == opt_data[0]) { /* here's the handler! */ error = 0; #ifndef __osf__ if (iop->ioc_cmd == PPPIO_XCOMP) { /* A previous call may have fetched memory for a compressor * that's now being retired or reset. Free it using it's * mechanism for freeing stuff. */ if (cp->xstate != NULL) { (*cp->xcomp->comp_free)(cp->xstate); cp->xstate = NULL; } cp->xcomp = *comp; cp->xstate = (*comp)->comp_alloc(opt_data, len); if (cp->xstate == NULL) error = ENOSR; } else { if (cp->rstate != NULL) { (*cp->rcomp->decomp_free)(cp->rstate); cp->rstate = NULL; } cp->rcomp = *comp; cp->rstate = (*comp)->decomp_alloc(opt_data, len); if (cp->rstate == NULL) error = ENOSR; } #else if ((error = cp->memreq.thread_status) != EAGAIN) if (iop->ioc_cmd == PPPIO_XCOMP) { if (cp->xstate) { (*cp->xcomp->comp_free)(cp->xstate); cp->xstate = 0; } /* sanity check for compressor options */ if (sizeof (cp->memreq.comp_opts) < len) { printf("can't handle options for compressor %d (%d)\n", opt_data[0], opt_data[1]); cp->memreq.thread_status = ENOSR; cp->memreq.returned_mem = 0; } /* fill in request for the thread and kick it off */ if (cp->memreq.thread_status == 0 && !cp->memreq.returned_mem) { bcopy(opt_data, cp->memreq.comp_opts, len); cp->memreq.cmd = PPPIO_XCOMP; cp->xcomp = *comp; error = cp->memreq.thread_status = EAGAIN; thread_wakeup((vm_offset_t)&cp->memreq.thread_status); } else { cp->xstate = cp->memreq.returned_mem; cp->memreq.returned_mem = 0; cp->memreq.thread_status = 0; } } else { if (cp->rstate) { (*cp->rcomp->decomp_free)(cp->rstate); cp->rstate = NULL; } if (sizeof (cp->memreq.comp_opts) < len) { printf("can't handle options for compressor %d (%d)\n", opt_data[0], opt_data[1]); cp->memreq.thread_status = ENOSR; cp->memreq.returned_mem = 0; } if (cp->memreq.thread_status == 0 && !cp->memreq.returned_mem) { bcopy(opt_data, cp->memreq.comp_opts, len); cp->memreq.cmd = PPPIO_RCOMP; cp->rcomp = *comp; error = cp->memreq.thread_status = EAGAIN; thread_wakeup((vm_offset_t)&cp->memreq.thread_status); } else { cp->rstate = cp->memreq.returned_mem; cp->memreq.returned_mem = 0; cp->memreq.thread_status = 0; } } #endif break; } iop->ioc_count = 0; break; case PPPIO_GETSTAT: if ((cp->flags & LAST_MOD) == 0) { error = -1; /* let the ppp_ahdl module handle it */ break; } np = allocb(sizeof(struct ppp_stats), BPRI_HI); if (np == 0) { error = ENOSR; break; } if (mp->b_cont != 0) freemsg(mp->b_cont); mp->b_cont = np; psp = (struct ppp_stats *) np->b_wptr; np->b_wptr += sizeof(struct ppp_stats); iop->ioc_count = sizeof(struct ppp_stats); psp->p = cp->stats; psp->vj = cp->vj_comp.stats; error = 0; break; case PPPIO_GETCSTAT: np = allocb(sizeof(struct ppp_comp_stats), BPRI_HI); if (np == 0) { error = ENOSR; break; } if (mp->b_cont != 0) freemsg(mp->b_cont); mp->b_cont = np; csp = (struct ppp_comp_stats *) np->b_wptr; np->b_wptr += sizeof(struct ppp_comp_stats); iop->ioc_count = sizeof(struct ppp_comp_stats); bzero((caddr_t)csp, sizeof(struct ppp_comp_stats)); if (cp->xstate != 0) (*cp->xcomp->comp_stat)(cp->xstate, &csp->c); if (cp->rstate != 0) (*cp->rcomp->decomp_stat)(cp->rstate, &csp->d); error = 0; break; case PPPIO_DEBUG: if (iop->ioc_count != sizeof(int)) break; if (mp->b_cont == 0) { DPRINT1("ppp_comp_wput/%d: PPPIO_DEBUG b_cont = 0!\n", cp->unit); break; } n = *(int *)mp->b_cont->b_rptr; if (n == PPPDBG_LOG + PPPDBG_COMP) { DPRINT1("ppp_comp%d: debug log enabled\n", cp->unit); cp->flags |= DBGLOG; error = 0; iop->ioc_count = 0; } else { error = -1; } break; case PPPIO_LASTMOD: cp->flags |= LAST_MOD; error = 0; break; default: error = -1; break; } if (error < 0) putnext(q, mp); else if (error == 0) { mp->b_datap->db_type = M_IOCACK; qreply(q, mp); } else { mp->b_datap->db_type = M_IOCNAK; iop->ioc_error = error; iop->ioc_count = 0; qreply(q, mp); } break; case M_CTL: switch (*mp->b_rptr) { case PPPCTL_MTU: cp->mtu = ((unsigned short *)mp->b_rptr)[1]; break; case PPPCTL_MRU: cp->mru = ((unsigned short *)mp->b_rptr)[1]; break; case PPPCTL_UNIT: cp->unit = mp->b_rptr[1]; break; } putnext(q, mp); break; default: putnext(q, mp); } return 0; } static int ppp_comp_wsrv(q) queue_t *q; { mblk_t *mp, *cmp = NULL; comp_state_t *cp; int len, proto, type, hlen, code; struct ip *ip; unsigned char *vjhdr, *dp; cp = (comp_state_t *) q->q_ptr; if (cp == 0) { DPRINT("cp == 0 in ppp_comp_wsrv\n"); return 0; } while ((mp = getq(q)) != 0) { /* assert(mp->b_datap->db_type == M_DATA) */ #ifdef PRIOQ if (!bcanputnext(q,mp->b_band)) #else if (!canputnext(q)) #endif /* PRIOQ */ { putbq(q, mp); break; } /* * First check the packet length and work out what the protocol is. */ len = msgdsize(mp); if (len < PPP_HDRLEN) { DPRINT1("ppp_comp_wsrv: bogus short packet (%d)\n", len); freemsg(mp); cp->stats.ppp_oerrors++; putctl1(RD(q)->q_next, M_CTL, PPPCTL_OERROR); continue; } proto = (MSG_BYTE(mp, 2) << 8) + MSG_BYTE(mp, 3); /* * Make sure we've got enough data in the first mblk * and that we are its only user. */ if (proto == PPP_CCP) hlen = len; else if (proto == PPP_IP) hlen = PPP_HDRLEN + MAX_IPHDR; else hlen = PPP_HDRLEN; if (hlen > len) hlen = len; if (mp->b_wptr < mp->b_rptr + hlen || mp->b_datap->db_ref > 1) { PULLUP(mp, hlen); if (mp == 0) { DPRINT1("ppp_comp_wsrv: pullup failed (%d)\n", hlen); cp->stats.ppp_oerrors++; putctl1(RD(q)->q_next, M_CTL, PPPCTL_OERROR); continue; } } /* * Do VJ compression if requested. */ if (proto == PPP_IP && (cp->flags & COMP_VJC)) { ip = (struct ip *) (mp->b_rptr + PPP_HDRLEN); if (ip->ip_p == IPPROTO_TCP) { type = vj_compress_tcp(ip, len - PPP_HDRLEN, &cp->vj_comp, (cp->flags & COMP_VJCCID), &vjhdr); switch (type) { case TYPE_UNCOMPRESSED_TCP: mp->b_rptr[3] = proto = PPP_VJC_UNCOMP; break; case TYPE_COMPRESSED_TCP: dp = vjhdr - PPP_HDRLEN; dp[1] = mp->b_rptr[1]; /* copy control field */ dp[0] = mp->b_rptr[0]; /* copy address field */ dp[2] = 0; /* set protocol field */ dp[3] = proto = PPP_VJC_COMP; mp->b_rptr = dp; break; } } } /* * Do packet compression if enabled. */ if (proto == PPP_CCP) ppp_comp_ccp(q, mp, 0); else if (proto != PPP_LCP && (cp->flags & CCP_COMP_RUN) && cp->xstate != NULL) { len = msgdsize(mp); (*cp->xcomp->compress)(cp->xstate, &cmp, mp, len, (cp->flags & CCP_ISUP? cp->mtu + PPP_HDRLEN: 0)); if (cmp != NULL) { #ifdef PRIOQ cmp->b_band=mp->b_band; #endif /* PRIOQ */ freemsg(mp); mp = cmp; } } /* * Do address/control and protocol compression if enabled. */ if ((cp->flags & COMP_AC) && !(proto == PPP_LCP && LCP_USE_DFLT(mp))) { mp->b_rptr += 2; /* drop the address & ctrl fields */ if (proto < 0x100 && (cp->flags & COMP_PROT)) ++mp->b_rptr; /* drop the high protocol byte */ } else if (proto < 0x100 && (cp->flags & COMP_PROT)) { /* shuffle up the address & ctrl fields */ mp->b_rptr[2] = mp->b_rptr[1]; mp->b_rptr[1] = mp->b_rptr[0]; ++mp->b_rptr; } cp->stats.ppp_opackets++; cp->stats.ppp_obytes += msgdsize(mp); putnext(q, mp); } return 0; } static int ppp_comp_rput(q, mp) queue_t *q; mblk_t *mp; { comp_state_t *cp; struct iocblk *iop; struct ppp_stats *psp; cp = (comp_state_t *) q->q_ptr; if (cp == 0) { DPRINT("cp == 0 in ppp_comp_rput\n"); freemsg(mp); return 0; } switch (mp->b_datap->db_type) { case M_DATA: putq(q, mp); break; case M_IOCACK: iop = (struct iocblk *) mp->b_rptr; switch (iop->ioc_cmd) { case PPPIO_GETSTAT: /* * Catch this on the way back from the ppp_ahdl module * so we can fill in the VJ stats. */ if (mp->b_cont == 0 || iop->ioc_count != sizeof(struct ppp_stats)) break; psp = (struct ppp_stats *) mp->b_cont->b_rptr; psp->vj = cp->vj_comp.stats; break; } putnext(q, mp); break; case M_CTL: switch (mp->b_rptr[0]) { case PPPCTL_IERROR: ++cp->stats.ppp_ierrors; break; case PPPCTL_OERROR: ++cp->stats.ppp_oerrors; break; } putnext(q, mp); break; default: putnext(q, mp); } return 0; } static int ppp_comp_rsrv(q) queue_t *q; { int proto, rv, i; mblk_t *mp, *dmp = NULL, *np; uchar_t *dp, *iphdr; comp_state_t *cp; int len, hlen, vjlen; u_int iphlen; cp = (comp_state_t *) q->q_ptr; if (cp == 0) { DPRINT("cp == 0 in ppp_comp_rsrv\n"); return 0; } while ((mp = getq(q)) != 0) { /* assert(mp->b_datap->db_type == M_DATA) */ if (!canputnext(q)) { putbq(q, mp); break; } len = msgdsize(mp); cp->stats.ppp_ibytes += len; cp->stats.ppp_ipackets++; /* * First work out the protocol and where the PPP header ends. */ i = 0; proto = MSG_BYTE(mp, 0); if (proto == PPP_ALLSTATIONS) { i = 2; proto = MSG_BYTE(mp, 2); } if ((proto & 1) == 0) { ++i; proto = (proto << 8) + MSG_BYTE(mp, i); } hlen = i + 1; /* * Now reconstruct a complete, contiguous PPP header at the * start of the packet. */ if (hlen < ((cp->flags & DECOMP_AC)? 0: 2) + ((cp->flags & DECOMP_PROT)? 1: 2)) { /* count these? */ goto bad; } if (mp->b_rptr + hlen > mp->b_wptr) { adjmsg(mp, hlen); /* XXX check this call */ hlen = 0; } if (hlen != PPP_HDRLEN) { /* * We need to put some bytes on the front of the packet * to make a full-length PPP header. * If we can put them in *mp, we do, otherwise we * tack another mblk on the front. * XXX we really shouldn't need to carry around * the address and control at this stage. */ dp = mp->b_rptr + hlen - PPP_HDRLEN; if (dp < mp->b_datap->db_base || mp->b_datap->db_ref > 1) { np = allocb(PPP_HDRLEN, BPRI_MED); if (np == 0) goto bad; np->b_cont = mp; mp->b_rptr += hlen; mp = np; dp = mp->b_wptr; mp->b_wptr += PPP_HDRLEN; } else mp->b_rptr = dp; dp[0] = PPP_ALLSTATIONS; dp[1] = PPP_UI; dp[2] = proto >> 8; dp[3] = proto; } /* * Now see if we have a compressed packet to decompress, * or a CCP packet to take notice of. */ proto = PPP_PROTOCOL(mp->b_rptr); if (proto == PPP_CCP) { len = msgdsize(mp); if (mp->b_wptr < mp->b_rptr + len) { PULLUP(mp, len); if (mp == 0) goto bad; } ppp_comp_ccp(q, mp, 1); } else if (proto == PPP_COMP) { if ((cp->flags & CCP_ISUP) && (cp->flags & CCP_DECOMP_RUN) && cp->rstate && (cp->flags & CCP_ERR) == 0) { rv = (*cp->rcomp->decompress)(cp->rstate, mp, &dmp); switch (rv) { case DECOMP_OK: freemsg(mp); mp = dmp; if (mp == NULL) { /* no error, but no packet returned either. */ continue; } break; case DECOMP_ERROR: cp->flags |= CCP_ERROR; ++cp->stats.ppp_ierrors; putctl1(q->q_next, M_CTL, PPPCTL_IERROR); break; case DECOMP_FATALERROR: cp->flags |= CCP_FATALERROR; ++cp->stats.ppp_ierrors; putctl1(q->q_next, M_CTL, PPPCTL_IERROR); break; } } } else if (cp->rstate && (cp->flags & CCP_DECOMP_RUN)) { (*cp->rcomp->incomp)(cp->rstate, mp); } /* * Now do VJ decompression. */ proto = PPP_PROTOCOL(mp->b_rptr); if (proto == PPP_VJC_COMP || proto == PPP_VJC_UNCOMP) { len = msgdsize(mp) - PPP_HDRLEN; if ((cp->flags & DECOMP_VJC) == 0 || len <= 0) goto bad; /* * Advance past the ppp header. * Here we assume that the whole PPP header is in the first mblk. */ np = mp; dp = np->b_rptr + PPP_HDRLEN; if (dp >= mp->b_wptr) { np = np->b_cont; dp = np->b_rptr; } /* * Make sure we have sufficient contiguous data at this point. */ hlen = (proto == PPP_VJC_COMP)? MAX_VJHDR: MAX_IPHDR; if (hlen > len) hlen = len; if (np->b_wptr < dp + hlen || np->b_datap->db_ref > 1) { PULLUP(mp, hlen + PPP_HDRLEN); if (mp == 0) goto bad; np = mp; dp = np->b_rptr + PPP_HDRLEN; } if (proto == PPP_VJC_COMP) { /* * Decompress VJ-compressed packet. * First reset compressor if an input error has occurred. */ if (cp->stats.ppp_ierrors != cp->vj_last_ierrors) { if (cp->flags & DBGLOG) DPRINT1("ppp%d: resetting VJ\n", cp->unit); vj_uncompress_err(&cp->vj_comp); cp->vj_last_ierrors = cp->stats.ppp_ierrors; } vjlen = vj_uncompress_tcp(dp, np->b_wptr - dp, len, &cp->vj_comp, &iphdr, &iphlen); if (vjlen < 0) { if (cp->flags & DBGLOG) DPRINT2("ppp%d: vj_uncomp_tcp failed, pkt len %d\n", cp->unit, len); ++cp->vj_last_ierrors; /* so we don't reset next time */ goto bad; } /* drop ppp and vj headers off */ if (mp != np) { freeb(mp); mp = np; } mp->b_rptr = dp + vjlen; /* allocate a new mblk for the ppp and ip headers */ if ((np = allocb(iphlen + PPP_HDRLEN + 4, BPRI_MED)) == 0) goto bad; dp = np->b_rptr; /* prepend mblk with TCP/IP hdr */ dp[0] = PPP_ALLSTATIONS; /* reconstruct PPP header */ dp[1] = PPP_UI; dp[2] = PPP_IP >> 8; dp[3] = PPP_IP; bcopy((caddr_t)iphdr, (caddr_t)dp + PPP_HDRLEN, iphlen); np->b_wptr = dp + iphlen + PPP_HDRLEN; np->b_cont = mp; /* XXX there seems to be a bug which causes panics in strread if we make an mbuf with only the IP header in it :-( */ if (mp->b_wptr - mp->b_rptr > 4) { bcopy((caddr_t)mp->b_rptr, (caddr_t)np->b_wptr, 4); mp->b_rptr += 4; np->b_wptr += 4; } else { bcopy((caddr_t)mp->b_rptr, (caddr_t)np->b_wptr, mp->b_wptr - mp->b_rptr); np->b_wptr += mp->b_wptr - mp->b_rptr; np->b_cont = mp->b_cont; freeb(mp); } mp = np; } else { /* * "Decompress" a VJ-uncompressed packet. */ cp->vj_last_ierrors = cp->stats.ppp_ierrors; if (!vj_uncompress_uncomp(dp, hlen, &cp->vj_comp)) { if (cp->flags & DBGLOG) DPRINT2("ppp%d: vj_uncomp_uncomp failed, pkt len %d\n", cp->unit, len); ++cp->vj_last_ierrors; /* don't need to reset next time */ goto bad; } mp->b_rptr[3] = PPP_IP; /* fix up the PPP protocol field */ } } putnext(q, mp); continue; bad: if (mp != 0) freemsg(mp); cp->stats.ppp_ierrors++; putctl1(q->q_next, M_CTL, PPPCTL_IERROR); } return 0; } /* * Handle a CCP packet being sent or received. * Here all the data in the packet is in a single mbuf. */ static void ppp_comp_ccp(q, mp, rcvd) queue_t *q; mblk_t *mp; int rcvd; { int len, clen; comp_state_t *cp; unsigned char *dp; len = msgdsize(mp); if (len < PPP_HDRLEN + CCP_HDRLEN) return; cp = (comp_state_t *) q->q_ptr; dp = mp->b_rptr + PPP_HDRLEN; len -= PPP_HDRLEN; clen = CCP_LENGTH(dp); if (clen > len) return; switch (CCP_CODE(dp)) { case CCP_CONFREQ: case CCP_TERMREQ: case CCP_TERMACK: cp->flags &= ~CCP_ISUP; break; case CCP_CONFACK: if ((cp->flags & (CCP_ISOPEN | CCP_ISUP)) == CCP_ISOPEN && clen >= CCP_HDRLEN + CCP_OPT_MINLEN && clen >= CCP_HDRLEN + CCP_OPT_LENGTH(dp + CCP_HDRLEN)) { if (!rcvd) { if (cp->xstate != NULL && (*cp->xcomp->comp_init) (cp->xstate, dp + CCP_HDRLEN, clen - CCP_HDRLEN, cp->unit, 0, ((cp->flags & DBGLOG) != 0))) cp->flags |= CCP_COMP_RUN; } else { if (cp->rstate != NULL && (*cp->rcomp->decomp_init) (cp->rstate, dp + CCP_HDRLEN, clen - CCP_HDRLEN, cp->unit, 0, cp->mru, ((cp->flags & DBGLOG) != 0))) cp->flags = (cp->flags & ~CCP_ERR) | CCP_DECOMP_RUN; } } break; case CCP_RESETACK: if (cp->flags & CCP_ISUP) { if (!rcvd) { if (cp->xstate && (cp->flags & CCP_COMP_RUN)) (*cp->xcomp->comp_reset)(cp->xstate); } else { if (cp->rstate && (cp->flags & CCP_DECOMP_RUN)) { (*cp->rcomp->decomp_reset)(cp->rstate); cp->flags &= ~CCP_ERROR; } } } break; } } #if 0 dump_msg(mp) mblk_t *mp; { dblk_t *db; while (mp != 0) { db = mp->b_datap; DPRINT2("mp=%x cont=%x ", mp, mp->b_cont); DPRINT3("rptr=%x wptr=%x datap=%x\n", mp->b_rptr, mp->b_wptr, db); DPRINT2(" base=%x lim=%x", db->db_base, db->db_lim); DPRINT2(" ref=%d type=%d\n", db->db_ref, db->db_type); mp = mp->b_cont; } } #endif static int msg_byte(mp, i) mblk_t *mp; unsigned int i; { while (mp != 0 && i >= mp->b_wptr - mp->b_rptr) mp = mp->b_cont; if (mp == 0) return -1; return mp->b_rptr[i]; } ppp-2.5.0/modules/ppp_mod.h0000664000175000017500000001160313772532513012530 00000000000000/* * Miscellaneous definitions for PPP STREAMS modules. */ /* * Macros for allocating and freeing kernel memory. */ #ifdef SVR4 /* SVR4, including Solaris 2 */ #include #define ALLOC_SLEEP(n) kmem_alloc((n), KM_SLEEP) #define ALLOC_NOSLEEP(n) kmem_alloc((n), KM_NOSLEEP) #define FREE(p, n) kmem_free((p), (n)) #endif #ifdef SUNOS4 #include /* SunOS 4.x */ #define ALLOC_SLEEP(n) kmem_alloc((n), KMEM_SLEEP) #define ALLOC_NOSLEEP(n) kmem_alloc((n), KMEM_NOSLEEP) #define FREE(p, n) kmem_free((p), (n)) #define NOTSUSER() (suser()? 0: EPERM) #define bcanputnext(q, band) canputnext((q)) #endif /* SunOS 4 */ #ifdef __osf__ #include /* caution: this mirrors macros in sys/malloc.h, and uses interfaces * which are subject to change. * The problems are that: * - the official MALLOC macro wants the lhs of the assignment as an argument, * and it takes care of the assignment itself (yuck.) * - PPP insists on using "FREE" which conflicts with a macro of the same name. * */ #ifdef BUCKETINDX /* V2.0 */ #define ALLOC_SLEEP(n) (void *)malloc((u_long)(n), BUCKETP(n), M_DEVBUF, M_WAITOK) #define ALLOC_NOSLEEP(n) (void *)malloc((u_long)(n), BUCKETP(n), M_DEVBUF, M_NOWAIT) #else #define ALLOC_SLEEP(n) (void *)malloc((u_long)(n), BUCKETINDEX(n), M_DEVBUF, M_WAITOK) #define ALLOC_NOSLEEP(n) (void *)malloc((u_long)(n), BUCKETINDEX(n), M_DEVBUF, M_NOWAIT) #endif #define bcanputnext(q, band) canputnext((q)) #ifdef FREE #undef FREE #endif #define FREE(p, n) free((void *)(p), M_DEVBUF) #define NO_DLPI 1 #ifndef IFT_PPP #define IFT_PPP 0x17 #endif #include #define NOTSUSER() (suser(u.u_procp->p_rcred, &u.u_acflag) ? EPERM : 0) /* #include "ppp_osf.h" */ #endif /* __osf__ */ #ifdef AIX4 #define ALLOC_SLEEP(n) xmalloc((n), 0, pinned_heap) /* AIX V4.x */ #define ALLOC_NOSLEEP(n) xmalloc((n), 0, pinned_heap) /* AIX V4.x */ #define FREE(p, n) xmfree((p), pinned_heap) #define NOTSUSER() (suser()? 0: EPERM) #endif /* AIX */ /* * Macros for printing debugging stuff. */ #ifdef DEBUG #if defined(SVR4) || defined(__osf__) #if defined(SNI) #include #define STRLOG_ID 4712 #define DPRINT(f) strlog(STRLOG_ID, 0, 0, SL_TRACE, f) #define DPRINT1(f, a1) strlog(STRLOG_ID, 0, 0, SL_TRACE, f, a1) #define DPRINT2(f, a1, a2) strlog(STRLOG_ID, 0, 0, SL_TRACE, f, a1, a2) #define DPRINT3(f, a1, a2, a3) strlog(STRLOG_ID, 0, 0, SL_TRACE, f, a1, a2, a3) #else #define DPRINT(f) cmn_err(CE_CONT, f) #define DPRINT1(f, a1) cmn_err(CE_CONT, f, a1) #define DPRINT2(f, a1, a2) cmn_err(CE_CONT, f, a1, a2) #define DPRINT3(f, a1, a2, a3) cmn_err(CE_CONT, f, a1, a2, a3) #endif /* SNI */ #else #define DPRINT(f) printf(f) #define DPRINT1(f, a1) printf(f, a1) #define DPRINT2(f, a1, a2) printf(f, a1, a2) #define DPRINT3(f, a1, a2, a3) printf(f, a1, a2, a3) #endif /* SVR4 or OSF */ #else #define DPRINT(f) 0 #define DPRINT1(f, a1) 0 #define DPRINT2(f, a1, a2) 0 #define DPRINT3(f, a1, a2, a3) 0 #endif /* DEBUG */ #ifndef SVR4 typedef unsigned char uchar_t; typedef unsigned short ushort_t; #ifndef __osf__ typedef int minor_t; #endif #endif /* * If we don't have multithreading support, define substitutes. */ #ifndef D_MP # define qprocson(q) # define qprocsoff(q) # define put(q, mp) ((*(q)->q_qinfo->qi_putp)((q), (mp))) # define canputnext(q) canput((q)->q_next) # define qwriter(q, mp, func, scope) (func)((q), (mp)) #endif #ifdef D_MP /* Use msgpullup if we have other multithreading support. */ #define PULLUP(mp, len) \ do { \ mblk_t *np = msgpullup((mp), (len)); \ freemsg((mp)); \ mp = np; \ } while (0) #else /* Use pullupmsg if we don't have any multithreading support. */ #define PULLUP(mp, len) \ do { \ if (!pullupmsg((mp), (len))) { \ freemsg((mp)); \ mp = 0; \ } \ } while (0) #endif /* * How to declare the open and close procedures for a module. */ #ifdef SVR4 #define MOD_OPEN_DECL(name) \ static int name(queue_t *, dev_t *, int, int, cred_t *) #define MOD_CLOSE_DECL(name) \ static int name(queue_t *, int, cred_t *) #define MOD_OPEN(name) \ static int name(q, devp, flag, sflag, credp) \ queue_t *q; \ dev_t *devp; \ int flag, sflag; \ cred_t *credp; #define MOD_CLOSE(name) \ static int name(q, flag, credp) \ queue_t *q; \ int flag; \ cred_t *credp; #define OPEN_ERROR(x) return (x) #define DRV_OPEN_OK(dev) return 0 #define NOTSUSER() (drv_priv(credp)) #else /* not SVR4 */ #define MOD_OPEN_DECL(name) \ static int name(queue_t *, int, int, int) #define MOD_CLOSE_DECL(name) \ static int name(queue_t *, int) #define MOD_OPEN(name) \ static int name(q, dev, flag, sflag) \ queue_t *q; \ int dev; \ int flag, sflag; #define MOD_CLOSE(name) \ static int name(q, flag) \ queue_t *q; \ int flag; #define OPEN_ERROR(x) { u.u_error = (x); return OPENFAIL; } #define DRV_OPEN_OK(dev) return (dev) #endif /* SVR4 */ ppp-2.5.0/modules/vjcompress.c0000644000175000017500000003763010007342716013256 00000000000000/* * Routines to compress and uncompess tcp packets (for transmission * over low speed serial lines. * * Copyright (c) 1989 Regents of the University of California. * All rights reserved. * * Redistribution and use in source and binary forms are permitted * provided that the above copyright notice and this paragraph are * duplicated in all such forms and that any documentation, * advertising materials, and other materials related to such * distribution and use acknowledge that the software was developed * by the University of California, Berkeley. The name of the * University may not be used to endorse or promote products derived * from this software without specific prior written permission. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * * Van Jacobson (van@helios.ee.lbl.gov), Dec 31, 1989: * - Initial distribution. * * Modified June 1993 by Paul Mackerras, paulus@cs.anu.edu.au, * so that the entire packet being decompressed doesn't have * to be in contiguous memory (just the compressed header). */ /* * This version is used under SunOS 4.x, Digital UNIX, AIX 4.x, * and SVR4 systems including Solaris 2. * * $Id: vjcompress.c,v 1.11 2004/01/17 05:47:55 carlsonj Exp $ */ #include #include #ifdef SVR4 #ifndef __GNUC__ #include /* for ntohl, etc. */ #else /* make sure we don't get the gnu "fixed" one! */ #include "/usr/include/sys/byteorder.h" #endif #endif #ifdef __osf__ #include #endif #include #ifdef AIX4 #define _NETINET_IN_SYSTM_H_ typedef u_long n_long; #else #include #endif #ifdef SOL2 #include #endif #include #include #include #include #ifndef VJ_NO_STATS #define INCR(counter) ++comp->stats.counter #else #define INCR(counter) #endif #define BCMP(p1, p2, n) bcmp((char *)(p1), (char *)(p2), (int)(n)) #undef BCOPY #define BCOPY(p1, p2, n) bcopy((char *)(p1), (char *)(p2), (int)(n)) #ifndef KERNEL #define ovbcopy bcopy #endif #ifdef __osf__ #define getip_hl(base) (((base).ip_vhl)&0xf) #define getth_off(base) ((((base).th_xoff)&0xf0)>>4) #else #define getip_hl(base) ((base).ip_hl) #define getth_off(base) ((base).th_off) #endif void vj_compress_init(comp, max_state) struct vjcompress *comp; int max_state; { register u_int i; register struct cstate *tstate = comp->tstate; if (max_state == -1) max_state = MAX_STATES - 1; bzero((char *)comp, sizeof(*comp)); for (i = max_state; i > 0; --i) { tstate[i].cs_id = i; tstate[i].cs_next = &tstate[i - 1]; } tstate[0].cs_next = &tstate[max_state]; tstate[0].cs_id = 0; comp->last_cs = &tstate[0]; comp->last_recv = 255; comp->last_xmit = 255; comp->flags = VJF_TOSS; } /* ENCODE encodes a number that is known to be non-zero. ENCODEZ * checks for zero (since zero has to be encoded in the long, 3 byte * form). */ #define ENCODE(n) { \ if ((u_short)(n) >= 256) { \ *cp++ = 0; \ cp[1] = (n); \ cp[0] = (n) >> 8; \ cp += 2; \ } else { \ *cp++ = (n); \ } \ } #define ENCODEZ(n) { \ if ((u_short)(n) >= 256 || (u_short)(n) == 0) { \ *cp++ = 0; \ cp[1] = (n); \ cp[0] = (n) >> 8; \ cp += 2; \ } else { \ *cp++ = (n); \ } \ } #define DECODEL(f) { \ if (*cp == 0) {\ u_int32_t tmp = ntohl(f) + ((cp[1] << 8) | cp[2]); \ (f) = htonl(tmp); \ cp += 3; \ } else { \ u_int32_t tmp = ntohl(f) + (u_int32_t)*cp++; \ (f) = htonl(tmp); \ } \ } #define DECODES(f) { \ if (*cp == 0) {\ u_short tmp = ntohs(f) + ((cp[1] << 8) | cp[2]); \ (f) = htons(tmp); \ cp += 3; \ } else { \ u_short tmp = ntohs(f) + (u_int32_t)*cp++; \ (f) = htons(tmp); \ } \ } #define DECODEU(f) { \ if (*cp == 0) {\ (f) = htons((cp[1] << 8) | cp[2]); \ cp += 3; \ } else { \ (f) = htons((u_int32_t)*cp++); \ } \ } u_int vj_compress_tcp(ip, mlen, comp, compress_cid, vjhdrp) register struct ip *ip; u_int mlen; struct vjcompress *comp; int compress_cid; u_char **vjhdrp; { register struct cstate *cs = comp->last_cs->cs_next; register u_int hlen = getip_hl(*ip); register struct tcphdr *oth; register struct tcphdr *th; register u_int deltaS, deltaA; register u_int changes = 0; u_char new_seq[16]; register u_char *cp = new_seq; /* * Bail if this is an IP fragment or if the TCP packet isn't * `compressible' (i.e., ACK isn't set or some other control bit is * set). (We assume that the caller has already made sure the * packet is IP proto TCP). */ if ((ip->ip_off & htons(0x3fff)) || mlen < 40) return (TYPE_IP); th = (struct tcphdr *)&((int *)ip)[hlen]; if ((th->th_flags & (TH_SYN|TH_FIN|TH_RST|TH_ACK)) != TH_ACK) return (TYPE_IP); /* * Packet is compressible -- we're going to send either a * COMPRESSED_TCP or UNCOMPRESSED_TCP packet. Either way we need * to locate (or create) the connection state. Special case the * most recently used connection since it's most likely to be used * again & we don't have to do any reordering if it's used. */ INCR(vjs_packets); if (ip->ip_src.s_addr != cs->cs_ip.ip_src.s_addr || ip->ip_dst.s_addr != cs->cs_ip.ip_dst.s_addr || *(int *)th != ((int *)&cs->cs_ip)[getip_hl(cs->cs_ip)]) { /* * Wasn't the first -- search for it. * * States are kept in a circularly linked list with * last_cs pointing to the end of the list. The * list is kept in lru order by moving a state to the * head of the list whenever it is referenced. Since * the list is short and, empirically, the connection * we want is almost always near the front, we locate * states via linear search. If we don't find a state * for the datagram, the oldest state is (re-)used. */ register struct cstate *lcs; register struct cstate *lastcs = comp->last_cs; do { lcs = cs; cs = cs->cs_next; INCR(vjs_searches); if (ip->ip_src.s_addr == cs->cs_ip.ip_src.s_addr && ip->ip_dst.s_addr == cs->cs_ip.ip_dst.s_addr && *(int *)th == ((int *)&cs->cs_ip)[getip_hl(cs->cs_ip)]) goto found; } while (cs != lastcs); /* * Didn't find it -- re-use oldest cstate. Send an * uncompressed packet that tells the other side what * connection number we're using for this conversation. * Note that since the state list is circular, the oldest * state points to the newest and we only need to set * last_cs to update the lru linkage. */ INCR(vjs_misses); comp->last_cs = lcs; hlen += getth_off(*th); hlen <<= 2; if (hlen > mlen) return (TYPE_IP); goto uncompressed; found: /* * Found it -- move to the front on the connection list. */ if (cs == lastcs) comp->last_cs = lcs; else { lcs->cs_next = cs->cs_next; cs->cs_next = lastcs->cs_next; lastcs->cs_next = cs; } } /* * Make sure that only what we expect to change changed. The first * line of the `if' checks the IP protocol version, header length & * type of service. The 2nd line checks the "Don't fragment" bit. * The 3rd line checks the time-to-live and protocol (the protocol * check is unnecessary but costless). The 4th line checks the TCP * header length. The 5th line checks IP options, if any. The 6th * line checks TCP options, if any. If any of these things are * different between the previous & current datagram, we send the * current datagram `uncompressed'. */ oth = (struct tcphdr *)&((int *)&cs->cs_ip)[hlen]; deltaS = hlen; hlen += getth_off(*th); hlen <<= 2; if (hlen > mlen) return (TYPE_IP); if (((u_short *)ip)[0] != ((u_short *)&cs->cs_ip)[0] || ((u_short *)ip)[3] != ((u_short *)&cs->cs_ip)[3] || ((u_short *)ip)[4] != ((u_short *)&cs->cs_ip)[4] || getth_off(*th) != getth_off(*oth) || (deltaS > 5 && BCMP(ip + 1, &cs->cs_ip + 1, (deltaS - 5) << 2)) || (getth_off(*th) > 5 && BCMP(th + 1, oth + 1, (getth_off(*th) - 5) << 2))) goto uncompressed; /* * Figure out which of the changing fields changed. The * receiver expects changes in the order: urgent, window, * ack, seq (the order minimizes the number of temporaries * needed in this section of code). */ if (th->th_flags & TH_URG) { deltaS = ntohs(th->th_urp); ENCODEZ(deltaS); changes |= NEW_U; } else if (th->th_urp != oth->th_urp) /* argh! URG not set but urp changed -- a sensible * implementation should never do this but RFC793 * doesn't prohibit the change so we have to deal * with it. */ goto uncompressed; if ((deltaS = (u_short)(ntohs(th->th_win) - ntohs(oth->th_win))) > 0) { ENCODE(deltaS); changes |= NEW_W; } if ((deltaA = ntohl(th->th_ack) - ntohl(oth->th_ack)) > 0) { if (deltaA > 0xffff) goto uncompressed; ENCODE(deltaA); changes |= NEW_A; } if ((deltaS = ntohl(th->th_seq) - ntohl(oth->th_seq)) > 0) { if (deltaS > 0xffff) goto uncompressed; ENCODE(deltaS); changes |= NEW_S; } switch(changes) { case 0: /* * Nothing changed. If this packet contains data and the * last one didn't, this is probably a data packet following * an ack (normal on an interactive connection) and we send * it compressed. Otherwise it's probably a retransmit, * retransmitted ack or window probe. Send it uncompressed * in case the other side missed the compressed version. */ if (ip->ip_len != cs->cs_ip.ip_len && ntohs(cs->cs_ip.ip_len) == hlen) break; /* (fall through) */ case SPECIAL_I: case SPECIAL_D: /* * actual changes match one of our special case encodings -- * send packet uncompressed. */ goto uncompressed; case NEW_S|NEW_A: if (deltaS == deltaA && deltaS == ntohs(cs->cs_ip.ip_len) - hlen) { /* special case for echoed terminal traffic */ changes = SPECIAL_I; cp = new_seq; } break; case NEW_S: if (deltaS == ntohs(cs->cs_ip.ip_len) - hlen) { /* special case for data xfer */ changes = SPECIAL_D; cp = new_seq; } break; } deltaS = ntohs(ip->ip_id) - ntohs(cs->cs_ip.ip_id); if (deltaS != 1) { ENCODEZ(deltaS); changes |= NEW_I; } if (th->th_flags & TH_PUSH) changes |= TCP_PUSH_BIT; /* * Grab the cksum before we overwrite it below. Then update our * state with this packet's header. */ deltaA = ntohs(th->th_sum); BCOPY(ip, &cs->cs_ip, hlen); /* * We want to use the original packet as our compressed packet. * (cp - new_seq) is the number of bytes we need for compressed * sequence numbers. In addition we need one byte for the change * mask, one for the connection id and two for the tcp checksum. * So, (cp - new_seq) + 4 bytes of header are needed. hlen is how * many bytes of the original packet to toss so subtract the two to * get the new packet size. */ deltaS = cp - new_seq; cp = (u_char *)ip; if (compress_cid == 0 || comp->last_xmit != cs->cs_id) { comp->last_xmit = cs->cs_id; hlen -= deltaS + 4; *vjhdrp = (cp += hlen); *cp++ = changes | NEW_C; *cp++ = cs->cs_id; } else { hlen -= deltaS + 3; *vjhdrp = (cp += hlen); *cp++ = changes; } *cp++ = deltaA >> 8; *cp++ = deltaA; BCOPY(new_seq, cp, deltaS); INCR(vjs_compressed); return (TYPE_COMPRESSED_TCP); /* * Update connection state cs & send uncompressed packet (that is, * a regular ip/tcp packet but with the 'conversation id' we hope * to use on future compressed packets in the protocol field). */ uncompressed: BCOPY(ip, &cs->cs_ip, hlen); ip->ip_p = cs->cs_id; comp->last_xmit = cs->cs_id; return (TYPE_UNCOMPRESSED_TCP); } /* * Called when we may have missed a packet. */ void vj_uncompress_err(comp) struct vjcompress *comp; { comp->flags |= VJF_TOSS; INCR(vjs_errorin); } /* * "Uncompress" a packet of type TYPE_UNCOMPRESSED_TCP. */ int vj_uncompress_uncomp(buf, buflen, comp) u_char *buf; int buflen; struct vjcompress *comp; { register u_int hlen; register struct cstate *cs; register struct ip *ip; ip = (struct ip *) buf; hlen = getip_hl(*ip) << 2; if (ip->ip_p >= MAX_STATES || hlen + sizeof(struct tcphdr) > buflen || (hlen += getth_off(*((struct tcphdr *)&((char *)ip)[hlen])) << 2) > buflen || hlen > MAX_HDR) { comp->flags |= VJF_TOSS; INCR(vjs_errorin); return (0); } cs = &comp->rstate[comp->last_recv = ip->ip_p]; comp->flags &=~ VJF_TOSS; ip->ip_p = IPPROTO_TCP; BCOPY(ip, &cs->cs_ip, hlen); cs->cs_hlen = hlen; INCR(vjs_uncompressedin); return (1); } /* * Uncompress a packet of type TYPE_COMPRESSED_TCP. * The packet starts at buf and is of total length total_len. * The first buflen bytes are at buf; this must include the entire * compressed TCP/IP header. This procedure returns the length * of the VJ header, with a pointer to the uncompressed IP header * in *hdrp and its length in *hlenp. */ int vj_uncompress_tcp(buf, buflen, total_len, comp, hdrp, hlenp) u_char *buf; int buflen, total_len; struct vjcompress *comp; u_char **hdrp; u_int *hlenp; { register u_char *cp; register u_int hlen, changes; register struct tcphdr *th; register struct cstate *cs; register u_short *bp; register u_int vjlen; register u_int32_t tmp; INCR(vjs_compressedin); cp = buf; changes = *cp++; if (changes & NEW_C) { /* Make sure the state index is in range, then grab the state. * If we have a good state index, clear the 'discard' flag. */ if (*cp >= MAX_STATES) goto bad; comp->flags &=~ VJF_TOSS; comp->last_recv = *cp++; } else { /* this packet has an implicit state index. If we've * had a line error since the last time we got an * explicit state index, we have to toss the packet. */ if (comp->flags & VJF_TOSS) { INCR(vjs_tossed); return (-1); } } cs = &comp->rstate[comp->last_recv]; hlen = getip_hl(cs->cs_ip) << 2; th = (struct tcphdr *)&((u_char *)&cs->cs_ip)[hlen]; th->th_sum = htons((*cp << 8) | cp[1]); cp += 2; if (changes & TCP_PUSH_BIT) th->th_flags |= TH_PUSH; else th->th_flags &=~ TH_PUSH; switch (changes & SPECIALS_MASK) { case SPECIAL_I: { register u_int32_t i = ntohs(cs->cs_ip.ip_len) - cs->cs_hlen; /* some compilers can't nest inline assembler.. */ tmp = ntohl(th->th_ack) + i; th->th_ack = htonl(tmp); tmp = ntohl(th->th_seq) + i; th->th_seq = htonl(tmp); } break; case SPECIAL_D: /* some compilers can't nest inline assembler.. */ tmp = ntohl(th->th_seq) + ntohs(cs->cs_ip.ip_len) - cs->cs_hlen; th->th_seq = htonl(tmp); break; default: if (changes & NEW_U) { th->th_flags |= TH_URG; DECODEU(th->th_urp); } else th->th_flags &=~ TH_URG; if (changes & NEW_W) DECODES(th->th_win); if (changes & NEW_A) DECODEL(th->th_ack); if (changes & NEW_S) DECODEL(th->th_seq); break; } if (changes & NEW_I) { DECODES(cs->cs_ip.ip_id); } else { cs->cs_ip.ip_id = ntohs(cs->cs_ip.ip_id) + 1; cs->cs_ip.ip_id = htons(cs->cs_ip.ip_id); } /* * At this point, cp points to the first byte of data in the * packet. Fill in the IP total length and update the IP * header checksum. */ vjlen = cp - buf; buflen -= vjlen; if (buflen < 0) /* we must have dropped some characters (crc should detect * this but the old slip framing won't) */ goto bad; total_len += cs->cs_hlen - vjlen; cs->cs_ip.ip_len = htons(total_len); /* recompute the ip header checksum */ bp = (u_short *) &cs->cs_ip; cs->cs_ip.ip_sum = 0; for (changes = 0; hlen > 0; hlen -= 2) changes += *bp++; changes = (changes & 0xffff) + (changes >> 16); changes = (changes & 0xffff) + (changes >> 16); cs->cs_ip.ip_sum = ~ changes; *hdrp = (u_char *) &cs->cs_ip; *hlenp = cs->cs_hlen; return vjlen; bad: comp->flags |= VJF_TOSS; INCR(vjs_errorin); return (-1); } ppp-2.5.0/scripts/0000755000175000017500000000000014412736275011020 500000000000000ppp-2.5.0/scripts/chatchat/0000755000175000017500000000000007654146242012576 500000000000000ppp-2.5.0/scripts/chatchat/chatchat.c0000644000175000017500000002057406716175475014461 00000000000000/* ************************************************************************* * NAME: chatchat.c * * DESCRIPTION: * * This program creates a pipe for the chat process to read. The user * can supply information (like a password) that will be picked up * by chat and sent just like the regular contents of a chat script. * * Usage is: * * chatchat * * where matches the option given in the chat script. * * for instance the chat script fragment: * * ... * name: \\dmyname \ * word: @/var/tmp/p \ * ... * ^ * (note: leave some whitespace after the filename) * * expect "name:", reply with a delay followed by "myname" * expect "word:", reply with the data read from the pipe /var/tmp/p * * the matching usage of chatchat would be: * * chatchat /var/tmp/p * * eg: * * $chatchat /var/tmp/p * ... * some other process eventually starts: * chat ... * chat parses the "@/var/tmp/p" option and opens * /var/tmp/p * (chatchat prompts:) * * type PIN into SecurID card * enter resulting passcode: [user inputs something] * * chat reads /var/tmp/p & gets what the * user typed at chatchat's "enter string" prompt * chat removes the pipe file * chat sends the user's input as a response in * place of "@/var/tmp/p" * * PROCESS: * * gcc -g -o chatchat chatchat.c * * * GLOBALS: none * * REFERENCES: * * see the man pages and documentation that come with the 'chat' program * (part of the ppp package). you will need to use the modified chat * program that accepts the '@' operator. * * LIMITATIONS: * * REVISION HISTORY: * * STR Description Author * * 23-Mar-99 initial coding gpk * 12-May-99 unlink the pipe after closing paulus * * TARGET: ANSI C * This program is in the public domain. * * * ************************************************************************* */ #include #include #include #include #include #include #include /* MAXINPUT - the data typed into chatchat must be fewer */ /* characters than this. */ #define MAXINPUT 80 /* ************************************************************************* NAME: main USAGE: int argc; char * argv[]; main(argc, argv[]); returns: int DESCRIPTION: if the pipe file name is given on the command line, create the pipe, prompt the user and put whatever is typed into the pipe. returns -1 on error else # characters entered REFERENCES: LIMITATIONS: GLOBAL VARIABLES: accessed: none modified: none FUNCTIONS CALLED: REVISION HISTORY: STR Description of Revision Author 25-Mar-99 initial coding gpk ************************************************************************* */ int main(int argc, char * argv[]) { int retval; int create_and_write_pipe(char * pipename); if (argc != 2) { fprintf(stderr, "usage: %s pipename\n", argv[0]); retval = -1; } else { retval = create_and_write_pipe(argv[1]); } return (retval); } /* ************************************************************************* NAME: create_and_write_pipe USAGE: int some_int; char * pipename; some_int = create_and_write_pipe(pipename); returns: int DESCRIPTION: given the pipename, create the pipe, open it, prompt the user for a string to put into the pipe, write the string, and close the pipe on error, print out an error message and return -1 returns -1 on error else #bytes written into the pipe REFERENCES: LIMITATIONS: GLOBAL VARIABLES: accessed: none modified: none FUNCTIONS CALLED: REVISION HISTORY: STR Description of Revision Author 25-Mar-99 initial coding gpk 12-May-99 remove pipe after closing paulus ************************************************************************* */ int create_and_write_pipe(char * pipename) { int retval, created, pipefd, nread, nwritten; char input[MAXINPUT]; char errstring[180]; int create_pipe(char * pipename); int write_to_pipe(int pipefd, char * input, int nchar); created = create_pipe(pipename); if (-1 == created) { sprintf(errstring, "unable to create pipe '%s'", pipename); perror(errstring); retval = -1; } else { /* note: this open won't succeed until chat has the pipe */ /* open and ready to read. this makes for nice timing. */ pipefd = open(pipename, O_WRONLY); if (-1 == pipefd) { sprintf(errstring, "unable to open pipe '%s'", pipename); perror(errstring); retval = -1; } else { fprintf(stderr, "%s \n %s", "type PIN into SecurID card and", "enter resulting passcode:"); nread = read(STDIN_FILENO, (void *)input, MAXINPUT); if (0 >= nread) { perror("unable to read from stdin"); retval = -1; } else { /* munch off the newline character, chat supplies */ /* a return when it sends the string out. */ input[nread -1] = 0; nread--; nwritten = write_to_pipe(pipefd, input, nread); /* printf("wrote [%d]: '%s'\n", nwritten, input); */ retval = nwritten; } close(pipefd); /* Now make the pipe go away. It won't actually go away completely until chat closes it. */ if (unlink(pipename) < 0) perror("Warning: couldn't remove pipe"); } } return(retval); } /* ************************************************************************* NAME: create_pipe USAGE: int some_int; char * pipename; some_int = create_pipe(pipename); returns: int DESCRIPTION: create a pipe of the given name if there is an error (like the pipe already exists) print an error message and return return -1 on failure else success REFERENCES: LIMITATIONS: GLOBAL VARIABLES: accessed: none modified: none FUNCTIONS CALLED: REVISION HISTORY: STR Description of Revision Author 25-Mar-99 initial coding gpk ************************************************************************* */ int create_pipe(char * pipename) { mode_t old_umask; int created; /* hijack the umask temporarily to get the mode I want */ /* on the pipe. */ old_umask = umask(000); created = mknod(pipename, S_IFIFO | S_IRWXU | S_IWGRP | S_IWOTH, (dev_t)NULL); /* now restore umask. */ (void)umask(old_umask); if (-1 == created) { perror("unable to create pipe"); } return(created); } /* ************************************************************************* NAME: write_to_pipe USAGE: int some_int; int pipefd; char * input; int nchar; some_int = write_to_pipe(pipefd, input, nchar); returns: int DESCRIPTION: write nchars of data from input to pipefd on error print a message to stderr return -1 on error, else # bytes written REFERENCES: LIMITATIONS: GLOBAL VARIABLES: accessed: none modified: none FUNCTIONS CALLED: REVISION HISTORY: STR Description of Revision Author 25-Mar-99 initial coding gpk 12-May-99 don't write count word first paulus ************************************************************************* */ int write_to_pipe(int pipefd, char * input, int nchar) { int nwritten; /* nwritten = write(pipefd, (void *)&nchar, sizeof(nchar)); */ nwritten = write(pipefd, (void *)input, nchar); if (-1 == nwritten) { perror("unable to write to pipe"); } return(nwritten); } ppp-2.5.0/scripts/chatchat/README0000644000175000017500000001111506716011423013363 00000000000000v 0.1 gpk@onramp.net 3/27/99 I Intro This document covers the use of the modified "chat" program and its adjunct "chatchat" to login using the Security Dynamics SecurID card on a linux system. This set of files comprises a modified version of the chat program (the one distributed with ppp-2.3.5) and a new program called chatchat that allows you to supply data from the keyboard to the chat program. The SecurID card generates passwords that have a lifetime of one minute and are used as a first layer in dial up security. The only software I know of for this card is for windows, so I wrote my own. This software allows you to type in the time-sensitive password right when your chat script is asked to supply the passcode by the remote system. II How It Works This version of chat his an additional command that can be put into its options that says "Don't reply with this string. Open this pipe, read the contents, and reply with that instead." Chatchat creates a pipe and lets you type your passcode into it, then chat picks that up and sends it out just as though the passcode was hardcoded into the options. III Installation I've provided intel binaries and source code the the modified chat program and the chatchat program. I'll recommend that you copy the chat.c program into your ppp-2.3.5/chat directory (save your original chat.c program first!) and re-make it using the Makefile that comes with chat. Copy the new chat somewhere into your path. (On my system chat lives in /usr/sbin/chat, so I've copied the modified one into /usr/sbin/chat.new and changed my dial in script to call chat.new instead of chat. Second, compile chatchat.c and install it somewhere in your path: gcc -g -o chatchat chatchat.c cp chatchat /usr/sbin Third, modify your chat script to use the chatchat program. Mine looks something like this: -------------------- #!/bin/sh # # This is part 2 of the ppp-on script. It will perform the connection # protocol for the desired connection. # use atm0 to turn down the speaker volume on my sportster x2 voice modem # gpk 11/2/97 exec /usr/sbin/chat.new -V -v \ ABORT "BUSY" \ ABORT "NO DIAL TONE" \ ABORT "NO ANSWER" \ TIMEOUT 50 \ "" "atm0" \ OK ATDT$TELEPHONE \ CONNECT '' \ name: \\da0xxxxxx \ word: @/var/tmp/p \ compress. '' ----------------------- This is a standard chat script: * abort if the modem is busy, you don't get a dial tone, no one answers, or 50 seconds elapses. * use atm0 to mute the modem * dial the modem, when it connects, wait to be asked for account name * when we see "name:" prompt, delay briefly then respond with your account name (fill in your account name) Now we get to the new stuff: * when we see "word:" in the password prompt, instead of responding with "@/var/tmp/p", the modified chat program will open the pipe /var/tmp/p, read the passcode out of there, and send it * when we see "compress." (the last word before ppp starts), reply with nothing. The script ends and we start ppp. Note: * Make sure there is some whitespace between the filename and the \. IV Usage To use this install the modified chat and chatchat programs, and modify your chat script similar to the above. Before you dial in, start that chatchat program giving it the same pipe as in your config file. In the above case: chatchat /var/tmp/p Wait until you have one or two tick marks left on your card's current number, then start your dial up process that eventually calls chat. When chat goes to open and read the pipe, chatchat will prompt: type PIN into SecurID card and enter resulting passcode: At that point, type your PIN number into your Securid card, press the diamond, and type the resulting numbers in as your passcode. If you've left the -V -v options on your chat command you'll see everything so out, otherwise it works silently. If you type the number wrong or run out of time, the server will respond with an authentication failure. In that case you will have to hang up and start again. I don't know how to build a conditional script that says either expect "compress" next, but if you see "name:" again, do this instead. V Additional Information You can obtain additional information about chat and ppp from the man pages for chat and pppd, as well as the PPP-HOWTO. ppp-2.5.0/scripts/Makefile.am0000664000175000017500000000103014076444143012764 00000000000000EXTRA_CHATCHAT = \ chatchat/chatchat.c \ chatchat/README EXTRA_SCRIPTS = \ autopppd \ callback \ chatchat \ ip-down.local.add \ ip-up.local.add \ ipv6-down.sample \ ipv6-up.sample \ options-rsh-loc \ options-rsh-rem \ options-ssh-loc \ options-ssh-rem \ plog \ poff \ pon \ pon.1 \ ppp-off \ ppp-on \ ppp-on-dialer \ ppp-on-rsh \ ppp-on-ssh \ README \ redialer \ secure-card EXTRA_DIST= \ $(EXTRA_CHATCHAT) \ $(EXTRA_SCRIPTS) ppp-2.5.0/scripts/Makefile.in0000644000175000017500000003312214407475314013004 00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = scripts ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_atm.m4 \ $(top_srcdir)/m4/ax_check_openssl.m4 \ $(top_srcdir)/m4/ax_check_openssl_func.m4 \ $(top_srcdir)/m4/ax_check_pam.m4 \ $(top_srcdir)/m4/ax_check_pcap.m4 \ $(top_srcdir)/m4/ax_check_srp.m4 $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/pkg.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/pppd/config.h \ $(top_builddir)/pppd/pppdconf.h \ $(top_builddir)/pppd/plugins/pppoe/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) am__DIST_COMMON = $(srcdir)/Makefile.in README DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ ATM_CFLAGS = @ATM_CFLAGS@ ATM_LDFLAGS = @ATM_LDFLAGS@ ATM_LIBS = @ATM_LIBS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CRYPT_LIBS = @CRYPT_LIBS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GREP = @GREP@ GTK_CFLAGS = @GTK_CFLAGS@ GTK_LIBS = @GTK_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_INCLUDES = @OPENSSL_INCLUDES@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAM_CFLAGS = @PAM_CFLAGS@ PAM_LDFLAGS = @PAM_LDFLAGS@ PAM_LIBS = @PAM_LIBS@ PATH_SEPARATOR = @PATH_SEPARATOR@ PCAP_CFLAGS = @PCAP_CFLAGS@ PCAP_LDFLAGS = @PCAP_LDFLAGS@ PCAP_LIBS = @PCAP_LIBS@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PPPD_LOGFILE_DIR = @PPPD_LOGFILE_DIR@ PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@ PPPD_RUNTIME_DIR = @PPPD_RUNTIME_DIR@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SRP_CFLAGS = @SRP_CFLAGS@ SRP_LDFLAGS = @SRP_LDFLAGS@ SRP_LIBS = @SRP_LIBS@ STRIP = @STRIP@ SYSTEMD_CFLAGS = @SYSTEMD_CFLAGS@ SYSTEMD_LIBS = @SYSTEMD_LIBS@ SYSTEM_CA_PATH = @SYSTEM_CA_PATH@ UTIL_LIBS = @UTIL_LIBS@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ EXTRA_CHATCHAT = \ chatchat/chatchat.c \ chatchat/README EXTRA_SCRIPTS = \ autopppd \ callback \ chatchat \ ip-down.local.add \ ip-up.local.add \ ipv6-down.sample \ ipv6-up.sample \ options-rsh-loc \ options-rsh-rem \ options-ssh-loc \ options-ssh-rem \ plog \ poff \ pon \ pon.1 \ ppp-off \ ppp-on \ ppp-on-dialer \ ppp-on-rsh \ ppp-on-ssh \ README \ redialer \ secure-card EXTRA_DIST = \ $(EXTRA_CHATCHAT) \ $(EXTRA_SCRIPTS) all: all-am .SUFFIXES: $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu scripts/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu scripts/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs tags TAGS: ctags CTAGS: cscope cscopelist: distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic clean-libtool \ cscopelist-am ctags-am distclean distclean-generic \ distclean-libtool distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: ppp-2.5.0/scripts/README0000644000175000017500000001405607063103362011613 00000000000000This directory contains a set of scripts which have been used on Linux as well as Solaris 2.x systems to initiate or maintain a connection with PPP. The files in this directory were contributed by Al Longyear (longyear@netcom.com) and Adi Masputra (adi.masputra@sun.com) ------------------------------------------------------------------------ 1. README This file. You are reading it. It is just documentation. ------------------------------------------------------------------------ 2. ppp-on This script will initiate a connection to the PPP system. It will run the chat program with the connection script as a parameter. This is a possible security hole. However, it is simple. It is meant to replace the previous version of ppp-on which was not very functional. The ppp-on script has entries for the account name, password, IP addresses, and telephone numbers. The parameters are passed to the pppd process and, then in turn, to the second part of the connect script, as a set of environment variables. Please make sure that you put the full path name to the ppp-on-dialer script in the reference to it in ppp-on. ------------------------------------------------------------------------ 3. ppp-on-dialer This is the second part to the simple calling script, ppp-on. It executes the chat program to connect the user with a standard UNIX style getty/login connection sequence. ------------------------------------------------------------------------ 4. callback This script may be used in lieu of the ppp-on-dialer to permit the common modem callback sequence. You may need to make changes to the expected prompt string for the modem. The script works by disabling the system's detection of the DCD condition and working on the modem status message "NO CARRIER" which is generated when the modem disconnects. It is crude. It does work for my modem connection. Use as you see fit. ------------------------------------------------------------------------ 5. redialer The redialer script is a replacement for the ppp-on-dialer script. It will do 'attack dialing' or 'demon dialing' of one or more telephone numbers. The first number which responds will be used for a connection. There is a limit of ten attempts and a 15 second delay between dialing attempts. Both values are set in the script. ------------------------------------------------------------------------ 6. ppp-off This is a script which will terminate the active ppp connection. Use as either "ppp-off" to terminate ppp0, or "ppp-off " to terminate the connection on . For example, "ppp-off ppp2" will terminate the ppp2 connection. ------------------------------------------------------------------------ 7. secure-card This script was written by Jim Isaacson . It is a script for the 'expect' programming language used with Tcl. You need to have expect and Tcl installed before this script may be used. This script will operate with a device marketed under the name "SecureCARD". This little device is mated with its controller. On the credit card size device, there is a sequence number which changes on a random basis. In order for you to connect you need to enter a fixed portion of your account name and the number which is displayed on this card device. The number must match the value at the controller in order for the account name to be used. The problem is that chat uses fixed response strings. In addition, the timing for running the script may prevent the use of a script that reads the value before it starts the dial sequence. What was needed was a script which asked the user at the user's console at the time that it is needed. This led to the use of expect. ------------------------------------------------------------------------ 8. ppp-on-rsh This script will initiate a PPP connection to a remote machine using rsh. This is implemented by creating a master/slave pseudo-tty with the slave pointing to rsh, specifically with the 'pty' and 'notty' options of pppd. It is assumed that the remote machine contains some sort of trust mechanisms (such as ~/.rhosts, et al) to allow the local machine to connect via rsh as root. ------------------------------------------------------------------------ 9. ppp-on-ssh This script will initiate a PPP connection to a remote machine using the secure shell, or ssh. I've only tested this on ssh 1.x, so those of you who are running ssh 2.x mahy need to modify the ssh options slightly. This is implemented by creating a master/slave pseudo-ttyt with the slave pointing to ssh, specifically with the 'pty' and 'notty' options of pppd. It is assumed that the remote machine can accept the ssh connection from the local host, in the sense that all ssh authentication mechanisms have been properly configured, so that a remote root user can open a ssh connection. ------------------------------------------------------------------------ 10. options-rsh-loc & options-rsh-rem These options files accompany the ppp-on-rsh script mentioned above. In theory, you'd want to copy the options-rsh-rem to the remote machine where in.rshd is running. The only extra option required on the remote machine options file is the 'notty' option. In addition, all ASCII control characters [0x00 to 0x1f], plus 0xff, are escaped. This may need to be modified depending on the rsh (or pseudo-tty) implementation which may differ across platforms, for further optimizations. ------------------------------------------------------------------------ 11. options-ssh-loc & options-ssh-rem These options files accompany the ppp-on-ssh script mentioned above. I've only tested this on ssh 1.x, so those of you who are running ssh 2.x need to modify the ssh options slightly. In theory, you'd want to copy the options-ssh-rem to the remote machine where sshd daemon is running. The only extra options required on the remote machine options file is the 'notty' option. In addition, all ASCII control characters [0x00 to 0x1f], plus 0xff, are escaped. This may need to be modified depending on the ssh (or pseudo-tty) implementation which may differ across platforms, for further optimizations. ppp-2.5.0/scripts/autopppd0000755000175000017500000001271714402506361012520 00000000000000#!/usr/bin/perl -w # Auto dial script by Brian May use Proc::Daemon; use strict; use Sys::Syslog qw(:DEFAULT setlogsock); # default set, plus setlogsock use Proc::WaitStat qw(:DEFAULT waitstat); Proc::Daemon::Init; open(PIDFILE,">/var/run/autopppd.pid"); print(PIDFILE "$$"); close(PIDFILE); sub toseconds($) { my ($hours,$minutes,$seconds) = split(/:/,shift); return ($hours*60+$minutes)*60+$seconds; } sub dseconds($) { my ($total) = @_; my $seconds = $total % 60; $total = ($total - $seconds)/60; my $minutes = $total % 60; $total = ($total - $minutes)/60; my $hours = $total % 24; $total = ($total - $hours)/24; my $days = $total; if ($days > 0) { return(sprintf("%d-%02d:%02d:%02d",$days,$hours,$minutes,$seconds)); } else { return(sprintf("%02d:%02d:%02d",$hours,$minutes,$seconds)); } } my $program="autopppd"; setlogsock('unix'); openlog($program, 'cons,pid', 'daemon'); my $pppd_start_time; my $pppd_end_time; my $pppd_run_time; my $pppd_fail; my $delay=0; my $idelay=0; my @delays = ( toseconds("00:01:00"), # 1 minute toseconds("00:07:00"), # 8 minutes toseconds("00:07:00"), # 15 minutes toseconds("00:15:00"), # 30 minutes toseconds("00:30:00"), # 1 hour toseconds("01:00:00"), # 2 hours toseconds("01:00:00"), # 3 hours toseconds("03:00:00"), # 6 hours toseconds("06:00:00"), # 12 hours toseconds("12:00:00"), # 24 hours toseconds("24:00:00") # 48 hours ); # action == 0 => immediate retry (!FIXME! needs to have some delay) # action == 1 => delayed retry # action == 2 => abort my $code = { 0 => { message=>"pppd detached", action=> 2 }, 1 => { message=>"fatal error", action=> 2 }, 2 => { message=>"options error", action=> 2 }, 3 => { message=>"not setuid-root error", action=> 2 }, 4 => { message=>"no kernel support for PPP", action=> 2 }, 5 => { message=>"SIGINT or SIGTERM or SIGHUP", action=> 1 }, 6 => { message=>"Serial port locked", action=> 1 }, # should be 0 7 => { message=>"Serial port open error", action=> 1 }, 8 => { message=>"Connect failed", action=> 1 }, 9 => { message=>"Could not execute pty command", action=> 1 }, 10 => { message=>"PPP negotiation failed", action=> 1 }, 11 => { message=>"Peer failed to authenticate", action=> 1 }, 12 => { message=>"Link was idle", action=> 1 }, 13 => { message=>"Time limit exceeded", action=> 1 }, 14 => { message=>"call back not implemented", action=> 2 }, 15 => { message=>"peer not responding", action=> 1 }, 16 => { message=>"modem hang up", action=> 1 }, 17 => { message=>"Serial loopback detected", action=> 1 }, 18 => { message=>"Init script failed", action=> 1 }, 19 => { message=>"We failed to authenticate", action=> 1 }, }; while (1) { $pppd_start_time=time; syslog('info', 'restarting pppd'); # logging sometimes stopped working after ppp was running for # some time. lets see if closing and reopening the log file helps... closelog(); # run ppp my $rc=system("pppd","-detach",@ARGV); # reopon log file openlog($program, 'cons,pid', 'daemon'); # calculate run time $pppd_end_time=time; $pppd_run_time=$pppd_end_time-$pppd_start_time; my $pppd_code = ($? >> 8); my $pppd_signal = $? & 127; my $pppd_coredump = $? & 128; $pppd_fail = 1; if ($pppd_signal != 0) { if ($pppd_coredump) { syslog('err',"pppd died with signal $pppd_signal, coredump"); } else { syslog('err',"pppd died with signal $pppd_signal"); } } elsif ($pppd_coredump) { syslog('err',"pppd died with coredump"); } elsif (defined($code->{$pppd_code}) && $code->{$pppd_code}{"action"} == 0) { syslog('err', "pppd returned: ".$code->{$pppd_code}{"message"}." ($pppd_code), immediate retry"); $pppd_fail = 0; } elsif (defined($code->{$pppd_code}) && $code->{$pppd_code}{"action"} == 1) { syslog('err', "pppd returned: ".$code->{$pppd_code}{"message"}." ($pppd_code), delayed retry"); $pppd_fail = 1; } elsif (defined($code->{$pppd_code}) && $code->{$pppd_code}{"action"} >= 2) { syslog('err', "pppd returned: ".$code->{$pppd_code}{"message"}." ($pppd_code), aborting"); exit(255); } elsif (defined($code->{$pppd_code}) && $code->{$pppd_code}{"action"} >= 2) { syslog('err', "pppd returned: unknown error ($pppd_code), delayed retry"); $pppd_fail = 1; } # if it hasn't ran for at least an hour, then something went wrong elsif ($pppd_run_time < toseconds("01:00:00")) { syslog('err',"pppd session didn't last 1 hour, delayed retry"); $pppd_fail = 1; } else { $pppd_fail = 0; } # if not failed, then reset delay. if (!$pppd_fail) { $idelay = 0; } # get next delay. $delay = $delays[$idelay]; # log statistics. syslog('info',"rc=".waitstat($rc)." runtime=".dseconds($pppd_run_time)." delay[$idelay]=".dseconds($delay).""); # delay for desired time. sleep($delay); # increment delay for next time. if (defined($delays[$idelay+1])) { $idelay++; } } closelog(); ppp-2.5.0/scripts/callback0000755000175000017500000000437510036473504012422 00000000000000#!/bin/sh ################################################################### # # Script to dial the remote system, negotiate the connection, and send # it the id. Then wait for the modem to disconnect. Reset the modem # to answer mode and wait for the system to call back. # # The telephone number and modempass are used when establishing the # connection to the modem. # PHONE=555-1212 MODEMPASS=modem_identifier # # Once the modem calls back, the account name and password are used for # a UNIX style login operation. # ACCOUNT=my_account_name PASSWORD=my_password ################################################################### # # Step 1. Dial the modem and negotiate the initial dialog. # note: the modem is configured to ignore loss of DCD at this point. # it is important that this be performed because the loss of DCD # will normally prevent system from working since 'modem' is used # for pppd. # # The script is terminated normally when the carrier is lost. # chat -v \ TIMEOUT 3 \ ABORT '\nBUSY\r' \ ABORT '\nNO ANSWER\r' \ ABORT '\nRINGING\r\n\r\nRINGING\r' \ '' AT \ 'OK-+++\c-OK' 'AT&C0&D2S0=0H0' \ TIMEOUT 30 \ OK ATDT$TELEPHONE \ CONNECT '' \ assword: $MODEMPASS \ "\nNO CARRIER\r" if [ "$?" = "0" ]; then ################################################################### # # Step 2. Wait for the call back from the remote. This will wait for at most # 30 seconds for the call back should the first attempt fail or # something happen with the callback logic at the remote. # # note: when the callback occurs, the DCD setting is re-enabled. # # If some voice call should happen during this period, the system will # answer the telephone and then hang up on them. I realize that this is # rude, but there is little that this script can do. # chat -v \ TIMEOUT 30 \ ABORT '\nVOICE\r' \ '\nRING\r' 'AT&C1A' \ CONNECT '' \ TIMEOUT 10 \ ogin:--ogin: $ACCOUNT \ TIMEOUT 45 \ assword: $PASSWORD if [ "$?" = "0" ]; then exit 0 fi fi ################################################################### # # The script has failed. Terminate the connection mode. # chat -v TIMEOUT 3 "" AT 'OK-+++\c-OK' 'AT&C1&D2S0=0H0' OK exit 1 ppp-2.5.0/scripts/ip-down.local.add0000644000175000017500000000104406665672552014067 00000000000000 # # This sample code shows you one way to modify your setup to allow automatic # configuration of your resolv.conf for peer supplied DNS addresses when using # the `usepeerdns' option. # # In my case I just added this to my /etc/ppp/ip-down.local script. You may need to # create an executable script if one does not exist. # # Nick Walker (nickwalker@email.com) # if [ -n "$USEPEERDNS" -a -f /etc/ppp/resolv.conf ]; then if [ -f /etc/ppp/resolv.prev ]; then cp -f /etc/ppp/resolv.prev /etc/resolv.conf else rm -f /etc/resolv.conf fi fi ppp-2.5.0/scripts/ip-up.local.add0000644000175000017500000000133107013676712013531 00000000000000 # # This sample code shows you one way to modify your setup to allow automatic # configuration of your resolv.conf for peer supplied DNS addresses when using # the `usepeerdns' option. # # In my case I just added this to my /etc/ppp/ip-up.local script. You may need to # create an executable script if one does not exist. # # Nick Walker (nickwalker@email.com) # if [ -n "$USEPEERDNS" -a -f /etc/ppp/resolv.conf ]; then rm -f /etc/ppp/resolv.prev if [ -f /etc/resolv.conf ]; then cp /etc/resolv.conf /etc/ppp/resolv.prev grep domain /etc/ppp/resolv.prev > /etc/resolv.conf grep search /etc/ppp/resolv.prev >> /etc/resolv.conf cat /etc/ppp/resolv.conf >> /etc/resolv.conf else cp /etc/ppp/resolv.conf /etc fi fi ppp-2.5.0/scripts/ipv6-down.sample0000644000175000017500000000114110036473504013760 00000000000000#!/bin/sh # # This script is called with the following parameters: # interface tty speed local-address remote-address ipparam # # Kill the router advertisement daemon on this interface. # The killing procedure is copied from RedHat 6.0 initscripts. DEVICE="$1" PIDFILE="/var/run/radvd-$DEVICE.pid" [ -f "$PIDFILE" ] || exit 0 PID="$(cat "$PIDFILE")" if [ "$PID" != "" ]; then if ps h "$PID" >/dev/null 2>&1; then kill -TERM "$PID" usleep 10000 if ps h "$PID" >/dev/null 2>&1; then sleep 1 if ps h "$PID" >/dev/null 2>&1; then kill -KILL "$PID" fi fi fi fi rm -f "$PIDFILE" ppp-2.5.0/scripts/ipv6-up.sample0000644000175000017500000000145710036473504013447 00000000000000#!/bin/sh # # This script is called with the following parameters: # interface tty speed local-address remote-address ipparam # # Start router advertisements on this link. # Based on radvd 0.5.0 behaviour DEVICE="$1" CFGFILE="/etc/radvd.conf-$DEVICE" PIDFILE="/var/run/radvd-$DEVICE.pid" EXEFILE="/usr/sbin/radvd" if [ -x "$EXEFILE" -a -f "$CFGFILE" ]; then touch "$PIDFILE" if [ ! -f "$PIDFILE" ]; then echo "error: $PIDFILE is not a regular file. Aborting" exit 0 fi PID="$(cat "$PIDFILE")" if [ -n "$PID" ]; then ps h "$PID" >/dev/null 2>&1 && exit 0 fi # radvd 0.5.0 doesn't write a pid-file so we do it here # enabling debugging keeps radvd in foreground, putting it # on background gives us the PID. "$EXEFILE" -d 1 -C "$CFGFILE" & echo $! >"$PIDFILE" fi ppp-2.5.0/scripts/options-rsh-loc0000644000175000017500000000012607062002230013676 00000000000000debug asyncmap FFFFFFFF escape FF kdebug 0 noipdefault nodefaultroute noauth mtu 1460 ppp-2.5.0/scripts/options-rsh-rem0000644000175000017500000000013407062002230013703 00000000000000notty debug asyncmap FFFFFFFF escape FF kdebug 0 noipdefault nodefaultroute noauth mtu 1460 ppp-2.5.0/scripts/options-ssh-loc0000644000175000017500000000012607062002230013677 00000000000000debug asyncmap FFFFFFFF escape FF kdebug 0 noipdefault nodefaultroute noauth mtu 1400 ppp-2.5.0/scripts/options-ssh-rem0000644000175000017500000000013407062002230013704 00000000000000notty debug asyncmap FFFFFFFF escape FF kdebug 0 noipdefault nodefaultroute noauth mtu 1400 ppp-2.5.0/scripts/plog0000644000175000017500000000022213301371201011574 00000000000000#!/bin/sh if [ -s /var/log/ppp.log ]; then exec tail "$@" /var/log/ppp.log else exec grep ' \(pppd\|chat\)\[' /var/log/syslog | tail "$@" fi ppp-2.5.0/scripts/poff0000644000175000017500000000533713301371201011601 00000000000000#!/bin/sh # $Id: poff,v 1.1 2002/11/24 23:30:44 etbe Exp $ # Written by John Hasler and based on work # by Phil Hands . Distributed under the GNU GPL if [ -x /usr/bin/kill ]; then KILL="/usr/bin/kill" else KILL="/bin/kill" fi SIG=TERM DONE="stopped" MODE="" usage () { cat < pon.txt .\" .TH PON 1 "July 2000" "Debian Project" "Debian PPPD" .SH NAME pon, poff, plog \- starts up, shuts down or lists the log of PPP connections .SH SYNOPSIS .B pon [ isp\-name [ options ] ] .br .B poff [ \-r ] [ \-d ] [ \-c ] [ \-a ] [ \-h ] [ isp\-name ] .br .B plog [ arguments ] .SH DESCRIPTION This manual page describes the \fBpon\fP, \fBplog\fP and \fBpoff\fP scripts, which allow users to control PPP connections. .. .SS pon \fBpon\fP, invoked without arguments, runs the \fI/etc/ppp/ppp_on_boot\fP file, if it exists and is executable. Otherwise, a PPP connection will be started using configuration from \fI/etc/ppp/peers/provider\fP. This is the default behaviour unless an \fBisp\-name\fP argument is given. .PP For instance, to use ISP configuration "myisp" run: .IP pon myisp .PP \fBpon\fP will then use the options file \fI/etc/ppp/peers/myisp\fP. You can pass additional \fBoptions\fP after the ISP name, too. \fBpon\fP can be used to run multiple, simultaneous PPP connections. .. .SS poff \fBpoff\fP closes a PPP connection. If more than one PPP connection exists, the one named in the argument to \fBpoff\fP will be killed, e.g. .IP poff myprovider2 .PP will terminate the connection to myprovider2, and leave the PPP connections to e.g. "myprovider1" or "myprovider3" up and running. .PP \fBpoff\fP takes the following command line options: .RS .TP .B "\-r" causes the connection to be redialed after it is dropped. .TP .B "\-d" toggles the state of pppd's debug option. .TP .B "\-c" causes .BR pppd (8) to renegotiate compression. .TP .B "\-a" stops all running ppp connections. If the argument \fBisp\-name\fP is given it will be ignored. .TP .B "\-h" displays help information. .TP .B "\-v" prints the version and exits. .PP If no argument is given, \fBpoff\fP will stop or signal pppd if and only if there is exactly one running. If more than one connection is active, it will exit with an error code of 1. .. .SS plog \fBplog\fP shows you the last few lines of \fI/var/log/ppp.log\fP. If that file doesn't exist, it shows you the last few lines of your \fI/var/log/syslog\fP file, but excluding the lines not generated by pppd. This script makes use of the .BR tail (1) command, so arguments that can be passed to .BR tail (1) can also be passed to \fBplog\fP. .PP Note: the \fBplog\fP script can only be used by root or another system administrator in group "adm", due to security reasons. Also, to have all pppd-generated information in one logfile, that plog can show, you need the following line in your \fI/etc/syslog.conf\fP file: .PP local2.* \-/var/log/ppp.log .RE .SH FILES .TP .I /etc/ppp/options PPPd system options file. .TP .I /etc/ppp/pap\-secrets System PAP passwords file. .TP .I /etc/ppp/chap\-secrets System CHAP passwords file. .TP .I /etc/ppp/peers/ Directory holding the peer options files. The default file is called \fIprovider\fP. .TP .I /etc/chatscripts/provider The chat script invoked from the default \fI/etc/ppp/peers/provider\fP. .TP .I /var/log/ppp.log The default PPP log file. .SH AUTHORS The p-commands were written by Christoph Lameter . Updated and revised by Philip Hands . .br This manual was written by Othmar Pasteka . Modified by Rob Levin , with some extensions taken from the old p-commands manual written by John Hasler . .SH "SEE ALSO" .BR pppd (8), .BR chat (8), .BR tail (1). ppp-2.5.0/scripts/ppp-off0000755000175000017500000000170706012021120012207 00000000000000#!/bin/sh ###################################################################### # # Determine the device to be terminated. # if [ "$1" = "" ]; then DEVICE=ppp0 else DEVICE=$1 fi ###################################################################### # # If the ppp0 pid file is present then the program is running. Stop it. if [ -r /var/run/$DEVICE.pid ]; then kill -INT `cat /var/run/$DEVICE.pid` # # If the kill did not work then there is no process running for this # pid. It may also mean that the lock file will be left. You may wish # to delete the lock file at the same time. if [ ! "$?" = "0" ]; then rm -f /var/run/$DEVICE.pid echo "ERROR: Removed stale pid file" exit 1 fi # # Success. Let pppd clean up its own junk. echo "PPP link to $DEVICE terminated." exit 0 fi # # The ppp process is not running for ppp0 echo "ERROR: PPP link is not active on $DEVICE" exit 1 ppp-2.5.0/scripts/ppp-on0000555000175000017500000000315106040520723012060 00000000000000#!/bin/sh # # Script to initiate a ppp connection. This is the first part of the # pair of scripts. This is not a secure pair of scripts as the codes # are visible with the 'ps' command. However, it is simple. # # These are the parameters. Change as needed. TELEPHONE=555-1212 # The telephone number for the connection ACCOUNT=george # The account name for logon (as in 'George Burns') PASSWORD=gracie # The password for this account (and 'Gracie Allen') LOCAL_IP=0.0.0.0 # Local IP address if known. Dynamic = 0.0.0.0 REMOTE_IP=0.0.0.0 # Remote IP address if desired. Normally 0.0.0.0 NETMASK=255.255.255.0 # The proper netmask if needed # # Export them so that they will be available at 'ppp-on-dialer' time. export TELEPHONE ACCOUNT PASSWORD # # This is the location of the script which dials the phone and logs # in. Please use the absolute file name as the $PATH variable is not # used on the connect option. (To do so on a 'root' account would be # a security hole so don't ask.) # DIALER_SCRIPT=/etc/ppp/ppp-on-dialer # # Initiate the connection # # I put most of the common options on this command. Please, don't # forget the 'lock' option or some programs such as mgetty will not # work. The asyncmap and escape will permit the PPP link to work with # a telnet or rlogin connection. You are welcome to make any changes # as desired. Don't use the 'defaultroute' option if you currently # have a default route to an ethernet gateway. # exec /usr/sbin/pppd debug lock modem crtscts /dev/ttyS0 38400 \ asyncmap 20A0000 escape FF kdebug 0 $LOCAL_IP:$REMOTE_IP \ noipdefault netmask $NETMASK defaultroute connect $DIALER_SCRIPT ppp-2.5.0/scripts/ppp-on-dialer0000744000175000017500000000061506040530621013316 00000000000000#!/bin/sh # # This is part 2 of the ppp-on script. It will perform the connection # protocol for the desired connection. # exec chat -v \ TIMEOUT 3 \ ABORT '\nBUSY\r' \ ABORT '\nNO ANSWER\r' \ ABORT '\nRINGING\r\n\r\nRINGING\r' \ '' \rAT \ 'OK-+++\c-OK' ATH0 \ TIMEOUT 30 \ OK ATDT$TELEPHONE \ CONNECT '' \ ogin:--ogin: $ACCOUNT \ assword: $PASSWORD ppp-2.5.0/scripts/ppp-on-rsh0000755000175000017500000000374707076035450012677 00000000000000#!/bin/sh # # A sample script to establish PPP session(s) via rsh # # Adi Masputra # Jan 24, 2000 # # # You'd definitely want to change the following addresses to suit # your network configuration # LOC_IP=10.0.0.1 REM_IP=10.0.0.2 NETMASK=255.255.0.0 export LOC_IP REM_IP # # This is the remote peer where in.rshd is running, either # its hostname or IP address # PPPD_RHOST=myremotehost # # For this example, we assume that pppd on both local and remote # machines reside in the same place, /usr/local/bin/pppd # PPPD_LOC=/usr/local/bin/pppd # # The location of local options file (where rsh client is running). # Note that the sample options file included in the distribution # may need further customizations, depending on your needs. The 'noauth' # option specified in the file is there to simplify the example. In # reality, you'd probably want to remove such option. # PPPD_LOC_OPT=/etc/ppp/options-rsh-loc # # The location of remote options file (where in.rshd daemon is running). # Note that the sample options file included in the distribution # may need further customizations, depending on your needs. The 'noauth' # option specified in the file is there to simplify the example. In # reality, you'd probably want to remove such option. Also note that # the remote options file need to include the 'notty' option for this # to work # PPPD_REM_OPT=/etc/ppp/options-rsh-rem # # The location of rsh client on the local machine # RSH_LOC=/bin/rsh export PPPD_LOC PPPD_LOC_OPT PPPD_REM_OPT PPPD_RHOST RSH_LOC # # Uncomment the following to enable IPv6, note that the IPv6 support # needs to be enabled during compilation # # PPPD_IPV6='+ipv6 ipv6cp-use-ipaddr' export PPPD_IPV6 # # And execute pppd with the pty option, specifying rsh client as the # slave side of the pseduo-tty master/slave pair. # exec $PPPD_LOC \ pty '$RSH_LOC $PPPD_RHOST $PPPD_LOC $REM_IP:$LOC_IP $PPPD_IPV6 file $PPPD_REM_OPT' \ $LOC_IP:$REM_IP netmask $NETMASK $PPPD_IPV6 file $PPPD_LOC_OPT ppp-2.5.0/scripts/ppp-on-ssh0000755000175000017500000000441607076035466012701 00000000000000#!/bin/sh # # A sample script to establish PPP session(s) via SSH 1.x # # Adi Masputra # Jan 24, 2000 # # # You'd definitely want to change the following addresses to suit # your network configuration # LOC_IP=10.0.0.1 REM_IP=10.0.0.2 NETMASK=255.255.0.0 export LOC_IP REM_IP # # This is the remote peer where sshd is running, either # its hostname or IP address # PPPD_RHOST=myremotehost # # For this example, we assume that pppd on both local and remote # machines reside in the same place, /usr/local/bin/pppd # PPPD_LOC=/usr/local/bin/pppd # # The location of local options file (where ssh client is running). # Note that the sample options file included in the distribution # may need further customizations, depending on your needs. The 'noauth' # option specified in the file is there to simplify the example, although # some may choose to have it there and rely on ssh authentication # instead. # PPPD_LOC_OPT=/etc/ppp/options-ssh-loc # # The location of remote options file (where sshd daemon is running) # Note that the sample options file included in the distribution # may need further customizations, depending on your needs. The 'noauth' # option specified in the file is there to simplify the example, although # some may choose to have it there and rely on ssh authentication # instead. Also note that the remote options file need to include the 'notty' # options for this to work. # PPPD_REM_OPT=/etc/ppp/options-ssh-rem # # The location of ssh client on the local machine # SSH_LOC=/usr/local/bin/ssh export PPPD_LOC PPPD_LOC_OPT PPPD_REM_OPT PPPD_RHOST SSH_LOC # # Uncomment the following to enable IPv6, note that the IPv6 support # needs to be enabled during compilation # # PPPD_IPV6='+ipv6 ipv6cp-use-ipaddr' export PPPD_IPV6 # # And execute pppd with the pty option, specifying ssh client as the # slave side of the pseudo-tty master/slave pair. Note that on this example, # ssh has been compiled to allow NULL encryption (thus the '-c none' option), # but in reality, you'd probably want to specify the encryption algorithm. # See the man page of ssh(1) for details. # exec $PPPD_LOC \ pty '$SSH_LOC -c none $PPPD_RHOST $PPPD_LOC $REM_IP:$LOC_IP $PPPD_IPV6 file $PPPD_REM_OPT' \ $LOC_IP:$REM_IP netmask $NETMASK $PPPD_IPV6 file $PPPD_LOC_OPT ppp-2.5.0/scripts/redialer0000755000175000017500000000427506012021120012432 00000000000000#!/bin/sh ################################################################### # # These parameters control the attack dialing sequence. # # Maximum number of attempts to reach the telephone number(s) MAX_ATTEMPTS=10 # Delay between each of the attempts. This is a parameter to sleep # so use "15s" for 15 seconds, "1m" for 1 minute, etc. SLEEP_DELAY=15s ################################################################### # # This is a list of telephone numbers. Add new numbers if you wish # and see the function 'callall' below for the dial process. PHONE1=555-1212 PHONE2=411 ################################################################### # # If you use the ppp-on script, then these are passed to this routine # automatically. There is no need to define them here. If not, then # you will need to set the values. # ACCOUNT=my_account_name PASSWORD=my_password ################################################################### # # Function to initialize the modem and ensure that it is in command # state. This may not be needed, but it doesn't hurt. # function initialize { chat -v TIMEOUT 3 '' AT 'OK-+++\c-OK' return } ################################################################### # # Script to dial a telephone # function callnumber { chat -v \ ABORT '\nBUSY\r' \ ABORT '\nNO ANSWER\r' \ ABORT '\nRINGING\r\n\r\nRINGING\r' \ '' ATDT$1 \ CONNECT '' \ ogin:--ogin: $ACCOUNT \ assword: $PASSWORD # # If the connection was successful then end the whole script with a # success. # if [ "$?" = "0" ]; then exit 0 fi return } ################################################################### # # Script to dial any telephone number # function callall { # echo "dialing attempt number: $1" >/dev/console callnumber $PHONE1 # callnumber $PHONE2 } ################################################################### # # Initialize the modem to ensure that it is in the command state # initialize if [ ! "$?" = "0" ]; then exit 1 fi # # Dial telephone numbers until one answers # attempt=0 while : ; do attempt=`expr $attempt + 1` callall $attempt if [ "$attempt" = "$MAX_ATTEMPTS" ]; then exit 1 fi sleep "$SLEEP_DELAY" done ppp-2.5.0/scripts/secure-card0000775000175000017500000000450613773254332013070 00000000000000#!/usr/bin/expect -f # # This script was written by Jim Isaacson . It is # designed to work as a script to use the SecureCARD(tm) device. This # little device is mated with a central controller. The number displayed # on this card changes every so often and you need to enter the number # along with your user account name in order to gain access. Since chat # is based upon fixed strings this procedure will not work with chat. # # It is included by permission. An excellent reference for the expect # program used by this script is in the book: # # "Exploring Expect" # by Don Libes # Published by O'Rielly and Associates # send_user "hello, starting ppp\n" system "stty 19200 -echoe -echo raw < /dev/ttyS3 > /dev/ttyS3" # # These are the parameters for the program. # set user Pxxxxxx set password xxxxxxx set modem /dev/ttyS3 set dialup set timeout 60 spawn -noecho -open [open $modem "r+"] send "AT&F\r" expect "OK" send "ATe0v1x4&c1q0&d2&c1s2=128s0=0DT $dialup\r" set timeout 15 set counter 0 set still_connecting 1 expect { -re ".*CONNECT.*\n" { set timeout 5 set still_connecting 0 continue -expect } -re ".*CONNECT.*\r" { set timeout 5 set still_connecting 0 continue -expect } -re ".*NO.*CARRIER" { send_user "Failed to Connect, exiting...\n" exit } -re ".*NO.*DIAL.*TONE" { send_user "Failed to Connect, exiting...\n" exit } -re ".*VOICE" { send_user "Failed to Connect, exiting...\n" exit } -re ".*sscode:.*\n" { continue -expect } -re ".*sscode:" { set timeout -1 expect_user -re "(.*)\n" send "$expect_out(1,string)\r" set timeout 30 continue -expect } -re ".*Next.*:" { set timeout -1 expect_user -re "(.*)\n" send "$expect_out(1,string)\r" set timeout 30 continue -expect } -re "Your.*" { send "\r" continue -expect } -re ".*in:" { send "$user\r" continue -expect } -re ".*word:" { send "$password\r" } timeout { if { $still_connecting > 0 } { continue -expect } set timeout 15 send "\r" incr counter if { $counter > 8 } { send_user "Cannot Connect\n" exit } else { continue -expect } } } overlay -0 $spawn_id -1 $spawn_id pppd /dev/ttyS3 19200 192.111.187.215: \ crtscts modem defaultroute debug